コード例 #1
0
ファイル: test_reactor.py プロジェクト: zihao-wang/cantera
    def test_Reactor(self):
        phase = ct.PureFluid('liquidvapor.xml', 'oxygen')
        air = ct.Solution('air.xml')

        phase.TP = 93, 4e5
        r1 = ct.Reactor(phase)
        r1.volume = 0.1

        air.TP = 300, 4e5
        r2 = ct.Reactor(air)
        r2.volume = 10.0

        air.TP = 500, 4e5
        env = ct.Reservoir(air)

        w1 = ct.Wall(r1,r2)
        w1.expansion_rate_coeff = 1e-3
        w2 = ct.Wall(env,r1, Q=500000, A=1)
        net = ct.ReactorNet([r1,r2])
        net.atol = 1e-10
        net.rtol = 1e-6

        states = ct.SolutionArray(phase, extra='t')
        for t in np.arange(0.0, 60.0, 1):
            net.advance(t)
            states.append(TD=r1.thermo.TD, t=net.time)

        self.assertEqual(states.X[0], 0)
        self.assertEqual(states.X[-1], 1)
        self.assertNear(states.X[30], 0.54806, 1e-4)
コード例 #2
0
ファイル: test_reactor.py プロジェクト: zihao-wang/cantera
    def setUp(self):
        self.referenceFile = pjoin(os.path.dirname(__file__), 'data', 'WallTest-integrateWithAdvance.csv')
        # reservoir to represent the environment
        self.gas0 = ct.Solution('air.xml')
        self.gas0.TP = 300, ct.one_atm
        self.env = ct.Reservoir(self.gas0)

        # reactor to represent the side filled with Argon
        self.gas1 = ct.Solution('air.xml')
        self.gas1.TPX = 1000.0, 30*ct.one_atm, 'AR:1.0'
        self.r1 = ct.Reactor(self.gas1)

        # reactor to represent the combustible mixture
        self.gas2 = ct.Solution('h2o2.xml')
        self.gas2.TPX = 500.0, 1.5*ct.one_atm, 'H2:0.5, O2:1.0, AR:10.0'
        self.r2 = ct.Reactor(self.gas2)

        # Wall between the two reactors
        self.w1 = ct.Wall(self.r2, self.r1, A=1.0, K=2e-4, U=400.0)

        # Wall to represent heat loss to the environment
        self.w2 = ct.Wall(self.r2, self.env, A=1.0, U=2000.0)

        # Create the reactor network
        self.sim = ct.ReactorNet([self.r1, self.r2])
コード例 #3
0
ファイル: test_reactor.py プロジェクト: zihao-wang/cantera
    def create_reactors(self, add_Q=False, add_mdot=False, add_surf=False):
        self.gas = ct.Solution('gri30.xml')
        self.gas.TPX = 900, 25*ct.one_atm, 'CO:0.5, H2O:0.2'

        self.gas1 = ct.Solution('gri30.xml')
        self.gas1.ID = 'gas'
        self.gas2 = ct.Solution('gri30.xml')
        self.gas2.ID = 'gas'
        resGas = ct.Solution('gri30.xml')
        solid = ct.Solution('diamond.xml', 'diamond')

        T0 = 1200
        P0 = 25*ct.one_atm
        X0 = 'CH4:0.5, H2O:0.2, CO:0.3'

        self.gas1.TPX = T0, P0, X0
        self.gas2.TPX = T0, P0, X0

        self.r1 = ct.IdealGasReactor(self.gas1)
        self.r2 = self.reactorClass(self.gas2)

        self.r1.volume = 0.2
        self.r2.volume = 0.2

        resGas.TP = T0 - 300, P0
        env = ct.Reservoir(resGas)

        U = 300 if add_Q else 0

        self.w1 = ct.Wall(self.r1, env, K=1e3, A=0.1, U=U)
        self.w2 = ct.Wall(self.r2, env, A=0.1, U=U)

        if add_mdot:
            mfc1 = ct.MassFlowController(env, self.r1, mdot=0.05)
            mfc2 = ct.MassFlowController(env, self.r2, mdot=0.05)

        if add_surf:
            self.interface1 = ct.Interface('diamond.xml', 'diamond_100',
                                      (self.gas1, solid))
            self.interface2 = ct.Interface('diamond.xml', 'diamond_100',
                                      (self.gas2, solid))

            C = np.zeros(self.interface1.n_species)
            C[0] = 0.3
            C[4] = 0.7
            self.surf1 = ct.ReactorSurface(self.interface1, A=0.2)
            self.surf2 = ct.ReactorSurface(self.interface2, A=0.2)
            self.surf1.coverages = C
            self.surf2.coverages = C
            self.surf1.install(self.r1)
            self.surf2.install(self.r2)

        self.net1 = ct.ReactorNet([self.r1])
        self.net2 = ct.ReactorNet([self.r2])
        self.net1.set_max_time_step(0.05)
        self.net2.set_max_time_step(0.05)
        self.net2.max_err_test_fails = 10
コード例 #4
0
ファイル: engines.py プロジェクト: NREL/MPRL
    def setup_reactor(self):
        self.gas = ct.Solution(self.rxnmech)
        self.xinit = {"O2": 0.21, "N2": 0.79}
        self.gas.TPX = self.T0, self.p0, self.xinit

        self.injection_gas, _ = setup_injection_gas(self.rxnmech,
                                                    self.fuel,
                                                    pure_fuel=True)
        self.injection_gas.TP = self.T0, self.p0
        fuel_res = ct.Reservoir(self.injection_gas)

        # Create the reactor object
        self.reactor = ct.Reactor(self.gas)
        self.rempty = ct.Reactor(self.gas)

        # Set the initial states of the reactor
        self.reactor.chemistry_enabled = True
        self.reactor.volume = self.history["V"][0]

        # Add in a fuel injector
        self.injector = ct.MassFlowController(fuel_res, self.reactor)

        # Add in a wall that moves according to piston velocity
        self.piston = ct.Wall(
            left=self.reactor,
            right=self.rempty,
            A=np.pi / 4.0 * self.bore**2,
            U=0.0,
            velocity=self.history["piston_velocity"][0],
        )

        # Create the network object
        self.sim = ct.ReactorNet([self.reactor])
