def test_elementary(self): r = ct.ElementaryReaction({'O':1, 'H2':1}, {'H':1, 'OH':1}) r.rate = ct.Arrhenius(3.87e1, 2.7, 6260*1000*4.184) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=self.species, reactions=[r]) gas2.TPX = self.gas.TPX self.assertNear(gas2.forward_rate_constants[0], self.gas.forward_rate_constants[2]) self.assertNear(gas2.net_rates_of_progress[0], self.gas.net_rates_of_progress[2])
def test_negative_A(self): species = ct.Species.listFromFile('gri30.cti') r = ct.ElementaryReaction('NH:1, NO:1', 'N2O:1, H:1') r.rate = ct.Arrhenius(-2.16e13, -0.23, 0) self.assertFalse(r.allow_negative_pre_exponential_factor) with self.assertRaises(Exception): gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) r.allow_negative_pre_exponential_factor = True gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r])
def test_modify_invalid(self): # different reaction type tbr = self.gas.reaction(0) R2 = ct.ElementaryReaction(tbr.reactants, tbr.products) R2.rate = tbr.rate with self.assertRaises(ct.CanteraError): self.gas.modify_reaction(0, R2) # different reactants R = self.gas.reaction(7) with self.assertRaises(ct.CanteraError): self.gas.modify_reaction(23, R) # different products R = self.gas.reaction(14) with self.assertRaises(ct.CanteraError): self.gas.modify_reaction(15, R)
def remove(seed, num, exclude): np.random.seed(seed) reactions = gas.reactions() removed = [] rcandidates = range(0, len(reactions)) rcandidates = [item for item in rcandidates if item not in exclude] removed = np.random.choice(rcandidates, size=num, replace=False) for ind in removed: if (gas.reaction_type(ind) == 1): newreac = ct.ElementaryReaction(reactants=reactions[ind].reactants, products=reactions[ind].products) gas.modify_reaction(ind, newreac) if (gas.reaction_type(ind) == 2): newreac = ct.ThreeBodyReaction(reactants=reactions[ind].reactants, products=reactions[ind].products) gas.modify_reaction(ind, newreac) if (gas.reaction_type(ind) == 4): newreac = ct.FalloffReaction(reactants=reactions[ind].reactants, products=reactions[ind].products) gas.modify_reaction(ind, newreac) return removed
constants for reaction 2 and reaction 3 to show that even two reactions that have the same Blowers-Masel parameters can have different forward rate constants. The first plot generated shows how the rate constant changes with respect to temperature for elementary and Blower-Masel reactions. The second plot shows the activation energy change of a Blowers-Masel reaction with respect to the delta enthalpy of the reaction. Requires: cantera >= 2.6.0, matplotlib >= 2.0 """ import cantera as ct import numpy as np import matplotlib.pyplot as plt #Create an elementary reaction O+H2<=>H+OH r1 = ct.ElementaryReaction({'O': 1, 'H2': 1}, {'H': 1, 'OH': 1}) r1.rate = ct.Arrhenius(3.87e1, 2.7, 6260 * 1000 * 4.184) #Create a Blowers-Masel reaction O+H2<=>H+OH r2 = ct.BlowersMaselReaction({'O': 1, 'H2': 1}, {'H': 1, 'OH': 1}) r2.rate = ct.BlowersMasel(3.87e1, 2.7, 6260 * 1000 * 4.184, 1e9) #Create a Blowers-Masel reaction with same parameters with r2 #reaction equation is H+CH4<=>CH3+H2 r3 = ct.BlowersMaselReaction({'H': 1, 'CH4': 1}, {'CH3': 1, 'H2': 1}) r3.rate = ct.BlowersMasel(3.87e1, 2.7, 6260 * 1000 * 4.184, 1e9) gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=ct.Solution('gri30.yaml').species(), reactions=[r1, r2, r3])
def perturb_parameter_thisisthecomplicatedonethatdoesntwork( self, parameter, new_value): param_info = self.model_parameter_info[parameter] reaction_number = param_info['reaction_number'] parameter_type = param_info['parameter_type'] print(parameter) print(param_info) reaction = self.gas.reaction(reaction_number) print(reaction.rate) rate = None efficiencies = None reactants = reaction.reactant_string products = reaction.product_string rtype = reaction.reaction_type pressurestring = 'pressure' HasFalloff = False if pressurestring in parameter_type: HasFalloff = True if HasFalloff: highrate = reaction.high_rate lowrate = reaction.low_rate if rtype == 4: newreaction = ct.FalloffReaction(reactants=reactants, products=products) if rtype == 8: newreaction = ct.ChemicallyActivatedReaction( reactants=reactants, products=products) else: rate = reaction.rate if rtype == 2: newreaction = ct.ThreeBodyReaction(reactants=reactants, products=products) else: newreaction = ct.ElementaryReaction(reactants=reactants, products=products) if parameter_type == 'A_factor': old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_A = new_value newreaction.rate = ct.Arrhenius(A=new_A, b=old_b, E=old_E) if parameter_type == 'Energy': old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_E = new_value newreaction.rate = ct.Arrhenius(A=old_A, b=old_b, E=new_E) if parameter_type == 'High_pressure_A': rate = highrate old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_A = new_value newreaction.high_rate = ct.Arrhenius(A=new_A, b=old_b, E=old_E) if parameter_type == 'High_pressure_E': rate = highrate old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_E = new_value newreaction.high_rate = ct.Arrhenius(A=old_A, b=old_b, E=new_E) if parameter_type == 'Low_pressure_A': rate = lowrate old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_A = new_value newreaction.low_rate = ct.Arrhenius(A=new_A, b=old_b, E=old_E) if parameter_type == 'Low_pressure_E': rate = lowrate old_A = rate.pre_exponential_factor old_b = rate.temperature_exponent old_E = rate.activation_energy new_E = new_value newreaction.low_rate = ct.Arrhenius(A=old_A, b=old_b, E=new_E) self.gas.modify_reaction(reaction_number, newreaction) if parameter_type == 'Efficiency': efficiencies = copy.deepcopy(reaction.efficiencies) species = param_info['species'] efficiencies[species] = new_value reaction.efficiencies = efficiencies return
def residual(eta, k0, observations, measure_ind, tmaxes, temperatures, pressures, initials, maxes, yields): rstart = timeit.default_timer() ret = 0 reactions = gas.reaction_equations() k = k0 * 10**eta if (gas.reaction_type(measure_ind) == 1): newrate = ct.ElementaryReaction(gas.reactions()[measure_ind].reactants, gas.reactions()[measure_ind].products) newrate.rate = ct.Arrhenius( k, gas.reactions()[measure_ind].rate.temperature_exponent, gas.reactions()[measure_ind].rate.activation_energy) gas.modify_reaction(measure_ind, newrate) if (gas.reaction_type(measure_ind) == 2): newrate = ct.ThreeBodyReaction( reactants=gas.reactions()[measure_ind].reactants, products=gas.reactions()[measure_ind].products) newrate.efficiencies = gas.reactions()[measure_ind].efficiencies newrate.rate = ct.Arrhenius( k, gas.reactions()[measure_ind].rate.temperature_exponent, gas.reactions()[measure_ind].rate.activation_energy) gas.modify_reaction(measure_ind, newrate) if (gas.reaction_type(measure_ind) == 4): newrate = ct.FalloffReaction( reactants=gas.reactions()[measure_ind].reactants, products=gas.reactions()[measure_ind].products) newrate.efficiencies = gas.reactions()[measure_ind].efficiencies newrate.falloff = gas.reactions()[measure_ind].falloff newrate.low_rate = ct.Arrhenius( k, gas.reactions()[measure_ind].low_rate.temperature_exponent, gas.reactions()[measure_ind].low_rate.temperature_exponent, gas.reactions()[measure_ind].low_rate.activation_energy) newrate.high_rate = gas.reactions()[measure_ind].high_rate gas.modify_reaction(measure_ind, newrate) sys.stdout.flush() for i in range(0, nmeasure): states = runsim_nosense(tmaxes[i], temperatures[i], pressures[i], initials[i]) for n in maxes: lst1 = observations[i].X[:, n] lst2 = states.X[:, n] ind1 = np.array(np.where(np.sign(np.diff(lst1)) == -1))[0, 0] if np.any(np.sign(np.diff(lst2)) == -1): ind2 = np.array(np.where(np.sign(np.diff(lst2)) == -1))[0, 0] else: ind2 = len(lst2) - 1 ret += ((1.0 * ind2 / ind1 - 1)**2 + (lst2[ind2] / lst1[ind1] - 1)**2) / nmeasure if (outflag == 1): print(temperatures[i], tmaxes[i], pressures[i] / ct.one_atm, (1.0 * ind2 / ind1 - 1), (lst2[ind2] / lst1[ind1] - 1)) sys.stdout.flush() for n in yields: lst1 = observations[i].X[:, n] lst2 = states.X[:, n] ret += ((lst2[-1] / lst1[-1] - 1)**2) / nmeasure if (outflag == 1): print(temperatures[i], tmaxes[i], pressures[i] / ct.one_atm, (lst2[-1] / lst1[-1] - 1)) sys.stdout.flush() if (outflag == 1): rstop = timeit.default_timer() print('iter time: %f' % (rstop - rstart)) print('residual: ', ret) print('x: ', eta) sys.stdout.flush() return np.sqrt(ret)
sensnorm, k / k0, result.fun, *removed, sep=' ', file=f) f.close() if (outflag == 1): print(result) sys.stdout.flush() reactions = gas.reaction_equations() if (gas.reaction_type(measure_ind) == 1): newrate = ct.ElementaryReaction( gas.reactions()[measure_ind].reactants, gas.reactions()[measure_ind].products) newrate.rate = ct.Arrhenius( k, gas.reactions()[measure_ind].rate.temperature_exponent, gas.reactions()[measure_ind].rate.activation_energy) gas.modify_reaction(measure_ind, newrate) if (gas.reaction_type(measure_ind) == 2): newrate = ct.ThreeBodyReaction( reactants=gas.reactions()[measure_ind].reactants, products=gas.reactions()[measure_ind].products) newrate.efficiencies = gas.reactions()[measure_ind].efficiencies newrate.rate = ct.Arrhenius( k, gas.reactions()[measure_ind].rate.temperature_exponent, gas.reactions()[measure_ind].rate.activation_energy)
[300.00, 1000.00], [2.08692170E+00, 1.33149650E-01, -8.11574520E-05, 2.94092860E-08, -6.51952130E-12, -3.59128140E+04, 2.73552890E+01] ), NASA( [1000.00, 5000.00], [2.48802010E+01, 7.82500480E-02, -3.15509730E-05, 5.78789000E-09, -3.98279680E-13, -4.31106840E+04, -9.36552550E+01] ) ), ) reaction( equation='A => B', kf=Arrhenius(A=52499925000.0, b=1.5, E=40900.0), ) """ gas = ct.Solution(source=cti_str) gas.TP = 1000, 101325 print(gas.reactions()[0].rate(1000)) print(gas.forward_rate_constants) r = ct.ElementaryReaction({'A': 1}, {'B': 1}) r.rate = ct.Arrhenius(3.87e1, 2.7, 6260 * 1000 * 4.184) gas.modify_reaction(0, r) print(gas.reactions()[0].rate(1000)) print(gas.forward_rate_constants)
def _build_cantera_solution(cls, gdata): p_ref = gdata['ref_pressure'] species_list = list() for s in gdata['species']: spec = gdata['species'][s] ctspec = ct.Species( s, ','.join( [f'{k}:{spec["atom_map"][k]}' for k in spec['atom_map']])) if spec['cp'][0] == 'constant': Tmin, Tmax, T0, h0, s0, cp = spec['cp'][1:] ctspec.thermo = ct.ConstantCp(Tmin, Tmax, p_ref, list([T0, h0, s0, cp])) elif spec['cp'][0] == 'NASA7': Tmin, Tmid, Tmax, low_coeffs, high_coeffs = spec['cp'][1:] coeffs = [Tmid] + high_coeffs + low_coeffs ctspec.thermo = ct.NasaPoly2(Tmin, Tmax, p_ref, coeffs) species_list.append(ctspec) reaction_list = list() for rxn in gdata['reactions']: type, reactants_stoich, products_stoich, reversible = rxn[:4] fwd_pre_exp_value, fwd_temp_exponent, fwd_act_energy = rxn[4:7] fwd_rate = ct.Arrhenius(fwd_pre_exp_value, fwd_temp_exponent, fwd_act_energy) if type == 'simple' or type == 'simple-special': ctrxn = ct.ElementaryReaction(reactants_stoich, products_stoich) ctrxn.rate = fwd_rate elif type == 'three-body' or type == 'three-body-special': ctrxn = ct.ThreeBodyReaction(reactants_stoich, products_stoich) ctrxn.rate = fwd_rate ctrxn.efficiencies = rxn[7] ctrxn.default_efficiency = rxn[8] elif type == 'Lindemann' or type == 'Lindemann-special': ctrxn = ct.FalloffReaction(reactants_stoich, products_stoich) ctrxn.efficiencies = rxn[7] ctrxn.default_efficiency = rxn[8] flf_pre_exp_value, flf_temp_exponent, flf_act_energy = rxn[ 9:12] ctrxn.high_rate = fwd_rate ctrxn.low_rate = ct.Arrhenius(flf_pre_exp_value, flf_temp_exponent, flf_act_energy) ctrxn.falloff = ct.Falloff() elif type == 'Troe' or type == 'Troe-special': ctrxn = ct.FalloffReaction(reactants_stoich, products_stoich) ctrxn.efficiencies = rxn[7] ctrxn.default_efficiency = rxn[8] flf_pre_exp_value, flf_temp_exponent, flf_act_energy = rxn[ 9:12] troe_params = rxn[12] ctrxn.high_rate = fwd_rate ctrxn.low_rate = ct.Arrhenius(flf_pre_exp_value, flf_temp_exponent, flf_act_energy) if len(troe_params) == 4 and abs(troe_params[3]) < 1e-300: ctrxn.falloff = ct.TroeFalloff(troe_params[:3]) else: ctrxn.falloff = ct.TroeFalloff(troe_params) if 'special' in type: ctrxn.orders = rxn[-1] ctrxn.reversible = reversible reaction_list.append(ctrxn) return ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species_list, reactions=reaction_list)
def set_mechanism(self, mech_dict, species_dict={}, bnds=[]): def get_Arrhenius_parameters(entry): A = entry['pre_exponential_factor'] b = entry['temperature_exponent'] Ea = entry['activation_energy'] return A, b, Ea if len(species_dict) == 0: species = self.gas.species() else: species = [] for n in range(len(species_dict)): s_dict = species_dict[n] s = ct.Species(name=s_dict['name'], composition=s_dict['composition'], charge=s_dict['charge'], size=s_dict['size']) thermo = s_dict['type'](s_dict['T_low'], s_dict['T_high'], s_dict['P_ref'], s_dict['coeffs']) s.thermo = thermo species.append(s) # Set kinetics data rxns = [] for rxnIdx in range(len(mech_dict)): if 'ElementaryReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ElementaryReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rxn.allow_negative_pre_exponential_factor = True A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs'][0]) rxn.rate = ct.Arrhenius(A, b, Ea) elif 'ThreeBodyReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ThreeBodyReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs'][0]) rxn.rate = ct.Arrhenius(A, b, Ea) rxn.efficiencies = mech_dict[rxnIdx]['rxnCoeffs'][0][ 'efficiencies'] elif 'PlogReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.PlogReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rates = [] for plog in mech_dict[rxnIdx]['rxnCoeffs']: pressure = plog['Pressure'] A, b, Ea = get_Arrhenius_parameters(plog) rates.append((pressure, ct.Arrhenius(A, b, Ea))) rxn.rates = rates elif 'FalloffReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.FalloffReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) # high pressure limit A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs']['high_rate']) rxn.high_rate = ct.Arrhenius(A, b, Ea) # low pressure limit A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs']['low_rate']) rxn.low_rate = ct.Arrhenius(A, b, Ea) # falloff parameters if mech_dict[rxnIdx]['rxnCoeffs']['falloff_type'] == 'Troe': falloff_param = mech_dict[rxnIdx]['rxnCoeffs'][ 'falloff_parameters'] if falloff_param[-1] == 0.0: falloff_param = falloff_param[0:-1] rxn.falloff = ct.TroeFalloff(falloff_param) else: rxn.falloff = ct.SriFalloff( mech_dict[rxnIdx]['rxnCoeffs']['falloff_parameters']) rxn.efficiencies = mech_dict[rxnIdx]['rxnCoeffs'][ 'efficiencies'] elif 'ChebyshevReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ChebyshevReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rxn.set_parameters(Tmin=mech_dict['Tmin'], Tmax=mech_dict['Tmax'], Pmin=mech_dict['Pmin'], Pmax=mech_dict['Pmax'], coeffs=mech_dict['coeffs']) rxn.duplicate = mech_dict[rxnIdx]['duplicate'] rxn.reversible = mech_dict[rxnIdx]['reversible'] rxn.allow_negative_orders = True rxn.allow_nonreactant_orders = True rxns.append(rxn) self.gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=rxns) self.set_rate_expression_coeffs(bnds) # set copy of coeffs self.set_thermo_expression_coeffs() # set copy of thermo coeffs
def run(gas, interval, num_states, work_dir, repeats=10): def arrhenius(T, A, b, Ea, print_stats=False): vals = A * np.power(T, b) * np.exp(-Ea / (ct.gas_constant * T)) if print_stats: print(A, b, Ea, np.max(np.abs(vals - kf) / kf)) return vals # first, convert all reactions to a single rate form reacs = gas.reactions()[:] for i, reac in enumerate(reacs): if isinstance(reac, ct.ChemicallyActivatedReaction): reacs[i] = ct.ElementaryReaction(reac.reactants, reac.products) reacs[i].rate = reac.high_rate elif isinstance(reac, ct.FalloffReaction): reacs[i] = ct.ElementaryReaction(reac.reactants, reac.products) reacs[i].rate = reac.high_rate elif isinstance(reac, ct.ThreeBodyReaction): reacs[i] = ct.ElementaryReaction(reac.reactants, reac.products) reacs[i].rate = reac.rate elif isinstance(reac, ct.PlogReaction): reacs[i] = ct.ElementaryReaction(reac.reactants, reac.products) reacs[i].rate = reac.rates[-1][1] elif isinstance(reac, ct.ChebyshevReaction): # fit _something_ to it at a 10 bar, for 600-2200K T = np.linspace(600, 2200, num=1000) kf = np.zeros_like(T) for j in range(T.size): kf[j] = reac(T[j], 10 * 10*1e5) A = 1e10 b = 1 Ea = 1200 * ct.gas_constant (A, b, Ea), _ = curve_fit( arrhenius, T, kf, p0=[A, b, Ea], bounds=[(0, -2, 0), (np.inf, 5, np.inf)], maxfev=1e6, xtol=1e-15) if False: plt.plot(T, kf, color='b', linestyle='-', label='cheb') plt.plot(T, arrhenius(T, A, b, Ea), color='r', linestyle='--', label='fit') plt.legend(loc=0) plt.show() reacs[i] = ct.ElementaryReaction(reac.reactants, reac.products) reacs[i].rate = ct.Arrhenius(A, b, Ea) # set all to reversible reacs[i].reversible = True # and convert gas gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', reactions=reacs, species=gas.species()) # next, order the reactions by the number of distinct species def get_reac_and_spec_maps(mygas): # first, create rxn->species maps reac_nu = mygas.reactant_stoich_coeffs() prod_nu = mygas.product_stoich_coeffs() # species -> rxn mappings spec_masks = np.zeros((mygas.n_species, mygas.n_reactions), dtype=np.bool) # the reaction -> species mappings reac_masks = [] for i, reac in enumerate(mygas.reactions()): for spec in set(list(reac.reactants.keys()) + list( reac.products.keys())): j = mygas.species_index(spec) if prod_nu[j, i] - reac_nu[j, i]: # non-zero species spec_masks[j, i] = True reac_masks.append(np.where(spec_masks[:, i])[0]) # convert to flat, fixed size array copy = np.array(reac_masks, copy=True) max_size = np.max([x.size for x in reac_masks]) reac_masks = np.full((len(reac_masks), max_size), -1) for i, mask in enumerate(copy): reac_masks[i, :mask.size] = mask[:] return spec_masks, reac_masks # ensure we didn't remove any species spec_masks, reac_masks = get_reac_and_spec_maps(gas) converted_spec_count = np.where(~np.sum(spec_masks, axis=1))[0].size assert converted_spec_count == gas.n_species def species_to_rxn_count(reac_list=slice(None)): """ The number of reactions each species is in """ return np.sum(spec_masks[:, reac_list], axis=1) def simple(specs, spec_counts): """ Returns 0 if any species in the reaction is unique to that reaction otherwise mean of the number of reactions per species in the reaction """ specs = specs[np.where(specs >= 0)] if np.any(spec_counts[specs] == 1): return 0 return np.mean(spec_counts[specs]) def minh(specs, spec_counts): """ The minimum number of reactions any species in the reaction is in """ specs = specs[np.where(specs >= 0)] minh = np.min(spec_counts[specs]) return 0 if minh == 1 else minh def rxn_scores(heuristic, reac_list=slice(None)): """ Returns a score from 0--1, where 1 indicates that the reactions is a good removal candidate and 0 a bad candidate Heuristics correspond to local methods """ reac_list = np.arange(gas.n_reactions)[reac_list] s2r = species_to_rxn_count(reac_list) scores = np.apply_along_axis(heuristic, 1, reac_masks[reac_list], s2r) return scores def get_next_removed(heuristic, reac_list=slice(None)): """ Get the index of the next reaction to remove from the current reac_list using the given heuristic """ scores = rxn_scores(heuristic, reac_list) amax = np.argmax(scores) if scores[amax] == 0: return -1 return reac_list[amax] def active_reactions(reac_list, return_active=False): """ Returns the number of active reactions in the reac_list If return_active is True, return the list of active reactions """ alist = np.where(reac_list >= 0)[0] if return_active: return alist return alist.size saved_reaction_lists = [] reac_list = np.arange(gas.n_reactions) saved_reaction_lists.append(active_reactions(reac_list, True)) while True: remove_at = get_next_removed(minh, reac_list=np.where( reac_list >= 0)[0]) if remove_at == -1: break reac_list[remove_at] = -1 if (active_reactions(reac_list) <= active_reactions( saved_reaction_lists[-1]) - interval): # save list saved_reaction_lists.append(active_reactions(reac_list, True)) # get final reaction list and save reac_list = active_reactions(reac_list, True) saved_reaction_lists.append(reac_list) def gas_from_reac_list(reac_list): reacs = gas.reactions()[:] reacs = [reacs[i] for i in reac_list] return ct.Solution(thermo='IdealGas', kinetics='GasKinetics', reactions=reacs, species=gas.species()) # remap, and ensure the number of removed species is not less than # previously newgas = gas_from_reac_list(reac_list) smap_final, _ = get_reac_and_spec_maps(newgas) scount_final = np.where(~np.sum(smap_final, axis=1))[0].size assert scount_final == converted_spec_count print('Final mechanism size: {} reactions, {} species'.format( newgas.n_reactions, scount_final)) vecsize = 8 platform = 'intel' split_rate_kernels = False lang = 'opencl' rate_spec = 'hybrid' num_cores = 1 order = 'C' def get_filename(wide=False): """ emulate pyjac's naming scheme """ desc = 'spec' vsize = vecsize if wide else '1' vectype = 'w' if wide else 'par' platform = 'intel' split = 'split' if split_rate_kernels else 'single' conp = 'conp' return '{}_{}_{}_{}_{}_{}_{}_{}_{}_{}'.format( desc, lang, vsize, order, vectype, platform, rate_spec, split, num_cores, conp) + '.txt' def check_file(file): if not os.path.exists(file): return repeats with open(file, 'r') as f: lines = f.readlines() import re todo = repeats for line in lines: line = line.split(',') if len(line) > 1 and sum( 1 if re.search(r'(?:\d+(?:\.\d+e[+-]\d+))', l) else 0 for l in line) == 4: # four doubles -> good line todo -= 1 return todo build = os.path.join(path, 'out') obj = os.path.join(path, 'obj') lib = os.path.join(path, 'lib') for wide in [True, False]: vsize = vecsize if wide else None # now, go through the various generated reactions lists and run # the test on each for reac_list in saved_reaction_lists: outname = get_filename(wide) todo = check_file(outname) # clean clean_dir(build, remove_dir=False) clean_dir(obj, remove_dir=False) clean_dir(lib, remove_dir=False) subdir = os.path.join(work_dir, str(active_reactions(reac_list))) create_dir(subdir) # generate the source rate evaluation rgas = gas_from_reac_list(reac_list) create_jacobian('opencl', gas=rgas, vector_size=vsize, wide=wide, build_path=build, rate_specialization=rate_spec, split_rate_kernels=split_rate_kernels, data_filename=os.path.abspath( os.path.join(work_dir, 'data.bin')), data_order=order, platform=platform, skip_jac=True) # first create the executable (via libgen) tester = generate_library(lang, build, obj_dir=obj, out_dir=lib, shared=True, btype=build_type.species_rates, as_executable=True) # and do runs with open(os.path.join(subdir, outname), 'a+') as file: for i in range(todo): print(i, "/", todo) subprocess.check_call([os.path.join(lib, tester), str(num_states), str(1)], stdout=file)
def toCantera(self, speciesList=None, useChemkinIdentifier = False): """ Converts the RMG Reaction object to a Cantera Reaction object with the appropriate reaction class. If useChemkinIdentifier is set to False, the species label is used instead. Be sure that species' labels are unique when setting it False. """ from rmgpy.kinetics import Arrhenius, ArrheniusEP, MultiArrhenius, PDepArrhenius, MultiPDepArrhenius, Chebyshev, ThirdBody, Lindemann, Troe import cantera as ct if speciesList is None: speciesList = [] # Create the dictionaries containing species strings and their stoichiometries # for initializing the cantera reaction object ctReactants = {} for reactant in self.reactants: if useChemkinIdentifier: reactantName = reactant.toChemkin() else: reactantName = reactant.label if reactantName in ctReactants: ctReactants[reactantName] += 1 else: ctReactants[reactantName] = 1 ctProducts = {} for product in self.products: if useChemkinIdentifier: productName = product.toChemkin() else: productName = product.label if productName in ctProducts: ctProducts[productName] += 1 else: ctProducts[productName] = 1 if self.kinetics: if isinstance(self.kinetics, Arrhenius): # Create an Elementary Reaction ctReaction = ct.ElementaryReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, MultiArrhenius): # Return a list of elementary reactions which are duplicates ctReaction = [ct.ElementaryReaction(reactants=ctReactants, products=ctProducts) for arr in self.kinetics.arrhenius] elif isinstance(self.kinetics, PDepArrhenius): ctReaction = ct.PlogReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, MultiPDepArrhenius): ctReaction = [ct.PlogReaction(reactants=ctReactants, products=ctProducts) for arr in self.kinetics.arrhenius] elif isinstance(self.kinetics, Chebyshev): ctReaction = ct.ChebyshevReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, ThirdBody): ctReaction = ct.ThreeBodyReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, Lindemann) or isinstance(self.kinetics, Troe): ctReaction = ct.FalloffReaction(reactants=ctReactants, products=ctProducts) else: raise NotImplementedError('Not able to set cantera kinetics for {0}'.format(self.kinetics)) # Set reversibility, duplicate, and ID attributes if isinstance(ctReaction,list): for rxn in ctReaction: rxn.reversible = self.reversible # Set the duplicate flag to true since this reaction comes from multiarrhenius or multipdeparrhenius rxn.duplicate = True # Set the ID flag to the original rmg index rxn.ID = str(self.index) else: ctReaction.reversible = self.reversible ctReaction.duplicate = self.duplicate ctReaction.ID = str(self.index) self.kinetics.setCanteraKinetics(ctReaction, speciesList) return ctReaction else: raise Exception('Cantera reaction cannot be created because there was no kinetics.')