From 3f766370b9f1b6ede97191b6e30cd95a198a2f56 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sun, 15 May 2016 21:17:36 -0400 Subject: [PATCH] [Reactor] Add ReactorSurface to simplify use of surface reactions This separates the handling of interactions between reactors (mediated by Wall objects) and surfaces on which surface reactions occur (handled by ReactorSurface). This simplifies the implementation within reactor, and reduces the complexity of user code involving surface reactions by eliminating the need to set up a Reservoir object for the opposite side of a Wall object that is only being used for surface reactions. --- include/cantera/zeroD/ReactorBase.h | 8 ++ include/cantera/zeroD/ReactorSurface.h | 91 +++++++++++++++ include/cantera/zeroD/Wall.h | 27 +++-- src/zeroD/ConstPressureReactor.cpp | 17 ++- src/zeroD/Reactor.cpp | 149 +++++++++++-------------- src/zeroD/ReactorBase.cpp | 14 +++ src/zeroD/ReactorSurface.cpp | 106 ++++++++++++++++++ src/zeroD/Wall.cpp | 104 +++-------------- 8 files changed, 321 insertions(+), 195 deletions(-) create mode 100644 include/cantera/zeroD/ReactorSurface.h create mode 100644 src/zeroD/ReactorSurface.cpp diff --git a/include/cantera/zeroD/ReactorBase.h b/include/cantera/zeroD/ReactorBase.h index 56ec9b1d60..b80f199d20 100644 --- a/include/cantera/zeroD/ReactorBase.h +++ b/include/cantera/zeroD/ReactorBase.h @@ -13,6 +13,7 @@ namespace Cantera class FlowDevice; class Wall; class ReactorNet; +class ReactorSurface; const int ReservoirType = 1; const int ReactorType = 2; @@ -114,6 +115,12 @@ class ReactorBase //! Return a reference to the *n*-th Wall connected to this reactor. Wall& wall(size_t n); + void addSurface(ReactorSurface* surf); + + //! Return a reference to the *n*-th ReactorSurface connected to this + //! reactor + ReactorSurface* surface(size_t n); + /** * Initialize the reactor. Called automatically by ReactorNet::initialize. */ @@ -230,6 +237,7 @@ class ReactorBase vector_fp m_state; std::vector m_inlet, m_outlet; std::vector m_wall; + std::vector m_surfaces; vector_int m_lr; std::string m_name; diff --git a/include/cantera/zeroD/ReactorSurface.h b/include/cantera/zeroD/ReactorSurface.h new file mode 100644 index 0000000000..29ccf2e721 --- /dev/null +++ b/include/cantera/zeroD/ReactorSurface.h @@ -0,0 +1,91 @@ +//! @file ReactorSurface.h Header file for class ReactorSurface + +#ifndef CT_REACTOR_SURFACE_H +#define CT_REACTOR_SURFACE_H + +#include "cantera/zeroD/ReactorBase.h" + +namespace Cantera +{ + +class Kinetics; +class SurfPhase; + +class ReactorSurface +{ +public: + ReactorSurface(); + + //! Returns the surface area [m^2] + double area() const; + + //! Set the surface area [m^2] + void setArea(double a); + + //! Accessor for the SurfPhase object + SurfPhase* thermo() { + return m_thermo; + } + + //! Accessor for the InterfaceKinetics object + Kinetics* kinetics() { + return m_kinetics; + } + + //! Set the InterfaceKinetics object for this surface + void setKinetics(Kinetics* kin); + + //! Set the reactor that this Surface interacts with + void setReactor(ReactorBase* reactor); + + //! Number of sensitivity parameters associated with reactions on this + //! surface + size_t nSensParams() const { + return m_params.size(); + } + + //! Set the surface coverages. Array `cov` has length equal to the number of + //! surface species. + void setCoverages(const double* cov); + + //! Set the surface coverages by name + void setCoverages(const Composition& cov); + + //! Set the surface coverages by name + void setCoverages(const std::string& cov); + + //! Get the surface coverages. Array `cov` should have length equal to the + //! number of surface species. + void getCoverages(double* cov) const; + + //! Set the coverages in the surface phase object to the values for this + //! surface. + void syncCoverages(); + + //! Enable calculation of sensitivities with respect to the rate constant + //! for reaction `i`. + void addSensitivityReaction(size_t i); + + //! Set reaction rate multipliers. `params` is the global vector of + //! sensitivity parameters. This function is called within + //! ReactorNet::eval() before the reaction rates are evaluated. + void setSensitivityParameters(const double* params); + + //! Set reaction rate multipliers back to their initial values. This + //! function is called within ReactorNet::eval() after all rates have been + //! evaluated. + void resetSensitivityParameters(); + +protected: + double m_area; + + SurfPhase* m_thermo; + Kinetics* m_kinetics; + ReactorBase* m_reactor; + vector_fp m_cov; + std::vector m_params; +}; + +} + +#endif diff --git a/include/cantera/zeroD/Wall.h b/include/cantera/zeroD/Wall.h index a0f92e88e6..2703356f2b 100644 --- a/include/cantera/zeroD/Wall.h +++ b/include/cantera/zeroD/Wall.h @@ -8,6 +8,7 @@ #include "cantera/base/ctexceptions.h" #include "cantera/numerics/Func1.h" #include "cantera/zeroD/ReactorBase.h" +#include "cantera/zeroD/ReactorSurface.h" namespace Cantera { @@ -61,6 +62,8 @@ class Wall //! Set the area [m^2]. void setArea(doublereal a) { m_area = a; + m_surf[0].setArea(a); + m_surf[1].setArea(a); } //! Get the area [m^2] @@ -147,13 +150,17 @@ class Wall //! Return a pointer to the surface phase object for the left //! (`leftright=0`) or right (`leftright=1`) wall surface. SurfPhase* surface(int leftright) { - return m_surf[leftright]; + return m_surf[leftright].thermo(); + } + + ReactorSurface* reactorSurface(int leftright) { + return &m_surf[leftright]; } //! Return a pointer to the surface kinetics object for the left //! (`leftright=0`) or right (`leftright=1`) wall surface. Kinetics* kinetics(int leftright) { - return m_chem[leftright]; + return m_surf[leftright].kinetics(); } //! Set the surface coverages on the left (`leftright = 0`) or right @@ -178,11 +185,7 @@ class Wall //! Number of sensitivity parameters associated with reactions on the left //! (`lr = 0`) or right (`lr = 1`) side of the wall. size_t nSensParams(int lr) const { - if (lr == 0) { - return m_pleft.size(); - } else { - return m_pright.size(); - } + return m_surf[lr].nSensParams(); } void addSensitivityReaction(int leftright, size_t rxn); void setSensitivityParameters(double* params); @@ -191,17 +194,13 @@ class Wall protected: ReactorBase* m_left; ReactorBase* m_right; - Kinetics* m_chem[2]; - SurfPhase* m_surf[2]; - size_t m_nsp[2]; + + std::vector m_surf; + doublereal m_area, m_k, m_rrth; doublereal m_emiss; Func1* m_vf; Func1* m_qf; - vector_fp m_leftcov, m_rightcov; - - std::vector m_pleft, m_pright; - vector_fp m_leftmult_save, m_rightmult_save; }; } diff --git a/src/zeroD/ConstPressureReactor.cpp b/src/zeroD/ConstPressureReactor.cpp index 9f16a037ed..36e4cf9c7a 100644 --- a/src/zeroD/ConstPressureReactor.cpp +++ b/src/zeroD/ConstPressureReactor.cpp @@ -5,6 +5,7 @@ #include "cantera/zeroD/ConstPressureReactor.h" #include "cantera/zeroD/FlowDevice.h" #include "cantera/zeroD/Wall.h" +#include "cantera/thermo/SurfPhase.h" using namespace std; @@ -162,16 +163,12 @@ std::string ConstPressureReactor::componentName(size_t k) { } else { k -= m_thermo->nSpecies(); } - for (size_t m = 0; m < m_wall.size(); m++) { - Wall& w = *m_wall[m]; - if (w.kinetics(m_lr[m])) { - size_t kp = w.kinetics(m_lr[m])->reactionPhaseIndex(); - ThermoPhase& th = w.kinetics(m_lr[m])->thermo(kp); - if (k < th.nSpecies()) { - return th.speciesName(k); - } else { - k -= th.nSpecies(); - } + for (auto& S : m_surfaces) { + ThermoPhase* th = S->thermo(); + if (k < th->nSpecies()) { + return th->speciesName(k); + } else { + k -= th->nSpecies(); } } } diff --git a/src/zeroD/Reactor.cpp b/src/zeroD/Reactor.cpp index 261e94029d..d5622b4e9c 100644 --- a/src/zeroD/Reactor.cpp +++ b/src/zeroD/Reactor.cpp @@ -7,6 +7,7 @@ #include "cantera/zeroD/Wall.h" #include "cantera/thermo/SurfPhase.h" #include "cantera/zeroD/ReactorNet.h" +#include "cantera/zeroD/ReactorSurface.h" #include @@ -70,12 +71,9 @@ void Reactor::getState(double* y) void Reactor::getSurfaceInitialConditions(double* y) { size_t loc = 0; - for (size_t m = 0; m < m_wall.size(); m++) { - SurfPhase* surf = m_wall[m]->surface(m_lr[m]); - if (surf) { - m_wall[m]->getCoverages(m_lr[m], y + loc); - loc += surf->nSpecies(); - } + for (auto& S : m_surfaces) { + S->getCoverages(y + loc); + loc += S->thermo()->nSpecies(); } } @@ -88,31 +86,28 @@ void Reactor::initialize(doublereal t0) m_thermo->restoreState(m_state); m_sdot.resize(m_nsp, 0.0); m_wdot.resize(m_nsp, 0.0); - m_nv = m_nsp + 3; - for (size_t w = 0; w < m_wall.size(); w++) { - if (m_wall[w]->surface(m_lr[w])) { - m_nv += m_wall[w]->surface(m_lr[w])->nSpecies(); - } - } m_enthalpy = m_thermo->enthalpy_mass(); m_pressure = m_thermo->pressure(); m_intEnergy = m_thermo->intEnergy_mass(); - size_t nt = 0, maxnt = 0; - for (size_t m = 0; m < m_wall.size(); m++) { - m_wall[m]->initialize(); - if (m_wall[m]->kinetics(m_lr[m])) { - nt = m_wall[m]->kinetics(m_lr[m])->nTotalSpecies(); - maxnt = std::max(maxnt, nt); - if (m_wall[m]->kinetics(m_lr[m])) { - if (&m_kin->thermo(0) != - &m_wall[m]->kinetics(m_lr[m])->thermo(0)) { - throw CanteraError("Reactor::initialize", - "First phase of all kinetics managers must be" - " the gas."); - } - } + for (size_t n = 0; n < m_wall.size(); n++) { + Wall* W = m_wall[n]; + W->initialize(); + if (W->kinetics(m_lr[n])) { + addSurface(W->reactorSurface(m_lr[n])); + } + } + + m_nv = m_nsp + 3; + size_t maxnt = 0; + for (auto& S : m_surfaces) { + m_nv += S->thermo()->nSpecies(); + size_t nt = S->kinetics()->nTotalSpecies(); + maxnt = std::max(maxnt, nt); + if (&m_kin->thermo(0) != &S->kinetics()->thermo(0)) { + throw CanteraError("Reactor::initialize", + "First phase of all kinetics managers must be the gas."); } } m_work.resize(maxnt); @@ -121,8 +116,8 @@ void Reactor::initialize(doublereal t0) size_t Reactor::nSensParams() { size_t ns = m_sensParams.size(); - for (size_t m = 0; m < m_wall.size(); m++) { - ns += m_wall[m]->nSensParams(m_lr[m]); + for (auto& S : m_surfaces) { + ns += S->nSensParams(); } return ns; } @@ -191,12 +186,9 @@ void Reactor::updateState(doublereal* y) void Reactor::updateSurfaceState(double* y) { size_t loc = 0; - for (size_t m = 0; m < m_wall.size(); m++) { - SurfPhase* surf = m_wall[m]->surface(m_lr[m]); - if (surf) { - m_wall[m]->setCoverages(m_lr[m], y+loc); - loc += surf->nSpecies(); - } + for (auto& S : m_surfaces) { + S->setCoverages(y+loc); + loc += S->thermo()->nSpecies(); } } @@ -284,30 +276,29 @@ double Reactor::evalSurfaces(double t, double* ydot) size_t loc = 0; // offset into ydot double mdot_surf = 0.0; // net mass flux from surface - for (size_t i = 0; i < m_wall.size(); i++) { - Kinetics* kin = m_wall[i]->kinetics(m_lr[i]); - SurfPhase* surf = m_wall[i]->surface(m_lr[i]); - if (surf && kin) { - double rs0 = 1.0/surf->siteDensity(); - size_t nk = surf->nSpecies(); - double sum = 0.0; - surf->setTemperature(m_state[0]); - m_wall[i]->syncCoverages(m_lr[i]); - kin->getNetProductionRates(&m_work[0]); - size_t ns = kin->surfacePhaseIndex(); - size_t surfloc = kin->kineticsSpeciesIndex(0,ns); - for (size_t k = 1; k < nk; k++) { - ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k); - sum -= ydot[loc + k]; - } - ydot[loc] = sum; - loc += nk; + for (auto S : m_surfaces) { + Kinetics* kin = S->kinetics(); + SurfPhase* surf = S->thermo(); + + double rs0 = 1.0/surf->siteDensity(); + size_t nk = surf->nSpecies(); + double sum = 0.0; + surf->setTemperature(m_state[0]); + S->syncCoverages(); + kin->getNetProductionRates(&m_work[0]); + size_t ns = kin->surfacePhaseIndex(); + size_t surfloc = kin->kineticsSpeciesIndex(0,ns); + for (size_t k = 1; k < nk; k++) { + ydot[loc + k] = m_work[surfloc+k]*rs0*surf->size(k); + sum -= ydot[loc + k]; + } + ydot[loc] = sum; + loc += nk; - double wallarea = m_wall[i]->area(); - for (size_t k = 0; k < m_nsp; k++) { - m_sdot[k] += m_work[k]*wallarea; - mdot_surf += m_sdot[k] * mw[k]; - } + double wallarea = S->area(); + for (size_t k = 0; k < m_nsp; k++) { + m_sdot[k] += m_work[k]*wallarea; + mdot_surf += m_sdot[k] * mw[k]; } } return mdot_surf; @@ -350,18 +341,14 @@ size_t Reactor::speciesIndex(const string& nm) const } // check for a wall species - size_t walloffset = 0, kp = 0; - thermo_t* th; - for (size_t m = 0; m < m_wall.size(); m++) { - if (m_wall[m]->kinetics(m_lr[m])) { - kp = m_wall[m]->kinetics(m_lr[m])->reactionPhaseIndex(); - th = &m_wall[m]->kinetics(m_lr[m])->thermo(kp); - k = th->speciesIndex(nm); - if (k != npos) { - return k + m_nsp + walloffset; - } else { - walloffset += th->nSpecies(); - } + size_t offset = m_nsp; + for (auto& S : m_surfaces) { + ThermoPhase* th = S->thermo(); + k = th->speciesIndex(nm); + if (k != npos) { + return k + offset; + } else { + offset += th->nSpecies(); } } return npos; @@ -412,16 +399,12 @@ std::string Reactor::componentName(size_t k) { } else { k -= m_thermo->nSpecies(); } - for (size_t m = 0; m < m_wall.size(); m++) { - Wall& w = *m_wall[m]; - if (w.kinetics(m_lr[m])) { - size_t kp = w.kinetics(m_lr[m])->reactionPhaseIndex(); - ThermoPhase& th = w.kinetics(m_lr[m])->thermo(kp); - if (k < th.nSpecies()) { - return th.speciesName(k); - } else { - k -= th.nSpecies(); - } + for (auto& S : m_surfaces) { + ThermoPhase* th = S->thermo(); + if (k < th->nSpecies()) { + return th->speciesName(k); + } else { + k -= th->nSpecies(); } } } @@ -441,8 +424,8 @@ void Reactor::applySensitivity(double* params) m_thermo->modifyOneHf298SS(p.local, p.value + params[p.global]); } } - for (size_t m = 0; m < m_wall.size(); m++) { - m_wall[m]->setSensitivityParameters(params); + for (auto& S : m_surfaces) { + S->setSensitivityParameters(params); } m_thermo->invalidateCache(); m_kin->invalidateCache(); @@ -460,8 +443,8 @@ void Reactor::resetSensitivity(double* params) m_thermo->resetHf298(p.local); } } - for (size_t m = 0; m < m_wall.size(); m++) { - m_wall[m]->resetSensitivityParameters(); + for (auto& S : m_surfaces) { + S->resetSensitivityParameters(); } m_thermo->invalidateCache(); m_kin->invalidateCache(); diff --git a/src/zeroD/ReactorBase.cpp b/src/zeroD/ReactorBase.cpp index 7f05334ce6..fe1e5f5926 100644 --- a/src/zeroD/ReactorBase.cpp +++ b/src/zeroD/ReactorBase.cpp @@ -5,6 +5,7 @@ #include "cantera/zeroD/ReactorBase.h" #include "cantera/zeroD/FlowDevice.h" #include "cantera/zeroD/ReactorNet.h" +#include "cantera/zeroD/ReactorSurface.h" using namespace std; namespace Cantera @@ -67,6 +68,19 @@ Wall& ReactorBase::wall(size_t n) return *m_wall[n]; } +void ReactorBase::addSurface(ReactorSurface* surf) +{ + if (find(m_surfaces.begin(), m_surfaces.end(), surf) == m_surfaces.end()) { + m_surfaces.push_back(surf); + surf->setReactor(this); + } +} + +ReactorSurface* ReactorBase::surface(size_t n) +{ + return m_surfaces[n]; +} + ReactorNet& ReactorBase::network() { if (m_net) { diff --git a/src/zeroD/ReactorSurface.cpp b/src/zeroD/ReactorSurface.cpp new file mode 100644 index 0000000000..a861a9a4ab --- /dev/null +++ b/src/zeroD/ReactorSurface.cpp @@ -0,0 +1,106 @@ +//! @file ReactorSurface.cpp + +#include "cantera/zeroD/ReactorSurface.h" +#include "cantera/zeroD/ReactorNet.h" +#include "cantera/thermo/SurfPhase.h" +#include "cantera/kinetics/Kinetics.h" + +namespace Cantera +{ + +ReactorSurface::ReactorSurface() + : m_area(1.0) + , m_thermo(nullptr) + , m_kinetics(nullptr) + , m_reactor(nullptr) +{ +} + +double ReactorSurface::area() const +{ + return m_area; +} + +void ReactorSurface::setArea(double a) +{ + m_area = a; +} + +void ReactorSurface::setKinetics(Kinetics* kin) { + m_kinetics = kin; + if (kin == nullptr) { + m_thermo = nullptr; + return; + } + + size_t i = kin->surfacePhaseIndex(); + if (i == npos) { + throw CanteraError("ReactorSurface::setKinetics", + "Specified surface kinetics manager does not represent a surface " + "kinetics mechanism."); + } + m_thermo = dynamic_cast(&kin->thermo(i)); + m_cov.resize(m_thermo->nSpecies()); + m_thermo->getCoverages(m_cov.data()); +} + +void ReactorSurface::setReactor(ReactorBase* reactor) +{ + m_reactor = reactor; +} + +void ReactorSurface::setCoverages(const double* cov) +{ + copy(cov, cov + m_cov.size(), m_cov.begin()); +} + +void ReactorSurface::setCoverages(const Composition& cov) +{ + m_thermo->setCoveragesByName(cov); + m_thermo->getCoverages(m_cov.data()); +} + +void ReactorSurface::setCoverages(const std::string& cov) +{ + m_thermo->setCoveragesByName(cov); + m_thermo->getCoverages(m_cov.data()); +} + +void ReactorSurface::getCoverages(double* cov) const +{ + copy(m_cov.begin(), m_cov.end(), cov); +} + +void ReactorSurface::syncCoverages() +{ + m_thermo->setCoverages(m_cov.data()); +} + +void ReactorSurface::addSensitivityReaction(size_t i) +{ + if (i >= m_kinetics->nReactions()) { + throw CanteraError("ReactorSurface::addSensitivityReaction", + "Reaction number out of range ({})", i); + } + size_t p = m_reactor->network().registerSensitivityParameter( + m_kinetics->reactionString(i), 1.0, 1.0); + m_params.emplace_back( + SensitivityParameter{i, p, 1.0, SensParameterType::reaction}); +} + +void ReactorSurface::setSensitivityParameters(const double* params) +{ + for (auto& p : m_params) { + p.value = m_kinetics->multiplier(p.local); + m_kinetics->setMultiplier(p.local, p.value*params[p.global]); + } +} + +void ReactorSurface::resetSensitivityParameters() +{ + for (auto& p : m_params) { + m_kinetics->setMultiplier(p.local, p.value); + } +} + +} diff --git a/src/zeroD/Wall.cpp b/src/zeroD/Wall.cpp index 16d7ccc9cf..87ac5020b1 100644 --- a/src/zeroD/Wall.cpp +++ b/src/zeroD/Wall.cpp @@ -8,14 +8,10 @@ namespace Cantera { Wall::Wall() : m_left(0), m_right(0), + m_surf(2), m_area(1.0), m_k(0.0), m_rrth(0.0), m_emiss(0.0), m_vf(0), m_qf(0) { - for (int n = 0; n < 2; n++) { - m_chem[n] = 0; - m_surf[n] = 0; - m_nsp[n] = 0; - } } bool Wall::install(ReactorBase& rleft, ReactorBase& rright) @@ -28,37 +24,15 @@ bool Wall::install(ReactorBase& rleft, ReactorBase& rright) m_right = &rright; m_left->addWall(*this, 0); m_right->addWall(*this, 1); + m_surf[0].setReactor(&rleft); + m_surf[1].setReactor(&rright); return true; } void Wall::setKinetics(Kinetics* left, Kinetics* right) { - m_chem[0] = left; - m_chem[1] = right; - size_t ileft = 0, iright = 0; - if (left) { - ileft = left->surfacePhaseIndex(); - if (ileft != npos) { - m_surf[0] = (SurfPhase*)&left->thermo(ileft); - m_nsp[0] = m_surf[0]->nSpecies(); - m_leftcov.resize(m_nsp[0]); - m_surf[0]->getCoverages(m_leftcov.data()); - } - } - if (right) { - iright = right->surfacePhaseIndex(); - if (iright != npos) { - m_surf[1] = (SurfPhase*)&right->thermo(iright); - m_nsp[1] = m_surf[1]->nSpecies(); - m_rightcov.resize(m_nsp[1]); - m_surf[1]->getCoverages(m_rightcov.data()); - } - } - if (ileft == npos || iright == npos) { - throw CanteraError("Wall::setKinetics", - "specified surface kinetics manager does not " - "represent a surface reaction mechanism."); - } + m_surf[0].setKinetics(left); + m_surf[1].setKinetics(right); } doublereal Wall::vdot(doublereal t) @@ -88,90 +62,44 @@ doublereal Wall::Q(doublereal t) void Wall::setCoverages(int leftright, const doublereal* cov) { - if (leftright == 0) { - copy(cov, cov + m_nsp[0], m_leftcov.begin()); - } else { - copy(cov, cov + m_nsp[1], m_rightcov.begin()); - } + m_surf[leftright].setCoverages(cov); } void Wall::setCoverages(int leftright, const compositionMap& cov) { - m_surf[leftright]->setCoveragesByName(cov); - if (leftright == 0) { - m_surf[0]->getCoverages(&m_leftcov[0]); - } else { - m_surf[1]->getCoverages(&m_rightcov[0]); - } + m_surf[leftright].setCoverages(cov); } void Wall::setCoverages(int leftright, const std::string& cov) { - m_surf[leftright]->setCoveragesByName(cov); - if (leftright == 0) { - m_surf[0]->getCoverages(&m_leftcov[0]); - } else { - m_surf[1]->getCoverages(&m_rightcov[0]); - } + m_surf[leftright].setCoverages(cov); } void Wall::getCoverages(int leftright, doublereal* cov) { - if (leftright == 0) { - copy(m_leftcov.begin(), m_leftcov.end(), cov); - } else { - copy(m_rightcov.begin(), m_rightcov.end(), cov); - } + m_surf[leftright].getCoverages(cov); } void Wall::syncCoverages(int leftright) { - if (leftright == 0) { - m_surf[0]->setCoverages(m_leftcov.data()); - } else { - m_surf[1]->setCoverages(m_rightcov.data()); - } + m_surf[leftright].syncCoverages(); } void Wall::addSensitivityReaction(int leftright, size_t rxn) { - if (rxn >= m_chem[leftright]->nReactions()) { - throw CanteraError("Wall::addSensitivityReaction", - "Reaction number out of range ({})", rxn); - } - if (leftright == 0) { - size_t p = m_left->network().registerSensitivityParameter( - m_chem[0]->reactionString(rxn), 1.0, 1.0); - m_pleft.emplace_back( - SensitivityParameter{rxn, p, 1.0, SensParameterType::reaction}); - } else { - size_t p = m_right->network().registerSensitivityParameter( - m_chem[1]->reactionString(rxn), 1.0, 1.0); - m_pright.emplace_back( - SensitivityParameter{rxn, p, 1.0, SensParameterType::reaction}); - } + m_surf[leftright].addSensitivityReaction(rxn); } void Wall::setSensitivityParameters(double* params) { - // process sensitivity parameters - for (auto& p : m_pleft) { - p.value = m_chem[0]->multiplier(p.local); - m_chem[0]->setMultiplier(p.local, p.value*params[p.global]); - } - for (auto& p : m_pright) { - p.value = m_chem[1]->multiplier(p.local); - m_chem[1]->setMultiplier(p.local, p.value*params[p.global]); - } + m_surf[0].setSensitivityParameters(params); + m_surf[1].setSensitivityParameters(params); } void Wall::resetSensitivityParameters() { - for (auto& p : m_pleft) { - m_chem[0]->setMultiplier(p.local, p.value); - } - for (auto& p : m_pright) { - m_chem[1]->setMultiplier(p.local, p.value); - } + m_surf[0].resetSensitivityParameters(); + m_surf[1].resetSensitivityParameters(); } + }