Cantera  4.0.0a1
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 return enthalpy_RT() - molarVolume() * m_pres;
39}
40
42{
43 return m_units.convertTo(m_Entrop_tr_pr, "J/kmol") + deltaS();
44}
45
47{
48 return m_Mu0_tr_pr + deltaG();
49}
50
51double PDSS_HKFT::cp_mole() const
52{
53 double pbar = m_pres * 1.0E-5;
54 double c1term = m_c1;
55 double c2term = m_c2 / (m_temp - 228.) / (m_temp - 228.);
56 double a3term = -m_a3 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp * (pbar - m_presR_bar);
57 double a4term = -m_a4 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp
58 * log((2600. + pbar)/(2600. + m_presR_bar));
59
60 double omega_j;
61 double domega_jdT;
62 double d2omega_jdT2;
63 if (m_charge_j == 0.0) {
64 omega_j = m_omega_pr_tr;
65 domega_jdT = 0.0;
66 d2omega_jdT2 = 0.0;
67 } else {
68 double nu = 166027;
69 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
70 double gval = gstar(m_temp, m_pres, 0);
71 double dgvaldT = gstar(m_temp, m_pres, 1);
72 double d2gvaldT2 = gstar(m_temp, m_pres, 2);
73
74 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
75 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
76 double d2r_e_jdT2 = fabs(m_charge_j) * d2gvaldT2;
77 double r_e_j2 = r_e_j * r_e_j;
78
79 double charge2 = m_charge_j * m_charge_j;
80 double r_e_H = 3.082 + gval;
81 double r_e_H2 = r_e_H * r_e_H;
82 omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
83 domega_jdT = nu * (-(charge2 / r_e_j2 * dr_e_jdT)
84 +(m_charge_j / r_e_H2 * dgvaldT));
85 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
86 -2.0*m_charge_j*dgvaldT*dgvaldT/(r_e_H2*r_e_H) + m_charge_j*d2gvaldT2 /r_e_H2);
87 }
88
89 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
90 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
91 double Y = drelepsilondT / (relepsilon * relepsilon);
92 double d2relepsilondT2 = m_waterProps->relEpsilon(m_temp, m_pres, 2);
93
94 double X = d2relepsilondT2 / (relepsilon* relepsilon) - 2.0 * relepsilon * Y * Y;
95 double Z = -1.0 / relepsilon;
96
97 double yterm = 2.0 * m_temp * Y * domega_jdT;
98 double xterm = omega_j * m_temp * X;
99 double otterm = m_temp * d2omega_jdT2 * (Z + 1.0);
100 double rterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
101
102 double Cp_calgmol = c1term + c2term + a3term + a4term + yterm + xterm + otterm + rterm;
103
104 return m_units.convertTo(Cp_calgmol, "J/kmol");
105}
106
108{
109 return molarVolumeTP(m_temp, m_pres);
110}
111
112double PDSS_HKFT::density() const
113{
114 return m_mw / molarVolume();
115}
116
117double PDSS_HKFT::molarVolumeTP(double temp, double pres) const
118{
119 double a1term = m_a1 * 1.0E-5;
120 double a2term = m_a2 / (2600.E5 + pres);
121 double a3term = m_a3 * 1.0E-5 / (temp - 228.);
122 double a4term = m_a4 / (temp - 228.) / (2600.E5 + pres);
123
124 double omega_j;
125 double domega_jdP;
126 if (m_charge_j == 0.0) {
127 omega_j = m_omega_pr_tr;
128 domega_jdP = 0.0;
129 } else {
130 double nu = 166027.;
131 double charge2 = m_charge_j * m_charge_j;
132 double r_e_j_pr_tr = charge2 / (m_omega_pr_tr/nu + m_charge_j/3.082);
133
134 double gval = gstar(temp, pres, 0);
135 double dgvaldP = gstar(temp, pres, 3);
136
137 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
138 double r_e_H = 3.082 + gval;
139
140 omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
141 double dr_e_jdP = fabs(m_charge_j) * dgvaldP;
142 domega_jdP = - nu * (charge2 / (r_e_j * r_e_j) * dr_e_jdP)
143 + nu * m_charge_j / (r_e_H * r_e_H) * dgvaldP;
144 }
145
146 double drelepsilondP = m_waterProps->relEpsilon(temp, pres, 3);
147 double relepsilon = m_waterProps->relEpsilon(temp, pres, 0);
148 double Q = drelepsilondP / (relepsilon * relepsilon);
149 double Z = -1.0 / relepsilon;
150 double wterm = - domega_jdP * (Z + 1.0);
151 double qterm = - omega_j * Q;
152 double molVol_calgmolPascal = a1term + a2term + a3term + a4term + wterm + qterm;
153 return m_units.convertTo(molVol_calgmolPascal, "J/kmol");
154}
155
156double PDSS_HKFT::dVdT() const
157{
158 double dT = 1.0e-4 * m_temp;
159 double v_hi = molarVolumeTP(m_temp + dT, m_pres);
160 double v_lo = molarVolumeTP(m_temp - dT, m_pres);
161 // Restore water state modified by gstar() calls inside molarVolumeTP
164 return (v_hi - v_lo) / (2.0 * dT);
165}
166
167double PDSS_HKFT::dVdP() const
168{
169 double dP = 1.0e-4 * m_pres;
170 double v_hi = molarVolumeTP(m_temp, m_pres + dP);
171 double v_lo = molarVolumeTP(m_temp, m_pres - dP);
172 // Restore water state modified by gstar() calls inside molarVolumeTP
175 return (v_hi - v_lo) / (2.0 * dP);
176}
177
179{
180 double m_psave = m_pres;
182 double ee = gibbs_RT();
183 m_pres = m_psave;
184 return ee;
185}
186
188{
189 double m_psave = m_pres;
191 double hh = enthalpy_RT();
192 m_pres = m_psave;
193 return hh;
194}
195
197{
198 double m_psave = m_pres;
200 double ee = entropy_R();
201 m_pres = m_psave;
202 return ee;
203}
204
206{
207 double m_psave = m_pres;
209 double ee = cp_R();
210 m_pres = m_psave;
211 return ee;
212}
213
215{
216 double m_psave = m_pres;
218 double ee = molarVolume();
219 m_pres = m_psave;
220 return ee;
221}
222
223void PDSS_HKFT::setState_TP(double temp, double pres)
224{
225 setTemperature(temp);
226 setPressure(pres);
227}
228
230{
232 if (m_input.hasKey("h0")) {
233 m_deltaH_formation_tr_pr = m_input.convert("h0", "cal/gmol");
234 }
235 if (m_input.hasKey("g0")) {
236 m_deltaG_formation_tr_pr = m_input.convert("g0", "cal/gmol");
237 }
238 if (m_input.hasKey("s0")) {
239 m_Entrop_tr_pr = m_input.convert("s0", "cal/gmol/K");
240 }
241 auto& units = m_input.units();
242 if (m_input.hasKey("a")) {
243 auto& a = m_input["a"].asVector<AnyValue>(4);
244 m_a1 = units.convert(a[0], "cal/gmol/bar");
245 m_a2 = units.convert(a[1], "cal/gmol");
246 m_a3 = units.convert(a[2], "cal*K/gmol/bar");
247 m_a4 = units.convert(a[3], "cal*K/gmol");
248 }
249 if (m_input.hasKey("c")) {
250 auto& c = m_input["c"].asVector<AnyValue>(2);
251 m_c1 = units.convert(c[0], "cal/gmol/K");
252 m_c2 = units.convert(c[1], "cal*K/gmol");
253 }
254 if (m_input.hasKey("omega")) {
255 m_omega_pr_tr = m_input.convert("omega", "cal/gmol");
256 }
257
258 // Ok, if we are missing one, then we construct its value from the other two.
259 // This code has been internally verified.
261 if (std::isnan(m_deltaH_formation_tr_pr)) {
263 double Hcalc = m_Mu0_tr_pr + 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
264 m_deltaH_formation_tr_pr = m_units.convertFrom(Hcalc, "J/kmol");
265 } else if (std::isnan(m_deltaG_formation_tr_pr)) {
266 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
267 m_Mu0_tr_pr = DHjmol - 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
269 double tmp = m_Mu0_tr_pr;
271 double totalSum = m_Mu0_tr_pr - tmp;
272 m_Mu0_tr_pr = tmp;
273 m_deltaG_formation_tr_pr = m_units.convertFrom(m_Mu0_tr_pr - totalSum, "J/kmol");
274 } else if (std::isnan(m_Entrop_tr_pr)) {
276 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
277 m_Entrop_tr_pr = m_units.convertFrom((DHjmol - m_Mu0_tr_pr) / 298.15, "J/kmol");
278 }
279
280 m_waterSS = &dynamic_cast<PDSS_Water&>(*m_tp->providePDSS(0));
281
282 // Section to initialize m_Z_pr_tr and m_Y_pr_tr
283 m_temp = 273.15 + 25.;
284 m_pres = OneAtm;
285 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
288 m_Z_pr_tr = -1.0 / relepsilon;
289 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
290 m_Y_pr_tr = drelepsilondT / (relepsilon * relepsilon);
291 m_waterProps = make_unique<WaterProps>(m_waterSS);
292 m_presR_bar = OneAtm / 1.0E5;
293 m_presR_bar = 1.0;
295
296 // Ok, we have mu. Let's check it against the input value
297 // of DH_F to see that we have some internal consistency
298 double Hcalc = m_Mu0_tr_pr + 298.15 * m_units.convertTo(m_Entrop_tr_pr, "J/kmol");
299 double DHjmol = m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol");
300
301 // If the discrepancy is greater than 100 cal gmol-1, print
302 // an error and exit.
303 if (fabs(Hcalc -DHjmol) > m_units.convertTo(100, "J/kmol")) {
304 string sname = m_tp->speciesName(m_spindex);
306 throw CanteraError("PDSS_HKFT::initThermo", "For {}, DHjmol is"
307 " not consistent with G and S: {} vs {} J/kmol",
308 sname, Hcalc, m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol"));
309 } else {
310 warn_user("PDSS_HKFT::initThermo",
311 "DHjmol for {} is not consistent with G and S: calculated {} "
312 "vs input {} J/kmol; continuing with consistent DHjmol = {}",
313 sname, Hcalc, m_units.convertTo(m_deltaH_formation_tr_pr, "J/kmol"),
314 Hcalc);
315 m_deltaH_formation_tr_pr = m_units.convertFrom(Hcalc, "J/kmol");
316 }
317 }
318 double nu = 166027;
319 double r_e_j_pr_tr;
320 if (m_charge_j != 0.0) {
321 r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
322 } else {
323 r_e_j_pr_tr = 0.0;
324 }
325
326 if (m_charge_j == 0.0) {
327 m_domega_jdT_prtr = 0.0;
328 } else {
329 double gval = gstar(m_temp, m_pres, 0);
330 double dgvaldT = gstar(m_temp, m_pres, 1);
331 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
332 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
333 m_domega_jdT_prtr = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
334 + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
335 }
336}
337
338void PDSS_HKFT::setDeltaH0(double dh0) {
339 m_deltaH_formation_tr_pr = m_units.convertFrom(dh0, "J/kmol");
340}
341
342void PDSS_HKFT::setDeltaG0(double dg0) {
343 m_deltaG_formation_tr_pr = m_units.convertFrom(dg0, "J/kmol");
344}
345
346void PDSS_HKFT::setS0(double s0) {
347 m_Entrop_tr_pr = m_units.convertFrom(s0, "J/kmol/K");
348}
349
350void PDSS_HKFT::set_a(span<const double> a) {
351 checkArraySize("PDSS_HKFT::set_a", a.size(), 4);
352 m_a1 = m_units.convertFrom(a[0], "J/kmol/Pa");
353 m_a2 = m_units.convertFrom(a[1], "J/kmol");
354 m_a3 = m_units.convertFrom(a[2], "J*K/kmol/Pa");
355 m_a4 = m_units.convertFrom(a[3], "J*K/kmol");
356}
357
358void PDSS_HKFT::set_c(span<const double> c) {
359 checkArraySize("PDSS_HKFT::set_c", c.size(), 2);
360 m_c1 = m_units.convertFrom(c[0], "J/kmol/K");
361 m_c2 = m_units.convertFrom(c[1], "J*K/kmol");
362}
363
364void PDSS_HKFT::setOmega(double omega) {
365 m_omega_pr_tr = m_units.convertFrom(omega, "J/kmol");
366}
367
369{
370 PDSS::getParameters(eosNode);
371 eosNode["model"] = "HKFT";
372 eosNode["h0"].setQuantity(m_deltaH_formation_tr_pr, "cal/gmol");
373 eosNode["g0"].setQuantity(m_deltaG_formation_tr_pr, "cal/gmol");
374 eosNode["s0"].setQuantity(m_Entrop_tr_pr, "cal/gmol/K");
375
376 vector<AnyValue> a(4), c(2);
377 a[0].setQuantity(m_a1, "cal/gmol/bar");
378 a[1].setQuantity(m_a2, "cal/gmol");
379 a[2].setQuantity(m_a3, "cal*K/gmol/bar");
380 a[3].setQuantity(m_a4, "cal*K/gmol");
381 eosNode["a"] = std::move(a);
382
383 c[0].setQuantity(m_c1, "cal/gmol/K");
384 c[1].setQuantity(m_c2, "cal*K/gmol");
385 eosNode["c"] = std::move(c);
386
387 eosNode["omega"].setQuantity(m_omega_pr_tr, "cal/gmol");
388}
389
390double PDSS_HKFT::deltaG() const
391{
392 double pbar = m_pres * 1.0E-5;
393 double sterm = - m_Entrop_tr_pr * (m_temp - 298.15);
394 double c1term = -m_c1 * (m_temp * log(m_temp/298.15) - (m_temp - 298.15));
395 double a1term = m_a1 * (pbar - m_presR_bar);
396 double a2term = m_a2 * log((2600. + pbar)/(2600. + m_presR_bar));
397 double c2term = -m_c2 * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.)) * (228. - m_temp)/228.
398 - m_temp / (228.*228.) * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
399 double a3term = m_a3 / (m_temp - 228.) * (pbar - m_presR_bar);
400 double a4term = m_a4 / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
401
402 double omega_j;
403 if (m_charge_j == 0.0) {
404 omega_j = m_omega_pr_tr;
405 } else {
406 double nu = 166027;
407 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
408 double gval = gstar(m_temp, m_pres, 0);
409 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
410 omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
411 }
412
413 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
414 double Z = -1.0 / relepsilon;
415 double wterm = - omega_j * (Z + 1.0);
416 double wrterm = m_omega_pr_tr * (m_Z_pr_tr + 1.0);
417 double yterm = m_omega_pr_tr * m_Y_pr_tr * (m_temp - 298.15);
418 double deltaG_calgmol = sterm + c1term + a1term + a2term + c2term + a3term + a4term + wterm + wrterm + yterm;
419
420 return m_units.convertTo(deltaG_calgmol, "J/kmol");
421}
422
423double PDSS_HKFT::deltaS() const
424{
425 double pbar = m_pres * 1.0E-5;
426
427 double c1term = m_c1 * log(m_temp/298.15);
428 double c2term = -m_c2 / 228. * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.))
429 + 1.0 / 228. * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
430 double a3term = m_a3 / (m_temp - 228.) / (m_temp - 228.) * (pbar - m_presR_bar);
431 double a4term = m_a4 / (m_temp - 228.) / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
432
433 double omega_j;
434 double domega_jdT;
435 if (m_charge_j == 0.0) {
436 omega_j = m_omega_pr_tr;
437 domega_jdT = 0.0;
438 } else {
439 double nu = 166027;
440 double r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
441 double gval = gstar(m_temp, m_pres, 0);
442 double dgvaldT = gstar(m_temp, m_pres, 1);
443 double r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
444 double dr_e_jdT = fabs(m_charge_j) * dgvaldT;
445 omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
446 domega_jdT = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
447 + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
448 }
449
450 double relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
451 double drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
452 double Y = drelepsilondT / (relepsilon * relepsilon);
453 double Z = -1.0 / relepsilon;
454 double wterm = omega_j * Y;
455 double wrterm = - m_omega_pr_tr * m_Y_pr_tr;
456 double otterm = domega_jdT * (Z + 1.0);
457 double otrterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
458 double deltaS_calgmol = c1term + c2term + a3term + a4term + wterm + wrterm + otterm + otrterm;
459
460 return m_units.convertTo(deltaS_calgmol, "J/kmol/K");
461}
462
463double PDSS_HKFT::ag(const double temp, const int ifunc) const
464{
465 static double ag_coeff[3] = { -2.037662, 5.747000E-3, -6.557892E-6};
466 if (ifunc == 0) {
467 return ag_coeff[0] + ag_coeff[1] * temp + ag_coeff[2] * temp * temp;
468 } else if (ifunc == 1) {
469 return ag_coeff[1] + ag_coeff[2] * 2.0 * temp;
470 }
471 if (ifunc != 2) {
472 return 0.0;
473 }
474 return ag_coeff[2] * 2.0;
475}
476
477double PDSS_HKFT::bg(const double temp, const int ifunc) const
478{
479 static double bg_coeff[3] = { 6.107361, -1.074377E-2, 1.268348E-5};
480 if (ifunc == 0) {
481 return bg_coeff[0] + bg_coeff[1] * temp + bg_coeff[2] * temp * temp;
482 } else if (ifunc == 1) {
483 return bg_coeff[1] + bg_coeff[2] * 2.0 * temp;
484 }
485 if (ifunc != 2) {
486 return 0.0;
487 }
488 return bg_coeff[2] * 2.0;
489}
490
491double PDSS_HKFT::f(const double temp, const double pres, const int ifunc) const
492{
493 static double af_coeff[3] = { 3.666666E1, -0.1504956E-9, 0.5107997E-13};
494 double TC = temp - 273.15;
495 double presBar = pres / 1.0E5;
496
497 if (TC < 155.0) {
498 return 0.0;
499 }
500 TC = std::min(TC, 355.0);
501 if (presBar > 1000.) {
502 return 0.0;
503 }
504
505 double T1 = (TC-155.0)/300.;
506 double p2 = (1000. - presBar) * (1000. - presBar);
507 double p3 = (1000. - presBar) * p2;
508 double p4 = p2 * p2;
509 double fac2 = af_coeff[1] * p3 + af_coeff[2] * p4;
510 if (ifunc == 0) {
511 return pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0) * fac2;
512 } else if (ifunc == 1) {
513 return (4.8 * pow(T1,3.8) + 16.0 * af_coeff[0] * pow(T1, 15.0)) / 300. * fac2;
514 } else if (ifunc == 2) {
515 return (4.8 * 3.8 * pow(T1,2.8) + 16.0 * 15.0 * af_coeff[0] * pow(T1, 14.0)) / (300. * 300.) * fac2;
516 } else if (ifunc == 3) {
517 double fac1 = pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0);
518 fac2 = - (3.0 * af_coeff[1] * p2 + 4.0 * af_coeff[2] * p3)/ 1.0E5;
519 return fac1 * fac2;
520 } else {
521 throw NotImplementedError("PDSS_HKFT::f");
522 }
523}
524
525double PDSS_HKFT::g(const double temp, const double pres, const int ifunc) const
526{
527 double afunc = ag(temp, 0);
528 double bfunc = bg(temp, 0);
529 m_waterSS->setState_TP(temp, pres);
531 // density in gm cm-3
532 double dens = m_densWaterSS * 1.0E-3;
533 double gval = afunc * pow((1.0-dens), bfunc);
534 if (dens >= 1.0) {
535 return 0.0;
536 }
537 if (ifunc == 0) {
538 return gval;
539 } else if (ifunc == 1 || ifunc == 2) {
540 double afuncdT = ag(temp, 1);
541 double bfuncdT = bg(temp, 1);
542 double alpha = m_waterSS->thermalExpansionCoeff();
543
544 double fac1 = afuncdT * gval / afunc;
545 double fac2 = bfuncdT * gval * log(1.0 - dens);
546 double fac3 = gval * alpha * bfunc * dens / (1.0 - dens);
547
548 double dgdt = fac1 + fac2 + fac3;
549 if (ifunc == 1) {
550 return dgdt;
551 }
552
553 double afuncdT2 = ag(temp, 2);
554 double bfuncdT2 = bg(temp, 2);
555 double dfac1dT = dgdt * afuncdT / afunc + afuncdT2 * gval / afunc
556 - afuncdT * afuncdT * gval / (afunc * afunc);
557 double ddensdT = - alpha * dens;
558 double dfac2dT = bfuncdT2 * gval * log(1.0 - dens)
559 + bfuncdT * dgdt * log(1.0 - dens)
560 - bfuncdT * gval /(1.0 - dens) * ddensdT;
561 double dalphadT = m_waterSS->dthermalExpansionCoeffdT();
562 double dfac3dT = dgdt * alpha * bfunc * dens / (1.0 - dens)
563 + gval * dalphadT * bfunc * dens / (1.0 - dens)
564 + gval * alpha * bfuncdT * dens / (1.0 - dens)
565 + gval * alpha * bfunc * ddensdT / (1.0 - dens)
566 + gval * alpha * bfunc * dens / ((1.0 - dens) * (1.0 - dens)) * ddensdT;
567
568 return dfac1dT + dfac2dT + dfac3dT;
569 } else if (ifunc == 3) {
570 double beta = m_waterSS->isothermalCompressibility();
571 return - bfunc * gval * dens * beta / (1.0 - dens);
572 } else {
573 throw NotImplementedError("PDSS_HKFT::g");
574 }
575 return 0.0;
576}
577
578double PDSS_HKFT::gstar(const double temp, const double pres, const int ifunc) const
579{
580 double gval = g(temp, pres, ifunc);
581 double fval = f(temp, pres, ifunc);
582 double res = gval - fval;
583 return res;
584}
585
586double PDSS_HKFT::LookupGe(const string& elemName)
587{
588 size_t iE = m_tp->elementIndex(elemName, true);
589 double geValue = m_tp->entropyElement298(iE);
590 if (geValue == ENTROPY298_UNKNOWN) {
591 throw CanteraError("PDSS_HKFT::LookupGe",
592 "element " + elemName + " does not have a supplied entropy298");
593 }
594 return geValue * -298.15;
595}
596
598{
599 // Ok let's get the element compositions and conversion factors.
600 double totalSum = 0.0;
601 for (size_t m = 0; m < m_tp->nElements(); m++) {
602 double na = m_tp->nAtoms(m_spindex, m);
603 if (na > 0.0) {
604 totalSum += na * LookupGe(m_tp->elementName(m));
605 }
606 }
607 // Add in the charge
608 if (m_charge_j != 0.0) {
609 totalSum -= m_charge_j * LookupGe("H");
610 }
611 double dg = m_units.convertTo(m_deltaG_formation_tr_pr, "J/kmol");
612 //! Store the result into an internal variable.
613 m_Mu0_tr_pr = dg + totalSum;
614}
615
616}
#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:431
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition AnyMap.cpp:1477
const UnitSystem & units() const
Return the default units that should be used to convert stored values.
Definition AnyMap.h:640
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:1595
A wrapper for a variable whose type is determined at runtime.
Definition AnyMap.h:88
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:303
double m_Y_pr_tr
y = dZdT = 1/(esp*esp) desp/dT at 298.15 and 1 bar
Definition PDSS_HKFT.h:284
double m_a4
Input a4 coefficient (cal K gmol-1)
Definition PDSS_HKFT.h:272
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:227
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.
size_t m_spindex
Index of this species within the parent phase.
Definition PDSS_HKFT.h:103
double m_densWaterSS
density of standard-state water. internal temporary variable
Definition PDSS_HKFT.h:224
double LookupGe(const string &elemName)
Function to look up Element Free Energies.
void set_c(span< const double > c)
Set "c" coefficients (array of 2 elements).
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:102
double m_Entrop_tr_pr
Input value of S_j at Tr and Pr (cal gmol-1 K-1)
Definition PDSS_HKFT.h:260
double m_deltaG_formation_tr_pr
Input value of deltaG of Formation at Tr and Pr (cal gmol-1)
Definition PDSS_HKFT.h:236
void set_a(span< const double > a)
Set "a" coefficients (array of 4 elements).
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:269
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:296
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 dVdP() const override
Return the pressure derivative of the standard state molar volume at constant temperature [m³/kmol/Pa...
double enthalpy_RT_ref() const override
Return the molar enthalpy divided by RT at reference pressure.
double molarVolumeTP(double temp, double pres) const
Evaluate the molar volume at a given temperature and 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 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:278
double m_presR_bar
Reference pressure is 1 atm in units of bar= 1.0132.
Definition PDSS_HKFT.h:290
double intEnergy_mole() const override
Return the molar internal Energy in units of J kmol-1.
Definition PDSS_HKFT.cpp:36
double m_domega_jdT_prtr
small value that is not quite zero
Definition PDSS_HKFT.h:293
double entropy_mole() const override
Return the molar entropy in units of J kmol-1 K-1.
Definition PDSS_HKFT.cpp:41
double m_omega_pr_tr
Input omega_pr_tr coefficient(cal gmol-1)
Definition PDSS_HKFT.h:281
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:287
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:51
double m_deltaH_formation_tr_pr
Input value of deltaH of Formation at Tr and Pr (cal gmol-1)
Definition PDSS_HKFT.h:245
double m_a1
Input a1 coefficient (cal gmol-1 bar-1)
Definition PDSS_HKFT.h:263
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:46
double m_c1
Input c1 coefficient (cal gmol-1 K-1)
Definition PDSS_HKFT.h:275
double molarVolume_ref() const override
Return the molar volume at reference pressure.
PDSS_Water * m_waterSS
Water standard state calculator.
Definition PDSS_HKFT.h:219
double m_Mu0_tr_pr
Value of the Absolute Gibbs Free Energy NIST scale at T_r and P_r.
Definition PDSS_HKFT.h:254
double dVdT() const override
Return the temperature derivative of the standard state molar volume at constant pressure [m³/kmol/K]...
double m_a2
Input a2 coefficient (cal gmol-1)
Definition PDSS_HKFT.h:266
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:189
double entropy_R() const override
Return the standard state entropy divided by RT.
Definition PDSS.cpp:179
double enthalpy_RT() const override
Return the standard state molar enthalpy divided by RT.
Definition PDSS.cpp:174
double gibbs_RT() const override
Return the molar Gibbs free energy divided by RT.
Definition PDSS.cpp:184
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 setTemperature(double temp)
Set the internal temperature.
Definition PDSS.cpp:148
virtual void initThermo()
Initialization routine.
Definition PDSS.h:397
double m_temp
Current temperature used by the PDSS object.
Definition PDSS.h:412
double m_pres
State of the system - pressure.
Definition PDSS.h:415
double m_mw
Molecular Weight of the species.
Definition PDSS.h:427
AnyMap m_input
Input data supplied via setParameters.
Definition PDSS.h:431
virtual void getParameters(AnyMap &eosNode) const
Store the parameters needed to reconstruct a copy of this PDSS object.
Definition PDSS.h:406
virtual void setPressure(double pres)
Sets the pressure in the object.
Definition PDSS.cpp:138
string speciesName(size_t k) const
Name of the species with index k.
Definition Phase.cpp:143
double nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
Definition Phase.cpp:101
size_t nElements() const
Number of elements.
Definition Phase.cpp:30
size_t elementIndex(const string &name, bool raise=true) const
Return the index of element named 'name'.
Definition Phase.cpp:51
string elementName(size_t m) const
Name of the element with index m.
Definition Phase.cpp:43
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:562
double entropyElement298(size_t m) const
Entropy of the element in its standard state at 298 K and 1 bar.
Definition Phase.cpp:74
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:571
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:555
void setDefaults(std::initializer_list< string > units)
Set the default units to convert from when explicit units are not provided.
Definition Units.cpp:429
This file contains definitions for utility functions and text for modules, inputfiles and logging,...
const double OneAtm
One atmosphere [Pa].
Definition ct_defs.h:99
void warn_user(const string &method, const string &msg, const Args &... args)
Print a user warning raised from method as CanteraWarning.
Definition global.h:263
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.
Contains declarations for string manipulation functions within Cantera.