Rearranging Cython module into a single shared object

This is necessary to deal with DLL linking limitations on Windows
This commit is contained in:
Ray Speth 2012-09-06 19:56:03 +00:00
parent 96f9b05f8c
commit dfb18b461e
15 changed files with 133 additions and 146 deletions

View file

@ -1,3 +1 @@
from .solution import *
from .constants import *
from .mixture import *
from ._cantera import *

View file

@ -1,5 +1,14 @@
from libcpp.vector cimport vector
from utils cimport *
from libcpp.string cimport string
cdef extern from "cantera/base/xml.h" namespace "Cantera":
cdef cppclass XML_Node:
XML_Node* findByName(string)
XML_Node* findID(string)
int nChildren()
cdef extern from "cantera/base/ctml.h" namespace "ctml":
XML_Node getCtmlTree(string) except +
cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
cdef cppclass CxxThermoPhase "Cantera::ThermoPhase":
@ -11,34 +20,50 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
int nSpecies()
XML_Node& xml()
cdef extern from "cantera/kinetics/Kinetics.h" namespace "Cantera":
cdef cppclass CxxKinetics "Cantera::Kinetics":
CxxKinetics()
int nReactions()
cdef extern from "cantera/transport/TransportBase.h" namespace "Cantera":
cdef cppclass CxxTransport "Cantera::Transport":
CxxTransport(CxxThermoPhase*)
double viscosity() except +
cdef extern from "cantera/transport/DustyGasTransport.h" namespace "Cantera":
cdef cppclass CxxDustyGasTransport "Cantera::DustyGasTransport":
void setPorosity(double) except +
cdef extern from "cantera/equil/MultiPhase.h" namespace "Cantera":
cdef cppclass CxxMultiPhase "Cantera::MultiPhase":
CxxMultiPhase()
void addPhase(CxxThermoPhase*, double) except +
void init() except +
double nSpecies()
void setTemperature(double)
double temperature()
void setPressure(double)
double pressure()
cdef extern from "cantera/thermo/ThermoFactory.h" namespace "Cantera":
cdef CxxThermoPhase* newPhase(string, string) except +
cdef CxxThermoPhase* newPhase(XML_Node&) except +
cdef extern from "cantera/kinetics/KineticsFactory.h" namespace "Cantera":
cdef CxxKinetics* newKineticsMgr(XML_Node&, vector[CxxThermoPhase*]) except +
cdef extern from "cantera/transport/TransportFactory.h" namespace "Cantera":
cdef CxxTransport* newDefaultTransportMgr(CxxThermoPhase*) except +
cdef CxxTransport* newTransportMgr(string, CxxThermoPhase*) except +
cdef string stringify(x)
cdef class _SolutionBase:
cdef CxxThermoPhase* thermo
cdef CxxKinetics* kinetics
cdef CxxTransport* transport
cdef class Mixture:
cdef CxxMultiPhase* mix
cdef list _phases

View file

@ -0,0 +1,17 @@
import numpy as np
cimport numpy as np
from cython.operator cimport dereference as deref
from _cantera cimport *
include "utils.pyx"
include "constants.pyx"
include "base.pyx"
include "thermo.pyx"
include "kinetics.pyx"
include "transport.pyx"
include "composite.pyx"
include "mixture.pyx"

View file

@ -0,0 +1,38 @@
cdef class _SolutionBase:
def __cinit__(self, infile, phaseid=''):
rootNode = getCtmlTree(stringify(infile))
# Get XML data
cdef XML_Node* phaseNode
if phaseid:
phaseNode = rootNode.findID(stringify(phaseid))
else:
phaseNode = rootNode.findByName(stringify('phase'))
if phaseNode is NULL:
raise ValueError("Couldn't read phase node from XML file")
# Thermo
if isinstance(self, ThermoPhase):
self.thermo = newPhase(deref(phaseNode))
else:
self.thermo = NULL
# Kinetics
cdef vector[CxxThermoPhase*] v
if isinstance(self, Kinetics):
v.push_back(self.thermo)
self.kinetics = newKineticsMgr(deref(phaseNode), v)
else:
self.kinetics = NULL
# Transport
if isinstance(self, Transport):
self.transport = newDefaultTransportMgr(self.thermo)
else:
self.transport = NULL
def __dealloc__(self):
del self.thermo
del self.kinetics
del self.transport

View file

@ -0,0 +1,4 @@
class Solution(ThermoPhase, Kinetics, Transport):
def __init__(self, *args, **kwars):
pass

View file

@ -0,0 +1,4 @@
cdef class Kinetics(_SolutionBase):
property nReactions:
def __get__(self):
return self.kinetics.nReactions()

View file

@ -1,16 +0,0 @@
from solution cimport *
cdef extern from "cantera/equil/MultiPhase.h" namespace "Cantera":
cdef cppclass CxxMultiPhase "Cantera::MultiPhase":
CxxMultiPhase()
void addPhase(CxxThermoPhase*, double) except +
void init() except +
double nSpecies()
void setTemperature(double)
double temperature()
void setPressure(double)
double pressure()
cdef class Mixture:
cdef CxxMultiPhase* mix
cdef list _phases

View file

@ -1,5 +1,3 @@
from mixture cimport *
cdef class Mixture:
def __cinit__(self, phases):
self.mix = new CxxMultiPhase()

View file

