From c41934d995a0a3064ecc3b98e3f5af7b15ac5f17 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Thu, 6 Sep 2012 19:57:27 +0000 Subject: [PATCH] [Python] Starting on full interface to ThermoPhase member functions --- interfaces/cython/cantera/_cantera.pxd | 87 +++++++++++++++++++++++-- interfaces/cython/cantera/thermo.pyx | 88 ++++++++++++++++++++++---- interfaces/cython/cantera/utils.pyx | 12 ++++ interfaces/cython/cantera/wrappers.h | 23 +++++++ 4 files changed, 193 insertions(+), 17 deletions(-) create mode 100644 interfaces/cython/cantera/wrappers.h diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index 0021f08e0..0de7e11b6 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -27,12 +27,67 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": cdef cppclass CxxThermoPhase "Cantera::ThermoPhase": CxxThermoPhase() int eosType() - double pressure() except + - double temperature() except + - void setMoleFractions(double*) except + - void getMassFractions(double*) except + - int nSpecies() XML_Node& xml() + string report(cbool) except + + + # basic thermodynamic properties + double temperature() except + + double pressure() except + + double density() except + + double molarDensity() except + + double molarVolume() except + + double isothermalCompressibility() except + + double thermalExpansionCoeff() except + + + # element properties + size_t nElements() + size_t elementIndex(string) + string elementName(size_t) except + + + # species properties + size_t nSpecies() + size_t speciesIndex(string) + string speciesName(size_t) except + + double nAtoms(size_t, size_t) except + + void getAtoms(size_t, double*) except + + + double molecularWeight(size_t) except + + double meanMolecularWeight() + + # composition + void setMassFractionsByName(string) except + + double massFraction(size_t) except + + double massFraction(string) except + + + void setMoleFractionsByName(string) except + + void getMoleFractions(double*) except + + double moleFraction(size_t) except + + double moleFraction(string) except + + + double concentration(size_t) except + + + # state setters + void setState_TR(double, double) except + + void setState_TP(double, double) except + + void setState_HP(double, double) except + + void setState_UV(double, double) except + + void setState_SP(double, double) except + + + # molar thermodynamic properties: + double enthalpy_mole() except + + double intEnergy_mole() except + + double entropy_mole() except + + double gibbs_mole() except + + double cp_mole() except + + double cv_mole() except + + + # specific (mass) properties: + double enthalpy_mass() except + + double intEnergy_mass() except + + double entropy_mass() except + + double gibbs_mass() except + + double cp_mass() except + + double cv_mass() except + # PureFluid properties double critTemperature() except + @@ -47,6 +102,28 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": void setState_Psat(double P, double x) except + +cdef extern from "wrappers.h": + # ThermoPhase composition + cdef void thermo_getMassFractions(CxxThermoPhase*, double*) except + + cdef void thermo_setMassFractions(CxxThermoPhase*, double*) except + + cdef void thermo_getMoleFractions(CxxThermoPhase*, double*) except + + cdef void thermo_setMoleFractions(CxxThermoPhase*, double*) except + + cdef void thermo_getConcentrations(CxxThermoPhase*, double*) except + + cdef void thermo_setConcentrations(CxxThermoPhase*, double*) except + + + # ThermoPhase partial molar properties + cdef void thermo_getChemPotentials(CxxThermoPhase*, double*) except + + cdef void thermo_getElectrochemPotentials(CxxThermoPhase*, double*) except + + cdef void thermo_getPartialMolarEnthalpies(CxxThermoPhase*, double*) except + + cdef void thermo_getPartialMolarEntropies(CxxThermoPhase*, double*) except + + cdef void thermo_getPartialMolarIntEnergies(CxxThermoPhase*, double*) except + + cdef void thermo_getPartialMolarCp(CxxThermoPhase*, double*) except + + cdef void thermo_getPartialMolarVolumes(CxxThermoPhase*, double*) except + + + # other ThermoPhase methods + cdef void thermo_getMolecularWeights(CxxThermoPhase*, double*) except + + + cdef extern from "cantera/thermo/IdealGasPhase.h": cdef cppclass CxxIdealGasPhase "Cantera::IdealGasPhase" diff --git a/interfaces/cython/cantera/thermo.pyx b/interfaces/cython/cantera/thermo.pyx index c0a7a2a71..cd30357b9 100644 --- a/interfaces/cython/cantera/thermo.pyx +++ b/interfaces/cython/cantera/thermo.pyx @@ -1,27 +1,91 @@ +cdef enum ThermoBasis: + mass = 0 + molar = 1 + +ctypedef void (*thermoMethod1d)(CxxThermoPhase*, double*) except + + cdef class ThermoPhase(_SolutionBase): + def report(self, show_thermo=True): + return pystr(self.thermo.report(bool(show_thermo))) + + property nElements: + def __get__(self): + return self.thermo.nElements() + + def elementIndex(self, name): + return self.thermo.elementIndex(stringify(name)) + + def elementName(self, m): + return pystr(self.thermo.elementName(m)) + property nSpecies: def __get__(self): return self.thermo.nSpecies() - property pressure: + def speciesName(self, k): + return pystr(self.thermo.speciesName(k)) + + def speciesIndex(self, name): + return self.thermo.speciesIndex(stringify(name)) + + property P: def __get__(self): return self.thermo.pressure() - property temperature: + property T: 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: + property rho: 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 + return self.thermo.density() + + cdef np.ndarray _getArray1(self, thermoMethod1d method): + cdef np.ndarray[np.double_t, ndim=1] data = np.empty(self.nSpecies) + method(self.thermo, &data[0]) + return data + + cdef void _setArray1(self, thermoMethod1d method, values) except *: + if len(values) != self.nSpecies: + raise ValueError("Array has incorrect length") + + cdef np.ndarray[np.double_t, ndim=1] data = \ + np.ascontiguousarray(values, dtype=np.double) + method(self.thermo, &data[0]) + + property molecularWeights: + def __get__(self): + return self._getArray1(thermo_getMolecularWeights) + + property Y: + def __get__(self): + return self._getArray1(thermo_getMassFractions) + def __set__(self, Y): + if isinstance(Y, str): + self.thermo.setMassFractionsByName(stringify(Y)) + else: + self._setArray1(thermo_setMassFractions, Y) + + def massFraction(self, int k): + return self.thermo.massFraction(k) + + property X: + def __get__(self): + return self._getArray1(thermo_getMoleFractions) + def __set__(self, X): + if isinstance(X, str): + self.thermo.setMoleFractionsByName(stringify(X)) + else: + self._setArray1(thermo_setMoleFractions, X) + + def moleFraction(self, int k): + return self.thermo.moleFraction(k) + + property concentrations: + def __get__(self): + return self._getArray1(thermo_getConcentrations) + def __set__(self, C): + self._setArray1(thermo_setConcentrations, C) cdef class InterfacePhase(ThermoPhase): diff --git a/interfaces/cython/cantera/utils.pyx b/interfaces/cython/cantera/utils.pyx index e4206d21a..106f1e18a 100644 --- a/interfaces/cython/cantera/utils.pyx +++ b/interfaces/cython/cantera/utils.pyx @@ -1,8 +1,20 @@ +import sys +cdef int _pythonMajorVersion = sys.version_info[0] + cdef string stringify(x): """ Converts Python strings to std::string. """ # This method works with both Python 2.x and 3.x. tmp = bytes(x.encode()) return string(tmp) +cdef pystr(string x): + cdef bytes s = x.c_str() + if _pythonMajorVersion == 2: + # Python 2.x + return s + else: + # Python 3.x + return s.decode() + def addDirectory(directory): CxxAddDirectory(stringify(directory)) diff --git a/interfaces/cython/cantera/wrappers.h b/interfaces/cython/cantera/wrappers.h new file mode 100644 index 000000000..2f74b428f --- /dev/null +++ b/interfaces/cython/cantera/wrappers.h @@ -0,0 +1,23 @@ +#include "cantera/thermo/ThermoPhase.h" + +#define ARRAY_FUNC(PREFIX, CLASS_NAME, FUNC_NAME) \ + void PREFIX ## _ ## FUNC_NAME(Cantera::CLASS_NAME* object, double* data) \ + { object->FUNC_NAME(data); } + +#define THERMO_1D(FUNC_NAME) ARRAY_FUNC(thermo, ThermoPhase, FUNC_NAME) + +THERMO_1D(getMassFractions) +THERMO_1D(setMassFractions) +THERMO_1D(getMoleFractions) +THERMO_1D(setMoleFractions) +THERMO_1D(getConcentrations) +THERMO_1D(setConcentrations) + +THERMO_1D(getMolecularWeights) +THERMO_1D(getChemPotentials) +THERMO_1D(getElectrochemPotentials) +THERMO_1D(getPartialMolarEnthalpies) +THERMO_1D(getPartialMolarEntropies) +THERMO_1D(getPartialMolarIntEnergies) +THERMO_1D(getPartialMolarCp) +THERMO_1D(getPartialMolarVolumes)