Improve setting of default energy and pressure units
Only treat activation energies as a special case, rather than all molar energies. Units of activation energy can be set either explicitly or by setting units for energy and quantity. Only the case where activation energies are given as temperatures needs to be specified explicitly. Allow setting of default energy units, which allows calories to be used. Also add dyn/cm^2 as an option for pressure units.
This commit is contained in:
parent
56612115f3
commit
3028c14a10
9 changed files with 170 additions and 107 deletions
|
|
@ -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<std::string, AnyValue>::const_iterator;
|
||||
const_iterator begin() const {
|
||||
|
|
|
|||
|
|
@ -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<std::string> 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<std::string> units);
|
||||
|
||||
//! Set the default units using a map of dimension to unit pairs.
|
||||
|
|
@ -119,15 +120,16 @@ public:
|
|||
//! UnitSystem system;
|
||||
//! std::map<string, string> 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<std::string, std::string>& 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -674,23 +674,6 @@ vector_fp AnyMap::convertVector(const std::string& key, const std::string& dest,
|
|||
return units().convert(at(key).asVector<AnyValue>(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;
|
||||
|
||||
|
|
|
|||
|
|
@ -52,10 +52,15 @@ const std::map<std::string, Units> 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<std::string, Units> 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<std::string> 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<std::string> 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<std::string> 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<std::string, std::string>& units)
|
||||
|
|
@ -266,29 +286,37 @@ void UnitSystem::setDefaults(const std::map<std::string, std::string>& 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<double, std::string> split_unit(const AnyValue& v) {
|
||||
|
|
@ -373,8 +402,8 @@ vector_fp UnitSystem::convert(const std::vector<AnyValue>& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -324,12 +324,12 @@ Arrhenius readArrhenius(const Reaction& R, const AnyValue& rate,
|
|||
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");
|
||||
Ta = units.convertActivationEnergy(rate_map["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");
|
||||
Ta = units.convertActivationEnergy(rate_vec[2], "K");
|
||||
}
|
||||
return Arrhenius(A, b, Ta);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<double, double> 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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<std::string, std::string> 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<std::string, std::string> 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<std::string, std::string> 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<AnyValue>();
|
||||
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<AnyMap>();
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue