def test_modify_thermo_invalid(self): S = {sp.name: sp for sp in ct.Species.listFromFile('h2o2.xml')} orig = S['H2'] thermo = orig.thermo copy = ct.Species('foobar', orig.composition) copy.thermo = thermo with self.assertRaises(ct.CanteraError): self.gas.modify_species(self.gas.species_index('H2'), copy) copy = ct.Species('H2', {'H': 3}) copy.thermo = thermo with self.assertRaises(ct.CanteraError): self.gas.modify_species(self.gas.species_index('H2'), copy) copy = ct.Species('H2', orig.composition) copy.thermo = ct.ConstantCp(thermo.min_temp, thermo.max_temp, thermo.reference_pressure, [300, 123, 456, 789]) with self.assertRaises(ct.CanteraError): self.gas.modify_species(self.gas.species_index('H2'), copy) copy = ct.Species('H2', orig.composition) copy.thermo = ct.NasaPoly2(thermo.min_temp + 200, thermo.max_temp, thermo.reference_pressure, thermo.coeffs) with self.assertRaises(ct.CanteraError): self.gas.modify_species(self.gas.species_index('H2'), copy)
def modify_thermo( self, multipliers): # Only works for NasaPoly2 (NASA 7) currently for i in range(np.shape(self.gas.species_names)[0]): S_initial = self.gas.species(i) S = self.gas.species(i) if type(S.thermo) is ct.NasaPoly2: # Get current values T_low = S_initial.thermo.min_temp T_high = S_initial.thermo.max_temp P_ref = S_initial.thermo.reference_pressure coeffs = S_initial.thermo.coeffs # Update thermo properties coeffs[1:] *= multipliers[i] S.thermo = ct.NasaPoly2(T_low, T_high, P_ref, coeffs) # elif type(S.thermo) is ct.ShomatePoly2: continue # elif type(S.thermo) is ct.NasaPoly1: continue # elif type(S.thermo) is ct.Nasa9PolyMultiTempRegion: continue # elif type(S.thermo) is ct.Nasa9Poly1: continue # elif type(S.thermo) is ct.ShomatePoly: continue else: print("{:.s}'s thermo is type: {:s}".format( self.gas.species_names[i], type(S.thermo))) continue self.gas.modify_species(i, S)
def test_create(self): st = ct.NasaPoly2(300, 3500, 101325, self.h2o_coeffs) for T in [300, 500, 900, 1200, 2000]: self.gas.TP = T, 101325 self.assertNear(st.cp(T), self.gas.cp_mole) self.assertNear(st.h(T), self.gas.enthalpy_mole) self.assertNear(st.s(T), self.gas.entropy_mole)
def test_yaml_inconsistent_species(self): gas = ct.Solution('h2o2.yaml', transport_model=None) gas2 = ct.Solution('h2o2.yaml', transport_model=None) gas2.name = 'modified' # modify the NASA coefficients for one species h2 = gas2.species('H2') nasa_coeffs = h2.thermo.coeffs nasa_coeffs[1] += 0.1 nasa_coeffs[8] += 0.1 h2.thermo = ct.NasaPoly2(h2.thermo.min_temp, h2.thermo.max_temp, h2.thermo.reference_pressure, nasa_coeffs) gas2.modify_species(gas2.species_index('H2'), h2) with self.assertRaisesRegex(ct.CanteraError, "different definitions"): gas.write_yaml('h2o2-error.yaml', phases=gas2)
def change_species_enthalpy(gas, species_name, dH): """ Find the species by name and change it's enthalpy by dH (in J/kmol) """ index = gas.species_index(species_name) species = gas.species(index) # dx is in fact (delta H / R). Note that R in cantera is 8314.462 J/kmol/K dx = dH / ct.gas_constant perturbed_coeffs = species.thermo.coeffs.copy() perturbed_coeffs[6] += dx perturbed_coeffs[13] += dx species.thermo = ct.NasaPoly2(species.thermo.min_temp, species.thermo.max_temp, species.thermo.reference_pressure, perturbed_coeffs) gas.modify_species(index, species)
def calc_tig(self, species, dH): gas, r, net = self.setup_ignition_delay() S = gas.species(species) st = S.thermo coeffs = st.coeffs coeffs[[6, 13]] += dH / ct.gas_constant snew = ct.NasaPoly2(st.min_temp, st.max_temp, st.reference_pressure, coeffs) S.thermo = snew gas.modify_species(gas.species_index(species), S) t = [] T = [] while net.time < 0.6: t.append(net.time) T.append(r.thermo.T) net.step() T = np.array(T) t = np.array(t) To = T[0] Tf = T[-1] return (t[-1]*T[-1] - np.trapz(T,t)) / (T[-1] - T[0])
def change_species_enthalpy(self, species_name, dH): """ Find the species by name and change it's enthlapy by dH (in J/kmol) """ phase, index = self.find_species_phase_index(species_name) species = phase.species(index) print(f"Initial H(298) = {species.thermo.h(298)/1e6:.1f} kJ/mol") dx = dH / ct.gas_constant # 'dx' is in fact (delta H / R). Note that R in cantera is 8314.462 J/kmol assert isinstance(species.thermo, ct.NasaPoly2) # print(species.thermo.coeffs) perturbed_coeffs = species.thermo.coeffs.copy() perturbed_coeffs[6] += dx perturbed_coeffs[13] += dx species.thermo = ct.NasaPoly2( species.thermo.min_temp, species.thermo.max_temp, species.thermo.reference_pressure, perturbed_coeffs, ) # print(species.thermo.coeffs) phase.modify_species(index, species) print(f"Modified H(298) = {species.thermo.h(298)/1e6:.1f} kJ/mol")
################################################################################ CO = ct.Species(name = 'CO') coeffs = np.zeros(15) coeffs[0] = T_mid coeffs[1:8] = [ 3.57953347E+00, -6.10353680E-04, 1.01681433E-06, 9.07005884E-10, -9.04424499E-13, 0.00000000E+00, 3.50840928E+00] coeffs[8:15] = [ 2.71518561E+00, 2.06252743E-03, -9.98825771E-07, 2.30053008E-10, -2.03647716E-14, 1.92213599E+02, 7.81868772E+00] CO.thermo = ct.NasaPoly2(T_low = T_low , T_high = T_high , P_ref = P_ref , coeffs = coeffs ) ################################################################################ # N2 ################################################################################ N2 = ct.Species(name = 'N2') coeffs = np.zeros(15) coeffs[0] = T_mid coeffs[1:8] = [ 3.29867700E+00, 1.40823990E-03, -3.96322180E-06, 5.64151480E-09, -2.44485400E-12, 0.00000000E+00, 3.95037200E+00] coeffs[8:15] = [ 2.92663788E+00, 1.48797700E-03, -5.68476030E-07,
def test_coeffs(self): st = ct.NasaPoly2(300, 3500, 101325, self.h2o_coeffs) self.assertEqual(st.min_temp, 300) self.assertEqual(st.max_temp, 3500) self.assertEqual(st.reference_pressure, 101325) self.assertArrayNear(self.h2o_coeffs, st.coeffs)
def test_invalid(self): with self.assertRaises(ValueError): # not enough coefficients st = ct.NasaPoly2(300, 3500, 101325, [1000.0, 3.03399249E+00, 2.17691804E-03])
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)
theta = theta_opt Rxn1 = pt_s_ca.reaction(0) if tog == 1: i_o = a * w_Pt + b else: i_o = i_o_opt Rxn1.rate = ct.Arrhenius(i_o, 0, 0) pt_s_ca.modify_reaction(0, Rxn1) O2 = naf_b_ca.species(naf_b_ca.species_index('O2(Naf)')) O2_thermo = O2.thermo.coeffs O2_thermo[[1, 8]] = np.array( [3.28253784 + offset_opt, 3.782456360 + offset_opt]) O2.thermo = ct.NasaPoly2(200, 3500, ct.one_atm, fuel_coeffs) naf_b_ca.modify_species(naf_b_ca.species_index('O2(Naf)'), O2) # If running optimization w/ the 2-step reaction mechanism: elif all([optimize == 1, rxn_mech == '2s']): R_naf = R_naf_opt theta = theta_opt A = A_opt i_o = i_o_opt Rxn1 = pt_s_ca.reaction(0) Rxn2 = pt_s_ca.reaction(1) Rxn1.rate = ct.Arrhenius(A, 0, 0) Rxn2.rate = ct.Arrhenius(i_o, 0, 0) pt_s_ca.modify_reaction(0, Rxn1) pt_s_ca.modify_reaction(1, Rxn2)
ct.Species('C', 'O:1'), ct.Species('D', 'O:2'), ct.Species('E', 'H:1, O:2'), ct.Species('N', 'H:1, O:1') ]) species_dict = dict({'const': list(), 'nasa7': list()}) for i, s in enumerate(species_decl): species_dict['const'].append(ct.Species(s.name, s.composition)) species_dict['const'][-1].thermo = ct.ConstantCp( 300., 3000., 101325., (300., 0., 0., float(i + 1) * 1.e4)) species_dict['nasa7'].append(ct.Species(s.name, s.composition)) coeffs = [ float(i + 1) * v for v in [1.e0, 1.e-2, 1.e-4, 1.e-6, 1.e-8, 1.e-10, 1.e-12] ] species_dict['nasa7'][-1].thermo = ct.NasaPoly2( 300., 3000., 101325., hstack([1200.] + coeffs + coeffs)) mechs = [('const', Mechanism.from_solution( ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species_dict['const'], reactions=[]))), ('nasa7', Mechanism.from_solution( ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species_dict['nasa7'], reactions=[])))] tolerance = 1.e-14