From 74eec731f1fb1f3c6343ff9a09784dc885d21f8c Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Mon, 17 Dec 2018 11:40:22 -0500 Subject: [PATCH] Add a version of UnitSystem.convert that handles default values --- include/cantera/base/Units.h | 19 +++++++++++++++++ src/base/Units.cpp | 32 +++++++++++++++++++++++++++++ src/thermo/SpeciesThermoFactory.cpp | 5 +---- test/general/test_units.cpp | 9 ++++++++ 4 files changed, 61 insertions(+), 4 deletions(-) diff --git a/include/cantera/base/Units.h b/include/cantera/base/Units.h index 79f34d36a..03504fb66 100644 --- a/include/cantera/base/Units.h +++ b/include/cantera/base/Units.h @@ -17,6 +17,7 @@ namespace Cantera { class AnyValue; +class AnyMap; //! A representation of the units associated with a dimensional quantity. /*! @@ -131,6 +132,16 @@ public: double convert(const AnyValue& val, const std::string& dest) const; double convert(const AnyValue& val, const Units& dest) const; + //! Convert the value at `node[key]` 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. '988 kg/m^3' and + //! convert from the specified units. If the key is missing, the `default_` + //! value is returned. + double convert(const AnyMap& node, const std::string key, + const std::string& dest, double default_) const; + double convert(const AnyMap& node, const std::string key, + const Units& dest, double default_) const; + //! Convert an array of AnyValue nodes to the units specified in `dest`. For //! each node, if the value is a double, convert it using the default units, //! and if it is a string, treat it as a value with the given dimensions. @@ -154,6 +165,14 @@ public: //! convert from the specified units. double convertMolarEnergy(const AnyValue& val, const std::string& dest) const; + //! Convert the value at `node[key]` to the molar energy 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. '988 + //! cal/mol' and convert from the specified units. If the key is missing, + //! the `default_` value is returned. + double convertMolarEnergy(const AnyMap& node, const std::string& key, + const std::string& dest, double default_) const; + private: //! Factor to convert mass from this unit system to kg double m_mass_factor; diff --git a/src/base/Units.cpp b/src/base/Units.cpp index 5420f5def..5ab9303f5 100644 --- a/src/base/Units.cpp +++ b/src/base/Units.cpp @@ -326,6 +326,27 @@ double UnitSystem::convert(const AnyValue& v, const Units& dest) const } } +double UnitSystem::convert(const AnyMap& node, const std::string key, + const std::string& dest, double default_) const +{ + if (node.hasKey(key)) { + return convert(node.at(key), Units(dest)); + } else { + return default_; + } +} + +double UnitSystem::convert(const AnyMap& node, const std::string key, + const Units& dest, double default_) const +{ + if (node.hasKey(key)) { + return convert(node.at(key), dest); + } else { + return default_; + } +} + + vector_fp UnitSystem::convert(const std::vector& vals, const std::string& dest) const { @@ -402,4 +423,15 @@ double UnitSystem::convertMolarEnergy(const AnyValue& v, } } +double UnitSystem::convertMolarEnergy( + const AnyMap& node, const std::string& key, + const std::string& dest, double default_) const +{ + if (node.hasKey(key)) { + return convertMolarEnergy(node.at(key), dest); + } else { + return default_; + } +} + } diff --git a/src/thermo/SpeciesThermoFactory.cpp b/src/thermo/SpeciesThermoFactory.cpp index 1ca8003f8..f7ee83ae3 100644 --- a/src/thermo/SpeciesThermoFactory.cpp +++ b/src/thermo/SpeciesThermoFactory.cpp @@ -145,10 +145,7 @@ static SpeciesThermoInterpType* newNasaThermoFromXML(vector nodes) void setupSpeciesThermo(SpeciesThermoInterpType& thermo, const AnyMap& node, const UnitSystem& units) { - double Pref = OneAtm; - if (node.hasKey("reference-pressure")) { - Pref = units.convert(node.at("reference-pressure"), "Pa"); - } + double Pref = units.convert(node, "reference-pressure", "Pa", OneAtm); thermo.setRefPressure(Pref); } diff --git a/test/general/test_units.cpp b/test/general/test_units.cpp index 34afc4fc7..330edb0b3 100644 --- a/test/general/test_units.cpp +++ b/test/general/test_units.cpp @@ -82,3 +82,12 @@ TEST(Units, from_anymap) { EXPECT_DOUBLE_EQ(U.convert(k1[0], "m^3/kmol"), 1e-9*5e2); EXPECT_DOUBLE_EQ(U.convertMolarEnergy(k1[2], "J/kmol"), 29000); } + +TEST(Units, from_anymap_default) { + AnyMap m = AnyMap::fromYamlString("{p0: 10 atm, h0: 10 cal/kmol}"); + UnitSystem U; + EXPECT_DOUBLE_EQ(U.convert(m, "p0", "Pa", 999), 10*OneAtm); + EXPECT_DOUBLE_EQ(U.convert(m, "p1", "Pa", 999), 999); + EXPECT_DOUBLE_EQ(U.convert(m, "h0", "J/kmol", 999), 41.84); + EXPECT_DOUBLE_EQ(U.convert(m, "h1", "J/kmol", 999), 999); +}