diff --git a/include/sfg/IrregularFreeSlip.hpp b/include/sfg/IrregularFreeSlip.hpp index 3409d630bed0d106c2be551e9ebfbcd403f9a883..c887b8e7bd55d437b4a0d83160c47b7fe66682a7 100644 --- a/include/sfg/IrregularFreeSlip.hpp +++ b/include/sfg/IrregularFreeSlip.hpp @@ -20,23 +20,23 @@ namespace walberla::sfg int32_t y; int32_t z; int32_t dir; - int32_t source_x; - int32_t source_y; - int32_t source_z; + int32_t source_offset_x; + int32_t source_offset_y; + int32_t source_offset_z; int32_t source_dir; IrregularFreeSlipLinkInfo( walberla::Cell fluidCell, walberla::stencil::Direction linkDir, walberla::Cell sourceCell, walberla::stencil::Direction sourceDir) : x{fluidCell.x()}, y{fluidCell.y()}, z{fluidCell.z()}, - dir{int32_t(linkDir)}, source_x{sourceCell.x()}, - source_y{sourceCell.y()}, source_z{sourceCell.z()}, + dir{int32_t(linkDir)}, source_offset_x{sourceCell.x() - fluidCell.x()}, + source_offset_y{sourceCell.y() - fluidCell.y()}, source_offset_z{sourceCell.z() - fluidCell.z()}, source_dir{int32_t(sourceDir)} {} bool operator==(const IrregularFreeSlipLinkInfo &other) const { - return std::tie(x, y, z, dir, source_x, source_y, source_z, source_dir) == - std::tie(other.x, other.y, other.z, other.dir, other.source_x, - other.source_y, other.source_z, other.source_dir); + return std::tie(x, y, z, dir, source_offset_x, source_offset_y, source_offset_z, source_dir) == + std::tie(other.x, other.y, other.z, other.dir, other.source_offset_x, + other.source_offset_y, other.source_offset_z, other.source_dir); } }; @@ -62,8 +62,8 @@ namespace walberla::sfg for (auto &block : sbfs_) { FlagField_T *flagField = block.getData<FlagField_T>(flagFieldID_); - flag_t boundaryFlag { flagField->getFlag(boundaryFlagUID_) }; - flag_t fluidFlag { flagField->getFlag(fluidFlagUID_) }; + flag_t boundaryFlag{flagField->getFlag(boundaryFlagUID_)}; + flag_t fluidFlag{flagField->getFlag(fluidFlagUID_)}; auto &idxVector = indexList.get(block); @@ -93,7 +93,7 @@ namespace walberla::sfg private: IrregularFreeSlipLinkInfo createLink(FlagField_T *flagField, const Cell &fluidCell, const stencil::Direction dir) { - const flag_t fluidFlag { flagField->getFlag(fluidFlagUID_) }; + const flag_t fluidFlag{flagField->getFlag(fluidFlagUID_)}; const Cell wallCell{fluidCell + dir}; // inverse direction of 'dir' as lattice vector @@ -162,7 +162,7 @@ namespace walberla::sfg template <typename FlagField_T> auto fromFlagField(BlockDataID flagFieldID, field::FlagUID boundaryFlagUID, field::FlagUID fluidFlagUID) { - detail::FreeSlipLinksFromFlagField< typename Impl::Stencil, FlagField_T > linksFromFlagField{ *blocks_, flagFieldID, boundaryFlagUID, fluidFlagUID}; + detail::FreeSlipLinksFromFlagField<typename Impl::Stencil, FlagField_T> linksFromFlagField{*blocks_, flagFieldID, boundaryFlagUID, fluidFlagUID}; auto indexVector = linksFromFlagField.collectLinks(); return impl().irregularFromIndexVector(indexVector); } @@ -172,12 +172,14 @@ namespace walberla::sfg BlockDataID pdfFieldID_; private: - Impl & impl() { - return *static_cast< Impl * >(this); + Impl &impl() + { + return *static_cast<Impl *>(this); } - const Impl & impl() const { - return *static_cast< const Impl * >(this); + const Impl &impl() const + { + return *static_cast<const Impl *>(this); } }; } diff --git a/src/sfg_walberla/boundaries/__init__.py b/src/sfg_walberla/boundaries/__init__.py index 716bcb0d762195ed032c7dc3698dd71d7e3ecb29..baeed122b07f2f2e9f07e36b6d63c5392688134f 100644 --- a/src/sfg_walberla/boundaries/__init__.py +++ b/src/sfg_walberla/boundaries/__init__.py @@ -1,4 +1,4 @@ from .hbb import SimpleHbbBoundary -from .freeslip import FreeSlip, IRREGULAR +from .freeslip import FreeSlip -__all__ = ["SimpleHbbBoundary", "FreeSlip", "IRREGULAR"] +__all__ = ["SimpleHbbBoundary", "FreeSlip"] diff --git a/src/sfg_walberla/boundaries/freeslip.py b/src/sfg_walberla/boundaries/freeslip.py index 2f2b8959a6c9f87c8199a265fe6c67dae113b9d3..863d49eb13c812721d96b5541d14654f7247888e 100644 --- a/src/sfg_walberla/boundaries/freeslip.py +++ b/src/sfg_walberla/boundaries/freeslip.py @@ -12,7 +12,7 @@ from .boundary_utils import WalberlaLbmBoundary from ..sweep import Sweep from ..api import SparseIndexList -__all__ = ["IRREGULAR", "FreeSlip"] +__all__ = ["FreeSlip"] class _IrregularSentinel: @@ -20,12 +20,11 @@ class _IrregularSentinel: return "IRREGULAR" -IRREGULAR = _IrregularSentinel() - - class FreeSlip(CustomGenerator): """Free-Slip boundary condition""" + IRREGULAR = _IrregularSentinel() + def __init__( self, name: str, @@ -39,7 +38,7 @@ class FreeSlip(CustomGenerator): self._wall_normal = wall_normal def generate(self, sfg: SfgComposer) -> None: - if self._wall_normal == IRREGULAR: + if self._wall_normal == self.IRREGULAR: self._generate_irregular(sfg) else: self._generate_regular(sfg) @@ -109,9 +108,9 @@ class WalberlaIrregularFreeSlip(LbBoundary, WalberlaLbmBoundary): ("y", BoundaryIndexType), ("z", BoundaryIndexType), ("dir", BoundaryIndexType), - ("source_x", BoundaryIndexType), - ("source_y", BoundaryIndexType), - ("source_z", BoundaryIndexType), + ("source_offset_x", BoundaryIndexType), + ("source_offset_y", BoundaryIndexType), + ("source_offset_z", BoundaryIndexType), ("source_dir", BoundaryIndexType), ), "walberla::sfg::IrregularFreeSlipLinkInfo", @@ -121,9 +120,9 @@ class WalberlaIrregularFreeSlip(LbBoundary, WalberlaLbmBoundary): self, f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, force_vector ): source_cell = ( - index_field("source_x"), - index_field("source_y"), - index_field("source_z"), + index_field("source_offset_x"), + index_field("source_offset_y"), + index_field("source_offset_z"), ) source_dir = index_field("source_dir") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cff7ae0de942c8d0e49d56ea8d6a80f977818c54..f6e52227b3c49260f6329d25dfa096a9e3e3dac1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,3 +19,5 @@ add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/sfg-walberla) # Test Directories include(CTest) + +add_subdirectory( FreeSlip ) diff --git a/tests/FreeSlip/CMakeLists.txt b/tests/FreeSlip/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..661ef3c7d06ef4512b754d2aa2614cc313f12430 --- /dev/null +++ b/tests/FreeSlip/CMakeLists.txt @@ -0,0 +1,4 @@ +add_executable( TestIrregularFreeSlip TestIrregularFreeSlip.cpp ) +walberla_generate_sources( TestIrregularFreeSlip SCRIPTS IrregularFreeSlip.py ) +target_link_libraries( TestIrregularFreeSlip core blockforest field geometry sfg_walberla ) +add_test( NAME TestIrregularFreeSlip COMMAND TestIrregularFreeSlip ) diff --git a/tests/FreeSlip/IrregularFreeSlip.py b/tests/FreeSlip/IrregularFreeSlip.py new file mode 100644 index 0000000000000000000000000000000000000000..4a5b5cdcccb7fbc580b69827a8aa315f5b604dfe --- /dev/null +++ b/tests/FreeSlip/IrregularFreeSlip.py @@ -0,0 +1,22 @@ +from pystencilssfg import SourceFileGenerator +from sfg_walberla.boundaries import FreeSlip +from lbmpy import LBStencil, Stencil, LBMConfig, create_lb_method +from pystencils import fields, Field + +with SourceFileGenerator() as sfg: + sfg.namespace("gen") + + stencil = LBStencil(Stencil.D3Q19) + d, q = stencil.D, stencil.Q + f: Field + f = fields(f"f({q}): double[{d}D]", layout="fzyx") # type: ignore + + stencil_name = stencil.name + sfg.include(f"stencil/{stencil_name}.h") + sfg.code(f"using LbStencil = walberla::stencil::{stencil_name};") + + lbm_config = LBMConfig(stencil=stencil) + lb_method = create_lb_method(lbm_config) + + bc = FreeSlip("FreeSlip", lb_method, f, wall_normal=FreeSlip.IRREGULAR) + sfg.generate(bc) diff --git a/tests/FreeSlip/TestIrregularFreeSlip.cpp b/tests/FreeSlip/TestIrregularFreeSlip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..68e4ae927e91caafa7693f0a30a2b2ed40f5ef64 --- /dev/null +++ b/tests/FreeSlip/TestIrregularFreeSlip.cpp @@ -0,0 +1,78 @@ + +#include "core/all.h" +#include "blockforest/all.h" +#include "field/all.h" +#include "geometry/all.h" + +#include <array> + +#include "gen/IrregularFreeSlip.hpp" + +namespace TestIrregularFreeSlip +{ + using namespace walberla; + + using PdfField_T = field::GhostLayerField<real_t, gen::LbStencil::Q>; + using FlagField_T = FlagField<uint8_t>; + + void run(int argc, char **argv) + { + Environment env{argc, argv}; + + AABB domainAabb{0., 0., 0., 1., 1., 1.}; + std::array<uint_t, 3> blocks{1, 1, 1}; + std::array<uint_t, 3> cpb{32, 32, 32}; + + auto sbfs = blockforest::createUniformBlockGrid( + domainAabb, + blocks[0], blocks[1], blocks[2], + cpb[0], cpb[1], cpb[2]); + + BlockDataID pdfsId = field::addToStorage<PdfField_T>(sbfs, "f", real_c(0.0)); + + const BlockDataID flagFieldId = field::addFlagFieldToStorage<FlagField_T>(sbfs, "flagField"); + const FlagUID fluidFlagUid{"Fluid"}; + const FlagUID freeSlipFlagUID{"FreeSlip"}; + + const CellInterval allCells{{0, 0, 0}, {sbfs->getNumberOfXCellsPerBlock() - 1, sbfs->getNumberOfYCellsPerBlock() - 1, sbfs->getNumberOfZCellsPerBlock() - 1}}; + const Vector3<real_t> sphereCenter{16., 16., 16.}; + const real_t sphereRadius{8.}; + + for (auto &block : *sbfs) + { + FlagField_T &flagField = *block.getData<FlagField_T>(flagFieldId); + const uint8_t freeSlipFlag{flagField.getOrRegisterFlag(freeSlipFlagUID)}; + + PdfField_T &pdfField = *block.getData<PdfField_T>(pdfsId); + + for (Cell c : allCells) + { + Cell globalCell{c}; + sbfs->transformBlockLocalToGlobalCell(globalCell, block); + Vector3<real_t> cellCenter{sbfs->getCellCenter(globalCell)}; + + if ((cellCenter - sphereCenter).sqrLength() < sphereRadius * sphereRadius) + { + flagField.addFlag(c, freeSlipFlag); + for (uint_t q = 0; q < 19; ++q) + { + pdfField.get(c, q) = NAN; + } + } + } + } + + geometry::setNonBoundaryCellsToDomain<FlagField_T>(*sbfs, flagFieldId, fluidFlagUid); + + gen::FreeSlip freeSlip{gen::FreeSlipFactory(sbfs, pdfsId).fromFlagField<FlagField_T>(flagFieldId, freeSlipFlagUID, fluidFlagUid)}; + + for(auto& block: *sbfs){ + freeSlip( &block ); + } + } +} + +int main(int argc, char **argv) +{ + TestIrregularFreeSlip::run(argc, argv); +}