preCICE v3.1.2
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,
26 const std::string & localParticipant,
29 const std::string & controller,
30 int minIterations,
31 int maxIterations)
32 : BaseCouplingScheme(maxTime, maxTimeWindows, timeWindowSize, localParticipant, minIterations, maxIterations, Implicit, dtMethod),
33 _m2ns(std::move(m2ns)), _controller(controller), _isController(controller == localParticipant)
34{
35 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
36 // Controller participant never does the first step, because it is never the first participant
38 PRECICE_DEBUG("MultiCoupling scheme is created for {}.", localParticipant);
39}
40
42{
43 for (auto &sendExchange : _sendDataVector | boost::adaptors::map_values) {
44 determineInitialSend(sendExchange);
45 }
46 for (auto &receiveExchange : _receiveDataVector | boost::adaptors::map_values) {
47 determineInitialReceive(receiveExchange);
48 }
49}
50
52{
53 std::vector<std::string> partnerNames;
54
55 for (const auto &m2nPair : _m2ns) {
56 partnerNames.emplace_back(m2nPair.first);
57 }
58
59 return partnerNames;
60}
61
63{
64 return std::any_of(_sendDataVector.cbegin(), _sendDataVector.cend(), [](const auto &sendExchange) { return not sendExchange.second.empty(); });
65}
66
68{
69 // MultiCouplingScheme applies acceleration to all CouplingData
70 return _allData;
71}
72
74{
75 // @todo check receiveData. Should only contain zero data!
76 for (auto &receiveExchange : _receiveDataVector) {
77 initializeWithZeroInitialData(receiveExchange.second);
78 }
79}
80
82{
83 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
84
85 if (_isController) {
87 for (auto &receiveExchange : _receiveDataVector) {
88 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
89 }
91 } else {
92 for (auto &receiveExchange : _receiveDataVector) {
93 initializeWithZeroInitialData(receiveExchange.second);
94 }
95 }
97 for (auto &sendExchange : _sendDataVector) {
98 sendData(_m2ns[sendExchange.first], sendExchange.second);
99 }
100 }
101 } else {
102 if (sendsInitializedData()) {
103 for (auto &sendExchange : _sendDataVector) {
104 sendData(_m2ns[sendExchange.first], sendExchange.second);
105 }
106 }
108 for (auto &receiveExchange : _receiveDataVector) {
109 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
110 }
112 } else {
113 for (auto &receiveExchange : _receiveDataVector) {
114 initializeWithZeroInitialData(receiveExchange.second);
115 }
116 }
117 }
118 PRECICE_DEBUG("Initial data is exchanged in MultiCouplingScheme");
119}
120
122{
123 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
124 // @todo implement MultiCouplingScheme for explicit coupling
125
126 PRECICE_DEBUG("Computed full length of iteration");
127
128 if (_isController) {
129 for (auto &receiveExchange : _receiveDataVector) {
130 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
131 }
133 } else {
134 for (auto &sendExchange : _sendDataVector) {
135 sendData(_m2ns[sendExchange.first], sendExchange.second);
136 }
137 }
138}
139
141{
142 PRECICE_ASSERT(isImplicitCouplingScheme(), "MultiCouplingScheme is always Implicit.");
143 // @todo implement MultiCouplingScheme for explicit coupling
144
145 if (not _isController) {
147 for (auto &receiveExchange : _receiveDataVector) {
148 receiveData(_m2ns[receiveExchange.first], receiveExchange.second);
149 }
151 } else {
153 for (const auto &m2n : _m2ns | boost::adaptors::map_values) {
154 sendConvergence(m2n);
155 }
156 for (auto &sendExchange : _sendDataVector) {
157 sendData(_m2ns[sendExchange.first], sendExchange.second);
158 }
159 }
160
161 if (hasConverged()) {
163 }
164
166}
167
169 const mesh::PtrData &data,
170 mesh::PtrMesh mesh,
171 bool requiresInitialization,
172 bool exchangeSubsteps,
173 const std::string & to)
174{
175 PtrCouplingData ptrCplData = addCouplingData(data, std::move(mesh), requiresInitialization, exchangeSubsteps, CouplingData::Direction::Send);
176 PRECICE_DEBUG("Configuring send data to {}", to);
177 _sendDataVector[to].emplace(data->getID(), ptrCplData);
178}
179
181 const mesh::PtrData &data,
182 mesh::PtrMesh mesh,
183 bool requiresInitialization,
184 bool exchangeSubsteps,
185 const std::string & from)
186{
187 PtrCouplingData ptrCplData = addCouplingData(data, std::move(mesh), requiresInitialization, exchangeSubsteps, CouplingData::Direction::Receive);
188 PRECICE_DEBUG("Configuring receive data from {}", from);
189 _receiveDataVector[from].emplace(data->getID(), ptrCplData);
190}
191
192} // namespace precice::cplscheme
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:64
T any_of(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
Abstract base class for standard coupling schemes.
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 sendsInitializedData() const override final
Getter for _sendsInitializedData.
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
bool receivesInitializedData() const
Getter for _receivesInitializedData.
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 override final
Returns the name of the local participant.
void receiveConvergence(const m2n::PtrM2N &m2n)
receives convergence from other participant via m2n
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::map< std::string, m2n::PtrM2N > _m2ns
A vector of m2ns. A m2n is a communication device to the other coupling participant.
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.
void determineInitialDataExchange() override
Determines which data is initialized and therefore has to be exchanged during initialize.
void initializeReceiveDataStorage() override final
Functions needed for initialize()
void exchangeInitialData() override final
implements functionality for initialize in base class.
void exchangeFirstData() override final
Functions needed for advance()
MultiCouplingScheme(double maxTime, int maxTimeWindows, double timeWindowSize, const std::string &localParticipant, std::map< std::string, m2n::PtrM2N > m2ns, constants::TimesteppingMethod dtMethod, const std::string &controller, int minIterations, int maxIterations)
Constructor.
void exchangeSecondData() override final
Exchanges the second set of data.
std::map< std::string, DataMap > _sendDataVector
A vector of all data to be sent.
bool _isController
if this is the controller or not
std::vector< std::string > getCouplingPartners() const override final
Returns list of all coupling partners.
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.
DataMap & getAccelerationData() override final
interface to provide accelerated data, depending on coupling scheme being used
std::map< std::string, DataMap > _receiveDataVector
A vector of all data to be received.
T emplace_back(T... args)
contains implementations of coupling schemes for coupled simulations.
STL namespace.