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
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
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
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)
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)
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