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