Fuel Cycle

This demonstration re-creates the tritium fuel cycle model described by Abdou et al. (2021). It is also described in Simon et al. (2025).

There are multiple ways to generate an input file that uses scalar kernels. The ParsedODEKernel and ODETimeDerivative can be used to deal with almost any system of ordinary differential equations, but there is also a utility class FuelCycleSystemScalarKernel which can be used to simplify the inputs.

Generating the Input File

First, we instantiate a mesh

[Mesh<<<{"href": "../../syntax/Mesh/index.html"}>>>]
  type = GeneratedMesh
  dim = 1
  xmin = 0
  xmax = 1
  nx = 1
[]

For our purposes this does nothing, but MOOSE requires a defined mesh as a placeholder to run the rest of the simulation.

Next, we need to define our system. Following the convention in Abdou et al. (2021), we have 11 modeled systems, each with their own ODE and tritium inventory:

Table 1: Systems and labels used in this example.

System NameSystem NumberTritium Inventory VariableSystem Equation
Breeding zone1T_01_BZEq. (1)
Tritium Extraction System2T_02_TESEq. (2)
First Wall3T_03_FWEq. (3)
Divertor4T_04_DIVEq. (4)
Heat Exchanger5T_05_HXEq. (5)
Coolant Purification System6T_06_CPSEq. (6)
Vacuum Pump7T_07_vacuumEq. (7)
Fuel Clean-up8T_08_FCUEq. (8)
Isotope Separation System9T_09_ISSEq. (9)
Exhaust and Water Detritiation System10T_10_exhaustEq. (10)
Storage and Management11T_11_storageEq. (11)

(1)

(2)

(3)

(4)

(5)

(6)

(7)

(8)

(9) (10) (11)

For an interpretation of these equations and explanations about the notations, readers should refer to Abdou et al. (2021) (Appendix). We instantiate the variables in the typical Variables block, making sure to set the "family" attribute to SCALAR for each variable. The default initial condition is zero.

[Variables<<<{"href": "../../syntax/Variables/index.html"}>>>]
  [T_01_BZ]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_02_TES]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_03_FW]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_04_DIV]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_05_HX]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_06_CPS]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_07_vacuum]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_08_FCU]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_09_ISS]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_10_exhaust]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
  []
  [T_11_storage]
    family<<<{"description": "Specifies the family of FE shape functions to use for this variable"}>>> = SCALAR
    initial_condition<<<{"description": "Specifies a constant initial condition for this variable"}>>> = 225.4215
  []
[]

Next we initiate the ScalarKernels block. We can model the time-dependent terms with ODETimeDerivative objects and the other terms can be lumped in ParsedODEKernel objects. We should have one ODETimeDerivative and one (or more) ParsedODEKernel object(s) per equation above. Internally, TMAP8 will sum the contributions of each object, so we need to negate the ParsedODEKernel equation from its representation above (move it to the left hand side). We use Postprocessors to re-use the recurring variables.

