Cantera  2.0
SurfPhase.h
Go to the documentation of this file.
1 /**
2  * @file SurfPhase.h
3  * Header for a simple thermodynamics model of a surface phase
4  * derived from ThermoPhase,
5  * assuming an ideal solution model
6  * (see \ref thermoprops and class \link Cantera::SurfPhase SurfPhase\endlink).
7  */
8 
9 // Copyright 2002 California Institute of Technology
10 
11 #ifndef CT_SURFPHASE_H
12 #define CT_SURFPHASE_H
13 
14 #include "mix_defs.h"
15 #include "ThermoPhase.h"
16 
17 namespace Cantera
18 {
19 
20 //! A simple thermodynamic model for a surface phase,
21 //! assuming an ideal solution model.
22 /*!
23  * The surface consists of a grid of equivalent sites.
24  * Surface species may be defined to
25  * occupy one or more sites. The surface species are assumed to be
26  * independent, and thus the species form an ideal solution.
27  *
28  * The density of surface sites is given by the variable \f$ n_0 \f$,
29  * which has SI units of kmol m-2.
30  *
31  * <b> Specification of Species Standard State Properties </b>
32  *
33  * It is assumed that the reference state thermodynamics may be
34  * obtained by a pointer to a populated species thermodynamic property
35  * manager class (see ThermoPhase::m_spthermo). How to relate pressure
36  * changes to the reference state thermodynamics is resolved at this level.
37  *
38  * Pressure is defined as an independent variable in this phase. However, it has
39  * no effect on any quantities, as the molar concentration is a constant.
40  *
41  * Therefore, The standard state internal energy for species <I>k</I> is
42  * equal to the enthalpy for species <I>k</I>.
43  *
44  * \f[
45  * u^o_k = h^o_k
46  * \f]
47  *
48  * Also, the standard state chemical potentials, entropy, and heat capacities
49  * are independent of pressure. The standard state gibbs free energy is obtained
50  * from the enthalpy and entropy functions.
51  *
52  * <b> Specification of Solution Thermodynamic Properties </b>
53  *
54  * The activity of species defined in the phase is given by
55  * \f[
56  * a_k = \theta_k
57  * \f]
58  *
59  * The chemical potential for species <I>k</I> is equal to
60  * \f[
61  * \mu_k(T,P) = \mu^o_k(T) + R T \log(\theta_k)
62  * \f]
63  *
64  * Pressure is defined as an independent variable in this phase. However, it has
65  * no effect on any quantities, as the molar concentration is a constant.
66  *
67  * The internal energy for species k is equal to the enthalpy for species <I>k</I>
68  * \f[
69  * u_k = h_k
70  * \f]
71  *
72  * The entropy for the phase is given by the following relation, which is
73  * independent of the pressure:
74  *
75  * \f[
76  * s_k(T,P) = s^o_k(T) - R \log(\theta_k)
77  * \f]
78  *
79  * <b> Application within %Kinetics Managers </b>
80  *
81  * The activity concentration,\f$ C^a_k \f$, used by the kinetics manager, is equal to
82  * the actual concentration, \f$ C^s_k \f$, and is given by the following
83  * expression.
84  * \f[
85  * C^a_k = C^s_k = \frac{\theta_k n_0}{s_k}
86  * \f]
87  *
88  * The standard concentration for species <I>k</I> is:
89  * \f[
90  * C^0_k = \frac{n_0}{s_k}
91  * \f]
92  *
93  * <b> Instantiation of the Class </b>
94  *
95  * The constructor for this phase is located in the default ThermoFactory
96  * for Cantera. A new SurfPhase may be created by the following code snippet:
97  *
98  * @code
99  * XML_Node *xc = get_XML_File("diamond.xml");
100  * XML_Node * const xs = xc->findNameID("phase", "diamond_100");
101  * ThermoPhase *diamond100TP_tp = newPhase(*xs);
102  * SurfPhase *diamond100TP = dynamic_cast <SurfPhase *>(diamond100TP_tp);
103  * @endcode
104  *
105  * or by the following constructor:
106  *
107  * @code
108  * XML_Node *xc = get_XML_File("diamond.xml");
109  * XML_Node * const xs = xc->findNameID("phase", "diamond_100");
110  * SurfPhase *diamond100TP = new SurfPhase(*xs);
111  * @endcode
112  *
113  * <b> XML Example </b>
114  *
115  * An example of an XML Element named phase setting up a SurfPhase object named diamond_100
116  * is given below.
117  *
118  * @verbatim
119  * <phase dim="2" id="diamond_100">
120  * <elementArray datasrc="elements.xml">H C</elementArray>
121  * <speciesArray datasrc="#species_data">c6HH c6H* c6*H c6** c6HM c6HM* c6*M c6B </speciesArray>
122  * <reactionArray datasrc="#reaction_data"/>
123  * <state>
124  * <temperature units="K">1200.0</temperature>
125  * <coverages>c6H*:0.1, c6HH:0.9</coverages>
126  * </state>
127  * <thermo model="Surface">
128  * <site_density units="mol/cm2">3e-09</site_density>
129  * </thermo>
130  * <kinetics model="Interface"/>
131  * <transport model="None"/>
132  * <phaseArray>
133  * gas_phase diamond_bulk
134  * </phaseArray>
135  * </phase>
136  *
137  * @endverbatim
138  *
139  * The model attribute, "Surface", on the thermo element identifies the phase as being
140  * a SurfPhase object.
141  *
142  * @ingroup thermoprops
143  */
144 class SurfPhase : public ThermoPhase
145 {
146 
147 public:
148 
149  //! Constructor.
150  /*!
151  * @param n0 Site Density of the Surface Phase
152  * Units: kmol m-2.
153  */
154  SurfPhase(doublereal n0 = 0.0);
155 
156  //! Construct and initialize a SurfPhase ThermoPhase object
157  //! directly from an ASCII input file
158  /*!
159  * @param infile name of the input file
160  * @param id name of the phase id in the file.
161  * If this is blank, the first phase in the file is used.
162  */
163  SurfPhase(std::string infile, std::string id);
164 
165  //! Construct and initialize a SurfPhase ThermoPhase object
166  //! directly from an XML database
167  /*!
168  * @param xmlphase XML node pointing to a SurfPhase description
169  */
170  SurfPhase(XML_Node& xmlphase);
171 
172  //! Copy Constructor
173  /*!
174  * Copy constructor for the object. Constructed
175  * object will be a clone of this object, but will
176  * also own all of its data.
177  * This is a wrapper around the assignment operator
178  *
179  * @param right Object to be copied.
180  */
181  SurfPhase(const SurfPhase& right);
182 
183  //! Assignment operator
184  /*!
185  * Assignment operator for the object. Constructed
186  * object will be a clone of this object, but will
187  * also own all of its data.
188  *
189  * @param right Object to be copied.
190  */
191  SurfPhase& operator=(const SurfPhase& right);
192 
193  //! Destructor.
194  virtual ~SurfPhase();
195 
196  //! Duplicator from the %ThermoPhase parent class
197  /*
198  * Given a pointer to a %ThermoPhase object, this function will
199  * duplicate the %ThermoPhase object and all underlying structures.
200  * This is basically a wrapper around the copy constructor.
201  *
202  * @return returns a pointer to a %ThermoPhase
203  */
205 
206  //----- reimplemented methods of class ThermoPhase ------
207 
208  //! Equation of state type flag.
209  /*!
210  * Redefine this to return cSurf, listed in mix_defs.h.
211  */
212  virtual int eosType() const {
213  return cSurf;
214  }
215 
216  //! Return the Molar Enthalpy. Units: J/kmol.
217  /*!
218  * For an ideal solution,
219  * \f[
220  * \hat h(T,P) = \sum_k X_k \hat h^0_k(T),
221  * \f]
222  * and is a function only of temperature.
223  * The standard-state pure-species Enthalpies
224  * \f$ \hat h^0_k(T) \f$ are computed by the species thermodynamic
225  * property manager.
226  *
227  * \see SpeciesThermo
228  */
229  virtual doublereal enthalpy_mole() const;
230 
231  //! Return the Molar Internal Energy. Units: J/kmol
232  /**
233  * For a surface phase, the pressure is not a relevant
234  * thermodynamic variable, and so the Enthalpy is equal to the
235  * Internal Energy.
236  */
237  virtual doublereal intEnergy_mole() const;
238 
239  //! Get the species chemical potentials. Units: J/kmol.
240  /*!
241  * This function returns a vector of chemical potentials of the
242  * species in solution at the current temperature, pressure
243  * and mole fraction of the solution.
244  *
245  * @param mu Output vector of species chemical
246  * potentials. Length: m_kk. Units: J/kmol
247  */
248  virtual void getChemPotentials(doublereal* mu) const;
249 
250  //! Returns an array of partial molar enthalpies for the species
251  //! in the mixture. Units (J/kmol)
252  /*!
253  * @param hbar Output vector of species partial molar enthalpies.
254  * Length: m_kk. units are J/kmol.
255  */
256  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
257 
258  //! Returns an array of partial molar entropies of the species in the
259  //! solution. Units: J/kmol/K.
260  /*!
261  * @param sbar Output vector of species partial molar entropies.
262  * Length = m_kk. units are J/kmol/K.
263  */
264  virtual void getPartialMolarEntropies(doublereal* sbar) const;
265 
266 
267 
268  //! Return an array of partial molar heat capacities for the
269  //! species in the mixture. Units: J/kmol/K
270  /*!
271  * @param cpbar Output vector of species partial molar heat
272  * capacities at constant pressure.
273  * Length = m_kk. units are J/kmol/K.
274  */
275  virtual void getPartialMolarCp(doublereal* cpbar) const;
276 
277  //! Return an array of partial molar volumes for the
278  //! species in the mixture. Units: m^3/kmol.
279  /*!
280  * @param vbar Output vector of species partial molar volumes.
281  * Length = m_kk. units are m^3/kmol.
282  */
283  virtual void getPartialMolarVolumes(doublereal* vbar) const;
284 
285  //! Get the array of chemical potentials at unit activity for the
286  //! standard state species at the current <I>T</I> and <I>P</I> of the solution.
287  /*!
288  * These are the standard state chemical potentials \f$ \mu^0_k(T,P)
289  * \f$. The values are evaluated at the current
290  * temperature and pressure of the solution
291  *
292  * @param mu0 Output vector of chemical potentials.
293  * Length: m_kk.
294  */
295  virtual void getStandardChemPotentials(doublereal* mu0) const;
296 
297 
298 
299  //! Return a vector of activity concentrations for each species
300  /*!
301  * For this phase the activity concentrations,\f$ C^a_k \f$, are defined to be
302  * equal to the actual concentrations, \f$ C^s_k \f$.
303  * Activity concentrations are
304  *
305  * \f[
306  * C^a_k = C^s_k = \frac{\theta_k n_0}{s_k}
307  * \f]
308  *
309  * where \f$ \theta_k \f$ is the surface site fraction for species k,
310  * \f$ n_0 \f$ is the surface site density for the phase, and
311  * \f$ s_k \f$ is the surface size of species k.
312  *
313  * \f$ C^a_k\f$ that are defined such that \f$ a_k = C^a_k /
314  * C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration
315  * defined below and \f$ a_k \f$ are activities used in
316  * the thermodynamic functions. These activity concentrations are used
317  * by kinetics manager classes to compute the forward and
318  * reverse rates of elementary reactions. Note that they may
319  * or may not have units of concentration --- they might be
320  * partial pressures, mole fractions, or surface coverages,
321  *
322  * @param c vector of activity concentration (kmol m-2).
323  */
324  virtual void getActivityConcentrations(doublereal* c) const;
325 
326  //! Return the standard concentration for the kth species
327  /*!
328  * The standard concentration \f$ C^0_k \f$ used to normalize
329  * the activity (i.e., generalized) concentration.
330  * For this phase, the standard concentration is species-
331  * specific
332  *
333  * \f[
334  * C^0_k = \frac{n_0}{s_k}
335  * \f]
336  *
337  * This definition implies that the activity is equal to \f$ \theta_k \f$.
338  *
339  * @param k Optional parameter indicating the species. The default
340  * is to assume this refers to species 0.
341  * @return
342  * Returns the standard Concentration in units of m3 kmol-1.
343  */
344  virtual doublereal standardConcentration(size_t k = 0) const;
345 
346  //! Return the log of the standard concentration for the kth species
347  /*!
348  * @param k species index (default 0)
349  */
350  virtual doublereal logStandardConc(size_t k=0) const;
351 
352  //! Set the equation of state parameters from the argument list
353  /*!
354  * @internal
355  * Set equation of state parameters.
356  *
357  * @param n number of parameters. Must be one
358  * @param c array of \a n coefficients
359  * c[0] = The site density (kmol m-2)
360  */
361  virtual void setParameters(int n, doublereal* const c);
362 
363  //! Set the Equation-of-State parameters by reading an XML Node Input
364  /*!
365  *
366  * The Equation-of-State data consists of one item, the site density.
367  *
368  * @param thermoData Reference to an XML_Node named thermo
369  * containing the equation-of-state data. The
370  * XML_Node is within the phase XML_Node describing
371  * the %SurfPhase object.
372  *
373  * An example of the contents of the thermoData XML_Node is provided
374  * below. The units attribute is used to supply the units of the
375  * site density in any convenient form. Internally it is changed
376  * into MKS form.
377  *
378  * @verbatim
379  * <thermo model="Surface">
380  * <site_density units="mol/cm2"> 3e-09 </site_density>
381  * </thermo>
382  * @endverbatim
383  */
384  virtual void setParametersFromXML(const XML_Node& thermoData);
385 
386 
387  //! Initialize the SurfPhase object after all species have been set up
388  /*!
389  * @internal Initialize.
390  *
391  * This method is provided to allow
392  * subclasses to perform any initialization required after all
393  * species have been added. For example, it might be used to
394  * resize internal work arrays that must have an entry for
395  * each species. The base class implementation does nothing,
396  * and subclasses that do not require initialization do not
397  * need to overload this method. When importing a CTML phase
398  * description, this method is called from ThermoPhase::initThermoXML(),
399  * which is called from importPhase(),
400  * just prior to returning from function importPhase().
401  *
402  * @see importCTML.cpp
403  */
404  virtual void initThermo();
405 
406 
407  //! Set the initial state of the Surface Phase from an XML_Node
408  /*!
409  * State variables that can be set by this routine are
410  * the temperature and the surface site coverages.
411  *
412  * @param state XML_Node containing the state information
413  *
414  * An example of the XML code block is given below.
415  *
416  * @verbatim
417  * <state>
418  * <temperature units="K">1200.0</temperature>
419  * <coverages>c6H*:0.1, c6HH:0.9</coverages>
420  * </state>
421  * @endverbatim
422  */
423  virtual void setStateFromXML(const XML_Node& state);
424 
425  //! Returns the site density
426  /*!
427  * Site density kmol m-2
428  */
429  doublereal siteDensity() {
430  return m_n0;
431  }
432 
433  //! Sets the potential energy of species k.
434  /*!
435  *
436  * @param k Species index
437  * @param pe Value of the potential energy (J kmol-1)
438  */
439  void setPotentialEnergy(int k, doublereal pe);
440 
441  //! Return the potential energy of species k.
442  /*!
443  * Returns the potential energy of species, k,
444  * J kmol-1
445  *
446  * @param k Species index
447  */
448  doublereal potentialEnergy(int k) {
449  return m_pe[k];
450  }
451 
452  //! Set the site density of the surface phase (kmol m-2)
453  /*!
454  * @param n0 Site density of the surface phase (kmol m-2)
455  */
456  void setSiteDensity(doublereal n0);
457 
458  //! Get the nondimensional Gibbs functions for the species
459  //! in their standard states at the current <I>T</I> and <I>P</I> of the solution.
460  /*!
461  * @param grt Output vector of nondimensional standard state gibbs free energies
462  * Length: m_kk.
463  */
464  virtual void getGibbs_RT(doublereal* grt) const;
465 
466  //! Get the nondimensional Enthalpy functions for the species standard states
467  //! at their standard states at the current <I>T</I> and <I>P</I> of the solution.
468  /*!
469  * @param hrt Output vector of nondimensional standard state enthalpies.
470  * Length: m_kk.
471  */
472  virtual void getEnthalpy_RT(doublereal* hrt) const;
473 
474  //! Get the array of nondimensional Entropy functions for the
475  //! species standard states at the current <I>T</I> and <I>P</I> of the solution.
476  /*!
477  * @param sr Output vector of nondimensional standard state entropies.
478  * Length: m_kk.
479  */
480  virtual void getEntropy_R(doublereal* sr) const;
481 
482  //! Get the nondimensional Heat Capacities at constant
483  //! pressure for the species standard states
484  //! at the current <I>T</I> and <I>P</I> of the solution
485  /*!
486  * @param cpr Output vector of nondimensional standard state heat capacities
487  * Length: m_kk.
488  */
489  virtual void getCp_R(doublereal* cpr) const;
490 
491  //! Get the molar volumes of the species standard states at the current
492  //! <I>T</I> and <I>P</I> of the solution.
493  /*!
494  * units = m^3 / kmol
495  *
496  * @param vol Output vector containing the standard state volumes.
497  * Length: m_kk.
498  */
499  virtual void getStandardVolumes(doublereal* vol) const;
500 
501  //! Return the thermodynamic pressure (Pa).
502  /*!
503  * This method must be overloaded in derived classes. Since the
504  * mass density, temperature, and mass fractions are stored,
505  * this method should use these values to implement the
506  * mechanical equation of state \f$ P(T, \rho, Y_1, \dots,
507  * Y_K) \f$.
508  */
509  virtual doublereal pressure() const {
510  return m_press;
511  }
512 
513  //! Set the internally stored pressure (Pa) at constant
514  //! temperature and composition
515  /*!
516  * This method must be reimplemented in derived classes, where it
517  * may involve the solution of a nonlinear equation. Within %Cantera,
518  * the independent variable is the density. Therefore, this function
519  * solves for the density that will yield the desired input pressure.
520  * The temperature and composition iare held constant during this process.
521  *
522  * This base class function will print an error, if not overwritten.
523  *
524  * @param p input Pressure (Pa)
525  */
526  virtual void setPressure(doublereal p) {
527  m_press = p;
528  }
529 
530  //! Returns the vector of nondimensional
531  //! Gibbs Free Energies of the reference state at the current temperature
532  //! of the solution and the reference pressure for the species.
533  /*!
534  * @param grt Output vector containing the nondimensional reference state
535  * Gibbs Free energies. Length: m_kk.
536  */
537  virtual void getGibbs_RT_ref(doublereal* grt) const;
538 
539  //! Returns the vector of nondimensional
540  //! enthalpies of the reference state at the current temperature
541  //! of the solution and the reference pressure for the species.
542  /*!
543  * @param hrt Output vector of nondimensional standard state enthalpies.
544  * Length: m_kk.
545  */
546  virtual void getEnthalpy_RT_ref(doublereal* hrt) const;
547 
548 #ifdef H298MODIFY_CAPABILITY
549 
550  //! Modify the value of the 298 K Heat of Formation of one species in the phase (J kmol-1)
551  /*!
552  * The 298K heat of formation is defined as the enthalpy change to create the standard state
553  * of the species from its constituent elements in their standard states at 298 K and 1 bar.
554  *
555  * @param k Species k
556  * @param Hf298New Specify the new value of the Heat of Formation at 298K and 1 bar
557  */
558  virtual void modifyOneHf298SS(const int k, const doublereal Hf298New) {
559  m_spthermo->modifyOneHf298(k, Hf298New);
560  m_tlast += 0.0001234;
561  }
562 #endif
563 
564  //! Returns the vector of nondimensional
565  //! entropies of the reference state at the current temperature
566  //! of the solution and the reference pressure for each species.
567  /*!
568  * @param er Output vector containing the nondimensional reference state
569  * entropies. Length: m_kk.
570  */
571  virtual void getEntropy_R_ref(doublereal* er) const;
572 
573  //! Returns the vector of nondimensional
574  //! constant pressure heat capacities of the reference state
575  //! at the current temperature of the solution
576  //! and reference pressure for each species.
577  /*!
578  * @param cprt Output vector of nondimensional reference state
579  * heat capacities at constant pressure for the species.
580  * Length: m_kk
581  */
582  virtual void getCp_R_ref(doublereal* cprt) const;
583 
584 
585  //------- new methods defined in this class ----------
586 
587  //! Set the surface site fractions to a specified state.
588  /*!
589  * This routine converts to concentrations
590  * in kmol/m2, using m_n0, the surface site density,
591  * and size(k), which is defined to be the number of
592  * surface sites occupied by the kth molecule.
593  * It then calls Phase::setConcentrations to set the
594  * internal concentration in the object.
595  *
596  * @param theta This is the surface site fraction
597  * for the kth species in the surface phase.
598  * This is a dimensionless quantity.
599  *
600  * This routine normalizes the theta's to 1, before application
601  */
602  void setCoverages(const doublereal* theta);
603 
604  //! Set the surface site fractions to a specified state.
605  /*!
606  * This routine converts to concentrations
607  * in kmol/m2, using m_n0, the surface site density,
608  * and size(k), which is defined to be the number of
609  * surface sites occupied by the kth molecule.
610  * It then calls Phase::setConcentrations to set the
611  * internal concentration in the object.
612  *
613  * @param theta This is the surface site fraction
614  * for the kth species in the surface phase.
615  * This is a dimensionless quantity.
616  */
617  void setCoveragesNoNorm(const doublereal* theta);
618 
619 
620  //! Set the coverages from a string of colon-separated name:value pairs.
621  /*!
622  * @param cov String containing colon-separated name:value pairs
623  */
624  void setCoveragesByName(std::string cov);
625 
626  //! Return a vector of surface coverages
627  /*!
628  * Get the coverages.
629  *
630  * @param theta Array theta must be at least as long as
631  * the number of species.
632  */
633  void getCoverages(doublereal* theta) const;
634 
635 protected:
636 
637  //! Surface site density (kmol m-2)
638  doublereal m_n0;
639 
640  //! log of the surface site density
641  doublereal m_logn0;
642 
643  //! Minimum temperature for valid species standard state thermo props
644  /*!
645  * This is the minimum temperature at which all species have valid standard
646  * state thermo props defined.
647  */
648  doublereal m_tmin;
649 
650  //! Maximum temperature for valid species standard state thermo props
651  /*!
652  * This is the maximum temperature at which all species have valid standard
653  * state thermo props defined.
654  */
655  doublereal m_tmax;
656 
657  //! Current value of the pressure (Pa)
658  doublereal m_press;
659 
660  //! Current value of the temperature (Kelvin)
661  mutable doublereal m_tlast;
662 
663  //! Temporary storage for the reference state enthalpies
664  mutable vector_fp m_h0;
665 
666  //! Temporary storage for the reference state entropies
667  mutable vector_fp m_s0;
668 
669  //! Temporary storage for the reference state heat capacities
670  mutable vector_fp m_cp0;
671 
672  //! Temporary storage for the reference state gibbs energies
673  mutable vector_fp m_mu0;
674 
675  //! Temporary work array
676  mutable vector_fp m_work;
677 
678  //! Potential energy of each species in the surface phase
679  /*!
680  * @todo Fix potential energy
681  * Note, the potential energy terms seem to be orphaned at the moment.
682  * They are not connected to the Gibbs free energy calculation in
683  * this object
684  *
685  * @deprecated
686  */
687  mutable vector_fp m_pe;
688 
689  //! vector storing the log of the size of each species.
690  /*!
691  * The size of each species is defined as the number of surface
692  * sites each species occupies.
693  */
695 
696 private:
697 
698  //! Update the species reference state thermodynamic functions
699  /*!
700  * The polynomials for the standard state functions are only
701  * reevaluated if the temperature has changed.
702  *
703  * @param force Boolean, which if true, forces a reevaluation
704  * of the thermo polynomials.
705  * default = false.
706  */
707  void _updateThermo(bool force=false) const;
708 
709 };
710 }
711 
712 #endif
713 
714 
715 
716 
717