def test_write_csv_str_column(self): states = ct.SolutionArray(self.gas, 3, extra={'spam': 'eggs'}) outfile = self.test_work_path / "solutionarray.csv" states.write_csv(outfile) b = ct.SolutionArray(self.gas, extra={'spam'}) b.read_csv(outfile) self.assertEqual(list(states.spam), list(b.spam))
def test_write_hdf_str_column(self): outfile = pjoin(self.test_work_dir, 'solutionarray.h5') if os.path.exists(outfile): os.remove(outfile) states = ct.SolutionArray(self.gas, 3, extra={'spam': 'eggs'}) states.write_hdf(outfile, mode='w') b = ct.SolutionArray(self.gas, extra={'spam'}) b.read_hdf(outfile) self.assertEqual(list(states.spam), list(b.spam))
def test_restore_thermo_models(self): def check(a, b): self.assertArrayNear(a.T, b.T) self.assertArrayNear(a.P, b.P) self.assertArrayNear(a.X, b.X) for ph in self.yml['phases']: skipped = ['pure-fluid'] if ph['thermo'] in skipped: continue ph_name = ph['name'] try: sol = ct.Solution(self.yml_file, ph_name) a = ct.SolutionArray(sol, 10) if ph['thermo'] == 'liquid-water-IAPWS95': # ensure that phase remains liquid a.TP = sol.T, sol.critical_pressure # assign some state T = 373.15 + 100*np.random.rand(10) P = a.P * (1 + np.random.rand(10)) if sol.is_pure: a.TP = T, P else: X = a.X xmin = np.min(X[X>0]) ix = np.where(xmin) X[ix] = .5 * X[ix] X = np.diag(X.sum(axis=1)).dot(X) self.assertFalse(sol.is_pure) self.assertIn('TPX', sol._full_states.values()) a.TPX = T, P, X # default columns data = a.collect_data() b = ct.SolutionArray(sol) b.restore_data(data) check(a, b) except Exception as inst: # raise meaningful error message without breaking test suite # ignore deprecation warnings originating in C++ layer # (converted to errors in test suite) if 'Deprecated' not in str(inst): msg = ("Error in processing of phase '{}' with type '{}'\n" "TPX = {}") msg = msg.format(ph['name'], ph['thermo'], sol.TPX) raise TypeError(msg) from inst
def test_collect_data(self): states = ct.SolutionArray(self.gas) collected = states.collect_data(tabular=True) self.assertIsInstance(collected, dict) self.assertIn('Y_H2', collected) self.assertEqual(len(collected['Y_H2']), 0) states = ct.SolutionArray(self.gas) collected = states.collect_data(tabular=False, species='X') self.assertIn('X', collected) self.assertEqual(collected['X'].shape, (0, self.gas.n_species))
def test_write_hdf_str_column(self): outfile = self.test_work_path / "solutionarray.h5" # In Python >= 3.8, this can be replaced by the missing_ok argument if outfile.is_file(): outfile.unlink() states = ct.SolutionArray(self.gas, 3, extra={'spam': 'eggs'}) states.write_hdf(outfile, mode='w') b = ct.SolutionArray(self.gas, extra={'spam'}) b.read_hdf(outfile) self.assertEqual(list(states.spam), list(b.spam))
def test_write_hdf_multidim_column(self): outfile = self.test_work_path / "solutionarray.h5" # In Python >= 3.8, this can be replaced by the missing_ok argument if outfile.is_file(): outfile.unlink() states = ct.SolutionArray(self.gas, 3, extra={'spam': [[1, 2], [3, 4], [5, 6]]}) states.write_hdf(outfile, mode='w') b = ct.SolutionArray(self.gas, extra={'spam'}) b.read_hdf(outfile) self.assertArrayNear(states.spam, b.spam)
def test_write_hdf_multidim_column(self): outfile = pjoin(self.test_work_dir, 'solutionarray.h5') if os.path.exists(outfile): os.remove(outfile) states = ct.SolutionArray(self.gas, 3, extra={'spam': [[1, 2], [3, 4], [5, 6]]}) states.write_hdf(outfile, mode='w') b = ct.SolutionArray(self.gas, extra={'spam'}) b.read_hdf(outfile) self.assertArrayNear(states.spam, b.spam)
def test_write_csv_single_row(self): gas = ct.Solution("gri30.yaml") states = ct.SolutionArray(gas) states.append(T=300., P=ct.one_atm, X="CH4:0.5, O2:0.4") states.equilibrate("HP") outfile = self.test_work_path / "solutionarray.csv" states.write_csv(outfile) b = ct.SolutionArray(gas) b.read_csv(outfile) self.assertArrayNear(states.T, b.T) self.assertArrayNear(states.P, b.P) self.assertArrayNear(states.X, b.X)
def test_slicing_ndim(self): states = ct.SolutionArray(self.gas, (2, 5)) states.TPX = np.linspace(500, 1000, 5), 2e5, 'H2:0.5, O2:0.4' T0 = states.T H0 = states.enthalpy_mass # Verify that original object is updated when slices change row2 = states[1] row2.TD = 300, 0.5 T = states.T D = states.density self.assertArrayNear(T[0], T0[0]) self.assertArrayNear(T[1], 300 * np.ones(5)) self.assertArrayNear(D[1], 0.5 * np.ones(5)) col3 = states[:, 2] col3.TD = 400, 2.5 T = states.T D = states.density self.assertArrayNear(T[:, 2], 400 * np.ones(2)) self.assertArrayNear(D[:, 2], 2.5 * np.ones(2)) # Verify that the slices are updated when the original object changes states.TP = 900, None self.assertArrayNear(col3.T, 900 * np.ones(2)) self.assertArrayNear(row2.T, 900 * np.ones(5))
def plug_flow_reactor(self, gas, details, length, area, u_0, **kwargs): # set default values var = {'observable': {'main': 'Concentration', 'sub': 0}, 't_lab_save': None, 'rtol': 1E-4, 'atol': 1E-7} var.update(kwargs) # Modify reactor if necessary for frozen composition and isothermal reactor.energy_enabled = var['solve_energy'] reactor.chemistry_enabled = not var['frozen_comp'] # Create Sim sim = ct.ReactorNet([reactor]) sim.atol = var['atol'] sim.rtol = var['rtol'] # set up times and observables ind_var = 't_lab' # INDEPENDENT VARIABLE CURRENTLY HARDCODED FOR t_lab if var['t_lab_save'] is None: t_all = [t_end] else: t_all = np.sort(np.unique(np.concatenate(([t_end], var['t_lab_save'])))) # combine t_end and t_save, sort, only unique values self.ODE_success = True details['success'] = True states = ct.SolutionArray(gas, extra=['t']) states.append(reactor.thermo.state, t = 0.0) for t in t_all: if not self.ODE_success: break while sim.time < t: # integrator step until time > target time try: sim.step() if sim.time > t: # force interpolation to target time sim.advance(t) states.append(reactor.thermo.state, t=sim.time) except: self.ODE_success = False details['success'] = False explanation = '\nCheck for: Fast rates or bad thermo data' checkRxns = self.checkRxnRates(gas) if len(checkRxns) > 0: explanation += '\nSuggested Reactions: ' + ', '.join([str(x) for x in checkRxns]) details['message'] = '\nODE Error: {:s}\n{:s}\n'.format(str(sys.exc_info()[1]), explanation) break reactor_vars = ['t_lab', 'T', 'P', 'h_tot', 'h', 's_tot', 's', 'rho', 'Y', 'X', 'conc', 'wdot', 'wdotfor', 'wdotrev', 'HRR_tot', 'HRR', 'delta_h', 'delta_s', 'eq_con', 'rate_con', 'rate_con_rev', 'net_ROP', 'for_ROP', 'rev_ROP'] num = {'reac': np.sum(gas.reactant_stoich_coeffs(), axis=0), 'prod': np.sum(gas.product_stoich_coeffs(), axis=0), 'rxns': gas.n_reactions} SIM = Simulation_Result(num, states, reactor_vars) SIM.finalize(self.ODE_success, ind_var, var['observable'], units='CGS') return SIM, details
def runsim(tmax, temp, pres, ics, sensitivity): dt = tmax / Npoints gas.TPX = temp, pres, ics r = ct.IdealGasReactor(gas, name='R1') sim = ct.ReactorNet([r]) nr = gas.n_reactions for i in range(0, nr): r.add_sensitivity_reaction(i) sim.rtol = 1.0e-8 sim.atol = 1.0e-14 sim.rtol_sensitivity = 1.0e-8 sim.atol_sensitivity = 1.0e-8 states = ct.SolutionArray(gas, extra=['t', 'sens']) for i in range(0, int(Npoints)): t = i * dt sim.advance(t) print("%5f" % (t / tmax), end='\r') sys.stdout.flush() sensitivities = [] for i in range(0, nr): sensitivities.append(sim.sensitivity(sensitivity, i)) states.append(r.thermo.state, t=t, sens=sensitivities) return states
def setUp(self): self._gas = ct.Solution('h2o2.yaml') self._arr = ct.SolutionArray(self._gas, 2) self._arr.TP = 300., ct.one_atm self._output.save(self._arr, 'foo') self._arr.TP = 500., ct.one_atm self._output.save(self._arr, 'bar')
def test_getitem(self): states = ct.SolutionArray(self.gas, 10, extra={"index": range(10)}) for ix, state in enumerate(states): assert state.index == ix assert list(states[:2].index) == [0, 1] assert list(states[100:102].index) == [] # outside of range
def test_Reactor(self): phase = ct.PureFluid('liquidvapor.xml', 'oxygen') air = ct.Solution('air.xml') phase.TP = 93, 4e5 r1 = ct.Reactor(phase) r1.volume = 0.1 air.TP = 300, 4e5 r2 = ct.Reactor(air) r2.volume = 10.0 air.TP = 500, 4e5 env = ct.Reservoir(air) w1 = ct.Wall(r1,r2) w1.expansion_rate_coeff = 1e-3 w2 = ct.Wall(env,r1, Q=500000, A=1) net = ct.ReactorNet([r1,r2]) net.atol = 1e-10 net.rtol = 1e-6 states = ct.SolutionArray(phase, extra='t') for t in np.arange(0.0, 60.0, 1): net.advance(t) states.append(TD=r1.thermo.TD, t=net.time) self.assertEqual(states.X[0], 0) self.assertEqual(states.X[-1], 1) self.assertNear(states.X[30], 0.54806, 1e-4)
def load_like(self, entry, other): "" if other is None: return None fname = Path(self.output_name) if not fname.is_file(): return None with h5py.File(fname, 'r') as hdf: if entry not in hdf.keys(): return None if type(other).__name__ == 'SolutionArray': if isinstance(ct, ImportError): raise ct # pylint: disable=raising-bad-type extra = list(other._extra.keys()) out = ct.SolutionArray(other._phase, extra=extra) out.read_hdf(fname, group=entry) return out elif type(other).__name__ == 'FreeFlame': if isinstance(ct, ImportError): raise ct # pylint: disable=raising-bad-type out = ct.FreeFlame(other.gas) out.read_hdf(fname, group=entry) return out raise NotImplementedError("Loader not implemented for '{}'".format( type(other).__name__))
def states_new_init(A): R_new = ct.Reaction.fromCti('''reaction('O2 + 2 H2 => 2 H2O', [%e, 0.0, 0.0])''' % (A)) #print(type(R_new)) #print(type(gas.reactions())) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=gas.species(), reactions=[R_new]) gas2.TPX = initial_state r_new = ct.IdealGasConstPressureReactor(gas2, energy='off') t_new = 0.0 states_new = ct.SolutionArray(gas2, extra=['t']) sim_new = ct.ReactorNet([r_new]) tt = [] TT = [] for n in range(100): '''t_new += 1.e-5 sim_new.advance(t_new) #print(t_new) tt.append(1000 * t_new*1000) TT.append(r_new.T)''' t_new += 1.e-5 sim_new.advance(t_new) states_new.append(r_new.thermo.state, t=t_new * 1e3) return states_new, gas2
def solve(gas, t): # Set the temperature and pressure for gas # t is different from t0 gas.TPX = t, pressure, composition surf.TP = t, pressure TDY = gas.TDY cov = surf.coverages # create a new reactor gas.TDY = TDY r = ct.IdealGasReactor(gas, energy='on') r.volume = rvol upstream = ct.Reservoir(gas, name='upstream') downstream = ct.Reservoir(gas, name='downstream') rsurf = ct.ReactorSurface(surf, r, A=cat_area) m = ct.MassFlowController(upstream, r, mdot=mass_flow_rate) v = ct.PressureController(r, downstream, master=m, K=1e-5) sim = ct.ReactorNet([r]) sim.max_err_test_fails = 20 sim.rtol = 1.0e-9 sim.atol = 1.0e-21 # define time, space, and other information vectors z2 = (np.arange(NReactors)) * rlen * 1e3 t_r2 = np.zeros_like(z2) # residence time in each reactor t2 = np.zeros_like(z2) states2 = ct.SolutionArray(gas) for n in range(NReactors): # Set the state of the reservoir to match that of the previous reactor gas.TDY = r.thermo.TDY upstream.syncState() sim.reinitialize() sim.advance_to_steady_state() dist = n * rlen * 1.0e3 # distance in mm t_r2[n] = r.mass / mass_flow_rate # residence time in this reactor t2[n] = np.sum(t_r2) states2.append(gas.state) print('Temperature of Gas :', t, ' residence time :', t2[-1]) MolFrac_CH4 = states2('CH4').X MolFrac_CO2 = states2('CO2').X MolFrac_CO = states2('CO').X MolFrac_H2 = states2('H2').X MolFrac_H2O = states2('H2O').X MolFrac_O2 = states2('O2').X kq = np.zeros(6) kq[0] = MolFrac_CH4[-1] * 100 kq[1] = MolFrac_CO2[-1] * 100 kq[2] = MolFrac_CO[-1] * 100 kq[3] = MolFrac_H2[-1] * 100 kq[4] = MolFrac_H2O[-1] * 100 kq[5] = MolFrac_O2[-1] * 100 return kq
def test_append_no_norm_water(self): w = ct.Water() states = ct.SolutionArray(w) w.TQ = 300, 0.5 states.append(w.state) self.assertEqual(states[0].T, w.T) self.assertEqual(states[0].P, w.P) self.assertEqual(states[0].Q, w.Q)
def test_append_state(self): gas = ct.Solution("h2o2.yaml") gas.TPX = 300, ct.one_atm, 'H2:0.5, O2:0.4' states = ct.SolutionArray(gas) states.append(gas.state) self.assertEqual(states[0].T, gas.T) self.assertEqual(states[0].P, gas.P) self.assertArrayNear(states[0].X, gas.X)
def test_import_no_norm_water(self): outfile = self.test_work_path / "solutionarray.h5" # In Python >= 3.8, this can be replaced by the missing_ok argument if outfile.is_file(): outfile.unlink() w = ct.Water() w.TQ = 300, 0.5 states = ct.SolutionArray(w, 5) states.write_hdf(outfile) w_new = ct.Water() c = ct.SolutionArray(w_new) c.read_hdf(outfile, normalize=False) self.assertArrayNear(states.T, c.T) self.assertArrayNear(states.P, c.P) self.assertArrayNear(states.Q, c.Q)
def test_import_no_norm_data(self): outfile = self.test_work_path / "solutionarray.h5" # In Python >= 3.8, this can be replaced by the missing_ok argument if outfile.is_file(): outfile.unlink() gas = ct.Solution("h2o2.yaml") gas.set_unnormalized_mole_fractions(np.full(gas.n_species, 0.3)) states = ct.SolutionArray(gas, 5) states.write_hdf(outfile) gas_new = ct.Solution("h2o2.yaml") b = ct.SolutionArray(gas_new) b.read_hdf(outfile, normalize=False) self.assertArrayNear(states.T, b.T) self.assertArrayNear(states.P, b.P) self.assertArrayNear(states.X, b.X)
def test_write_csv(self): states = ct.SolutionArray(self.gas, 7) states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4' states.equilibrate('HP') outfile = self.test_work_path / "solutionarray.csv" states.write_csv(outfile) data = np.genfromtxt(outfile, names=True, delimiter=',') self.assertEqual(len(data), 7) self.assertEqual(len(data.dtype), self.gas.n_species + 2) self.assertIn('Y_H2', data.dtype.fields) b = ct.SolutionArray(self.gas) b.read_csv(outfile) self.assertArrayNear(states.T, b.T) self.assertArrayNear(states.P, b.P) self.assertArrayNear(states.X, b.X)
def test_append_no_norm_data(self): gas = ct.Solution("h2o2.yaml") gas.TP = 300, ct.one_atm gas.set_unnormalized_mass_fractions(np.full(gas.n_species, 0.3)) states = ct.SolutionArray(gas) states.append(T=gas.T, P=gas.P, Y=gas.Y, normalize=False) self.assertEqual(states[0].T, gas.T) self.assertEqual(states[0].P, gas.P) self.assertArrayNear(states[0].Y, gas.Y)
def test_to_pandas(self): states = ct.SolutionArray(self.gas, 7, extra={"props": range(7)}) states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4' df = states.to_pandas() self.assertEqual(df.shape[0], 7) states.props = np.zeros((7,2,)) with self.assertRaisesRegex(NotImplementedError, 'not supported'): states.to_pandas()
def test_write_hdf(self): outfile = self.test_work_path / "solutionarray.h5" # In Python >= 3.8, this can be replaced by the missing_ok argument if outfile.is_file(): outfile.unlink() extra = {'foo': range(7), 'bar': range(7)} meta = {'spam': 'eggs', 'hello': 'world'} states = ct.SolutionArray(self.gas, 7, extra=extra, meta=meta) states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4' states.equilibrate('HP') states.write_hdf(outfile, attrs={'foobar': 'spam and eggs'}) b = ct.SolutionArray(self.gas) attr = b.read_hdf(outfile) self.assertArrayNear(states.T, b.T) self.assertArrayNear(states.P, b.P) self.assertArrayNear(states.X, b.X) self.assertArrayNear(states.foo, b.foo) self.assertArrayNear(states.bar, b.bar) self.assertEqual(b.meta['spam'], 'eggs') self.assertEqual(b.meta['hello'], 'world') self.assertEqual(attr['foobar'], 'spam and eggs') gas = ct.Solution('gri30.yaml', transport_model=None) ct.SolutionArray(gas, 10).write_hdf(outfile) with _h5py.File(outfile, 'a') as hdf: hdf.create_group('spam') c = ct.SolutionArray(self.gas) with self.assertRaisesRegex(IOError, 'does not contain valid data'): c.read_hdf(outfile, group='spam') with self.assertRaisesRegex(IOError, 'does not contain group'): c.read_hdf(outfile, group='eggs') with self.assertRaisesRegex(IOError, 'phases do not match'): c.read_hdf(outfile, group='group1') with self.assertRaisesRegex(IOError, 'does not contain data'): c.read_hdf(outfile, subgroup='foo') states.write_hdf(outfile, group='foo/bar/baz') c.read_hdf(outfile, group='foo/bar/baz') self.assertArrayNear(states.T, c.T)
def test_write_hdf(self): outfile = pjoin(self.test_work_dir, 'solutionarray.h5') if os.path.exists(outfile): os.remove(outfile) extra = {'foo': range(7), 'bar': range(7)} meta = {'spam': 'eggs', 'hello': 'world'} states = ct.SolutionArray(self.gas, 7, extra=extra, meta=meta) states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4' states.equilibrate('HP') states.write_hdf(outfile, attrs={'foobar': 'spam and eggs'}) b = ct.SolutionArray(self.gas) attr = b.read_hdf(outfile) self.assertTrue(np.allclose(states.T, b.T)) self.assertTrue(np.allclose(states.P, b.P)) self.assertTrue(np.allclose(states.X, b.X)) self.assertTrue(np.allclose(states.foo, b.foo)) self.assertTrue(np.allclose(states.bar, b.bar)) self.assertEqual(b.meta['spam'], 'eggs') self.assertEqual(b.meta['hello'], 'world') self.assertEqual(attr['foobar'], 'spam and eggs') gas = ct.Solution('gri30.yaml') ct.SolutionArray(gas, 10).write_hdf(outfile) with _h5py.File(outfile, 'a') as hdf: hdf.create_group('spam') c = ct.SolutionArray(self.gas) with self.assertRaisesRegex(IOError, 'does not contain valid data'): c.read_hdf(outfile, group='spam') with self.assertRaisesRegex(IOError, 'does not contain group'): c.read_hdf(outfile, group='eggs') with self.assertRaisesRegex(IOError, 'phases do not match'): c.read_hdf(outfile, group='group1') with self.assertRaisesRegex(IOError, 'does not contain data'): c.read_hdf(outfile, subgroup='foo') states.write_hdf(outfile, group='foo/bar/baz') c.read_hdf(outfile, group='foo/bar/baz') self.assertTrue(np.allclose(states.T, c.T))
def totaldelaydata1(ITemp, IPressure, Ifraction, IER): Temp = np.zeros(ITemp) a = np.zeros(Ifraction) pressure = np.zeros(IPressure) ER = np.zeros(IER) # write output CSV file for importing into Excel gas = ct.Solution('gri30.xml') #writer.writerow(gas.species_names) for i in range(ITemp): Temp[i] = 1000.0 + 50 * i for m in range(IPressure): pressure[m] = 1 * ct.one_atm + 5.0 * m * ct.one_atm for n in range(Ifraction): a[n] = 0.1 * n for e in range(IER): gas.TP = Temp[i], pressure[m] ER[e] = 0.5 + 0.1 * e fO2 = ((1 - a[n]) * 2.0 + a[n] * 0.5) * (1 / ER[e]) CH4_P = 1 - a[n] H2_P = a[n] O2_P = fO2 N2_P = 3.76 * fO2 gas.X = { 'CH4': 1 - a[n], 'H2': a[n], 'O2': fO2, 'N2': 3.76 * fO2 } r = ct.IdealGasConstPressureReactor(gas) sim = ct.ReactorNet([r]) time = 0.0 states = ct.SolutionArray(gas, extra=['t']) #print('%10s %10s %10s %14s' % ('t [s]','T [K]','P [Pa]','u [J/kg]')) for number in range(10000): time += 1.e-6 sim.advance(time) states.append(r.thermo.state, t=time * 1e3) #print('%10.3e %10.3f %10.3f %14.6e' % (sim.time, r.T,r.thermo.P, r.thermo.u)) X_OH = np.max(states.X[:, gas.species_index('OH')]) X_HO2 = np.max(states.X[:, gas.species_index('HO2')]) # We will use the 'OH' species to compute the ignition delay max_index = np.argmax(states.X[:, gas.species_index('OH')]) Tau1 = states.t[max_index] # We will use the 'HO2' species to compute the ignition delay #max_index = np.argmax(states.X[:, gas.species_index('HO2')]) #Tau2[i] = states.t[max_index] # writer.writerow([pressure, Temp[i], CH4_P, H2_P, # O2_P, N2_P, ER, X_OH[i], X_HO2[i], Tau1[i]]) yield pressure[m], Temp[ i], CH4_P, H2_P, O2_P, N2_P, X_OH, X_HO2, Tau1 gas = ct.Solution('gri30.xml')
def test_get_state(self): states = ct.SolutionArray(self.gas, 4) H, P = states.HP self.assertEqual(H.shape, (4, )) self.assertEqual(P.shape, (4, )) S, P, Y = states.SPY self.assertEqual(S.shape, (4, )) self.assertEqual(P.shape, (4, )) self.assertEqual(Y.shape, (4, self.gas.n_species))
def test_write_csv_multidim_column(self): states = ct.SolutionArray(self.gas, 3, extra={'spam': np.zeros(( 3, 5, ))}) outfile = self.test_work_path / "solutionarray.csv" with self.assertRaisesRegex(NotImplementedError, 'not supported'): states.write_csv(outfile)
def test_to_pandas(self): states = ct.SolutionArray(self.gas, 7) states.TPX = np.linspace(300, 1000, 7), 2e5, 'H2:0.5, O2:0.4' try: # this will run through if pandas is installed df = states.to_pandas() self.assertEqual(df.shape[0], 7) except ImportError as err: # pandas is not installed and correct exception is raised pass