Air-source heat pump (ASHP — space conditioning)¶
ASHP conditions a building zone (heating + cooling) rather than charging a DHW tank. The refrigerant cycle and outdoor-coil source side are shared with ASHPB; what differs is the load side — a zone energy balance instead of a tank.
Overview¶
The class is tmhp.AirSourceHeatPump. Use it when the heat
pump’s job is space conditioning rather than DHW production.
Base usage¶
from tmhp import AirSourceHeatPump
ashp = AirSourceHeatPump(ref="R32")
# See API reference below for the full constructor and
# analyze_steady / analyze_dynamic signatures.
Source-side mechanics¶
Identical to ASHPB — outdoor coil with variable-speed fan, ε-NTU air-side heat exchanger.
Sink-side mechanics¶
A zone temperature / load proxy stands in for the building. The heat pump’s condenser duty serves whatever space-heating or cooling load the caller supplies; there is no tank energy balance.
API reference¶
Air source heat pump — physics-based cycle model with indoor unit.
Resolves a vapour-compression refrigerant cycle coupled to
an outdoor-air heat exchanger and an indoor-air heat exchanger.
Supports both cooling (Q_r_iu > 0) and heating (Q_r_iu < 0)
modes. The indoor load Q_r_iu is imposed externally each timestep.
At each time step the model finds the minimum-power operating point (compressor + indoor fan + outdoor fan) via bounded 2-D optimisation over the evaporator and condenser approach temperature differences.
Architecture mirrors AirSourceHeatPumpBoiler — uses the same
shared utility functions (calc_ref_state, calc_HX_perf_for_target_heat,
calc_fan_power_from_dV_fan) and the same postprocess_exergy()
pattern, but replaces the tank energy balance with direct air-side
heat exchange at the indoor unit.
- class tmhp.air_source_heat_pump.AirSourceHeatPump(ref='R32', V_disp_cmp=0.0001, eta_cmp_isen=None, eta_cmp_vol=None, eta_cmp_mech=0.855, dT_superheat=3.0, dT_subcool=3.0, UA_cond_design=None, UA_evap_design=None, dV_ou_fan_a_design=None, dP_ou_fan_design=60.0, A_cross_ou=None, eta_ou_fan_design=0.6, dV_iu_fan_a_design=None, dP_iu_fan_design=60.0, A_cross_iu=None, eta_iu_fan_design=0.6, hp_capacity=4000.0, T_a_room=27.0, vsd_coeffs_ou=None, vsd_coeffs_iu=None)[source]¶
Bases:
objectAir source heat pump with indoor-unit air heat exchange.
The refrigerant cycle is resolved via CoolProp with user-specified superheat / subcool margins. A bounded 2-D optimiser minimises total electrical input (
E_cmp + E_iu_fan + E_ou_fan) over the evaporator and condenser approach temperatures.- Parameters:
ref (
str)V_disp_cmp (
float)eta_cmp_isen (
Union[float,Callable,None])eta_cmp_vol (
Union[float,Callable,None])eta_cmp_mech (
float|Callable)dT_superheat (
float)dT_subcool (
float)UA_cond_design (
Optional[float])UA_evap_design (
Optional[float])dV_ou_fan_a_design (
Optional[float])dP_ou_fan_design (
float)A_cross_ou (
Optional[float])eta_ou_fan_design (
float)dV_iu_fan_a_design (
Optional[float])dP_iu_fan_design (
float)A_cross_iu (
Optional[float])eta_iu_fan_design (
float)hp_capacity (
float)T_a_room (
float)vsd_coeffs_ou (
Optional[dict])vsd_coeffs_iu (
Optional[dict])
- __init__(ref='R32', V_disp_cmp=0.0001, eta_cmp_isen=None, eta_cmp_vol=None, eta_cmp_mech=0.855, dT_superheat=3.0, dT_subcool=3.0, UA_cond_design=None, UA_evap_design=None, dV_ou_fan_a_design=None, dP_ou_fan_design=60.0, A_cross_ou=None, eta_ou_fan_design=0.6, dV_iu_fan_a_design=None, dP_iu_fan_design=60.0, A_cross_iu=None, eta_iu_fan_design=0.6, hp_capacity=4000.0, T_a_room=27.0, vsd_coeffs_ou=None, vsd_coeffs_iu=None)[source]¶
- Parameters:
ref (
str)V_disp_cmp (
float)eta_cmp_isen (
Union[float,Callable,None])eta_cmp_vol (
Union[float,Callable,None])eta_cmp_mech (
float|Callable)dT_superheat (
float)dT_subcool (
float)UA_cond_design (
Optional[float])UA_evap_design (
Optional[float])dV_ou_fan_a_design (
Optional[float])dP_ou_fan_design (
float)A_cross_ou (
Optional[float])eta_ou_fan_design (
float)dV_iu_fan_a_design (
Optional[float])dP_iu_fan_design (
float)A_cross_iu (
Optional[float])eta_iu_fan_design (
float)hp_capacity (
float)T_a_room (
float)vsd_coeffs_ou (
Optional[dict])vsd_coeffs_iu (
Optional[dict])
- analyze_steady(Q_r_iu, T0, T_a_room=None, *, return_dict=True, postprocess=True, verbose=True)[source]¶
Run a steady-state performance snapshot.
- Parameters:
Q_r_iu (float) – Indoor thermal load [W]. >0 cooling, <0 heating, 0 off.
T0 (float) – Dead-state / outdoor-air temperature [°C].
T_a_room (float | None) – Room air temperature [°C]. Uses constructor default if None.
return_dict (bool) – If True return dict; else single-row DataFrame.
postprocess (bool) – If True, apply postprocess_exergy to the output.
verbose (bool) – If True, print warnings upon convergence failure.
- Returns:
Cycle state plus diagnostic flags.
Two keys are useful for branching:
"converged"(bool) — True only when the inner HX optimisation and the SciPy optimiser both succeeded."failure_reason"(str) — one of"none","cycle_invalid"(the refrigerant cycle itself was infeasible),"hx_not_converged"(cycle OK but the HX residual exceeded tolerance), or"optimizer_failed"(SciPy reportedsuccess=False).
ASHP triggers an off-mode fallback for any of the non-
"none"reasons —E_cmp [W]will be 0 and the COP keys will be NaN in that case. Treatfailure_reason != "none"as “do not trust the numbers”.- Return type:
dict | pd.DataFrame
- analyze_dynamic(simulation_period_sec, dt_s, Q_r_iu_schedule, T0_schedule, T_a_room_schedule=None, result_save_csv_path=None)[source]¶
Run a time-stepping dynamic simulation.
- Parameters:
simulation_period_sec (int) – Total simulation duration [s].
dt_s (int) – Time step size [s].
Q_r_iu_schedule (array-like) – Indoor thermal load per step [W].
T0_schedule (array-like) – Outdoor temperature per step [°C].
T_a_room_schedule (array-like | None) – Room air temperature per step [°C]. If None, uses constructor default.
result_save_csv_path (str | None) – Optional CSV output path.
- Returns:
Per-timestep result DataFrame.
- Return type:
pd.DataFrame
- postprocess_exergy(df)[source]¶
Compute ASHP-specific exergy variables.
Mirrors
AirSourceHeatPumpBoiler.postprocess_exergy()with adaptations for indoor-unit air exchange.Pipeline:
Refrigerant state-point exergy (CoolProp)
Electricity = exergy (compressor, IU fan, OU fan)
Air exergy (outdoor unit + indoor unit)
HX Carnot exergy (condenser, evaporator)
Component-level exergy destruction
Exergetic efficiency metrics
- Parameters:
df (
DataFrame)- Return type:
DataFrame