コード例 #5
0
        def setup(order):
            gas1.TPX = 1200, 1e3, 'H:0.002, H2:1, CH4:0.01, CH3:0.0002'
            gas2.TPX = 900, 101325, 'H2:0.1, OH:1e-7, O2:0.1, AR:1e-5'
            net = ct.ReactorNet()
            rA = ct.Reactor(gas1)
            rB = ct.Reactor(gas2)

            if order % 2 == 0:
                wA = ct.Wall(rA, rB)
                wB = ct.Wall(rB, rA)
            else:
                wB = ct.Wall(rB, rA)
                wA = ct.Wall(rA, rB)

            wA.left.kinetics = interface
            wB.right.kinetics = interface

            wA.area = 0.1
            wB.area = 10

            C1 = np.zeros(interface.nSpecies)
            C2 = np.zeros(interface.nSpecies)
            C1[0] = 0.3
            C1[4] = 0.7

            C2[0] = 0.9
            C2[4] = 0.1
            wA.left.coverages = C1
            wB.right.coverages = C2

            if order // 2 == 0:
                net.addReactor(rA)
                net.addReactor(rB)
            else:
                net.addReactor(rB)
                net.addReactor(rA)

            return rA,rB,wA,wB,net
コード例 #6
0
    def __init__(self, initial_temperature, initial_pressure, volume, is_reactive,
                 end_temp=2500., end_time=0.2, chem_file='species.cti', cti_source=None):

        if volume is None:
            volume = np.genfromtxt('volume.csv', delimiter=',')

        inp_time = volume[:, 0]
        inp_vol = volume[:, 1]

        self.time = []
        self.temperature = []
        self.pressure = []
        self.input_volume = volume
        self.simulated_volume = []
        self.end_temp = end_temp
        self.end_time = end_time
        self.is_reactive = is_reactive
        self.chem_file = chem_file
        self.initial_temperature = initial_temperature
        self.initial_pressure = initial_pressure

        if cti_source is None:
            gas = ct.Solution(chem_file)
        else:
            gas = ct.Solution(source=cti_source)
        gas.TP = self.initial_temperature, self.initial_pressure
        if not self.is_reactive:
            gas.set_multiplier(0)
        reac = ct.IdealGasReactor(gas)
        env = ct.Reservoir(ct.Solution('air.xml'))
        ct.Wall(reac, env, A=1.0, velocity=VolumeProfile(inp_time, inp_vol))
        netw = ct.ReactorNet([reac])
        netw.set_max_time_step(inp_time[1])
        self.time.append(netw.time)
        self.temperature.append(reac.T)
        self.pressure.append(gas.P/1E5)
        self.simulated_volume.append(reac.volume)

        while reac.T < self.end_temp and netw.time < self.end_time:
            netw.step()
            self.time.append(netw.time)
            self.temperature.append(reac.T)
            self.pressure.append(gas.P/1E5)
            self.simulated_volume.append(reac.volume)

        self.time = np.array(self.time)
        self.pressure = np.array(self.pressure)
        self.temperature = np.array(self.temperature)
        self.simulated_volume = np.array(self.simulated_volume)
        self.derivative = self.calculate_derivative(self.pressure, self.time)
コード例 #7
0
    def makeReactors(self):
        self.net = ct.ReactorNet()

        self.gas = ct.Solution('diamond.xml', 'gas')
        self.solid = ct.Solution('diamond.xml', 'diamond')
        self.interface = ct.Interface('diamond.xml', 'diamond_100',
                                      (self.gas, self.solid))
        self.r1 = ct.Reactor(self.gas)
        self.net.addReactor(self.r1)

        self.r2 = ct.Reactor(self.gas)
        self.net.addReactor(self.r2)

        self.w = ct.Wall(self.r1, self.r2)
コード例 #8
0
def def_walls(r, env, zone, z, v_factor, keywords, t_wall, a_rcm):
    """
    Defines walls for handling the volume variation and heat transfer
    
    Returns
    -------
    wq : List of Cantera Wall objects handling the heat transfer
    wv: List of Cantera Wall objects handling the volume trace
    """
    wq = [0]
    wv = [0]
    q = heat_transfer(z, zone, r, t_wall)

    wq.append(ct.Wall(r[1], env, A=zone[1].surface_area, Q=q[1]))

    for x in range(2, z):
        wq.append(ct.Wall(r[x], env, A=zone[x].surface_area, Q=q[x]))

    wq.append(ct.Wall(r[z], env, A=zone[z].surface_area, Q=q[z]))

    for x in range(1, z + 1):
        wv.append(ct.Wall(r[x], env, velocity=VolumeProfile(keywords, a_rcm)))
        wv[x].area = v_factor[x]
    return wq, wv
コード例 #9
0
ファイル: test_reactor.py プロジェクト: damian-666/cantera
    def setUp(self):
        # reservoir to represent the environment
        self.gas0 = ct.Solution('air.xml')
        self.gas0.TP = 300, ct.one_atm
        self.env = ct.Reservoir(self.gas0)

        # reactor to represent the side filled with Argon
        self.gas1 = ct.Solution('air.xml')
        self.gas1.TPX = 1000.0, 30 * ct.one_atm, 'AR:1.0'
        self.r1 = ct.Reactor(self.gas1)

        # reactor to represent the combustible mixture
        self.gas2 = ct.Solution('h2o2.xml')
        self.gas2.TPX = 500.0, 1.5 * ct.one_atm, 'H2:0.5, O2:1.0, AR:10.0'
        self.r2 = ct.Reactor(self.gas2)

        # Wall between the two reactors
        self.w1 = ct.Wall(self.r2, self.r1, A=1.0, K=2e-4, U=400.0)

        # Wall to represent heat loss to the environment
        self.w2 = ct.Wall(self.r2, self.env, A=1.0, U=2000.0)

        # Create the reactor network
        self.sim = ct.ReactorNet([self.r1, self.r2])
