50 BlockDataID m_flagfield_id;
51 BlockDataID m_indexvector_id;
52 bool m_pending_changes;
61#if defined(__CUDACC__)
64 detail::ReactionKernelIndexedSelector::KernelTrait<>::
65 ReactionKernelIndexed::IndexVectors,
66 detail::ReactionKernelIndexedSelector::KernelTraitGPU<>::
67 ReactionKernelIndexedGPU::IndexVectors>::type;
70 detail::ReactionKernelIndexedSelector::KernelTrait<>::
71 ReactionKernelIndexed::IndexInfo,
72 detail::ReactionKernelIndexedSelector::KernelTraitGPU<>::
73 ReactionKernelIndexedGPU::IndexInfo>::type;
75 using IndexVectors = detail::ReactionKernelIndexedSelector::KernelTrait<>::
76 ReactionKernelIndexed::IndexVectors;
77 using IndexInfo = detail::ReactionKernelIndexedSelector::KernelTrait<>::
78 ReactionKernelIndexed::IndexInfo;
82 auto get_flag_field_and_flag(IBlock *
block, BlockDataID
const &flagfield_id) {
83 auto const flag_field =
84 block->template uncheckedFastGetData<FlagField>(flagfield_id);
85 auto const boundary_flag = flag_field->getFlag(
Boundary_flag);
86 return std::make_tuple(flag_field, boundary_flag);
93 m_pending_changes(false) {
94 m_flagfield_id = field::addFlagFieldToStorage<FlagField>(
98 auto createIdxVector = [](IBlock *
const, StructuredBlockStorage *
const) {
103 ->template addStructuredBlockData<IndexVectors>(
104 createIdxVector,
"IndexField");
107 auto flag_field =
block.template getData<FlagField>(m_flagfield_id);
112 auto domain_flag = flag_field->getFlag(
Domain_flag);
114 for (
auto it = flag_field->begin(); it != flag_field->end(); ++it) {
115 flag_field->addFlag(it.x(), it.y(), it.z(), domain_flag);
116 flag_field->removeFlag(it.x(), it.y(), it.z(), boundary_flag);
128 std::function<void(IBlock *)> kernel;
130 kernel = detail::ReactionKernelIndexedSelector::get_kernel(
133#if defined(__CUDACC__)
134 kernel = detail::ReactionKernelIndexedSelector::get_kernel_gpu(
144 bool is_boundary)
override {
146 auto const [flag_field, boundary_flag] =
147 get_flag_field_and_flag(bc->block, m_flagfield_id);
149 flag_field->addFlag(bc->cell, boundary_flag);
151 flag_field->removeFlag(bc->cell, boundary_flag);
153 m_pending_changes =
true;
157 [[nodiscard]] std::optional<bool>
160 auto const [flag_field, boundary_flag] =
161 get_flag_field_and_flag(bc->block, m_flagfield_id);
162 return {flag_field->isFlagSet(bc->cell, boundary_flag)};
168 if (m_pending_changes) {
170 fillFromFlagField(
block);
172 m_pending_changes =
false;
177 void fillFromFlagField(IBlock &
block) {
192 auto inner = flagField->xyzSize();
193 inner.expand(cell_idx_t(-1));
195 indexVectorAll.clear();
196 indexVectorInner.clear();
197 indexVectorOuter.clear();
199 auto flagWithGLayers = flagField->xyzSizeWithGhostLayer();
200 for (
auto it = flagField->beginWithGhostLayerXYZ(); it != flagField->end();
202 if (!isFlagSet(it, boundaryFlag))
205 if (flagWithGLayers.contains(it.x(), it.y(), it.z()) &&
206 isFlagSet(it.neighbor(0, 0, 0, 0), domainFlag)) {
207 auto element =
IndexInfo(it.x(), it.y(), it.z());
208 indexVectorAll.push_back(element);
209 if (inner.contains(it.x(), it.y(), it.z())) {
210 indexVectorInner.push_back(element);
212 indexVectorOuter.push_back(element);
217 indexVectors->syncGPU();