From d12a88dbd1e2f5373b20bc815fae6c33153ef6e7 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Tue, 30 Aug 2022 18:07:29 -0400 Subject: [PATCH] Add more documentation for ExtensibleRate --- doc/sphinx/cython/kinetics.rst | 5 +++ doc/sphinx/cython/utilities.rst | 2 + .../cantera/kinetics/ReactionRateDelegator.h | 5 +++ interfaces/cython/cantera/delegator.pyx | 35 +++++++++++++++++ interfaces/cython/cantera/reaction.pyx | 38 ++++++++++++++++++- interfaces/cython/cantera/reactor.pyx | 2 +- 6 files changed, 84 insertions(+), 3 deletions(-) diff --git a/doc/sphinx/cython/kinetics.rst b/doc/sphinx/cython/kinetics.rst index c3ac82816c7..96b4068d5ff 100644 --- a/doc/sphinx/cython/kinetics.rst +++ b/doc/sphinx/cython/kinetics.rst @@ -116,6 +116,11 @@ CustomRate .. autoclass:: CustomRate(k) :no-undoc-members: +ExtensibleRate +^^^^^^^^^^^^^^ +.. autoclass:: ExtensibleRate() + :no-undoc-members: + InterfaceRateBase ^^^^^^^^^^^^^^^^^ .. autoclass:: InterfaceRateBase diff --git a/doc/sphinx/cython/utilities.rst b/doc/sphinx/cython/utilities.rst index b78564b2e2a..393c85a5622 100644 --- a/doc/sphinx/cython/utilities.rst +++ b/doc/sphinx/cython/utilities.rst @@ -43,6 +43,8 @@ Global Functions .. autofunction:: debug_mode_enabled .. autofunction:: add_module_directory +.. autofunction:: extension + Exceptions ---------- diff --git a/include/cantera/kinetics/ReactionRateDelegator.h b/include/cantera/kinetics/ReactionRateDelegator.h index fbf1eab5513..b77c2f3f8c6 100644 --- a/include/cantera/kinetics/ReactionRateDelegator.h +++ b/include/cantera/kinetics/ReactionRateDelegator.h @@ -13,6 +13,7 @@ namespace Cantera { +//! Delegate methods of the ReactionRate class to external functions class ReactionRateDelegator : public Delegator, public ReactionRate { public: @@ -40,6 +41,7 @@ class ReactionRateDelegator : public Delegator, public ReactionRate new MultiRate); } + //! Set the reaction type based on the user-provided reaction rate parameterization void setType(const std::string& type) { m_rateType = type; } @@ -50,6 +52,9 @@ class ReactionRateDelegator : public Delegator, public ReactionRate // Delegatable methods + //! Evaluate reaction rate + //! + //! @param shared_data data shared by all reactions of a given type double evalFromStruct(const ArrheniusData& shared_data) { // @TODO: replace passing pointer to temperature with a language-specific // wrapper of the ReactionData object diff --git a/interfaces/cython/cantera/delegator.pyx b/interfaces/cython/cantera/delegator.pyx index 9189c12e7f9..1c50dddc1c1 100644 --- a/interfaces/cython/cantera/delegator.pyx +++ b/interfaces/cython/cantera/delegator.pyx @@ -332,6 +332,41 @@ def extension(*, name): """ A decorator for declaring Cantera extensions that should be registered with the corresponding factory classes to create objects with the specified *name*. + + This decorator can be used in combination with an ``extensions`` section in a YAML + input file to trigger registration of extensions marked with this decorator, + For example, consider an input file containing top level ``extensions`` and + ``reactions`` sections such as: + + .. code:: yaml + + extensions: + - type: python + name: cool_module + + ... # phases and species sections + + reactions: + - equation: O + H2 <=> H + OH # Reaction 3 + type: cool-rate + A: 3.87e+04 + b: 2.7 + Ea: 6260.0 + + and a Python module ``cool_module.py``:: + + import cantera as ct + + @ct.extension(name="cool-rate") + class CoolRate(ct.ExtensibleRate): + def after_set_parameters(self, params, units): + ... + def replace_eval(self, T): + ... + + Loading this input file from any Cantera user interface would cause Cantera to load + the ``cool_module.py`` module and register the ``CoolRate`` class to handle + reactions whose ``type`` in the YAML file is set to ``cool-rate``. """ def decorator(cls): if issubclass(cls, ExtensibleRate): diff --git a/interfaces/cython/cantera/reaction.pyx b/interfaces/cython/cantera/reaction.pyx index 50b051c5d1a..9e3c37c102a 100644 --- a/interfaces/cython/cantera/reaction.pyx +++ b/interfaces/cython/cantera/reaction.pyx @@ -712,7 +712,41 @@ cdef class CustomRate(ReactionRate): cdef class ExtensibleRate(ReactionRate): - _reaction_rate_type = "extensible" + """ + A base class for a reaction rate with delegated methods. Classes derived from this + class should be decorated with the `extension` decorator to specify the name + of the rate parameterization and to make these rates constructible through factory + functions and input files. + + The following methods of the C++ :ct:`ReactionRate` class can be modified by a + Python class that inherits from this class. For each method, the name below should + be prefixed with ``before_``, ``after_``, or ``replace_``, indicating whether this + method should be called before, after, or instead of the corresponding method from + the base class. + + For methods that return a value and have a ``before`` method specified, if that + method returns a value other than ``None`` that value will be returned without + calling the base class method; otherwise, the value from the base class method will + be returned. For methods that return a value and have an ``after`` method specified, + the returned value wil be the sum of the values from the supplied method and the + base class method. + + ``set_parameters(self, params: dict, units: Units) -> None`` + Responsible for setting rate parameters based on the input data. For example, + for reactions created from YAML, ``params`` is the YAML reaction entry converted + to a ``dict``. ``units`` specifies the units of the rate coefficient. + + ``eval(self, T: float) -> float`` + Responsible for calculating the forward rate constant based on the current state + of the phase. This method must *replace* the base class method, as there is no + base class implementation. Currently, the state information provided is the + temperature, ``T`` [K]. + + **Warning:** The delegatable methods defined here are an experimental part of the + Cantera API and may change without notice. + """ + + _reaction_rate_type = "undefined-extensible" delegatable_methods = { "eval": ("evalFromStruct", "double(void*)"), @@ -727,7 +761,7 @@ cdef class ExtensibleRate(ReactionRate): if self._rate.get() is not NULL: assign_delegates(self, dynamic_cast[CxxDelegatorPtr](self.rate)) - if self._reaction_rate_type == "extensible": + if self._reaction_rate_type == "undefined-extensible": raise NotImplementedError(f"{self.__class__} does not have a rate name specified") # ReactionRate does not define __init__, so it does not need to be called diff --git a/interfaces/cython/cantera/reactor.pyx b/interfaces/cython/cantera/reactor.pyx index 45772f5c938..33fb9a046ae 100644 --- a/interfaces/cython/cantera/reactor.pyx +++ b/interfaces/cython/cantera/reactor.pyx @@ -449,7 +449,7 @@ cdef class ExtensibleReactor(Reactor): The following methods of the C++ :ct:`Reactor` class can be modified by a Python class which inherits from this class. For each method, the name below should be prefixed with ``before_``, ``after_``, or ``replace_``, indicating - whether the this method should be called before, after, or instead of the + whether this method should be called before, after, or instead of the corresponding method from the base class. For methods that return a value and have a ``before`` method specified, if