Fix definition of elemental mole fraction
The elemental mole fractions should be invariant under composition changes which conserve atoms.
This commit is contained in:
parent
97b32069cf
commit
e8292d387e
4 changed files with 42 additions and 16 deletions
|
|
@ -541,12 +541,16 @@ public:
|
|||
//! Elemental mole fraction of element m
|
||||
/*!
|
||||
* The elemental mole fraction \f$Z_{\mathrm{mole},m}\f$ of element \f$m\f$
|
||||
* is defined as
|
||||
* is the number of atoms of element *m* divided by the total number of
|
||||
* atoms. It is defined as:
|
||||
*
|
||||
* \f[
|
||||
* Z_{\mathrm{mole},m} = \sum_k \frac{a_{m,k}}{\sum_j a_{j,k}} X_k
|
||||
* Z_{\mathrm{mole},m} = \frac{\sum_k a_{m,k} X_k}
|
||||
* {\sum_k \sum_j a_{j,k} X_k}
|
||||
* \f]
|
||||
* with \f$a_{m,k}\f$ being the number of atoms of element \f$m\f$ in
|
||||
* species \f$k\f$and \f$X_k\f$ the mole fraction of species \f$k\f$.
|
||||
* species \f$k\f$, \f$\sum_j\f$ being a sum over all elements, and
|
||||
* \f$X_k\f$ being the mole fraction of species \f$k\f$.
|
||||
*
|
||||
* @param[in] m Index of the element within the phase. If m is outside the
|
||||
* valid range, an exception will be thrown.
|
||||
|
|
|
|||
|
|
@ -65,8 +65,8 @@ class TestThermoPhase(utilities.CanteraTest):
|
|||
|
||||
mO = self.phase.element_index('O')
|
||||
self.assertEqual(Zo, self.phase.elemental_mole_fraction(mO))
|
||||
self.assertNear(Zo, 0.5/3 + 0.5)
|
||||
self.assertNear(Zh, 0.5*2/3)
|
||||
self.assertNear(Zo, (0.5 + 1) / (0.5*3 + 0.5*2))
|
||||
self.assertNear(Zh, (2*0.5) / (0.5*3 + 0.5*2))
|
||||
self.assertEqual(Zar, 0.0)
|
||||
|
||||
with self.assertRaises(ValueError):
|
||||
|
|
@ -74,6 +74,22 @@ class TestThermoPhase(utilities.CanteraTest):
|
|||
with self.assertRaises(ValueError):
|
||||
self.phase.elemental_mole_fraction(5)
|
||||
|
||||
def test_elemental_mass_mole_fraction(self):
|
||||
# expected relationship between elmental mass and mole fractions
|
||||
comps = ['H2O:0.5, O2:0.5', 'H2:0.1, O2:0.4, H2O2:0.3, AR:0.2',
|
||||
'O2:0.1, H2:0.9']
|
||||
for comp in comps:
|
||||
self.phase.X = comp
|
||||
|
||||
denom = sum(self.phase.elemental_mole_fraction(i)
|
||||
* self.phase.atomic_weight(i)
|
||||
for i in range(self.phase.n_elements))
|
||||
|
||||
for i in range(self.phase.n_elements):
|
||||
self.assertNear(self.phase.elemental_mass_fraction(i),
|
||||
self.phase.elemental_mole_fraction(i)
|
||||
* self.phase.atomic_weight(i) / denom)
|
||||
|
||||
def test_weights(self):
|
||||
atomic_weights = self.phase.atomic_weights
|
||||
molecular_weights = self.phase.molecular_weights
|
||||
|
|
|
|||
|
|
@ -542,13 +542,15 @@ cdef class ThermoPhase(_SolutionBase):
|
|||
def elemental_mole_fraction(self, m):
|
||||
r"""
|
||||
Get the elemental mole fraction :math:`Z_{\mathrm{mole},m}` of element
|
||||
:math:`m` as defined by:
|
||||
:math:`m` (the number of atoms of element m divided by the total number
|
||||
of atoms) as defined by:
|
||||
|
||||
.. math:: Z_{\mathrm{mole},m} = \sum_k \frac{a_{m,k}}{\sum_j a_{j,k}} X_k
|
||||
.. math:: Z_{\mathrm{mole},m} = \frac{\sum_k a_{m,k} X_k}
|
||||
{\sum_k \sum_j a_{j,k} X_k}
|
||||
|
||||
with :math:`a_{m,k}` being the number of atoms of element :math:`m` in
|
||||
species :math:`k` and :math:`X_k` the mole fraction of species
|
||||
:math:`k`.
|
||||
species :math:`k`, :math:`\sum_j` being a sum over all elements, and
|
||||
:math:`X_k` being the mole fraction of species :math:`k`.
|
||||
|
||||
:param m:
|
||||
Base element, may be specified by name or by index.
|
||||
|
|
|
|||
|
|
@ -643,15 +643,19 @@ doublereal Phase::elementalMassFraction(const size_t m) const
|
|||
doublereal Phase::elementalMoleFraction(const size_t m) const
|
||||
{
|
||||
checkElementIndex(m);
|
||||
doublereal Z_n = 0.0;
|
||||
for (size_t k = 0; k != m_kk; ++k) {
|
||||
double nTotalAtoms = 0;
|
||||
for (size_t l = 0; l != m_mm; ++l) {
|
||||
nTotalAtoms += nAtoms(k, l);
|
||||
double denom = 0;
|
||||
for (size_t k = 0; k < m_kk; k++) {
|
||||
double atoms = 0;
|
||||
for (size_t j = 0; j < nElements(); j++) {
|
||||
atoms += nAtoms(k, j);
|
||||
}
|
||||
Z_n += nAtoms(k, m) / nTotalAtoms * moleFraction(k);
|
||||
denom += atoms * moleFraction(k);
|
||||
}
|
||||
return Z_n;
|
||||
doublereal numerator = 0.0;
|
||||
for (size_t k = 0; k != m_kk; ++k) {
|
||||
numerator += nAtoms(k, m) * moleFraction(k);
|
||||
}
|
||||
return numerator / denom;
|
||||
}
|
||||
|
||||
doublereal Phase::molarDensity() const
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue