Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PhaseCombo_Interaction.cpp
Go to the documentation of this file.
1 /**
2  * @file
3  */
4 /*
5  * Copyright (2009) Sandia Corporation. Under the terms of
6  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
7  * U.S. Government retains certain rights in this software.
8  */
9 
13 #include "cantera/base/ctml.h"
14 
15 using namespace std;
16 
17 namespace Cantera
18 {
19 PhaseCombo_Interaction::PhaseCombo_Interaction() :
20  numBinaryInteractions_(0),
21  formMargules_(0),
22  formTempModel_(0)
23 {
24 }
25 
27  const std::string& id_) :
28  numBinaryInteractions_(0),
29  formMargules_(0),
30  formTempModel_(0)
31 {
32  initThermoFile(inputFile, id_);
33 }
34 
36  const std::string& id_) :
37  numBinaryInteractions_(0),
38  formMargules_(0),
39  formTempModel_(0)
40 {
41  importPhase(*findXMLPhase(&phaseRoot, id_), this);
42 }
43 
45 {
47 }
48 
50 {
51  if (&b == this) {
52  return *this;
53  }
54 
56 
58  m_HE_b_ij = b.m_HE_b_ij;
59  m_HE_c_ij = b.m_HE_c_ij;
60  m_HE_d_ij = b.m_HE_d_ij;
61  m_SE_b_ij = b.m_SE_b_ij;
62  m_SE_c_ij = b.m_SE_c_ij;
63  m_SE_d_ij = b.m_SE_d_ij;
74 
75  return *this;
76 }
77 
80 {
81  return new PhaseCombo_Interaction(*this);
82 }
83 
86  numBinaryInteractions_(0),
87  formMargules_(0),
88  formTempModel_(0)
89 {
90  warn_deprecated("PhaseCombo_Interaction::PhaseCombo_Interaction(int testProb)",
91  "To be removed after Cantera 2.2");
92 
93  initThermoFile("PhaseCombo_Interaction.xml", "");
94 
95 
97 
98  m_HE_b_ij.resize(1);
99  m_HE_c_ij.resize(1);
100  m_HE_d_ij.resize(1);
101 
102  m_SE_b_ij.resize(1);
103  m_SE_c_ij.resize(1);
104  m_SE_d_ij.resize(1);
105 
106  m_VHE_b_ij.resize(1);
107  m_VHE_c_ij.resize(1);
108  m_VHE_d_ij.resize(1);
109 
110  m_VSE_b_ij.resize(1);
111  m_VSE_c_ij.resize(1);
112  m_VSE_d_ij.resize(1);
113 
114  m_pSpecies_A_ij.resize(1);
115  m_pSpecies_B_ij.resize(1);
116 
117 
118 
119  m_HE_b_ij[0] = -17570E3;
120  m_HE_c_ij[0] = -377.0E3;
121  m_HE_d_ij[0] = 0.0;
122 
123  m_SE_b_ij[0] = -7.627E3;
124  m_SE_c_ij[0] = 4.958E3;
125  m_SE_d_ij[0] = 0.0;
126 
127 
128  size_t iLiT = speciesIndex("LiTFe1S2(S)");
129  if (iLiT == npos) {
130  throw CanteraError("PhaseCombo_Interaction test1 constructor",
131  "Unable to find LiTFe1S2(S)");
132  }
133  m_pSpecies_A_ij[0] = iLiT;
134 
135 
136  size_t iLi2 = speciesIndex("Li2Fe1S2(S)");
137  if (iLi2 == npos) {
138  throw CanteraError("PhaseCombo_Interaction test1 constructor",
139  "Unable to find Li2Fe1S2(S)");
140  }
141  m_pSpecies_B_ij[0] = iLi2;
142  throw CanteraError("PhaseCombo_Interaction test1 constructor", "unimplemented");
143 }
144 
145 /*
146  * -------------- Utilities -------------------------------
147  */
148 
150 {
151  return cPhaseCombo_Interaction;
152 }
153 
154 /*
155  * - Activities, Standard States, Activity Concentrations -----------
156  */
157 
159 {
160  /*
161  * Update the activity coefficients
162  */
164 
165  /*
166  * take the exp of the internally stored coefficients.
167  */
168  for (size_t k = 0; k < m_kk; k++) {
169  ac[k] = exp(lnActCoeff_Scaled_[k]);
170  }
171 }
172 
173 /*
174  * ------------ Partial Molar Properties of the Solution ------------
175  */
176 
178 {
179  getChemPotentials(mu);
180  double ve = Faraday * electricPotential();
181  for (size_t k = 0; k < m_kk; k++) {
182  mu[k] += ve*charge(k);
183  }
184 }
185 
187 {
188  /*
189  * First get the standard chemical potentials in
190  * molar form.
191  * -> this requires updates of standard state as a function
192  * of T and P
193  */
195  /*
196  * Update the activity coefficients
197  */
199 
200  doublereal RT = GasConstant * temperature();
201  for (size_t k = 0; k < m_kk; k++) {
202  double xx = std::max(moleFractions_[k], SmallNumber);
203  mu[k] += RT * (log(xx) + lnActCoeff_Scaled_[k]);
204  }
205 }
206 
208 {
209  double h = 0;
210  vector_fp hbar(m_kk);
211  getPartialMolarEnthalpies(&hbar[0]);
212  for (size_t i = 0; i < m_kk; i++) {
213  h += moleFractions_[i]*hbar[i];
214  }
215  return h;
216 }
217 
219 {
220  double s = 0;
221  vector_fp sbar(m_kk);
222  getPartialMolarEntropies(&sbar[0]);
223  for (size_t i = 0; i < m_kk; i++) {
224  s += moleFractions_[i]*sbar[i];
225  }
226  return s;
227 }
228 
230 {
231  double cp = 0;
232  vector_fp cpbar(m_kk);
233  getPartialMolarCp(&cpbar[0]);
234  for (size_t i = 0; i < m_kk; i++) {
235  cp += moleFractions_[i]*cpbar[i];
236  }
237  return cp;
238 }
239 
241 {
242  return cp_mole() - GasConstant;
243 }
244 
246 {
247  /*
248  * Get the nondimensional standard state enthalpies
249  */
250  getEnthalpy_RT(hbar);
251  /*
252  * dimensionalize it.
253  */
254  double T = temperature();
255  for (size_t k = 0; k < m_kk; k++) {
256  hbar[k] *= GasConstant * T;
257  }
258  /*
259  * Update the activity coefficients, This also update the
260  * internally stored molalities.
261  */
264  for (size_t k = 0; k < m_kk; k++) {
265  hbar[k] -= GasConstant * T * T * dlnActCoeffdT_Scaled_[k];
266  }
267 }
268 
269 void PhaseCombo_Interaction::getPartialMolarCp(doublereal* cpbar) const
270 {
271  /*
272  * Get the nondimensional standard state entropies
273  */
274  getCp_R(cpbar);
275  double T = temperature();
276  /*
277  * Update the activity coefficients, This also update the
278  * internally stored molalities.
279  */
282 
283  for (size_t k = 0; k < m_kk; k++) {
284  cpbar[k] -= 2 * T * dlnActCoeffdT_Scaled_[k] + T * T * d2lnActCoeffdT2_Scaled_[k];
285  }
286  /*
287  * dimensionalize it.
288  */
289  for (size_t k = 0; k < m_kk; k++) {
290  cpbar[k] *= GasConstant;
291  }
292 }
293 
295 {
296  /*
297  * Get the nondimensional standard state entropies
298  */
299  getEntropy_R(sbar);
300  double T = temperature();
301  /*
302  * Update the activity coefficients, This also update the
303  * internally stored molalities.
304  */
307 
308  for (size_t k = 0; k < m_kk; k++) {
309  double xx = std::max(moleFractions_[k], SmallNumber);
310  sbar[k] += - lnActCoeff_Scaled_[k] - log(xx) - T * dlnActCoeffdT_Scaled_[k];
311  }
312  /*
313  * dimensionalize it.
314  */
315  for (size_t k = 0; k < m_kk; k++) {
316  sbar[k] *= GasConstant;
317  }
318 }
319 
321 {
322  double T = temperature();
323 
324  /*
325  * Get the standard state values in m^3 kmol-1
326  */
327  getStandardVolumes(vbar);
328 
329  for (size_t iK = 0; iK < m_kk; iK++) {
330  int delAK = 0;
331  int delBK = 0;
332  for (size_t i = 0; i < numBinaryInteractions_; i++) {
333 
334  size_t iA = m_pSpecies_A_ij[i];
335  size_t iB = m_pSpecies_B_ij[i];
336 
337  if (iA==iK) {
338  delAK = 1;
339  } else if (iB==iK) {
340  delBK = 1;
341  }
342 
343  double XA = moleFractions_[iA];
344  double XB = moleFractions_[iB];
345 
346  double g0 = (m_VHE_b_ij[i] - T * m_VSE_b_ij[i]);
347  double g1 = (m_VHE_c_ij[i] - T * m_VSE_c_ij[i]);
348 
349  vbar[iK] += XA*XB*(g0+g1*XB)+((delAK-XA)*XB+XA*(delBK-XB))*(g0+g1*XB)+XA*XB*(delBK-XB)*g1;
350  }
351  }
352 }
353 
355 {
356  initLengths();
358 }
359 
361 {
363 }
364 
365 void PhaseCombo_Interaction::initThermoXML(XML_Node& phaseNode, const std::string& id)
366 {
367  if ((int) id.size() > 0 && phaseNode.id() != id) {
368  throw CanteraError("PhaseCombo_Interaction::initThermoXML",
369  "phasenode and Id are incompatible");
370  }
371 
372  /*
373  * Check on the thermo field. Must have:
374  * <thermo model="PhaseCombo_Interaction" />
375  */
376  if (!phaseNode.hasChild("thermo")) {
377  throw CanteraError("PhaseCombo_Interaction::initThermoXML",
378  "no thermo XML node");
379  }
380  XML_Node& thermoNode = phaseNode.child("thermo");
381  string formString = lowercase(thermoNode.attrib("model"));
382  if (formString != "phasecombo_interaction") {
383  throw CanteraError("PhaseCombo_Interaction::initThermoXML",
384  "model name isn't PhaseCombo_Interaction: " + formString);
385  }
386 
387  /*
388  * Go get all of the coefficients and factors in the
389  * activityCoefficients XML block
390  */
391  if (thermoNode.hasChild("activityCoefficients")) {
392  XML_Node& acNode = thermoNode.child("activityCoefficients");
393  string mString = acNode.attrib("model");
394  if (lowercase(mString) != "margules") {
395  throw CanteraError("PhaseCombo_Interaction::initThermoXML",
396  "Unknown activity coefficient model: " + mString);
397  }
398  for (size_t i = 0; i < acNode.nChildren(); i++) {
399  XML_Node& xmlACChild = acNode.child(i);
400  /*
401  * Process a binary salt field, or any of the other XML fields
402  * that make up the Pitzer Database. Entries will be ignored
403  * if any of the species in the entry isn't in the solution.
404  */
405  if (lowercase(xmlACChild.name()) == "binaryneutralspeciesparameters") {
406  readXMLBinarySpecies(xmlACChild);
407 
408  }
409  }
410  }
411 
412  /*
413  * Go down the chain
414  */
415  GibbsExcessVPSSTP::initThermoXML(phaseNode, id);
416 
417 
418 }
419 
421 {
422  doublereal T = temperature();
423  lnActCoeff_Scaled_.assign(m_kk, 0.0);
424 
425  for (size_t iK = 0; iK < m_kk; iK++) {
426  /*
427  * We never sample the end of the mole fraction domains
428  */
429  double xx = std::max(moleFractions_[iK], SmallNumber);
430  /*
431  * First wipe out the ideal solution mixing term
432  */
433  lnActCoeff_Scaled_[iK] = - log(xx);
434 
435  /*
436  * Then add in the Margules interaction terms. that's it!
437  */
438  for (size_t i = 0; i < numBinaryInteractions_; i++) {
439  size_t iA = m_pSpecies_A_ij[i];
440  size_t iB = m_pSpecies_B_ij[i];
441  int delAK = 0;
442  int delBK = 0;
443  if (iA==iK) {
444  delAK = 1;
445  } else if (iB==iK) {
446  delBK = 1;
447  }
448  double XA = moleFractions_[iA];
449  double XB = moleFractions_[iB];
450  double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / (GasConstant*T);
451  double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / (GasConstant*T);
452  lnActCoeff_Scaled_[iK] += (delAK * XB + XA * delBK - XA * XB) * (g0 + g1 * XB) + XA * XB * (delBK - XB) * g1;
453  }
454  }
455 }
456 
458 {
459  doublereal T = temperature();
460  dlnActCoeffdT_Scaled_.assign(m_kk, 0.0);
461  d2lnActCoeffdT2_Scaled_.assign(m_kk, 0.0);
462  for (size_t iK = 0; iK < m_kk; iK++) {
463  for (size_t i = 0; i < numBinaryInteractions_; i++) {
464  size_t iA = m_pSpecies_A_ij[i];
465  size_t iB = m_pSpecies_B_ij[i];
466  int delAK = 0;
467  int delBK = 0;
468  if (iA==iK) {
469  delAK = 1;
470  } else if (iB==iK) {
471  delBK = 1;
472  }
473  double XA = moleFractions_[iA];
474  double XB = moleFractions_[iB];
475  double g0 = -m_HE_b_ij[i] / (GasConstant*T*T);
476  double g1 = -m_HE_c_ij[i] / (GasConstant*T*T);
477  double temp = (delAK * XB + XA * delBK - XA * XB) * (g0 + g1 * XB) + XA * XB * (delBK - XB) * g1;
478  dlnActCoeffdT_Scaled_[iK] += temp;
479  d2lnActCoeffdT2_Scaled_[iK] -= 2.0 * temp / T;
480  }
481  }
482 }
483 
484 void PhaseCombo_Interaction::getdlnActCoeffdT(doublereal* dlnActCoeffdT) const
485 {
487  for (size_t k = 0; k < m_kk; k++) {
488  dlnActCoeffdT[k] = dlnActCoeffdT_Scaled_[k];
489  }
490 }
491 
492 void PhaseCombo_Interaction::getd2lnActCoeffdT2(doublereal* d2lnActCoeffdT2) const
493 {
495  for (size_t k = 0; k < m_kk; k++) {
496  d2lnActCoeffdT2[k] = d2lnActCoeffdT2_Scaled_[k];
497  }
498 }
499 
500 void PhaseCombo_Interaction::getdlnActCoeffds(const doublereal dTds, const doublereal* const dXds,
501  doublereal* dlnActCoeffds) const
502 {
503  doublereal T = temperature();
505 
506  for (size_t iK = 0; iK < m_kk; iK++) {
507  /*
508  * We never sample the end of the mole fraction domains
509  */
510  double xx = std::max(moleFractions_[iK], SmallNumber);
511  /*
512  * First wipe out the ideal solution mixing term
513  */
514  if (xx > SmallNumber) {
515  dlnActCoeffds[iK] += - 1.0 / xx;
516  }
517 
518  for (size_t i = 0; i < numBinaryInteractions_; i++) {
519  size_t iA = m_pSpecies_A_ij[i];
520  size_t iB = m_pSpecies_B_ij[i];
521 
522  int delAK = 0;
523  int delBK = 0;
524 
525  if (iA==iK) {
526  delAK = 1;
527  } else if (iB==iK) {
528  delBK = 1;
529  }
530 
531  double XA = moleFractions_[iA];
532  double XB = moleFractions_[iB];
533 
534  double dXA = dXds[iA];
535  double dXB = dXds[iB];
536 
537  double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / (GasConstant*T);
538  double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / (GasConstant*T);
539 
540  dlnActCoeffds[iK] += ((delBK-XB)*dXA + (delAK-XA)*dXB)*(g0+2*g1*XB) + (delBK-XB)*2*g1*XA*dXB
541  + dlnActCoeffdT_Scaled_[iK]*dTds;
542  }
543  }
544 }
545 
547 {
548  doublereal T = temperature();
549  dlnActCoeffdlnN_diag_.assign(m_kk, 0.0);
550 
551  for (size_t iK = 0; iK < m_kk; iK++) {
552 
553  double XK = moleFractions_[iK];
554  /*
555  * We never sample the end of the mole fraction domains
556  */
557  double xx = std::max(moleFractions_[iK], SmallNumber);
558  /*
559  * First wipe out the ideal solution mixing term
560  */
561  if (xx > SmallNumber) {
562  dlnActCoeffdlnN_diag_[iK] = - 1.0 + xx;
563  }
564 
565  for (size_t i = 0; i < numBinaryInteractions_; i++) {
566  size_t iA = m_pSpecies_A_ij[i];
567  size_t iB = m_pSpecies_B_ij[i];
568 
569  int delAK = 0;
570  int delBK = 0;
571 
572  if (iA==iK) {
573  delAK = 1;
574  } else if (iB==iK) {
575  delBK = 1;
576  }
577 
578  double XA = moleFractions_[iA];
579  double XB = moleFractions_[iB];
580 
581  double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / (GasConstant*T);
582  double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / (GasConstant*T);
583 
584  dlnActCoeffdlnN_diag_[iK] += 2*(delBK-XB)*(g0*(delAK-XA)+g1*(2*(delAK-XA)*XB+XA*(delBK-XB)));
585  }
587  }
588 
589 }
590 
592 {
593  double T = temperature();
595 
596  /*
597  * Loop over the activity coefficient gamma_k
598  */
599  for (size_t iK = 0; iK < m_kk; iK++) {
600  /*
601  * We never sample the end of the mole fraction domains
602  */
603  double xx = std::max(moleFractions_[iK], SmallNumber);
604 
605  for (size_t iM = 0; iM < m_kk; iM++) {
606  double XM = moleFractions_[iM];
607 
608  if (xx > SmallNumber) {
609  double delKM = 0.0;
610  if (iK == iM) {
611  delKM = 1.0;
612  }
613  // this gets multiplied by XM at the bottom
614  dlnActCoeffdlnN_(iK,iM) += - delKM/XM + 1.0;
615  }
616 
617  for (size_t i = 0; i < numBinaryInteractions_; i++) {
618  size_t iA = m_pSpecies_A_ij[i];
619  size_t iB = m_pSpecies_B_ij[i];
620 
621  double delAK = 0.0;
622  double delBK = 0.0;
623  double delAM = 0.0;
624  double delBM = 0.0;
625  if (iA==iK) {
626  delAK = 1.0;
627  } else if (iB==iK) {
628  delBK = 1.0;
629  }
630  if (iA==iM) {
631  delAM = 1.0;
632  } else if (iB==iM) {
633  delBM = 1.0;
634  }
635 
636  double XA = moleFractions_[iA];
637  double XB = moleFractions_[iB];
638 
639  double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / (GasConstant*T);
640  double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / (GasConstant*T);
641 
642  dlnActCoeffdlnN_(iK,iM) += g0*((delAM-XA)*(delBK-XB)+(delAK-XA)*(delBM-XB));
643  dlnActCoeffdlnN_(iK,iM) += 2*g1*((delAM-XA)*(delBK-XB)*XB+(delAK-XA)*(delBM-XB)*XB+(delBM-XB)*(delBK-XB)*XA);
644 
645  }
646  dlnActCoeffdlnN_(iK,iM) = XM * dlnActCoeffdlnN_(iK,iM);
647  }
648  }
649 }
650 
652 {
653  doublereal T = temperature();
654  dlnActCoeffdlnX_diag_.assign(m_kk, 0.0);
655  for (size_t i = 0; i < numBinaryInteractions_; i++) {
656  size_t iA = m_pSpecies_A_ij[i];
657  size_t iB = m_pSpecies_B_ij[i];
658 
659  double XA = moleFractions_[iA];
660  double XB = moleFractions_[iB];
661 
662  double g0 = (m_HE_b_ij[i] - T * m_SE_b_ij[i]) / (GasConstant * T);
663  double g1 = (m_HE_c_ij[i] - T * m_SE_c_ij[i]) / (GasConstant * T);
664 
665  dlnActCoeffdlnX_diag_[iA] += XA*XB*(2*g1*-2*g0-6*g1*XB);
666  dlnActCoeffdlnX_diag_[iB] += XA*XB*(2*g1*-2*g0-6*g1*XB);
667  }
668  throw CanteraError("PhaseCombo_Interaction::s_update_dlnActCoeff_dlnX_diag", "unimplemented");
669 }
670 
671 void PhaseCombo_Interaction::getdlnActCoeffdlnN_diag(doublereal* dlnActCoeffdlnN_diag) const
672 {
674  for (size_t k = 0; k < m_kk; k++) {
675  dlnActCoeffdlnN_diag[k] = dlnActCoeffdlnN_diag_[k];
676  }
677 }
678 
679 void PhaseCombo_Interaction::getdlnActCoeffdlnX_diag(doublereal* dlnActCoeffdlnX_diag) const
680 {
682  for (size_t k = 0; k < m_kk; k++) {
683  dlnActCoeffdlnX_diag[k] = dlnActCoeffdlnX_diag_[k];
684  }
685 }
686 
687 void PhaseCombo_Interaction::getdlnActCoeffdlnN(const size_t ld, doublereal* dlnActCoeffdlnN)
688 {
690  double* data = & dlnActCoeffdlnN_(0,0);
691  for (size_t k = 0; k < m_kk; k++) {
692  for (size_t m = 0; m < m_kk; m++) {
693  dlnActCoeffdlnN[ld * k + m] = data[m_kk * k + m];
694  }
695  }
696 }
697 
699 {
701  m_HE_b_ij.resize(num, 0.0);
702  m_HE_c_ij.resize(num, 0.0);
703  m_HE_d_ij.resize(num, 0.0);
704  m_SE_b_ij.resize(num, 0.0);
705  m_SE_c_ij.resize(num, 0.0);
706  m_SE_d_ij.resize(num, 0.0);
707  m_VHE_b_ij.resize(num, 0.0);
708  m_VHE_c_ij.resize(num, 0.0);
709  m_VHE_d_ij.resize(num, 0.0);
710  m_VSE_b_ij.resize(num, 0.0);
711  m_VSE_c_ij.resize(num, 0.0);
712  m_VSE_d_ij.resize(num, 0.0);
713 
714  m_pSpecies_A_ij.resize(num, npos);
715  m_pSpecies_B_ij.resize(num, npos);
716 }
717 
719 {
720  string xname = xmLBinarySpecies.name();
721  if (xname != "binaryNeutralSpeciesParameters") {
722  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies",
723  "Incorrect name for processing this routine: " + xname);
724  }
725  vector_fp vParams;
726  string iName = xmLBinarySpecies.attrib("speciesA");
727  if (iName == "") {
728  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies", "no speciesA attrib");
729  }
730  string jName = xmLBinarySpecies.attrib("speciesB");
731  if (jName == "") {
732  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies", "no speciesB attrib");
733  }
734  /*
735  * Find the index of the species in the current phase. It's not
736  * an error to not find the species
737  */
738  size_t iSpecies = speciesIndex(iName);
739  if (iSpecies == npos) {
740  return;
741  }
742  string ispName = speciesName(iSpecies);
743  if (charge(iSpecies) != 0) {
744  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies", "speciesA charge problem");
745  }
746  size_t jSpecies = speciesIndex(jName);
747  if (jSpecies == npos) {
748  return;
749  }
750  string jspName = speciesName(jSpecies);
751  if (charge(jSpecies) != 0) {
752  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies", "speciesB charge problem");
753  }
754 
756  size_t iSpot = numBinaryInteractions_ - 1;
757  m_pSpecies_A_ij[iSpot] = iSpecies;
758  m_pSpecies_B_ij[iSpot] = jSpecies;
759 
760  for (size_t iChild = 0; iChild < xmLBinarySpecies.nChildren(); iChild++) {
761  XML_Node& xmlChild = xmLBinarySpecies.child(iChild);
762  string nodeName = lowercase(xmlChild.name());
763  /*
764  * Process the binary species interaction child elements
765  */
766  if (nodeName == "excessenthalpy") {
767  /*
768  * Get the string containing all of the values
769  */
770  getFloatArray(xmlChild, vParams, true, "toSI", "excessEnthalpy");
771  if (vParams.size() != 2) {
772  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies::excessEnthalpy for " + ispName
773  + "::" + jspName,
774  "wrong number of params found");
775  }
776  m_HE_b_ij[iSpot] = vParams[0];
777  m_HE_c_ij[iSpot] = vParams[1];
778  }
779 
780  if (nodeName == "excessentropy") {
781  /*
782  * Get the string containing all of the values
783  */
784  getFloatArray(xmlChild, vParams, true, "toSI", "excessEntropy");
785  if (vParams.size() != 2) {
786  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies::excessEntropy for " + ispName
787  + "::" + jspName,
788  "wrong number of params found");
789  }
790  m_SE_b_ij[iSpot] = vParams[0];
791  m_SE_c_ij[iSpot] = vParams[1];
792  }
793 
794  if (nodeName == "excessvolume_enthalpy") {
795  /*
796  * Get the string containing all of the values
797  */
798  getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Enthalpy");
799  if (vParams.size() != 2) {
800  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies::excessVolume_Enthalpy for " + ispName
801  + "::" + jspName,
802  "wrong number of params found");
803  }
804  m_VHE_b_ij[iSpot] = vParams[0];
805  m_VHE_c_ij[iSpot] = vParams[1];
806  }
807 
808  if (nodeName == "excessvolume_entropy") {
809  /*
810  * Get the string containing all of the values
811  */
812  getFloatArray(xmlChild, vParams, true, "toSI", "excessVolume_Entropy");
813  if (vParams.size() != 2) {
814  throw CanteraError("PhaseCombo_Interaction::readXMLBinarySpecies::excessVolume_Entropy for " + ispName
815  + "::" + jspName,
816  "wrong number of params found");
817  }
818  m_VSE_b_ij[iSpot] = vParams[0];
819  m_VSE_c_ij[iSpot] = vParams[1];
820  }
821  }
822 }
823 
824 }
vector_fp m_VSE_b_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
PhaseCombo_Interaction & operator=(const PhaseCombo_Interaction &b)
Assignment operator.
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...
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar entropies for the species in the mixture.
int formTempModel_
form of the temperature dependence of the Margules interaction expression
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
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const
Get the array of temperature derivatives of the log activity coefficients.
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:527
vector_fp m_VHE_c_ij
Enthalpy term for the ternary mole fraction interaction of the excess Gibbs free energy expression...
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
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the log activity coefficients with respect to the ln species mole num...
Header for intermediate ThermoPhase object for phases which employ the Margules Gibbs free energy for...
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...
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
void initLengths()
Initialize lengths of local variables after all species have been identified.
void s_update_dlnActCoeff_dT() const
Update the derivative of the log of the activity coefficients wrt T.
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...
virtual doublereal cv_mole() const
Molar heat capacity at constant volume. Units: J/kmol/K.
virtual void getdlnActCoeffds(const doublereal dTds, const doublereal *const dXds, doublereal *dlnActCoeffds) const
Get the change in activity coefficients w.r.t.
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
doublereal size(size_t k) const
This routine returns the size of species k.
Definition: Phase.h:411
vector_fp m_HE_d_ij
Enthalpy term for the quaternary mole fraction interaction of the excess Gibbs free energy expression...
void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object.
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:78
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
int formMargules_
form of the Margules interaction expression
virtual void getdlnActCoeffdlnX_diag(doublereal *dlnActCoeffdlnX_diag) const
Get the array of log concentration-like derivatives of the log activity coefficients - diagonal compo...
std::string lowercase(const std::string &s)
Cast a copy of a string to lower case.
Definition: stringUtils.cpp:73
std::vector< doublereal > d2lnActCoeffdT2_Scaled_
Storage for the current derivative values of the gradients with respect to temperature of the log of ...
void resizeNumInteractions(const size_t num)
Resize internal arrays within the object that depend upon the number of binary Margules interaction t...
std::vector< doublereal > dlnActCoeffdlnN_diag_
Storage for the current derivative values of the gradients with respect to logarithm of the mole frac...
void s_update_dlnActCoeff_dlnN() const
Update the derivative of the log of the activity coefficients wrt log(moles_m)
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 ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
void readXMLBinarySpecies(XML_Node &xmlBinarySpecies)
Process an XML node called "binaryNeutralSpeciesParameters".
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.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
vector_fp m_VSE_d_ij
Entropy term for the quaternary mole fraction interaction of the excess Gibbs free energy expression...
void getElectrochemPotentials(doublereal *mu) const
Get the species electrochemical potentials.
vector_fp m_VHE_d_ij
Enthalpy term for the quaternary mole fraction interaction of the excess Gibbs free energy expression...
void s_update_dlnActCoeff_dlnX_diag() const
Update the derivative of the log of the activity coefficients wrt log(mole fraction) ...
std::string name() const
Returns the name of the XML node.
Definition: xml.h:394
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.
std::string id() const
Return the string id for the phase.
Definition: Phase.cpp:147
vector_fp m_HE_b_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
std::vector< size_t > m_pSpecies_B_ij
vector of species indices representing species B in the interaction
vector_fp m_VSE_c_ij
Entropy term for the ternary mole fraction interaction of the excess Gibbs free energy expression...
size_t numBinaryInteractions_
number of binary interaction expressions
vector_fp m_SE_c_ij
Entropy term for the ternary mole fraction interaction of the excess Gibbs free energy expression...
void s_update_lnActCoeff() const
Update the activity coefficients.
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:563
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
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 getdlnActCoeffdlnN_diag(doublereal *dlnActCoeffdlnN_diag) const
Get the array of derivatives of the log activity coefficients wrt mole numbers - diagonal only...
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.
PhaseCombo_Interaction is a derived class of GibbsExcessVPSSTP that employs the Margules approximatio...
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.
vector_fp m_SE_d_ij
Entropy term for the quaternary mole fraction interaction of the excess Gibbs free energy expression...
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol.
virtual int eosType() const
Equation of state type flag.
vector_fp m_SE_b_ij
Entropy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
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 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 getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity.
vector_fp m_HE_c_ij
Enthalpy term for the ternary mole fraction interaction of the excess Gibbs free energy expression...
vector_fp m_VHE_b_ij
Enthalpy term for the binary mole fraction interaction of the excess Gibbs free energy expression...
virtual void getd2lnActCoeffdT2(doublereal *d2lnActCoeffdT2) const
Get the array of temperature second derivatives of the log activity coefficients. ...
void s_update_dlnActCoeff_dlnN_diag() const
Update the derivative of the log of the activity coefficients wrt log(moles) - diagonal only...
std::string speciesName(size_t k) const
Name of the species with index k.
Definition: Phase.cpp:272
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 void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies for the species in the mixture.
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
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.