def test_plog(self): gas1 = ct.Solution('pdep-test.cti') species = ct.Species.listFromFile('pdep-test.cti') r = ct.PlogReaction() r.reactants = {'R1A': 1, 'R1B': 1} r.products = {'P1': 1, 'H': 1} r.rates = [ (0.01 * ct.one_atm, ct.Arrhenius(1.2124e13, -0.5779, 10872.7 * 4184)), (1.0 * ct.one_atm, ct.Arrhenius(4.9108e28, -4.8507, 24772.8 * 4184)), (10.0 * ct.one_atm, ct.Arrhenius(1.2866e44, -9.0246, 39796.5 * 4184)), (100.0 * ct.one_atm, ct.Arrhenius(5.9632e53, -11.529, 52599.6 * 4184)) ] gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) gas2.X = gas1.X = 'R1A:0.3, R1B:0.6, P1:0.1' for P in [0.001, 0.01, 0.2, 1.0, 1.1, 9.0, 10.0, 99.0, 103.0]: gas1.TP = gas2.TP = 900, P * ct.one_atm self.assertNear(gas2.forward_rate_constants[0], gas1.forward_rate_constants[0]) self.assertNear(gas2.net_rates_of_progress[0], gas1.net_rates_of_progress[0])
def test_negative_A_falloff(self): species = ct.Species.listFromFile('gri30.yaml') r = ct.FalloffReaction('NH:1, NO:1', 'N2O:1, H:1') r.low_rate = ct.Arrhenius(2.16e13, -0.23, 0) r.high_rate = ct.Arrhenius(-8.16e12, -0.5, 0) self.assertFalse(r.allow_negative_pre_exponential_factor) with self.assertRaisesRegex(ct.CanteraError, 'pre-exponential'): gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) r.allow_negative_pre_exponential_factor = True # Should still fail because of mixed positive and negative A factors with self.assertRaisesRegex(ct.CanteraError, 'pre-exponential'): gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) r.low_rate = ct.Arrhenius(-2.16e13, -0.23, 0) gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) self.assertLess(gas.forward_rate_constants, 0)
def setUpClass(cls): ReactionTests.setUpClass() param = cls._rate["low_P_rate_constant"] low = ct.Arrhenius(param["A"], param["b"], param["Ea"]) param = cls._rate["high_P_rate_constant"] high = ct.Arrhenius(param["A"], param["b"], param["Ea"]) cls._rate_obj = ct.LindemannRate(low=low, high=high, falloff_coeffs=[])
def setUpClass(cls): ReactionTests.setUpClass() param = cls._rate["low_P_rate_constant"] low = ct.Arrhenius(param["A"], param["b"], param["Ea"]) param = cls._rate["high_P_rate_constant"] high = ct.Arrhenius(param["A"], param["b"], param["Ea"]) param = cls._rate["Troe"] data = [param["A"], param["T3"], param["T1"], param["T2"]] cls._rate_obj = ct.TroeRate(low=low, high=high, falloff_coeffs=data)
def modify_surface_kinetics(surface, param_to_set): """changes a set of numerical parameters of a an Interface among following: site_density, coverages, concentrations, pre-exponential factor, temperature_exponent, activation_energy """ if not HAS_CANTERA: raise SpectroChemPyException( 'Cantera is not available : please install it before continuing: \n' 'conda install -c cantera cantera') # check some parameters if type(surface) is not ct.composite.Interface: raise ValueError('only implemented of ct.composite.Interface') for param in param_to_set: # check that param_to_change exists try: eval('surface.' + param) except ValueError: print('class {} has no \'{}\' attribute'.format( type(surface), param)) raise # if exists => sets its new value # if the attribute is writable: if param in ('site_density', 'coverages', 'concentrations'): init_coverages = surface.coverages exec('surface.' + param + '=' + str(param_to_set[param])) if param == 'site_density': # coverages must be reset surface.coverages = init_coverages # else use Cantera methods (or derived from cantera) elif param.split('.')[-1] == 'pre_exponential_factor': str_rate = 'surface.' + '.'.join(param.split('.')[-3:-1]) b, E = eval(str_rate + '.temperature_exponent,' + str_rate + '.activation_energy ') rxn = int(param.split('.')[0].split('[')[-1].split(']')[0]) modify_rate(surface, rxn, ct.Arrhenius(param_to_set[param], b, E)) elif param.split('.')[-1] == 'temperature_exponent': str_rate = 'surface.' + '.'.join(param.split('.')[-3:-1]) A, E = eval(str_rate + 'pre_exponential_factor,' + str_rate + '.activation_energy ') rxn = int(param.split('.')[0].split('[')[-1].split(']')[0]) modify_rate(surface, rxn, ct.Arrhenius(A, param_to_set[param], E)) elif param.split('.')[-1] == 'activation_energy': str_rate = 'surface.' + '.'.join(param.split('.')[-3:-1]) A, b = eval(str_rate + 'pre_exponential_factor,' + str_rate + '.temperature_exponent') rxn = int(param.split('.')[0].split('[')[-1].split(']')[0]) modify_rate(surface, rxn, ct.Arrhenius(A, b, param_to_set[param])) return
def test_falloff(self): r = ct.FalloffReaction('OH:2', 'H2O2:1') r.high_rate = ct.Arrhenius(7.4e10, -0.37, 0.0) r.low_rate = ct.Arrhenius(2.3e12, -0.9, -1700*1000*4.184) r.falloff = ct.TroeFalloff((0.7346, 94, 1756, 5182)) r.efficiencies = {'AR':0.7, 'H2':2.0, 'H2O':6.0} 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[20]) self.assertNear(gas2.net_rates_of_progress[0], self.gas.net_rates_of_progress[20])
def setUpClass(cls): ReactionTests.setUpClass() if cls._legacy: args = list(cls._rate.values()) cls._rate_obj = ct.Arrhenius(*args) else: cls._rate_obj = ct.ArrheniusRate(**cls._rate)
def test_interface(self): surf_species = ct.Species.listFromFile('ptcombust.xml') gas = ct.Solution('ptcombust.xml', 'gas') surf1 = ct.Interface('ptcombust.xml', 'Pt_surf', [gas]) r1 = ct.InterfaceReaction() r1.reactants = 'H(S):2' r1.products = 'H2:1, PT(S):2' r1.rate = ct.Arrhenius(3.7e20, 0, 67.4e6) r1.coverage_deps = {'H(S)': (0, 0, -6e6)} self.assertNear(r1.coverage_deps['H(S)'][2], -6e6) surf2 = ct.Interface(thermo='Surface', species=surf_species, kinetics='interface', reactions=[r1], phases=[gas]) surf2.site_density = surf1.site_density surf1.coverages = surf2.coverages = 'PT(S):0.7, H(S):0.3' gas.TP = surf2.TP = surf1.TP for T in [300, 500, 1500]: gas.TP = surf1.TP = surf2.TP = T, 5 * ct.one_atm self.assertNear(surf1.forward_rate_constants[1], surf2.forward_rate_constants[0]) self.assertNear(surf1.net_rates_of_progress[1], surf2.net_rates_of_progress[0])
def modify_reactions( self, coeffs, rxnNums=[]): # Only works for Arrhenius equations currently if not rxnNums: # if rxnNums does not exist, modify all rxnNums = range(len(coeffs)) else: if isinstance( rxnNums, (float, int)): # if single reaction given, run that one rxnNums = [rxnNums] for rxnNum in rxnNums: rxn = self.gas.reaction(rxnNum) if type(rxn) is ct.ElementaryReaction or type( rxn) is ct.ThreeBodyReaction: # Get current values A = coeffs[rxnNum]['pre_exponential_factor'] b = coeffs[rxnNum]['temperature_exponent'] Ea = coeffs[rxnNum]['activation_energy'] # Update reaction rate rxn.rate = ct.Arrhenius(A, b, Ea) # elif type(rxn) is ct.PlogReaction: # print(dir(rxn)) # print(rxn.rates[rxn_num]) # elif type(rxn) is ct.ChebyshevReaction: # print(dir(rxn)) # print(rxn.rates[rxn_num]) else: continue self.gas.modify_reaction(rxnNum, rxn)
def fitness(indv): tmp_parameters = indv.solution tmp_reactions = R.copy() for i in range(len(tmp_reactions)): if tmp_reactions[i].reaction_type !=4: tmp_reactions[i].rate = ct.Arrhenius(A = tmp_parameters[3*i], \ b = tmp_parameters[3*i+1], E = tmp_parameters[3*i+2]) else: tmp_reactions[i].low_rate = ct.Arrhenius(A = tmp_parameters[3*i], \ b = tmp_parameters[3*i+1], E = tmp_parameters[3*i+2]) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics',species=gas.species(),reactions=tmp_reactions) gas2.TPX = temp, pres, 'CH4:1, O2:2' r = ct.IdealGasConstPressureReactor(gas2) sim = ct.ReactorNet([r]) states = ct.SolutionArray(gas2, extra=['t']) try: for t in np.arange(0, end_time, step_time): sim.advance(t) states.append(r.thermo.state, t=1000*t) except: return 1e8 max_delta = 0 index_temp = 0 for i in range(len(states.T)-2): if(states.T[i+1] - states.T[i] > max_delta): max_delta = states.T[i+1] - states.T[i] index_temp = i ignite_time_optimised = float(states.t[index_temp]) optimised_T = float(states.T[-1] ) optimised_CH4 = float(states('CH4').X[-1] ) optimised_O2 = float(states('O2').X[-1] ) optimised_CO2 = float(states('CO2').X[-1] ) optimised_H2O = float(states('H2O').X[-1] ) optimised_H = float(states('H').X[-1] ) optimised_OH = float(states('OH').X[-1] ) # return ((ignite_time_optimised - ignite_time_precise)/ignite_time_precise)**2\ # + ((optimised_T - precise_T)/precise_T)**2\ # + ((optimised_O2 - precise_O2)/precise_O2)**2\ # + ((optimised_CO2 - precise_CO2)/precise_CO2)**2\ # + ((optimised_H2O - precise_H2O)/precise_H2O)**2\ return 1e8*abs(ignite_time_optimised - ignite_time_precise) + abs(optimised_T - precise_T)
def test_arrhenius(self): # test assigning Arrhenius rate rate = ct.Arrhenius(self._rate["A"], self._rate["b"], self._rate["Ea"]) rxn = self.from_rate(None) if self._legacy: rxn.rate = rate else: with self.assertWarnsRegex(DeprecationWarning, "'Arrhenius' object is deprecated"): rxn.rate = rate self.check_rxn(rxn)
def test_arrhenius(self): # test assigning Arrhenius rate rate = ct.Arrhenius(self._rate["A"], self._rate["b"], self._rate["Ea"]) rxn = self._cls(equation=self._equation, kinetics=self.gas, legacy=self._legacy, **self._kwargs) if self._legacy: rxn.rate = rate else: with self.assertWarnsRegex(DeprecationWarning, "'Arrhenius' object is deprecated"): rxn.rate = rate self.check_rxn(rxn)
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_modify_sticking(self): gas = ct.Solution('ptcombust.xml', 'gas') surf = ct.Interface('ptcombust.xml', 'Pt_surf', [gas]) surf.coverages = 'O(S):0.1, PT(S):0.5, H(S):0.4' gas.TP = surf.TP R = surf.reaction(2) R.rate = ct.Arrhenius(0.25, 0, 0) # original sticking coefficient = 1.0 k1 = surf.forward_rate_constants[2] surf.modify_reaction(2, R) k2 = surf.forward_rate_constants[2] self.assertNear(k1, 4*k2)
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_threebody(self): r = ct.ThreeBodyReaction() r.reactants = {'O':1, 'H':1} r.products = {'OH':1} r.rate = ct.Arrhenius(5e11, -1.0, 0.0) r.efficiencies = {'AR':0.7, 'H2':2.0, 'H2O':6.0} 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[1]) self.assertNear(gas2.net_rates_of_progress[0], self.gas.net_rates_of_progress[1])
def test_modify_third_body(self): gas = ct.Solution('h2o2.xml') gas.TPX = self.gas.TPX R = self.gas.reaction(5) A1 = R.rate.pre_exponential_factor b1 = R.rate.temperature_exponent T = gas.T kf1 = gas.forward_rate_constants[5] A2 = 1.7 * A1 b2 = b1 - 0.1 R.rate = ct.Arrhenius(A2, b2, 0.0) gas.modify_reaction(5, R) kf2 = gas.forward_rate_constants[5] self.assertNear((A2 * T**b2) / (A1 * T**b1), kf2 / kf1)
def test_modify_elementary(self): gas = ct.Solution('h2o2.xml') gas.TPX = self.gas.TPX R = self.gas.reaction(2) A1 = R.rate.pre_exponential_factor b1 = R.rate.temperature_exponent Ta1 = R.rate.activation_energy / ct.gas_constant T = gas.T self.assertNear(A1*T**b1*np.exp(-Ta1/T), gas.forward_rate_constants[2]) A2 = 1.5 * A1 b2 = b1 + 0.1 Ta2 = Ta1 * 1.2 R.rate = ct.Arrhenius(A2, b2, Ta2 * ct.gas_constant) gas.modify_reaction(2, R) self.assertNear(A2*T**b2*np.exp(-Ta2/T), gas.forward_rate_constants[2])
def test_set_rates(self): # test setter for property rates other = [ {"P": 100., "A": 1.2124e+16, "b": -1., "Ea": 45491376.8}, {"P": 10000., "A": 4.9108e+31, "b": -2., "Ea": 103649395.2}, {"P": 1000000., "A": 1.2866e+47, "b": -3., "Ea": 166508556.0}] rate = ct.PlogRate([(o["P"], ct.Arrhenius(o["A"], o["b"], o["Ea"])) for o in other]) rates = rate.rates self.assertEqual(len(rates), len(other)) for index, item in enumerate(rates): P, rate = item self.assertNear(P, other[index]["P"]) self.assertNear(rate.pre_exponential_factor, other[index]["A"]) self.assertNear(rate.temperature_exponent, other[index]["b"]) self.assertNear(rate.activation_energy, other[index]["Ea"])
def modify_reactions( self, coeffs, rxnNums=[]): # Only works for Arrhenius equations currently if not rxnNums: # if rxnNums does not exist, modify all rxnNums = range(len(coeffs)) else: if isinstance( rxnNums, (float, int)): # if single reaction given, run that one rxnNums = [rxnNums] for rxnNum in rxnNums: rxn = self.gas.reaction(rxnNum) rxnChanged = False if type(rxn) is ct.ElementaryReaction or type( rxn) is ct.ThreeBodyReaction: for coefName in [ 'activation_energy', 'pre_exponential_factor', 'temperature_exponent' ]: if coeffs[rxnNum][coefName] != eval( f'rxn.rate.{coefName}'): rxnChanged = True if rxnChanged: # Update reaction rate A = coeffs[rxnNum]['pre_exponential_factor'] b = coeffs[rxnNum]['temperature_exponent'] Ea = coeffs[rxnNum]['activation_energy'] rxn.rate = ct.Arrhenius(A, b, Ea) # elif type(rxn) is ct.PlogReaction: # print(dir(rxn)) # print(rxn.rates[rxn_num]) # elif type(rxn) is ct.ChebyshevReaction: # print(dir(rxn)) # print(rxn.rates[rxn_num]) else: continue if rxnChanged: self.gas.modify_reaction(rxnNum, rxn) time.sleep( 5E-3 ) # Not sure if this is necessary, but it reduces strange behavior in incident shock reactor
def set_max_sticking_coeff(rxn, A=0.75): """ Fix the maximum sticking coefficient for the given reaction. ToDo: currently this ignores n and Ea in an Arrhenius expression and replaces with a uniform A value.. Also, doesn't yet actually update the kinetics object in Cantera memory. """ assert rxn.is_sticking_coefficient if rxn.rate.pre_exponential_factor > A: old_stick = rxn.rate rate = ct.Arrhenius(A) rxn.rate = rate print( f"Changed sticking coeff for {rxn.equation} from {old_stick!r} to {rxn.rate.pre_exponential_factor}" ) raise NotImplementedError( "Haven't updated the kinetics object in Cantera")
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)
*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) gas.modify_reaction(measure_ind, newrate) if (gas.reaction_type(measure_ind) == 4): newrate = ct.FalloffReaction( reactants=gas.reactions()[measure_ind].reactants,
states('CO2').X, '--', label='Redeuced to {} reactions'.format(gas2.n_reactions)) plt.legend() plt.xlabel('Time (ms)') plt.ylabel('CO2 Mole Fraction') import best_fit tmp_reactions = R.copy() tmp_parameters = best_fit.best_fit[-1][1] print(len(tmp_reactions)) for i in range(len(tmp_reactions)): if tmp_reactions[i].reaction_type != 4: tmp_reactions[i].rate = ct.Arrhenius(A=tmp_parameters[3 * i], b=tmp_parameters[3 * i + 1], E=tmp_parameters[3 * i + 2]) else: tmp_reactions[i].low_rate = ct.Arrhenius(A=tmp_parameters[3 * i], b=tmp_parameters[3 * i + 1], E=tmp_parameters[3 * i + 2]) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=gas.species(), reactions=tmp_reactions) gas2.TPX = temp, pres, 'CH4:1, O2:2' r = ct.IdealGasConstPressureReactor(gas2) sim = ct.ReactorNet([r]) states = ct.SolutionArray(gas2, extra=['t'])
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 cti_write(x={},original_cti='',master_rxns='',master_index=[]): if not original_cti: raise Exception('Please provide a name for the original mechanism file and try again.') if not master_rxns and np.any(master_index): raise Exception('Please provide a mechanism file for reactions analysed with master equation or leave master_index empty') if master_rxns and not np.any(master_index): raise Exception('Please provide master_index, a non-empty list of reaction numbers from original file which are analysed with master equation.') if not master_rxns and not master_index: master_index=np.ones(ct.Solution(original_cti).n_reactions,dtype=bool) elif master_rxns and np.any(master_index): temp=np.ones(ct.Solution(original_cti).n_reactions,dtype=bool) for j in np.arange(len(master_index)): temp[master_index[j]-1]=False master_index=temp lineList=[] with open(original_cti) as f: lineList=f.readlines() done=False count=0 while not done or count<len(lineList): if 'Reaction data' in lineList[count] or 'Reaction Data' in lineList[count] or 'reaction data' in lineList[count]: done=True lineList=lineList[0:count-1] else:count+=1 with open('tempcti.cti','w') as p: p.writelines(lineList) NewModel=ct.Solution('tempcti.cti') original_mechanism=ct.Solution(original_cti) master_count=0 if master_rxns: master_reactions=ct.Solution(master_rxns) for i in np.arange(original_mechanism.n_reactions): if master_index[i]==True: NewModel.add_reaction(original_mechanism.reaction(i)) elif master_index[i]==False: NewModel.add_reaction(master_reactions.reaction(master_count)) master_count+=1 if x=={}: for j in np.arange(original_mechanism.n_reactions): if master_index[j]: if 'ThreeBodyReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rate=original_mechanism.reaction(j).rate elif 'ElementaryReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rate=original_mechanism.reaction(j).rate elif 'FalloffReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).high_rate=original_mechanism.reaction(j).high_rate NewModel.reaction(j).low_rate=original_mechanism.reaction(j).low_rate if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'ChemicallyActivatedReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).high_rate=original_mechanism.reaction(j).high_rate NewModel.reaction(j).low_rate=original_mechanism.reaction(j).low_rate if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'PlogReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rates=original_mechanism.reaction(j).rates elif 'ChebyshevReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).set_parameters(original_mechanism.reaction(j).Tmin,original_mechanism.reaction(j).Tmax,original_mechanism.reaction(j).Pmin,original_mechanism.reaction(j).Pmax,original_mechanism.reaction(j).coeffs) if x!={}: for j in np.arange(original_mechanism.n_reactions): if master_index[j]: try: if 'ThreeBodyReaction' in str(type(original_mechanism.reaction(j))): A=original_mechanism.reaction(j).rate.pre_exponential_factor n=original_mechanism.reaction(j).rate.temperature_exponent Ea=original_mechanism.reaction(j).rate.activation_energy NewModel.reaction(j).rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) elif 'ElementaryReaction' in str(type(original_mechanism.reaction(j))): A=original_mechanism.reaction(j).rate.pre_exponential_factor n=original_mechanism.reaction(j).rate.temperature_exponent Ea=original_mechanism.reaction(j).rate.activation_energy NewModel.reaction(j).rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) elif 'FalloffReaction' in str(type(original_mechanism.reaction(j))): A=original_mechanism.reaction(j).high_rate.pre_exponential_factor n=original_mechanism.reaction(j).high_rate.temperature_exponent Ea=original_mechanism.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) A=original_mechanism.reaction(j).low_rate.pre_exponential_factor n=original_mechanism.reaction(j).low_rate.temperature_exponent Ea=original_mechanism.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'ChemicallyActivatedReaction' in str(type(original_mechanism.reaction(j))): A=original_mechanism.reaction(j).high_rate.pre_exponential_factor n=original_mechanism.reaction(j).high_rate.temperature_exponent Ea=original_mechanism.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) A=original_mechanism.reaction(j).low_rate.pre_exponential_factor n=original_mechanism.reaction(j).low_rate.temperature_exponent Ea=original_mechanism.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate=ct.Arrhenius(A*np.exp(x['r'+str(j)]['A']),n+x['r'+str(j)]['n'],Ea+x['r'+str(j)]['Ea']) if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'PlogReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rates=original_mechanism.reaction(j).rates elif 'ChebyshevReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).set_parameters(original_mechanism.reaction(j).Tmin,original_mechanism.reaction(j).Tmax,original_mechanism.reaction(j).Pmin,original_mechanism.reaction(j).Pmax,original_mechanism.reaction(j).coeffs) except: if 'ThreeBodyReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rate=original_mechanism.reaction(j).rate elif 'ElementaryReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rate=original_mechanism.reaction(j).rate elif 'FalloffReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).high_rate=original_mechanism.reaction(j).high_rate NewModel.reaction(j).low_rate=original_mechanism.reaction(j).low_rate if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'ChemicallyActivatedReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).high_rate=original_mechanism.reaction(j).high_rate NewModel.reaction(j).low_rate=original_mechanism.reaction(j).low_rate if original_mechanism.reaction(j).falloff.type=='Troe': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff if original_mechanism.reaction(j).falloff.type=='Sri': NewModel.reaction(j).falloff=original_mechanism.reaction(j).falloff elif 'PlogReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).rates=original_mechanism.reaction(j).rates elif 'ChebyshevReaction' in str(type(original_mechanism.reaction(j))): NewModel.reaction(j).set_parameters(original_mechanism.reaction(j).Tmin,original_mechanism.reaction(j).Tmax,original_mechanism.reaction(j).Pmin,original_mechanism.reaction(j).Pmax,original_mechanism.reaction(j).coeffs) new_file=ctiw.write(NewModel) return new_file
def run_single(self): def chebyshev_zeros(da,*args): i, m, k, gas, modified_rate, current_array=args temp_r=gas.reactions()[i] temp_array=copy.deepcopy(current_array) temp_array[m,k]=current_array[m,k]+da temp_r.set_parameters(temp_r.Tmin,temp_r.Tmax,temp_r.Pmin,temp_r.Pmax,temp_array) #temp_r.coeffs[m,k]=gas.reactions()[i].coeffs[m,k]+da gas.modify_reaction(i,temp_r) adjusted_rate=gas.forward_rate_constants[i] diff=adjusted_rate-modified_rate return diff gas=self.processor.solution self.flame=ct.FreeFlame(gas,width=self.flame_width) self.TPX=copy.deepcopy(gas.TPX) self.flame.flame.set_steady_tolerances(default=self.tol_ss) #Set steady state tolerances self.flame.flame.set_transient_tolerances(default=self.tol_ts) #Set transient tolerances print('Running simulation at T = '+str(round(gas.T,5))+', P = '+str(round(gas.P,5))+'\nConditions: '+str(self.conditions)) if re.match('[aA]diabatic',self.thermalBoundary): energycon = True self.flame.energy_enabled = energycon self.flame.transport_model = 'Multi' self.flame.set_max_jac_age(10,10) #self.flame.solve(self.loglevel,refine_grid=False) self.flame.soret_enabled = self.soret self.flame.set_refine_criteria(ratio=2.0,slope=0.01,curve=0.025) #self.flame.transport_model = 'Multi' self.flame.solve(self.loglevel,refine_grid=True) self.forward_rates=self.flame.forward_rate_constants self.net_rates=self.flame.net_rates_of_progress self.reverse_rates=self.flame.reverse_rate_constants gas.TPX=self.TPX #self.flame.solve(self.loglevel,refine_grid=False) # self.flame.solve(self.loglevel,refine_grid=False) # self.flame.solve(self.loglevel,refine_grid=False) # self.flame.solve(self.loglevel,refine_grid=False) # self.flame.solve(self.loglevel,refine_grid=False) # self.flame.solve(self.loglevel,refine_grid=False) self.dk=0.01 if re.match('[Ff]lame [Ss]peed',self.flametype): columns=['T_in','pressure']+list(self.conditions.keys())+['u0'] self.solution=pd.DataFrame(columns=columns) for i in range(len(columns)): if i==0: self.solution['T_in']=[self.temperature] elif i==1: self.solution['pressure']=[self.pressure] elif i>1 and i<len(columns)-1: self.solution[columns[i]]=[self.conditions[columns[i]]] elif i==len(columns)-1: self.solution['u0']=[self.flame.u[0]] elif re.match('[Aa]diabatic [Ff]lame',self.flametype): self.solution=self.flame.X columnNames=gas.species_names tempdata=pd.DataFrame(columns=columnNames,data=self.flame.X) print(tempdata) if re.match('[Aa]diabatic [Ff]lame',self.flametype) and self.kineticSens==1 and bool(self.observables): self.dk=0.01 #Calculate kinetic sensitivities sensIndex = [self.flame.grid.tolist(),gas.reaction_equations(),self.observables] S = np.zeros((len(self.flame.grid),gas.n_reactions,len(self.observables))) #print(solution.X[solution.flame.component_index(observables[0])-4,len(f.grid)-1]) #a=solution.X[solution.flame.component_index(observables[0])-4,len(f.grid)-1] for m in range(gas.n_reactions): gas.set_multiplier(1.0) gas.set_multiplier(1+self.dk,m) self.flame.solve(loglevel=1,refine_grid=False) for i in np.arange(len(self.observables)): for k in np.arange(len(self.flame.grid)): S[k,m,i]=np.log10(self.solution[self.flame.flame.component_index(self.observables[i])-4,k])-np.log10(self.flame.X[self.flame.flame.component_index(self.observables[i])-4,k]) #print(solution.X[solution.flame.component_index(observables[i])-4,k]) #print(f.X[f.flame.component_index(observables[i])-4,k]) S[k,m,i]=np.divide(S[k,m,i],np.log10(self.dk)) elif self.kineticSens==1 and bool(self.observables)==False and not re.match('[Ff]lame [Ss]peed',self.flametype): raise Exception('Please supply a list of observables in order to run kinetic sensitivity analysis') #gas.set_multiplier(1.0) elif self.kineticSens==1 and re.match('[Ff]lame [Ss]peed',self.flametype): #self.fsens = self.flame.get_flame_speed_reaction_sensitivities() sensdict={} nominal_u=self.flame.u[0] for i in range(len(gas.reactions())): equation_type=type(gas.reaction(i)).__name__ gas.TPX=self.TPX if equation_type=='ElementaryReaction' or equation_type=='ThreeBodyReaction': tempA=copy.deepcopy(gas.reaction(i).rate.pre_exponential_factor) tempn=copy.deepcopy(gas.reaction(i).rate.temperature_exponent) tempEa=copy.deepcopy(gas.reaction(i).rate.activation_energy) #gas.reaction(i).rate=ct.Arrhenius(tempA*(1.0+self.dk),tempn,tempEa) #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn,tempEa) temp_r=gas.reactions()[i] temp_r.rate=ct.Arrhenius(tempA*(1.0+self.dk),tempn,tempEa) gas.modify_reaction(i,temp_r) print('Solving flame speed sensitivity with respect to Arrhenius parameters for reaction '+str(i)) #print(self.flame.gas.reaction(i).rate) #print(tempA,tempn,tempEa) if self.log_file: with open(self.log_name,'a') as f: f.write('Reaction '+str(i)+' Nominals: '+str(round(tempA,9))+', '+str(round(tempn,9))+', '+str(round(tempEa,9))+'\n') f.write('Reaction '+str(i)+' Modified: '+str(round(gas.reaction(i).rate.pre_exponential_factor,9))+', '+str(round(tempn,9))+', '+str(round(tempEa,9))+'\n') self.flame.solve(self.loglevel,refine_grid=False) temp_u_A=copy.deepcopy(self.flame.u[0]) #print(temp_u_A) if self.log_file: with open(self.log_name,'a') as f: f.write('Nominal u0: '+str(round(nominal_u,9))+'\n') f.write('Modified A'+str(i) +' u0: '+str(round(temp_u_A,9))+'\n') #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn*(1.0+self.dk),tempEa) #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn,tempEa) temp_r=gas.reactions()[i] dn=0.00136059 temp_r.rate=ct.Arrhenius(tempA,tempn+dn,tempEa) gas.modify_reaction(i,temp_r) self.flame.solve(self.loglevel,refine_grid=False) temp_u_n=copy.deepcopy(self.flame.u[0]) #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn,tempEa*(1.0+self.dk)) #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn,tempEa) temp_r=gas.reactions()[i] dEa=-14.9255*ct.gas_constant temp_r.rate=ct.Arrhenius(tempA,tempn,tempEa+dEa) gas.modify_reaction(i,temp_r) self.flame.solve(self.loglevel,refine_grid=False) temp_u_Ea=copy.deepcopy(self.flame.u[0]) tempChanges=np.array([temp_u_A,temp_u_n,temp_u_Ea]) nominals=nominal_u*np.ones(len(tempChanges)) nominal_df=pd.DataFrame(columns=['u0']) nominal_df['u0']=nominals tempChanges_df = pd.DataFrame(columns=['u0']) tempChanges_df['u0'] = tempChanges temp_sens=np.zeros(3) temp_sens[0]=self.sensitivityCalculation(float(nominal_df['u0'][0]),float(tempChanges_df['u0'][0]),self.dk) temp_sens[1]=self.sensitivityCalculation(float(nominal_df['u0'][1]),float(tempChanges_df['u0'][1]),dn) temp_sens[2]=self.sensitivityCalculation(float(nominal_df['u0'][2]),float(tempChanges_df['u0'][2]),dEa) sensdict['Reaction '+str(i)]=temp_sens #gas.reaction(i).rate=ct.Arrhenius(tempA,tempn, tempEa) temp_r=gas.reactions()[i] temp_r.rate=ct.Arrhenius(tempA,tempn,tempEa) gas.modify_reaction(i,temp_r) elif equation_type=='FalloffReaction': print('Solving flame speed sensitivity with respect to Arrhenius parameters for reaction '+str(i)) tempAl=copy.deepcopy(gas.reaction(i).low_rate.pre_exponential_factor) tempnl=copy.deepcopy(gas.reaction(i).low_rate.temperature_exponent) tempEal=copy.deepcopy(gas.reaction(i).low_rate.activation_energy) tempAh=copy.deepcopy(gas.reaction(i).high_rate.pre_exponential_factor) tempnh=copy.deepcopy(gas.reaction(i).high_rate.temperature_exponent) tempEah=copy.deepcopy(gas.reaction(i).high_rate.activation_energy) temp_r=gas.reactions()[i] temp_r.low_rate=ct.Arrhenius(tempAl*(1.0+self.dk),tempnl,tempEal) temp_r.high_rate=ct.Arrhenius(tempAh*(1.0+self.dk),tempnh,tempEah) gas.modify_reaction(i,temp_r) #self.flame.gas.reaction(i).low_rate=ct.Arrhenius(tempAl*(1.0+self.dk),tempnl,tempEal) #self.flame.gas.reaction(i).high_rate=ct.Arrhenius(tempAh*(1.0+self.dk),tempnh,tempEah) self.flame.solve(self.loglevel,refine_grid=False) temp_u_A=copy.deepcopy(self.flame.u[0]) temp_r=gas.reactions()[i] dn=0.00136059 temp_r.low_rate=ct.Arrhenius(tempAl,tempnl+dn,tempEal) temp_r.high_rate=ct.Arrhenius(tempAh,tempnh+dn,tempEah) gas.modify_reaction(i,temp_r) #self.flame.gas.reaction(i).low_rate=ct.Arrhenius(tempAl,tempnl*(1.0+self.dk),tempEal) #self.flame.gas.reaction(i).high_rate=ct.Arrhenius(tempAh,tempnh*(1.0+self.dk),tempEah) self.flame.solve(self.loglevel,refine_grid=False) temp_u_n=copy.deepcopy(self.flame.u[0]) temp_r=gas.reactions()[i] dEa=-14.9255*ct.gas_constant temp_r.low_rate=ct.Arrhenius(tempAl,tempnl,tempEal+dEa) temp_r.high_rate=ct.Arrhenius(tempAh,tempnh,tempEah+dEa) gas.modify_reaction(i,temp_r) #self.flame.gas.reaction(i).low_rate=ct.Arrhenius(tempAl,tempnl,tempEal*(1.0+self.dk)) #self.flame.gas.reaction(i).high_rate=ct.Arrhenius(tempAh,tempnh,tempEah*(1.0+self.dk)) self.flame.solve(self.loglevel,refine_grid=False) temp_u_Ea=copy.deepcopy(self.flame.u[0]) tempChanges=np.array([temp_u_A,temp_u_n,temp_u_Ea]) nominals=nominal_u*np.ones(len(tempChanges)) nominal_df=pd.DataFrame(columns=['u0']) nominal_df['u0']=nominals tempChanges_df = pd.DataFrame(columns=['u0']) tempChanges_df['u0'] = tempChanges temp_sens=np.zeros(3) temp_sens[0]=self.sensitivityCalculation(float(nominal_df['u0'][0]),float(tempChanges_df['u0'][0]),self.dk) temp_sens[1]=self.sensitivityCalculation(float(nominal_df['u0'][1]),float(tempChanges_df['u0'][1]),dn) temp_sens[2]=self.sensitivityCalculation(float(nominal_df['u0'][2]),float(tempChanges_df['u0'][2]),dEa) sensdict['Reaction '+str(i)]=temp_sens temp_r=gas.reactions()[i] temp_r.low_rate=ct.Arrhenius(tempAl,tempnl,tempEal) temp_r.high_rate=ct.Arrhenius(tempAh,tempnh,tempEah) gas.modify_reaction(i,temp_r) #self.flame.gas.reaction(i).low_rate=ct.Arrhenius(tempAl,tempnl, tempEal) #self.flame.gas.reaction(i).high_rate=ct.Arrhenius(tempAh,tempnh, tempEah) elif equation_type=='ChebyshevReaction': #print('Chebyshev sensitivities not yet installed') current_array=copy.deepcopy(gas.reaction(i).coeffs) temp_u=np.zeros(np.shape(current_array)) sens=np.zeros(np.shape(current_array)) temp_gas=ct.Solution(self.processor.cti_path) #temp_gas.TPX=gas.TPX #temp_gas.TP=1500,gas.P #temp_range=np.linspace(gas.reactions()[i].Tmin,gas.reactions()[i].Tmax,len(gas.reactions()[i].coeffs[:,0])+1) temp_range=np.linspace(gas.reactions()[i].Tmin,gas.reactions()[i].Tmax,len(gas.reactions()[i].coeffs[:,0])) #midpoints=np.zeros(len(temp_range)-1) midpoints=copy.deepcopy(temp_range) midpoints[0]=(temp_range[0]+temp_range[1])/2 midpoints[-1]=(temp_range[-1]+temp_range[-2])/2 #for j,T in enumerate(midpoints): #midpoints[j]=(temp_range[j]+temp_range[j+1])/2.0 for m in range(len(current_array[:,0])): for k in range(len(current_array[0,:])): gas.TPX=self.TPX temp_gas.TPX=gas.TPX temp_gas.TP=midpoints[m],gas.P current_rate=temp_gas.forward_rate_constants[i] modified_rate=1.01*current_rate print('Solving Chebyshev parameter sensitivity ['+str(m)+', '+str(k)+' for reaction ' +str(i)) print(temp_gas.TP) temp_r=temp_gas.reactions()[i] args=(i,m,k,temp_gas,modified_rate,current_array) da=scipy.optimize.fsolve(chebyshev_zeros,current_array[m,k],args=args) gas.TPX=self.TPX print('Delta alpha '+str(m)+', '+str(k)+'= '+str(da)) #temp_r.coeffs=current_array temp_r.set_parameters(temp_r.Tmin,temp_r.Tmax,temp_r.Pmin,temp_r.Pmax,current_array) temp_current_array=copy.deepcopy(current_array) temp_current_array[m,k]=current_array[m,k]+da temp_r.set_parameters(temp_r.Tmin,temp_r.Tmax,temp_r.Pmin,temp_r.Pmax,temp_current_array) gas.modify_reaction(i,temp_r) self.flame.solve(self.loglevel,refine_grid=True) temp_u[m,k]=copy.deepcopy(self.flame.u[0]) nominals=nominal_u*np.ones(np.shape(current_array)) sens[m,k]=self.sensitivityCalculation(nominals[m,k],temp_u[m,k],da) temp_r=gas.reactions()[i] temp_r.set_parameters(temp_r.Tmin,temp_r.Tmax,temp_r.Pmin,temp_r.Pmax,current_array) gas.modify_reaction(i,temp_r) sensdict['Reaction '+str(i)]=sens self.fsens=sensdict if self.kineticSens==1 and re.match('[Ff]lame [Ss]peed',self.flametype): #numpyMatrixsksens = [dfs[dataframe].values for dataframe in range(len(dfs))] #self.kineticSensitivities = np.dstack(numpyMatrixsksens) #print(np.shape(self.kineticSensitivities)) #self.solution=data return (self.solution,self.fsens) elif self.kineticSens==1 and re.match('[Aa]diabatic [Ff]lame',self.flametype): dfs = [pd.DataFrame() for x in range(len(self.observables))] #print((pd.DataFrame(sens[0,:])).transpose()) #test=pd.concat([pd.DataFrame(),pd.DataFrame(sens[0,:]).transpose()]) #print(test) #for k in range(len(self.observables)): #dfs[k] = dfs[k].append(((pd.DataFrame(sens[k,:])).transpose()),ignore_index=True) #dfs[k]=pd.concat([dfs[k],pd.DataFrame(sens[k,:]).transpose()]) #dfs[k]=pd.DataFrame(sens[k,:]).transpose() #print(dfs) numpyMatrixsksens = [dfs[dataframe].values for dataframe in range(len(dfs))] self.kineticSensitivities = np.dstack(numpyMatrixsksens) #print(np.shape(self.kineticSensitivities)) #self.solution=data return (self.solution,self.kineticSensitivities) elif self.kineticSens==0: #numpyMatrixsksens = [dfs[dataframe].values for dataframe in range(len(dfs))] return (self.solution,[]) else: #self.solution=data return (self.solution,[])
class TestElementary(utilities.CanteraTest): _cls = ct.ElementaryReaction _equation = 'H2 + O <=> H + OH' _rate = {'A': 38.7, 'b': 2.7, 'Ea': 2.619184e+07} _rate_obj = ct.Arrhenius(38.7, 2.7, 2.619184e+07) _index = 2 _type = "elementary" @classmethod def setUpClass(cls): utilities.CanteraTest.setUpClass() cls.gas = ct.Solution('h2o2.xml') cls.gas.X = 'H2:0.1, H2O:0.2, O2:0.7, O:1e-4, OH:1e-5, H:2e-5' cls.gas.TP = 900, 2*ct.one_atm cls.species = ct.Species.listFromFile('h2o2.xml') def check_rxn(self, rxn): ix = self._index self.assertEqual(rxn.reaction_type, self._type) self.assertNear(rxn.rate(self.gas.T), self.gas.forward_rate_constants[ix]) self.assertEqual(rxn.reactants, self.gas.reaction(ix).reactants) self.assertEqual(rxn.products, self.gas.reaction(ix).products) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=self.species, reactions=[rxn]) gas2.TPX = self.gas.TPX self.check_sol(gas2) def check_sol(self, gas2): ix = self._index self.assertEqual(gas2.reaction_type_str(0), self._type) self.assertNear(gas2.forward_rate_constants[0], self.gas.forward_rate_constants[ix]) self.assertNear(gas2.net_rates_of_progress[0], self.gas.net_rates_of_progress[ix]) def test_rate(self): self.assertNear(self._rate_obj(self.gas.T), self.gas.forward_rate_constants[self._index]) def test_from_parts(self): orig = self.gas.reaction(self._index) rxn = self._cls(orig.reactants, orig.products) rxn.rate = self._rate_obj self.check_rxn(rxn) def test_from_dict(self): rxn = self._cls(equation=self._equation, rate=self._rate, kinetics=self.gas) self.check_rxn(rxn) def test_from_rate(self): rxn = self._cls(equation=self._equation, rate=self._rate_obj, kinetics=self.gas) self.check_rxn(rxn) def test_add_rxn(self): gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=self.species, reactions=[]) gas2.TPX = self.gas.TPX rxn = self._cls(equation=self._equation, rate=self._rate_obj, kinetics=self.gas) gas2.add_reaction(rxn) self.check_sol(gas2) def test_wrong_rate(self): with self.assertRaises(TypeError): rxn = self._cls(equation=self._equation, rate=[], kinetics=self.gas) def test_no_rate(self): rxn = self._cls(equation=self._equation, kinetics=self.gas) self.assertNear(rxn.rate(self.gas.T), 0.) gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=self.species, reactions=[rxn]) gas2.TPX = self.gas.TPX self.assertNear(gas2.forward_rate_constants[0], 0.) self.assertNear(gas2.net_rates_of_progress[0], 0.) def test_replace_rate(self): rxn = self._cls(equation=self._equation, kinetics=self.gas) rxn.rate = self._rate_obj self.check_rxn(rxn)
def cti_write2(x={}, original_cti='', master_rxns='', master_index=[], MP={}, working_directory='', file_name=''): #print(MP) print(bool(x)) if not original_cti: raise Exception( 'Please provide a name for the original mechanism file and try again.' ) if not master_rxns and np.any(master_index): raise Exception( 'Please provide a mechanism file for reactions analysed with master equation or leave master_index empty' ) if master_rxns and not np.any(master_index): raise Exception( 'Please provide master_index, a non-empty list of reaction numbers from original file which are analysed with master equation.' ) if not master_rxns and not master_index: master_index = np.ones(ct.Solution(original_cti).n_reactions, dtype=bool) elif master_rxns and np.any(master_index): temp = np.ones(ct.Solution(original_cti).n_reactions, dtype=bool) for j in np.arange(len(master_index)): temp[master_index[j] - 1] = False master_index = temp lineList = [] with open(original_cti) as f: lineList = f.readlines() done = False count = 0 while not done or count < len(lineList): if 'Reaction data' in lineList[count] or 'Reaction Data' in lineList[ count] or 'reaction data' in lineList[count]: done = True lineList = lineList[0:count - 1] else: count += 1 with open('tempcti.cti', 'w') as p: p.writelines(lineList) NewModel = ct.Solution('tempcti.cti') original_mechanism = ct.Solution(original_cti) original_rxn_count = 0 master_rxn_eqs = [] if master_rxns: with open(master_rxns) as f: reactionsList = f.readlines() lineList = lineList + reactionsList with open('masterTemp.cti', 'w') as f: f.writelines(lineList) master_reactions = ct.Solution('masterTemp.cti') master_rxn_eqs = master_reactions.reaction_equations() original_rxn_eqs = [] for i in np.arange(original_mechanism.n_reactions): if master_index[i]: NewModel.add_reaction(original_mechanism.reaction(i)) original_rxn_count += 1 original_rxn_eqs.append(original_mechanism.reaction_equation(i)) # if 'FalloffReaction' in str(type(original_mechanism.reaction(i))): # print(original_mechanism.reaction(i).high_rate) # print(original_mechanism.reaction(i).low_rate) if master_rxns: for i in np.arange(master_reactions.n_reactions): # print(master_reactions.reaction(i).rate) NewModel.add_reaction(master_reactions.reaction(i)) #print(master_reactions.reaction(0).rate) if x == {}: for j in np.arange(original_rxn_count - 1): #if master_index[j]: #print(str(type(original_mechanism.reaction(j))),str(type(NewModel.reaction(j)))) if 'ThreeBodyReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'ElementaryReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'FalloffReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction(j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction(j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction(j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction(j).falloff elif 'ChemicallyActivatedReaction' in str( type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction(j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction(j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction(j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction(j).falloff elif 'PlogReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rates = NewModel.reaction(j).rates elif 'ChebyshevReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).set_parameters( NewModel.reaction(j).Tmin, NewModel.reaction(j).Tmax, NewModel.reaction(j).Pmin, NewModel.reaction(j).Pmax, NewModel.reaction(j).coeffs) #Rinv = 1/R #cal/mol*K E = 1 #going test for energy #T = 4184 #T= 4.186e3 T = ct.gas_constant if x != {}: for j in np.arange(original_rxn_count - 1): #if master_index[j]: try: if 'ThreeBodyReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).rate.pre_exponential_factor n = NewModel.reaction(j).rate.temperature_exponent Ea = NewModel.reaction(j).rate.activation_energy NewModel.reaction(j).rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) elif 'ElementaryReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).rate.pre_exponential_factor n = NewModel.reaction(j).rate.temperature_exponent Ea = NewModel.reaction(j).rate.activation_energy NewModel.reaction(j).rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) elif 'FalloffReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).high_rate.pre_exponential_factor n = NewModel.reaction(j).high_rate.temperature_exponent Ea = NewModel.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) A = NewModel.reaction(j).low_rate.pre_exponential_factor n = NewModel.reaction(j).low_rate.temperature_exponent Ea = NewModel.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'ChemicallyActivatedReaction' in str( type(NewModel.reaction(j))): A = NewModel.reaction(j).high_rate.pre_exponential_factor n = NewModel.reaction(j).high_rate.temperature_exponent Ea = NewModel.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) A = NewModel.reaction(j).low_rate.pre_exponential_factor n = NewModel.reaction(j).low_rate.temperature_exponent Ea = NewModel.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'PlogReaction' in str(type(NewModel.reaction(j))): for number, reactions in enumerate( NewModel.reaction(j).rates): A = NewModel.reaction( j)[number][1].pre_exponential_factor n = NewModel.reaction( j)[number][1].temperature_exponent Ea = NewModel.reaction(j)[number][1].activation_energy NewModel.reaction(j)[number][1] = ct.Arrhenius( A * np.exp(x['r' + str(j)]['A']), n + x['r' + str(j)]['n'], Ea + x['r' + str(j)]['Ea'] * T) NewModel.reaction(j).rates = NewModel.reaction(j).rates elif 'ChebyshevReaction' in str( type(original_mechanism.reaction(j))): NewModel.reaction(j).set_parameters( NewModel.reaction(j).Tmin, NewModel.reaction(j).Tmax, NewModel.reaction(j).Pmin, NewModel.reaction(j).Pmax, NewModel.reaction(j).coeffs) except: #print ('we are in the except statment in marks code',j) if 'ThreeBodyReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'ElementaryReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'FalloffReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction( j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction( j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'ChemicallyActivatedReaction' in str( type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction( j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction( j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'PlogReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rates = NewModel.reaction(j).rates elif 'ChebyshevReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).set_parameters( NewModel.reaction(j).Tmin, NewModel.reaction(j).Tmax, NewModel.reaction(j).Pmin, NewModel.reaction(j).Pmax, NewModel.reaction(j).coeffs) if MP != {}: print('insdie the MP if statment') for j in np.arange(original_rxn_count, NewModel.n_reactions): try: if 'ThreeBodyReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).rate.pre_exponential_factor n = NewModel.reaction(j).rate.temperature_exponent Ea = NewModel.reaction(j).rate.activation_energy NewModel.reaction(j).rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) elif 'ElementaryReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).rate.pre_exponential_factor n = NewModel.reaction(j).rate.temperature_exponent Ea = NewModel.reaction(j).rate.activation_energy NewModel.reaction(j).rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) elif 'FalloffReaction' in str(type(NewModel.reaction(j))): A = NewModel.reaction(j).high_rate.pre_exponential_factor n = NewModel.reaction(j).high_rate.temperature_exponent Ea = NewModel.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) A = NewModel.reaction(j).low_rate.pre_exponential_factor n = NewModel.reaction(j).low_rate.temperature_exponent Ea = NewModel.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'ChemicallyActivatedReaction' in str( type(NewModel.reaction(j))): A = NewModel.reaction(j).high_rate.pre_exponential_factor n = NewModel.reaction(j).high_rate.temperature_exponent Ea = NewModel.reaction(j).high_rate.activation_energy NewModel.reaction(j).high_rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) A = NewModel.reaction(j).low_rate.pre_exponential_factor n = NewModel.reaction(j).low_rate.temperature_exponent Ea = NewModel.reaction(j).low_rate.activation_energy NewModel.reaction(j).low_rate = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'PlogReaction' in str(type(NewModel.reaction(j))): for number, reactions in enumerate( NewModel.reaction(j).rates): A = NewModel.reaction( j)[number][1].pre_exponential_factor n = NewModel.reaction( j)[number][1].temperature_exponent Ea = NewModel.reaction(j)[number][1].activation_energy NewModel.reaction(j)[number][1] = ct.Arrhenius( A * np.exp(MP['r' + str(j)]['A']), n + MP['r' + str(j)]['n'], Ea + MP['r' + str(j)]['Ea'] * E) NewModel.reaction(j).rates = NewModel.reaction(j).rates elif 'ChebyshevReaction' in str( type(original_mechanism.reaction(j))): NewModel.reaction(j).set_parameters( NewModel.reaction(j).Tmin, NewModel.reaction(j).Tmax, NewModel.reaction(j).Pmin, NewModel.reaction(j).Pmax, NewModel.reaction(j).coeffs) except: print('we are in the except statment in marks code', j) if 'ThreeBodyReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'ElementaryReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rate = NewModel.reaction(j).rate elif 'FalloffReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction( j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction( j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'ChemicallyActivatedReaction' in str( type(NewModel.reaction(j))): NewModel.reaction(j).high_rate = NewModel.reaction( j).high_rate NewModel.reaction(j).low_rate = NewModel.reaction( j).low_rate if NewModel.reaction(j).falloff.type == 'Troe': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff if NewModel.reaction(j).falloff.type == 'Sri': NewModel.reaction(j).falloff = NewModel.reaction( j).falloff elif 'PlogReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).rates = NewModel.reaction(j).rates elif 'ChebyshevReaction' in str(type(NewModel.reaction(j))): NewModel.reaction(j).set_parameters( NewModel.reaction(j).Tmin, NewModel.reaction(j).Tmax, NewModel.reaction(j).Pmin, NewModel.reaction(j).Pmax, NewModel.reaction(j).coeffs) new_file = ctiw.write(NewModel, cwd=working_directory, file_name=file_name, original_cti=original_cti) #tab return new_file, original_rxn_eqs, master_rxn_eqs
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])