Cantera/Adding Python Class Via C++: Difference between revisions
From charlesreid1
No edit summary |
|||
| (3 intermediate revisions by the same user not shown) | |||
| Line 17: | Line 17: | ||
4. Create a Cython object (this fourth step was added between Cantera 2.0 and Cantera 2.1) | 4. Create a Cython object (this fourth step was added between Cantera 2.0 and Cantera 2.1) | ||
== | ==The Example== | ||
This example will show you how to extend the FlowController class to create a new mass flow controller type - specifically, a mass flow controller that controls the flow of a single species. (Note that this is analogous to [http://en.wikipedia.org/wiki/Maxwell's_demon Maxwell's Demon].) | This example will show you how to extend the FlowController class to create a new mass flow controller type - specifically, a mass flow controller that controls the flow of a single species. (Note that this is analogous to [http://en.wikipedia.org/wiki/Maxwell's_demon Maxwell's Demon].) | ||
==Strategies== | ==Strategies== | ||
| Line 32: | Line 31: | ||
===Think Properties=== | ===Think Properties=== | ||
Rather than try and get fancy with new classes or class hierarchies, you can keep it simple by using accessors, or properties. | |||
That means that you extend classes and simply define a set of new properties, which are accessible with get/set methods. | |||
===The Way Things Ought To Be=== | ===The Way Things Ought To Be=== | ||
| Line 40: | Line 41: | ||
Ultimately, the ideal solution (to quote Rush Limbaugh: "the way things ought to be") is for the library to be implemented in Python, which provides much more flexibility and sanity than C++. Some underlying Cython would add speed, as would some C, but really, you should be interfacing with external Python and/or C libraries for the heavy lifting (ODEs, solvers, matrices, and such). | Ultimately, the ideal solution (to quote Rush Limbaugh: "the way things ought to be") is for the library to be implemented in Python, which provides much more flexibility and sanity than C++. Some underlying Cython would add speed, as would some C, but really, you should be interfacing with external Python and/or C libraries for the heavy lifting (ODEs, solvers, matrices, and such). | ||
Numpy does | [[Numpy]] provides a great model for how this outsourcing of numerics could be done, as does [[Fipy]]. | ||
=Getting Started: The C++= | |||
We are going to do something simple and straightforward: we are going to add a new class that redefines a few methods. (Remember - keep it simple!) | |||
=Wrapping with the C API= | |||
(...) | |||
=Creating the Python-C Interface= | |||
(Is this necessary?) | |||
=Creating the Cython-C Interface= | |||
(...) | |||
[[Category:Cantera]] | [[Category:Cantera]] | ||
Latest revision as of 04:47, 13 August 2014
The following instructions describe how to implement a new C++ class in Cantera 2.1 and make it accessible via Python.
Hopefully this will save you the headaches and streams of expletives that navigating changes between 2.0 and 2.1 caused me.
(Note to Cantera developers: if you break backwards compatibility and change the way the API works, you need to increment the MAJOR version number, not the MINOR version number.)
Overview
To add a new C++ class in Cantera, you will need to follow a couple of steps:
1. Add the C++ code for the class
2. Wrap the new C++ code with the C API
3. Create a Python object that calls the C API code (is this even necessary?)
4. Create a Cython object (this fourth step was added between Cantera 2.0 and Cantera 2.1)
The Example
This example will show you how to extend the FlowController class to create a new mass flow controller type - specifically, a mass flow controller that controls the flow of a single species. (Note that this is analogous to Maxwell's Demon.)
Strategies
Before jumping into Cantera with both feet (and spending hours thrashing around in the code base), it's important that you step back for a moment and strategize how you want to go about adding your class.
Keep It Simple
The Cantera code base has a lot of layers. That means that for every function or object you implement, you'll be writing 3 or 4 APIs for it. That means that complicated input arguments, non-trivial (well, even trivial) class inheritance diagrams, or modifications to existing functionality is NOT RECOMMENDED.
Think Properties
Rather than try and get fancy with new classes or class hierarchies, you can keep it simple by using accessors, or properties.
That means that you extend classes and simply define a set of new properties, which are accessible with get/set methods.
The Way Things Ought To Be
It is unfortunate that Cantera is so cumbersome to extend, given the philosophy behind Cantera: it was intended to be an easily-extendable library with modular functionality. However, with the additional layers of the C API, the Python-C wrappers, and most recently, Cython, you end up doing a lot of code gymnastics for even the simplest extensions.
Ultimately, the ideal solution (to quote Rush Limbaugh: "the way things ought to be") is for the library to be implemented in Python, which provides much more flexibility and sanity than C++. Some underlying Cython would add speed, as would some C, but really, you should be interfacing with external Python and/or C libraries for the heavy lifting (ODEs, solvers, matrices, and such).
Numpy provides a great model for how this outsourcing of numerics could be done, as does Fipy.
Getting Started: The C++
We are going to do something simple and straightforward: we are going to add a new class that redefines a few methods. (Remember - keep it simple!)
Wrapping with the C API
(...)
Creating the Python-C Interface
(Is this necessary?)
Creating the Cython-C Interface
(...)