51 BlockDataID m_flagfield_id;
52 BlockDataID m_indexvector_id;
53 bool m_pending_changes;
62#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
65 detail::ReactionKernelIndexedSelector::KernelTrait<>::
66 ReactionKernelIndexed::IndexVectors,
67 detail::ReactionKernelIndexedSelector::KernelTraitGPU<>::
68 ReactionKernelIndexedGPU::IndexVectors>::type;
71 detail::ReactionKernelIndexedSelector::KernelTrait<>::
72 ReactionKernelIndexed::IndexInfo,
73 detail::ReactionKernelIndexedSelector::KernelTraitGPU<>::
74 ReactionKernelIndexedGPU::IndexInfo>::type;
76 using IndexVectors = detail::ReactionKernelIndexedSelector::KernelTrait<>::
77 ReactionKernelIndexed::IndexVectors;
78 using IndexInfo = detail::ReactionKernelIndexedSelector::KernelTrait<>::
79 ReactionKernelIndexed::IndexInfo;
83 auto get_flag_field_and_flag(IBlock *
block, BlockDataID
const &flagfield_id) {
84 auto const flag_field =
85 block->template uncheckedFastGetData<FlagField>(flagfield_id);
86 auto const boundary_flag = flag_field->getFlag(
Boundary_flag);
87 return std::make_tuple(flag_field, boundary_flag);
94 m_pending_changes(false) {
95 m_flagfield_id = field::addFlagFieldToStorage<FlagField>(
99 auto createIdxVector = [](IBlock *
const, StructuredBlockStorage *
const) {
104 ->template addStructuredBlockData<IndexVectors>(
105 createIdxVector,
"IndexField");
108 auto flag_field =
block.template getData<FlagField>(m_flagfield_id);
113 auto domain_flag = flag_field->getFlag(
Domain_flag);
115 for (
auto it = flag_field->begin(); it != flag_field->end(); ++it) {
116 flag_field->addFlag(it.x(), it.y(), it.z(), domain_flag);
117 flag_field->removeFlag(it.x(), it.y(), it.z(), boundary_flag);
129 std::function<void(IBlock *)> kernel;
131 kernel = detail::ReactionKernelIndexedSelector::get_kernel(
134#if defined(__CUDACC__) and defined(WALBERLA_BUILD_WITH_CUDA)
135 kernel = detail::ReactionKernelIndexedSelector::get_kernel_gpu(
145 bool is_boundary)
override {
147 auto const [flag_field, boundary_flag] =
148 get_flag_field_and_flag(bc->block, m_flagfield_id);
150 flag_field->addFlag(bc->cell, boundary_flag);
152 flag_field->removeFlag(bc->cell, boundary_flag);
154 m_pending_changes =
true;
158 [[nodiscard]] std::optional<bool>
161 auto const [flag_field, boundary_flag] =
162 get_flag_field_and_flag(bc->block, m_flagfield_id);
163 return {flag_field->isFlagSet(bc->cell, boundary_flag)};
168 [[nodiscard]] std::vector<int>
171 std::vector<int> out;
173 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
174 out.assign(ci->numCells(), 0);
175 for (
auto const &
block : *lattice.get_blocks()) {
176 auto const block_offset = lattice.get_block_corner(
block,
true);
178 lattice, lower_corner, upper_corner, block_offset,
block)) {
179 auto const *flag_field =
180 block.template getData<FlagField>(m_flagfield_id);
181 auto const boundary_flag = flag_field->getFlag(
Boundary_flag);
183 *bci, *ci, block_offset, lower_corner,
184 [&out, flag_field, boundary_flag,
185 &block_offset](
unsigned const,
unsigned const local_index,
187 auto const cell =
to_cell(node - block_offset);
189 flag_field->isFlagSet(cell, boundary_flag) ? 1 : 0;
199 std::vector<int>
const &is_boundary)
override {
201 if (
auto const ci =
get_interval(lattice, lower_corner, upper_corner)) {
202 for (
auto &
block : *lattice.get_blocks()) {
203 auto const block_offset = lattice.get_block_corner(
block,
true);
205 lattice, lower_corner, upper_corner, block_offset,
block)) {
206 auto *flag_field =
block.template getData<FlagField>(m_flagfield_id);
207 auto const boundary_flag = flag_field->getFlag(
Boundary_flag);
209 [flag_field, boundary_flag, &is_boundary,
210 &block_offset](
unsigned const,
211 unsigned const local_index,
213 auto const cell =
to_cell(node - block_offset);
214 if (is_boundary[local_index] != 0) {
215 flag_field->addFlag(cell, boundary_flag);
217 flag_field->removeFlag(cell, boundary_flag);
222 m_pending_changes =
true;
229 if (m_pending_changes) {
231 fillFromFlagField(
block);
233 m_pending_changes =
false;
238 void fillFromFlagField(IBlock &
block) {
253 auto inner = flagField->xyzSize();
254 inner.expand(cell_idx_t(-1));
256 indexVectorAll.clear();
257 indexVectorInner.clear();
258 indexVectorOuter.clear();
260 auto flagWithGLayers = flagField->xyzSizeWithGhostLayer();
261 for (
auto it = flagField->beginWithGhostLayerXYZ(); it != flagField->end();
263 if (!isFlagSet(it, boundaryFlag))
266 if (flagWithGLayers.contains(it.x(), it.y(), it.z()) &&
267 isFlagSet(it.neighbor(0, 0, 0, 0), domainFlag)) {
268 auto element =
IndexInfo(it.x(), it.y(), it.z());
269 indexVectorAll.push_back(element);
270 if (inner.contains(it.x(), it.y(), it.z())) {
271 indexVectorInner.push_back(element);
273 indexVectorOuter.push_back(element);
278 indexVectors->syncGPU();
void copy_block_buffer(CellInterval const &bci, CellInterval const &ci, Utils::Vector3i const &block_offset, Utils::Vector3i const &lower_corner, auto &&kernel)
Synchronize data between a sliced block and a container.
std::optional< walberla::cell::CellInterval > get_block_interval(::LatticeWalberla const &lattice, Utils::Vector3i const &lower_corner, Utils::Vector3i const &upper_corner, Utils::Vector3i const &block_offset, IBlock const &block)