コード例 #10
0
    def test_sensitivities2(self):
        net = ct.ReactorNet()

        gas1 = ct.Solution('diamond.xml', 'gas')
        solid = ct.Solution('diamond.xml', 'diamond')
        interface = ct.Interface('diamond.xml', 'diamond_100',
                                 (gas1, solid))
        r1 = ct.IdealGasReactor(gas1)
        net.add_reactor(r1)
        net.atol_sensitivity = 1e-10
        net.rtol_sensitivity = 1e-8

        gas2 = ct.Solution('h2o2.xml')
        gas2.TPX = 900, 101325, 'H2:0.1, OH:1e-7, O2:0.1, AR:1e-5'
        r2 = ct.IdealGasReactor(gas2)
        net.add_reactor(r2)

        w = ct.Wall(r1, r2)
        w.area = 1.5
        w.left.kinetics = interface

        C = np.zeros(interface.n_species)
        C[0] = 0.3
        C[4] = 0.7

        w.left.coverages = C
        w.left.add_sensitivity_reaction(2)
        r2.add_sensitivity_reaction(18)

        for T in (901, 905, 910, 950, 1500):
            while r2.T < T:
                net.step(1.0)

            S = net.sensitivities()

            # number of non-species variables in each reactor
            Ns = r1.component_index(gas1.species_name(0))

            # Index of first variable corresponding to r2
            K2 = Ns + gas1.n_species + interface.n_species

            # Constant volume should generate zero sensitivity coefficient
            self.assertArrayNear(S[1,:], np.zeros(2))
            self.assertArrayNear(S[K2+1,:], np.zeros(2))

            # Sensitivity coefficients for the disjoint reactors should be zero
            self.assertNear(np.linalg.norm(S[Ns:K2,1]), 0.0, atol=1e-5)
            self.assertNear(np.linalg.norm(S[K2+Ns:,0]), 0.0, atol=1e-5)
コード例 #11
0
    def make_reactors(self):
        self.net = ct.ReactorNet()

        self.gas = ct.Solution('diamond.xml', 'gas')
        self.solid = ct.Solution('diamond.xml', 'diamond')
        self.interface = ct.Interface('diamond.xml', 'diamond_100',
                                      (self.gas, self.solid))
        self.r1 = ct.IdealGasReactor(self.gas)
        self.r1.volume = 0.01
        self.net.add_reactor(self.r1)

        self.r2 = ct.IdealGasReactor(self.gas)
        self.r2.volume = 0.01
        self.net.add_reactor(self.r2)

        self.w = ct.Wall(self.r1, self.r2)
        self.w.area = 1.0
コード例 #12
0
    def test_sensitivities2(self):
        net = ct.ReactorNet()

        gas1 = ct.Solution('diamond.xml', 'gas')
        solid = ct.Solution('diamond.xml', 'diamond')
        interface = ct.Interface('diamond.xml', 'diamond_100',
                                 (gas1, solid))
        r1 = ct.Reactor(gas1)
        net.addReactor(r1)

        gas2 = ct.Solution('h2o2.xml')
        gas2.TPX = 900, 101325, 'H2:0.1, OH:1e-7, O2:0.1, AR:1e-5'
        r2 = ct.Reactor(gas2)
        net.addReactor(r2)

        w = ct.Wall(r1, r2)
        w.left.kinetics = interface

        C = np.zeros(interface.nSpecies)
        C[0] = 0.3
        C[4] = 0.7

        w.left.coverages = C
        w.left.addSensitivityReaction(2)
        r2.addSensitivityReaction(18)

        for T in (901, 905, 910, 950, 1500):
            while r2.T < T:
                net.step(1.0)

            S = net.sensitivities()
            K1 = gas1.nSpecies + interface.nSpecies

            # Constant internal energy and volume should generate zero
            # sensitivity coefficients
            self.assertArrayNear(S[0:2,:], np.zeros((2,2)))
            self.assertArrayNear(S[K1+2:K1+4,:], np.zeros((2,2)))

            S11 = np.linalg.norm(S[2:K1+2,0])
            S21 = np.linalg.norm(S[2:K1+2,1])
            S12 = np.linalg.norm(S[K1+4:,0])
            S22 = np.linalg.norm(S[K1+4:,1])

            self.assertTrue(S11 > 1e5 * S12)
            self.assertTrue(S22 > 1e5 * S21)
コード例 #13
0
ファイル: simulation.py プロジェクト: zdz0309/pyMARS
    def __init__(self, idx, properties, model, path=''):
        """Initialize simulation case.

        :param idx: identifier number for this case
        :type idx: int
        :param properties: set of properties for this case
        :type properties: dict
        :param str model_file: Filename for Cantera-format model
        :param str path: Path for data file
        """
        self.idx = idx
        self.properties = properties

        self.gas = model

        self.time_end = 10  #This is just a filler idk how end time should actually be determined yet

        self.gas.TP = (self.properties['temperature'],
                       self.properties['pressure'] * float(ct.one_atm))
        self.gas.set_equivalence_ratio(self.properties['equivalence_ratio'],
                                       self.properties['fuel'],
                                       self.properties['oxidizer'])

        # Create non-interacting ``Reservoir`` on other side of ``Wall``
        env = ct.Reservoir(ct.Solution('air.xml'))

        # All reactors are ``IdealGasReactor`` objects
        self.reac = ct.IdealGasReactor(self.gas)
        self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)

        # Create ``ReactorNet`` newtork
        self.reac_net = ct.ReactorNet([self.reac])

        # Set file for later data file
        file_path = os.path.join(path, str(self.idx) + '.h5')
        self.save_file = file_path
        self.sample_points = []

        self.ignition_delay = 0.0
