Cantera  2.0
MolarityIonicVPSSTP.h
Go to the documentation of this file.
1 /**
2  * @file MolarityIonicVPSSTP.h
3  * Header for intermediate ThermoPhase object for phases which
4  * employ gibbs excess free energy based formulations
5  * (see \ref thermoprops
6  * and class \link Cantera::MolarityIonicVPSSTP MolarityIonicVPSSTP\endlink).
7  *
8  * Header file for a derived class of ThermoPhase that handles
9  * variable pressure standard state methods for calculating
10  * thermodynamic properties that are further based upon activities
11  * based on the molarity scale. In this class, we expect that there are
12  * ions, but they are treated on the molarity scale.
13  */
14 /*
15  * Copyright (2006) Sandia Corporation. Under the terms of
16  * Contract DE-AC04-94AL85000 with Sandia Corporation, the
17  * U.S. Government retains certain rights in this software.
18  */
19 
20 #ifndef CT_MOLARITYIONICVPSSTP_H
21 #define CT_MOLARITYIONICVPSSTP_H
22 
23 #include "GibbsExcessVPSSTP.h"
24 
25 namespace Cantera
26 {
27 
28 /**
29  * @ingroup thermoprops
30  */
31 
32 /*!
33  * MolarityIonicVPSSTP is a derived class of ThermoPhase
34  * GibbsExcessVPSSTP that handles
35  * variable pressure standard state methods for calculating
36  * thermodynamic properties that are further based on
37  * expressing the Excess Gibbs free energy as a function of
38  * the mole fractions (or pseudo mole fractions) of the constituents.
39  * This category is the workhorse for describing ionic systems which are not on the molality scale.
40  *
41  * This class adds additional functions onto the %ThermoPhase interface
42  * that handles the calculation of the excess Gibbs free energy. The %ThermoPhase
43  * class includes a member function, ThermoPhase::activityConvention()
44  * that indicates which convention the activities are based on. The
45  * default is to assume activities are based on the molar convention.
46  * That default is used here.
47  *
48  * All of the Excess Gibbs free energy formulations in this area employ
49  * symmetrical formulations.
50  *
51  * This layer will massage the mole fraction vector to implement
52  * cation and anion based mole numbers in an optional manner, such that
53  * it is expected that there exists a charge balance at all times.
54  * One of the ions must be a "special ion" in the sense that its' thermodynamic
55  * functions are set to zero, and the thermo functions of all other
56  * ions are based on a valuation relative to that special ion.
57  *
58  */
60 {
61 
62 public:
63 
64  /// Constructors
65  /*!
66  * This doesn't do much more than initialize constants with
67  * default values for water at 25C. Water molecular weight
68  * comes from the default elements.xml file. It actually
69  * differs slightly from the IAPWS95 value of 18.015268. However,
70  * density conservation and therefore element conservation
71  * is the more important principle to follow.
72  */
74 
75  //! Construct and initialize a MolarityIonicVPSSTP ThermoPhase object
76  //! directly from an xml input file
77  /*!
78  * Working constructors
79  *
80  * The two constructors below are the normal way the phase initializes itself. They are shells that call
81  * the routine initThermo(), with a reference to the XML database to get the info for the phase.
82  *
83  * @param inputFile Name of the input file containing the phase XML data
84  * to set up the object
85  * @param id ID of the phase in the input file. Defaults to the
86  * empty string.
87  */
88  MolarityIonicVPSSTP(std::string inputFile, std::string id = "");
89 
90  //! Construct and initialize a MolarityIonicVPSSTP ThermoPhase object
91  //! directly from an XML database
92  /*!
93  * @param phaseRef XML phase node containing the description of the phase
94  * @param id id attribute containing the name of the phase.
95  * (default is the empty string)
96  */
97  MolarityIonicVPSSTP(XML_Node& phaseRef, std::string id = "");
98 
99 
100  //! Copy constructor
101  /*!
102  * Note this stuff will not work until the underlying phase
103  * has a working copy constructor
104  *
105  * @param b class to be copied
106  */
108 
109  /// Assignment operator
110  /*!
111  *
112  * @param b class to be copied.
113  */
115 
116  /// Destructor.
117  virtual ~MolarityIonicVPSSTP();
118 
119  //! Duplication routine for objects which inherit from ThermoPhase.
120  /*!
121  * This virtual routine can be used to duplicate thermophase objects
122  * inherited from ThermoPhase even if the application only has
123  * a pointer to ThermoPhase to work with.
124  */
125  virtual ThermoPhase* duplMyselfAsThermoPhase() const;
126 
127  /**
128  *
129  * @name Utilities
130  * @{
131  */
132 
133 
134  //! Equation of state type flag.
135  /*!
136  * The ThermoPhase base class returns
137  * zero. Subclasses should define this to return a unique
138  * non-zero value. Known constants defined for this purpose are
139  * listed in mix_defs.h. The MolalityVPSSTP class also returns
140  * zero, as it is a non-complete class.
141  */
142  virtual int eosType() const;
143 
144  //! Initialization of a phase using an xml file
145  /*!
146  * This routine is a precursor to
147  * routine, which does most of the work.
148  *
149  * @param inputFile XML file containing the description of the
150  * phase
151  *
152  * @param id Optional parameter identifying the name of the
153  * phase. If none is given, the first XML
154  * phase element will be used.
155  */
156  void constructPhaseFile(std::string inputFile, std::string id);
157 
158  //! Import and initialize a phase
159  //! specification in an XML tree into the current object.
160  /*!
161  * Here we read an XML description of the phase.
162  * We import descriptions of the elements that make up the
163  * species in a phase.
164  * We import information about the species, including their
165  * reference state thermodynamic polynomials. We then freeze
166  * the state of the species.
167  *
168  * Then, we read the species molar volumes from the xml
169  * tree to finish the initialization.
170  *
171  * @param phaseNode This object must be the phase node of a
172  * complete XML tree
173  * description of the phase, including all of the
174  * species data. In other words while "phase" must
175  * point to an XML phase object, it must have
176  * sibling nodes "speciesData" that describe
177  * the species in the phase.
178  *
179  * @param id ID of the phase. If nonnull, a check is done
180  * to see if phaseNode is pointing to the phase
181  * with the correct id.
182  */
183  void constructPhaseXML(XML_Node& phaseNode, std::string id);
184 
185  /**
186  * @}
187  * @name Molar Thermodynamic Properties
188  * @{
189  */
190 
191 
192  /**
193  * @}
194  * @name Utilities for Solvent ID and Molality
195  * @{
196  */
197 
198 
199 
200 
201  /**
202  * @}
203  * @name Mechanical Properties
204  * @{
205  */
206 
207  /**
208  * @}
209  * @name Potential Energy
210  *
211  * Species may have an additional potential energy due to the
212  * presence of external gravitation or electric fields. These
213  * methods allow specifying a potential energy for individual
214  * species.
215  * @{
216  */
217 
218  /**
219  * @}
220  * @name Activities, Standard States, and Activity Concentrations
221  *
222  * The activity \f$a_k\f$ of a species in solution is
223  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
224  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
225  * the chemical potential at unit activity, which depends only
226  * on temperature and pressure.
227  * @{
228  */
229 
230  //! Get the array of non-dimensional molar-based ln activity coefficients at
231  //! the current solution temperature, pressure, and solution concentration.
232  /*!
233  * @param lnac Output vector of ln activity coefficients. Length: m_kk.
234  */
235  virtual void getLnActivityCoefficients(doublereal* lnac) const;
236 
237  //@}
238  /// @name Partial Molar Properties of the Solution
239  //@{
240 
241  //! Get the species chemical potentials. Units: J/kmol.
242  /*!
243  * This function returns a vector of chemical potentials of the
244  * species in solution at the current temperature, pressure
245  * and mole fraction of the solution.
246  *
247  * @param mu Output vector of species chemical
248  * potentials. Length: m_kk. Units: J/kmol
249  */
250  virtual void getChemPotentials(doublereal* mu) const;
251 
252  /**
253  * Get the species electrochemical potentials.
254  * These are partial molar quantities.
255  * This method adds a term \f$ Fz_k \phi_k \f$ to the
256  * to each chemical potential.
257  *
258  * Units: J/kmol
259  *
260  * @param mu output vector containing the species electrochemical potentials.
261  * Length: m_kk.
262  */
263  void getElectrochemPotentials(doublereal* mu) const;
264 
265  //! Returns an array of partial molar enthalpies for the species
266  //! in the mixture.
267  /*!
268  * Units (J/kmol)
269  *
270  * For this phase, the partial molar enthalpies are equal to the
271  * standard state enthalpies modified by the derivative of the
272  * molality-based activity coefficient wrt temperature
273  *
274  * \f[
275  * \bar h_k(T,P) = h^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
276  * \f]
277  *
278  * @param hbar Vector of returned partial molar enthalpies
279  * (length m_kk, units = J/kmol)
280  */
281  virtual void getPartialMolarEnthalpies(doublereal* hbar) const;
282 
283  //! Returns an array of partial molar entropies for the species
284  //! in the mixture.
285  /*!
286  * Units (J/kmol)
287  *
288  * For this phase, the partial molar enthalpies are equal to the
289  * standard state enthalpies modified by the derivative of the
290  * activity coefficient wrt temperature
291  *
292  * \f[
293  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
294  * - R \ln( \gamma_k X_k)
295  * - R T \frac{d \ln(\gamma_k) }{dT}
296  * \f]
297  *
298  * @param sbar Vector of returned partial molar entropies
299  * (length m_kk, units = J/kmol/K)
300  */
301  virtual void getPartialMolarEntropies(doublereal* sbar) const;
302 
303  //! Returns an array of partial molar entropies for the species
304  //! in the mixture.
305  /*!
306  * Units (J/kmol)
307  *
308  * For this phase, the partial molar enthalpies are equal to the
309  * standard state enthalpies modified by the derivative of the
310  * activity coefficient wrt temperature
311  *
312  * \f[
313  * ???????????????
314  * \bar s_k(T,P) = s^o_k(T,P) - R T^2 \frac{d \ln(\gamma_k)}{dT}
315  * - R \ln( \gamma_k X_k)
316  * - R T \frac{d \ln(\gamma_k) }{dT}
317  * ???????????????
318  * \f]
319  *
320  * @param cpbar Vector of returned partial molar heat capacities
321  * (length m_kk, units = J/kmol/K)
322  */
323  virtual void getPartialMolarCp(doublereal* cpbar) const;
324 
325  //! Return an array of partial molar volumes for the
326  //! species in the mixture. Units: m^3/kmol.
327  /*!
328  * Frequently, for this class of thermodynamics representations,
329  * the excess Volume due to mixing is zero. Here, we set it as
330  * a default. It may be overridden in derived classes.
331  *
332  * @param vbar Output vector of species partial molar volumes.
333  * Length = m_kk. units are m^3/kmol.
334  */
335  virtual void getPartialMolarVolumes(doublereal* vbar) const;
336 
337 
338  //@}
339  /// @name Properties of the Standard State of the Species in the Solution
340  //@{
341 
342 
343 
344  //@}
345  /// @name Thermodynamic Values for the Species Reference States
346  //@{
347 
348 
349  ///////////////////////////////////////////////////////
350  //
351  // The methods below are not virtual, and should not
352  // be overloaded.
353  //
354  //////////////////////////////////////////////////////
355 
356  /**
357  * @name Specific Properties
358  * @{
359  */
360 
361 
362  /**
363  * @name Setting the State
364  *
365  * These methods set all or part of the thermodynamic
366  * state.
367  * @{
368  */
369 
370  //! Calculate pseudo binary mole fractions
371  /*!
372  *
373  */
374  virtual void calcPseudoBinaryMoleFractions() const;
375 
376 
377  //@}
378 
379  /**
380  * @name Chemical Equilibrium
381  * Routines that implement the Chemical equilibrium capability
382  * for a single phase, based on the element-potential method.
383  * @{
384  */
385 
386 
387 
388  //@}
389 
390 
391 
392  /// The following methods are used in the process of constructing
393  /// the phase and setting its parameters from a specification in an
394  /// input file. They are not normally used in application programs.
395  /// To see how they are used, see files importCTML.cpp and
396  /// ThermoFactory.cpp.
397 
398 
399  /*!
400  * @internal Initialize. This method is provided to allow
401  * subclasses to perform any initialization required after all
402  * species have been added. For example, it might be used to
403  * resize internal work arrays that must have an entry for
404  * each species. The base class implementation does nothing,
405  * and subclasses that do not require initialization do not
406  * need to overload this method. When importing a CTML phase
407  * description, this method is called just prior to returning
408  * from function importPhase.
409  *
410  * @see importCTML.cpp
411  */
412  virtual void initThermo();
413 
414 
415  /**
416  * Import and initialize a ThermoPhase object
417  *
418  * @param phaseNode This object must be the phase node of a
419  * complete XML tree
420  * description of the phase, including all of the
421  * species data. In other words while "phase" must
422  * point to an XML phase object, it must have
423  * sibling nodes "speciesData" that describe
424  * the species in the phase.
425  * @param id ID of the phase. If nonnull, a check is done
426  * to see if phaseNode is pointing to the phase
427  * with the correct id.
428  */
429  void initThermoXML(XML_Node& phaseNode, std::string id);
430 
431 
432  //! returns a summary of the state of the phase as a string
433  /*!
434  * @param show_thermo If true, extra information is printed out
435  * about the thermodynamic state of the system.
436  */
437  virtual std::string report(bool show_thermo = true) const;
438 
439 
440 private:
441 
442 
443  //! Initialize lengths of local variables after all species have been identified.
444  void initLengths();
445 
446  //! Process an XML node called "binaryNeutralSpeciesParameters"
447  /*!
448  * This node contains all of the parameters necessary to describe
449  * the Redlich-Kister model for a particular binary interaction.
450  * This function reads the XML file and writes the coefficients
451  * it finds to an internal data structures.
452  *
453  * @param xmlBinarySpecies Reference to the XML_Node named "binaryNeutralSpeciesParameters"
454  * containing the binary interaction
455  */
456  void readXMLBinarySpecies(XML_Node& xmlBinarySpecies);
457 
458 
459  //! Update the activity coefficients
460  /*!
461  * This function will be called to update the internally stored
462  * natural logarithm of the activity coefficients
463  */
464  void s_update_lnActCoeff() const;
465 
466  //! Update the derivative of the log of the activity coefficients wrt T
467  /*!
468  * This function will be called to update the internally stored
469  * derivative of the natural logarithm of the activity coefficients
470  * wrt temperature.
471  */
472  void s_update_dlnActCoeff_dT() const;
473 
474  //! Internal routine that calculates the derivative of the activity coefficients wrt
475  //! the mole fractions.
476  /*!
477  * This routine calculates the the derivative of the activity coefficients wrt to mole fraction
478  * with all other mole fractions held constant. This is strictly not permitted. However, if the
479  * resulting matrix is multiplied by a permissible deltaX vector then everything is ok.
480  *
481  * This is the natural way to handle concentration derivatives in this routine.
482  */
483  void s_update_dlnActCoeff_dX_() const;
484 
485 
486 private:
487  //! Error function
488  /*!
489  * Print an error string and exit
490  *
491  * @param msg Message to be printed
492  */
493  doublereal err(std::string msg) const;
494 
495 protected:
496 
497  // Pseudobinary type
498  /*!
499  * PBTYPE_PASSTHROUGH All species are passthrough species
500  * PBTYPE_SINGLEANION there is only one anion in the mixture
501  * PBTYPE_SINGLECATION there is only one cation in the mixture
502  * PBTYPE_MULTICATIONANION Complex mixture
503  */
504  int PBType_;
505 
506  //! Number of pseudo binary species
508 
509  //! index of special species
511 
512  mutable std::vector<doublereal> PBMoleFractions_;
513 
514  //! Vector of cation indices in the mixture
515  std::vector<size_t> cationList_;
516 
517  //! Number of cations in the mixture
519 
520  std::vector<size_t> anionList_;
521  size_t numAnionSpecies_;
522 
523  std::vector<size_t> passThroughList_;
524  size_t numPassThroughSpecies_;
525  size_t neutralPBindexStart;
526 
527  mutable std::vector<doublereal> moleFractionsTmp_;
528 
529 private:
530 
531 
532 };
533 
534 #define PBTYPE_PASSTHROUGH 0
535 #define PBTYPE_SINGLEANION 1
536 #define PBTYPE_SINGLECATION 2
537 #define PBTYPE_MULTICATIONANION 3
538 
539 
540 
541 }
542 
543 #endif
544 
545 
546 
547 
548