Heat Pump ModelΒΆ
Here is a simple example of how to do a heat pump cycle calculation for a simple four-component system, with very simple models for each component
[1]:
from dataclasses import dataclass
import os
import numpy as np
import scipy
import teqp
R = 8.31446261815324
k_B = 1.380649e-23
N_A = R/k_B
@dataclass
class ModelCombo:
model : object
aig: object
name: str
def get_h(self, T, rhomolar, molefrac):
Atot10 = self.model.get_Ar10(T, rhomolar, molefrac) + self.aig.get_Aig10(T, rhomolar, molefrac)
return R*T*(1+self.model.get_Ar01(T, rhomolar, molefrac) + Atot10)
def get_s(self, T, rhomolar, molefrac):
Atot10 = self.model.get_Ar10(T, rhomolar, molefrac) + self.aig.get_Aig10(T, rhomolar, molefrac)
Atot00 = self.model.get_Ar00(T, rhomolar, molefrac) + self.aig.get_Aig00(T, rhomolar, molefrac)
return R*(Atot10 - Atot00)
def get_p(self, T, rhomolar, molefrac):
return rhomolar*self.model.get_R(molefrac)*T*(1 + self.model.get_Ar01(T, rhomolar, molefrac))
def cycle(combo, anc, *, Tevap, Tcond, DELTAT_sh, DELTAT_sc, eta_comp):
"""
combo(ModelCombo): The joined model with ideal-gas and residual portions
anc : A set of ancillary functions implementing rhoL(T) and rhoV(T) methods
Tevap : Saturated vapor temperature in evaporator, in K
Tcond : Saturated vapor temperature in condenser, in K
DELTAT_sh : superheat, in K
DELTAT_sc : subcooling, in K
eta_comp : compressor efficiency
"""
model = combo.model
z = np.array([1.0])
# VLE densities,
# w/ guess values from the ancillary
rhomolar1satL, rhomolar1sat = model.pure_VLE_T(Tevap, anc.rhoL(Tevap), anc.rhoV(Tevap), 10)
rhomolar3sat, rhomolar3satV = model.pure_VLE_T(Tcond, anc.rhoL(Tcond), anc.rhoV(Tcond), 10)
p1 = combo.get_p(Tevap, rhomolar1sat, z)
p2 = combo.get_p(Tcond, rhomolar3sat, z)
# Evaporator outlet & compressor inlet @ state point 1
T1 = Tevap + DELTAT_sh
rhomolar1 = scipy.optimize.newton(lambda rho_: combo.get_p(T1, rho_, z)-p1, rhomolar1sat)
h1 = combo.get_h(T1, rhomolar1, z)
s1 = combo.get_s(T1, rhomolar1, z)
# Solve for isentropic compressor outlet
res = lambda x: [combo.get_p(x[0], x[1], z)-p2, combo.get_s(x[0], x[1], z)-s1]
T2s, rho2s = scipy.optimize.fsolve(res, [Tcond, rhomolar1sat])
h2s = combo.get_h(T2s, rho2s, z)
h2 = h1 + (h2s-h1)/eta_comp # @ state point 2
# Condenser outlet and expansion valve inlet @ state point 3
T3 = Tcond - DELTAT_sc
rhomolar3 = scipy.optimize.newton(lambda rho_: combo.get_p(T3, rho_, z)-p2, rhomolar3sat)
h3 = combo.get_h(T3, rhomolar3, z)
COP = (h1-h3)/(h2-h1)
return {
'name': combo.name,
'COP': COP,
'pevap / kPa': p1/1e3,
'pcond / kPa': p2/1e3,
'rho1 / mol/m^3': rhomolar1,
'Qvol / kJ/m^3': (h1-h3)*rhomolar1/1e3,
}
# Build the model (ideal-gas and residual)
FLD = 'R125'
path = teqp.get_datapath()+f'/dev/fluids/{FLD}.json'
assert(os.path.exists(path))
jig = teqp.convert_CoolProp_idealgas(path, 0)
combo = ModelCombo(
model=teqp.build_multifluid_model([path], ''),
aig=teqp.IdealHelmholtz([jig]),
name=FLD
)
# Generic ancillary functions from on-the-fly ancillary construction
anc = teqp.build_ancillaries(combo.model, 360, 6000, 250)
cycle(combo, anc=anc, Tevap=270, Tcond=313, DELTAT_sh=5, DELTAT_sc=5, eta_comp=0.7)
[1]:
{'name': 'R125',
'COP': np.float64(3.238624644077594),
'pevap / kPa': np.float64(606.2416455945954),
'pcond / kPa': np.float64(2001.2735289000334),
'rho1 / mol/m^3': np.float64(306.9219167132696),
'Qvol / kJ/m^3': np.float64(3287.7920883249403)}
Exercise for the reader: plot the points on a P-H diagram, showing the saturated liquid and vapor states