preCICE v3.2.0
Loading...
Searching...
No Matches
PreconditionerTest.cpp
Go to the documentation of this file.
1#include <Eigen/Core>
2#include <algorithm>
3#include <cstddef>
4#include <vector>
12#include "testing/Testing.hpp"
13
14BOOST_AUTO_TEST_SUITE(AccelerationTests)
15
16using namespace precice;
17using namespace precice::acceleration;
18using namespace precice::acceleration::impl;
19
21 Eigen::VectorXd _data;
22 Eigen::VectorXd _res;
23 Eigen::VectorXd _dataLargerSize;
24 Eigen::VectorXd _dataSmallerSize;
25 Eigen::VectorXd _compareDataRes;
26 Eigen::VectorXd _compareDataResSum;
27 Eigen::VectorXd _compareDataResSum2;
29 Eigen::VectorXd _compareDataResSumUpdate;
32 Eigen::VectorXd _compareDataValue;
33 Eigen::VectorXd _compareDataConstant;
34
36 {
37 _data.resize(8);
38 _data << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0;
39
40 _dataLargerSize.resize(10);
41 _dataLargerSize << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 10.0, 20.0;
42
43 _dataSmallerSize.resize(6);
44 _dataSmallerSize << 1.0, 2.0, 3.0, 4.0, 5.0, 6.0;
45
46 _res.resize(8);
47 _res << 0.1, 0.1, 0.001, 0.001, 0.001, 0.001, 10.0, 20.0;
48
49 _compareDataRes.resize(8);
50 _compareDataRes << 7.07106781186547372897e+00,
51 1.41421356237309474579e+01,
52 1.50000000000000000000e+03,
53 2.00000000000000000000e+03,
54 2.50000000000000000000e+03,
55 3.00000000000000000000e+03,
56 3.13049516849970566046e-01,
57 3.57770876399966353265e-01;
58
59 _compareDataResSum.resize(8);
60 _compareDataResSum << 7.90585229434499154877e+01,
61 1.58117045886899830975e+02,
62 1.67708453051717078779e+04,
63 2.23611270735622783832e+04,
64 2.79514088419528488885e+04,
65 3.35416906103434157558e+04,
66 3.50007001329973377324e+00,
67 4.00008001519969536020e+00;
68
69 _compareDataResSum2.resize(8);
70 _compareDataResSum2 << 1.58113093108981217938e+02,
71 3.16226186217962435876e+02,
72 4.74339279326943596971e+02,
73 4.00008000319945455914e+00,
74 5.00010000399932064141e+00,
75 6.00012000479918228280e+00,
76 7.00014000559904481236e+00,
77 8.00016000639890734192e+00;
78
80 _compareDataResSumThreshold << 7.90585229434499154877e+00,
81 1.58117045886899830975e+01,
82 1.67708453051717078779e+03,
83 2.23611270735622783832e+03,
84 2.79514088419528488885e+03,
85 3.35416906103434157558e+03,
86 3.50007001329973377324e-01,
87 4.00008001519969536020e-01;
88
90 _compareDataResSumUpdate << 1.43742768988091e+01,
91 2.87485537976182e+01,
92 3.04924460094031e+03,
93 4.06565946792041e+03,
94 5.08207433490052e+03,
95 6.09848920188062e+03,
96 0.636376366054497e+00,
97 0.727287275490854e+00;
98
100 _compareDataLargerSizeResSum << 7.90585229434499154877e+01,
101 1.58117045886899830975e+02,
102 1.67708453051717078779e+04,
103 2.23611270735622783832e+04,
104 2.79514088419528488885e+04,
105 3.35416906103434157558e+04,
106 3.50007001329973377324e+00,
107 4.00008001519969536020e+00,
108 10.0,
109 20.0;
110
112 _compareDataSmallerSizeResSum << 7.90585229434499154877e+01,
113 1.58117045886899830975e+02,
114 1.67708453051717078779e+04,
115 2.23611270735622783832e+04,
116 2.79514088419528488885e+04,
117 3.35416906103434157558e+04;
118
119 _compareDataValue.resize(8);
120 _compareDataValue << 4.47213595499957927704e-01,
121 8.94427190999915855407e-01,
122 3.23498319610315276940e-01,
123 4.31331092813753647075e-01,
124 5.39163866017192239255e-01,
125 6.46996639220630553879e-01,
126 6.58504607868518165859e-01,
127 7.52576694706877713514e-01;
128
129 _compareDataConstant.resize(8);
130 _compareDataConstant << 1.00000000000000002082e-03,
131 2.00000000000000004163e-03,
132 1.49999999999999977796e+00,
133 1.99999999999999955591e+00,
134 2.50000000000000044409e+00,
135 2.99999999999999955591e+00,
136 6.99999999999999883585e+05,
137 7.99999999999999650754e+05;
138 }
140};
141
142BOOST_FIXTURE_TEST_SUITE(ResPreconditionerTests, ResPreconditionerFixture)
143
144PRECICE_TEST_SETUP(1_rank)
145BOOST_AUTO_TEST_CASE(testResPreconditioner)
146{
147 PRECICE_TEST();
149 svs.push_back(2);
150 svs.push_back(4);
151 svs.push_back(2);
152
153 ResidualPreconditioner precond(-1);
154
155 precond.initialize(svs);
156 Eigen::VectorXd backup = _data;
157
158 // should change
159 precond.update(false, _data, _res);
160 BOOST_TEST(precond.requireNewQR());
161 precond.newQRfulfilled();
162 precond.apply(_data);
163 BOOST_TEST(testing::equals(_data, _compareDataRes));
164 precond.revert(_data);
165 BOOST_TEST(testing::equals(_data, backup));
166
167 // should not change weights
168 precond.update(true, _data, _res * 10);
169 BOOST_TEST(not precond.requireNewQR());
170 precond.apply(_data);
171 BOOST_TEST(testing::equals(_data, _compareDataRes));
172 precond.revert(_data);
173 BOOST_TEST(testing::equals(_data, backup));
174}
175
176PRECICE_TEST_SETUP(1_rank)
177BOOST_AUTO_TEST_CASE(testResSumPreconditioner)
178{
179 PRECICE_TEST();
181 svs.push_back(2);
182 svs.push_back(4);
183 svs.push_back(2);
184
185 ResidualSumPreconditioner precond(-1, false);
186
187 precond.initialize(svs);
188 Eigen::VectorXd backup = _data;
189
190 // should change, update twice to really test the summation
191 precond.update(false, _data, _res);
192 precond.update(false, _data, _res * 2);
193 BOOST_TEST(precond.requireNewQR());
194 precond.newQRfulfilled();
195 precond.apply(_data);
196 BOOST_TEST(testing::equals(_data, _compareDataResSum));
197
198 precond.revert(_data);
199 BOOST_TEST(testing::equals(_data, backup));
200
201 // should not change weights
202 precond.update(true, _data, _res * 10);
203 BOOST_TEST(not precond.requireNewQR());
204 precond.apply(_data);
205 BOOST_TEST(testing::equals(_data, _compareDataResSum));
206 precond.revert(_data);
207 BOOST_TEST(testing::equals(_data, backup));
208}
209
210PRECICE_TEST_SETUP(1_rank)
211BOOST_AUTO_TEST_CASE(testResSumPreconditionerUpdate)
212{
213 PRECICE_TEST();
215 svs.push_back(2);
216 svs.push_back(4);
217 svs.push_back(2);
218
219 ResidualSumPreconditioner precond(-1, true);
220
221 precond.initialize(svs);
222 Eigen::VectorXd backup = _data;
223
224 // should change, update twice to really test the summation
225 precond.update(false, _data, _res);
226 precond.update(false, _data, _res * 2);
227 BOOST_TEST(precond.requireNewQR());
228 precond.newQRfulfilled();
229 precond.apply(_data);
230 BOOST_TEST(testing::equals(_data, _compareDataResSum));
231
232 precond.revert(_data);
233 BOOST_TEST(testing::equals(_data, backup));
234
235 // should not change weights
236 precond.update(true, _data, _res * 10);
237 BOOST_TEST(not precond.requireNewQR());
238 precond.apply(_data);
239 BOOST_TEST(testing::equals(_data, _compareDataResSum));
240 precond.revert(_data);
241 BOOST_TEST(testing::equals(_data, backup));
242
243 // New time windows stops automatic update of weights
244 precond.update(false, _data, _res * 3);
245 // New residuals are not large enough to trigger a change
246 BOOST_TEST(not precond.requireNewQR());
247 precond.apply(_data);
248 BOOST_TEST(testing::equals(_data, _compareDataResSum));
249 precond.revert(_data);
250
251 // Apply multiple preconditioners
252 for (int i = 0; i < 5; i++) {
253 precond.update(false, _data, _res * 3);
254 }
255 // New residuals are not large enough to trigger a change
256 BOOST_TEST(not precond.requireNewQR());
257 precond.apply(_data);
258 BOOST_TEST(testing::equals(_data, _compareDataResSum));
259 precond.revert(_data);
260
261 // Apply multiple preconditioners until weights change enough
262 for (int i = 0; i < 14; i++) {
263 precond.update(false, _data, _res * 3);
264 }
265 // New residuals are now large enough to trigger a change
266 BOOST_TEST(precond.requireNewQR());
267 precond.newQRfulfilled();
268 precond.apply(_data);
269 BOOST_TEST(testing::equals(_data, _compareDataResSumThreshold));
270 precond.revert(_data);
271}
272
273PRECICE_TEST_SETUP(1_rank)
274BOOST_AUTO_TEST_CASE(testValuePreconditioner)
275{
276 PRECICE_TEST();
278 svs.push_back(2);
279 svs.push_back(4);
280 svs.push_back(2);
281
282 ValuePreconditioner precond(-1);
283
284 precond.initialize(svs);
285 Eigen::VectorXd backup = _data;
286
287 // should change, since this is the first time window
288 precond.update(false, _data, _res);
289 BOOST_TEST(precond.requireNewQR());
290 precond.newQRfulfilled();
291 precond.apply(_data);
292 BOOST_TEST(testing::equals(_data, _compareDataValue));
293 precond.revert(_data);
294 BOOST_TEST(testing::equals(_data, backup));
295
296 // now no change
297 precond.update(false, _data, _res);
298 BOOST_TEST(not precond.requireNewQR());
299 precond.apply(_data);
300 BOOST_TEST(testing::equals(_data, _compareDataValue));
301 precond.revert(_data);
302 BOOST_TEST(testing::equals(_data, backup));
303
304 // should change weights
305 precond.update(true, _data * 2, _res);
306 BOOST_TEST(precond.requireNewQR());
307 precond.newQRfulfilled();
308}
309
310PRECICE_TEST_SETUP(1_rank)
311BOOST_AUTO_TEST_CASE(testConstPreconditioner)
312{
313 PRECICE_TEST();
315 svs.push_back(2);
316 svs.push_back(4);
317 svs.push_back(2);
318
319 std::vector<double> factors;
320 factors.push_back(1e3);
321 factors.push_back(2.0);
322 factors.push_back(1e-5);
323
324 ConstantPreconditioner precond(factors);
325
326 precond.initialize(svs); // new weights already computed here
327 Eigen::VectorXd backup = _data;
328
329 // should have no effect
330 precond.update(false, _data, _res);
331 BOOST_TEST(not precond.requireNewQR());
332 precond.apply(_data);
333 BOOST_TEST(testing::equals(_data, _compareDataConstant));
334 precond.revert(_data);
335 BOOST_TEST(testing::equals(_data, backup));
336
337 // should not change weights
338 precond.update(true, _data, _res);
339 BOOST_TEST(not precond.requireNewQR());
340 precond.apply(_data);
341 BOOST_TEST(testing::equals(_data, _compareDataConstant));
342 precond.revert(_data);
343 BOOST_TEST(testing::equals(_data, backup));
344}
345
346PRECICE_TEST_SETUP(1_rank)
347BOOST_AUTO_TEST_CASE(testPreconditionerLargerDataSize)
348{
349 PRECICE_TEST();
351 svs.push_back(2);
352 svs.push_back(4);
353 svs.push_back(2);
354
355 ResidualSumPreconditioner precond(-1, false);
356
357 precond.initialize(svs);
358 Eigen::VectorXd backup = _dataLargerSize;
359
360 // should change, update twice to really test the summation
361 precond.update(false, _data, _res);
362 precond.update(false, _data, _res * 2);
363 BOOST_TEST(precond.requireNewQR());
364 precond.newQRfulfilled();
365 precond.apply(_dataLargerSize); // should only scale the first 8 values
366 BOOST_TEST(testing::equals(_dataLargerSize, _compareDataLargerSizeResSum));
367
368 precond.revert(_dataLargerSize);
369 BOOST_TEST(testing::equals(_dataLargerSize, backup));
370
371 // should not change weights
372 precond.update(true, _data, _res * 10);
373 BOOST_TEST(not precond.requireNewQR());
374 precond.apply(_dataLargerSize);
375 BOOST_TEST(testing::equals(_dataLargerSize, _compareDataLargerSizeResSum));
376 precond.revert(_dataLargerSize);
377 BOOST_TEST(testing::equals(_dataLargerSize, backup));
378}
379
380PRECICE_TEST_SETUP(1_rank)
381BOOST_AUTO_TEST_CASE(testPreconditionerLargerResSize)
382{
383 PRECICE_TEST();
385 svs.push_back(2);
386 svs.push_back(4);
387 svs.push_back(2);
388
389 ResidualSumPreconditioner precond(-1, false);
390
391 precond.initialize(svs);
392 Eigen::VectorXd backup = _dataSmallerSize;
393
394 // should change, update twice to really test the summation
395 precond.update(false, _data, _res);
396 precond.update(false, _data, _res * 2);
397 BOOST_TEST(precond.requireNewQR());
398 precond.newQRfulfilled();
399 precond.apply(_dataSmallerSize); // should only use the first 6 scaling factors
400 BOOST_TEST(testing::equals(_dataSmallerSize, _compareDataSmallerSizeResSum));
401
402 precond.revert(_dataSmallerSize);
403 BOOST_TEST(testing::equals(_dataSmallerSize, backup));
404
405 // should not change weights
406 precond.update(true, _data, _res * 10);
407 BOOST_TEST(not precond.requireNewQR());
408 precond.apply(_dataSmallerSize);
409 BOOST_TEST(testing::equals(_dataSmallerSize, _compareDataSmallerSizeResSum));
410 precond.revert(_dataSmallerSize);
411 BOOST_TEST(testing::equals(_dataSmallerSize, backup));
412}
413
414PRECICE_TEST_SETUP(1_rank)
415BOOST_AUTO_TEST_CASE(testMultilpleMeshes)
416{
417 PRECICE_TEST();
419 svs.push_back(3);
420 svs.push_back(5);
421
422 ResidualSumPreconditioner precond(-1, false);
423
424 precond.initialize(svs);
425 Eigen::VectorXd backup = _data;
426
427 // should change
428 precond.update(false, _data, _res);
429 BOOST_TEST(precond.requireNewQR());
430 precond.newQRfulfilled();
431 precond.apply(_data);
432 BOOST_TEST(testing::equals(_data, _compareDataResSum2));
433 precond.revert(_data);
434 BOOST_TEST(testing::equals(_data, backup));
435
436 // should not change weights
437 precond.update(true, _data, _res * 10);
438 BOOST_TEST(not precond.requireNewQR());
439 precond.apply(_data);
440 BOOST_TEST(testing::equals(_data, _compareDataResSum2));
441 precond.revert(_data);
442 BOOST_TEST(testing::equals(_data, backup));
443}
444
445#ifndef PRECICE_NO_MPI
446PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
447BOOST_AUTO_TEST_CASE(testParallelMatrixScaling)
448{
449 PRECICE_TEST();
450 // setup data
451 int localN = -1;
452 if (context.isPrimary()) {
453 localN = 2;
454 } else if (context.isRank(1)) {
455 localN = 1;
456 } else if (context.isRank(2)) {
457 localN = 0;
458 } else if (context.isRank(3)) {
459 localN = 1;
460 }
461
462 int globalN = 4;
463
464 Eigen::MatrixXd V(localN, 2);
465 Eigen::MatrixXd M(globalN, localN);
466 Eigen::VectorXd x(localN);
467 Eigen::MatrixXd V_back(localN, 2);
468 Eigen::MatrixXd M_back(globalN, localN);
469 Eigen::VectorXd x_back(localN);
470
471 if (context.isPrimary()) {
472 V(0, 0) = 1.0;
473 V(0, 1) = 2.0;
474 V(1, 0) = 3.0;
475 V(1, 1) = 4.0;
476 M(0, 0) = 1.0;
477 M(0, 1) = 2.0;
478 M(1, 0) = 3.0;
479 M(1, 1) = 4.0;
480 M(2, 0) = 1.0;
481 M(2, 1) = 2.0;
482 M(3, 0) = 3.0;
483 M(3, 1) = 4.0;
484 x(0) = 5.0;
485 x(1) = 5.0;
486 } else if (context.isRank(1)) {
487 V(0, 0) = 5.0;
488 V(0, 1) = 6.0;
489 M(0, 0) = 1.0;
490 M(1, 0) = 2.0;
491 M(2, 0) = 3.0;
492 M(3, 0) = 4.0;
493 x(0) = 5.0;
494 } else if (context.isRank(2)) {
495 } else if (context.isRank(3)) {
496 V(0, 0) = 7.0;
497 V(0, 1) = 8.0;
498 M(0, 0) = 1.0;
499 M(1, 0) = 2.0;
500 M(2, 0) = 3.0;
501 M(3, 0) = 4.0;
502 x(0) = 5.0;
503 }
504
505 V_back = V;
506 M_back = M;
507 x_back = x;
508
510 svs.push_back(localN);
511
512 ValuePreconditioner precond(-1);
513 precond.initialize(svs);
514 precond.update(true, x, x);
515 BOOST_TEST(precond.requireNewQR());
516
517 precond.apply(V);
518
519 BOOST_TEST(testing::equals(V, V_back * 0.1));
520
521 precond.revert(V);
522
523 BOOST_TEST(testing::equals(V, V_back));
524}
525#endif
526
BOOST_AUTO_TEST_CASE(testIQNIMVJPPWithSubsteps)
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
#define PRECICE_TEST()
Definition Testing.hpp:39
#define PRECICE_TEST_SETUP(...)
Creates and attaches a TestSetup to a Boost test case.
Definition Testing.hpp:29
Preconditioner that uses the constant user-defined factors to scale the quasi-Newton system.
void initialize(std::vector< size_t > &svs) override
initialize the preconditioner
void apply(Eigen::MatrixXd &M, bool transpose)
Apply preconditioner to matrix.
void revert(Eigen::MatrixXd &M, bool transpose)
Apply inverse preconditioner to matrix.
void newQRfulfilled()
to tell the preconditioner that QR-decomposition has been recomputed
void update(bool timeWindowComplete, const Eigen::VectorXd &oldValues, const Eigen::VectorXd &res)
Update the scaling after every FSI iteration and require a new QR decomposition (if necessary)
virtual void initialize(std::vector< size_t > &svs)
initialize the preconditioner
bool requireNewQR()
returns true if a QR decomposition from scratch is necessary
Preconditioner that uses the recent residual to scale the quasi-Newton system.
Preconditioner that uses the residuals of all iterations of the current time window summed up to scal...
void initialize(std::vector< size_t > &svs) override
initialize the preconditioner
Preconditioner that uses the values from the previous time window to scale the quasi-Newton system.
contains implementations of acceleration schemes.
boost::test_tools::predicate_result equals(const std::vector< float > &VectorA, const std::vector< float > &VectorB, float tolerance)
equals to be used in tests. Compares two std::vectors using a given tolerance. Prints both operands o...
Definition Testing.cpp:93
Main namespace of the precice library.
T push_back(T... args)
Eigen::VectorXd _compareDataSmallerSizeResSum
Eigen::VectorXd _compareDataResSumUpdate
~ResPreconditionerFixture()=default
Eigen::VectorXd _compareDataResSumThreshold
Eigen::VectorXd _compareDataLargerSizeResSum