Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance py m++ #269

Merged
merged 2 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 160 additions & 4 deletions interface/python/src/pyMixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,50 @@ void py_export_Mixture(py::module &m) {
py::class_<Mutation::Mixture>(m, "Mixture")
.def(py::init<Mutation::MixtureOptions>())
.def(py::init<std::string &>())

.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.")

Expand Down Expand Up @@ -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<double> 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<double> 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 "
Expand Down Expand Up @@ -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<double> x) {
std::vector<double> 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<double> x) {
std::vector<double> 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.")
Expand Down Expand Up @@ -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<double> 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<double> 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<double> 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<double> 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<double> 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")

;
}
132 changes: 132 additions & 0 deletions tests/python/test_mutation.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env python

import numpy as np
import mutationpp as mpp
import pytest

Expand Down Expand Up @@ -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)
Loading