Coverage for backend/ahuora-compounds/ahuora_property_packages/modular/builder/data/chem_sep.py: 29%
143 statements
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2026-07-22 05:22 +0000
1"""
2Methods for calculating pure component properties from:
4http://www.chemsep.org/downloads/docs/book.htm
6IDAES naming conventions followed for compatibility with modular property packages
7"""
9from pyomo.environ import log, exp, units as pyunits
10from idaes.core.util.misc import set_param_from_config
11from pyomo.environ import Var
12from scipy.integrate import quad
14class ChemSep(object):
16 class cp_mol_ig_comp:
17 @staticmethod
18 def build_parameters(cobj):
19 cobj.cp_mol_ig_comp_coeff_A = Var(
20 doc="Parameter A for ideal gas molar heat capacity",
21 units=pyunits.J / pyunits.kilomol / pyunits.K,
22 )
23 set_param_from_config(cobj, param="cp_mol_ig_comp_coeff", index="A")
25 cobj.cp_mol_ig_comp_coeff_B = Var(
26 doc="Parameter B for ideal gas molar heat capacity",
27 units=pyunits.J / pyunits.kilomol / pyunits.K ** 2,
28 )
29 set_param_from_config(cobj, param="cp_mol_ig_comp_coeff", index="B")
31 cobj.cp_mol_ig_comp_coeff_C = Var(
32 doc="Parameter C for ideal gas molar heat capacity",
33 units=pyunits.J / pyunits.kilomol / pyunits.K ** 3,
34 )
35 set_param_from_config(cobj, param="cp_mol_ig_comp_coeff", index="C")
37 cobj.cp_mol_ig_comp_coeff_D = Var(
38 doc="Parameter D for ideal gas molar heat capacity",
39 units=pyunits.J / pyunits.kilomol / pyunits.K ** 4,
40 )
41 set_param_from_config(cobj, param="cp_mol_ig_comp_coeff", index="D")
43 cobj.cp_mol_ig_comp_coeff_E = Var(
44 doc="Parameter E for ideal gas molar heat capacity",
45 units=pyunits.J / pyunits.kilomol / pyunits.K ** 5,
46 )
47 set_param_from_config(cobj, param="cp_mol_ig_comp_coeff", index="E")
49 @staticmethod
50 def return_expression(b, cobj, T):
51 T = pyunits.convert(T, to_units=pyunits.K)
52 cp = (
53 cobj.cp_mol_ig_comp_coeff_A +
54 cobj.cp_mol_ig_comp_coeff_B*T +
55 cobj.cp_mol_ig_comp_coeff_C*T**2 +
56 cobj.cp_mol_ig_comp_coeff_D*T**3 +
57 cobj.cp_mol_ig_comp_coeff_E*T**4
58 )
60 units = b.params.get_metadata().derived_units
61 return pyunits.convert(cp, units.HEAT_CAPACITY_MOLE)
63 class enth_mol_ig_comp:
64 @staticmethod
65 def build_parameters(cobj):
66 # Required for calculating entropy
67 if not hasattr(cobj, "cp_mol_ig_comp_coeff_A"):
68 ChemSep.cp_mol_ig_comp.build_parameters(cobj)
70 if cobj.parent_block().config.include_enthalpy_of_formation:
72 units = cobj.parent_block().get_metadata().derived_units
74 cobj.enth_mol_form_vap_comp_ref = Var(
75 doc="Vapor phase molar heat of formation",
76 units=units.ENERGY_MOLE,
77 )
78 set_param_from_config(cobj, param="enth_mol_form_vap_comp_ref")
80 @staticmethod
81 def return_expression(b, cobj, T):
82 # Specific enthalpy
83 T = pyunits.convert(T, to_units=pyunits.K)
84 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K)
86 units = b.params.get_metadata().derived_units
88 h_form = (
89 cobj.enth_mol_form_vap_comp_ref
90 if b.params.config.include_enthalpy_of_formation
91 else 0 * units.ENERGY_MOLE
92 )
94 h = (
95 pyunits.convert(
96 (cobj.cp_mol_ig_comp_coeff_A * (T - Tr)
97 + (cobj.cp_mol_ig_comp_coeff_B / 2) * (T**2 - Tr**2)
98 + (cobj.cp_mol_ig_comp_coeff_C / 3) * (T**3 - Tr**3)
99 + (cobj.cp_mol_ig_comp_coeff_D / 4) * (T**4 - Tr**4)
100 + (cobj.cp_mol_ig_comp_coeff_E / 5) * (T**5 - Tr**5)),
101 units.ENERGY_MOLE,
102 ) + h_form
103 )
105 return h
107 class entr_mol_ig_comp:
108 @staticmethod
109 def build_parameters(cobj):
110 # Required for calculating enthalpy
111 if not hasattr(cobj, "cp_mol_ig_comp_coeff_A"):
112 ChemSep.cp_mol_ig_comp.build_parameters(cobj)
114 units = cobj.parent_block().get_metadata().derived_units
116 cobj.entr_mol_form_vap_comp_ref = Var(
117 doc="Vapor phase molar entropy of formation",
118 units=units.ENTROPY_MOLE,
119 )
121 set_param_from_config(cobj, param="entr_mol_form_vap_comp_ref")
123 @staticmethod
124 def return_expression(b, cobj, T):
125 # Specific entropy
126 T = pyunits.convert(T, to_units=pyunits.K)
127 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K)
129 units = b.params.get_metadata().derived_units
131 s = (
132 pyunits.convert(
133 (cobj.cp_mol_ig_comp_coeff_A * log(T / Tr)
134 + cobj.cp_mol_ig_comp_coeff_B * (T - Tr)
135 + (cobj.cp_mol_ig_comp_coeff_C / 2) * (T ** 2 - Tr ** 2)
136 + (cobj.cp_mol_ig_comp_coeff_D / 3) * (T ** 3 - Tr ** 3)
137 + (cobj.cp_mol_ig_comp_coeff_E / 4) * (T ** 4 - Tr ** 4)),
138 units.ENTROPY_MOLE,
139 ) + cobj.entr_mol_form_vap_comp_ref
140 )
142 return s
144 class pressure_sat_comp:
145 @staticmethod
146 def build_parameters(cobj):
147 cobj.pressure_sat_comp_coeff_A = Var(
148 doc="Antoine A coefficient for calculating P-sat",
149 units=pyunits.dimensionless
150 )
151 set_param_from_config(cobj, param="pressure_sat_comp_coeff", index="A")
153 cobj.pressure_sat_comp_coeff_B = Var(
154 doc="Antoine B coefficient for calculating P-sat",
155 units=pyunits.K
156 )
157 set_param_from_config(cobj, param="pressure_sat_comp_coeff", index="B")
159 cobj.pressure_sat_comp_coeff_C = Var(
160 doc="Antoine C coefficient for calculating P-sat",
161 units=pyunits.K
162 )
163 set_param_from_config(cobj, param="pressure_sat_comp_coeff", index="C")
165 @staticmethod
166 def return_expression(b, cobj, T, dT=False):
167 psat = (
168 exp(
169 cobj.pressure_sat_comp_coeff_A - cobj.pressure_sat_comp_coeff_B /
170 (pyunits.convert(T, to_units=pyunits.K) + cobj.pressure_sat_comp_coeff_C))
171 ) * pyunits.Pa
173 units = b.params.get_metadata().derived_units
174 return pyunits.convert(psat, to_units=units.PRESSURE)
176 class cp_mol_liq_comp:
177 @staticmethod
178 def build_parameters(cobj):
179 cobj.cp_mol_liq_comp_coeff_A = Var(
180 doc="Parameter A for liquid phase molar heat capacity",
181 units=pyunits.J * pyunits.kmol**-1 * pyunits.K**-1,
182 )
183 set_param_from_config(cobj, param="cp_mol_liq_comp_coeff", index="A")
185 cobj.cp_mol_liq_comp_coeff_B = Var(
186 doc="Parameter B for liquid phase molar heat capacity",
187 units=pyunits.J * pyunits.kmol**-1 * pyunits.K**-2,
188 )
189 set_param_from_config(cobj, param="cp_mol_liq_comp_coeff", index="B")
191 cobj.cp_mol_liq_comp_coeff_C = Var(
192 doc="Parameter C for liquid phase molar heat capacity",
193 units=pyunits.J * pyunits.kmol**-1 * pyunits.K**-3,
194 )
195 set_param_from_config(cobj, param="cp_mol_liq_comp_coeff", index="C")
197 cobj.cp_mol_liq_comp_coeff_D = Var(
198 doc="Parameter D for liquid phase molar heat capacity",
199 units=pyunits.J * pyunits.kmol**-1 * pyunits.K**-4,
200 )
201 set_param_from_config(cobj, param="cp_mol_liq_comp_coeff", index="D")
203 cobj.cp_mol_liq_comp_coeff_E = Var(
204 doc="Parameter E for liquid phase molar heat capacity",
205 units=pyunits.J * pyunits.kmol**-1 * pyunits.K**-5,
206 )
207 set_param_from_config(cobj, param="cp_mol_liq_comp_coeff", index="E")
209 @staticmethod
210 def return_expression(b, cobj, T):
211 # Specific heat capacity
212 T = pyunits.convert(T, to_units=pyunits.K)
214 cp = (
215 cobj.cp_mol_liq_comp_coeff_A +
216 exp(
217 cobj.cp_mol_liq_comp_coeff_B / T
218 + cobj.cp_mol_liq_comp_coeff_C
219 + cobj.cp_mol_liq_comp_coeff_D * T
220 + cobj.cp_mol_liq_comp_coeff_E * T**2
221 )
222 )
224 units = b.params.get_metadata().derived_units
225 return pyunits.convert(cp, units.HEAT_CAPACITY_MOLE)
227 class enth_mol_liq_comp:
228 @staticmethod
229 def build_parameters(cobj):
230 if not hasattr(cobj, "cp_mol_liq_comp_coeff_A"):
231 ChemSep.cp_mol_liq_comp.build_parameters(cobj)
233 if cobj.parent_block().config.include_enthalpy_of_formation:
234 units = cobj.parent_block().get_metadata().derived_units
236 cobj.enth_mol_form_liq_comp_ref = Var(
237 doc="Liquid phase molar heat of formation @ Tref",
238 units=units.ENERGY_MOLE,
239 )
240 set_param_from_config(cobj, param="enth_mol_form_liq_comp_ref")
242 @staticmethod
243 def return_expression(b, cobj, T):
244 # Specific enthalpy
245 T = pyunits.convert(T, to_units=pyunits.K)
246 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K)
248 units = b.params.get_metadata().derived_units
250 def integrand(T):
251 return ChemSep.cp_mol_liq_comp.return_expression(b, cobj, T)
253 h = (
254 pyunits.convert(
255 quad(integrand, Tr, T) + Tr,
256 units.ENERGY_MOLE,
257 )
258 )
260 return h
262 class entr_mol_liq_comp:
263 @staticmethod
264 def build_parameters(cobj):
265 if not hasattr(cobj, "cp_mol_liq_comp_coeff_A"):
266 ChemSep.cp_mol_liq_comp.build_parameters(cobj)
268 units = cobj.parent_block().get_metadata().derived_units
270 cobj.entr_mol_form_liq_comp_ref = Var(
271 doc="Liquid phase molar entropy of formation @ Tref",
272 units=units.ENTROPY_MOLE,
273 )
274 set_param_from_config(cobj, param="entr_mol_form_liq_comp_ref")
276 @staticmethod
277 def return_expression(b, cobj, T):
278 # Specific entropy
279 T = pyunits.convert(T, to_units=pyunits.K)
280 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K)
282 units = b.params.get_metadata().derived_units
284 def integrand(T):
285 return ChemSep.cp_mol_liq_comp.return_expression(b, cobj, T)
287 s = (
288 pyunits.convert(
289 quad(integrand, Tr, T)/T + Tr,
290 units.ENERGY_MOLE,
291 )
292 )
294 return s
296 class dens_mol_liq_comp:
297 @staticmethod
298 def build_parameters(cobj):
299 cobj.dens_mol_liq_comp_coeff_A = Var(
300 doc="Parameter A for liquid phase molar density",
301 units=pyunits.kmol / pyunits.m**3,
302 )
303 set_param_from_config(cobj, param="dens_mol_liq_comp_coeff", index="A")
305 cobj.dens_mol_liq_comp_coeff_B = Var(
306 doc="Parameter B for liquid phase molar density",
307 units=pyunits.dimensionless,
308 )
309 set_param_from_config(cobj, param="dens_mol_liq_comp_coeff", index="B")
311 cobj.dens_mol_liq_comp_coeff_C = Var(
312 doc="Parameter C for liquid phase molar density",
313 units=pyunits.dimensionless,
314 )
315 set_param_from_config(cobj, param="dens_mol_liq_comp_coeff", index="C")
317 cobj.dens_mol_liq_comp_coeff_D = Var(
318 doc="Parameter D for liquid phase molar density",
319 units=pyunits.dimensionless,
320 )
321 set_param_from_config(cobj, param="dens_mol_liq_comp_coeff", index="D")
323 cobj.dens_mol_liq_comp_coeff_E = Var(
324 doc="Parameter E for liquid phase molar density",
325 units=pyunits.dimensionless,
326 )
327 set_param_from_config(cobj, param="dens_mol_liq_comp_coeff", index="E")
329 @staticmethod
330 def return_expression(b, cobj, T):
331 # Molar density
332 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K)
334 rho = (
335 cobj.dens_mol_liq_comp_coeff_A * (1 - Tr) ^
336 (
337 cobj.dens_mol_liq_comp_coeff_B
338 + cobj.dens_mol_liq_comp_coeff_C * Tr
339 + cobj.dens_mol_liq_comp_coeff_D * Tr**2
340 + cobj.dens_mol_liq_comp_coeff_E * Tr**3
341 )
342 )
344 units = b.params.get_metadata().derived_units
345 return pyunits.convert(rho, units.MOLAR_DENSITY)