@ -1,88 +0,0 @@
import numpy as np
cimport numpy as np
from cython.operator cimport dereference as deref
from utils cimport *
cdef class _SolutionBase:
def __cinit__(self, infile, phaseid=''):
rootNode = getCtmlTree(stringify(infile))
# Get XML data
cdef XML_Node* phaseNode
if phaseid:
phaseNode = rootNode.findID(stringify(phaseid))
else:
phaseNode = rootNode.findByName(stringify('phase'))
if phaseNode is NULL:
raise ValueError("Couldn't read phase node from XML file")
# Thermo
if isinstance(self, ThermoPhase):
self.thermo = newPhase(deref(phaseNode))
else:
self.thermo = NULL
# Kinetics
cdef vector[CxxThermoPhase*] v
if isinstance(self, Kinetics):
v.push_back(self.thermo)
self.kinetics = newKineticsMgr(deref(phaseNode), v)
else:
self.kinetics = NULL
# Transport
if isinstance(self, Transport):
self.transport = newDefaultTransportMgr(self.thermo)
else:
self.transport = NULL
def __dealloc__(self):
del self.thermo
del self.kinetics
del self.transport
cdef class ThermoPhase(_SolutionBase):
property nSpecies:
def __get__(self):
return self.thermo.nSpecies()
property pressure:
def __get__(self):
return self.thermo.pressure()
property temperature:
def __get__(self):
return self.thermo.temperature()
def setMoleFractions(self, X):
if len(X) != self.nSpecies:
raise ValueError("Mole fraction array has incorrect length")
cdef np.ndarray[np.double_t, ndim=1] X_c = np.ascontiguousarray(X, dtype=np.double)
self.thermo.setMoleFractions(&X_c[0])
property massFractions:
def __get__(self):
cdef np.ndarray[np.double_t, ndim=1] X_c = np.empty(self.nSpecies)
self.thermo.getMassFractions(&X_c[0])
return X_c
cdef class Kinetics(_SolutionBase):
property nReactions:
def __get__(self):
return self.kinetics.nReactions()
cdef class Transport(_SolutionBase):
property viscosity:
def __get__(self):
return self.transport.viscosity()
class Solution(ThermoPhase, Kinetics, Transport):
def __init__(self, *args, **kwars):
pass

View file

@ -0,0 +1,24 @@
cdef class ThermoPhase(_SolutionBase):
property nSpecies:
def __get__(self):
return self.thermo.nSpecies()
property pressure:
def __get__(self):
return self.thermo.pressure()
property temperature:
def __get__(self):
return self.thermo.temperature()
def setMoleFractions(self, X):
if len(X) != self.nSpecies:
raise ValueError("Mole fraction array has incorrect length")
cdef np.ndarray[np.double_t, ndim=1] X_c = np.ascontiguousarray(X, dtype=np.double)
self.thermo.setMoleFractions(&X_c[0])
property massFractions:
def __get__(self):
cdef np.ndarray[np.double_t, ndim=1] X_c = np.empty(self.nSpecies)
self.thermo.getMassFractions(&X_c[0])
return X_c

View file

@ -0,0 +1,4 @@
cdef class Transport(_SolutionBase):
property viscosity:
def __get__(self):
return self.transport.viscosity()

View file

@ -1,14 +0,0 @@
from libcpp.string cimport string
cdef extern from "cantera/base/xml.h" namespace "Cantera":
cdef cppclass XML_Node:
XML_Node* findByName(string)
XML_Node* findID(string)
int nChildren()
cdef extern from "cantera/base/ctml.h" namespace "ctml":
XML_Node getCtmlTree(string) except +
cdef string stringify(x)

View file

@ -1,5 +1,3 @@
from utils cimport *
cdef string stringify(x):
""" Converts Python strings to std::string. """
# This method works with both Python 2.x and 3.x.

View file

@ -9,21 +9,14 @@ if os.name == 'nt':
else:
dataFiles.append('libcantera_shared.so')
exts = []
def addExtension(name):
exts.append(Extension("cantera.%s" % name,
["cantera/%s.pyx" % name],
include_dirs=@py_include_dirs@,
language="c++",
libraries=@py_cantera_libs@,
library_dirs=@py_libdirs@,
extra_link_args=@py_extra_link_args@))
addExtension('solution')
addExtension('mixture')
addExtension('utils')
addExtension('constants')
exts = [Extension("cantera._cantera",
["cantera/_cantera.pyx"],
include_dirs=@py_include_dirs@,
language="c++",
libraries=@py_cantera_libs@,
library_dirs=@py_libdirs@,
extra_compile_args=@py_extra_compiler_args@,
extra_link_args=@py_extra_link_args@)]
setup(name="Cantera",
version="@cantera_version@",

View file

@ -117,13 +117,15 @@ libDirs = ('../../build/lib', localenv['sundials_libdir'],
localenv['boost_lib_dir'])
localenv['py_include_dirs'] = repr([x for x in incDirs if x])
localenv['py_cantera_libs'] = repr(localenv['cantera_shared_libs'])
localenv['py_cantera_libs'] = repr(localenv['cantera_libs'])
localenv['py_libdirs'] = repr([x for x in libDirs if x])
if localenv['CC'] == 'cl':
localenv['py_extra_link_args'] = repr([])
localenv['py_extra_compiler_args'] = repr(['/EHsc'])
else:
localenv['py_extra_link_args'] = repr(['-Wl,-rpath=$$ORIGIN'])
localenv['py_extra_compiler_args'] = repr([])
make_setup = localenv.SubstFile('#interfaces/cython/setup.py',
'#interfaces/cython/setup.py.in')