Cantera 2.6.0

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