Ejemplo n.º 1
0
def solve(gas, t):
    # Set the temperature and pressure for gas
    # t is different from t0
    gas.TPX = t, pressure, composition
    surf.TP = t, pressure
    TDY = gas.TDY
    cov = surf.coverages

    # create a new reactor
    gas.TDY = TDY
    r = ct.IdealGasReactor(gas, energy='on')
    r.volume = rvol

    upstream = ct.Reservoir(gas, name='upstream')
    downstream = ct.Reservoir(gas, name='downstream')
    rsurf = ct.ReactorSurface(surf, r, A=cat_area)
    m = ct.MassFlowController(upstream, r, mdot=mass_flow_rate)

    v = ct.PressureController(r, downstream, master=m, K=1e-5)

    sim = ct.ReactorNet([r])
    sim.max_err_test_fails = 20
    sim.rtol = 1.0e-9
    sim.atol = 1.0e-21

    # define time, space, and other information vectors
    z2 = (np.arange(NReactors)) * rlen * 1e3

    t_r2 = np.zeros_like(z2)  # residence time in each reactor

    t2 = np.zeros_like(z2)
    states2 = ct.SolutionArray(gas)

    for n in range(NReactors):
        # Set the state of the reservoir to match that of the previous reactor
        gas.TDY = r.thermo.TDY
        upstream.syncState()
        sim.reinitialize()

        sim.advance_to_steady_state()
        dist = n * rlen * 1.0e3  # distance in mm

        t_r2[n] = r.mass / mass_flow_rate  # residence time in this reactor
        t2[n] = np.sum(t_r2)
        states2.append(gas.state)
    print('Temperature of Gas :', t, ' residence time :', t2[-1])
    MolFrac_CH4 = states2('CH4').X
    MolFrac_CO2 = states2('CO2').X
    MolFrac_CO = states2('CO').X
    MolFrac_H2 = states2('H2').X
    MolFrac_H2O = states2('H2O').X
    MolFrac_O2 = states2('O2').X
    kq = np.zeros(6)
    kq[0] = MolFrac_CH4[-1] * 100
    kq[1] = MolFrac_CO2[-1] * 100
    kq[2] = MolFrac_CO[-1] * 100
    kq[3] = MolFrac_H2[-1] * 100
    kq[4] = MolFrac_H2O[-1] * 100
    kq[5] = MolFrac_O2[-1] * 100
    return kq
Ejemplo n.º 2
0
    def setup(self, T0, P0, mdot_fuel, mdot_ox):

        self.gas = ct.Solution('gri30.xml')

        # fuel inlet
        self.gas.TPX = T0, P0, "CH4:1.0"
        self.fuel_in = ct.Reservoir(self.gas)

        # oxidizer inlet
        self.gas.TPX = T0, P0, "N2:3.76, O2:1.0"
        self.oxidizer_in = ct.Reservoir(self.gas)

        # reactor, initially filled with N2
        self.gas.TPX = T0, P0, "N2:1.0"
        self.combustor = ct.IdealGasReactor(self.gas)
        self.combustor.volume = 1.0

        # outlet
        self.exhaust = ct.Reservoir(self.gas)

        # connect the reactor to the reservoirs
        self.fuel_mfc = ct.MassFlowController(self.fuel_in, self.combustor)
        self.fuel_mfc.set_mass_flow_rate(mdot_fuel)
        self.oxidizer_mfc = ct.MassFlowController(self.oxidizer_in, self.combustor)
        self.oxidizer_mfc.set_mass_flow_rate(mdot_ox)
        self.valve = ct.Valve(self.combustor, self.exhaust)
        self.valve.set_valve_coeff(1.0)

        self.net = ct.ReactorNet()
        self.net.add_reactor(self.combustor)
        self.net.max_err_test_fails = 10
