Water-source heat pump boiler (WSHPB)¶
Source side is a water loop with a prescribed inlet temperature; sink side is the shared DHW tank demand model used by the boiler families.
Overview¶
The class is tmhp.WaterSourceHeatPumpBoiler. Unlike GSHPB,
WSHPB takes the source-side inlet temperature as a schedule input
rather than computing it from a borehole field — useful when the
water loop is driven by an external simulation or measurement.
Base usage¶
from tmhp import WaterSourceHeatPumpBoiler
wshpb = WaterSourceHeatPumpBoiler(ref="R134a")
result = wshpb.analyze_steady(
T_tank_w=55.0,
T_source=15.0, # water-loop inlet [°C]
Q_ref_tank=8_000,
)
Source-side mechanics¶
A single ε-NTU heat exchanger between the refrigerant evaporator and the source-side water loop. No borehole transient — the loop inlet temperature is whatever the user supplies.
Sink-side mechanics¶
Shared DHW tank sink with an implicit per-step energy balance.
API reference¶
Ground source heat pump boiler — physics-based cycle model.
Resolves a vapour-compression refrigerant cycle coupled to a borehole heat exchanger (BHE) on the evaporator side and a lumped-capacitance hot-water tank on the condenser side. At each time step the model finds the minimum-power operating point via 1D Brent optimization over the evaporator approach temperature difference, while the condenser temperature is solved analytically.
Borehole thermal response is tracked with pygfunction-based multi-borehole g-functions, enabling robust long-term ground temperature drift modeling.
- class tmhp.water_source_heat_pump_boiler.WaterSourceHeatPumpBoiler(ref='R410A', V_cmp_ref=None, eta_cmp_isen=None, eta_cmp_vol=None, eta_cmp=None, UA_tank_hx=None, UA_water=None, T0=0.0, Ts=16.0, T_tank_w_upper_bound=65.0, T_tank_w_lower_bound=55.0, T_mix_w_out=40.0, T_tank_w_in=15.0, hp_capacity=8000.0, dV_mix_w_out_max=0.0001, r0=0.2, H=0.8, x_shell=0.01, x_ins=0.05, k_shell=25, k_ins=0.03, h_o=15, N_1=1, N_2=1, B=6.0, D_b=0, H_b=200, r_b=0.08, R_b=None, k_g=1.5, k_p=0.4, r_out=0.016, r_in=0.013, D_s=0.025, dV_b_f_lpm=24, k_s=2.0, c_s=800, rho_s=2000, E_pmp=200, v_river=0.5, dT_superheat=5.0, dT_subcool=5.0, tank_always_full=True, prevent_simultaneous_flow=False, tank_level_lower_bound=0.5, tank_level_upper_bound=1.0, dV_tank_w_in_refill=0.001, hp_on_schedule=None, stc=None, pv=None, uv=None, t_max_s=31536000, dt_s=3600, T_sur=20.0, dT_hx_min=0.5, PR_cycle_min=1.5, PR_cycle_max=20.0, rps_min=10.0, rps_max=150.0, *, refrigerant=None, V_disp_cmp=None, UA_tank=None, UA_cond_design=None, UA_evap_design=None)[source]¶
Bases:
objectWater source heat pump boiler with BHE and lumped-tank model.
The refrigerant cycle is resolved via CoolProp with user-specified superheat / subcool margins. An optimizer minimises total cycle electrical input subject to NTU-based evaporator constraints and analytical condenser temperature relations.
- Parameters:
ref (
str)V_cmp_ref (
Optional[float])eta_cmp_isen (
Union[float,Callable,None])eta_cmp_vol (
Union[float,Callable,None])eta_cmp (
Union[float,Callable,None])UA_tank_hx (
Optional[float])UA_water (
Optional[float])T0 (
float)Ts (
float)T_tank_w_upper_bound (
float)T_tank_w_lower_bound (
float)T_mix_w_out (
float)T_tank_w_in (
float)hp_capacity (
float)dV_mix_w_out_max (
float)r0 (
float)H (
float)x_shell (
float)x_ins (
float)k_shell (
float)k_ins (
float)h_o (
float)N_1 (
int)N_2 (
int)B (
float)D_b (
float)H_b (
float)r_b (
float)R_b (
Optional[float])k_g (
float)k_p (
float)r_out (
float)r_in (
float)D_s (
float)dV_b_f_lpm (
float)k_s (
float)c_s (
float)rho_s (
float)E_pmp (
float)v_river (
float)dT_superheat (
float)dT_subcool (
float)tank_always_full (
bool)prevent_simultaneous_flow (
bool)tank_level_lower_bound (
float)tank_level_upper_bound (
float)dV_tank_w_in_refill (
float)hp_on_schedule (
Optional[list[tuple[float,float]]])stc (
Optional[SolarThermalCollector])t_max_s (
float)dt_s (
float)T_sur (
float)dT_hx_min (
float)PR_cycle_min (
float)PR_cycle_max (
float)rps_min (
float)rps_max (
float)refrigerant (
Optional[str])V_disp_cmp (
Optional[float])UA_tank (
Optional[float])UA_cond_design (
Optional[float])UA_evap_design (
Optional[float])
- __init__(ref='R410A', V_cmp_ref=None, eta_cmp_isen=None, eta_cmp_vol=None, eta_cmp=None, UA_tank_hx=None, UA_water=None, T0=0.0, Ts=16.0, T_tank_w_upper_bound=65.0, T_tank_w_lower_bound=55.0, T_mix_w_out=40.0, T_tank_w_in=15.0, hp_capacity=8000.0, dV_mix_w_out_max=0.0001, r0=0.2, H=0.8, x_shell=0.01, x_ins=0.05, k_shell=25, k_ins=0.03, h_o=15, N_1=1, N_2=1, B=6.0, D_b=0, H_b=200, r_b=0.08, R_b=None, k_g=1.5, k_p=0.4, r_out=0.016, r_in=0.013, D_s=0.025, dV_b_f_lpm=24, k_s=2.0, c_s=800, rho_s=2000, E_pmp=200, v_river=0.5, dT_superheat=5.0, dT_subcool=5.0, tank_always_full=True, prevent_simultaneous_flow=False, tank_level_lower_bound=0.5, tank_level_upper_bound=1.0, dV_tank_w_in_refill=0.001, hp_on_schedule=None, stc=None, pv=None, uv=None, t_max_s=31536000, dt_s=3600, T_sur=20.0, dT_hx_min=0.5, PR_cycle_min=1.5, PR_cycle_max=20.0, rps_min=10.0, rps_max=150.0, *, refrigerant=None, V_disp_cmp=None, UA_tank=None, UA_cond_design=None, UA_evap_design=None)[source]¶
- Parameters:
ref (
str)V_cmp_ref (
Optional[float])eta_cmp_isen (
Union[float,Callable,None])eta_cmp_vol (
Union[float,Callable,None])eta_cmp (
Union[float,Callable,None])UA_tank_hx (
Optional[float])UA_water (
Optional[float])T0 (
float)Ts (
float)T_tank_w_upper_bound (
float)T_tank_w_lower_bound (
float)T_mix_w_out (
float)T_tank_w_in (
float)hp_capacity (
float)dV_mix_w_out_max (
float)r0 (
float)H (
float)x_shell (
float)x_ins (
float)k_shell (
float)k_ins (
float)h_o (
float)N_1 (
int)N_2 (
int)B (
float)D_b (
float)H_b (
float)r_b (
float)R_b (
Optional[float])k_g (
float)k_p (
float)r_out (
float)r_in (
float)D_s (
float)dV_b_f_lpm (
float)k_s (
float)c_s (
float)rho_s (
float)E_pmp (
float)v_river (
float)dT_superheat (
float)dT_subcool (
float)tank_always_full (
bool)prevent_simultaneous_flow (
bool)tank_level_lower_bound (
float)tank_level_upper_bound (
float)dV_tank_w_in_refill (
float)hp_on_schedule (
Optional[list[tuple[float,float]]])stc (
Optional[SolarThermalCollector])t_max_s (
float)dt_s (
float)T_sur (
float)dT_hx_min (
float)PR_cycle_min (
float)PR_cycle_max (
float)rps_min (
float)rps_max (
float)refrigerant (
Optional[str])V_disp_cmp (
Optional[float])UA_tank (
Optional[float])UA_cond_design (
Optional[float])UA_evap_design (
Optional[float])
- analyze_dynamic(simulation_period_sec, dt_s, T_tank_w_init_C, dhw_usage_schedule, T0_schedule, I_DN_schedule=None, I_dH_schedule=None, T_sup_w_schedule=None, T_source_w_schedule=None, tank_level_init=1.0, result_save_csv_path=None, T_sur_schedule=None)[source]¶
- Parameters:
simulation_period_sec (
float)dt_s (
float)T_tank_w_init_C (
float)tank_level_init (
float)
- Return type:
DataFrame
- analyze_steady(T_tank_w, T_source, Q_ref_tank, T0=0.0, *, return_dict=True)[source]¶
Run a steady-state performance snapshot.
Evaluates the refrigerant cycle at a given operating point (
T_tank_w,T_source,Q_ref_tank) without solving the tank energy balance or tracking dynamic flows.- Parameters:
T_tank_w (float) – Tank water temperature [°C] — treated as a given input.
T_source (float) – Source fluid temperature entering the heat pump [°C].
Q_ref_tank (float) – Target condenser heat rate [W].
T0 (float) – Dead-state / outdoor-air temperature [°C] (for exergy calculations).
return_dict (bool) – If
Truereturn dict; else single-row DataFrame.
- Returns:
Cycle state plus diagnostic flags. Notable keys:
"converged"(bool) — True only when the HX optimisation and the SciPy optimiser both succeeded."failure_reason"(str) — one of"none","cycle_invalid","hx_not_converged", or"optimizer_failed".
Important: like GSHPB, WSHPB often reports
failure_reason="hx_not_converged"on realistic operating points; the cycle numbers (E_cmp,Q_ref_tank,cop_sys, …) are still usable in that case. Only"cycle_invalid"forces an off-mode fallback (E_cmp=0, COP=NaN). Branch onE_cmp [W] > 0rather thanfailure_reason == "none"if you only want to discard truly broken results.- Return type:
dict | pd.DataFrame