diff --git a/include/cantera/base/AnyMap.h b/include/cantera/base/AnyMap.h index f1ce0756d..7cf5f84d4 100644 --- a/include/cantera/base/AnyMap.h +++ b/include/cantera/base/AnyMap.h @@ -291,21 +291,6 @@ public: vector_fp convertVector(const std::string& key, const std::string& units, size_t nMin=npos, size_t nMax=npos) 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 - //! units. If the input is a string, treat this as a dimensioned value, e.g. - //! '2.7e4 J/kmol' and convert from the specified units. - double convertMolarEnergy(const std::string& key, - const std::string& 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 - //! units. If the stored value is a string, treat it as a dimensioned value, - //! e.g. '2.7e4 J/kmol' and convert from the specified units. If the key is - //! missing, the `default_` value is returned. - double convertMolarEnergy(const std::string& key, const std::string& units, - double default_) const; - // Define begin() and end() to allow use with range-based for loops using const_iterator = std::unordered_map::const_iterator; const_iterator begin() const { diff --git a/include/cantera/base/Units.h b/include/cantera/base/Units.h index 59875161d..499ebf8d0 100644 --- a/include/cantera/base/Units.h +++ b/include/cantera/base/Units.h @@ -67,6 +67,7 @@ private: double m_current_dim; double m_quantity_dim; double m_pressure_dim; //!< pseudo-dimension to track explicit pressure units + double m_energy_dim; //!< pseudo-dimension to track explicit energy units friend class UnitSystem; }; @@ -90,9 +91,9 @@ private: * * Metric prefixes are recognized for all units, e.g. nm, hPa, mg, EJ, mL, kcal. * - * Special functions for converting molar energies (e.g. activation energies) - * allow these values to be expressed as either energy per quantity or - * temperature by applying a factor of the gas constant where needed. + * Special functions for converting activation energies allow these values to be + * expressed as either energy per quantity, energy (e.g. eV), or temperature by + * applying a factor of the Avogadro number or the gas constant where needed. * * @ingroup inputfiles */ @@ -103,12 +104,12 @@ public: UnitSystem(std::initializer_list units={}); //! Set the default units to convert from when explicit units are not - //! provided. Defaults can be set for mass, length, time, quantity, and - //! pressure. Conversion using the pressure unit is done only when the - //! target units explicitly contain pressure units. + //! provided. Defaults can be set for mass, length, time, quantity, energy, + //! and pressure. Conversion using the pressure or energy units is done only + //! when the target units explicitly contain pressure or energy units. //! - //! * To use SI+kmol: `setDefaults({"kg", "m", "s", "kmol"});` - //! * To use CGS+mol: `setDefaults({"cm", "g", "mol"});` + //! * To use SI+kmol: `setDefaults({"kg", "m", "s", "Pa", "J", "kmol"});` + //! * To use CGS+mol: `setDefaults({"cm", "g", "dyn/cm^2", "erg", "mol"});` void setDefaults(std::initializer_list units); //! Set the default units using a map of dimension to unit pairs. @@ -119,15 +120,16 @@ public: //! UnitSystem system; //! std::map defaults{ //! {"length", "m"}, {"mass", "kg"}, {"time", "s"}, - //! {"quantity", "kmol"}, {"pressure", "Pa"}, {"molar-energy", "J/kmol"} + //! {"quantity", "kmol"}, {"pressure", "Pa"}, {"energy", "J"}, + //! {"activation-energy", "J/kmol"} //! }; //! setDefaults(defaults); //! ``` void setDefaults(const std::map& units); - //! Set the default units to convert from when using the `convertMolarEnergy` - //! function. - void setDefaultMolarEnergy(const std::string& e_units); + //! Set the default units to convert from when using the + //! `convertActivationEnergy` function. + void setDefaultActivationEnergy(const std::string& e_units); //! Convert `value` from the units of `src` to the units of `dest`. double convert(double value, const std::string& src, @@ -155,20 +157,20 @@ public: const Units& dest) const; //! Convert `value` from the units of `src` to the units of `dest`, allowing - //! for the different dimensions that can be used for molar energies - double convertMolarEnergy(double value, const std::string& src, - const std::string& dest) const; + //! for the different dimensions that can be used for activation energies + double convertActivationEnergy(double value, const std::string& src, + const std::string& dest) const; - //! Convert `value` from the default molar energy units to the + //! Convert `value` from the default activation energy units to the //! specified units - double convertMolarEnergy(double value, const std::string& dest) const; + double convertActivationEnergy(double value, const std::string& dest) const; //! Convert a generic AnyValue node to the units specified in `dest`. If the //! input is a double, convert it using the default units. If the input is a //! string, treat this as a dimensioned value, e.g. '2.7e4 J/kmol' and //! convert from the specified units. - double convertMolarEnergy(const AnyValue& val, const std::string& dest) const; - + double convertActivationEnergy(const AnyValue& val, + const std::string& dest) const; private: //! Factor to convert mass from this unit system to kg @@ -183,11 +185,18 @@ private: //! Factor to convert pressure from this unit system to Pa double m_pressure_factor; - //! Factor to convert molar energy from this unit system to J/kmol - double m_molar_energy_factor; + //! Factor to convert energy from this unit system to J + double m_energy_factor; + + //! Factor to convert activation energy from this unit system to J/kmol + double m_activation_energy_factor; //! Factor to convert quantity from this unit system to kmol double m_quantity_factor; + + //! True if activation energy units are set explicitly, rather than as a + //! combination of energy and quantity units + bool m_explicit_activation_energy; }; } diff --git a/src/base/AnyMap.cpp b/src/base/AnyMap.cpp index 82f5545bb..859ca4953 100644 --- a/src/base/AnyMap.cpp +++ b/src/base/AnyMap.cpp @@ -674,23 +674,6 @@ vector_fp AnyMap::convertVector(const std::string& key, const std::string& dest, return units().convert(at(key).asVector(nMin, nMax), dest); } -double AnyMap::convertMolarEnergy(const std::string& key, - const std::string& dest) const -{ - return units().convertMolarEnergy(at(key), dest); -} - -double AnyMap::convertMolarEnergy(const std::string& key, - const std::string& dest, - double default_) const -{ - if (hasKey(key)) { - return units().convertMolarEnergy(at(key), dest); - } else { - return default_; - } -} - void AnyMap::applyUnits(const UnitSystem& units) { m_units = units; diff --git a/src/base/Units.cpp b/src/base/Units.cpp index 5fbcf6c5c..e22168fd9 100644 --- a/src/base/Units.cpp +++ b/src/base/Units.cpp @@ -52,10 +52,15 @@ const std::map knownUnits{ {"erg", Units(1e-7, 1, 2, -2)}, {"eV", Units(ElectronCharge, 1, 2, -2)}, + // Force [M*L/T^2] + {"N", Units(1.0, 1, 1, -2)}, + {"dyn", Units(1e-5, 1, 1, -2)}, + // Pressure [M/L/T^2] {"Pa", Units(1.0, 1, -1, -2)}, {"atm", Units(OneAtm, 1, -1, -2)}, {"bar", Units(1.0e5, 1, -1, -2)}, + {"dyn/cm^2", Units(0.1, 1, -1, -2)}, // Volume [L^3] {"m^3", Units(1.0, 0, 3, 0)}, @@ -69,7 +74,7 @@ const std::map knownUnits{ {"V", Units(1.0, 1, 2, -3, 0, -1)}, // kg*m^2/s^3/A {"coulomb", Units(1.0, 0, 0, 1, 0, 1)}, // A*s - //! Molar energy units [M*L^2/T^2/Q] + //! Activation energy units [M*L^2/T^2/Q] {"J/kmol", Units(1.0, 1, 2, -2, 0, 0, -1)}, }; @@ -109,11 +114,17 @@ Units::Units(double factor, double mass, double length, double time, , m_current_dim(current) , m_quantity_dim(quantity) , m_pressure_dim(0) + , m_energy_dim(0) { if (mass != 0 && length == -mass && time == -2 * mass && temperature == 0 && current == 0 && quantity == 0) { // Dimension looks like Pa^n m_pressure_dim = mass; + } else if (mass != 0 && length == 2 * mass && time == -2 * mass + && temperature == 0 && current == 0 && quantity == 0) + { + // Dimesion looks like J^n + m_energy_dim = mass; } } @@ -126,6 +137,7 @@ Units::Units(const std::string& name) , m_current_dim(0) , m_quantity_dim(0) , m_pressure_dim(0) + , m_energy_dim(0) { size_t start = 0; while (true) { @@ -193,6 +205,7 @@ Units& Units::operator*=(const Units& other) m_current_dim += other.m_current_dim; m_quantity_dim += other.m_quantity_dim; m_pressure_dim += other.m_pressure_dim; + m_energy_dim += other.m_energy_dim; return *this; } @@ -217,8 +230,10 @@ UnitSystem::UnitSystem(std::initializer_list units) , m_length_factor(1.0) , m_time_factor(1.0) , m_pressure_factor(1.0) - , m_molar_energy_factor(1.0) + , m_energy_factor(1.0) + , m_activation_energy_factor(1.0) , m_quantity_factor(1.0) + , m_explicit_activation_energy(false) { setDefaults(units); } @@ -237,6 +252,8 @@ void UnitSystem::setDefaults(std::initializer_list units) m_quantity_factor = unit.factor(); } else if (unit.convertible(knownUnits.at("Pa"))) { m_pressure_factor = unit.factor(); + } else if (unit.convertible(knownUnits.at("J"))) { + m_energy_factor = unit.factor(); } else if (unit.convertible(knownUnits.at("K")) || unit.convertible(knownUnits.at("A"))) { // Do nothing -- no other scales are supported for temperature and current @@ -245,6 +262,9 @@ void UnitSystem::setDefaults(std::initializer_list units) "Unable to match unit '{}' to a basic dimension", name); } } + if (!m_explicit_activation_energy) { + m_activation_energy_factor = m_energy_factor / m_quantity_factor; + } } void UnitSystem::setDefaults(const std::map& units) @@ -266,29 +286,37 @@ void UnitSystem::setDefaults(const std::map& units) m_quantity_factor = unit.factor(); } else if (name == "pressure" && unit.convertible(knownUnits.at("Pa"))) { m_pressure_factor = unit.factor(); - } else if (name == "molar-energy" && unit.convertible(knownUnits.at("J/kmol"))) { - m_molar_energy_factor = unit.factor(); + } else if (name == "energy" && unit.convertible(knownUnits.at("J"))) { + m_energy_factor = unit.factor(); + } else if (name == "activation-energy") { + // handled separately to allow override } else { throw CanteraError("UnitSystem::setDefaults", "Unable to set default unit for '{}' to '{}' ({}).", name, item.second, unit.str()); } } + if (units.find("activation-energy") != units.end()) { + setDefaultActivationEnergy(units.at("activation-energy")); + } else if (!m_explicit_activation_energy) { + m_activation_energy_factor = m_energy_factor / m_quantity_factor; + } } -void UnitSystem::setDefaultMolarEnergy(const std::string& e_units) +void UnitSystem::setDefaultActivationEnergy(const std::string& e_units) { Units u(e_units); if (u.convertible(Units("J/kmol"))) { - m_molar_energy_factor = u.factor(); + m_activation_energy_factor = u.factor(); } else if (u.convertible(knownUnits.at("K"))) { - m_molar_energy_factor = GasConstant; + m_activation_energy_factor = GasConstant; } else if (u.convertible(knownUnits.at("eV"))) { - m_molar_energy_factor = u.factor() * Avogadro; + m_activation_energy_factor = u.factor() * Avogadro; } else { - throw CanteraError("Units::setDefaultMolarEnergy", - "Unable to match unit '{}' to a unit of molar energy", e_units); + throw CanteraError("Units::setDefaultActivationEnergy", + "Unable to match unit '{}' to a unit of activation energy", e_units); } + m_explicit_activation_energy = true; } double UnitSystem::convert(double value, const std::string& src, @@ -315,11 +343,12 @@ double UnitSystem::convert(double value, const std::string& dest) const double UnitSystem::convert(double value, const Units& dest) const { return value / dest.factor() - * pow(m_mass_factor, dest.m_mass_dim - dest.m_pressure_dim) - * pow(m_length_factor, dest.m_length_dim + dest.m_pressure_dim) - * pow(m_time_factor, dest.m_time_dim + 2*dest.m_pressure_dim) + * pow(m_mass_factor, dest.m_mass_dim - dest.m_pressure_dim - dest.m_energy_dim) + * pow(m_length_factor, dest.m_length_dim + dest.m_pressure_dim - 2*dest.m_energy_dim) + * pow(m_time_factor, dest.m_time_dim + 2*dest.m_pressure_dim + 2*dest.m_energy_dim) * pow(m_quantity_factor, dest.m_quantity_dim) - * pow(m_pressure_factor, dest.m_pressure_dim); + * pow(m_pressure_factor, dest.m_pressure_dim) + * pow(m_energy_factor, dest.m_energy_dim); } static std::pair split_unit(const AnyValue& v) { @@ -373,8 +402,8 @@ vector_fp UnitSystem::convert(const std::vector& vals, return out; } -double UnitSystem::convertMolarEnergy(double value, const std::string& src, - const std::string& dest) const +double UnitSystem::convertActivationEnergy(double value, const std::string& src, + const std::string& dest) const { // Convert to J/kmol Units usrc(src); @@ -385,8 +414,8 @@ double UnitSystem::convertMolarEnergy(double value, const std::string& src, } else if (usrc.convertible(Units("eV"))) { value *= Avogadro * usrc.factor(); } else { - throw CanteraError("UnitSystem::convertMolarEnergy", - "Don't understand units '{}' as a molar energy", src); + throw CanteraError("UnitSystem::convertActivationEnergy", + "Don't understand units '{}' as an activation energy", src); } // Convert from J/kmol @@ -398,38 +427,39 @@ double UnitSystem::convertMolarEnergy(double value, const std::string& src, } else if (udest.convertible(Units("eV"))) { value /= Avogadro * udest.factor(); } else { - throw CanteraError("UnitSystem::convertMolarEnergy", - "Don't understand units '{}' as a molar energy", dest); + throw CanteraError("UnitSystem::convertActivationEnergy", + "Don't understand units '{}' as an activation energy", dest); } return value; } -double UnitSystem::convertMolarEnergy(double value, const std::string& dest) const +double UnitSystem::convertActivationEnergy(double value, + const std::string& dest) const { Units udest(dest); if (udest.convertible(Units("J/kmol"))) { - return value * m_molar_energy_factor / udest.factor(); + return value * m_activation_energy_factor / udest.factor(); } else if (udest.convertible(knownUnits.at("K"))) { - return value * m_molar_energy_factor / GasConstant; + return value * m_activation_energy_factor / GasConstant; } else if (udest.convertible(knownUnits.at("eV"))) { - return value * m_molar_energy_factor / (Avogadro * udest.factor()); + return value * m_activation_energy_factor / (Avogadro * udest.factor()); } else { - throw CanteraError("UnitSystem::convertMolarEnergy", - "'{}' is not a unit of molar energy", dest); + throw CanteraError("UnitSystem::convertActivationEnergy", + "'{}' is not a unit of activation energy", dest); } } -double UnitSystem::convertMolarEnergy(const AnyValue& v, - const std::string& dest) const +double UnitSystem::convertActivationEnergy(const AnyValue& v, + const std::string& dest) const { auto val_units = split_unit(v); if (val_units.second.empty()) { // Just a value, so convert using default units - return convertMolarEnergy(val_units.first, dest); + return convertActivationEnergy(val_units.first, dest); } else { // Both source and destination units are explicit - return convertMolarEnergy(val_units.first, val_units.second, dest); + return convertActivationEnergy(val_units.first, val_units.second, dest); } } diff --git a/src/kinetics/Reaction.cpp b/src/kinetics/Reaction.cpp index b602aa4ce..8f294ce0b 100644 --- a/src/kinetics/Reaction.cpp +++ b/src/kinetics/Reaction.cpp @@ -324,12 +324,12 @@ Arrhenius readArrhenius(const Reaction& R, const AnyValue& rate, auto& rate_map = rate.as(); A = units.convert(rate_map["A"], rc_units); b = rate_map["b"].asDouble(); - Ta = rate_map.convertMolarEnergy("Ea", "K"); + Ta = units.convertActivationEnergy(rate_map["Ea"], "K"); } else { auto& rate_vec = rate.asVector(3); A = units.convert(rate_vec[0], rc_units); b = rate_vec[1].asDouble(); - Ta = units.convertMolarEnergy(rate_vec[2], "K"); + Ta = units.convertActivationEnergy(rate_vec[2], "K"); } return Arrhenius(A, b, Ta); } diff --git a/src/thermo/SpeciesThermoFactory.cpp b/src/thermo/SpeciesThermoFactory.cpp index 87e30c66d..c9a050fe8 100644 --- a/src/thermo/SpeciesThermoFactory.cpp +++ b/src/thermo/SpeciesThermoFactory.cpp @@ -369,14 +369,14 @@ void setupMu0(Mu0Poly& thermo, const AnyMap& node) { setupSpeciesThermo(thermo, node); bool dimensionless = node.getBool("dimensionless", false); - double h0 = node.convertMolarEnergy("h0", "J/kmol", 0.0); + double h0 = node.convert("h0", "J/kmol", 0.0); map T_mu; for (const auto& item : node["data"]) { double T = node.units().convert(fpValueCheck(item.first), "K"); if (dimensionless) { T_mu[T] = item.second.asDouble() * GasConstant * T; } else { - T_mu[T] = node.units().convertMolarEnergy(item.second, "J/kmol"); + T_mu[T] = node.units().convert(item.second, "J/kmol"); } } thermo.setParameters(h0, T_mu); diff --git a/test/data/ideal-gas.yaml b/test/data/ideal-gas.yaml index 2e6e7985f..ff8145f3a 100644 --- a/test/data/ideal-gas.yaml +++ b/test/data/ideal-gas.yaml @@ -1,4 +1,4 @@ -units: {length: cm, time: s, quantity: mol, molar-energy: cal/mol} +units: {length: cm, time: s, quantity: mol, energy: cal} phases: - name: simple diff --git a/test/data/test_subdir/species-elements.yaml b/test/data/test_subdir/species-elements.yaml index 0888e1415..78fbf23ec 100644 --- a/test/data/test_subdir/species-elements.yaml +++ b/test/data/test_subdir/species-elements.yaml @@ -1,4 +1,4 @@ -units: {length: cm, time: s, quantity: mol, molar-energy: cal/mol} +units: {length: cm, time: s, quantity: mol, energy: cal} isotopes: - symbol: Ar diff --git a/test/general/test_units.cpp b/test/general/test_units.cpp index f21dee317..951b060c2 100644 --- a/test/general/test_units.cpp +++ b/test/general/test_units.cpp @@ -40,8 +40,8 @@ TEST(Units, prefixes) { EXPECT_DOUBLE_EQ(U.convert(1.0, "m/s", "km/hr"), 3.6); } -TEST(Units, with_defaults) { - UnitSystem U({"cm", "g", "mol", "atm"}); +TEST(Units, with_defaults1) { + UnitSystem U({"cm", "g", "mol", "atm", "kcal"}); EXPECT_DOUBLE_EQ(U.convert(1.0, "m"), 0.01); EXPECT_DOUBLE_EQ(U.convert(1.0, "kmol/m^3"), 1000); EXPECT_DOUBLE_EQ(U.convert(1.0, "kg/kmol"), 1.0); @@ -49,12 +49,19 @@ TEST(Units, with_defaults) { EXPECT_DOUBLE_EQ(U.convert(1.0, "Pa"), 101325); EXPECT_DOUBLE_EQ(U.convert(1.0, "hPa"), 1013.25); EXPECT_DOUBLE_EQ(U.convert(1.0, "Pa*m^6/kmol"), 101325*1e-12*1000); + EXPECT_DOUBLE_EQ(U.convert(1.0, "J"), 4184); +} + +TEST(Units, with_defaults2) { + UnitSystem U({"dyn/cm^2"}); + EXPECT_DOUBLE_EQ(U.convert(1.0, "Pa"), 0.1); + EXPECT_DOUBLE_EQ(U.convert(1.0, "N/m^2"), 1.0); } TEST(Units, with_defaults_map) { std::map defaults{ {"length", "cm"}, {"mass", "g"}, {"quantity", "mol"}, - {"pressure", "atm"} + {"pressure", "atm"}, {"energy", "J"} }; UnitSystem U; U.setDefaults(defaults); @@ -65,7 +72,7 @@ TEST(Units, with_defaults_map) { EXPECT_DOUBLE_EQ(U.convert(1.0, "Pa"), 101325); EXPECT_DOUBLE_EQ(U.convert(1.0, "hPa"), 1013.25); EXPECT_DOUBLE_EQ(U.convert(1.0, "Pa*m^6/kmol"), 101325*1e-12*1000); - + EXPECT_DOUBLE_EQ(U.convert(1.0, "J/cm^3"), 1.0); } TEST(Units, bad_defaults) { @@ -77,22 +84,55 @@ TEST(Units, bad_defaults) { } -TEST(Units, activation_energies) { +TEST(Units, activation_energies1) { UnitSystem U; - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(1000, "J/kmol", "J/mol"), 1.0); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(100, "K", "K"), 100); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(500, "K", "J/kmol"), 500 * GasConstant); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(3, "J/mol", "K"), 3000 / GasConstant); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "J/kmol", "J/mol"), 1.0); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(100, "K", "K"), 100); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(500, "K", "J/kmol"), 500 * GasConstant); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(3, "J/mol", "K"), 3000 / GasConstant); +} - U.setDefaults({"cm", "g"}); - U.setDefaultMolarEnergy("cal/mol"); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(1000, "cal/mol"), 1000); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(1000, "J/kmol"), 4184e3); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(1000, "K"), 4184e3 / GasConstant); +TEST(Units, activation_energies2) { + UnitSystem U; + U.setDefaultActivationEnergy("cal/mol"); + U.setDefaults({"cm", "g", "J"}); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "cal/mol"), 1000); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "J/kmol"), 4184e3); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "K"), 4184e3 / GasConstant); +} - U.setDefaultMolarEnergy("K"); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(2000, "K"), 2000); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(2000, "J/kmol"), 2000 * GasConstant); +TEST(Units, activation_energies3) { + UnitSystem U({"cal", "mol"}); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "cal/mol"), 1000); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "J/kmol"), 4184e3); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1000, "K"), 4184e3 / GasConstant); +} + +TEST(Units, activation_energies4) { + UnitSystem U; + U.setDefaultActivationEnergy("K"); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(2000, "K"), 2000); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(2000, "J/kmol"), 2000 * GasConstant); +} + +TEST(Units, activation_energies5) { + UnitSystem U; + std::map defaults{ + {"quantity", "mol"}, {"energy", "cal"}, {"activation-energy", "K"} + }; + U.setDefaults(defaults); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(2000, "K"), 2000); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(2000, "J/kmol"), 2000 * GasConstant); +} + +TEST(Units, activation_energies6) { + UnitSystem U; + std::map defaults{ + {"activation-energy", "eV"} + }; + U.setDefaults(defaults); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1, "J/kmol"), ElectronCharge * Avogadro); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(1, "eV"), 1.0); } TEST(Units, from_anymap) { @@ -107,7 +147,7 @@ TEST(Units, from_anymap) { EXPECT_DOUBLE_EQ(m.convert("V", "m^3"), 1e-9); auto k1 = m["k1"].asVector(); EXPECT_DOUBLE_EQ(U.convert(k1[0], "m^3/kmol"), 1e-9*5e2); - EXPECT_DOUBLE_EQ(U.convertMolarEnergy(k1[2], "J/kmol"), 29000); + EXPECT_DOUBLE_EQ(U.convertActivationEnergy(k1[2], "J/kmol"), 29000); } TEST(Units, from_anymap_default) { @@ -141,3 +181,19 @@ TEST(Units, from_yaml) { EXPECT_DOUBLE_EQ(spam[0].convert("eggs", "m"), 3000); EXPECT_DOUBLE_EQ(spam[1].convertVector("ham", "m")[2], 500); } + +TEST(Units, act_energy_from_yaml) { + AnyMap m = AnyMap::fromYamlString( + "units: {energy: J, quantity: mol, activation-energy: K}\n" + "foo:\n" + "- units: {quantity: kmol}\n" // applies to items in foo + "- bar: 0.6\n" + "- baz: 0.2\n" + " units: {energy: kJ}\n" // applies to just this entry (with "baz") + ); + auto& foo = m["foo"].asVector(); + EXPECT_DOUBLE_EQ(foo[0].units().convertActivationEnergy(foo[0]["bar"], "K"), 0.6); + EXPECT_DOUBLE_EQ(foo[1].units().convertActivationEnergy(foo[1]["baz"], "K"), 0.2); + EXPECT_DOUBLE_EQ(foo[0].convert("bar", "J/mol"), 0.0006); + EXPECT_DOUBLE_EQ(foo[1].convert("baz", "J/mol"), 0.2); +}