mirror of
https://github.com/Cantera/cantera.git
synced 2025-02-25 18:55:29 -06:00
[Input] Allow mapping for Arrhenius parameters, and use this as the default
Pressure-dependent Arrhenius reactions now use a list of mappings instead of a more complicated nested list structure.
This commit is contained in:
@@ -94,6 +94,7 @@ public:
|
||||
template<class T>
|
||||
std::vector<T>& asVector(size_t nMin=npos, size_t nMax=npos);
|
||||
|
||||
explicit AnyValue(const AnyMap& value);
|
||||
AnyValue& operator=(const AnyMap& value);
|
||||
AnyValue& operator=(AnyMap&& value);
|
||||
|
||||
@@ -262,6 +263,7 @@ public:
|
||||
//! units. If the input is a string, treat this as a dimensioned value, e.g.
|
||||
//! '988 kg/m^3' and convert from the specified units.
|
||||
double convert(const std::string& key, const std::string& units) const;
|
||||
double convert(const std::string& key, const Units& units) const;
|
||||
|
||||
//! Convert the item stored by the given `key` to the units specified in
|
||||
//! `units`. If the stored value is a double, convert it using the default
|
||||
|
||||
@@ -321,18 +321,21 @@ class Arrhenius:
|
||||
self.Ea = Ea
|
||||
self.parser = parser
|
||||
|
||||
def as_yaml(self):
|
||||
def as_yaml(self, extra=()):
|
||||
out = FlowMap(extra)
|
||||
if compatible_quantities(self.parser.output_quantity_units, self.A[1]):
|
||||
A = self.A[0]
|
||||
out['A'] = self.A[0]
|
||||
else:
|
||||
A = "{0:e} {1}".format(*self.A)
|
||||
out['A'] = "{0:e} {1}".format(*self.A)
|
||||
|
||||
out['b'] = self.b
|
||||
|
||||
if self.Ea[1] == self.parser.output_energy_units:
|
||||
Ea = self.Ea[0]
|
||||
out['Ea'] = self.Ea[0]
|
||||
else:
|
||||
Ea = "{0} {1}".format(*self.Ea)
|
||||
out['Ea'] = "{0} {1}".format(*self.Ea)
|
||||
|
||||
return FlowList([A, self.b, Ea])
|
||||
return out
|
||||
|
||||
|
||||
class ElementaryRate(KineticsModel):
|
||||
@@ -426,8 +429,8 @@ class PDepArrhenius(KineticsModel):
|
||||
output['type'] = 'pressure-dependent-Arrhenius'
|
||||
rates = []
|
||||
for pressure, arrhenius in zip(self.pressures, self.arrhenius):
|
||||
rates.append(FlowList(('{0} {1}'.format(pressure, self.pressure_units),
|
||||
arrhenius.as_yaml())))
|
||||
rates.append(arrhenius.as_yaml(
|
||||
[('P', '{0} {1}'.format(pressure, self.pressure_units))]))
|
||||
output['rate-constants'] = rates
|
||||
|
||||
|
||||
|
||||
@@ -224,6 +224,9 @@ struct convert<Cantera::AnyValue> {
|
||||
target = node.as<std::vector<AnyValue>>();
|
||||
}
|
||||
return true;
|
||||
} else if (node.IsMap()) {
|
||||
target = node.as<AnyMap>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -369,6 +372,8 @@ const long int& AnyValue::asInt() const {
|
||||
return as<long int>();
|
||||
}
|
||||
|
||||
AnyValue::AnyValue(const AnyMap& value) : m_value(new boost::any{value}) {}
|
||||
|
||||
AnyValue& AnyValue::operator=(const AnyMap& value) {
|
||||
*m_value = value;
|
||||
return *this;
|
||||
@@ -662,6 +667,11 @@ double AnyMap::convert(const std::string& key, const std::string& dest) const
|
||||
return units().convert(at(key), dest);
|
||||
}
|
||||
|
||||
double AnyMap::convert(const std::string& key, const Units& dest) const
|
||||
{
|
||||
return units().convert(at(key), dest);
|
||||
}
|
||||
|
||||
double AnyMap::convert(const std::string& key, const std::string& dest,
|
||||
double default_) const
|
||||
{
|
||||
|
||||
@@ -318,12 +318,19 @@ Arrhenius readArrhenius(const Reaction& R, const AnyValue& rate,
|
||||
const Kinetics& kin, const UnitSystem& units,
|
||||
int pressure_dependence=0)
|
||||
{
|
||||
|
||||
auto& rate_vec = rate.asVector<AnyValue>(3);
|
||||
double A, b, Ta;
|
||||
Units rc_units = rateCoeffUnits(R, kin, pressure_dependence);
|
||||
double A = units.convert(rate_vec[0], rc_units);
|
||||
double b = rate_vec[1].asDouble();
|
||||
double Ta = units.convertMolarEnergy(rate_vec[2], "K");
|
||||
if (rate.is<AnyMap>()) {
|
||||
auto& rate_map = rate.as<AnyMap>();
|
||||
A = units.convert(rate_map["A"], rc_units);
|
||||
b = rate_map["b"].asDouble();
|
||||
Ta = rate_map.convertMolarEnergy("Ea", "K");
|
||||
} else {
|
||||
auto& rate_vec = rate.asVector<AnyValue>(3);
|
||||
A = units.convert(rate_vec[0], rc_units);
|
||||
b = rate_vec[1].asDouble();
|
||||
Ta = units.convertMolarEnergy(rate_vec[2], "K");
|
||||
}
|
||||
return Arrhenius(A, b, Ta);
|
||||
}
|
||||
|
||||
@@ -679,10 +686,9 @@ void setupPlogReaction(PlogReaction& R, const AnyMap& node, const Kinetics& kin)
|
||||
{
|
||||
setupReaction(R, node);
|
||||
std::multimap<double, Arrhenius> rates;
|
||||
for (const auto& rate : node.at("rate-constants").asVector<AnyValue>()) {
|
||||
const auto& p_rate = rate.asVector<AnyValue>(2);
|
||||
rates.insert({node.units().convert(p_rate[0], "Pa"),
|
||||
readArrhenius(R, p_rate[1], kin, node.units())});
|
||||
for (const auto& rate : node.at("rate-constants").asVector<AnyMap>()) {
|
||||
rates.insert({rate.convert("P", "Pa"),
|
||||
readArrhenius(R, AnyValue(rate), kin, node.units())});
|
||||
}
|
||||
R.rate = Plog(rates);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ TEST(Reaction, FalloffFromYaml2)
|
||||
"{equation: H + CH2 (+ N2) <=> CH3 (+N2),"
|
||||
" type: falloff,"
|
||||
" high-P-rate-constant: [6.00000E+14 cm^3/mol/s, 0, 0],"
|
||||
" low-P-rate-constant: [1.04000E+26 cm^6/mol^2/s, -2.76, 1600],"
|
||||
" low-P-rate-constant: {A: 1.04000E+26 cm^6/mol^2/s, b: -2.76, Ea: 1600},"
|
||||
" Troe: {A: 0.562, T3: 91, T1: 5836}}");
|
||||
|
||||
auto R = newReaction(rxn, gas);
|
||||
@@ -90,6 +90,7 @@ TEST(Reaction, FalloffFromYaml2)
|
||||
EXPECT_DOUBLE_EQ(FR.third_body.efficiency("H2O"), 0.0);
|
||||
EXPECT_DOUBLE_EQ(FR.high_rate.preExponentialFactor(), 6e11);
|
||||
EXPECT_DOUBLE_EQ(FR.low_rate.preExponentialFactor(), 1.04e20);
|
||||
EXPECT_DOUBLE_EQ(FR.low_rate.activationEnergy_R(), 1600 / GasConstant);
|
||||
vector_fp params(4);
|
||||
FR.falloff->getParameters(params.data());
|
||||
EXPECT_DOUBLE_EQ(params[0], 0.562);
|
||||
@@ -122,10 +123,10 @@ TEST(Reaction, PlogFromYaml)
|
||||
"units: {pressure: atm}\n"
|
||||
"type: pressure-dependent-Arrhenius\n"
|
||||
"rate-constants:\n"
|
||||
"- [0.039474, [2.720000e+09 cm^3/mol/s, 1.2, 6834.0]]\n"
|
||||
"- [1.0 atm, [1.260000e+20, -1.83, 15003.0]]\n"
|
||||
"- [1.0 atm, [1.230000e+04, 2.68, 6335.0]]\n"
|
||||
"- [1.01325 MPa, [1.680000e+16, -0.6, 14754.0]]");
|
||||
"- {P: 0.039474, A: 2.720000e+09 cm^3/mol/s, b: 1.2, Ea: 6834.0}\n"
|
||||
"- {P: 1.0 atm, A: 1.260000e+20, b: -1.83, Ea: 15003.0}\n"
|
||||
"- {P: 1.0 atm, A: 1.230000e+04, b: 2.68, Ea: 6335.0}\n"
|
||||
"- {P: 1.01325 MPa, A: 1.680000e+16, b: -0.6, Ea: 14754.0}");
|
||||
|
||||
auto R = newReaction(rxn, gas);
|
||||
auto PR = dynamic_cast<PlogReaction&>(*R);
|
||||
@@ -136,6 +137,7 @@ TEST(Reaction, PlogFromYaml)
|
||||
EXPECT_NEAR(rates[3].first, 10 * OneAtm, 1e-6);
|
||||
EXPECT_DOUBLE_EQ(rates[0].second.preExponentialFactor(), 2.72e6);
|
||||
EXPECT_DOUBLE_EQ(rates[3].second.preExponentialFactor(), 1.68e16);
|
||||
EXPECT_DOUBLE_EQ(rates[3].second.temperatureExponent(), -0.6);
|
||||
}
|
||||
|
||||
TEST(Reaction, ChebyshevFromYaml)
|
||||
|
||||
Reference in New Issue
Block a user