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