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

1""" 

2Methods for calculating pure component properties from: 

3 

4http://www.chemsep.org/downloads/docs/book.htm 

5 

6IDAES naming conventions followed for compatibility with modular property packages 

7""" 

8 

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 

13 

14class ChemSep(object): 

15 

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") 

24 

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") 

30 

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") 

36 

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") 

42 

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") 

48 

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 ) 

59 

60 units = b.params.get_metadata().derived_units 

61 return pyunits.convert(cp, units.HEAT_CAPACITY_MOLE) 

62 

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) 

69 

70 if cobj.parent_block().config.include_enthalpy_of_formation: 

71 

72 units = cobj.parent_block().get_metadata().derived_units 

73 

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") 

79 

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) 

85 

86 units = b.params.get_metadata().derived_units 

87 

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 ) 

93 

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 ) 

104 

105 return h 

106 

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) 

113 

114 units = cobj.parent_block().get_metadata().derived_units 

115 

116 cobj.entr_mol_form_vap_comp_ref = Var( 

117 doc="Vapor phase molar entropy of formation", 

118 units=units.ENTROPY_MOLE, 

119 ) 

120 

121 set_param_from_config(cobj, param="entr_mol_form_vap_comp_ref") 

122 

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) 

128 

129 units = b.params.get_metadata().derived_units 

130 

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 ) 

141 

142 return s 

143 

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") 

152 

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") 

158 

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") 

164 

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 

172 

173 units = b.params.get_metadata().derived_units 

174 return pyunits.convert(psat, to_units=units.PRESSURE) 

175 

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") 

184 

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") 

190 

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") 

196 

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") 

202 

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") 

208 

209 @staticmethod 

210 def return_expression(b, cobj, T): 

211 # Specific heat capacity 

212 T = pyunits.convert(T, to_units=pyunits.K) 

213 

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 ) 

223 

224 units = b.params.get_metadata().derived_units 

225 return pyunits.convert(cp, units.HEAT_CAPACITY_MOLE) 

226 

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) 

232 

233 if cobj.parent_block().config.include_enthalpy_of_formation: 

234 units = cobj.parent_block().get_metadata().derived_units 

235 

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") 

241 

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) 

247 

248 units = b.params.get_metadata().derived_units 

249 

250 def integrand(T): 

251 return ChemSep.cp_mol_liq_comp.return_expression(b, cobj, T) 

252 

253 h = ( 

254 pyunits.convert( 

255 quad(integrand, Tr, T) + Tr, 

256 units.ENERGY_MOLE, 

257 ) 

258 ) 

259 

260 return h 

261 

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) 

267 

268 units = cobj.parent_block().get_metadata().derived_units 

269 

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") 

275 

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) 

281 

282 units = b.params.get_metadata().derived_units 

283 

284 def integrand(T): 

285 return ChemSep.cp_mol_liq_comp.return_expression(b, cobj, T) 

286 

287 s = ( 

288 pyunits.convert( 

289 quad(integrand, Tr, T)/T + Tr, 

290 units.ENERGY_MOLE, 

291 ) 

292 ) 

293 

294 return s 

295 

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") 

304 

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") 

310 

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") 

316 

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") 

322 

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") 

328 

329 @staticmethod 

330 def return_expression(b, cobj, T): 

331 # Molar density 

332 Tr = pyunits.convert(b.params.temperature_ref, to_units=pyunits.K) 

333 

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 ) 

343 

344 units = b.params.get_metadata().derived_units 

345 return pyunits.convert(rho, units.MOLAR_DENSITY)