Improve MaxLoad sizing methodology#2235
Conversation
…HPXML into maxload_sizing # Conflicts: # HPXMLtoOpenStudio/measure.xml
…HPXML into maxload_sizing # Conflicts: # HPXMLtoOpenStudio/measure.xml # workflow/tests/base_results/results_simulations_bills.csv # workflow/tests/base_results/results_simulations_energy.csv # workflow/tests/base_results/results_simulations_loads.csv # workflow/tests/base_results/results_simulations_misc.csv
There was a problem hiding this comment.
Pull request overview
Refactors air-source heat-pump sizing to improve MaxLoad calculations and account for HERS-adjusted capacity when sizing supplemental backup heat.
Changes:
- Selects MaxLoad capacity from independently calculated heating and cooling capacities.
- Applies HERS capacity adjustments before supplemental backup sizing.
- Updates documentation, tests, metadata, and simulation baselines.
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
HPXMLtoOpenStudio/resources/hvac_sizing.rb |
Refactors heat-pump capacity sizing. |
HPXMLtoOpenStudio/tests/test_hvac_sizing.rb |
Adjusts sizing methodology test coverage. |
HPXMLtoOpenStudio/measure.xml |
Updates measure metadata and checksums. |
docs/source/workflow_inputs.rst |
Clarifies air-source applicability. |
Changelog.md |
Records the MaxLoad fix. |
workflow/tests/base_results/results_hers_hvac.csv |
Updates HERS HVAC baselines. |
workflow/tests/base_results/results_simulations_misc.csv |
Updates miscellaneous simulation baselines. |
workflow/tests/base_results/results_simulations_loads.csv |
Updates load baselines. |
workflow/tests/base_results/results_simulations_energy.csv |
Updates energy baselines. |
workflow/tests/base_results/results_simulations_bills.csv |
Updates utility-bill baselines. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…HPXML into maxload_sizing # Conflicts: # HPXMLtoOpenStudio/measure.xml # workflow/tests/base_results/results_simulations_bills.csv # workflow/tests/base_results/results_simulations_energy.csv # workflow/tests/base_results/results_simulations_misc.csv
| if hpxml_bldg.header.heat_pump_sizing_methodology == HPXML::HeatPumpSizingMaxLoad | ||
| # MaxLoad sizing methodology: autosized heat pumps have their nominal capacity | ||
| # sized based on the larger of heating/cooling design loads, while taking into | ||
| # account the heat pump's reduced capacity at the design temperature, such that | ||
| # no backup heating should be necessary. | ||
| hp_capacities = [] | ||
| hp_capacities << hvac_sizings.Cool_Capacity if hvac_heating.fraction_cool_load_served > 0 | ||
| hp_capacities << heat_cap_rated if hvac_heating.fraction_heat_load_served > 0 | ||
| hp_capacity = hp_capacities.max | ||
| if hvac_heating.fraction_cool_load_served > 0 | ||
| scaling_factor = hp_capacity / hvac_sizings.Cool_Capacity | ||
| hvac_sizings.Cool_Capacity = hp_capacity | ||
| hvac_sizings.Cool_Capacity_Sens *= scaling_factor | ||
| hvac_sizings.Cool_Airflow *= scaling_factor | ||
| end | ||
| if hvac_heating.fraction_heat_load_served > 0 | ||
| hvac_sizings.Heat_Capacity = hp_capacity | ||
| end |
There was a problem hiding this comment.
All MaxLoad code moved to here (which only applies to air-source HPs). At this point, we have the autosized cooling capacity as determined by Manual J/S. Then we compare that to the heating capacity needed to meet the full heating load, choose the larger of the two, and bump up capacities/airflows as needed.
| end | ||
|
|
||
| return heating_load | ||
| if hpxml_bldg.header.heat_pump_sizing_methodology == HPXML::HeatPumpSizingHERS |
There was a problem hiding this comment.
Moved the existing HERS code to here so that it applies before we determine the backup heating capacity (needed when HeatPumpBackupSizingMethodology="supplemental"). This fixes a small unrelated bug.
| end | ||
| elsif cool_cap_adj_factor.nil? # Heat pump has no cooling | ||
| # Size equal to heating design load (arbitrary) | ||
| hvac_sizings.Heat_Capacity = hvac_sizings.Heat_Load |
There was a problem hiding this comment.
Should this be heating_load instead of hvac_sizings.Heat_Load (here and elsewhere)?
Or maybe we should remove this path and make sure that cool_cap_adj_factor is always defined?
| denver-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons-sizing-methodology-MaxLoad-backup-emergency.xml,53765.0,53765.0,23884.0,1613.0,1613.0 | ||
| denver-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons-sizing-methodology-MaxLoad-backup-supplemental.xml,53765.0,53765.0,23884.0,1613.0,1613.0 | ||
| denver-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons-sizing-methodology-MaxLoad-backup-emergency.xml,38589.0,38589.0,23884.0,1158.0,1158.0 | ||
| denver-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons-sizing-methodology-MaxLoad-backup-supplemental.xml,38589.0,38589.0,23884.0,1158.0,1158.0 |
There was a problem hiding this comment.
Consider adding another sample file (for simulation results).
| if hpxml_bldg.header.heat_pump_sizing_methodology == HPXML::HeatPumpSizingMaxLoad | ||
| # Size based on heating, taking into account reduced heat pump capacity at the design temperature | ||
| hvac_sizings.Cool_Capacity = heat_cap_rated | ||
| # Size based on cooling, but with ACCA oversizing allowances for heating | ||
| load_shr = hvac_sizings.Cool_Load_Sens / hvac_sizings.Cool_Load_Tot | ||
| if ((weather.data.HDD65F / weather.data.CDD50F) < 2.0) || (load_shr < 0.95) | ||
| # Mild winter or has a latent cooling load | ||
| hvac_sizings.Cool_Capacity = [(oversize_limit * hvac_sizings.Cool_Load_Tot) / cool_cap_adj_factor, heat_cap_rated].min | ||
| else | ||
| # Size based on cooling, but with ACCA oversizing allowances for heating | ||
| load_shr = hvac_sizings.Cool_Load_Sens / hvac_sizings.Cool_Load_Tot | ||
| if ((weather.data.HDD65F / weather.data.CDD50F) < 2.0) || (load_shr < 0.95) | ||
| # Mild winter or has a latent cooling load | ||
| hvac_sizings.Cool_Capacity = [(oversize_limit * hvac_sizings.Cool_Load_Tot) / cool_cap_adj_factor, heat_cap_rated].min | ||
| else | ||
| # Cold winter and no latent cooling load (add a ton rule applies) | ||
| hvac_sizings.Cool_Capacity = [(hvac_sizings.Cool_Load_Tot + oversize_delta) / cool_cap_adj_factor, heat_cap_rated].min | ||
| end | ||
| # Cold winter and no latent cooling load (add a ton rule applies) | ||
| hvac_sizings.Cool_Capacity = [(hvac_sizings.Cool_Load_Tot + oversize_delta) / cool_cap_adj_factor, heat_cap_rated].min |
There was a problem hiding this comment.
Looks like a lot of changes but really just removed any if hpxml_bldg.header.heat_pump_sizing_methodology == HPXML::HeatPumpSizingMaxLoad branches.
| # Test that the supplemental heating capacity is reduced when we switch | ||
| # from ACCA to HERS sizing methodology (which increases the HP capacity) |
There was a problem hiding this comment.
Found this unrelated bug and added a test to show it now works as expected.
Pull Request Description
Closes #2226.
This also fixes the case where
HeatPumpSizingMethodology="HERS"andHeatPumpBackupSizingMethodology="supplemental"are used together. If the HP heating capacity was increased due to the HERS methodology, the supplemental heating capacity is now reduced accordingly.Checklist
Not all may apply:
EPvalidator.sch) has been updatedopenstudio tasks.rb update_hpxmls)HPXMLtoOpenStudio/tests/test*.rband/orworkflow/tests/test*.rb)openstudio tasks.rb update_measureshas been run