Moving Bed Reactor#

The IDAES Moving Bed Reactor (MBR) model represents a unit operation where two material streams – a solid phase and a gas phase – pass through a linear reactor vessel while undergoing chemical reaction(s). The two streams have opposite flow directions (counter-flow). The MBR mathematical model is a 1-D rigorous first-principles model consisting of a set of differential equations obtained by applying the mass, energy (for each phase) and momentum balance equations.

The model code is located in the main unit model module and may be imported as:

>>> from idaes.models_extra.gas_solid_contactors.unit_models.moving_bed import MBR

Assumptions:

  • The radial concentration and temperature gradients are assumed to be negligible.

  • The reactor is assumed to be adiabatic.

  • The solid phase is assumed to be moving at a constant velocity determined by the solids feed rate to the reactor.

Requirements:

  • Property package contains temperature and pressure variables.

  • Property package contains minimum fluidization velocity.

The MBR model is based on:

  1. Ostace, A. Lee, C.O. Okoli, A.P. Burgard, D.C. Miller, D. Bhattacharyya, Mathematical modeling of a moving-bed reactor for chemical looping combustion of methane, in: M.R. Eden, M. Ierapetritou, G.P. Towler (Eds.),13th Int. Symp. Process Syst. Eng. (PSE 2018), Computer-Aided Chemical Engineering 2018, pp. 325–330 , San Diego, CA.

Degrees of Freedom#

MBRs generally have at least 2 (or more) degrees of freedom, consisting of design and operating variables. The design variables of reactor length and diameter are typically the minimum variables to be fixed.

Model Structure#

The core MBR unit model consists of two ControlVolume1DBlock Blocks (named gas_phase and solid_phase), each with one Inlet Port (named gas_inlet and solid_inlet) and one Outlet Port (named gas_outlet and solid_outlet).

Discretization#

The default spatial discretization is a backward finite difference with respect to increasing \(x\) coordinate. For dynamic operation, we recommend a discretization that is backward with respect to direction of flow, i.e. backward for the gas phase and forward for the solid phase. Discretizations may be set for gas and solid phases individually using the gas_transformation_scheme and solid_transformation_scheme config options.

Constraints#

In the following, the subscripts \(g\) and \(s\) refer to the gas and solid phases, respectively. In addition to the constraints written by the control_volume Block, MBR units write the following Constraints:

Geometry Constraints#

Area of the reactor bed:

\[A_{bed} = \pi \left( \frac{ D_{bed} }{ 2 } \right)^2\]

Area of the gas domain:

\[A_{g,t,x} = \varepsilon A_{bed}\]

Area of the solid domain:

\[A_{s,t,x} = (1 - \varepsilon) A_{bed}\]

Length of the gas domain:

\[L_{g} = L_{bed}\]

Length of the solid domain:

\[L_{s} = L_{bed}\]

Hydrodynamic Constraints#

Superficial velocity of the gas:

\[u_{g,t,x} = \frac{ F_{mol,g,t,x} }{ A_{bed} \rho_{mol,g,t,x} }\]

Superficial velocity of the solids:

\[u_{s,t} = \frac{ F_{mass,s,t,inlet} }{ A_{bed} \rho_{mass,s,t,inlet} }\]

Pressure drop:

The constraints written by the MBR model to compute the pressure drop (if has_pressure_change is ‘True’) in the reactor depend upon the construction arguments chosen:

If pressure_drop_type is simple_correlation:

\[- \frac{ dP_{g,t,x} }{ dx } = 0.2 \left( \rho_{mass,s,t,x} - \rho_{mass,g,t,x} \right) u_{g,t,x}\]

If pressure_drop_type is ergun_correlation:

\[- \frac{ dP_{g,t,x} }{ dx } = \frac{ 150 \mu_{g,t,x} {\left( 1 - \varepsilon \right)}^{2} \left( u_{g,t,x} + u_{s,t} \right) }{ \varepsilon^{3} d_{p}^2 } + \frac{ 1.75 \left( 1 - \varepsilon \right) \rho_{mass,g,t,x} \left( u_{g,t,x} + u_{s,t} \right)^{2} }{ \varepsilon^{3} d_{p} }\]

Reaction Constraints#

Gas phase reaction extent:

If gas_phase_config.reaction_package is not ‘None’:

\[\xi_{g,t,x,r} = r_{g,t,x,r} A_{g,t,x}\]

Solid phase reaction extent:

If solid_phase_config.reaction_package is not ‘None’:

\[\xi_{s,t,x,r} = r_{s,t,x,r} A_{s,t,x}\]

