cantera/src/kinetics/ReactionStoichMgr.cpp
Harry Moffat 25ba149aab Sorry for monolithic commit. Will break it up in the future.
Moved the external libraries to separate library files so that libcantera.a just contains its own namespace externals.

Fixed several errors in the equilibrium program that occurred during the port. (int to size_t issues).

Moved some equilibrium program headers to the include file system, so that it can link with equilibrium program.

Worked on Cantera.mak. Needs more work.

Fixed an issue with the Residual virtual base classes within numerics. They didn't inherit due to int to size_t migration. This caused numerous test problems to fail (issue with backwards compatibility - do we want it and how much do we want?).

Added csvdiff back so that it's available for shell environment runtests.
2012-04-05 00:24:31 +00:00

290 lines
8.8 KiB
C++

//------------------------------------------------
///
/// @file ReactionStoichMgr.cpp
///
///
//------------------------------------------------
#include "cantera/kinetics/ReactionStoichMgr.h"
#include "cantera/kinetics/StoichManager.h"
#include "cantera/base/ctexceptions.h"
#include "cantera/kinetics/ReactionData.h"
#include <fstream>
using namespace std;
namespace Cantera
{
//====================================================================================================================
// create stoichiometry managers for the reactants of all reactions,
// for the products of the reversible reactions, and for the
// products of the irreversible reactions.
ReactionStoichMgr::ReactionStoichMgr()
{
m_dummy.resize(10,1.0);
}
//====================================================================================================================
ReactionStoichMgr::~ReactionStoichMgr()
{
}
//====================================================================================================================
ReactionStoichMgr::ReactionStoichMgr(const ReactionStoichMgr& right) :
m_reactants(right.m_reactants),
m_revproducts(right.m_revproducts),
m_irrevproducts(right.m_irrevproducts),
m_dummy(right.m_dummy)
{
}
//====================================================================================================================
ReactionStoichMgr& ReactionStoichMgr::operator=(const ReactionStoichMgr& right)
{
if (this != &right) {
m_reactants = right.m_reactants;
m_revproducts = right.m_revproducts;
m_irrevproducts = right.m_irrevproducts;
m_dummy = right.m_dummy;
}
return *this;
}
//====================================================================================================================
void ReactionStoichMgr::
add(size_t rxn, const std::vector<size_t>& reactants,
const std::vector<size_t>& products,
bool reversible)
{
m_reactants.add(rxn, reactants);
if (reversible) {
m_revproducts.add(rxn, products);
} else {
m_irrevproducts.add(rxn, products);
}
}
void ReactionStoichMgr::
add(size_t rxn, const ReactionData& r)
{
std::vector<size_t> rk;
doublereal frac;
bool isfrac = false;
for (size_t n = 0; n < r.reactants.size(); n++) {
size_t ns = size_t(r.rstoich[n]);
frac = r.rstoich[n] - 1.0*int(r.rstoich[n]);
if (frac != 0.0) {
isfrac = true;
}
for (size_t m = 0; m < ns; m++) {
rk.push_back(r.reactants[n]);
}
}
// if the reaction has fractional stoichiometric coefficients
// or specified reaction orders, then add it in a general reaction
if (isfrac || r.global || rk.size() > 3) {
m_reactants.add(rxn, r.reactants, r.rorder, r.rstoich);
} else {
m_reactants.add(rxn, rk);
}
std::vector<size_t> pk;
isfrac = false;
for (size_t n = 0; n < r.products.size(); n++) {
size_t ns = size_t(r.pstoich[n]);
frac = r.pstoich[n] - 1.0*int(r.pstoich[n]);
if (frac != 0.0) {
isfrac = true;
}
for (size_t m = 0; m < ns; m++) {
pk.push_back(r.products[n]);
}
}
if (r.reversible) {
if (isfrac && !r.isReversibleWithFrac) {
throw CanteraError("ReactionStoichMgr::add",
"Fractional product stoichiometric coefficients only allowed "
"\nfor irreversible reactions and most reversible reactions");
}
if (pk.size() > 3 || r.isReversibleWithFrac) {
m_revproducts.add(rxn, r.products, r.porder, r.pstoich);
} else {
m_revproducts.add(rxn, pk);
}
} else if (isfrac || pk.size() > 3) {
m_irrevproducts.add(rxn, r.products, r.porder, r.pstoich);
} else {
m_irrevproducts.add(rxn, pk);
}
}
void ReactionStoichMgr::
getCreationRates(size_t nsp, const doublereal* ropf,
const doublereal* ropr, doublereal* c)
{
// zero out the output array
fill(c, c + nsp, 0.0);
// the forward direction creates product species
m_revproducts.incrementSpecies(ropf, c);
m_irrevproducts.incrementSpecies(ropf, c);
// the reverse direction creates reactant species
m_reactants.incrementSpecies(ropr, c);
}
void ReactionStoichMgr::
getDestructionRates(size_t nsp, const doublereal* ropf,
const doublereal* ropr, doublereal* d)
{
fill(d, d + nsp, 0.0);
// the reverse direction destroys products in reversible reactions
m_revproducts.incrementSpecies(ropr, d);
// the forward direction destroys reactants
m_reactants.incrementSpecies(ropf, d);
}
void ReactionStoichMgr::
getNetProductionRates(size_t nsp, const doublereal* ropnet, doublereal* w)
{
fill(w, w + nsp, 0.0);
// products are created for positive net rate of progress
m_revproducts.incrementSpecies(ropnet, w);
m_irrevproducts.incrementSpecies(ropnet, w);
// reactants are destroyed for positive net rate of progress
m_reactants.decrementSpecies(ropnet, w);
}
void ReactionStoichMgr::
getReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
{
fill(dg, dg + nr, 0.0);
// products add
m_revproducts.incrementReactions(g, dg);
m_irrevproducts.incrementReactions(g, dg);
// reactants subtract
m_reactants.decrementReactions(g, dg);
}
void ReactionStoichMgr::
getRevReactionDelta(size_t nr, const doublereal* g, doublereal* dg)
{
fill(dg, dg + nr, 0.0);
m_revproducts.incrementReactions(g, dg);
m_reactants.decrementReactions(g, dg);
}
void ReactionStoichMgr::
multiplyReactants(const doublereal* c, doublereal* r)
{
m_reactants.multiply(c, r);
}
void ReactionStoichMgr::
multiplyRevProducts(const doublereal* c, doublereal* r)
{
m_revproducts.multiply(c, r);
}
void ReactionStoichMgr::
write(string filename)
{
ofstream f(filename.c_str());
f << "namespace mech {" << endl;
writeCreationRates(f);
writeDestructionRates(f);
writeNetProductionRates(f);
writeMultiplyReactants(f);
writeMultiplyRevProducts(f);
f << "} // namespace mech" << endl;
f.close();
}
void ReactionStoichMgr::
writeCreationRates(ostream& f)
{
f << " void getCreationRates(const doublereal* rf, const doublereal* rb," << endl;
f << " doublereal* c) {" << endl;
map<size_t, string> out;
m_revproducts.writeIncrementSpecies("rf",out);
m_irrevproducts.writeIncrementSpecies("rf",out);
m_reactants.writeIncrementSpecies("rb",out);
map<size_t, string>::iterator b;
for (b = out.begin(); b != out.end(); ++b) {
string rhs = wrapString(b->second);
rhs[1] = '=';
f << " c[" << b->first << "] " << rhs << ";" << endl;
}
f << " }" << endl << endl << endl;
}
void ReactionStoichMgr::
writeDestructionRates(ostream& f)
{
f << " void getDestructionRates(const doublereal* rf, const doublereal* rb," << endl;
f << " doublereal* d) {" << endl;
map<size_t, string> out;
m_revproducts.writeIncrementSpecies("rb",out);
m_reactants.writeIncrementSpecies("rf",out);
map<size_t, string>::iterator b;
for (b = out.begin(); b != out.end(); ++b) {
string rhs = wrapString(b->second);
rhs[1] = '=';
f << " d[" << b->first << "] " << rhs << ";" << endl;
}
f << " }" << endl << endl << endl;
}
void ReactionStoichMgr::
writeNetProductionRates(ostream& f)
{
f << " void getNetProductionRates(const doublereal* r, doublereal* w) {" << endl;
map<size_t, string> out;
m_revproducts.writeIncrementSpecies("r",out);
m_irrevproducts.writeIncrementSpecies("r",out);
m_reactants.writeDecrementSpecies("r",out);
map<size_t, string>::iterator b;
for (b = out.begin(); b != out.end(); ++b) {
string rhs = wrapString(b->second);
rhs[1] = '=';
f << " w[" << b->first << "] " << rhs << ";" << endl;
}
f << " }" << endl << endl << endl;
}
void ReactionStoichMgr::
writeMultiplyReactants(ostream& f)
{
f << " void multiplyReactants(const doublereal* c, doublereal* r) {" << endl;
map<size_t, string> out;
m_reactants.writeMultiply("c",out);
map<size_t, string>::iterator b;
for (b = out.begin(); b != out.end(); ++b) {
string rhs = b->second;
f << " r[" << b->first << "] *= " << rhs << ";" << endl;
}
f << " }" << endl << endl << endl;
}
void ReactionStoichMgr::
writeMultiplyRevProducts(ostream& f)
{
f << " void multiplyRevProducts(const doublereal* c, doublereal* r) {" << endl;
map<size_t, string> out;
m_revproducts.writeMultiply("c",out);
map<size_t, string>::iterator b;
for (b = out.begin(); b != out.end(); ++b) {
string rhs = b->second;
f << " r[" << b->first << "] *= " << rhs << ";" << endl;
}
f << " }" << endl << endl << endl;
}
}