From 008570d183145571a84b1b2ad2b59e2bd1b3c900 Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Sat, 20 Jan 2024 11:19:05 -0700 Subject: [PATCH 1/9] allow FractionDuctArea --- rulesets/resources/301ruleset.rb | 15 +++++++++++++-- rulesets/resources/301validator.xml | 2 +- rulesets/resources/ES_ZERHruleset.rb | 4 +++- rulesets/tests/test_hvac.rb | 24 ++++++++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/rulesets/resources/301ruleset.rb b/rulesets/resources/301ruleset.rb index 8e99ccd88..364749965 100644 --- a/rulesets/resources/301ruleset.rb +++ b/rulesets/resources/301ruleset.rb @@ -1415,12 +1415,23 @@ def self.set_systems_hvac_rated(orig_bldg, new_bldg) # Ducts orig_hvac_distribution.ducts.each do |orig_duct| + if orig_duct.duct_surface_area.nil? + # Default duct surface area(s) + cfa_served = orig_hvac_distribution.conditioned_floor_area_served + n_returns = orig_hvac_distribution.number_of_return_registers + total_duct_area = HVAC.get_default_duct_surface_area(orig_duct.duct_type, @ncfl_ag, cfa_served, n_returns).sum() + duct_surface_area = total_duct_area * orig_duct.duct_fraction_area + duct_surface_area_isdefaulted = true + else + duct_surface_area = orig_duct.duct_surface_area + end new_hvac_distribution.ducts.add(id: orig_duct.id, duct_type: orig_duct.duct_type, duct_insulation_r_value: orig_duct.duct_insulation_r_value, duct_location: orig_duct.duct_location, - duct_surface_area: orig_duct.duct_surface_area, - duct_buried_insulation_level: orig_duct.duct_buried_insulation_level) + duct_surface_area: duct_surface_area, + duct_buried_insulation_level: orig_duct.duct_buried_insulation_level, + duct_surface_area_isdefaulted: duct_surface_area_isdefaulted) end end diff --git a/rulesets/resources/301validator.xml b/rulesets/resources/301validator.xml index 9d0881a59..dc74f1c6c 100644 --- a/rulesets/resources/301validator.xml +++ b/rulesets/resources/301validator.xml @@ -1100,7 +1100,7 @@ Expected DuctBuriedInsulationLevel to be 'not buried' or 'partially buried' or 'fully buried' or 'deeply buried' Expected 1 element(s) for xpath: DuctLocation Expected DuctLocation to be 'conditioned space' or 'basement - conditioned' or 'basement - unconditioned' or 'crawlspace - vented' or 'crawlspace - unvented' or 'attic - vented' or 'attic - unvented' or 'garage' or 'exterior wall' or 'under slab' or 'roof deck' or 'outside' or 'other housing unit' or 'other heated space' or 'other multifamily buffer space' or 'other non-freezing space' - Expected 1 element(s) for xpath: DuctSurfaceArea + Expected 1 or more element(s) for xpath: FractionDuctArea | DuctSurfaceArea Expected 1 element(s) for xpath: ../NumberofReturnRegisters Expected 1 element(s) for xpath: ../../../ConditionedFloorAreaServed diff --git a/rulesets/resources/ES_ZERHruleset.rb b/rulesets/resources/ES_ZERHruleset.rb index 71c55c851..b35fc8f56 100644 --- a/rulesets/resources/ES_ZERHruleset.rb +++ b/rulesets/resources/ES_ZERHruleset.rb @@ -1173,7 +1173,8 @@ def self.get_radiant_barrier_bool(orig_bldg) ducts_in_uncond_attic = false all_ducts.each do |duct| - if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include?(duct.duct_location) && duct.duct_surface_area > 0 + if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include?(duct.duct_location) && + (!duct.duct_surface_area.to_f.zero? || !duct.duct_fraction_area.to_f.zero?) ducts_in_uncond_attic = true end end @@ -1358,6 +1359,7 @@ def self.get_duct_location_areas(orig_bldg, total_duct_area) duct_fractions.split(',').each do |data| loc, frac = data.split('=').map(&:strip) + puts loc if loc == 'attic' duct_location_areas[HPXML::LocationAtticVented] = Float(frac) * total_duct_area elsif loc == 'crawlspace' diff --git a/rulesets/tests/test_hvac.rb b/rulesets/tests/test_hvac.rb index c4e3942c5..8839977ed 100644 --- a/rulesets/tests/test_hvac.rb +++ b/rulesets/tests/test_hvac.rb @@ -942,6 +942,30 @@ def test_ducts_buried end end + def test_duct_fraction_area + hpxml_name = 'base.xml' + hpxml = HPXML.new(hpxml_path: File.join(@root_path, 'workflow', 'sample_files', hpxml_name)) + hpxml_bldg = hpxml.buildings[0] + hpxml_bldg.hvac_distributions.each do |hvac_distribution| + hvac_distribution.ducts.each do |duct| + duct.duct_surface_area = nil + duct.duct_fraction_area = 0.7 + end + end + hpxml_name = File.basename(@tmp_hpxml_path) + XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) + + _all_calc_types.each do |calc_type| + _hpxml, hpxml_bldg = _test_ruleset(hpxml_name, calc_type) + if [Constants.CalcTypeERIRatedHome].include? calc_type + _check_ducts(hpxml_bldg, [{ duct_type: HPXML::DuctTypeSupply, duct_rvalue: 4.0, duct_area: 510.3, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 189.0, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }]) + else + _check_ducts(hpxml_bldg) + end + end + end + def test_dse hpxml_name = 'base-hvac-dse.xml' From 80273eec3c12c21ac72a5046bc8b4f8c55f8c905 Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Sat, 20 Jan 2024 11:24:48 -0700 Subject: [PATCH 2/9] remove diagnostic puts in ES_ZERHruleset --- rulesets/resources/ES_ZERHruleset.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/rulesets/resources/ES_ZERHruleset.rb b/rulesets/resources/ES_ZERHruleset.rb index b35fc8f56..e5b9caf8e 100644 --- a/rulesets/resources/ES_ZERHruleset.rb +++ b/rulesets/resources/ES_ZERHruleset.rb @@ -1359,7 +1359,6 @@ def self.get_duct_location_areas(orig_bldg, total_duct_area) duct_fractions.split(',').each do |data| loc, frac = data.split('=').map(&:strip) - puts loc if loc == 'attic' duct_location_areas[HPXML::LocationAtticVented] = Float(frac) * total_duct_area elsif loc == 'crawlspace' From a7c5146f7c03b5c1b2f71e537d8552517621d0ed Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Tue, 23 Jan 2024 15:51:06 -0700 Subject: [PATCH 3/9] update changelog and docs [ci skip] --- Changelog.md | 1 + docs/source/workflow_inputs.rst | 39 ++++++++++++++++++++++++--------- 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7437ca844..720437f4d 100644 --- a/Changelog.md +++ b/Changelog.md @@ -9,6 +9,7 @@ __New Features__ - Ground source heat pump model enhancements. - Allows `Roof/RadiantBarrier` to be omitted; defaults to false. - Adds more error-checking for inappropriate inputs (e.g., HVAC SHR=0 or clothes washer IMEF=0). +- Allows `FractionDuctArea` as alternative to `DuctSurfaceArea` __Bugfixes__ - Fixes possible 301ruleset.rb error due to floating point arithmetic. diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index a77b90939..a2d695cb5 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -1532,16 +1532,16 @@ Additional information is entered in each ``DuctLeakageMeasurement``. Additional information is entered in each ``Ducts``. - ============================= ======= ============ =========== ======== ========== =============================== - Element Type Units Constraints Required Default Notes - ============================= ======= ============ =========== ======== ========== =============================== - ``SystemIdentifier`` id Yes Unique identifier - ``DuctType`` string See [#]_ Yes Supply or return ducts - ``DuctInsulationRValue`` double F-ft2-hr/Btu >= 0 Yes R-value of duct insulation [#]_ - ``DuctBuriedInsulationLevel`` string See [#]_ No not buried Duct buried insulation level [#]_ - ``DuctLocation`` string See [#]_ Yes Duct location - ``DuctSurfaceArea`` double ft2 >= 0 Yes Duct surface area - ============================= ======= ============ =========== ======== ========== =============================== + =============================================== ======= ============ ================ ======== ========== ====================================== + Element Type Units Constraints Required Default Notes + =============================================== ======= ============ ================ ======== ========== ====================================== + ``SystemIdentifier`` id Yes Unique identifier + ``DuctType`` string See [#]_ Yes Supply or return ducts + ``DuctInsulationRValue`` double F-ft2-hr/Btu >= 0 Yes R-value of duct insulation [#]_ + ``DuctBuriedInsulationLevel`` string See [#]_ No not buried Duct buried insulation level [#]_ + ``DuctLocation`` string See [#]_ Yes Duct location + ``FractionDuctArea`` and/or ``DuctSurfaceArea`` double frac or ft2 0-1 or >= 0 [#]_ See [#]_ See [#]_ Duct fraction/surface area in location + =============================================== ======= ============ ================ ======== ========== ====================================== .. [#] DuctType choices are "supply" or "return". .. [#] DuctInsulationRValue should not include the exterior air film (i.e., use 0 for an uninsulated duct). @@ -1554,6 +1554,25 @@ Additional information is entered in each ``Ducts``. See the `Building America Solution Center `_ for more information. .. [#] DuctLocation choices are "conditioned space", "basement - conditioned", "basement - unconditioned", "crawlspace - unvented", "crawlspace - vented", "attic - unvented", "attic - vented", "garage", "outside", "exterior wall", "under slab", "roof deck", "other housing unit", "other heated space", "other multifamily buffer space", or "other non-freezing space". See :ref:`hpxmllocations` for descriptions. + .. [#] The sum of all FractionDuctArea must each equal to 1, both for the supply side and return side. + .. [#] FractionDuctArea or DuctSurfaceArea are required if DuctLocation is provided. If both are provided, DuctSurfaceArea will be used in the model. + .. [#] If neither DuctSurfaceArea nor FractionDuctArea provided, duct surface areas will be calculated based on `ASHRAE Standard 152 `_: + + \- **Primary supply duct area**: 0.27 * F_out * ConditionedFloorAreaServed + + \- **Secondary supply duct area**: 0.27 * (1 - F_out) * ConditionedFloorAreaServed + + \- **Total supply duct area**: **Primary supply duct area** + **Secondary supply duct area** + + \- **Primary return duct area**: b_r * F_out * ConditionedFloorAreaServed + + \- **Secondary return duct area**: b_r * (1 - F_out) * ConditionedFloorAreaServed + + \- **Total return duct area**: **Primary return duct area** + **Secondary return duct area** + + where F_out is 1.0 when NumberofConditionedFloorsAboveGrade <= 1 and 0.75 when NumberofConditionedFloorsAboveGrade > 1, and b_r is 0.05 * NumberofReturnRegisters with a maximum value of 0.25. + + If FractionDuctArea is provided, each duct surface area will be FractionDuctArea times total duct area, which is calculated using the sum of primary and secondary duct areas from the equations above. .. _hvac_distribution_hydronic: From d8cd2a88dbe3839625bcfaf1b4117841795a164a Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Tue, 23 Jan 2024 15:54:46 -0700 Subject: [PATCH 4/9] run update_measures --- rulesets/resources/ES_ZERHruleset.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rulesets/resources/ES_ZERHruleset.rb b/rulesets/resources/ES_ZERHruleset.rb index e5b9caf8e..8b6aea492 100644 --- a/rulesets/resources/ES_ZERHruleset.rb +++ b/rulesets/resources/ES_ZERHruleset.rb @@ -1173,8 +1173,8 @@ def self.get_radiant_barrier_bool(orig_bldg) ducts_in_uncond_attic = false all_ducts.each do |duct| - if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include?(duct.duct_location) && - (!duct.duct_surface_area.to_f.zero? || !duct.duct_fraction_area.to_f.zero?) + if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include?(duct.duct_location) && + (!duct.duct_surface_area.to_f.zero? || !duct.duct_fraction_area.to_f.zero?) ducts_in_uncond_attic = true end end From ce56aee578cf3f7c54da80346834b9baa193e0d4 Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Thu, 25 Jan 2024 00:48:28 -0700 Subject: [PATCH 5/9] address review comments --- docs/source/workflow_inputs.rst | 22 ++++++---------------- rulesets/resources/301ruleset.rb | 16 +++------------- rulesets/resources/301validator.xml | 3 +++ rulesets/tests/test_hvac.rb | 11 ++++++++++- tasks.rb | 1 + 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index a2d695cb5..1ba07cb0b 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -1540,7 +1540,7 @@ Additional information is entered in each ``Ducts``. ``DuctInsulationRValue`` double F-ft2-hr/Btu >= 0 Yes R-value of duct insulation [#]_ ``DuctBuriedInsulationLevel`` string See [#]_ No not buried Duct buried insulation level [#]_ ``DuctLocation`` string See [#]_ Yes Duct location - ``FractionDuctArea`` and/or ``DuctSurfaceArea`` double frac or ft2 0-1 or >= 0 [#]_ See [#]_ See [#]_ Duct fraction/surface area in location + ``FractionDuctArea`` and/or ``DuctSurfaceArea`` double frac or ft2 0-1 or >= 0 [#]_ Yes [#]_ See [#]_ Duct fraction/surface area in location =============================================== ======= ============ ================ ======== ========== ====================================== .. [#] DuctType choices are "supply" or "return". @@ -1555,23 +1555,13 @@ Additional information is entered in each ``Ducts``. .. [#] DuctLocation choices are "conditioned space", "basement - conditioned", "basement - unconditioned", "crawlspace - unvented", "crawlspace - vented", "attic - unvented", "attic - vented", "garage", "outside", "exterior wall", "under slab", "roof deck", "other housing unit", "other heated space", "other multifamily buffer space", or "other non-freezing space". See :ref:`hpxmllocations` for descriptions. .. [#] The sum of all FractionDuctArea must each equal to 1, both for the supply side and return side. - .. [#] FractionDuctArea or DuctSurfaceArea are required if DuctLocation is provided. If both are provided, DuctSurfaceArea will be used in the model. - .. [#] If neither DuctSurfaceArea nor FractionDuctArea provided, duct surface areas will be calculated based on `ASHRAE Standard 152 `_: - - \- **Primary supply duct area**: 0.27 * F_out * ConditionedFloorAreaServed - - \- **Secondary supply duct area**: 0.27 * (1 - F_out) * ConditionedFloorAreaServed + .. [#] If both are provided, DuctSurfaceArea will be used in the model. + .. [#] Duct surface areas will be calculated based on BSR/RESNET/ICC 301-2022 Table 4.2.2(1) footnote z. aa.: - \- **Total supply duct area**: **Primary supply duct area** + **Secondary supply duct area** - - \- **Primary return duct area**: b_r * F_out * ConditionedFloorAreaServed - - \- **Secondary return duct area**: b_r * (1 - F_out) * ConditionedFloorAreaServed + \- **Supply duct area**: 0.27 * ConditionedFloorAreaServed + + \- **Return duct area**: (if Number of Returns < 6, 0.05 * Number of Returns, 0.25 otherwise) * ConditionedFloorAreaServed - \- **Total return duct area**: **Primary return duct area** + **Secondary return duct area** - - where F_out is 1.0 when NumberofConditionedFloorsAboveGrade <= 1 and 0.75 when NumberofConditionedFloorsAboveGrade > 1, and b_r is 0.05 * NumberofReturnRegisters with a maximum value of 0.25. - If FractionDuctArea is provided, each duct surface area will be FractionDuctArea times total duct area, which is calculated using the sum of primary and secondary duct areas from the equations above. .. _hvac_distribution_hydronic: diff --git a/rulesets/resources/301ruleset.rb b/rulesets/resources/301ruleset.rb index 364749965..d1a102a43 100644 --- a/rulesets/resources/301ruleset.rb +++ b/rulesets/resources/301ruleset.rb @@ -1415,23 +1415,13 @@ def self.set_systems_hvac_rated(orig_bldg, new_bldg) # Ducts orig_hvac_distribution.ducts.each do |orig_duct| - if orig_duct.duct_surface_area.nil? - # Default duct surface area(s) - cfa_served = orig_hvac_distribution.conditioned_floor_area_served - n_returns = orig_hvac_distribution.number_of_return_registers - total_duct_area = HVAC.get_default_duct_surface_area(orig_duct.duct_type, @ncfl_ag, cfa_served, n_returns).sum() - duct_surface_area = total_duct_area * orig_duct.duct_fraction_area - duct_surface_area_isdefaulted = true - else - duct_surface_area = orig_duct.duct_surface_area - end new_hvac_distribution.ducts.add(id: orig_duct.id, duct_type: orig_duct.duct_type, duct_insulation_r_value: orig_duct.duct_insulation_r_value, duct_location: orig_duct.duct_location, - duct_surface_area: duct_surface_area, - duct_buried_insulation_level: orig_duct.duct_buried_insulation_level, - duct_surface_area_isdefaulted: duct_surface_area_isdefaulted) + duct_surface_area: orig_duct.duct_surface_area, + duct_fraction_area: orig_duct.duct_fraction_area, + duct_buried_insulation_level: orig_duct.duct_buried_insulation_level) end end diff --git a/rulesets/resources/301validator.xml b/rulesets/resources/301validator.xml index dc74f1c6c..a74e043c9 100644 --- a/rulesets/resources/301validator.xml +++ b/rulesets/resources/301validator.xml @@ -1103,6 +1103,9 @@ Expected 1 or more element(s) for xpath: FractionDuctArea | DuctSurfaceArea Expected 1 element(s) for xpath: ../NumberofReturnRegisters Expected 1 element(s) for xpath: ../../../ConditionedFloorAreaServed + + Expected sum(Ducts/FractionDuctArea) for DuctType="supply" to be 1 + Expected sum(Ducts/FractionDuctArea) for DuctType="return" to be 1 diff --git a/rulesets/tests/test_hvac.rb b/rulesets/tests/test_hvac.rb index 8839977ed..4eff60e59 100644 --- a/rulesets/tests/test_hvac.rb +++ b/rulesets/tests/test_hvac.rb @@ -952,6 +952,13 @@ def test_duct_fraction_area duct.duct_fraction_area = 0.7 end end + [HPXML::DuctTypeSupply, HPXML::DuctTypeReturn].each do |duct_type| + hpxml_bldg.hvac_distributions[-1].ducts.add(id: "Ducts#{hpxml_bldg.hvac_distributions[-1].ducts.size + 1}", + duct_type: duct_type, + duct_insulation_r_value: 0, + duct_location: HPXML::LocationConditionedSpace, + duct_fraction_area: 0.3) + end hpxml_name = File.basename(@tmp_hpxml_path) XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) @@ -959,7 +966,9 @@ def test_duct_fraction_area _hpxml, hpxml_bldg = _test_ruleset(hpxml_name, calc_type) if [Constants.CalcTypeERIRatedHome].include? calc_type _check_ducts(hpxml_bldg, [{ duct_type: HPXML::DuctTypeSupply, duct_rvalue: 4.0, duct_area: 510.3, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, - { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 189.0, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }]) + { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 189.0, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeSupply, duct_rvalue: 0.0, duct_area: 218.7, duct_location: HPXML::LocationConditionedSpace, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 81.0, duct_location: HPXML::LocationConditionedSpace, duct_buried: HPXML::DuctBuriedInsulationNone }]) else _check_ducts(hpxml_bldg) end diff --git a/tasks.rb b/tasks.rb index 148126be1..d81315e28 100644 --- a/tasks.rb +++ b/tasks.rb @@ -2439,6 +2439,7 @@ def create_sample_hpxmls 'base-hvac-central-ac-only-var-speed.xml', 'base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml', 'base-hvac-dse.xml', + 'base-hvac-ducts-area-fractions.xml', 'base-hvac-ducts-leakage-cfm50.xml', 'base-hvac-ducts-buried.xml', 'base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml', From 35db6f5ae5de044e582fa86d9d274716cb8fa4e6 Mon Sep 17 00:00:00 2001 From: bpark1327 <59635239+bpark1327@users.noreply.github.com> Date: Thu, 25 Jan 2024 11:26:46 -0700 Subject: [PATCH 6/9] Update docs/source/workflow_inputs.rst Co-authored-by: Scott Horowitz --- docs/source/workflow_inputs.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index 1ba07cb0b..988fbab18 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -1556,7 +1556,7 @@ Additional information is entered in each ``Ducts``. See :ref:`hpxmllocations` for descriptions. .. [#] The sum of all FractionDuctArea must each equal to 1, both for the supply side and return side. .. [#] If both are provided, DuctSurfaceArea will be used in the model. - .. [#] Duct surface areas will be calculated based on BSR/RESNET/ICC 301-2022 Table 4.2.2(1) footnote z. aa.: + .. [#] If DuctSurfaceArea not provided, duct surface areas will be calculated based on ANSI/RESNET/ICC 301-2022: \- **Supply duct area**: 0.27 * ConditionedFloorAreaServed From 3fe8437aadcb3b331c3a9f6c0023236abfeda54c Mon Sep 17 00:00:00 2001 From: bpark1327 Date: Thu, 25 Jan 2024 12:16:31 -0700 Subject: [PATCH 7/9] run update_measures; modify test_duct_fraction_area and docs --- docs/source/workflow_inputs.rst | 2 +- rulesets/tests/test_hvac.rb | 23 +- .../base-hvac-ducts-area-fractions.xml | 537 ++++++++++++++++++ 3 files changed, 543 insertions(+), 19 deletions(-) create mode 100644 workflow/sample_files/base-hvac-ducts-area-fractions.xml diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index 988fbab18..b1afb3500 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -1562,7 +1562,7 @@ Additional information is entered in each ``Ducts``. \- **Return duct area**: (if Number of Returns < 6, 0.05 * Number of Returns, 0.25 otherwise) * ConditionedFloorAreaServed - If FractionDuctArea is provided, each duct surface area will be FractionDuctArea times total duct area, which is calculated using the sum of primary and secondary duct areas from the equations above. + If FractionDuctArea is provided, each duct surface area will be FractionDuctArea times duct area. .. _hvac_distribution_hydronic: diff --git a/rulesets/tests/test_hvac.rb b/rulesets/tests/test_hvac.rb index 4eff60e59..9cbde006c 100644 --- a/rulesets/tests/test_hvac.rb +++ b/rulesets/tests/test_hvac.rb @@ -943,32 +943,19 @@ def test_ducts_buried end def test_duct_fraction_area - hpxml_name = 'base.xml' + hpxml_name = 'base-hvac-ducts-area-fractions.xml' hpxml = HPXML.new(hpxml_path: File.join(@root_path, 'workflow', 'sample_files', hpxml_name)) hpxml_bldg = hpxml.buildings[0] - hpxml_bldg.hvac_distributions.each do |hvac_distribution| - hvac_distribution.ducts.each do |duct| - duct.duct_surface_area = nil - duct.duct_fraction_area = 0.7 - end - end - [HPXML::DuctTypeSupply, HPXML::DuctTypeReturn].each do |duct_type| - hpxml_bldg.hvac_distributions[-1].ducts.add(id: "Ducts#{hpxml_bldg.hvac_distributions[-1].ducts.size + 1}", - duct_type: duct_type, - duct_insulation_r_value: 0, - duct_location: HPXML::LocationConditionedSpace, - duct_fraction_area: 0.3) - end hpxml_name = File.basename(@tmp_hpxml_path) XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) _all_calc_types.each do |calc_type| _hpxml, hpxml_bldg = _test_ruleset(hpxml_name, calc_type) if [Constants.CalcTypeERIRatedHome].include? calc_type - _check_ducts(hpxml_bldg, [{ duct_type: HPXML::DuctTypeSupply, duct_rvalue: 4.0, duct_area: 510.3, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, - { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 189.0, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, - { duct_type: HPXML::DuctTypeSupply, duct_rvalue: 0.0, duct_area: 218.7, duct_location: HPXML::LocationConditionedSpace, duct_buried: HPXML::DuctBuriedInsulationNone }, - { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 81.0, duct_location: HPXML::LocationConditionedSpace, duct_buried: HPXML::DuctBuriedInsulationNone }]) + _check_ducts(hpxml_bldg, [{ duct_type: HPXML::DuctTypeSupply, duct_rvalue: 4.0, duct_area: 820.1, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 455.6, duct_location: HPXML::LocationAtticUnvented, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeSupply, duct_rvalue: 4.0, duct_area: 273.4, duct_location: HPXML::LocationExteriorWall, duct_buried: HPXML::DuctBuriedInsulationNone }, + { duct_type: HPXML::DuctTypeReturn, duct_rvalue: 0.0, duct_area: 151.9, duct_location: HPXML::LocationConditionedSpace, duct_buried: HPXML::DuctBuriedInsulationNone }]) else _check_ducts(hpxml_bldg) end diff --git a/workflow/sample_files/base-hvac-ducts-area-fractions.xml b/workflow/sample_files/base-hvac-ducts-area-fractions.xml new file mode 100644 index 000000000..2588f47c7 --- /dev/null +++ b/workflow/sample_files/base-hvac-ducts-area-fractions.xml @@ -0,0 +1,537 @@ + + + + HPXML + tasks.rb + 2000-01-01T00:00:00-07:00 + create + + + + + latest + + + latest + + + SF_National_3.2 + + + 2021 + + + SF_2.0 + + + + + + + +
+ CO + 80206 +
+
+ + proposed workscope + + + + + + electricity + natural gas + + + + single-family detached + 3.0 + 2.0 + 3 + 4050.0 + + + + + 2006 + 5B + + + 2021 + 5B + + + + USA_CO_Denver.Intl.AP.725650_TMY3 + + USA_CO_Denver.Intl.AP.725650_TMY3.epw + + + + + + + + 50.0 + + ACH + 3.0 + + 32400.0 + + + + + + + + false + + + false + + + + + + + + + + + true + + + + + + + + + + + attic - unvented + 1509.3 + 0.7 + 0.92 + 6.0 + + + 2.3 + + + + + + + outside + basement - conditioned + 115.6 + 0.7 + 0.92 + + + 23.0 + + + + + outside + conditioned space + 116.0 + 0.7 + 0.92 + + + 23.0 + + + + + + + outside + conditioned space + + + + 2400.0 + 0.7 + 0.92 + + + 23.0 + + + + + outside + attic - unvented + + + + 225.0 + 0.7 + 0.92 + + + 4.0 + + + + + + + ground + basement - conditioned + 8.0 + 1200.0 + 8.0 + 7.0 + + + + continuous - exterior + 8.9 + 0.0 + 8.0 + + + continuous - interior + 0.0 + 0.0 + 0.0 + + + + + + + + attic - unvented + conditioned space + + + + 1350.0 + + + 39.3 + + + + + + + basement - conditioned + 1350.0 + 4.0 + 150.0 + + + + 0.0 + 0.0 + + + + + + 0.0 + 0.0 + + + + 0.0 + 0.0 + + + + + + + 216.0 + 0 + 0.33 + 0.45 + 0.67 + + + + + 144.0 + 90 + 0.33 + 0.45 + 0.67 + + + + + 216.0 + 180 + 0.33 + 0.45 + 0.67 + + + + + 144.0 + 270 + 0.33 + 0.45 + 0.67 + + + + + + + + 40.0 + 180 + 4.4 + + + + + + + + + + + + + natural gas + 48000.0 + + AFUE + 0.92 + + 1.0 + + 0.58 + -0.25 + + + + + + central air conditioner + electricity + 36000.0 + single stage + 1.0 + + SEER + 13.0 + + 0.73 + + -0.25 + -0.25 + 0.58 + + + + + + manual thermostat + + + + + + regular velocity + + supply + + CFM25 + 75.0 + to outside + + + + return + + CFM25 + 25.0 + to outside + + + + + supply + 4.0 + attic - unvented + 0.75 + + + + return + 0.0 + attic - unvented + 0.75 + + + + supply + 4.0 + exterior wall + 0.25 + + + + return + 0.0 + conditioned space + 0.25 + + 3 + + + 4050.0 + + + + + + electricity + storage water heater + conditioned space + false + 40.0 + 1.0 + 18767.0 + 0.95 + + + + + + 50.0 + + + + 0.0 + + + + + shower head + true + + + + faucet + false + + + + + + + false + conditioned space + 1.21 + 380.0 + 0.12 + 1.09 + 27.0 + 6.0 + 3.2 + + + + false + conditioned space + electricity + 3.73 + true + 150.0 + + + + false + conditioned space + 307.0 + 12 + 0.12 + 1.09 + 22.32 + 4.0 + + + + conditioned space + 650.0 + true + + + + conditioned space + electricity + false + + + + false + + + + + + interior + 0.4 + + + + + + + interior + 0.1 + + + + + + + interior + 0.25 + + + + + + + exterior + 0.4 + + + + + + + exterior + 0.1 + + + + + + + exterior + 0.25 + + + + + + +
+
\ No newline at end of file From 1b1849ee06c9fff8525f2847b41baf7a9110bcf5 Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Thu, 25 Jan 2024 21:20:03 +0000 Subject: [PATCH 8/9] Latest results. --- workflow/tests/base_results/sample_files.csv | 1 + 1 file changed, 1 insertion(+) diff --git a/workflow/tests/base_results/sample_files.csv b/workflow/tests/base_results/sample_files.csv index 3a3907381..64ee9d4e2 100644 --- a/workflow/tests/base_results/sample_files.csv +++ b/workflow/tests/base_results/sample_files.csv @@ -110,6 +110,7 @@ base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml,86.18,29.51,8.31,10.4 base-hvac-dse.xml,78.18,29.51,8.31,10.49,47.03,5.17,11.53,37.28,5.37,9.02,21.28,0.0,0.0,0.22149,150.0,8329.47,5495.15,1.0105,56.44,1.0,56.44,78.18,78.18,0.0,50.97,1.0,50.97,78.18,78.18,0.0,74.21,33.6,8.25,10.49,53.52,5.15,11.53,37.28,5.37,9.02,21.28,0.0,0.0,0.22149 base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-lockout-temperatures.xml,80.78,29.52,8.31,10.49,31.7,4.36,11.53,27.830000000000002,3.67,9.02,21.28,0.0,0.0,0.2195,109.48,6079.06,5495.15,1.0105,53.24,1.0,53.24,80.78,80.78,0.0,47.42,1.0,47.42,80.78,80.78,0.0,76.88,33.59,8.25,10.49,35.57,4.34,11.53,27.830000000000002,3.67,9.02,21.28,0.0,0.0,0.2195 base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml,80.07,29.509999999999998,8.31,10.49,35.339999999999996,4.36,11.53,30.89,3.67,9.02,21.28,0.0,0.0,0.21935,120.03,6664.7,5495.15,1.0104,53.24,1.0,53.24,80.07,80.07,0.0,47.42,1.0,47.42,80.07,80.07,0.0,76.19,33.59,8.25,10.49,39.64,4.34,11.53,30.89,3.67,9.02,21.28,0.0,0.0,0.21935 +base-hvac-ducts-area-fractions.xml,84.24,45.24,12.2,10.49,72.06,7.16,11.53,62.52,7.16,8.87,27.42,0.0,0.0,0.22149,177.08,12686.54,7421.05,0.9654,55.9,1.0,55.9,84.24,84.24,0.0,51.06,1.0,51.06,84.24,84.24,0.0,77.12,54.86,12.16,10.49,87.37,7.13,11.53,62.52,7.16,8.87,27.42,0.0,0.0,0.22149 base-hvac-ducts-buried.xml,75.28,29.51,8.31,10.49,47.03,5.17,11.53,35.77,4.53,9.02,21.28,0.0,0.0,0.22149,144.76,8038.85,5495.15,1.0105,56.45,1.0,56.45,75.28,75.28,0.0,50.97,1.0,50.97,75.28,75.28,0.0,71.46,33.6,8.25,10.49,53.52,5.15,11.53,35.77,4.53,9.02,21.28,0.0,0.0,0.22149 base-hvac-ducts-leakage-cfm50.xml,76.63,29.51,8.31,10.49,47.03,5.17,11.53,37.06,4.71,9.02,21.28,0.0,0.0,0.22149,148.39,8240.02,5495.15,1.0105,56.45,1.0,56.45,76.63,76.63,0.0,50.97,1.0,50.97,76.63,76.63,0.0,72.74,33.6,8.25,10.49,53.52,5.15,11.53,37.06,4.71,9.02,21.28,0.0,0.0,0.22149 base-hvac-elec-resistance-only.xml,94.64,29.51,8.31,10.49,22.92,5.2,11.53,27.49,4.71,9.02,21.28,0.0,0.0,0.21902,93.1,5314.07,5648.96,1.0104,56.01,1.0,56.01,94.64,94.64,0.0,50.3,1.0,50.3,94.64,94.64,0.0,90.2,33.6,8.25,10.49,25.88,5.18,11.53,27.49,4.71,9.02,21.28,0.0,0.0,0.21902 From bed481ad7ff839fb63a5eecabf2492366319dab4 Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Thu, 25 Jan 2024 15:09:52 -0700 Subject: [PATCH 9/9] A couple unrelated things (update PR template, separate tasks to mirror OS-HPXML tasks). Small update to docs. [ci skip] --- .github/pull_request_template.md | 6 +++--- docs/source/workflow_inputs.rst | 4 ++-- tasks.rb | 22 +++++++++++++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f8df4d1ff..ce857e2f6 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -9,10 +9,10 @@ PR Author: Check these when they're done. Not all may apply. ~~strikethrough~~ a PR Reviewer: Verify each has been completed. - [ ] OS-HPXML git subtree has been pulled -- [ ] 301/ES rulesets and unit tests have been updated - [ ] 301validator.xml has been updated (reference EPvalidator.xml) -- [ ] Workflow tests have been updated +- [ ] Sample files have been added/updated (`openstudio tasks.rb update_hpxmls`) +- [ ] Tests have been added/updated (e.g., `rulesets\tests` and/or `workflow/tests/*_test.rb`) - [ ] Documentation has been updated - [ ] Changelog has been updated - [ ] `openstudio tasks.rb update_measures` has been run -- [ ] No unexpected regression test changes on CI +- [ ] No unexpected changes to simulation results on CI diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst index b1afb3500..25df2bd44 100644 --- a/docs/source/workflow_inputs.rst +++ b/docs/source/workflow_inputs.rst @@ -1560,9 +1560,9 @@ Additional information is entered in each ``Ducts``. \- **Supply duct area**: 0.27 * ConditionedFloorAreaServed - \- **Return duct area**: (if Number of Returns < 6, 0.05 * Number of Returns, 0.25 otherwise) * ConditionedFloorAreaServed + \- **Return duct area**: (if NumberofReturnRegisters < 6, 0.05 * NumberofReturnRegisters, 0.25 otherwise) * ConditionedFloorAreaServed - If FractionDuctArea is provided, each duct surface area will be FractionDuctArea times duct area. + where each duct surface area will be FractionDuctArea multiplied by supply, or return, duct area. .. _hvac_distribution_hydronic: diff --git a/tasks.rb b/tasks.rb index d81315e28..23b0b4039 100644 --- a/tasks.rb +++ b/tasks.rb @@ -2948,7 +2948,7 @@ def create_sample_hpxmls end end -command_list = [:update_measures, :create_release_zips] +command_list = [:update_measures, :update_hpxmls, :create_release_zips] def display_usage(command_list) puts "Usage: openstudio #{File.basename(__FILE__)} [COMMAND]\nCommands:\n " + command_list.join("\n ") @@ -2969,16 +2969,10 @@ def display_usage(command_list) end if ARGV[0].to_sym == :update_measures - require 'oga' - require_relative 'rulesets/resources/constants' - # Prevent NREL error regarding U: drive when not VPNed in ENV['HOME'] = 'C:' if !ENV['HOME'].nil? && ENV['HOME'].start_with?('U:') ENV['HOMEDRIVE'] = 'C:\\' if !ENV['HOMEDRIVE'].nil? && ENV['HOMEDRIVE'].start_with?('U:') - create_test_hpxmls - create_sample_hpxmls - # Apply rubocop cops = ['Layout', 'Lint/DeprecatedClassMethods', @@ -3014,6 +3008,20 @@ def display_usage(command_list) puts 'Done.' end +if ARGV[0].to_sym == :update_hpxmls + require 'oga' + require_relative 'rulesets/resources/constants' + + # Prevent NREL error regarding U: drive when not VPNed in + ENV['HOME'] = 'C:' if !ENV['HOME'].nil? && ENV['HOME'].start_with?('U:') + ENV['HOMEDRIVE'] = 'C:\\' if !ENV['HOMEDRIVE'].nil? && ENV['HOMEDRIVE'].start_with?('U:') + + t = Time.now + create_test_hpxmls + create_sample_hpxmls + puts "Completed in #{(Time.now - t).round(1)}s" +end + if ARGV[0].to_sym == :create_release_zips require_relative 'workflow/version'