コード例 #14
0
ファイル: test_reactor.py プロジェクト: zihao-wang/cantera
    def test_ConstPressureReactor(self):
        phase = ct.Nitrogen()
        air = ct.Solution('air.xml')

        phase.TP = 75, 4e5
        r1 = ct.ConstPressureReactor(phase)
        r1.volume = 0.1

        air.TP = 500, 4e5
        env = ct.Reservoir(air)

        w2 = ct.Wall(env,r1, Q=250000, A=1)
        net = ct.ReactorNet([r1])

        states = ct.SolutionArray(phase, extra='t')
        for t in np.arange(0.0, 100.0, 10):
            net.advance(t)
            states.append(TD=r1.thermo.TD, t=t)

        self.assertEqual(states.X[1], 0)
        self.assertEqual(states.X[-2], 1)
        for i in range(3,7):
            self.assertNear(states.T[i], states.T[2])
コード例 #15
0
ファイル: piston.py プロジェクト: peterma123456789/cantera
gas2.TPX = 900.0, ct.one_atm, 'CO:2, H2O:0.01, O2:5'

r1 = ct.IdealGasReactor(gas1)
r1.volume = 0.5
r2 = ct.IdealGasReactor(gas2)
r2.volume = 0.1

# The wall is held fixed until t = 0.1 s, then released to allow the pressure to
# equilibrate.
def v(t):
    if t < 0.1:
        return 0.0
    else:
        return (r1.thermo.P - r2.thermo.P) * 1e-4

w = ct.Wall(r1, r2, velocity=v)

net = ct.ReactorNet([r1, r2])

states1 = ct.SolutionArray(r1.thermo, extra=['t','v'])
states2 = ct.SolutionArray(r2.thermo, extra=['t','v'])

for n in range(200):
    time = (n+1)*0.001
    net.advance(time)
    if n % 4 == 3:
        print(fmt % (time, r1.T, r2.T, r1.volume, r2.volume,
                     r1.volume + r2.volume, r2.thermo['CO'].X[0]))

    states1.append(r1.thermo.state, t=1000*time, v=r1.volume)
    states2.append(r2.thermo.state, t=1000*time, v=r2.volume)
コード例 #16
0
    return 2.0 * np.pi * rps * t + ca_start * np.pi / 180.0

# set up IC engine parameters
stroke *= 0.001
bore *= 0.001
conrod *= 0.001
area = 0.25 * np.pi * bore * bore
vol_h = stroke * area  # volume cylinder
vol_c = vol_h / (cratio - 1.0) # volume combustion dome
ca = crank_angle(0.0) # initial CA
r_ca = stroke * 0.5 # crank radius
vol_ini= (r_ca + conrod - (r_ca * np.cos(ca) + np.sqrt(conrod**2 - r_ca**2 * np.sin(ca)**2))) * area + vol_c
r.volume = vol_ini # initial volume

# set up piston 
piston = ct.Wall(outer, r)
piston.area = area  # piston area
def piston_speed(t):
    ca = crank_angle(t)
    return -2.0 * np.pi * rps * (r_ca * np.sin(ca) + r_ca**2 * np.sin(2.0 * ca) / 2.0 / np.sqrt(conrod**2 - r_ca**2 * np.sin(ca)**2))
piston.set_velocity(piston_speed)  # piston speed

# set up time
t_sim = (ca_end - ca_start) / rps / 360.0  # simulation time
t_step = ca_step / rps / 360.0  # simulation time step
t_out = ca_out / rps / 360.0 # simulation output time
ttt = 0.0

# set up output data arrays
states = ct.SolutionArray(r.thermo)
t = []
コード例 #17
0
 def addWall(self, **kwargs):
     self.w = ct.Wall(self.r1, self.r2, **kwargs)
     return self.w
コード例 #18
0
fmt = '%10.3f  %10.1f  %10.4f  %10.4g  %10.4g  %10.4g  %10.4g'
print('%10s  %10s  %10s  %10s  %10s  %10s %10s' %
      ('time [s]', 'T1 [K]', 'T2 [K]', 'V1 [m^3]', 'V2 [m^3]', 'V1+V2 [m^3]',
       'X(CO)'))

gas1 = ct.Solution('h2o2.cti')
gas1.TPX = 900.0, ct.one_atm, 'H2:2, O2:1, AR:20'

gas2 = ct.Solution('gri30.xml')
gas2.TPX = 900.0, ct.one_atm, 'CO:2, H2O:0.01, O2:5'

r1 = ct.Reactor(gas1)
r1.volume = 0.5
r2 = ct.Reactor(gas2)
r2.volume = 0.1
w = ct.Wall(r1, r2, K=1.0e3)

net = ct.ReactorNet([r1, r2])

tim = []
t1 = []
t2 = []
v1 = []
v2 = []
v = []
xco = []
xh2 = []

for n in range(30):
    time = (n + 1) * 0.002
    net.advance(time)
コード例 #19
0
cstr = ct.IdealGasReactor(gas)

# Set its volume to 10 cm^3. In this problem, the reactor volume is fixed, so
# the initial volume is the volume at all later times.
cstr.volume = 10.0 * 1.0e-6

# We need to have heat loss to see the oscillations. Create a reservoir to
# represent the environment, and initialize its temperature to the reactor
# temperature.
env = ct.Reservoir(gas)

# Create a heat-conducting wall between the reactor and the environment. Set its
# area, and its overall heat transfer coefficient. Larger U causes the reactor
# to be closer to isothermal. If U is too small, the gas ignites, and the
# temperature spikes and stays high.
w = ct.Wall(cstr, env, A=1.0, U=0.02)

# Connect the upstream reservoir to the reactor with a mass flow controller
# (constant mdot). Set the mass flow rate to 1.25 sccm.
sccm = 1.25
vdot = sccm * 1.0e-6 / 60.0 * (
    (ct.one_atm / gas.P) * (gas.T / 273.15))  # m^3/s
mdot = gas.density * vdot  # kg/s
mfc = ct.MassFlowController(upstream, cstr, mdot=mdot)

# now create a downstream reservoir to exhaust into.
downstream = ct.Reservoir(gas)

