Cantera  2.5.1
IdealMolalSoln.cpp
Go to the documentation of this file.
1 /**
2  * @file IdealMolalSoln.cpp
3  * ThermoPhase object for the ideal molal equation of
4  * state (see \ref thermoprops
5  * and class \link Cantera::IdealMolalSoln IdealMolalSoln\endlink).
6  *
7  * Definition file for a derived class of ThermoPhase that handles variable
8  * pressure standard state methods for calculating thermodynamic properties that
9  * are further based upon activities on the molality scale. The Ideal molal
10  * solution assumes that all molality-based activity coefficients are equal to
11  * one. This turns out, actually, to be highly nonlinear when the solvent
12  * densities get low.
13  */
14 
15 // This file is part of Cantera. See License.txt in the top-level directory or
16 // at https://cantera.org/license.txt for license and copyright information.
17 
20 #include "cantera/base/ctml.h"
22 
23 #include <iostream>
24 
25 namespace Cantera
26 {
27 
29  m_formGC(2),
30  IMS_typeCutoff_(0),
31  IMS_X_o_cutoff_(0.20),
32  IMS_gamma_o_min_(0.00001),
33  IMS_gamma_k_min_(10.0),
34  IMS_slopefCut_(0.6),
35  IMS_slopegCut_(0.0),
36  IMS_cCut_(.05),
37  IMS_dfCut_(0.0),
38  IMS_efCut_(0.0),
39  IMS_afCut_(0.0),
40  IMS_bfCut_(0.0),
41  IMS_dgCut_(0.0),
42  IMS_egCut_(0.0),
43  IMS_agCut_(0.0),
44  IMS_bgCut_(0.0)
45 {
46 }
47 
48 IdealMolalSoln::IdealMolalSoln(const std::string& inputFile,
49  const std::string& id_) :
51  m_formGC(2),
52  IMS_typeCutoff_(0),
53  IMS_X_o_cutoff_(0.2),
54  IMS_gamma_o_min_(0.00001),
55  IMS_gamma_k_min_(10.0),
56  IMS_slopefCut_(0.6),
57  IMS_slopegCut_(0.0),
58  IMS_cCut_(.05),
59  IMS_dfCut_(0.0),
60  IMS_efCut_(0.0),
61  IMS_afCut_(0.0),
62  IMS_bfCut_(0.0),
63  IMS_dgCut_(0.0),
64  IMS_egCut_(0.0),
65  IMS_agCut_(0.0),
66  IMS_bgCut_(0.0)
67 {
68  initThermoFile(inputFile, id_);
69 }
70 
71 IdealMolalSoln::IdealMolalSoln(XML_Node& root, const std::string& id_) :
73  m_formGC(2),
74  IMS_typeCutoff_(0),
75  IMS_X_o_cutoff_(0.2),
76  IMS_gamma_o_min_(0.00001),
77  IMS_gamma_k_min_(10.0),
78  IMS_slopefCut_(0.6),
79  IMS_slopegCut_(0.0),
80  IMS_cCut_(.05),
81  IMS_dfCut_(0.0),
82  IMS_efCut_(0.0),
83  IMS_afCut_(0.0),
84  IMS_bfCut_(0.0),
85  IMS_dgCut_(0.0),
86  IMS_egCut_(0.0),
87  IMS_agCut_(0.0),
88  IMS_bgCut_(0.0)
89 {
90  importPhase(root, this);
91 }
92 
94 {
96  return mean_X(m_tmpV);
97 }
98 
100 {
102  return mean_X(m_tmpV);
103 }
104 
106 {
108  return mean_X(m_tmpV);
109 }
110 
111 doublereal IdealMolalSoln::gibbs_mole() const
112 {
113  getChemPotentials(m_tmpV.data());
114  return mean_X(m_tmpV);
115 }
116 
117 doublereal IdealMolalSoln::cp_mole() const
118 {
119  getPartialMolarCp(m_tmpV.data());
120  return mean_X(m_tmpV);
121 }
122 
123 // ------- Mechanical Equation of State Properties ------------------------
124 
126 {
128  doublereal dd = meanMolecularWeight() / mean_X(m_tmpV);
130 }
131 
133 {
134  return 0.0;
135 }
136 
138 {
139  return 0.0;
140 }
141 
142 void IdealMolalSoln::setDensity(const doublereal rho)
143 {
144  warn_deprecated("IdealMolalSoln::setDensity",
145  "Overloaded function to be removed after Cantera 2.5. "
146  "Error will be thrown by Phase::setDensity instead");
147  if (rho != density()) {
148  throw CanteraError("IdealMolalSoln::setDensity",
149  "Density is not an independent variable");
150  }
151 }
152 
153 void IdealMolalSoln::setMolarDensity(const doublereal conc)
154 {
155  warn_deprecated("IdealMolalSoln::setMolarDensity",
156  "Overloaded function to be removed after Cantera 2.5. "
157  "Error will be thrown by Phase::setMolarDensity instead");
158  if (conc != Phase::molarDensity()) {
159  throw CanteraError("IdealMolalSoln::setMolarDensity",
160  "molarDensity/density is not an independent variable");
161  }
162 }
163 
164 // ------- Activities and Activity Concentrations
165 
167 {
168  if (m_formGC == 0) {
169  return Units(1.0); // dimensionless
170  } else {
171  // kmol/m^3 for bulk phases
172  return Units(1.0, 0, -static_cast<double>(nDim()), 0, 0, 0, 1);
173  }
174 }
175 
177 {
178  if (m_formGC != 1) {
179  double c_solvent = standardConcentration();
180  getActivities(c);
181  for (size_t k = 0; k < m_kk; k++) {
182  c[k] *= c_solvent;
183  }
184  } else {
185  getActivities(c);
186  for (size_t k = 0; k < m_kk; k++) {
187  double c0 = standardConcentration(k);
188  c[k] *= c0;
189  }
190  }
191 }
192 
193 doublereal IdealMolalSoln::standardConcentration(size_t k) const
194 {
195  switch (m_formGC) {
196  case 0:
197  return 1.0;
198  case 1:
199  return 1.0 / m_speciesMolarVolume[k];
200  case 2:
201  return 1.0 / m_speciesMolarVolume[0];
202  default:
203  throw CanteraError("IdealMolalSoln::standardConcentration",
204  "m_formGC is set to an incorrect value. \
205  Allowed values are 0, 1, and 2");
206  }
207 }
208 
209 void IdealMolalSoln::getActivities(doublereal* ac) const
210 {
212 
213  // Update the molality array, m_molalities(). This requires an update due to
214  // mole fractions
215  if (IMS_typeCutoff_ == 0) {
216  calcMolalities();
217  for (size_t k = 0; k < m_kk; k++) {
218  ac[k] = m_molalities[k];
219  }
220  double xmolSolvent = moleFraction(0);
221  // Limit the activity coefficient to be finite as the solvent mole
222  // fraction goes to zero.
223  xmolSolvent = std::max(m_xmolSolventMIN, xmolSolvent);
224  ac[0] = exp((xmolSolvent - 1.0)/xmolSolvent);
225  } else {
226 
228 
229  // Now calculate the array of activities.
230  for (size_t k = 1; k < m_kk; k++) {
231  ac[k] = m_molalities[k] * exp(IMS_lnActCoeffMolal_[k]);
232  }
233  double xmolSolvent = moleFraction(0);
234  ac[0] = exp(IMS_lnActCoeffMolal_[0]) * xmolSolvent;
235  }
236 }
237 
238 void IdealMolalSoln::getMolalityActivityCoefficients(doublereal* acMolality) const
239 {
240  if (IMS_typeCutoff_ == 0) {
241  for (size_t k = 0; k < m_kk; k++) {
242  acMolality[k] = 1.0;
243  }
244  double xmolSolvent = moleFraction(0);
245  // Limit the activity coefficient to be finite as the solvent mole
246  // fraction goes to zero.
247  xmolSolvent = std::max(m_xmolSolventMIN, xmolSolvent);
248  acMolality[0] = exp((xmolSolvent - 1.0)/xmolSolvent) / xmolSolvent;
249  } else {
251  std::copy(IMS_lnActCoeffMolal_.begin(), IMS_lnActCoeffMolal_.end(), acMolality);
252  for (size_t k = 0; k < m_kk; k++) {
253  acMolality[k] = exp(acMolality[k]);
254  }
255  }
256 }
257 
258 // ------ Partial Molar Properties of the Solution -----------------
259 
260 void IdealMolalSoln::getChemPotentials(doublereal* mu) const
261 {
262  // First get the standard chemical potentials. This requires updates of
263  // standard state as a function of T and P These are defined at unit
264  // molality.
266 
267  // Update the molality array, m_molalities(). This requires an update due to
268  // mole fractions
269  calcMolalities();
270 
271  // get the solvent mole fraction
272  double xmolSolvent = moleFraction(0);
273 
274  if (IMS_typeCutoff_ == 0 || xmolSolvent > 3.* IMS_X_o_cutoff_/2.0) {
275  for (size_t k = 1; k < m_kk; k++) {
276  double xx = std::max(m_molalities[k], SmallNumber);
277  mu[k] += RT() * log(xx);
278  }
279 
280  // Do the solvent
281  // -> see my notes
282  double xx = std::max(xmolSolvent, SmallNumber);
283  mu[0] += (RT() * (xmolSolvent - 1.0) / xx);
284  } else {
285  // Update the activity coefficients. This also updates the internal
286  // molality array.
288 
289  for (size_t k = 1; k < m_kk; k++) {
290  double xx = std::max(m_molalities[k], SmallNumber);
291  mu[k] += RT() * (log(xx) + IMS_lnActCoeffMolal_[k]);
292  }
293  double xx = std::max(xmolSolvent, SmallNumber);
294  mu[0] += RT() * (log(xx) + IMS_lnActCoeffMolal_[0]);
295  }
296 }
297 
298 void IdealMolalSoln::getPartialMolarEnthalpies(doublereal* hbar) const
299 {
300  getEnthalpy_RT(hbar);
301  for (size_t k = 0; k < m_kk; k++) {
302  hbar[k] *= RT();
303  }
304 }
305 
306 void IdealMolalSoln::getPartialMolarEntropies(doublereal* sbar) const
307 {
308  getEntropy_R(sbar);
309  calcMolalities();
310  if (IMS_typeCutoff_ == 0) {
311  for (size_t k = 1; k < m_kk; k++) {
312  doublereal mm = std::max(SmallNumber, m_molalities[k]);
313  sbar[k] -= GasConstant * log(mm);
314  }
315  double xmolSolvent = moleFraction(0);
316  sbar[0] -= (GasConstant * (xmolSolvent - 1.0) / xmolSolvent);
317  } else {
318  // Update the activity coefficients, This also update the internally
319  // stored molalities.
321 
322  // First we will add in the obvious dependence on the T term out front
323  // of the log activity term
324  doublereal mm;
325  for (size_t k = 1; k < m_kk; k++) {
326  mm = std::max(SmallNumber, m_molalities[k]);
327  sbar[k] -= GasConstant * (log(mm) + IMS_lnActCoeffMolal_[k]);
328  }
329  double xmolSolvent = moleFraction(0);
330  mm = std::max(SmallNumber, xmolSolvent);
331  sbar[0] -= GasConstant *(log(mm) + IMS_lnActCoeffMolal_[0]);
332  }
333 }
334 
335 void IdealMolalSoln::getPartialMolarVolumes(doublereal* vbar) const
336 {
337  getStandardVolumes(vbar);
338 }
339 
340 void IdealMolalSoln::getPartialMolarCp(doublereal* cpbar) const
341 {
342  // Get the nondimensional Gibbs standard state of the species at the T and P
343  // of the solution.
344  getCp_R(cpbar);
345  for (size_t k = 0; k < m_kk; k++) {
346  cpbar[k] *= GasConstant;
347  }
348 }
349 
350 // -------------- Utilities -------------------------------
351 
352 bool IdealMolalSoln::addSpecies(shared_ptr<Species> spec)
353 {
354  bool added = MolalityVPSSTP::addSpecies(spec);
355  if (added) {
356  m_speciesMolarVolume.push_back(0.0);
357  m_tmpV.push_back(0.0);
358  IMS_lnActCoeffMolal_.push_back(0.0);
359  }
360  return added;
361 }
362 
363 void IdealMolalSoln::initThermoXML(XML_Node& phaseNode, const std::string& id_)
364 {
365  MolalityVPSSTP::initThermoXML(phaseNode, id_);
366 
367  if (id_.size() > 0 && phaseNode.id() != id_) {
368  throw CanteraError("IdealMolalSoln::initThermoXML",
369  "phasenode and Id are incompatible");
370  }
371 
372  // Find the Thermo XML node
373  if (!phaseNode.hasChild("thermo")) {
374  throw CanteraError("IdealMolalSoln::initThermoXML",
375  "no thermo XML node");
376  }
377  XML_Node& thermoNode = phaseNode.child("thermo");
378 
379  // Possible change the form of the standard concentrations
380  if (thermoNode.hasChild("standardConc")) {
381  XML_Node& scNode = thermoNode.child("standardConc");
382  setStandardConcentrationModel(scNode["model"]);
383  }
384 
385  if (thermoNode.hasChild("activityCoefficients")) {
386  XML_Node& acNode = thermoNode.child("activityCoefficients");
387  std::string modelString = acNode.attrib("model");
388  if (modelString != "IdealMolalSoln") {
389  throw CanteraError("IdealMolalSoln::initThermoXML",
390  "unknown ActivityCoefficient model: " + modelString);
391  }
392  if (acNode.hasChild("idealMolalSolnCutoff")) {
393  XML_Node& ccNode = acNode.child("idealMolalSolnCutoff");
394  modelString = ccNode.attrib("model");
395  if (modelString != "") {
396  setCutoffModel(modelString);
397  if (ccNode.hasChild("gamma_o_limit")) {
398  IMS_gamma_o_min_ = getFloat(ccNode, "gamma_o_limit");
399  }
400  if (ccNode.hasChild("gamma_k_limit")) {
401  IMS_gamma_k_min_ = getFloat(ccNode, "gamma_k_limit");
402  }
403  if (ccNode.hasChild("X_o_cutoff")) {
404  IMS_X_o_cutoff_ = getFloat(ccNode, "X_o_cutoff");
405  }
406  if (ccNode.hasChild("c_0_param")) {
407  IMS_cCut_ = getFloat(ccNode, "c_0_param");
408  }
409  if (ccNode.hasChild("slope_f_limit")) {
410  IMS_slopefCut_ = getFloat(ccNode, "slope_f_limit");
411  }
412  if (ccNode.hasChild("slope_g_limit")) {
413  IMS_slopegCut_ = getFloat(ccNode, "slope_g_limit");
414  }
415  }
416  } else {
417  setCutoffModel("none");
418  }
419  }
420 }
421 
423 {
425 
426  if (m_input.hasKey("standard-concentration-basis")) {
427  setStandardConcentrationModel(m_input["standard-concentration-basis"].asString());
428  }
429  if (m_input.hasKey("cutoff")) {
430  auto& cutoff = m_input["cutoff"].as<AnyMap>();
431  setCutoffModel(cutoff.getString("model", "none"));
432  if (cutoff.hasKey("gamma_o")) {
433  IMS_gamma_o_min_ = cutoff["gamma_o"].asDouble();
434  }
435  if (cutoff.hasKey("gamma_k")) {
436  IMS_gamma_k_min_ = cutoff["gamma_k"].asDouble();
437  }
438  if (cutoff.hasKey("X_o")) {
439  IMS_X_o_cutoff_ = cutoff["X_o"].asDouble();
440  }
441  if (cutoff.hasKey("c_0")) {
442  IMS_cCut_ = cutoff["c_0"].asDouble();
443  }
444  if (cutoff.hasKey("slope_f")) {
445  IMS_slopefCut_ = cutoff["slope_f"].asDouble();
446  }
447  if (cutoff.hasKey("slope_g")) {
448  IMS_slopegCut_ = cutoff["slope_g"].asDouble();
449  }
450  }
451 
452  for (size_t k = 0; k < nSpecies(); k++) {
453  m_speciesMolarVolume[k] = providePDSS(k)->molarVolume();
454  }
455  if (IMS_typeCutoff_ == 2) {
457  }
458  setMoleFSolventMin(1.0E-5);
459 }
460 
461 void IdealMolalSoln::setStandardConcentrationModel(const std::string& model)
462 {
463  if (caseInsensitiveEquals(model, "unity")) {
464  m_formGC = 0;
465  } else if (caseInsensitiveEquals(model, "species-molar-volume")
466  || caseInsensitiveEquals(model, "molar_volume")) {
467  m_formGC = 1;
468  } else if (caseInsensitiveEquals(model, "solvent-molar-volume")
469  || caseInsensitiveEquals(model, "solvent_volume")) {
470  m_formGC = 2;
471  } else {
472  throw CanteraError("IdealMolalSoln::setStandardConcentrationModel",
473  "Unknown standard concentration model '{}'", model);
474  }
475 }
476 
477 void IdealMolalSoln::setCutoffModel(const std::string& model)
478 {
479  if (caseInsensitiveEquals(model, "none")) {
480  IMS_typeCutoff_ = 0;
481  } else if (caseInsensitiveEquals(model, "poly")) {
482  IMS_typeCutoff_ = 1;
483  } else if (caseInsensitiveEquals(model, "polyexp")) {
484  IMS_typeCutoff_ = 2;
485  } else {
486  throw CanteraError("IdealMolalSoln::setCutoffModel",
487  "Unknown cutoff model '{}'", model);
488  }
489 }
490 
491 // ------------ Private and Restricted Functions ------------------
492 
494 {
495  // Calculate the molalities. Currently, the molalities may not be current
496  // with respect to the contents of the State objects' data.
497  calcMolalities();
498 
499  double xmolSolvent = moleFraction(0);
500  double xx = std::max(m_xmolSolventMIN, xmolSolvent);
501 
502  if (IMS_typeCutoff_ == 0) {
503  for (size_t k = 1; k < m_kk; k++) {
504  IMS_lnActCoeffMolal_[k]= 0.0;
505  }
506  IMS_lnActCoeffMolal_[0] = - log(xx) + (xx - 1.0)/xx;
507  return;
508  } else if (IMS_typeCutoff_ == 1) {
509  if (xmolSolvent > 3.0 * IMS_X_o_cutoff_/2.0) {
510  for (size_t k = 1; k < m_kk; k++) {
511  IMS_lnActCoeffMolal_[k]= 0.0;
512  }
513  IMS_lnActCoeffMolal_[0] = - log(xx) + (xx - 1.0)/xx;
514  return;
515  } else if (xmolSolvent < IMS_X_o_cutoff_/2.0) {
516  double tmp = log(xx * IMS_gamma_k_min_);
517  for (size_t k = 1; k < m_kk; k++) {
518  IMS_lnActCoeffMolal_[k]= tmp;
519  }
521  return;
522  } else {
523  // If we are in the middle region, calculate the connecting polynomials
524  double xminus = xmolSolvent - IMS_X_o_cutoff_/2.0;
525  double xminus2 = xminus * xminus;
526  double xminus3 = xminus2 * xminus;
527  double x_o_cut2 = IMS_X_o_cutoff_ * IMS_X_o_cutoff_;
528  double x_o_cut3 = x_o_cut2 * IMS_X_o_cutoff_;
529 
530  double h2 = 3.5 * xminus2 / IMS_X_o_cutoff_ - 2.0 * xminus3 / x_o_cut2;
531  double h2_prime = 7.0 * xminus / IMS_X_o_cutoff_ - 6.0 * xminus2 / x_o_cut2;
532 
533  double h1 = (1.0 - 3.0 * xminus2 / x_o_cut2 + 2.0 * xminus3/ x_o_cut3);
534  double h1_prime = (- 6.0 * xminus / x_o_cut2 + 6.0 * xminus2/ x_o_cut3);
535 
536  double h1_g = h1 / IMS_gamma_o_min_;
537  double h1_g_prime = h1_prime / IMS_gamma_o_min_;
538 
539  double alpha = 1.0 / (exp(1.0) * IMS_gamma_k_min_);
540  double h1_f = h1 * alpha;
541  double h1_f_prime = h1_prime * alpha;
542 
543  double f = h2 + h1_f;
544  double f_prime = h2_prime + h1_f_prime;
545 
546  double g = h2 + h1_g;
547  double g_prime = h2_prime + h1_g_prime;
548 
549  double tmp = (xmolSolvent/ g * g_prime + (1.0-xmolSolvent) / f * f_prime);
550  double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
551  double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
552 
553  tmp = log(xmolSolvent) + lngammak;
554  for (size_t k = 1; k < m_kk; k++) {
555  IMS_lnActCoeffMolal_[k]= tmp;
556  }
557  IMS_lnActCoeffMolal_[0] = lngammao;
558  }
559  } else if (IMS_typeCutoff_ == 2) {
560  // Exponentials - trial 2
561  if (xmolSolvent > IMS_X_o_cutoff_) {
562  for (size_t k = 1; k < m_kk; k++) {
563  IMS_lnActCoeffMolal_[k]= 0.0;
564  }
565  IMS_lnActCoeffMolal_[0] = - log(xx) + (xx - 1.0)/xx;
566  return;
567  } else {
568  double xoverc = xmolSolvent/IMS_cCut_;
569  double eterm = std::exp(-xoverc);
570 
571  double fptmp = IMS_bfCut_ - IMS_afCut_ / IMS_cCut_ - IMS_bfCut_*xoverc
572  + 2.0*IMS_dfCut_*xmolSolvent - IMS_dfCut_*xmolSolvent*xoverc;
573  double f_prime = 1.0 + eterm*fptmp;
574  double f = xmolSolvent + IMS_efCut_ + eterm * (IMS_afCut_ + xmolSolvent * (IMS_bfCut_ + IMS_dfCut_*xmolSolvent));
575 
576  double gptmp = IMS_bgCut_ - IMS_agCut_ / IMS_cCut_ - IMS_bgCut_*xoverc
577  + 2.0*IMS_dgCut_*xmolSolvent - IMS_dgCut_*xmolSolvent*xoverc;
578  double g_prime = 1.0 + eterm*gptmp;
579  double g = xmolSolvent + IMS_egCut_ + eterm * (IMS_agCut_ + xmolSolvent * (IMS_bgCut_ + IMS_dgCut_*xmolSolvent));
580 
581  double tmp = (xmolSolvent / g * g_prime + (1.0 - xmolSolvent) / f * f_prime);
582  double lngammak = -1.0 - log(f) + tmp * xmolSolvent;
583  double lngammao =-log(g) - tmp * (1.0-xmolSolvent);
584 
585  tmp = log(xx) + lngammak;
586  for (size_t k = 1; k < m_kk; k++) {
587  IMS_lnActCoeffMolal_[k]= tmp;
588  }
589  IMS_lnActCoeffMolal_[0] = lngammao;
590  }
591  }
592 }
593 
595 {
596  IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_);
597  IMS_efCut_ = 0.0;
598  bool converged = false;
599  for (int its = 0; its < 100 && !converged; its++) {
600  double oldV = IMS_efCut_;
601  IMS_afCut_ = 1.0 / (std::exp(1.0) * IMS_gamma_k_min_) - IMS_efCut_;
602  IMS_bfCut_ = IMS_afCut_ / IMS_cCut_ + IMS_slopefCut_ - 1.0;
603  IMS_dfCut_ = ((- IMS_afCut_/IMS_cCut_ + IMS_bfCut_ - IMS_bfCut_*IMS_X_o_cutoff_/IMS_cCut_)
604  /
605  (IMS_X_o_cutoff_*IMS_X_o_cutoff_/IMS_cCut_ - 2.0 * IMS_X_o_cutoff_));
606  double tmp = IMS_afCut_ + IMS_X_o_cutoff_*(IMS_bfCut_ + IMS_dfCut_ * IMS_X_o_cutoff_);
607  double eterm = std::exp(-IMS_X_o_cutoff_/IMS_cCut_);
608  IMS_efCut_ = - eterm * (tmp);
609  if (fabs(IMS_efCut_ - oldV) < 1.0E-14) {
610  converged = true;
611  }
612  }
613  if (!converged) {
614  throw CanteraError("IdealMolalSoln::calcCutoffParams_",
615  "failed to converge on the f polynomial");
616  }
617  converged = false;
618  double f_0 = IMS_afCut_ + IMS_efCut_;
619  double f_prime_0 = 1.0 - IMS_afCut_ / IMS_cCut_ + IMS_bfCut_;
620  IMS_egCut_ = 0.0;
621  for (int its = 0; its < 100 && !converged; its++) {
622  double oldV = IMS_egCut_;
623  double lng_0 = -log(IMS_gamma_o_min_) - f_prime_0 / f_0;
624  IMS_agCut_ = exp(lng_0) - IMS_egCut_;
625  IMS_bgCut_ = IMS_agCut_ / IMS_cCut_ + IMS_slopegCut_ - 1.0;
626  IMS_dgCut_ = ((- IMS_agCut_/IMS_cCut_ + IMS_bgCut_ - IMS_bgCut_*IMS_X_o_cutoff_/IMS_cCut_)
627  /
628  (IMS_X_o_cutoff_*IMS_X_o_cutoff_/IMS_cCut_ - 2.0 * IMS_X_o_cutoff_));
629  double tmp = IMS_agCut_ + IMS_X_o_cutoff_*(IMS_bgCut_ + IMS_dgCut_ *IMS_X_o_cutoff_);
630  double eterm = std::exp(-IMS_X_o_cutoff_/IMS_cCut_);
631  IMS_egCut_ = - eterm * (tmp);
632  if (fabs(IMS_egCut_ - oldV) < 1.0E-14) {
633  converged = true;
634  }
635  }
636  if (!converged) {
637  throw CanteraError("IdealMolalSoln::calcCutoffParams_",
638  "failed to converge on the g polynomial");
639  }
640 }
641 
642 }
Cantera::ThermoPhase::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
Definition: ThermoPhase.cpp:1089
Cantera::IdealMolalSoln::standardConcentrationUnits
virtual Units standardConcentrationUnits() const
Returns the units of the "standard concentration" for this phase.
Definition: IdealMolalSoln.cpp:166
Cantera::MolalityVPSSTP::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: MolalityVPSSTP.cpp:365
Cantera::IdealMolalSoln::enthalpy_mole
virtual doublereal enthalpy_mole() const
Molar enthalpy of the solution. Units: J/kmol.
Definition: IdealMolalSoln.cpp:93
Cantera::SmallNumber
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:149
Cantera::MolalityVPSSTP::m_xmolSolventMIN
doublereal m_xmolSolventMIN
Definition: MolalityVPSSTP.h:596
Cantera::IdealMolalSoln::entropy_mole
virtual doublereal entropy_mole() const
Molar entropy of the solution. Units: J/kmol/K.
Definition: IdealMolalSoln.cpp:105
Cantera::IdealMolalSoln::initThermoXML
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id="")
Import and initialize a ThermoPhase object using an XML tree.
Definition: IdealMolalSoln.cpp:363
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::IdealMolalSoln::setCutoffModel
void setCutoffModel(const std::string &model)
Set cutoff model. Must be one of 'none', 'poly', or 'polyExp'.
Definition: IdealMolalSoln.cpp:477
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::MolalityVPSSTP::setMoleFSolventMin
void setMoleFSolventMin(doublereal xmolSolventMIN)
Sets the minimum mole fraction in the molality formulation.
Definition: MolalityVPSSTP.cpp:53
Cantera::IdealMolalSoln::initThermo
virtual void initThermo()
Definition: IdealMolalSoln.cpp:422
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::Phase::nDim
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
Definition: Phase.h:651
Cantera::XML_Node::attrib
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:492
Cantera::IdealMolalSoln::getChemPotentials
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials: Units: J/kmol.
Definition: IdealMolalSoln.cpp:260
Cantera::IdealMolalSoln::getPartialMolarEnthalpies
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
Definition: IdealMolalSoln.cpp:298
Cantera::IdealMolalSoln::addSpecies
virtual bool addSpecies(shared_ptr< Species > spec)
Definition: IdealMolalSoln.cpp:352
Cantera::IdealMolalSoln::calcDensity
void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
Definition: IdealMolalSoln.cpp:125
Cantera::IdealMolalSoln::IMS_typeCutoff_
int IMS_typeCutoff_
Cutoff type.
Definition: IdealMolalSoln.h:466
ThermoFactory.h
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::IdealMolalSoln::s_updateIMS_lnMolalityActCoeff
void s_updateIMS_lnMolalityActCoeff() const
This function will be called to update the internally stored natural logarithm of the molality activi...
Definition: IdealMolalSoln.cpp:493
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::IdealMolalSoln::standardConcentration
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Definition: IdealMolalSoln.cpp:193
Cantera::IdealMolalSoln::gibbs_mole
virtual doublereal gibbs_mole() const
Molar Gibbs function for the solution: Units J/kmol.
Definition: IdealMolalSoln.cpp:111
Cantera::Phase::m_kk
size_t m_kk
Number of species in the phase.
Definition: Phase.h:942
Cantera::MolalityVPSSTP
Definition: MolalityVPSSTP.h:181
Cantera::ThermoPhase::m_input
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1874
Cantera::IdealMolalSoln::calcIMSCutoffParams_
void calcIMSCutoffParams_()
Calculate parameters for cutoff treatments of activity coefficients.
Definition: IdealMolalSoln.cpp:594
Cantera::Phase::density
virtual double density() const
Density (kg/m^3).
Definition: Phase.h:685
Cantera::IdealMolalSoln::m_formGC
int m_formGC
The standard concentrations can have one of three different forms: 0 = 'unity', 1 = 'molar_volume',...
Definition: IdealMolalSoln.h:463
Cantera::IdealMolalSoln::IMS_slopefCut_
doublereal IMS_slopefCut_
Parameter in the polyExp cutoff treatment.
Definition: IdealMolalSoln.h:490
Cantera::IdealMolalSoln::isothermalCompressibility
virtual doublereal isothermalCompressibility() const
The isothermal compressibility. Units: 1/Pa.
Definition: IdealMolalSoln.cpp:132
Cantera::IdealMolalSoln::IMS_X_o_cutoff_
doublereal IMS_X_o_cutoff_
value of the solute mole fraction that centers the cutoff polynomials for the cutoff =1 process;
Definition: IdealMolalSoln.h:480
Cantera::IdealMolalSoln::getMolalityActivityCoefficients
virtual void getMolalityActivityCoefficients(doublereal *acMolality) const
Definition: IdealMolalSoln.cpp:238
Cantera::IdealMolalSoln::intEnergy_mole
virtual doublereal intEnergy_mole() const
Molar internal energy of the solution: Units: J/kmol.
Definition: IdealMolalSoln.cpp:99
Cantera::PDSS::molarVolume
virtual doublereal molarVolume() const
Return the molar volume at standard state.
Definition: PDSS.cpp:72
Cantera::IdealMolalSoln::getPartialMolarVolumes
virtual void getPartialMolarVolumes(doublereal *vbar) const
Definition: IdealMolalSoln.cpp:335
Cantera::XML_Node
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
Cantera::caseInsensitiveEquals
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
Definition: stringUtils.cpp:268
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::ThermoPhase::initThermoFile
virtual void initThermoFile(const std::string &inputFile, const std::string &id)
Definition: ThermoPhase.cpp:1064
ctml.h
Cantera::IdealMolalSoln::getPartialMolarEntropies
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
Definition: IdealMolalSoln.cpp:306
Cantera::IdealMolalSoln::IMS_slopegCut_
doublereal IMS_slopegCut_
Parameter in the polyExp cutoff treatment.
Definition: IdealMolalSoln.h:494
Cantera::IdealMolalSoln::IdealMolalSoln
IdealMolalSoln()
Constructor.
Definition: IdealMolalSoln.cpp:28
stringUtils.h
Cantera::IdealMolalSoln::m_speciesMolarVolume
vector_fp m_speciesMolarVolume
Species molar volume .
Definition: IdealMolalSoln.h:456
Cantera::MolalityVPSSTP::m_molalities
vector_fp m_molalities
Current value of the molalities of the species in the phase.
Definition: MolalityVPSSTP.h:605
Cantera::IdealMolalSoln::getActivityConcentrations
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
Definition: IdealMolalSoln.cpp:176
Cantera::IdealMolalSoln::IMS_lnActCoeffMolal_
vector_fp IMS_lnActCoeffMolal_
Logarithm of the molal activity coefficients.
Definition: IdealMolalSoln.h:476
Cantera::IdealMolalSoln::getActivities
virtual void getActivities(doublereal *ac) const
Definition: IdealMolalSoln.cpp:209
Cantera::Phase::nSpecies
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:285
IdealMolalSoln.h
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::IdealMolalSoln::setDensity
virtual void setDensity(const doublereal rho)
Overridden setDensity() function is necessary because the density is not an independent variable.
Definition: IdealMolalSoln.cpp:142
Cantera::IdealMolalSoln::setStandardConcentrationModel
void setStandardConcentrationModel(const std::string &model)
Set the standard concentration model.
Definition: IdealMolalSoln.cpp:461
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::Units
A representation of the units associated with a dimensional quantity.
Definition: Units.h:29
Cantera::IdealMolalSoln::setMolarDensity
virtual void setMolarDensity(const doublereal rho)
Overridden setMolarDensity() function is necessary because the density is not an independent variable...
Definition: IdealMolalSoln.cpp:153
Cantera::AnyMap
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:359
Cantera::IdealMolalSoln::cp_mole
virtual doublereal cp_mole() const
Molar heat capacity of the solution at constant pressure. Units: J/kmol/K.
Definition: IdealMolalSoln.cpp:117
Cantera::IdealMolalSoln::IMS_gamma_o_min_
doublereal IMS_gamma_o_min_
gamma_o value for the cutoff process at the zero solvent point
Definition: IdealMolalSoln.h:483
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::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::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::IdealMolalSoln::m_tmpV
vector_fp m_tmpV
vector of size m_kk, used as a temporary holding area.
Definition: IdealMolalSoln.h:470
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::IdealMolalSoln::getPartialMolarCp
virtual void getPartialMolarCp(doublereal *cpbar) const
Partial molar heat capacity of the solution:. UnitsL J/kmol/K.
Definition: IdealMolalSoln.cpp:340
Cantera::IdealMolalSoln::IMS_gamma_k_min_
doublereal IMS_gamma_k_min_
gamma_k minimum for the cutoff process at the zero solvent point
Definition: IdealMolalSoln.h:486
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::IdealMolalSoln::thermalExpansionCoeff
virtual doublereal thermalExpansionCoeff() const
The thermal expansion coefficient. Units: 1/K.
Definition: IdealMolalSoln.cpp:137