Cantera  3.2.0a4
Loading...
Searching...
No Matches
LatticeSolidPhase.cpp
Go to the documentation of this file.
1/**
2 * @file LatticeSolidPhase.cpp
3 * Definitions for a simple thermodynamics model of a bulk solid phase
4 * derived from ThermoPhase,
5 * assuming an ideal solution model based on a lattice of solid atoms
6 * (see @ref thermoprops and class @link Cantera::LatticeSolidPhase LatticeSolidPhase@endlink).
7 */
8
9// This file is part of Cantera. See License.txt in the top-level directory or
10// at https://cantera.org/license.txt for license and copyright information.
11
18
19#include <boost/algorithm/string.hpp>
20
21namespace ba = boost::algorithm;
22
23namespace Cantera
24{
25
27{
28 warn_deprecated("class LatticeSolidPhase", "To be removed after Cantera 3.2. No "
29 "known usage exists, and the model does not satisfy several basic thermodynamic"
30 "identities. See https://github.com/Cantera/cantera/issues/1310.");
31}
32
33double LatticeSolidPhase::minTemp(size_t k) const
34{
35 if (k != npos) {
36 for (size_t n = 0; n < m_lattice.size(); n++) {
37 if (lkstart_[n+1] < k) {
38 return m_lattice[n]->minTemp(k-lkstart_[n]);
39 }
40 }
41 }
42 double mm = 0;
43 for (auto& lattice : m_lattice) {
44 mm = std::max(mm, lattice->minTemp());
45 }
46 return mm;
47}
48
49double LatticeSolidPhase::maxTemp(size_t k) const
50{
51 if (k != npos) {
52 for (size_t n = 0; n < m_lattice.size(); n++) {
53 if (lkstart_[n+1] < k) {
54 return (m_lattice[n])->maxTemp(k - lkstart_[n]);
55 }
56 }
57 }
58 double mm = BigNumber;
59 for (auto& lattice : m_lattice) {
60 mm = std::min(mm, lattice->maxTemp());
61 }
62 return mm;
63}
64
66{
67 return m_lattice[0]->refPressure();
68}
69
71{
73 double sum = 0.0;
74 for (size_t n = 0; n < m_lattice.size(); n++) {
75 sum += theta_[n] * m_lattice[n]->enthalpy_mole();
76 }
77 return sum;
78}
79
81{
83 double sum = 0.0;
84 for (size_t n = 0; n < m_lattice.size(); n++) {
85 sum += theta_[n] * m_lattice[n]->intEnergy_mole();
86 }
87 return sum;
88}
89
91{
93 double sum = 0.0;
94 for (size_t n = 0; n < m_lattice.size(); n++) {
95 sum += theta_[n] * m_lattice[n]->entropy_mole();
96 }
97 return sum;
98}
99
101{
103 double sum = 0.0;
104 for (size_t n = 0; n < m_lattice.size(); n++) {
105 sum += theta_[n] * m_lattice[n]->gibbs_mole();
106 }
107 return sum;
108}
109
111{
113 double sum = 0.0;
114 for (size_t n = 0; n < m_lattice.size(); n++) {
115 sum += theta_[n] * m_lattice[n]->cp_mole();
116 }
117 return sum;
118}
119
121{
122 return Units(1.0);
123}
124
126{
128 size_t strt = 0;
129 for (size_t n = 0; n < m_lattice.size(); n++) {
130 m_lattice[n]->getMoleFractions(c+strt);
131 strt += m_lattice[n]->nSpecies();
132 }
133}
134
136{
137 for (size_t k = 0; k < m_kk; k++) {
138 ac[k] = 1.0;
139 }
140}
141
143{
144 return 1.0;
145}
146
148{
149 return 0.0;
150}
151
153{
154 m_press = p;
155 for (size_t n = 0; n < m_lattice.size(); n++) {
156 m_lattice[n]->setPressure(m_press);
157 }
158 calcDensity();
159}
160
162{
163 double sum = 0.0;
164 for (size_t n = 0; n < m_lattice.size(); n++) {
165 sum += theta_[n] * m_lattice[n]->density();
166 }
168 return sum;
169}
170
171void LatticeSolidPhase::setMoleFractions(const double* const x)
172{
173 size_t strt = 0;
174 for (size_t n = 0; n < m_lattice.size(); n++) {
175 size_t nsp = m_lattice[n]->nSpecies();
176 m_lattice[n]->setMoleFractions(x + strt);
177 strt += nsp;
178 }
179 for (size_t k = 0; k < strt; k++) {
180 m_x[k] = x[k] / m_lattice.size();
181 }
183 calcDensity();
184}
185
186void LatticeSolidPhase::getMoleFractions(double* const x) const
187{
188 size_t strt = 0;
189 // the ifdef block should be the way we calculate this.!!!!!
191 for (size_t n = 0; n < m_lattice.size(); n++) {
192 size_t nsp = m_lattice[n]->nSpecies();
193 double sum = 0.0;
194 for (size_t k = 0; k < nsp; k++) {
195 sum += (x + strt)[k];
196 }
197 for (size_t k = 0; k < nsp; k++) {
198 (x + strt)[k] /= sum;
199 }
200
201 // At this point we can check against the mole fraction vector of the
202 // underlying LatticePhase objects and get the same answer.
203 m_lattice[n]->getMoleFractions(&m_x[strt]);
204 for (size_t k = 0; k < nsp; k++) {
205 if (fabs((x + strt)[k] - m_x[strt+k]) > 1.0E-14) {
206 throw CanteraError("LatticeSolidPhase::getMoleFractions",
207 "internal error");
208 }
209 }
210 strt += nsp;
211 }
212}
213
215{
217 size_t strt = 0;
218 for (size_t n = 0; n < m_lattice.size(); n++) {
219 size_t nlsp = m_lattice[n]->nSpecies();
220 m_lattice[n]->getChemPotentials(mu+strt);
221 strt += nlsp;
222 }
223}
224
226{
228 size_t strt = 0;
229 for (size_t n = 0; n < m_lattice.size(); n++) {
230 size_t nlsp = m_lattice[n]->nSpecies();
231 m_lattice[n]->getPartialMolarEnthalpies(hbar + strt);
232 strt += nlsp;
233 }
234}
235
237{
239 size_t strt = 0;
240 for (size_t n = 0; n < m_lattice.size(); n++) {
241 size_t nlsp = m_lattice[n]->nSpecies();
242 m_lattice[n]->getPartialMolarEntropies(sbar + strt);
243 strt += nlsp;
244 }
245}
246
248{
250 size_t strt = 0;
251 for (size_t n = 0; n < m_lattice.size(); n++) {
252 size_t nlsp = m_lattice[n]->nSpecies();
253 m_lattice[n]->getPartialMolarCp(cpbar + strt);
254 strt += nlsp;
255 }
256}
257
259{
261 size_t strt = 0;
262 for (size_t n = 0; n < m_lattice.size(); n++) {
263 size_t nlsp = m_lattice[n]->nSpecies();
264 m_lattice[n]->getPartialMolarVolumes(vbar + strt);
265 strt += nlsp;
266 }
267}
268
270{
272 size_t strt = 0;
273 for (size_t n = 0; n < m_lattice.size(); n++) {
274 m_lattice[n]->getStandardChemPotentials(mu0+strt);
275 strt += m_lattice[n]->nSpecies();
276 }
277}
278
280{
282 for (size_t n = 0; n < m_lattice.size(); n++) {
283 m_lattice[n]->getGibbs_RT_ref(grt + lkstart_[n]);
284 }
285}
286
288{
290 for (size_t k = 0; k < m_kk; k++) {
291 g[k] *= RT();
292 }
293}
294
296 const AnyMap& rootNode)
297{
298 ThermoPhase::setParameters(phaseNode, rootNode);
299 m_rootNode = rootNode;
300}
301
303{
304 if (m_input.hasKey("composition")) {
305 Composition composition = m_input["composition"].asMap<double>();
306 for (auto& [name, stoich] : composition) {
307 AnyMap& node = m_rootNode["phases"].getMapWhere("name", name);
309 }
310 setLatticeStoichiometry(composition);
311 }
312
313 setMoleFractions(m_x.data());
315}
316
318{
320 AnyMap composition;
321 for (size_t i = 0; i < m_lattice.size(); i++) {
322 composition[m_lattice[i]->name()] = theta_[i];
323 }
324 phaseNode["composition"] = std::move(composition);
325
326 // Remove fields not used in this model
327 phaseNode.erase("species");
328 vector<string> elements;
329 for (auto& el : phaseNode["elements"].asVector<string>()) {
330 if (!ba::starts_with(el, "LC_")) {
331 elements.push_back(el);
332 }
333 }
334 phaseNode["elements"] = elements;
335}
336
338 AnyMap& speciesNode) const
339{
340 // Use child lattice phases to determine species parameters so that these
341 // are set consistently
342 for (const auto& phase : m_lattice) {
343 if (phase->speciesIndex(name) != npos) {
344 phase->getSpeciesParameters(name, speciesNode);
345 break;
346 }
347 }
348}
349
350bool LatticeSolidPhase::addSpecies(shared_ptr<Species> spec)
351{
352 // Species are added from component phases in addLattice()
353 return false;
354}
355
356void LatticeSolidPhase::addLattice(shared_ptr<ThermoPhase> lattice)
357{
358 m_lattice.push_back(lattice);
359 if (lkstart_.empty()) {
360 lkstart_.push_back(0);
361 }
362 lkstart_.push_back(lkstart_.back() + lattice->nSpecies());
363
364 if (theta_.size() == 0) {
365 theta_.push_back(1.0);
366 } else {
367 theta_.push_back(0.0);
368 }
369
370 for (size_t k = 0; k < lattice->nSpecies(); k++) {
371 ThermoPhase::addSpecies(lattice->species(k));
372 vector<double> constArr(lattice->nElements());
373 const vector<double>& aws = lattice->atomicWeights();
374 for (size_t es = 0; es < lattice->nElements(); es++) {
375 addElement(lattice->elementName(es), aws[es], lattice->atomicNumber(es),
376 lattice->entropyElement298(es), lattice->elementType(es));
377 }
378 m_x.push_back(lattice->moleFraction(k));
379 tmpV_.push_back(0.0);
380 }
381}
382
384{
385 for (size_t i = 0; i < m_lattice.size(); i++) {
386 theta_[i] = getValue(comp, m_lattice[i]->name(), 0.0);
387 }
388 // Add in the lattice stoichiometry constraint
389 for (size_t i = 1; i < m_lattice.size(); i++) {
390 string econ = fmt::format("LC_{}_{}", i, name());
391 size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO);
392 size_t mm = nElements();
393 for (size_t k = 0; k < m_lattice[0]->nSpecies(); k++) {
394 m_speciesComp[k * mm + m] = -theta_[0];
395 }
396 for (size_t k = 0; k < m_lattice[i]->nSpecies(); k++) {
397 size_t ks = lkstart_[i] + k;
398 m_speciesComp[ks * mm + m] = theta_[i];
399 }
400 }
401}
402
404{
405 double tnow = temperature();
406 if (m_tlast != tnow) {
407 getMoleFractions(m_x.data());
408 size_t strt = 0;
409 for (size_t n = 0; n < m_lattice.size(); n++) {
410 m_lattice[n]->setTemperature(tnow);
411 m_lattice[n]->setMoleFractions(&m_x[strt]);
412 m_lattice[n]->setPressure(m_press);
413 strt += m_lattice[n]->nSpecies();
414 }
415 m_tlast = tnow;
416 }
417}
418
420{
421 m_lattice[nn]->setMoleFractionsByName(x);
422 size_t loc = 0;
423 for (size_t n = 0; n < m_lattice.size(); n++) {
424 size_t nsp = m_lattice[n]->nSpecies();
425 double ndens = m_lattice[n]->molarDensity();
426 for (size_t k = 0; k < nsp; k++) {
427 m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
428 loc++;
429 }
430 }
431 setMoleFractions(m_x.data());
432}
433
434void LatticeSolidPhase::modifyOneHf298SS(const size_t k, const double Hf298New)
435{
436 for (size_t n = 0; n < m_lattice.size(); n++) {
437 if (lkstart_[n+1] < k) {
438 size_t kk = k-lkstart_[n];
439 MultiSpeciesThermo& l_spthermo = m_lattice[n]->speciesThermo();
440 l_spthermo.modifyOneHf298(kk, Hf298New);
441 }
442 }
445}
446
448{
449 if (k != npos) {
450 for (size_t n = 0; n < m_lattice.size(); n++) {
451 if (lkstart_[n+1] < k) {
452 size_t kk = k-lkstart_[n];
453 m_lattice[n]->speciesThermo().resetHf298(kk);
454 }
455 }
456 } else {
457 for (size_t n = 0; n < m_lattice.size(); n++) {
458 m_lattice[n]->speciesThermo().resetHf298(npos);
459 }
460 }
463}
464
465} // End namespace Cantera
#define CT_ELEM_TYPE_LATTICERATIO
Constraint associated with maintaining a fixed lattice stoichiometry in a solid.
Definition Elements.h:54
Header for a simple thermodynamics model of a bulk solid phase derived from ThermoPhase,...
Header for a general species thermodynamic property manager for a phase (see MultiSpeciesThermo).
Header for factory functions to build instances of classes that manage the standard-state thermodynam...
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
void erase(const string &key)
Erase the value held by key.
Definition AnyMap.cpp:1483
Base class for exceptions thrown by Cantera classes.
vector< shared_ptr< ThermoPhase > > m_lattice
Vector of sublattice ThermoPhase objects.
void setLatticeStoichiometry(const Composition &comp)
Set the lattice stoichiometric coefficients, .
void getStandardChemPotentials(double *mu0) const override
Get the array of standard state chemical potentials at unit activity for the species at their standar...
double enthalpy_mole() const override
Return the Molar Enthalpy. Units: J/kmol.
double logStandardConc(size_t k=0) const override
Natural logarithm of the standard concentration of the kth species.
AnyMap m_rootNode
Root node of the AnyMap which contains this phase definition.
LatticeSolidPhase()
Base empty constructor.
void getPartialMolarEnthalpies(double *hbar) const override
Returns an array of partial molar enthalpies for the species in the mixture.
void getChemPotentials(double *mu) const override
Get the species chemical potentials. Units: J/kmol.
vector< double > tmpV_
Temporary vector.
vector< double > m_x
Vector of mole fractions.
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...
void getGibbs_ref(double *g) const override
Returns the vector of the Gibbs function of the reference state at the current temperature of the sol...
void modifyOneHf298SS(const size_t k, const double Hf298New) override
Modify the value of the 298 K Heat of Formation of one species in the phase (J kmol-1)
vector< double > theta_
Lattice stoichiometric coefficients.
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 setMoleFractions(const double *const x) override
Set the mole fractions to the specified values, and then normalize them so that they sum to 1....
void getActivityConcentrations(double *c) const override
This method returns an array of generalized concentrations.
void setPressure(double p) override
Set the pressure at constant temperature. Units: Pa.
void getPartialMolarVolumes(double *vbar) const override
returns an array of partial molar volumes of the species in the solution.
void setLatticeMoleFractionsByName(int n, const string &x)
Set the Lattice mole fractions using a string.
double m_press
Current value of the pressure.
double refPressure() const override
Returns the reference pressure in Pa.
double minTemp(size_t k=npos) const override
Minimum temperature for which the thermodynamic data for the species or phase are valid.
double intEnergy_mole() const override
Return the Molar Internal Energy. Units: J/kmol.
double entropy_mole() const override
Return the Molar Entropy. Units: J/kmol/K.
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
double cp_mole() const override
Return the constant pressure heat capacity. Units: J/kmol/K.
Units standardConcentrationUnits() const override
Returns the units of the "standard concentration" for this phase.
void getPartialMolarCp(double *cpbar) const override
Returns an array of partial molar Heat Capacities at constant pressure of the species in the solution...
double gibbs_mole() const override
Return the Molar Gibbs energy. Units: J/kmol.
double standardConcentration(size_t k=0) const override
Return the standard concentration for the kth species.
void addLattice(shared_ptr< ThermoPhase > lattice)
Add a lattice to this phase.
double calcDensity()
Calculate the density of the solid mixture.
bool addSpecies(shared_ptr< Species > spec) override
Add a Species to this Phase.
void _updateThermo() const
Update the reference thermodynamic functions.
void getGibbs_RT_ref(double *grt) const override
Returns the vector of nondimensional Gibbs Free Energies of the reference state at the current temper...
void getActivityCoefficients(double *ac) const override
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap()) override
Set equation of state parameters from an AnyMap phase description.
void resetHf298(const size_t k=npos) override
Restore the original heat of formation of one or more species.
void getPartialMolarEntropies(double *sbar) const override
Returns an array of partial molar entropies of the species in the solution.
double maxTemp(size_t k=npos) const override
Maximum temperature for which the thermodynamic data for the species are valid.
A species thermodynamic property manager for a phase.
virtual void modifyOneHf298(const size_t k, const double Hf298New)
Modify the value of the 298 K Heat of Formation of the standard state of one species in the phase (J ...
void assignDensity(const double density_)
Set the internally stored constant density (kg/m^3) of the phase.
Definition Phase.cpp:625
virtual void setMoleFractions(const double *const x)
Set the mole fractions to the specified values.
Definition Phase.cpp:310
vector< double > m_speciesComp
Atomic composition of the species.
Definition Phase.h:888
size_t m_kk
Number of species in the phase.
Definition Phase.h:879
double temperature() const
Temperature (K).
Definition Phase.h:587
void getMoleFractions(double *const x) const
Get the species mole fraction vector.
Definition Phase.cpp:462
size_t nElements() const
Number of elements.
Definition Phase.cpp:30
size_t addElement(const string &symbol, double weight=-12345.0, int atomicNumber=0, double entropy298=ENTROPY298_UNKNOWN, int elem_type=CT_ELEM_TYPE_ABSPOS)
Add an element.
Definition Phase.cpp:663
string name() const
Return the name of the phase.
Definition Phase.cpp:20
virtual void setParameters(const AnyMap &phaseNode, const AnyMap &rootNode=AnyMap())
Set equation of state parameters from an AnyMap phase description.
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 invalidateCache() override
Invalidate any cached values which are normally updated only when a change in state is detected.
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
shared_ptr< ThermoPhase > newThermo(const AnyMap &phaseNode, const AnyMap &rootNode)
Create a new ThermoPhase object and initialize it.
Namespace for the Cantera kernel.
Definition AnyMap.cpp:595
const size_t npos
index returned by functions to indicate "no position"
Definition ct_defs.h:180
void warn_deprecated(const string &source, const AnyBase &node, const string &message)
A deprecation warning for syntax in an input file.
Definition AnyMap.cpp:1997
const double BigNumber
largest number to compare to inf.
Definition ct_defs.h:160
const U & getValue(const map< T, U > &m, const T &key, const U &default_val)
Const accessor for a value in a map.
Definition utilities.h:190
map< string, double > Composition
Map from string names to doubles.
Definition ct_defs.h:177
Contains declarations for string manipulation functions within Cantera.
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...