Creating LBM kernels and Parameter Specifications¶
Kernel functions are created in four/five steps represented by five
python functions: create_lb_method
, create_lb_collision_rule/create_lb_update_rule, create_lb_ast
and
create_lb_function
Each of those functions is configured with three data classes.
One dataclass defines the lattice Boltzmann method itself. This class is called LBMConfig
. It defines, for example,
which collision space or LB stencil should be used.
The second one determines optimisations that are specific to the LBM. Optimisations like the
common subexpression elimination. Most of these optimisations act on the assignment level.
This means they only manipulate the assignments. The config class is called LBMOptimisation
.
The third data class determines hardware optimisation. This means that contrary to the LBMOptimisation
class,
it acts on the level of the abstract syntax tree. Thus, it is independent of the assignments and the LBM
and belongs to pystencils, not lbmpy. This can be found in the pystencils module as
‘pystencils.kernelcreation.CreateKernelConfig’. With this class, for example, the target (CPU, GPU etc.)
of the generated code is specified.
- Method:
the method defines the collision process. Currently, there are two big categories: moment and cumulant based methods. A method defines how each moment or cumulant is relaxed by storing the equilibrium value and the relaxation rate for each moment/cumulant.
- Collision/Update Rule:
Methods can generate a “collision rule” which is an equation collection that define the post collision values as a function of the pre-collision values. On these equation collection simplifications are applied to reduce the number of floating point operations. At this stage an entropic optimisation step can also be added to determine one relaxation rate by an entropy condition. Then a streaming rule is added which transforms the collision rule into an update rule. The streaming step depends on the pdf storage (source/destination, AABB pattern, EsoTwist). Currently only the simple source/destination pattern is supported.
- AST:
The abstract syntax tree describes the structure of the kernel, including loops and conditionals. The ast can be modified, e.g., to add OpenMP pragmas, reorder loops or apply other optimisations.
- Function:
This step compiles the AST into an executable function, either for CPU or GPUs. This function behaves like a normal Python function and runs one LBM time step.
Each stage (apart from Function) also adds its result to the given LBMConfig
object. The LBMConfig
thus coalesces all information defining the LBM kernel.
The function create_lb_function()
runs the whole pipeline, the other functions in this module
execute this pipeline only up to a certain step. Each function optionally also takes the result of the previous step.
For example, to modify the AST one can run:
ast = create_lb_ast(...)
# modify ast here
func = create_lb_function(ast=ast, ...)
- class LBMConfig(stencil=<lbmpy.stencils.LBStencil object>, method=Method.SRT, relaxation_rates=None, relaxation_rate=None, compressible=False, zero_centered=True, delta_equilibrium=None, equilibrium_order=2, c_s_sq=1/3, weighted=True, nested_moments=None, force_model=None, force=(0, 0, 0), continuous_equilibrium=True, maxwellian_moments=None, initial_velocity=(None, ), galilean_correction=False, fourth_order_correction=False, collision_space_info=None, entropic=False, entropic_newton_iterations=None, omega_output_field=None, eddy_viscosity_field=None, subgrid_scale_model=None, cassons=False, fluctuating=False, temperature=None, psm_config=None, output=<factory>, velocity_input=None, density_input=None, conserved_moments=True, kernel_type='default_stream_collide', streaming_pattern='pull', timestep=Timestep.BOTH, field_name='src', temporary_field_name='dst', lb_method=None, collision_rule=None, update_rule=None, ast=None)¶
Below all parameters for the LBMConfig are explained
-
stencil:
LBStencil
= <lbmpy.stencils.LBStencil object>¶ All stencils are defined in
lbmpy.enums.Stencil
. From thatlbmpy.stencils.LBStencil
class will be created
-
method:
Method
= 1¶ Name of lattice Boltzmann method. Defined by
lbmpy.enums.Method
. This determines the selection and relaxation pattern of moments/cumulants, i.e. which moment/cumulant basis is chosen, and which of the basis vectors are relaxed together
-
relaxation_rates:
Iterable
= None¶ Sequence of relaxation rates, number depends on selected method. If you specify more rates than method needs, the additional rates are ignored.
If no relaxation rates are specified, the parameter relaxation_rate will be consulted.
-
relaxation_rate:
Union
[int
,float
,Type
[Symbol
]] = None¶ The method’s primary relaxation rate. In most cases, this is the relaxation rate governing shear viscosity. For SRT, this is the only relaxation rate. For TRT, the second relaxation rate is then determined via magic number. In the case of raw moment, central moment, and cumulant-based MRT methods, all other relaxation rates will be set to unity.
If neither relaxation_rate nor relaxation_rates is specified, the behaviour is as if relaxation_rate=sp.Symbol(‘omega’) was set.
-
compressible:
bool
= False¶ Affects the selection of equilibrium moments. Both options approximate the incompressible Navier Stokes Equations. However when chosen as False, the approximation is better, the standard LBM derivation is compressible.
-
zero_centered:
bool
= True¶ Governs the storage format of populations. If False, the discrete particle distribution vector is stored in its absolute form. If True, instead, only the distribution’s deviation from its rest state (typically given by the lattice weights) is stored.
-
delta_equilibrium:
bool
= None¶ Determines whether or not the (continuous or discrete, see continuous_equilibrium) Maxwellian equilibrium is expressed in its absolute form, or only by its deviation from the rest state (typically given by the reference density and zero velocity). This parameter is only effective if zero_centered is set to True. Then, if delta_equilibrium is False, the rest state must be reintroduced to the populations during collision. Otherwise, if delta_equilibrium is True, the collision equations can be derived using only the deviations from the rest state.
If None is passed to delta_equilibrium, its value will be chosen automatically, depending on the value of zero_centered and the chosen method.
-
equilibrium_order:
int
= 2¶ Order in velocity, at which the equilibrium moment approximation is truncated. Order 2 is sufficient to approximate Navier-Stokes. This parameter has no effect on cumulant-based methods, whose equilibrium terms have no contributions above order one.
-
c_s_sq:
Rational
= 1/3¶ The squared lattice speed of sound used to derive the LB method. It is very uncommon to use a value different to 1 / 3.
-
weighted:
bool
= True¶ Affects only orthogonal MRT methods. If set to True a weighted Gram-Schmidt procedure is used to orthogonalise the moments.
-
nested_moments:
List
[List
] = None¶ A list of lists of modes, grouped by common relaxation times. This is usually used in conjunction with lbmpy.methods.default_moment_sets.mrt_orthogonal_modes_literature. If this argument is not provided, Gram-Schmidt orthogonalisation of the default modes is performed.
-
force_model:
Union
[AbstractForceModel
,ForceModel
] = None¶ Force model to determine how forcing terms enter the collision rule. Possibilities are defined in :class: lbmpy.enums.ForceModel
-
force:
Union
[Tuple
,Field
] = (0, 0, 0)¶ Either constant force or a symbolic expression depending on field value
-
continuous_equilibrium:
bool
= True¶ Way to compute equilibrium moments/cumulants, if False the standard discretised LBM equilibrium is used, otherwise the equilibrium moments are computed from the continuous Maxwellian. This makes only a difference if sparse stencils are used e.g. D2Q9 and D3Q27 are not affected, D319 and DQ15 are affected.
-
maxwellian_moments:
bool
= None¶ Deprecated and due for removal by version 0.5; use continuous_equilibrium instead.
-
initial_velocity:
Tuple
= (None,)¶ Initial velocity in domain, can either be a tuple (x,y,z) velocity to set a constant velocity everywhere, or a numpy array with the same size of the domain, with a last coordinate of shape dim to set velocities on cell level
-
galilean_correction:
bool
= False¶ Special correction for D3Q27 cumulant LBMs. For Details see
lbmpy.methods.cumulantbased.galilean_correction
-
fourth_order_correction:
Union
[float
,bool
] = False¶ Special correction for rendering D3Q27 cumulant LBMs fourth-order accurate in diffusion. For Details see
lbmpy.methods.cumulantbased.fourth_order_correction
. If set to True, the fourth-order correction is employed without limiters (or more precisely with a very high limiter, practically disabling the limiters). If this variable is set to a number, the latter is used for the limiters (uniformly for omega_3, omega_4 and omega_5).
-
collision_space_info:
CollisionSpaceInfo
= None¶ Information about the LB method’s collision space (see
lbmpy.methods.creationfunctions.CollisionSpaceInfo
) including the classes defining how populations are transformed to these spaces. If left at None, it will be inferred according to the value of method. If an instance of thelbmpy.enums.CollisionSpace
enum is passed, albmpy.method.CollisionSpaceInfo
instance with the space’s default setup is created. Otherwise, the selected collision space must be in accord with the chosenlbmpy.enum.Method
.
-
entropic:
bool
= False¶ In case there are two distinct relaxation rate in a method, one of them (usually the one, not determining the viscosity) can be automatically chosen w.r.t an entropy condition. For details see
lbmpy.methods.momentbased.entropic
-
entropic_newton_iterations:
int
= None¶ For moment methods the entropy optimum can be calculated in closed form. For cumulant methods this is not possible, in that case it is computed using Newton iterations. This parameter can be used to force Newton iterations and specify how many should be done
-
omega_output_field:
Field
= None¶ A pystencils Field can be passed here, where the calculated free relaxation rate of an entropic or subgrid-scale method is written to
-
eddy_viscosity_field:
Field
= None¶ A pystencils Field can be passed here, where the eddy-viscosity of a subgrid-scale model is written.
-
subgrid_scale_model:
Union
[SubgridScaleModel
,tuple
[SubgridScaleModel
,float
],tuple
[SubgridScaleModel
,int
]] = None¶ Choose a subgrid-scale model (SGS) for large-eddy simulations.
omega_output_field
can be set to write out adapted relaxation rates. Either provide just the SGS and use the default model constants or provide a tuple of the SGS and its corresponding model constant.
-
cassons:
CassonsParameters
= False¶ //doi.org/10.1007/s10955-005-8415-x The parameters are set with the
CassonsParameters
dataclass.- Type:
Adds the Cassons model according to https
-
fluctuating:
dict
= False¶ Enables fluctuating lattice Boltzmann by randomizing collision process. Pass dictionary with parameters to
lbmpy.fluctuatinglb.add_fluctuations_to_collision_rule
. Can only be used for weighed MRT collision operators.
-
psm_config:
PSMConfig
= None¶ If a PSM config is specified, (1 - fractionField) is added to the relaxation rates of the collision and to the potential force term, and a solid collision is build and added to the main assignments.
-
output:
dict
¶ A dictionary mapping macroscopic quantites e.g. the strings ‘density’ and ‘velocity’ to pystencils fields. In each timestep the corresponding quantities are written to the given fields. Possible input would be: {‘density’: density_field, ‘velocity’: velocity_field}
-
velocity_input:
Field
= None¶ Symbolic field where the velocities are read from. If None is given the velocity is calculated inplace from with first order moments.
-
density_input:
Field
= None¶ Symbolic field where the density is read from. If None is given the density is calculated inplace from with zeroth order moment.
-
conserved_moments:
bool
= True¶ If lower order moments are conserved or not. If velocity or density input is set the lower order moments are not conserved anymore.
-
kernel_type:
Union
[str
,Type
[PdfFieldAccessor
]] = 'default_stream_collide'¶ 'default_stream_collide'
(default),'collide_only'
,'stream_pull_only'
. With'default_stream_collide'
, streaming pattern and even/odd time-step (for in-place patterns) can be specified by thestreaming_pattern
andtimestep
arguments. For backwards compatibility,kernel_type
also accepts'stream_pull_collide'
,'collide_stream_push'
,'esotwist_even'
,'esotwist_odd'
,'aa_even'
and'aa_odd'
for selection of the streaming pattern.- Type:
Supported values
-
streaming_pattern:
str
= 'pull'¶ The streaming pattern to be used with a
'default_stream_collide'
kernel. Accepted values are'pull'
,'push'
,'aa'
and'esotwist'
.
-
timestep:
Timestep
= 2¶ Timestep modulus for the streaming pattern. For two-fields patterns, this argument is irrelevant and by default set to
Timestep.BOTH
. For in-place patterns,Timestep.EVEN
orTimestep.ODD
must be specified.
-
lb_method:
Type
[AbstractLbMethod
] = None¶ Instance of lbmpy.methods.abstractlbmethod.AbstractLbMethod. If this parameter is None, the lb_method is derived via create_lb_method.
-
collision_rule:
LbmCollisionRule
= None¶ Instance of
lbmpy.methods.LbmCollisionRule
. If this parameter is None, the collision rule is derived via create_lb_collision_rule.
-
update_rule:
LbmCollisionRule
= None¶ Instance of
lbmpy.methods.LbmCollisionRule
. If this parameter is None, the update rule is derived via create_lb_update_rule.
-
ast:
KernelFunction
= None¶ Instance of pystencils.astnodes.KernelFunction. If this parameter is None, the ast is derived via create_lb_ast.
-
stencil:
- class LBMOptimisation(cse_pdfs=False, cse_global=False, simplification='auto', pre_simplification=True, split=False, field_size=None, field_layout='fzyx', symbolic_field=None, symbolic_temporary_field=None, builtin_periodicity=(False, False, False))¶
Below all parameters for the LBMOptimisation are explained
-
cse_global:
bool
= False¶ Run common subexpression elimination after all other simplifications have been executed.
-
simplification:
Union
[str
,bool
,SimplificationStrategy
] = 'auto'¶ Simplifications applied during the derivation of the collision rule. If
True
or'auto'
, a default simplification strategy is selected according to the type of the method; seelbmpy.simplificationfactory.create_simplification_strategy()
. IfFalse
, no simplification is applied. Otherwise, the given simplification strategy will be applied.
-
pre_simplification:
bool
= True¶ Simplifications applied during the derivation of the collision rule for cumulant LBMs. For details see
lbmpy.moment_transforms
.
-
split:
bool
= False¶ Split innermost loop, to handle only two directions per loop. This reduces the number of parallel load/store streams and thus speeds up the kernel on most architectures.
-
field_layout:
str
= 'fzyx'¶ 'c'
or'numpy'
for standard numpy layout,'reverse_numpy'
or'f'
for fortran layout, this does not apply when pdf_arr was given, then the same layout as pdf_arr is used.
-
symbolic_field:
Field
= None¶ Pystencils field for source (pdf field that is read)
-
symbolic_temporary_field:
Field
= None¶ Pystencils field for temporary (pdf field that is written in stream, or stream-collide)
-
builtin_periodicity:
Tuple
[bool
] = (False, False, False)¶ Instead of handling periodicity by copying ghost layers, the periodicity is built into the kernel. This parameters specifies if the domain is periodic in (x,y,z) direction. Even if the periodicity is built into the kernel, the fields have one ghost layer to be consistent with other functions.
-
cse_global:
- create_lb_function(ast=None, lbm_config=None, lbm_optimisation=None, config=None, optimization=None, **kwargs)¶
Creates a Python function for the LB method
- create_lb_ast(update_rule=None, lbm_config=None, lbm_optimisation=None, config=None, optimization=None, **kwargs)¶
Creates a pystencils AST for the LB method
- create_lb_method(lbm_config=None, **params)¶
Creates a LB method, defined by moments/cumulants for collision space, equilibrium and relaxation rates.