Gas phase heterogeneous rate generation/consumption:

\[M_{g,t,x,p,j} = A_{s,t,x} \sum_{r}^{reactions} {\nu_{s,j,r} r_{s,t,x,r}}\]

Dimensionless numbers, mass and heat transfer coefficients#

Particle Reynolds number:

\[Re_{p,t,x} = \frac{ u_{g,t,x} \rho_{mass,g,t,x} }{ \mu_{g,t,x} d_{p}}\]

Prandtl number:

\[Pr_{t,x} = \frac{ c_{p,t,x} \mu_{g,t,x} }{ k_{g,t,x} }\]

Particle Nusselt number:

\[Nu_{p,t,x} = 2 + 1.1 Pr_{t,x}^{1/3} \left| Re_{p,t,x} \right|^{0.6}\]

Particle to fluid heat transfer coefficient

\[h_{gs,t,x} d_{p} = Nu_{p,t,x} k_{g,t,x}\]

If energy_balance_type not EnergyBalanceType.none:

Gas phase - gas to solid heat transfer:

\[H_{g,t,x} = - \frac{ 6 } { d_{p} } h_{gs,t,x} \left( T_{g,t,x} - T_{s,t,x} \right) A_{s,t,x}\]

Solid phase - gas to solid heat transfer:

\[H_{s,t,x} = \frac{ 6 } { d_{p} } h_{gs,t,x} \left( T_{g,t,x} - T_{s,t,x} \right) A_{s,t,x}\]

List of Variables#

Variable

Description

Reference to

\(A_{bed}\)

Reactor bed cross-sectional area

bed_area

\(A_{g,t,x}\)

Gas phase area (interstitial cross-sectional area)

gas_phase.area

\(A_{s,t,x}\)

Solid phase area

solid_phase.area

\(c_{p,t,x}\)

Gas phase heat capacity (constant \(P\))

gas_phase.properties.cp_mass

\(D_{bed}\)

Reactor bed diameter

bed_diameter

\(F_{mass,s,t,inlet}\)

Total mass flow rate of solids, at inlet (\(x=1\))

solid_phase.properties.flow_mass

\(F_{mol,g,t,x}\)

Total molar flow rate of gas

gas_phase.properties.flow_mol

\(H_{g,t,x}\)

Gas to solid heat transfer term, gas phase

gas_phase.heat

\(H_{s,t,x}\)

Gas to solid heat transfer term, solid phase

solid_phase.heat

\(h_{gs,t,x}\)

Gas-solid heat transfer coefficient

gas_solid_htc

\(k_{g,t,x}\)

Gas thermal conductivity

gas_phase.properties.therm_cond

\(L_{bed}\)

Reactor bed height

bed_height

\(L_{g}\)

Gas domain length

gas_phase.length

\(L_{s}\)

Solid domain length

solid_phase.length

\(M_{g,t,x,p,j}\)

Rate generation/consumption term, gas phase

gas_phase.mass_transfer_term

\(Nu_{p,t,x}\)

Particle Nusselt number

Nu_particle

\(dP_{g,t,x}\)

Total pressure derivative w.r.t. \(x\) (axial position)

gas_phase.deltaP

\(Pr_{t,x}\)

Prandtl number

Pr

\(r_{g,t,x,r}\)

Gas phase reaction rate

gas_phase.reactions.reaction_rate

\(r_{s,t,x,r}\)

Solid phase reaction rate

solid_phase.reactions.reaction_rate

\(Re_{p,t,x}\)

Particle Reynolds number

Re_particle

\(T_{g,t,x}\)

Gas phase temperature

gas_phase.properties.temperature

\(T_{s,t,x}\)

Solid phase temperature

solid_phase.properties.temperature

\(u_{g,t,x}\)

Superficial velocity of the gas

velocity_superficial_gas

\(u_{s,t}\)

Superficial velocity of the solids

velocity_superficial_solid

Greek letters

\(\varepsilon\)

Reactor bed voidage

bed_voidage

\(\mu_{g,t,x}\)

Dynamic viscosity of gas mixture

gas_phase.properties.visc_d

\(\xi_{g,t,x,r}\)

Gas phase reaction extent

gas_phase.rate_reaction_extent

\(\xi_{s,t,x,r}\)

Solid phase reaction extent

solid_phase.rate_reaction_extent

\(\rho_{mass,g,t,inlet}\)

Density of gas mixture

gas_phase.properties.dens_mass

\(\rho_{mass,s,t,inlet}\)

Density of solid particles

solid_phase.properties.dens_mass_particle