# connect the reactor to the downstream reservoir with a valve, and set the
# coefficient sufficiently large to keep the reactor pressure close to the
# downstream pressure of 60 Torr.
コード例 #20
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
コード例 #21
0
ファイル: Cantera.py プロジェクト: swiderskia/MKWS2020
gas.TPX = 1000, 1*ct.one_atm, 'CH4:1, O2:2, N2:7.52'

# reactor to represent the cylinder filled with gas
r = ct.IdealGasReactor(gas)
r.volume = 1.0

sim = ct.ReactorNet([r])

time = 0.0  # initial time
states = ct.SolutionArray(gas, extra=['t'])

# implementation of heater that gives constant heat
heater_gas = ct.Solution('gri30.xml')
heater_gas.TPX = 1000, ct.one_atm, 'H2:2,O2:1'
heater = ct.Reservoir(heater_gas)
w = ct.Wall(heater, r, A=1.0, K=0, U=0, Q=1000000000, velocity=0)

time_step = 1.e-6

print('%10s %10s %10s %14s' % ('t [s]','T [K]','P [Pa]','u [J/kg]'))
for n in range(100):
    time += time_step
    sim.advance(time)
    states.append(r.thermo.state, t=time*1e3)
    plt.clf()

    plt.subplot(2, 2, 1)
    plt.plot(states.t, states.T)
    plt.xlabel('Time (ms)')
    plt.ylabel('Temperature (K)')
コード例 #22
0
ファイル: RCM.py プロジェクト: markbarbet/MSI
    def run(self, initialTime: float = -1.0, finalTime: float = -1.0):
        '''
        Run the shock tube simulation
        '''

        #p_alpha = meq.Master_Equation.chebyshev_specific_poly(self,l,meq.Master_Equation.calc_reduced_P(self,target_press_new*101325))
        if self.exact_deriv_flag == False:
            inp_time = self.volume_trace_class.time
            inp_vol = self.volume_trace_class.volume
        if self.exact_deriv_flag == True:
            inp_time = self.volume_trace_class_exact_derivitive.time
            inp_vol = self.volume_trace_class_exact_derivitive.volume

        if initialTime == -1.0:
            initialTime = self.initialTime
        if finalTime == -1.0:
            finalTime = self.finalTime
        self.timeHistory = None
        self.kineticSensitivities = None  #3D numpy array, columns are reactions with timehistories, depth gives the observable for those histories
        conditions = self.settingRCMConditions()
        mechanicalBoundary = conditions[1]
        #same solution for both cp and cv sims

        if mechanicalBoundary == 'constant pressure':

            print('RCM is not a constant pressure simulation')
        else:
            if self.exact_deriv_flag == False:
                RCM = ct.IdealGasReactor(self.processor.solution)
                env = ct.Reservoir(ct.Solution('air.xml'))
                wall = ct.Wall(RCM,
                               env,
                               A=1.0,
                               velocity=self.volume_trace_class)
                sim = ct.ReactorNet([RCM])
                sim.set_max_time_step(inp_time[1])

            if self.exact_deriv_flag == True:
                RCM = ct.IdealGasReactor(self.processor.solution)
                env = ct.Reservoir(ct.Solution('air.xml'))
                wall = ct.Wall(
                    RCM,
                    env,
                    A=1.0,
                    velocity=self.volume_trace_class_exact_derivitive)
                sim = ct.ReactorNet([RCM])
                sim.set_max_time_step(inp_time[1])

        sim.rtol = self.rtol
        sim.atol = self.atol
        sim.rtol_sensitivity = self.rtol_sensitivity
        sim.atol_sensitivity = self.atol_sensitivity

        columnNames = [RCM.component_name(item) for item in range(RCM.n_vars)]
        columnNames = ['time'] + ['pressure'] + columnNames
        self.timeHistory = pd.DataFrame(columns=columnNames)

        if self.kineticSens == 1:
            for i in range(self.processor.solution.n_reactions):
                RCM.add_sensitivity_reaction(i)
            dfs = [pd.DataFrame() for x in range(len(self.observables))]
            tempArray = [
                np.zeros(self.processor.solution.n_reactions)
                for x in range(len(self.observables))
            ]

        t = self.initialTime
        counter = 0
        #print(sim.rtol_sensitivity,sim.atol_sensitivity)

        vol_sol = ct.SolutionArray(self.processor.solution,
                                   extra=["time", "volume"])

        self.vol_sol = vol_sol

        #while t < self.finalTime and RCM.T < 2500:
        #should we have this temperature limiting factor?
        #while t < self.finalTime and RCM.T<2500:
        while t < self.finalTime:
            t = sim.step()
            #print(t)
            if mechanicalBoundary == 'constant volume':
                state = np.hstack([
                    t, RCM.thermo.P, RCM.mass, RCM.volume, RCM.T, RCM.thermo.X
                ])
                #vol_sol.append(time=sim.time, T=RCM.T, P=RCM.thermo.P, X=RCM.thermo.X, volume=RCM.volume)
                #t = sim.step()
            else:
                print('RCM has variable volume')

            self.timeHistory.loc[counter] = state
            if self.kineticSens == 1:
                counter_1 = 0
                for observable, reaction in itertools.product(
                        self.observables,
                        range(self.processor.solution.n_reactions)):
                    tempArray[self.observables.index(
                        observable)][reaction] = sim.sensitivity(
                            observable, reaction)
                    counter_1 += 1
                    if counter_1 % self.processor.solution.n_reactions == 0:
                        dfs[self.observables.index(observable)] = dfs[
                            self.observables.index(observable)].append(
                                ((pd.DataFrame(
                                    tempArray[self.observables.index(
                                        observable)])).transpose()),
                                ignore_index=True)
            counter += 1

        #temp_v = pd.DataFrame()
        #temp_v['velocity'] = np.array(self.volume_trace_class.velocity_list_temp)
        #temp_v['time']= self.timeHistory['time']
        #temp_v.to_csv('/Users/carlylagrotta/Dropbox/Columbia/MSI/data/DME-Methanol_Blends_RCM/time_history_velocity_test/velocity_unrefined.csv',index=False)

        if self.timeHistories != None:

            self.timeHistory.time = self.timeHistory.time + self.time_shift_value
            #self.timeHistory.time = self.timeHistory.time + 0

            self.timeHistories.append(self.timeHistory)
            #print(self.timeHistory)
            ############################################################

        if self.kineticSens == 1:
            numpyMatrixsksens = [
                dfs[dataframe].values for dataframe in range(len(dfs))
            ]
            self.kineticSensitivities = np.dstack(numpyMatrixsksens)
            return self.timeHistory, self.kineticSensitivities
        else:
            import matplotlib.pyplot as plt
            #plt.figure()
            #plt.plot(self.timeHistory['time'],self.timeHistory['pressure']/100000)
            return self.timeHistory
