Cantera
2.1.2
|
Class ChemEquil implements a chemical equilibrium solver for single-phase solutions. More...
#include <ChemEquil.h>
Public Member Functions | |
ChemEquil (thermo_t &s) | |
Constructor combined with the initialization function. More... | |
int | equilibrate (thermo_t &s, const char *XY, bool useThermoPhaseElementPotentials=false, int loglevel=0) |
int | equilibrate (thermo_t &s, const char *XY, vector_fp &elMoles, bool useThermoPhaseElementPotentials=false, int loglevel=0) |
const vector_fp & | elementPotentials () const |
Public Attributes | |
EquilOpt | options |
Options controlling how the calculation is carried out. More... | |
Protected Member Functions | |
doublereal | nAtoms (size_t k, size_t m) const |
number of atoms of element m in species k. More... | |
void | initialize (thermo_t &s) |
void | setToEquilState (thermo_t &s, const vector_fp &x, doublereal t) |
int | setInitialMoles (thermo_t &s, vector_fp &elMoleGoal, int loglevel=0) |
Estimate the initial mole numbers. More... | |
int | estimateElementPotentials (thermo_t &s, vector_fp &lambda, vector_fp &elMolesGoal, int loglevel=0) |
Generate a starting estimate for the element potentials. More... | |
int | estimateEP_Brinkley (thermo_t &s, vector_fp &lambda, vector_fp &elMoles) |
int | dampStep (thermo_t &s, vector_fp &oldx, double oldf, vector_fp &grad, vector_fp &step, vector_fp &x, double &f, vector_fp &elmols, double xval, double yval) |
Find an acceptable step size and take it. More... | |
void | equilResidual (thermo_t &s, const vector_fp &x, const vector_fp &elmtotal, vector_fp &resid, double xval, double yval, int loglevel=0) |
Evaluates the residual vector F, of length m_mm. More... | |
void | equilJacobian (thermo_t &s, vector_fp &x, const vector_fp &elmols, DenseMatrix &jac, double xval, double yval, int loglevel=0) |
void | adjustEloc (thermo_t &s, vector_fp &elMolesGoal) |
void | update (const thermo_t &s) |
Update internally stored state information. More... | |
double | calcEmoles (thermo_t &s, vector_fp &x, const double &n_t, const vector_fp &Xmol_i_calc, vector_fp &eMolesCalc, vector_fp &n_i_calc, double pressureConst) |
Given a vector of dimensionless element abundances, this routine calculates the moles of the elements and the moles of the species. More... | |
Protected Attributes | |
thermo_t * | m_phase |
Pointer to the ThermoPhase object used to initialize this object. More... | |
size_t | m_mm |
number of elements in the phase More... | |
size_t | m_kk |
number of species in the phase More... | |
size_t | m_skip |
size_t | m_nComponents |
This is equal to the rank of the stoichiometric coefficient matrix when it is computed. More... | |
std::auto_ptr < PropertyCalculator< thermo_t > > | m_p1 |
std::auto_ptr < PropertyCalculator< thermo_t > > | m_p2 |
vector_fp | m_molefractions |
Current value of the mole fractions in the single phase. More... | |
vector_fp | m_lambda |
Current value of the dimensional element potentials -> length = m_mm. More... | |
doublereal | m_elementTotalSum |
vector_fp | m_elementmolefracs |
vector_fp | m_reswork |
vector_fp | m_jwork1 |
vector_fp | m_jwork2 |
vector_fp | m_comp |
doublereal | m_temp |
doublereal | m_dens |
doublereal | m_p0 |
size_t | m_eloc |
Index of the element id corresponding to the electric charge of each species. More... | |
vector_fp | m_startSoln |
vector_fp | m_grt |
vector_fp | m_mu_RT |
vector_fp | m_muSS_RT |
Dimensionless values of the gibbs free energy for the standard state of each species, at the temperature and pressure of the solution (the star standard state). More... | |
std::vector< size_t > | m_component |
double | m_elemFracCutoff |
element fractional cutoff, below which the element will be zeroed. More... | |
bool | m_doResPerturb |
std::vector< size_t > | m_orderVectorElements |
std::vector< size_t > | m_orderVectorSpecies |
Class ChemEquil implements a chemical equilibrium solver for single-phase solutions.
It is a "non-stoichiometric" solver in the terminology of Smith and Missen, meaning that every intermediate state is a valid chemical equilibrium state, but does not necessarily satisfy the element constraints. In contrast, the solver implemented in class MultiPhaseEquil uses a "stoichiometric" algorithm, in which each intermediate state satisfies the element constraints but is not a state of chemical equilibrium. Non-stoichiometric methods are faster when they converge, but stoichiometric ones tend to be more robust and can be used also for problems with multiple condensed phases. As expected, the ChemEquil solver is faster than MultiPhaseEquil for many single-phase equilibrium problems (particularly if there are only a few elements but very many species), but can be less stable. Problem situations include low temperatures where only a few species have non-zero mole fractions, precisely stoichiometric compositions (e.g. 2 H2 + O2). In general, if speed is important, this solver should be tried first, and if it fails then use MultiPhaseEquil.
Definition at line 95 of file ChemEquil.h.
Constructor combined with the initialization function.
This constructor initializes the ChemEquil object with everything it needs to start solving equilibrium problems.
s | ThermoPhase object that will be used in the equilibrium calls. |
Definition at line 58 of file ChemEquil.cpp.
References ChemEquil::initialize().
int equilibrate | ( | thermo_t & | s, |
const char * | XY, | ||
bool | useThermoPhaseElementPotentials = false , |
||
int | loglevel = 0 |
||
) |
Equilibrate a phase, holding the elemental composition fixed at the initial value found within the ThermoPhase object s.
The value of 2 specified properties are obtained by querying the ThermoPhase object. The properties must be already contained within the current thermodynamic state of the system.
Definition at line 394 of file ChemEquil.cpp.
References ChemEquil::initialize(), Phase::nElements(), and ChemEquil::update().
Referenced by Cantera::equilibrate(), and Cantera::vcs_equilibrate().
int equilibrate | ( | thermo_t & | s, |
const char * | XY, | ||
vector_fp & | elMoles, | ||
bool | useThermoPhaseElementPotentials = false , |
||
int | loglevel = 0 |
||
) |
Compute the equilibrium composition for 2 specified properties and the specified element moles.
The 2 specified properties are obtained by querying the ThermoPhase object. The properties must be already contained within the current thermodynamic state of the system.
s | phase object to be equilibrated |
XY | property pair to hold constant |
elMoles | specified vector of element abundances. |
useThermoPhaseElementPotentials | get the initial estimate for the chemical potentials from the ThermoPhase object (true) or create our own estimate (false) |
loglvel | Specify amount of debug logging (0 to disable) |
Definition at line 406 of file ChemEquil.cpp.
References Cantera::_equilflag(), EquilOpt::absElemTol, Cantera::addLogEntry(), Cantera::beginLogGroup(), ChemEquil::dampStep(), DATA_PTR, Cantera::dot(), Phase::elementName(), Phase::elementNames(), Cantera::endLogGroup(), ChemEquil::equilResidual(), ChemEquil::estimateElementPotentials(), ChemEquil::estimateEP_Brinkley(), Cantera::fp2str(), Cantera::GasConstant, ThermoPhase::getElementPotentials(), ChemEquil::initialize(), Cantera::int2str(), EquilOpt::iterations, ChemEquil::m_elemFracCutoff, ChemEquil::m_eloc, ChemEquil::m_kk, ChemEquil::m_lambda, ChemEquil::m_mm, ChemEquil::m_nComponents, EquilOpt::maxIterations, ThermoPhase::maxTemp(), ThermoPhase::minTemp(), Phase::moleFraction(), Phase::nElements(), Cantera::npos, Phase::nSpecies(), ChemEquil::options, EquilOpt::relTolerance, Phase::restoreState(), CanteraError::save(), Phase::saveState(), Cantera::scale(), ThermoPhase::setElementPotentials(), ChemEquil::setInitialMoles(), Phase::setMoleFractions(), Phase::setTemperature(), ChemEquil::setToEquilState(), Cantera::solve(), Phase::temperature(), ChemEquil::update(), Cantera::writelog(), and Cantera::writelogf().
|
inlineprotected |
number of atoms of element m in species k.
Definition at line 166 of file ChemEquil.h.
References ChemEquil::m_mm.
Referenced by ChemEquil::calcEmoles(), ChemEquil::estimateElementPotentials(), ChemEquil::estimateEP_Brinkley(), ChemEquil::setToEquilState(), and ChemEquil::update().
|
protected |
Prepare for equilibrium calculations.
s | object representing the solution phase. |
Definition at line 72 of file ChemEquil.cpp.
References Phase::atomicWeight(), Phase::elementName(), Cantera::fp2str(), ChemEquil::m_eloc, ChemEquil::m_kk, ChemEquil::m_lambda, ChemEquil::m_mm, ChemEquil::m_molefractions, ChemEquil::m_muSS_RT, ChemEquil::m_nComponents, ChemEquil::m_phase, Phase::nAtoms(), Phase::nElements(), Cantera::npos, Phase::nSpecies(), ThermoPhase::refPressure(), Phase::speciesName(), and Cantera::writelog().
Referenced by ChemEquil::ChemEquil(), and ChemEquil::equilibrate().
Set mixture to an equilibrium state consistent with specified element potentials and temperature.
s | mixture to be updated |
x | vector of non-dimensional element potentials \[ \lambda_m/RT \] . |
t | temperature in K. |
Definition at line 147 of file ChemEquil.cpp.
References DATA_PTR, ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::nAtoms(), Phase::setTemperature(), ThermoPhase::setToEquilState(), and ChemEquil::update().
Referenced by ChemEquil::equilibrate(), and ChemEquil::equilResidual().
Estimate the initial mole numbers.
This version borrows from the MultiPhaseEquil solver.
Definition at line 197 of file ChemEquil.cpp.
References Cantera::addLogEntry(), MultiPhase::addPhase(), Cantera::beginLogGroup(), Phase::elementName(), Cantera::endLogGroup(), MultiPhase::init(), ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::m_nComponents, Phase::moleFraction(), ThermoPhase::pressure(), CanteraError::save(), Phase::speciesName(), Phase::temperature(), ChemEquil::update(), Cantera::writelog(), and Cantera::writelogf().
Referenced by ChemEquil::equilibrate().
|
protected |
Generate a starting estimate for the element potentials.
Definition at line 262 of file ChemEquil.cpp.
References Cantera::addLogEntry(), MultiPhase::addPhase(), Cantera::BasisOptimize(), Cantera::beginLogGroup(), DATA_PTR, Phase::elementName(), Cantera::ElemRearrange(), Cantera::endLogGroup(), Cantera::GasConstant, ThermoPhase::getChemPotentials(), Phase::getMoleFractions(), MultiPhase::init(), ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::m_nComponents, ChemEquil::nAtoms(), Phase::nSpecies(), ThermoPhase::pressure(), Cantera::scale(), Phase::setMoleFractions(), Cantera::solve(), Phase::speciesName(), Phase::temperature(), Cantera::writelog(), and Cantera::writelogf().
Referenced by ChemEquil::equilibrate().
Do a calculation of the element potentials using the Brinkley method, p. 129 Smith and Missen.
We have found that the previous estimate may not be good enough to avoid drastic numerical issues associated with the use of a numerically generated jacobian used in the main algorithm.
The Brinkley algorithm, here, assumes a constant T, P system and uses a linearized analytical Jacobian that turns out to be very stable even given bad initial guesses.
The pressure and temperature to be used are in the ThermoPhase object input into the routine.
The initial guess for the element potentials used by this routine is taken from the input vector, x.
elMoles is the input element abundance vector to be matched.
Nonideal phases are handled in principle. This is done by calculating the activity coefficients and adding them into the formula in the correct position. However, these are treated as a rhs contribution only. Therefore, convergence might be a problem. This has not been tested. Also molality based unit systems aren't handled.
On return, int return value contains the success code:
NOTE: update for activity coefficients.
Definition at line 1180 of file ChemEquil.cpp.
References EquilOpt::absElemTol, Cantera::addLogEntry(), ChemEquil::calcEmoles(), DATA_PTR, Phase::elementName(), Phase::elementNames(), ThermoPhase::getActivityCoefficients(), ThermoPhase::getGibbs_RT(), Phase::getMoleFractions(), ChemEquil::m_eloc, ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::m_muSS_RT, ChemEquil::m_nComponents, EquilOpt::maxIterations, ChemEquil::nAtoms(), Cantera::npos, ChemEquil::options, ThermoPhase::pressure(), EquilOpt::relTolerance, Phase::restoreState(), CanteraError::save(), Phase::saveState(), Phase::setMoleFractions(), ThermoPhase::setPressure(), Cantera::solve(), Phase::speciesName(), Phase::temperature(), Cantera::writelog(), and Cantera::writelogf().
Referenced by ChemEquil::equilibrate().
|
protected |
Find an acceptable step size and take it.
The original implementation employed a line search technique that enforced a reduction in the norm of the residual at every successful step. Unfortunately, this method created false convergence errors near the end of a significant number of steps, usually special conditions where there were stoichiometric constraints.
This new method just does a delta damping approach, based on limiting the jump in the dimensionless element potentials. Mole fractions are limited to a factor of 2 jump in the values from this method. Near convergence, the delta damping gets out of the way.
Definition at line 979 of file ChemEquil.cpp.
References ChemEquil::m_eloc, ChemEquil::m_mm, Cantera::writelog(), and Cantera::writelogf().
Referenced by ChemEquil::equilibrate().
|
protected |
Evaluates the residual vector F, of length m_mm.
Definition at line 1025 of file ChemEquil.cpp.
References Cantera::addLogEntry(), Cantera::beginLogGroup(), Phase::elementName(), Cantera::endLogGroup(), Cantera::fp2str(), ChemEquil::m_elemFracCutoff, ChemEquil::m_eloc, ChemEquil::m_mm, ChemEquil::m_nComponents, ChemEquil::setToEquilState(), Cantera::writelog(), and Cantera::writelogf().
Referenced by ChemEquil::equilibrate().
|
protected |
Update internally stored state information.
Definition at line 167 of file ChemEquil.cpp.
References DATA_PTR, Phase::density(), Cantera::fp2str(), Phase::getMoleFractions(), ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::m_molefractions, ChemEquil::nAtoms(), Phase::speciesName(), and Phase::temperature().
Referenced by ChemEquil::equilibrate(), ChemEquil::setInitialMoles(), and ChemEquil::setToEquilState().
|
protected |
Given a vector of dimensionless element abundances, this routine calculates the moles of the elements and the moles of the species.
[in] | x | = current dimensionless element potentials.. |
Definition at line 1140 of file ChemEquil.cpp.
References DATA_PTR, ThermoPhase::getActivityCoefficients(), ChemEquil::m_kk, ChemEquil::m_mm, ChemEquil::m_muSS_RT, ChemEquil::nAtoms(), Phase::setMoleFractions(), and ThermoPhase::setPressure().
Referenced by ChemEquil::estimateEP_Brinkley().
EquilOpt options |
Options controlling how the calculation is carried out.
Definition at line 150 of file ChemEquil.h.
Referenced by Cantera::equilibrate(), ChemEquil::equilibrate(), ChemEquil::estimateEP_Brinkley(), and Cantera::vcs_equilibrate().
|
protected |
Pointer to the ThermoPhase object used to initialize this object.
This ThermoPhase object must be compatible with the ThermoPhase objects input from the equilibrate function. Currently, this means that the 2 ThermoPhases have to have consist of the same species and elements.
Definition at line 163 of file ChemEquil.h.
Referenced by ChemEquil::initialize().
|
protected |
number of elements in the phase
Definition at line 275 of file ChemEquil.h.
Referenced by ChemEquil::calcEmoles(), ChemEquil::dampStep(), ChemEquil::equilibrate(), ChemEquil::equilResidual(), ChemEquil::estimateElementPotentials(), ChemEquil::estimateEP_Brinkley(), ChemEquil::initialize(), ChemEquil::nAtoms(), ChemEquil::setInitialMoles(), ChemEquil::setToEquilState(), and ChemEquil::update().
|
protected |
number of species in the phase
Definition at line 276 of file ChemEquil.h.
Referenced by ChemEquil::calcEmoles(), ChemEquil::equilibrate(), ChemEquil::estimateElementPotentials(), ChemEquil::estimateEP_Brinkley(), ChemEquil::initialize(), ChemEquil::setInitialMoles(), ChemEquil::setToEquilState(), and ChemEquil::update().
|
protected |
This is equal to the rank of the stoichiometric coefficient matrix when it is computed.
It's initialized to m_mm.
Definition at line 283 of file ChemEquil.h.
Referenced by ChemEquil::equilibrate(), ChemEquil::equilResidual(), ChemEquil::estimateElementPotentials(), ChemEquil::estimateEP_Brinkley(), ChemEquil::initialize(), and ChemEquil::setInitialMoles().
|
protected |
Current value of the mole fractions in the single phase.
-> length = m_kk.
Definition at line 291 of file ChemEquil.h.
Referenced by ChemEquil::initialize(), and ChemEquil::update().
|
protected |
Current value of the dimensional element potentials -> length = m_mm.
Definition at line 296 of file ChemEquil.h.
Referenced by ChemEquil::equilibrate(), and ChemEquil::initialize().
|
protected |
Index of the element id corresponding to the electric charge of each species.
Equal to -1 if there is no such element id.
Definition at line 324 of file ChemEquil.h.
Referenced by ChemEquil::dampStep(), ChemEquil::equilibrate(), ChemEquil::equilResidual(), ChemEquil::estimateEP_Brinkley(), and ChemEquil::initialize().
|
protected |
Dimensionless values of the gibbs free energy for the standard state of each species, at the temperature and pressure of the solution (the star standard state).
Definition at line 336 of file ChemEquil.h.
Referenced by ChemEquil::calcEmoles(), ChemEquil::estimateEP_Brinkley(), and ChemEquil::initialize().
|
protected |
element fractional cutoff, below which the element will be zeroed.
Definition at line 340 of file ChemEquil.h.
Referenced by ChemEquil::equilibrate(), and ChemEquil::equilResidual().