Cantera  2.5.1
RedlichKisterVPSSTP.cpp
Go to the documentation of this file.
1 /**
2  * @file RedlichKisterVPSSTP.cpp
3  * Definitions for ThermoPhase object for phases which
4  * employ excess Gibbs free energy formulations related to RedlichKister
5  * expansions (see \ref thermoprops
6  * and class \link Cantera::RedlichKisterVPSSTP RedlichKisterVPSSTP\endlink).
7  */
8 
9 // This file is part of Cantera. See License.txt in the top-level directory or
10 // at https://cantera.org/license.txt for license and copyright information.
11 
15 #include "cantera/base/ctml.h"
16 
17 using namespace std;
18 
19 namespace Cantera
20 {
21 RedlichKisterVPSSTP::RedlichKisterVPSSTP() :
22  numBinaryInteractions_(0),
23  formRedlichKister_(0),
24  formTempModel_(0)
25 {
26 }
27 
28 RedlichKisterVPSSTP::RedlichKisterVPSSTP(const std::string& inputFile,
29  const std::string& id_) :
30  numBinaryInteractions_(0),
31  formRedlichKister_(0),
32  formTempModel_(0)
33 {
34  initThermoFile(inputFile, id_);
35 }
36 
38  const std::string& id_) :
39  numBinaryInteractions_(0),
40  formRedlichKister_(0),
41  formTempModel_(0)
42 {
43  importPhase(phaseRoot, this);
44 }
45 
46 // - Activities, Standard States, Activity Concentrations -----------
47 
49 {
50  // Update the activity coefficients
52 
53  for (size_t k = 0; k < m_kk; k++) {
54  lnac[k] = lnActCoeff_Scaled_[k];
55  }
56 }
57 
58 // ------------ Partial Molar Properties of the Solution ------------
59 
60 void RedlichKisterVPSSTP::getChemPotentials(doublereal* mu) const
61 {
62  // First get the standard chemical potentials in molar form. This requires
63  // updates of standard state as a function of T and P
65  // Update the activity coefficients
67 
68  for (size_t k = 0; k < m_kk; k++) {
69  double xx = std::max(moleFractions_[k], SmallNumber);
70  mu[k] += RT() * (log(xx) + lnActCoeff_Scaled_[k]);
71  }
72 }
73 
75 {
76  double h = 0;
77  vector_fp hbar(m_kk);
78  getPartialMolarEnthalpies(&hbar[0]);
79  for (size_t i = 0; i < m_kk; i++) {
80  h += moleFractions_[i]*hbar[i];
81  }
82  return h;
83 }
84 
86 {
87  double s = 0;
88  vector_fp sbar(m_kk);
89  getPartialMolarEntropies(&sbar[0]);
90  for (size_t i = 0; i < m_kk; i++) {
91  s += moleFractions_[i]*sbar[i];
92  }
93  return s;
94 }
95 
96 doublereal RedlichKisterVPSSTP::cp_mole() const
97 {
98  double cp = 0;
99  vector_fp cpbar(m_kk);
100  getPartialMolarCp(&cpbar[0]);
101  for (size_t i = 0; i < m_kk; i++) {
102  cp += moleFractions_[i]*cpbar[i];
103  }
104  return cp;
105 }
106 
108 {
109  return cp_mole() - GasConstant;
110 }
111 
113 {
114  // Get the nondimensional standard state enthalpies
115  getEnthalpy_RT(hbar);
116  // dimensionalize it.
117  double T = temperature();
118  for (size_t k = 0; k < m_kk; k++) {
119  hbar[k] *= GasConstant * T;
120  }
121 
122  // Update the activity coefficients, This also update the internally stored
123  // molalities.
126  for (size_t k = 0; k < m_kk; k++) {
127  hbar[k] -= GasConstant * T * T * dlnActCoeffdT_Scaled_[k];
128  }
129 }
130 
131 void RedlichKisterVPSSTP::getPartialMolarCp(doublereal* cpbar) const
132 {
133  getCp_R(cpbar);
134  double T = temperature();
135 
136  // Update the activity coefficients, This also update the internally stored
137  // molalities.
140 
141  for (size_t k = 0; k < m_kk; k++) {
142  cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
143  }
144  // dimensionalize it.
145  for (size_t k = 0; k < m_kk; k++) {
146  cpbar[k] *= GasConstant;
147  }
148 }
149 
151 {
152  // Get the nondimensional standard state entropies
153  getEntropy_R(sbar);
154  double T = temperature();
155 
156  // Update the activity coefficients, This also update the internally stored
157  // molalities.
160 
161  for (size_t k = 0; k < m_kk; k++) {
162  double xx = std::max(moleFractions_[k], SmallNumber);
163  sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k];
164  }
165  // dimensionalize it.
166  for (size_t k = 0; k < m_kk; k++) {
167  sbar[k] *= GasConstant;
168  }
169 }
170 
172 {
173  // Get the standard state values in m^3 kmol-1
174  getStandardVolumes(vbar);
175  for (size_t iK = 0; iK < m_kk; iK++) {
176  vbar[iK] += 0.0;
177  }
178 }
179 
181 {
182  if (m_input.hasKey("interactions")) {
183  for (const auto& item : m_input["interactions"].asVector<AnyMap>()) {
184  auto& species = item["species"].asVector<string>(2);
185  vector_fp h_excess = item.convertVector("excess-enthalpy", "J/kmol");
186  vector_fp s_excess = item.convertVector("excess-entropy", "J/kmol/K");
188  h_excess.data(), h_excess.size(),
189  s_excess.data(), s_excess.size());
190  }
191  }
192  initLengths();
194 }
195 
197 {
199 }
200 
201 void RedlichKisterVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_)
202 {
203  if ((int) id_.size() > 0 && phaseNode.id() != id_) {
204  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
205  "phasenode and Id are incompatible");
206  }
207 
208  // Check on the thermo field. Must have:
209  // <thermo model="Redlich-Kister" />
210  if (!phaseNode.hasChild("thermo")) {
211  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
212  "no thermo XML node");
213  }
214  XML_Node& thermoNode = phaseNode.child("thermo");
215  if (!caseInsensitiveEquals(thermoNode["model"], "redlich-kister")) {
216  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
217  "Unknown thermo model: " + thermoNode["model"]
218  + " - This object only knows \"Redlich-Kister\" ");
219  }
220 
221  // Go get all of the coefficients and factors in the activityCoefficients
222  // XML block
223  if (thermoNode.hasChild("activityCoefficients")) {
224  XML_Node& acNode = thermoNode.child("activityCoefficients");
225  if (!caseInsensitiveEquals(acNode["model"], "redlich-kister")) {
226  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
227  "Unknown activity coefficient model: " + acNode["model"]);
228  }
229  for (size_t i = 0; i < acNode.nChildren(); i++) {
230  XML_Node& xmlACChild = acNode.child(i);
231 
232  // Process a binary salt field, or any of the other XML fields that
233  // make up the Pitzer Database. Entries will be ignored if any of
234  // the species in the entry isn't in the solution.
235  if (caseInsensitiveEquals(xmlACChild.name(), "binaryneutralspeciesparameters")) {
236  readXMLBinarySpecies(xmlACChild);
237  }
238  }
239  }
240  // Go down the chain
241  GibbsExcessVPSSTP::initThermoXML(phaseNode, id_);
242 }
243 
245 {
246  doublereal T = temperature();
247  lnActCoeff_Scaled_.assign(m_kk, 0.0);
248 
249  // Scaling: I moved the division of RT higher so that we are always dealing
250  // with G/RT dimensionless terms within the routine. There is a severe
251  // problem with roundoff error in these calculations. The dimensionless
252  // terms help.
253  for (size_t i = 0; i < numBinaryInteractions_; i++) {
254  size_t iA = m_pSpecies_A_ij[i];
255  size_t iB = m_pSpecies_B_ij[i];
256  double XA = moleFractions_[iA];
257  double XB = moleFractions_[iB];
258  doublereal deltaX = XA - XB;
259  size_t N = m_N_ij[i];
260  vector_fp& he_vec = m_HE_m_ij[i];
261  vector_fp& se_vec = m_SE_m_ij[i];
262  doublereal poly = 1.0;
263  doublereal polyMm1 = 1.0;
264  doublereal sum = 0.0;
265  doublereal sumMm1 = 0.0;
266  doublereal sum2 = 0.0;
267  for (size_t m = 0; m < N; m++) {
268  doublereal A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);
269  sum += A_ge * poly;
270  sum2 += A_ge * (m + 1) * poly;
271  poly *= deltaX;
272  if (m >= 1) {
273  sumMm1 += (A_ge * polyMm1 * m);
274  polyMm1 *= deltaX;
275  }
276  }
277  doublereal oneMXA = 1.0 - XA;
278  doublereal oneMXB = 1.0 - XB;
279  for (size_t k = 0; k < m_kk; k++) {
280  if (iA == k) {
281  lnActCoeff_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
282  } else if (iB == k) {
283  lnActCoeff_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
284  } else {
285  lnActCoeff_Scaled_[k] += -(XA * XB * sum2);
286  }
287  }
288  // Debug against formula in literature
289  }
290 }
291 
293 {
294  dlnActCoeffdT_Scaled_.assign(m_kk, 0.0);
295  d2lnActCoeffdT2_Scaled_.assign(m_kk, 0.0);
296 
297  for (size_t i = 0; i < numBinaryInteractions_; i++) {
298  size_t iA = m_pSpecies_A_ij[i];
299  size_t iB = m_pSpecies_B_ij[i];
300  double XA = moleFractions_[iA];
301  double XB = moleFractions_[iB];
302  doublereal deltaX = XA - XB;
303  size_t N = m_N_ij[i];
304  doublereal poly = 1.0;
305  doublereal sum = 0.0;
306  vector_fp& se_vec = m_SE_m_ij[i];
307  doublereal sumMm1 = 0.0;
308  doublereal polyMm1 = 1.0;
309  doublereal sum2 = 0.0;
310  for (size_t m = 0; m < N; m++) {
311  doublereal A_ge = - se_vec[m];
312  sum += A_ge * poly;
313  sum2 += A_ge * (m + 1) * poly;
314  poly *= deltaX;
315  if (m >= 1) {
316  sumMm1 += (A_ge * polyMm1 * m);
317  polyMm1 *= deltaX;
318  }
319  }
320  doublereal oneMXA = 1.0 - XA;
321  doublereal oneMXB = 1.0 - XB;
322  for (size_t k = 0; k < m_kk; k++) {
323  if (iA == k) {
324  dlnActCoeffdT_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
325  } else if (iB == k) {
326  dlnActCoeffdT_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
327  } else {
328  dlnActCoeffdT_Scaled_[k] += -(XA * XB * sum2);
329  }
330  }
331  }
332 }
333 
334 void RedlichKisterVPSSTP::getdlnActCoeffdT(doublereal* dlnActCoeffdT) const
335 {
337  for (size_t k = 0; k < m_kk; k++) {
338  dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k];
339  }
340 }
341 
342 void RedlichKisterVPSSTP::getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const
343 {
345  for (size_t k = 0; k < m_kk; k++) {
346  d2lnActCoeffdT2[k] = d2lnActCoeffdT2_Scaled_[k];
347  }
348 }
349 
351 {
352  double T = temperature();
353  dlnActCoeffdlnX_diag_.assign(m_kk, 0.0);
354 
355  for (size_t i = 0; i < numBinaryInteractions_; i++) {
356  size_t iA = m_pSpecies_A_ij[i];
357  size_t iB = m_pSpecies_B_ij[i];
358  double XA = moleFractions_[iA];
359  double XB = moleFractions_[iB];
360  double deltaX = XA - XB;
361  size_t N = m_N_ij[i];
362  double poly = 1.0;
363  double sum = 0.0;
364  vector_fp& he_vec = m_HE_m_ij[i];
365  vector_fp& se_vec = m_SE_m_ij[i];
366  double sumMm1 = 0.0;
367  double polyMm1 = 1.0;
368  double polyMm2 = 1.0;
369  double sumMm2 = 0.0;
370  for (size_t m = 0; m < N; m++) {
371  double A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);;
372  sum += A_ge * poly;
373  poly *= deltaX;
374  if (m >= 1) {
375  sumMm1 += (A_ge * polyMm1 * m);
376  polyMm1 *= deltaX;
377  }
378  if (m >= 2) {
379  sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
380  polyMm2 *= deltaX;
381  }
382  }
383 
384  for (size_t k = 0; k < m_kk; k++) {
385  if (iA == k) {
387  XA * (- (1-XA+XB) * sum + 2*(1.0 - XA) * XB * sumMm1
388  + sumMm1 * (XB * (1 - 2*XA + XB) - XA * (1 - XA + 2*XB))
389  + 2 * XA * XB * sumMm2 * (1.0 - XA + XB));
390  } else if (iB == k) {
392  XB * (- (1-XB+XA) * sum - 2*(1.0 - XB) * XA * sumMm1
393  + sumMm1 * (XA * (2*XB - XA - 1) - XB * (-2*XA + XB - 1))
394  - 2 * XA * XB * sumMm2 * (-XA - 1 + XB));
395  }
396  }
397  }
398 }
399 
401 {
402  doublereal T = temperature();
404 
405  for (size_t i = 0; i < numBinaryInteractions_; i++) {
406  size_t iA = m_pSpecies_A_ij[i];
407  size_t iB = m_pSpecies_B_ij[i];
408  double XA = moleFractions_[iA];
409  double XB = moleFractions_[iB];
410  doublereal deltaX = XA - XB;
411  size_t N = m_N_ij[i];
412  doublereal poly = 1.0;
413  doublereal sum = 0.0;
414  vector_fp& he_vec = m_HE_m_ij[i];
415  vector_fp& se_vec = m_SE_m_ij[i];
416  doublereal sumMm1 = 0.0;
417  doublereal polyMm1 = 1.0;
418  doublereal polyMm2 = 1.0;
419  doublereal sum2 = 0.0;
420  doublereal sum2Mm1 = 0.0;
421  doublereal sumMm2 = 0.0;
422  for (size_t m = 0; m < N; m++) {
423  doublereal A_ge = he_vec[m] - T * se_vec[m];
424  sum += A_ge * poly;
425  sum2 += A_ge * (m + 1) * poly;
426  poly *= deltaX;
427  if (m >= 1) {
428  sumMm1 += (A_ge * polyMm1 * m);
429  sum2Mm1 += (A_ge * polyMm1 * m * (1.0 + m));
430  polyMm1 *= deltaX;
431  }
432  if (m >= 2) {
433  sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
434  polyMm2 *= deltaX;
435  }
436  }
437 
438  for (size_t k = 0; k < m_kk; k++) {
439  if (iA == k) {
440  dlnActCoeff_dX_(k, iA) += (- XB * sum + (1.0 - XA) * XB * sumMm1
441  + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
442  + XA * XB * sumMm2 * (1.0 - XA + XB));
443 
444  dlnActCoeff_dX_(k, iB) += ((1.0 - XA) * sum - (1.0 - XA) * XB * sumMm1
445  + XA * sumMm1 * (1.0 + 2.0 * XB - XA)
446  - XA * XB * sumMm2 * (1.0 - XA + XB));
447  } else if (iB == k) {
448  dlnActCoeff_dX_(k, iA) += ((1.0 - XB) * sum + (1.0 - XA) * XB * sumMm1
449  + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
450  + XA * XB * sumMm2 * (1.0 - XA + XB));
451 
452  dlnActCoeff_dX_(k, iB) += (- XA * sum - (1.0 - XB) * XA * sumMm1
453  + XA * sumMm1 * (XB - XA - (1.0 - XB))
454  - XA * XB * sumMm2 * (-XA - (1.0 - XB)));
455  } else {
456  dlnActCoeff_dX_(k, iA) += (- XB * sum2 - XA * XB * sum2Mm1);
457  dlnActCoeff_dX_(k, iB) += (- XA * sum2 + XA * XB * sum2Mm1);
458  }
459  }
460  }
461 }
462 
463 void RedlichKisterVPSSTP::getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
464  doublereal* dlnActCoeffds) const
465 {
468  for (size_t k = 0; k < m_kk; k++) {
469  dlnActCoeffds[k] = dlnActCoeffdT_Scaled_[k] * dTds;
470  for (size_t j = 0; j < m_kk; j++) {
471  dlnActCoeffds[k] += dlnActCoeff_dX_(k, j) * dXds[j];
472  }
473  }
474 }
475 
476 void RedlichKisterVPSSTP::getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const
477 {
479  for (size_t j = 0; j < m_kk; j++) {
480  dlnActCoeffdlnN_diag[j] = dlnActCoeff_dX_(j, j);
481  for (size_t k = 0; k < m_kk; k++) {
482  dlnActCoeffdlnN_diag[k] -= dlnActCoeff_dX_(j, k) * moleFractions_[k];
483  }
484  }
485 }
486 
487 void RedlichKisterVPSSTP::getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const
488 {
490  for (size_t k = 0; k < m_kk; k++) {
491  dlnActCoeffdlnX_diag[k] = dlnActCoeffdlnX_diag_[k];
492  }
493 }
494 
495 void RedlichKisterVPSSTP::getdlnActCoeffdlnN(const size_t ld, doublereal* dlnActCoeffdlnN)
496 {
498  double* data = & dlnActCoeffdlnN_(0,0);
499  for (size_t k = 0; k < m_kk; k++) {
500  for (size_t m = 0; m < m_kk; m++) {
501  dlnActCoeffdlnN[ld * k + m] = data[m_kk * k + m];
502  }
503  }
504 }
505 
507 {
508  std::string xname = xmLBinarySpecies.name();
509  if (xname != "binaryNeutralSpeciesParameters") {
510  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies",
511  "Incorrect name for processing this routine: " + xname);
512  }
513  vector_fp hParams, sParams;
514  std::string iName = xmLBinarySpecies.attrib("speciesA");
515  if (iName == "") {
516  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
517  }
518  std::string jName = xmLBinarySpecies.attrib("speciesB");
519  if (jName == "") {
520  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
521  }
522 
523  // Find the index of the species in the current phase. It's not an error to
524  // not find the species. This means that the interaction doesn't occur for
525  // the current implementation of the phase.
526  size_t iSpecies = speciesIndex(iName);
527  if (iSpecies == npos) {
528  return;
529  }
530  size_t jSpecies = speciesIndex(jName);
531  if (jSpecies == npos) {
532  return;
533  }
534 
535  // Ok we have found a valid interaction
536  for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
537  XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
538  string nodeName = toLowerCopy(xmlChild.name());
539 
540  // Process the binary species interaction child elements
541  if (nodeName == "excessenthalpy") {
542  getFloatArray(xmlChild, hParams, true, "toSI", "excessEnthalpy");
543  } else if (nodeName == "excessentropy") {
544  getFloatArray(xmlChild, sParams, true, "toSI", "excessEntropy");
545  }
546  }
547  addBinaryInteraction(iName, jName, hParams.data(), hParams.size(),
548  sParams.data(), sParams.size());
549 }
550 
552  const std::string& speciesA, const std::string& speciesB,
553  const double* excess_enthalpy, size_t n_enthalpy,
554  const double* excess_entropy, size_t n_entropy)
555 {
556  size_t kA = speciesIndex(speciesA);
557  size_t kB = speciesIndex(speciesB);
558  if (kA == npos) {
559  throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
560  "Species '{}' not present in phase", speciesA);
561  } else if (kB == npos) {
562  throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
563  "Species '{}' not present in phase", speciesB);
564  }
565  if (charge(kA) != 0) {
566  throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
567  "Species '{}' should be neutral", speciesA);
568  } else if (charge(kB) != 0) {
569  throw CanteraError("RedlichKisterVPSSTP::addBinaryInteraction",
570  "Species '{}' should be neutral", speciesB);
571  }
572 
573  m_pSpecies_A_ij.push_back(kA);
574  m_pSpecies_B_ij.push_back(kB);
575  m_HE_m_ij.emplace_back(excess_enthalpy, excess_enthalpy + n_enthalpy);
576  m_SE_m_ij.emplace_back(excess_entropy, excess_entropy + n_entropy);
577  size_t N = max(n_enthalpy, n_entropy);
578  m_HE_m_ij.back().resize(N, 0.0);
579  m_SE_m_ij.back().resize(N, 0.0);
580  m_N_ij.push_back(N);
581  dlnActCoeff_dX_.resize(N, N, 0.0);
583 }
584 
585 }
(see Thermodynamic Properties and class RedlichKisterVPSSTP).
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:984
void resize(size_t n, size_t m, doublereal v=0.0)
Resize the array, and fill the new entries with 'v'.
Definition: Array.h:112
void zero()
Set all of the entries to zero.
Definition: Array.h:198
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
vector_fp dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
vector_fp lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
vector_fp d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
vector_fp moleFractions_
Storage for the current values of the mole fractions of the species.
vector_fp dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
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:643
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
doublereal temperature() const
Temperature (K).
Definition: Phase.h:667
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:201
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Definition: Phase.cpp:980
void s_update_dlnActCoeff_dX_() const
Internal routine that calculates the derivative of the activity coefficients wrt the mole fractions.
Array2D dlnActCoeff_dX_
Two dimensional array of derivatives of activity coefficients wrt mole fractions.
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients.
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
size_t numBinaryInteractions_
number of binary interaction expressions
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
std::vector< vector_fp > m_HE_m_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
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 ...
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
std::vector< size_t > m_N_ij
Vector of the length of the polynomial for the interaction.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of ln mole fraction derivatives of the log activity coefficients - diagonal component o...
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
std::vector< size_t > m_pSpecies_A_ij
vector of species indices representing species A in the interaction
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of log species mole number derivatives of the log activity coefficients.
virtual void getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients wrt changes in state (temp, mole fraction,...
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
void initLengths()
Initialize lengths of local variables after all species have been identified.
void s_update_dlnActCoeff_dlnX_diag() const
Internal routine that calculates the total derivative of the activity coefficients with respect to th...
void s_update_lnActCoeff() const
Update the activity coefficients.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
std::vector< vector_fp > m_SE_m_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression.
void addBinaryInteraction(const std::string &speciesA, const std::string &speciesB, const double *excess_enthalpy, size_t n_enthalpy, const double *excess_entropy, size_t n_entropy)
Add a binary species interaction with the specified parameters.
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:776
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1874
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:104
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:492
std::string name() const
Returns the name of the XML node.
Definition: xml.h:372
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:528
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:538
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:556
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:546
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:149
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:180
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:264
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
std::string toLowerCopy(const std::string &input)
Convert to lower case.
size_t getFloatArray(const XML_Node &node, vector_fp &v, const bool convert, const std::string &unitsString, const std::string &nodeName)
This function reads the current node or a child node of the current node with the default name,...
Definition: ctml.cpp:256
Contains declarations for string manipulation functions within Cantera.