Source code for CADETProcess.processModel.discretization

"""
================================================================
Discretization (:mod:`CADETProcess.processModel.discretization`)
================================================================

The following module is a collection of classes that define different discretization
schemes for :mod:`UnitOperations <CADETProcess.processModel.unitOperation>` for the
CADETProcess software package.

The :class:`~CADETProcess.processModel.DiscretizationParametersBase` class is the base
class for all other classes in this module and defines some common parameters.
Specific parameters for each scheme are defined as attributes of each class.

"""
from CADETProcess.dataStructure import Structure
from CADETProcess.dataStructure import (
    Bool, Switch,
    RangedInteger, UnsignedInteger, UnsignedFloat,
    SizedRangedList
)


__all__ = [
    'NoDiscretization',
    'LRMDiscretizationFV', 'LRMDiscretizationDG',
    'LRMPDiscretizationFV', 'LRMPDiscretizationDG',
    'GRMDiscretizationFV', 'GRMDiscretizationDG',
    'WenoParameters', 'ConsistencySolverParameters',
    'DGMixin'
]


[docs] class DiscretizationParametersBase(Structure): """Base class for storing discretization parameters. Attributes ---------- dimensionality : dict Dimensionality of the parameters weno_parameters : WenoParameters Parameters for the WENO scheme. consistency_solver: ConsistencySolverParameters Consistency solver parameters for Cadet. """ _dimensionality = [] def __init__(self): """Initialize a new DiscretizationParametersBase instance.""" self.weno_parameters = WenoParameters() self.consistency_solver = ConsistencySolverParameters() super().__init__() @property def dimensionality(self): """dict: Dimensionality of the parameters.""" dim = {} for d in self._dimensionality: v = getattr(self, d) if v is None: continue dim[d] = v return dim @property def parameters(self): """dict: Dictionary with parameter values.""" parameters = super().parameters parameters['weno'] = self.weno_parameters.parameters parameters['consistency_solver'] = self.consistency_solver.parameters return parameters @parameters.setter def parameters(self, parameters): try: self.weno_parameters.parameters = parameters.pop('weno') except KeyError: pass try: self.consistency_solver.parameters \ = parameters.pop('consistency_solver') except KeyError: pass super(DiscretizationParametersBase, self.__class__).parameters.fset( self, parameters )
[docs] class NoDiscretization(DiscretizationParametersBase): """Class for unit operations without spatial discretization.""" pass
[docs] class DGMixin(DiscretizationParametersBase): pass
[docs] class LRMDiscretizationFV(DiscretizationParametersBase): """Discretization parameters of the FV version of the LRM. This class stores parameters for the Lax-Richtmyer-Morton (LRM) flux-based finite volume discretization. Attributes ---------- ncol : UnsignedInteger, optional Number of axial column discretization cells. Default is 100. 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'. """ ncol = UnsignedInteger(default=100) use_analytic_jacobian = Bool(default=True) reconstruction = Switch(default='WENO', valid=['WENO']) _parameters = DiscretizationParametersBase._parameters + [ 'ncol', 'use_analytic_jacobian', 'reconstruction', ] _dimensionality = ['ncol']
[docs] class LRMDiscretizationDG(DGMixin): """Discretization parameters of the DG version of the LRM. Attributes ---------- ncol : UnsignedInteger, optional Number of axial column discretization cells. Default is 16. 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'. polynomial_degree : UnsignedInteger, optional Degree of the polynomial used for axial discretization. Default is 3. polydeg : UnsignedInteger, optional Degree of the polynomial used for axial discretization. Default is 3. exact_integration : Bool, optional Whether to use exact integration for the axial discretization. Default is False. See Also -------- CADETProcess.processModel.LRMPDiscretizationFV CADETProcess.processModel.LumpedRateModelWithPores """ ncol = UnsignedInteger(default=16) use_analytic_jacobian = Bool(default=True) reconstruction = Switch(default='WENO', valid=['WENO']) polynomial_degree = UnsignedInteger(default=3) polydeg = polynomial_degree exact_integration = Bool(default=False) _parameters = DiscretizationParametersBase._parameters + [ 'ncol', 'use_analytic_jacobian', 'reconstruction', 'polydeg', 'exact_integration' ] _dimensionality = ['axial_dof'] @property def axial_dof(self): """int: Number of degrees of freedom in the axial discretization.""" return self.ncol * (self.polynomial_degree + 1)
[docs] class LRMPDiscretizationFV(DiscretizationParametersBase): """Discretization parameters of the FV version of the LRMP. Attributes ---------- ncol : UnsignedInteger, optional Number of axial column discretization cells. Default is 100. par_geom : Switch, optional The geometry of the particles in the model. Valid values are 'SPHERE', 'CYLINDER', and 'SLAB'. Default is 'SPHERE'. 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 * NPARTYPE is used. The 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. See Also -------- CADETProcess.processModel.LRMPDiscretizationDG CADETProcess.processModel.LumpedRateModelWithPores """ ncol = UnsignedInteger(default=100) par_geom = Switch( default='SPHERE', valid=['SPHERE', 'CYLINDER', 'SLAB'] ) 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) _parameters = DiscretizationParametersBase._parameters + [ 'ncol', 'par_geom', 'use_analytic_jacobian', 'reconstruction', 'gs_type', 'max_krylov', 'max_restarts', 'schur_safety' ] _dimensionality = ['ncol']
[docs] class LRMPDiscretizationDG(DGMixin): """Discretization parameters of the DG version of the LRMP. Attributes ---------- ncol : UnsignedInteger, optional Number of axial column discretization cells. Default is 16. par_geom : Switch, optional The geometry of the particles in the model. Valid values are 'SPHERE', 'CYLINDER', and 'SLAB'. Default is 'SPHERE'. 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'. polynomial_degree : UnsignedInteger, optional Degree of the polynomial used for spatial discretization. Default is 3. polydeg : UnsignedInteger, optional Alias for polynomial_degree. exact_integration : Bool, optional Whether to use exact integration for the spatial discretization. Default is False. 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 * NPARTYPE is used. The 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. See Also -------- CADETProcess.processModel.LRMPDiscretizationFV CADETProcess.processModel.LumpedRateModelWithPores """ ncol = UnsignedInteger(default=16) par_geom = Switch( default='SPHERE', valid=['SPHERE', 'CYLINDER', 'SLAB'] ) use_analytic_jacobian = Bool(default=True) reconstruction = Switch(default='WENO', valid=['WENO']) polynomial_degree = UnsignedInteger(default=3) polydeg = polynomial_degree exact_integration = Bool(default=False) gs_type = Bool(default=True) max_krylov = UnsignedInteger(default=0) max_restarts = UnsignedInteger(default=10) schur_safety = UnsignedFloat(default=1.0e-8) _parameters = DiscretizationParametersBase._parameters + [ 'ncol', 'par_geom', 'use_analytic_jacobian', 'reconstruction', 'polydeg', 'exact_integration', 'gs_type', 'max_krylov', 'max_restarts', 'schur_safety' ] _dimensionality = ['axial_dof'] @property def axial_dof(self): """int: Number of axial degrees of freedom in the spatial discretization.""" return self.ncol * (self.polynomial_degree + 1)
[docs] class GRMDiscretizationFV(DiscretizationParametersBase): """Discretization parameters of the FV version of the LRMP. 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. See Also -------- CADETProcess.processModel.LRMPDiscretizationDG CADETProcess.processModel.LumpedRateModelWithPores """ ncol = UnsignedInteger(default=100) npar = UnsignedInteger(default=5) 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', 'par_geom', 'par_disc_type', 'par_disc_vector', 'par_boundary_order', 'use_analytic_jacobian', 'reconstruction', 'gs_type', 'max_krylov', 'max_restarts', 'schur_safety', 'fix_zero_surface_diffusion', ] _required_parameters = [ 'ncol', 'npar', 'par_geom', 'par_disc_type', 'par_boundary_order', 'use_analytic_jacobian', 'reconstruction', 'gs_type', 'max_krylov', 'max_restarts', 'schur_safety', 'fix_zero_surface_diffusion', ] _dimensionality = ['ncol', 'npar'] @property def par_disc_vector_length(self): """int: Number of entries in the particle discretization vector.""" return self.npar + 1
[docs] class GRMDiscretizationDG(DGMixin): """Discretization parameters of the DG version of the GRM. Attributes ---------- ncol : UnsignedInteger, optional Number of axial column discretization cells. Default is 16. npar : UnsignedInteger, optional Number of particle (radial) discretization cells for each particle type. Default is 1. nparcell : UnsignedInteger, optional Alias for npar par_geom : Switch, optional The geometry of the particles in the model. Valid values are 'SPHERE', 'CYLINDER', and 'SLAB'. Default is 'SPHERE'. 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'. polynomial_degree : UnsignedInteger, optional Degree of the polynomial used for axial discretization. Default is 3. polydeg : UnsignedInteger, optional Alias for polynomial_degree. polynomial_degree_particle : UnsignedInteger, optional Degree of the polynomial used for particle radial discretization. Default is 3. exact_integration : Bool, optional Whether to use exact integration for the axial discretization. Default is False. exact_integration : Bool, optional Whether to use exact integration for the particle radial discretization. Default is False. 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 * NPARTYPE is used. The 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 Whether to fix zero surface diffusion for particles. Default is False. If True, the parameters must not become non-zero during this or subsequent simulation runs. The internal data structures are optimized for a more efficient simulation. Default is False (optimization disabled in favor of flexibility). See Also -------- CADETProcess.processModel.GRMDiscretizationDG CADETProcess.processModel.GeneralRateModel """ ncol = UnsignedInteger(default=16) npar = UnsignedInteger(default=1) nparcell = npar 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' ) par_boundary_order = RangedInteger(lb=1, ub=2, default=2) use_analytic_jacobian = Bool(default=True) reconstruction = Switch(default='WENO', valid=['WENO']) polynomial_degree = UnsignedInteger(default=3) polydeg = polynomial_degree polynomial_degree_particle = UnsignedInteger(default=3) parpolydeg = polynomial_degree_particle exact_integration = Bool(default=False) exact_integration_particle = Bool(default=True) par_exact_integration = exact_integration_particle 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', 'nparcell', 'par_geom', 'par_disc_type', 'par_disc_vector', 'par_boundary_order', 'use_analytic_jacobian', 'reconstruction', 'polydeg', 'parpolydeg', 'exact_integration', 'par_exact_integration', 'gs_type', 'max_krylov', 'max_restarts', 'schur_safety', 'fix_zero_surface_diffusion', ] _dimensionality = ['axial_dof', 'par_dof'] @property def axial_dof(self): """int: Number of axial degrees of freedom in the axial discretization.""" return self.ncol * (self.polynomial_degree + 1) @property def par_dof(self): """int: Number of particle degrees of freedom in the axial discretization.""" return self.ncol * (self.polynomial_degree_particle + 1) @property def par_disc_vector_length(self): """int: Number of entries in the particle discretization vector.""" return self.npar + 1
[docs] class WenoParameters(Structure): """Discretization parameters for the WENO scheme. Attributes ---------- boundary_model : Switch, optional Specifies the method for dealing with boundary cells. Valid values are: 0: Lower WENO order (stable) 1: Zero weights (unstable for small `D_ax`) 2: Zero weights for p != 0 (stable?) 3: Large ghost points Default is 0. weno_eps : UnsignedFloat, optional A small positive number used to avoid division by zero in the WENO scheme. Default is 1e-10. weno_order : UnsignedInteger, optional Order of the WENO scheme. Valid values are: 1: Standard upwind scheme (order 1) 2: WENO 2 (order 3) 3: WENO 3 (order 5) Default is 3. See Also -------- Structure """ boundary_model = UnsignedInteger(default=0, ub=3) weno_eps = UnsignedFloat(default=1e-10) weno_order = UnsignedInteger(default=3, ub=3) _parameters = ['boundary_model', 'weno_eps', 'weno_order']
[docs] class ConsistencySolverParameters(Structure): """A class for defining the consistency solver parameters for Cadet. Parameters ---------- solver_name : Switch, optional Name of the solver. Valid values are 'LEVMAR', 'ATRN_RES', 'ATRN_ERR', and 'COMPOSITE'. The default is 'LEVMAR' init_damping : UnsignedFloat, optional The initial damping parameter. Default is 0.01. min_damping : UnsignedFloat, optional The minimum damping parameter. Default is 0.0001. max_iterations : UnsignedFloat, optional The maximum number of iterations. Default is 50. subsolvers : Switch, optional Vector with names of solvers for the composite solver (only required for composite solver). Valid values are 'LEVMAR', 'ATRN_RES', 'ATRN_ERR', and 'COMPOSITE'. The default is 'LEVMAR' See Also -------- Structure """ solver_name = Switch( default='LEVMAR', valid=['LEVMAR', 'ATRN_RES', 'ARTN_ERR', 'COMPOSITE'] ) init_damping = UnsignedFloat(default=0.01) min_damping = UnsignedFloat(default=0.0001) max_iterations = UnsignedInteger(default=50) subsolvers = Switch( default='LEVMAR', valid=['LEVMAR', 'ATRN_RES', 'ARTN_ERR'] ) _parameters = [ 'solver_name', 'init_damping', 'min_damping', 'max_iterations', 'subsolvers' ]