コード例 #23
0
gas.TPX = Tin, p, comp
mdot = vin * area * gas.density
dx = length / n_reactor

#r = ct.IdealGasReactor(gas)
r = ct.Reactor(gas)  # since water is not ideal gas
r.volume = area * dx

upstream = ct.Reservoir(gas, name='upstream')
downstream = ct.Reservoir(gas, name='downstream')
m = ct.MassFlowController(upstream, r, mdot=mdot)
v = ct.PressureController(r, downstream, master=m, K=1.0e-5)

gas.TPX = Tout, p, comp
outer = ct.Reservoir(gas)
wall = ct.Wall(outer, r, U=ht)
wall.area = area_wall / n_reactor

sim = ct.ReactorNet([r])

# solve
outfile = open('wall_heat_transfer.csv', 'w', newline='')
writer = csv.writer(outfile)
writer.writerow(['Distance (m)', 'u(m/s)', 'rtime(s)', 'T(K)', 'P(Pa)'] +
                gas.species_names)

t_res = 0.0
for n in range(n_reactor):
    gas.TDY = r.thermo.TDY
    upstream.syncState()
    sim.reinitialize()
コード例 #24
0
import cantera as ct

gri3 = ct.Solution('gri30.xml')
temp = 1500.0
pres = ct.one_atm

gri3.TPX = temp, pres, 'CH4:0.1, O2:2, N2:7.52'
r = ct.Reactor(gri3)

air = ct.Solution('air.xml')
air.TP = temp, pres
env = ct.Reservoir(air)

# Define a wall between the reactor and the environment, and make it flexible,
# so that the pressure in the reactor is held at the environment pressure.
w = ct.Wall(r, env)
w.expansion_rate_coeff = 1.0e6  # set expansion parameter. dV/dt = KA(P_1 - P_2)
w.area = 1.0

sim = ct.ReactorNet([r])

# enable sensitivity with respect to the rates of the first 10
# reactions (reactions 0 through 9)
for i in range(10):
    r.add_sensitivity_reaction(i)

# set the tolerances for the solution and for the sensitivity coefficients
sim.rtol = 1.0e-6
sim.atol = 1.0e-15
sim.rtol_sensitivity = 1.0e-6
sim.atol_sensitivity = 1.0e-6
コード例 #25
0
ファイル: custom2.py プロジェクト: ischoegl/cantera
    def before_component_name(self, i):
        # Other components are handled by the method from the base Reactor class
        if i == self.i_wall:
            return 'v_wall'


gas = ct.Solution('h2o2.yaml')

# Initial condition
P = ct.one_atm
gas.TPY = 920, P, 'H2:1.0, O2:1.0, N2:3.76'

# Set up the reactor network
res = ct.Reservoir(gas)
r = InertialWallReactor(gas, neighbor=res)
w = ct.Wall(r, res)
net = ct.ReactorNet([r])

# Integrate the equations, keeping T(t) and Y(k,t)
states = ct.SolutionArray(gas, 1, extra={'t': [0.0], 'V': [r.volume]})
while net.time < 0.5:
    net.advance(net.time + 0.005)
    states.append(TPY=r.thermo.TPY, V=r.volume, t=net.time)

# Plot the results
try:
    import matplotlib.pyplot as plt
    L1 = plt.plot(states.t, states.T, color='r', label='T', lw=2)
    plt.xlabel('time (s)')
    plt.ylabel('Temperature (K)')
    plt.twinx()
コード例 #26
0
# To effect the volume change, instances of `Wall`s can be installed between two Cantera reactors. 
# =============================================================================
# In this case, we only care about reactions and changes in the reactor representing the RCM reaction chamber, 
# so we install a `Wall` between the `IdealGasReactor` and a `Reservoir`, which represents the environment. 
# Then we specify the `VolumeProfile` class as the means to calculate the velocity. 
# Other options would be a constant value, or a function that takes a single argument (the simulation time). 
# With the velocity defined and the `Wall` installed, the simulation can proceed as before.
# =============================================================================

# In[13]:


reac = ct.IdealGasReactor(gas)
env = ct.Reservoir(ct.Solution('air.xml'))
wall = ct.Wall(reac, env, A=1.0, velocity=vpro)
netw = ct.ReactorNet([reac])
netw.set_max_time_step(inp_time[1])

vol_sol = ct.SolutionArray(gas, extra=["time", "volume"])
# End the simulation when the temperature exceeds 2500 K or the time reaches 0.1 s
while reac.T < 2500 and netw.time < 0.1:
    vol_sol.append(time=netw.time, T=reac.T, P=reac.thermo.P, X=reac.thermo.X, volume=reac.volume)
    netw.step()


# We can compare a number of parameters between the simulation and experiment. 
# =============================================================================
# First, we can compare the volume that is read from the input file to the simulated volume of the reactor as a function of time. 
# Remember that we did not specify the volume of the reactor directly, 
# instead we specified it through the velocity. 
コード例 #27
0
ファイル: main.py プロジェクト: Wenbin-Xu/PSR-droplet
def execute():
    #==============================================================================