Ejemplo n.º 3
0
 def run_single(self):
     
     gas=self.processor.solution
     reactorPressure=gas.P
     self.reactorPressure=self.processor.solution.P
     pressureValveCoefficient=self.pvalveCoefficient
     maxPressureRiseAllowed=self.maxPrise
     
     print(maxPressureRiseAllowed,self.reactorPressure,pressureValveCoefficient)
     #Build the system components for JSR
     fuelAirMixtureTank=ct.Reservoir(self.processor.solution)
     exhaust=ct.Reservoir(self.processor.solution)
     
     stirredReactor=ct.IdealGasReactor(self.processor.solution,energy=self.energycon,volume=self.reactor_volume)
     massFlowController=ct.MassFlowController(upstream=fuelAirMixtureTank,
                                              downstream=stirredReactor,mdot=stirredReactor.mass/self.residence_time)
     pressureRegulator=ct.Valve(upstream=stirredReactor,downstream=exhaust,K=pressureValveCoefficient)
     reactorNetwork=ct.ReactorNet([stirredReactor])
     
     if bool(self.observables) and self.kineticSens==1:
         for i in range(gas.n_reactions):
             stirredReactor.add_sensitivity_reaction(i)
         
     if self.kineticSens and bool(self.observables)==False:
         #except:
             print('Please supply a non-empty list of observables for sensitivity analysis or set kinetic_sens=0')
     if self.physicalSens==1 and bool(self.observables)==False:
def runSinglePSR(T, P, moleFraction, factor, reactionIndex, targetSpc):

    start = time.time()

    # create the gas mixture
    gas = ct.Solution('HXD15_Battin_mech.xml')
    gas.TPX = T, P, moleFraction

    # create an upstream reservoir that will supply the reactor. The temperature,
    # pressure, and composition of the upstream reservoir are set to those of the
    # 'gas' object at the time the reservoir is created.
    upstream = ct.Reservoir(gas)

    # Now create the reactor object with the same initial state
    cstr = ct.IdealGasReactor(gas)

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

    # Connect the upstream reservoir to the reactor with a mass flow controller
    # (constant mdot). Set the mass flow rate.
    vdot = 40* 1.0e-6 # 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.
    v = ct.Valve(cstr, downstream, K=1.0e-9)

    # create the network
    network = ct.ReactorNet([cstr])

    # modify the A factor of the given reaction
    gas.set_multiplier(factor,reactionIndex-1)

    # now integrate in time
    t = 0.0
    dt   = 0.1

    print "\n\n\n**************************\n***** Solving case %d *****\n"%(reactionIndex)

    while t < 30.0:
        print t
        t += dt
        network.advance(t)

    results = []
    for spc in targetSpc:
        results.append(cstr.thermo[spc].X[0]*1.0e6)

    end = time.time()
    print 'Execution time is:'
    print end - start

    return [gas.reaction_equation(reactionIndex-1)] + results
Ejemplo n.º 5
0
    def setUp(self):
        self.gas = ct.Solution('h2o2.xml')

        # create a reservoir for the fuel inlet, and set to pure methane.
        self.gas.TPX = 300.0, ct.one_atm, 'H2:1.0'
        fuel_in = ct.Reservoir(self.gas)
        fuel_mw = self.gas.mean_molecular_weight

        # Oxidizer inlet
        self.gas.TPX = 300.0, ct.one_atm, 'O2:1.0, AR:3.0'
        oxidizer_in = ct.Reservoir(self.gas)
        oxidizer_mw = self.gas.mean_molecular_weight

        # to ignite the fuel/air mixture, we'll introduce a pulse of radicals.
        # The steady-state behavior is independent of how we do this, so we'll
        # just use a stream of pure atomic hydrogen.
        self.gas.TPX = 300.0, ct.one_atm, 'H:1.0'
        self.igniter = ct.Reservoir(self.gas)

        # create the combustor, and fill it in initially with a diluent
        self.gas.TPX = 300.0, ct.one_atm, 'AR:1.0'
        self.combustor = ct.IdealGasReactor(self.gas)

        # create a reservoir for the exhaust
        self.exhaust = ct.Reservoir(self.gas)

        # compute fuel and air mass flow rates
        factor = 0.1
        oxidizer_mdot = 4 * factor * oxidizer_mw
        fuel_mdot = factor * fuel_mw

        # The igniter will use a time-dependent igniter mass flow rate.
        def igniter_mdot(t, t0=0.1, fwhm=0.05, amplitude=0.1):
            return amplitude * math.exp(
                -(t - t0)**2 * 4 * math.log(2) / fwhm**2)

        # create and install the mass flow controllers. Controllers
        # m1 and m2 provide constant mass flow rates, and m3 provides
        # a short Gaussian pulse only to ignite the mixture
        m1 = ct.MassFlowController(fuel_in, self.combustor, mdot=fuel_mdot)
        m2 = ct.MassFlowController(oxidizer_in,
                                   self.combustor,
                                   mdot=oxidizer_mdot)
        m3 = ct.MassFlowController(self.igniter,
                                   self.combustor,
                                   mdot=igniter_mdot)

        # put a valve on the exhaust line to regulate the pressure
        self.v = ct.Valve(self.combustor, self.exhaust, K=1.0)

        # the simulation only contains one reactor
        self.sim = ct.ReactorNet([self.combustor])
Ejemplo n.º 6
0
def cstr0(self, F, P, V, T=None, dt=2.0, t=None, disp=0):
    # mix streams if there is more than one
    self, F = mixer(self, F)
    # set initial conditions
    self.TP = T, P
    # create a new reactor
    if T == None or T == 0:
        r = ct.IdealGasReactor(self, energy='on')
    else:
        r = ct.IdealGasReactor(self, energy='off')
    r.volume = V
    # create up and downstream reservoirs
    upstream = ct.Reservoir(self)
    downstream = ct.Reservoir(self)
    # set mass flow into reactor
    m = ct.MassFlowController(upstream, r, mdot=F)
    # set valve to hold pressure constant
    ct.PressureController(r, downstream, master=m, K=1e-5)
    # create reactor network
    s = ct.ReactorNet([r])
    s.rtol, s.atol, s.max_err_test_fails = rel_tol, abs_tol, test_fails
    # set parameters
    time = 0
    residual = 1
    all_done = False
    # forces reinitialization
    s.set_initial_time(0)
    while not all_done:
        Yo = r.thermo.Y
        To = r.thermo.T
        try:
            time += dt
            s.advance(time)
        except:
            dt *= 0.1
            time += dt
            s.advance(time)
        if t != None and time >= t: all_done = False
        if time > 10 * dt:
            all_done = True
            residual = slope(Yo, r.thermo.Y, dt)
            if T == None:
                residual = np.max(np.append(residual,slope(To,r.thermo.T,dt)))
            if residual > rel_tol:
                all_done = False
                break
        if disp == True: print 'Residual: %1.3e' %(residual)
    return self, time, residual
Ejemplo n.º 7
0
    def test_mass_flow_controller(self):
        self.makeReactors(nReactors=1)
        gas2 = ct.Solution('h2o2.xml')
        gas2.TPX = 300, 10*101325, 'H2:1.0'
        reservoir = ct.Reservoir(gas2)

        mfc = ct.MassFlowController(reservoir, self.r1)
        mfc.setMassFlowRate(lambda t: 0.1 if 0.2 <= t < 1.2 else 0.0)

        self.assertEqual(len(reservoir.inlets), 0)
        self.assertEqual(len(reservoir.outlets), 1)
        self.assertEqual(reservoir.outlets[0], mfc)
        self.assertEqual(len(self.r1.outlets), 0)
        self.assertEqual(len(self.r1.inlets), 1)
        self.assertEqual(self.r1.inlets[0], mfc)

        ma = self.r1.volume * self.r1.density
        Ya = self.r1.Y

        self.net.advance(2.5)

        mb = self.r1.volume * self.r1.density
        Yb = self.r1.Y

        self.assertNear(ma + 0.1, mb)
        self.assertArrayNear(ma * Ya + 0.1 * gas2.Y, mb * Yb)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
