moved files to kinetics subdirectory
This commit is contained in:
parent
9581e8db9a
commit
0762b467c2
35 changed files with 11909 additions and 0 deletions
532
Cantera/src/kinetics/EdgeKinetics.cpp
Normal file
532
Cantera/src/kinetics/EdgeKinetics.cpp
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
/**
|
||||
* @file EdgeKinetics.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2002 California Institute of Technology
|
||||
|
||||
|
||||
// turn off warnings under Windows
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "EdgeKinetics.h"
|
||||
#include "SurfPhase.h"
|
||||
|
||||
#include "ReactionData.h"
|
||||
//#include "StoichManager.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Construct an empty EdgeKinetics reaction mechanism.
|
||||
*/
|
||||
EdgeKinetics::
|
||||
EdgeKinetics() :
|
||||
Kinetics(),
|
||||
m_kk(0),
|
||||
m_redo_rates(false),
|
||||
m_nirrev(0),
|
||||
m_nrev(0),
|
||||
m_finalized(false),
|
||||
m_has_electrochem_rxns(false)
|
||||
{
|
||||
m_kdata = new EdgeKineticsData;
|
||||
m_kdata->m_temp = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
EdgeKinetics::
|
||||
~EdgeKinetics(){
|
||||
delete m_kdata;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update properties that depend on temperature
|
||||
*
|
||||
*/
|
||||
void EdgeKinetics::
|
||||
_update_rates_T() {
|
||||
_update_rates_phi();
|
||||
doublereal T = thermo(surfacePhaseIndex()).temperature();
|
||||
if (T != m_kdata->m_temp || m_redo_rates) {
|
||||
m_kdata->m_logtemp = log(T);
|
||||
m_rates.update(T, m_kdata->m_logtemp, DATA_PTR(m_kdata->m_rfn));
|
||||
if (m_has_electrochem_rxns)
|
||||
applyButlerVolmerCorrection(DATA_PTR(m_kdata->m_rfn));
|
||||
m_kdata->m_temp = T;
|
||||
updateKc();
|
||||
m_kdata->m_ROP_ok = false;
|
||||
m_redo_rates = false;
|
||||
}
|
||||
}
|
||||
|
||||
void EdgeKinetics::
|
||||
_update_rates_phi() {
|
||||
int np = nPhases();
|
||||
for (int n = 0; n < np; n++) {
|
||||
if (thermo(n).electricPotential() != m_phi[n]) {
|
||||
m_phi[n] = thermo(n).electricPotential();
|
||||
m_redo_rates = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update properties that depend on concentrations. This method
|
||||
* fills out the array of generalized concentrations by calling
|
||||
* method getActivityConcentrations for each phase, which classes
|
||||
* representing phases should overload to return the appropriate
|
||||
* quantities.
|
||||
*/
|
||||
void EdgeKinetics::
|
||||
_update_rates_C() {
|
||||
int n;
|
||||
|
||||
//m_rates.update(m_kdata->m_temp,
|
||||
// m_kdata->m_logtemp, m_kdata->m_rfn.begin());
|
||||
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getActivityConcentrations(DATA_PTR(m_conc) + m_start[n]);
|
||||
}
|
||||
m_kdata->m_ROP_ok = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the equilibrium constants in molar units for all
|
||||
* reversible reactions. Irreversible reactions have their
|
||||
* equilibrium constant set to zero.
|
||||
*/
|
||||
void EdgeKinetics::updateKc() {
|
||||
int i, irxn;
|
||||
vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
fill(m_rkc.begin(), m_rkc.end(), 0.0);
|
||||
|
||||
if (m_nrev > 0) {
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getStandardChemPotentials(DATA_PTR(m_mu0) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute Delta mu^0 for all reversible reactions
|
||||
m_reactantStoich.decrementReactions(DATA_PTR(m_mu0),
|
||||
DATA_PTR(m_rkc));
|
||||
m_revProductStoich.incrementReactions(DATA_PTR(m_mu0),
|
||||
DATA_PTR(m_rkc));
|
||||
|
||||
for (i = 0; i < m_nrev; i++) {
|
||||
irxn = m_revindex[i];
|
||||
m_rkc[irxn] = exp(m_rkc[irxn]*rrt);
|
||||
}
|
||||
for (i = 0; i != m_nirrev; ++i) {
|
||||
m_rkc[ m_irrev[i] ] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EdgeKinetics::checkPartialEquil() {
|
||||
int i, irxn;
|
||||
vector_fp dmu(nTotalSpecies(), 0.0);
|
||||
vector_fp rmu(nReactions(), 0.0);
|
||||
if (m_nrev > 0) {
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getChemPotentials(DATA_PTR(dmu) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
dmu[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
cout << thermo(n).speciesName(k) << " " << dmu[ik] << endl;
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute Delta mu^ for all reversible reactions
|
||||
m_reactantStoich.decrementReactions(DATA_PTR(dmu), DATA_PTR(rmu));
|
||||
m_revProductStoich.incrementReactions(DATA_PTR(dmu), DATA_PTR(rmu));
|
||||
|
||||
for (i = 0; i < m_nrev; i++) {
|
||||
irxn = m_revindex[i];
|
||||
cout << "Reaction " << irxn << " " << exp(rmu[irxn]*rrt) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the equilibrium constants of all reactions, whether
|
||||
* reversible or not.
|
||||
*/
|
||||
void EdgeKinetics::getEquilibriumConstants(doublereal* kc) {
|
||||
int i;
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getStandardChemPotentials(DATA_PTR(m_mu0) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
fill(kc, kc + m_ii, 0.0);
|
||||
|
||||
m_reactantStoich.decrementReactions(DATA_PTR(m_mu0), kc);
|
||||
m_revProductStoich.incrementReactions(DATA_PTR(m_mu0), kc);
|
||||
m_irrevProductStoich.incrementReactions(DATA_PTR(m_mu0), kc);
|
||||
|
||||
for (i = 0; i < m_ii; i++) {
|
||||
kc[i] = exp(-kc[i]*rrt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* For reactions that transfer charge across a potential difference,
|
||||
* the activation energies are modified by the potential difference.
|
||||
* (see, for example, Baird and Falkner, "Electrochemical Methods").
|
||||
* This method applies this correction.
|
||||
*/
|
||||
void EdgeKinetics::applyButlerVolmerCorrection(doublereal* kf) {
|
||||
int i;
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
|
||||
// compute the electrical potential energy of each species
|
||||
for (n = 0; n < np; n++) {
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_pot[ik] = Faraday*thermo(n).charge(k)*m_phi[n];
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute the change in electrical potential energy for each
|
||||
// reaction. This will only be non-zero if a potential
|
||||
// difference is present.
|
||||
fill(DATA_PTR(m_rwork), DATA_PTR(m_rwork) + m_ii, 0.0);
|
||||
m_reactantStoich.decrementReactions(DATA_PTR(m_pot), DATA_PTR(m_rwork));
|
||||
m_revProductStoich.incrementReactions(DATA_PTR(m_pot), DATA_PTR(m_rwork));
|
||||
m_irrevProductStoich.incrementReactions(DATA_PTR(m_pot), DATA_PTR(m_rwork));
|
||||
|
||||
// modify the reaction rates. Only modify those with a
|
||||
// non-zero activation energy, and do not decrease the
|
||||
// activation energy below zero.
|
||||
doublereal ea, eamod;
|
||||
|
||||
int nct = m_beta.size();
|
||||
int irxn;
|
||||
for (i = 0; i < nct; i++) {
|
||||
irxn = m_ctrxn[i];
|
||||
eamod = m_beta[i]*m_rwork[irxn];
|
||||
//cout << "i, beta = " << i << " " << m_beta[i] << endl;
|
||||
if (eamod != 0.0 && m_E[i] != 0.0) {
|
||||
ea = GasConstant * m_E[i];
|
||||
if (eamod + ea < 0.0) {
|
||||
writelog("Warning: act energy mod too large");
|
||||
eamod = -ea;
|
||||
}
|
||||
kf[irxn] *= exp(-eamod*rrt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the rates of progress of the reactions in the reaciton
|
||||
* mechanism. This routine operates on internal data.
|
||||
*/
|
||||
void EdgeKinetics::updateROP() {
|
||||
|
||||
_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
if (m_kdata->m_ROP_ok) return;
|
||||
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
const vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
array_fp& ropr = m_kdata->m_ropr;
|
||||
array_fp& ropnet = m_kdata->m_ropnet;
|
||||
|
||||
// copy rate coefficients into ropf
|
||||
copy(rf.begin(), rf.end(), ropf.begin());
|
||||
|
||||
// multiply by perturbation factor
|
||||
multiply_each(ropf.begin(), ropf.end(), m_perturb.begin());
|
||||
|
||||
// copy the forward rates to the reverse rates
|
||||
copy(ropf.begin(), ropf.end(), ropr.begin());
|
||||
|
||||
// for reverse rates computed from thermochemistry, multiply
|
||||
// the forward rates copied into m_ropr by the reciprocals of
|
||||
// the equilibrium constants
|
||||
multiply_each(ropr.begin(), ropr.end(), m_rkc.begin());
|
||||
|
||||
// multiply ropf by concentration products
|
||||
m_reactantStoich.multiply(DATA_PTR(m_conc), DATA_PTR(ropf));
|
||||
|
||||
// for reversible reactions, multiply ropr by concentration
|
||||
// products
|
||||
m_revProductStoich.multiply(DATA_PTR(m_conc), DATA_PTR(ropr));
|
||||
|
||||
// do global reactions
|
||||
//m_globalReactantStoich.power(DATA_PTR(m_conc), ropf.begin());
|
||||
|
||||
for (int j = 0; j != m_ii; ++j) {
|
||||
ropnet[j] = ropf[j] - ropr[j];
|
||||
}
|
||||
|
||||
m_kdata->m_ROP_ok = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a single reaction to the mechanism. This routine
|
||||
* must be called after init() and before finalize().
|
||||
* This function branches on the types of reactions allowed
|
||||
* by the interfaceKinetics manager in order to install
|
||||
* the reaction correctly in the manager.
|
||||
* The manager allows the following reaction types
|
||||
* Elementary
|
||||
* Surface
|
||||
* Global
|
||||
* There is no difference between elementary and surface
|
||||
* reactions.
|
||||
*/
|
||||
void EdgeKinetics::
|
||||
addReaction(const ReactionData& r) {
|
||||
|
||||
int nr = r.reactants.size();
|
||||
|
||||
// a global reaction is idnetified as one with
|
||||
// a reactant stoichiometric coefficient not equal
|
||||
// to the molecularity for some reactant
|
||||
bool isglobal = false;
|
||||
for (int n = 0; n < nr; n++) {
|
||||
if (r.rstoich[n] != int(r.order[n])) {
|
||||
isglobal = true; break;
|
||||
}
|
||||
}
|
||||
if (isglobal)
|
||||
addGlobalReaction(r);
|
||||
else
|
||||
addElementaryReaction(r);
|
||||
|
||||
installReagents( r );
|
||||
installGroups(reactionNumber(), r.rgroups, r.pgroups);
|
||||
incrementRxnCount();
|
||||
m_rxneqn.push_back(r.equation);
|
||||
}
|
||||
|
||||
|
||||
void EdgeKinetics::
|
||||
addElementaryReaction(const ReactionData& r) {
|
||||
int iloc;
|
||||
|
||||
// install rate coeff calculator
|
||||
vector_fp rp = r.rateCoeffParameters;
|
||||
|
||||
// coverage dependence
|
||||
int ncov = r.cov.size();
|
||||
for (int m = 0; m < ncov; m++) rp.push_back(r.cov[m]);
|
||||
|
||||
iloc = m_rates.install( reactionNumber(), r.rateCoeffType, rp.size(),
|
||||
DATA_PTR(rp) );
|
||||
|
||||
// store activation energy
|
||||
if (r.beta > 0.0) {
|
||||
m_has_electrochem_rxns = true;
|
||||
m_E.push_back(r.rateCoeffParameters[2]);
|
||||
m_beta.push_back(r.beta);
|
||||
m_ctrxn.push_back(reactionNumber());
|
||||
}
|
||||
|
||||
// add constant term to rate coeff value vector
|
||||
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
|
||||
registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
void EdgeKinetics::
|
||||
addGlobalReaction(const ReactionData& r) {
|
||||
|
||||
int iloc;
|
||||
// install rate coeff calculator
|
||||
vector_fp rp = r.rateCoeffParameters;
|
||||
int ncov = r.cov.size();
|
||||
for (int m = 0; m < ncov; m++) rp.push_back(r.cov[m]);
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, rp.size(),
|
||||
DATA_PTR(rp) );
|
||||
|
||||
// add constant term to rate coeff value vector
|
||||
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
|
||||
int nr = r.order.size();
|
||||
vector_fp ordr(nr);
|
||||
for (int n = 0; n < nr; n++) {
|
||||
ordr[n] = r.order[n] - r.rstoich[n];
|
||||
}
|
||||
m_globalReactantStoich.add( reactionNumber(),
|
||||
r.reactants, ordr);
|
||||
|
||||
registerReaction( reactionNumber(), GLOBAL_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
void EdgeKinetics::installReagents(const ReactionData& r) {
|
||||
|
||||
m_kdata->m_ropf.push_back(0.0); // extend by one for new rxn
|
||||
m_kdata->m_ropr.push_back(0.0);
|
||||
m_kdata->m_ropnet.push_back(0.0);
|
||||
int n, ns, m;
|
||||
doublereal nsFlt;
|
||||
int rnum = reactionNumber();
|
||||
|
||||
vector_int rk;
|
||||
int nr = r.reactants.size();
|
||||
for (n = 0; n < nr; n++) {
|
||||
nsFlt = r.rstoich[n];
|
||||
ns = (int) nsFlt;
|
||||
if ((doublereal) ns != nsFlt) {
|
||||
if (ns < 1) ns = 1;
|
||||
}
|
||||
m_rrxn[r.reactants[n]][rnum] = ns;
|
||||
for (m = 0; m < ns; m++) {
|
||||
rk.push_back(r.reactants[n]);
|
||||
}
|
||||
}
|
||||
m_reactants.push_back(rk);
|
||||
|
||||
vector_int pk;
|
||||
int np = r.products.size();
|
||||
for (n = 0; n < np; n++) {
|
||||
nsFlt = r.pstoich[n];
|
||||
ns = (int) nsFlt;
|
||||
if ((doublereal) ns != nsFlt) {
|
||||
if (ns < 1) ns = 1;
|
||||
}
|
||||
m_prxn[r.products[n]][rnum] = ns;
|
||||
for (m = 0; m < ns; m++) {
|
||||
pk.push_back(r.products[n]);
|
||||
}
|
||||
}
|
||||
m_products.push_back(pk);
|
||||
|
||||
m_kdata->m_rkcn.push_back(0.0);
|
||||
|
||||
m_reactantStoich.add( reactionNumber(), rk);
|
||||
|
||||
if (r.reversible) {
|
||||
m_revProductStoich.add(reactionNumber(), pk);
|
||||
//m_dn.push_back(pk.size() - rk.size());
|
||||
m_revindex.push_back(reactionNumber());
|
||||
m_nrev++;
|
||||
}
|
||||
else {
|
||||
m_irrevProductStoich.add(reactionNumber(), pk);
|
||||
//m_dn.push_back(pk.size() - rk.size());
|
||||
m_irrev.push_back( reactionNumber() );
|
||||
m_nirrev++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EdgeKinetics::installGroups(int irxn,
|
||||
const vector<grouplist_t>& r, const vector<grouplist_t>& p) {
|
||||
if (!r.empty()) {
|
||||
m_rgroups[reactionNumber()] = r;
|
||||
m_pgroups[reactionNumber()] = p;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the class for the addition of reactions. This function
|
||||
* must be called after instantiation of the class, but before
|
||||
* any reactions are actually added to the mechanism.
|
||||
* This function calculates m_kk the number of species in all
|
||||
* phases participating in the reaction mechanism. We don't know
|
||||
* m_kk previously, before all phases have been added.
|
||||
*/
|
||||
void EdgeKinetics::init() {
|
||||
int n;
|
||||
m_kk = 0;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
m_kk += thermo(n).nSpecies();
|
||||
}
|
||||
m_rrxn.resize(m_kk);
|
||||
m_prxn.resize(m_kk);
|
||||
m_conc.resize(m_kk);
|
||||
m_mu0.resize(m_kk);
|
||||
m_pot.resize(m_kk, 0.0);
|
||||
m_phi.resize(np, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish adding reactions and prepare for use. This function
|
||||
* must be called after all reactions are entered into the mechanism
|
||||
* and before the mechanism is used to calculate reaction rates.
|
||||
*
|
||||
* Here, we resize work arrays based on the number of reactions,
|
||||
* since we don't know this number up to now.
|
||||
*/
|
||||
void EdgeKinetics::finalize() {
|
||||
m_rwork.resize(nReactions());
|
||||
m_finalized = true;
|
||||
}
|
||||
|
||||
|
||||
bool EdgeKinetics::ready() const {
|
||||
return (m_finalized);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
392
Cantera/src/kinetics/EdgeKinetics.h
Normal file
392
Cantera/src/kinetics/EdgeKinetics.h
Normal file
|
|
@ -0,0 +1,392 @@
|
|||
/**
|
||||
* @file EdgeKinetics.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_EDGEKINETICS_H
|
||||
#define CT_EDGEKINETICS_H
|
||||
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mix_defs.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
#include "utilities.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
#include "StoichManager.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
// forward references
|
||||
|
||||
class ReactionData;
|
||||
class EdgeKineticsData;
|
||||
class ThermoPhase;
|
||||
class SurfPhase;
|
||||
class ImplicitSurfChem;
|
||||
|
||||
/**
|
||||
* Holds mechanism-specific data.
|
||||
*/
|
||||
class EdgeKineticsData {
|
||||
public:
|
||||
EdgeKineticsData() :
|
||||
m_ROP_ok(false),
|
||||
m_temp(0.0), m_logtemp(0.0)
|
||||
{}
|
||||
virtual ~EdgeKineticsData(){}
|
||||
|
||||
doublereal m_logp0, m_logc0;
|
||||
array_fp m_ropf, m_ropr, m_ropnet;
|
||||
//array_fp m_rfn_low, m_rfn_high;
|
||||
bool m_ROP_ok;
|
||||
|
||||
doublereal m_temp, m_logtemp;
|
||||
vector_fp m_rfn;
|
||||
vector_fp m_rkcn;
|
||||
};
|
||||
|
||||
|
||||
class EdgeKinetics : public Kinetics {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
*/
|
||||
EdgeKinetics();
|
||||
|
||||
/// Destructor.
|
||||
virtual ~EdgeKinetics();
|
||||
|
||||
/**
|
||||
* Identifies the subclass of the Kinetics manager type.
|
||||
* These are listed in mix_defs.h.
|
||||
*/
|
||||
virtual int ID() { return cEdgeKinetics; }
|
||||
|
||||
/**
|
||||
* Identifies the subclass of the Kinetics manager type.
|
||||
* These are listed in mix_defs.h.
|
||||
*/
|
||||
virtual int type() { return cEdgeKinetics; }
|
||||
|
||||
/**
|
||||
* Set the electric potential in the nth phase
|
||||
*
|
||||
* @param n phase Index in this kinetics object.
|
||||
* @param V Electric potential (volts)
|
||||
*/
|
||||
void setElectricPotential(int n, doublereal V) {
|
||||
thermo(n).setElectricPotential(V);
|
||||
m_redo_rates = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @name Reaction Rates Of Progress
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Forward rates of progress.
|
||||
* Return the forward rates of progress in array fwdROP, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
* Units are kmol/m2/s
|
||||
*/
|
||||
virtual void getFwdRatesOfProgress(doublereal* fwdROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse rates of progress.
|
||||
* Return the reverse rates of progress in array revROP, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
* Units are kmol/m2/s
|
||||
*/
|
||||
virtual void getRevRatesOfProgress(doublereal* revROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropr.begin(), m_kdata->m_ropr.end(), revROP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Net rates of progress. Return the net (forward - reverse)
|
||||
* rates of progress in array netROP, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* reactions.
|
||||
* Units are kmol/m2/s
|
||||
*/
|
||||
virtual void getNetRatesOfProgress(doublereal* netROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equilibrium constants. Return the equilibrium constants of
|
||||
* the reactions in concentration units in array kc, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
*/
|
||||
virtual void getEquilibriumConstants(doublereal* kc);
|
||||
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Species Production Rates
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Species creation rates [kmol/m^2/s]. Return the species
|
||||
* creation rates in array cdot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species in all phases of the kinetics
|
||||
* model
|
||||
*
|
||||
*/
|
||||
virtual void getCreationRates(doublereal* cdot) {
|
||||
updateROP();
|
||||
std::fill(cdot, cdot + m_kk, 0.0);
|
||||
m_revProductStoich.incrementSpecies(
|
||||
&m_kdata->m_ropf[0], cdot);
|
||||
m_irrevProductStoich.incrementSpecies(
|
||||
&m_kdata->m_ropf[0], cdot);
|
||||
m_reactantStoich.incrementSpecies(
|
||||
&m_kdata->m_ropr[0], cdot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Species destruction rates [kmol/m^2/s]. Return the species
|
||||
* destruction rates in array ddot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species in all phases of the kinetics
|
||||
* model
|
||||
*
|
||||
*/
|
||||
virtual void getDestructionRates(doublereal* ddot) {
|
||||
updateROP();
|
||||
std::fill(ddot, ddot + m_kk, 0.0);
|
||||
m_revProductStoich.incrementSpecies(
|
||||
&m_kdata->m_ropr[0], ddot);
|
||||
m_reactantStoich.incrementSpecies(
|
||||
&m_kdata->m_ropf[0], ddot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Species net production rates [kmol/m^2/s]. Return the species
|
||||
* net production rates (creation - destruction) in array
|
||||
* wdot, which must be dimensioned at least as large as the
|
||||
* total number of species in all phases of the kinetics
|
||||
* model
|
||||
*/
|
||||
virtual void getNetProductionRates(doublereal* net) {
|
||||
updateROP();
|
||||
std::fill(net, net + m_kk, 0.0);
|
||||
m_revProductStoich.incrementSpecies(
|
||||
&m_kdata->m_ropnet[0], net);
|
||||
m_irrevProductStoich.incrementSpecies(
|
||||
&m_kdata->m_ropnet[0], net);
|
||||
m_reactantStoich.decrementSpecies(
|
||||
&m_kdata->m_ropnet[0], net);
|
||||
}
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Informational Query Routines
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a reactant in
|
||||
* reaction i.
|
||||
*/
|
||||
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
||||
return m_rrxn[k][i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a product in
|
||||
* reaction i.
|
||||
*/
|
||||
virtual doublereal productStoichCoeff(int k, int i) const {
|
||||
return m_prxn[k][i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag specifying the type of reaction. The legal values and
|
||||
* their meaning are specific to the particular kinetics
|
||||
* manager.
|
||||
*/
|
||||
virtual int reactionType(int i) const {
|
||||
return m_index[i].first;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if reaction i has been declared to be reversible. If
|
||||
* isReversible(i) is false, then the reverse rate of progress
|
||||
* for reaction i is always zero.
|
||||
*/
|
||||
virtual bool isReversible(int i) {
|
||||
if (std::find(m_revindex.begin(), m_revindex.end(), i)
|
||||
< m_revindex.end()) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the reaction.
|
||||
*/
|
||||
virtual std::string reactionString(int i) const {
|
||||
return m_rxneqn[i];
|
||||
}
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Construction
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Prepare the class for the addition of reactions. This function
|
||||
* must be called after instantiation of the class, but before
|
||||
* any reactions are actually added to the mechanism.
|
||||
* This function calculates m_kk the number of species in all
|
||||
* phases participating in the reaction mechanism. We don't know
|
||||
* m_kk previously, before all phases have been added.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Add a single reaction to the mechanism.
|
||||
*/
|
||||
virtual void addReaction(const ReactionData& r);
|
||||
|
||||
/**
|
||||
* Finish adding reactions and prepare for use. This function
|
||||
* must be called after all reactions are entered into the mechanism
|
||||
* and before the mechanism is used to calculate reaction rates.
|
||||
*/
|
||||
virtual void finalize();
|
||||
virtual bool ready() const;
|
||||
|
||||
|
||||
void updateROP();
|
||||
|
||||
|
||||
const std::vector<grouplist_t>& reactantGroups(int i)
|
||||
{ return m_rgroups[i]; }
|
||||
const std::vector<grouplist_t>& productGroups(int i)
|
||||
{ return m_pgroups[i]; }
|
||||
|
||||
void _update_rates_T();
|
||||
void _update_rates_phi();
|
||||
void _update_rates_C();
|
||||
void checkPartialEquil();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* m_kk here is the number of species in all of the phases
|
||||
* that participate in the kinetics mechanism.
|
||||
*/
|
||||
int m_kk;
|
||||
|
||||
Rate1<SurfaceArrhenius> m_rates;
|
||||
//Rate1<Arrhenius> m_rates;
|
||||
bool m_redo_rates;
|
||||
|
||||
/**
|
||||
* Vector of information about reactions in the
|
||||
* mechanism.
|
||||
* The key is the reaction index (0 < i < m_ii).
|
||||
* The first pair is the reactionType of the reaction.
|
||||
* The second pair is ...
|
||||
*/
|
||||
mutable std::map<int, std::pair<int, int> > m_index;
|
||||
|
||||
std::vector<int> m_irrev;
|
||||
|
||||
StoichManagerN m_reactantStoich;
|
||||
StoichManagerN m_revProductStoich;
|
||||
StoichManagerN m_irrevProductStoich;
|
||||
|
||||
StoichManagerN m_globalReactantStoich;
|
||||
|
||||
int m_nirrev;
|
||||
|
||||
/**
|
||||
* Number of reversible reactions in the mechanism
|
||||
*/
|
||||
int m_nrev;
|
||||
|
||||
std::map<int, std::vector<grouplist_t> > m_rgroups;
|
||||
std::map<int, std::vector<grouplist_t> > m_pgroups;
|
||||
|
||||
std::vector<int> m_rxntype;
|
||||
|
||||
mutable std::vector<std::map<int, doublereal> > m_rrxn;
|
||||
mutable std::vector<std::map<int, doublereal> > m_prxn;
|
||||
|
||||
vector_int m_revindex;
|
||||
std::vector<std::string> m_rxneqn;
|
||||
|
||||
/**
|
||||
* Temporary data storage used in calculating the rates of
|
||||
* of reactions.
|
||||
*/
|
||||
EdgeKineticsData* m_kdata;
|
||||
|
||||
/**
|
||||
* An array of generalized concentrations
|
||||
* \f$ C_k \f$ that are defined such that \f$ a_k = C_k /
|
||||
* C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration/
|
||||
* These generalized concentrations are used
|
||||
* by this kinetics manager class to compute the forward and
|
||||
* reverse rates of elementary reactions. The "units" for the
|
||||
* concentrations of each phase depend upon the implementation
|
||||
* of kinetics within that phase.
|
||||
* The order of the species within the vector is based on
|
||||
* the order of listed ThermoPhase objects in the class, and the
|
||||
* order of the species within each ThermoPhase class.
|
||||
*/
|
||||
vector_fp m_conc;
|
||||
|
||||
vector_fp m_mu0;
|
||||
vector_fp m_phi;
|
||||
vector_fp m_pot;
|
||||
vector_fp m_rwork;
|
||||
vector_fp m_E;
|
||||
vector_fp m_beta;
|
||||
vector_int m_ctrxn;
|
||||
|
||||
private:
|
||||
|
||||
int reactionNumber(){ return m_ii;}
|
||||
void addElementaryReaction(const ReactionData& r);
|
||||
void addGlobalReaction(const ReactionData& r);
|
||||
void installReagents(const ReactionData& r);
|
||||
|
||||
void installGroups(int irxn, const std::vector<grouplist_t>& r,
|
||||
const std::vector<grouplist_t>& p);
|
||||
void updateKc();
|
||||
|
||||
void registerReaction(int rxnNumber, int type, int loc) {
|
||||
m_index[rxnNumber] = std::pair<int, int>(type, loc);
|
||||
}
|
||||
void applyButlerVolmerCorrection(doublereal* kf);
|
||||
bool m_finalized;
|
||||
bool m_has_electrochem_rxns;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
81
Cantera/src/kinetics/Enhanced3BConc.h
Executable file
81
Cantera/src/kinetics/Enhanced3BConc.h
Executable file
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* @file Enhanced3BConc.h
|
||||
*/
|
||||
|
||||
/* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_ENH_CONC_H
|
||||
#define CT_ENH_CONC_H
|
||||
|
||||
#include <map>
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Computes enhanced third-body concentrations.
|
||||
* @see GasKinetics
|
||||
*/
|
||||
class Enhanced3BConc {
|
||||
|
||||
public:
|
||||
|
||||
Enhanced3BConc() : m_n (0), m_deflt (1.0) {}
|
||||
|
||||
Enhanced3BConc(int n, const std::map<int, doublereal>& enhanced,
|
||||
doublereal deflt = 1.0) {
|
||||
std::map<int, doublereal>::const_iterator iter;
|
||||
for (iter = enhanced.begin(); iter != enhanced.end(); ++iter) {
|
||||
m_index.push_back( iter->first );
|
||||
m_eff.push_back( iter->second - deflt);
|
||||
}
|
||||
m_deflt = deflt;
|
||||
m_n = n;
|
||||
}
|
||||
|
||||
Enhanced3BConc(int n, const vector_int& e_index,
|
||||
const vector_fp& efficiencies, doublereal deflt = 1.0)
|
||||
: m_index (e_index), m_eff (efficiencies) {
|
||||
int i;
|
||||
m_n = n;
|
||||
m_deflt = deflt;
|
||||
for (i = 0; i < m_n; i++) {
|
||||
m_eff[i] -= m_deflt;
|
||||
}
|
||||
}
|
||||
|
||||
doublereal update(const vector_fp& c, doublereal ctot) const {
|
||||
int i;
|
||||
doublereal sum = 0.0;
|
||||
for (i = 0; i < m_n; i++) {
|
||||
sum += m_eff[i] * c[m_index[i]];
|
||||
}
|
||||
return m_deflt * ctot + sum;
|
||||
}
|
||||
|
||||
void getEfficiencies(vector_fp& eff) const {
|
||||
int i;
|
||||
for (i = 0; i < m_n; i++) {
|
||||
eff[m_index[i]] = m_eff[i] + m_deflt;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int m_n;
|
||||
vector_int m_index;
|
||||
vector_fp m_eff;
|
||||
doublereal m_deflt;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
288
Cantera/src/kinetics/FalloffFactory.cpp
Executable file
288
Cantera/src/kinetics/FalloffFactory.cpp
Executable file
|
|
@ -0,0 +1,288 @@
|
|||
/**
|
||||
* @file FalloffFactory.cpp
|
||||
*/
|
||||
|
||||
/* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "FalloffFactory.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
FalloffFactory* FalloffFactory::s_factory = 0;
|
||||
|
||||
/**
|
||||
* The 3-parameter Troe falloff parameterization.
|
||||
* This parameterization is
|
||||
* defined by
|
||||
* \f[ F = F_{cent}^{1/(1 + f_1^2)} \f]
|
||||
* where
|
||||
* \f[ F_{cent} = (1 - A)\exp(-T/T_3) + A \exp(-T/T_1) \f]
|
||||
* \f[ f_1 = (\log_{10} P_r + C) / \left(N - 0.14
|
||||
* (\log_{10} P_r + C)\right) \f]
|
||||
* \f[ C = -0.4 - 0.67 \log_{10} F_{cent} \f]
|
||||
* \f[ N = 0.75 - 1.27 \log_{10} F_{cent} \f]
|
||||
*/
|
||||
class Troe3 : public Falloff {
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
Troe3() : m_a (0.0), m_rt3 (0.0), m_rt1 (0.0) {}
|
||||
|
||||
// Destructor. Does nothing.
|
||||
virtual ~Troe3() {}
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
* @param c Coefficient vector of length 3,
|
||||
* with entries \f$ (A, T_3, T_1) \f$
|
||||
*/
|
||||
virtual void init(const vector_fp& c) {
|
||||
m_a = c[0];
|
||||
m_rt3 = 1.0/c[1];
|
||||
m_rt1 = 1.0/c[2];
|
||||
}
|
||||
|
||||
virtual void updateTemp(doublereal T, workPtr work) const {
|
||||
doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 )
|
||||
+ m_a * exp(- T * m_rt1 );
|
||||
*work = log10( fmaxx( Fcent, SmallNumber ) );
|
||||
}
|
||||
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const {
|
||||
doublereal lpr,f1,lgf, cc, nn;
|
||||
lpr = log10( fmaxx(pr,SmallNumber) );
|
||||
cc = -0.4 - 0.67 * (*work);
|
||||
nn = 0.75 - 1.27 * (*work);
|
||||
f1 = ( lpr + cc )/ ( nn - 0.14 * ( lpr + cc ) );
|
||||
lgf = (*work) / ( 1.0 + f1 * f1 );
|
||||
return pow(10.0, lgf );
|
||||
}
|
||||
|
||||
virtual size_t workSize() { return 1; }
|
||||
|
||||
protected:
|
||||
|
||||
doublereal m_a, m_rt3, m_rt1;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The 4-parameter Troe falloff parameterization. This parameterization is
|
||||
* defined by
|
||||
*
|
||||
* \f[ F = F_{cent}^{1/(1 + f_1^2)} \f]
|
||||
* where
|
||||
* \f[ F_{cent} = (1 - A)\exp(-T/T_3) + A \exp(-T/T_1) + \exp(-T_2/T) \f]
|
||||
* \f[ f_1 = (\log_{10} P_r + C) / \left(N - 0.14
|
||||
* (\log_{10} P_r + C)\right) \f]
|
||||
* \f[ C = -0.4 - 0.67 \log_{10} F_{cent} \f]
|
||||
* \f[ N = 0.75 - 1.27 \log_{10} F_{cent} \f]
|
||||
*
|
||||
*/
|
||||
|
||||
class Troe4 : public Falloff {
|
||||
public:
|
||||
|
||||
Troe4() : m_a (0.0), m_rt3 (0.0), m_rt1 (0.0),
|
||||
m_t2 (0.0) {}
|
||||
virtual ~Troe4() {}
|
||||
|
||||
virtual void init(const vector_fp& c) {
|
||||
m_a = c[0];
|
||||
m_rt3 = 1.0/c[1];
|
||||
m_rt1 = 1.0/c[2];
|
||||
m_t2 = c[3];
|
||||
}
|
||||
|
||||
virtual void updateTemp(doublereal T, workPtr work) const {
|
||||
doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 )
|
||||
+ m_a * exp(- T * m_rt1 )
|
||||
+ exp(- m_t2 / T );
|
||||
*work = log10( fmaxx( Fcent, SmallNumber ) );
|
||||
}
|
||||
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const {
|
||||
doublereal lpr,f1,lgf, cc, nn;
|
||||
lpr = log10( fmaxx(pr,SmallNumber) );
|
||||
cc = -0.4 - 0.67 * (*work);
|
||||
nn = 0.75 - 1.27 * (*work);
|
||||
f1 = ( lpr + cc )/ ( nn - 0.14 * ( lpr + cc ) );
|
||||
lgf = (*work) / ( 1.0 + f1 * f1 );
|
||||
return pow(10.0, lgf );
|
||||
}
|
||||
|
||||
virtual size_t workSize() { return 1; }
|
||||
|
||||
protected:
|
||||
|
||||
doublereal m_a, m_rt3, m_rt1;
|
||||
doublereal m_t2;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
/**
|
||||
* The 3-parameter SRI falloff function.
|
||||
*/
|
||||
class SRI3 : public Falloff {
|
||||
|
||||
public:
|
||||
|
||||
SRI3() {}
|
||||
virtual ~SRI3() {}
|
||||
|
||||
virtual void init(const vector_fp& c) {
|
||||
m_a = c[0];
|
||||
m_b = c[1];
|
||||
m_c = c[2];
|
||||
}
|
||||
|
||||
virtual void updateTemp(doublereal T, workPtr work) const {
|
||||
*work = m_a * exp( - m_b / T);
|
||||
if (m_c != 0.0) *work += exp( - T/m_c );
|
||||
}
|
||||
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const {
|
||||
doublereal lpr = log10( fmaxx(pr,SmallNumber) );
|
||||
doublereal xx = 1.0/(1.0 + lpr*lpr);
|
||||
doublereal ff = pow( *work , xx);
|
||||
return ff;
|
||||
}
|
||||
|
||||
virtual size_t workSize() { return 1; }
|
||||
|
||||
protected:
|
||||
doublereal m_a, m_b, m_c;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The 5-parameter SRI falloff function.
|
||||
*/
|
||||
class SRI5 : public Falloff {
|
||||
|
||||
public:
|
||||
SRI5() {}
|
||||
virtual ~SRI5() {}
|
||||
virtual void init(const vector_fp& c) {
|
||||
m_a = c[0];
|
||||
m_b = c[1];
|
||||
m_c = c[2];
|
||||
m_d = c[3];
|
||||
m_e = c[4];
|
||||
}
|
||||
|
||||
virtual void updateTemp(doublereal T, workPtr work) const {
|
||||
*work = m_a * exp( - m_b / T);
|
||||
if (m_c != 0.0) *work += exp( - T/m_c );
|
||||
work[1] = m_d * pow(T,m_e);
|
||||
}
|
||||
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const {
|
||||
doublereal lpr = log10( fmaxx(pr,SmallNumber) );
|
||||
doublereal xx = 1.0/(1.0 + lpr*lpr);
|
||||
return pow( *work, xx) * work[1];
|
||||
}
|
||||
|
||||
virtual size_t workSize() { return 2; }
|
||||
|
||||
protected:
|
||||
|
||||
doublereal m_a, m_b, m_c;
|
||||
doublereal m_d, m_e;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wang-Frenklach falloff function. Reference: Wang, H., and
|
||||
* Frenklach, M., Chem. Phys. Lett. vol. 205, 271 (1993).
|
||||
*/
|
||||
class WF93 : public Falloff {
|
||||
|
||||
public:
|
||||
WF93() {}
|
||||
virtual ~WF93() {}
|
||||
|
||||
virtual void init(const vector_fp& c) {
|
||||
m_a = c[0];
|
||||
m_rt1 = 1.0/c[1];
|
||||
m_t2 = c[2];
|
||||
m_rt3 = 1.0/c[3];
|
||||
m_alpha0 = c[4];
|
||||
m_alpha1 = c[5];
|
||||
m_alpha2 = c[6];
|
||||
m_sigma0 = c[7];
|
||||
m_sigma1 = c[8];
|
||||
m_sigma2 = c[9];
|
||||
}
|
||||
|
||||
virtual void updateTemp(doublereal T, workPtr work) const {
|
||||
work[0] = m_alpha0 + (m_alpha1 + m_alpha2*T)*T; // alpha
|
||||
work[1] = m_sigma0 + (m_sigma1 + m_sigma2*T)*T; // sigma
|
||||
doublereal Fcent = (1.0 - m_a) * exp(- T * m_rt3 )
|
||||
+ m_a * exp(- T * m_rt1 ) + exp(-m_t2/T);
|
||||
work[2] = log10(Fcent);
|
||||
}
|
||||
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const {
|
||||
doublereal lpr = log10( fmaxx(pr, SmallNumber) );
|
||||
doublereal x = (lpr - work[0])/work[1];
|
||||
doublereal flog = work[2]/exp(x*x);
|
||||
return pow( 10.0, flog);
|
||||
}
|
||||
|
||||
virtual size_t workSize() { return 3; }
|
||||
|
||||
protected:
|
||||
|
||||
doublereal m_alpha0, m_alpha1, m_alpha2;
|
||||
doublereal m_sigma0, m_sigma1, m_sigma2;
|
||||
doublereal m_a, m_rt1, m_t2, m_rt3;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
|
||||
Falloff* FalloffFactory::newFalloff(int type, const vector_fp& c) {
|
||||
Falloff* f;
|
||||
switch(type) {
|
||||
case TROE3_FALLOFF:
|
||||
f = new Troe3(); break;
|
||||
case TROE4_FALLOFF:
|
||||
f = new Troe4(); break;
|
||||
case SRI3_FALLOFF:
|
||||
f = new SRI3(); break;
|
||||
case SRI5_FALLOFF:
|
||||
f = new SRI5(); break;
|
||||
case WF_FALLOFF:
|
||||
f = new WF93(); break;
|
||||
default: return 0;
|
||||
}
|
||||
f->init(c);
|
||||
return f;
|
||||
}
|
||||
|
||||
}
|
||||
136
Cantera/src/kinetics/FalloffFactory.h
Executable file
136
Cantera/src/kinetics/FalloffFactory.h
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* @file FalloffFactory.h
|
||||
*
|
||||
* Parameterizations for reaction falloff functions. Used by classes
|
||||
* that implement gas-phase kinetics (GasKinetics, GRI_30_Kinetics).
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_NEWFALLOFF_H
|
||||
#define CT_NEWFALLOFF_H
|
||||
|
||||
#include "ct_defs.h"
|
||||
#include "reaction_defs.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Base class for falloff function calculators. Each instance of a
|
||||
* subclass of Falloff computes one falloff function.
|
||||
*/
|
||||
class Falloff {
|
||||
public:
|
||||
|
||||
Falloff(){}
|
||||
virtual ~Falloff(){}
|
||||
|
||||
/**
|
||||
* Initialize. Must be called before any other method is
|
||||
* invoked.
|
||||
*
|
||||
* @param c Vector of coefficients of the parameterization.
|
||||
* The number and meaning of these coefficients is
|
||||
* subclass-dependent.
|
||||
*/
|
||||
virtual void init(const vector_fp& c) =0;
|
||||
|
||||
/**
|
||||
* Update the temperature-dependent portions of the falloff
|
||||
* function, if any. This method evaluates temperature-dependent
|
||||
* intermediate results and stores them in the 'work' array.
|
||||
* If not overloaded, the default behavior is to do nothing.
|
||||
* @param T Temperature [K].
|
||||
* @param work storage space for intermediate results.
|
||||
*/
|
||||
virtual void updateTemp (doublereal T, workPtr work) const {}
|
||||
|
||||
/**
|
||||
* The falloff function. This is defined so that the
|
||||
* rate coefficient is
|
||||
* \f[ k = F(Pr)\frac{Pr}{1 + Pr}. \f]
|
||||
* Here \f$ Pr \f$ is the reduced pressure, defined by
|
||||
* \f[
|
||||
* Pr = \frac{k_0 [M]}{k_\infty}.
|
||||
* \f]
|
||||
* @param pr reduced pressure (dimensionless).
|
||||
* @param work array of size workSize() containing cached
|
||||
* temperature-dependent intermediate results from a prior call
|
||||
* to updateTemp.
|
||||
*/
|
||||
virtual doublereal F(doublereal pr, const_workPtr work) const =0;
|
||||
|
||||
/**
|
||||
* The size of the work array required.
|
||||
*/
|
||||
virtual size_t workSize() =0;
|
||||
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Factory class to construct falloff function calculators.
|
||||
* The falloff factory is accessed through static method factory:
|
||||
* @code
|
||||
* Falloff* f = FalloffFactory::factory()->newFalloff(type, c)
|
||||
* @endcode
|
||||
* @ingroup falloffGroup
|
||||
*/
|
||||
class FalloffFactory {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Return a pointer to the factory. On the first call, a new
|
||||
* instance is created. Since there is no need to instantiate
|
||||
* more than one factory, on all subsequent calls, a pointer
|
||||
* to the existing factory is returned.
|
||||
*/
|
||||
static FalloffFactory* factory() {
|
||||
if (!s_factory) s_factory = new FalloffFactory;
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
static void deleteFalloffFactory() {
|
||||
if (s_factory) {
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor doesn't do anything. We do not delete statically
|
||||
* created single instance of this class here, because it would
|
||||
* create an infinite loop if destructor is called for that
|
||||
* single instance. Instead, to delete single instance, we
|
||||
* call delete[] from FalloffMng's destructor.
|
||||
*/
|
||||
virtual ~FalloffFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a pointer to a new falloff function calculator.
|
||||
* @param type Integer flag specifying the type of falloff function.
|
||||
* The standard types are defined in file reaction_defs.h. A factory
|
||||
* class derived from FalloffFactory may define other types as well.
|
||||
*/
|
||||
virtual Falloff* newFalloff(int type, const vector_fp& c);
|
||||
|
||||
private:
|
||||
static FalloffFactory* s_factory;
|
||||
FalloffFactory(){}
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
123
Cantera/src/kinetics/FalloffMgr.h
Executable file
123
Cantera/src/kinetics/FalloffMgr.h
Executable file
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* @file FalloffMgr.h
|
||||
*
|
||||
* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_FALLOFFMGR_H
|
||||
#define CT_FALLOFFMGR_H
|
||||
|
||||
#include "reaction_defs.h"
|
||||
#include "FalloffFactory.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* A falloff manager that implements any set of falloff functions.
|
||||
* @ingroup falloffGroup
|
||||
*/
|
||||
class FalloffMgr {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param f If supplied, this factory will be used to construct
|
||||
* falloff function calculators. If omitted, the standard factory
|
||||
* will be used.
|
||||
*/
|
||||
FalloffMgr(FalloffFactory* f = 0) :
|
||||
m_n(0), m_n0(0), m_worksize(0) {
|
||||
if (f == 0) m_factory = FalloffFactory::factory();
|
||||
else m_factory = f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor. Deletes all installed falloff function
|
||||
* calculators.
|
||||
*/
|
||||
virtual ~FalloffMgr(){
|
||||
int i;
|
||||
for (i = 0; i < m_n; i++) delete m_falloff[i];
|
||||
if (m_factory) {
|
||||
FalloffFactory::deleteFalloffFactory();
|
||||
m_factory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Install a new falloff function calculator. @param rxn
|
||||
* Index of the falloff reaction. This will be used to determine
|
||||
* which array entry is modified in method pr_to_falloff.
|
||||
*
|
||||
* @param type of falloff function to install.
|
||||
* @param c vector of coefficients for the falloff function.
|
||||
*/
|
||||
void install(int rxn, int type,
|
||||
const vector_fp& c) {
|
||||
if (type != SIMPLE_FALLOFF) {
|
||||
m_rxn.push_back(rxn);
|
||||
Falloff* f = m_factory->newFalloff(type,c);
|
||||
m_offset.push_back(m_worksize);
|
||||
m_worksize += f->workSize();
|
||||
m_falloff.push_back(f);
|
||||
m_n++;
|
||||
}
|
||||
else {
|
||||
m_rxn0.push_back(rxn);
|
||||
m_n0++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Size of the work array required to store intermediate results.
|
||||
*/
|
||||
size_t workSize() { return m_worksize; }
|
||||
|
||||
/**
|
||||
* Update the cached temperature-dependent intermediate
|
||||
* results for all installed falloff functions.
|
||||
* @param t Temperature [K].
|
||||
* @param work Work array. Must be dimensioned at least workSize().
|
||||
*/
|
||||
void updateTemp(doublereal t, workPtr work) {
|
||||
int i;
|
||||
for (i = 0; i < m_n; i++) {
|
||||
m_falloff[i]->updateTemp(t,
|
||||
work + m_offset[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a vector of reduced pressures for each falloff reaction,
|
||||
* replace each entry by the value of the falloff function.
|
||||
*/
|
||||
void pr_to_falloff(doublereal* values, const_workPtr work) {
|
||||
doublereal pr;
|
||||
int i;
|
||||
for (i = 0; i < m_n0; i++) {
|
||||
values[m_rxn0[i]] /= (1.0 + values[m_rxn0[i]]);
|
||||
}
|
||||
for (i = 0; i < m_n; i++) {
|
||||
pr = values[m_rxn[i]];
|
||||
values[m_rxn[i]] *=
|
||||
m_falloff[i]->F(pr, work + m_offset[i]) /(1.0 + pr);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
vector_int m_rxn, m_rxn0;
|
||||
std::vector<Falloff*> m_falloff;
|
||||
FalloffFactory* m_factory;
|
||||
vector_int m_loc;
|
||||
int m_n, m_n0;
|
||||
std::vector<vector_fp::difference_type> m_offset;
|
||||
size_t m_worksize;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
999
Cantera/src/kinetics/GRI_30_Kinetics.cpp
Executable file
999
Cantera/src/kinetics/GRI_30_Kinetics.cpp
Executable file
|
|
@ -0,0 +1,999 @@
|
|||
/**
|
||||
* @file GRI_30_Kinetics.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
// turn off warnings under Windows
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "GRI_30_Kinetics.h"
|
||||
|
||||
#include "ReactionData.h"
|
||||
//#include "StoichManager.h"
|
||||
#include "Enhanced3BConc.h"
|
||||
#include "ThirdBodyMgr.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
#include "IdealGasPhase.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Construct an empty reaction mechanism.
|
||||
*/
|
||||
GRI_30_Kinetics::
|
||||
GRI_30_Kinetics(thermo_t* th) : GasKinetics(th) {}
|
||||
|
||||
void GRI_30_Kinetics::
|
||||
gri30_update_rates_T() {
|
||||
doublereal T = thermo().temperature();
|
||||
if (fabs(T - m_kdata->m_temp) > m_dt_threshold) {
|
||||
doublereal logT = log(T);
|
||||
m_kdata->m_logc_ref = m_kdata->m_logp_ref - logT;
|
||||
update_rates(T, logT, &m_kdata->m_rfn[0]);
|
||||
m_falloff_low_rates.update(T, logT, &m_kdata->m_rfn_low[0]);
|
||||
m_falloff_high_rates.update(T, logT, &m_kdata->m_rfn_high[0]);
|
||||
m_falloffn.updateTemp(T, &m_kdata->falloff_work[0]);
|
||||
m_kdata->m_temp = T;
|
||||
gri30_updateKc();
|
||||
m_kdata->m_ROP_ok = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update the equilibrium constants in molar units.
|
||||
* @todo This formulation assumes an ideal gas.
|
||||
*/
|
||||
void GRI_30_Kinetics::gri30_updateKc() {
|
||||
doublereal* rkc = &m_kdata->m_rkcn[0];
|
||||
const doublereal* a =
|
||||
&((IdealGasPhase*)m_thermo[0])->expGibbs_RT_ref()[0];
|
||||
doublereal exp_c_ref = exp(m_kdata->m_logc_ref);
|
||||
update_kc(a, exp_c_ref, rkc);
|
||||
}
|
||||
|
||||
|
||||
void GRI_30_Kinetics::gri30_updateROP() {
|
||||
|
||||
gri30_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
if (m_kdata->m_ROP_ok) return;
|
||||
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
const vector_fp& rkc = m_kdata->m_rkcn;
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
array_fp& ropnet = m_kdata->m_ropnet;
|
||||
|
||||
copy(rf.begin(), rf.end(), ropf.begin());
|
||||
m_3b_concm.multiply( &ropf[0], &m_kdata->concm_3b_values[0] );
|
||||
processFalloffReactions();
|
||||
multiply_each(ropf.begin(), ropf.end(), m_perturb.begin());
|
||||
eval_ropnet(&m_conc[0], &ropf[0], &rkc[0], &ropnet[0]);
|
||||
m_kdata->m_ROP_ok = true;
|
||||
}
|
||||
|
||||
|
||||
void GRI_30_Kinetics::update_rates(double t, double tlog, double* rf) {
|
||||
double rt = 1.0/t;
|
||||
rf[0] = exp(25.5108 + -1 * tlog);
|
||||
rf[1] = exp(26.9379 + -1 * tlog);
|
||||
rf[2] = exp(3.65584 + 2.7 * tlog - 3150.48 * rt);
|
||||
rf[4] = exp(9.17264 + 2 * tlog - 2013.09 * rt);
|
||||
rf[10] = exp(13.8353 + 1.5 * tlog - 4328.13 * rt);
|
||||
rf[14] = exp(24.3868 - 1781.58 * rt);
|
||||
rf[17] = exp(5.96101 + 2.5 * tlog - 1560.14 * rt);
|
||||
rf[18] = exp(4.86753 + 2.5 * tlog - 2516.36 * rt);
|
||||
rf[20] = exp(9.51044 + 2 * tlog - 956.215 * rt);
|
||||
rf[21] = exp(38.3674 + -1.41 * tlog - 14569.7 * rt);
|
||||
rf[22] = exp(8.84506 + 2 * tlog - 956.215 * rt);
|
||||
rf[24] = exp(9.43348 + 1.83 * tlog - 110.72 * rt);
|
||||
rf[26] = exp(11.4053 + 1.92 * tlog - 2863.61 * rt);
|
||||
rf[28] = exp(23.0259 - 4026.17 * rt);
|
||||
rf[29] = exp(21.2829 - 679.416 * rt);
|
||||
rf[30] = exp(21.6396 - 24056.4 * rt);
|
||||
rf[31] = exp(25.3284 - 20130.9 * rt);
|
||||
rf[32] = exp(28.6606 + -0.86 * tlog);
|
||||
rf[33] = exp(30.666 + -1.24 * tlog);
|
||||
rf[34] = exp(30.0523 + -0.76 * tlog);
|
||||
rf[35] = exp(30.8891 + -1.24 * tlog);
|
||||
rf[36] = exp(27.2743 + -0.8 * tlog);
|
||||
rf[37] = exp(30.9082 + -0.6707 * tlog - 8576.25 * rt);
|
||||
rf[38] = exp(27.631 + -1 * tlog);
|
||||
rf[39] = exp(25.2231 + -0.6 * tlog);
|
||||
rf[40] = exp(31.7254 + -1.25 * tlog);
|
||||
rf[41] = exp(33.9409 + -2 * tlog);
|
||||
rf[42] = exp(37.6298 + -2 * tlog);
|
||||
rf[43] = exp(22.102 - 337.695 * rt);
|
||||
rf[44] = exp(24.5255 - 537.494 * rt);
|
||||
rf[45] = exp(25.1541 - 319.577 * rt);
|
||||
rf[46] = exp(9.40096 + 2 * tlog - 2617.01 * rt);
|
||||
rf[47] = exp(23.0259 - 1811.78 * rt);
|
||||
rf[52] = exp(13.4 + 1.62 * tlog - 5455.46 * rt);
|
||||
rf[57] = exp(10.9578 + 1.9 * tlog - 1379.97 * rt);
|
||||
rf[60] = exp(18.9215 + 0.65 * tlog - -142.929 * rt);
|
||||
rf[61] = exp(24.2137 + -0.09 * tlog - 306.995 * rt);
|
||||
rf[63] = exp(10.6334 + 1.63 * tlog - 968.294 * rt);
|
||||
rf[65] = exp(21.1287 + 0.5 * tlog - -55.3598 * rt);
|
||||
rf[66] = exp(26.2916 + -0.23 * tlog - 538.5 * rt);
|
||||
rf[67] = exp(9.74097 + 2.1 * tlog - 2450.93 * rt);
|
||||
rf[68] = exp(8.34284 + 2.1 * tlog - 2450.93 * rt);
|
||||
rf[74] = exp(7.18917 + 2.53 * tlog - 6160.04 * rt);
|
||||
rf[77] = exp(11.6527 + 1.9 * tlog - 3789.63 * rt);
|
||||
rf[79] = exp(24.6353 - 4026.17 * rt);
|
||||
rf[80] = exp(23.1481 - 1725.21 * rt);
|
||||
rf[83] = exp(12.283 + 1.51 * tlog - 1726.22 * rt);
|
||||
rf[85] = exp(3.57515 + 2.4 * tlog - -1061.9 * rt);
|
||||
rf[86] = exp(23.3974 - -251.636 * rt);
|
||||
rf[87] = exp(21.4164 - 214.897 * rt);
|
||||
rf[88] = exp(35.0694 - 14801.2 * rt);
|
||||
rf[92] = exp(9.33256 + 2 * tlog - 1509.81 * rt);
|
||||
rf[95] = exp(10.9331 + 1.6 * tlog - 2727.73 * rt);
|
||||
rf[96] = exp(34.0987 + -1.34 * tlog - 713.135 * rt);
|
||||
rf[97] = exp(11.5129 + 1.6 * tlog - 1570.21 * rt);
|
||||
rf[98] = exp(10.7706 + 1.228 * tlog - 35.229 * rt);
|
||||
rf[100] = exp(15.0481 + 1.18 * tlog - -224.962 * rt);
|
||||
rf[103] = exp(7.2724 + 2 * tlog - -422.748 * rt);
|
||||
rf[104] = exp(8.7483 + 2 * tlog - 754.907 * rt);
|
||||
rf[106] = exp(-15.3388 + 4.5 * tlog - -503.271 * rt);
|
||||
rf[107] = exp(6.22258 + 2.3 * tlog - 6794.16 * rt);
|
||||
rf[108] = exp(10.4253 + 2 * tlog - 7045.8 * rt);
|
||||
rf[109] = exp(-14.5432 + 4 * tlog - -1006.54 * rt);
|
||||
rf[111] = exp(8.18869 + 2 * tlog - 1258.18 * rt);
|
||||
rf[112] = exp(8.17188 + 2.12 * tlog - 437.846 * rt);
|
||||
rf[113] = exp(22.7382 - 1006.54 * rt);
|
||||
rf[114] = exp(18.683 - -820.332 * rt);
|
||||
rf[115] = exp(26.7635 - 6039.26 * rt);
|
||||
rf[119] = exp(25.7339 - 11877.2 * rt);
|
||||
rf[120] = exp(8.63052 + 2 * tlog - 6039.26 * rt);
|
||||
rf[121] = exp(24.7837 - 289.884 * rt);
|
||||
rf[125] = exp(25.4054 - 1565.17 * rt);
|
||||
rf[126] = exp(22.4655 - -379.97 * rt);
|
||||
rf[131] = exp(25.9703 - 7947.66 * rt);
|
||||
rf[132] = exp(25.2729 - -259.185 * rt);
|
||||
rf[134] = exp(22.3327 - 754.907 * rt);
|
||||
rf[135] = exp(6.21461 + 2 * tlog - 3638.65 * rt);
|
||||
rf[136] = exp(28.101 - 6011.07 * rt);
|
||||
rf[138] = exp(7.80792 + 2 * tlog - 4162.05 * rt);
|
||||
rf[141] = exp(23.4313 - 301.963 * rt);
|
||||
rf[142] = exp(22.9205 - 301.963 * rt);
|
||||
rf[148] = exp(23.2082 - -286.865 * rt);
|
||||
rf[149] = exp(23.4959 - -286.865 * rt);
|
||||
rf[153] = exp(24.4121 - -276.799 * rt);
|
||||
rf[154] = exp(24.2956 - 15339.7 * rt);
|
||||
rf[155] = exp(21.5605 - 10224 * rt);
|
||||
rf[156] = exp(3.19867 + 2.47 * tlog - 2606.95 * rt);
|
||||
rf[158] = exp(22.6461 + 0.1 * tlog - 5334.68 * rt);
|
||||
rf[160] = exp(1.19996 + 2.81 * tlog - 2949.17 * rt);
|
||||
rf[161] = exp(10.309 + 1.5 * tlog - 5002.52 * rt);
|
||||
rf[162] = exp(9.21034 + 1.5 * tlog - 5002.52 * rt);
|
||||
rf[163] = exp(5.42495 + 2 * tlog - 4630.1 * rt);
|
||||
rf[164] = exp(8.72258 + 1.74 * tlog - 5259.18 * rt);
|
||||
rf[165] = exp(34.9442 + -1 * tlog - 8555.61 * rt);
|
||||
rf[166] = exp(32.8621 + -1 * tlog - 8555.61 * rt);
|
||||
rf[167] = exp(23.3222 - 201.309 * rt);
|
||||
rf[168] = exp(23.6136 - 452.944 * rt);
|
||||
rf[169] = exp(-35.3874 + 7.6 * tlog - -1776.55 * rt);
|
||||
rf[170] = exp(23.0259 - -379.97 * rt);
|
||||
rf[171] = exp(17.855 + 0.9 * tlog - 1003.02 * rt);
|
||||
rf[172] = exp(31.4553 + -1.39 * tlog - 510.82 * rt);
|
||||
rf[174] = exp(20.5489 - 1950.18 * rt);
|
||||
rf[175] = exp(21.8864 - 429.794 * rt);
|
||||
rf[177] = exp(24.0191 - 178.661 * rt);
|
||||
rf[178] = exp(16.0127 + 1 * tlog - 3271.26 * rt);
|
||||
rf[179] = exp(24.2378 - 193.759 * rt);
|
||||
rf[180] = exp(21.0597 - 5440.36 * rt);
|
||||
rf[181] = exp(24.0906 - 11650.7 * rt);
|
||||
rf[182] = exp(26.6817 - 9501.76 * rt);
|
||||
rf[183] = exp(21.4164 - 10598.9 * rt);
|
||||
rf[185] = exp(21.47 - -241.57 * rt);
|
||||
rf[186] = exp(32.2945 + -1.41 * tlog);
|
||||
rf[187] = exp(22.0842 - -120.785 * rt);
|
||||
rf[188] = exp(25.6061 - 181.178 * rt);
|
||||
rf[190] = exp(24.189 - 166.08 * rt);
|
||||
rf[192] = exp(14.5087 + 1.2 * tlog);
|
||||
rf[193] = exp(6.1334 + 2 * tlog - 3271.26 * rt);
|
||||
rf[194] = exp(7.15462 + 1.5 * tlog - 50.3271 * rt);
|
||||
rf[196] = exp(23.719 - 6970.31 * rt);
|
||||
rf[197] = exp(23.796 + -0.23 * tlog);
|
||||
rf[198] = exp(26.6232 + -0.45 * tlog);
|
||||
rf[201] = exp(24.4121 - 1836.94 * rt);
|
||||
rf[202] = exp(11.4076 + 1.5 * tlog - -231.505 * rt);
|
||||
rf[204] = exp(25.5908 + -0.11 * tlog - 2506.29 * rt);
|
||||
rf[211] = exp(31.4332 + -1.32 * tlog - 372.421 * rt);
|
||||
rf[213] = exp(20.6179 + 0.72 * tlog - 332.159 * rt);
|
||||
rf[214] = exp(9.4727 + 1.9 * tlog - -478.108 * rt);
|
||||
rf[215] = exp(23.0259 - 6542.53 * rt);
|
||||
rf[218] = exp(22.8027 - 3754.4 * rt);
|
||||
rf[219] = exp(22.5381 - -221.439 * rt);
|
||||
rf[220] = exp(5.68698 + 2.45 * tlog - 1127.33 * rt);
|
||||
rf[225] = exp(21.4164 - 10065.4 * rt);
|
||||
rf[226] = exp(26.4598 - 27201.8 * rt);
|
||||
rf[227] = exp(32.878 + -1.52 * tlog - 372.421 * rt);
|
||||
rf[228] = exp(35.8738 + -2 * tlog - 402.617 * rt);
|
||||
rf[229] = exp(59.9064 + -3.3 * tlog - 63714.1 * rt);
|
||||
rf[230] = exp(3.01062 + 2.64 * tlog - 2506.29 * rt);
|
||||
rf[231] = exp(1.62334 + 2.64 * tlog - 2506.29 * rt);
|
||||
rf[232] = exp(15.179 + 1.58 * tlog - 13387 * rt);
|
||||
rf[233] = exp(7.00307 + 2.03 * tlog - 6728.74 * rt);
|
||||
rf[234] = exp(1.4816 + 2.26 * tlog - 3220.94 * rt);
|
||||
rf[235] = exp(-1.83258 + 2.56 * tlog - 4529.44 * rt);
|
||||
rf[237] = exp(24.8176 - 201.309 * rt);
|
||||
rf[238] = exp(24.8664 - 23160.5 * rt);
|
||||
rf[239] = exp(14.9533 + 0.88 * tlog - 10130.9 * rt);
|
||||
rf[241] = exp(23.0259 - 37242.1 * rt);
|
||||
rf[242] = exp(18.4207 - 32712.6 * rt);
|
||||
rf[248] = exp(33.3676 + -1.38 * tlog - 639.155 * rt);
|
||||
rf[249] = exp(26.3931 + -0.69 * tlog - 382.486 * rt);
|
||||
rf[250] = exp(24.3609 + -0.36 * tlog - 291.897 * rt);
|
||||
rf[251] = exp(33.3676 + -1.38 * tlog - 639.155 * rt);
|
||||
rf[252] = exp(26.3931 + -0.69 * tlog - 382.486 * rt);
|
||||
rf[253] = exp(24.3609 + -0.36 * tlog - 291.897 * rt);
|
||||
rf[254] = exp(25.2876 - 14494.2 * rt);
|
||||
rf[255] = exp(20.7233 - 10946.1 * rt);
|
||||
rf[261] = exp(11.4927 + 1.41 * tlog - 4277.81 * rt);
|
||||
rf[262] = exp(11.9184 + 1.57 * tlog - 22143.9 * rt);
|
||||
rf[263] = exp(7.69621 + 2.11 * tlog - 5737.29 * rt);
|
||||
rf[264] = exp(10.0213 + 1.7 * tlog - 1912.43 * rt);
|
||||
rf[265] = exp(4.65396 + 2.5 * tlog - 6693.51 * rt);
|
||||
rf[266] = exp(10.4043 + 1.5 * tlog - 1811.78 * rt);
|
||||
rf[267] = exp(8.10168 + 1.5 * tlog - 1811.78 * rt);
|
||||
rf[268] = exp(30.0991 - 42637.1 * rt);
|
||||
rf[269] = exp(28.373 + -0.69 * tlog - 1434.32 * rt);
|
||||
rf[270] = exp(19.4139 + 0.18 * tlog - 1066.94 * rt);
|
||||
rf[271] = exp(25.8591 + -0.75 * tlog - 1454.45 * rt);
|
||||
rf[272] = exp(9.90349 + 2 * tlog - 1006.54 * rt);
|
||||
rf[274] = exp(27.1367 + -0.31 * tlog - 145.949 * rt);
|
||||
rf[275] = exp(22.0316 + 0.15 * tlog - -45.2944 * rt);
|
||||
rf[276] = exp(6.29157 + 2.4 * tlog - 4989.93 * rt);
|
||||
rf[277] = exp(10.8198 + 1.6 * tlog - 480.624 * rt);
|
||||
rf[278] = exp(9.14846 + 1.94 * tlog - 3251.13 * rt);
|
||||
rf[279] = exp(23.0259 - 7221.94 * rt);
|
||||
rf[280] = exp(29.4491 + -0.752 * tlog - 173.629 * rt);
|
||||
rf[281] = exp(21.9019 - -354.806 * rt);
|
||||
rf[282] = exp(21.8219 - 5686.97 * rt);
|
||||
rf[284] = exp(8.80986 + 1.83 * tlog - 110.72 * rt);
|
||||
rf[286] = exp(29.2405 - 8721.69 * rt);
|
||||
rf[287] = exp(15.895 + 0.5 * tlog - -883.241 * rt);
|
||||
rf[289] = exp(22.4811 - 754.907 * rt);
|
||||
rf[290] = exp(21.5987 - 754.907 * rt);
|
||||
rf[291] = exp(26.0216 - 5530.45 * rt);
|
||||
rf[292] = exp(18.038 + 0.25 * tlog - -470.559 * rt);
|
||||
rf[293] = exp(19.5292 + 0.29 * tlog - 5.53598 * rt);
|
||||
rf[294] = exp(7.19818 + 1.61 * tlog - -193.256 * rt);
|
||||
rf[295] = exp(22.488 - 909.914 * rt);
|
||||
rf[296] = exp(22.488 - 909.914 * rt);
|
||||
rf[297] = exp(24.1278 - 19703.1 * rt);
|
||||
rf[298] = exp(14.5334 + 1.16 * tlog - 1210.37 * rt);
|
||||
rf[299] = exp(14.5334 + 1.16 * tlog - 1210.37 * rt);
|
||||
rf[300] = exp(16.9695 + 0.73 * tlog - -560.141 * rt);
|
||||
rf[301] = exp(21.8252 - 6000.5 * rt);
|
||||
rf[302] = exp(7.90839 + 1.77 * tlog - 2979.37 * rt);
|
||||
rf[312] = exp(5.26269 + 2.68 * tlog - 1870.16 * rt);
|
||||
rf[313] = exp(7.18539 + 2.54 * tlog - 3400.1 * rt);
|
||||
rf[314] = exp(10.3609 + 1.8 * tlog - 470.055 * rt);
|
||||
rf[315] = exp(-0.972861 + 2.72 * tlog - 754.907 * rt);
|
||||
rf[316] = exp(-7.00979 + 3.65 * tlog - 3600.4 * rt);
|
||||
rf[320] = exp(8.30894 + 2.19 * tlog - 447.911 * rt);
|
||||
rf[322] = exp(17.0542 + 0.255 * tlog - -474.585 * rt);
|
||||
rf[324] = exp(23.6818 + -0.32 * tlog);
|
||||
}
|
||||
|
||||
|
||||
void GRI_30_Kinetics::update_kc(const double* a, double exp_c0, double* rkc) {
|
||||
rkc[0] = a[3]*exp_c0/(a[2]*a[2]);
|
||||
rkc[1] = a[4]*exp_c0/(a[1]*a[2]);
|
||||
rkc[2] = a[1]*a[4]/(a[0]*a[2]);
|
||||
rkc[3] = a[3]*a[4]/(a[2]*a[6]);
|
||||
rkc[4] = a[4]*a[6]/(a[2]*a[7]);
|
||||
rkc[5] = a[1]*a[14]/(a[2]*a[9]);
|
||||
rkc[6] = a[1]*a[16]/(a[2]*a[10]);
|
||||
rkc[7] = a[0]*a[14]/(a[2]*a[11]);
|
||||
rkc[8] = a[1]*a[16]/(a[2]*a[11]);
|
||||
rkc[9] = a[1]*a[17]/(a[2]*a[12]);
|
||||
rkc[10] = a[4]*a[12]/(a[2]*a[13]);
|
||||
rkc[11] = a[15]*exp_c0/(a[2]*a[14]);
|
||||
rkc[12] = a[4]*a[14]/(a[2]*a[16]);
|
||||
rkc[13] = a[1]*a[15]/(a[2]*a[16]);
|
||||
rkc[14] = a[4]*a[16]/(a[2]*a[17]);
|
||||
rkc[15] = a[4]*a[17]/(a[2]*a[18]);
|
||||
rkc[16] = a[4]*a[17]/(a[2]*a[19]);
|
||||
rkc[17] = a[4]*a[18]/(a[2]*a[20]);
|
||||
rkc[18] = a[4]*a[19]/(a[2]*a[20]);
|
||||
rkc[19] = a[9]*a[14]/(a[2]*a[21]);
|
||||
rkc[20] = a[1]*a[27]/(a[2]*a[22]);
|
||||
rkc[21] = a[4]*a[21]/(a[2]*a[22]);
|
||||
rkc[22] = a[10]*a[14]/(a[2]*a[22]);
|
||||
rkc[23] = a[1]*a[28]/(a[2]*a[23]);
|
||||
rkc[24] = a[12]*a[16]/(a[2]*a[24]);
|
||||
rkc[25] = a[12]*a[17]/(a[2]*a[25]);
|
||||
rkc[26] = a[4]*a[25]/(a[2]*a[26]);
|
||||
rkc[27] = a[1]*a[14]*a[14]/(a[2]*a[27]*exp_c0);
|
||||
rkc[28] = a[4]*a[27]/(a[2]*a[28]);
|
||||
rkc[29] = a[10]*a[15]/(a[2]*a[28]);
|
||||
rkc[30] = a[2]*a[15]/(a[3]*a[14]);
|
||||
rkc[31] = a[6]*a[16]/(a[3]*a[17]);
|
||||
rkc[32] = a[6]*exp_c0/(a[1]*a[3]);
|
||||
rkc[33] = a[3]*a[6]*exp_c0/(a[1]*a[3]*a[3]);
|
||||
rkc[34] = a[5]*a[6]*exp_c0/(a[1]*a[3]*a[5]);
|
||||
rkc[35] = a[6]*a[47]*exp_c0/(a[1]*a[3]*a[47]);
|
||||
rkc[36] = a[6]*a[48]*exp_c0/(a[1]*a[3]*a[48]);
|
||||
rkc[37] = a[2]*a[4]/(a[1]*a[3]);
|
||||
rkc[38] = a[0]*exp_c0/(a[1]*a[1]);
|
||||
rkc[39] = a[0]*a[0]*exp_c0/(a[0]*a[1]*a[1]);
|
||||
rkc[40] = a[0]*a[5]*exp_c0/(a[1]*a[1]*a[5]);
|
||||
rkc[41] = a[0]*a[15]*exp_c0/(a[1]*a[1]*a[15]);
|
||||
rkc[42] = a[5]*exp_c0/(a[1]*a[4]);
|
||||
rkc[43] = a[2]*a[5]/(a[1]*a[6]);
|
||||
rkc[44] = a[0]*a[3]/(a[1]*a[6]);
|
||||
rkc[45] = a[4]*a[4]/(a[1]*a[6]);
|
||||
rkc[46] = a[0]*a[6]/(a[1]*a[7]);
|
||||
rkc[47] = a[4]*a[5]/(a[1]*a[7]);
|
||||
rkc[48] = a[0]*a[8]/(a[1]*a[9]);
|
||||
rkc[49] = a[12]*exp_c0/(a[1]*a[10]);
|
||||
rkc[50] = a[0]*a[9]/(a[1]*a[11]);
|
||||
rkc[51] = a[13]*exp_c0/(a[1]*a[12]);
|
||||
rkc[52] = a[0]*a[12]/(a[1]*a[13]);
|
||||
rkc[53] = a[17]*exp_c0/(a[1]*a[16]);
|
||||
rkc[54] = a[0]*a[14]/(a[1]*a[16]);
|
||||
rkc[55] = a[18]*exp_c0/(a[1]*a[17]);
|
||||
rkc[56] = a[19]*exp_c0/(a[1]*a[17]);
|
||||
rkc[57] = a[0]*a[16]/(a[1]*a[17]);
|
||||
rkc[58] = a[20]*exp_c0/(a[1]*a[18]);
|
||||
rkc[59] = a[0]*a[17]/(a[1]*a[18]);
|
||||
rkc[60] = a[4]*a[12]/(a[1]*a[18]);
|
||||
rkc[61] = a[5]*a[11]/(a[1]*a[18]);
|
||||
rkc[62] = a[20]*exp_c0/(a[1]*a[19]);
|
||||
rkc[63] = a[1]*a[18]/(a[1]*a[19]);
|
||||
rkc[64] = a[0]*a[17]/(a[1]*a[19]);
|
||||
rkc[65] = a[4]*a[12]/(a[1]*a[19]);
|
||||
rkc[66] = a[5]*a[11]/(a[1]*a[19]);
|
||||
rkc[67] = a[0]*a[18]/(a[1]*a[20]);
|
||||
rkc[68] = a[0]*a[19]/(a[1]*a[20]);
|
||||
rkc[69] = a[22]*exp_c0/(a[1]*a[21]);
|
||||
rkc[70] = a[23]*exp_c0/(a[1]*a[22]);
|
||||
rkc[71] = a[24]*exp_c0/(a[1]*a[23]);
|
||||
rkc[72] = a[0]*a[22]/(a[1]*a[23]);
|
||||
rkc[73] = a[25]*exp_c0/(a[1]*a[24]);
|
||||
rkc[74] = a[0]*a[23]/(a[1]*a[24]);
|
||||
rkc[75] = a[26]*exp_c0/(a[1]*a[25]);
|
||||
rkc[76] = a[0]*a[24]/(a[1]*a[25]);
|
||||
rkc[77] = a[0]*a[25]/(a[1]*a[26]);
|
||||
rkc[78] = a[11]*a[14]/(a[1]*a[27]);
|
||||
rkc[79] = a[0]*a[27]/(a[1]*a[28]);
|
||||
rkc[80] = a[12]*a[14]/(a[1]*a[28]);
|
||||
rkc[81] = a[1]*a[28]/(a[1]*a[29]);
|
||||
rkc[82] = a[17]*exp_c0/(a[0]*a[14]);
|
||||
rkc[83] = a[1]*a[5]/(a[0]*a[4]);
|
||||
rkc[84] = a[7]*exp_c0/(a[4]*a[4]);
|
||||
rkc[85] = a[2]*a[5]/(a[4]*a[4]);
|
||||
rkc[86] = a[3]*a[5]/(a[4]*a[6]);
|
||||
rkc[87] = a[5]*a[6]/(a[4]*a[7]);
|
||||
rkc[88] = a[5]*a[6]/(a[4]*a[7]);
|
||||
rkc[89] = a[1]*a[14]/(a[4]*a[8]);
|
||||
rkc[90] = a[1]*a[16]/(a[4]*a[9]);
|
||||
rkc[91] = a[1]*a[17]/(a[4]*a[10]);
|
||||
rkc[92] = a[5]*a[9]/(a[4]*a[10]);
|
||||
rkc[93] = a[1]*a[17]/(a[4]*a[11]);
|
||||
rkc[94] = a[20]*exp_c0/(a[4]*a[12]);
|
||||
rkc[95] = a[5]*a[10]/(a[4]*a[12]);
|
||||
rkc[96] = a[5]*a[11]/(a[4]*a[12]);
|
||||
rkc[97] = a[5]*a[12]/(a[4]*a[13]);
|
||||
rkc[98] = a[1]*a[15]/(a[4]*a[14]);
|
||||
rkc[99] = a[5]*a[14]/(a[4]*a[16]);
|
||||
rkc[100] = a[5]*a[16]/(a[4]*a[17]);
|
||||
rkc[101] = a[5]*a[17]/(a[4]*a[18]);
|
||||
rkc[102] = a[5]*a[17]/(a[4]*a[19]);
|
||||
rkc[103] = a[5]*a[18]/(a[4]*a[20]);
|
||||
rkc[104] = a[5]*a[19]/(a[4]*a[20]);
|
||||
rkc[105] = a[1]*a[27]/(a[4]*a[21]);
|
||||
rkc[106] = a[1]*a[28]/(a[4]*a[22]);
|
||||
rkc[107] = a[1]*a[29]/(a[4]*a[22]);
|
||||
rkc[108] = a[5]*a[21]/(a[4]*a[22]);
|
||||
rkc[109] = a[12]*a[14]/(a[4]*a[22]);
|
||||
rkc[110] = a[5]*a[22]/(a[4]*a[23]);
|
||||
rkc[111] = a[5]*a[23]/(a[4]*a[24]);
|
||||
rkc[112] = a[5]*a[25]/(a[4]*a[26]);
|
||||
rkc[113] = a[5]*a[27]/(a[4]*a[28]);
|
||||
rkc[114] = a[3]*a[7]/(a[6]*a[6]);
|
||||
rkc[115] = a[3]*a[7]/(a[6]*a[6]);
|
||||
rkc[116] = a[4]*a[17]/(a[6]*a[10]);
|
||||
rkc[117] = a[3]*a[13]/(a[6]*a[12]);
|
||||
rkc[118] = a[4]*a[19]/(a[6]*a[12]);
|
||||
rkc[119] = a[4]*a[15]/(a[6]*a[14]);
|
||||
rkc[120] = a[7]*a[16]/(a[6]*a[17]);
|
||||
rkc[121] = a[2]*a[14]/(a[3]*a[8]);
|
||||
rkc[122] = a[1]*a[21]/(a[8]*a[10]);
|
||||
rkc[123] = a[1]*a[22]/(a[8]*a[12]);
|
||||
rkc[124] = a[2]*a[16]/(a[3]*a[9]);
|
||||
rkc[125] = a[1]*a[10]/(a[0]*a[9]);
|
||||
rkc[126] = a[1]*a[17]/(a[5]*a[9]);
|
||||
rkc[127] = a[1]*a[22]/(a[9]*a[10]);
|
||||
rkc[128] = a[1]*a[23]/(a[9]*a[12]);
|
||||
rkc[129] = a[1]*a[24]/(a[9]*a[13]);
|
||||
rkc[130] = a[27]*exp_c0/(a[9]*a[14]);
|
||||
rkc[131] = a[14]*a[16]/(a[9]*a[15]);
|
||||
rkc[132] = a[1]*a[28]/(a[9]*a[17]);
|
||||
rkc[133] = a[14]*a[22]/(a[9]*a[27]);
|
||||
rkc[135] = a[1]*a[12]/(a[0]*a[10]);
|
||||
rkc[136] = a[0]*a[22]/(a[10]*a[10]);
|
||||
rkc[137] = a[1]*a[24]/(a[10]*a[12]);
|
||||
rkc[138] = a[12]*a[12]/(a[10]*a[13]);
|
||||
rkc[139] = a[28]*exp_c0/(a[10]*a[14]);
|
||||
rkc[140] = a[14]*a[23]/(a[10]*a[27]);
|
||||
rkc[141] = a[10]*a[47]/(a[11]*a[47]);
|
||||
rkc[142] = a[10]*a[48]/(a[11]*a[48]);
|
||||
rkc[143] = a[1]*a[4]*a[14]/(a[3]*a[11]*exp_c0);
|
||||
rkc[144] = a[5]*a[14]/(a[3]*a[11]);
|
||||
rkc[145] = a[1]*a[12]/(a[0]*a[11]);
|
||||
rkc[146] = a[20]*exp_c0/(a[5]*a[11]);
|
||||
rkc[147] = a[5]*a[10]/(a[5]*a[11]);
|
||||
rkc[148] = a[1]*a[24]/(a[11]*a[12]);
|
||||
rkc[149] = a[12]*a[12]/(a[11]*a[13]);
|
||||
rkc[150] = a[10]*a[14]/(a[11]*a[14]);
|
||||
rkc[151] = a[10]*a[15]/(a[11]*a[15]);
|
||||
rkc[152] = a[14]*a[17]/(a[11]*a[15]);
|
||||
rkc[153] = a[12]*a[25]/(a[11]*a[26]);
|
||||
rkc[154] = a[2]*a[19]/(a[3]*a[12]);
|
||||
rkc[155] = a[4]*a[17]/(a[3]*a[12]);
|
||||
rkc[156] = a[6]*a[13]/(a[7]*a[12]);
|
||||
rkc[157] = a[26]*exp_c0/(a[12]*a[12]);
|
||||
rkc[158] = a[1]*a[25]/(a[12]*a[12]);
|
||||
rkc[159] = a[13]*a[14]/(a[12]*a[16]);
|
||||
rkc[160] = a[13]*a[16]/(a[12]*a[17]);
|
||||
rkc[161] = a[13]*a[18]/(a[12]*a[20]);
|
||||
rkc[162] = a[13]*a[19]/(a[12]*a[20]);
|
||||
rkc[163] = a[13]*a[23]/(a[12]*a[24]);
|
||||
rkc[164] = a[13]*a[25]/(a[12]*a[26]);
|
||||
rkc[165] = a[1]*a[5]*a[14]/(a[5]*a[16]*exp_c0);
|
||||
rkc[166] = a[1]*a[14]/(a[16]*exp_c0);
|
||||
rkc[167] = a[6]*a[14]/(a[3]*a[16]);
|
||||
rkc[168] = a[6]*a[17]/(a[3]*a[18]);
|
||||
rkc[169] = a[6]*a[17]/(a[3]*a[19]);
|
||||
rkc[170] = a[14]*a[16]/(a[3]*a[21]);
|
||||
rkc[171] = a[1]*a[22]/(a[0]*a[21]);
|
||||
rkc[172] = a[16]*a[17]/(a[3]*a[23]);
|
||||
rkc[173] = a[0]*a[22]/(a[24]*exp_c0);
|
||||
rkc[174] = a[6]*a[24]/(a[3]*a[25]);
|
||||
rkc[175] = a[4]*a[14]*a[14]/(a[3]*a[27]*exp_c0);
|
||||
rkc[176] = a[14]*a[14]*a[22]/(a[27]*a[27]*exp_c0);
|
||||
rkc[177] = a[2]*a[47]/(a[30]*a[35]);
|
||||
rkc[178] = a[2]*a[35]/(a[3]*a[30]);
|
||||
rkc[179] = a[1]*a[35]/(a[4]*a[30]);
|
||||
rkc[180] = a[3]*a[47]/(a[2]*a[37]);
|
||||
rkc[181] = a[35]*a[35]/(a[2]*a[37]);
|
||||
rkc[182] = a[4]*a[47]/(a[1]*a[37]);
|
||||
rkc[183] = a[6]*a[47]/(a[4]*a[37]);
|
||||
rkc[184] = a[2]*a[47]/(a[37]*exp_c0);
|
||||
rkc[185] = a[4]*a[36]/(a[6]*a[35]);
|
||||
rkc[186] = a[36]*exp_c0/(a[2]*a[35]);
|
||||
rkc[187] = a[3]*a[35]/(a[2]*a[36]);
|
||||
rkc[188] = a[4]*a[35]/(a[1]*a[36]);
|
||||
rkc[189] = a[1]*a[35]/(a[2]*a[31]);
|
||||
rkc[190] = a[0]*a[30]/(a[1]*a[31]);
|
||||
rkc[191] = a[1]*a[38]/(a[4]*a[31]);
|
||||
rkc[192] = a[5]*a[30]/(a[4]*a[31]);
|
||||
rkc[193] = a[2]*a[38]/(a[3]*a[31]);
|
||||
rkc[194] = a[4]*a[35]/(a[3]*a[31]);
|
||||
rkc[195] = a[1]*a[47]/(a[30]*a[31]);
|
||||
rkc[196] = a[0]*a[38]/(a[5]*a[31]);
|
||||
rkc[197] = a[4]*a[47]/(a[31]*a[35]);
|
||||
rkc[198] = a[1]*a[37]/(a[31]*a[35]);
|
||||
rkc[199] = a[4]*a[31]/(a[2]*a[32]);
|
||||
rkc[200] = a[1]*a[38]/(a[2]*a[32]);
|
||||
rkc[201] = a[0]*a[31]/(a[1]*a[32]);
|
||||
rkc[202] = a[5]*a[31]/(a[4]*a[32]);
|
||||
rkc[203] = a[1]*a[47]/(a[34]*exp_c0);
|
||||
rkc[204] = a[1]*a[47]/(a[34]*exp_c0);
|
||||
rkc[205] = a[6]*a[47]/(a[3]*a[34]);
|
||||
rkc[206] = a[4]*a[47]/(a[2]*a[34]);
|
||||
rkc[207] = a[31]*a[35]/(a[2]*a[34]);
|
||||
rkc[208] = a[0]*a[47]/(a[1]*a[34]);
|
||||
rkc[209] = a[5]*a[47]/(a[4]*a[34]);
|
||||
rkc[210] = a[13]*a[47]/(a[12]*a[34]);
|
||||
rkc[211] = a[38]*exp_c0/(a[1]*a[35]);
|
||||
rkc[212] = a[4]*a[35]/(a[2]*a[38]);
|
||||
rkc[213] = a[0]*a[35]/(a[1]*a[38]);
|
||||
rkc[214] = a[5]*a[35]/(a[4]*a[38]);
|
||||
rkc[215] = a[6]*a[35]/(a[3]*a[38]);
|
||||
rkc[216] = a[14]*a[30]/(a[2]*a[39]);
|
||||
rkc[217] = a[1]*a[46]/(a[4]*a[39]);
|
||||
rkc[218] = a[4]*a[40]/(a[5]*a[39]);
|
||||
rkc[219] = a[2]*a[46]/(a[3]*a[39]);
|
||||
rkc[220] = a[1]*a[40]/(a[0]*a[39]);
|
||||
rkc[221] = a[14]*a[35]/(a[2]*a[46]);
|
||||
rkc[222] = a[14]*a[31]/(a[1]*a[46]);
|
||||
rkc[223] = a[1]*a[14]*a[35]/(a[4]*a[46]*exp_c0);
|
||||
rkc[224] = a[14]*a[47]/(a[30]*a[46]);
|
||||
rkc[225] = a[15]*a[35]/(a[3]*a[46]);
|
||||
rkc[226] = a[14]*a[30]/(a[46]*exp_c0);
|
||||
rkc[227] = a[14]*a[37]/(a[35]*a[46]);
|
||||
rkc[228] = a[15]*a[47]/(a[35]*a[46]);
|
||||
rkc[229] = a[1]*a[39]/(a[40]*exp_c0);
|
||||
rkc[230] = a[1]*a[46]/(a[2]*a[40]);
|
||||
rkc[231] = a[14]*a[31]/(a[2]*a[40]);
|
||||
rkc[232] = a[4]*a[39]/(a[2]*a[40]);
|
||||
rkc[233] = a[1]*a[44]/(a[4]*a[40]);
|
||||
rkc[234] = a[1]*a[45]/(a[4]*a[40]);
|
||||
rkc[235] = a[14]*a[32]/(a[4]*a[40]);
|
||||
rkc[236] = a[41]*exp_c0/(a[1]*a[40]);
|
||||
rkc[237] = a[10]*a[47]/(a[30]*a[41]);
|
||||
rkc[238] = a[30]*a[39]/(a[8]*a[47]);
|
||||
rkc[239] = a[30]*a[40]/(a[9]*a[47]);
|
||||
rkc[240] = a[42]*exp_c0/(a[9]*a[47]);
|
||||
rkc[241] = a[31]*a[40]/(a[10]*a[47]);
|
||||
rkc[242] = a[31]*a[40]/(a[11]*a[47]);
|
||||
rkc[243] = a[2]*a[39]/(a[8]*a[35]);
|
||||
rkc[244] = a[14]*a[30]/(a[8]*a[35]);
|
||||
rkc[245] = a[2]*a[40]/(a[9]*a[35]);
|
||||
rkc[246] = a[1]*a[46]/(a[9]*a[35]);
|
||||
rkc[247] = a[16]*a[30]/(a[9]*a[35]);
|
||||
rkc[248] = a[1]*a[45]/(a[10]*a[35]);
|
||||
rkc[249] = a[4]*a[40]/(a[10]*a[35]);
|
||||
rkc[250] = a[1]*a[43]/(a[10]*a[35]);
|
||||
rkc[251] = a[1]*a[45]/(a[11]*a[35]);
|
||||
rkc[252] = a[4]*a[40]/(a[11]*a[35]);
|
||||
rkc[253] = a[1]*a[43]/(a[11]*a[35]);
|
||||
rkc[254] = a[5]*a[40]/(a[12]*a[35]);
|
||||
rkc[255] = a[4]*a[41]/(a[12]*a[35]);
|
||||
rkc[256] = a[1]*a[14]*a[47]/(a[2]*a[42]*exp_c0);
|
||||
rkc[257] = a[35]*a[40]/(a[2]*a[42]);
|
||||
rkc[258] = a[2]*a[16]*a[47]/(a[3]*a[42]*exp_c0);
|
||||
rkc[259] = a[1]*a[16]*a[47]/(a[4]*a[42]*exp_c0);
|
||||
rkc[260] = a[10]*a[47]/(a[1]*a[42]);
|
||||
rkc[261] = a[15]*a[31]/(a[2]*a[45]);
|
||||
rkc[262] = a[14]*a[38]/(a[2]*a[45]);
|
||||
rkc[263] = a[4]*a[46]/(a[2]*a[45]);
|
||||
rkc[264] = a[14]*a[32]/(a[1]*a[45]);
|
||||
rkc[265] = a[0]*a[46]/(a[1]*a[45]);
|
||||
rkc[266] = a[5]*a[46]/(a[4]*a[45]);
|
||||
rkc[267] = a[15]*a[32]/(a[4]*a[45]);
|
||||
rkc[268] = a[14]*a[31]/(a[45]*exp_c0);
|
||||
rkc[269] = a[1]*a[45]/(a[1]*a[43]);
|
||||
rkc[270] = a[4]*a[40]/(a[1]*a[43]);
|
||||
rkc[271] = a[14]*a[32]/(a[1]*a[43]);
|
||||
rkc[272] = a[1]*a[45]/(a[1]*a[44]);
|
||||
rkc[273] = a[14]*a[43]/(a[27]*a[35]);
|
||||
rkc[274] = a[1]*a[41]/(a[12]*a[30]);
|
||||
rkc[275] = a[0]*a[40]/(a[12]*a[30]);
|
||||
rkc[276] = a[0]*a[32]/(a[1]*a[33]);
|
||||
rkc[277] = a[5]*a[32]/(a[4]*a[33]);
|
||||
rkc[278] = a[4]*a[32]/(a[2]*a[33]);
|
||||
rkc[279] = a[14]*a[38]/(a[15]*a[31]);
|
||||
rkc[280] = a[35]*a[46]/(a[36]*a[39]);
|
||||
rkc[281] = a[15]*a[37]/(a[36]*a[46]);
|
||||
rkc[282] = a[14]*a[35]/(a[15]*a[30]);
|
||||
rkc[284] = a[1]*a[51]/(a[2]*a[24]);
|
||||
rkc[285] = a[1]*a[52]/(a[2]*a[25]);
|
||||
rkc[286] = a[3]*a[5]/(a[4]*a[6]);
|
||||
rkc[288] = a[12]*exp_c0/(a[0]*a[9]);
|
||||
rkc[290] = a[2]*a[17]/(a[3]*a[10]);
|
||||
rkc[293] = a[2]*a[51]/(a[3]*a[23]);
|
||||
rkc[294] = a[6]*a[22]/(a[3]*a[23]);
|
||||
rkc[295] = a[4]*a[51]/(a[2]*a[52]);
|
||||
rkc[298] = a[0]*a[51]/(a[1]*a[52]);
|
||||
rkc[303] = a[51]*exp_c0/(a[1]*a[28]);
|
||||
rkc[307] = a[12]*a[16]/(a[1]*a[51]);
|
||||
rkc[308] = a[0]*a[28]/(a[1]*a[51]);
|
||||
rkc[309] = a[5]*a[28]/(a[4]*a[51]);
|
||||
rkc[310] = a[16]*a[18]/(a[4]*a[51]);
|
||||
rkc[311] = a[50]*exp_c0/(a[12]*a[25]);
|
||||
rkc[312] = a[4]*a[49]/(a[2]*a[50]);
|
||||
rkc[313] = a[0]*a[49]/(a[1]*a[50]);
|
||||
rkc[314] = a[5]*a[49]/(a[4]*a[50]);
|
||||
rkc[315] = a[6]*a[50]/(a[7]*a[49]);
|
||||
rkc[316] = a[13]*a[49]/(a[12]*a[50]);
|
||||
rkc[317] = a[49]*exp_c0/(a[12]*a[24]);
|
||||
rkc[318] = a[17]*a[25]/(a[2]*a[49]);
|
||||
rkc[319] = a[50]*exp_c0/(a[1]*a[49]);
|
||||
rkc[320] = a[12]*a[25]/(a[1]*a[49]);
|
||||
rkc[321] = a[18]*a[25]/(a[4]*a[49]);
|
||||
rkc[322] = a[3]*a[50]/(a[6]*a[49]);
|
||||
rkc[324] = a[25]*a[25]/(a[12]*a[49]);
|
||||
}
|
||||
|
||||
|
||||
void GRI_30_Kinetics::get_wdot(const double* rop, double* wdot) {
|
||||
wdot[0] = - rop[2] + rop[7] + rop[38] + rop[39] + rop[40] + rop[41] + rop[44] + rop[46] + rop[48] + rop[50] + rop[52] + rop[54] + rop[57] + rop[59] + rop[64] + rop[67] + rop[68] + rop[72] + rop[74] + rop[76] + rop[77] + rop[79] - rop[82] - rop[83] - rop[125] - rop[135] + rop[136] - rop[145] - rop[171] + rop[173] + rop[190] + rop[196] + rop[201] + rop[208] + rop[213] - rop[220] + rop[265] + rop[275] + rop[276] + rop[283] + rop[287] - rop[288] + rop[292] + rop[298] + rop[299] + rop[308] + rop[313];
|
||||
wdot[1] = - rop[1] + rop[2] + rop[5] + rop[6] + rop[8] + rop[9] + rop[13] + rop[20] + rop[23] + rop[27] - rop[32] - rop[33] - rop[34] - rop[35] - rop[36] - rop[37] - 2*rop[38] - 2*rop[39] - 2*rop[40] - 2*rop[41] - rop[42] - rop[43] - rop[44] - rop[45] - rop[46] - rop[47] - rop[48] - rop[49] - rop[50] - rop[51] - rop[52] - rop[53] - rop[54] - rop[55] - rop[56] - rop[57] - rop[58] - rop[59] - rop[60] - rop[61] - rop[62] - rop[64] - rop[65] - rop[66] - rop[67] - rop[68] - rop[69] - rop[70] - rop[71] - rop[72] - rop[73] - rop[74] - rop[75] - rop[76] - rop[77] - rop[78] - rop[79] - rop[80] + rop[83] + rop[89] + rop[90] + rop[91] + rop[93] + rop[98] + rop[105] + rop[106] + rop[107] + rop[122] + rop[123] + rop[125] + rop[126] + rop[127] + rop[128] + rop[129] + rop[132] + rop[134] + rop[135] + rop[137] + rop[143] + rop[145] + rop[148] + rop[158] + rop[165] + rop[166] + rop[171] + rop[179] - rop[182] - rop[188] + rop[189] - rop[190] + rop[191] + rop[195] + rop[198] + rop[200] - rop[201] + rop[203] + rop[204] - rop[208] - rop[211] - rop[213] + rop[217] + rop[220] - rop[222] + rop[223] + rop[229] + rop[230] + rop[233] + rop[234] - rop[236] + rop[246] + rop[248] + rop[250] + rop[251] + rop[253] + rop[256] + rop[259] - rop[260] - rop[264] - rop[265] - rop[270] - rop[271] + rop[274] - rop[276] + rop[283] + rop[284] + rop[285] + 2*rop[289] + 2*rop[291] - rop[298] - rop[299] - rop[303] + rop[304] - rop[307] - rop[308] - rop[313] - rop[319] - rop[320];
|
||||
wdot[2] = - 2*rop[0] - rop[1] - rop[2] - rop[3] - rop[4] - rop[5] - rop[6] - rop[7] - rop[8] - rop[9] - rop[10] - rop[11] - rop[12] - rop[13] - rop[14] - rop[15] - rop[16] - rop[17] - rop[18] - rop[19] - rop[20] - rop[21] - rop[22] - rop[23] - rop[24] - rop[25] - rop[26] - rop[27] - rop[28] - rop[29] + rop[30] + rop[37] + rop[43] + rop[85] + rop[121] + rop[124] + rop[154] + rop[177] + rop[178] - rop[180] - rop[181] + rop[184] - rop[186] - rop[187] - rop[189] + rop[193] - rop[199] - rop[200] - rop[206] - rop[207] - rop[212] - rop[216] + rop[219] - rop[221] - rop[230] - rop[231] - rop[232] + rop[243] + rop[245] - rop[256] - rop[257] + rop[258] - rop[261] - rop[262] - rop[263] - rop[278] - rop[283] - rop[284] - rop[285] + rop[290] + rop[293] - rop[295] - rop[296] - rop[304] - rop[312] - rop[318];
|
||||
wdot[3] = + rop[0] + rop[3] - rop[30] - rop[31] - rop[32] - rop[33] - rop[34] - rop[35] - rop[36] - rop[37] + rop[44] + rop[86] + rop[114] + rop[115] + rop[117] - rop[121] - rop[124] - rop[134] - rop[143] - rop[144] - rop[154] - rop[155] - rop[167] - rop[168] - rop[169] - rop[170] - rop[172] - rop[174] - rop[175] - rop[178] + rop[180] + rop[187] - rop[193] - rop[194] - rop[205] - rop[215] - rop[219] - rop[225] - rop[258] + rop[286] - rop[289] - rop[290] - rop[293] - rop[294] - rop[297] - rop[305] - rop[306] + rop[322];
|
||||
wdot[4] = + rop[1] + rop[2] + rop[3] + rop[4] + rop[10] + rop[12] + rop[14] + rop[15] + rop[16] + rop[17] + rop[18] + rop[21] + rop[26] + rop[28] + rop[37] - rop[42] + 2*rop[45] + rop[47] + rop[60] + rop[65] - rop[83] - 2*rop[84] - 2*rop[85] - rop[86] - rop[87] - rop[88] - rop[89] - rop[90] - rop[91] - rop[92] - rop[93] - rop[94] - rop[95] - rop[96] - rop[97] - rop[98] - rop[99] - rop[100] - rop[101] - rop[102] - rop[103] - rop[104] - rop[105] - rop[106] - rop[107] - rop[108] - rop[109] - rop[110] - rop[111] - rop[112] - rop[113] + rop[116] + rop[118] + rop[119] + rop[134] + rop[143] + rop[155] + rop[175] - rop[179] + rop[182] - rop[183] + rop[185] + rop[188] - rop[191] - rop[192] + rop[194] + rop[197] + rop[199] - rop[202] + rop[206] - rop[209] + rop[212] - rop[214] - rop[217] + rop[218] - rop[223] + rop[232] - rop[233] - rop[234] - rop[235] + rop[249] + rop[252] + rop[255] - rop[259] + rop[263] - rop[266] - rop[267] + rop[270] - rop[277] + rop[278] - rop[286] - rop[287] + rop[295] + rop[296] - rop[300] + rop[305] + rop[306] - rop[309] - rop[310] + rop[312] - rop[314] - rop[321] + rop[323];
|
||||
wdot[5] = + rop[42] + rop[43] + rop[47] + rop[61] + rop[66] + rop[83] + rop[85] + rop[86] + rop[87] + rop[88] + rop[92] + rop[95] + rop[96] + rop[97] + rop[99] + rop[100] + rop[101] + rop[102] + rop[103] + rop[104] + rop[108] + rop[110] + rop[111] + rop[112] + rop[113] - rop[126] + rop[144] - rop[146] + rop[192] - rop[196] + rop[202] + rop[209] + rop[214] - rop[218] + rop[254] + rop[266] + rop[277] + rop[286] - rop[292] + rop[300] + rop[309] + rop[314];
|
||||
wdot[6] = - rop[3] + rop[4] + rop[31] + rop[32] + rop[33] + rop[34] + rop[35] + rop[36] - rop[43] - rop[44] - rop[45] + rop[46] - rop[86] + rop[87] + rop[88] - 2*rop[114] - 2*rop[115] - rop[116] - rop[117] - rop[118] - rop[119] - rop[120] + rop[156] + rop[167] + rop[168] + rop[169] + rop[174] + rop[183] - rop[185] + rop[205] + rop[215] - rop[286] + rop[294] + rop[297] - rop[301] + rop[315] - rop[322] - rop[323];
|
||||
wdot[7] = - rop[4] - rop[46] - rop[47] + rop[84] - rop[87] - rop[88] + rop[114] + rop[115] + rop[120] - rop[156] + rop[301] - rop[315];
|
||||
wdot[8] = + rop[48] - rop[89] - rop[121] - rop[122] - rop[123] - rop[238] - rop[243] - rop[244];
|
||||
wdot[9] = - rop[5] + rop[19] - rop[48] + rop[50] - rop[90] + rop[92] - rop[124] - rop[125] - rop[126] - rop[127] - rop[128] - rop[129] - rop[130] - rop[131] - rop[132] - rop[133] - rop[239] - rop[240] - rop[245] - rop[246] - rop[247] - rop[288];
|
||||
wdot[10] = - rop[6] + rop[22] + rop[29] - rop[49] - rop[91] - rop[92] + rop[95] - rop[116] - rop[122] + rop[125] - rop[127] - rop[134] - rop[135] - 2*rop[136] - rop[137] - rop[138] - rop[139] - rop[140] + rop[141] + rop[142] + rop[147] + rop[150] + rop[151] + rop[237] - rop[241] - rop[248] - rop[249] - rop[250] + rop[260] - rop[289] - rop[290] - 2*rop[291] + rop[304];
|
||||
wdot[11] = - rop[7] - rop[8] - rop[50] + rop[61] + rop[66] + rop[78] - rop[93] + rop[96] - rop[141] - rop[142] - rop[143] - rop[144] - rop[145] - rop[146] - rop[147] - rop[148] - rop[149] - rop[150] - rop[151] - rop[152] - rop[153] - rop[242] - rop[251] - rop[252] - rop[253] - rop[292];
|
||||
wdot[12] = - rop[9] + rop[10] + rop[24] + rop[25] + rop[49] - rop[51] + rop[52] + rop[60] + rop[65] + rop[80] - rop[94] - rop[95] - rop[96] + rop[97] + rop[109] - rop[117] - rop[118] - rop[123] - rop[128] + rop[135] - rop[137] + 2*rop[138] + rop[145] - rop[148] + 2*rop[149] + rop[153] - rop[154] - rop[155] - rop[156] - 2*rop[157] - 2*rop[158] - rop[159] - rop[160] - rop[161] - rop[162] - rop[163] - rop[164] - rop[210] - rop[254] - rop[255] - rop[274] - rop[275] - rop[283] - rop[287] + rop[288] + rop[296] + rop[297] + rop[299] + rop[300] + rop[301] + rop[307] - rop[311] - rop[316] - rop[317] + rop[320] - rop[324];
|
||||
wdot[13] = - rop[10] + rop[51] - rop[52] - rop[97] + rop[117] - rop[129] - rop[138] - rop[149] + rop[156] + rop[159] + rop[160] + rop[161] + rop[162] + rop[163] + rop[164] + rop[210] + rop[302] + rop[316];
|
||||
wdot[14] = + rop[5] + rop[7] - rop[11] + rop[12] + rop[19] + rop[22] + 2*rop[27] - rop[30] + rop[54] + rop[78] + rop[80] - rop[82] + rop[89] - rop[98] + rop[99] + rop[109] - rop[119] + rop[121] - rop[130] + rop[131] + rop[133] + rop[134] - rop[139] + rop[140] + rop[143] + rop[144] + rop[152] + rop[159] + rop[165] + rop[166] + rop[167] + rop[170] + 2*rop[175] + 2*rop[176] + rop[216] + rop[221] + rop[222] + rop[223] + rop[224] + rop[226] + rop[227] + rop[231] + rop[235] + rop[244] + rop[256] + rop[262] + rop[264] + rop[268] + rop[271] + rop[273] + rop[279] + rop[282] + rop[283] + rop[296] + rop[297] + rop[299] + rop[300] + rop[301] + rop[302] + rop[305];
|
||||
wdot[15] = + rop[11] + rop[13] + rop[29] + rop[30] + rop[98] + rop[119] - rop[131] - rop[152] + rop[225] + rop[228] + rop[261] + rop[267] - rop[279] + rop[281] - rop[282] + rop[289] + rop[304];
|
||||
wdot[16] = + rop[6] + rop[8] - rop[12] - rop[13] + rop[14] + rop[24] + rop[31] - rop[53] - rop[54] + rop[57] + rop[90] - rop[99] + rop[100] + rop[120] + rop[124] + rop[131] - rop[159] + rop[160] - rop[165] - rop[166] - rop[167] + rop[170] + rop[172] + rop[247] + rop[258] + rop[259] + 2*rop[306] + rop[307] + rop[310];
|
||||
wdot[17] = + rop[9] - rop[14] + rop[15] + rop[16] + rop[25] - rop[31] + rop[53] - rop[55] - rop[56] - rop[57] + rop[59] + rop[64] + rop[82] + rop[91] + rop[93] - rop[100] + rop[101] + rop[102] + rop[116] - rop[120] + rop[126] - rop[132] + rop[152] + rop[155] - rop[160] + rop[168] + rop[169] + rop[172] + rop[287] + rop[290] + rop[292] + rop[305] + rop[318] + rop[323];
|
||||
wdot[18] = - rop[15] + rop[17] + rop[55] - rop[58] - rop[59] - rop[60] - rop[61] + rop[63] + rop[67] - rop[101] + rop[103] + rop[161] - rop[168] + rop[310] + rop[321];
|
||||
wdot[19] = - rop[16] + rop[18] + rop[56] - rop[62] - rop[63] - rop[64] - rop[65] - rop[66] + rop[68] - rop[102] + rop[104] + rop[118] + rop[154] + rop[162] - rop[169];
|
||||
wdot[20] = - rop[17] - rop[18] + rop[58] + rop[62] - rop[67] - rop[68] + rop[94] - rop[103] - rop[104] + rop[146] - rop[161] - rop[162];
|
||||
wdot[21] = - rop[19] + rop[21] - rop[69] - rop[105] + rop[108] + rop[122] - rop[170] - rop[171];
|
||||
wdot[22] = - rop[20] - rop[21] - rop[22] + rop[69] - rop[70] + rop[72] - rop[106] - rop[107] - rop[108] - rop[109] + rop[110] + rop[123] + rop[127] + rop[133] + rop[136] + rop[171] + rop[173] + rop[176] + rop[291] + rop[294];
|
||||
wdot[23] = - rop[23] + rop[70] - rop[71] - rop[72] + rop[74] - rop[110] + rop[111] + rop[128] + rop[140] + rop[163] - rop[172] - rop[293] - rop[294];
|
||||
wdot[24] = - rop[24] + rop[71] - rop[73] - rop[74] + rop[76] - rop[111] + rop[129] + rop[137] + rop[148] - rop[163] - rop[173] + rop[174] - rop[284] - rop[317];
|
||||
wdot[25] = - rop[25] + rop[26] + rop[73] - rop[75] - rop[76] + rop[77] + rop[112] + rop[153] + rop[158] + rop[164] - rop[174] - rop[285] - rop[311] + rop[318] + rop[320] + rop[321] + rop[323] + 2*rop[324];
|
||||
wdot[26] = - rop[26] + rop[75] - rop[77] - rop[112] - rop[153] + rop[157] - rop[164];
|
||||
wdot[27] = + rop[20] - rop[27] + rop[28] - rop[78] + rop[79] + rop[105] + rop[113] + rop[130] - rop[133] - rop[140] - rop[175] - 2*rop[176] - rop[273];
|
||||
wdot[28] = + rop[23] - rop[28] - rop[29] - rop[79] - rop[80] + rop[81] + rop[106] - rop[113] + rop[132] + rop[139] - rop[303] + rop[308] + rop[309];
|
||||
wdot[29] = - rop[81] + rop[107];
|
||||
wdot[30] = - rop[177] - rop[178] - rop[179] + rop[190] + rop[192] - rop[195] + rop[216] - rop[224] + rop[226] - rop[237] + rop[238] + rop[239] + rop[244] + rop[247] - rop[274] - rop[275] - rop[282];
|
||||
wdot[31] = - rop[189] - rop[190] - rop[191] - rop[192] - rop[193] - rop[194] - rop[195] - rop[196] - rop[197] - rop[198] + rop[199] + rop[201] + rop[202] + rop[207] + rop[222] + rop[231] + rop[241] + rop[242] + rop[261] + rop[268] - rop[279];
|
||||
wdot[32] = - rop[199] - rop[200] - rop[201] - rop[202] + rop[235] + rop[264] + rop[267] + rop[271] + rop[276] + rop[277] + rop[278];
|
||||
wdot[33] = - rop[276] - rop[277] - rop[278];
|
||||
wdot[34] = - rop[203] - rop[204] - rop[205] - rop[206] - rop[207] - rop[208] - rop[209] - rop[210];
|
||||
wdot[35] = - rop[177] + rop[178] + rop[179] + 2*rop[181] - rop[185] - rop[186] + rop[187] + rop[188] + rop[189] + rop[194] - rop[197] - rop[198] + rop[207] - rop[211] + rop[212] + rop[213] + rop[214] + rop[215] + rop[221] + rop[223] + rop[225] - rop[227] - rop[228] - rop[243] - rop[244] - rop[245] - rop[246] - rop[247] - rop[248] - rop[249] - rop[250] - rop[251] - rop[252] - rop[253] - rop[254] - rop[255] + rop[257] - rop[273] + rop[280] + rop[282];
|
||||
wdot[36] = + rop[185] + rop[186] - rop[187] - rop[188] - rop[280] - rop[281];
|
||||
wdot[37] = - rop[180] - rop[181] - rop[182] - rop[183] - rop[184] + rop[198] + rop[227] + rop[281];
|
||||
wdot[38] = + rop[191] + rop[193] + rop[196] + rop[200] + rop[211] - rop[212] - rop[213] - rop[214] - rop[215] + rop[262] + rop[279];
|
||||
wdot[39] = - rop[216] - rop[217] - rop[218] - rop[219] - rop[220] + rop[229] + rop[232] + rop[238] + rop[243] - rop[280];
|
||||
wdot[40] = + rop[218] + rop[220] - rop[229] - rop[230] - rop[231] - rop[232] - rop[233] - rop[234] - rop[235] - rop[236] + rop[239] + rop[241] + rop[242] + rop[245] + rop[249] + rop[252] + rop[254] + rop[257] + rop[270] + rop[275];
|
||||
wdot[41] = + rop[236] - rop[237] + rop[255] + rop[274];
|
||||
wdot[42] = + rop[240] - rop[256] - rop[257] - rop[258] - rop[259] - rop[260];
|
||||
wdot[43] = + rop[250] + rop[253] - rop[269] - rop[270] - rop[271] + rop[273];
|
||||
wdot[44] = + rop[233] - rop[272];
|
||||
wdot[45] = + rop[234] + rop[248] + rop[251] - rop[261] - rop[262] - rop[263] - rop[264] - rop[265] - rop[266] - rop[267] - rop[268] + rop[269] + rop[272];
|
||||
wdot[46] = + rop[217] + rop[219] - rop[221] - rop[222] - rop[223] - rop[224] - rop[225] - rop[226] - rop[227] - rop[228] + rop[230] + rop[246] + rop[263] + rop[265] + rop[266] + rop[280] - rop[281];
|
||||
wdot[47] = + rop[177] + rop[180] + rop[182] + rop[183] + rop[184] + rop[195] + rop[197] + rop[203] + rop[204] + rop[205] + rop[206] + rop[208] + rop[209] + rop[210] + rop[224] + rop[228] + rop[237] - rop[238] - rop[239] - rop[240] - rop[241] - rop[242] + rop[256] + rop[258] + rop[259] + rop[260];
|
||||
wdot[48] = 0.0;
|
||||
wdot[49] = + rop[312] + rop[313] + rop[314] - rop[315] + rop[316] + rop[317] - rop[318] - rop[319] - rop[320] - rop[321] - rop[322] - rop[323] - rop[324];
|
||||
wdot[50] = + rop[311] - rop[312] - rop[313] - rop[314] + rop[315] - rop[316] + rop[319] + rop[322];
|
||||
wdot[51] = + rop[284] + rop[293] + rop[295] + rop[298] + rop[303] - rop[304] - rop[305] - rop[306] - rop[307] - rop[308] - rop[309] - rop[310];
|
||||
wdot[52] = + rop[285] - rop[295] - rop[296] - rop[297] - rop[298] - rop[299] - rop[300] - rop[301] - rop[302];
|
||||
}
|
||||
|
||||
|
||||
void GRI_30_Kinetics::eval_ropnet(const double* c, const double* rf, const double* rkc, double* r) {
|
||||
r[0] = rf[0] * (c[2] * c[2] - rkc[0] * c[3]);
|
||||
r[1] = rf[1] * (c[2] * c[1] - rkc[1] * c[4]);
|
||||
r[2] = rf[2] * (c[2] * c[0] - rkc[2] * c[1] * c[4]);
|
||||
r[3] = rf[3] * (c[2] * c[6] - rkc[3] * c[4] * c[3]);
|
||||
r[4] = rf[4] * (c[2] * c[7] - rkc[4] * c[4] * c[6]);
|
||||
r[5] = rf[5] * (c[2] * c[9] - rkc[5] * c[1] * c[14]);
|
||||
r[6] = rf[6] * (c[2] * c[10] - rkc[6] * c[1] * c[16]);
|
||||
r[7] = rf[7] * (c[2] * c[11] - rkc[7] * c[0] * c[14]);
|
||||
r[8] = rf[8] * (c[2] * c[11] - rkc[8] * c[1] * c[16]);
|
||||
r[9] = rf[9] * (c[2] * c[12] - rkc[9] * c[1] * c[17]);
|
||||
r[10] = rf[10] * (c[2] * c[13] - rkc[10] * c[4] * c[12]);
|
||||
r[11] = rf[11] * (c[2] * c[14] - rkc[11] * c[15]);
|
||||
r[12] = rf[12] * (c[2] * c[16] - rkc[12] * c[4] * c[14]);
|
||||
r[13] = rf[13] * (c[2] * c[16] - rkc[13] * c[1] * c[15]);
|
||||
r[14] = rf[14] * (c[2] * c[17] - rkc[14] * c[4] * c[16]);
|
||||
r[15] = rf[15] * (c[2] * c[18] - rkc[15] * c[4] * c[17]);
|
||||
r[16] = rf[16] * (c[2] * c[19] - rkc[16] * c[4] * c[17]);
|
||||
r[17] = rf[17] * (c[2] * c[20] - rkc[17] * c[4] * c[18]);
|
||||
r[18] = rf[18] * (c[2] * c[20] - rkc[18] * c[4] * c[19]);
|
||||
r[19] = rf[19] * (c[2] * c[21] - rkc[19] * c[9] * c[14]);
|
||||
r[20] = rf[20] * (c[2] * c[22] - rkc[20] * c[1] * c[27]);
|
||||
r[21] = rf[21] * (c[2] * c[22] - rkc[21] * c[4] * c[21]);
|
||||
r[22] = rf[22] * (c[2] * c[22] - rkc[22] * c[14] * c[10]);
|
||||
r[23] = rf[23] * (c[2] * c[23] - rkc[23] * c[1] * c[28]);
|
||||
r[24] = rf[24] * (c[2] * c[24] - rkc[24] * c[12] * c[16]);
|
||||
r[25] = rf[25] * (c[2] * c[25] - rkc[25] * c[12] * c[17]);
|
||||
r[26] = rf[26] * (c[2] * c[26] - rkc[26] * c[4] * c[25]);
|
||||
r[27] = rf[27] * (c[2] * c[27] - rkc[27] * c[1] * c[14] * c[14]);
|
||||
r[28] = rf[28] * (c[2] * c[28] - rkc[28] * c[4] * c[27]);
|
||||
r[29] = rf[29] * (c[2] * c[28] - rkc[29] * c[10] * c[15]);
|
||||
r[30] = rf[30] * (c[3] * c[14] - rkc[30] * c[2] * c[15]);
|
||||
r[31] = rf[31] * (c[3] * c[17] - rkc[31] * c[6] * c[16]);
|
||||
r[32] = rf[32] * (c[1] * c[3] - rkc[32] * c[6]);
|
||||
r[33] = rf[33] * (c[1] * c[3] * c[3] - rkc[33] * c[6] * c[3]);
|
||||
r[34] = rf[34] * (c[1] * c[3] * c[5] - rkc[34] * c[6] * c[5]);
|
||||
r[35] = rf[35] * (c[1] * c[3] * c[47] - rkc[35] * c[6] * c[47]);
|
||||
r[36] = rf[36] * (c[1] * c[3] * c[48] - rkc[36] * c[6] * c[48]);
|
||||
r[37] = rf[37] * (c[1] * c[3] - rkc[37] * c[2] * c[4]);
|
||||
r[38] = rf[38] * (c[1] * c[1] - rkc[38] * c[0]);
|
||||
r[39] = rf[39] * (c[1] * c[1] * c[0] - rkc[39] * c[0] * c[0]);
|
||||
r[40] = rf[40] * (c[1] * c[1] * c[5] - rkc[40] * c[0] * c[5]);
|
||||
r[41] = rf[41] * (c[1] * c[1] * c[15] - rkc[41] * c[0] * c[15]);
|
||||
r[42] = rf[42] * (c[1] * c[4] - rkc[42] * c[5]);
|
||||
r[43] = rf[43] * (c[1] * c[6] - rkc[43] * c[2] * c[5]);
|
||||
r[44] = rf[44] * (c[1] * c[6] - rkc[44] * c[3] * c[0]);
|
||||
r[45] = rf[45] * (c[1] * c[6] - rkc[45] * c[4] * c[4]);
|
||||
r[46] = rf[46] * (c[1] * c[7] - rkc[46] * c[6] * c[0]);
|
||||
r[47] = rf[47] * (c[1] * c[7] - rkc[47] * c[4] * c[5]);
|
||||
r[48] = rf[48] * (c[1] * c[9] - rkc[48] * c[8] * c[0]);
|
||||
r[49] = rf[49] * (c[1] * c[10] - rkc[49] * c[12]);
|
||||
r[50] = rf[50] * (c[1] * c[11] - rkc[50] * c[9] * c[0]);
|
||||
r[51] = rf[51] * (c[1] * c[12] - rkc[51] * c[13]);
|
||||
r[52] = rf[52] * (c[1] * c[13] - rkc[52] * c[12] * c[0]);
|
||||
r[53] = rf[53] * (c[1] * c[16] - rkc[53] * c[17]);
|
||||
r[54] = rf[54] * (c[1] * c[16] - rkc[54] * c[0] * c[14]);
|
||||
r[55] = rf[55] * (c[1] * c[17] - rkc[55] * c[18]);
|
||||
r[56] = rf[56] * (c[1] * c[17] - rkc[56] * c[19]);
|
||||
r[57] = rf[57] * (c[1] * c[17] - rkc[57] * c[16] * c[0]);
|
||||
r[58] = rf[58] * (c[1] * c[18] - rkc[58] * c[20]);
|
||||
r[59] = rf[59] * (c[1] * c[18] - rkc[59] * c[0] * c[17]);
|
||||
r[60] = rf[60] * (c[1] * c[18] - rkc[60] * c[4] * c[12]);
|
||||
r[61] = rf[61] * (c[1] * c[18] - rkc[61] * c[11] * c[5]);
|
||||
r[62] = rf[62] * (c[1] * c[19] - rkc[62] * c[20]);
|
||||
r[63] = rf[63] * (c[1] * c[19] - rkc[63] * c[1] * c[18]);
|
||||
r[64] = rf[64] * (c[1] * c[19] - rkc[64] * c[0] * c[17]);
|
||||
r[65] = rf[65] * (c[1] * c[19] - rkc[65] * c[4] * c[12]);
|
||||
r[66] = rf[66] * (c[1] * c[19] - rkc[66] * c[11] * c[5]);
|
||||
r[67] = rf[67] * (c[1] * c[20] - rkc[67] * c[18] * c[0]);
|
||||
r[68] = rf[68] * (c[1] * c[20] - rkc[68] * c[19] * c[0]);
|
||||
r[69] = rf[69] * (c[1] * c[21] - rkc[69] * c[22]);
|
||||
r[70] = rf[70] * (c[1] * c[22] - rkc[70] * c[23]);
|
||||
r[71] = rf[71] * (c[1] * c[23] - rkc[71] * c[24]);
|
||||
r[72] = rf[72] * (c[1] * c[23] - rkc[72] * c[0] * c[22]);
|
||||
r[73] = rf[73] * (c[1] * c[24] - rkc[73] * c[25]);
|
||||
r[74] = rf[74] * (c[1] * c[24] - rkc[74] * c[23] * c[0]);
|
||||
r[75] = rf[75] * (c[1] * c[25] - rkc[75] * c[26]);
|
||||
r[76] = rf[76] * (c[1] * c[25] - rkc[76] * c[0] * c[24]);
|
||||
r[77] = rf[77] * (c[1] * c[26] - rkc[77] * c[25] * c[0]);
|
||||
r[78] = rf[78] * (c[1] * c[27] - rkc[78] * c[11] * c[14]);
|
||||
r[79] = rf[79] * (c[1] * c[28] - rkc[79] * c[27] * c[0]);
|
||||
r[80] = rf[80] * (c[1] * c[28] - rkc[80] * c[12] * c[14]);
|
||||
r[81] = rf[81] * (c[1] * c[29] - rkc[81] * c[1] * c[28]);
|
||||
r[82] = rf[82] * (c[0] * c[14] - rkc[82] * c[17]);
|
||||
r[83] = rf[83] * (c[4] * c[0] - rkc[83] * c[1] * c[5]);
|
||||
r[84] = rf[84] * (c[4] * c[4] - rkc[84] * c[7]);
|
||||
r[85] = rf[85] * (c[4] * c[4] - rkc[85] * c[2] * c[5]);
|
||||
r[86] = rf[86] * (c[4] * c[6] - rkc[86] * c[3] * c[5]);
|
||||
r[87] = rf[87] * (c[4] * c[7] - rkc[87] * c[6] * c[5]);
|
||||
r[88] = rf[88] * (c[4] * c[7] - rkc[88] * c[6] * c[5]);
|
||||
r[89] = rf[89] * (c[4] * c[8] - rkc[89] * c[1] * c[14]);
|
||||
r[90] = rf[90] * (c[4] * c[9] - rkc[90] * c[1] * c[16]);
|
||||
r[91] = rf[91] * (c[4] * c[10] - rkc[91] * c[1] * c[17]);
|
||||
r[92] = rf[92] * (c[4] * c[10] - rkc[92] * c[9] * c[5]);
|
||||
r[93] = rf[93] * (c[4] * c[11] - rkc[93] * c[1] * c[17]);
|
||||
r[94] = rf[94] * (c[4] * c[12] - rkc[94] * c[20]);
|
||||
r[95] = rf[95] * (c[4] * c[12] - rkc[95] * c[10] * c[5]);
|
||||
r[96] = rf[96] * (c[4] * c[12] - rkc[96] * c[11] * c[5]);
|
||||
r[97] = rf[97] * (c[4] * c[13] - rkc[97] * c[12] * c[5]);
|
||||
r[98] = rf[98] * (c[4] * c[14] - rkc[98] * c[1] * c[15]);
|
||||
r[99] = rf[99] * (c[4] * c[16] - rkc[99] * c[5] * c[14]);
|
||||
r[100] = rf[100] * (c[4] * c[17] - rkc[100] * c[16] * c[5]);
|
||||
r[101] = rf[101] * (c[4] * c[18] - rkc[101] * c[5] * c[17]);
|
||||
r[102] = rf[102] * (c[4] * c[19] - rkc[102] * c[5] * c[17]);
|
||||
r[103] = rf[103] * (c[4] * c[20] - rkc[103] * c[18] * c[5]);
|
||||
r[104] = rf[104] * (c[4] * c[20] - rkc[104] * c[19] * c[5]);
|
||||
r[105] = rf[105] * (c[4] * c[21] - rkc[105] * c[1] * c[27]);
|
||||
r[106] = rf[106] * (c[4] * c[22] - rkc[106] * c[1] * c[28]);
|
||||
r[107] = rf[107] * (c[4] * c[22] - rkc[107] * c[1] * c[29]);
|
||||
r[108] = rf[108] * (c[4] * c[22] - rkc[108] * c[21] * c[5]);
|
||||
r[109] = rf[109] * (c[4] * c[22] - rkc[109] * c[12] * c[14]);
|
||||
r[110] = rf[110] * (c[4] * c[23] - rkc[110] * c[5] * c[22]);
|
||||
r[111] = rf[111] * (c[4] * c[24] - rkc[111] * c[23] * c[5]);
|
||||
r[112] = rf[112] * (c[4] * c[26] - rkc[112] * c[25] * c[5]);
|
||||
r[113] = rf[113] * (c[4] * c[28] - rkc[113] * c[27] * c[5]);
|
||||
r[114] = rf[114] * (c[6] * c[6] - rkc[114] * c[3] * c[7]);
|
||||
r[115] = rf[115] * (c[6] * c[6] - rkc[115] * c[3] * c[7]);
|
||||
r[116] = rf[116] * (c[6] * c[10] - rkc[116] * c[4] * c[17]);
|
||||
r[117] = rf[117] * (c[6] * c[12] - rkc[117] * c[3] * c[13]);
|
||||
r[118] = rf[118] * (c[6] * c[12] - rkc[118] * c[4] * c[19]);
|
||||
r[119] = rf[119] * (c[6] * c[14] - rkc[119] * c[4] * c[15]);
|
||||
r[120] = rf[120] * (c[6] * c[17] - rkc[120] * c[16] * c[7]);
|
||||
r[121] = rf[121] * (c[8] * c[3] - rkc[121] * c[2] * c[14]);
|
||||
r[122] = rf[122] * (c[8] * c[10] - rkc[122] * c[1] * c[21]);
|
||||
r[123] = rf[123] * (c[8] * c[12] - rkc[123] * c[1] * c[22]);
|
||||
r[124] = rf[124] * (c[9] * c[3] - rkc[124] * c[2] * c[16]);
|
||||
r[125] = rf[125] * (c[9] * c[0] - rkc[125] * c[1] * c[10]);
|
||||
r[126] = rf[126] * (c[9] * c[5] - rkc[126] * c[1] * c[17]);
|
||||
r[127] = rf[127] * (c[9] * c[10] - rkc[127] * c[1] * c[22]);
|
||||
r[128] = rf[128] * (c[9] * c[12] - rkc[128] * c[1] * c[23]);
|
||||
r[129] = rf[129] * (c[9] * c[13] - rkc[129] * c[1] * c[24]);
|
||||
r[130] = rf[130] * (c[9] * c[14] - rkc[130] * c[27]);
|
||||
r[131] = rf[131] * (c[9] * c[15] - rkc[131] * c[16] * c[14]);
|
||||
r[132] = rf[132] * (c[9] * c[17] - rkc[132] * c[1] * c[28]);
|
||||
r[133] = rf[133] * (c[9] * c[27] - rkc[133] * c[14] * c[22]);
|
||||
r[134] = rf[134] * (c[10] * c[3]);
|
||||
r[135] = rf[135] * (c[10] * c[0] - rkc[135] * c[1] * c[12]);
|
||||
r[136] = rf[136] * (c[10] * c[10] - rkc[136] * c[0] * c[22]);
|
||||
r[137] = rf[137] * (c[10] * c[12] - rkc[137] * c[1] * c[24]);
|
||||
r[138] = rf[138] * (c[10] * c[13] - rkc[138] * c[12] * c[12]);
|
||||
r[139] = rf[139] * (c[10] * c[14] - rkc[139] * c[28]);
|
||||
r[140] = rf[140] * (c[10] * c[27] - rkc[140] * c[23] * c[14]);
|
||||
r[141] = rf[141] * (c[11] * c[47] - rkc[141] * c[10] * c[47]);
|
||||
r[142] = rf[142] * (c[11] * c[48] - rkc[142] * c[10] * c[48]);
|
||||
r[143] = rf[143] * (c[11] * c[3] - rkc[143] * c[1] * c[4] * c[14]);
|
||||
r[144] = rf[144] * (c[11] * c[3] - rkc[144] * c[14] * c[5]);
|
||||
r[145] = rf[145] * (c[11] * c[0] - rkc[145] * c[12] * c[1]);
|
||||
r[146] = rf[146] * (c[11] * c[5] - rkc[146] * c[20]);
|
||||
r[147] = rf[147] * (c[11] * c[5] - rkc[147] * c[10] * c[5]);
|
||||
r[148] = rf[148] * (c[11] * c[12] - rkc[148] * c[1] * c[24]);
|
||||
r[149] = rf[149] * (c[11] * c[13] - rkc[149] * c[12] * c[12]);
|
||||
r[150] = rf[150] * (c[11] * c[14] - rkc[150] * c[10] * c[14]);
|
||||
r[151] = rf[151] * (c[11] * c[15] - rkc[151] * c[10] * c[15]);
|
||||
r[152] = rf[152] * (c[11] * c[15] - rkc[152] * c[14] * c[17]);
|
||||
r[153] = rf[153] * (c[11] * c[26] - rkc[153] * c[12] * c[25]);
|
||||
r[154] = rf[154] * (c[12] * c[3] - rkc[154] * c[2] * c[19]);
|
||||
r[155] = rf[155] * (c[12] * c[3] - rkc[155] * c[4] * c[17]);
|
||||
r[156] = rf[156] * (c[12] * c[7] - rkc[156] * c[6] * c[13]);
|
||||
r[157] = rf[157] * (c[12] * c[12] - rkc[157] * c[26]);
|
||||
r[158] = rf[158] * (c[12] * c[12] - rkc[158] * c[1] * c[25]);
|
||||
r[159] = rf[159] * (c[12] * c[16] - rkc[159] * c[13] * c[14]);
|
||||
r[160] = rf[160] * (c[12] * c[17] - rkc[160] * c[16] * c[13]);
|
||||
r[161] = rf[161] * (c[12] * c[20] - rkc[161] * c[18] * c[13]);
|
||||
r[162] = rf[162] * (c[12] * c[20] - rkc[162] * c[19] * c[13]);
|
||||
r[163] = rf[163] * (c[12] * c[24] - rkc[163] * c[23] * c[13]);
|
||||
r[164] = rf[164] * (c[12] * c[26] - rkc[164] * c[25] * c[13]);
|
||||
r[165] = rf[165] * (c[16] * c[5] - rkc[165] * c[1] * c[14] * c[5]);
|
||||
r[166] = rf[166] * (c[16] - rkc[166] * c[1] * c[14]);
|
||||
r[167] = rf[167] * (c[16] * c[3] - rkc[167] * c[6] * c[14]);
|
||||
r[168] = rf[168] * (c[18] * c[3] - rkc[168] * c[6] * c[17]);
|
||||
r[169] = rf[169] * (c[19] * c[3] - rkc[169] * c[6] * c[17]);
|
||||
r[170] = rf[170] * (c[21] * c[3] - rkc[170] * c[16] * c[14]);
|
||||
r[171] = rf[171] * (c[21] * c[0] - rkc[171] * c[1] * c[22]);
|
||||
r[172] = rf[172] * (c[23] * c[3] - rkc[172] * c[16] * c[17]);
|
||||
r[173] = rf[173] * (c[24] - rkc[173] * c[0] * c[22]);
|
||||
r[174] = rf[174] * (c[25] * c[3] - rkc[174] * c[6] * c[24]);
|
||||
r[175] = rf[175] * (c[27] * c[3] - rkc[175] * c[4] * c[14] * c[14]);
|
||||
r[176] = rf[176] * (c[27] * c[27] - rkc[176] * c[14] * c[14] * c[22]);
|
||||
r[177] = rf[177] * (c[30] * c[35] - rkc[177] * c[47] * c[2]);
|
||||
r[178] = rf[178] * (c[30] * c[3] - rkc[178] * c[35] * c[2]);
|
||||
r[179] = rf[179] * (c[30] * c[4] - rkc[179] * c[35] * c[1]);
|
||||
r[180] = rf[180] * (c[37] * c[2] - rkc[180] * c[47] * c[3]);
|
||||
r[181] = rf[181] * (c[37] * c[2] - rkc[181] * c[35] * c[35]);
|
||||
r[182] = rf[182] * (c[37] * c[1] - rkc[182] * c[47] * c[4]);
|
||||
r[183] = rf[183] * (c[37] * c[4] - rkc[183] * c[47] * c[6]);
|
||||
r[184] = rf[184] * (c[37] - rkc[184] * c[47] * c[2]);
|
||||
r[185] = rf[185] * (c[6] * c[35] - rkc[185] * c[36] * c[4]);
|
||||
r[186] = rf[186] * (c[35] * c[2] - rkc[186] * c[36]);
|
||||
r[187] = rf[187] * (c[36] * c[2] - rkc[187] * c[35] * c[3]);
|
||||
r[188] = rf[188] * (c[36] * c[1] - rkc[188] * c[35] * c[4]);
|
||||
r[189] = rf[189] * (c[31] * c[2] - rkc[189] * c[35] * c[1]);
|
||||
r[190] = rf[190] * (c[31] * c[1] - rkc[190] * c[30] * c[0]);
|
||||
r[191] = rf[191] * (c[31] * c[4] - rkc[191] * c[38] * c[1]);
|
||||
r[192] = rf[192] * (c[31] * c[4] - rkc[192] * c[30] * c[5]);
|
||||
r[193] = rf[193] * (c[31] * c[3] - rkc[193] * c[38] * c[2]);
|
||||
r[194] = rf[194] * (c[31] * c[3] - rkc[194] * c[35] * c[4]);
|
||||
r[195] = rf[195] * (c[31] * c[30] - rkc[195] * c[47] * c[1]);
|
||||
r[196] = rf[196] * (c[31] * c[5] - rkc[196] * c[38] * c[0]);
|
||||
r[197] = rf[197] * (c[31] * c[35] - rkc[197] * c[47] * c[4]);
|
||||
r[198] = rf[198] * (c[31] * c[35] - rkc[198] * c[37] * c[1]);
|
||||
r[199] = rf[199] * (c[32] * c[2] - rkc[199] * c[4] * c[31]);
|
||||
r[200] = rf[200] * (c[32] * c[2] - rkc[200] * c[1] * c[38]);
|
||||
r[201] = rf[201] * (c[32] * c[1] - rkc[201] * c[31] * c[0]);
|
||||
r[202] = rf[202] * (c[32] * c[4] - rkc[202] * c[31] * c[5]);
|
||||
r[203] = rf[203] * (c[34] - rkc[203] * c[47] * c[1]);
|
||||
r[204] = rf[204] * (c[34] - rkc[204] * c[47] * c[1]);
|
||||
r[205] = rf[205] * (c[34] * c[3] - rkc[205] * c[6] * c[47]);
|
||||
r[206] = rf[206] * (c[34] * c[2] - rkc[206] * c[4] * c[47]);
|
||||
r[207] = rf[207] * (c[34] * c[2] - rkc[207] * c[31] * c[35]);
|
||||
r[208] = rf[208] * (c[34] * c[1] - rkc[208] * c[0] * c[47]);
|
||||
r[209] = rf[209] * (c[34] * c[4] - rkc[209] * c[5] * c[47]);
|
||||
r[210] = rf[210] * (c[34] * c[12] - rkc[210] * c[13] * c[47]);
|
||||
r[211] = rf[211] * (c[1] * c[35] - rkc[211] * c[38]);
|
||||
r[212] = rf[212] * (c[38] * c[2] - rkc[212] * c[35] * c[4]);
|
||||
r[213] = rf[213] * (c[38] * c[1] - rkc[213] * c[0] * c[35]);
|
||||
r[214] = rf[214] * (c[38] * c[4] - rkc[214] * c[35] * c[5]);
|
||||
r[215] = rf[215] * (c[38] * c[3] - rkc[215] * c[6] * c[35]);
|
||||
r[216] = rf[216] * (c[39] * c[2] - rkc[216] * c[14] * c[30]);
|
||||
r[217] = rf[217] * (c[39] * c[4] - rkc[217] * c[46] * c[1]);
|
||||
r[218] = rf[218] * (c[39] * c[5] - rkc[218] * c[40] * c[4]);
|
||||
r[219] = rf[219] * (c[39] * c[3] - rkc[219] * c[46] * c[2]);
|
||||
r[220] = rf[220] * (c[39] * c[0] - rkc[220] * c[40] * c[1]);
|
||||
r[221] = rf[221] * (c[46] * c[2] - rkc[221] * c[35] * c[14]);
|
||||
r[222] = rf[222] * (c[46] * c[1] - rkc[222] * c[31] * c[14]);
|
||||
r[223] = rf[223] * (c[46] * c[4] - rkc[223] * c[35] * c[1] * c[14]);
|
||||
r[224] = rf[224] * (c[46] * c[30] - rkc[224] * c[47] * c[14]);
|
||||
r[225] = rf[225] * (c[46] * c[3] - rkc[225] * c[35] * c[15]);
|
||||
r[226] = rf[226] * (c[46] - rkc[226] * c[30] * c[14]);
|
||||
r[227] = rf[227] * (c[46] * c[35] - rkc[227] * c[37] * c[14]);
|
||||
r[228] = rf[228] * (c[46] * c[35] - rkc[228] * c[47] * c[15]);
|
||||
r[229] = rf[229] * (c[40] - rkc[229] * c[1] * c[39]);
|
||||
r[230] = rf[230] * (c[40] * c[2] - rkc[230] * c[46] * c[1]);
|
||||
r[231] = rf[231] * (c[40] * c[2] - rkc[231] * c[31] * c[14]);
|
||||
r[232] = rf[232] * (c[40] * c[2] - rkc[232] * c[39] * c[4]);
|
||||
r[233] = rf[233] * (c[40] * c[4] - rkc[233] * c[44] * c[1]);
|
||||
r[234] = rf[234] * (c[40] * c[4] - rkc[234] * c[45] * c[1]);
|
||||
r[235] = rf[235] * (c[40] * c[4] - rkc[235] * c[32] * c[14]);
|
||||
r[236] = rf[236] * (c[1] * c[40] - rkc[236] * c[41]);
|
||||
r[237] = rf[237] * (c[41] * c[30] - rkc[237] * c[47] * c[10]);
|
||||
r[238] = rf[238] * (c[8] * c[47] - rkc[238] * c[39] * c[30]);
|
||||
r[239] = rf[239] * (c[9] * c[47] - rkc[239] * c[40] * c[30]);
|
||||
r[240] = rf[240] * (c[9] * c[47] - rkc[240] * c[42]);
|
||||
r[241] = rf[241] * (c[10] * c[47] - rkc[241] * c[40] * c[31]);
|
||||
r[242] = rf[242] * (c[11] * c[47] - rkc[242] * c[31] * c[40]);
|
||||
r[243] = rf[243] * (c[8] * c[35] - rkc[243] * c[39] * c[2]);
|
||||
r[244] = rf[244] * (c[8] * c[35] - rkc[244] * c[14] * c[30]);
|
||||
r[245] = rf[245] * (c[9] * c[35] - rkc[245] * c[40] * c[2]);
|
||||
r[246] = rf[246] * (c[9] * c[35] - rkc[246] * c[1] * c[46]);
|
||||
r[247] = rf[247] * (c[9] * c[35] - rkc[247] * c[30] * c[16]);
|
||||
r[248] = rf[248] * (c[10] * c[35] - rkc[248] * c[1] * c[45]);
|
||||
r[249] = rf[249] * (c[10] * c[35] - rkc[249] * c[4] * c[40]);
|
||||
r[250] = rf[250] * (c[10] * c[35] - rkc[250] * c[1] * c[43]);
|
||||
r[251] = rf[251] * (c[11] * c[35] - rkc[251] * c[1] * c[45]);
|
||||
r[252] = rf[252] * (c[11] * c[35] - rkc[252] * c[4] * c[40]);
|
||||
r[253] = rf[253] * (c[11] * c[35] - rkc[253] * c[1] * c[43]);
|
||||
r[254] = rf[254] * (c[12] * c[35] - rkc[254] * c[40] * c[5]);
|
||||
r[255] = rf[255] * (c[12] * c[35] - rkc[255] * c[41] * c[4]);
|
||||
r[256] = rf[256] * (c[42] * c[2] - rkc[256] * c[14] * c[1] * c[47]);
|
||||
r[257] = rf[257] * (c[42] * c[2] - rkc[257] * c[40] * c[35]);
|
||||
r[258] = rf[258] * (c[42] * c[3] - rkc[258] * c[2] * c[16] * c[47]);
|
||||
r[259] = rf[259] * (c[42] * c[4] - rkc[259] * c[1] * c[16] * c[47]);
|
||||
r[260] = rf[260] * (c[42] * c[1] - rkc[260] * c[10] * c[47]);
|
||||
r[261] = rf[261] * (c[45] * c[2] - rkc[261] * c[31] * c[15]);
|
||||
r[262] = rf[262] * (c[45] * c[2] - rkc[262] * c[38] * c[14]);
|
||||
r[263] = rf[263] * (c[45] * c[2] - rkc[263] * c[46] * c[4]);
|
||||
r[264] = rf[264] * (c[45] * c[1] - rkc[264] * c[32] * c[14]);
|
||||
r[265] = rf[265] * (c[45] * c[1] - rkc[265] * c[0] * c[46]);
|
||||
r[266] = rf[266] * (c[45] * c[4] - rkc[266] * c[46] * c[5]);
|
||||
r[267] = rf[267] * (c[45] * c[4] - rkc[267] * c[32] * c[15]);
|
||||
r[268] = rf[268] * (c[45] - rkc[268] * c[31] * c[14]);
|
||||
r[269] = rf[269] * (c[43] * c[1] - rkc[269] * c[1] * c[45]);
|
||||
r[270] = rf[270] * (c[43] * c[1] - rkc[270] * c[4] * c[40]);
|
||||
r[271] = rf[271] * (c[43] * c[1] - rkc[271] * c[32] * c[14]);
|
||||
r[272] = rf[272] * (c[44] * c[1] - rkc[272] * c[1] * c[45]);
|
||||
r[273] = rf[273] * (c[27] * c[35] - rkc[273] * c[43] * c[14]);
|
||||
r[274] = rf[274] * (c[12] * c[30] - rkc[274] * c[41] * c[1]);
|
||||
r[275] = rf[275] * (c[12] * c[30] - rkc[275] * c[40] * c[0]);
|
||||
r[276] = rf[276] * (c[33] * c[1] - rkc[276] * c[32] * c[0]);
|
||||
r[277] = rf[277] * (c[33] * c[4] - rkc[277] * c[32] * c[5]);
|
||||
r[278] = rf[278] * (c[33] * c[2] - rkc[278] * c[32] * c[4]);
|
||||
r[279] = rf[279] * (c[31] * c[15] - rkc[279] * c[38] * c[14]);
|
||||
r[280] = rf[280] * (c[39] * c[36] - rkc[280] * c[46] * c[35]);
|
||||
r[281] = rf[281] * (c[46] * c[36] - rkc[281] * c[37] * c[15]);
|
||||
r[282] = rf[282] * (c[30] * c[15] - rkc[282] * c[35] * c[14]);
|
||||
r[283] = rf[283] * (c[2] * c[12]);
|
||||
r[284] = rf[284] * (c[2] * c[24] - rkc[284] * c[1] * c[51]);
|
||||
r[285] = rf[285] * (c[2] * c[25] - rkc[285] * c[1] * c[52]);
|
||||
r[286] = rf[286] * (c[4] * c[6] - rkc[286] * c[3] * c[5]);
|
||||
r[287] = rf[287] * (c[4] * c[12]);
|
||||
r[288] = rf[288] * (c[9] * c[0] - rkc[288] * c[12]);
|
||||
r[289] = rf[289] * (c[10] * c[3]);
|
||||
r[290] = rf[290] * (c[10] * c[3] - rkc[290] * c[2] * c[17]);
|
||||
r[291] = rf[291] * (c[10] * c[10]);
|
||||
r[292] = rf[292] * (c[11] * c[5]);
|
||||
r[293] = rf[293] * (c[23] * c[3] - rkc[293] * c[2] * c[51]);
|
||||
r[294] = rf[294] * (c[23] * c[3] - rkc[294] * c[6] * c[22]);
|
||||
r[295] = rf[295] * (c[2] * c[52] - rkc[295] * c[4] * c[51]);
|
||||
r[296] = rf[296] * (c[2] * c[52]);
|
||||
r[297] = rf[297] * (c[3] * c[52]);
|
||||
r[298] = rf[298] * (c[1] * c[52] - rkc[298] * c[51] * c[0]);
|
||||
r[299] = rf[299] * (c[1] * c[52]);
|
||||
r[300] = rf[300] * (c[4] * c[52]);
|
||||
r[301] = rf[301] * (c[6] * c[52]);
|
||||
r[302] = rf[302] * (c[12] * c[52]);
|
||||
r[303] = rf[303] * (c[1] * c[28] - rkc[303] * c[51]);
|
||||
r[304] = rf[304] * (c[2] * c[51]);
|
||||
r[305] = rf[305] * (c[3] * c[51]);
|
||||
r[306] = rf[306] * (c[3] * c[51]);
|
||||
r[307] = rf[307] * (c[1] * c[51] - rkc[307] * c[12] * c[16]);
|
||||
r[308] = rf[308] * (c[1] * c[51] - rkc[308] * c[28] * c[0]);
|
||||
r[309] = rf[309] * (c[4] * c[51] - rkc[309] * c[5] * c[28]);
|
||||
r[310] = rf[310] * (c[4] * c[51] - rkc[310] * c[16] * c[18]);
|
||||
r[311] = rf[311] * (c[12] * c[25] - rkc[311] * c[50]);
|
||||
r[312] = rf[312] * (c[2] * c[50] - rkc[312] * c[4] * c[49]);
|
||||
r[313] = rf[313] * (c[1] * c[50] - rkc[313] * c[49] * c[0]);
|
||||
r[314] = rf[314] * (c[4] * c[50] - rkc[314] * c[49] * c[5]);
|
||||
r[315] = rf[315] * (c[49] * c[7] - rkc[315] * c[6] * c[50]);
|
||||
r[316] = rf[316] * (c[12] * c[50] - rkc[316] * c[49] * c[13]);
|
||||
r[317] = rf[317] * (c[12] * c[24] - rkc[317] * c[49]);
|
||||
r[318] = rf[318] * (c[2] * c[49] - rkc[318] * c[25] * c[17]);
|
||||
r[319] = rf[319] * (c[1] * c[49] - rkc[319] * c[50]);
|
||||
r[320] = rf[320] * (c[1] * c[49] - rkc[320] * c[12] * c[25]);
|
||||
r[321] = rf[321] * (c[4] * c[49] - rkc[321] * c[25] * c[18]);
|
||||
r[322] = rf[322] * (c[6] * c[49] - rkc[322] * c[3] * c[50]);
|
||||
r[323] = rf[323] * (c[6] * c[49]);
|
||||
r[324] = rf[324] * (c[12] * c[49] - rkc[324] * c[25] * c[25]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
50
Cantera/src/kinetics/GRI_30_Kinetics.h
Executable file
50
Cantera/src/kinetics/GRI_30_Kinetics.h
Executable file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
*
|
||||
* @file GRI_30_Kinetics.h
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_GRI30_KINETICS_H
|
||||
#define CT_GRI30_KINETICS_H
|
||||
|
||||
#include "GasKinetics.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
const int cGRI_30_Kinetics = cGasKinetics + 1;
|
||||
|
||||
/**
|
||||
* Kinetics manager implementing reaction mechanism GRI-Mech 3.0
|
||||
*/
|
||||
class GRI_30_Kinetics : public GasKinetics {
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
GRI_30_Kinetics(thermo_t* th=0);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~GRI_30_Kinetics(){}
|
||||
|
||||
virtual int ID() { return cGRI_30_Kinetics; }
|
||||
|
||||
virtual void getNetProductionRates(doublereal* net) {
|
||||
gri30_updateROP();
|
||||
get_wdot(&m_kdata->m_ropnet[0], net);
|
||||
}
|
||||
|
||||
private:
|
||||
void gri30_update_rates_T();
|
||||
void gri30_updateROP();
|
||||
void gri30_updateKc();
|
||||
void get_wdot(const doublereal* rop, doublereal* wdot);
|
||||
void update_kc(const double* grt, double c0, double* rkc);
|
||||
void update_rates(double t, double tlog, double* rf);
|
||||
void eval_ropnet(const double* c, const double* rf, const double* rkc, double* r);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
666
Cantera/src/kinetics/GasKinetics.cpp
Executable file
666
Cantera/src/kinetics/GasKinetics.cpp
Executable file
|
|
@ -0,0 +1,666 @@
|
|||
/**
|
||||
* @file GasKinetics.cpp
|
||||
*
|
||||
* Homogeneous kinetics in ideal gases
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
// turn off warnings under Windows
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "GasKinetics.h"
|
||||
|
||||
#include "ReactionData.h"
|
||||
#include "Enhanced3BConc.h"
|
||||
#include "ThirdBodyMgr.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
//#include "../user/grirxnstoich.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
|
||||
/**
|
||||
* Construct an empty reaction mechanism.
|
||||
*/
|
||||
GasKinetics::
|
||||
GasKinetics(thermo_t* thermo) :
|
||||
Kinetics(),
|
||||
m_kk(0),
|
||||
m_nfall(0),
|
||||
m_dt_threshold(0.0), // 1.e-6),
|
||||
m_nirrev(0),
|
||||
m_nrev(0),
|
||||
m_finalized(false)
|
||||
{
|
||||
if (thermo != 0) addPhase(*thermo);
|
||||
m_kdata = new GasKineticsData;
|
||||
m_kdata->m_temp = 0.0;
|
||||
m_rxnstoich = new ReactionStoichMgr;
|
||||
}
|
||||
|
||||
GasKinetics::
|
||||
~GasKinetics() {delete m_kdata; delete m_rxnstoich;}
|
||||
|
||||
/**
|
||||
* Update temperature-dependent portions of reaction rates and
|
||||
* falloff functions.
|
||||
*/
|
||||
void GasKinetics::
|
||||
update_T() {}
|
||||
|
||||
void GasKinetics::
|
||||
update_C() {}
|
||||
|
||||
void GasKinetics::
|
||||
_update_rates_T() {
|
||||
doublereal T = thermo().temperature();
|
||||
m_kdata->m_logStandConc = log(thermo().standardConcentration());
|
||||
if (fabs(T - m_kdata->m_temp) > 0.0) { // m_dt_threshold) {
|
||||
doublereal logT = log(T);
|
||||
//m_kdata->m_logp0 - logT;
|
||||
m_rates.update(T, logT, &m_kdata->m_rfn[0]);
|
||||
m_falloff_low_rates.update(T, logT, &m_kdata->m_rfn_low[0]);
|
||||
m_falloff_high_rates.update(T, logT, &m_kdata->m_rfn_high[0]);
|
||||
m_falloffn.updateTemp(T, &m_kdata->falloff_work[0]);
|
||||
m_kdata->m_temp = T;
|
||||
updateKc();
|
||||
m_kdata->m_ROP_ok = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Update properties that depend on concentrations. Currently only
|
||||
* the enhanced collision partner concentrations are updated here.
|
||||
*/
|
||||
void GasKinetics::
|
||||
_update_rates_C() {
|
||||
thermo().getActivityConcentrations(&m_conc[0]);
|
||||
doublereal ctot = thermo().molarDensity();
|
||||
m_3b_concm.update(m_conc, ctot, &m_kdata->concm_3b_values[0]);
|
||||
m_falloff_concm.update(m_conc, ctot,
|
||||
&m_kdata->concm_falloff_values[0]);
|
||||
m_kdata->m_ROP_ok = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the equilibrium constants in molar units.
|
||||
*/
|
||||
void GasKinetics::updateKc() {
|
||||
int i, irxn;
|
||||
vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
|
||||
thermo().getStandardChemPotentials(&m_grt[0]);
|
||||
fill(m_rkc.begin(), m_rkc.end(), 0.0);
|
||||
|
||||
// compute Delta G^0 for all reversible reactions
|
||||
m_rxnstoich->getRevReactionDelta(m_ii, &m_grt[0], &m_rkc[0]);
|
||||
|
||||
doublereal logStandConc = m_kdata->m_logStandConc;
|
||||
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
|
||||
for (i = 0; i < m_nrev; i++) {
|
||||
irxn = m_revindex[i];
|
||||
m_rkc[irxn] = exp(m_rkc[irxn]*rrt - m_dn[irxn]*logStandConc);
|
||||
}
|
||||
|
||||
for(i = 0; i != m_nirrev; ++i) {
|
||||
m_rkc[ m_irrev[i] ] = 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the equilibrium constants of all reactions, whether
|
||||
* reversible or not.
|
||||
*/
|
||||
void GasKinetics::getEquilibriumConstants(doublereal* kc) {
|
||||
int i;
|
||||
_update_rates_T();
|
||||
vector_fp& rkc = m_kdata->m_rkcn;
|
||||
//thermo().getGibbs_RT(m_grt.begin());
|
||||
thermo().getStandardChemPotentials(&m_grt[0]);
|
||||
fill(rkc.begin(), rkc.end(), 0.0);
|
||||
|
||||
// compute Delta G^0 for all reactions
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], &rkc[0]);
|
||||
|
||||
doublereal logStandConc = m_kdata->m_logStandConc;
|
||||
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
|
||||
for (i = 0; i < m_ii; i++) {
|
||||
kc[i] = exp(-rkc[i]*rrt + m_dn[i]*logStandConc);
|
||||
}
|
||||
|
||||
// force an update of T-dependent properties, so that m_rkcn will
|
||||
// be updated before it is used next.
|
||||
m_kdata->m_temp = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaGibbs():
|
||||
*
|
||||
* Return the vector of values for the reaction gibbs free energy
|
||||
* change
|
||||
* These values depend upon the concentration
|
||||
* of the ideal gas.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void GasKinetics::getDeltaGibbs(doublereal* deltaG) {
|
||||
/*
|
||||
* Get the chemical potentials of the species in the
|
||||
* ideal gas solution.
|
||||
*/
|
||||
thermo().getChemPotentials(&m_grt[0]);
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaG);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaEnthalpy():
|
||||
*
|
||||
* Return the vector of values for the reactions change in
|
||||
* enthalpy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void GasKinetics::getDeltaEnthalpy(doublereal* deltaH) {
|
||||
/*
|
||||
* Get the partial molar enthalpy of all species in the
|
||||
* ideal gas.
|
||||
*/
|
||||
thermo().getPartialMolarEnthalpies(&m_grt[0]);
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaH);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* getDeltaEntropy():
|
||||
*
|
||||
* Return the vector of values for the reactions change in
|
||||
* entropy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
void GasKinetics::getDeltaEntropy( doublereal* deltaS) {
|
||||
/*
|
||||
* Get the partial molar entropy of all species in the
|
||||
* solid solution.
|
||||
*/
|
||||
thermo().getPartialMolarEntropies(&m_grt[0]);
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaS for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaS);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaSSGibbs():
|
||||
*
|
||||
* Return the vector of values for the reaction
|
||||
* standard state gibbs free energy change.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void GasKinetics::getDeltaSSGibbs(doublereal* deltaG) {
|
||||
/*
|
||||
* Get the standard state chemical potentials of the species.
|
||||
* This is the array of chemical potentials at unit activity
|
||||
* We define these here as the chemical potentials of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
thermo().getStandardChemPotentials(&m_grt[0]);
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaG);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaSSEnthalpy():
|
||||
*
|
||||
* Return the vector of values for the change in the
|
||||
* standard state enthalpies of reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void GasKinetics::getDeltaSSEnthalpy(doublereal* deltaH) {
|
||||
/*
|
||||
* Get the standard state enthalpies of the species.
|
||||
* This is the array of chemical potentials at unit activity
|
||||
* We define these here as the enthalpies of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
thermo().getEnthalpy_RT(&m_grt[0]);
|
||||
doublereal RT = thermo().temperature() * GasConstant;
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
m_grt[k] *= RT;
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaH);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* getDeltaSSEntropy():
|
||||
*
|
||||
* Return the vector of values for the change in the
|
||||
* standard state entropies for each reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
void GasKinetics::getDeltaSSEntropy(doublereal* deltaS) {
|
||||
/*
|
||||
* Get the standard state entropy of the species.
|
||||
* We define these here as the entropies of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
thermo().getEntropy_R(&m_grt[0]);
|
||||
doublereal R = GasConstant;
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
m_grt[k] *= R;
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaS for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich->getReactionDelta(m_ii, &m_grt[0], deltaS);
|
||||
}
|
||||
|
||||
void GasKinetics::processFalloffReactions() {
|
||||
|
||||
int i;
|
||||
const vector_fp& fc = m_kdata->concm_falloff_values;
|
||||
const array_fp& m_rf_low = m_kdata->m_rfn_low;
|
||||
const array_fp& m_rf_high = m_kdata->m_rfn_high;
|
||||
|
||||
// use m_ropr for temporary storage of reduced pressure
|
||||
array_fp& pr = m_kdata->m_ropr;
|
||||
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
|
||||
for (i = 0; i < m_nfall; i++) {
|
||||
pr[i] = fc[i] * m_rf_low[i] / m_rf_high[i];
|
||||
}
|
||||
|
||||
m_falloffn.pr_to_falloff( &pr[0], &m_kdata->falloff_work[0] );
|
||||
|
||||
for (i = 0; i < m_nfall; i++) {
|
||||
pr[i] *= m_rf_high[i];
|
||||
}
|
||||
|
||||
scatter_copy(pr.begin(), pr.begin() + m_nfall,
|
||||
ropf.begin(), m_fallindx.begin());
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::updateROP() {
|
||||
|
||||
_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
if (m_kdata->m_ROP_ok) return;
|
||||
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
const vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
array_fp& ropr = m_kdata->m_ropr;
|
||||
array_fp& ropnet = m_kdata->m_ropnet;
|
||||
|
||||
// copy rate coefficients into ropf
|
||||
copy(rf.begin(), rf.end(), ropf.begin());
|
||||
|
||||
// multiply ropf by enhanced 3b conc for all 3b rxns
|
||||
m_3b_concm.multiply( &ropf[0], &m_kdata->concm_3b_values[0] );
|
||||
|
||||
processFalloffReactions();
|
||||
|
||||
// multiply by perturbation factor
|
||||
multiply_each(ropf.begin(), ropf.end(), m_perturb.begin());
|
||||
|
||||
// copy the forward rates to the reverse rates
|
||||
copy(ropf.begin(), ropf.end(), ropr.begin());
|
||||
|
||||
// for reverse rates computed from thermochemistry, multiply
|
||||
// the forward rates copied into m_ropr by the reciprocals of
|
||||
// the equilibrium constants
|
||||
multiply_each(ropr.begin(), ropr.end(), m_rkc.begin());
|
||||
|
||||
// multiply ropf by concentration products
|
||||
m_rxnstoich->multiplyReactants(&m_conc[0], &ropf[0]);
|
||||
//m_reactantStoich.multiply(m_conc.begin(), ropf.begin());
|
||||
|
||||
// for reversible reactions, multiply ropr by concentration
|
||||
// products
|
||||
m_rxnstoich->multiplyRevProducts(&m_conc[0], &ropr[0]);
|
||||
//m_revProductStoich.multiply(m_conc.begin(), ropr.begin());
|
||||
|
||||
for (int j = 0; j != m_ii; ++j) {
|
||||
ropnet[j] = ropf[j] - ropr[j];
|
||||
}
|
||||
|
||||
m_kdata->m_ROP_ok = true;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getFwdRateConstants():
|
||||
*
|
||||
* Update the rate of progress for the reactions.
|
||||
* This key routine makes sure that the rate of progress vectors
|
||||
* located in the solid kinetics data class are up to date.
|
||||
*/
|
||||
void GasKinetics::
|
||||
getFwdRateConstants(doublereal *kfwd) {
|
||||
_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
// copy rate coefficients into ropf
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
copy(rf.begin(), rf.end(), ropf.begin());
|
||||
|
||||
// multiply ropf by enhanced 3b conc for all 3b rxns
|
||||
m_3b_concm.multiply(&ropf[0], &m_kdata->concm_3b_values[0] );
|
||||
|
||||
/*
|
||||
* This routine is hardcoded to replace some of the values
|
||||
* of the ropf vector.
|
||||
*/
|
||||
processFalloffReactions();
|
||||
|
||||
// multiply by perturbation factor
|
||||
multiply_each(ropf.begin(), ropf.end(), m_perturb.begin());
|
||||
|
||||
for (int i = 0; i < m_ii; i++) {
|
||||
kfwd[i] = ropf[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getRevRateConstants():
|
||||
*
|
||||
* Return a vector of the reverse reaction rate constants
|
||||
*
|
||||
* Length is the number of reactions. units depends
|
||||
* on many issues. Note, this routine will return rate constants
|
||||
* for irreversible reactions if the default for
|
||||
* doIrreversible is overridden.
|
||||
*/
|
||||
void GasKinetics::
|
||||
getRevRateConstants(doublereal *krev, bool doIrreversible) {
|
||||
/*
|
||||
* go get the forward rate constants. -> note, we don't
|
||||
* really care about speed or redundancy in these
|
||||
* informational routines.
|
||||
*/
|
||||
getFwdRateConstants(krev);
|
||||
|
||||
if (doIrreversible) {
|
||||
doublereal *tmpKc = &m_kdata->m_ropnet[0];
|
||||
getEquilibriumConstants(tmpKc);
|
||||
for (int i = 0; i < m_ii; i++) {
|
||||
krev[i] /= tmpKc[i];
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* m_rkc[] is zero for irreversibly reactions
|
||||
*/
|
||||
const vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
for (int i = 0; i < m_ii; i++) {
|
||||
krev[i] *= m_rkc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GasKinetics::
|
||||
addReaction(const ReactionData& r) {
|
||||
|
||||
if (r.reactionType == ELEMENTARY_RXN) addElementaryReaction(r);
|
||||
else if (r.reactionType == THREE_BODY_RXN) addThreeBodyReaction(r);
|
||||
else if (r.reactionType == FALLOFF_RXN) addFalloffReaction(r);
|
||||
|
||||
// operations common to all reaction types
|
||||
installReagents( r );
|
||||
installGroups(reactionNumber(), r.rgroups, r.pgroups);
|
||||
incrementRxnCount();
|
||||
m_rxneqn.push_back(r.equation);
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::
|
||||
addFalloffReaction(const ReactionData& r) {
|
||||
|
||||
// install high and low rate coeff calculators
|
||||
|
||||
int iloc = m_falloff_high_rates.install(m_nfall,
|
||||
r.rateCoeffType,
|
||||
r.rateCoeffParameters.size(),
|
||||
&r.rateCoeffParameters[0] );
|
||||
|
||||
m_falloff_low_rates.install( m_nfall,
|
||||
r.rateCoeffType, r.auxRateCoeffParameters.size(),
|
||||
DATA_PTR(r.auxRateCoeffParameters) );
|
||||
|
||||
// add constant terms to high and low rate
|
||||
// coeff value vectors
|
||||
m_kdata->m_rfn_high.push_back(r.rateCoeffParameters[0]);
|
||||
m_kdata->m_rfn_low.push_back(r.auxRateCoeffParameters[0]);
|
||||
|
||||
// add a dummy entry in m_rf, where computed falloff
|
||||
// rate coeff will be put
|
||||
m_kdata->m_rfn.push_back(0.0);
|
||||
|
||||
// add this reaction number to the list of
|
||||
// falloff reactions
|
||||
m_fallindx.push_back( reactionNumber() );
|
||||
|
||||
// install the enhanced third-body concentration
|
||||
// calculator for this reaction
|
||||
m_falloff_concm.install( m_nfall, r.thirdBodyEfficiencies,
|
||||
r.default_3b_eff);
|
||||
|
||||
// install the falloff function calculator for
|
||||
// this reaction
|
||||
m_falloffn.install( m_nfall, r.falloffType, r.falloffParameters );
|
||||
|
||||
// forward rxn order equals number of reactants, since rate
|
||||
// coeff is defined in terms of the high-pressure limit
|
||||
m_fwdOrder.push_back(r.reactants.size());
|
||||
|
||||
// increment the falloff reaction counter
|
||||
++m_nfall;
|
||||
registerReaction( reactionNumber(), FALLOFF_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::
|
||||
addElementaryReaction(const ReactionData& r) {
|
||||
int iloc;
|
||||
|
||||
// install rate coeff calculator
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, r.rateCoeffParameters.size(),
|
||||
DATA_PTR(r.rateCoeffParameters) );
|
||||
|
||||
// add constant term to rate coeff value vector
|
||||
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
|
||||
// forward rxn order equals number of reactants
|
||||
m_fwdOrder.push_back(r.reactants.size());
|
||||
registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::
|
||||
addThreeBodyReaction(const ReactionData& r) {
|
||||
|
||||
int iloc;
|
||||
// install rate coeff calculator
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, r.rateCoeffParameters.size(),
|
||||
DATA_PTR(r.rateCoeffParameters) );
|
||||
|
||||
// add constant term to rate coeff value vector
|
||||
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
|
||||
// forward rxn order equals number of reactants + 1
|
||||
m_fwdOrder.push_back(r.reactants.size() + 1);
|
||||
|
||||
m_3b_concm.install( reactionNumber(), r.thirdBodyEfficiencies,
|
||||
r.default_3b_eff );
|
||||
registerReaction( reactionNumber(), THREE_BODY_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::installReagents(const ReactionData& r) {
|
||||
|
||||
m_kdata->m_ropf.push_back(0.0); // extend by one for new rxn
|
||||
m_kdata->m_ropr.push_back(0.0);
|
||||
m_kdata->m_ropnet.push_back(0.0);
|
||||
int n, ns, m;
|
||||
doublereal nsFlt;
|
||||
doublereal reactantGlobalOrder = 0.0;
|
||||
doublereal productGlobalOrder = 0.0;
|
||||
int rnum = reactionNumber();
|
||||
|
||||
vector_int rk;
|
||||
int nr = r.reactants.size();
|
||||
for (n = 0; n < nr; n++) {
|
||||
nsFlt = r.rstoich[n];
|
||||
reactantGlobalOrder += nsFlt;
|
||||
ns = (int) nsFlt;
|
||||
if ((doublereal) ns != nsFlt) {
|
||||
if (ns < 1) {
|
||||
ns = 1;
|
||||
}
|
||||
}
|
||||
if (r.rstoich[n] != 0.0)
|
||||
m_rrxn[r.reactants[n]][rnum] += r.rstoich[n];
|
||||
for (m = 0; m < ns; m++) {
|
||||
rk.push_back(r.reactants[n]);
|
||||
}
|
||||
}
|
||||
m_reactants.push_back(rk);
|
||||
|
||||
vector_int pk;
|
||||
int np = r.products.size();
|
||||
for (n = 0; n < np; n++) {
|
||||
nsFlt = r.pstoich[n];
|
||||
productGlobalOrder += nsFlt;
|
||||
ns = (int) nsFlt;
|
||||
if ((double) ns != nsFlt) {
|
||||
if (ns < 1) {
|
||||
ns = 1;
|
||||
}
|
||||
}
|
||||
if (r.pstoich[n] != 0.0)
|
||||
m_prxn[r.products[n]][rnum] += r.pstoich[n];
|
||||
for (m = 0; m < ns; m++) {
|
||||
pk.push_back(r.products[n]);
|
||||
}
|
||||
}
|
||||
m_products.push_back(pk);
|
||||
|
||||
m_kdata->m_rkcn.push_back(0.0);
|
||||
|
||||
m_rxnstoich->add(reactionNumber(), r);
|
||||
|
||||
if (r.reversible) {
|
||||
m_dn.push_back(productGlobalOrder - reactantGlobalOrder);
|
||||
m_revindex.push_back(reactionNumber());
|
||||
m_nrev++;
|
||||
}
|
||||
else {
|
||||
m_dn.push_back(productGlobalOrder - reactantGlobalOrder);
|
||||
m_irrev.push_back( reactionNumber() );
|
||||
m_nirrev++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::installGroups(int irxn,
|
||||
const vector<grouplist_t>& r, const vector<grouplist_t>& p) {
|
||||
if (!r.empty()) {
|
||||
writelog("installing groups for reaction "+int2str(reactionNumber()));
|
||||
m_rgroups[reactionNumber()] = r;
|
||||
m_pgroups[reactionNumber()] = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GasKinetics::init() {
|
||||
m_kk = thermo().nSpecies();
|
||||
m_rrxn.resize(m_kk);
|
||||
m_prxn.resize(m_kk);
|
||||
m_conc.resize(m_kk);
|
||||
m_grt.resize(m_kk);
|
||||
m_kdata->m_logp_ref = log(thermo().refPressure()) - log(GasConstant);
|
||||
}
|
||||
|
||||
void GasKinetics::finalize() {
|
||||
if (!m_finalized) {
|
||||
// int i, j, nr, np;
|
||||
m_kdata->falloff_work.resize(
|
||||
static_cast<size_t>(m_falloffn.workSize()));
|
||||
m_kdata->concm_3b_values.resize(
|
||||
static_cast<size_t>(m_3b_concm.workSize()));
|
||||
m_kdata->concm_falloff_values.resize(
|
||||
static_cast<size_t>(m_falloff_concm.workSize()));
|
||||
|
||||
// for (i = 0; i < m_ii; i++) {
|
||||
// nr = m_reactants[i].size();
|
||||
// for (j = 0; j < nr; j++) {
|
||||
// m_rstoich[i][m_reactants[i][j]]++;
|
||||
// }
|
||||
// np = m_products[i].size();
|
||||
// for (j = 0; j < np; j++) {
|
||||
// m_pstoich[i][m_products[i][j]]++;
|
||||
// }
|
||||
// }
|
||||
//m_rxnstoich->write("c.cpp");
|
||||
m_finalized = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool GasKinetics::ready() const {
|
||||
return (m_finalized);
|
||||
}
|
||||
|
||||
}
|
||||
420
Cantera/src/kinetics/GasKinetics.h
Executable file
420
Cantera/src/kinetics/GasKinetics.h
Executable file
|
|
@ -0,0 +1,420 @@
|
|||
/**
|
||||
* @file GasKinetics.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_GASKINETICS_H
|
||||
#define CT_GASKINETICS_H
|
||||
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mix_defs.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
#include "utilities.h"
|
||||
|
||||
#include "ReactionStoichMgr.h"
|
||||
#include "ThirdBodyMgr.h"
|
||||
#include "FalloffMgr.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
void get_wdot(const doublereal* rop, doublereal* wdot);
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
// forward references
|
||||
|
||||
class Enhanced3BConc;
|
||||
class ReactionData;
|
||||
class GasKineticsData;
|
||||
class Thermo;
|
||||
|
||||
/**
|
||||
* Holds mechanism-specific data.
|
||||
*/
|
||||
class GasKineticsData {
|
||||
public:
|
||||
GasKineticsData() :
|
||||
m_logp_ref(0.0),
|
||||
m_logc_ref(0.0),
|
||||
m_logStandConc(0.0),
|
||||
m_ROP_ok(false),
|
||||
m_temp(0.0)
|
||||
{}
|
||||
virtual ~GasKineticsData(){}
|
||||
|
||||
doublereal m_logp_ref, m_logc_ref, m_logStandConc;
|
||||
array_fp m_ropf, m_ropr, m_ropnet;
|
||||
array_fp m_rfn_low, m_rfn_high;
|
||||
bool m_ROP_ok;
|
||||
|
||||
doublereal m_temp;
|
||||
vector_fp m_rfn;
|
||||
vector_fp falloff_work;
|
||||
vector_fp concm_3b_values;
|
||||
vector_fp concm_falloff_values;
|
||||
vector_fp m_rkcn;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Kinetics manager for elementary gas-phase chemistry. This
|
||||
* kinetics manager implements standard mass-action reaction rate
|
||||
* expressions for low-density gases.
|
||||
* @ingroup kinetics
|
||||
*/
|
||||
|
||||
class GasKinetics : public Kinetics {
|
||||
|
||||
public:
|
||||
/**
|
||||
* @name Constructors and General Information about Mechanism
|
||||
*/
|
||||
//@{
|
||||
/// Constructor.
|
||||
GasKinetics(thermo_t* thermo = 0);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~GasKinetics();
|
||||
|
||||
virtual int ID() { return cGasKinetics; }
|
||||
|
||||
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
||||
return m_rrxn[k][i];
|
||||
}
|
||||
|
||||
virtual doublereal productStoichCoeff(int k, int i) const {
|
||||
return m_prxn[k][i];
|
||||
}
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Rates Of Progress
|
||||
*/
|
||||
//@{
|
||||
/**
|
||||
* Forward rates of progress.
|
||||
* Return the forward rates of progress in array fwdROP, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
*/
|
||||
virtual void getFwdRatesOfProgress(doublereal* fwdROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP);
|
||||
}
|
||||
/**
|
||||
* Reverse rates of progress.
|
||||
* Return the reverse rates of progress in array revROP, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
*/
|
||||
virtual void getRevRatesOfProgress(doublereal* revROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropr.begin(), m_kdata->m_ropr.end(), revROP);
|
||||
}
|
||||
/**
|
||||
* Net rates of progress. Return the net (forward - reverse)
|
||||
* rates of progress in array netROP, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* reactions.
|
||||
*/
|
||||
virtual void getNetRatesOfProgress(doublereal* netROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Equilibrium constants. Return the equilibrium constants of
|
||||
* the reactions in concentration units in array kc, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
*/
|
||||
virtual void getEquilibriumConstants(doublereal* kc);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reaction gibbs free energy
|
||||
* change.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaGibbs( doublereal* deltaG);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* enthalpy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaEnthalpy( doublereal* deltaH);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* entropy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
virtual void getDeltaEntropy(doublereal* deltaS);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reaction
|
||||
* standard state gibbs free energy change.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaSSGibbs(doublereal* deltaG);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the
|
||||
* standard state enthalpies of reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaSSEnthalpy(doublereal* deltaH);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the
|
||||
* standard state entropies for each reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
virtual void getDeltaSSEntropy(doublereal* deltaS);
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Species Production Rates
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Species net production rates [kmol/m^3]. Return the species
|
||||
* net production rates (creation - destruction) in array
|
||||
* wdot, which must be dimensioned at least as large as the
|
||||
* total number of species.
|
||||
*/
|
||||
virtual void getNetProductionRates(doublereal* net) {
|
||||
updateROP();
|
||||
#ifdef HWMECH
|
||||
get_wdot(&m_kdata->m_ropnet[0], net);
|
||||
#else
|
||||
m_rxnstoich->getNetProductionRates(m_kk, &m_kdata->m_ropnet[0], net);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Species creation rates [kmol/m^3]. Return the species
|
||||
* creation rates in array cdot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species.
|
||||
*
|
||||
*/
|
||||
virtual void getCreationRates(doublereal* cdot) {
|
||||
updateROP();
|
||||
m_rxnstoich->getCreationRates(m_kk, &m_kdata->m_ropf[0],
|
||||
&m_kdata->m_ropr[0], cdot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Species destruction rates [kmol/m^3]. Return the species
|
||||
* destruction rates in array ddot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species.
|
||||
*
|
||||
*/
|
||||
virtual void getDestructionRates(doublereal* ddot) {
|
||||
updateROP();
|
||||
m_rxnstoich->getDestructionRates(m_kk, &m_kdata->m_ropf[0],
|
||||
&m_kdata->m_ropr[0], ddot);
|
||||
// fill(ddot, ddot + m_kk, 0.0);
|
||||
//m_revProductStoich.incrementSpecies(
|
||||
// m_kdata->m_ropr.begin(), ddot);
|
||||
//m_reactantStoich.incrementSpecies(
|
||||
// m_kdata->m_ropf.begin(), ddot);
|
||||
}
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Informational Query Routines
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Flag specifying the type of reaction. The legal values and
|
||||
* their meaning are specific to the particular kinetics
|
||||
* manager.
|
||||
*/
|
||||
virtual int reactionType(int i) const {
|
||||
return m_index[i].first;
|
||||
}
|
||||
|
||||
virtual std::string reactionString(int i) const {
|
||||
return m_rxneqn[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* True if reaction i has been declared to be reversible. If
|
||||
* isReversible(i) is false, then the reverse rate of progress
|
||||
* for reaction i is always zero.
|
||||
*/
|
||||
virtual bool isReversible(int i) {
|
||||
if (std::find(m_revindex.begin(), m_revindex.end(), i)
|
||||
< m_revindex.end()) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the forward rate constants
|
||||
*
|
||||
* length is the number of reactions. units depends
|
||||
* on many issues.
|
||||
*/
|
||||
virtual void getFwdRateConstants(doublereal *kfwd);
|
||||
|
||||
/**
|
||||
* Return the reverse rate constants.
|
||||
*
|
||||
* length is the number of reactions. units depends
|
||||
* on many issues. Note, this routine will return rate constants
|
||||
* for irreversible reactions if the default for
|
||||
* doIrreversible is overridden.
|
||||
*/
|
||||
virtual void getRevRateConstants(doublereal *krev,
|
||||
bool doIrreversible = false);
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Setup Routines
|
||||
*/
|
||||
//@{
|
||||
|
||||
|
||||
/**
|
||||
* Set delta T threshold for updating temperature-dependent
|
||||
* rates.
|
||||
*/
|
||||
void setRateUpdateThreshold(doublereal dt) {
|
||||
m_dt_threshold = dt;
|
||||
}
|
||||
|
||||
virtual void init();
|
||||
|
||||
/// Add a reaction to the mechanism.
|
||||
void addReaction(const ReactionData& r);
|
||||
|
||||
virtual void finalize();
|
||||
virtual bool ready() const;
|
||||
|
||||
virtual void update_T();
|
||||
virtual void update_C();
|
||||
|
||||
void updateROP();
|
||||
|
||||
|
||||
const std::vector<grouplist_t>& reactantGroups(int i)
|
||||
{ return m_rgroups[i]; }
|
||||
const std::vector<grouplist_t>& productGroups(int i)
|
||||
{ return m_pgroups[i]; }
|
||||
|
||||
|
||||
void _update_rates_T();
|
||||
void _update_rates_C();
|
||||
|
||||
//@}
|
||||
|
||||
protected:
|
||||
|
||||
int m_kk, m_nfall;
|
||||
|
||||
vector_int m_fallindx;
|
||||
doublereal m_dt_threshold;
|
||||
|
||||
Rate1<Arrhenius> m_falloff_low_rates;
|
||||
Rate1<Arrhenius> m_falloff_high_rates;
|
||||
Rate1<Arrhenius> m_rates;
|
||||
|
||||
mutable std::map<int, std::pair<int, int> > m_index;
|
||||
|
||||
FalloffMgr m_falloffn;
|
||||
|
||||
ThirdBodyMgr<Enhanced3BConc> m_3b_concm;
|
||||
ThirdBodyMgr<Enhanced3BConc> m_falloff_concm;
|
||||
|
||||
std::vector<int> m_irrev;
|
||||
|
||||
ReactionStoichMgr* m_rxnstoich;
|
||||
|
||||
std::vector<int> m_fwdOrder;
|
||||
|
||||
int m_nirrev;
|
||||
int m_nrev;
|
||||
|
||||
std::map<int, std::vector<grouplist_t> > m_rgroups;
|
||||
std::map<int, std::vector<grouplist_t> > m_pgroups;
|
||||
|
||||
std::vector<int> m_rxntype;
|
||||
|
||||
mutable std::vector<std::map<int, doublereal> > m_rrxn;
|
||||
mutable std::vector<std::map<int, doublereal> > m_prxn;
|
||||
|
||||
/**
|
||||
* Difference between the input global reactants order
|
||||
* and the input global products order. Changed to a double
|
||||
* to account for the fact that we can have real-valued
|
||||
* stoichiometries.
|
||||
*/
|
||||
vector_fp m_dn;
|
||||
vector_int m_revindex;
|
||||
|
||||
std::vector<std::string> m_rxneqn;
|
||||
|
||||
GasKineticsData* m_kdata;
|
||||
|
||||
vector_fp m_conc;
|
||||
void processFalloffReactions();
|
||||
vector_fp m_grt;
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int reactionNumber(){ return m_ii;}
|
||||
std::vector<std::map<int, doublereal> > m_stoich;
|
||||
|
||||
void addElementaryReaction(const ReactionData& r);
|
||||
void addThreeBodyReaction(const ReactionData& r);
|
||||
void addFalloffReaction(const ReactionData& r);
|
||||
|
||||
void installReagents(const ReactionData& r);
|
||||
|
||||
void installGroups(int irxn, const std::vector<grouplist_t>& r,
|
||||
const std::vector<grouplist_t>& p);
|
||||
void updateKc();
|
||||
|
||||
void registerReaction(int rxnNumber, int type, int loc) {
|
||||
m_index[rxnNumber] = std::pair<int, int>(type, loc);
|
||||
}
|
||||
bool m_finalized;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
136
Cantera/src/kinetics/GasKineticsWriter.cpp
Executable file
136
Cantera/src/kinetics/GasKineticsWriter.cpp
Executable file
|
|
@ -0,0 +1,136 @@
|
|||
/**
|
||||
* @file GasKineticsWriter.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
// turn off warnings under Windows
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "ReactionData.h"
|
||||
#include "GasKineticsWriter.h"
|
||||
|
||||
#include "StoichManager.h"
|
||||
#include "Enhanced3BConc.h"
|
||||
#include "ThirdBodyMgr.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
//#include "ThermoPhase.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Construct an empty reaction mechanism.
|
||||
*/
|
||||
GasKineticsWriter::
|
||||
GasKineticsWriter() : m_kk(0), m_ii(0), m_nfall(0), m_nrev(0), m_nirrev(0),
|
||||
m_finalized(false) {}
|
||||
|
||||
void GasKineticsWriter::
|
||||
addReaction(const ReactionData& r) {
|
||||
|
||||
if (r.reactionType == ELEMENTARY_RXN) addElementaryReaction(r);
|
||||
else if (r.reactionType == THREE_BODY_RXN) addThreeBodyReaction(r);
|
||||
else if (r.reactionType == FALLOFF_RXN) addFalloffReaction(r);
|
||||
|
||||
// operations common to all reaction types
|
||||
installReagents( r.reactants, r.products, r.reversible );
|
||||
m_ii++;
|
||||
}
|
||||
|
||||
|
||||
void GasKineticsWriter::
|
||||
addFalloffReaction(const ReactionData& r) {
|
||||
|
||||
// install high and low rate coeff calculators
|
||||
m_falloff_high_rates.install( m_nfall,
|
||||
r.rateCoeffType, r.rateCoeffParameters.size(),
|
||||
r.rateCoeffParameters.begin() );
|
||||
m_falloff_low_rates.install( m_nfall,
|
||||
r.rateCoeffType, r.auxRateCoeffParameters.size(),
|
||||
r.auxRateCoeffParameters.begin() );
|
||||
|
||||
// add this reaction number to the list of
|
||||
// falloff reactions
|
||||
m_fallindx.push_back( reactionNumber() );
|
||||
|
||||
// increment the falloff reaction counter
|
||||
++m_nfall;
|
||||
}
|
||||
|
||||
|
||||
void GasKineticsWriter::
|
||||
addElementaryReaction(const ReactionData& r) {
|
||||
|
||||
int iloc;
|
||||
// install rate coeff calculator
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, r.rateCoeffParameters.size(),
|
||||
r.rateCoeffParameters.begin() );
|
||||
}
|
||||
|
||||
|
||||
void GasKineticsWriter::
|
||||
addThreeBodyReaction(const ReactionData& r) {
|
||||
|
||||
int iloc;
|
||||
// install rate coeff calculator
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, r.rateCoeffParameters.size(),
|
||||
r.rateCoeffParameters.begin() );
|
||||
}
|
||||
|
||||
|
||||
void GasKineticsWriter::installReagents(const vector_int& r,
|
||||
const vector_int& p, bool reversible) {
|
||||
|
||||
int nr = r.size();
|
||||
int rnum = reactionNumber();
|
||||
int i;
|
||||
for (i = 0; i < nr; i++) {
|
||||
m_rrxn[r[i]][rnum] += 1.0;
|
||||
}
|
||||
|
||||
m_reactantWriter.add( reactionNumber(), r);
|
||||
|
||||
int np = p.size();
|
||||
|
||||
for (i = 0; i < np; i++) {
|
||||
m_prxn[p[i]][rnum] += 1.0;
|
||||
}
|
||||
|
||||
if (reversible) {
|
||||
m_revProductWriter.add(reactionNumber(), p);
|
||||
m_dn.push_back(np - nr);
|
||||
m_revindex.push_back(reactionNumber());
|
||||
m_nrev++;
|
||||
}
|
||||
else {
|
||||
m_irrevProductWriter.add(reactionNumber(), p);
|
||||
m_irrev.push_back( reactionNumber() );
|
||||
m_nirrev++;
|
||||
}
|
||||
}
|
||||
|
||||
void GasKineticsWriter::init(int nsp) {
|
||||
m_rrxn.resize(nsp);
|
||||
m_prxn.resize(nsp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
203
Cantera/src/kinetics/GasKineticsWriter.h
Executable file
203
Cantera/src/kinetics/GasKineticsWriter.h
Executable file
|
|
@ -0,0 +1,203 @@
|
|||
/**
|
||||
*
|
||||
* @file GasKineticsWriter.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_GASKINETICSWRITER_H
|
||||
#define CT_GASKINETICSWRITER_H
|
||||
|
||||
#define WRITE_UPDATE
|
||||
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mix_defs.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
#include "utilities.h"
|
||||
#include "StoichManager.h"
|
||||
#include "ThirdBodyMgr.h"
|
||||
#include "FalloffMgr.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
#include "Phase.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
// forward references
|
||||
class Enhanced3BConc;
|
||||
class ReactionData;
|
||||
|
||||
//! Class to write a hard-coded version of a mechanism.
|
||||
/*!
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
class GasKineticsWriter {
|
||||
|
||||
public:
|
||||
|
||||
/// Default constructor.
|
||||
GasKineticsWriter();
|
||||
|
||||
/// Destructor.
|
||||
virtual ~GasKineticsWriter(){}
|
||||
|
||||
void init(int nsp);
|
||||
doublereal reactantStoichCoeff(int k, int i) const {
|
||||
return m_rrxn[k][i];
|
||||
}
|
||||
|
||||
doublereal productStoichCoeff(int k, int i) const {
|
||||
return m_prxn[k][i];
|
||||
}
|
||||
void writeUpdateROP(){}
|
||||
|
||||
void writeGetNetProductionRates(ostream& s, int nsp, int nrxns) {
|
||||
int i, k;
|
||||
s << "void get_wdot(const double* rop, double* wdot) {" << endl;
|
||||
for (k = 0; k < nsp; k++) {
|
||||
s << " wdot[" << k << "] = ";
|
||||
doublereal net;
|
||||
bool empty = true;
|
||||
for (i = 0; i < nrxns; i++) {
|
||||
net = productStoichCoeff(k,i) - reactantStoichCoeff(k,i);
|
||||
if (net > 0.0) {
|
||||
empty = false;
|
||||
if (net == 1.0)
|
||||
s << " + rop[" << i << "]";
|
||||
else
|
||||
s << " + " << net << "*rop[" << i << "]";
|
||||
}
|
||||
else if (net < 0.0) {
|
||||
empty = false;
|
||||
if (net == -1.0)
|
||||
s << " - rop[" << i << "]";
|
||||
else
|
||||
s << " - " << -net << "*rop[" << i << "]";
|
||||
}
|
||||
}
|
||||
if (empty) s << "0.0";
|
||||
s << ";" << endl;
|
||||
}
|
||||
s << "}" << endl;
|
||||
}
|
||||
|
||||
|
||||
void writeUpdateKc(ostream& s, int nsp, int nrxns) {
|
||||
int i, k, n, nn, ir;
|
||||
s << "void update_kc(const double* a, "
|
||||
"double exp_c0, double* rkc) {" << endl;
|
||||
for (i = 0; i != m_nrev; i++) {
|
||||
//if (isReversible(i)) {
|
||||
ir = m_revindex[i];
|
||||
s << " rkc[" << ir << "] = ";
|
||||
bool empty = true;
|
||||
for (k = 0; k < nsp; k++) {
|
||||
n = int(productStoichCoeff(k,ir));
|
||||
for (nn = 0; nn != n; nn++) {
|
||||
if (!empty) s << "*";
|
||||
s << "a[" << k << "]";
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
if (m_dn[i] < 0.0) {
|
||||
n = -m_dn[i];
|
||||
for (nn = 0; nn < n; nn++) s << "*exp_c0";
|
||||
}
|
||||
s << "/(";
|
||||
empty = true;
|
||||
for (k = 0; k < nsp; k++) {
|
||||
n = int(reactantStoichCoeff(k,ir));
|
||||
for (nn = 0; nn < n; nn++) {
|
||||
if (!empty) s << "*";
|
||||
s << "a[" << k << "]";
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
if (m_dn[i] > 0.0) {
|
||||
n = m_dn[i];
|
||||
for (nn = 0; nn != n; nn++) s << "*exp_c0";
|
||||
}
|
||||
s << ");" << endl;
|
||||
}
|
||||
s << "}" << endl;
|
||||
}
|
||||
|
||||
void writeEvalRopnet(ostream& s) {
|
||||
int i;
|
||||
s << "void eval_ropnet(const double* c, "
|
||||
"const double* rf, const double* rkc, double* r) {" << endl;
|
||||
for (i = 0; i < m_ii; i++) {
|
||||
s << " r[" << i << "] = rf[" << i << "] * ("
|
||||
<< m_reactantWriter.mult(i);
|
||||
if (isReversible(i)) {
|
||||
s << " - rkc[" << i << "] * "
|
||||
<< m_revProductWriter.mult(i);
|
||||
}
|
||||
s << ");" << endl;
|
||||
}
|
||||
s << "}" << endl;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void writeUpdateRates(ostream& s) {
|
||||
s << "void update_rates(double t, double tlog, double* rf) {" << endl;
|
||||
s << " double rt = 1.0/t;" << endl;
|
||||
m_rates.writeUpdate(s, "rf");
|
||||
s << "}" << endl;
|
||||
}
|
||||
|
||||
/// Add a reaction to the mechanism.
|
||||
void addReaction(const ReactionData& r);
|
||||
|
||||
protected:
|
||||
|
||||
int m_kk, m_ii, m_nfall, m_nrev, m_nirrev;
|
||||
|
||||
vector_int m_fallindx;
|
||||
|
||||
Rate1<Arrhenius> m_falloff_low_rates;
|
||||
Rate1<Arrhenius> m_falloff_high_rates;
|
||||
Rate1<Arrhenius> m_rates;
|
||||
|
||||
vector<int> m_irrev;
|
||||
|
||||
StoichWriter m_reactantWriter;
|
||||
StoichWriter m_revProductWriter;
|
||||
StoichWriter m_irrevProductWriter;
|
||||
|
||||
mutable vector<map<int, doublereal> > m_rrxn;
|
||||
mutable vector<map<int, doublereal> > m_prxn;
|
||||
|
||||
vector_int m_dn;
|
||||
vector_int m_revindex;
|
||||
|
||||
private:
|
||||
|
||||
int reactionNumber(){ return m_ii;}
|
||||
void addElementaryReaction(const ReactionData& r);
|
||||
void addThreeBodyReaction(const ReactionData& r);
|
||||
void addFalloffReaction(const ReactionData& r);
|
||||
|
||||
void installReagents(const vector_int& r,
|
||||
const vector_int& p, bool reversible);
|
||||
|
||||
virtual bool isReversible(int i) {
|
||||
if (find(m_revindex.begin(), m_revindex.end(), i)
|
||||
< m_revindex.end()) return true;
|
||||
else return false;
|
||||
}
|
||||
bool m_finalized;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
85
Cantera/src/kinetics/Group.cpp
Executable file
85
Cantera/src/kinetics/Group.cpp
Executable file
|
|
@ -0,0 +1,85 @@
|
|||
/**
|
||||
* @file Group.cpp
|
||||
*
|
||||
* Implementation file for the Group class used in reaction path analysis.
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
// reaction path analysis support
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include "Group.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* A group is 'valid' if all of its nonzero atom numbers have
|
||||
* the same sign, either positive or negative. This method
|
||||
* checks for this, and if the group is not valid it sets
|
||||
* m_sign to -999, and sets all atom numbers to zero.
|
||||
*/
|
||||
void Group::validate() {
|
||||
|
||||
int n = m_comp.size();
|
||||
|
||||
// if already checked and not valid, return
|
||||
if (m_sign == -999) return;
|
||||
|
||||
m_sign = 0;
|
||||
bool ok = true;
|
||||
for (int m = 0; m < n; m++)
|
||||
{
|
||||
if (m_comp[m] != 0)
|
||||
{
|
||||
if (m_sign == 0) {
|
||||
m_sign = m_comp[m]/abs(m_comp[m]);
|
||||
}
|
||||
else if (m_sign * m_comp[m] < 0) {
|
||||
ok = false; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ok) { m_sign = -999; m_comp.resize(n,0); }
|
||||
}
|
||||
|
||||
std::ostream& Group::fmt(std::ostream& s,
|
||||
const std::vector<std::string>& esymbols) const {
|
||||
s << "(";
|
||||
int nm;
|
||||
bool first = true;
|
||||
int n = m_comp.size();
|
||||
for (int m = 0; m < n; m++) {
|
||||
nm = m_comp[m];
|
||||
if (nm != 0) {
|
||||
if (!first) s << "-";
|
||||
s << esymbols[m];
|
||||
if (nm != 1) s << nm;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
s << ")";
|
||||
return s;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const Cantera::Group& g) {
|
||||
if (g.valid()) {
|
||||
s << g.m_comp;
|
||||
} else {
|
||||
s << "<none>";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
}
|
||||
131
Cantera/src/kinetics/Group.h
Executable file
131
Cantera/src/kinetics/Group.h
Executable file
|
|
@ -0,0 +1,131 @@
|
|||
/**
|
||||
* @file Group.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
#ifndef CT_RXNPATH_GROUP
|
||||
#define CT_RXNPATH_GROUP
|
||||
|
||||
#include "ct_defs.h"
|
||||
|
||||
//using namespace std;
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Class Group is an internal class used by class ReactionPath. It
|
||||
* represents some subset of the atoms of a molecule.
|
||||
*/
|
||||
class Group {
|
||||
public:
|
||||
Group() : m_sign(-999) { }
|
||||
Group(int n) : m_sign(0) { m_comp.resize(n,0);}
|
||||
Group(const vector_int& elnumbers) :
|
||||
m_comp(elnumbers), m_sign(0) {
|
||||
validate();
|
||||
}
|
||||
Group(const Group& g) :
|
||||
m_comp(g.m_comp), m_sign(g.m_sign) { }
|
||||
Group& operator=(const Group& g) {
|
||||
if (&g != this) {
|
||||
m_comp = g.m_comp;
|
||||
m_sign = g.m_sign;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
virtual ~Group(){}
|
||||
|
||||
/**
|
||||
* Decrement the atom numbers by those in group 'other'.
|
||||
*/
|
||||
void operator-=(const Group& other) {
|
||||
verifyInputs(*this, other);
|
||||
int n = m_comp.size();
|
||||
for (int m = 0; m < n; m++)
|
||||
m_comp[m] -= other.m_comp[m];
|
||||
validate();
|
||||
}
|
||||
void operator+=(const Group& other) {
|
||||
verifyInputs(*this, other);
|
||||
int n = m_comp.size();
|
||||
for (int m = 0; m < n; m++)
|
||||
m_comp[m] += other.m_comp[m];
|
||||
validate();
|
||||
}
|
||||
void operator*=(int a) {
|
||||
int n = m_comp.size();
|
||||
for (int m = 0; m < n; m++)
|
||||
m_comp[m] *= a;
|
||||
validate();
|
||||
}
|
||||
bool operator==(const Group& other) const {
|
||||
verifyInputs(*this, other);
|
||||
int n = m_comp.size();
|
||||
for (int m = 0; m < n; m++) {
|
||||
if (m_comp[m] != other.m_comp[m]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
friend Group operator-(const Group& g1, const Group& g2) {
|
||||
verifyInputs(g1, g2);
|
||||
Group diff(g1);
|
||||
diff -= g2;
|
||||
return diff;
|
||||
}
|
||||
friend Group operator+(const Group& g1, const Group& g2) {
|
||||
verifyInputs(g1, g2);
|
||||
Group sum(g1);
|
||||
sum += g2;
|
||||
return sum;
|
||||
}
|
||||
friend void verifyInputs(const Group& g1, const Group& g2) {
|
||||
// if (Debug::on) {
|
||||
// if (g1.size() != g2.size()) {
|
||||
// cerr << "Group: size mismatch!" << std::endl;
|
||||
// cerr << " group 1 = " << g1 << std::endl;
|
||||
// cerr << " group 2 = " << g2 << std::endl;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
void validate();
|
||||
|
||||
/**
|
||||
* True if all non-zero atom numbers have the same sign.
|
||||
*/
|
||||
bool valid() const { return (m_sign != -999); }
|
||||
bool operator!() const { return (m_sign == -999); }
|
||||
int sign() const { return m_sign; }
|
||||
int size() const { return m_comp.size(); }
|
||||
|
||||
/// Number of atoms in the group (>= 0)
|
||||
int nAtoms() const {
|
||||
int n = m_comp.size();
|
||||
int sum = 0;
|
||||
for (int m = 0; m < n; m++) sum += std::abs(m_comp[m]);
|
||||
return sum;
|
||||
}
|
||||
/// Number of atoms of element m (positive or negative)
|
||||
int nAtoms(int m) const {
|
||||
if (m_comp.empty()) return 0;
|
||||
return m_comp[m];
|
||||
}
|
||||
|
||||
std::ostream& fmt(std::ostream& s, const std::vector<std::string>& esymbols) const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s,
|
||||
const Group& g);
|
||||
|
||||
private:
|
||||
vector_int m_comp;
|
||||
int m_sign;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
89
Cantera/src/kinetics/ImplicitChem.cpp
Executable file
89
Cantera/src/kinetics/ImplicitChem.cpp
Executable file
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* @file ImplicitChem.cpp
|
||||
*/
|
||||
|
||||
/* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "ImplicitChem.h"
|
||||
#include "Integrator.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
ImplicitChem::ImplicitChem(Kinetics& kin, ThermoPhase& therm)
|
||||
: FuncEval(), m_kin(&kin), m_thermo(&therm), m_integ(0),
|
||||
m_atol(1.e-15), m_rtol(1.e-7), m_maxstep(0.0), m_energy(false)
|
||||
{
|
||||
m_integ = newIntegrator("CVODE"); //CVodeInt;
|
||||
//m_mix = &kin.phase();
|
||||
m_wt = m_thermo->molecularWeights();
|
||||
|
||||
// use backward differencing, with a full Jacobian computed
|
||||
// numerically, and use a Newton linear iterator
|
||||
m_integ->setMethod(BDF_Method);
|
||||
m_integ->setProblemType(DENSE + NOJAC);
|
||||
m_integ->setIterator(Newton_Iter);
|
||||
m_nsp = m_thermo->nSpecies();
|
||||
}
|
||||
|
||||
// overloaded method of FuncEval. Called by the integrator to
|
||||
// get the initial conditions.
|
||||
void ImplicitChem::getInitialConditions(double t0, size_t leny, double* y)
|
||||
{
|
||||
m_thermo->getMassFractions(y);
|
||||
m_h0 = m_thermo->enthalpy_mass();
|
||||
m_rho = m_thermo->density();
|
||||
m_press = m_thermo->pressure();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Must be called before calling method 'advance'
|
||||
*/
|
||||
void ImplicitChem::initialize(doublereal t0) {
|
||||
m_integ->setTolerances(m_rtol, m_atol);
|
||||
// m_integ->setMaxStep(m_maxstep);
|
||||
m_integ->initialize(t0, *this);
|
||||
}
|
||||
|
||||
|
||||
void ImplicitChem::updateState(doublereal* y) {
|
||||
m_thermo->setMassFractions(y);
|
||||
if (m_energy) {
|
||||
doublereal delta, temp = m_thermo->temperature();
|
||||
do {
|
||||
delta = -(m_thermo->enthalpy_mass() - m_h0)/m_thermo->cp_mass();
|
||||
temp += delta;
|
||||
m_thermo->setTemperature(temp);
|
||||
}
|
||||
while (fabs(delta) > 1.e-7);
|
||||
}
|
||||
m_thermo->setPressure(m_press);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the integrator to evaluate ydot given y at time 'time'.
|
||||
*/
|
||||
void ImplicitChem::eval(doublereal time, doublereal* y,
|
||||
doublereal* ydot, doublereal* p)
|
||||
{
|
||||
updateState(y); // synchronize the mixture state with y
|
||||
m_thermo->setPressure(m_press);
|
||||
m_kin->getNetProductionRates(ydot); // "omega dot"
|
||||
int k;
|
||||
for (k = 0; k < m_nsp; k++) {
|
||||
ydot[k] *= m_wt[k]/m_rho;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
118
Cantera/src/kinetics/ImplicitChem.h
Executable file
118
Cantera/src/kinetics/ImplicitChem.h
Executable file
|
|
@ -0,0 +1,118 @@
|
|||
/**
|
||||
* @file ImplicitChem.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
#ifndef CT_IMPCHEM_H
|
||||
#define CT_IMPCHEM_H
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "FuncEval.h"
|
||||
#include "Integrator.h"
|
||||
#include "Kinetics.h"
|
||||
#include "ThermoPhase.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Advances the composition of an associated phase object in time
|
||||
* by implicitly integrating
|
||||
* \f[
|
||||
* \dot Y_k = \frac{\omega_k}{\rho}
|
||||
* \f]
|
||||
*/
|
||||
class ImplicitChem : public FuncEval {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
ImplicitChem(Kinetics& kin, ThermoPhase& therm);
|
||||
|
||||
|
||||
/**
|
||||
* Destructor. Deletes the integrator.
|
||||
*/
|
||||
virtual ~ImplicitChem(){ delete m_integ; }
|
||||
|
||||
|
||||
/**
|
||||
* Overloads the virtual function
|
||||
* declared in FuncEval.
|
||||
*/
|
||||
virtual void initialize(doublereal t0 = 0.0);
|
||||
|
||||
void adiabatic() {
|
||||
m_energy = true;
|
||||
}
|
||||
|
||||
void isothermal() {
|
||||
m_energy = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrate from t0 to t1. The integrator is reinitialized
|
||||
* first.
|
||||
*/
|
||||
void integrate(doublereal t0, doublereal t1) {
|
||||
m_integ->reinitialize(t0, *this);
|
||||
m_integ->setMaxStepSize(t1 - t0);
|
||||
m_rho = m_thermo->density();
|
||||
m_integ->integrate(t1);
|
||||
updateState(m_integ->solution());
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrate from t0 to t1 without reinitializing the
|
||||
* integrator.
|
||||
*/
|
||||
void integrate0(doublereal t0, doublereal t1) {
|
||||
m_integ->integrate(t1);
|
||||
updateState(m_integ->solution());
|
||||
}
|
||||
|
||||
// overloaded methods of class FuncEval
|
||||
virtual int neq() { return m_nsp; }
|
||||
virtual void eval(doublereal t, doublereal* y, doublereal* ydot,
|
||||
doublereal* p);
|
||||
virtual void getInitialConditions(doublereal t0, size_t leny,
|
||||
doublereal* y);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Set the mixture to a state consistent with solution
|
||||
* vector y.
|
||||
*/
|
||||
void updateState(doublereal* y);
|
||||
|
||||
//Kinetics::phase_t* m_mix;
|
||||
Kinetics* m_kin;
|
||||
ThermoPhase* m_thermo;
|
||||
int m_nsp;
|
||||
Integrator* m_integ; // pointer to integrator
|
||||
doublereal m_atol, m_rtol; // tolerances
|
||||
doublereal m_maxstep; // max step size
|
||||
array_fp m_wt;
|
||||
doublereal m_rho;
|
||||
bool m_energy;
|
||||
doublereal m_h0;
|
||||
doublereal m_press;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
114
Cantera/src/kinetics/ImplicitSurfChem.cpp
Executable file
114
Cantera/src/kinetics/ImplicitSurfChem.cpp
Executable file
|
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* @file ImplicitSurfChem.cpp
|
||||
*
|
||||
* Implicit integration of surface site density equations
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "ImplicitSurfChem.h"
|
||||
#include "Integrator.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
ImplicitSurfChem::ImplicitSurfChem(vector<InterfaceKinetics*> k)
|
||||
: FuncEval(), m_nv(0), m_integ(0),
|
||||
m_atol(1.e-14), m_rtol(1.e-7), m_maxstep(0.0)
|
||||
{
|
||||
m_nsurf = static_cast<int>(k.size());
|
||||
int ns;
|
||||
int nt, ntmax = 0;
|
||||
for (int n = 0; n < m_nsurf; n++) {
|
||||
m_kin.push_back(k[n]);
|
||||
ns = k[n]->surfacePhaseIndex();
|
||||
if (ns < 0)
|
||||
throw CanteraError("ImplicitSurfChem",
|
||||
"kinetics manager contains no surface phase");
|
||||
m_surfindex.push_back(ns);
|
||||
m_surf.push_back((SurfPhase*)&k[n]->thermo(ns));
|
||||
m_nsp.push_back(m_surf.back()->nSpecies());
|
||||
m_nv += m_nsp.back();
|
||||
nt = k[n]->nTotalSpecies();
|
||||
if (nt > ntmax) ntmax = nt;
|
||||
}
|
||||
m_integ = newIntegrator("CVODE");// CVodeInt;
|
||||
|
||||
// use backward differencing, with a full Jacobian computed
|
||||
// numerically, and use a Newton linear iterator
|
||||
|
||||
m_integ->setMethod(BDF_Method);
|
||||
m_integ->setProblemType(DENSE + NOJAC);
|
||||
m_integ->setIterator(Newton_Iter);
|
||||
m_work.resize(ntmax);
|
||||
}
|
||||
|
||||
|
||||
// overloaded method of FuncEval. Called by the integrator to
|
||||
// get the initial conditions.
|
||||
void ImplicitSurfChem::getInitialConditions(double t0, size_t lenc,
|
||||
double* c)
|
||||
{
|
||||
int loc = 0;
|
||||
for (int n = 0; n < m_nsurf; n++) {
|
||||
m_surf[n]->getCoverages(c + loc);
|
||||
loc += m_nsp[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Must be called before calling method 'advance'
|
||||
*/
|
||||
void ImplicitSurfChem::initialize(doublereal t0) {
|
||||
m_integ->setTolerances(m_rtol, m_atol);
|
||||
m_integ->initialize(t0, *this);
|
||||
}
|
||||
|
||||
|
||||
void ImplicitSurfChem::updateState(doublereal* c) {
|
||||
int loc = 0;
|
||||
for (int n = 0; n < m_nsurf; n++) {
|
||||
m_surf[n]->setCoverages(c + loc);
|
||||
loc += m_nsp[n];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the integrator to evaluate ydot given y at time 'time'.
|
||||
*/
|
||||
void ImplicitSurfChem::eval(doublereal time, doublereal* y,
|
||||
doublereal* ydot, doublereal* p)
|
||||
{
|
||||
int n;
|
||||
updateState(y); // synchronize the surface state(s) with y
|
||||
doublereal rs0, sum;
|
||||
int loc, k, kstart;
|
||||
for (n = 0; n < m_nsurf; n++) {
|
||||
rs0 = 1.0/m_surf[n]->siteDensity();
|
||||
m_kin[n]->getNetProductionRates(DATA_PTR(m_work));
|
||||
kstart = m_kin[n]->kineticsSpeciesIndex(0,m_surfindex[n]);
|
||||
sum = 0.0;
|
||||
loc = 0;
|
||||
for (k = 1; k < m_nsp[n]; k++) {
|
||||
ydot[k + loc] = m_work[kstart + k] * rs0 * m_surf[n]->size(k);
|
||||
sum -= ydot[k];
|
||||
}
|
||||
ydot[loc] = sum;
|
||||
loc += m_nsp[n];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
117
Cantera/src/kinetics/ImplicitSurfChem.h
Executable file
117
Cantera/src/kinetics/ImplicitSurfChem.h
Executable file
|
|
@ -0,0 +1,117 @@
|
|||
/**
|
||||
* @file ImplicitSurfChem.h
|
||||
*
|
||||
* Implicit integration of surface site density equations.
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_IMPSURFCHEM_H
|
||||
#define CT_IMPSURFCHEM_H
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "FuncEval.h"
|
||||
#include "Integrator.h"
|
||||
#include "InterfaceKinetics.h"
|
||||
#include "SurfPhase.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* Advances the surface coverages of an associated SurfacePhase
|
||||
* object in time by implicitly integrating \f[ \dot \theta_k =
|
||||
* \dot s_k (\sigma_k / s_0)\f]
|
||||
*/
|
||||
class ImplicitSurfChem : public FuncEval {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
//ImplicitSurfChem(InterfaceKinetics& kin);
|
||||
|
||||
/**
|
||||
* Constructor for multiple surfaces.
|
||||
*/
|
||||
ImplicitSurfChem(std::vector<InterfaceKinetics*> k);
|
||||
|
||||
/**
|
||||
* Destructor. Deletes the integrator.
|
||||
*/
|
||||
virtual ~ImplicitSurfChem(){ delete m_integ; }
|
||||
|
||||
|
||||
/**
|
||||
* Overloads the virtual function
|
||||
* declared in FuncEval.
|
||||
*/
|
||||
virtual void initialize(doublereal t0 = 0.0);
|
||||
|
||||
|
||||
/**
|
||||
* Integrate from t0 to t1. The integrator is reinitialized
|
||||
* first.
|
||||
*/
|
||||
void integrate(doublereal t0, doublereal t1) {
|
||||
m_integ->initialize(t0, *this);
|
||||
m_integ->setMaxStepSize(t1 - t0);
|
||||
m_integ->integrate(t1);
|
||||
updateState(m_integ->solution());
|
||||
}
|
||||
|
||||
/**
|
||||
* Integrate from t0 to t1 without reinitializing the
|
||||
* integrator. Use when the coverages have not changed from
|
||||
* their values on return from the last call to integrate or
|
||||
* integrate0.
|
||||
*/
|
||||
void integrate0(doublereal t0, doublereal t1) {
|
||||
m_integ->integrate(t1);
|
||||
updateState(m_integ->solution());
|
||||
}
|
||||
|
||||
// overloaded methods of class FuncEval
|
||||
virtual int neq() { return m_nv; }
|
||||
virtual void eval(doublereal t, doublereal* y, doublereal* ydot,
|
||||
doublereal* p);
|
||||
virtual void getInitialConditions(doublereal t0,
|
||||
size_t leny, doublereal* y);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Set the mixture to a state consistent with solution
|
||||
* vector y.
|
||||
*/
|
||||
void updateState(doublereal* y);
|
||||
|
||||
std::vector<SurfPhase*> m_surf;
|
||||
std::vector<InterfaceKinetics*> m_kin;
|
||||
vector_int m_nsp;
|
||||
vector_int m_surfindex;
|
||||
int m_nsurf;
|
||||
int m_nv;
|
||||
//int m_nsp, m_surfindex;
|
||||
Integrator* m_integ; // pointer to integrator
|
||||
doublereal m_atol, m_rtol; // tolerances
|
||||
doublereal m_maxstep; // max step size
|
||||
vector_fp m_work;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
836
Cantera/src/kinetics/InterfaceKinetics.cpp
Normal file
836
Cantera/src/kinetics/InterfaceKinetics.cpp
Normal file
|
|
@ -0,0 +1,836 @@
|
|||
/**
|
||||
* @file InterfaceKinetics.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2002 California Institute of Technology
|
||||
|
||||
|
||||
// turn off warnings under Windows
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#pragma warning(disable:4503)
|
||||
#endif
|
||||
|
||||
#include "InterfaceKinetics.h"
|
||||
#include "SurfPhase.h"
|
||||
|
||||
#include "ReactionData.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
#include "ImplicitSurfChem.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Construct an empty InterfaceKinetics reaction mechanism.
|
||||
* @param thermo This is an optional parameter that may be
|
||||
* used to initialize the inherited Kinetics class with
|
||||
* one ThermoPhase class object -> in other words it's
|
||||
* useful for initialization of homogeneous kinetics
|
||||
* mechanisms.
|
||||
*/
|
||||
InterfaceKinetics::
|
||||
InterfaceKinetics(thermo_t* thermo) :
|
||||
Kinetics(),
|
||||
m_kk(0),
|
||||
m_redo_rates(false),
|
||||
m_nirrev(0),
|
||||
m_nrev(0),
|
||||
m_surf(0),
|
||||
m_integrator(0),
|
||||
m_finalized(false),
|
||||
m_has_coverage_dependence(false)
|
||||
{
|
||||
if (thermo != 0) addPhase(*thermo);
|
||||
m_kdata = new InterfaceKineticsData;
|
||||
m_kdata->m_temp = 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
InterfaceKinetics::
|
||||
~InterfaceKinetics(){
|
||||
delete m_kdata;
|
||||
delete m_integrator;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update properties that depend on temperature
|
||||
*
|
||||
*/
|
||||
void InterfaceKinetics::
|
||||
_update_rates_T() {
|
||||
_update_rates_phi();
|
||||
if (m_has_coverage_dependence) {
|
||||
m_surf->getCoverages(DATA_PTR(m_conc));
|
||||
m_rates.update_C(DATA_PTR(m_conc));
|
||||
m_redo_rates = true;
|
||||
}
|
||||
doublereal T = thermo(surfacePhaseIndex()).temperature();
|
||||
if (T != m_kdata->m_temp || m_redo_rates) {
|
||||
m_kdata->m_logtemp = log(T);
|
||||
m_rates.update(T, m_kdata->m_logtemp, DATA_PTR(m_kdata->m_rfn));
|
||||
applyButlerVolmerCorrection(DATA_PTR(m_kdata->m_rfn));
|
||||
m_kdata->m_temp = T;
|
||||
updateKc();
|
||||
m_kdata->m_ROP_ok = false;
|
||||
m_redo_rates = false;
|
||||
}
|
||||
}
|
||||
|
||||
void InterfaceKinetics::
|
||||
_update_rates_phi() {
|
||||
int np = nPhases();
|
||||
for (int n = 0; n < np; n++) {
|
||||
if (thermo(n).electricPotential() != m_phi[n]) {
|
||||
m_phi[n] = thermo(n).electricPotential();
|
||||
m_redo_rates = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update properties that depend on concentrations. This method
|
||||
* fills out the array of generalized concentrations by calling
|
||||
* method getActivityConcentrations for each phase, which classes
|
||||
* representing phases should overload to return the appropriate
|
||||
* quantities.
|
||||
*/
|
||||
void InterfaceKinetics::
|
||||
_update_rates_C() {
|
||||
int n;
|
||||
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
/*
|
||||
* We call the getActivityConcentrations function of each
|
||||
* ThermoPhase class that makes up this kinetics object to
|
||||
* obtain the generalized concentrations for species within that
|
||||
* class. This is collected in the vector m_conc. m_start[]
|
||||
* are integer indecises for that vector denoting the start of the
|
||||
* species for each phase.
|
||||
*/
|
||||
thermo(n).getActivityConcentrations(DATA_PTR(m_conc) + m_start[n]);
|
||||
}
|
||||
m_kdata->m_ROP_ok = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the equilibrium constants in molar units for all
|
||||
* reversible reactions. Irreversible reactions have their
|
||||
* equilibrium constant set to zero.
|
||||
*/
|
||||
void InterfaceKinetics::updateKc() {
|
||||
int i, irxn;
|
||||
|
||||
vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
fill(m_rkc.begin(), m_rkc.end(), 0.0);
|
||||
|
||||
//static vector_fp mu(nTotalSpecies());
|
||||
if (m_nrev > 0) {
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getStandardChemPotentials(DATA_PTR(m_mu0) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute Delta mu^0 for all reversible reactions
|
||||
//m_reactantStoich.decrementReactions(m_mu0.begin(), m_rkc.begin());
|
||||
//m_revProductStoich.incrementReactions(m_mu0.begin(), m_rkc.begin());
|
||||
m_rxnstoich.getRevReactionDelta(m_ii, DATA_PTR(m_mu0),
|
||||
DATA_PTR(m_rkc));
|
||||
|
||||
for (i = 0; i < m_nrev; i++) {
|
||||
irxn = m_revindex[i];
|
||||
if (irxn < 0 || irxn >= nReactions()) {
|
||||
throw CanteraError("InterfaceKinetics","illegal value: irxn = "+int2str(irxn));
|
||||
}
|
||||
m_rkc[irxn] = exp(m_rkc[irxn]*rrt);
|
||||
}
|
||||
for (i = 0; i != m_nirrev; ++i) {
|
||||
m_rkc[ m_irrev[i] ] = 0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterfaceKinetics::checkPartialEquil() {
|
||||
int i, irxn;
|
||||
vector_fp dmu(nTotalSpecies(), 0.0);
|
||||
vector_fp rmu(nReactions(), 0.0);
|
||||
vector_fp frop(nReactions(), 0.0);
|
||||
vector_fp rrop(nReactions(), 0.0);
|
||||
vector_fp netrop(nReactions(), 0.0);
|
||||
if (m_nrev > 0) {
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
cout << "T = " << thermo(0).temperature() << " " << rt << endl;
|
||||
int n, nsp, k, ik=0;
|
||||
//doublereal rt = GasConstant*thermo(0).temperature();
|
||||
// doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
doublereal delta;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getChemPotentials(DATA_PTR(dmu) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
delta = Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
cout << thermo(n).speciesName(k) << " " << (delta+dmu[ik])/rt << " " << dmu[ik]/rt << endl;
|
||||
dmu[ik] += delta;
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute Delta mu^ for all reversible reactions
|
||||
m_rxnstoich.getRevReactionDelta(m_ii, DATA_PTR(dmu), DATA_PTR(rmu));
|
||||
getFwdRatesOfProgress(DATA_PTR(frop));
|
||||
getRevRatesOfProgress(DATA_PTR(rrop));
|
||||
getNetRatesOfProgress(DATA_PTR(netrop));
|
||||
for (i = 0; i < m_nrev; i++) {
|
||||
irxn = m_revindex[i];
|
||||
cout << "Reaction " << reactionString(irxn)
|
||||
<< " " << rmu[irxn]/rt << endl;
|
||||
printf("%12.6e %12.6e %12.6e %12.6e \n",
|
||||
frop[irxn], rrop[irxn], netrop[irxn],
|
||||
netrop[irxn]/(frop[irxn] + rrop[irxn]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the equilibrium constants of all reactions, whether
|
||||
* reversible or not.
|
||||
*/
|
||||
void InterfaceKinetics::getEquilibriumConstants(doublereal* kc) {
|
||||
int i;
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getStandardChemPotentials(DATA_PTR(m_mu0) + m_start[n]);
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_mu0[ik] -= rt*thermo(n).logStandardConc(k);
|
||||
m_mu0[ik] += Faraday * m_phi[n] * thermo(n).charge(k);
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
fill(kc, kc + m_ii, 0.0);
|
||||
|
||||
//m_reactantStoich.decrementReactions(m_mu0.begin(), kc);
|
||||
//m_revProductStoich.incrementReactions(m_mu0.begin(), kc);
|
||||
//m_irrevProductStoich.incrementReactions(m_mu0.begin(), kc);
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu0), kc);
|
||||
|
||||
for (i = 0; i < m_ii; i++) {
|
||||
kc[i] = exp(-kc[i]*rrt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void InterfaceKinetics::applyButlerVolmerCorrection(doublereal* kf) {
|
||||
int i;
|
||||
|
||||
int n, nsp, k, ik=0;
|
||||
doublereal rt = GasConstant*thermo(0).temperature();
|
||||
doublereal rrt = 1.0/rt;
|
||||
int np = nPhases();
|
||||
|
||||
// compute the electrical potential energy of each species
|
||||
for (n = 0; n < np; n++) {
|
||||
nsp = thermo(n).nSpecies();
|
||||
for (k = 0; k < nsp; k++) {
|
||||
m_pot[ik] = Faraday*thermo(n).charge(k)*m_phi[n];
|
||||
ik++;
|
||||
}
|
||||
}
|
||||
|
||||
// compute the change in electrical potential energy for each
|
||||
// reaction. This will only be non-zero if a potential
|
||||
// difference is present.
|
||||
//fill(m_rwork.begin(), m_rwork.begin() + m_ii, 0.0);
|
||||
//m_reactantStoich.decrementReactions(m_pot.begin(), m_rwork.begin());
|
||||
//m_revProductStoich.incrementReactions(m_pot.begin(), m_rwork.begin());
|
||||
//m_irrevProductStoich.incrementReactions(m_pot.begin(), m_rwork.begin());
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_pot),
|
||||
DATA_PTR(m_rwork));
|
||||
|
||||
// modify the reaction rates. Only modify those with a
|
||||
// non-zero activation energy, and do not decrease the
|
||||
// activation energy below zero.
|
||||
doublereal ea, eamod;
|
||||
|
||||
for (i = 0; i < m_ii; i++) {
|
||||
eamod = 0.5*m_rwork[i];
|
||||
if (eamod != 0.0 && m_E[i] != 0.0) {
|
||||
ea = GasConstant * m_E[i];
|
||||
if (eamod + ea < 0.0) {
|
||||
eamod = -ea;
|
||||
writelog("warning: modified E < 0.\n");
|
||||
}
|
||||
kf[i] *= exp(-eamod*rrt);
|
||||
// if (kf[i] == 0.0) {
|
||||
// for (n = 0; n < np; n++) {
|
||||
// cout << "phi " << n << " " << thermo(n).electricPotential() << " " << m_phi[n] << endl;
|
||||
// }
|
||||
// cout << "Zero rate coeff." << endl;
|
||||
// cout << "eamod = " << eamod << " " << eamod*rrt << endl;
|
||||
// cout << eamod/Faraday << endl;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Update the rates of progress of the reactions in the reaciton
|
||||
* mechanism. This routine operates on internal data.
|
||||
*/
|
||||
void InterfaceKinetics::getFwdRateConstants(doublereal* kfwd) {
|
||||
|
||||
_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
|
||||
// copy rate coefficients into kfwd
|
||||
copy(rf.begin(), rf.end(), kfwd);
|
||||
|
||||
// multiply by perturbation factor
|
||||
multiply_each(kfwd, kfwd + nReactions(), m_perturb.begin());
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update the rates of progress of the reactions in the reaciton
|
||||
* mechanism. This routine operates on internal data.
|
||||
*/
|
||||
void InterfaceKinetics::getRevRateConstants(doublereal* krev, bool doIrreversible) {
|
||||
getFwdRateConstants(krev);
|
||||
if (doIrreversible) {
|
||||
doublereal *tmpKc = DATA_PTR(m_kdata->m_ropnet);
|
||||
getEquilibriumConstants(tmpKc);
|
||||
for (int i = 0; i < m_ii; i++) {
|
||||
krev[i] /= tmpKc[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
const vector_fp& rkc = m_kdata->m_rkcn;
|
||||
multiply_each(krev, krev + nReactions(), rkc.begin());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterfaceKinetics::getActivationEnergies(doublereal *E) {
|
||||
copy(m_E.begin(), m_E.end(), E);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the rates of progress of the reactions in the reaciton
|
||||
* mechanism. This routine operates on internal data.
|
||||
*/
|
||||
void InterfaceKinetics::updateROP() {
|
||||
|
||||
_update_rates_T();
|
||||
_update_rates_C();
|
||||
|
||||
if (m_kdata->m_ROP_ok) return;
|
||||
|
||||
const vector_fp& rf = m_kdata->m_rfn;
|
||||
const vector_fp& m_rkc = m_kdata->m_rkcn;
|
||||
array_fp& ropf = m_kdata->m_ropf;
|
||||
array_fp& ropr = m_kdata->m_ropr;
|
||||
array_fp& ropnet = m_kdata->m_ropnet;
|
||||
|
||||
// copy rate coefficients into ropf
|
||||
copy(rf.begin(), rf.end(), ropf.begin());
|
||||
|
||||
// multiply by perturbation factor
|
||||
multiply_each(ropf.begin(), ropf.end(), m_perturb.begin());
|
||||
|
||||
// copy the forward rates to the reverse rates
|
||||
copy(ropf.begin(), ropf.end(), ropr.begin());
|
||||
|
||||
// for reverse rates computed from thermochemistry, multiply
|
||||
// the forward rates copied into m_ropr by the reciprocals of
|
||||
// the equilibrium constants
|
||||
multiply_each(ropr.begin(), ropr.end(), m_rkc.begin());
|
||||
|
||||
// multiply ropf by concentration products
|
||||
m_rxnstoich.multiplyReactants(DATA_PTR(m_conc), DATA_PTR(ropf));
|
||||
//m_reactantStoich.multiply(m_conc.begin(), ropf.begin());
|
||||
|
||||
// for reversible reactions, multiply ropr by concentration
|
||||
// products
|
||||
m_rxnstoich.multiplyRevProducts(DATA_PTR(m_conc),
|
||||
DATA_PTR(ropr));
|
||||
//m_revProductStoich.multiply(m_conc.begin(), ropr.begin());
|
||||
|
||||
// do global reactions
|
||||
//m_globalReactantStoich.power(m_conc.begin(), ropf.begin());
|
||||
|
||||
for (int j = 0; j != m_ii; ++j) {
|
||||
ropnet[j] = ropf[j] - ropr[j];
|
||||
}
|
||||
|
||||
m_kdata->m_ROP_ok = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaGibbs():
|
||||
*
|
||||
* Return the vector of values for the reaction gibbs free energy
|
||||
* change
|
||||
* These values depend upon the concentration
|
||||
* of the ideal gas.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaGibbs(doublereal* deltaG) {
|
||||
/*
|
||||
* Get the chemical potentials of the species in the
|
||||
* ideal gas solution.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getChemPotentials(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaG);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaEnthalpy():
|
||||
*
|
||||
* Return the vector of values for the reactions change in
|
||||
* enthalpy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaEnthalpy(doublereal* deltaH) {
|
||||
/*
|
||||
* Get the partial molar enthalpy of all species in the
|
||||
* ideal gas.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getPartialMolarEnthalpies(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaH);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* getDeltaEntropy():
|
||||
*
|
||||
* Return the vector of values for the reactions change in
|
||||
* entropy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaEntropy( doublereal* deltaS) {
|
||||
/*
|
||||
* Get the partial molar entropy of all species in the
|
||||
* solid solution.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getPartialMolarEntropies(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaS for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaSSGibbs():
|
||||
*
|
||||
* Return the vector of values for the reaction
|
||||
* standard state gibbs free energy change.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaSSGibbs(doublereal* deltaG) {
|
||||
/*
|
||||
* Get the standard state chemical potentials of the species.
|
||||
* This is the array of chemical potentials at unit activity
|
||||
* We define these here as the chemical potentials of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getStandardChemPotentials(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaG);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* getDeltaSSEnthalpy():
|
||||
*
|
||||
* Return the vector of values for the change in the
|
||||
* standard state enthalpies of reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaSSEnthalpy(doublereal* deltaH) {
|
||||
/*
|
||||
* Get the standard state enthalpies of the species.
|
||||
* This is the array of chemical potentials at unit activity
|
||||
* We define these here as the enthalpies of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getEnthalpy_RT(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
doublereal RT = thermo().temperature() * GasConstant;
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
m_grt[k] *= RT;
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaG for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaH);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* getDeltaSSEntropy():
|
||||
*
|
||||
* Return the vector of values for the change in the
|
||||
* standard state entropies for each reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
void InterfaceKinetics::getDeltaSSEntropy(doublereal* deltaS) {
|
||||
/*
|
||||
* Get the standard state entropy of the species.
|
||||
* We define these here as the entropies of the pure
|
||||
* species at the temperature and pressure of the solution.
|
||||
*/
|
||||
int np = nPhases();
|
||||
int n;
|
||||
for (n = 0; n < np; n++) {
|
||||
thermo(n).getEntropy_R(DATA_PTR(m_grt) + m_start[n]);
|
||||
}
|
||||
doublereal R = GasConstant;
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
m_grt[k] *= R;
|
||||
}
|
||||
/*
|
||||
* Use the stoichiometric manager to find deltaS for each
|
||||
* reaction.
|
||||
*/
|
||||
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a single reaction to the mechanism. This routine
|
||||
* must be called after init() and before finalize().
|
||||
* This function branches on the types of reactions allowed
|
||||
* by the interfaceKinetics manager in order to install
|
||||
* the reaction correctly in the manager.
|
||||
* The manager allows the following reaction types
|
||||
* Elementary
|
||||
* Surface
|
||||
* Global
|
||||
* There is no difference between elementary and surface
|
||||
* reactions.
|
||||
*/
|
||||
void InterfaceKinetics::
|
||||
addReaction(const ReactionData& r) {
|
||||
|
||||
addElementaryReaction(r);
|
||||
|
||||
// operations common to all reaction types
|
||||
installReagents( r );
|
||||
//installGroups(reactionNumber(), r.rgroups, r.pgroups);
|
||||
incrementRxnCount();
|
||||
m_rxneqn.push_back(r.equation);
|
||||
}
|
||||
|
||||
|
||||
void InterfaceKinetics::
|
||||
addElementaryReaction(const ReactionData& r) {
|
||||
int iloc;
|
||||
// install rate coeff calculator
|
||||
vector_fp rp = r.rateCoeffParameters;
|
||||
int ncov = r.cov.size();
|
||||
if (ncov > 3) {
|
||||
m_has_coverage_dependence = true;
|
||||
}
|
||||
for (int m = 0; m < ncov; m++) rp.push_back(r.cov[m]);
|
||||
iloc = m_rates.install( reactionNumber(),
|
||||
r.rateCoeffType, rp.size(),
|
||||
DATA_PTR(rp) );
|
||||
// store activation energy
|
||||
m_E.push_back(r.rateCoeffParameters[2]);
|
||||
// add constant term to rate coeff value vector
|
||||
m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
registerReaction( reactionNumber(), ELEMENTARY_RXN, iloc);
|
||||
}
|
||||
|
||||
|
||||
// void InterfaceKinetics::
|
||||
// addGlobalReaction(const ReactionData& r) {
|
||||
|
||||
// int iloc;
|
||||
// // install rate coeff calculator
|
||||
// vector_fp rp = r.rateCoeffParameters;
|
||||
// int ncov = r.cov.size();
|
||||
// for (int m = 0; m < ncov; m++) rp.push_back(r.cov[m]);
|
||||
// iloc = m_rates.install( reactionNumber(),
|
||||
// r.rateCoeffType, rp.size(),
|
||||
// rp.begin() );
|
||||
// // store activation energy
|
||||
// m_E.push_back(r.rateCoeffParameters[2]);
|
||||
// // add constant term to rate coeff value vector
|
||||
// m_kdata->m_rfn.push_back(r.rateCoeffParameters[0]);
|
||||
|
||||
// int nr = r.order.size();
|
||||
// vector_fp ordr(nr);
|
||||
// for (int n = 0; n < nr; n++) {
|
||||
// ordr[n] = r.order[n] - r.rstoich[n];
|
||||
// }
|
||||
// m_globalReactantStoich.add( reactionNumber(),
|
||||
// r.reactants, ordr);
|
||||
|
||||
// registerReaction( reactionNumber(), GLOBAL_RXN, iloc);
|
||||
// }
|
||||
|
||||
|
||||
void InterfaceKinetics::installReagents(const ReactionData& r) {
|
||||
|
||||
int n, ns, m;
|
||||
doublereal nsFlt;
|
||||
/*
|
||||
* extend temporary storage by one for this rxn.
|
||||
*/
|
||||
m_kdata->m_ropf.push_back(0.0);
|
||||
m_kdata->m_ropr.push_back(0.0);
|
||||
m_kdata->m_ropnet.push_back(0.0);
|
||||
m_kdata->m_rkcn.push_back(0.0);
|
||||
|
||||
/*
|
||||
* Obtain the current reaction index for the reaction that we
|
||||
* are adding. The first reaction is labeled 0.
|
||||
*/
|
||||
int rnum = reactionNumber();
|
||||
|
||||
// vectors rk and pk are lists of species numbers, with
|
||||
// repeated entries for species with stoichiometric
|
||||
// coefficients > 1. This allows the reaction to be defined
|
||||
// with unity reaction order for each reactant, and so the
|
||||
// faster method 'multiply' can be used to compute the rate of
|
||||
// progress instead of 'power'.
|
||||
|
||||
vector_int rk;
|
||||
int nr = r.reactants.size();
|
||||
for (n = 0; n < nr; n++) {
|
||||
nsFlt = r.rstoich[n];
|
||||
ns = (int) nsFlt;
|
||||
if ((doublereal) ns != nsFlt) {
|
||||
if (ns < 1) ns = 1;
|
||||
}
|
||||
/*
|
||||
* Add to m_rrxn. m_rrxn is a vector of maps. m_rrxn has a length
|
||||
* equal to the total number of species for each species, there
|
||||
* exists a map, with the reaction number being the key, and the
|
||||
* reactant stoichiometric coefficient being the value.
|
||||
*/
|
||||
m_rrxn[r.reactants[n]][rnum] = ns;
|
||||
for (m = 0; m < ns; m++) {
|
||||
rk.push_back(r.reactants[n]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now that we have rk[], we add it into the vector<vector_int> m_reactants
|
||||
* in the rnum index spot. Thus m_reactants[rnum] yields a vector
|
||||
* of reactants for the rnum'th reaction
|
||||
*/
|
||||
m_reactants.push_back(rk);
|
||||
|
||||
vector_int pk;
|
||||
int np = r.products.size();
|
||||
for (n = 0; n < np; n++) {
|
||||
nsFlt = r.pstoich[n];
|
||||
ns = (int) nsFlt;
|
||||
if ((doublereal) ns != nsFlt) {
|
||||
if (ns < 1) ns = 1;
|
||||
}
|
||||
/*
|
||||
* Add to m_prxn. m_prxn is a vector of maps. m_prxn has a length
|
||||
* equal to the total number of species for each species, there
|
||||
* exists a map, with the reaction number being the key, and the
|
||||
* product stoichiometric coefficient being the value.
|
||||
*/
|
||||
m_prxn[r.products[n]][rnum] = ns;
|
||||
for (m = 0; m < ns; m++) {
|
||||
pk.push_back(r.products[n]);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Now that we have pk[], we add it into the vector<vector_int> m_products
|
||||
* in the rnum index spot. Thus m_products[rnum] yields a vector
|
||||
* of products for the rnum'th reaction
|
||||
*/
|
||||
m_products.push_back(pk);
|
||||
/*
|
||||
* Add this reaction to the stoichiometric coefficient manager. This
|
||||
* calculates rates of species production from reaction rates of
|
||||
* progress.
|
||||
*/
|
||||
m_rxnstoich.add( reactionNumber(), r);
|
||||
/*
|
||||
* register reaction in lists of reversible and irreversible rxns.
|
||||
*/
|
||||
if (r.reversible) {
|
||||
m_revindex.push_back(reactionNumber());
|
||||
m_nrev++;
|
||||
} else {
|
||||
m_irrev.push_back( reactionNumber() );
|
||||
m_nirrev++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//void InterfaceKinetics::installGroups(int irxn,
|
||||
// const vector<grouplist_t>& r, const vector<grouplist_t>& p) {
|
||||
// if (!r.empty()) {
|
||||
// m_rgroups[reactionNumber()] = r;
|
||||
// m_pgroups[reactionNumber()] = p;
|
||||
// }
|
||||
//}
|
||||
|
||||
/**
|
||||
* Prepare the class for the addition of reactions. This function
|
||||
* must be called after instantiation of the class, but before
|
||||
* any reactions are actually added to the mechanism.
|
||||
* This function calculates m_kk the number of species in all
|
||||
* phases participating in the reaction mechanism. We don't know
|
||||
* m_kk previously, before all phases have been added.
|
||||
*/
|
||||
void InterfaceKinetics::init() {
|
||||
int n;
|
||||
m_kk = 0;
|
||||
int np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
m_kk += thermo(n).nSpecies();
|
||||
}
|
||||
m_rrxn.resize(m_kk);
|
||||
m_prxn.resize(m_kk);
|
||||
m_conc.resize(m_kk);
|
||||
m_mu0.resize(m_kk);
|
||||
m_grt.resize(m_kk);
|
||||
m_pot.resize(m_kk, 0.0);
|
||||
m_phi.resize(np, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Finish adding reactions and prepare for use. This function
|
||||
* must be called after all reactions are entered into the mechanism
|
||||
* and before the mechanism is used to calculate reaction rates.
|
||||
*
|
||||
* Here, we resize work arrays based on the number of reactions,
|
||||
* since we don't know this number up to now.
|
||||
*/
|
||||
void InterfaceKinetics::finalize() {
|
||||
m_rwork.resize(nReactions());
|
||||
int ks = surfacePhaseIndex();
|
||||
if (ks < 0) throw CanteraError("InterfaceKinetics::finalize",
|
||||
"no surface phase is present.");
|
||||
m_surf = (SurfPhase*)&thermo(ks);
|
||||
m_finalized = true;
|
||||
}
|
||||
|
||||
|
||||
bool InterfaceKinetics::ready() const {
|
||||
return (m_finalized);
|
||||
}
|
||||
|
||||
void InterfaceKinetics::
|
||||
advanceCoverages(doublereal tstep) {
|
||||
if (m_integrator == 0) {
|
||||
vector<InterfaceKinetics*> k;
|
||||
k.push_back(this);
|
||||
m_integrator = new ImplicitSurfChem(k);
|
||||
m_integrator->initialize();
|
||||
}
|
||||
m_integrator->integrate(0.0, tstep);
|
||||
delete m_integrator;
|
||||
m_integrator = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
419
Cantera/src/kinetics/InterfaceKinetics.h
Normal file
419
Cantera/src/kinetics/InterfaceKinetics.h
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/**
|
||||
* @file InterfaceKinetics.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_IFACEKINETICS_H
|
||||
#define CT_IFACEKINETICS_H
|
||||
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mix_defs.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
#include "utilities.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
#include "ReactionStoichMgr.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
// forward references
|
||||
|
||||
class ReactionData;
|
||||
class InterfaceKineticsData;
|
||||
class ThermoPhase;
|
||||
class SurfPhase;
|
||||
class ImplicitSurfChem;
|
||||
|
||||
|
||||
/**
|
||||
* Holds mechanism-specific data.
|
||||
*/
|
||||
class InterfaceKineticsData {
|
||||
public:
|
||||
InterfaceKineticsData() :
|
||||
m_ROP_ok(false),
|
||||
m_temp(0.0), m_logtemp(0.0)
|
||||
{}
|
||||
virtual ~InterfaceKineticsData(){}
|
||||
|
||||
doublereal m_logp0, m_logc0;
|
||||
array_fp m_ropf, m_ropr, m_ropnet;
|
||||
//array_fp m_rfn_low, m_rfn_high;
|
||||
bool m_ROP_ok;
|
||||
|
||||
doublereal m_temp, m_logtemp;
|
||||
vector_fp m_rfn;
|
||||
vector_fp m_rkcn;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// A kinetics manager for heterogeneous reaction mechanisms. The
|
||||
/// reactions are assumed to occur at a 2D interface between two
|
||||
/// 3D phases.
|
||||
///
|
||||
class InterfaceKinetics : public Kinetics {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thermo The optional parameter may be used to initialize
|
||||
* the object with one ThermoPhase object.
|
||||
* HKM Note -> Since the interface kinetics
|
||||
* object will probably require multiple thermophase
|
||||
* objects, this is probably not a good idea
|
||||
* to have this parameter.
|
||||
*/
|
||||
InterfaceKinetics(thermo_t* thermo = 0);
|
||||
|
||||
|
||||
/// Destructor.
|
||||
virtual ~InterfaceKinetics();
|
||||
|
||||
virtual int ID() { return cInterfaceKinetics; }
|
||||
virtual int type() { return cInterfaceKinetics; }
|
||||
|
||||
///
|
||||
/// @name Reaction Rates Of Progress
|
||||
///
|
||||
//@{
|
||||
|
||||
|
||||
virtual void getFwdRatesOfProgress(doublereal* fwdROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropf.begin(), m_kdata->m_ropf.end(), fwdROP);
|
||||
}
|
||||
|
||||
virtual void getRevRatesOfProgress(doublereal* revROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropr.begin(), m_kdata->m_ropr.end(), revROP);
|
||||
}
|
||||
|
||||
virtual void getNetRatesOfProgress(doublereal* netROP) {
|
||||
updateROP();
|
||||
std::copy(m_kdata->m_ropnet.begin(), m_kdata->m_ropnet.end(), netROP);
|
||||
}
|
||||
|
||||
virtual void getEquilibriumConstants(doublereal* kc);
|
||||
|
||||
|
||||
virtual void getDeltaGibbs( doublereal* deltaG);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* enthalpy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaEnthalpy( doublereal* deltaH);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* entropy.
|
||||
* These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
virtual void getDeltaEntropy(doublereal* deltaS);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reaction
|
||||
* standard state gibbs free energy change.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaSSGibbs(doublereal* deltaG);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the
|
||||
* standard state enthalpies of reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*/
|
||||
virtual void getDeltaSSEnthalpy(doublereal* deltaH);
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the
|
||||
* standard state entropies for each reaction.
|
||||
* These values don't depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*/
|
||||
virtual void getDeltaSSEntropy(doublereal* deltaS);
|
||||
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Species Production Rates
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Species creation rates [kmol/m^2/s]. Return the species
|
||||
* creation rates in array cdot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species in all phases of the kinetics
|
||||
* model
|
||||
*
|
||||
*/
|
||||
virtual void getCreationRates(doublereal* cdot) {
|
||||
updateROP();
|
||||
m_rxnstoich.getCreationRates(m_kk, &m_kdata->m_ropf[0],
|
||||
&m_kdata->m_ropr[0], cdot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Species destruction rates [kmol/m^2/s]. Return the species
|
||||
* destruction rates in array ddot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species in all phases of the kinetics
|
||||
* model
|
||||
*
|
||||
*/
|
||||
virtual void getDestructionRates(doublereal* ddot) {
|
||||
updateROP();
|
||||
m_rxnstoich.getDestructionRates(m_kk, &m_kdata->m_ropf[0],
|
||||
&m_kdata->m_ropr[0], ddot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Species net production rates [kmol/m^2/s]. Return the species
|
||||
* net production rates (creation - destruction) in array
|
||||
* wdot, which must be dimensioned at least as large as the
|
||||
* total number of species in all phases of the kinetics
|
||||
* model
|
||||
*/
|
||||
virtual void getNetProductionRates(doublereal* net) {
|
||||
updateROP();
|
||||
m_rxnstoich.getNetProductionRates(m_kk,
|
||||
&m_kdata->m_ropnet[0],
|
||||
net);
|
||||
}
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Informational Query Routines
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a reactant in
|
||||
* reaction i.
|
||||
*/
|
||||
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
||||
return m_rrxn[k][i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a product in
|
||||
* reaction i.
|
||||
*/
|
||||
virtual doublereal productStoichCoeff(int k, int i) const {
|
||||
return m_prxn[k][i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag specifying the type of reaction. The legal values and
|
||||
* their meaning are specific to the particular kinetics
|
||||
* manager.
|
||||
*/
|
||||
virtual int reactionType(int i) const {
|
||||
return m_index[i].first;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if reaction i has been declared to be reversible. If
|
||||
* isReversible(i) is false, then the reverse rate of progress
|
||||
* for reaction i is always zero.
|
||||
*/
|
||||
virtual bool isReversible(int i) {
|
||||
if (std::find(m_revindex.begin(), m_revindex.end(), i)
|
||||
< m_revindex.end()) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representing the reaction.
|
||||
*/
|
||||
virtual std::string reactionString(int i) const {
|
||||
return m_rxneqn[i];
|
||||
}
|
||||
|
||||
|
||||
virtual void getFwdRateConstants(doublereal* kfwd);
|
||||
virtual void getRevRateConstants(doublereal* krev,
|
||||
bool doIrreversible = false);
|
||||
virtual void getActivationEnergies(doublereal *E);
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Construction
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Prepare the class for the addition of reactions. This function
|
||||
* must be called after instantiation of the class, but before
|
||||
* any reactions are actually added to the mechanism.
|
||||
* This function calculates m_kk the number of species in all
|
||||
* phases participating in the reaction mechanism. We don't know
|
||||
* m_kk previously, before all phases have been added.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Add a single reaction to the mechanism.
|
||||
*/
|
||||
virtual void addReaction(const ReactionData& r);
|
||||
|
||||
/**
|
||||
* Finish adding reactions and prepare for use. This function
|
||||
* must be called after all reactions are entered into the mechanism
|
||||
* and before the mechanism is used to calculate reaction rates.
|
||||
*/
|
||||
virtual void finalize();
|
||||
virtual bool ready() const;
|
||||
|
||||
|
||||
void updateROP();
|
||||
|
||||
|
||||
//const std::vector<grouplist_t>& reactantGroups(int i)
|
||||
// { return m_rgroups[i]; }
|
||||
//const std::vector<grouplist_t>& productGroups(int i)
|
||||
// { return m_pgroups[i]; }
|
||||
|
||||
void _update_rates_T();
|
||||
void _update_rates_phi();
|
||||
void _update_rates_C();
|
||||
|
||||
void advanceCoverages(doublereal tstep);
|
||||
void checkPartialEquil();
|
||||
vector_fp m_grt;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* m_kk here is the number of species in all of the phases
|
||||
* that participate in the kinetics mechanism.
|
||||
*/
|
||||
int m_kk;
|
||||
vector_int m_revindex;
|
||||
|
||||
Rate1<SurfaceArrhenius> m_rates;
|
||||
bool m_redo_rates;
|
||||
|
||||
/**
|
||||
* Vector of information about reactions in the
|
||||
* mechanism.
|
||||
* The key is the reaction index (0 < i < m_ii).
|
||||
* The first pair is the reactionType of the reaction.
|
||||
* The second pair is ...
|
||||
*/
|
||||
mutable std::map<int, std::pair<int, int> > m_index;
|
||||
|
||||
std::vector<int> m_irrev;
|
||||
|
||||
ReactionStoichMgr m_rxnstoich;
|
||||
|
||||
int m_nirrev;
|
||||
|
||||
/**
|
||||
* Number of reversible reactions in the mechanism
|
||||
*/
|
||||
int m_nrev;
|
||||
|
||||
std::vector<int> m_rxntype;
|
||||
|
||||
/**
|
||||
* m_rrxn is a vector of maps. m_rrxn has a length
|
||||
* equal to the total number of species in the kinetics
|
||||
* object. For each species, there exists a map, with the
|
||||
* reaction number being the key, and the
|
||||
* reactant stoichiometric coefficient being the value.
|
||||
* HKM -> mutable because search sometimes creates extra
|
||||
* entries. To be fixed in future...
|
||||
*/
|
||||
mutable std::vector<std::map<int, doublereal> > m_rrxn;
|
||||
|
||||
/**
|
||||
* m_rrxn is a vector of maps. m_rrxn has a length
|
||||
* equal to the total number of species in the kinetics
|
||||
* object. For each species, there exists a map, with the
|
||||
* reaction number being the key, and the
|
||||
* product stoichiometric coefficient being the value.
|
||||
*/
|
||||
mutable std::vector<std::map<int, doublereal> > m_prxn;
|
||||
|
||||
|
||||
std::vector<std::string> m_rxneqn;
|
||||
|
||||
/**
|
||||
* Temporary data storage used in calculating the rates of
|
||||
* of reactions.
|
||||
*/
|
||||
InterfaceKineticsData* m_kdata;
|
||||
|
||||
/**
|
||||
* An array of generalized concentrations
|
||||
* \f$ C_k \f$ that are defined such that \f$ a_k = C_k /
|
||||
* C^0_k, \f$ where \f$ C^0_k \f$ is a standard concentration/
|
||||
* These generalized concentrations are used
|
||||
* by this kinetics manager class to compute the forward and
|
||||
* reverse rates of elementary reactions. The "units" for the
|
||||
* concentrations of each phase depend upon the implementation
|
||||
* of kinetics within that phase.
|
||||
* The order of the species within the vector is based on
|
||||
* the order of listed ThermoPhase objects in the class, and the
|
||||
* order of the species within each ThermoPhase class.
|
||||
*/
|
||||
vector_fp m_conc;
|
||||
|
||||
vector_fp m_mu0;
|
||||
vector_fp m_phi;
|
||||
vector_fp m_pot;
|
||||
vector_fp m_rwork;
|
||||
vector_fp m_E;
|
||||
|
||||
SurfPhase* m_surf;
|
||||
ImplicitSurfChem* m_integrator;
|
||||
|
||||
private:
|
||||
|
||||
int reactionNumber(){ return m_ii;}
|
||||
void addElementaryReaction(const ReactionData& r);
|
||||
void addGlobalReaction(const ReactionData& r);
|
||||
void installReagents(const ReactionData& r);
|
||||
|
||||
void updateKc();
|
||||
|
||||
void registerReaction(int rxnNumber, int type, int loc) {
|
||||
m_index[rxnNumber] = std::pair<int, int>(type, loc);
|
||||
}
|
||||
void applyButlerVolmerCorrection(doublereal* kf);
|
||||
bool m_finalized;
|
||||
bool m_has_coverage_dependence;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
234
Cantera/src/kinetics/Kinetics.cpp
Normal file
234
Cantera/src/kinetics/Kinetics.cpp
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
/**
|
||||
* @file Kinetics.cpp
|
||||
* Declarations for the base class for kinetics
|
||||
* managers (see \ref kineticsmgr and class
|
||||
* \link Cantera::Kinetics Kinetics\endlink).
|
||||
*
|
||||
* Kinetics managers calculate rates of progress of species due to homogeneous or heterogeneous kinetics.
|
||||
*/
|
||||
|
||||
// Copyright 2001-2004 California Institute of Technology
|
||||
|
||||
|
||||
|
||||
#include "InterfaceKinetics.h"
|
||||
#include "SurfPhase.h"
|
||||
#include "ReactionData.h"
|
||||
#include "StoichManager.h"
|
||||
#include "RateCoeffMgr.h"
|
||||
|
||||
#include "ImplicitSurfChem.h"
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
|
||||
Kinetics::Kinetics() : m_ii(0), m_thermo(0),
|
||||
m_index(-1), m_surfphase(-1), m_rxnphase(-1),
|
||||
m_mindim(4) {}
|
||||
|
||||
/*
|
||||
Kinetics::Kinetics(thermo_t* thermo) :
|
||||
m_ii(0),
|
||||
m_index(-1),
|
||||
m_surfphase(-1) ,
|
||||
m_rxnphase(0), m_mindim(4)
|
||||
{
|
||||
if (thermo) {
|
||||
addPhase(*thermo);
|
||||
}
|
||||
deprecatedMethod("Kinetics","Kinetics(thermo_t*)","Kinetics()");
|
||||
removeAtVersion("Kinetics(thermo_t*)","1.6.0");
|
||||
}
|
||||
*/
|
||||
|
||||
Kinetics::~Kinetics(){}
|
||||
|
||||
/**
|
||||
* Takes as input an array of properties for all species in the
|
||||
* mechanism and copies those values beloning to a particular
|
||||
* phase to the output array.
|
||||
* @param data Input data array.
|
||||
* @param phase Pointer to one of the phase objects participating
|
||||
* in this reaction mechanism
|
||||
* @param phase_data Output array where the values for the the
|
||||
* specified phase are to be written.
|
||||
*/
|
||||
void Kinetics::selectPhase(const doublereal* data, const thermo_t* phase,
|
||||
doublereal* phase_data) {
|
||||
int n, nsp, np = nPhases();
|
||||
for (n = 0; n < np; n++) {
|
||||
if (phase == m_thermo[n]) {
|
||||
nsp = phase->nSpecies();
|
||||
copy(data + m_start[n],
|
||||
data + m_start[n] + nsp, phase_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw CanteraError("Kinetics::selectPhase", "Phase not found.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* kineticsSpeciesName():
|
||||
*
|
||||
* Return the string name of the kth species in the kinetics
|
||||
* manager. k is an integer from 0 to ktot - 1, where ktot is
|
||||
* the number of species in the kinetics manager, which is the
|
||||
* sum of the number of species in all phases participating in
|
||||
* the kinetics manager. If k is out of bounds, the string
|
||||
* "<unknown>" is returned.
|
||||
*/
|
||||
string Kinetics::kineticsSpeciesName(int k) const {
|
||||
int np = m_start.size();
|
||||
for (int n = np-1; n >= 0; n--) {
|
||||
if (k >= m_start[n]) {
|
||||
return thermo(n).speciesName(k - m_start[n]);
|
||||
}
|
||||
}
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
/**
|
||||
* kineticsSpeciesIndex():
|
||||
*
|
||||
* This routine will look up a species number based on
|
||||
* the input string nm. The lookup of species will
|
||||
* occur for all phases listed in the kinetics object,
|
||||
* unless the string ph refers to a specific phase of
|
||||
* the object.
|
||||
*
|
||||
* return
|
||||
* - If a match is found, the position in the species list
|
||||
* is returned.
|
||||
* - If a specific phase is specified and no match is found,
|
||||
* the value -1 is returned.
|
||||
* - If no match is found in any phase, the value -2 is returned.
|
||||
*/
|
||||
int Kinetics::kineticsSpeciesIndex(std::string nm, std::string ph) const {
|
||||
int np = static_cast<int>(m_thermo.size());
|
||||
int k;
|
||||
string id;
|
||||
for (int n = 0; n < np; n++) {
|
||||
id = thermo(n).id();
|
||||
if (ph == id) {
|
||||
k = thermo(n).speciesIndex(nm);
|
||||
if (k < 0) return -1;
|
||||
return k + m_start[n];
|
||||
}
|
||||
else if (ph == "<any>") {
|
||||
/*
|
||||
* Call the speciesIndex() member function of the
|
||||
* ThermoPhase object to find a match.
|
||||
*/
|
||||
k = thermo(n).speciesIndex(nm);
|
||||
if (k >= 0) return k + m_start[n];
|
||||
}
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function looks up the string name of a species and
|
||||
* returns a reference to the ThermoPhase object of the
|
||||
* phase where the species resides.
|
||||
* Will throw an error if the species string doesn't match.
|
||||
*/
|
||||
thermo_t& Kinetics::speciesPhase(std::string nm) {
|
||||
int np = static_cast<int>(m_thermo.size());
|
||||
int k;
|
||||
string id;
|
||||
for (int n = 0; n < np; n++) {
|
||||
k = thermo(n).speciesIndex(nm);
|
||||
if (k >= 0) return thermo(n);
|
||||
}
|
||||
throw CanteraError("speciesPhase", "unknown species "+nm);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes as an argument the kineticsSpecies index
|
||||
* (i.e., the list index in the list of species in the kinetics
|
||||
* manager) and returns the index of the phase owning the
|
||||
* species.
|
||||
*/
|
||||
int Kinetics::speciesPhaseIndex(int k) {
|
||||
int np = m_start.size();
|
||||
for (int n = np-1; n >= 0; n--) {
|
||||
if (k >= m_start[n]) {
|
||||
return n;
|
||||
}
|
||||
}
|
||||
throw CanteraError("speciesPhaseIndex",
|
||||
"illegal species index: "+int2str(k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a phase to the kinetics manager object. This must
|
||||
* be done before the function init() is called or
|
||||
* before any reactions are input.
|
||||
* The following fields are updated:
|
||||
* m_start -> vector of integers, containing the
|
||||
* starting position of the species for
|
||||
* each phase in the kinetics mechanism.
|
||||
* m_surfphase -> index of the surface phase.
|
||||
* m_thermo -> vector of pointers to ThermoPhase phases
|
||||
* that participate in the kinetics
|
||||
* mechanism.
|
||||
* m_phaseindex -> map containing the string id of each
|
||||
* ThermoPhase phase as a key and the
|
||||
* index of the phase within the kinetics
|
||||
* manager object as the value.
|
||||
*/
|
||||
void Kinetics::addPhase(thermo_t& thermo) {
|
||||
|
||||
// if not the first thermo object, set the start position
|
||||
// to that of the last object added + the number of its species
|
||||
if (m_thermo.size() > 0) {
|
||||
m_start.push_back(m_start.back()
|
||||
+ m_thermo.back()->nSpecies());
|
||||
}
|
||||
// otherwise start at 0
|
||||
else {
|
||||
m_start.push_back(0);
|
||||
}
|
||||
|
||||
// the phase with lowest dimensionality is assumed to be the
|
||||
// phase/interface at which reactions take place
|
||||
if (thermo.nDim() <= m_mindim) {
|
||||
m_mindim = thermo.nDim();
|
||||
m_rxnphase = nPhases();
|
||||
}
|
||||
|
||||
// there should only be one surface phase
|
||||
int ptype = -100;
|
||||
if (type() == cEdgeKinetics) ptype = cEdge;
|
||||
else if (type() == cInterfaceKinetics) ptype = cSurf;
|
||||
if (thermo.eosType() == ptype) {
|
||||
// if (m_surfphase >= 0) {
|
||||
// throw CanteraError("Kinetics::addPhase",
|
||||
// "cannot add more than one surface phase");
|
||||
// }
|
||||
m_surfphase = nPhases();
|
||||
m_rxnphase = nPhases();
|
||||
}
|
||||
m_thermo.push_back(&thermo);
|
||||
m_phaseindex[m_thermo.back()->id()] = nPhases();
|
||||
}
|
||||
|
||||
|
||||
//! Private function of the class Kinetics, indicating that a function
|
||||
//! inherited from the base class hasn't had a definition assigned to it
|
||||
/*!
|
||||
* @param m String message
|
||||
*/
|
||||
void Kinetics::err(std::string m) const {
|
||||
throw CanteraError("Kinetics::" + m,
|
||||
"The default Base class method was called, when "
|
||||
"the inherited class's method should "
|
||||
"have been called");
|
||||
}
|
||||
|
||||
}
|
||||
956
Cantera/src/kinetics/Kinetics.h
Executable file
956
Cantera/src/kinetics/Kinetics.h
Executable file
|
|
@ -0,0 +1,956 @@
|
|||
/**
|
||||
* @file Kinetics.h
|
||||
* Base class for kinetics managers and also contains the kineticsmgr
|
||||
* module documentation (see \ref kineticsmgr and class
|
||||
* \link Cantera::Kinetics Kinetics\endlink).
|
||||
*
|
||||
* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*/
|
||||
|
||||
// Copyright 2001-2004 California Institute of Technology
|
||||
|
||||
#ifndef CT_KINETICS_H
|
||||
#define CT_KINETICS_H
|
||||
|
||||
#include "ctexceptions.h"
|
||||
#include "ThermoPhase.h"
|
||||
#include "mix_defs.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
// forward references
|
||||
class ReactionData;
|
||||
|
||||
/// @defgroup kineticsmgr Kinetics Managers
|
||||
/// @section kinmodman Models and Managers
|
||||
///
|
||||
/// A kinetics manager is a C++ class that implements a kinetics
|
||||
/// model; a kinetics model is a set of mathematical equation
|
||||
/// describing how various kinetic quanities are to be computed --
|
||||
/// reaction rates, species production rates, etc. Many different
|
||||
/// kinetics models might be defined to handle different types of
|
||||
/// kinetic processes. For example, one kinetics model might use
|
||||
/// expressions valid for elementary reactions in ideal gas
|
||||
/// mixtures. It might, for example, require the reaction orders
|
||||
/// to be integral and equal to the forward stoichiometric
|
||||
/// coefficients, require that each reaction be reversible with a
|
||||
/// reverse rate satisfying detailed balance, include
|
||||
/// pressure-dependent unimolecular reactions, etc. Another
|
||||
/// kinetics model might be designed for heterogeneous chemistry
|
||||
/// at interfaces, and might allow empirical reaction orders,
|
||||
/// coverage-dependent activation energies, irreversible
|
||||
/// reactions, and include effects of potential differences across
|
||||
/// the interface on reaction rates.
|
||||
///
|
||||
/// A kinetics manager implements a kinetics model. Since the
|
||||
/// model equations may be complex and expensive to evaluate, a
|
||||
/// kinetics manager may adopt various strategies to 'manage' the
|
||||
/// computation and evaluate the expressions efficiently. For
|
||||
/// example, if there are rate coefficients or other quantities
|
||||
/// that depend only on temperature, a manager class may choose to
|
||||
/// store these quantities internally, and re-evaluate them only
|
||||
/// when the temperature has actually changed. Or a manager
|
||||
/// designed for use with reaction mechanisms with a few repeated
|
||||
/// activation energies might precompute the terms \f$ exp(-E/RT)
|
||||
/// \f$, instead of evaluating the exponential repeatedly for each
|
||||
/// reaction. There are many other possible 'management styles',
|
||||
/// each of which might be better suited to some reaction
|
||||
/// mechanisms than others.
|
||||
///
|
||||
/// But however a manager structures the internal computation, the
|
||||
/// tasks the manager class must perform are, for the most part,
|
||||
/// the same. It must be able to compute reaction rates, species
|
||||
/// production rates, equilibrium constants, etc. Therefore, all
|
||||
/// kinetics manager classes should have a common set of public
|
||||
/// methods, but differ in how they implement these methods.
|
||||
///
|
||||
/// A kinetics manager computes reaction rates of progress,
|
||||
/// species production rates, equilibrium constants, and similar
|
||||
/// quantities for a reaction mechanism. All kinetics manager
|
||||
/// classes derive from class Kinetics, which defines a common
|
||||
/// public interface for all kinetics managers. Each derived class
|
||||
/// overloads the virtual methods of Kinetics to implement a
|
||||
/// particular kinetics model.
|
||||
///
|
||||
/// For example, class GasKinetics implements reaction rate
|
||||
/// expressions appropriate for homogeneous reactions in ideal gas
|
||||
/// mixtures, and class InterfaceKinetics implements expressions
|
||||
/// appropriate for heterogeneous mechanisms at interfaces,
|
||||
/// including how to handle reactions involving charged species of
|
||||
/// phases with different electric potentials --- something that
|
||||
/// class GasKinetics doesn't deal with at all.
|
||||
///
|
||||
/// Kinetics managers may be also created that hard-wire a
|
||||
/// particular reaction mechanism in C++ code. This can often
|
||||
/// result in faster performance. An example of this is the
|
||||
/// kinetics manager GRI30_Kinetics that hard-wires the rate
|
||||
/// expressions for the natural gas combustion mechanism GRI-3.0.
|
||||
///
|
||||
/// Many of the methods of class Kinetics write into arrays the
|
||||
/// values of some quantity for each species, for example the net
|
||||
/// production rate. These methods always write the results into
|
||||
/// flat arrays, ordered by phase in the order the phase was
|
||||
/// added, and within a phase in the order the species were added
|
||||
/// to the phase (which is the same ordering as in the input
|
||||
/// file). Example: suppose a heterogeneous mechanism involves
|
||||
/// three phases -- a bulk phase 'a', another bulk phase 'b', and
|
||||
/// the surface phase 'a:b' at the a/b interface. Phase 'a'
|
||||
/// contains 12 species, phase 'b' contains 3, and at the
|
||||
/// interface there are 5 adsorbed species defined in phase
|
||||
/// 'a:b'. Then methods like getNetProductionRates(doublereal* net)
|
||||
/// will write and output array of length 20, beginning at the location
|
||||
/// pointed to by 'net'. The first 12 values will be the net production
|
||||
/// rates for all 12 species of phase 'a' (even if some do not participate
|
||||
/// in the reactions), the next 3 will be for phase 'b', and finally the
|
||||
/// net production rates for the surface species will occupy the last
|
||||
/// 5 locations.
|
||||
|
||||
|
||||
//! Public interface for kinetics managers.
|
||||
/*!
|
||||
* This class serves as a
|
||||
* base class to derive 'kinetics managers', which are classes
|
||||
* that manage homogeneous chemistry within one phase, or
|
||||
* heterogeneous chemistry at one interface. The virtual methods
|
||||
* of this class are meant to be overloaded in subclasses. The
|
||||
* non-virtual methods perform generic functions and are
|
||||
* implemented in Kinetics. They should not be overloaded. Only
|
||||
* those methods required by a subclass need to be overloaded;
|
||||
* the rest will throw exceptions if called. @ingroup kinetics
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
class Kinetics {
|
||||
|
||||
public:
|
||||
|
||||
//! typedef for ThermoPhase
|
||||
typedef ThermoPhase thermo_t;
|
||||
|
||||
/**
|
||||
* @name Constructors and General Information about Mechanism
|
||||
*/
|
||||
//@{
|
||||
|
||||
/// Default constructor.
|
||||
Kinetics();
|
||||
|
||||
/// This constructor initializes with a starting phase.
|
||||
/// @deprecated
|
||||
// Kinetics(thermo_t* thermo);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~Kinetics();
|
||||
|
||||
/// Identifies the kinetics manager type. Each class derived
|
||||
/// from Kinetics should overload this method to return a
|
||||
/// unique integer. Standard values are defined in file
|
||||
/// mix_defs.h.
|
||||
virtual int type() { return 0; }
|
||||
|
||||
/// Number of reactions in the reaction mechanism.
|
||||
int nReactions() const {return m_ii;}
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
/**
|
||||
* @name Information/Lookup Functions about Phases and Species
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* The number of phases participating in the reaction
|
||||
* mechanism. For a homogeneous reaction mechanism, this will
|
||||
* always return 1, but for a heterogeneous mechanism it will
|
||||
* return the total number of phases in the mechanism.
|
||||
*/
|
||||
int nPhases() const { return static_cast<int>(m_thermo.size()); }
|
||||
|
||||
/**
|
||||
* Return the phase index of a phase in the list of phases
|
||||
* defined within the object.
|
||||
*
|
||||
* @param ph std::string name of the phase
|
||||
*
|
||||
* If a -1 is returned, then the phase is not defined in
|
||||
* the Kinetics object.
|
||||
*/
|
||||
int phaseIndex(std::string ph) {
|
||||
if (m_phaseindex.find(ph) == m_phaseindex.end()) {
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return m_phaseindex[ph] - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the integer index of the phase which has
|
||||
* ThermoPhase type cSurf. For heterogeneous mechanisms, this
|
||||
* identifies the one surface phase. For homogeneous
|
||||
* mechanisms, this reurns -1.
|
||||
*/
|
||||
int surfacePhaseIndex() { return m_surfphase; }
|
||||
|
||||
/**
|
||||
* Phase where the reactions occur. For heterogeneous
|
||||
* mechanisms, one of the phases in the list of phases
|
||||
* represents the 2D interface or 1D edge at which the
|
||||
* reactions take place. This method returns the index of the
|
||||
* phase with the smallest spatial dimension (1, 2, or 3)
|
||||
* among the list of phases. If there is more than one, the
|
||||
* index of the first one is returned. For homogeneous
|
||||
* mechanisms, the value 0 is returned.
|
||||
*/
|
||||
int reactionPhaseIndex() { return m_rxnphase; }
|
||||
|
||||
|
||||
/**
|
||||
* This method returns a reference to the nth ThermoPhase
|
||||
* object defined in this kinetics mechanism. It is typically
|
||||
* used so that member functions of the ThermoPhase object may
|
||||
* be called. For homogeneous mechanisms, there is only one
|
||||
* object, and this method can be called without an argument
|
||||
* to access it.
|
||||
*
|
||||
* @param n Index of the ThermoPhase being sought.
|
||||
*/
|
||||
thermo_t& thermo(int n=0) { return *m_thermo[n]; }
|
||||
const thermo_t& thermo(int n=0) const { return *m_thermo[n]; }
|
||||
|
||||
/**
|
||||
* This method returns a reference to the nth ThermoPhase
|
||||
* defined in this kinetics mechanism.
|
||||
* It is typically used so that member functions of the
|
||||
* ThermoPhase may be called. @deprecated This method is redundant.
|
||||
*
|
||||
* @param n Index of the ThermoPhase being sought.
|
||||
*/
|
||||
thermo_t& phase(int n=0) {
|
||||
deprecatedMethod("Kinetics","phase","thermo");
|
||||
return *m_thermo[n];
|
||||
}
|
||||
/**
|
||||
* This method returns a reference to the nth ThermoPhase
|
||||
* defined in this kinetics mechanism.
|
||||
* It is typically used so that member functions of the
|
||||
* ThermoPhase may be called. @deprecated This method is redundant.
|
||||
*
|
||||
* @param n Index of the ThermoPhase being sought.
|
||||
*/
|
||||
const thermo_t& phase(int n=0) const {
|
||||
deprecatedMethod("Kinetics","phase","thermo");
|
||||
return *m_thermo[n];
|
||||
}
|
||||
|
||||
/**
|
||||
* The total number of species in all phases participating in
|
||||
* the kinetics mechanism. This is useful to dimension arrays
|
||||
* for use in calls to methods that return the species
|
||||
* production rates, for example.
|
||||
*/
|
||||
int nTotalSpecies() const {
|
||||
int n=0, np;
|
||||
np = nPhases();
|
||||
for (int p = 0; p < np; p++) n += thermo(p).nSpecies();
|
||||
return n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the starting index of the species in the nth phase
|
||||
* associated with the reaction mechanism.
|
||||
*
|
||||
* @param n Return the index of first species in the nth phase
|
||||
* associated with the reaction mechanism.
|
||||
*/
|
||||
int start(int n) {
|
||||
deprecatedMethod("Kinetics","start","kineticsSpeciesIndex(0,n)");
|
||||
return m_start[n];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The location of species k of phase n in species arrays.
|
||||
* Kinetics manager classes return species production rates in
|
||||
* flat arrays, with the species of each phases following one
|
||||
* another, in the order the phases were added. This method
|
||||
* is useful to find the value for a particular species of a
|
||||
* particular phase in arrrays returned from methods like
|
||||
* getCreationRates that return an array of species-specific
|
||||
* quantities.
|
||||
*
|
||||
* Example: suppose a heterogeneous mechanism involves three
|
||||
* phases. The first contains 12 species, the second 26, and
|
||||
* the third 3. Then species arrays must have size at least
|
||||
* 41, and positions 0 - 11 are the values for the species in
|
||||
* the first phase, positions 12 - 37 are the values for the
|
||||
* species in the second phase, etc. Then
|
||||
* kineticsSpeciesIndex(7, 0) = 7, kineticsSpeciesIndex(4, 1)
|
||||
* = 16, and kineticsSpeciesIndex(2, 2) = 40.
|
||||
*
|
||||
* @param k species index
|
||||
* @param n phase index for the species
|
||||
*/
|
||||
int kineticsSpeciesIndex(int k, int n) const {
|
||||
return m_start[n] + k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the std::string name of the kth species in the kinetics
|
||||
* manager. k is an integer from 0 to ktot - 1, where ktot is
|
||||
* the number of species in the kinetics manager, which is the
|
||||
* sum of the number of species in all phases participating in
|
||||
* the kinetics manager. If k is out of bounds, the std::string
|
||||
* "<unknown>" is returned.
|
||||
*
|
||||
* @param k species index
|
||||
*/
|
||||
std::string kineticsSpeciesName(int k) const;
|
||||
|
||||
/**
|
||||
* This routine will look up a species number based on
|
||||
* the input std::string nm. The lookup of species will
|
||||
* occur for all phases listed in the kinetics object,
|
||||
* unless the std::string ph refers to a specific phase of
|
||||
* the object.
|
||||
*
|
||||
* return
|
||||
* - If a match is found, the position in the species list
|
||||
* is returned.
|
||||
* - If a specific phase is specified and no match is found,
|
||||
* the value -1 is returned.
|
||||
* - If no match is found in any phase, the value -2 is returned.
|
||||
*
|
||||
* @param nm Input string name of the species
|
||||
* @param ph Input string name of the phase. Defaults to "<any>"
|
||||
*/
|
||||
int kineticsSpeciesIndex(std::string nm, std::string ph = "<any>") const;
|
||||
|
||||
/**
|
||||
* This function looks up the std::string name of a species and
|
||||
* returns a reference to the ThermoPhase object of the
|
||||
* phase where the species resides.
|
||||
* Will throw an error if the species std::string doesn't match.
|
||||
*
|
||||
* @param nm String containing the name of the species.
|
||||
*/
|
||||
thermo_t& speciesPhase(std::string nm);
|
||||
|
||||
/**
|
||||
* This function takes as an argument the kineticsSpecies index
|
||||
* (i.e., the list index in the list of species in the kinetics
|
||||
* manager) and returns the species' owning ThermoPhase object.
|
||||
*
|
||||
* @param k Species index
|
||||
*/
|
||||
thermo_t& speciesPhase(int k) {
|
||||
return thermo(speciesPhaseIndex(k));
|
||||
}
|
||||
|
||||
/**
|
||||
* This function takes as an argument the kineticsSpecies index
|
||||
* (i.e., the list index in the list of species in the kinetics
|
||||
* manager) and returns the index of the phase owning the
|
||||
* species.
|
||||
*
|
||||
* @param k Species index
|
||||
*/
|
||||
int speciesPhaseIndex(int k);
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @name Reaction Rates Of Progress
|
||||
*/
|
||||
//@{
|
||||
|
||||
//! Return the forward rates of progress of the reactions
|
||||
/*!
|
||||
* Forward rates of progress. Return the forward rates of
|
||||
* progress in array fwdROP, which must be dimensioned at
|
||||
* least as large as the total number of reactions.
|
||||
*
|
||||
* @param fwdROP Output vector containing forward rates
|
||||
* of progress of the reactions. Length: m_ii.
|
||||
*/
|
||||
virtual void getFwdRatesOfProgress(doublereal* fwdROP) {
|
||||
err("getFwdRatesOfProgress");
|
||||
}
|
||||
|
||||
//! Return the Reverse rates of progress of the reactions
|
||||
/*!
|
||||
* Return the reverse rates of
|
||||
* progress in array revROP, which must be dimensioned at
|
||||
* least as large as the total number of reactions.
|
||||
*
|
||||
* @param revROP Output vector containing reverse rates
|
||||
* of progress of the reactions. Length: m_ii.
|
||||
*/
|
||||
virtual void getRevRatesOfProgress(doublereal* revROP) {
|
||||
err("getRevRatesOfProgress");
|
||||
}
|
||||
|
||||
/**
|
||||
* Net rates of progress. Return the net (forward - reverse)
|
||||
* rates of progress in array netROP, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* reactions.
|
||||
*
|
||||
* @param netROP Output vector of the net ROP. Length: m_ii.
|
||||
*/
|
||||
virtual void getNetRatesOfProgress(doublereal* netROP) {
|
||||
err("getNetRatesOfProgress");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! Return a vector of Equilibrium constants.
|
||||
/*!
|
||||
* Return the equilibrium constants of
|
||||
* the reactions in concentration units in array kc, which
|
||||
* must be dimensioned at least as large as the total number
|
||||
* of reactions.
|
||||
*
|
||||
* @param kc Output vector containing the equilibrium constants.
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getEquilibriumConstants(doublereal* kc) {
|
||||
err("getEquilibriumConstants");
|
||||
}
|
||||
|
||||
/**
|
||||
* Change in species properties. Given an array of molar species
|
||||
* property values \f$ z_k, k = 1, \dots, K \f$, return the
|
||||
* array of reaction values
|
||||
* \f[
|
||||
* \Delta Z_i = \sum_k \nu_{k,i} z_k, i = 1, \dots, I.
|
||||
* \f]
|
||||
* For example, if this method is called with the array of
|
||||
* standard-state molar Gibbs free energies for the species,
|
||||
* then the values returned in array \c deltaProperty would be
|
||||
* the standard-state Gibbs free energies of reaction for each
|
||||
* reaction.
|
||||
*
|
||||
* @param property Input vector of property value. Length: m_kk.
|
||||
* @param deltaProperty Output vector of deltaRxn. Length: m_ii.
|
||||
*/
|
||||
virtual void getReactionDelta(const doublereal* property,
|
||||
doublereal* deltaProperty) {
|
||||
err("getReactionDelta");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reaction gibbs free
|
||||
* energy change. These values depend upon the concentration
|
||||
* of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*
|
||||
* @param deltaG Output vector of deltaG's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaGibbs( doublereal* deltaG) {
|
||||
err("getDeltaGibbs");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* enthalpy. These values depend upon the concentration of
|
||||
* the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*
|
||||
* @param deltaH Output vector of deltaH's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaEnthalpy( doublereal* deltaH) {
|
||||
err("getDeltaEnthalpy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reactions change in
|
||||
* entropy. These values depend upon the concentration of the
|
||||
* solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*
|
||||
* @param deltaS Output vector of deltaS's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaEntropy( doublereal* deltaS) {
|
||||
err("getDeltaEntropy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the reaction standard state
|
||||
* gibbs free energy change. These values don't depend upon
|
||||
* the concentration of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*
|
||||
* @param deltaG Output vector of ss deltaG's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaSSGibbs( doublereal* deltaG) {
|
||||
err("getDeltaSSGibbs");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the standard
|
||||
* state enthalpies of reaction. These values don't depend
|
||||
* upon the concentration of the solution.
|
||||
*
|
||||
* units = J kmol-1
|
||||
*
|
||||
* @param deltaH Output vector of ss deltaH's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaSSEnthalpy( doublereal* deltaH) {
|
||||
err("getDeltaSSEnthalpy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vector of values for the change in the standard
|
||||
* state entropies for each reaction. These values don't
|
||||
* depend upon the concentration of the solution.
|
||||
*
|
||||
* units = J kmol-1 Kelvin-1
|
||||
*
|
||||
* @param deltaS Output vector of ss deltaS's for reactions
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getDeltaSSEntropy( doublereal* deltaS) {
|
||||
err("getDeltaSSEntropy");
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Species Production Rates
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Species creation rates [kmol/m^3/s or kmol/m^2/s]. Return the
|
||||
* species creation rates in array cdot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species in all phases. @see nTotalSpecies.
|
||||
*
|
||||
* @param cdot Output vector of creation rates.
|
||||
* Length: m_kk.
|
||||
*/
|
||||
virtual void getCreationRates(doublereal* cdot) {
|
||||
err("getCreationRates");
|
||||
}
|
||||
|
||||
/**
|
||||
* Species destruction rates [kmol/m^3/s or kmol/m^2/s]. Return
|
||||
* the species destruction rates in array ddot, which must be
|
||||
* dimensioned at least as large as the total number of
|
||||
* species. @see nTotalSpecies.
|
||||
*
|
||||
* @param ddot Output vector of destruction rates.
|
||||
* Length: m_kk.
|
||||
*/
|
||||
virtual void getDestructionRates(doublereal* ddot) {
|
||||
err("getDestructionRates");
|
||||
}
|
||||
|
||||
/**
|
||||
* Species net production rates [kmol/m^3/s or kmol/m^2/s]. Return
|
||||
* the species net production rates (creation - destruction)
|
||||
* in array wdot, which must be dimensioned at least as large
|
||||
* as the total number of species. @see nTotalSpecies.
|
||||
*
|
||||
* @param wdot Output vector of net production rates.
|
||||
* Length: m_kk.
|
||||
*/
|
||||
virtual void getNetProductionRates(doublereal* wdot) {
|
||||
err("getNetProductionRates");
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
/**
|
||||
* @name Reaction Mechanism Informational Query Routines
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a reactant in
|
||||
* reaction i.
|
||||
*
|
||||
* @param k species index
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual doublereal reactantStoichCoeff(int k, int i) const {
|
||||
err("reactantStoichCoeff");
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stoichiometric coefficient of species k as a product in
|
||||
* reaction i.
|
||||
*
|
||||
* @param k species index
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual doublereal productStoichCoeff(int k, int i) const {
|
||||
err("productStoichCoeff");
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* reactant Order of species k in reaction i.
|
||||
*
|
||||
* @param k species index
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual doublereal reactantOrder(int k, int i) const {
|
||||
err("reactantOrder");
|
||||
return -1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only reference to the vector of reactant
|
||||
* index numbers for reaction i.
|
||||
*
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual const vector_int& reactants(int i) const {
|
||||
return m_reactants[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only reference to the vector of product
|
||||
* index numbers for reaction i.
|
||||
*
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual const vector_int& products(int i) const {
|
||||
return m_products[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Flag specifying the type of reaction. The legal values and
|
||||
* their meaning are specific to the particular kinetics
|
||||
* manager.
|
||||
*
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual int reactionType(int i) const {
|
||||
err("reactionType");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if reaction i has been declared to be reversible. If
|
||||
* isReversible(i) is false, then the reverse rate of progress
|
||||
* for reaction i is always zero.
|
||||
*
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual bool isReversible(int i){
|
||||
err("isReversible");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a std::string representing the reaction.
|
||||
*
|
||||
* @param i reaction index
|
||||
*/
|
||||
virtual std::string reactionString(int i) const {
|
||||
err("reactionStd::String"); return "<null>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the forward rate constants
|
||||
*
|
||||
* length is the number of reactions. units depends
|
||||
* on many issues. @todo DGG: recommend changing name to
|
||||
* getFwdRateCoefficients.
|
||||
*
|
||||
* @param kfwd Output vector containing the foward reaction rate constants.
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getFwdRateConstants(doublereal *kfwd) {
|
||||
err("getFwdRateConstants");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reverse rate constants.
|
||||
*
|
||||
* length is the number of reactions. units depends
|
||||
* on many issues. Note, this routine will return rate constants
|
||||
* for irreversible reactions if the default for
|
||||
* doIrreversible is overridden. @todo DGG: recommend changing name to
|
||||
* getRevRateCoefficients.
|
||||
*
|
||||
* @param krev Output vector of reverse rate constants.
|
||||
* @param doIrreversible boolean indicating whether irreversible reactions
|
||||
* should be included.
|
||||
*/
|
||||
virtual void getRevRateConstants(doublereal *krev,
|
||||
bool doIrreversible = false) {
|
||||
err("getFwdRateConstants");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the activation energies in Kelvin.
|
||||
*
|
||||
* length is the number of reactions
|
||||
*
|
||||
* @param E Ouptut vector of activation energies.
|
||||
* Length: m_ii.
|
||||
*/
|
||||
virtual void getActivationEnergies(doublereal *E) {
|
||||
err("getActivationEnergies");
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Reaction Mechanism Construction
|
||||
*/
|
||||
//@{
|
||||
|
||||
/**
|
||||
* Add a phase to the kinetics manager object. This must
|
||||
* be done before the function init() is called or
|
||||
* before any reactions are input.
|
||||
* The following fields are updated:
|
||||
* m_start -> vector of integers, containing the
|
||||
* starting position of the species for
|
||||
* each phase in the kinetics mechanism.
|
||||
* m_surfphase -> index of the surface phase.
|
||||
* m_thermo -> vector of pointers to ThermoPhase phases
|
||||
* that participate in the kinetics
|
||||
* mechanism.
|
||||
* m_phaseindex -> map containing the std::string id of each
|
||||
* ThermoPhase phase as a key and the
|
||||
* index of the phase within the kinetics
|
||||
* manager object as the value.
|
||||
*
|
||||
* @param thermo Reference to the ThermoPhase to be added.
|
||||
*/
|
||||
void addPhase(thermo_t& thermo);
|
||||
|
||||
/**
|
||||
* Prepare the class for the addition of reactions. This
|
||||
* method is called by function importKinetics after all
|
||||
* phases have been added but before any reactions have
|
||||
* been. The base class method does nothing, but derived
|
||||
* classes may use this to perform any initialization
|
||||
* (allocating arrays, etc.) that requires knowing the phases
|
||||
* and species, but before any reactions are added.
|
||||
*/
|
||||
virtual void init() {}
|
||||
|
||||
/**
|
||||
* Finish adding reactions and prepare for use. This method is
|
||||
* called by function importKinetics after all reactions have
|
||||
* been entered into the mechanism and before the mechanism is
|
||||
* used to calculate reaction rates. The base class method
|
||||
* does nothing, but derived classes may use this to perform
|
||||
* any initialization (allocating arrays, etc.) that must be
|
||||
* done after the reactions are entered.
|
||||
*/
|
||||
virtual void finalize() {}
|
||||
|
||||
/**
|
||||
* Add a single reaction to the mechanism. This routine
|
||||
* must be called after init() and before finalize().
|
||||
*
|
||||
* @param r Reference to the ReactionRate object for the reaction
|
||||
* to be added.
|
||||
*/
|
||||
virtual void addReaction(const ReactionData& r) {
|
||||
err("addReaction");
|
||||
}
|
||||
|
||||
virtual const std::vector<grouplist_t>& reactantGroups(int i) {
|
||||
//err("reactantGroups");
|
||||
return m_dummygroups;
|
||||
}
|
||||
|
||||
virtual const std::vector<grouplist_t>& productGroups(int i) {
|
||||
//err("productGroups");
|
||||
return m_dummygroups;
|
||||
}
|
||||
|
||||
|
||||
//@}
|
||||
/**
|
||||
* @name Altering Reaction Rates
|
||||
*
|
||||
* These methods alter reaction rates. They are designed
|
||||
* primarily for carrying out sensitivity analysis, but may be
|
||||
* used for any purpose requiring dynamic alteration of rate
|
||||
* constants. For each reaction, a real-valued multiplier may
|
||||
* be defined that multiplies the reaction rate
|
||||
* coefficient. The multiplier may be set to zero to
|
||||
* completely remove a reaction from the mechanism.
|
||||
*/
|
||||
//@{
|
||||
|
||||
/// The current value of the multiplier for reaction i.
|
||||
/*!
|
||||
* @param i index of the reaction
|
||||
*/
|
||||
doublereal multiplier(int i) const {return m_perturb[i];}
|
||||
|
||||
/// Set the multiplier for reaction i to f.
|
||||
/*!
|
||||
* @param i index of the reaction
|
||||
* @param f value of the multiplier.
|
||||
*/
|
||||
void setMultiplier(int i, doublereal f) {m_perturb[i] = f;}
|
||||
|
||||
//@}
|
||||
|
||||
/**
|
||||
* Increment the number of reactions in the mechanism by one.
|
||||
* @todo Should be protected?
|
||||
*/
|
||||
void incrementRxnCount() { m_ii++; m_perturb.push_back(1.0); }
|
||||
|
||||
/**
|
||||
* Returns true if the kinetics manager has been properly
|
||||
* initialized and finalized.
|
||||
*/
|
||||
virtual bool ready() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract from array \c data the portion pertaining to phase \c phase.
|
||||
*
|
||||
* @param data data
|
||||
* @param phase phase
|
||||
* @param phase_data phase_data
|
||||
*/
|
||||
void selectPhase(const doublereal* data, const thermo_t* phase,
|
||||
doublereal* phase_data);
|
||||
|
||||
/// For internal use. May be removed in a future release.
|
||||
int index(){ return m_index; }
|
||||
|
||||
//! Set the index of the Kinetics Manager
|
||||
/*!
|
||||
* @param index input index
|
||||
*/
|
||||
void setIndex(int index) { m_index = index; }
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
//! Number of reactions in the mechanism
|
||||
int m_ii;
|
||||
|
||||
/// Vector of perturbation factors for each reaction's rate of
|
||||
/// progress vector. It is initialized to one.
|
||||
///
|
||||
vector_fp m_perturb;
|
||||
|
||||
/**
|
||||
* This is a vector of vectors containing the reactants for
|
||||
* each reaction. The outer vector is over the number of
|
||||
* reactions, m_ii. The inner vector is a list of species
|
||||
* indices. If the stoichiometric coefficient for a reactant
|
||||
* is greater than one, then the reactant is listed
|
||||
* contiguously in the vector a number of times equal to its
|
||||
* stoichiometric coefficient.
|
||||
* NOTE: These vectors will be wrong if there are real
|
||||
* stoichiometric coefficients in the expression.
|
||||
*/
|
||||
std::vector<vector_int> m_reactants;
|
||||
|
||||
/**
|
||||
* This is a vector of vectors containing the products for
|
||||
* each reaction. The outer vector is over the number of
|
||||
* reactions, m_ii. The inner vector is a list of species
|
||||
* indeces. If the stoichiometric coefficient for a product is
|
||||
* greater than one, then the reactant is listed contiguously
|
||||
* in the vector a number of times equal to its stoichiometric
|
||||
* coefficient.
|
||||
* NOTE: These vectors will be wrong if there are real
|
||||
* stoichiometric coefficients in the expression.
|
||||
*/
|
||||
std::vector<vector_int> m_products;
|
||||
|
||||
/**
|
||||
* m_thermo is a vector of pointers to ThermoPhase
|
||||
* objects. For homogeneous kinetics applications, this vector
|
||||
* will only have one entry. For interfacial reactions, this
|
||||
* vector will consist of multiple entries; some of them will
|
||||
* be surface phases, and the other ones will be bulk phases.
|
||||
* The order that the objects are listed determines the order
|
||||
* in which the species comprising each phase are listed in
|
||||
* the source term vector, originating from the reaction
|
||||
* mechanism.
|
||||
*/
|
||||
std::vector<thermo_t*> m_thermo;
|
||||
|
||||
/**
|
||||
* m_start is a vector of integers specifying the beginning position
|
||||
* for the species vector for the n'th phase in the kinetics
|
||||
* class.
|
||||
*/
|
||||
vector_int m_start;
|
||||
|
||||
/**
|
||||
* Mapping of the phase id, i.e., the id attribute in the xml
|
||||
* phase element to the position of the phase within the
|
||||
* kinetics object. Positions start with the value of 1. The
|
||||
* member function, phaseIndex() decrements by one before
|
||||
* returning the index value, so that missing phases return
|
||||
* -1.
|
||||
*/
|
||||
std::map<std::string, int> m_phaseindex;
|
||||
//! Index of the Kinetics Manager
|
||||
int m_index;
|
||||
|
||||
/**
|
||||
* Index in the list of phases of the one surface phase.
|
||||
*/
|
||||
int m_surfphase;
|
||||
|
||||
/**
|
||||
* Index in the list of phases of the one phase where the reactions
|
||||
* occur.
|
||||
*/
|
||||
int m_rxnphase;
|
||||
|
||||
/// number of spatial dimensions of lowest-dimensional phase.
|
||||
int m_mindim;
|
||||
|
||||
private:
|
||||
|
||||
//! Vector of group lists
|
||||
std::vector<grouplist_t> m_dummygroups;
|
||||
|
||||
//! Function for unhandled situations
|
||||
/*!
|
||||
* @param m String error message
|
||||
*/
|
||||
void err(std::string m) const;
|
||||
|
||||
};
|
||||
|
||||
//! typedef for the kinetics base class
|
||||
typedef Kinetics kinetics_t;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
152
Cantera/src/kinetics/KineticsFactory.cpp
Normal file
152
Cantera/src/kinetics/KineticsFactory.cpp
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* @file KineticsFactory.cpp
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable:4786)
|
||||
#endif
|
||||
|
||||
#include "KineticsFactory.h"
|
||||
|
||||
#include "GasKinetics.h"
|
||||
#include "GRI_30_Kinetics.h"
|
||||
#include "InterfaceKinetics.h"
|
||||
#include "EdgeKinetics.h"
|
||||
#include "importKinetics.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
KineticsFactory* KineticsFactory::s_factory = 0;
|
||||
|
||||
static int ntypes = 5;
|
||||
static string _types[] = {"none", "GasKinetics", "GRI30", "Interface", "Edge"};
|
||||
static int _itypes[] = {0, cGasKinetics, cGRI30, cInterfaceKinetics, cEdgeKinetics};
|
||||
|
||||
/**
|
||||
* Return a new kinetics manager that implements a reaction
|
||||
* mechanism specified in a CTML file. In other words, the
|
||||
* kinetics manager, given the rate constants and formulation of the
|
||||
* reactions that make up a kinetics mechanism, is responsible for
|
||||
* calculating the rates of progress of the reactions and for
|
||||
* calculating the source terms for species.
|
||||
*
|
||||
* Input
|
||||
* ------
|
||||
* phaseData = This is an XML_Node that contains the xml data
|
||||
* describing the phase. Of particular note to this
|
||||
* routine is the child xml element called "kinetics".
|
||||
* The element has one attribute called "model",
|
||||
* with a string value. The value of this string
|
||||
* is used to decide which kinetics manager is used
|
||||
* to calculate the reacton mechanism.
|
||||
*
|
||||
* Return
|
||||
* ---------
|
||||
* Pointer to the new kinetics manager.
|
||||
*/
|
||||
|
||||
Kinetics* KineticsFactory::
|
||||
newKinetics(XML_Node& phaseData, vector<ThermoPhase*> th) {
|
||||
/*
|
||||
* Look for a child of the xml element phase called
|
||||
* "kinetics". It has an attribute name "model".
|
||||
* Store the value of that attribute in the variable kintype
|
||||
*/
|
||||
string kintype = phaseData.child("kinetics")["model"];
|
||||
/*
|
||||
* look up the string kintype in the list of known
|
||||
* kinetics managers (list is kept at the top of this file).
|
||||
* Translate it to an integer value, ikin.
|
||||
*/
|
||||
int ikin=-1;
|
||||
int n;
|
||||
for (n = 0; n < ntypes; n++) {
|
||||
if (kintype == _types[n]) ikin = _itypes[n];
|
||||
}
|
||||
/*
|
||||
* Assign the kinetics manager based on the value of ikin.
|
||||
* Kinetics managers are classes derived from the base
|
||||
* Kinetics class. Unknown kinetics managers will throw a
|
||||
* CanteraError here.
|
||||
*/
|
||||
Kinetics* k=0;
|
||||
switch (ikin) {
|
||||
|
||||
case 0:
|
||||
k = new Kinetics;
|
||||
break;
|
||||
|
||||
case cGasKinetics:
|
||||
k = new GasKinetics;
|
||||
break;
|
||||
|
||||
case cGRI30:
|
||||
k = new GRI_30_Kinetics;
|
||||
break;
|
||||
|
||||
case cInterfaceKinetics:
|
||||
k = new InterfaceKinetics;
|
||||
break;
|
||||
|
||||
case cEdgeKinetics:
|
||||
k = new EdgeKinetics;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw UnknownKineticsModel("KineticsFactory::newKinetics",
|
||||
kintype);
|
||||
}
|
||||
|
||||
// Now that we have the kinetics manager, we can
|
||||
// import the reaction mechanism into it.
|
||||
importKinetics(phaseData, th, k);
|
||||
|
||||
// Return the pointer to the kinetics manager
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a new, empty kinetics manager.
|
||||
*/
|
||||
Kinetics* KineticsFactory::newKinetics(string model) {
|
||||
|
||||
int ikin = -1;
|
||||
int n;
|
||||
for (n = 0; n < ntypes; n++) {
|
||||
if (model == _types[n]) ikin = _itypes[n];
|
||||
}
|
||||
Kinetics* k=0;
|
||||
switch (ikin) {
|
||||
|
||||
case cGasKinetics:
|
||||
k = new GasKinetics;
|
||||
break;
|
||||
|
||||
case cGRI30:
|
||||
k = new GRI_30_Kinetics;
|
||||
break;
|
||||
|
||||
case cInterfaceKinetics:
|
||||
k = new InterfaceKinetics;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw UnknownKineticsModel("KineticsFactory::newKinetics",
|
||||
model);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
}
|
||||
91
Cantera/src/kinetics/KineticsFactory.h
Normal file
91
Cantera/src/kinetics/KineticsFactory.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* @file KineticsFactory.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef KINETICS_FACTORY_H
|
||||
#define KINETICS_FACTORY_H
|
||||
|
||||
#include "Kinetics.h"
|
||||
#include "xml.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
|
||||
class UnknownKineticsModel : public CanteraError {
|
||||
public:
|
||||
UnknownKineticsModel(std::string proc, std::string kineticsModel) :
|
||||
CanteraError(proc, "Specified Kinetics model "
|
||||
+ kineticsModel +
|
||||
" does not match any known type.") {}
|
||||
virtual ~UnknownKineticsModel() {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Factory for kinetics managers.
|
||||
*/
|
||||
class KineticsFactory {
|
||||
|
||||
public:
|
||||
|
||||
static KineticsFactory* factory() {
|
||||
if (!s_factory) s_factory = new KineticsFactory;
|
||||
return s_factory;
|
||||
}
|
||||
|
||||
virtual ~KineticsFactory() {
|
||||
delete s_factory;
|
||||
s_factory = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new kinetics manager.
|
||||
*/
|
||||
virtual Kinetics* newKinetics(XML_Node& phase,
|
||||
std::vector<ThermoPhase*> th);
|
||||
|
||||
virtual Kinetics* newKinetics(std::string model);
|
||||
|
||||
private:
|
||||
|
||||
static KineticsFactory* s_factory;
|
||||
KineticsFactory(){}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Create a new kinetics manager.
|
||||
*/
|
||||
inline Kinetics* newKineticsMgr(XML_Node& phase,
|
||||
std::vector<ThermoPhase*> th, KineticsFactory* f=0) {
|
||||
if (f == 0) {
|
||||
f = KineticsFactory::factory();
|
||||
}
|
||||
Kinetics* kin = f->newKinetics(phase, th);
|
||||
return kin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new kinetics manager.
|
||||
*/
|
||||
inline Kinetics* newKineticsMgr(std::string model, KineticsFactory* f=0) {
|
||||
if (f == 0) {
|
||||
f = KineticsFactory::factory();
|
||||
}
|
||||
Kinetics* kin = f->newKinetics(model);
|
||||
return kin;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
164
Cantera/src/kinetics/RateCoeffMgr.h
Executable file
164
Cantera/src/kinetics/RateCoeffMgr.h
Executable file
|
|
@ -0,0 +1,164 @@
|
|||
/**
|
||||
* @file RateCoeffMgr.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_RATECOEFF_MGR_H
|
||||
#define CT_RATECOEFF_MGR_H
|
||||
|
||||
#include "utilities.h"
|
||||
#include "RxnRates.h"
|
||||
|
||||
#include "ct_defs.h"
|
||||
#include "ctexceptions.h"
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* This rate coefficient manager supports one parameterization of
|
||||
* the rate constant of any type.
|
||||
*/
|
||||
template<class R>
|
||||
class Rate1 {
|
||||
|
||||
public:
|
||||
|
||||
Rate1(){}
|
||||
virtual ~Rate1(){}
|
||||
|
||||
/**
|
||||
* Install a rate coefficient calculator.
|
||||
* @param rxnNumber the reaction number
|
||||
* @param rateType the rate type
|
||||
* @param m length of coefficient array
|
||||
* @param coefficients
|
||||
*/
|
||||
int install( int rxnNumber, int rateType, int m,
|
||||
const doublereal* c ) {
|
||||
/*
|
||||
* Check to see if the current reaction rate type
|
||||
* is the same as the type of this class. If not,
|
||||
* throw an error condition.
|
||||
*/
|
||||
if (rateType != R::type())
|
||||
throw CanteraError("Rate1::install",
|
||||
"incorrect rate coefficient type: "+int2str(rateType));
|
||||
|
||||
// if any coefficient other than the first is non-zero, or
|
||||
// if alwaysComputeRate() is true, install a rate
|
||||
// calculator and return the index of the calculator.
|
||||
for (int i = 1; i < m; i++) {
|
||||
if (c[i] != 0.0 || R::alwaysComputeRate() ) {
|
||||
m_rxn.push_back(rxnNumber);
|
||||
m_rates.push_back(R(m, c));
|
||||
return static_cast<int>(m_rates.size()) - 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the nth rate coefficient calculator.
|
||||
* Note that this is not the same as the calculator for
|
||||
* reaction n, since reactions with constant rate coefficients
|
||||
* do not have a calculator.
|
||||
*/
|
||||
const R& rateCoeff(int loc) const { return m_rates[loc]; }
|
||||
|
||||
/**
|
||||
* Update the concentration-dependent parts of the rate
|
||||
* coefficient, if any. Used by class SurfaceArrhenius to
|
||||
* compute coverage-dependent * modifications to the Arrhenius
|
||||
* parameters. The array c should contain whatever data the
|
||||
* particular rate coefficient class needs to update its
|
||||
* rates. Note that this method does not return anything. To
|
||||
* get the updated rates, method update must be called after
|
||||
* the call to update_C.
|
||||
*/
|
||||
void update_C(const doublereal* c) {
|
||||
TYPENAME_KEYWORD std::vector<R>::iterator b = m_rates.begin();
|
||||
TYPENAME_KEYWORD std::vector<R>::iterator e = m_rates.end();
|
||||
int i = 0;
|
||||
for (; b != e; ++b, ++i) {
|
||||
b->update_C(c);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the rate coefficients into array values. Each
|
||||
* calculator writes one entry in values, at the location
|
||||
* specified by the reaction number when it was
|
||||
* installed. Note that nothing will be done for reactions
|
||||
* that have constant rates. The array values should be
|
||||
* preloaded with the constant rate coefficients.
|
||||
*/
|
||||
void update(doublereal T, doublereal logT, doublereal* values) {
|
||||
TYPENAME_KEYWORD std::vector<R>::const_iterator b = m_rates.begin();
|
||||
TYPENAME_KEYWORD std::vector<R>::const_iterator e = m_rates.end();
|
||||
doublereal recipT = 1.0/T;
|
||||
int i = 0;
|
||||
for (; b != e; ++b, ++i) {
|
||||
// values[m_rxn[i]] = exp(b->update(logT, recipT));
|
||||
values[m_rxn[i]] = b->updateRC(logT, recipT);
|
||||
}
|
||||
}
|
||||
|
||||
void writeUpdate(std::ostream & output1, std::string key) {
|
||||
output1 << key;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<R> m_rates;
|
||||
std::vector<int> m_rxn;
|
||||
array_fp m_const; // not used
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* This rate coefficient manager supports two parameterizations of
|
||||
* any type.
|
||||
*/
|
||||
template<class R1, class R2>
|
||||
class Rate2 {
|
||||
public:
|
||||
|
||||
Rate2(){}
|
||||
virtual ~Rate2(){}
|
||||
|
||||
int install( int rxnNumber, int rateType, int m,
|
||||
const doublereal* c) {
|
||||
if (rateType == R1::type())
|
||||
return m_r1.install(rxnNumber, rateType, m, c);
|
||||
else if (rateType == R2::type())
|
||||
return m_r2.install(rxnNumber, rateType, m, c);
|
||||
else
|
||||
throw CanteraError("Rate2::install",
|
||||
"unknown rate coefficient type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
void update(doublereal T, doublereal logT,
|
||||
doublereal* values) {
|
||||
m_r1.update(T, logT, values);
|
||||
m_r2.update(T, logT, values);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
Rate1<R1> m_r1;
|
||||
Rate1<R2> m_r2;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
61
Cantera/src/kinetics/ReactionData.h
Executable file
61
Cantera/src/kinetics/ReactionData.h
Executable file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @file ReactionData.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_REACTION_DATA_H
|
||||
#define CT_REACTION_DATA_H
|
||||
|
||||
#include "reaction_defs.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
class ReactionData {
|
||||
public:
|
||||
ReactionData() {
|
||||
reactionType = ELEMENTARY_RXN;
|
||||
number = 0;
|
||||
rxn_number = 0;
|
||||
reversible = true;
|
||||
rateCoeffType = ARRHENIUS;
|
||||
falloffType = NONE;
|
||||
error = 0;
|
||||
equation = "";
|
||||
default_3b_eff = 1.0;
|
||||
global = false;
|
||||
beta = 0.0;
|
||||
}
|
||||
~ReactionData(){}
|
||||
|
||||
int reactionType;
|
||||
int number, rxn_number;
|
||||
vector_int reactants;
|
||||
vector_int products;
|
||||
vector_fp order;
|
||||
vector_fp rstoich;
|
||||
vector_fp pstoich;
|
||||
std::vector<grouplist_t> rgroups;
|
||||
std::vector<grouplist_t> pgroups;
|
||||
std::map<int, doublereal> thirdBodyEfficiencies;
|
||||
bool reversible;
|
||||
int rateCoeffType;
|
||||
vector_fp rateCoeffParameters;
|
||||
vector_fp auxRateCoeffParameters;
|
||||
int falloffType;
|
||||
vector_fp falloffParameters;
|
||||
int error;
|
||||
std::string equation;
|
||||
doublereal default_3b_eff;
|
||||
vector_fp cov;
|
||||
bool global;
|
||||
doublereal beta; // for electrochemical reactions
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
1017
Cantera/src/kinetics/ReactionPath.cpp
Executable file
1017
Cantera/src/kinetics/ReactionPath.cpp
Executable file
File diff suppressed because it is too large
Load diff
278
Cantera/src/kinetics/ReactionPath.h
Executable file
278
Cantera/src/kinetics/ReactionPath.h
Executable file
|
|
@ -0,0 +1,278 @@
|
|||
/**
|
||||
* @file ReactionPath.h
|
||||
*
|
||||
* Classes for reaction path analysis.
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_RXNPATH_H
|
||||
#define CT_RXNPATH_H
|
||||
|
||||
// Cantera includes
|
||||
#include "ct_defs.h"
|
||||
#include "DenseMatrix.h"
|
||||
#include "Group.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
enum flow_t { NetFlow, OneWayFlow };
|
||||
|
||||
Group parseGroupString(std::string str, std::vector<std::string>& esyms);
|
||||
|
||||
// forward references
|
||||
class Path;
|
||||
|
||||
/**
|
||||
* Nodes in reaction path graphs.
|
||||
*/
|
||||
class SpeciesNode {
|
||||
public:
|
||||
|
||||
typedef std::vector<Path*> path_list;
|
||||
|
||||
/// Default constructor
|
||||
SpeciesNode() : number(-1), name(""), value(0.0),
|
||||
visible(false), m_in(0.0), m_out(0.0) {}
|
||||
|
||||
/// Destructor
|
||||
virtual ~SpeciesNode() {}
|
||||
|
||||
// public attributes
|
||||
int number; ///< Species number
|
||||
std::string name; ///< Label on graph
|
||||
doublereal value; ///< May be used to set node appearance
|
||||
bool visible; ///< Visible on graph;
|
||||
|
||||
|
||||
// public methods
|
||||
|
||||
/**
|
||||
* @name References.
|
||||
* Return a reference to a path object connecting this node
|
||||
* to another node.
|
||||
*/
|
||||
//@{
|
||||
Path* path(int n) { return m_paths[n]; }
|
||||
const Path* path(int n) const { return m_paths[n]; }
|
||||
//@}
|
||||
|
||||
|
||||
/// Total number of paths to or from this node
|
||||
int nPaths() const { return static_cast<int>(m_paths.size()); }
|
||||
|
||||
/// add a path to or from this node
|
||||
void addPath(Path* path);
|
||||
|
||||
double outflow() {return m_out;}
|
||||
double inflow() {return m_in;}
|
||||
double netOutflow() {return m_out - m_in;}
|
||||
|
||||
void printPaths();
|
||||
|
||||
|
||||
protected:
|
||||
double m_in, m_out;
|
||||
path_list m_paths;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class Path {
|
||||
|
||||
public:
|
||||
|
||||
typedef std::map<int, doublereal> rxn_path_map;
|
||||
|
||||
/**
|
||||
* Constructor. Construct a one-way path from
|
||||
* \c begin to \c end.
|
||||
*/
|
||||
Path(SpeciesNode* begin, SpeciesNode* end);
|
||||
|
||||
/// Destructor
|
||||
virtual ~Path() {}
|
||||
|
||||
void addReaction(int rxnNumber, doublereal value, std::string label = "");
|
||||
|
||||
/// Upstream node.
|
||||
const SpeciesNode* begin() const { return m_a; }
|
||||
SpeciesNode* begin() { return m_a; }
|
||||
|
||||
/// Downstream node.
|
||||
const SpeciesNode* end() const { return m_b; }
|
||||
SpeciesNode* end() { return m_b; }
|
||||
|
||||
/**
|
||||
* If \c n is one of the nodes this path connects, then
|
||||
* the other node is returned. Otherwise zero is returned.
|
||||
*/
|
||||
SpeciesNode* otherNode(SpeciesNode* n) {
|
||||
return (n == m_a ? m_b : (n == m_b ? m_a : 0));
|
||||
}
|
||||
|
||||
/// The total flow in this path
|
||||
doublereal flow() { return m_total; }
|
||||
void setFlow(doublereal v) { m_total = v; }
|
||||
|
||||
/// Number of reactions contributing to this path
|
||||
int nReactions() {
|
||||
return static_cast<int>(m_rxn.size());
|
||||
}
|
||||
|
||||
/// Map from reaction number to flow from that reaction in this path.
|
||||
const rxn_path_map& reactionMap() { return m_rxn; }
|
||||
|
||||
void writeLabel(std::ostream& s, doublereal threshold = 0.005);
|
||||
|
||||
protected:
|
||||
|
||||
std::map<std::string, doublereal> m_label;
|
||||
SpeciesNode *m_a, *m_b;
|
||||
rxn_path_map m_rxn;
|
||||
doublereal m_total;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reaction path diagrams (graphs).
|
||||
*/
|
||||
class ReactionPathDiagram {
|
||||
|
||||
public:
|
||||
|
||||
ReactionPathDiagram();
|
||||
|
||||
virtual ~ReactionPathDiagram();
|
||||
|
||||
/// The largest one-way flow value in any path
|
||||
doublereal maxFlow() { return m_flxmax; }
|
||||
|
||||
/// The net flow from node \c k1 to node \c k2
|
||||
doublereal netFlow(int k1, int k2) {
|
||||
return flow(k1, k2) - flow(k2, k1);
|
||||
}
|
||||
|
||||
/// The one-way flow from node \c k1 to node \c k2
|
||||
doublereal flow(int k1, int k2) {
|
||||
return (m_paths[k1][k2] ? m_paths[k1][k2]->flow() : 0.0);
|
||||
}
|
||||
|
||||
/// True if a node for species k exists
|
||||
bool hasNode(int k) {
|
||||
return (m_nodes[k] != 0);
|
||||
}
|
||||
|
||||
void writeData(std::ostream& s);
|
||||
void exportToDot(std::ostream& s);
|
||||
void add(ReactionPathDiagram& d);
|
||||
SpeciesNode* node(int k) { return m_nodes[k]; }
|
||||
Path* path(int k1, int k2) { return m_paths[k1][k2]; }
|
||||
Path* path(int n) { return m_pathlist[n]; }
|
||||
int nPaths() { return static_cast<int>(m_pathlist.size()); }
|
||||
int nNodes() { return static_cast<int>(m_nodes.size()); }
|
||||
|
||||
void addNode(int k, std::string nm, doublereal x = 0.0);
|
||||
|
||||
void displayOnly(int k=-1) { m_local = k; }
|
||||
|
||||
void linkNodes(int k1, int k2, int rxn, doublereal value,
|
||||
std::string legend = "");
|
||||
|
||||
void include(std::string aaname) { m_include.push_back(aaname); }
|
||||
void exclude(std::string aaname) { m_exclude.push_back(aaname); }
|
||||
void include(std::vector<std::string>& names) {
|
||||
int n = static_cast<int>(names.size());
|
||||
for (int i = 0; i < n; i++) m_include.push_back(names[i]);
|
||||
}
|
||||
void exclude(std::vector<std::string>& names) {
|
||||
int n = static_cast<int>(names.size());
|
||||
for (int i = 0; i < n; i++) m_exclude.push_back(names[i]);
|
||||
}
|
||||
std::vector<std::string>& included() { return m_include; }
|
||||
std::vector<std::string>& excluded() { return m_exclude; }
|
||||
vector_int species();
|
||||
vector_int reactions();
|
||||
void findMajorPaths(doublereal threshold, int lda, doublereal* a);
|
||||
void setFont(std::string font) {
|
||||
m_font = font;
|
||||
}
|
||||
// public attributes
|
||||
|
||||
std::string title;
|
||||
std::string bold_color;
|
||||
std::string normal_color;
|
||||
std::string dashed_color;
|
||||
std::string element;
|
||||
std::string m_font;
|
||||
doublereal threshold,
|
||||
bold_min, dashed_max, label_min;
|
||||
doublereal x_size, y_size;
|
||||
std::string name, dot_options;
|
||||
flow_t flow_type;
|
||||
double scale;
|
||||
double arrow_width;
|
||||
bool show_details;
|
||||
double arrow_hue;
|
||||
|
||||
protected:
|
||||
|
||||
doublereal m_flxmax;
|
||||
std::map<int, std::map<int, Path*> > m_paths;
|
||||
std::map<int, SpeciesNode*> m_nodes;
|
||||
std::vector<Path*> m_pathlist;
|
||||
std::vector<std::string> m_include;
|
||||
std::vector<std::string> m_exclude;
|
||||
vector_int m_speciesNumber;
|
||||
std::map<int, int> m_rxns;
|
||||
int m_local;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ReactionPathBuilder {
|
||||
|
||||
public:
|
||||
ReactionPathBuilder() {}
|
||||
virtual ~ReactionPathBuilder() {}
|
||||
|
||||
int init(std::ostream& logfile, Kinetics& s);
|
||||
|
||||
int build(Kinetics& s, std::string element, std::ostream& output,
|
||||
ReactionPathDiagram& r, bool quiet=false);
|
||||
|
||||
int findGroups(std::ostream& logfile, Kinetics& s);
|
||||
|
||||
void writeGroup(std::ostream& out, const Group& g);
|
||||
|
||||
protected:
|
||||
void findElements(Kinetics& kin);
|
||||
|
||||
int m_nr;
|
||||
int m_ns;
|
||||
int m_nel;
|
||||
vector_fp m_ropf;
|
||||
vector_fp m_ropr;
|
||||
array_fp m_x;
|
||||
std::vector<vector_int> m_reac;
|
||||
std::vector<vector_int> m_prod;
|
||||
DenseMatrix m_elatoms;
|
||||
std::vector<std::vector<int> > m_groups;
|
||||
std::vector<Group> m_sgroup;
|
||||
std::vector<std::string> m_elementSymbols;
|
||||
// std::map<int, int> m_warn;
|
||||
std::map<int, std::map<int, std::map<int, Group> > > m_transfer;
|
||||
std::vector<bool> m_determinate;
|
||||
Array2D m_atoms;
|
||||
std::map<std::string,int> m_enamemap;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
241
Cantera/src/kinetics/ReactionStoichMgr.h
Normal file
241
Cantera/src/kinetics/ReactionStoichMgr.h
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
/**
|
||||
* @file ReactionStoichMgr.h
|
||||
*
|
||||
* Header file declaring class ReactionStoichMgr.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
#ifndef CT_RXN_STOICH
|
||||
#define CT_RXN_STOICH
|
||||
|
||||
#include "ct_defs.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
class StoichManagerN;
|
||||
class ReactionData;
|
||||
|
||||
/**
|
||||
* Reaction mechanism stoichiometry manager. This is an internal class used
|
||||
* by kinetics manager classes, and is not meant for direct use in
|
||||
* user programs.
|
||||
*
|
||||
* Class ReactionStoichMgr handles the calculation of quantities involving
|
||||
* the stoichiometry of a set of reactions. The reactions must have integer
|
||||
* stoichiometric coefficients. Specifically, its methods compute
|
||||
* - species creation rates
|
||||
* - species destruction rates
|
||||
* - species net production rates
|
||||
* - the change in molar species properties in the reactions
|
||||
* - concentration products
|
||||
*
|
||||
* To use this class, method 'add' is first used to add each reaction.
|
||||
* Once all reactions have been added, the methods that compute various
|
||||
* quantities may be called.
|
||||
*
|
||||
* The nomenclature used below to document the methods is as follows.
|
||||
*
|
||||
* - \f$ N_r \f$
|
||||
* Integer reactant stoichiometric coefficient matrix. The (k,i)
|
||||
* element of this matrix is the stoichiometric coefficient of
|
||||
* species \i k as a reactant in reaction \i i.
|
||||
* - \f$ N_p \f$
|
||||
* Integer product stoichiometric coefficient matrix. The (k,i)
|
||||
* element of this matrix is the stoichiometric coefficient of
|
||||
* species \i k as a product in reaction \i i.
|
||||
* - \f$ Q_{\rm fwd} \f$
|
||||
* Vector of length I of forward rates of progress.
|
||||
* - \f$ Q_{\rm rev} \f$
|
||||
* Vector of length I of reverse rates of progress.
|
||||
* - \f$ C \f$
|
||||
* Vector of K species creation rates.
|
||||
* - \f$ D \f$
|
||||
* Vector of K species destruction rates.
|
||||
* - \f$ W = C - D \f$
|
||||
* Vector of K species net production rates.
|
||||
*
|
||||
*/
|
||||
class ReactionStoichMgr {
|
||||
|
||||
public:
|
||||
|
||||
/// Constructor.
|
||||
ReactionStoichMgr();
|
||||
|
||||
/// Destructor.
|
||||
virtual ~ReactionStoichMgr();
|
||||
|
||||
/**
|
||||
* Add a reaction with mass-action kinetics. Vectors
|
||||
* 'reactants' and 'products' contain the integer species
|
||||
* indices of the reactants and products, respectively. Note
|
||||
* that if more than one molecule of a given species is
|
||||
* involved in the reaction, then its index is repeated.
|
||||
*
|
||||
* For example, suppose a reaction mechanism involves the
|
||||
* species N2, O2, O, N, NO. N2 is assigned index number 0, O2
|
||||
* number 1, and so on through NO with number 4. Then the
|
||||
* representation of the following reactions is as shown here.
|
||||
*
|
||||
* - N + O = NO
|
||||
* - reactants: (3, 2)
|
||||
* - products: (4)
|
||||
*
|
||||
* - O + O = O2
|
||||
* - reactants: (2, 2) [ note repeated index ]
|
||||
* - products: (1)
|
||||
*
|
||||
* @param rxn Reaction number. This number will be used as the index
|
||||
* into the rate of progess vector in the methods below.
|
||||
* @param reactants vector of integer reactant indices
|
||||
* @param products vector of integer product indices
|
||||
* @param reversible true if the reaction is reversible, false otherwise
|
||||
*/
|
||||
virtual void add(int rxn, const vector_int& reactants, const vector_int& products,
|
||||
bool reversible);
|
||||
|
||||
/**
|
||||
* Add a reaction with specified, possibly non-integral, reaction orders.
|
||||
* @param rxn Reaction number
|
||||
* @param reactants vector of integer reactant indices
|
||||
* @param products vector of integer product indices
|
||||
* @param reversible true if the reaction is reversible, false otherwise.
|
||||
* If the reaction is reversible, its reverse rate will be computed from
|
||||
* the reaction stoichiometry.
|
||||
* @param fwdOrder reaction orders for the reactants. This vector must
|
||||
* be the same length as 'reactants,' and the reaction orders are for the
|
||||
* species with index in the corresponding location in 'reactants.'
|
||||
*
|
||||
*/
|
||||
// void add(int rxn, const vector_int& reactants, const vector_int& products,
|
||||
// bool reversible, const vector_fp& fwdOrder);
|
||||
|
||||
|
||||
virtual void add(int rxn, const ReactionData& r);
|
||||
|
||||
/**
|
||||
* Species creation rates.
|
||||
* Given the arrays of the forward and reverse rates of
|
||||
* progress for all reactions, compute the species creation
|
||||
* rates, given by
|
||||
* \f[
|
||||
* C = N_p Q_f + N_r Q_r.
|
||||
* \f]
|
||||
*/
|
||||
virtual void getCreationRates(int nSpecies,
|
||||
const doublereal* fwdRatesOfProgress,
|
||||
const doublereal* revRatesOfProgress,
|
||||
doublereal* creationRates);
|
||||
|
||||
|
||||
/**
|
||||
* Species destruction rates.
|
||||
* Given the arrays of the forward and reverse rates of
|
||||
* progress for all reactions, compute the species destruction
|
||||
* rates, given by
|
||||
* \f[
|
||||
* D = N_r Q_f + N_p Q_r,
|
||||
* \f]
|
||||
* Note that the stoichiometric coefficient matrices are very sparse, integer
|
||||
* matrices.
|
||||
*/
|
||||
virtual void getDestructionRates(int nSpecies,
|
||||
const doublereal* fwdRatesOfProgress,
|
||||
const doublereal* revRatesOfProgress,
|
||||
doublereal* destructionRates);
|
||||
|
||||
|
||||
/**
|
||||
* Given the array of the net rates of progress for all
|
||||
* reactions, compute the species net production rates and
|
||||
* return them in array w.
|
||||
*/
|
||||
/**
|
||||
* Species net production rates.
|
||||
* Given the array of the net rates of
|
||||
* progress for all reactions, compute the species net production
|
||||
* rates, given by
|
||||
* \f[
|
||||
* W = (N_r - N_p) Q_{\rm net},
|
||||
* \f]
|
||||
*/
|
||||
virtual void getNetProductionRates(int nsp, const doublereal* ropnet, doublereal* w);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Change of a molar species property in a reaction. Given an
|
||||
* array of species properties 'g', return in array 'dg' the
|
||||
* change in this quantity in the reactions. Array 'g' must
|
||||
* have a length at least as great as the number of species,
|
||||
* and array 'dg' must have a length as great as the total
|
||||
* number of reactions.
|
||||
*/
|
||||
virtual void getReactionDelta(int nReactions,
|
||||
const doublereal* g,
|
||||
doublereal* dg);
|
||||
|
||||
|
||||
/**
|
||||
* Given an array of species properties 'g', return in array
|
||||
* 'dg' the change in this quantity in the reversible
|
||||
* reactions. Array 'g' must have a length at least as great
|
||||
* as the number of species, and array 'dg' must have a length
|
||||
* as great as the total number of reactions. This method
|
||||
* only computes 'dg' for the reversible reactions, and the
|
||||
* entries of 'dg' for the irreversible reactions are
|
||||
* unaltered. This is primarily designed for use in
|
||||
* calculating reveerse rate coefficients from thermochemistry
|
||||
* for reversible reactions.
|
||||
*/
|
||||
virtual void getRevReactionDelta(int nr, const doublereal* g, doublereal* dg);
|
||||
|
||||
|
||||
/**
|
||||
* Given an array of concentrations C, multiply the entries in array R by
|
||||
* the concentration products for the reactants:
|
||||
* \f[
|
||||
* R_i = R_i * \prod_k C_k^{o_{k,i}}
|
||||
* \f]
|
||||
* Here \f$ o_{k,i} \f$ is the reaction order of species k in reaction i.
|
||||
*/
|
||||
virtual void multiplyReactants(const doublereal* C, doublereal* R);
|
||||
|
||||
|
||||
/**
|
||||
* Given an array of concentrations C, multiply the entries in array R by
|
||||
* the concentration products for the products:
|
||||
* \f[
|
||||
* R_i = R_i * \prod_k C_k^{\nu^{(p)}_{k,i}}
|
||||
* \f]
|
||||
* Here \f$ \nu^{(p)}_{k,i} \f$ is the product stoichiometric coefficient
|
||||
* of species k in reaction i.
|
||||
*/
|
||||
virtual void multiplyRevProducts(const doublereal* c, doublereal* r);
|
||||
|
||||
virtual void write(std::string filename);
|
||||
|
||||
protected:
|
||||
|
||||
void writeCreationRates(std::ostream& f);
|
||||
void writeDestructionRates(std::ostream& f);
|
||||
void writeNetProductionRates(std::ostream& f);
|
||||
void writeMultiplyReactants(std::ostream& f);
|
||||
void writeMultiplyRevProducts(std::ostream& f);
|
||||
StoichManagerN* m_reactants;
|
||||
StoichManagerN* m_revproducts;
|
||||
StoichManagerN* m_irrevproducts;
|
||||
vector_fp m_dummy;
|
||||
|
||||
#ifdef INCL_STOICH_WRITER
|
||||
StoichWriter* m_rwriter;
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
372
Cantera/src/kinetics/RxnRates.h
Executable file
372
Cantera/src/kinetics/RxnRates.h
Executable file
|
|
@ -0,0 +1,372 @@
|
|||
/**
|
||||
* @file RxnRates.h
|
||||
*
|
||||
*/
|
||||
|
||||
/* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_RXNRATES_H
|
||||
#define CT_RXNRATES_H
|
||||
|
||||
#include "reaction_defs.h"
|
||||
#include "ctexceptions.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* A rate coefficient of the form
|
||||
* \f[
|
||||
* A T^b \exp (-E/RT)
|
||||
* \f]
|
||||
*/
|
||||
class Arrhenius {
|
||||
|
||||
public:
|
||||
|
||||
/// return the rate coefficient type.
|
||||
static int type(){ return ARRHENIUS; }
|
||||
|
||||
/// 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.
|
||||
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 ArrheniusSum {
|
||||
|
||||
public:
|
||||
static int type(){ return ARRHENIUS_SUM; }
|
||||
ArrheniusSum() : m_nterms(0) {}
|
||||
|
||||
void addArrheniusTerm(doublereal A, doublereal b, doublereal E) {
|
||||
if (A > 0.0) {
|
||||
m_terms.push_back(Arrhenius(A, b, E));
|
||||
m_sign.push_back(1);
|
||||
}
|
||||
else if (A < 0.0) {
|
||||
m_terms.push_back(Arrhenius(-A, b, E));
|
||||
m_sign.push_back(-1);
|
||||
}
|
||||
m_nterms++;
|
||||
}
|
||||
|
||||
void update_C(const doublereal* c) {}
|
||||
|
||||
/**
|
||||
* Update the value of the logarithm of the rate constant.
|
||||
*
|
||||
*/
|
||||
doublereal update(doublereal logT, doublereal recipT) const {
|
||||
int n;
|
||||
doublereal f, fsum = 0.0;
|
||||
for (n = 0; n < m_nterms; n++) {
|
||||
f = m_terms[n].updateRC(logT, recipT);
|
||||
fsum += m_sign[n]*f;
|
||||
}
|
||||
return log(fsum);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
int n;
|
||||
doublereal f, fsum = 0.0;
|
||||
for (n = 0; n < m_nterms; n++) {
|
||||
f = m_terms[n].updateRC(logT, recipT);
|
||||
fsum += m_sign[n]*f;
|
||||
}
|
||||
return fsum;
|
||||
}
|
||||
|
||||
void writeUpdateRHS(std::ostream& s) const {
|
||||
;
|
||||
}
|
||||
|
||||
static bool alwaysComputeRate() { return false;}
|
||||
|
||||
protected:
|
||||
std::vector<Arrhenius> m_terms;
|
||||
vector_int m_sign;
|
||||
int m_nterms;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* An Arrhenius rate with coverage-dependent terms.
|
||||
*/
|
||||
class SurfaceArrhenius {
|
||||
|
||||
public:
|
||||
static int type(){ return ARRHENIUS; }
|
||||
SurfaceArrhenius() :
|
||||
m_logA(-1.0E300),
|
||||
m_b (0.0),
|
||||
m_E (0.0),
|
||||
m_A(0.0),
|
||||
m_acov(0.0),
|
||||
m_ecov(0.0),
|
||||
m_mcov(0.0),
|
||||
m_ncov(0),
|
||||
m_nmcov(0)
|
||||
{
|
||||
}
|
||||
|
||||
SurfaceArrhenius( int csize, const doublereal* c ) :
|
||||
m_b (c[1]),
|
||||
m_E (c[2]),
|
||||
m_A (c[0]),
|
||||
m_acov(0.0),
|
||||
m_ecov(0.0),
|
||||
m_mcov(0.0),
|
||||
m_ncov(0),
|
||||
m_nmcov(0)
|
||||
{
|
||||
if (m_A <= 0.0) {
|
||||
m_logA = -1.0E300;
|
||||
} else {
|
||||
m_logA = log(c[0]);
|
||||
}
|
||||
if (csize >= 7) {
|
||||
for (int n = 3; n < csize-3; n += 4) {
|
||||
addCoverageDependence(int(c[n]),
|
||||
c[n+1], c[n+2], c[n+3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addCoverageDependence(int k, doublereal a,
|
||||
doublereal m, doublereal e) {
|
||||
m_ncov++;
|
||||
m_sp.push_back(k);
|
||||
m_ac.push_back(a);
|
||||
m_ec.push_back(e);
|
||||
if (m != 0.0) {
|
||||
m_msp.push_back(k);
|
||||
m_mc.push_back(m);
|
||||
m_nmcov++;
|
||||
}
|
||||
}
|
||||
|
||||
void update_C(const doublereal* theta) {
|
||||
m_acov = 0.0;
|
||||
m_ecov = 0.0;
|
||||
m_mcov = 0.0;
|
||||
int n, k;
|
||||
doublereal th;
|
||||
for (n = 0; n < m_ncov; n++) {
|
||||
k = m_sp[n];
|
||||
m_acov += m_ac[n] * theta[k];
|
||||
m_ecov += m_ec[n] * theta[k];
|
||||
}
|
||||
for (n = 0; n < m_nmcov; n++) {
|
||||
k = m_msp[n];
|
||||
// changed n to k, dgg 1/22/04
|
||||
th = fmaxx(theta[k], Tiny);
|
||||
// th = fmaxx(theta[n], Tiny);
|
||||
m_mcov += m_mc[n]*log(th);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the value of the logarithm of the rate constant.
|
||||
*
|
||||
* This calculation is not safe for negative values of
|
||||
* the preexponential.
|
||||
*/
|
||||
doublereal update(doublereal logT, doublereal recipT) const {
|
||||
return m_logA + m_acov + m_b*logT
|
||||
- (m_E + m_ecov)*recipT + m_mcov;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_acov + m_b*logT - (m_E + m_ecov)*recipT + m_mcov);
|
||||
}
|
||||
|
||||
doublereal activationEnergy_R() const {
|
||||
return m_E + m_ecov;
|
||||
}
|
||||
|
||||
static bool alwaysComputeRate() { return true;}
|
||||
|
||||
protected:
|
||||
doublereal m_logA, m_b, m_E, m_A;
|
||||
doublereal m_acov, m_ecov, m_mcov;
|
||||
vector_int m_sp, m_msp;
|
||||
vector_fp m_ac, m_ec, m_mc;
|
||||
int m_ncov, m_nmcov;
|
||||
};
|
||||
|
||||
|
||||
#ifdef INCL_TST
|
||||
|
||||
class TST {
|
||||
|
||||
public:
|
||||
static int type(){ return TSTRATE; }
|
||||
TST() {}
|
||||
TST( const vector_fp& c ) {
|
||||
m_b.resize(10);
|
||||
copy(c.begin(), c.begin() + 10, m_b.begin());
|
||||
m_k = int(c[10]);
|
||||
}
|
||||
|
||||
void update_C(const vector_fp& c) {
|
||||
doublereal ck = c[m_k];
|
||||
delta_s0 = m_b[0] + m_b[1]*ck + m_b[2]*ck*ck;
|
||||
delta_e0 = m_b[5] + m_b[6]*ck + m_b[7]*ck*ck;
|
||||
}
|
||||
|
||||
doublereal update(doublereal logT, doublereal recipT) const {
|
||||
doublereal delta_s = delta_s0*(1.0 + m_b[3]*logT + m_b[4]*recipT);
|
||||
doublereal delta_E = delta_e0*(1.0 + m_b[8]*logT + m_b[9]*recipT);
|
||||
return logBoltz_Planck + logT + delta_s - delta_E*recipT;
|
||||
}
|
||||
|
||||
doublereal updateRC(doublereal logT, doublereal recipT) const {
|
||||
double lres = update(logT, recipT);
|
||||
return exp(lres);
|
||||
}
|
||||
|
||||
void writeUpdateRHS(std::ostream& s) const {}
|
||||
|
||||
protected:
|
||||
doublereal delta_s0, delta_e0;
|
||||
int m_k;
|
||||
vector_fp m_b;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
824
Cantera/src/kinetics/StoichManager.h
Executable file
824
Cantera/src/kinetics/StoichManager.h
Executable file
|
|
@ -0,0 +1,824 @@
|
|||
/**
|
||||
* @file StoichManager.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_STOICH_MGR_H
|
||||
#define CT_STOICH_MGR_H
|
||||
|
||||
#include "stringUtils.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
/**
|
||||
* @defgroup Stoichiometry Stoichiometry
|
||||
*
|
||||
* Note: these classes are designed for internal use in class
|
||||
* ReactionStoichManager.
|
||||
*
|
||||
* The classes defined here implement simple operations that are
|
||||
* used by class ReactionStoichManager to compute things like
|
||||
* rates of progress, species production rates, etc. In general, a
|
||||
* reaction mechanism may involve many species and many reactions,
|
||||
* but any given reaction typically only involves a few species as
|
||||
* reactants, and a few as products. Therefore, the matrix of
|
||||
* stoichiometric coefficients is very sparse. Not only is it
|
||||
* sparse, but the non-zero matrix elements often have the value
|
||||
* 1, and in many cases no more than three coefficients are
|
||||
* non-zero for the reactants and/or the products.
|
||||
*
|
||||
|
||||
* For the present purposes, we will consider each direction of a
|
||||
* reversible reaction to be a separate reaction. We often need to
|
||||
* compute quantities that can formally be written as a matrix
|
||||
* product of a stoichiometric coefficient matrix and a vector of
|
||||
* reaction rates. For example, the species creation rates are
|
||||
* given by
|
||||
* \f[
|
||||
* \dot C_k = \sum_k \nu^{(p)}_{k,i} R_i
|
||||
* \f]
|
||||
* where \f$ \nu^{(p)_{k,i}} \f$ is the product-side stoichiometric
|
||||
* coefficient of species \a k in reaction \a i.
|
||||
* This could be done be straightforward matrix multiplication, but would be inefficient, since most of the matrix elements of \f$ \nu^{(p)}_{k,i} \f$ are zero. We could do better by using sparse-matrix algorithms to compute this product.
|
||||
|
||||
If the reactions are general ones, with non-integral stoichiometric
|
||||
coefficients, this is about as good as we can do. But we are
|
||||
particularly concerned here with the performance for very large
|
||||
reaction mechanisms, which are usually composed of elementary
|
||||
reactions, which have integral stoichiometric
|
||||
coefficients. Furthermore, very few elementary reactions involve more
|
||||
than 3 product or reactant molecules. This means that instead of
|
||||
|
||||
|
||||
But we can do even better if we take account of the special structure
|
||||
of this matrix for elementary reactions.
|
||||
|
||||
involve three or fewer product molecules (or reactant molecules).
|
||||
|
||||
* To take advantage of this structure, reactions are divided int
|
||||
These classes are
|
||||
* designed to take advantage of this sparse structure when
|
||||
* computing quantities that can be written as matrix multiplies
|
||||
|
||||
They are designed to explicitly unroll loops over species or reactions for
|
||||
|
||||
* Operations on reactions that require knowing the reaction
|
||||
* stoichiometry.
|
||||
* This module consists of class StoichManager, and
|
||||
* classes C1, C2, and C3. Classes C1, C2, and C3 handle operations
|
||||
* involving one, two, or three species, respectively, in a
|
||||
* reaction. Instances are instantiated with a reaction number, and n
|
||||
* species numbers (n = 1 for C1, etc.). All three classes have the
|
||||
* same interface.
|
||||
*
|
||||
* These classes are designed for use by StoichManager, and the
|
||||
* operations implemented are those needed to efficiently compute
|
||||
* quantities such as rates of progress, species production rates,
|
||||
* reaction thermochemistry, etc. The compiler will inline these
|
||||
* methods into the body of the corresponding StoichManager method,
|
||||
* and so there is no performance penalty (unless inlining is turned
|
||||
* off).
|
||||
*
|
||||
* To describe the methods, consider class C3 and suppose an instance
|
||||
* is created with reaction number irxn and species numbers k0, k1,
|
||||
* and k2.
|
||||
*
|
||||
* - multiply(in, out) : out[irxn] is multiplied by
|
||||
* in[k0] * in[k1] * in[k2]
|
||||
*
|
||||
* - power(in, out) : out[irxn] is multiplied by
|
||||
* (in[k0]^order0) * (in[k1]^order1) * (in[k2]^order2)
|
||||
*
|
||||
* - incrementReaction(in, out) : out[irxn] is incremented by
|
||||
* in[k0] + in[k1] + in[k2]
|
||||
*
|
||||
* - decrementReaction(in, out) : out[irxn] is decremented by
|
||||
* in[k0] + in[k1] + in[k2]
|
||||
*
|
||||
* - incrementSpecies(in, out) : out[k0], out[k1], and out[k2]
|
||||
* are all incremented by in[irxn]
|
||||
*
|
||||
* - decrementSpecies(in, out) : out[k0], out[k1], and out[k2]
|
||||
* are all decremented by in[irxn]
|
||||
*
|
||||
* The function multiply() is usually used when evaluating the
|
||||
* forward and reverse rates of progress of reactions.
|
||||
* The rate constants are usually loaded into out[]. Then
|
||||
* multply() is called to add in the dependence of the
|
||||
* species concentrations to yield a forward and reverse rop.
|
||||
*
|
||||
* The function incrementSpecies() and its cousin decrementSpecies()
|
||||
* is used to translate from rates of progress to species production
|
||||
* rates. The vector in[] is preloaed with the rates of progess of
|
||||
* all reactions. Then incrementSpecies() is called to
|
||||
* increment the species production vector, out[], with the rates
|
||||
* of progress.
|
||||
*
|
||||
* The functions incrementReaction() and decrementReaction() are
|
||||
* used to find the standard state equilibrium constant for
|
||||
* a reaction. Here, output[] is a vector of length
|
||||
* number of reactions, usually the standard gibbs free energies
|
||||
* of reaction, while input, usually the standard state
|
||||
* gibbs free energies of species, is a vector of length number of
|
||||
* species.
|
||||
*
|
||||
* Note the stoichiometric coefficient for a species in a reaction
|
||||
* is handled by always assuming it is equal to one and then
|
||||
* treating reactants and products for a reaction separately.
|
||||
* Bimolecular reactions involving the identical species are
|
||||
* treated as involving separate species.
|
||||
*
|
||||
* @internal This class should be upgraded to include cases where
|
||||
* real stoichiometric coefficients are used. Shouldn't be that
|
||||
* hard to do, and they occur in engineering simulations with some
|
||||
* regularity.
|
||||
*
|
||||
*/
|
||||
|
||||
static doublereal ppow(doublereal x, doublereal order) {
|
||||
if (x > 0.0)
|
||||
return std::pow(x, order);
|
||||
else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
inline static std::string fmt(std::string r, int n) { return r + "[" + int2str(n) + "]"; }
|
||||
|
||||
|
||||
/**
|
||||
* Handles one species in a reaction.
|
||||
* @ingroup Stoichiometry
|
||||
* @internal
|
||||
*/
|
||||
class C1 {
|
||||
|
||||
public:
|
||||
|
||||
C1( int rxn = 0, int ic0 = 0)
|
||||
: m_rxn (rxn), m_ic0 (ic0) {}
|
||||
|
||||
int data(std::vector<int>& ic) {
|
||||
ic.resize(1);
|
||||
ic[0] = m_ic0;
|
||||
return m_rxn;
|
||||
}
|
||||
|
||||
void incrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] += R[m_rxn];
|
||||
}
|
||||
|
||||
void decrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] -= R[m_rxn];
|
||||
}
|
||||
|
||||
void multiply(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] *= S[m_ic0];
|
||||
}
|
||||
|
||||
void incrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] += S[m_ic0];
|
||||
}
|
||||
|
||||
void decrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] -= S[m_ic0];
|
||||
}
|
||||
|
||||
int rxnNumber() const { return m_rxn; }
|
||||
int speciesIndex(int n) const { return m_ic0; }
|
||||
int nSpecies() { return 1;}
|
||||
|
||||
void writeMultiply(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] = fmt(r, m_ic0);
|
||||
}
|
||||
|
||||
void writeIncrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " + "+fmt(r, m_ic0);
|
||||
}
|
||||
void writeDecrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " - "+fmt(r, m_ic0);
|
||||
}
|
||||
|
||||
void writeIncrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_ic0] += " + "+fmt(r, m_rxn);
|
||||
}
|
||||
void writeDecrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_ic0] += " - "+fmt(r, m_rxn);
|
||||
}
|
||||
|
||||
private:
|
||||
int m_rxn, m_ic0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Handles two species in a single reaction.
|
||||
* @ingroup Stoichiometry
|
||||
*/
|
||||
class C2 {
|
||||
public:
|
||||
C2( int rxn = 0, int ic0 = 0, int ic1 = 0)
|
||||
: m_rxn (rxn), m_ic0 (ic0), m_ic1 (ic1) {}
|
||||
|
||||
int data(std::vector<int>& ic) {
|
||||
ic.resize(2);
|
||||
ic[0] = m_ic0;
|
||||
ic[1] = m_ic1;
|
||||
return m_rxn;
|
||||
}
|
||||
|
||||
void incrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] += R[m_rxn];
|
||||
S[m_ic1] += R[m_rxn];
|
||||
}
|
||||
|
||||
void decrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] -= R[m_rxn];
|
||||
S[m_ic1] -= R[m_rxn];
|
||||
}
|
||||
|
||||
void multiply(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] *= S[m_ic0] * S[m_ic1];
|
||||
}
|
||||
|
||||
void incrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] += S[m_ic0] + S[m_ic1];
|
||||
}
|
||||
|
||||
void decrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] -= (S[m_ic0] + S[m_ic1]);
|
||||
}
|
||||
|
||||
int rxnNumber() const { return m_rxn; }
|
||||
int speciesIndex(int n) const { return (n == 0 ? m_ic0 : m_ic1); }
|
||||
int nSpecies() { return 2;}
|
||||
|
||||
void writeMultiply(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] = fmt(r, m_ic0) + " * " + fmt(r, m_ic1);
|
||||
}
|
||||
void writeIncrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " + "+fmt(r, m_ic0)+" + "+fmt(r, m_ic1);
|
||||
}
|
||||
void writeDecrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " - "+fmt(r, m_ic0)+" - "+fmt(r, m_ic1);
|
||||
}
|
||||
|
||||
void writeIncrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = " + "+fmt(r, m_rxn);
|
||||
out[m_ic0] += s;
|
||||
out[m_ic1] += s;
|
||||
}
|
||||
void writeDecrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = " - "+fmt(r, m_rxn);
|
||||
out[m_ic0] += s;
|
||||
out[m_ic1] += s;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
* Reaction index -> index into the ROP vector
|
||||
*/
|
||||
int m_rxn;
|
||||
|
||||
/**
|
||||
* Species indecise -> index into the species vector for the
|
||||
* two species.
|
||||
*/
|
||||
int m_ic0, m_ic1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles three species in a reaction.
|
||||
* @ingroup Stoichiometry
|
||||
*/
|
||||
class C3 {
|
||||
public:
|
||||
C3( int rxn = 0, int ic0 = 0, int ic1 = 0, int ic2 = 0)
|
||||
: m_rxn (rxn), m_ic0 (ic0), m_ic1 (ic1), m_ic2 (ic2) {}
|
||||
|
||||
int data(std::vector<int>& ic) {
|
||||
ic.resize(3);
|
||||
ic[0] = m_ic0;
|
||||
ic[1] = m_ic1;
|
||||
ic[2] = m_ic2;
|
||||
return m_rxn;
|
||||
}
|
||||
|
||||
void incrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] += R[m_rxn];
|
||||
S[m_ic1] += R[m_rxn];
|
||||
S[m_ic2] += R[m_rxn];
|
||||
}
|
||||
|
||||
void decrementSpecies(const doublereal* R, doublereal* S) const {
|
||||
S[m_ic0] -= R[m_rxn];
|
||||
S[m_ic1] -= R[m_rxn];
|
||||
S[m_ic2] -= R[m_rxn];
|
||||
}
|
||||
|
||||
void multiply(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] *= S[m_ic0] * S[m_ic1] * S[m_ic2];
|
||||
}
|
||||
|
||||
void incrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] += S[m_ic0] + S[m_ic1] + S[m_ic2];
|
||||
}
|
||||
|
||||
void decrementReaction(const doublereal* S, doublereal* R) const {
|
||||
R[m_rxn] -= (S[m_ic0] + S[m_ic1] + S[m_ic2]);
|
||||
}
|
||||
|
||||
int rxnNumber() const { return m_rxn; }
|
||||
int speciesIndex(int n) const { return (n == 0 ? m_ic0 : (n == 1 ? m_ic1 : m_ic2)); }
|
||||
int nSpecies() { return 3;}
|
||||
|
||||
void writeMultiply(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] = fmt(r, m_ic0) + " * " + fmt(r, m_ic1) + " * " + fmt(r, m_ic2);
|
||||
}
|
||||
void writeIncrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " + "+fmt(r, m_ic0)+" + "+fmt(r, m_ic1)+" + "+fmt(r, m_ic2);
|
||||
}
|
||||
void writeDecrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
out[m_rxn] += " - "+fmt(r, m_ic0)+" - "+fmt(r, m_ic1)+" - "+fmt(r, m_ic2);
|
||||
}
|
||||
void writeIncrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = " + "+fmt(r, m_rxn);
|
||||
out[m_ic0] += s;
|
||||
out[m_ic1] += s;
|
||||
out[m_ic2] += s;
|
||||
}
|
||||
void writeDecrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = " - "+fmt(r, m_rxn);
|
||||
out[m_ic0] += s;
|
||||
out[m_ic1] += s;
|
||||
out[m_ic2] += s;
|
||||
}
|
||||
private:
|
||||
int m_rxn, m_ic0, m_ic1, m_ic2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles any number of species in a reaction, including fractional
|
||||
* stoichiometric coefficients, and arbitrary reaction orders.
|
||||
* @ingroup Stoichiometry
|
||||
*/
|
||||
class C_AnyN {
|
||||
public:
|
||||
C_AnyN() : m_rxn (-1) {}
|
||||
|
||||
C_AnyN( int rxn, const vector_int& ic, const vector_fp& order,
|
||||
const vector_fp& stoich)
|
||||
: m_rxn (rxn) {
|
||||
m_n = ic.size();
|
||||
m_ic.resize(m_n);
|
||||
m_order.resize(m_n);
|
||||
m_stoich.resize(m_n);
|
||||
for (int n = 0; n < m_n; n++) {
|
||||
m_ic[n] = ic[n];
|
||||
m_order[n] = order[n];
|
||||
m_stoich[n] = stoich[n];
|
||||
}
|
||||
}
|
||||
|
||||
int data(std::vector<int>& ic) {
|
||||
ic.resize(m_n);
|
||||
int n;
|
||||
for (n = 0; n < m_n; n++) ic[n] = m_ic[n];
|
||||
return m_rxn;
|
||||
}
|
||||
|
||||
doublereal order(int n) const {return m_order[n];}
|
||||
doublereal stoich(int n) const {return m_stoich[n];}
|
||||
int speciesIndex(int n) const {return m_ic[n];}
|
||||
|
||||
void multiply(const doublereal* input, doublereal* output) const {
|
||||
for (int n = 0; n < m_n; n++) {
|
||||
output[m_rxn] *=
|
||||
ppow(input[m_ic[n]],m_order[n]);
|
||||
}
|
||||
}
|
||||
|
||||
void incrementSpecies(const doublereal* input,
|
||||
doublereal* output) const {
|
||||
doublereal x = input[m_rxn];
|
||||
for (int n = 0; n < m_n; n++) output[m_ic[n]] += m_stoich[n]*x;
|
||||
}
|
||||
|
||||
void decrementSpecies(const doublereal* input,
|
||||
doublereal* output) const {
|
||||
doublereal x = input[m_rxn];
|
||||
for (int n = 0; n < m_n; n++) output[m_ic[n]] -= m_stoich[n]*x;
|
||||
}
|
||||
|
||||
void incrementReaction(const doublereal* input,
|
||||
doublereal* output) const {
|
||||
for (int n = 0; n < m_n; n++) output[m_rxn]
|
||||
+= m_stoich[n]*input[m_ic[n]];
|
||||
}
|
||||
|
||||
void decrementReaction(const doublereal* input,
|
||||
doublereal* output) const {
|
||||
for (int n = 0; n < m_n; n++) output[m_rxn]
|
||||
-= m_stoich[n]*input[m_ic[n]];
|
||||
}
|
||||
|
||||
void writeMultiply(std::string r, std::map<int, std::string>& out) {
|
||||
int n;
|
||||
out[m_rxn] = "";
|
||||
for (n = 0; n < m_n; n++) {
|
||||
if (m_order[n] == 1.0)
|
||||
out[m_rxn] += fmt(r, m_ic[n]);
|
||||
else
|
||||
out[m_rxn] += "pow("+fmt(r, m_ic[n])+","+fp2str(m_order[n])+")";
|
||||
if (n < m_n-1)
|
||||
out[m_rxn] += " * ";
|
||||
}
|
||||
}
|
||||
void writeIncrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
int n;
|
||||
for (n = 0; n < m_n; n++) {
|
||||
out[m_rxn] += " + "+fp2str(m_stoich[n]) + "*" + fmt(r, m_ic[n]);
|
||||
}
|
||||
}
|
||||
void writeDecrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
int n;
|
||||
for (n = 0; n < m_n; n++) {
|
||||
out[m_rxn] += " - "+fp2str(m_stoich[n]) + "*" + fmt(r, m_ic[n]);
|
||||
}
|
||||
}
|
||||
void writeIncrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = fmt(r, m_rxn);
|
||||
int n;
|
||||
for (n = 0; n < m_n; n++) {
|
||||
out[m_ic[n]] += " + "+fp2str(m_stoich[n]) + "*" + s;
|
||||
}
|
||||
}
|
||||
|
||||
void writeDecrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
std::string s = fmt(r, m_rxn);
|
||||
int n;
|
||||
for (n = 0; n < m_n; n++) {
|
||||
out[m_ic[n]] += " - "+fp2str(m_stoich[n]) + "*" + s;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int m_n, m_rxn;
|
||||
vector_int m_ic;
|
||||
vector_fp m_order;
|
||||
vector_fp m_stoich;
|
||||
};
|
||||
|
||||
|
||||
template<class InputIter, class Vec1, class Vec2>
|
||||
inline static void _multiply(InputIter begin, InputIter end,
|
||||
const Vec1& input, Vec2& output) {
|
||||
for (; begin != end; ++begin)
|
||||
begin->multiply(input, output);
|
||||
}
|
||||
|
||||
template<class InputIter, class Vec1, class Vec2>
|
||||
inline static void _incrementSpecies(InputIter begin,
|
||||
InputIter end, const Vec1& input, Vec2& output) {
|
||||
for (; begin != end; ++begin)
|
||||
begin->incrementSpecies(input, output);
|
||||
}
|
||||
|
||||
template<class InputIter, class Vec1, class Vec2>
|
||||
inline static void _decrementSpecies(InputIter begin,
|
||||
InputIter end, const Vec1& input, Vec2& output) {
|
||||
for (; begin != end; ++begin)
|
||||
begin->decrementSpecies(input, output);
|
||||
}
|
||||
|
||||
template<class InputIter, class Vec1, class Vec2>
|
||||
inline static void _incrementReactions(InputIter begin,
|
||||
InputIter end, const Vec1& input, Vec2& output) {
|
||||
for (; begin != end; ++begin)
|
||||
begin->incrementReaction(input, output);
|
||||
}
|
||||
|
||||
template<class InputIter, class Vec1, class Vec2>
|
||||
inline static void _decrementReactions(InputIter begin,
|
||||
InputIter end, const Vec1& input, Vec2& output) {
|
||||
for (; begin != end; ++begin)
|
||||
begin->decrementReaction(input, output);
|
||||
}
|
||||
|
||||
|
||||
template<class InputIter>
|
||||
inline static void _writeIncrementSpecies(InputIter begin, InputIter end, std::string r,
|
||||
std::map<int, std::string>& out) {
|
||||
for (; begin != end; ++begin) begin->writeIncrementSpecies(r, out);
|
||||
}
|
||||
|
||||
template<class InputIter>
|
||||
inline static void _writeDecrementSpecies(InputIter begin, InputIter end, std::string r,
|
||||
std::map<int, std::string>& out) {
|
||||
for (; begin != end; ++begin) begin->writeDecrementSpecies(r, out);
|
||||
}
|
||||
|
||||
template<class InputIter>
|
||||
inline static void _writeIncrementReaction(InputIter begin, InputIter end, std::string r,
|
||||
std::map<int, std::string>& out) {
|
||||
for (; begin != end; ++begin) begin->writeIncrementReaction(r, out);
|
||||
}
|
||||
|
||||
template<class InputIter>
|
||||
inline static void _writeDecrementReaction(InputIter begin, InputIter end, std::string r,
|
||||
std::map<int, std::string>& out) {
|
||||
for (; begin != end; ++begin) begin->writeDecrementReaction(r, out);
|
||||
}
|
||||
|
||||
template<class InputIter>
|
||||
inline static void _writeMultiply(InputIter begin, InputIter end, std::string r,
|
||||
std::map<int, std::string>& out) {
|
||||
for (; begin != end; ++begin) begin->writeMultiply(r, out);
|
||||
}
|
||||
|
||||
/*
|
||||
* This class handles operations involving the stoichiometric
|
||||
* coefficients on one side of a reaction (reactant or product) for
|
||||
* a set of reactions comprising a reaction mechanism. This class is
|
||||
* used by class ReactionStoichMgr, which contains three instances
|
||||
* of this class (one to handle operations on the reactions, one for
|
||||
* the products of reversible reactions, and one for the products of
|
||||
* irreversible reactions).
|
||||
*
|
||||
* This class is designed for use with elementary reactions, or at
|
||||
* least ones with integral stoichiometric coefficients. Let \f$ M(i) \f$
|
||||
* be the number of molecules on the product or reactant side of
|
||||
* reaction number i.
|
||||
* \f[
|
||||
* r_i = \sum_m^{M_i} s_{k_{m,i}}
|
||||
* \f]
|
||||
* To understand the operations performed by this class, let
|
||||
* \f$ N_{k,i}\f$ denote the stoichiometric coefficient of species k on
|
||||
* one side (reactant or product) in reaction i. Then \b N is a sparse
|
||||
* K by I matrix of stoichiometric coefficients.
|
||||
*
|
||||
* The following matrix operations may be carried out with a vector
|
||||
* S of length K, and a vector R of length I:
|
||||
*
|
||||
* - \f$ S = S + N R\f$ (incrementSpecies)
|
||||
* - \f$ S = S - N R\f$ (decrementSpecies)
|
||||
* - \f$ R = R + N^T S \f$ (incrementReaction)
|
||||
* - \f$ R = R - N^T S \f$ (deccrementReaction)
|
||||
*
|
||||
* The actual implementation, however, does not compute these
|
||||
* quantities by matrix multiplication. A faster algorithm is used
|
||||
* that makes use of the fact that the \b integer-valued N matrix is
|
||||
* very sparse, and the non-zero terms are small positive integers.
|
||||
* \f[
|
||||
* S_k = R_{i1} + \dots + R_{iM}
|
||||
* \f]
|
||||
* where M is the number of molecules, and $\f i(m) \f$ is the
|
||||
* @ingroup Stoichiometry
|
||||
*/
|
||||
class StoichManagerN {
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for the StoichManagerN class.
|
||||
*
|
||||
* @internal Consider adding defaulted entries here that supply
|
||||
* the total number of reactions in the mechanism and the total
|
||||
* number of species in the species list. Then, we could use those
|
||||
* numbers to provide error checks during the construction of the
|
||||
* object. Those numbers would also provide some clarity to the
|
||||
* purpose and utility of this class.
|
||||
*
|
||||
* DGG - the problem is that the number of reactions and species
|
||||
* are not known initially.
|
||||
*/
|
||||
StoichManagerN() {}
|
||||
|
||||
/**
|
||||
* Add a single reaction to the list of reactions that this
|
||||
* stoichiometric manager object handles.
|
||||
*
|
||||
* This function is the same as the add() function below. However,
|
||||
* the order of each species in the power list expression is
|
||||
* set to one automatically.
|
||||
*/
|
||||
void add(int rxn, const vector_int& k) {
|
||||
vector_fp order(k.size(), 1.0);
|
||||
vector_fp stoich(k.size(), 1.0);
|
||||
add(rxn, k, order, stoich);
|
||||
}
|
||||
|
||||
void add(int rxn, const vector_int& k, const vector_fp& order) {
|
||||
vector_fp stoich(k.size(), 1.0);
|
||||
add(rxn, k, order, stoich);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a single reaction to the list of reactions that this
|
||||
* stoichiometric manager object handles.
|
||||
*
|
||||
* @param rxn Reaction index of the current reaction. This is used
|
||||
* as an index into vectors which have length n_total_rxn.
|
||||
* @param k This is a vector of integer values specifying the
|
||||
* species indecises. The length of this vector species
|
||||
* the number of different species in the description.
|
||||
* The value of the entries are the species indices.
|
||||
* These are used as indexes into vectors which have
|
||||
* length n_total_species.
|
||||
* @param order This is a vector of the same length as vector k.
|
||||
* The order is used for the routine power(), which produces
|
||||
* a power law expression involving the species vector.
|
||||
* @param stoich This is used to handle fractional stoichiometric coefficients
|
||||
* on the product side of irreversible reactions.
|
||||
*/
|
||||
void add(int rxn, const vector_int& k, const vector_fp& order,
|
||||
const vector_fp& stoich) {
|
||||
m_n[rxn] = static_cast<int>(k.size());
|
||||
int ns = stoich.size();
|
||||
int n;
|
||||
bool frac = false;
|
||||
for (n = 0; n < ns; n++) {
|
||||
if (stoich[n] != 1.0) frac = true;
|
||||
}
|
||||
if (frac) {
|
||||
m_loc[rxn] = static_cast<int>(m_cn_list.size());
|
||||
m_cn_list.push_back(C_AnyN(rxn, k, order, stoich));
|
||||
}
|
||||
else {
|
||||
switch (k.size()) {
|
||||
case 1:
|
||||
m_loc[rxn] = static_cast<int>(m_c1_list.size());
|
||||
m_c1_list.push_back(C1(rxn, k[0]));
|
||||
break;
|
||||
case 2:
|
||||
m_loc[rxn] = static_cast<int>(m_c2_list.size());
|
||||
m_c2_list.push_back(C2(rxn, k[0], k[1]));
|
||||
break;
|
||||
case 3:
|
||||
m_loc[rxn] = static_cast<int>(m_c3_list.size());
|
||||
m_c3_list.push_back(C3(rxn, k[0], k[1], k[2]));
|
||||
break;
|
||||
default:
|
||||
m_loc[rxn] = static_cast<int>(m_cn_list.size());
|
||||
m_cn_list.push_back(C_AnyN(rxn, k, order, stoich));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void multiply(const doublereal* input, doublereal* output) const {
|
||||
_multiply(m_c1_list.begin(), m_c1_list.end(), input, output);
|
||||
_multiply(m_c2_list.begin(), m_c2_list.end(), input, output);
|
||||
_multiply(m_c3_list.begin(), m_c3_list.end(), input, output);
|
||||
_multiply(m_cn_list.begin(), m_cn_list.end(), input, output);
|
||||
}
|
||||
|
||||
void incrementSpecies(const doublereal* input, doublereal* output) const {
|
||||
_incrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output);
|
||||
_incrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output);
|
||||
_incrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output);
|
||||
_incrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output);
|
||||
}
|
||||
|
||||
void decrementSpecies(const doublereal* input, doublereal* output) const {
|
||||
_decrementSpecies(m_c1_list.begin(), m_c1_list.end(), input, output);
|
||||
_decrementSpecies(m_c2_list.begin(), m_c2_list.end(), input, output);
|
||||
_decrementSpecies(m_c3_list.begin(), m_c3_list.end(), input, output);
|
||||
_decrementSpecies(m_cn_list.begin(), m_cn_list.end(), input, output);
|
||||
}
|
||||
|
||||
void incrementReactions(const doublereal* input, doublereal* output) const {
|
||||
_incrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output);
|
||||
_incrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output);
|
||||
_incrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output);
|
||||
_incrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output);
|
||||
}
|
||||
|
||||
void decrementReactions(const doublereal* input, doublereal* output) const {
|
||||
_decrementReactions(m_c1_list.begin(), m_c1_list.end(), input, output);
|
||||
_decrementReactions(m_c2_list.begin(), m_c2_list.end(), input, output);
|
||||
_decrementReactions(m_c3_list.begin(), m_c3_list.end(), input, output);
|
||||
_decrementReactions(m_cn_list.begin(), m_cn_list.end(), input, output);
|
||||
}
|
||||
|
||||
void writeIncrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
_writeIncrementSpecies(m_c1_list.begin(), m_c1_list.end(), r, out);
|
||||
_writeIncrementSpecies(m_c2_list.begin(), m_c2_list.end(), r, out);
|
||||
_writeIncrementSpecies(m_c3_list.begin(), m_c3_list.end(), r, out);
|
||||
_writeIncrementSpecies(m_cn_list.begin(), m_cn_list.end(), r, out);
|
||||
}
|
||||
|
||||
void writeDecrementSpecies(std::string r, std::map<int, std::string>& out) {
|
||||
_writeDecrementSpecies(m_c1_list.begin(), m_c1_list.end(), r, out);
|
||||
_writeDecrementSpecies(m_c2_list.begin(), m_c2_list.end(), r, out);
|
||||
_writeDecrementSpecies(m_c3_list.begin(), m_c3_list.end(), r, out);
|
||||
_writeDecrementSpecies(m_cn_list.begin(), m_cn_list.end(), r, out);
|
||||
}
|
||||
|
||||
void writeIncrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
_writeIncrementReaction(m_c1_list.begin(), m_c1_list.end(), r, out);
|
||||
_writeIncrementReaction(m_c2_list.begin(), m_c2_list.end(), r, out);
|
||||
_writeIncrementReaction(m_c3_list.begin(), m_c3_list.end(), r, out);
|
||||
_writeIncrementReaction(m_cn_list.begin(), m_cn_list.end(), r, out);
|
||||
}
|
||||
|
||||
void writeDecrementReaction(std::string r, std::map<int, std::string>& out) {
|
||||
_writeDecrementReaction(m_c1_list.begin(), m_c1_list.end(), r, out);
|
||||
_writeDecrementReaction(m_c2_list.begin(), m_c2_list.end(), r, out);
|
||||
_writeDecrementReaction(m_c3_list.begin(), m_c3_list.end(), r, out);
|
||||
_writeDecrementReaction(m_cn_list.begin(), m_cn_list.end(), r, out);
|
||||
}
|
||||
|
||||
void writeMultiply(std::string r, std::map<int, std::string>& out) {
|
||||
_writeMultiply(m_c1_list.begin(), m_c1_list.end(), r, out);
|
||||
_writeMultiply(m_c2_list.begin(), m_c2_list.end(), r, out);
|
||||
_writeMultiply(m_c3_list.begin(), m_c3_list.end(), r, out);
|
||||
_writeMultiply(m_cn_list.begin(), m_cn_list.end(), r, out);
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
std::vector<C1> m_c1_list;
|
||||
std::vector<C2> m_c2_list;
|
||||
std::vector<C3> m_c3_list;
|
||||
std::vector<C_AnyN> m_cn_list;
|
||||
/**
|
||||
* Std::Mapping with the Reaction Number as key and the Number of species
|
||||
* as the value.
|
||||
*/
|
||||
std::map<int, int> m_n;
|
||||
/**
|
||||
* Std::Mapping with the Reaction Number as key and the placement in the
|
||||
* vector of reactions list( i.e., m_c1_list[]) as key
|
||||
*/
|
||||
std::map<int, int> m_loc;
|
||||
};
|
||||
|
||||
#undef INCL_STOICH_WRITER
|
||||
#ifdef INCL_STOICH_WRITER
|
||||
|
||||
class StoichWriter {
|
||||
public:
|
||||
|
||||
StoichWriter() {}
|
||||
|
||||
void add(int rxn, const vector_int& k) {
|
||||
int n, nn = k.size();
|
||||
for (n = 0; n < nn; n++) {
|
||||
if (m_mult[rxn] != "") m_mult[rxn] += " * ";
|
||||
m_mult[rxn] += "c[" + int2str(k[n]) + "]";
|
||||
m_is[k[n]] += " + rop[" + int2str(rxn) + "]";
|
||||
m_ds[k[n]] += " - rop[" + int2str(rxn) + "]";
|
||||
m_ir[rxn] += " + grt[" + int2str(k[n]) + "]";
|
||||
m_dr[rxn] += " - grt[" + int2str(k[n]) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
void add(int rxn, const vector_int& k, const vector_fp& order,
|
||||
const vector_fp& stoich) {
|
||||
int n, nn = k.size();
|
||||
std::string s;
|
||||
for (n = 0; n < nn; n++) {
|
||||
if (order[n] == 1.0)
|
||||
m_mult[rxn] += "*c[" + int2str(k[n]) + "]";
|
||||
else
|
||||
m_mult[rxn] += "*pow(c[" _ int2str(k[n]) + "],"+fp2str(order[n])+")";
|
||||
if (stoich[n] == 1.0) {
|
||||
m_is[k[n]] += " + r[" + int2str(rxn) + "]";
|
||||
m_ds[k[n]] += " - r[" + int2str(rxn) + "]";
|
||||
m_ir[rxn] += " + g[" + int2str(k[n]) + "]";
|
||||
m_dr[rxn] += " - g[" + int2str(k[n]) + "]";
|
||||
}
|
||||
else {
|
||||
s = fp2str(stoich[n]);
|
||||
m_is[k[n]] += " + "+s+"*r[" + int2str(rxn) + "]";
|
||||
m_ds[k[n]] += " - "+s+"*r[" + int2str(rxn) + "]";
|
||||
m_ir[rxn] += " + "+s+"*g[" + int2str(k[n]) + "]";
|
||||
m_dr[rxn] += " - "+s+"*g[" + int2str(k[n]) + "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string mult(int rxn) { return m_mult[rxn]; }
|
||||
std::string incrSpec(int k, std::string) { return m_is[k]; }
|
||||
std::string decrSpec(int k) { return m_ds[k]; }
|
||||
std::string incrRxn(int rxn) { return m_ir[rxn]; }
|
||||
std::string decrRxn(int rxn) { return m_dr[rxn]; }
|
||||
|
||||
private:
|
||||
std::map<int, std::string> m_mult, m_ir, m_dr, m_is, m_ds;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
187
Cantera/src/kinetics/ThirdBodyMgr.h
Executable file
187
Cantera/src/kinetics/ThirdBodyMgr.h
Executable file
|
|
@ -0,0 +1,187 @@
|
|||
/**
|
||||
* @file ThirdBodyMgr.h
|
||||
*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_THIRDBODY_MGR_H
|
||||
#define CT_THIRDBODY_MGR_H
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "ct_defs.h"
|
||||
#include "utilities.h"
|
||||
#include "Enhanced3BConc.h"
|
||||
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
template<class _E>
|
||||
class ThirdBodyMgr{
|
||||
|
||||
public:
|
||||
|
||||
ThirdBodyMgr<_E>() : m_n(0) {}
|
||||
|
||||
void install( int rxnNumber, const std::map<int, doublereal>& enhanced,
|
||||
doublereal dflt=1.0) {
|
||||
m_n++;
|
||||
m_reaction_index.push_back( rxnNumber );
|
||||
m_concm.push_back( _E(static_cast<int>(enhanced.size()),
|
||||
enhanced, dflt ) );
|
||||
}
|
||||
|
||||
void update(const vector_fp& conc, doublereal ctot, workPtr work) {
|
||||
TYPENAME_KEYWORD std::vector<_E>::const_iterator b = m_concm.begin();
|
||||
//doublereal* v = m_values.begin();
|
||||
for (; b != m_concm.end(); ++b, ++work)
|
||||
*work = b->update(conc, ctot);
|
||||
}
|
||||
|
||||
void multiply(doublereal* output, const_workPtr work) {
|
||||
scatter_mult(work, work + m_n,
|
||||
output, m_reaction_index.begin());
|
||||
}
|
||||
|
||||
size_t workSize() { return m_concm.size(); }
|
||||
bool contains(int rxnNumber) {
|
||||
return (find(m_reaction_index.begin(),
|
||||
m_reaction_index.end(), rxnNumber)
|
||||
!= m_reaction_index.end());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
int m_n;
|
||||
vector_int m_reaction_index;
|
||||
std::vector<_E> m_concm;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1069
Cantera/src/kinetics/importKinetics.cpp
Normal file
1069
Cantera/src/kinetics/importKinetics.cpp
Normal file
File diff suppressed because it is too large
Load diff
217
Cantera/src/kinetics/importKinetics.h
Normal file
217
Cantera/src/kinetics/importKinetics.h
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
/**
|
||||
* @file importKinetics.h
|
||||
* Definitions of global routines for the importing
|
||||
* of data from XML files (see \ref inputfiles).
|
||||
*
|
||||
* This file contains routines which are global routines, i.e.,
|
||||
* not part of any object. These routine take as input, ctml
|
||||
* pointers to data, and pointers to %Cantera objects. The purpose
|
||||
* of these routines is to intialize the %Cantera objects with data
|
||||
* from the ctml tree structures.
|
||||
*/
|
||||
/*
|
||||
* $Author$
|
||||
* $Revision$
|
||||
* $Date$
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2002 California Institute of Technology
|
||||
|
||||
|
||||
#ifndef CT_IMPORTCTML_H
|
||||
#define CT_IMPORTCTML_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "ThermoPhase.h"
|
||||
#include "Kinetics.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
class Kinetics;
|
||||
class SpeciesThermoFactory;
|
||||
class XML_Node;
|
||||
|
||||
|
||||
//!This function returns a ratio if two reactions are duplicates of
|
||||
//!one another, and 0.0 otherwise.
|
||||
/*!
|
||||
* The input arguments are two
|
||||
* maps from species number to stoichiometric coefficient, one for
|
||||
* each reaction. The reactions are considered duplicates if their
|
||||
* stoichiometric coefficients have the same ratio for all
|
||||
* species.
|
||||
*
|
||||
* @param r1 map 1
|
||||
* @param r2 map 2
|
||||
*
|
||||
* @return
|
||||
* Returns 0.0 if the reactions are not the same.
|
||||
* If the reactions are the same, it returns the ratio of the
|
||||
* stoichiometric coefficients.
|
||||
*
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
doublereal isDuplicateReaction(std::map<int, doublereal>& r1,
|
||||
std::map<int, doublereal>& r2);
|
||||
|
||||
|
||||
//! This function will check a specific reaction to see if the elements balance.
|
||||
/*!
|
||||
* @param kin Kinetics object
|
||||
* @param rdata Object containing the information about one reaction
|
||||
* @param errorTolerance double containing the error tolerance.
|
||||
*
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
void checkRxnElementBalance(Kinetics& kin,
|
||||
const ReactionData &rdata,
|
||||
doublereal errorTolerance = 1.0e-3);
|
||||
|
||||
//! Read the rate coefficient data from the XML file.
|
||||
/*!
|
||||
* Extract the rate coefficient for a reaction from the xml node, kf.
|
||||
* kf should point to a XML element named "rateCoeff".
|
||||
* rdata is the partially filled ReactionData object for the reaction.
|
||||
* This function will fill in more fields in the ReactionData object.
|
||||
*
|
||||
* @param kf XML_Node containing information about the rate coefficients.
|
||||
* @param kin kinetics manager
|
||||
* @param rdata ReactionData referece
|
||||
* @param negA Boolean indicating whether negative A's are ok.
|
||||
*
|
||||
* Trigger anexception for negative A unless specifically authorized.
|
||||
*
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
void getRateCoefficient(const XML_Node& kf, kinetics_t& kin,
|
||||
ReactionData& rdata, int negA);
|
||||
|
||||
|
||||
//! Create a new ThermoPhase object and initializes it according to the XML tree database.
|
||||
|
||||
|
||||
//! Install information about reactions into the kinetics object, kin.
|
||||
/*!
|
||||
* At this point, parent usually refers to the phase xml element.
|
||||
* One of the children of this element is reactionArray,
|
||||
* the element which determines where in the xml file to
|
||||
* look up the reaction rate data.
|
||||
*
|
||||
* This is a wrapper routine around the static function installReaction()
|
||||
*
|
||||
* @param p parent XML phase element
|
||||
* @param kin Kinetics object to install reactions into
|
||||
* @param default_phase The default_phase is the default phase to assume when
|
||||
* looking up species.
|
||||
* @param check_for_duplicates Check for reactions with exactly the same
|
||||
* reactants and products.
|
||||
*
|
||||
* @return
|
||||
* On return, if reaction instantiation goes correctly, return true.
|
||||
* If there is a problem, return false.
|
||||
*
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
bool installReactionArrays(const XML_Node& p, Kinetics& kin,
|
||||
std::string default_phase,
|
||||
bool check_for_duplicates = false);
|
||||
|
||||
//! Import a reaction mechanism for a phase or an interface.
|
||||
/*!
|
||||
* This routine will import a reaction mechanism into a
|
||||
* kinetics object. The reaction
|
||||
* mechanism may either be homogeneous or heterogeneous,
|
||||
* involving multiple ThermoPhase objects.
|
||||
* The hosting phase should be included as the first argument.
|
||||
* For example, if phase I is an interface phase between bulk
|
||||
* phases A and B. Then, the XML_Node for phase I should be
|
||||
* the first argument.
|
||||
* The vector of %ThermoPhase objects should be consist of pointers
|
||||
* to phases I, A, and B.
|
||||
*
|
||||
* @param phase This is an xml node containing a description
|
||||
* of a phase. Within the phase is a XML element
|
||||
* called reactionArray containing the location
|
||||
* of the description of the reactions that make
|
||||
* up the kinetics object.
|
||||
* Also within the phase is an XML element called
|
||||
* phaseArray containing a listing of other phases
|
||||
* that participate in the kinetics mechanism.
|
||||
*
|
||||
* @param th This is a list of ThermoPhase pointers containing
|
||||
* the phases that participate in the kinetics
|
||||
* reactions. All of the phases must have already
|
||||
* been initialized and formed within Cantera.
|
||||
* However, their pointers should not have been
|
||||
* added to the Kinetics object; this addition
|
||||
* is carried out here.
|
||||
*
|
||||
* @param kin This is a pointer to a bare kinetics manager class
|
||||
* that will be initialized with the kinetics
|
||||
* mechanism.
|
||||
*
|
||||
* @ingroup kineticsmgr
|
||||
*
|
||||
*/
|
||||
bool importKinetics(const XML_Node& phase, std::vector<ThermoPhase*> th,
|
||||
Kinetics* kin);
|
||||
|
||||
//!Build a single-phase ThermoPhase object with associated kinetics mechanism.
|
||||
/*!
|
||||
* In a single call, this routine initializes a ThermoPhase object and a
|
||||
* homogenous kinetics object for a phase.
|
||||
*
|
||||
* @param root pointer to the XML tree which will be searched to find the
|
||||
* XML phase element.
|
||||
*
|
||||
* @param id Name of the phase to be searched for.
|
||||
* @param nm Name of the XML element. Should be "phase"
|
||||
* @param th Pointer to a bare ThermoPhase object, which will be initialized
|
||||
* by this operaton.
|
||||
* @param k Pointer to a bare Kinetics object, which will be initialized
|
||||
* by this operation to a homogeneous kinetics manager
|
||||
*
|
||||
* @return
|
||||
* Returns true if all went well. If there are errors, it will return false.
|
||||
*
|
||||
* For Example
|
||||
*
|
||||
* @code
|
||||
* ThermoPhase *th = new ThermoPhase();
|
||||
* Kinetics *k = new Kinetics();
|
||||
* XML_Node *root = get_XML_File("gri30.xml");
|
||||
* ok = buildSolutionFromXML(root, "gri30_mix", "phase", th, k)
|
||||
* @endcode
|
||||
*
|
||||
* @ingroup inputfiles
|
||||
* @see importKinetics()
|
||||
*/
|
||||
bool buildSolutionFromXML(XML_Node& root, std::string id, std::string nm,
|
||||
ThermoPhase* th, Kinetics* k);
|
||||
|
||||
//! Search an XML tree for species data.
|
||||
/*!
|
||||
*
|
||||
* This utility routine will search the XML tree for the species
|
||||
* named by the string, kname. It will return the XML_Node
|
||||
* pointer.
|
||||
* Failures of any kind return the null pointer.
|
||||
*
|
||||
* @param kname species Name
|
||||
* @param phaseSpeciesData Pointer to the phase XML node pertaining to the
|
||||
* species database for the phase to be found
|
||||
*
|
||||
* @return
|
||||
* Returns a pointer to teh XML node containing the species data.
|
||||
*
|
||||
* @ingroup inputfiles
|
||||
*/
|
||||
//const XML_Node *speciesXML_Node(std::string kname,
|
||||
// const XML_Node *phaseSpeciesData);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
111
Cantera/src/kinetics/reaction_defs.h
Executable file
111
Cantera/src/kinetics/reaction_defs.h
Executable file
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* @file reaction_defs.h
|
||||
* This file defines some constants used to specify reaction types.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*
|
||||
*/
|
||||
|
||||
// Copyright 2001 California Institute of Technology
|
||||
|
||||
#ifndef CT_RXN_DEFS_H
|
||||
#define CT_RXN_DEFS_H
|
||||
|
||||
#include "ct_defs.h"
|
||||
|
||||
namespace Cantera {
|
||||
|
||||
const int NONE = 0;
|
||||
|
||||
/// @name Reaction Types
|
||||
|
||||
//@{
|
||||
|
||||
/**
|
||||
* A reaction with a rate coefficient that depends only on
|
||||
* temperature. Example: O + OH <-> O2 + H
|
||||
*/
|
||||
const int ELEMENTARY_RXN = 1;
|
||||
|
||||
/**
|
||||
* A reaction that requires a third-body collision partner. Example:
|
||||
* O2 + M <-> O + O + M
|
||||
*/
|
||||
const int THREE_BODY_RXN = 2;
|
||||
|
||||
/**
|
||||
* The general form for an association or dissociation reaction, with a
|
||||
* pressure-dependent rate. Example: CH3 + H (+M) <-> CH4 (+M)
|
||||
*/
|
||||
const int FALLOFF_RXN = 4;
|
||||
|
||||
/**
|
||||
* A chemical activation reaction. For these reactions, the rate falls
|
||||
* off as the pressure increases, due to collisional stabilization of
|
||||
* a reaction intermediate. Example: Si + SiH4 (+M) <-> Si2H2 + H2
|
||||
* (+M), which competes with Si + SiH4 (+M) <-> Si2H4 (+M).
|
||||
* @todo Implement chemical activation reactions.
|
||||
*/
|
||||
const int CHEMACT_RXN = 8;
|
||||
|
||||
/**
|
||||
* A reaction occurring on a surface.
|
||||
*/
|
||||
const int SURFACE_RXN = 20;
|
||||
|
||||
/**
|
||||
* A reaction occurring at a one-dimensional interface between two
|
||||
* surface phases.
|
||||
*/
|
||||
const int EDGE_RXN = 22;
|
||||
|
||||
/**
|
||||
* A global reaction. These may have non-integral reaction orders,
|
||||
* and are not allowed to be reversible.
|
||||
*/
|
||||
const int GLOBAL_RXN = 30;
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Rate Coefficient Types
|
||||
* These types define the supported rate coefficient types for
|
||||
* elementary reactions. Any of these may also be used as the high and
|
||||
* low-pressure limits of falloff and chemical activation reactions.
|
||||
*
|
||||
* Note that not all of these are currently implemented!
|
||||
* @todo Finish implementing reaction rate types.
|
||||
*/
|
||||
//@{
|
||||
|
||||
const int ARRHENIUS = 1;
|
||||
const int LANDAUTELLER = 2;
|
||||
const int TSTRATE = 3;
|
||||
const int SURF_ARRHENIUS = 4;
|
||||
const int ARRHENIUS_SUM = 5;
|
||||
|
||||
//@}
|
||||
|
||||
/** @name Falloff Function Types
|
||||
*/
|
||||
//@{
|
||||
const int SIMPLE_FALLOFF = 100;
|
||||
const int TROE3_FALLOFF = 110;
|
||||
const int TROE4_FALLOFF = 111;
|
||||
const int SRI3_FALLOFF = 112;
|
||||
const int SRI5_FALLOFF = 113;
|
||||
const int WF_FALLOFF = 114;
|
||||
//@}
|
||||
|
||||
// error flags
|
||||
const int NO_ERROR = 0;
|
||||
const int UNKNOWN_REACTION_TYPE = -100;
|
||||
const int UNKNOWN_RATE_COEFF_TYPE = -200;
|
||||
const int NOT_YET_IMPLEMENTED = -300;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Reference in a new issue