diff --git a/cmake/PrepareSFG.cmake b/cmake/PrepareSFG.cmake index 54ee564d846f00a668ecf0524907e517aac62379..9c042b24d82e0c8291c0a6745588e38dba862f34 100644 --- a/cmake/PrepareSFG.cmake +++ b/cmake/PrepareSFG.cmake @@ -28,7 +28,7 @@ if( WALBERLA_CODEGEN_USE_PRIVATE_VENV ) ) execute_process( - COMMAND ${_venv_python_exe} -m pip install ${sfg_walberla_SOURCE_DIR} + COMMAND ${_venv_python_exe} -m pip install -e ${sfg_walberla_SOURCE_DIR} OUTPUT_QUIET ) diff --git a/cmake/venv-reqs.txt b/cmake/venv-reqs.txt index f82e5aae7f4ca722991030c572bb2391d70096bc..97f53bbb590d9fd5e0fede0c74ca92b59014b804 100644 --- a/cmake/venv-reqs.txt +++ b/cmake/venv-reqs.txt @@ -4,5 +4,5 @@ git+https://i10git.cs.fau.de/pycodegen/pystencils.git@v2.0-dev # lbmpy: feature branch for pystencils-2.0 compatibility git+https://i10git.cs.fau.de/pycodegen/lbmpy.git@fhennig/pystencils2.0-compat -# pystencils-sfg: (development branch with updated CMake modules) -git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@fhennig/cmake-custom-python +# pystencils-sfg: (development branch with updated CMake modules and cpptypes) +git+https://i10git.cs.fau.de/pycodegen/pystencils-sfg.git@fhennig/devel diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 2325a59a150872cd039792735b23a8df59c7a71e..59c36c295de0103a5eb5657faee2ff1dfadc1fb4 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -14,4 +14,4 @@ FetchContent_MakeAvailable(walberla) add_subdirectory(${CMAKE_SOURCE_DIR}/.. ${CMAKE_BINARY_DIR}/sfg-walberla) add_subdirectory( GeneratorScriptBasics ) -add_subdirectory( FullyPeriodicAde ) +add_subdirectory( ForceDrivenChannel ) diff --git a/examples/ForceDrivenChannel/Channel.prm b/examples/ForceDrivenChannel/Channel.prm new file mode 100644 index 0000000000000000000000000000000000000000..36aa90daf3229784037bd6b99d89412df5a7f9f8 --- /dev/null +++ b/examples/ForceDrivenChannel/Channel.prm @@ -0,0 +1,23 @@ +DomainSetup +{ + blocks < 1, 1, 1 >; + cellsPerBlock < 4, 4, 32 >; + periodic < 1, 1, 0 >; +} + +Parameters +{ + omega 1.0; + force < 6.25e-5, 0, 0 >; + timesteps 5000; +} + +Boundaries { + Border { direction T; walldistance -1; flag NoSlip; } + Border { direction B; walldistance -1; flag NoSlip; } +} + +Output +{ + vtkWriteFrequency 100; +} \ No newline at end of file diff --git a/examples/ForceDrivenChannel/ForceDrivenChannel.cpp b/examples/ForceDrivenChannel/ForceDrivenChannel.cpp index 9b6bdc2ec2f03e639bbb4a5124ae710e2467741b..52238a70a2ebcb079d0f61257174e7aef82102bf 100644 --- a/examples/ForceDrivenChannel/ForceDrivenChannel.cpp +++ b/examples/ForceDrivenChannel/ForceDrivenChannel.cpp @@ -1,3 +1,145 @@ -int main(void) { - return 0; +#include "blockforest/all.h" +#include "blockforest/communication/UniformBufferedScheme.h" + +#include "core/all.h" + +#include "domain_decomposition/SharedSweep.h" + +#include "field/all.h" +#include "field/communication/PackInfo.h" +#include "field/communication/StencilRestrictedPackInfo.h" + +#include "geometry/InitBoundaryHandling.h" + +#include "stencil/all.h" + +#include "timeloop/all.h" + +#include "vtk/all.h" + +#include "gen/Ex_ForceDrivenChannel/LbmAlgorithms.hpp" + +namespace Ex_ForceDrivenChannel +{ + using namespace walberla; + using namespace blockforest; + + using std::make_unique; + using std::shared_ptr; + + using ScalarField_T = field::GhostLayerField<real_t, 1>; + using VectorField_T = field::GhostLayerField<real_t, 3>; + + using LbStencil = stencil::D3Q19; + using PdfField_T = field::GhostLayerField<real_t, LbStencil::Q>; + + using CommScheme = blockforest::communication::UniformBufferedScheme<LbStencil>; + using PdfsPackInfo = field::communication::StencilRestrictedPackInfo<PdfField_T, LbStencil>; + + using FlagField_T = FlagField<uint8_t>; + + void run(const shared_ptr<Config> &config) + { + auto blocks = createUniformBlockGridFromConfig(config); + + Config::BlockHandle simParams = config->getBlock("Parameters"); + const real_t omega{simParams.getParameter<real_t>("omega")}; + + const Vector3<real_t> force = simParams.getParameter<Vector3<real_t>>("force"); + + BlockDataID pdfsId = field::addToStorage<PdfField_T>(blocks, "pdfs", real_c(0.0), field::fzyx, 1); + BlockDataID rhoId = field::addToStorage<ScalarField_T>(blocks, "rho", real_c(1.0), field::fzyx, 0); + BlockDataID uId = field::addToStorage<VectorField_T>(blocks, "u", real_c(0.0), field::fzyx, 0); + + gen::LbInit lbInit{pdfsId, rhoId, uId, force}; + + for (auto &block : *blocks) + { + lbInit(&block); + } + + // Stream-Collide + + auto streamCollide = make_shared<gen::LbStreamCollide>(pdfsId, rhoId, uId, force, omega); + + // Communication Setup + + CommScheme comm{blocks}; + auto pdfsPackInfo = std::make_shared<PdfsPackInfo>(pdfsId); + comm.addPackInfo(pdfsPackInfo); + + // Boundary Conditions + + const BlockDataID flagFieldId = field::addFlagFieldToStorage<FlagField_T>(blocks, "flagField"); + const FlagUID fluidFlagUid{"Fluid"}; + const FlagUID noSlipFlagUid{"NoSlip"}; + + auto boundariesConfig = config->getBlock("Boundaries"); + if (boundariesConfig) + { + WALBERLA_LOG_INFO_ON_ROOT("Setting boundary conditions") + geometry::initBoundaryHandling<FlagField_T>(*blocks, flagFieldId, boundariesConfig); + } + + geometry::setNonBoundaryCellsToDomain<FlagField_T>(*blocks, flagFieldId, fluidFlagUid); + + 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); + + auto boundarySweep = [&](IBlock *block) + { + (*noSlip)(block); + }; + + // Timeloop + const uint_t numTimesteps{simParams.getParameter<uint_t>("timesteps")}; + SweepTimeloop loop{blocks->getBlockStorage(), numTimesteps}; + + loop.add() << Sweep(makeSharedSweep(streamCollide)); + loop.add() << Sweep(boundarySweep) << AfterFunction(comm); + + RemainingTimeLogger logger{numTimesteps}; + loop.addFuncAfterTimeStep(logger); + + // VTK Output + + Config::BlockHandle outputParams = config->getBlock("Output"); + + const uint_t vtkWriteFrequency = outputParams.getParameter<uint_t>("vtkWriteFrequency", 0); + if (vtkWriteFrequency > 0) + { + auto vtkOutput = vtk::createVTKOutput_BlockData(*blocks, "vtk", vtkWriteFrequency, 0, false, "vtk_out", + "simulation_step", false, true, true, false, 0); + + auto densityWriter = make_shared<field::VTKWriter<ScalarField_T, float32>>(rhoId, "density"); + vtkOutput->addCellDataWriter(densityWriter); + + auto velWriter = make_shared<field::VTKWriter<VectorField_T, float32>>(uId, "velocity"); + vtkOutput->addCellDataWriter(velWriter); + + const cell_idx_t xCells = cell_idx_c(blocks->getNumberOfXCells()); + const cell_idx_t yCells = cell_idx_c(blocks->getNumberOfYCells()); + const cell_idx_t zCells = cell_idx_c(blocks->getNumberOfZCells()); + + loop.addFuncAfterTimeStep(vtk::writeFiles(vtkOutput), "VTK Output"); + } + + // Run the Simulation + + WALBERLA_LOG_INFO_ON_ROOT("Commencing simulation with " << numTimesteps << " timesteps") + + loop.run(); + } +} + +int main(int argc, char **argv) +{ + walberla::Environment env{argc, argv}; + + Ex_ForceDrivenChannel::run(env.config()); + + return EXIT_SUCCESS; } diff --git a/examples/ForceDrivenChannel/LbmAlgorithms.py b/examples/ForceDrivenChannel/LbmAlgorithms.py index c27d3ee7d8e490de863ba5fff77d581b6b8f33e2..fe9b7c1c314090e88db71ee82afe01311e6983c4 100644 --- a/examples/ForceDrivenChannel/LbmAlgorithms.py +++ b/examples/ForceDrivenChannel/LbmAlgorithms.py @@ -2,8 +2,10 @@ import sympy as sp from pystencilssfg import SourceFileGenerator from sfg_walberla import Sweep +from sfg_walberla.boundaries import SimpleHbbBoundary + from pystencils import Target, fields -import pystencils.config as cfg +import pystencils.codegen.config as cfg from lbmpy import ( LBStencil, Stencil, @@ -14,6 +16,7 @@ from lbmpy import ( create_lb_update_rule, ) +from lbmpy.boundaries import NoSlip from lbmpy.macroscopic_value_kernels import macroscopic_values_setter stencil = LBStencil(Stencil.D3Q19) @@ -37,7 +40,7 @@ lbm_config = LBMConfig( lb_method = create_lb_method(lbm_config) with SourceFileGenerator() as sfg: - sfg.namespace("ForceDrivenChannel::gen") + sfg.namespace("Ex_ForceDrivenChannel::gen") sfg.include(f"stencil/{stencil.name}.h") sfg.code(f"using LbStencil = walberla::stencil::{stencil.name};") @@ -59,3 +62,5 @@ with SourceFileGenerator() as sfg: lb_init_sweep = Sweep("LbInit", lb_init, gen_config) sfg.generate(lb_init_sweep) + # No-Slip Wall + sfg.generate(SimpleHbbBoundary(NoSlip(), lb_method, f)) diff --git a/src/sfg_walberla/boundaries/hbb.py b/src/sfg_walberla/boundaries/hbb.py index 2a79cb70a0f6d4ed6d6f3fe8e38d87726a225132..2da0f1765def3493ae0c806c5a65d47f2c6f5ec2 100644 --- a/src/sfg_walberla/boundaries/hbb.py +++ b/src/sfg_walberla/boundaries/hbb.py @@ -211,7 +211,7 @@ def _create_lb_boundary_kernel( inv_dir = indexing.inverse_dir_symbol boundary_assignments = boundary_functor( - f_out, f_in, dir_symbol, inv_dir, lb_method, index_field + f_out, f_in, dir_symbol, inv_dir, lb_method, index_field, None # TODO: Fix force vector ) boundary_assignments = indexing.substitute_proxies(boundary_assignments)