cantera/include/cantera/thermo/MolalityVPSSTP.h
2012-02-27 18:15:02 +00:00

998 lines
35 KiB
C++

/**
* @file MolalityVPSSTP.h
* Header for intermediate ThermoPhase object for phases which
* employ molality based activity coefficient formulations
* (see \ref thermoprops
* and class \link Cantera::MolalityVPSSTP MolalityVPSSTP\endlink).
*
* Header file for a derived class of ThermoPhase that handles
* variable pressure standard state methods for calculating
* thermodynamic properties that are further based upon activities
* based on the molality scale. These include most of the methods for
* calculating liquid electrolyte thermodynamics.
*/
/*
* Copyright (2006) Sandia Corporation. Under the terms of
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
* U.S. Government retains certain rights in this software.
*/
#ifndef CT_MOLALITYVPSSTP_H
#define CT_MOLALITYVPSSTP_H
#include "VPStandardStateTP.h"
namespace Cantera
{
/**
* @ingroup thermoprops
*/
/*!
* MolalityVPSSTP is a derived class of ThermoPhase that handles
* variable pressure standard state methods for calculating
* thermodynamic properties that are further based on
* molality-scaled activities.
* This category incorporates most of the methods
* for calculating liquid electrolyte thermodynamics that have been
* developed since the 1970's.
*
* This class adds additional functions onto the %ThermoPhase interface
* that handle molality based standard states. The %ThermoPhase
* class includes a member function, ThermoPhase::activityConvention()
* that indicates which convention the activities are based on. The
* default is to assume activities are based on the molar convention.
* However, classes which derive from the MolalityVPSSTP class return
* <b>cAC_CONVENTION_MOLALITY</b> from this member function.
*
* The molality of a solute, \f$ m_i \f$, is defined as
*
* \f[
* m_i = \frac{n_i}{\tilde{M}_o n_o}
* \f]
* where
* \f[
* \tilde{M}_o = \frac{M_o}{1000}
* \f]
*
* where \f$ M_o \f$ is the molecular weight of the solvent. The molality
* has units of gmol kg<SUP>-1</SUP>. For the solute, the molality may be
* considered as the amount of gmol's of solute per kg of solvent, a natural
* experimental quantity.
*
* The formulas for calculating mole fractions if given the molalities of
* the solutes is stated below. First calculate \f$ L^{sum} \f$, an intermediate
* quantity.
*
* \f[
* L^{sum} = \frac{1}{\tilde{M}_o X_o} = \frac{1}{\tilde{M}_o} + \sum_{i\ne o} m_i
* \f]
* Then,
* \f[
* X_o = \frac{1}{\tilde{M}_o L^{sum}}
* \f]
* \f[
* X_i = \frac{m_i}{L^{sum}}
* \f]
* where \f$ X_o \f$ is the mole fraction of solvent, and \f$ X_o \f$ is the
* mole fraction of solute <I>i</I>. Thus, the molality scale and the mole fraction
* scale offer a one-to-one mapping between each other, except in the limit
* of a zero solvent mole fraction.
*
* The standard states for thermodynamic objects that derive from <b>MolalityVPSSTP</b>
* are on the unit molality basis. Chemical potentials
* of the solutes, \f$ \mu_k \f$, and the solvent, \f$ \mu_o \f$, which are based
* on the molality form, have the following general format:
*
* \f[
* \mu_k = \mu^{\triangle}_k(T,P) + R T ln(\gamma_k^{\triangle} \frac{m_k}{m^\triangle})
* \f]
* \f[
* \mu_o = \mu^o_o(T,P) + RT ln(a_o)
* \f]
*
* where \f$ \gamma_k^{\triangle} \f$ is the molality based activity coefficient for species
* \f$k\f$.
*
* The chemical potential of the solvent is thus expressed in a different format
* than the chemical potential of the solutes. Additionally, the activity of the
* solvent, \f$ a_o \f$, is further reexpressed in terms of an osmotic coefficient,
* \f$ \phi \f$.
* \f[
* \phi = \frac{- ln(a_o)}{\tilde{M}_o \sum_{i \ne o} m_i}
* \f]
*
* MolalityVPSSTP::osmoticCoefficient() returns the value of \f$ \phi \f$.
* Note there are a few of definitions of the osmotic coefficient floating
* around. We use the one defined in
* (Activity Coefficients in Electrolyte Solutions, K. S. Pitzer
* CRC Press, Boca Raton, 1991, p. 85, Eqn. 28). This definition is most clearly
* related to theoretical calculation.
*
* The molar-based activity coefficients \f$ \gamma_k \f$ may be calculated
* from the molality-based
* activity coefficients, \f$ \gamma_k^\triangle \f$ by the following
* formula.
* \f[
* \gamma_k = \frac{\gamma_k^\triangle}{X_o}
* \f]
* For purposes of establishing a convention, the molar activity coefficient of the
* solvent is set equal to the molality-based activity coefficient of the
* solvent:
* \f[
* \gamma_o = \gamma_o^\triangle
* \f]
*
* The molality-based and molarity-based standard states may be related to one
* another by the following formula.
*
* \f[
* \mu_k^\triangle(T,P) = \mu_k^o(T,P) + R T \ln(\tilde{M}_o m^\triangle)
* \f]
*
* An important convention is followed in all routines that derive from <b>%MolalityVPSSTP</b>.
* Standard state thermodynamic functions and reference state thermodynamic functions
* return the molality-based quantities. Also all functions which return
* activities return the molality-based activities. The reason for this convention
* has been discussed in supporting memos. However, it's important because the
* term in the equation above is non-trivial. For example it's equal
* to 2.38 kcal gmol<SUP>-1</SUP> for water at 298 K.
*
*
* In order to prevent a singularity, this class includes the concept of a minimum
* value for the solvent mole fraction. All calculations involving the formulation
* of activity coefficients and other non-ideal solution behavior adhere to
* this concept of a minimal value for the solvent mole fraction. This makes sense
* because these solution behavior were all designed and measured far away from
* the zero solvent singularity condition and are not applicable in that limit.
*
*
* This objects add a layer that supports molality. It inherits from VPStandardStateTP.
*
* All objects that derive from this are assumed to have molality based standard states.
*
* Molality based activity coefficients are scaled according to the current
* pH scale. See the Eq3/6 manual for details.
*
* Activity coefficients for species k may be altered between scales s1 to s2
* using the following formula
*
* \f[
* ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
* + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
* \f]
*
* where j is any one species. For the NBS scale, j is equal to the Cl- species
* and
*
* \f[
* ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
* \f]
*
* The Pitzer scale doesn't actually change anything. The pitzer scale is defined
* as the raw unscaled activity coefficients produced by the underlying objects.
*
* <H3> SetState Strategy </H3>
*
* The MolalityVPSSTP object does not have a setState strategy concerning the
* molalities. It does not keep track of whether the molalities have changed.
* It's strictly an interfacial layer that writes the current mole fractions to the
* State object. When molalities are needed it recalculates the molalities from
* the State object's mole fraction vector.
*
*
* @todo Make two solvent minimum fractions. One would be for calculation of the non-ideal
* factors. The other one would be for purposes of stoichiometry evaluation. the
* stoichiometry evaluation one would be a 1E-13 limit. Anything less would create
* problems with roundoff error.
*
*/
class MolalityVPSSTP : public VPStandardStateTP
{
public:
/// Constructors
/*!
* This doesn't do much more than initialize constants with
* default values for water at 25C. Water molecular weight
* comes from the default elements.xml file. It actually
* differs slightly from the IAPWS95 value of 18.015268. However,
* density conservation and therefore element conservation
* is the more important principle to follow.
*/
MolalityVPSSTP();
//! Copy constructor
/*!
* Note this stuff will not work until the underlying phase
* has a working copy constructor
*
* @param b class to be copied
*/
MolalityVPSSTP(const MolalityVPSSTP& b);
/// Assignment operator
/*!
* Note this stuff will not work until the underlying phase
* has a working assignment operator
*
* @param b class to be copied.
*/
MolalityVPSSTP& operator=(const MolalityVPSSTP& b);
/// Destructor.
virtual ~MolalityVPSSTP();
//! Duplication routine for objects which inherit from ThermoPhase.
/*!
* This virtual routine can be used to duplicate thermophase objects
* inherited from ThermoPhase even if the application only has
* a pointer to ThermoPhase to work with.
*/
virtual ThermoPhase* duplMyselfAsThermoPhase() const;
/**
*
* @name Utilities
* @{
*/
//! Equation of state type flag.
/*!
* The ThermoPhase base class returns
* zero. Subclasses should define this to return a unique
* non-zero value. Known constants defined for this purpose are
* listed in mix_defs.h. The MolalityVPSSTP class also returns
* zero, as it is a non-complete class.
*/
virtual int eosType() const;
//! Set the pH scale, which determines the scale for single-ion activity
//! coefficients.
/*!
* Single ion activity coefficients are not unique in terms of the
* representing actual measurable quantities.
*
* @param pHscaleType Integer representing the pHscale
*/
void setpHScale(const int pHscaleType);
//! Reports the pH scale, which determines the scale for single-ion activity
//! coefficients.
/*!
* Single ion activity coefficients are not unique in terms of the
* representing actual measurable quantities.
*
* @return Return the pHscale type
*/
int pHScale() const;
/**
* @}
* @name Molar Thermodynamic Properties
* @{
*/
/**
* @}
* @name Utilities for Solvent ID and Molality
* @{
*/
/**
* This routine sets the index number of the solvent for
* the phase.
*
* Note, having a solvent
* is a precursor to many things having to do with molality.
*
* @param k the solvent index number
*/
void setSolvent(size_t k);
/**
* Sets the minimum mole fraction in the molality formulation.
* Note the molality formulation is singular in the limit that
* the solvent mole fraction goes to zero. Numerically, how
* this limit is treated and resolved is an ongoing issue within
* Cantera.
*
* @param xmolSolventMIN Input double containing the minimum mole fraction
*/
void setMoleFSolventMin(doublereal xmolSolventMIN);
//! Returns the solvent index.
size_t solventIndex() const;
/**
* Returns the minimum mole fraction in the molality
* formulation.
*/
doublereal moleFSolventMin() const;
//! Calculates the molality of all species and stores the result internally.
/*!
* We calculate the vector of molalities of the species
* in the phase and store the result internally:
* \f[
* m_i = \frac{X_i}{1000 * M_o * X_{o,p}}
* \f]
* where
* - \f$ M_o \f$ is the molecular weight of the solvent
* - \f$ X_o \f$ is the mole fraction of the solvent
* - \f$ X_i \f$ is the mole fraction of the solute.
* - \f$ X_{o,p} = max (X_{o}^{min}, X_o) \f$
* - \f$ X_{o}^{min} \f$ = minimum mole fraction of solvent allowed
* in the denominator.
*/
void calcMolalities() const;
//! This function will return the molalities of the species.
/*!
* We calculate the vector of molalities of the species
* in the phase
* \f[
* m_i = \frac{X_i}{1000 * M_o * X_{o,p}}
* \f]
* where
* - \f$ M_o \f$ is the molecular weight of the solvent
* - \f$ X_o \f$ is the mole fraction of the solvent
* - \f$ X_i \f$ is the mole fraction of the solute.
* - \f$ X_{o,p} = \max (X_{o}^{min}, X_o) \f$
* - \f$ X_{o}^{min} \f$ = minimum mole fraction of solvent allowed
* in the denominator.
*
* @param molal Output vector of molalities. Length: m_kk.
*/
void getMolalities(doublereal* const molal) const;
//! Set the molalities of the solutes in a phase
/*!
* Note, the entry for the solvent is not used.
* We are supplied with the molalities of all of the
* solute species. We then calculate the mole fractions of all
* species and update the %ThermoPhase object.
* \f[
* m_i = \frac{X_i}{M_o/1000 * X_{o,p}}
* \f]
* where
* - \f$M_o\f$ is the molecular weight of the solvent
* - \f$X_o\f$ is the mole fraction of the solvent
* - \f$X_i\f$ is the mole fraction of the solute.
* - \f$X_{o,p} = \max(X_o^{min}, X_o)\f$
* - \f$X_o^{min}\f$ = minimum mole fraction of solvent allowed
* in the denominator.
*
* The formulas for calculating mole fractions are
* \f[
* L^{sum} = \frac{1}{\tilde{M}_o X_o} = \frac{1}{\tilde{M}_o} + \sum_{i\ne o} m_i
* \f]
* Then,
* \f[
* X_o = \frac{1}{\tilde{M}_o L^{sum}}
* \f]
* \f[
* X_i = \frac{m_i}{L^{sum}}
* \f]
* It is currently an error if the solvent mole fraction is attempted to be set
* to a value lower than \f$X_o^{min}\f$.
*
* @param molal Input vector of molalities. Length: m_kk.
*/
void setMolalities(const doublereal* const molal);
//! Set the molalities of a phase
/*!
* Set the molalities of the solutes in a phase. Note, the entry for the
* solvent is not used.
*
* @param xMap Composition Map containing the molalities.
*/
void setMolalitiesByName(compositionMap& xMap);
//! Set the molalities of a phase
/*!
* Set the molalities of the solutes in a phase. Note, the entry for the
* solvent is not used.
*
* @param name String containing the information for a composition map.
*/
void setMolalitiesByName(const std::string& name);
/**
* @}
* @name Mechanical Properties
* @{
*/
/**
* @}
* @name Potential Energy
*
* Species may have an additional potential energy due to the
* presence of external gravitation or electric fields. These
* methods allow specifying a potential energy for individual
* species.
* @{
*/
/**
* @}
* @name Activities, Standard States, and Activity Concentrations
*
* The activity \f$a_k\f$ of a species in solution is
* related to the chemical potential by \f[ \mu_k = \mu_k^0(T)
* + \hat R T \log a_k. \f] The quantity \f$\mu_k^0(T,P)\f$ is
* the chemical potential at unit activity, which depends only
* on temperature and pressure.
* @{
*/
/**
* This method returns the activity convention.
* Currently, there are two activity conventions
* Molar-based activities
* Unit activity of species at either a hypothetical pure
* solution of the species or at a hypothetical
* pure ideal solution at infinite dilution
* cAC_CONVENTION_MOLAR 0
* - default
*
* Molality based activities
* (unit activity of solutes at a hypothetical 1 molal
* solution referenced to infinite dilution at all
* pressures and temperatures).
* cAC_CONVENTION_MOLALITY 1
*
* We set the convention to molality here.
*/
int activityConvention() const;
/**
* This method returns an array of generalized concentrations
* \f$ C_k\f$ that are defined such that
* \f$ a_k = C_k / C^0_k, \f$ where \f$ C^0_k \f$
* is a standard concentration
* defined below. These generalized concentrations are used
* by kinetics manager classes to compute the forward and
* reverse rates of elementary reactions.
*
* @param c Array of generalized concentrations. The
* units depend upon the implementation of the
* reaction rate expressions within the phase.
*/
virtual void getActivityConcentrations(doublereal* c) const;
/**
* The standard concentration \f$ C^0_k \f$ used to normalize
* the generalized concentration. In many cases, this quantity
* will be the same for all species in a phase - for example,
* for an ideal gas \f$ C^0_k = P/\hat R T \f$. For this
* reason, this method returns a single value, instead of an
* array. However, for phases in which the standard
* concentration is species-specific (e.g. surface species of
* different sizes), this method may be called with an
* optional parameter indicating the species.
*
* @param k species index. Defaults to zero.
*/
virtual doublereal standardConcentration(size_t k=0) const;
/**
* Returns the natural logarithm of the standard
* concentration of the kth species
*
* @param k species index
*/
virtual doublereal logStandardConc(size_t k=0) const;
/**
* Returns the units of the standard and generalized
* concentrations Note they have the same units, as their
* ratio is defined to be equal to the activity of the kth
* species in the solution, which is unitless.
*
* This routine is used in print out applications where the
* units are needed. Usually, MKS units are assumed throughout
* the program and in the XML input files.
*
* @param uA Output vector containing the units
* uA[0] = kmol units - default = 1
* uA[1] = m units - default = -nDim(), the number of spatial
* dimensions in the Phase class.
* uA[2] = kg units - default = 0;
* uA[3] = Pa(pressure) units - default = 0;
* uA[4] = Temperature units - default = 0;
* uA[5] = time units - default = 0
* @param k species index. Defaults to 0.
* @param sizeUA output int containing the size of the vector.
* Currently, this is equal to 6.
*/
virtual void getUnitsStandardConc(double* uA, int k = 0,
int sizeUA = 6) const;
//! Get the array of non-dimensional activities (molality
//! based for this class and classes that derive from it) at
//! the current solution temperature, pressure, and solution concentration.
/*!
* All standard state properties for molality-based phases are
* evaluated consistent with the molality scale. Therefore, this function
* must return molality-based activities.
*
* \f[
* a_i^\triangle = \gamma_k^{\triangle} \frac{m_k}{m^\triangle}
* \f]
*
* This function must be implemented in derived classes.
*
* @param ac Output vector of molality-based activities. Length: m_kk.
*/
virtual void getActivities(doublereal* ac) const;
//! Get the array of non-dimensional activity coefficients at
//! the current solution temperature, pressure, and solution concentration.
/*!
* These are mole-fraction based activity coefficients. In this
* object, their calculation is based on translating the values
* of the molality-based activity coefficients.
* See Denbigh p. 278 for a thorough discussion.
*
* The molar-based activity coefficients \f$ \gamma_k \f$ may be calculated from the
* molality-based
* activity coefficients, \f$ \gamma_k^\triangle \f$ by the following
* formula.
* \f[
* \gamma_k = \frac{\gamma_k^\triangle}{X_o}
* \f]
*
* For purposes of establishing a convention, the molar activity coefficient of the
* solvent is set equal to the molality-based activity coefficient of the
* solvent:
*
* \f[
* \gamma_o = \gamma_o^\triangle
* \f]
*
* Derived classes don't need to overload this function. This function is
* handled at this level.
*
* @param ac Output vector containing the mole-fraction based activity coefficients.
* length: m_kk.
*/
void getActivityCoefficients(doublereal* ac) const;
//! Get the array of non-dimensional molality based
//! activity coefficients at the current solution temperature,
//! pressure, and solution concentration.
/*!
* See Denbigh p. 278 for a thorough discussion. This class must be overwritten in
* classes which derive from %MolalityVPSSTP. This function takes over from the
* molar-based activity coefficient calculation, getActivityCoefficients(), in
* derived classes.
*
* These molality based activity coefficients are scaled according to the current
* pH scale. See the Eq3/6 manual for details.
*
* Activity coefficients for species k may be altered between scales s1 to s2
* using the following formula
*
* \f[
* ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
* + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
* \f]
*
* where j is any one species. For the NBS scale, j is equal to the Cl- species
* and
*
* \f[
* ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
* \f]
*
* @param acMolality Output vector containing the molality based activity coefficients.
* length: m_kk.
*/
virtual void getMolalityActivityCoefficients(doublereal* acMolality) const;
//! Calculate the osmotic coefficient
/*!
* \f[
* \phi = \frac{- ln(a_o)}{\tilde{M}_o \sum_{i \ne o} m_i}
* \f]
*
* Note there are a few of definitions of the osmotic coefficient floating
* around. We use the one defined in
* (Activity Coefficients in Electrolyte Solutions, K. S. Pitzer
* CRC Press, Boca Raton, 1991, p. 85, Eqn. 28). This definition is most clearly
* related to theoretical calculation.
*
* units = dimensionless
*/
virtual double osmoticCoefficient() const;
//@}
/// @name Partial Molar Properties of the Solution
//@{
/**
* Get the species electrochemical potentials.
* These are partial molar quantities.
* This method adds a term \f$ Fz_k \phi_k \f$ to the
* to each chemical potential.
*
* Units: J/kmol
*
* @param mu output vector containing the species electrochemical potentials.
* Length: m_kk.
*/
void getElectrochemPotentials(doublereal* mu) const;
//@}
/// @name Properties of the Standard State of the Species in the Solution
//@{
//@}
/// @name Thermodynamic Values for the Species Reference States
//@{
///////////////////////////////////////////////////////
//
// The methods below are not virtual, and should not
// be overloaded.
//
//////////////////////////////////////////////////////
/**
* @name Specific Properties
* @{
*/
/**
* @name Setting the State
*
* These methods set all or part of the thermodynamic
* state.
* @{
*/
//@}
/**
* @name Chemical Equilibrium
* Routines that implement the Chemical equilibrium capability
* for a single phase, based on the element-potential method.
* @{
*/
/**
* This method is used by the ChemEquil element-potential
* based equilibrium solver.
* It sets the state such that the chemical potentials of the
* species within the current phase satisfy
* \f[ \frac{\mu_k}{\hat R T} = \sum_m A_{k,m}
* \left(\frac{\lambda_m} {\hat R T}\right) \f] where
* \f$ \lambda_m \f$ is the element potential of element m. The
* temperature is unchanged. Any phase (ideal or not) that
* implements this method can be equilibrated by ChemEquil.
*
* @param lambda_RT Input vector containing the dimensionless
* element potentials.
*/
virtual void setToEquilState(const doublereal* lambda_RT);
//@}
//! Set equation of state parameter values from XML entries.
/*!
* This method is called by function importPhase() in
* file importCTML.cpp when processing a phase definition in
* an input file. It should be overloaded in subclasses to set
* any parameters that are specific to that particular phase
* model.
*
* The MolalityVPSSTP object defines a new method for setting
* the concentrations of a phase. The new method is defined by a
* block called "soluteMolalities". If this block
* is found, the concentrations within that phase are
* set to the "name":"molalities pairs found within that
* XML block. The solvent concentration is then set
* to everything else.
*
* The function first calls the overloaded function ,
* VPStandardStateTP::setStateFromXML(), to pick up the parent class
* behavior.
*
* usage: Overloaded functions should call this function
* before carrying out their own behavior.
*
* @param state An XML_Node object corresponding to
* the "state" entry for this phase in the input file.
*/
virtual void setStateFromXML(const XML_Node& state);
/// The following methods are used in the process of constructing
/// the phase and setting its parameters from a specification in an
/// input file. They are not normally used in application programs.
/// To see how they are used, see files importCTML.cpp and
/// ThermoFactory.cpp.
/*!
* @internal Initialize. This method is provided to allow
* subclasses to perform any initialization required after all
* species have been added. For example, it might be used to
* resize internal work arrays that must have an entry for
* each species. The base class implementation does nothing,
* and subclasses that do not require initialization do not
* need to overload this method. When importing a CTML phase
* description, this method is called just prior to returning
* from function importPhase.
*
* @see importCTML.cpp
*/
virtual void initThermo();
/**
* Import and initialize a ThermoPhase object
*
* @param phaseNode This object must be the phase node of a
* complete XML tree
* description of the phase, including all of the
* species data. In other words while "phase" must
* point to an XML phase object, it must have
* sibling nodes "speciesData" that describe
* the species in the phase.
* @param id ID of the phase. If nonnull, a check is done
* to see if phaseNode is pointing to the phase
* with the correct id.
*/
void initThermoXML(XML_Node& phaseNode, std::string id);
//! Set the temperature (K), pressure (Pa), and molalities
//!(gmol kg-1) of the solutes
/*!
* @param t Temperature (K)
* @param p Pressure (Pa)
* @param molalities Input vector of molalities of the solutes.
* Length: m_kk.
*/
void setState_TPM(doublereal t, doublereal p,
const doublereal* const molalities);
//! Set the temperature (K), pressure (Pa), and molalities.
/*!
* @param t Temperature (K)
* @param p Pressure (Pa)
* @param m compositionMap containing the molalities
*/
void setState_TPM(doublereal t, doublereal p, compositionMap& m);
//! Set the temperature (K), pressure (Pa), and molalities.
/*!
* @param t Temperature (K)
* @param p Pressure (Pa)
* @param m String which gets translated into a composition
* map for the molalities of the solutes.
*/
void setState_TPM(doublereal t, doublereal p, const std::string& m);
//! Get the array of derivatives of the log activity coefficients with respect to the log of the species mole numbers
/*!
* Implementations should take the derivative of the logarithm of the activity coefficient with respect to a
* species log mole number (with all other species mole numbers held constant). The default treatment in the
* %ThermoPhase object is to set this vector to zero.
*
* units = 1 / kmol
*
* dlnActCoeffdlnN[ ld * k + m] will contain the derivative of log act_coeff for the <I>m</I><SUP>th</SUP>
* species with respect to the number of moles of the <I>k</I><SUP>th</SUP> species.
*
* \f[
* \frac{d \ln(\gamma_m) }{d \ln( n_k ) }\Bigg|_{n_i}
* \f]
*
* @param ld Number of rows in the matrix
* @param dlnActCoeffdlnN Output vector of derivatives of the
* log Activity Coefficients. length = m_kk * m_kk
*/
virtual void getdlnActCoeffdlnN(const size_t ld, doublereal* const dlnActCoeffdlnN) {
getdlnActCoeffdlnN_numderiv(ld, dlnActCoeffdlnN);
}
//! returns a summary of the state of the phase as a string
/*!
* @param show_thermo If true, extra information is printed out
* about the thermodynamic state of the system.
*/
virtual std::string report(bool show_thermo = true) const;
//! returns a summary of the state of the phase to specified
//! comma separated files
/*!
* @param csvFile ofstream file to print comma separated data for
* the phase
*/
virtual void reportCSV(std::ofstream& csvFile) const;
protected:
//! Get the array of unscaled non-dimensional molality based
//! activity coefficients at the current solution temperature,
//! pressure, and solution concentration.
/*!
* See Denbigh p. 278 for a thorough discussion. This class must be overwritten in
* classes which derive from %MolalityVPSSTP. This function takes over from the
* molar-based activity coefficient calculation, getActivityCoefficients(), in
* derived classes.
*
* @param acMolality Output vector containing the molality based activity coefficients.
* length: m_kk.
*/
virtual void getUnscaledMolalityActivityCoefficients(doublereal* acMolality) const;
//! Apply the current phScale to a set of activity Coefficients or activities
/*!
* See the Eq3/6 Manual for a thorough discussion.
*
* @param acMolality input/Output vector containing the molality based
* activity coefficients. length: m_kk.
*/
virtual void applyphScale(doublereal* acMolality) const;
private:
//! Returns the index of the Cl- species.
/*!
* The Cl- species is special in the sense that its single ion
* molality-based activity coefficient is used in the specification
* of the pH scale for single ions. Therefore, we need to know
* what species index is Cl-. If the species isn't in the species
* list then this routine returns -1, and we can't use the NBS
* pH scale.
*
* Right now we use a restrictive interpretation. The species
* must be named "Cl-". It must consist of exactly one Cl and one E
* atom.
*/
virtual size_t findCLMIndex() const;
//! Initialize lengths of local variables after all species have
//! been identified.
void initLengths();
protected:
//! Index of the solvent
/*!
* Currently the index of the solvent is hard-coded to the value 0
*/
size_t m_indexSolvent;
//! Scaling to be used for output of single-ion species activity
//! coefficients.
/*!
* Index of the species to be used in the single-ion scaling
* law. This is the identity of the Cl- species for the PHSCALE_NBS
* scaling.
* Either PHSCALE_PITZER or PHSCALE_NBS
*/
int m_pHScalingType;
//! Index of the phScale species
/*!
* Index of the species to be used in the single-ion scaling
* law. This is the identity of the Cl- species for the PHSCALE_NBS
* scaling
*/
size_t m_indexCLM;
//! Molecular weight of the Solvent
doublereal m_weightSolvent;
/*!
* In any molality implementation, it makes sense to have
* a minimum solvent mole fraction requirement, since the
* implementation becomes singular in the xmolSolvent=0
* limit. The default is to set it to 0.01.
* We then modify the molality definition to ensure that
* molal_solvent = 0 when xmol_solvent = 0.
*/
doublereal m_xmolSolventMIN;
//! This is the multiplication factor that goes inside
//! log expressions involving the molalities of species.
/*!
* It's equal to Wt_0 / 1000,
* where Wt_0 = weight of solvent (kg/kmol)
*/
doublereal m_Mnaught;
//! Current value of the molalities of the species in the phase.
/*!
* Note this vector is a mutable quantity.
* units are (kg/kmol)
*/
mutable vector_fp m_molalities;
private:
//! Error function
/*!
* Print an error string and exit
*
* @param msg Message to be printed
*/
doublereal err(std::string msg) const;
};
//! Scale to be used for the output of single-ion activity coefficients
//! is that used by Pitzer.
/*!
* This is the internal scale used within the code. One property is that
* the activity coefficients for the cation and anion of a single salt
* will be equal. This scale is the one presumed by the formulation of the
* single-ion activity coefficients described in this report.
*
* Activity coefficients for species k may be altered between scales s1 to s2
* using the following formula
*
* \f[
* ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
* + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
* \f]
*
* where j is any one species.
*
*
*/
const int PHSCALE_PITZER = 0;
//! Scale to be used for evaluation of single-ion activity coefficients
//! is that used by the NBS standard for evaluation of the pH variable.
/*!
* This is not the internal scale used within the code.
*
* Activity coefficients for species k may be altered between scales s1 to s2
* using the following formula
*
* \f[
* ln(\gamma_k^{s2}) = ln(\gamma_k^{s1})
* + \frac{z_k}{z_j} \left( ln(\gamma_j^{s2}) - ln(\gamma_j^{s1}) \right)
* \f]
*
* where j is any one species. For the NBS scale, j is equal to the Cl- species
* and
*
* \f[
* ln(\gamma_{Cl-}^{s2}) = \frac{-A_{\phi} \sqrt{I}}{1.0 + 1.5 \sqrt{I}}
* \f]
*
* This is the NBS pH scale, which is used in all conventional pH
* measurements. and is based on the Bates-Guggenheim equations.
*
*/
const int PHSCALE_NBS = 1;
}
#endif