Cantera  2.3.0
ThermoPhase.cpp
Go to the documentation of this file.
1 /**
2  * @file ThermoPhase.cpp
3  * Definition file for class ThermoPhase, the base class for phases with
4  * thermodynamic properties
5  * (see class \link Cantera::ThermoPhase ThermoPhase\endlink).
6  */
7 
8 // This file is part of Cantera. See License.txt in the top-level directory or
9 // at http://www.cantera.org/license.txt for license and copyright information.
10 
17 #include "cantera/base/ctml.h"
18 
19 #include <iomanip>
20 #include <fstream>
21 
22 using namespace std;
23 
24 namespace Cantera
25 {
26 
27 ThermoPhase::ThermoPhase() :
28  m_spthermo(new MultiSpeciesThermo()), m_speciesData(0),
29  m_phi(0.0),
30  m_hasElementPotentials(false),
31  m_chargeNeutralityNecessary(false),
32  m_ssConvention(cSS_CONVENTION_TEMPERATURE),
33  m_tlast(0.0)
34 {
35 }
36 
37 ThermoPhase::~ThermoPhase()
38 {
39  for (size_t k = 0; k < m_speciesData.size(); k++) {
40  delete m_speciesData[k];
41  }
42  delete m_spthermo;
43 }
44 
46  m_spthermo(new MultiSpeciesThermo()),
47  m_speciesData(0),
48  m_phi(0.0),
49  m_hasElementPotentials(false),
50  m_chargeNeutralityNecessary(false),
51  m_ssConvention(cSS_CONVENTION_TEMPERATURE)
52 {
53  warn_deprecated("ThermoPhase copy constructor", "To be removed after"
54  " Cantera 2.3 for all classes derived from ThermoPhase.");
55  // Call the assignment operator
56  *this = right;
57 }
58 
60 {
61  warn_deprecated("ThermoPhase assignment operator", "To be removed after"
62  " Cantera 2.3 for all classes derived from ThermoPhase.");
63  // Check for self assignment.
64  if (this == &right) {
65  return *this;
66  }
67 
68  // We need to destruct first
69  for (size_t k = 0; k < m_speciesData.size(); k++) {
70  delete m_speciesData[k];
71  }
72  delete m_spthermo;
73 
74  // Call the base class assignment operator
75  Phase::operator=(right);
76 
77  // Pointer to the species thermodynamic property manager
78  // We own this, so we need to do a deep copy
80 
81  // Do a deep copy of species Data, because we own this
82  m_speciesData.resize(m_kk);
83  for (size_t k = 0; k < m_kk; k++) {
84  m_speciesData[k] = new XML_Node(*(right.m_speciesData[k]));
85  }
86 
87  m_phi = right.m_phi;
88  m_lambdaRRT = right.m_lambdaRRT;
92  m_tlast = right.m_tlast;
93  return *this;
94 }
95 
97 {
98  warn_deprecated("ThermoPhase::duplMyselfAsThermoPhase",
99  "To be removed after Cantera 2.3.");
100  return new ThermoPhase(*this);
101 }
102 
103 void ThermoPhase::resetHf298(size_t k) {
104  if (k != npos) {
106  } else {
107  for (size_t k = 0; k < nSpecies(); k++) {
109  }
110  }
111  invalidateCache();
112 }
113 
115 {
116  return cAC_CONVENTION_MOLAR;
117 }
118 
120 {
121  return m_ssConvention;
122 }
123 
124 doublereal ThermoPhase::logStandardConc(size_t k) const
125 {
126  return log(standardConcentration(k));
127 }
128 
129 void ThermoPhase::getActivities(doublereal* a) const
130 {
132  for (size_t k = 0; k < nSpecies(); k++) {
133  a[k] /= standardConcentration(k);
134  }
135 }
136 
137 void ThermoPhase::getLnActivityCoefficients(doublereal* lnac) const
138 {
140  for (size_t k = 0; k < m_kk; k++) {
141  lnac[k] = std::log(lnac[k]);
142  }
143 }
144 
145 void ThermoPhase::getElectrochemPotentials(doublereal* mu) const
146 {
147  getChemPotentials(mu);
148  double ve = Faraday * electricPotential();
149  for (size_t k = 0; k < m_kk; k++) {
150  mu[k] += ve*charge(k);
151  }
152 }
153 
154 void ThermoPhase::setState_TPX(doublereal t, doublereal p, const doublereal* x)
155 {
156  setMoleFractions(x);
157  setState_TP(t,p);
158 }
159 
160 void ThermoPhase::setState_TPX(doublereal t, doublereal p, const compositionMap& x)
161 {
163  setState_TP(t,p);
164 }
165 
166 void ThermoPhase::setState_TPX(doublereal t, doublereal p, const std::string& x)
167 {
169  setState_TP(t,p);
170 }
171 
172 void ThermoPhase::setState_TPY(doublereal t, doublereal p, const doublereal* y)
173 {
174  setMassFractions(y);
175  setState_TP(t,p);
176 }
177 
178 void ThermoPhase::setState_TPY(doublereal t, doublereal p, const compositionMap& y)
179 {
181  setState_TP(t,p);
182 }
183 
184 void ThermoPhase::setState_TPY(doublereal t, doublereal p, const std::string& y)
185 {
187  setState_TP(t,p);
188 }
189 
190 void ThermoPhase::setState_TP(doublereal t, doublereal p)
191 {
192  setTemperature(t);
193  setPressure(p);
194 }
195 
196 void ThermoPhase::setState_RPX(doublereal rho, doublereal p, const doublereal* x)
197 {
198  setMoleFractions(x);
199  setState_RP(rho, p);
200 }
201 
202 void ThermoPhase::setState_RPX(doublereal rho, doublereal p, const compositionMap& x)
203 {
205  setState_RP(rho,p);
206 }
207 
208 void ThermoPhase::setState_RPX(doublereal rho, doublereal p, const std::string& x)
209 {
211  setState_RP(rho,p);
212 }
213 
214 void ThermoPhase::setState_RPY(doublereal rho, doublereal p, const doublereal* y)
215 {
216  setMassFractions(y);
217  setState_RP(rho,p);
218 }
219 
220 void ThermoPhase::setState_RPY(doublereal rho, doublereal p, const compositionMap& y)
221 {
223  setState_RP(rho,p);
224 }
225 
226 void ThermoPhase::setState_RPY(doublereal rho, doublereal p, const std::string& y)
227 {
229  setState_RP(rho,p);
230 }
231 
232 void ThermoPhase::setState_PX(doublereal p, doublereal* x)
233 {
234  setMoleFractions(x);
235  setPressure(p);
236 }
237 
238 void ThermoPhase::setState_PY(doublereal p, doublereal* y)
239 {
240  setMassFractions(y);
241  setPressure(p);
242 }
243 
244 void ThermoPhase::setState_HP(double Htarget, double p, double rtol)
245 {
246  setState_HPorUV(Htarget, p, rtol, false);
247 }
248 
249 void ThermoPhase::setState_UV(double u, double v, double rtol)
250 {
251  setState_HPorUV(u, v, rtol, true);
252 }
253 
254 void ThermoPhase::setState_conditional_TP(doublereal t, doublereal p, bool set_p)
255 {
256  setTemperature(t);
257  if (set_p) {
258  setPressure(p);
259  }
260 }
261 
262 void ThermoPhase::setState_HPorUV(double Htarget, double p,
263  double rtol, bool doUV)
264 {
265  doublereal dt;
266  doublereal v = 0.0;
267 
268  // Assign the specific volume or pressure and make sure it's positive
269  if (doUV) {
270  doublereal v = p;
271  if (v < 1.0E-300) {
272  throw CanteraError("setState_HPorUV (UV)",
273  "Input specific volume is too small or negative. v = {}", v);
274  }
275  setDensity(1.0/v);
276  } else {
277  if (p < 1.0E-300) {
278  throw CanteraError("setState_HPorUV (HP)",
279  "Input pressure is too small or negative. p = {}", p);
280  }
281  setPressure(p);
282  }
283  double Tmax = maxTemp() + 0.1;
284  double Tmin = minTemp() - 0.1;
285 
286  // Make sure we are within the temperature bounds at the start
287  // of the iteration
288  double Tnew = temperature();
289  double Tinit = Tnew;
290  if (Tnew > Tmax) {
291  Tnew = Tmax - 1.0;
292  } else if (Tnew < Tmin) {
293  Tnew = Tmin + 1.0;
294  }
295  if (Tnew != Tinit) {
296  setState_conditional_TP(Tnew, p, !doUV);
297  }
298 
299  double Hnew = (doUV) ? intEnergy_mass() : enthalpy_mass();
300  double Cpnew = (doUV) ? cv_mass() : cp_mass();
301  double Htop = Hnew;
302  double Ttop = Tnew;
303  double Hbot = Hnew;
304  double Tbot = Tnew;
305 
306  bool ignoreBounds = false;
307  // Unstable phases are those for which cp < 0.0. These are possible for
308  // cases where we have passed the spinodal curve.
309  bool unstablePhase = false;
310  // Counter indicating the last temperature point where the
311  // phase was unstable
312  double Tunstable = -1.0;
313  bool unstablePhaseNew = false;
314 
315  // Newton iteration
316  for (int n = 0; n < 500; n++) {
317  double Told = Tnew;
318  double Hold = Hnew;
319  double cpd = Cpnew;
320  if (cpd < 0.0) {
321  unstablePhase = true;
322  Tunstable = Tnew;
323  }
324  // limit step size to 100 K
325  dt = clip((Htarget - Hold)/cpd, -100.0, 100.0);
326 
327  // Calculate the new T
328  Tnew = Told + dt;
329 
330  // Limit the step size so that we are convergent This is the step that
331  // makes it different from a Newton's algorithm
332  if ((dt > 0.0 && unstablePhase) || (dt <= 0.0 && !unstablePhase)) {
333  if (Hbot < Htarget && Tnew < (0.75 * Tbot + 0.25 * Told)) {
334  dt = 0.75 * (Tbot - Told);
335  Tnew = Told + dt;
336  }
337  } else if (Htop > Htarget && Tnew > (0.75 * Ttop + 0.25 * Told)) {
338  dt = 0.75 * (Ttop - Told);
339  Tnew = Told + dt;
340  }
341 
342  // Check Max and Min values
343  if (Tnew > Tmax && !ignoreBounds) {
344  setState_conditional_TP(Tmax, p, !doUV);
345  double Hmax = (doUV) ? intEnergy_mass() : enthalpy_mass();
346  if (Hmax >= Htarget) {
347  if (Htop < Htarget) {
348  Ttop = Tmax;
349  Htop = Hmax;
350  }
351  } else {
352  Tnew = Tmax + 1.0;
353  ignoreBounds = true;
354  }
355  }
356  if (Tnew < Tmin && !ignoreBounds) {
357  setState_conditional_TP(Tmin, p, !doUV);
358  double Hmin = (doUV) ? intEnergy_mass() : enthalpy_mass();
359  if (Hmin <= Htarget) {
360  if (Hbot > Htarget) {
361  Tbot = Tmin;
362  Hbot = Hmin;
363  }
364  } else {
365  Tnew = Tmin - 1.0;
366  ignoreBounds = true;
367  }
368  }
369 
370  // Try to keep phase within its region of stability
371  // -> Could do a lot better if I calculate the
372  // spinodal value of H.
373  for (int its = 0; its < 10; its++) {
374  Tnew = Told + dt;
375  if (Tnew < Told / 3.0) {
376  Tnew = Told / 3.0;
377  dt = -2.0 * Told / 3.0;
378  }
379  setState_conditional_TP(Tnew, p, !doUV);
380  if (doUV) {
381  Hnew = intEnergy_mass();
382  Cpnew = cv_mass();
383  } else {
384  Hnew = enthalpy_mass();
385  Cpnew = cp_mass();
386  }
387  if (Cpnew < 0.0) {
388  unstablePhaseNew = true;
389  Tunstable = Tnew;
390  } else {
391  unstablePhaseNew = false;
392  break;
393  }
394  if (unstablePhase == false && unstablePhaseNew == true) {
395  dt *= 0.25;
396  }
397  }
398 
399  if (Hnew == Htarget) {
400  return;
401  } else if (Hnew > Htarget && (Htop < Htarget || Hnew < Htop)) {
402  Htop = Hnew;
403  Ttop = Tnew;
404  } else if (Hnew < Htarget && (Hbot > Htarget || Hnew > Hbot)) {
405  Hbot = Hnew;
406  Tbot = Tnew;
407  }
408  // Convergence in H
409  double Herr = Htarget - Hnew;
410  double acpd = std::max(fabs(cpd), 1.0E-5);
411  double denom = std::max(fabs(Htarget), acpd * Tnew);
412  double HConvErr = fabs((Herr)/denom);
413  if (HConvErr < rtol || fabs(dt/Tnew) < rtol) {
414  return;
415  }
416  }
417  // We are here when there hasn't been convergence
418 
419  // Formulate a detailed error message, since questions seem to arise often
420  // about the lack of convergence.
421  string ErrString = "No convergence in 500 iterations\n";
422  if (doUV) {
423  ErrString += fmt::format(
424  "\tTarget Internal Energy = {}\n"
425  "\tCurrent Specific Volume = {}\n"
426  "\tStarting Temperature = {}\n"
427  "\tCurrent Temperature = {}\n"
428  "\tCurrent Internal Energy = {}\n"
429  "\tCurrent Delta T = {}\n",
430  Htarget, v, Tinit, Tnew, Hnew, dt);
431  } else {
432  ErrString += fmt::format(
433  "\tTarget Enthalpy = {}\n"
434  "\tCurrent Pressure = {}\n"
435  "\tStarting Temperature = {}\n"
436  "\tCurrent Temperature = {}\n"
437  "\tCurrent Enthalpy = {}\n"
438  "\tCurrent Delta T = {}\n",
439  Htarget, p, Tinit, Tnew, Hnew, dt);
440  }
441  if (unstablePhase) {
442  ErrString += fmt::format(
443  "\t - The phase became unstable (Cp < 0) T_unstable_last = {}\n",
444  Tunstable);
445  }
446  if (doUV) {
447  throw CanteraError("setState_HPorUV (UV)", ErrString);
448  } else {
449  throw CanteraError("setState_HPorUV (HP)", ErrString);
450  }
451 }
452 
453 void ThermoPhase::setState_SP(double Starget, double p, double rtol)
454 {
455  setState_SPorSV(Starget, p, rtol, false);
456 }
457 
458 void ThermoPhase::setState_SV(double Starget, double v, double rtol)
459 {
460  setState_SPorSV(Starget, v, rtol, true);
461 }
462 
463 void ThermoPhase::setState_SPorSV(double Starget, double p,
464  double rtol, bool doSV)
465 {
466  doublereal v = 0.0;
467  doublereal dt;
468  if (doSV) {
469  v = p;
470  if (v < 1.0E-300) {
471  throw CanteraError("setState_SPorSV (SV)",
472  "Input specific volume is too small or negative. v = {}", v);
473  }
474  setDensity(1.0/v);
475  } else {
476  if (p < 1.0E-300) {
477  throw CanteraError("setState_SPorSV (SP)",
478  "Input pressure is too small or negative. p = {}", p);
479  }
480  setPressure(p);
481  }
482  double Tmax = maxTemp() + 0.1;
483  double Tmin = minTemp() - 0.1;
484 
485  // Make sure we are within the temperature bounds at the start
486  // of the iteration
487  double Tnew = temperature();
488  double Tinit = Tnew;
489  if (Tnew > Tmax) {
490  Tnew = Tmax - 1.0;
491  } else if (Tnew < Tmin) {
492  Tnew = Tmin + 1.0;
493  }
494  if (Tnew != Tinit) {
495  setState_conditional_TP(Tnew, p, !doSV);
496  }
497 
498  double Snew = entropy_mass();
499  double Cpnew = (doSV) ? cv_mass() : cp_mass();
500  double Stop = Snew;
501  double Ttop = Tnew;
502  double Sbot = Snew;
503  double Tbot = Tnew;
504 
505  bool ignoreBounds = false;
506  // Unstable phases are those for which Cp < 0.0. These are possible for
507  // cases where we have passed the spinodal curve.
508  bool unstablePhase = false;
509  double Tunstable = -1.0;
510  bool unstablePhaseNew = false;
511 
512  // Newton iteration
513  for (int n = 0; n < 500; n++) {
514  double Told = Tnew;
515  double Sold = Snew;
516  double cpd = Cpnew;
517  if (cpd < 0.0) {
518  unstablePhase = true;
519  Tunstable = Tnew;
520  }
521  // limit step size to 100 K
522  dt = clip((Starget - Sold)*Told/cpd, -100.0, 100.0);
523  Tnew = Told + dt;
524 
525  // Limit the step size so that we are convergent
526  if ((dt > 0.0 && unstablePhase) || (dt <= 0.0 && !unstablePhase)) {
527  if (Sbot < Starget && Tnew < Tbot) {
528  dt = 0.75 * (Tbot - Told);
529  Tnew = Told + dt;
530  }
531  } else if (Stop > Starget && Tnew > Ttop) {
532  dt = 0.75 * (Ttop - Told);
533  Tnew = Told + dt;
534  }
535 
536  // Check Max and Min values
537  if (Tnew > Tmax && !ignoreBounds) {
538  setState_conditional_TP(Tmax, p, !doSV);
539  double Smax = entropy_mass();
540  if (Smax >= Starget) {
541  if (Stop < Starget) {
542  Ttop = Tmax;
543  Stop = Smax;
544  }
545  } else {
546  Tnew = Tmax + 1.0;
547  ignoreBounds = true;
548  }
549  } else if (Tnew < Tmin && !ignoreBounds) {
550  setState_conditional_TP(Tmin, p, !doSV);
551  double Smin = entropy_mass();
552  if (Smin <= Starget) {
553  if (Sbot > Starget) {
554  Tbot = Tmin;
555  Sbot = Smin;
556  }
557  } else {
558  Tnew = Tmin - 1.0;
559  ignoreBounds = true;
560  }
561  }
562 
563  // Try to keep phase within its region of stability
564  // -> Could do a lot better if I calculate the
565  // spinodal value of H.
566  for (int its = 0; its < 10; its++) {
567  Tnew = Told + dt;
568  setState_conditional_TP(Tnew, p, !doSV);
569  Cpnew = (doSV) ? cv_mass() : cp_mass();
570  Snew = entropy_mass();
571  if (Cpnew < 0.0) {
572  unstablePhaseNew = true;
573  Tunstable = Tnew;
574  } else {
575  unstablePhaseNew = false;
576  break;
577  }
578  if (unstablePhase == false && unstablePhaseNew == true) {
579  dt *= 0.25;
580  }
581  }
582 
583  if (Snew == Starget) {
584  return;
585  } else if (Snew > Starget && (Stop < Starget || Snew < Stop)) {
586  Stop = Snew;
587  Ttop = Tnew;
588  } else if (Snew < Starget && (Sbot > Starget || Snew > Sbot)) {
589  Sbot = Snew;
590  Tbot = Tnew;
591  }
592  // Convergence in S
593  double Serr = Starget - Snew;
594  double acpd = std::max(fabs(cpd), 1.0E-5);
595  double denom = std::max(fabs(Starget), acpd * Tnew);
596  double SConvErr = fabs((Serr * Tnew)/denom);
597  if (SConvErr < rtol || fabs(dt/Tnew) < rtol) {
598  return;
599  }
600  }
601  // We are here when there hasn't been convergence
602 
603  // Formulate a detailed error message, since questions seem to arise often
604  // about the lack of convergence.
605  string ErrString = "No convergence in 500 iterations\n";
606  if (doSV) {
607  ErrString += fmt::format(
608  "\tTarget Entropy = {}\n"
609  "\tCurrent Specific Volume = {}\n"
610  "\tStarting Temperature = {}\n"
611  "\tCurrent Temperature = {}\n"
612  "\tCurrent Entropy = {}\n"
613  "\tCurrent Delta T = {}\n",
614  Starget, v, Tinit, Tnew, Snew, dt);
615  } else {
616  ErrString += fmt::format(
617  "\tTarget Entropy = {}\n"
618  "\tCurrent Pressure = {}\n"
619  "\tStarting Temperature = {}\n"
620  "\tCurrent Temperature = {}\n"
621  "\tCurrent Entropy = {}\n"
622  "\tCurrent Delta T = {}\n",
623  Starget, p, Tinit, Tnew, Snew, dt);
624  }
625  if (unstablePhase) {
626  ErrString += fmt::format("\t - The phase became unstable (Cp < 0) T_unstable_last = {}\n",
627  Tunstable);
628  }
629  if (doSV) {
630  throw CanteraError("setState_SPorSV (SV)", ErrString);
631  } else {
632  throw CanteraError("setState_SPorSV (SP)", ErrString);
633  }
634 }
635 
637 {
638  warn_deprecated("ThermoPhase::setSpeciesThermo",
639  "Unused. To be removed after Cantera 2.3.");
640  if (m_spthermo && m_spthermo != spthermo) {
641  delete m_spthermo;
642  }
643  m_spthermo = spthermo;
644 }
645 
647 {
648  if (!m_spthermo) {
649  throw CanteraError("ThermoPhase::speciesThermo()",
650  "species reference state thermo manager was not set");
651  }
652  return *m_spthermo;
653 }
654 
655 void ThermoPhase::initThermoFile(const std::string& inputFile,
656  const std::string& id)
657 {
658  XML_Node* fxml = get_XML_File(inputFile);
659  XML_Node* fxml_phase = findXMLPhase(fxml, id);
660  if (!fxml_phase) {
661  throw CanteraError("ThermoPhase::initThermoFile",
662  "ERROR: Can not find phase named {} in file"
663  " named {}", id, inputFile);
664  }
665  importPhase(*fxml_phase, this);
666 }
667 
668 void ThermoPhase::initThermoXML(XML_Node& phaseNode, const std::string& id)
669 {
670  if (phaseNode.hasChild("state")) {
671  setStateFromXML(phaseNode.child("state"));
672  }
673  xMol_Ref.resize(m_kk);
675 }
676 
677 void ThermoPhase::setReferenceComposition(const doublereal* const x)
678 {
679  warn_deprecated("ThermoPhase::setReferenceComposition",
680  "To be removed after Cantera 2.3.");
681  xMol_Ref.resize(m_kk);
682  if (x) {
683  copy(x, x + m_kk, xMol_Ref.begin());
684  } else {
686  }
687  double sum = accumulate(xMol_Ref.begin(), xMol_Ref.end(), -1.0);
688  if (fabs(sum) > 1.0E-11) {
689  throw CanteraError("ThermoPhase::setReferenceComposition",
690  "input mole fractions don't sum to 1.0");
691  }
692 }
693 
694 void ThermoPhase::getReferenceComposition(doublereal* const x) const
695 {
696  warn_deprecated("ThermoPhase::getReferenceComposition",
697  "To be removed after Cantera 2.3.");
698  copy(xMol_Ref.begin(), xMol_Ref.end(), x);
699 }
700 
702 {
703  // Check to see that all of the species thermo objects have been initialized
704  if (!m_spthermo->ready(m_kk)) {
705  throw CanteraError("ThermoPhase::initThermo()",
706  "Missing species thermo data");
707  }
708 }
710 {
711  warn_deprecated("ThermoPhase::installSlavePhases",
712  "Unused. To be removed after Cantera 2.3.");
713 }
714 
715 bool ThermoPhase::addSpecies(shared_ptr<Species> spec)
716 {
717  if (!spec->thermo) {
718  throw CanteraError("ThermoPhase::addSpecies",
719  "Species {} has no thermo data", spec->name);
720  }
721  bool added = Phase::addSpecies(spec);
722  if (added) {
723  spec->thermo->validate(spec->name);
724  m_spthermo->install_STIT(m_kk-1, spec->thermo);
725  xMol_Ref.push_back(0.0);
726  }
727  return added;
728 }
729 
730 void ThermoPhase::modifySpecies(size_t k, shared_ptr<Species> spec)
731 {
732  if (!spec->thermo) {
733  throw CanteraError("ThermoPhase::modifySpecies",
734  "Species {} has no thermo data", spec->name);
735  }
736  Phase::modifySpecies(k, spec);
737  if (speciesName(k) != spec->name) {
738  throw CanteraError("ThermoPhase::modifySpecies",
739  "New species '{}' does not match existing species '{}' at index {}",
740  spec->name, speciesName(k), k);
741  }
742  spec->thermo->validate(spec->name);
743  m_spthermo->modifySpecies(k, spec->thermo);
744 }
745 
746 void ThermoPhase::saveSpeciesData(const size_t k, const XML_Node* const data)
747 {
748  if (m_speciesData.size() < (k + 1)) {
749  m_speciesData.resize(k+1, 0);
750  }
751  m_speciesData[k] = new XML_Node(*data);
752 }
753 
754 const std::vector<const XML_Node*> & ThermoPhase::speciesData() const
755 {
756  if (m_speciesData.size() != m_kk) {
757  throw CanteraError("ThermoPhase::speciesData",
758  "m_speciesData is the wrong size");
759  }
760  return m_speciesData;
761 }
762 
764 {
765  string comp = getChildValue(state,"moleFractions");
766  if (comp != "") {
768  } else {
769  comp = getChildValue(state,"massFractions");
770  if (comp != "") {
772  }
773  }
774  if (state.hasChild("temperature")) {
775  double t = getFloat(state, "temperature", "temperature");
776  setTemperature(t);
777  }
778  if (state.hasChild("pressure")) {
779  double p = getFloat(state, "pressure", "pressure");
780  setPressure(p);
781  }
782  if (state.hasChild("density")) {
783  double rho = getFloat(state, "density", "density");
784  setDensity(rho);
785  }
786 }
787 
790  m_tlast += 0.1234;
791 }
792 
793 void ThermoPhase::equilibrate(const std::string& XY, const std::string& solver,
794  double rtol, int max_steps, int max_iter,
795  int estimate_equil, int log_level)
796 {
797  if (solver == "auto" || solver == "element_potential") {
798  vector_fp initial_state;
799  saveState(initial_state);
800  debuglog("Trying ChemEquil solver\n", log_level);
801  try {
802  ChemEquil E;
803  E.options.maxIterations = max_steps;
804  E.options.relTolerance = rtol;
805  bool use_element_potentials = (estimate_equil == 0);
806  int ret = E.equilibrate(*this, XY.c_str(), use_element_potentials, log_level-1);
807  if (ret < 0) {
808  throw CanteraError("ThermoPhase::equilibrate",
809  "ChemEquil solver failed. Return code: {}", ret);
810  }
811  setElementPotentials(E.elementPotentials());
812  debuglog("ChemEquil solver succeeded\n", log_level);
813  return;
814  } catch (std::exception& err) {
815  debuglog("ChemEquil solver failed.\n", log_level);
816  debuglog(err.what(), log_level);
817  restoreState(initial_state);
818  if (solver == "auto") {
819  } else {
820  throw;
821  }
822  }
823  }
824 
825  if (solver == "auto" || solver == "vcs" || solver == "gibbs") {
826  MultiPhase M;
827  M.addPhase(this, 1.0);
828  M.init();
829  M.equilibrate(XY, solver, rtol, max_steps, max_iter,
830  estimate_equil, log_level);
831  return;
832  }
833 
834  if (solver != "auto") {
835  throw CanteraError("ThermoPhase::equilibrate",
836  "Invalid solver specified: '{}'", solver);
837  }
838 }
839 
841 {
842  size_t mm = nElements();
843  if (lambda.size() < mm) {
844  throw CanteraError("setElementPotentials", "lambda too small");
845  }
846  if (!m_hasElementPotentials) {
847  m_lambdaRRT.resize(mm);
848  }
849  scale(lambda.begin(), lambda.end(), m_lambdaRRT.begin(), 1.0/RT());
850  m_hasElementPotentials = true;
851 }
852 
853 bool ThermoPhase::getElementPotentials(doublereal* lambda) const
854 {
856  scale(m_lambdaRRT.begin(), m_lambdaRRT.end(), lambda, RT());
857  }
858  return m_hasElementPotentials;
859 }
860 
861 void ThermoPhase::getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN)
862 {
863  for (size_t m = 0; m < m_kk; m++) {
864  for (size_t k = 0; k < m_kk; k++) {
865  dlnActCoeffdlnN[ld * k + m] = 0.0;
866  }
867  }
868  return;
869 }
870 
871 void ThermoPhase::getdlnActCoeffdlnN_numderiv(const size_t ld, doublereal* const dlnActCoeffdlnN)
872 {
873  double deltaMoles_j = 0.0;
874  double pres = pressure();
875 
876  // Evaluate the current base activity coefficients if necessary
877  vector_fp ActCoeff_Base(m_kk);
878  getActivityCoefficients(ActCoeff_Base.data());
879  vector_fp Xmol_Base(m_kk);
880  getMoleFractions(Xmol_Base.data());
881 
882  // Make copies of ActCoeff and Xmol_ for use in taking differences
883  vector_fp ActCoeff(m_kk);
884  vector_fp Xmol(m_kk);
885  double v_totalMoles = 1.0;
886  double TMoles_base = v_totalMoles;
887 
888  // Loop over the columns species to be deltad
889  for (size_t j = 0; j < m_kk; j++) {
890  // Calculate a value for the delta moles of species j
891  // -> Note Xmol_[] and Tmoles are always positive or zero quantities.
892  // -> experience has shown that you always need to make the deltas
893  // greater than needed to change the other mole fractions in order
894  // to capture some effects.
895  double moles_j_base = v_totalMoles * Xmol_Base[j];
896  deltaMoles_j = 1.0E-7 * moles_j_base + v_totalMoles * 1.0E-13 + 1.0E-150;
897 
898  // Now, update the total moles in the phase and all of the mole
899  // fractions based on this.
900  v_totalMoles = TMoles_base + deltaMoles_j;
901  for (size_t k = 0; k < m_kk; k++) {
902  Xmol[k] = Xmol_Base[k] * TMoles_base / v_totalMoles;
903  }
904  Xmol[j] = (moles_j_base + deltaMoles_j) / v_totalMoles;
905 
906  // Go get new values for the activity coefficients.
907  // -> Note this calls setState_PX();
908  setState_PX(pres, Xmol.data());
909  getActivityCoefficients(ActCoeff.data());
910 
911  // Calculate the column of the matrix
912  double* const lnActCoeffCol = dlnActCoeffdlnN + ld * j;
913  for (size_t k = 0; k < m_kk; k++) {
914  lnActCoeffCol[k] = (2*moles_j_base + deltaMoles_j) *(ActCoeff[k] - ActCoeff_Base[k]) /
915  ((ActCoeff[k] + ActCoeff_Base[k]) * deltaMoles_j);
916  }
917  // Revert to the base case Xmol_, v_totalMoles
918  v_totalMoles = TMoles_base;
919  Xmol = Xmol_Base;
920  }
921 
922  setState_PX(pres, Xmol_Base.data());
923 }
924 
925 std::string ThermoPhase::report(bool show_thermo, doublereal threshold) const
926 {
927  fmt::MemoryWriter b;
928  try {
929  if (name() != "") {
930  b.write("\n {}:\n", name());
931  }
932  b.write("\n");
933  b.write(" temperature {:12.6g} K\n", temperature());
934  b.write(" pressure {:12.6g} Pa\n", pressure());
935  b.write(" density {:12.6g} kg/m^3\n", density());
936  b.write(" mean mol. weight {:12.6g} amu\n", meanMolecularWeight());
937 
938  doublereal phi = electricPotential();
939  if (phi != 0.0) {
940  b.write(" potential {:12.6g} V\n", phi);
941  }
942  if (show_thermo) {
943  b.write("\n");
944  b.write(" 1 kg 1 kmol\n");
945  b.write(" ----------- ------------\n");
946  b.write(" enthalpy {:12.5g} {:12.4g} J\n",
948  b.write(" internal energy {:12.5g} {:12.4g} J\n",
950  b.write(" entropy {:12.5g} {:12.4g} J/K\n",
952  b.write(" Gibbs function {:12.5g} {:12.4g} J\n",
953  gibbs_mass(), gibbs_mole());
954  b.write(" heat capacity c_p {:12.5g} {:12.4g} J/K\n",
955  cp_mass(), cp_mole());
956  try {
957  b.write(" heat capacity c_v {:12.5g} {:12.4g} J/K\n",
958  cv_mass(), cv_mole());
959  } catch (NotImplementedError&) {
960  b.write(" heat capacity c_v <not implemented> \n");
961  }
962  }
963 
964  vector_fp x(m_kk);
965  vector_fp y(m_kk);
966  vector_fp mu(m_kk);
967  getMoleFractions(&x[0]);
968  getMassFractions(&y[0]);
969  getChemPotentials(&mu[0]);
970  int nMinor = 0;
971  doublereal xMinor = 0.0;
972  doublereal yMinor = 0.0;
973  b.write("\n");
974  if (show_thermo) {
975  b.write(" X "
976  " Y Chem. Pot. / RT\n");
977  b.write(" ------------- "
978  "------------ ------------\n");
979  for (size_t k = 0; k < m_kk; k++) {
980  if (abs(x[k]) >= threshold) {
981  if (abs(x[k]) > SmallNumber) {
982  b.write("{:>18s} {:12.6g} {:12.6g} {:12.6g}\n",
983  speciesName(k), x[k], y[k], mu[k]/RT());
984  } else {
985  b.write("{:>18s} {:12.6g} {:12.6g}\n",
986  speciesName(k), x[k], y[k]);
987  }
988  } else {
989  nMinor++;
990  xMinor += x[k];
991  yMinor += y[k];
992  }
993  }
994  } else {
995  b.write(" X Y\n");
996  b.write(" ------------- ------------\n");
997  for (size_t k = 0; k < m_kk; k++) {
998  if (abs(x[k]) >= threshold) {
999  b.write("{:>18s} {:12.6g} {:12.6g}\n",
1000  speciesName(k), x[k], y[k]);
1001  } else {
1002  nMinor++;
1003  xMinor += x[k];
1004  yMinor += y[k];
1005  }
1006  }
1007  }
1008  if (nMinor) {
1009  b.write(" [{:+5d} minor] {:12.6g} {:12.6g}\n",
1010  nMinor, xMinor, yMinor);
1011  }
1012  } catch (CanteraError& err) {
1013  return b.str() + err.what();
1014  }
1015  return b.str();
1016 }
1017 
1018 void ThermoPhase::reportCSV(std::ofstream& csvFile) const
1019 {
1020  int tabS = 15;
1021  int tabM = 30;
1022  csvFile.precision(8);
1023  vector_fp X(nSpecies());
1024  getMoleFractions(&X[0]);
1025  std::vector<std::string> pNames;
1026  std::vector<vector_fp> data;
1027  getCsvReportData(pNames, data);
1028 
1029  csvFile << setw(tabS) << "Species,";
1030  for (size_t i = 0; i < pNames.size(); i++) {
1031  csvFile << setw(tabM) << pNames[i] << ",";
1032  }
1033  csvFile << endl;
1034  for (size_t k = 0; k < nSpecies(); k++) {
1035  csvFile << setw(tabS) << speciesName(k) + ",";
1036  if (X[k] > SmallNumber) {
1037  for (size_t i = 0; i < pNames.size(); i++) {
1038  csvFile << setw(tabM) << data[i][k] << ",";
1039  }
1040  csvFile << endl;
1041  } else {
1042  for (size_t i = 0; i < pNames.size(); i++) {
1043  csvFile << setw(tabM) << 0 << ",";
1044  }
1045  csvFile << endl;
1046  }
1047  }
1048 }
1049 
1050 void ThermoPhase::getCsvReportData(std::vector<std::string>& names,
1051  std::vector<vector_fp>& data) const
1052 {
1053  names.clear();
1054  data.assign(10, vector_fp(nSpecies()));
1055 
1056  names.push_back("X");
1057  getMoleFractions(&data[0][0]);
1058 
1059  names.push_back("Y");
1060  getMassFractions(&data[1][0]);
1061 
1062  names.push_back("Chem. Pot (J/kmol)");
1063  getChemPotentials(&data[2][0]);
1064 
1065  names.push_back("Activity");
1066  getActivities(&data[3][0]);
1067 
1068  names.push_back("Act. Coeff.");
1069  getActivityCoefficients(&data[4][0]);
1070 
1071  names.push_back("Part. Mol Enthalpy (J/kmol)");
1072  getPartialMolarEnthalpies(&data[5][0]);
1073 
1074  names.push_back("Part. Mol. Entropy (J/K/kmol)");
1075  getPartialMolarEntropies(&data[6][0]);
1076 
1077  names.push_back("Part. Mol. Energy (J/kmol)");
1078  getPartialMolarIntEnergies(&data[7][0]);
1079 
1080  names.push_back("Part. Mol. Cp (J/K/kmol");
1081  getPartialMolarCp(&data[8][0]);
1082 
1083  names.push_back("Part. Mol. Cv (J/K/kmol)");
1084  getPartialMolarVolumes(&data[9][0]);
1085 }
1086 
1087 }
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:149
Class ChemEquil implements a chemical equilibrium solver for single-phase solutions.
Definition: ChemEquil.h:82
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
ThermoPhase()
Constructor.
Definition: ThermoPhase.cpp:27
EquilOpt options
Options controlling how the calculation is carried out.
Definition: ChemEquil.h:138
virtual void setState_SV(double s, double v, double tol=1e-9)
Set the specific entropy (J/kg/K) and specific volume (m^3/kg).
size_t nElements() const
Number of elements.
Definition: Phase.cpp:161
virtual bool addSpecies(shared_ptr< Species > spec)
void restoreState(const vector_fp &state)
Restore a state saved on a previous call to saveState.
Definition: Phase.cpp:309
virtual void setState_RPX(doublereal rho, doublereal p, const doublereal *x)
Set the density (kg/m**3), pressure (Pa) and mole fractions.
XML_Node * get_XML_File(const std::string &file, int debug)
Return a pointer to the XML tree for a Cantera input file.
Definition: global.cpp:96
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual void modifySpecies(size_t k, shared_ptr< Species > spec)
Modify the thermodynamic data associated with a species.
XML_Node * findXMLPhase(XML_Node *root, const std::string &idtarget)
Search an XML_Node tree for a named phase XML_Node.
Definition: xml.cpp:1038
void getMassFractions(doublereal *const y) const
Get the species mass fractions.
Definition: Phase.cpp:584
std::string getChildValue(const XML_Node &parent, const std::string &nameString)
This function reads a child node with the name, nameString, and returns its XML value as the return s...
Definition: ctml.cpp:145
doublereal relTolerance
Relative tolerance.
Definition: ChemEquil.h:34
vector_fp xMol_Ref
Reference Mole Fraction Composition.
Definition: ThermoPhase.h:1734
bool ready(size_t nSpecies)
Check if data for all species (0 through nSpecies-1) has been installed.
doublereal temperature() const
Temperature (K).
Definition: Phase.h:601
const std::vector< const XML_Node * > & speciesData() const
Return a pointer to the vector of XML nodes containing the species data for this phase.
std::vector< const XML_Node * > m_speciesData
Vector of pointers to the species databases.
Definition: ThermoPhase.h:1701
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
Definition: ThermoPhase.h:263
An error indicating that an unimplemented function has been called.
Definition: ctexceptions.h:193
virtual void resetHf298(const size_t k)
Restore the original heat of formation of one or more species.
virtual void setState_TPX(doublereal t, doublereal p, const doublereal *x)
Set the temperature (K), pressure (Pa), and mole fractions.
virtual void modifySpecies(size_t index, shared_ptr< SpeciesThermoInterpType > spec)
Modify the species thermodynamic property parameterization for a species.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: ThermoPhase.h:530
doublereal cp_mass() const
Specific heat at constant pressure. Units: J/kg/K.
Definition: ThermoPhase.h:784
void saveState(vector_fp &state) const
Save the current internal state of the phase.
Definition: Phase.cpp:297
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
ThermoPhase & operator=(const ThermoPhase &right)
Definition: ThermoPhase.cpp:59
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: ThermoPhase.h:494
const int cAC_CONVENTION_MOLAR
Standard state uses the molar convention.
Definition: ThermoPhase.h:26
bool getElementPotentials(doublereal *lambda) const
Returns the element potentials stored in the ThermoPhase object.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
void addPhase(ThermoPhase *p, doublereal moles)
Add a phase to the mixture.
Definition: MultiPhase.cpp:49
const char * what() const
Get a description of the error.
const int cSS_CONVENTION_TEMPERATURE
Standard state uses the molar convention.
Definition: ThermoPhase.h:36
int equilibrate(thermo_t &s, const char *XY, bool useThermoPhaseElementPotentials=false, int loglevel=0)
Definition: ChemEquil.cpp:309
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
void setState_conditional_TP(doublereal t, doublereal p, bool set_p)
Helper function used by setState_HPorUV and setState_SPorSV.
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
Definition: ThermoPhase.h:403
T clip(const T &value, const T &lower, const T &upper)
Clip value such that lower <= value <= upper.
Definition: global.h:295
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:262
STL namespace.
virtual doublereal density() const
Density (kg/m^3).
Definition: Phase.h:607
vector_fp m_lambdaRRT
Vector of element potentials. Length equal to number of elements.
Definition: ThermoPhase.h:1707
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid...
Definition: ThermoPhase.h:164
doublereal enthalpy_mass() const
Specific enthalpy. Units: J/kg.
Definition: ThermoPhase.h:764
void setState_HPorUV(doublereal h, doublereal p, doublereal tol=1e-9, bool doUV=false)
Carry out work in HP and UV calculations.
virtual void setState_HP(double h, double p, double tol=1e-9)
Set the internally stored specific enthalpy (J/kg) and pressure (Pa) of the phase.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: ThermoPhase.h:238
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: ThermoPhase.h:561
void equilibrate(const std::string &XY, const std::string &solver="auto", double rtol=1e-9, int max_steps=50000, int max_iter=100, int estimate_equil=0, int log_level=0)
Equilibrate a ThermoPhase object.
void saveSpeciesData(const size_t k, const XML_Node *const data)
Store a reference pointer to the XML tree containing the species data for this phase.
virtual MultiSpeciesThermo & speciesThermo(int k=-1)
Return a changeable reference to the calculation manager for species reference-state thermodynamic pr...
doublereal m_tlast
last value of the temperature processed by reference state
Definition: ThermoPhase.h:1737
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Definition: ThermoPhase.h:424
Headers for the MultiPhase object that is used to set up multiphase equilibrium problems (see Equilfu...
virtual void setState_PY(doublereal p, doublereal *y)
Set the internally stored pressure (Pa) and mass fractions.
void setState_SPorSV(double s, double p, double tol=1e-9, bool doSV=false)
Carry out work in SP and SV calculations.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:809
virtual void getActivities(doublereal *a) const
Get the array of non-dimensional activities at the current solution temperature, pressure, and solution concentration.
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:93
Pure Virtual Base class for individual species reference state thermodynamic managers and text for th...
virtual void invalidateCache()
Invalidate any cached values which are normally updated only when a change in state is detected...
virtual void setReferenceComposition(const doublereal *const x)
Sets the reference composition.
bool m_chargeNeutralityNecessary
Boolean indicating whether a charge neutrality condition is a necessity.
Definition: ThermoPhase.h:1721
virtual void setStateFromXML(const XML_Node &state)
Set the initial state of the phase to the conditions specified in the state XML element.
virtual doublereal intEnergy_mole() const
Molar internal energy. Units: J/kmol.
Definition: ThermoPhase.h:243
A class for multiphase mixtures.
Definition: MultiPhase.h:57
void getElectrochemPotentials(doublereal *mu) const
Get the species electrochemical potentials.
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
Definition: ThermoPhase.h:253
virtual void getCsvReportData(std::vector< std::string > &names, std::vector< vector_fp > &data) const
Fills names and data with the column names and species thermo properties to be included in the output...
void setSpeciesThermo(MultiSpeciesThermo *spthermo)
Install a species thermodynamic property manager.
doublereal m_phi
Stored value of the electric potential for this phase. Units are Volts.
Definition: ThermoPhase.h:1704
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:267
virtual void setState_TPY(doublereal t, doublereal p, const doublereal *y)
Set the internally stored temperature (K), pressure (Pa), and mass fractions of the phase...
doublereal electricPotential() const
Returns the electric potential of this phase (V).
Definition: ThermoPhase.h:335
void setMoleFractionsByName(const compositionMap &xMap)
Set the species mole fractions by name.
Definition: Phase.cpp:368
int m_ssConvention
Contains the standard state convention.
Definition: ThermoPhase.h:1724
doublereal entropy_mass() const
Specific entropy. Units: J/kg/K.
Definition: ThermoPhase.h:774
virtual int activityConvention() const
This method returns the convention used in specification of the activities, of which there are curren...
void setMassFractionsByName(const compositionMap &yMap)
Set the species mass fractions by name.
Definition: Phase.cpp:412
virtual void modifySpecies(size_t k, shared_ptr< Species > spec)
Modify the thermodynamic data associated with a species.
Definition: Phase.cpp:851
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:65
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: ThermoPhase.h:520
virtual int standardStateConvention() const
This method returns the convention used in specification of the standard state, of which there are cu...
virtual void invalidateCache()
Invalidate any cached values which are normally updated only when a change in state is detected...
Definition: Phase.cpp:895
virtual void getPartialMolarIntEnergies(doublereal *ubar) const
Return an array of partial molar internal energies for the species in the mixture.
Definition: ThermoPhase.h:540
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Definition: ThermoPhase.h:258
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values.
Definition: Phase.cpp:327
virtual doublereal logStandardConc(size_t k=0) const
Natural logarithm of the standard concentration of the kth species.
virtual void setState_UV(double u, double v, double tol=1e-9)
Set the specific internal energy (J/kg) and specific volume (m^3/kg).
virtual void resetHf298(const size_t k=npos)
Restore the original heat of formation of one or more species.
virtual void setState_RP(doublereal rho, doublereal p)
Set the density (kg/m**3) and pressure (Pa) at constant composition.
Definition: ThermoPhase.h:1120
virtual bool addSpecies(shared_ptr< Species > spec)
Add a Species to this Phase.
Definition: Phase.cpp:761
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:542
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
virtual void setState_TP(doublereal t, doublereal p)
Set the temperature (K) and pressure (Pa)
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Definition: ThermoPhase.h:453
virtual doublereal pressure() const
Return the thermodynamic pressure (Pa).
Definition: ThermoPhase.h:278
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
Definition: ThermoPhase.cpp:96
virtual void setState_SP(double s, double p, double tol=1e-9)
Set the specific entropy (J/kg/K) and pressure (Pa).
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:536
void debuglog(const std::string &msg, int loglevel)
Write a message to the log only if loglevel > 0.
Definition: global.h:161
MultiSpeciesThermo * m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
Definition: ThermoPhase.h:1693
XML_Node & child(const size_t n) const
Return a changeable reference to the n&#39;th child of the current node.
Definition: xml.cpp:546
doublereal cv_mass() const
Specific heat at constant volume. Units: J/kg/K.
Definition: ThermoPhase.h:789
virtual std::string report(bool show_thermo=true, doublereal threshold=-1e-14) const
returns a summary of the state of the phase as a string
virtual void setPressure(doublereal p)
Set the internally stored pressure (Pa) at constant temperature and composition.
Definition: ThermoPhase.h:831
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
const doublereal SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:126
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:157
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:661
virtual void setTemperature(const doublereal temp)
Set the internally stored temperature of the phase (K).
Definition: Phase.h:637
void scale(InputIter begin, InputIter end, OutputIter out, S scale_factor)
Multiply elements of an array by a scale factor.
Definition: utilities.h:130
doublereal gibbs_mass() const
Specific Gibbs function. Units: J/kg.
Definition: ThermoPhase.h:779
void init()
Process phases and build atomic composition array.
Definition: MultiPhase.cpp:116
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:151
virtual void setState_PX(doublereal p, doublereal *x)
Set the pressure (Pa) and mole fractions.
Contains declarations for string manipulation functions within Cantera.
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:178
virtual void getReferenceComposition(doublereal *const x) const
Gets the reference composition.
virtual void setMassFractions(const doublereal *const y)
Set the mass fractions to the specified values and normalize them.
Definition: Phase.cpp:387
void setElementPotentials(const vector_fp &lambda)
Stores the element potentials in the ThermoPhase object.
int maxIterations
Maximum number of iterations.
Definition: ChemEquil.h:36
size_t m_kk
Number of species in the phase.
Definition: Phase.h:784
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the log activity coefficients with respect to the log of the species ...
A species thermodynamic property manager for a phase.
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void reportCSV(std::ofstream &csvFile) const
returns a summary of the state of the phase to a comma separated file.
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
Definition: ThermoPhase.h:551
virtual void install_STIT(size_t index, shared_ptr< SpeciesThermoInterpType > stit)
Install a new species thermodynamic property parameterization for one species.
Namespace for the Cantera kernel.
Definition: application.cpp:29
doublereal intEnergy_mass() const
Specific internal energy. Units: J/kg.
Definition: ThermoPhase.h:769
bool m_hasElementPotentials
Boolean indicating whether there is a valid set of saved element potentials for this phase...
Definition: ThermoPhase.h:1711
virtual void setState_RPY(doublereal rho, doublereal p, const doublereal *y)
Set the density (kg/m**3), pressure (Pa) and mass fractions.
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
Definition: ThermoPhase.h:217
Header file for class ThermoPhase, the base class for phases with thermodynamic properties, and the text for the Module thermoprops (see Thermodynamic Properties and class ThermoPhase).
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: ThermoPhase.h:248
Chemical equilibrium.
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:577
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase.
Definition: Phase.h:622
virtual void installSlavePhases(XML_Node *phaseNode)
Add in species from Slave phases.