[Python] Add access to properties of simple reaction types

This includes ElementaryReaction and ThirdBodyReaction
This commit is contained in:
Ray Speth 2015-04-22 18:16:13 -04:00
parent af93dc774d
commit bbe2e1c79b
8 changed files with 214 additions and 10 deletions

View file

@ -806,6 +806,11 @@ public:
*/
virtual void addReaction(shared_ptr<Reaction> r);
/**
* Return the Reaction object for reaction *i*.
*/
shared_ptr<Reaction> reaction(size_t i);
//! Determine behavior when adding a new reaction that contains species not
//! defined in any of the phases associated with this kinetics manager. If
//! set to true, the reaction will silently be ignored. If false, (the

View file

@ -190,6 +190,51 @@ cdef extern from "cantera/thermo/SurfPhase.h":
void getCoverages(double*) except +
cdef extern from "cantera/kinetics/Reaction.h" namespace "Cantera":
cdef cppclass CxxArrhenius "Cantera::Arrhenius":
CxxArrhenius()
CxxArrhenius(double, double, double)
double updateRC(double, double)
double preExponentialFactor()
double temperatureExponent()
double activationEnergy_R()
cdef cppclass CxxReaction "Cantera::Reaction":
# Note, this default constructor doesn't actually exist. The declaration
# is required by a Cython bug which should be resolved in Cython 0.22.
CxxReaction()
CxxReaction(int)
string reactantString()
string productString()
string equation()
void validate() except +
int reaction_type
Composition reactants
Composition products
Composition orders
string id
cbool reversible
cbool duplicate
cbool allow_nonreactant_orders
cbool allow_negative_orders
cdef cppclass CxxElementaryReaction "Cantera::ElementaryReaction" (CxxReaction):
CxxElementaryReaction()
CxxArrhenius rate
cbool allow_negative_pre_exponential_factor
cdef cppclass CxxThirdBody "Cantera::ThirdBody":
CxxThirdBody()
CxxThirdBody(double)
double efficiency(string)
Composition efficiencies
double default_efficiency
cdef cppclass CxxThirdBodyReaction "Cantera::ThirdBodyReaction" (CxxElementaryReaction):
CxxThirdBodyReaction()
CxxThirdBody third_body
cdef extern from "cantera/kinetics/Kinetics.h" namespace "Cantera":
cdef cppclass CxxKinetics "Cantera::Kinetics":
CxxKinetics()
@ -204,6 +249,7 @@ cdef extern from "cantera/kinetics/Kinetics.h" namespace "Cantera":
CxxThermoPhase& thermo(int)
shared_ptr[CxxReaction] reaction(size_t) except +
cbool isReversible(int) except +
int reactionType(int) except +
string reactionString(int) except +
@ -657,6 +703,15 @@ cdef class ThermoPhase(_SolutionBase):
cdef class InterfacePhase(ThermoPhase):
cdef CxxSurfPhase* surf
cdef class Reaction:
cdef shared_ptr[CxxReaction] _reaction
cdef CxxReaction* reaction
cdef _assign(self, shared_ptr[CxxReaction] other)
cdef class Arrhenius:
cdef CxxArrhenius* rate
cdef Reaction reaction # parent reaction, to prevent garbage collection
cdef class Kinetics(_SolutionBase):
pass
@ -799,3 +854,4 @@ cdef np.ndarray get_transport_1d(Transport tran, transportMethod1d method)
cdef np.ndarray get_transport_2d(Transport tran, transportMethod2d method)
cdef CxxIdealGasPhase* getIdealGasPhase(ThermoPhase phase) except *
cdef wrapSpeciesThermo(shared_ptr[CxxSpeciesThermo] spthermo)
cdef Reaction wrapReaction(shared_ptr[CxxReaction] reaction)

View file

@ -16,6 +16,7 @@ include "func1.pyx"
include "base.pyx"
include "speciesthermo.pyx"
include "thermo.pyx"
include "reaction.pyx"
include "kinetics.pyx"
include "transport.pyx"
include "composite.pyx"

View file

@ -73,6 +73,9 @@ cdef class Kinetics(_SolutionBase):
self._check_phase_index(k)
return self.kinetics.kineticsSpeciesIndex(k, phase)
def reaction(self, int i_reaction):
return wrapReaction(self.kinetics.reaction(i_reaction))
def is_reversible(self, int i_reaction):
"""True if reaction `i_reaction` is reversible."""
self._check_reaction_index(i_reaction)

View file

