[Reactor] Add componentName function to ReactorNet and Reactor classes
This commit is contained in:
parent
3a129677df
commit
8ff82c06ce
13 changed files with 145 additions and 5 deletions
|
|
@ -43,6 +43,7 @@ public:
|
||||||
//! the name of a homogeneous phase species, or the name of a surface
|
//! the name of a homogeneous phase species, or the name of a surface
|
||||||
//! species.
|
//! species.
|
||||||
virtual size_t componentIndex(const std::string& nm) const;
|
virtual size_t componentIndex(const std::string& nm) const;
|
||||||
|
std::string componentName(size_t k);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ public:
|
||||||
//! "temperature", the name of a homogeneous phase species, or the name of a
|
//! "temperature", the name of a homogeneous phase species, or the name of a
|
||||||
//! surface species.
|
//! surface species.
|
||||||
virtual size_t componentIndex(const std::string& nm) const;
|
virtual size_t componentIndex(const std::string& nm) const;
|
||||||
|
std::string componentName(size_t k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector_fp m_hk; //!< Species molar enthalpies
|
vector_fp m_hk; //!< Species molar enthalpies
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ public:
|
||||||
//! "volume", "temperature", the name of a homogeneous phase species, or the
|
//! "volume", "temperature", the name of a homogeneous phase species, or the
|
||||||
//! name of a surface species.
|
//! name of a surface species.
|
||||||
virtual size_t componentIndex(const std::string& nm) const;
|
virtual size_t componentIndex(const std::string& nm) const;
|
||||||
|
std::string componentName(size_t k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
vector_fp m_uk; //!< Species molar internal energies
|
vector_fp m_uk; //!< Species molar internal energies
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ public:
|
||||||
|
|
||||||
//! Number of equations (state variables) for this reactor
|
//! Number of equations (state variables) for this reactor
|
||||||
virtual size_t neq() {
|
virtual size_t neq() {
|
||||||
|
if (!m_nv) {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
return m_nv;
|
return m_nv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,6 +139,10 @@ public:
|
||||||
//! surface species.
|
//! surface species.
|
||||||
virtual size_t componentIndex(const std::string& nm) const;
|
virtual size_t componentIndex(const std::string& nm) const;
|
||||||
|
|
||||||
|
//! Return the name of the solution component with index *i*.
|
||||||
|
//! @see componentIndex()
|
||||||
|
virtual std::string componentName(size_t k);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//! Set reaction rate multipliers based on the sensitivity variables in
|
//! Set reaction rate multipliers based on the sensitivity variables in
|
||||||
//! *params*.
|
//! *params*.
|
||||||
|
|
|
||||||
|
|
@ -174,6 +174,11 @@ public:
|
||||||
//! reactor network.
|
//! reactor network.
|
||||||
size_t globalComponentIndex(const std::string& component, size_t reactor=0);
|
size_t globalComponentIndex(const std::string& component, size_t reactor=0);
|
||||||
|
|
||||||
|
//! Return the name of the i-th component of the global state vector. The
|
||||||
|
//! name returned includes both the name of the reactor and the specific
|
||||||
|
//! component, e.g. `'reactor1: CH4'`.
|
||||||
|
std::string componentName(size_t i) const;
|
||||||
|
|
||||||
//! Used by Reactor and Wall objects to register the addition of
|
//! Used by Reactor and Wall objects to register the addition of
|
||||||
//! sensitivity parameters so that the ReactorNet can keep track of the
|
//! sensitivity parameters so that the ReactorNet can keep track of the
|
||||||
//! order in which sensitivity parameters are added.
|
//! order in which sensitivity parameters are added.
|
||||||
|
|
|
||||||
|
|
@ -487,6 +487,7 @@ cdef extern from "cantera/zeroD/Reactor.h":
|
||||||
void setEnergy(int)
|
void setEnergy(int)
|
||||||
cbool energyEnabled()
|
cbool energyEnabled()
|
||||||
size_t componentIndex(string&)
|
size_t componentIndex(string&)
|
||||||
|
string componentName(size_t) except +
|
||||||
size_t neq()
|
size_t neq()
|
||||||
void getState(double*)
|
void getState(double*)
|
||||||
|
|
||||||
|
|
@ -566,6 +567,7 @@ cdef extern from "cantera/zeroD/ReactorNet.h":
|
||||||
void setVerbose(cbool)
|
void setVerbose(cbool)
|
||||||
size_t neq()
|
size_t neq()
|
||||||
void getState(double*)
|
void getState(double*)
|
||||||
|
string componentName(size_t) except +
|
||||||
|
|
||||||
void setSensitivityTolerances(double, double)
|
void setSensitivityTolerances(double, double)
|
||||||
double rtolSensitivity()
|
double rtolSensitivity()
|
||||||
|
|
|
||||||
|
|
@ -233,9 +233,9 @@ cdef class Reactor(ReactorBase):
|
||||||
"""
|
"""
|
||||||
Returns the index of the component named *name* in the system. This
|
Returns the index of the component named *name* in the system. This
|
||||||
determines the (relative) index of the component in the vector of
|
determines the (relative) index of the component in the vector of
|
||||||
sensitivity coefficients. *name* is either a species name or the name
|
sensitivity coefficients. *name* is either a species name or the name of
|
||||||
of a reactor state variable, e.g. 'U', 'T', depending on the reactor's
|
a reactor state variable, e.g. 'int_energy', 'temperature', depending on
|
||||||
equations.
|
the reactor's equations.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
k = self.reactor.componentIndex(stringify(name))
|
k = self.reactor.componentIndex(stringify(name))
|
||||||
|
|
@ -243,6 +243,14 @@ cdef class Reactor(ReactorBase):
|
||||||
raise IndexError('No such component: {!r}'.format(name))
|
raise IndexError('No such component: {!r}'.format(name))
|
||||||
return k
|
return k
|
||||||
|
|
||||||
|
def component_name(self, int i):
|
||||||
|
"""
|
||||||
|
Returns the name of the component with index *i* within the array of
|
||||||
|
variables returned by `get_state`. This is the inverse of
|
||||||
|
`component_index`.
|
||||||
|
"""
|
||||||
|
return pystr(self.reactor.componentName(i))
|
||||||
|
|
||||||
property n_vars:
|
property n_vars:
|
||||||
"""
|
"""
|
||||||
The number of state variables in the reactor.
|
The number of state variables in the reactor.
|
||||||
|
|
@ -276,8 +284,9 @@ cdef class Reactor(ReactorBase):
|
||||||
- 1 - enthalpy or temperature
|
- 1 - enthalpy or temperature
|
||||||
- 2+ - mass fractions of the species
|
- 2+ - mass fractions of the species
|
||||||
|
|
||||||
You can use the function `component_index` to determine the location
|
You can use the function `component_index` to determine the location of
|
||||||
of a specific component
|
a specific component from its name, or `component_name` to determine the
|
||||||
|
name from the index.
|
||||||
"""
|
"""
|
||||||
if not self.n_vars:
|
if not self.n_vars:
|
||||||
raise Exception('Reactor empty or network not initialized.')
|
raise Exception('Reactor empty or network not initialized.')
|
||||||
|
|
@ -908,6 +917,14 @@ cdef class ReactorNet:
|
||||||
def __set__(self, pybool v):
|
def __set__(self, pybool v):
|
||||||
self.net.setVerbose(v)
|
self.net.setVerbose(v)
|
||||||
|
|
||||||
|
def component_name(self, int i):
|
||||||
|
"""
|
||||||
|
Return the name of the i-th component of the global state vector. The
|
||||||
|
name returned includes both the name of the reactor and the specific
|
||||||
|
component, e.g. `'reactor1: CH4'`.
|
||||||
|
"""
|
||||||
|
return pystr(self.net.componentName(i))
|
||||||
|
|
||||||
def sensitivity(self, component, int p, int r=0):
|
def sensitivity(self, component, int p, int r=0):
|
||||||
"""
|
"""
|
||||||
Returns the sensitivity of the solution variable *component* in
|
Returns the sensitivity of the solution variable *component* in
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,16 @@ class TestReactor(utilities.CanteraTest):
|
||||||
for i, name in enumerate(self.gas1.species_names):
|
for i, name in enumerate(self.gas1.species_names):
|
||||||
self.assertEqual(i + N0, self.r1.component_index(name))
|
self.assertEqual(i + N0, self.r1.component_index(name))
|
||||||
|
|
||||||
|
def test_component_names(self):
|
||||||
|
self.make_reactors(n_reactors=2)
|
||||||
|
N = self.net.n_vars // 2
|
||||||
|
for i in range(N):
|
||||||
|
self.assertEqual(self.r1.component_index(self.r1.component_name(i)), i)
|
||||||
|
self.assertEqual(self.net.component_name(i),
|
||||||
|
'{}: {}'.format(self.r1.name, self.r1.component_name(i)))
|
||||||
|
self.assertEqual(self.net.component_name(N+i),
|
||||||
|
'{}: {}'.format(self.r2.name, self.r2.component_name(i)))
|
||||||
|
|
||||||
def test_disjoint(self):
|
def test_disjoint(self):
|
||||||
T1, P1 = 300, 101325
|
T1, P1 = 300, 101325
|
||||||
T2, P2 = 500, 300000
|
T2, P2 = 500, 300000
|
||||||
|
|
@ -757,6 +767,13 @@ class TestConstPressureReactor(utilities.CanteraTest):
|
||||||
for i, name in enumerate(iface.species_names):
|
for i, name in enumerate(iface.species_names):
|
||||||
self.assertEqual(i + N1, r.component_index(name))
|
self.assertEqual(i + N1, r.component_index(name))
|
||||||
|
|
||||||
|
def test_component_names(self):
|
||||||
|
self.create_reactors(add_surf=True)
|
||||||
|
for i in range(self.net1.n_vars):
|
||||||
|
self.assertEqual(self.r1.component_index(self.r1.component_name(i)), i)
|
||||||
|
self.assertEqual(self.net1.component_name(i),
|
||||||
|
'{}: {}'.format(self.r1.name, self.r1.component_name(i)))
|
||||||
|
|
||||||
def integrate(self, surf=False):
|
def integrate(self, surf=False):
|
||||||
for t in np.arange(0.5, 50, 1.0):
|
for t in np.arange(0.5, 50, 1.0):
|
||||||
self.net1.advance(t)
|
self.net1.advance(t)
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include "cantera/zeroD/ConstPressureReactor.h"
|
#include "cantera/zeroD/ConstPressureReactor.h"
|
||||||
#include "cantera/zeroD/FlowDevice.h"
|
#include "cantera/zeroD/FlowDevice.h"
|
||||||
|
#include "cantera/zeroD/Wall.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
|
@ -149,4 +150,33 @@ size_t ConstPressureReactor::componentIndex(const string& nm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ConstPressureReactor::componentName(size_t k) {
|
||||||
|
if (k == 0) {
|
||||||
|
return "mass";
|
||||||
|
} else if (k == 1) {
|
||||||
|
return "enthalpy";
|
||||||
|
} else if (k >= 2 && k < neq()) {
|
||||||
|
k -= 2;
|
||||||
|
if (k < m_thermo->nSpecies()) {
|
||||||
|
return m_thermo->speciesName(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw CanteraError("ConstPressureReactor::componentName",
|
||||||
|
"Index is out of bounds.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -161,4 +161,12 @@ size_t IdealGasConstPressureReactor::componentIndex(const string& nm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string IdealGasConstPressureReactor::componentName(size_t k) {
|
||||||
|
if (k == 1) {
|
||||||
|
return "temperature";
|
||||||
|
} else {
|
||||||
|
return ConstPressureReactor::componentName(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -176,4 +176,13 @@ size_t IdealGasReactor::componentIndex(const string& nm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string IdealGasReactor::componentName(size_t k) {
|
||||||
|
if (k == 2) {
|
||||||
|
return "temperature";
|
||||||
|
} else {
|
||||||
|
return Reactor::componentName(k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -398,6 +398,36 @@ size_t Reactor::componentIndex(const string& nm) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Reactor::componentName(size_t k) {
|
||||||
|
if (k == 0) {
|
||||||
|
return "mass";
|
||||||
|
} else if (k == 1) {
|
||||||
|
return "volume";
|
||||||
|
} else if (k == 2) {
|
||||||
|
return "int_energy";
|
||||||
|
} else if (k >= 3 && k < neq()) {
|
||||||
|
k -= 3;
|
||||||
|
if (k < m_thermo->nSpecies()) {
|
||||||
|
return m_thermo->speciesName(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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw CanteraError("Reactor::componentName", "Index is out of bounds.");
|
||||||
|
}
|
||||||
|
|
||||||
void Reactor::applySensitivity(double* params)
|
void Reactor::applySensitivity(double* params)
|
||||||
{
|
{
|
||||||
if (!params) {
|
if (!params) {
|
||||||
|
|
|
||||||
|
|
@ -242,6 +242,18 @@ size_t ReactorNet::globalComponentIndex(const string& component, size_t reactor)
|
||||||
return m_start[reactor] + m_reactors[reactor]->componentIndex(component);
|
return m_start[reactor] + m_reactors[reactor]->componentIndex(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ReactorNet::componentName(size_t i) const
|
||||||
|
{
|
||||||
|
for (auto r : m_reactors) {
|
||||||
|
if (i < r->neq()) {
|
||||||
|
return r->name() + ": " + r->componentName(i);
|
||||||
|
} else {
|
||||||
|
i -= r->neq();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw CanteraError("ReactorNet::componentName", "Index out of bounds");
|
||||||
|
}
|
||||||
|
|
||||||
size_t ReactorNet::registerSensitivityParameter(
|
size_t ReactorNet::registerSensitivityParameter(
|
||||||
const std::string& name, double value, double scale)
|
const std::string& name, double value, double scale)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue