Beispiel #1
0
    def test_sequence(self):
        f = ct.Func1([5])
        for t in [0.1, 0.7, 4.5]:
            self.assertNear(f(t), 5)

        with self.assertRaises(TypeError):
            ct.Func1([3, 4])
Beispiel #2
0
    def test_numpy(self):
        f = ct.Func1(np.array(5))
        g = ct.Func1(np.array([[5]]))
        for t in [0.1, 0.7, 4.5]:
            self.assertNear(f(t), 5)
            self.assertNear(g(t), 5)

        with self.assertRaises(TypeError):
            ct.Func1(np.array([3, 4]))
Beispiel #3
0
    def test_failure(self):
        def fails(t):
            raise ValueError('bad')

        f = ct.Func1(fails)
        with self.assertRaises(ValueError):
            f(0.1)
Beispiel #4
0
    def test_callable(self):
        class Multiplier(object):
            def __init__(self, factor):
                self.factor = factor
            def __call__(self, t):
                return self.factor * t

        m = Multiplier(8.1)
        f = ct.Func1(m)
        for t in [0.1, 0.7, 4.5]:
            self.assertNear(f(t), 8.1*t)
Beispiel #5
0
 def test_function(self):
     f = ct.Func1(np.sin)
     self.assertNear(f(0), np.sin(0))
     self.assertNear(f(0.1), np.sin(0.1))
     self.assertNear(f(0.7), np.sin(0.7))
Beispiel #6
0
 def test_uncopyable(self):
     import copy
     f = ct.Func1(np.sin)
     with self.assertRaises(NotImplementedError):
         copy.copy(f)
Beispiel #7
0
 def test_unpicklable(self):
     import pickle
     f = ct.Func1(np.sin)
     with self.assertRaises(NotImplementedError):
         pickle.dumps(f)
Beispiel #8
0
 def test_constant(self):
     f = ct.Func1(5)
     for t in [0.1, 0.7, 4.5]:
         self.assertNear(f(t), 5)
Beispiel #9
0
 def test_lambda(self):
     f = ct.Func1(lambda t: np.sin(t) * np.sqrt(t))
     for t in [0.1, 0.7, 4.5]:
         self.assertNear(f(t), np.sin(t) * np.sqrt(t))