@ -0,0 +1,134 @@
cdef extern from "cantera/kinetics/reaction_defs.h" namespace "Cantera":
cdef int ELEMENTARY_RXN
cdef int THREE_BODY_RXN
cdef int FALLOFF_RXN
cdef int PLOG_RXN
cdef int CHEBYSHEV_RXN
cdef int CHEMACT_RXN
cdef int INTERFACE_RXN
cdef class Reaction:
def __cinit__(self, *args, init=True, **kwargs):
if init:
self._reaction.reset(new CxxReaction(0))
self.reaction = self._reaction.get()
cdef _assign(self, shared_ptr[CxxReaction] other):
self._reaction = other
self.reaction = self._reaction.get()
property reactant_string:
def __get__(self):
return pystr(self.reaction.reactantString())
property product_string:
def __get__(self):
return pystr(self.reaction.productString())
property equation:
def __get__(self):
return pystr(self.reaction.equation())
property reactants:
def __get__(self):
return comp_map_to_dict(self.reaction.reactants)
property products:
def __get__(self):
return comp_map_to_dict(self.reaction.products)
property orders:
def __get__(self):
return comp_map_to_dict(self.reaction.orders)
property ID:
def __get__(self):
return pystr(self.reaction.id)
property reversible:
def __get__(self):
return self.reaction.reversible
property duplicate:
def __get__(self):
return self.reaction.duplicate
property allow_nonreactant_orders:
def __get__(self):
return self.reaction.allow_nonreactant_orders
property allow_negative_orders:
def __get__(self):
return self.reaction.allow_negative_orders
cdef class Arrhenius:
def __cinit__(self, init=True):
if init:
self.rate = new CxxArrhenius()
self.reaction = None
def __dealloc__(self):
if self.reaction is None:
del self.rate
property preexponential_factor:
def __get__(self):
return self.rate.preExponentialFactor()
property temperature_exponent:
def __get__(self):
return self.rate.temperatureExponent()
property activation_energy:
def __get__(self):
return self.rate.activationEnergy_R() * gas_constant
cdef wrapArrhenius(CxxArrhenius* rate, Reaction reaction):
r = Arrhenius(init=False)
r.rate = rate
r.reaction = reaction
return r
cdef class ElementaryReaction(Reaction):
property rate:
def __get__(self):
cdef CxxElementaryReaction* r = <CxxElementaryReaction*>self.reaction
return wrapArrhenius(&(r.rate), self)
cdef class ThirdBodyReaction(ElementaryReaction):
cdef CxxThirdBodyReaction* tbr(self):
return <CxxThirdBodyReaction*>self.reaction
property efficiencies:
def __get__(self):
return comp_map_to_dict(self.tbr().third_body.efficiencies)
property default_efficiency:
def __get__(self):
return self.tbr().third_body.default_efficiency
def efficiency(self, species):
return self.tbr().third_body.efficiency(stringify(species))
cdef Reaction wrapReaction(shared_ptr[CxxReaction] reaction):
"""
Wrap a C++ Reaction object with a Python object of the correct derived type.
"""
cdef int reaction_type = reaction.get().reaction_type
if reaction_type == ELEMENTARY_RXN:
R = ElementaryReaction(init=False)
elif reaction_type == THREE_BODY_RXN:
R = ThirdBodyReaction(init=False)
else:
R = Reaction(init=False)
R._assign(reaction)
return R

View file

@ -5,16 +5,6 @@ cdef enum Thermasis:
molar_basis = 1
cdef Composition comp_map(dict X) except *:
cdef Composition m
for species,value in X.items():
m[stringify(species)] = value
return m
cdef comp_map_to_dict(Composition m):
return {pystr(species):value for species,value in m.items()}
cdef class Species:
def __cinit__(self, *args, init=True, **kwargs):
if init:

View file

@ -34,3 +34,12 @@ __version__ = pystr(get_cantera_version())
def appdelete():
""" Delete all global Cantera C++ objects """
CxxAppdelete()
cdef Composition comp_map(dict X) except *:
cdef Composition m
for species,value in X.items():
m[stringify(species)] = value
return m
cdef comp_map_to_dict(Composition m):
return {pystr(species):value for species,value in m.items()}

View file

@ -769,6 +769,12 @@ void Kinetics::addReaction(shared_ptr<Reaction> r)
m_ropnet.push_back(0.0);
}
shared_ptr<Reaction> Kinetics::reaction(size_t i)
{
checkReactionIndex(i);
return m_reactions[i];
}
void Kinetics::installGroups(size_t irxn, const vector<grouplist_t>& r,
const vector<grouplist_t>& p)