cantera/Cantera/src/thermo/GibbsExcessVPSSTP.h

609 lines
20 KiB
C++

/**
* @file GibbsExcessVPSSTP.h
* Header for intermediate ThermoPhase object for phases which
* employ gibbs excess free energy based formulations
* (see \ref thermoprops
* and class \link Cantera::GibbsExcessVPSSTP GibbsExcessVPSSTP\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.
*/
/*
* Copywrite (2006) Sandia Corporation. Under the terms of
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
* U.S. Government retains certain rights in this software.
*/
/*
* $Id$
*/
#ifndef CT_GIBBSEXCESSVPSSTP_H
#define CT_GIBBSEXCESSVPSSTP_H
#include "VPStandardStateTP.h"
namespace Cantera {
/**
* @ingroup thermoprops
*/
/*!
* GibbsExcessVPSSTP is a derived class of ThermoPhase that handles
* variable pressure standard state methods for calculating
* thermodynamic properties that are further based on
* expressing the Excess Gibbs free energy as a function of
* the mole fractions (or pseudo mole fractions) of consitituents.
* This category is the workhorse for describing molten salts,
* solid-phase mixtures of semiconductors, and mixtures of miscible
* and semi-miscible compounds.
*
* It includes
* . regular solutions
* . Margueles expansions
* . NTRL equation
* . Wilson's equation
* . UNIQUAC equation of state.
*
* This class adds additional functions onto the %ThermoPhase interface
* that handles the calculation of the excess Gibbs free energy. 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.
* That default is used here.
*
* All of the Excess Gibbs free energy formulations in this area employ
* symmetrical formulations.
*
*
* Chemical potentials
* of species k, \f$ \mu_o \f$, has the following general format:
*
* \f[
* \mu_k = \mu^o_k(T,P) + R T ln( \gamma_k X_k )
* \f]
*
*
* where \f$ \gamma_k^{\triangle} \f$ is a molar based activity coefficient for species
* \f$k\f$.
*
* GibbsExcessVPSSTP contains an internal vector with the current mole
* fraction vector. That's one of its primary usages. In order to keep the mole fraction
* vector constant, all of the setState functions are redesigned at this layer.
*
* <H3> SetState Strategy </H3>
*
* All setState functions that set the internal state of the ThermoPhase object are
* overloaded at this level, so that a current mole fraction vector is maintained within
* the object.
*
*
*/
class GibbsExcessVPSSTP : 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.
*/
GibbsExcessVPSSTP();
//! Copy constructor
/*!
* Note this stuff will not work until the underlying phase
* has a working copy constructor
*
* @param b class to be copied
*/
GibbsExcessVPSSTP(const GibbsExcessVPSSTP &b);
/// Assignment operator
/*!
*
* @param b class to be copied.
*/
GibbsExcessVPSSTP& operator=(const GibbsExcessVPSSTP &b);
/// Destructor.
virtual ~GibbsExcessVPSSTP();
//! 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;
/**
* @}
* @name Molar Thermodynamic Properties
* @{
*/
/**
* @}
* @name Mechanical Properties
* @{
*/
//! Set the internally storred pressure (Pa) at constant
//! temperature and composition
/*!
* This method sets the pressure within the object.
* The water model is a completely compressible model.
* Also, the dielectric constant is pressure dependent.
*
* @param p input Pressure (Pa)
*
* @todo Implement a variable pressure capability
*/
virtual void setPressure(doublereal p);
protected:
/**
* Calculate the density of the mixture using the partial
* molar volumes and mole fractions as input
*
* The formula for this is
*
* \f[
* \rho = \frac{\sum_k{X_k W_k}}{\sum_k{X_k V_k}}
* \f]
*
* where \f$X_k\f$ are the mole fractions, \f$W_k\f$ are
* the molecular weights, and \f$V_k\f$ are the pure species
* molar volumes.
*
* Note, the basis behind this formula is that in an ideal
* solution the partial molar volumes are equal to the pure
* species molar volumes. We have additionally specified
* in this class that the pure species molar volumes are
* independent of temperature and pressure.
*
* NOTE: This is a non-virtual function, which is not a
* member of the ThermoPhase base class.
*/
void calcDensity();
public:
/**
* @}
* @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.
* @{
*/
/**
* 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(int k=0) const;
/**
* Returns the natural logarithm of the standard
* concentration of the kth species
*
* @param k species index
*/
virtual doublereal logStandardConc(int 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.
/*!
* \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 temperature derivatives of the log activity coefficients
/*!
* This function is a virtual class, but it first appears in GibbsExcessVPSSTP
* class and derived classes from GibbsExcessVPSSTP.
*
* units = 1/Kelvin
*
* @param dlnActCoeffdT Output vector of temperature derivatives of the
* log Activity Coefficients. length = m_kk
*/
virtual void getdlnActCoeffdT(doublereal *dlnActCoeffdT) const {
err("getdlnActCoeffdT");
}
//! Get the array of change in the log activity coefficients w.r.t. change in state (change temp, change mole fractions)
/*!
* This function is a virtual class, but it first appears in GibbsExcessVPSSTP
* class and derived classes from GibbsExcessVPSSTP.
*
* This function is a virtual method. For ideal mixtures
* (unity activity coefficients), this can gradX/X.
*
* @param dT Input of temperature change
* @param dX Input vector of changes in mole fraction. length = m_kk
* @param dlnActCoeff Output vector of derivatives of the
* log Activity Coefficients. length = m_kk
*/
virtual void getdlnActCoeff(const doublereal dT, const doublereal * const dX, doublereal *dlnActCoeff) const {
err("getdlnActCoeff");
}
//! Get the array of log concentration-like derivatives of the
//! log activity coefficients
/*!
* This function is a virtual method. For ideal mixtures
* (unity activity coefficients), this can return zero.
* Implementations should take the derivative of the
* logarithm of the activity coefficient with respect to the
* logarithm of the concentration-like variable (i.e. mole fraction,
* molality, etc.) that represents the standard state.
* This quantity is to be used in conjunction with derivatives of
* that concentration-like variable when the derivative of the chemical
* potential is taken.
*
* units = dimensionless
*
* @param dlnActCoeffdlnN Output vector of derivatives of the
* log Activity Coefficients. length = m_kk
*/
virtual void getdlnActCoeffdlnN(doublereal *dlnActCoeffdlnN) const {
err("getdlnActCoeffdlnN");
}
//! Get the array of log concentration-like derivatives of the
//! log activity coefficients
/*!
* This function is a virtual method. For ideal mixtures
* (unity activity coefficients), this can return zero.
* Implementations should take the derivative of the
* logarithm of the activity coefficient with respect to the
* logarithm of the concentration-like variable (i.e. number of moles in
* in a unit volume. ) that represents the standard state.
* This quantity is to be used in conjunction with derivatives of
* that concentration-like variable when the derivative of the chemical
* potential is taken.
*
* units = dimensionless
*
* @param dlnActCoeffdlnX Output vector of derivatives of the
* log Activity Coefficients. length = m_kk
*/
virtual void getdlnActCoeffdlnX(doublereal *dlnActCoeffdlnX) const {
err("getdlnActCoeffdlnX");
}
//@}
/// @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;
//! Return an array of partial molar volumes for the
//! species in the mixture. Units: m^3/kmol.
/*!
* Frequently, for this class of thermodynamics representations,
* the excess Volume due to mixing is zero. Here, we set it as
* a default. It may be overriden in derived classes.
*
* @param vbar Output vector of speciar partial molar volumes.
* Length = m_kk. units are m^3/kmol.
*/
virtual void getPartialMolarVolumes(doublereal* vbar) 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.
* @{
*/
//! Set the temperature (K) and pressure (Pa)
/*!
* Set the temperature and pressure.
*
* @param t Temperature (K)
* @param p Pressure (Pa)
*/
virtual void setState_TP(doublereal t, doublereal p);
//@}
/**
* @name Chemical Equilibrium
* Routines that implement the Chemical equilibrium capability
* for a single phase, based on the element-potential method.
* @{
*/
/**
* Set the mass fractions to the specified values, and then
* normalize them so that they sum to 1.0.
* @param y Array of unnormalized mass fraction values (input).
* Must have a length greater than or equal to the number of
* species.
*
* @param y Input vector of mass fractions.
* Length is m_kk.
*/
virtual void setMassFractions(const doublereal* const y);
/**
* Set the mass fractions to the specified values without
* normalizing. This is useful when the normalization
* condition is being handled by some other means, for example
* by a constraint equation as part of a larger set of
* equations.
*
* @param y Input vector of mass fractions.
* Length is m_kk.
*/
virtual void setMassFractions_NoNorm(const doublereal* const y);
/**
* Set the mole fractions to the specified values, and then
* normalize them so that they sum to 1.0.
* @param x Array of unnormalized mole fraction values (input).
* Must have a length greater than or equal to the number of
* species.
*
* @param x Input vector of mole fractions.
* Length is m_kk.
*/
virtual void setMoleFractions(const doublereal* const x);
/**
* Set the mole fractions to the specified values without
* normalizing. This is useful when the normalization
* condition is being handled by some other means, for example
* by a constraint equation as part of a larger set of
* equations.
*
* @param x Input vector of mole fractions.
* Length is m_kk.
*/
virtual void setMoleFractions_NoNorm(const doublereal* const x);
/**
* Set the concentrations to the specified values within the
* phase.
*
* @param c The input vector to this routine is in dimensional
* units. For volumetric phases c[k] is the
* concentration of the kth species in kmol/m3.
* For surface phases, c[k] is the concentration
* in kmol/m2. The length of the vector is the number
* of species in the phase.
*/
virtual void setConcentrations(const doublereal* const c);
//@}
/// 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();
private:
//! Initialize lengths of local variables after all species have
//! been identified.
void initLengths();
//! Error function
/*!
* Print an error string and exit
*
* @param msg Message to be printed
*/
doublereal err(std::string msg) const;
protected:
//! utility routine to check mole fraction sum
/*!
* @param x vector of mole fractions.
*/
double checkMFSum(const doublereal * const x) const;
protected:
//! Storage for the current values of the mole fractions of the species
/*!
* This vector is kept up-to-date when the setState functions are called.
* Therefore, it may be considered to be an independent variable.
*
* Note in order to do this, the setState functions are redefined to always
* keep this vector current.
*/
mutable std::vector<doublereal> moleFractions_;
//! Storage for the current values of the activity coefficients of the
//! species, divided by RT
mutable std::vector<doublereal> lnActCoeff_Scaled_;
//! Storage for the current derivative values of the
//! gradients with respect to temperature of the
//! log of theactivity coefficients of the species
mutable std::vector<doublereal> dlnActCoeffdT_Scaled_;
//! Storage for the current derivative values of the
//! gradients with respect to temperature of the
//! log of theactivity coefficients of the species
mutable std::vector<doublereal> d2lnActCoeffdT2_Scaled_;
//! Storage for the current derivative values of the
//! gradients with respect to logarithm of the mole fraction of the
//! log of theactivity coefficients of the species
mutable std::vector<doublereal> dlnActCoeffdlnN_Scaled_;
//! Storage for the current derivative values of the
//! gradients with respect to logarithm of the mole fraction of the
//! log of theactivity coefficients of the species
mutable std::vector<doublereal> dlnActCoeffdlnX_Scaled_;
//! Temporary storage space that is fair game
mutable std::vector<doublereal> m_pp;
};
}
#endif