66template <
class Indices,
class Src,
class Dst,
class Size>
67void add_to_indirect_blocks(
69 const Indices &indices,
73 for (
size_t i = 0; i < indices.size(); ++i) {
74 auto srcfirst = blockSize * i;
75 auto dstfirst = blockSize * indices[i];
76 PRECICE_ASSERT(srcfirst >= 0 &&
static_cast<size_t>(srcfirst + blockSize) <= src.size(), srcfirst, blockSize, src.size());
77 PRECICE_ASSERT(dstfirst >= 0 &&
static_cast<size_t>(dstfirst + blockSize) <= dst.size(), dstfirst, blockSize, dst.size());
82template <
class Indices,
class Src,
class Dst,
class Size>
83void copy_from_indirect_blocks(
85 const Indices &indices,
89 for (
size_t i = 0; i < indices.size(); ++i) {
90 auto srcfirst = blockSize * indices[i];
91 auto dstfirst = blockSize * i;
92 PRECICE_ASSERT(srcfirst >= 0 &&
static_cast<size_t>(srcfirst + blockSize) <= src.size(), srcfirst, blockSize, src.size());
93 PRECICE_ASSERT(dstfirst >= 0 &&
static_cast<size_t>(dstfirst + blockSize) <= dst.size(), dstfirst, blockSize, dst.size());
94 std::copy_n(&src[srcfirst], blockSize, &dst[dstfirst]);
106 if (!itemsToSend.
empty()) {
115 const auto &vertexDistribution =
_mesh->getVertexDistribution();
116 const int globalSize =
_mesh->getGlobalNumberOfVertices() * valueDimension;
117 PRECICE_DEBUG(
"Gathering data on primary ({} elements)", globalSize);
122 const auto &primaryDistribution = vertexDistribution.at(0);
123 add_to_indirect_blocks(itemsToSend, primaryDistribution, valueDimension, globalItemsToSend);
124 PRECICE_DEBUG(
"Directly gathered {} entries from primary", primaryDistribution.size() * valueDimension);
131 auto iter = vertexDistribution.find(secondaryRank);
132 if (iter == vertexDistribution.end()) {
135 const auto &secondaryDistribution = iter->second;
137 int secondaryRankSize = secondaryDistribution.size() * valueDimension;
138 PRECICE_DEBUG(
"Gathering {} entries from secondary rank {}", secondaryRankSize, secondaryRank);
139 if (secondaryDistribution.empty()) {
144 add_to_indirect_blocks(secondaryRankValues, secondaryDistribution, valueDimension, globalItemsToSend);
149 _com->sendRange(globalItemsToSend, 0);
158 if (!itemsToReceive.
empty()) {
161 PRECICE_DEBUG(
"Received scattered data starting with {}", received[0]);
162 std::copy(received.begin(), received.end(), itemsToReceive.
begin());
170 const int globalSize =
_mesh->getGlobalNumberOfVertices() * valueDimension;
171 PRECICE_DEBUG(
"Receiving {} elements from other participant to scatter", globalSize);
176 const auto &vertexDistribution =
_mesh->getVertexDistribution();
180 const auto &primaryDistribution = vertexDistribution.at(0);
181 copy_from_indirect_blocks(globalItemsToReceive, primaryDistribution, valueDimension, itemsToReceive);
183 PRECICE_DEBUG(
"Directly extracted {} data entries for primary", primaryDistribution.size() * valueDimension);
190 auto iter = vertexDistribution.find(secondaryRank);
191 if (iter == vertexDistribution.end()) {
194 const auto &secondaryDistribution = iter->second;
196 int secondarySize = secondaryDistribution.size() * valueDimension;
197 PRECICE_DEBUG(
"Scattering {} entries to secondary {}", secondarySize, secondarySize);
198 if (secondaryDistribution.empty()) {
203 copy_from_indirect_blocks(globalItemsToReceive, secondaryDistribution, valueDimension, secondaryRankValues);
204 PRECICE_DEBUG(
"Scattering data starting with {} to rank {}", secondaryRankValues[0], secondaryRank);
213 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
220 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
225 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
230 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
235 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
240 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
245 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
250 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
255 PRECICE_ASSERT(
false,
"Not available for GatherScatterCommunication.");
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_ASSERT(...)
Interface for all distributed solver to solver communication classes.
mesh::PtrMesh _mesh
mesh that dictates the distribution of this mapping
com::PtrCommunication _com
primary to primary basic communication
bool isConnected() const override
Returns true, if a connection to a remote participant has been setup.
~GatherScatterCommunication() override
void broadcastReceiveAllMesh() override
Receive mesh partitions per connected rank on remote participant. Not available for GatherScatterComm...
void acceptConnection(const std::string &acceptorName, const std::string &requesterName) override
Accepts connection from participant, which has to call requestConnection().
GatherScatterCommunication(com::PtrCommunication com, mesh::PtrMesh mesh)
void broadcastSendMesh() override
Broadcasts a mesh to connected ranks on remote participant. Not available for GatherScatterCommunicat...
void broadcastReceiveAll(std::vector< int > &itemToReceive) override
Receives an int per connected rank on remote participant. Not available for GatherScatterCommunicatio...
void completeSecondaryRanksConnection() override
Completes the secondary connections for both acceptor and requester by updating the vertex list in _m...
void closeConnection() override
Disconnects from communication space, i.e. participant.
void receive(precice::span< double > itemsToReceive, int valueDimension) override
All ranks receive an array of doubles (different for each rank).
void broadcastSend(int itemToSend) override
Broadcasts an int to connected ranks on remote participant. Not available for GatherScatterCommunicat...
void scatterAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Scatters a communication map over connected ranks on remote participant. Not available for GatherScat...
void acceptPreConnection(std::string const &acceptorName, std::string const &requesterName) override
void requestConnection(const std::string &acceptorName, const std::string &requesterName) override
Requests connection from participant, which has to call acceptConnection().
void requestPreConnection(std::string const &acceptorName, std::string const &requesterName) override
void send(precice::span< double const > itemsToSend, int valueDimension) override
Sends an array of double values from all ranks (different for each rank).
bool _isConnected
Global communication is set up or not.
void gatherAllCommunicationMap(CommunicationMap &localCommunicationMap) override
Gathers a communication maps from connected ranks on remote participant. Not available for GatherScat...
A C++ 11 implementation of the non-owning C++20 std::span type.
PRECICE_SPAN_NODISCARD constexpr bool empty() const noexcept
constexpr iterator begin() const noexcept
constexpr size_type size() const noexcept
static Rank getRank()
Current 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.
contains the logic of the parallel communication between participants.
void add_n(InputIt first, Size count, InOutIt result)