Added option to ignore third-body efficiencies for undeclared species
To enable this option, in the phase definition, add 'skip_undeclared_third_bodies' to the list passed as the 'options' argument.
This commit is contained in:
parent
df40d898b0
commit
754faa3b13
4 changed files with 75 additions and 44 deletions
|
|
@ -252,17 +252,20 @@ The options field is used to indicate how certain conditions should be handled
|
|||
when importing the phase definition. The options field may be assigned a string
|
||||
or a sequence of strings from the table below.
|
||||
|
||||
============================== ================
|
||||
Option String Meaning
|
||||
============================== ================
|
||||
``'no_validation'`` Turn off all validation. Use when the definition
|
||||
has been previously validated to speed up importing
|
||||
the definition into an application. Use with caution!
|
||||
``'skip_undeclared_elements'`` When importing species, skip any containing undeclared
|
||||
elements, rather than flagging them as an error.
|
||||
``'skip_undeclared_species'`` When importing reactions, skip any containing undeclared
|
||||
species, rather than flagging them as an error.
|
||||
============================== ================
|
||||
================================== ================
|
||||
Option String Meaning
|
||||
================================== ================
|
||||
``'no_validation'`` Turn off all validation. Use when the definition
|
||||
has been previously validated to speed up importing
|
||||
the definition into an application. Use with caution!
|
||||
``'skip_undeclared_elements'`` When importing species, skip any containing undeclared
|
||||
elements, rather than flagging them as an error.
|
||||
``'skip_undeclared_species'`` When importing reactions, skip any containing undeclared
|
||||
species, rather than flagging them as an error.
|
||||
``'skip_undeclared_third_bodies'`` When importing reactions with third body efficiencies,
|
||||
ignore any efficiencies for undeclared species, rather
|
||||
than flagging them as an error.
|
||||
================================== ================
|
||||
|
||||
Using the ``options`` field, it is possible to extract a sub-mechanism from a large
|
||||
reaction mechanism, as follows::
|
||||
|
|
|
|||
|
|
@ -27,6 +27,14 @@ class Kinetics;
|
|||
class SpeciesThermoFactory;
|
||||
class XML_Node;
|
||||
|
||||
//! Rules for parsing and installing reactions
|
||||
struct ReactionRules
|
||||
{
|
||||
ReactionRules();
|
||||
bool skipUndeclaredSpecies;
|
||||
bool skipUndeclaredThirdBodies;
|
||||
bool allowNegativeA;
|
||||
};
|
||||
|
||||
//!This function returns a ratio if two reactions are duplicates of
|
||||
//!one another, and 0.0 otherwise.
|
||||
|
|
@ -85,17 +93,15 @@ void checkRxnElementBalance(Kinetics& kin,
|
|||
* Length is number of reactants or products.
|
||||
* stoich = stoichiometric coefficient of the reactant or product
|
||||
* Length is number of reactants or products.
|
||||
* order = Order of the reactant and product in the reaction
|
||||
* rate expression
|
||||
* @param rule If we fail to find a species, we will throw an error
|
||||
* if rule != 1. If rule = 1, we simply return false,
|
||||
* allowing the calling routine to skip this reaction
|
||||
* and continue.
|
||||
* order = Order of the reactant and product in the reaction rate expression
|
||||
* @param rules If rules.skipUndeclaredSpecies is set and we fail to find a
|
||||
* species we simply return false, allowing the calling routine to skip
|
||||
* this reaction and continue. Otherwise, we will throw an error.
|
||||
*/
|
||||
bool getReagents(const XML_Node& rxn, Kinetics& kin, int rp,
|
||||
std::string default_phase,
|
||||
std::vector<size_t>& spnum, vector_fp& stoich,
|
||||
vector_fp& order, int rule);
|
||||
vector_fp& order, const ReactionRules& rule);
|
||||
|
||||
//! Read the rate coefficient data from the XML file.
|
||||
/*!
|
||||
|
|
@ -113,8 +119,8 @@ bool getReagents(const XML_Node& rxn, Kinetics& kin, int rp,
|
|||
*
|
||||
* @ingroup kineticsmgr
|
||||
*/
|
||||
void getRateCoefficient(const XML_Node& kf, Kinetics& kin,
|
||||
ReactionData& rdata, int negA);
|
||||
void getRateCoefficient(const XML_Node& kf, Kinetics& kin, ReactionData& rdata,
|
||||
const ReactionRules& rules);
|
||||
|
||||
|
||||
//! Create a new ThermoPhase object and initializes it according to the XML tree database.
|
||||
|
|
|
|||
|
|
@ -1621,10 +1621,16 @@ class phase:
|
|||
datasrc = r[0]
|
||||
ra = p.addChild('reactionArray')
|
||||
ra['datasrc'] = datasrc+'#reaction_data'
|
||||
rk = None
|
||||
if 'skip_undeclared_species' in self._options:
|
||||
rk = ra.addChild('skip')
|
||||
rk['species'] = 'undeclared'
|
||||
|
||||
if 'skip_undeclared_third_bodies' in self._options:
|
||||
if not rk:
|
||||
rk = ra.addChild('skip')
|
||||
rk['third_bodies'] = 'undeclared'
|
||||
|
||||
rtoks = r[1].split()
|
||||
if rtoks[0] != 'all':
|
||||
i = ra.addChild('include')
|
||||
|
|
|
|||
|
|
@ -40,6 +40,13 @@ using namespace std;
|
|||
namespace Cantera
|
||||
{
|
||||
|
||||
ReactionRules::ReactionRules() :
|
||||
skipUndeclaredSpecies(false),
|
||||
skipUndeclaredThirdBodies(false),
|
||||
allowNegativeA(false)
|
||||
{
|
||||
}
|
||||
|
||||
//! these are all used to check for duplicate reactions
|
||||
class rxninfo
|
||||
{
|
||||
|
|
@ -67,7 +74,7 @@ public:
|
|||
std::map<std::vector<char>, std::vector<size_t> > m_participants;
|
||||
|
||||
bool installReaction(int i, const XML_Node& r, Kinetics& kin,
|
||||
std::string default_phase, int rule,
|
||||
std::string default_phase, ReactionRules& rule,
|
||||
bool validate_rxn) ;
|
||||
};
|
||||
|
||||
|
|
@ -162,14 +169,15 @@ void checkRxnElementBalance(Kinetics& kin,
|
|||
* Length is number of reactants or products.
|
||||
* order = Order of the reactant and product in the reaction
|
||||
* rate expression
|
||||
* rule = If we fail to find a species, we will throw an error
|
||||
* rules = If we fail to find a species, we will throw an error
|
||||
* if rule != 1. If rule = 1, we simply return false,
|
||||
* allowing the calling routine to skip this reaction
|
||||
* and continue.
|
||||
*/
|
||||
bool getReagents(const XML_Node& rxn, Kinetics& kin, int rp,
|
||||
std::string default_phase, std::vector<size_t>& spnum,
|
||||
vector_fp& stoich, vector_fp& order, int rule)
|
||||
vector_fp& stoich, vector_fp& order,
|
||||
const ReactionRules& rules)
|
||||
{
|
||||
|
||||
string rptype;
|
||||
|
|
@ -211,7 +219,7 @@ bool getReagents(const XML_Node& rxn, Kinetics& kin, int rp,
|
|||
*/
|
||||
size_t isp = kin.kineticsSpeciesIndex(sp);
|
||||
if (isp == npos) {
|
||||
if (rule == 1) {
|
||||
if (rules.skipUndeclaredSpecies) {
|
||||
return false;
|
||||
} else {
|
||||
throw CanteraError("getReagents",
|
||||
|
|
@ -464,7 +472,8 @@ static void getFalloff(const XML_Node& f, ReactionData& rdata)
|
|||
* reaction mechanism is homogeneous, so that all species belong
|
||||
* to phase(0) of 'kin'.
|
||||
*/
|
||||
static void getEfficiencies(const XML_Node& eff, Kinetics& kin, ReactionData& rdata)
|
||||
static void getEfficiencies(const XML_Node& eff, Kinetics& kin,
|
||||
ReactionData& rdata, const ReactionRules& rules)
|
||||
{
|
||||
// set the default collision efficiency
|
||||
rdata.default_3b_eff = fpValue(eff["default"]);
|
||||
|
|
@ -476,12 +485,13 @@ static void getEfficiencies(const XML_Node& eff, Kinetics& kin, ReactionData& rd
|
|||
for (size_t n = 0; n < key.size(); n++) { // ; bb != ee; ++bb) {
|
||||
nm = key[n];// bb->first;
|
||||
size_t k = kin.kineticsSpeciesIndex(nm, phse);
|
||||
if (k == npos) {
|
||||
if (k != npos) {
|
||||
rdata.thirdBodyEfficiencies[k] = fpValue(val[n]); // bb->second;
|
||||
} else if (!rules.skipUndeclaredThirdBodies) {
|
||||
throw CanteraError("getEfficiencies", "Encountered third-body "
|
||||
"efficiency for undefined species \"" + nm + "\"\n"
|
||||
"while adding reaction " + int2str(rdata.number+1) + ".");
|
||||
}
|
||||
rdata.thirdBodyEfficiencies[k] = fpValue(val[n]); // bb->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -494,7 +504,7 @@ static void getEfficiencies(const XML_Node& eff, Kinetics& kin, ReactionData& rd
|
|||
* @param kf Reference to the XML Node named rateCoeff
|
||||
*/
|
||||
void getRateCoefficient(const XML_Node& kf, Kinetics& kin,
|
||||
ReactionData& rdata, int negA)
|
||||
ReactionData& rdata, const ReactionRules& rules)
|
||||
{
|
||||
if (rdata.reactionType == PLOG_RXN) {
|
||||
rdata.rateCoeffType = PLOG_REACTION_RATECOEFF_TYPE;
|
||||
|
|
@ -560,7 +570,7 @@ void getRateCoefficient(const XML_Node& kf, Kinetics& kin,
|
|||
kin.thermo(kin.surfacePhaseIndex()), rdata);
|
||||
}
|
||||
|
||||
if (coeff[0] <= 0.0 && negA == 0) {
|
||||
if (coeff[0] <= 0.0 && !rules.allowNegativeA) {
|
||||
throw CanteraError("getRateCoefficient",
|
||||
"negative or zero A coefficient for reaction "+int2str(rdata.number));
|
||||
}
|
||||
|
|
@ -572,7 +582,7 @@ void getRateCoefficient(const XML_Node& kf, Kinetics& kin,
|
|||
} else if (nm == "falloff") {
|
||||
getFalloff(c, rdata);
|
||||
} else if (nm == "efficiencies") {
|
||||
getEfficiencies(c, kin, rdata);
|
||||
getEfficiencies(c, kin, rdata, rules);
|
||||
} else if (nm == "electrochem") {
|
||||
rdata.beta = fpValue(c["beta"]);
|
||||
}
|
||||
|
|
@ -666,7 +676,7 @@ next:
|
|||
* @ingroup kineticsmgr
|
||||
*/
|
||||
bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin,
|
||||
string default_phase, int rule,
|
||||
string default_phase, ReactionRules& rules,
|
||||
bool validate_rxn)
|
||||
{
|
||||
// Check to see that we are in fact at a reaction node
|
||||
|
|
@ -687,7 +697,7 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin,
|
|||
|
||||
// Check to see if the reaction rate constant can be negative. It's an
|
||||
// error if a negative rate constant is found and this is not set.
|
||||
int negA = (r.hasAttrib("negative_A")) ? 1 : 0;
|
||||
rules.allowNegativeA = (r.hasAttrib("negative_A")) ? 1 : 0;
|
||||
|
||||
// Use the contents of the "equation" child element as the reaction's
|
||||
// string representation. Post-process to convert "[" and "]" characters
|
||||
|
|
@ -705,11 +715,11 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin,
|
|||
|
||||
// get the reactants
|
||||
bool ok = getReagents(r, kin, 1, default_phase, rdata.reactants,
|
||||
rdata.rstoich, rdata.rorder, rule);
|
||||
rdata.rstoich, rdata.rorder, rules);
|
||||
|
||||
// Get the products. We store the id of products in rdata.products
|
||||
ok = ok && getReagents(r, kin, -1, default_phase, rdata.products,
|
||||
rdata.pstoich, rdata.porder, rule);
|
||||
rdata.pstoich, rdata.porder, rules);
|
||||
|
||||
// if there was a problem getting either the reactants or the products,
|
||||
// then abort.
|
||||
|
|
@ -845,7 +855,7 @@ bool rxninfo::installReaction(int iRxn, const XML_Node& r, Kinetics& kin,
|
|||
|
||||
// Read the rate coefficient data from the XML file. Trigger an
|
||||
// exception for negative A unless specifically authorized.
|
||||
getRateCoefficient(r.child("rateCoeff"), kin, rdata, negA);
|
||||
getRateCoefficient(r.child("rateCoeff"), kin, rdata, rules);
|
||||
|
||||
// Check to see that the elements balance in the reaction.
|
||||
// Throw an error if they don't
|
||||
|
|
@ -909,20 +919,26 @@ bool installReactionArrays(const XML_Node& p, Kinetics& kin,
|
|||
*/
|
||||
const XML_Node* rdata = get_XML_Node(rxns["datasrc"], &rxns.root());
|
||||
/*
|
||||
* If the reactionArray element has a child element named
|
||||
* "skip", and if the attribute of skip called "species" has
|
||||
* a value of "undeclared", we will set rxnrule = 1.
|
||||
* rxnrule is passed to the routine that parses each individual
|
||||
* reaction. I believe what this means is that the parser will
|
||||
* skip all reactions containing an undefined species without
|
||||
* throwing an error condition.
|
||||
* If the reactionArray element has a child element named "skip", and
|
||||
* if the attribute of skip called "species" has a value of "undeclared",
|
||||
* we will set rxnrule.skipUndeclaredSpecies to 'true'. rxnrule is
|
||||
* passed to the routine that parses each individual reaction so that
|
||||
* the parser will skip all reactions containing an undefined species
|
||||
* without throwing an error.
|
||||
*
|
||||
* Similarly, an attribute named "third_bodies" with the value of
|
||||
* "undeclared" will skip undeclared third body efficiencies (while
|
||||
* retaining the reaction and any other efficiencies).
|
||||
*/
|
||||
int rxnrule = 0;
|
||||
ReactionRules rxnrule;
|
||||
if (rxns.hasChild("skip")) {
|
||||
const XML_Node& sk = rxns.child("skip");
|
||||
string sskip = sk["species"];
|
||||
if (sskip == "undeclared") {
|
||||
rxnrule = 1;
|
||||
rxnrule.skipUndeclaredSpecies = true;
|
||||
}
|
||||
if (sk["third_bodies"] == "undeclared") {
|
||||
rxnrule.skipUndeclaredThirdBodies = true;
|
||||
}
|
||||
}
|
||||
int i, nrxns = 0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue