Cantera  4.0.0a1
Loading...
Searching...
No Matches
IdealSolidSolnPhase.cpp
Go to the documentation of this file.
1/**
2 * @file IdealSolidSolnPhase.cpp Implementation file for an ideal solid
3 * solution model with incompressible thermodynamics (see @ref
4 * thermoprops and @link Cantera::IdealSolidSolnPhase
5 * IdealSolidSolnPhase@endlink).
6 */
7
8// This file is part of Cantera. See License.txt in the top-level directory or
9// at https://cantera.org/license.txt for license and copyright information.
10
16
17namespace Cantera
18{
19
20IdealSolidSolnPhase::IdealSolidSolnPhase(const string& inputFile, const string& id_)
21{
22 initThermoFile(inputFile, id_);
23}
24
25// Molar Thermodynamic Properties of the Solution
26
28{
29 return GasConstant * (mean_X(entropy_R_ref()) - sum_xlogx());
30}
31
33{
34 double Pv = (pressure() - m_Pref)/molarDensity();
35 return RT() * (mean_X(gibbs_RT_ref()) + sum_xlogx()) + Pv;
36}
37
39{
40 return GasConstant * mean_X(cp_R_ref());
41}
42
43// Mechanical Equation of State
44
46{
47 // Calculate the molarVolume of the solution (m**3 kmol-1)
48 double v_mol = mean_X(m_speciesMolarVolume);
49
50 // Set the density in the parent object directly, by calling the
51 // Phase::assignDensity() function.
53}
54
56{
57 m_Pcurrent = p;
59}
60
62{
65}
66
67// Chemical Potentials and Activities
68
70{
71 if (m_formGC == 0) {
72 return Units(1.0); // dimensionless
73 } else {
74 // kmol/m^3 for bulk phases
75 return Units(1.0, 0, -static_cast<double>(nDim()), 0, 0, 0, 1);
76 }
77}
78
80{
82 switch (m_formGC) {
83 case 0:
84 break;
85 case 1:
86 for (size_t k = 0; k < m_kk; k++) {
87 c[k] /= m_speciesMolarVolume[k];
88 }
89 break;
90 case 2:
91 for (size_t k = 0; k < m_kk; k++) {
92 c[k] /= m_speciesMolarVolume[m_kk-1];
93 }
94 break;
95 }
96}
97
99{
100 switch (m_formGC) {
101 case 0:
102 return 1.0;
103 case 1:
104 return 1.0 / m_speciesMolarVolume[k];
105 case 2:
106 return 1.0/m_speciesMolarVolume[m_kk-1];
107 }
108 return 0.0;
109}
110
112{
113 checkArraySize("IdealSolidSolnPhase::getActivityCoefficients", ac.size(), m_kk);
114 for (size_t k = 0; k < m_kk; k++) {
115 ac[k] = 1.0;
116 }
117}
118
119void IdealSolidSolnPhase::getChemPotentials(span<double> mu) const
120{
121 checkArraySize("IdealSolidSolnPhase::getChemPotentials", mu.size(), m_kk);
122 double delta_p = m_Pcurrent - m_Pref;
123 auto g_RT = gibbs_RT_ref();
124 for (size_t k = 0; k < m_kk; k++) {
125 double xx = std::max(SmallNumber, moleFraction(k));
126 mu[k] = RT() * (g_RT[k] + log(xx))
127 + delta_p * m_speciesMolarVolume[k];
128 }
129}
130
131// Partial Molar Properties
132
134{
135 checkArraySize("IdealSolidSolnPhase::getPartialMolarEnthalpies", hbar.size(), m_kk);
136 auto _h = enthalpy_RT_ref();
137 double delta_p = m_Pcurrent - m_Pref;
138 for (size_t k = 0; k < m_kk; k++) {
139 hbar[k] = _h[k]*RT() + delta_p * m_speciesMolarVolume[k];
140 }
141 // scale(_h.begin(), _h.end(), hbar, RT());
142}
143
145{
146 checkArraySize("IdealSolidSolnPhase::getPartialMolarEntropies", sbar.size(), m_kk);
147 auto _s = entropy_R_ref();
148 for (size_t k = 0; k < m_kk; k++) {
149 double xx = std::max(SmallNumber, moleFraction(k));
150 sbar[k] = GasConstant * (_s[k] - log(xx));
151 }
152}
153
154void IdealSolidSolnPhase::getPartialMolarCp(span<double> cpbar) const
155{
156 getCp_R(cpbar);
157 for (size_t k = 0; k < m_kk; k++) {
158 cpbar[k] *= GasConstant;
159 }
160}
161
163{
164 getStandardVolumes(vbar);
165}
166
167// Properties of the Standard State of the Species in the Solution
168
170{
171 checkArraySize("IdealSolidSolnPhase::getStandardChemPotentials", g0.size(), m_kk);
172 auto gibbsrt = gibbs_RT_ref();
173 double delta_p = (m_Pcurrent - m_Pref);
174 for (size_t k = 0; k < m_kk; k++) {
175 g0[k] = RT() * gibbsrt[k] + delta_p * m_speciesMolarVolume[k];
176 }
177}
178
179void IdealSolidSolnPhase::getGibbs_RT(span<double> grt) const
180{
181 checkArraySize("IdealSolidSolnPhase::getGibbs_RT", grt.size(), m_kk);
182 auto gibbsrt = gibbs_RT_ref();
183 double delta_prt = (m_Pcurrent - m_Pref)/ RT();
184 for (size_t k = 0; k < m_kk; k++) {
185 grt[k] = gibbsrt[k] + delta_prt * m_speciesMolarVolume[k];
186 }
187}
188
189void IdealSolidSolnPhase::getEnthalpy_RT(span<double> hrt) const
190{
191 checkArraySize("IdealSolidSolnPhase::getEnthalpy_RT", hrt.size(), m_kk);
192 auto _h = enthalpy_RT_ref();
193 double delta_prt = (m_Pcurrent - m_Pref) / RT();
194 for (size_t k = 0; k < m_kk; k++) {
195 hrt[k] = _h[k] + delta_prt * m_speciesMolarVolume[k];
196 }
197}
198
199void IdealSolidSolnPhase::getEntropy_R(span<double> sr) const
200{
201 checkArraySize("IdealSolidSolnPhase::getEntropy_R", sr.size(), m_kk);
202 auto _s = entropy_R_ref();
203 copy(_s.begin(), _s.end(), sr.begin());
204}
205
206void IdealSolidSolnPhase::getIntEnergy_RT(span<double> urt) const
207{
208 checkArraySize("IdealSolidSolnPhase::getIntEnergy_RT", urt.size(), m_kk);
209 auto _h = enthalpy_RT_ref();
210 double prefrt = m_Pref / RT();
211 for (size_t k = 0; k < m_kk; k++) {
212 urt[k] = _h[k] - prefrt * m_speciesMolarVolume[k];
213 }
214}
215
216void IdealSolidSolnPhase::getCp_R(span<double> cpr) const
217{
218 checkArraySize("IdealSolidSolnPhase::getCp_R", cpr.size(), m_kk);
219 auto _cpr = cp_R_ref();
220 copy(_cpr.begin(), _cpr.end(), cpr.begin());
221}
222
223void IdealSolidSolnPhase::getStandardVolumes(span<double> vol) const
224{
225 checkArraySize("IdealSolidSolnPhase::getStandardVolumes", vol.size(), m_kk);
226 copy(m_speciesMolarVolume.begin(), m_speciesMolarVolume.end(), vol.begin());
227}
228
229// Thermodynamic Values for the Species Reference States
230
231void IdealSolidSolnPhase::getEnthalpy_RT_ref(span<double> hrt) const
232{
233 checkArraySize("IdealSolidSolnPhase::getEnthalpy_RT_ref", hrt.size(), m_kk);
235 for (size_t k = 0; k != m_kk; k++) {
236 hrt[k] = m_h0_RT[k];
237 }
238}
239
240void IdealSolidSolnPhase::getGibbs_RT_ref(span<double> grt) const
241{
242 checkArraySize("IdealSolidSolnPhase::getGibbs_RT_ref", grt.size(), m_kk);
244 for (size_t k = 0; k != m_kk; k++) {
245 grt[k] = m_g0_RT[k];
246 }
247}
248
249void IdealSolidSolnPhase::getGibbs_ref(span<double> g) const
250{
251 checkArraySize("IdealSolidSolnPhase::getGibbs_ref", g.size(), m_kk);
253 double tmp = RT();
254 for (size_t k = 0; k != m_kk; k++) {
255 g[k] = tmp * m_g0_RT[k];
256 }
257}
258
260{
261 checkArraySize("IdealSolidSolnPhase::getIntEnergy_RT_ref", urt.size(), m_kk);
262 auto _h = enthalpy_RT_ref();
263 double prefrt = m_Pref / RT();
264 for (size_t k = 0; k < m_kk; k++) {
265 urt[k] = _h[k] - prefrt * m_speciesMolarVolume[k];
266 }
267}
268
269void IdealSolidSolnPhase::getEntropy_R_ref(span<double> er) const
270{
271 checkArraySize("IdealSolidSolnPhase::getEntropy_R_ref", er.size(), m_kk);
273 for (size_t k = 0; k != m_kk; k++) {
274 er[k] = m_s0_R[k];
275 }
276}
277
278void IdealSolidSolnPhase::getCp_R_ref(span<double> cpr) const
279{
280 checkArraySize("IdealSolidSolnPhase::getCp_R_ref", cpr.size(), m_kk);
282 for (size_t k = 0; k != m_kk; k++) {
283 cpr[k] = m_cp0_R[k];
284 }
285}
286
287span<const double> IdealSolidSolnPhase::enthalpy_RT_ref() const
288{
290 return m_h0_RT;
291}
292
293span<const double> IdealSolidSolnPhase::entropy_R_ref() const
294{
296 return m_s0_R;
297}
298
299// Utility Functions
300
301bool IdealSolidSolnPhase::addSpecies(shared_ptr<Species> spec)
302{
303 bool added = ThermoPhase::addSpecies(spec);
304 if (added) {
305 if (m_kk == 1) {
306 // Obtain the reference pressure by calling the ThermoPhase function
307 // refPressure, which in turn calls the species thermo reference
308 // pressure function of the same name.
310 }
311
312 m_h0_RT.push_back(0.0);
313 m_g0_RT.push_back(0.0);
314 m_expg0_RT.push_back(0.0);
315 m_cp0_R.push_back(0.0);
316 m_s0_R.push_back(0.0);
317 m_pp.push_back(0.0);
318 if (spec->input.hasKey("equation-of-state")) {
319 auto& eos = spec->input["equation-of-state"].getMapWhere("model", "constant-volume");
320 double mv;
321 if (eos.hasKey("density")) {
322 mv = molecularWeight(m_kk-1) / eos.convert("density", "kg/m^3");
323 } else if (eos.hasKey("molar-density")) {
324 mv = 1.0 / eos.convert("molar-density", "kmol/m^3");
325 } else if (eos.hasKey("molar-volume")) {
326 mv = eos.convert("molar-volume", "m^3/kmol");
327 } else {
328 throw CanteraError("IdealSolidSolnPhase::addSpecies",
329 "equation-of-state entry for species '{}' is missing "
330 "'density', 'molar-volume', or 'molar-density' "
331 "specification", spec->name);
332 }
333 m_speciesMolarVolume.push_back(mv);
334 } else {
335 throw CanteraError("IdealSolidSolnPhase::addSpecies",
336 "Molar volume not specified for species '{}'", spec->name);
337 }
338 if (ready()) {
339 calcDensity();
340 }
341 }
342 return added;
343}
344
346{
347 if (m_input.hasKey("standard-concentration-basis")) {
348 setStandardConcentrationModel(m_input["standard-concentration-basis"].asString());
349 }
351}
352
354{
356 if (m_formGC == 1) {
357 phaseNode["standard-concentration-basis"] = "species-molar-volume";
358 } else if (m_formGC == 2) {
359 phaseNode["standard-concentration-basis"] = "solvent-molar-volume";
360 }
361}
362
364 AnyMap& speciesNode) const
365{
367 size_t k = speciesIndex(name, true);
368 const auto S = species(k);
369 auto& eosNode = speciesNode["equation-of-state"].getMapWhere(
370 "model", "constant-volume", true);
371 // Output volume information in a form consistent with the input
372 if (S->input.hasKey("equation-of-state")) {
373 auto& eosIn = S->input["equation-of-state"];
374 if (eosIn.hasKey("density")) {
375 eosNode["density"].setQuantity(
376 molecularWeight(k) / m_speciesMolarVolume[k], "kg/m^3");
377 } else if (eosIn.hasKey("molar-density")) {
378 eosNode["molar-density"].setQuantity(1.0 / m_speciesMolarVolume[k],
379 "kmol/m^3");
380 } else {
381 eosNode["molar-volume"].setQuantity(m_speciesMolarVolume[k],
382 "m^3/kmol");
383 }
384 } else {
385 eosNode["molar-volume"].setQuantity(m_speciesMolarVolume[k],
386 "m^3/kmol");
387 }
388}
389
390void IdealSolidSolnPhase::setToEquilState(span<const double> mu_RT)
391{
392 checkArraySize("IdealSolidSolnPhase::setToEquilState", mu_RT.size(), m_kk);
393 auto grt = gibbs_RT_ref();
394
395 // Within the method, we protect against inf results if the exponent is too
396 // high.
397 //
398 // If it is too low, we set the partial pressure to zero. This capability is
399 // needed by the elemental potential method.
400 double pres = 0.0;
401 double m_p0 = refPressure();
402 for (size_t k = 0; k < m_kk; k++) {
403 double tmp = -grt[k] + mu_RT[k];
404 if (tmp < -600.) {
405 m_pp[k] = 0.0;
406 } else if (tmp > 500.0) {
407 // Protect against inf results if the exponent is too high
408 double tmp2 = tmp / 500.;
409 tmp2 *= tmp2;
410 m_pp[k] = m_p0 * exp(500.) * tmp2;
411 } else {
412 m_pp[k] = m_p0 * exp(tmp);
413 }
414 pres += m_pp[k];
415 }
416 // set state
418 setPressure(pres);
419}
420
422{
423 if (caseInsensitiveEquals(model, "unity")) {
424 m_formGC = 0;
425 } else if (caseInsensitiveEquals(model, "species-molar-volume")
426 || caseInsensitiveEquals(model, "molar_volume")) {
427 m_formGC = 1;
428 } else if (caseInsensitiveEquals(model, "solvent-molar-volume")
429 || caseInsensitiveEquals(model, "solvent_volume")) {
430 m_formGC = 2;
431 } else {
432 throw CanteraError("IdealSolidSolnPhase::setStandardConcentrationModel",
433 "Unknown standard concentration model '{}'", model);
434 }
435}
436
438{
439 return m_speciesMolarVolume[k];
440}
441
443{
444 checkArraySize("IdealSolidSolnPhase::getSpeciesMolarVolumes", smv.size(), m_kk);
445 copy(m_speciesMolarVolume.begin(), m_speciesMolarVolume.end(), smv.begin());
446}
447
449{
450 double tnow = temperature();
451 if (m_tlast != tnow) {
452
453 // Update the thermodynamic functions of the reference state.
455 m_tlast = tnow;
456 for (size_t k = 0; k < m_kk; k++) {
457 m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
458 }
459 m_tlast = tnow;
460 }
461}
462
463} // end namespace Cantera
Header file for an ideal solid solution model with incompressible thermodynamics (see Thermodynamic P...
Declaration for class Cantera::Species.
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:431
bool hasKey(const string &key) const
Returns true if the map contains an item named key.
Definition AnyMap.cpp:1477
Base class for exceptions thrown by Cantera classes.
void getGibbs_ref(span< double > g) const override
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
void getCp_R(span< double > cpr) const override
Get the nondimensional heat capacity at constant pressure function for the species standard states at...
void getStandardChemPotentials(span< double > mu0) const override
Get the standard state chemical potentials of the species.
void getEntropy_R_ref(span< double > er) const override
Returns the vector of nondimensional entropies of the reference state at the current temperature of t...
void getPartialMolarEnthalpies(span< double > hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
double pressure() const override
Pressure.
vector< double > m_g0_RT
Vector containing the species reference Gibbs functions at T = m_tlast.
void getIntEnergy_RT(span< double > urt) const override
Returns the vector of nondimensional Internal Energies of the standard state species at the current T...
void getSpeciesParameters(const string &name, AnyMap &speciesNode) const override
Get phase-specific parameters of a Species object such that an identical one could be reconstructed a...
vector< double > m_h0_RT
Vector containing the species reference enthalpies at T = m_tlast.
double speciesMolarVolume(int k) const
Report the molar volume of species k.
void getPartialMolarCp(span< double > cpbar) const override
Returns an array of partial molar Heat Capacities at constant pressure of the species in the solution...
vector< double > m_pp
Temporary array used in equilibrium calculations.
double m_Pref
Value of the reference pressure for all species in this phase.
span< const double > enthalpy_RT_ref() const
Returns a reference to the vector of nondimensional enthalpies of the reference state at the current ...
void getActivityCoefficients(span< double > ac) const override
Get the array of species activity coefficients.
void getGibbs_RT(span< double > grt) const override
Get the nondimensional Gibbs function for the species standard states at the current T and P of the s...
void getCp_R_ref(span< double > cprt) const override
Returns the vector of nondimensional constant pressure heat capacities of the reference state at the ...
void getParameters(AnyMap &phaseNode) const override
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
void initThermo() override
Initialize the ThermoPhase object after all species have been set up.
void setPressure(double p) override
Set the pressure at constant temperature.
void getIntEnergy_RT_ref(span< double > urt) const override
Returns the vector of nondimensional internal Energies of the reference state at the current temperat...
void getEnthalpy_RT_ref(span< double > hrt) const override
Returns the vector of nondimensional enthalpies of the reference state at the current temperature of ...
void getEnthalpy_RT(span< double > hrt) const override
Get the array of nondimensional Enthalpy functions for the standard state species at the current T an...
double standardConcentration(size_t k) const override
The standard concentration used to normalize the generalized concentration.
void setStandardConcentrationModel(const string &model)
Set the form for the standard and generalized concentrations.
void setToEquilState(span< const double > mu_RT) override
This method is used by the ChemEquil equilibrium solver.
void getEntropy_R(span< double > sr) const override
Get the nondimensional Entropies for the species standard states at the current T and P of the soluti...
vector< double > m_s0_R
Vector containing the species reference entropies at T = m_tlast.
double entropy_mole() const override
Molar entropy of the solution.
int m_formGC
The standard concentrations can have one of three different forms: 0 = 'unity', 1 = 'species-molar-vo...
vector< double > m_speciesMolarVolume
Vector of molar volumes for each species in the solution.
void getGibbs_RT_ref(span< double > grt) const override
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
span< const double > cp_R_ref() const
Returns a reference to the vector of nondimensional enthalpies of the reference state at the current ...
double cp_mole() const override
Molar heat capacity of the solution at at constant pressure and composition [J/kmol/K].
span< const double > entropy_R_ref() const
Returns a reference to the vector of nondimensional enthalpies of the reference state at the current ...
void getSpeciesMolarVolumes(span< double > smv) const
Fill in a return vector containing the species molar volumes.
void getPartialMolarVolumes(span< double > vbar) const override
returns an array of partial molar volumes of the species in the solution.
Units standardConcentrationUnits() const override
Returns the units of the "standard concentration" for this phase.
IdealSolidSolnPhase(const string &infile="", const string &id="")
Construct and initialize an IdealSolidSolnPhase ThermoPhase object directly from an input file.
void getStandardVolumes(span< double > vol) const override
Get the molar volumes of the species standard states at the current T and P of the solution.
void compositionChanged() override
Apply changes to the state which are needed after the composition changes.
void getPartialMolarEntropies(span< double > sbar) const override
Returns an array of partial molar entropies of the species in the solution.
double gibbs_mole() const override
Molar Gibbs free energy of the solution.
vector< double > m_cp0_R
Vector containing the species reference constant pressure heat capacities at T = m_tlast.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
span< const double > gibbs_RT_ref() const
Returns a reference to the vector of nondimensional enthalpies of the reference state at the current ...
virtual void _updateThermo() const
This function gets called for every call to functions in this class.
void getChemPotentials(span< double > mu) const override
Get the species chemical potentials.
void getActivityConcentrations(span< double > c) const override
This method returns the array of generalized concentrations.
vector< double > m_expg0_RT
Vector containing the species reference exp(-G/RT) functions at T = m_tlast.
double m_Pcurrent
m_Pcurrent = The current pressure Since the density isn't a function of pressure, but only of the mol...
virtual void calcDensity()
Calculate the density of the mixture using the partial molar volumes and mole fractions as input.
virtual void update(double T, span< double > cp_R, span< double > h_RT, span< double > s_R) const
Compute the reference-state properties for all species.
void getMoleFractions(span< double > x) const
Get the species mole fraction vector.
Definition Phase.cpp:441
virtual double molarDensity() const
Molar density (kmol/m^3).
Definition Phase.cpp:587
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition Phase.cpp:608
size_t m_kk
Number of species in the phase.
Definition Phase.h:875
size_t nDim() const
Returns the number of spatial dimensions (1, 2, or 3)
Definition Phase.h:569
size_t speciesIndex(const string &name, bool raise=true) const
Returns the index of a species named 'name' within the Phase object.
Definition Phase.cpp:127
double temperature() const
Temperature (K).
Definition Phase.h:585
double meanMolecularWeight() const
The mean molecular weight. Units: (kg/kmol)
Definition Phase.h:676
double sum_xlogx() const
Evaluate .
Definition Phase.cpp:633
double mean_X(span< const double > Q) const
Evaluate the mole-fraction-weighted mean of an array Q.
Definition Phase.cpp:627
double moleFraction(size_t k) const
Return the mole fraction of a single species.
Definition Phase.cpp:447
virtual void compositionChanged()
Apply changes to the state which are needed after the composition changes.
Definition Phase.cpp:925
virtual void setMoleFractions(span< const double > x)
Set the mole fractions to the specified values.
Definition Phase.cpp:283
virtual bool ready() const
Returns a bool indicating whether the object is ready for use.
Definition Phase.cpp:905
double molecularWeight(size_t k) const
Molecular weight of species k.
Definition Phase.cpp:388
shared_ptr< Species > species(const string &name) const
Return the Species object for the named species.
Definition Phase.cpp:881
string name() const
Return the name of the phase.
Definition Phase.cpp:20
virtual void getParameters(AnyMap &phaseNode) const
Store the parameters of a ThermoPhase object such that an identical one could be reconstructed using ...
double RT() const
Return the Gas Constant multiplied by the current temperature.
double m_tlast
last value of the temperature processed by reference state
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
void initThermoFile(const string &inputFile, const string &id)
Initialize a ThermoPhase object using an input file.
virtual void getSpeciesParameters(const string &name, AnyMap &speciesNode) const
Get phase-specific parameters of a Species object such that an identical one could be reconstructed a...
MultiSpeciesThermo m_spthermo
Pointer to the calculation manager for species reference-state thermodynamic properties.
virtual double refPressure() const
Returns the reference pressure in Pa.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
AnyMap m_input
Data supplied via setParameters.
A representation of the units associated with a dimensional quantity.
Definition Units.h:35
bool caseInsensitiveEquals(const string &input, const string &test)
Case insensitive equality predicate.
const double GasConstant
Universal Gas Constant [J/kmol/K].
Definition ct_defs.h:123
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const double SmallNumber
smallest number to compare to zero.
Definition ct_defs.h:161
void checkArraySize(const char *procedure, size_t available, size_t required)
Wrapper for throwing ArraySizeError.
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...