Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
13 #include "cantera/base/ctml.h"
14 #include "cantera/base/utilities.h"
15 
16 using namespace std;
17 
18 namespace Cantera
19 {
20 LatticeSolidPhase::LatticeSolidPhase() :
21  m_press(-1.0),
22  m_molar_density(0.0),
23  m_nlattice(0)
24 {
25 }
26 
28  m_press(-1.0),
29  m_molar_density(0.0),
30  m_nlattice(0)
31 {
32  *this = right;
33 }
34 
37 {
38  if (&right != this) {
40  m_tlast = right.m_tlast;
41  m_press = right.m_press;
43  m_nlattice = right.m_nlattice;
44  deepStdVectorPointerCopy<LatticePhase>(right.m_lattice, m_lattice);
45  m_x = right.m_x;
46  theta_ = right.theta_;
47  tmpV_ = right.tmpV_;
48  }
49  return *this;
50 }
51 
53 {
54  // We own the sublattices. So we have to delete the sublattices
55  for (size_t n = 0; n < m_nlattice; n++) {
56  delete m_lattice[n];
57  m_lattice[n] = 0;
58  }
59 }
60 
62 {
63  return new LatticeSolidPhase(*this);
64 }
65 
66 doublereal LatticeSolidPhase::minTemp(size_t k) const
67 {
68  if (k != npos) {
69  for (size_t n = 0; n < m_nlattice; n++) {
70  if (lkstart_[n+1] < k) {
71  return (m_lattice[n])->minTemp(k-lkstart_[n]);
72  }
73  }
74  }
75  doublereal mm = 1.0E300;
76  for (size_t n = 0; n < m_nlattice; n++) {
77  double ml = (m_lattice[n])->minTemp();
78  mm = std::min(mm, ml);
79  }
80  return mm;
81 }
82 
83 doublereal LatticeSolidPhase::maxTemp(size_t k) const
84 {
85  if (k != npos) {
86  for (size_t n = 0; n < m_nlattice; n++) {
87  if (lkstart_[n+1] < k) {
88  return (m_lattice[n])->maxTemp(k - lkstart_[n]);
89  }
90  }
91  }
92  doublereal mm = -1.0E300;
93  for (size_t n = 0; n < m_nlattice; n++) {
94  double ml = (m_lattice[n])->maxTemp();
95  mm = std::max(mm, ml);
96  }
97  return mm;
98 }
99 
101 {
102  return m_lattice[0]->refPressure();
103 }
104 
106 {
107  _updateThermo();
108  doublereal sum = 0.0;
109  for (size_t n = 0; n < m_nlattice; n++) {
110  sum += theta_[n] * m_lattice[n]->enthalpy_mole();
111  }
112  return sum;
113 }
114 
116 {
117  _updateThermo();
118  doublereal sum = 0.0;
119  for (size_t n = 0; n < m_nlattice; n++) {
120  sum += theta_[n] * m_lattice[n]->intEnergy_mole();
121  }
122  return sum;
123 }
124 
126 {
127  _updateThermo();
128  doublereal sum = 0.0;
129  for (size_t n = 0; n < m_nlattice; n++) {
130  sum += theta_[n] * m_lattice[n]->entropy_mole();
131  }
132  return sum;
133 }
134 
136 {
137  _updateThermo();
138  doublereal sum = 0.0;
139  for (size_t n = 0; n < m_nlattice; n++) {
140  sum += theta_[n] * m_lattice[n]->gibbs_mole();
141  }
142  return sum;
143 }
144 
145 doublereal LatticeSolidPhase::cp_mole() const
146 {
147  _updateThermo();
148  doublereal sum = 0.0;
149  for (size_t n = 0; n < m_nlattice; n++) {
150  sum += theta_[n] * m_lattice[n]->cp_mole();
151  }
152  return sum;
153 }
154 
156 {
157  _updateThermo();
158  size_t strt = 0;
159  for (size_t n = 0; n < m_nlattice; n++) {
160  m_lattice[n]->getMoleFractions(c+strt);
161  strt += m_lattice[n]->nSpecies();
162  }
163 }
164 
166 {
167  for (size_t k = 0; k < m_kk; k++) {
168  ac[k] = 1.0;
169  }
170 }
171 
173 {
174  return 1.0;
175 }
176 
177 doublereal LatticeSolidPhase::logStandardConc(size_t k) const
178 {
179  return 0.0;
180 }
181 
183 {
184  m_press = p;
185  for (size_t n = 0; n < m_nlattice; n++) {
186  m_lattice[n]->setPressure(m_press);
187  }
188  calcDensity();
189 }
190 
192 {
193  double sum = 0.0;
194  for (size_t n = 0; n < m_nlattice; n++) {
195  sum += theta_[n] * m_lattice[n]->density();
196  }
197  Phase::setDensity(sum);
198  return sum;
199 }
200 
201 void LatticeSolidPhase::setMoleFractions(const doublereal* const x)
202 {
203  size_t strt = 0;
204  for (size_t n = 0; n < m_nlattice; n++) {
205  size_t nsp = m_lattice[n]->nSpecies();
206  m_lattice[n]->setMoleFractions(x + strt);
207  strt += nsp;
208  }
209  for (size_t k = 0; k < strt; k++) {
210  m_x[k] = x[k] / m_nlattice;
211  }
213  calcDensity();
214 }
215 
216 void LatticeSolidPhase::getMoleFractions(doublereal* const x) const
217 {
218  size_t strt = 0;
219  // the ifdef block should be the way we calculate this.!!!!!
221  for (size_t n = 0; n < m_nlattice; n++) {
222  size_t nsp = m_lattice[n]->nSpecies();
223  double sum = 0.0;
224  for (size_t k = 0; k < nsp; k++) {
225  sum += (x + strt)[k];
226  }
227  for (size_t k = 0; k < nsp; k++) {
228  (x + strt)[k] /= sum;
229  }
230  /*
231  * At this point we can check against the mole fraction vector of the underlying LatticePhase objects and
232  * get the same answer.
233  */
234  if (DEBUG_MODE_ENABLED) {
235  m_lattice[n]->getMoleFractions(&(m_x[strt]));
236  for (size_t k = 0; k < nsp; k++) {
237  if (fabs((x + strt)[k] - m_x[strt+k]) > 1.0E-14) {
238  throw CanteraError("LatticeSolidPhase::getMoleFractions()",
239  "internal error");
240  }
241  }
242  }
243  strt += nsp;
244  }
245 }
246 
247 void LatticeSolidPhase::getChemPotentials(doublereal* mu) const
248 {
249  _updateThermo();
250  size_t strt = 0;
251  for (size_t n = 0; n < m_nlattice; n++) {
252  size_t nlsp = m_lattice[n]->nSpecies();
253  m_lattice[n]->getChemPotentials(mu+strt);
254  strt += nlsp;
255  }
256 }
257 
259 {
260  _updateThermo();
261  size_t strt = 0;
262  for (size_t n = 0; n < m_nlattice; n++) {
263  size_t nlsp = m_lattice[n]->nSpecies();
264  m_lattice[n]->getPartialMolarEnthalpies(hbar + strt);
265  strt += nlsp;
266  }
267 }
268 
270 {
271  _updateThermo();
272  size_t strt = 0;
273  for (size_t n = 0; n < m_nlattice; n++) {
274  size_t nlsp = m_lattice[n]->nSpecies();
275  m_lattice[n]->getPartialMolarEntropies(sbar + strt);
276  strt += nlsp;
277  }
278 }
279 
280 void LatticeSolidPhase::getPartialMolarCp(doublereal* cpbar) const
281 {
282  _updateThermo();
283  size_t strt = 0;
284  for (size_t n = 0; n < m_nlattice; n++) {
285  size_t nlsp = m_lattice[n]->nSpecies();
286  m_lattice[n]->getPartialMolarCp(cpbar + strt);
287  strt += nlsp;
288  }
289 }
290 
291 void LatticeSolidPhase::getPartialMolarVolumes(doublereal* vbar) const
292 {
293  _updateThermo();
294  size_t strt = 0;
295  for (size_t n = 0; n < m_nlattice; n++) {
296  size_t nlsp = m_lattice[n]->nSpecies();
297  m_lattice[n]->getPartialMolarVolumes(vbar + strt);
298  strt += nlsp;
299  }
300 }
301 
303 {
304  _updateThermo();
305  size_t strt = 0;
306  for (size_t n = 0; n < m_nlattice; n++) {
307  m_lattice[n]->getStandardChemPotentials(mu0+strt);
308  strt += m_lattice[n]->nSpecies();
309  }
310 }
311 
312 void LatticeSolidPhase::getGibbs_RT_ref(doublereal* grt) const
313 {
314  _updateThermo();
315  for (size_t n = 0; n < m_nlattice; n++) {
316  m_lattice[n]->getGibbs_RT_ref(grt + lkstart_[n]);
317  }
318 }
319 
320 void LatticeSolidPhase::getGibbs_ref(doublereal* g) const
321 {
322  getGibbs_RT_ref(g);
323  for (size_t k = 0; k < m_kk; k++) {
324  g[k] *= GasConstant * temperature();
325  }
326 }
327 
329 {
330  size_t kk = 0;
331  size_t kstart = 0;
332  m_speciesData.clear();
333 
334  XML_Node& la = phaseNode->child("thermo").child("LatticeArray");
335  std::vector<XML_Node*> lattices = la.getChildren("phase");
336  for (size_t n = 0; n < m_nlattice; n++) {
337  LatticePhase* lp = m_lattice[n];
338  vector<doublereal> constArr(lp->nElements());
339  const vector_fp& aws = lp->atomicWeights();
340  for (size_t es = 0; es < lp->nElements(); es++) {
341  addElement(lp->elementName(es), aws[es], lp->atomicNumber(es),
342  lp->entropyElement298(es), lp->elementType(es));
343  }
344  kstart = kk;
345 
346  for (size_t k = 0; k < lp->nSpecies(); k++) {
347  addSpecies(lp->species(k));
348  kk++;
349  }
350  /*
351  * Add in the lattice stoichiometry constraint
352  */
353  if (n > 0) {
354  string econ = "LC_" + int2str(n) + "_" + id();
355  size_t m = addElement(econ, 0.0, 0, 0.0, CT_ELEM_TYPE_LATTICERATIO);
356  size_t mm = nElements();
357  size_t nsp0 = m_lattice[0]->nSpecies();
358  for (size_t k = 0; k < nsp0; k++) {
359  m_speciesComp[k * mm + m] = -theta_[0];
360  }
361  for (size_t k = 0; k < lp->nSpecies(); k++) {
362  size_t ks = kstart + k;
363  m_speciesComp[ks * mm + m] = theta_[n];
364  }
365  }
366  }
367 }
368 
370 {
371  initLengths();
372  size_t loc = 0;
373  for (size_t n = 0; n < m_nlattice; n++) {
374  size_t nsp = m_lattice[n]->nSpecies();
375  lkstart_[n] = loc;
376  for (size_t k = 0; k < nsp; k++) {
377  m_x[loc] =m_lattice[n]->moleFraction(k) / (double) m_nlattice;
378  loc++;
379  }
380  lkstart_[n+1] = loc;
381  }
384 }
385 
387 {
388  theta_.resize(m_nlattice,0);
389  lkstart_.resize(m_nlattice+1);
390  m_x.resize(m_kk, 0.0);
391  tmpV_.resize(m_kk, 0.0);
392 }
393 
395 {
396  doublereal tnow = temperature();
397  if (m_tlast != tnow) {
399  size_t strt = 0;
400  for (size_t n = 0; n < m_nlattice; n++) {
401  m_lattice[n]->setTemperature(tnow);
402  m_lattice[n]->setMoleFractions(DATA_PTR(m_x) + strt);
403  m_lattice[n]->setPressure(m_press);
404  strt += m_lattice[n]->nSpecies();
405  }
406  m_tlast = tnow;
407  }
408 }
409 
410 void LatticeSolidPhase::setLatticeMoleFractionsByName(int nn, const std::string& x)
411 {
412  m_lattice[nn]->setMoleFractionsByName(x);
413  size_t loc = 0;
414  for (size_t n = 0; n < m_nlattice; n++) {
415  size_t nsp = m_lattice[n]->nSpecies();
416  double ndens = m_lattice[n]->molarDensity();
417  for (size_t k = 0; k < nsp; k++) {
418  m_x[loc] = ndens * m_lattice[n]->moleFraction(k);
419  loc++;
420  }
421  }
423 }
424 
426 {
427  eosdata._require("model","LatticeSolid");
428  XML_Node& la = eosdata.child("LatticeArray");
429  std::vector<XML_Node*> lattices = la.getChildren("phase");
430  m_nlattice = lattices.size();
431  for (size_t n = 0; n < m_nlattice; n++) {
432  m_lattice.push_back((LatticePhase*)newPhase(*lattices[n]));
433  }
434  std::vector<string> pnam;
435  std::vector<string> pval;
436  int np = getPairs(eosdata.child("LatticeStoichiometry"), pnam, pval);
437  theta_.resize(m_nlattice);
438  for (int i = 0; i < np; i++) {
439  double val = fpValueCheck(pval[i]);
440  bool found = false;
441  for (size_t j = 0; j < m_nlattice; j++) {
442  ThermoPhase& tp = *(m_lattice[j]);
443  string idj = tp.id();
444  if (idj == pnam[i]) {
445  theta_[j] = val;
446  found = true;
447  break;
448  }
449  }
450  if (!found) {
451  throw CanteraError("LatticeSolidPhase::setParametersFromXML", "not found");
452  }
453  }
454 
455 }
456 
457 void LatticeSolidPhase::modifyOneHf298SS(const size_t k, const doublereal Hf298New)
458 {
459  for (size_t n = 0; n < m_nlattice; n++) {
460  if (lkstart_[n+1] < k) {
461  size_t kk = k-lkstart_[n];
462  SpeciesThermo& l_spthermo = m_lattice[n]->speciesThermo();
463  l_spthermo.modifyOneHf298(kk, Hf298New);
464  }
465  }
466  m_tlast += 0.0001234;
467  _updateThermo();
468 }
469 
470 } // End namespace Cantera
ThermoPhase * newPhase(XML_Node &xmlphase)
Create a new ThermoPhase object and initializes it according to the XML tree.
void _require(const std::string &a, const std::string &v) const
Require that the current XML node have an attribute named by the first argument, a, and that this attribute have the the string value listed in the second argument, v.
Definition: xml.cpp:603
virtual void modifyOneHf298SS(const size_t k, const doublereal Hf298New)
Modify the value of the 298 K Heat of Formation of one species in the phase (J kmol-1) ...
std::string int2str(const int n, const std::string &fmt)
Convert an int to a string using a format converter.
Definition: stringUtils.cpp:39
virtual bool addSpecies(shared_ptr< Species > spec)
Add a Species to this Phase.
virtual doublereal logStandardConc(size_t k=0) const
Natural logarithm of the standard concentration of the kth species.
std::vector< LatticePhase * > m_lattice
Vector of sublattic ThermoPhase objects.
virtual void installSlavePhases(Cantera::XML_Node *phaseNode)
Add in species from Slave phases.
virtual void getPartialMolarEntropies(doublereal *sbar) const
Returns an array of partial molar entropies of the species in the solution.
virtual void getPartialMolarCp(doublereal *cpbar) const
Returns an array of partial molar Heat Capacities at constant pressure of the species in the solution...
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
virtual void getChemPotentials(doublereal *mu) const
Get the species chemical potentials. Units: J/kmol.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
size_t nElements() const
Number of elements.
Definition: Phase.cpp:167
std::vector< const XML_Node * > m_speciesData
Vector of pointers to the species databases.
Definition: ThermoPhase.h:1617
Various templated functions that carry out common vector operations (see Templated Utility Functions)...
doublereal calcDensity()
Calculate the density of the solid mixture.
virtual void initThermo()
Initialize the ThermoPhase object after all species have been set up.
const size_t npos
index returned by functions to indicate "no position"
Definition: ct_defs.h:165
ThermoPhase & operator=(const ThermoPhase &right)
Assignment operator.
Definition: ThermoPhase.cpp:60
LatticeSolidPhase & operator=(const LatticeSolidPhase &right)
Assignment operator.
virtual doublereal standardConcentration(size_t k=0) const
Return the standard concentration for the kth species.
Headers for the factory class that can create known ThermoPhase objects (see Thermodynamic Properties...
LatticeSolidPhase()
Base empty constructor.
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values, and then normalize them so that they sum to 1...
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
virtual doublereal cp_mole() const
Return the constant pressure heat capacity. Units: J/kmol/K.
virtual ~LatticeSolidPhase()
Destructor.
A simple thermodynamic model for a bulk phase, assuming a lattice of solid atoms. ...
Definition: LatticePhase.h:241
void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
Definition: Phase.cpp:556
doublereal m_tlast
last value of the temperature processed by reference state
Definition: ThermoPhase.h:1656
Pure Virtual base class for the species thermo manager classes.
shared_ptr< Species > species(const std::string &name) const
Return the Species object for the named species.
Definition: Phase.cpp:978
virtual void setPressure(doublereal p)
Set the pressure at constant temperature. Units: Pa.
XML_Node & child(const size_t n) const
Return a changeable reference to the n'th child of the current node.
Definition: xml.cpp:573
doublereal entropyElement298(size_t m) const
Entropy of the element in its standard state at 298 K and 1 bar.
Definition: Phase.cpp:212
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:97
void _updateThermo() const
Update the reference thermodynamic functions.
virtual void getGibbs_RT_ref(doublereal *grt) const
Returns the vector of nondimensional enthalpies of the reference state at the current temperature of ...
virtual void getStandardChemPotentials(doublereal *mu0) const
Get the array of standard state chemical potentials at unit activity for the species at their standar...
const vector_fp & atomicWeights() const
Return a read-only reference to the vector of atomic weights.
Definition: Phase.cpp:221
virtual void getGibbs_ref(doublereal *g) const
Returns the vector of the Gibbs function of the reference state at the current temperatureof the solu...
Header for a simple thermodynamics model of a bulk solid phase derived from ThermoPhase, assuming an ideal solution model based on a lattice of solid atoms (see Thermodynamic Properties and class LatticeSolidPhase).
void initLengths()
Initialize vectors that depend on the number of species and sublattices.
ThermoPhase * duplMyselfAsThermoPhase() const
Duplication function.
doublereal m_molar_density
Current value of the molar density.
int atomicNumber(size_t m) const
Atomic number of element m.
Definition: Phase.cpp:226
vector_fp tmpV_
Temporary vector.
int getPairs(const XML_Node &node, std::vector< std::string > &key, std::vector< std::string > &val)
This function interprets the value portion of an XML element as a series of "Pairs" separated by whit...
Definition: ctml.cpp:417
std::string id() const
Return the string id for the phase.
Definition: Phase.cpp:147
Base class for exceptions thrown by Cantera classes.
Definition: ctexceptions.h:99
doublereal m_press
Current value of the pressure.
virtual void setMoleFractions(const doublereal *const x)
Set the mole fractions to the specified values There is no restriction on the sum of the mole fractio...
Definition: Phase.cpp:331
virtual doublereal maxTemp(size_t k=npos) const
Maximum temperature for which the thermodynamic data for the species are valid.
virtual void getPartialMolarVolumes(doublereal *vbar) const
returns an array of partial molar volumes of the species in the solution.
virtual doublereal refPressure() const
Returns the reference pressure in Pa.
virtual doublereal intEnergy_mole() const
Return the Molar Internal Energy. Units: J/kmol.
void setLatticeMoleFractionsByName(int n, const std::string &x)
Set the Lattice mole fractions using a string.
size_t nSpecies() const
Returns the number of species in the phase.
Definition: Phase.h:265
virtual doublereal minTemp(size_t k=npos) const
Minimum temperature for which the thermodynamic data for the species or phase are valid...
doublereal temperature() const
Temperature (K).
Definition: Phase.h:602
vector_fp m_x
Vector of mole fractions.
Header for factory to build instances of classes that manage the standard-state thermodynamic propert...
size_t addElement(const std::string &symbol, doublereal weight=-12345.0, int atomicNumber=0, doublereal entropy298=ENTROPY298_UNKNOWN, int elem_type=CT_ELEM_TYPE_ABSPOS)
Add an element.
Definition: Phase.cpp:714
Headers for a completely general species thermodynamic property manager for a phase (see Managers for...
std::vector< doublereal > theta_
Lattice stoichiometric coefficients.
std::vector< double > vector_fp
Turn on the use of stl vectors for the basic array type within cantera Vector of doubles.
Definition: ct_defs.h:157
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized activity concentrations.
virtual void setParametersFromXML(const XML_Node &eosdata)
Set equation of state parameter values from XML entries.
A phase that is comprised of a fixed additive combination of other lattice phases.
const doublereal GasConstant
Universal Gas Constant. [J/kmol/K].
Definition: ct_defs.h:64
virtual void modifyOneHf298(const size_t k, const doublereal Hf298New)=0
Modify the value of the 298 K Heat of Formation of the standard state of one species in the phase (J ...
#define DATA_PTR(vec)
Creates a pointer to the start of the raw data for a vector.
Definition: ct_defs.h:36
virtual void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional molar-based activity coefficients at the current solution temperatur...
virtual doublereal entropy_mole() const
Return the Molar Entropy. Units: J/kmol/K.
std::string elementName(size_t m) const
Name of the element with index m.
Definition: Phase.cpp:186
int elementType(size_t m) const
Return the element constraint type Possible types include:
Definition: Phase.cpp:231
vector_fp m_speciesComp
Atomic composition of the species.
Definition: Phase.h:852
#define CT_ELEM_TYPE_LATTICERATIO
Constraint associated with maintaining a fixed lattice stoichiometry in a solid.
Definition: Elements.h:54
size_t m_kk
Number of species in the phase.
Definition: Phase.h:843
size_t m_nlattice
Number of sublattice phases.
virtual void getMoleFractions(doublereal *const x) const
Get the species mole fraction vector.
virtual doublereal enthalpy_mole() const
Return the Molar Enthalpy. Units: J/kmol.
doublereal fpValueCheck(const std::string &val)
Translate a string into one doublereal value, with error checking.
virtual doublereal gibbs_mole() const
Return the Molar Gibbs energy. Units: J/kmol.
virtual void getPartialMolarEnthalpies(doublereal *hbar) const
Returns an array of partial molar enthalpies for the species in the mixture.
void getChildren(const std::string &name, std::vector< XML_Node * > &children) const
Get a vector of pointers to XML_Node containing all of the children of the current node which matches...
Definition: xml.cpp:915
virtual void setDensity(const doublereal density_)
Set the internally stored density (kg/m^3) of the phase Note the density of a phase is an independent...
Definition: Phase.h:623