Ejemplo n.º 1
0
def FreelyPropagatingFlame(mech='gri30.xml',
                           transport='UnityLewis',
                           fuel_name='CH4',
                           p=1.,
                           T=300.,
                           eqv=1.,
                           width=0.03):

    # supress log output
    loglevel = 0

    # gas object, ideal gas
    gas = ct.Solution(mech)
    if eqv < 0.:
        raise ValueError('Negative equivalence ratio')

    params = {}
    params['F'] = fuel_name
    params['p'] = p
    params['T'] = T
    params['eqv'] = eqv

    case = params2name(params)

    p *= ct.one_atm  # pressure [Pa]

    # construct mixture by volume
    air = {'O2': 1., 'N2': 3.76}
    fuel_index = gas.species_index(fuel_name)
    stoich_nu = gas.n_atoms(fuel_index,
                            'C') + gas.n_atoms(fuel_index, 'H') / 4.

    mixture = air
    mixture[fuel_name] = eqv / stoich_nu

    gas.TPX = T, p, mixture

    # flame object
    f = ct.FreeFlame(gas, width=width)

    f.set_initial_guess()

    f.set_refine_criteria(ratio=3, slope=0.06, curve=0.1, prune=0.01)
    f.soret_enabled = False
    f.radiation_enabled = False

    f.transport_model = transport
    try:
        f.solve(loglevel=loglevel)
    except Exception as e:
        print('Error: not converge for case:', e)
        return -1

    # return for unburnt flame
    if np.max(f.T) < T + 100:
        return 1

    f.save('{}.xml'.format(case))

    return 0
Ejemplo n.º 2
0
fuel = ct.Solution('gri30.xml')
fuel.TPX = flame_params['tf'], p, {flame_params['F']:1}

oxidizer = ct.Solution('gri30.xml')
oxidizer.TPX = flame_params['to'], p, {'O2':1,'N2':3.76}

Zst = canteraFlame.StoichiometricMixtureFraction( fuel, oxidizer )

gas = ct.Solution('gri30.xml')
f = ct.CounterflowDiffusionFlame(gas, width=0.01)

for i, a in enumerate(strain):

    flame_params['a'] = a

    flame_name = params2name( flame_params )
    f.restore( '{}.xml'.format(flame_name), loglevel=0 )

    Z = canteraFlame.BilgerMixtureFraction( f, fuel, oxidizer )
    c = canteraFlame.ProgressVariable( f, speciesProgressVariable )

    flameGradient = np.gradient( c, Z )

    ax.plot( Z, flameGradient, label='{:g}'.format(a), ls=linestyle[i], lw=1 )

ax.legend(frameon=False)

ax.plot([0, Zst], [5, 5], 'k--',
        [Zst, 1], [-0.291, -0.291], 'k--', lw=2
       )
Ejemplo n.º 3
0
Zst = canteraFlame.StoichiometricMixtureFraction(fuel, oxidizer)

gas = ct.Solution('gri30.xml')
f = ct.CounterflowDiffusionFlame(gas, width=0.01)

