preCICE v3.1.1
Loading...
Searching...
No Matches
AitkenAcceleration.cpp
Go to the documentation of this file.
2#include <Eigen/Core>
3#include <boost/range/adaptor/map.hpp>
4#include <cmath>
5#include <cstddef>
6#include <limits>
7#include <map>
8#include <memory>
9#include <numeric>
10#include <ostream>
11#include <utility>
12
14#include "logging/LogMacros.hpp"
15#include "math/math.hpp"
17#include "utils/Helpers.hpp"
18#include "utils/IntraComm.hpp"
19#include "utils/assertion.hpp"
20
21namespace precice::acceleration {
22
24 std::vector<int> dataIDs,
25 impl::PtrPreconditioner preconditioner)
26 : _initialRelaxation(initialRelaxation),
27 _dataIDs(std::move(dataIDs)),
28 _aitkenFactor(initialRelaxation),
29 _preconditioner(std::move(preconditioner))
30{
32 "Initial relaxation factor for Aitken acceleration has to "
33 "be larger than zero and smaller or equal to one. "
34 "Current initial relaxation is: {}",
36}
37
39{
40 checkDataIDs(cplData);
41 for (const auto &data : cplData | boost::adaptors::map_values) {
42 PRECICE_CHECK(!data->exchangeSubsteps(),
43 "Aitken acceleration does not yet support using data from all substeps. Please set substeps=\"false\" in the exchange tag of data \"{}\".", data->getDataName());
44 }
45
46 // Accumulate number of entries
47 // Size for each subvector needed for preconditioner
48 std::vector<std::size_t> subVectorSizes;
49 // Gather sizes
50 std::transform(_dataIDs.cbegin(), _dataIDs.cend(), std::back_inserter(subVectorSizes), [&cplData](const auto &d) { return cplData.at(d)->getSize(); });
51 // The accumulated sum
52 Eigen::Index entries = std::accumulate(subVectorSizes.cbegin(), subVectorSizes.cend(), static_cast<Eigen::Index>(0));
53
54 // Allocate memory
55 _oldResiduals = Eigen::VectorXd::Zero(entries);
56 _values = Eigen::VectorXd::Zero(entries);
57 _oldValues = Eigen::VectorXd::Zero(entries);
58 if (_dataIDs.size() > 1) {
59 _preconditioner->initialize(subVectorSizes);
60 }
61}
62
64 DataMap &cplData)
65{
67
68 // Compute aitken relaxation factor
70
72
73 // Compute current residual = values - oldValues
74 Eigen::VectorXd residuals = _values - _oldValues;
75
76 // Compute residual deltas (= residuals - oldResiduals) and store it in _oldResiduals
77 Eigen::VectorXd residualDeltas = residuals - _oldResiduals;
78
79 // We need to update the preconditioner in every iteration
80 if (_dataIDs.size() > 1) {
81 _preconditioner->update(false, _values, residuals);
82 }
83
84 // Select/compute aitken factor depending on current iteration count
85 if (_iterationCounter == 0) {
86 // preconditioner not necessary
88 } else {
89 // If we have more than one data set, we scale the data to get a better approximation
90 // of the Aitken factor
91 if (_dataIDs.size() > 1) {
92 _preconditioner->apply(residualDeltas);
94 }
95 // compute fraction of aitken factor with residuals and residual deltas
96 double nominator = utils::IntraComm::dot(_oldResiduals, residualDeltas);
97 double denominator = utils::IntraComm::dot(residualDeltas, residualDeltas);
98 _aitkenFactor = -_aitkenFactor * (nominator / denominator);
99 }
100
101 PRECICE_DEBUG("AitkenFactor: {}", _aitkenFactor);
102
103 // Perform relaxation with aitken factor
105
106 // Store residuals for next iteration
107 _oldResiduals = std::move(residuals);
108
110}
111
113 const DataMap &cplData)
114{
116 if (_dataIDs.size() > 1) {
117 _preconditioner->update(true, _values, _oldResiduals);
118 }
119 _oldResiduals = Eigen::VectorXd::Constant(_oldResiduals.size(), std::numeric_limits<double>::max());
120}
121
122} // namespace precice::acceleration
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:64
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:95
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:35
T accumulate(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:87
T back_inserter(T... args)
T cbegin(T... args)
void checkDataIDs(const DataMap &cplData) const
Checks if all dataIDs are contained in cplData.
static void applyRelaxation(double omega, DataMap &cplData)
performs a relaxation given a relaxation factor omega
void concatenateCouplingData(const DataMap &cplData, const std::vector< DataID > &dataIDs, Eigen::VectorXd &targetValues, Eigen::VectorXd &targetOldValues) const
Concatenates all coupling data involved into a single vector.
AitkenAcceleration(double initialRelaxationFactor, std::vector< int > dataIDs, impl::PtrPreconditioner preconditioner)
virtual void iterationsConverged(const DataMap &cpldata)
virtual void performAcceleration(DataMap &cpldata)
virtual void initialize(const DataMap &cpldata)
impl::PtrPreconditioner _preconditioner
Preconditioner for data vector if multiple data sets are used.
static double dot(const Eigen::VectorXd &vec1, const Eigen::VectorXd &vec2)
T cend(T... args)
T min(T... args)
contains implementations of acceleration schemes.
int sign(double number)
Return the sign, one of {-1, 0, 1}.
Definition math.hpp:11
bool contained(const ELEMENT_T &element, const std::vector< ELEMENT_T > &vec)
Returns true, if given element is in vector, otherwise false.
Definition Helpers.hpp:39
STL namespace.
T size(T... args)
T transform(T... args)