Reactors and Reactor Networks

Cantera Reactors and Reactor Networks model zero-dimensional reactors and their interactions with the surroundings.

Reactors

A Cantera Reactor() represents the simplest form of a chemically reacting system. It corresponds to an extensive thermodynamic control volume \(V\), in which all state variables are homogeneously distributed. The system is generally unsteady -- that is, all states are functions of time. In particular, transient state changes due to chemical reactions are possible. However, thermodynamic (but not chemical) equilibrium is assumed to be present throughout the reactor at all instants of time.

Reactors can interact with the surrounding environment in multiple ways:

  • Expansion/compression work: By moving the walls of the reactor, its volume can be changed and expansion or compression work can be done by or on the reactor.

  • Heat transfer: An arbitrary heat transfer rate can be defined to cross the boundaries of the reactor.

  • Mass transfer: The reactor can have multiple inlets and outlets. For the inlets, arbitrary states can be defined. Fluid with the current state of the reactor exits the reactor at the outlets.

  • Surface interaction: One or multiple walls can influence the chemical reactions in the reactor. This is not just restricted to catalytic reactions, but mass transfer between the surface and the fluid can also be modeled.

All of these interactions do not have to be constant, but can vary as a function of time or state. For example, heat transfer can be described as a function of the temperature difference between the reactor and the environment, or the wall movement can be modeled depending on the pressure difference. Interactions of the reactor with the environment are defined on one or more walls, inlets, and outlets.

In addition to single reactors, Cantera is also able to interconnect reactors into a Reactor Network. Each reactor in a network may be connected so that the contents of one reactor flow into another. Reactors may also be in contact with one another or the environment via walls that conduct heat or move to do work.

Reactor Types and Governing Equations

All reactor types are modelled using combinations of Cantera's governing equations of state. The specific governing equations defining Cantera's supported reactor models are derived and described below.

Control Volume Reactor

A reactor where the volume is prescribed by the motion of the reactor's walls. The state variables are the volume, mass, total internal energy, and species mass fractions.

Constant Pressure Reactor

A reactor where the pressure is held constant by varying the volume. The state variables are the mass, total enthalpy, and species mass fractions.

Ideal Gas Reactor

A reactor where the volume is prescribed by the motion of the reactor's walls, specialized for ideal gas mixtures. The state variables are the mass, volume, temperature, and species mass fractions.

Ideal Gas Constant Pressure Reactor

A reactor where the pressure is held constant by varying the volume, specialized for ideal gas mixtures. The state variables are the mass, temperature, and species mass fractions.

Plug Flow Reactor

A steady-state reactor channel with an ideal gas flowing through it and heterogeneous reactions occurring on the walls.

A set of reactors with a mole-based state vector are implemented to leverage preconditioning techniques which do not have the same applicability to traditional mass fraction based solutions. More on preconditioning can be found in description of the SUNDIALS time integration here. The primary difference in "Mole reactors" is that the governing equations are derived in terms of the moles of each species instead of total mass and the mass fractions.

Mole Reactor

A control volume reactor where the state variables are the volume, total internal energy, and moles of each species.

Constant Pressure Mole Reactor

A constant pressure reactor where the state variables are the total enthalpy and the moles of each species.

Ideal Gas Mole Reactor

A control volume reactor specialized for ideal gases, where the state variables are the volume, temperature, and the moles of each species.

Ideal Gas Constant Pressure Mole Reactor

A constant pressure reactor specialized for ideal gases, where the state variables are the temperature and the moles of each species.

Extensible Reactors

In some cases, Cantera's built-in reactor types are insufficient to model a problem. In this situation, the ExtensibleReactor family of classes can be used to modify and governing equations, starting from one of the built-in reactor types.

These reactor types allow the methods that implement the governing equations and related reactor configuration to be augmented or replaced with user-defined Python functions. New state variables can be added to the reactor, and existing ones can be redefined. User-defined ExtensibleReactor implementations can be used alongside the built-in reactor types to build reactor networks that can be integrated using the ReactorNet integrator provided by Cantera.

Several examples demonstrating the use of ExtensibleReactor classes are given below. Detailed API documentation can be found with the Python ExtensibleReactor() class.

Extensible Reactor Tutorial

A simple example of an ExtensibleReactor that walks through the definition of modified governing equations and shows how to define the Python methods that implement these changes to the equations.

Adding New State Variables

An example that shows how to add a new state variable to an ExtensibleReactor, in order to implement a reactor where an adjacent wall has inertia and takes time to respond to changes in the reactor's pressure.

Complex Reactor Interactions

