import unittest import cantera as ct from . import utilities class TestMixture(utilities.CanteraTest): @classmethod def setUpClass(self): utilities.CanteraTest.setUpClass() self.phase1 = ct.Solution('h2o2.yaml', transport_model=None) self.phase2 = ct.Solution('air.yaml') def setUp(self): self.mix = ct.Mixture([(self.phase1, 1.0), (self.phase2, 2.0)]) def test_sizes(self): self.assertEqual(self.mix.n_phases, 2) self.assertEqual(self.mix.n_species, self.phase1.n_species + self.phase2.n_species) E = set(self.phase1.element_names) | set(self.phase2.element_names) self.assertEqual(len(E), self.mix.n_elements) def test_element_index(self): m_H = self.mix.element_index('H') self.assertEqual(m_H, self.mix.element_index(m_H)) with self.assertRaisesRegex(ValueError, 'No such element'): self.mix.element_index('W') with self.assertRaisesRegex(ValueError, 'No such element'): self.mix.element_index(41) with self.assertRaisesRegex(TypeError, 'must be a string or a number'): self.mix.element_index(None) def test_speciesIndex(self): names = self.mix.species_names kOH = names.index('OH') kN2 = names.index('N2O') self.assertEqual(self.mix.species_name(kOH), 'OH') self.assertEqual(self.mix.species_name(kN2), 'N2O') self.assertEqual(self.mix.species_index(0, 'OH'), kOH) self.assertEqual(self.mix.species_index(self.phase1, 'OH'), kOH) self.assertEqual(self.mix.species_index(self.phase1.name, 'OH'), kOH) self.assertEqual(self.mix.species_index(0, self.phase1.species_index('OH')), kOH) self.assertEqual(self.mix.species_index(1, self.phase2.species_index('N2O')), kN2) self.assertEqual(self.mix.species_index(1, 'N2O'), kN2) with self.assertRaisesRegex(IndexError, 'out of range'): self.mix.species_index(3, 'OH') with self.assertRaisesRegex(ValueError, 'No such species'): self.mix.species_index(1, 'OH') with self.assertRaisesRegex(ValueError, 'out of range'): self.mix.species_index(0, -2) with self.assertRaisesRegex(ValueError, 'No such species'): self.mix.species_index(1, 'CO2') def test_n_atoms(self): names = self.mix.species_names kOH = names.index('OH') kN2 = names.index('N2') mH = self.mix.element_index('H') mN = self.mix.element_index('N') self.assertEqual(self.mix.n_atoms(kOH, 'H'), 1) self.assertEqual(self.mix.n_atoms(kOH, 'O'), 1) self.assertEqual(self.mix.n_atoms(kOH, mH), 1) self.assertEqual(self.mix.n_atoms(kOH, mN), 0) self.assertEqual(self.mix.n_atoms(kN2, mN), 2) self.assertEqual(self.mix.n_atoms(kN2, mH), 0) def test_phase(self): self.assertEqual(self.phase1, self.mix.phase(0)) self.assertEqual(self.phase2, self.mix.phase(1)) phaseNames = self.mix.phase_names self.assertEqual(len(phaseNames), self.mix.n_phases) self.assertEqual(phaseNames[0], self.phase1.name) self.assertEqual(phaseNames[1], self.phase2.name) def test_phase_index(self): self.assertEqual(self.mix.phase_index(self.phase1), 0) self.assertEqual(self.mix.phase_index(self.phase2), 1) self.assertEqual(self.mix.phase_index(self.phase2.name), 1) self.assertEqual(self.mix.phase_index(1), 1) with self.assertRaises(KeyError): self.mix.phase_index('foobar') with self.assertRaises(IndexError): self.mix.phase_index(2) def test_properties(self): self.mix.T = 350 self.assertEqual(self.mix.T, 350) self.mix.P = 2e5 self.assertEqual(self.mix.P, 2e5) self.assertEqual(self.mix.T, 350) self.assertGreater(self.mix.max_temp, self.mix.min_temp) def test_charge(self): C = sum(self.mix.phase_charge(i) for i in range(self.mix.n_phases)) self.assertEqual(self.mix.charge, C) def test_phase_moles(self): M = self.mix.phase_moles() self.assertEqual(M[0], self.mix.phase_moles(0)) self.assertEqual(M[1], self.mix.phase_moles('air')) self.mix.set_phase_moles('air', 4) self.assertEqual(self.mix.phase_moles(1), 4) def test_species_moles(self): self.mix.species_moles = 'H2:1.0, NO2:4.0' P = self.mix.phase_moles() S = self.mix.species_moles self.assertEqual(P[0], 1) self.assertEqual(P[1], 4) self.assertEqual(S[self.mix.species_index(0, 'H2')], 1) self.assertEqual(S[self.mix.species_index(1, 'NO2')], 4) S[2] = 7 self.mix.species_moles = S self.assertNear(self.mix.species_moles[2], S[2]) self.assertNear(self.mix.phase_moles(0), sum(S[:self.phase1.n_species])) with self.assertRaises(ValueError): self.mix.species_moles = (1,2,3) with self.assertRaises(TypeError): self.mix.species_moles = 9 def test_element_moles(self): self.mix.species_moles = 'H2:1.0, OH:4.0' self.assertNear(self.mix.element_moles('H'), 6) self.assertNear(self.mix.element_moles('O'), 4) self.assertNear(self.mix.element_moles('N'), 0) def test_chemical_potentials(self): C = self.mix.chemical_potentials C1 = self.phase1.chemical_potentials C2 = self.phase2.chemical_potentials self.assertArrayNear(C[:self.phase1.n_species], C1) self.assertArrayNear(C[self.phase1.n_species:], C2) def test_equilibrate1(self): self.mix.species_moles = 'H2:1.0, O2:0.5, N2:1.0' self.mix.T = 400 self.mix.P = 2 * ct.one_atm E1 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] self.mix.equilibrate('TP', solver='vcs', estimate_equil=-1) E2 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] self.assertArrayNear(E1, E2) self.assertNear(self.mix.T, 400) self.assertNear(self.mix.P, 2 * ct.one_atm) @unittest.expectedFailure # See https://github.com/Cantera/cantera/issues/1023 def test_equilibrate2(self): self.mix.species_moles = 'H2:1.0, O2:0.5, N2:1.0' self.mix.T = 400 self.mix.P = 2 * ct.one_atm E1 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] self.mix.equilibrate('TP', solver='gibbs') E2 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] self.assertArrayNear(E1, E2) self.assertNear(self.mix.T, 400) self.assertNear(self.mix.P, 2 * ct.one_atm) def test_invalid_property(self): x = self.mix with self.assertRaises(AttributeError): x.foobar = 300 with self.assertRaises(AttributeError): x.foobar def test_invalid_phase_type(self): water = ct.Water() with self.assertRaisesRegex(ct.CanteraError, 'not compatible'): self.mix = ct.Mixture([(self.phase1, 1.0), (water, 2.0)])