[Kinetics] Combine ReactionStoichMgr with class Kinetics

Class ReactionStoichMgr is now deprecated, as all of its functions were just
pass-throughs between Kinetics and StoichManagerN.
This commit is contained in:
Ray Speth 2014-11-01 00:13:46 +00:00
parent f1387be98a
commit 557ffffc5b
9 changed files with 186 additions and 46 deletions

View file

@ -11,7 +11,7 @@
#define CT_KINETICS_H
#include "cantera/thermo/ThermoPhase.h"
#include "ReactionStoichMgr.h"
#include "StoichManager.h"
#include "cantera/thermo/mix_defs.h"
namespace Cantera
@ -457,9 +457,19 @@ public:
* @param deltaProperty Output vector of deltaRxn. Length: m_ii.
*/
virtual void getReactionDelta(const doublereal* property,
doublereal* deltaProperty) {
throw NotImplementedError("Kinetics::getReactionDelta");
}
doublereal* deltaProperty);
/**
* 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 reverse rate coefficients
* from thermochemistry for reversible reactions.
*/
virtual void getRevReactionDelta(const doublereal* g, doublereal* dg);
//! Return the vector of values for the reaction gibbs free energy change.
/*!
@ -863,13 +873,23 @@ protected:
throw NotImplementedError("Kinetics::updateROP");
}
//! Stoichiometric manager for the reaction mechanism
//! @name Stoichiometry management
/*!
* This is the manager for the kinetics mechanism that handles turning
* reaction extents into species production rates and also handles
* turning thermo properties into reaction thermo properties.
* These objects and functions handle turning reaction extents into species
* production rates and also handle turning thermo properties into reaction
* thermo properties.
*/
ReactionStoichMgr m_rxnstoich;
//@{
//! Stoichiometry manager for the reactants for each reaction
StoichManagerN m_reactantStoich;
//! Stoichiometry manager for the products of reversible reactions
StoichManagerN m_revProductStoich;
//! Stoichiometry manager for the products of irreversible reactions
StoichManagerN m_irrevProductStoich;
//@}
//! Number of reactions in the mechanism
size_t m_ii;

View file

@ -51,7 +51,8 @@ class ReactionData;
* Vector of K species destruction rates.
* - \f$ W = C - D \f$
* Vector of K species net production rates.
*
* @deprecated Unused; Functionality merged into class Kinetics. To be removed
* after Cantera 2.2.
*/
class ReactionStoichMgr
{

View file

@ -58,7 +58,7 @@ void AqueousKinetics::updateKc()
}
// compute Delta G^0 for all reversible reactions
m_rxnstoich.getRevReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
getRevReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_revindex.size(); i++) {
@ -84,7 +84,7 @@ void AqueousKinetics::getEquilibriumConstants(doublereal* kc)
}
// compute Delta G^0 for all reactions
m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
getReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_ii; i++) {
@ -119,10 +119,10 @@ void AqueousKinetics::updateROP()
multiply_each(m_ropr.begin(), m_ropr.end(), m_rkcn.begin());
// multiply ropf by concentration products
m_rxnstoich.multiplyReactants(&m_conc[0], &m_ropf[0]);
m_reactantStoich.multiply(&m_conc[0], &m_ropf[0]);
// for reversible reactions, multiply ropr by concentration products
m_rxnstoich.multiplyRevProducts(&m_conc[0], &m_ropr[0]);
m_revProductStoich.multiply(&m_conc[0], &m_ropr[0]);
for (size_t j = 0; j != m_ii; ++j) {
m_ropnet[j] = m_ropf[j] - m_ropr[j];

View file

@ -36,7 +36,7 @@ void BulkKinetics::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);
getReactionDelta(&m_grt[0], deltaG);
}
void BulkKinetics::getDeltaEnthalpy(doublereal* deltaH)
@ -44,7 +44,7 @@ void BulkKinetics::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 deltaH for each reaction.
m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaH);
getReactionDelta(&m_grt[0], deltaH);
}
void BulkKinetics::getDeltaEntropy(doublereal* deltaS)
@ -52,7 +52,7 @@ void BulkKinetics::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);
getReactionDelta(&m_grt[0], deltaS);
}
void BulkKinetics::getDeltaSSGibbs(doublereal* deltaG)
@ -63,7 +63,7 @@ void BulkKinetics::getDeltaSSGibbs(doublereal* deltaG)
// 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);
getReactionDelta(&m_grt[0], deltaG);
}
void BulkKinetics::getDeltaSSEnthalpy(doublereal* deltaH)
@ -75,7 +75,7 @@ void BulkKinetics::getDeltaSSEnthalpy(doublereal* deltaH)
m_grt[k] *= RT;
}
// Use the stoichiometric manager to find deltaH for each reaction.
m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaH);
getReactionDelta(&m_grt[0], deltaH);
}
void BulkKinetics::getDeltaSSEntropy(doublereal* deltaS)
@ -89,7 +89,7 @@ void BulkKinetics::getDeltaSSEntropy(doublereal* deltaS)
m_grt[k] *= R;
}
// Use the stoichiometric manager to find deltaS for each reaction.
m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], deltaS);
getReactionDelta(&m_grt[0], deltaS);
}
void BulkKinetics::getRevRateConstants(doublereal* krev, bool doIrreversible)

View file

@ -195,11 +195,11 @@ void ElectrodeKinetics::updateROP()
// multiply ropf by the actyivity concentration reaction orders to obtain
// the forward rates of progress.
//
m_rxnstoich.multiplyReactants(DATA_PTR(m_actConc), DATA_PTR(m_ropf));
m_reactantStoich.multiply(DATA_PTR(m_actConc), DATA_PTR(m_ropf));
//
// For reversible reactions, multiply ropr by the activity concentration products
//
m_rxnstoich.multiplyRevProducts(DATA_PTR(m_actConc), DATA_PTR(m_ropr));
m_revProductStoich.multiply(DATA_PTR(m_actConc), DATA_PTR(m_ropr));
//
// Fix up these calculations for cases where the above formalism doesn't hold
//

View file

@ -103,7 +103,7 @@ void GasKinetics::updateKc()
fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
// compute Delta G^0 for all reversible reactions
m_rxnstoich.getRevReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
getRevReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_revindex.size(); i++) {
@ -124,7 +124,7 @@ void GasKinetics::getEquilibriumConstants(doublereal* kc)
fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
// compute Delta G^0 for all reactions
m_rxnstoich.getReactionDelta(m_ii, &m_grt[0], &m_rkcn[0]);
getReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_ii; i++) {
@ -194,10 +194,10 @@ void GasKinetics::updateROP()
multiply_each(m_ropr.begin(), m_ropr.end(), m_rkcn.begin());
// multiply ropf by concentration products
m_rxnstoich.multiplyReactants(&m_conc[0], &m_ropf[0]);
m_reactantStoich.multiply(&m_conc[0], &m_ropf[0]);
// for reversible reactions, multiply ropr by concentration products
m_rxnstoich.multiplyRevProducts(&m_conc[0], &m_ropr[0]);
m_revProductStoich.multiply(&m_conc[0], &m_ropr[0]);
for (size_t j = 0; j != m_ii; ++j) {
m_ropnet[j] = m_ropf[j] - m_ropr[j];

View file

@ -251,7 +251,7 @@ void InterfaceKinetics::updateKc()
doublereal rrt = 1.0 / (GasConstant * thermo(0).temperature());
// compute Delta mu^0 for all reversible reactions
m_rxnstoich.getRevReactionDelta(m_ii, DATA_PTR(m_mu0_Kc), DATA_PTR(m_rkcn));
getRevReactionDelta(DATA_PTR(m_mu0_Kc), DATA_PTR(m_rkcn));
for (size_t i = 0; i < m_nrev; i++) {
size_t irxn = m_revindex[i];
@ -314,7 +314,7 @@ void InterfaceKinetics::checkPartialEquil()
}
// compute Delta mu^ for all reversible reactions
m_rxnstoich.getRevReactionDelta(m_ii, DATA_PTR(dmu), DATA_PTR(rmu));
getRevReactionDelta(DATA_PTR(dmu), DATA_PTR(rmu));
updateROP();
for (size_t i = 0; i < m_nrev; i++) {
size_t irxn = m_revindex[i];
@ -334,7 +334,7 @@ void InterfaceKinetics::getEquilibriumConstants(doublereal* kc)
std::fill(kc, kc + m_ii, 0.0);
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu0_Kc), kc);
getReactionDelta(DATA_PTR(m_mu0_Kc), kc);
for (size_t i = 0; i < m_ii; i++) {
kc[i] = exp(-kc[i]*rrt);
@ -368,13 +368,13 @@ void InterfaceKinetics::updateExchangeCurrentQuantities()
}
}
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu0), DATA_PTR(m_deltaG0));
getReactionDelta(DATA_PTR(m_mu0), DATA_PTR(m_deltaG0));
// Calculate the product of the standard concentrations of the reactants
for (size_t i = 0; i < m_ii; i++) {
m_ProdStanConcReac[i] = 1.0;
}
m_rxnstoich.multiplyReactants(DATA_PTR(m_StandardConc), DATA_PTR(m_ProdStanConcReac));
m_reactantStoich.multiply(DATA_PTR(m_StandardConc), DATA_PTR(m_ProdStanConcReac));
}
void InterfaceKinetics::applyVoltageKfwdCorrection(doublereal* const kf)
@ -392,7 +392,7 @@ void InterfaceKinetics::applyVoltageKfwdCorrection(doublereal* const kf)
// Compute the change in electrical potential energy for each
// reaction. This will only be non-zero if a potential
// difference is present.
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_pot), DATA_PTR(deltaElectricEnergy_));
getReactionDelta(DATA_PTR(m_pot), DATA_PTR(deltaElectricEnergy_));
// Modify the reaction rates. Only modify those with a
// non-zero activation energy. Below we decrease the
@ -540,10 +540,10 @@ void InterfaceKinetics::updateROP()
// multiply ropf by the actyivity concentration reaction orders to obtain
// the forward rates of progress.
m_rxnstoich.multiplyReactants(DATA_PTR(m_actConc), DATA_PTR(m_ropf));
m_reactantStoich.multiply(DATA_PTR(m_actConc), DATA_PTR(m_ropf));
// For reversible reactions, multiply ropr by the activity concentration products
m_rxnstoich.multiplyRevProducts(DATA_PTR(m_actConc), DATA_PTR(m_ropr));
m_revProductStoich.multiply(DATA_PTR(m_actConc), DATA_PTR(m_ropr));
// Fix up these calculations for cases where the above formalism doesn't hold
double OCV = 0.0;
@ -663,7 +663,7 @@ void InterfaceKinetics::getDeltaGibbs(doublereal* deltaG)
}
// Use the stoichiometric manager to find deltaG for each reaction.
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu), DATA_PTR(m_deltaG));
getReactionDelta(DATA_PTR(m_mu), DATA_PTR(m_deltaG));
if (deltaG != 0 && (DATA_PTR(m_deltaG) != deltaG)) {
for (size_t j = 0; j < m_ii; ++j) {
deltaG[j] = m_deltaG[j];
@ -684,7 +684,7 @@ void InterfaceKinetics::getDeltaElectrochemPotentials(doublereal* deltaM)
* Use the stoichiometric manager to find deltaG for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaM);
getReactionDelta(DATA_PTR(m_grt), deltaM);
}
void InterfaceKinetics::getDeltaEnthalpy(doublereal* deltaH)
@ -699,7 +699,7 @@ void InterfaceKinetics::getDeltaEnthalpy(doublereal* deltaH)
* Use the stoichiometric manager to find deltaG for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaH);
getReactionDelta(DATA_PTR(m_grt), deltaH);
}
void InterfaceKinetics::getDeltaEntropy(doublereal* deltaS)
@ -715,7 +715,7 @@ void InterfaceKinetics::getDeltaEntropy(doublereal* deltaS)
* Use the stoichiometric manager to find deltaS for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS);
getReactionDelta(DATA_PTR(m_grt), deltaS);
}
void InterfaceKinetics::getDeltaSSGibbs(doublereal* deltaGSS)
@ -733,7 +733,7 @@ void InterfaceKinetics::getDeltaSSGibbs(doublereal* deltaGSS)
* Use the stoichiometric manager to find deltaG for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_mu0), deltaGSS);
getReactionDelta(DATA_PTR(m_mu0), deltaGSS);
}
void InterfaceKinetics::getDeltaSSEnthalpy(doublereal* deltaH)
@ -755,7 +755,7 @@ void InterfaceKinetics::getDeltaSSEnthalpy(doublereal* deltaH)
* Use the stoichiometric manager to find deltaG for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaH);
getReactionDelta(DATA_PTR(m_grt), deltaH);
}
void InterfaceKinetics::getDeltaSSEntropy(doublereal* deltaS)
@ -776,7 +776,7 @@ void InterfaceKinetics::getDeltaSSEntropy(doublereal* deltaS)
* Use the stoichiometric manager to find deltaS for each
* reaction.
*/
m_rxnstoich.getReactionDelta(m_ii, DATA_PTR(m_grt), deltaS);
getReactionDelta(DATA_PTR(m_grt), deltaS);
}
void InterfaceKinetics::addReaction(ReactionData& r)

View file

@ -44,7 +44,9 @@ Kinetics& Kinetics::operator=(const Kinetics& right)
return *this;
}
m_rxnstoich = right.m_rxnstoich;
m_reactantStoich = right.m_reactantStoich;
m_revProductStoich = right.m_revProductStoich;
m_irrevProductStoich = right.m_irrevProductStoich;
m_ii = right.m_ii;
m_kk = right.m_kk;
m_perturb = right.m_perturb;
@ -269,24 +271,61 @@ void Kinetics::getNetRatesOfProgress(doublereal* netROP)
std::copy(m_ropnet.begin(), m_ropnet.end(), netROP);
}
void Kinetics::getReactionDelta(const double* prop, double* deltaProp)
{
fill(deltaProp, deltaProp + m_ii, 0.0);
// products add
m_revProductStoich.incrementReactions(prop, deltaProp);
m_irrevProductStoich.incrementReactions(prop, deltaProp);
// reactants subtract
m_reactantStoich.decrementReactions(prop, deltaProp);
}
void Kinetics::getRevReactionDelta(const double* prop, double* deltaProp)
{
fill(deltaProp, deltaProp + m_ii, 0.0);
// products add
m_revProductStoich.incrementReactions(prop, deltaProp);
// reactants subtract
m_reactantStoich.decrementReactions(prop, deltaProp);
}
void Kinetics::getCreationRates(double* cdot)
{
updateROP();
m_rxnstoich.getCreationRates(m_kk, &m_ropf[0], &m_ropr[0], cdot);
// zero out the output array
fill(cdot, cdot + m_kk, 0.0);
// the forward direction creates product species
m_revProductStoich.incrementSpecies(&m_ropf[0], cdot);
m_irrevProductStoich.incrementSpecies(&m_ropf[0], cdot);
// the reverse direction creates reactant species
m_reactantStoich.incrementSpecies(&m_ropr[0], cdot);
}
void Kinetics::getDestructionRates(doublereal* ddot)
{
updateROP();
m_rxnstoich.getDestructionRates(m_kk, &m_ropf[0], &m_ropr[0], ddot);
fill(ddot, ddot + m_kk, 0.0);
// the reverse direction destroys products in reversible reactions
m_revProductStoich.incrementSpecies(&m_ropr[0], ddot);
// the forward direction destroys reactants
m_reactantStoich.incrementSpecies(&m_ropf[0], ddot);
}
void Kinetics::getNetProductionRates(doublereal* net)
{
updateROP();
m_rxnstoich.getNetProductionRates(m_kk, &m_ropnet[0], net);
fill(net, net + m_kk, 0.0);
// products are created for positive net rate of progress
m_revProductStoich.incrementSpecies(&m_ropnet[0], net);
m_irrevProductStoich.incrementSpecies(&m_ropnet[0], net);
// reactants are destroyed for positive net rate of progress
m_reactantStoich.decrementSpecies(&m_ropnet[0], net);
}
void Kinetics::addPhase(thermo_t& thermo)
@ -340,10 +379,12 @@ void Kinetics::addReaction(ReactionData& r) {
// so the faster method 'multiply' can be used to compute the rate of
// progress instead of 'power'.
std::vector<size_t> rk;
bool fracReactants = false;
for (size_t n = 0; n < r.reactants.size(); n++) {
double nsFlt = r.rstoich[n];
size_t ns = (size_t) nsFlt;
if ((double) ns != nsFlt) {
fracReactants = true;
ns = std::max<size_t>(ns, 1);
}
if (r.rstoich[n] != 0.0) {
@ -356,10 +397,12 @@ void Kinetics::addReaction(ReactionData& r) {
m_reactants.push_back(rk);
std::vector<size_t> pk;
bool fracProducts = false;
for (size_t n = 0; n < r.products.size(); n++) {
double nsFlt = r.pstoich[n];
size_t ns = (size_t) nsFlt;
if ((double) ns != nsFlt) {
fracProducts = true;
ns = std::max<size_t>(ns, 1);
}
if (r.pstoich[n] != 0.0) {
@ -370,7 +413,81 @@ void Kinetics::addReaction(ReactionData& r) {
}
}
m_products.push_back(pk);
m_rxnstoich.add(nReactions(), r);
size_t irxn = nReactions();
bool doGlobal = false;
std::vector<size_t> extReactants = r.reactants;
vector_fp extRStoich = r.rstoich;
vector_fp extROrder = r.rorder;
// If we have a complete global reaction then we need to do something more
// complete than the previous treatment. Basically we will use the reactant
// manager to calculate the global forward reaction rate of progress.
if (r.forwardFullOrder_.size() > 0) {
// Trigger a treatment where the order of the reaction and the
// stoichiometry are treated as different.
doGlobal = true;
size_t nsp = r.forwardFullOrder_.size();
// Set up a signal vector to indicate whether the species has been added
// into the input vectors for the stoich manager
vector_int kHandled(nsp, 0);
// Loop over the reactants which are also nonzero stoichioemtric entries
// making sure the forwardFullOrder_ entries take precedence over rorder
// entries
for (size_t kk = 0; kk < r.reactants.size(); kk++) {
size_t k = r.reactants[kk];
double oo = r.rorder[kk];
double of = r.forwardFullOrder_[k];
if (of != oo) {
extROrder[kk] = of;
}
kHandled[k] = 1;
}
for (size_t k = 0; k < nsp; k++) {
double of = r.forwardFullOrder_[k];
if (of != 0.0) {
if (kHandled[k] == 0) {
// Add extra entries to reactant inputs. Set their reactant
// stoichiometric entries to zero.
extReactants.push_back(k);
extROrder.push_back(of);
extRStoich.push_back(0.0);
}
}
}
}
// If the reaction is non-mass action add it in in a general way
// Reactants get extra terms for the forward reaction rate of progress
// that may have zero stoichiometries.
if (doGlobal) {
m_reactantStoich.add(irxn, extReactants, extROrder, extRStoich);
} else {
// this is confusing. The only issue should be whether rorder is different than rstoich!
if (fracReactants || r.global || rk.size() > 3) {
m_reactantStoich.add(irxn, r.reactants, r.rorder, r.rstoich);
} else {
m_reactantStoich.add(irxn, rk);
}
}
if (r.reversible) {
// this is confusing. The only issue should be whether porder is different than pstoich!
if (pk.size() > 3 || r.isReversibleWithFrac) {
m_revProductStoich.add(irxn, r.products, r.porder, r.pstoich);
} else {
m_revProductStoich.add(irxn, pk);
}
} else {
// this is confusing. The only issue should be whether porder is different than pstoich!
if (fracProducts || pk.size() > 3) {
m_irrevProductStoich.add(irxn, r.products, r.porder, r.pstoich);
} else {
m_irrevProductStoich.add(irxn, pk);
}
}
installGroups(nReactions(), r.rgroups, r.pgroups);
incrementRxnCount();

View file

@ -18,6 +18,8 @@ namespace Cantera
{
ReactionStoichMgr::ReactionStoichMgr()
{
warn_deprecated("class ReactionStoichMgr",
"To be removed after Cantera 2.2.");
m_dummy.resize(10,1.0);
}