Cantera  2.5.1
DebyeHuckel.cpp
Go to the documentation of this file.
1 /**
2  * @file DebyeHuckel.cpp
3  * Declarations for the DebyeHuckel ThermoPhase object, which models dilute
4  * electrolyte solutions
5  * (see \ref thermoprops and \link Cantera::DebyeHuckel DebyeHuckel \endlink).
6  *
7  * Class DebyeHuckel represents a dilute liquid electrolyte phase which
8  * obeys the Debye Huckel formulation for nonideality.
9  */
10 
11 // This file is part of Cantera. See License.txt in the top-level directory or
12 // at https://cantera.org/license.txt for license and copyright information.
13 
20 #include "cantera/base/ctml.h"
21 
22 #include <cstdio>
23 
24 using namespace std;
25 
26 namespace Cantera
27 {
28 
29 DebyeHuckel::DebyeHuckel() :
30  m_formDH(DHFORM_DILUTE_LIMIT),
31  m_IionicMolality(0.0),
32  m_maxIionicStrength(30.0),
33  m_useHelgesonFixedForm(false),
34  m_IionicMolalityStoich(0.0),
35  m_form_A_Debye(A_DEBYE_CONST),
36  m_A_Debye(1.172576), // units = sqrt(kg/gmol)
37  m_B_Debye(3.28640E9), // units = sqrt(kg/gmol) / m
38  m_waterSS(0),
39  m_densWaterSS(1000.)
40 {
41 }
42 
43 DebyeHuckel::DebyeHuckel(const std::string& inputFile,
44  const std::string& id_) :
45  m_formDH(DHFORM_DILUTE_LIMIT),
46  m_IionicMolality(0.0),
47  m_maxIionicStrength(30.0),
48  m_useHelgesonFixedForm(false),
49  m_IionicMolalityStoich(0.0),
50  m_form_A_Debye(A_DEBYE_CONST),
51  m_A_Debye(1.172576), // units = sqrt(kg/gmol)
52  m_B_Debye(3.28640E9), // units = sqrt(kg/gmol) / m
53  m_waterSS(0),
54  m_densWaterSS(1000.)
55 {
56  initThermoFile(inputFile, id_);
57 }
58 
59 DebyeHuckel::DebyeHuckel(XML_Node& phaseRoot, const std::string& id_) :
60  m_formDH(DHFORM_DILUTE_LIMIT),
61  m_IionicMolality(0.0),
62  m_maxIionicStrength(3.0),
63  m_useHelgesonFixedForm(false),
64  m_IionicMolalityStoich(0.0),
65  m_form_A_Debye(A_DEBYE_CONST),
66  m_A_Debye(1.172576), // units = sqrt(kg/gmol)
67  m_B_Debye(3.28640E9), // units = sqrt(kg/gmol) / m
68  m_waterSS(0),
69  m_densWaterSS(1000.)
70 {
71  importPhase(phaseRoot, this);
72 }
73 
74 DebyeHuckel::~DebyeHuckel()
75 {
76 }
77 
78 // -------- Molar Thermodynamic Properties of the Solution ---------------
79 
80 doublereal DebyeHuckel::enthalpy_mole() const
81 {
83  return mean_X(m_tmpV);
84 }
85 
86 doublereal DebyeHuckel::entropy_mole() const
87 {
89  return mean_X(m_tmpV);
90 }
91 
92 doublereal DebyeHuckel::gibbs_mole() const
93 {
94  getChemPotentials(m_tmpV.data());
95  return mean_X(m_tmpV);
96 }
97 
98 doublereal DebyeHuckel::cp_mole() const
99 {
100  getPartialMolarCp(m_tmpV.data());
101  return mean_X(m_tmpV);
102 }
103 
104 // ------- Mechanical Equation of State Properties ------------------------
105 
107 {
108  if (m_waterSS) {
109  // Store the internal density of the water SS. Note, we would have to do
110  // this for all other species if they had pressure dependent properties.
112  }
114  double dd = meanMolecularWeight() / mean_X(m_tmpV);
116 }
117 
118 void DebyeHuckel::setDensity(doublereal rho)
119 {
120  warn_deprecated("DebyeHuckel::setDensity",
121  "Overloaded function to be removed after Cantera 2.5. "
122  "Error will be thrown by Phase::setDensity instead");
123  double dens = density();
124  if (rho != dens) {
125  throw CanteraError("DebyeHuckel::setDensity",
126  "Density is not an independent variable");
127  }
128 }
129 
130 void DebyeHuckel::setMolarDensity(const doublereal conc)
131 {
132  warn_deprecated("DebyeHuckel::setMolarDensity",
133  "Overloaded function to be removed after Cantera 2.5. "
134  "Error will be thrown by Phase::setMolarDensity instead");
135  double concI = molarDensity();
136  if (conc != concI) {
137  throw CanteraError("DebyeHuckel::setMolarDensity",
138  "molarDensity/density is not an independent variable");
139  }
140 }
141 
142 // ------- Activities and Activity Concentrations
143 
144 void DebyeHuckel::getActivityConcentrations(doublereal* c) const
145 {
146  double c_solvent = standardConcentration();
147  getActivities(c);
148  for (size_t k = 0; k < m_kk; k++) {
149  c[k] *= c_solvent;
150  }
151 }
152 
153 doublereal DebyeHuckel::standardConcentration(size_t k) const
154 {
155  double mvSolvent = providePDSS(0)->molarVolume();
156  return 1.0 / mvSolvent;
157 }
158 
159 void DebyeHuckel::getActivities(doublereal* ac) const
160 {
162 
163  // Update the molality array, m_molalities(). This requires an update due to
164  // mole fractions
166  for (size_t k = 1; k < m_kk; k++) {
167  ac[k] = m_molalities[k] * exp(m_lnActCoeffMolal[k]);
168  }
169  double xmolSolvent = moleFraction(0);
170  ac[0] = exp(m_lnActCoeffMolal[0]) * xmolSolvent;
171 }
172 
173 void DebyeHuckel::getMolalityActivityCoefficients(doublereal* acMolality) const
174 {
176  A_Debye_TP(-1.0, -1.0);
178  copy(m_lnActCoeffMolal.begin(), m_lnActCoeffMolal.end(), acMolality);
179  for (size_t k = 0; k < m_kk; k++) {
180  acMolality[k] = exp(acMolality[k]);
181  }
182 }
183 
184 // ------ Partial Molar Properties of the Solution -----------------
185 
186 void DebyeHuckel::getChemPotentials(doublereal* mu) const
187 {
188  double xx;
189 
190  // First get the standard chemical potentials in molar form. This requires
191  // updates of standard state as a function of T and P
193 
194  // Update the activity coefficients. This also updates the internal molality
195  // array.
197  double xmolSolvent = moleFraction(0);
198  for (size_t k = 1; k < m_kk; k++) {
199  xx = std::max(m_molalities[k], SmallNumber);
200  mu[k] += RT() * (log(xx) + m_lnActCoeffMolal[k]);
201  }
202  xx = std::max(xmolSolvent, SmallNumber);
203  mu[0] += RT() * (log(xx) + m_lnActCoeffMolal[0]);
204 }
205 
206 void DebyeHuckel::getPartialMolarEnthalpies(doublereal* hbar) const
207 {
208  // Get the nondimensional standard state enthalpies
209  getEnthalpy_RT(hbar);
210 
211  // Dimensionalize it.
212  for (size_t k = 0; k < m_kk; k++) {
213  hbar[k] *= RT();
214  }
215 
216  // Check to see whether activity coefficients are temperature
217  // dependent. If they are, then calculate the their temperature
218  // derivatives and add them into the result.
219  double dAdT = dA_DebyedT_TP();
220  if (dAdT != 0.0) {
221  // Update the activity coefficients, This also update the
222  // internally stored molalities.
225  for (size_t k = 0; k < m_kk; k++) {
226  hbar[k] -= RT() * temperature() * m_dlnActCoeffMolaldT[k];
227  }
228  }
229 }
230 
231 void DebyeHuckel::getPartialMolarEntropies(doublereal* sbar) const
232 {
233  // Get the standard state entropies at the temperature and pressure of the
234  // solution.
235  getEntropy_R(sbar);
236 
237  // Dimensionalize the entropies
238  for (size_t k = 0; k < m_kk; k++) {
239  sbar[k] *= GasConstant;
240  }
241 
242  // Update the activity coefficients, This also update the internally stored
243  // molalities.
245 
246  // First we will add in the obvious dependence on the T term out front of
247  // the log activity term
248  doublereal mm;
249  for (size_t k = 1; k < m_kk; k++) {
250  mm = std::max(SmallNumber, m_molalities[k]);
251  sbar[k] -= GasConstant * (log(mm) + m_lnActCoeffMolal[k]);
252  }
253  double xmolSolvent = moleFraction(0);
254  mm = std::max(SmallNumber, xmolSolvent);
255  sbar[0] -= GasConstant *(log(mm) + m_lnActCoeffMolal[0]);
256 
257  // Check to see whether activity coefficients are temperature dependent. If
258  // they are, then calculate the their temperature derivatives and add them
259  // into the result.
260  double dAdT = dA_DebyedT_TP();
261  if (dAdT != 0.0) {
263  for (size_t k = 0; k < m_kk; k++) {
264  sbar[k] -= RT() * m_dlnActCoeffMolaldT[k];
265  }
266  }
267 }
268 
269 void DebyeHuckel::getPartialMolarVolumes(doublereal* vbar) const
270 {
271  getStandardVolumes(vbar);
272 
273  // Update the derivatives wrt the activity coefficients.
276  for (size_t k = 0; k < m_kk; k++) {
277  vbar[k] += RT() * m_dlnActCoeffMolaldP[k];
278  }
279 }
280 
281 void DebyeHuckel::getPartialMolarCp(doublereal* cpbar) const
282 {
283  getCp_R(cpbar);
284  for (size_t k = 0; k < m_kk; k++) {
285  cpbar[k] *= GasConstant;
286  }
287 
288  // Check to see whether activity coefficients are temperature dependent. If
289  // they are, then calculate the their temperature derivatives and add them
290  // into the result.
291  double dAdT = dA_DebyedT_TP();
292  if (dAdT != 0.0) {
293  // Update the activity coefficients, This also update the internally
294  // stored molalities.
298  for (size_t k = 0; k < m_kk; k++) {
299  cpbar[k] -= (2.0 * RT() * m_dlnActCoeffMolaldT[k] +
301  }
302  }
303 }
304 
305 // -------------- Utilities -------------------------------
306 
307 //! Utility function to assign an integer value from a string for the
308 //! ElectrolyteSpeciesType field.
309 /*!
310  * @param estString input string that will be interpreted
311  */
312 static int interp_est(const std::string& estString)
313 {
314  if (caseInsensitiveEquals(estString, "solvent")) {
315  return cEST_solvent;
316  } else if (estString == "charged-species"
317  || caseInsensitiveEquals(estString, "chargedspecies")) {
318  return cEST_chargedSpecies;
319  } else if (estString == "weak-acid-associated"
320  || caseInsensitiveEquals(estString, "weakacidassociated")) {
321  return cEST_weakAcidAssociated;
322  } else if (estString == "strong-acid-associated"
323  || caseInsensitiveEquals(estString, "strongacidassociated")) {
324  return cEST_strongAcidAssociated;
325  } else if (estString == "polar-neutral"
326  || caseInsensitiveEquals(estString, "polarneutral")) {
327  return cEST_polarNeutral;
328  } else if (estString == "nonpolar-neutral"
329  || caseInsensitiveEquals(estString, "nonpolarneutral")) {
330  return cEST_nonpolarNeutral;
331  } else {
332  throw CanteraError("interp_est (DebyeHuckel)",
333  "Invalid electrolyte species type '{}'", estString);
334  }
335 }
336 
337 void DebyeHuckel::setDebyeHuckelModel(const std::string& model) {
338  if (model == ""
339  || model == "dilute-limit"
340  || caseInsensitiveEquals(model, "Dilute_limit")) {
341  m_formDH = DHFORM_DILUTE_LIMIT;
342  } else if (model == "B-dot-with-variable-a"
343  || caseInsensitiveEquals(model, "Bdot_with_variable_a")) {
344  m_formDH = DHFORM_BDOT_AK;
345  } else if (model == "B-dot-with-common-a"
346  || caseInsensitiveEquals(model, "Bdot_with_common_a")) {
347  m_formDH = DHFORM_BDOT_ACOMMON;
348  } else if (caseInsensitiveEquals(model, "beta_ij")) {
349  m_formDH = DHFORM_BETAIJ;
350  m_Beta_ij.resize(m_kk, m_kk, 0.0);
351  } else if (model == "Pitzer-with-beta_ij"
352  || caseInsensitiveEquals(model, "Pitzer_with_Beta_ij")) {
353  m_formDH = DHFORM_PITZER_BETAIJ;
354  m_Beta_ij.resize(m_kk, m_kk, 0.0);
355  } else {
356  throw CanteraError("DebyeHuckel::setDebyeHuckelModel",
357  "Unknown model '{}'", model);
358  }
359 }
360 
362 {
363  if (A < 0) {
364  m_form_A_Debye = A_DEBYE_WATER;
365  } else {
366  m_form_A_Debye = A_DEBYE_CONST;
367  m_A_Debye = A;
368  }
369 }
370 
371 void DebyeHuckel::setB_dot(double bdot)
372 {
373  if (m_formDH == DHFORM_BETAIJ || m_formDH == DHFORM_DILUTE_LIMIT ||
374  m_formDH == DHFORM_PITZER_BETAIJ) {
375  throw CanteraError("DebyeHuckel::setB_dot",
376  "B_dot entry in the wrong DH form");
377  }
378  // Set B_dot parameters for charged species
379  for (size_t k = 0; k < nSpecies(); k++) {
380  if (fabs(charge(k)) > 0.0001) {
381  m_B_Dot[k] = bdot;
382  } else {
383  m_B_Dot[k] = 0.0;
384  }
385  }
386 }
387 
389 {
390  for (size_t k = 0; k < m_kk; k++) {
391  if (std::isnan(m_Aionic[k])) {
392  m_Aionic[k] = value;
393  }
394  }
395 }
396 
397 void DebyeHuckel::setBeta(const std::string& sp1, const std::string& sp2,
398  double value)
399 {
400  size_t k1 = speciesIndex(sp1);
401  if (k1 == npos) {
402  throw CanteraError("DebyeHuckel::setBeta", "Species '{}' not found", sp1);
403  }
404  size_t k2 = speciesIndex(sp2);
405  if (k2 == npos) {
406  throw CanteraError("DebyeHuckel::setBeta", "Species '{}' not found", sp2);
407  }
408  m_Beta_ij(k1, k2) = value;
409  m_Beta_ij(k2, k1) = value;
410 }
411 
412 void DebyeHuckel::initThermoXML(XML_Node& phaseNode, const std::string& id_)
413 {
414  if (id_.size() > 0) {
415  std::string idp = phaseNode.id();
416  if (idp != id_) {
417  throw CanteraError("DebyeHuckel::initThermoXML",
418  "phasenode and Id are incompatible");
419  }
420  }
421 
422  // Find the Thermo XML node
423  if (!phaseNode.hasChild("thermo")) {
424  throw CanteraError("DebyeHuckel::initThermoXML",
425  "no thermo XML node");
426  }
427  XML_Node& thermoNode = phaseNode.child("thermo");
428 
429  // Determine the form of the Debye-Huckel model, m_formDH. We will use
430  // this information to size arrays below. If there is no XML node named
431  // "activityCoefficients", assume that we are doing the extreme dilute
432  // limit assumption
433  if (thermoNode.hasChild("activityCoefficients")) {
434  setDebyeHuckelModel(thermoNode.child("activityCoefficients")["model"]);
435  } else {
436  setDebyeHuckelModel("Dilute_limit");
437  }
438 
439  // Go get all of the coefficients and factors in the activityCoefficients
440  // XML block
441  XML_Node* acNodePtr = 0;
442  if (thermoNode.hasChild("activityCoefficients")) {
443  XML_Node& acNode = thermoNode.child("activityCoefficients");
444  acNodePtr = &acNode;
445 
446  // Look for parameters for A_Debye
447  if (acNode.hasChild("A_Debye")) {
448  XML_Node* ss = acNode.findByName("A_Debye");
449  string modelString = ss->attrib("model");
450  if (modelString != "") {
451  if (caseInsensitiveEquals(modelString, "water")) {
452  setA_Debye(-1);
453  } else {
454  throw CanteraError("DebyeHuckel::initThermoXML",
455  "A_Debye Model \"" + modelString +
456  "\" is not known");
457  }
458  } else {
459  setA_Debye(getFloat(acNode, "A_Debye"));
460  }
461  }
462 
463  // Look for parameters for B_Debye
464  if (acNode.hasChild("B_Debye")) {
465  setB_Debye(getFloat(acNode, "B_Debye"));
466  }
467 
468  // Look for parameters for B_dot
469  if (acNode.hasChild("B_dot")) {
470  setB_dot(getFloat(acNode, "B_dot"));
471  }
472 
473  // Look for Parameters for the Maximum Ionic Strength
474  if (acNode.hasChild("maxIonicStrength")) {
475  setMaxIonicStrength(getFloat(acNode, "maxIonicStrength"));
476  }
477 
478  // Look for Helgeson Parameters
479  useHelgesonFixedForm(acNode.hasChild("UseHelgesonFixedForm"));
480 
481  // Look for parameters for the Ionic radius
482  if (acNode.hasChild("ionicRadius")) {
483  XML_Node& irNode = acNode.child("ionicRadius");
484 
485  double Afactor = 1.0;
486  if (irNode.hasAttrib("units")) {
487  std::string Aunits = irNode.attrib("units");
488  Afactor = toSI(Aunits);
489  }
490 
491  if (irNode.hasAttrib("default")) {
492  setDefaultIonicRadius(Afactor * fpValue(irNode.attrib("default")));
493  }
494 
495  // If the Debye-Huckel form is BDOT_AK, we can have separate values
496  // for the denominator's ionic size. -> That's how the activity
497  // coefficient is parameterized. In this case only do we allow the
498  // code to read in these parameters.
499  if (m_formDH == DHFORM_BDOT_AK) {
500  // Define a string-string map, and interpret the value of the
501  // XML element as binary pairs separated by colons, e.g.:
502  // Na+:3.0
503  // Cl-:4.0
504  // H+:9.0
505  // OH-:3.5
506  // Read them into the map.
507  map<string, string> m;
508  getMap(irNode, m);
509 
510  // Iterate over the map pairs, interpreting the first string as
511  // a species in the current phase. If no match is made, silently
512  // ignore the lack of agreement (HKM -> may be changed in the
513  // future).
514  for (const auto& b : m) {
515  size_t k = speciesIndex(b.first);
516  if (k != npos) {
517  m_Aionic[k] = fpValue(b.second) * Afactor;
518  }
519  }
520  }
521  }
522 
523  // Get the matrix of coefficients for the Beta binary interaction
524  // parameters. We assume here that this matrix is symmetric, so that we
525  // only have to input 1/2 of the values.
526  if (acNode.hasChild("DHBetaMatrix")) {
527  if (m_formDH == DHFORM_BETAIJ ||
528  m_formDH == DHFORM_PITZER_BETAIJ) {
529  XML_Node& irNode = acNode.child("DHBetaMatrix");
530  const vector<string>& sn = speciesNames();
531  getMatrixValues(irNode, sn, sn, m_Beta_ij, true, true);
532  } else {
533  throw CanteraError("DebyeHuckel::initThermoXML:",
534  "DHBetaMatrix found for wrong type");
535  }
536  }
537 
538  // Override stoichiometric Ionic Strength based on the phase definition
539  if (acNodePtr && acNodePtr->hasChild("stoichIsMods")) {
540  XML_Node& sIsNode = acNodePtr->child("stoichIsMods");
541  map<std::string, std::string> msIs;
542  getMap(sIsNode, msIs);
543  for (const auto& b : msIs) {
544  size_t kk = speciesIndex(b.first);
545  double val = fpValue(b.second);
546  m_speciesCharge_Stoich[kk] = val;
547  }
548  }
549  }
550 
551  // Override electrolyte species type based on the phase definition
552  if (acNodePtr && acNodePtr->hasChild("electrolyteSpeciesType")) {
553  XML_Node& ESTNode = acNodePtr->child("electrolyteSpeciesType");
554  map<std::string, std::string> msEST;
555  getMap(ESTNode, msEST);
556  for (const auto& b : msEST) {
557  size_t kk = speciesIndex(b.first);
558  std::string est = b.second;
559  if ((m_electrolyteSpeciesType[kk] = interp_est(est)) == -1) {
560  throw CanteraError("DebyeHuckel:initThermoXML",
561  "Bad electrolyte type: " + est);
562  }
563  }
564  }
565 
566  // Lastly set the state
567  if (phaseNode.hasChild("state")) {
568  XML_Node& stateNode = phaseNode.child("state");
569  setStateFromXML(stateNode);
570  }
571 }
572 
574 {
576  if (m_input.hasKey("activity-data")) {
577  auto& node = m_input["activity-data"].as<AnyMap>();
578  setDebyeHuckelModel(node["model"].asString());
579  if (node.hasKey("A_Debye")) {
580  if (node["A_Debye"] == "variable") {
581  setA_Debye(-1);
582  } else {
583  setA_Debye(node.convert("A_Debye", "kg^0.5/gmol^0.5"));
584  }
585  }
586  if (node.hasKey("B_Debye")) {
587  setB_Debye(node.convert("B_Debye", "kg^0.5/gmol^0.5/m"));
588  }
589  if (node.hasKey("max-ionic-strength")) {
590  setMaxIonicStrength(node["max-ionic-strength"].asDouble());
591  }
592  if (node.hasKey("use-Helgeson-fixed-form")) {
593  useHelgesonFixedForm(node["use-Helgeson-fixed-form"].asBool());
594  }
595  if (node.hasKey("default-ionic-radius")) {
596  setDefaultIonicRadius(node.convert("default-ionic-radius", "m"));
597  }
598  if (node.hasKey("B-dot")) {
599  setB_dot(node["B-dot"].asDouble());
600  }
601  if (node.hasKey("beta")) {
602  for (auto& item : node["beta"].asVector<AnyMap>()) {
603  auto& species = item["species"].asVector<string>(2);
604  setBeta(species[0], species[1], item["beta"].asDouble());
605  }
606  }
607  }
608 
609  // Solvent
610  m_waterSS = dynamic_cast<PDSS_Water*>(providePDSS(0));
611  if (m_waterSS) {
612  // Initialize the water property calculator. It will share the internal
613  // eos water calculator.
614  if (m_form_A_Debye == A_DEBYE_WATER) {
615  m_waterProps.reset(new WaterProps(m_waterSS));
616  }
617  } else if (dynamic_cast<PDSS_ConstVol*>(providePDSS(0)) == 0) {
618  throw CanteraError("DebyeHuckel::initThermo", "Solvent standard state"
619  " model must be WaterIAPWS or constant_incompressible.");
620  }
621 
622  // Solutes
623  for (size_t k = 1; k < nSpecies(); k++) {
624  if (dynamic_cast<PDSS_ConstVol*>(providePDSS(k)) == 0) {
625  throw CanteraError("DebyeHuckel::initThermo", "Solute standard"
626  " state model must be constant_incompressible.");
627  }
628  }
629 }
630 
631 double DebyeHuckel::A_Debye_TP(double tempArg, double presArg) const
632 {
633  double T = temperature();
634  double A;
635  if (tempArg != -1.0) {
636  T = tempArg;
637  }
638  double P = pressure();
639  if (presArg != -1.0) {
640  P = presArg;
641  }
642 
643  switch (m_form_A_Debye) {
644  case A_DEBYE_CONST:
645  A = m_A_Debye;
646  break;
647  case A_DEBYE_WATER:
648  A = m_waterProps->ADebye(T, P, 0);
649  m_A_Debye = A;
650  break;
651  default:
652  throw CanteraError("DebyeHuckel::A_Debye_TP", "shouldn't be here");
653  }
654  return A;
655 }
656 
657 double DebyeHuckel::dA_DebyedT_TP(double tempArg, double presArg) const
658 {
659  double T = temperature();
660  if (tempArg != -1.0) {
661  T = tempArg;
662  }
663  double P = pressure();
664  if (presArg != -1.0) {
665  P = presArg;
666  }
667  double dAdT;
668  switch (m_form_A_Debye) {
669  case A_DEBYE_CONST:
670  dAdT = 0.0;
671  break;
672  case A_DEBYE_WATER:
673  dAdT = m_waterProps->ADebye(T, P, 1);
674  break;
675  default:
676  throw CanteraError("DebyeHuckel::dA_DebyedT_TP", "shouldn't be here");
677  }
678  return dAdT;
679 }
680 
681 double DebyeHuckel::d2A_DebyedT2_TP(double tempArg, double presArg) const
682 {
683  double T = temperature();
684  if (tempArg != -1.0) {
685  T = tempArg;
686  }
687  double P = pressure();
688  if (presArg != -1.0) {
689  P = presArg;
690  }
691  double d2AdT2;
692  switch (m_form_A_Debye) {
693  case A_DEBYE_CONST:
694  d2AdT2 = 0.0;
695  break;
696  case A_DEBYE_WATER:
697  d2AdT2 = m_waterProps->ADebye(T, P, 2);
698  break;
699  default:
700  throw CanteraError("DebyeHuckel::d2A_DebyedT2_TP", "shouldn't be here");
701  }
702  return d2AdT2;
703 }
704 
705 double DebyeHuckel::dA_DebyedP_TP(double tempArg, double presArg) const
706 {
707  double T = temperature();
708  if (tempArg != -1.0) {
709  T = tempArg;
710  }
711  double P = pressure();
712  if (presArg != -1.0) {
713  P = presArg;
714  }
715  double dAdP;
716  switch (m_form_A_Debye) {
717  case A_DEBYE_CONST:
718  dAdP = 0.0;
719  break;
720  case A_DEBYE_WATER:
721  dAdP = m_waterProps->ADebye(T, P, 3);
722  break;
723  default:
724  throw CanteraError("DebyeHuckel::dA_DebyedP_TP", "shouldn't be here");
725  }
726  return dAdP;
727 }
728 
729 // ---------- Other Property Functions
730 
731 double DebyeHuckel::AionicRadius(int k) const
732 {
733  return m_Aionic[k];
734 }
735 
736 // ------------ Private and Restricted Functions ------------------
737 
738 bool DebyeHuckel::addSpecies(shared_ptr<Species> spec)
739 {
740  bool added = MolalityVPSSTP::addSpecies(spec);
741  if (added) {
742  m_lnActCoeffMolal.push_back(0.0);
743  m_dlnActCoeffMolaldT.push_back(0.0);
744  m_d2lnActCoeffMolaldT2.push_back(0.0);
745  m_dlnActCoeffMolaldP.push_back(0.0);
746  m_B_Dot.push_back(0.0);
747  m_tmpV.push_back(0.0);
748 
749  // NAN will be replaced with default value
750  double Aionic = NAN;
751 
752  // Guess electrolyte species type based on charge properties
753  int est = cEST_nonpolarNeutral;
754  double stoichCharge = spec->charge;
755  if (fabs(spec->charge) > 0.0001) {
756  est = cEST_chargedSpecies;
757  }
758 
759  if (spec->input.hasKey("Debye-Huckel")) {
760  auto& dhNode = spec->input["Debye-Huckel"].as<AnyMap>();
761  Aionic = dhNode.convert("ionic-radius", "m", NAN);
762  if (dhNode.hasKey("weak-acid-charge")) {
763  stoichCharge = dhNode["weak-acid-charge"].asDouble();
764  if (fabs(stoichCharge - spec->charge) > 0.0001) {
765  est = cEST_weakAcidAssociated;
766  }
767  }
768  // Apply override of the electrolyte species type
769  if (dhNode.hasKey("electrolyte-species-type")) {
770  est = interp_est(dhNode["electrolyte-species-type"].asString());
771  }
772  }
773 
774  if (m_electrolyteSpeciesType.size() == 0) {
775  est = cEST_solvent; // species 0 is the solvent
776  }
777 
778  m_Aionic.push_back(Aionic);
779  m_speciesCharge_Stoich.push_back(stoichCharge);
780  m_electrolyteSpeciesType.push_back(est);
781  }
782  return added;
783 }
784 
785 double DebyeHuckel::_nonpolarActCoeff(double IionicMolality)
786 {
787  // These are coefficients to describe the increase in activity coeff for
788  // non-polar molecules due to the electrolyte becoming stronger (the so-
789  // called salt-out effect)
790  const static double npActCoeff[] = {0.1127, -0.01049, 1.545E-3};
791  double I2 = IionicMolality * IionicMolality;
792  double l10actCoeff =
793  npActCoeff[0] * IionicMolality +
794  npActCoeff[1] * I2 +
795  npActCoeff[2] * I2 * IionicMolality;
796  return pow(10.0 , l10actCoeff);
797 }
798 
800 {
801  const double a0 = 1.454;
802  const double b0 = 0.02236;
803  const double c0 = 9.380E-3;
804  const double d0 = -5.362E-4;
805  double Is = m_IionicMolalityStoich;
806  if (Is <= 0.0) {
807  return 0.0;
808  }
809  double Is2 = Is * Is;
810  double bhat = 1.0 + a0 * sqrt(Is);
811  double func = bhat - 2.0 * log(bhat) - 1.0/bhat;
812  double v1 = m_A_Debye / (a0 * a0 * a0 * Is) * func;
813  double oc = 1.0 - v1 + b0 * Is / 2.0 + 2.0 * c0 * Is2 / 3.0
814  + 3.0 * d0 * Is2 * Is / 4.0;
815  return oc;
816 }
817 
819 {
820  // Update the internally stored vector of molalities
821  calcMolalities();
822  double oc = _osmoticCoeffHelgesonFixedForm();
823  double sum = 0.0;
824  for (size_t k = 1; k < m_kk; k++) {
825  sum += std::max(m_molalities[k], 0.0);
826  }
827  if (sum > 2.0 * m_maxIionicStrength) {
828  sum = 2.0 * m_maxIionicStrength;
829  };
830  return - m_Mnaught * sum * oc;
831 }
832 
834 {
835  double z_k, zs_k1, zs_k2;
836 
837  // Update the internally stored vector of molalities
838  calcMolalities();
839 
840  // Calculate the apparent (real) ionic strength.
841  //
842  // Note this is not the stoichiometric ionic strengh, where reactions of
843  // ions forming neutral salts are ignorred in calculating the ionic
844  // strength.
845  m_IionicMolality = 0.0;
846  for (size_t k = 0; k < m_kk; k++) {
847  z_k = m_speciesCharge[k];
848  m_IionicMolality += m_molalities[k] * z_k * z_k;
849  }
850  m_IionicMolality /= 2.0;
852 
853  // Calculate the stoichiometric ionic charge
855  for (size_t k = 0; k < m_kk; k++) {
856  z_k = m_speciesCharge[k];
857  zs_k1 = m_speciesCharge_Stoich[k];
858  if (z_k == zs_k1) {
859  m_IionicMolalityStoich += m_molalities[k] * z_k * z_k;
860  } else {
861  zs_k2 = z_k - zs_k1;
862  m_IionicMolalityStoich += m_molalities[k] * (zs_k1 * zs_k1 + zs_k2 * zs_k2);
863  }
864  }
865  m_IionicMolalityStoich /= 2.0;
867 
868  // Possibly update the stored value of the Debye-Huckel parameter A_Debye
869  // This parameter appears on the top of the activity coefficient expression.
870  // It depends on T (and P), as it depends explicitly on the temperature.
871  // Also, the dielectric constant is usually a fairly strong function of T,
872  // also.
873  m_A_Debye = A_Debye_TP();
874 
875  // Calculate a safe value for the mole fraction of the solvent
876  double xmolSolvent = moleFraction(0);
877  xmolSolvent = std::max(8.689E-3, xmolSolvent);
878 
879  int est;
880  double ac_nonPolar = 1.0;
881  double numTmp = m_A_Debye * sqrt(m_IionicMolality);
882  double denomTmp = m_B_Debye * sqrt(m_IionicMolality);
883  double coeff;
884  double lnActivitySolvent = 0.0;
885  double tmp;
886  double tmpLn;
887  double y, yp1, sigma;
888  switch (m_formDH) {
889  case DHFORM_DILUTE_LIMIT:
890  for (size_t k = 0; k < m_kk; k++) {
891  z_k = m_speciesCharge[k];
892  m_lnActCoeffMolal[k] = - z_k * z_k * numTmp;
893  }
894  lnActivitySolvent =
895  (xmolSolvent - 1.0)/xmolSolvent +
896  2.0 / 3.0 * m_A_Debye * m_Mnaught *
898  break;
899 
900  case DHFORM_BDOT_AK:
901  ac_nonPolar = _nonpolarActCoeff(m_IionicMolality);
902  for (size_t k = 0; k < m_kk; k++) {
903  est = m_electrolyteSpeciesType[k];
904  if (est == cEST_nonpolarNeutral) {
905  m_lnActCoeffMolal[k] = log(ac_nonPolar);
906  } else {
907  z_k = m_speciesCharge[k];
908  m_lnActCoeffMolal[k] =
909  - z_k * z_k * numTmp / (1.0 + denomTmp * m_Aionic[k])
910  + log(10.0) * m_B_Dot[k] * m_IionicMolality;
911  }
912  }
913 
914  lnActivitySolvent = (xmolSolvent - 1.0)/xmolSolvent;
915  coeff = 2.0 / 3.0 * m_A_Debye * m_Mnaught
916  * sqrt(m_IionicMolality);
917  tmp = 0.0;
918  if (denomTmp > 0.0) {
919  for (size_t k = 0; k < m_kk; k++) {
920  if (k != 0 || m_Aionic[k] != 0.0) {
921  y = denomTmp * m_Aionic[k];
922  yp1 = y + 1.0;
923  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
924  z_k = m_speciesCharge[k];
925  tmp += m_molalities[k] * z_k * z_k * sigma / 2.0;
926  }
927  }
928  }
929  lnActivitySolvent += coeff * tmp;
930  tmp = 0.0;
931  for (size_t k = 1; k < m_kk; k++) {
932  z_k = m_speciesCharge[k];
933  if (z_k != 0.0) {
934  tmp += m_B_Dot[k] * m_molalities[k];
935  }
936  }
937  lnActivitySolvent -=
938  m_Mnaught * log(10.0) * m_IionicMolality * tmp / 2.0;
939 
940  // Special section to implement the Helgeson fixed form for the water
941  // brine activity coefficient.
943  lnActivitySolvent = _lnactivityWaterHelgesonFixedForm();
944  }
945  break;
946 
947  case DHFORM_BDOT_ACOMMON:
948  denomTmp *= m_Aionic[0];
949  for (size_t k = 0; k < m_kk; k++) {
950  z_k = m_speciesCharge[k];
951  m_lnActCoeffMolal[k] =
952  - z_k * z_k * numTmp / (1.0 + denomTmp)
953  + log(10.0) * m_B_Dot[k] * m_IionicMolality;
954  }
955  if (denomTmp > 0.0) {
956  y = denomTmp;
957  yp1 = y + 1.0;
958  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
959  } else {
960  sigma = 0.0;
961  }
962  lnActivitySolvent =
963  (xmolSolvent - 1.0)/xmolSolvent +
964  2.0 /3.0 * m_A_Debye * m_Mnaught *
965  m_IionicMolality * sqrt(m_IionicMolality) * sigma;
966  tmp = 0.0;
967  for (size_t k = 1; k < m_kk; k++) {
968  z_k = m_speciesCharge[k];
969  if (z_k != 0.0) {
970  tmp += m_B_Dot[k] * m_molalities[k];
971  }
972  }
973  lnActivitySolvent -=
974  m_Mnaught * log(10.0) * m_IionicMolality * tmp / 2.0;
975  break;
976 
977  case DHFORM_BETAIJ:
978  denomTmp = m_B_Debye * m_Aionic[0];
979  denomTmp *= sqrt(m_IionicMolality);
980  lnActivitySolvent =
981  (xmolSolvent - 1.0)/xmolSolvent;
982 
983  for (size_t k = 1; k < m_kk; k++) {
984  z_k = m_speciesCharge[k];
985  m_lnActCoeffMolal[k] =
986  - z_k * z_k * numTmp / (1.0 + denomTmp);
987  for (size_t j = 0; j < m_kk; j++) {
988  double beta = m_Beta_ij.value(k, j);
989  m_lnActCoeffMolal[k] += 2.0 * m_molalities[j] * beta;
990  }
991  }
992  if (denomTmp > 0.0) {
993  y = denomTmp;
994  yp1 = y + 1.0;
995  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 -2.0*log(yp1));
996  } else {
997  sigma = 0.0;
998  }
999  lnActivitySolvent =
1000  (xmolSolvent - 1.0)/xmolSolvent +
1001  2.0 /3.0 * m_A_Debye * m_Mnaught *
1002  m_IionicMolality * sqrt(m_IionicMolality) * sigma;
1003  tmp = 0.0;
1004  for (size_t k = 0; k < m_kk; k++) {
1005  for (size_t j = 0; j < m_kk; j++) {
1006  tmp +=
1007  m_Beta_ij.value(k, j) * m_molalities[k] * m_molalities[j];
1008  }
1009  }
1010  lnActivitySolvent -= m_Mnaught * tmp;
1011  break;
1012 
1013  case DHFORM_PITZER_BETAIJ:
1014  denomTmp = m_B_Debye * sqrt(m_IionicMolality);
1015  denomTmp *= m_Aionic[0];
1016  numTmp = m_A_Debye * sqrt(m_IionicMolality);
1017  tmpLn = log(1.0 + denomTmp);
1018  for (size_t k = 1; k < m_kk; k++) {
1019  z_k = m_speciesCharge[k];
1020  m_lnActCoeffMolal[k] =
1021  - z_k * z_k * numTmp / 3.0 / (1.0 + denomTmp);
1022  m_lnActCoeffMolal[k] +=
1023  - 2.0 * z_k * z_k * m_A_Debye * tmpLn /
1024  (3.0 * m_B_Debye * m_Aionic[0]);
1025  for (size_t j = 0; j < m_kk; j++) {
1026  m_lnActCoeffMolal[k] += 2.0 * m_molalities[j] *
1027  m_Beta_ij.value(k, j);
1028  }
1029  }
1030  sigma = 1.0 / (1.0 + denomTmp);
1031  lnActivitySolvent =
1032  (xmolSolvent - 1.0)/xmolSolvent +
1033  2.0 /3.0 * m_A_Debye * m_Mnaught *
1034  m_IionicMolality * sqrt(m_IionicMolality) * sigma;
1035  tmp = 0.0;
1036  for (size_t k = 0; k < m_kk; k++) {
1037  for (size_t j = 0; j < m_kk; j++) {
1038  tmp +=
1039  m_Beta_ij.value(k, j) * m_molalities[k] * m_molalities[j];
1040  }
1041  }
1042  lnActivitySolvent -= m_Mnaught * tmp;
1043  break;
1044 
1045  default:
1046  throw CanteraError("DebyeHuckel::s_update_lnMolalityActCoeff", "ERROR");
1047  }
1048 
1049  // Above, we calculated the ln(activitySolvent). Translate that into the
1050  // molar-based activity coefficient by dividing by the solvent mole
1051  // fraction. Solvents are not on the molality scale.
1052  xmolSolvent = moleFraction(0);
1053  m_lnActCoeffMolal[0] = lnActivitySolvent - log(xmolSolvent);
1054 }
1055 
1057 {
1058  double z_k, coeff, tmp, y, yp1, sigma, tmpLn;
1059  // First we store dAdT explicitly here
1060  double dAdT = dA_DebyedT_TP();
1061  if (dAdT == 0.0) {
1062  for (size_t k = 0; k < m_kk; k++) {
1063  m_dlnActCoeffMolaldT[k] = 0.0;
1064  }
1065  return;
1066  }
1067 
1068  // Calculate a safe value for the mole fraction of the solvent
1069  double xmolSolvent = moleFraction(0);
1070  xmolSolvent = std::max(8.689E-3, xmolSolvent);
1071  double sqrtI = sqrt(m_IionicMolality);
1072  double numdAdTTmp = dAdT * sqrtI;
1073  double denomTmp = m_B_Debye * sqrtI;
1074  double d_lnActivitySolvent_dT = 0;
1075 
1076  switch (m_formDH) {
1077  case DHFORM_DILUTE_LIMIT:
1078  for (size_t k = 1; k < m_kk; k++) {
1080  m_lnActCoeffMolal[k] * dAdT / m_A_Debye;
1081  }
1082  d_lnActivitySolvent_dT = 2.0 / 3.0 * dAdT * m_Mnaught *
1084  m_dlnActCoeffMolaldT[0] = d_lnActivitySolvent_dT;
1085  break;
1086 
1087  case DHFORM_BDOT_AK:
1088  for (size_t k = 0; k < m_kk; k++) {
1089  z_k = m_speciesCharge[k];
1091  - z_k * z_k * numdAdTTmp / (1.0 + denomTmp * m_Aionic[k]);
1092  }
1093 
1094  m_dlnActCoeffMolaldT[0] = 0.0;
1095  coeff = 2.0 / 3.0 * dAdT * m_Mnaught * sqrtI;
1096  tmp = 0.0;
1097  if (denomTmp > 0.0) {
1098  for (size_t k = 0; k < m_kk; k++) {
1099  y = denomTmp * m_Aionic[k];
1100  yp1 = y + 1.0;
1101  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1102  z_k = m_speciesCharge[k];
1103  tmp += m_molalities[k] * z_k * z_k * sigma / 2.0;
1104  }
1105  }
1106  m_dlnActCoeffMolaldT[0] += coeff * tmp;
1107  break;
1108 
1109  case DHFORM_BDOT_ACOMMON:
1110  denomTmp *= m_Aionic[0];
1111  for (size_t k = 0; k < m_kk; k++) {
1112  z_k = m_speciesCharge[k];
1114  - z_k * z_k * numdAdTTmp / (1.0 + denomTmp);
1115  }
1116  if (denomTmp > 0.0) {
1117  y = denomTmp;
1118  yp1 = y + 1.0;
1119  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1120  } else {
1121  sigma = 0.0;
1122  }
1123  m_dlnActCoeffMolaldT[0] = 2.0 /3.0 * dAdT * m_Mnaught *
1124  m_IionicMolality * sqrtI * sigma;
1125  break;
1126 
1127  case DHFORM_BETAIJ:
1128  denomTmp *= m_Aionic[0];
1129  for (size_t k = 1; k < m_kk; k++) {
1130  z_k = m_speciesCharge[k];
1131  m_dlnActCoeffMolaldT[k] = -z_k*z_k * numdAdTTmp / (1.0 + denomTmp);
1132  }
1133  if (denomTmp > 0.0) {
1134  y = denomTmp;
1135  yp1 = y + 1.0;
1136  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1137  } else {
1138  sigma = 0.0;
1139  }
1140  m_dlnActCoeffMolaldT[0] = 2.0 /3.0 * dAdT * m_Mnaught *
1141  m_IionicMolality * sqrtI * sigma;
1142  break;
1143 
1144  case DHFORM_PITZER_BETAIJ:
1145  denomTmp *= m_Aionic[0];
1146  tmpLn = log(1.0 + denomTmp);
1147  for (size_t k = 1; k < m_kk; k++) {
1148  z_k = m_speciesCharge[k];
1150  - z_k * z_k * numdAdTTmp / (1.0 + denomTmp)
1151  - 2.0 * z_k * z_k * dAdT * tmpLn / (m_B_Debye * m_Aionic[0]);
1152  m_dlnActCoeffMolaldT[k] /= 3.0;
1153  }
1154 
1155  sigma = 1.0 / (1.0 + denomTmp);
1156  m_dlnActCoeffMolaldT[0] = 2.0 /3.0 * dAdT * m_Mnaught *
1157  m_IionicMolality * sqrtI * sigma;
1158  break;
1159 
1160  default:
1161  throw CanteraError("DebyeHuckel::s_update_dlnMolalityActCoeff_dT",
1162  "ERROR");
1163  }
1164 }
1165 
1167 {
1168  double z_k, coeff, tmp, y, yp1, sigma, tmpLn;
1169  double dAdT = dA_DebyedT_TP();
1170  double d2AdT2 = d2A_DebyedT2_TP();
1171  if (d2AdT2 == 0.0 && dAdT == 0.0) {
1172  for (size_t k = 0; k < m_kk; k++) {
1173  m_d2lnActCoeffMolaldT2[k] = 0.0;
1174  }
1175  return;
1176  }
1177 
1178  // Calculate a safe value for the mole fraction of the solvent
1179  double xmolSolvent = moleFraction(0);
1180  xmolSolvent = std::max(8.689E-3, xmolSolvent);
1181  double sqrtI = sqrt(m_IionicMolality);
1182  double numd2AdT2Tmp = d2AdT2 * sqrtI;
1183  double denomTmp = m_B_Debye * sqrtI;
1184 
1185  switch (m_formDH) {
1186  case DHFORM_DILUTE_LIMIT:
1187  for (size_t k = 0; k < m_kk; k++) {
1189  m_lnActCoeffMolal[k] * d2AdT2 / m_A_Debye;
1190  }
1191  break;
1192 
1193  case DHFORM_BDOT_AK:
1194  for (size_t k = 0; k < m_kk; k++) {
1195  z_k = m_speciesCharge[k];
1197  - z_k * z_k * numd2AdT2Tmp / (1.0 + denomTmp * m_Aionic[k]);
1198  }
1199 
1200  m_d2lnActCoeffMolaldT2[0] = 0.0;
1201  coeff = 2.0 / 3.0 * d2AdT2 * m_Mnaught * sqrtI;
1202  tmp = 0.0;
1203  if (denomTmp > 0.0) {
1204  for (size_t k = 0; k < m_kk; k++) {
1205  y = denomTmp * m_Aionic[k];
1206  yp1 = y + 1.0;
1207  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1208  z_k = m_speciesCharge[k];
1209  tmp += m_molalities[k] * z_k * z_k * sigma / 2.0;
1210  }
1211  }
1212  m_d2lnActCoeffMolaldT2[0] += coeff * tmp;
1213  break;
1214 
1215  case DHFORM_BDOT_ACOMMON:
1216  denomTmp *= m_Aionic[0];
1217  for (size_t k = 0; k < m_kk; k++) {
1218  z_k = m_speciesCharge[k];
1220  - z_k * z_k * numd2AdT2Tmp / (1.0 + denomTmp);
1221  }
1222  if (denomTmp > 0.0) {
1223  y = denomTmp;
1224  yp1 = y + 1.0;
1225  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1226  } else {
1227  sigma = 0.0;
1228  }
1229  m_d2lnActCoeffMolaldT2[0] = 2.0 /3.0 * d2AdT2 * m_Mnaught *
1230  m_IionicMolality * sqrtI * sigma;
1231  break;
1232 
1233  case DHFORM_BETAIJ:
1234  denomTmp *= m_Aionic[0];
1235  for (size_t k = 1; k < m_kk; k++) {
1236  z_k = m_speciesCharge[k];
1237  m_d2lnActCoeffMolaldT2[k] = -z_k*z_k * numd2AdT2Tmp / (1.0 + denomTmp);
1238  }
1239  if (denomTmp > 0.0) {
1240  y = denomTmp;
1241  yp1 = y + 1.0;
1242  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 -2.0*log(yp1));
1243  } else {
1244  sigma = 0.0;
1245  }
1246  m_d2lnActCoeffMolaldT2[0] = 2.0 /3.0 * d2AdT2 * m_Mnaught *
1247  m_IionicMolality * sqrtI * sigma;
1248  break;
1249 
1250  case DHFORM_PITZER_BETAIJ:
1251  denomTmp *= m_Aionic[0];
1252  tmpLn = log(1.0 + denomTmp);
1253  for (size_t k = 1; k < m_kk; k++) {
1254  z_k = m_speciesCharge[k];
1256  - z_k * z_k * numd2AdT2Tmp / (1.0 + denomTmp)
1257  - 2.0 * z_k * z_k * d2AdT2 * tmpLn / (m_B_Debye * m_Aionic[0]);
1258  m_d2lnActCoeffMolaldT2[k] /= 3.0;
1259  }
1260 
1261  sigma = 1.0 / (1.0 + denomTmp);
1262  m_d2lnActCoeffMolaldT2[0] = 2.0 /3.0 * d2AdT2 * m_Mnaught *
1263  m_IionicMolality * sqrtI * sigma;
1264  break;
1265 
1266  default:
1267  throw CanteraError("DebyeHuckel::s_update_d2lnMolalityActCoeff_dT2",
1268  "ERROR");
1269  }
1270 }
1271 
1273 {
1274  double z_k, coeff, tmp, y, yp1, sigma, tmpLn;
1275  int est;
1276  double dAdP = dA_DebyedP_TP();
1277  if (dAdP == 0.0) {
1278  for (size_t k = 0; k < m_kk; k++) {
1279  m_dlnActCoeffMolaldP[k] = 0.0;
1280  }
1281  return;
1282  }
1283 
1284  // Calculate a safe value for the mole fraction of the solvent
1285  double xmolSolvent = moleFraction(0);
1286  xmolSolvent = std::max(8.689E-3, xmolSolvent);
1287  double sqrtI = sqrt(m_IionicMolality);
1288  double numdAdPTmp = dAdP * sqrtI;
1289  double denomTmp = m_B_Debye * sqrtI;
1290 
1291  switch (m_formDH) {
1292  case DHFORM_DILUTE_LIMIT:
1293  for (size_t k = 0; k < m_kk; k++) {
1295  m_lnActCoeffMolal[k] * dAdP / m_A_Debye;
1296  }
1297  break;
1298 
1299  case DHFORM_BDOT_AK:
1300  for (size_t k = 0; k < m_kk; k++) {
1301  est = m_electrolyteSpeciesType[k];
1302  if (est == cEST_nonpolarNeutral) {
1303  m_lnActCoeffMolal[k] = 0.0;
1304  } else {
1305  z_k = m_speciesCharge[k];
1307  - z_k * z_k * numdAdPTmp / (1.0 + denomTmp * m_Aionic[k]);
1308  }
1309  }
1310 
1311  m_dlnActCoeffMolaldP[0] = 0.0;
1312  coeff = 2.0 / 3.0 * dAdP * m_Mnaught * sqrtI;
1313  tmp = 0.0;
1314  if (denomTmp > 0.0) {
1315  for (size_t k = 0; k < m_kk; k++) {
1316  y = denomTmp * m_Aionic[k];
1317  yp1 = y + 1.0;
1318  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1319  z_k = m_speciesCharge[k];
1320  tmp += m_molalities[k] * z_k * z_k * sigma / 2.0;
1321  }
1322  }
1323  m_dlnActCoeffMolaldP[0] += coeff * tmp;
1324  break;
1325 
1326  case DHFORM_BDOT_ACOMMON:
1327  denomTmp *= m_Aionic[0];
1328  for (size_t k = 0; k < m_kk; k++) {
1329  z_k = m_speciesCharge[k];
1331  - z_k * z_k * numdAdPTmp / (1.0 + denomTmp);
1332  }
1333  if (denomTmp > 0.0) {
1334  y = denomTmp;
1335  yp1 = y + 1.0;
1336  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1337  } else {
1338  sigma = 0.0;
1339  }
1341  2.0 /3.0 * dAdP * m_Mnaught *
1342  m_IionicMolality * sqrtI * sigma;
1343  break;
1344 
1345  case DHFORM_BETAIJ:
1346  denomTmp *= m_Aionic[0];
1347  for (size_t k = 1; k < m_kk; k++) {
1348  z_k = m_speciesCharge[k];
1349  m_dlnActCoeffMolaldP[k] = - z_k*z_k * numdAdPTmp / (1.0 + denomTmp);
1350  }
1351  if (denomTmp > 0.0) {
1352  y = denomTmp;
1353  yp1 = y + 1.0;
1354  sigma = 3.0 / (y * y * y) * (yp1 - 1.0/yp1 - 2.0*log(yp1));
1355  } else {
1356  sigma = 0.0;
1357  }
1358  m_dlnActCoeffMolaldP[0] = 2.0 /3.0 * dAdP * m_Mnaught *
1359  m_IionicMolality * sqrtI * sigma;
1360  break;
1361 
1362  case DHFORM_PITZER_BETAIJ:
1363  denomTmp *= m_Aionic[0];
1364  tmpLn = log(1.0 + denomTmp);
1365  for (size_t k = 1; k < m_kk; k++) {
1366  z_k = m_speciesCharge[k];
1368  - z_k * z_k * numdAdPTmp / (1.0 + denomTmp)
1369  - 2.0 * z_k * z_k * dAdP * tmpLn
1370  / (m_B_Debye * m_Aionic[0]);
1371  m_dlnActCoeffMolaldP[k] /= 3.0;
1372  }
1373 
1374  sigma = 1.0 / (1.0 + denomTmp);
1375  m_dlnActCoeffMolaldP[0] = 2.0 /3.0 * dAdP * m_Mnaught *
1376  m_IionicMolality * sqrtI * sigma;
1377  break;
1378 
1379  default:
1380  throw CanteraError("DebyeHuckel::s_update_dlnMolalityActCoeff_dP",
1381  "ERROR");
1382  }
1383 }
1384 
1385 }
Cantera::DebyeHuckel::m_lnActCoeffMolal
vector_fp m_lnActCoeffMolal
Logarithm of the activity coefficients on the molality scale.
Definition: DebyeHuckel.h:1137
Cantera::DebyeHuckel::s_update_dlnMolalityActCoeff_dT
void s_update_dlnMolalityActCoeff_dT() const
Calculation of temperature derivative of activity coefficient.
Definition: DebyeHuckel.cpp:1056
Cantera::XML_Node::hasAttrib
bool hasAttrib(const std::string &a) const
Tests whether the current node has an attribute with a particular name.
Definition: xml.cpp:533
Cantera::VPStandardStateTP::pressure
virtual doublereal pressure() const
Returns the current pressure of the phase.
Definition: VPStandardStateTP.h:138
Cantera::DebyeHuckel::m_waterSS
PDSS_Water * m_waterSS
Pointer to the Water standard state object.
Definition: DebyeHuckel.h:1096
Cantera::DebyeHuckel::getPartialMolarEnthalpies
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: DebyeHuckel.cpp:206
Cantera::getMap
void getMap(const XML_Node &node, std::map< std::string, std::string > &m)
This routine is used to interpret the value portions of XML elements that contain colon separated pai...
Definition: ctml.cpp:330
Cantera::DebyeHuckel::s_update_d2lnMolalityActCoeff_dT2
void s_update_d2lnMolalityActCoeff_dT2() const
Calculate the temperature 2nd derivative of the activity coefficient.
Definition: DebyeHuckel.cpp:1166
Cantera::MolalityVPSSTP::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: MolalityVPSSTP.cpp:365
Cantera::DebyeHuckel::entropy_mole
virtual doublereal entropy_mole() const
Molar entropy. Units: J/kmol/K.
Definition: DebyeHuckel.cpp:86
PDSS_ConstVol.h
Cantera::DebyeHuckel::AionicRadius
double AionicRadius(int k=0) const
Reports the ionic radius of the kth species.
Definition: DebyeHuckel.cpp:731
Cantera::SmallNumber
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:149
Cantera::DebyeHuckel::m_Beta_ij
Array2D m_Beta_ij
Array of 2D data used in the DHFORM_BETAIJ formulation Beta_ij.value(i,j) is the coefficient of the j...
Definition: DebyeHuckel.h:1130
Cantera::interp_est
static int interp_est(const std::string &estString)
Utility function to assign an integer value from a string for the ElectrolyteSpeciesType field.
Definition: DebyeHuckel.cpp:312
Cantera::AnyMap::convert
double convert(const std::string &key, const std::string &units) const
Convert the item stored by the given key to the units specified in units.
Definition: AnyMap.cpp:1055
Cantera::DebyeHuckel::calcDensity
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
Definition: DebyeHuckel.cpp:106
Cantera::DebyeHuckel::getPartialMolarCp
virtual void getPartialMolarCp(doublereal *cpbar) const
Return an array of partial molar heat capacities for the species in the mixture.
Definition: DebyeHuckel.cpp:281
Cantera::warn_deprecated
void warn_deprecated(const std::string &method, const std::string &extra)
Print a warning indicating that method is deprecated.
Definition: global.cpp:54
Cantera::XML_Node::id
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:538
Cantera::Phase::meanMolecularWeight
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:748
Cantera::XML_Node::hasChild
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:528
Cantera::VPStandardStateTP::getEntropy_R
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
Definition: VPStandardStateTP.cpp:64
Cantera::AnyMap::hasKey
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:984
Cantera::DebyeHuckel::setA_Debye
void setA_Debye(double A)
Set the A_Debye parameter.
Definition: DebyeHuckel.cpp:361
electrolytes.h
Cantera::DebyeHuckel::m_IionicMolality
double m_IionicMolality
Current value of the ionic strength on the molality scale.
Definition: DebyeHuckel.h:1009
Cantera::Phase::assignDensity
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition: Phase.cpp:727
Cantera::DebyeHuckel::getMolalityActivityCoefficients
virtual void getMolalityActivityCoefficients(doublereal *acMolality) const
Get the array of non-dimensional molality-based activity coefficients at the current solution tempera...
Definition: DebyeHuckel.cpp:173
Cantera::DebyeHuckel::m_speciesCharge_Stoich
vector_fp m_speciesCharge_Stoich
Stoichiometric species charge -> This is for calculations of the ionic strength which ignore ion-ion ...
Definition: DebyeHuckel.h:1122
Cantera::DebyeHuckel::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: DebyeHuckel.cpp:412
Cantera::XML_Node::attrib
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:492
Cantera::DebyeHuckel::A_Debye_TP
virtual double A_Debye_TP(double temperature=-1.0, double pressure=-1.0) const
Return the Debye Huckel constant as a function of temperature and pressure (Units = sqrt(kg/gmol))
Definition: DebyeHuckel.cpp:631
Cantera::DebyeHuckel::getActivities
virtual void getActivities(doublereal *ac) const
Get the array of non-dimensional activities at the current solution temperature, pressure,...
Definition: DebyeHuckel.cpp:159
Cantera::DebyeHuckel::m_dlnActCoeffMolaldP
vector_fp m_dlnActCoeffMolaldP
Derivative of log act coeff wrt P.
Definition: DebyeHuckel.h:1146
ThermoFactory.h
Cantera::DebyeHuckel::getActivityConcentrations
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
Definition: DebyeHuckel.cpp:144
Cantera::DebyeHuckel::m_electrolyteSpeciesType
vector_int m_electrolyteSpeciesType
Vector containing the electrolyte species type.
Definition: DebyeHuckel.h:1003
Cantera::DebyeHuckel::m_B_Debye
double m_B_Debye
Current value of the constant that appears in the denominator.
Definition: DebyeHuckel.h:1082
Cantera::Phase::moleFraction
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:577
Cantera::VPStandardStateTP::getCp_R
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
Definition: VPStandardStateTP.cpp:92
Cantera::DebyeHuckel::setMolarDensity
virtual void setMolarDensity(const doublereal conc)
Set the internally stored molar density (kmol/m^3) of the phase.
Definition: DebyeHuckel.cpp:130
Cantera::DebyeHuckel::d2A_DebyedT2_TP
virtual double d2A_DebyedT2_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the 2nd derivative of the Debye Huckel constant with respect to temperature as a function of...
Definition: DebyeHuckel.cpp:681
Cantera::MolalityVPSSTP::initThermo
virtual void initThermo()
Definition: MolalityVPSSTP.cpp:291
Cantera::MolalityVPSSTP::calcMolalities
void calcMolalities() const
Calculates the molality of all species and stores the result internally.
Definition: MolalityVPSSTP.cpp:68
Cantera::DebyeHuckel::_lnactivityWaterHelgesonFixedForm
double _lnactivityWaterHelgesonFixedForm() const
Formula for the log of the water activity that occurs in the GWB.
Definition: DebyeHuckel.cpp:818
Cantera::Array2D::resize
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
PDSS_Water.h
DebyeHuckel.h
Cantera::MolalityVPSSTP::setStateFromXML
virtual void setStateFromXML(const XML_Node &state)
Set equation of state parameter values from XML entries.
Definition: MolalityVPSSTP.cpp:242
Cantera::DebyeHuckel::cp_mole
virtual doublereal cp_mole() const
Molar heat capacity at constant pressure. Units: J/kmol/K.
Definition: DebyeHuckel.cpp:98
Cantera::DebyeHuckel::m_d2lnActCoeffMolaldT2
vector_fp m_d2lnActCoeffMolaldT2
2nd Derivative of log act coeff wrt T
Definition: DebyeHuckel.h:1143
Cantera::Phase::m_kk
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
Cantera::Phase::charge
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
Cantera::DebyeHuckel::m_tmpV
vector_fp m_tmpV
vector of size m_kk, used as a temporary holding area.
Definition: DebyeHuckel.h:1108
Cantera::ThermoPhase::m_input
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1874
Cantera::Phase::density
virtual double density() const
Density (kg/m^3).
Definition: Phase.h:685
Cantera::PDSS_Water::density
virtual doublereal density() const
Return the standard state density at standard state.
Definition: PDSS_Water.cpp:217
Cantera::Array2D::value
doublereal & value(size_t i, size_t j)
Returns a changeable reference to position in the matrix.
Definition: Array.h:231
Cantera::DebyeHuckel::m_densWaterSS
double m_densWaterSS
Storage for the density of water's standard state.
Definition: DebyeHuckel.h:1102
Cantera::DebyeHuckel::gibbs_mole
virtual doublereal gibbs_mole() const
Molar Gibbs function. Units: J/kmol.
Definition: DebyeHuckel.cpp:92
Cantera::DebyeHuckel::m_form_A_Debye
int m_form_A_Debye
Form of the constant outside the Debye-Huckel term called A.
Definition: DebyeHuckel.h:1042
Cantera::DebyeHuckel::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: DebyeHuckel.cpp:738
Cantera::DebyeHuckel::standardConcentration
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Definition: DebyeHuckel.cpp:153
Cantera::toSI
doublereal toSI(const std::string &unit)
Return the conversion factor to convert unit std::string 'unit' to SI units.
Definition: global.cpp:140
Cantera::PDSS::molarVolume
virtual doublereal molarVolume() const
Return the molar volume at standard state.
Definition: PDSS.cpp:72
Cantera::DebyeHuckel::m_dlnActCoeffMolaldT
vector_fp m_dlnActCoeffMolaldT
Derivative of log act coeff wrt T.
Definition: DebyeHuckel.h:1140
Cantera::Phase::speciesIndex
size_t speciesIndex(const std::string &name) const
Returns the index of a species named 'name' within the Phase object.
Definition: Phase.cpp:201
Cantera::XML_Node
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
Cantera::DebyeHuckel::initThermo
virtual void initThermo()
Definition: DebyeHuckel.cpp:573
Cantera::caseInsensitiveEquals
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Definition: stringUtils.cpp:268
Cantera::DebyeHuckel::setDefaultIonicRadius
void setDefaultIonicRadius(double value)
Set the default ionic radius [m] for each species.
Definition: DebyeHuckel.cpp:388
Cantera::ThermoPhase::RT
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:776
Cantera::VPStandardStateTP::getEnthalpy_RT
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Definition: VPStandardStateTP.cpp:58
Cantera::Phase::m_speciesCharge
vector_fp m_speciesCharge
Vector of species charges. length m_kk.
Definition: Phase.h:953
Cantera::ThermoPhase::initThermoFile
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
Definition: ThermoPhase.cpp:1064
Cantera::WaterProps
The WaterProps class is used to house several approximation routines for properties of water.
Definition: WaterProps.h:99
Cantera::DebyeHuckel::_osmoticCoeffHelgesonFixedForm
double _osmoticCoeffHelgesonFixedForm() const
Formula for the osmotic coefficient that occurs in the GWB.
Definition: DebyeHuckel.cpp:799
Cantera::DebyeHuckel::setDebyeHuckelModel
void setDebyeHuckelModel(const std::string &form)
Set the DebyeHuckel parameterization form.
Definition: DebyeHuckel.cpp:337
ctml.h
Cantera::MolalityVPSSTP::m_Mnaught
doublereal m_Mnaught
This is the multiplication factor that goes inside log expressions involving the molalities of specie...
Definition: MolalityVPSSTP.h:601
Cantera::DebyeHuckel::_nonpolarActCoeff
static double _nonpolarActCoeff(double IionicMolality)
Static function that implements the non-polar species salt-out modifications.
Definition: DebyeHuckel.cpp:785
Cantera::DebyeHuckel::m_IionicMolalityStoich
double m_IionicMolalityStoich
Stoichiometric ionic strength on the molality scale.
Definition: DebyeHuckel.h:1023
stringUtils.h
Cantera::DebyeHuckel::setBeta
void setBeta(const std::string &sp1, const std::string &sp2, double value)
Set the value for the beta interaction between species sp1 and sp2.
Definition: DebyeHuckel.cpp:397
Cantera::DebyeHuckel::enthalpy_mole
virtual doublereal enthalpy_mole() const
Molar enthalpy. Units: J/kmol.
Definition: DebyeHuckel.cpp:80
Cantera::getMatrixValues
void getMatrixValues(const XML_Node &node, const std::vector< std::string > &keyStringRow, const std::vector< std::string > &keyStringCol, Array2D &retnValues, const bool convert, const bool matrixSymmetric)
This function interprets the value portion of an XML element as a series of "Matrix ids and entries" ...
Definition: ctml.cpp:362
Cantera::MolalityVPSSTP::m_molalities
vector_fp m_molalities
Current value of the molalities of the species in the phase.
Definition: MolalityVPSSTP.h:605
Cantera::Phase::temperature
doublereal temperature() const
Temperature (K).
Definition: Phase.h:667
Cantera::DebyeHuckel::m_useHelgesonFixedForm
bool m_useHelgesonFixedForm
If true, then the fixed for of Helgeson's activity for water is used instead of the rigorous form obt...
Definition: DebyeHuckel.h:1020
Cantera::DebyeHuckel::m_waterProps
std::unique_ptr< WaterProps > m_waterProps
Pointer to the water property calculator.
Definition: DebyeHuckel.h:1105
Cantera::Phase::nSpecies
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:285
Cantera::getFloat
doublereal getFloat(const XML_Node &parent, const std::string &name, const std::string &type)
Get a floating-point value from a child element.
Definition: ctml.cpp:164
Cantera::Phase::mean_X
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
Definition: Phase.cpp:746
Cantera::DebyeHuckel::getChemPotentials
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
Definition: DebyeHuckel.cpp:186
Cantera::DebyeHuckel::DebyeHuckel
DebyeHuckel()
Default Constructor.
Definition: DebyeHuckel.cpp:29
Cantera::DebyeHuckel::dA_DebyedP_TP
virtual double dA_DebyedP_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to pressure, as a function of tempe...
Definition: DebyeHuckel.cpp:705
Cantera::DebyeHuckel::dA_DebyedT_TP
virtual double dA_DebyedT_TP(double temperature=-1.0, double pressure=-1.0) const
Value of the derivative of the Debye Huckel constant with respect to temperature.
Definition: DebyeHuckel.cpp:657
Cantera::AnyMap
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:359
Cantera::Phase::molarDensity
double molarDensity() const
Molar density (kmol/m^3).
Definition: Phase.cpp:700
Cantera::GasConstant
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:109
Cantera::VPStandardStateTP::getStandardVolumes
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
Definition: VPStandardStateTP.cpp:98
Cantera::DebyeHuckel::setDensity
virtual void setDensity(const doublereal rho)
Set the internally stored density (gm/m^3) of the phase.
Definition: DebyeHuckel.cpp:118
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:60
Cantera::importPhase
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Definition: ThermoFactory.cpp:237
Cantera::Phase::speciesNames
const std::vector< std::string > & speciesNames() const
Return a const reference to the vector of species names.
Definition: Phase.cpp:235
Cantera::VPStandardStateTP::_updateStandardStateThermo
virtual void _updateStandardStateThermo() const
Updates the standard state thermodynamic functions at the current T and P of the solution.
Definition: VPStandardStateTP.cpp:262
Cantera::DebyeHuckel::m_A_Debye
double m_A_Debye
Current value of the Debye Constant, A_Debye.
Definition: DebyeHuckel.h:1064
Cantera::npos
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:188
Cantera::DebyeHuckel::s_update_dlnMolalityActCoeff_dP
void s_update_dlnMolalityActCoeff_dP() const
Calculate the pressure derivative of the activity coefficient.
Definition: DebyeHuckel.cpp:1272
Cantera::DebyeHuckel::s_update_lnMolalityActCoeff
void s_update_lnMolalityActCoeff() const
Calculate the log activity coefficients.
Definition: DebyeHuckel.cpp:833
Cantera::XML_Node::findByName
const XML_Node * findByName(const std::string &nm, int depth=100000) const
This routine carries out a recursive search for an XML node based on the name of the node.
Definition: xml.cpp:679
Cantera::DebyeHuckel::getPartialMolarVolumes
virtual void getPartialMolarVolumes(doublereal *vbar) const
Return an array of partial molar volumes for the species in the mixture.
Definition: DebyeHuckel.cpp:269
Cantera::Phase::species
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Definition: Phase.cpp:980
Cantera
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:263
Cantera::VPStandardStateTP::getStandardChemPotentials
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
Definition: VPStandardStateTP.cpp:50
Cantera::DebyeHuckel::m_Aionic
vector_fp m_Aionic
a_k = Size of the ionic species in the DH formulation. units = meters
Definition: DebyeHuckel.h:1006
Cantera::DebyeHuckel::m_B_Dot
vector_fp m_B_Dot
Array of B_Dot values.
Definition: DebyeHuckel.h:1090
Cantera::fpValue
doublereal fpValue(const std::string &val)
Translate a string into one doublereal value.
Definition: stringUtils.cpp:129
Cantera::cEST_solvent
const int cEST_solvent
Electrolyte species type.
Definition: electrolytes.h:18
Cantera::PDSS_ConstVol
Class for pressure dependent standard states that use a constant volume model.
Definition: PDSS_ConstVol.h:22
Cantera::XML_Node::child
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
Cantera::DebyeHuckel::m_maxIionicStrength
double m_maxIionicStrength
Maximum value of the ionic strength allowed in the calculation of the activity coefficients.
Definition: DebyeHuckel.h:1013
Cantera::PDSS_Water
Class for the liquid water pressure dependent standard state.
Definition: PDSS_Water.h:49
Cantera::DebyeHuckel::getPartialMolarEntropies
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: DebyeHuckel.cpp:231
Cantera::DebyeHuckel::m_formDH
int m_formDH
form of the Debye-Huckel parameterization used in the model.
Definition: DebyeHuckel.h:990