3#ifndef DUNE_MMESH_MISC_PARTITIONHELPER_HH
4#define DUNE_MMESH_MISC_PARTITIONHELPER_HH
14 static constexpr int dim = Grid::dimension;
15 using IdType =
typename Grid::IdType;
19 typename Grid::LeafIterator::Implementation::HostGridLeafIterator;
25 if constexpr (
dim == 2) {
26 leafBegin_ = grid().getHostGrid().finite_faces_begin();
27 leafEnd_ = grid().getHostGrid().finite_faces_end();
28 }
else if constexpr (
dim == 3) {
29 leafBegin_ = grid().getHostGrid().finite_cells_begin();
30 leafEnd_ = grid().getHostGrid().finite_cells_end();
33 if (grid().
comm().
size() == 1)
return;
39 template <
class Entity>
41 return contains(pitype, partition(e));
65 template <
class Entity>
88 template <
class Entity>
90 if constexpr (Entity::dimension ==
dim)
91 return e.
impl().hostEntity()->info().connectivity;
94 return interfaceConnectivity_.at(e.
impl().id());
101 template <
class Entity>
103 if constexpr (Entity::dimension ==
dim)
104 return e.
impl().hostEntity()->info().rank;
106 return grid().asIntersection(e).inside().impl().hostEntity()->info().rank;
115 template <
class Entity>
116 int partition(
const Entity& e)
const {
117 static constexpr int cd = Entity::codimension;
118 if (grid().
comm().
size() == 1)
return 0;
120 if constexpr (Entity::dimension ==
dim) {
121 if constexpr (Entity::codimension == 0 || Entity::codimension ==
dim)
122 return e.
impl().hostEntity()->info().partition;
124 auto entry = partition_[cd - 1].find(e.
impl().id());
125 if (entry != partition_[cd - 1].
end())
return entry->second;
128 auto entry = interfacePartition_[cd].find(e.
impl().id());
129 if (entry != interfacePartition_[cd].
end())
return entry->second;
135 DUNE_THROW(InvalidStateException,
"Partition not set yet!");
140 template <
class Entity>
141 void setPartition(
const Entity& e,
int partition) {
142 if constexpr (Entity::dimension ==
dim) {
143 if constexpr (Entity::codimension == 0 || Entity::codimension ==
dim)
144 e.impl().hostEntity()->info().partition =
partition;
146 partition_[Entity::codimension - 1][e.impl().id()] =
partition;
148 interfacePartition_[Entity::codimension][e.impl().id()] =
partition;
152 template <
class Entity>
153 void addConnectivity(
const Entity& e,
int rank) {
154 if constexpr (Entity::dimension ==
dim)
155 e.impl().hostEntity()->info().connectivity.insert(
rank);
157 interfaceConnectivity_[e.impl().id()].insert(
rank);
165 template <
class Entity>
166 void clearConnectivity(
const Entity& e) {
167 if constexpr (Entity::dimension ==
dim)
168 e.impl().hostEntity()->info().connectivity.clear();
170 interfaceConnectivity_[e.impl().id()].clear();
180 if constexpr (
dim == 2)
181 N = grid().getHostGrid().number_of_faces();
183 N = grid().getHostGrid().number_of_cells();
186 forEntityDim<dim>([
this, &i, &
rank, &
size, &
N](
const auto& fc) {
191 if (r ==
rank && getRank(i - 1) ==
rank - 1) this->leafBegin_ = fc;
194 if (r ==
rank + 1 && getRank(i - 1) ==
rank) this->leafEnd_ = fc;
196 auto e = grid().
entity(fc);
197 e.
impl().hostEntity()->info().rank = r;
203 void computePartitions() {
206 for (
int i = 0; i <=
dim; ++i) partition_[i].
clear();
209 forEntityDim<dim>([
this](
const auto& fc) {
210 const auto e = grid().
entity(fc);
216 clearConnectivity(e);
220 forEntityDim<
dim - 1>([
this](
const auto& fc) {
221 const auto e = grid().
entity(fc);
222 const auto is = grid().asIntersection(e);
224 const auto& inside = is.inside();
225 const auto& outside = is.outside();
230 if ((pIn == 0 && pOut != 0) or (pIn != 0 && pOut == 0)) {
231 setPartition(pIn == 0 ? outside : inside, 2);
232 addConnectivity(inside,
rank(outside));
233 addConnectivity(outside,
rank(inside));
243 forEntityDim<
dim - 1>([
this](
const auto& fc) {
244 const auto e = grid().
entity(fc);
245 const auto is = grid().asIntersection(e);
253 if (pIn == 0 && pOut == 0) setPartition(e, 0);
256 else if ((pIn == 0 && pOut == 2) or (pIn == 2 && pOut == 0))
260 else if (pIn == 2 || pOut == 2)
268 if (pIn == 0) setPartition(e, 0);
281 if constexpr (
dim == 3) {
282 forEntityDim<1>([
this](
const auto& fc) {
283 const auto edge = grid().
entity(fc);
292 if (interior == count) setPartition(edge, 0);
295 else if (interior > 0 and ghost > 0)
296 setPartition(edge, 1);
299 else if (interior == 0 and ghost > 0)
300 setPartition(edge, 2);
304 setPartition(edge, -1);
309 forEntityDim<0>([
this](
const auto& fc) {
310 const auto v = grid().
entity(fc);
319 if (interior == count) setPartition(v, 0);
322 else if (interior > 0 and ghost > 0)
326 else if (interior == 0 and ghost > 0)
338 static constexpr int idim =
dim - 1;
340 for (
int i = 0; i <= idim; ++i) interfacePartition_[i].
clear();
343 forEntityDim<idim>([
this](
const auto& fc) {
344 if (!grid().isInterface(grid().
entity(fc)))
return;
346 const auto e = grid().interfaceGrid().
entity(fc);
347 const auto is = grid().asIntersection(e);
349 clearConnectivity(e);
357 addConnectivity(e,
rank(is.outside()));
365 if (partition(e) == -1) {
367 addConnectivity(e,
rank(is.inside()));
372 forEntityDim<idim - 1>([
this](
const auto& fc) {
373 if (!grid().isInterface(grid().
entity(fc)))
return;
376 const auto e = grid().interfaceGrid().
entity(fc);
381 if (partition(incident) == 0) interior++;
382 if (partition(incident) != 0)
other++;
386 if (interior > 0 and
other > 0)
388 if (partition(incident) == -1) {
389 setPartition(incident, 2);
392 auto intersection = grid().asIntersection(incident);
393 if (partition(intersection.inside()) == -1)
394 setPartition(intersection.inside(), 2);
395 if (intersection.neighbor())
396 if (partition(intersection.outside()) == -1)
397 setPartition(intersection.outside(), 2);
402 forEntityDim<idim - 1>([
this](
const auto& fc) {
403 if (!grid().isInterface(grid().
entity(fc)))
return;
406 const auto e = grid().interfaceGrid().
entity(fc);
412 if (partition(incident) == 0) interior++;
413 if (partition(incident) == 2) ghost++;
418 if (interior == count) setPartition(e, 0);
421 else if (interior > 0 and ghost > 0) {
426 if (r !=
rank(incident)) addConnectivity(incident, r);
439 if constexpr (
dim == 3) {
440 forEntityDim<idim - 2>([
this](
const auto& fc) {
441 if (!grid().isInterface(grid().
entity(fc)))
return;
443 const auto v = grid().interfaceGrid().
entity(fc);
448 if (partition(incident) == 0) interior++;
449 if (partition(incident) == 2) ghost++;
453 if (interior == count) setPartition(v, 0);
456 else if (interior > 0 and ghost > 0)
471 template <
int edim,
class F>
472 void forEntityDim(
const F& f) {
473 if constexpr (edim ==
dim) {
474 if constexpr (
dim == 2)
475 for (
auto fc = grid().getHostGrid().finite_faces_begin();
476 fc != grid().getHostGrid().finite_faces_end(); ++fc)
479 if constexpr (
dim == 3)
480 for (
auto fc = grid().getHostGrid().finite_cells_begin();
481 fc != grid().getHostGrid().finite_cells_end(); ++fc)
485 if constexpr (edim == 0)
486 for (
auto fc = grid().getHostGrid().finite_vertices_begin();
487 fc != grid().getHostGrid().finite_vertices_end(); ++fc)
490 if constexpr (edim == 1)
491 for (
auto fc = grid().getHostGrid().finite_edges_begin();
492 fc != grid().getHostGrid().finite_edges_end(); ++fc)
495 if constexpr (
dim == 3 && edim == 2)
496 for (
auto fc = grid().getHostGrid().finite_facets_begin();
497 fc != grid().getHostGrid().finite_facets_end(); ++fc)
501 const Grid& grid()
const {
return grid_; }
static constexpr size_type N()
#define DUNE_THROW(E,...)
auto incidentElements(const Entity &entity)
Elements incident to a given entity.
Definition rangegenerators.hh:13
auto incidentInterfaceElements(const Entity &entity)
Incident interface elements.
Definition rangegenerators.hh:112
constexpr Interior interior
const EntityType & entity() const
GridImp::template Codim< cd >::Entity Entity
Codim< EntitySeed::codimension >::Entity entity(const EntitySeed &seed) const
const Communication & comm() const
StackAllocator< U, S > other
Definition partitionhelper.hh:13
typename Grid::LeafIterator::Implementation::HostGridLeafIterator LeafIterator
Definition partitionhelper.hh:19
typename Grid::IdType IdType
Definition partitionhelper.hh:15
const LeafIterator & leafInteriorEnd() const
Definition partitionhelper.hh:111
bool contains(PartitionIteratorType pitype, int partitionType) const
Definition partitionhelper.hh:44
auto & comm() const
Definition partitionhelper.hh:85
ConnectivityType connectivity(const Entity &e) const
Get connectivity (list of ranks)
Definition partitionhelper.hh:89
bool contains(PartitionIteratorType pitype, const Entity &e) const
Definition partitionhelper.hh:40
void updatePartitions()
Definition partitionhelper.hh:80
void computeInterfacePartitions()
Compute partition type for every interface entity.
Definition partitionhelper.hh:337
const LinksType & links() const
List of connected ranks.
Definition partitionhelper.hh:83
PartitionType partitionType(int partition) const
Definition partitionhelper.hh:70
void distribute()
Definition partitionhelper.hh:23
PartitionType partitionType(const Entity &e) const
Definition partitionhelper.hh:66
std::unordered_set< int > ConnectivityType
Definition partitionhelper.hh:16
int rank(const Entity &e) const
Get rank of an entity.
Definition partitionhelper.hh:102
const LeafIterator & leafInteriorBegin() const
Definition partitionhelper.hh:109
static constexpr int dim
Definition partitionhelper.hh:14
std::vector< int > LinksType
Definition partitionhelper.hh:17
PartitionHelper(const Grid &grid)
Definition partitionhelper.hh:21