Cantera  2.0
MineralEQ3.h
Go to the documentation of this file.
1 /**
2  * @file MineralEQ3.h
3  * Header file for the MineralEQ3 class, which represents a fixed-composition
4  * incompressible substance based on EQ3's parameterization (see \ref thermoprops and
5  * class \link Cantera::MineralEQ3 MineralEQ3\endlink)
6  */
7 
8 /*
9  * Copyright (2006) Sandia Corporation. Under the terms of
10  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
11  * U.S. Government retains certain rights in this software.
12  *
13  * Copyright 2001 California Institute of Technology
14  */
15 #ifndef CT_MINERALEQ3_H
16 #define CT_MINERALEQ3_H
17 
18 #include "mix_defs.h"
19 #include "SingleSpeciesTP.h"
20 #include "SpeciesThermo.h"
21 #include "StoichSubstanceSSTP.h"
22 
23 namespace Cantera
24 {
25 
26 //! Class %MineralEQ3 represents a stoichiometric (fixed
27 //! composition) incompressible substance based on EQ3's parameterization
28 /*!
29  * This class inherits from SingleSpeciesSSTP class.
30  * EQ's parameterization is mapped onto the Shomate polynomial class.
31  *
32  * <b> Specification of Species Standard %State Properties </b>
33  *
34  * This class inherits from SingleSpeciesTP.
35  * It is assumed that the reference state thermodynamics may be
36  * obtained by a pointer to a populated species thermodynamic property
37  * manager class (see ThermoPhase::m_spthermo). How to relate pressure
38  * changes to the reference state thermodynamics is resolved at this level.
39  *
40  * For an incompressible,
41  * stoichiometric substance, the molar internal energy is
42  * independent of pressure. Since the thermodynamic properties
43  * are specified by giving the standard-state enthalpy, the
44  * term \f$ P_0 \hat v\f$ is subtracted from the specified molar
45  * enthalpy to compute the molar internal energy. The entropy is
46  * assumed to be independent of the pressure.
47  *
48  * The enthalpy function is given by the following relation.
49  *
50  * \f[
51  * \raggedright h^o_k(T,P) =
52  * h^{ref}_k(T) + \tilde v \left( P - P_{ref} \right)
53  * \f]
54  *
55  * For an incompressible,
56  * stoichiometric substance, the molar internal energy is
57  * independent of pressure. Since the thermodynamic properties
58  * are specified by giving the standard-state enthalpy, the
59  * term \f$ P_{ref} \tilde v\f$ is subtracted from the specified reference molar
60  * enthalpy to compute the molar internal energy.
61  *
62  * \f[
63  * u^o_k(T,P) = h^{ref}_k(T) - P_{ref} \tilde v
64  * \f]
65  *
66  * The standard state heat capacity and entropy are independent
67  * of pressure. The standard state gibbs free energy is obtained
68  * from the enthalpy and entropy functions.
69  *
70  *
71  * <b> Specification of Solution Thermodynamic Properties </b>
72  *
73  * All solution properties are obtained from the standard state
74  * species functions, since there is only one species in the phase.
75  *
76  * <b> Application within %Kinetics Managers </b>
77  *
78  * The standard concentration is equal to 1.0. This means that the
79  * kinetics operator works on an (activities basis). Since this
80  * is a stoichiometric substance, this means that the concentration
81  * of this phase drops out of kinetics expressions.
82  *
83  * An example of a reaction using this is a sticking coefficient
84  * reaction of a substance in an ideal gas phase on a surface with a bulk phase
85  * species in this phase. In this case, the rate of progress for this
86  * reaction, \f$ R_s \f$, may be expressed via the following equation:
87  * \f[
88  * R_s = k_s C_{gas}
89  * \f]
90  * where the units for \f$ R_s \f$ are kmol m-2 s-1. \f$ C_{gas} \f$ has units
91  * of kmol m-3. Therefore, the kinetic rate constant, \f$ k_s \f$, has
92  * units of m s-1. Nowhere does the concentration of the bulk phase
93  * appear in the rate constant expression, since it's a stoichiometric
94  * phase and the activity is always equal to 1.0.
95  *
96  * <b> Instantiation of the Class </b>
97  *
98  * The constructor for this phase is NOT located in the default ThermoFactory
99  * for %Cantera. However, a new %StoichSubstanceSSTP may be created by
100  * the following code snippets:
101  *
102  * @code
103  * sprintf(file_ID,"%s#NaCl(S)", iFile);
104  * XML_Node *xm = get_XML_NameID("phase", file_ID, 0);
105  * StoichSubstanceSSTP *solid = new StoichSubstanceSSTP(*xm);
106  * @endcode
107  *
108  * or by the following call to importPhase():
109  *
110  * @code
111  * sprintf(file_ID,"%s#NaCl(S)", iFile);
112  * XML_Node *xm = get_XML_NameID("phase", file_ID, 0);
113  * StoichSubstanceSSTP solid;
114  * importPhase(*xm, &solid);
115  * @endcode
116  *
117  * <b> XML Example </b>
118  *
119  * The phase model name for this is called StoichSubstance. It must be supplied
120  * as the model attribute of the thermo XML element entry.
121  * Within the phase XML block,
122  * the density of the phase must be specified. An example of an XML file
123  * this phase is given below.
124  *
125  * @verbatim
126  <!-- phase NaCl(S) -->
127  <phase dim="3" id="NaCl(S)">
128  <elementArray datasrc="elements.xml">
129  Na Cl
130  </elementArray>
131  <speciesArray datasrc="#species_NaCl(S)"> NaCl(S) </speciesArray>
132  <thermo model="StoichSubstanceSSTP">
133  <density units="g/cm3">2.165</density>
134  </thermo>
135  <transport model="None"/>
136  <kinetics model="none"/>
137  </phase>
138 
139  <!-- species definitions -->
140  <speciesData id="species_NaCl(S)">
141  <!-- species NaCl(S) -->
142  <species name="NaCl(S)">
143  <atomArray> Na:1 Cl:1 </atomArray>
144  <thermo>
145  <Shomate Pref="1 bar" Tmax="1075.0" Tmin="250.0">
146  <floatArray size="7">
147  50.72389, 6.672267, -2.517167,
148  10.15934, -0.200675, -427.2115,
149  130.3973
150  </floatArray>
151  </Shomate>
152  </thermo>
153  <density units="g/cm3">2.165</density>
154  </species>
155  </speciesData> @endverbatim
156  *
157  * The model attribute, "StoichSubstanceSSTP", on the thermo element identifies the phase as being
158  * a StoichSubstanceSSTP object.
159  *
160  * @ingroup thermoprops
161  */
163 {
164 
165 public:
166 
167  //! Default constructor for the StoichSubstanceSSTP class
168  MineralEQ3();
169 
170  //! Construct and initialize a StoichSubstanceSSTP ThermoPhase object
171  //! directly from an ASCII input file
172  /*!
173  * @param infile name of the input file
174  * @param id name of the phase id in the file.
175  * If this is blank, the first phase in the file is used.
176  */
177  MineralEQ3(std::string infile, std::string id = "");
178 
179  //! Construct and initialize a StoichSubstanceSSTP ThermoPhase object
180  //! directly from an XML database
181  /*!
182  * @param phaseRef XML node pointing to a StoichSubstanceSSTP description
183  * @param id Id of the phase.
184  */
185  MineralEQ3(XML_Node& phaseRef, std::string id = "");
186 
187  //! Copy constructor
188  /*!
189  * @param right Object to be copied
190  */
191  MineralEQ3(const MineralEQ3& right);
192 
193  //! Assignment operator
194  /*!
195  * @param right Object to be copied
196  */
197  MineralEQ3& operator=(const MineralEQ3& right);
198 
199  //! Destructor for the routine (virtual)
200  virtual ~MineralEQ3();
201 
202  //! Duplication function
203  /*!
204  * This virtual function is used to create a duplicate of the
205  * current phase. It's used to duplicate the phase when given
206  * a ThermoPhase pointer to the phase.
207  *
208  * @return It returns a ThermoPhase pointer.
209  */
211 
212  /**
213  *
214  * @name Utilities
215  * @{
216  */
217 
218  /**
219  * Equation of state flag.
220  *
221  * Returns the value cStoichSubstance, defined in mix_defs.h.
222  */
223  virtual int eosType() const;
224 
225  /**
226  * @}
227  * @name Molar Thermodynamic Properties of the Solution
228  * @{
229  */
230 
231  /**
232  * @}
233  * @name Mechanical Equation of State
234  * @{
235  */
236 
237 
238  //! Report the Pressure. Units: Pa.
239  /*!
240  * For an incompressible substance, the density is independent
241  * of pressure. This method simply returns the stored
242  * pressure value.
243  */
244  virtual doublereal pressure() const;
245 
246  //! Set the pressure at constant temperature. Units: Pa.
247  /*!
248  * For an incompressible substance, the density is
249  * independent of pressure. Therefore, this method only
250  * stores the specified pressure value. It does not
251  * modify the density.
252  *
253  * @param p Pressure (units - Pa)
254  */
255  virtual void setPressure(doublereal p);
256 
257  //! Returns the isothermal compressibility. Units: 1/Pa.
258  /*!
259  * The isothermal compressibility is defined as
260  * \f[
261  * \kappa_T = -\frac{1}{v}\left(\frac{\partial v}{\partial P}\right)_T
262  * \f]
263  */
264  virtual doublereal isothermalCompressibility() const;
265 
266  //! Return the volumetric thermal expansion coefficient. Units: 1/K.
267  /*!
268  * The thermal expansion coefficient is defined as
269  * \f[
270  * \beta = \frac{1}{v}\left(\frac{\partial v}{\partial T}\right)_P
271  * \f]
272  */
273  virtual doublereal thermalExpansionCoeff() const ;
274 
275  /**
276  * @}
277  * @name Activities, Standard States, and Activity Concentrations
278  *
279  * This section is largely handled by parent classes, since there
280  * is only one species. Therefore, the activity is equal to one.
281  * @{
282  */
283 
284  //! This method returns an array of generalized concentrations
285  /*!
286  * \f$ C^a_k\f$ are defined such that \f$ a_k = C^a_k /
287  * C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration
288  * defined below and \f$ a_k \f$ are activities used in the
289  * thermodynamic functions. These activity (or generalized)
290  * concentrations are used
291  * by kinetics manager classes to compute the forward and
292  * reverse rates of elementary reactions.
293  *
294  * For a stoichiometric substance, there is
295  * only one species, and the generalized concentration is 1.0.
296  *
297  * @param c Output array of generalized concentrations. The
298  * units depend upon the implementation of the
299  * reaction rate expressions within the phase.
300  */
301  virtual void getActivityConcentrations(doublereal* c) const;
302 
303  //! Return the standard concentration for the kth species
304  /*!
305  * The standard concentration \f$ C^0_k \f$ used to normalize
306  * the activity (i.e., generalized) concentration.
307  * This phase assumes that the kinetics operator works on an
308  * dimensionless basis. Thus, the standard concentration is
309  * equal to 1.0.
310  *
311  * @param k Optional parameter indicating the species. The default
312  * is to assume this refers to species 0.
313  * @return
314  * Returns The standard Concentration as 1.0
315  */
316  virtual doublereal standardConcentration(size_t k=0) const;
317 
318  //! Natural logarithm of the standard concentration of the kth species.
319  /*!
320  * @param k index of the species (defaults to zero)
321  */
322  virtual doublereal logStandardConc(size_t k=0) const;
323 
324  //! Get the array of chemical potentials at unit activity for the species
325  //! at their standard states at the current <I>T</I> and <I>P</I> of the solution.
326  /*!
327  * For a stoichiometric substance, there is no activity term in
328  * the chemical potential expression, and therefore the
329  * standard chemical potential and the chemical potential
330  * are both equal to the molar Gibbs function.
331  *
332  * These are the standard state chemical potentials \f$ \mu^0_k(T,P)
333  * \f$. The values are evaluated at the current
334  * temperature and pressure of the solution
335  *
336  * @param mu0 Output vector of chemical potentials.
337  * Length: m_kk.
338  */
339  virtual void getStandardChemPotentials(doublereal* mu0) const;
340 
341  //! Returns the units of the standard and generalized concentrations.
342  /*!
343  * Note they have the same units, as their
344  * ratio is defined to be equal to the activity of the kth
345  * species in the solution, which is unitless.
346  *
347  * This routine is used in print out applications where the
348  * units are needed. Usually, MKS units are assumed throughout
349  * the program and in the XML input files.
350  *
351  * The base %ThermoPhase class assigns the default quantities
352  * of (kmol/m3) for all species.
353  * Inherited classes are responsible for overriding the default
354  * values if necessary.
355  *
356  * @param uA Output vector containing the units
357  * uA[0] = kmol units - default = 1
358  * uA[1] = m units - default = -nDim(), the number of spatial
359  * dimensions in the Phase class.
360  * uA[2] = kg units - default = 0;
361  * uA[3] = Pa(pressure) units - default = 0;
362  * uA[4] = Temperature units - default = 0;
363  * uA[5] = time units - default = 0
364  * @param k species index. Defaults to 0.
365  * @param sizeUA output int containing the size of the vector.
366  * Currently, this is equal to 6.
367  */
368  virtual void getUnitsStandardConc(doublereal* uA, int k = 0,
369  int sizeUA = 6) const;
370 
371  //@}
372  /// @name Partial Molar Properties of the Solution
373  ///
374  /// These properties are handled by the parent class,
375  /// SingleSpeciesTP
376  //@{
377 
378 
379  //@}
380  /// @name Properties of the Standard State of the Species in the Solution
381  //@{
382 
383  //! Get the nondimensional Enthalpy functions for the species
384  //! at their standard states at the current <I>T</I> and <I>P</I> of the solution.
385  /*!
386  * @param hrt Output vector of nondimensional standard state enthalpies.
387  * Length: m_kk.
388  */
389  virtual void getEnthalpy_RT(doublereal* hrt) const;
390 
391  //! Get the array of nondimensional Entropy functions for the
392  //! standard state species at the current <I>T</I> and <I>P</I> of the solution.
393  /*!
394  * @param sr Output vector of nondimensional standard state entropies.
395  * Length: m_kk.
396  */
397  virtual void getEntropy_R(doublereal* sr) const;
398 
399  //! Get the nondimensional Gibbs functions for the species
400  //! in their standard states at the current <I>T</I> and <I>P</I> of the solution.
401  /*!
402  * @param grt Output vector of nondimensional standard state gibbs free energies
403  * Length: m_kk.
404  */
405  virtual void getGibbs_RT(doublereal* grt) const;
406 
407  //! Get the nondimensional Heat Capacities at constant
408  //! pressure for the species standard states
409  //! at the current <I>T</I> and <I>P</I> of the solution
410  /*!
411  * @param cpr Output vector of nondimensional standard state heat capacities
412  * Length: m_kk.
413  */
414  virtual void getCp_R(doublereal* cpr) const;
415 
416  //! Returns the vector of nondimensional Internal Energies of the standard
417  //! state species at the current <I>T</I> and <I>P</I> of the solution
418  /*!
419  * For an incompressible,
420  * stoichiometric substance, the molar internal energy is
421  * independent of pressure. Since the thermodynamic properties
422  * are specified by giving the standard-state enthalpy, the
423  * term \f$ P_{ref} \hat v\f$ is subtracted from the specified reference molar
424  * enthalpy to compute the standard state molar internal energy.
425  *
426  * @param urt output vector of nondimensional standard state
427  * internal energies of the species. Length: m_kk.
428  */
429  virtual void getIntEnergy_RT(doublereal* urt) const;
430 
431  //@}
432  /// @name Thermodynamic Values for the Species Reference States
433  //@{
434 
435  //! Returns the vector of nondimensional
436  //! internal Energies of the reference state at the current temperature
437  //! of the solution and the reference pressure for each species.
438  /*!
439  * @param urt Output vector of nondimensional reference state
440  * internal energies of the species.
441  * Length: m_kk
442  */
443  virtual void getIntEnergy_RT_ref(doublereal* urt) const;
444 
445  /*
446  * ---- Critical State Properties
447  */
448 
449 
450  /*
451  * ---- Saturation Properties
452  */
453 
454  //! Initialization of a HMWSoln phase using an xml file
455  /*!
456  * This routine is a precursor to initThermo(XML_Node*)
457  * routine, which does most of the work.
458  *
459  * @param inputFile XML file containing the description of the
460  * phase
461  *
462  * @param id Optional parameter identifying the name of the
463  * phase. If none is given, the first XML
464  * phase element will be used.
465  */
466  void constructPhaseFile(std::string inputFile, std::string id);
467 
468  //! Import and initialize a HMWSoln phase
469  //! specification in an XML tree into the current object.
470  /*!
471  * Here we read an XML description of the phase.
472  * We import descriptions of the elements that make up the
473  * species in a phase.
474  * We import information about the species, including their
475  * reference state thermodynamic polynomials. We then freeze
476  * the state of the species.
477  *
478  * Then, we read the species molar volumes from the xml
479  * tree to finish the initialization.
480  *
481  * @param phaseNode This object must be the phase node of a
482  * complete XML tree
483  * description of the phase, including all of the
484  * species data. In other words while "phase" must
485  * point to an XML phase object, it must have
486  * sibling nodes "speciesData" that describe
487  * the species in the phase.
488  *
489  * @param id ID of the phase. If nonnull, a check is done
490  * to see if phaseNode is pointing to the phase
491  * with the correct id.
492  */
493  void constructPhaseXML(XML_Node& phaseNode, std::string id);
494 
495  //! Internal initialization required after all species have
496  //! been added
497  /*!
498  * @internal Initialize. This method is provided to allow
499  * subclasses to perform any initialization required after all
500  * species have been added. For example, it might be used to
501  * resize internal work arrays that must have an entry for
502  * each species. The base class implementation does nothing,
503  * and subclasses that do not require initialization do not
504  * need to overload this method. When importing a CTML phase
505  * description, this method is called just prior to returning
506  * from function importPhase.
507  *
508  * @see importCTML.cpp
509  */
510  virtual void initThermo();
511 
512  //! Initialize the phase parameters from an XML file.
513  /*!
514  * initThermoXML() (virtual from ThermoPhase)
515  *
516  * This gets called from importPhase(). It processes the XML file
517  * after the species are set up. This is the main routine for
518  * reading in activity coefficient parameters.
519  *
520  * @param phaseNode This object must be the phase node of a
521  * complete XML tree
522  * description of the phase, including all of the
523  * species data. In other words while "phase" must
524  * point to an XML phase object, it must have
525  * sibling nodes "speciesData" that describe
526  * the species in the phase.
527  * @param id ID of the phase. If nonnull, a check is done
528  * to see if phaseNode is pointing to the phase
529  * with the correct id.
530  */
531  virtual void initThermoXML(XML_Node& phaseNode, std::string id);
532 
533  //! Set the equation of state parameters
534  /*!
535  * @internal
536  * The number and meaning of these depends on the subclass.
537  *
538  * @param n number of parameters
539  * @param c array of \a n coefficients
540  * c[0] = density of phase [ kg/m3 ]
541  */
542  virtual void setParameters(int n, doublereal* const c);
543 
544  //! Get the equation of state parameters in a vector
545  /*!
546  * @internal
547  *
548  * @param n number of parameters
549  * @param c array of \a n coefficients
550  *
551  * For this phase:
552  * - n = 1
553  * - c[0] = density of phase [ kg/m3 ]
554  */
555  virtual void getParameters(int& n, doublereal* const c) const;
556 
557  //! Set equation of state parameter values from XML entries.
558  /*!
559  * This method is called by function importPhase() in
560  * file importCTML.cpp when processing a phase definition in
561  * an input file. It should be overloaded in subclasses to set
562  * any parameters that are specific to that particular phase
563  * model. Note, this method is called before the phase is
564  * initialized with elements and/or species.
565  *
566  * For this phase, the density of the phase is specified in this block.
567  *
568  * @param eosdata An XML_Node object corresponding to
569  * the "thermo" entry for this phase in the input file.
570  *
571  * eosdata points to the thermo block, and looks like this:
572  *
573  * @verbatim
574  <phase id="stoichsolid" >
575  <thermo model="StoichSubstance">
576  <density units="g/cm3">3.52</density>
577  </thermo>
578  </phase> @endverbatim
579  *
580  */
581  virtual void setParametersFromXML(const XML_Node& eosdata);
582  doublereal LookupGe(const std::string& elemName);
583  void convertDGFormation();
584 
585 protected:
586 
587  //! Value of the Absolute Gibbs Free Energy NIST scale at T_r and P_r
588  /*!
589  * This is the NIST scale value of Gibbs free energy at T_r = 298.15
590  * and P_r = 1 atm.
591  *
592  * J kmol-1
593  */
594  doublereal m_Mu0_pr_tr;
595 
596 
597  //! Input value of S_j at Tr and Pr (cal gmol-1 K-1)
598  /*!
599  * Tr = 298.15 Pr = 1 atm
600  */
601  doublereal m_Entrop_pr_tr;
602 
603  //! Input Value of deltaG of Formation at Tr and Pr (cal gmol-1)
604  /*!
605  * Tr = 298.15 Pr = 1 atm
606  *
607  * This is the delta G for the formation reaction of the
608  * ion from elements in their stable state at Tr, Pr.
609  */
611 
612  //! Input Value of deltaH of Formation at Tr and Pr (cal gmol-1)
613  /*!
614  * Tr = 298.15 Pr = 1 atm
615  *
616  * This is the delta H for the formation reaction of the
617  * ion from elements in their stable state at Tr, Pr.
618  */
620 
621  //! Input Value of the molar volume at T_r and P_r
622  /*!
623  * cm^3 / gmol
624  */
625  doublereal m_V0_pr_tr;
626 
627  //! a coefficient (cal gmol-1 K-1)
628  doublereal m_a;
629 
630  //! b coefficient (cal gmol-1 K-2) x 10^3
631  doublereal m_b;
632 
633  //! c coefficient (cal K gmol-1 K) x 10^-5
634  doublereal m_c;
635 
636 };
637 
638 }
639 
640 #endif