MAIA bb96820c
Multiphysics at AIA
Loading...
Searching...
No Matches
fvstructuredsolverwindowinfo.cpp
Go to the documentation of this file.
1// Copyright (C) 2024 The m-AIA AUTHORS
2//
3// This file is part of m-AIA (https://git.rwth-aachen.de/aia/m-AIA/m-AIA)
4//
5// SPDX-License-Identifier: LGPL-3.0-only
6
8#include "COMM/mpioverride.h"
10#include "UTIL/kdtree.h"
11#include "UTIL/pointbox.h"
13#include "globals.h"
14#include "vector"
15
16using namespace std;
17
18
19template <MInt nDim>
21 MPI_Comm structuredCommunicator_,
22 const MInt noDomains_,
23 const MInt domainId_,
24 const MInt solverId_)
25 : m_grid(grid_),
26 m_noBlocks(grid_->m_noBlocks),
27 m_blockId(grid_->m_blockId),
28 m_noDomains(noDomains_),
29 m_domainId(domainId_),
30 m_solverId(solverId_),
31 m_noGhostLayers(grid_->m_noGhostLayers),
32 m_StructuredComm(structuredCommunicator_) {}
33
34template <MInt nDim>
36 // do nothing
37}
38
39template <>
41 constexpr MInt nDim = 2;
42 MInt countConnection = 0; // numConnections;
43 unique_ptr<StructuredWindowMap<nDim>> newWindow;
44 MBool found, notexisted, labell;
45 connectionNode temp1(nDim);
46 MInt numWindows[nDim] = {0, 0};
47
48 // set<connectionNode>::iterator it;
49
50 while(connectionset.size() != 0) {
51 auto element = connectionset.begin();
52 MInt order[2] = {-1, -1};
53 MInt step1[2] = {1, 1};
54 MInt step2[2] = {1, 1};
55 MInt pos1[3], pos2[3], b1, b2;
56
57 pos1[0] = element->pos1[0];
58 pos1[1] = element->pos1[1];
59 pos2[0] = element->pos2[0];
60 pos2[1] = element->pos2[1];
61 b1 = element->blockId1;
62 b2 = element->blockId2;
63
64 newWindow = make_unique<StructuredWindowMap<nDim>>();
65 mapCreate(b1, pos1, pos1, step1, b2, pos2, pos2, step2, order, element->BC, newWindow);
66 newWindow->Nstar = -1;
67
68 for(MInt i = 0; i < 2; ++i) {
69 found = false;
70 pos1[0] = newWindow->start1[0];
71 pos1[1] = newWindow->start1[1];
72
73 if(newWindow->order[i] == -1) {
74 // D1+
75
76 pos1[i] = newWindow->start1[i] + 1;
77 for(MInt j = 0; j < 2; ++j) {
78 // D2
79 pos2[0] = newWindow->start2[0];
80 pos2[1] = newWindow->start2[1];
81
82 notexisted = true;
83 for(MInt k = 0; k < 2; ++k) {
84 if(newWindow->order[k] == j) notexisted = false;
85 }
86
87 if(notexisted) {
88 pos2[j] = newWindow->start2[j] + 1;
89
90 temp1.BC = newWindow->BC;
91 temp1.blockId1 = newWindow->Id1;
92 temp1.blockId2 = newWindow->Id2;
93 temp1.pos1[0] = pos1[0];
94 temp1.pos1[1] = pos1[1];
95 temp1.pos2[0] = pos2[0];
96 temp1.pos2[1] = pos2[1];
97 temp1.Nstar = -1;
98 found = findConnection(temp1);
99
100 if(found) {
101 newWindow->step1[i] = 1;
102 newWindow->step2[j] = 1;
103 newWindow->order[i] = j;
104 break;
105 }
106
107 // D2-
108 pos2[j] = newWindow->start2[j] - 1;
109 temp1.BC = newWindow->BC;
110 temp1.blockId1 = newWindow->Id1;
111 temp1.blockId2 = newWindow->Id2;
112 temp1.pos1[0] = pos1[0];
113 temp1.pos1[1] = pos1[1];
114 temp1.pos2[0] = pos2[0];
115 temp1.pos2[1] = pos2[1];
116 temp1.Nstar = -1;
117 found = findConnection(temp1);
118 if(found) {
119 newWindow->step1[i] = 1;
120 newWindow->step2[j] = -1;
121 newWindow->order[i] = j;
122 break;
123 }
124 }
125 }
126
127 if(found) {
128 continue;
129 }
130
131 // D1-
132 pos1[i] = newWindow->start1[i] - 1;
133 for(MInt j = 0; j < 2; ++j) {
134 // D2+
135 pos2[0] = newWindow->start2[0];
136 pos2[1] = newWindow->start2[1];
137 notexisted = true;
138 for(MInt k = 0; k < 2; ++k) {
139 if(newWindow->order[k] == j) {
140 notexisted = false;
141 }
142 }
143
144 if(notexisted) {
145 pos2[j] = newWindow->start2[j] + 1;
146 temp1.BC = newWindow->BC;
147 temp1.blockId1 = newWindow->Id1;
148 temp1.blockId2 = newWindow->Id2;
149 temp1.pos1[0] = pos1[0];
150 temp1.pos1[1] = pos1[1];
151 temp1.pos2[0] = pos2[0];
152 temp1.pos2[1] = pos2[1];
153 temp1.Nstar = -1;
154 found = findConnection(temp1);
155
156 if(found) {
157 newWindow->step1[i] = -1;
158 newWindow->step2[j] = 1;
159 newWindow->order[i] = j;
160 break;
161 }
162
163 // D2-
164 pos2[j] = newWindow->start2[j] - 1;
165 temp1.BC = newWindow->BC;
166 temp1.blockId1 = newWindow->Id1;
167 temp1.blockId2 = newWindow->Id2;
168 temp1.pos1[0] = pos1[0];
169 temp1.pos1[1] = pos1[1];
170 temp1.pos2[0] = pos2[0];
171 temp1.pos2[1] = pos2[1];
172 temp1.Nstar = -1;
173 found = findConnection(temp1);
174
175 if(found) {
176 newWindow->step1[i] = -1;
177 newWindow->step2[j] = -1;
178 newWindow->order[i] = j;
179 break;
180 }
181 }
182 }
183 if(found) {
184 continue;
185 }
186 }
187 }
188
189 MInt ordercount = 0;
190 MBool facewindow, directionInWindow[nDim];
191 for(MInt i = 0; i < nDim; ++i) {
192 directionInWindow[i] = false;
193 if(newWindow->order[i] != -1) {
194 ordercount++;
195 directionInWindow[i] = true;
196 }
197 }
198
199 if(ordercount > 2) {
200 cout << "Invalid volume mapping found! Are your blocks overlapping or is the grid epsilon too large?" << endl;
201 }
202
203 if(ordercount == 2) {
204 facewindow = true;
205 } else {
206 facewindow = false;
207 }
208
209 for(MInt i = 0; i < 2; ++i) {
210 MInt j = 0;
211
212 if(newWindow->order[i] == -1) {
213 for(j = 0; j < 2; ++j) {
214 labell = true;
215 for(MInt k = 0; k < 2; ++k) {
216 if(newWindow->order[k] == j) {
217 labell = false;
218 }
219 }
220
221 if(labell == true) {
222 newWindow->order[i] = j;
223 break;
224 }
225 }
226
227 if(facewindow) {
228 if(newWindow->start1[i] == 0) {
229 newWindow->dc1 = i + 1;
230 } else {
231 newWindow->dc1 = -i - 1;
232 }
233
234 if(newWindow->start2[j] == 0) {
235 newWindow->dc2 = j + 1;
236 } else {
237 newWindow->dc2 = -j - 1;
238 }
239 } else {
240 newWindow->dc1 = 999;
241 newWindow->dc2 = 999;
242 }
243 }
244 }
245
246 MInt start1[2], end1[2], start2[2], end2[2];
247 MBool goGo = true;
248 MInt countDim, countDim2;
249 MInt ii, jj;
250 while(goGo) {
251 goGo = false;
252 for(countDim = 0; countDim < nDim; ++countDim) {
253 if(directionInWindow[countDim]) {
254 countDim2 = newWindow->order[countDim];
255
256 for(MInt i = 0; i < 2; ++i) {
257 start1[i] = newWindow->start1[i];
258 end1[i] = newWindow->end1[i];
259 start2[i] = newWindow->start2[i];
260 end2[i] = newWindow->end2[i];
261 }
262 end1[countDim] = end1[countDim] + newWindow->step1[countDim];
263 end2[countDim2] = end2[countDim2] + newWindow->step2[countDim2];
264 start1[countDim] = end1[countDim];
265 start2[countDim2] = end2[countDim2];
266
267
268 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
269 jj = start1[1];
270 do {
271 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
272 ii = start1[0];
273 do {
274 pos1[0] = ii;
275 pos1[1] = jj;
276 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
277 labell = true;
278 } else {
279 labell = false;
280 }
281
282 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
283 found = findConnection(temp2);
284
285 if(!found && domainId() == 0 && newWindow->BC == 4401 && newWindow->Id1 == 2 && newWindow->Id2 != 2) {
286 // temp2.print();
287 connectionNode temp3(newWindow->BC, newWindow->Id2, pos2, newWindow->Id1, pos1, labell, nDim);
288 found = findConnection(temp3);
289
290 if(found) {
291 cout << "wooooo!! somthing is wrong and i do not know where and why!!!!!!" << endl;
292 }
293 }
294 if(!found) {
295 break;
296 }
297 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
298 ii = ii + newWindow->step1[0];
299
300 } while(ii >= start1[0] && ii <= end1[0]);
301 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
302 jj = jj + newWindow->step1[1];
303
304 } while(jj >= start1[1] && jj <= end1[1]);
305
306
307 if(found) {
308 // all connections have been found
309 for(MInt m = 0; m < 2; ++m) {
310 newWindow->end1[m] = end1[m];
311 newWindow->end2[m] = end2[m];
312 }
313 goGo = true;
314 }
315
316 for(MInt i = 0; i < 2; ++i) {
317 start1[i] = newWindow->start1[i];
318 end1[i] = newWindow->end1[i];
319 start2[i] = newWindow->start2[i];
320 end2[i] = newWindow->end2[i];
321 }
322 start1[countDim] = start1[countDim] - newWindow->step1[countDim];
323 start2[countDim2] = start2[countDim2] - newWindow->step2[countDim2];
324 end1[countDim] = start1[countDim];
325 end2[countDim2] = start2[countDim2];
326
327 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
328 jj = start1[1];
329 do {
330 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
331 ii = start1[0];
332 do {
333 pos1[0] = ii;
334 pos1[1] = jj;
335 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
336 labell = true;
337 } else {
338 labell = false;
339 }
340
341 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
342 found = findConnection(temp2);
343
344 if(!found && domainId() == 0 && newWindow->BC == 4401 && newWindow->Id1 == 2 && newWindow->Id2 != 2) {
345 connectionNode temp3(newWindow->BC, newWindow->Id2, pos2, newWindow->Id1, pos1, labell, nDim);
346 found = findConnection(temp3);
347 if(found) {
348 cout << "wooooo!! somthing is wrong and i do not know where and why!!!!!!" << endl;
349 }
350 }
351 if(!found) {
352 break;
353 }
354 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
355 ii = ii + newWindow->step1[0];
356
357 } while(ii >= start1[0] && ii <= end1[0]);
358 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
359 jj = jj + newWindow->step1[1];
360
361 } while(jj >= start1[1] && jj <= end1[1]);
362
363
364 if(found) {
365 // all connections have been found
366 for(MInt m = 0; m < 2; ++m) {
367 newWindow->start1[m] = start1[m];
368 newWindow->start2[m] = start2[m];
369 }
370 goGo = true;
371 }
372 }
373 }
374 }
375
376 if(newWindow->BC >= 6000 && newWindow->BC < 6010
377 && newWindow->Id2
378 < newWindow->Id1) { //(newWindow->BC == 6000 && newWindow->Id2 < newWindow->Id1) { //6000er-change
379 mapInvert1(newWindow);
380 }
381 mapNormalize3(newWindow);
382
383 // delete treated connections
384 pos2[newWindow->order[1]] = newWindow->start2[newWindow->order[1]];
385 for(MInt j = newWindow->start1[1]; j <= newWindow->end1[1]; j = j + newWindow->step1[1]) {
386 pos2[newWindow->order[0]] = newWindow->start2[newWindow->order[0]];
387 for(MInt i = newWindow->start1[0]; i <= newWindow->end1[0]; i = i + newWindow->step1[0]) {
388 pos1[0] = i;
389 pos1[1] = j;
390
391 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
392 labell = true;
393 } else {
394 labell = false;
395 }
396
397 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
398 found = findConnection(temp2);
399
400 if(!found) {
401 cout << "error!! can not delete the element!!!" << endl;
402 cout << "BC: " << newWindow->BC << " id1:" << newWindow->Id1 << " id1:" << newWindow->Id2 << endl;
403 cout << "i: " << i << " iend:" << newWindow->end1[0] << " j: " << j << " jend:" << newWindow->end1[1] << endl;
404 }
405
406 if(found) {
407 removeConnection(temp2);
408 countConnection = countConnection + 1;
409 }
410
411 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
412 }
413 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
414 }
415
416 MInt facecount;
417 if(!mapCheck(newWindow)) {
418 cout << "invalid window!" << endl;
419 }
420
421 facecount = 0;
422 for(MInt i = 0; i < nDim; ++i) {
423 if(newWindow->end1[i] - newWindow->start1[i] != 0) {
424 facecount++;
425 }
426 }
427
428 switch(facecount) {
429 case 1: {
430 window1d.push_back(std::move(newWindow));
431 numWindows[1]++;
432 } break;
433
434 case 0: {
435 window0d.push_back(std::move(newWindow));
436 numWindows[0]++;
437 } break;
438
439 default:
440 cout << "ERROR!!! face dim is wrong!!!" << endl;
441 }
442 }
443
444 m_log << "Connection Statistics: " << numWindows[1] << " 1D-, and " << numWindows[0] << " 0D-connections found"
445 << endl;
446}
447
448
449template <>
451 TRACE();
452 const MInt nDim = 2;
453 // TODO_SS labels:FV,toenhance In 2d singularities are points. The following algorithm is a unnecessary overhead
454
455 // cout<<"number of connections: "<<numConnections<<endl;
456 MInt countConnection = 0, numConnections = 0, Nstar;
457 unique_ptr<StructuredWindowMap<nDim>> newWindow;
458 MBool found, notexisted, labell;
459 connectionNode temp1(nDim);
460 MInt numWindows[nDim]{};
461 numConnections = singularconnectionset.size();
462
463 // typename set<connectionNode>::iterator it;
464
465 while(singularconnectionset.size() != 0) {
466 auto element = singularconnectionset.begin();
467 MInt order[2] = {-1, -1};
468 MInt step1[2] = {1, 1};
469 MInt step2[2] = {1, 1};
470 MInt pos1[3], pos2[3], b1, b2;
471
472 pos1[0] = element->pos1[0];
473 pos1[1] = element->pos1[1];
474 pos2[0] = element->pos2[0];
475 pos2[1] = element->pos2[1];
476 b1 = element->blockId1;
477 b2 = element->blockId2;
478 Nstar = element->Nstar;
479
480 newWindow = make_unique<StructuredWindowMap<nDim>>();
481 mapCreate(b1, pos1, pos1, step1, b2, pos2, pos2, step2, order, element->BC, newWindow);
482 newWindow->Nstar = Nstar;
483
484 for(MInt i = 0; i < nDim; ++i) {
485 found = false;
486 pos1[0] = newWindow->start1[0];
487 pos1[1] = newWindow->start1[1];
488
489 if(newWindow->order[i] == -1) {
490 // D1+
491
492 pos1[i] = newWindow->start1[i] + 1;
493 for(MInt j = 0; j < nDim; ++j) {
494 // D2
495 pos2[0] = newWindow->start2[0];
496 pos2[1] = newWindow->start2[1];
497
498 notexisted = true;
499 for(MInt k = 0; k < nDim; ++k) {
500 if(newWindow->order[k] == j) {
501 notexisted = false;
502 }
503 }
504
505 if(notexisted) {
506 pos2[j] = newWindow->start2[j] + 1;
507
508 temp1.BC = newWindow->BC;
509 temp1.blockId1 = newWindow->Id1;
510 temp1.blockId2 = newWindow->Id2;
511 temp1.pos1[0] = pos1[0];
512 temp1.pos1[1] = pos1[1];
513 temp1.pos2[0] = pos2[0];
514 temp1.pos2[1] = pos2[1];
515 temp1.Nstar = Nstar;
516 found = findConnection(temp1, Nstar);
517
518 if(found) {
519 newWindow->step1[i] = 1;
520 newWindow->step2[j] = 1;
521 newWindow->order[i] = j;
522 break;
523 }
524
525 // D2-
526 pos2[j] = newWindow->start2[j] - 1;
527 // temp1(newWindow->BC,newWindow->Id1,pos1,newWindow->Id2,pos2);
528 temp1.BC = newWindow->BC;
529 temp1.blockId1 = newWindow->Id1;
530 temp1.blockId2 = newWindow->Id2;
531 temp1.pos1[0] = pos1[0];
532 temp1.pos1[1] = pos1[1];
533 temp1.pos2[0] = pos2[0];
534 temp1.pos2[1] = pos2[1];
535 temp1.Nstar = Nstar;
536 found = findConnection(temp1, Nstar);
537
538 if(found) {
539 newWindow->step1[i] = 1;
540 newWindow->step2[j] = -1;
541 newWindow->order[i] = j;
542 break;
543 }
544 }
545 }
546 if(found) {
547 continue;
548 }
549
550 // D1-
551 pos1[i] = newWindow->start1[i] - 1;
552 for(MInt j = 0; j < nDim; ++j) {
553 // D2+
554 pos2[0] = newWindow->start2[0];
555 pos2[1] = newWindow->start2[1];
556 notexisted = true;
557
558 for(MInt k = 0; k < nDim; ++k) {
559 if(newWindow->order[k] == j) notexisted = false;
560 }
561
562 if(notexisted) {
563 pos2[j] = newWindow->start2[j] + 1;
564 temp1.BC = newWindow->BC;
565 temp1.blockId1 = newWindow->Id1;
566 temp1.blockId2 = newWindow->Id2;
567 temp1.pos1[0] = pos1[0];
568 temp1.pos1[1] = pos1[1];
569 temp1.pos2[0] = pos2[0];
570 temp1.pos2[1] = pos2[1];
571 temp1.Nstar = Nstar;
572 found = findConnection(temp1, Nstar);
573
574 if(found) {
575 newWindow->step1[i] = -1;
576 newWindow->step2[j] = 1;
577 newWindow->order[i] = j;
578 break;
579 }
580 // D2-
581 pos2[j] = newWindow->start2[j] - 1;
582 temp1.BC = newWindow->BC;
583 temp1.blockId1 = newWindow->Id1;
584 temp1.blockId2 = newWindow->Id2;
585 temp1.pos1[0] = pos1[0];
586 temp1.pos1[1] = pos1[1];
587 temp1.pos2[0] = pos2[0];
588 temp1.pos2[1] = pos2[1];
589 temp1.Nstar = Nstar;
590 found = findConnection(temp1, Nstar);
591
592 if(found) {
593 newWindow->step1[i] = -1;
594 newWindow->step2[j] = -1;
595 newWindow->order[i] = j;
596 break;
597 }
598 }
599 }
600 if(found) {
601 continue;
602 }
603 }
604 }
605
606 MInt ordercount = 0;
607 MBool facewindow, directionInWindow[nDim];
608
609 for(MInt i = 0; i < nDim; ++i) {
610 directionInWindow[i] = false;
611 if(newWindow->order[i] != -1) {
612 ordercount++;
613 directionInWindow[i] = true;
614 }
615 }
616
617 ASSERT(ordercount == 0, "In 2D only ordercount==0 makes sense!");
618
619 if(ordercount > 2) {
620 cout << "Invalid volume mapping found! "
621 << "Are your blockIds overlapping or is the grid epsilon too large?" << endl;
622 }
623
624 if(ordercount == 2) {
625 facewindow = true;
626 } else {
627 facewindow = false;
628 }
629
630 for(MInt i = 0; i < nDim; ++i) {
631 MInt j = 0;
632 if(newWindow->order[i] == -1) {
633 for(j = 0; j < nDim; ++j) {
634 labell = true;
635 for(MInt k = 0; k < nDim; ++k) {
636 if(newWindow->order[k] == j) {
637 labell = false;
638 }
639 }
640 if(labell == true) {
641 newWindow->order[i] = j;
642 break;
643 }
644 }
645
646 if(facewindow) {
647 if(newWindow->start1[i] == 0) {
648 newWindow->dc1 = i + 1;
649 } else {
650 newWindow->dc1 = -i - 1;
651 }
652
653 if(newWindow->start2[j] == 0) {
654 newWindow->dc2 = j + 1;
655 } else {
656 newWindow->dc2 = -j - 1;
657 }
658 } else {
659 newWindow->dc1 = 999;
660 newWindow->dc2 = 999;
661 }
662 }
663 }
664
665 MInt start1[2], end1[2], start2[2], end2[2];
666 MBool goGo = true;
667 MInt countDim, countDim2;
668 MInt ii, jj;
669
670 while(goGo) {
671 goGo = false;
672 for(countDim = 0; countDim < nDim; ++countDim) {
673 if(directionInWindow[countDim]) {
674 countDim2 = newWindow->order[countDim];
675 for(MInt i = 0; i < nDim; ++i) {
676 start1[i] = newWindow->start1[i];
677 end1[i] = newWindow->end1[i];
678 start2[i] = newWindow->start2[i];
679 end2[i] = newWindow->end2[i];
680 }
681 end1[countDim] = end1[countDim] + newWindow->step1[countDim];
682 end2[countDim2] = end2[countDim2] + newWindow->step2[countDim2];
683 start1[countDim] = end1[countDim];
684 start2[countDim2] = end2[countDim2];
685
686 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
687 jj = start1[1];
688 do {
689 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
690 ii = start1[0];
691 do {
692 pos1[0] = ii;
693 pos1[1] = jj;
694 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
695 labell = true;
696 } else {
697 labell = false;
698 }
699
700 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
701 temp2.Nstar = Nstar;
702 found = findConnection(temp2, Nstar);
703
704 if(!found) {
705 break;
706 }
707 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
708 ii = ii + newWindow->step1[0];
709
710 } while(ii >= start1[0] && ii <= end1[0]);
711 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
712 jj = jj + newWindow->step1[1];
713
714 } while(jj >= start1[1] && jj <= end1[1]);
715
716 if(found) {
717 // all connections have been found
718 for(MInt m = 0; m < nDim; ++m) {
719 newWindow->end1[m] = end1[m];
720 newWindow->end2[m] = end2[m];
721 }
722 goGo = true;
723 }
724
725 for(MInt i = 0; i < nDim; ++i) {
726 start1[i] = newWindow->start1[i];
727 end1[i] = newWindow->end1[i];
728 start2[i] = newWindow->start2[i];
729 end2[i] = newWindow->end2[i];
730 }
731
732 start1[countDim] = start1[countDim] - newWindow->step1[countDim];
733 start2[countDim2] = start2[countDim2] - newWindow->step2[countDim2];
734 end1[countDim] = start1[countDim];
735 end2[countDim2] = start2[countDim2];
736
737 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
738 jj = start1[1];
739 do {
740 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
741 ii = start1[0];
742 do {
743 pos1[0] = ii;
744 pos1[1] = jj;
745
746 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
747 labell = true;
748 } else {
749 labell = false;
750 }
751
752 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
753 temp2.Nstar = Nstar;
754 found = findConnection(temp2, Nstar);
755
756 if(!found) {
757 break;
758 }
759
760 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
761 ii = ii + newWindow->step1[0];
762
763 } while(ii >= start1[0] && ii <= end1[0]);
764 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
765 jj = jj + newWindow->step1[1];
766
767 } while(jj >= start1[1] && jj <= end1[1]);
768
769 if(found) {
770 // all connections have been found
771 for(MInt m = 0; m < nDim; ++m) {
772 newWindow->start1[m] = start1[m];
773 newWindow->start2[m] = start2[m];
774 }
775
776 goGo = true;
777 }
778 }
779 }
780 }
781
782 if(newWindow->BC >= 6000 && newWindow->BC < 6010
783 && newWindow->Id2
784 < newWindow->Id1) { //(newWindow->BC == 6000 && newWindow->Id2 < newWindow->Id1) { //6000er-change
785 mapInvert1(newWindow);
786 }
787 mapNormalize3(newWindow);
788
789 // delete treated connections
790 pos2[newWindow->order[1]] = newWindow->start2[newWindow->order[1]];
791 for(MInt j = newWindow->start1[1]; j <= newWindow->end1[1]; j = j + newWindow->step1[1]) {
792 pos2[newWindow->order[0]] = newWindow->start2[newWindow->order[0]];
793 for(MInt i = newWindow->start1[0]; i <= newWindow->end1[0]; i = i + newWindow->step1[0]) {
794 pos1[0] = i;
795 pos1[1] = j;
796
797 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
798 labell = true;
799 } else {
800 labell = false;
801 }
802
803 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
804 temp2.Nstar = Nstar;
805 found = findConnection(temp2, Nstar);
806
807 if(!found) {
808 cout << "singular error!! can not delete the element!!!" << endl;
809 }
810
811 removeConnection(temp2, Nstar);
812 if(found) {
813 countConnection = countConnection + 1;
814 }
815 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
816 }
817 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
818 }
819
820 // set Id for singularmap
821 newWindow->SingularId = numWindows[0];
822 singularwindow.push_back(std::move(newWindow));
823 numWindows[0]++;
824
825 if(domainId() == 0) {
826 cout << numWindows[0] << " singular connections found (" << countConnection * 100 / numConnections << "% done)"
827 << endl;
828 }
829 }
830}
831
832
833template <>
835 const MInt nDim = 3;
836 MInt countConnection = 0; // numConnections;
837 unique_ptr<StructuredWindowMap<nDim>> newWindow;
838 MBool found, notexisted, labell;
839 connectionNode temp1(nDim);
840 MInt numWindows[3] = {0, 0, 0};
841
842 // set<connectionNode>::iterator it;
843 // numConnections=connectionset.size();
844
845 while(connectionset.size() != 0) {
846 auto element = connectionset.begin();
847 MInt order[3] = {-1, -1, -1};
848 MInt step1[3] = {1, 1, 1};
849 MInt step2[3] = {1, 1, 1};
850 MInt pos1[3], pos2[3], b1, b2;
851
852 pos1[0] = element->pos1[0];
853 pos1[1] = element->pos1[1];
854 pos1[2] = element->pos1[2];
855 pos2[0] = element->pos2[0];
856 pos2[1] = element->pos2[1];
857 pos2[2] = element->pos2[2];
858 b1 = element->blockId1;
859 b2 = element->blockId2;
860
861 newWindow = make_unique<StructuredWindowMap<nDim>>();
862 mapCreate(b1, pos1, pos1, step1, b2, pos2, pos2, step2, order, element->BC, newWindow);
863 newWindow->Nstar = -1;
864
865 for(MInt i = 0; i < nDim; ++i) {
866 found = false;
867 pos1[0] = newWindow->start1[0];
868 pos1[1] = newWindow->start1[1];
869 pos1[2] = newWindow->start1[2];
870
871 if(newWindow->order[i] == -1) {
872 // D1+
873
874 pos1[i] = newWindow->start1[i] + 1;
875 for(MInt j = 0; j < nDim; ++j) {
876 // D2
877 pos2[0] = newWindow->start2[0];
878 pos2[1] = newWindow->start2[1];
879 pos2[2] = newWindow->start2[2];
880
881 notexisted = true;
882 for(MInt k = 0; k < nDim; ++k) {
883 if(newWindow->order[k] == j) notexisted = false;
884 }
885
886 if(notexisted) {
887 pos2[j] = newWindow->start2[j] + 1;
888
889 temp1.BC = newWindow->BC;
890 temp1.blockId1 = newWindow->Id1;
891 temp1.blockId2 = newWindow->Id2;
892 temp1.pos1[0] = pos1[0];
893 temp1.pos1[1] = pos1[1];
894 temp1.pos1[2] = pos1[2];
895 temp1.pos2[0] = pos2[0];
896 temp1.pos2[1] = pos2[1];
897 temp1.pos2[2] = pos2[2];
898 temp1.Nstar = -1;
899 found = findConnection(temp1);
900
901 if(found) {
902 newWindow->step1[i] = 1;
903 newWindow->step2[j] = 1;
904 newWindow->order[i] = j;
905 break;
906 }
907
908 // D2-
909 pos2[j] = newWindow->start2[j] - 1;
910 temp1.BC = newWindow->BC;
911 temp1.blockId1 = newWindow->Id1;
912 temp1.blockId2 = newWindow->Id2;
913 temp1.pos1[0] = pos1[0];
914 temp1.pos1[1] = pos1[1];
915 temp1.pos1[2] = pos1[2];
916 temp1.pos2[0] = pos2[0];
917 temp1.pos2[1] = pos2[1];
918 temp1.pos2[2] = pos2[2];
919 temp1.Nstar = -1;
920 found = findConnection(temp1);
921 if(found) {
922 newWindow->step1[i] = 1;
923 newWindow->step2[j] = -1;
924 newWindow->order[i] = j;
925 break;
926 }
927 }
928 }
929
930 if(found) {
931 continue;
932 }
933
934 // D1-
935 pos1[i] = newWindow->start1[i] - 1;
936 for(MInt j = 0; j < nDim; ++j) {
937 // D2+
938 pos2[0] = newWindow->start2[0];
939 pos2[1] = newWindow->start2[1];
940 pos2[2] = newWindow->start2[2];
941 notexisted = true;
942 for(MInt k = 0; k < nDim; ++k) {
943 if(newWindow->order[k] == j) {
944 notexisted = false;
945 }
946 }
947
948 if(notexisted) {
949 pos2[j] = newWindow->start2[j] + 1;
950 temp1.BC = newWindow->BC;
951 temp1.blockId1 = newWindow->Id1;
952 temp1.blockId2 = newWindow->Id2;
953 temp1.pos1[0] = pos1[0];
954 temp1.pos1[1] = pos1[1];
955 temp1.pos1[2] = pos1[2];
956 temp1.pos2[0] = pos2[0];
957 temp1.pos2[1] = pos2[1];
958 temp1.pos2[2] = pos2[2];
959 temp1.Nstar = -1;
960 found = findConnection(temp1);
961
962 if(found) {
963 newWindow->step1[i] = -1;
964 newWindow->step2[j] = 1;
965 newWindow->order[i] = j;
966 break;
967 }
968
969 // D2-
970 pos2[j] = newWindow->start2[j] - 1;
971 temp1.BC = newWindow->BC;
972 temp1.blockId1 = newWindow->Id1;
973 temp1.blockId2 = newWindow->Id2;
974 temp1.pos1[0] = pos1[0];
975 temp1.pos1[1] = pos1[1];
976 temp1.pos1[2] = pos1[2];
977 temp1.pos2[0] = pos2[0];
978 temp1.pos2[1] = pos2[1];
979 temp1.pos2[2] = pos2[2];
980 temp1.Nstar = -1;
981 found = findConnection(temp1);
982
983 if(found) {
984 newWindow->step1[i] = -1;
985 newWindow->step2[j] = -1;
986 newWindow->order[i] = j;
987 break;
988 }
989 }
990 }
991 if(found) {
992 continue;
993 }
994 }
995 }
996
997 MInt ordercount = 0;
998 MBool facewindow, directionInWindow[3];
999 for(MInt i = 0; i < nDim; ++i) {
1000 directionInWindow[i] = false;
1001 if(newWindow->order[i] != -1) {
1002 ordercount++;
1003 directionInWindow[i] = true;
1004 }
1005 }
1006
1007 if(ordercount > 2) {
1008 cout << "Invalid volume mapping found! Are your blockIds overlapping or is the grid epsilon too large?" << endl;
1009 }
1010
1011 if(ordercount == 2) {
1012 facewindow = true;
1013 } else {
1014 facewindow = false;
1015 }
1016
1017 for(MInt i = 0; i < nDim; ++i) {
1018 MInt j = 0;
1019
1020 if(newWindow->order[i] == -1) {
1021 for(j = 0; j < nDim; ++j) {
1022 labell = true;
1023 for(MInt k = 0; k < nDim; ++k) {
1024 if(newWindow->order[k] == j) {
1025 labell = false;
1026 }
1027 }
1028
1029 if(labell == true) {
1030 newWindow->order[i] = j;
1031 break;
1032 }
1033 }
1034
1035 if(facewindow) {
1036 if(newWindow->start1[i] == 0) {
1037 newWindow->dc1 = i + 1;
1038 } else {
1039 newWindow->dc1 = -i - 1;
1040 }
1041
1042 if(newWindow->start2[j] == 0) {
1043 newWindow->dc2 = j + 1;
1044 } else {
1045 newWindow->dc2 = -j - 1;
1046 }
1047 } else {
1048 newWindow->dc1 = 999;
1049 newWindow->dc2 = 999;
1050 }
1051 }
1052 }
1053
1054 MInt start1[3], end1[3], start2[3], end2[3];
1055 MBool goGo = true;
1056 MInt countDim, countDim2;
1057 MInt ii, jj, kk;
1058 while(goGo) {
1059 goGo = false;
1060 for(countDim = 0; countDim < nDim; ++countDim) {
1061 if(directionInWindow[countDim]) {
1062 countDim2 = newWindow->order[countDim];
1063
1064 for(MInt i = 0; i < nDim; ++i) {
1065 start1[i] = newWindow->start1[i];
1066 end1[i] = newWindow->end1[i];
1067 start2[i] = newWindow->start2[i];
1068 end2[i] = newWindow->end2[i];
1069 }
1070 end1[countDim] = end1[countDim] + newWindow->step1[countDim];
1071 end2[countDim2] = end2[countDim2] + newWindow->step2[countDim2];
1072 start1[countDim] = end1[countDim];
1073 start2[countDim2] = end2[countDim2];
1074
1075 pos2[newWindow->order[2]] = start2[newWindow->order[2]];
1076 kk = start1[2];
1077 do {
1078 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
1079 jj = start1[1];
1080 do {
1081 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
1082 ii = start1[0];
1083 do {
1084 pos1[0] = ii;
1085 pos1[1] = jj;
1086 pos1[2] = kk;
1087 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1088 labell = true;
1089 } else {
1090 labell = false;
1091 }
1092
1093 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1094 found = findConnection(temp2);
1095
1096 if(!found && domainId() == 0 && newWindow->BC == 4401 && newWindow->Id1 == 2 && newWindow->Id2 != 2) {
1097 // temp2.print();
1098 connectionNode temp3(newWindow->BC, newWindow->Id2, pos2, newWindow->Id1, pos1, labell, nDim);
1099 found = findConnection(temp3);
1100
1101 if(found) {
1102 cout << "wooooo!! somthing is wrong and i do not know where and why!!!!!!" << endl;
1103 }
1104 }
1105 if(!found) {
1106 break;
1107 }
1108 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1109 ii = ii + newWindow->step1[0];
1110
1111 } while(ii >= start1[0] && ii <= end1[0]);
1112 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1113 jj = jj + newWindow->step1[1];
1114
1115 } while(jj >= start1[1] && jj <= end1[1]);
1116 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1117 kk = kk + newWindow->step1[2];
1118
1119 } while(kk >= start1[2] && kk <= end1[2]);
1120
1121 if(found) {
1122 // all connections have been found
1123 for(MInt m = 0; m < nDim; ++m) {
1124 newWindow->end1[m] = end1[m];
1125 newWindow->end2[m] = end2[m];
1126 }
1127 goGo = true;
1128 }
1129
1130 for(MInt i = 0; i < nDim; ++i) {
1131 start1[i] = newWindow->start1[i];
1132 end1[i] = newWindow->end1[i];
1133 start2[i] = newWindow->start2[i];
1134 end2[i] = newWindow->end2[i];
1135 }
1136 start1[countDim] = start1[countDim] - newWindow->step1[countDim];
1137 start2[countDim2] = start2[countDim2] - newWindow->step2[countDim2];
1138 end1[countDim] = start1[countDim];
1139 end2[countDim2] = start2[countDim2];
1140
1141 pos2[newWindow->order[2]] = start2[newWindow->order[2]];
1142 kk = start1[2];
1143 do {
1144 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
1145 jj = start1[1];
1146 do {
1147 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
1148 ii = start1[0];
1149 do {
1150 pos1[0] = ii;
1151 pos1[1] = jj;
1152 pos1[2] = kk;
1153 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1154 labell = true;
1155 } else {
1156 labell = false;
1157 }
1158
1159 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1160 found = findConnection(temp2);
1161
1162 if(!found && domainId() == 0 && newWindow->BC == 4401 && newWindow->Id1 == 2 && newWindow->Id2 != 2) {
1163 connectionNode temp3(newWindow->BC, newWindow->Id2, pos2, newWindow->Id1, pos1, labell, nDim);
1164 found = findConnection(temp3);
1165 if(found) {
1166 cout << "wooooo!! somthing is wrong and i do not know where and why!!!!!!" << endl;
1167 }
1168 }
1169 if(!found) {
1170 break;
1171 }
1172 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1173 ii = ii + newWindow->step1[0];
1174
1175 } while(ii >= start1[0] && ii <= end1[0]);
1176 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1177 jj = jj + newWindow->step1[1];
1178
1179 } while(jj >= start1[1] && jj <= end1[1]);
1180 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1181 kk = kk + newWindow->step1[2];
1182
1183 } while(kk >= start1[2] && kk <= end1[2]);
1184
1185
1186 if(found) {
1187 // all connections have been found
1188 for(MInt m = 0; m < nDim; ++m) {
1189 newWindow->start1[m] = start1[m];
1190 newWindow->start2[m] = start2[m];
1191 }
1192 goGo = true;
1193 }
1194 }
1195 }
1196 }
1197
1198 if(newWindow->BC >= 6000 && newWindow->BC < 6010
1199 && newWindow->Id2
1200 < newWindow->Id1) { //(newWindow->BC == 6000 && newWindow->Id2 < newWindow->Id1) { //6000er-change
1201 mapInvert1(newWindow);
1202 }
1203 mapNormalize3(newWindow);
1204
1205 // delete treated connections
1206 pos2[newWindow->order[2]] = newWindow->start2[newWindow->order[2]];
1207 for(MInt k = newWindow->start1[2]; k <= newWindow->end1[2]; k = k + newWindow->step1[2]) {
1208 pos2[newWindow->order[1]] = newWindow->start2[newWindow->order[1]];
1209 for(MInt j = newWindow->start1[1]; j <= newWindow->end1[1]; j = j + newWindow->step1[1]) {
1210 pos2[newWindow->order[0]] = newWindow->start2[newWindow->order[0]];
1211 for(MInt i = newWindow->start1[0]; i <= newWindow->end1[0]; i = i + newWindow->step1[0]) {
1212 pos1[0] = i;
1213 pos1[1] = j;
1214 pos1[2] = k;
1215
1216 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1217 labell = true;
1218 } else {
1219 labell = false;
1220 }
1221
1222 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1223 found = findConnection(temp2);
1224
1225 if(!found) {
1226 cout << "error!! can not delete the element!!!" << endl;
1227 cout << "BC: " << newWindow->BC << " id1:" << newWindow->Id1 << " id1:" << newWindow->Id2 << endl;
1228 cout << "i: " << i << " iend:" << newWindow->end1[0] << " j: " << j << " jend:" << newWindow->end1[1]
1229 << " k: " << k << " kend:" << newWindow->end1[2] << endl;
1230 }
1231
1232 if(found) {
1233 removeConnection(temp2);
1234 countConnection = countConnection + 1;
1235 }
1236
1237 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1238 }
1239 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1240 }
1241 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1242 }
1243
1244 MInt facecount;
1245 if(!mapCheck(newWindow)) {
1246 cout << "invalid window!" << endl;
1247 }
1248
1249 facecount = 0;
1250 for(MInt i = 0; i < nDim; ++i) {
1251 if(newWindow->end1[i] - newWindow->start1[i] != 0) {
1252 facecount++;
1253 }
1254 }
1255
1256 switch(facecount) {
1257 case 2: {
1258 window2d.push_back(std::move(newWindow));
1259 numWindows[2]++;
1260 } break;
1261
1262 case 1: {
1263 window1d.push_back(std::move(newWindow));
1264 numWindows[1]++;
1265 } break;
1266
1267 case 0: {
1268 window0d.push_back(std::move(newWindow));
1269 numWindows[0]++;
1270 } break;
1271
1272 default:
1273 cout << "ERROR!!! face dim is wrong!!!" << endl;
1274 }
1275 }
1276
1277 m_log << "Connection Statistics: " << numWindows[2] << " 2D-, " << numWindows[1] << " 1D-, and " << numWindows[0]
1278 << " 0D-connections found" << endl;
1279}
1280
1281template <>
1283 const MInt nDim = 3;
1284 // cout<<"number of connections: "<<numConnections<<endl;
1285 MInt countConnection = 0, numConnections = 0, Nstar;
1286 unique_ptr<StructuredWindowMap<nDim>> newWindow;
1287 MBool found, notexisted, labell;
1288 connectionNode temp1(nDim);
1289 MInt numWindows[3] = {0, 0, 0};
1290 numConnections = singularconnectionset.size();
1291
1292 // typename set<connectionNode>::iterator it;
1293
1294 while(singularconnectionset.size() != 0) {
1295 auto element = singularconnectionset.begin();
1296 MInt order[3] = {-1, -1, -1};
1297 MInt step1[3] = {1, 1, 1};
1298 MInt step2[3] = {1, 1, 1};
1299 MInt pos1[3], pos2[3], b1, b2;
1300
1301 pos1[0] = element->pos1[0];
1302 pos1[1] = element->pos1[1];
1303 pos1[2] = element->pos1[2];
1304 pos2[0] = element->pos2[0];
1305 pos2[1] = element->pos2[1];
1306 pos2[2] = element->pos2[2];
1307 b1 = element->blockId1;
1308 b2 = element->blockId2;
1309 Nstar = element->Nstar;
1310
1311 newWindow = make_unique<StructuredWindowMap<nDim>>();
1312 mapCreate(b1, pos1, pos1, step1, b2, pos2, pos2, step2, order, element->BC, newWindow);
1313 newWindow->Nstar = Nstar;
1314
1315 for(MInt i = 0; i < nDim; ++i) {
1316 found = false;
1317 pos1[0] = newWindow->start1[0];
1318 pos1[1] = newWindow->start1[1];
1319 pos1[2] = newWindow->start1[2];
1320
1321 if(newWindow->order[i] == -1) {
1322 // D1+
1323
1324 pos1[i] = newWindow->start1[i] + 1;
1325 for(MInt j = 0; j < nDim; ++j) {
1326 // D2
1327 pos2[0] = newWindow->start2[0];
1328 pos2[1] = newWindow->start2[1];
1329 pos2[2] = newWindow->start2[2];
1330
1331 notexisted = true;
1332 for(MInt k = 0; k < nDim; ++k) {
1333 if(newWindow->order[k] == j) {
1334 notexisted = false;
1335 }
1336 }
1337
1338 if(notexisted) {
1339 pos2[j] = newWindow->start2[j] + 1;
1340
1341 temp1.BC = newWindow->BC;
1342 temp1.blockId1 = newWindow->Id1;
1343 temp1.blockId2 = newWindow->Id2;
1344 temp1.pos1[0] = pos1[0];
1345 temp1.pos1[1] = pos1[1];
1346 temp1.pos1[2] = pos1[2];
1347 temp1.pos2[0] = pos2[0];
1348 temp1.pos2[1] = pos2[1];
1349 temp1.pos2[2] = pos2[2];
1350 temp1.Nstar = Nstar;
1351 found = findConnection(temp1, Nstar);
1352
1353 if(found) {
1354 newWindow->step1[i] = 1;
1355 newWindow->step2[j] = 1;
1356 newWindow->order[i] = j;
1357 break;
1358 }
1359
1360 // D2-
1361 pos2[j] = newWindow->start2[j] - 1;
1362 // temp1(newWindow->BC,newWindow->Id1,pos1,newWindow->Id2,pos2);
1363 temp1.BC = newWindow->BC;
1364 temp1.blockId1 = newWindow->Id1;
1365 temp1.blockId2 = newWindow->Id2;
1366 temp1.pos1[0] = pos1[0];
1367 temp1.pos1[1] = pos1[1];
1368 temp1.pos1[2] = pos1[2];
1369 temp1.pos2[0] = pos2[0];
1370 temp1.pos2[1] = pos2[1];
1371 temp1.pos2[2] = pos2[2];
1372 temp1.Nstar = Nstar;
1373 found = findConnection(temp1, Nstar);
1374
1375 if(found) {
1376 newWindow->step1[i] = 1;
1377 newWindow->step2[j] = -1;
1378 newWindow->order[i] = j;
1379 break;
1380 }
1381 }
1382 }
1383 if(found) {
1384 continue;
1385 }
1386
1387 // D1-
1388 pos1[i] = newWindow->start1[i] - 1;
1389 for(MInt j = 0; j < nDim; ++j) {
1390 // D2+
1391 pos2[0] = newWindow->start2[0];
1392 pos2[1] = newWindow->start2[1];
1393 pos2[2] = newWindow->start2[2];
1394 notexisted = true;
1395
1396 for(MInt k = 0; k < nDim; ++k) {
1397 if(newWindow->order[k] == j) notexisted = false;
1398 }
1399
1400 if(notexisted) {
1401 pos2[j] = newWindow->start2[j] + 1;
1402 temp1.BC = newWindow->BC;
1403 temp1.blockId1 = newWindow->Id1;
1404 temp1.blockId2 = newWindow->Id2;
1405 temp1.pos1[0] = pos1[0];
1406 temp1.pos1[1] = pos1[1];
1407 temp1.pos1[2] = pos1[2];
1408 temp1.pos2[0] = pos2[0];
1409 temp1.pos2[1] = pos2[1];
1410 temp1.pos2[2] = pos2[2];
1411 temp1.Nstar = Nstar;
1412 found = findConnection(temp1, Nstar);
1413
1414 if(found) {
1415 newWindow->step1[i] = -1;
1416 newWindow->step2[j] = 1;
1417 newWindow->order[i] = j;
1418 break;
1419 }
1420 // D2-
1421 pos2[j] = newWindow->start2[j] - 1;
1422 temp1.BC = newWindow->BC;
1423 temp1.blockId1 = newWindow->Id1;
1424 temp1.blockId2 = newWindow->Id2;
1425 temp1.pos1[0] = pos1[0];
1426 temp1.pos1[1] = pos1[1];
1427 temp1.pos1[2] = pos1[2];
1428 temp1.pos2[0] = pos2[0];
1429 temp1.pos2[1] = pos2[1];
1430 temp1.pos2[2] = pos2[2];
1431 temp1.Nstar = Nstar;
1432 found = findConnection(temp1, Nstar);
1433
1434 if(found) {
1435 newWindow->step1[i] = -1;
1436 newWindow->step2[j] = -1;
1437 newWindow->order[i] = j;
1438 break;
1439 }
1440 }
1441 }
1442 if(found) {
1443 continue;
1444 }
1445 }
1446 }
1447
1448 MInt ordercount = 0;
1449 MBool facewindow, directionInWindow[3];
1450
1451 for(MInt i = 0; i < nDim; ++i) {
1452 directionInWindow[i] = false;
1453 if(newWindow->order[i] != -1) {
1454 ordercount++;
1455 directionInWindow[i] = true;
1456 }
1457 }
1458
1459 if(ordercount > 2) {
1460 cout << "Invalid volume mapping found! "
1461 << "Are your blockIds overlapping or is the grid epsilon too large?" << endl;
1462 }
1463
1464 if(ordercount == 2) {
1465 facewindow = true;
1466 } else {
1467 facewindow = false;
1468 }
1469
1470 for(MInt i = 0; i < nDim; ++i) {
1471 MInt j = 0;
1472 if(newWindow->order[i] == -1) {
1473 for(j = 0; j < nDim; ++j) {
1474 labell = true;
1475 for(MInt k = 0; k < nDim; ++k) {
1476 if(newWindow->order[k] == j) {
1477 labell = false;
1478 }
1479 }
1480 if(labell == true) {
1481 newWindow->order[i] = j;
1482 break;
1483 }
1484 }
1485
1486 if(facewindow) {
1487 if(newWindow->start1[i] == 0) {
1488 newWindow->dc1 = i + 1;
1489 } else {
1490 newWindow->dc1 = -i - 1;
1491 }
1492
1493 if(newWindow->start2[j] == 0) {
1494 newWindow->dc2 = j + 1;
1495 } else {
1496 newWindow->dc2 = -j - 1;
1497 }
1498 } else {
1499 newWindow->dc1 = 999;
1500 newWindow->dc2 = 999;
1501 }
1502 }
1503 }
1504
1505 MInt start1[3], end1[3], start2[3], end2[3];
1506 MBool goGo = true;
1507 MInt countDim, countDim2;
1508 MInt ii, jj, kk;
1509
1510 while(goGo) {
1511 goGo = false;
1512 for(countDim = 0; countDim < nDim; ++countDim) {
1513 if(directionInWindow[countDim]) {
1514 countDim2 = newWindow->order[countDim];
1515 for(MInt i = 0; i < nDim; ++i) {
1516 start1[i] = newWindow->start1[i];
1517 end1[i] = newWindow->end1[i];
1518 start2[i] = newWindow->start2[i];
1519 end2[i] = newWindow->end2[i];
1520 }
1521 end1[countDim] = end1[countDim] + newWindow->step1[countDim];
1522 end2[countDim2] = end2[countDim2] + newWindow->step2[countDim2];
1523 start1[countDim] = end1[countDim];
1524 start2[countDim2] = end2[countDim2];
1525
1526 pos2[newWindow->order[2]] = start2[newWindow->order[2]];
1527 kk = start1[2];
1528
1529 do {
1530 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
1531 jj = start1[1];
1532 do {
1533 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
1534 ii = start1[0];
1535 do {
1536 pos1[0] = ii;
1537 pos1[1] = jj;
1538 pos1[2] = kk;
1539 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1540 labell = true;
1541 } else {
1542 labell = false;
1543 }
1544
1545 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1546 temp2.Nstar = Nstar;
1547 found = findConnection(temp2, Nstar);
1548
1549 if(!found) {
1550 break;
1551 }
1552 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1553 ii = ii + newWindow->step1[0];
1554
1555 } while(ii >= start1[0] && ii <= end1[0]);
1556 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1557 jj = jj + newWindow->step1[1];
1558
1559 } while(jj >= start1[1] && jj <= end1[1]);
1560 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1561 kk = kk + newWindow->step1[2];
1562
1563 } while(kk >= start1[2] && kk <= end1[2]);
1564
1565 if(found) {
1566 // all connections have been found
1567 for(MInt m = 0; m < nDim; ++m) {
1568 newWindow->end1[m] = end1[m];
1569 newWindow->end2[m] = end2[m];
1570 }
1571 goGo = true;
1572 }
1573
1574 for(MInt i = 0; i < nDim; ++i) {
1575 start1[i] = newWindow->start1[i];
1576 end1[i] = newWindow->end1[i];
1577 start2[i] = newWindow->start2[i];
1578 end2[i] = newWindow->end2[i];
1579 }
1580
1581 start1[countDim] = start1[countDim] - newWindow->step1[countDim];
1582 start2[countDim2] = start2[countDim2] - newWindow->step2[countDim2];
1583 end1[countDim] = start1[countDim];
1584 end2[countDim2] = start2[countDim2];
1585
1586 pos2[newWindow->order[2]] = start2[newWindow->order[2]];
1587 kk = start1[2];
1588
1589 do {
1590 pos2[newWindow->order[1]] = start2[newWindow->order[1]];
1591 jj = start1[1];
1592 do {
1593 pos2[newWindow->order[0]] = start2[newWindow->order[0]];
1594 ii = start1[0];
1595 do {
1596 pos1[0] = ii;
1597 pos1[1] = jj;
1598 pos1[2] = kk;
1599
1600 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1601 labell = true;
1602 } else {
1603 labell = false;
1604 }
1605
1606 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1607 temp2.Nstar = Nstar;
1608 found = findConnection(temp2, Nstar);
1609
1610 if(!found) {
1611 break;
1612 }
1613
1614 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1615 ii = ii + newWindow->step1[0];
1616
1617 } while(ii >= start1[0] && ii <= end1[0]);
1618 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1619 jj = jj + newWindow->step1[1];
1620
1621 } while(jj >= start1[1] && jj <= end1[1]);
1622 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1623 kk = kk + newWindow->step1[2];
1624
1625 } while(kk >= start1[2] && kk <= end1[2]);
1626
1627 if(found) {
1628 // all connections have been found
1629 for(MInt m = 0; m < nDim; ++m) {
1630 newWindow->start1[m] = start1[m];
1631 newWindow->start2[m] = start2[m];
1632 }
1633
1634 goGo = true;
1635 }
1636 }
1637 }
1638 }
1639
1640 if(newWindow->BC >= 6000 && newWindow->BC < 6010
1641 && newWindow->Id2
1642 < newWindow->Id1) { //(newWindow->BC == 6000 && newWindow->Id2 < newWindow->Id1) { //6000er-change
1643 mapInvert1(newWindow);
1644 }
1645 mapNormalize3(newWindow);
1646
1647 // delete treated connections
1648 pos2[newWindow->order[2]] = newWindow->start2[newWindow->order[2]];
1649 for(MInt k = newWindow->start1[2]; k <= newWindow->end1[2]; k = k + newWindow->step1[2]) {
1650 pos2[newWindow->order[1]] = newWindow->start2[newWindow->order[1]];
1651 for(MInt j = newWindow->start1[1]; j <= newWindow->end1[1]; j = j + newWindow->step1[1]) {
1652 pos2[newWindow->order[0]] = newWindow->start2[newWindow->order[0]];
1653 for(MInt i = newWindow->start1[0]; i <= newWindow->end1[0]; i = i + newWindow->step1[0]) {
1654 pos1[0] = i;
1655 pos1[1] = j;
1656 pos1[2] = k;
1657
1658 if(newWindow->BC >= 6000 && newWindow->BC < 6010) { //(newWindow->BC==6000) { //6000er-change
1659 labell = true;
1660 } else {
1661 labell = false;
1662 }
1663
1664 connectionNode temp2(newWindow->BC, newWindow->Id1, pos1, newWindow->Id2, pos2, labell, nDim);
1665 temp2.Nstar = Nstar;
1666 found = findConnection(temp2, Nstar);
1667
1668 if(!found) {
1669 cout << "singular error!! can not delete the element!!!" << endl;
1670 }
1671
1672 removeConnection(temp2, Nstar);
1673 if(found) {
1674 countConnection = countConnection + 1;
1675 }
1676 pos2[newWindow->order[0]] = pos2[newWindow->order[0]] + newWindow->step2[newWindow->order[0]];
1677 }
1678 pos2[newWindow->order[1]] = pos2[newWindow->order[1]] + newWindow->step2[newWindow->order[1]];
1679 }
1680 pos2[newWindow->order[2]] = pos2[newWindow->order[2]] + newWindow->step2[newWindow->order[2]];
1681 }
1682
1683 // set Id for singularmap
1684 newWindow->SingularId = numWindows[0];
1685 singularwindow.push_back(std::move(newWindow));
1686 numWindows[0]++;
1687
1688 if(domainId() == 0) {
1689 cout << numWindows[0] << " singular connections found (" << countConnection * 100 / numConnections << "% done)"
1690 << endl;
1691 }
1692 }
1693}
1694
1695template <>
1697 constexpr MInt nDim = 3;
1698
1699 MInt hasConnectionInfo = 0;
1700 if(globalDomainId() == 0) {
1701 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
1702 MBool attributeExists = pio.hasAttribute("hasConnectionInfo", "Connectivity");
1703 if(attributeExists) {
1704 m_log << "Grid file has connection info!" << endl;
1705 pio.getAttribute(&hasConnectionInfo, "hasConnectionInfo", "Connectivity");
1706 }
1707 MPI_Bcast(&hasConnectionInfo, 1, MPI_INT, 0, m_StructuredComm, AT_, "hasConnectionInfo");
1708 } else {
1709 MPI_Bcast(&hasConnectionInfo, 1, MPI_INT, 0, m_StructuredComm, AT_, "hasConnectionInfo");
1710 }
1711
1712 MBool readInConnectionInfo = true;
1713
1714 if(!hasConnectionInfo) {
1715 readInConnectionInfo = false;
1716 } else {
1717 if(Context::propertyExists("readInConnectionInfo", m_solverId)) {
1718 readInConnectionInfo =
1719 Context::getSolverProperty<MBool>("readInConnectionInfo", solverId(), AT_, &readInConnectionInfo);
1720 }
1721 }
1722
1723 if(readInConnectionInfo) {
1724 m_log << "Connection info available, reading connection information from grid file!" << endl;
1725 readConnectionWindowInformation3D(periodicDisplacements);
1726 } else {
1727 if(domainId() == 0) {
1728 cout << "Starting grid connection info search..." << endl;
1729 }
1730 m_log << " Starting grid connection info search..." << endl;
1731 MInt offset[3], size[3], count = 0;
1732 // 3) read in the coordinates of the grid points
1733 // open file for reading the grid data
1734 // pointType<nDim>* nodeMap;
1735 MInt totalGridCells = 0;
1736 MInt** totalGridBlockDim = nullptr;
1737 MInt* totalGridBlockCells = nullptr;
1738
1739 mAlloc(totalGridBlockDim, m_noBlocks, 3, "totalGridBlockDim", -1, AT_);
1740 mAlloc(totalGridBlockCells, m_noBlocks, "totalGridBlockCells", -1, AT_);
1741
1742 for(MInt i = 0; i < m_noBlocks; ++i) {
1743 MInt temp = 1;
1744 for(MInt dim = 0; dim < 3; ++dim) {
1745 temp *= m_grid->getBlockNoCells(i, dim) + 1;
1746 totalGridBlockDim[i][dim] = m_grid->getBlockNoCells(i, dim) + 1; // number of points in the grid File
1747 }
1748 totalGridBlockCells[i] = temp;
1749 if(temp != 1) totalGridCells += temp;
1750 }
1751
1752 MInt countNode = 0;
1753 for(MInt i = 0; i < m_noBlocks; i++) {
1754 countNode = countNode + 2 * totalGridBlockDim[i][1] * totalGridBlockDim[i][2]
1755 + 2 * totalGridBlockDim[i][2] * (totalGridBlockDim[i][0] - 2)
1756 + 2 * (totalGridBlockDim[i][0] - 2) * (totalGridBlockDim[i][1] - 2);
1757 }
1758
1759 MFloatScratchSpace coordinates(3, countNode, AT_, "coordinates");
1760 coordinates.fill(-1.01010101);
1761 std::vector<pointType<nDim>> nodeMap;
1762 nodeMap.resize(countNode);
1763
1764
1765 // auxiliary lambda functions to determine BC of interface points
1766 const MInt converter[] = {2, 1, 0};
1767 auto getCurrentWindow = [this, converter](const MInt blockId, const MInt* const offset_, const MInt* const size_) {
1768 std::vector<MInt> currentWindows;
1769 for(MInt windowId = 0; windowId < noInputWindowInformation; ++windowId) {
1770 if(inputWindows[windowId]->blockId != blockId) continue;
1771 if(inputWindows[windowId]->BC < 6000 || inputWindows[windowId]->BC >= 6010) continue;
1772 // Besides the windows of the same face, windows of adjacent faces are also candidates for the corner points
1773 MBool takeIt = true;
1774 for(MInt dim = 0; dim < nDim; ++dim) {
1775 if(inputWindows[windowId]->startindex[dim] >= offset_[converter[dim]] + size_[converter[dim]]
1776 || inputWindows[windowId]->endindex[dim] < offset_[converter[dim]]) {
1777 takeIt = false;
1778 break;
1779 }
1780 }
1781 if(takeIt) currentWindows.push_back(windowId);
1782 }
1783 return currentWindows;
1784 };
1785 std::vector<MInt> pointsFoundPerWindow(noInputWindowInformation); // for detailed output
1786 auto getBCFromWindow = [this, &pointsFoundPerWindow](const MInt idx[nDim],
1787 const std::vector<MInt>& currentWindows) {
1788 std::vector<MInt> BCset; // CHANGE_SET
1789 // Use set in order to have a unique list
1790 // std::set<MInt> BCset;
1791 // MInt BC[3] = {0, 0, 0}; //we can have at most 3 different BCs shared by one point
1792 // MInt cnt = 0;
1793 for(auto windowId : currentWindows) {
1794 MBool takeIt = true;
1795 for(MInt dim = 0; dim < nDim; ++dim) {
1796 if(inputWindows[windowId]->startindex[dim] > idx[dim] || inputWindows[windowId]->endindex[dim] < idx[dim]) {
1797 takeIt = false;
1798 break;
1799 }
1800 }
1801 if(takeIt) {
1802 ++pointsFoundPerWindow[windowId];
1803 BCset.push_back(inputWindows[windowId]->BC); // CHANGE_SET
1804 // BCset.insert(inputWindows[windowId]->BC);
1805 // BC[cnt++] = inputWindows[windowId]->BC;
1806 }
1807 }
1808 // if (cnt>3) mTerm(1, "");
1809 // if (cnt>0) return MAX3(BC[0], BC[1], BC[2]); //higher BC has higher priority; in future think of something
1810 // more sophisticated return 6000; //default //-1;
1811 // we can have at most 3 different BCs shared by one point
1812 if(BCset.size() > 3) mTerm(1, "");
1813 if(BCset.size() == 0) BCset.push_back(6000); // BCset.insert(6000); //CHANGE_SET
1814 MInt BC[3] = {0, 0, 0};
1815 MInt cnt = 0;
1816 for(auto it = BCset.begin(); it != BCset.end(); ++it)
1817 BC[cnt++] = *it;
1818 return std::tuple<MInt, MInt, MInt>(BC[0], BC[1], BC[2]);
1819 };
1820
1821 MInt memsize = 0;
1822 // domain 0 reads the coordinates for all 6 sides of all blocks
1823 if(domainId() == 0) {
1824 cout << "Reading in all coordinates of all block faces" << endl;
1825 }
1826
1827 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
1828
1829 for(MInt i = 0; i < m_noBlocks; ++i) {
1830 MString bName = "/block";
1831 stringstream number;
1832 number << i << "/";
1833 bName += number.str();
1834
1835 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
1836 ParallelIo::size_type ioSize[3] = {0, 0, 0};
1837 // in grid file 2:i 1:j 0:k
1841 // face +x face 1
1842
1843 if(m_domainId == 0) {
1844 ioOffset[2] = 0;
1845 ioSize[2] = 1; // i
1846 ioOffset[1] = 0;
1847 ioSize[1] = m_grid->getBlockNoCells(i, 1) + 1; // j
1848 ioOffset[0] = 0;
1849 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // k
1850
1851 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
1852 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
1853 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
1854 } else {
1855 ioOffset[2] = 0;
1856 ioSize[2] = 0; // i
1857 ioOffset[1] = 0;
1858 ioSize[1] = 0; // j
1859 ioOffset[0] = 0;
1860 ioSize[0] = 0; // k
1861
1862 MFloat empty = 0;
1863 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
1864 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
1865 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
1866 }
1867 for(int dim = 0; dim < 3; ++dim) {
1868 offset[dim] = ioOffset[dim];
1869 size[dim] = ioSize[dim];
1870 }
1871
1872 std::vector<MInt> currentWindows = getCurrentWindow(i, offset, size);
1873
1874 // write all computational coordinates
1875 // of the face to nodeMap object
1876 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
1877 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
1878 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
1879 nodeMap[count].blockId = i;
1880 nodeMap[count].pos[0] = a;
1881 nodeMap[count].pos[1] = b;
1882 nodeMap[count].pos[2] = c;
1883 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
1884 getBCFromWindow(nodeMap[count].pos, currentWindows);
1885 count++;
1886 }
1887 }
1888 }
1889 memsize += size[0] * size[1] * size[2];
1890
1894 // face -x face 2
1895 if(m_domainId == 0) {
1896 ioOffset[2] = m_grid->getBlockNoCells(i, 2);
1897 ioSize[2] = 1; // i
1898 ioOffset[1] = 0;
1899 ioSize[1] = m_grid->getBlockNoCells(i, 1) + 1; // j
1900 ioOffset[0] = 0;
1901 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // k
1902 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
1903 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
1904 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
1905 } else {
1906 ioOffset[2] = 0;
1907 ioSize[2] = 0; // i
1908 ioOffset[1] = 0;
1909 ioSize[1] = 0; // j
1910 ioOffset[0] = 0;
1911 ioSize[0] = 0; // k
1912 MFloat empty = 0;
1913 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
1914 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
1915 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
1916 }
1917 for(int dim = 0; dim < 3; ++dim) {
1918 offset[dim] = ioOffset[dim];
1919 size[dim] = ioSize[dim];
1920 }
1921
1922 currentWindows = getCurrentWindow(i, offset, size);
1923
1924 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
1925 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
1926 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
1927 nodeMap[count].blockId = i;
1928 nodeMap[count].pos[0] = a;
1929 nodeMap[count].pos[1] = b;
1930 nodeMap[count].pos[2] = c;
1931 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
1932 getBCFromWindow(nodeMap[count].pos, currentWindows);
1933 count++;
1934 }
1935 }
1936 }
1937 memsize += size[0] * size[1] * size[2];
1938
1942 // face +y face 3
1943 if(m_domainId == 0) {
1944 ioOffset[2] = 1;
1945 ioSize[2] = m_grid->getBlockNoCells(i, 2) - 1; // i
1946 ioOffset[1] = 0;
1947 ioSize[1] = 1; // j
1948 ioOffset[0] = 0;
1949 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // k
1950 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
1951 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
1952 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
1953 } else {
1954 ioOffset[2] = 0;
1955 ioSize[2] = 0; // i
1956 ioOffset[1] = 0;
1957 ioSize[1] = 0; // j
1958 ioOffset[0] = 0;
1959 ioSize[0] = 0; // k
1960 MFloat empty = 0;
1961 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
1962 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
1963 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
1964 }
1965 for(int dim = 0; dim < 3; ++dim) {
1966 offset[dim] = ioOffset[dim];
1967 size[dim] = ioSize[dim];
1968 }
1969
1970 currentWindows = getCurrentWindow(i, offset, size);
1971
1972 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
1973 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
1974 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
1975 nodeMap[count].blockId = i;
1976 nodeMap[count].pos[0] = a;
1977 nodeMap[count].pos[1] = b;
1978 nodeMap[count].pos[2] = c;
1979 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
1980 getBCFromWindow(nodeMap[count].pos, currentWindows);
1981 count++;
1982 }
1983 }
1984 }
1985 memsize += size[0] * size[1] * size[2];
1986
1990 // face -y face 4
1991 if(m_domainId == 0) {
1992 ioOffset[2] = 1;
1993 ioSize[2] = m_grid->getBlockNoCells(i, 2) - 1; // i
1994 ioOffset[1] = m_grid->getBlockNoCells(i, 1);
1995 ioSize[1] = 1; // j
1996 ioOffset[0] = 0;
1997 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // k
1998 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
1999 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
2000 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
2001 } else {
2002 ioOffset[2] = 0;
2003 ioSize[2] = 0; // i
2004 ioOffset[1] = 0;
2005 ioSize[1] = 0; // j
2006 ioOffset[0] = 0;
2007 ioSize[0] = 0; // k
2008 MFloat empty = 0;
2009 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
2010 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
2011 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
2012 }
2013 for(int dim = 0; dim < 3; ++dim) {
2014 offset[dim] = ioOffset[dim];
2015 size[dim] = ioSize[dim];
2016 }
2017
2018 currentWindows = getCurrentWindow(i, offset, size);
2019
2020 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
2021 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
2022 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
2023 nodeMap[count].blockId = i;
2024 nodeMap[count].pos[0] = a;
2025 nodeMap[count].pos[1] = b;
2026 nodeMap[count].pos[2] = c;
2027 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
2028 getBCFromWindow(nodeMap[count].pos, currentWindows);
2029 count++;
2030 }
2031 }
2032 }
2033 memsize += size[0] * size[1] * size[2];
2034
2038 // face +z face 5
2039 if(m_domainId == 0) {
2040 ioOffset[2] = 1;
2041 ioSize[2] = m_grid->getBlockNoCells(i, 2) - 1; // i
2042 ioOffset[1] = 1;
2043 ioSize[1] = m_grid->getBlockNoCells(i, 1) - 1; // j
2044 ioOffset[0] = 0;
2045 ioSize[0] = 1; // k
2046 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
2047 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
2048 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
2049 } else {
2050 ioOffset[2] = 0;
2051 ioSize[2] = 0; // i
2052 ioOffset[1] = 0;
2053 ioSize[1] = 0; // j
2054 ioOffset[0] = 0;
2055 ioSize[0] = 0; // k
2056 MFloat empty = 0;
2057 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
2058 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
2059 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
2060 }
2061 for(int dim = 0; dim < 3; ++dim) {
2062 offset[dim] = ioOffset[dim];
2063 size[dim] = ioSize[dim];
2064 }
2065
2066 currentWindows = getCurrentWindow(i, offset, size);
2067
2068 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
2069 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
2070 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
2071 nodeMap[count].blockId = i;
2072 nodeMap[count].pos[0] = a;
2073 nodeMap[count].pos[1] = b;
2074 nodeMap[count].pos[2] = c;
2075 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
2076 getBCFromWindow(nodeMap[count].pos, currentWindows);
2077 count++;
2078 }
2079 }
2080 }
2081 memsize += size[0] * size[1] * size[2];
2082
2086 // face -z face 6
2087 if(m_domainId == 0) {
2088 ioOffset[2] = 1;
2089 ioSize[2] = m_grid->getBlockNoCells(i, 2) - 1; // i
2090 ioOffset[1] = 1;
2091 ioSize[1] = m_grid->getBlockNoCells(i, 1) - 1; // j
2092 ioOffset[0] = m_grid->getBlockNoCells(i, 0);
2093 ioSize[0] = 1; // k
2094 pio.readArray(&coordinates(0, memsize), bName, "x", 3, ioOffset, ioSize);
2095 pio.readArray(&coordinates(1, memsize), bName, "y", 3, ioOffset, ioSize);
2096 pio.readArray(&coordinates(2, memsize), bName, "z", 3, ioOffset, ioSize);
2097 } else {
2098 ioOffset[2] = 0;
2099 ioSize[2] = 0; // i
2100 ioOffset[1] = 0;
2101 ioSize[1] = 0; // j
2102 ioOffset[0] = 0;
2103 ioSize[0] = 0; // k
2104 MFloat empty = 0;
2105 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
2106 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
2107 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
2108 }
2109 for(int dim = 0; dim < 3; ++dim) {
2110 offset[dim] = ioOffset[dim];
2111 size[dim] = ioSize[dim];
2112 }
2113
2114 currentWindows = getCurrentWindow(i, offset, size);
2115
2116 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
2117 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
2118 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
2119 nodeMap[count].blockId = i;
2120 nodeMap[count].pos[0] = a;
2121 nodeMap[count].pos[1] = b;
2122 nodeMap[count].pos[2] = c;
2123 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1], nodeMap[count].BC[2]) =
2124 getBCFromWindow(nodeMap[count].pos, currentWindows);
2125 count++;
2126 }
2127 }
2128 }
2129 memsize += size[0] * size[1] * size[2];
2130 }
2131
2132 // Sanity check
2133 for(MInt windowId = 0; windowId < noInputWindowInformation; ++windowId) {
2134 if(inputWindows[windowId]->BC < 6000 || inputWindows[windowId]->BC >= 6010) continue;
2135 MInt noWindowPoints = 1;
2136 for(MInt dim = 0; dim < nDim; ++dim) {
2137 noWindowPoints *= inputWindows[windowId]->endindex[dim] - inputWindows[windowId]->startindex[dim];
2138 }
2139 // Every point should be found at least once
2140 if(noWindowPoints > pointsFoundPerWindow[windowId]) mTerm(1, "noWindowPOints > pointsFoundPerWindow");
2141 }
2142
2143 // now broadcast the surface coordinates to every processor
2144 MPI_Bcast(&count, 1, MPI_INT, 0, m_StructuredComm, AT_, "count");
2145 MPI_Bcast(&memsize, 1, MPI_INT, 0, m_StructuredComm, AT_, "memsize");
2146 MPI_Bcast(&coordinates(0, 0), memsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "coordinates(0");
2147 MPI_Bcast(&coordinates(1, 0), memsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "coordinates(1");
2148 MPI_Bcast(&coordinates(2, 0), memsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "coordinates(2");
2149
2150 // also broadcast the nodeMap to every processor
2151 MPI_Datatype matrix;
2152 MPI_Type_contiguous(2 + 2 * nDim, MPI_INT, &matrix, AT_);
2153 MPI_Type_commit(&matrix, AT_);
2154 MPI_Bcast(nodeMap.data(), memsize, matrix, 0, m_StructuredComm, AT_, "nodeMap");
2155
2159 if(domainId() == 0) {
2160 cout << "Building up connections for multiblock connection search" << endl;
2161 }
2162 vector<Point<3>> pts;
2163 for(MInt j = 0; j < count; ++j) {
2164 Point<3> a(coordinates(0, j), coordinates(1, j), coordinates(2, j));
2165 pts.push_back(a);
2166 nodeMap[j].found = false;
2167 }
2168
2169 MFloat m_gridEps = 0.0000001;
2170
2171 KDtree<3> tree(pts);
2172 MBool add;
2173 MInt numConnections = 0, numSingularConnections = 0, nfound, tempnum = 0, tempcount;
2174 MInt results[10];
2175 for(MInt i = 0; i < count; ++i) {
2176 if(!nodeMap[i].found) {
2177 Point<3> a(coordinates(0, i), coordinates(1, i), coordinates(2, i));
2178 nfound = tree.locatenear(a, m_gridEps, results, 10, false); // 0.00001
2179 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2180 for(MInt countNode3 = countNode2 + 1; countNode3 < nfound; ++countNode3) {
2181 MBool check = false;
2182 for(MInt bc2 = 0; bc2 < nDim; ++bc2) {
2183 if(nodeMap[results[countNode2]].BC[bc2] == 0) break;
2184 for(MInt bc3 = 0; bc3 < nDim; ++bc3) {
2185 if(nodeMap[results[countNode2]].BC[bc2] == nodeMap[results[countNode3]].BC[bc3]) {
2186 check = true;
2187 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2188 if(addConnection(
2189 nodeMap[results[countNode2]].BC[bc2], // Does this make sense? Check! //6000, //6000er-change
2190 nodeMap[results[countNode2]].blockId,
2191 nodeMap[results[countNode2]].pos,
2192 nodeMap[results[countNode3]].blockId,
2193 nodeMap[results[countNode3]].pos)) {
2194 numConnections = numConnections + 1;
2195 }
2196 }
2197 }
2198 }
2199 if(!check) {
2200 cout << "DANGER: x|y|z=" << coordinates(0, i) << "|" << coordinates(1, i) << "|" << coordinates(2, i)
2201 << " nodeMap2: inpuBlockId=" << nodeMap[results[countNode2]].blockId << " BC =";
2202 for(MInt d = 0; d < nDim; ++d)
2203 cout << " " << nodeMap[results[countNode2]].BC[d];
2204 cout << " nodeMap3: blockId=" << nodeMap[results[countNode3]].blockId << " BC =";
2205 for(MInt d = 0; d < nDim; ++d)
2206 cout << " " << nodeMap[results[countNode3]].BC[d];
2207 cout << endl;
2208 // mTerm(1, "");
2209 }
2210
2211 /* if (nodeMap[results[countNode2]].BC!=nodeMap[results[countNode3]].BC) {
2212 // By now the higher BC has a higher priority; Check if this makes sense
2213 nodeMap[results[countNode2]].BC = mMax(nodeMap[results[countNode2]].BC,
2214 nodeMap[results[countNode3]].BC);
2215 cout << "WARNING: 2 nodes with different BCs!!!" << endl;
2216 }
2217 //CHANGE_SET: currently addConnection will always return true, because we are now using a
2218 multiset if (addConnection( nodeMap[results[countNode2]].BC, // Does this make sense? Check! //6000,
2219 //6000er-change nodeMap[results[countNode2]].blockId, nodeMap[results[countNode2]].pos,
2220 nodeMap[results[countNode3]].blockId,
2221 nodeMap[results[countNode3]].pos)) {
2222 numConnections = numConnections + 1;
2223 }*/
2224 }
2225 nodeMap[results[countNode2]].found = true;
2226 }
2227
2228 std::set<MInt> BCs;
2229 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2230 for(MInt d = 0; d < nDim; ++d) {
2231 if(nodeMap[results[countNode2]].BC[d] != 0) {
2232 BCs.insert(nodeMap[results[countNode2]].BC[d]);
2233 }
2234 }
2235 }
2236
2237 // if three points share the same
2238 // coordinate it must be a 3-star
2239 if(nfound == 3) {
2240 add = false;
2241 tempcount = 0;
2242
2243 // check if it is a singularity 3-star or normal 3-point connection
2244 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2245 for(MInt j = 0; j < m_noBlocks; ++j) {
2246 if(nodeMap[results[countNode2]].blockId == j) {
2247 tempnum = j;
2248 break;
2249 }
2250 }
2251 for(MInt j = 0; j < 3; ++j) {
2252 // pos[]: ijk DirLast[]: kji
2253 if(nodeMap[results[countNode2]].pos[j] == 0
2254 || nodeMap[results[countNode2]].pos[j] == m_grid->getBlockNoCells(tempnum, 2 - j)) {
2255 ++tempcount;
2256 }
2257 }
2258 }
2259
2260 if(tempcount == 9 || tempcount == 6) {
2261 add = true;
2262 }
2263
2264 if(add) {
2265 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2266 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
2267 for(const auto& BC : BCs) {
2268 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2269 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
2270 nodeMap[results[countNode2]].blockId,
2271 nodeMap[results[countNode2]].pos,
2272 nodeMap[results[countNode2]].blockId,
2273 nodeMap[results[countNode2]].pos,
2274 3)) {
2275 numSingularConnections = numSingularConnections + 1;
2276 }
2277 }
2278 }
2279 }
2280 }
2281
2282 // if three points share the same
2283 // coordinate it must be a 5-star
2284 if(nfound == 5) {
2285 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2286 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
2287 for(const auto& BC : BCs) {
2288 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2289 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
2290 nodeMap[results[countNode2]].blockId,
2291 nodeMap[results[countNode2]].pos,
2292 nodeMap[results[countNode2]].blockId,
2293 nodeMap[results[countNode2]].pos,
2294 5)) {
2295 numSingularConnections = numSingularConnections + 1;
2296 }
2297 }
2298 }
2299 }
2300 // coordinate it must be a 6-star
2301 if(nfound == 6) {
2302 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2303 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
2304 for(const auto& BC : BCs) {
2305 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2306 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
2307 nodeMap[results[countNode2]].blockId,
2308 nodeMap[results[countNode2]].pos,
2309 nodeMap[results[countNode2]].blockId,
2310 nodeMap[results[countNode2]].pos,
2311 6)) {
2312 numSingularConnections = numSingularConnections + 1;
2313 }
2314 }
2315 }
2316 }
2317 }
2318 }
2319
2320
2321 MFloat tmppoint[3];
2322 MInt pcount = 0, plocation = 0, numofpoints[3];
2323
2324 for(MInt i = 0; i < noInputWindowInformation; i++) {
2325 if(inputWindows[i]->BC > 4000 && inputWindows[i]->BC < 5000) {
2326 for(MInt j = 0; j < 3; j++) {
2327 numofpoints[j] = inputWindows[i]->endindex[j] - inputWindows[i]->startindex[j] + 1;
2328 }
2329 pcount += numofpoints[0] * numofpoints[1] * numofpoints[2];
2330 }
2331 }
2332
2333 if(pcount > 0) {
2334 MFloatScratchSpace periodicCoordinates(3, pcount, AT_, "periodicCoordinates");
2335 periodicCoordinates.fill(-1.01010101);
2336 std::vector<pointType<nDim>> nodeMapP;
2337 nodeMapP.resize(pcount);
2338
2339 if(domainId() == 0) {
2340 cout << "Loading periodic face coordinates" << endl;
2341 }
2342 MInt pmemsize = 0;
2343 for(MInt i = 0; i < noInputWindowInformation; i++) {
2344 if(inputWindows[i]->BC >= 4000 && inputWindows[i]->BC < 5000) {
2345 MString bName = "/block";
2346 stringstream number;
2347 number << inputWindows[i]->blockId << "/";
2348 bName += number.str();
2349
2350 ParallelIo::size_type ioOffset[3] = {0, 0, 0};
2351 ParallelIo::size_type ioSize[3] = {0, 0, 0};
2352 if(m_domainId == 0) {
2353 for(MInt j = 0; j < 3; j++) {
2354 ioOffset[j] = inputWindows[i]->startindex[2 - j];
2355 ioSize[j] = inputWindows[i]->endindex[2 - j] - inputWindows[i]->startindex[2 - j] + 1;
2356 }
2357
2358 pio.readArray(&periodicCoordinates(0, plocation), bName, "x", 3, ioOffset, ioSize);
2359 pio.readArray(&periodicCoordinates(1, plocation), bName, "y", 3, ioOffset, ioSize);
2360 pio.readArray(&periodicCoordinates(2, plocation), bName, "z", 3, ioOffset, ioSize);
2361 } else {
2362 ioOffset[2] = 0;
2363 ioSize[2] = 0; // i
2364 ioOffset[1] = 0;
2365 ioSize[1] = 0; // j
2366 ioOffset[0] = 0;
2367 ioSize[0] = 0; // k
2368 MFloat empty = 0;
2369 pio.readArray(&empty, bName, "x", 3, ioOffset, ioSize);
2370 pio.readArray(&empty, bName, "y", 3, ioOffset, ioSize);
2371 pio.readArray(&empty, bName, "z", 3, ioOffset, ioSize);
2372 }
2373 for(int dim = 0; dim < 3; ++dim) {
2374 offset[dim] = ioOffset[dim];
2375 size[dim] = ioSize[dim];
2376 }
2377
2378
2379 for(MInt c = offset[0]; c < offset[0] + size[0]; ++c) {
2380 for(MInt b = offset[1]; b < offset[1] + size[1]; ++b) {
2381 for(MInt a = offset[2]; a < offset[2] + size[2]; ++a) {
2382 nodeMapP[plocation].BC[0] = inputWindows[i]->BC;
2383 nodeMapP[plocation].blockId = inputWindows[i]->blockId;
2384 nodeMapP[plocation].pos[0] = a;
2385 nodeMapP[plocation].pos[1] = b;
2386 nodeMapP[plocation].pos[2] = c;
2387 plocation++;
2388 }
2389 }
2390 }
2391 pmemsize += size[0] * size[1] * size[2];
2392 }
2393 }
2394
2395 MPI_Bcast(&plocation, 1, MPI_INT, 0, m_StructuredComm, AT_, "plocation");
2396 MPI_Bcast(&pmemsize, 1, MPI_INT, 0, m_StructuredComm, AT_, "pmemsize");
2397
2398 MPI_Bcast(&periodicCoordinates(0, 0), pmemsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "periodicCoordinates(0");
2399 MPI_Bcast(&periodicCoordinates(1, 0), pmemsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "periodicCoordinates(1");
2400 MPI_Bcast(&periodicCoordinates(2, 0), pmemsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "periodicCoordinates(2");
2401
2402 MPI_Bcast(nodeMapP.data(), pmemsize, matrix, 0, m_StructuredComm, AT_, "nodeMapP");
2403
2404 if(domainId() == 0) {
2405 cout << "Computing periodic window displacements" << endl;
2406 }
2407 m_log << "Computing periodic window displacements" << endl;
2411 MFloatScratchSpace periodicWindowCenter(m_noBlocks, nDim, 2 * nDim, AT_, "periodicWindowCOGS");
2412 MIntScratchSpace periodicWindowNoNodes(m_noBlocks, 2 * nDim, AT_, "periodicWindowNoNodes");
2413 cout.precision(10);
2414 periodicWindowCenter.fill(F0);
2415 periodicWindowNoNodes.fill(0);
2416
2417 // compute displacement
2418 const MInt periodicOffset = 4401;
2419 for(MInt i = 0; i < pcount; ++i) {
2420 if(nodeMapP[i].BC[0] < 4401 || nodeMapP[i].BC[0] > 4406) {
2421 continue;
2422 }
2423
2424 // add up all coordinates
2425 for(MInt dim = 0; dim < nDim; dim++) {
2426 periodicWindowCenter(nodeMapP[i].blockId, dim, nodeMapP[i].BC[0] - periodicOffset) +=
2427 periodicCoordinates(dim, i);
2428 }
2429
2430 periodicWindowNoNodes(nodeMapP[i].blockId, nodeMapP[i].BC[0] - periodicOffset) += 1;
2431 }
2432
2433 // new approach to account also for block distribution which are periodic in spanwise direction
2434 // and splited in spanwise direction
2435
2436 // 1) Compute center of the the faces and split even and odd sides
2437 multimap<MInt, pair<vector<MFloat>, MInt>> oddPeriodicSides;
2438 multimap<MInt, pair<vector<MFloat>, MInt>> evenPeriodicSides;
2439 // vector< tuple<MInt, vector<MInt>, MInt>> oddPeriodicSides;
2440 // vector< tuple<MInt, vector<MInt>, MInt>> evenPeriodicSides;
2441 // evenPeriodicSides.reserve(m_noBlocks*nDim); //per block we can only have max 3 odd sides
2442 // oddPeriodicSides.reserve(m_noBlocks*nDim); //per block we can only have mac 3 even sides
2443
2444 // now compute the center
2445 //(not weighted, should be basically the same surface in another location)
2446 // and compute distance between the two centers
2447 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
2448 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
2449 if(periodicWindowNoNodes(blockId, periodicWindowId) <= 0) { // we have no periodic cells
2450 continue;
2451 }
2452 vector<MFloat> centerDimensions(nDim);
2453 for(MInt dim = 0; dim < nDim; dim++) { // add the periodic cells
2454 periodicWindowCenter(blockId, dim, periodicWindowId) /=
2455 (MFloat)periodicWindowNoNodes(blockId, periodicWindowId);
2456 centerDimensions[dim] =
2457 periodicWindowCenter(blockId, dim,
2458 periodicWindowId); //(MFloat)periodicWindowNoNodes(blockId,periodicWindowId);
2459 cout << "periodic Window center " << periodicWindowCenter(blockId, dim, periodicWindowId) << endl;
2460 }
2461 if(periodicWindowId % 2 == 0) { // we have an even side
2462 // evenPeriodicSides.push_back(make_tuple(blockId,centerDimensions, periodicWindowId));
2463 evenPeriodicSides.insert(pair<MInt, pair<vector<MFloat>, MInt>>(
2464 blockId, pair<vector<MFloat>, MInt>(centerDimensions, periodicWindowId)));
2465 cout << "dimensions of centerDimensions (even)" << centerDimensions[0] << " " << centerDimensions[1] << " "
2466 << centerDimensions[2] << endl;
2467 } else { // we have an odd side
2468 // oddPeriodicSides.push_back(make_tuple(blockId,centerDimensions, periodicWindowId));
2469 oddPeriodicSides.insert(pair<MInt, pair<vector<MFloat>, MInt>>(
2470 blockId, pair<vector<MFloat>, MInt>(centerDimensions, periodicWindowId)));
2471 cout << "dimensions of centerDimensions (odd)" << centerDimensions[0] << " " << centerDimensions[1] << " "
2472 << centerDimensions[2] << endl;
2473 }
2474 }
2475 }
2476
2477 // 2) now set the perodic sides for the blockId
2478 // a) check for periodic sides in the same blockId
2479
2480 // get the iterator start and end of the m_block
2481 pair<multimap<MInt, pair<vector<MFloat>, MInt>>::iterator, multimap<MInt, pair<vector<MFloat>, MInt>>::iterator>
2482 evenIt;
2483 pair<multimap<MInt, pair<vector<MFloat>, MInt>>::iterator, multimap<MInt, pair<vector<MFloat>, MInt>>::iterator>
2484 oddIt;
2485
2486
2487 MFloatScratchSpace periodicDisplacementsBlockIds(m_noBlocks, nDim * nDim, AT_,
2488 "periodic Displacements per block");
2489
2490 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
2491 MInt noEvenPerodicWindowsBlockIds = evenPeriodicSides.count(blockId);
2492 MInt noOddPeriodicWindowsBlockIds = oddPeriodicSides.count(blockId);
2493 cout << "we have evenSides " << noEvenPerodicWindowsBlockIds << " and we have oddSides "
2494 << noOddPeriodicWindowsBlockIds << " in BlockId " << blockId << endl;
2495 if(noEvenPerodicWindowsBlockIds == 0) continue; // there are no periodic connections
2496 if(noOddPeriodicWindowsBlockIds == 0)
2497 continue; // there are no periodic connections associated with that blockId
2498 // else we have a interblock connection (much easier to find
2499 evenIt = evenPeriodicSides.equal_range(blockId);
2500 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator eit = evenIt.first;
2501 while(eit != evenIt.second) {
2502 MBool tobeErased = false;
2503 MInt evenSideDim =
2504 ceil(((MFloat)((*eit).second.second + 1) / 2.0) - 1); // get the dimensional direction of the side
2505 MInt evenSide = (*eit).second.second;
2506 MInt oddSide = evenSide + 1;
2507 oddIt = oddPeriodicSides.equal_range(blockId);
2508 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator oit = oddIt.first;
2509
2510 while(oit != oddIt.second) {
2511 if((*oit).second.second == oddSide) { // yes we found a corresponding odd side
2512 // compute the periodic connection and put them into the scratchspace
2513 for(MInt dim = 0; dim < nDim; dim++) {
2514 cout << "first element is " << (*oit).second.first[dim] << " and we subtract "
2515 << (*eit).second.first[dim] << endl;
2516 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim) =
2517 abs((*oit).second.first[dim] - (*eit).second.first[dim]);
2518 }
2519 oit = oddPeriodicSides.erase(oit);
2520 tobeErased = true;
2521 break;
2522 } else {
2523 oit++;
2524 }
2525 }
2526 if(tobeErased) {
2527 eit = evenPeriodicSides.erase(eit);
2528 } else {
2529 eit++;
2530 }
2531 }
2532 }
2533
2534 MFloat periodicEpsilon = 0.000001;
2535 // now the list only contains the inner blockId periodic conditions.
2536 // check for multiblock communications
2537 if(evenPeriodicSides.size() != 0
2538 && oddPeriodicSides.size() != 0) { // we did not delete everything in the side container
2539 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
2540 MInt noEvenPerodicWindowsBlockId = evenPeriodicSides.count(blockId);
2541 if(noEvenPerodicWindowsBlockId == 0) continue; // there are no periodic connections left in the even container
2542 evenIt = evenPeriodicSides.equal_range(blockId);
2543 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator eit = evenIt.first;
2544 while(eit != evenIt.second) {
2545 MBool tobeErased = false;
2546 MInt evenSideDim =
2547 ceil(((MFloat)((*eit).second.second + 1) / 2.0) - 1); // get the dimensional direction of the side
2548 // MInt evenSide = (*eit).second.second;
2549 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator oit = oddPeriodicSides.begin();
2550 while(oit != oddPeriodicSides.end()) {
2551 // check the number of conncetions which have the same cooridnates
2552 MInt equalConnectionDims = 0;
2553 for(MInt d = 0; d < nDim; d++) {
2554 if(abs((*oit).second.first[d] - (*eit).second.first[d]) < periodicEpsilon) equalConnectionDims++;
2555 }
2556 if(equalConnectionDims == 2) { // yes we found a pair belonging together
2557 for(MInt dim = 0; dim < nDim; dim++) {
2558 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim) =
2559 abs((*oit).second.first[dim] - (*eit).second.first[dim]);
2560 // now store the odd side also for multiblock communication
2561 periodicDisplacementsBlockIds((*oit).first, evenSideDim + nDim * dim) =
2562 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim);
2563 }
2564 tobeErased = true;
2565 oit = oddPeriodicSides.erase(oit);
2566 } else {
2567 oit++;
2568 }
2569 }
2570 if(tobeErased) {
2571 eit = evenPeriodicSides.erase(eit);
2572 } else {
2573 eit++;
2574 }
2575 }
2576 }
2577 }
2578
2579
2580 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
2581 if(periodicWindowId % 2 == 1) {
2582 for(MInt dim = 0; dim < nDim; dim++) {
2583 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
2584 periodicDisplacements[dim * nDim + displacementId] =
2585 periodicWindowCenter(m_blockId, dim, periodicWindowId)
2586 - periodicWindowCenter(m_blockId, dim, periodicWindowId - 1);
2587 m_log << m_blockId << " periodicWindowCenter for window: " << periodicWindowId + periodicOffset
2588 << " dim: " << dim << " displacementId: " << displacementId
2589 << " displacement: " << periodicDisplacements[dim * nDim + displacementId] << endl;
2590 }
2591 }
2592 }
2593
2594 cout << "old approach" << endl;
2595 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
2596 if(periodicWindowId % 2 == 1) {
2597 for(MInt dim = 0; dim < nDim; dim++) {
2598 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
2599 periodicDisplacements[dim * nDim + displacementId] =
2600 periodicWindowCenter(m_blockId, dim, periodicWindowId)
2601 - periodicWindowCenter(m_blockId, dim, periodicWindowId - 1);
2602 cout << "blockId = " << m_blockId
2603 << "periodicWindowCenter for window: " << periodicWindowId + periodicOffset << " dim: " << dim
2604 << " displacementId: " << displacementId
2605 << " displacement: " << periodicDisplacements[dim * nDim + displacementId] << endl;
2606 }
2607 }
2608 }
2609 cout << "new approach " << endl;
2610 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
2611 if(periodicWindowId % 2 == 1) {
2612 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
2613 for(MInt dim = 0; dim < nDim; dim++) {
2614 cout << "blockId = " << m_blockId
2615 << "periodicWindowCenter for window: " << periodicWindowId + periodicOffset << " dim: " << dim
2616 << " displacementId: " << displacementId
2617 << " displacement: " << periodicDisplacementsBlockIds(m_blockId, dim * nDim + displacementId) << endl;
2618 }
2619 }
2620 }
2621 MPI_Barrier(m_StructuredComm, AT_);
2622 if(domainId() == 0) {
2623 for(MInt b = 0; b < m_noBlocks; b++) {
2624 cout << "BlockId " << b << ": " << endl;
2625 cout << "\t";
2626 for(MInt i = 0; i < nDim * nDim; i++) {
2627 cout << periodicDisplacementsBlockIds(b, i) << " ";
2628 }
2629 cout << endl;
2630 }
2631 }
2632 MPI_Barrier(m_StructuredComm, AT_);
2633 for(MInt b = 0; b < m_noBlocks; b++) {
2634 if(b == m_blockId) {
2635 for(MInt i = 0; i < nDim * nDim; i++) {
2636 periodicDisplacements[i] = periodicDisplacementsBlockIds(b, i);
2637 }
2638 }
2639 }
2640 // mTerm(-1, AT_, "I want to terminate ");
2641
2644
2646
2647 for(MInt i = 0; i < pcount; ++i) {
2648 tmppoint[0] = periodicCoordinates(0, i);
2649 tmppoint[1] = periodicCoordinates(1, i);
2650 tmppoint[2] = periodicCoordinates(2, i);
2651 periodicPointsChange(tmppoint, nodeMapP[i].BC[0], periodicDisplacements);
2652 Point<3> aaa(tmppoint[0], tmppoint[1], tmppoint[2]);
2653 nfound = tree.locatenear(aaa, m_gridEps, results, 10, false); // 0.0001
2654 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
2655 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2656 if(addConnection(nodeMapP[i].BC[0],
2657 nodeMapP[i].blockId,
2658 nodeMapP[i].pos,
2659 nodeMap[results[countNode2]].blockId,
2660 nodeMap[results[countNode2]].pos)) {
2661 numConnections = numConnections + 1;
2662 }
2663 }
2664
2665 if(nfound == 5) {
2666 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2667 if(addConnection(nodeMapP[i].BC[0], nodeMapP[i].blockId, nodeMapP[i].pos, nodeMapP[i].blockId,
2668 nodeMapP[i].pos, 5)) {
2669 numSingularConnections = numSingularConnections + 1;
2670 }
2671 }
2672 // 6 star for periodic bc
2673 if(nfound == 6) {
2674 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
2675 if(addConnection(nodeMapP[i].BC[0], nodeMapP[i].blockId, nodeMapP[i].pos, nodeMapP[i].blockId,
2676 nodeMapP[i].pos, 6)) {
2677 numSingularConnections = numSingularConnections + 1;
2678 }
2679 }
2680 }
2681 }
2682
2683 if(domainId() == 0) {
2684 cout << "Assemble multiblock connections" << endl;
2685 }
2689 multiBlockAssembling();
2690 singularityAssembling();
2691
2692 // Delete duplicate windows
2693 deleteDuplicateWindows(window0d, window0d);
2694 deleteDuplicateWindows(window1d, window1d);
2695 deleteDuplicateWindows(window2d, window2d);
2696 deleteDuplicateWindows(window0d, window1d);
2697 deleteDuplicateWindows(window0d, window2d);
2698 deleteDuplicateWindows(window1d, window2d);
2699
2700 //
2701
2702 for(auto it = singularwindow.cbegin(); it != singularwindow.cend();) {
2703 if(singularwindow.empty()) {
2704 break;
2705 }
2706 // TODO_SS labels:FV by now don't do anything if BC is perioduc
2707 if((*it)->BC >= 4400 && (*it)->BC < 4410) continue;
2708 MInt noSameWindows = 0;
2709 (*it)->BCsingular[noSameWindows++] = (*it)->BC;
2710 (*it)->BC = 0;
2711 for(auto it2 = it + 1; it2 != singularwindow.cend();) {
2712 if(singularwindow.empty()) {
2713 break;
2714 }
2715 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
2716 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
2717 const MBool test = mapCompare11(map1, map2);
2718 if(test) {
2719 if((*it)->BCsingular[0] == (*it2)->BC || (*it)->Nstar != (*it2)->Nstar) {
2720 mTerm(1, "There is no hope anymore!");
2721 }
2722
2723 if(noSameWindows >= (*it)->Nstar) {
2724 mTerm(1, "");
2725 }
2726
2727 (*it)->BCsingular[noSameWindows++] = (*it2)->BC;
2728 singularwindow.erase(it2);
2729 } else {
2730 ++it2;
2731 }
2732 }
2733 ++it;
2734 }
2735
2736
2737 // Create global BC maps for those singularities which don't have one
2738 /* for (MInt i = 0; i < (signed)singularwindow.size(); ++i) {
2739 const auto& mymap = singularwindow[i];
2740 for (MInt bc = 0; bc < mymap->Nstar; ++bc) {
2741 if (mymap->BCsingular[bc]!=0 && mymap->BCsingular[bc]!=6000) {
2742 MBool addMap = true;
2743 for (MInt j = 0; j < (signed)globalStructuredBndryCndMaps.size(); ++j) {
2744 if (mymap->Id1==globalStructuredBndryCndMaps[j]->Id1 &&
2745 mymap->BCsingular[bc]==globalStructuredBndryCndMaps[j]->BC) { MBool addMap_temp = false; for (MInt d = 0; d <
2746 nDim; ++d) { if (globalStructuredBndryCndMaps[j]->start1[d]>mymap->start1[d] ||
2747 globalStructuredBndryCndMaps[j]->end1[d]<mymap->end1[d]) { addMap_temp = true;
2748 }
2749 }
2750 addMap = addMap_temp;
2751 if (!addMap) break;
2752 }
2753 }
2754 if (addMap) {
2755 StructuredWindowMap* windowMap=new StructuredWindowMap(nDim);
2756 MInt order[3]={0,1,2};
2757 MInt step1[3]={1,1,1};
2758 mapCreate(mymap->Id1, mymap->start1, mymap->end1, step1,
2759 -1 , NULL, NULL , NULL, order,mymap->BCsingular[bc], windowMap );
2760 windowMap->Nstar = mymap->Nstar;
2761 //add the map to the list!
2762 if (domainId()==0) {
2763 cout << "ADDDING following GlobalBCMap:" << endl;
2764 mapPrint(windowMap);
2765 }
2766 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
2767 }
2768 }
2769 }
2770 }*/
2771
2772 // StructuredWindowMap* windowMap;
2773 for(MInt i = 0; i < (MInt)window2d.size(); ++i) {
2774 // To distinguish between communication bcs and normal ones, do the following, negate the communication bcs
2775 const MInt BC = (window2d[i]->BC >= 6000 && window2d[i]->BC < 6010) ? -window2d[i]->BC : window2d[i]->BC;
2776
2777 unique_ptr<StructuredWindowMap<nDim>> windowMap1 = make_unique<StructuredWindowMap<nDim>>();
2778 mapCreate(window2d[i]->Id1, window2d[i]->start1, window2d[i]->end1, window2d[i]->step1, window2d[i]->Id2,
2779 window2d[i]->start2, window2d[i]->end2, window2d[i]->step2, window2d[i]->order, BC, windowMap1);
2780 windowMap1->Nstar = -1;
2781 windowMap1->SingularId = -1;
2782 windowMap1->dc1 = window2d[i]->dc1;
2783 windowMap1->dc2 = window2d[i]->dc2;
2784
2785 // i-surface: change sign of I; same for J and K
2786 if(windowMap1->dc1 * windowMap1->dc2 > 0) {
2787 MInt tempdim = abs(windowMap1->dc2) - 1;
2788 windowMap1->step2[tempdim] = -1;
2789 }
2790
2791 // add the map to the list!
2792 globalStructuredBndryCndMaps.push_back(std::move(windowMap1));
2793
2794
2795 if(window2d[i]->BC >= 6000 && window2d[i]->BC < 6010) { //( window2d[i]->BC==6000) { //6000er-change
2796 unique_ptr<StructuredWindowMap<nDim>> windowMap = make_unique<StructuredWindowMap<nDim>>();
2797 mapCreate(window2d[i]->Id1, window2d[i]->start1, window2d[i]->end1, window2d[i]->step1, window2d[i]->Id2,
2798 window2d[i]->start2, window2d[i]->end2, window2d[i]->step2, window2d[i]->order, BC, windowMap);
2799 windowMap->Nstar = -1;
2800 windowMap->SingularId = -1;
2801 windowMap->dc1 = window2d[i]->dc1;
2802 windowMap->dc2 = window2d[i]->dc2;
2803 // i-surface: change sign of I; same for J and K
2804 if(windowMap->dc1 * windowMap->dc2 > 0) {
2805 MInt tempdim = abs(windowMap->dc2) - 1;
2806 windowMap->step2[tempdim] = -1;
2807 }
2808
2809 mapInvert1(windowMap);
2810 mapNormalize3(windowMap);
2811 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
2812 }
2813 }
2814
2815
2816 for(MInt i = 0; i < (MInt)window1d.size(); ++i) {
2817 // To distinguish between communication bcs and normal ones, do the followin, negate the communication bcs
2818 const MInt BC = (window1d[i]->BC >= 6000 && window1d[i]->BC < 6010) ? -window1d[i]->BC : window1d[i]->BC;
2819
2820 unique_ptr<StructuredWindowMap<nDim>> windowMap1 = make_unique<StructuredWindowMap<nDim>>();
2821 mapCreate(window1d[i]->Id1, window1d[i]->start1, window1d[i]->end1, window1d[i]->step1, window1d[i]->Id2,
2822 window1d[i]->start2, window1d[i]->end2, window1d[i]->step2, window1d[i]->order, BC, windowMap1);
2823 windowMap1->Nstar = -1;
2824 windowMap1->SingularId = -1;
2825 windowMap1->dc1 = window1d[i]->dc1;
2826 windowMap1->dc2 = window1d[i]->dc2;
2827
2828 // i-surface: change sign of I; same for J and K
2829 for(MInt j = 0; j < 3; ++j) {
2830 if(windowMap1->start1[j] == windowMap1->end1[j]) {
2831 if(windowMap1->start1[j] == 0 && windowMap1->start2[windowMap1->order[j]] == 0) {
2832 windowMap1->step2[windowMap1->order[j]] = -1;
2833 }
2834 if(windowMap1->start1[j] > 0 && windowMap1->start2[windowMap1->order[j]] > 0) {
2835 windowMap1->step2[windowMap1->order[j]] = -1;
2836 }
2837 }
2838 }
2839
2840 // now for 5 star communicaitons (or ...... if needed)
2841 // 3 star does not need additional information
2842 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
2843 const MInt test = mapCompare11(windowMap1, singularwindow[j]);
2844 if(test) {
2845 windowMap1->Nstar = singularwindow[j]->Nstar;
2846 windowMap1->SingularId = singularwindow[j]->SingularId;
2847 }
2848 }
2849
2850 // add the map to the list!
2851 globalStructuredBndryCndMaps.push_back(std::move(windowMap1));
2852
2853 if(window1d[i]->BC >= 6000 && window1d[i]->BC < 6010) { //( window1d[i]->BC==6000) { //6000er-change
2854 unique_ptr<StructuredWindowMap<nDim>> windowMap = make_unique<StructuredWindowMap<nDim>>();
2855 mapCreate(window1d[i]->Id1, window1d[i]->start1, window1d[i]->end1, window1d[i]->step1, window1d[i]->Id2,
2856 window1d[i]->start2, window1d[i]->end2, window1d[i]->step2, window1d[i]->order, BC, windowMap);
2857 windowMap->Nstar = -1;
2858 windowMap->SingularId = -1;
2859 windowMap->dc1 = window1d[i]->dc1;
2860 windowMap->dc2 = window1d[i]->dc2;
2861
2862 // i-surface: change sign of I; same for J and K
2863 for(MInt j = 0; j < 3; ++j) {
2864 if(windowMap->start1[j] == windowMap->end1[j]) {
2865 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
2866 windowMap->step2[windowMap->order[j]] = -1;
2867 }
2868 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
2869 windowMap->step2[windowMap->order[j]] = -1;
2870 }
2871 }
2872 }
2873
2874 mapInvert1(windowMap);
2875 mapNormalize3(windowMap);
2876
2877 // now for 5 star communicaitons (or ...... if needed)
2878 // 3 star does not need additional information
2879 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
2880 const MInt test = mapCompare11(windowMap, singularwindow[j]);
2881 if(test) {
2882 windowMap->Nstar = singularwindow[j]->Nstar;
2883 windowMap->SingularId = singularwindow[j]->SingularId;
2884 }
2885 }
2886
2887 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
2888 }
2889 }
2890
2891
2892 for(MInt i = 0; i < (MInt)window0d.size(); ++i) {
2893 // To distinguish between communication bcs and normal ones, do the followin, negate the communication bcs
2894 const MInt BC = (window0d[i]->BC >= 6000 && window0d[i]->BC < 6010) ? -window0d[i]->BC : window0d[i]->BC;
2895
2896 // point communicaiton (rare)
2897 unique_ptr<StructuredWindowMap<nDim>> windowMap1 = make_unique<StructuredWindowMap<nDim>>();
2898 mapCreate(window0d[i]->Id1, window0d[i]->start1, window0d[i]->end1, window0d[i]->step1, window0d[i]->Id2,
2899 window0d[i]->start2, window0d[i]->end2, window0d[i]->step2, window0d[i]->order, BC, windowMap1);
2900 windowMap1->Nstar = -1;
2901 windowMap1->SingularId = -1;
2902 windowMap1->dc1 = window0d[i]->dc1;
2903 windowMap1->dc2 = window0d[i]->dc2;
2904 // i-surface: change sign of I; same for J and K
2905 for(MInt j = 0; j < 3; ++j) {
2906 if(windowMap1->start1[j] == windowMap1->end1[j]) {
2907 if(windowMap1->start1[j] == 0 && windowMap1->start2[windowMap1->order[j]] == 0) {
2908 windowMap1->step2[windowMap1->order[j]] = -1;
2909 }
2910 if(windowMap1->start1[j] > 0 && windowMap1->start2[windowMap1->order[j]] > 0) {
2911 windowMap1->step2[windowMap1->order[j]] = -1;
2912 }
2913 }
2914 }
2915
2916 // now for 5 star communicaitons (or ...... if needed)
2917 // 3 star does not need additional information
2918 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
2919 const MInt test = mapCompare11(windowMap1, singularwindow[j]);
2920 if(test) {
2921 windowMap1->Nstar = singularwindow[j]->Nstar;
2922 windowMap1->SingularId = singularwindow[j]->SingularId;
2923 }
2924 }
2925
2926 // add the map to the list!
2927 globalStructuredBndryCndMaps.push_back(std::move(windowMap1));
2928
2929 if(window0d[i]->BC >= 6000 && window0d[i]->BC < 6010) { //( window0d[i]->BC==6000) { //6000er-change
2930 unique_ptr<StructuredWindowMap<nDim>> windowMap = make_unique<StructuredWindowMap<nDim>>();
2931 mapCreate(window0d[i]->Id1, window0d[i]->start1, window0d[i]->end1, window0d[i]->step1, window0d[i]->Id2,
2932 window0d[i]->start2, window0d[i]->end2, window0d[i]->step2, window0d[i]->order, BC, windowMap);
2933 windowMap->Nstar = -1;
2934 windowMap->SingularId = -1;
2935 windowMap->dc1 = window0d[i]->dc1;
2936 windowMap->dc2 = window0d[i]->dc2;
2937
2938 // i-surface: change sign of I; same for J and K
2939 for(MInt j = 0; j < 3; ++j) {
2940 if(windowMap->start1[j] == windowMap->end1[j]) {
2941 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
2942 windowMap->step2[windowMap->order[j]] = -1;
2943 }
2944 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
2945 windowMap->step2[windowMap->order[j]] = -1;
2946 }
2947 }
2948 }
2949
2950 mapInvert1(windowMap);
2951 mapNormalize3(windowMap);
2952
2953 // now for 5 star communicaitons (or ...... if needed)
2954 // 3 star does not need additional information
2955 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
2956 const MInt test = mapCompare11(windowMap, singularwindow[j]);
2957 if(test) {
2958 windowMap->Nstar = singularwindow[j]->Nstar;
2959 windowMap->SingularId = singularwindow[j]->SingularId;
2960 }
2961 }
2962 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
2963 }
2964 }
2965
2966 // Duplicates are already deleted above. The following call should be unnecessary
2967 deleteDuplicateCommMaps();
2968
2969#ifndef NDEBUG
2970 if(domainId() == 0) {
2971 cout << "======= GLOBALSTRUCTUREDBNDRYCNDMAPS ======" << endl;
2972 for(MInt i = 0; i < (signed)globalStructuredBndryCndMaps.size(); ++i) {
2973 mapPrint(globalStructuredBndryCndMaps[i]);
2974 }
2975
2976 cout << " ======= SINGULARWINDOW =============" << endl;
2977 for(MInt i = 0; i < (signed)singularwindow.size(); ++i) {
2978 mapPrint(singularwindow[i]);
2979 }
2980
2981 cout << " ======== window0d ==============" << endl;
2982 for(MInt i = 0; i < (signed)window0d.size(); ++i) {
2983 mapPrint(window0d[i]);
2984 }
2985
2986 cout << " ======== window1d ==============" << endl;
2987 for(MInt i = 0; i < (signed)window1d.size(); ++i) {
2988 mapPrint(window1d[i]);
2989 }
2990
2991 cout << " ======== window2d ==============" << endl;
2992 for(MInt i = 0; i < (signed)window2d.size(); ++i) {
2993 mapPrint(window2d[i]);
2994 }
2995 }
2996#endif
2997
2998 if(!hasConnectionInfo) {
2999 cout << "Writing connection info" << endl;
3000 writeConnectionWindowInformation3D(periodicDisplacements);
3001 } else {
3002 if(domainId() == 0) {
3003 cout << "##########################################################################" << endl;
3004 cout << "WARNING: OLD CONNECTION INFO EXISTS, DELETE BEFORE NEW ONE CAN BE WRITTEN!" << endl;
3005 cout << "##########################################################################" << endl;
3006 }
3007 }
3008
3009 if(domainId() == 0) {
3010 cout << "Connection identification and window creation finished! NUM_SINGULAR=" << numSingularConnections << endl;
3011 }
3012 }
3013}
3014
3015
3016template <MInt nDim>
3018 MFloat angle = 0;
3019 /*
3020 case 4401 4402: first periodic direction
3021 case 4403 4404: second periodic direction
3022 case 4405 4405: third periodic direction
3023 case 4011 4012: rotation X axis clockwise and anticlockwise
3024 */
3025 MFloat rotationMatrix[3][3]{};
3026 MFloat tmp[3]{};
3027 switch(type) {
3028 case 4401:
3029 case 4403:
3030 case 4405: {
3031 const MInt displacementId = (MFloat)(type - 4400 + 1) / 2.0 - 1;
3032 for(MInt dim = 0; dim < nDim; ++dim) {
3033 pt[dim] = pt[dim] + periodicDisplacements[dim * nDim + displacementId];
3034 }
3035 break;
3036 }
3037
3038 case 4402:
3039 case 4404:
3040 case 4406: {
3041 const MInt displacementId = (MFloat)(type - 4400) / 2.0 - 1;
3042 for(MInt dim = 0; dim < nDim; ++dim) {
3043 pt[dim] = pt[dim] - periodicDisplacements[dim * nDim + displacementId];
3044 }
3045 break;
3046 }
3047
3048 case 4011: {
3049 ASSERT(nDim == 3, "");
3050 rotationMatrix[1][1] = cos(angle);
3051 rotationMatrix[1][2] = -sin(angle);
3052 rotationMatrix[2][1] = sin(angle);
3053 rotationMatrix[2][2] = cos(angle);
3054 tmp[0] = pt[0];
3055 tmp[1] = pt[1];
3056 tmp[2] = pt[2];
3057 for(MInt i = 0; i < nDim; ++i) {
3058 pt[i] = rotationMatrix[i][0] * tmp[0] + rotationMatrix[i][1] * tmp[1] + rotationMatrix[i][2] * tmp[2];
3059 }
3060 break;
3061 }
3062
3063 case 4012: {
3064 ASSERT(nDim == 3, "");
3065 rotationMatrix[1][1] = cos(-angle);
3066 rotationMatrix[1][2] = -sin(-angle);
3067 rotationMatrix[2][1] = sin(-angle);
3068 rotationMatrix[2][2] = cos(-angle);
3069 tmp[0] = pt[0];
3070 tmp[1] = pt[1];
3071 tmp[2] = pt[2];
3072 for(MInt i = 0; i < nDim; ++i) {
3073 pt[i] = rotationMatrix[i][0] * tmp[0] + rotationMatrix[i][1] * tmp[1] + rotationMatrix[i][2] * tmp[2];
3074 }
3075 break;
3076 }
3077
3078 default: {
3079 cout << "ERROR!!! periodic type is wrong!!! in windowinfoe" << endl;
3080 }
3081 }
3082}
3083
3084template <MInt nDim>
3086 // add connections for 6000 and 6000+
3087 // pair<multiset<connectionNode>::iterator,MBool> ret; //CHANGE_SET
3088
3089 if(connectiontype >= 6000 && connectiontype < 6010) { //(connectiontype==6000) { //6000er-change
3090 connectionNode a(connectiontype, b1, p1, b2, p2, true, nDim);
3091 /*ret=*/connectionset.insert(a);
3092 } else {
3093 connectionNode a(connectiontype, b1, p1, b2, p2, false, nDim);
3094 /*ret=*/connectionset.insert(a);
3095 }
3096
3097 // if(ret.second==false) { //CHANGE_SET
3098 // cout<<"error! same connection can not be added! check the connections!"<<endl;
3099 // return false;
3100 // }
3101
3102 return true;
3103}
3104
3105template <MInt nDim>
3107 MInt Nstar) {
3108 // add special connections (3 or 5-star)
3109 // pair<multiset<connectionNode>::iterator,MBool> ret; //CHANGE_SET
3110
3111 if(connectiontype >= 6000 && connectiontype < 6010) { //(connectiontype==6000) { //6000er-change
3112 connectionNode a(connectiontype, b1, p1, b2, p2, true, nDim);
3113 a.Nstar = Nstar;
3114 /*ret=*/singularconnectionset.insert(a);
3115 } else if(connectiontype >= 4000 && connectiontype < 5000) {
3116 // periodic boundary condition only need to handle 5 star communications
3117 connectionNode a(connectiontype, b1, p1, b2, p2, false, nDim);
3118 a.Nstar = Nstar;
3119 /*ret=*/singularconnectionset.insert(a);
3120 } else {
3121 cout << "singular point on BC " << connectiontype << " is not supported!! check it!!!" << endl;
3122 exit(0);
3123 }
3124
3125 // if(ret.second==false) { //CHANGE_SET
3126 // cout<<"error! same connection can not be added! check the connections!"<<endl;
3127 // return false;
3128 // }
3129
3130 return true;
3131}
3132
3133
3134template <MInt nDim>
3136 multiset<connectionNode>::iterator it; // CHANGE_SET
3137 it = connectionset.find(a);
3138
3139 if(it != connectionset.end()) {
3140 return true;
3141 } else {
3142 return false;
3143 }
3144}
3145
3146template <MInt nDim>
3148 // connectionset.erase(a); //CHANGE_SET
3149 auto it = connectionset.find(a);
3150 connectionset.erase(it);
3151}
3152
3153template <MInt nDim>
3155 multiset<connectionNode>::iterator it; // CHANGE_SET
3156 a.Nstar = Nstar;
3157 it = singularconnectionset.find(a);
3158
3159 if(it != singularconnectionset.end()) {
3160 return true;
3161 } else {
3162 return false;
3163 }
3164}
3165
3166template <MInt nDim>
3168 a.Nstar = Nstar;
3169 // singularconnectionset.erase(a); //CHANGE_SET
3170 auto it = singularconnectionset.find(a);
3171 singularconnectionset.erase(it);
3172}
3173
3174
3175template <>
3177 constexpr MInt nDim = 2;
3178
3179 MInt hasConnectionInfo = 0;
3180 if(globalDomainId() == 0) {
3181 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
3182 MBool attributeExists = pio.hasAttribute("hasConnectionInfo", "Connectivity");
3183 if(attributeExists) {
3184 m_log << "Grid file has connection info!" << endl;
3185 pio.getAttribute(&hasConnectionInfo, "hasConnectionInfo", "Connectivity");
3186 }
3187 MPI_Bcast(&hasConnectionInfo, 1, MPI_INT, 0, m_StructuredComm, AT_, "hasConnectionInfo");
3188 } else {
3189 MPI_Bcast(&hasConnectionInfo, 1, MPI_INT, 0, m_StructuredComm, AT_, "hasConnectionInfo");
3190 }
3191
3192 MBool readInConnectionInfo = true;
3193
3194 if(!hasConnectionInfo) {
3195 readInConnectionInfo = false;
3196 } else {
3197 if(Context::propertyExists("readInConnectionInfo", m_solverId)) {
3198 readInConnectionInfo =
3199 Context::getSolverProperty<MBool>("readInConnectionInfo", solverId(), AT_, &readInConnectionInfo);
3200 }
3201 }
3202
3203 if(readInConnectionInfo) {
3204 m_log << "Connection info available, reading connection information from grid file!" << endl;
3205 readConnectionWindowInformation2D(periodicDisplacements);
3206 } else {
3207 if(domainId() == 0) {
3208 cout << "Starting grid connection info search..." << endl;
3209 }
3210
3211 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
3212 m_log << " Starting grid connection info search..." << endl;
3213 MInt offset[2], size[2], count = 0;
3214 // 3) read in the coordinates of the grid points
3215 // open file for reading the grid data
3216 pointType<nDim>* nodeMap;
3217 MInt totalGridCells = 0;
3218 MInt** totalGridBlockDim = nullptr;
3219 MInt* totalGridBlockCells = nullptr;
3220
3221 mAlloc(totalGridBlockDim, m_noBlocks, 2, "totalGridBlockDim", -1, AT_);
3222 mAlloc(totalGridBlockCells, m_noBlocks, "totalGridBlockCells", -1, AT_);
3223
3224 for(MInt i = 0; i < m_noBlocks; ++i) {
3225 MInt temp = 1;
3226 for(MInt dim = 0; dim < nDim; ++dim) {
3227 temp *= m_grid->getBlockNoCells(i, dim) + 1;
3228 totalGridBlockDim[i][dim] = m_grid->getBlockNoCells(i, dim) + 1; // number of points in the grid File
3229 }
3230 totalGridBlockCells[i] = temp;
3231 if(temp != 1) totalGridCells += temp;
3232 }
3233
3234 MInt countNode = 0;
3235 for(MInt i = 0; i < m_noBlocks; i++) {
3236 countNode = countNode + 2 * totalGridBlockDim[i][1] + 2 * totalGridBlockDim[i][0] - 2;
3237 }
3238
3239 MFloatScratchSpace coordinates(2, countNode, AT_, "coordinates");
3240 coordinates.fill(-1.01010101);
3241 nodeMap = new pointType<nDim>[countNode];
3242
3243 // auxiliary lambda functions to determine BC of interface points
3244 const MInt converter[] = {1, 0};
3245 auto getCurrentWindow = [this, converter](const MInt blockId, const MInt* const offset_, const MInt* const size_) {
3246 std::vector<MInt> currentWindows;
3247 for(MInt windowId = 0; windowId < noInputWindowInformation; ++windowId) {
3248 if(inputWindows[windowId]->blockId != blockId) continue;
3249 if(inputWindows[windowId]->BC < 6000 || inputWindows[windowId]->BC >= 6010) continue;
3250 // Besides the windows of the same face, windows of adjacent faces are also candidates for the corner points
3251 MBool takeIt = true;
3252 for(MInt dim = 0; dim < nDim; ++dim) {
3253 if(inputWindows[windowId]->startindex[dim] >= offset_[converter[dim]] + size_[converter[dim]]
3254 || inputWindows[windowId]->endindex[dim] < offset_[converter[dim]]) {
3255 takeIt = false;
3256 break;
3257 }
3258 }
3259 if(takeIt) currentWindows.push_back(std::move(windowId));
3260 }
3261 return currentWindows;
3262 };
3263 std::vector<MInt> pointsFoundPerWindow(noInputWindowInformation); // for detailed output
3264 auto getBCFromWindow = [this, &pointsFoundPerWindow](const MInt idx[nDim],
3265 const std::vector<MInt>& currentWindows) {
3266 std::vector<MInt> BCset; // CHANGE_SET
3267 // Use set in order to have a unique list
3268 // std::set<MInt> BCset;
3269 // MInt BC[2] = {0, 0}; //we can have at most 2 different BCs shared by one point
3270 // MInt cnt = 0;
3271 for(auto windowId : currentWindows) {
3272 MBool takeIt = true;
3273 for(MInt dim = 0; dim < nDim; ++dim) {
3274 if(inputWindows[windowId]->startindex[dim] > idx[dim] || inputWindows[windowId]->endindex[dim] < idx[dim]) {
3275 takeIt = false;
3276 break;
3277 }
3278 }
3279 if(takeIt) {
3280 ++pointsFoundPerWindow[windowId];
3281 // BCset.insert(inputWindows[windowId]->BC);
3282 BCset.push_back(inputWindows[windowId]->BC); // CHANGE_SET
3283 // BC[cnt++] = inputWindows[windowId]->BC;
3284 }
3285 }
3286 // if (cnt>2) mTerm(1, "");
3287 // if (cnt>0) return mMax(BC[0], BC[1]); //higher BC has higher priority; in future think of something
3288 // more sophisticated return 6000; //default //-1;
3289 // we can have at most 2 different BCs shared by one point
3290 if(BCset.size() > 2) mTerm(1, "");
3291 if(BCset.size() == 0) BCset.push_back(6000); // BCset.insert(6000); //CHANGE_SET
3292 MInt BC[2] = {0, 0};
3293 MInt cnt = 0;
3294 for(auto it = BCset.begin(); it != BCset.end(); ++it)
3295 BC[cnt++] = *it;
3296 return std::tuple<MInt, MInt>(BC[0], BC[1]);
3297 };
3298
3299 MInt memsize = 0;
3300 // domain 0 reads the coordinates for all 4 sides of all blocks
3301 if(domainId() == 0) {
3302 cout << "Reading in all coordinates of all block faces" << endl;
3303 }
3304 for(MInt i = 0; i < m_noBlocks; ++i) {
3305 MString bName = "/block";
3306 stringstream number;
3307 number << i << "/";
3308 bName += number.str();
3309
3310 ParallelIo::size_type ioOffset[2] = {0, 0};
3311 ParallelIo::size_type ioSize[2] = {0, 0};
3312 // in grid file 2:i 1:j 0:k
3316 // face +x face 1
3317 if(m_domainId == 0) {
3318 ioOffset[1] = 0;
3319 ioSize[1] = 1; // i
3320 ioOffset[0] = 0;
3321 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // j
3322
3323 cout << "offset[1]=" << ioOffset[1] << " offset[0]=" << ioOffset[0] << endl;
3324 cout << "size[1]=" << ioSize[1] << " size[0]=" << ioSize[0] << endl;
3325 pio.readArray(&coordinates(0, memsize), bName, "x", 2, ioOffset, ioSize);
3326 pio.readArray(&coordinates(1, memsize), bName, "y", 2, ioOffset, ioSize);
3327 } else {
3328 ioOffset[1] = 0;
3329 ioSize[1] = 0; // i
3330 ioOffset[0] = 0;
3331 ioSize[0] = 0; // j
3332 MFloat empty = 0;
3333 pio.readArray(&empty, bName, "x", 2, ioOffset, ioSize);
3334 pio.readArray(&empty, bName, "y", 2, ioOffset, ioSize);
3335 }
3336 for(int dim = 0; dim < nDim; ++dim) {
3337 offset[dim] = ioOffset[dim];
3338 size[dim] = ioSize[dim];
3339 }
3340
3341 std::vector<MInt> currentWindows = getCurrentWindow(i, offset, size);
3342
3343 // write all computational coordinates
3344 // of the face to nodeMap object
3345 for(MInt a = offset[1]; a < offset[1] + size[1]; ++a) {
3346 for(MInt b = offset[0]; b < offset[0] + size[0]; ++b) {
3347 nodeMap[count].blockId = i;
3348 nodeMap[count].pos[0] = a;
3349 nodeMap[count].pos[1] = b;
3350 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1]) = getBCFromWindow(nodeMap[count].pos, currentWindows);
3351 count++;
3352 }
3353 }
3354 memsize += size[0] * size[1];
3355
3359 // face -x face 2
3360 if(m_domainId == 0) {
3361 ioOffset[1] = m_grid->getBlockNoCells(i, 1);
3362 ioSize[1] = 1; // i
3363 ioOffset[0] = 0;
3364 ioSize[0] = m_grid->getBlockNoCells(i, 0) + 1; // j
3365
3366 cout << "offset[1]=" << ioOffset[1] << " offset[0]=" << ioOffset[0] << endl;
3367 cout << "size[1]=" << ioSize[1] << " size[0]=" << ioSize[0] << endl;
3368 pio.readArray(&coordinates(0, memsize), bName, "x", 2, ioOffset, ioSize);
3369 pio.readArray(&coordinates(1, memsize), bName, "y", 2, ioOffset, ioSize);
3370 } else {
3371 ioOffset[1] = 0;
3372 ioSize[1] = 0; // i
3373 ioOffset[0] = 0;
3374 ioSize[0] = 0; // j
3375 MFloat empty = 0;
3376 pio.readArray(&empty, bName, "x", 2, ioOffset, ioSize);
3377 pio.readArray(&empty, bName, "y", 2, ioOffset, ioSize);
3378 }
3379 for(int dim = 0; dim < nDim; ++dim) {
3380 offset[dim] = ioOffset[dim];
3381 size[dim] = ioSize[dim];
3382 }
3383
3384 currentWindows = getCurrentWindow(i, offset, size);
3385
3386 for(MInt a = offset[1]; a < offset[1] + size[1]; ++a) {
3387 for(MInt b = offset[0]; b < offset[0] + size[0]; ++b) {
3388 nodeMap[count].blockId = i;
3389 nodeMap[count].pos[0] = a;
3390 nodeMap[count].pos[1] = b;
3391 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1]) = getBCFromWindow(nodeMap[count].pos, currentWindows);
3392 count++;
3393 }
3394 }
3395 memsize += size[0] * size[1];
3396
3400 // face +y face 3
3401 if(m_domainId == 0) {
3402 ioOffset[1] = 1;
3403 ioSize[1] = m_grid->getBlockNoCells(i, 1) - 1; // i
3404 ioOffset[0] = 0;
3405 ioSize[0] = 1; // j
3406 pio.readArray(&coordinates(0, memsize), bName, "x", 2, ioOffset, ioSize);
3407 pio.readArray(&coordinates(1, memsize), bName, "y", 2, ioOffset, ioSize);
3408 } else {
3409 ioOffset[1] = 0;
3410 ioSize[1] = 0; // i
3411 ioOffset[0] = 0;
3412 ioSize[0] = 0; // j
3413 MFloat empty = 0;
3414 pio.readArray(&empty, bName, "x", 2, ioOffset, ioSize);
3415 pio.readArray(&empty, bName, "y", 2, ioOffset, ioSize);
3416 }
3417 for(int dim = 0; dim < nDim; ++dim) {
3418 offset[dim] = ioOffset[dim];
3419 size[dim] = ioSize[dim];
3420 }
3421
3422 currentWindows = getCurrentWindow(i, offset, size);
3423
3424 for(MInt b = offset[0]; b < offset[0] + size[0]; ++b) {
3425 for(MInt a = offset[1]; a < offset[1] + size[1]; ++a) {
3426 nodeMap[count].blockId = i;
3427 nodeMap[count].pos[0] = a;
3428 nodeMap[count].pos[1] = b;
3429 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1]) = getBCFromWindow(nodeMap[count].pos, currentWindows);
3430 count++;
3431 }
3432 }
3433 memsize += size[0] * size[1];
3434
3438 // face -y face 4
3439 if(m_domainId == 0) {
3440 ioOffset[1] = 1;
3441 ioSize[1] = m_grid->getBlockNoCells(i, 1) - 1; // i
3442 ioOffset[0] = m_grid->getBlockNoCells(i, 0);
3443 ioSize[0] = 1; // j
3444 pio.readArray(&coordinates(0, memsize), bName, "x", 2, ioOffset, ioSize);
3445 pio.readArray(&coordinates(1, memsize), bName, "y", 2, ioOffset, ioSize);
3446 } else {
3447 ioOffset[1] = 0;
3448 ioSize[1] = 0; // i
3449 ioOffset[0] = 0;
3450 ioSize[0] = 0; // j
3451 MFloat empty = 0;
3452 pio.readArray(&empty, bName, "x", 2, ioOffset, ioSize);
3453 pio.readArray(&empty, bName, "y", 2, ioOffset, ioSize);
3454 }
3455 for(int dim = 0; dim < nDim; ++dim) {
3456 offset[dim] = ioOffset[dim];
3457 size[dim] = ioSize[dim];
3458 }
3459
3460 currentWindows = getCurrentWindow(i, offset, size);
3461
3462 for(MInt b = offset[0]; b < offset[0] + size[0]; ++b) {
3463 for(MInt a = offset[1]; a < offset[1] + size[1]; ++a) {
3464 nodeMap[count].blockId = i;
3465 nodeMap[count].pos[0] = a;
3466 nodeMap[count].pos[1] = b;
3467 std::tie(nodeMap[count].BC[0], nodeMap[count].BC[1]) = getBCFromWindow(nodeMap[count].pos, currentWindows);
3468 count++;
3469 }
3470 }
3471 memsize += size[0] * size[1];
3472 }
3473
3474 // Sanity check
3475 for(MInt windowId = 0; windowId < noInputWindowInformation; ++windowId) {
3476 if(inputWindows[windowId]->BC < 6000 || inputWindows[windowId]->BC >= 6010) continue;
3477 MInt noWindowPoints = 1;
3478 for(MInt dim = 0; dim < nDim; ++dim) {
3479 noWindowPoints *= inputWindows[windowId]->endindex[dim] - inputWindows[windowId]->startindex[dim];
3480 }
3481 // Every point should be found at least once
3482 if(noWindowPoints > pointsFoundPerWindow[windowId]) mTerm(1, "noWindowPOints > pointFoundPerWindow");
3483 }
3484
3485 // now broadcast the surface coordinates to every processor
3486 MPI_Bcast(&count, 1, MPI_INT, 0, m_StructuredComm, AT_, "count");
3487 MPI_Bcast(&memsize, 1, MPI_INT, 0, m_StructuredComm, AT_, "memsize");
3488 MPI_Bcast(&coordinates(0, 0), memsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "coordinates(0");
3489 MPI_Bcast(&coordinates(1, 0), memsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "coordinates(1");
3490
3491 // also broadcast the nodeMap to every processor
3492 MPI_Datatype matrix;
3493 MPI_Type_contiguous(2 + 2 * nDim, MPI_INT, &matrix, AT_);
3494 MPI_Type_commit(&matrix, AT_);
3495 MPI_Bcast(nodeMap, memsize, matrix, 0, m_StructuredComm, AT_, "nodeMap");
3496
3497 // Periodic
3498 pointType<nDim>* nodeMapP;
3499 MFloat tmppoint[nDim];
3500 MInt pcount = 0, plocation = 0, numofpoints[nDim];
3501
3502 for(MInt i = 0; i < noInputWindowInformation; i++) {
3503 if(inputWindows[i]->BC > 4000 && inputWindows[i]->BC < 5000) {
3504 for(MInt j = 0; j < nDim; j++) {
3505 numofpoints[j] = inputWindows[i]->endindex[j] - inputWindows[i]->startindex[j] + 1;
3506 }
3507 pcount += numofpoints[0] * numofpoints[1];
3508 }
3509 }
3510
3511
3512 MFloatScratchSpace periodicCoordinates(nDim, max(1, pcount), AT_, "periodicCoordinates");
3513 periodicCoordinates.fill(-1.01010101);
3514 nodeMapP = new pointType<nDim>[pcount];
3515
3516 if(domainId() == 0) {
3517 cout << "Loading periodic face coordinates" << endl;
3518 }
3519 MInt pmemsize = 0;
3520 for(MInt i = 0; i < noInputWindowInformation; i++) {
3521 if(inputWindows[i]->BC >= 4000 && inputWindows[i]->BC < 5000) {
3522 MString bName = "/block";
3523 stringstream number;
3524 number << inputWindows[i]->blockId << "/";
3525 bName += number.str();
3526
3527 ParallelIo::size_type ioOffset[2] = {0, 0};
3528 ParallelIo::size_type ioSize[2] = {0, 0};
3529 if(domainId() == 0) {
3530 for(MInt j = 0; j < nDim; j++) {
3531 ioOffset[j] = inputWindows[i]->startindex[1 - j];
3532 ioSize[j] = inputWindows[i]->endindex[1 - j] - inputWindows[i]->startindex[1 - j] + 1;
3533 }
3534
3535 pio.readArray(&periodicCoordinates(0, plocation), bName, "x", nDim, ioOffset, ioSize);
3536 pio.readArray(&periodicCoordinates(1, plocation), bName, "y", nDim, ioOffset, ioSize);
3537 } else {
3538 ioOffset[1] = 0;
3539 ioSize[1] = 0; // i
3540 ioOffset[0] = 0;
3541 ioSize[0] = 0; // j
3542 MFloat empty = 0;
3543 pio.readArray(&empty, bName, "x", nDim, ioOffset, ioSize);
3544 pio.readArray(&empty, bName, "y", nDim, ioOffset, ioSize);
3545 }
3546
3547 for(int dim = 0; dim < nDim; ++dim) {
3548 offset[dim] = ioOffset[dim];
3549 size[dim] = ioSize[dim];
3550 }
3551
3552 for(MInt b = offset[0]; b < offset[0] + size[0]; ++b) {
3553 for(MInt a = offset[1]; a < offset[1] + size[1]; ++a) {
3554 nodeMapP[plocation].BC[0] = inputWindows[i]->BC;
3555 nodeMapP[plocation].blockId = inputWindows[i]->blockId;
3556 nodeMapP[plocation].pos[0] = a;
3557 nodeMapP[plocation].pos[1] = b;
3558 plocation++;
3559 }
3560 }
3561 pmemsize += size[0] * size[1];
3562 }
3563 }
3564
3565 MPI_Bcast(&plocation, 1, MPI_INT, 0, m_StructuredComm, AT_, "plocation");
3566 MPI_Bcast(&pmemsize, 1, MPI_INT, 0, m_StructuredComm, AT_, "pmemsize");
3567
3568 MPI_Bcast(&periodicCoordinates(0, 0), pmemsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "periodicCoordinates(0");
3569 MPI_Bcast(&periodicCoordinates(1, 0), pmemsize, MPI_DOUBLE, 0, m_StructuredComm, AT_, "periodicCoordinates(1");
3570
3571 MPI_Bcast(nodeMapP, pmemsize, matrix, 0, m_StructuredComm, AT_, "nodeMapP");
3572
3576 if(domainId() == 0) {
3577 cout << "Building up connections for multiblock connection search" << endl;
3578 }
3579 vector<Point<2>> pts;
3580 for(MInt j = 0; j < count; ++j) {
3581 Point<2> a(coordinates(0, j), coordinates(1, j));
3582 pts.push_back(a);
3583 nodeMap[j].found = false;
3584 }
3585
3586 MFloat m_gridEps = 0.0000001;
3587
3588 KDtree<2> tree(pts);
3589 MBool add;
3590 MInt numConnections = 0, numSingularConnections = 0, nfound, tempnum = 0, tempcount;
3591 MInt results[10];
3592 // results=new MInt [10];
3593 for(MInt i = 0; i < count; ++i) {
3594 if(!nodeMap[i].found) {
3595 Point<2> a(coordinates(0, i), coordinates(1, i));
3596 nfound = tree.locatenear(a, m_gridEps, results, 10, false); // 0.00001
3597 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3598 for(MInt countNode3 = countNode2 + 1; countNode3 < nfound; ++countNode3) {
3599 MBool check = false;
3600 for(MInt bc2 = 0; bc2 < nDim; ++bc2) {
3601 if(nodeMap[results[countNode2]].BC[bc2] == 0) break;
3602 for(MInt bc3 = 0; bc3 < nDim; ++bc3) {
3603 if(nodeMap[results[countNode2]].BC[bc2] == nodeMap[results[countNode3]].BC[bc3]) {
3604 check = true;
3605 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
3606 if(addConnection(
3607 nodeMap[results[countNode2]].BC[bc2], // Does this make sense? Check! //6000, //6000er-change
3608 nodeMap[results[countNode2]].blockId,
3609 nodeMap[results[countNode2]].pos,
3610 nodeMap[results[countNode3]].blockId,
3611 nodeMap[results[countNode3]].pos)) {
3612 numConnections = numConnections + 1;
3613 }
3614 }
3615 }
3616 }
3617 if(!check) {
3618 cout << "DANGER: x|y=" << coordinates(0, i) << "|" << coordinates(1, i)
3619 << " nodeMap2: blockId=" << nodeMap[results[countNode2]].blockId << " BC =";
3620 for(MInt d = 0; d < nDim; ++d)
3621 cout << " " << nodeMap[results[countNode2]].BC[d];
3622 cout << " nodeMap3: blockId=" << nodeMap[results[countNode3]].blockId << " BC =";
3623 for(MInt d = 0; d < nDim; ++d)
3624 cout << " " << nodeMap[results[countNode3]].BC[d];
3625 cout << endl;
3626 // mTerm(1, "");
3627 }
3628
3629 /* if (nodeMap[results[countNode2]].BC!=nodeMap[results[countNode3]].BC) {
3630 // By now the higher BC has a higher priority; Check if this makes sense
3631 nodeMap[results[countNode2]].BC = mMax(nodeMap[results[countNode2]].BC,
3632 nodeMap[results[countNode3]].BC);
3633 cout << "WARNING: 2 nodes with different BCs!!!" << endl;
3634 }
3635 //CHANGE_SET: currently addConnection will always return true, because we are now using a
3636 multiset if (addConnection( nodeMap[results[countNode2]].BC, // Does this make sense? Check! //6000,
3637 //6000er-change nodeMap[results[countNode2]].blockId, nodeMap[results[countNode2]].pos,
3638 nodeMap[results[countNode3]].blockId,
3639 nodeMap[results[countNode3]].pos)) {
3640 numConnections = numConnections + 1;
3641 }*/
3642 }
3643 nodeMap[results[countNode2]].found = true;
3644 }
3645
3646 // TODO_SS labels:FV,cleanup The following algorithm is better for singularity detection then the one below and
3647 // should replace
3648 // the below algorithm; it works in case the singularity is surrounded by 6000er BCs
3649 MInt Nstar = 1;
3650 std::set<MInt> BCs;
3651 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3652 for(MInt bc2 = 0; bc2 < nDim; ++bc2) {
3653 const MInt BC = nodeMap[results[countNode2]].BC[bc2];
3654 if(BC < 6000 || BC >= 6010) Nstar = 0;
3655 }
3656 }
3657 if(Nstar) {
3658 tempcount = 0;
3659 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3660 for(MInt j = 0; j < m_noBlocks; ++j) {
3661 if(nodeMap[results[countNode2]].blockId == j) {
3662 tempnum = j;
3663 break;
3664 }
3665 }
3666 for(MInt j = 0; j < nDim; ++j) {
3667 // pos[]: ijk DirLast[]: kji
3668 if(nodeMap[results[countNode2]].pos[j] == 0
3669 || nodeMap[results[countNode2]].pos[j] == m_grid->getBlockNoCells(tempnum, 1 - j)) {
3670 ++tempcount;
3671 }
3672 }
3673 }
3674 Nstar = nfound + 2 * nfound - tempcount;
3675 if(Nstar == 4) Nstar = 0;
3676 if(Nstar) {
3677 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3678 for(MInt d = 0; d < nDim; ++d) {
3679 if(nodeMap[results[countNode2]].BC[d] != 0) {
3680 BCs.insert(nodeMap[results[countNode2]].BC[d]);
3681 }
3682 }
3683 }
3684 }
3685 }
3686
3687 // if three points share the same
3688 // coordinate it must be a 3-star
3689 if(nfound == 3) {
3690 add = false;
3691 tempcount = 0;
3692
3693 // check if it is a singularity 3-star or normal 3-point connection
3694 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3695 for(MInt j = 0; j < m_noBlocks; ++j) {
3696 if(nodeMap[results[countNode2]].blockId == j) {
3697 tempnum = j;
3698 break;
3699 }
3700 }
3701 for(MInt j = 0; j < nDim; ++j) {
3702 // pos[]: ijk DirLast[]: kji
3703 if(nodeMap[results[countNode2]].pos[j] == 0
3704 || nodeMap[results[countNode2]].pos[j] == m_grid->getBlockNoCells(tempnum, 1 - j)) {
3705 ++tempcount;
3706 }
3707 }
3708 }
3709
3710 if(tempcount == 6) { //(tempcount==9||tempcount==6) {
3711 add = true;
3712 }
3713
3714 if(add) {
3715 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3716 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
3717 for(const auto& BC : BCs) {
3718 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
3719 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
3720 nodeMap[results[countNode2]].blockId,
3721 nodeMap[results[countNode2]].pos,
3722 nodeMap[results[countNode2]].blockId,
3723 nodeMap[results[countNode2]].pos,
3724 3)) {
3725 ASSERT(Nstar == 3, "");
3726 Nstar = 0;
3727 numSingularConnections = numSingularConnections + 1;
3728 }
3729 }
3730 }
3731 }
3732 }
3733
3734 // if three points share the same
3735 // coordinate it must be a 5-star
3736 if(nfound == 5) {
3737 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3738 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
3739 for(const auto& BC : BCs) {
3740 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
3741 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
3742 nodeMap[results[countNode2]].blockId,
3743 nodeMap[results[countNode2]].pos,
3744 nodeMap[results[countNode2]].blockId,
3745 nodeMap[results[countNode2]].pos,
3746 5)) {
3747 ASSERT(Nstar == 5, "");
3748 Nstar = 0;
3749 numSingularConnections = numSingularConnections + 1;
3750 }
3751 }
3752 }
3753 }
3754 // coordinate it must be a 6-star
3755 if(nfound == 6) {
3756 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
3757 if(BCs.size() > 1) cout << "CAUTION: This singular point has more than one BC!" << endl;
3758 for(const auto& BC : BCs) {
3759 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
3760 if(addConnection(BC, // nodeMap[results[countNode2]].BC[0], //6000, //6000er-change
3761 nodeMap[results[countNode2]].blockId,
3762 nodeMap[results[countNode2]].pos,
3763 nodeMap[results[countNode2]].blockId,
3764 nodeMap[results[countNode2]].pos,
3765 6)) {
3766 ASSERT(Nstar == 6, "");
3767 Nstar = 0;
3768 numSingularConnections = numSingularConnections + 1;
3769 }
3770 }
3771 }
3772 }
3773 if(Nstar != 0) {
3774 cout << "ERROR: nfound=" << nfound << " Nstar=" << Nstar << endl;
3775 // mTerm(1, "Inconsistency in singularity detection!");
3776 }
3777 }
3778 }
3779
3780 if(domainId() == 0) {
3781 cout << "Computing periodic window displacements" << endl;
3782 }
3783 m_log << "Computing periodic window displacements" << endl;
3787 MFloatScratchSpace periodicWindowCenter(m_noBlocks, nDim, 2 * nDim, AT_, "periodicWindowCOGS");
3788 MIntScratchSpace periodicWindowNoNodes(m_noBlocks, 2 * nDim, AT_, "periodicWindowNoNodes");
3789 cout.precision(10);
3790 periodicWindowCenter.fill(F0);
3791 periodicWindowNoNodes.fill(0);
3792
3793 // compute displacement
3794 const MInt periodicOffset = 4401;
3795 for(MInt i = 0; i < pcount; ++i) {
3796 if(nodeMapP[i].BC[0] < 4401 || nodeMapP[i].BC[0] > 4406) {
3797 continue;
3798 }
3799
3800 // add up all coordinates
3801 for(MInt dim = 0; dim < nDim; dim++) {
3802 periodicWindowCenter(nodeMapP[i].blockId, dim, nodeMapP[i].BC[0] - periodicOffset) +=
3803 periodicCoordinates(dim, i);
3804 }
3805
3806 periodicWindowNoNodes(nodeMapP[i].blockId, nodeMapP[i].BC[0] - periodicOffset) += 1;
3807 }
3808
3809 // new approach to account also for input block distribution which are periodic in spanwise direction
3810 // and splited in spanwise direction
3811
3812 // 1) Compute center of the the faces and split even and odd sides
3813 multimap<MInt, pair<vector<MFloat>, MInt>> oddPeriodicSides;
3814 multimap<MInt, pair<vector<MFloat>, MInt>> evenPeriodicSides;
3815 // vector< tuple<MInt, vector<MInt>, MInt>> oddPeriodicSides;
3816 // vector< tuple<MInt, vector<MInt>, MInt>> evenPeriodicSides;
3817 // evenPeriodicSides.reserve(m_noBlocks*nDim); //per block we can only have max 3 odd sides
3818 // oddPeriodicSides.reserve(m_noBlocks*nDim); //per block we can only have mac 3 even sides
3819
3820 // now compute the center
3821 //(not weighted, should be basically the same surface in another location)
3822 // and compute distance between the two centers
3823 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
3824 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
3825 if(periodicWindowNoNodes(blockId, periodicWindowId) <= 0) { // we have no periodic cells
3826 continue;
3827 }
3828 vector<MFloat> centerDimensions(nDim);
3829 for(MInt dim = 0; dim < nDim; dim++) { // add the periodic cells
3830 periodicWindowCenter(blockId, dim, periodicWindowId) /=
3831 (MFloat)periodicWindowNoNodes(blockId, periodicWindowId);
3832 centerDimensions[dim] =
3833 periodicWindowCenter(blockId, dim,
3834 periodicWindowId); //(MFloat)periodicWindowNoNodes(blockId,periodicWindowId);
3835 cout << "periodic Window center " << periodicWindowCenter(blockId, dim, periodicWindowId) << endl;
3836 }
3837 if(periodicWindowId % 2 == 0) { // we have an even side
3838 // evenPeriodicSides.push_back(make_tuple(blockId,centerDimensions, periodicWindowId));
3839 evenPeriodicSides.insert(pair<MInt, pair<vector<MFloat>, MInt>>(
3840 blockId, pair<vector<MFloat>, MInt>(centerDimensions, periodicWindowId)));
3841 cout << "dimensions of centerDimensions (even)" << centerDimensions[0] << " " << centerDimensions[1]
3842 << endl; // << " " << centerDimensions[2] << endl;
3843 } else { // we have an odd side
3844 // oddPeriodicSides.push_back(make_tuple(blockId,centerDimensions, periodicWindowId));
3845 oddPeriodicSides.insert(pair<MInt, pair<vector<MFloat>, MInt>>(
3846 blockId, pair<vector<MFloat>, MInt>(centerDimensions, periodicWindowId)));
3847 cout << "dimensions of centerDimensions (odd)" << centerDimensions[0] << " " << centerDimensions[1]
3848 << endl; //" " << centerDimensions[2] << endl;
3849 }
3850 }
3851 }
3852
3853 // 2) now set the perodic sides for the input blockId
3854 // a) check for periodic sides in the same blockId
3855
3856 // get the iterator start and end of the m_block
3857 pair<multimap<MInt, pair<vector<MFloat>, MInt>>::iterator, multimap<MInt, pair<vector<MFloat>, MInt>>::iterator>
3858 evenIt;
3859 pair<multimap<MInt, pair<vector<MFloat>, MInt>>::iterator, multimap<MInt, pair<vector<MFloat>, MInt>>::iterator>
3860 oddIt;
3861
3862
3863 MFloatScratchSpace periodicDisplacementsBlockIds(m_noBlocks, nDim * nDim, AT_, "periodic Displacements per block");
3864
3865 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
3866 MInt noEvenPerodicWindowsBlockIds = evenPeriodicSides.count(blockId);
3867 MInt noOddPeriodicWindowsBlockIds = oddPeriodicSides.count(blockId);
3868 cout << "we have evenSides " << noEvenPerodicWindowsBlockIds << " and we have oddSides "
3869 << noOddPeriodicWindowsBlockIds << " in BlockId " << blockId << endl;
3870 if(noEvenPerodicWindowsBlockIds == 0) continue; // there are no periodic connections
3871 if(noOddPeriodicWindowsBlockIds == 0) continue; // there are no periodic connections associated with that blockId
3872 // else we have a interBlock connection (much easier to find
3873 evenIt = evenPeriodicSides.equal_range(blockId);
3874 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator eit = evenIt.first;
3875 while(eit != evenIt.second) {
3876 MBool tobeErased = false;
3877 MInt evenSideDim =
3878 ceil(((MFloat)((*eit).second.second + 1) / 2.0) - 1); // get the dimensional direction of the side
3879 MInt evenSide = (*eit).second.second;
3880 MInt oddSide = evenSide + 1;
3881 oddIt = oddPeriodicSides.equal_range(blockId);
3882 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator oit = oddIt.first;
3883
3884 while(oit != oddIt.second) {
3885 if((*oit).second.second == oddSide) { // yes we found a corresponding odd side
3886 // compute the periodic connection and put them into the scratchspace
3887 for(MInt dim = 0; dim < nDim; dim++) {
3888 cout << "first element is " << (*oit).second.first[dim] << " and we subtract " << (*eit).second.first[dim]
3889 << endl;
3890 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim) =
3891 abs((*oit).second.first[dim] - (*eit).second.first[dim]);
3892 }
3893 oit = oddPeriodicSides.erase(oit);
3894 tobeErased = true;
3895 break;
3896 } else {
3897 oit++;
3898 }
3899 }
3900 if(tobeErased) {
3901 eit = evenPeriodicSides.erase(eit);
3902 } else {
3903 eit++;
3904 }
3905 }
3906 }
3907
3908 MFloat periodicEpsilon = 0.000001;
3909 // now the list only contains the inner blockId periodic conditions.
3910 // check for multiblock communications
3911 if(evenPeriodicSides.size() != 0
3912 && oddPeriodicSides.size() != 0) { // we did not delete everything in the side container
3913 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
3914 MInt noEvenPerodicWindowsBlockId = evenPeriodicSides.count(blockId);
3915 if(noEvenPerodicWindowsBlockId == 0) continue; // there are no periodic connections left in the even container
3916 evenIt = evenPeriodicSides.equal_range(blockId);
3917 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator eit = evenIt.first;
3918 while(eit != evenIt.second) {
3919 MBool tobeErased = false;
3920 MInt evenSideDim =
3921 ceil(((MFloat)((*eit).second.second + 1) / 2.0) - 1); // get the dimensional direction of the side
3922 // MInt evenSide = (*eit).second.second;
3923 multimap<MInt, pair<vector<MFloat>, MInt>>::iterator oit = oddPeriodicSides.begin();
3924 while(oit != oddPeriodicSides.end()) {
3925 // check the number of conncetions which have the same cooridnates
3926 MInt equalConnectionDims = 0;
3927 for(MInt d = 0; d < nDim; d++) {
3928 if(abs((*oit).second.first[d] - (*eit).second.first[d]) < periodicEpsilon) equalConnectionDims++;
3929 }
3930 if(equalConnectionDims == 2) { // yes we found a pair belonging together
3931 for(MInt dim = 0; dim < nDim; dim++) {
3932 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim) =
3933 abs((*oit).second.first[dim] - (*eit).second.first[dim]);
3934 // now store the odd side also for multiblock communication
3935 periodicDisplacementsBlockIds((*oit).first, evenSideDim + nDim * dim) =
3936 periodicDisplacementsBlockIds(blockId, evenSideDim + nDim * dim);
3937 }
3938 tobeErased = true;
3939 oit = oddPeriodicSides.erase(oit);
3940 } else {
3941 oit++;
3942 }
3943 }
3944 if(tobeErased) {
3945 eit = evenPeriodicSides.erase(eit);
3946 } else {
3947 eit++;
3948 }
3949 }
3950 }
3951 }
3952
3953
3954 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
3955 if(periodicWindowId % 2 == 1) {
3956 for(MInt dim = 0; dim < nDim; dim++) {
3957 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
3958 periodicDisplacements[dim * nDim + displacementId] =
3959 periodicWindowCenter(m_blockId, dim, periodicWindowId)
3960 - periodicWindowCenter(m_blockId, dim, periodicWindowId - 1);
3961 m_log << m_blockId << " periodicWindowCenter for window: " << periodicWindowId + periodicOffset
3962 << " dim: " << dim << " displacementId: " << displacementId
3963 << " displacement: " << periodicDisplacements[dim * nDim + displacementId] << endl;
3964 }
3965 }
3966 }
3967
3968 cout << "old approach" << endl;
3969 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
3970 if(periodicWindowId % 2 == 1) {
3971 for(MInt dim = 0; dim < nDim; dim++) {
3972 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
3973 periodicDisplacements[dim * nDim + displacementId] =
3974 periodicWindowCenter(m_blockId, dim, periodicWindowId)
3975 - periodicWindowCenter(m_blockId, dim, periodicWindowId - 1);
3976 cout << "blockId = " << m_blockId << "periodicWindowCenter for window: " << periodicWindowId + periodicOffset
3977 << " dim: " << dim << " displacementId: " << displacementId
3978 << " displacement: " << periodicDisplacements[dim * nDim + displacementId] << endl;
3979 }
3980 }
3981 }
3982 cout << "new approach " << endl;
3983 for(MInt periodicWindowId = 0; periodicWindowId < 2 * nDim; periodicWindowId++) {
3984 if(periodicWindowId % 2 == 1) {
3985 const MInt displacementId = (MFloat)(periodicWindowId + 1) / 2.0 - 1;
3986 for(MInt dim = 0; dim < nDim; dim++) {
3987 cout << "blockId = " << m_blockId << "periodicWindowCenter for window: " << periodicWindowId + periodicOffset
3988 << " dim: " << dim << " displacementId: " << displacementId
3989 << " displacement: " << periodicDisplacementsBlockIds(m_blockId, dim * nDim + displacementId) << endl;
3990 }
3991 }
3992 }
3993 MPI_Barrier(m_StructuredComm, AT_);
3994 if(domainId() == 0) {
3995 for(MInt b = 0; b < m_noBlocks; b++) {
3996 cout << "BlockId " << b << ": " << endl;
3997 cout << "\t";
3998 for(MInt i = 0; i < nDim * nDim; i++) {
3999 cout << periodicDisplacementsBlockIds(b, i) << " ";
4000 }
4001 cout << endl;
4002 }
4003 }
4004 MPI_Barrier(m_StructuredComm, AT_);
4005 for(MInt b = 0; b < m_noBlocks; b++) {
4006 if(b == m_blockId) {
4007 for(MInt i = 0; i < nDim * nDim; i++) {
4008 periodicDisplacements[i] = periodicDisplacementsBlockIds(b, i);
4009 }
4010 }
4011 }
4012 // mTerm(-1, AT_, "I want to terminate ");
4013
4016
4018
4019 for(MInt i = 0; i < pcount; ++i) {
4020 tmppoint[0] = periodicCoordinates(0, i);
4021 tmppoint[1] = periodicCoordinates(1, i);
4022 periodicPointsChange(tmppoint, nodeMapP[i].BC[0], periodicDisplacements);
4023 Point<2> aaa(tmppoint[0], tmppoint[1]);
4024 nfound = tree.locatenear(aaa, m_gridEps, results, 10, false); // 0.0001
4025 for(MInt countNode2 = 0; countNode2 < nfound; ++countNode2) {
4026 // CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
4027 if(addConnection(nodeMapP[i].BC[0],
4028 nodeMapP[i].blockId,
4029 nodeMapP[i].pos,
4030 nodeMap[results[countNode2]].blockId,
4031 nodeMap[results[countNode2]].pos)) {
4032 numConnections = numConnections + 1;
4033 }
4034 }
4035
4036 /*
4037 if(nfound==5) {
4038 //CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
4039 if (addConnection( nodeMapP[i].BC[0],
4040 nodeMapP[i].blockId,
4041 nodeMapP[i].pos,
4042 nodeMapP[i].blockId,
4043 nodeMapP[i].pos,
4044 5)) {
4045 numSingularConnections = numSingularConnections + 1;
4046 }
4047 }
4048 //6 star for periodic bc
4049 if(nfound==6) {
4050 //CHANGE_SET: currently addConnection will always return true, because we are now using a multiset
4051 if (addConnection( nodeMapP[i].BC[0],
4052 nodeMapP[i].blockId,
4053 nodeMapP[i].pos,
4054 nodeMapP[i].blockId,
4055 nodeMapP[i].pos,
4056 6)) {
4057 numSingularConnections = numSingularConnections + 1;
4058 }
4059 }*/
4060 }
4061
4062
4063 if(domainId() == 0) {
4064 cout << "Assemble multiblock connections" << endl;
4065 }
4069 multiBlockAssembling();
4070 singularityAssembling();
4071
4072 // Delete duplicate windows
4073 deleteDuplicateWindows(window0d, window0d);
4074 deleteDuplicateWindows(window1d, window1d);
4075 deleteDuplicateWindows(window0d, window1d);
4076
4077 for(auto it = singularwindow.cbegin(); it != singularwindow.cend(); ++it) {
4078 // TODO_SS labels:FV by now don't do anything if BC is perioduc
4079 if((*it)->BC >= 4400 && (*it)->BC < 4410) continue;
4080 MInt noSameWindows = 0;
4081 (*it)->BCsingular[noSameWindows++] = (*it)->BC;
4082 (*it)->BC = 0;
4083 for(auto it2 = it + 1; it2 != singularwindow.cend();) {
4084 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4085 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4086 const MBool test = mapCompare11(map1, map2);
4087 if(test) {
4088 if((*it)->BCsingular[0] == (*it2)->BC || (*it)->Nstar != (*it2)->Nstar) {
4089 mTerm(1, "There is no hope anymore!");
4090 }
4091
4092 if(noSameWindows >= (*it)->Nstar) {
4093 mTerm(1, "");
4094 }
4095
4096 (*it)->BCsingular[noSameWindows++] = (*it2)->BC;
4097 singularwindow.erase(it2);
4098 } else {
4099 ++it2;
4100 }
4101 }
4102 }
4103
4104
4105 // Create global BC maps for those singularities which don't have one
4106 /* for (MInt i = 0; i < (signed)singularwindow.size(); ++i) {
4107 const auto& mymap = singularwindow[i];
4108 for (MInt bc = 0; bc < mymap->Nstar; ++bc) {
4109 if (mymap->BCsingular[bc]!=0 && mymap->BCsingular[bc]!=6000) {
4110 MBool addMap = true;
4111 for (MInt j = 0; j < (signed)globalStructuredBndryCndMaps.size(); ++j) {
4112 if (mymap->Id1==globalStructuredBndryCndMaps[j]->Id1 &&
4113 mymap->BCsingular[bc]==globalStructuredBndryCndMaps[j]->BC) { MBool addMap_temp = false; for (MInt d = 0; d <
4114 nDim; ++d) { if (globalStructuredBndryCndMaps[j]->start1[d]>mymap->start1[d] ||
4115 globalStructuredBndryCndMaps[j]->end1[d]<mymap->end1[d]) { addMap_temp = true;
4116 }
4117 }
4118 addMap = addMap_temp;
4119 if (!addMap) break;
4120 }
4121 }
4122 if (addMap) {
4123 StructuredWindowMap* windowMap=new StructuredWindowMap(nDim);
4124 MInt order[3]={0,1,2};
4125 MInt step1[3]={1,1,1};
4126 mapCreate(mymap->Id1, mymap->start1, mymap->end1, step1,
4127 -1 , NULL, NULL , NULL, order,mymap->BCsingular[bc], windowMap );
4128 windowMap->Nstar = mymap->Nstar;
4129 //add the map to the list!
4130 if (domainId()==0) {
4131 cout << "ADDDING following GlobalBCMap:" << endl;
4132 mapPrint(windowMap);
4133 }
4134 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4135 }
4136 }
4137 }
4138 }*/
4139
4140 unique_ptr<StructuredWindowMap<nDim>> windowMap;
4141 // TODO_SS labels:FV in 2D impossible
4142 /* for(MInt i=0;i<(MInt)window2d.size();++i) {
4143
4144 // To distinguish between communication bcs and normal ones, do the following, negate the communication bcs
4145 const MInt BC = (window2d[i]->BC>=6000 && window2d[i]->BC<6010) ? -window2d[i]->BC : window2d[i]->BC;
4146
4147 windowMap=new StructuredWindowMap(nDim);
4148 mapCreate(window2d[i]->Id1, window2d[i]->start1, window2d[i]->end1, window2d[i]->step1,
4149 window2d[i]->Id2, window2d[i]->start2, window2d[i]->end2, window2d[i]->step2,
4150 window2d[i]->order, BC, windowMap);
4151 windowMap->Nstar=-1;windowMap->SingularId=-1;
4152 windowMap->dc1=window2d[i]->dc1;
4153 windowMap->dc2=window2d[i]->dc2;
4154
4155 //i-surface: change sign of I; same for J and K
4156 if(windowMap->dc1*windowMap->dc2>0) {
4157 MInt tempdim=abs(windowMap->dc2)-1;
4158 windowMap->step2[tempdim]=-1;
4159 }
4160
4161 //add the map to the list!
4162 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4163
4164
4165 if (window2d[i]->BC>=6000 && window2d[i]->BC<6010) { //( window2d[i]->BC==6000) { //6000er-change
4166 windowMap=new StructuredWindowMap(nDim);
4167 mapCreate(window2d[i]->Id1, window2d[i]->start1, window2d[i]->end1, window2d[i]->step1,
4168 window2d[i]->Id2, window2d[i]->start2, window2d[i]->end2 ,window2d[i]->step2,
4169 window2d[i]->order, BC, windowMap);
4170 windowMap->Nstar=-1;windowMap->SingularId=-1;
4171 windowMap->dc1=window2d[i]->dc1;
4172 windowMap->dc2=window2d[i]->dc2;
4173 //i-surface: change sign of I; same for J and K
4174 if(windowMap->dc1*windowMap->dc2>0) {
4175 MInt tempdim=abs(windowMap->dc2)-1;
4176 windowMap->step2[tempdim]=-1;
4177 }
4178
4179 mapInvert1(windowMap);
4180 mapNormalize3(windowMap);
4181 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4182 }
4183 }*/
4184
4185
4186 for(MInt i = 0; i < (MInt)window1d.size(); ++i) {
4187 // To distinguish between communication bcs and normal ones, do the following, negate the communication bcs
4188 const MInt BC = (window1d[i]->BC >= 6000 && window1d[i]->BC < 6010) ? -window1d[i]->BC : window1d[i]->BC;
4189
4190 windowMap = make_unique<StructuredWindowMap<nDim>>();
4191 mapCreate(window1d[i]->Id1, window1d[i]->start1, window1d[i]->end1, window1d[i]->step1, window1d[i]->Id2,
4192 window1d[i]->start2, window1d[i]->end2, window1d[i]->step2, window1d[i]->order, BC, windowMap);
4193 windowMap->Nstar = -1;
4194 windowMap->SingularId = -1;
4195 windowMap->dc1 = window1d[i]->dc1;
4196 windowMap->dc2 = window1d[i]->dc2;
4197
4198 // i-surface: change sign of I; same for J and K
4199 for(MInt j = 0; j < nDim; ++j) {
4200 if(windowMap->start1[j] == windowMap->end1[j]) {
4201 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
4202 windowMap->step2[windowMap->order[j]] = -1;
4203 }
4204 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
4205 windowMap->step2[windowMap->order[j]] = -1;
4206 }
4207 }
4208 }
4209
4210 // now for 5 star communicaitons (or ...... if needed)
4211 // 3 star does not need additional information
4212 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
4213 const MBool test = mapCompare11(windowMap, singularwindow[j]);
4214 if(test) {
4215 mTerm(1, "Impossible behaviour!");
4216 windowMap->Nstar = singularwindow[j]->Nstar;
4217 windowMap->SingularId = singularwindow[j]->SingularId;
4218 }
4219 }
4220
4221 // add the map to the list!
4222 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4223
4224 if(window1d[i]->BC >= 6000 && window1d[i]->BC < 6010) { //( window1d[i]->BC==6000) { //6000er-change
4225 windowMap = make_unique<StructuredWindowMap<nDim>>();
4226 mapCreate(window1d[i]->Id1, window1d[i]->start1, window1d[i]->end1, window1d[i]->step1, window1d[i]->Id2,
4227 window1d[i]->start2, window1d[i]->end2, window1d[i]->step2, window1d[i]->order, BC, windowMap);
4228 windowMap->Nstar = -1;
4229 windowMap->SingularId = -1;
4230 windowMap->dc1 = window1d[i]->dc1;
4231 windowMap->dc2 = window1d[i]->dc2;
4232
4233 // i-surface: change sign of I; same for J and K
4234 for(MInt j = 0; j < nDim; ++j) {
4235 if(windowMap->start1[j] == windowMap->end1[j]) {
4236 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
4237 windowMap->step2[windowMap->order[j]] = -1;
4238 }
4239 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
4240 windowMap->step2[windowMap->order[j]] = -1;
4241 }
4242 }
4243 }
4244
4245 mapInvert1(windowMap);
4246 mapNormalize3(windowMap);
4247
4248 // now for 5 star communicaitons (or ...... if needed)
4249 // 3 star does not need additional information
4250 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
4251 const MBool test = mapCompare11(windowMap, singularwindow[j]);
4252 if(test) {
4253 mTerm(1, "Impossible behaviour!");
4254 windowMap->Nstar = singularwindow[j]->Nstar;
4255 windowMap->SingularId = singularwindow[j]->SingularId;
4256 }
4257 }
4258
4259 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4260 }
4261 }
4262
4263
4264 for(MInt i = 0; i < (MInt)window0d.size(); ++i) {
4265 // To distinguish between communication bcs and normal ones, do the following, negate the communication bcs
4266 const MInt BC = (window0d[i]->BC >= 6000 && window0d[i]->BC < 6010) ? -window0d[i]->BC : window0d[i]->BC;
4267
4268 // point communicaiton (rare)
4269 windowMap = make_unique<StructuredWindowMap<nDim>>();
4270 mapCreate(window0d[i]->Id1, window0d[i]->start1, window0d[i]->end1, window0d[i]->step1, window0d[i]->Id2,
4271 window0d[i]->start2, window0d[i]->end2, window0d[i]->step2, window0d[i]->order, BC, windowMap);
4272 windowMap->Nstar = -1;
4273 windowMap->SingularId = -1;
4274 windowMap->dc1 = window0d[i]->dc1;
4275 windowMap->dc2 = window0d[i]->dc2;
4276 // i-surface: change sign of I; same for J and K
4277 for(MInt j = 0; j < nDim; ++j) {
4278 if(windowMap->start1[j] == windowMap->end1[j]) {
4279 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
4280 windowMap->step2[windowMap->order[j]] = -1;
4281 }
4282 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
4283 windowMap->step2[windowMap->order[j]] = -1;
4284 }
4285 }
4286 }
4287
4288 // now for 5 star communicaitons (or ...... if needed)
4289 // 3 star does not need additional information
4290 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
4291 const MBool test = mapCompare11(windowMap, singularwindow[j]);
4292 if(test) {
4293 windowMap->Nstar = singularwindow[j]->Nstar;
4294 windowMap->SingularId = singularwindow[j]->SingularId;
4295 }
4296 }
4297
4298 // add the map to the list!
4299 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4300
4301 if(window0d[i]->BC >= 6000 && window0d[i]->BC < 6010) { //( window0d[i]->BC==6000) { //6000er-change
4302 windowMap = make_unique<StructuredWindowMap<nDim>>();
4303 mapCreate(window0d[i]->Id1, window0d[i]->start1, window0d[i]->end1, window0d[i]->step1, window0d[i]->Id2,
4304 window0d[i]->start2, window0d[i]->end2, window0d[i]->step2, window0d[i]->order, BC, windowMap);
4305 windowMap->Nstar = -1;
4306 windowMap->SingularId = -1;
4307 windowMap->dc1 = window0d[i]->dc1;
4308 windowMap->dc2 = window0d[i]->dc2;
4309
4310 // i-surface: change sign of I; same for J and K
4311 for(MInt j = 0; j < nDim; ++j) {
4312 if(windowMap->start1[j] == windowMap->end1[j]) {
4313 if(windowMap->start1[j] == 0 && windowMap->start2[windowMap->order[j]] == 0) {
4314 windowMap->step2[windowMap->order[j]] = -1;
4315 }
4316 if(windowMap->start1[j] > 0 && windowMap->start2[windowMap->order[j]] > 0) {
4317 windowMap->step2[windowMap->order[j]] = -1;
4318 }
4319 }
4320 }
4321
4322 mapInvert1(windowMap);
4323 mapNormalize3(windowMap);
4324
4325 // now for 5 star communicaitons (or ...... if needed)
4326 // 3 star does not need additional information
4327 for(MInt j = 0; j < (MInt)singularwindow.size(); ++j) {
4328 const MBool test = mapCompare11(windowMap, singularwindow[j]);
4329 if(test) {
4330 windowMap->Nstar = singularwindow[j]->Nstar;
4331 windowMap->SingularId = singularwindow[j]->SingularId;
4332 }
4333 }
4334 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
4335 }
4336 }
4337
4338 // Duplicates are already deleted above. The following call should be unnecessary
4339 deleteDuplicateCommMaps();
4340
4341#ifndef NDEBUG
4342 if(domainId() == 0) {
4343 cout << "======= GLOBALSTRUCTUREDBNDRYCNDMAPS ======" << endl;
4344 for(MInt i = 0; i < (signed)globalStructuredBndryCndMaps.size(); ++i) {
4345 mapPrint(globalStructuredBndryCndMaps[i]);
4346 }
4347
4348 cout << " ======= SINGULARWINDOW =============" << endl;
4349 for(MInt i = 0; i < (signed)singularwindow.size(); ++i) {
4350 mapPrint(singularwindow[i]);
4351 }
4352
4353 cout << " ======== window0d ==============" << endl;
4354 for(MInt i = 0; i < (signed)window0d.size(); ++i) {
4355 mapPrint(window0d[i]);
4356 }
4357
4358 cout << " ======== window1d ==============" << endl;
4359 for(MInt i = 0; i < (signed)window1d.size(); ++i) {
4360 mapPrint(window1d[i]);
4361 }
4362
4363 cout << " ======== window2d ==============" << endl;
4364 for(MInt i = 0; i < (signed)window2d.size(); ++i) {
4365 mapPrint(window2d[i]);
4366 }
4367 }
4368#endif
4369
4370 if(!hasConnectionInfo) {
4371 writeConnectionWindowInformation2D(periodicDisplacements);
4372 } else {
4373 if(domainId() == 0) {
4374 cout << "##########################################################################" << endl;
4375 cout << "WARNING: OLD CONNECTION INFO EXISTS, DELETE BEFORE NEW ONE CAN BE WRITTEN!" << endl;
4376 cout << "##########################################################################" << endl;
4377 }
4378 }
4379
4380 if(domainId() == 0) {
4381 cout << "Connection identification and window creation finished!" << endl;
4382 }
4383 }
4384}
4385
4386
4387template <MInt nDim>
4389 unique_ptr<StructuredWindowMap<nDim>>& g_window,
4390 const MInt singularcount) {
4391 const MInt s_blockId = s_window->Id1;
4392 const MInt g_blockId = g_window->Id2;
4393 stringstream prop_name;
4394 prop_name << "BCMap_" << std::min(s_blockId, g_blockId) << "_" << std::max(s_blockId, g_blockId);
4395 const MInt BC_temp = Context::getSolverProperty<MInt>(prop_name.str(), solverId(), AT_);
4396 if(BC_temp < 6000 || BC_temp >= 6010) mTerm(1, "Your are an idiot!");
4397 s_window->BCsingular[singularcount + 2] = -BC_temp;
4398 g_window->BC = -BC_temp;
4399}
4400
4401
4402template <MInt nDim>
4404 std::vector<unique_ptr<StructuredWindowMap<nDim>>>& window1,
4405 std::vector<unique_ptr<StructuredWindowMap<nDim>>>& window2) {
4406 // Communication BCs exist in duplicate; the following algorithm should consistently remove both maps
4407 const MBool isSame = (&window1 == &window2);
4408
4409 // Loop over all comm Bcs
4410 for(auto it = window1.cbegin(); it != window1.cend();) {
4411 if(window1.empty()) {
4412 break;
4413 }
4414 MBool deleted1 = false;
4415 if((*it)->BC >= 6000 && (*it)->BC < 6010) {
4416 for(auto it2 = isSame ? it + 1 : window2.cbegin(); it2 != window2.cend();) {
4417 if(window2.empty()) {
4418 break;
4419 }
4420 MBool deleted2 = false;
4421 if((*it2)->BC >= 6000 && (*it2)->BC < 6010) {
4422 // Compare if both BCs describe the communication bewteen same blocks
4423 // TODO_SS labels:FV,toenhance Isn't it enough to check just for the receive blocks, i.g., to check that
4424 // a block receives data for same range of cells multiple times? Afterwards also delete
4425 // the inverted maps
4426 if((*it)->Id1 == (*it2)->Id1 && (*it)->Id2 == (*it2)->Id2) {
4427 // Determine if one BC is fully included in the other one;
4428 // Assumption: When on e map is fully included in another map on one side
4429 // then it is also included on the opposite side
4430 MInt diffStart[nDim], diffEnd[nDim];
4431 for(MInt dim = 0; dim < nDim; ++dim) {
4432 // Sanity check that map is normalized
4433 if((*it)->step1[dim] < 0 || (*it2)->step1[dim] < 0) {
4434 mTerm(1, "");
4435 }
4436
4437 diffStart[dim] = (*it)->start1[dim] - (*it2)->start1[dim];
4438 diffEnd[dim] = (*it)->end1[dim] - (*it2)->end1[dim];
4439 }
4440
4441 const MInt minStart = *std::min_element(&diffStart[0], &diffStart[0] + nDim);
4442 const MInt maxStart = *std::max_element(&diffStart[0], &diffStart[0] + nDim);
4443 const MInt minEnd = *std::min_element(&diffEnd[0], &diffEnd[0] + nDim);
4444 const MInt maxEnd = *std::max_element(&diffEnd[0], &diffEnd[0] + nDim);
4445 if(minStart * maxStart >= 0 && minEnd * maxEnd >= 0
4446 && ((minStart >= 0 && maxEnd <= 0) || (maxStart <= 0 && minEnd >= 0))) {
4447 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && (minStart>=maxEnd||maxStart<=minEnd)) {
4448 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && minStart*minEnd<=0) {
4449 // TODO_SS labels:FV Previously if two maps cover exactly same range, nothing was done, except they
4450 // belong to same BC
4451 // const MBool sameBC = (((*it))->BC == (it2)->BC);
4452 // if (!(minStart==0 && maxStart==0 && minEnd==0 && maxEnd==0 && !sameBC)) {
4453
4454 if(minStart == 0 && maxStart == 0 && minEnd == 0 && maxEnd == 0) {
4455 if((*it)->BC != 6000 || (*it2)->BC != 6000) {
4456 if(domainId() == 0) cout << "CAUTION: BC reset to 6000!" << endl;
4457 (*it2)->BC = 6000;
4458 }
4459 }
4460
4461 // Check which map is the enclosed map
4462 // if (maxStart>0 || minEnd<0) {
4463 if(minStart >= 0 && maxEnd <= 0) {
4464#ifndef NDEBUG
4465 if(domainId() == 0) {
4466 cout << "!!! DELETE WINDOW: !!!" << endl;
4467 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4468 mapPrint(map1);
4469 cout << "!!! BECAUSE OF: !!!" << endl;
4470 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4471 mapPrint(map2);
4472 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4473 }
4474#endif
4475 it = window1.erase(it);
4476 deleted1 = true;
4477 break;
4478 } else {
4479#ifndef NDEBUG
4480 if(domainId() == 0) {
4481 cout << "!!! DELETE WINDOW2: !!!" << endl;
4482 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4483 mapPrint(map2);
4484 cout << "!!! BECAUSE OF: !!!" << endl;
4485 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4486 mapPrint(map1);
4487 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4488 }
4489#endif
4490 it2 = window2.erase(it2);
4491 deleted2 = true;
4492 }
4493
4494 // }
4495 }
4496 }
4497 }
4498 if(!deleted2) ++it2;
4499 }
4500 }
4501 if(!deleted1) ++it;
4502 }
4503
4504
4505 // Similar story for periodic BCs: Check if receive maps overlap and delete the one which is
4506 // completly contained in some other periodic map
4507 for(auto it = window1.cbegin(); it != window1.cend();) {
4508 if(window1.empty()) {
4509 break;
4510 }
4511 MBool deleted1 = false;
4512 if((*it)->BC >= 4401 && (*it)->BC <= 4406) {
4513 for(auto it2 = isSame ? it + 1 : window2.cbegin(); it2 != window2.cend();) {
4514 if(window2.empty()) {
4515 break;
4516 }
4517 MBool deleted2 = false;
4518 if((*it2)->BC >= 4401 && (*it2)->BC <= 4406) {
4519 // Compare receive blocks
4520 if((*it)->Id2 == (*it2)->Id2) {
4521 // Determine if one BC is fully included in the other one;
4522 // Assumption: When on e map is fully included in another map on one side
4523 // then it is also included on the opposite side
4524 MInt diffStart[nDim], diffEnd[nDim];
4525 for(MInt dim = 0; dim < nDim; ++dim) {
4526 auto it_start2 = (*it)->step2[dim] > 0 ? (*it)->start2[dim] : (*it)->end2[dim];
4527 auto it_end2 = (*it)->step2[dim] > 0 ? (*it)->end2[dim] : (*it)->start2[dim];
4528 auto it2_start2 = (*it2)->step2[dim] > 0 ? (*it2)->start2[dim] : (*it2)->end2[dim];
4529 auto it2_end2 = (*it2)->step2[dim] > 0 ? (*it2)->end2[dim] : (*it2)->start2[dim];
4530 diffStart[dim] = it_start2 - it2_start2;
4531 diffEnd[dim] = it_end2 - it2_end2;
4532 }
4533
4534
4535 const MInt minStart = *std::min_element(&diffStart[0], &diffStart[0] + nDim);
4536 const MInt maxStart = *std::max_element(&diffStart[0], &diffStart[0] + nDim);
4537 const MInt minEnd = *std::min_element(&diffEnd[0], &diffEnd[0] + nDim);
4538 const MInt maxEnd = *std::max_element(&diffEnd[0], &diffEnd[0] + nDim);
4539 if(minStart * maxStart >= 0 && minEnd * maxEnd >= 0
4540 && ((minStart >= 0 && maxEnd <= 0) || (maxStart <= 0 && minEnd >= 0))) {
4541 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && (minStart>=maxEnd||maxStart<=minEnd)) {
4542 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && minStart*minEnd<=0) {
4543 // TODO_SS labels:FV By now if two maps cover exactly same range, do nothing
4544 if(!(minStart == 0 && maxStart == 0 && minEnd == 0 && maxEnd == 0)) {
4545 // Check which map is the enclosed map
4546 // if (maxStart>0 || minEnd<0) {
4547 if(minStart >= 0 && maxEnd <= 0) {
4548#ifndef NDEBUG
4549 if(domainId() == 0) {
4550 cout << "!!! DELETE WINDOW: !!!" << endl;
4551 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4552 mapPrint(map1);
4553 cout << minStart << "|" << maxStart << " " << minEnd << "|" << maxEnd << endl;
4554 cout << "!!! BECAUSE OF: !!!" << endl;
4555 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4556 mapPrint(map2);
4557 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4558 }
4559#endif
4560 it = window1.erase(it);
4561 deleted1 = true;
4562 break;
4563 } else {
4564#ifndef NDEBUG
4565 if(domainId() == 0) {
4566 cout << "!!! DELETE WINDOW2: !!!" << endl;
4567 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4568 mapPrint(map2);
4569 cout << "!!! BECAUSE OF: !!!" << endl;
4570 cout << minStart << "|" << maxStart << " " << minEnd << "|" << maxEnd << endl;
4571 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4572 mapPrint(map1);
4573 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4574 }
4575#endif
4576 it2 = window2.erase(it2);
4577 deleted2 = true;
4578 }
4579 }
4580 }
4581 }
4582 }
4583 if(!deleted2) ++it2;
4584 }
4585 }
4586 if(!deleted1) ++it;
4587 }
4588}
4589
4590
4591template <MInt nDim>
4593 // Communication BCs exist in duplicate; the following algorithm should consistently remove both maps
4594
4595 // Loop over all comm Bcs
4596 for(auto it = globalStructuredBndryCndMaps.cbegin(); it != globalStructuredBndryCndMaps.cend();) {
4597 if(globalStructuredBndryCndMaps.empty()) {
4598 break;
4599 }
4600
4601 MBool deleted1 = false;
4602 if((*it)->BC <= -6000 && (*it)->BC > -6010) {
4603 for(auto it2 = it + 1; it2 != globalStructuredBndryCndMaps.cend();) {
4604 if(globalStructuredBndryCndMaps.empty()) {
4605 break;
4606 }
4607
4608 MBool deleted2 = false;
4609 if((*it2)->BC <= -6000 && (*it2)->BC > -6010) {
4610 if((*it)->Nstar != (*it2)->Nstar) {
4611 ++it2;
4612 continue;
4613 }
4614
4615 // Compare if both BCs describe the communication bewteen same blocks
4616 // TODO_SS labels:FV,toenhance Isn't it enough to check just for the receive blocks, i.g., to check that
4617 // a blocks receives data for same range of cells multiple times? Afterwards also delete
4618 // the inverted maps
4619 if((*it)->Id1 == (*it2)->Id1 && (*it)->Id2 == (*it2)->Id2) {
4620 // Determine if one BC is fully included in the other one;
4621 // Assumption: When on e map is fully included in another map on one side
4622 // then it is also included on the opposite side
4623 MInt diffStart[nDim], diffEnd[nDim];
4624 for(MInt dim = 0; dim < nDim; ++dim) {
4625 // Sanity check that map is normalized
4626 if((*it)->step1[dim] < 0 || (*it2)->step1[dim] < 0) mTerm(1, "");
4627 diffStart[dim] = (*it)->start1[dim] - (*it2)->start1[dim];
4628 diffEnd[dim] = (*it)->end1[dim] - (*it2)->end1[dim];
4629 }
4630 const MInt minStart = *std::min_element(&diffStart[0], &diffStart[0] + nDim);
4631 const MInt maxStart = *std::max_element(&diffStart[0], &diffStart[0] + nDim);
4632 const MInt minEnd = *std::min_element(&diffEnd[0], &diffEnd[0] + nDim);
4633 const MInt maxEnd = *std::max_element(&diffEnd[0], &diffEnd[0] + nDim);
4634 if(minStart * maxStart >= 0 && minEnd * maxEnd >= 0
4635 && ((minStart >= 0 && maxEnd <= 0) || (maxStart <= 0 && minEnd >= 0))) {
4636 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && (minStart>=maxEnd||maxStart<=minEnd)) {
4637 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && minStart*minEnd<=0) {
4638 // TODO_SS labels:FV By now if two maps cover exactly same range, do nothing
4639 if(!(minStart == 0 && maxStart == 0 && minEnd == 0 && maxEnd == 0)) {
4640 mTerm(1, "Duplicates are supposed to be deleted already in deleteDuplicateWindows!");
4641
4642 // Check which map is the enclosed map
4643 // if (maxStart>0 || minEnd<0) {
4644 if(minStart >= 0 && maxEnd <= 0) {
4645#ifndef NDEBUG
4646 if(domainId() == 0) {
4647 cout << "!!! DELETE MAP: !!!" << endl;
4648 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4649 mapPrint(map1);
4650 cout << "!!! BECAUSE OF: !!!" << endl;
4651 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4652 mapPrint(map2);
4653 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4654 }
4655#endif
4656 it = globalStructuredBndryCndMaps.erase(it);
4657 deleted1 = true;
4658 break;
4659 } else {
4660#ifndef NDEBUG
4661 if(domainId() == 0) {
4662 cout << "!!! DELETE MAP2: !!!" << endl;
4663 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4664 mapPrint(map2);
4665 cout << "!!! BECAUSE OF: !!!" << endl;
4666 cout << minStart << "|" << maxStart << " " << minEnd << "|" << maxEnd << endl;
4667 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4668 mapPrint(map1);
4669 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4670 }
4671#endif
4672 it2 = globalStructuredBndryCndMaps.erase(it2);
4673 deleted2 = true;
4674 }
4675 }
4676 }
4677 }
4678 }
4679 if(!deleted2) ++it2;
4680 }
4681 }
4682 if(!deleted1) ++it;
4683 }
4684
4685 // Similar story for periodic BCs: Check if receive maps overlap and delete the one which is
4686 // completly contained in some other periodic map
4687
4688 for(auto it = globalStructuredBndryCndMaps.cbegin(); it != globalStructuredBndryCndMaps.cend();) {
4689 if(globalStructuredBndryCndMaps.empty()) {
4690 break;
4691 }
4692
4693 MBool deleted1 = false;
4694 if((*it)->BC >= 4401 && (*it)->BC <= 4406) {
4695 for(auto it2 = it + 1; it2 != globalStructuredBndryCndMaps.cend();) {
4696 if(globalStructuredBndryCndMaps.empty()) {
4697 break;
4698 }
4699
4700 MBool deleted2 = false;
4701 if((*it2)->BC >= 4401 && (*it2)->BC <= 4406) {
4702 // Compare receive blocks
4703 if((*it)->Id2 == (*it2)->Id2) {
4704 // Determine if one BC is fully included in the other one;
4705 // Assumption: When on e map is fully included in another map on one side
4706 // then it is also included on the opposite side
4707 MInt diffStart[nDim], diffEnd[nDim];
4708 for(MInt dim = 0; dim < nDim; ++dim) {
4709 auto it_start2 = (*it)->step2[dim] > 0 ? (*it)->start2[dim] : (*it)->end2[dim];
4710 auto it_end2 = (*it)->step2[dim] > 0 ? (*it)->end2[dim] : (*it)->start2[dim];
4711 auto it2_start2 = (*it2)->step2[dim] > 0 ? (*it2)->start2[dim] : (*it2)->end2[dim];
4712 auto it2_end2 = (*it2)->step2[dim] > 0 ? (*it2)->end2[dim] : (*it2)->start2[dim];
4713 diffStart[dim] = it_start2 - it2_start2;
4714 diffEnd[dim] = it_end2 - it2_end2;
4715 }
4716
4717
4718 const MInt minStart = *std::min_element(&diffStart[0], &diffStart[0] + nDim);
4719 const MInt maxStart = *std::max_element(&diffStart[0], &diffStart[0] + nDim);
4720 const MInt minEnd = *std::min_element(&diffEnd[0], &diffEnd[0] + nDim);
4721 const MInt maxEnd = *std::max_element(&diffEnd[0], &diffEnd[0] + nDim);
4722 if(minStart * maxStart >= 0 && minEnd * maxEnd >= 0
4723 && ((minStart >= 0 && maxEnd <= 0) || (maxStart <= 0 && minEnd >= 0))) {
4724 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && (minStart>=maxEnd||maxStart<=minEnd)) {
4725 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && minStart*minEnd<=0) {
4726 // TODO_SS labels:FV By now if two maps cover exactly same range, do nothing
4727 if(!(minStart == 0 && maxStart == 0 && minEnd == 0 && maxEnd == 0)) {
4728 mTerm(1, "Duplicates are supposed to be deleted already in deleteDuplicateWindows!");
4729
4730 // Check which map is the enclosed map
4731 // if (maxStart>0 || minEnd<0) {
4732 if(minStart >= 0 && maxEnd <= 0) {
4733#ifndef NDEBUG
4734 if(domainId() == 0) {
4735 cout << "!!! DELETE MAP: !!!" << endl;
4736 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4737 mapPrint(map1);
4738 cout << minStart << "|" << maxStart << " " << minEnd << "|" << maxEnd << endl;
4739 cout << "!!! BECAUSE OF: !!!" << endl;
4740 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4741 mapPrint(map2);
4742 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4743 }
4744#endif
4745 it = globalStructuredBndryCndMaps.erase(it);
4746 deleted1 = true;
4747 break;
4748 } else {
4749#ifndef NDEBUG
4750 if(domainId() == 0) {
4751 cout << "!!! DELETE MAP2: !!!" << endl;
4752 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4753 mapPrint(map2);
4754 cout << "!!! BECAUSE OF: !!!" << endl;
4755 cout << minStart << "|" << maxStart << " " << minEnd << "|" << maxEnd << endl;
4756 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4757 mapPrint(map1);
4758 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4759 }
4760#endif
4761 it2 = globalStructuredBndryCndMaps.erase(it2);
4762 deleted2 = true;
4763 }
4764 }
4765 }
4766 }
4767 }
4768 if(!deleted2) ++it2;
4769 }
4770 }
4771 if(!deleted1) ++it;
4772 }
4773}
4774
4775
4776template <MInt nDim>
4778 std::vector<unique_ptr<StructuredWindowMap<nDim>>>& BCMap) {
4779 for(auto it = BCMap.cbegin(); it != BCMap.cend();) {
4780 if(BCMap.empty()) {
4781 break;
4782 }
4783
4784 MBool deleted1 = false;
4785 for(auto it2 = it + 1; it2 != BCMap.cend();) {
4786 if(BCMap.empty()) {
4787 break;
4788 }
4789
4790 MBool deleted2 = false;
4791
4792 // It should not matter if I compare "1"-indices or "2"-indices.
4793 // We could also check here if both maps have same BC, before
4794 // deciding which one to delete
4795
4796 // Determine if one BC is fully included in the other one;
4797 // Assumption: When on e map is fully included in another map on one side
4798 // then it is also included on the opposite side
4799 MInt diffStart[nDim], diffEnd[nDim];
4800 for(MInt dim = 0; dim < nDim; ++dim) {
4801 diffStart[dim] = (*it)->start1[dim] - (*it2)->start1[dim];
4802 diffEnd[dim] = (*it)->end1[dim] - (*it2)->end1[dim];
4803 }
4804 const MInt minStart = *std::min_element(&diffStart[0], &diffStart[0] + nDim);
4805 const MInt maxStart = *std::max_element(&diffStart[0], &diffStart[0] + nDim);
4806 const MInt minEnd = *std::min_element(&diffEnd[0], &diffEnd[0] + nDim);
4807 const MInt maxEnd = *std::max_element(&diffEnd[0], &diffEnd[0] + nDim);
4808 // if (minStart*maxStart>=0 && minEnd*maxEnd>=0 && (minStart>=maxEnd||maxStart<=minEnd)) {
4809 if(minStart * maxStart >= 0 && minEnd * maxEnd >= 0
4810 && ((minStart >= 0 && maxEnd <= 0) || (maxStart <= 0 && minEnd >= 0))) {
4811 // TODO_SS labels:FV By now if two maps cover exactly same range, do nothing
4812 if(!(minStart == 0 && maxStart == 0 && minEnd == 0 && maxEnd == 0)) {
4813 // Check which map is the enclosed map
4814 // if (maxStart>0 || minEnd<0) {
4815 if(minStart >= 0 && maxEnd <= 0) {
4816#ifndef NDEBUG
4817 if(domainId() == 0) {
4818 cout << "!!! DELETE MAP: !!!" << endl;
4819 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4820 mapPrint(map1);
4821 cout << "!!! BECAUSE OF: !!!" << endl;
4822 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4823 mapPrint(map2);
4824 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4825 }
4826#endif
4827 it = BCMap.erase(it);
4828 deleted1 = true;
4829 break;
4830 } else {
4831#ifndef NDEBUG
4832 if(domainId() == 0) {
4833 cout << "!!! DELETE MAP2: !!!" << endl;
4834 const unique_ptr<StructuredWindowMap<nDim>>& map2 = (*it2);
4835 mapPrint(map2);
4836 cout << "!!! BECAUSE OF: !!!" << endl;
4837 const unique_ptr<StructuredWindowMap<nDim>>& map1 = (*it);
4838 mapPrint(map1);
4839 cout << "!!!!!!!!!!!!!!!!!!!" << endl;
4840 }
4841#endif
4842 it2 = BCMap.erase(it2);
4843 deleted2 = true;
4844 }
4845 }
4846 }
4847 if(!deleted2) ++it2;
4848 }
4849 if(!deleted1) ++it;
4850 }
4851}
4852
4853
4854template <MInt nDim>
4856 m_log << "-->reading windowInformation from file ...(serial->parallel approach)" << endl;
4857 if(globalDomainId() == 0) {
4858 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
4859 stringstream dummy1;
4860 // go to the windowInformation folder and get number of windows
4861 noInputWindowInformation = 0;
4862 pio.getAttribute(&noInputWindowInformation, "noWindows", "/WindowInformation");
4863 // pio.getAttribute(&noInputWindowConnections, "noConnec", "Connectivity");
4864 noInputWindowConnections = 0;
4865 pio.getAttribute(&noInputBndryCnds, "noBndryCnds", "/BC");
4866
4867 MIntScratchSpace windowInfo(noInputWindowInformation * 7, AT_, "widnow information");
4868
4869 MInt indices[MAX_SPACE_DIMENSIONS][2]; // stores the indices of the windowInformation
4870 // copy the data of the windowInformations into a Scratspace which is send to everyone
4871 for(MInt i = 0; i < noInputWindowInformation; i++) {
4872 stringstream windowdummy;
4873 windowdummy << (i + 1);
4874 MString window = "window" + windowdummy.str();
4875 MString window1 = "/WindowInformation/window" + windowdummy.str();
4876 pio.getAttribute(&(windowInfo[i * 7]), "block", window1);
4877 ParallelIo::size_type ioSize[2] = {nDim, 2};
4878 pio.readArray(&(windowInfo[i * 7 + 1]), "WindowInformation", window, 2, ioSize);
4879 }
4880
4881 MInt noBcWindows;
4882 MInt** BCInformation = new MInt*[mMax(noInputBndryCnds, 0)];
4883 MInt* bcCndId = new MInt[mMax(noInputBndryCnds, 0)];
4884 MInt* noBcCndWindows = new MInt[mMax(noInputBndryCnds, 0)];
4885
4886 for(MInt i = 0; i < noInputBndryCnds; i++) {
4887 stringstream bcDummy;
4888 stringstream bcDummy1;
4889 bcDummy << "/BC/BC" << (i + 1);
4890 bcDummy1 << "BC" << (i + 1);
4891 char bcIdWindows[80];
4892 char bcId[80];
4893 strcpy(bcIdWindows, &bcDummy.str()[0]);
4894 strcpy(bcId, &bcDummy.str()[0]);
4895 strcat(bcIdWindows, "/noWindows");
4896 pio.getAttribute(&noBcWindows, "noWindows", bcDummy.str());
4897 noBcCndWindows[i] = noBcWindows;
4898 BCInformation[i] = new MInt[mMax((MInt)noBcWindows, 0)];
4899 ParallelIo::size_type ioSize = noBcWindows;
4900 pio.readArray(&BCInformation[i][0], "BC", bcDummy1.str(), 1, &ioSize);
4901 strcat(bcId, "/BC");
4902 pio.getAttribute(&bcCndId[i], "BC", bcDummy.str());
4903 }
4904
4905 MInt noWindows = 0;
4906 for(MInt i = 0; i < noInputBndryCnds; i++) {
4907 noWindows += noBcCndWindows[i];
4908 }
4909 // put everything into a vector to send the data
4910 MInt count = 0;
4911 MIntScratchSpace bcInfo(noWindows + 3 * noInputBndryCnds, AT_, "send bc info");
4912 for(MInt i = 0; i < noInputBndryCnds; i++) {
4913 bcInfo[count] = bcCndId[i];
4914 count++;
4915 bcInfo[count] = noBcCndWindows[i];
4916 count++;
4917 memcpy(&(bcInfo[count]), &(BCInformation[i][0]), noBcCndWindows[i] * sizeof(MInt));
4918 count += noBcCndWindows[i];
4919 bcInfo[count] = bcCndId[i];
4920 count++;
4921 }
4922
4923 MInt countInfo[3] = {noInputWindowInformation, noInputBndryCnds, noWindows};
4924 MPI_Bcast(countInfo, 3, MPI_INT, 0, m_StructuredComm, AT_, "countInfo");
4925
4926 // broadcast the information
4927 MPI_Bcast(windowInfo.getPointer(), noInputWindowInformation * 7, MPI_INT, 0, m_StructuredComm, AT_,
4928 "windowInfo.getPointer()");
4929 MPI_Bcast(bcInfo.getPointer(), (noWindows + 3 * noInputBndryCnds), MPI_INT, 0, m_StructuredComm, AT_,
4930 "bcInfo.getPointer()");
4931
4932 // put the window information into the right place
4933 for(MInt i = 0; i < noInputWindowInformation; i++) {
4934 std::unique_ptr<windowInformation<nDim>> temp = make_unique<windowInformation<nDim>>();
4935 // fill the windowInformation with life
4936 // first attribute the windowId to the object
4937 temp->windowId = i;
4938 temp->blockId = windowInfo[i * 7];
4939 memcpy(&indices[0][0], &(windowInfo[i * 7 + 1]), MAX_SPACE_DIMENSIONS * 2 * sizeof(MInt));
4940 for(MInt dim = 0; dim < nDim; dim++) {
4941 temp->startindex[dim] = indices[dim][0] - 1;
4942 temp->endindex[dim] = indices[dim][1] - 1;
4943 }
4944 // add the window to the vector
4945 inputWindows.push_back(std::move(temp));
4946 }
4947 // distribute the boundary conditions to the windows!
4948 for(MInt i = 0; i < noInputBndryCnds; ++i) {
4949 for(MInt j = 0; j < noBcCndWindows[i]; ++j) {
4950 MInt windowId = BCInformation[i][j] - 1; // correct the fortran notation
4951 inputWindows[windowId]->BC = bcCndId[i];
4952 }
4953 }
4954
4955 delete[] bcCndId;
4956 delete[] noBcCndWindows;
4957 for(MInt i = 0; i < noInputBndryCnds; i++) {
4958 delete[] BCInformation[i];
4959 }
4960 delete[] BCInformation;
4961 } else {
4962 // receive the data first
4963 MInt countInfo[3] = {0, 0, 0};
4964 MPI_Bcast(countInfo, 3, MPI_INT, 0, m_StructuredComm, AT_, "countInfo");
4965 noInputWindowInformation = countInfo[0];
4966 noInputBndryCnds = countInfo[1];
4967 MInt noWindows = countInfo[2];
4968 MIntScratchSpace bcInfo(noWindows + 3 * noInputBndryCnds, AT_, "send bc info");
4969 MIntScratchSpace windowInfo(noInputWindowInformation * 7, AT_, "widnow information");
4970 // receive the data from the other processes
4971 MPI_Bcast(windowInfo.getPointer(), noInputWindowInformation * 7, MPI_INT, 0, m_StructuredComm, AT_,
4972 "windowInfo.getPointer()");
4973 MPI_Bcast(bcInfo.getPointer(), (noWindows + 3 * noInputBndryCnds), MPI_INT, 0, m_StructuredComm, AT_,
4974 "bcInfo.getPointer()");
4975 MInt indices[MAX_SPACE_DIMENSIONS][2]; // stores the indices of the windowInformation
4976 // put the window information into the right place
4977 for(MInt i = 0; i < noInputWindowInformation; i++) {
4978 std::unique_ptr<windowInformation<nDim>> temp = make_unique<windowInformation<nDim>>();
4979 // fill the windowInformation with life
4980 // first attribute the windowId to the object
4981 temp->windowId = i;
4982 temp->blockId = windowInfo[i * 7];
4983 memcpy(&indices[0][0], &(windowInfo[i * 7 + 1]), MAX_SPACE_DIMENSIONS * 2 * sizeof(MInt));
4984 for(MInt dim = 0; dim < nDim; dim++) {
4985 temp->startindex[dim] = indices[dim][0] - 1;
4986 temp->endindex[dim] = indices[dim][1] - 1;
4987 }
4988 // add the window to the vector
4989 inputWindows.push_back(std::move(temp));
4990 }
4991
4992 // put the boundary condition info into the right place
4993 MInt** BCInformation = new MInt*[mMax(noInputBndryCnds, 0)];
4994 MInt* bcCndId = new MInt[mMax(noInputBndryCnds, 0)];
4995 MInt* noBcCndWindows = new MInt[mMax(noInputBndryCnds, 0)];
4996 MInt count = 0;
4997 for(MInt i = 0; i < noInputBndryCnds; i++) {
4998 bcCndId[i] = bcInfo[count];
4999 count++;
5000 noBcCndWindows[i] = bcInfo[count];
5001 count++;
5002 BCInformation[i] = new MInt[mMax(noBcCndWindows[i], 0)];
5003 memcpy(&(BCInformation[i][0]), &(bcInfo[count]), noBcCndWindows[i] * sizeof(MInt));
5004 count += noBcCndWindows[i];
5005 bcCndId[i] = bcInfo[count];
5006 count++;
5007 }
5008
5009 // distribute the boundary conditions to the windows!
5010 for(MInt i = 0; i < noInputBndryCnds; ++i) {
5011 for(MInt j = 0; j < noBcCndWindows[i]; ++j) {
5012 MInt windowId = BCInformation[i][j] - 1; // correct the fortran notation
5013 inputWindows[windowId]->BC = bcCndId[i];
5014 }
5015 }
5016
5017 delete[] bcCndId;
5018 delete[] noBcCndWindows;
5019 for(MInt i = 0; i < noInputBndryCnds; i++) {
5020 delete[] BCInformation[i];
5021 }
5022 delete[] BCInformation;
5023 }
5024}
5025
5026template <MInt nDim>
5028 unique_ptr<StructuredWindowMap<nDim>> windowMap;
5029 // MInt noPeriodicWindows[3] = {0,0,0};
5030 // function creates a map of all the global boundary conditions
5031 // global means from Input file !!!
5032
5033 // first look which periodic direction is not used
5034 // MBool switchPeriodicIds = true;
5035 MBool isPeriodicDirUsed[3] = {false, false, false};
5036 MBool switchPeriodicBC[3] = {true, true, true};
5037
5038 // check if periodic direction (4401,4403,4405) is already in use (find free slots for channel bc)
5039 // also check if distinct bc numbers (4401/4402, 4403/4404, 4405/4406) for both surfaces are used
5040 // or if both periodic surfaces have the same number, in that case swtich
5041 for(MInt windowId = 0; windowId < noInputWindowInformation; windowId++) {
5042 switch(inputWindows[windowId]->BC) {
5043 case 4401:
5044 isPeriodicDirUsed[0] = true;
5045 break;
5046 case 4402:
5047 switchPeriodicBC[0] = false;
5048 break;
5049 case 4403:
5050 isPeriodicDirUsed[1] = true;
5051 break;
5052 case 4404:
5053 switchPeriodicBC[1] = false;
5054 break;
5055 case 4405:
5056 isPeriodicDirUsed[2] = true;
5057 break;
5058 case 4406:
5059 switchPeriodicBC[2] = false;
5060 break;
5061 default:
5062 // do nothing
5063 break;
5064 }
5065 }
5066
5067 for(MInt noWin = 0; noWin < noInputWindowInformation; noWin++) {
5068 windowMap = make_unique<StructuredWindowMap<nDim>>();
5069 MInt order[3] = {0, 1, 2};
5070 MInt step1[3] = {1, 1, 1};
5071
5072 // use the standard mapping to itself
5073 // pushback all information on the boundary condition into the global container
5074 // except for periodic and multiblock communication
5075 if(inputWindows[noWin]->BC != 6000
5076 && (inputWindows[noWin]->BC < 4000
5077 || inputWindows[noWin]->BC >= 5000) /*&&inputWindows[noWin]->BC!=2222&&inputWindows[noWin]->BC!=2221*/) {
5078 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5079 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, inputWindows[noWin]->BC,
5080 windowMap);
5081 // add the map to the list!
5082 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5083 }
5084
5085 // Pascal: Why do we have a spcial treatment for that? this is exactely what is done above
5086 // special treatment for zonal BC 2222
5087 /*if(inputWindows[noWin]->BC==2222) {
5088 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5089 (inputWindows[noWin]->windowId+1) , nullptr, nullptr , nullptr, order,inputWindows[noWin]->BC , windowMap );
5090 //add map for bc2222 to list
5091 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5092 }
5093 */
5094 // special treatment for zonal BC 2221
5095 if(inputWindows[noWin]->BC == 2221) {
5096 /*mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5097 (inputWindows[noWin]->windowId+1) , nullptr, nullptr , nullptr, order,inputWindows[noWin]->BC , windowMap );
5098 //add map for bc2221 to list
5099 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5100 */
5101 // now add a copy of the boundary condition of type bc7909 to list (special treatment)
5102 windowMap = make_unique<StructuredWindowMap<nDim>>();
5103 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5104 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, 7909, windowMap);
5105 // add the map to the list!
5106 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5107 }
5108
5109
5110 if(inputWindows[noWin]->BC > 4000 && inputWindows[noWin]->BC < 5000) {
5111 // add channel flow and rotating periodic BC to physical BC.
5112 // in order to build the comm groups for channel and rotation.
5114 // 4001 and 4002 for rotation
5115 // 2401 and 2402 for channel
5116
5117 if(inputWindows[noWin]->BC == 4011) {
5118 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5119 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, 4001, windowMap);
5120 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5121 }
5122
5123 if(inputWindows[noWin]->BC == 4012) {
5124 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5125 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, 4002, windowMap);
5126 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5127 }
5128
5129 if(inputWindows[noWin]->BC > 4400 && inputWindows[noWin]->BC < 4407) {
5130 // if same BC number is used for both periodic surfaces
5131 // switch BC number of the surface at the end of the blocks
5132 MInt periodicDirection = -1;
5133 for(MInt dim = 0; dim < nDim; dim++) {
5134 if(inputWindows[noWin]->startindex[dim] == inputWindows[noWin]->endindex[dim]) {
5135 periodicDirection = dim;
5136 break;
5137 }
5138 }
5139
5140 MInt bigBlockId = inputWindows[noWin]->blockId;
5141 MInt bigBlockSize = m_grid->getBlockNoCells(bigBlockId, nDim - 1 - periodicDirection);
5142 MInt periodicId = inputWindows[noWin]->BC - 4401;
5143 MInt periodicIndex = periodicId / 2;
5144
5145 if(switchPeriodicBC[periodicIndex] && bigBlockSize == inputWindows[noWin]->startindex[periodicDirection]
5146 && periodicId % 2 == 0) {
5147 m_log << "Changing BC from " << inputWindows[noWin]->BC << " to " << inputWindows[noWin]->BC + 1 << endl;
5148 inputWindows[noWin]->BC++;
5149 }
5150 }
5151
5152 // Channel BCs
5153 // for BC 4005 and 4006 two periodic bcs 4401 and 4402
5154 // will be created and also physical bcs 2401 and 2402
5155 // to correct the pressure and density at both sides
5156 if(inputWindows[noWin]->BC == 4005 || inputWindows[noWin]->BC == 4006) {
5157 // use the first unused periodic direction
5158 MInt freePeriodicBC = 4400;
5159 for(MInt dir = 0; dir < nDim; dir++) {
5160 if(isPeriodicDirUsed[dir] == false) {
5161 freePeriodicBC += dir * 2 + 1;
5162 break;
5163 }
5164 }
5165
5166 m_log << "Using Periodic BC " << freePeriodicBC << " / " << freePeriodicBC + 1 << " for the channel/pipe flow"
5167 << endl;
5168
5169 if(inputWindows[noWin]->BC == 4005) {
5170 m_log << "Identified channel inflow bc 4005, creating periodic map BC " << freePeriodicBC
5171 << " and physicalMap BC " << 2401 << endl;
5172 inputWindows[noWin]->BC = freePeriodicBC;
5173 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5174 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, 2401, windowMap);
5175 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5176 }
5177
5178 if(inputWindows[noWin]->BC == 4006) {
5179 m_log << "Identified channel inflow bc 4006, creating periodic map BC " << freePeriodicBC + 1
5180 << " and physicalMap BC " << 2402 << endl;
5181 inputWindows[noWin]->BC = freePeriodicBC + 1;
5182 mapCreate(inputWindows[noWin]->blockId, inputWindows[noWin]->startindex, inputWindows[noWin]->endindex, step1,
5183 (inputWindows[noWin]->windowId + 1), nullptr, nullptr, nullptr, order, 2402, windowMap);
5184 globalStructuredBndryCndMaps.push_back(std::move(windowMap));
5185 }
5186 }
5187 }
5188 }
5189}
5190
5191template <MInt nDim>
5196 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_APPEND, m_StructuredComm);
5197 MInt noConnectionMaps = 0;
5198 MInt empty = 0;
5199 for(MInt mapId = 0; mapId < (MInt)globalStructuredBndryCndMaps.size(); mapId++) {
5200 // The 6000er connection maps have negative BC?!
5201 // only write out the connection maps
5202 if((globalStructuredBndryCndMaps[mapId]->BC <= -6000 && globalStructuredBndryCndMaps[mapId]->BC > -6010)
5203 || // (globalStructuredBndryCndMaps[mapId]->BC==6000) || //6000er-change ; check if this change makes sense!
5204 (globalStructuredBndryCndMaps[mapId]->BC > 4400 && globalStructuredBndryCndMaps[mapId]->BC < 4407)) {
5205 stringstream windowName;
5206 windowName << "map" << noConnectionMaps << endl;
5207 MString windowNameStr = windowName.str();
5208 ParallelIo::size_type noWindowInformation = 7 * nDim + 16;
5209 pio.defineArray(maia::parallel_io::PIO_INT, "Connectivity", windowNameStr, 1, &noWindowInformation);
5210
5211 MIntScratchSpace windowInformation((MInt)noWindowInformation, AT_, "windowInformation");
5212 writeMapToArray(globalStructuredBndryCndMaps[mapId], windowInformation.begin());
5213
5214
5215 ParallelIo::size_type offset = 0;
5216 if(globalDomainId() == 0) {
5217 pio.writeArray(windowInformation.begin(), "Connectivity", windowNameStr, 1, &offset, &noWindowInformation);
5218 } else {
5219 ParallelIo::size_type zeroWindows = 0;
5220 pio.writeArray(&empty, "Connectivity", windowNameStr, 1, &offset, &zeroWindows);
5221 }
5222 noConnectionMaps++;
5223 }
5224 }
5225
5229 MInt noSingularityMaps = 0;
5230 for(MInt mapId = 0; mapId < (MInt)singularwindow.size(); mapId++) {
5231 stringstream windowName;
5232 windowName << "singularMap" << noSingularityMaps << endl;
5233 MString windowNameStr = windowName.str();
5234 ParallelIo::size_type noWindowInformation = 7 * nDim + 16;
5235 pio.defineArray(maia::parallel_io::PIO_INT, "Connectivity", windowNameStr, 1, &noWindowInformation);
5236
5237 MIntScratchSpace windowInformation(noWindowInformation, AT_, "windowInformation");
5238 writeMapToArray(singularwindow[mapId], windowInformation.begin());
5239
5240 ParallelIo::size_type offset = 0;
5241 if(domainId() == 0) {
5242 pio.writeArray(windowInformation.begin(), "Connectivity", windowNameStr, 1, &offset, &noWindowInformation);
5243 } else {
5244 ParallelIo::size_type zeroWindows = 0;
5245 pio.writeArray(&empty, "Connectivity", windowNameStr, 1, &offset, &zeroWindows);
5246 }
5247 noSingularityMaps++;
5248 }
5249
5253 cout << "Starting write out " << endl;
5254 MInt noPeriodicDisplacementInfo = nDim * nDim;
5255 MFloatScratchSpace localPeriodicDisplacements(m_noBlocks * noPeriodicDisplacementInfo, AT_,
5256 "allPeriodicDisplacements");
5257 MFloatScratchSpace globalPeriodicDisplacements(m_noBlocks * noPeriodicDisplacementInfo, AT_,
5258 "allPeriodicDisplacements");
5259 localPeriodicDisplacements.fill(-99999999.0);
5260 for(MInt periodicId = 0; periodicId < noPeriodicDisplacementInfo; periodicId++) {
5261 localPeriodicDisplacements(m_blockId * noPeriodicDisplacementInfo + periodicId) = periodicDisplacements[periodicId];
5262 }
5263
5264 cout << "Allreduce noBlocks: " << m_noBlocks << " totalSize: " << m_noBlocks * noPeriodicDisplacementInfo << endl;
5265 MPI_Allreduce(&localPeriodicDisplacements(0), &globalPeriodicDisplacements(0),
5266 m_noBlocks * noPeriodicDisplacementInfo, MPI_DOUBLE, MPI_MAX, m_StructuredComm, AT_,
5267 "localPeriodicDisplacements(0)", "globalPeriodicDisplacements(0)");
5268
5269 cout << "Writing out periodic Window displacements" << endl;
5270
5271 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
5272 stringstream path;
5273 path << "periodicDisplacements" << blockId;
5274 MString pathStr = path.str();
5275 ParallelIo::size_type ioSize = noPeriodicDisplacementInfo;
5276 if(!pio.hasDataset(pathStr, "Connectivity")) {
5277 pio.defineArray(maia::parallel_io::PIO_FLOAT, "Connectivity", pathStr, 1, &ioSize);
5278 }
5279 ParallelIo::size_type ioOffset = 0;
5280 if(domainId() == 0) {
5281 pio.writeArray(&globalPeriodicDisplacements[blockId * noPeriodicDisplacementInfo], "Connectivity", pathStr, 1,
5282 &ioOffset, &ioSize);
5283 } else {
5284 ParallelIo::size_type zeroWindows = 0;
5285 MFloat emptyVar = 0;
5286 pio.writeArray(&emptyVar, "Connectivity", pathStr, 1, &ioOffset, &zeroWindows);
5287 }
5288 }
5289
5290 MInt hasConnectionInfo = 1;
5291 m_log << "Connection info written to grid file, normalConnections: " << noConnectionMaps
5292 << " noSingularityMaps: " << noSingularityMaps << endl;
5293
5294 pio.setAttribute(hasConnectionInfo, "hasConnectionInfo", "Connectivity");
5295 pio.setAttribute(noConnectionMaps, "noConnections", "Connectivity");
5296 pio.setAttribute(noSingularityMaps, "noSingularConnections", "Connectivity");
5297}
5298
5299template <MInt nDim>
5301 MInt noConnectionMaps = 0;
5302 MInt noSingularityMaps = 0;
5303 MInt noPeriodicDisplacementInfo = nDim * nDim;
5304 MFloatScratchSpace globalPeriodicDisplacements(m_noBlocks * noPeriodicDisplacementInfo, AT_,
5305 "allPeriodicDisplacements");
5306
5307 // first read the number of connection information
5308 // and broadcast it to all partitions
5309 if(globalDomainId() == 0) {
5310 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
5311 pio.getAttribute(&noConnectionMaps, "noConnections", "Connectivity");
5312 pio.getAttribute(&noSingularityMaps, "noSingularConnections", "Connectivity");
5313 MInt dummy[2] = {noConnectionMaps, noSingularityMaps};
5314 MPI_Bcast(dummy, 2, MPI_INT, 0, m_StructuredComm, AT_, "dummy");
5315 } else {
5316 MInt dummy[2] = {0, 0};
5317 MPI_Bcast(dummy, 2, MPI_INT, 0, m_StructuredComm, AT_, "dummy");
5318 noConnectionMaps = dummy[0];
5319 noSingularityMaps = dummy[1];
5320 }
5321
5322 // if connections were looked for previously (hasConnectionInfo is set)
5323 // but there are no connections there is no need to read them
5324 if(noConnectionMaps == 0 && noSingularityMaps == 0) {
5325 if(globalDomainId() == 0) {
5326 cout << "Connections were previously searched for, none found!" << endl
5327 << "---> hasConnectionInfo = 1" << endl
5328 << "---> noConnectionMaps = 0" << endl
5329 << "---> noSingularityMaps = 0" << endl;
5330 }
5331 return;
5332 }
5333
5334 if(globalDomainId() == 0) {
5335 ParallelIoHdf5 pio(m_grid->m_gridInputFileName, maia::parallel_io::PIO_READ, MPI_COMM_SELF);
5336 MInt noWindowInformation = 7 * nDim + 16;
5337 if(noConnectionMaps > 0) {
5338 MIntScratchSpace windowInformation(noWindowInformation * noConnectionMaps, AT_, "windowInformation");
5339 for(MInt mapId = 0; mapId < noConnectionMaps; mapId++) {
5340 stringstream windowName;
5341 windowName << "map" << mapId << endl;
5342 MString windowNameStr = windowName.str();
5343 ParallelIo::size_type ioSize = noWindowInformation;
5344 pio.readArray(&(windowInformation[mapId * noWindowInformation]), "Connectivity", windowNameStr, 1, &ioSize);
5345 }
5346 MPI_Bcast(windowInformation.getPointer(), noWindowInformation * noConnectionMaps, MPI_INT, 0, m_StructuredComm,
5347 AT_, "windowInformation.getPointer()");
5348
5349 for(MInt mapId = 0; mapId < noConnectionMaps; mapId++) {
5350 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5351 readMapFromArray(temp, &windowInformation[mapId * noWindowInformation]);
5352 globalStructuredBndryCndMaps.push_back(std::move(temp));
5353 }
5354 }
5355
5356 if(noSingularityMaps > 0) {
5357 MIntScratchSpace singularityInformation(noWindowInformation * noSingularityMaps, AT_, "singularityInformation");
5358 for(MInt mapId = 0; mapId < noSingularityMaps; mapId++) {
5359 stringstream windowName;
5360 windowName << "singularMap" << mapId << endl;
5361 MString windowNameStr = windowName.str();
5362 ParallelIo::size_type ioSize = noWindowInformation;
5363 pio.readArray(&(singularityInformation[mapId * noWindowInformation]), "Connectivity", windowNameStr, 1,
5364 &ioSize);
5365 }
5366 MPI_Bcast(singularityInformation.getPointer(), noWindowInformation * noSingularityMaps, MPI_INT, 0,
5367 m_StructuredComm, AT_, "singularityInformation.getPointer()");
5368 for(MInt mapId = 0; mapId < noSingularityMaps; mapId++) {
5369 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5370 readMapFromArray(temp, &(singularityInformation[mapId * noWindowInformation]));
5371 singularwindow.push_back(std::move(temp));
5372 }
5373 }
5374
5375 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
5376 stringstream path;
5377 path << "periodicDisplacements" << blockId;
5378 MString pathStr = path.str();
5379 ParallelIo::size_type ioSize = noPeriodicDisplacementInfo;
5380 if(pio.hasDataset(pathStr, "Connectivity")) {
5381 // check if path for block individual displacements exists, if not read
5382 // same dataset for every block
5383 pio.readArray(&globalPeriodicDisplacements[blockId * noPeriodicDisplacementInfo], "Connectivity", pathStr, 1,
5384 &ioSize);
5385 } else {
5386 pio.readArray(&globalPeriodicDisplacements[blockId * noPeriodicDisplacementInfo], "Connectivity",
5387 "periodicDisplacements", 1, &ioSize);
5388 }
5389 }
5390
5391 MPI_Bcast(&globalPeriodicDisplacements(0), m_noBlocks * noPeriodicDisplacementInfo, MPI_DOUBLE, 0, m_StructuredComm,
5392 AT_, "globalPeriodicDisplacements(0)");
5393
5394 for(MInt blockId = 0; blockId < m_noBlocks; blockId++) {
5395 for(MInt i = 0; i < noPeriodicDisplacementInfo; i++) {
5396 cout << "globalPeriodicDisplacement: " << globalPeriodicDisplacements[blockId * noPeriodicDisplacementInfo + i]
5397 << endl;
5398 }
5399 }
5400 } else {
5401 MInt noWindowInformation = 7 * nDim + 16;
5402 if(noConnectionMaps > 0) {
5403 MIntScratchSpace windowInformation(noWindowInformation * noConnectionMaps, AT_, "windowInformation");
5404 MPI_Bcast(windowInformation.getPointer(), noWindowInformation * noConnectionMaps, MPI_INT, 0, m_StructuredComm,
5405 AT_, "windowInformation.getPointer()");
5406 for(MInt mapId = 0; mapId < noConnectionMaps; mapId++) {
5407 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5408 readMapFromArray(temp, &windowInformation[mapId * noWindowInformation]);
5409 globalStructuredBndryCndMaps.push_back(std::move(temp));
5410 }
5411 }
5412 if(noSingularityMaps > 0) {
5413 MIntScratchSpace singularityInformation(noWindowInformation * noSingularityMaps, AT_, "singularityInformation");
5414 MPI_Bcast(singularityInformation.getPointer(), noWindowInformation * noSingularityMaps, MPI_INT, 0,
5415 m_StructuredComm, AT_, "singularityInformation.getPointer()");
5416 for(MInt mapId = 0; mapId < noSingularityMaps; mapId++) {
5417 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5418 readMapFromArray(temp, &(singularityInformation[mapId * noWindowInformation]));
5419 singularwindow.push_back(std::move(temp));
5420 }
5421 }
5422
5423 MPI_Bcast(&globalPeriodicDisplacements(0), m_noBlocks * noPeriodicDisplacementInfo, MPI_DOUBLE, 0, m_StructuredComm,
5424 AT_, "globalPeriodicDisplacements(0)");
5425 }
5426
5427 for(MInt periodicId = 0; periodicId < noPeriodicDisplacementInfo; periodicId++) {
5428 periodicDisplacements[periodicId] =
5429 globalPeriodicDisplacements(m_blockId * noPeriodicDisplacementInfo + periodicId);
5430 }
5431}
5432
5433
5434template <MInt nDim>
5436 MFloat* thickness, MInt* bcInfo, MInt informationType) {
5437 // we could also use the window information for sponges
5438 // set through properties.
5439
5440 // add the sponge Layter type to it too!!.
5441 if(informationType) {
5442 for(MUint bcId = 0; bcId < globalStructuredBndryCndMaps.size(); ++bcId) {
5443 for(MInt i = 0; i < noSpongeInfo; ++i) {
5444 if(globalStructuredBndryCndMaps[bcId]->BC == bcInfo[i]) {
5445 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5446 mapCpy(globalStructuredBndryCndMaps[bcId], temp);
5447 temp->spongeThickness = thickness[i];
5448 temp->beta = beta[i];
5449 temp->sigma = sigma[i];
5450 m_spongeInfoMap.push_back(std::move(temp));
5451 }
5452 }
5453 }
5454 } else {
5455 for(MUint bcId = 0; bcId < globalStructuredBndryCndMaps.size(); ++bcId) {
5456 for(MInt i = 0; i < noSpongeInfo; ++i) {
5457 if(globalStructuredBndryCndMaps[bcId]->Id2 == bcInfo[i]) {
5458 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5459 mapCpy(globalStructuredBndryCndMaps[bcId], temp);
5460 temp->spongeThickness = thickness[i];
5461 temp->beta = beta[i];
5462 temp->sigma = sigma[i];
5463 m_spongeInfoMap.push_back(std::move(temp));
5464 }
5465 }
5466 }
5467 }
5468}
5469
5470
5471template <MInt nDim>
5473 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5474 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5475 if(globalStructuredBndryCndMaps[i]->BC == 2221 || globalStructuredBndryCndMaps[i]->BC == 2222) {
5476 mapCpy(globalStructuredBndryCndMaps[i], temp);
5477 m_zonalBCMaps.push_back(std::move(temp));
5478 temp = make_unique<StructuredWindowMap<nDim>>();
5479 }
5480 }
5481}
5482
5483template <MInt nDim>
5485 unique_ptr<StructuredWindowMap<nDim>>& map2) {
5486 if(map1->BC == map2->BC && map1->Id1 == map2->Id1) {
5487 return true;
5488 }
5489
5490 return false;
5491}
5492
5493
5494// new function to create list of all wall bcs needed for SA RANS
5495template <MInt nDim>
5497 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5498 for(MUint bcId = 0; bcId < globalStructuredBndryCndMaps.size(); ++bcId) {
5499 MInt firstDigit = (MInt)(((MFloat)globalStructuredBndryCndMaps[bcId]->BC) / 1000.0);
5500 if(firstDigit == 1 || globalStructuredBndryCndMaps[bcId]->BC == 2601) {
5501 mapCpy(globalStructuredBndryCndMaps[bcId], temp);
5502 m_wallDistInfoMap.push_back(std::move(temp));
5503 temp = make_unique<StructuredWindowMap<nDim>>();
5504 }
5505 }
5506}
5507
5508
5509// TODO_SS labels:FV Check if physicalAuxDataMap has the same information except that physicalAuxDataMap is not
5510// thickened by the # of ghost cells
5511// TODO_SS labels:FV,toremove The following is not used and can be deleted
5512// new function to create list of all wall bcs needed for SA RANS
5513template <MInt nDim>
5515 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
5516 for(MUint bcId = 0; bcId < localStructuredBndryCndMaps.size(); ++bcId) {
5517 MInt firstDigit = (MInt)(((MFloat)localStructuredBndryCndMaps[bcId]->BC) / 1000.0);
5518 if(firstDigit == 1 || localStructuredBndryCndMaps[bcId]->BC == 2601) {
5519 mapCpy(localStructuredBndryCndMaps[bcId], temp);
5520 temp->face = localStructuredBndryCndMaps[bcId]->face;
5521
5522 // Undo of thickening of the physicalBCMaps at the edges of the domain
5523 for(MInt dim = 0; dim < nDim; ++dim) {
5524 if(dim != (MInt)temp->face / 2) {
5525 if(temp->start1[dim] == m_myMapWithGC->start2[dim]) {
5526 temp->start1[dim] += m_noGhostLayers;
5527 temp->start2[dim] += m_noGhostLayers;
5528 }
5529 if(temp->end1[dim] == m_myMapWithGC->end2[dim]) {
5530 temp->end1[dim] -= m_noGhostLayers;
5531 temp->end2[dim] -= m_noGhostLayers;
5532 }
5533 } else { // dim==face/2
5534 const MInt face = temp->face;
5535 const MInt n = (face % 2) * 2 - 1; //-1,+1
5536 temp->start1[dim] += (MInt)(0.5 - (1.5 * (MFloat)n));
5537 temp->start2[dim] += (MInt)(0.5 - (1.5 * (MFloat)n));
5538 }
5539 }
5540
5541 m_wallDistInfoMap.push_back(std::move(temp));
5542 temp = make_unique<StructuredWindowMap<nDim>>();
5543 }
5544 }
5545}
5546
5547
5548template <MInt nDim>
5550 const MString blockType,
5551 const std::vector<MInt>& porousBlockIds,
5552 const std::vector<MInt>& auxDataWindowIds,
5553 const MBool force) {
5557 // For computing the modified wall distance we need to be on the side of the porous block,
5558 // but for computing the wall forces (cf & cp) we want to be on the fluid side
5559 // const MBool considerFPInterfaces = /*(blockType=="porous")
5560 // &&*/ (auxDataType==1 || auxDataType==2 || auxDataType==3);
5561
5562 // create the auxilary data maps
5563 // needed to write out cf,cp etc ...
5564 unique_ptr<StructuredWindowMap<nDim>> localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5565 MInt counter = 0;
5566 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5567 // if (globalStructuredBndryCndMaps[i]->Nstar!=-1) continue;
5568 const MInt BC = globalStructuredBndryCndMaps[i]->BC;
5569 MInt firstDigit = (MInt)(((MFloat)BC) / 1000.0);
5570 // If not solid and not fluid-porous interface continue
5571 // if (firstDigit!=1 && (!considerFPInterfaces || BC!=6002)) continue;
5572 if(firstDigit != 1 && BC != 6002) continue;
5573
5574
5575 MBool candidate = false;
5576
5577 if(auxDataType == 3) {
5578 for(auto windowId : auxDataWindowIds) {
5579 if(globalStructuredBndryCndMaps[i]->Id2 == windowId) { // && BC!=6000) {
5580 candidate = true;
5581 break;
5582 }
5583 }
5584 } else if(auxDataType == 0) { // only solid
5585 if(firstDigit == 1) candidate = true;
5586 } else if(auxDataType == 2) { // only fluid-porous
5587 if(BC == 6002 && porousBlockIds[globalStructuredBndryCndMaps[i]->Id1] == -1 /*blockType=="fluid"*/)
5588 candidate = true;
5589 } else if(firstDigit == 1
5590 || (BC == 6002
5591 && porousBlockIds[globalStructuredBndryCndMaps[i]->Id1]
5592 == -1 /*blockType=="fluid"*/)) { // fluid-porous interfaces and solids
5593 candidate = true;
5594 }
5595
5596 if(candidate) m_auxDataWindowIds.insert({i, globalStructuredBndryCndMaps[i]->Id2});
5597
5598 if(candidate || force) { // all the wall should be covered
5599 mapCombine11(m_myMapWithoutGC, globalStructuredBndryCndMaps[i], localMapDummy);
5600 MBool test = false;
5601 test = mapCheck(localMapDummy);
5602 if(test == true) {
5603 physicalAuxDataMap.push_back(std::move(localMapDummy));
5604 for(MInt j = 0; j < nDim; ++j) {
5605 // correct the global part for the output!!!
5606 physicalAuxDataMap[counter]->start2[j] -= globalStructuredBndryCndMaps[i]->start2[j];
5607 physicalAuxDataMap[counter]->end2[j] -= globalStructuredBndryCndMaps[i]->start2[j];
5608 }
5609 if(globalStructuredBndryCndMaps[i]->BC == 6002 && blockType == "porous")
5610 physicalAuxDataMap[counter]->isFluidPorousInterface = true;
5611 counter++;
5612 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5613 }
5614 }
5615 }
5616
5617 deleteDuplicateBCMaps(physicalAuxDataMap);
5618
5619 for(MInt i = 0; i < (MInt)physicalAuxDataMap.size(); i++) {
5620 for(MInt dim = 0; dim < nDim; dim++) {
5621 // check if the index is the same
5622 // MPI_Barrier(m_StructuredComm, AT_ );
5623 if(physicalAuxDataMap[i]->start1[dim] == physicalAuxDataMap[i]->end1[dim]) {
5624 // check which face it is and save this information
5625 switch(dim) {
5626 case 0: { // face 0 or 1
5627 // check if face 0 or 1
5628 if(physicalAuxDataMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
5629 // test of start2 instead of start1.
5630 physicalAuxDataMap[i]->face = 0;
5631 } else {
5632 physicalAuxDataMap[i]->face = 1;
5633 }
5634 break;
5635 }
5636 case 1: { // face 2 or 3
5637 // check if face 2 or 3
5638 if(physicalAuxDataMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
5639 physicalAuxDataMap[i]->face = 2;
5640 } else {
5641 physicalAuxDataMap[i]->face = 3;
5642 }
5643 break;
5644 }
5645 case 2: { // face 4 or 5
5646 // check if face 4 or 5
5647 if(physicalAuxDataMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
5648 physicalAuxDataMap[i]->face = 4;
5649 } else {
5650 physicalAuxDataMap[i]->face = 5;
5651 }
5652 break;
5653 }
5654 default: {
5655 cerr << "error no side could be attributed" << endl;
5656 exit(1);
5657 }
5658 }
5659 continue;
5660 }
5661 }
5662 }
5663}
5664
5665//#include <chrono>
5666//#include <thread>
5667template <MInt nDim>
5669 MPI_Comm* channelIn, MPI_Comm* channelOut, MPI_Comm* channelWorld, MInt* channelRoots, MPI_Comm* commStg,
5670 MInt* commStgRoot, MInt* commStgRootGlobal, MPI_Comm* commBC2600, MInt* commBC2600Root, MInt* commBC2600RootGlobal,
5671 MPI_Comm* rescalingCommGrComm, MInt* rescalingCommGrRoot, MInt* rescalingCommGrRootGlobal, MPI_Comm* commPerRotOne,
5672 MPI_Comm* commPerRotTwo, MPI_Comm* commPerRotWorld, MInt* rotationRoots, MInt& perRotGroup,
5673 SingularInformation* singularity, MInt* hasSingularity, MPI_Comm* plenumComm, MInt* plenumRoot) {
5674 // create a map of the partition and check whether it fits any of the globals
5675 // boundary Condition Maps
5676 // thus this functions relates the partition to the actual window and there-
5677 // fore also to the boundary condition.
5678
5679 MInt start1[3] = {0, 0, 0};
5680 MInt end1[3] = {0, 0, 0};
5681 MInt step1[3] = {1, 1, 1};
5682 MInt order[3] = {0, 1, 2};
5683 MInt start2[3] = {0, 0, 0};
5684 MInt end2[3] = {0, 0, 0};
5685
5686 MInt blockId = m_grid->getBlockId(domainId());
5687
5691 // this is the map of the active cells (no ghostcells) in my own partition
5692 // shifted by the no of ghost-cells
5693 for(MInt i = 0; i < nDim; i++) {
5694 start1[i] = m_grid->getMyOffset(nDim - 1 - i) + m_noGhostLayers; // shifted by the number of ghost layers
5695 start2[i] = m_noGhostLayers; // shifted by the number of ghost layers
5696 end1[i] = start1[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1;
5697 end2[i] = start2[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1;
5698 }
5699
5700 m_myMapWithoutGC = make_unique<StructuredWindowMap<nDim>>();
5701 mapCreate(blockId, start1, end1, step1, domainId(), start2, end2, step1, order, -1, m_myMapWithoutGC);
5702
5703 // this is the map of all the cells (including ghost-cells) in my own partition
5704 for(MInt i = 0; i < nDim; i++) {
5705 if(m_grid->getMyOffset(nDim - 1 - i) != 0) {
5706 start1[i] = m_grid->getMyOffset(nDim - 1 - i);
5707 end1[i] = start1[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1 + 2 * m_noGhostLayers;
5708 } else {
5709 start1[i] = 0;
5710 end1[i] = start1[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1 + 2 * m_noGhostLayers;
5711 }
5712 start2[i] = 0;
5713 end2[i] = m_grid->getMyActivePoints(nDim - 1 - i) - 1 + 2 * m_noGhostLayers;
5714 }
5715 m_myMapWithGC = make_unique<StructuredWindowMap<nDim>>();
5716 mapCreate(blockId, start1, end1, step1, domainId(), start2, end2, step1, order, -1, m_myMapWithGC);
5717
5718
5719 // maps of all partitions WITHOUT the ghostcells
5720 unique_ptr<StructuredWindowMap<nDim>> localMapDummy = nullptr;
5721 for(MInt j = 0; j < noDomains(); j++) {
5722 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5723
5724 blockId = m_grid->getBlockId(j);
5725 for(MInt i = 0; i < nDim; i++) {
5726 start1[i] = m_grid->getOffset(j, nDim - 1 - i) + m_noGhostLayers;
5727 start2[i] = 0;
5728 end1[i] = start1[i] + m_grid->getActivePoints(j, nDim - 1 - i) - 1;
5729 end2[i] = m_grid->getActivePoints(j, nDim - 1 - i) - 1;
5730 }
5731 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, -6000, localMapDummy);
5732 m_partitionMapsWithoutGC.push_back(std::move(localMapDummy));
5733 }
5734
5735 // maps of all partitions WITH the ghostcells
5736 for(MInt j = 0; j < noDomains(); j++) {
5737 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5738
5739 blockId = m_grid->getBlockId(j);
5740
5741 for(MInt i = 0; i < nDim; i++) {
5742 if(m_grid->getOffset(j, nDim - 1 - i) != 0) {
5743 start1[i] = m_grid->getOffset(j, nDim - 1 - i);
5744 end1[i] = start1[i] + m_grid->getActivePoints(j, nDim - 1 - i) - 1 + 2 * m_noGhostLayers;
5745 } else {
5746 start1[i] = 0;
5747 end1[i] = start1[i] + m_grid->getActivePoints(j, nDim - 1 - i) - 1 + 2 * m_noGhostLayers;
5748 }
5749
5750 start2[i] = 0;
5751 end2[i] = m_grid->getActivePoints(j, nDim - 1 - i) - 1 + 4;
5752 }
5753 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, -6000, localMapDummy);
5754 m_partitionMapsWithGC.push_back(std::move(localMapDummy));
5755 }
5756
5760
5761 // check overlapping of own partition with other partition and put into SND maps
5762 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5763 for(MInt i = 0; i < noDomains(); i++) {
5764 // skip if comparison to itself
5765 if(domainId() == i) {
5766 continue;
5767 }
5768 mapCombine11(m_myMapWithoutGC, m_partitionMapsWithGC[i], localMapDummy);
5769 MBool test = false;
5770 test = mapCheck(localMapDummy);
5771 if(test == true) {
5772 localMapDummy->BC = -6000;
5773 sndMap.push_back(std::move(localMapDummy));
5774 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5775 }
5776 }
5777
5778 // check overlapping of own partition with other partition and put into RCV maps
5779 for(MInt i = 0; i < noDomains(); i++) {
5780 // skip if comparison to itself
5781 if(domainId() == i) {
5782 continue;
5783 }
5784 mapCombine11(m_myMapWithGC, m_partitionMapsWithoutGC[i], localMapDummy);
5785 MBool test = false;
5786 test = mapCheck(localMapDummy);
5787 if(test == true) {
5788 localMapDummy->BC = -6000;
5789 rcvMap.push_back(std::move(localMapDummy));
5790 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5791 }
5792 }
5793
5794 // shift globalBC maps by ghost-cells
5795 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5796 for(MInt dim = 0; dim < nDim; dim++) {
5797 globalStructuredBndryCndMaps[i]->start1[dim] += m_noGhostLayers;
5798 globalStructuredBndryCndMaps[i]->end1[dim] += m_noGhostLayers;
5799 if((globalStructuredBndryCndMaps[i]->BC <= -6000 && globalStructuredBndryCndMaps[i]->BC > -6010)
5800 || (globalStructuredBndryCndMaps[i]->BC >= 4000 && globalStructuredBndryCndMaps[i]->BC < 5000)
5801 || globalStructuredBndryCndMaps[i]->BC == 6011) {
5802 // if(globalStructuredBndryCndMaps[i]->BC==6000 ||
5803 // (globalStructuredBndryCndMaps[i]->BC>=4000&&globalStructuredBndryCndMaps[i]->BC<5000) ||
5804 // globalStructuredBndryCndMaps[i]->BC==6001 ) { //6000er-change
5805 // for these special cases we also need to change the opposite side
5806 globalStructuredBndryCndMaps[i]->start2[dim] += m_noGhostLayers;
5807 globalStructuredBndryCndMaps[i]->end2[dim] += m_noGhostLayers;
5808 }
5809 }
5810 }
5811
5812 // go over all the global boundary maps and check if there is any overlapping part with the local partition and store
5813 // it in localStructuredBndryCndMaps
5814 //==>find all the local boundaries of the partition (including the periodic part)
5815
5816 // check for local boundary maps
5817 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5818 mapCombine11(m_myMapWithoutGC, globalStructuredBndryCndMaps[i], localMapDummy);
5819 MBool test = false;
5820 test = mapCheck(localMapDummy);
5821
5822 if(test == true) {
5823 localMapDummy->BC = globalStructuredBndryCndMaps[i]->BC;
5824 localMapDummy->Nstar = globalStructuredBndryCndMaps[i]->Nstar;
5825 localMapDummy->SingularId = globalStructuredBndryCndMaps[i]->SingularId;
5826 localMapDummy->dc1 = globalStructuredBndryCndMaps[i]->dc1;
5827 localMapDummy->dc2 = globalStructuredBndryCndMaps[i]->dc2;
5828 localMapDummy->Id1 = globalStructuredBndryCndMaps[i]->Id1;
5829 localStructuredBndryCndMaps.push_back(std::move(localMapDummy));
5830 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5831 }
5832 }
5833
5834 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
5835 for(MInt i = 0; i < nDim; i++) {
5836 m_partitionMapsWithoutGC[j]->start2[i] += m_noGhostLayers;
5837 m_partitionMapsWithoutGC[j]->end2[i] += m_noGhostLayers;
5838 }
5839 }
5840
5841 // check overlapping with bc 6000 (multiblock)
5842 vector<unique_ptr<StructuredWindowMap<nDim>>> SndMapBC6000;
5843
5844 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5845 if(globalStructuredBndryCndMaps[i]->BC <= -6000
5846 && globalStructuredBndryCndMaps[i]->BC > -6010) { //(globalStructuredBndryCndMaps[i]->BC==6000) { //6000er-change
5847 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
5848 // skip own domain, but only if 6000 does not connect the same domain
5849 if(globalStructuredBndryCndMaps[i]->Id1 != globalStructuredBndryCndMaps[i]->Id2) {
5850 if(domainId() == m_partitionMapsWithoutGC[j]->Id2) {
5851 continue;
5852 }
5853 }
5854
5855 MInt myBlockId = m_grid->getBlockId(domainId());
5856 if(globalStructuredBndryCndMaps[i]->Id2 == myBlockId) {
5857 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
5858 MBool test = false;
5859 test = mapCheck(localMapDummy);
5860
5861 if(test == true) {
5862 localMapDummy->BC = globalStructuredBndryCndMaps[i]->BC;
5863 localMapDummy->Nstar = globalStructuredBndryCndMaps[i]->Nstar;
5864 localMapDummy->SingularId = globalStructuredBndryCndMaps[i]->SingularId;
5865 localMapDummy->dc1 = globalStructuredBndryCndMaps[i]->dc1;
5866 localMapDummy->dc2 = globalStructuredBndryCndMaps[i]->dc2;
5867
5868 SndMapBC6000.push_back(std::move(localMapDummy));
5869 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5870 }
5871 }
5872 }
5873 }
5874 }
5875
5876
5877 // now check overlapping with bc 4xxx (periodic bc)
5878 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
5879 if(globalStructuredBndryCndMaps[i]->BC >= 4000 && globalStructuredBndryCndMaps[i]->BC < 5000) {
5880 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
5881 // self communication is allowed
5882 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
5883 MBool test = false;
5884 test = mapCheck(localMapDummy);
5885
5886 if(test == true) {
5887 localMapDummy->BC = globalStructuredBndryCndMaps[i]->BC;
5888 localMapDummy->Nstar = globalStructuredBndryCndMaps[i]->Nstar;
5889 localMapDummy->SingularId = globalStructuredBndryCndMaps[i]->SingularId;
5890 localMapDummy->dc1 = globalStructuredBndryCndMaps[i]->dc1;
5891 localMapDummy->dc2 = globalStructuredBndryCndMaps[i]->dc2;
5892 SndMapBC6000.push_back(std::move(localMapDummy));
5893 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5894 }
5895 }
5896 }
5897 }
5898
5899 // now 6000 and 4xxx communication bc are both in SndMapBC6000
5900
5904 // special treatment of singularities
5905 MInt singularPoint = (MInt)singularwindow.size();
5906 for(MInt i = 0; i < singularPoint; ++i) {
5907 for(MInt dim = 0; dim < nDim; ++dim) {
5908 singularwindow[i]->start1[dim] += m_noGhostLayers;
5909 singularwindow[i]->end1[dim] += m_noGhostLayers;
5910 // need also to change the opposite side
5911 singularwindow[i]->start2[dim] += m_noGhostLayers;
5912 singularwindow[i]->end2[dim] += m_noGhostLayers;
5913 }
5914 }
5915
5916
5917 for(MInt i = 0; i < singularPoint; ++i) {
5918 MInt singularcount = 0, limit = singularwindow[i]->Nstar - 3, cnt = 0;
5919
5920 std::set<MInt> BCs;
5921 if(singularwindow[i]->BC < 4400 || singularwindow[i]->BC >= 4410) {
5922 // all 6000er singularities have BC=-6000
5923 singularwindow[i]->BC = -6000;
5924 for(MInt t = 0; t < singularwindow[i]->Nstar; ++t) {
5925 if(singularwindow[i]->BCsingular[t] != 0) BCs.insert(-singularwindow[i]->BCsingular[t]);
5926 }
5927 singularwindow[i]->BCsingular[0] = 0;
5928 singularwindow[i]->BCsingular[1] = 0;
5929 }
5930
5931 for(MInt j = 0; j < (MInt)globalStructuredBndryCndMaps.size(); j++) {
5932 if((globalStructuredBndryCndMaps[j]->Nstar == 5 || globalStructuredBndryCndMaps[j]->Nstar == 6)
5933 && (globalStructuredBndryCndMaps[j]->BC <= -6000 && globalStructuredBndryCndMaps[j]->BC > -6010)
5934 && globalStructuredBndryCndMaps[j]->Nstar == singularwindow[i]->Nstar) {
5935 // if((globalStructuredBndryCndMaps[j]->Nstar==5||globalStructuredBndryCndMaps[j]->Nstar==6)&&globalStructuredBndryCndMaps[j]->BC==6000&&globalStructuredBndryCndMaps[j]->Nstar==singularwindow[i]->Nstar)
5936 // { //6000er-change
5937
5938 // TODO_SS labels:FV I am not sure if the following is always true
5939 if(singularwindow[i]->BC >= 4400 && singularwindow[i]->BC < 4410) mTerm(1, "ERROR 0");
5940
5941 MInt labell = 0;
5942 labell = mapCompare11(singularwindow[i], globalStructuredBndryCndMaps[j]);
5943 if(labell) {
5944 singularwindow[i]->SingularBlockId[singularcount] = globalStructuredBndryCndMaps[j]->Id2;
5945 if(BCs.size() == 1) {
5946 if(*BCs.cbegin() != globalStructuredBndryCndMaps[j]->BC) mTerm(1, "ERROR 1");
5947 singularwindow[i]->BCsingular[singularcount + 2] = *BCs.cbegin();
5948 } else {
5949 setBCsingular(singularwindow[i], globalStructuredBndryCndMaps[j], singularcount);
5950 }
5951 singularcount++;
5952 }
5953 }
5954 if(singularcount > limit)
5955 cout << "Important!! " << globalStructuredBndryCndMaps[j]->Nstar
5956 << " star check error!!!!!!!!!!!!!!!!!! check it !!!!!" << endl;
5957
5958 // set BCsingular[0] and BCsingular[1] in arbritary order
5959 if(globalStructuredBndryCndMaps[j]->Nstar == -1
5960 && (globalStructuredBndryCndMaps[j]->BC <= -6000 && globalStructuredBndryCndMaps[j]->BC > -6010)) {
5961 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
5962 mapCombine11(singularwindow[i], globalStructuredBndryCndMaps[j], localMapDummy);
5963 MBool test = false;
5964 test = mapCheck(localMapDummy);
5965 if(test) {
5966 singularwindow[i]->BCsingular[cnt++] = globalStructuredBndryCndMaps[j]->BC;
5967 }
5968 }
5969 }
5970
5971 if(cnt >= 3) mTerm(1, "");
5972 }
5973
5974 // if(domainId()==0)
5975 // {
5976 // for(MInt i=0; i<singularPoint; ++i) {
5977 // if (singularwindow[i]->BC>=6000 && singularwindow[i]->BC<6010) //(singularwindow[i]->BC==6000) //6000er-change
5978 // cout<< "singularmaps Id1: " << singularwindow[i]->Id1 << " Id2: " << singularwindow[i]->Id2 << " BC: " <<
5979 // singularwindow[i]->BC<<" "<< singularwindow[i]->start1[0] <<"-" << singularwindow[i]->end1[0]<< " "<<
5980 // singularwindow[i]->start1[1] <<"-" << singularwindow[i]->end1[1]<< " "<< singularwindow[i]->start1[2] <<"-"
5981 // << singularwindow[i]->end1[2]<< " ID: " <<singularwindow[i]->SingularBlockId[0]<<"
5982 // "<<singularwindow[i]->SingularBlockId[1]<< endl;
5983
5984 // }
5985 // }
5986
5987 /* if (domainId()==0) {
5988 cout << "MY TESTGLOBAL" << endl;
5989 for (MInt i = 0; i < (signed)globalStructuredBndryCndMaps.size(); ++i) {
5990 if (abs(globalStructuredBndryCndMaps[i]->BC)>=6000 && abs(globalStructuredBndryCndMaps[i]->BC<6010))
5991 mapPrint(globalStructuredBndryCndMaps[i]);
5992 }
5993 cout << "MY TEST SINGULAR" << endl;
5994 for (MInt i = 0; i < (signed)singularwindow.size(); ++i) {
5995 mapPrint(singularwindow[i]);
5996 }
5997 }*/
5998
5999 for(MInt i = 0; i < singularPoint; ++i) {
6000 mapCombine11(m_myMapWithoutGC, singularwindow[i], localMapDummy);
6001 MBool test = false;
6002 test = mapCheck(localMapDummy);
6003 localMapDummy->Nstar = singularwindow[i]->Nstar;
6004 localMapDummy->SingularId = singularwindow[i]->SingularId;
6005 for(MInt n = 0; n < 6; ++n) {
6006 localMapDummy->BCsingular[n] = singularwindow[i]->BCsingular[n];
6007 }
6008
6009 // // To distinguish between communication bcs and normal ones, do the following, negate the communication bcs
6010 // const MInt BC = (singularwindow[i]->BC>=6000 && singularwindow[i]->BC<6010) ? -singularwindow[i]->BC :
6011 // singularwindow[i]->BC;
6012 localMapDummy->BC = singularwindow[i]->BC;
6013
6014 localMapDummy->SingularBlockId[0] = singularwindow[i]->SingularBlockId[0];
6015 localMapDummy->SingularBlockId[1] = singularwindow[i]->SingularBlockId[1];
6016 localMapDummy->SingularBlockId[2] = singularwindow[i]->SingularBlockId[2];
6017 localMapDummy->SingularBlockId[3] = singularwindow[i]->SingularBlockId[3];
6018
6019 if(test == true) {
6020 localSingularMap.push_back(std::move(localMapDummy));
6021 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
6022 }
6023 }
6024
6025 *hasSingularity = (MInt)localSingularMap.size();
6026 singularPoint = (MInt)localSingularMap.size();
6027
6028 for(MInt i = 0; i < (MInt)localSingularMap.size(); ++i) {
6029 memcpy(singularity[i].start, localSingularMap[i]->start1, nDim * sizeof(MInt));
6030 memcpy(singularity[i].end, localSingularMap[i]->end1, nDim * sizeof(MInt));
6031 singularity[i].Nstar = localSingularMap[i]->Nstar;
6032 singularity[i].count = localSingularMap[i]->SingularId;
6033 singularity[i].BC = localSingularMap[i]->BC;
6034 for(MInt n = 0; n < 6; ++n) {
6035 singularity[i].BCsingular[n] = localSingularMap[i]->BCsingular[n];
6036 }
6037 singularity[i].SingularBlockId[0] = localSingularMap[i]->SingularBlockId[0];
6038 singularity[i].SingularBlockId[1] = localSingularMap[i]->SingularBlockId[1];
6039 singularity[i].SingularBlockId[2] = localSingularMap[i]->SingularBlockId[2];
6040 singularity[i].SingularBlockId[3] = localSingularMap[i]->SingularBlockId[3];
6041
6043 // for local singular map
6044 // BC6000: line only (no point and face) BC4000: point only.
6045
6046 if(localSingularMap[i]->BC >= 4400 && localSingularMap[i]->BC < 4410) {
6047 localSingularMap[i]->face = localSingularMap[i]->BC - 4401;
6048 } else {
6049 for(MInt k = 0; k < nDim; ++k) {
6050 if(localSingularMap[i]->start1[k] != localSingularMap[i]->end1[k]) {
6051 localSingularMap[i]->face = k * 2;
6052 }
6053 }
6054 }
6055
6056 MInt displace[nDim], dimcount = 0;
6057 MInt dimN = -1;
6058 MInt dimT1, dimT2;
6059 for(MInt k = 0; k < nDim; ++k) {
6060 if(singularity[i].start[k] == singularity[i].end[k]) {
6061 if(singularity[i].start[k] == 2) {
6062 displace[k] = -1;
6063 } else {
6064 displace[k] = 1;
6065 }
6066 dimcount++;
6067 } else {
6068 displace[k] = 0;
6069 dimN = k;
6070 }
6071 }
6072
6073 IF_CONSTEXPR(nDim == 2) {
6074 ASSERT(dimcount == 2, "Impossible!");
6075 dimN = 0;
6076 }
6077
6078 if(dimcount == 3) {
6079 if(localSingularMap[i]->face != -1) {
6080 dimN = localSingularMap[i]->face / 2;
6081 displace[dimN] = 0;
6082 // TODO_SS labels:FV take care of the next if-clause
6083 if(singularity[i].BC >= 6000
6084 && singularity[i].BC < 6010) { //(singularity[i].BC==6000) { //6000er-change ; what is the next line supposed
6085 // to do? 6003 is nowhere used!
6086 singularity[i].BC = 6003;
6087 }
6088 } else {
6089 cout << "ERROR!!! point singular communication cannot decide the direction!! check the singularity!!!" << endl;
6090 exit(0);
6091 }
6092 }
6093
6094 if(dimN == 0 && nDim != 2) {
6095 dimT1 = 1;
6096 dimT2 = 2;
6097 } else if(dimN == 1) {
6098 dimT1 = 0;
6099 dimT2 = 2;
6100 } else {
6101 dimT1 = 0;
6102 dimT2 = 1;
6103 } // this else clause is always true in 2D
6104
6105 switch(singularity[i].Nstar) {
6106 case 3: {
6107 // labels:FV bugs possibly exist
6108 singularity[i].displacement[0][dimN] = 0;
6109 singularity[i].displacement[0][dimT1] = displace[dimT1];
6110 singularity[i].displacement[0][dimT2] = 0;
6111
6112 singularity[i].displacement[1][dimN] = 0;
6113 singularity[i].displacement[1][dimT1] = 0;
6114 singularity[i].displacement[1][dimT2] = displace[dimT2];
6115
6116 break;
6117 }
6118 case 5: {
6120 // labels:FV bugs exist need to be fixed
6121 singularity[i].displacement[0][dimN] = 0;
6122 singularity[i].displacement[0][dimT1] = displace[dimT1];
6123 singularity[i].displacement[0][dimT2] = 0;
6124
6125 singularity[i].displacement[1][dimN] = 0;
6126 singularity[i].displacement[1][dimT1] = 0;
6127 singularity[i].displacement[1][dimT2] = displace[dimT2];
6128
6129 singularity[i].displacement[2][dimN] = 0;
6130 singularity[i].displacement[2][dimT1] = displace[dimT1];
6131 singularity[i].displacement[2][dimT2] = displace[dimT2];
6132
6133 singularity[i].displacement[3][dimN] = 0;
6134 singularity[i].displacement[3][dimT1] = 2 * displace[dimT1];
6135 singularity[i].displacement[3][dimT2] = 2 * displace[dimT2];
6136
6137
6138 // communication map change start from 2 to 3
6139 singularity[i].count = 2;
6140
6141 break;
6142 }
6143 case 6: {
6145 // labels:FV bugs exist need to be fixed
6146 singularity[i].displacement[0][dimN] = 0;
6147 singularity[i].displacement[0][dimT1] = displace[dimT1];
6148 singularity[i].displacement[0][dimT2] = 0;
6149
6150 singularity[i].displacement[1][dimN] = 0;
6151 singularity[i].displacement[1][dimT1] = 0;
6152 singularity[i].displacement[1][dimT2] = displace[dimT2];
6153
6154 singularity[i].displacement[2][dimN] = 0;
6155 singularity[i].displacement[2][dimT1] = displace[dimT1];
6156 singularity[i].displacement[2][dimT2] = displace[dimT2];
6157
6158 singularity[i].displacement[3][dimN] = 0;
6159 singularity[i].displacement[3][dimT1] = 2 * displace[dimT1];
6160 singularity[i].displacement[3][dimT2] = 2 * displace[dimT2];
6161
6162 singularity[i].displacement[4][dimN] = 0;
6163 singularity[i].displacement[4][dimT1] = displace[dimT1];
6164 singularity[i].displacement[4][dimT2] = 2 * displace[dimT2];
6165
6166
6167 // communication map change start from 2 to 3
6168 singularity[i].count = 2;
6169
6170 break;
6171 }
6172 default: {
6173 break;
6174 }
6175 }
6176 }
6177
6178 // expand the singularmap
6179 for(MInt i = 0; i < (MInt)localSingularMap.size(); ++i) {
6180 if(localSingularMap[i]->BC <= -6000
6181 && localSingularMap[i]->BC > -6010) //(localSingularMap[i]->BC==6000) //6000er-change
6182 {
6183 for(MInt k = 0; k < nDim; ++k) {
6184 if(localSingularMap[i]->start1[k] != localSingularMap[i]->end1[k]) {
6185 // if ( m_myMapWithoutGC->start2[k]==localSingularMap[i]->start1[k])
6186 {
6187 localSingularMap[i]->start1[k] -= 2;
6188 localSingularMap[i]->start2[k] -= 2;
6189 }
6190 // if ( m_myMapWithoutGC->end2[k]==localSingularMap[i]->end1[k])
6191 {
6192 localSingularMap[i]->end1[k] += 2;
6193 localSingularMap[i]->end2[k] += 2;
6194 }
6195 } // if !=
6196 } // for k
6197 } // if 6000
6198 }
6199
6200 /* for (MInt i = 0; i < (MInt)localSingularMap.size(); ++i) {
6201 cout << "SINGULARITY CHECK : d=" << domainId() << " Nstar=" << singularity[i].Nstar
6202 << " singularBlockId=" << singularity[i].SingularBlockId[0] << "|" <<
6203 singularity[i].SingularBlockId[1] << "|" << singularity[i].SingularBlockId[2] << "|" <<
6204 singularity[i].SingularBlockId[3]
6205 << " BC=" << singularity[i].BC << " BC_singularity=" << singularity[i].BCsingular[0] << "|" <<
6206 singularity[i].BCsingular[1] << "|" << singularity[i].BCsingular[2] << "|" << singularity[i].BCsingular[3]
6207 << " start=" << singularity[i].start[0] << "|" << singularity[i].start[1]
6208 << " end=" << singularity[i].end[0] << "|" << singularity[i].end[1] << endl;
6209 }*/
6210
6211 // first put multiblock communication maps into addCommBC,
6212 // afterwards also add the periodic communcation maps
6213
6214 vector<unique_ptr<StructuredWindowMap<nDim>>> periodicBC;
6215 vector<unique_ptr<StructuredWindowMap<nDim>>> addCommBC;
6216 MPI_Barrier(m_StructuredComm, AT_);
6217
6218 // auto& localMap = begin(localStructuredBndryCndMaps);
6219 for(auto& localMap : localStructuredBndryCndMaps) {
6220 const MInt BC = (localMap->BC <= -6000 && localMap->BC > -6010) ? 6000 : localMap->BC; // 6000er-change
6221 switch(BC) {
6222 case 4011: // periodic rotational 1
6223 case 4012: // periodic rotational 2
6224 case 4401: // periodic surface 1
6225 case 4402: // periodic surface 2
6226 case 4403:
6227 case 4404:
6228 case 4405:
6229 case 4406: {
6230 break;
6231 }
6232 case 6000: // additional block communication (interblock communication)
6233 {
6234 // save the additional Communication
6235 unique_ptr<StructuredWindowMap<nDim>> copy = make_unique<StructuredWindowMap<nDim>>();
6236 mapCpy(localMap, copy);
6237 addCommBC.push_back(std::move(copy));
6238 // localMap = localStructuredBndryCndMaps.erase(localMap);
6239 break;
6240 }
6241 case 2097: { // this is for the plenum inlet where we need the surface informations
6242 unique_ptr<StructuredWindowMap<nDim>> copy1 = make_unique<StructuredWindowMap<nDim>>();
6243 mapCpy(localMap, copy1);
6244 physicalBCMap.push_back(std::move(copy1));
6245
6246 unique_ptr<StructuredWindowMap<nDim>> copy2 = make_unique<StructuredWindowMap<nDim>>();
6247 mapCpy(localMap, copy2);
6248 plenumInletSurfaceIndices.push_back(std::move(copy2)); // needed for identifiaction of areas etc.
6249
6250 // localMap = localStructuredBndryCndMaps.erase(localMap);
6251 break;
6252 }
6253 case 2401:
6254 case 2402: // this is for the channel flow
6255 {
6256 // we need a copy of the map to find the channel In/Outflow parti-
6257 // cipating processors.
6258 unique_ptr<StructuredWindowMap<nDim>> copy1 = make_unique<StructuredWindowMap<nDim>>();
6259 mapCpy(localMap, copy1);
6260 physicalBCMap.push_back(std::move(copy1));
6261
6262 unique_ptr<StructuredWindowMap<nDim>> copy2 = make_unique<StructuredWindowMap<nDim>>();
6263 mapCpy(localMap, copy2);
6264 channelSurfaceIndices.push_back(std::move(copy2)); // needed for identifiaction of aereas etc.
6265
6266 // localMap = localStructuredBndryCndMaps.erase(localMap);
6267 break;
6268 }
6269 default: {
6270 unique_ptr<StructuredWindowMap<nDim>> copy = make_unique<StructuredWindowMap<nDim>>();
6271 mapCpy(localMap, copy);
6272 physicalBCMap.push_back(std::move(copy));
6273
6274 // localMap = localStructuredBndryCndMaps.erase(localMap);
6275 break;
6276 }
6277 }
6278 }
6279
6280 // localMap = begin(localStructuredBndryCndMaps);
6281 // while (localMap != end(localStructuredBndryCndMaps)) {
6282 for(auto& localMap : localStructuredBndryCndMaps) {
6283 switch(localMap->BC) {
6284 case 4011: // periodic rotational 1
6285 case 4012: // periodic rotational 2
6286 case 4401: // periodic surface 1
6287 case 4402: // periodic surface 2
6288 case 4403:
6289 case 4404:
6290 case 4405:
6291 case 4406: {
6292 // save the periodic boundary condition to addcommBC, same position
6293 unique_ptr<StructuredWindowMap<nDim>> copy = make_unique<StructuredWindowMap<nDim>>();
6294 mapCpy(localMap, copy);
6295 addCommBC.push_back(std::move(copy));
6296 break;
6297 }
6298 default: {
6299 // do nothing
6300 break;
6301 }
6302 }
6303 }
6304
6308 vector<MInt> plenumPartitions;
6309 MInt count = 1;
6310 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6311 if(globalStructuredBndryCndMaps[i]->BC == 2097) {
6312 // found a face containing the plenum inlet
6313 count++;
6314 // loop over all domains without ghost cells
6315 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6316 // check if boundary condition is contained
6317 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6318 MBool test = false;
6319 test = mapCheck(localMapDummy); // true if a match is found
6320 if(test) { // match is found
6321 plenumPartitions.push_back(m_partitionMapsWithoutGC[j]->Id2); // store the domainId
6322 }
6323 }
6324 }
6325 }
6326
6327 // get the ranks for building up a communicator
6328 vector<MInt> plenumInflow;
6329 if(plenumPartitions.size() != 0) {
6330 for(auto& plenumPartition : plenumPartitions) {
6331 // for(MInt i=0; i< plenumPartitions.size(); i++){
6332 for(MInt j = 0; j < noDomains(); j++) {
6333 if(plenumPartition == j) {
6334 plenumInflow.push_back(j);
6335 }
6336 }
6337 }
6338
6339 m_log << "Number of input partitions plenum Inlet " << plenumInflow.size() << endl;
6340 MPI_Group groupIn = MPI_GROUP_NULL;
6341 MPI_Group* newgroupIn = new MPI_Group;
6342 MPI_Comm_group(m_StructuredComm, &groupIn, AT_, "groupIn");
6343 MPI_Group_incl(groupIn, (MInt)plenumInflow.size(), plenumInflow.data(), newgroupIn, AT_);
6344 MPI_Comm_create(m_StructuredComm, newgroupIn[0], plenumComm, AT_, "plenumComm");
6345
6346 if(domainId() == plenumInflow[0]) {
6347 MPI_Comm_rank(plenumComm[0], &plenumRoot[0]);
6348 }
6349 MPI_Bcast(&plenumRoot[0], 1, MPI_INT, plenumInflow[0], m_StructuredComm, AT_, "plenumRoots[0]");
6350 }
6351
6355
6356 // creating the communicators
6357 vector<MInt> channelface;
6358 vector<MInt> channelpartitions;
6359 MInt anzahl = 1;
6360 MInt counterIn = 0;
6361 MInt counterOut = 0;
6362 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6363 if(globalStructuredBndryCndMaps[i]->BC == 2401 || globalStructuredBndryCndMaps[i]->BC == 2402) {
6364 // found a face containing the channel in/out flow
6365 // now check the partition it belongs to!!
6366 // cout << "found " << anzahl << endl;
6367 anzahl++;
6368 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6369 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6370 MBool test = false;
6371 test = mapCheck(localMapDummy);
6372 if(test == true) {
6373 channelpartitions.push_back(m_partitionMapsWithoutGC[j]->Id2);
6374 // partition contains part of the boundary
6375 // check the face
6376
6377 // now check the face
6378 if(globalStructuredBndryCndMaps[i]->BC == 2401) {
6379 channelface.push_back(globalStructuredBndryCndMaps[i]->BC);
6380 counterIn++;
6381 } else {
6382 channelface.push_back(globalStructuredBndryCndMaps[i]->BC);
6383 counterOut++;
6384 }
6385 }
6386 }
6387 }
6388 }
6389
6390 // now assign the ranks
6391 MIntScratchSpace channelInflow(counterIn, AT_, "channelInflow");
6392 MIntScratchSpace channelOutflow(counterOut, AT_, "channelInflow");
6393
6394 if(channelpartitions.size() != 0) {
6395 MInt counterI = 0, counterO = 0;
6396 for(MInt i = 0; i < (MInt)channelpartitions.size(); i++) {
6397 for(MInt j = 0; j < noDomains(); j++) {
6398 if(channelpartitions[i] == j) {
6399 if(channelface[i] == 2401) {
6400 channelInflow[counterI] = j;
6401 counterI++;
6402 }
6403 if(channelface[i] == 2402) {
6404 channelOutflow[counterO] = j;
6405 counterO++;
6406 }
6407 }
6408 }
6409 }
6410
6411
6412 m_log << "ChannelIn: " << counterI << " ChannelOut: " << counterOut << endl;
6413
6414 // create a communicator for the in- and the outflow
6415 // averaging process
6416 MPI_Group groupIn = MPI_GROUP_NULL;
6417 MPI_Group newgroupIn = MPI_GROUP_NULL;
6418 MPI_Group groupOut = MPI_GROUP_NULL;
6419 MPI_Group newgroupOut = MPI_GROUP_NULL;
6420
6421 MPI_Comm_group(m_StructuredComm, &groupIn, AT_, "groupIn");
6422 MPI_Comm_group(m_StructuredComm, &groupOut, AT_, "groupOut");
6423
6424 MPI_Group_incl(groupIn, counterIn, channelInflow.begin(), &newgroupIn, AT_);
6425 MPI_Comm_create(m_StructuredComm, newgroupIn, channelIn, AT_, "channelIn");
6426
6427 MPI_Group_incl(groupOut, counterOut, channelOutflow.begin(), &newgroupOut, AT_);
6428 MPI_Comm_create(m_StructuredComm, newgroupOut, channelOut, AT_, "channelOut");
6429
6430 // finally we need to create a overall channel surface communicator to distribute
6431 // the averaged values p & T
6432
6433 // create group of all in- and outflow participants
6434 // but pay attention to duplicates (one domain shares in- and outflow)
6435 MInt counterAll = 0;
6436 MInt* channelAll = new MInt[counterOut + counterIn];
6437 for(MInt i = 0; i < counterIn; i++) {
6438 channelAll[i] = channelInflow[i];
6439 counterAll++;
6440 }
6441 for(MInt i = 0; i < counterOut; i++) {
6442 MBool check = false;
6443 for(MInt j = 0; j < counterIn; ++j) {
6444 if(channelAll[j] == channelOutflow[i]) {
6445 check = true;
6446 cout << "ATTENTION: Skipping duplicate generation in channelAll" << endl;
6447 mTerm(1, "In some cases this causes undefined behavior");
6448 break;
6449 }
6450 }
6451 // if this domain is already in channelAll we must not insert it again
6452 if(!check) {
6453 channelAll[counterIn + i] = channelOutflow[i];
6454 counterAll++;
6455 }
6456 }
6457 MPI_Group groupAll = MPI_GROUP_NULL;
6458 MPI_Group newgroupAll = MPI_GROUP_NULL;
6459 MPI_Comm_group(m_StructuredComm, &groupAll, AT_, "groupAll");
6460 MPI_Group_incl(groupAll, (MInt)(counterAll), channelAll, &newgroupAll, AT_);
6461
6462 MPI_Comm_create(m_StructuredComm, newgroupAll, channelWorld, AT_, "channelWorld");
6463
6464 // for global exchange we need a root process
6465 if(domainId() == channelInflow[0]) {
6466 MPI_Comm_rank(*channelIn, &channelRoots[0]);
6467 MPI_Comm_rank(*channelWorld, &channelRoots[2]);
6468 }
6469 MPI_Barrier(m_StructuredComm, AT_);
6470 MPI_Bcast(&channelRoots[0], 1, MPI_INT, channelInflow[0], m_StructuredComm, AT_, "channelRoots[0]");
6471 MPI_Bcast(&channelRoots[2], 1, MPI_INT, channelInflow[0], m_StructuredComm, AT_, "channelRoots[2]");
6472
6473 if(domainId() == channelOutflow[0]) {
6474 MPI_Comm_rank(*channelOut, &channelRoots[1]);
6475 MPI_Comm_rank(*channelWorld, &channelRoots[3]);
6476 }
6477 MPI_Barrier(m_StructuredComm, AT_);
6478 MPI_Bcast(&channelRoots[1], 1, MPI_INT, channelOutflow[0], m_StructuredComm, AT_, "channelRoots[1]");
6479 MPI_Bcast(&channelRoots[3], 1, MPI_INT, channelOutflow[0], m_StructuredComm, AT_, "channelRoots[3]");
6480 }
6481
6485
6486 vector<MInt> rotatingface;
6487 vector<MInt> rotatingpartitions;
6488
6489 MInt noRotPartitions = 0;
6490 counterIn = 0;
6491 counterOut = 0;
6492
6493 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6494 if(globalStructuredBndryCndMaps[i]->BC == 4001
6495 || globalStructuredBndryCndMaps[i]->BC == 4002) { //== containing rotation info
6496 // found a face containing the per. rotation BC ==> which partition?
6497 noRotPartitions++;
6498 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6499 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6500 MBool test = false;
6501 test = mapCheck(localMapDummy);
6502 if(test == true) {
6503 rotatingpartitions.push_back(m_partitionMapsWithoutGC[j]->Id2);
6504 // partition contains part of the boundary
6505 if(globalStructuredBndryCndMaps[i]->BC == 4001) {
6506 rotatingface.push_back(globalStructuredBndryCndMaps[i]->BC);
6507 counterIn++;
6508 } else {
6509 rotatingface.push_back(globalStructuredBndryCndMaps[i]->BC);
6510 counterOut++;
6511 }
6512 }
6513 }
6514 }
6515 }
6516
6517 MInt* rotationOne = nullptr;
6518 MInt* rotationTwo = nullptr;
6519 if(rotatingpartitions.size() != 0) {
6520 MInt counterI = 0, counterO = 0;
6521 rotationOne = new MInt[counterIn];
6522 rotationTwo = new MInt[counterOut];
6523 for(MInt i = 0; i < (MInt)rotatingpartitions.size(); i++) {
6524 for(MInt j = 0; j < noDomains(); j++) {
6525 if(rotatingpartitions[i] == j) {
6526 if(rotatingface[i] == 4001) {
6527 rotationOne[counterI] = j;
6528 ++counterI;
6529 } else {
6530 rotationTwo[counterO] = j;
6531 counterO++;
6532 }
6533 }
6534 }
6535 }
6536 // check which group the processor is in
6537 perRotGroup = 0;
6538 for(MInt i = 0; i < counterI; ++i) {
6539 if(domainId() == rotationOne[i]) {
6540 perRotGroup = 1;
6541 break;
6542 }
6543 }
6544 for(MInt i = 0; i < counterO; ++i) {
6545 if(domainId() == rotationTwo[i]) {
6546 // Maybe domain is in both groups, then set to 3
6547 if(perRotGroup == 1)
6548 perRotGroup = 3;
6549 else
6550 perRotGroup = 2;
6551
6552 break;
6553 }
6554 }
6555
6556 // create a communicator for the two sides of the rotation BC
6557 MPI_Group groupOne = MPI_GROUP_NULL;
6558 MPI_Group* newgroupOne = new MPI_Group;
6559 MPI_Group groupTwo = MPI_GROUP_NULL;
6560 MPI_Group* newgroupTwo = new MPI_Group;
6561
6562 MPI_Comm_group(m_StructuredComm, &groupOne, AT_, "groupOne");
6563 MPI_Comm_group(m_StructuredComm, &groupTwo, AT_, "groupTwo");
6564
6565 MPI_Group_incl(groupOne, (MInt)counterIn, rotationOne, newgroupOne, AT_);
6566
6567 MPI_Comm_create(m_StructuredComm, *newgroupOne, commPerRotOne, AT_, "commPerRotOne");
6568
6569 MPI_Group_incl(groupTwo, (MInt)counterOut, rotationTwo, newgroupTwo, AT_);
6570
6571 MPI_Comm_create(m_StructuredComm, *newgroupTwo, commPerRotTwo, AT_, "commPerRotTwo");
6572
6573 // we also need one cross communicator containing all processors involved
6574 // in the periodic rotation boundary condition
6575
6576 MInt counterAll = 0;
6577 MInt* rotationAll = new MInt[counterOut + counterIn];
6578 for(MInt i = 0; i < counterIn; ++i) {
6579 rotationAll[i] = rotationOne[i];
6580 counterAll++;
6581 }
6582
6583 for(MInt i = 0; i < counterOut; ++i) {
6584 // check if this domain is already in rotationAll
6585 MBool check = false;
6586 for(MInt j = 0; j < counterIn; ++j) {
6587 if(rotationAll[j] == rotationTwo[i]) {
6588 check = true;
6589 cout << "ATTENTION: Skipping duplicate generation in rotationAll" << endl;
6590 break;
6591 }
6592 }
6593
6594 // if this domain is already in rotationAll we must not insert it again
6595 if(!check) {
6596 rotationAll[counterIn + i] = rotationTwo[i];
6597 counterAll++;
6598 }
6599 }
6600
6601 MPI_Group groupAll = MPI_GROUP_NULL;
6602 MPI_Group* newgroupAll = new MPI_Group;
6603
6604 MPI_Comm_group(m_StructuredComm, &groupAll, AT_, "groupAll");
6605 MPI_Group_incl(groupAll, (MInt)(counterAll), rotationAll, newgroupAll, AT_);
6606
6607 MPI_Comm_create(m_StructuredComm, *newgroupAll, commPerRotWorld, AT_, "commPerRotWorld");
6608
6609 // fix the root processes for the communication
6610 if(domainId() == rotationOne[0]) {
6611 MPI_Comm_rank(commPerRotOne[0], &rotationRoots[0]);
6612 MPI_Comm_rank(commPerRotWorld[0], &rotationRoots[2]);
6613 }
6614 MPI_Barrier(m_StructuredComm, AT_);
6615 MPI_Bcast(&rotationRoots[0], 1, MPI_INT, rotationOne[0], m_StructuredComm, AT_, "rotationRoots[0]");
6616 MPI_Bcast(&rotationRoots[2], 1, MPI_INT, rotationOne[0], m_StructuredComm, AT_, "rotationRoots[2]");
6617
6618 if(domainId() == rotationTwo[0]) {
6619 MPI_Comm_rank(commPerRotTwo[0], &rotationRoots[1]);
6620 MPI_Comm_rank(commPerRotWorld[0], &rotationRoots[3]);
6621 }
6622 MPI_Barrier(m_StructuredComm, AT_);
6623 MPI_Bcast(&rotationRoots[1], 1, MPI_INT, rotationTwo[0], m_StructuredComm, AT_, "rotationRoots[1]");
6624 MPI_Bcast(&rotationRoots[3], 1, MPI_INT, rotationTwo[0], m_StructuredComm, AT_, "rotationRoots[3]");
6625 }
6626
6627
6631
6632 /*
6633 Create the MPI Group for the STG methods that only includes those
6634 domains that are located at the STG inflow.
6635 */
6636
6637 vector<MInt> stgpartitions;
6638
6639 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6640 if(globalStructuredBndryCndMaps[i]->BC == 7909) {
6641 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6642 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6643 MBool test = false;
6644 test = mapCheck(localMapDummy);
6645 if(test == true) stgpartitions.push_back(m_partitionMapsWithoutGC[j]->Id2);
6646 }
6647 }
6648 }
6649
6650 MPI_Barrier(m_StructuredComm, AT_);
6651
6652 if(stgpartitions.size() != 0) {
6653 m_log << "STG domains: ";
6654 MInt counterstg = 0;
6655 MIntScratchSpace stgranks(stgpartitions.size(), "stgranks", AT_);
6656
6657 for(MInt i = 0; i < (MInt)stgpartitions.size(); i++) {
6658 for(MInt j = 0; j < noDomains(); j++) {
6659 if(stgpartitions[i] == j) {
6660 stgranks[counterstg] = j;
6661 counterstg++;
6662 m_log << j << ", ";
6663 }
6664 }
6665 }
6666 m_log << endl;
6667 m_log << "Total number of STG domains: " << counterstg << endl;
6668
6669 MPI_Barrier(m_StructuredComm, AT_);
6670
6671 MPI_Group groupStg, newgroupStg;
6672 MInt stgcommsize = (MInt)(stgpartitions.size());
6673
6674 MPI_Comm_group(m_StructuredComm, &groupStg, AT_, "groupStg");
6675 MPI_Group_incl(groupStg, stgcommsize, stgranks.begin(), &newgroupStg, AT_);
6676
6677 MPI_Comm_create(m_StructuredComm, newgroupStg, commStg, AT_, "commStg");
6678
6679 if(domainId() == stgranks[0]) {
6680 MPI_Comm_rank(*commStg, commStgRoot);
6681 MPI_Comm_rank(m_StructuredComm, commStgRootGlobal);
6682 }
6683
6684 MPI_Barrier(m_StructuredComm, AT_);
6685 MPI_Bcast(commStgRoot, 1, MPI_INT, stgranks[0], m_StructuredComm, AT_, "commStgRoot");
6686 MPI_Bcast(commStgRootGlobal, 1, MPI_INT, stgranks[0], m_StructuredComm, AT_, "commStgRootGlobal");
6687 }
6688
6689
6693 vector<MInt> bc2600partitions;
6694
6695 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6696 if(globalStructuredBndryCndMaps[i]->BC == 2600) {
6697 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6698 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6699 MBool test = false;
6700 test = mapCheck(localMapDummy);
6701 if(test == true) bc2600partitions.push_back(m_partitionMapsWithoutGC[j]->Id2);
6702 }
6703 }
6704 }
6705
6706 MPI_Barrier(m_StructuredComm, AT_);
6707
6708 MInt* bc2600ranks;
6709 if(bc2600partitions.size() != 0) {
6710 m_log << "bc2600 domains: ";
6711 MInt counterBC2600 = 0;
6712 bc2600ranks = new MInt[mMax(MInt(bc2600partitions.size()), 0)];
6713 for(MInt i = 0; i < (MInt)bc2600partitions.size(); i++) {
6714 for(MInt j = 0; j < noDomains(); j++) {
6715 if(bc2600partitions[i] == j) {
6716 bc2600ranks[counterBC2600] = j;
6717 counterBC2600++;
6718 m_log << j << ", ";
6719 }
6720 }
6721 }
6722 m_log << endl;
6723 m_log << "Total number of BC2600 domains: " << counterBC2600 << endl;
6724
6725 MPI_Barrier(m_StructuredComm, AT_);
6726
6727 MPI_Group groupBC2600, newgroupBC2600;
6728 MInt bc2600commsize = (MInt)(bc2600partitions.size());
6729
6730 MPI_Comm_group(m_StructuredComm, &groupBC2600, AT_, "groupBC2600");
6731 MPI_Group_incl(groupBC2600, bc2600commsize, bc2600ranks, &newgroupBC2600, AT_);
6732 MPI_Comm_create(m_StructuredComm, newgroupBC2600, commBC2600, AT_, "commBC2600");
6733
6734 if(domainId() == bc2600ranks[0]) {
6735 MPI_Comm_rank(commBC2600[0], &commBC2600Root[0]);
6736 MPI_Comm_rank(m_StructuredComm, &commBC2600RootGlobal[0]);
6737 }
6738
6739 MPI_Barrier(m_StructuredComm, AT_);
6740 MPI_Bcast(commBC2600Root, 1, MPI_INT, bc2600ranks[0], m_StructuredComm, AT_, "commBC2600Root");
6741 MPI_Bcast(commBC2600RootGlobal, 1, MPI_INT, bc2600ranks[0], m_StructuredComm, AT_, "commBC2600RootGlobal");
6742 }
6743
6744
6748 vector<MInt> rescalingCommGrPartitions;
6749 for(MInt i = 0; i < (MInt)globalStructuredBndryCndMaps.size(); i++) {
6750 if(globalStructuredBndryCndMaps[i]->BC == 2500 || globalStructuredBndryCndMaps[i]->BC == 2501) {
6751 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6752 mapCombine11(globalStructuredBndryCndMaps[i], m_partitionMapsWithoutGC[j], localMapDummy);
6753 MBool test = false;
6754 test = mapCheck(localMapDummy);
6755 if(test == true) {
6756 rescalingCommGrPartitions.push_back(m_partitionMapsWithoutGC[j]->Id2);
6757 }
6758 }
6759 }
6760 }
6761
6762 MPI_Barrier(m_StructuredComm, AT_);
6763
6764 MInt* rescalingCommGrRanks;
6765
6766 if(rescalingCommGrPartitions.size() != 0) {
6767 MInt counterCommGrRescaling = 0;
6768 rescalingCommGrRanks = new MInt[mMax(MInt(rescalingCommGrPartitions.size()), 0)];
6769 for(MInt i = 0; i < (MInt)rescalingCommGrPartitions.size(); i++) {
6770 for(MInt j = 0; j < noDomains(); j++) {
6771 if(rescalingCommGrPartitions[i] == j) {
6772 rescalingCommGrRanks[counterCommGrRescaling] = j;
6773 counterCommGrRescaling++;
6774 }
6775 }
6776 }
6777
6778 MPI_Barrier(m_StructuredComm, AT_);
6779 MPI_Group groupRescalingCommGr, newgroupRescalingCommGr;
6780 MInt rescalingCommGrCommsize = (MInt)(rescalingCommGrPartitions.size());
6781
6782 MPI_Comm_group(m_StructuredComm, &groupRescalingCommGr, AT_, "groupRescalingCommGr");
6783 MPI_Group_incl(groupRescalingCommGr, rescalingCommGrCommsize, rescalingCommGrRanks, &newgroupRescalingCommGr, AT_);
6784
6785 MPI_Comm_create(m_StructuredComm, newgroupRescalingCommGr, rescalingCommGrComm, AT_, "rescalingCommGrComm");
6786
6787 if(domainId() == rescalingCommGrRanks[0]) {
6788 MPI_Comm_rank(rescalingCommGrComm[0], &rescalingCommGrRoot[0]);
6789 MPI_Comm_rank(m_StructuredComm, &rescalingCommGrRootGlobal[0]);
6790 }
6791
6792 MPI_Barrier(m_StructuredComm, AT_);
6793 MPI_Bcast(rescalingCommGrRoot, 1, MPI_INT, rescalingCommGrRanks[0], m_StructuredComm, AT_, "rescalingCommGrRoot");
6794 MPI_Bcast(rescalingCommGrRootGlobal, 1, MPI_INT, rescalingCommGrRanks[0], m_StructuredComm, AT_,
6795 "rescalingCommGrRootGlobal");
6796 }
6797
6798 MPI_Barrier(m_StructuredComm, AT_);
6799
6803
6804 vector<unique_ptr<StructuredWindowMap<nDim>>> addComm6000Recv; // store the maps for the communication
6805 vector<unique_ptr<StructuredWindowMap<nDim>>> addComm6000Snd;
6806 vector<MInt> adjacentPartitionBC6000;
6807 // we do know from the addCommBC which side we possess but we need to search for the opposite side
6808 // and the partition containing the opposite side!!!
6809
6810 // correct indices only for local multiblock bc comm maps
6811 for(MInt i = 0; i < (MInt)addCommBC.size(); i++) {
6812 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
6813 MInt dimcount = 0;
6814 for(MInt dim = 0; dim < nDim; dim++) {
6815 if(addCommBC[i]->start1[dim] != addCommBC[i]->end1[dim]
6816 && (addCommBC[i]->BC <= -6000 && addCommBC[i]->BC > -6010)) { // 6000er-change
6817 if(addCommBC[i]->step2[addCommBC[i]->order[dim]] > 0) {
6818 // TODO_SS labels:FV the next if-clause and the following ones, are a first attempt to fix the bug, but
6819 // consistent treatment of corners etc. to have e.g. solutions which are independent of
6820 // particular block topologies is still necessary
6821 if(addCommBC[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
6822 addCommBC[i]->start1[dim] -= m_noGhostLayers;
6823 addCommBC[i]->start2[addCommBC[i]->order[dim]] -= m_noGhostLayers;
6824 }
6825 if(addCommBC[i]->end1[dim] == m_myMapWithoutGC->end2[dim]) {
6826 addCommBC[i]->end1[dim] += m_noGhostLayers;
6827 addCommBC[i]->end2[addCommBC[i]->order[dim]] += m_noGhostLayers;
6828 }
6829 } else {
6830 if(addCommBC[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
6831 addCommBC[i]->start1[dim] -= m_noGhostLayers;
6832 addCommBC[i]->start2[addCommBC[i]->order[dim]] += m_noGhostLayers;
6833 }
6834 if(addCommBC[i]->end1[dim] == m_myMapWithoutGC->end2[dim]) {
6835 addCommBC[i]->end1[dim] += m_noGhostLayers;
6836 addCommBC[i]->end2[addCommBC[i]->order[dim]] -= m_noGhostLayers;
6837 }
6838 }
6839 }
6840 if(addCommBC[i]->start1[dim] == addCommBC[i]->end1[dim]
6841 && (addCommBC[i]->BC <= -6000 && addCommBC[i]->BC > -6010)) // 6000er-change
6842 dimcount++;
6843 }
6844 // TODO labels:FV How is it in 2D?
6845 if(dimcount == 3) {
6846 cout << "error!!!!!! 0d surface found!! check it .... " << endl;
6847 }
6848
6849 // now compare the multiblock/periodic bc maps to all partitions
6850 for(MInt j = 0; j < (MInt)m_partitionMapsWithoutGC.size(); j++) {
6851 mapCombine21(addCommBC[i], m_partitionMapsWithoutGC[j], temp);
6852 temp->BC = addCommBC[i]->BC;
6853 temp->Nstar = addCommBC[i]->Nstar;
6854 temp->SingularId = addCommBC[i]->SingularId;
6855 temp->dc1 = addCommBC[i]->dc1;
6856 temp->dc2 = addCommBC[i]->dc2;
6857 MBool test = false;
6858
6859 if(addCommBC[i]->BC <= -6000 && addCommBC[i]->BC > -6010) //(addCommBC[i]->BC==6000) //6000er-change
6860 {
6861 if(dimcount == 1)
6862 test = mapCheck2d(temp);
6863 else if(dimcount == 2)
6864 test = mapCheck1d(temp);
6865 else if(dimcount == 3)
6866 test = mapCheck0d(temp);
6867 } else {
6868 test = mapCheck(temp); // map does exist
6869 }
6870 if(test == true) {
6871 addComm6000Recv.push_back(std::move(temp));
6872 adjacentPartitionBC6000.push_back(j);
6873 temp = make_unique<StructuredWindowMap<nDim>>();
6874 }
6875 }
6876 }
6877
6878
6879 // first correct the SndMapBC6000 only for multiblock by GC layers
6880 for(MInt i = 0; i < (MInt)SndMapBC6000.size(); i++) {
6881 MInt recvDom = -1;
6882 for(MInt j = 0; j < noDomains(); ++j) {
6883 if(SndMapBC6000[i]->Id2 == j) {
6884 recvDom = j;
6885 break;
6886 }
6887 }
6888 if(recvDom == -1) mTerm(1, "");
6889
6890 MInt dimcount = 0;
6891 for(MInt dim = 0; dim < nDim; dim++) {
6892 if(SndMapBC6000[i]->start1[dim] != SndMapBC6000[i]->end1[dim]
6893 && (SndMapBC6000[i]->BC <= -6000 && SndMapBC6000[i]->BC > -6010)) { // 6000er-change
6894 if(SndMapBC6000[i]->step2[SndMapBC6000[i]->order[dim]] > 0) {
6895 // TODO_SS labels:FV the next if-clause and the following ones, are a first attempt to fix the bug, but
6896 // consistent treatment of corners etc. to have e.g. solutions which are independent of
6897 // particular block topologies is still necessary
6898 if(SndMapBC6000[i]->start2[SndMapBC6000[i]->order[dim]]
6899 == m_partitionMapsWithoutGC[recvDom]->start2[SndMapBC6000[i]->order[dim]]) {
6900 SndMapBC6000[i]->start1[dim] -= m_noGhostLayers;
6901 SndMapBC6000[i]->start2[SndMapBC6000[i]->order[dim]] -= m_noGhostLayers;
6902 }
6903 if(SndMapBC6000[i]->end2[SndMapBC6000[i]->order[dim]]
6904 == m_partitionMapsWithoutGC[recvDom]->end2[SndMapBC6000[i]->order[dim]]) {
6905 SndMapBC6000[i]->end1[dim] += m_noGhostLayers;
6906 SndMapBC6000[i]->end2[SndMapBC6000[i]->order[dim]] += m_noGhostLayers;
6907 }
6908 } else {
6909 if(SndMapBC6000[i]->start2[SndMapBC6000[i]->order[dim]]
6910 == m_partitionMapsWithoutGC[recvDom]->end2[SndMapBC6000[i]->order[dim]]) {
6911 SndMapBC6000[i]->start1[dim] -= m_noGhostLayers;
6912 SndMapBC6000[i]->start2[SndMapBC6000[i]->order[dim]] += m_noGhostLayers;
6913 }
6914 if(SndMapBC6000[i]->end2[SndMapBC6000[i]->order[dim]]
6915 == m_partitionMapsWithoutGC[recvDom]->start2[SndMapBC6000[i]->order[dim]]) {
6916 SndMapBC6000[i]->end1[dim] += m_noGhostLayers;
6917 SndMapBC6000[i]->end2[SndMapBC6000[i]->order[dim]] -= m_noGhostLayers;
6918 }
6919 }
6920 }
6921 if(SndMapBC6000[i]->start1[dim] == SndMapBC6000[i]->end1[dim]
6922 && (SndMapBC6000[i]->BC <= -6000 && SndMapBC6000[i]->BC > -6010)) // 6000er-change
6923 dimcount++;
6924 }
6925 // TODO labels:FV How is it in 2D?
6926 if(dimcount == 3) {
6927 cout << "error!!!!!! 0d surface found!! check it .... " << endl;
6928 }
6929
6930 // now compare multiblock/periodic bc map (with ghost-cells) with own map (w/o ghost-cells)
6931 // for(MInt i=0; i<(MInt)SndMapBC6000.size(); i++) {
6932 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
6933
6934 mapCombine11(m_myMapWithoutGC, SndMapBC6000[i], temp);
6935 temp->BC = SndMapBC6000[i]->BC;
6936 temp->Nstar = SndMapBC6000[i]->Nstar;
6937 temp->SingularId = SndMapBC6000[i]->SingularId;
6938 temp->dc1 = SndMapBC6000[i]->dc1;
6939 temp->dc2 = SndMapBC6000[i]->dc2;
6940
6941 MBool test = false;
6942 if(SndMapBC6000[i]->BC <= -6000 && SndMapBC6000[i]->BC > -6010) //(SndMapBC6000[i]->BC==6000) //6000er-change
6943 {
6944 if(dimcount == 1)
6945 test = mapCheck2d(temp);
6946 else if(dimcount == 2)
6947 test = mapCheck1d(temp);
6948 else if(dimcount == 3)
6949 test = mapCheck0d(temp);
6950 } else {
6951 test = mapCheck(temp); // map does exist
6952 }
6953 if(test == true) {
6954 addComm6000Snd.push_back(std::move(temp));
6955 temp = make_unique<StructuredWindowMap<nDim>>();
6956 }
6957 }
6958
6959 // special treatment for certain cases where number of SND and RCV maps is unequal
6960 MInt count1[4] = {0, 0, 0, 0}, count2[4] = {0, 0, 0, 0};
6961 for(MInt i = 0; i < (MInt)addComm6000Snd.size(); ++i) {
6962 if((addComm6000Snd[i]->BC <= -6000 && addComm6000Snd[i]->BC > -6010)
6963 && addComm6000Snd[i]->Nstar == -1) // 6000er-change
6964 count1[0]++;
6965 else if((addComm6000Snd[i]->BC <= -6000 && addComm6000Snd[i]->BC > -6010)
6966 && addComm6000Snd[i]->Nstar != -1) // 6000er-change
6967 count1[1]++;
6968 else if(addComm6000Snd[i]->BC >= 4000 && addComm6000Snd[i]->BC < 5000 && addComm6000Snd[i]->Nstar == -1)
6969 count1[2]++;
6970 else if(addComm6000Snd[i]->BC >= 4000 && addComm6000Snd[i]->BC < 5000 && addComm6000Snd[i]->Nstar != -1)
6971 count1[3]++;
6972 }
6973 for(MInt i = 0; i < (MInt)addComm6000Recv.size(); ++i) {
6974 if((addComm6000Recv[i]->BC <= -6000 && addComm6000Recv[i]->BC > -6010)
6975 && addComm6000Recv[i]->Nstar == -1) // 6000er-change
6976 count2[0]++;
6977 else if((addComm6000Recv[i]->BC <= -6000 && addComm6000Recv[i]->BC > -6010)
6978 && addComm6000Recv[i]->Nstar != -1) // 6000er-change
6979 count2[1]++;
6980 else if(addComm6000Recv[i]->BC >= 4000 && addComm6000Recv[i]->BC < 5000 && addComm6000Recv[i]->Nstar == -1)
6981 count2[2]++;
6982 else if(addComm6000Recv[i]->BC >= 4000 && addComm6000Recv[i]->BC < 5000 && addComm6000Recv[i]->Nstar != -1)
6983 count2[3]++;
6984 }
6985
6986 MPI_Barrier(m_StructuredComm, AT_);
6987
6988
6992
6993 // determine faces of receiving maps
6994 // and make maps three-dimensional
6995 // RCV maps, no singularity
6996 for(MInt i = 0; i < (MInt)addComm6000Recv.size(); ++i) {
6997 if(addComm6000Recv[i]->Nstar == -1
6998 && (addComm6000Recv[i]->BC <= -6000 && addComm6000Recv[i]->BC > -6010)) { // 6000er-change
6999 unique_ptr<StructuredWindowMap<nDim>> tempRCV = make_unique<StructuredWindowMap<nDim>>();
7000 mapCpy(addComm6000Recv[i], tempRCV);
7001
7002 // IMPORTANT:
7003 // the faces are important for the unique send and rcv tags
7004 for(MInt dim = 0; dim < nDim; dim++) {
7005 if(addComm6000Recv[i]->step2[dim] < 0) {
7006 MInt haha = addComm6000Recv[i]->start2[dim];
7007 addComm6000Recv[i]->start2[dim] = addComm6000Recv[i]->end2[dim];
7008 addComm6000Recv[i]->end2[dim] = haha;
7009 }
7010 }
7011
7012 // check the side for the receiving parts and save the face
7013 for(MInt part = 0; part < (MInt)m_partitionMapsWithoutGC.size(); ++part) {
7014 if(addComm6000Recv[i]->Id2 == m_partitionMapsWithoutGC[part]->Id2) {
7015 for(MInt dim = 0; dim < nDim; dim++) {
7016 if(addComm6000Recv[i]->start2[dim] == addComm6000Recv[i]->end2[dim]) {
7017 switch(dim) {
7018 case 0: { // face 0 or 1
7019 // check if face 0 or 1
7020 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7021 // test of start2 instead of start1.
7022 tempRCV->face = 0;
7023 } else {
7024 tempRCV->face = 1;
7025 }
7026 break;
7027 }
7028 case 1: { // face 2 or 3
7029 // check if face 2 or 3
7030 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7031 tempRCV->face = 2;
7032 } else {
7033 tempRCV->face = 3;
7034 }
7035 break;
7036 }
7037 case 2: { // face 4 or 5
7038 // check if face 4 or 5
7039 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7040 tempRCV->face = 4;
7041 } else {
7042 tempRCV->face = 5;
7043 }
7044 break;
7045 }
7046 default: {
7047 cerr << "error no side could be attributed" << endl;
7048 exit(1);
7049 }
7050 }
7051 }
7052 }
7053 }
7054 }
7055
7056 // //check how many dimensions the map has
7057 // MInt mapDimension = 0;
7058 // for(MInt dim=0; dim<nDim; dim++) {
7059 // if(addComm6000Recv[i]->start1[dim]==addComm6000Recv[i]->end1[dim]) {
7060 // mapDimension++;
7061 // }
7062 // }
7063 // //this is a 2d face with one zero dimension
7064 // //in that case extend in both finite dimensions
7065 // if(mapDimension==1||mapDimension==2) {
7066 // for(MInt dim=0; dim<nDim; dim++) {
7067 // if(addComm6000Recv[i]->start1[dim]!=addComm6000Recv[i]->end1[dim]) {
7068 // tempRCV->start1[dim]-=m_noGhostLayers;
7069 // tempRCV->end1[dim]+=m_noGhostLayers;
7070 // }
7071 // }
7072 // }
7073
7074 // make the RCV maps three-dimensional
7075 for(MInt dim = 0; dim < nDim; dim++) {
7076 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7077 // values are the same:
7078 // change the send and receive values
7079 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7080 // we are on the start side of the domain
7081 tempRCV->start1[dim] -= m_noGhostLayers;
7082 } else {
7083 // we are at the end side of the domain
7084 tempRCV->end1[dim] += m_noGhostLayers;
7085 }
7086 }
7087 }
7088 tempRCV->BC = addComm6000Recv[i]->BC;
7089 rcvMap.push_back(std::move(tempRCV));
7090 }
7091 }
7092
7093
7094 // determine faces of receiving maps
7095 // and make maps three-dimensional
7096 // RCV maps, with singularity
7097 for(MInt i = 0; i < (MInt)addComm6000Recv.size(); ++i) {
7098 if(addComm6000Recv[i]->Nstar != -1
7099 && (addComm6000Recv[i]->BC <= -6000 && addComm6000Recv[i]->BC > -6010)) { // 6000er-change
7100 // unique_ptr<StructuredWindowMap<nDim>> tempSND= make_unique<StructuredWindowMap<nDim>>();
7101 unique_ptr<StructuredWindowMap<nDim>> tempRCV = make_unique<StructuredWindowMap<nDim>>();
7102 mapCpy(addComm6000Recv[i], tempRCV);
7103
7104 // IMPORTANT:
7105 // the faces are important for the unique send and rcv tags
7106 MInt dimcount = 0;
7107 for(MInt dim = 0; dim < nDim; dim++) {
7108 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7109 dimcount++;
7110 }
7111 }
7112
7113 if(dimcount == 2) {
7114 for(MInt dim = 0; dim < nDim; dim++) {
7115 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7116 // values are the same:
7117 // change the send and receive values
7118 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7119 // corner
7120 // rcv Maps:
7121 tempRCV->end1[dim] += 1;
7122 } else {
7123 // rcv Maps:
7124 tempRCV->start1[dim] -= 1;
7125 }
7126 } else {
7127 // line
7128 // rcv Maps:
7129 // tempRCV->start1[dim]-=m_noGhostLayers;
7130 // tempRCV->end1[dim] +=m_noGhostLayers;
7131 }
7132 }
7133 } else if(dimcount == 3) {
7134 MInt dimN;
7135 if(addComm6000Recv[i]->BC >= 4400 && addComm6000Recv[i]->BC < 4410) {
7136 addComm6000Recv[i]->face = addComm6000Recv[i]->BC - 4401;
7137 }
7138 if(addComm6000Recv[i]->face != -1) {
7139 dimN = addComm6000Recv[i]->face / 2;
7140 } else {
7141 cout << "ERROR!!! point singular communication cannot decide the direction!! check the singularity!!!"
7142 << endl;
7143 exit(0);
7144 }
7145
7146 for(MInt dim = 0; dim < nDim; dim++) {
7147 if(dim != dimN) {
7148 // values are the same:
7149 // change the send and receive values
7150 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7151 // corner
7152 // rcv Maps:
7153 tempRCV->end1[dim] += 1;
7154
7155 } else {
7156 // rcv Maps:
7157 tempRCV->start1[dim] -= 1;
7158 }
7159
7160 } else {
7161 // rcv Maps:
7162 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7163 // rcv Maps:
7164 tempRCV->start1[dim] -= 2;
7165
7166 } else {
7167 // rcv Maps:
7168 tempRCV->end1[dim] += 2;
7169 }
7170 }
7171 }
7172 }
7173
7174 for(MInt j = 0; j < singularPoint; ++j) {
7175 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
7176 /* MBool b = false;
7177 for (MInt n = 0; n < 6; ++n) {
7178 if (localSingularMap[j]->BCsingular[n]==addComm6000Recv[i]->BC)
7179 b = true;
7180 }*/
7181 if(localSingularMap[j]->BC == addComm6000Recv[i]->BC) {
7182 // if (b) {
7183 // TODO_SS labels:FV,toenhance temporary fix. Check if there is a better way
7184 const MInt temporary = localSingularMap[j]->Id1;
7185 localSingularMap[j]->Id1 = m_grid->getBlockId(domainId());
7186 mapCombine11(localSingularMap[j], addComm6000Recv[i], temp);
7187 localSingularMap[j]->Id1 = temporary;
7188 }
7189 MBool test = false;
7190 test = mapCheck(temp); // map does exist
7191 if(test == true) {
7192 MInt Recvblock = m_grid->getBlockId(addComm6000Recv[i]->Id2);
7193 MInt singnumber = -1;
7194 for(MInt k = 0; k < addComm6000Recv[i]->Nstar - 3; k++) {
7195 if(Recvblock == singularity[j].SingularBlockId[k]) {
7196 singnumber = k;
7197 break;
7198 }
7199 }
7200
7201 // if (Recvblock== singularity[j].SingularBlockId[0] )
7202 // singnumber=0;
7203 // else if (Recvblock== singularity[j].SingularBlockId[1] )
7204 // singnumber=1;
7205 if(singnumber == -1) {
7206 cout << "ERROR!!!!!!!!can not find the correct the displacement!!!!!!" << endl;
7207 cout << "recvid2:" << addComm6000Recv[i]->Id2 << " recvblock:" << Recvblock
7208 << " id:" << singularity[j].SingularBlockId[0] << " " << singularity[j].SingularBlockId[1] << endl;
7209 }
7210
7211 // MInt singnumber=addComm6000Recv[i]->Nstar;
7212 for(MInt dim = 0; dim < nDim; dim++) {
7213 tempRCV->start1[dim] += singularity[j].displacement[singnumber + 2][dim];
7214 tempRCV->end1[dim] += singularity[j].displacement[singnumber + 2][dim];
7215 }
7216 tempRCV->BCsingular[0] = singularity[j].BCsingular[singnumber + 2];
7217 // singularity[j].count++;
7218 tempRCV->SingularId = j;
7219 break;
7220 }
7221 }
7222
7223 tempRCV->face = 100;
7224
7225 if(addComm6000Recv[i]->BC >= 4000 && addComm6000Recv[i]->BC < 5000) {
7226 tempRCV->BC = addComm6000Recv[i]->BC;
7227 } else {
7228 tempRCV->BC = 6333;
7229 }
7230 rcvMap.push_back(std::move(tempRCV));
7231 }
7232 }
7233
7234 // determine faces of receiving maps
7235 // and make maps three-dimensional
7236 // SND maps, no singularity
7237 for(MInt i = 0; i < (MInt)addComm6000Snd.size(); i++) {
7238 if(addComm6000Snd[i]->Nstar == -1
7239 && (addComm6000Snd[i]->BC <= -6000 && addComm6000Snd[i]->BC > -6010)) { // 6000er-change
7240 unique_ptr<StructuredWindowMap<nDim>> tempSND = make_unique<StructuredWindowMap<nDim>>();
7241 mapCpy(addComm6000Snd[i], tempSND);
7242 // IMPORTANT:
7243 // the faces are important for the unique send and rcv tags
7244 // first check the side for the sending parts
7245 for(MInt dim = 0; dim < nDim; dim++) {
7246 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7247 switch(dim) {
7248 case 0: { // face 0 or 1
7249 // check if face 0 or 1
7250 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7251 // test of start2 instead of start1.
7252 tempSND->face = 0;
7253 } else {
7254 tempSND->face = 1;
7255 }
7256 break;
7257 }
7258 case 1: { // face 2 or 3
7259 // check if face 2 or 3
7260 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7261 tempSND->face = 2;
7262 } else {
7263 tempSND->face = 3;
7264 }
7265 break;
7266 }
7267 case 2: { // face 4 or 5
7268 // check if face 4 or 5
7269 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7270 tempSND->face = 4;
7271 } else {
7272 tempSND->face = 5;
7273 }
7274 break;
7275 }
7276 default: {
7277 cerr << "error no side could be attributed" << endl;
7278 exit(1);
7279 }
7280 }
7281 }
7282 }
7283
7284 for(MInt dim = 0; dim < nDim; dim++) {
7285 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7286 // values are the same:
7287 // change the send and receive values
7288 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7289 // we are on the start side of the domain
7290 tempSND->end1[dim] += m_noGhostLayers;
7291 } else {
7292 // we are at the end side of the domain
7293 tempSND->start1[dim] -= m_noGhostLayers;
7294 }
7295 }
7296 }
7297
7298 tempSND->BC = addComm6000Snd[i]->BC;
7299 sndMap.push_back(std::move(tempSND));
7300 }
7301 }
7302
7303 // determine faces of receiving maps
7304 // and make maps three-dimensional
7305 // SND maps, with singularity
7306 for(MInt i = 0; i < (MInt)addComm6000Snd.size(); i++) {
7307 if(addComm6000Snd[i]->Nstar != -1
7308 && (addComm6000Snd[i]->BC <= -6000 && addComm6000Snd[i]->BC > -6010)) { // 6000er-change
7309 unique_ptr<StructuredWindowMap<nDim>> tempSND = make_unique<StructuredWindowMap<nDim>>();
7310 mapCpy(addComm6000Snd[i], tempSND);
7311
7312 MInt dimcount = 0;
7313 for(MInt dim = 0; dim < nDim; dim++) {
7314 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7315 dimcount++;
7316 }
7317 }
7318
7319 if(dimcount == 2) {
7320 for(MInt dim = 0; dim < nDim; dim++) {
7321 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7322 // values are the same:
7323 // change the send and receive values
7324 // corner
7325 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7326 // snd Maps:
7327 tempSND->end1[dim] += 1;
7328 } else {
7329 // snd Maps:
7330 tempSND->start1[dim] -= 1;
7331 }
7332 } else {
7333 // line
7334 // snd Maps:
7335 // tempSND->start1[dim]-=m_noGhostLayers;
7336 // tempSND->end1[dim]+=m_noGhostLayers;
7337 }
7338 }
7339 } else if(dimcount == 3) {
7340 MInt dimN;
7341 if(addComm6000Snd[i]->BC >= 4400 && addComm6000Snd[i]->BC < 4410) {
7342 addComm6000Snd[i]->face = addComm6000Snd[i]->BC - 4401;
7343 }
7344 if(addComm6000Snd[i]->face != -1) {
7345 dimN = addComm6000Snd[i]->face / 2;
7346 } else {
7347 cout << "erroor!!! point singular communication cannot decide the direction!! check the singylairy!!!!!!"
7348 << endl;
7349 exit(0);
7350 }
7351
7352 for(MInt dim = 0; dim < nDim; dim++) {
7353 if(dim != dimN) {
7354 // values are the same:
7355 // change the send and receive values
7356 // corner
7357 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7358 // rcv Maps:
7359 tempSND->end1[dim] += 1;
7360 } else {
7361 // rcv Maps:
7362 tempSND->start1[dim] -= 1;
7363 }
7364 } else {
7365 // line
7366 // rcv Maps:
7367 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7368 // rcv Maps:
7369 tempSND->end1[dim] += 2;
7370
7371 } else {
7372 // rcv Maps:
7373 tempSND->start1[dim] -= 2;
7374 }
7375 }
7376 }
7377 }
7378
7379 for(MInt j = 0; j < singularPoint; ++j) {
7380 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
7381 if(localSingularMap[j]->BC == addComm6000Snd[i]->BC) {
7382 // TODO_SS labels:FV,toenhance temporary fix. Check if there is a better way
7383 const MInt temporary = localSingularMap[j]->Id1;
7384 localSingularMap[j]->Id1 = m_grid->getBlockId(domainId());
7385 mapCombine11(localSingularMap[j], addComm6000Snd[i], temp);
7386 localSingularMap[j]->Id1 = temporary;
7387 }
7388 MBool test = false;
7389 test = mapCheck(temp); // map does exist
7390 if(test == true) {
7391 MInt Recvblock = m_grid->getBlockId(addComm6000Snd[i]->Id2);
7392 MInt singnumber = -1;
7393 for(MInt k = 0; k < addComm6000Snd[i]->Nstar - 3; k++) {
7394 if(Recvblock == singularity[j].SingularBlockId[k]) {
7395 singnumber = k;
7396 break;
7397 }
7398 }
7399
7400 // if (Recvblock== singularity[j].SingularBlockId[0] )
7401 // singnumber=0;
7402 // else if (Recvblock== singularity[j].SingularBlockId[1] )
7403 // singnumber=1;
7404 if(singnumber == -1) {
7405 cout << "ERROR!!!!!!!!can not find the correct the displacement!!!!!!" << endl;
7406 cout << "recvid2:" << addComm6000Snd[i]->Id2 << " recvblock:" << Recvblock
7407 << " id:" << singularity[j].SingularBlockId[0] << " " << singularity[j].SingularBlockId[1] << endl;
7408 }
7409
7410 tempSND->BCsingular[0] = singularity[j].BCsingular[singnumber + 2];
7411 // singularity[j].count++;
7412 tempSND->SingularId = j;
7413 break;
7414 }
7415 }
7416
7417 tempSND->face = 100;
7418
7419 if(addComm6000Snd[i]->BC >= 4000 && addComm6000Snd[i]->BC < 5000) {
7420 tempSND->BC = addComm6000Snd[i]->BC;
7421 } else {
7422 tempSND->BC = 6333;
7423 }
7424
7425 sndMap.push_back(std::move(tempSND));
7426 }
7427 }
7428
7432
7433 // determine faces of receiving maps
7434 // and make maps three-dimensional
7435 // RCV maps, no singularity
7436 for(MInt i = 0; i < (MInt)addComm6000Recv.size(); ++i) {
7437 if(addComm6000Recv[i]->Nstar == -1
7438 && (addComm6000Recv[i]->BC > -6000 || addComm6000Recv[i]->BC <= -6010)) { // 6000er-change
7439 unique_ptr<StructuredWindowMap<nDim>> tempRCV = make_unique<StructuredWindowMap<nDim>>();
7440 mapCpy(addComm6000Recv[i], tempRCV);
7441
7442 // IMPORTANT:
7443 // the faces are important for the unique send and rcv tags
7444 for(MInt dim = 0; dim < nDim; dim++) {
7445 if(addComm6000Recv[i]->step2[dim] < 0) {
7446 MInt tmp = addComm6000Recv[i]->start2[dim];
7447 addComm6000Recv[i]->start2[dim] = addComm6000Recv[i]->end2[dim];
7448 addComm6000Recv[i]->end2[dim] = tmp;
7449 }
7450 }
7451 // check the side for the receiving parts
7452 for(MInt part = 0; part < (MInt)m_partitionMapsWithoutGC.size(); ++part) {
7453 if(addComm6000Recv[i]->Id2 == m_partitionMapsWithoutGC[part]->Id2) {
7454 for(MInt dim = 0; dim < nDim; dim++) {
7455 if(addComm6000Recv[i]->start2[dim] == addComm6000Recv[i]->end2[dim]) {
7456 switch(dim) {
7457 case 0: { // face 0 or 1
7458 // check if face 0 or 1
7459 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7460 // test of start2 instead of start1.
7461 tempRCV->face = 0;
7462 } else {
7463 tempRCV->face = 1;
7464 }
7465 break;
7466 }
7467 case 1: { // face 2 or 3
7468 // check if face 2 or 3
7469 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7470 tempRCV->face = 2;
7471 } else {
7472 tempRCV->face = 3;
7473 }
7474 break;
7475 }
7476 case 2: { // face 4 or 5
7477 // check if face 4 or 5
7478 if(addComm6000Recv[i]->start2[dim] == m_partitionMapsWithoutGC[part]->start2[dim]) {
7479 tempRCV->face = 4;
7480 } else {
7481 tempRCV->face = 5;
7482 }
7483 break;
7484 }
7485 default: {
7486 cerr << "error no side could be attributed" << endl;
7487 exit(1);
7488 }
7489 }
7490 }
7491 }
7492 }
7493 }
7494
7495 // check how many dimensions the map has
7496 MInt mapDimension = 0;
7497 for(MInt dim = 0; dim < nDim; dim++) {
7498 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7499 mapDimension++;
7500 }
7501 }
7502
7503 // this is a 2d face with one zero dimension
7504 // in that case extend in both finite dimensions
7505 if(mapDimension == 1) {
7506 for(MInt dim = 0; dim < nDim; dim++) {
7507 if(addComm6000Recv[i]->start1[dim] != addComm6000Recv[i]->end1[dim]) {
7508 tempRCV->start1[dim] -= m_noGhostLayers;
7509 tempRCV->end1[dim] += m_noGhostLayers;
7510 }
7511 }
7512 }
7513
7514 // now thicken the map:
7515 // point: thicken in all three dimensions
7516 // line: thicken in two zero dimensions
7517 // face: thicken in the only zero dimension
7518 for(MInt dim = 0; dim < nDim; dim++) {
7519 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7520 // values are the same:
7521 // change the send and receive values
7522 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7523 // we are on the start side of the domain
7524 // rcv Maps:
7525 tempRCV->start1[dim] -= m_noGhostLayers;
7526 } else {
7527 // we are at the end side of the domain
7528 // rcv Maps:
7529 tempRCV->end1[dim] += m_noGhostLayers;
7530 }
7531 }
7532 }
7533
7534 tempRCV->BC = addComm6000Recv[i]->BC;
7535 rcvMap.push_back(std::move(tempRCV));
7536 }
7537 }
7538
7539 // determine faces of receiving maps
7540 // and make maps three-dimensional
7541 // RCV maps, with singularity
7542 for(MInt i = 0; i < (MInt)addComm6000Recv.size(); ++i) {
7543 if(addComm6000Recv[i]->Nstar != -1
7544 && (addComm6000Recv[i]->BC > -6000 || addComm6000Recv[i]->BC <= -6010)) { // 6000er-change
7545 unique_ptr<StructuredWindowMap<nDim>> tempRCV = make_unique<StructuredWindowMap<nDim>>();
7546 mapCpy(addComm6000Recv[i], tempRCV);
7547
7548 // IMPORTANT:
7549 // the faces are important for the unique send and rcv tags
7550 MInt dimcount = 0;
7551 for(MInt dim = 0; dim < nDim; dim++) {
7552 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7553 dimcount++;
7554 }
7555 }
7556
7557 if(dimcount == 2) {
7558 for(MInt dim = 0; dim < nDim; dim++) {
7559 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7560 // values are the same:
7561 // change the send and receive values
7562 // corner
7563 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7564 // rcv Maps:
7565 tempRCV->end1[dim] += 1;
7566 } else {
7567 // rcv Maps:
7568 tempRCV->start1[dim] -= 1;
7569 }
7570 } else {
7571 // line
7572 // rcv Maps:
7573 tempRCV->start1[dim] -= m_noGhostLayers;
7574 tempRCV->end1[dim] += m_noGhostLayers;
7575 }
7576 }
7577 } else if(dimcount == 3) {
7578 MInt dimN;
7579 if(addComm6000Recv[i]->BC >= 4400 && addComm6000Recv[i]->BC < 4410) {
7580 addComm6000Recv[i]->face = addComm6000Recv[i]->BC - 4401;
7581 }
7582 if(addComm6000Recv[i]->face != -1) {
7583 dimN = addComm6000Recv[i]->face / 2;
7584 } else {
7585 cout << "erroor!!! point singular communication cannot decide the direction!! check the singylairy!!!!!!"
7586 << endl;
7587 exit(0);
7588 }
7589
7590 for(MInt dim = 0; dim < nDim; dim++) {
7591 if(dim != dimN) {
7592 // values are the same:
7593 // change the send and receive values
7594 // corner
7595 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7596 // rcv Maps:
7597 tempRCV->end1[dim] += 1;
7598 } else {
7599 // rcv Maps:
7600 tempRCV->start1[dim] -= 1;
7601 }
7602 } else {
7603 // line
7604 // rcv Maps:
7605 if(addComm6000Recv[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7606 // corner
7607 // rcv Maps:
7608 tempRCV->start1[dim] -= 2;
7609 } else {
7610 // rcv Maps:
7611 tempRCV->end1[dim] += 2;
7612 }
7613 }
7614 }
7615 }
7616
7617 for(MInt j = 0; j < singularPoint; ++j) {
7618 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
7619 if(localSingularMap[j]->BC == addComm6000Recv[i]->BC)
7620 mapCombine11(localSingularMap[j], addComm6000Recv[i], temp);
7621 MBool test = false;
7622 test = mapCheck(temp); // map does exist
7623 if(test == true) {
7624 // communication map change start from 2 to 3
7625 MInt singnumber = singularity[j].count;
7626 // MInt singnumber=addComm6000Recv[i]->Nstar;
7627 for(MInt dim = 0; dim < nDim; dim++) {
7628 tempRCV->start1[dim] += singularity[j].displacement[singnumber][dim];
7629 tempRCV->end1[dim] += singularity[j].displacement[singnumber][dim];
7630 }
7631 singularity[j].count++;
7632 tempRCV->SingularId = j;
7633 break;
7634 }
7635 }
7636
7637 tempRCV->face = 100;
7638
7639 if(addComm6000Recv[i]->BC >= 4000 && addComm6000Recv[i]->BC < 5000) {
7640 tempRCV->BC = addComm6000Recv[i]->BC;
7641 } else {
7642 tempRCV->BC = 6333;
7643 }
7644
7645 rcvMap.push_back(std::move(tempRCV));
7646 }
7647 }
7648
7649 // determine faces of receiving maps
7650 // and make maps three-dimensional
7651 // SND maps, no singularity
7652 for(MInt i = 0; i < (MInt)addComm6000Snd.size(); i++) {
7653 if(addComm6000Snd[i]->Nstar == -1
7654 && (addComm6000Snd[i]->BC > -6000 || addComm6000Snd[i]->BC <= -6010)) { // 6000er-change
7655 unique_ptr<StructuredWindowMap<nDim>> tempSND = make_unique<StructuredWindowMap<nDim>>();
7656 mapCpy(addComm6000Snd[i], tempSND);
7657 // IMPORTANT:
7658 // the faces are important for the unique send and rcv tags
7659
7660 // first check the side for the sending parts
7661 for(MInt dim = 0; dim < nDim; dim++) {
7662 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7663 switch(dim) {
7664 case 0: { // face 0 or 1
7665 // check if face 0 or 1
7666 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7667 // test of start2 instead of start1.
7668 tempSND->face = 0;
7669 } else {
7670 tempSND->face = 1;
7671 }
7672 break;
7673 }
7674 case 1: { // face 2 or 3
7675 // check if face 2 or 3
7676 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7677 tempSND->face = 2;
7678 } else {
7679 tempSND->face = 3;
7680 }
7681 break;
7682 }
7683 case 2: { // face 4 or 5
7684 // check if face 4 or 5
7685 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7686 tempSND->face = 4;
7687 } else {
7688 tempSND->face = 5;
7689 }
7690 break;
7691 }
7692 default: {
7693 cerr << "error no side could be attributed" << endl;
7694 exit(1);
7695 }
7696 }
7697 }
7698 }
7699
7700 // check how many dimensions the map has
7701 MInt mapDimension = 0;
7702 for(MInt dim = 0; dim < nDim; dim++) {
7703 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7704 mapDimension++;
7705 }
7706 }
7707
7708 // this is a 2d face with one zero dimension
7709 // in that case extend in both finite dimensions
7710 if(mapDimension == 1) {
7711 for(MInt dim = 0; dim < nDim; dim++) {
7712 if(addComm6000Snd[i]->start1[dim] != addComm6000Snd[i]->end1[dim]) {
7713 // if(tempSND->end1[dim]-tempSND->start1[dim]!=m_noGhostLayers) {
7714 tempSND->start1[dim] -= m_noGhostLayers;
7715 tempSND->end1[dim] += m_noGhostLayers;
7716 // }
7717 }
7718 }
7719 }
7720
7721 // now thicken the map:
7722 // point: thicken in all three dimensions
7723 // line: thicken in two zero dimensions
7724 // face: thicken in the only zero dimension
7725 for(MInt dim = 0; dim < nDim; dim++) {
7726 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7727 // values are the same:
7728 // change the send and receive values
7729 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7730 // we are on the start side of the domain
7731 // snd Maps:
7732 tempSND->end1[dim] += m_noGhostLayers;
7733 } else {
7734 // we are at the end side of the domain
7735 // snd Maps:
7736 tempSND->start1[dim] -= m_noGhostLayers;
7737 }
7738 }
7739 }
7740
7741 tempSND->BC = addComm6000Snd[i]->BC;
7742 sndMap.push_back(std::move(tempSND));
7743 }
7744 }
7745
7746 // determine faces of receiving maps
7747 // and make maps three-dimensional
7748 // SND maps, with singularity
7749 for(MInt i = 0; i < (MInt)addComm6000Snd.size(); i++) {
7750 if(addComm6000Snd[i]->Nstar != -1
7751 && (addComm6000Snd[i]->BC > -6000 || addComm6000Snd[i]->BC <= -6010)) { // 6000er-change
7752 unique_ptr<StructuredWindowMap<nDim>> tempSND = make_unique<StructuredWindowMap<nDim>>();
7753 mapCpy(addComm6000Snd[i], tempSND);
7754
7755 MInt dimcount = 0;
7756 for(MInt dim = 0; dim < nDim; dim++) {
7757 if(addComm6000Recv[i]->start1[dim] == addComm6000Recv[i]->end1[dim]) {
7758 dimcount++;
7759 }
7760 }
7761
7762 if(dimcount == 2) {
7763 for(MInt dim = 0; dim < nDim; dim++) {
7764 if(addComm6000Snd[i]->start1[dim] == addComm6000Snd[i]->end1[dim]) {
7765 // values are the same:
7766 // change the send and receive values
7767 // corner
7768 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7769 // snd Maps:
7770 tempSND->end1[dim] += 1;
7771 } else {
7772 // snd Maps:
7773 tempSND->start1[dim] -= 1;
7774 }
7775 } else {
7776 // line
7777 // snd Maps:
7778 tempSND->start1[dim] -= m_noGhostLayers;
7779 tempSND->end1[dim] += m_noGhostLayers;
7780 }
7781 }
7782 } else if(dimcount == 3) {
7783 MInt dimN;
7784 if(addComm6000Snd[i]->BC >= 4400 && addComm6000Snd[i]->BC < 4410) {
7785 addComm6000Snd[i]->face = addComm6000Snd[i]->BC - 4401;
7786 }
7787 if(addComm6000Snd[i]->face != -1) {
7788 dimN = addComm6000Snd[i]->face / 2;
7789 } else {
7790 cout << "erroor!!! point singular communication cannot decide the direction!! check the singylairy!!!!!!"
7791 << endl;
7792 exit(0);
7793 }
7794
7795 for(MInt dim = 0; dim < nDim; dim++) {
7796 if(dim != dimN) {
7797 // values are the same:
7798 // change the send and receive values
7799 // corner
7800 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7801 // rcv Maps:
7802 tempSND->end1[dim] += 1;
7803 } else {
7804 // rcv Maps:
7805 tempSND->start1[dim] -= 1;
7806 }
7807 } else {
7808 // line
7809 // rcv Maps:
7810 if(addComm6000Snd[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7811 // corner
7812 // rcv Maps:
7813 tempSND->end1[dim] += 2;
7814 } else {
7815 // rcv Maps:
7816 tempSND->start1[dim] -= 2;
7817 }
7818 }
7819 }
7820 }
7821
7822 tempSND->face = 100;
7823
7824 if(addComm6000Snd[i]->BC >= 4000 && addComm6000Snd[i]->BC < 5000) {
7825 tempSND->BC = addComm6000Snd[i]->BC;
7826 } else {
7827 tempSND->BC = 6333;
7828 }
7829
7830 sndMap.push_back(std::move(tempSND));
7831 }
7832 }
7833
7837
7838 for(MInt i = 0; i < singularPoint; ++i) {
7839 for(MInt dim = 0; dim < nDim; dim++) {
7840 singularity[i].Viscous[dim] = 0;
7841
7842 if(singularity[i].start[dim] == singularity[i].end[dim]) {
7843 // values are the same:
7844 if(singularity[i].start[dim] == m_myMapWithoutGC->start2[dim]) {
7845 // corner
7846 singularity[i].end[dim] += 1;
7847 singularity[i].Viscous[dim] = -1;
7848 } else {
7849 singularity[i].start[dim] -= 1;
7850 }
7851 } else {
7852 singularity[i].start[dim] -= m_noGhostLayers;
7853 singularity[i].end[dim] += m_noGhostLayers;
7854 }
7855 }
7856 }
7857
7858 //=============> now the snd and rcv maps contain the following order
7859 // 1) all the communication because of partitioning
7860 // 2) communication to other partition/block because of multiblock 6000 bc or periodic boundary condition 4xxx
7861
7865 // correct all the start2/end2 indices on the physical maps
7866 // to get correct results from mapCombine
7867 for(MInt i = 0; i < (MInt)physicalBCMap.size(); i++) {
7868 for(MInt dim = 0; dim < nDim; dim++) {
7869 physicalBCMap[i]->start2[dim] += m_noGhostLayers;
7870 physicalBCMap[i]->end2[dim] += m_noGhostLayers;
7871 }
7872 }
7873
7874 // until now, all physical BCs are still 2D or 1D,
7875 // now thicken them to 3D and extend them if necessary
7876 for(MInt i = 0; i < (MInt)physicalBCMap.size(); i++) {
7877 /* if (physicalBCMap[i]->Nstar!=-1) {
7878 unique_ptr<StructuredWindowMap<nDim>> map = physicalBCMap[i];
7879 cout << "TEST00 BC_" << i << " BC=" << map->BC << "; start1=" << map->start1[0] << "|" << map->start1[1]// <<
7880 "|" << map->start1[2]
7881 << "; end1=" << map->end1[0] << "|" << map->end1[1] << endl;// << "|" << map->end1[2] << endl
7882 physicalBCMap[i]->face = -1;
7883 physicalBCMap[i]->originShape = 0;
7884 continue;
7885 }*/
7886
7887 MInt addDimensionCount = 0;
7888
7889 for(MInt dim = 0; dim < nDim; dim++) {
7890 if(physicalBCMap[i]->start1[dim] == physicalBCMap[i]->end1[dim]) {
7891 // check which face it is and save this information
7892 // also thicken in the face normal direction by two ghost-cells
7893 switch(dim) {
7894 case 0: { // face 0 or 1
7895 // check if face 0 or 1
7896 if(physicalBCMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7897 physicalBCMap[i]->face = 0;
7898 physicalBCMap[i]->start1[dim] -= m_noGhostLayers;
7899 physicalBCMap[i]->start2[dim] -= m_noGhostLayers;
7900 } else {
7901 physicalBCMap[i]->face = 1;
7902 physicalBCMap[i]->end1[dim] += m_noGhostLayers;
7903 physicalBCMap[i]->end2[dim] += m_noGhostLayers;
7904 }
7905 break;
7906 }
7907 case 1: { // face 2 or 3
7908 if(physicalBCMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7909 // check if face 2 or 3
7910 physicalBCMap[i]->face = 2;
7911 physicalBCMap[i]->start1[dim] -= m_noGhostLayers;
7912 physicalBCMap[i]->start2[dim] -= m_noGhostLayers;
7913 } else {
7914 physicalBCMap[i]->face = 3;
7915 physicalBCMap[i]->end1[dim] += m_noGhostLayers;
7916 physicalBCMap[i]->end2[dim] += m_noGhostLayers;
7917 }
7918 break;
7919 }
7920 case 2: { // face 4 or 5
7921 if(physicalBCMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7922 // check if face 4 or 5
7923 physicalBCMap[i]->face = 4;
7924 physicalBCMap[i]->start1[dim] -= m_noGhostLayers;
7925 physicalBCMap[i]->start2[dim] -= m_noGhostLayers;
7926 } else {
7927 physicalBCMap[i]->face = 5;
7928 physicalBCMap[i]->end1[dim] += m_noGhostLayers;
7929 physicalBCMap[i]->end2[dim] += m_noGhostLayers;
7930 }
7931 break;
7932 }
7933 default: {
7934 cerr << "error no side could be attributed" << endl;
7935 exit(1);
7936 }
7937 }
7938
7939 addDimensionCount++;
7940 continue;
7941 }
7942
7943 // if the map starts at the begin of the domain, extend in negative direction
7944 if(physicalBCMap[i]->start1[dim] == m_myMapWithoutGC->start2[dim]) {
7945 physicalBCMap[i]->start1[dim] -= m_noGhostLayers;
7946 physicalBCMap[i]->start2[dim] -= m_noGhostLayers;
7947 }
7948
7949 // if the map end at the end of the domain, extend in positive direction
7950 if(physicalBCMap[i]->end1[dim] == m_myMapWithoutGC->end2[dim]) {
7951 physicalBCMap[i]->end1[dim] += m_noGhostLayers;
7952 physicalBCMap[i]->end2[dim] += m_noGhostLayers;
7953 }
7954 }
7955
7956 physicalBCMap[i]->originShape = addDimensionCount;
7957 }
7958
7959 // I guess this call would have been also possible before the "PHYSICAL BC MAP CORRECTION"?!
7960 deleteDuplicateBCMaps(physicalBCMap);
7961
7965
7966 // remove the extension in the cases where a partition boundary
7967 // coincides with two different BCs
7968 //(if we don't remove it, there might be two overlapping BCs with
7969 // uncertainty which one is applied first and second, this
7970 // can cause oscillations and NANs eventually)
7971
7972 // go over all physical maps
7973 for(MInt i = 0; i < (MInt)physicalBCMap.size(); i++) {
7974 // first loop: only maps that were originally surfaces
7975 if(physicalBCMap[i]->originShape == 2) {
7976 continue;
7977 }
7978 for(MInt j = 0; j < (MInt)physicalBCMap.size(); j++) {
7979 // // I don't know for sure why I need to skip this, but ...
7980 // if (physicalBCMap[j]->Nstar!=-1) continue;
7981 // second loop: only maps that were originally lines
7982 if(physicalBCMap[j]->originShape != 2) {
7983 continue;
7984 }
7985 // skip if BC number is equal (we can leave the extension then)
7986 if(physicalBCMap[i]->BC == physicalBCMap[j]->BC) {
7987 continue;
7988 }
7989
7990 mapCombine11(physicalBCMap[i], physicalBCMap[j], localMapDummy);
7991 MBool is3dMap = mapCheck3d(localMapDummy);
7992
7993 if(is3dMap) {
7994 MInt faceDim = physicalBCMap[i]->face / 2;
7995
7996 for(MInt dim = 0; dim < nDim; dim++) {
7997 // skip if is the face normal direction
7998 if(dim == faceDim) {
7999 continue;
8000 }
8001
8002 // start of domain
8003 if(physicalBCMap[j]->start1[dim] == physicalBCMap[i]->start1[dim]
8004 && physicalBCMap[j]->end1[dim] == m_myMapWithoutGC->start2[dim]) {
8005 physicalBCMap[i]->start1[dim] += m_noGhostLayers;
8006 cout << "DomainID: " << domainId()
8007 << " cutting extension at start of partition because of partition/bc conflict with BCs "
8008 << physicalBCMap[i]->BC << " and " << physicalBCMap[j]->BC << endl;
8009 }
8010
8011 // end of domain
8012 if(physicalBCMap[j]->start1[dim] == m_myMapWithoutGC->end2[dim]
8013 && physicalBCMap[j]->end1[dim] == physicalBCMap[i]->end1[dim]) {
8014 physicalBCMap[i]->end1[dim] -= m_noGhostLayers;
8015 cout << "DomainID: " << domainId()
8016 << " cutting extension at end of partition because of partition/bc conflict with BCs "
8017 << physicalBCMap[i]->BC << " and " << physicalBCMap[j]->BC << endl;
8018 }
8019 }
8020 }
8021 }
8022 }
8023
8024
8025 // correct all the start2/end2 indices on the rcv maps
8026 for(MInt j = 0; j < (MInt)rcvMap.size(); j++) {
8027 for(MInt dim = 0; dim < nDim; dim++) {
8028 rcvMap[j]->start2[dim] = rcvMap[j]->start1[dim] + m_grid->getMyOffset(nDim - 1 - dim);
8029 rcvMap[j]->end2[dim] = rcvMap[j]->end1[dim] + m_grid->getMyOffset(nDim - 1 - dim);
8030 }
8031 }
8032
8033 // Create singularity global BCs from rcv map
8034 for(MInt j = 0; j < (MInt)rcvMap.size(); j++) {
8035 if(rcvMap[j]->Nstar > 3 && rcvMap[j]->BCsingular[0] < -6000 && rcvMap[j]->BCsingular[0] > -6010) {
8036 unique_ptr<StructuredWindowMap<nDim>> windowMap = make_unique<StructuredWindowMap<nDim>>();
8037 mapCreate(rcvMap[j]->Id1, rcvMap[j]->start1, rcvMap[j]->end1, rcvMap[j]->step1, -1, NULL, NULL, NULL,
8038 rcvMap[j]->order, -rcvMap[j]->BCsingular[0], windowMap);
8039 windowMap->Nstar = rcvMap[j]->Nstar;
8040 windowMap->SingularId = rcvMap[j]->SingularId;
8041 physicalBCMap.push_back(std::move(windowMap));
8042 }
8043 }
8044
8045 // Check that 6000er BCs only cover the range, which is also covered by -6000er communication BCs
8046 // Therefore check the edges/extensions; This istuation arises at singularities; we don't want to have
8047 // the extension in case of Nstar==5 or Nstar==6
8048 for(MInt i = 0; i < (MInt)physicalBCMap.size(); i++) {
8049 if(physicalBCMap[i]->BC >= 6000 && physicalBCMap[i]->BC < 6010 && physicalBCMap[i]->Nstar == -1) {
8050 for(MInt d = 0; d < nDim; ++d) {
8051 if(physicalBCMap[i]->step1[d] < 0) mTerm(1, "");
8052 }
8053 const MInt faceDim = physicalBCMap[i]->face / 2;
8054
8055 MInt start_begin[nDim], end_begin[nDim];
8056 MInt start_end[nDim], end_end[nDim];
8057 std::copy(&physicalBCMap[i]->start1[0], &physicalBCMap[i]->start1[0] + nDim, &start_begin[0]);
8058 std::copy(&physicalBCMap[i]->start1[0], &physicalBCMap[i]->start1[0] + nDim, &end_begin[0]);
8059 std::copy(&physicalBCMap[i]->end1[0], &physicalBCMap[i]->end1[0] + nDim, &end_end[0]);
8060 std::copy(&physicalBCMap[i]->end1[0], &physicalBCMap[i]->end1[0] + nDim, &start_end[0]);
8061 for(MInt d = 0; d < nDim; ++d) {
8062 if(physicalBCMap[i]->start1[d] + m_noGhostLayers == m_myMapWithoutGC->start2[d] || d == faceDim)
8063 end_begin[d] += m_noGhostLayers;
8064 if(physicalBCMap[i]->end1[d] - m_noGhostLayers == m_myMapWithoutGC->end2[d] || d == faceDim)
8065 start_end[d] -= m_noGhostLayers;
8066 if(faceDim != -1 && d != faceDim && end_begin[d] > start_end[d]) {
8067 // std::this_thread::sleep_for(std::chrono::milliseconds(2000)*domainId());
8068 cout << "STOP " << d << "|" << faceDim << " " << start_end[d] << "|" << end_begin[d] << endl;
8069 mapPrint(physicalBCMap[i]);
8070 mTerm(1, "stop");
8071 }
8072 }
8073
8074 MBool overlap1 = false;
8075 MBool overlap2 = false;
8076 for(MInt j = 0; j < (MInt)rcvMap.size(); j++) {
8077 // if (rcvMap[j]->BC>-6000 || rcvMap[j]->BC<=-6010) continue;
8078 MBool overlap1_temp = true;
8079 MBool overlap2_temp = true;
8080 for(MInt d = 0; d < nDim; ++d) {
8081 if(rcvMap[j]->step1[d] < 0) mTerm(1, "");
8082 }
8083
8084 //
8085 for(MInt d = 0; d < nDim; ++d) {
8086 if(rcvMap[j]->start1[d] > start_begin[d] || rcvMap[j]->end1[d] < end_begin[d]) overlap1_temp = false;
8087 if(rcvMap[j]->start1[d] > start_end[d] || rcvMap[j]->end1[d] < end_end[d]) overlap2_temp = false;
8088 }
8089
8090 if(overlap1_temp) overlap1 = overlap1_temp;
8091 if(overlap2_temp) overlap2 = overlap2_temp;
8092 }
8093
8094 if(!overlap1) {
8095 cout << "DomainID: " << domainId() << " cutting extension at start of partition! " << endl;
8096 for(MInt d = 0; d < nDim; ++d) {
8097 if(d == faceDim) continue;
8098
8099 physicalBCMap[i]->start1[d] += m_noGhostLayers;
8100 }
8101 }
8102 if(!overlap2) {
8103 cout << "DomainID: " << domainId() << " cutting extension at end of partition! " << endl;
8104 for(MInt d = 0; d < nDim; ++d) {
8105 if(d == faceDim) continue;
8106
8107 physicalBCMap[i]->end1[d] -= m_noGhostLayers;
8108 }
8109 }
8110 }
8111 }
8112
8113
8114 for(MInt i = 0; i < (MInt)physicalBCMap.size(); i++) {
8115 if(physicalBCMap[i]->BC == 2501) {
8116 continue;
8117 }
8118 for(MInt j = 0; j < (MInt)rcvMap.size(); j++) {
8119 mapCombine11(rcvMap[j], physicalBCMap[i], localMapDummy);
8120 MBool is3dMap = mapCheck3d(localMapDummy);
8121 if(is3dMap && ((rcvMap[j]->BC <= -6000 && rcvMap[j]->BC > -6010) || rcvMap[j]->BC == 6333)) { // 6000er-change
8122 cout << "############ ATTENTION: BC MAP IS OVERLAPPING WITH 6000 RCV MAP!!! #############" << endl;
8123 cout << "receiveMap: " << endl;
8124 mapPrint(rcvMap[j]);
8125 cout << "physicalBCMap: " << endl;
8126 mapPrint(physicalBCMap[i]);
8127 cout << "combined21: " << endl;
8128 mapPrint(localMapDummy);
8129 }
8130 }
8131 }
8132
8133
8134 /* MPI_Barrier(m_StructuredComm, AT_);
8135 std::this_thread::sleep_for(std::chrono::milliseconds(2000*domainId()));
8136 cout << "MY DOMAINID=" << domainId() << " blockId="
8137 << m_grid->getBlockId(domainId()) << endl; for (MInt i = 0; i <
8138 (signed)physicalBCMap.size(); ++i) { cout << "GLOBAL BCs" << endl; mapPrint(physicalBCMap[i]);
8139 }
8140
8141 for (MInt i = 0; i < (signed)rcvMap.size(); ++i) {
8142 cout << "RCV MAP " << endl;
8143 mapPrint(rcvMap[i]);
8144 }
8145
8146 for (MInt i = 0; i < (signed)sndMap.size(); ++i) {
8147 cout << "SND MAP " << endl;
8148 mapPrint(sndMap[i]);
8149 }
8150
8151 for (MInt i = 0; i < singularPoint; ++i) {
8152 cout << "SINGULARITY: d=" << domainId() << " Nstar=" << singularity[i].Nstar
8153 << " singularBlockId=" << singularity[i].SingularBlockId[0] << "|" <<
8154 singularity[i].SingularBlockId[1]
8155 << "|" << singularity[i].SingularBlockId[2] << "|" << singularity[i].SingularBlockId[3]
8156 << " BC=" << singularity[i].BC << " BC_singularity=" << singularity[i].BCsingular[0]
8157 << "|" << singularity[i].BCsingular[1] << "|" << singularity[i].BCsingular[2] << "|" <<
8158 singularity[i].BCsingular[3]
8159 << " start=" << singularity[i].start[0] << "|" << singularity[i].start[1]
8160 << " end=" << singularity[i].end[0] << "|" << singularity[i].end[1] << endl;
8161 }
8162 MPI_Barrier(m_StructuredComm, AT_);*/
8163}
8164
8165template <MInt nDim>
8167 if(nDim != 3) return;
8168 waveRcvMap.clear();
8169 waveSndMap.clear();
8170
8171 MInt start1[3] = {0, 0, 0};
8172 MInt end1[3] = {0, 0, 0};
8173 MInt step1[3] = {1, 1, 1};
8174 MInt order[3] = {0, 1, 2};
8175 MInt start2[3] = {0, 0, 0};
8176 MInt end2[3] = {0, 0, 0};
8177 MInt offsetCells[3] = {0, 0, 0};
8178 MInt activeCells[3] = {0, 0, 0};
8179
8180 MInt blockId = m_grid->getBlockId(domainId());
8181
8185 // this is the map of the active cells (no ghostcells) in my own partition
8186 // shifted by the no of ghost-cells
8187 for(MInt i = 0; i < nDim; i++) {
8188 start1[i] = m_grid->getMyOffset(nDim - 1 - i); // shifted by the number of ghost layers
8189 start2[i] = 0; // shifted by the number of ghost layers
8190 end1[i] = start1[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1;
8191 end2[i] = start2[i] + m_grid->getMyActivePoints(nDim - 1 - i) - 1;
8192 }
8193
8194 unique_ptr<StructuredWindowMap<nDim>> waveMyMap = make_unique<StructuredWindowMap<nDim>>();
8195 mapCreate(blockId, start1, end1, step1, domainId(), start2, end2, step1, order, -1, waveMyMap);
8196
8197 MInt allCells[3] = {0, 0, 0};
8198 for(MInt dim = 0; dim < nDim; dim++) {
8199 allCells[dim] = m_grid->getBlockNoCells(0, nDim - 1 - dim);
8200 }
8201
8202 vector<unique_ptr<StructuredWindowMap<nDim>>> waveSndPartitionMaps;
8203 unique_ptr<StructuredWindowMap<nDim>> localMapDummy = nullptr;
8204 for(MInt j = 0; j < noDomains(); j++) {
8205 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8206 blockId = m_grid->getBlockId(j);
8207
8208 for(MInt dim = 0; dim < nDim; dim++) {
8209 offsetCells[dim] = m_grid->getOffset(j, nDim - 1 - dim);
8210 activeCells[dim] = m_grid->getActivePoints(j, nDim - 1 - dim) - 1;
8211 }
8212
8213 for(MInt dim = 0; dim < nDim; dim++) {
8214 start1[dim] = offsetCells[dim];
8215 end1[dim] = start1[dim] + activeCells[dim];
8216 }
8217
8218 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, 0, localMapDummy);
8219 waveSndPartitionMaps.push_back(std::move(localMapDummy));
8220 }
8221
8222 vector<unique_ptr<StructuredWindowMap<nDim>>> wavePartitionMaps;
8223 // maps of all the partitions moved to the relative system
8224 for(MInt j = 0; j < noDomains(); j++) {
8225 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8226
8227 // preparation
8228 MInt shiftedOffset[3] = {0, 0, 0};
8229 MInt croppedActiveCells[3] = {0, 0, 0};
8230 MInt overhangCells[3] = {0, 0, 0};
8231 MInt overhangOffset[3] = {0, 0, 0};
8232 blockId = m_grid->getBlockId(j);
8233 for(MInt dim = 0; dim < nDim; dim++) {
8234 offsetCells[dim] = m_grid->getOffset(j, nDim - 1 - dim);
8235 activeCells[dim] = m_grid->getActivePoints(j, nDim - 1 - dim) - 1;
8236 }
8237
8238 // first fill with the unmoved values
8239 // important for 0- and 1-direction
8240 for(MInt dim = 0; dim < nDim; dim++) {
8241 shiftedOffset[dim] = offsetCells[dim];
8242 croppedActiveCells[dim] = activeCells[dim];
8243 overhangCells[dim] = activeCells[dim];
8244 overhangOffset[dim] = offsetCells[dim];
8245 }
8246
8247 if(offsetCells[2] + activeCells[2] <= waveZeroPos) {
8248 // domain is before wave zero
8249 // only shift domain
8250 shiftedOffset[2] = allCells[2] - waveZeroPos + offsetCells[2];
8251 for(MInt dim = 0; dim < nDim; dim++) {
8252 start1[dim] = shiftedOffset[dim];
8253 end1[dim] = start1[dim] + activeCells[dim];
8254 }
8255 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, 0, localMapDummy);
8256 wavePartitionMaps.push_back(std::move(localMapDummy));
8257 } else if(offsetCells[2] < waveZeroPos && offsetCells[2] + activeCells[2] > waveZeroPos) {
8258 // create first map
8259 croppedActiveCells[2] = waveZeroPos - offsetCells[2];
8260 shiftedOffset[2] = allCells[2] - croppedActiveCells[2];
8261 for(MInt dim = 0; dim < nDim; dim++) {
8262 start1[dim] = shiftedOffset[dim];
8263 end1[dim] = start1[dim] + croppedActiveCells[dim];
8264 }
8265 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, 0, localMapDummy);
8266 wavePartitionMaps.push_back(std::move(localMapDummy));
8267 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8268 // create second map
8269 overhangCells[2] = activeCells[2] - croppedActiveCells[2];
8270 overhangOffset[2] = 0;
8271 for(MInt dim = 0; dim < nDim; dim++) {
8272 start1[dim] = overhangOffset[dim];
8273 end1[dim] = start1[dim] + overhangCells[dim];
8274 }
8275 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, 1, localMapDummy);
8276 wavePartitionMaps.push_back(std::move(localMapDummy));
8277 } else {
8278 shiftedOffset[2] = offsetCells[2] - waveZeroPos;
8279 for(MInt dim = 0; dim < nDim; dim++) {
8280 start1[dim] = shiftedOffset[dim];
8281 end1[dim] = start1[dim] + activeCells[dim];
8282 }
8283 mapCreate(blockId, start1, end1, step1, j, start2, end2, step1, order, 1, localMapDummy);
8284 wavePartitionMaps.push_back(std::move(localMapDummy));
8285 }
8286 }
8287
8291
8292 // check overlapping of own non-gc partition with other gc partitions and put into SND maps
8293 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8294 for(MInt i = 0; i < (MInt)wavePartitionMaps.size(); i++) {
8295 // only do this for own maps
8296 if(wavePartitionMaps[i]->Id2 != domainId()) {
8297 continue;
8298 }
8299
8300 for(MInt j = 0; j < (MInt)waveSndPartitionMaps.size(); j++) {
8301 mapCombineWave(wavePartitionMaps[i], waveSndPartitionMaps[j], localMapDummy);
8302 MBool test = false;
8303 test = mapCheckWave(localMapDummy);
8304 if(test == true) {
8305 localMapDummy->BC = wavePartitionMaps[i]->BC;
8306 if(localMapDummy->start1[2] < allCells[2] - waveZeroPos) {
8307 const MInt translationK = allCells[2] - waveZeroPos - localMapDummy->start1[2];
8308 const MInt sizeK = localMapDummy->end1[2] - localMapDummy->start1[2];
8309 localMapDummy->start1[2] = allCells[2] - translationK;
8310 localMapDummy->end1[2] = localMapDummy->start1[2] + sizeK;
8311 } else {
8312 const MInt translationK = allCells[2] - waveZeroPos;
8313 localMapDummy->start1[2] -= translationK;
8314 localMapDummy->end1[2] -= translationK;
8315 }
8316 waveSndMap.push_back(std::move(localMapDummy));
8317 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8318 }
8319 }
8320 }
8321
8322 // check overlapping of own gc partition with other non-gc partitions and put into RCV maps
8323 for(MInt i = 0; i < (MInt)wavePartitionMaps.size(); i++) {
8324 mapCombineWave(waveMyMap, wavePartitionMaps[i], localMapDummy);
8325 MBool test = false;
8326 test = mapCheckWave(localMapDummy);
8327 if(test == true) {
8328 waveRcvMap.push_back(std::move(localMapDummy));
8329 localMapDummy = make_unique<StructuredWindowMap<nDim>>();
8330 }
8331 }
8332
8333 for(MInt i = 0; i < (MInt)waveRcvMap.size(); i++) {
8334 for(MInt dim = 0; dim < nDim; dim++) {
8335 const MInt offset = m_grid->getMyOffset(nDim - 1 - dim);
8336 waveRcvMap[i]->start1[dim] = waveRcvMap[i]->start1[dim] - offset + m_noGhostLayers;
8337 waveRcvMap[i]->end1[dim] = waveRcvMap[i]->end1[dim] - offset + m_noGhostLayers;
8338 }
8339 }
8340
8341 for(MInt i = 0; i < (MInt)waveSndMap.size(); i++) {
8342 for(MInt dim = 0; dim < nDim; dim++) {
8343 const MInt offset = m_grid->getMyOffset(nDim - 1 - dim);
8344 waveSndMap[i]->start1[dim] = waveSndMap[i]->start1[dim] - offset + m_noGhostLayers;
8345 waveSndMap[i]->end1[dim] = waveSndMap[i]->end1[dim] - offset + m_noGhostLayers;
8346 }
8347 }
8348
8349 waveSndPartitionMaps.clear();
8350 wavePartitionMaps.clear();
8351}
8352
8353template <MInt nDim>
8355 vector<unique_ptr<StructuredComm<nDim>>>& sndComm,
8356 vector<unique_ptr<StructuredComm<nDim>>>& rcvComm,
8357 const MInt noVariables) {
8358 sndComm.clear();
8359 rcvComm.clear();
8360 // SND Maps
8361 for(MInt i = 0; i < (MInt)waveSndMap.size(); i++) {
8362 // compute the buffersizes for sending and receiving
8363 MInt noCellsSnd = 1;
8364 for(MInt j = 0; j < nDim; j++) {
8365 MInt cellSizes = (waveSndMap[i]->end1[j] - waveSndMap[i]->start1[j]);
8366 if(cellSizes != 0) {
8367 noCellsSnd *= (cellSizes);
8368 }
8369 }
8370
8372
8373 unique_ptr<StructuredComm<nDim>> snd =
8374 make_unique<StructuredComm<nDim>>(noVariables, nullptr, noCellsSnd, 0, commType);
8375
8376 snd->nghbrId = waveSndMap[i]->Id2;
8377 for(MInt dim = 0; dim < nDim; ++dim) {
8378 snd->startInfoCells[dim] = waveSndMap[i]->start1[dim];
8379 snd->endInfoCells[dim] = waveSndMap[i]->end1[dim];
8380 }
8381 snd->tagHelper = waveSndMap[i]->BC;
8382
8383 sndComm.push_back(std::move(snd));
8384 }
8385
8386 // RCV Maps
8387 for(MInt i = 0; i < (MInt)waveRcvMap.size(); i++) {
8388 // compute the buffersizes for sending and receiving
8389 MInt noCellsRcv = 1;
8390 for(MInt j = 0; j < nDim; j++) {
8391 MInt cellSizes = (waveRcvMap[i]->end1[j] - waveRcvMap[i]->start1[j]);
8392 if(cellSizes != 0) {
8393 noCellsRcv *= (cellSizes);
8394 }
8395 }
8396
8398
8399 unique_ptr<StructuredComm<nDim>> rcv =
8400 make_unique<StructuredComm<nDim>>(noVariables, nullptr, noCellsRcv, 0, commType);
8401
8402 rcv->nghbrId = waveRcvMap[i]->Id2;
8403 for(MInt dim = 0; dim < nDim; ++dim) {
8404 rcv->startInfoCells[dim] = waveRcvMap[i]->start1[dim];
8405 rcv->endInfoCells[dim] = waveRcvMap[i]->end1[dim];
8406 }
8407 rcv->tagHelper = waveRcvMap[i]->BC;
8408
8409 rcvComm.push_back(std::move(rcv));
8410 }
8411}
8412
8413template <MInt nDim>
8415 vector<unique_ptr<StructuredComm<nDim>>>& sndComm,
8416 vector<unique_ptr<StructuredComm<nDim>>>& rcvComm,
8417 const MInt noVariables,
8418 MFloat* const* const variables) {
8419 if(rcvMap.size() != sndMap.size()) {
8420 MInt count1[4] = {0, 0, 0, 0}, count2[4] = {0, 0, 0, 0};
8421 for(MInt i = 0; i < (MInt)sndMap.size(); ++i) {
8422 if((sndMap[i]->BC <= -6000 && sndMap[i]->BC > -6010) && sndMap[i]->Nstar == -1) // 6000er-change
8423 count1[0]++;
8424 else if((sndMap[i]->BC <= -6000 && sndMap[i]->BC > -6010) && sndMap[i]->Nstar != -1) // 6000er-change
8425 count1[1]++;
8426 else if(sndMap[i]->BC >= 4000 && sndMap[i]->BC < 5000 && sndMap[i]->Nstar == -1)
8427 count1[2]++;
8428 else if(sndMap[i]->BC >= 4000 && sndMap[i]->BC < 5000 && sndMap[i]->Nstar != -1)
8429 count1[3]++;
8430 }
8431 for(MInt i = 0; i < (MInt)rcvMap.size(); ++i) {
8432 if((rcvMap[i]->BC <= -6000 && rcvMap[i]->BC > -6010) && rcvMap[i]->Nstar == -1) // 6000er-change
8433 count2[0]++;
8434 else if((rcvMap[i]->BC <= -6000 && rcvMap[i]->BC > -6010) && rcvMap[i]->Nstar != -1) // 6000er-change
8435 count2[1]++;
8436 else if(rcvMap[i]->BC >= 4000 && rcvMap[i]->BC < 5000 && rcvMap[i]->Nstar == -1)
8437 count2[2]++;
8438 else if(rcvMap[i]->BC >= 4000 && rcvMap[i]->BC < 5000 && rcvMap[i]->Nstar != -1)
8439 count2[3]++;
8440 }
8441
8442 // sending and receiving does not correspond ==> error
8443 cout << "***********************************WARNING************************************** " << endl;
8444 cout << "this error may be caused by the partition when you have a Step in the grid, try to change number of "
8445 "domains "
8446 "and run again!"
8447 << endl;
8448 cout << "******************************************************************************** " << endl;
8449 mTerm(1, AT_, "number of sending and receiving processes does not match");
8450 }
8451
8452 for(MInt i = 0; i < (MInt)rcvMap.size(); i++) {
8454 const MInt BC = (rcvMap[i]->BC <= -6000 && rcvMap[i]->BC > -6010) ? 6000 : rcvMap[i]->BC; // 6000er-change
8455
8456 MInt bcIdSnd = sndMap[i]->BC;
8457 MInt bcIdRcv = rcvMap[i]->BC;
8458
8459 switch(BC) {
8460 case 6333: // singular communications
8461 {
8462 commType = SINGULAR;
8463 bcIdSnd = sndMap[i]->BCsingular[0];
8464 bcIdRcv = rcvMap[i]->BCsingular[0];
8465 break;
8466 }
8467 case 4011:
8468 case 4012:
8469 case 4401:
8470 case 4402:
8471 case 4403:
8472 case 4404:
8473 case 4405:
8474 case 4406: {
8475 if(rcvMap[i]->Nstar != -1) {
8476 commType = PERIODIC_BC_SINGULAR;
8477 } else {
8478 commType = PERIODIC_BC;
8479 }
8480
8481 break;
8482 }
8483 // case 6011: {
8484 // commType = CHANNEL;
8485 // break;
8486 // }
8487 default: {
8488 commType = PARTITION_NORMAL;
8489 }
8490 }
8491
8495 // compute the buffersizes for sending and receiving
8496 MInt noCellsSnd = 1, noPointsSnd = 1;
8497 for(MInt j = 0; j < nDim; j++) {
8498 MInt cellSizes = (sndMap[i]->end1[j] - sndMap[i]->start1[j]);
8499 if(cellSizes != 0) {
8500 noCellsSnd *= (cellSizes);
8501 noPointsSnd *= (cellSizes + 1);
8502 }
8503 }
8504
8505 unique_ptr<StructuredComm<nDim>> snd =
8506 make_unique<StructuredComm<nDim>>(noVariables, variables, noCellsSnd, noPointsSnd, commType);
8507
8508 snd->nghbrId = sndMap[i]->Id2;
8509
8510 for(MInt dim = 0; dim < nDim; ++dim) {
8511 snd->startInfoCells[dim] = sndMap[i]->start1[dim];
8512 snd->endInfoCells[dim] = sndMap[i]->end1[dim];
8513 snd->startInfoPoints[dim] = sndMap[i]->start1[dim];
8514 snd->endInfoPoints[dim] = sndMap[i]->end1[dim];
8515 }
8516
8517 snd->tagHelper = sndMap[i]->face;
8518 if(snd->tagHelper < 0) {
8519 snd->tagHelper = 0;
8520 }
8521
8522 snd->bcId = bcIdSnd;
8523
8524 sndComm.push_back(std::move(snd));
8525
8526
8530 // compute the buffersizes for sending and receiving
8531 MInt noCellsRcv = 1, noPointsRcv = 1;
8532 for(MInt j = 0; j < nDim; j++) {
8533 MInt cellSizes = (rcvMap[i]->end1[j] - rcvMap[i]->start1[j]);
8534 if(cellSizes != 0) {
8535 noCellsRcv *= (cellSizes);
8536 noPointsRcv *= (cellSizes + 1);
8537 }
8538 }
8539
8540 unique_ptr<StructuredComm<nDim>> rcv =
8541 make_unique<StructuredComm<nDim>>(noVariables, variables, noCellsRcv, noPointsRcv, commType);
8542
8543 rcv->nghbrId = rcvMap[i]->Id2;
8544 for(MInt dim = 0; dim < nDim; ++dim) {
8545 rcv->startInfoCells[dim] = rcvMap[i]->start1[dim];
8546 rcv->endInfoCells[dim] = rcvMap[i]->end1[dim];
8547 rcv->startInfoPoints[dim] = rcvMap[i]->start1[dim];
8548 rcv->endInfoPoints[dim] = rcvMap[i]->end1[dim];
8549 rcv->orderInfo[dim] = rcvMap[i]->order[dim];
8550 rcv->stepInfo[dim] = rcvMap[i]->step2[dim];
8551 }
8552
8553 rcv->tagHelper = rcvMap[i]->face;
8554 if(rcv->tagHelper < 0) {
8555 rcv->tagHelper = 0;
8556 }
8557
8558 rcv->bcId = bcIdRcv;
8559
8560 rcvComm.push_back(std::move(rcv));
8561 }
8562}
8563
8564template <MInt nDim>
8566 unique_ptr<StructuredWindowMap<nDim>>& map2) {
8567 if(map1->Id1 != map2->Id1) return 0;
8568 if(map1->Id2 != map2->Id2) return 0;
8569 for(MInt i = 0; i < nDim; i++) {
8570 if(map1->start1[i] != map2->start1[i]) return 0;
8571 if(map1->end1[i] != map2->end1[i]) return 0;
8572 // if(map1->start2[i]!=map2->start2[i]) return 0;
8573 // if(map1->end2[i]!=map2->end2[i]) return 0;
8574 if(map1->step1[i] != map2->step1[i]) return 0;
8575 // if(map1->step2[i]!=map2->step2[i]) return 0;
8576 if(map1->order[i] != map2->order[i]) return 0;
8577 }
8578 return 1;
8579}
8580
8581template <MInt nDim>
8583 const unique_ptr<StructuredWindowMap<nDim>>& map2) {
8584 // only compare the Id1, start1 and end1
8585 if(map1->Id1 != map2->Id1) return 0;
8586 for(MInt i = 0; i < nDim; i++) {
8587 if(map1->start1[i] != map2->start1[i]) return 0;
8588 if(map1->end1[i] != map2->end1[i]) return 0;
8589 }
8590 return 1;
8591}
8592
8593template <MInt nDim>
8595 MInt* start2, MInt* end2, MInt* step2, MInt* order, MInt BC,
8596 unique_ptr<StructuredWindowMap<nDim>>& output) {
8597 output->Id1 = Id1;
8598 output->BC = BC;
8599 output->Nstar = -1;
8600 output->dc1 = 888;
8601 output->dc2 = 888;
8602 output->SingularId = -1;
8603
8604 if(Id2 != -1) {
8605 output->Id2 = Id2;
8606 } else {
8607 output->Id2 = Id1;
8608 }
8609
8610 memcpy(output->start1, start1, nDim * sizeof(MInt));
8611 if(start2 != nullptr) {
8612 memcpy(output->start2, start2, nDim * sizeof(MInt));
8613 } else {
8614 memcpy(output->start2, start1, nDim * sizeof(MInt));
8615 }
8616
8617 memcpy(output->end1, end1, nDim * sizeof(MInt));
8618 if(end2 != nullptr) {
8619 memcpy(output->end2, end2, nDim * sizeof(MInt));
8620 } else {
8621 memcpy(output->end2, end1, nDim * sizeof(MInt));
8622 }
8623
8624 if(step1 != nullptr) {
8625 memcpy(output->step1, step1, nDim * sizeof(MInt));
8626 } else {
8627 for(MInt i = 0; i < nDim; i++)
8628 output->step1[i] = 1;
8629 }
8630
8631 if(step2 != nullptr) {
8632 memcpy(output->step2, step2, nDim * sizeof(MInt));
8633 } else {
8634 for(MInt i = 0; i < nDim; i++)
8635 output->step2[i] = 1;
8636 }
8637
8638 if(order != nullptr) {
8639 memcpy(output->order, order, nDim * sizeof(MInt));
8640 } else {
8641 for(MInt i = 1; i < nDim; i++)
8642 output->order[i] = i;
8643 }
8644
8645 output->SingularId = -1;
8646 output->Nstar = -1;
8647 output->dc1 = -999;
8648 output->dc2 = -999;
8649}
8650
8651template <MInt nDim>
8653 MBool test;
8654 for(MInt i = 0; i < nDim; i++) {
8655 test = false;
8656 if(input->step1[i] == 0) break;
8657 if(input->step2[i] == 0) break;
8658 if(input->step1[i] > 0) {
8659 if(input->end1[i] < input->start1[i]) break;
8660 } else {
8661 if(input->start1[i] < input->end1[i]) break;
8662 }
8663 if(input->step2[i] > 0) {
8664 if(input->end2[i] < input->start2[i]) break;
8665 } else {
8666 if(input->start2[i] < input->end2[i]) break;
8667 }
8668
8669 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8670 if(((input->end2[i] - input->start2[i]) % (input->step2[i])) != 0) break;
8671
8672 if(input->order[i] < 0 || input->order[i] > (nDim - 1)) break;
8673
8674 if(((input->end1[i] - input->start1[i]) / input->step1[i])
8675 != ((input->end2[input->order[i]] - input->start2[input->order[i]]) / input->step2[input->order[i]]))
8676 break;
8677
8678 test = true;
8679 }
8680 // check on Boundary Condition not possible
8681 return test;
8682}
8683
8684template <MInt nDim>
8686 MInt dummy = 0;
8687 MBool test;
8688 for(MInt i = 0; i < nDim; i++) {
8689 test = false;
8690 if(input->step1[i] == 0) break;
8691 if(input->step2[i] == 0) break;
8692 if(input->step1[i] > 0) {
8693 if(input->end1[i] < input->start1[i]) break;
8694 } else {
8695 if(input->start1[i] < input->end1[i]) break;
8696 }
8697 if(input->step2[i] > 0) {
8698 if(input->end2[i] < input->start2[i]) break;
8699 } else {
8700 if(input->start2[i] < input->end2[i]) break;
8701 }
8702
8703 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8704 if(((input->end2[i] - input->start2[i]) % (input->step2[i])) != 0) break;
8705
8706 if(input->order[i] < 0 || input->order[i] > (nDim - 1)) break;
8707
8708 if(((input->end1[i] - input->start1[i]) / input->step1[i])
8709 != ((input->end2[input->order[i]] - input->start2[input->order[i]]) / input->step2[input->order[i]]))
8710 break;
8711
8712 // check if the map is a line (3D) or a point (2D-problem)
8713 // if it is a line then two of the three indicies are the same else for a point
8714 // only one is
8715 if(input->start1[i] == input->end1[i]) dummy++;
8716
8717
8718 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
8719 // line or point is acceptable!!!!
8720
8721 test = true;
8722 }
8723 if(dummy != 3) test = false;
8724 // check on Boundary Condition not possible
8725 return test;
8726}
8727
8728template <MInt nDim>
8730 // MInt pointorline = 2;
8731 MInt dummy = 0;
8732 MBool test;
8733 for(MInt i = 0; i < nDim; i++) {
8734 test = false;
8735 if(input->step1[i] == 0) break;
8736 if(input->step2[i] == 0) break;
8737 if(input->step1[i] > 0) {
8738 if(input->end1[i] < input->start1[i]) break;
8739 } else {
8740 if(input->start1[i] < input->end1[i]) break;
8741 }
8742 if(input->step2[i] > 0) {
8743 if(input->end2[i] < input->start2[i]) break;
8744 } else {
8745 if(input->start2[i] < input->end2[i]) break;
8746 }
8747
8748 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8749 if(((input->end2[i] - input->start2[i]) % (input->step2[i])) != 0) break;
8750
8751 if(input->order[i] < 0 || input->order[i] > (nDim - 1)) break;
8752
8753 if(((input->end1[i] - input->start1[i]) / input->step1[i])
8754 != ((input->end2[input->order[i]] - input->start2[input->order[i]]) / input->step2[input->order[i]]))
8755 break;
8756
8757 // check if the map is a line (3D) or a point (2D-problem)
8758 // if it is a line then two of the three indicies are the same else for a point
8759 // only one is
8760 if(input->start1[i] == input->end1[i]) dummy++;
8761
8762
8763 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
8764 // line or point is acceptable!!!!
8765
8766 test = true;
8767 }
8768 if(dummy != 2) test = false;
8769 // check on Boundary Condition not possible
8770 return test;
8771}
8772
8773template <MInt nDim>
8775 // MInt pointorline = nDim-1;
8776 MInt dummy = 0;
8777 MBool result = false;
8778 for(MInt i = 0; i < nDim; i++) {
8779 result = false;
8780 if(input->step1[i] == 0) break;
8781 if(input->step2[i] == 0) break;
8782 if(input->step1[i] > 0) {
8783 if(input->end1[i] < input->start1[i]) break;
8784 } else {
8785 if(input->start1[i] < input->end1[i]) break;
8786 }
8787 if(input->step2[i] > 0) {
8788 if(input->end2[i] < input->start2[i]) break;
8789 } else {
8790 if(input->start2[i] < input->end2[i]) break;
8791 }
8792
8793 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8794 if(((input->end2[i] - input->start2[i]) % (input->step2[i])) != 0) break;
8795
8796 if(input->order[i] < 0 || input->order[i] > (nDim - 1)) break;
8797
8798 if(((input->end1[i] - input->start1[i]) / input->step1[i])
8799 != ((input->end2[input->order[i]] - input->start2[input->order[i]]) / input->step2[input->order[i]]))
8800 break;
8801
8802
8803 // check if the map is a line (3D) or a point (2D-problem)
8804 // if it is a line then two of the three indicies are the same else for a point
8805 // only one is
8806 if(input->start1[i] == input->end1[i]) dummy++;
8807
8808 result = true;
8809 }
8810
8811 if(dummy != 1 || result == false) {
8812 return false;
8813 } else {
8814 return true;
8815 }
8816}
8817
8818template <MInt nDim>
8820 // MInt pointorline = nDim-1;
8821 MInt dummy = 0;
8822 MBool result = false;
8823 for(MInt i = 0; i < nDim; i++) {
8824 result = false;
8825 if(input->step1[i] == 0) break;
8826 if(input->step2[i] == 0) break;
8827 if(input->step1[i] > 0) {
8828 if(input->end1[i] < input->start1[i]) break;
8829 } else {
8830 if(input->start1[i] < input->end1[i]) break;
8831 }
8832 if(input->step2[i] > 0) {
8833 if(input->end2[i] < input->start2[i]) break;
8834 } else {
8835 if(input->start2[i] < input->end2[i]) break;
8836 }
8837
8838 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8839 if(((input->end2[i] - input->start2[i]) % (input->step2[i])) != 0) break;
8840
8841 if(input->order[i] < 0 || input->order[i] > (nDim - 1)) break;
8842
8843 if(((input->end1[i] - input->start1[i]) / input->step1[i])
8844 != ((input->end2[input->order[i]] - input->start2[input->order[i]]) / input->step2[input->order[i]]))
8845 break;
8846
8847 // check if the map is a line (3D) or a point (2D-problem)
8848 // if it is a line then two of the three indicies are the same else for a point
8849 // only one is
8850 if(input->start1[i] == input->end1[i]) dummy++;
8851
8852 result = true;
8853 }
8854
8855 if(dummy != 0 || result == false) {
8856 return false;
8857 } else {
8858 return true;
8859 }
8860}
8861
8862template <MInt nDim>
8864 // MInt pointorline = nDim-1;
8865 MInt dummy = 0;
8866 MBool result = false;
8867 for(MInt i = 0; i < nDim; i++) {
8868 result = false;
8869 if(input->step1[i] == 0) break;
8870 if(input->step1[i] > 0) {
8871 if(input->end1[i] < input->start1[i]) break;
8872 } else {
8873 if(input->start1[i] < input->end1[i]) break;
8874 }
8875
8876 if(((input->end1[i] - input->start1[i]) % (input->step1[i])) != 0) break;
8877
8878 // check if the map is a line (3D) or a point (2D-problem)
8879 // if it is a line then two of the three indicies are the same else for a point
8880 // only one is
8881 if(input->start1[i] == input->end1[i]) dummy++;
8882 result = true;
8883 }
8884
8885 if(dummy != 0 || result == false) {
8886 return false;
8887 } else {
8888 return true;
8889 }
8890}
8891
8892template <MInt nDim>
8894 cout << "======== MAP INFO =======" << endl;
8895 cout << "Id1: " << input->Id1 << endl;
8896 stringstream start1;
8897 start1 << "start1: ";
8898 stringstream start2;
8899 start2 << "start2: ";
8900 stringstream end1;
8901 end1 << "end1: ";
8902 stringstream end2;
8903 end2 << "end2: ";
8904 stringstream step1;
8905 step1 << "step1: ";
8906 stringstream step2;
8907 step2 << "step2: ";
8908 stringstream order;
8909 order << "order: ";
8910 for(MInt i = 0; i < nDim; i++) {
8911 start1 << input->start1[i] << " ";
8912 start2 << input->start2[i] << " ";
8913 end1 << input->end1[i] << " ";
8914 end2 << input->end2[i] << " ";
8915 step1 << input->step1[i] << " ";
8916 step2 << input->step2[i] << " ";
8917 order << input->order[i] << " ";
8918 }
8919 cout << start1.str() << endl;
8920 cout << end1.str() << endl;
8921 cout << step1.str() << endl;
8922 cout << order.str() << endl;
8923 cout << "Id2: " << input->Id2 << endl;
8924 cout << start2.str() << endl;
8925 cout << end2.str() << endl;
8926 cout << step2.str() << endl;
8927 cout << "BC: " << input->BC << endl;
8928 if(input->Nstar != -1)
8929 cout << "BCsingular: " << input->BCsingular[0] << "|" << input->BCsingular[1] << "|" << input->BCsingular[2] << "|"
8930 << input->BCsingular[3] << "|" << input->BCsingular[4] << "|" << input->BCsingular[5] << endl;
8931 cout << "Face: " << input->face << endl;
8932
8933 cout << "spongInfos:" << endl;
8934 cout << "hasSponge: " << input->hasSponge << endl;
8935 cout << "spongeThickness: " << input->spongeThickness << endl;
8936 cout << "beta: " << input->beta << endl;
8937 cout << "sigma: " << input->sigma << endl;
8938
8939 cout << "Nstar: " << input->Nstar << endl;
8940 cout << "SingularId: " << input->SingularId << endl;
8941 cout << "DC1: " << input->dc1 << " DC2: " << input->dc2 << endl;
8942 cout << "======== MAP INFO END=======" << endl;
8943}
8944
8945template <MInt nDim>
8947 stringstream start1;
8948 start1 << "start1: ";
8949 stringstream start2;
8950 start2 << "start2: ";
8951 stringstream step2;
8952 step2 << "step2: ";
8953 stringstream order;
8954 order << "order: ";
8955
8956 for(MInt i = 0; i < nDim; i++) {
8957 start1 << input->start1[i] << "-" << input->end1[i] << " ";
8958 start2 << input->start2[i] << "-" << input->end2[i] << " ";
8959 step2 << input->step2[i] << " ";
8960 order << input->order[i] << " ";
8961 }
8962 cout << "Id1: " << input->Id1 << " Id2: " << input->Id2 << " BC: " << input->BC << " " << start1.str() << " "
8963 << start2.str() << step2.str() << order.str() << " BC:" << input->BC << " Nstar:" << input->Nstar << endl;
8964}
8965
8966template <MInt nDim>
8968 // output=make_unique<StructuredWindowMap<nDim>>();
8969 output->Id1 = 0;
8970 output->Id2 = 0;
8971 for(MInt i = 0; i < nDim; i++) {
8972 output->start1[i] = 0;
8973 output->end1[i] = -1;
8974 output->step1[i] = 1;
8975 output->start2[i] = 0;
8976 output->end2[i] = -1;
8977 output->step2[i] = 1;
8978 output->order[i] = 0;
8979 output->BC = -1;
8980 }
8981 output->hasSponge = false;
8982 output->spongeThickness = F0;
8983 output->beta = F0;
8984 output->sigma = F0;
8985}
8986
8987template <MInt nDim>
8989 unique_ptr<StructuredWindowMap<nDim>>& output) {
8990 // output= make_unique<StructuredWindowMap<nDim>>();
8991 output->Id1 = input->Id2;
8992 output->Id2 = input->Id1;
8993
8994 memcpy(output->start2, input->start1, nDim * sizeof(MInt));
8995
8996 memcpy(output->end2, input->end1, nDim * sizeof(MInt));
8997 memcpy(output->step2, input->step1, nDim * sizeof(MInt));
8998 memcpy(output->start1, input->start2, nDim * sizeof(MInt));
8999 memcpy(output->end1, input->end2, nDim * sizeof(MInt));
9000 memcpy(output->step1, input->step2, nDim * sizeof(MInt));
9001
9002 for(MInt i = 0; i < nDim; i++) {
9003 output->order[input->order[i]] = i;
9004 }
9005}
9006
9007template <MInt nDim>
9009 // output= make_unique<StructuredWindowMap<nDim>>();
9010 unique_ptr<StructuredWindowMap<nDim>> input;
9011 input = make_unique<StructuredWindowMap<nDim>>();
9012 mapCpy(output, input);
9013 output->Id1 = input->Id2;
9014 output->Id2 = input->Id1;
9015
9016 output->dc1 = input->dc2;
9017 output->dc2 = input->dc1;
9018
9019 memcpy(output->start2, input->start1, nDim * sizeof(MInt));
9020
9021 memcpy(output->end2, input->end1, nDim * sizeof(MInt));
9022 memcpy(output->step2, input->step1, nDim * sizeof(MInt));
9023 memcpy(output->start1, input->start2, nDim * sizeof(MInt));
9024 memcpy(output->end1, input->end2, nDim * sizeof(MInt));
9025 memcpy(output->step1, input->step2, nDim * sizeof(MInt));
9026
9027 for(MInt i = 0; i < nDim; i++) {
9028 output->order[input->order[i]] = i;
9029 }
9030}
9031
9032template <MInt nDim>
9034 unique_ptr<StructuredWindowMap<nDim>>& output) {
9035 output->Id1 = input->Id1;
9036 output->Id2 = input->Id2;
9037 memcpy(output->start1, input->start1, nDim * sizeof(MInt));
9038 memcpy(output->start2, input->start2, nDim * sizeof(MInt));
9039 memcpy(output->end1, input->end1, nDim * sizeof(MInt));
9040 memcpy(output->end2, input->end2, nDim * sizeof(MInt));
9041 memcpy(output->step1, input->step1, nDim * sizeof(MInt));
9042 memcpy(output->step2, input->step2, nDim * sizeof(MInt));
9043 memcpy(output->order, input->order, nDim * sizeof(MInt));
9044 output->BC = input->BC;
9045 output->Nstar = input->Nstar;
9046 output->SingularId = input->SingularId;
9047 output->dc1 = input->dc1;
9048 output->dc2 = input->dc2;
9049 memcpy(output->SingularBlockId, input->SingularBlockId, 4 * sizeof(MInt));
9050}
9051
9052template <MInt nDim>
9054 unique_ptr<StructuredWindowMap<nDim>> temp = make_unique<StructuredWindowMap<nDim>>();
9055 mapCpy(output, temp);
9056 for(MInt i = 0; i < nDim; i++) {
9057 if(temp->step1[i] < 0) {
9058 output->step1[i] = -temp->step1[i];
9059 output->start1[i] = temp->end1[i];
9060 output->end1[i] = temp->start1[i];
9061 output->step2[output->order[i]] = -temp->step2[temp->order[i]];
9062 output->start2[output->order[i]] = temp->end2[temp->order[i]];
9063 output->end2[output->order[i]] = temp->start2[temp->order[i]];
9064 }
9065 }
9066}
9067
9068template <MInt nDim>
9070 unique_ptr<StructuredWindowMap<nDim>>& output) {
9071 mapCpy(input, output);
9072 for(MInt i = 0; i < nDim; i++) {
9073 if(input->step1[i] < 0) {
9074 output->step1[i] = -input->step1[i];
9075 output->start1[i] = input->end1[i];
9076 output->end1[i] = input->start1[i];
9077 output->step2[output->order[i]] = -input->step2[input->order[i]];
9078 output->start2[output->order[i]] = input->end2[input->order[i]];
9079 output->end2[output->order[i]] = input->start2[input->order[i]];
9080 }
9081 }
9082}
9083
9084template <MInt nDim>
9086 unique_ptr<StructuredWindowMap<nDim>>& output) {
9087 unique_ptr<StructuredWindowMap<nDim>> out = make_unique<StructuredWindowMap<nDim>>();
9088 unique_ptr<StructuredWindowMap<nDim>> out1 = make_unique<StructuredWindowMap<nDim>>();
9089 mapInvert(input, out);
9090 mapNormalize1(out, out1);
9091 mapInvert(out1, output);
9092}
9093
9094template <MInt nDim>
9096 unique_ptr<StructuredWindowMap<nDim>>& input2,
9097 unique_ptr<StructuredWindowMap<nDim>>& output) {
9098 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9099 MInt shift, shift2;
9100 if(input1->Id1 != input2->Id1) {
9101 mapZero(output);
9102 } else {
9103 mapNormalize1(input1, output);
9104 mapNormalize1(input2, tmp);
9105 for(MInt i = 0; i < nDim; i++) {
9106 shift = 0;
9107 while(output->start1[i] + shift * output->step1[i] <= output->end1[i]) {
9108 if((output->start1[i] + shift * output->step1[i] >= tmp->start1[i])
9109 && (((output->start1[i] + shift * output->step1[i]) - (tmp->start1[i])) % (tmp->step1[i])) == 0)
9110 break;
9111 shift = shift + 1;
9112 }
9113 output->start1[i] = output->start1[i] + shift * output->step1[i];
9114 output->start2[output->order[i]] = output->start2[output->order[i]] + shift * output->step2[output->order[i]];
9115
9116 shift = 0;
9117
9118 while((output->end1[i] - shift * output->step1[i]) >= output->start1[i]) {
9119 if(((output->end1[i] - shift * output->step1[i]) <= tmp->end1[i])
9120 && ((output->end1[i] - shift * output->step1[i] - tmp->end1[i]) % tmp->step1[i]) == 0)
9121 break;
9122 ++shift;
9123 }
9124
9125 output->end1[i] = output->end1[i] - shift * output->step1[i];
9126 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9127
9128 shift = 0;
9129
9130 while(tmp->start1[i] + shift * tmp->step1[i] <= tmp->end1[i]) {
9131 if((tmp->start1[i] + shift * tmp->step1[i] >= output->start1[i])
9132 && ((tmp->start1[i] + (shift * tmp->step1[i]) - output->start1[i]) % output->step1[i]) == 0)
9133 break;
9134 ++shift;
9135 }
9136
9137 tmp->start1[i] = tmp->start1[i] + shift * tmp->step1[i];
9138 tmp->start2[tmp->order[i]] = tmp->start2[tmp->order[i]] + shift * tmp->step2[tmp->order[i]];
9139
9140 shift = 0;
9141 while(tmp->end1[i] - shift * tmp->step1[i] >= tmp->start1[i]) {
9142 if(((tmp->end1[i] - shift * tmp->step1[i]) <= output->end1[i])
9143 && ((tmp->end1[i] - shift * tmp->step1[i] - output->end1[i]) % output->step1[i]) == 0)
9144 break;
9145 ++shift;
9146 }
9147 tmp->end1[i] = tmp->end1[i] - shift * tmp->step1[i];
9148 tmp->end2[tmp->order[i]] = tmp->end2[tmp->order[i]] - shift * tmp->step2[tmp->order[i]];
9149
9150
9151 shift = 1;
9152 shift2 = 1;
9153
9154 while(output->step1[i] * shift != tmp->step1[i] * shift2) {
9155 if(output->step1[i] * shift < tmp->step1[i] * shift2) {
9156 ++shift;
9157 } else {
9158 ++shift2;
9159 }
9160 }
9161 output->step1[i] = shift * output->step1[i];
9162 output->step2[output->order[i]] = shift * output->step2[output->order[i]];
9163 tmp->step1[i] = shift2 * tmp->step1[i];
9164 tmp->step2[tmp->order[i]] = shift2 * tmp->step2[tmp->order[i]];
9165 }
9166
9167 unique_ptr<StructuredWindowMap<nDim>> tmp1 = make_unique<StructuredWindowMap<nDim>>();
9168 mapCpy(output, tmp1);
9169 mapInvert(tmp1, output);
9170 for(MInt i = 0; i < nDim; i++) {
9171 output->order[i] = tmp->order[output->order[i]];
9172 }
9173 output->Id2 = tmp->Id2;
9174 memcpy(output->start2, tmp->start2, nDim * sizeof(MInt));
9175 memcpy(output->end2, tmp->end2, nDim * sizeof(MInt));
9176 memcpy(output->step2, tmp->step2, nDim * sizeof(MInt));
9177
9178 mapCpy(output, tmp1);
9179 mapNormalize1(tmp1, output);
9180 if(input1->BC == -1 && input2->BC > 0) {
9181 output->BC = input2->BC;
9182 } else {
9183 output->BC = input1->BC;
9184 }
9185 }
9186}
9187
9188template <MInt nDim>
9190 unique_ptr<StructuredWindowMap<nDim>>& input2,
9191 unique_ptr<StructuredWindowMap<nDim>>& output) {
9192 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9193 mapInvert(input2, tmp);
9194 mapCombine11(input1, tmp, output);
9195 // return tmp;
9196}
9197
9198template <MInt nDim>
9200 unique_ptr<StructuredWindowMap<nDim>>& input2,
9201 unique_ptr<StructuredWindowMap<nDim>>& output) {
9202 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9203 mapInvert(input1, tmp);
9204 mapCombine11(tmp, input2, output);
9205}
9206
9207template <MInt nDim>
9209 unique_ptr<StructuredWindowMap<nDim>>& input2,
9210 unique_ptr<StructuredWindowMap<nDim>>& output) {
9211 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9212 unique_ptr<StructuredWindowMap<nDim>> tmp1 = make_unique<StructuredWindowMap<nDim>>();
9213 mapInvert(input1, tmp);
9214 mapInvert(input2, tmp1);
9215 mapCombine11(tmp, tmp1, output);
9216}
9217
9218template <MInt nDim>
9220 unique_ptr<StructuredWindowMap<nDim>>& input2,
9221 unique_ptr<StructuredWindowMap<nDim>>& output) {
9222 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9223 MInt shift, shift2;
9224 if(input1->Id1 != input2->Id1) {
9225 mapZero(output);
9226 } else {
9227 mapNormalize1(input1, output);
9228 mapNormalize1(input2, tmp);
9229 for(MInt i = 0; i < nDim; i++) {
9230 if(output->start1[i] == output->end1[i] || tmp->start1[i] == tmp->end1[i]) {
9231 shift = 0;
9232 while(output->start1[i] + shift * output->step1[i] <= output->end1[i]) {
9233 if((output->start1[i] + shift * output->step1[i] >= tmp->start1[i])
9234 && (((output->start1[i] + shift * output->step1[i]) - (tmp->start1[i])) % (tmp->step1[i])) == 0)
9235 break;
9236 shift = shift + 1;
9237 }
9238 output->start1[i] = output->start1[i] + shift * output->step1[i];
9239 output->start2[output->order[i]] = output->start2[output->order[i]] + shift * output->step2[output->order[i]];
9240
9241 shift = 0;
9242
9243 while((output->end1[i] - shift * output->step1[i]) >= output->start1[i]) {
9244 if(((output->end1[i] - shift * output->step1[i]) <= tmp->end1[i])
9245 && ((output->end1[i] - shift * output->step1[i] - tmp->end1[i]) % tmp->step1[i]) == 0)
9246 break;
9247 ++shift;
9248 }
9249
9250 output->end1[i] = output->end1[i] - shift * output->step1[i];
9251 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9252
9253 shift = 0;
9254
9255 while(tmp->start1[i] + shift * tmp->step1[i] <= tmp->end1[i]) {
9256 if((tmp->start1[i] + shift * tmp->step1[i] >= output->start1[i])
9257 && ((tmp->start1[i] + (shift * tmp->step1[i]) - output->start1[i]) % output->step1[i]) == 0)
9258 break;
9259 ++shift;
9260 }
9261
9262 tmp->start1[i] = tmp->start1[i] + shift * tmp->step1[i];
9263 tmp->start2[tmp->order[i]] = tmp->start2[tmp->order[i]] + shift * tmp->step2[tmp->order[i]];
9264
9265 shift = 0;
9266 while(tmp->end1[i] - shift * tmp->step1[i] >= tmp->start1[i]) {
9267 if(((tmp->end1[i] - shift * tmp->step1[i]) <= output->end1[i])
9268 && ((tmp->end1[i] - shift * tmp->step1[i] - output->end1[i]) % output->step1[i]) == 0)
9269 break;
9270 ++shift;
9271 }
9272 tmp->end1[i] = tmp->end1[i] - shift * tmp->step1[i];
9273 tmp->end2[tmp->order[i]] = tmp->end2[tmp->order[i]] - shift * tmp->step2[tmp->order[i]];
9274 }
9275
9276
9277 else {
9278 shift = 1;
9279 output->end1[i] = output->end1[i] - shift * output->step1[i];
9280 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9281 tmp->end1[i] = tmp->end1[i] - shift * tmp->step1[i];
9282 tmp->end2[tmp->order[i]] = tmp->end2[tmp->order[i]] - shift * tmp->step2[tmp->order[i]];
9283
9284
9285 shift = 0;
9286 while(output->start1[i] + shift * output->step1[i] <= output->end1[i]) {
9287 if((output->start1[i] + shift * output->step1[i] >= tmp->start1[i])
9288 && (((output->start1[i] + shift * output->step1[i]) - (tmp->start1[i])) % (tmp->step1[i])) == 0)
9289 break;
9290 shift = shift + 1;
9291 }
9292 output->start1[i] = output->start1[i] + shift * output->step1[i];
9293 output->start2[output->order[i]] = output->start2[output->order[i]] + shift * output->step2[output->order[i]];
9294
9295 shift = 0;
9296
9297 while((output->end1[i] - shift * output->step1[i]) >= output->start1[i]) {
9298 if(((output->end1[i] - shift * output->step1[i]) <= tmp->end1[i])
9299 && ((output->end1[i] - shift * output->step1[i] - tmp->end1[i]) % tmp->step1[i]) == 0)
9300 break;
9301 ++shift;
9302 }
9303
9304 output->end1[i] = output->end1[i] - shift * output->step1[i];
9305 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9306
9307
9308 shift = 0;
9309
9310 while(tmp->start1[i] + shift * tmp->step1[i] <= tmp->end1[i]) {
9311 if((tmp->start1[i] + shift * tmp->step1[i] >= output->start1[i])
9312 && ((tmp->start1[i] + (shift * tmp->step1[i]) - output->start1[i]) % output->step1[i]) == 0)
9313 break;
9314 ++shift;
9315 }
9316
9317 tmp->start1[i] = tmp->start1[i] + shift * tmp->step1[i];
9318 tmp->start2[tmp->order[i]] = tmp->start2[tmp->order[i]] + shift * tmp->step2[tmp->order[i]];
9319
9320 shift = 0;
9321 while(tmp->end1[i] - shift * tmp->step1[i] >= tmp->start1[i]) {
9322 if(((tmp->end1[i] - shift * tmp->step1[i]) <= output->end1[i])
9323 && ((tmp->end1[i] - shift * tmp->step1[i] - output->end1[i]) % output->step1[i]) == 0)
9324 break;
9325 ++shift;
9326 }
9327 tmp->end1[i] = tmp->end1[i] - shift * tmp->step1[i];
9328 tmp->end2[tmp->order[i]] = tmp->end2[tmp->order[i]] - shift * tmp->step2[tmp->order[i]];
9329
9330
9331 if(output->start1[i] <= output->end1[i] && tmp->start1[i] <= tmp->end1[i]) {
9332 shift = -1;
9333 output->end1[i] = output->end1[i] - shift * output->step1[i];
9334 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9335 tmp->end1[i] = tmp->end1[i] - shift * tmp->step1[i];
9336 tmp->end2[tmp->order[i]] = tmp->end2[tmp->order[i]] - shift * tmp->step2[tmp->order[i]];
9337 }
9338 }
9339
9340 shift = 1;
9341 shift2 = 1;
9342
9343 while(output->step1[i] * shift != tmp->step1[i] * shift2) {
9344 if(output->step1[i] * shift < tmp->step1[i] * shift2) {
9345 ++shift;
9346 } else {
9347 ++shift2;
9348 }
9349 }
9350 output->step1[i] = shift * output->step1[i];
9351 output->step2[output->order[i]] = shift * output->step2[output->order[i]];
9352 tmp->step1[i] = shift2 * tmp->step1[i];
9353 tmp->step2[tmp->order[i]] = shift2 * tmp->step2[tmp->order[i]];
9354 }
9355
9356 unique_ptr<StructuredWindowMap<nDim>> tmp1 = make_unique<StructuredWindowMap<nDim>>();
9357 mapCpy(output, tmp1);
9358 mapInvert(tmp1, output);
9359 for(MInt i = 0; i < nDim; i++) {
9360 output->order[i] = tmp->order[output->order[i]];
9361 }
9362 output->Id2 = tmp->Id2;
9363 memcpy(output->start2, tmp->start2, nDim * sizeof(MInt));
9364 memcpy(output->end2, tmp->end2, nDim * sizeof(MInt));
9365 memcpy(output->step2, tmp->step2, nDim * sizeof(MInt));
9366
9367 mapCpy(output, tmp1);
9368 mapNormalize1(tmp1, output);
9369 if(input1->BC == -1 && input2->BC > 0) {
9370 output->BC = input2->BC;
9371 } else {
9372 output->BC = input1->BC;
9373 }
9374 }
9375}
9376
9377template <MInt nDim>
9379 unique_ptr<StructuredWindowMap<nDim>>& input2,
9380 unique_ptr<StructuredWindowMap<nDim>>& output) {
9381 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9382 MInt shift;
9383 if(input1->Id1 != input2->Id1) {
9384 mapZero(output);
9385 } else {
9386 mapNormalize1(input1, output);
9387 mapNormalize1(input2, tmp);
9388 for(MInt i = 0; i < nDim; i++) {
9389 shift = 0;
9390 // go from map1.start1 to map1.end1 and find starting point of
9391 // overlapping part
9392 while(output->start1[i] + shift * output->step1[i] <= output->end1[i]) {
9393 // stop incrementing if map1.start1 >= map2.start2
9394
9395 if((output->start1[i] + shift * output->step1[i] >= tmp->start1[i])
9396 && (((output->start1[i] + shift * output->step1[i]) - (tmp->start1[i])) % (tmp->step1[i])) == 0)
9397 break;
9398 shift = shift + 1;
9399 }
9400
9401 output->start1[i] = output->start1[i] + shift * output->step1[i];
9402
9403 output->start2[output->order[i]] = output->start2[output->order[i]] + shift * output->step2[output->order[i]];
9404
9405 shift = 0;
9406
9407 // go from map1.end1 to map1.start1 and find ending point of
9408 // overlapping part
9409 while((output->end1[i] - shift * output->step1[i]) >= output->start1[i]) {
9410 // stop incrementing if map1.end1 <= map2.end2
9411 if(((output->end1[i] - shift * output->step1[i]) <= tmp->end1[i])
9412 && ((output->end1[i] - shift * output->step1[i] - tmp->end1[i]) % tmp->step1[i]) == 0)
9413 break;
9414 ++shift;
9415 }
9416
9417 output->end1[i] = output->end1[i] - shift * output->step1[i];
9418
9419 output->end2[output->order[i]] = output->end2[output->order[i]] - shift * output->step2[output->order[i]];
9420
9421 shift = 0;
9422 }
9423
9424 output->Id1 = output->Id2;
9425 output->Id2 = tmp->Id2;
9426 output->BC = tmp->BC;
9427 }
9428}
9429
9430template <MInt nDim>
9432 unique_ptr<StructuredWindowMap<nDim>>& input2,
9433 unique_ptr<StructuredWindowMap<nDim>>& output) {
9434 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9435 mapInvert(input2, tmp);
9436 mapCombineCell11(input1, tmp, output);
9437 // return tmp;
9438}
9439
9440template <MInt nDim>
9442 unique_ptr<StructuredWindowMap<nDim>>& input2,
9443 unique_ptr<StructuredWindowMap<nDim>>& output) {
9444 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9445 mapInvert(input1, tmp);
9446 mapCombineCell11(tmp, input2, output);
9447}
9448
9449template <MInt nDim>
9451 unique_ptr<StructuredWindowMap<nDim>>& input2,
9452 unique_ptr<StructuredWindowMap<nDim>>& output) {
9453 unique_ptr<StructuredWindowMap<nDim>> tmp = make_unique<StructuredWindowMap<nDim>>();
9454 unique_ptr<StructuredWindowMap<nDim>> tmp1 = make_unique<StructuredWindowMap<nDim>>();
9455 mapInvert(input1, tmp);
9456 mapInvert(input2, tmp1);
9457 mapCombineCell11(tmp, tmp1, output);
9458}
9459
9460template <MInt nDim>
9462 for(MInt dim = 0; dim < nDim; dim++) {
9463 map->start1[dim] = dataField[0 * nDim + dim];
9464 map->end1[dim] = dataField[1 * nDim + dim];
9465 map->step1[dim] = dataField[2 * nDim + dim];
9466 map->start2[dim] = dataField[3 * nDim + dim];
9467 map->end2[dim] = dataField[4 * nDim + dim];
9468 map->step2[dim] = dataField[5 * nDim + dim];
9469 map->order[dim] = dataField[6 * nDim + dim];
9470 }
9471
9472 map->Id1 = dataField[7 * nDim + 0];
9473 map->Id2 = dataField[7 * nDim + 1];
9474 // map->nDim = dataField[7 * nDim + 2]; removed
9475 map->BC = dataField[7 * nDim + 3];
9476 // map->constIndex = dataField[7 * nDim + 4]; removed
9477 map->face = dataField[7 * nDim + 5];
9478 map->dir = dataField[7 * nDim + 6];
9479 map->dc1 = dataField[7 * nDim + 7];
9480 map->dc2 = dataField[7 * nDim + 8];
9481 map->originShape = dataField[7 * nDim + 9];
9482 map->hasSponge = dataField[7 * nDim + 10];
9483 map->spongeThickness = dataField[7 * nDim + 11];
9484 map->beta = dataField[7 * nDim + 12];
9485 map->sigma = dataField[7 * nDim + 13];
9486 map->Nstar = dataField[7 * nDim + 14];
9487 map->SingularId = dataField[7 * nDim + 15];
9488}
9489
9490template <MInt nDim>
9492 for(MInt dim = 0; dim < nDim; dim++) {
9493 dataField[0 * nDim + dim] = map->start1[dim];
9494 dataField[1 * nDim + dim] = map->end1[dim];
9495 dataField[2 * nDim + dim] = map->step1[dim];
9496 dataField[3 * nDim + dim] = map->start2[dim];
9497 dataField[4 * nDim + dim] = map->end2[dim];
9498 dataField[5 * nDim + dim] = map->step2[dim];
9499 dataField[6 * nDim + dim] = map->order[dim];
9500 }
9501
9502 dataField[7 * nDim + 0] = map->Id1;
9503 dataField[7 * nDim + 1] = map->Id2;
9504 // dataField[7 * nDim + 2] = map->nDim; removed
9505 dataField[7 * nDim + 3] = map->BC;
9506 // dataField[7 * nDim + 4] = map->constIndex; removed
9507 dataField[7 * nDim + 5] = map->face;
9508 dataField[7 * nDim + 6] = map->dir;
9509 dataField[7 * nDim + 7] = map->dc1;
9510 dataField[7 * nDim + 8] = map->dc2;
9511 dataField[7 * nDim + 9] = map->originShape;
9512 dataField[7 * nDim + 10] = map->hasSponge;
9513 dataField[7 * nDim + 11] = map->spongeThickness;
9514 dataField[7 * nDim + 12] = map->beta;
9515 dataField[7 * nDim + 13] = map->sigma;
9516 dataField[7 * nDim + 14] = map->Nstar;
9517 dataField[7 * nDim + 15] = map->SingularId;
9518}
9519
9520// Explicit instantiations for 2D and 3D
9521template class FvStructuredSolverWindowInfo<2>;
9522template class FvStructuredSolverWindowInfo<3>;
void mAlloc(T *&a, const MLong N, const MString &objectName, MString function)
allocates memory for one-dimensional array 'a' of size N
Definition: alloc.h:173
static MBool propertyExists(const MString &name, MInt solver=m_noSolvers)
This function checks if a property exists in general.
Definition: context.cpp:494
void mapPrintSimple(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void writeConnectionWindowInformation3D(MFloat *periodicDisplacements)
void mapCombine12(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapCombineCell22(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void createAuxDataMap(const MInt, const MString, const std::vector< MInt > &, const std::vector< MInt > &, const MBool)
void createWaveCommunicationExchangeFlags(std::vector< std::unique_ptr< StructuredComm< nDim > > > &, std::vector< std::unique_ptr< StructuredComm< nDim > > > &, const MInt noVariables)
MBool mapCheck0d(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void mapNormalize2(std::unique_ptr< StructuredWindowMap< nDim > > &input, std::unique_ptr< StructuredWindowMap< nDim > > &output)
MInt mapCompare11(const std::unique_ptr< StructuredWindowMap< nDim > > &map1, const std::unique_ptr< StructuredWindowMap< nDim > > &map2)
void setBCsingular(std::unique_ptr< StructuredWindowMap< nDim > > &, std::unique_ptr< StructuredWindowMap< nDim > > &, const MInt)
MBool mapCheckWave(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void mapCombine22(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void deleteDuplicateWindows(std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &, std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &)
void mapCombine11(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void writeMapToArray(std::unique_ptr< StructuredWindowMap< nDim > > &map, MInt *array)
MBool mapCheck1d(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void readConnectionWindowInformation3D(MFloat *periodicDisplacments)
void mapCombineCell11(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapCreate(MInt Id1, MInt *start1, MInt *end1, MInt *step1, MInt Id2, MInt *start2, MInt *end2, MInt *step2, MInt *order, MInt BC, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void readMapFromArray(std::unique_ptr< StructuredWindowMap< nDim > > &map, MInt *array)
void mapPrint(const std::unique_ptr< StructuredWindowMap< nDim > > &input)
MBool mapCheck2d(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void setSpongeInformation(MInt noSpongeInfo, MFloat *beta, MFloat *sigma, MFloat *thickness, MInt *bcInfo, MInt informationType)
void mapCombineCell12(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void deleteDuplicateBCMaps(std::vector< std::unique_ptr< StructuredWindowMap< nDim > > > &)
void mapZero(std::unique_ptr< StructuredWindowMap< nDim > > &output)
MBool checkZonalBCMaps(std::unique_ptr< StructuredWindowMap< nDim > > &, std::unique_ptr< StructuredWindowMap< nDim > > &)
void mapCombineWave(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void createCommunicationExchangeFlags(std::vector< std::unique_ptr< StructuredComm< nDim > > > &, std::vector< std::unique_ptr< StructuredComm< nDim > > > &, const MInt, MFloat *const *const)
void mapCpy(std::unique_ptr< StructuredWindowMap< nDim > > &input, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapNormalize3(std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapNormalize1(std::unique_ptr< StructuredWindowMap< nDim > > &input, std::unique_ptr< StructuredWindowMap< nDim > > &output)
MInt mapCompare(std::unique_ptr< StructuredWindowMap< nDim > > &map1, std::unique_ptr< StructuredWindowMap< nDim > > &map2)
FvStructuredSolverWindowInfo(StructuredGrid< nDim > *, MPI_Comm, const MInt, const MInt, const MInt)
MBool addConnection(MInt connectiontype, MInt b1, MInt *p1, MInt b2, MInt *p2)
void periodicPointsChange(MFloat *pt, MInt type, MFloat *periodicDisplacements)
void mapInvert(std::unique_ptr< StructuredWindowMap< nDim > > &input, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapCombine21(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void mapInvert1(std::unique_ptr< StructuredWindowMap< nDim > > &output)
void createWindowMapping(MPI_Comm *channelIn, MPI_Comm *channelOut, MPI_Comm *channelWorld, MInt *channelRoots, MPI_Comm *commStg, MInt *commStgRoot, MInt *commStgRootGlobal, MPI_Comm *commBC2600, MInt *commBC2600Root, MInt *commBC2600RootGlobal, MPI_Comm *rescalingCommGrComm, MInt *rescalingCommGrRoot, MInt *rescalingCommGrRootGlobal, MPI_Comm *commPerRotOne, MPI_Comm *commPerRotTwo, MPI_Comm *commPerRotWorld, MInt *rotationRoots, MInt &perRotGroup, SingularInformation *singularity, MInt *hasSingularity, MPI_Comm *plenumComm, MInt *plenumRoots)
void mapCombineCell21(std::unique_ptr< StructuredWindowMap< nDim > > &input1, std::unique_ptr< StructuredWindowMap< nDim > > &input2, std::unique_ptr< StructuredWindowMap< nDim > > &output)
void readWindowCoordinates(MFloat *periodicDisplacements)
MBool mapCheck(std::unique_ptr< StructuredWindowMap< nDim > > &input)
MBool mapCheck3d(std::unique_ptr< StructuredWindowMap< nDim > > &input)
void defineArray(maiabd_type type, const MString &name, size_type totalCount)
Create a new array in the file.
Definition: parallelio.h:783
void writeArray(const T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Write array data to file. [MPI]
Definition: parallelio.h:1046
MBool hasDataset(const MString &name, MInt dimension)
Check if the file contains an dataset with the given name and dimension.
Definition: parallelio.h:467
void getAttribute(T *value, const MString &name, const MString &datasetName="")
Retrieve a file or dataset attribute.
Definition: parallelio.h:1788
MBool hasAttribute(const MString &name, const MString &path="")
Check if a given attribute exists in the file.
Definition: parallelio.h:714
void setAttribute(const T &value, const MString &name, const MString &datasetName="")
Set a file or dataset attribute. [MPI]
Definition: parallelio.h:1438
void readArray(T *array, const MString &name, size_type memoryStride=-1, size_type diskStride=-1)
Read array data from file. [MPI]
Definition: parallelio.h:1523
This class is a ScratchSpace.
Definition: scratch.h:758
T * getPointer() const
Deprecated: use begin() instead!
Definition: scratch.h:316
void fill(T val)
fill the scratch with a given value
Definition: scratch.h:311
iterator begin()
Definition: scratch.h:273
Structured grid class.
StructuredCommType
Definition: enums.h:343
@ PARTITION_NORMAL
Definition: enums.h:343
@ PERIODIC_BC_SINGULAR
Definition: enums.h:343
@ PERIODIC_BC
Definition: enums.h:343
@ SINGULAR
Definition: enums.h:343
void mTerm(const MInt errorCode, const MString &location, const MString &message)
Definition: functions.cpp:29
constexpr T mMax(const T &x, const T &y)
Definition: functions.h:94
MInt globalDomainId()
Return global domain id.
InfoOutFile m_log
int32_t MInt
Definition: maiatypes.h:62
uint32_t MUint
Definition: maiatypes.h:63
std::basic_string< char > MString
Definition: maiatypes.h:55
double MFloat
Definition: maiatypes.h:52
bool MBool
Definition: maiatypes.h:58
int MPI_Barrier(MPI_Comm comm, const MString &name)
same as MPI_Barrier
int MPI_Type_commit(MPI_Datatype *datatype, const MString &name)
same as MPI_Type_commit
int MPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm *newcomm, const MString &name, const MString &varname)
same as MPI_Comm_create, but updates the number of MPI communicators
int MPI_Group_incl(MPI_Group group, int n, const int ranks[], MPI_Group *newgroup, const MString &name)
same as MPI_Group_incl
int MPI_Comm_group(MPI_Comm comm, MPI_Group *group, const MString &name, const MString &varname)
same as MPI_Comm_group
int MPI_Type_contiguous(int count, MPI_Datatype old_type, MPI_Datatype *new_type_p, const MString &name)
same as MPI_Type_contiguous
int MPI_Allreduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm, const MString &name, const MString &sndvarname, const MString &rcvvarname)
same as MPI_Allreduce
int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm, const MString &name, const MString &varname)
same as MPI_Bcast
const MInt PIO_INT
Definition: parallelio.h:48
const MInt PIO_APPEND
Definition: parallelio.h:38
const MInt PIO_FLOAT
Definition: parallelio.h:46
const MInt PIO_READ
Definition: parallelio.h:40
Definition: kdtree.h:73
MInt locatenear(Point< DIM > pt, MFloat r, MInt *list, MInt nmax, MBool returnCellId=true)
Definition: kdtree.h:320
Definition: pointbox.h:20
MInt displacement[5][3]
Definition: contexttypes.h:19