예제 #1
0
    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)
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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