Added a new way to specify the kinetics reaction rate coefficient

when dealing with electron transfer surface reactions.
This way specifies an exchange current density reaction rate coefficient
in units of amps / m2.  This is slightly more informative for 
electrode reactions. 

The new also preserves the correct treatment of activity coefficients
for these reactions. 

A memo describing this new capability is in the works.
This commit is contained in:
Harry Moffat 2010-03-01 18:14:07 +00:00
parent 60afcc5d57
commit 263aeb6b35
15 changed files with 781 additions and 295 deletions

View file

@ -25,9 +25,8 @@ using namespace std;
namespace Cantera { namespace Cantera {
////////////////////////////////////////////////////////////////// //====================================================================================================================
/*
/**
* Construct an empty InterfaceKinetics reaction mechanism. * Construct an empty InterfaceKinetics reaction mechanism.
* @param thermo This is an optional parameter that may be * @param thermo This is an optional parameter that may be
* used to initialize the inherited Kinetics class with * used to initialize the inherited Kinetics class with
@ -35,8 +34,7 @@ namespace Cantera {
* useful for initialization of homogeneous kinetics * useful for initialization of homogeneous kinetics
* mechanisms. * mechanisms.
*/ */
InterfaceKinetics:: InterfaceKinetics::InterfaceKinetics(thermo_t* thermo) :
InterfaceKinetics(thermo_t* thermo) :
Kinetics(), Kinetics(),
m_kk(0), m_kk(0),
m_redo_rates(false), m_redo_rates(false),
@ -44,27 +42,33 @@ namespace Cantera {
m_nrev(0), m_nrev(0),
m_surf(0), m_surf(0),
m_integrator(0), m_integrator(0),
m_beta(0),
m_ctrxn(0),
m_ctrxn_ecdf(0),
m_logStandardConc(0),
m_deltaG0(0),
m_logProdStanConcReac(0),
m_finalized(false), m_finalized(false),
m_has_coverage_dependence(false), m_has_coverage_dependence(false),
m_has_electrochem_rxns(false), m_has_electrochem_rxns(false),
m_has_exchange_current_density_formulation(false),
m_ioFlag(0) m_ioFlag(0)
{ {
if (thermo != 0) addPhase(*thermo); if (thermo != 0) addPhase(*thermo);
m_kdata = new InterfaceKineticsData; m_kdata = new InterfaceKineticsData;
m_kdata->m_temp = 0.0; m_kdata->m_temp = 0.0;
} }
//====================================================================================================================
/** /*
* Destructor * Destructor
*/ */
InterfaceKinetics:: InterfaceKinetics::~InterfaceKinetics(){
~InterfaceKinetics(){
delete m_kdata; delete m_kdata;
if (m_integrator) { if (m_integrator) {
delete m_integrator; delete m_integrator;
} }
} }
//====================================================================================================================
// Copy Constructor for the %InterfaceKinetics object. // Copy Constructor for the %InterfaceKinetics object.
/* /*
* Currently, this is not fully implemented. If called it will * Currently, this is not fully implemented. If called it will
@ -78,9 +82,16 @@ namespace Cantera {
m_nrev(0), m_nrev(0),
m_surf(0), m_surf(0),
m_integrator(0), m_integrator(0),
m_beta(0),
m_ctrxn(0),
m_ctrxn_ecdf(0),
m_logStandardConc(0),
m_deltaG0(0),
m_logProdStanConcReac(0),
m_finalized(false), m_finalized(false),
m_has_coverage_dependence(false), m_has_coverage_dependence(false),
m_has_electrochem_rxns(false), m_has_electrochem_rxns(false),
m_has_exchange_current_density_formulation(false),
m_ioFlag(0) m_ioFlag(0)
{ {
m_kdata = new InterfaceKineticsData; m_kdata = new InterfaceKineticsData;
@ -90,7 +101,7 @@ namespace Cantera {
*/ */
*this = operator=(right); *this = operator=(right);
} }
//====================================================================================================================
// Assignment operator // Assignment operator
/* /*
* This is NOT a virtual function. * This is NOT a virtual function.
@ -127,19 +138,23 @@ namespace Cantera {
m_E = right.m_E; m_E = right.m_E;
m_surf = right.m_surf; //DANGER - shallow copy m_surf = right.m_surf; //DANGER - shallow copy
m_integrator = right.m_integrator; //DANGER - shallow copy m_integrator = right.m_integrator; //DANGER - shallow copy
m_beta = right.m_beta; m_beta = right.m_beta;
m_ctrxn = right.m_ctrxn; m_ctrxn = right.m_ctrxn;
m_ctrxn_ecdf = right.m_ctrxn_ecdf;
m_logStandardConc = right.m_logStandardConc;
m_deltaG0 = right.m_deltaG0;
m_logProdStanConcReac = right.m_logProdStanConcReac;
m_finalized = right.m_finalized; m_finalized = right.m_finalized;
m_has_coverage_dependence = right.m_has_coverage_dependence; m_has_coverage_dependence = right.m_has_coverage_dependence;
m_has_electrochem_rxns = right.m_has_electrochem_rxns; m_has_electrochem_rxns = right.m_has_electrochem_rxns;
m_has_exchange_current_density_formulation = right.m_has_exchange_current_density_formulation;
m_ioFlag = right.m_ioFlag; m_ioFlag = right.m_ioFlag;
return *this; return *this;
} }
//====================================================================================================================
// Duplication routine for objects which inherit from Kinetics
// Duplication routine for objects which inherit from
// Kinetics
/* /*
* This virtual routine can be used to duplicate %Kinetics objects * This virtual routine can be used to duplicate %Kinetics objects
* inherited from %Kinetics even if the application only has * inherited from %Kinetics even if the application only has
@ -152,14 +167,18 @@ namespace Cantera {
InterfaceKinetics* tp = new InterfaceKinetics(*this); InterfaceKinetics* tp = new InterfaceKinetics(*this);
return dynamic_cast<Kinetics *>(tp); return dynamic_cast<Kinetics *>(tp);
} }
//====================================================================================================================
// Update properties that depend on temperature
/** /*
* Update properties that depend on temperature * This is called to update all of the properties that depend on temperature
* *
*/ * Current objects that this function updates
void InterfaceKinetics:: * m_kdata->m_logtemp
_update_rates_T() { * m_kdata->m_rfn
* m_rates.
* updateKc();
*/
void InterfaceKinetics::_update_rates_T() {
_update_rates_phi(); _update_rates_phi();
if (m_has_coverage_dependence) { if (m_has_coverage_dependence) {
m_surf->getCoverages(DATA_PTR(m_conc)); m_surf->getCoverages(DATA_PTR(m_conc));
@ -167,20 +186,24 @@ namespace Cantera {
m_redo_rates = true; m_redo_rates = true;
} }
doublereal T = thermo(surfacePhaseIndex()).temperature(); doublereal T = thermo(surfacePhaseIndex()).temperature();
m_redo_rates = true;
if (T != m_kdata->m_temp || m_redo_rates) { if (T != m_kdata->m_temp || m_redo_rates) {
m_kdata->m_logtemp = log(T); m_kdata->m_logtemp = log(T);
m_rates.update(T, m_kdata->m_logtemp, DATA_PTR(m_kdata->m_rfn)); m_rates.update(T, m_kdata->m_logtemp, DATA_PTR(m_kdata->m_rfn));
if (m_has_electrochem_rxns) if (m_has_exchange_current_density_formulation) {
applyExchangeCurrentDensityFormulation(DATA_PTR(m_kdata->m_rfn));
}
if (m_has_electrochem_rxns) {
applyButlerVolmerCorrection(DATA_PTR(m_kdata->m_rfn)); applyButlerVolmerCorrection(DATA_PTR(m_kdata->m_rfn));
}
m_kdata->m_temp = T; m_kdata->m_temp = T;
updateKc(); updateKc();
m_kdata->m_ROP_ok = false; m_kdata->m_ROP_ok = false;
m_redo_rates = false; m_redo_rates = false;
} }
} }
//====================================================================================================================
void InterfaceKinetics:: void InterfaceKinetics::_update_rates_phi() {
_update_rates_phi() {
int np = nPhases(); int np = nPhases();
for (int n = 0; n < np; n++) { for (int n = 0; n < np; n++) {
if (thermo(n).electricPotential() != m_phi[n]) { if (thermo(n).electricPotential() != m_phi[n]) {
@ -189,6 +212,7 @@ namespace Cantera {
} }
} }
} }
//====================================================================================================================
/** /**
@ -198,8 +222,7 @@ namespace Cantera {
* representing phases should overload to return the appropriate * representing phases should overload to return the appropriate
* quantities. * quantities.
*/ */
void InterfaceKinetics:: void InterfaceKinetics::_update_rates_C() {
_update_rates_C() {
int n; int n;
int np = nPhases(); int np = nPhases();
@ -263,6 +286,8 @@ namespace Cantera {
} }
} }
} }
//====================================================================================================================
void InterfaceKinetics::checkPartialEquil() { void InterfaceKinetics::checkPartialEquil() {
@ -338,6 +363,36 @@ namespace Cantera {
} }
} }
void InterfaceKinetics::getExchangeCurrentQuantities() {
/*
* First collect vectors of the standard Gibbs free energies of the
* species and the standard concentrations
* - m_mu0
* - m_logStandardConc
*/
int ik = 0;
int np = nPhases();
for (int n = 0; n < np; n++) {
thermo(n).getStandardChemPotentials(DATA_PTR(m_mu0) + m_start[n]);
int nsp = thermo(n).nSpecies();
for (int k = 0; k < nsp; k++) {
m_logStandardConc[ik] = thermo(n).logStandardConc(k);
ik++;
}
}
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu0), DATA_PTR(m_deltaG0));
for (int i = 0; i < m_ii; i++) {
m_logProdStanConcReac[i] = 1.0;
}
m_rxnstoich.multiplyReactants(DATA_PTR(m_logStandardConc), DATA_PTR(m_logProdStanConcReac));
}
// Returns the Species creation rates [kmol/m^2/s]. // Returns the Species creation rates [kmol/m^2/s].
/* /*
* Return the species * Return the species
@ -385,12 +440,17 @@ namespace Cantera {
net); net);
} }
/** //====================================================================================================================
// Apply corrections for interfacial charge transfer reactions
/*
* For reactions that transfer charge across a potential difference, * For reactions that transfer charge across a potential difference,
* the activation energies are modified by the potential difference. * the activation energies are modified by the potential difference.
* (see, for example, ...). This method applies this correction. * (see, for example, ...). This method applies this correction.
*
* @param kf Vector of forward reaction rate constants on which to have
* the correction applied
*/ */
void InterfaceKinetics::applyButlerVolmerCorrection(doublereal* kf) { void InterfaceKinetics::applyButlerVolmerCorrection(doublereal* const kf) {
int i; int i;
int n, nsp, k, ik=0; int n, nsp, k, ik=0;
@ -410,8 +470,7 @@ namespace Cantera {
// Compute the change in electrical potential energy for each // Compute the change in electrical potential energy for each
// reaction. This will only be non-zero if a potential // reaction. This will only be non-zero if a potential
// difference is present. // difference is present.
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_pot), m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_pot), DATA_PTR(m_rwork));
DATA_PTR(m_rwork));
// Modify the reaction rates. Only modify those with a // Modify the reaction rates. Only modify those with a
// non-zero activation energy. Below we decrease the // non-zero activation energy. Below we decrease the
@ -432,7 +491,8 @@ namespace Cantera {
for (i = 0; i < nct; i++) { for (i = 0; i < nct; i++) {
irxn = m_ctrxn[i]; irxn = m_ctrxn[i];
eamod = m_beta[i]*m_rwork[irxn]; eamod = m_beta[i]*m_rwork[irxn];
if (eamod != 0.0 && m_E[irxn] != 0.0) { // if (eamod != 0.0 && m_E[irxn] != 0.0) {
if (eamod != 0.0) {
#ifdef DEBUG_KIN_MODE #ifdef DEBUG_KIN_MODE
ea = GasConstant * m_E[irxn]; ea = GasConstant * m_E[irxn];
if (eamod + ea < 0.0) { if (eamod + ea < 0.0) {
@ -450,18 +510,31 @@ namespace Cantera {
} }
} }
} }
//====================================================================================================================
void InterfaceKinetics::applyExchangeCurrentDensityFormulation(doublereal* const kfwd) {
getExchangeCurrentQuantities();
int nct = m_ctrxn.size();
doublereal rt = GasConstant*thermo(0).temperature();
doublereal rrt = 1.0/rt;
for (int i = 0; i < nct; i++) {
int irxn = m_ctrxn[i];
int iECDFormulation = m_ctrxn_ecdf[i];
if (iECDFormulation) {
double tmp = exp(- m_beta[i] * m_deltaG0[irxn] * rrt);
tmp *= 1.0 / m_logProdStanConcReac[irxn] / Faraday;
kfwd[irxn] *= tmp;
}
}
}
//====================================================================================================================
/** /**
* Update the rates of progress of the reactions in the reaciton * Update the rates of progress of the reactions in the reaciton
* mechanism. This routine operates on internal data. * mechanism. This routine operates on internal data.
*/ */
void InterfaceKinetics::getFwdRateConstants(doublereal* kfwd) { void InterfaceKinetics::getFwdRateConstants(doublereal* kfwd) {
// _update_rates_T();
// _update_rates_C();
updateROP(); updateROP();
const vector_fp& rf = m_kdata->m_rfn; const vector_fp& rf = m_kdata->m_rfn;
@ -738,7 +811,7 @@ namespace Cantera {
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS); m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS);
} }
//====================================================================================================================
/** /**
* Add a single reaction to the mechanism. This routine * Add a single reaction to the mechanism. This routine
* must be called after init() and before finalize(). * must be called after init() and before finalize().
@ -752,8 +825,7 @@ namespace Cantera {
* There is no difference between elementary and surface * There is no difference between elementary and surface
* reactions. * reactions.
*/ */
void InterfaceKinetics:: void InterfaceKinetics::addReaction(const ReactionData& r) {
addReaction(const ReactionData& r) {
addElementaryReaction(r); addElementaryReaction(r);
@ -763,10 +835,8 @@ namespace Cantera {
incrementRxnCount(); incrementRxnCount();
m_rxneqn.push_back(r.equation); m_rxneqn.push_back(r.equation);
} }
//====================================================================================================================
void InterfaceKinetics::addElementaryReaction(const ReactionData& r) {
void InterfaceKinetics::
addElementaryReaction(const ReactionData& r) {
int iloc; int iloc;
// install rate coeff calculator // install rate coeff calculator
@ -776,12 +846,11 @@ namespace Cantera {
if (ncov > 3) { if (ncov > 3) {
m_has_coverage_dependence = true; m_has_coverage_dependence = true;
} }
for (int m = 0; m < ncov; m++) rp.push_back(r.cov[m]); for (int m = 0; m < ncov; m++) {
rp.push_back(r.cov[m]);
iloc = m_rates.install( reactionNumber(), }
r.rateCoeffType, rp.size(), // iloc = m_rates.install(reactionNumber(), r.rateCoeffType, rp.size(), DATA_PTR(rp));
DATA_PTR(rp) ); iloc = m_rates.install(reactionNumber(), ARRHENIUS_REACTION_RATECOEFF_TYPE, rp.size(), DATA_PTR(rp));
// store activation energy // store activation energy
m_E.push_back(r.rateCoeffParameters[2]); m_E.push_back(r.rateCoeffParameters[2]);
@ -789,13 +858,19 @@ namespace Cantera {
m_has_electrochem_rxns = true; m_has_electrochem_rxns = true;
m_beta.push_back(r.beta); m_beta.push_back(r.beta);
m_ctrxn.push_back(reactionNumber()); m_ctrxn.push_back(reactionNumber());
if (r.rateCoeffType == EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE) {
m_has_exchange_current_density_formulation = true;
m_ctrxn_ecdf.push_back(1);
} else {
m_ctrxn_ecdf.push_back(0);
}
} }
// add constant term to rate coeff value vector // add constant term to rate coeff value vector
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]); m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc); registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc);
} }
//====================================================================================================================
void InterfaceKinetics::setIOFlag(int ioFlag) { void InterfaceKinetics::setIOFlag(int ioFlag) {
m_ioFlag = ioFlag; m_ioFlag = ioFlag;
@ -958,6 +1033,7 @@ namespace Cantera {
* since we don't know this number up to now. * since we don't know this number up to now.
*/ */
void InterfaceKinetics::finalize() { void InterfaceKinetics::finalize() {
Kinetics::finalize();
m_rwork.resize(nReactions()); m_rwork.resize(nReactions());
int ks = reactionPhaseIndex(); int ks = reactionPhaseIndex();
if (ks < 0) throw CanteraError("InterfaceKinetics::finalize", if (ks < 0) throw CanteraError("InterfaceKinetics::finalize",
@ -967,6 +1043,13 @@ namespace Cantera {
throw CanteraError("InterfaceKinetics::finalize", throw CanteraError("InterfaceKinetics::finalize",
"expected interface dimension = 2, but got dimension = " "expected interface dimension = 2, but got dimension = "
+int2str(m_surf->nDim())); +int2str(m_surf->nDim()));
m_logStandardConc.resize(m_nTotalSpecies, 0.0);
m_deltaG0.resize(m_ii, 0.0);
m_logProdStanConcReac.resize(m_ii, 0.0);
m_finalized = true; m_finalized = true;
} }

View file

@ -45,11 +45,15 @@ namespace Cantera {
class InterfaceKineticsData { class InterfaceKineticsData {
public: public:
InterfaceKineticsData() : InterfaceKineticsData() :
m_logp0(0.0),
m_logc0(0.0),
m_ROP_ok(false), m_ROP_ok(false),
m_temp(0.0), m_logtemp(0.0) m_temp(0.0),
m_logtemp(0.0)
{} {}
//! Virtual destructor //! Virtual destructor
virtual ~InterfaceKineticsData(){} virtual ~InterfaceKineticsData() {
}
doublereal m_logp0; doublereal m_logp0;
doublereal m_logc0; doublereal m_logc0;
@ -59,7 +63,9 @@ namespace Cantera {
bool m_ROP_ok; bool m_ROP_ok;
//! Current temperature of the data
doublereal m_temp; doublereal m_temp;
//! Current log of the temperature
doublereal m_logtemp; doublereal m_logtemp;
vector_fp m_rfn; vector_fp m_rfn;
vector_fp m_rkcn; vector_fp m_rkcn;
@ -76,9 +82,9 @@ namespace Cantera {
public: public:
/**
* Constructor //! Constructor
* /*!
* @param thermo The optional parameter may be used to initialize * @param thermo The optional parameter may be used to initialize
* the object with one ThermoPhase object. * the object with one ThermoPhase object.
* HKM Note -> Since the interface kinetics * HKM Note -> Since the interface kinetics
@ -125,9 +131,9 @@ namespace Cantera {
virtual int ID() const { return cInterfaceKinetics; } virtual int ID() const { return cInterfaceKinetics; }
virtual int type() const { return cInterfaceKinetics; } virtual int type() const { return cInterfaceKinetics; }
/**
* Set the electric potential in the nth phase //! Set the electric potential in the nth phase
* /*!
* @param n phase Index in this kinetics object. * @param n phase Index in this kinetics object.
* @param V Electric potential (volts) * @param V Electric potential (volts)
*/ */
@ -172,8 +178,17 @@ namespace Cantera {
std::copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP); std::copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP);
} }
//! Get the equilibrium constants of all reactions, whether
//! the reaction is reversible or not.
/*!
* @param kc Returns the concentration equation constant for the reaction.
* Length is the number of reactions
*/
virtual void getEquilibriumConstants(doublereal* kc); virtual void getEquilibriumConstants(doublereal* kc);
void getExchangeCurrentQuantities();
virtual void getDeltaGibbs( doublereal* deltaG); virtual void getDeltaGibbs( doublereal* deltaG);
@ -394,8 +409,19 @@ namespace Cantera {
void updateROP(); void updateROP();
//! Update properties that depend on temperature
/*!
* This is called to update all of the properties that depend on temperature
*
* Current objects that this function updates
* m_kdata->m_logtemp
* m_kdata->m_rfn
* m_rates.
* updateKc();
*/
void _update_rates_T(); void _update_rates_T();
void _update_rates_phi(); void _update_rates_phi();
void _update_rates_C(); void _update_rates_C();
@ -445,12 +471,50 @@ namespace Cantera {
void setIOFlag(int ioFlag); void setIOFlag(int ioFlag);
void checkPartialEquil(); void checkPartialEquil();
int reactionNumber() const { return m_ii;}
void addElementaryReaction(const ReactionData& r);
void addGlobalReaction(const ReactionData& r);
void installReagents(const ReactionData& r);
void updateKc();
//! Write values into m_index
/*!
* @param rxnNumber reaction number
* @param type reaction type
* @param loc location ??
*/
void registerReaction(int rxnNumber, int type, int loc) {
m_index[rxnNumber] = std::pair<int, int>(type, loc);
}
//! Apply corrections for interfacial charge transfer reactions
/*!
* For reactions that transfer charge across a potential difference,
* the activation energies are modified by the potential difference.
* (see, for example, ...). This method applies this correction.
*
* @param kf Vector of forward reaction rate constants on which to have
* the correction applied
*/
void applyButlerVolmerCorrection(doublereal* const kf);
//! When an electrode reaction rate is optionally specified in terms of its
//! exchange current density, extra vectors need to be precalculated
/*!
*
*/
void applyExchangeCurrentDensityFormulation(doublereal* const kfwd);
protected:
//! Temporary work vector of length m_kk //! Temporary work vector of length m_kk
vector_fp m_grt; vector_fp m_grt;
protected:
//! m_kk is the number of species in all of the phases //! m_kk is the number of species in all of the phases
//! that participate in this kinetics mechanism. //! that participate in this kinetics mechanism.
int m_kk; int m_kk;
@ -489,7 +553,7 @@ namespace Cantera {
* production rates and also handles turning thermo * production rates and also handles turning thermo
* properties into reaction thermo properties. * properties into reaction thermo properties.
*/ */
ReactionStoichMgr m_rxnstoich; ReactionStoichMgr m_rxnstoich;
//! Number of irreversible reactions in the mechanism //! Number of irreversible reactions in the mechanism
int m_nirrev; int m_nirrev;
@ -607,42 +671,58 @@ namespace Cantera {
ImplicitSurfChem* m_integrator; ImplicitSurfChem* m_integrator;
vector_fp m_beta; vector_fp m_beta;
//! Vector of reaction indexes specifying the id of the current transfer reactions
//! in the mechanism
/*!
* Vector of reaction indecices which involve current transfers. This provides
* an index into the m_beta array.
*
* irxn = m_ctrxn[i]
*/
vector_int m_ctrxn; vector_int m_ctrxn;
int reactionNumber(){ return m_ii;} //! Vector of booleans indicating whether the charge transfer reaction may be
//! described by an exchange current density expression
vector_int m_ctrxn_ecdf;
void addElementaryReaction(const ReactionData& r); vector_fp m_logStandardConc;
void addGlobalReaction(const ReactionData& r); vector_fp m_deltaG0;
void installReagents(const ReactionData& r); vector_fp m_logProdStanConcReac;
void updateKc();
//! Write values into m_index
/*!
* @param rxnNumber reaction number
* @param type reaction type
* @param loc location ??
*/
void registerReaction(int rxnNumber, int type, int loc) {
m_index[rxnNumber] = std::pair<int, int>(type, loc);
}
void applyButlerVolmerCorrection(doublereal* kf);
//! boolean indicating whether mechanism has been finalized //! boolean indicating whether mechanism has been finalized
bool m_finalized; bool m_finalized;
//! Boolean flag indicating whether any reaction in the mechanism
//! has a coverage dependent forward reaction rate
/*!
* If this is true, then the coverage dependence is multiplied into
* the forward reaction rates constant
*/
bool m_has_coverage_dependence; bool m_has_coverage_dependence;
//! Boolean flag indicating whether any reaction in the mechanism //! Boolean flag indicating whether any reaction in the mechanism
//! has a beta electrochemical parameter. //! has a beta electrochemical parameter.
/*! /*!
* If this is true, the the Butler-Volmer correction is applied * If this is true, the Butler-Volmer correction is applied
* to the forward reaction rate for those reactions. * to the forward reaction rate for those reactions.
* *
* fac = exp ( - beta * (delta_phi)) * fac = exp ( - beta * (delta_phi))
*/ */
bool m_has_electrochem_rxns; bool m_has_electrochem_rxns;
//! Boolean flag indicating whether any reaction in the mechanism
//! is described by an exchange current density expression
/*!
* If this is true, the standard state gibbs free energy of the reaction and
* the product of the reactant standard concentrations must be precalculated
* in order to calculate the rate constant.
*/
bool m_has_exchange_current_density_formulation;
int m_ioFlag; int m_ioFlag;
private: private:

View file

@ -29,9 +29,16 @@ using namespace std;
namespace Cantera { namespace Cantera {
Kinetics::Kinetics() : m_ii(0), m_thermo(0), Kinetics::Kinetics() :
m_index(-1), m_surfphase(-1), m_rxnphase(-1), m_ii(0),
m_mindim(4) {} m_nTotalSpecies(0),
m_thermo(0),
m_index(-1),
m_surfphase(-1),
m_rxnphase(-1),
m_mindim(4)
{
}
Kinetics::~Kinetics(){} Kinetics::~Kinetics(){}
@ -42,7 +49,8 @@ namespace Cantera {
* throw an exception. * throw an exception.
*/ */
Kinetics::Kinetics(const Kinetics &right) : Kinetics::Kinetics(const Kinetics &right) :
m_ii(0), m_ii(0),
m_nTotalSpecies(0),
m_thermo(0), m_thermo(0),
m_index(-1), m_index(-1),
m_surfphase(-1), m_surfphase(-1),
@ -70,6 +78,7 @@ namespace Cantera {
if (this == &right) return *this; if (this == &right) return *this;
m_ii = right.m_ii; m_ii = right.m_ii;
m_nTotalSpecies = right.m_nTotalSpecies;
m_perturb = right.m_perturb; m_perturb = right.m_perturb;
m_reactants = right.m_reactants; m_reactants = right.m_reactants;
m_products = right.m_products; m_products = right.m_products;
@ -285,6 +294,15 @@ namespace Cantera {
m_phaseindex[m_thermo.back()->id()] = nPhases(); m_phaseindex[m_thermo.back()->id()] = nPhases();
} }
void Kinetics::finalize() {
m_nTotalSpecies = 0;
int np = nPhases();
for (int n = 0; n < np; n++) {
int nsp = m_thermo[n]->nSpecies();
m_nTotalSpecies += nsp;
}
}
//! Private function of the class Kinetics, indicating that a function //! Private function of the class Kinetics, indicating that a function
//! inherited from the base class hasn't had a definition assigned to it //! inherited from the base class hasn't had a definition assigned to it

View file

@ -811,7 +811,7 @@ namespace Cantera {
* any initialization (allocating arrays, etc.) that must be * any initialization (allocating arrays, etc.) that must be
* done after the reactions are entered. * done after the reactions are entered.
*/ */
virtual void finalize() {} virtual void finalize();
/** /**
* Add a single reaction to the mechanism. This routine * Add a single reaction to the mechanism. This routine
@ -904,6 +904,9 @@ namespace Cantera {
//! Number of reactions in the mechanism //! Number of reactions in the mechanism
int m_ii; int m_ii;
//! Number of species in the species vector for this kinetics operator
int m_nTotalSpecies;
/// Vector of perturbation factors for each reaction's rate of /// Vector of perturbation factors for each reaction's rate of
/// progress vector. It is initialized to one. /// progress vector. It is initialized to one.

View file

@ -25,7 +25,7 @@ namespace Cantera {
number = 0; number = 0;
rxn_number = 0; rxn_number = 0;
reversible = true; reversible = true;
rateCoeffType = ARRHENIUS; rateCoeffType = ARRHENIUS_REACTION_RATECOEFF_TYPE;
falloffType = NONE; falloffType = NONE;
error = 0; error = 0;
equation = ""; equation = "";
@ -36,7 +36,12 @@ namespace Cantera {
} }
virtual ~ReactionData(){} virtual ~ReactionData(){}
//! type of the reaction
/*!
* The valid types are listed in the file, reaction_defs.h.
*/
int reactionType; int reactionType;
int number; int number;
int rxn_number; int rxn_number;
vector_int reactants; vector_int reactants;
@ -51,7 +56,14 @@ namespace Cantera {
//! True if the current reaction is reversible. False otherwise //! True if the current reaction is reversible. False otherwise
bool reversible; bool reversible;
//! type of the rate coefficient for the forward rate constant
/*!
* The valid types are listed in the file, reaction_defs.h and they
* all end in RATECOEFF_TYPE
*/
int rateCoeffType; int rateCoeffType;
vector_fp rateCoeffParameters; vector_fp rateCoeffParameters;
vector_fp auxRateCoeffParameters; vector_fp auxRateCoeffParameters;
int falloffType; int falloffType;

View file

@ -214,6 +214,7 @@ namespace Cantera {
* \f[ * \f[
* R_i = R_i * \prod_k C_k^{o_{k,i}} * R_i = R_i * \prod_k C_k^{o_{k,i}}
* \f] * \f]
*
* Here \f$ o_{k,i} \f$ is the reaction order of species k in reaction i. * Here \f$ o_{k,i} \f$ is the reaction order of species k in reaction i.
*/ */
virtual void multiplyReactants(const doublereal* C, doublereal* R); virtual void multiplyReactants(const doublereal* C, doublereal* R);

View file

@ -19,93 +19,100 @@
namespace Cantera { namespace Cantera {
/** //! Arrhenius reaction rate type depends only on temperature
* A rate coefficient of the form /**
* \f[ * A reaction rate coefficient of the following form.
* A T^b \exp (-E/RT) *
* \f] * \f[
* k_f = A T^b \exp (-E/RT)
* \f]
*
*/
class Arrhenius {
public:
//! return the rate coefficient type.
static int type() {
return ARRHENIUS_REACTION_RATECOEFF_TYPE;
}
//! Default constructor.
Arrhenius() :
m_logA(-1.0E300),
m_b (0.0),
m_E (0.0),
m_A(0.0) {}
//! Constructor with Arrhenius parameters specified with an array.
Arrhenius(int csize, const doublereal* c) :
m_b (c[1]),
m_E (c[2]),
m_A (c[0])
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
/// Constructor.
/// @param A pre-exponential. The unit system is
/// (kmol, m, s). The actual units depend on the reaction
/// order and the dimensionality (surface or bulk).
/// @param b Temperature exponent. Non-dimensional.
/// @param E Activation energy in temperature units. Kelvin.
Arrhenius(doublereal A, doublereal b, doublereal E) :
m_b (b),
m_E (E),
m_A (A)
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
//! Update concentration-dependent parts of the rate coefficient.
/*!
* For this class, there are no
* concentration-dependent parts, so this method does nothing.
*/ */
class Arrhenius { void update_C(const doublereal* c) {
}
public:
/// return the rate coefficient type. /**
static int type(){ return ARRHENIUS; } * Update the value of the logarithm of the rate constant.
*
/// Default constructor. * Note, this function should never be called for negative A values.
Arrhenius() : * If it does then it will produce a negative overflow result, and
m_logA(-1.0E300), * a zero net forwards reaction rate, instead of a negative reaction
m_b (0.0), * rate constant that is the expected result.
m_E (0.0), */
m_A(0.0) {} doublereal update(doublereal logT, doublereal recipT) const {
return m_logA + m_b*logT - m_E*recipT;
/// Constructor with Arrhenius parameters specified with an array. }
Arrhenius(int csize, const doublereal* c) :
m_b (c[1]),
m_E (c[2]),
m_A (c[0])
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
/// Constructor.
/// @param A pre-exponential. The unit system is
/// (kmol, m, s). The actual units depend on the reaction
/// order and the dimensionality (surface or bulk).
/// @param b Temperature exponent. Non-dimensional.
/// @param E Activation energy in temperature units. Kelvin.
Arrhenius(doublereal A, doublereal b, doublereal E) :
m_b (b),
m_E (E),
m_A (A)
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
/// Update concentration-dependent parts of the rate
/// coefficient. For this class, there are no
/// concentration-dependent parts, so this method does
/// nothing.
void update_C(const doublereal* c) {}
/** /**
* Update the value of the logarithm of the rate constant. * Update the value the rate constant.
* *
* Note, this function should never be called for negative A values. * This function returns the actual value of the rate constant.
* If it does then it will produce a negative overflow result, and * It can be safely called for negative values of the pre-exponential
* a zero net forwards reaction rate, instead of a negative reaction * factor.
* rate constant that is the expected result. */
*/ doublereal updateRC(doublereal logT, doublereal recipT) const {
doublereal update(doublereal logT, doublereal recipT) const { return m_A * exp(m_b*logT - m_E*recipT);
return m_logA + m_b*logT - m_E*recipT; }
}
/**
* Update the value the rate constant.
*
* This function returns the actual value of the rate constant.
* It can be safely called for negative values of the pre-exponential
* factor.
*/
doublereal updateRC(doublereal logT, doublereal recipT) const {
return m_A * exp(m_b*logT - m_E*recipT);
}
void writeUpdateRHS(std::ostream& s) const { void writeUpdateRHS(std::ostream& s) const {
s << " exp(" << m_logA; s << " exp(" << m_logA;
if (m_b != 0.0) s << " + " << m_b << " * tlog"; if (m_b != 0.0) s << " + " << m_b << " * tlog";
if (m_E != 0.0) s << " - " << m_E << " * rt"; if (m_E != 0.0) s << " - " << m_E << " * rt";
s << ");" << std::endl; s << ");" << std::endl;
} }
doublereal activationEnergy_R() const { doublereal activationEnergy_R() const {
return m_E; return m_E;
@ -121,19 +128,22 @@ namespace Cantera {
class ArrheniusSum { class ArrheniusSum {
public: public:
static int type(){ return ARRHENIUS_SUM; } static int type() {
return ARRHENIUS_SUM_REACTION_RATECOEFF_TYPE;
}
ArrheniusSum() : m_nterms(0) {} ArrheniusSum() : m_nterms(0) {}
void addArrheniusTerm(doublereal A, doublereal b, doublereal E) { void addArrheniusTerm(doublereal A, doublereal b, doublereal E) {
if (A > 0.0) { if (A > 0.0) {
m_terms.push_back(Arrhenius(A, b, E)); m_terms.push_back(Arrhenius(A, b, E));
m_sign.push_back(1); m_sign.push_back(1);
} }
else if (A < 0.0) { else if (A < 0.0) {
m_terms.push_back(Arrhenius(-A, b, E)); m_terms.push_back(Arrhenius(-A, b, E));
m_sign.push_back(-1); m_sign.push_back(-1);
} }
m_nterms++; m_nterms++;
} }
void update_C(const doublereal* c) {} void update_C(const doublereal* c) {}
@ -169,38 +179,41 @@ namespace Cantera {
return fsum; return fsum;
} }
void writeUpdateRHS(std::ostream& s) const { void writeUpdateRHS(std::ostream& s) const {
; ;
} }
static bool alwaysComputeRate() { return false;} static bool alwaysComputeRate() { return false;}
protected: protected:
std::vector<Arrhenius> m_terms; std::vector<Arrhenius> m_terms;
vector_int m_sign; vector_int m_sign;
int m_nterms; int m_nterms;
}; };
/** /**
* An Arrhenius rate with coverage-dependent terms. * An Arrhenius rate with coverage-dependent terms.
*/ */
class SurfaceArrhenius { class SurfaceArrhenius {
public: public:
static int type(){ return ARRHENIUS; } static int type() {
SurfaceArrhenius() : return ARRHENIUS_REACTION_RATECOEFF_TYPE;
m_logA(-1.0E300), }
m_b (0.0),
m_E (0.0), SurfaceArrhenius() :
m_A(0.0), m_logA(-1.0E300),
m_acov(0.0), m_b (0.0),
m_ecov(0.0), m_E (0.0),
m_mcov(0.0), m_A(0.0),
m_ncov(0), m_acov(0.0),
m_nmcov(0) m_ecov(0.0),
{ m_mcov(0.0),
} m_ncov(0),
m_nmcov(0)
{
}
SurfaceArrhenius( int csize, const doublereal* c ) : SurfaceArrhenius( int csize, const doublereal* c ) :
m_b (c[1]), m_b (c[1]),
@ -325,7 +338,7 @@ namespace Cantera {
return exp(lres); return exp(lres);
} }
void writeUpdateRHS(std::ostream& s) const {} void writeUpdateRHS(std::ostream& s) const {}
protected: protected:
doublereal delta_s0, delta_e0; doublereal delta_s0, delta_e0;
@ -335,37 +348,143 @@ namespace Cantera {
#endif #endif
}
// class LandauTeller { //! Arrhenius reaction rate type depends only on temperature
/**
* A reaction rate coefficient of the following form.
*
* \f[
* k_f = A T^b \exp (-E/RT)
* \f]
*
*/
class ExchangeCurrent {
// public: public:
// static int type(){ return LANDAUTELLER; }
// LandauTeller(){}
// LandauTeller( const vector_fp& c ) : m_c(c) { m_c[0] = log(c[0]); }
// doublereal update(doublereal logT, doublereal recipT) const { //! return the rate coefficient type.
// return m_c[0] + m_c[1]*tt[1] - m_c[2]*tt[2] static int type() {
// + m_c[3]*tt[3] + m_c[4]*tt[4]; return EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
// } }
// //void writeUpdateRHS(ostream& s) const {
// // s << exp(m_logA);
// // s << " * exp(";
// // if (m_b != 0.0) s << m_b << " * tlog";
// // if (m_E != 0.0) s << " - " << m_E << " * rt";
// // if (m_E != 0.0) s << " - " << m_E << " * rt";
// // s << ");" << endl;
// // }
// //}
// protected: //! Default constructor.
// doublereal m_logA, m_b, m_E; ExchangeCurrent() :
// }; m_logA(-1.0E300),
m_b (0.0),
m_E (0.0),
m_A(0.0) {}
//! Constructor with Arrhenius parameters specified with an array.
ExchangeCurrent(int csize, const doublereal* c) :
m_b (c[1]),
m_E (c[2]),
m_A (c[0])
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
/// Constructor.
/// @param A pre-exponential. The unit system is
/// (kmol, m, s). The actual units depend on the reaction
/// order and the dimensionality (surface or bulk).
/// @param b Temperature exponent. Non-dimensional.
/// @param E Activation energy in temperature units. Kelvin.
ExchangeCurrent(doublereal A, doublereal b, doublereal E) :
m_b (b),
m_E (E),
m_A (A)
{
if (m_A <= 0.0) {
m_logA = -1.0E300;
} else {
m_logA = log(m_A);
}
}
//! Update concentration-dependent parts of the rate coefficient.
/*!
* For this class, there are no
* concentration-dependent parts, so this method does nothing.
*/
void update_C(const doublereal* c) {
}
/**
* Update the value of the logarithm of the rate constant.
*
* Note, this function should never be called for negative A values.
* If it does then it will produce a negative overflow result, and
* a zero net forwards reaction rate, instead of a negative reaction
* rate constant that is the expected result.
*/
doublereal update(doublereal logT, doublereal recipT) const {
return m_logA + m_b*logT - m_E*recipT;
}
/**
* Update the value the rate constant.
*
* This function returns the actual value of the rate constant.
* It can be safely called for negative values of the pre-exponential
* factor.
*/
doublereal updateRC(doublereal logT, doublereal recipT) const {
return m_A * exp(m_b*logT - m_E*recipT);
}
void writeUpdateRHS(std::ostream& s) const {
s << " exp(" << m_logA;
if (m_b != 0.0) s << " + " << m_b << " * tlog";
if (m_E != 0.0) s << " - " << m_E << " * rt";
s << ");" << std::endl;
}
doublereal activationEnergy_R() const {
return m_E;
}
static bool alwaysComputeRate() { return false;}
protected:
doublereal m_logA, m_b, m_E, m_A;
};
// class LandauTeller {
// public:
// static int type(){ return LANDAUTELLER; }
// LandauTeller(){}
// LandauTeller( const vector_fp& c ) : m_c(c) { m_c[0] = log(c[0]); }
// doublereal update(doublereal logT, doublereal recipT) const {
// return m_c[0] + m_c[1]*tt[1] - m_c[2]*tt[2]
// + m_c[3]*tt[3] + m_c[4]*tt[4];
// }
// //void writeUpdateRHS(ostream& s) const {
// // s << exp(m_logA);
// // s << " * exp(";
// // if (m_b != 0.0) s << m_b << " * tlog";
// // if (m_E != 0.0) s << " - " << m_E << " * rt";
// // if (m_E != 0.0) s << " - " << m_E << " * rt";
// // s << ");" << endl;
// // }
// //}
// protected:
// doublereal m_logA, m_b, m_E;
// };
//} //}
}
#endif #endif

View file

@ -521,9 +521,24 @@ namespace Cantera {
* kf should point to a XML element named "rateCoeff". * kf should point to a XML element named "rateCoeff".
* rdata is the partially filled ReactionData object for the reaction. * rdata is the partially filled ReactionData object for the reaction.
* This function will fill in more fields in the ReactionData object. * This function will fill in more fields in the ReactionData object.
*
* @param kf Reference to the XML Node named rateCoeff
*/ */
void getRateCoefficient(const node_t& kf, kinetics_t& kin, void getRateCoefficient(const node_t& kf, kinetics_t& kin,
ReactionData& rdata, int negA) { ReactionData& rdata, int negA) {
string type = kf.attrib("type");
if (type == "") {
type = "Arrhenius";
rdata.rateCoeffType = ARRHENIUS_REACTION_RATECOEFF_TYPE;
}
if (type == "ExchangeCurrentDensity") {
rdata.rateCoeffType = EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
} else if (type == "Arrhenius") {
} else {
throw CanteraError("getRateCoefficient",
"Unknown type: " + type);
}
int nc = kf.nChildren(); int nc = kf.nChildren();
nodeset_t& kf_children = kf.children(); nodeset_t& kf_children = kf.children();
@ -557,6 +572,12 @@ namespace Cantera {
"negative or zero A coefficient for reaction "+int2str(rdata.number)); "negative or zero A coefficient for reaction "+int2str(rdata.number));
} }
} }
else if (nm == "Arrhenius_ExchangeCurrentDensity") {
vector_fp coeff(3);
getArrhenius(c, highlow, coeff[0], coeff[1], coeff[2]);
chigh = coeff;
rdata.rateCoeffType = EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE;
}
else if (nm == "falloff") { else if (nm == "falloff") {
getFalloff(c, rdata); getFalloff(c, rdata);
} }
@ -580,6 +601,9 @@ namespace Cantera {
rdata.auxRateCoeffParameters = clow; rdata.auxRateCoeffParameters = clow;
else if (rdata.reactionType == CHEMACT_RXN) else if (rdata.reactionType == CHEMACT_RXN)
rdata.auxRateCoeffParameters = chigh; rdata.auxRateCoeffParameters = chigh;
} }

View file

@ -81,11 +81,12 @@ namespace Cantera {
*/ */
//@{ //@{
const int ARRHENIUS = 1; const int ARRHENIUS_REACTION_RATECOEFF_TYPE = 1;
const int LANDAUTELLER = 2; const int LANDAUTELLER_REACTION_RATECOEFF_TYPE = 2;
const int TSTRATE = 3; const int TSTRATE_REACTION_RATECOEFF_TYPE = 3;
const int SURF_ARRHENIUS = 4; const int SURF_ARRHENIUS_REACTION_RATECOEFF_TYPE = 4;
const int ARRHENIUS_SUM = 5; const int ARRHENIUS_SUM_REACTION_RATECOEFF_TYPE = 5;
const int EXCHANGE_CURRENT_REACTION_RATECOEFF_TYPE = 6;
//@} //@}

View file

@ -72,7 +72,7 @@ namespace Cantera {
return *this; return *this;
} }
/** /*
* *
* ~GibbsExcessVPSSTP(): (virtual) * ~GibbsExcessVPSSTP(): (virtual)
* *
@ -313,7 +313,6 @@ namespace Cantera {
void GibbsExcessVPSSTP::initThermo() { void GibbsExcessVPSSTP::initThermo() {
initLengths(); initLengths();
VPStandardStateTP::initThermo(); VPStandardStateTP::initThermo();
} }
@ -328,34 +327,12 @@ namespace Cantera {
dlnActCoeffdlnN_Scaled_.resize(m_kk); dlnActCoeffdlnN_Scaled_.resize(m_kk);
m_pp.resize(m_kk); m_pp.resize(m_kk);
} }
/*
* initThermoXML() (virtual from ThermoPhase)
* 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 GibbsExcessVPSSTP::initThermoXML(XML_Node& phaseNode, std::string id) {
VPStandardStateTP::initThermoXML(phaseNode, id);
}
/** /*
* Format a summary of the mixture state for output. * Format a summary of the mixture state for output.
*/ */
std::string GibbsExcessVPSSTP::report(bool show_thermo) const { std::string GibbsExcessVPSSTP::report(bool show_thermo) const {
char p[800]; char p[800];
string s = ""; string s = "";
try { try {

View file

@ -71,13 +71,14 @@ namespace Cantera {
* \f$k\f$. * \f$k\f$.
* *
* GibbsExcessVPSSTP contains an internal vector with the current mole * GibbsExcessVPSSTP contains an internal vector with the current mole
* fraction vector. That's one of its primary usages. * 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> * <H3> SetState Strategy </H3>
* *
* The gibbsExcessVPSSTP object does not have a setState strategy. * All setState functions that set the internal state of the ThermoPhase object are
* It's strictly an interfacial layer that writes the current mole fractions to the * overloaded at this level, so that a current mole fraction vector is maintained within
* State object. * the object.
* *
* *
*/ */
@ -172,6 +173,7 @@ namespace Cantera {
virtual void setPressure(doublereal p); virtual void setPressure(doublereal p);
protected: protected:
/** /**
* Calculate the density of the mixture using the partial * Calculate the density of the mixture using the partial
* molar volumes and mole fractions as input * molar volumes and mole fractions as input
@ -531,24 +533,6 @@ namespace Cantera {
* @see importCTML.cpp * @see importCTML.cpp
*/ */
virtual void initThermo(); 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);
//! returns a summary of the state of the phase as a string //! returns a summary of the state of the phase as a string
/*! /*!
@ -560,14 +544,10 @@ namespace Cantera {
private: private:
//! Initialize lengths of local variables after all species have //! Initialize lengths of local variables after all species have
//! been identified. //! been identified.
void initLengths(); void initLengths();
private:
//! Error function //! Error function
/*! /*!
* Print an error string and exit * Print an error string and exit
@ -587,6 +567,13 @@ namespace Cantera {
protected: protected:
//! Storage for the current values of the mole fractions of the species //! 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_; mutable std::vector<doublereal> moleFractions_;
//! Storage for the current values of the activity coefficients of the //! Storage for the current values of the activity coefficients of the

165
configure vendored
View file

@ -9740,6 +9740,154 @@ if test "$BUILD_WITH_F2C"="n"; then
fi fi
#
# Check to see if we have a -lm line
#
echo "$as_me:$LINENO: checking for printf in -lm" >&5
echo $ECHO_N "checking for printf in -lm... $ECHO_C" >&6
if test "${ac_cv_lib_m_printf+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lm $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char printf ();
int
main ()
{
printf ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_cxx_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_m_printf=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_m_printf=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_m_printf" >&5
echo "${ECHO_T}$ac_cv_lib_m_printf" >&6
if test $ac_cv_lib_m_printf = yes; then
add_stm=1
else
add_stm=0
fi
#
# Check to see if we have a -lstdc++ line
#
echo "$as_me:$LINENO: checking for printf in -lstdc++" >&5
echo $ECHO_N "checking for printf in -lstdc++... $ECHO_C" >&6
if test "${ac_cv_lib_stdcpp_printf+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lstdc++ $LIBS"
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char printf ();
int
main ()
{
printf ();
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_cxx_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_lib_stdcpp_printf=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_cv_lib_stdcpp_printf=no
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
echo "$as_me:$LINENO: result: $ac_cv_lib_stdcpp_printf" >&5
echo "${ECHO_T}$ac_cv_lib_stdcpp_printf" >&6
if test $ac_cv_lib_stdcpp_printf = yes; then
add_stdc=1
else
add_stdc=0
fi
# #
# Ending Libs for compiling static applications and # Ending Libs for compiling static applications and
# dynamically loaded libraries # dynamically loaded libraries
@ -9755,6 +9903,17 @@ case $ac_sys_system in
LCXX_END_LIBS="$LCXX_END_LIBS"" -lCrun -lCstd -lfsu" ;; LCXX_END_LIBS="$LCXX_END_LIBS"" -lCrun -lCstd -lfsu" ;;
esac ;; esac ;;
esac esac
if test $add_stm = 1 ; then
echo 'Adding -lm to the end of the LCXX_END_LIBS variable'
LCXX_END_LIBS="$LCXX_END_LIBS"" -lm"
echo 'LCXX_END_LIBS = ' $LCXX_END_LIBS
fi
if test $add_stdc = 1 ; then
echo 'Adding -lstdc++ to the end of the LCXX_END_LIBS variable'
LCXX_END_LIBS="$LCXX_END_LIBS"" -lstdc++ "
echo 'LCXX_END_LIBS = ' $LCXX_END_LIBS
fi
@ -9888,7 +10047,7 @@ fi
# Provide some information about the compiler. # Provide some information about the compiler.
echo "$as_me:9891:" \ echo "$as_me:10050:" \
"checking for Fortran 77 compiler version" >&5 "checking for Fortran 77 compiler version" >&5
ac_compiler=`set X $ac_compile; echo $2` ac_compiler=`set X $ac_compile; echo $2`
{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@ -10095,7 +10254,7 @@ _ACEOF
# flags. # flags.
ac_save_FFLAGS=$FFLAGS ac_save_FFLAGS=$FFLAGS
FFLAGS="$FFLAGS $ac_verb" FFLAGS="$FFLAGS $ac_verb"
(eval echo $as_me:10098: \"$ac_link\") >&5 (eval echo $as_me:10257: \"$ac_link\") >&5
ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'` ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'`
echo "$ac_f77_v_output" >&5 echo "$ac_f77_v_output" >&5
FFLAGS=$ac_save_FFLAGS FFLAGS=$ac_save_FFLAGS
@ -10173,7 +10332,7 @@ _ACEOF
# flags. # flags.
ac_save_FFLAGS=$FFLAGS ac_save_FFLAGS=$FFLAGS
FFLAGS="$FFLAGS $ac_cv_prog_f77_v" FFLAGS="$FFLAGS $ac_cv_prog_f77_v"
(eval echo $as_me:10176: \"$ac_link\") >&5 (eval echo $as_me:10335: \"$ac_link\") >&5
ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'` ac_f77_v_output=`eval $ac_link 5>&1 2>&1 | grep -v 'Driving:'`
echo "$ac_f77_v_output" >&5 echo "$ac_f77_v_output" >&5
FFLAGS=$ac_save_FFLAGS FFLAGS=$ac_save_FFLAGS

View file

@ -1463,6 +1463,16 @@ if test "$BUILD_WITH_F2C"="n"; then
fi fi
AC_SUBST(LCXX_FLAGS) AC_SUBST(LCXX_FLAGS)
#
# Check to see if we have a -lm line
#
AC_CHECK_LIB(m, printf, [add_stm=1], [add_stm=0], [ ])
#
# Check to see if we have a -lstdc++ line
#
AC_CHECK_LIB(stdc++, printf, [add_stdc=1], [add_stdc=0], [])
# #
# Ending Libs for compiling static applications and # Ending Libs for compiling static applications and
# dynamically loaded libraries # dynamically loaded libraries
@ -1478,6 +1488,17 @@ case $ac_sys_system in
LCXX_END_LIBS="$LCXX_END_LIBS"" -lCrun -lCstd -lfsu" ;; LCXX_END_LIBS="$LCXX_END_LIBS"" -lCrun -lCstd -lfsu" ;;
esac ;; esac ;;
esac esac
if test $add_stm = 1 ; then
echo 'Adding -lm to the end of the LCXX_END_LIBS variable'
LCXX_END_LIBS="$LCXX_END_LIBS"" -lm"
echo 'LCXX_END_LIBS = ' $LCXX_END_LIBS
fi
if test $add_stdc = 1 ; then
echo 'Adding -lstdc++ to the end of the LCXX_END_LIBS variable'
LCXX_END_LIBS="$LCXX_END_LIBS"" -lstdc++ "
echo 'LCXX_END_LIBS = ' $LCXX_END_LIBS
fi
AC_SUBST(LCXX_END_LIBS) AC_SUBST(LCXX_END_LIBS)

View file

@ -1849,7 +1849,7 @@ LiO J 3/64LI 1.O 1. 0. 0.G 300.000 5000.000 22.94040 1
LiO- J12/67LI 1.O 1.E 1. 0.G 300.000 5000.000 22.94095 1 LiO- J12/67LI 1.O 1.E 1. 0.G 300.000 5000.000 22.94095 1
4.18102170E+00 4.17850000E-04-1.50248450E-07 2.83977320E-11-1.97891810E-15 2 4.18102170E+00 4.17850000E-04-1.50248450E-07 2.83977320E-11-1.97891810E-15 2
-9.38497020E+03-1.42392337E-01 2.85158660E+00 5.01698800E-03-5.95474750E-06 3 -9.38497020E+03-1.42392337E-01 2.85158660E+00 5.01698800E-03-5.95474750E-06 3
3.03994510E-09-4.78729690E-13-9.07780760E+03 6.45947067E+00-8.05144594E+03 4 03994510E-09-4.78729690E-13-9.07780760E+03 6.45947067E+00-8.05144594E+03 4
LiOH J 6/71LI 1.O 1.H 1. 0.G 300.000 5000.000 23.94834 1 LiOH J 6/71LI 1.O 1.H 1. 0.G 300.000 5000.000 23.94834 1
5.50969570E+00 1.36854640E-03-3.94414690E-07 5.23321950E-11-2.59586760E-15 2 5.50969570E+00 1.36854640E-03-3.94414690E-07 5.23321950E-11-2.59586760E-15 2
-2.98992310E+04-6.50701600E+00 3.34623000E+00 1.17872530E-02-1.82526570E-05 3 -2.98992310E+04-6.50701600E+00 3.34623000E+00 1.17872530E-02-1.82526570E-05 3
@ -4558,4 +4558,4 @@ ZrO2(L) J12/65ZR 1.O 2. 0. 0.C 2950.000 5000.000 123.22280 1
1.05676750E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 1.05676750E+01 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2
-1.28427450E+05-5.45922640E+01 1.05676750E+01 0.00000000E+00 0.00000000E+00 3 -1.28427450E+05-5.45922640E+01 1.05676750E+01 0.00000000E+00 0.00000000E+00 3
0.00000000E+00 0.00000000E+00-1.28427450E+05-5.45922640E+01 0.00000000E+00 4 0.00000000E+00 0.00000000E+00-1.28427450E+05-5.45922640E+01 0.00000000E+00 4
END END

View file

@ -1,8 +1,12 @@
/** /**
* @file example2.cpp * @file cti2ctml.cpp
* *
*/ */
/*
* $Id$
*/
// Example // Example
// //
// Read a mechanism and a thermodynamics file for the // Read a mechanism and a thermodynamics file for the
@ -21,9 +25,6 @@
using namespace Cantera; using namespace Cantera;
using namespace std; using namespace std;
#ifdef DEBUG_HKM
int iDebug_HKM = 0;
#endif
/*****************************************************************/ /*****************************************************************/
/*****************************************************************/ /*****************************************************************/
@ -38,14 +39,14 @@ static void printUsage()
/*****************************************************************/
int main(int argc, char** argv) { int main(int argc, char** argv) {
string infile; std::string infile;
// look for command-line options // look for command-line options
if (argc > 1) { if (argc > 1) {
string tok; std::string tok;
for (int j = 1; j < argc; j++) { for (int j = 1; j < argc; j++) {
tok = string(argv[j]); tok = string(argv[j]);
if (tok[0] == '-') { if (tok[0] == '-') {
@ -75,7 +76,7 @@ int main(int argc, char** argv) {
try { try {
XML_Node *xc = new XML_Node(); XML_Node *xc = new XML_Node();
string path = findInputFile(infile); std::string path = findInputFile(infile);
ctml::get_CTML_Tree(xc, path, 0); ctml::get_CTML_Tree(xc, path, 0);
//XML_Node *xd = new XML_Node(); //XML_Node *xd = new XML_Node();
//xc->copy(xd); //xc->copy(xd);