From 11caddea1ef3f84a153d15b41d72d40a7869ad65 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Fri, 17 Oct 2014 23:44:42 +0000 Subject: [PATCH] Implement factory functions for SpeciesThermoInterpType --- .../cantera/thermo/Nasa9PolyMultiTempRegion.h | 2 + include/cantera/thermo/NasaPoly2.h | 8 ++- include/cantera/thermo/ShomatePoly.h | 6 ++ include/cantera/thermo/SpeciesThermoFactory.h | 29 +++++++- .../cantera/thermo/SpeciesThermoInterpType.h | 8 +++ src/thermo/GeneralSpeciesThermo.cpp | 45 ++----------- src/thermo/Nasa9PolyMultiTempRegion.cpp | 7 ++ src/thermo/NasaPoly2.cpp | 6 +- src/thermo/SpeciesThermoFactory.cpp | 67 ++++++++++++++++--- 9 files changed, 120 insertions(+), 58 deletions(-) diff --git a/include/cantera/thermo/Nasa9PolyMultiTempRegion.h b/include/cantera/thermo/Nasa9PolyMultiTempRegion.h index 21442d469..fc0a50500 100644 --- a/include/cantera/thermo/Nasa9PolyMultiTempRegion.h +++ b/include/cantera/thermo/Nasa9PolyMultiTempRegion.h @@ -72,6 +72,8 @@ public: virtual int reportType() const; + virtual void setIndex(size_t index); + virtual size_t temperaturePolySize() const { return 7; } virtual void updateTemperaturePoly(double T, double* T_poly) const; diff --git a/include/cantera/thermo/NasaPoly2.h b/include/cantera/thermo/NasaPoly2.h index 413db97dc..e2393e952 100644 --- a/include/cantera/thermo/NasaPoly2.h +++ b/include/cantera/thermo/NasaPoly2.h @@ -109,6 +109,12 @@ public: return NASA2; } + virtual void setIndex(size_t index) { + SpeciesThermoInterpType::setIndex(index); + mnp_low.setIndex(index); + mnp_high.setIndex(index); + } + virtual size_t temperaturePolySize() const { return 6; } virtual void updateTemperaturePoly(double T, double* T_poly) const { @@ -197,7 +203,7 @@ public: mnp_high.modifyOneHf298(k, hnew); } - double checkContinuity(const std::string& name=""); + void validate(const std::string& name); protected: //! Midrange temperature diff --git a/include/cantera/thermo/ShomatePoly.h b/include/cantera/thermo/ShomatePoly.h index a7e5e5631..a0933a94e 100644 --- a/include/cantera/thermo/ShomatePoly.h +++ b/include/cantera/thermo/ShomatePoly.h @@ -360,6 +360,12 @@ public: return SHOMATE2; } + virtual void setIndex(size_t index) { + SpeciesThermoInterpType::setIndex(index); + msp_low.setIndex(index); + msp_high.setIndex(index); + } + virtual size_t temperaturePolySize() const { return 7; } virtual void updateTemperaturePoly(double T, double* T_poly) const { diff --git a/include/cantera/thermo/SpeciesThermoFactory.h b/include/cantera/thermo/SpeciesThermoFactory.h index 7cd75a8d6..457a01e5f 100644 --- a/include/cantera/thermo/SpeciesThermoFactory.h +++ b/include/cantera/thermo/SpeciesThermoFactory.h @@ -269,8 +269,33 @@ SpeciesThermo* newSpeciesThermoMgr(const std::string& stype, SpeciesThermo* newSpeciesThermoMgr(std::vector spDataNodeList, SpeciesThermoFactory* f=0); + +//! Create a new SpeciesThermoInterpType object given a corresponding constant. +/*! + * @param type A constant specifying the type to be created + * @param tlow The lowest temperature at which the parameterization is valid + * @param thigh The highest temperature at which the parameterization is valid + * @param pref The reference pressure for the parameterization + * @param coeffs The array of coefficients for the parameterization + * @return Returns the pointer to the newly allocated + * SpeciesThermoInterpType object + */ +SpeciesThermoInterpType* newSpeciesThermoInterpType(int type, double tlow, + double thigh, double pref, const double* coeffs); + +//! Create a new SpeciesThermoInterpType object given a string +/*! + * @param type String name for the species thermo type + * @param tlow The lowest temperature at which the parameterization is valid + * @param thigh The highest temperature at which the parameterization is valid + * @param pref The reference pressure for the parameterization + * @param coeffs The array of coefficients for the parameterization + * @return Returns the pointer to the newly allocated + * SpeciesThermoInterpType object + */ +SpeciesThermoInterpType* newSpeciesThermoInterpType(const std::string& type, + double tlow, double thigh, double pref, const double* coeffs); + } #endif - - diff --git a/include/cantera/thermo/SpeciesThermoInterpType.h b/include/cantera/thermo/SpeciesThermoInterpType.h index 3e65708af..5f11dcb7c 100644 --- a/include/cantera/thermo/SpeciesThermoInterpType.h +++ b/include/cantera/thermo/SpeciesThermoInterpType.h @@ -187,6 +187,10 @@ public: return m_Pref; } + //! Check for problems with the parameterization, and generate warnings or + //! throw and exception if any are found. + virtual void validate(const std::string& name) {} + //! Returns an integer representing the type of parameterization virtual int reportType() const = 0; @@ -195,6 +199,10 @@ public: return m_index; } + virtual void setIndex(size_t index) { + m_index = index; + } + //! Number of terms in the temperature polynomial for this parameterization virtual size_t temperaturePolySize() const { return 1; } diff --git a/src/thermo/GeneralSpeciesThermo.cpp b/src/thermo/GeneralSpeciesThermo.cpp index 95fabcd81..45cb5475d 100644 --- a/src/thermo/GeneralSpeciesThermo.cpp +++ b/src/thermo/GeneralSpeciesThermo.cpp @@ -7,13 +7,7 @@ // Copyright 2001-2004 California Institute of Technology #include "cantera/thermo/GeneralSpeciesThermo.h" -#include "cantera/thermo/NasaPoly1.h" -#include "cantera/thermo/NasaPoly2.h" -#include "cantera/thermo/ShomatePoly.h" -#include "cantera/thermo/ConstCpPoly.h" -#include "cantera/thermo/Mu0Poly.h" -#include "cantera/thermo/AdsorbateThermo.h" -#include "cantera/thermo/StatMech.h" +#include "cantera/thermo/SpeciesThermoFactory.h" namespace Cantera { @@ -107,39 +101,10 @@ void GeneralSpeciesThermo::install(const std::string& name, /* * Create the necessary object */ - SpeciesThermoInterpType* sp; - switch (type) { - case NASA1: - sp = new NasaPoly1(index, minTemp_, maxTemp_, refPressure_, c); - break; - case SHOMATE1: - sp = new ShomatePoly(index, minTemp_, maxTemp_, refPressure_, c); - break; - case CONSTANT_CP: - case SIMPLE: - sp = new ConstCpPoly(index, minTemp_, maxTemp_, refPressure_, c); - break; - case MU0_INTERP: - sp = new Mu0Poly(index, minTemp_, maxTemp_, refPressure_, c); - break; - case SHOMATE2: - sp = new ShomatePoly2(index, minTemp_, maxTemp_, refPressure_, c); - break; - case NASA2: - sp = new NasaPoly2(index, minTemp_, maxTemp_, refPressure_, c); - dynamic_cast(sp)->checkContinuity(name); - break; - case STAT: - sp = new StatMech(index, minTemp_, maxTemp_, refPressure_, c, name); - break; - case ADSORBATE: - sp = new Adsorbate(index, minTemp_, maxTemp_, refPressure_, c); - break; - default: - throw CanteraError("GeneralSpeciesThermo::install", - "unknown species type: " + int2str(type)); - } - + SpeciesThermoInterpType* sp = newSpeciesThermoInterpType(type, + minTemp_, maxTemp_, refPressure_, c); + sp->setIndex(index); + sp->validate(name); install_STIT(sp); } diff --git a/src/thermo/Nasa9PolyMultiTempRegion.cpp b/src/thermo/Nasa9PolyMultiTempRegion.cpp index bae28f9fd..5692ef4c9 100644 --- a/src/thermo/Nasa9PolyMultiTempRegion.cpp +++ b/src/thermo/Nasa9PolyMultiTempRegion.cpp @@ -113,6 +113,13 @@ int Nasa9PolyMultiTempRegion::reportType() const return NASA9MULTITEMP; } +void Nasa9PolyMultiTempRegion::setIndex(size_t index) { + SpeciesThermoInterpType::setIndex(index); + for (size_t i = 0; i < m_numTempRegions; i++) { + m_regionPts[i]->setIndex(index); + } +} + void Nasa9PolyMultiTempRegion::updateTemperaturePoly(double T, double* T_poly) const { T_poly[0] = T; diff --git a/src/thermo/NasaPoly2.cpp b/src/thermo/NasaPoly2.cpp index 6f2bd9e54..70e474bec 100644 --- a/src/thermo/NasaPoly2.cpp +++ b/src/thermo/NasaPoly2.cpp @@ -4,7 +4,7 @@ namespace Cantera { -double NasaPoly2::checkContinuity(const std::string& name) +void NasaPoly2::validate(const std::string& name) { size_t offset = mnp_low.speciesIndex(); double cp_low, h_low, s_low; @@ -15,7 +15,6 @@ double NasaPoly2::checkContinuity(const std::string& name) &h_high - offset, &s_high - offset); double delta = cp_low - cp_high; - double maxError = std::abs(delta); if (fabs(delta/(fabs(cp_low)+1.0E-4)) > 0.001) { writelog("\n\n**** WARNING ****\nFor species "+name+ ", discontinuity in cp/R detected at Tmid = " @@ -28,7 +27,6 @@ double NasaPoly2::checkContinuity(const std::string& name) // enthalpy delta = h_low - h_high; - maxError = std::max(std::abs(delta), maxError); if (fabs(delta/(fabs(h_low)+cp_low*m_midT)) > 0.001) { writelog("\n\n**** WARNING ****\nFor species "+name+ ", discontinuity in h/RT detected at Tmid = " @@ -41,7 +39,6 @@ double NasaPoly2::checkContinuity(const std::string& name) // entropy delta = s_low - s_high; - maxError = std::max(std::abs(delta), maxError); if (fabs(delta/(fabs(s_low)+cp_low)) > 0.001) { writelog("\n\n**** WARNING ****\nFor species "+name+ ", discontinuity in s/R detected at Tmid = " @@ -51,7 +48,6 @@ double NasaPoly2::checkContinuity(const std::string& name) writelog("\tValue computed using high-temperature polynomial: " +fp2str(s_high)+".\n"); } - return maxError; } } diff --git a/src/thermo/SpeciesThermoFactory.cpp b/src/thermo/SpeciesThermoFactory.cpp index a94b917e0..78c466c61 100644 --- a/src/thermo/SpeciesThermoFactory.cpp +++ b/src/thermo/SpeciesThermoFactory.cpp @@ -17,7 +17,8 @@ #include "cantera/thermo/Nasa9PolyMultiTempRegion.h" #include "cantera/thermo/Nasa9Poly1.h" #include "cantera/thermo/StatMech.h" - +#include "cantera/thermo/NasaPoly2.h" +#include "cantera/thermo/ConstCpPoly.h" #include "cantera/thermo/AdsorbateThermo.h" #include "cantera/thermo/SpeciesThermoMgr.h" #include "cantera/thermo/speciesThermoTypes.h" @@ -97,15 +98,6 @@ static void getSpeciesThermoTypes(std::vector & spDataNodeList, } } -//! Static method to return an instance of this class -/*! - * This class is implemented as a singleton -- one in which - * only one instance is needed. The recommended way to access - * the factory is to call this static method, which - * instantiates the class if it is the first call, but - * otherwise simply returns the pointer to the existing - * instance. - */ SpeciesThermoFactory* SpeciesThermoFactory::factory() { ScopedLock lock(species_thermo_mutex); @@ -192,6 +184,61 @@ SpeciesThermo* SpeciesThermoFactory::newSpeciesThermoManager(const std::string& return (SpeciesThermo*) 0; } +SpeciesThermoInterpType* newSpeciesThermoInterpType(int type, double tlow, + double thigh, double pref, const double* coeffs) +{ + switch (type) { + case NASA1: + return new NasaPoly1(0, tlow, thigh, pref, coeffs); + case SHOMATE1: + return new ShomatePoly(0, tlow, thigh, pref, coeffs); + case CONSTANT_CP: + case SIMPLE: + return new ConstCpPoly(0, tlow, thigh, pref, coeffs); + case MU0_INTERP: + return new Mu0Poly(0, tlow, thigh, pref, coeffs); + case SHOMATE2: + return new ShomatePoly2(0, tlow, thigh, pref, coeffs); + case NASA2: + return new NasaPoly2(0, tlow, thigh, pref, coeffs); + case ADSORBATE: + return new Adsorbate(0, tlow, thigh, pref, coeffs); + default: + throw CanteraError("newSpeciesThermoInterpType", + "Unknown species thermo type: " + int2str(type) + "."); + } +} + +SpeciesThermoInterpType* newSpeciesThermoInterpType(const std::string& stype, + double tlow, double thigh, double pref, const double* coeffs) +{ + int itype = -1; + std::string type = lowercase(stype); + if (type == "nasa2" || type == "nasa") { + itype = NASA2; // two-region 7-coefficient NASA polynomials + } else if (type == "const_cp" || type == "simple") { + itype = CONSTANT_CP; + } else if (type == "shomate" || type == "shomate1") { + itype = SHOMATE1; // single-region Shomate polynomial + } else if (type == "shomate2") { + itype = SHOMATE2; // two-region Shomate polynomials + } else if (type == "nasa1") { + itype = NASA1; // single-region, 7-coefficient NASA polynomial + } else if (type == "nasa9") { + itype = NASA9; // single-region, 9-coefficient NASA polynomial + } else if (type == "nasa9multi") { + itype = NASA9MULTITEMP; // multi-region, 9-coefficient NASA polynomials + } else if (type == "mu0") { + itype = MU0_INTERP; + } else if (type == "adsorbate") { + itype = ADSORBATE; + } else { + throw CanteraError("newSpeciesThermoInterpType", + "Unknown species thermo type: '" + stype + "'."); + } + return newSpeciesThermoInterpType(itype, tlow, thigh, pref, coeffs); +} + //! Install a NASA polynomial thermodynamic property parameterization for species k into a SpeciesThermo instance. /*! * This is called by method installThermoForSpecies if a NASA block is found in the XML input.