diff --git a/interfaces/cython/cantera/_cantera.pxd b/interfaces/cython/cantera/_cantera.pxd index b7cdf9ce8..d95535ec0 100644 --- a/interfaces/cython/cantera/_cantera.pxd +++ b/interfaces/cython/cantera/_cantera.pxd @@ -86,11 +86,13 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera": # composition void setMassFractionsByName(string) except + void setMassFractionsByName(stdmap[string,double]&) except + + void setMassFractions_NoNorm(double*) except + double massFraction(size_t) except + double massFraction(string) except + void setMoleFractionsByName(string) except + void setMoleFractionsByName(stdmap[string,double]&) except + + void setMoleFractions_NoNorm(double*) except + void getMoleFractions(double*) except + double moleFraction(size_t) except + double moleFraction(string) except + diff --git a/interfaces/cython/cantera/test/test_thermo.py b/interfaces/cython/cantera/test/test_thermo.py index 7a911c009..3f8d614b3 100644 --- a/interfaces/cython/cantera/test/test_thermo.py +++ b/interfaces/cython/cantera/test/test_thermo.py @@ -94,6 +94,29 @@ class TestThermoPhase(utilities.CanteraTest): self.assertNear(Y[0], 0.25) self.assertNear(Y[3], 0.75) + def test_setCompositionNoNorm(self): + X = np.zeros(self.phase.n_species) + X[2] = 1.0 + X[0] = 0.01 + self.phase.set_unnormalized_mole_fractions(X) + self.assertArrayNear(self.phase.X, X) + self.assertNear(sum(X), 1.01) + + Y = np.zeros(self.phase.n_species) + Y[2] = 1.0 + Y[0] = 0.01 + self.phase.set_unnormalized_mass_fractions(Y) + self.assertArrayNear(self.phase.Y, Y) + self.assertNear(sum(Y), 1.01) + + def test_setCompositionNoNormBad(self): + X = np.zeros(self.phase.n_species - 1) + with self.assertRaises(ValueError): + self.phase.set_unnormalized_mole_fractions(X) + + with self.assertRaises(ValueError): + self.phase.set_unnormalized_mass_fractions([1,2,3]) + @unittest.expectedFailure def test_setCompositionDict_bad1(self): # Non-existent species should raise an exception diff --git a/interfaces/cython/cantera/thermo.pyx b/interfaces/cython/cantera/thermo.pyx index a317a7cfe..39a9df640 100644 --- a/interfaces/cython/cantera/thermo.pyx +++ b/interfaces/cython/cantera/thermo.pyx @@ -317,6 +317,32 @@ cdef class ThermoPhase(_SolutionBase): def __set__(self, C): self._setArray1(thermo_setConcentrations, C) + def set_unnormalized_mass_fractions(self, Y): + """ + Set the mass fractions without normalizing to force sum(Y) == 1.0. + Useful primarily when calculating derivatives with respect to Y[k] by + finite difference. + """ + cdef np.ndarray[np.double_t, ndim=1] data + if len(Y) == self.n_species: + data = np.ascontiguousarray(Y, dtype=np.double) + else: + raise ValueError("Array has incorrect length") + self.thermo.setMassFractions_NoNorm(&data[0]) + + def set_unnormalized_mole_fractions(self, X): + """ + Set the mole fractions without normalizing to force sum(X) == 1.0. + Useful primarily when calculating derivatives with respect to X[k] + by finite difference. + """ + cdef np.ndarray[np.double_t, ndim=1] data + if len(X) == self.n_species: + data = np.ascontiguousarray(X, dtype=np.double) + else: + raise ValueError("Array has incorrect length") + self.thermo.setMoleFractions_NoNorm(&data[0]) + ######## Read-only thermodynamic properties ######## property P: