示例#1
0
def run():
    from spitfire.chemistry.mechanism import ChemicalMechanismSpec
    from spitfire.chemistry.tabulation import build_unreacted_library
    import spitfire.chemistry.analysis as sca

    test_xml = abspath(join('tests', 'test_mechanisms', 'h2-burke.xml'))
    m = ChemicalMechanismSpec(cantera_xml=test_xml, group_name='h2-burke')
    pressure = 101325.
    air = m.stream(stp_air=True)
    air.TP = 1200., pressure
    fuel = m.stream('TPY', (300., pressure, 'H2:1'))

    flamelet_specs = {
        'mech_spec': m,
        'oxy_stream': air,
        'fuel_stream': fuel,
        'grid_points': 34
    }

    l = build_unreacted_library(flamelet_specs, verbose=False)
    l = sca.compute_specific_enthalpy(m, l)
    l = sca.compute_isochoric_specific_heat(m, l)
    l = sca.compute_isobaric_specific_heat(m, l)
    l = sca.compute_density(m, l)
    l = sca.compute_pressure(m, l)
    l = sca.compute_viscosity(m, l)

    return l
示例#2
0
def run(num_procs):
    from spitfire.chemistry.mechanism import ChemicalMechanismSpec
    from spitfire.chemistry.tabulation import build_nonadiabatic_defect_steady_slfm_library
    import spitfire.chemistry.analysis as sca
    import numpy as np

    test_xml = abspath(join('tests', 'test_mechanisms', 'h2-burke.xml'))
    m = ChemicalMechanismSpec(cantera_xml=test_xml, group_name='h2-burke')
    pressure = 101325.
    air = m.stream(stp_air=True)
    air.TP = 1200., pressure
    fuel = m.stream('TPY', (300., pressure, 'H2:1'))

    flamelet_specs = {
        'mech_spec': m,
        'oxy_stream': air,
        'fuel_stream': fuel,
        'grid_points': 34
    }

    l = build_nonadiabatic_defect_steady_slfm_library(
        flamelet_specs,
        verbose=False,
        diss_rate_values=np.logspace(0, 1, 4),
        integration_args={'transient_tolerance': 1e-10},
        num_procs=num_procs)
    l = sca.compute_specific_enthalpy(m, l)
    l = sca.compute_isochoric_specific_heat(m, l)
    l = sca.compute_isobaric_specific_heat(m, l)
    l = sca.compute_density(m, l)
    l = sca.compute_pressure(m, l)
    l = sca.compute_viscosity(m, l)

    return l
示例#3
0
def run():
    from spitfire.chemistry.mechanism import ChemicalMechanismSpec
    from spitfire.chemistry.tabulation import build_adiabatic_eq_library, apply_mixing_model, PDFSpec
    import spitfire.chemistry.analysis as sca

    test_xml = abspath(join('tests', 'test_mechanisms', 'h2-burke.xml'))
    m = ChemicalMechanismSpec(cantera_xml=test_xml, group_name='h2-burke')
    pressure = 101325.
    air = m.stream(stp_air=True)
    air.TP = 1200., pressure
    fuel = m.stream('TPY', (300., pressure, 'H2:1'))

    flamelet_specs = {
        'mech_spec': m,
        'oxy_stream': air,
        'fuel_stream': fuel,
        'grid_points': 34
    }

    l = build_adiabatic_eq_library(flamelet_specs, verbose=False)
    l = sca.compute_specific_enthalpy(m, l)
    l = sca.compute_isochoric_specific_heat(m, l)
    l = sca.compute_isobaric_specific_heat(m, l)
    l = sca.compute_density(m, l)
    l = sca.compute_pressure(m, l)
    l = sca.compute_viscosity(m, l)
    scaled_variance_values = np.linspace(0., 1., 5)
    l_t = apply_mixing_model(l, {
        'mixture_fraction':
        PDFSpec(pdf='ClipGauss', scaled_variance_values=scaled_variance_values)
    },
                             num_procs=1)
    return l_t
def post_processing(configuration, mass_transfer, heat_transfer):
    air = mechanism.stream(stp_air=True)
    fuel = mechanism.stream('X', 'H2:1')

    mix = mechanism.mix_for_equivalence_ratio(1.0, fuel, air)
    mix.TP = 1200., 101325.

    feed = mechanism.copy_stream(mix)

    tau = 1.e-3

    extra_args = dict()
    if mass_transfer == 'open':
        if configuration == 'isobaric':
            extra_args['feed_temperature'] = feed.T
            extra_args['feed_mass_fractions'] = feed.Y
            extra_args['mixing_tau'] = tau
        elif configuration == 'isochoric':
            extra_args['feed_temperature'] = feed.T
            extra_args['feed_mass_fractions'] = feed.Y
            extra_args['feed_density'] = feed.density
            extra_args['mixing_tau'] = tau
    if heat_transfer == 'diathermal':
        extra_args['convection_coefficient'] = 1.
        extra_args['convection_temperature'] = 300.
        extra_args['radiative_emissivity'] = 1.
        extra_args['radiation_temperature'] = 300.
        extra_args['shape_dimension_dict'] = {'shape': 'sphere', 'char. length': 1.e-3}

    try:
        reactor = HomogeneousReactor(mechanism, mix,
                                     configuration=configuration,
                                     heat_transfer=heat_transfer,
                                     mass_transfer=mass_transfer,
                                     **extra_args)

        tol = np.sqrt(np.finfo(float).eps)
        test_success = True

        output_library = reactor.integrate_to_time(1e-16, minimum_time_step_count=0)
        output_library = sca.compute_specific_enthalpy(mechanism, output_library)
        output_library = sca.compute_density(mechanism, output_library)
        output_library = sca.compute_pressure(mechanism, output_library)
        output_library = sca.compute_isobaric_specific_heat(mechanism, output_library)
        output_library = sca.compute_isochoric_specific_heat(mechanism, output_library)
        output_library = sca.explosive_mode_analysis(mechanism, output_library,
                                                     configuration, heat_transfer,
                                                     True, True, True)

        test_success = test_success and np.abs(mix.T - output_library['temperature'][-1]) / mix.T < tol
        test_success = test_success and np.abs(mix.P - output_library['pressure'][-1]) / mix.P < tol
        test_success = test_success and np.abs(mix.density - output_library['density'][-1]) / mix.density < tol
        test_success = test_success and np.abs(mix.enthalpy - output_library['enthalpy'][-1]) / mix.enthalpy_mass < tol
        test_success = test_success and np.abs(mix.cv_mass - output_library['heat capacity cv'][-1]) / mix.cv_mass < tol
        test_success = test_success and np.abs(mix.cp_mass - output_library['heat capacity cp'][-1]) / mix.cp_mass < tol

        return test_success
    except:
        return False
示例#5
0
def _expand_enthalpy_defect_dimension_steady(chi_st, managed_dict,
                                             flamelet_specs, table_dict,
                                             h_stoich_spacing, verbose,
                                             input_integration_args,
                                             solver_verbose):
    flamelet_specs.initial_condition = table_dict[chi_st]['adiabatic_state']
    flamelet_specs.stoich_dissipation_rate = chi_st
    flamelet_specs.heat_transfer = 'nonadiabatic'
    flamelet_specs.scale_heat_loss_by_temp_range = False
    flamelet_specs.scale_convection_by_dissipation = False
    flamelet_specs.use_linear_ref_temp_profile = True
    flamelet_specs.radiative_emissivity = 0.
    flamelet_specs.convection_coefficient = 0.

    flamelet = Flamelet(flamelet_specs)

    first = True
    refine_before_extinction = False
    extinguished = False
    extinguished_first = False
    maxT = -1
    state_old = np.copy(flamelet.current_interior_state)
    hval = 0.
    dh = 1.e-1
    diff_target = 1e-1
    diff_norm = 1e-1

    hval_max = 1.e10

    solutions = []
    hvalues = []
    hvalues.append(hval)
    solutions.append(dict())

    for p in table_dict[chi_st]:
        if p != 'adiabatic_state':
            solutions[-1][p] = table_dict[chi_st][p]

    current_state = table_dict[chi_st]['adiabatic_state']

    cput0000 = perf_counter()
    while first or (not extinguished and hval < hval_max):
        hval += dh
        if first:
            first = False

        flamelet_specs.convection_coefficient = hval
        flamelet_specs.initial_condition = current_state
        flamelet = Flamelet(flamelet_specs)

        g_library = flamelet.compute_steady_state(verbose=solver_verbose)
        current_state = flamelet.current_interior_state
        maxT = np.max(current_state)

        diff_norm = np.max(
            np.abs(current_state - state_old) /
            (np.abs(current_state) + 1.e-4))

        extinguished = maxT < (
            np.max([flamelet.oxy_stream.T, flamelet.fuel_stream.T]) + 10.)
        if (extinguished and
            (not extinguished_first)) and refine_before_extinction:
            extinguished_first = True
            extinguished = False

            hval -= dh
            dh *= 0.1
            diff_target *= 0.1
            current_state = state_old.copy()

            continue

        state_old = np.copy(current_state)
        dh *= np.min([np.max([np.sqrt(diff_target / diff_norm), 0.1]), 2.])
        hvalues.append(hval)
        solutions.append(dict())
        for p in g_library.props:
            solutions[-1][p] = g_library[p].ravel()

    z_dim = Dimension(_mixture_fraction_name, flamelet.mixfrac_grid)
    h_dim = Dimension(_enthalpy_defect_name + _stoich_suffix,
                      np.array(hvalues))
    steady_lib = Library(z_dim, h_dim)
    steady_lib.extra_attributes['mech_spec'] = flamelet_specs.mech_spec
    for p in table_dict[chi_st]:
        if p != 'adiabatic_state':
            steady_lib[p] = steady_lib.get_empty_dataset()
    for ig, sol in enumerate(solutions):
        for p in sol:
            steady_lib[p][:, ig] = sol[p].ravel()

    indices = [0]
    z = flamelet.mixfrac_grid
    z_st = flamelet.mechanism.stoich_mixture_fraction(flamelet.fuel_stream,
                                                      flamelet.oxy_stream)
    h_tz = sca.compute_specific_enthalpy(flamelet_specs.mech_spec,
                                         steady_lib)['enthalpy']
    h_ad = h_tz[:, 0]
    nz, nt = h_tz.shape
    last_hst = interp1d(z, h_ad)(z_st)
    for i in range(nt - 1):
        this_hst = interp1d(z, h_tz[:, i])(z_st)
        if last_hst - this_hst > h_stoich_spacing:
            indices.append(i)
            last_hst = this_hst

    for i in indices:
        defect = h_tz[:, i] - h_ad
        gst = float(interp1d(z, defect)(z_st))
        this_data = dict()
        this_data['enthalpy_defect'] = np.copy(defect)
        this_data['enthalpy_cons'] = np.copy(h_ad)
        this_data['enthalpy'] = np.copy(h_tz[:, i])
        this_data[_mixture_fraction_name] = flamelet.mixfrac_grid
        for q in steady_lib.props:
            this_data[q] = steady_lib[q][:, i]
        managed_dict[(chi_st, gst)] = this_data

    dcput = perf_counter() - cput0000

    if verbose:
        print('chi_st = {:8.1e} 1/s converged in {:6.2f} s'.format(
            chi_st, dcput),
              flush=True)
示例#6
0
def _expand_enthalpy_defect_dimension_transient(chi_st, managed_dict,
                                                flamelet_specs, table_dict,
                                                h_stoich_spacing, verbose,
                                                input_integration_args,
                                                solver_verbose):
    flamelet_specs.initial_condition = table_dict[chi_st]['adiabatic_state']
    flamelet_specs.stoich_dissipation_rate = chi_st
    flamelet_specs.heat_transfer = 'nonadiabatic'
    flamelet_specs.scale_heat_loss_by_temp_range = True
    flamelet_specs.scale_convection_by_dissipation = True
    flamelet_specs.use_linear_ref_temp_profile = True
    flamelet_specs.convection_coefficient = 1.e7
    flamelet_specs.radiative_emissivity = 0.

    integration_args = dict({
        'first_time_step': 1.e-9,
        'max_time_step': 1.e-1,
        'write_log': solver_verbose,
        'log_rate': 100
    })

    if input_integration_args is not None:
        integration_args.update(input_integration_args)

    if 'transient_tolerance' not in integration_args:
        integration_args['transient_tolerance'] = 1.e-8

    cput0000 = perf_counter()
    running = True
    while running and integration_args['transient_tolerance'] > 1.e-15:
        try:
            fnonad = Flamelet(flamelet_specs)
            transient_lib = fnonad.integrate_for_heat_loss(**integration_args)
            running = False
        except Exception as e:
            if solver_verbose:
                print(
                    f'Transient heat loss calculation failed with tolerance of {integration_args["transient_tolerance"]:.1e}, retrying with 100x lower...'
                )
            integration_args.update(
                dict({
                    'transient_tolerance':
                    integration_args['transient_tolerance'] * 1.e-2
                }))
    indices = [0]
    z = fnonad.mixfrac_grid
    z_st = fnonad.mechanism.stoich_mixture_fraction(fnonad.fuel_stream,
                                                    fnonad.oxy_stream)
    h_tz = sca.compute_specific_enthalpy(flamelet_specs.mech_spec,
                                         transient_lib)['enthalpy']
    h_ad = h_tz[0, :]
    nt, nz = h_tz.shape
    last_hst = interp1d(z, h_ad)(z_st)
    for i in range(nt):
        this_hst = interp1d(z, h_tz[i, :])(z_st)
        if last_hst - this_hst > h_stoich_spacing:
            indices.append(i)
            last_hst = this_hst
    if nt - 1 not in indices:
        indices.append(-1)

    for i in indices:
        defect = h_tz[i, :] - h_ad
        gst = float(interp1d(z, defect)(z_st))
        this_data = dict()
        this_data['enthalpy_defect'] = np.copy(defect)
        this_data['enthalpy_cons'] = np.copy(h_ad)
        this_data['enthalpy'] = np.copy(h_tz[i, :])
        this_data[_mixture_fraction_name] = fnonad.mixfrac_grid
        for q in transient_lib.props:
            this_data[q] = transient_lib[q][i, :]
        managed_dict[(chi_st, gst)] = this_data

    dcput = perf_counter() - cput0000

    if verbose:
        print('chi_st = {:8.1e} 1/s converged in {:6.2f} s'.format(
            chi_st, dcput),
              flush=True)
