Skip to content
Snippets Groups Projects
Commit 8fe9ceac authored by Markus Holzer's avatar Markus Holzer
Browse files

Implement force on boundary

parent ffef586b
No related branches found
No related tags found
1 merge request!177Integrate force calculation in wall boundaries
Pipeline #69224 failed
from dataclasses import replace
import numpy as np
from pystencils import Assignment, CreateKernelConfig, create_kernel, Field, Target
......@@ -167,19 +168,21 @@ def create_lattice_boltzmann_boundary_kernel(pdf_field, index_field, lb_method,
dir_symbol = indexing.dir_symbol
inv_dir = indexing.inverse_dir_symbol
config = CreateKernelConfig(target=target, default_number_int="int32",
skip_independence_check=True, **kernel_creation_args)
default_data_type = config.data_type.default_factory()
if force_vector is None:
force_vector_type = np.dtype([(f"F_{i}", np.float64) for i in range(dim)], align=True)
force_vector_type = np.dtype([(f"F_{i}", default_data_type.c_name) for i in range(dim)], align=True)
force_vector = Field.create_generic('force_vector', spatial_dimensions=1,
dtype=force_vector_type,
field_type=FieldType.INDEXED)
dtype=force_vector_type, field_type=FieldType.INDEXED)
config = replace(config, index_fields=[index_field, force_vector])
boundary_assignments = boundary_functor(f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, force_vector)
boundary_assignments = indexing.substitute_proxies(boundary_assignments)
config = CreateKernelConfig(index_fields=[index_field, force_vector], target=target, default_number_int="int32",
skip_independence_check=True, **kernel_creation_args)
default_data_type = config.data_type.default_factory()
if pdf_field.dtype != default_data_type:
boundary_assignments = add_subexpressions_for_field_reads(boundary_assignments, data_type=default_data_type)
......
import numpy as np
import pytest
from lbmpy.boundaries import NoSlip, UBB, SimpleExtrapolationOutflow, ExtrapolationOutflow, \
FixedDensity, DiffusionDirichlet, NeumannByCopy, StreamInConstant, FreeSlip
from lbmpy.boundaries.boundaryhandling import LatticeBoltzmannBoundaryHandling
from lbmpy.boundaries import (NoSlip, NoSlipLinearBouzidi, QuadraticBounceBack,
UBB, SimpleExtrapolationOutflow, ExtrapolationOutflow, FixedDensity, DiffusionDirichlet,
NeumannByCopy, StreamInConstant, FreeSlip)
from lbmpy.boundaries.boundaryhandling import LatticeBoltzmannBoundaryHandling, create_lattice_boltzmann_boundary_kernel
from lbmpy.creationfunctions import create_lb_function, create_lb_method, LBMConfig
from lbmpy.enums import Stencil, Method
from lbmpy.geometry import add_box_boundary
from lbmpy.lbstep import LatticeBoltzmannStep
from lbmpy.stencils import LBStencil
import pystencils as ps
from pystencils import create_data_handling, make_slice, Target, CreateKernelConfig
from pystencils.slicing import slice_from_direction
from pystencils.stencil import inverse_direction
......@@ -435,3 +437,45 @@ def test_boundary_utility_functions():
assert stream == StreamInConstant(constant=1.0, name="stream")
assert not stream == StreamInConstant(constant=1.0, name="test")
assert not stream == noslip
@pytest.mark.parametrize("given_force_vector", [True, False])
@pytest.mark.parametrize("dtype", ["float32", "float64"])
def test_force_on_boundary(given_force_vector, dtype):
stencil = LBStencil(Stencil.D2Q9)
pdfs = ps.fields(f"pdfs_src({stencil.Q}): {dtype}[{stencil.D}D]", layout='fzyx')
method = create_lb_method(lbm_config=LBMConfig(stencil=stencil, method=Method.SRT, relaxation_rate=1.8))
noslip = NoSlip(name="noslip", calculate_force_on_boundary=True)
bouzidi = NoSlipLinearBouzidi(name="bouzidi", calculate_force_on_boundary=True)
qq_bounce_Back = QuadraticBounceBack(name="qqBB", relaxation_rate=1.8, calculate_force_on_boundary=True)
boundary_objects = [noslip, bouzidi, qq_bounce_Back]
for boundary in boundary_objects:
if given_force_vector:
force_vector_type = np.dtype([(f"F_{i}", dtype) for i in range(stencil.D)], align=True)
force_vector = ps.Field('forceVector', ps.FieldType.INDEXED, force_vector_type, layout=[0],
shape=(ps.TypedSymbol("forceVectorSize", "int32"), 1), strides=(1, 1))
else:
force_vector = None
index_struct_dtype = _numpy_data_type_for_boundary_object(boundary, stencil.D)
index_field = ps.Field('indexVector', ps.FieldType.INDEXED, index_struct_dtype, layout=[0],
shape=(ps.TypedSymbol("indexVectorSize", "int32"), 1), strides=(1, 1))
create_lattice_boltzmann_boundary_kernel(pdfs, index_field, method, boundary, force_vector=force_vector)
def _numpy_data_type_for_boundary_object(boundary_object, dim):
boundary_index_array_coordinate_names = ["x", "y", "z"]
direction_member_name = "dir"
default_index_array_dtype = np.int32
coordinate_names = boundary_index_array_coordinate_names[:dim]
return np.dtype(
[(name, default_index_array_dtype) for name in coordinate_names]
+ [(direction_member_name, default_index_array_dtype)]
+ [(i[0], i[1].numpy_dtype) for i in boundary_object.additional_data],
align=True,)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment