Unit Operation Models#

A UnitOperation is a class that represents the physico-chemical behavior of an apparatus and holds its model parameters. For an overview of all unit operation models currently available in CADET-Process, refer to processModel. Each unit operation model can be associated with binding models that describe the interaction of components with the surface of a chromatographic stationary phase. For more information about binding models, refer to Binding Models. Moreover, ReactionModels can be used to model chemical reactions. For more information, refer to Chemical Reactions. To describe more complex operating modes, multiple unit operations can be connected in a FlowSheet. For more information about the FlowSheet class, refer to Flow Sheet

To instantiate a unit operation model, the corresponding class needs to be imported from the CADETProcess.processModel module. For example, to use a Cstr use the following:

Hide code cell content
from CADETProcess.processModel import ComponentSystem
component_system = ComponentSystem(2)
from CADETProcess.processModel import Cstr
unit = Cstr(component_system, 'tank')

All parameters are stored in the parameters attribute.

print(unit.parameters)
{'porosity': 1.0, 'flow_rate_filter': 0.0, 'c': [0, 0], 'q': [], 'V': None, 'flow_rate': None}

Note that some parameters might have default values. To only show required parameters, inspect required_parameters.

print(unit.required_parameters)
['V']

Polynomial Coefficients#

Some parameters in CADET-Process are represented by polynomial coefficients. For example, the flow_rate of an Inlet can be described by a cubic polynomial (in time).

By default, all coefficients are \(0\).

Hide code cell content
from CADETProcess.processModel import Inlet
inlet = Inlet(component_system, 'inlet')
print(inlet.flow_rate)
[0. 0. 0. 0.]

When assigning a scalar value to the parameter, the new state is assumed to be constant. All other coefficients are set to \(0\). Note that polynomial coefficients are specified in order of increasing degree. I.e. the first coefficient corresponds to the constant term, the second to the linear term, etc.

inlet.flow_rate = 1
print(inlet.flow_rate)
[1. 0. 0. 0.]

It is also possible to specify only any subset of polynomial coefficients. E.g. consider a linear gradient where the flow rate starts at \(1 m^3 \cdot s^{-1}\) and increases with a slope of \(2 m^3 \cdot s^{-2}\):

inlet.flow_rate = [1, 2]
print(inlet.flow_rate)
[1. 2. 0. 0.]

Or, specify all polynomial coefficients:

inlet.flow_rate = [0, 1, 2, 3]
print(inlet.flow_rate)
[0. 1. 2. 3.]

This also works for parameters with multiple entries, e.g. the concentration of an Inlet.

Set all components to same (constant) concentration:

inlet.c = 1
print(inlet.c)
[[1. 0. 0. 0.]
 [1. 0. 0. 0.]]

Specify constant term for each component:

inlet.c = [1, 2]
print(inlet.c)
[[1. 0. 0. 0.]
 [2. 0. 0. 0.]]

Specify polynomial coefficients for each component:

inlet.c = [[1, 2], 1]
print(inlet.c)
[[1. 2. 0. 0.]
 [1. 0. 0. 0.]]

Specify all polynomial coefficients:

inlet.c = [[0, 1, 2, 3], [4, 5, 6, 7]]
print(inlet.c)
[[0. 1. 2. 3.]
 [4. 5. 6. 7.]]

Since these parameters are mostly used in dynamic process models, they are usually modified using Events.

For an example, refer to SSR process.

Discretization#

Some of the unit operations need to be spatially discretized. The discretization parameters are stored in a DiscretizationParametersBase class. For example, consider a LumpedRateModelWithoutPores.

Hide code cell content
from CADETProcess.processModel import LumpedRateModelWithoutPores
lrm = LumpedRateModelWithoutPores(component_system, 'lrm')

The discretization parameters can be imported and configured manually. For example, to use the finite volume implementation (see LRMDiscretizationFV) import the corresponding class and configure the parameters.

from CADETProcess.processModel import LRMDiscretizationFV

lrm_discretization_fv = LRMDiscretizationFV()
print(lrm_discretization_fv.parameters)
{'ncol': 100, 'use_analytic_jacobian': True, 'reconstruction': 'WENO', 'weno': {'boundary_model': 0, 'weno_eps': 1e-10, 'weno_order': 3}, 'consistency_solver': {'solver_name': 'LEVMAR', 'init_damping': 0.01, 'min_damping': 0.0001, 'max_iterations': 50, 'subsolvers': 'LEVMAR'}}

Notable parameters are:

  • ncol: Number of axial column discretization cells. Default is 100.

  • weno_parameters: Discretization parameters for the WENO scheme

  • consistency_solver: Consistency solver parameters for Cadet.

Then, set the discretization attribute.

lrm.discretization = lrm_discretization_fv

Note that by default, all models are already pre-configured with the finite volume discretization. Hence, it is usually not necessary to manually import and set this attribute.

CADET also offers a discontinuous Galerkin (DG) discretization scheme.

Note

DG functionality is still work in progress. For it to work, the DG-version of CADET needs to be compiled.

To use DG, import the corresponding LRMDiscretizationDG class and set the attribute. Alternatively, it is also possible to simply set discretization_scheme='DG' in the constructor.

lrm_dg = LumpedRateModelWithoutPores(component_system, 'lrm_dg', discretization_scheme='DG')
print(lrm_dg.discretization)
<CADETProcess.processModel.discretization.LRMDiscretizationDG object at 0x7fb715c13fd0>

Solution Recorder#

To store the solution of a unit operation, a solution recorder needs to be configured. In this recorder, a flag can be set to store different partitions (e.g. inlet, outlet, bulk, etc.) of the solution of that unit operation. Consider the solution_recorder of a LumpedRateModelWithoutPores.

print(lrm.solution_recorder)
<CADETProcess.processModel.solutionRecorder.LRMRecorder object at 0x7fb715a32850>

By default, only the inlet and outlet of each unit are stored after simulation. To also store the solution of bulk, particle liquid, or particle solid, configure the corresponding attributes. For example, to store the particle solid phase solution, set the following:

lrm.solution_recorder.write_solution_solid = True

In the solution recorder, it can also be configured whether derivatives or sensitivities of that unit are to be stored. For more information on the solution, refer to Simulation Results.