49 BlockDataID m_flagfield_id;
50 BlockDataID m_indexvector_id;
51 bool m_pending_changes;
60 using IndexVectors = detail::ReactionKernelIndexedSelector::KernelTrait<>::
61 ReactionKernelIndexed::IndexVectors;
62 using IndexInfo = detail::ReactionKernelIndexedSelector::KernelTrait<>::
63 ReactionKernelIndexed::IndexInfo;
66 auto get_flag_field_and_flag(IBlock *
block, BlockDataID
const &flagfield_id) {
67 auto const flag_field =
68 block->template uncheckedFastGetData<FlagField>(flagfield_id);
69 auto const boundary_flag = flag_field->getFlag(
Boundary_flag);
70 return std::make_tuple(flag_field, boundary_flag);
77 m_pending_changes(false) {
78 m_flagfield_id = field::addFlagFieldToStorage<FlagField>(
82 auto createIdxVector = [](IBlock *
const, StructuredBlockStorage *
const) {
87 ->template addStructuredBlockData<IndexVectors>(
88 createIdxVector,
"IndexField");
91 auto flag_field =
block.template getData<FlagField>(m_flagfield_id);
96 auto domain_flag = flag_field->getFlag(
Domain_flag);
98 for (
auto it = flag_field->begin(); it != flag_field->end(); ++it) {
99 flag_field->addFlag(it.x(), it.y(), it.z(), domain_flag);
100 flag_field->removeFlag(it.x(), it.y(), it.z(), boundary_flag);
112 auto kernel = detail::ReactionKernelIndexedSelector::get_kernel(
120 bool is_boundary)
override {
122 auto const [flag_field, boundary_flag] =
123 get_flag_field_and_flag(bc->block, m_flagfield_id);
125 flag_field->addFlag(bc->cell, boundary_flag);
127 flag_field->removeFlag(bc->cell, boundary_flag);
129 m_pending_changes =
true;
133 [[nodiscard]] std::optional<bool>
136 auto const [flag_field, boundary_flag] =
137 get_flag_field_and_flag(bc->block, m_flagfield_id);
138 return {flag_field->isFlagSet(bc->cell, boundary_flag)};
144 if (m_pending_changes) {
146 fillFromFlagField(
block);
148 m_pending_changes =
false;
153 void fillFromFlagField(IBlock &
block) {
168 auto inner = flagField->xyzSize();
169 inner.expand(cell_idx_t(-1));
171 indexVectorAll.clear();
172 indexVectorInner.clear();
173 indexVectorOuter.clear();
175 auto flagWithGLayers = flagField->xyzSizeWithGhostLayer();
176 for (
auto it = flagField->beginWithGhostLayerXYZ(); it != flagField->end();
178 if (!isFlagSet(it, boundaryFlag))
181 if (flagWithGLayers.contains(it.x(), it.y(), it.z()) &&
182 isFlagSet(it.neighbor(0, 0, 0, 0), domainFlag)) {
183 auto element =
IndexInfo(it.x(), it.y(), it.z());
184 indexVectorAll.push_back(element);
185 if (inner.contains(it.x(), it.y(), it.z())) {
186 indexVectorInner.push_back(element);
188 indexVectorOuter.push_back(element);
193 indexVectors->syncGPU();