46 bool hasMeshBeenGathered =
false;
48 bool twoLevelInitAlreadyUsed =
false;
51 if (
m2n->usesTwoLevelInitialization()) {
53 PRECICE_CHECK(not twoLevelInitAlreadyUsed,
"Two-level initialization does not yet support multiple receivers of a provided mesh. "
54 "Please either switch two-level initialization off in your m2n definition, or "
55 "adapt your mesh setup such that each provided mesh is only received by maximum one "
57 twoLevelInitAlreadyUsed =
true;
63 _m2ns[0]->getPrimaryRankCommunication()->send(
_mesh->getGlobalNumberOfVertices(), 0);
69 const int minGlobalVertexID = vertexOffset -
_mesh->nVertices();
70 const int maxGlobalVertexID = vertexOffset - 1;
73 _m2ns[0]->broadcastSend(minGlobalVertexID, *
_mesh);
74 _m2ns[0]->broadcastSend(maxGlobalVertexID, *
_mesh);
81 if (not hasMeshBeenGathered) {
94 PRECICE_DEBUG(
"Received sub-mesh, from secondary rank: {}, global vertexCount: {}", secondaryRank, globalMesh.
nVertices());
100 hasMeshBeenGathered =
true;
109 "The provided mesh \"{}\" is empty. Please set the mesh using setMeshVertex()/setMeshVertices() prior to calling initialize().",
127 int numberOfVertices =
_mesh->nVertices();
133 for (
int i = 0; i < numberOfVertices; i++) {
134 _mesh->vertex(i).setGlobalIndex(i);
138 vertexOffsets[0] = numberOfVertices;
139 int globalNumberOfVertices = numberOfVertices;
143 int numberOfSecondaryRankVertices = -1;
145 vertexOffsets[secondaryRank] = numberOfSecondaryRankVertices + vertexOffsets[secondaryRank - 1];
147 globalNumberOfVertices += numberOfSecondaryRankVertices;
150 _mesh->setVertexOffsets(vertexOffsets);
153 _mesh->setGlobalNumberOfVertices(globalNumberOfVertices);
154 PRECICE_DEBUG(
"Broadcast global number of vertices: {}", globalNumberOfVertices);
167 auto &localIds = vertexDistribution[0];
168 localIds.resize(vertexOffsets[0]);
169 std::iota(localIds.begin(), localIds.end(), 0);
173 auto &secondaryIds = vertexDistribution[secondaryRank];
174 for (
int i = vertexOffsets[secondaryRank - 1]; i < vertexOffsets[secondaryRank]; i++) {
175 secondaryIds.push_back(i);
179 _mesh->setVertexDistribution(std::move(vertexDistribution));
184 PRECICE_DEBUG(
"Send number of vertices: {}", numberOfVertices);
188 int globalVertexCounter = -1;
191 for (
int i = 0; i < numberOfVertices; i++) {
192 _mesh->vertex(i).setGlobalIndex(globalVertexCounter + i);
196 int globalNumberOfVertices = -1;
199 _mesh->setGlobalNumberOfVertices(globalNumberOfVertices);
206 _mesh->setVertexOffsets(std::move(vertexOffsets));
210 _mesh->setVertexDistribution([&] {
212 for (
int i = 0; i < numberOfVertices; i++) {
213 vertexDistribution[0].push_back(i);
214 _mesh->vertex(i).setGlobalIndex(i);
216 return vertexDistribution;
218 _mesh->setVertexOffsets({numberOfVertices});
219 _mesh->setGlobalNumberOfVertices(numberOfVertices);
236 if (
m2n->usesTwoLevelInitialization()) {
240 m2n->gatherAllCommunicationMap(
_mesh->getCommunicationMap(), *
_mesh);
249 _mesh->clearPartitioning();
257 if (not
_m2ns[0]->usesTwoLevelInitialization())
262 PRECICE_ASSERT(
_mesh->getBoundingBox().getDimension() ==
_mesh->getDimensions(),
"The boundingbox of the local mesh is invalid!");
278 bbm.
emplace(secondaryRank, bb);
288 int remoteConnectionMapSize = 0;
295 remoteConnectionMapSize = connectedRanksList.
size();
298 for (
auto &rank : connectedRanksList) {
299 remoteConnectionMap[rank] = {-1};
301 if (remoteConnectionMapSize != 0) {
307 if (remoteConnectionMapSize != 0) {
313 _mesh->setConnectedRanks([&] {
315 for (
const auto &remoteRank : remoteConnectionMap) {
316 for (
const auto &includedRank : remoteRank.second) {
330 if (!connectedRanksList.
empty()) {
331 for (
Rank rank : connectedRanksList) {
332 remoteConnectionMap[rank] = {-1};
338 _mesh->setConnectedRanks([&] {
340 for (
const auto &remoteRank : remoteConnectionMap) {
341 for (
int includedRanks : remoteRank.second) {
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_INFO(...)
#define PRECICE_CHECK(check,...)
#define PRECICE_ASSERT(...)
An axis-aligned bounding box around a (partition of a) mesh.
Container and creator for meshes.
std::map< Rank, std::vector< VertexID > > CommunicationMap
A mapping from remote local ranks to the IDs that must be communicated.
void addMesh(Mesh &deltaMesh)
const std::string & getName() const
Returns the name of the mesh, as set in the config file.
static constexpr MeshID MESH_ID_UNDEFINED
Use if the id of the mesh is not necessary.
std::map< Rank, std::vector< VertexID > > VertexDistribution
A mapping from rank to used (not necessarily owned) vertex IDs.
std::size_t nVertices() const
Returns the number of vertices.
std::map< int, BoundingBox > BoundingBoxMap
std::vector< int > VertexOffsets
Partition(mesh::PtrMesh mesh)
Constructor.
std::vector< m2n::PtrM2N > _m2ns
m2n connection to each connected participant
void compute() override
All distribution data structures are set up.
ProvidedPartition(mesh::PtrMesh mesh)
void communicate() override
The mesh is gathered and sent to another participant (if required)
void compareBoundingBoxes() override
Intersections between bounding boxes around each rank are computed.
static int getSize()
Number of ranks. This includes ranks from both participants, e.g. minimal size is 2.
static Rank getRank()
Current rank.
static bool isPrimary()
True if this process is running the primary rank.
static auto allSecondaryRanks()
Returns an iterable range over salve ranks [1, _size)
static bool isSecondary()
True if this process is running a secondary rank.
static com::PtrCommunication & getCommunication()
Intra-participant communication.
void sendMesh(Communication &communication, int rankReceiver, const mesh::Mesh &mesh)
void sendBoundingBox(Communication &communication, int rankReceiver, const mesh::BoundingBox &bb)
constexpr auto asVector
Allows to use Communication::AsVectorTag in a less verbose way.
void receiveConnectionMap(Communication &communication, int rankSender, mesh::Mesh::ConnectionMap &cm)
void receiveMesh(Communication &communication, int rankSender, mesh::Mesh &mesh)
void broadcastSendConnectionMap(Communication &communication, const mesh::Mesh::ConnectionMap &cm)
void sendBoundingBoxMap(Communication &communication, int rankReceiver, const mesh::Mesh::BoundingBoxMap &bbm)
void broadcastReceiveConnectionMap(Communication &communication, mesh::Mesh::ConnectionMap &cm)
void receiveBoundingBox(Communication &communication, int rankSender, mesh::BoundingBox &bb)
contains the logic of the parallel communication between participants.
std::shared_ptr< M2N > PtrM2N
provides Mesh, Data and primitives.
std::shared_ptr< Mesh > PtrMesh
contains the partitioning of distributed meshes.
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.