def def_reactors(z, zone, temp0, p0, mechanism, mixture):
    """
    Defines reactors
         
    Returns
    -------
    r : List of Cantera Reactor objects
    env: Cantera Reservoir object
    contents: List of Cantera solution objects corresponding to content 
              of each reactor
    """

    gas = ct.Solution(mechanism)
    gas.TPX = temp0, p0, mixture
    gas.transport_model = 'Multi'

    env = ct.Reservoir(ct.Solution(mechanism))

    contents = [0]
    for x in range(1, z + 1):
        contents.append(gas)

    r = [ct.IdealGasReactor(gas)]
    for x in range(1, z + 1):
        r.append(ct.IdealGasReactor(contents[x], volume=zone[x].volume))

    return r, env, contents
Ejemplo n.º 10
0
Archivo: engines.py Proyecto: 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])
Ejemplo n.º 11
0
    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])
Ejemplo n.º 12
0
Archivo: psr.py Proyecto: WayneYann/GPS
def psr_ss(soln_in, soln_out, p, T0, T, X0, X, tau):

    #sys.stdout.flush()

    """
    find the steady state of a PSR

    :param mech:    mechanism
    :param p:       pressure (Pa)
    :param T0:      temperature (K) of the inlet flow
    :param T:       initial temperature (K) of the reactor
    :param tau:     residence time (s) of the reactor

    :return reactor:

    """

    vol = 1.0     # unit: m3
    K = 1.0
    t_end = tau * 100.0

    #print 't_end = '+str(t_end)

    soln_out.TPX = T, p, X
    soln_in.TPX = T0, p, X0

    inlet = ct.Reservoir(soln_in)
    reactor = ct.IdealGasReactor(soln_out)
    reactor.volume = vol

    vdot = vol/tau
    mdot = soln_out.density * vdot
    mfc = ct.MassFlowController(inlet, reactor, mdot=mdot)

    exhaust = ct.Reservoir(soln_out)
    valve = ct.Valve(reactor, exhaust, K=K)

    network = ct.ReactorNet([reactor])
    try:
        network.advance(t_end)
    except RuntimeError as e:

        print '@'*10+'\nct.exceptions = \n'+str(e)
        #sys.exit()
        return None

    return soln_out
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    def test_valve_errors(self):
        self.make_reactors()
        res = ct.Reservoir()

        with self.assertRaises(ct.CanteraError):
            # Must assign contents of both reactors before creating Valve
            v = ct.Valve(self.r1, res)

        v = ct.Valve(self.r1, self.r2)
        with self.assertRaises(ct.CanteraError):
            # inlet and outlet cannot be reassigned
            v._install(self.r2, self.r1)
Ejemplo n.º 15
0
 def createReactors(self):
     """Use this function to create exhaust stream network"""
     #Creating fuel reservoir
     self.fuel.equilibrate('HP')
     self.fuelReservoir = ct.Reservoir(contents=self.fuel, name='fuel')
     #Creating combustor
     self.reactors = ct.ConstPressureReactor(contents=self.fuel,
                                             name='combustor',
                                             energy='on'),
     #Creating exhaust reactors
     exCycle = it.cycle(self.exhausts)
     self.reactors += tuple([
         ct.ConstPressureReactor(contents=next(exCycle),
                                 name='exhaust{}'.format(i),
                                 energy='on') for i in range(self.nex)
     ])
     #Creating atomspheric reactor
     self.atmosReservoir = ct.Reservoir(contents=self.atmosphere,
                                        name='atmosphere')
     self.exhaustReservoir = ct.Reservoir(contents=self.atmosphere,
                                          name='exhaust')
