def test_mixture_averaged(self, saveReference=False): T_in = 373.0 # inlet temperature comp = 'H2:1.6, O2:1, AR:7' # premixed gas composition gas = ct.Solution('h2o2.xml') gas.TPX = T_in, 0.05 * ct.one_atm, comp width = 0.2 # m sim = ct.CounterflowPremixedFlame(gas=gas, width=width) # set the properties at the inlets sim.reactants.mdot = 0.12 # kg/m^2/s sim.reactants.X = comp sim.reactants.T = T_in sim.products.mdot = 0.06 # kg/m^2/s sim.flame.set_steady_tolerances(default=[1.0e-5, 1.0e-11]) sim.flame.set_transient_tolerances(default=[1.0e-5, 1.0e-11]) sim.set_initial_guess() # assume adiabatic equilibrium products sim.energy_enabled = False sim.solve(loglevel=0, refine_grid=False) sim.set_refine_criteria(ratio=3, slope=0.2, curve=0.4, prune=0.02) sim.energy_enabled = True self.assertFalse(sim.radiation_enabled) sim.solve(loglevel=0, refine_grid=True) data = np.empty((sim.flame.n_points, gas.n_species + 4)) data[:, 0] = sim.grid data[:, 1] = sim.velocity data[:, 2] = sim.spread_rate data[:, 3] = sim.T data[:, 4:] = sim.Y.T referenceFile = pjoin(self.test_data_dir, 'CounterflowPremixedFlame-h2-mix.csv') if saveReference: np.savetxt(referenceFile, data, '%11.6e', ', ') else: bad = utilities.compareProfiles(referenceFile, data, rtol=1e-2, atol=1e-8, xtol=1e-2) self.assertFalse(bad, bad) filename = pjoin(self.test_work_dir, 'CounterflowPremixedFlame-h2-mix.csv') sim.write_csv(filename) # check output self.assertTrue(os.path.exists(filename)) csv_data = np.genfromtxt(filename, dtype=float, delimiter=',', names=True) self.assertNotIn('qdot', csv_data.dtype.names) os.remove(filename)
def run_case(self, phi, T, width, P): gas = ct.Solution('h2o2.xml') gas.TPX = T, P * ct.one_atm, {'H2': phi, 'O2': 0.5, 'AR': 2} sim = ct.CounterflowPremixedFlame(gas=gas, width=width) sim.reactants.mdot = 10 * gas.density sim.products.mdot = 5 * gas.density sim.set_refine_criteria(ratio=6, slope=0.7, curve=0.8, prune=0.4) sim.solve(loglevel=0, auto=True) self.assertTrue(all(sim.T >= T - 1e-3)) self.assertTrue(all(sim.spread_rate >= -1e-9)) return sim
def solve_flame(gas): gas.TPX = 373, 0.05*ct.one_atm, 'H2:0.4, CO:0.6, O2:1, N2:3.76' # Create the flame simulation object sim = ct.CounterflowPremixedFlame(gas=gas, width=0.2) sim.reactants.mdot = 0.12 # kg/m^2/s sim.products.mdot = 0.06 # kg/m^2/s sim.set_refine_criteria(ratio=3, slope=0.1, curve=0.2) sim.solve(0, auto=True) return sim
def __init__(self, solution, chemistry, fuel, oxidizer={ 'O2': 1., 'N2': 3.76 }, T=None): self.chemistry = chemistry gas = ct.Solution(chemistry, loglevel=0) flame = ct.CounterflowPremixedFlame(gas, width=0.1) flame.restore(solution, loglevel=0) PremixedFlameState.__init__(self, flame, fuel, oxidizer, T)
def test_mixture_averaged(self, saveReference=False): T_in = 373.0 # inlet temperature comp = 'H2:1.6, O2:1, AR:7' # premixed gas composition gas = ct.Solution('h2o2.xml') gas.TPX = T_in, 0.05 * ct.one_atm, comp initial_grid = np.linspace(0.0, 0.2, 12) # m sim = ct.CounterflowPremixedFlame(gas=gas, grid=initial_grid) # set the properties at the inlets sim.reactants.mdot = 0.12 # kg/m^2/s sim.reactants.X = comp sim.reactants.T = T_in sim.products.mdot = 0.06 # kg/m^2/s sim.flame.set_steady_tolerances(default=[1.0e-5, 1.0e-11]) sim.flame.set_transient_tolerances(default=[1.0e-5, 1.0e-11]) sim.set_initial_guess() # assume adiabatic equilibrium products sim.energy_enabled = False sim.solve(loglevel=0, refine_grid=False) sim.set_refine_criteria(ratio=3, slope=0.2, curve=0.4, prune=0.02) sim.energy_enabled = True self.assertFalse(sim.radiation_enabled) sim.solve(loglevel=0, refine_grid=True) data = np.empty((sim.flame.n_points, gas.n_species + 4)) data[:, 0] = sim.grid data[:, 1] = sim.u data[:, 2] = sim.V data[:, 3] = sim.T data[:, 4:] = sim.Y.T if saveReference: np.savetxt(self.referenceFile, data, '%11.6e', ', ') else: bad = utilities.compareProfiles(self.referenceFile, data, rtol=1e-2, atol=1e-8, xtol=1e-2) self.assertFalse(bad, bad)
def solve_flame(gas): gas.TPX = 373, 0.05*ct.one_atm, 'H2:0.4, CO:0.6, O2:1, N2:3.76' # Create the flame simulation object sim = ct.CounterflowPremixedFlame(gas=gas, grid=np.linspace(0.0, 0.2, 10)) sim.reactants.mdot = 0.12 # kg/m^2/s sim.products.mdot = 0.06 # kg/m^2/s sim.flame.set_steady_tolerances(default=[1.0e-7, 1.0e-13]) sim.flame.set_transient_tolerances(default=[1.0e-7, 1.0e-11]) sim.set_initial_guess() sim.energy_enabled = False sim.solve(0, refine_grid=False) sim.set_refine_criteria(ratio=3, slope=0.1, curve=0.2) sim.energy_enabled = True sim.solve(0, refine_grid=True) return sim
mdot_reactants = 0.12 # kg/m^2/s mdot_products = 0.06 # kg/m^2/s rxnmech = 'h2o2.yaml' # reaction mechanism file comp = 'H2:1.6, O2:1, AR:7' # premixed gas composition width = 0.2 # m loglevel = 1 # amount of diagnostic output (0 to 5) # Set up the problem gas = ct.Solution(rxnmech) # set state to that of the unburned gas at the burner gas.TPX = T_in, p, comp # Create the flame simulation object sim = ct.CounterflowPremixedFlame(gas=gas, width=width) # Set grid refinement parameters sim.set_refine_criteria(ratio=3, slope=0.1, curve=0.2, prune=0.02) # set the boundary flow rates sim.reactants.mdot = mdot_reactants sim.products.mdot = mdot_products sim.set_initial_guess() # assume adiabatic equilibrium products sim.show_solution() sim.solve(loglevel, auto=True) # write the velocity, temperature, and mole fractions to a CSV file sim.write_csv('premixed_counterflow.csv', quiet=False)
loglevel = 1 # amount of diagnostic output (0 to 5) # Grid refinement parameters ratio = 3 slope = 0.1 curve = 0.2 prune = 0.02 # Set up the problem gas = ct.Solution(rxnmech) # set state to that of the unburned gas at the burner gas.TPX = T_in, p, comp # Create the flame simulation object sim = ct.CounterflowPremixedFlame(gas=gas, grid=initial_grid) # set the properties at the inlet sim.reactants.mdot = mdot_reactants sim.reactants.X = comp sim.reactants.T = T_in sim.products.mdot = mdot_products sim.flame.set_steady_tolerances(default=tol_ss) sim.flame.set_transient_tolerances(default=tol_ts) sim.set_initial_guess() # assume adiabatic equilibrium products sim.show_solution() sim.energy_enabled = False sim.solve(loglevel, False)
def counterflow_premixed_flame_(gas, a=1000., solution=None, **kwargs): # read kwargs if 'transport' in kwargs.keys(): transport = kwargs['transport'] else: transport = 'Mix' if 'width' in kwargs.keys(): width = kwargs['width'] else: width = 0.05 if 'loglevel' in kwargs.keys(): loglevel = kwargs['loglevel'] else: # supress log output loglevel = 0 # kwargs for flame solver if 'ct_ratio' in kwargs.keys(): ct_ratio = kwargs['ct_ratio'] else: ct_ratio = 2. if 'ct_slope' in kwargs.keys(): ct_slope = kwargs['ct_slope'] else: ct_slope = 0.2 if 'ct_curve' in kwargs.keys(): ct_curve = kwargs['ct_curve'] else: ct_curve = 0.2 if 'ct_prune' in kwargs.keys(): ct_prune = kwargs['ct_prune'] else: ct_prune = 0.1 if 'ct_max_grids' in kwargs.keys(): ct_max_grids = kwargs['ct_max_grids'] else: ct_max_grids = 5000 # Create flame object f = ct.CounterflowPremixedFlame(gas=gas, width=width) # unburnt stream rho_u = gas.density # burnt stream gas.equilibrate('HP') rho_b = gas.density # get inlet velocity based on the strain rate # $a_1=\dfrac{2U_1}{L}\left(1+\dfrac{U_2\sqrt{\rho_2}}{U_1\sqrt{\rho_1}}\right)$ # $a_2=\dfrac{2U_2}{L}\left(1+\dfrac{U_1\sqrt{\rho_1}}{U_2\sqrt{\rho_2}}\right)$ # with $\rho_1 U_1^2 = \rho_2 U_2^2$ # $a_1=\dfrac{4U_1}{L}$ $a_2=\dfrac{4U_2}{L}$ # set stream 1 and 2 for unburnt and equilibrium status respectively v_u = a * width / 4.0 v_b = np.sqrt(rho_u * np.square(v_u) / rho_b) # mass rate m_u = rho_u * v_u m_b = rho_b * v_b f.transport_model = transport f.P = gas.P f.reactants.mdot = m_u f.products.mdot = m_b f.set_refine_criteria(ratio=ct_ratio, slope=ct_slope, curve=ct_curve, prune=ct_prune) f.set_max_grid_points(f.flame, ct_max_grids) # load saved case if presented if solution is not None: f.restore(solution, loglevel=loglevel) # scaling of saved solution solution_width = f.grid[-1] - f.grid[0] width_factor = width / solution_width solution_a = 4. * f.u[0] / solution_width a_factor = a / solution_a normalized_grid = f.grid / solution_width u_factor = a_factor * width_factor # update solution initialization following Fiala & Sattelmayer f.flame.grid = normalized_grid * width f.set_profile('u', normalized_grid, f.u * u_factor) f.set_profile('V', normalized_grid, f.V * a_factor) f.set_profile('lambda', normalized_grid, f.L * np.square(a_factor)) f.reactants.mdot = m_u f.products.mdot = m_b else: f.set_initial_guess() f.solve(loglevel=loglevel, auto=True) return f
def counterflow_premixed_flame(chemistry='gri30.xml', fuel={'CH4': 1.}, oxidizer={ 'O2': 1, 'N2': 3.76 }, temperature=300., pressure=1., phi=1., a=1000., solution=None, **kwargs): # for unrealistic parameters if pressure < 0.: raise ValueError('Negative pressure') if temperature < 0.: raise ValueError('Negative inlet temperature') if phi < 0.: raise ValueError('Negative equivalence ratio') # read kwargs if 'transport' in kwargs.keys(): transport = kwargs['transport'] else: transport = 'Mix' if 'width' in kwargs.keys(): width = kwargs['width'] else: width = 0.05 if 'loglevel' in kwargs.keys(): loglevel = kwargs['loglevel'] else: # supress log output loglevel = 0 # kwargs for flame solver if 'ct_ratio' in kwargs.keys(): ct_ratio = kwargs['ct_ratio'] else: ct_ratio = 2. if 'ct_slope' in kwargs.keys(): ct_slope = kwargs['ct_slope'] else: ct_slope = 0.02 if 'ct_curve' in kwargs.keys(): ct_curve = kwargs['ct_curve'] else: ct_curve = 0.02 if 'ct_prune' in kwargs.keys(): ct_prune = kwargs['ct_prune'] else: ct_prune = 0.01 if 'ct_max_grids' in kwargs.keys(): ct_max_grids = kwargs['ct_max_grids'] else: ct_max_grids = 5000 # case name params = {} params['T'] = temperature params['p'] = pressure params['phi'] = phi params['a'] = a case = params2name(params) # pressure pressure *= ct.one_atm # gas object #gas = ct.Solution(chemistry) # construct mixutre #mixture = cg.mixture_two_streams(gas, fuel, oxidizer, phi) # unburnt stream #gas.TPX = temperature, pressure, mixture gas = cg.mixture(chemistry, fuel, oxidizer, temperature, pressure, phi) rho_u = gas.density # burnt stream gas.equilibrate('HP') rho_b = gas.density gas = cg.mixture(chemistry, fuel, oxidizer, temperature, pressure, phi) # get inlet velocity based on the strain rate # $a_1=\dfrac{2U_1}{L}\left(1+\dfrac{U_2\sqrt{\rho_2}}{U_1\sqrt{\rho_1}}\right)$ # $a_2=\dfrac{2U_2}{L}\left(1+\dfrac{U_1\sqrt{\rho_1}}{U_2\sqrt{\rho_2}}\right)$ # with $\rho_1 U_1^2 = \rho_2 U_2^2$ # $a_1=\dfrac{4U_1}{L}$ $a_2=\dfrac{4U_2}{L}$ # set stream 1 and 2 for unburnt and equilibrium status respectively v_u = a * width / 4.0 v_b = np.sqrt(rho_u * np.square(v_u) / rho_b) # mass rate m_u = rho_u * v_u m_b = rho_b * v_b # Create flame object f = ct.CounterflowPremixedFlame(gas=gas, width=width) f.transport_model = transport f.P = pressure f.reactants.mdot = m_u f.products.mdot = m_b f.set_refine_criteria(ratio=ct_ratio, slope=ct_slope, curve=ct_curve, prune=ct_prune) f.set_max_grid_points(f.flame, ct_max_grids) # load saved case if presented if solution is not None: f.restore(solution, loglevel=loglevel) # scaling of saved solution solution_width = f.grid[-1] - f.grid[0] width_factor = width / solution_width solution_a = 4. * f.u[0] / solution_width a_factor = a / solution_a normalized_grid = f.grid / solution_width u_factor = a_factor * width_factor # update solution initialization following Fiala & Sattelmayer f.flame.grid = normalized_grid * width f.set_profile('u', normalized_grid, f.u * u_factor) f.set_profile('V', normalized_grid, f.V * a_factor) f.set_profile('lambda', normalized_grid, f.L * np.square(a_factor)) f.reactants.mdot = m_u f.products.mdot = m_b else: f.set_initial_guess() f.solve(loglevel=loglevel, auto=True) HRR = f.heat_release_rate idx = HRR.argmax() if HRR[idx] > 1000: f.save('{}.xml'.format(case)) if f.u[idx] > 0: return 0 else: return 2 else: return 1