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)};
169 if (m_pending_changes) {
171 fillFromFlagField(
block);
173 m_pending_changes =
false;
178 void fillFromFlagField(IBlock &
block) {
193 auto inner = flagField->xyzSize();
194 inner.expand(cell_idx_t(-1));
196 indexVectorAll.clear();
197 indexVectorInner.clear();
198 indexVectorOuter.clear();
200 auto flagWithGLayers = flagField->xyzSizeWithGhostLayer();
201 for (
auto it = flagField->beginWithGhostLayerXYZ(); it != flagField->end();
203 if (!isFlagSet(it, boundaryFlag))
206 if (flagWithGLayers.contains(it.x(), it.y(), it.z()) &&
207 isFlagSet(it.neighbor(0, 0, 0, 0), domainFlag)) {
208 auto element =
IndexInfo(it.x(), it.y(), it.z());
209 indexVectorAll.push_back(element);
210 if (inner.contains(it.x(), it.y(), it.z())) {
211 indexVectorInner.push_back(element);
213 indexVectorOuter.push_back(element);
218 indexVectors->syncGPU();