Skip to content
145 changes: 142 additions & 3 deletions CADETProcess/processModel/discretization.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ def axial_dof(self) -> int:

class GRMDiscretizationFV(DiscretizationParametersBase):
"""
Discretization parameters of the FV version of the LRMP.
Discretization parameters of the FV version of the GRM.

Attributes
----------
Expand Down Expand Up @@ -362,8 +362,9 @@ class GRMDiscretizationFV(DiscretizationParametersBase):

See Also
--------
CADETProcess.processModel.LRMPDiscretizationDG
CADETProcess.processModel.LumpedRateModelWithPores
CADETProcess.processModel.GRMDiscretizationFV
CADETProcess.processModel.GeneralRateModel

"""

spatial_method = Constant(value="FV")
Expand Down Expand Up @@ -523,6 +524,144 @@ def par_disc_vector_length(self) -> int:
return self.par_nelem * (self.par_polydeg + 1)


class GRM2DDiscretizationFV(DiscretizationParametersBase):
"""
Discretization parameters of the FV version of the GRM2D.

Attributes
----------
ncol : UnsignedInteger, optional
Number of axial column discretization cells. Default is 100.
npar : UnsignedInteger, optional
Number of discretization cells in the radial direction. Default is 5.
par_geom : Switch, optional
The geometry of the particles in the model.
Valid values are 'SPHERE', 'CYLINDER', and 'SLAB'.
Default is 'SPHERE'.
par_disc_type : Switch, optional
Discretization scheme inside the particles for all or each particle type.
Valid values are 'EQUIDISTANT_PAR', 'EQUIVOLUME_PAR', and 'USER_DEFINED_PAR'.
Default is 'EQUIDISTANT_PAR'.
par_disc_vector : SizedRangedList, optional
Node coordinates for the cell boundaries
(ignored if `par_disc_type` != `USER_DEFINED_PAR).
The coordinates are relative and have to include the endpoints `0` and `1`.
They are later linearly mapped to the true radial range.
The coordinates for each particle type are appended to one long vector in
type-major ordering.
Default is a uniformly spaced vector with `npar+1` points between 0 and 1.
par_boundary_order : RangedInteger, optional
The order of the boundary scheme used to discretize the particles.
Valid values are 1 (first order) and 2 (second order).
Default is 2.
use_analytic_jacobian : Bool, optional
If True, use analytically computed Jacobian matrix (faster).
If False, use Jacobians generated by algorithmic differentiation (slower).
Default is True.
reconstruction : Switch, optional
Method for spatial reconstruction. Valid values are 'WENO' (Weighted
Essentially Non-Oscillatory). Default is 'WENO'.
gs_type : Bool, optional
Type of Gram-Schmidt orthogonalization.
If 0, use classical Gram-Schmidt.
If 1, use modified Gram-Schmidt.
The default is 1.
max_krylov : UnsignedInteger, optional
Size of the Krylov subspace in the iterative linear GMRES solver.
If 0, max_krylov = ncol * ncomp * npar is used, where ncomp is the
number of components in the model.
Default is 0.
max_restarts : UnsignedInteger, optional
Maximum number of restarts to use for the GMRES method. Default is 10.
schur_safety : UnsignedFloat, optional
Safety factor for the Schur complement solver. Default is 1.0e-8.
fix_zero_surface_diffusion : Bool, optional
If True, fix the surface diffusion coefficient of particles with zero
surface diffusion to a small positive value. Default is False.

"""

spatial_method = Constant(value="FV")
ncol = UnsignedInteger(default=100)
nrad = UnsignedInteger(default=1)
npar = UnsignedInteger(default=5)

radial_disc_type = Switch(
default="EQUIDISTANT", valid=["EQUIDISTANT", "EQUIVOLUME", "USER_DEFINED"]
)

radial_compartments = SizedRangedList(
lb=0, size="radial_compartments_length", is_optional=True
)

par_geom = Switch(default="SPHERE", valid=["SPHERE", "CYLINDER", "SLAB"])
par_disc_type = Switch(
default="EQUIDISTANT_PAR",
valid=["EQUIDISTANT_PAR", "EQUIVOLUME_PAR", "USER_DEFINED_PAR"],
)
par_disc_vector = SizedRangedList(
lb=0, ub=1, size="par_disc_vector_length", is_optional=True
)

par_boundary_order = RangedInteger(lb=1, ub=2, default=2)

use_analytic_jacobian = Bool(default=True)
reconstruction = Switch(default="WENO", valid=["WENO"])

gs_type = Bool(default=True)
max_krylov = UnsignedInteger(default=0)
max_restarts = UnsignedInteger(default=10)
schur_safety = UnsignedFloat(default=1.0e-8)

fix_zero_surface_diffusion = Bool(default=False)

_parameters = DiscretizationParametersBase._parameters + [
"ncol",
"npar",
"nrad",
"par_geom",
"par_disc_type",
"par_disc_vector",
"par_boundary_order",
"radial_disc_type",
"radial_compartments",
"use_analytic_jacobian",
"reconstruction",
"gs_type",
"max_krylov",
"max_restarts",
"schur_safety",
"fix_zero_surface_diffusion",
]
_required_parameters = [
"ncol",
"npar",
"nrad",
"par_geom",
"par_disc_type",
"par_boundary_order",
"radial_disc_type",
"use_analytic_jacobian",
"reconstruction",
"gs_type",
"max_krylov",
"max_restarts",
"schur_safety",
"fix_zero_surface_diffusion",
]
_dimensionality = ["ncol", "nrad", "npar"]

@property
def radial_compartments_length(self) -> int:
"""int: Number of entries in the radial compartments vector."""
return self.nrad + 1

@property
def par_disc_vector_length(self) -> int:
"""int: Number of entries in the particle discretization vector."""
return self.npar + 1


@frozen_attributes
class WenoParameters(Structure):
"""
Expand Down
26 changes: 26 additions & 0 deletions CADETProcess/processModel/solutionRecorder.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,32 @@ class GRMRecorder(
pass


class GRM2DRecorder(
SolutionRecorderBase,
BaseMixin,
IOMixin,
BulkMixin,
FluxMixin,
ParticleMixin,
SolidMixin,
):
"""Recorder for TubularReactor.

See Also
--------
BaseMixin
IOMixin
BulkMixin
FluxMixin
ParticleMixin
SolidMixin
CADETProcess.processModel.GeneralRateModel2D

"""

pass


class CSTRRecorder(
SolutionRecorderBase, BaseMixin, IOMixin, BulkMixin, SolidMixin, VolumeMixin
):
Expand Down
Loading
Loading