Skip to content

Commit

Permalink
Ensure registration of extension rates in host Cantera library
Browse files Browse the repository at this point in the history
If a user application is linked statically to the Cantera library,
ExtensibleRate objects need to be registered in this copy of the Cantera
library rather than the one that is embedded in the Python module.
This is achieved by accessing the ReactionRateFactory from the main
application rather than from the Python module.
  • Loading branch information
speth committed Sep 11, 2022
1 parent 242a4fe commit 82a76e8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 0 deletions.
11 changes: 11 additions & 0 deletions interfaces/cython/cantera/delegator.pyx
Expand Up @@ -328,6 +328,11 @@ cdef int assign_delegates(obj, CxxDelegator* delegator) except -1:

return 0

# Specifications for ReactionRate delegators that have not yet been registered with
# ReactionRateFactory. This list is read by PythonExtensionManager::registerRateBuilders
# and then cleared.
_rate_delegators = []

def extension(*, name):
"""
A decorator for declaring Cantera extensions that should be registered with
Expand Down Expand Up @@ -371,8 +376,14 @@ def extension(*, name):
def decorator(cls):
if issubclass(cls, ExtensibleRate):
cls._reaction_rate_type = name
# Registering immediately supports the case where the main
# application is Python
CxxPythonExtensionManager.registerPythonRateBuilder(
stringify(cls.__module__), stringify(cls.__name__), stringify(name))

# Deferred registration supports the case where the main application
# is not Python
_rate_delegators.append((cls.__module__, cls.__name__, name))
else:
raise TypeError(f"{cls} is not extensible")
return cls
Expand Down
1 change: 1 addition & 0 deletions src/extensions/PythonExtensionManager.cpp
Expand Up @@ -144,6 +144,7 @@ void PythonExtensionManager::registerRateBuilders(const string& extensionName)
throw CanteraError("PythonExtensionManager::registerRateBuilders",
"Problem loading module:\n{}", getPythonExceptionInfo());
}
ct_registerReactionDelegators();
}

void PythonExtensionManager::registerPythonRateBuilder(
Expand Down
15 changes: 15 additions & 0 deletions src/extensions/pythonExtensions.pyx
Expand Up @@ -13,6 +13,7 @@ import importlib
import inspect

import cantera as ct
from cantera._utils cimport stringify
from cantera.reaction cimport ExtensibleRate, CxxReactionRate
from cantera.delegator cimport CxxDelegator, assign_delegates

Expand All @@ -22,6 +23,12 @@ cdef extern from "cantera/kinetics/ReactionRateDelegator.h" namespace "Cantera":
CxxReactionRateDelegator()


cdef extern from "cantera/extensions/PythonExtensionManager.h" namespace "Cantera":
cdef cppclass CxxPythonExtensionManager "Cantera::PythonExtensionManager":
@staticmethod
void registerPythonRateBuilder(string&, string&, string&)


cdef public char* ct_getExceptionString(object exType, object exValue, object exTraceback):
import traceback
result = str(exValue) + "\n\n"
Expand All @@ -40,3 +47,11 @@ cdef public object ct_newPythonExtensibleRate(CxxReactionRateDelegator* delegato
cdef ExtensibleRate rate = getattr(mod, class_name.decode())(init=False)
rate.set_cxx_object(delegator)
return rate


cdef public ct_registerReactionDelegators():
for module, cls, name in ct.delegator._rate_delegators:
CxxPythonExtensionManager.registerPythonRateBuilder(
stringify(module), stringify(cls), stringify(name))

ct.delegator._rate_delegators.clear()

0 comments on commit 82a76e8

Please sign in to comment.