def test_mechanism_simple_api_methods(self): try: xml = abspath(join('tests', 'test_mechanisms', 'h2-burke.xml')) sol = Solution(xml) m = ChemicalMechanismSpec.from_solution(sol) self.assertEqual(m.n_species, sol.n_species, 'ChemicalMechanismSpec.n_species vs ct.Solution.n_species') self.assertEqual(m.n_reactions, sol.n_reactions, 'ChemicalMechanismSpec.n_reactions vs ct.Solution.n_reactions') for i in range(m.n_species): self.assertEqual(m.species_names[i], sol.species_names[i], 'ChemicalMechanismSpec.species_name[i] vs ct.Solution.species_name[i]') for n in m.species_names: self.assertEqual(m.species_index(n), sol.species_index(n), 'ChemicalMechanismSpec.species_index(name) vs ct.Solution.species_index(name)') for i, n in enumerate(m.species_names): self.assertEqual(m.species_index(n), i, 'species names and indices are consistent, index vs i') self.assertEqual(n, m.species_names[i], 'species names and indices are consistent, name vs n') self.assertEqual(m.molecular_weight(i), m.molecular_weight(n), 'ChemicalMechanismSpec molecular_weight(name) vs molecular_weight(idx)') except: self.assertTrue(False) try: xml = abspath(join('tests', 'test_mechanisms', 'h2-burke.xml')) m = ChemicalMechanismSpec.from_solution(Solution(xml)) m.molecular_weight(list()) self.assertTrue(False) except: self.assertTrue(True)
def new_result_dict(sln: ct.Solution, species_list=None): """ Returns an empty result dictionary used for storing state variables during kinetic simulations :param sln: ct.Solution object to be used in the simulation :param species_list: list of species for which to record mole fractions; default None to record all species in mechansim :return dict: result dictionary with empty lists in fields for time, T, P, and all species, along with a list of all included species and another of the species indices within the sln.X array """ # if the species list is None, make entries for all the species in the Solution object if species_list is None: species_list = sln.species_names else: # remove any species in the list not in the Solution to prevent errors species_list_2, species_list = list(species_list), [ ] # store provided species_list as species_list_2, make a # new species list for storing valid species for sp in species_list_2: if sp in sln.species_names and sp not in species_list: species_list += [sp] elif sp not in sln.species_names: print(f"{sp} not in mechanism; removed from tracked species.") # start initializing the dictionary with basic properties - time, temperature (T), pressure (P) result_dict = {'time': [], 'T': [], 'P': []} # now add entries for the species for sp in species_list: result_dict[sp] = [] # finally, add entries with a list of the species and their indices result_dict['species'] = species_list result_dict['indices'] = [sln.species_index(sp) for sp in species_list] return result_dict
def equilibrium_constants_expr(sol: ct.Solution, react: ct.Reaction, gibbs_rt): indices_reac = [sol.species_index(sp) for sp in react.reactants] indices_prod = [sol.species_index(sp) for sp in react.products] # Stoichiometric coefficients nu_reac = [react.reactants[sp] for sp in react.reactants] nu_prod = [react.products[sp] for sp in react.products] sum_r = sum(nu_reac_i * gibbs_rt[indices_reac_i] for indices_reac_i, nu_reac_i in zip(indices_reac, nu_reac)) sum_p = sum(nu_prod_i * gibbs_rt[indices_prod_i] for indices_prod_i, nu_prod_i in zip(indices_prod, nu_prod)) # Check if reaction is termolecular sum_nu_net = sum(nu_prod) - sum(nu_reac) if sum_nu_net < 0: # Three species on reactants side return sum_p + p.Variable("C0") - sum_r elif sum_nu_net > 0: # Three species on products side return sum_p - (sum_r + p.Variable("C0")) else: return sum_p - sum_r
def get_kinetic_parameters_from_yaml( loaded_yaml: dict, gas: ct.Solution) -> Tuple[KineticsCoeffs, KineticsData]: """ Extract Arrhenius, Troe parameters, reaction type indices from loaded YAML file returns: tuple containing namedtuples of KineticCoeffs and KineticsData Adapted from https://github.com/DENG-MIT/reactorch/blob/master/reactorch/Solution.py """ reactions = defaultdict(list) efficiencies_coeffs = onp.ones((gas.n_species, gas.n_reactions)) reactant_stoich_coeffs = reactant_orders = gas.reactant_stoich_coeffs() arrhenius_coeffs = onp.zeros((gas.n_reactions, 3), dtype=onp.float64) arrhenius0_coeffs = onp.zeros((gas.n_reactions, 3), dtype=onp.float64) troe_coeffs = onp.zeros((gas.n_reactions, 4), dtype=onp.float64) is_reversible = onp.zeros(gas.n_reactions) three_body_indices, falloff_indices, troe_falloff_indices = list(), list( ), list() for i in range(gas.n_reactions): reactions[i] = {"equation": gas.reaction_equation(i)} reactions[i]["reactants"] = gas.reactants(i) reactions[i]["products"] = gas.products(i) reactions[i]["reaction_type"] = gas.reaction_type(i) if gas.is_reversible(i): is_reversible[i] = 1.0 if gas.reaction_type(i) in [1, 2]: reactions[i]["A"] = loaded_yaml["reactions"][i]["rate-constant"][ "A"] reactions[i]["b"] = loaded_yaml["reactions"][i]["rate-constant"][ "b"] if type(loaded_yaml["reactions"][i]["rate-constant"]["Ea"]) is str: Ea = onp.float64([ loaded_yaml["reactions"][i]["rate-constant"]["Ea"].split( " ")[0] ]) else: Ea = loaded_yaml["reactions"][i]["rate-constant"]["Ea"] reactions[i]["Ea"] = Ea if gas.reaction_type(i) in [2]: three_body_indices.append(i) if "efficiencies" in loaded_yaml["reactions"][i]: reactions[i]["efficiencies"] = loaded_yaml["reactions"][i][ "efficiencies"] for key, value in reactions[i]["efficiencies"].items(): efficiencies_coeffs[gas.species_index(key), i] = value if gas.reaction_type(i) in [4]: if "efficiencies" in loaded_yaml["reactions"][i]: reactions[i]["efficiencies"] = loaded_yaml["reactions"][i][ "efficiencies"] for key, value in reactions[i]["efficiencies"].items(): efficiencies_coeffs[gas.species_index(key), i] = value high_p = loaded_yaml["reactions"][i]["high-P-rate-constant"] low_p = loaded_yaml["reactions"][i]["low-P-rate-constant"] reactions[i]["A"] = high_p["A"] reactions[i]["b"] = high_p["b"] if type(high_p["Ea"]) is str: high_Ea = onp.float64([high_p["Ea"].split(" ")[0]]) else: high_Ea = high_p["Ea"] reactions[i]["Ea"] = high_Ea reactions[i]["A_0"] = low_p["A"] reactions[i]["b_0"] = low_p["b"] if type(low_p["Ea"]) is str: low_Ea = onp.float64([low_p["Ea"].split(" ")[0]]) else: low_Ea = low_p["Ea"] reactions[i]["Ea_0"] = low_Ea if "Troe" in loaded_yaml["reactions"][i]: troe_falloff_indices.append(i) Troe = loaded_yaml["reactions"][i]["Troe"] if "T2" in loaded_yaml["reactions"][i]["Troe"]: reactions[i]["Troe"] = { "A": Troe["A"], "T1": Troe["T1"], "T2": Troe["T2"], "T3": Troe["T3"], } troe_coeffs[i, 0] = Troe["A"] troe_coeffs[i, 1] = Troe["T1"] troe_coeffs[i, 2] = Troe["T2"] troe_coeffs[i, 3] = Troe["T3"] else: reactions[i]["Troe"] = { "A": Troe["A"], "T1": Troe["T1"], "T3": Troe["T3"], } troe_coeffs[i, 0] = Troe["A"] troe_coeffs[i, 1] = Troe["T1"] troe_coeffs[i, 2] = 0.0 troe_coeffs[i, 3] = Troe["T3"] else: falloff_indices.append(i) if "orders" in loaded_yaml["reactions"][i]: for key, value in loaded_yaml["reactions"][i]["orders"].items(): reactant_orders[gas.species_index(key), i] = value if "units" in loaded_yaml: if (loaded_yaml["units"]["length"] == "cm" and loaded_yaml["units"]["quantity"] == "mol"): reactions[i]["A"] *= (1e-3)**( reactant_stoich_coeffs[:, i].sum() - 1) if gas.reaction_type(i) in [2]: reactions[i]["A"] *= 1e-3 if gas.reaction_type(i) in [4]: reactions[i]["A_0"] *= 1e-3 reactions[i]["A_0"] *= (1e-3)**( reactant_stoich_coeffs[:, i].sum() - 1) arrhenius0_coeffs[i, 0] = reactions[i]["A_0"] arrhenius0_coeffs[i, 1] = reactions[i]["b_0"] arrhenius0_coeffs[i, 2] = reactions[i]["Ea_0"] arrhenius_coeffs[i, 0] = reactions[i]["A"] arrhenius_coeffs[i, 1] = reactions[i]["b"] arrhenius_coeffs[i, 2] = reactions[i]["Ea"] kinetics_coeffs = KineticsCoeffs( arrhenius_coeffs=np.array(arrhenius_coeffs, dtype=np.float64), arrhenius0_coeffs=np.array(arrhenius0_coeffs, dtype=np.float64), troe_coeffs=np.array(troe_coeffs, dtype=np.float64), efficiency_coeffs=np.array(efficiencies_coeffs, dtype=np.float64), ) kinetics_data = KineticsData( three_body_indices=np.array(three_body_indices, dtype=np.int64), falloff_indices=np.array(falloff_indices, dtype=np.int64), troe_falloff_indices=np.array(troe_falloff_indices, dtype=np.int64), is_reversible=np.array(is_reversible, dtype=np.int64), ) return kinetics_coeffs, kinetics_data