An example that implements fully-customized governing equations to implement a porous media burner, with several new forms of interaction between adjacent reactors.

Reactor Networks

While reactors by themselves just define the above governing equations of the reactor, the time integration is performed in reactor networks. In other words defining a reactor without assigning it to a reactor network prevents Cantera from performing time integration to solve the governing equations. A reactor network is therefore necessary to define even if only a single reactor is considered. An example of a single reactor network can be found here.

Time Integration for Reactor Networks: CVODES

Cantera uses the CVODES solver from the SUNDIALS package to integrate the stiff ODEs of reacting systems. These stiff ODEs are referring to the governing equations defining the reactors above. More in-depth information on the CVODES solver can be found here.

Reactor Peripherals

Reactor networks are also how Cantera interconnects multiple reactors. Not only mass flow from one reactor into another can be incorporated, but also heat can be transferred, or the wall between reactors can move. Documentation on the different ways to connect reactors is explained here.

To set up a network, the following components can be defined in addition to the reactors previously mentioned:

  • Reservoir(): A reservoir can be thought of as an infinitely large volume, in which all states are predefined and never change from their initial values. Typically, it represents a vessel to define temperature and composition of a stream of mass flowing into a reactor, or the ambient fluid surrounding the reactor network. Besides, the fluid flow finally exiting a reactor network has to flow into a reservoir. In the latter case, the state of the reservoir (except pressure) is irrelevant.

  • Wall(): 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. See the Wall Interactions section below for detail of how the wall affects the connected reactors.

  • Valve(): A valve is a flow devices with mass flow rate that is a function of the pressure drop across it. The mass flow rate is computed as:

    \begin{equation*} \dot m = K_v g(t) f(P_1 - P_2) \end{equation*}

    with \(K_v\) being a proportionality constant that is set using the class property valve_coeff(). Further, \(g\) and \(f\) are functions of time and pressure drop that are set by class methods set_time_function() and set_pressure_function(), respectively. If no functions are specified, the mass flow rate defaults to:

    \begin{equation*} \dot m = K_v (P_1 - P_2) \end{equation*}

    The pressure difference between upstream (1) and downstream (2) reservoir is defined as \(P_1 - P_2\). 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, which means that the flow rate is set to zero if \(P_1 < P_2\).

    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.

  • MassFlowController(): 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

    \begin{equation*} \dot m = m_0 g(t) \end{equation*}

    where \(m_0\) is a mass flow coefficient and \(g\) is a function of time which are set by class property mass_flow_coeff() and method set_time_function(), respectively. If no function is specified, the mass flow rate defaults to:

    \begin{equation*} \dot m = m_0 \end{equation*}

    Note that if \(\dot m < 0\), the mass flow rate will be set to zero, since a 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.

  • PressureController(): A pressure controller 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:

    \begin{equation*} \dot m = \dot m_{\text{master}} + K_v f(P_1 - P_2) \end{equation*}

    where \(K_v\) is a proportionality constant and \(f\) is a function of pressure drop \(P_1 - P_2\) that are set by class property pressure_coeff() and method set_pressure_function(), respectively. If no function is specified, the mass flow rate defaults to:

    \begin{equation*} \dot m = \dot m_{\text{master}} + K_v (P_1 - P_2) \end{equation*}

    Note that if \(\dot m < 0\), the mass flow rate will be set to zero, since a reversal of the flow direction is not allowed.

    Cantera comes with a broad variety of well-commented example scrips for reactor networks. Please see the Cantera Examples for further information.

Wall Interactions

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

\begin{equation*} v = K(P_{\mathrm{left}} - P_{\mathrm{right}}) + v_0(t), \end{equation*}

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 total rate of heat transfer through all walls is:

\begin{equation*} \dot{Q} = \sum_w f_w \dot{Q}_w \end{equation*}

where \(f_w = \pm 1\) indicates the facing of the wall (-1 for the reactor on the left, +1 for the reactor on the right). The heat flux \(\dot{Q}_w\) through a wall \(w\) connecting reactors "left" and "right" is computed as:

\begin{equation*} \dot{Q}_w = U A (T_{\mathrm{left}} - T_{\mathrm{right}}) + \epsilon\sigma A (T_{\mathrm{left}}^4 - T_{\mathrm{right}}^4) + A q_0(t) \end{equation*}

where \(U\) is a user-specified heat transfer coefficient (W/m2-K), \(A\) is the wall area (m2), \(\epsilon\) is the user-specified emissivity, \(\sigma\) is the Stefan-Boltzmann radiation constant, and \(q_0(t)\) is a user-specified, time-dependent heat flux (W/m2). This definition is such that positive \(q_0(t)\) implies heat transfer from the "left" reactor to the "right" reactor. Each of the user-specified terms defaults to 0.

