29bool compatibleTimeWindowSizes(
const CouplingScheme &impl,
const CouplingScheme &expl)
31 if (!impl.hasTimeWindowSize() || !expl.hasTimeWindowSize()) {
34 double idt = impl.getTimeWindowSize();
35 double edt = expl.getTimeWindowSize();
43 if (compatibleTimeWindowSizes(impl, expl)) {
53 "The participant {} is implicitly coupled to {} with time-window-size {} and explicitly coupled to {} with time-window-size {}, which isn't well-defined. "
54 "Explicit time windows should be aligned with implicit time windows. "
55 "Choose time window sizes so that the explicit (currently {}) is an integer multiple of the implicit (currently {}).",
56 local, implPartners.front(), idt, explPartners.front(), edt,
64 if (!couplingScheme->isImplicitCouplingScheme()) {
87 scheme->initialize(startTime, startTimeWindow);
114 auto explicitAtWindowEnd =
false;
116 explicitAtWindowEnd |= scheme->addComputedTime(timeToAdd);
118 return explicitAtWindowEnd;
122 auto implicitAtWindowEnd =
_implicitScheme->addComputedTime(timeToAdd);
128 return implicitAtWindowEnd;
132 auto explicitAtWindowEnd =
false;
134 explicitAtWindowEnd |= scheme->addComputedTime(timeToAdd);
137 if (implicitAtWindowEnd) {
138 PRECICE_DEBUG(
"Implicit scheme reached the end of the first iteration at t={}. "
139 "Explicit schemes are on hold until convergence achieved.",
146 return implicitAtWindowEnd || explicitAtWindowEnd;
156 auto remoteChanges = scheme->firstSynchronization(changes);
157 totalChanges.
insert(totalChanges.
end(), remoteChanges.begin(), remoteChanges.end());
168 scheme->firstExchange();
181 scheme->firstExchange();
191 auto remoteChanges = scheme->secondSynchronization();
192 totalChanges.
insert(totalChanges.
end(), remoteChanges.begin(), remoteChanges.end());
203 scheme->secondExchange();
213 bool iterating = implicitTime < explicitTime;
216 PRECICE_DEBUG(
"Implicit scheme hasn't converged. Explicit schemes remain on hold.");
220 PRECICE_DEBUG(
"Implicit scheme converged. Running explicit schemes.");
223 scheme->firstExchange();
226 scheme->secondSynchronization();
229 scheme->secondExchange();
231 PRECICE_DEBUG(
"Explicit schemes caught up. All schemes are in sync.");
250 auto subpartners = scheme->getCouplingPartners();
251 partners.
insert(partners.
end(), subpartners.begin(), subpartners.end());
268 bool willBeExchanged =
std::any_of(schemes.begin(), schemes.end(),
269 [lastSolverTimeStepSize](
const auto &cpl) { return cpl->willDataBeExchanged(lastSolverTimeStepSize); });
271 return willBeExchanged;
281 return hasBeenReceived;
302 schemes.begin(), schemes.end(),
314 schemes.begin(), schemes.end(),
382 return isOneCompleted;
389 bool isRequired =
false;
392 if (scheme->isActionRequired(action)) {
405 bool isFulfilled =
false;
407 if (scheme->isActionFulfilled(action)) {
421 if (scheme->isActionRequired(action)) {
422 scheme->markActionFulfilled(action);
440 if (not state.
empty()) {
443 partners = scheme->getCouplingPartners();
444 state += partners[0];
446 state += scheme->printCouplingState();
509 if (scheme->requiresSubsteps()) {
#define PRECICE_WARN(...)
#define PRECICE_DEBUG(...)
#define PRECICE_TRACE(...)
#define PRECICE_ASSERT(...)
#define PRECICE_UNREACHABLE(...)
bool requiresSubsteps() const override final
Returns true if any send data of the scheme requires substeps.
PtrCouplingScheme _implicitScheme
The optional implicit scheme to be handled last.
ChangedMeshes secondSynchronization() override
void initialize(double startTime, int startTimeWindow) final override
Initializes the coupling scheme and establishes a communication connection to the coupling partner.
std::vector< CouplingScheme * > activeOrAllSchemes() const
Actions also work before initialize is called.
bool isTimeWindowComplete() const final override
Returns true, when the accessor can advance to the next time window.
bool hasConverged() const final
True if the implicit scheme has converged or no implicit scheme is defined.
std::vector< CouplingScheme * > allSchemes() const
Returns all schemes in execution order, explicit as well as implicit.
void updateActiveSchemes()
void finalize() final override
Finalizes the coupling and disconnects communication.
bool isImplicitCouplingScheme() const final
True if one cplscheme is an implicit scheme.
std::vector< CouplingScheme * > _activeSchemes
double getTimeWindowStart() const override final
bool isCouplingOngoing() const final override
Returns true, when the coupled simulation is still ongoing.
double getTime() const final override
Returns the currently computed time of the coupling scheme.
std::vector< std::string > getCouplingPartners() const final override
Returns list of all coupling partners.
Schemes _explicitSchemes
Explicit coupling schemes to be executed.
double getTimeWindowSize() const final override
Returns the time window size, if one is given by the coupling scheme.
void secondExchange() override
bool isActionRequired(Action action) const final override
Returns true, if the given action has to be performed by the accessor.
void markActionFulfilled(Action action) final override
Tells the coupling scheme that the accessor has performed the given action.
bool addComputedTime(double timeToAdd) final override
Adds newly computed time. Has to be called before every advance.
std::string localParticipant() const override final
Returns the name of the local participant.
bool hasDataBeenReceived() const final override
checks all coupling schemes this coupling scheme is composed of.
int getTimeWindows() const final override
Returns the currently computed time windows of the coupling scheme.
void requireAction(Action action) final override
Sets an action required to be performed by the accessor.
bool isInitialized() const final override
Returns true, if initialize has been called.
bool _explicitOnHold
Are explicit schemes on hold?
double getNextTimeStepMaxSize() const final override
Returns the maximal size of the next time step to be computed.
bool hasTimeWindowSize() const final override
Returns true, if time window size is given by any of the coupling schemes in this compositional coupl...
void addCouplingScheme(const PtrCouplingScheme &scheme)
Adds another coupling scheme in parallel to this scheme.
void firstExchange() override
ChangedMeshes firstSynchronization(const ChangedMeshes &changes) override
Exchanges data and updates the state of the coupling scheme.
bool willDataBeExchanged(double lastSolverTimeStepSize) const final override
Returns true, if data will be exchanged when calling advance().
void checkCompatibleTimeWindowSizes(const CouplingScheme &impl, const CouplingScheme &expl) const
check if time windows are compatible
std::string printCouplingState() const final override
Returns a string representation of the current coupling state.
bool sendsInitializedData() const override final
Returns true, if any of the composed coupling schemes sendsInitializedData for this participant.
ImplicitData implicitDataToReceive() const override final
Returns a vector of implicit data to receive in the next advance.
bool isActionFulfilled(Action action) const final override
Returns true, if the given action has been performed by the accessor.
Interface for all coupling schemes.
Action
Actions that are required by CouplingSchemes.
virtual std::vector< std::string > getCouplingPartners() const =0
Returns list of all coupling partners.
virtual double getTimeWindowStart() const =0
virtual bool isInitialized() const =0
Returns true, if initialize has been called.
virtual double getNextTimeStepMaxSize() const =0
Returns the maximal size of the next time step to be computed.
virtual bool isTimeWindowComplete() const =0
Returns true, when the accessor can advance to the next time window.
virtual double getTimeWindowSize() const =0
Returns the time window size, if one is given by the coupling scheme.
virtual bool sendsInitializedData() const =0
Returns whether this participant of the coupling scheme sends initialized data.
virtual int getTimeWindows() const =0
Returns the currently computed time windows of the coupling scheme.
virtual bool hasDataBeenReceived() const =0
Returns true, if data has been exchanged in last call of advance().
virtual std::string localParticipant() const =0
Returns the name of the local participant.
T emplace_back(T... args)
contains implementations of coupling schemes for coupled simulations.
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.