175 lines
5 KiB
C++
Executable file
175 lines
5 KiB
C++
Executable file
/**
|
|
* @file ChemEquil.h
|
|
*
|
|
* Chemical equilibrium.
|
|
*
|
|
* $Author$
|
|
* $Date$
|
|
* $Revision$
|
|
*
|
|
* Copyright 2001 California Institute of Technology
|
|
*
|
|
*/
|
|
|
|
|
|
#ifndef CT_CHEM_EQUIL_H
|
|
#define CT_CHEM_EQUIL_H
|
|
|
|
|
|
// Cantera includes
|
|
#include "ct_defs.h"
|
|
#include "vec_functions.h"
|
|
#include "ctexceptions.h"
|
|
#include "ThermoPhase.h"
|
|
#include "DenseMatrix.h"
|
|
|
|
#include "MultiPhaseEquil.h"
|
|
|
|
namespace Cantera {
|
|
|
|
int _equilflag(const char* xy);
|
|
|
|
/**
|
|
* Chemical equilibrium options. Used internally by class ChemEquil.
|
|
*/
|
|
class EquilOpt {
|
|
public:
|
|
EquilOpt() : relTolerance(1.e-10), maxIterations(1000), iterations(0),
|
|
maxStepSize(10.0), propertyPair(TP), contin(false) {}
|
|
|
|
doublereal relTolerance; ///< Relative tolerance
|
|
int maxIterations; ///< Maximum number of iterations
|
|
int iterations; ///< Iteration counter
|
|
|
|
/**
|
|
* Maximum step size. Largest change in any element potential or
|
|
* in log(T) allowed in one Newton step. Default: 10.0
|
|
*/
|
|
doublereal maxStepSize;
|
|
|
|
/**
|
|
* Property pair flag. Determines which two thermodynamic properties
|
|
* are fixed.
|
|
*/
|
|
int propertyPair;
|
|
|
|
/**
|
|
* Continuation flag. Set true if the calculation should be
|
|
* initialized from the last calculation. Otherwise, the
|
|
* calculation will be started from scratch and the initial
|
|
* composition and element potentials estimated.
|
|
*/
|
|
bool contin;
|
|
};
|
|
|
|
template<class M>
|
|
class PropertyCalculator;
|
|
|
|
/**
|
|
* @defgroup equil Chemical Equilibrium
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* 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
|
|
* vvery 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.
|
|
* @ingroup equil
|
|
*/
|
|
class ChemEquil {
|
|
|
|
public:
|
|
ChemEquil();
|
|
virtual ~ChemEquil();
|
|
|
|
int equilibrate(thermo_t& s, const char* XY);
|
|
int equilibrate(thermo_t& s, const char* XY, vector_fp& elMoles);
|
|
const vector_fp& elementPotentials() const { return m_lambda; }
|
|
|
|
/**
|
|
* Options controlling how the calculation is carried out.
|
|
* @see EquilOptions
|
|
*/
|
|
EquilOpt options;
|
|
|
|
|
|
protected:
|
|
|
|
thermo_t* m_phase;
|
|
thermo_t* m_thermo;
|
|
|
|
/// number of atoms of element m in species k.
|
|
doublereal nAtoms(int k, int m) const { return m_comp[k*m_mm + m]; }
|
|
|
|
void initialize(thermo_t& s);
|
|
|
|
void setToEquilState(thermo_t& s,
|
|
const vector_fp& x, doublereal t);
|
|
|
|
int setInitialMoles(thermo_t& s);
|
|
|
|
int estimateElementPotentials(thermo_t& s,
|
|
vector_fp& lambda);
|
|
|
|
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 );
|
|
|
|
void equilResidual(thermo_t& s, const vector_fp& x,
|
|
const vector_fp& elmtotal, vector_fp& resid,
|
|
double xval, double yval);
|
|
|
|
void equilJacobian(thermo_t& s, vector_fp& x,
|
|
const vector_fp& elmols, DenseMatrix& jac,
|
|
double xval, double yval);
|
|
|
|
void update(const thermo_t& s);
|
|
|
|
int m_mm;
|
|
int m_kk;
|
|
int m_skip;
|
|
|
|
PropertyCalculator<thermo_t> *m_p1, *m_p2;
|
|
|
|
vector_fp m_molefractions;
|
|
vector_fp m_lambda;
|
|
vector_fp m_elementmolefracs;
|
|
vector_fp m_reswork;
|
|
vector_fp m_jwork1;
|
|
vector_fp m_jwork2;
|
|
vector_fp m_comp;
|
|
doublereal m_temp, m_dens;
|
|
doublereal m_p0;
|
|
int m_eloc;
|
|
doublereal m_abscharge;
|
|
|
|
doublereal m_startTemp, m_startDens;
|
|
vector_fp m_startSoln;
|
|
|
|
vector_fp m_grt;
|
|
vector_fp m_mu_RT;
|
|
vector_int m_component;
|
|
};
|
|
|
|
}
|
|
|
|
|
|
#endif
|
|
|