示例#7
0
def _build_nonadiabatic_defect_unstrained_library(initialization,
                                                  flamelet_specs,
                                                  n_defect_st=16,
                                                  verbose=True):
    flamelet_specs = FlameletSpec(**flamelet_specs) if isinstance(
        flamelet_specs, dict) else copy.copy(flamelet_specs)

    m = flamelet_specs.mech_spec
    fuel = flamelet_specs.fuel_stream
    oxy = flamelet_specs.oxy_stream

    z_st = m.stoich_mixture_fraction(fuel, oxy)

    flamelet_specs.initial_condition = initialization
    flamelet = Flamelet(flamelet_specs)

    # compute the extreme enthalpy defect
    state_ad = flamelet.initial_interior_state
    adiabatic_lib = flamelet.make_library_from_interior_state(state_ad)
    enthalpy_ad = sca.compute_specific_enthalpy(m, adiabatic_lib)['enthalpy']

    z_interior = flamelet.mixfrac_grid[1:-1]
    state_cooled_eq = state_ad.copy()
    state_cooled_eq[::m.
                    n_species] = z_interior * fuel.T + (1 - z_interior) * oxy.T
    cooled_lib = flamelet.make_library_from_interior_state(state_cooled_eq)
    enthalpy_cooled_eq = sca.compute_specific_enthalpy(m,
                                                       cooled_lib)['enthalpy']

    z = flamelet.mixfrac_grid
    h_ad_st = interp1d(z, enthalpy_ad)(z_st)
    h_ce_st = interp1d(z, enthalpy_cooled_eq)(z_st)
    defect_ext = h_ad_st - h_ce_st

    # build the library with equilibrium solutions at with enthalpies offset by the triangular defect form
    defect_range = np.linspace(-defect_ext, 0, n_defect_st)[::-1]
    z_dim = Dimension(_mixture_fraction_name, flamelet.mixfrac_grid)
    g_dim = Dimension(_enthalpy_defect_name + _stoich_suffix, defect_range)
    output_library = Library(z_dim, g_dim)
    output_library.extra_attributes['mech_spec'] = m

    for p in adiabatic_lib.props:
        output_library[p] = output_library.get_empty_dataset()
    output_library['enthalpy_defect'] = output_library.get_empty_dataset()
    output_library['enthalpy_cons'] = output_library.get_empty_dataset()
    output_library['enthalpy'] = output_library.get_empty_dataset()
    output_library[_mixture_fraction_name] = output_library.get_empty_dataset()

    fz = z.copy()
    fz[z <= z_st] = z[z <= z_st] / z_st
    fz[z > z_st] = (1 - z[z > z_st]) / (1 - z_st)

    ns = m.n_species
    g_library = flamelet.make_library_from_interior_state(
        flamelet.initial_interior_state)
    for ig in range(n_defect_st):
        defected_enthalpy = enthalpy_ad + defect_range[ig] * fz

        for iz in range(1, z.size - 1):
            y = np.zeros(ns)
            for ispec in range(ns):
                y[ispec] = g_library['mass fraction ' +
                                     m.species_names[ispec]][iz]
            m.gas.HPY = defected_enthalpy[iz], flamelet.pressure, y
            if initialization == 'equilibrium':
                m.gas.equilibrate('HP')
            g_library['temperature'][iz] = m.gas.T
            for ispec in range(ns):
                g_library['mass fraction ' +
                          m.species_names[ispec]][iz] = m.gas.Y[ispec]

        for p in g_library.props:
            if p != 'defected_enthapy':
                output_library[p][:, ig] = g_library[p].ravel()
        output_library['enthalpy_defect'][:,
                                          ig] = defected_enthalpy - enthalpy_ad
        output_library['enthalpy_cons'][:, ig] = enthalpy_ad
        output_library['enthalpy'][:, ig] = defected_enthalpy
        output_library[
            _mixture_fraction_name][:, ig] = flamelet.mixfrac_grid.ravel()

    return output_library