version 3.11-dev
Loading...
Searching...
No Matches
distributedboundingboxtree.hh
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3//
4// SPDX-FileCopyrightText: Copyright © DuMux Project contributors, see AUTHORS.md in root folder
5// SPDX-License-Identifier: GPL-3.0-or-later
6//
22#ifndef DUMUX_GEOMETRY_DISTRIBUTED_BOUNDINGBOXTREE_HH
23#define DUMUX_GEOMETRY_DISTRIBUTED_BOUNDINGBOXTREE_HH
24
25#include <cassert>
26#include <vector>
27#include <array>
28#include <span>
29#include <memory>
30#include <algorithm>
31#include <type_traits>
32#include <utility>
33
34#include <dune/common/fvector.hh>
35#include <dune/common/exceptions.hh>
36
40
41namespace Dumux {
42
58template<class GeometricEntitySet>
59 requires requires(const GeometricEntitySet& set) { { set.comm() }; }
61{
62 static constexpr int dimworld = GeometricEntitySet::dimensionworld;
63 using ctype = typename GeometricEntitySet::ctype;
64
65 // internal types for the replicated process tree (the tree over the per-process boxes,
66 // each leaf being a process partition box carrying its owning rank)
67 using ProcessBoxGeometry = BoundingBoxGeometry<ctype, dimworld>;
68 using ProcessEntitySet = ProcessGeometricEntitySet<ctype, dimworld>;
69 using ProcessEntity = typename ProcessEntitySet::Entity;
70
71public:
75 using EntitySet = GeometricEntitySet;
77 using Communication = std::decay_t<decltype(std::declval<const GeometricEntitySet>().comm())>;
80
83
85 explicit DistributedBoundingBoxTree(std::shared_ptr<const GeometricEntitySet> set)
86 { build(set); }
87
89 void build(std::shared_ptr<const GeometricEntitySet> set)
90 {
91 entitySet_ = set;
92 comm_ = set->comm();
93 const int numProc = comm_.size();
94
95 // build the process-local tree (guarding against empty partitions for
96 // which the sequential tree is not well-defined)
97 const bool hasLocalEntities = set->size() > 0;
99 localTree_ = std::make_shared<const LocalTree>(set);
100 else
101 localTree_.reset();
102
103 // determine the bounding box of the local partition (the root box of
104 // the local tree) or a sentinel for empty partitions
105 std::array<ctype, 2*dimworld> localBox{};
107 std::copy_n(localBoundingBox().data(), 2*dimworld, localBox.begin());
108
109 // communicate the per-process bounding boxes to all processes
110 std::vector<ctype> processBoxes(2*dimworld*numProc, 0.0);
111 comm_.allgather(localBox.data(), 2*dimworld, processBoxes.data());
112
113 // communicate which processes actually hold entities (valid boxes)
114 const int localValid = hasLocalEntities ? 1 : 0;
115 std::vector<int> processValid(numProc, 0);
116 comm_.allgather(&localValid, 1, processValid.data());
117
118 // build the replicated process tree over the non-empty process boxes;
119 // each entity carries the rank it belongs to
120 std::vector<ProcessEntity> processEntities;
121 processEntities.reserve(numProc);
122 for (int p = 0; p < numProc; ++p)
123 {
124 if (!processValid[p])
125 continue;
126
127 const ctype* b = processBoxes.data() + std::size_t(p)*2*dimworld;
128 Dune::FieldVector<ctype, dimworld> lower, upper;
129 for (int d = 0; d < dimworld; ++d)
130 {
131 lower[d] = b[d];
132 upper[d] = b[d + dimworld];
133 }
134 // the entity's consecutive index is its position in the set
135 processEntities.emplace_back(ProcessBoxGeometry{lower, upper}, processEntities.size(), p);
136 }
137
138 // the global entity set is assumed non-empty (at least one process holds
139 // entities), just like for the sequential bounding box tree
140 assert(!processEntities.empty());
141 processTree_ = std::make_shared<const ProcessTree>(
142 std::make_shared<const ProcessEntitySet>(std::move(processEntities)));
143 }
144
146 const EntitySet& entitySet() const
147 { return *entitySet_; }
148
150 const Communication& comm() const
151 { return comm_; }
152
154 int rank() const
155 { return comm_.rank(); }
156
158 bool hasLocalEntities() const
159 { return static_cast<bool>(localTree_); }
160
162 const LocalTree& localTree() const
163 {
164 if (!localTree_)
165 DUNE_THROW(Dune::InvalidStateException, "No local bounding box tree on a process without entities");
166 return *localTree_;
167 }
168
171 { return *processTree_; }
172
174 int processForLeaf(std::size_t leafIdx) const
175 { return processTree_->entitySet().rank(leafIdx); }
176
178 std::span<const ctype, 2*dimworld> localBoundingBox() const
179 {
180 if (!localTree_)
181 DUNE_THROW(Dune::InvalidStateException, "No local bounding box on a process without entities");
182 const auto* root = localTree_->getBoundingBoxCoordinates(localTree_->numBoundingBoxes() - 1);
183 return std::span<const ctype, 2*dimworld>{root, 2*dimworld};
184 }
185
186private:
188 std::shared_ptr<const EntitySet> entitySet_;
189
191 std::shared_ptr<const LocalTree> localTree_;
192
194 std::shared_ptr<const ProcessTree> processTree_;
195
197 Communication comm_{};
198};
199
200} // end namespace Dumux
201
202#endif
A thin axis-aligned box geometry.
An axis-aligned bounding box volume hierarchy for dune grids.
A thin axis-aligned box geometry.
Definition boundingboxgeometry.hh:34
An axis-aligned bounding box volume tree implementation.
Definition boundingboxtree.hh:105
BoundingBoxTree< ProcessEntitySet > ProcessTree
the type of the replicated process tree
Definition distributedboundingboxtree.hh:79
DistributedBoundingBoxTree()=default
Default constructor.
void build(std::shared_ptr< const GeometricEntitySet > set)
Build the distributed bounding box tree for the given entity set.
Definition distributedboundingboxtree.hh:89
const LocalTree & localTree() const
the process-local bounding box tree (only valid if hasLocalEntities())
Definition distributedboundingboxtree.hh:162
const EntitySet & entitySet() const
the entity set this tree was built with
Definition distributedboundingboxtree.hh:146
const ProcessTree & processTree() const
the replicated process tree over the per-process boxes
Definition distributedboundingboxtree.hh:170
GeometricEntitySet EntitySet
the type of entity set this tree was built with
Definition distributedboundingboxtree.hh:75
std::span< const ctype, 2 *dimworld > localBoundingBox() const
the bounding box (min then max) of this process' partition (only valid if hasLocalEntities())
Definition distributedboundingboxtree.hh:178
BoundingBoxTree< GeometricEntitySet > LocalTree
the type of the process-local bounding box tree
Definition distributedboundingboxtree.hh:73
DistributedBoundingBoxTree(std::shared_ptr< const GeometricEntitySet > set)
Constructor with an entity set.
Definition distributedboundingboxtree.hh:85
const Communication & comm() const
the communicator this tree was built with
Definition distributedboundingboxtree.hh:150
int processForLeaf(std::size_t leafIdx) const
the rank owning the given leaf of the process tree
Definition distributedboundingboxtree.hh:174
int rank() const
the rank of this process
Definition distributedboundingboxtree.hh:154
std::decay_t< decltype(std::declval< const GeometricEntitySet >().comm())> Communication
the communicator type
Definition distributedboundingboxtree.hh:77
bool hasLocalEntities() const
Definition distributedboundingboxtree.hh:158
A set of axis-aligned bounding boxes each owned by a process rank.
Definition geometricentityset.hh:375
Detail::GeometricEntity::ProcessEntity< ctype, dimworld > Entity
Definition geometricentityset.hh:377
An interface for a set of geometric entities.
Definition adapt.hh:17