Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 /*
10  * Copyright (2009) Sandia Corporation. Under the terms of
11  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
12  * U.S. Government retains certain rights in this software.
13  */
14 
18 #include "cantera/base/ctml.h"
19 
20 using namespace std;
21 
22 namespace Cantera
23 {
24 RedlichKisterVPSSTP::RedlichKisterVPSSTP() :
25  numBinaryInteractions_(0),
26  formRedlichKister_(0),
27  formTempModel_(0)
28 {
29 }
30 
31 RedlichKisterVPSSTP::RedlichKisterVPSSTP(const std::string& inputFile,
32  const std::string& id_) :
33  numBinaryInteractions_(0),
34  formRedlichKister_(0),
35  formTempModel_(0)
36 {
37  initThermoFile(inputFile, id_);
38 }
39 
41  const std::string& id_) :
42  numBinaryInteractions_(0),
43  formRedlichKister_(0),
44  formTempModel_(0)
45 {
46  importPhase(*findXMLPhase(&phaseRoot, id_), this);
47 }
48 
50  numBinaryInteractions_(0),
51  formRedlichKister_(0),
52  formTempModel_(0)
53 {
54  warn_deprecated("RedlichKisterVPSSTP::RedlichKisterVPSSTP(int testProb)",
55  "To be removed after Cantera 2.2");
56 
57  initThermoFile("LiKCl_liquid.xml", "");
59 
60  m_HE_m_ij.resize(0);
61  m_SE_m_ij.resize(0);
62 
63  vector_fp he(2);
64  he[0] = 0.0;
65  he[1] = 0.0;
66  vector_fp se(2);
67  se[0] = 0.0;
68  se[1] = 0.0;
69 
70  m_HE_m_ij.push_back(he);
71  m_SE_m_ij.push_back(se);
72  m_N_ij.push_back(1);
73  m_pSpecies_A_ij.resize(1);
74  m_pSpecies_B_ij.resize(1);
75 
76  size_t iLiLi = speciesIndex("LiLi");
77  if (iLiLi == npos) {
78  throw CanteraError("RedlichKisterVPSSTP test1 constructor",
79  "Unable to find LiLi");
80  }
81  m_pSpecies_A_ij[0] = iLiLi;
82 
83 
84  size_t iVLi = speciesIndex("VLi");
85  if (iVLi == npos) {
86  throw CanteraError("RedlichKisterVPSSTP test1 constructor",
87  "Unable to find VLi");
88  }
89  m_pSpecies_B_ij[0] = iVLi;
90 }
91 
93  numBinaryInteractions_(0),
94  formRedlichKister_(0),
95  formTempModel_(0)
96 {
98 }
99 
101 {
102  if (&b == this) {
103  return *this;
104  }
105 
107 
111  m_N_ij = b.m_N_ij;
112  m_HE_m_ij = b.m_HE_m_ij;
113  m_SE_m_ij = b.m_SE_m_ij;
117 
118  return *this;
119 }
120 
122 {
123  return new RedlichKisterVPSSTP(*this);
124 }
125 
126 /*
127  * - Activities, Standard States, Activity Concentrations -----------
128  */
129 
131 {
132  /*
133  * Update the activity coefficients
134  */
136 
137  /*
138  * take the exp of the internally stored coefficients.
139  */
140  for (size_t k = 0; k < m_kk; k++) {
141  lnac[k] = lnActCoeff_Scaled_[k];
142  }
143 }
144 
145 /*
146  * ------------ Partial Molar Properties of the Solution ------------
147  */
148 
150 {
151  getChemPotentials(mu);
152  double ve = Faraday * electricPotential();
153  for (size_t k = 0; k < m_kk; k++) {
154  mu[k] += ve*charge(k);
155  }
156 }
157 
158 void RedlichKisterVPSSTP::getChemPotentials(doublereal* mu) const
159 {
160  /*
161  * First get the standard chemical potentials in
162  * molar form.
163  * -> this requires updates of standard state as a function
164  * of T and P
165  */
167  /*
168  * Update the activity coefficients
169  */
171 
172  doublereal RT = GasConstant * temperature();
173  for (size_t k = 0; k < m_kk; k++) {
174  double xx = std::max(moleFractions_[k], SmallNumber);
175  mu[k] += RT * (log(xx) + lnActCoeff_Scaled_[k]);
176  }
177 }
178 
180 {
181  double h = 0;
182  vector_fp hbar(m_kk);
183  getPartialMolarEnthalpies(&hbar[0]);
184  for (size_t i = 0; i < m_kk; i++) {
185  h += moleFractions_[i]*hbar[i];
186  }
187  return h;
188 }
189 
191 {
192  double s = 0;
193  vector_fp sbar(m_kk);
194  getPartialMolarEntropies(&sbar[0]);
195  for (size_t i = 0; i < m_kk; i++) {
196  s += moleFractions_[i]*sbar[i];
197  }
198  return s;
199 }
200 
202 {
203  double cp = 0;
204  vector_fp cpbar(m_kk);
205  getPartialMolarCp(&cpbar[0]);
206  for (size_t i = 0; i < m_kk; i++) {
207  cp += moleFractions_[i]*cpbar[i];
208  }
209  return cp;
210 }
211 
213 {
214  return cp_mole() - GasConstant;
215 }
216 
218 {
219  /*
220  * Get the nondimensional standard state enthalpies
221  */
222  getEnthalpy_RT(hbar);
223  /*
224  * dimensionalize it.
225  */
226  double T = temperature();
227  for (size_t k = 0; k < m_kk; k++) {
228  hbar[k] *= GasConstant * T;
229  }
230  /*
231  * Update the activity coefficients, This also update the
232  * internally stored molalities.
233  */
236  for (size_t k = 0; k < m_kk; k++) {
237  hbar[k] -= GasConstant * T * T * dlnActCoeffdT_Scaled_[k];
238  }
239 }
240 
241 void RedlichKisterVPSSTP::getPartialMolarCp(doublereal* cpbar) const
242 {
243  /*
244  * Get the nondimensional standard state entropies
245  */
246  getCp_R(cpbar);
247  double T = temperature();
248  /*
249  * Update the activity coefficients, This also update the
250  * internally stored molalities.
251  */
254 
255  for (size_t k = 0; k < m_kk; k++) {
256  cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
257  }
258  /*
259  * dimensionalize it.
260  */
261  for (size_t k = 0; k < m_kk; k++) {
262  cpbar[k] *= GasConstant;
263  }
264 }
265 
267 {
268  /*
269  * Get the nondimensional standard state entropies
270  */
271  getEntropy_R(sbar);
272  double T = temperature();
273  /*
274  * Update the activity coefficients, This also update the
275  * internally stored molalities.
276  */
279 
280  for (size_t k = 0; k < m_kk; k++) {
281  double xx = std::max(moleFractions_[k], SmallNumber);
282  sbar[k] += - lnActCoeff_Scaled_[k] -log(xx) - T * dlnActCoeffdT_Scaled_[k];
283  }
284  /*
285  * dimensionalize it.
286  */
287  for (size_t k = 0; k < m_kk; k++) {
288  sbar[k] *= GasConstant;
289  }
290 }
291 
293 {
294  /*
295  * Get the standard state values in m^3 kmol-1
296  */
297  getStandardVolumes(vbar);
298  for (size_t iK = 0; iK < m_kk; iK++) {
299 
300  vbar[iK] += 0.0;
301  }
302 }
303 
305 {
306  initLengths();
308 }
309 
311 {
313 }
314 
315 void RedlichKisterVPSSTP::initThermoXML(XML_Node& phaseNode, const std::string& id_)
316 {
317  if ((int) id_.size() > 0 && phaseNode.id() != id_) {
318  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
319  "phasenode and Id are incompatible");
320  }
321 
322  /*
323  * Check on the thermo field. Must have:
324  * <thermo model="Redlich-Kister" />
325  */
326  if (!phaseNode.hasChild("thermo")) {
327  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
328  "no thermo XML node");
329  }
330  XML_Node& thermoNode = phaseNode.child("thermo");
331  std::string mString = thermoNode.attrib("model");
332  if (lowercase(mString) != "redlich-kister") {
333  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
334  "Unknown thermo model: " + mString + " - This object only knows \"Redlich-Kister\" ");
335  }
336 
337  /*
338  * Go get all of the coefficients and factors in the
339  * activityCoefficients XML block
340  */
341  if (thermoNode.hasChild("activityCoefficients")) {
342  XML_Node& acNode = thermoNode.child("activityCoefficients");
343  mString = acNode.attrib("model");
344  if (lowercase(mString) != "redlich-kister") {
345  throw CanteraError("RedlichKisterVPSSTP::initThermoXML",
346  "Unknown activity coefficient model: " + mString);
347  }
348  for (size_t i = 0; i < acNode.nChildren(); i++) {
349  XML_Node& xmlACChild = acNode.child(i);
350  /*
351  * Process a binary salt field, or any of the other XML fields
352  * that make up the Pitzer Database. Entries will be ignored
353  * if any of the species in the entry isn't in the solution.
354  */
355  if (lowercase(xmlACChild.name()) == "binaryneutralspeciesparameters") {
356  readXMLBinarySpecies(xmlACChild);
357  }
358  }
359  }
360  /*
361  * Go down the chain
362  */
363  GibbsExcessVPSSTP::initThermoXML(phaseNode, id_);
364 }
365 
367 {
368  doublereal T = temperature();
369  lnActCoeff_Scaled_.assign(m_kk, 0.0);
370 
371  /*
372  * Scaling: I moved the division of RT higher so that we are always dealing with G/RT dimensionless terms
373  * within the routine. There is a severe problem with roundoff error in these calculations. The
374  * dimensionless terms help.
375  */
376 
377  for (size_t i = 0; i < numBinaryInteractions_; i++) {
378  size_t iA = m_pSpecies_A_ij[i];
379  size_t iB = m_pSpecies_B_ij[i];
380  double XA = moleFractions_[iA];
381  double XB = moleFractions_[iB];
382  doublereal deltaX = XA - XB;
383  size_t N = m_N_ij[i];
384  vector_fp& he_vec = m_HE_m_ij[i];
385  vector_fp& se_vec = m_SE_m_ij[i];
386  doublereal poly = 1.0;
387  doublereal polyMm1 = 1.0;
388  doublereal sum = 0.0;
389  doublereal sumMm1 = 0.0;
390  doublereal sum2 = 0.0;
391  for (size_t m = 0; m < N; m++) {
392  doublereal A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);
393  sum += A_ge * poly;
394  sum2 += A_ge * (m + 1) * poly;
395  poly *= deltaX;
396  if (m >= 1) {
397  sumMm1 += (A_ge * polyMm1 * m);
398  polyMm1 *= deltaX;
399  }
400  }
401  doublereal oneMXA = 1.0 - XA;
402  doublereal oneMXB = 1.0 - XB;
403  for (size_t k = 0; k < m_kk; k++) {
404  if (iA == k) {
405  lnActCoeff_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
406  } else if (iB == k) {
407  lnActCoeff_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
408  } else {
409  lnActCoeff_Scaled_[k] += -(XA * XB * sum2);
410  }
411  }
412  // Debug against formula in literature
413 #ifdef DEBUG_MODE_NOT
414  double lnA = 0.0;
415  double lnB = 0.0;
416  double polyk = 1.0;
417  double fac = 2.0 * XA - 1.0;
418  for (int m = 0; m < N; m++) {
419  doublereal A_ge = (he_vec[m] - T * se_vec[m]) / (GasConstant * T);
420  lnA += A_ge * oneMXA * oneMXA * polyk * (1.0 + 2.0 * XA * m / fac);
421  lnB += A_ge * XA * XA * polyk * (1.0 - 2.0 * oneMXA * m / fac);
422  polyk *= fac;
423  }
424  // This gives the same result as above
425 #endif
426 
427  }
428 
429 }
430 
432 {
433  dlnActCoeffdT_Scaled_.assign(m_kk, 0.0);
434  d2lnActCoeffdT2_Scaled_.assign(m_kk, 0.0);
435 
436  for (size_t i = 0; i < numBinaryInteractions_; i++) {
437  size_t iA = m_pSpecies_A_ij[i];
438  size_t iB = m_pSpecies_B_ij[i];
439  double XA = moleFractions_[iA];
440  double XB = moleFractions_[iB];
441  doublereal deltaX = XA - XB;
442  size_t N = m_N_ij[i];
443  doublereal poly = 1.0;
444  doublereal sum = 0.0;
445 
446  vector_fp& se_vec = m_SE_m_ij[i];
447  doublereal sumMm1 = 0.0;
448  doublereal polyMm1 = 1.0;
449  doublereal sum2 = 0.0;
450  for (size_t m = 0; m < N; m++) {
451  doublereal A_ge = - se_vec[m];
452  sum += A_ge * poly;
453  sum2 += A_ge * (m + 1) * poly;
454  poly *= deltaX;
455  if (m >= 1) {
456  sumMm1 += (A_ge * polyMm1 * m);
457  polyMm1 *= deltaX;
458  }
459  }
460  doublereal oneMXA = 1.0 - XA;
461  doublereal oneMXB = 1.0 - XB;
462  for (size_t k = 0; k < m_kk; k++) {
463  if (iA == k) {
464  dlnActCoeffdT_Scaled_[k] += (oneMXA * XB * sum) + (XA * XB * sumMm1 * (oneMXA + XB));
465  } else if (iB == k) {
466  dlnActCoeffdT_Scaled_[k] += (oneMXB * XA * sum) + (XA * XB * sumMm1 * (-oneMXB - XA));
467  } else {
468  dlnActCoeffdT_Scaled_[k] += -(XA * XB * sum2);
469  }
470  }
471  }
472 }
473 
474 void RedlichKisterVPSSTP::getdlnActCoeffdT(doublereal* dlnActCoeffdT) const
475 {
477  for (size_t k = 0; k < m_kk; k++) {
478  dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k];
479  }
480 }
481 
482 void RedlichKisterVPSSTP::getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const
483 {
485  for (size_t k = 0; k < m_kk; k++) {
486  d2lnActCoeffdT2[k] = d2lnActCoeffdT2_Scaled_[k];
487  }
488 }
489 
491 {
492  doublereal T = temperature();
493 
495 
496  for (size_t i = 0; i < numBinaryInteractions_; i++) {
497  size_t iA = m_pSpecies_A_ij[i];
498  size_t iB = m_pSpecies_B_ij[i];
499  double XA = moleFractions_[iA];
500  double XB = moleFractions_[iB];
501  doublereal deltaX = XA - XB;
502  size_t N = m_N_ij[i];
503  doublereal poly = 1.0;
504  doublereal sum = 0.0;
505  vector_fp& he_vec = m_HE_m_ij[i];
506  vector_fp& se_vec = m_SE_m_ij[i];
507  doublereal sumMm1 = 0.0;
508  doublereal polyMm1 = 1.0;
509  doublereal polyMm2 = 1.0;
510  doublereal sum2 = 0.0;
511  doublereal sum2Mm1 = 0.0;
512  doublereal sumMm2 = 0.0;
513  for (size_t m = 0; m < N; m++) {
514  doublereal A_ge = he_vec[m] - T * se_vec[m];
515  sum += A_ge * poly;
516  sum2 += A_ge * (m + 1) * poly;
517  poly *= deltaX;
518  if (m >= 1) {
519  sumMm1 += (A_ge * polyMm1 * m);
520  sum2Mm1 += (A_ge * polyMm1 * m * (1.0 + m));
521  polyMm1 *= deltaX;
522  }
523  if (m >= 2) {
524  sumMm2 += (A_ge * polyMm2 * m * (m - 1.0));
525  polyMm2 *= deltaX;
526  }
527  }
528 
529  for (size_t k = 0; k < m_kk; k++) {
530  if (iA == k) {
531 
532  dlnActCoeff_dX_(k, iA) += (- XB * sum + (1.0 - XA) * XB * sumMm1
533  + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
534  + XA * XB * sumMm2 * (1.0 - XA + XB));
535 
536  dlnActCoeff_dX_(k, iB) += ((1.0 - XA) * sum - (1.0 - XA) * XB * sumMm1
537  + XA * sumMm1 * (1.0 + 2.0 * XB - XA)
538  - XA * XB * sumMm2 * (1.0 - XA + XB));
539 
540  } else if (iB == k) {
541 
542  dlnActCoeff_dX_(k, iA) += ((1.0 - XB) * sum + (1.0 - XA) * XB * sumMm1
543  + XB * sumMm1 * (1.0 - 2.0 * XA + XB)
544  + XA * XB * sumMm2 * (1.0 - XA + XB));
545 
546  dlnActCoeff_dX_(k, iB) += (- XA * sum - (1.0 - XB) * XA * sumMm1
547  + XA * sumMm1 * (XB - XA - (1.0 - XB))
548  - XA * XB * sumMm2 * (-XA - (1.0 - XB)));
549  } else {
550 
551  dlnActCoeff_dX_(k, iA) += (- XB * sum2 - XA * XB * sum2Mm1);
552 
553  dlnActCoeff_dX_(k, iB) += (- XA * sum2 + XA * XB * sum2Mm1);
554 
555  }
556  }
557  }
558 }
559 
560 void RedlichKisterVPSSTP::getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
561  doublereal* dlnActCoeffds) const
562 {
565  for (size_t k = 0; k < m_kk; k++) {
566  dlnActCoeffds[k] = dlnActCoeffdT_Scaled_[k] * dTds;
567  for (size_t l = 0; l < m_kk; l++) {
568  dlnActCoeffds[k] += dlnActCoeff_dX_(k, l) * dXds[l];
569  }
570  }
571 }
572 
573 void RedlichKisterVPSSTP::getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const
574 {
576  for (size_t l = 0; l < m_kk; l++) {
577  dlnActCoeffdlnN_diag[l] = dlnActCoeff_dX_(l, l);
578  for (size_t k = 0; k < m_kk; k++) {
579  dlnActCoeffdlnN_diag[k] -= dlnActCoeff_dX_(l, k) * moleFractions_[k];
580  }
581  }
582 }
583 
584 void RedlichKisterVPSSTP::getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const
585 {
587  for (size_t k = 0; k < m_kk; k++) {
588  dlnActCoeffdlnX_diag[k] = dlnActCoeffdlnX_diag_[k];
589  }
590 }
591 
592 void RedlichKisterVPSSTP::getdlnActCoeffdlnN(const size_t ld, doublereal* dlnActCoeffdlnN)
593 {
595  double* data = & dlnActCoeffdlnN_(0,0);
596  for (size_t k = 0; k < m_kk; k++) {
597  for (size_t m = 0; m < m_kk; m++) {
598  dlnActCoeffdlnN[ld * k + m] = data[m_kk * k + m];
599  }
600  }
601 }
602 
604 {
606  m_pSpecies_A_ij.resize(num, npos);
607  m_pSpecies_B_ij.resize(num, npos);
608  m_N_ij.resize(num, npos);
609  m_HE_m_ij.resize(num);
610  m_SE_m_ij.resize(num);
611  dlnActCoeff_dX_.resize(num, num, 0.0);
612 }
613 
615 {
616  std::string xname = xmLBinarySpecies.name();
617  if (xname != "binaryNeutralSpeciesParameters") {
618  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies",
619  "Incorrect name for processing this routine: " + xname);
620  }
621  size_t Npoly = 0;
622  vector_fp hParams, sParams;
623  std::string iName = xmLBinarySpecies.attrib("speciesA");
624  if (iName == "") {
625  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesA attrib");
626  }
627  std::string jName = xmLBinarySpecies.attrib("speciesB");
628  if (jName == "") {
629  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "no speciesB attrib");
630  }
631  /*
632  * Find the index of the species in the current phase. It's not
633  * an error to not find the species. This means that the interaction doesn't occur for the current
634  * implementation of the phase.
635  */
636  size_t iSpecies = speciesIndex(iName);
637  if (iSpecies == npos) {
638  return;
639  }
640  string ispName = speciesName(iSpecies);
641  if (charge(iSpecies) != 0) {
642  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "speciesA charge problem");
643  }
644  size_t jSpecies = speciesIndex(jName);
645  if (jSpecies == npos) {
646  return;
647  }
648  std::string jspName = speciesName(jSpecies);
649  if (charge(jSpecies) != 0) {
650  throw CanteraError("RedlichKisterVPSSTP::readXMLBinarySpecies", "speciesB charge problem");
651  }
652  /*
653  * Ok we have found a valid interaction
654  */
656  size_t iSpot = numBinaryInteractions_ - 1;
659  m_pSpecies_A_ij[iSpot] = iSpecies;
660  m_pSpecies_B_ij[iSpot] = jSpecies;
661 
662  for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
663  XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
664  string nodeName = lowercase(xmlChild.name());
665  /*
666  * Process the binary species interaction child elements
667  */
668  if (nodeName == "excessenthalpy") {
669  /*
670  * Get the string containing all of the values
671  */
672  getFloatArray(xmlChild, hParams, true, "toSI", "excessEnthalpy");
673  Npoly = std::max(hParams.size(), Npoly);
674  }
675 
676  if (nodeName == "excessentropy") {
677  /*
678  * Get the string containing all of the values
679  */
680  getFloatArray(xmlChild, sParams, true, "toSI", "excessEntropy");
681  Npoly = std::max(sParams.size(), Npoly);
682  }
683  }
684  hParams.resize(Npoly, 0.0);
685  sParams.resize(Npoly, 0.0);
686  m_HE_m_ij.push_back(hParams);
687  m_SE_m_ij.push_back(sParams);
688  m_N_ij.push_back(Npoly);
690 }
691 
692 #ifdef DEBUG_MODE
693 void RedlichKisterVPSSTP::Vint(double& VintOut, double& voltsOut)
694 {
695  doublereal T = temperature();
696  double Volts = 0.0;
697 
698  lnActCoeff_Scaled_.assign(m_kk, 0.0);
699 
700  for (size_t i = 0; i < numBinaryInteractions_; i++) {
701  size_t iA = m_pSpecies_A_ij[i];
702  double XA = moleFractions_[iA];
703  if (XA <= 1.0E-14) {
704  XA = 1.0E-14;
705  }
706  if (XA >= (1.0 - 1.0E-14)) {
707  XA = 1.0 - 1.0E-14;
708  }
709 
710  size_t N = m_N_ij[i];
711  vector_fp& he_vec = m_HE_m_ij[i];
712  vector_fp& se_vec = m_SE_m_ij[i];
713  double fac = 2.0 * XA - 1.0;
714  if (fabs(fac) < 1.0E-13) {
715  fac = 1.0E-13;
716  }
717  double polykp1 = fac;
718  double poly1mk = fac;
719 
720  for (size_t m = 0; m < N; m++) {
721  doublereal A_ge = he_vec[m] - T * se_vec[m];
722  Volts += A_ge * (polykp1 - (2.0 * XA * m * (1.0-XA)) / poly1mk);
723  polykp1 *= fac;
724  poly1mk /= fac;
725  }
726  }
727  Volts /= Faraday;
728 
729  double termp = GasConstant * T * log((1.0 - XA)/XA) / Faraday;
730 
731  VintOut = Volts;
732  voltsOut = Volts + termp;
733 }
734 #endif
735 }
virtual void getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients w.r.t.
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
doublereal electricPotential() const
Returns the electric potential of this phase (V).
Definition: ThermoPhase.h:352
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
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 attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:527
GibbsExcessVPSSTP & operator=(const GibbsExcessVPSSTP &b)
Assignment operator.
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:121
RedlichKisterVPSSTP is a derived class of GibbsExcessVPSSTP that employs the Redlich-Kister approxima...
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of each species in their standard states at the current T and P of the solution...
RedlichKisterVPSSTP & operator=(const RedlichKisterVPSSTP &b)
Assignment operator.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
size_t numBinaryInteractions_
number of binary interaction expressions
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the standard state of the species at ...
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
std::vector< vector_fp > m_HE_m_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
int formRedlichKister_
form of the RedlichKister interaction expression
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:78
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:73
int formTempModel_
form of the temperature dependence of the Redlich-Kister interaction expression
std::vector< doublereal > d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
Array2D dlnActCoeff_dX_
Two dimensional array of derivatives of activity coefficients wrt mole fractions. ...
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
std::vector< size_t > m_pSpecies_A_ij
vector of species indices representing species A in the interaction
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:97
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:257
bool importPhase(XML_Node &phase, ThermoPhase *th, SpeciesThermoFactory *spfactory)
Import a phase information into an empty ThermoPhase object.
void s_update_lnActCoeff() const
Update the activity coefficients.
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
std::string name() const
Returns the name of the XML node.
Definition: xml.h:394
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of log concentration-like derivatives of the log activity coefficients - diagonal compo...
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
virtual void getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of derivatives of the log activity coefficients wrt mole numbers - diagonal only...
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:563
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
std::vector< doublereal > dlnActCoeffdlnX_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Enthalpy functions for the standard state species at the current T an...
doublereal temperature() const
Temperature (K).
Definition: Phase.h:602
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:448
const doublereal SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:126
void initLengths()
Initialize lengths of local variables after all species have been identified.
std::vector< doublereal > lnActCoeff_Scaled_
Storage for the current values of the activity coefficients of the species.
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
virtual void getLnActivityCoefficients(doublereal *lnac) const
Get the array of non-dimensional molar-based ln activity coefficients at the current solution tempera...
void s_update_dlnActCoeff_dX_() const
Internal routine that calculates the derivative of the activity coefficients wrt the mole fractions...
size_t getFloatArray(const XML_Node &node, std::vector< doublereal > &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:323
std::vector< doublereal > moleFractions_
Storage for the current values of the mole fractions of the species.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Initialize a ThermoPhase object, potentially reading activity coefficient information from an XML dat...
Contains declarations for string manipulation functions within Cantera.
void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
void getElectrochemPotentials(doublereal *mu) const
Get the species electrochemical potentials.
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the ln activity coefficients with respect to the ln species mole numb...
size_t m_kk
Number of species in the phase.
Definition: Phase.h:843
Array2D dlnActCoeffdlnN_
Storage for the current derivative values of the gradients with respect to logarithm of the species m...
void Vint(double &VintOut, double &voltsOut)
Utility routine that calculates a literature expression.
void zero()
Set all of the entries to zero.
Definition: Array.h:251
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity.
Header for intermediate ThermoPhase object for phases which employ Gibbs excess free energy based for...
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients. ...
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:272
void resizeNumInteractions(const size_t num)
Resize internal arrays within the object that depend upon the number of binary Redlich-Kister interac...
size_t nChildren(bool discardComments=false) const
Return the number of children.
Definition: xml.cpp:583
std::vector< doublereal > dlnActCoeffdT_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol.
std::vector< size_t > m_N_ij
Vector of the length of the polynomial for the interaction.
std::vector< vector_fp > m_SE_m_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
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:578