From 7121030924c655b86be637145be94fe1719338d0 Mon Sep 17 00:00:00 2001 From: Ray Speth Date: Sat, 11 Nov 2023 07:19:22 -0500 Subject: [PATCH] [Doc] Transfer docs for homogeneous reactors, flow devices, and walls --- .../constant-pressure-mole-reactor.md | 51 +++++ .../reactors/constant-pressure-reactor.md | 74 +++++++ .../reference/reactors/controlreactor.md | 44 ++-- ...deal-gas-constant-pressure-mole-reactor.md | 50 +++++ .../ideal-gas-constant-pressure-reactor.md | 71 +++++++ .../reactors/ideal-gas-mole-reactor.md | 60 ++++++ .../reference/reactors/ideal-gas-reactor.md | 89 ++++++++ doc/sphinx/reference/reactors/index.md | 141 ++++++++----- doc/sphinx/reference/reactors/interactions.md | 196 ++++++++++++++++++ doc/sphinx/reference/reactors/mole-reactor.md | 56 +++++ interfaces/cython/cantera/reactor.pyx | 2 +- 11 files changed, 766 insertions(+), 68 deletions(-) create mode 100644 doc/sphinx/reference/reactors/constant-pressure-mole-reactor.md create mode 100644 doc/sphinx/reference/reactors/constant-pressure-reactor.md create mode 100644 doc/sphinx/reference/reactors/ideal-gas-constant-pressure-mole-reactor.md create mode 100644 doc/sphinx/reference/reactors/ideal-gas-constant-pressure-reactor.md create mode 100644 doc/sphinx/reference/reactors/ideal-gas-mole-reactor.md create mode 100644 doc/sphinx/reference/reactors/ideal-gas-reactor.md create mode 100644 doc/sphinx/reference/reactors/interactions.md create mode 100644 doc/sphinx/reference/reactors/mole-reactor.md diff --git a/doc/sphinx/reference/reactors/constant-pressure-mole-reactor.md b/doc/sphinx/reference/reactors/constant-pressure-mole-reactor.md new file mode 100644 index 000000000..cbf60e6dd --- /dev/null +++ b/doc/sphinx/reference/reactors/constant-pressure-mole-reactor.md @@ -0,0 +1,51 @@ +```{py:currentmodule} cantera +``` + +# Constant Pressure Mole Reactor + +A constant pressure mole reactor is implemented by the C++ class +{ct}`ConstPressureMoleReactor` and is available in Python as the +{py:class}`ConstPressureMoleReactor` class. It is defined by the state variables: + +- $H$, the total enthalpy of the reactor's contents (in J) +- $n_k$, the number of moles for each species (in kmol) + +Equations 1 and 2 below are the governing equations for a constant pressure mole +reactor. + +## Species Equations + +The moles of each species in the reactor changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous gas phase +species and reactions on the reactor [surfaces](sec-reactor-surface). The rate at which +species $k$ is generated through homogeneous phase reactions is $V \dot{\omega}_k$, and +the total rate at which moles of species $k$ changes is: + +$$ +\frac{dn_k}{dt} = V \dot{\omega}_k + \sum_{in} \dot{n}_{k, in} + - \sum_{out} \dot{n}_{k, out} + \dot{n}_{k, wall} +$$ (const-pressure-mole-reactor-species) + +Where the subscripts *in* and *out* refer to the sum of the corresponding property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Energy Equation + +Taking the definition of the total enthalpy and differentiating with respect to time +gives: + +$$ +H &= U + pV + +\frac{dH}{dt} &= \frac{d U}{d t} + p \frac{dV}{dt} + V \frac{dp}{dt} +$$ + +Noting that $dp/dt = 0$ and substituting into the control volume mole reactor energy +equation {eq}`molereactor-energy` yields: + +$$ +\frac{dH}{dt} = \dot{Q} + \sum_{in} \dot{n}_{in} \hat{h}_{in} + - \hat{h} \sum_{out} \dot{n}_{out} +$$ (const-pressure-mole-reactor-energy) + +where positive $\dot{Q}$ represents heat addition to the system. diff --git a/doc/sphinx/reference/reactors/constant-pressure-reactor.md b/doc/sphinx/reference/reactors/constant-pressure-reactor.md new file mode 100644 index 000000000..347065447 --- /dev/null +++ b/doc/sphinx/reference/reactors/constant-pressure-reactor.md @@ -0,0 +1,74 @@ +```{py:currentmodule} cantera +``` + +# Constant Pressure Reactor + +For this reactor model, the pressure is held constant and the energy equation is defined +in terms of the total enthalpy. This model is implemented by the C++ class +{ct}`ConstPressureReactor` and available in Python as the +{py:class}`ConstPressureReactor` class. A constant pressure reactor is defined by the +state variables: + +- $m$, the mass of the reactor's contents (in kg) +- $H$, the total enthalpy of the reactor's contents (in J) +- $Y_k$, the mass fractions for each species (dimensionless) + +Equations 1-3 below are the governing equations for a constant pressure reactor. + +## Mass Conservation + +The total mass of the reactor's contents changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous phase +species on [surfaces](sec-reactor-surface): + +$$ +\frac{dm}{dt} = \sum_{in} \dot{m}_{in} - \sum_{out} \dot{m}_{out} + \dot{m}_{wall} +$$ (constpressurereactor-mass) + +Where the subscripts *in* and *out* refer to the sum of the superscripted property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Species Equations + +The rate at which species $k$ is generated through homogeneous phase reactions is $V +\dot{\omega}_k W_k$, and the total rate at which species $k$ is generated is: + +$$ \dot{m}_{k,gen} = V \dot{\omega}_k W_k + \dot{m}_{k,wall} $$ + +The rate of change in the mass of each species is: + +$$ +\frac{d(mY_k)}{dt} = \sum_{in} \dot{m}_{in} Y_{k,in} - \sum_{out} \dot{m}_{out} Y_k + + \dot{m}_{k,gen} +$$ + +Expanding the derivative on the left hand side and substituting the equation for +$dm/dt$, the equation for each homogeneous phase species is: + +$$ +m \frac{dY_k}{dt} = \sum_{in} \dot{m}_{in} (Y_{k,in} - Y_k) + + \dot{m}_{k,gen} - Y_k \dot{m}_{wall} +$$ (constpressurereactor-species) + +## Energy Equation + +Writing the first law for an open system gives: + +$$ +\frac{dU}{dt} = - p \frac{dV}{dt} + \dot{Q} + + \sum_{in} \dot{m}_{in} h_{in} - h \sum_{out} \dot{m}_{out} +$$ + +where positive $\dot{Q}$ represents heat addition to the system and $h$ is the specific +enthalpy of the reactor's contents. + +Differentiating the definition of the total enthalpy, $H = U + pV$, with respect to time +gives: + +$$ \frac{dH}{dt} = \frac{dU}{dt} + p \frac{dV}{dt} + V \frac{dp}{dt} $$ + +Noting that $dp/dt = 0$ and substituting into the energy equation yields: + +$$ +\frac{dH}{dt} = \dot{Q} + \sum_{in} \dot{m}_{in} h_{in} - h \sum_{out} \dot{m}_{out} +$$ (constpressurereactor-energy) diff --git a/doc/sphinx/reference/reactors/controlreactor.md b/doc/sphinx/reference/reactors/controlreactor.md index ea0535125..ec823b494 100644 --- a/doc/sphinx/reference/reactors/controlreactor.md +++ b/doc/sphinx/reference/reactors/controlreactor.md @@ -4,22 +4,21 @@ # Control Volume Reactor This model represents a homogeneous zero-dimensional reactor, as implemented by the C++ -class {ct}`Reactor`. By default, these reactors 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 such as {py:class}`Wall`, -{py:class}`ReactorSurface`, {py:class}`MassFlowController`, and -{py:class}`Valve`. - -A control volume reactor is defined by the four state variables: +class {ct}`Reactor` and available in Python as the {py:class}`Reactor` class. A control +volume reactor is defined by the state variables: - $m$, the mass of the reactor's contents (in kg) - $V$, the reactor volume (in m$^3$) - $U$, the total internal energy of the reactors contents (in J) - $Y_k$, the mass fractions for each species (dimensionless) +Equations 1-4 below are the governing equations for a control volume reactor. + +## Mass Conservation + The total mass of the reactor's contents changes as a result of flow through the -reactor's inlets and outlets, and production of homogeneous phase species on the reactor -{py:class}`Wall`. +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous phase +species on [surfaces](sec-reactor-surface): $$ \frac{dm}{dt} = \sum_{in} \dot{m}_{in} - \sum_{out} \dot{m}_{out} + \dot{m}_{wall} @@ -28,7 +27,10 @@ $$ (mass) Where the subscripts *in* and *out* refer to the sum of the corresponding property over all inlets and outlets respectively. A dot above a variable signifies a time derivative. -The reactor volume changes as a function of time due to the motion of one or more walls: +## Volume Equation + +The reactor volume changes as a function of time due to the motion of one or more +[walls](sec-wall): $$ \frac{dV}{dt} = \sum_w f_w A_w v_w(t) @@ -38,15 +40,7 @@ where $f_w = \pm 1$ indicates the facing of the wall (whether moving the wall in or decreases the volume of the reactor), $A_w$ is the surface area of the wall, and $v_w(t)$ is the velocity of the wall as a function of time. -The equation for the total internal energy is found by writing the first law for an open -system: - -$$ -\frac{dU}{dt} = - p \frac{dV}{dt} + \dot{Q} + - \sum_{in} \dot{m}_{in} h_{in} - h \sum_{out} \dot{m}_{out} -$$ (energy) - -Where $\dot{Q}$ is the net rate of heat addition to the system. +## Species Equations The rate at which species $k$ is generated through homogeneous phase reactions is $V \dot{\omega}_k W_k$, and the total rate at which species $k$ is generated is: @@ -70,4 +64,14 @@ m \frac{dY_k}{dt} = \sum_{in} \dot{m}_{in} (Y_{k,in} - Y_k) + \dot{m}_{k,gen} - Y_k \dot{m}_{wall} $$ (species) -Equations 1-4 are the governing equations for a control volume reactor. +## Energy Equation + +The equation for the total internal energy is found by writing the first law for an open +system: + +$$ +\frac{dU}{dt} = - p \frac{dV}{dt} + \dot{Q} + + \sum_{in} \dot{m}_{in} h_{in} - h \sum_{out} \dot{m}_{out} +$$ (cv-energy) + +Where $\dot{Q}$ is the net rate of heat addition to the system. diff --git a/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-mole-reactor.md b/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-mole-reactor.md new file mode 100644 index 000000000..fecbc0613 --- /dev/null +++ b/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-mole-reactor.md @@ -0,0 +1,50 @@ +```{py:currentmodule} cantera +``` + +# Ideal Gas Constant Pressure Mole Reactor + +An ideal gas constant pressure mole reactor, as implemented by the C++ class +{ct}`IdealGasConstPressureMoleReactor` and available in Python as the +{py:class}`IdealGasConstPressureMoleReactor` class. It is defined by the state +variables: + +- $T$, the temperature (in K) +- $n_k$, the number of moles for each species (in kmol) + +Equations 1 and 2 below are the governing equations for an ideal gas constant pressure +mole reactor. + +## Species Equations + +The moles of each species in the reactor changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous gas phase +species and reactions on the reactor [surfaces](sec-reactor-surface). The rate at which +species $k$ is generated through homogeneous phase reactions is $V \dot{\omega}_k$, and +the total rate at which moles of species $k$ changes is: + +$$ +\frac{dn_k}{dt} = V \dot{\omega}_k + \sum_{in} \dot{n}_{k, in} + - \sum_{out} \dot{n}_{k, out} + \dot{n}_{k, wall} +$$ (ig-const-pressure-mole-reactor-species) + +Where the subscripts *in* and *out* refer to the sum of the corresponding property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Energy Equation + +As for the [ideal gas mole reactor](ideal-gas-mole-reactor), we replace the total +enthalpy as a state variable with the temperature by writing the total enthalpy in terms +of the species moles and temperature: + +$$ H = \sum_k \hat{h}_k(T) n_k $$ + +and differentiating with respect to time: + +$$ \frac{dH}{dt} = \frac{dT}{dt}\sum_k n_k \hat{c}_{p,k} + \sum \hat{h}_k \dot{n}_k $$ + +Substituting this into the energy equation for the constant pressure mole reactor +{eq}`const-pressure-mole-reactor-energy` yields an equation for the temperature: + +$$ +\sum_k n_k \hat{c}_{p,k} \frac{dT}{dt} = \dot{Q} - \sum \hat{h}_k \dot{n}_k +$$ (ig-const-pressure-mole-reactor-energy) diff --git a/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-reactor.md b/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-reactor.md new file mode 100644 index 000000000..36ac59f61 --- /dev/null +++ b/doc/sphinx/reference/reactors/ideal-gas-constant-pressure-reactor.md @@ -0,0 +1,71 @@ +```{py:currentmodule} cantera +``` + +# Ideal Gas Constant Pressure Reactor + +An ideal gas constant pressure reactor, as implemented by the C++ class +{ct}`IdealGasConstPressureReactor` and available in Python as the +{py:class}`IdealGasConstPressureReactor` class. It is defined by the state variables: + +- $m$, the mass of the reactor's contents (in kg) +- $T$, the temperature (in K) +- $Y_k$, the mass fractions for each species (dimensionless) + +Equations 1-3 below are the governing equations for an ideal gas constant pressure +reactor. + +## Mass Conservation + +The total mass of the reactor's contents changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous phase +species on [surfaces](sec-reactor-surface): + +$$ +\frac{dm}{dt} = \sum_{in} \dot{m}_{in} - \sum_{out} \dot{m}_{out} + \dot{m}_{wall} +$$ (igcpr-mass) + +Where the subscripts *in* and *out* refer to the sum of the corresponding property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Species Equations + +The rate at which species $k$ is generated through homogeneous phase reactions is +$V \dot{\omega}_k W_k$, and the total rate at which species $k$ is generated is: + +$$ \dot{m}_{k,gen} = V \dot{\omega}_k W_k + \dot{m}_{k,wall} $$ + +The rate of change in the mass of each species is: + +$$ +\frac{d(mY_k)}{dt} = \sum_{in} \dot{m}_{in} Y_{k,in} - \sum_{out} \dot{m}_{out} Y_k + + \dot{m}_{k,gen} +$$ + +Expanding the derivative on the left hand side and substituting the equation +for $dm/dt$, the equation for each homogeneous phase species is: + +$$ +m \frac{dY_k}{dt} = \sum_{in} \dot{m}_{in} (Y_{k,in} - Y_k) + \dot{m}_{k,gen} + - Y_k \dot{m}_{wall} +$$ (igcpr-species) + +## Energy Equation + +As for the [ideal gas reactor](ideal-gas-reactor), we replace the total enthalpy as a +state variable with the temperature by writing the total enthalpy in terms of the mass +fractions and temperature and differentiating with respect to time: + +$$ +H &= m \sum_k Y_k h_k(T) + +\frac{dH}{dt} &= h \frac{dm}{dt} + m c_p \frac{dT}{dt} + + m \sum_k h_k \frac{dY_k}{dt} +$$ + +Substituting the corresponding derivatives into the constant pressure reactor energy +equation {eq}`constpressurereactor-energy` yields an equation for the temperature: + +$$ +m c_p \frac{dT}{dt} = \dot{Q} - \sum_k h_k \dot{m}_{k,gen} + + \sum_{in} \dot{m}_{in} \left(h_{in} - \sum_k h_k Y_{k,in} \right) +$$ (igcpr-energy) diff --git a/doc/sphinx/reference/reactors/ideal-gas-mole-reactor.md b/doc/sphinx/reference/reactors/ideal-gas-mole-reactor.md new file mode 100644 index 000000000..d12ddd7c0 --- /dev/null +++ b/doc/sphinx/reference/reactors/ideal-gas-mole-reactor.md @@ -0,0 +1,60 @@ +```{py:currentmodule} cantera +``` + +# Ideal Gas Control Volume Mole Reactor + +An ideal gas control volume mole reactor, as implemented by the C++ class +{ct}`IdealGasMoleReactor` and available in Python as the {py:class}`IdealGasMoleReactor` +class. It is defined by the state variables: + +- $T$, the temperature (in K) +- $V$, the reactor volume (in m{sup}`3`) +- $n_k$, the number of moles for each species (in kmol) + +Equations 1-3 are the governing equations for an ideal gas control volume mole reactor. + +## Volume Equation + +The reactor volume can change as a function of time due to the motion of one or more +[walls](sec-wall): + +$$ +\frac{dV}{dt} = \sum_w f_w A_w v_w(t) +$$ (ig-mole-reactor-volume) + +Where $f_w = \pm 1$ indicates the facing of the wall (whether moving the wall increases +or decreases the volume of the reactor), $A_w$ is the surface area of the wall, and +$v_w(t)$ is the velocity of the wall as a function of time. + +## Species Equations + +The moles of each species in the reactor changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous gas phase +species and reactions on the reactor [surfaces](sec-reactor-surface). The rate at which +species $k$ is generated through homogeneous phase reactions is $V \dot{\omega}_k$, and +the total rate at which moles of species $k$ changes is: + +$$ +\frac{dn_k}{dt} = V \dot{\omega}_k + \sum_{in} \dot{n}_{k, in} + - \sum_{out} \dot{n}_{k, out} + \dot{n}_{k, wall} +$$ (ig-mole-reactor-species) + +## Energy Equation + +In the case of the ideal gas control volume mole reactor model, the reactor temperature +$T$ is used instead of the total internal energy $U$ as a state variable. For an ideal +gas, we can rewrite the total internal energy in terms of the species moles and +temperature: + +$$ U = \sum_k \hat{u}_k(T) n_k $$ + +and differentiate it with respect to time to obtain: + +$$ \frac{dU}{dt} = \frac{dT}{dt}\sum_k n_k \hat{c}_{v,k} + \sum \hat{u}_k \dot{n}_k $$ + +Substituting this into the energy equation for the control volume mole reactor +{eq}`molereactor-energy` yields an equation for the temperature: + +$$ +\sum_k n_k \hat{c}_{v,k} \frac{dT}{dt} = \dot{Q} - \sum \hat{u}_k \dot{n}_k +$$ (ig-mole-reactor-energy) diff --git a/doc/sphinx/reference/reactors/ideal-gas-reactor.md b/doc/sphinx/reference/reactors/ideal-gas-reactor.md new file mode 100644 index 000000000..8801f46cd --- /dev/null +++ b/doc/sphinx/reference/reactors/ideal-gas-reactor.md @@ -0,0 +1,89 @@ +```{py:currentmodule} cantera +``` + +# Ideal Gas Control Volume Reactor + +An ideal gas control volume reactor, as implemented by the C++ class +{ct}`IdealGasReactor` and available in Python as the {py:class}`IdealGasReactor` class. +It is defined by the state variables: + +- $m$, the mass of the reactor's contents (in kg) +- $V$, the reactor volume (in m{sup}`3`) +- $T$, the temperature (in K) +- $Y_k$, the mass fractions for each species (dimensionless) + +Equations 1-4 below are the governing equations for an ideal gas reactor. + +## Mass Conservation + +The total mass of the reactor's contents changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of gas phase species on +[surfaces](sec-reactor-surface): + +$$ +\frac{dm}{dt} = \sum_{in} \dot{m}_{in} - \sum_{out} \dot{m}_{out} + \dot{m}_{wall} +$$ (igr-mass) + +where the subscripts *in* and *out* refer to the sum of the corresponding property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Volume Equation + +The reactor volume can change as a function of time due to the motion of one or more +[walls](sec-wall): + +$$ +\frac{dV}{dt} = \sum_w f_w A_w v_w(t) +$$ (igr-volume) + +where $f_w = \pm 1$ indicates the facing of the wall (whether moving the wall increases +or decreases the volume of the reactor), $A_w$ is the surface area of the wall, and +$v_w(t)$ is the velocity of the wall as a function of time. + +## Species Equations + +The rate at which species $k$ is generated through homogeneous phase reactions is +$V \dot{\omega}_k W_k$, and the total rate at which species $k$ is generated is: + +$$ \dot{m}_{k,gen} = V \dot{\omega}_k W_k + \dot{m}_{k,wall} $$ + +The rate of change in the mass of each species is: + +$$ +\frac{d(mY_k)}{dt} = \sum_{in} \dot{m}_{in} Y_{k,in} - \sum_{out} \dot{m}_{out} Y_k + + \dot{m}_{k,gen} +$$ + +Expanding the derivative on the left hand side and substituting the equation +for $dm/dt$, the equation for each homogeneous phase species is: + +$$ +m \frac{dY_k}{dt} = \sum_{in} \dot{m}_{in} (Y_{k,in} - Y_k)+ \dot{m}_{k,gen} + - Y_k \dot{m}_{wall} +$$ (igr-species) + +## Energy Equation + +In the case of the ideal gas control volume reactor model, the reactor temperature $T$ +is used instead of the total internal energy $U$ as a state variable. For an ideal gas, +we can rewrite the total internal energy in terms of the mass fractions and temperature: + +$$ U = m \sum_k Y_k u_k(T) $$ + +and differentiate it with respect to time to obtain: + +$$ +\frac{dU}{dt} = u \frac{dm}{dt} + m c_v \frac{dT}{dt} + m \sum_k u_k \frac{dY_k}{dt} +$$ + +Substituting this into the energy equation for the control volume reactor +{eq}`cv-energy` yields an equation for the temperature: + +$$ +m c_v \frac{dT}{dt} =& - p \frac{dV}{dt} + \dot{Q} + \sum_{in} \dot{m}_{in} \left( h_{in} - \sum_k u_k Y_{k,in} \right) \\ + &- \frac{p V}{m} \sum_{out} \dot{m}_{out} - \sum_k \dot{m}_{k,gen} u_k +$$ (igr-energy) + +While this form of the energy equation is somewhat more complicated, it significantly +reduces the cost of evaluating the system Jacobian, since the derivatives of the species +equations are taken at constant temperature instead of constant internal energy. diff --git a/doc/sphinx/reference/reactors/index.md b/doc/sphinx/reference/reactors/index.md index fe80fddfd..0ea87da92 100644 --- a/doc/sphinx/reference/reactors/index.md +++ b/doc/sphinx/reference/reactors/index.md @@ -1,3 +1,6 @@ +```{py:currentmodule} cantera +``` + # Reactors and Reactor Networks ```{caution} @@ -5,63 +8,107 @@ This page is a work in progress. For more complete documentation of the current release (Cantera 3.0), please see this page. ``` -## 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. +In Cantera, a *reactor network* represents a set of one or more homogeneous reactors and +reacting surfaces that may be connected to each other and to the environment through +devices representing mass flow, heat transfer, and moving walls. The system is generally +unsteady -- that is, all states are functions of time. In particular, transient state +changes due to chemical reactions are possible. ## 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. +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. By default, these reactors are closed (no +inlets or outlets) and have adiabatic, chemically-inert walls. These properties may all +be changed by adding components such as walls, surfaces, mass flow controllers, and +valves, as described [below](sec-reactor-interactions). +The specific governing equations defining Cantera's reactor models are derived and +described below. These models represent different combinations of whether pressure or +volume are held constant, whether they support any equation of state or are specialized +for ideal gas mixtures, and whether mass fractions or moles of each species are used as +the state variables representing the composition. -````{grid} 2 -:gutter: 3 +[Control Volume Reactor](controlreactor) +: A reactor where the volume is prescribed by the motion of the reactor's walls. -```{grid-item-card} Control Volume Reactor -:link: controlreactor -:link-type: doc +[Constant Pressure Reactor](constant-pressure-reactor) +: A reactor where the pressure is held constant. -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. -``` +[Ideal Gas Control Volume Reactor](ideal-gas-reactor) +: A reactor where the volume is prescribed by the motion of the reactor's walls, + specialized for ideal gas mixtures. -```` +[Ideal Gas Constant Pressure Reactor](ideal-gas-constant-pressure-reactor) +: A reactor where the pressure is held constant, specialized for ideal gas mixtures. + +[Control Volume Mole Reactor](mole-reactor) +: A reactor where the volume is prescribed by the motion of the reactor's walls, with + the composition stored in moles. + +[Constant Pressure Mole Reactor](constant-pressure-mole-reactor) +: A reactor where the pressure is held constant and the composition is stored in moles. + +[Ideal Gas Control Volume Mole Reactor](ideal-gas-mole-reactor) +: A reactor where the volume is prescribed by the motion of the reactor's walls, + specialized for ideal gas mixtures and with the composition stored in moles. + +[Ideal Gas Constant Pressure Mole Reactor](ideal-gas-constant-pressure-mole-reactor) +: A reactor where the pressure is held constant, specialized for ideal gas mixtures and + with the composition stored in moles. ```{toctree} :hidden: +:caption: Reactor models +:maxdepth: 1 controlreactor -``` \ No newline at end of file +constant-pressure-reactor +ideal-gas-reactor +ideal-gas-constant-pressure-reactor +mole-reactor +constant-pressure-mole-reactor +ideal-gas-mole-reactor +ideal-gas-constant-pressure-mole-reactor + +interactions +``` + +(sec-reactor-interactions)= +## Reactor Interactions + +Reactors can interact with each other and the surrounding environment in multiple ways. +Mass can flow from one reactor into another can be incorporated, heat can be +transferred, and the walls between reactors can move. In addition, reactions can occur +on surfaces within a reactor. The models used to establish these interconnections are +described in the following sections: + +All of these interactions can vary as a function of time or system state. For example, +heat transfer can be described as a function of the temperature difference between the +reactor and the environment, or wall movement can be modeled as depending on the +pressure difference. Interactions of the reactor with the environment are defined using +the following models: + +[Reservoirs](sec-reservoir) +: Reservoirs are used to represent constant conditions defining the inlets, outlets, and + surroundings of a reactor network. + +[Flow Devices](sec-flow-device) +: Flow devices are used to define mass transfer between two reactors, or between + reactors and the surrounding environment as defined by a reservoir. + +[Walls](sec-wall) +: Walls between reactors are used to allow heat transfer between reactors. 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. + +[Reacting Surfaces](sec-reactor-surface) +: Reactions may occur on the surfaces of a reactor. These reactions may include both + catalytic reactions and reactions resulting in net mass transfer between the surface + and the fluid. + +```{seealso} +Cantera comes with a broad variety of well-commented example scrips for reactor +networks. Please see the [Cantera Examples](/examples/python/reactors/index) for further +information. +``` diff --git a/doc/sphinx/reference/reactors/interactions.md b/doc/sphinx/reference/reactors/interactions.md new file mode 100644 index 000000000..bcb1485b0 --- /dev/null +++ b/doc/sphinx/reference/reactors/interactions.md @@ -0,0 +1,196 @@ +```{py:currentmodule} cantera +``` + +# Reactor Interactions + +(sec-reservoir)= +## Reservoirs + +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. In addition, the fluid flow exiting a +reactor network has to flow into a reservoir. In the latter case, the state of the +reservoir (except pressure) is irrelevant. + +:::{admonition} Python Usage +:class: tip + +In Python, a reservoir can be defined using the {py:class}`Reservoir` class. +::: + +(sec-flow-device)= +## Flow Devices + +A *flow device* connects two reactors and allows mass flow from an upstream reactor (1) +to a downstream reactor (2). Different kinds of flow devices are defined based on how +the mass flow rate is determined. + +A reactor can have multiple inlets and outlets. For the inlets, arbitrary states can be +defined by setting a reservoir as the upstream reactor. Fluid with the current state of +the reactor exits the reactor at the outlets. + +(sec-valve)= +### Valves + +A *valve* is a flow device with mass flow rate that is a function of the pressure drop +across it. The mass flow rate is computed as: + +$$ \dot m = K_v g(t) f(P_1 - P_2) $$ + +with $K_v$ being a proportionality constant in kg/s/Pa and $f$ and $g$ being scalar +functions that can be defined by the user. By default, $g(t) = 1$ and $f(\Delta P) = +\Delta P$ such that the mass flow rate defaults to: + +$$ \dot m = K_v (P_1 - P_2) $$ + +corresponding to a linear dependence of the mass flow rate on the pressure difference. +The pressure difference between the upstream (1) and downstream (2) reactor is defined +as $P_1 - P_2$. The flow is not allowed to reverse and go from the downstream to the +upstream reactor/reservoir, which means that the flow rate is set to zero if $P_1 < +P_2$. + +Valves 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. However, excessively large values +of $K_v$ may slow down the integrator or cause it to fail. + +:::{admonition} Python Usage +:class: tip + +In Python, a valve is implemented by class {py:class}`Valve`; $K_v$ is set using the +{py:attr}`Valve.valve_coeff` property; $f(\Delta P)$ is set using the +{py:attr}`Valve.time_function` property; and $g(t)$ is set using the +{py:attr}`Valve.pressure_function` property. +::: + +(sec-mass-flow-controller)= +### Mass Flow Controllers + +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 = m_0 g(t) $$ + +where $m_0$ is a mass flow coefficient and $g(t)$ is user-specifiable function of time +that defaults to $g(t) = 1$. 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 Cantera mass flow controller 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. + +:::{admonition} Python Usage +:class: tip + +Mass flow controllers can be implemented in Python using the +{py:class}`MassFlowController` class. The {py:attr}`MassFlowController.mass_flow_coeff` +property can be used to set $m_0$ and the {py:attr}`MassFlowController.time_function` +property can be used to set $g(t)$. +::: + +(sec-pressure-controller)= +### Pressure Controllers + +A pressure controller is designed to be used in conjunction with another "primary" flow +controller, typically a mass flow controller. The primary flow controller is installed +on the inlet of the reactor, and the corresponding pressure controller is installed on +on outlet of the reactor. The mass flow rate of the pressure controller is equal to that +of the primary mass flow rate, plus a small correction dependent on the pressure +difference: + +$$ \dot m = \dot m_{\text{primary}} + K_v f(P_1 - P_2) $$ + +where $K_v$ is a proportionality constant and $f$ is a function of the pressure drop +that defaults to $f(\Delta P) = \Delta P$. If $\dot m < 0$, the mass flow rate will be +set to zero, since a reversal of the flow direction is not allowed. + +:::{admonition} Python Usage +:class: tip + +Pressure controllers can be defined in Python using the {py:class}`PressureController` +class. The primary flow controller can be set using the +{py:attr}`PressureController.primary` property; $K_v$ can be set using the +{py:attr}`PressureController.pressure_coeff` property; and $f(\Delta P)$ can be set +using the {py:attr}`PressureController.pressure_function`. +::: + +(sec-wall)= +## Walls + +In Cantera, 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_{\mathrm{left}} - P_{\mathrm{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 total rate of heat transfer through all walls is: + +$$ \dot{Q} = \sum_w f_w \dot{Q}_w $$ + +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: + +$$ +\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) +$$ + +where $U$ is a user-specified heat transfer coefficient (W/m{sup}`2`-K), $A$ is the wall +area (m{sup}`2`), $\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/m{sup}`2`). 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. + +:::{admonition} Python Usage +:class: tip + +In Python, walls are defined using the {py:class}`Wall` class. +::: + +(sec-reactor-surface)= +## Reacting Surfaces + +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/m{sup}`2`). The +total (mass) production rate for homogeneous phase species $k$ on all walls is: + +$$ \dot{m}_{k,wall} = W_k \sum_w A_w \dot{s}_{k,w} $$ + +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: + +$$ \dot{m}_{wall} = \sum_k \dot{m}_{k,wall} $$ + +For each surface species $i$, the rate of change of the site fraction $\theta_{i,w}$ on +each wall $w$ is integrated with time: + +$$ \frac{d\theta_{i,w}}{dt} = \frac{\dot{s}_{i,w} \sigma_i}{\Gamma_w} $$ + +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: + +$$ \dot{n}_{k, wall} = A_{w}\sum_{w}\dot{s}_{w, k} $$ + +:::{admonition} Python Usage +:class: tip + +In Python, reacting surfaces are defined using the {py:class}`ReactorSurface` class. +::: diff --git a/doc/sphinx/reference/reactors/mole-reactor.md b/doc/sphinx/reference/reactors/mole-reactor.md new file mode 100644 index 000000000..76a7073e7 --- /dev/null +++ b/doc/sphinx/reference/reactors/mole-reactor.md @@ -0,0 +1,56 @@ +```{py:currentmodule} cantera +``` + +# Control Volume Mole Reactor + +A control volume mole reactor, as implemented by the C++ class {ct}`MoleReactor` and +available in Python as the {py:class}`MoleReactor` class. It is defined by the state +variables: + +- $U$, the total internal energy of the reactor's contents (in J) +- $V$, the reactor volume (in m{sup}`3`) +- $n_k$, the number of moles for each species (in kmol) + +Equations 1-3 are the governing equations for a control volume mole reactor. + +## Volume Equation + +The reactor volume changes as a function of time due to the motion of one or +more [walls](sec-wall): + +$$ +\frac{dV}{dt} = \sum_w f_w A_w v_w(t) +$$ (molereactor-volume) + +where $f_w = \pm 1$ indicates the facing of the wall (whether moving the wall increases +or decreases the volume of the reactor), $A_w$ is the surface area of the wall, and +$v_w(t)$ is the velocity of the wall as a function of time. + +## Species Equations + +The moles of each species in the reactor changes as a result of flow through the +reactor's [inlets and outlets](sec-flow-device), and production of homogeneous gas phase +species and reactions on the reactor [surfaces](sec-reactor-surface). The rate at which +species $k$ is generated through homogeneous phase reactions is $V \dot{\omega}_k$, and +the total rate at which moles of species $k$ changes is: + +$$ +\frac{dn_k}{dt} = V \dot{\omega}_k + \sum_{in} \dot{n}_{k, in} + - \sum_{out} \dot{n}_{k, out} + \dot{n}_{k, wall} +$$ (molereactor-species) + +where the subscripts *in* and *out* refer to the sum of the corresponding property over +all inlets and outlets respectively. A dot above a variable signifies a time derivative. + +## Energy Equation + +The equation for the total internal energy is found by writing the first law for an open +system: + +$$ +\frac{dU}{dt} = - p \frac{dV}{dt} + \dot{Q} + \sum_{in} \dot{n}_{in} \hat{h}_{in} + - \hat{h} \sum_{out} \dot{n}_{out} +$$ (molereactor-energy) + +where $\dot{Q}$ is the net rate of heat addition to the system and $\hat{h}$ is the +molar enthalpy. diff --git a/interfaces/cython/cantera/reactor.pyx b/interfaces/cython/cantera/reactor.pyx index 4dfe4ea05..92752f9e9 100644 --- a/interfaces/cython/cantera/reactor.pyx +++ b/interfaces/cython/cantera/reactor.pyx @@ -1434,7 +1434,7 @@ cdef class Valve(FlowDevice): .. math:: \dot m = K_v*(P_1 - P_2) - where :math:`K_v` is a constant set by the `set_valve_coeff` method. + where :math:`K_v` is a constant set using the `valve_coeff` property. Note that :math:`P_1` must be greater than :math:`P_2`; otherwise, :math:`\dot m = 0`. However, an arbitrary function can also be specified, such that