#     set up the cantera gases and reactors
#==============================================================================
    drop = droplet(50e-6, 'A2', 300, 1) #drop is defined only to use the drop properties
    #environment air
    gas_env = ct.Solution('a2.cti')
    gas_env.TPX = 300, ct.one_atm, 'O2:29,N2:71'

    gas_fuel = ct.Solution('a2.cti')
    gas_fuel.TPX = drop.ABP, ct.one_atm, 'POSF10325:1' #gaseous fuel at average boiling temperature

    gas_kernel = ct.Solution('a2.cti')
    gas_kernel.TPX = 4000, ct.one_atm, 'O2:29,N2:71'
    gas_kernel.equilibrate('HP')
    
    res_air = ct.Reservoir(gas_env)
    res_fuel = ct.Reservoir(gas_fuel)
    kernel = ct.IdealGasConstPressureReactor(gas_kernel)
    kernel.volume = 2.4e-8 #m^3

    mfc1 = ct.MassFlowController(res_air, kernel) #connect air reservoir to kernel
    mfc2 = ct.MassFlowController(res_fuel, kernel) #connect fuel reservoir to kernel

    mfc1.set_mass_flow_rate(6e-5)
    mfc2.set_mass_flow_rate(0)

    w = ct.Wall(kernel, res_fuel)
    w.set_heat_flux(0)
    w.expansion_rate_coeff = 1e8

    net = ct.ReactorNet({kernel})
    net.atol = 1e-10 #absolute tolerance
    net.rtol = 1e-10 #relative tolerance
#==============================================================================
#   endtime, time steps, and data to be stored    
#==============================================================================
    dt = 1e-6 #change time step for advancing the reactor
    endtime = 1000e-6
    mdot_fuel = 1.98e-6 #this number should be calculated based on equivalence ratio, kg/s
    
    droplets = []
    T = []
    time = []
    m = []
    m_dot = []
    q_dot = []
    droplet_count = []
    X_fuel = []
    X_O = []
    X_CO2 = []
    num_d = []
    
#==============================================================================
#     advance reaction
#==============================================================================
    print("Running simulation")
    for i in range(1,int(endtime/dt)):
        print (int(endtime/dt) - i)
        #entrain droplets every 1 microsecond
        droplets.extend(entrainer(400, 5.*mdot_fuel))  
        mdot, qdot = vaporize(gas_kernel.T, droplets, dt)
        
#        print(gas_kernel.T, mdot, qdot, len(droplets))
#        print(str(mdot) + str(qdot) + str(gas_kernel.T)+'  '+str(len(droplets)))
        mfc2.set_mass_flow_rate(mdot)
        w.set_heat_flux(qdot) #heat required to heat up the droplets during that time step
        
        net.advance(i*dt)
        
        num_d.append(len(droplets))
        #storing variables
        T.append(gas_kernel.T)
        time.append(net.time)
        m.append(kernel.mass)
        m_dot.append(mdot)
        q_dot.append(qdot)
        droplet_count.append(len(droplets))
        if gas_kernel.X[0] < 0:
            gas_kernel.X[0] = 0
        X_fuel.append(gas_kernel.X[gas_kernel.species_index("POSF10325")])
        X_O.append(gas_kernel.X[gas_kernel.species_index("O")])
        X_CO2.append(gas_kernel.X[gas_kernel.species_index("CO2")])
        
#==============================================================================
#   plotting important information      
#==============================================================================
    plt.plot([t*1e3 for t in time],T, linewidth=3)
    plt.xlabel('time(ms)', FontSize=15)
    plt.ylabel('Temperature (K)', FontSize=15)
    plt.show()
    
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ax1.plot([t*1e3 for t in time], X_fuel, color = 'red', linewidth = 3)
    ax1.set_xlabel('time (ms)', FontSize=15)
    ax1.set_ylabel('X_fuel', color='red', FontSize=15)
#    ax2.plot([t*1e3 for t in time], X_O, color = 'green', linewidth = 3)
    ax2.set_ylabel('X_CO2', color='green', FontSize=15)
    ax2.plot([t*1e3 for t in time], X_CO2, color = 'blue', linewidth = 3)
    plt.show()
    
    fig, ax1 = plt.subplots()
    ax2 = ax1.twinx()
    ax1.plot([t*1e3 for t in time], m_dot, color = 'red', linewidth = 3)
    ax1.set_xlabel('time (ms)', FontSize=15)
    ax1.set_ylabel('m_dot', color='red', FontSize=15)
    ax2.plot([t*1e3 for t in time], q_dot, color = 'green', linewidth = 3)
    ax2.set_ylabel('q_dot', color='green', FontSize=15)
    plt.show()
    
    fig,ax1 = plt.subplots()
    ax1.plot([t*1e3 for t in time], num_d, linewidth=3)
    ax1.set_xlabel('time(ms)', FontSize=15)
    ax1.set_ylabel('#droplets', FontSize=15)
    plt.show()
