From 1352a67e1c42694a95bc61d12d289af03348f52f Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Wed, 29 May 2013 00:11:57 +0000 Subject: [PATCH] [Cython] Added interface for ReactionPathDiagram --- doc/sphinx/cython/kinetics.rst | 2 + interfaces/cython/cantera/_cantera.pxd | 34 ++++ interfaces/cython/cantera/_cantera.pyx | 1 + interfaces/cython/cantera/reactionpath.pyx | 184 +++++++++++++++++++++ 4 files changed, 221 insertions(+) create mode 100644 interfaces/cython/cantera/reactionpath.pyx diff --git a/doc/sphinx/cython/kinetics.rst b/doc/sphinx/cython/kinetics.rst index c53f91fbd..487267478 100644 --- a/doc/sphinx/cython/kinetics.rst +++ b/doc/sphinx/cython/kinetics.rst @@ -4,3 +4,5 @@ Chemical Kinetics ================= .. autoclass:: Kinetics + +.. autoclass:: ReactionPathDiagram diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index baf03ae82..14458f744 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -458,6 +458,40 @@ cdef extern from "cantera/oneD/Sim1D.h": void setFixedTemperature(double) void setInterrupt(CxxFunc1*) except + +cdef extern from "": + cdef cppclass CxxStringStream "std::stringstream": + string str() + +cdef extern from "cantera/kinetics/ReactionPath.h": + cdef enum CxxFlow_t "flow_t": + CxxNetFlow "Cantera::NetFlow" + CxxOneWayFlow "Cantera::OneWayFlow" + + cdef cppclass CxxReactionPathDiagram "Cantera::ReactionPathDiagram": + cbool show_details + double threshold + string bold_color + string normal_color + string dashed_color + string dot_options + double bold_min + double dashed_max + double label_min + double scale + double arrow_width + CxxFlow_t flow_type + string title + void setFont(string) + string m_font + void add(CxxReactionPathDiagram&) except + + void exportToDot(CxxStringStream&) + void writeData(CxxStringStream&) + void displayOnly(size_t) + + cdef cppclass CxxReactionPathBuilder "Cantera::ReactionPathBuilder": + void init(CxxStringStream&, CxxKinetics&) except + + void build(CxxKinetics&, string&, CxxStringStream&, CxxReactionPathDiagram&, cbool) + cdef extern from "wrappers.h": # config definitions diff --git a/interfaces/cython/cantera/_cantera.pyx b/interfaces/cython/cantera/_cantera.pyx index 7fe4d17ce..67cce0bbb 100644 --- a/interfaces/cython/cantera/_cantera.pyx +++ b/interfaces/cython/cantera/_cantera.pyx @@ -22,3 +22,4 @@ include "composite.pyx" include "mixture.pyx" include "reactor.pyx" include "onedim.pyx" +include "reactionpath.pyx" diff --git a/interfaces/cython/cantera/reactionpath.pyx b/interfaces/cython/cantera/reactionpath.pyx new file mode 100644 index 000000000..390c43733 --- /dev/null +++ b/interfaces/cython/cantera/reactionpath.pyx @@ -0,0 +1,184 @@ +cdef class ReactionPathDiagram: + cdef CxxReactionPathDiagram diagram + cdef CxxReactionPathBuilder builder + cdef Kinetics kinetics + cdef str element + cdef pybool built + cdef CxxStringStream _log + + def __init__(self, Kinetics kin, str element): + """ + Create a reaction path diagram for the fluxes of the element *element* + according the the net reaction rates determined by the Kinetics object + *kin*. + """ + self.kinetics = kin + self.builder.init(self._log, deref(kin.kinetics)) + self.element = element + self.built = False + + property show_details: + """ Show the details of which reactions contribute to the flux """ + def __get__(self): + return self.diagram.show_details + def __set__(self, pybool value): + self.diagram.show_details = value + + property threshold: + """ + Set the threshold for the minimum flux relative value that will be + plotted. + """ + def __get__(self): + return self.diagram.threshold + def __set__(self, double value): + self.diagram.threshold = value + + property bold_threshold: + """ minimum relative flux for bold lines """ + def __get__(self): + return self.diagram.bold_min + def __set__(self, double value): + self.diagram.bold_min = value + + property normal_threshold: + """ maximum relative flux for dashed lines """ + def __get__(self): + return self.diagram.dashed_max + def __set__(self, double value): + self.diagram.dashed_max = value + + property label_threshold: + """ minimum relative flux for labels """ + def __get__(self): + return self.diagram.label_min + def __set__(self, double value): + self.diagram.label_min = value + + property bold_color: + """ color for bold lines """ + def __get__(self): + return pystr(self.diagram.bold_color) + def __set__(self, str value): + self.diagram.bold_color = stringify(value) + + property normal_color: + """ color for normal-weight lines """ + def __get__(self): + return pystr(self.diagram.normal_color) + def __set__(self, str value): + self.diagram.normal_color = stringify(value) + + property dashed_color: + """ color for dashed lines """ + def __get__(self): + return pystr(self.diagram.dashed_color) + def __set__(self, str value): + self.diagram.dashed_color = stringify(value) + + property dot_options: + """ options for the 'dot' program """ + def __get__(self): + return pystr(self.diagram.dot_options) + def __set__(self, str value): + self.diagram.dot_options = stringify(value) + + property font: + def __get__(self): + return pystr(self.diagram.m_font) + def __set__(self, str value): + self.diagram.setFont(stringify(value)) + + property scale: + """ + Scaling factor for the fluxes. Set to -1 to normalize by the maximum + net flux. + """ + def __get__(self): + return self.diagram.scale + def __set__(self, double value): + self.diagram.scale = value + + property flow_type: + """ Set to either 'NetFlow' or 'OneWayFlow' """ + def __get__(self): + if self.diagram.flow_type == CxxNetFlow: + return 'NetFlow' + else: + return 'OneWayFlow' + + def __set__(self, str value): + if value == 'OneWayFlow': + self.diagram.flow_type = CxxOneWayFlow + elif value == 'NetFlow': + self.diagram.flow_type = CxxNetFlow + else: + raise ValueError('Invalid flow_type: {!r}'.format(value)) + + property arrow_width: + """ arrow width. If < 0, then scale with flux value """ + def __get__(self): + return self.diagram.arrow_width + def __set__(self, double value): + self.diagram.arrow_width = value + + property title: + def __get__(self): + return pystr(self.diagram.title) + def __set__(self, str value): + self.diagram.title = stringify(value) + + def add(self, ReactionPathDiagram other): + """ Add fluxes from `other` to this diagram """ + self.diagram.add(other.diagram) + + def display_only(self, int k): + self.diagram.displayOnly(k) + + def get_dot(self): + """ + Return a string containing the reaction path diagram formatted for use + by Graphviz's 'dot' program. + """ + if not self.built: + self.build() + cdef CxxStringStream out + self.diagram.exportToDot(out) + return pystr(out.str()) + + def write_dot(self, filename): + """ + Write the reaction path diagram formatted for use by Graphviz's 'dot' + program to the file named *filename*. + """ + open(filename, 'wb').write(self.get_dot()) + + def get_data(self): + """ + Get a (roughly) human-readable representation of the reaction path + diagram. + """ + if not self.built: + self.build() + cdef CxxStringStream out + self.diagram.writeData(out) + return pystr(out.str()) + + def build(self, verbose=False): + """ + Build the reaction path diagram. Called automatically by methods which + return representations of the diagram, e.g. write_dot(). + """ + self.builder.build(deref(self.kinetics.kinetics), + stringify(self.element), self._log, + self.diagram, True) + self.built = True + if verbose: + print self.log + + property log: + """ + Logging messages generated while building the reaction path diagram + """ + def __get__(self): + return pystr(self._log.str())