Changing HPHW efficiency does not impact results on a large building

Hello,

I have a large complex model for a multifamily residential building. I am looking to compare the energy impacts of different water heating configurations (gas, hphw, geothermal). This is a building with over 400 units. When I run the script with the gas water heater and an efficiency of 0.8, the EUI is about 20. When I run the script with a HPHW and an efficiency of 3.5, the “water systems” EUI reduces to about 15. However, when I change the efficiency of the HPHW, either lower or higher, the “water systems” EUI barely moves. I even ran a scenario changing the efficiency to 15 and the result was nearly the same.

I tried to troubleshoot the Energy Plus report, thinking that maybe the backup heater is doing al

Proposed HPWH w Separate Zones (619.0 KB)

l the work, or some other issue, but I haven’t been able to come up with a solution.

I would think changing the COP could have significant impacts for a system this large.

Any thoughts?

I’ve been working with @jdelaneybbb on this model and we traced the root cause, verified it with three single-variable test runs on a 104-unit residential slice (~85k sf) of the same building, and found a practical workaround. Posting the full picture since this affects anyone using the HeatPump_WaterHeater SHW template at central-plant scale.

Root cause

The HPWH template’s DX compressor is left at a residential-scale default capacity and never scales to the load.

In honeybee_openstudio/shw.py (shw_system_to_openstudio), the HeatPump_WaterHeater branch creates the DX coil and sets its COP — but never sets its rated capacity:

python

heat_pump = OSCoilWaterHeatingAirToWaterHeatPump(os_model)
heat_pump.setName('SHW HPWH DX Coil')
heat_pump.setRatedCOP(shw.heater_efficiency)   # COP is set
# rated heating capacity: never touched → OpenStudio SDK constructor default

The OpenStudio SDK constructor for CoilWaterHeatingAirToWaterHeatPump hardcodes setRatedHeatingCapacity(4000.0), and the exported IDF confirms it:

Coil:WaterHeating:AirToWaterHeatPump:Pumped,
  SHW HPWH DX Coil,
  4000,        !- Rated Heating Capacity {W}
  3.5,         !- Rated COP {W/W}

Meanwhile the tank’s backup element is set to 1,000,000 W at Heater Thermal Efficiency 1.0. From our Run 1 results, the annual thermal DHW demand for this slice averages roughly 50 kW — so a 4 kW compressor running flat-out covers less than 8% of demand, and the electric resistance element quietly does the rest.

That’s why changing the COP — even to 15 — barely moves the result: it only applies to that small slice of the load. Your original numbers are consistent with this: gas @ 0.8 → ~20 EUI implies ~16 EUI of thermal demand, and the HPWH result of ~15 is what a COP ≈ 1.0 electricity bill looks like (blended effective COP of ~8% at 3.5 + ~92% at 1.0 ≈ 1.05).

Test runs (single-variable, same model)

Run Change Water Systems (kBtu/ft²) Effective COP
1 Stock HPWH template, COP 3.5 17.6 ≈ 1.0
2 Coil capacity 4 kW → ~200 kW via IDF edit 14.8 ≈ 1.1
3 Tank Heater Thermal Efficiency 1.0 → 3.5 via IDF edit 5.2 = demand ÷ 3.5 ✓

Run 2 is worth understanding: fixing the capacity alone doesn’t fix it. Honeybee requires ambient_condition to be a Room for the HeatPump type, and OpenStudio’s addToThermalZone then forces the wrapper’s Inlet Air Configuration to ZoneAirOnly — the evaporator breathes one zone’s air. At COP 3.5, a ~200 kW coil extracts ~143 kW of heat from that zone, which quickly crashes the zone below the wrapper’s Minimum Inlet Air Temperature for Compressor Operation (10°C, set by the OpenStudio constructor). The compressor locks out and the model falls back to resistance. A central-scale air-source HPWH can’t live in a mechanical room, and E+ faithfully models that.

The workaround we’re using: IDF edit via HB Run IDF

(a) Simplest and verified (Run 3): model the system as Electric_WaterHeater, export the IDF, and edit the WaterHeater:Mixed object’s Heater Thermal Efficiency from 1.0 to your seasonal COP (e.g., 3.5), then re-run through HB Run IDF. Alternatively, leave the model untouched and divide the Water Systems result by your COP in post-processing — same arithmetic.

Note on why the IDF edit is needed: honeybee-energy’s validation asserts heater_efficiency <= 1 for non-HeatPump equipment types, so a COP can’t be entered upstream. EnergyPlus itself accepts it — the IDD field for WaterHeater:Mixed Heater Thermal Efficiency has \minimum> 0.0 and no maximum. Run 3 returns exactly demand ÷ 3.5, as expected.

This effectively models a constant-COP plant, which is a reasonable first approximation for a central heat pump or ground-source system in an early-stage comparison.

(b) For a dynamic COP (closer to a real central air-source or ground-source plant): keep the HPWH object, set a realistic coil capacity, and change the WaterHeater:HeatPump:PumpedCondenser Inlet Air Configuration from ZoneAirOnly to Schedule with a constant-temperature inlet schedule (~15–20°C) — effectively an infinite constant-temperature source, and a reasonable ground-source approximation. Be aware this is a multi-field edit: with Schedule you must also supply an Inlet Air Humidity Schedule (fraction RH) alongside the temperature schedule, blank the Inlet Air Zone Name, replace the zone exhaust/inlet air nodes with plain unique node names, and resolve the Compressor Location (and zone equipment list) accordingly — otherwise E+ will throw severe errors.

Suggested library fixes

  1. Size the DX coil’s Rated Heating Capacity from total_flow, which is already passed into shw_system_to_openstudio for tank sizing. (This field is not autosizable in EnergyPlus — only the evaporator air flow and condenser water flow are — so the capacity would need to be computed, e.g., sized to recover the tank volume over a target period at the loop ΔT.)

  2. Consider a source-temperature input for central plants, so the evaporator isn’t necessarily tied to a single zone’s air. @chris