[Thermo] Add PDSS objects to VPStandardStateTP without XML

Added PDSSFactory class to generalize PDSS object creation
This commit is contained in:
Ray Speth 2017-02-19 11:37:47 -05:00
parent c28ca48cf8
commit 3c771ded2b
5 changed files with 132 additions and 48 deletions

View file

@ -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<PDSS>
{
public:
//! Static function that creates a static instance of the factory.
static PDSSFactory* factory() {
std::unique_lock<std::mutex> 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<std::mutex> 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

View file

@ -247,7 +247,8 @@ public:
using Phase::addSpecies;
virtual bool addSpecies(shared_ptr<Species> 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);
PDSS* providePDSS(size_t k);
const PDSS* providePDSS(size_t k) const;

View file

@ -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);
}
}

View file

@ -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<PDSS> kPDSS(newPDSS(ss_model));
kPDSS->setParametersFromXML(*s);
vpss_ptr->installPDSS(k, std::move(kPDSS));
}
th->saveSpeciesData(k, s);
}

View file

@ -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)
{
pdss->setParent(this, k);
pdss->setMolecularWeight(molecularWeight(k));
if (pdss->useSTITbyPDSS()) {
m_spthermo.install_STIT(k, make_shared<STITbyPDSS>(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_Water*>(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<STITbyPDSS>(kPDSS);
m_spthermo.install_STIT(k, stit);
} else {
shared_ptr<SpeciesThermoInterpType> 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)