コード例 #28
0
ファイル: simulation.py プロジェクト: AdamKrivoshein/PyTeCK
    def setup_case(self, model_file, species_key, path=''):
        """Sets up the simulation case to be run.

        :param str model_file: Filename for Cantera-format model
        :param dict species_key: Dictionary with species names for `model_file`
        :param str path: Path for data file
        """

        self.gas = ct.Solution(model_file)

        # Convert ignition delay to seconds
        self.properties.ignition_delay.ito('second')

        # Set end time of simulation to 100 times the experimental ignition delay
        self.time_end = 100. * self.properties.ignition_delay.magnitude

        # Initial temperature needed in Kelvin for Cantera
        self.properties.temperature.ito('kelvin')

        # Initial pressure needed in Pa for Cantera
        self.properties.pressure.ito('pascal')

        # convert reactant names to those needed for model
        reactants = [species_key[spec['species-name']] + ':' + str(spec['amount'].magnitude)
                     for spec in self.properties.composition
                     ]
        reactants = ','.join(reactants)

        # Reactants given in format for Cantera
        if self.properties.composition_type in ['mole fraction', 'mole percent']:
            self.gas.TPX = (self.properties.temperature.magnitude,
                            self.properties.pressure.magnitude,
                            reactants
                            )
        elif self.properties.composition_type == 'mass fraction':
            self.gas.TPY = (self.properties.temperature.magnitude,
                            self.properties.pressure.magnitude,
                            reactants
                            )
        else:
            raise(BaseException('error: not supported'))
            return

        # Create non-interacting ``Reservoir`` on other side of ``Wall``
        env = ct.Reservoir(ct.Solution('air.xml'))

        # All reactors are ``IdealGasReactor`` objects
        self.reac = ct.IdealGasReactor(self.gas)
        if self.apparatus == 'shock tube' and self.properties.pressure_rise is None:
            # Shock tube modeled by constant UV
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)

        elif self.apparatus == 'shock tube' and self.properties.pressure_rise is not None:
            # Shock tube modeled by constant UV with isentropic compression

            # Need to convert pressure rise units to seconds
            self.properties.pressure_rise.ito('1 / second')

            self.wall = ct.Wall(self.reac, env, A=1.0,
                                velocity=PressureRiseProfile(
                                    model_file,
                                    self.gas.T,
                                    self.gas.P,
                                    self.gas.X,
                                    self.properties.pressure_rise.magnitude,
                                    self.time_end
                                    )
                                )

        elif (self.apparatus == 'rapid compression machine' and
              self.properties.volume_history is None
              ):
            # Rapid compression machine modeled by constant UV
            self.wall = ct.Wall(self.reac, env, A=1.0, velocity=0)

        elif (self.apparatus == 'rapid compression machine' and
              self.properties.volume_history is not None
              ):
            # Rapid compression machine modeled with volume-time history

            # First convert time units if necessary
            self.properties.volume_history.time.ito('second')

            self.wall = ct.Wall(self.reac, env, A=1.0,
                                velocity=VolumeProfile(self.properties.volume_history)
                                )

        # Number of solution variables is number of species + mass,
        # volume, temperature
        self.n_vars = self.reac.kinetics.n_species + 3

        # Create ``ReactorNet`` newtork
        self.reac_net = ct.ReactorNet([self.reac])

        # Set maximum time step based on volume-time history, if present
        if self.properties.volume_history is not None:
            # Minimum difference between volume profile times
            min_time = numpy.min(numpy.diff(self.properties.volume_history.time.magnitude))
            self.reac_net.set_max_time_step(min_time)

        # Check if species ignition target, that species is present.
        if self.properties.ignition_type['target'] not in ['pressure', 'temperature']:
            # Other targets are species
            spec = self.properties.ignition_type['target']

            # Try finding species in upper- and lower-case
            try_list = [spec, spec.lower()]

            # If excited radical, may need to fall back to nonexcited species
            if spec[-1] == '*':
                try_list += [spec[:-1], spec[:-1].lower()]

            ind = None
            for sp in try_list:
                try:
                    ind = self.gas.species_index(sp)
                    break
                except ValueError:
                    pass

            if ind:
                self.properties.ignition_target = ind
                self.properties.ignition_type = self.properties.ignition_type['type']
            else:
                print('Warning: ' + spec + ' not found in model; '
                      'falling back on pressure.'
                      )
                self.properties.ignition_target = 'pressure'
                self.properties.ignition_type = 'd/dt max'
        else:
            self.properties.ignition_target = self.properties.ignition_type['target']
            self.properties.ignition_type = self.properties.ignition_type['type']

        # Set file for later data file
        file_path = os.path.join(path, self.meta['id'] + '.h5')
        self.meta['save-file'] = file_path
コード例 #29
0
ファイル: reactor2.py プロジェクト: Althenor/Cantera
# use GRI-Mech 3.0 for the methane/air mixture, and set its initial state
gas = ct.Solution('gri30.xml')
gas.TP = 500.0, 0.2 * ct.one_atm
gas.set_equivalence_ratio(1.1, 'CH4:1.0', 'O2:2, N2:7.52')

# create a reactor for the methane/air side
r2 = ct.IdealGasReactor(gas)

#-----------------------------------------------------------------------------
# Now couple the reactors by defining common walls that may move (a piston) or
# conduct heat
#-----------------------------------------------------------------------------

# add a flexible wall (a piston) between r2 and r1
w = ct.Wall(r2, r1, A=1.0, K=0.5e-4, U=100.0)

# heat loss to the environment. Heat loss always occur through walls, so we
# create a wall separating r1 from the environment, give it a non-zero area,
# and specify the overall heat transfer coefficient through the wall.
w2 = ct.Wall(r2, env, A=1.0, U=500.0)

sim = ct.ReactorNet([r1, r2])

# Now the problem is set up, and we're ready to solve it.
print('finished setup, begin solution...')

time = 0.0
n_steps = 300
outfile = open('piston.csv', 'w')
csvfile = csv.writer(outfile)
コード例 #30
0
inlet = ct.Reservoir(gas)
# define injector state (gaseous!)
gas.TPX = T_injector, p_injector, comp_injector
injector = ct.Reservoir(gas)
# define outlet pressure (temperature and composition don't matter)
gas.TPX = T_ambient, p_outlet, comp_ambient
outlet = ct.Reservoir(gas)
# define ambient pressure (temperature and composition don't matter)
gas.TPX = T_ambient, p_ambient, comp_ambient
ambient_air = ct.Reservoir(gas)

# set up connecting devices
inlet_valve = ct.Valve(inlet, r)
injector_mfc = ct.MassFlowController(injector, r)
outlet_valve = ct.Valve(r, outlet)
piston = ct.Wall(ambient_air, r)

# convert time to crank angle
def crank_angle(t):
    return np.remainder(2 * np.pi * f * t, 4 * np.pi)

# set up IC engine parameters
V_oT = V_H / (epsilon - 1.)
A_piston = .25 * np.pi * d_piston ** 2
stroke = V_H / A_piston
r.volume = V_oT
piston.area = A_piston
def piston_speed(t):
    return - stroke / 2 * 2 * np.pi * f * np.sin(crank_angle(t))
piston.set_velocity(piston_speed)