\(\rho_{mol,g,t,x}\)

Molar density of the gas

gas_phase.properties.dens_mole

List of Parameters#

Parameter

Description

Reference to

\(d_{p}\)

Solid particle diameter

solid_phase.properties._params.particle_dia

\(\nu_{s,j,r}\)

Stoichiometric coefficients

solid_phase.reactions.rate_reaction_stoichiometry

Initialization#

The initialization method for this model will save the current state of the model before commencing initialization and reloads it afterwards. The state of the model will be the same after initialization, only the initial guesses for unfixed variables will be changed.

The model allows for the passing of a dictionary of values of the state variables of the gas and solid phases that can be used as initial guesses for the state variables throughout the time and spatial domains of the model. This is optional but recommended. A typical guess could be values of the gas and solid inlet port variables at time \(t=0\).

The model initialization proceeds through a sequential hierarchical method where the model equations are deactivated at the start of the initialization routine, and the complexity of the model is built up through activation and solution of various sub-model blocks and equations at each initialization step. At each step the model variables are updated to better guesses obtained from the model solution at that step.

The initialization routine proceeds in as follows:

  • Step 1: Initialize the thermo-physical and transport properties model blocks.

  • Step 2: Initialize the hydrodynamic properties.

  • Step 3a: Initialize mass balances without reactions and pressure drop.

  • Step 3b: Initialize mass balances with reactions and without pressure drop.

  • Step 3c: Initialize mass balances with reactions and pressure drop.

  • Step 4: Initialize energy balances.

MBR Class#

