#### Previous topic

Transport Properties

#### Next topic

One-dimensional Reacting Flows

Warning

This documentation is for an old version of Cantera. You can find docs for newer versions here.

# Zero-Dimensional Reactor Networks¶

## Defining Functions¶

class cantera.Func1

Bases: object

This class is used as a wrapper for a function of one variable, i.e. $$y = f(t)$$, that is defined in Python and can be called by the Cantera C++ core. Func1 objects are constructed from callable Python objects, e.g. functions or classes which implement the __call__ method:

>>> f1 = Func1(math.sin)
>>> f1(math.pi/4)
0.7071067811865475

>>> f2 = Func1(lambda t: t**2 + 1)
>>> f2(3)
10

>>> class Multiplier(object):
...     def __init__(self, factor):
...         self.factor = factor
...     def __call__(self, t):
...         return self.factor * t
>>> f3 = Func1(Multiplier(5))
>>> f3(6)
30.0


For simplicity, constant functions can be defined by passing the constant value directly:

>>> f4 = Func1(2.5)
>>> f4(0.1)
2.5


Note that all methods which accept Func1 objects will also accept the callable object and create the wrapper on their own, so it is generally unnecessary to explicitly create a Func1 object.

## Base Classes¶

class cantera.ReactorBase

Bases: object

ReactorBase(ThermoPhase contents=None, name=None, **kwargs)

Common base class for reactors and reservoirs.

T

The temperature [K] of the reactor’s contents.

Y

The mass fractions of the reactor’s contents.

density

The density [kg/m^3 or kmol/m^3] of the reactor’s contents.

inlets

List of flow devices installed as inlets to this reactor

insert(self, _SolutionBase solution)

Set solution to be the object used to compute thermodynamic properties and kinetic rates for this reactor.

mass

The mass of the reactor’s contents.

name

The name of the reactor.

outlets

List of flow devices installed as outlets to this reactor

reactor_type = 'None'
thermo

The ThermoPhase object representing the reactor’s contents.

volume

The volume [m^3] of the reactor.

walls

List of walls installed on this reactor

class cantera.FlowDevice

Bases: object

FlowDevice(upstream, downstream, name=None, *)

Base class for devices that allow flow between reactors.

FlowDevice objects are assumed to be adiabatic, non-reactive, and have negligible internal volume, so that they are internally always in steady-state even if the upstream and downstream reactors are not. The fluid enthalpy, chemical composition, and mass flow rate are constant across a FlowDevice, and the pressure difference equals the difference in pressure between the upstream and downstream reactors.

mdot(self, double t)

The mass flow rate [kg/s] through this device at time t [s].

## Reactor Networks¶

class cantera.ReactorNet

Bases: object

ReactorNet(reactors=())

Networks of reactors. ReactorNet objects are used to simultaneously advance the state of one or more coupled reactors.

Example:

>>> r1 = Reactor(gas1)
>>> r2 = Reactor(gas2)
>>> <... install walls, inlets, outlets, etc...>

>>> reactor_network = ReactorNet([r1, r2])


Add a reactor to the network.

Advance the state of the reactor network in time from the current time to time t [s], taking as many integrator timesteps as necessary.

atol

The absolute error tolerance used while integrating the reactor equations.

atol_sensitivity

The absolute error tolerance for sensitivity analysis.

max_err_test_fails

The maximum number of error test failures permitted by the CVODES integrator in a single time step.

n_sensitivity_params
n_vars
rtol

The relative error tolerance used while integrating the reactor equations.

rtol_sensitivity

The relative error tolerance for sensitivity analysis.

sensitivities(self)
sensitivity(self, species, int p, int r=0)
sensitivity_parameter_name(self, int p)
set_initial_time(self, double t)

Set the initial time. Restarts integration from this time using the current state as the initial condition. Default: 0.0 s.

set_max_time_step(self, double t)

Set the maximum time step t [s] that the integrator is allowed to use.

step(self, double t)

Take a single internal time step toward time t [s]. The time after taking the step is returned.

time

The current time [s].

verbose

If True, verbose debug information will be printed during integration. The default is False.

## Reactors¶

class cantera.Reservoir

Bases: cantera._cantera.ReactorBase

