Cantera  2.1.2
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  * Copyright (2006) Sandia Corporation. Under the terms of
10  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
11  * U.S. Government retains certain rights in this software.
12  */
13 
14 #include "cantera/base/ctml.h"
19 
20 #include <fstream>
21 
22 using namespace std;
23 using namespace ctml;
24 
25 namespace Cantera
26 {
27 PDSS_HKFT::PDSS_HKFT(VPStandardStateTP* tp, size_t spindex) :
28  PDSS(tp, spindex),
29  m_waterSS(0),
30  m_densWaterSS(-1.0),
31  m_waterProps(0),
32  m_born_coeff_j(-1.0),
33  m_r_e_j(-1.0),
34  m_deltaG_formation_tr_pr(0.0),
35  m_deltaH_formation_tr_pr(0.0),
36  m_Mu0_tr_pr(0.0),
37  m_Entrop_tr_pr(0.0),
38  m_a1(0.0),
39  m_a2(0.0),
40  m_a3(0.0),
41  m_a4(0.0),
42  m_c1(0.0),
43  m_c2(0.0),
44  m_omega_pr_tr(0.0),
45  m_Y_pr_tr(0.0),
46  m_Z_pr_tr(0.0),
47  m_presR_bar(0.0),
48  m_domega_jdT_prtr(0.0),
49  m_charge_j(0.0)
50 {
51  m_pres = OneAtm;
52  m_pdssType = cPDSS_MOLAL_HKFT;
53  m_presR_bar = OneAtm * 1.0E-5;
54 }
55 
57  const std::string& inputFile, const std::string& id) :
58  PDSS(tp, spindex),
59  m_waterSS(0),
60  m_densWaterSS(-1.0),
61  m_waterProps(0),
62  m_born_coeff_j(-1.0),
63  m_r_e_j(-1.0),
64  m_deltaG_formation_tr_pr(0.0),
65  m_deltaH_formation_tr_pr(0.0),
66  m_Mu0_tr_pr(0.0),
67  m_Entrop_tr_pr(0.0),
68  m_a1(0.0),
69  m_a2(0.0),
70  m_a3(0.0),
71  m_a4(0.0),
72  m_c1(0.0),
73  m_c2(0.0),
74  m_omega_pr_tr(0.0),
75  m_Y_pr_tr(0.0),
76  m_Z_pr_tr(0.0),
77  m_presR_bar(0.0),
78  m_domega_jdT_prtr(0.0),
79  m_charge_j(0.0)
80 {
81  m_pres = OneAtm;
82  m_pdssType = cPDSS_MOLAL_HKFT;
83  m_presR_bar = OneAtm * 1.0E-5;
84  constructPDSSFile(tp, spindex, inputFile, id);
85 }
86 
87 PDSS_HKFT::PDSS_HKFT(VPStandardStateTP* tp, size_t spindex, const XML_Node& speciesNode,
88  const XML_Node& phaseRoot, bool spInstalled) :
89  PDSS(tp, spindex),
90  m_waterSS(0),
91  m_densWaterSS(-1.0),
92  m_waterProps(0),
93  m_born_coeff_j(-1.0),
94  m_r_e_j(-1.0),
95  m_deltaG_formation_tr_pr(0.0),
96  m_deltaH_formation_tr_pr(0.0),
97  m_Mu0_tr_pr(0.0),
98  m_Entrop_tr_pr(0.0),
99  m_a1(0.0),
100  m_a2(0.0),
101  m_a3(0.0),
102  m_a4(0.0),
103  m_c1(0.0),
104  m_c2(0.0),
105  m_omega_pr_tr(0.0),
106  m_Y_pr_tr(0.0),
107  m_Z_pr_tr(0.0),
108  m_presR_bar(0.0),
109  m_domega_jdT_prtr(0.0),
110  m_charge_j(0.0)
111 {
112  m_pres = OneAtm;
113  m_pdssType = cPDSS_MOLAL_HKFT;
114  m_presR_bar = OneAtm * 1.0E-5;
115  // We have to read the info from here
116  constructPDSSXML(tp, spindex, speciesNode, phaseRoot, spInstalled);
117 }
118 
120  PDSS(b),
121  m_waterSS(0),
122  m_densWaterSS(-1.0),
123  m_waterProps(0),
124  m_born_coeff_j(-1.0),
125  m_r_e_j(-1.0),
126  m_deltaG_formation_tr_pr(0.0),
127  m_deltaH_formation_tr_pr(0.0),
128  m_Mu0_tr_pr(0.0),
129  m_Entrop_tr_pr(0.0),
130  m_a1(0.0),
131  m_a2(0.0),
132  m_a3(0.0),
133  m_a4(0.0),
134  m_c1(0.0),
135  m_c2(0.0),
136  m_omega_pr_tr(0.0),
137  m_Y_pr_tr(0.0),
138  m_Z_pr_tr(0.0),
139  m_presR_bar(0.0),
140  m_domega_jdT_prtr(0.0),
141  m_charge_j(0.0)
142 {
143  m_pdssType = cPDSS_MOLAL_HKFT;
144  m_presR_bar = OneAtm * 1.0E-5;
145  /*
146  * Use the assignment operator to do the brunt
147  * of the work for the copy constructor.
148  */
149  *this = b;
150 }
151 
153 {
154  if (&b == this) {
155  return *this;
156  }
157  /*
158  * Call the base class operator
159  */
160  PDSS::operator=(b);
161 
162  //! Need to call initAllPtrs AFTER, to get the correct m_waterSS
163  m_waterSS = 0;
165  //! Need to call initAllPtrs AFTER, to get the correct m_waterProps
166  delete m_waterProps;
167  m_waterProps = 0;
169  m_r_e_j = b.m_r_e_j;
174  m_a1 = b.m_a1;
175  m_a2 = b.m_a2;
176  m_a3 = b.m_a3;
177  m_a4 = b.m_a4;
178  m_c1 = b.m_c1;
179  m_c2 = b.m_c2;
181  m_Y_pr_tr = b.m_Y_pr_tr;
182  m_Z_pr_tr = b.m_Z_pr_tr;
186 
187  // Here we just fill these in so that local copies within the VPSS object work.
188  m_waterSS = b.m_waterSS;
190 
191  return *this;
192 }
193 
195 {
196  delete m_waterProps;
197 }
198 
200 {
201  return new PDSS_HKFT(*this);
202 }
203 
204 doublereal PDSS_HKFT::enthalpy_mole() const
205 {
206  // Ok we may change this evaluation method in the future.
207  doublereal GG = gibbs_mole();
208  doublereal SS = entropy_mole();
209  doublereal h = GG + m_temp * SS;
210 
211 #ifdef DEBUG_MODE_NOT
212  doublereal h2 = enthalpy_mole2();
213  if (fabs(h - h2) > 1.0E-1) {
214  printf("we are here, h = %g, h2 = %g, k = %d, T = %g, P = %g p0 = %g\n",
215  h, h2, m_spindex, m_temp, m_pres,
216  m_p0);
217  }
218 #endif
219  return h;
220 }
221 
222 doublereal PDSS_HKFT::enthalpy_RT() const
223 {
224  doublereal hh = enthalpy_mole();
225  doublereal RT = GasConstant * m_temp;
226  return hh / RT;
227 }
228 
229 #ifdef DEBUG_MODE
230 doublereal PDSS_HKFT::enthalpy_mole2() const
231 {
232  doublereal delH = deltaH();
233  double enthTRPR = m_Mu0_tr_pr + 298.15 * m_Entrop_tr_pr * 1.0E3 * 4.184;
234  return delH + enthTRPR;
235 }
236 #endif
237 
238 doublereal PDSS_HKFT::intEnergy_mole() const
239 {
240  doublereal hh = enthalpy_RT();
241  doublereal mv = molarVolume();
242  return hh - mv * m_pres;
243 }
244 
245 doublereal PDSS_HKFT::entropy_mole() const
246 {
247  doublereal delS = deltaS();
248  return m_Entrop_tr_pr * 1.0E3 * 4.184 + delS;
249 }
250 
251 doublereal PDSS_HKFT::gibbs_mole() const
252 {
253  doublereal delG = deltaG();
254  return m_Mu0_tr_pr + delG;
255 }
256 
257 doublereal PDSS_HKFT::cp_mole() const
258 {
259  doublereal pbar = m_pres * 1.0E-5;
260  doublereal c1term = m_c1;
261 
262  doublereal c2term = m_c2 / (m_temp - 228.) / (m_temp - 228.);
263 
264  doublereal a3term = -m_a3 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp * (pbar - m_presR_bar);
265 
266  doublereal a4term = -m_a4 / (m_temp - 228.) / (m_temp - 228.) / (m_temp - 228.) * 2.0 * m_temp
267  * log((2600. + pbar)/(2600. + m_presR_bar));
268 
269  doublereal omega_j;
270  doublereal domega_jdT;
271  doublereal d2omega_jdT2;
272  if (m_charge_j == 0.0) {
273  omega_j = m_omega_pr_tr;
274  domega_jdT = 0.0;
275  d2omega_jdT2 = 0.0;
276  } else {
277  doublereal nu = 166027;
278  doublereal r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
279 
280  doublereal gval = gstar(m_temp, m_pres, 0);
281 
282  doublereal dgvaldT = gstar(m_temp, m_pres, 1);
283  doublereal d2gvaldT2 = gstar(m_temp, m_pres, 2);
284 
285  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
286  doublereal dr_e_jdT = fabs(m_charge_j) * dgvaldT;
287  doublereal d2r_e_jdT2 = fabs(m_charge_j) * d2gvaldT2;
288 
289  doublereal r_e_j2 = r_e_j * r_e_j;
290 
291  doublereal charge2 = m_charge_j * m_charge_j;
292 
293  doublereal r_e_H = 3.082 + gval;
294  doublereal r_e_H2 = r_e_H * r_e_H;
295 
296  omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
297 
298  domega_jdT = nu * (-(charge2 / r_e_j2 * dr_e_jdT)
299  +(m_charge_j / r_e_H2 * dgvaldT));
300 
301  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
302  -2.0*m_charge_j*dgvaldT*dgvaldT/(r_e_H2*r_e_H) + m_charge_j*d2gvaldT2 /r_e_H2);
303  }
304 
305  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
306  doublereal drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
307 
308  doublereal Y = drelepsilondT / (relepsilon * relepsilon);
309 
310  doublereal d2relepsilondT2 = m_waterProps->relEpsilon(m_temp, m_pres, 2);
311 
312 #ifdef DEBUG_MODE_NOT
313  doublereal d1 = m_waterProps->relEpsilon(m_temp, m_pres, 1);
314  doublereal d2 = m_waterProps->relEpsilon(m_temp + 0.0001, m_pres, 1);
315  doublereal d3 = (d2 - d1) / 0.0001;
316  if (fabs(d2relepsilondT2 - d3) > 1.0E-6) {
317  printf("we are here\n");
318  }
319 #endif
320 
321  doublereal X = d2relepsilondT2 / (relepsilon* relepsilon) - 2.0 * relepsilon * Y * Y;
322 
323  doublereal Z = -1.0 / relepsilon;
324 
325  doublereal yterm = 2.0 * m_temp * Y * domega_jdT;
326 
327  doublereal xterm = omega_j * m_temp * X;
328 
329  doublereal otterm = m_temp * d2omega_jdT2 * (Z + 1.0);
330 
331  doublereal rterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
332 
333  doublereal Cp_calgmol = c1term + c2term + a3term + a4term + yterm + xterm + otterm + rterm;
334 
335  // Convert to Joules / kmol
336  doublereal Cp = Cp_calgmol * 1.0E3 * 4.184;
337 
338 #ifdef DEBUG_MODE_NOT
339  double e1 = enthalpy_mole();
340  m_temp = m_temp - 0.001;
341  double e2 = enthalpy_mole();
342  m_temp = m_temp + 0.001;
343  double cpd = (e1 - e2) / 0.001;
344  if (fabs(Cp - cpd) > 10.0) {
345  printf("Cp difference : raw: %g, delta: %g, k = %d, T = %g, m_pres = %g\n",
346  Cp, cpd, m_spindex, m_temp, m_pres);
347  }
348 #endif
349  return Cp;
350 }
351 
352 doublereal
354 {
355  throw CanteraError("PDSS_HKFT::cv_mole()", "unimplemented");
356  return 0.0;
357 }
358 
359 doublereal PDSS_HKFT::molarVolume() const
360 {
361  // Initially do all calculations in (cal/gmol/Pa)
362 
363  doublereal a1term = m_a1 * 1.0E-5;
364 
365  doublereal a2term = m_a2 / (2600.E5 + m_pres);
366 
367  doublereal a3term = m_a3 * 1.0E-5/ (m_temp - 228.);
368 
369  doublereal a4term = m_a4 / (m_temp - 228.) / (2600.E5 + m_pres);
370 
371  doublereal omega_j;
372  doublereal domega_jdP;
373  if (m_charge_j == 0.0) {
374  omega_j = m_omega_pr_tr;
375  domega_jdP = 0.0;
376  } else {
377  doublereal nu = 166027.;
378  doublereal charge2 = m_charge_j * m_charge_j;
379  doublereal r_e_j_pr_tr = charge2 / (m_omega_pr_tr/nu + m_charge_j/3.082);
380 
381  doublereal gval = gstar(m_temp, m_pres, 0);
382  doublereal dgvaldP = gstar(m_temp, m_pres, 3);
383 
384  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
385  doublereal r_e_H = 3.082 + gval;
386 
387  omega_j = nu * (charge2 / r_e_j - m_charge_j / r_e_H);
388 
389  doublereal dr_e_jdP = fabs(m_charge_j) * dgvaldP;
390 
391  domega_jdP = - nu * (charge2 / (r_e_j * r_e_j) * dr_e_jdP)
392  + nu * m_charge_j / (r_e_H * r_e_H) * dgvaldP;
393  }
394 
395  doublereal drelepsilondP = m_waterProps->relEpsilon(m_temp, m_pres, 3);
396 
397  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
398 
399  doublereal Q = drelepsilondP / (relepsilon * relepsilon);
400 
401  doublereal Z = -1.0 / relepsilon;
402 
403  doublereal wterm = - domega_jdP * (Z + 1.0);
404 
405  doublereal qterm = - omega_j * Q;
406 
407  doublereal molVol_calgmolPascal = a1term + a2term + a3term + a4term + wterm + qterm;
408 
409  // Convert to m**3 / kmol from (cal/gmol/Pa)
410  return molVol_calgmolPascal * 4.184 * 1.0E3;
411 }
412 
413 doublereal
415 {
416  doublereal val = molarVolume();
417  return m_mw/val;
418 }
419 
420 doublereal
422 {
423  doublereal m_psave = m_pres;
425  doublereal ee = gibbs_RT();
426  m_pres = m_psave;
427  return ee;
428 }
429 
430 doublereal
432 {
433  doublereal m_psave = m_pres;
435  doublereal hh = enthalpy_RT();
436  m_pres = m_psave;
437  return hh;
438 }
439 
440 doublereal
442 {
443  doublereal m_psave = m_pres;
445  doublereal ee = entropy_R();
446  m_pres = m_psave;
447  return ee;
448 }
449 
450 doublereal
452 {
453  doublereal m_psave = m_pres;
455  doublereal ee = cp_R();
456  m_pres = m_psave;
457  return ee;
458 }
459 
460 doublereal
462 {
463  doublereal m_psave = m_pres;
465  doublereal ee = molarVolume();
466  m_pres = m_psave;
467  return ee;
468 }
469 
470 doublereal
472 {
473  return m_pres;
474 }
475 
476 void
478 {
479  m_pres = p;
480 }
481 
482 void PDSS_HKFT::setTemperature(doublereal temp)
483 {
484  m_temp = temp;
485 }
486 
487 doublereal PDSS_HKFT::temperature() const
488 {
489  return m_temp;
490 }
491 
492 void PDSS_HKFT::setState_TP(doublereal temp, doublereal pres)
493 {
494  setTemperature(temp);
495  setPressure(pres);
496 }
497 
498 doublereal
500 {
501  throw CanteraError("PDSS_HKFT::critTemperature()", "unimplemented");
502  return 0.0;
503 }
504 
505 doublereal PDSS_HKFT::critPressure() const
506 {
507  throw CanteraError("PDSS_HKFT::critPressure()", "unimplemented");
508  return 0.0;
509 }
510 
511 doublereal PDSS_HKFT::critDensity() const
512 {
513  throw CanteraError("PDSS_HKFT::critDensity()", "unimplemented");
514  return 0.0;
515 }
516 
518 {
520 
521  m_waterSS = (PDSS_Water*) m_tp->providePDSS(0);
522  /*
523  * Section to initialize m_Z_pr_tr and m_Y_pr_tr
524  */
525  m_temp = 273.15 + 25.;
526  m_pres = OneAtm;
527  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
528 
531  m_Z_pr_tr = -1.0 / relepsilon;
532 
533  doublereal drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
534 
535  m_Y_pr_tr = drelepsilondT / (relepsilon * relepsilon);
536 
538 
539  m_presR_bar = OneAtm / 1.0E5;
542 
543  //! Ok, we have mu. Let's check it against the input value
544  // of DH_F to see that we have some internal consistency
545 
546  doublereal Hcalc = m_Mu0_tr_pr + 298.15 * (m_Entrop_tr_pr * 1.0E3 * 4.184);
547 
548  doublereal DHjmol = m_deltaH_formation_tr_pr * 1.0E3 * 4.184;
549 
550  // If the discrepancy is greater than 100 cal gmol-1, print
551  // an error and exit.
552  if (fabs(Hcalc -DHjmol) > 100.* 1.0E3 * 4.184) {
553  throw CanteraError(" PDSS_HKFT::initThermo()",
554  "DHjmol is not consistent with G and S: " +
555  fp2str(Hcalc/(4.184E3)) + " vs "
556  + fp2str(m_deltaH_formation_tr_pr) + "cal gmol-1");
557  }
558  doublereal nu = 166027;
559 
560  doublereal r_e_j_pr_tr;
561  if (m_charge_j != 0.0) {
562  r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
563  } else {
564  r_e_j_pr_tr = 0.0;
565  }
566 
567  if (m_charge_j == 0.0) {
568  m_domega_jdT_prtr = 0.0;
569  } else {
570  doublereal gval = gstar(m_temp, m_pres, 0);
571 
572  doublereal dgvaldT = gstar(m_temp, m_pres, 1);
573 
574  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
575  doublereal dr_e_jdT = fabs(m_charge_j) * dgvaldT;
576 
577  m_domega_jdT_prtr = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
578  + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
579  }
580 }
581 
582 void PDSS_HKFT::initThermoXML(const XML_Node& phaseNode, const std::string& id)
583 {
584  PDSS::initThermoXML(phaseNode, id);
585 }
586 
587 void PDSS_HKFT::initAllPtrs(VPStandardStateTP* vptp_ptr, VPSSMgr* vpssmgr_ptr,
588  SpeciesThermo* spthermo_ptr)
589 {
590  PDSS::initAllPtrs(vptp_ptr, vpssmgr_ptr, spthermo_ptr);
591  m_waterSS = (PDSS_Water*) m_tp->providePDSS(0);
592  delete m_waterProps;
594 }
595 
597  const XML_Node& speciesNode,
598  const XML_Node& phaseNode, bool spInstalled)
599 {
600  int hasDGO = 0;
601  int hasSO = 0;
602  int hasDHO = 0;
603 
604  if (!spInstalled) {
605  throw CanteraError("PDSS_HKFT::constructPDSSXML", "spInstalled false not handled");
606  }
607 
608  const XML_Node* tn = speciesNode.findByName("thermo");
609  if (!tn) {
610  throw CanteraError("PDSS_HKFT::constructPDSSXML",
611  "no thermo Node for species " + speciesNode.name());
612  }
613  std::string model = lowercase((*tn)["model"]);
614  if (model != "hkft") {
615  throw CanteraError("PDSS_HKFT::initThermoXML",
616  "thermo model for species isn't hkft: "
617  + speciesNode.name());
618  }
619  const XML_Node* hh = tn->findByName("HKFT");
620  if (!hh) {
621  throw CanteraError("PDSS_HKFT::constructPDSSXML",
622  "no Thermo::HKFT Node for species " + speciesNode.name());
623  }
624 
625  // go get the attributes
626  m_p0 = OneAtm;
627  std::string p0string = (*hh)["Pref"];
628  if (p0string != "") {
629  m_p0 = strSItoDbl(p0string);
630  }
631 
632  std::string minTstring = (*hh)["Tmin"];
633  if (minTstring != "") {
634  m_minTemp = fpValueCheck(minTstring);
635  }
636 
637  std::string maxTstring = (*hh)["Tmax"];
638  if (maxTstring != "") {
639  m_maxTemp = fpValueCheck(maxTstring);
640  }
641 
642  if (hh->hasChild("DG0_f_Pr_Tr")) {
643  doublereal val = getFloat(*hh, "DG0_f_Pr_Tr");
645  hasDGO = 1;
646  } else {
647  // throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing DG0_f_Pr_Tr field");
648  }
649 
650  if (hh->hasChild("DH0_f_Pr_Tr")) {
651  doublereal val = getFloat(*hh, "DH0_f_Pr_Tr");
653  hasDHO = 1;
654  } else {
655  // throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing DH0_f_Pr_Tr field");
656  }
657 
658  if (hh->hasChild("S0_Pr_Tr")) {
659  doublereal val = getFloat(*hh, "S0_Pr_Tr");
660  m_Entrop_tr_pr= val;
661  hasSO = 1;
662  } else {
663  // throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing S0_Pr_Tr field");
664  }
665 
666  const XML_Node* ss = speciesNode.findByName("standardState");
667  if (!ss) {
668  throw CanteraError("PDSS_HKFT::constructPDSSXML",
669  "no standardState Node for species " + speciesNode.name());
670  }
671  model = lowercase((*ss)["model"]);
672  if (model != "hkft") {
673  throw CanteraError("PDSS_HKFT::initThermoXML",
674  "standardState model for species isn't hkft: "
675  + speciesNode.name());
676  }
677  if (ss->hasChild("a1")) {
678  doublereal val = getFloat(*ss, "a1");
679  m_a1 = val;
680  } else {
681  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing a1 field");
682  }
683  if (ss->hasChild("a2")) {
684  doublereal val = getFloat(*ss, "a2");
685  m_a2 = val;
686  } else {
687  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing a2 field");
688  }
689  if (ss->hasChild("a3")) {
690  doublereal val = getFloat(*ss, "a3");
691  m_a3 = val;
692  } else {
693  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing a3 field");
694  }
695  if (ss->hasChild("a4")) {
696  doublereal val = getFloat(*ss, "a4");
697  m_a4 = val;
698  } else {
699  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing a4 field");
700  }
701 
702  if (ss->hasChild("c1")) {
703  doublereal val = getFloat(*ss, "c1");
704  m_c1 = val;
705  } else {
706  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing c1 field");
707  }
708  if (ss->hasChild("c2")) {
709  doublereal val = getFloat(*ss, "c2");
710  m_c2 = val;
711  } else {
712  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing c2 field");
713  }
714  if (ss->hasChild("omega_Pr_Tr")) {
715  doublereal val = getFloat(*ss, "omega_Pr_Tr");
716  m_omega_pr_tr = val;
717  } else {
718  throw CanteraError("PDSS_HKFT::constructPDSSXML", " missing omega_Pr_Tr field");
719  }
720 
721 
722  int isum = hasDGO + hasDHO + hasSO;
723  if (isum < 2) {
724  throw CanteraError("PDSS_HKFT::constructPDSSXML",
725  "Missing 2 or more of DG0_f_Pr_Tr, DH0_f_Pr_Tr, or S0_f_Pr_Tr fields. "
726  "Need to supply at least two of these fields");
727  }
728  // Ok, if we are missing one, then we construct its value from the other two.
729  // This code has been internally verified.
730  if (hasDHO == 0) {
733  doublereal Hcalc = m_Mu0_tr_pr + 298.15 * (m_Entrop_tr_pr * 1.0E3 * 4.184);
734  m_deltaH_formation_tr_pr = Hcalc / (1.0E3 * 4.184);
735  }
736  if (hasDGO == 0) {
737  doublereal DHjmol = m_deltaH_formation_tr_pr * 1.0E3 * 4.184;
738  m_Mu0_tr_pr = DHjmol - 298.15 * (m_Entrop_tr_pr * 1.0E3 * 4.184);
739  m_deltaG_formation_tr_pr = m_Mu0_tr_pr / (1.0E3 * 4.184);
740  double tmp = m_Mu0_tr_pr;
743  double totalSum = m_Mu0_tr_pr - tmp;
744  m_Mu0_tr_pr = tmp;
745  m_deltaG_formation_tr_pr = (m_Mu0_tr_pr - totalSum)/ (1.0E3 * 4.184);
746  }
747  if (hasSO == 0) {
750  doublereal DHjmol = m_deltaH_formation_tr_pr * 1.0E3 * 4.184;
751  m_Entrop_tr_pr = (DHjmol - m_Mu0_tr_pr) / (298.15 * 1.0E3 * 4.184);
752  }
753 
754 }
755 
757  const std::string& inputFile,
758  const std::string& id)
759 {
760  if (inputFile.size() == 0) {
761  throw CanteraError("PDSS_HKFT::initThermo",
762  "input file is null");
763  }
764  std::string path = findInputFile(inputFile);
765  ifstream fin(path.c_str());
766  if (!fin) {
767  throw CanteraError("PDSS_HKFT::initThermo","could not open "
768  +path+" for reading.");
769  }
770  /*
771  * The phase object automatically constructs an XML object.
772  * Use this object to store information.
773  */
774 
775  XML_Node* fxml = new XML_Node();
776  fxml->build(fin);
777  XML_Node* fxml_phase = findXMLPhase(fxml, id);
778  if (!fxml_phase) {
779  throw CanteraError("PDSS_HKFT::initThermo",
780  "ERROR: Can not find phase named " +
781  id + " in file named " + inputFile);
782  }
783 
784  XML_Node& speciesList = fxml_phase->child("speciesArray");
785  XML_Node* speciesDB = get_XML_NameID("speciesData", speciesList["datasrc"],
786  &(fxml_phase->root()));
787  const vector<string>&sss = tp->speciesNames();
788  const XML_Node* s = speciesDB->findByAttr("name", sss[spindex]);
789 
790  constructPDSSXML(tp, spindex, *s, *fxml_phase, true);
791  delete fxml;
792 }
793 
794 #ifdef DEBUG_MODE
795 doublereal PDSS_HKFT::deltaH() const
796 {
797  doublereal pbar = m_pres * 1.0E-5;
798 
799  doublereal c1term = m_c1 * (m_temp - 298.15);
800 
801  doublereal a1term = m_a1 * (pbar - m_presR_bar);
802 
803  doublereal a2term = m_a2 * log((2600. + pbar)/(2600. + m_presR_bar));
804 
805  doublereal c2term = -m_c2 * (1.0/(m_temp - 228.) - 1.0/(298.15 - 228.));
806 
807  double a3tmp = (2.0 * m_temp - 228.)/ (m_temp - 228.) /(m_temp - 228.);
808 
809  doublereal a3term = m_a3 * a3tmp * (pbar - m_presR_bar);
810 
811  doublereal a4term = m_a4 * a3tmp * log((2600. + pbar)/(2600. + m_presR_bar));
812 
813  doublereal omega_j;
814  doublereal domega_jdT;
815  if (m_charge_j == 0.0) {
816  omega_j = m_omega_pr_tr;
817  domega_jdT = 0.0;
818  } else {
819  doublereal nu = 166027;
820  doublereal r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
821  doublereal gval = gstar(m_temp, m_pres, 0);
822  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
823 
824  doublereal dgvaldT = gstar(m_temp, m_pres, 1);
825  doublereal dr_e_jdT = fabs(m_charge_j) * dgvaldT;
826 
827  omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
828 
829  domega_jdT = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
830  + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
831  }
832 
833  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
834  doublereal drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
835 
836  doublereal Y = drelepsilondT / (relepsilon * relepsilon);
837 
838  doublereal Z = -1.0 / relepsilon;
839 
840  doublereal yterm = m_temp * omega_j * Y;
841  doublereal yrterm = - 298.15 * m_omega_pr_tr * m_Y_pr_tr;
842 
843  doublereal wterm = - omega_j * (Z + 1.0);
844  doublereal wrterm = + m_omega_pr_tr * (m_Z_pr_tr + 1.0);
845 
846  doublereal otterm = m_temp * domega_jdT * (Z + 1.0);
847  doublereal otrterm = - m_temp * m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
848 
849  doublereal deltaH_calgmol = c1term + a1term + a2term + c2term + a3term + a4term
850  + yterm + yrterm + wterm + wrterm + otterm + otrterm;
851 
852  // Convert to Joules / kmol
853  return deltaH_calgmol * 1.0E3 * 4.184;
854 }
855 #endif
856 
857 doublereal PDSS_HKFT::deltaG() const
858 {
859  doublereal pbar = m_pres * 1.0E-5;
860  //doublereal m_presR_bar = OneAtm * 1.0E-5;
861 
862  doublereal sterm = - m_Entrop_tr_pr * (m_temp - 298.15);
863 
864  doublereal c1term = -m_c1 * (m_temp * log(m_temp/298.15) - (m_temp - 298.15));
865  doublereal a1term = m_a1 * (pbar - m_presR_bar);
866 
867  doublereal a2term = m_a2 * log((2600. + pbar)/(2600. + m_presR_bar));
868 
869  doublereal c2term = -m_c2 * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.)) * (228. - m_temp)/228.
870  - m_temp / (228.*228.) * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
871 
872  doublereal a3term = m_a3 / (m_temp - 228.) * (pbar - m_presR_bar);
873 
874  doublereal a4term = m_a4 / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
875 
876  doublereal omega_j;
877  if (m_charge_j == 0.0) {
878  omega_j = m_omega_pr_tr;
879  } else {
880  doublereal nu = 166027;
881  doublereal r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
882  doublereal gval = gstar(m_temp, m_pres, 0);
883  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
884  omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
885  }
886 
887  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
888 
889  doublereal Z = -1.0 / relepsilon;
890 
891  doublereal wterm = - omega_j * (Z + 1.0);
892 
893  doublereal wrterm = m_omega_pr_tr * (m_Z_pr_tr + 1.0);
894 
895  doublereal yterm = m_omega_pr_tr * m_Y_pr_tr * (m_temp - 298.15);
896 
897  doublereal deltaG_calgmol = sterm + c1term + a1term + a2term + c2term + a3term + a4term + wterm + wrterm + yterm;
898 
899  // Convert to Joules / kmol
900  return deltaG_calgmol * 1.0E3 * 4.184;
901 }
902 
903 doublereal PDSS_HKFT::deltaS() const
904 {
905  doublereal pbar = m_pres * 1.0E-5;
906 
907  doublereal c1term = m_c1 * log(m_temp/298.15);
908 
909  doublereal c2term = -m_c2 / 228. * ((1.0/(m_temp - 228.) - 1.0/(298.15 - 228.))
910  + 1.0 / 228. * log((298.15*(m_temp-228.)) / (m_temp*(298.15-228.))));
911 
912  doublereal a3term = m_a3 / (m_temp - 228.) / (m_temp - 228.) * (pbar - m_presR_bar);
913 
914  doublereal a4term = m_a4 / (m_temp - 228.) / (m_temp - 228.) * log((2600. + pbar)/(2600. + m_presR_bar));
915 
916  doublereal omega_j;
917  doublereal domega_jdT;
918  if (m_charge_j == 0.0) {
919  omega_j = m_omega_pr_tr;
920  domega_jdT = 0.0;
921  } else {
922 
923  doublereal nu = 166027;
924  doublereal r_e_j_pr_tr = m_charge_j * m_charge_j / (m_omega_pr_tr/nu + m_charge_j/3.082);
925 
926  doublereal gval = gstar(m_temp, m_pres, 0);
927 
928  doublereal dgvaldT = gstar(m_temp, m_pres, 1);
929 
930  doublereal r_e_j = r_e_j_pr_tr + fabs(m_charge_j) * gval;
931  doublereal dr_e_jdT = fabs(m_charge_j) * dgvaldT;
932 
933  omega_j = nu * (m_charge_j * m_charge_j / r_e_j - m_charge_j / (3.082 + gval));
934 
935  domega_jdT = - nu * (m_charge_j * m_charge_j / (r_e_j * r_e_j) * dr_e_jdT)
936  + nu * m_charge_j / (3.082 + gval) / (3.082 + gval) * dgvaldT;
937  }
938 
939  doublereal relepsilon = m_waterProps->relEpsilon(m_temp, m_pres, 0);
940  doublereal drelepsilondT = m_waterProps->relEpsilon(m_temp, m_pres, 1);
941 
942  doublereal Y = drelepsilondT / (relepsilon * relepsilon);
943 
944  doublereal Z = -1.0 / relepsilon;
945 
946  doublereal wterm = omega_j * Y;
947 
948  doublereal wrterm = - m_omega_pr_tr * m_Y_pr_tr;
949 
950  doublereal otterm = domega_jdT * (Z + 1.0);
951 
952  doublereal otrterm = - m_domega_jdT_prtr * (m_Z_pr_tr + 1.0);
953 
954  doublereal deltaS_calgmol = c1term + c2term + a3term + a4term + wterm + wrterm + otterm + otrterm;
955 
956  // Convert to Joules / kmol
957  return deltaS_calgmol * 1.0E3 * 4.184;
958 }
959 
960 doublereal PDSS_HKFT::ag(const doublereal temp, const int ifunc) const
961 {
962  static doublereal ag_coeff[3] = { -2.037662, 5.747000E-3, -6.557892E-6};
963  if (ifunc == 0) {
964  doublereal t2 = temp * temp;
965  return ag_coeff[0] + ag_coeff[1] * temp + ag_coeff[2] * t2;
966  } else if (ifunc == 1) {
967  return ag_coeff[1] + ag_coeff[2] * 2.0 * temp;
968  }
969  if (ifunc != 2) {
970  return 0.0;
971  }
972  return ag_coeff[2] * 2.0;
973 }
974 
975 doublereal PDSS_HKFT::bg(const doublereal temp, const int ifunc) const
976 {
977  static doublereal bg_coeff[3] = { 6.107361, -1.074377E-2, 1.268348E-5};
978  if (ifunc == 0) {
979  doublereal t2 = temp * temp;
980  return bg_coeff[0] + bg_coeff[1] * temp + bg_coeff[2] * t2;
981  } else if (ifunc == 1) {
982  return bg_coeff[1] + bg_coeff[2] * 2.0 * temp;
983  }
984  if (ifunc != 2) {
985  return 0.0;
986  }
987  return bg_coeff[2] * 2.0;
988 }
989 
990 doublereal PDSS_HKFT::f(const doublereal temp, const doublereal pres, const int ifunc) const
991 {
992  static doublereal af_coeff[3] = { 3.666666E1, -0.1504956E-9, 0.5107997E-13};
993  doublereal TC = temp - 273.15;
994  doublereal presBar = pres / 1.0E5;
995 
996  if (TC < 155.0) {
997  return 0.0;
998  }
999  if (TC > 355.0) {
1000  TC = 355.0;
1001  }
1002  if (presBar > 1000.) {
1003  return 0.0;
1004  }
1005 
1006 
1007  doublereal T1 = (TC-155.0)/300.;
1008  doublereal fac1;
1009 
1010  doublereal p2 = (1000. - presBar) * (1000. - presBar);
1011  doublereal p3 = (1000. - presBar) * p2;
1012  doublereal p4 = p2 * p2;
1013  doublereal fac2 = af_coeff[1] * p3 + af_coeff[2] * p4;
1014  if (ifunc == 0) {
1015  fac1 = pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0);
1016  return fac1 * fac2;
1017  } else if (ifunc == 1) {
1018  fac1 = (4.8 * pow(T1,3.8) + 16.0 * af_coeff[0] * pow(T1, 15.0)) / 300.;
1019  return fac1 * fac2;
1020  } else if (ifunc == 2) {
1021  fac1 = (4.8 * 3.8 * pow(T1,2.8) + 16.0 * 15.0 * af_coeff[0] * pow(T1, 14.0)) / (300. * 300.);
1022  return fac1 * fac2;
1023  } else if (ifunc == 3) {
1024  fac1 = pow(T1,4.8) + af_coeff[0] * pow(T1, 16.0);
1025  fac2 = - (3.0 * af_coeff[1] * p2 + 4.0 * af_coeff[2] * p3)/ 1.0E5;
1026  return fac1 * fac2;
1027  } else {
1028  throw CanteraError("HKFT_PDSS::gg", "unimplemented");
1029  }
1030  return 0.0;
1031 }
1032 
1033 doublereal PDSS_HKFT::g(const doublereal temp, const doublereal pres, const int ifunc) const
1034 {
1035  doublereal afunc = ag(temp, 0);
1036  doublereal bfunc = bg(temp, 0);
1037  m_waterSS->setState_TP(temp, pres);
1039  // density in gm cm-3
1040  doublereal dens = m_densWaterSS * 1.0E-3;
1041  doublereal gval = afunc * pow((1.0-dens), bfunc);
1042  if (dens >= 1.0) {
1043  return 0.0;
1044  }
1045  if (ifunc == 0) {
1046  return gval;
1047 
1048  } else if (ifunc == 1 || ifunc == 2) {
1049  doublereal afuncdT = ag(temp, 1);
1050  doublereal bfuncdT = bg(temp, 1);
1051  doublereal alpha = m_waterSS->thermalExpansionCoeff();
1052 
1053  doublereal fac1 = afuncdT * gval / afunc;
1054  doublereal fac2 = bfuncdT * gval * log(1.0 - dens);
1055  doublereal fac3 = gval * alpha * bfunc * dens / (1.0 - dens);
1056 
1057  doublereal dgdt = fac1 + fac2 + fac3;
1058  if (ifunc == 1) {
1059  return dgdt;
1060  }
1061 
1062  doublereal afuncdT2 = ag(temp, 2);
1063  doublereal bfuncdT2 = bg(temp, 2);
1064 
1065  doublereal dfac1dT = dgdt * afuncdT / afunc + afuncdT2 * gval / afunc
1066  - afuncdT * afuncdT * gval / (afunc * afunc);
1067 
1068  doublereal ddensdT = - alpha * dens;
1069  doublereal dfac2dT = bfuncdT2 * gval * log(1.0 - dens)
1070  + bfuncdT * dgdt * log(1.0 - dens)
1071  - bfuncdT * gval /(1.0 - dens) * ddensdT;
1072 
1073  doublereal dalphadT = m_waterSS->dthermalExpansionCoeffdT();
1074 
1075  doublereal dfac3dT = dgdt * alpha * bfunc * dens / (1.0 - dens)
1076  + gval * dalphadT * bfunc * dens / (1.0 - dens)
1077  + gval * alpha * bfuncdT * dens / (1.0 - dens)
1078  + gval * alpha * bfunc * ddensdT / (1.0 - dens)
1079  + gval * alpha * bfunc * dens / ((1.0 - dens) * (1.0 - dens)) * ddensdT;
1080 
1081  return dfac1dT + dfac2dT + dfac3dT;
1082 
1083  } else if (ifunc == 3) {
1084  doublereal beta = m_waterSS->isothermalCompressibility();
1085 
1086  return - bfunc * gval * dens * beta / (1.0 - dens);
1087  } else {
1088  throw CanteraError("HKFT_PDSS::g", "unimplemented");
1089  }
1090  return 0.0;
1091 }
1092 
1093 doublereal PDSS_HKFT::gstar(const doublereal temp, const doublereal pres, const int ifunc) const
1094 {
1095  doublereal gval = g(temp, pres, ifunc);
1096  doublereal fval = f(temp, pres, ifunc);
1097  double res = gval - fval;
1098 #ifdef DEBUG_MODE_NOT
1099  if (ifunc == 2) {
1100  double gval1 = g(temp, pres, 1);
1101  double fval1 = f(temp, pres, 1);
1102  double gval2 = g(temp + 0.001, pres, 1);
1103  double fval2 = f(temp + 0.001, pres, 1);
1104  double gvalT = (gval2 - gval1) / 0.001;
1105  double fvalT = (fval2 - fval1) / 0.001;
1106  if (fabs(gvalT - gval) > 1.0E-9) {
1107  printf("we are here\n");
1108  }
1109  if (fabs(fvalT - fval) > 1.0E-9) {
1110  printf("we are here\n");
1111  }
1112  // return gvalT - fvalT;
1113  }
1114 #endif
1115  return res;
1116 }
1117 
1118 doublereal PDSS_HKFT::LookupGe(const std::string& elemName)
1119 {
1120  size_t iE = m_tp->elementIndex(elemName);
1121  if (iE == npos) {
1122  throw CanteraError("PDSS_HKFT::LookupGe", "element " + elemName + " not found");
1123  }
1124  doublereal geValue = m_tp->entropyElement298(iE);
1125  if (geValue == ENTROPY298_UNKNOWN) {
1126  throw CanteraError("PDSS_HKFT::LookupGe",
1127  "element " + elemName + " does not have a supplied entropy298");
1128  }
1129  geValue *= (-298.15);
1130  return geValue;
1131 }
1132 
1134 {
1135  /*
1136  * Ok let's get the element compositions and conversion factors.
1137  */
1138  size_t ne = m_tp->nElements();
1139  doublereal na;
1140  doublereal ge;
1141  string ename;
1142 
1143  doublereal totalSum = 0.0;
1144  for (size_t m = 0; m < ne; m++) {
1145  na = m_tp->nAtoms(m_spindex, m);
1146  if (na > 0.0) {
1147  ename = m_tp->elementName(m);
1148  ge = LookupGe(ename);
1149  totalSum += na * ge;
1150  }
1151  }
1152  // Add in the charge
1153  if (m_charge_j != 0.0) {
1154  ename = "H";
1155  ge = LookupGe(ename);
1156  totalSum -= m_charge_j * ge;
1157  }
1158  // Ok, now do the calculation. Convert to joules kmol-1
1159  doublereal dg = m_deltaG_formation_tr_pr * 4.184 * 1.0E3;
1160  //! Store the result into an internal variable.
1161  m_Mu0_tr_pr = dg + totalSum;
1162 }
1163 
1164 void PDSS_HKFT::reportParams(size_t& kindex, int& type,
1165  doublereal* const c,
1166  doublereal& minTemp_,
1167  doublereal& maxTemp_,
1168  doublereal& refPressure_) const
1169 {
1170  warn_deprecated("PDSS_HKFT::reportParams");
1171  // Fill in the first part
1172  PDSS::reportParams(kindex, type, c, minTemp_, maxTemp_,
1173  refPressure_);
1174 
1175  c[0] = m_deltaG_formation_tr_pr;
1176  c[1] = m_deltaH_formation_tr_pr;
1177  c[2] = m_Mu0_tr_pr;
1178  c[3] = m_Entrop_tr_pr;
1179  c[4] = m_a1;
1180  c[5] = m_a2;
1181  c[6] = m_a3;
1182  c[7] = m_a4;
1183  c[8] = m_c1;
1184  c[9] = m_c2;
1185  c[10] = m_omega_pr_tr;
1186 }
1187 
1188 }
virtual doublereal gibbs_RT() const
Return the molar Gibbs free energy divided by RT.
Definition: PDSS.cpp:252
virtual doublereal enthalpy_RT() const
Return the standard state molar enthalpy divided by RT.
Definition: PDSS_HKFT.cpp:222
doublereal nAtoms(size_t k, size_t m) const
Number of atoms of element m in species k.
Definition: Phase.cpp:215
virtual doublereal enthalpy_mole() const
Return the molar enthalpy in units of J kmol-1.
Definition: PDSS_HKFT.cpp:204
XML_Node * findByAttr(const std::string &attr, const std::string &val, int depth=100000) const
This routine carries out a recursive search for an XML node based on an attribute of each XML node...
Definition: xml.cpp:716
doublereal m_a4
Input a4 coefficient (cal K gmol-1)
Definition: PDSS_HKFT.h:424
virtual void setTemperature(doublereal temp)
Set the internal temperature.
Definition: PDSS_HKFT.cpp:482
virtual doublereal thermalExpansionCoeff() const
Return the volumetric thermal expansion coefficient. Units: 1/K.
Definition: PDSS_Water.cpp:395
doublereal m_densWaterSS
density of standard-state water
Definition: PDSS_HKFT.h:370
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual doublereal density() const
Return the standard state density at standard state.
Definition: PDSS_HKFT.cpp:414
doublereal f(const doublereal temp, const doublereal pres, const int ifunc=0) const
Difference function f appearing in the formulation.
Definition: PDSS_HKFT.cpp:990
virtual doublereal critTemperature() const
critical temperature
Definition: PDSS_HKFT.cpp:499
XML_Node * findXMLPhase(XML_Node *root, const std::string &idtarget)
Search an XML_Node tree for a named phase XML_Node.
Definition: xml.cpp:1104
virtual void setState_TP(doublereal temp, doublereal pres)
Set the internal temperature and pressure.
Definition: PDSS_HKFT.cpp:492
size_t nElements() const
Number of elements.
Definition: Phase.cpp:139
doublereal bg(const doublereal temp, const int ifunc=0) const
Internal formula for the calculation of b_g()
Definition: PDSS_HKFT.cpp:975
doublereal m_deltaG_formation_tr_pr
Input value of deltaG of Formation at Tr and Pr (cal gmol-1)
Definition: PDSS_HKFT.h:388
doublereal gstar(const doublereal temp, const doublereal pres, const int ifunc=0) const
Evaluate the Gstar value appearing in the HKFT formulation.
Definition: PDSS_HKFT.cpp:1093
const doublereal OneAtm
One atmosphere [Pa].
Definition: ct_defs.h:71
Virtual base class for the classes that manage the calculation of standard state properties for all t...
Definition: VPSSMgr.h:238
std::string findInputFile(const std::string &name)
Find an input file.
Definition: global.cpp:191
virtual void initThermoXML(const XML_Node &phaseNode, const std::string &id)
Initialization routine for the PDSS object based on the phaseNode.
Definition: PDSS.cpp:175
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:173
virtual doublereal cv_mole() const
Return the molar const volume heat capacity in units of J kmol-1 K-1.
Definition: PDSS_HKFT.cpp:353
doublereal m_Mu0_tr_pr
Value of the Absolute Gibbs Free Energy NIST scale at T_r and P_r.
Definition: PDSS_HKFT.h:406
doublereal enthalpy_mole2() const
Return the molar enthalpy in units of J kmol-1.
Definition: PDSS_HKFT.cpp:230
doublereal deltaG() const
Main routine that actually calculates the gibbs free energy difference between the reference state at...
Definition: PDSS_HKFT.cpp:857
doublereal m_pres
State of the system - pressure.
Definition: PDSS.h:576
doublereal m_c2
Input c2 coefficient (cal K gmol-1)
Definition: PDSS_HKFT.h:430
virtual doublereal pressure() const
Returns the pressure (Pa)
Definition: PDSS_HKFT.cpp:471
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
Implementation of a pressure dependent standard state virtual function for a Pure Water Phase (see Sp...
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:76
doublereal getFloat(const Cantera::XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:267
virtual doublereal cp_mole() const
Return the molar const pressure heat capacity in units of J kmol-1 K-1.
Definition: PDSS_HKFT.cpp:257
virtual doublereal dthermalExpansionCoeffdT() const
Return the derivative of the volumetric thermal expansion coefficient. Units: 1/K2.
Definition: PDSS_Water.cpp:400
virtual void initAllPtrs(VPStandardStateTP *vptp_ptr, VPSSMgr *vpssmgr_ptr, SpeciesThermo *spthermo_ptr)
Initialize or Reinitialize all shallow pointers in the object.
Definition: PDSS.cpp:192
Header for a class used to house several approximation routines for properties of water...
virtual ~PDSS_HKFT()
Destructor for the phase.
Definition: PDSS_HKFT.cpp:194
doublereal m_a3
Input a3 coefficient (cal K gmol-1 bar-1)
Definition: PDSS_HKFT.h:421
size_t m_spindex
Species index in the ThermoPhase corresponding to this species.
Definition: PDSS.h:606
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:58
virtual doublereal density() const
Return the standard state density at standard state.
Definition: PDSS_Water.cpp:442
PDSS_enumType m_pdssType
Enumerated type describing the type of the PDSS object.
Definition: PDSS.h:570
doublereal deltaS() const
Main routine that actually calculates the entropy difference between the reference state at Tr...
Definition: PDSS_HKFT.cpp:903
PDSS_HKFT & operator=(const PDSS_HKFT &b)
Assignment operator.
Definition: PDSS_HKFT.cpp:152
doublereal m_omega_pr_tr
Input omega_pr_tr coefficient(cal gmol-1)
Definition: PDSS_HKFT.h:433
Pure Virtual base class for the species thermo manager classes.
doublereal m_Y_pr_tr
y = dZdT = 1/(esp*esp) desp/dT at 298.15 and 1 bar
Definition: PDSS_HKFT.h:436
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:584
virtual void initAllPtrs(VPStandardStateTP *vptp_ptr, VPSSMgr *vpssmgr_ptr, SpeciesThermo *spthermo_ptr)
Initialize or Reinitialize all shallow pointers in the object.
Definition: PDSS_HKFT.cpp:587
doublereal entropyElement298(size_t m) const
Entropy of the element in its standard state at 298 K and 1 bar.
Definition: Phase.cpp:184
const XML_Node * findByName(const std::string &nm, int depth=100000) const
This routine carries out a recursive search for an XML node based on the name of the node...
Definition: xml.cpp:754
doublereal pref_safe(doublereal temp) const
Returns a reference pressure value that can be safely calculated by the underlying real equation of s...
Definition: PDSS_Water.cpp:467
doublereal g(const doublereal temp, const doublereal pres, const int ifunc=0) const
function g appearing in the formulation
Definition: PDSS_HKFT.cpp:1033
virtual doublereal entropy_R() const
Return the standard state entropy divided by RT.
Definition: PDSS.cpp:241
virtual void initThermo()
Initialization routine for all of the shallow pointers.
Definition: PDSS_HKFT.cpp:517
doublereal m_a2
Input a2 coefficient (cal gmol-1)
Definition: PDSS_HKFT.h:418
doublereal m_charge_j
Charge of the ion.
Definition: PDSS_HKFT.h:448
virtual void initThermo()
Initialization routine for all of the shallow pointers.
Definition: PDSS.cpp:183
virtual doublereal entropy_mole() const
Return the molar entropy in units of J kmol-1 K-1.
Definition: PDSS_HKFT.cpp:245
void constructPDSSXML(VPStandardStateTP *vptp_ptr, size_t spindex, const XML_Node &speciesNode, const XML_Node &phaseNode, bool spInstalled)
Initialization of a PDSS object using an xml tree.
Definition: PDSS_HKFT.cpp:596
virtual void setPressure(doublereal pres)
Sets the pressure in the object.
Definition: PDSS_HKFT.cpp:477
The WaterProps class is used to house several approximation routines for properties of water...
Definition: WaterProps.h:96
virtual void setState_TP(doublereal temp, doublereal pres)
Set the internal temperature and pressure.
Definition: PDSS_Water.cpp:454
PDSS_HKFT(VPStandardStateTP *tp, size_t spindex)
Constructor that initializes the object by examining the XML entries from the ThermoPhase object...
Definition: PDSS_HKFT.cpp:27
std::string fp2str(const double x, const std::string &fmt)
Convert a double into a c++ string.
Definition: stringUtils.cpp:29
Class for the liquid water pressure dependent standard state.
Definition: PDSS_Water.h:54
doublereal m_deltaH_formation_tr_pr
Input value of deltaH of Formation at Tr and Pr (cal gmol-1)
Definition: PDSS_HKFT.h:397
std::string name() const
Returns the name of the XML node.
Definition: xml.h:390
virtual doublereal entropy_R_ref() const
Return the molar entropy divided by R at reference pressure.
Definition: PDSS_HKFT.cpp:441
doublereal deltaH() const
Routine that actually calculates the enthalpy difference between the reference state at Tr...
Definition: PDSS_HKFT.cpp:795
doublereal m_Entrop_tr_pr
Input value of S_j at Tr and Pr (cal gmol-1 K-1)
Definition: PDSS_HKFT.h:412
virtual doublereal molarVolume_ref() const
Return the molar volume at reference pressure.
Definition: PDSS_HKFT.cpp:461
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:68
WaterProps * m_waterProps
Pointer to the water property calculator.
Definition: PDSS_HKFT.h:373
void convertDGFormation()
Translate a Gibbs free energy of formation value to a NIST-based Chemical potential.
Definition: PDSS_HKFT.cpp:1133
virtual doublereal molarVolume() const
Return the molar volume at standard state.
Definition: PDSS_HKFT.cpp:359
doublereal m_presR_bar
Reference pressure is 1 atm in units of bar= 1.0132.
Definition: PDSS_HKFT.h:442
This is a filter class for ThermoPhase that implements some prepatory steps for efficiently handling ...
virtual doublereal critPressure() const
critical pressure
Definition: PDSS_HKFT.cpp:505
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:574
virtual doublereal enthalpy_RT_ref() const
Return the molar enthalpy divided by RT at reference pressure.
Definition: PDSS_HKFT.cpp:431
doublereal m_maxTemp
Maximum temperature.
Definition: PDSS.h:585
doublereal m_domega_jdT_prtr
small value that is not quite zero
Definition: PDSS_HKFT.h:445
doublereal m_minTemp
Minimum temperature.
Definition: PDSS.h:582
virtual doublereal gibbs_RT_ref() const
Return the molar gibbs free energy divided by RT at reference pressure.
Definition: PDSS_HKFT.cpp:421
#define ENTROPY298_UNKNOWN
Number indicating we don't know the entropy of the element in its most stable state at 298...
Definition: Elements.h:84
virtual void reportParams(size_t &kindex, int &type, doublereal *const c, doublereal &minTemp, doublereal &maxTemp, doublereal &refPressure) const
This utility function reports back the type of parameterization and all of the parameters for the spe...
Definition: PDSS_HKFT.cpp:1164
PDSS_Water * m_waterSS
Water standard state calculator.
Definition: PDSS_HKFT.h:364
doublereal ag(const doublereal temp, const int ifunc=0) const
Internal formula for the calculation of a_g()
Definition: PDSS_HKFT.cpp:960
const std::vector< std::string > & speciesNames() const
Return a const reference to the vector of species names.
Definition: Phase.cpp:252
virtual void initThermoXML(const XML_Node &phaseNode, const std::string &id)
Initialization routine for the PDSS object based on the phaseNode.
Definition: PDSS_HKFT.cpp:582
doublereal LookupGe(const std::string &elemName)
Function to look up Element Free Energies.
Definition: PDSS_HKFT.cpp:1118
virtual void reportParams(size_t &kindex, int &type, doublereal *const c, doublereal &minTemp, doublereal &maxTemp, doublereal &refPressure) const
This utility function reports back the type of parameterization and all of the parameters for the spe...
Definition: PDSS.cpp:419
virtual doublereal cp_R() const
Return the molar const pressure heat capacity divided by RT.
Definition: PDSS.cpp:264
doublereal m_Z_pr_tr
Z = -1 / relEpsilon at 298.15 and 1 bar.
Definition: PDSS_HKFT.h:439
Virtual base class for a species with a pressure dependent standard state.
Definition: PDSS.h:195
size_t elementIndex(const std::string &name) const
Return the index of element named 'name'.
Definition: Phase.cpp:164
VPStandardStateTP * m_tp
ThermoPhase which this species belongs to.
Definition: PDSS.h:593
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:66
doublereal m_temp
Current temperature used by the PDSS object.
Definition: PDSS.h:573
virtual doublereal isothermalCompressibility() const
Returns the isothermal compressibility. Units: 1/Pa.
Definition: PDSS_Water.cpp:416
PDSS & operator=(const PDSS &b)
Assignment operator.
Definition: PDSS.cpp:110
Contains declarations for string manipulation functions within Cantera.
std::string elementName(size_t m) const
Name of the element with index m.
Definition: Phase.cpp:158
Class for pressure dependent standard states corresponding to ionic solutes in electrolyte water...
Definition: PDSS_HKFT.h:32
doublereal m_c1
Input c1 coefficient (cal gmol-1 K-1)
Definition: PDSS_HKFT.h:427
virtual PDSS * duplMyselfAsPDSS() const
Duplication routine for objects which inherit from PDSS.
Definition: PDSS_HKFT.cpp:199
virtual doublereal gibbs_mole() const
Return the molar Gibbs free energy in units of J kmol-1.
Definition: PDSS_HKFT.cpp:251
doublereal relEpsilon(doublereal T, doublereal P_pascal, int ifunc=0)
Bradley-Pitzer equation for the dielectric constant of water as a function of temperature and pressur...
Definition: WaterProps.cpp:143
doublereal m_r_e_j
Electrostatic radii.
Definition: PDSS_HKFT.h:379
XML_Node & root() const
Return the root of the current XML_Node tree.
Definition: xml.cpp:1091
doublereal m_born_coeff_j
Born coefficient for the current ion or species.
Definition: PDSS_HKFT.h:376
doublereal strSItoDbl(const std::string &strSI)
Interpret one or two token string as a single double.
virtual doublereal critDensity() const
critical density
Definition: PDSS_HKFT.cpp:511
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
void build(std::istream &f)
Main routine to create an tree-like representation of an XML file.
Definition: xml.cpp:776
XML_Node * get_XML_NameID(const std::string &nameTarget, const std::string &file_ID, XML_Node *root)
This routine will locate an XML node in either the input XML tree or in another input file specified ...
Definition: global.cpp:271
virtual doublereal cp_R_ref() const
Return the molar heat capacity divided by R at reference pressure.
Definition: PDSS_HKFT.cpp:451
Declarations for the class PDSS_HKFT (pressure dependent standard state) which handles calculations f...
doublereal m_p0
Reference state pressure of the species.
Definition: PDSS.h:579
doublereal m_a1
Input a1 coefficient (cal gmol-1 bar-1)
Definition: PDSS_HKFT.h:415
doublereal m_mw
Molecular Weight of the species.
Definition: PDSS.h:601
void constructPDSSFile(VPStandardStateTP *vptp_ptr, size_t spindex, const std::string &inputFile, const std::string &id)
Initialization of a PDSS object using an input XML file.
Definition: PDSS_HKFT.cpp:756
virtual doublereal intEnergy_mole() const
Return the molar internal Energy in units of J kmol-1.
Definition: PDSS_HKFT.cpp:238
doublereal 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:504