def solve(self, phi, T, width, P): gas = ct.Solution('h2o2.xml') gas.TP = T, ct.one_atm gas.set_equivalence_ratio(phi, 'H2', 'O2:1.0, AR:4.0') sim = ct.CounterflowTwinPremixedFlame(gas=gas, width=width) sim.set_refine_criteria(ratio=5, slope=0.6, curve=0.8, prune=0.1) axial_velocity = 2.0 sim.reactants.mdot = gas.density * axial_velocity sim.solve(loglevel=0, auto=True) self.assertGreater(sim.T[-1], T + 100)
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.CounterflowTwinPremixedFlame(gas, width=0.1) flame.restore(solution, loglevel=0) PremixedFlameState.__init__(self, flame, fuel, oxidizer, T)
# Create a CH4/Air premixed mixture with equivalence ratio=0.75, and at room # temperature and pressure. gas.set_equivalence_ratio(0.75, 'CH4', {'O2': 1.0, 'N2': 3.76}) gas.TP = 300, ct.one_atm # Set the velocity axial_velocity = 0.25 # in m/s # Domain half-width of 2.5 cm, meaning the whole domain is 5 cm wide width = 0.025 # Done with initial conditions # Compute the mass flux, as this is what the Flame object requires massFlux = gas.density * axial_velocity # units kg/m2/s # Create the flame object oppFlame = ct.CounterflowTwinPremixedFlame(gas, width=width) # Now run the solver # The solver returns the peak temperature and strain rate. You can plot/see all # state space variables by calling oppFlame.foo where foo is T, Y[i] or whatever # The spatial variable (distance in meters) is in oppFlame.grid Thus to plot # temperature vs distance, use oppFlame.grid and oppFlame.T (T, K) = solveOpposedFlame(oppFlame, massFlux) print("Peak temperature: {0}".format(T)) print("Strain Rate: {0}".format(K)) oppFlame.write_csv("premixed_twin_flame.csv", quiet=False)
def counterflow_twin_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 # 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 = a * width / 4. # mass rate mass_flux = gas.density * v # Create flame object f = ct.CounterflowTwinPremixedFlame(gas=gas, width=width) f.transport_model = transport f.P = gas.P f.reactants.mdot = mass_flux 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 = mass_flux else: f.set_initial_guess() f.solve(loglevel=loglevel, auto=True) return f