Exemplo n.º 1
0
    def toCantera(self, useChemkinIdentifier = False):
        """
        Converts the RMG Species object to a Cantera Species object
        with the appropriate thermo data.

        If useChemkinIdentifier is set to False, the species label is used
        instead. Be sure that species' labels are unique when setting it False.
        """
        import cantera as ct
        
        # Determine the number of each type of element in the molecule
        elementDict = {} # elementCounts = [0,0,0,0]
        for atom in self.molecule[0].atoms:
            # The atom itself
            symbol = atom.element.symbol
            if symbol not in elementDict:
                elementDict[symbol] = 1
            else:
                elementDict[symbol] += 1
        if useChemkinIdentifier:
            ctSpecies = ct.Species(self.toChemkin(), elementDict)
        else:
            ctSpecies = ct.Species(self.label, elementDict)
        if self.thermo:
            try:
                ctSpecies.thermo = self.thermo.toCantera()
            except Exception:
                logging.error('Could not convert thermo to create Cantera Species object. Check that thermo is a NASA polynomial.')
                raise
        
        if self.transportData:
            ctSpecies.transport = self.transportData.toCantera()
            
        return ctSpecies
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    def test_qss_artificial(self):
        """Test using four species artificial model with QSS species from 2006 DRG paper.

        # R \approx F / 1e3
        """
        R1 = ct.Reaction.fromCti('''reaction('F => R', [1.0, 0.0, 0.0])''')
        R2 = ct.Reaction.fromCti('''reaction('R => P', [1.0e3, 0.0, 0.0])''')
        R3 = ct.Reaction.fromCti('''reaction('R => Pp', [1.0, 0.0, 0.0])''')

        F = ct.Species('F', 'H:1')
        R = ct.Species('R', 'H:1')
        P = ct.Species('P', 'H:1')
        Pp = ct.Species('Pp', 'H:1')
        for sp in [F, R, P, Pp]:
            sp.thermo = ct.ConstantCp(300, 1000, 101325, (300, 1.0, 1.0, 1.0))
        model = ct.Solution(thermo='IdealGas',
                            kinetics='GasKinetics',
                            species=[F, R, P, Pp],
                            reactions=[R1, R2, R3])
        state = 1000, ct.one_atm, [1., 1. / 1.e3, 0., 0.]
        matrix = create_drg_matrix(state, model)

        correct = np.array([[0, 1.0, 0, 0], [0.5, 0, 0.5, 0.5 * 1e-3],
                            [0, 1.0, 0, 0], [0, 1, 0, 0]])
        assert np.allclose(correct, matrix, rtol=1e-3)
Exemplo n.º 4
0
    def test_pe_artificial(self):
        """Test using three species artificial model with PE reactions from 2006 DRG paper.
        """
        R1 = ct.Reaction.fromCti('''reaction('F <=> R', [1.0e3, 0.0, 0.0])''')
        R2 = ct.Reaction.fromCti('''reaction('R <=> P', [1.0, 0.0, 0.0])''')

        F = ct.Species('F', 'H:1')
        R = ct.Species('R', 'H:1')
        P = ct.Species('P', 'H:1')

        for sp in [F, R, P]:
            sp.thermo = ct.ConstantCp(300, 1000, 101325, (300, 1.0, 1.0, 1.0))
        model = ct.Solution(thermo='IdealGas',
                            kinetics='GasKinetics',
                            species=[F, R, P],
                            reactions=[R1, R2])
        conc_R = 0.1
        conc_F = ((1 + 1e-3) * conc_R - (1 / 2e3)) / (1 - (1 / 2e3))
        conc_P = 1.0 - (conc_R + conc_F)
        state = 1000, ct.one_atm, [conc_F, conc_R, conc_P]
        matrix = create_drg_matrix(state, model)

        correct = np.array([
            [0, 1.0, 0],
            [1. / 3., 0, 2. / 3.],
            [0, 1.0, 0],
        ])
        assert np.allclose(correct, matrix, rtol=1e-3)
Exemplo n.º 5
0
    def test_defaults(self):
        s = ct.Species('H2')
        self.assertEqual(s.size, 1.0)
        self.assertEqual(s.charge, 0.0)

        self.assertIsNone(s.thermo)
        self.assertIsNone(s.transport)
Exemplo n.º 6
0
    def toCantera(self, speciesList=[]):
        """
        Converts the RMG Species object to a Cantera Species object
        with the appropriate thermo data.
        """
        import cantera as ct

        # Determine the number of each type of element in the molecule
        elementDict = {}  # elementCounts = [0,0,0,0]
        for atom in self.molecule[0].atoms:
            # The atom itself
            symbol = atom.element.symbol
            if symbol not in elementDict:
                elementDict[symbol] = 1
            else:
                elementDict[symbol] += 1

        ctSpecies = ct.Species(self.toChemkin(), elementDict)
        if self.thermo:
            try:
                ctSpecies.thermo = self.thermo.toCantera()
            except Exception, e:
                print e
                raise Exception(
                    'Could not convert thermo to create Cantera Species object. Check that thermo is a NASA polynomial.'
                )
Exemplo n.º 7
0
    def test_standalone(self):
        s = ct.Species('CH4', {'C': 1, 'H': 4})

        self.assertEqual(s.name, 'CH4')
        c = s.composition
        self.assertEqual(len(c), 2)
        self.assertEqual(c['C'], 1)
        self.assertEqual(c['H'], 4)
Exemplo n.º 8
0
    def test_dormant_modes(self):
        """Test using three species artificial model with dormant modes from 2006 DRG paper.
        """
        R1 = ct.Reaction.fromCti('''reaction('A <=> B', [1.0, 0.0, 0.0])''')
        R2 = ct.Reaction.fromCti('''reaction('B <=> C', [1.0e-3, 0.0, 0.0])''')

        A = ct.Species('A', 'H:1')
        B = ct.Species('B', 'H:1')
        C = ct.Species('C', 'H:1')

        for sp in [A, B, C]:
            sp.thermo = ct.ConstantCp(300, 1000, 101325, (300, 1.0, 1.0, 1.0))
        model = ct.Solution(thermo='IdealGas',
                            kinetics='GasKinetics',
                            species=[A, B, C],
                            reactions=[R1, R2])
        state = 1000, ct.one_atm, [1.0, 2.0, 1.0]
        matrix = create_drg_matrix(state, model)

        correct = np.array([
            [0, 1.0, 0],
            [1 / (1 + 1e-3), 0, 1e-3 / (1 + 1e-3)],
            [0, 1.0, 0],
        ])
        assert np.allclose(correct, matrix, rtol=1e-3)

        conc_A = 1.370536
        conc_B = 1.370480
        conc_C = 1.258985
        state = 1000, ct.one_atm, [conc_A, conc_B, conc_C]
        matrix = create_drg_matrix(state, model)

        correct = np.array([
            [0, 1.0, 0],
            [
                abs(conc_A - conc_B) /
                (abs(conc_A - conc_B) + 1e-3 * abs(conc_B - conc_C)), 0,
                1e-3 * abs(conc_B - conc_C) /
                (abs(conc_A - conc_B) + 1e-3 * abs(conc_B - conc_C))
            ],
            [0, 1.0, 0],
        ])
        assert np.allclose(correct, matrix, rtol=1e-3)
Exemplo n.º 9
0
    def test_csp_mech5(self):
        """Test of simple mech 5 from 2006 DRG paper.
        """
        R1 = ct.Reaction.fromCti('''reaction('F => P', [1.0, 0.0, 0.0])''')
        R2 = ct.Reaction.fromCti('''reaction('F => R', [1.0e-2, 0.0, 0.0])''')
        R3 = ct.Reaction.fromCti('''reaction('R => P', [1.0e2, 0.0, 0.0])''')

        F = ct.Species('F', 'H:1')
        P = ct.Species('P', 'H:1')
        R = ct.Species('R', 'H:1')

        for sp in [F, P, R]:
            sp.thermo = ct.ConstantCp(300, 1000, 101325, (300, 1.0, 1.0, 1.0))
        model = ct.Solution(thermo='IdealGas',
                            kinetics='GasKinetics',
                            species=[F, P, R],
                            reactions=[R1, R2, R3])
        state = 1000, ct.one_atm, [1.0, 1.0, 1.0e-4]
        matrix = create_drg_matrix(state, model)
        reached = trim_drg(matrix, ['F', 'P', 'R'], ['F'], 0.1)

        assert check_equal(reached, ['F', 'P'])
Exemplo n.º 10
0
 def _get_cantera_element_mw_map(cls, ctsol: ct.Solution):
     species_list = [
         ct.Species(element_name, f'{element_name}: 1')
         for element_name in ctsol.element_names
     ]
     for i in range(len(species_list)):
         species_list[i].thermo = ct.ConstantCp(300., 3000., 101325.,
                                                (300., 0., 0., 1.e4))
     element_only_ctsol = ct.Solution(thermo='IdealGas',
                                      kinetics='GasKinetics',
                                      species=species_list,
                                      reactions=[])
     return {
         name: mw
         for name, mw in zip(element_only_ctsol.species_names,
                             element_only_ctsol.molecular_weights)
     }
Exemplo n.º 11
0
from nanoparticles.nanoparticle_units import *

################################################################################
# GAS
################################################################################

T_low  =  200.00 # [K]
T_mid  = 1000.00 # [K]
T_high = 3500.00 # [K]
P_ref  =    1.00 * atm

################################################################################
# CO
################################################################################

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 )
Exemplo n.º 12
0
    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)
Exemplo n.º 13
0
    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
Exemplo n.º 14
0
import unittest
from numpy import max, abs, ones, zeros, hstack, sqrt, finfo
from cantera import gas_constant
from spitfire import ChemicalMechanismSpec as Mechanism
import pickle
import cantera as ct

species_decl = list([
    ct.Species('A', 'H:2'),
    ct.Species('B', 'H:1'),
    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',