Ejemplo n.º 16
0
    def test_pressure_controller(self):
        self.makeReactors(nReactors=1)
        g = ct.Solution('h2o2.xml')
        g.TPX = 500, 2*101325, 'H2:1.0'
        inletReservoir = ct.Reservoir(g)
        g.TP = 300, 101325
        outletReservoir = ct.Reservoir(g)

        mfc = ct.MassFlowController(inletReservoir, self.r1)
        mdot = lambda t: np.exp(-100*(t-0.5)**2)
        mfc.setMassFlowRate(mdot)

        pc = ct.PressureController(self.r1, outletReservoir)
        pc.setMaster(mfc)
        pc.setPressureCoeff(1e-5)

        t = 0
        while t < 1.0:
            t = self.net.step(1.0)
            self.assertNear(mdot(t), mfc.mdot(t))
            dP = self.r1.thermo.P - outletReservoir.thermo.P
            self.assertNear(mdot(t) + 1e-5 * dP, pc.mdot(t))
Ejemplo n.º 17
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)
Ejemplo n.º 18
0
 def run(self,):
     
     gas=processor.solution.P
     reactorPressure=gas
     pressureValveCoefficient=pvalveCoefficient
     maxPressureRiseAllowed=maxPrise
     
     
     #Build the system components for JSR
     fuelAirMixtureTank=ct.Reservoir(gas)
     exhaust=ct.Reservoir(gas)
     
     stirredReactor=ct.IdealGasReactor(gas,energy=energycon,volume=volume)
     massFlowController=ct.MassFlowController(upstream=fuelAirMixtureTank,
                                              downstream=stirredReactor,mdot=stirredReactor.mass/restime)
     pressureRegulator=ct.Valve(upstream=stirredReactor,downstream=exhaust,K=pressureValveCoefficient)
     reactorNetwork=ct.ReactorNet([stirredReactor])
     
     if bool(self.moleFractionObservables) and self.kineticSens==1:
         for i in range(gas.n_reactions):
             stirredReactor.add_sensitivity_reaction(i)
         
     if self.kineticSens and bool(self.moleFractionObservables)==False:
         except:
Ejemplo n.º 19
0
    def test_pressure_controller_errors(self):
        self.make_reactors()
        res = ct.Reservoir(self.gas1)
        mfc = ct.MassFlowController(res, self.r1, mdot=0.6)

        p = ct.PressureController(self.r1, self.r2, master=mfc, K=0.5)

        with self.assertRaises(ct.CanteraError):
            p = ct.PressureController(self.r1, self.r2, K=0.5)
            p.mdot(0.0)

        with self.assertRaises(ct.CanteraError):
            p = ct.PressureController(self.r1, self.r2, master=mfc)
            p.mdot(0.0)

        with self.assertRaises(ct.CanteraError):
            p = ct.PressureController(self.r1, self.r2)
            p.mdot(0.0)
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
    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])
Ejemplo n.º 22
0
    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])