[ScalarKernels<<<{"href": "../../syntax/ScalarKernels/index.html"}>>>]
  [I1t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_01_BZ
  []
  [I2t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_02_TES
  []
  [I3t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_03_FW
  []
  [I4t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_04_DIV
  []
  [I5t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_05_HX
  []
  [I6t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_06_CPS
  []
  [I7t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_07_vacuum
  []
  [I8t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_08_FCU
  []
  [I9t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_09_ISS
  []
  [I10t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_10_exhaust
  []
  [I11t]
    type = ODETimeDerivative<<<{"description": "Returns the time derivative contribution to the residual for a scalar variable.", "href": "../../source/scalarkernels/ODETimeDerivative.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = T_11_storage
  []
  [I1]
    # Breeding Zone
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(tritium_burn_rate * TBR + (1 - TES_efficiency)*T_02_TES/residence2 - T_01_BZ/residence1
                    - T_01_BZ*epsilon1/residence1 - T_01_BZ*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_01_BZ'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_02_TES'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'TBR tritium_burn_rate TES_efficiency residence1 residence2 tdecay epsilon1'
  []
  [I2]
    #Tritium Extraction System
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-((1 - BZ_HX_leak_fraction)*T_01_BZ/residence1 - T_02_TES/residence2
                     - T_02_TES*epsilon2/residence2 - T_02_TES*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_02_TES'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_01_BZ'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'BZ_HX_leak_fraction residence1 residence2 tdecay epsilon2'
  []
  [I3]
    #First Wall
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(P_FW_leak_fraction*tritium_burn_rate /tritium_burn_fraction / tritium_fueling_efficiency
                    + HX_FW_leak_fraction * (1 - HX_CPS_leak_fraction) * (1 - HX_EXO_leak_fraction)
                    * T_05_HX/residence5 + CPS_FW_leak_fraction * (1 - CPS_efficiency) * T_06_CPS/residence6
                    - T_03_FW/residence3 - T_03_FW*epsilon3/residence3 - T_03_FW*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_03_FW'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_05_HX T_06_CPS'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'P_FW_leak_fraction tritium_burn_rate tritium_burn_fraction tritium_fueling_efficiency
                      HX_FW_leak_fraction HX_CPS_leak_fraction HX_EXO_leak_fraction residence5
                      CPS_FW_leak_fraction CPS_efficiency residence6 residence3 tdecay epsilon3'
  []
  [I4]
    #Divertor
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(P_DIV_leak_fraction * tritium_burn_rate/tritium_burn_fraction / tritium_fueling_efficiency
                    + (1-HX_FW_leak_fraction)* (1-HX_CPS_leak_fraction)*(1-HX_EXO_leak_fraction)
                    * T_05_HX/residence5 + (1-CPS_FW_leak_fraction)*(1 - CPS_efficiency) * T_06_CPS/residence6
                      - T_04_DIV*epsilon4/residence4 - T_04_DIV/residence4 - T_04_DIV*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_04_DIV'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_06_CPS T_05_HX'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'P_DIV_leak_fraction tritium_burn_rate tritium_burn_fraction
                     tritium_fueling_efficiency HX_FW_leak_fraction HX_CPS_leak_fraction
                     HX_EXO_leak_fraction residence5 CPS_FW_leak_fraction CPS_efficiency
                     residence6 residence4 tdecay epsilon4'
  []
  [I5]
    #Heat eXchanger
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(BZ_HX_leak_fraction * T_01_BZ/residence1 + T_03_FW/residence3 + T_04_DIV/residence4
                  - T_05_HX/residence5 - T_05_HX*epsilon5/residence5 -T_05_HX*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_05_HX'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_01_BZ T_03_FW T_04_DIV'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'BZ_HX_leak_fraction residence1 residence3 residence4 residence5 tdecay
                      epsilon5'
  []
  [I6]
    #Coolant Purification System
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(HX_CPS_leak_fraction * (1 - HX_EXO_leak_fraction)*T_05_HX/residence5
                    - T_06_CPS/residence6 - T_06_CPS*epsilon6/residence6 - T_06_CPS*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_06_CPS'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_05_HX'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'HX_CPS_leak_fraction HX_EXO_leak_fraction residence5 residence6 tdecay
                      epsilon6'
  []
  [I7]
    #Vacuum Pump
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-((1-tritium_burn_fraction*tritium_fueling_efficiency - P_FW_leak_fraction
                    - P_DIV_leak_fraction)* tritium_burn_rate/(tritium_burn_fraction
                    * tritium_fueling_efficiency) - T_07_vacuum/residence7
                    - T_07_vacuum*epsilon7/residence7 - T_07_vacuum*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_07_vacuum'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'tritium_burn_rate tritium_fueling_efficiency P_FW_leak_fraction
                      P_DIV_leak_fraction tritium_burn_fraction residence7 tdecay epsilon7'
  []
  [I8]
    #Fuel clean-up
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(T_07_vacuum/residence7 - T_08_FCU/residence8 - T_08_FCU*epsilon8/residence8
                    - T_08_FCU*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_08_FCU'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'residence7 residence8 tdecay epsilon8'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_07_vacuum'
  []
  [I9]
    #Isotope Separation System
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-((1-FCU_STO_fraction)*T_08_FCU/residence8 + T_10_exhaust/residence10
                    + TES_efficiency*T_02_TES/residence2 + CPS_efficiency*T_06_CPS/residence6
                    - T_09_ISS/residence9 - T_09_ISS*epsilon9/residence9 - T_09_ISS*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_09_ISS'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_08_FCU T_10_exhaust T_02_TES T_06_CPS'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'FCU_STO_fraction residence8 residence10 TES_efficiency residence2
                      CPS_efficiency residence6 residence9 tdecay epsilon9'
  []
  [I10]
    #Exhaust and Water Detritiation System (EXO)
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(HX_EXO_leak_fraction * T_05_HX/residence5 + ISS_EXO_leak_fraction*T_09_ISS/residence9
                    - T_10_exhaust/residence10 - T_10_exhaust*epsilon10/residence10 - T_10_exhaust*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_10_exhaust'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_05_HX T_09_ISS'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'HX_EXO_leak_fraction residence5 ISS_EXO_leak_fraction residence9 residence10
                      tdecay epsilon10'
  []
  [I11]
    #Storage and Management (STO)
    type = ParsedODEKernel<<<{"description": "Parsed expression ODE kernel.", "href": "../../source/scalarkernels/ParsedODEKernel.html"}>>>
    expression<<<{"description": "function expression"}>>> = '-(FCU_STO_fraction * T_08_FCU/residence8 + (1-ISS_EXO_leak_fraction)*T_09_ISS/residence9
                    - tritium_burn_rate/tritium_burn_fraction/tritium_fueling_efficiency
                    - T_11_storage*tdecay)'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_11_storage'
    coupled_variables<<<{"description": "Scalar variables coupled in the parsed expression."}>>> = 'T_08_FCU T_09_ISS'
    postprocessors<<<{"description": "Vector of postprocessor names used in the function expression"}>>> = 'FCU_STO_fraction residence8 ISS_EXO_leak_fraction residence9 tritium_burn_rate
                      tritium_burn_fraction tritium_fueling_efficiency tdecay'
  []
[]
(test/tests/fuel_cycle_Abdou/fuel_cycle.i)

Manually entering equations that describe these systems opens the potential for arithmetical errors, so the FuelCycleSystemScalarKernel scalar kernel has been created, allowing each system to be modelled with one scalar kernel. Each of the parameters in the scalar kernel is only required to be a Functor, allowing great flexibility in the kinds of information that can be fed to the scalar kernel. An example model using each approach can be found at fuel_cycle_abdou.i and fuel_cycle_abdou_generic.i

[ScalarKernels<<<{"href": "../../syntax/ScalarKernels/index.html"}>>>]
  [I1]
    # Breeding Zone
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    TBR<<<{"description": "Tritium breeding ratio. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = TBR
    burn_rate<<<{"description": "Burn rate of tritium within this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = tritium_burn_rate
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_02_TES '
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = TES_frac # expression = '(1 - TES_efficiency)/residence2'
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence1
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon1
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_01_BZ'
  []
  [I2]
    #Tritium Extraction System
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_01_BZ'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = BZ_TES_frac
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence2
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon2
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_02_TES'
  []
  [I3]
    #First Wall
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_03_FW'
    other_sources<<<{"description": "Other tritium sources - terms not dependent on any scalar variables. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'plasma_FW_flux'
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_05_HX T_06_CPS'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'HX_FW_flux HX_CPS_flux'
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence3
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon3
  []
  [I4]
    #Divertor
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    other_sources<<<{"description": "Other tritium sources - terms not dependent on any scalar variables. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'plasma_div_flux'
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_05_HX T_06_CPS'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'HX_div_flux CPS_div_flux'
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence4
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon4
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_04_DIV'
  []
  [I5]
    #Heat eXchanger
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_01_BZ T_03_FW T_04_DIV'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'BZ_HX_flux FW_HX_flux div_HX_flux'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_05_HX'
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'residence5'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon5
  []
  [I6]
    #Coolant Purification System
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_05_HX'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'CPS_HX_flux'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon6
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence6
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_06_CPS'
  []
  [I7]
    #Vacuum Pump
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    other_sources<<<{"description": "Other tritium sources - terms not dependent on any scalar variables. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = Vacuum_pump_breeding
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_07_vacuum'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon7
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence7
  []
  [I8]
    #Fuel clean-up
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_07_vacuum'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'VAC_FCX_flux'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon8
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence8
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_08_FCU'
  []
  [I9]
    #Isotope Separation System
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_02_TES T_06_CPS T_08_FCU T_10_exhaust'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'TES_ISS_flux CPS_ISS_flux FCU_ISS_flux EXH_ISS_flux'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon9
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence9
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_09_ISS'
  []
  [I10]
    #Exhaust and Water Detritiation System (EXO)
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_05_HX T_09_ISS'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'HX_EXO_flux ISS_EXO_flux'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_10_exhaust'
    leakage_rate<<<{"description": "The fractional loss rate for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = epsilon10
    residence_time<<<{"description": "The residence time for tritium in this system. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = residence10
  []
  [I11]
    #Storage and Management (STO)
    type = FuelCycleSystemScalarKernel<<<{"description": "Implements a generic scalar system component for tritium fuel cycle calculations.", "href": "../../source/scalarkernels/FuelCycleSystemScalarKernel.html"}>>>
    inputs<<<{"description": "Variables (usually tritium inventory) which feed into this system. Takes a list of scalar variable names"}>>> = 'T_08_FCU T_09_ISS'
    input_fractions<<<{"description": "Fraction of upstream variable (inventory) coming into this system. Must be the same length as 'inputs'. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'FCU_STO_flux ISS_STO_flux'
    other_sinks<<<{"description": "Other tritium sinks - terms not dependent on any scalar variables. A functor is any of the following: a variable, a functor material property, a function, a postprocessor or a number."}>>> = 'device_T_consumption'
    variable<<<{"description": "The name of the variable that this residual object operates on"}>>> = 'T_11_storage'
    disable_residence_time<<<{"description": "Assume an infinite residence time. (no leakage from this system)."}>>> = true
  []
[]
(test/tests/fuel_cycle_Abdou/fuel_cycle_abdou_generic.i)

Finally, we define the Postprocessors and set their values to those referenced in Abdou et al. (2021). Because the Postprocessors are inputs, not outputs, we must be careful to properly set the "execute_on" parameter. We also gather the values of the different variables in separate Postprocessors and take their sum to obtain the total tritium inventory.

[Postprocessors<<<{"href": "../../syntax/Postprocessors/index.html"}>>>]
  [BZ_HX_leak_fraction]
    #f_{1-5}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-2
  []
  [CPS_FW_leak_fraction]
    #f_{6-3}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.6
  []
  [CPS_efficiency]
    #eta_6
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.95
  []
  [FCU_STO_fraction]
    #f_{8-11}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0
  []
  [HX_CPS_leak_fraction]
    #f_{5-6}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-2
  []
  [HX_EXO_leak_fraction]
    #f_{5-10}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [HX_FW_leak_fraction]
    #f_{5-3}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.6
  []
  [ISS_EXO_leak_fraction]
    #f_{9-10}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-1
  []
  [P_DIV_leak_fraction]
    #f_{P-4}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [P_FW_leak_fraction]
    #f_{P_3}
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [TES_efficiency]
    #eta_2
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.95
  []
  [TBR]
    #According to the PhD Thesis referenced in the paper,
    # this is the required Tritium Breeding Ratio (TBR)
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1.9247
  []
  [epsilon1]
    #BZ
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0
  []
  [epsilon2]
    #TES
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon3]
    #FW
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0
  []
  [epsilon4]
    #DIV
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0
  []
  [epsilon5]
    #HX
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon6]
    #CPS
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon7]
    #Vac
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon8]
    #FCU
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon9]
    #ISS
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon10]
    #EXO
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1e-4
  []
  [epsilon11]
    #STO
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0
  []
  [residence1]
    #BZ
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 86400 #1 day, Abdou
    #value = 8640-86400 EXOTIC-6-7-8
  []
  [residence2]
    #TES
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 86400 # Abdou
    #value = 86400-432000 Riva
  []
  [residence3]
    #FW
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1000 #Riva
  []
  [residence4]
    #DIV
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1000 #Riva
  []
  [residence5]
    #HX
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1000 # Abdou 2021 paper chosen for analysis
  []
  [residence6]
    #CPS
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 864000 #Abdou analysis case
    #value 8640000 Abdou 1,4
  []
  [residence7]
    #Vac
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1
    #value = 1800 # 30 minutes (20-30 minutes)
  []
  [residence8]
    #FCU
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 1
    #value = 4680 # 1.3 h as per Day
    #value = 5 h Coleman
    #value = 8640 Abdou
    #value = 86400 Abdou
  []
  [residence9]
    #ISS
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 14400
    #value = 7920 #(for four hour overall residence time in inner loop)
  []
  [residence10]
    #EXO
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 3600 # Day et al
    #value = 72000 #Coleman et al
  []
  [tdecay]
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = '${fparse log(2)/388800000.0}'
  []
  [tritium_burn_fraction]
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.0036
  []
  [tritium_burn_rate]
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 5.3125e-6 # 0.459 kg/day
  []
  [tritium_fueling_efficiency]
    type = ConstantPostprocessor<<<{"description": "Postprocessor that holds a constant value", "href": "../../source/postprocessors/ConstantPostprocessor.html"}>>>
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = 'TIMESTEP_BEGIN INITIAL LINEAR NONLINEAR'
    value<<<{"description": "The value"}>>> = 0.25
  []
  # These postprocessors exist to sum up the tritium inventory
  #  across the entirety of the system
  [T_BZ]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_01_BZ
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_TES]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_02_TES
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_FW]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_03_FW
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_DIV]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_04_DIV
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_HX]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_05_HX
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_CPS]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_06_CPS
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_VAC]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_07_vacuum
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_FCU]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_08_FCU
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_ISS]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_09_ISS
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_EXO]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_10_exhaust
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [T_STO]
    type = ScalarVariable<<<{"description": "Returns the value of a scalar variable as a postprocessor value.", "href": "../../source/postprocessors/ScalarVariable.html"}>>>
    variable<<<{"description": "Name of the variable"}>>> = T_11_storage
    execute_on<<<{"description": "The list of flag(s) indicating when this object should be executed. For a description of each flag, see https://mooseframework.inl.gov/source/interfaces/SetupInterface.html."}>>> = TIMESTEP_END
  []
  [total_tritium]
    type = SumPostprocessor<<<{"description": "Sums the values of several postprocessors", "href": "../../source/postprocessors/SumPostprocessor.html"}>>>
    values<<<{"description": "List of postprocessors to add"}>>> = 'T_BZ T_TES T_FW T_DIV T_HX T_CPS T_VAC T_FCU T_ISS T_EXO T_STO'
  []
[]

Finally, we can set the Executioner block. In this case, we ask for a simple Transient executioner with an exponentially growing TimeStepper, IterationAdaptiveDT.

[Executioner<<<{"href": "../../syntax/Executioner/index.html"}>>>]
  type = Transient
  start_time = 0
  dtmin = 1
  end_time = 946080000.0
  [TimeStepper<<<{"href": "../../syntax/Executioner/TimeStepper/index.html"}>>>]
    type = IterationAdaptiveDT
    growth_factor = 1.4
    dt = 5
    #timestep_limiting_function = 'catch_five_year'
    #max_function_change = 0.5
    #force_step_every_function_point = true
  []
  solve_type = 'PJFNK'
  nl_rel_tol = 1e-08
  nl_abs_tol = 1e-14
[]

With these blocks set, we can now run the simulation and track tritium inventory.

Implementing a high-fidelity model to replace the default values of specific postprocessors or to more accurately model specific components is an exercise left for a later date.

Comparing Results Against Literature

In order to compare against Abdou et al. (2021), we need to make a few assumptions. First, we set the residence times and other parameters to the values listed in Tables 1-3 of Abdou et al. (2021) (the underlined value if there are multiple options). Here we also assume that the "Fuel clean-up and isotope separation system" total residence time of 4 hours as specified in the paper refers to a residence time of 4 hours for the isotope separation system, and negligible (1 second) residence times for the vacuum pump and fuel clean-up system.

Targeting the black lines of Figure 3 of Abdou et al. (2021), we also need to determine the appropriate reserve inventory , which, given and comes out to 127.5 kg. With this constraint, we can determine the relevant TBR to obtain a doubling time of 5 years, and iterating by hand, a value of 1.9247 yields a doubling time of 5 years to three decimal places if T_11_storage is given an initial condition of 225.4215 as shown in Table 2.

Table 2: Assumptions and iteratively obtained conditions used for this example.

ParameterValue
residence7 ()1 s
residence8 ()1 s
residence9 ()14400 s
TBR ()1.9247
Initial value for T_11_storage225.4215 kg

We compare our results with those from the black lines in Figure 3 from Abdou et al. (2021) in Figure 1. The lighter lines are estimates of the values shown in the paper, and the darker lines are the results from the model. The agreement is quite good, with only a slight deviation for the tritium extraction system inventory as it transitions to a steady-state value.

Tritium inventories of specific systems as a function of time. Shaded regions are best estimate of Figure 3 in [!cite](Abdou2021).

Figure 1: Tritium inventories of specific systems as a function of time. Shaded regions are best estimate of Figure 3 in Abdou et al. (2021).

!include fuel_cycle_abdou_base.i

[ScalarKernels]
  [I1t]
    type = ODETimeDerivative
    variable = T_01_BZ
  []
  [I2t]
    type = ODETimeDerivative
    variable = T_02_TES
  []
  [I3t]
    type = ODETimeDerivative
    variable = T_03_FW
  []
  [I4t]
    type = ODETimeDerivative
    variable = T_04_DIV
  []
  [I5t]
    type = ODETimeDerivative
    variable = T_05_HX
  []
  [I6t]
    type = ODETimeDerivative
    variable = T_06_CPS
  []
  [I7t]
    type = ODETimeDerivative
    variable = T_07_vacuum
  []
  [I8t]
    type = ODETimeDerivative
    variable = T_08_FCU
  []
  [I9t]
    type = ODETimeDerivative
    variable = T_09_ISS
  []
  [I10t]
    type = ODETimeDerivative
    variable = T_10_exhaust
  []
  [I11t]
    type = ODETimeDerivative
    variable = T_11_storage
  []
  [I1] # Breeding Zone
    type = ParsedODEKernel
    expression = '-(tritium_burn_rate * TBR + (1 - TES_efficiency)*T_02_TES/residence2 - T_01_BZ/residence1
                    - T_01_BZ*epsilon1/residence1 - T_01_BZ*tdecay)'
    variable = 'T_01_BZ'
    coupled_variables = 'T_02_TES'
    postprocessors = 'TBR tritium_burn_rate TES_efficiency residence1 residence2 tdecay epsilon1'
  []
  [I2] #Tritium Extraction System
    type = ParsedODEKernel
    expression = '-((1 - BZ_HX_leak_fraction)*T_01_BZ/residence1 - T_02_TES/residence2
                     - T_02_TES*epsilon2/residence2 - T_02_TES*tdecay)'
    variable = 'T_02_TES'
    coupled_variables = 'T_01_BZ'
    postprocessors = 'BZ_HX_leak_fraction residence1 residence2 tdecay epsilon2'
  []
  [I3] #First Wall
    type = ParsedODEKernel
    expression = '-(P_FW_leak_fraction*tritium_burn_rate /tritium_burn_fraction / tritium_fueling_efficiency
                    + HX_FW_leak_fraction * (1 - HX_CPS_leak_fraction) * (1 - HX_EXO_leak_fraction)
                    * T_05_HX/residence5 + CPS_FW_leak_fraction * (1 - CPS_efficiency) * T_06_CPS/residence6
                    - T_03_FW/residence3 - T_03_FW*epsilon3/residence3 - T_03_FW*tdecay)'
    variable = 'T_03_FW'
    coupled_variables = 'T_05_HX T_06_CPS'
    postprocessors = 'P_FW_leak_fraction tritium_burn_rate tritium_burn_fraction tritium_fueling_efficiency
                      HX_FW_leak_fraction HX_CPS_leak_fraction HX_EXO_leak_fraction residence5
                      CPS_FW_leak_fraction CPS_efficiency residence6 residence3 tdecay epsilon3'
  []
  [I4] #Divertor
    type = ParsedODEKernel
    expression = '-(P_DIV_leak_fraction * tritium_burn_rate/tritium_burn_fraction / tritium_fueling_efficiency
                    + (1-HX_FW_leak_fraction)* (1-HX_CPS_leak_fraction)*(1-HX_EXO_leak_fraction)
                    * T_05_HX/residence5 + (1-CPS_FW_leak_fraction)*(1 - CPS_efficiency) * T_06_CPS/residence6
                      - T_04_DIV*epsilon4/residence4 - T_04_DIV/residence4 - T_04_DIV*tdecay)'
    variable = 'T_04_DIV'
    coupled_variables = 'T_06_CPS T_05_HX'
    postprocessors = 'P_DIV_leak_fraction tritium_burn_rate tritium_burn_fraction
                     tritium_fueling_efficiency HX_FW_leak_fraction HX_CPS_leak_fraction
                     HX_EXO_leak_fraction residence5 CPS_FW_leak_fraction CPS_efficiency
                     residence6 residence4 tdecay epsilon4'
  []
  [I5] #Heat eXchanger
    type = ParsedODEKernel
    expression = '-(BZ_HX_leak_fraction * T_01_BZ/residence1 + T_03_FW/residence3 + T_04_DIV/residence4
                  - T_05_HX/residence5 - T_05_HX*epsilon5/residence5 -T_05_HX*tdecay)'
    variable = 'T_05_HX'
    coupled_variables = 'T_01_BZ T_03_FW T_04_DIV'
    postprocessors = 'BZ_HX_leak_fraction residence1 residence3 residence4 residence5 tdecay
                      epsilon5'
  []
  [I6] #Coolant Purification System
    type = ParsedODEKernel
    expression = '-(HX_CPS_leak_fraction * (1 - HX_EXO_leak_fraction)*T_05_HX/residence5
                    - T_06_CPS/residence6 - T_06_CPS*epsilon6/residence6 - T_06_CPS*tdecay)'
    variable = 'T_06_CPS'
    coupled_variables = 'T_05_HX'
    postprocessors = 'HX_CPS_leak_fraction HX_EXO_leak_fraction residence5 residence6 tdecay
                      epsilon6'
  []
  [I7] #Vacuum Pump
    type = ParsedODEKernel
    expression = '-((1-tritium_burn_fraction*tritium_fueling_efficiency - P_FW_leak_fraction
                    - P_DIV_leak_fraction)* tritium_burn_rate/(tritium_burn_fraction
                    * tritium_fueling_efficiency) - T_07_vacuum/residence7
                    - T_07_vacuum*epsilon7/residence7 - T_07_vacuum*tdecay)'
    variable = 'T_07_vacuum'
    postprocessors = 'tritium_burn_rate tritium_fueling_efficiency P_FW_leak_fraction
                      P_DIV_leak_fraction tritium_burn_fraction residence7 tdecay epsilon7'
  []
  [I8] #Fuel clean-up
    type = ParsedODEKernel
    expression = '-(T_07_vacuum/residence7 - T_08_FCU/residence8 - T_08_FCU*epsilon8/residence8
                    - T_08_FCU*tdecay)'
    variable = 'T_08_FCU'
    postprocessors = 'residence7 residence8 tdecay epsilon8'
    coupled_variables = 'T_07_vacuum'
  []
  [I9] #Isotope Separation System
    type = ParsedODEKernel
    expression = '-((1-FCU_STO_fraction)*T_08_FCU/residence8 + T_10_exhaust/residence10
                    + TES_efficiency*T_02_TES/residence2 + CPS_efficiency*T_06_CPS/residence6
                    - T_09_ISS/residence9 - T_09_ISS*epsilon9/residence9 - T_09_ISS*tdecay)'
    variable = 'T_09_ISS'
    coupled_variables = 'T_08_FCU T_10_exhaust T_02_TES T_06_CPS'
    postprocessors = 'FCU_STO_fraction residence8 residence10 TES_efficiency residence2
                      CPS_efficiency residence6 residence9 tdecay epsilon9'
  []
  [I10] #Exhaust and Water Detritiation System (EXO)
    type = ParsedODEKernel
    expression = '-(HX_EXO_leak_fraction * T_05_HX/residence5 + ISS_EXO_leak_fraction*T_09_ISS/residence9
                    - T_10_exhaust/residence10 - T_10_exhaust*epsilon10/residence10 - T_10_exhaust*tdecay)'
    variable = 'T_10_exhaust'
    coupled_variables = 'T_05_HX T_09_ISS'
    postprocessors = 'HX_EXO_leak_fraction residence5 ISS_EXO_leak_fraction residence9 residence10
                      tdecay epsilon10'
  []
  [I11] #Storage and Management (STO)
    type = ParsedODEKernel
    expression = '-(FCU_STO_fraction * T_08_FCU/residence8 + (1-ISS_EXO_leak_fraction)*T_09_ISS/residence9
                    - tritium_burn_rate/tritium_burn_fraction/tritium_fueling_efficiency
                    - T_11_storage*tdecay)'
    variable = 'T_11_storage'
    coupled_variables = 'T_08_FCU T_09_ISS'
    postprocessors = 'FCU_STO_fraction residence8 ISS_EXO_leak_fraction residence9 tritium_burn_rate
                      tritium_burn_fraction tritium_fueling_efficiency tdecay'
  []
[]
Outputs/csv/file_base=fuel_cycle_out
(test/tests/fuel_cycle_Abdou/fuel_cycle.i)

How to run

This example can be run from three different driver input files, an explicit model using ParsedODEKernel and two class-based models which leverage FuelCycleSystemScalarKernel, one with and one without automatic differentiation. As there is significant overlap between the two models, they both use the !include syntax to import common terms from a base file.

Python-based Interactive Script

A python-based graphical interactive script is available at (test/tests/fuel_cycle_Abdou/fuel_cycle_gui.py) as a demonstration of the various effects of individual parameters. To use it, navigate to the scripts directory and run the script. All of the input parameters for the model can be changed by editing the associated entry, then clicking the "Run" button. Once the simulation has run, checkboxes will appear for each system-level tritium inventory. Time units can also be adjusted by selecting the appropriate timescale.

References

  1. Mohamed Abdou, Marco Riva, Alice Ying, Christian Day, Alberto Loarte, Larry R. Baylor, Paul Humrickhouse, Thomas F. Fuerst, and Seungyon Cho. Physics and technology considerations for the deuterium–tritium fuel cycle and conditions for tritium fuel self sufficiency. Nuclear Fusion, 61(1):013001, 2021. URL: https://dx.doi.org/10.1088/1741-4326/abbf35, doi:10.1088/1741-4326/abbf35.[BibTeX]
  2. Pierre-Clément A. Simon, Casey T. Icenhour, Gyanender Singh, Alexander D Lindsay, Chaitanya Vivek Bhave, Lin Yang, Adriaan Anthony Riet, Yifeng Che, Paul Humrickhouse, Masashi Shimada, and Pattrick Calderoni. MOOSE-based tritium migration analysis program, version 8 (TMAP8) for advanced open-source tritium transport and fuel cycle modeling. Fusion Engineering and Design, 214:114874, May 2025. doi:10.1016/j.fusengdes.2025.114874.[BibTeX]