Skip to content

Commit 2022425

Browse files
authored
Merge pull request #1527 from NREL/1_and_2_speed_hvac_regressions
Replace HVAC inverse calculations with regressions
2 parents d741ae7 + d5d589b commit 2022425

9 files changed

+662
-1073
lines changed

Changelog.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,10 @@ __New Features__
1616
- Allows `NumberofUnits` to be used as a multiplier on dwelling unit simulation results to reduce simulation runtime.
1717
- See the [OpenStudio-HPXML documentation](https://openstudio-hpxml.readthedocs.io/en/v1.7.0/workflow_inputs.html#whole-sfa-mf-buildings) for more detail.
1818
- HVAC modeling updates:
19-
- Updated assumptions for variable-speed air conditioners, heat pumps, and mini-splits.
19+
- Updated assumptions for variable-speed air conditioners, heat pumps, and mini-splits based on NEEP data. Expect results to change, potentially significantly so depending on the scenario.
2020
- Allows detailed heating and cooling performance data (min/max COPs and capacities at different outdoor temperatures) for variable-speed systems.
2121
- Updates deep ground temperatures (used for modeling ground-source heat pumps) using L. Xing's simplified design model (2014).
22+
- Replaces inverse calculations, used to calculate COPs from rated efficiencies, with regressions for single/two-speed central ACs and ASHPs.
2223
- Output updates:
2324
- **Breaking change**: "Hot Tub" outputs renamed to "Permanent Spa".
2425
- Adds "Peak Electricity: Annual Total (W)" output.
@@ -50,6 +51,7 @@ __Bugfixes__
5051
- Fixes missing radiation exchange between window and sky when an interior/exterior window shading multiplier less than 1 exists.
5152
- Fixes monthly shallow ground temperatures (used primarily in HVAC autosizing) for the southern hemisphere.
5253
- Various HVAC sizing bugfixes and improvements.
54+
- Fixes low-speed heating COPs for some two-speed ASHPs and cooling COPs for some single-speed ACs/HPs.
5355
- BuildResidentialHPXML measure: Fixes air distribution CFA served when there is not a central system that meets 100% of the load.
5456

5557
## OpenStudio-HPXML v1.6.0

HPXMLtoOpenStudio/measure.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
<schema_version>3.1</schema_version>
44
<name>hpxm_lto_openstudio</name>
55
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
6-
<version_id>cfae944b-c977-42d1-915c-b9231c3a3fdd</version_id>
7-
<version_modified>2023-11-13T20:11:06Z</version_modified>
6+
<version_id>441f9a3f-8b7f-4b51-87b8-fc22b13ec262</version_id>
7+
<version_modified>2023-11-13T22:10:19Z</version_modified>
88
<xml_checksum>D8922A73</xml_checksum>
99
<class_name>HPXMLtoOpenStudio</class_name>
1010
<display_name>HPXML to OpenStudio Translator</display_name>
@@ -292,13 +292,13 @@
292292
<filename>hvac.rb</filename>
293293
<filetype>rb</filetype>
294294
<usage_type>resource</usage_type>
295-
<checksum>B601226F</checksum>
295+
<checksum>B014F262</checksum>
296296
</file>
297297
<file>
298298
<filename>hvac_sizing.rb</filename>
299299
<filetype>rb</filetype>
300300
<usage_type>resource</usage_type>
301-
<checksum>6458264A</checksum>
301+
<checksum>00BE0F0C</checksum>
302302
</file>
303303
<file>
304304
<filename>lighting.rb</filename>
@@ -568,7 +568,7 @@
568568
<filename>test_hvac.rb</filename>
569569
<filetype>rb</filetype>
570570
<usage_type>test</usage_type>
571-
<checksum>93FAD19F</checksum>
571+
<checksum>19EE9DA5</checksum>
572572
</file>
573573
<file>
574574
<filename>test_hvac_sizing.rb</filename>

HPXMLtoOpenStudio/resources/hvac.rb

+20-433
Large diffs are not rendered by default.

HPXMLtoOpenStudio/resources/hvac_sizing.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -2755,8 +2755,8 @@ def self.gshp_hxbore_ft_per_ton(weather, hvac_cooling_ap, bore_spacing, pipe_r_v
27552755
rtf_DesignMon_Heat = [0.25, (71.0 - weather.data.MonthlyAvgDrybulbs[heating_month]) / @htd].max
27562756
rtf_DesignMon_Cool = [0.25, (weather.data.MonthlyAvgDrybulbs[cooling_month] - 76.0) / @ctd].max
27572757

2758-
nom_length_heat = (1.0 - hvac_cooling_ap.heat_rated_eirs[0]) * (r_value_bore + r_value_ground * rtf_DesignMon_Heat) / (weather.data.DeepGroundAnnualTemp - (2.0 * hvac_cooling_ap.design_hw - hvac_cooling_ap.design_delta_t) / 2.0) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2759-
nom_length_cool = (1.0 + hvac_cooling_ap.cool_rated_eirs[0]) * (r_value_bore + r_value_ground * rtf_DesignMon_Cool) / ((2.0 * hvac_cooling_ap.design_chw + hvac_cooling_ap.design_delta_t) / 2.0 - weather.data.DeepGroundAnnualTemp) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2758+
nom_length_heat = (1.0 - 1.0 / hvac_cooling_ap.heat_rated_cops[0]) * (r_value_bore + r_value_ground * rtf_DesignMon_Heat) / (weather.data.DeepGroundAnnualTemp - (2.0 * hvac_cooling_ap.design_hw - hvac_cooling_ap.design_delta_t) / 2.0) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2759+
nom_length_cool = (1.0 + 1.0 / hvac_cooling_ap.cool_rated_cops[0]) * (r_value_bore + r_value_ground * rtf_DesignMon_Cool) / ((2.0 * hvac_cooling_ap.design_chw + hvac_cooling_ap.design_delta_t) / 2.0 - weather.data.DeepGroundAnnualTemp) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
27602760

27612761
return nom_length_heat, nom_length_cool
27622762
end

HPXMLtoOpenStudio/tests/test_hvac.rb

+10-10
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def test_central_air_conditioner_1_speed
2929
# Check cooling coil
3030
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
3131
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
32-
assert_in_epsilon(3.73, clg_coil.ratedCOP, 0.01)
32+
assert_in_epsilon(3.77, clg_coil.ratedCOP, 0.01)
3333
assert_in_epsilon(7230, clg_coil.ratedTotalCoolingCapacity.get, 0.01)
3434

3535
# Check EMS
@@ -49,7 +49,7 @@ def test_central_air_conditioner_2_speed
4949
assert_equal(1, model.getCoilCoolingDXMultiSpeeds.size)
5050
clg_coil = model.getCoilCoolingDXMultiSpeeds[0]
5151
assert_equal(2, clg_coil.stages.size)
52-
[4.95, 4.59].each_with_index do |cop, i|
52+
[4.95, 4.53].each_with_index do |cop, i|
5353
assert_in_epsilon(cop, clg_coil.stages[i].grossRatedCoolingCOP, 0.01)
5454
end
5555
[5143, 7158].each_with_index do |capacity, i|
@@ -449,13 +449,13 @@ def test_air_to_air_heat_pump_1_speed
449449
# Check cooling coil
450450
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
451451
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
452-
assert_in_epsilon(3.73, clg_coil.ratedCOP, 0.01)
452+
assert_in_epsilon(3.77, clg_coil.ratedCOP, 0.01)
453453
assert_in_epsilon(10846, clg_coil.ratedTotalCoolingCapacity.get, 0.01)
454454

455455
# Check heating coil
456456
assert_equal(1, model.getCoilHeatingDXSingleSpeeds.size)
457457
htg_coil = model.getCoilHeatingDXSingleSpeeds[0]
458-
assert_in_epsilon(3.28, htg_coil.ratedCOP, 0.01)
458+
assert_in_epsilon(3.29, htg_coil.ratedCOP, 0.01)
459459
assert_in_epsilon(10262, htg_coil.ratedTotalHeatingCapacity.get, 0.01)
460460

461461
# Check supp heating coil
@@ -527,7 +527,7 @@ def test_air_to_air_heat_pump_2_speed
527527
assert_equal(1, model.getCoilCoolingDXMultiSpeeds.size)
528528
clg_coil = model.getCoilCoolingDXMultiSpeeds[0]
529529
assert_equal(2, clg_coil.stages.size)
530-
[4.95, 4.59].each_with_index do |cop, i|
530+
[4.95, 4.53].each_with_index do |cop, i|
531531
assert_in_epsilon(cop, clg_coil.stages[i].grossRatedCoolingCOP, 0.01)
532532
end
533533
[7715, 10736].each_with_index do |clg_capacity, i|
@@ -538,7 +538,7 @@ def test_air_to_air_heat_pump_2_speed
538538
assert_equal(1, model.getCoilHeatingDXMultiSpeeds.size)
539539
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
540540
assert_equal(2, htg_coil.stages.size)
541-
[4.52, 4.08].each_with_index do |cop, i|
541+
[4.52, 3.93].each_with_index do |cop, i|
542542
assert_in_epsilon(cop, htg_coil.stages[i].grossRatedHeatingCOP, 0.01)
543543
end
544544
[7499, 10360].each_with_index do |htg_capacity, i|
@@ -810,7 +810,7 @@ def test_shared_chiller_baseboard
810810
# Check cooling coil
811811
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
812812
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
813-
assert_in_epsilon(3.85, clg_coil.ratedCOP, 0.01)
813+
assert_in_epsilon(3.62, clg_coil.ratedCOP, 0.01)
814814
refute_in_epsilon(capacity, clg_coil.ratedTotalCoolingCapacity.get, 0.01) # Uses autosized capacity
815815
end
816816

@@ -826,7 +826,7 @@ def test_shared_chiller_fan_coil
826826
# Check cooling coil
827827
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
828828
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
829-
assert_in_epsilon(3.45, clg_coil.ratedCOP, 0.01)
829+
assert_in_epsilon(3.31, clg_coil.ratedCOP, 0.01)
830830
refute_in_epsilon(capacity, clg_coil.ratedTotalCoolingCapacity.get, 0.01) # Uses autosized capacity
831831
end
832832

@@ -842,7 +842,7 @@ def test_shared_chiller_water_loop_heat_pump
842842
# Check cooling coil
843843
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
844844
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
845-
assert_in_epsilon(1.30, clg_coil.ratedCOP, 0.01)
845+
assert_in_epsilon(1.50, clg_coil.ratedCOP, 0.01)
846846
refute_in_epsilon(capacity, clg_coil.ratedTotalCoolingCapacity.get, 0.01) # Uses autosized capacity
847847
end
848848

@@ -858,7 +858,7 @@ def test_shared_cooling_tower_water_loop_heat_pump
858858
# Check cooling coil
859859
assert_equal(1, model.getCoilCoolingDXSingleSpeeds.size)
860860
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
861-
assert_in_epsilon(3.68, clg_coil.ratedCOP, 0.01)
861+
assert_in_epsilon(3.50, clg_coil.ratedCOP, 0.01)
862862
refute_in_epsilon(capacity, clg_coil.ratedTotalCoolingCapacity.get, 0.01) # Uses autosized capacity
863863
end
864864

0 commit comments

Comments
 (0)