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
20#include "cantera/thermo/PDSS.h"
21#include "cantera/base/ctml.h"
23
24#include <iostream>
25
26namespace {
27double X_o_cutoff_default = 0.20;
28double gamma_o_min_default = 0.00001;
29double gamma_k_min_default = 10.0;
30double slopefCut_default = 0.6;
31double slopegCut_default = 0.0;
32double cCut_default = .05;
33}
34
35namespace Cantera
36{
37
38IdealMolalSoln::IdealMolalSoln(const std::string& inputFile,
39 const std::string& id_) :
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
61IdealMolalSoln::IdealMolalSoln(XML_Node& root, const std::string& id_) :
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
84{
86 return mean_X(m_tmpV);
87}
88
90{
92 return mean_X(m_tmpV);
93}
94
96{
98 return mean_X(m_tmpV);
99}
100
102{
104 return mean_X(m_tmpV);
105}
106
107doublereal IdealMolalSoln::cp_mole() const
108{
110 return mean_X(m_tmpV);
111}
112
113// ------- Mechanical Equation of State Properties ------------------------
114
116{
118 doublereal dd = meanMolecularWeight() / mean_X(m_tmpV);
120}
121
123{
124 return 0.0;
125}
126
128{
129 return 0.0;
130}
131
132// ------- Activities and Activity Concentrations
133
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
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
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
177void IdealMolalSoln::getActivities(doublereal* ac) const
178{
180
181 // Update the molality array, m_molalities(). This requires an update due to
182 // mole fractions
183 if (IMS_typeCutoff_ == 0) {
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
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
206void 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 {
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
228void 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.
234
235 // Update the molality array, m_molalities(). This requires an update due to
236 // mole fractions
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.
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
267{
268 getEnthalpy_RT(hbar);
269 for (size_t k = 0; k < m_kk; k++) {
270 hbar[k] *= RT();
271 }
272}
273
275{
276 getEntropy_R(sbar);
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.
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
303void IdealMolalSoln::getPartialMolarVolumes(doublereal* vbar) const
304{
305 getStandardVolumes(vbar);
306}
307
308void 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
320bool 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
331void 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
391{
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) {
413 }
414 setMoleFSolventMin(1.0E-5);
415}
416
418{
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
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
475void 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
492{
493 // Calculate the molalities. Currently, the molalities may not be current
494 // with respect to the contents of the State objects' data.
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 }
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
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 /
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 /
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}
ThermoPhase object for the ideal molal equation of state (see Thermodynamic Properties and class Idea...
Declarations for the virtual base class PDSS (pressure dependent standard state) which handles calcul...
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
A map of string keys to values whose type can vary at runtime.
Definition: AnyMap.h:399
size_t size() const
Returns the number of elements in this map.
Definition: AnyMap.h:590
bool hasKey(const std::string &key) const
Returns true if the map contains an item named key.
Definition: AnyMap.cpp:1406
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:61
void calcIMSCutoffParams_()
Calculate parameters for cutoff treatments of activity coefficients.
IdealMolalSoln(const std::string &inputFile="", const std::string &id="")
Constructor for phase initialization.
void setCutoffModel(const std::string &model)
Set cutoff model. Must be one of 'none', 'poly', or 'polyExp'.
virtual bool addSpecies(shared_ptr< Species > spec)
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
doublereal IMS_slopegCut_
Parameter in the polyExp cutoff treatment.
int IMS_typeCutoff_
Cutoff type.
virtual doublereal cp_mole() const
Molar heat capacity of the solution at constant pressure. Units: J/kmol/K.
virtual void getMolalityActivityCoefficients(doublereal *acMolality) const
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
doublereal IMS_slopefCut_
Parameter in the polyExp cutoff treatment.
virtual doublereal enthalpy_mole() const
Molar enthalpy of the solution. Units: J/kmol.
doublereal IMS_X_o_cutoff_
value of the solute mole fraction that centers the cutoff polynomials for the cutoff =1 process;
virtual void getPartialMolarVolumes(doublereal *vbar) const
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations.
virtual doublereal thermalExpansionCoeff() const
The thermal expansion coefficient. Units: 1/K.
virtual void getPartialMolarCp(doublereal *cpbar) const
Partial molar heat capacity of the solution:. UnitsL J/kmol/K.
vector_fp m_speciesMolarVolume
Species molar volume .
virtual doublereal entropy_mole() const
Molar entropy of the solution. Units: J/kmol/K.
doublereal IMS_gamma_o_min_
gamma_o value for the cutoff process at the zero solvent point
int m_formGC
The standard concentrations can have one of three different forms: 0 = 'unity', 1 = 'molar_volume',...
virtual doublereal gibbs_mole() const
Molar Gibbs function for the solution: Units J/kmol.
vector_fp IMS_lnActCoeffMolal_
Logarithm of the molal activity coefficients.
virtual Units standardConcentrationUnits() const
Returns the units of the "standard concentration" for this phase.
doublereal IMS_gamma_k_min_
gamma_k minimum for the cutoff process at the zero solvent point
void setStandardConcentrationModel(const std::string &model)
Set the standard concentration model.
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials: Units: J/kmol.
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id="")
Import and initialize a ThermoPhase object using an XML tree.
void s_updateIMS_lnMolalityActCoeff() const
This function will be called to update the internally stored natural logarithm of the molality activi...
virtual void getActivities(doublereal *ac) const
vector_fp m_tmpV
vector of size m_kk, used as a temporary holding area.
virtual doublereal intEnergy_mole() const
Molar internal energy of the solution: Units: J/kmol.
void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
virtual doublereal isothermalCompressibility() const
The isothermal compressibility. Units: 1/Pa.
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
virtual bool addSpecies(shared_ptr< Species > spec)
void setMoleFSolventMin(doublereal xmolSolventMIN)
Sets the minimum mole fraction in the molality formulation.
void calcMolalities() const
Calculates the molality of all species and stores the result internally.
vector_fp m_molalities
Current value of the molalities of the species in the phase.
virtual doublereal molarVolume() const
Return the molar volume at standard state.
Definition: PDSS.cpp:72
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition: Phase.cpp:698
doublereal mean_X(const doublereal *const Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
Definition: Phase.cpp:717
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:273
size_t m_kk
Number of species in the phase.
Definition: Phase.h:943
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
Definition: Phase.h:638
doublereal meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition: Phase.h:751
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition: Phase.cpp:548
doublereal RT() const
Return the Gas Constant multiplied by the current temperature.
Definition: ThermoPhase.h:782
void initThermoFile(const std::string &inputFile, const std::string &id)
virtual void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object using an XML tree.
AnyMap m_input
Data supplied via setParameters.
Definition: ThermoPhase.h:1898
virtual void getParameters(int &n, doublereal *const c) const
Get the equation of state parameters in a vector.
A representation of the units associated with a dimensional quantity.
Definition: Units.h:30
virtual void _updateStandardStateThermo() const
Updates the standard state thermodynamic functions at the current T and P of the solution.
virtual void getStandardVolumes(doublereal *vol) const
Get the molar volumes of the species standard states at the current T and P of the solution.
virtual void getCp_R(doublereal *cpr) const
Get the nondimensional Heat Capacities at constant pressure for the species standard states at the cu...
virtual void getEntropy_R(doublereal *sr) const
Get the array of nondimensional Entropy functions for the standard state species at the current T and...
virtual void getStandardChemPotentials(doublereal *mu) const
Get the array of chemical potentials at unit activity for the species at their standard states at the...
virtual void getEnthalpy_RT(doublereal *hrt) const
Get the nondimensional Enthalpy functions for the species at their standard states at the current T a...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:103
std::string attrib(const std::string &attr) const
Function returns the value of an attribute.
Definition: xml.cpp:493
bool hasChild(const std::string &ch) const
Tests whether the current node has a child node with a particular name.
Definition: xml.cpp:529
std::string id() const
Return the id attribute, if present.
Definition: xml.cpp:539
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 ("Cantera Markup Language") is the variant of XML that Cantera uses to store data.
void importPhase(XML_Node &phase, ThermoPhase *th)
Import a phase information into an empty ThermoPhase object.
Namespace for the Cantera kernel.
Definition: AnyMap.h:29
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
bool caseInsensitiveEquals(const std::string &input, const std::string &test)
Case insensitive equality predicate.
const double SmallNumber
smallest number to compare to zero.
Definition: ct_defs.h:153
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition: ct_defs.h:113
Contains declarations for string manipulation functions within Cantera.