From 3c771ded2bf184b4cffb362127fd77ba35390da4 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sun, 19 Feb 2017 11:37:47 -0500 Subject: [PATCH] [Thermo] Add PDSS objects to VPStandardStateTP without XML Added PDSSFactory class to generalize PDSS object creation --- include/cantera/thermo/PDSSFactory.h | 59 ++++++++++++++++++++ include/cantera/thermo/VPStandardStateTP.h | 3 +- src/thermo/PDSSFactory.cpp | 47 ++++++++++++++++ src/thermo/ThermoFactory.cpp | 7 ++- src/thermo/VPStandardStateTP.cpp | 64 ++++++---------------- 5 files changed, 132 insertions(+), 48 deletions(-) create mode 100644 include/cantera/thermo/PDSSFactory.h create mode 100644 src/thermo/PDSSFactory.cpp diff --git a/include/cantera/thermo/PDSSFactory.h b/include/cantera/thermo/PDSSFactory.h new file mode 100644 index 000000000..d406ae22b --- /dev/null +++ b/include/cantera/thermo/PDSSFactory.h @@ -0,0 +1,59 @@ +//! @file PDSSFactory.h + +// This file is part of Cantera. See License.txt in the top-level directory or +// at http://www.cantera.org/license.txt for license and copyright information. + +#ifndef PDSS_FACTORY_H +#define PDSS_FACTORY_H + +#include "PDSS.h" +#include "cantera/base/FactoryBase.h" +#include "cantera/thermo/VPStandardStateTP.h" + +namespace Cantera +{ + +class PDSSFactory : public Factory +{ +public: + //! Static function that creates a static instance of the factory. + static PDSSFactory* factory() { + std::unique_lock lock(thermo_mutex); + if (!s_factory) { + s_factory = new PDSSFactory; + } + return s_factory; + } + + //! delete the static instance of this factory + virtual void deleteFactory() { + std::unique_lock lock(thermo_mutex); + delete s_factory; + s_factory = 0; + } + + //! Create a new thermodynamic property manager. + /*! + * @param model String to look up the model against + * @returns a pointer to a new PDSS instance matching the model string. + * Returns NULL if something went wrong. Throws an exception if the string + * wasn't matched. + */ + virtual PDSS* newPDSS(const std::string& model); + +private: + //! static member of a single instance + static PDSSFactory* s_factory; + + //! Private constructors prevents usage + PDSSFactory(); + + //! Decl for locking mutex for thermo factory singleton + static std::mutex thermo_mutex; +}; + +PDSS* newPDSS(const std::string& model); + +} + +#endif diff --git a/include/cantera/thermo/VPStandardStateTP.h b/include/cantera/thermo/VPStandardStateTP.h index 3828fac3d..0fb62a8d8 100644 --- a/include/cantera/thermo/VPStandardStateTP.h +++ b/include/cantera/thermo/VPStandardStateTP.h @@ -247,7 +247,8 @@ public: using Phase::addSpecies; virtual bool addSpecies(shared_ptr spec); - void createInstallPDSS(size_t k, const XML_Node& s, const XML_Node* phaseNode_ptr); + //! Install a PDSS object for species *k* + void installPDSS(size_t k, std::unique_ptr&& pdss); PDSS* providePDSS(size_t k); const PDSS* providePDSS(size_t k) const; diff --git a/src/thermo/PDSSFactory.cpp b/src/thermo/PDSSFactory.cpp new file mode 100644 index 000000000..26400eaf8 --- /dev/null +++ b/src/thermo/PDSSFactory.cpp @@ -0,0 +1,47 @@ +//! @file PDSSFactory.cpp + +// This file is part of Cantera. See License.txt in the top-level directory or +// at http://www.cantera.org/license.txt for license and copyright information. + +#include "cantera/thermo/PDSSFactory.h" +#include "cantera/thermo/PDSS_IdealGas.h" +#include "cantera/thermo/PDSS_Water.h" +#include "cantera/thermo/PDSS_ConstVol.h" +#include "cantera/thermo/PDSS_SSVol.h" +#include "cantera/thermo/PDSS_HKFT.h" +#include "cantera/thermo/PDSS_IonsFromNeutral.h" + +namespace Cantera +{ + +PDSSFactory* PDSSFactory::s_factory = 0; +std::mutex PDSSFactory::thermo_mutex; + +PDSSFactory::PDSSFactory() +{ + reg("ideal-gas", []() { return new PDSS_IdealGas(); }); + reg("constant-incompressible", []() { return new PDSS_ConstVol(); }); + m_synonyms["constant_incompressible"] = "constant-incompressible"; + reg("water", []() { return new PDSS_Water(); }); + m_synonyms["waterPDSS"] = m_synonyms["waterIAPWS"] = "water"; + reg("ions-from-neutral", []() { return new PDSS_IonsFromNeutral(); }); + m_synonyms["IonFromNeutral"] = "ions-from-neutral"; + reg("constant", []() { return new PDSS_SSVol(); }); + m_synonyms["temperature_polynomial"] = "constant"; + m_synonyms["temperature-polynomial"] = "constant"; + m_synonyms["density_temperature_polynomial"] = "constant"; + m_synonyms["density-temperature-polynomial"] = "constant"; + reg("HKFT", []() { return new PDSS_HKFT(); }); +} + +PDSS* PDSSFactory::newPDSS(const std::string& model) +{ + return create(model); +} + +PDSS* newPDSS(const std::string& model) +{ + return PDSSFactory::factory()->newPDSS(model); +} + +} diff --git a/src/thermo/ThermoFactory.cpp b/src/thermo/ThermoFactory.cpp index d0ca945d0..686ad6374 100644 --- a/src/thermo/ThermoFactory.cpp +++ b/src/thermo/ThermoFactory.cpp @@ -12,6 +12,7 @@ #include "cantera/thermo/Species.h" #include "cantera/thermo/speciesThermoTypes.h" #include "cantera/thermo/SpeciesThermoFactory.h" +#include "cantera/thermo/PDSSFactory.h" #include "cantera/thermo/MultiSpeciesThermo.h" #include "cantera/thermo/IdealGasPhase.h" @@ -346,7 +347,11 @@ void importPhase(XML_Node& phase, ThermoPhase* th) } th->addSpecies(newSpecies(*s)); if (vpss_ptr) { - vpss_ptr->createInstallPDSS(k, *s, &phase); + const XML_Node* const ss = s->findByName("standardState"); + std::string ss_model = (ss) ? ss->attrib("model") : "ideal-gas"; + unique_ptr kPDSS(newPDSS(ss_model)); + kPDSS->setParametersFromXML(*s); + vpss_ptr->installPDSS(k, std::move(kPDSS)); } th->saveSpeciesData(k, s); } diff --git a/src/thermo/VPStandardStateTP.cpp b/src/thermo/VPStandardStateTP.cpp index 4a3b7273e..6c8d0998e 100644 --- a/src/thermo/VPStandardStateTP.cpp +++ b/src/thermo/VPStandardStateTP.cpp @@ -11,14 +11,10 @@ #include "cantera/thermo/VPStandardStateTP.h" #include "cantera/thermo/PDSS.h" -#include "cantera/thermo/PDSS_IdealGas.h" #include "cantera/thermo/PDSS_Water.h" -#include "cantera/thermo/PDSS_ConstVol.h" -#include "cantera/thermo/PDSS_SSVol.h" -#include "cantera/thermo/PDSS_HKFT.h" -#include "cantera/thermo/PDSS_IonsFromNeutral.h" #include "cantera/thermo/IonsFromNeutralVPSSTP.h" #include "cantera/thermo/SpeciesThermoFactory.h" +#include "cantera/thermo/PDSSFactory.h" #include "cantera/base/utilities.h" #include "cantera/base/ctml.h" @@ -256,51 +252,27 @@ void VPStandardStateTP::setState_TP(doublereal t, doublereal pres) calcDensity(); } -void VPStandardStateTP::createInstallPDSS(size_t k, const XML_Node& s, - const XML_Node* phaseNode) +void VPStandardStateTP::installPDSS(size_t k, unique_ptr&& pdss) { + pdss->setParent(this, k); + pdss->setMolecularWeight(molecularWeight(k)); + if (pdss->useSTITbyPDSS()) { + m_spthermo.install_STIT(k, make_shared(pdss.get())); + } else { + auto stit = species(k)->thermo; + stit->validate(speciesName(k)); + pdss->setReferenceThermo(stit); + m_spthermo.install_STIT(k, stit); + } + + if (dynamic_cast(pdss.get())) { + m_useTmpRefStateStorage = false; + } + if (m_PDSS_storage.size() < k+1) { m_PDSS_storage.resize(k+1); } - PDSS* kPDSS = nullptr; - - const XML_Node* const ss = s.findByName("standardState"); - if (!ss) { - kPDSS = new PDSS_IdealGas(); - } else { - std::string model = ss->attrib("model"); - if (model == "constant_incompressible") { - kPDSS = new PDSS_ConstVol(); - } else if (model == "waterIAPWS" || model == "waterPDSS") { - kPDSS = new PDSS_Water(); - m_useTmpRefStateStorage = false; - } else if (model == "HKFT") { - kPDSS = new PDSS_HKFT(); - } else if (model == "IonFromNeutral") { - kPDSS = new PDSS_IonsFromNeutral(); - } else if (model == "constant" || model == "temperature_polynomial" || model == "density_temperature_polynomial") { - kPDSS = new PDSS_SSVol(); - } else { - throw CanteraError("VPStandardStateTP::createInstallPDSS", - "unknown standard state formulation: " + model); - } - } - kPDSS->setParent(this, k); - kPDSS->setMolecularWeight(molecularWeight(k)); - kPDSS->setParametersFromXML(s); - - if (kPDSS->useSTITbyPDSS()) { - auto stit = make_shared(kPDSS); - m_spthermo.install_STIT(k, stit); - } else { - shared_ptr stit( - newSpeciesThermoInterpType(s.child("thermo"))); - stit->validate(s["name"]); - kPDSS->setReferenceThermo(stit); - m_spthermo.install_STIT(k, stit); - } - - m_PDSS_storage[k].reset(kPDSS); + m_PDSS_storage[k].swap(pdss); } PDSS* VPStandardStateTP::providePDSS(size_t k)