1import unittest 2import cantera as ct 3from . import utilities 4 5 6class TestMixture(utilities.CanteraTest): 7 @classmethod 8 def setUpClass(self): 9 utilities.CanteraTest.setUpClass() 10 self.phase1 = ct.Solution('h2o2.yaml', transport_model=None) 11 self.phase2 = ct.Solution('air.yaml') 12 13 def setUp(self): 14 self.mix = ct.Mixture([(self.phase1, 1.0), (self.phase2, 2.0)]) 15 16 def test_sizes(self): 17 self.assertEqual(self.mix.n_phases, 2) 18 19 self.assertEqual(self.mix.n_species, 20 self.phase1.n_species + self.phase2.n_species) 21 22 E = set(self.phase1.element_names) | set(self.phase2.element_names) 23 self.assertEqual(len(E), self.mix.n_elements) 24 25 def test_element_index(self): 26 m_H = self.mix.element_index('H') 27 self.assertEqual(m_H, self.mix.element_index(m_H)) 28 29 with self.assertRaisesRegex(ValueError, 'No such element'): 30 self.mix.element_index('W') 31 32 with self.assertRaisesRegex(ValueError, 'No such element'): 33 self.mix.element_index(41) 34 35 with self.assertRaisesRegex(TypeError, 'must be a string or a number'): 36 self.mix.element_index(None) 37 38 def test_speciesIndex(self): 39 names = self.mix.species_names 40 kOH = names.index('OH') 41 kN2 = names.index('N2O') 42 self.assertEqual(self.mix.species_name(kOH), 'OH') 43 self.assertEqual(self.mix.species_name(kN2), 'N2O') 44 45 self.assertEqual(self.mix.species_index(0, 'OH'), kOH) 46 self.assertEqual(self.mix.species_index(self.phase1, 'OH'), kOH) 47 self.assertEqual(self.mix.species_index(self.phase1.name, 'OH'), kOH) 48 self.assertEqual(self.mix.species_index(0, self.phase1.species_index('OH')), kOH) 49 self.assertEqual(self.mix.species_index(1, self.phase2.species_index('N2O')), kN2) 50 self.assertEqual(self.mix.species_index(1, 'N2O'), kN2) 51 52 with self.assertRaisesRegex(IndexError, 'out of range'): 53 self.mix.species_index(3, 'OH') 54 55 with self.assertRaisesRegex(ValueError, 'No such species'): 56 self.mix.species_index(1, 'OH') 57 58 with self.assertRaisesRegex(ValueError, 'out of range'): 59 self.mix.species_index(0, -2) 60 61 with self.assertRaisesRegex(ValueError, 'No such species'): 62 self.mix.species_index(1, 'CO2') 63 64 def test_n_atoms(self): 65 names = self.mix.species_names 66 kOH = names.index('OH') 67 kN2 = names.index('N2') 68 mH = self.mix.element_index('H') 69 mN = self.mix.element_index('N') 70 71 self.assertEqual(self.mix.n_atoms(kOH, 'H'), 1) 72 self.assertEqual(self.mix.n_atoms(kOH, 'O'), 1) 73 self.assertEqual(self.mix.n_atoms(kOH, mH), 1) 74 self.assertEqual(self.mix.n_atoms(kOH, mN), 0) 75 76 self.assertEqual(self.mix.n_atoms(kN2, mN), 2) 77 self.assertEqual(self.mix.n_atoms(kN2, mH), 0) 78 79 def test_phase(self): 80 self.assertEqual(self.phase1, self.mix.phase(0)) 81 self.assertEqual(self.phase2, self.mix.phase(1)) 82 83 phaseNames = self.mix.phase_names 84 self.assertEqual(len(phaseNames), self.mix.n_phases) 85 self.assertEqual(phaseNames[0], self.phase1.name) 86 self.assertEqual(phaseNames[1], self.phase2.name) 87 88 def test_phase_index(self): 89 self.assertEqual(self.mix.phase_index(self.phase1), 0) 90 self.assertEqual(self.mix.phase_index(self.phase2), 1) 91 self.assertEqual(self.mix.phase_index(self.phase2.name), 1) 92 self.assertEqual(self.mix.phase_index(1), 1) 93 94 with self.assertRaises(KeyError): 95 self.mix.phase_index('foobar') 96 97 with self.assertRaises(IndexError): 98 self.mix.phase_index(2) 99 100 def test_properties(self): 101 self.mix.T = 350 102 self.assertEqual(self.mix.T, 350) 103 104 self.mix.P = 2e5 105 self.assertEqual(self.mix.P, 2e5) 106 self.assertEqual(self.mix.T, 350) 107 108 self.assertGreater(self.mix.max_temp, self.mix.min_temp) 109 110 def test_charge(self): 111 C = sum(self.mix.phase_charge(i) for i in range(self.mix.n_phases)) 112 self.assertEqual(self.mix.charge, C) 113 114 def test_phase_moles(self): 115 M = self.mix.phase_moles() 116 self.assertEqual(M[0], self.mix.phase_moles(0)) 117 self.assertEqual(M[1], self.mix.phase_moles('air')) 118 119 self.mix.set_phase_moles('air', 4) 120 self.assertEqual(self.mix.phase_moles(1), 4) 121 122 def test_species_moles(self): 123 self.mix.species_moles = 'H2:1.0, NO2:4.0' 124 P = self.mix.phase_moles() 125 S = self.mix.species_moles 126 127 self.assertEqual(P[0], 1) 128 self.assertEqual(P[1], 4) 129 130 self.assertEqual(S[self.mix.species_index(0, 'H2')], 1) 131 self.assertEqual(S[self.mix.species_index(1, 'NO2')], 4) 132 133 S[2] = 7 134 self.mix.species_moles = S 135 self.assertNear(self.mix.species_moles[2], S[2]) 136 self.assertNear(self.mix.phase_moles(0), sum(S[:self.phase1.n_species])) 137 138 with self.assertRaises(ValueError): 139 self.mix.species_moles = (1,2,3) 140 141 with self.assertRaises(TypeError): 142 self.mix.species_moles = 9 143 144 def test_element_moles(self): 145 self.mix.species_moles = 'H2:1.0, OH:4.0' 146 147 self.assertNear(self.mix.element_moles('H'), 6) 148 self.assertNear(self.mix.element_moles('O'), 4) 149 self.assertNear(self.mix.element_moles('N'), 0) 150 151 def test_chemical_potentials(self): 152 C = self.mix.chemical_potentials 153 C1 = self.phase1.chemical_potentials 154 C2 = self.phase2.chemical_potentials 155 156 self.assertArrayNear(C[:self.phase1.n_species], C1) 157 self.assertArrayNear(C[self.phase1.n_species:], C2) 158 159 def test_equilibrate1(self): 160 self.mix.species_moles = 'H2:1.0, O2:0.5, N2:1.0' 161 self.mix.T = 400 162 self.mix.P = 2 * ct.one_atm 163 164 E1 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] 165 self.mix.equilibrate('TP', solver='vcs', estimate_equil=-1) 166 167 E2 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] 168 self.assertArrayNear(E1, E2) 169 self.assertNear(self.mix.T, 400) 170 self.assertNear(self.mix.P, 2 * ct.one_atm) 171 172 @unittest.expectedFailure # See https://github.com/Cantera/cantera/issues/1023 173 def test_equilibrate2(self): 174 self.mix.species_moles = 'H2:1.0, O2:0.5, N2:1.0' 175 self.mix.T = 400 176 self.mix.P = 2 * ct.one_atm 177 178 E1 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] 179 self.mix.equilibrate('TP', solver='gibbs') 180 181 E2 = [self.mix.element_moles(m) for m in range(self.mix.n_elements)] 182 self.assertArrayNear(E1, E2) 183 self.assertNear(self.mix.T, 400) 184 self.assertNear(self.mix.P, 2 * ct.one_atm) 185 186 def test_invalid_property(self): 187 x = self.mix 188 with self.assertRaises(AttributeError): 189 x.foobar = 300 190 with self.assertRaises(AttributeError): 191 x.foobar 192 193 def test_invalid_phase_type(self): 194 water = ct.Water() 195 with self.assertRaisesRegex(ct.CanteraError, 'not compatible'): 196 self.mix = ct.Mixture([(self.phase1, 1.0), (water, 2.0)]) 197