preCICE v3.2.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
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
97 for (const DataMap::value_type &pair : cplData) {
98 _dataIDs.push_back(pair.first);
99 }
100
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) {
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{
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
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
295 }
296 _preconditioner->newQRfulfilled();
297 }
298
299 if (_firstIteration) {
300 _nbDelCols = 0;
301 _nbDropCols = 0;
302 }
303
304 // apply the configured filter to the LS system
305 profiling::Event applyingFilter("ApplyFilter");
306 applyFilter();
307 applyingFilter.stop();
308
309 // revert scaling of V, in computeQNUpdate all data objects are unscaled.
310 _preconditioner->revert(_matrixV);
311
317 Eigen::VectorXd xUpdate = Eigen::VectorXd::Zero(_values.size());
318 computeQNUpdate(xUpdate);
319
320 // Apply the quasi-Newton update
321 _values += xUpdate;
322
323 // pending deletion: delete old V, W matrices if timeWindowsReused = 0
324 // those were only needed for the first iteration (instead of underrelax.)
326 // save current matrix data in case the coupling for the next time window will terminate
327 // after the first iteration (no new data, i.e., V = W = 0)
328 if (getLSSystemCols() > 0) {
332 }
333 // if no time windows reused, the matrix data needs to be cleared as it was only needed for the
334 // QN-step in the first iteration (idea: rather perform QN-step with information from last converged
335 // time window instead of doing a underrelaxation)
336 if (not _firstTimeWindow) {
337 _matrixV.resize(0, 0);
338 _matrixW.resize(0, 0);
340 _matrixCols.push_front(0); // vital after clear()
341 _qrV.reset();
342 // set the number of global rows in the QRFactorization.
344 _resetLS = true; // need to recompute _Wtil, Q, R (only for IMVJ efficient update)
345 }
346 }
347
350 "The quasi-Newton update contains NaN values. This means that the quasi-Newton acceleration failed to converge. "
351 "When writing your own adapter this could indicate that you give wrong information to preCICE, such as identical "
352 "data in succeeding iterations. Or you do not properly save and reload checkpoints. "
353 "If you give the correct data this could also mean that the coupled problem is too hard to solve. Try to use a QR "
354 "filter or increase its threshold (larger epsilon).");
355
356 // updates the waveform and values in coupling data by splitting the primary and secondary data back into the individual data objects
357 updateCouplingData(cplData, windowStart);
358
359 // number of iterations (usually equals number of columns in LS-system)
360 its++;
361 _firstIteration = false;
362}
363
365{
367
369 // do nothing
370 } else {
371 // do: filtering of least-squares system to maintain good conditioning
372 std::vector<int> delIndices(0);
374 // start with largest index (as V,W matrices are shrunk and shifted
375
376 for (int i = delIndices.size() - 1; i >= 0; i--) {
377
378 removeMatrixColumn(delIndices[i]);
379
380 PRECICE_DEBUG(" Filter: removing column with index {} in iteration {} of time window: {}", delIndices[i], its, tWindows);
381 }
382 PRECICE_ASSERT(_matrixV.cols() == _qrV.cols(), _matrixV.cols(), _qrV.cols());
383 }
384}
385
387 const DataMap &cplData, double windowStart)
388{
389
391 // offset to keep track of the position in xUpdate
392 Eigen::Index offset = 0;
393
394 for (int id : _dataIDs) {
395
396 auto &couplingData = *cplData.at(id);
397 size_t dataSize = couplingData.getSize();
398
399 Eigen::VectorXd timeGrid = _timeGrids->getTimeGridAfter(id, windowStart);
400 couplingData.timeStepsStorage().trimAfter(windowStart);
401 for (int i = 0; i < timeGrid.size(); i++) {
402
403 Eigen::VectorXd temp = Eigen::VectorXd::Zero(dataSize);
404 for (size_t j = 0; j < dataSize; j++) {
405 temp(j) = _values(offset + j);
406 }
407 offset += dataSize;
408
409 couplingData.setSampleAtTime(timeGrid(i), time::Sample(couplingData.getDimensions(), temp));
410 }
411 }
412}
413
423 const DataMap &cplData, double windowStart)
424{
426
428 _infostringstream << "# time window " << tWindows << " converged #\n iterations: " << its
429 << "\n used cols: " << getLSSystemCols() << "\n del cols: " << _nbDelCols << '\n';
430
431 its = 0;
432 tWindows++;
433
434 // the most recent differences for the V, W matrices have not been added so far
435 // this has to be done in iterations converged, as PP won't be called any more if
436 // convergence was achieved
437
438 // 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.
440 initializeVectorsAndPreconditioner(cplData, windowStart);
441 }
442
443 // Needs to be called in the first iteration of each time window.
444 if (_firstIteration) {
445 _timeGrids->moveTimeGridToNewWindow(cplData);
446 _primaryTimeGrids->moveTimeGridToNewWindow(cplData);
447 }
450 concatenateCouplingData(_values, _oldValues, cplData, _dataIDs, _timeGrids.value(), windowStart);
453
454 if (not _matrixCols.empty() && _matrixCols.front() == 0) { // Did only one iteration
456 }
457
458#ifndef NDEBUG
459 std::ostringstream stream;
460 stream << "Matrix column counters: ";
461 for (int cols : _matrixCols) {
462 stream << cols << ", ";
463 }
464 PRECICE_DEBUG(stream.str());
465#endif // Debug
466
467 // doing specialized stuff for the corresponding acceleration scheme after
468 // convergence of iteration i.e.:
469 // - analogously to the V,W matrices, remove columns from matrices for secondary data
470 // - save the old Jacobian matrix
472
473 // if we already have convergence in the first iteration of the first time window
474 // we need to do underrelaxation in the first iteration of the second time window
475 // so "_firstTimeWindow" is slightly misused, but still the best way to understand
476 // the concept
477 if (not _firstIteration)
478 _firstTimeWindow = false;
479
480 // update preconditioner depending on residuals or values (must be after specialized iterations converged --> IMVJ)
482
483 if (_timeWindowsReused == 0) {
485 _matrixV.resize(0, 0);
486 _matrixW.resize(0, 0);
487 _qrV.reset();
488 // set the number of global rows in the QRFactorization.
490 _matrixCols.clear(); // _matrixCols.push_front() at the end of the method.
491 } else {
497 }
498 } else if (static_cast<int>(_matrixCols.size()) > _timeWindowsReused) {
499 int toRemove = _matrixCols.back();
500 _nbDropCols += toRemove;
501 PRECICE_ASSERT(toRemove > 0, toRemove);
502 PRECICE_DEBUG("Removing {} cols from least-squares system with {} cols", toRemove, getLSSystemCols());
503 PRECICE_ASSERT(_matrixV.cols() == _matrixW.cols(), _matrixV.cols(), _matrixW.cols());
504 PRECICE_ASSERT(getLSSystemCols() > toRemove, getLSSystemCols(), toRemove);
505
506 // remove columns
507 for (int i = 0; i < toRemove; i++) {
510 // also remove the corresponding columns from the dynamic QR-descomposition of _matrixV
511 _qrV.popBack();
512 }
514 }
515
517 _firstIteration = true;
518}
519
527 int columnIndex)
528{
529 PRECICE_TRACE(columnIndex, _matrixV.cols());
530
531 _nbDelCols++;
532
533 PRECICE_ASSERT(_matrixV.cols() > 1);
536
537 // Reduce column count
538 std::deque<int>::iterator iter = _matrixCols.begin();
539 int cols = 0;
540 while (iter != _matrixCols.end()) {
541 cols += *iter;
542 if (cols > columnIndex) {
543 PRECICE_ASSERT(*iter > 0);
544 *iter -= 1;
545 if (*iter == 0) {
546 _matrixCols.erase(iter);
547 }
548 break;
549 }
550 iter++;
551 }
552}
553
558
563
565{
566 return _nbDelCols;
567}
568
570{
571 return _nbDropCols;
572}
573
575{
576 int cols = 0;
577 for (int col : _matrixCols) {
578 cols += col;
579 }
581 PRECICE_ASSERT(cols == _matrixV.cols(), cols, _matrixV.cols(), _matrixCols, _qrV.cols());
582 PRECICE_ASSERT(cols == _matrixW.cols(), cols, _matrixW.cols());
583 }
584
585 return cols;
586}
587
592
597
599{
601 return _dimOffsets.back();
602 }
603 return _residuals.size();
604}
605
607{
609 return _dimOffsetsPrimary.back();
610 }
611 return _primaryResiduals.size();
612}
613
615 const std::string &s, bool allProcs)
616{
618 // serial acceleration mode
620
621 // parallel acceleration
622 } else {
623 if (not allProcs) {
626 } else {
628 }
629 }
631}
632
633void BaseQNAcceleration::concatenateCouplingData(Eigen::VectorXd &data, Eigen::VectorXd &oldData, const DataMap &cplData, std::vector<int> dataIDs, precice::time::TimeGrids timeGrids, double windowStart) const
634{
635 Eigen::Index offset = 0;
636 for (int id : dataIDs) {
637 Eigen::Index dataSize = cplData.at(id)->getSize();
638 Eigen::VectorXd timeGrid = timeGrids.getTimeGridAfter(id, windowStart);
639
640 for (int i = 0; i < timeGrid.size(); i++) {
641
642 auto current = cplData.at(id)->timeStepsStorage().sample(timeGrid(i));
643 auto old = cplData.at(id)->getPreviousValuesAtTime(timeGrid(i));
644
645 PRECICE_ASSERT(data.size() >= offset + dataSize, "the values were not initialized correctly");
646 PRECICE_ASSERT(oldData.size() >= offset + dataSize, "the values were not initialized correctly");
647
648 for (Eigen::Index i = 0; i < dataSize; i++) {
649 data(i + offset) = current(i);
650 oldData(i + offset) = old(i);
651 }
652 offset += dataSize;
653 }
654 }
655}
656
658{
659 // Saves the time grid of each waveform in the data field to be used in the QN method
660 _timeGrids.emplace(cplData, _dataIDs, false);
662
663 // Helper function
664 auto addTimeSliceSize = [&](size_t sum, int id, precice::time::TimeGrids timeGrids) { return sum + timeGrids.getTimeGridAfter(id, windowStart).size() * cplData.at(id)->getSize(); };
665
666 // Size of primary data
667 const size_t primaryDataSize = std::accumulate(_primaryDataIDs.begin(), _primaryDataIDs.end(), (size_t) 0, [&](size_t sum, int id) { return addTimeSliceSize(sum, id, _primaryTimeGrids.value()); });
668
669 // Size of values
670 const size_t dataSize = std::accumulate(_dataIDs.begin(), _dataIDs.end(), (size_t) 0, [&](size_t sum, int id) { return addTimeSliceSize(sum, id, _timeGrids.value()); });
671
672 _values = Eigen::VectorXd::Zero(dataSize);
673 _oldValues = Eigen::VectorXd::Zero(dataSize);
674 _oldXTilde = Eigen::VectorXd::Zero(dataSize);
675 _residuals = Eigen::VectorXd::Zero(dataSize);
676 _primaryValues = Eigen::VectorXd::Zero(primaryDataSize);
677 _oldPrimaryValues = Eigen::VectorXd::Zero(primaryDataSize);
678 _oldPrimaryXTilde = Eigen::VectorXd::Zero(primaryDataSize);
679 _primaryResiduals = Eigen::VectorXd::Zero(primaryDataSize);
680 _oldPrimaryResiduals = Eigen::VectorXd::Zero(primaryDataSize);
681
682 // Also clear the matrices, since the initialization phase will be called more than once when using remeshing
683 _matrixW.resize(0, 0);
684 _matrixV.resize(0, 0);
685
694
695 if (primaryDataSize <= 0) {
696 _hasNodesOnInterface = false;
697 }
698
706 _dimOffsets[0] = 0;
707 _dimOffsetsPrimary[0] = 0;
708 for (size_t i = 0; i < _dimOffsets.size() - 1; i++) {
709 int accumulatedNumberOfUnknowns = 0;
710 int accumulatedNumberOfPrimaryUnknowns = 0;
711
712 for (auto &elem : _dataIDs) {
713 const auto &offsets = cplData.at(elem)->getVertexOffsets();
714
715 accumulatedNumberOfUnknowns += offsets[i] * cplData.at(elem)->getDimensions() * _timeGrids.value().getTimeGridAfter(elem, windowStart).size();
716
718 accumulatedNumberOfPrimaryUnknowns += offsets[i] * cplData.at(elem)->getDimensions() * _primaryTimeGrids.value().getTimeGridAfter(elem, windowStart).size();
719 }
720 }
721 _dimOffsets[i + 1] = accumulatedNumberOfUnknowns;
722 _dimOffsetsPrimary[i + 1] = accumulatedNumberOfPrimaryUnknowns;
723 }
724
725 PRECICE_DEBUG("Number of unknowns at the interface (global): {}", _dimOffsets.back());
727 _infostringstream << fmt::format("\n--------\n DOFs (global): {}\n offsets: {}\n", _dimOffsets.back(), _dimOffsets);
728 }
729
730 // test that the computed number of unknown per proc equals the number of primaryDataSize actually present on that proc
732 PRECICE_ASSERT(dataSize == unknowns, dataSize, unknowns);
734 PRECICE_ASSERT(primaryDataSize == primaryUnknowns, primaryDataSize, primaryUnknowns);
735 } else {
736 _infostringstream << fmt::format("\n--------\n DOFs (global): {}\n", dataSize);
737 }
738
739 // set the number of global rows in the QRFactorization.
740 _qrV.reset();
742
743 std::vector<size_t> subVectorSizes; // needed for preconditioner
744 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(); });
745 _preconditioner->initialize(subVectorSizes);
746
748}
749
750} // namespace acceleration
751} // 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(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.
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.
void applyFilter(double singularityLimit, std::vector< int > &delIndices, Eigen::MatrixXd &V)
filters the least squares system, i.e., the decomposition Q*R = V according to the defined filter tec...
void reset()
resets the QR factorization zo zero Q(0:0, 0:0)R(0:0, 0:0)
void popBack()
deletes the column at position _cols-1, i.e., deletes the last column and updates the QR factorizatio...
void pushFront(const Eigen::VectorXd &v)
inserts a new column at position 0, i.e., shifts right and inserts at first position and updates the ...
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 clear(T... args)
T empty(T... args)
T cend(T... args)
T erase(T... args)
T flush(T... args)
T front(T... args)
T isnan(T... args)
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:21
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 pop_back(T... args)
T pop_front(T... args)
T push_back(T... args)
T push_front(T... args)
T resize(T... args)
T size(T... args)
T str(T... args)
T transform(T... args)