Ejemplo n.º 23
0
"""

import numpy as np
import matplotlib.pyplot as plt
import cantera as ct

# Use reaction mechanism GRI-Mech 3.0. For 0-D simulations,
# no transport model is necessary.
gas = ct.Solution('gri30.yaml')

# Create a Reservoir for the inlet, set to a methane/air mixture at a specified
# equivalence ratio
equiv_ratio = 0.5  # lean combustion
gas.TP = 300.0, ct.one_atm
gas.set_equivalence_ratio(equiv_ratio, 'CH4:1.0', 'O2:1.0, N2:3.76')
inlet = ct.Reservoir(gas)

# Create the combustor, and fill it initially with a mixture consisting of the
# equilibrium products of the inlet mixture. This state corresponds to the state
# the reactor would reach with infinite residence time, and thus provides a good
# initial condition from which to reach a steady-state solution on the reacting
# branch.
gas.equilibrate('HP')
combustor = ct.IdealGasReactor(gas)
combustor.volume = 1.0

# Create a reservoir for the exhaust
exhaust = ct.Reservoir(gas)

# Use a variable mass flow rate to keep the residence time in the reactor
# constant (residence_time = mass / mass_flow_rate). The mass flow rate function
Ejemplo n.º 24
0
import cantera as ct

#-----------------------------------------------------------------------
# First create each gas needed, and a reactor or reservoir for each one.
#-----------------------------------------------------------------------

# create an argon gas object and set its state
ar = ct.Solution('argon.xml')
ar.TP = 1000.0, 20.0 * ct.one_atm

# create a reactor to represent the side of the cylinder filled with argon
r1 = ct.IdealGasReactor(ar)

# create a reservoir for the environment, and fill it with air.
env = ct.Reservoir(ct.Solution('air.xml'))

# 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
Ejemplo n.º 25
0
def runSinglePFR(T_0, pressure, composition_0, length, v_0, d, tempProfile,
                 factor, reactionIndex):

    start = time.time()

    # input file containing the reaction mechanism
    reaction_mechanism = 'HXD15_Battin_mech.xml'

    # import the gas model and set the initial conditions
    gas2 = ct.Solution(reaction_mechanism)
    gas2.TPX = T_0, pressure, composition_0
    mass_flow_rate2 = v_0 * gas2.density * (1.01325e5 / pressure) * (T_0 /
                                                                     298.15)

    # Resolution: The PFR will be simulated by 'n_steps' time steps or by a chain
    # of 'n_steps' stirred reactors.
    n_steps = 100
    area = math.pi * d * d / 4
    dz = length / n_steps
    r_vol = area * dz

    # create a new reactor
    r2 = ct.IdealGasReactor(gas2)
    r2.volume = r_vol

    # create a reservoir to represent the reactor immediately upstream. Note
    # that the gas object is set already to the state of the upstream reactor
    upstream = ct.Reservoir(gas2, name='upstream')

    # create a reservoir for the reactor to exhaust into. The composition of
    # this reservoir is irrelevant.
    downstream = ct.Reservoir(gas2, name='downstream')

    # The mass flow rate into the reactor will be fixed by using a
    # MassFlowController object.
    m = ct.MassFlowController(upstream, r2, mdot=mass_flow_rate2)

    # We need an outlet to the downstream reservoir. This will determine the
    # pressure in the reactor. The value of K will only affect the transient
    # pressure difference.
    v = ct.PressureController(r2, downstream, master=m, K=1.0e-9)

    sim2 = ct.ReactorNet([r2])

    from scipy.interpolate import UnivariateSpline
    [zz, tem] = readTemperatureProfile(tempProfile)
    para = UnivariateSpline(zz, tem)

    # modify the A factor of the given reaction
    gas2.set_multiplier(factor, reactionIndex - 1)

    # iterate through the PFR cells

    # define time, space, and other information vectors
    # z2 = (np.arange(n_steps+1) + 1) * dz
    # t_r2 = np.zeros_like(z2)  # residence time in each reactor
    # u2 = np.zeros_like(z2)
    # t2 = np.zeros_like(z2)

    for n in range(n_steps + 1):
        print n
        position = dz * float(n)
        # Set the state of the reservoir to match that of the previous reactor
        gas2.TDY = para(position), r2.thermo.density, r2.thermo.Y

        upstream.syncState()
        sim2.reinitialize()
        # integrate the reactor forward in time until steady state is reached
        sim2.advance_to_steady_state()
        # compute velocity and transform into time
        # u2[n] = mass_flow_rate2 / area / r2.thermo.density
        # t_r2[n] = r2.mass / mass_flow_rate2  # residence time in this reactor
        # t2[n] = np.sum(t_r2)
        # write output data
        # print position, r2.thermo.T, r2.thermo.P, u2[n], t2[n], r2.thermo['C3H6'].X[0]
        # moleFractionC3H6.append([dz*n, u2[n], t2[n], r2.thermo.T, r2.thermo['C3H6'].X[0]])

    end = time.time()
    print 'Done! Execution time is:'
    print end - start

    return [
        gas2.reaction_equation(reactionIndex - 1),
        r2.thermo['C3H6'].X[0] * 1.0e6
    ]
Ejemplo n.º 26
0
a MassFlowController, and the use of the SolutionArray class to store results
during reactor network integration and use these results to generate plots.

Requires: cantera >= 2.5.0, matplotlib >= 2.0
"""

import numpy as np
import matplotlib.pyplot as plt
import cantera as ct

# Use a reduced n-dodecane mechanism with PAH formation pathways
gas = ct.Solution('nDodecane_Reitz.yaml', 'nDodecane_IG')

# Create a Reservoir for the fuel inlet, set to pure dodecane
gas.TPX = 300, 20 * ct.one_atm, 'c12h26:1.0'
inlet = ct.Reservoir(gas)

# Create Reactor and set initial contents to be products of lean combustion
gas.TP = 1000, 20 * ct.one_atm
gas.set_equivalence_ratio(0.30, 'c12h26', 'n2:3.76, o2:1.0')
gas.equilibrate('TP')
r = ct.IdealGasReactor(gas)
r.volume = 0.001  # 1 liter


def fuel_mdot(t):
    """Create an inlet for the fuel, supplied as a Gaussian pulse"""
    total = 3.0e-3  # mass of fuel [kg]
    width = 0.5  # width of the pulse [s]
    t0 = 2.0  # time of fuel pulse peak [s]
    amplitude = total / (width * np.sqrt(2 * np.pi))
Ejemplo n.º 27
0
# import the gas model and set the initial conditions
ignition_delay = []
for T_0 in (i):
    gas2 = ct.Solution(reaction_mechanism)
    gas2.TPX = T_0, pressure, composition_0
    mass_flow_rate2 = u_0 * gas2.density * area
    dz = length / n_steps
    r_vol = area * dz

    # create a new reactor
    r2 = ct.IdealGasReactor(gas2)
    r2.volume = r_vol

    # create a reservoir to represent the reactor immediately 	upstream. Note
    # that the gas object is set already to the state of the 	upstream reactor
    upstream = ct.Reservoir(gas2, name='upstream')

    # create a reservoir for the reactor to exhaust into. The 	composition of
    # this reservoir is irrelevant.
    downstream = ct.Reservoir(gas2, name='downstream')

    # The mass flow rate into the reactor will be fixed by using 	a
    # MassFlowController object.
    m = ct.MassFlowController(upstream, r2, mdot=mass_flow_rate2)

    # We need an outlet to the downstream reservoir. This will 	determine the
    # pressure in the reactor. The value of K will only affect 	the transient
    # pressure difference.
    v = ct.PressureController(r2, downstream, master=m, K=1e-5)

    sim2 = ct.ReactorNet([r2])
Ejemplo n.º 28
0
the chemistry. A simple igniter is a pulsed flow of atomic hydrogen. After the
igniter is turned off, the system approaches the steady burning solution.
"""

import math
import csv

import cantera as ct

# use reaction mechanism GRI-Mech 3.0

gas = ct.Solution('gri30.xml')

# create a reservoir for the fuel inlet, and set to pure methane.
gas.TPX = 300.0, ct.one_atm, 'CH4:1.0'
fuel_in = ct.Reservoir(gas)
fuel_mw = gas.mean_molecular_weight

# use predefined function Air() for the air inlet
air = ct.Solution('air.xml')
air_in = ct.Reservoir(air)
air_mw = air.mean_molecular_weight

# to ignite the fuel/air mixture, we'll introduce a pulse of radicals. The
# steady-state behavior is independent of how we do this, so we'll just use a
# stream of pure atomic hydrogen.
gas.TPX = 300.0, ct.one_atm, 'H:1.0'
igniter = ct.Reservoir(gas)

# create the combustor, and fill it in initially with N2
gas.TPX = 300.0, ct.one_atm, 'N2:1.0'
# In[2]:

# create the gas mixture
gas = ct.Solution('h2o2.cti')

# pressure = 60 Torr, T = 770 K
p = 60.0 * 133.3
t = 770.0

gas.TPX = t, p, 'H2:2, O2:1'

# create an upstream reservoir that will supply the reactor. The temperature,
# pressure, and composition of the upstream reservoir are set to those of the
# 'gas' object at the time the reservoir is created.
upstream = ct.Reservoir(gas)

# Now create the reactor object with the same initial state
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
Ejemplo n.º 30
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