for i, phi in enumerate(phif):

    folder_params['phif'] = phi
    flame_params['phif'] = phi

    label = r'$\varphi_r=\;$' + '{:g}'.format(phi)

    if phi == float('inf'):
        label = r'$\varphi_r=\infty$'

    folderName = params2name(folder_params)
    flameName = params2name(flame_params)

    fileName = '{}/{}.xml'.format(folderName, flameName)

    f.restore(fileName, loglevel=0)

    Z = canteraFlame.BilgerMixtureFraction(f, fuel, oxidizer)

    rangeIndex = np.where(np.logical_and(Z < 0.06, Z > 0.05))
    rangeZ = Z[rangeIndex]
    rangeGrid = f.grid[rangeIndex]
    locZst = np.interp(Zst, rangeZ[::-1], rangeGrid[::-1])

    ax.plot(locZst - f.grid,
            f.T,
def CounterflowPartiallyPremixedFlame(mech='gri30.xml',
                                      transport='UnityLewis',
                                      flag_soret=False,
                                      flag_radiation=False,
                                      fuel_name='CH4',
                                      strain_rate=285.,
                                      width=0.01,
                                      p=1.,
                                      phi_f='inf',
                                      phi_o=0.,
                                      tin_f=300.,
                                      tin_o=300.,
                                      solution=None):

    ################################################################################

    # Create the gas object used to evaluate all thermodynamic, kinetic, and
    # transport properties.
    gas = ct.Solution(mech)

    phi_f = float(phi_f)
    if phi_f <= 1.:
        sys.exit('Equivalence ratio of fuel side {:g}'.format(phi_f))
    if phi_o >= 1.:
        sys.exit('Equivalence ratio of oxidizer side {:g}'.format(phi_o))

    # construct case name
    flame_params = {}
    flame_params['F'] = fuel_name
    flame_params['p'] = p
    flame_params['a'] = strain_rate
    flame_params['phif'] = phi_f
    flame_params['phio'] = phi_o
    flame_params['tf'] = tin_f
    flame_params['to'] = tin_o

    case_name = params2name(flame_params)

    ################################################################################

    p *= ct.one_atm  # pressure

    # Create an object representing the counterflow flame configuration,
    # which consists of a fuel inlet on the left, the flow in the middle,
    # and the oxidizer inlet on the right.
    f = ct.CounterflowDiffusionFlame(gas, width=width)
    f.transport_model = transport
    f.P = p

    if solution is not None:
        f.restore(solution, loglevel=0)

        solution_width = f.grid[-1] - f.grid[0]
        width_factor = width / solution_width

        solution_strain = (f.u[0] - f.u[-1]) / solution_width
        strain_factor = strain_rate / solution_strain

        normalized_grid = f.grid / solution_width

        u_factor = strain_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 * strain_factor)
        f.set_profile('lambda', normalized_grid,
                      f.L * np.square(strain_factor))

    oxy = {'O2': 1., 'N2': 3.76}  # air composition
    fuel_index = gas.species_index(fuel_name)
    stoich_nu = gas.n_atoms(fuel_index,
                            'C') + gas.n_atoms(fuel_index, 'H') / 4.

    comp_f = {}
    comp_o = {}
    comp_f[fuel_name] = 1
    for k, v in oxy.items():
        comp_o[k] = v
        comp_f[k] = v * stoich_nu / phi_f

    comp_o[fuel_name] = phi_o / stoich_nu

    gas.TPX = tin_f, p, comp_o
    dens_o = gas.density

    gas.TPX = tin_o, p, comp_f
    dens_f = gas.density

    # fuel and oxidizer streams have the same velocity
    u = strain_rate * width / 2.

    # get mass flow rate
    mdot_o = u * dens_o
    mdot_f = u * dens_f  # kg/m^2/s

    # Set the state of the two inlets
    f.fuel_inlet.mdot = mdot_f
    f.fuel_inlet.X = comp_f
    f.fuel_inlet.T = tin_f

    f.oxidizer_inlet.mdot = mdot_o
    f.oxidizer_inlet.X = comp_o
    f.oxidizer_inlet.T = tin_o

    # Set the boundary emissivities
    f.set_boundary_emissivities(0.0, 0.0)
    # Turn radiation off
    f.radiation_enabled = False

    f.set_refine_criteria(ratio=2, slope=0.1, curve=0.1, prune=0.01)

    # Solve the problem
    try:
        f.solve(loglevel=0, auto=True)
    except Exception as e:
        print('Error: not converge for case:', e)
        return -1

    if flag_radiation:
        f.radiation_enabled = True
        try:
            f.solve(loglevel=0, auto=True)
        except Exception as e:
            print('Error: not converge for case:', e)
            return -1

    if flag_soret:
        f.soret_enabled = True
        try:
            f.solve(loglevel=0, auto=True)
        except Exception as e:
            print('Error: not converge for case:', e)
            return -1

    f.save('{}.xml'.format(case_name))

    if np.max(f.T) < np.max((tin_f, tin_o)) + 100:
        return 1
    else:
        return 0
