Mixing two streams#

Since reactors can have multiple inlets and outlets, they can be used to implement mixers, splitters, etc. In this example, air and methane are mixed in stoichiometric proportions. Due to the low temperature, no reactions occur. Note that the air stream and the methane stream use different reaction mechanisms, with different numbers of species and reactions. When gas flows from one reactor or reservoir to another one with a different reaction mechanism, species are matched by name. If the upstream reactor contains a species that is not present in the downstream reaction mechanism, it will be ignored. In general, reaction mechanisms for downstream reactors should contain all species that might be present in any upstream reactor.

Compare this approach for the transient problem to the method used for the steady-state problem in mixing.py.

Requires: cantera >= 3.1.0, graphviz

Tags: Python thermodynamics reactor network mixture

import cantera as ct

Set up the reactor network#

Use air for stream a.

gas_a = ct.Solution('air.yaml')
gas_a.TPX = 300.0, ct.one_atm, 'O2:0.21, N2:0.78, AR:0.01'
rho_a = gas_a.density

Use GRI-Mech 3.0 for stream b (methane) and for the mixer. If it is desired to have a pure mixer, with no chemistry, use instead a reaction mechanism for gas_b that has no reactions.

gas_b = ct.Solution('gri30.yaml')
gas_b.TPX = 300.0, ct.one_atm, 'CH4:1'
rho_b = gas_b.density

Create reservoirs for the two inlet streams and for the outlet stream. The upstream reservoirs could be replaced by reactors, which might themselves be connected to reactors further upstream. The outlet reservoir could be replaced with a reactor with no outlet, if it is desired to integrate the composition leaving the mixer in time, or by an arbitrary network of downstream reactors.

res_a = ct.Reservoir(gas_a, name='Air Reservoir')
res_b = ct.Reservoir(gas_b, name='Fuel Reservoir')
downstream = ct.Reservoir(gas_a, name='Outlet Reservoir')

Create a reactor for the mixer. A reactor is required instead of a reservoir, since the state will change with time if the inlet mass flow rates change or if there is chemistry occurring.

gas_b.TPX = 300.0, ct.one_atm, 'O2:0.21, N2:0.78, AR:0.01'
mixer = ct.IdealGasReactor(gas_b, name='Mixer')

Create two mass flow controllers connecting the upstream reservoirs to the mixer, and set their mass flow rates to values corresponding to stoichiometric combustion.

mfc1 = ct.MassFlowController(res_a, mixer, mdot=rho_a*2.5/0.21, name="Air Inlet")
mfc2 = ct.MassFlowController(res_b, mixer, mdot=rho_b*1.0, name="Fuel Inlet")

Connect the mixer to the downstream reservoir with a valve.

outlet = ct.Valve(mixer, downstream, K=10.0, name="Valve")

sim = ct.ReactorNet([mixer])

Get the mixed state#

Since the mixer is a reactor, we need to integrate in time to reach steady state.

sim.advance_to_steady_state()

# view the state of the gas in the mixer
print(mixer.thermo.report())
 gri30:

      temperature   300 K
         pressure   1.0133e+05 Pa
          density   1.1361 kg/m^3
 mean mol. weight   27.968 kg/kmol
  phase of matter   gas

                         1 kg             1 kmol
                    ---------------   ---------------
         enthalpy        -2.047e+05        -5.725e+06  J
  internal energy       -2.9388e+05       -8.2194e+06  J
          entropy            7158.8        2.0022e+05  J/K
   Gibbs function       -2.3523e+06       -6.5791e+07  J
heat capacity c_p            1057.5             29578  J/K
heat capacity c_v            760.26             21263  J/K

                     mass frac. Y      mole frac. X     chem. pot. / RT
                    ---------------   ---------------   ---------------
               O2           0.22164           0.19373           -26.315
              CH4           0.04445          0.077491            -54.88
               N2           0.72073           0.71956           -23.362
               AR          0.013177         0.0092251           -23.296
    [  +49 minor]       -4.9702e-29       -8.6629e-29

Show the network structure#

try:
    diagram = sim.draw(print_state=True, species="X")
except ImportError as err:
    print(f"Unable to show network structure:\n{err}")
mix1

Total running time of the script: (0 minutes 0.090 seconds)

Gallery generated by Sphinx-Gallery