preCICE v3.2.0
Loading...
Searching...
No Matches
MultiCouplingScheme.cpp
Go to the documentation of this file.
2#include <algorithm>
3#include <boost/range/adaptor/map.hpp>
4#include <cstddef>
5#include <map>
6#include <memory>
7#include <ostream>
8#include <type_traits>
9#include <utility>
15#include "logging/LogMacros.hpp"
16#include "m2n/SharedPointer.hpp"
17#include "mesh/Data.hpp"
18#include "mesh/Mesh.hpp"
19
20namespace precice::cplscheme {
21
23 double maxTime,
24 int maxTimeWindows,
25 double timeWindowSize,
28 const std::string &controller,
29 int minIterations,
30 int maxIterations)
31 : BaseCouplingScheme(maxTime, maxTimeWindows, timeWindowSize, localParticipant, minIterations, maxIterations, Implicit, constants::TimesteppingMethod::FIXED_TIME_WINDOW_SIZE),
32 _m2ns(std::move(m2ns)), _controller(controller), _isController(controller == localParticipant)
33{
34 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
35 // Controller participant never does the first step, because it is never the first participant
37 PRECICE_DEBUG("MultiCoupling scheme is created for {}.", localParticipant);
38}
39
41{
42 for (auto &sendExchange : _sendDataVector | boost::adaptors::map_values) {
43 determineInitialSend(sendExchange);
44 }
45 for (auto &receiveExchange : _receiveDataVector | boost::adaptors::map_values) {
46 determineInitialReceive(receiveExchange);
47 }
48}
49
51{
52 std::vector<std::string> partnerNames;
53
54 for (const auto &m2nPair : _m2ns) {
55 partnerNames.emplace_back(m2nPair.first);
56 }
57
58 return partnerNames;
59}
60
62{
63 return std::any_of(_sendDataVector.cbegin(), _sendDataVector.cend(), [](const auto &sendExchange) { return not sendExchange.second.empty(); });
64}
65
67{
68 // MultiCouplingScheme applies acceleration to all CouplingData
69 return _allData;
70}
71
73{
74 // @todo check receiveData. Should only contain zero data!
75 for (auto &receiveExchange : _receiveDataVector) {
76 initializeWithZeroInitialData(receiveExchange.second);
77 }
78}
79
81{
82 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
84
85 if (_isController) {
86 for (auto &[from, data] : _receiveDataVector) {
88 receiveData(_m2ns.at(from), data);
89 } else {
91 }
92 }
94 for (auto &[to, data] : _sendDataVector) {
95 if (sendsInitializedDataTo(to)) {
96 sendData(_m2ns.at(to), data);
97 }
98 }
99 } else {
100 for (auto &[to, data] : _sendDataVector) {
101 if (sendsInitializedDataTo(to)) {
102 sendData(_m2ns.at(to), data);
103 }
104 }
105 for (auto &[from, data] : _receiveDataVector) {
106 if (receivesInitializedDataFrom(from)) {
107 receiveData(_m2ns.at(from), data);
108 } else {
110 }
111 }
113 }
114 PRECICE_DEBUG("Initial data is exchanged in MultiCouplingScheme");
115}
116
118{
119 return _sendInitialTo.count(to) > 0;
120}
121
123{
124 return _receiveInitialFrom.count(from) > 0;
125}
126
128{
129 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
131 // @todo implement MultiCouplingScheme for explicit coupling
132
133 PRECICE_DEBUG("Computed full length of iteration");
134
135 if (_isController) {
136 for (auto &receiveExchange : _receiveDataVector) {
137 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
138 }
140 } else {
141 for (auto &sendExchange : _sendDataVector) {
142 sendData(_m2ns[sendExchange.first], sendExchange.second);
143 }
144 }
145}
146
148{
149 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
151 // @todo implement MultiCouplingScheme for explicit coupling
152
153 if (not _isController) {
155 for (auto &receiveExchange : _receiveDataVector) {
156 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
157 }
159 } else {
161 for (const auto &m2n : _m2ns | boost::adaptors::map_values) {
163 }
164 for (auto &sendExchange : _sendDataVector) {
165 sendData(_m2ns[sendExchange.first], sendExchange.second);
166 }
167 }
168
169 if (hasConverged()) {
171 }
172
174}
175
177 const mesh::PtrData &data,
179 bool requiresInitialization,
180 bool exchangeSubsteps,
181 const std::string &to)
182{
183 PtrCouplingData ptrCplData = addCouplingData(data, std::move(mesh), requiresInitialization, exchangeSubsteps, CouplingData::Direction::Send);
184 PRECICE_DEBUG("Configuring send data to {}", to);
185 _sendDataVector[to].emplace(data->getID(), ptrCplData);
186 if (requiresInitialization) {
187 _sendInitialTo.emplace(to);
188 }
189}
190
192 const mesh::PtrData &data,
194 bool requiresInitialization,
195 bool exchangeSubsteps,
196 const std::string &from)
197{
198 PtrCouplingData ptrCplData = addCouplingData(data, std::move(mesh), requiresInitialization, exchangeSubsteps, CouplingData::Direction::Receive);
199 PRECICE_DEBUG("Configuring receive data from {}", from);
200 _receiveDataVector[from].emplace(data->getID(), ptrCplData);
201 if (requiresInitialization) {
202 _receiveInitialFrom.emplace(from);
203 }
204}
205
206} // namespace precice::cplscheme
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:61
T any_of(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
void initializeWithZeroInitialData(const DataMap &receiveData)
Initializes storage in receiveData as zero.
void determineInitialReceive(DataMap &receiveData)
Sets _receivesInitializedData, if receiveData requires initialization.
void determineInitialSend(DataMap &sendData)
Sets _sendsInitializedData, if sendData requires initialization.
void notifyDataHasBeenReceived()
Used to set flag after data has been received using receiveData().
void sendData(const m2n::PtrM2N &m2n, const DataMap &sendData)
Sends data sendDataIDs given in mapCouplingData with communication.
void storeIteration()
used for storing all Data at end of doImplicitStep for later reference.
bool isImplicitCouplingScheme() const override
Function to determine whether coupling scheme is an implicit coupling scheme.
void sendConvergence(const m2n::PtrM2N &m2n)
sends convergence to other participant via m2n
bool hasConverged() const override
Checks if the implicit cplscheme has converged.
void moveToNextWindow()
finalizes this window's data and initializes data for next window.
void doImplicitStep()
perform a coupling iteration
double getTime() const final override
getter for _time
PtrCouplingData addCouplingData(const mesh::PtrData &data, mesh::PtrMesh mesh, bool requiresInitialization, bool exchangeSubsteps, CouplingData::Direction direction)
Adds CouplingData with given properties to this BaseCouplingScheme and returns a pointer to the Coupl...
DataMap _allData
All send and receive data as a map "data ID -> data".
std::string localParticipant() const final override
Returns the name of the local participant.
void receiveConvergence(const m2n::PtrM2N &m2n)
receives convergence from other participant via m2n
BaseCouplingScheme(double maxTime, int maxTimeWindows, double timeWindowSize, std::string localParticipant, int minIterations, int maxIterations, CouplingMode cplMode, constants::TimesteppingMethod dtMethod)
void setDoesFirstStep(bool doesFirstStep)
Setter for _doesFirstStep.
void receiveData(const m2n::PtrM2N &m2n, const DataMap &receiveData)
Receives data receiveDataIDs given in mapCouplingData with communication.
std::string _controller
name of the controller participant
std::set< std::string > _receiveInitialFrom
Coupling partners to receive initial data from.
std::map< std::string, m2n::PtrM2N > _m2ns
A vector of m2ns. A m2n is a communication device to the other coupling participant.
void exchangeInitialData() final override
implements functionality for initialize in base class.
bool sendsInitializedDataTo(const std::string &to) const
void addDataToSend(const mesh::PtrData &data, mesh::PtrMesh mesh, bool requiresInitialization, bool exchangeSubsteps, const std::string &to)
Adds data to be sent on data exchange and possibly be modified during coupling iterations.
DataMap & getAccelerationData() final override
interface to provide accelerated data, depending on coupling scheme being used
void exchangeFirstData() final override
Functions needed for advance()
void determineInitialDataExchange() override
Determines which data is initialized and therefore has to be exchanged during initialize.
void initializeReceiveDataStorage() final override
Functions needed for initialize()
std::set< std::string > _sendInitialTo
Coupling partners to send initial data to.
MultiCouplingScheme(double maxTime, int maxTimeWindows, double timeWindowSize, const std::string &localParticipant, std::map< std::string, m2n::PtrM2N > m2ns, const std::string &controller, int minIterations, int maxIterations)
Constructor.
std::map< std::string, DataMap > _sendDataVector
A vector of all data to be sent.
std::vector< std::string > getCouplingPartners() const final override
Returns list of all coupling partners.
bool _isController
if this is the controller or not
void addDataToReceive(const mesh::PtrData &data, mesh::PtrMesh mesh, bool requiresInitialization, bool exchangeSubsteps, const std::string &from)
Adds data to be received on data exchange.
std::map< std::string, DataMap > _receiveDataVector
A vector of all data to be received.
void exchangeSecondData() final override
Exchanges the second set of data.
bool receivesInitializedDataFrom(const std::string &from) const
T emplace_back(T... args)
contains implementations of coupling schemes for coupled simulations.
std::shared_ptr< CouplingData > PtrCouplingData
std::map< int, PtrCouplingData > DataMap
contains the logic of the parallel communication between participants.
Definition BoundM2N.cpp:12
constexpr bool equals(const Eigen::MatrixBase< DerivedA > &A, const Eigen::MatrixBase< DerivedB > &B, double tolerance=NUMERICAL_ZERO_DIFFERENCE)
Compares two Eigen::MatrixBase for equality up to tolerance.
provides Mesh, Data and primitives.
std::shared_ptr< Data > PtrData
std::shared_ptr< Mesh > PtrMesh
STL namespace.