cantera/src/kinetics/AqueousKinetics.cpp

185 lines
4.8 KiB
C++

/**
* @file AqueousKinetics.cpp
*
* Homogeneous kinetics in an aqueous phase, either condensed
* or dilute in salts
*/
/*
* Copyright (2006) Sandia Corporation. Under the terms of
* Contract DE-AC04-94AL85000 with Sandia Corporation, the
* U.S. Government retains certain rights in this software.
*/
#include "cantera/kinetics/AqueousKinetics.h"
#include "cantera/kinetics/Reaction.h"
#include "cantera/base/vec_functions.h"
using namespace std;
namespace Cantera
{
AqueousKinetics::AqueousKinetics(thermo_t* thermo) :
BulkKinetics(thermo)
{
}
Kinetics* AqueousKinetics::duplMyselfAsKinetics(const std::vector<thermo_t*> & tpVector) const
{
AqueousKinetics* gK = new AqueousKinetics(*this);
gK->assignShallowPointers(tpVector);
return gK;
}
void AqueousKinetics::_update_rates_T()
{
doublereal T = thermo().temperature();
m_rates.update(T, log(T), &m_rfn[0]);
m_temp = T;
updateKc();
m_ROP_ok = false;
}
void AqueousKinetics::_update_rates_C()
{
thermo().getActivityConcentrations(&m_conc[0]);
m_ROP_ok = false;
}
void AqueousKinetics::updateKc()
{
doublereal rt = GasConstant * m_temp;
thermo().getStandardChemPotentials(&m_grt[0]);
fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
for (size_t k = 0; k < thermo().nSpecies(); k++) {
doublereal logStandConc_k = thermo().logStandardConc(k);
m_grt[k] -= rt * logStandConc_k;
}
// compute Delta G^0 for all reversible reactions
getRevReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_revindex.size(); i++) {
size_t irxn = m_revindex[i];
m_rkcn[irxn] = exp(m_rkcn[irxn]*rrt);
}
for (size_t i = 0; i != m_irrev.size(); ++i) {
m_rkcn[ m_irrev[i] ] = 0.0;
}
}
void AqueousKinetics::getEquilibriumConstants(doublereal* kc)
{
_update_rates_T();
thermo().getStandardChemPotentials(&m_grt[0]);
fill(m_rkcn.begin(), m_rkcn.end(), 0.0);
doublereal rt = GasConstant * m_temp;
for (size_t k = 0; k < thermo().nSpecies(); k++) {
doublereal logStandConc_k = thermo().logStandardConc(k);
m_grt[k] -= rt * logStandConc_k;
}
// compute Delta G^0 for all reactions
getReactionDelta(&m_grt[0], &m_rkcn[0]);
doublereal rrt = 1.0/(GasConstant * thermo().temperature());
for (size_t i = 0; i < m_ii; i++) {
kc[i] = exp(-m_rkcn[i]*rrt);
}
// force an update of T-dependent properties, so that m_rkcn will
// be updated before it is used next.
m_temp = 0.0;
}
void AqueousKinetics::updateROP()
{
_update_rates_T();
_update_rates_C();
if (m_ROP_ok) {
return;
}
// copy rate coefficients into ropf
copy(m_rfn.begin(), m_rfn.end(), m_ropf.begin());
// multiply by perturbation factor
multiply_each(m_ropf.begin(), m_ropf.end(), m_perturb.begin());
// copy the forward rates to the reverse rates
copy(m_ropf.begin(), m_ropf.end(), m_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(m_ropr.begin(), m_ropr.end(), m_rkcn.begin());
// multiply ropf by concentration products
m_reactantStoich.multiply(&m_conc[0], &m_ropf[0]);
// for reversible reactions, multiply ropr by concentration products
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];
}
m_ROP_ok = true;
}
void AqueousKinetics::getFwdRateConstants(doublereal* kfwd)
{
_update_rates_T();
_update_rates_C();
// copy rate coefficients into ropf
copy(m_rfn.begin(), m_rfn.end(), m_ropf.begin());
// multiply by perturbation factor
multiply_each(m_ropf.begin(), m_ropf.end(), m_perturb.begin());
for (size_t i = 0; i < m_ii; i++) {
kfwd[i] = m_ropf[i];
}
}
void AqueousKinetics::addReaction(ReactionData& r)
{
if (r.reactionType == ELEMENTARY_RXN) {
addElementaryReaction(r);
}
BulkKinetics::addReaction(r);
}
bool AqueousKinetics::addReaction(shared_ptr<Reaction> r)
{
bool added = BulkKinetics::addReaction(r);
if (!added) {
return false;
}
if (r->reaction_type == ELEMENTARY_RXN) {
addElementaryReaction(dynamic_cast<ElementaryReaction&>(*r));
} else {
throw CanteraError("AqueousKinetics::addReaction",
"Invalid reaction type: " + int2str(r->reaction_type));
}
return true;
}
void AqueousKinetics::modifyReaction(size_t i, shared_ptr<Reaction> rNew)
{
BulkKinetics::modifyReaction(i, rNew);
modifyElementaryReaction(i, dynamic_cast<ElementaryReaction&>(*rNew));
// invalidate all cached data
m_ROP_ok = false;
m_temp += 0.1234;
}
}