Source code for cansen.profiles

# Standard libraries

# Third-party modules
import numpy as np


[docs]class VolumeProfile(object): """ Set the velocity of the piston by using a user specified volume profile. The initialization and calling of this class are handled by the :py:class:`~cantera.Func1` interface of Cantera. Used with the input keyword :ref:`VPRO <VPRO>` """ def __init__(self, keywords): """Set the initial values of the arrays from the input keywords. The time and volume are read from the input file and stored in the ``keywords`` dictionary. The velocity is calculated by assuming a unit area and using the forward difference, calculated by ``numpy.diff``. This function is only called once when the class is initialized at the beginning of a problem so it is efficient. :param keywords: Dictionary of keywords read from the input file """ # The time and volume are stored as lists in the keywords # dictionary. The volume is normalized by the first volume # element so that a unit area can be used to calculate the # velocity. self.time = np.array(keywords['vproTime']) self.volume = np.array(keywords['vproVol'])/keywords['vproVol'][0] # The velocity is calculated by the forward difference. # numpy.diff returns an array one element smaller than the # input array, so we append a zero to match the length of the # self.time array. self.velocity = np.diff(self.volume)/np.diff(self.time) self.velocity = np.append(self.velocity, 0)
[docs] def __call__(self, t): """Return the velocity when called during a time step. :param t: Input float, current simulation time. """ if t < self.time[-1]: # prev_time_point is the previous value in the time array # after the current simulation time prev_time_point = self.time[self.time <= t][-1] # index is the index of the time array where # prev_time_point occurs index = np.where(self.time == prev_time_point)[0][0] return self.velocity[index] else: return 0
[docs]class TemperatureProfile(object): """ Set the temperature of the reactor by using a user specified temperature profile. The initialization and calling of this class are handled by the :py:class:`~cantera.Func1` interface of Cantera. Used with the input keyword :ref:`TPRO <TPRO>` """ def __init__(self, keywords): """Set the initial values of the arrays from the input keywords. The time and temperature are read from the input file and stored in the ``keywords`` dictionary as lists. This function is only called once when the class is initialized at the beginning of a problem so it is efficient. """ self.time = np.array(keywords['TproTime']) self.temperature = np.array(keywords['TproTemp'])
[docs] def __call__(self, t): """Return the temperature when called during a time step. Using linear interpolation, determine the temperature at a given input time ``t``. :param t: Input float, current simulation time. """ if t == 0: return self.temperature[0] if t < self.time[1]: tim0 = self.time[0] tim1 = self.time[1] temp0 = self.temperature[0] temp1 = self.temperature[1] elif t >= self.time[1] and t <= self.time[-1]: tim0 = self.time[self.time < t][-1] tim1 = self.time[np.where(self.time == tim0)[0][0]+1] temp0 = self.temperature[self.time < t][-1] temp1 = self.temperature[np.where(self.time == tim0)[0][0]+1] elif t > self.time[-1]: return self.temperature[-1] interp = temp0 + (temp1-temp0)*(t-tim0)/(tim1-tim0) return interp
[docs]class ICEngineProfile(object): """ Set the velocity of the wall according to the parameters of a reciprocating engine. The initialization and calling of this class are handled by the :py:class:`~cantera.Func1` interface of Cantera. Used with the input keyword :ref:`ICEN <ICEN>`. """ def __init__(self, keywords): """Set the initial values of the engine parameters. The parameters are read from the input file into the ``keywords`` dictionary. """ start_crank_angle = keywords.get('start_crank_angle', 180.0) self.rod_radius_ratio = keywords['rod_radius_ratio'] rev_per_minute = keywords['rev_per_min'] self.stroke_length = keywords['stroke_length'] # Angular velocity, rad/s self.omega = rev_per_minute*np.pi/30 # Start angle, rad self.start_crank_rad = start_crank_angle/180.0*np.pi
[docs] def __call__(self, time): """Return the velocity of the piston when called. The function for the velocity is given by Heywood. See :doc:`/icengine`. :param time: Input float, current simulation time """ theta = self.start_crank_rad - self.omega * time # Technically, this is negative, but the way we install the # wall between the reactor and the environment handles the # sign. return (self.omega*self.stroke_length/2*np.sin(theta) * (1 + np.cos(theta)/np.sqrt(self.rod_radius_ratio**2 - np.sin(theta)**2)))
[docs]class PressureProfile(object): """ Dummy class for the pressure profile, to be implemented in CanSen v2.0 """ pass