diff --git a/lib/walberla/experimental/lbm/GenericHbbBoundary.hpp b/lib/walberla/experimental/lbm/GenericHbbBoundary.hpp index aad3c4bcb383d7cf2aeb5341f5ec3cb57a82c83e..54a536fa5a6dd9f7f9d1c6f9f7fb153625d80157 100644 --- a/lib/walberla/experimental/lbm/GenericHbbBoundary.hpp +++ b/lib/walberla/experimental/lbm/GenericHbbBoundary.hpp @@ -16,93 +16,92 @@ #include "walberla/experimental/sweep/SparseIndexList.hpp" -namespace walberla::experimental -{ -namespace lbm +namespace walberla::experimental::lbm { struct HbbLink { - int32_t x; - int32_t y; - int32_t z; - int32_t dir; - - /** - * Create a halfway bounce-back boundary link from a fluid cell `c` to a boundary cell in direction `d`. - */ - HbbLink(const Cell& c, const stencil::Direction d) - : x{ int32_c(c.x()) }, y{ int32_c(c.y()) }, z{ int32_c(c.z()) }, dir{ int32_t(d) } - {} - - bool operator==(const HbbLink& other) const - { - return std::tie(x, y, z, dir) == std::tie(other.x, other.y, other.z, other.dir); - } + int32_t x; + int32_t y; + int32_t z; + int32_t dir; + + /** + * Create a halfway bounce-back boundary link from a fluid cell `c` to a boundary cell in direction `d`. + */ + HbbLink(const Cell& c, const stencil::Direction d) + : x{ int32_c(c.x()) }, y{ int32_c(c.y()) }, z{ int32_c(c.z()) }, dir{ int32_t(d) } + {} + + bool operator==(const HbbLink& other) const + { + return std::tie(x, y, z, dir) == std::tie(other.x, other.y, other.z, other.dir); + } }; -/** - * @brief Boundary index list for half-way bounce-back boundary conditions - */ -template< typename Stencil_T > -class GenericHbbBoundary +template< typename Impl > +struct GenericHbbFactoryImplTraits { -public: - using Stencil = Stencil_T; - using IndexVectors = sweep::internal::IndexListBuffer< HbbLink >; - - GenericHbbBoundary(StructuredBlockForest& blocks) - { - auto createIdxVector = [](IBlock* const, StructuredBlockStorage* const) { return new IndexVectors(); }; - indexVectorsId_ = blocks.addStructuredBlockData< IndexVectors >(createIdxVector); - } - - template< typename FlagField_T > - void fillFromFlagField(StructuredBlockForest& blocks, ConstBlockDataID flagFieldID, - FlagUID boundaryFlagUID, FlagUID domainFlagUID) - { - for (auto & block: blocks) - fillFromFlagField< FlagField_T >(block, flagFieldID, boundaryFlagUID, domainFlagUID); - } - - template< typename FlagField_T > - void fillFromFlagField(IBlock& block, ConstBlockDataID flagFieldID, FlagUID boundaryFlagUID, FlagUID domainFlagUID); - -protected: - BlockDataID indexVectorsId_; + using Stencil_T = typename Impl::Stencil; + using IdxStruct_T = HbbLink; + using IndexListMemTag_T = typename Impl::memtag_t; + using IndexList_T = sweep::SparseIndexList< IdxStruct_T, IndexListMemTag_T >; }; -template< typename Stencil_T > -template< typename FlagField_T > -void GenericHbbBoundary< Stencil_T >::fillFromFlagField(IBlock& block, ConstBlockDataID flagFieldID, - FlagUID boundaryFlagUID, FlagUID domainFlagUID) +template< typename Impl > +class GenericHbbFactory { - auto* indexVectors = block.getData< IndexVectors >(indexVectorsId_); - auto& indexVectorAll = indexVectors->vector(); - auto* flagField = block.getData< FlagField_T >(flagFieldID); + using ImplTraits = GenericHbbFactoryImplTraits< Impl >; + + public: + GenericHbbFactory(const shared_ptr< StructuredBlockForest > blocks, BlockDataID pdfFieldID) + : blocks_{ blocks }, pdfFieldID_{ pdfFieldID } + {} + + template< typename FlagField_T > + auto fromFlagField(BlockDataID flagFieldID, field::FlagUID boundaryFlagUID, field::FlagUID fluidFlagUID) + { + using flag_t = typename FlagField_T::flag_t; + using IndexList_T = typename ImplTraits::IndexList_T; + using Stencil = typename ImplTraits::Stencil_T; + + IndexList_T indexList{ *blocks_ }; - if (!(flagField->flagExists(boundaryFlagUID) && flagField->flagExists(domainFlagUID))) return; + for (auto& block : *blocks_) + { + FlagField_T* flagField = block.getData< FlagField_T >(flagFieldID); + flag_t boundaryFlag{ flagField->getFlag(boundaryFlagUID) }; + flag_t fluidFlag{ flagField->getFlag(fluidFlagUID) }; - auto boundaryFlag = flagField->getFlag(boundaryFlagUID); - auto domainFlag = flagField->getFlag(domainFlagUID); + if (!(flagField->flagExists(boundaryFlagUID) && flagField->flagExists(fluidFlagUID))) continue; - indexVectorAll.clear(); + auto& idxVector = indexList.getVector(block); - const cell_idx_t numGhostLayers = cell_idx_c(flagField->nrOfGhostLayers() - 1); - for (auto it = flagField->beginWithGhostLayerXYZ(numGhostLayers); it != flagField->end(); ++it) - { - const Cell fluidCell{ it.cell() }; + for (auto it = flagField->beginXYZ(); it != flagField->end(); ++it) + { + Cell fluidCell{ it.cell() }; + if (!isFlagSet(it, fluidFlag)) { continue; } - if (!isFlagSet(it, domainFlag)) continue; + for (auto dIt = Stencil::beginNoCenter(); dIt != Stencil::end(); ++dIt) + { + stencil::Direction dir{ *dIt }; + Cell neighbor{ fluidCell + dir }; + if (flagField->isFlagSet(neighbor, boundaryFlag)) { idxVector.emplace_back(fluidCell, dir); } + } + } + } - for (auto dIt = Stencil::beginNoCenter(); dIt != Stencil::end(); ++dIt) - { - const stencil::Direction dir{ *dIt }; + return impl().irregularFromIndexVector(indexList); + } - if (isFlagSet(it.neighbor(dir), boundaryFlag)) { indexVectorAll.emplace_back(fluidCell, dir); } - } - } -} + protected: + shared_ptr< StructuredBlockForest > blocks_; + BlockDataID pdfFieldID_; + + private: + Impl& impl() { return *static_cast< Impl* >(this); } + + const Impl& impl() const { return *static_cast< const Impl* >(this); } +}; -} // namespace sfg -} // namespace walberla +} // namespace walberla::experimental::lbm diff --git a/src/walberla/codegen/boundaries/__init__.py b/src/walberla/codegen/boundaries/__init__.py index b505fbeaf0ac2e2353f5f7aec9ed71e3334c25bd..4364cb21aab5d7e712f8773c5f3f8363e2fe8b1c 100644 --- a/src/walberla/codegen/boundaries/__init__.py +++ b/src/walberla/codegen/boundaries/__init__.py @@ -1,4 +1,3 @@ -from .hbb import SimpleHbbBoundary -from .linkwise import NoSlip, FreeSlip +from .linkwise import NoSlip, FreeSlip, GenericHBB -__all__ = ["SimpleHbbBoundary", "NoSlip", "FreeSlip"] +__all__ = ["NoSlip", "FreeSlip", "GenericHBB"] diff --git a/src/walberla/codegen/boundaries/boundary_utils.py b/src/walberla/codegen/boundaries/boundary_utils.py index 453d611cba1fa1c4bb7891f921befe6fd68867a2..e3ce6b0b29550b7c1221cb0533b4f63345e4c2d1 100644 --- a/src/walberla/codegen/boundaries/boundary_utils.py +++ b/src/walberla/codegen/boundaries/boundary_utils.py @@ -1,4 +1,6 @@ from functools import cache +from typing import Any +from abc import abstractmethod from pystencils import Field, FieldType, TypedSymbol, Assignment from pystencils.types import PsStructType, create_type @@ -35,6 +37,9 @@ class WalberlaLbmBoundary: (TypedSymbol("indexVectorLength", BoundaryIndexType), 1), (1, 1), ) + + @abstractmethod + def boundary_obj(self) -> LbBoundary: ... def get_assignments( self, @@ -43,8 +48,6 @@ class WalberlaLbmBoundary: prev_timestep: Timestep = Timestep.BOTH, streaming_pattern="pull", ) -> list[Assignment]: - assert isinstance(self, LbBoundary) - index_field = self.get_index_field() from lbmpy.advanced_streaming.indexing import BetweenTimestepsIndexing @@ -62,7 +65,7 @@ class WalberlaLbmBoundary: dir_symbol = indexing.dir_symbol inv_dir = indexing.inverse_dir_symbol - boundary_assignments = self( + boundary_assignments = self.boundary_obj()( f_out, f_in, dir_symbol, @@ -78,10 +81,20 @@ class WalberlaLbmBoundary: index_arrs_node = indexing.create_code_node() elements += index_arrs_node.get_array_declarations() - for node in self.get_additional_code_nodes(lb_method)[::-1]: + for node in self.boundary_obj().get_additional_code_nodes(lb_method)[::-1]: elements += node.get_array_declarations() elements += [Assignment(dir_symbol, index_field[0]("dir"))] elements += boundary_assignments.all_assignments return elements + + +class GenericHbbWrapper(WalberlaLbmBoundary): + idx_struct_type = HbbLinkType + + def __init__(self, hbb: LbBoundary): + self._hbb = hbb + + def boundary_obj(self) -> LbBoundary: + return self._hbb diff --git a/src/walberla/codegen/boundaries/hbb.py b/src/walberla/codegen/boundaries/hbb.py deleted file mode 100644 index c249667fc374021a0d9ab8d4ab9c8d60c12d299e..0000000000000000000000000000000000000000 --- a/src/walberla/codegen/boundaries/hbb.py +++ /dev/null @@ -1,202 +0,0 @@ -"""Code generation for half-way bounce-back LBM boundary conditions in waLBerla""" - -from pystencils import Field, FieldType, TypedSymbol, Target, AssignmentCollection - -from pystencilssfg import SfgComposer -from pystencilssfg.composer.class_composer import SfgClassComposer -from pystencilssfg.composer.custom import CustomGenerator -from pystencilssfg.lang import AugExpr - -from lbmpy.methods import AbstractLbMethod -from lbmpy.boundaries.boundaryconditions import LbBoundary -from lbmpy.advanced_streaming.indexing import Timestep - -from ..sweep import ( - GlFieldInfo, - SweepClassProperties, - BlockforestParameters, - combine_vectors, -) -from ..api import GhostLayerFieldPtr, BlockDataID, IBlockPtr, StructuredBlockForest, IndexListBufferPtr -from .boundary_utils import HbbLinkType, BoundaryIndexType - - -class HbbBoundaryProperties(SweepClassProperties): - def _constructor(self, sfg: SfgComposer) -> SfgClassComposer.ConstructorBuilder: - blocks = StructuredBlockForest.shared_ptr_ref() - return sfg.constructor(blocks).init("GenericHbbBoundary")( - AugExpr.format("*{}", blocks) - ) - - -class SimpleHbbBoundary(CustomGenerator): - def __init__(self, bc: LbBoundary, lb_method: AbstractLbMethod, pdf_field: Field): - if bc.additional_data: - raise ValueError( - "The SimpleHbbBoundary generator only supports boundary conditions without " - "additional per-link data." - ) - - self._bc = bc - self._name = bc.name - self._lb_method = lb_method - self._pdf_field = pdf_field - self._index_field = self._get_index_field() - self._stencil = lb_method.stencil - - def generate(self, sfg: SfgComposer) -> None: - sfg.include("walberla/experimental/lbm/GenericHbbBoundary.hpp") - sfg.include(f"stencil/{self._stencil.name}.h") - - knamespace = sfg.kernel_namespace(f"{self._name}_kernels") - bc_kernel = _create_lb_boundary_kernel( - self._pdf_field, self._get_index_field(), self._lb_method, self._bc - ) - - khandle = knamespace.add(bc_kernel, self._name) - - domain_fields: list[GlFieldInfo] = sorted( - ( - GlFieldInfo( - f, GhostLayerFieldPtr.create(f), BlockDataID().var(f"{f.name}Id") - ) - for f in khandle.fields - if f.field_type == FieldType.GENERIC - ), - key=lambda f: f.field.name, - ) - - props = HbbBoundaryProperties() - block = IBlockPtr().var("block") - - parameters = khandle.scalar_parameters - - blockforest_params = BlockforestParameters(props, block, None) - parameters = blockforest_params.filter_params(parameters) - - vector_groups = combine_vectors(parameters) - - for fi in domain_fields: - props.add_property(fi.data_id, setter=False, getter=True) - - for s in sorted(parameters, key=lambda p: p.name): - props.add_property(s, setter=True, getter=True) - - idx_vector = IndexListBufferPtr(HbbLinkType).var("indexVector") - idx_vector_id = BlockDataID().bind("this->indexVectorsId_") - - base_class = f"walberla::experimental::lbm::GenericHbbBoundary< walberla::stencil::{self._stencil.name} >" - - sfg.klass(self._name, bases=[f"public {base_class}"])( - *props.render(sfg), - sfg.public( - sfg.method("operator()")( - # Get block data IDs for fields - *( - sfg.init(fi.data_id)(props.get(fi.data_id)) - for fi in domain_fields - ), - # Get fields from block - *( - sfg.init(fi.wlb_field)( - block.getData(fi.wlb_field.field_type, fi.data_id) - ) - for fi in domain_fields - ), - # Map GhostLayerFields to pystencils fields - *(sfg.map_field(fi.field, fi.wlb_field) for fi in domain_fields), - # Get index vector - sfg.init(idx_vector)( - block.getData(idx_vector.field_type, idx_vector_id) - ), - # Map index vector to pystencils field - sfg.map_field(self._index_field, idx_vector), - # Extract parameters - *(sfg.init(param)(props.get(param)) for param in parameters), - # Extract vector components - *( - sfg.map_vector(comps, vec) - for vec, comps in vector_groups.items() - ), - # Extract geometry information - *(blockforest_params.render_extractions(sfg)), - # Call kernel - sfg.call(khandle), - ) - ), - ) - - def _get_index_field(self) -> Field: - return Field( - "indexField", - FieldType.INDEXED, - HbbLinkType, - (0,), - (TypedSymbol("index_vector_length", BoundaryIndexType), 1), - (1, 1), - ) - - -def _create_lb_boundary_kernel( - pdf_field: Field, - index_field, - lb_method, - boundary_functor, - prev_timestep=Timestep.BOTH, - streaming_pattern="pull", - target=Target.CPU, - **kernel_creation_args, -): - """Almost-copy of `lbmpy.boundaryhandling.create_lattice_boltzmann_boundary_kernel`, - extended with waLBerla-specific function expansion.""" - - from lbmpy.advanced_streaming.indexing import BetweenTimestepsIndexing - - indexing = BetweenTimestepsIndexing( - pdf_field, lb_method.stencil, prev_timestep, streaming_pattern, "int32", "int32" - ) - - f_out, f_in = indexing.proxy_fields - dir_symbol = indexing.dir_symbol - inv_dir = indexing.inverse_dir_symbol - - boundary_assignments = boundary_functor( - f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, None # TODO: Fix force vector - ) - boundary_assignments = indexing.substitute_proxies(boundary_assignments) - - from pystencils.types.quick import SInt - from pystencils import CreateKernelConfig, Assignment, create_kernel - from pystencils.simp import add_subexpressions_for_field_reads - - config = CreateKernelConfig( - index_field=index_field, - target=target, - index_dtype=SInt(32), - default_dtype=pdf_field.dtype, # type: ignore - skip_independence_check=True, - **kernel_creation_args, - ) - - default_data_type = config.default_dtype - if pdf_field.dtype != default_data_type: - boundary_assignments = add_subexpressions_for_field_reads( - boundary_assignments, data_type=default_data_type - ) - - elements: list[Assignment] = [] - - index_arrs_node = indexing.create_code_node() - elements += index_arrs_node.get_array_declarations() - - for node in boundary_functor.get_additional_code_nodes(lb_method)[::-1]: - elements += node.get_array_declarations() - - elements += [Assignment(dir_symbol, index_field[0]("dir"))] - elements += boundary_assignments.all_assignments - - asms = AssignmentCollection(elements) - asms = BlockforestParameters.process(asms) - - kernel = create_kernel(asms, config=config) - return kernel diff --git a/src/walberla/codegen/boundaries/linkwise.py b/src/walberla/codegen/boundaries/linkwise.py index a82e9b444e45d0832039acfd4726cc7f92bfa9b8..04a6491ba0712f4f17b55d386757f89cf83e4070 100644 --- a/src/walberla/codegen/boundaries/linkwise.py +++ b/src/walberla/codegen/boundaries/linkwise.py @@ -4,6 +4,7 @@ from pystencils import ( CreateKernelConfig, Target, AssignmentCollection, + FieldType, ) from pystencils.types import PsStructType @@ -13,7 +14,7 @@ from lbmpy.boundaries.boundaryconditions import LbBoundary from pystencilssfg import SfgComposer from pystencilssfg.composer.custom import CustomGenerator -from .hbb import BoundaryIndexType +from .boundary_utils import BoundaryIndexType, GenericHbbWrapper from .boundary_utils import WalberlaLbmBoundary from ..sweep import Sweep from ..api import SparseIndexList, MemTags @@ -107,6 +108,97 @@ class NoSlip(GenericLinkwiseBoundary): return AssignmentCollection(asms) +class GenericHBB(GenericLinkwiseBoundary): + def __init__( + self, + bc: LbBoundary, + lb_method: AbstractLbMethod, + pdf_field: Field, + target: Target | None = None, + ): + if bc.additional_data: + raise ValueError( + "The SimpleHbbBoundary generator only supports boundary conditions without " + "additional per-link data." + ) + + self._bc = GenericHbbWrapper(bc) + self._name = bc.name + self._lb_method = lb_method + self._pdf_field = pdf_field + self._stencil = lb_method.stencil + self._target = target + + @property + def target(self) -> Target | None: + return self._target + + @target.setter + def target(self, t: Target | None): + self._target = t + + def generate(self, sfg: SfgComposer) -> None: + return self._generate_irregular(sfg) + + def _generate_irregular(self, sfg: SfgComposer): + sfg.include("walberla/experimental/lbm/GenericHbbBoundary.hpp") + + # Get assignments for bc + bc_obj = self._bc + bc_asm = bc_obj.get_assignments(self._lb_method, self._pdf_field) + + # Build generator config + bc_cfg = CreateKernelConfig(target=self._target) + bc_cfg.index_dtype = BoundaryIndexType + index_field = bc_obj.get_index_field() + bc_cfg.index_field = index_field + + # Prepare sweep + bc_sweep = Sweep(self._name, bc_asm, bc_cfg) + + # Emit code + sfg.generate(bc_sweep) + + # Build factory + factory_name = f"{self._name}Factory" + factory_crtp_base = ( + f"walberla::experimental::lbm::GenericHbbFactory< {factory_name} >" + ) + memtag_t = MemTags.unified if bc_cfg.get_target().is_gpu() else MemTags.host + index_vector = SparseIndexList( + GenericHbbWrapper.idx_struct_type, memtag_t=memtag_t, ref=True + ).var("indexVector") + + sweep_type = bc_sweep.generated_class() + sweep_ctor_args = { + f"{self._pdf_field.name}Id": "this->pdfFieldID_", + f"{index_field.name}": index_vector, + } + + stencil_name = self._lb_method.stencil.name + sfg.include(f"stencil/{stencil_name}.h") + + sfg.klass(factory_name, bases=[f"public {factory_crtp_base}"])( + sfg.public( + f"using Base = {factory_crtp_base};", + f"friend class {factory_crtp_base};", + f"using Stencil = walberla::stencil::{stencil_name};", + f"using Sweep = {sweep_type.get_dtype().c_string()};", + f"using memtag_t = {memtag_t.c_string()};" "using Base::Base;", + ), + sfg.private( + sfg.method( + "irregularFromIndexVector", + ) + .returns(sweep_type.get_dtype()) + .inline()(sfg.expr("return {};", sweep_type.ctor(**sweep_ctor_args))), + ), + ) + + def _generate_regular(self, sfg: SfgComposer): + assert False + + class FreeSlip(GenericLinkwiseBoundary): """Specular-reflection half-way bounce back boundary condition. @@ -195,8 +287,7 @@ class FreeSlip(GenericLinkwiseBoundary): f"friend class {factory_crtp_base};", f"using Stencil = walberla::stencil::{stencil_name};", f"using Sweep = {sweep_type.get_dtype().c_string()};", - f"using memtag_t = {memtag_t.c_string()};" - "using Base::Base;", + f"using memtag_t = {memtag_t.c_string()};" "using Base::Base;", ), sfg.private( sfg.method( @@ -262,6 +353,9 @@ class WalberlaIrregularFreeSlip(LbBoundary, WalberlaLbmBoundary): "walberla::experimental::lbm::IrregularFreeSlipLinkInfo", ) + def boundary_obj(self) -> LbBoundary: + return self + def __call__( self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, force_vector ): diff --git a/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp b/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp index 2871b8d363703cba9fb93bddb69469b3e5ae103a..f87b21e243f489a63df9f5d2b20c25e472dcd14f 100644 --- a/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp +++ b/user_manual/examples/ForceDrivenChannel/ForceDrivenChannel.cpp @@ -86,12 +86,13 @@ namespace Ex_ForceDrivenChannel auto flagFieldOutput = field::createVTKOutput<FlagField_T>(flagFieldId, *blocks, "flagField", 1, 0); flagFieldOutput(); - auto noSlip = make_unique<gen::NoSlip>(blocks, pdfsId); - noSlip->fillFromFlagField<FlagField_T>(*blocks, flagFieldId, noSlipFlagUid, fluidFlagUid); + gen::NoSlip noSlip { + gen::NoSlipFactory(blocks, pdfsId).fromFlagField< FlagField_T >(flagFieldId, noSlipFlagUid, fluidFlagUid) + }; auto boundarySweep = [&](IBlock *block) { - (*noSlip)(block); + noSlip(block); }; // Timeloop diff --git a/user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py b/user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py index af4285acf81e2a7104d50813908c2f611223cdf0..6289568aa40c49b1f56560db34676c12eb9abe5b 100644 --- a/user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py +++ b/user_manual/examples/ForceDrivenChannel/LbmAlgorithms.py @@ -3,7 +3,7 @@ import pystencils as ps from pystencilssfg import SourceFileGenerator from walberla.codegen import Sweep -from walberla.codegen.boundaries import SimpleHbbBoundary +from walberla.codegen.boundaries import GenericHBB from lbmpy import ( LBStencil, @@ -21,7 +21,8 @@ from lbmpy.macroscopic_value_kernels import macroscopic_values_setter stencil = LBStencil(Stencil.D3Q19) dim = stencil.D f, f_tmp, rho, u = ps.fields( - f"f({stencil.Q}), f_tmp({stencil.Q}), rho(1), u({dim}): double[{dim}D]", layout="fzyx" + f"f({stencil.Q}), f_tmp({stencil.Q}), rho(1), u({dim}): double[{dim}D]", + layout="fzyx", ) omega = sp.Symbol("omega") force = sp.symbols(f"F_:{dim}") @@ -46,8 +47,9 @@ with SourceFileGenerator() as sfg: lbm_opt = LBMOptimisation(symbolic_field=f, symbolic_temporary_field=f_tmp) - gen_config = ps.CreateKernelConfig() - gen_config.target = ps.Target.CPU + target = ps.Target.GenericCPU + + gen_config = ps.CreateKernelConfig(target=target) gen_config.cpu.openmp.enable = True lb_update = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) @@ -62,4 +64,4 @@ with SourceFileGenerator() as sfg: sfg.generate(lb_init_sweep) # No-Slip Wall - sfg.generate(SimpleHbbBoundary(NoSlip(), lb_method, f)) + sfg.generate(GenericHBB(NoSlip(), lb_method, f, target=target)) diff --git a/user_manual/examples/FreeSlipBubble/LbmAlgorithms.py b/user_manual/examples/FreeSlipBubble/LbmAlgorithms.py index dddace06a9f0e447924b00da023f52958a7a2bfc..a7f5521a54facc081498c55e4ca72aeb433bbe0f 100644 --- a/user_manual/examples/FreeSlipBubble/LbmAlgorithms.py +++ b/user_manual/examples/FreeSlipBubble/LbmAlgorithms.py @@ -1,7 +1,7 @@ import sympy as sp from pystencilssfg import SourceFileGenerator -from pystencils import fields, Field +from pystencils import fields, Field, Target, CreateKernelConfig from lbmpy import LBStencil, Stencil, LBMConfig, LBMOptimisation, create_lb_update_rule from lbmpy.macroscopic_value_kernels import macroscopic_values_setter @@ -28,11 +28,14 @@ with SourceFileGenerator() as sfg: symbolic_temporary_field=pdfs_tmp, ) + target = Target.GenericCPU + cfg = CreateKernelConfig(target=target) + lb_update = create_lb_update_rule(lbm_config=lbm_config, lbm_optimisation=lbm_opt) lb_method = lb_update.method assert lb_update is not None - lb_update_sweep = Sweep("LbStreamCollide", lb_update) + lb_update_sweep = Sweep("LbStreamCollide", lb_update, cfg) lb_update_sweep.swap_fields(pdfs, pdfs_tmp) sfg.generate(lb_update_sweep) @@ -42,7 +45,7 @@ with SourceFileGenerator() as sfg: velocity=sp.symbols(f"velocity_:{d}"), pdfs=pdfs, ) - lb_init_sweep = Sweep("LbInit", lb_init) + lb_init_sweep = Sweep("LbInit", lb_init, cfg) sfg.generate(lb_init_sweep) # begin irregular-freeslip @@ -53,6 +56,7 @@ with SourceFileGenerator() as sfg: lb_method, pdfs, wall_normal=FreeSlip.IRREGULAR, + target=target ) sfg.generate(freeslip)