A reservoir is a reactor with a constant state. The temperature, pressure, and chemical composition in a reservoir never change from their initial values.

reactor_type = 'Reservoir'
class cantera.Reactor

Bases: cantera._cantera.ReactorBase

Reactor(contents=None, name=None, *, energy=’on’, **kwargs)

A homogeneous zero-dimensional reactor. By default, they are closed (no inlets or outlets), have fixed volume, and have adiabatic, chemically-inert walls. These properties may all be changed by adding appropriate components, e.g. Wall, MassFlowController and Valve.

Parameters: contents – Reactor contents. If not specified, the reactor is initially empty. In this case, call insert to specify the contents. name – Used only to identify this reactor in output. If not specified, defaults to 'Reactor_n', where n is an integer assigned in the order Reactor objects are created. energy – Set to 'on' or 'off'. If set to 'off', the energy equation is not solved, and the temperature is held at its initial value..

Some examples showing how to create Reactor objects are shown below.

>>> gas = Solution('gri30.xml')
>>> r1 = Reactor(gas)


This is equivalent to:

>>> r1 = Reactor()
>>> r1.insert(gas)


Arguments may be specified using keywords in any order:

>>> r2 = Reactor(contents=gas, energy='off',
...              name='isothermal_reactor')

component_index(self, name)

Returns the index of the component named name in the system. This determines the (relative) index of the component in the vector of sensitivity coefficients. name is either a species name or the name of a reactor state variable, e.g. ‘U’, ‘T’, depending on the reactor’s equations.

energy_enabled

True when the energy equation is being solved for this reactor. When this is False, the reactor temperature is held constant.

insert(self, _SolutionBase solution)
kinetics

The Kinetics object used for calculating kinetic rates in this reactor.

reactor_type = 'Reactor'
class cantera.IdealGasReactor

Bases: cantera._cantera.Reactor

A constant volume, zero-dimensional reactor for ideal gas mixtures.

Parameters: contents – Reactor contents. If not specified, the reactor is initially empty. In this case, call insert to specify the contents. name – Used only to identify this reactor in output. If not specified, defaults to 'Reactor_n', where n is an integer assigned in the order Reactor objects are created. energy – Set to 'on' or 'off'. If set to 'off', the energy equation is not solved, and the temperature is held at its initial value..

Some examples showing how to create Reactor objects are shown below.

>>> gas = Solution('gri30.xml')
>>> r1 = Reactor(gas)


This is equivalent to:

>>> r1 = Reactor()
>>> r1.insert(gas)


Arguments may be specified using keywords in any order:

>>> r2 = Reactor(contents=gas, energy='off',
...              name='isothermal_reactor')

reactor_type = 'IdealGasReactor'
class cantera.ConstPressureReactor

Bases: cantera._cantera.Reactor

A homogeneous, constant pressure, zero-dimensional reactor. The volume of the reactor changes as a function of time in order to keep the pressure constant.

Parameters: contents – Reactor contents. If not specified, the reactor is initially empty. In this case, call insert to specify the contents. name – Used only to identify this reactor in output. If not specified, defaults to 'Reactor_n', where n is an integer assigned in the order Reactor objects are created. energy – Set to 'on' or 'off'. If set to 'off', the energy equation is not solved, and the temperature is held at its initial value..

Some examples showing how to create Reactor objects are shown below.

>>> gas = Solution('gri30.xml')
>>> r1 = Reactor(gas)


This is equivalent to:

>>> r1 = Reactor()
>>> r1.insert(gas)


Arguments may be specified using keywords in any order:

>>> r2 = Reactor(contents=gas, energy='off',
...              name='isothermal_reactor')

reactor_type = 'ConstPressureReactor'
class cantera.IdealGasConstPressureReactor

Bases: cantera._cantera.Reactor

A homogeneous, constant pressure, zero-dimensional reactor for ideal gas mixtures. The volume of the reactor changes as a function of time in order to keep the pressure constant.

Parameters: contents – Reactor contents. If not specified, the reactor is initially empty. In this case, call insert to specify the contents. name – Used only to identify this reactor in output. If not specified, defaults to 'Reactor_n', where n is an integer assigned in the order Reactor objects are created. energy – Set to 'on' or 'off'. If set to 'off', the energy equation is not solved, and the temperature is held at its initial value..

Some examples showing how to create Reactor objects are shown below.

>>> gas = Solution('gri30.xml')
>>> r1 = Reactor(gas)


This is equivalent to:

>>> r1 = Reactor()
>>> r1.insert(gas)


Arguments may be specified using keywords in any order:

>>> r2 = Reactor(contents=gas, energy='off',
...              name='isothermal_reactor')

reactor_type = 'IdealGasConstPressureReactor'
class cantera.FlowReactor

Bases: cantera._cantera.Reactor

A steady-state plug flow reactor with constant cross sectional area. Time integration follows a fluid element along the length of the reactor. The reactor is assumed to be frictionless and adiabatic.

Parameters: contents – Reactor contents. If not specified, the reactor is initially empty. In this case, call insert to specify the contents. name – Used only to identify this reactor in output. If not specified, defaults to 'Reactor_n', where n is an integer assigned in the order Reactor objects are created. energy – Set to 'on' or 'off'. If set to 'off', the energy equation is not solved, and the temperature is held at its initial value..

Some examples showing how to create Reactor objects are shown below.

>>> gas = Solution('gri30.xml')
>>> r1 = Reactor(gas)


This is equivalent to:

>>> r1 = Reactor()
>>> r1.insert(gas)


Arguments may be specified using keywords in any order:

>>> r2 = Reactor(contents=gas, energy='off',
...              name='isothermal_reactor')

distance

The distance of the fluid element from the inlet of the reactor.

mass_flow_rate

Mass flow rate per unit area [kg/m^2*s]

reactor_type = 'FlowReactor'
speed

Speed [m/s] of the flow in the reactor at the current position

## Flow Controllers¶

class cantera.Wall

Bases: object

Wall(left, right, name=None, *, A=None, K=None, U=None, Q=None, velocity=None, kinetics=(None, None))

A Wall separates two reactors, or a reactor and a reservoir. A wall has a finite area, may conduct or radiate heat between the two reactors on either side, and may move like a piston.

Walls are stateless objects in Cantera, meaning that no differential equation is integrated to determine any wall property. Since it is the wall (piston) velocity that enters the energy equation, this means that it is the velocity, not the acceleration or displacement, that is specified. The wall velocity is computed from

$v = K(P_{\rm left} - P_{\rm right}) + v_0(t),$

where $$K$$ is a non-negative constant, and $$v_0(t)$$ is a specified function of time. The velocity is positive if the wall is moving to the right.

The heat flux through the wall is computed from

$q = U(T_{\rm left} - T_{\rm right}) + \epsilon\sigma (T_{\rm left}^4 - T_{\rm right}^4) + q_0(t),$

where $$U$$ is the overall heat transfer coefficient for conduction/convection, and $$\epsilon$$ is the emissivity. The function $$q_0(t)$$ is a specified function of time. The heat flux is positive when heat flows from the reactor on the left to the reactor on the right.

A heterogeneous reaction mechanism may be specified for one or both of the wall surfaces. The mechanism object (typically an instance of class Interface) must be constructed so that it is properly linked to the object representing the fluid in the reactor the surface in question faces. The surface temperature on each side is taken to be equal to the temperature of the reactor it faces.

Parameters: left – Reactor or reservoir on the left. Required. right – Reactor or reservoir on the right. Required. name – Name string. If omitted, the name is 'Wall_n', where 'n' is an integer assigned in the order walls are created. A – Wall area [m^2]. Defaults to 1.0 m^2. K – Wall expansion rate parameter [m/s/Pa]. Defaults to 0.0. U – Overall heat transfer coefficient [W/m^2]. Defaults to 0.0 (adiabatic wall). Q – Heat flux function $$q_0(t)$$ [W/m^2]. Optional. Default: $$q_0(t) = 0.0$$. velocity – Wall velocity function $$v_0(t)$$ [m/s]. Default: $$v_0(t) = 0.0$$. kinetics – Surface reaction mechanisms for the left-facing and right-facing surface, respectively. These must be instances of class Kinetics, or of a class derived from Kinetics, such as Interface. If chemistry occurs on only one side, enter None for the non-reactive side.
area