# generate figure and axes
fig, ax = plt.subplots(num_rows,
                       num_cols,
                       sharex=True,
                       sharey=True,
                       figsize=figureSize.cm2inch(plot_width, plot_height))

#for i in range(num_cols):
#    ax[i].plot([0,1],[0.5,0.5],'k:',linewidth=1)

# get data
for k, phi in enumerate(phif):
    folder_params['phif'] = phi

    folder = params2name(folder_params)

    label = r'$\varphi_r=$' + '{0:g}'.format(phi)

    os.chdir(folder)

    for i, model in enumerate(models):
        fileList = glob.glob('*.{}'.format(model))
        data = np.zeros((len(fileList), 2))

        for j, fileName in enumerate(fileList):
            flameName = fileName[:fileName.find(model)]
            flameParams = name2params(flameName)
            data[j, 0] = flameParams['ave']

            FI = np.genfromtxt(fileName, usecols=(3, ))
plot_height = (num_rows * subplot_height + margin_bottom + margin_top +
               (num_rows - 1) * space_height)

# In[5]:

fig, ax = plt.subplots(num_rows,
                       num_cols,
                       sharex='row',
                       sharey=True,
                       figsize=figureSize.cm2inch(plot_width, plot_height))

for i, phi in enumerate(phif):
    flame_params['phif'] = phi
    folder_params['phif'] = phi

    folder = params2name(folder_params)
    flame = params2name(flame_params)

    for j, model in enumerate(models):

        ax[i, j].plot([0, 1], [0.5, 0.5], 'k--', linewidth=1)
        ax[i, j].plot([Zst, Zst], [0, 1], 'k-.', linewidth=1)

        file_name = '{}/{}.{}'.format(folder, flame, models[j])

        FI = np.genfromtxt(file_name)

        # 1000 pts at largest
        ntotal = FI.shape[0]
        if ntotal > 1000:
            # get PDF of FI for EMST
def CounterflowFlameStrainDriver(mech='gri30.xml',
                                 transport='UnityLewis',
                                 flag_soret=False,
                                 flag_radiation=False,
                                 fuel_name='CH4',
                                 width=0.01,
                                 p=1.,
                                 phi_f='inf',
                                 phi_o=0.,
                                 tin_f=300.,
                                 tin_o=300.):

    strain_list = np.array([50, 100, 200, 400])

    folder_params = {}
    folder_params['phif'] = phi_f
    folder_params['phio'] = phi_o

    folder_name = params2name(folder_params)

    if not os.path.exists(folder_name):
        os.makedirs(folder_name)

    os.chdir(folder_name)

    # parameters
    flame_params = {}
    flame_params['F'] = fuel_name
    flame_params['p'] = p
    flame_params['a'] = None
    flame_params['phif'] = phi_f
    flame_params['phio'] = phi_o
    flame_params['tf'] = tin_f
    flame_params['to'] = tin_o

    solution = None

    for a in strain_list:

        flame_params['a'] = a
        case_name = params2name(flame_params)
        file_name = '{}.xml'.format(case_name)

        info = CounterflowPartiallyPremixedFlame(mech=mech,
                                                 transport=transport,
                                                 flag_soret=flag_soret,
                                                 flag_radiation=flag_radiation,
                                                 fuel_name=flame_params['F'],
                                                 strain_rate=flame_params['a'],
                                                 width=width,
                                                 p=flame_params['p'],
                                                 phi_f=flame_params['phif'],
                                                 phi_o=flame_params['phio'],
                                                 tin_f=flame_params['tf'],
                                                 tin_o=flame_params['to'],
                                                 solution=solution)

        if info == 0:
            print('strain rate = {:g} success'.format(flame_params['a']))
            solution = file_name
        elif info == -1:
            print('strain rate = {:g} fail'.format(flame_params['a']))
            break
        elif info == 1:
            print('strain rate = {:g} extinct'.format(flame_params['a']))
            os.remove(file_name)
            break