From 0da3424249a4c739ebc78051e4fb00cad67f7501 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Wed, 15 Oct 2014 02:02:55 +0000 Subject: [PATCH] [Thermo] Improve performance of GeneralSpeciesThermo Compute the temperature polynomial only once for each parameterization type. By doing this, we essentially get performance parity with the specialized SpeciesThermo types (NasaThermo, ShomateThermo, SimpleThermo). --- include/cantera/thermo/GeneralSpeciesThermo.h | 8 +- src/thermo/GeneralSpeciesThermo.cpp | 168 ++++++++++-------- 2 files changed, 105 insertions(+), 71 deletions(-) diff --git a/include/cantera/thermo/GeneralSpeciesThermo.h b/include/cantera/thermo/GeneralSpeciesThermo.h index ca4ab9d0c..3411c9cf1 100644 --- a/include/cantera/thermo/GeneralSpeciesThermo.h +++ b/include/cantera/thermo/GeneralSpeciesThermo.h @@ -133,6 +133,8 @@ private: */ SpeciesThermoInterpType* provideSTIT(size_t k); + const SpeciesThermoInterpType* provideSTIT(size_t k) const; + protected: /** * This is the main unknown in the object. It is @@ -144,7 +146,11 @@ protected: * species. These cases must be handled by the calling * routine. */ - std::vector m_sp; + std::map > m_sp; + + mutable std::map > m_tpoly; + + std::map > m_speciesLoc; //! Maximum value of the lowest temperature doublereal m_tlow_max; diff --git a/src/thermo/GeneralSpeciesThermo.cpp b/src/thermo/GeneralSpeciesThermo.cpp index baa9c0128..d8e3d232c 100644 --- a/src/thermo/GeneralSpeciesThermo.cpp +++ b/src/thermo/GeneralSpeciesThermo.cpp @@ -33,15 +33,25 @@ GeneralSpeciesThermo::GeneralSpeciesThermo() : } GeneralSpeciesThermo::GeneralSpeciesThermo(const GeneralSpeciesThermo& b) : + m_tpoly(b.m_tpoly), m_tlow_max(b.m_tlow_max), m_thigh_min(b.m_thigh_min), m_kk(b.m_kk) { - m_sp.resize(m_kk, 0); - for (size_t k = 0; k < m_kk; k++) { - SpeciesThermoInterpType* bk = b.m_sp[k]; - if (bk) { - m_sp[k] = bk->duplMyselfAsSpeciesThermoInterpType(); + // Delete current SpeciesThermoInterpType objects + std::map >::const_iterator iter; + for (iter = m_sp.begin(); iter != m_sp.end(); iter++) { + for (size_t k = 0; k < iter->second.size(); k++) { + delete iter->second[k]; + } + } + m_sp.clear(); + + // Copy SpeciesThermoInterpTypes from 'b' + for (iter = b.m_sp.begin(); iter != b.m_sp.end(); iter++) { + for (size_t k = 0; k < iter->second.size(); k++) { + const SpeciesThermoInterpType* spec = iter->second[k]; + m_sp[iter->first].push_back(spec->duplMyselfAsSpeciesThermoInterpType()); } } } @@ -49,29 +59,45 @@ GeneralSpeciesThermo::GeneralSpeciesThermo(const GeneralSpeciesThermo& b) : GeneralSpeciesThermo& GeneralSpeciesThermo::operator=(const GeneralSpeciesThermo& b) { - if (&b != this) { - m_tlow_max = b.m_tlow_max; - m_thigh_min = b.m_thigh_min; + if (&b == this) { + return *this; + } - for (size_t k = 0; k < m_kk; k++) { - delete m_sp[k]; - } - m_kk = b.m_kk; - m_sp.assign(m_kk, 0); - for (size_t k = 0; k < m_kk; k++) { - SpeciesThermoInterpType* bk = b.m_sp[k]; - if (bk) { - m_sp[k] = bk->duplMyselfAsSpeciesThermoInterpType(); - } + // Delete current SpeciesThermoInterpType objects + std::map >::const_iterator iter; + for (iter = m_sp.begin(); iter != m_sp.end(); iter++) { + for (size_t k = 0; k < iter->second.size(); k++) { + delete iter->second[k]; } } + m_sp.clear(); + + // Copy SpeciesThermoInterpType objects from 'b' + for (iter = b.m_sp.begin(); iter != b.m_sp.end(); iter++) { + for (size_t k = 0; k < iter->second.size(); k++) { + const SpeciesThermoInterpType* spec = iter->second[k]; + m_sp[iter->first].push_back(spec->duplMyselfAsSpeciesThermoInterpType()); + } + } + + m_tpoly = b.m_tpoly; + m_tlow_max = b.m_tlow_max; + m_thigh_min = b.m_thigh_min; + m_kk = b.m_kk; + m_p0 = b.m_p0; + return *this; } GeneralSpeciesThermo::~GeneralSpeciesThermo() { - for (size_t k = 0; k < m_kk; k++) { - delete m_sp[k]; + for (std::map >::iterator iter=m_sp.begin(); + iter != m_sp.end(); + iter++) { + std::vector& sp = iter->second; + for (size_t k = 0; k < sp.size(); k++) { + delete sp[k]; + } } } @@ -100,7 +126,6 @@ void GeneralSpeciesThermo::install(const std::string& name, } if (index >= m_kk) { - m_sp.resize(index+1, 0); m_kk = index+1; } @@ -108,55 +133,40 @@ void GeneralSpeciesThermo::install(const std::string& name, * Create the necessary object */ + SpeciesThermoInterpType* sp; switch (type) { case NASA1: - m_sp[index] = new NasaPoly1(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new NasaPoly1(index, minTemp_, maxTemp_, refPressure_, c); break; case SHOMATE1: - m_sp[index] = new ShomatePoly(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new ShomatePoly(index, minTemp_, maxTemp_, refPressure_, c); break; case CONSTANT_CP: case SIMPLE: - m_sp[index] = new ConstCpPoly(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new ConstCpPoly(index, minTemp_, maxTemp_, refPressure_, c); break; case MU0_INTERP: - m_sp[index] = new Mu0Poly(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new Mu0Poly(index, minTemp_, maxTemp_, refPressure_, c); break; case SHOMATE2: - m_sp[index] = new ShomatePoly2(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new ShomatePoly2(index, minTemp_, maxTemp_, refPressure_, c); break; case NASA2: - m_sp[index] = new NasaPoly2(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new NasaPoly2(index, minTemp_, maxTemp_, refPressure_, c); break; - case STAT: - m_sp[index] = new StatMech(index, minTemp_, maxTemp_, - refPressure_, c, name); + sp = new StatMech(index, minTemp_, maxTemp_, refPressure_, c, name); break; - case ADSORBATE: - m_sp[index] = new Adsorbate(index, minTemp_, maxTemp_, - refPressure_, c); + sp = new Adsorbate(index, minTemp_, maxTemp_, refPressure_, c); break; default: throw UnknownSpeciesThermoModel( "GeneralSpeciesThermo::install", "unknown species type", int2str(type)); - break; } - if (!m_sp[index]) { - cout << "Null m_sp... index = " << index << endl; - cout << "type = " << type << endl; - } - m_tlow_max = max(minTemp_, m_tlow_max); - m_thigh_min = min(maxTemp_, m_thigh_min); - markInstalled(index); + + install_STIT(sp); } void GeneralSpeciesThermo::install_STIT(SpeciesThermoInterpType* stit_ptr) @@ -171,15 +181,17 @@ void GeneralSpeciesThermo::install_STIT(SpeciesThermoInterpType* stit_ptr) } size_t index = stit_ptr->speciesIndex(); if (index >= m_kk) { - m_sp.resize(index+1, 0); m_kk = index+1; } - AssertThrow(m_sp[index] == 0, + AssertThrow(m_speciesLoc.find(index) == m_speciesLoc.end(), "Index position isn't null, duplication of assignment: " + int2str(index)); - /* - * Now, simply assign the position - */ - m_sp[index] = stit_ptr; + + int type = stit_ptr->reportType(); + m_speciesLoc[index] = make_pair(type, m_sp[type].size()); + m_sp[type].push_back(stit_ptr); + if (m_sp[type].size() == 1) { + m_tpoly[type].resize(stit_ptr->temperaturePolySize()); + } /* * Calculate max and min @@ -199,7 +211,7 @@ void GeneralSpeciesThermo::installPDSShandler(size_t k, PDSS* PDSS_ptr, void GeneralSpeciesThermo::update_one(size_t k, doublereal t, doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { - SpeciesThermoInterpType* sp_ptr = m_sp[k]; + const SpeciesThermoInterpType* sp_ptr = provideSTIT(k); if (sp_ptr) { sp_ptr->updatePropertiesTemp(t, cp_R, h_RT, s_R); } @@ -208,21 +220,21 @@ void GeneralSpeciesThermo::update_one(size_t k, doublereal t, doublereal* cp_R, void GeneralSpeciesThermo::update(doublereal t, doublereal* cp_R, doublereal* h_RT, doublereal* s_R) const { - vector::const_iterator _begin, _end; - _begin = m_sp.begin(); - _end = m_sp.end(); - SpeciesThermoInterpType* sp_ptr = 0; - for (; _begin != _end; ++_begin) { - sp_ptr = *(_begin); - if (sp_ptr) { - sp_ptr->updatePropertiesTemp(t, cp_R, h_RT, s_R); + map >::const_iterator iter = m_sp.begin(); + map >::iterator jter = m_tpoly.begin(); + for (; iter != m_sp.end(); iter++, jter++) { + const vector& species = iter->second; + double* tpoly = &jter->second[0]; + species[0]->updateTemperaturePoly(t, tpoly); + for (size_t k = 0; k < species.size(); k++) { + species[k]->updateProperties(tpoly, cp_R, h_RT, s_R); } } } int GeneralSpeciesThermo::reportType(size_t index) const { - SpeciesThermoInterpType* sp = m_sp[index]; + const SpeciesThermoInterpType* sp = provideSTIT(index); if (sp) { return sp->reportType(); } @@ -233,7 +245,7 @@ void GeneralSpeciesThermo::reportParams(size_t index, int& type, doublereal* const c, doublereal& minTemp_, doublereal& maxTemp_, doublereal& refPressure_) const { - SpeciesThermoInterpType* sp = m_sp[index]; + const SpeciesThermoInterpType* sp = provideSTIT(index); size_t n; if (sp) { sp->reportParameters(n, type, minTemp_, maxTemp_, @@ -252,7 +264,7 @@ doublereal GeneralSpeciesThermo::minTemp(size_t k) const if (k == npos) { return m_tlow_max; } else { - SpeciesThermoInterpType* sp = m_sp[k]; + const SpeciesThermoInterpType* sp = provideSTIT(k); if (sp) { return sp->minTemp(); } @@ -265,7 +277,7 @@ doublereal GeneralSpeciesThermo::maxTemp(size_t k) const if (k == npos) { return m_thigh_min; } else { - SpeciesThermoInterpType* sp = m_sp[k]; + const SpeciesThermoInterpType* sp = provideSTIT(k); if (sp) { return sp->maxTemp(); } @@ -278,7 +290,7 @@ doublereal GeneralSpeciesThermo::refPressure(size_t k) const if (k == npos) { return m_p0; } else { - SpeciesThermoInterpType* sp = m_sp[k]; + const SpeciesThermoInterpType* sp = provideSTIT(k); if (sp) { return sp->refPressure(); } @@ -288,12 +300,28 @@ doublereal GeneralSpeciesThermo::refPressure(size_t k) const SpeciesThermoInterpType* GeneralSpeciesThermo::provideSTIT(size_t k) { - return m_sp[k]; + try { + const std::pair& loc = getValue(m_speciesLoc, k); + return getValue(m_sp, loc.first)[loc.second]; + } catch (std::out_of_range&) { + return 0; + } } +const SpeciesThermoInterpType* GeneralSpeciesThermo::provideSTIT(size_t k) const +{ + try { + const std::pair& loc = getValue(m_speciesLoc, k); + return getValue(m_sp, loc.first)[loc.second]; + } catch (std::out_of_range&) { + return 0; + } +} + + doublereal GeneralSpeciesThermo::reportOneHf298(const size_t k) const { - SpeciesThermoInterpType* sp_ptr = m_sp[k]; + const SpeciesThermoInterpType* sp_ptr = provideSTIT(k); doublereal h = -1.0; if (sp_ptr) { h = sp_ptr->reportHf298(0); @@ -303,7 +331,7 @@ doublereal GeneralSpeciesThermo::reportOneHf298(const size_t k) const void GeneralSpeciesThermo::modifyOneHf298(const size_t k, const doublereal Hf298New) { - SpeciesThermoInterpType* sp_ptr = m_sp[k]; + SpeciesThermoInterpType* sp_ptr = provideSTIT(k); if (sp_ptr) { sp_ptr->modifyOneHf298(k, Hf298New); }