Skip to content

Commit

Permalink
Add a default evaluation function for reactors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
anthony-walker committed Feb 8, 2024
1 parent d71543f commit 9a2d1b2
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 0 deletions.
8 changes: 8 additions & 0 deletions include/cantera/zeroD/ReactorDelegator.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ class ReactorAccessor
//! Set the state of the thermo object for surface *n* to correspond to the
//! state of that surface
virtual void restoreSurfaceState(size_t n) = 0;

//! Public access to the default evaluation function so it can be used in
//! replace functions
virtual void defaultEval(double t, double* LHS, double* RHS) = 0;
};

//! Delegate methods of the Reactor class to external functions
Expand Down Expand Up @@ -161,6 +165,10 @@ class ReactorDelegator : public Delegator, public R, public ReactorAccessor
m_build_jacobian(jacVector);
}

void defaultEval(double t, double* LHS, double* RHS) override {
R::eval(t, LHS, RHS);
}

// Public access to protected Reactor variables needed by derived classes

void setNEq(size_t n) override {
Expand Down
1 change: 1 addition & 0 deletions interfaces/cython/cantera/reactor.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ cdef extern from "cantera/zeroD/ReactorDelegator.h" namespace "Cantera":
void setHeatRate(double)
void restoreThermoState() except +translate_exception
void restoreSurfaceState(size_t) except +translate_exception
void defaultEval(double time, double* LHS, double* RHS)


ctypedef CxxReactorAccessor* CxxReactorAccessorPtr
Expand Down
11 changes: 11 additions & 0 deletions interfaces/cython/cantera/reactor.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# at https://cantera.org/license.txt for license and copyright information.

import warnings
import numpy as np
from collections import defaultdict as _defaultdict
import numbers as _numbers
from cython.operator cimport dereference as deref
Expand Down Expand Up @@ -738,6 +739,16 @@ cdef class ExtensibleReactor(Reactor):
"""
self.accessor.restoreSurfaceState(n)

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


cdef class ExtensibleIdealGasReactor(ExtensibleReactor):
"""
Expand Down
23 changes: 23 additions & 0 deletions test/python/test_reactor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3250,3 +3250,26 @@ def replace_build_jacobian(self, jac_vector):
# test that jacobian wall element is hard coded value
jac = r.jacobian
assert np.sum(jac) == 0

def test_replace_with_default_eval(self):
class ReplaceEvalReactor(ct.ExtensibleIdealGasConstPressureMoleReactor):

def replace_eval(self, t, LHS, RHS):
self.default_eval(t, LHS, RHS)

# setup thermo object
gas = ct.Solution("h2o2.yaml", "ohmech")
gas.set_equivalence_ratio(0.5, "H2:1.0", "O2:1.0")
gas.equilibrate("HP")
# replacement reactor
r = ReplaceEvalReactor(gas)
r.volume = 1.0
# default reactor
rstd = ct.IdealGasConstPressureMoleReactor(gas)
rstd.volume = r.volume
# network of both reactors
net = ct.ReactorNet([r, rstd])
net.preconditioner = ct.AdaptivePreconditioner()
net.advance_to_steady_state()
# reactors should have the same solution because the default is used
self.assertArrayNear(r.get_state(), rstd.get_state())

0 comments on commit 9a2d1b2

Please sign in to comment.