In case of surface reactions, there can be a net generation (or destruction) of homogeneous (gas) phase species at the wall. The molar rate of production for each homogeneous phase species \(k\) on wall \(w\) is \(\dot{s}_{k,w}\) (in kmol/s/m2). The total (mass) production rate for homogeneous phase species \(k\) on all walls is:

\begin{equation*} \dot{m}_{k,wall} = W_k \sum_w A_w \dot{s}_{k,w} \end{equation*}

where \(W_k\) is the molecular weight of species \(k\) and \(A_w\) is the area of each wall. The net mass flux from all walls is then:

\begin{equation*} \dot{m}_{wall} = \sum_k \dot{m}_{k,wall} \end{equation*}

For each surface species \(i\), the rate of change of the site fraction \(\theta_{i,w}\) on each wall \(w\) is integrated with time:

\begin{equation*} \frac{d\theta_{i,w}}{dt} = \frac{\dot{s}_{i,w} \sigma_i}{\Gamma_w} \end{equation*}

where \(\Gamma_w\) is the total surface site density on wall \(w\) and \(\sigma_i\) is the number of surface sites occupied by a molecule of species \(i\) (sometimes referred to within Cantera as the molecule's "size").

In the case of mole based reactors, \(\dot{n}_{wall}\) is needed which is calculated as:

\begin{equation*} \dot{n}_{k, wall} = A_{w}\sum_{w}\dot{s}_{w, k} \end{equation*}

Common Reactor Types and their Implementation in Cantera

Batch Reactor at Constant Volume or at Constant Pressure

If you are interested in how a homogeneous chemical composition changes in time when it is left to its own devices, a simple batch reactor can be used. Two versions are commonly considered: A rigid vessel with fixed volume but variable pressure, or a system idealized at constant pressure but varying volume.

In Cantera, such a simulation can be performed very easily. The initial state of the solution can be specified by composition and a set of thermodynamic parameters (like temperature and pressure) as a standard Cantera solution object. Upon its base, a general (Ideal Gas) Reactor or an (Ideal Gas) Constant Pressure Reactor can be created, depending on if a constant volume or constant pressure batch reactor should be considered, respectively. The behavior of the solution in time can be simulated as a very simple Reactor Network containing only the formerly created reactor.

An example for such a Batch Reactor is given in the examples.

Continuously Stirred Tank Reactor

A Continuously Stirred Tank Reactor (CSTR), also often referred to as Well-Stirred Reactor (WSR), Perfectly Stirred Reactor (PSR), or Longwell Reactor, is essentially a single Cantera reactor with an inlet, an outlet, and constant volume. Therefore, the governing equations for single reactors defined above apply accordingly.

Steady state solutions to CSTRs are often of interest. In this case, the mass flow rate \(\dot{m}\) is constant and equal at inlet and outlet. The mass contained in the confinement \(m\) divided by \(\dot{m}\) defines the mean residence time of the fluid in the confinement.

At steady state, the time derivatives in the governing equations become zero, and the system of ordinary differential equations can be reduced to a set of coupled nonlinear algebraic equations. A Newton solver could be used to solve this system of equations. However, a sophisticated implementation might be required to account for the strong nonlinearities and the presence of multiple solutions.

Cantera does not have such a Newton solver implemented. Instead, steady CSTRs are simulated by considering a time-dependent constant volume reactor with specified in- and outflow conditions. Starting off at an initial solution, the reactor network containing this reactor is advanced in time until the state of the solution is converged. An example for this procedure is the combustor example.

A problem can be the ignition of a CSTR: If the reactants are not reactive enough, the simulation can result in the trivial solution that inflow and outflow states are identical. To solve this problem, the reactor can be initialized with a high temperature and/or radical concentration. A good approach is to use the equilibrium composition of the reactants (which can be computed using Cantera's equilibrate function) as an initial guess.

Cantera always solves a transient problem. If you are interested in steady-state conditions, you can run your simulation for a long time until the states are converged (see the surface reactor example and the combustor example ).

For even more information on reactor equations, check out this reference:

Kee2017

R. J. Kee, M. E. Coltrin, P. Glarborg, and H. Zhu. Chemically Reacting Flow: Theory and Practice. 2nd Ed. John Wiley and Sons, 2017.

Footnotes

1

Prior to Cantera 2.6, the sense of the net heat flow was reversed, with positive \(\dot{Q}\) representing heat removal from the system. However, the sense of heat flow through a wall between two reactors was the same, with a positive value representing heat flow from the left reactor to the right reactor.