Skip to content

Commit 0afed91

Browse files
anthony-walkerspeth
authored andcommitted
Add a default evaluation function for reactors
It can sometimes be useful to add on to the default evaluation in such a way that the standard before or after delegations cannot handle. A default evaluation function allows for this.
1 parent 3f36650 commit 0afed91

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

include/cantera/zeroD/ReactorDelegator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ class ReactorAccessor
5252
//! Set the state of the thermo object for surface *n* to correspond to the
5353
//! state of that surface
5454
virtual void restoreSurfaceState(size_t n) = 0;
55+
56+
//! Public access to the default evaluation function so it can be used in
57+
//! replace functions
58+
virtual void defaultEval(double t, double* LHS, double* RHS) = 0;
5559
};
5660

5761
//! Delegate methods of the Reactor class to external functions
@@ -167,6 +171,10 @@ class ReactorDelegator : public Delegator, public R, public ReactorAccessor
167171
m_build_jacobian(jacVector);
168172
}
169173

174+
void defaultEval(double t, double* LHS, double* RHS) override {
175+
R::eval(t, LHS, RHS);
176+
}
177+
170178
// Public access to protected Reactor variables needed by derived classes
171179

172180
void setNEq(size_t n) override {

interfaces/cython/cantera/reactor.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ cdef extern from "cantera/zeroD/ReactorDelegator.h" namespace "Cantera":
222222
void setHeatRate(double)
223223
void restoreThermoState() except +translate_exception
224224
void restoreSurfaceState(size_t) except +translate_exception
225+
void defaultEval(double time, double* LHS, double* RHS)
225226

226227

227228
ctypedef CxxReactorAccessor* CxxReactorAccessorPtr

interfaces/cython/cantera/reactor.pyx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
# at https://cantera.org/license.txt for license and copyright information.
33

44
import warnings
5+
import numpy as np
6+
from collections import defaultdict as _defaultdict
57
import numbers as _numbers
68
from cython.operator cimport dereference as deref
79

@@ -713,6 +715,16 @@ cdef class ExtensibleReactor(Reactor):
713715
"""
714716
self.accessor.restoreSurfaceState(n)
715717

718+
def default_eval(self, time, LHS, RHS):
719+
"""
720+
Evaluation of the base reactors `eval` function to be used in `replace`
721+
functions and maintain original functionality.
722+
"""
723+
assert len(LHS) == self.n_vars and len(RHS) == self.n_vars
724+
cdef np.ndarray[np.double_t, ndim=1, mode="c"] rhs = np.frombuffer(RHS)
725+
cdef np.ndarray[np.double_t, ndim=1, mode="c"] lhs = np.frombuffer(LHS)
726+
self.accessor.defaultEval(time, &lhs[0], &rhs[0])
727+
716728

717729
cdef class ExtensibleIdealGasReactor(ExtensibleReactor):
718730
"""

test/python/test_reactor.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,6 +3327,29 @@ def replace_build_jacobian(self, jac_vector):
33273327
jac = r.jacobian
33283328
assert np.sum(jac) == 0
33293329

3330+
def test_replace_with_default_eval(self):
3331+
class ReplaceEvalReactor(ct.ExtensibleIdealGasConstPressureMoleReactor):
3332+
3333+
def replace_eval(self, t, LHS, RHS):
3334+
self.default_eval(t, LHS, RHS)
3335+
3336+
# setup thermo object
3337+
gas = ct.Solution("h2o2.yaml", "ohmech")
3338+
gas.set_equivalence_ratio(0.5, "H2:1.0", "O2:1.0")
3339+
gas.equilibrate("HP")
3340+
# replacement reactor
3341+
r = ReplaceEvalReactor(gas)
3342+
r.volume = 1.0
3343+
# default reactor
3344+
rstd = ct.IdealGasConstPressureMoleReactor(gas)
3345+
rstd.volume = r.volume
3346+
# network of both reactors
3347+
net = ct.ReactorNet([r, rstd])
3348+
net.preconditioner = ct.AdaptivePreconditioner()
3349+
net.advance_to_steady_state()
3350+
# reactors should have the same solution because the default is used
3351+
self.assertArrayNear(r.get_state(), rstd.get_state())
3352+
33303353

33313354
class TestSteadySolver:
33323355
@pytest.mark.parametrize("reactor_class",

0 commit comments

Comments
 (0)