The wall area [m^2].

emissivity

The emissivity (nondimensional)

expansion_rate_coeff

The coefficient K [m/s/Pa] that determines the velocity of the wall as a function of the pressure difference between the adjacent reactors.

heat_transfer_coeff

the overall heat transfer coefficient [W/m^2/K]

left

The left surface of this wall.

qdot(self, double t)

Total heat flux [W] through the wall at time t. A positive value corresponds to heat flowing from the left-hand reactor to the right-hand one.

right

The right surface of this wall.

set_heat_flux(self, q)

Heat flux [W/m^2] across the wall. May be either a constant or an arbitrary function of time. See Func1.

set_velocity(self, v)

The wall velocity [m/s]. May be either a constant or an arbirary function of time. See Func1.

vdot(self, double t)

The rate of volumetric change [m^3/s] associated with the wall at time t. A positive value corresponds to the left-hand reactor volume increasing, and the right-hand reactor volume decreasing.

class cantera.MassFlowController

Bases: cantera._cantera.FlowDevice

MassFlowController(upstream, downstream, name=None, *, mdot=None)

A mass flow controller maintains a specified mass flow rate independent of upstream and downstream conditions. The equation used to compute the mass flow rate is

$\dot m = \max(\dot m_0, 0.0),$

where $$\dot m_0$$ is either a constant value or a function of time. Note that if $$\dot m_0 < 0$$, the mass flow rate will be set to zero, since reversal of the flow direction is not allowed.

Unlike a real mass flow controller, a MassFlowController object will maintain the flow even if the downstream pressure is greater than the upstream pressure. This allows simple implementation of loops, in which exhaust gas from a reactor is fed back into it through an inlet. But note that this capability should be used with caution, since no account is taken of the work required to do this.

set_mass_flow_rate(self, m)

Set the mass flow rate [kg/s] through this controller to be either a constant or an arbitrary function of time. See Func1.

>>> mfc.set_mass_flow_rate(0.3)
>>> mfc.set_mass_flow_rate(lambda t: 2.5 * exp(-10 * (t - 0.5)**2))

class cantera.Valve

Bases: cantera._cantera.FlowDevice

Valve(upstream, downstream, name=None, *, K=None)

In Cantera, a Valve is a flow devices with mass flow rate that is a function of the pressure drop across it. The default behavior is linear:

$\dot m = K_v (P_1 - P_2)$

if $$P_1 > P_2.$$ Otherwise, $$\dot m = 0$$. However, an arbitrary function can also be specified, such that

$\dot m = F(P_1 - P_2)$

if $$P_1 > P_2$$, or $$\dot m = 0$$ otherwise. It is never possible for the flow to reverse and go from the downstream to the upstream reactor/reservoir through a line containing a Valve object.

Valve objects are often used between an upstream reactor and a downstream reactor or reservoir to maintain them both at nearly the same pressure. By setting the constant $$K_v$$ to a sufficiently large value, very small pressure differences will result in flow between the reactors that counteracts the pressure difference.

set_valve_coeff(self, k)

Set the relationship betwen mass flow rate and the pressure drop across the valve. If a number is given, it is the proportionality constant [kg/s/Pa]. If a function is given, it should compute the mass flow rate [kg/s] given the pressure drop [Pa].

>>> V = Valve(res1, reactor1)
>>> V.set_valve_coeff(1e-4)
>>> V.set_valve_coeff(lambda dP: (1e-5 * dP)**2)

class cantera.PressureController

Bases: cantera._cantera.FlowDevice

PressureController(upstream, downstream, name=None, *, master=None, K=None)

A PressureController is designed to be used in conjunction with another ‘master’ flow controller, typically a MassFlowController. The master flow controller is installed on the inlet of the reactor, and the corresponding PressureController is installed on on outlet of the reactor. The PressureController mass flow rate is equal to the master mass flow rate, plus a small correction dependent on the pressure difference:

$\dot m = \dot m_{\rm master} + K_v(P_1 - P_2).$
set_master(self, FlowDevice d)

Set the “master” FlowDevice used to compute this device’s mass flow rate.

set_pressure_coeff(self, double k)

Set the proportionality constant k [kg/s/Pa] between the pressure drop and the mass flow rate.