preCICE v3.3.0
Loading...
Searching...
No Matches
BaseQNAcceleration.cpp
Go to the documentation of this file.
2#include <Eigen/Core>
3#include <boost/range/adaptor/map.hpp>
4#include <cmath>
5#include <memory>
6#include <utility>
7
10#include "com/Communication.hpp"
11#include "com/SharedPointer.hpp"
13#include "logging/LogMacros.hpp"
14#include "mesh/Mesh.hpp"
16#include "profiling/Event.hpp"
17#include "time/TimeGrids.hpp"
19#include "utils/Helpers.hpp"
20#include "utils/IntraComm.hpp"
21#include "utils/assertion.hpp"
22
23namespace precice {
24namespace io {
25class TXTReader;
26class TXTWriter;
27} // namespace io
28namespace acceleration {
29
30/* ----------------------------------------------------------------------------
31 * Constructor
32 * ----------------------------------------------------------------------------
33 */
35 double initialRelaxation,
36 bool forceInitialRelaxation,
37 int maxIterationsUsed,
38 int timeWindowsReused,
39 int filter,
40 double singularityLimit,
41 std::vector<int> dataIDs,
42 impl::PtrPreconditioner preconditioner,
43 bool reducedTimeGrid)
44 : _preconditioner(std::move(preconditioner)),
45 _initialRelaxation(initialRelaxation),
46 _maxIterationsUsed(maxIterationsUsed),
47 _timeWindowsReused(timeWindowsReused),
48 _primaryDataIDs(std::move(dataIDs)),
49 _forceInitialRelaxation(forceInitialRelaxation),
50 _reducedTimeGrid(reducedTimeGrid),
51 _qrV(filter),
52 _filter(filter),
53 _singularityLimit(singularityLimit),
54 _infostringstream(std::ostringstream::ate)
55{
57 "Initial relaxation factor for QN acceleration has to "
58 "be larger than zero and smaller or equal than one. "
59 "Current initial relaxation is {}",
62 "Maximum number of iterations used in the quasi-Newton acceleration "
63 "scheme has to be larger than zero. "
64 "Current maximum reused iterations is {}",
67 "Number of previous time windows to be reused for "
68 "quasi-Newton acceleration has to be larger than or equal to zero. "
69 "Current number of time windows reused is {}",
71}
72
80 const DataMap &cplData)
81{
82 PRECICE_TRACE(cplData.size());
83
84 for (const DataMap::value_type &pair : cplData) {
85 PRECICE_ASSERT(pair.second->getSize() == pair.second->getPreviousIterationSize(), "current and previousIteration have to be initialized and of identical size.",
86 pair.second->getSize(), pair.second->getPreviousIterationSize());
87 }
88
90 std::any_of(cplData.cbegin(), cplData.cend(), [](const auto &p) { return p.second->hasGradient(); }),
91 "Gradient data, which is required by at least one of the configured data mappings, is not yet compatible with quasi-Newton acceleration. This combination might lead to numerical issues. "
92 "Consider switching to a different acceleration scheme or a different data mapping scheme.");
93
94 checkDataIDs(cplData);
95 // store all data IDs in vector
96 _dataIDs.clear();
97 for (const DataMap::value_type &pair : cplData) {
98 _dataIDs.push_back(pair.first);
99 }
100
101 _matrixCols.clear();
102 _matrixCols.push_front(0);
103 _firstIteration = true;
104 _firstTimeWindow = true;
105}
106
115 const DataMap &cplData)
116{
118
119 // Compute current residual: vertex-data - oldData
124
126 "The coupling residual equals almost zero. There is maybe something wrong in your adapter. "
127 "Maybe you always write the same data or you call advance without "
128 "providing new data first or you do not use available read data. "
129 "Or you just converge much further than actually necessary.");
130
131 // if (_firstIteration && (_firstTimeWindow || (_matrixCols.size() < 2))) {
133 // do nothing: constant relaxation
134 } else {
135 PRECICE_DEBUG(" Update Difference Matrices");
136 if (not _firstIteration) {
137 // Update matrices V, W with newest information
138
139 PRECICE_ASSERT(_matrixV.cols() == _matrixW.cols(), _matrixV.cols(), _matrixW.cols());
141
144 "The number of columns in the least squares system exceeded half the number of unknowns at the interface. "
145 "The system will probably become bad or ill-conditioned and the quasi-Newton acceleration may not "
146 "converge. Maybe the number of allowed columns (\"max-used-iterations\") should be limited.");
147
148 Eigen::VectorXd deltaR = _primaryResiduals;
149 deltaR -= _oldPrimaryResiduals;
150
151 Eigen::VectorXd deltaXTilde = _values;
152 deltaXTilde -= _oldXTilde;
153
154 double residualMagnitude = utils::IntraComm::l2norm(deltaR);
155
157 residualMagnitude /= utils::IntraComm::l2norm(_primaryValues);
158 }
160 math::equals(residualMagnitude, 0.0),
161 "Adding a vector with a two-norm of {} to the quasi-Newton V matrix, which will lead to "
162 "ill-conditioning. A filter might delete the column again. Still, this could mean that you are "
163 "converging too tightly, that you reached steady-state, or that you are giving by mistake identical "
164 "data to preCICE in two consecutive iterations.",
165 residualMagnitude);
166
167 bool columnLimitReached = getLSSystemCols() == _maxIterationsUsed;
168 bool overdetermined = getLSSystemCols() <= getLSSystemRows();
169 if (not columnLimitReached && overdetermined) {
170
172 utils::appendFront(_matrixW, deltaXTilde);
173
174 // insert column deltaR = _primaryResiduals - _oldPrimaryResiduals at pos. 0 (front) into the
175 // QR decomposition and update decomposition
176
177 // apply scaling here
178 _preconditioner->apply(deltaR);
179 _qrV.pushFront(deltaR);
180
181 _matrixCols.front()++;
182 } else {
184 utils::shiftSetFirst(_matrixW, deltaXTilde);
185
186 // inserts column deltaR at pos. 0 to the QR decomposition and deletes the last column
187 // the QR decomposition of V is updated
188 _preconditioner->apply(deltaR);
189 _qrV.pushFront(deltaR);
190 _qrV.popBack();
191
192 _matrixCols.front()++;
193 _matrixCols.back()--;
194 if (_matrixCols.back() == 0) {
195 _matrixCols.pop_back();
196 }
197 _nbDropCols++;
198 }
199 }
200 _oldPrimaryResiduals = _primaryResiduals; // Store residuals
201 _oldPrimaryXTilde = _primaryValues; // Store x_tilde
202 _oldXTilde = _values; // Store coupling x_tilde
203 }
204}
205
213 DataMap &cplData,
214 double windowStart,
215 double windowEnd)
216{
217 PRECICE_TRACE(_primaryDataIDs.size(), cplData.size());
218
219 profiling::Event e("cpl.computeQuasiNewtonUpdate", profiling::Synchronize);
220
221 // We can only initialize here since we need to know the time grid already.
223 initializeVectorsAndPreconditioner(cplData, windowStart);
224 }
225
230
231 // Needs to be called in the first iteration of each time window.
232 if (_firstIteration) {
233 _timeGrids.value().moveTimeGridToNewWindow(cplData);
234 _primaryTimeGrids.value().moveTimeGridToNewWindow(cplData);
235 }
236
239 concatenateCouplingData(_values, _oldValues, cplData, _dataIDs, _timeGrids.value(), windowStart);
241
248
250 PRECICE_DEBUG(" Performing underrelaxation");
251 _oldPrimaryXTilde = _primaryValues; // Store x tilde of primary data
252 _oldXTilde = _values; // Store x tilde of primary and secondary data
253 _oldPrimaryResiduals = _primaryResiduals; // Store current residual of primary data
254
255 applyRelaxation(_initialRelaxation, cplData, windowStart);
256 its++;
257 _firstIteration = false;
258 return;
259 }
260
261 PRECICE_DEBUG(" Performing quasi-Newton Step");
262
263 // If the previous time window converged within one single iteration, nothing was added
264 // to the LS system matrices and they need to be restored from the backup at time T-2
266 PRECICE_DEBUG(" Last time window converged after one iteration. Need to restore the matrices from backup.");
267
271
272 // re-computation of QR decomposition from _matrixV = _matrixVBackup
273 // this occurs very rarely, to be precise, it occurs only if the coupling terminates
274 // after the first iteration and the matrix data from time window t-2 has to be used
276 _qrV.reset(_matrixV, getLSSystemRows());
277 _preconditioner->revert(_matrixV);
278 _resetLS = true; // need to recompute _Wtil, Q, R (only for IMVJ efficient update)
279 }
280
288
289 // apply scaling to V, V' := P * V (only needed to reset the QR-dec of V)
291
292 if (_preconditioner->requireNewQR()) {
293 if (not(_filter == Acceleration::QR2FILTER || _filter == Acceleration::QR3FILTER)) { // for QR2 and QR3 filter, there is no need to do this twice
294 _qrV.reset(_matrixV, getLSSystemRows());
295 }
296 if (_filter == Acceleration::QR3FILTER) { // QR3 filter needs to recompute QR3 filter
297 _qrV.requireQR3Fallback();
298 }
299 _preconditioner->newQRfulfilled();
300 }
301
302 if (_firstIteration) {
303 _nbDelCols = 0;
304 _nbDropCols = 0;
305 }
306
307 // apply the configured filter to the LS system
308 profiling::Event applyingFilter("ApplyFilter");
309 applyFilter();
310 applyingFilter.stop();
311
312 // revert scaling of V, in computeQNUpdate all data objects are unscaled.
313 _preconditioner->revert(_matrixV);
314
320 Eigen::VectorXd xUpdate = Eigen::VectorXd::Zero(_values.size());
321 computeQNUpdate(xUpdate);
322
323 // Apply the quasi-Newton update
324 _values += xUpdate;
325
326 // pending deletion: delete old V, W matrices if timeWindowsReused = 0
327 // those were only needed for the first iteration (instead of underrelax.)
329 // save current matrix data in case the coupling for the next time window will terminate
330 // after the first iteration (no new data, i.e., V = W = 0)
331 if (getLSSystemCols() > 0) {
335 }
336 // if no time windows reused, the matrix data needs to be cleared as it was only needed for the
337 // QN-step in the first iteration (idea: rather perform QN-step with information from last converged
338 // time window instead of doing a underrelaxation)
339 if (not _firstTimeWindow) {
340 _matrixV.resize(0, 0);
341 _matrixW.resize(0, 0);
342 _matrixCols.clear();
343 _matrixCols.push_front(0); // vital after clear()
344 _qrV.reset();
345 // set the number of global rows in the QRFactorization.
346 _qrV.setGlobalRows(getPrimaryLSSystemRows());
347 _resetLS = true; // need to recompute _Wtil, Q, R (only for IMVJ efficient update)
348 }
349 }
350
353 "The quasi-Newton update contains NaN values. This means that the quasi-Newton acceleration failed to converge. "
354 "When writing your own adapter this could indicate that you give wrong information to preCICE, such as identical "
355 "data in succeeding iterations. Or you do not properly save and reload checkpoints. "
356 "If you give the correct data this could also mean that the coupled problem is too hard to solve. Try to use a QR "
357 "filter or increase its threshold (larger epsilon).");
358
359 // updates the waveform and values in coupling data by splitting the primary and secondary data back into the individual data objects
360 updateCouplingData(cplData, windowStart);
361
362 // number of iterations (usually equals number of columns in LS-system)
363 its++;
364 _firstIteration = false;
365}
366
368{
370
372 // do nothing
373 } else {
374 // do: filtering of least-squares system to maintain good conditioning
375 std::vector<int> delIndices(0);
376 _qrV.applyFilter(_singularityLimit, delIndices, _matrixV);
377 // start with largest index (as V,W matrices are shrunk and shifted
378
379 for (int i = delIndices.size() - 1; i >= 0; i--) {
380
381 removeMatrixColumn(delIndices[i]);
382
383 PRECICE_DEBUG(" Filter: removing column with index {} in iteration {} of time window: {}", delIndices[i], its, tWindows);
384 }
385 PRECICE_ASSERT(_matrixV.cols() == _qrV.cols(), _matrixV.cols(), _qrV.cols());
386 }
387}
388
390 const DataMap &cplData, double windowStart)
391{
392
394 // offset to keep track of the position in xUpdate
395 Eigen::Index offset = 0;
396
397 for (int id : _dataIDs) {
398
399 auto &couplingData = *cplData.at(id);
400 size_t dataSize = couplingData.getSize();
401
402 Eigen::VectorXd timeGrid = _timeGrids->getTimeGridAfter(id, windowStart);
403 couplingData.timeStepsStorage().trimAfter(windowStart);
404 for (int i = 0; i < timeGrid.size(); i++) {
405
406 Eigen::VectorXd temp = Eigen::VectorXd::Zero(dataSize);
407 for (size_t j = 0; j < dataSize; j++) {
408 temp(j) = _values(offset + j);
409 }
410 offset += dataSize;
411
412 couplingData.setSampleAtTime(timeGrid(i), time::Sample(couplingData.getDimensions(), temp));
413 }
414 }
415}
416
426 const DataMap &cplData, double windowStart)
427{
429
431 _infostringstream << "# time window " << tWindows << " converged #\n iterations: " << its
432 << "\n used cols: " << getLSSystemCols() << "\n del cols: " << _nbDelCols << '\n';
433
434 its = 0;
435 tWindows++;
436
437 // the most recent differences for the V, W matrices have not been added so far
438 // this has to be done in iterations converged, as PP won't be called any more if
439 // convergence was achieved
440
441 // If, in the first time window, we converge already in the first iteration, we have not yet initialized. Then, we need to do it here.
443 initializeVectorsAndPreconditioner(cplData, windowStart);
444 }
445
446 // Needs to be called in the first iteration of each time window.
447 if (_firstIteration) {
448 _timeGrids->moveTimeGridToNewWindow(cplData);
449 _primaryTimeGrids->moveTimeGridToNewWindow(cplData);
450 }
453 concatenateCouplingData(_values, _oldValues, cplData, _dataIDs, _timeGrids.value(), windowStart);
456
457 if (not _matrixCols.empty() && _matrixCols.front() == 0) { // Did only one iteration
458 _matrixCols.pop_front();
459 }
460
461#ifndef NDEBUG
462 std::ostringstream stream;
463 stream << "Matrix column counters: ";
464 for (int cols : _matrixCols) {
465 stream << cols << ", ";
466 }
467 PRECICE_DEBUG(stream.str());
468#endif // Debug
469
470 // doing specialized stuff for the corresponding acceleration scheme after
471 // convergence of iteration i.e.:
472 // - analogously to the V,W matrices, remove columns from matrices for secondary data
473 // - save the old Jacobian matrix
475
476 // if we already have convergence in the first iteration of the first time window
477 // we need to do underrelaxation in the first iteration of the second time window
478 // so "_firstTimeWindow" is slightly misused, but still the best way to understand
479 // the concept
480 if (not _firstIteration)
481 _firstTimeWindow = false;
482
483 // update preconditioner depending on residuals or values (must be after specialized iterations converged --> IMVJ)
485
486 if (_timeWindowsReused == 0) {
488 _matrixV.resize(0, 0);
489 _matrixW.resize(0, 0);
490 _qrV.reset();
491 // set the number of global rows in the QRFactorization.
492 _qrV.setGlobalRows(getPrimaryLSSystemRows());
493 _matrixCols.clear(); // _matrixCols.push_front() at the end of the method.
494 } else {
500 }
501 } else if (static_cast<int>(_matrixCols.size()) > _timeWindowsReused) {
502 int toRemove = _matrixCols.back();
503 _nbDropCols += toRemove;
504 PRECICE_ASSERT(toRemove > 0, toRemove);
505 PRECICE_DEBUG("Removing {} cols from least-squares system with {} cols", toRemove, getLSSystemCols());
506 PRECICE_ASSERT(_matrixV.cols() == _matrixW.cols(), _matrixV.cols(), _matrixW.cols());
507 PRECICE_ASSERT(getLSSystemCols() > toRemove, getLSSystemCols(), toRemove);
508
509 // remove columns
510 for (int i = 0; i < toRemove; i++) {
513 // also remove the corresponding columns from the dynamic QR-descomposition of _matrixV
514 _qrV.popBack();
515 }
516 _matrixCols.pop_back();
517 }
518
519 _matrixCols.push_front(0);
520 _firstIteration = true;
521}
522
530 int columnIndex)
531{
532 PRECICE_TRACE(columnIndex, _matrixV.cols());
533
534 _nbDelCols++;
535
536 PRECICE_ASSERT(_matrixV.cols() > 1);
539
540 // Reduce column count
541 std::deque<int>::iterator iter = _matrixCols.begin();
542 int cols = 0;
543 while (iter != _matrixCols.end()) {
544 cols += *iter;
545 if (cols > columnIndex) {
546 PRECICE_ASSERT(*iter > 0);
547 *iter -= 1;
548 if (*iter == 0) {
549 _matrixCols.erase(iter);
550 }
551 break;
552 }
553 iter++;
554 }
555}
556
561
566
568{
569 return _nbDelCols;
570}
571
573{
574 return _nbDropCols;
575}
576
578{
579 int cols = 0;
580 for (int col : _matrixCols) {
581 cols += col;
582 }
584 PRECICE_ASSERT(cols == _matrixV.cols(), cols, _matrixV.cols(), _matrixCols, _qrV.cols());
585 PRECICE_ASSERT(cols == _matrixW.cols(), cols, _matrixW.cols());
586 }
587
588 return cols;
589}
590
595
600
602{
604 return _dimOffsets.back();
605 }
606 return _residuals.size();
607}
608
610{
612 return _dimOffsetsPrimary.back();
613 }
614 return _primaryResiduals.size();
615}
616
618 const std::string &s, bool allProcs)
619{
621 // serial acceleration mode
623
624 // parallel acceleration
625 } else {
626 if (not allProcs) {
629 } else {
631 }
632 }
634}
635
636void BaseQNAcceleration::concatenateCouplingData(Eigen::VectorXd &data, Eigen::VectorXd &oldData, const DataMap &cplData, std::vector<int> dataIDs, precice::time::TimeGrids timeGrids, double windowStart) const
637{
638 Eigen::Index offset = 0;
639 for (int id : dataIDs) {
640 Eigen::Index dataSize = cplData.at(id)->getSize();
641 Eigen::VectorXd timeGrid = timeGrids.getTimeGridAfter(id, windowStart);
642
643 for (int i = 0; i < timeGrid.size(); i++) {
644
645 auto current = cplData.at(id)->timeStepsStorage().sample(timeGrid(i));
646 auto old = cplData.at(id)->getPreviousValuesAtTime(timeGrid(i));
647
648 PRECICE_ASSERT(data.size() >= offset + dataSize, "the values were not initialized correctly");
649 PRECICE_ASSERT(oldData.size() >= offset + dataSize, "the values were not initialized correctly");
650
651 for (Eigen::Index i = 0; i < dataSize; i++) {
652 data(i + offset) = current(i);
653 oldData(i + offset) = old(i);
654 }
655 offset += dataSize;
656 }
657 }
658}
659
661{
662 // Saves the time grid of each waveform in the data field to be used in the QN method
663 _timeGrids.emplace(cplData, _dataIDs, false);
665
666 // Helper function
667 auto addTimeSliceSize = [&](size_t sum, int id, precice::time::TimeGrids timeGrids) { return sum + timeGrids.getTimeGridAfter(id, windowStart).size() * cplData.at(id)->getSize(); };
668
669 // Size of primary data
670 const size_t primaryDataSize = std::accumulate(_primaryDataIDs.begin(), _primaryDataIDs.end(), (size_t) 0, [&](size_t sum, int id) { return addTimeSliceSize(sum, id, _primaryTimeGrids.value()); });
671
672 // Size of values
673 const size_t dataSize = std::accumulate(_dataIDs.begin(), _dataIDs.end(), (size_t) 0, [&](size_t sum, int id) { return addTimeSliceSize(sum, id, _timeGrids.value()); });
674
675 _values = Eigen::VectorXd::Zero(dataSize);
676 _oldValues = Eigen::VectorXd::Zero(dataSize);
677 _oldXTilde = Eigen::VectorXd::Zero(dataSize);
678 _residuals = Eigen::VectorXd::Zero(dataSize);
679 _primaryValues = Eigen::VectorXd::Zero(primaryDataSize);
680 _oldPrimaryValues = Eigen::VectorXd::Zero(primaryDataSize);
681 _oldPrimaryXTilde = Eigen::VectorXd::Zero(primaryDataSize);
682 _primaryResiduals = Eigen::VectorXd::Zero(primaryDataSize);
683 _oldPrimaryResiduals = Eigen::VectorXd::Zero(primaryDataSize);
684
685 // Also clear the matrices, since the initialization phase will be called more than once when using remeshing
686 _matrixW.resize(0, 0);
687 _matrixV.resize(0, 0);
688
697
698 if (primaryDataSize <= 0) {
699 _hasNodesOnInterface = false;
700 }
701
709 _dimOffsets[0] = 0;
710 _dimOffsetsPrimary[0] = 0;
711 for (size_t i = 0; i < _dimOffsets.size() - 1; i++) {
712 int accumulatedNumberOfUnknowns = 0;
713 int accumulatedNumberOfPrimaryUnknowns = 0;
714
715 for (auto &elem : _dataIDs) {
716 const auto &offsets = cplData.at(elem)->getVertexOffsets();
717
718 accumulatedNumberOfUnknowns += offsets[i] * cplData.at(elem)->getDimensions() * _timeGrids.value().getTimeGridAfter(elem, windowStart).size();
719
721 accumulatedNumberOfPrimaryUnknowns += offsets[i] * cplData.at(elem)->getDimensions() * _primaryTimeGrids.value().getTimeGridAfter(elem, windowStart).size();
722 }
723 }
724 _dimOffsets[i + 1] = accumulatedNumberOfUnknowns;
725 _dimOffsetsPrimary[i + 1] = accumulatedNumberOfPrimaryUnknowns;
726 }
727
728 PRECICE_DEBUG("Number of unknowns at the interface (global): {}", _dimOffsets.back());
730 _infostringstream << fmt::format("\n--------\n DOFs (global): {}\n offsets: {}\n", _dimOffsets.back(), _dimOffsets);
731 }
732
733 // test that the computed number of unknown per proc equals the number of primaryDataSize actually present on that proc
735 PRECICE_ASSERT(dataSize == unknowns, dataSize, unknowns);
737 PRECICE_ASSERT(primaryDataSize == primaryUnknowns, primaryDataSize, primaryUnknowns);
738 } else {
739 _infostringstream << fmt::format("\n--------\n DOFs (global): {}\n", dataSize);
740 }
741
742 // set the number of global rows in the QRFactorization.
743 _qrV.reset();
744 _qrV.setGlobalRows(getPrimaryLSSystemRows());
745
746 std::vector<size_t> subVectorSizes; // needed for preconditioner
747 std::transform(_primaryDataIDs.cbegin(), _primaryDataIDs.cend(), std::back_inserter(subVectorSizes), [&cplData, windowStart, this](const auto &d) { return _primaryTimeGrids.value().getTimeGridAfter(d, windowStart).size() * cplData.at(d)->getSize(); });
748 _preconditioner->initialize(subVectorSizes);
749
751}
752
753} // namespace acceleration
754} // namespace precice
#define PRECICE_WARN_IF(condition,...)
Definition LogMacros.hpp:18
#define PRECICE_DEBUG(...)
Definition LogMacros.hpp:61
#define PRECICE_TRACE(...)
Definition LogMacros.hpp:92
#define PRECICE_CHECK(check,...)
Definition LogMacros.hpp:32
T accumulate(T... args)
T any_of(T... args)
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
T at(T... args)
T back_inserter(T... args)
T cbegin(T... args)
static void applyRelaxation(double omega, DataMap &cplData, double windowStart)
performs a relaxation given a relaxation factor omega
void checkDataIDs(const DataMap &cplData) const
Checks if all dataIDs are contained in cplData.
std::map< int, cplscheme::PtrCouplingData > DataMap
Map from data ID to data values.
virtual void updateDifferenceMatrices(const DataMap &cplData)
Updates the V, W matrices (as well as the matrices for the secondary data)
const double _initialRelaxation
Constant relaxation factor used for first iteration.
virtual void computeQNUpdate(Eigen::VectorXd &xUpdate)=0
Computes the quasi-Newton update using the specified pp scheme (IQNIMVJ, IQNILS)
std::vector< int > _dimOffsetsPrimary
Stores the local dimensions regarding primary data,.
Eigen::VectorXd _oldPrimaryValues
Concatenation of all old primary data involved in the QN system.
int getLSSystemCols() const
: computes number of cols in least squares system, i.e, number of cols in _matrixV,...
int _nbDelCols
Number of filtered out columns in this time window.
void concatenateCouplingData(Eigen::VectorXd &data, Eigen::VectorXd &oldData, const DataMap &cplData, std::vector< int > dataIDs, precice::time::TimeGrids timeGrids, double windowStart) const
Samples and concatenates the data and old data in cplData into a long vector.
virtual void specializedIterationsConverged(const DataMap &cplData)=0
Marks a iteration sequence as converged.
virtual void applyFilter()
Applies the filter method for the least-squares system, defined in the configuration.
Eigen::VectorXd _oldValues
Concatenation of all old primary and secondary data involved in the QN system.
int getMaxUsedTimeWindows() const
Get the maximum number of reused time windows.
int getMaxUsedIterations() const
Get the maximum number of reused iterations.
Eigen::MatrixXd _matrixVBackup
backup of the V,W and matrixCols data structures. Needed for the skipping of initial relaxation,...
Eigen::VectorXd _oldXTilde
Solver output from last iteration.
Eigen::VectorXd _primaryResiduals
Current iteration residuals of primary IQN data. Temporary.
std::ostringstream _infostringstream
write some debug/acceleration info to file
virtual void updateCouplingData(const DataMap &cplData, double windowStart)
Splits up QN system vector back into the waveforms in coupling data.
bool _resetLS
If true, the LS system has been modified (reset or recomputed) in such a way, that mere updating of m...
void importState(io::TXTReader &reader) final override
Imports the last exported state of the acceleration from file.
Eigen::VectorXd _primaryValues
Concatenation of all primary data involved in the QN system.
int _nbDropCols
Number of dropped columns in this time window (old time window out of scope)
int getDroppedColumns() const
how many QN columns were dropped (went out of scope) in this time window
const int _filter
filter method that is used to maintain good conditioning of the least-squares system Either of two ty...
Eigen::MatrixXd _matrixV
Stores residual deltas.
std::vector< int > _dimOffsets
Stores the local dimensions, i.e., the offsets in _invJacobian for all processors.
const double _singularityLimit
Determines sensitivity when two matrix columns are considered equal.
const int _maxIterationsUsed
Maximum number of old data iterations kept.
void exportState(io::TXTWriter &writer) final override
Exports the current state of the acceleration to a file.
Eigen::VectorXd _residuals
Current iteration residuals of IQN data. Temporary.
std::optional< time::TimeGrids > _primaryTimeGrids
Stores the time grids to which the primary data involved in the QN system will be interpolated to....
virtual void specializedInitializeVectorsAndPreconditioner(const DataMap &cplData)=0
handles the initialization of matrices and vectors in the sub-classes
virtual void removeMatrixColumn(int columnIndex)
Removes one iteration from V,W matrices and adapts _matrixCols.
Eigen::MatrixXd _matrixW
Stores x tilde deltas, where x tilde are values computed by solvers.
Eigen::VectorXd _values
Concatenation of all primary and secondary data involved in the QN system.
std::optional< time::TimeGrids > _timeGrids
Stores the time grids to which the primary and secondary data involved in the QN system will be inter...
void initialize(const DataMap &cplData) final override
Initializes the acceleration.
const int _timeWindowsReused
Maximum number of old time windows (with data values) kept.
BaseQNAcceleration(double initialRelaxation, bool forceInitialRelaxation, int maxIterationsUsed, int timeWindowsReused, int filter, double singularityLimit, std::vector< int > dataIDs, impl::PtrPreconditioner preconditioner, bool reducedTimeGrid)
const std::vector< int > _primaryDataIDs
Data IDs of primary data to be involved in the IQN coefficient computation.
void writeInfo(const std::string &s, bool allProcs=false)
Writes info to the _infostream (also in parallel)
std::deque< int > _matrixCols
Indices (of columns in W, V matrices) of 1st iterations of time windows.
bool _firstIteration
Indicates the first iteration, where constant relaxation is used.
int getDeletedColumns() const
how many QN columns were deleted in this time window
const bool _reducedTimeGrid
if _reducedTimeGrid = false uses the full QN-WI and if _reducedTimeGrid = true uses rQN-WI form the p...
impl::PtrPreconditioner _preconditioner
Preconditioner for least-squares system if vectorial system is used.
impl::QRFactorization _qrV
Stores the current QR decomposition ov _matrixV, can be updated via deletion/insertion of columns.
std::vector< int > _dataIDs
Data IDs of all coupling data.
void iterationsConverged(const DataMap &cplData, double windowStart) final override
Marks a iteration sequence as converged.
void performAcceleration(DataMap &cplData, double windowStart, double windowEnd) final override
Performs one acceleration step.
void initializeVectorsAndPreconditioner(const DataMap &cplData, double windowStart)
Initializes the vectors, matrices and preconditioner This has to be done after the first iteration of...
Eigen::VectorXd _oldPrimaryResiduals
Difference between solver input and output from last time window regarding primary data.
Eigen::VectorXd _oldPrimaryXTilde
Solver output regarding primary data from last iteration.
File reader for matrix/vector in Matlab V7 ASCII format.
Definition TXTReader.hpp:15
File writer for matrix in Matlab V7 ASCII format.
Definition TXTWriter.hpp:13
void stop()
Stops a running event.
Definition Event.cpp:51
Interface for storing the time grids in the Quasi-Newton and Aitken methods. A time grid is a ordered...
Definition TimeGrids.hpp:21
Eigen::VectorXd getTimeGridAfter(int dataID, double time) const
Definition TimeGrids.cpp:23
static int getSize()
Number of ranks. This includes ranks from both participants, e.g. minimal size is 2.
Definition IntraComm.cpp:47
static double l2norm(const Eigen::VectorXd &vec)
The l2 norm of a vector is calculated on distributed data.
Definition IntraComm.cpp:67
static Rank getRank()
Current rank.
Definition IntraComm.cpp:42
static bool isPrimary()
True if this process is running the primary rank.
Definition IntraComm.cpp:52
static bool isParallel()
True if this process is running in parallel.
Definition IntraComm.cpp:62
static com::PtrCommunication & getCommunication()
Intra-participant communication.
Definition IntraComm.hpp:31
T cend(T... args)
T flush(T... args)
T isnan(T... args)
std::shared_ptr< Preconditioner > PtrPreconditioner
contains implementations of acceleration schemes.
provides Import and Export of the coupling mesh and data.
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.
static constexpr SynchronizeTag Synchronize
Convenience instance of the SynchronizeTag.
Definition Event.hpp:28
void removeColumnFromMatrix(Eigen::MatrixXd &A, int col)
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:38
void appendFront(Eigen::MatrixXd &A, Eigen::VectorXd &v)
void shiftSetFirst(Eigen::MatrixXd &A, const Eigen::VectorXd &v)
Main namespace of the precice library.
STL namespace.
T size(T... args)
T str(T... args)
T transform(T... args)