diff --git a/interface/python/src/pyMixture.cpp b/interface/python/src/pyMixture.cpp index 265abb11..d3e83824 100644 --- a/interface/python/src/pyMixture.cpp +++ b/interface/python/src/pyMixture.cpp @@ -20,6 +20,50 @@ void py_export_Mixture(py::module &m) { py::class_(m, "Mixture") .def(py::init()) .def(py::init()) + + .def("NA", + [](const Mutation::Mixture &self) { + return Mutation::NA; + }, + "Returns the Avogadro's number (molecule/mol)." + ) + + .def("KB", + [](const Mutation::Mixture &self) { + return Mutation::KB; + }, + "Returns the Boltzmann's constant (J/molecule-K)") + + .def("RU", + [](const Mutation::Mixture &self) { + return Mutation::RU; + }, + "Returns the Universal Gas constant (J/mole-K)") + + .def("HP", + [](const Mutation::Mixture &self) { + return Mutation::HP; + }, + "Returns the Planck's constant (J-s)") + + .def("C0", + [](const Mutation::Mixture &self) { + return Mutation::C0; + }, + "Returns the Speed of light in vacuum (m/s)") + + .def("ONEATM", + [](const Mutation::Mixture &self) { + return Mutation::ONEATM; + }, + "Returns the 1 atm in Pa") + + .def("SB", + [](const Mutation::Mixture &self) { + return Mutation::SB; + }, + "Returns the Stefan-Boltzmann constant (W/m^2-K^4)") + .def("nElements", &Mutation::Mixture::nElements, "Returns the number of elements considered in the mixture.") @@ -380,12 +424,21 @@ void py_export_Mixture(py::module &m) { "elemental mole fractions. " "If the mole fractions are not given, then the default fractions are " "used.") + .def( + "speciesHOverRT", + [](const Mutation::Mixture &self) { + std::vector h_i(self.nSpecies()); + self.speciesHOverRT(h_i.data()); + return py::array(py::cast(h_i)); + }, + "Computes the unitless species enthalpies and can optionally fill vectors" + "for each energy mode.") .def( "speciesHOverRT", - [](const Mutation::Mixture &self) { + [](const Mutation::Mixture &self, double T) { std::vector h_i(self.nSpecies()); - self.speciesCpOverR(h_i.data()); + self.speciesHOverRT(T, h_i.data()); return py::array(py::cast(h_i)); }, "Returns the unitless vector of species enthalpies \f$ H_i / R_u T " @@ -489,6 +542,26 @@ void py_export_Mixture(py::module &m) { }, "Converts species mass to elemental mass fraction.") + .def( + "convert_xe_to_ye", + [](const Mutation::Mixture &self, std::vector x) { + std::vector y(self.nElements()); + self.Mutation::Mixture::Thermodynamics::convert< + Mutation::Thermodynamics::XE_TO_YE>(x.data(), y.data()); + return py::array(py::cast(y)); + }, + "Converts elemental mole fraction to elemental mass fractions.") + + .def( + "convert_ye_to_xe", + [](const Mutation::Mixture &self, std::vector x) { + std::vector y(self.nElements()); + self.Mutation::Mixture::Thermodynamics::convert< + Mutation::Thermodynamics::YE_TO_XE>(x.data(), y.data()); + return py::array(py::cast(y)); + }, + "Converts elemental mass fraction to elemental mole fractions.") + .def("dRhodP", &Mutation::Mixture::dRhodP, "Returns the density derivative with respect to pressure for the " "current equilibrium state.") @@ -741,5 +814,88 @@ void py_export_Mixture(py::module &m) { self.averageDiffusionCoeffs(array.data()); return py::array(py::cast(array)); }, - "Returns the average diffusion coefficients."); -} + "Returns the average diffusion coefficients.") + + .def( + "getTemperatures", + [](const Mutation::Mixture &self) { + std::vector T_i(self.nEnergyEqns()); + self.getTemperatures(T_i.data()); + return py::array(py::cast(T_i)); + }, + "Fills temperature array with tempertures according to the used " + "StateModel.") + + .def( + "getEnergiesMass", + [](const Mutation::Mixture &self) { + std::vector e_i(self.nSpecies()); + self.Mutation::Mixture::getEnergiesMass(e_i.data()); + return py::array(py::cast(e_i)); + }, + "Fills energy per mass array with energies according to the used " + "StateModel (total + internal for each species).") + + .def( + "getEnthalpiesMass", + [](const Mutation::Mixture &self) { + std::vector h_i(self.nSpecies()); + self.Mutation::Mixture::getEnthalpiesMass(h_i.data()); + return py::array(py::cast(h_i)); + }, + "Fills enthalpy per mass array with enthalpy according to the used " + "StateModel (total + internal for each species).") + + .def( + "getCpsMass", + [](const Mutation::Mixture &self) { + std::vector cp_i(self.nSpecies()); + self.Mutation::Mixture::getCpsMass(cp_i.data()); + return py::array(py::cast(cp_i)); + }, + "Fills the constant pressure specific heat according to the used " + "StateModel") + + .def( + "getCvsMass", + [](const Mutation::Mixture &self) { + std::vector cv_i(self.nSpecies()); + self.Mutation::Mixture::getCvsMass(cv_i.data()); + return py::array(py::cast(cv_i)); + }, + "Fills the constant volume specific heat according to the used " + "StateModel") + + + .def( + "getGibbsMass", + [](const Mutation::Mixture &self) { + Eigen::ArrayXd gibbs_i(self.nSpecies()); + self.Mutation::Mixture::speciesGOverRT(gibbs_i.data()); + gibbs_i*=self.T()* Mutation::RU/self.speciesMw(); + return py::array(py::cast(gibbs_i));; + }, + "Return an array of gibbs free energy for each species per unit mass") + + .def( + "getGibbsMass", + [](const Mutation::Mixture &self, double T, double P) { + Eigen::ArrayXd gibbs_i(self.nSpecies()); + self.Mutation::Mixture::speciesGOverRT(T, P, gibbs_i.data()); + gibbs_i*=T* Mutation::RU/self.speciesMw(); + return py::array(py::cast(gibbs_i));; + }, + "Return an array of gibbs free energy for each species per unit mass") + + .def( + "getSTGibbsMass", + [](const Mutation::Mixture &self, double T) { + Eigen::ArrayXd gibbs_i(self.nSpecies()); + self.Mutation::Mixture::speciesSTGOverRT(T, gibbs_i.data()); + gibbs_i*=T* Mutation::RU/self.speciesMw(); + return py::array(py::cast(gibbs_i));; + }, + "Return an array of gibbs free energy for each species per unit mass at standard pressure") + + ; +} \ No newline at end of file diff --git a/tests/python/test_mutation.py b/tests/python/test_mutation.py index a308e080..1f826631 100644 --- a/tests/python/test_mutation.py +++ b/tests/python/test_mutation.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import numpy as np import mutationpp as mpp import pytest @@ -276,3 +277,134 @@ def test_X(): def test_Y(): # Todo: write proper test assert sum(mixture.Y()) == 1. + +def test_convert_xe_to_ye(): + np.testing.assert_array_equal( + mixture.convert_xe_to_ye([0, 0, 1]), np.array([0, 0, 1]) + ) + +def test_convert_ye_to_xe(): + np.testing.assert_array_equal( + mixture.convert_ye_to_xe([0, 0, 1]), np.array([0, 0, 1]) + ) + +def test_speciesHOverRT(): + expected = [ + 1.54166667e-02, + 7.54484667e02, + 6.28975420e02, + 3.97181733e02, + 6.05194961e02, + 4.69649788e02, + 1.89420120e02, + 9.99331729e01, + 3.65398913e01, + 2.15923313e-02, + 2.17600146e-02, + ] + assert np.allclose(mixture.speciesHOverRT(), expected) + + +def test_speciesHOverRT(): + expected = [ + 2.36710963e-02, + 7.51986575e02, + 6.26894106e02, + 3.95873824e02, + 6.03195982e02, + 4.68101138e02, + 1.88799123e02, + 9.96094746e01, + 3.64301530e01, + 3.31535710e-02, + 3.34133823e-02, + ] + assert np.allclose(mixture.speciesHOverRT(301), expected) + +def test_getEnergiesMass(): + + expected = mixture.getEnthalpiesMass() - mixture.T()*mixture.RU()/mixture.speciesMw() + + assert mixture.getEnergiesMass() == pytest.approx(expected) + + +def test_getEnthalpiesMass(): + + expected = [ + 7.0098139454e+07, + 1.3436541662e+08, + 9.8062005405e+07, + 3.3017452040e+07, + 5.3888226083e+07, + 3.6610342011e+07, + 3.3732317707e+07, + 1.5579800144e+07, + 3.0374812162e+06, + 1.9226029990e+03, + 1.6962169231e+03 + ] + + assert mixture.getEnthalpiesMass() == pytest.approx(expected) + +def test_getCpsMass(): + + expected = [ + 3.7890886192e+07, + 1.5192147894e+03, + 1.2992294338e+03, + 9.7019017139e+02, + 1.0395135823e+03, + 9.1103684272e+02, + 1.4840168399e+03, + 1.2991848864e+03, + 9.7219901895e+02, + 1.0392575435e+03, + 9.1700386827e+02 + ] + + assert mixture.getCpsMass() == pytest.approx(expected) + + +def test_getGibbsMass(): + + expected = [ + -3.2412103851e+10, + 1.3011972425e+08, + 9.4435909312e+07, + 3.0651845001e+07, + 5.1361201327e+07, + 3.4318319525e+07, + 2.9626009866e+07, + 1.1827394569e+07, + 5.4328552314e+05, + -2.4612058750e+06, + -2.2814767433e+06 + ] + + assert mixture.getGibbsMass() == pytest.approx(expected) + +def test_getCvsMass(): + + expected = mixture.getCpsMass()- mixture.RU()/mixture.speciesMw() + assert mixture.getCvsMass() == pytest.approx(expected) + +def test_mixtureSMass(): + assert mixture.mixtureSMass() == pytest.approx(8218.83) + +def test_NA(): + assert mixture.NA() == pytest.approx(6.0221415E23) + +def test_KB(): + assert mixture.KB() == pytest.approx(1.3806503E-23) + +def test_RU(): + assert mixture.RU() == pytest.approx(mixture.KB()* mixture.NA()) + +def test_HP(): + assert mixture.HP() == pytest.approx(6.626068E-34) + +def test_C0(): + assert mixture.C0() == pytest.approx(299792458.0) + +def test_ONEATM(): + assert mixture.ONEATM() == pytest.approx(101325.0)