Beispiel #10
0
    def setup_case(self):
        """
        Sets up the case to be run. Initializes the ``ThermoPhase``,
        ``Reactor``, and ``ReactorNet`` according to the values from
        the input file.
        """

        self.gas = ct.Solution(self.mech_filename)

        initial_temp = self.keywords['temperature']
        # The initial pressure in Cantera is expected in Pa; in SENKIN
        # it is expected in atm, so convert
        initial_pres = self.keywords['pressure'] * ct.one_atm
        # If the equivalence ratio has been specified, send the
        # keywords for conversion.
        if 'eqRatio' in self.keywords:
            reactants = utils.equivalence_ratio(
                self.gas,
                self.keywords['eqRatio'],
                self.keywords['fuel'],
                self.keywords['oxidizer'],
                self.keywords['completeProducts'],
                self.keywords['additionalSpecies'],
            )
        else:
            # The reactants are stored in the ``keywords`` dictionary
            # as a list of strings, so they need to be joined.
            reactants = ','.join(self.keywords['reactants'])

        self.gas.TPX = initial_temp, initial_pres, reactants

        # Create a non-interacting ``Reservoir`` to be on the other
        # side of the ``Wall``.
        env = ct.Reservoir(ct.Solution('air.xml'))
        # Set the ``temp_func`` to ``None`` as default; it will be set
        # later if needed.
        self.temp_func = None
        # All of the reactors are ``IdealGas`` Reactors. Set a ``Wall``
        # for every case so that later code can be more generic. If the
        # velocity is set to zero, the ``Wall`` won't affect anything.
        # We have to set the ``n_vars`` here because until the first
        # time step, ``ReactorNet.n_vars`` is zero, but we need the
        # ``n_vars`` before the first time step.
        if self.keywords['problemType'] == 1:
            self.reac = ct.IdealGasReactor(self.gas)
            # Number of solution variables is number of species + mass,
            # volume, temperature
            self.n_vars = self.reac.kinetics.n_species + 3
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
        elif self.keywords['problemType'] == 2:
            self.reac = ct.IdealGasConstPressureReactor(self.gas)
            # Number of solution variables is number of species + mass,
            # temperature
            self.n_vars = self.reac.kinetics.n_species + 2
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
        elif self.keywords['problemType'] == 3:
            self.reac = ct.IdealGasReactor(self.gas)
            # Number of solution variables is number of species + mass,
            # volume, temperature
            self.n_vars = self.reac.kinetics.n_species + 3
            self.wall = ct.Wall(self.reac,
                                env,
                                A=1.0,
                                velocity=VolumeProfile(self.keywords))
        elif self.keywords['problemType'] == 4:
            self.reac = ct.IdealGasConstPressureReactor(self.gas, energy='off')
            # Number of solution variables is number of species + mass,
            # temperature
            self.n_vars = self.reac.kinetics.n_species + 2
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
        elif self.keywords['problemType'] == 5:
            self.reac = ct.IdealGasReactor(self.gas, energy='off')
            # Number of solution variables is number of species + mass,
            # volume, temperature
            self.n_vars = self.reac.kinetics.n_species + 3
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
        elif self.keywords['problemType'] == 6:
            from user_routines import VolumeFunctionTime
            self.reac = ct.IdealGasReactor(self.gas)
            # Number of solution variables is number of species + mass,
            # volume, temperature
            self.n_vars = self.reac.kinetics.n_species + 3
            self.wall = ct.Wall(self.reac,
                                env,
                                A=1.0,
                                velocity=VolumeFunctionTime())
        elif self.keywords['problemType'] == 7:
            from user_routines import TemperatureFunctionTime
            self.reac = ct.IdealGasConstPressureReactor(self.gas, energy='off')
            # Number of solution variables is number of species + mass,
            # temperature
            self.n_vars = self.reac.kinetics.n_species + 2
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
            self.temp_func = ct.Func1(TemperatureFunctionTime())
        elif self.keywords['problemType'] == 8:
            self.reac = ct.IdealGasConstPressureReactor(self.gas, energy='off')
            # Number of solution variables is number of species + mass,
            # temperature
            self.n_vars = self.reac.kinetics.n_species + 2
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)
            self.temp_func = ct.Func1(TemperatureProfile(self.keywords))
        elif self.keywords['problemType'] == 9:
            self.reac = ct.IdealGasReactor(self.gas)
            # Number of solution variables is number of species + mass,
            # volume, temperature
            self.n_vars = self.reac.kinetics.n_species + 3
            self.wall = ct.Wall(env,
                                self.reac,
                                A=1.0,
                                velocity=ICEngineProfile(self.keywords))

        if 'reactorVolume' in self.keywords:
            self.reac.volume = self.keywords['reactorVolume']

        # Create the Reactor Network.
        self.netw = ct.ReactorNet([self.reac])

        if 'sensitivity' in self.keywords:
            self.sensitivity = True
            # There is no automatic way to calculate the sensitivity of
            # all of the reactions, so do it manually.
            for i in range(self.reac.kinetics.n_reactions):
                self.reac.add_sensitivity_reaction(i)
            # If no tolerances for the sensitivity are specified, set
            # to the SENKIN defaults.
            if 'sensAbsTol' in self.keywords:
                self.netw.atol_sensitivity = self.keywords['sensAbsTol']
            else:
                self.netw.atol_sensitivity = 1.0E-06
            if 'sensRelTol' in self.keywords:
                self.netw.rtol_sensitivity = self.keywords['sensRelTol']
            else:
                self.netw.rtol_sensitivity = 1.0E-04
        else:
            self.sensitivity = False

        # If no solution tolerances are specified, set to the default
        # SENKIN values.
        if 'abstol' in self.keywords:
            self.netw.atol = self.keywords['abstol']
        else:
            self.netw.atol = 1.0E-20

        if 'reltol' in self.keywords:
            self.netw.rtol = self.keywords['reltol']
        else:
            self.netw.rtol = 1.0E-08

        if 'tempLimit' in self.keywords:
            self.temp_limit = self.keywords['tempLimit']
        else:
            # tempThresh is set in the parser even if it is not present
            # in the input file
            self.temp_limit = (self.keywords['tempThresh'] +
                               self.keywords['temperature'])

        self.tend = self.keywords['endTime']

        # Set the maximum time step the solver can take. If a value is
        # not specified in the input file, default to 0.001*self.tend.
        # Set the time steps for saving to the binary file and writing
        # to the screen. If the time step for printing to the screen is
        # not set, default to printing 100 times.
        print_time_int = self.keywords.get('prntTimeInt')
        save_time_int = self.keywords.get('saveTimeInt')
        max_time_int = self.keywords.get('maxTimeStep')

        time_ints = [
            value for value in [print_time_int, save_time_int, max_time_int]
            if value is not None
        ]

        if time_ints:
            self.netw.set_max_time_step(min(time_ints))
        else:
            self.netw.set_max_time_step(self.tend / 100)

        if print_time_int is not None:
            self.print_time_step = print_time_int
        else:
            self.print_time_step = self.tend / 100

        self.print_time = self.print_time_step

        self.save_time_step = save_time_int

        if self.save_time_step is not None:
            self.save_time = self.save_time_step

        # Store the species names in a slightly shorter variable name
        self.species_names = self.reac.thermo.species_names

        # Initialize the ignition time, in case the end time is reached
        # before ignition occurs
        self.ignition_time = None
