diff --git a/Changelog.md b/Changelog.md
index 6b45149864..5900c773c8 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -50,6 +50,7 @@ __Bugfixes__
- Fixes possible error for a combi boiler system.
- Fixes error if modeling a ground-to-air heat pump with a separate backup heating system.
- Fixes default CFIS fan power during ventilation only mode.
+- Fixes a bug that potentially oversizes heat pumps when detailed performance capacity fractions are provided.
## OpenStudio-HPXML v1.8.1
diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml
index f834f1337d..819304b94d 100644
--- a/HPXMLtoOpenStudio/measure.xml
+++ b/HPXMLtoOpenStudio/measure.xml
@@ -3,8 +3,8 @@
3.1
hpxm_lto_openstudio
b1543b30-9465-45ff-ba04-1d1f85e763bc
- aab4ee31-48b7-4f7a-bfc0-1d8edf16961d
- 2024-10-22T03:59:34Z
+ e7d819f6-fda2-4bf2-b6c3-cd1ff3adb569
+ 2024-10-22T17:43:11Z
D8922A73
HPXMLtoOpenStudio
HPXML to OpenStudio Translator
@@ -393,7 +393,7 @@
hvac_sizing.rb
rb
resource
- BEF6DAA5
+ CD77F9C7
internal_gains.rb
@@ -693,7 +693,7 @@
test_hvac_sizing.rb
rb
test
- 822ACA5D
+ C88CFFFC
test_lighting.rb
diff --git a/HPXMLtoOpenStudio/resources/hvac_sizing.rb b/HPXMLtoOpenStudio/resources/hvac_sizing.rb
index 6acc08d3cf..d35a98c61d 100644
--- a/HPXMLtoOpenStudio/resources/hvac_sizing.rb
+++ b/HPXMLtoOpenStudio/resources/hvac_sizing.rb
@@ -2530,11 +2530,14 @@ def self.adjust_outdoor_condition_var_speed(outdoor_temp, hvac_sys, mode)
max_rated_dp = detailed_performance_data.find { |dp| dp.outdoor_temperature == rated_odb && dp.capacity_description == HPXML::CapacityDescriptionMaximum }
if max_rated_dp.capacity.nil?
property = :capacity_fraction_of_nominal
+ # Should use nominal instead of maximum
+ capacity_nominal = 1.0
else
property = :capacity
+ # Should use nominal instead of maximum
+ capacity_nominal = (mode == :clg) ? hvac_sys.cooling_capacity : hvac_sys.heating_capacity
end
- capacity_max = detailed_performance_data.find { |dp| dp.outdoor_temperature == rated_odb && dp.capacity_description == HPXML::CapacityDescriptionMaximum }.send(property)
- odb_adj = HVAC.interpolate_to_odb_table_point(detailed_performance_data, HPXML::CapacityDescriptionMaximum, outdoor_temp, property) / capacity_max
+ odb_adj = HVAC.interpolate_to_odb_table_point(detailed_performance_data, HPXML::CapacityDescriptionMaximum, outdoor_temp, property) / capacity_nominal
end
return odb_adj
end
diff --git a/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb b/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb
index 44deb9f4bf..c1317f888d 100644
--- a/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb
+++ b/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb
@@ -1153,6 +1153,7 @@ def test_autosizing_factors
htg_cap_orig = hpxml_bldg.heat_pumps[0].heating_capacity
clg_cap_orig = hpxml_bldg.heat_pumps[0].cooling_capacity
backup_htg_cap_orig = hpxml_bldg.heat_pumps[0].backup_heating_capacity
+
# apply autosizing factor
hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance-autosize.xml')
hpxml_bldg.heat_pumps[0].backup_heating_capacity = nil
@@ -1345,6 +1346,35 @@ def test_autosizing_limits
end
end
+ def test_detailed_performance_autosizing
+ args_hash = {}
+ args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
+
+ # Test heat pump w/ detailed performance
+ hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance-autosize.xml')
+ hpxml_bldg.header.heat_pump_sizing_methodology = HPXML::HeatPumpSizingMaxLoad
+ hpxml_bldg.heat_pumps[0].backup_heating_capacity = nil
+ XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
+ _model, _hpxml, hpxml_bldg = _test_measure(args_hash)
+ htg_cap_orig = hpxml_bldg.heat_pumps[0].heating_capacity
+ clg_cap_orig = hpxml_bldg.heat_pumps[0].cooling_capacity
+ backup_htg_cap_orig = hpxml_bldg.heat_pumps[0].backup_heating_capacity
+
+ # Test heat pump w/ detailed performance when maximum fractions are over 1.0 at rated temperature
+ hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-var-speed-detailed-performance-autosize.xml')
+ hpxml_bldg.header.heat_pump_sizing_methodology = HPXML::HeatPumpSizingMaxLoad
+ hpxml_bldg.heat_pumps[0].backup_heating_capacity = nil
+ hpxml_bldg.heat_pumps[0].heating_capacity = nil
+ hpxml_bldg.heat_pumps[0].cooling_capacity = nil
+ hpxml_bldg.heat_pumps[0].heating_detailed_performance_data.find { |dp| dp.outdoor_temperature == HVAC::AirSourceHeatRatedODB && dp.capacity_description == HPXML::CapacityDescriptionMaximum }.capacity_fraction_of_nominal = 1.2
+ hpxml_bldg.heat_pumps[0].cooling_detailed_performance_data.find { |dp| dp.outdoor_temperature == HVAC::AirSourceCoolRatedODB && dp.capacity_description == HPXML::CapacityDescriptionMaximum }.capacity_fraction_of_nominal = 1.1
+ XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
+ _model, _hpxml, hpxml_bldg = _test_measure(args_hash)
+ assert_equal(hpxml_bldg.heat_pumps[0].heating_capacity, htg_cap_orig)
+ assert_equal(hpxml_bldg.heat_pumps[0].cooling_capacity, clg_cap_orig)
+ assert_equal(hpxml_bldg.heat_pumps[0].backup_heating_capacity, backup_htg_cap_orig)
+ end
+
def test_manual_j_detailed_sizing_inputs
# Run base
args_hash = {}