class idaes.models_extra.gas_solid_contactors.unit_models.moving_bed.MBR(*args, **kwds)#
Parameters:
  • rule (function) – A rule function or None. Default rule calls build().

  • concrete (bool) – If True, make this a toplevel model. Default - False.

  • ctype (class) –

    Pyomo ctype of the block. Default - pyomo.environ.Block

    Config args

    dynamic

    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}

    has_holdup

    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { useDefault - get flag from parent (default = False), True - construct holdup terms, False - do not construct holdup terms}

    finite_elements

    Number of finite elements to use when discretizing length domain (default=20)

    length_domain_set

    length_domain_set - (optional) list of point to use to initialize a new ContinuousSet if length_domain is not provided (default = [0.0, 1.0])

    transformation_method

    Method to use to transform domain. Must be a method recognized by the Pyomo TransformationFactory, default - “dae.finite_difference”. Valid values: { “dae.finite_difference” - Use a finite difference transformation method, “dae.collocation” - use a collocation transformation method}

    transformation_scheme

    Scheme to use when transforming domain. If specified, this scheme is applied to discretizations in both the gas and solid phases. In this case, gas_transformation_scheme and solid_transformation_scheme cannot be specified. See Pyomo documentation for supported schemes. default - None. Valid values: { None - defaults to “BACKWARD” for finite difference transformation method, and to “LAGRANGE-RADAU” for collocation transformation method, “BACKWARD” - Use a finite difference transformation method, “FORWARD”” - use a finite difference transformation method, “LAGRANGE-RADAU”” - use a collocation transformation method}

    gas_transformation_scheme

    Scheme to use when transforming length domain of the gas phase. If this option is supplied, solid_transformation_scheme must be supplied as well. This cannot be set (other than to None) if the transformation_scheme option is set. See Pyomo documentation for supported schemes. default - None. Valid values: { None - defaults to the value of the transformation_scheme option, “BACKWARD” - Use a finite difference transformation method, “FORWARD”” - use a finite difference transformation method}

    solid_transformation_scheme

    Scheme to use when transforming length domain of the solid phase. If this option is supplied, gas_transformation_scheme must be supplied as well. This cannot be set (other than to None) if the transformation_scheme option is set. See Pyomo documentation for supported schemes, default - None. Valid values: { None - defaults to the value of the transformation_scheme option, “BACKWARD” - Use a finite difference transformation method, “FORWARD”” - use a finite difference transformation method}

    collocation_points

    Number of collocation points to use per finite element when discretizing length domain (default=3)

    flow_type

    Flow configuration of Moving Bed - counter_current: gas side flows from 0 to 1 solid side flows from 1 to 0

    material_balance_type

    Indicates what type of mass balance should be constructed, default - MaterialBalanceType.componentTotal. Valid values: { MaterialBalanceType.none - exclude material balances, MaterialBalanceType.componentPhase - use phase component balances, MaterialBalanceType.componentTotal - use total component balances, MaterialBalanceType.elementTotal - use total element balances, MaterialBalanceType.total - use total material balance.}

    energy_balance_type

    Indicates what type of energy balance should be constructed, default - EnergyBalanceType.enthalpyTotal. Valid values: { EnergyBalanceType.none - exclude energy balances, EnergyBalanceType.enthalpyTotal - single enthalpy balance for material, EnergyBalanceType.enthalpyPhase - enthalpy balances for each phase, EnergyBalanceType.energyTotal - single energy balance for material, EnergyBalanceType.energyPhase - energy balances for each phase.}

    momentum_balance_type

    Indicates what type of momentum balance should be constructed, default - MomentumBalanceType.pressureTotal. Valid values: { MomentumBalanceType.none - exclude momentum balances, MomentumBalanceType.pressureTotal - single pressure balance for material, MomentumBalanceType.pressurePhase - pressure balances for each phase, MomentumBalanceType.momentumTotal - single momentum balance for material, MomentumBalanceType.momentumPhase - momentum balances for each phase.}

    has_pressure_change

    Indicates whether terms for pressure change should be constructed, default - False. Valid values: { True - include pressure change terms, False - exclude pressure change terms.}

    pressure_drop_type

    Indicates what type of pressure drop correlation should be used, default - “simple_correlation”. Valid values: { “simple_correlation” - Use a simplified pressure drop correlation, “ergun_correlation” - Use the Ergun equation.}

    gas_phase_config

    gas phase config arguments

    gas_phase_config
    dynamic

    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}

    has_holdup

    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { useDefault - get flag from parent (default = False), True - construct holdup terms, False - do not construct holdup terms}

    has_equilibrium_reactions

    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}

    property_package

    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object

    property_package_args

    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)

    reaction_package

    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}

    reaction_package_args

    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}

    solid_phase_config

    solid phase config arguments

    solid_phase_config
    dynamic

    Indicates whether this model will be dynamic or not, default = useDefault. Valid values: { useDefault - get flag from parent (default = False), True - set as a dynamic model, False - set as a steady-state model.}

    has_holdup

    Indicates whether holdup terms should be constructed or not. Must be True if dynamic = True, default - False. Valid values: { useDefault - get flag from parent (default = False), True - construct holdup terms, False - do not construct holdup terms}

    has_equilibrium_reactions

    Indicates whether terms for equilibrium controlled reactions should be constructed, default - True. Valid values: { True - include equilibrium reaction terms, False - exclude equilibrium reaction terms.}

    property_package

    Property parameter object used to define property calculations (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a ParameterBlock object

    property_package_args

    A dict of arguments to be passed to the PropertyBlockData and used when constructing these (default = ‘use_parent_value’) - ‘use_parent_value’ - get package from parent (default = None) - a dict (see property package for documentation)

    reaction_package

    Reaction parameter object used to define reaction calculations, default - None. Valid values: { None - no reaction package, ReactionParameterBlock - a ReactionParameterBlock object.}

    reaction_package_args

    A ConfigBlock with arguments to be passed to a reaction block(s) and used when constructing these, default - None. Valid values: { see reaction package for documentation.}

  • initialize (dict) – ProcessBlockData config for individual elements. Keys are BlockData indexes and values are dictionaries with config arguments as keys.

  • idx_map (function) – Function to take the index of a BlockData element and return the index in the initialize dict from which to read arguments. This can be provided to override the default behavior of matching the BlockData index exactly to the index in initialize.

Returns:

(MBR) New instance

MBRData Class#

class idaes.models_extra.gas_solid_contactors.unit_models.moving_bed.MBRData(component)[source]#

Standard Moving Bed Unit Model Class.

build()[source]#

Begin building model (pre-DAE transformation).

Parameters:

None

Returns:

None

initialize_build(gas_phase_state_args=None, solid_phase_state_args=None, outlvl=0, solver=None, optarg=None)[source]#

Initialization routine for MB unit.

Keyword Arguments:
  • gas_phase_state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = None).

  • solid_phase_state_args – a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = None).

  • outlvl – sets output level of initialization routine

  • optarg – solver options dictionary object (default=None, use default solver options)

  • solver – str indicating which solver to use during initialization (default = None, use default solver)

Returns:

None

results_plot()[source]#

Plot method for common moving bed variables

Variables plotted:

Tg : Temperature in gas phase Ts : Temperature in solid phase vg : Superficial gas velocity P : Pressure in gas phase Ftotal : Total molar flowrate of gas Mtotal : Total mass flowrate of solid Cg : Concentration of gas components in the gas phase y_frac : Mole fraction of gas components in the gas phase x_frac : Mass fraction of solid components in the solid phase