Cantera  2.2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MolalityVPSSTP.h
Go to the documentation of this file.
1 /**
2  * @file MolalityVPSSTP.h
3  * Header for intermediate ThermoPhase object for phases which
4  * employ molality based activity coefficient formulations
5  * (see \ref thermoprops
6  * and class \link Cantera::MolalityVPSSTP MolalityVPSSTP\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 molality scale. These include most of the methods for
12  * calculating liquid electrolyte thermodynamics.
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 #ifndef CT_MOLALITYVPSSTP_H
20 #define CT_MOLALITYVPSSTP_H
21 
22 #include "VPStandardStateTP.h"
23 
24 namespace Cantera
25 {
26 
27 /**
28  * @ingroup thermoprops
29  */
30 
31 /*!
32  * MolalityVPSSTP is a derived class of ThermoPhase that handles
33  * variable pressure standard state methods for calculating
34  * thermodynamic properties that are further based on
35  * molality-scaled activities.
36  * This category incorporates most of the methods
37  * for calculating liquid electrolyte thermodynamics that have been
38  * developed since the 1970's.
39  *
40  * This class adds additional functions onto the ThermoPhase interface
41  * that handle molality based standard states. The ThermoPhase
42  * class includes a member function, ThermoPhase::activityConvention()
43  * that indicates which convention the activities are based on. The
44  * default is to assume activities are based on the molar convention.
45  * However, classes which derive from the MolalityVPSSTP class return
46  * <b>cAC_CONVENTION_MOLALITY</b> from this member function.
47  *
48  * The molality of a solute, \f$ m_i \f$, is defined as
49  *
50  * \f[
51  * m_i = \frac{n_i}{\tilde{M}_o n_o}
52  * \f]
53  * where
54  * \f[
55  * \tilde{M}_o = \frac{M_o}{1000}
56  * \f]
57  *
58  * where \f$ M_o \f$ is the molecular weight of the solvent. The molality
59  * has units of gmol kg<SUP>-1</SUP>. For the solute, the molality may be
60  * considered as the amount of gmol's of solute per kg of solvent, a natural
61  * experimental quantity.
62  *
63  * The formulas for calculating mole fractions if given the molalities of
64  * the solutes is stated below. First calculate \f$ L^{sum} \f$, an intermediate
65  * quantity.
66  *
67  * \f[
68  * L^{sum} = \frac{1}{\tilde{M}_o X_o} = \frac{1}{\tilde{M}_o} + \sum_{i\ne o} m_i
69  * \f]
70  * Then,
71  * \f[
72  * X_o = \frac{1}{\tilde{M}_o L^{sum}}
73  * \f]
74  * \f[
75  * X_i = \frac{m_i}{L^{sum}}
76  * \f]
77  * where \f$ X_o \f$ is the mole fraction of solvent, and \f$ X_o \f$ is the
78  * mole fraction of solute <I>i</I>. Thus, the molality scale and the mole fraction
79  * scale offer a one-to-one mapping between each other, except in the limit
80  * of a zero solvent mole fraction.
81  *
82  * The standard states for thermodynamic objects that derive from <b>MolalityVPSSTP</b>
83  * are on the unit molality basis. Chemical potentials
84  * of the solutes, \f$ \mu_k \f$, and the solvent, \f$ \mu_o \f$, which are based
85  * on the molality form, have the following general format:
86  *
87  * \f[
88  * \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle})
89  * \f]
90  * \f[
91  * \mu_o = \mu^o_o(T,P) + RT ln(a_o)
92  * \f]
93  *
94  * where \f$ \gamma_k^{\triangle} \f$ is the molality based activity coefficient for species
95  * \f$k\f$.
96  *
97  * The chemical potential of the solvent is thus expressed in a different format
98  * than the chemical potential of the solutes. Additionally, the activity of the
99  * solvent, \f$ a_o \f$, is further reexpressed in terms of an osmotic coefficient,
100  * \f$ \phi \f$.
101  * \f[
102  * \phi = \frac{- ln(a_o)}{\tilde{M}_o \sum_{i \ne o} m_i}
103  * \f]
104  *
105  * MolalityVPSSTP::osmoticCoefficient() returns the value of \f$ \phi \f$.
106  * Note there are a few of definitions of the osmotic coefficient floating
107  * around. We use the one defined in
108  * (Activity Coefficients in Electrolyte Solutions, K. S. Pitzer
109  * CRC Press, Boca Raton, 1991, p. 85, Eqn. 28). This definition is most clearly
110  * related to theoretical calculation.
111  *
112  * The molar-based activity coefficients \f$ \gamma_k \f$ may be calculated
113  * from the molality-based
114  * activity coefficients, \f$ \gamma_k^\triangle \f$ by the following
115  * formula.
116  * \f[
117  * \gamma_k = \frac{\gamma_k^\triangle}{X_o}
118  * \f]
119  * For purposes of establishing a convention, the molar activity coefficient of the
120  * solvent is set equal to the molality-based activity coefficient of the
121  * solvent:
122  * \f[
123  * \gamma_o = \gamma_o^\triangle
124  * \f]
125  *
126  * The molality-based and molarity-based standard states may be related to one
127  * another by the following formula.
128  *
129  * \f[
130  * \mu_k^\triangle(T,P) = \mu_k^o(T,P) + R T \ln(\tilde{M}_o m^\triangle)
131  * \f]
132  *
133  * An important convention is followed in all routines that derive from MolalityVPSSTP.
134  * Standard state thermodynamic functions and reference state thermodynamic functions
135  * return the molality-based quantities. Also all functions which return
136  * activities return the molality-based activities. The reason for this convention
137  * has been discussed in supporting memos. However, it's important because the
138  * term in the equation above is non-trivial. For example it's equal
139  * to 2.38 kcal gmol<SUP>-1</SUP> for water at 298 K.
140  *
141  *
142  * In order to prevent a singularity, this class includes the concept of a minimum
143  * value for the solvent mole fraction. All calculations involving the formulation
144  * of activity coefficients and other non-ideal solution behavior adhere to
145  * this concept of a minimal value for the solvent mole fraction. This makes sense
146  * because these solution behavior were all designed and measured far away from
147  * the zero solvent singularity condition and are not applicable in that limit.
148  *
149  *
150  * This objects add a layer that supports molality. It inherits from VPStandardStateTP.
151  *
152  * All objects that derive from this are assumed to have molality based standard states.
153  *
154  * Molality based activity coefficients are scaled according to the current
155  * pH scale. See the Eq3/6 manual for details.
156  *
157  * Activity coefficients for species k may be altered between scales s1 to s2
158  * using the following formula
159  *
160  * \f[
161  * ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
162  * + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
163  * \f]
164  *
165  * where j is any one species. For the NBS scale, j is equal to the Cl- species
166  * and
167  *
168  * \f[
169  * ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
170  * \f]
171  *
172  * The Pitzer scale doesn't actually change anything. The pitzer scale is defined
173  * as the raw unscaled activity coefficients produced by the underlying objects.
174  *
175  * <H3> SetState Strategy </H3>
176  *
177  * The MolalityVPSSTP object does not have a setState strategy concerning the
178  * molalities. It does not keep track of whether the molalities have changed.
179  * It's strictly an interfacial layer that writes the current mole fractions to the
180  * State object. When molalities are needed it recalculates the molalities from
181  * the State object's mole fraction vector.
182  *
183  *
184  * @todo Make two solvent minimum fractions. One would be for calculation of the non-ideal
185  * factors. The other one would be for purposes of stoichiometry evaluation. the
186  * stoichiometry evaluation one would be a 1E-13 limit. Anything less would create
187  * problems with roundoff error.
188  */
190 {
191 public:
192  /// Default Constructor
193  /*!
194  * This doesn't do much more than initialize constants with
195  * default values for water at 25C. Water molecular weight
196  * comes from the default elements.xml file. It actually
197  * differs slightly from the IAPWS95 value of 18.015268. However,
198  * density conservation and therefore element conservation
199  * is the more important principle to follow.
200  */
201  MolalityVPSSTP();
202 
203  //! Copy constructor
204  /*!
205  * @param b class to be copied
206  */
207  MolalityVPSSTP(const MolalityVPSSTP& b);
208 
209  /// Assignment operator
210  /*!
211  * @param b class to be copied.
212  */
214 
215  //! Duplication routine for objects which inherit from ThermoPhase.
216  /*!
217  * This virtual routine can be used to duplicate objects
218  * inherited from ThermoPhase even if the application only has
219  * a pointer to ThermoPhase to work with.
220  */
221  virtual ThermoPhase* duplMyselfAsThermoPhase() const;
222 
223  //! @name Utilities
224  //! @{
225 
226  //! Set the pH scale, which determines the scale for single-ion activity
227  //! coefficients.
228  /*!
229  * Single ion activity coefficients are not unique in terms of the
230  * representing actual measurable quantities.
231  *
232  * @param pHscaleType Integer representing the pHscale
233  */
234  void setpHScale(const int pHscaleType);
235 
236  //! Reports the pH scale, which determines the scale for single-ion activity
237  //! coefficients.
238  /*!
239  * Single ion activity coefficients are not unique in terms of the
240  * representing actual measurable quantities.
241  *
242  * @return Return the pHscale type
243  */
244  int pHScale() const;
245 
246  //! @}
247  //! @name Utilities for Solvent ID and Molality
248  //! @{
249 
250  /**
251  * This routine sets the index number of the solvent for the phase.
252  *
253  * Note, having a solvent is a precursor to many things having to do
254  * with molality.
255  *
256  * @param k the solvent index number
257  */
258  void setSolvent(size_t k);
259 
260  //! Returns the solvent index.
261  size_t solventIndex() const;
262 
263  /**
264  * Sets the minimum mole fraction in the molality formulation.
265  * Note the molality formulation is singular in the limit that
266  * the solvent mole fraction goes to zero. Numerically, how
267  * this limit is treated and resolved is an ongoing issue within
268  * Cantera. The minimum mole fraction must be in the range 0 to 0.9.
269  *
270  * @param xmolSolventMIN Input double containing the minimum mole fraction
271  */
272  void setMoleFSolventMin(doublereal xmolSolventMIN);
273 
274  //! Returns the minimum mole fraction in the molality formulation.
275  doublereal moleFSolventMin() const;
276 
277  //! Calculates the molality of all species and stores the result internally.
278  /*!
279  * We calculate the vector of molalities of the species
280  * in the phase and store the result internally:
281  * \f[
282  * m_i = \frac{X_i}{1000 * M_o * X_{o,p}}
283  * \f]
284  * where
285  * - \f$ M_o \f$ is the molecular weight of the solvent
286  * - \f$ X_o \f$ is the mole fraction of the solvent
287  * - \f$ X_i \f$ is the mole fraction of the solute.
288  * - \f$ X_{o,p} = \max (X_{o}^{min}, X_o) \f$
289  * - \f$ X_{o}^{min} \f$ = minimum mole fraction of solvent allowed
290  * in the denominator.
291  */
292  void calcMolalities() const;
293 
294  //! This function will return the molalities of the species.
295  /*!
296  * We calculate the vector of molalities of the species
297  * in the phase
298  * \f[
299  * m_i = \frac{X_i}{1000 * M_o * X_{o,p}}
300  * \f]
301  * where
302  * - \f$ M_o \f$ is the molecular weight of the solvent
303  * - \f$ X_o \f$ is the mole fraction of the solvent
304  * - \f$ X_i \f$ is the mole fraction of the solute.
305  * - \f$ X_{o,p} = \max (X_{o}^{min}, X_o) \f$
306  * - \f$ X_{o}^{min} \f$ = minimum mole fraction of solvent allowed
307  * in the denominator.
308  *
309  * @param molal Output vector of molalities. Length: m_kk.
310  */
311  void getMolalities(doublereal* const molal) const;
312 
313  //! Set the molalities of the solutes in a phase
314  /*!
315  * Note, the entry for the solvent is not used.
316  * We are supplied with the molalities of all of the
317  * solute species. We then calculate the mole fractions of all
318  * species and update the ThermoPhase object.
319  * \f[
320  * m_i = \frac{X_i}{M_o/1000 * X_{o,p}}
321  * \f]
322  * where
323  * - \f$M_o\f$ is the molecular weight of the solvent
324  * - \f$X_o\f$ is the mole fraction of the solvent
325  * - \f$X_i\f$ is the mole fraction of the solute.
326  * - \f$X_{o,p} = \max(X_o^{min}, X_o)\f$
327  * - \f$X_o^{min}\f$ = minimum mole fraction of solvent allowed
328  * in the denominator.
329  *
330  * The formulas for calculating mole fractions are
331  * \f[
332  * L^{sum} = \frac{1}{\tilde{M}_o X_o} = \frac{1}{\tilde{M}_o} + \sum_{i\ne o} m_i
333  * \f]
334  * Then,
335  * \f[
336  * X_o = \frac{1}{\tilde{M}_o L^{sum}}
337  * \f]
338  * \f[
339  * X_i = \frac{m_i}{L^{sum}}
340  * \f]
341  * It is currently an error if the solvent mole fraction is attempted to be set
342  * to a value lower than \f$X_o^{min}\f$.
343  *
344  * @param molal Input vector of molalities. Length: m_kk.
345  */
346  void setMolalities(const doublereal* const molal);
347 
348  //! Set the molalities of a phase
349  /*!
350  * Set the molalities of the solutes in a phase. Note, the entry for the
351  * solvent is not used.
352  *
353  * @param xMap Composition Map containing the molalities.
354  */
355  void setMolalitiesByName(const compositionMap& xMap);
356 
357  //! Set the molalities of a phase
358  /*!
359  * Set the molalities of the solutes in a phase. Note, the entry for the
360  * solvent is not used.
361  *
362  * @param name String containing the information for a composition map.
363  */
364  void setMolalitiesByName(const std::string& name);
365 
366  /**
367  * @}
368  * @name Activities, Standard States, and Activity Concentrations
369  *
370  * The activity \f$a_k\f$ of a species in solution is
371  * related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
372  * + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
373  * the chemical potential at unit activity, which depends only
374  * on temperature and pressure.
375  * @{
376  */
377 
378  /**
379  * This method returns the activity convention.
380  * Currently, there are two activity conventions:
381  * - Molar-based activities: %Unit activity of species at either a
382  * hypothetical pure solution of the species or at a hypothetical
383  * pure ideal solution at infinite dilution.
384  * `cAC_CONVENTION_MOLAR 0` (default)
385  * - Molality based activities: unit activity of solutes at a hypothetical
386  * 1 molal solution referenced to infinite dilution at all pressures and
387  * temperatures. The solvent is still on molar basis.
388  * `cAC_CONVENTION_MOLALITY 1`
389  *
390  * We set the convention to molality here.
391  */
392  int activityConvention() const;
393 
394  /**
395  * This method returns an array of generalized concentrations
396  * \f$ C_k\f$ that are defined such that
397  * \f$ a_k = C_k / C^0_k, \f$ where \f$ C^0_k \f$
398  * is a standard concentration
399  * defined below. These generalized concentrations are used
400  * by kinetics manager classes to compute the forward and
401  * reverse rates of elementary reactions.
402  *
403  * @param c Array of generalized concentrations. The
404  * units depend upon the implementation of the
405  * reaction rate expressions within the phase.
406  */
407  virtual void getActivityConcentrations(doublereal* c) const;
408 
409  /**
410  * The standard concentration \f$ C^0_k \f$ used to normalize
411  * the generalized concentration. In many cases, this quantity
412  * will be the same for all species in a phase - for example,
413  * for an ideal gas \f$ C^0_k = P/\hat R T \f$. For this
414  * reason, this method returns a single value, instead of an
415  * array. However, for phases in which the standard
416  * concentration is species-specific (e.g. surface species of
417  * different sizes), this method may be called with an
418  * optional parameter indicating the species.
419  *
420  * @param k species index. Defaults to zero.
421  */
422  virtual doublereal standardConcentration(size_t k=0) const;
423 
424  /**
425  * Returns the units of the standard and generalized
426  * concentrations Note they have the same units, as their
427  * ratio is defined to be equal to the activity of the kth
428  * species in the solution, which is unitless.
429  *
430  * This routine is used in print out applications where the
431  * units are needed. Usually, MKS units are assumed throughout
432  * the program and in the XML input files.
433  *
434  * @param uA Output vector containing the units
435  * uA[0] = kmol units - default = 1
436  * uA[1] = m units - default = -nDim(), the number of spatial
437  * dimensions in the Phase class.
438  * uA[2] = kg units - default = 0;
439  * uA[3] = Pa(pressure) units - default = 0;
440  * uA[4] = Temperature units - default = 0;
441  * uA[5] = time units - default = 0
442  * @param k species index. Defaults to 0.
443  * @param sizeUA output int containing the size of the vector.
444  * Currently, this is equal to 6.
445  * @deprecated To be removed after Cantera 2.2.
446  */
447  virtual void getUnitsStandardConc(double* uA, int k = 0,
448  int sizeUA = 6) const;
449 
450  //! Get the array of non-dimensional activities (molality
451  //! based for this class and classes that derive from it) at
452  //! the current solution temperature, pressure, and solution concentration.
453  /*!
454  * All standard state properties for molality-based phases are
455  * evaluated consistent with the molality scale. Therefore, this function
456  * must return molality-based activities.
457  *
458  * \f[
459  * a_i^\triangle = \gamma_k^{\triangle} \frac{m_k}{m^\triangle}
460  * \f]
461  *
462  * This function must be implemented in derived classes.
463  *
464  * @param ac Output vector of molality-based activities. Length: m_kk.
465  */
466  virtual void getActivities(doublereal* ac) const;
467 
468  //! Get the array of non-dimensional activity coefficients at
469  //! the current solution temperature, pressure, and solution concentration.
470  /*!
471  * These are mole-fraction based activity coefficients. In this
472  * object, their calculation is based on translating the values
473  * of the molality-based activity coefficients.
474  * See Denbigh p. 278 for a thorough discussion.
475  *
476  * The molar-based activity coefficients \f$ \gamma_k \f$ may be calculated from the
477  * molality-based
478  * activity coefficients, \f$ \gamma_k^\triangle \f$ by the following
479  * formula.
480  * \f[
481  * \gamma_k = \frac{\gamma_k^\triangle}{X_o}
482  * \f]
483  *
484  * For purposes of establishing a convention, the molar activity coefficient of the
485  * solvent is set equal to the molality-based activity coefficient of the
486  * solvent:
487  *
488  * \f[
489  * \gamma_o = \gamma_o^\triangle
490  * \f]
491  *
492  * Derived classes don't need to overload this function. This function is
493  * handled at this level.
494  *
495  * @param ac Output vector containing the mole-fraction based activity coefficients.
496  * length: m_kk.
497  */
498  void getActivityCoefficients(doublereal* ac) const;
499 
500  //! Get the array of non-dimensional molality based
501  //! activity coefficients at the current solution temperature,
502  //! pressure, and solution concentration.
503  /*!
504  * See Denbigh p. 278 for a thorough discussion. This class must be overwritten in
505  * classes which derive from MolalityVPSSTP. This function takes over from the
506  * molar-based activity coefficient calculation, getActivityCoefficients(), in
507  * derived classes.
508  *
509  * These molality based activity coefficients are scaled according to the current
510  * pH scale. See the Eq3/6 manual for details.
511  *
512  * Activity coefficients for species k may be altered between scales s1 to s2
513  * using the following formula
514  *
515  * \f[
516  * ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
517  * + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
518  * \f]
519  *
520  * where j is any one species. For the NBS scale, j is equal to the Cl- species
521  * and
522  *
523  * \f[
524  * ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
525  * \f]
526  *
527  * @param acMolality Output vector containing the molality based activity coefficients.
528  * length: m_kk.
529  */
530  virtual void getMolalityActivityCoefficients(doublereal* acMolality) const;
531 
532  //! Calculate the osmotic coefficient
533  /*!
534  * \f[
535  * \phi = \frac{- ln(a_o)}{\tilde{M}_o \sum_{i \ne o} m_i}
536  * \f]
537  *
538  * Note there are a few of definitions of the osmotic coefficient floating
539  * around. We use the one defined in
540  * (Activity Coefficients in Electrolyte Solutions, K. S. Pitzer
541  * CRC Press, Boca Raton, 1991, p. 85, Eqn. 28). This definition is most clearly
542  * related to theoretical calculation.
543  *
544  * units = dimensionless
545  */
546  virtual double osmoticCoefficient() const;
547 
548  //@}
549  /// @name Partial Molar Properties of the Solution
550  //@{
551 
552  /**
553  * Get the species electrochemical potentials.
554  * These are partial molar quantities. This method adds a term
555  * \f$ Fz_k \phi_k \f$ to each chemical potential.
556  *
557  * Units: J/kmol
558  *
559  * @param mu output vector containing the species electrochemical potentials.
560  * Length: m_kk.
561  */
562  void getElectrochemPotentials(doublereal* mu) const;
563 
564  //@}
565  /**
566  * @name Chemical Equilibrium
567  * Routines that implement the Chemical equilibrium capability
568  * for a single phase, based on the element-potential method.
569  * @{
570  */
571 
572  /**
573  * This method is used by the ChemEquil element-potential
574  * based equilibrium solver.
575  * It sets the state such that the chemical potentials of the
576  * species within the current phase satisfy
577  * \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m}
578  * \left(\frac{\lambda_m} {\hat R T}\right) \f] where
579  * \f$ \lambda_m \f$ is the element potential of element m. The
580  * temperature is unchanged. Any phase (ideal or not) that
581  * implements this method can be equilibrated by ChemEquil.
582  *
583  * @param lambda_RT Input vector containing the dimensionless
584  * element potentials.
585  */
586  virtual void setToEquilState(const doublereal* lambda_RT);
587 
588  //@}
589 
590  //! Set equation of state parameter values from XML entries.
591  /*!
592  * This method is called by function importPhase() when processing a phase
593  * definition in an input file. It should be overloaded in subclasses to set
594  * any parameters that are specific to that particular phase model.
595  *
596  * The MolalityVPSSTP object defines a new method for setting
597  * the concentrations of a phase. The new method is defined by a
598  * block called "soluteMolalities". If this block
599  * is found, the concentrations within that phase are
600  * set to the "name":"molalities pairs found within that
601  * XML block. The solvent concentration is then set
602  * to everything else.
603  *
604  * The function first calls the overloaded function,
605  * VPStandardStateTP::setStateFromXML(), to pick up the parent class
606  * behavior.
607  *
608  * usage: Overloaded functions should call this function
609  * before carrying out their own behavior.
610  *
611  * @param state An XML_Node object corresponding to
612  * the "state" entry for this phase in the input file.
613  */
614  virtual void setStateFromXML(const XML_Node& state);
615 
616  //@}
617  //! @name Initialization
618  /// The following methods are used in the process of constructing
619  /// the phase and setting its parameters from a specification in an
620  /// input file. They are not normally used in application programs.
621  /// To see how they are used, see importPhase().
622  //@{
623 
624  virtual void initThermo();
625 
626  /**
627  * Import and initialize a ThermoPhase object
628  *
629  * @param phaseNode This object must be the phase node of a
630  * complete XML tree
631  * description of the phase, including all of the
632  * species data. In other words while "phase" must
633  * point to an XML phase object, it must have
634  * sibling nodes "speciesData" that describe
635  * the species in the phase.
636  * @param id ID of the phase. If nonnull, a check is done
637  * to see if phaseNode is pointing to the phase
638  * with the correct id.
639  */
640  void initThermoXML(XML_Node& phaseNode, const std::string& id);
641 
642  //@}
643 
644  //! Set the temperature (K), pressure (Pa), and molalities
645  //!(gmol kg-1) of the solutes
646  /*!
647  * @param t Temperature (K)
648  * @param p Pressure (Pa)
649  * @param molalities Input vector of molalities of the solutes.
650  * Length: m_kk.
651  */
652  void setState_TPM(doublereal t, doublereal p,
653  const doublereal* const molalities);
654 
655  //! Set the temperature (K), pressure (Pa), and molalities.
656  /*!
657  * @param t Temperature (K)
658  * @param p Pressure (Pa)
659  * @param m compositionMap containing the molalities
660  */
661  void setState_TPM(doublereal t, doublereal p, const compositionMap& m);
662 
663  //! Set the temperature (K), pressure (Pa), and molalities.
664  /*!
665  * @param t Temperature (K)
666  * @param p Pressure (Pa)
667  * @param m String which gets translated into a composition
668  * map for the molalities of the solutes.
669  */
670  void setState_TPM(doublereal t, doublereal p, const std::string& m);
671 
672  //! Get the array of derivatives of the log activity coefficients with respect to the log of the species mole numbers
673  /*!
674  * Implementations should take the derivative of the logarithm of the activity coefficient with respect to a
675  * species log mole number (with all other species mole numbers held constant). The default treatment in the
676  * ThermoPhase object is to set this vector to zero.
677  *
678  * units = 1 / kmol
679  *
680  * dlnActCoeffdlnN[ ld * k + m] will contain the derivative of log act_coeff for the <I>m</I><SUP>th</SUP>
681  * species with respect to the number of moles of the <I>k</I><SUP>th</SUP> species.
682  *
683  * \f[
684  * \frac{d \ln(\gamma_m) }{d \ln( n_k ) }\Bigg|_{n_i}
685  * \f]
686  *
687  * @param ld Number of rows in the matrix
688  * @param dlnActCoeffdlnN Output vector of derivatives of the
689  * log Activity Coefficients. length = m_kk * m_kk
690  */
691  virtual void getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN) {
692  getdlnActCoeffdlnN_numderiv(ld, dlnActCoeffdlnN);
693  }
694 
695  //! returns a summary of the state of the phase as a string
696  /*!
697  * @param show_thermo If true, extra information is printed out
698  * about the thermodynamic state of the system.
699  * @param threshold Show information about species with mole fractions
700  * greater than *threshold*.
701  */
702  virtual std::string report(bool show_thermo=true,
703  doublereal threshold=1e-14) const;
704 
705 protected:
706 
707  virtual void getCsvReportData(std::vector<std::string>& names,
708  std::vector<vector_fp>& data) const;
709 
710  //! Get the array of unscaled non-dimensional molality based
711  //! activity coefficients at the current solution temperature,
712  //! pressure, and solution concentration.
713  /*!
714  * See Denbigh p. 278 for a thorough discussion. This class must be overwritten in
715  * classes which derive from MolalityVPSSTP. This function takes over from the
716  * molar-based activity coefficient calculation, getActivityCoefficients(), in
717  * derived classes.
718  *
719  * @param acMolality Output vector containing the molality based activity coefficients.
720  * length: m_kk.
721  */
722  virtual void getUnscaledMolalityActivityCoefficients(doublereal* acMolality) const;
723 
724  //! Apply the current phScale to a set of activity Coefficients or activities
725  /*!
726  * See the Eq3/6 Manual for a thorough discussion.
727  *
728  * @param acMolality input/Output vector containing the molality based
729  * activity coefficients. length: m_kk.
730  */
731  virtual void applyphScale(doublereal* acMolality) const;
732 
733 private:
734  //! Returns the index of the Cl- species.
735  /*!
736  * The Cl- species is special in the sense that its single ion
737  * molality-based activity coefficient is used in the specification
738  * of the pH scale for single ions. Therefore, we need to know
739  * what species index is Cl-. If the species isn't in the species
740  * list then this routine returns -1, and we can't use the NBS
741  * pH scale.
742  *
743  * Right now we use a restrictive interpretation. The species
744  * must be named "Cl-". It must consist of exactly one Cl and one E
745  * atom.
746  */
747  virtual size_t findCLMIndex() const;
748 
749  //! Initialize lengths of local variables after all species have
750  //! been identified.
751  void initLengths();
752 
753 protected:
754 
755  //! Index of the solvent
756  /*!
757  * Currently the index of the solvent is hard-coded to the value 0
758  */
760 
761  //! Scaling to be used for output of single-ion species activity
762  //! coefficients.
763  /*!
764  * Index of the species to be used in the single-ion scaling
765  * law. This is the identity of the Cl- species for the PHSCALE_NBS
766  * scaling.
767  * Either PHSCALE_PITZER or PHSCALE_NBS
768  */
770 
771  //! Index of the phScale species
772  /*!
773  * Index of the species to be used in the single-ion scaling
774  * law. This is the identity of the Cl- species for the PHSCALE_NBS
775  * scaling
776  */
777  size_t m_indexCLM;
778 
779  //! Molecular weight of the Solvent
780  doublereal m_weightSolvent;
781 
782  /*!
783  * In any molality implementation, it makes sense to have
784  * a minimum solvent mole fraction requirement, since the
785  * implementation becomes singular in the xmolSolvent=0
786  * limit. The default is to set it to 0.01.
787  * We then modify the molality definition to ensure that
788  * molal_solvent = 0 when xmol_solvent = 0.
789  */
790  doublereal m_xmolSolventMIN;
791 
792  //! This is the multiplication factor that goes inside
793  //! log expressions involving the molalities of species.
794  /*!
795  * It's equal to Wt_0 / 1000,
796  * where Wt_0 = weight of solvent (kg/kmol)
797  */
798  doublereal m_Mnaught;
799 
800  //! Current value of the molalities of the species in the phase.
801  /*!
802  * Note this vector is a mutable quantity.
803  * units are (kg/kmol)
804  */
806 };
807 
808 
809 //! Scale to be used for the output of single-ion activity coefficients
810 //! is that used by Pitzer.
811 /*!
812  * This is the internal scale used within the code. One property is that
813  * the activity coefficients for the cation and anion of a single salt
814  * will be equal. This scale is the one presumed by the formulation of the
815  * single-ion activity coefficients described in this report.
816  *
817  * Activity coefficients for species k may be altered between scales s1 to s2
818  * using the following formula
819  *
820  * \f[
821  * ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
822  * + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
823  * \f]
824  *
825  * where j is any one species.
826  */
827 const int PHSCALE_PITZER = 0;
828 
829 //! Scale to be used for evaluation of single-ion activity coefficients
830 //! is that used by the NBS standard for evaluation of the pH variable.
831 /*!
832  * This is not the internal scale used within the code.
833  *
834  * Activity coefficients for species k may be altered between scales s1 to s2
835  * using the following formula
836  *
837  * \f[
838  * ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
839  * + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
840  * \f]
841  *
842  * where j is any one species. For the NBS scale, j is equal to the Cl- species
843  * and
844  *
845  * \f[
846  * ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
847  * \f]
848  *
849  * This is the NBS pH scale, which is used in all conventional pH
850  * measurements. and is based on the Bates-Guggenheim equations.
851  */
852 const int PHSCALE_NBS = 1;
853 
854 }
855 
856 #endif
std::map< std::string, doublereal > compositionMap
Map connecting a string name with a double.
Definition: ct_defs.h:149
virtual double osmoticCoefficient() const
Calculate the osmotic coefficient.
void initLengths()
Initialize lengths of local variables after all species have been identified.
void getElectrochemPotentials(doublereal *mu) const
Get the species electrochemical potentials.
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal *const dlnActCoeffdlnN)
Get the array of derivatives of the log activity coefficients with respect to the log of the species ...
void setSolvent(size_t k)
This routine sets the index number of the solvent for the phase.
virtual void applyphScale(doublereal *acMolality) const
Apply the current phScale to a set of activity Coefficients or activities.
virtual std::string report(bool show_thermo=true, doublereal threshold=1e-14) const
returns a summary of the state of the phase as a string
doublereal m_Mnaught
This is the multiplication factor that goes inside log expressions involving the molalities of specie...
void setpHScale(const int pHscaleType)
Set the pH scale, which determines the scale for single-ion activity coefficients.
size_t m_indexCLM
Index of the phScale species.
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:100
virtual void getUnscaledMolalityActivityCoefficients(doublereal *acMolality) const
Get the array of unscaled non-dimensional molality based activity coefficients at the current solutio...
std::string name() const
Return the name of the phase.
Definition: Phase.cpp:157
Base class for a phase with thermodynamic properties.
Definition: ThermoPhase.h:97
size_t solventIndex() const
Returns the solvent index.
virtual void getActivities(doublereal *ac) const
Get the array of non-dimensional activities (molality based for this class and classes that derive fr...
void setMolalitiesByName(const compositionMap &xMap)
Set the molalities of a phase.
MolalityVPSSTP & operator=(const MolalityVPSSTP &b)
Assignment operator.
virtual void getMolalityActivityCoefficients(doublereal *acMolality) const
Get the array of non-dimensional molality based activity coefficients at the current solution tempera...
virtual void setToEquilState(const doublereal *lambda_RT)
This method is used by the ChemEquil element-potential based equilibrium solver.
const int PHSCALE_NBS
Scale to be used for evaluation of single-ion activity coefficients is that used by the NBS standard ...
virtual void getActivityConcentrations(doublereal *c) const
This method returns an array of generalized concentrations that are defined such that where is a s...
const int PHSCALE_PITZER
Scale to be used for the output of single-ion activity coefficients is that used by Pitzer...
This is a filter class for ThermoPhase that implements some prepatory steps for efficiently handling ...
int m_pHScalingType
Scaling to be used for output of single-ion species activity coefficients.
virtual void setStateFromXML(const XML_Node &state)
Set equation of state parameter values from XML entries.
virtual size_t findCLMIndex() const
Returns the index of the Cl- species.
void setMolalities(const doublereal *const molal)
Set the molalities of the solutes in a phase.
void setState_TPM(doublereal t, doublereal p, const doublereal *const molalities)
Set the temperature (K), pressure (Pa), and molalities (gmol kg-1) of the solutes.
doublereal moleFSolventMin() const
Returns the minimum mole fraction in the molality formulation.
void getActivityCoefficients(doublereal *ac) const
Get the array of non-dimensional activity coefficients at the current solution temperature, pressure, and solution concentration.
vector_fp m_molalities
Current value of the molalities of the species in the phase.
Header file for a derived class of ThermoPhase that handles variable pressure standard state methods ...
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 getCsvReportData(std::vector< std::string > &names, std::vector< vector_fp > &data) const
Fills names and data with the column names and species thermo properties to be included in the output...
void getMolalities(doublereal *const molal) const
This function will return the molalities of the species.
doublereal m_weightSolvent
Molecular weight of the Solvent.
void initThermoXML(XML_Node &phaseNode, const std::string &id)
Import and initialize a ThermoPhase object.
int activityConvention() const
This method returns the activity convention.
int pHScale() const
Reports the pH scale, which determines the scale for single-ion activity coefficients.
size_t m_indexSolvent
Index of the solvent.
virtual ThermoPhase * duplMyselfAsThermoPhase() const
Duplication routine for objects which inherit from ThermoPhase.
MolalityVPSSTP()
Default Constructor.
void calcMolalities() const
Calculates the molality of all species and stores the result internally.
virtual void getUnitsStandardConc(double *uA, int k=0, int sizeUA=6) const
Returns the units of the standard and generalized concentrations Note they have the same units...
void setMoleFSolventMin(doublereal xmolSolventMIN)
Sets the minimum mole fraction in the molality formulation.
virtual doublereal standardConcentration(size_t k=0) const
The standard concentration used to normalize the generalized concentration.