preCICE v3.2.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PartitionOfUnityMappingTest.cpp
Go to the documentation of this file.
1#include <Eigen/Core>
2#include <algorithm>
3#include <memory>
4#include <ostream>
5#include <string>
6#include <utility>
7#include <vector>
8#include "logging/Logger.hpp"
9#include "mapping/Mapping.hpp"
13#include "mesh/Data.hpp"
14#include "mesh/Mesh.hpp"
16#include "mesh/Utils.hpp"
17#include "mesh/Vertex.hpp"
20#include "testing/Testing.hpp"
21
22using namespace precice;
23using namespace precice::mesh;
24using namespace precice::mapping;
25using namespace precice::testing;
27
28BOOST_AUTO_TEST_SUITE(MappingTests)
30
31void addGlobalIndex(mesh::PtrMesh &mesh, int offset = 0)
32{
33 for (mesh::Vertex &v : mesh->vertices()) {
34 v.setGlobalIndex(v.getID() + offset);
35 }
36}
37
38double sumComponentWise(const Eigen::VectorXd &vec, int component, int dataDimension)
39{
40 PRECICE_ASSERT(component < dataDimension);
41 double sum = 0;
42 for (unsigned int i = 0; i < vec.size() / dataDimension; ++i) {
43 sum += vec[(i * dataDimension) + component];
44 }
45 return sum;
46}
47
49
51{
52 int dimensions = 2;
53 using Eigen::Vector2d;
54
55 // Create mesh to map from
56 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
57 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
58 int inDataID = inData->getID();
59 inMesh->createVertex(Vector2d(0.0, 0.0));
60 inMesh->createVertex(Vector2d(1.0, 0.0));
61 inMesh->createVertex(Vector2d(1.0, 1.0));
62 inMesh->createVertex(Vector2d(0.0, 1.0));
63
64 inMesh->createVertex(Vector2d(2.0, 0.0));
65 inMesh->createVertex(Vector2d(3.0, 0.0));
66 inMesh->createVertex(Vector2d(3.0, 1.0));
67 inMesh->createVertex(Vector2d(2.0, 1.0));
68
69 inMesh->createVertex(Vector2d(4.0, 0.0));
70 inMesh->createVertex(Vector2d(5.0, 0.0));
71 inMesh->createVertex(Vector2d(5.0, 1.0));
72 inMesh->createVertex(Vector2d(4.0, 1.0));
73
74 inMesh->allocateDataValues();
75 addGlobalIndex(inMesh);
76
77 auto &values = inData->values();
78 values << 1.0, 2.0, 2.0, 1.0, 3.0, 4.0, 4.0, 3.0, 5.0, 6.0, 6.0, 5.0;
79
80 // Create mesh to map to
81 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
82 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
83 int outDataID = outData->getID();
84 mesh::Vertex &vertex = outMesh->createVertex(Vector2d(0, 0));
85 outMesh->createVertex(Vector2d(3.5, 0.5));
86 outMesh->createVertex(Vector2d(2.5, 0.5));
87 // vertex will be changed
88 outMesh->createVertex(Vector2d(0, 0));
89 outMesh->createVertex(Vector2d(5, 1));
90 outMesh->allocateDataValues();
91 addGlobalIndex(outMesh);
92
93 // Setup mapping with mapping coordinates and geometry used
94 mapping.setMeshes(inMesh, outMesh);
95 BOOST_TEST(mapping.hasComputedMapping() == false);
96
97 vertex.setCoords(Vector2d(0.0, 0.0));
98 mapping.computeMapping();
99 mapping.map(inDataID, outDataID);
100 double value = outData->values()(0);
101 double value1 = outData->values()(1);
102 double value2 = outData->values()(2);
103 BOOST_TEST(mapping.hasComputedMapping() == true);
104 BOOST_TEST(value == 1.0);
105 BOOST_TEST(value1 == 4.5);
106 BOOST_TEST(value2 == 3.5);
107
108 vertex.setCoords(Vector2d(0.0, 0.5));
109 mapping.clear();
110 outData->values().setZero();
111 BOOST_TEST(mapping.hasComputedMapping() == false);
112 mapping.computeMapping();
113 mapping.map(inDataID, outDataID);
114 value = outData->values()(0);
115 BOOST_TEST(mapping.hasComputedMapping() == true);
116 BOOST_TEST(value == 1.0);
117
118 vertex.setCoords(Vector2d(0.0, 1.0));
119 mapping.clear();
120 outData->values().setZero();
121 mapping.computeMapping();
122 mapping.map(inDataID, outDataID);
123 value = outData->values()(0);
124 BOOST_TEST(mapping.hasComputedMapping() == true);
125 BOOST_TEST(value == 1.0);
126
127 vertex.setCoords(Vector2d(1.0, 0.0));
128 mapping.clear();
129 outData->values().setZero();
130 mapping.computeMapping();
131 mapping.map(inDataID, outDataID);
132 value = outData->values()(0);
133 BOOST_TEST(mapping.hasComputedMapping() == true);
134 BOOST_TEST(value == 2.0);
135
136 vertex.setCoords(Vector2d(1.0, 0.5));
137 mapping.clear();
138 outData->values().setZero();
139 mapping.computeMapping();
140 mapping.map(inDataID, outDataID);
141 value = outData->values()(0);
142 BOOST_TEST(mapping.hasComputedMapping() == true);
143 BOOST_TEST(value == 2.0);
144
145 vertex.setCoords(Vector2d(1.0, 1.0));
146 mapping.clear();
147 outData->values().setZero();
148 mapping.computeMapping();
149 mapping.map(inDataID, outDataID);
150 value = outData->values()(0);
151 BOOST_TEST(mapping.hasComputedMapping() == true);
152 BOOST_TEST(value == 2.0);
153
154 vertex.setCoords(Vector2d(0.5, 0.0));
155 mapping.clear();
156 outData->values().setZero();
157 mapping.computeMapping();
158 mapping.map(inDataID, outDataID);
159 value = outData->values()(0);
160 BOOST_TEST(mapping.hasComputedMapping() == true);
161 BOOST_TEST(value == 1.5);
162
163 vertex.setCoords(Vector2d(0.5, 0.5));
164 mapping.clear();
165 outData->values().setZero();
166 mapping.computeMapping();
167 mapping.map(inDataID, outDataID);
168 value = outData->values()(0);
169 BOOST_TEST(mapping.hasComputedMapping() == true);
170 BOOST_TEST(value == 1.5);
171
172 vertex.setCoords(Vector2d(0.5, 1.0));
173 mapping.clear();
174 outData->values().setZero();
175 mapping.computeMapping();
176 mapping.map(inDataID, outDataID);
177 value = outData->values()(0);
178 BOOST_TEST(mapping.hasComputedMapping() == true);
179 BOOST_TEST(value == 1.5);
180}
181
183{
184 int dimensions = 2;
185 int dataDimensions = dimensions;
186 using Eigen::Vector2d;
187
188 // Create mesh to map from
189 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
190 mesh::PtrData inData = inMesh->createData("InData", dataDimensions, 0_dataID);
191 int inDataID = inData->getID();
192 inMesh->createVertex(Vector2d(0.0, 0.0));
193 inMesh->createVertex(Vector2d(1.0, 0.0));
194 inMesh->createVertex(Vector2d(1.0, 1.0));
195 inMesh->createVertex(Vector2d(0.0, 1.0));
196
197 inMesh->createVertex(Vector2d(2.0, 0.0));
198 inMesh->createVertex(Vector2d(3.0, 0.0));
199 inMesh->createVertex(Vector2d(3.0, 1.0));
200 inMesh->createVertex(Vector2d(2.0, 1.0));
201
202 inMesh->createVertex(Vector2d(4.0, 0.0));
203 inMesh->createVertex(Vector2d(5.0, 0.0));
204 inMesh->createVertex(Vector2d(5.0, 1.0));
205 inMesh->createVertex(Vector2d(4.0, 1.0));
206
207 inMesh->allocateDataValues();
208 addGlobalIndex(inMesh);
209
210 auto &values = inData->values();
211 // We select the second component = 2 * first component
212 values << 1.0, 2.0, 2.0, 4.0, 2.0, 4.0, 1.0, 2.0, 3.0, 6.0, 4.0, 8.0, 4.0, 8.0, 3.0, 6.0, 5.0, 10.0, 6.0, 12.0, 6.0, 12.0, 5.0, 10.0;
213
214 // Create mesh to map to
215 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
216 mesh::PtrData outData = outMesh->createData("OutData", dataDimensions, 1_dataID);
217 int outDataID = outData->getID();
218 mesh::Vertex &vertex = outMesh->createVertex(Vector2d(0, 0));
219 outMesh->createVertex(Vector2d(3.5, 0.5));
220 outMesh->createVertex(Vector2d(2.5, 0.5));
221 // vertex will be changed
222 outMesh->createVertex(Vector2d(0, 0));
223 outMesh->createVertex(Vector2d(5, 1));
224 outMesh->allocateDataValues();
225 addGlobalIndex(outMesh);
226
227 // Setup mapping with mapping coordinates and geometry used
228 mapping.setMeshes(inMesh, outMesh);
229 BOOST_TEST(mapping.hasComputedMapping() == false);
230
231 vertex.setCoords(Vector2d(0.0, 0.0));
232 mapping.computeMapping();
233 mapping.map(inDataID, outDataID);
234 DataID index = 0;
235 DataID index1 = 1 * dataDimensions;
236 DataID index2 = 2 * dataDimensions;
237 BOOST_TEST(mapping.hasComputedMapping() == true);
238 BOOST_TEST(outData->values()(index) == 1.0);
239 BOOST_TEST(outData->values()(index + 1) == 2.0);
240 BOOST_TEST(outData->values()(index1) == 4.5);
241 BOOST_TEST(outData->values()(index1 + 1) == 9.0);
242 BOOST_TEST(outData->values()(index2) == 3.5);
243 BOOST_TEST(outData->values()(index2 + 1) == 7.0);
244
245 vertex.setCoords(Vector2d(0.0, 0.5));
246 mapping.clear();
247 outData->values().setZero();
248 mapping.computeMapping();
249 mapping.map(inDataID, outDataID);
250 BOOST_TEST(mapping.hasComputedMapping() == true);
251 BOOST_TEST(outData->values()(0) == 1.0);
252 BOOST_TEST(outData->values()(1) == 2.0);
253
254 vertex.setCoords(Vector2d(0.0, 1.0));
255 mapping.clear();
256 outData->values().setZero();
257 mapping.computeMapping();
258 mapping.map(inDataID, outDataID);
259 BOOST_TEST(mapping.hasComputedMapping() == true);
260 BOOST_TEST(outData->values()(0) == 1.0);
261 BOOST_TEST(outData->values()(1) == 2.0);
262
263 vertex.setCoords(Vector2d(1.0, 0.0));
264 mapping.clear();
265 outData->values().setZero();
266 mapping.computeMapping();
267 mapping.map(inDataID, outDataID);
268 BOOST_TEST(mapping.hasComputedMapping() == true);
269 BOOST_TEST(outData->values()(0) == 2.0);
270 BOOST_TEST(outData->values()(1) == 4.0);
271
272 vertex.setCoords(Vector2d(1.0, 0.5));
273 mapping.clear();
274 outData->values().setZero();
275 mapping.computeMapping();
276 mapping.map(inDataID, outDataID);
277 BOOST_TEST(mapping.hasComputedMapping() == true);
278 BOOST_TEST(outData->values()(0) == 2.0);
279 BOOST_TEST(outData->values()(1) == 4.0);
280
281 vertex.setCoords(Vector2d(1.0, 1.0));
282 mapping.clear();
283 outData->values().setZero();
284 mapping.computeMapping();
285 mapping.map(inDataID, outDataID);
286 BOOST_TEST(mapping.hasComputedMapping() == true);
287 BOOST_TEST(outData->values()(0) == 2.0);
288 BOOST_TEST(outData->values()(1) == 4.0);
289
290 vertex.setCoords(Vector2d(0.5, 0.0));
291 mapping.clear();
292 outData->values().setZero();
293 mapping.computeMapping();
294 mapping.map(inDataID, outDataID);
295 BOOST_TEST(mapping.hasComputedMapping() == true);
296 BOOST_TEST(outData->values()(0) == 1.5);
297 BOOST_TEST(outData->values()(1) == 3.0);
298
299 vertex.setCoords(Vector2d(0.5, 0.5));
300 mapping.clear();
301 outData->values().setZero();
302 mapping.computeMapping();
303 mapping.map(inDataID, outDataID);
304 BOOST_TEST(mapping.hasComputedMapping() == true);
305 BOOST_TEST(outData->values()(0) == 1.5);
306 BOOST_TEST(outData->values()(1) == 3.0);
307
308 vertex.setCoords(Vector2d(0.5, 1.0));
309 mapping.clear();
310 outData->values().setZero();
311 mapping.computeMapping();
312 mapping.map(inDataID, outDataID);
313 BOOST_TEST(mapping.hasComputedMapping() == true);
314 BOOST_TEST(outData->values()(0) == 1.5);
315 BOOST_TEST(outData->values()(1) == 3.0);
316}
317
318// Tests the automatic reduction of dead axis
320{
321 // Create mesh to map from
322 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dim, testing::nextMeshID()));
323 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
324 int inDataID = inData->getID();
325
326 // create 20 vertices with two very close lines
327 for (unsigned int i = 0; i < 20; ++i)
328 if (dim == 2) {
329 inMesh->createVertex(Eigen::Vector2d(0.0, 0.0 + i * dim));
330 inMesh->createVertex(Eigen::Vector2d(1e-5, 0.0 + i * dim));
331 } else {
332 inMesh->createVertex(Eigen::Vector3d(7.0, 7.0, 40 + i * dim));
333 inMesh->createVertex(Eigen::Vector3d(7.001, 7.001, 40 + i * dim));
334 }
335
336 inMesh->allocateDataValues();
337 addGlobalIndex(inMesh);
338
339 auto &values = inData->values();
340 for (std::size_t v = 0; v < 20; ++v) {
341 values[v * 2] = v * dim * 1e-5;
342 values[v * 2 + 1] = v * dim * 1e-5 + 2;
343 }
344
345 // Create mesh to map to
346 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dim, testing::nextMeshID()));
347 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
348 int outDataID = outData->getID();
349
350 for (unsigned int i = 0; i < 15; ++i) {
351 if (dim == 2)
352 outMesh->createVertex(Eigen::Vector2d(.1, 1 + 1 + i * dim));
353 else {
354 outMesh->createVertex(Eigen::Vector3d(7.4, 7.4, 41 + i * dim));
355 }
356 }
357 outMesh->allocateDataValues();
358 addGlobalIndex(outMesh);
359
360 // Setup mapping with mapping coordinates and geometry used
361 mapping.setMeshes(inMesh, outMesh);
362 BOOST_TEST(mapping.hasComputedMapping() == false);
363
364 mapping.computeMapping();
365 mapping.map(inDataID, outDataID);
366 double value = outData->values()(0);
367 double value1 = outData->values()(1);
368 double value2 = outData->values()(2);
369 BOOST_TEST(mapping.hasComputedMapping() == true);
370 if (dim == 2) {
371 BOOST_TEST(math::equals(value, 19935.374757794027, 0.2));
372 BOOST_TEST(math::equals(value1, 19935.37795225389, 0.2));
373 BOOST_TEST(math::equals(value2, 19935.35164938603, 0.2));
374 } else {
375 BOOST_TEST(value == 829.28063055069435);
376 BOOST_TEST(value1 == 819.35577218983303);
377 BOOST_TEST(value2 == 829.38388713302811);
378 }
379}
380
382{
383 int dimensions = 2;
384 using Eigen::Vector2d;
385
386 // Create mesh to map from
387 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
388 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
389 int inDataID = inData->getID();
390
391 // vertices will be changed
392 inMesh->createVertex(Vector2d(1.0, 0.0));
393 inMesh->createVertex(Vector2d(3.5, 0.0));
394 inMesh->createVertex(Vector2d(2.5, 0.5));
395
396 inMesh->createVertex(Vector2d(0, 0));
397 inMesh->createVertex(Vector2d(5, 1));
398 inMesh->allocateDataValues();
399 addGlobalIndex(inMesh);
400 inMesh->setGlobalNumberOfVertices(inMesh->nVertices());
401
402 auto &values = inData->values();
403 values << 10.0, 0.0, 0.0, 10.0, 0.0;
404 // Create mesh to map to
405 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
406 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
407 int outDataID = outData->getID();
408
409 outMesh->createVertex(Vector2d(0.0, 0.0));
410 outMesh->createVertex(Vector2d(1.0, 0.0));
411 outMesh->createVertex(Vector2d(1.0, 1.0));
412 outMesh->createVertex(Vector2d(0.0, 1.0));
413
414 outMesh->createVertex(Vector2d(2.0, 0.0));
415 outMesh->createVertex(Vector2d(3.0, 0.0));
416 outMesh->createVertex(Vector2d(3.0, 1.0));
417 outMesh->createVertex(Vector2d(2.0, 1.0));
418
419 outMesh->createVertex(Vector2d(4.0, 0.0));
420 outMesh->createVertex(Vector2d(5.0, 0.0));
421 outMesh->createVertex(Vector2d(5.0, 1.0));
422 outMesh->createVertex(Vector2d(4.0, 1.0));
423
424 outMesh->allocateDataValues();
425 addGlobalIndex(outMesh);
426 outMesh->setGlobalNumberOfVertices(outMesh->nVertices());
427
428 // Setup mapping with mapping coordinates and geometry used
429 mapping.setMeshes(inMesh, outMesh);
430 BOOST_TEST(mapping.hasComputedMapping() == false);
431
432 // Test that we get point-wise exact data values on output vertices 1 and 2
433 // remaining vertices are zero
434 mapping.computeMapping();
435 mapping.map(inDataID, outDataID);
436
437 BOOST_TEST(outData->values().sum() == inData->values().sum());
438 BOOST_TEST(outData->values()(0) == 10);
439 BOOST_TEST(outData->values()(1) == 10);
440 BOOST_TEST(outData->values()(2) == 0);
441 BOOST_TEST(outData->values()(3) == 0);
442
443 // Test that we have a symmetric solution if we have a force acting
444 // in between two output vertices (here 5 and 8), there is actually
445 // no guarantee, but it holds for this setup
446 values << 0.0, 10.0, 0.0, 0.0, 0.0;
447
448 mapping.clear();
449 outData->values().setZero();
450 mapping.computeMapping();
451 mapping.map(inDataID, outDataID);
452 BOOST_TEST(outData->values().sum() == inData->values().sum());
453 BOOST_TEST(outData->values()(5) == outData->values()(8));
454
455 // Test the conservation property if we have everywhere non-zero input data
456 values << 5.0, 10.0, 7.0, 3.0, 4.0;
457
458 mapping.clear();
459 outData->values().setZero();
460 mapping.computeMapping();
461 mapping.map(inDataID, outDataID);
462
463 BOOST_TEST(outData->values().sum() == inData->values().sum());
464 BOOST_TEST(mapping.hasComputedMapping() == true);
465
466 // Test the conservation property if we have everywhere non-zero input data
467 values << 3.0, 4.0, 5.0, 7.0, 9.0;
468
469 mapping.clear();
470 outData->values().setZero();
471 mapping.computeMapping();
472 mapping.map(inDataID, outDataID);
473 BOOST_TEST(outData->values().sum() == inData->values().sum());
474 BOOST_TEST(mapping.hasComputedMapping() == true);
475 BOOST_TEST(outData->values()(5) == 3.2931869752057001);
476}
477
479{
480 int dimensions = 2;
481 int dataDimensions = dimensions;
482 using Eigen::Vector2d;
483
484 // Create mesh to map to
485 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
486 mesh::PtrData inData = inMesh->createData("InData", dataDimensions, 0_dataID);
487 DataID inDataID = inData->getID();
488 mesh::Vertex &vertex = inMesh->createVertex(Vector2d(0, 0));
489 inMesh->createVertex(Vector2d(3.5, 0.5));
490 inMesh->createVertex(Vector2d(2.5, 0.5));
491 // vertex will be changed
492 inMesh->createVertex(Vector2d(0, 0));
493 inMesh->createVertex(Vector2d(5, 1));
494
495 inMesh->allocateDataValues();
496 addGlobalIndex(inMesh);
497
498 auto &values = inData->values();
499 // We select the second component = 2 * first component
500 values << 1.0, 2.0, 2.0, 4.0, 2.0, 4.0, 1.0, 2.0, 3.0, 6.0;
501
502 // Create mesh to map from
503 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
504 mesh::PtrData outData = outMesh->createData("OutData", dataDimensions, 1_dataID);
505 DataID outDataID = outData->getID();
506
507 outMesh->createVertex(Vector2d(0.0, 0.0));
508 outMesh->createVertex(Vector2d(1.0, 0.0));
509 outMesh->createVertex(Vector2d(1.0, 1.0));
510 outMesh->createVertex(Vector2d(0.0, 1.0));
511
512 outMesh->createVertex(Vector2d(2.0, 0.0));
513 outMesh->createVertex(Vector2d(3.0, 0.0));
514 outMesh->createVertex(Vector2d(3.0, 1.0));
515 outMesh->createVertex(Vector2d(2.0, 1.0));
516
517 outMesh->createVertex(Vector2d(4.0, 0.0));
518 outMesh->createVertex(Vector2d(5.0, 0.0));
519 outMesh->createVertex(Vector2d(5.0, 1.0));
520 outMesh->createVertex(Vector2d(4.0, 1.0));
521
522 outMesh->allocateDataValues();
523 addGlobalIndex(outMesh);
524
525 // Setup mapping with mapping coordinates and geometry used
526 mapping.setMeshes(inMesh, outMesh);
527 BOOST_TEST(mapping.hasComputedMapping() == false);
528
529 // Check that we preserve data component-wise
530 vertex.setCoords(Vector2d(1.0, 0.0));
531 mapping.computeMapping();
532 mapping.map(inDataID, outDataID);
533
534 // component 0
535 double insumc0 = sumComponentWise(inData->values(), 0, dataDimensions);
536 double outsumc0 = sumComponentWise(outData->values(), 0, dataDimensions);
537 BOOST_TEST(insumc0 == outsumc0);
538
539 // component 1
540 double insumc1 = sumComponentWise(inData->values(), 1, dataDimensions);
541 double outsumc1 = sumComponentWise(outData->values(), 1, dataDimensions);
542
543 BOOST_TEST(insumc0 * 2 == insumc1);
544 BOOST_TEST(outsumc0 * 2 == outsumc1);
545 BOOST_TEST(insumc1 == outsumc1);
546
547 BOOST_TEST(mapping.hasComputedMapping() == true);
548
549 // Check for specific sum values for each component
550 values << 1.0, 0.0, 12.0, 0.0, 2.0, 0.0, 1.0, 0.0, 3.0, 0.0;
551
552 mapping.clear();
553 outData->values().setZero();
554 mapping.computeMapping();
555 mapping.map(inDataID, outDataID);
556
557 // component 0
558 outsumc0 = sumComponentWise(outData->values(), 0, dataDimensions);
559 BOOST_TEST(19.0 == outsumc0);
560
561 // we expect no contribution for the zeroth component
562 // component 1
563 outsumc1 = sumComponentWise(outData->values(), 1, dataDimensions);
564 BOOST_TEST(0.0 == outsumc1);
565
566 BOOST_TEST(mapping.hasComputedMapping() == true);
567
568 // Check for specific sum values for each component
569 values << 0.0, 2.0, 0.0, 4.0, 0.0, 8.0, 0.0, 7.0, 0.0, 0.0;
570
571 mapping.clear();
572 outData->values().setZero();
573 mapping.computeMapping();
574 mapping.map(inDataID, outDataID);
575
576 // component 0
577 outsumc0 = sumComponentWise(outData->values(), 0, dataDimensions);
578 BOOST_TEST(0.0 == outsumc0);
579
580 // we expect no contribution for the zeroth component
581 // component 1
582 outsumc1 = sumComponentWise(outData->values(), 1, dataDimensions);
583 BOOST_TEST(21.0 == outsumc1);
584
585 BOOST_TEST(mapping.hasComputedMapping() == true);
586
587 // Check for the exact reproduction of matching vertices
588 values << 10.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27.0;
589
590 mapping.clear();
591 outData->values().setZero();
592 mapping.computeMapping();
593 mapping.map(inDataID, outDataID);
594
595 // component 0
596 outsumc0 = sumComponentWise(outData->values(), 0, dataDimensions);
597 BOOST_TEST(10.0 == outsumc0);
598 BOOST_TEST(outData->values()(2) == 10);
599
600 // component 1
601 outsumc1 = sumComponentWise(outData->values(), 1, dataDimensions);
602 BOOST_TEST(27.0 == outsumc1);
603 BOOST_TEST(outData->values()(21) == 27);
604
605 BOOST_TEST(mapping.hasComputedMapping() == true);
606
607 // Check for the interpolation at some vertex
608 values << 3.0, 6.0, 2.0, 4.0, 12.0, 24.0, 1.0, 2.0, 3.0, 6.0;
609
610 mapping.clear();
611 outData->values().setZero();
612 mapping.computeMapping();
613 mapping.map(inDataID, outDataID);
614
615 BOOST_TEST(outData->values().sum() == inData->values().sum());
616
617 double expectedValue = 3.5933508322619825;
618 // component 0
619 BOOST_TEST(outData->values()(12) == expectedValue);
620
621 // component 1
622 BOOST_TEST(outData->values()(13) == 2 * expectedValue);
623}
624
626{
627 int dimensions = 3;
628 using Eigen::Vector3d;
629
630 // Create mesh to map from
631 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
632 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
633 int inDataID = inData->getID();
634 inMesh->createVertex(Vector3d(0.0, 0.0, 0.0));
635 inMesh->createVertex(Vector3d(1.0, 0.0, 0.0));
636 inMesh->createVertex(Vector3d(1.0, 1.0, 0.0));
637 inMesh->createVertex(Vector3d(0.0, 1.0, 0.0));
638
639 inMesh->createVertex(Vector3d(0.0, 0.0, 1.0));
640 inMesh->createVertex(Vector3d(1.0, 0.0, 1.0));
641 inMesh->createVertex(Vector3d(1.0, 1.0, 1.0));
642 inMesh->createVertex(Vector3d(0.0, 1.0, 1.0));
643
644 inMesh->createVertex(Vector3d(2.0, 0.0, 0.0));
645 inMesh->createVertex(Vector3d(3.0, 0.0, 0.0));
646 inMesh->createVertex(Vector3d(3.0, 1.0, 0.0));
647 inMesh->createVertex(Vector3d(2.0, 1.0, 0.0));
648
649 inMesh->createVertex(Vector3d(2.0, 0.0, 1.0));
650 inMesh->createVertex(Vector3d(3.0, 0.0, 1.0));
651 inMesh->createVertex(Vector3d(3.0, 1.0, 1.0));
652 inMesh->createVertex(Vector3d(2.0, 1.0, 1.0));
653
654 inMesh->createVertex(Vector3d(4.0, 0.0, 0.0));
655 inMesh->createVertex(Vector3d(5.0, 0.0, 0.0));
656 inMesh->createVertex(Vector3d(5.0, 1.0, 0.0));
657 inMesh->createVertex(Vector3d(4.0, 1.0, 0.0));
658
659 inMesh->createVertex(Vector3d(4.0, 0.0, 1.0));
660 inMesh->createVertex(Vector3d(5.0, 0.0, 1.0));
661 inMesh->createVertex(Vector3d(5.0, 1.0, 1.0));
662 inMesh->createVertex(Vector3d(4.0, 1.0, 1.0));
663
664 inMesh->allocateDataValues();
665 addGlobalIndex(inMesh);
666
667 auto &values = inData->values();
668 // Set the values in the parallel (z) plane 3*values
669 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0;
670
671 // Create mesh to map to
672 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
673 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
674 int outDataID = outData->getID();
675 mesh::Vertex &vertex = outMesh->createVertex(Vector3d(0, 0, 0));
676 outMesh->createVertex(Vector3d(3.5, 0.5, 0.5));
677 outMesh->createVertex(Vector3d(2.5, 0.5, 1.0));
678 outMesh->createVertex(Vector3d(0, 0, 0.5));
679 outMesh->createVertex(Vector3d(5, 1, 0.5));
680 outMesh->allocateDataValues();
681 addGlobalIndex(outMesh);
682
683 // Setup mapping with mapping coordinates and geometry used
684 mapping.setMeshes(inMesh, outMesh);
685 BOOST_TEST(mapping.hasComputedMapping() == false);
686
687 vertex.setCoords(Vector3d(0.0, 0.0, 0.0));
688 mapping.computeMapping();
689 mapping.map(inDataID, outDataID);
690 double value = outData->values()(0);
691 double value1 = outData->values()(1);
692 double value2 = outData->values()(2);
693 BOOST_TEST(mapping.hasComputedMapping() == true);
694 BOOST_TEST(value == 1.0);
695 BOOST_TEST(value1 == 9.0);
696 BOOST_TEST(value2 == 10.5);
697
698 vertex.setCoords(Vector3d(0.0, 0.5, 0.5));
699 mapping.clear();
700 outData->values().setZero();
701 mapping.computeMapping();
702 mapping.map(inDataID, outDataID);
703 value = outData->values()(0);
704 BOOST_TEST(mapping.hasComputedMapping() == true);
705 BOOST_TEST(value == 2.0);
706
707 vertex.setCoords(Vector3d(0.0, 1.0, 1.0));
708 mapping.clear();
709 outData->values().setZero();
710 mapping.computeMapping();
711 mapping.map(inDataID, outDataID);
712 value = outData->values()(0);
713 BOOST_TEST(mapping.hasComputedMapping() == true);
714 BOOST_TEST(value == 3.0);
715
716 vertex.setCoords(Vector3d(1.0, 0.0, 0.0));
717 mapping.clear();
718 outData->values().setZero();
719 mapping.computeMapping();
720 mapping.map(inDataID, outDataID);
721 value = outData->values()(0);
722 BOOST_TEST(mapping.hasComputedMapping() == true);
723 BOOST_TEST(value == 2.0);
724
725 vertex.setCoords(Vector3d(1.0, 0.5, 0.5));
726 mapping.clear();
727 outData->values().setZero();
728 mapping.computeMapping();
729 mapping.map(inDataID, outDataID);
730 value = outData->values()(0);
731 BOOST_TEST(mapping.hasComputedMapping() == true);
732 BOOST_TEST(value == 4.0);
733
734 vertex.setCoords(Vector3d(1.0, 1.0, 1.0));
735 mapping.clear();
736 outData->values().setZero();
737 mapping.computeMapping();
738 mapping.map(inDataID, outDataID);
739 value = outData->values()(0);
740 BOOST_TEST(mapping.hasComputedMapping() == true);
741 BOOST_TEST(value == 6.0);
742
743 vertex.setCoords(Vector3d(0.5, 0.0, 0.5));
744 mapping.clear();
745 outData->values().setZero();
746 mapping.computeMapping();
747 mapping.map(inDataID, outDataID);
748 value = outData->values()(0);
749 BOOST_TEST(mapping.hasComputedMapping() == true);
750 BOOST_TEST(value == 3.0);
751
752 vertex.setCoords(Vector3d(0.5, 0.5, 1.0));
753 mapping.clear();
754 outData->values().setZero();
755 mapping.computeMapping();
756 mapping.map(inDataID, outDataID);
757 value = outData->values()(0);
758 BOOST_TEST(mapping.hasComputedMapping() == true);
759 BOOST_TEST(value == 4.5);
760
761 vertex.setCoords(Vector3d(0.5, 1.0, 0.0));
762 mapping.clear();
763 outData->values().setZero();
764 mapping.computeMapping();
765 mapping.map(inDataID, outDataID);
766 value = outData->values()(0);
767 BOOST_TEST(mapping.hasComputedMapping() == true);
768 BOOST_TEST(value == 1.5);
769}
770
771// uses scalar data in 3D
773{
774 const int dimensions = 3;
775 const int dataComponents = 1;
776
777 // Create mesh to map from
778 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
779 mesh::PtrData inData = inMesh->createData("InData", dataComponents, 0_dataID);
780 inMesh->createVertex(Eigen::Vector3d(0.0, 0.0, 0.0));
781 inMesh->createVertex(Eigen::Vector3d(1.0, 0.0, 0.0));
782 inMesh->createVertex(Eigen::Vector3d(1.0, 1.0, 0.0));
783 inMesh->createVertex(Eigen::Vector3d(0.0, 1.0, 0.0));
784
785 inMesh->createVertex(Eigen::Vector3d(0.0, 0.0, 1.0));
786 inMesh->createVertex(Eigen::Vector3d(1.0, 0.0, 1.0));
787 inMesh->createVertex(Eigen::Vector3d(1.0, 1.0, 1.0));
788 inMesh->createVertex(Eigen::Vector3d(0.0, 1.0, 1.0));
789
790 inMesh->createVertex(Eigen::Vector3d(2.0, 0.0, 0.0));
791 inMesh->createVertex(Eigen::Vector3d(3.0, 0.0, 0.0));
792 inMesh->createVertex(Eigen::Vector3d(3.0, 1.0, 0.0));
793 inMesh->createVertex(Eigen::Vector3d(2.0, 1.0, 0.0));
794
795 inMesh->createVertex(Eigen::Vector3d(2.0, 0.0, 1.0));
796 inMesh->createVertex(Eigen::Vector3d(3.0, 0.0, 1.0));
797 inMesh->createVertex(Eigen::Vector3d(3.0, 1.0, 1.0));
798 inMesh->createVertex(Eigen::Vector3d(2.0, 1.0, 1.0));
799
800 inMesh->createVertex(Eigen::Vector3d(4.0, 0.0, 0.0));
801 inMesh->createVertex(Eigen::Vector3d(5.0, 0.0, 0.0));
802 inMesh->createVertex(Eigen::Vector3d(5.0, 1.0, 0.0));
803 inMesh->createVertex(Eigen::Vector3d(4.0, 1.0, 0.0));
804
805 inMesh->createVertex(Eigen::Vector3d(4.0, 0.0, 1.0));
806 inMesh->createVertex(Eigen::Vector3d(5.0, 0.0, 1.0));
807 inMesh->createVertex(Eigen::Vector3d(5.0, 1.0, 1.0));
808 inMesh->createVertex(Eigen::Vector3d(4.0, 1.0, 1.0));
809
810 inMesh->allocateDataValues();
811 addGlobalIndex(inMesh);
812
813 auto &values = inData->values();
814
815 // Set the values in the parallel (z) plane 3*values
816 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0;
817
818 // the dummy target mesh
820
821 // Setup mapping with mapping coordinates and geometry used
822 mapping.setMeshes(inMesh, toMesh);
823 BOOST_TEST(mapping.hasComputedMapping() == false);
824 // compute the mapping (affects only the inMesh)
825 mapping.computeMapping();
826 BOOST_TEST(mapping.hasComputedMapping() == true);
827
828 // Now, we can setup the MappingDataCache with the structures
829 // from computeMapping
830 mapping::impl::MappingDataCache cache(dataComponents);
831 mapping.initializeMappingDataCache(cache);
832
833 // computeMapping and the initializeMappingDataCache are only required for changes in the input coords
834 // whereas the cache update is for new data values
835 mapping.updateMappingDataCache(cache, values);
836 // we can also give the cache a time stamp (not strictly necessary)
837 double stamp = 1;
838 cache.setTimeStamp(stamp);
839
840 // Test infrastructure
841 Eigen::MatrixXd coords(dimensions, 1);
842 Eigen::MatrixXd result(dataComponents, 1);
843
844 // Now we can evaluate at any point we want
845 coords.setZero();
846 // Check that we have the right time
847 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
848 mapping.mapConsistentAt(coords, cache, result);
849 BOOST_TEST(result(0, 0) == 1.0);
850
851 coords.col(0) = Eigen::RowVector3d(3.5, 0.5, 0.5);
852 // Check that we have the right time
853 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
854 mapping.mapConsistentAt(coords, cache, result);
855 BOOST_TEST(result(0, 0) == 9.0);
856
857 coords.col(0) = Eigen::RowVector3d(2.5, 0.5, 1.0);
858 // Check that we have the right time
859 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
860 mapping.mapConsistentAt(coords, cache, result);
861 BOOST_TEST(result(0, 0) == 10.5);
862
863 // We can also pass multiple vertices at once
864 coords.resize(dimensions, 3);
865 result.resize(dataComponents, 3);
866
867 coords.col(0) = Eigen::RowVector3d(0.0, 0.5, 0.5);
868 coords.col(1) = Eigen::RowVector3d(0.0, 1.0, 1.0);
869 coords.col(2) = Eigen::RowVector3d(1.0, 0.0, 0.0);
870 // Check that we have the right time
871 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
872 mapping.mapConsistentAt(coords, cache, result);
873 BOOST_TEST(result(0, 0) == 2.0);
874 BOOST_TEST(result(0, 1) == 3.0);
875 BOOST_TEST(result(0, 2) == 2.0);
876
877 // Now we alter the data (double values)
878 values *= 2;
879 // Mapping remains the same
880 BOOST_TEST(mapping.hasComputedMapping() == true);
881 // Step 1: invalidate cache (happens in the DataContext)
882 cache.resetTimeStamp();
883 BOOST_TEST(!cache.hasDataAtTimeStamp(stamp));
884 // Step 2: update the cache
885 mapping.updateMappingDataCache(cache, values);
886 // Step 3: mark the cache
887 stamp = 2.0;
888 cache.setTimeStamp(stamp);
889 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
890
891 // Ready for new mappings
892 mapping.mapConsistentAt(coords, cache, result);
893 BOOST_TEST(result(0, 0) == 4.0);
894 BOOST_TEST(result(0, 1) == 6.0);
895 BOOST_TEST(result(0, 2) == 4.0);
896
897 coords.col(0) = Eigen::RowVector3d(0.5, 0.0, 0.5);
898 coords.col(1) = Eigen::RowVector3d(0.5, 0.5, 1.0);
899 coords.col(2) = Eigen::RowVector3d(0.5, 1.0, 0.0);
900 // Check that we have the right time
901 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
902 mapping.mapConsistentAt(coords, cache, result);
903 BOOST_TEST(result(0, 0) == 6.0);
904 BOOST_TEST(result(0, 1) == 9.0);
905 BOOST_TEST(result(0, 2) == 3.0);
906
907 // If we clear the mapping, the we have to recompute it
908 mapping.clear();
909 // We just clear the mesh index here instead of calling mesh.clear
910 // to not repeat all the vertices above. Recomputing the index is require
911 // when altering the mesh
912 inMesh->index().clear();
913 // We extend the mesh a bit
914 inMesh->createVertex(Eigen::Vector3d(6.0, 0.0, 0.0));
915 inMesh->createVertex(Eigen::Vector3d(7.0, 0.0, 0.0));
916 inMesh->createVertex(Eigen::Vector3d(7.0, 1.0, 0.0));
917 inMesh->createVertex(Eigen::Vector3d(6.0, 1.0, 0.0));
918 inMesh->allocateDataValues();
919 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0, 7.0, 8.0, 8.0, 7.0;
920 // Setup mapping with mapping coordinates and geometry used
921 mapping.setMeshes(inMesh, toMesh);
922 BOOST_TEST(mapping.hasComputedMapping() == false);
923 // compute the mapping (affects only the inMesh)
924 mapping.computeMapping();
925 BOOST_TEST(mapping.hasComputedMapping() == true);
926
927 cache.resetTimeStamp();
928 mapping.initializeMappingDataCache(cache);
929 mapping.updateMappingDataCache(cache, values);
930 cache.setTimeStamp(stamp);
931 coords.col(0) = Eigen::RowVector3d(6.5, 1.0, 0.0);
932 mapping.mapConsistentAt(coords, cache, result);
933 BOOST_TEST(result(0, 0) == 7.5);
934 BOOST_TEST(result(0, 1) == 4.5);
935 BOOST_TEST(result(0, 2) == 1.5);
936}
937
938// uses vectorial data in 2D
940{
941 int dimensions = 2;
942 int dataComponents = 2;
943
944 // Create mesh to map from
945 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
946 mesh::PtrData inData = inMesh->createData("InData", dataComponents, 0_dataID);
947 inMesh->createVertex(Eigen::Vector2d(0.0, 0.0));
948 inMesh->createVertex(Eigen::Vector2d(1.0, 0.0));
949 inMesh->createVertex(Eigen::Vector2d(1.0, 1.0));
950 inMesh->createVertex(Eigen::Vector2d(0.0, 1.0));
951
952 inMesh->createVertex(Eigen::Vector2d(2.0, 0.0));
953 inMesh->createVertex(Eigen::Vector2d(3.0, 0.0));
954 inMesh->createVertex(Eigen::Vector2d(3.0, 1.0));
955 inMesh->createVertex(Eigen::Vector2d(2.0, 1.0));
956
957 inMesh->createVertex(Eigen::Vector2d(4.0, 0.0));
958 inMesh->createVertex(Eigen::Vector2d(5.0, 0.0));
959 inMesh->createVertex(Eigen::Vector2d(5.0, 1.0));
960 inMesh->createVertex(Eigen::Vector2d(4.0, 1.0));
961
962 inMesh->allocateDataValues();
963 addGlobalIndex(inMesh);
964
965 auto &values = inData->values();
966
967 // Set the values in the parallel (z) plane 3*values
968 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0;
969
970 // the dummy target mesh
972
973 // Setup mapping with mapping coordinates and geometry used
974 mapping.setMeshes(inMesh, toMesh);
975 BOOST_TEST(mapping.hasComputedMapping() == false);
976 // compute the mapping (affects only the inMesh)
977 mapping.computeMapping();
978 BOOST_TEST(mapping.hasComputedMapping() == true);
979
980 // Now, we can setup the MappingDataCache with the structures
981 // from computeMapping
982 mapping::impl::MappingDataCache cache(dataComponents);
983 mapping.initializeMappingDataCache(cache);
984
985 // computeMapping and the initializeMappingDataCache are only required for changes in the input coords
986 // whereas the cache update is for new data values
987 mapping.updateMappingDataCache(cache, values);
988 // we can also give the cache a time stamp (not strictly necessary)
989 double stamp = 1;
990 cache.setTimeStamp(stamp);
991
992 // Test infrastructure
993 Eigen::MatrixXd coords(dimensions, 1);
994 Eigen::MatrixXd result(dataComponents, 1);
995
996 // Now we can evaluate at any point we want
997 coords.setZero();
998 // Check that we have the right time
999 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1000 mapping.mapConsistentAt(coords, cache, result);
1001 BOOST_TEST(result(0, 0) == 1.0);
1002 BOOST_TEST(result(1, 0) == 2.0);
1003
1004 // Second last point given
1005 coords.col(0) = Eigen::RowVector2d(5.0, 1.0);
1006 // Check that we have the right time
1007 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1008 mapping.mapConsistentAt(coords, cache, result);
1009 BOOST_TEST(result(0, 0) == 15.0);
1010 BOOST_TEST(result(1, 0) == 18.0);
1011
1012 // Between the first and the second point
1013 coords.col(0) = Eigen::RowVector2d(0.5, 0.0);
1014 // Check that we have the right time
1015 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1016 mapping.mapConsistentAt(coords, cache, result);
1017 BOOST_TEST(result(0, 0) == 1.71978075, boost::test_tools::tolerance(1e-7));
1018 BOOST_TEST(result(1, 0) == 1.71978075, boost::test_tools::tolerance(1e-7));
1019
1020 coords.col(0) = Eigen::RowVector2d(3.5, 0.5);
1021 // Check that we have the right time
1022 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1023 mapping.mapConsistentAt(coords, cache, result);
1024 BOOST_TEST(result(0, 0) == 10.39684625, boost::test_tools::tolerance(1e-7));
1025 BOOST_TEST(result(1, 0) == 10.48101386, boost::test_tools::tolerance(1e-7));
1026
1027 // We can also pass multiple vertices at once
1028 coords.resize(dimensions, 2);
1029 result.resize(dataComponents, 2);
1030
1031 coords.col(0) = Eigen::RowVector2d(4.0, 0.0);
1032 coords.col(1) = Eigen::RowVector2d(5.0, 0.0);
1033 // // Check that we have the right time
1034 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1035 mapping.mapConsistentAt(coords, cache, result);
1036 BOOST_TEST(result(0, 0) == 5.0);
1037 BOOST_TEST(result(1, 0) == 6.0);
1038 BOOST_TEST(result(0, 1) == 6.0);
1039 BOOST_TEST(result(1, 1) == 5.0);
1040
1041 // Now we alter the data (double values)
1042 values *= 0.5;
1043 // Mapping remains the same
1044 BOOST_TEST(mapping.hasComputedMapping() == true);
1045 // Step 1: invalidate cache (happens in the DataContext)
1046 cache.resetTimeStamp();
1047 BOOST_TEST(!cache.hasDataAtTimeStamp(stamp));
1048 // Step 2: update the cache
1049 mapping.updateMappingDataCache(cache, values);
1050 // Step 3: mark the cache
1051 stamp = 2.0;
1052 cache.setTimeStamp(stamp);
1053 BOOST_TEST(cache.hasDataAtTimeStamp(stamp));
1054
1055 // Ready for new mappings
1056 mapping.mapConsistentAt(coords, cache, result);
1057 BOOST_TEST(result(0, 0) == 2.5);
1058 BOOST_TEST(result(1, 0) == 3.0);
1059 BOOST_TEST(result(0, 1) == 3.0);
1060 BOOST_TEST(result(1, 1) == 2.5);
1061
1062 // If we clear the mapping, the we have to recompute it
1063 mapping.clear();
1064 // We just clear the mesh index here instead of calling mesh.clear
1065 // to not repeat all the vertices above. Recomputing the index is require
1066 // when altering the mesh
1067 inMesh->index().clear();
1068 // We extend the mesh a bit
1069 inMesh->createVertex(Eigen::Vector2d(6.0, 0.0));
1070 inMesh->createVertex(Eigen::Vector2d(7.0, 0.0));
1071 inMesh->createVertex(Eigen::Vector2d(7.0, 1.0));
1072 inMesh->createVertex(Eigen::Vector2d(6.0, 1.0));
1073 inMesh->allocateDataValues();
1074 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0, 7.0, 8.0, 8.0, 7.0, 20.0, 22.0, 22.0, 20.0;
1075 // Setup mapping with mapping coordinates and geometry used
1076 mapping.setMeshes(inMesh, toMesh);
1077 BOOST_TEST(mapping.hasComputedMapping() == false);
1078 // compute the mapping (affects only the inMesh)
1079 mapping.computeMapping();
1080 BOOST_TEST(mapping.hasComputedMapping() == true);
1081
1082 cache.resetTimeStamp();
1083 mapping.initializeMappingDataCache(cache);
1084 mapping.updateMappingDataCache(cache, values);
1085 cache.setTimeStamp(stamp);
1086
1087 mapping.mapConsistentAt(coords, cache, result);
1088 BOOST_TEST(result(0, 0) == 5.0);
1089 BOOST_TEST(result(1, 0) == 6.0);
1090 BOOST_TEST(result(0, 1) == 6.0);
1091 BOOST_TEST(result(1, 1) == 5.0);
1092
1093 coords.col(0) = Eigen::RowVector2d(7.0, 1.0);
1094 coords.col(1) = Eigen::RowVector2d(6.0, 0.0);
1095 mapping.mapConsistentAt(coords, cache, result);
1096 BOOST_TEST(result(0, 0) == 20.0);
1097 BOOST_TEST(result(1, 0) == 22.0);
1098 BOOST_TEST(result(0, 1) == 7.0);
1099 BOOST_TEST(result(1, 1) == 8.0);
1100}
1101
1103{
1104 int dimensions = 3;
1105 int dataDimensions = dimensions;
1106
1107 using Eigen::Vector3d;
1108
1109 // Create mesh to map from
1110 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
1111 mesh::PtrData inData = inMesh->createData("InData", dataDimensions, 0_dataID);
1112 int inDataID = inData->getID();
1113 inMesh->createVertex(Vector3d(0.0, 0.0, 0.0));
1114 inMesh->createVertex(Vector3d(1.0, 0.0, 0.0));
1115 inMesh->createVertex(Vector3d(1.0, 1.0, 0.0));
1116 inMesh->createVertex(Vector3d(0.0, 1.0, 0.0));
1117
1118 inMesh->createVertex(Vector3d(0.0, 0.0, 1.0));
1119 inMesh->createVertex(Vector3d(1.0, 0.0, 1.0));
1120 inMesh->createVertex(Vector3d(1.0, 1.0, 1.0));
1121 inMesh->createVertex(Vector3d(0.0, 1.0, 1.0));
1122
1123 inMesh->createVertex(Vector3d(2.0, 0.0, 0.0));
1124 inMesh->createVertex(Vector3d(3.0, 0.0, 0.0));
1125 inMesh->createVertex(Vector3d(3.0, 1.0, 0.0));
1126 inMesh->createVertex(Vector3d(2.0, 1.0, 0.0));
1127
1128 inMesh->createVertex(Vector3d(2.0, 0.0, 1.0));
1129 inMesh->createVertex(Vector3d(3.0, 0.0, 1.0));
1130 inMesh->createVertex(Vector3d(3.0, 1.0, 1.0));
1131 inMesh->createVertex(Vector3d(2.0, 1.0, 1.0));
1132
1133 inMesh->createVertex(Vector3d(4.0, 0.0, 0.0));
1134 inMesh->createVertex(Vector3d(5.0, 0.0, 0.0));
1135 inMesh->createVertex(Vector3d(5.0, 1.0, 0.0));
1136 inMesh->createVertex(Vector3d(4.0, 1.0, 0.0));
1137
1138 inMesh->createVertex(Vector3d(4.0, 0.0, 1.0));
1139 inMesh->createVertex(Vector3d(5.0, 0.0, 1.0));
1140 inMesh->createVertex(Vector3d(5.0, 1.0, 1.0));
1141 inMesh->createVertex(Vector3d(4.0, 1.0, 1.0));
1142
1143 inMesh->allocateDataValues();
1144 addGlobalIndex(inMesh);
1145
1146 // Create mesh to map to
1147 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1148 mesh::PtrData outData = outMesh->createData("OutData", dataDimensions, 1_dataID);
1149 int outDataID = outData->getID();
1150 outMesh->createVertex(Vector3d(0, 0, 0));
1151 outMesh->createVertex(Vector3d(3.5, 0.5, 0.5));
1152 outMesh->createVertex(Vector3d(2.5, 0.5, 1.0));
1153 outMesh->createVertex(Vector3d(0, 0, 0.5));
1154 outMesh->createVertex(Vector3d(5, 1, 0.5));
1155 outMesh->allocateDataValues();
1156 addGlobalIndex(outMesh);
1157
1158 // Setup mapping with mapping coordinates and geometry used
1159 mapping.setMeshes(inMesh, outMesh);
1160 BOOST_TEST(mapping.hasComputedMapping() == false);
1161
1162 for (unsigned int i = 0; i < inData->values().size() / dataDimensions; ++i) {
1163 inData->values()(i * dataDimensions) = 7;
1164 inData->values()(i * dataDimensions + 1) = 38;
1165 inData->values()(i * dataDimensions + 2) = 19;
1166 }
1167
1168 // Check for the independent interpolation of each component when applying a constant field
1169 mapping.computeMapping();
1170 mapping.map(inDataID, outDataID);
1171 BOOST_TEST(mapping.hasComputedMapping() == true);
1172 BOOST_TEST(outData->values()(0) == 7.0);
1173 BOOST_TEST(outData->values()(1) == 38.0);
1174 BOOST_TEST(outData->values()(2) == 19.0);
1175 BOOST_TEST(outData->values()(9) == 7.0);
1176 BOOST_TEST(outData->values()(10) == 38.0);
1177 BOOST_TEST(outData->values()(11) == 19.0);
1178
1179 // Check for the consistency between individual components
1180 for (unsigned int i = 0; i < inData->values().size() / dataDimensions; ++i) {
1181 inData->values()(i * dataDimensions) = std::pow(i * dataDimensions, 2);
1182 inData->values()(i * dataDimensions + 1) = 2 * std::pow(i * dataDimensions, 2);
1183 inData->values()(i * dataDimensions + 2) = 3 * std::pow(i * dataDimensions, 2);
1184 }
1185
1186 mapping.clear();
1187 outData->values().setZero();
1188 mapping.computeMapping();
1189 mapping.map(inDataID, outDataID);
1190 BOOST_TEST(mapping.hasComputedMapping() == true);
1191 BOOST_TEST(outData->values()(12) == 3673.7308684337013);
1192 BOOST_TEST(outData->values()(13) == 2 * outData->values()(12));
1193 BOOST_TEST(outData->values()(14) == 3 * outData->values()(12));
1194
1195 // The remaining parts should already be covered by the other 3D/2D tests
1196}
1197
1199{
1200 int dimensions = 3;
1201 using Eigen::Vector3d;
1202
1203 // Create mesh to map from
1204 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
1205 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
1206 const DataID inDataID = inData->getID();
1207 inMesh->createVertex(Vector3d(0, 0, 0));
1208 inMesh->createVertex(Vector3d(3.5, 0.5, 0.5));
1209 inMesh->createVertex(Vector3d(2.5, 0.5, 1.0));
1210 inMesh->createVertex(Vector3d(1, 1, 1));
1211 inMesh->createVertex(Vector3d(5, 1, 0.5));
1212 inMesh->allocateDataValues();
1213 addGlobalIndex(inMesh);
1214
1215 // Create mesh to map from
1216 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1217 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
1218 const DataID outDataID = outData->getID();
1219 outMesh->createVertex(Vector3d(0.0, 0.0, 0.0));
1220 outMesh->createVertex(Vector3d(1.0, 0.0, 0.0));
1221 outMesh->createVertex(Vector3d(1.0, 1.0, 0.0));
1222 outMesh->createVertex(Vector3d(0.0, 1.0, 0.0));
1223
1224 outMesh->createVertex(Vector3d(0.0, 0.0, 1.0));
1225 outMesh->createVertex(Vector3d(1.0, 0.0, 1.0));
1226 outMesh->createVertex(Vector3d(1.0, 1.0, 1.0));
1227 outMesh->createVertex(Vector3d(0.0, 1.0, 1.0));
1228
1229 outMesh->createVertex(Vector3d(2.0, 0.0, 0.0));
1230 outMesh->createVertex(Vector3d(3.0, 0.0, 0.0));
1231 outMesh->createVertex(Vector3d(3.0, 1.0, 0.0));
1232 outMesh->createVertex(Vector3d(2.0, 1.0, 0.0));
1233
1234 outMesh->createVertex(Vector3d(2.0, 0.0, 1.0));
1235 outMesh->createVertex(Vector3d(3.0, 0.0, 1.0));
1236 outMesh->createVertex(Vector3d(3.0, 1.0, 1.0));
1237 outMesh->createVertex(Vector3d(2.0, 1.0, 1.0));
1238
1239 outMesh->createVertex(Vector3d(4.0, 0.0, 0.0));
1240 outMesh->createVertex(Vector3d(5.0, 0.0, 0.0));
1241 outMesh->createVertex(Vector3d(5.0, 1.0, 0.0));
1242 outMesh->createVertex(Vector3d(4.0, 1.0, 0.0));
1243
1244 outMesh->createVertex(Vector3d(4.0, 0.0, 1.0));
1245 outMesh->createVertex(Vector3d(5.0, 0.0, 1.0));
1246 outMesh->createVertex(Vector3d(5.0, 1.0, 1.0));
1247 outMesh->createVertex(Vector3d(4.0, 1.0, 1.0));
1248
1249 outMesh->allocateDataValues();
1250 addGlobalIndex(outMesh);
1251
1252 // Setup mapping with mapping coordinates and geometry used
1253 mapping.setMeshes(inMesh, outMesh);
1254 BOOST_TEST(mapping.hasComputedMapping() == false);
1255
1256 auto &values = inData->values();
1257 // Some arbitrary input values in order to check conservation
1258 values << 1.0, 2.0, 2.0, 1.0, 3.0;
1259
1260 mapping.computeMapping();
1261 mapping.map(inDataID, outDataID);
1262 BOOST_TEST(mapping.hasComputedMapping() == true);
1263 BOOST_TEST(outData->values().sum() == inData->values().sum());
1264
1265 // Check for the exact reproduction of individual values
1266 values << 12.0, 5.0, 7.0, 8.0, 9.0;
1267
1268 mapping.clear();
1269 outData->values().setZero();
1270 mapping.computeMapping();
1271 mapping.map(inDataID, outDataID);
1272 BOOST_TEST(mapping.hasComputedMapping() == true);
1273 const double expectedSum = 41;
1274 BOOST_TEST(outData->values().sum() == expectedSum);
1275 BOOST_TEST(outData->values()(6) == 8);
1276 BOOST_TEST(outData->values()(0) == 12);
1277
1278 // Check for consistency (applying a heavy load to the front layer z = 1)
1279 values << 0.0, 50.0, 107.0, 108.0, 48.0;
1280
1281 mapping.clear();
1282 outData->values().setZero();
1283 mapping.computeMapping();
1284 mapping.map(inDataID, outDataID);
1285 BOOST_TEST(mapping.hasComputedMapping() == true);
1286 BOOST_TEST(outData->values().sum() == inData->values().sum());
1287 BOOST_TEST(outData->values()(0) == 0.0);
1288 BOOST_TEST(outData->values()(6) > outData->values()(1));
1289 BOOST_TEST(outData->values()(13) > outData->values()(9));
1290
1291 // Check for symmetry when applying a central load (not guaranteed ?)
1292 values << 0.0, 100.0, 0.0, 0.0, 0.0;
1293
1294 mapping.clear();
1295 outData->values().setZero();
1296 mapping.computeMapping();
1297 mapping.map(inDataID, outDataID);
1298 BOOST_TEST(mapping.hasComputedMapping() == true);
1299 BOOST_TEST(outData->values().sum() == inData->values().sum());
1300 BOOST_TEST(outData->values()(9) == outData->values()(13));
1301 BOOST_TEST(outData->values()(9) == outData->values()(10));
1302 BOOST_TEST(outData->values()(16) == outData->values()(19));
1303 // TODO: There is no symmetry between the (3, x, x) and (4, x , x) layer
1304 // as the domain length is 5 and we have a partition center at x = 2.9 and x = 3.75
1305 // BOOST_TEST(outData->values()(16) == outData->values()(9));
1306 BOOST_TEST(outData->values()(20) == outData->values()(23));
1307 BOOST_TEST(outData->values()(16) == outData->values()(20));
1308 BOOST_TEST(outData->values()(9) == 15.470584170385226);
1309}
1310
1312{
1313 const int dimensions = 3;
1314 const int dataComponents = 1;
1315
1316 // the dummy from mesh
1318
1319 // Create mesh to map from
1320 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1321 mesh::PtrData outData = outMesh->createData("OutData", dataComponents, 1_dataID);
1322
1323 outMesh->createVertex(Eigen::Vector3d(0.0, 0.0, 0.0));
1324 outMesh->createVertex(Eigen::Vector3d(1.0, 0.0, 0.0));
1325 outMesh->createVertex(Eigen::Vector3d(1.0, 1.0, 0.0));
1326 outMesh->createVertex(Eigen::Vector3d(0.0, 1.0, 0.0));
1327
1328 outMesh->createVertex(Eigen::Vector3d(0.0, 0.0, 1.0));
1329 outMesh->createVertex(Eigen::Vector3d(1.0, 0.0, 1.0));
1330 outMesh->createVertex(Eigen::Vector3d(1.0, 1.0, 1.0));
1331 outMesh->createVertex(Eigen::Vector3d(0.0, 1.0, 1.0));
1332
1333 outMesh->createVertex(Eigen::Vector3d(2.0, 0.0, 0.0));
1334 outMesh->createVertex(Eigen::Vector3d(3.0, 0.0, 0.0));
1335 outMesh->createVertex(Eigen::Vector3d(3.0, 1.0, 0.0));
1336 outMesh->createVertex(Eigen::Vector3d(2.0, 1.0, 0.0));
1337
1338 outMesh->createVertex(Eigen::Vector3d(2.0, 0.0, 1.0));
1339 outMesh->createVertex(Eigen::Vector3d(3.0, 0.0, 1.0));
1340 outMesh->createVertex(Eigen::Vector3d(3.0, 1.0, 1.0));
1341 outMesh->createVertex(Eigen::Vector3d(2.0, 1.0, 1.0));
1342
1343 outMesh->createVertex(Eigen::Vector3d(4.0, 0.0, 0.0));
1344 outMesh->createVertex(Eigen::Vector3d(5.0, 0.0, 0.0));
1345 outMesh->createVertex(Eigen::Vector3d(5.0, 1.0, 0.0));
1346 outMesh->createVertex(Eigen::Vector3d(4.0, 1.0, 0.0));
1347
1348 outMesh->createVertex(Eigen::Vector3d(4.0, 0.0, 1.0));
1349 outMesh->createVertex(Eigen::Vector3d(5.0, 0.0, 1.0));
1350 outMesh->createVertex(Eigen::Vector3d(5.0, 1.0, 1.0));
1351 outMesh->createVertex(Eigen::Vector3d(4.0, 1.0, 1.0));
1352
1353 outMesh->allocateDataValues();
1354 addGlobalIndex(outMesh);
1355
1356 // Setup mapping with mapping coordinates and geometry used
1357 mapping.setMeshes(inMesh, outMesh);
1358 BOOST_TEST(mapping.hasComputedMapping() == false);
1359
1360 mapping.computeMapping();
1361 BOOST_TEST(mapping.hasComputedMapping() == true);
1362
1363 // Now, we can setup the MappingDataCache with the structures
1364 // from computeMapping before starting the mappings
1365 mapping::impl::MappingDataCache cache(dataComponents);
1366 mapping.initializeMappingDataCache(cache);
1367
1368 // Test infrastructure/ the user input
1369 Eigen::MatrixXd coords(dimensions, 1);
1370 Eigen::MatrixXd inData(dataComponents, 1);
1371 Eigen::Map<Eigen::MatrixXd> outValues(outData->values().data(), dataComponents, outMesh->vertices().size());
1372
1373 // before writing first, we have to reset the cache to contain zeros
1374 cache.resetData();
1375 outValues.setZero();
1376
1377 coords.col(0) = Eigen::RowVector3d(5.0, 0.0, 1.0);
1378 inData(0, 0) = 4.3;
1379 // note that the outvalues are only filled in the completeJustInTimeMapping
1380 mapping.mapConservativeAt(coords, inData, cache, outValues);
1381
1382 // Once all values are written, we complete the mapping (expensive part)
1383 mapping.completeJustInTimeMapping(cache, outValues);
1384 BOOST_TEST(outValues.sum() == inData.sum());
1385 Eigen::VectorXd expectedValues(24);
1386 expectedValues.setZero();
1387 expectedValues(21) = 4.3;
1388 BOOST_TEST(outData->values() == expectedValues, boost::test_tools::per_element());
1389
1390 // clear data again for the next go
1391 cache.resetData();
1392 outValues.setZero();
1393
1394 // if we call the function twice for the same coordinate, we get twice the contribution
1395 mapping.mapConservativeAt(coords, inData, cache, outValues);
1396 mapping.mapConservativeAt(coords, inData, cache, outValues);
1397 mapping.completeJustInTimeMapping(cache, outValues);
1398 BOOST_TEST(outValues.sum() == 2 * inData.sum());
1399 BOOST_TEST(outData->values() == 2 * expectedValues, boost::test_tools::per_element());
1400
1401 // clear data again for the next go
1402 cache.resetData();
1403 outValues.setZero();
1404
1405 double expectedSum = 0;
1406 mapping.mapConservativeAt(coords, inData, cache, outValues);
1407 expectedSum += inData.sum();
1408
1409 // We can also change the shape of the user input
1410 coords.resize(dimensions, 3);
1411 inData.resize(dataComponents, 3);
1412 coords.col(0) = Eigen::RowVector3d(3.5, 0.5, 0.5);
1413 coords.col(1) = Eigen::RowVector3d(4.5, 1.0, 1.0);
1414 coords.col(2) = Eigen::RowVector3d(0.1, 0.0, 1.0);
1415 inData(0, 0) = 4.3;
1416 inData(0, 1) = 17.3;
1417 inData(0, 2) = 5.8;
1418 mapping.mapConservativeAt(coords, inData, cache, outValues);
1419 expectedSum += inData.sum();
1420
1421 mapping.completeJustInTimeMapping(cache, outValues);
1422 BOOST_TEST(outValues.sum() == expectedSum);
1423 BOOST_TEST(outValues(0, 6) == 0.063700286667, boost::test_tools::tolerance(1e-7));
1424 BOOST_TEST(outValues(0, 23) == 9.2744883594, boost::test_tools::tolerance(1e-7));
1425
1426 // next go
1427 cache.resetData();
1428 outValues.setZero();
1429 expectedSum = 0;
1430
1431 // We can use different shapes for different calls
1432 coords.col(0) = Eigen::RowVector3d(0, 0, 0);
1433 coords.col(1) = Eigen::RowVector3d(3.5, 0.5, 0.5);
1434 coords.col(2) = Eigen::RowVector3d(2.5, 0.5, 1.0);
1435 inData(0, 0) = 0;
1436 inData(0, 1) = 50;
1437 inData(0, 2) = 107;
1438 mapping.mapConservativeAt(coords, inData, cache, outValues);
1439 expectedSum += inData.sum();
1440
1441 coords.resize(dimensions, 2);
1442 inData.resize(dataComponents, 2);
1443 coords.col(0) = Eigen::RowVector3d(1, 1, 1);
1444 coords.col(1) = Eigen::RowVector3d(5, 1, 0.5);
1445 inData(0, 0) = 108;
1446 inData(0, 1) = 48;
1447 mapping.mapConservativeAt(coords, inData, cache, outValues);
1448 expectedSum += inData.sum();
1449
1450 mapping.completeJustInTimeMapping(cache, outValues);
1451 BOOST_TEST(outValues.sum() == expectedSum);
1452
1453 BOOST_TEST(mapping.hasComputedMapping() == true);
1454 BOOST_TEST(outData->values()(0) == 0.0);
1455 BOOST_TEST(outData->values()(6) > outData->values()(1));
1456 BOOST_TEST(outData->values()(13) > outData->values()(9));
1457
1458 // Now we check for re-computing the mapping after changing the mesh
1459 mapping.clear();
1460 outMesh->index().clear();
1461 outMesh->createVertex(Eigen::Vector3d(6, 0, 0));
1462 outMesh->allocateDataValues();
1463
1464 BOOST_TEST(mapping.hasComputedMapping() == false);
1465 mapping.computeMapping();
1466 BOOST_TEST(mapping.hasComputedMapping() == true);
1467
1468 mapping.initializeMappingDataCache(cache);
1469
1470 Eigen::Map<Eigen::MatrixXd> outValues2(outData->values().data(), dataComponents, outMesh->vertices().size());
1471
1472 // before writing first, we have to reset the cache to contain zeros
1473 cache.resetData();
1474 outValues2.setZero();
1475 expectedSum = 0;
1476
1477 coords.resize(dimensions, 1);
1478 inData.resize(dataComponents, 1);
1479 coords.col(0) = Eigen::RowVector3d(0.5, 0.5, 0.5);
1480 inData(0, 0) = 4.3;
1481 mapping.mapConservativeAt(coords, inData, cache, outValues2);
1482 expectedSum += inData.sum();
1483 coords.col(0) = Eigen::RowVector3d(6.0, 0, 0);
1484 inData(0, 0) = 42;
1485 mapping.mapConservativeAt(coords, inData, cache, outValues2);
1486 expectedSum += inData.sum();
1487
1488 mapping.completeJustInTimeMapping(cache, outValues2);
1489 BOOST_TEST(outValues2.sum() == expectedSum);
1490 BOOST_TEST(outValues2(0, 24) == 42, boost::test_tools::tolerance(1e-12));
1491 BOOST_TEST(outValues2(0, 0) == 0.505106848, boost::test_tools::tolerance(1e-7));
1492}
1493
1495{
1496 const int dimensions = 2;
1497 const int dataComponents = 2;
1498
1499 // the dummy from mesh
1501
1502 // Create mesh to map from
1503 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1504 mesh::PtrData outData = outMesh->createData("OutData", dataComponents, 1_dataID);
1505
1506 outMesh->createVertex(Eigen::Vector2d(0.0, 0.0));
1507 outMesh->createVertex(Eigen::Vector2d(1.0, 0.0));
1508 outMesh->createVertex(Eigen::Vector2d(1.0, 1.0));
1509 outMesh->createVertex(Eigen::Vector2d(0.0, 1.0));
1510
1511 outMesh->createVertex(Eigen::Vector2d(2.0, 0.0));
1512 outMesh->createVertex(Eigen::Vector2d(3.0, 0.0));
1513 outMesh->createVertex(Eigen::Vector2d(3.0, 1.0));
1514 outMesh->createVertex(Eigen::Vector2d(2.0, 1.0));
1515
1516 outMesh->createVertex(Eigen::Vector2d(4.0, 0.0));
1517 outMesh->createVertex(Eigen::Vector2d(5.0, 0.0));
1518 outMesh->createVertex(Eigen::Vector2d(5.0, 1.0));
1519 outMesh->createVertex(Eigen::Vector2d(4.0, 1.0));
1520
1521 outMesh->allocateDataValues();
1522 addGlobalIndex(outMesh);
1523
1524 // Setup mapping with mapping coordinates and geometry used
1525 mapping.setMeshes(inMesh, outMesh);
1526 BOOST_TEST(mapping.hasComputedMapping() == false);
1527
1528 mapping.computeMapping();
1529 BOOST_TEST(mapping.hasComputedMapping() == true);
1530
1531 // Now, we can setup the MappingDataCache with the structures
1532 // from computeMapping before starting the mappings
1533 mapping::impl::MappingDataCache cache(dataComponents);
1534 mapping.initializeMappingDataCache(cache);
1535
1536 // Test infrastructure/ the user input
1537 Eigen::MatrixXd coords(dimensions, 1);
1538 Eigen::MatrixXd inData(dataComponents, 1);
1539 Eigen::Map<Eigen::MatrixXd> outValues(outData->values().data(), dataComponents, outMesh->vertices().size());
1540
1541 // before writing first, we have to reset the cache to contain zeros
1542 cache.resetData();
1543 outValues.setZero();
1544
1545 coords.col(0) = Eigen::RowVector2d(5.0, 0.0);
1546 inData.col(0) = Eigen::RowVector2d(7.3, 14.6);
1547
1548 // note that the outvalues are only filled in the completeJustInTimeMapping
1549 mapping.mapConservativeAt(coords, inData, cache, outValues);
1550
1551 // Once all values are written, we complete the mapping (expensive part)
1552 mapping.completeJustInTimeMapping(cache, outValues);
1553 BOOST_TEST(outValues.sum() == inData.sum());
1554 Eigen::MatrixXd expectedValues(dataComponents, 12);
1555 expectedValues.setZero();
1556 expectedValues.col(9) = Eigen::RowVector2d(7.3, 14.6);
1557 BOOST_TEST(outValues.row(0) == expectedValues.row(0), boost::test_tools::per_element());
1558 BOOST_TEST(outValues.row(1) == expectedValues.row(1), boost::test_tools::per_element());
1559 BOOST_TEST(outValues.row(0) == 0.5 * outValues.row(1), boost::test_tools::per_element());
1560
1561 // clear data again for the next go
1562 cache.resetData();
1563 outValues.setZero();
1564
1565 // // if we call the function twice for the same coordinate, we get twice the contribution
1566 mapping.mapConservativeAt(coords, inData, cache, outValues);
1567 mapping.mapConservativeAt(coords, inData, cache, outValues);
1568 mapping.completeJustInTimeMapping(cache, outValues);
1569 BOOST_TEST(outValues.row(0) == 2 * expectedValues.row(0), boost::test_tools::per_element());
1570 BOOST_TEST(outValues.row(1) == 2 * expectedValues.row(1), boost::test_tools::per_element());
1571 BOOST_TEST(outValues.row(0) == 0.5 * outValues.row(1), boost::test_tools::per_element());
1572
1573 // // clear data again for the next go
1574 cache.resetData();
1575 outValues.setZero();
1576
1577 Eigen::Vector2d expectedSum;
1578 expectedSum.setZero();
1579 mapping.mapConservativeAt(coords, inData, cache, outValues);
1580 expectedSum += inData.rowwise().sum();
1581
1582 // We can also change the shape of the user input
1583 coords.resize(dimensions, 3);
1584 inData.resize(dataComponents, 3);
1585 coords.col(0) = Eigen::RowVector2d(3.5, 0.5);
1586 coords.col(1) = Eigen::RowVector2d(4.5, 1.0);
1587 coords.col(2) = Eigen::RowVector2d(0.1, 0.0);
1588
1589 inData.col(0) = Eigen::RowVector2d(4.3, 8.6);
1590 inData.col(1) = Eigen::RowVector2d(17.3, 34.6);
1591 inData.col(2) = Eigen::RowVector2d(5.8, 11.6);
1592
1593 mapping.mapConservativeAt(coords, inData, cache, outValues);
1594 expectedSum += inData.rowwise().sum();
1595
1596 mapping.completeJustInTimeMapping(cache, outValues);
1597 // We don't reach full conservative'ness with the RBF config
1598 BOOST_TEST(outValues.rowwise().sum()(0) == expectedSum(0), boost::test_tools::tolerance(0.6));
1599 BOOST_TEST(outValues.rowwise().sum()(1) == expectedSum(1), boost::test_tools::tolerance(0.6));
1600 BOOST_TEST(outValues.row(0) == 0.5 * outValues.row(1), boost::test_tools::per_element());
1601 BOOST_TEST(outValues(0, 10) == 8.76997588, boost::test_tools::tolerance(1e-7));
1602
1603 // Now we check for re-computing the mapping after changing the mesh
1604 mapping.clear();
1605 outMesh->index().clear();
1606 outMesh->createVertex(Eigen::Vector2d(6.0, 0.0));
1607 outMesh->allocateDataValues();
1608
1609 BOOST_TEST(mapping.hasComputedMapping() == false);
1610 mapping.computeMapping();
1611 BOOST_TEST(mapping.hasComputedMapping() == true);
1612
1613 mapping.initializeMappingDataCache(cache);
1614
1615 Eigen::Map<Eigen::MatrixXd> outValues2(outData->values().data(), dataComponents, outMesh->vertices().size());
1616
1617 // before writing first, we have to reset the cache to contain zeros
1618 cache.resetData();
1619 outValues2.setZero();
1620 expectedSum.setZero();
1621
1622 coords.resize(dimensions, 1);
1623 inData.resize(dataComponents, 1);
1624 coords.col(0) = Eigen::RowVector2d(0.5, 0.5);
1625 inData.col(0) = Eigen::RowVector2d(4.3, 43);
1626 mapping.mapConservativeAt(coords, inData, cache, outValues2);
1627 expectedSum += inData.rowwise().sum();
1628 coords.col(0) = Eigen::RowVector2d(6.0, 0);
1629 inData.col(0) = Eigen::RowVector2d(5.1, 51);
1630 mapping.mapConservativeAt(coords, inData, cache, outValues2);
1631 expectedSum += inData.rowwise().sum();
1632
1633 mapping.completeJustInTimeMapping(cache, outValues2);
1634 BOOST_TEST(outValues2.rowwise().sum()(0) == expectedSum(0), boost::test_tools::tolerance(0.6));
1635 BOOST_TEST(outValues2.rowwise().sum()(1) == expectedSum(1), boost::test_tools::tolerance(0.6));
1636 BOOST_TEST(outValues2.col(12) == Eigen::RowVector2d(5.1, 51), boost::test_tools::per_element());
1637 BOOST_TEST(outValues2(0, 0) == 1.13162327, boost::test_tools::tolerance(1e-7));
1638}
1639
1641{
1642 const int dimensions = 3;
1643 const int dataDimension = dimensions;
1644 using Eigen::Vector3d;
1645
1646 // Create mesh to map from
1647 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
1648 mesh::PtrData inData = inMesh->createData("InData", dataDimension, 0_dataID);
1649 const DataID inDataID = inData->getID();
1650 inMesh->createVertex(Vector3d(0, 0, 0));
1651 inMesh->createVertex(Vector3d(3.5, 0.5, 0.5));
1652 inMesh->createVertex(Vector3d(2.5, 0.5, 1.0));
1653 inMesh->createVertex(Vector3d(1, 1, 1));
1654 inMesh->createVertex(Vector3d(5, 1, 0.5));
1655 inMesh->allocateDataValues();
1656 addGlobalIndex(inMesh);
1657
1658 // Create mesh to map from
1659 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1660 mesh::PtrData outData = outMesh->createData("OutData", dataDimension, 1_dataID);
1661 const DataID outDataID = outData->getID();
1662 outMesh->createVertex(Vector3d(0.0, 0.0, 0.0));
1663 outMesh->createVertex(Vector3d(1.0, 0.0, 0.0));
1664 outMesh->createVertex(Vector3d(1.0, 1.0, 0.0));
1665 outMesh->createVertex(Vector3d(0.0, 1.0, 0.0));
1666
1667 outMesh->createVertex(Vector3d(0.0, 0.0, 1.0));
1668 outMesh->createVertex(Vector3d(1.0, 0.0, 1.0));
1669 outMesh->createVertex(Vector3d(1.0, 1.0, 1.0));
1670 outMesh->createVertex(Vector3d(0.0, 1.0, 1.0));
1671
1672 outMesh->createVertex(Vector3d(2.0, 0.0, 0.0));
1673 outMesh->createVertex(Vector3d(3.0, 0.0, 0.0));
1674 outMesh->createVertex(Vector3d(3.0, 1.0, 0.0));
1675 outMesh->createVertex(Vector3d(2.0, 1.0, 0.0));
1676
1677 outMesh->createVertex(Vector3d(2.0, 0.0, 1.0));
1678 outMesh->createVertex(Vector3d(3.0, 0.0, 1.0));
1679 outMesh->createVertex(Vector3d(3.0, 1.0, 1.0));
1680 outMesh->createVertex(Vector3d(2.0, 1.0, 1.0));
1681
1682 outMesh->createVertex(Vector3d(4.0, 0.0, 0.0));
1683 outMesh->createVertex(Vector3d(5.0, 0.0, 0.0));
1684 outMesh->createVertex(Vector3d(5.0, 1.0, 0.0));
1685 outMesh->createVertex(Vector3d(4.0, 1.0, 0.0));
1686
1687 outMesh->createVertex(Vector3d(4.0, 0.0, 1.0));
1688 outMesh->createVertex(Vector3d(5.0, 0.0, 1.0));
1689 outMesh->createVertex(Vector3d(5.0, 1.0, 1.0));
1690 outMesh->createVertex(Vector3d(4.0, 1.0, 1.0));
1691
1692 outMesh->allocateDataValues();
1693 addGlobalIndex(outMesh);
1694
1695 // Setup mapping with mapping coordinates and geometry used
1696 mapping.setMeshes(inMesh, outMesh);
1697 BOOST_TEST(mapping.hasComputedMapping() == false);
1698
1699 // Check for the correct sum in the first component
1700 for (unsigned int i = 0; i < inData->values().size() / dataDimension; ++i) {
1701 inData->values()(i * dataDimension) = 7;
1702 inData->values()(i * dataDimension + 1) = 0;
1703 inData->values()(i * dataDimension + 2) = 0;
1704 }
1705
1706 mapping.computeMapping();
1707 mapping.map(inDataID, outDataID);
1708 BOOST_TEST(mapping.hasComputedMapping() == true);
1709 BOOST_TEST(outData->values().sum() == inData->values().sum());
1710 BOOST_TEST(outData->values().sum() == 35);
1711 for (unsigned int i = 0; i < outData->values().size() / dataDimension; ++i) {
1712 BOOST_TEST(outData->values()(i * dataDimension + 1) == 0);
1713 BOOST_TEST(outData->values()(i * dataDimension + 2) == 0);
1714 }
1715
1716 // Check for the correct sum in the second component
1717 for (unsigned int i = 0; i < inData->values().size() / dataDimension; ++i) {
1718 inData->values()(i * dataDimension) = 0;
1719 inData->values()(i * dataDimension + 1) = 27;
1720 inData->values()(i * dataDimension + 2) = 0;
1721 }
1722 mapping.clear();
1723 outData->values().setZero();
1724 mapping.computeMapping();
1725 mapping.map(inDataID, outDataID);
1726 BOOST_TEST(mapping.hasComputedMapping() == true);
1727 BOOST_TEST(outData->values().sum() == inData->values().sum());
1728 BOOST_TEST(outData->values().sum() == 135);
1729
1730 for (unsigned int i = 0; i < outData->values().size() / dataDimension; ++i) {
1731 BOOST_TEST(outData->values()(i * dataDimension) == 0);
1732 BOOST_TEST(outData->values()(i * dataDimension + 2) == 0);
1733 }
1734
1735 // Check for the correct sum in the third component
1736 for (unsigned int i = 0; i < inData->values().size() / dataDimension; ++i) {
1737 inData->values()(i * dataDimension) = 0;
1738 inData->values()(i * dataDimension + 1) = 0;
1739 inData->values()(i * dataDimension + 2) = 3;
1740 }
1741 mapping.clear();
1742 outData->values().setZero();
1743 mapping.computeMapping();
1744 mapping.map(inDataID, outDataID);
1745 BOOST_TEST(mapping.hasComputedMapping() == true);
1746 BOOST_TEST(outData->values().sum() == inData->values().sum());
1747 BOOST_TEST(outData->values().sum() == 15);
1748
1749 for (unsigned int i = 0; i < outData->values().size() / dataDimension; ++i) {
1750 BOOST_TEST(outData->values()(i * dataDimension) == 0);
1751 BOOST_TEST(outData->values()(i * dataDimension + 1) == 0);
1752 }
1753
1754 // Check for the correct relation between components
1755 for (unsigned int i = 0; i < inData->values().size() / dataDimension; ++i) {
1756 inData->values()(i * dataDimension) = std::pow(i * dataDimension, 3);
1757 inData->values()(i * dataDimension + 1) = 5 * std::pow(i * dataDimension, 3);
1758 inData->values()(i * dataDimension + 2) = 10 * std::pow(i * dataDimension, 3);
1759 }
1760 mapping.clear();
1761 outData->values().setZero();
1762 mapping.computeMapping();
1763 mapping.map(inDataID, outDataID);
1764 BOOST_TEST(mapping.hasComputedMapping() == true);
1765 BOOST_TEST(outData->values().sum() == inData->values().sum());
1766
1767 for (unsigned int i = 0; i < outData->values().size() / dataDimension; ++i) {
1768 // Some result values are close to zero and we cannot compare the relation between these values
1769 if (outData->values()(i * dataDimension) > 1e-10) {
1770 BOOST_TEST(outData->values()(i * dataDimension + 1) == 5 * outData->values()(i * dataDimension));
1771 BOOST_TEST(outData->values()(i * dataDimension + 2) == 10 * outData->values()(i * dataDimension));
1772 }
1773 }
1774 BOOST_TEST(outData->values()(55) == 4087.8100404079933);
1775
1776 // The remaining parts should already be covered by the other 3D/2D tests
1777}
1778
1779PRECICE_TEST_SETUP(1_rank)
1780BOOST_AUTO_TEST_CASE(PartitionOfUnityMappingTests)
1781{
1782 PRECICE_TEST();
1783 mapping::CompactPolynomialC0 function(3);
1784 mapping::PartitionOfUnityMapping<CompactPolynomialC0> consistentMap2D(Mapping::CONSISTENT, 2, function, Polynomial::SEPARATE, 5, 0.4, false);
1785 perform2DTestConsistentMapping(consistentMap2D);
1786 mapping::PartitionOfUnityMapping<CompactPolynomialC0> consistentMap2DVector(Mapping::CONSISTENT, 2, function, Polynomial::SEPARATE, 5, 0.4, false);
1787 perform2DTestConsistentMappingVector(consistentMap2DVector);
1788 mapping::PartitionOfUnityMapping<CompactPolynomialC6> consistentMap2DDeadAxis(Mapping::CONSISTENT, 2, mapping::CompactPolynomialC6(6), Polynomial::SEPARATE, 5, 0.4, false);
1789 performTestConsistentMapDeadAxis(consistentMap2DDeadAxis, 2);
1790 mapping::PartitionOfUnityMapping<CompactPolynomialC6> consistentMap3DDeadAxis(Mapping::CONSISTENT, 3, mapping::CompactPolynomialC6(8), Polynomial::SEPARATE, 5, 0.265, false);
1791 performTestConsistentMapDeadAxis(consistentMap3DDeadAxis, 3);
1792 mapping::PartitionOfUnityMapping<CompactPolynomialC0> conservativeMap2D(Mapping::CONSERVATIVE, 2, function, Polynomial::SEPARATE, 5, 0.4, false);
1793 perform2DTestConservativeMapping(conservativeMap2D);
1794 mapping::PartitionOfUnityMapping<CompactPolynomialC0> conservativeMap2DVector(Mapping::CONSERVATIVE, 2, function, Polynomial::SEPARATE, 5, 0.4, false);
1795 perform2DTestConservativeMappingVector(conservativeMap2DVector);
1796 mapping::PartitionOfUnityMapping<CompactPolynomialC0> consistentMap3D(Mapping::CONSISTENT, 3, function, Polynomial::SEPARATE, 5, 0.265, false);
1797 perform3DTestConsistentMapping(consistentMap3D);
1798 mapping::PartitionOfUnityMapping<CompactPolynomialC0> consistentMap3DVector(Mapping::CONSISTENT, 3, function, Polynomial::SEPARATE, 5, 0.265, false);
1799 perform3DTestConsistentMappingVector(consistentMap3DVector);
1800 mapping::PartitionOfUnityMapping<CompactPolynomialC0> conservativeMap3D(Mapping::CONSERVATIVE, 3, function, Polynomial::SEPARATE, 5, 0.265, false);
1801 perform3DTestConservativeMapping(conservativeMap3D);
1802 mapping::PartitionOfUnityMapping<CompactPolynomialC0> conservativeMap3DVector(Mapping::CONSERVATIVE, 3, function, Polynomial::SEPARATE, 5, 0.265, false);
1803 perform3DTestConservativeMappingVector(conservativeMap3DVector);
1804}
1805
1806PRECICE_TEST_SETUP(1_rank)
1807BOOST_AUTO_TEST_CASE(JustInTimeMapping)
1808{
1809 PRECICE_TEST();
1810 // using scalar data
1811 mapping::CompactPolynomialC0 c0function(3);
1812 mapping::PartitionOfUnityMapping<CompactPolynomialC0> polynomial3Dconsistent(Mapping::CONSISTENT, 3, c0function, Polynomial::SEPARATE, 5, 0.265, false);
1813 perform3DTestJustInTimeMappingWithPolynomial(polynomial3Dconsistent);
1814 // using vector data
1815 mapping::CompactPolynomialC4 c4function(3);
1816 mapping::PartitionOfUnityMapping<CompactPolynomialC4> noPolynomial2Dconsistent(Mapping::CONSISTENT, 2, c4function, Polynomial::OFF, 5, 0.265, false);
1817 perform2DTestJustInTimeMappingNoPolynomial(noPolynomial2Dconsistent);
1818
1819 // using scalar data
1820 mapping::CompactPolynomialC2 c2function(3);
1821 mapping::PartitionOfUnityMapping<CompactPolynomialC2> polynomial3Dconservative(Mapping::CONSERVATIVE, 3, c2function, Polynomial::SEPARATE, 5, 0.265, false);
1822 perform3DTestJustInTimeMappingConservative(polynomial3Dconservative);
1823 // using vector data
1824 mapping::CompactPolynomialC6 c6function(10);
1825 mapping::PartitionOfUnityMapping<CompactPolynomialC6> noPolynomial2Dconservative(Mapping::CONSERVATIVE, 2, c6function, Polynomial::OFF, 5, 0.265, false);
1826 perform2DTestJustInTimeMappingConservative(noPolynomial2Dconservative);
1827}
1828
1829// Test for small meshes, where the number of requested vertices per cluster is bigger than the global
1830PRECICE_TEST_SETUP(1_rank)
1831BOOST_AUTO_TEST_CASE(TestSingleClusterPartitionOfUnity)
1832{
1833 PRECICE_TEST();
1834 mapping::CompactPolynomialC0 function(3);
1835 mapping::PartitionOfUnityMapping<CompactPolynomialC0> mapping(Mapping::CONSISTENT, 3, function, Polynomial::SEPARATE, 50, 0.4, false);
1836
1837 int dimensions = 3;
1838 using Eigen::Vector3d;
1839
1840 // Create mesh to map from
1841 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", dimensions, testing::nextMeshID()));
1842 mesh::PtrData inData = inMesh->createData("InData", 1, 0_dataID);
1843 int inDataID = inData->getID();
1844 inMesh->createVertex(Vector3d(0.0, 0.0, 0.0));
1845 inMesh->createVertex(Vector3d(1.0, 0.0, 0.0));
1846 inMesh->createVertex(Vector3d(1.0, 1.0, 0.0));
1847 inMesh->createVertex(Vector3d(0.0, 1.0, 0.0));
1848
1849 inMesh->createVertex(Vector3d(0.0, 0.0, 1.0));
1850 inMesh->createVertex(Vector3d(1.0, 0.0, 1.0));
1851 inMesh->createVertex(Vector3d(1.0, 1.0, 1.0));
1852 inMesh->createVertex(Vector3d(0.0, 1.0, 1.0));
1853
1854 inMesh->createVertex(Vector3d(2.0, 0.0, 0.0));
1855 inMesh->createVertex(Vector3d(3.0, 0.0, 0.0));
1856 inMesh->createVertex(Vector3d(3.0, 1.0, 0.0));
1857 inMesh->createVertex(Vector3d(2.0, 1.0, 0.0));
1858
1859 inMesh->createVertex(Vector3d(2.0, 0.0, 1.0));
1860 inMesh->createVertex(Vector3d(3.0, 0.0, 1.0));
1861 inMesh->createVertex(Vector3d(3.0, 1.0, 1.0));
1862 inMesh->createVertex(Vector3d(2.0, 1.0, 1.0));
1863
1864 inMesh->createVertex(Vector3d(4.0, 0.0, 0.0));
1865 inMesh->createVertex(Vector3d(5.0, 0.0, 0.0));
1866 inMesh->createVertex(Vector3d(5.0, 1.0, 0.0));
1867 inMesh->createVertex(Vector3d(4.0, 1.0, 0.0));
1868
1869 inMesh->createVertex(Vector3d(4.0, 0.0, 1.0));
1870 inMesh->createVertex(Vector3d(5.0, 0.0, 1.0));
1871 inMesh->createVertex(Vector3d(5.0, 1.0, 1.0));
1872 inMesh->createVertex(Vector3d(4.0, 1.0, 1.0));
1873
1874 inMesh->allocateDataValues();
1875 addGlobalIndex(inMesh);
1876
1877 auto &values = inData->values();
1878 // Set the values in the parallel (z) plane 3*values
1879 values << 1.0, 2.0, 2.0, 1.0, 3.0, 6.0, 6.0, 3.0, 3.0, 4.0, 4.0, 3.0, 9.0, 12.0, 12.0, 9.0, 5.0, 6.0, 6.0, 5.0, 15.0, 18.0, 18.0, 15.0;
1880
1881 // Create mesh to map to
1882 mesh::PtrMesh outMesh(new mesh::Mesh("OutMesh", dimensions, testing::nextMeshID()));
1883 mesh::PtrData outData = outMesh->createData("OutData", 1, 1_dataID);
1884 int outDataID = outData->getID();
1885 mesh::Vertex &vertex = outMesh->createVertex(Vector3d(0, 0, 0));
1886 outMesh->createVertex(Vector3d(3.5, 0.5, 0.5));
1887 outMesh->createVertex(Vector3d(2.5, 0.5, 1.0));
1888 outMesh->createVertex(Vector3d(0, 0, 0.5));
1889 outMesh->createVertex(Vector3d(5, 1, 0.5));
1890 outMesh->allocateDataValues();
1891 addGlobalIndex(outMesh);
1892
1893 // Setup mapping with mapping coordinates and geometry used
1894 mapping.setMeshes(inMesh, outMesh);
1895 BOOST_TEST(mapping.hasComputedMapping() == false);
1896
1897 vertex.setCoords(Vector3d(0.0, 0.0, 0.0));
1898 mapping.computeMapping();
1899 mapping.map(inDataID, outDataID);
1900 double value = outData->values()(0);
1901 double value1 = outData->values()(1);
1902 double value2 = outData->values()(2);
1903 BOOST_TEST(mapping.hasComputedMapping() == true);
1904 BOOST_TEST(value == 1.0);
1905 BOOST_TEST(value1 == 9.0);
1906 BOOST_TEST(value2 == 10.5);
1907
1908 vertex.setCoords(Vector3d(0.0, 0.5, 0.5));
1909 mapping.clear();
1910 outData->values().setZero();
1911 mapping.computeMapping();
1912 mapping.map(inDataID, outDataID);
1913 value = outData->values()(0);
1914 BOOST_TEST(mapping.hasComputedMapping() == true);
1915 BOOST_TEST(value == 2.0);
1916
1917 vertex.setCoords(Vector3d(1.0, 0.0, 0.0));
1918 mapping.clear();
1919 outData->values().setZero();
1920 mapping.computeMapping();
1921 mapping.map(inDataID, outDataID);
1922 value = outData->values()(0);
1923 BOOST_TEST(mapping.hasComputedMapping() == true);
1924 BOOST_TEST(value == 2.0);
1925
1926 vertex.setCoords(Vector3d(1.0, 0.5, 0.5));
1927 mapping.clear();
1928 outData->values().setZero();
1929 mapping.computeMapping();
1930 mapping.map(inDataID, outDataID);
1931 value = outData->values()(0);
1932 BOOST_TEST(mapping.hasComputedMapping() == true);
1933 BOOST_TEST(value == 4.0);
1934
1935 vertex.setCoords(Vector3d(0.5, 0.5, 1.0));
1936 mapping.clear();
1937 outData->values().setZero();
1938 mapping.computeMapping();
1939 mapping.map(inDataID, outDataID);
1940 value = outData->values()(0);
1941 BOOST_TEST(mapping.hasComputedMapping() == true);
1942 BOOST_TEST(value > 4.6);
1943
1944 vertex.setCoords(Vector3d(0.5, 1.0, 0.0));
1945 mapping.clear();
1946 outData->values().setZero();
1947 mapping.computeMapping();
1948 mapping.map(inDataID, outDataID);
1949 value = outData->values()(0);
1950 BOOST_TEST(mapping.hasComputedMapping() == true);
1951 BOOST_TEST(value < 1.4);
1952}
1953
1954BOOST_AUTO_TEST_SUITE_END() // Serial
1955
1956BOOST_AUTO_TEST_SUITE(Parallel)
1957
1958void addGlobalIndex(mesh::PtrMesh &mesh, int offset = 0)
1959{
1960 for (mesh::Vertex &v : mesh->vertices()) {
1961 v.setGlobalIndex(v.getID() + offset);
1962 }
1963}
1964
1972
1973/*
1974MeshSpecification format:
1975{ {rank, owner rank, {x, y, z}, {v}}, ... }
1976
1977also see struct VertexSpecification.
1978
1979- -1 on rank means all ranks
1980- -1 on owner rank means no rank
1981- x, y, z is position of vertex, z is optional, 2D mesh will be created then
1982- v is the value of the respective vertex. Only 1D supported at this time.
1983
1984ReferenceSpecification format:
1985{ {rank, {v}, ... }
1986- -1 on rank means all ranks
1987- v is the expected value of n-th vertex on that particular rank
1988*/
1990
1993
1995 MeshSpecification const &vertices,
1996 mesh::PtrMesh &mesh,
1997 mesh::PtrData &data,
1998 int globalIndexOffset = 0,
1999 bool meshIsSmaller = false)
2000{
2001 Eigen::VectorXd d;
2002
2003 int i = 0;
2004 for (auto &vertex : vertices) {
2005 if (vertex.rank == context.rank or vertex.rank == -1) {
2006 if (vertex.position.size() == 3) // 3-dimensional
2007 mesh->createVertex(Eigen::Vector3d(vertex.position.data()));
2008 else if (vertex.position.size() == 2) // 2-dimensional
2009 mesh->createVertex(Eigen::Vector2d(vertex.position.data()));
2010
2011 int valueDimension = vertex.value.size();
2012
2013 if (vertex.owner == context.rank)
2014 mesh->vertices().back().setOwner(true);
2015 else
2016 mesh->vertices().back().setOwner(false);
2017
2018 d.conservativeResize(i * valueDimension + valueDimension);
2019 // Get data in every dimension
2020 for (int dim = 0; dim < valueDimension; ++dim) {
2021 d(i * valueDimension + dim) = vertex.value.at(dim);
2022 }
2023 i++;
2024 }
2025 }
2026 addGlobalIndex(mesh, globalIndexOffset);
2027 mesh->allocateDataValues();
2028 // All tests use eight vertices
2029 // if (meshIsSmaller) {
2030 // mesh->setGlobalNumberOfVertices(7);
2031 // } else {
2032 // mesh->setGlobalNumberOfVertices(8);
2033 // }
2034 data->values() = d;
2035}
2036
2037void testDistributed(const TestContext &context,
2038 Mapping &mapping,
2039 MeshSpecification inMeshSpec,
2040 MeshSpecification outMeshSpec,
2041 ReferenceSpecification referenceSpec,
2042 int inGlobalIndexOffset = 0,
2043 bool meshIsSmaller = false)
2044{
2045 int meshDimension = inMeshSpec.at(0).position.size();
2046 int valueDimension = inMeshSpec.at(0).value.size();
2047
2048 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", meshDimension, testing::nextMeshID()));
2049 mesh::PtrData inData = inMesh->createData("InData", valueDimension, 0_dataID);
2050 int inDataID = inData->getID();
2051
2052 getDistributedMesh(context, inMeshSpec, inMesh, inData, inGlobalIndexOffset);
2053
2054 mesh::PtrMesh outMesh(new mesh::Mesh("outMesh", meshDimension, testing::nextMeshID()));
2055 mesh::PtrData outData = outMesh->createData("OutData", valueDimension, 1_dataID);
2056 int outDataID = outData->getID();
2057
2058 getDistributedMesh(context, outMeshSpec, outMesh, outData, 0, meshIsSmaller);
2059
2060 mapping.setMeshes(inMesh, outMesh);
2061 BOOST_TEST(mapping.hasComputedMapping() == false);
2062
2063 mapping.computeMapping();
2064 BOOST_TEST(mapping.hasComputedMapping() == true);
2065 mapping.map(inDataID, outDataID);
2066
2067 int index = 0;
2068 for (auto &referenceVertex : referenceSpec) {
2069 if (referenceVertex.first == context.rank or referenceVertex.first == -1) {
2070 for (int dim = 0; dim < valueDimension; ++dim) {
2071 BOOST_TEST_INFO("Index of vertex: " << index << " - Dimension: " << dim);
2072 BOOST_TEST(outData->values()(index * valueDimension + dim) == referenceVertex.second.at(dim));
2073 }
2074 ++index;
2075 }
2076 }
2077 BOOST_TEST(outData->values().size() == index * valueDimension);
2078}
2079
2080PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2081BOOST_AUTO_TEST_CASE(DistributedConsistent2D)
2082{
2083 PRECICE_TEST();
2084 std::vector<int> globalIndexOffsets = {0, 0, 0, 0};
2085
2086 MeshSpecification in{// Consistent mapping: The inMesh is communicated
2087 {-1, 0, {0, 0}, {1}},
2088 {-1, 0, {0, 1}, {2}},
2089 {-1, 1, {1, 0}, {3}},
2090 {-1, 1, {1, 1}, {4}},
2091 {-1, 2, {2, 0}, {5}},
2092 {-1, 2, {2, 1}, {6}},
2093 {-1, 3, {3, 0}, {7}},
2094 {-1, 3, {3, 1}, {8}}};
2095 MeshSpecification out{// The outMesh is local, distributed among all ranks
2096 {0, -1, {0, 0}, {0}},
2097 {0, -1, {0, 1}, {0}},
2098 {1, -1, {1, 0}, {0}},
2099 {1, -1, {1, 1}, {0}},
2100 {2, -1, {2, 0}, {0}},
2101 {2, -1, {2, 1}, {0}},
2102 {3, -1, {3, 0}, {0}},
2103 {3, -1, {3, 1}, {0}}};
2104
2105 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2106 {0, {1}},
2107 {0, {2}},
2108 {1, {3}},
2109 {1, {4}},
2110 {2, {5}},
2111 {2, {6}},
2112 {3, {7}},
2113 {3, {8}}};
2114
2115 mapping::PartitionOfUnityMapping<CompactPolynomialC6> consistentMap2D(Mapping::CONSISTENT, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2116 testDistributed(context, consistentMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2117}
2118
2119// Same as above, but including empty ranks not participating
2120PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2121BOOST_AUTO_TEST_CASE(DistributedConsistent2DEmptyOut)
2122{
2123 PRECICE_TEST();
2124 std::vector<int> globalIndexOffsets = {0, 0, 0, 0};
2125
2126 MeshSpecification in{// Consistent mapping: The inMesh is communicated
2127 {-1, 0, {0, 0}, {1}},
2128 {-1, 0, {0, 1}, {2}},
2129 {-1, 1, {1, 0}, {3}},
2130 {-1, 1, {1, 1}, {4}},
2131 {-1, 2, {2, 0}, {5}},
2132 {-1, 2, {2, 1}, {6}},
2133 {-1, 3, {3, 0}, {7}},
2134 {-1, 3, {3, 1}, {8}}};
2135 MeshSpecification out{// The outMesh is local, distributed among all ranks
2136 {0, 0, {0, 0}, {0}},
2137 {0, 0, {0, 1}, {0}},
2138 {1, 1, {1, 0}, {0}},
2139 {1, 1, {1, 1}, {0}},
2140 {2, 2, {2, 0}, {0}},
2141 {2, 2, {2, 1}, {0}},
2142 {2, 2, {3, 0}, {0}},
2143 {2, 2, {3, 1}, {0}}};
2144
2145 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2146 {0, {1}},
2147 {0, {2}},
2148 {1, {3}},
2149 {1, {4}},
2150 {2, {5}},
2151 {2, {6}},
2152 {2, {7}},
2153 {2, {8}}};
2154
2155 mapping::PartitionOfUnityMapping<CompactPolynomialC6> consistentMap2D(Mapping::CONSISTENT, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2156 testDistributed(context, consistentMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2157}
2158
2159// Same as above, but including empty ranks not participating
2160PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2161BOOST_AUTO_TEST_CASE(DistributedConsistent2DEmptyRank)
2162{
2163 PRECICE_TEST();
2164 std::vector<int> globalIndexOffsets = {0, 0, 0, 0};
2165
2166 MeshSpecification in{// Consistent mapping: The inMesh is communicated
2167 {-1, 0, {0, 0}, {1}},
2168 {-1, 0, {0, 1}, {2}},
2169 {-1, 1, {1, 0}, {3}},
2170 {-1, 1, {1, 1}, {4}},
2171 {-1, 2, {2, 0}, {5}},
2172 {-1, 2, {2, 1}, {6}}};
2173
2174 MeshSpecification out{// The outMesh is local, distributed among all ranks
2175 {0, 0, {0, 0}, {0}},
2176 {0, 0, {0, 1}, {0}},
2177 {1, 1, {1, 0}, {0}},
2178 {1, 1, {1, 1}, {0}},
2179 {2, 2, {2, 0}, {0}},
2180 {2, 2, {2, 1}, {0}}};
2181
2182 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2183 {0, {1}},
2184 {0, {2}},
2185 {1, {3}},
2186 {1, {4}},
2187 {2, {5}},
2188 {2, {6}}};
2189
2190 mapping::PartitionOfUnityMapping<CompactPolynomialC6> consistentMap2D(Mapping::CONSISTENT, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2191 testDistributed(context, consistentMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2192}
2193
2194PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2195BOOST_AUTO_TEST_CASE(DistributedConservative2D)
2196{
2197 PRECICE_TEST();
2198 std::vector<int> globalIndexOffsets = {0, 0, 0, 0};
2199
2200 MeshSpecification in{// Conservative mapping: The inMesh is local
2201 {0, -1, {0, 0}, {1}},
2202 {0, -1, {0, 1}, {2}},
2203 {1, -1, {1, 0}, {3}},
2204 {1, -1, {1, 1}, {4}},
2205 {2, -1, {2, 0}, {5}},
2206 {2, -1, {2, 1}, {6}},
2207 {3, -1, {3, 0}, {7}},
2208 {3, -1, {3, 1}, {8}}};
2209 MeshSpecification out{// The outMesh is remote, distributed among all ranks
2210 {0, 0, {0, 0}, {0}},
2211 {0, 0, {0, 1}, {0}},
2212 {1, 1, {1, 0}, {0}},
2213 {1, 1, {1, 1}, {0}},
2214 {2, 2, {2, 0}, {0}},
2215 {2, 2, {2, 1}, {0}},
2216 {3, 3, {3, 0}, {0}},
2217 {3, 3, {3, 1}, {0}}};
2218
2219 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2220 {0, {1}},
2221 {0, {2}},
2222 {1, {3}},
2223 {1, {4}},
2224 {2, {5}},
2225 {2, {6}},
2226 {3, {7}},
2227 {3, {8}}};
2228
2229 mapping::PartitionOfUnityMapping<CompactPolynomialC6> conservativeMap2D(Mapping::CONSERVATIVE, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2230 testDistributed(context, conservativeMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2231}
2232
2233// Same as above, but checking with empty ranks
2234PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2235BOOST_AUTO_TEST_CASE(DistributedConservative2DEmptyRank)
2236{
2237 PRECICE_TEST();
2238 std::vector<int> globalIndexOffsets = {0, 2, 4, 6};
2239
2240 MeshSpecification in{// Conservative mapping: The inMesh is local
2241 {0, -1, {0, 0}, {1}},
2242 {0, -1, {0, 1}, {2}},
2243 {1, -1, {1, 0}, {3}},
2244 {1, -1, {1, 1}, {4}},
2245 {2, -1, {2, 0}, {5}},
2246 {2, -1, {2, 1}, {6}},
2247 {2, -1, {3, 0}, {7}},
2248 {2, -1, {3, 1}, {8}}};
2249 MeshSpecification out{// The outMesh is remote, distributed among all ranks
2250 {-1, 0, {0, 0}, {0}},
2251 {-1, 0, {0, 1}, {0}},
2252 {-1, 1, {1, 0}, {0}},
2253 {-1, 1, {1, 1}, {0}},
2254 {-1, 2, {2, 0}, {0}},
2255 {-1, 2, {2, 1}, {0}},
2256 {-1, 3, {3, 0}, {0}},
2257 {-1, 3, {3, 1}, {0}}};
2258
2259 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2260 {0, {1}},
2261 {0, {2}},
2262 {0, {0}},
2263 {0, {0}},
2264 {0, {0}},
2265 {0, {0}},
2266 {0, {0}},
2267 {0, {0}},
2268 {1, {0}},
2269 {1, {0}},
2270 {1, {3}},
2271 {1, {4}},
2272 {1, {0}},
2273 {1, {0}},
2274 {1, {0}},
2275 {1, {0}},
2276 {2, {0}},
2277 {2, {0}},
2278 {2, {0}},
2279 {2, {0}},
2280 {2, {5}},
2281 {2, {6}},
2282 {2, {7}},
2283 {2, {8}},
2284 {3, {0}},
2285 {3, {0}},
2286 {3, {0}},
2287 {3, {0}},
2288 {3, {0}},
2289 {3, {0}},
2290 {3, {0}},
2291 {3, {0}}};
2292
2293 mapping::PartitionOfUnityMapping<CompactPolynomialC6> conservativeMap2D(Mapping::CONSERVATIVE, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2294 testDistributed(context, conservativeMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2295}
2296
2297// Same as above, but checking the primary rank for all output vertices
2298PRECICE_TEST_SETUP(""_on(2_ranks).setupIntraComm())
2299BOOST_AUTO_TEST_CASE(DistributedConservative2DTwoRanks)
2300{
2301 PRECICE_TEST();
2302 std::vector<int> globalIndexOffsets = {0, 2};
2303
2304 MeshSpecification in{// Conservative mapping: The inMesh is local
2305 {0, -1, {0, 0}, {1}},
2306 {0, -1, {0, 1}, {2}},
2307 {0, -1, {1, 0}, {3}},
2308 {0, -1, {1, 1}, {4}},
2309 {1, -1, {2, 0}, {5}},
2310 {1, -1, {2, 1}, {6}},
2311 {1, -1, {3, 0}, {7}},
2312 {1, -1, {3, 1}, {8}}};
2313 MeshSpecification out{// The outMesh is remote, distributed among all ranks
2314 {-1, 0, {0, 0}, {0}},
2315 {-1, 0, {0, 1}, {0}},
2316 {-1, 0, {1, 0}, {0}},
2317 {-1, 0, {1, 1}, {0}},
2318 {-1, 0, {2, 0}, {0}},
2319 {-1, 0, {2, 1}, {0}},
2320 {-1, 0, {3, 0}, {0}},
2321 {-1, 0, {3, 1}, {0}}};
2322
2323 ReferenceSpecification ref{// Tests for {0, 1} on the first rank, {1, 2} on the second, ...
2324 {0, {1}},
2325 {0, {2}},
2326 {0, {3}},
2327 {0, {4}},
2328 {0, {0}},
2329 {0, {0}},
2330 {0, {0}},
2331 {0, {0}},
2332 {1, {0}},
2333 {1, {0}},
2334 {1, {0}},
2335 {1, {0}},
2336 {1, {5}},
2337 {1, {6}},
2338 {1, {7}},
2339 {1, {8}}};
2340
2341 mapping::PartitionOfUnityMapping<CompactPolynomialC6> conservativeMap2D(Mapping::CONSERVATIVE, 2, CompactPolynomialC6(3.), Polynomial::SEPARATE, 5, 0.3, false);
2342 testDistributed(context, conservativeMap2D, in, out, ref, globalIndexOffsets.at(context.rank));
2343}
2344
2345void testTagging(const TestContext &context,
2346 MeshSpecification inMeshSpec,
2347 MeshSpecification outMeshSpec,
2348 MeshSpecification shouldTagFirstRound,
2349 MeshSpecification shouldTagSecondRound,
2350 bool consistent)
2351{
2352 int meshDimension = inMeshSpec.at(0).position.size();
2353 int valueDimension = inMeshSpec.at(0).value.size();
2354
2355 mesh::PtrMesh inMesh(new mesh::Mesh("InMesh", meshDimension, testing::nextMeshID()));
2356 mesh::PtrData inData = inMesh->createData("InData", valueDimension, 0_dataID);
2357 getDistributedMesh(context, inMeshSpec, inMesh, inData);
2358
2359 mesh::PtrMesh outMesh(new mesh::Mesh("outMesh", meshDimension, testing::nextMeshID()));
2360 mesh::PtrData outData = outMesh->createData("OutData", valueDimension, 1_dataID);
2361 getDistributedMesh(context, outMeshSpec, outMesh, outData);
2362
2364 mapping::PartitionOfUnityMapping<CompactPolynomialC4> mapping(constr, 2, CompactPolynomialC4(2), Polynomial::SEPARATE, 2, 0.3, false);
2365 inMesh->computeBoundingBox();
2366 outMesh->computeBoundingBox();
2367
2368 mapping.setMeshes(inMesh, outMesh);
2369 mapping.tagMeshFirstRound();
2370
2371 for (const auto &v : inMesh->vertices()) {
2372 auto pos = std::find_if(shouldTagFirstRound.begin(), shouldTagFirstRound.end(),
2373 [meshDimension, &v](const VertexSpecification &spec) {
2374 return std::equal(spec.position.data(), spec.position.data() + meshDimension, v.getCoords().data());
2375 });
2376 bool found = pos != shouldTagFirstRound.end();
2377 BOOST_TEST(found >= v.isTagged(),
2378 "FirstRound: Vertex " << v << " is tagged, but should not be.");
2379 BOOST_TEST(found <= v.isTagged(),
2380 "FirstRound: Vertex " << v << " is not tagged, but should be.");
2381 }
2382
2383 mapping.tagMeshSecondRound();
2384
2385 for (const auto &v : inMesh->vertices()) {
2386 auto posFirst = std::find_if(shouldTagFirstRound.begin(), shouldTagFirstRound.end(),
2387 [meshDimension, &v](const VertexSpecification &spec) {
2388 return std::equal(spec.position.data(), spec.position.data() + meshDimension, v.getCoords().data());
2389 });
2390 bool foundFirst = posFirst != shouldTagFirstRound.end();
2391 auto posSecond = std::find_if(shouldTagSecondRound.begin(), shouldTagSecondRound.end(),
2392 [meshDimension, &v](const VertexSpecification &spec) {
2393 return std::equal(spec.position.data(), spec.position.data() + meshDimension, v.getCoords().data());
2394 });
2395 bool foundSecond = posSecond != shouldTagSecondRound.end();
2396 BOOST_TEST(foundFirst <= v.isTagged(), "SecondRound: Vertex " << v
2397 << " is not tagged, but should be from the first round.");
2398 BOOST_TEST(foundSecond <= v.isTagged(), "SecondRound: Vertex " << v
2399 << " is not tagged, but should be.");
2400 BOOST_TEST((foundSecond or foundFirst) >= v.isTagged(), "SecondRound: Vertex " << v
2401 << " is tagged, but should not be.");
2402 }
2403}
2404
2405PRECICE_TEST_SETUP(""_on(4_ranks).setupIntraComm())
2406BOOST_AUTO_TEST_CASE(testTagFirstRound)
2407{
2408 PRECICE_TEST();
2409
2410 MeshSpecification outMeshSpec = {
2411 {0, -1, {0, 0}, {0}}};
2412 MeshSpecification inMeshSpec = {
2413 {0, -1, {-1, 0}, {1}}, // inside
2414 {0, -1, {-3, 0}, {1}}, // outside
2415 {0, 0, {1, 0}, {1}}, // inside, owner
2416 {0, -1, {3, 0}, {1}}, // outside
2417 {0, -1, {0, -1}, {1}}, // inside
2418 {0, -1, {0, -3}, {1}}, // outside
2419 {0, -1, {0, 1}, {1}}, // inside
2420 {0, -1, {0, 3}, {1}} // outside
2421 };
2422 MeshSpecification shouldTagFirstRound = {
2423 {0, -1, {-1, 0}, {1}},
2424 {0, -1, {1, 0}, {1}},
2425 {0, -1, {0, -1}, {1}},
2426 {0, -1, {0, 1}, {1}}};
2427 // No tagging happening in round two
2428 MeshSpecification shouldTagSecondRound;
2429
2430 testTagging(context, inMeshSpec, outMeshSpec, shouldTagFirstRound, shouldTagSecondRound, true);
2431 // For conservative just swap meshes.
2432 testTagging(context, outMeshSpec, inMeshSpec, shouldTagFirstRound, shouldTagSecondRound, false);
2433}
2434
2435BOOST_AUTO_TEST_SUITE_END() // Parallel
2436
std::ostream & out
BOOST_AUTO_TEST_SUITE(PreProcess)
BOOST_AUTO_TEST_SUITE_END()
void testTagging(const TestContext &context, MeshSpecification inMeshSpec, MeshSpecification outMeshSpec, MeshSpecification shouldTagFirstRound, MeshSpecification shouldTagSecondRound, bool consistent)
void addGlobalIndex(mesh::PtrMesh &mesh, int offset=0)
void perform2DTestConservativeMappingVector(Mapping &mapping)
void perform3DTestConsistentMappingVector(Mapping &mapping)
void perform2DTestConsistentMappingVector(Mapping &mapping)
void perform2DTestConsistentMapping(Mapping &mapping)
void perform2DTestJustInTimeMappingConservative(Mapping &mapping)
BOOST_AUTO_TEST_CASE(PartitionOfUnityMappingTests)
void perform3DTestConsistentMapping(Mapping &mapping)
void testDistributed(const TestContext &context, Mapping &mapping, MeshSpecification inMeshSpec, MeshSpecification outMeshSpec, ReferenceSpecification referenceSpec, int inGlobalIndexOffset=0, bool meshIsSmaller=false)
double sumComponentWise(const Eigen::VectorXd &vec, int component, int dataDimension)
void perform3DTestConservativeMapping(Mapping &mapping)
void perform3DTestJustInTimeMappingConservative(Mapping &mapping)
void perform2DTestConservativeMapping(Mapping &mapping)
void perform3DTestConservativeMappingVector(Mapping &mapping)
void perform2DTestJustInTimeMappingNoPolynomial(Mapping &mapping)
void perform3DTestJustInTimeMappingWithPolynomial(Mapping &mapping)
void getDistributedMesh(const TestContext &context, MeshSpecification const &vertices, mesh::PtrMesh &mesh, mesh::PtrData &data, int globalIndexOffset=0, bool meshIsSmaller=false)
void performTestConsistentMapDeadAxis(Mapping &mapping, int dim)
unsigned int index
#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
#define PRECICE_ASSERT(...)
Definition assertion.hpp:85
T at(T... args)
T back(T... args)
Wendland radial basis function with compact support.
Wendland radial basis function with compact support.
Wendland radial basis function with compact support.
Wendland radial basis function with compact support.
Abstract base class for mapping of data from one mesh to another.
Definition Mapping.hpp:16
virtual void initializeMappingDataCache(impl::MappingDataCache &cache)
Allocates memory and sets up the data structures inside the MappingDataCache.
Definition Mapping.cpp:281
Constraint
Specifies additional constraints for a mapping.
Definition Mapping.hpp:30
virtual void completeJustInTimeMapping(impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > result)
Completes a just-in-time mapping for conservative constraints.
Definition Mapping.cpp:301
virtual void mapConsistentAt(const Eigen::Ref< const Eigen::MatrixXd > &coordinates, const impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > values)
Just-in-time mapping variant of mapConsistent.
Definition Mapping.cpp:312
virtual void clear()=0
Removes a computed mapping.
virtual void updateMappingDataCache(impl::MappingDataCache &cache, const Eigen::Ref< const Eigen::VectorXd > &in)
Allows updating a so-called MappingDataCache for more efficient just-in-time mappings.
Definition Mapping.cpp:270
void setMeshes(const mesh::PtrMesh &input, const mesh::PtrMesh &output)
Sets input and output meshes carrying data to be mapped.
Definition Mapping.cpp:28
virtual void mapConservativeAt(const Eigen::Ref< const Eigen::MatrixXd > &coordinates, const Eigen::Ref< const Eigen::MatrixXd > &source, impl::MappingDataCache &cache, Eigen::Ref< Eigen::MatrixXd > target)
Just-in-time mapping variant of mapConservative.
Definition Mapping.cpp:292
virtual void computeMapping()=0
Computes the mapping coefficients from the in- and output mesh.
bool hasComputedMapping() const
Returns true, if the mapping has been computed.
Definition Mapping.cpp:253
void map(int inputDataID, int outputDataID)
Definition Mapping.cpp:127
void tagMeshSecondRound() final override
nothing to do here
void tagMeshFirstRound() final override
tag the vertices required for the mapping
void clear() final override
Clears a computed mapping by deleting the content of the _clusters vector.
DataID getID() const
Returns the ID of the data set (supposed to be unique).
Definition Data.cpp:110
Eigen::VectorXd & values()
Returns a reference to the data values.
Definition Data.cpp:28
static mesh::PtrMesh getJustInTimeMappingMesh(int dimension)
Container and creator for meshes.
Definition Mesh.hpp:38
void setGlobalNumberOfVertices(int num)
Definition Mesh.hpp:270
VertexContainer & vertices()
Returns modifieable container holding all vertices.
Definition Mesh.cpp:55
std::size_t nVertices() const
Returns the number of vertices.
Definition Mesh.cpp:65
const query::Index & index() const
Call preprocess() before index() to ensure correct projection handling.
Definition Mesh.hpp:321
PtrData & createData(const std::string &name, int dimension, DataID id, int waveformDegree=time::Time::DEFAULT_WAVEFORM_DEGREE)
Create only data for vertex.
Definition Mesh.cpp:153
void computeBoundingBox()
Computes the boundingBox for the vertices.
Definition Mesh.cpp:244
Vertex & createVertex(const Eigen::Ref< const Eigen::VectorXd > &coords)
Creates and initializes a Vertex object.
Definition Mesh.cpp:105
void allocateDataValues()
Allocates memory for the vertex data values and corresponding gradient values.
Definition Mesh.cpp:235
Vertex of a mesh.
Definition Vertex.hpp:16
void setCoords(const VECTOR_T &coordinates)
Sets the coordinates of the vertex.
Definition Vertex.hpp:101
void setOwner(bool owner)
Definition Vertex.cpp:27
void clear()
Clear the index.
Definition Index.cpp:391
Rank rank
the rank of the current participant
T find_if(T... args)
contains data mapping from points to meshes.
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.
provides Mesh, Data and primitives.
contains the testing framework.
Definition helper.hpp:9
Main namespace of the precice library.
int DataID
Definition Types.hpp:25
T pow(T... args)
T ref(T... args)
T size(T... args)
Holds rank, owner, position and value of a single vertex.
bool hasDataAtTimeStamp(double time) const
Check, if the current data vector (in inData or the std::vectors) hold data of time time.
void setTimeStamp(double time)
Set the timestamp of the MappingDataCache to the specified time.
void resetData()
Reset all data containers to zero.
void resetTimeStamp()
Reset the time stamp associated with the data.