From b77f368ead76d70cc73b6c1c174d872be80b0d06 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 5 Mar 2019 00:15:18 -0500 Subject: [PATCH] [Input] Instantiate BinarySolutionTabulatedThermo from YAML --- doc/sphinx/yaml/phases.rst | 30 +++++++++++++++ .../thermo/BinarySolutionTabulatedThermo.h | 1 + src/thermo/BinarySolutionTabulatedThermo.cpp | 38 +++++++++++++++++++ src/thermo/ThermoFactory.cpp | 1 + test/data/thermo-models.yaml | 31 +++++++++++++++ test/thermo/thermoFromYaml.cpp | 10 +++++ 6 files changed, 111 insertions(+) diff --git a/doc/sphinx/yaml/phases.rst b/doc/sphinx/yaml/phases.rst index 95d33dfab..e3635c568 100644 --- a/doc/sphinx/yaml/phases.rst +++ b/doc/sphinx/yaml/phases.rst @@ -53,6 +53,7 @@ The fields of a ``phase`` entry are: String specifying the phase thermodynamic model to be used. Supported model strings are: + - :ref:`binary-solution-tabulated ` - :ref:`compound-lattice ` - :ref:`constant-density ` - :ref:`Debye-Huckel ` @@ -175,6 +176,35 @@ The following synonyms are also implemented for use in any of the pairs: Phase thermodynamic models ========================== +.. _sec-yaml-binary-solution-tabulated: + +``binary-solution-tabulated`` +----------------------------- + +A phase implementing tabulated standard state thermodynamics for one species in +a binary solution, as `described here `_. + +Includes the fields of :ref:`sec-yaml-ideal-molal-solution`, plus: + +``tabulated-species`` + The name of the species to which the tabulated enthalpy and entropy is + added. + +``tabulated-thermo`` + A mapping containing three lists of equal lengths: + + ``mole-fractions`` + A list of mole fraction values for the tabulated species. + + ``enthalpy`` + The extra molar enthalpy to be added to the tabulated species at these + mole fractions. + + ``entropy`` + The extra molar entropy to be added to the tabulated species at these + mole fractions. + + .. _sec-yaml-compound-lattice: ``compound-lattice`` diff --git a/include/cantera/thermo/BinarySolutionTabulatedThermo.h b/include/cantera/thermo/BinarySolutionTabulatedThermo.h index 973164efa..977a90bdf 100644 --- a/include/cantera/thermo/BinarySolutionTabulatedThermo.h +++ b/include/cantera/thermo/BinarySolutionTabulatedThermo.h @@ -143,6 +143,7 @@ public: return "BinarySolutionTabulatedThermo"; } + virtual void initThermo(); virtual void initThermoXML(XML_Node& phaseNode, const std::string& id_); protected: diff --git a/src/thermo/BinarySolutionTabulatedThermo.cpp b/src/thermo/BinarySolutionTabulatedThermo.cpp index fa87dc735..e99e282d3 100644 --- a/src/thermo/BinarySolutionTabulatedThermo.cpp +++ b/src/thermo/BinarySolutionTabulatedThermo.cpp @@ -83,6 +83,44 @@ void BinarySolutionTabulatedThermo::_updateThermo() const } } +void BinarySolutionTabulatedThermo::initThermo() +{ + if (m_input.hasKey("tabulated-thermo")) { + m_kk_tab = speciesIndex(m_input["tabulated-species"].asString()); + if (m_kk_tab == npos) { + throw InputFileError("BinarySolutionTabulatedThermo::initThermo", + m_input["tabulated-species"], + "Species '{}' is not in phase '{}'", + m_input["tabulated-species"].asString(), name()); + } + const AnyMap& table = m_input["tabulated-thermo"].as(); + vector_fp x = table["mole-fractions"].asVector(); + size_t N = x.size(); + vector_fp h = table.convertVector("enthalpy", "J/kmol", N); + vector_fp s = table.convertVector("entropy", "J/kmol/K", N); + + // Sort the x, h, s data in the order of increasing x + std::vector> x_h(N), x_s(N); + for(size_t i = 0; i < N; i++){ + x_h[i] = {x[i], h[i]}; + x_s[i] = {x[i], s[i]}; + } + std::sort(x_h.begin(), x_h.end()); + std::sort(x_s.begin(), x_s.end()); + + // Store the sorted values in different arrays + m_molefrac_tab.resize(N); + m_enthalpy_tab.resize(N); + m_entropy_tab.resize(N); + for (size_t i = 0; i < N; i++) { + m_molefrac_tab[i] = x_h[i].first; + m_enthalpy_tab[i] = x_h[i].second; + m_entropy_tab[i] = x_s[i].second; + } + } + IdealSolidSolnPhase::initThermo(); +} + void BinarySolutionTabulatedThermo::initThermoXML(XML_Node& phaseNode, const std::string& id_) { vector_fp x, h, s; diff --git a/src/thermo/ThermoFactory.cpp b/src/thermo/ThermoFactory.cpp index 66ee17954..0f6347579 100644 --- a/src/thermo/ThermoFactory.cpp +++ b/src/thermo/ThermoFactory.cpp @@ -93,6 +93,7 @@ ThermoFactory::ThermoFactory() reg("PureLiquidWater", []() { return new WaterSSTP(); }); m_synonyms["water-IAPWS95"] = "PureLiquidWater"; reg("BinarySolutionTabulatedThermo", []() { return new BinarySolutionTabulatedThermo(); }); + m_synonyms["binary-solution-tabulated"] = "BinarySolutionTabulatedThermo"; } ThermoPhase* ThermoFactory::newThermoPhase(const std::string& model) diff --git a/test/data/thermo-models.yaml b/test/data/thermo-models.yaml index 51fb3620a..041c9b801 100644 --- a/test/data/thermo-models.yaml +++ b/test/data/thermo-models.yaml @@ -210,6 +210,21 @@ phases: density: 9 kg/m^3 state: {T: 1073.15, P: 1 atm} +- name: graphite-anode + thermo: binary-solution-tabulated + species: ["Li[anode]", "V[anode]"] + standard-concentration-basis: unity + tabulated-species: Li[anode] + units: {energy: J, quantity: mol, pressure: atm} + tabulated-thermo: + mole-fractions: [5.75000E-03, 1.25841E-01, 2.45932E-01, 3.66023E-01, + 4.86114E-01, 6.06205E-01, 7.26295E-01] + enthalpy: [-6.40692E+04, -9.69664E+03, -8.31339E+03, -7.69063E+03, + -3.94568E+03, -2.01329E+03, -1.59649E+03] + entropy: [3.05724E+01, 2.53501E+01, 1.27000E+01, 1.21865E+01, 1.70474E+01, + 1.92980E+01, 1.92885E+01] + state: {T: 300, P: 1, X: {"Li[anode]": 0.3, "V[anode]": 0.7}} + species: - name: NaCl(s) @@ -328,6 +343,22 @@ species: thermo: model: constant-cp +- name: Li[anode] + composition: {Li: 1, C: 6} + thermo: + model: constant-cp + equation-of-state: + model: constant-volume + density: 5.0317 g/cm^3 + +- name: V[anode] + composition: {C: 6} + thermo: + model: constant-cp + equation-of-state: + model: constant-volume + density: 5.0317 g/cm^3 + ideal-molal-fake-species: # Fake thermo data (GRI 3.0 coefficients for H2) diff --git a/test/thermo/thermoFromYaml.cpp b/test/thermo/thermoFromYaml.cpp index fb71534a3..2d47898c6 100644 --- a/test/thermo/thermoFromYaml.cpp +++ b/test/thermo/thermoFromYaml.cpp @@ -374,3 +374,13 @@ TEST(ThermoFromYaml, Metal) EXPECT_DOUBLE_EQ(thermo->density(), 9.0); EXPECT_DOUBLE_EQ(thermo->gibbs_mass(), 0.0); } + +TEST(ThermoFromYaml, BinarySolutionTabulatedThermo) +{ + auto thermo = newThermo("thermo-models.yaml", "graphite-anode"); + EXPECT_NEAR(thermo->density(), 5031.7, 1e-5); + EXPECT_NEAR(thermo->enthalpy_mass(), -32501.11354902755, 1e-9); + EXPECT_NEAR(thermo->entropy_mass(), 90.44311338593356, 1e-12); + thermo->setMoleFractionsByName("Li[anode]: 0.55, V[anode]: 0.45"); + EXPECT_NEAR(thermo->gibbs_mass(), -87065.61349532499, 1e-9); +}