8#include <kernel/geometry/conformal_mesh.hpp>
9#include <kernel/geometry/mesh_part.hpp>
10#include <kernel/adjacency/graph.hpp>
21 template<
typename Shape_,
int shape_dim_ = Shape_::dimension>
22 class PatchInvMapWrapper;
24 template<
typename Shape_>
25 class PatchHaloSplitPart;
32 template<
typename Mesh_>
43 template<
typename Shape_,
int num_coords_,
typename Coord_>
45 public Geometry::Factory<Geometry::MeshPart<Geometry::ConformalMesh<Shape_, num_coords_, Coord_>>>
51 static constexpr int shape_dim = ShapeType::dimension;
58 typedef Intern::PatchHaloSplitPart<ShapeType> SplitHaloType;
82 _base_mesh(base_mesh),
83 _patch_mesh_part(patch_mesh_part),
84 _patch_inv_map(std::size_t(shape_dim+1)),
85 _isect_halo_idx(std::size_t(shape_dim+1))
88 _patch_inv_map.resize(std::size_t(shape_dim+1));
89 for(
int dim(0); dim <= shape_dim; ++dim)
94 Intern::PatchInvMapWrapper<ShapeType>::build(_patch_inv_map, patch_mesh_part.get_target_set_holder());
113 auto sh = std::make_shared<SplitHaloType>();
116 if(!sh->split(_patch_inv_map, halo.get_target_set_holder()))
117 return std::size_t(0);
120 return _split_halos.emplace(halo_rank, sh).first->second->size();
137 const auto it = _split_halos.find(halo_rank);
138 XASSERT(it != _split_halos.end());
140 std::vector<Index> buffer;
141 it->second->serialize(buffer, child_rank);
164 for(
auto& x : _isect_halo_idx)
167 const auto it = _split_halos.find(halo_rank);
168 if(it == _split_halos.end())
172 return it->second->intersect(_isect_halo_idx, buffer, std::size_t(buffer_offset));
179 virtual Index get_num_entities(
int dim)
override
181 return Index(_isect_halo_idx.at(std::size_t(dim)).size());
184 virtual void fill_attribute_sets(
typename MeshPartType::AttributeSetContainer& )
override
189 virtual void fill_index_sets(std::unique_ptr<typename MeshPartType::IndexSetHolderType>& index_set_holder)
override
191 XASSERT(index_set_holder.get() ==
nullptr);
195 virtual void fill_target_sets(
typename MeshPartType::TargetSetHolderType& target_set_holder)
override
197 Intern::PatchInvMapWrapper<ShapeType>::fill(target_set_holder, _isect_halo_idx);
208 static void build(std::vector<Index>& pim,
const TargetSet& ts)
210 for(Index i(0); i < ts.get_num_entities(); ++i)
214 static bool split(std::vector<Index>& shi, std::vector<Index>& spi,
const std::vector<Index>& pim,
const TargetSet& ts)
216 shi.reserve(ts.get_num_entities());
217 spi.reserve(ts.get_num_entities());
219 for(Index i(0); i < ts.get_num_entities(); ++i)
221 const Index patch_idx = pim[ts[i]];
222 if(patch_idx != ~
Index(0))
224 spi.push_back(patch_idx);
232 static void fill(TargetSet& trg,
const std::vector<Index>& idx)
234 const Index n = trg.get_num_entities();
236 for(Index i(0); i < n; ++i)
237 trg[i] = idx[std::size_t(i)];
241 template<
typename Shape_,
int shape_dim_>
242 class PatchInvMapWrapper
245 static_assert(shape_dim_ > 0,
"invalid shape dimension");
246 static void build(std::vector<std::vector<Index>>& pim,
const TargetSetHolder<Shape_>& tsh)
248 PatchInvMapWrapper<Shape_, shape_dim_-1>::build(pim, tsh);
249 PatchInvMap::build(pim.at(std::size_t(shape_dim_)), tsh.template get_target_set<shape_dim_>());
253 std::vector<std::vector<Index>>& shi, std::vector<std::vector<Index>>& spi,
254 const std::vector<std::vector<Index>>& pim,
const TargetSetHolder<Shape_>& tsh)
256 bool have = PatchInvMapWrapper<Shape_, shape_dim_-1>::split(shi, spi, pim, tsh);
257 const std::size_t k = std::size_t(shape_dim_);
258 return PatchInvMap::split(shi.at(k), spi.at(k), pim.at(k), tsh.template get_target_set<shape_dim_>()) || have;
261 static void fill(TargetSetHolder<Shape_>& tsh,
const std::vector<std::vector<Index>>& idx)
263 PatchInvMapWrapper<Shape_, shape_dim_-1>::fill(tsh, idx);
264 PatchInvMap::fill(tsh.template get_target_set<shape_dim_>(), idx.at(std::size_t(shape_dim_)));
268 template<
typename Shape_>
269 class PatchInvMapWrapper<Shape_, 0>
272 static void build(std::vector<std::vector<Index>>& pim,
const TargetSetHolder<Shape_>& tsh)
274 PatchInvMap::build(pim.at(std::size_t(0)), tsh.template get_target_set<0>());
277 std::vector<std::vector<Index>>& shi, std::vector<std::vector<Index>>& spi,
278 const std::vector<std::vector<Index>>& pim,
const TargetSetHolder<Shape_>& tsh)
280 const std::size_t k = std::size_t(0);
281 return PatchInvMap::split(shi.at(k), spi.at(k), pim.at(k), tsh.template get_target_set<0>());
284 static void fill(TargetSetHolder<Shape_>& tsh,
const std::vector<std::vector<Index>>& idx)
286 PatchInvMap::fill(tsh.template get_target_set<0>(), idx.at(std::size_t(0)));
290 template<
typename Shape_>
291 class PatchHaloSplitPart
294 static constexpr int shape_dim = Shape_::dimension;
297 std::vector<std::vector<Index>> _halo_idx;
299 std::vector<std::vector<Index>> _patch_idx;
302 explicit PatchHaloSplitPart()
304 std::size_t sdim = std::size_t(shape_dim+1);
305 _halo_idx.resize(sdim);
306 _patch_idx.resize(sdim);
309 bool split(
const std::vector<std::vector<Index>>& pim,
const TargetSetHolder<Shape_>& tsh)
311 return PatchInvMapWrapper<Shape_>::split(_halo_idx, _patch_idx, pim, tsh);
314 std::size_t size()
const
316 std::size_t s = std::size_t(0);
317 for(
const auto& x : _halo_idx)
321 return s == std::size_t(0) ? s : ++s + _halo_idx.size();
324 void serialize(std::vector<Index>& buffer,
int child_rank)
326 const std::size_t s = this->size();
327 if(this->size() == std::size_t(0))
330 if(buffer.capacity() < buffer.size() + s)
331 buffer.reserve(buffer.size() + s);
333 buffer.push_back(
Index(child_rank));
335 for(std::size_t i(0); i < _halo_idx.size(); ++i)
336 buffer.push_back(
Index(_halo_idx.at(i).size()));
338 for(std::size_t i(0); i < _halo_idx.size(); ++i)
340 const std::vector<Index>& v = _halo_idx.at(i);
341 for(std::size_t j(0); j < v.size(); ++j)
342 buffer.push_back(v[j]);
346 bool intersect(std::vector<std::vector<Index>>& isect,
const std::vector<Index>& other,
const std::size_t offset)
const
349 std::size_t off = offset + std::size_t(shape_dim+2);
354 for(std::size_t i(0); i <= std::size_t(shape_dim); ++i)
357 const std::size_t n_1 = _halo_idx.at(i).size();
358 const std::size_t n_2 =
other.at(offset+i+1u);
361 const std::size_t n_min = Math::min(n_1, n_2);
362 if(n_min == std::size_t(0))
369 const Index* idx_1 = _halo_idx.at(i).data();
371 const Index* idx_p = _patch_idx.at(i).data();
374 std::vector<Index>& idx = isect.at(i);
376 for(std::size_t j_1(0), j_2(0); (j_1 < n_1) && (j_2 < n_2); )
378 if(idx_1[j_1] < idx_2[j_2])
380 else if(idx_1[j_1] > idx_2[j_2])
385 idx.push_back(idx_p[j_1]);
#define XASSERT(expr)
Assertion macro definition.
Mesh Factory class template.
Class template for partial meshes.
Base-Mesh Patch Halo splitter.
@ other
generic/other permutation strategy
std::uint64_t Index
Index data type.