diff --git a/lib/walberla/experimental/Sweep.hpp b/lib/walberla/experimental/Sweep.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d9f475324050ee5ee54ac22862305af7e520b632 --- /dev/null +++ b/lib/walberla/experimental/Sweep.hpp @@ -0,0 +1,4 @@ +#pragma once + +#include "./sweep/DomainSlices.hpp" +#include "./sweep/SparseIndexList.hpp" diff --git a/lib/walberla/experimental/sweep/DomainSlices.hpp b/lib/walberla/experimental/sweep/DomainSlices.hpp new file mode 100644 index 0000000000000000000000000000000000000000..450316dd1c6e7bc883a61f130d46b2d1c981bd4f --- /dev/null +++ b/lib/walberla/experimental/sweep/DomainSlices.hpp @@ -0,0 +1,81 @@ +#pragma once + +#include "blockforest/StructuredBlockForest.h" + +#include "core/cell/CellInterval.h" + +#include "domain_decomposition/IBlock.h" + +#include "stencil/Directions.h" + +namespace walberla::experimental::sweep +{ + +template< typename T > +concept CellIntervalSweep = requires(T obj, IBlock* block, const CellInterval& ci) { + { obj.runOnCellInterval(block, ci) } -> std::same_as< void >; +}; + +namespace detail +{ +template< stencil::Direction BorderDir > +struct BorderSweepSlice +{ + shared_ptr< StructuredBlockForest > blocks; + cell_idx_t offset; + + CellInterval ci(); + bool isBlockAtBorder(IBlock& b); +}; + +template<> +CellInterval BorderSweepSlice< stencil::Direction::T >::ci() +{ + return { { 0, 0, cell_idx_c(blocks->getNumberOfZCellsPerBlock()) - (offset + 1) }, + { cell_idx_c(blocks->getNumberOfXCellsPerBlock()) - 1, // + cell_idx_c(blocks->getNumberOfYCellsPerBlock()) - 1, // + cell_idx_c(blocks->getNumberOfZCellsPerBlock()) - (offset + 1) } }; +}; + +template<> +bool BorderSweepSlice< stencil::Direction::B >::isBlockAtBorder(IBlock& b) +{ + return blocks->atDomainZMinBorder(b); +} + +template<> +CellInterval BorderSweepSlice< stencil::Direction::B >::ci() +{ + return { { 0, 0, offset }, + { cell_idx_c(blocks->getNumberOfXCellsPerBlock()) - 1, // + cell_idx_c(blocks->getNumberOfYCellsPerBlock()) - 1, // + offset } }; +}; + +template<> +bool BorderSweepSlice< stencil::Direction::T >::isBlockAtBorder(IBlock& b) +{ + return blocks->atDomainZMaxBorder(b); +} +} // namespace detail + +template< stencil::Direction BorderDir, CellIntervalSweep Sweep > +class BorderSweep +{ + private: + Sweep sweep_; + detail::BorderSweepSlice< BorderDir > slice_; + CellInterval ci_; + + public: + BorderSweep(const shared_ptr< StructuredBlockForest >& blocks, const Sweep& sweep, cell_idx_t offset = 0) + : sweep_{ sweep }, slice_{ blocks, offset }, ci_{ slice_.ci() } + {} + + void operator()(IBlock* block) + { + if (slice_.isBlockAtBorder(*block)) { sweep_.runOnCellInterval(block, ci_); } + } +}; + +} // namespace walberla::experimental::sweep \ No newline at end of file