Cantera  3.0.0
Loading...
Searching...
No Matches
PDSS_HKFT.cpp
Go to the documentation of this file.
1/**
2 * @file PDSS_HKFT.cpp
3 * Definitions for the class PDSS_HKFT (pressure dependent standard state)
4 * which handles calculations for a single species in a phase using the
5 * HKFT standard state
6 * (see @ref pdssthermo and class @link Cantera::PDSS_HKFT PDSS_HKFT@endlink).
7 */
8
9// This file is part of Cantera. See License.txt in the top-level directory or
10// at https://cantera.org/license.txt for license and copyright information.
11
16#include "cantera/base/global.h"
17
18namespace Cantera
19{
20// Set the default to error exit if there is an input file inconsistency
22
24{
25 m_pres = OneAtm;
26 m_units.setDefaults({"cm", "gmol", "cal", "bar"});
27}
28
30{
31 // Ok we may change this evaluation method in the future.
32 double h = gibbs_mole() + m_temp * entropy_mole();
33 return h;
34}
35
37{
38 warn_deprecated("PDSS_HKFT::enthalpy_mole2", "To be removed after Cantera 3.0");
39 double enthTRPR = m_Mu0_tr_pr + 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
40 return deltaH() + enthTRPR;
41}
42
44{
45 return enthalpy_RT() - molarVolume() * m_pres;
46}
47
49{
50 return m_units.convertTo(m_Entrop_tr_pr, "J/kmol") + deltaS();
51}
52
54{
55 return m_Mu0_tr_pr + deltaG();
56}
57
58double PDSS_HKFT::cp_mole() const
59{
60 double pbar = m_pres * 1.0E-5;
61 double c1term = m_c1;
62 double c2term = m_c2 / (m_temp - 228.) / (m_temp - 228.);
63 double a3term = -m_a3 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp * (pbar - m_presR_bar);
64 double a4term = -m_a4 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp
65 * log((2600. + pbar)/(2600. + m_presR_bar));
66
67 double omega_j;
68 double domega_jdT;
69 double d2omega_jdT2;
70 if (m_charge_j == 0.0) {
71 omega_j = m_omega_pr_tr;
72 domega_jdT = 0.0;
73 d2omega_jdT2 = 0.0;
74 } else {
75 double nu = 166027;
76 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
77 double gval = gstar(m_temp, m_pres, 0);
78 double dgvaldT = gstar(m_temp, m_pres, 1);
79 double d2gvaldT2 = gstar(m_temp, m_pres, 2);
80
81 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
82 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
83 double d2r_e_jdT2 = fabs(m_charge_j) * d2gvaldT2;
84 double r_e_j2 = r_e_j * r_e_j;
85
86 double charge2 = m_charge_j * m_charge_j;
87 double r_e_H = 3.082 + gval;
88 double r_e_H2 = r_e_H * r_e_H;
89 omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
90 domega_jdT = nu * (-(charge2 / r_e_j2 * dr_e_jdT)
91 +(m_charge_j / r_e_H2 * dgvaldT));
92 d2omega_jdT2 = nu * (2.0*charge2*dr_e_jdT*dr_e_jdT/(r_e_j2*r_e_j) - charge2*d2r_e_jdT2/r_e_j2
93 -2.0*m_charge_j*dgvaldT*dgvaldT/(r_e_H2*r_e_H) + m_charge_j*d2gvaldT2 /r_e_H2);
94 }
95
96 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
97 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
98 double Y = drelepsilondT / (relepsilon * relepsilon);
99 double d2relepsilondT2 = m_waterProps->relEpsilon(m_temp, m_pres, 2);
100
101 double X = d2relepsilondT2 / (relepsilon* relepsilon) - 2.0 * relepsilon * Y * Y;
102 double Z = -1.0 / relepsilon;
103
104 double yterm = 2.0 * m_temp * Y * domega_jdT;
105 double xterm = omega_j * m_temp * X;
106 double otterm = m_temp * d2omega_jdT2 * (Z + 1.0);
107 double rterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
108
109 double Cp_calgmol = c1term + c2term + a3term + a4term + yterm + xterm + otterm + rterm;
110
111 return m_units.convertTo(Cp_calgmol, "J/kmol");
112}
113
115{
116 // Initially do all calculations in (cal/gmol/Pa)
117
118 double a1term = m_a1 * 1.0E-5;
119 double a2term = m_a2 / (2600.E5 + m_pres);
120 double a3term = m_a3 * 1.0E-5/ (m_temp - 228.);
121 double a4term = m_a4 / (m_temp - 228.) / (2600.E5 + m_pres);
122
123 double omega_j;
124 double domega_jdP;
125 if (m_charge_j == 0.0) {
126 omega_j = m_omega_pr_tr;
127 domega_jdP = 0.0;
128 } else {
129 double nu = 166027.;
130 double charge2 = m_charge_j * m_charge_j;
131 double r_e_j_pr_tr = charge2 / (m_omega_pr_tr/nu + m_charge_j/3.082);
132
133 double gval = gstar(m_temp, m_pres, 0);
134 double dgvaldP = gstar(m_temp, m_pres, 3);
135
136 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
137 double r_e_H = 3.082 + gval;
138
139 omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
140 double dr_e_jdP = fabs(m_charge_j) * dgvaldP;
141 domega_jdP = - nu * (charge2 / (r_e_j * r_e_j) * dr_e_jdP)
142 + nu * m_charge_j / (r_e_H * r_e_H) * dgvaldP;
143 }
144
145 double drelepsilondP = m_waterProps->relEpsilon(m_temp, m_pres, 3);
146 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
147 double Q = drelepsilondP / (relepsilon * relepsilon);
148 double Z = -1.0 / relepsilon;
149 double wterm = - domega_jdP * (Z + 1.0);
150 double qterm = - omega_j * Q;
151 double molVol_calgmolPascal = a1term + a2term + a3term + a4term + wterm + qterm;
152
153 // Convert to m**3 / kmol from (cal/gmol/Pa)
154 return m_units.convertTo(molVol_calgmolPascal, "J/kmol");
155}
156
157double PDSS_HKFT::density() const
158{
159 return m_mw / molarVolume();
160}
161
163{
164 double m_psave = m_pres;
166 double ee = gibbs_RT();
167 m_pres = m_psave;
168 return ee;
169}
170
172{
173 double m_psave = m_pres;
175 double hh = enthalpy_RT();
176 m_pres = m_psave;
177 return hh;
178}
179
181{
182 double m_psave = m_pres;
184 double ee = entropy_R();
185 m_pres = m_psave;
186 return ee;
187}
188
190{
191 double m_psave = m_pres;
193 double ee = cp_R();
194 m_pres = m_psave;
195 return ee;
196}
197
199{
200 double m_psave = m_pres;
202 double ee = molarVolume();
203 m_pres = m_psave;
204 return ee;
205}
206
207void PDSS_HKFT::setState_TP(double temp, double pres)
208{
209 setTemperature(temp);
210 setPressure(pres);
211}
212
214{
216 if (m_input.hasKey("h0")) {
217 m_deltaH_formation_tr_pr = m_input.convert("h0", "cal/gmol");
218 }
219 if (m_input.hasKey("g0")) {
220 m_deltaG_formation_tr_pr = m_input.convert("g0", "cal/gmol");
221 }
222 if (m_input.hasKey("s0")) {
223 m_Entrop_tr_pr = m_input.convert("s0", "cal/gmol/K");
224 }
225 auto& units = m_input.units();
226 if (m_input.hasKey("a")) {
227 auto& a = m_input["a"].asVector<AnyValue>(4);
228 m_a1 = units.convert(a[0], "cal/gmol/bar");
229 m_a2 = units.convert(a[1], "cal/gmol");
230 m_a3 = units.convert(a[2], "cal*K/gmol/bar");
231 m_a4 = units.convert(a[3], "cal*K/gmol");
232 }
233 if (m_input.hasKey("c")) {
234 auto& c = m_input["c"].asVector<AnyValue>(2);
235 m_c1 = units.convert(c[0], "cal/gmol/K");
236 m_c2 = units.convert(c[1], "cal*K/gmol");
237 }
238 if (m_input.hasKey("omega")) {
239 m_omega_pr_tr = m_input.convert("omega", "cal/gmol");
240 }
241
242 // Ok, if we are missing one, then we construct its value from the other two.
243 // This code has been internally verified.
245 if (std::isnan(m_deltaH_formation_tr_pr)) {
247 double Hcalc = m_Mu0_tr_pr + 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
248 m_deltaH_formation_tr_pr = m_units.convertFrom(Hcalc, "J/kmol");
249 } else if (std::isnan(m_deltaG_formation_tr_pr)) {
250 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
251 m_Mu0_tr_pr = DHjmol - 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
253 double tmp = m_Mu0_tr_pr;
255 double totalSum = m_Mu0_tr_pr - tmp;
256 m_Mu0_tr_pr = tmp;
257 m_deltaG_formation_tr_pr = m_units.convertFrom(m_Mu0_tr_pr - totalSum, "J/kmol");
258 } else if (std::isnan(m_Entrop_tr_pr)) {
260 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
261 m_Entrop_tr_pr = m_units.convertFrom((DHjmol - m_Mu0_tr_pr) / 298.15, "J/kmol");
262 }
263
264 m_waterSS = &dynamic_cast<PDSS_Water&>(*m_tp->providePDSS(0));
265
266 // Section to initialize m_Z_pr_tr and m_Y_pr_tr
267 m_temp = 273.15 + 25.;
268 m_pres = OneAtm;
269 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
272 m_Z_pr_tr = -1.0 / relepsilon;
273 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
274 m_Y_pr_tr = drelepsilondT / (relepsilon * relepsilon);
275 m_waterProps = make_unique<WaterProps>(m_waterSS);
276 m_presR_bar = OneAtm / 1.0E5;
277 m_presR_bar = 1.0;
279
280 // Ok, we have mu. Let's check it against the input value
281 // of DH_F to see that we have some internal consistency
282 double Hcalc = m_Mu0_tr_pr + 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
283 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
284
285 // If the discrepancy is greater than 100 cal gmol-1, print
286 // an error and exit.
287 if (fabs(Hcalc -DHjmol) > m_units.convertTo(100, "J/kmol")) {
288 string sname = m_tp->speciesName(m_spindex);
290 throw CanteraError("PDSS_HKFT::initThermo", "For {}, DHjmol is"
291 " not consistent with G and S: {} vs {} J/kmol",
292 sname, Hcalc, m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol"));
293 } else {
294 warn_user("PDSS_HKFT::initThermo",
295 "DHjmol for {} is not consistent with G and S: calculated {} "
296 "vs input {} J/kmol; continuing with consistent DHjmol = {}",
297 sname, Hcalc, m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol"),
298 Hcalc);
299 m_deltaH_formation_tr_pr = m_units.convertFrom(Hcalc, "J/kmol");
300 }
301 }
302 double nu = 166027;
303 double r_e_j_pr_tr;
304 if (m_charge_j != 0.0) {
305 r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
306 } else {
307 r_e_j_pr_tr = 0.0;
308 }
309
310 if (m_charge_j == 0.0) {
311 m_domega_jdT_prtr = 0.0;
312 } else {
313 double gval = gstar(m_temp, m_pres, 0);
314 double dgvaldT = gstar(m_temp, m_pres, 1);
315 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
316 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
317 m_domega_jdT_prtr = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
318 + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
319 }
320}
321
322void PDSS_HKFT::setDeltaH0(double dh0) {
323 m_deltaH_formation_tr_pr = m_units.convertFrom(dh0, "J/kmol");
324}
325
326void PDSS_HKFT::setDeltaG0(double dg0) {
327 m_deltaG_formation_tr_pr = m_units.convertFrom(dg0, "J/kmol");
328}
329
330void PDSS_HKFT::setS0(double s0) {
331 m_Entrop_tr_pr = m_units.convertFrom(s0, "J/kmol/K");
332}
333
334void PDSS_HKFT::set_a(double* a) {
335 m_a1 = m_units.convertFrom(a[0], "J/kmol/Pa");
336 m_a2 = m_units.convertFrom(a[1], "J/kmol");
337 m_a3 = m_units.convertFrom(a[2], "J*K/kmol/Pa");
338 m_a4 = m_units.convertFrom(a[3], "J*K/kmol");
339}
340
341void PDSS_HKFT::set_c(double* c) {
342 m_c1 = m_units.convertFrom(c[0], "J/kmol/K");
343 m_c2 = m_units.convertFrom(c[1], "J*K/kmol");
344}
345
346void PDSS_HKFT::setOmega(double omega) {
347 m_omega_pr_tr = m_units.convertFrom(omega, "J/kmol");
348}
349
351{
352 PDSS::getParameters(eosNode);
353 eosNode["model"] = "HKFT";
354 eosNode["h0"].setQuantity(m_deltaH_formation_tr_pr, "cal/gmol");
355 eosNode["g0"].setQuantity(m_deltaG_formation_tr_pr, "cal/gmol");
356 eosNode["s0"].setQuantity(m_Entrop_tr_pr, "cal/gmol/K");
357
358 vector<AnyValue> a(4), c(2);
359 a[0].setQuantity(m_a1, "cal/gmol/bar");
360 a[1].setQuantity(m_a2, "cal/gmol");
361 a[2].setQuantity(m_a3, "cal*K/gmol/bar");
362 a[3].setQuantity(m_a4, "cal*K/gmol");
363 eosNode["a"] = std::move(a);
364
365 c[0].setQuantity(m_c1, "cal/gmol/K");
366 c[1].setQuantity(m_c2, "cal*K/gmol");
367 eosNode["c"] = std::move(c);
368
369 eosNode["omega"].setQuantity(m_omega_pr_tr, "cal/gmol");
370}
371
372double PDSS_HKFT::deltaH() const
373{
374 warn_deprecated("PDSS_HKFT::deltaH", "To be removed after Cantera 3.0");
375 double pbar = m_pres * 1.0E-5;
376 double c1term = m_c1 * (m_temp - 298.15);
377 double a1term = m_a1 * (pbar - m_presR_bar);
378 double a2term = m_a2 * log((2600. + pbar)/(2600. + m_presR_bar));
379 double c2term = -m_c2 * (1.0/(m_temp - 228.) - 1.0/(298.15 - 228.));
380 double a3tmp = (2.0 * m_temp - 228.)/ (m_temp - 228.) /(m_temp - 228.);
381 double a3term = m_a3 * a3tmp * (pbar - m_presR_bar);
382 double a4term = m_a4 * a3tmp * log((2600. + pbar)/(2600. + m_presR_bar));
383 double omega_j;
384 double domega_jdT;
385 if (m_charge_j == 0.0) {
386 omega_j = m_omega_pr_tr;
387 domega_jdT = 0.0;
388 } else {
389 double nu = 166027;
390 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
391 double gval = gstar(m_temp, m_pres, 0);
392 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
393 double dgvaldT = gstar(m_temp, m_pres, 1);
394 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
395 omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
396 domega_jdT = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
397 + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
398 }
399
400 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
401 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
402
403 double Y = drelepsilondT / (relepsilon * relepsilon);
404 double Z = -1.0 / relepsilon;
405
406 double yterm = m_temp * omega_j * Y;
407 double yrterm = - 298.15 * m_omega_pr_tr * m_Y_pr_tr;
408
409 double wterm = - omega_j * (Z + 1.0);
410 double wrterm = + m_omega_pr_tr * (m_Z_pr_tr + 1.0);
411
412 double otterm = m_temp * domega_jdT * (Z + 1.0);
413 double otrterm = - m_temp * m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
414
415 double deltaH_calgmol = c1term + a1term + a2term + c2term + a3term + a4term
416 + yterm + yrterm + wterm + wrterm + otterm + otrterm;
417
418 return m_units.convertTo(deltaH_calgmol, "J/kmol");
419}
420
421double PDSS_HKFT::deltaG() const
422{
423 double pbar = m_pres * 1.0E-5;
424 double sterm = - m_Entrop_tr_pr * (m_temp - 298.15);
425 double c1term = -m_c1 * (m_temp * log(m_temp/298.15) - (m_temp - 298.15));
426 double a1term = m_a1 * (pbar - m_presR_bar);
427 double a2term = m_a2 * log((2600. + pbar)/(2600. + m_presR_bar));
428 double c2term = -m_c2 * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.)) * (228. - m_temp)/228.
429 - m_temp / (228.*228.) * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
430 double a3term = m_a3 / (m_temp - 228.) * (pbar - m_presR_bar);
431 double a4term = m_a4 / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
432
433 double omega_j;
434 if (m_charge_j == 0.0) {
435 omega_j = m_omega_pr_tr;
436 } else {
437 double nu = 166027;
438 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
439 double gval = gstar(m_temp, m_pres, 0);
440 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
441 omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
442 }
443
444 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
445 double Z = -1.0 / relepsilon;
446 double wterm = - omega_j * (Z + 1.0);
447 double wrterm = m_omega_pr_tr * (m_Z_pr_tr + 1.0);
448 double yterm = m_omega_pr_tr * m_Y_pr_tr * (m_temp - 298.15);
449 double deltaG_calgmol = sterm + c1term + a1term + a2term + c2term + a3term + a4term + wterm + wrterm + yterm;
450
451 return m_units.convertTo(deltaG_calgmol, "J/kmol");
452}
453
454double PDSS_HKFT::deltaS() const
455{
456 double pbar = m_pres * 1.0E-5;
457
458 double c1term = m_c1 * log(m_temp/298.15);
459 double c2term = -m_c2 / 228. * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.))
460 + 1.0 / 228. * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
461 double a3term = m_a3 / (m_temp - 228.) / (m_temp - 228.) * (pbar - m_presR_bar);
462 double a4term = m_a4 / (m_temp - 228.) / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
463
464 double omega_j;
465 double domega_jdT;
466 if (m_charge_j == 0.0) {
467 omega_j = m_omega_pr_tr;
468 domega_jdT = 0.0;
469 } else {
470 double nu = 166027;
471 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
472 double gval = gstar(m_temp, m_pres, 0);
473 double dgvaldT = gstar(m_temp, m_pres, 1);
474 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
475 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
476 omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
477 domega_jdT = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
478 + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
479 }
480
481 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
482 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
483 double Y = drelepsilondT / (relepsilon * relepsilon);
484 double Z = -1.0 / relepsilon;
485 double wterm = omega_j * Y;
486 double wrterm = - m_omega_pr_tr * m_Y_pr_tr;
487 double otterm = domega_jdT * (Z + 1.0);
488 double otrterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
489 double deltaS_calgmol = c1term + c2term + a3term + a4term + wterm + wrterm + otterm + otrterm;
490
491 return m_units.convertTo(deltaS_calgmol, "J/kmol/K");
492}
493
494double PDSS_HKFT::ag(const double temp, const int ifunc) const
495{
496 static double ag_coeff[3] = { -2.037662, 5.747000E-3, -6.557892E-6};
497 if (ifunc == 0) {
498 return ag_coeff[0] + ag_coeff[1] * temp + ag_coeff[2] * temp * temp;
499 } else if (ifunc == 1) {
500 return ag_coeff[1] + ag_coeff[2] * 2.0 * temp;
501 }
502 if (ifunc != 2) {
503 return 0.0;
504 }
505 return ag_coeff[2] * 2.0;
506}
507
508double PDSS_HKFT::bg(const double temp, const int ifunc) const
509{
510 static double bg_coeff[3] = { 6.107361, -1.074377E-2, 1.268348E-5};
511 if (ifunc == 0) {
512 return bg_coeff[0] + bg_coeff[1] * temp + bg_coeff[2] * temp * temp;
513 } else if (ifunc == 1) {
514 return bg_coeff[1] + bg_coeff[2] * 2.0 * temp;
515 }
516 if (ifunc != 2) {
517 return 0.0;
518 }
519 return bg_coeff[2] * 2.0;
520}
521
522double PDSS_HKFT::f(const double temp, const double pres, const int ifunc) const
523{
524 static double af_coeff[3] = { 3.666666E1, -0.1504956E-9, 0.5107997E-13};
525 double TC = temp - 273.15;
526 double presBar = pres / 1.0E5;
527
528 if (TC < 155.0) {
529 return 0.0;
530 }
531 TC = std::min(TC, 355.0);
532 if (presBar > 1000.) {
533 return 0.0;
534 }
535
536 double T1 = (TC-155.0)/300.;
537 double p2 = (1000. - presBar) * (1000. - presBar);
538 double p3 = (1000. - presBar) * p2;
539 double p4 = p2 * p2;
540 double fac2 = af_coeff[1] * p3 + af_coeff[2] * p4;
541 if (ifunc == 0) {
542 return pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0) * fac2;
543 } else if (ifunc == 1) {
544 return (4.8 * pow(T1,3.8) + 16.0 * af_coeff[0] * pow(T1, 15.0)) / 300. * fac2;
545 } else if (ifunc == 2) {
546 return (4.8 * 3.8 * pow(T1,2.8) + 16.0 * 15.0 * af_coeff[0] * pow(T1, 14.0)) / (300. * 300.) * fac2;
547 } else if (ifunc == 3) {
548 double fac1 = pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0);
549 fac2 = - (3.0 * af_coeff[1] * p2 + 4.0 * af_coeff[2] * p3)/ 1.0E5;
550 return fac1 * fac2;
551 } else {
552 throw NotImplementedError("PDSS_HKFT::f");
553 }
554}
555
556double PDSS_HKFT::g(const double temp, const double pres, const int ifunc) const
557{
558 double afunc = ag(temp, 0);
559 double bfunc = bg(temp, 0);
560 m_waterSS->setState_TP(temp, pres);
562 // density in gm cm-3
563 double dens = m_densWaterSS * 1.0E-3;
564 double gval = afunc * pow((1.0-dens), bfunc);
565 if (dens >= 1.0) {
566 return 0.0;
567 }
568 if (ifunc == 0) {
569 return gval;
570 } else if (ifunc == 1 || ifunc == 2) {
571 double afuncdT = ag(temp, 1);
572 double bfuncdT = bg(temp, 1);
573 double alpha = m_waterSS->thermalExpansionCoeff();
574
575 double fac1 = afuncdT * gval / afunc;
576 double fac2 = bfuncdT * gval * log(1.0 - dens);
577 double fac3 = gval * alpha * bfunc * dens / (1.0 - dens);
578
579 double dgdt = fac1 + fac2 + fac3;
580 if (ifunc == 1) {
581 return dgdt;
582 }
583
584 double afuncdT2 = ag(temp, 2);
585 double bfuncdT2 = bg(temp, 2);
586 double dfac1dT = dgdt * afuncdT / afunc + afuncdT2 * gval / afunc
587 - afuncdT * afuncdT * gval / (afunc * afunc);
588 double ddensdT = - alpha * dens;
589 double dfac2dT = bfuncdT2 * gval * log(1.0 - dens)
590 + bfuncdT * dgdt * log(1.0 - dens)
591 - bfuncdT * gval /(1.0 - dens) * ddensdT;
592 double dalphadT = m_waterSS->dthermalExpansionCoeffdT();
593 double dfac3dT = dgdt * alpha * bfunc * dens / (1.0 - dens)
594 + gval * dalphadT * bfunc * dens / (1.0 - dens)
595 + gval * alpha * bfuncdT * dens / (1.0 - dens)
596 + gval * alpha * bfunc * ddensdT / (1.0 - dens)
597 + gval * alpha * bfunc * dens / ((1.0 - dens) * (1.0 - dens)) * ddensdT;
598
599 return dfac1dT + dfac2dT + dfac3dT;
600 } else if (ifunc == 3) {
601 double beta = m_waterSS->isothermalCompressibility();
602 return - bfunc * gval * dens * beta / (1.0 - dens);
603 } else {
604 throw NotImplementedError("PDSS_HKFT::g");
605 }
606 return 0.0;
607}
608
609double PDSS_HKFT::gstar(const double temp, const double pres, const int ifunc) const
610{
611 double gval = g(temp, pres, ifunc);
612 double fval = f(temp, pres, ifunc);
613 double res = gval - fval;
614 return res;
615}
616
617double PDSS_HKFT::LookupGe(const string& elemName)
618{
619 size_t iE = m_tp->elementIndex(elemName);
620 if (iE == npos) {
621 throw CanteraError("PDSS_HKFT::LookupGe", "element " + elemName + " not found");
622 }
623 double geValue = m_tp->entropyElement298(iE);
624 if (geValue == ENTROPY298_UNKNOWN) {
625 throw CanteraError("PDSS_HKFT::LookupGe",
626 "element " + elemName + " does not have a supplied entropy298");
627 }
628 return geValue * -298.15;
629}
630
632{
633 // Ok let's get the element compositions and conversion factors.
634 double totalSum = 0.0;
635 for (size_t m = 0; m < m_tp->nElements(); m++) {
636 double na = m_tp->nAtoms(m_spindex, m);
637 if (na > 0.0) {
638 totalSum += na * LookupGe(m_tp->elementName(m));
639 }
640 }
641 // Add in the charge
642 if (m_charge_j != 0.0) {
643 totalSum -= m_charge_j * LookupGe("H");
644 }
645 double dg = m_units.convertTo(m_deltaG_formation_tr_pr, "J/kmol");
646 //! Store the result into an internal variable.
647 m_Mu0_tr_pr = dg + totalSum;
648}
649
650void PDSS_HKFT::reportParams(size_t& kindex, int& type, double* const c,
651 double& minTemp_, double& maxTemp_,
652 double& refPressure_) const
653{
654 // Fill in the first part
655 PDSS::reportParams(kindex, type, c, minTemp_, maxTemp_,
656 refPressure_);
657
660 c[2] = m_Mu0_tr_pr;
661 c[3] = m_Entrop_tr_pr;
662 c[4] = m_a1;
663 c[5] = m_a2;
664 c[6] = m_a3;
665 c[7] = m_a4;
666 c[8] = m_c1;
667 c[9] = m_c2;
668 c[10] = m_omega_pr_tr;
669}
670
671}
#define ENTROPY298_UNKNOWN
Number indicating we don't know the entropy of the element in its most stable state at 298....
Definition Elements.h:85
Declarations for the class PDSS_HKFT (pressure dependent standard state) which handles calculations f...
Implementation of a pressure dependent standard state virtual function for a Pure Water Phase (see Sp...
Header file for a derived class of ThermoPhase that handles variable pressure standard state methods ...
A map of string keys to values whose type can vary at runtime.
Definition AnyMap.h:427
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition AnyMap.cpp:1423
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
Definition AnyMap.h:630
double convert(const string &key, const string &units) const
Convert the item stored by the given key to the units specified in units.
Definition AnyMap.cpp:1535
A wrapper for a variable whose type is determined at runtime.
Definition AnyMap.h:86
Base class for exceptions thrown by Cantera classes.
An error indicating that an unimplemented function has been called.
void setOmega(double omega)
Set omega [J/kmol].
double molarVolume() const override
Return the molar volume at standard state.
static int s_InputInconsistencyErrorExit
Static variable determining error exiting.
Definition PDSS_HKFT.h:346
double m_Y_pr_tr
y = dZdT = 1/(esp*esp) desp/dT at 298.15 and 1 bar
Definition PDSS_HKFT.h:327
double m_a4
Input a4 coefficient (cal K gmol-1)
Definition PDSS_HKFT.h:315
double enthalpy_mole() const override
Return the molar enthalpy in units of J kmol-1.
Definition PDSS_HKFT.cpp:29
unique_ptr< WaterProps > m_waterProps
Pointer to the water property calculator.
Definition PDSS_HKFT.h:270
double deltaS() const
Main routine that actually calculates the entropy difference between the reference state at Tr,...
double f(const double temp, const double pres, const int ifunc=0) const
Difference function f appearing in the formulation.
double deltaH() const
Routine that actually calculates the enthalpy difference between the reference state at Tr,...
size_t m_spindex
Index of this species within the parent phase.
Definition PDSS_HKFT.h:142
double m_densWaterSS
density of standard-state water. internal temporary variable
Definition PDSS_HKFT.h:267
double LookupGe(const string &elemName)
Function to look up Element Free Energies.
double gibbs_RT_ref() const override
Return the molar Gibbs free energy divided by RT at reference pressure.
VPStandardStateTP * m_tp
Parent VPStandardStateTP (ThermoPhase) object.
Definition PDSS_HKFT.h:141
double m_Entrop_tr_pr
Input value of S_j at Tr and Pr (cal gmol-1 K-1)
Definition PDSS_HKFT.h:303
double m_deltaG_formation_tr_pr
Input value of deltaG of Formation at Tr and Pr (cal gmol-1)
Definition PDSS_HKFT.h:279
void setDeltaG0(double dg0)
Set Gibbs free energy of formation at Pr, Tr [J/kmol].
void initThermo() override
Initialization routine.
double m_a3
Input a3 coefficient (cal K gmol-1 bar-1)
Definition PDSS_HKFT.h:312
double gstar(const double temp, const double pres, const int ifunc=0) const
Evaluate the Gstar value appearing in the HKFT formulation.
double m_charge_j
Charge of the ion.
Definition PDSS_HKFT.h:339
PDSS_HKFT()
Default Constructor.
Definition PDSS_HKFT.cpp:23
double entropy_R_ref() const override
Return the molar entropy divided by R at reference pressure.
double deltaG() const
Main routine that actually calculates the Gibbs free energy difference between the reference state at...
double enthalpy_RT_ref() const override
Return the molar enthalpy divided by RT at reference pressure.
void setS0(double s0)
Set entropy of formation at Pr, Tr [J/kmol/K].
double bg(const double temp, const int ifunc=0) const
Internal formula for the calculation of b_g()
void reportParams(size_t &kindex, int &type, double *const c, double &minTemp, double &maxTemp, double &refPressure) const override
This utility function reports back the type of parameterization and all of the parameters for the spe...
void getParameters(AnyMap &eosNode) const override
Store the parameters needed to reconstruct a copy of this PDSS object.
double m_c2
Input c2 coefficient (cal K gmol-1)
Definition PDSS_HKFT.h:321
double m_presR_bar
Reference pressure is 1 atm in units of bar= 1.0132.
Definition PDSS_HKFT.h:333
void set_a(double *a)
Set "a" coefficients (array of 4 elements).
double intEnergy_mole() const override
Return the molar internal Energy in units of J kmol-1.
Definition PDSS_HKFT.cpp:43
double m_domega_jdT_prtr
small value that is not quite zero
Definition PDSS_HKFT.h:336
double entropy_mole() const override
Return the molar entropy in units of J kmol-1 K-1.
Definition PDSS_HKFT.cpp:48
double m_omega_pr_tr
Input omega_pr_tr coefficient(cal gmol-1)
Definition PDSS_HKFT.h:324
double enthalpy_mole2() const
Return the molar enthalpy in units of J kmol-1.
Definition PDSS_HKFT.cpp:36
double g(const double temp, const double pres, const int ifunc=0) const
function g appearing in the formulation
void setState_TP(double temp, double pres) override
Set the internal temperature and pressure.
double m_Z_pr_tr
Z = -1 / relEpsilon at 298.15 and 1 bar.
Definition PDSS_HKFT.h:330
void convertDGFormation()
Translate a Gibbs free energy of formation value to a NIST-based Chemical potential.
double cp_mole() const override
Return the molar const pressure heat capacity in units of J kmol-1 K-1.
Definition PDSS_HKFT.cpp:58
double m_deltaH_formation_tr_pr
Input value of deltaH of Formation at Tr and Pr (cal gmol-1)
Definition PDSS_HKFT.h:288
double m_a1
Input a1 coefficient (cal gmol-1 bar-1)
Definition PDSS_HKFT.h:306
double ag(const double temp, const int ifunc=0) const
Internal formula for the calculation of a_g()
double density() const override
Return the standard state density at standard state.
double gibbs_mole() const override
Return the molar Gibbs free energy in units of J kmol-1.
Definition PDSS_HKFT.cpp:53
double m_c1
Input c1 coefficient (cal gmol-1 K-1)
Definition PDSS_HKFT.h:318
double molarVolume_ref() const override
Return the molar volume at reference pressure.
PDSS_Water * m_waterSS
Water standard state calculator.
Definition PDSS_HKFT.h:262
double m_Mu0_tr_pr
Value of the Absolute Gibbs Free Energy NIST scale at T_r and P_r.
Definition PDSS_HKFT.h:297
void set_c(double *c)
Set "c" coefficients (array of 2 elements).
double m_a2
Input a2 coefficient (cal gmol-1)
Definition PDSS_HKFT.h:309
void setDeltaH0(double dh0)
Set enthalpy of formation at Pr, Tr [J/kmol].
double cp_R_ref() const override
Return the molar heat capacity divided by R at reference pressure.
double cp_R() const override
Return the molar const pressure heat capacity divided by RT.
Definition PDSS.cpp:220
double entropy_R() const override
Return the standard state entropy divided by RT.
Definition PDSS.cpp:210
double enthalpy_RT() const override
Return the standard state molar enthalpy divided by RT.
Definition PDSS.cpp:205
double gibbs_RT() const override
Return the molar Gibbs free energy divided by RT.
Definition PDSS.cpp:215
Class for the liquid water pressure dependent standard state.
Definition PDSS_Water.h:50
double thermalExpansionCoeff() const override
Return the volumetric thermal expansion coefficient. Units: 1/K.
double isothermalCompressibility() const
Returns the isothermal compressibility. Units: 1/Pa.
double dthermalExpansionCoeffdT() const
Return the derivative of the volumetric thermal expansion coefficient.
void setState_TP(double temp, double pres) override
Set the internal temperature and pressure.
double pref_safe(double temp) const
Returns a reference pressure value that can be safely calculated by the underlying real equation of s...
double density() const override
Return the standard state density at standard state.
virtual void reportParams(size_t &kindex, int &type, double *const c, double &minTemp, double &maxTemp, double &refPressure) const
This utility function reports back the type of parameterization and all of the parameters for the spe...
Definition PDSS.cpp:191
virtual void setTemperature(double temp)
Set the internal temperature.
Definition PDSS.cpp:162
virtual void initThermo()
Initialization routine.
Definition PDSS.h:418
double m_temp
Current temperature used by the PDSS object.
Definition PDSS.h:449
double m_pres
State of the system - pressure.
Definition PDSS.h:452
double m_mw
Molecular Weight of the species.
Definition PDSS.h:464
AnyMap m_input
Input data supplied via setParameters.
Definition PDSS.h:468
virtual void getParameters(AnyMap &eosNode) const
Store the parameters needed to reconstruct a copy of this PDSS object.
Definition PDSS.h:427
virtual void setPressure(double pres)
Sets the pressure in the object.
Definition PDSS.cpp:152
size_t elementIndex(const string &name) const
Return the index of element named 'name'.
Definition Phase.cpp:55
string speciesName(size_t k) const
Name of the species with index k.
Definition Phase.cpp:151
double nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
Definition Phase.cpp:103
size_t nElements() const
Number of elements.
Definition Phase.cpp:30
string elementName(size_t m) const
Name of the element with index m.
Definition Phase.cpp:49
double charge(size_t k) const
Dimensionless electrical charge of a single molecule of species k The charge is normalized by the the...
Definition Phase.h:638
double entropyElement298(size_t m) const
Entropy of the element in its standard state at 298 K and 1 bar.
Definition Phase.cpp:75
double convertFrom(double value, const string &src) const
Convert value from the specified src units to units appropriate for this unit system (defined by setD...
Definition Units.cpp:570
double convertTo(double value, const string &dest) const
Convert value to the specified dest units from the appropriate units for this unit system (defined by...
Definition Units.cpp:554
void setDefaults(std::initializer_list< string > units)
Set the default units to convert from when explicit units are not provided.
Definition Units.cpp:428
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
const double OneAtm
One atmosphere [Pa].
Definition ct_defs.h:96
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition global.h:267
Namespace for the Cantera kernel.
Definition AnyMap.cpp:564
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:195
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
Definition AnyMap.cpp:1926
Contains declarations for string manipulation functions within Cantera.