Beispiel #11
0
 def test_rate_func(self):
     f = ct.Func1(self._rate)
     rate = ct.CustomRate(f)
     self.assertNear(rate(self.gas.T), self.gas.forward_rate_constants[self._index])
Beispiel #12
0
 def test_from_func(self):
     f = ct.Func1(self._rate)
     rxn = ct.CustomReaction(equation=self._equation, rate=f, kinetics=self.gas)
     self.check_rxn(rxn)
Beispiel #13
0
t_step_1 = t_1/steps_1
steps_2 = 110
t_2 = 0.031
t_step_2 = (t_2 - t_1)/steps_2
steps_3 = 200
t_3 = 0.033
t_step_3 = (t_3 - t_2)/steps_3
steps_4 = 250
t_4 = 0.0355
t_step_4 = (t_4 - t_3)/steps_4
steps_5 = 3000
t_5 = 0.3355
t_step_5 = (t_5 - t_4)/steps_5

# Velocity of the piston
v_1 = ct.Func1(lambda t: 21/20*1000*t )
v_2 = ct.Func1(lambda t: (26.5-21)/11*(t*1000-20)+21 )
v_3 = ct.Func1(lambda t: (26.5 - 1)/2*(33-t*1000)+1 )
v_4 = ct.Func1(lambda t: (35.5-t*1000)/2.5*1 )
v_5 = ct.Func1(lambda t: 0 )

# Heat loss setting for the boundary layer zone. It varies with the wall area.
q_1 = ct.Func1(lambda t: -1/area_2*(r2.T - Tw)*h_2*(2*(area_1+area_2) + Awalls - t*t/0.02*21/2*np.pi*dia_2) )
q_2 = ct.Func1(lambda t: -1/area_2*(r2.T - Tw)*h_2*(2*(area_1+area_2) + Awalls - (0.02*21/2 + (21+((26.5-21)/0.011*(t-0.02))+21)*(t-0.02)/2)*np.pi*dia_2) )
q_3 = ct.Func1(lambda t: -1/area_2*(r2.T - Tw)*h_2*(2*(area_1+area_2) + Awalls - (0.02*21/2 + (21+26.5)*0.011/2 + ( (26.5-1)/0.002*(0.033-t)+1 +26.5 )*(t-0.031)/2)*np.pi*dia_2) )
q_4 = ct.Func1(lambda t: -1/area_2*(r2.T - Tw)*h_2*(2*(area_1+area_2) + Awalls - (0.02*21/2 + (21+26.5)*0.011/2 + (26.5+1)*0.002/2 + (0.0025*1/2 - (0.0355-t)*(0.0355-t)/0.0025*1/2) )*np.pi*dia_2) )
q_5 = ct.Func1(lambda t: -1/area_2*(r2.T - Tw)*h_2*(2*(area_1+area_2) + Awalls - (0.02*21/2 + (21+26.5)*0.011/2 + (26.5+1)*0.002/2 + 0.0025*1/2 )*np.pi*dia_2) )


n_steps = steps_1 + steps_2 + steps_3 + steps_4 + steps_5
data = np.zeros( (n_steps, 13) )
Beispiel #14
0
 def test_rate_func(self):
     # check result of rate expression
     f = ct.Func1(self._rate)
     rate = ct.CustomRate(f)
     self.assertNear(rate(self.gas.T), self.gas.forward_rate_constants[self._index])
Beispiel #15
0
 def test_from_func1(self):
     # check instantiation from keywords / rate provided as func1
     f = ct.Func1(self._rate)
     rxn = ct.CustomReaction(equation=self._equation, rate=f, kinetics=self.gas)
     self.check_rxn(rxn)
Beispiel #16
0
 def test_from_func1(self):
     # check instantiation from keywords / rate provided as func1
     f = ct.Func1(self._rate)
     rxn = self.from_rate(f)
     self.check_rxn(rxn)