OpenLB 1.8.1
Loading...
Searching...
No Matches
blockGeometry.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2011, 2014 Mathias J. Krause, Simon Zimny
4 * 2021 Clara Schragmann, Adrian Kummerlaender
5 * E-mail contact: info@openlb.net
6 * The most recent release of OpenLB can be downloaded at
7 * <http://www.openlb.net/>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with this program; if not, write to the Free
21 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 */
24
29#ifndef BLOCK_GEOMETRY_HH
30#define BLOCK_GEOMETRY_HH
31
33
36
39
40namespace olb {
41
42
43template<typename T, unsigned D>
44BlockGeometry<T,D>::BlockGeometry(Cuboid<T,D>& cuboid, int padding, int iCglob)
45 : BlockStructureD<D>(cuboid.getExtent(), padding),
46 _data(this->getNcells()),
47 _communicatable(_data),
48 _cuboid(cuboid),
49 _iCglob(iCglob),
50 _statistics(this),
51 clout(std::cout, ("BlockGeometry" + std::to_string(D) + "D"))
52{
53 _statistics.update(false);
54}
55
56template<typename T, unsigned D>
58{
59 return _statistics;
60}
61
62template<typename T, unsigned D>
67
68template<typename T, unsigned D>
70{
71 return _cuboid.getOrigin();
72}
73
74template<typename T, unsigned D>
76{
77 return _cuboid.getDeltaR();
78}
79
80template<typename T, unsigned D>
82{
83 return _data[0][this->getCellId(latticeR)];
84}
85
86template<typename T, unsigned D>
87int BlockGeometry<T,D>::get(const int latticeR[D]) const
88{
89 return _data[0][this->getCellId(latticeR)];
90}
91
92template<typename T, unsigned D>
93int BlockGeometry<T,D>::get(std::size_t iCell) const
94{
95 return _data[0][iCell];
96}
98template<typename T, unsigned D>
101 if (this->isInside(latticeR)) {
102 return _data[0][this->getCellId(latticeR)];
103 }
104 else {
105 return 0;
106 }
107}
108
109template<typename T, unsigned D>
110int BlockGeometry<T,D>::getMaterial(const int latticeR[D]) const
112 LatticeR<D> loc{latticeR};
113 if (this->isInside(loc)) {
114 return _data[0][this->getCellId(loc)];
116 else {
117 return 0;
118 }
119}
120
121template<typename T, unsigned D>
122void BlockGeometry<T,D>::set(LatticeR<D> latticeR, int material)
123{
124 set(this->getCellId(latticeR), material);
127template<typename T, unsigned D>
128void BlockGeometry<T,D>::set(const int latticeR[D], int material)
129{
130 set(this->getCellId(latticeR), material);
131}
132
133template<typename T, unsigned D>
134void BlockGeometry<T,D>::set(std::size_t iCell, int material)
136 resetStatistics();
137 _data[0][iCell] = material;
138}
139
140template<typename T, unsigned D>
142{
143 physR = _cuboid.getPhysR(latticeR);
144 return;
145}
146
147template<typename T, unsigned D>
149{
150 return _iCglob;
151}
153template<typename T, unsigned D>
155{
156 if constexpr (D == 3) {
157 return Vector<int,3>(this->getNx(), this->getNy(), this->getNz());
158 } else {
159 return Vector<int,2>(this->getNx(), this->getNy());
160 }
161 __builtin_unreachable();
162}
163
164template<typename T, unsigned D>
165template<typename DESCRIPTOR>
166int BlockGeometry<T,D>::clean(bool verbose, std::vector<int> bulkMaterials)
168 //using DESCRIPTOR = std::conditional_t<D==2,descriptors::D2Q5<>,descriptors::D3Q27<>>;
169int counter=0;
170 bool toClean = true;
171 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
172 // material not 0 and not in bulkMaterials
173 if (get(latticeR) != 0 && (! util::isContained(bulkMaterials, get(latticeR))) ) {
174 toClean = true;
175 for (int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
176 if ( util::isContained(bulkMaterials, get(latticeR + (descriptors::c<DESCRIPTOR>(iPop)))) ){
177 toClean = false;
179 }
180 if (toClean){
181 set(latticeR, 0);
182 counter++;
183 }
184 }
185 });
186 if (verbose) {
187 clout << "cleaned "<< counter << " outer boundary voxel(s)" << std::endl;
189 return counter;
190}
192template<typename T, unsigned D>
193int BlockGeometry<T,D>::outerClean(bool verbose, std::vector<int> bulkMaterials)
194{
195 int counter=0;
196 using DESCRIPTOR = std::conditional_t<D==2,descriptors::D2Q9<>,descriptors::D3Q27<>>;
197 bool toClean = false;
198 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
199 if (util::isContained(bulkMaterials, get(latticeR))) {
200 toClean = false;
201 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
202 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop))) == 0){
203 toClean = true;
204 }
205 }
206 if(toClean){
207 set(latticeR, 0);
208 counter++;
209 }
210 }
211 });
212 if (verbose) {
213 clout << "cleaned "<< counter << " outer fluid voxel(s)" << std::endl;
214 }
215 return counter;
216}
217
218template<typename T, unsigned D>
220{
221 int count2 = 0;
222 using DESCRIPTOR = std::conditional_t<D==2,descriptors::D2Q5<>,descriptors::D3Q7<>>;
223
224 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
225 if (get(latticeR) != 1 && get(latticeR) != 0) {
226 if constexpr (D==3){
227 bool var[7] = {false};
228 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
229 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop)))==1){
230 var[iPop] = true;
231 }
232 }
233 int comb[12][3]={{1,4,2},{1,4,3},{1,4,5},{1,4,6},{2,5,1},{2,5,3},{2,5,4},{2,5,6},{3,6,1},{3,6,2},{3,6,4},{3,6,5}};
234 for(int i = 0; i < 12; i++){
235 if (var[(comb[i][0])] == true
236 && var[(comb[i][1])] == true
237 && var[(comb[i][2])] == true){
238 set(latticeR, 1);
239 count2++;//count2 is the same value as before, count2 gets increased even if this cell has already been cleaned
240 }
241 }
242 } else {
243 int var = 0;
244 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
245 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop)))==1){
246 var = var+1;
247 }
248 }
249 if(var >= 3){
250 set(latticeR, 1);
251 count2++;//count2 differs from original count2
252 }
253 }
254 }
255 });
256
257 if (verbose) {
258 clout << "cleaned "<< count2 << " inner boundary voxel(s)" << std::endl;
259 }
260 return count2;
261}
262
263template<typename T, unsigned D>
264int BlockGeometry<T,D>::innerClean(int fromM, bool verbose)
265{
266 int count2 = 0;
267 using DESCRIPTOR = std::conditional_t<D==2,descriptors::D2Q5<>,descriptors::D3Q7<>>;
268
269 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
270 if (get(latticeR) != 1 && get(latticeR) != 0 && get(latticeR) == fromM) {
271 if constexpr (D==3){
272 bool var[7] = {false};
273 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
274 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop)))==1){
275 var[iPop] = true;
276 }
277 }
278 int comb[12][3]={{1,4,2},{1,4,3},{1,4,5},{1,4,6},{2,5,1},{2,5,3},{2,5,4},{2,5,6},{3,6,1},{3,6,2},{3,6,4},{3,6,5}};
279 for(int i = 0; i < 12; i++){
280 if (var[(comb[i][0])] == true
281 && var[(comb[i][1])] == true
282 && var[(comb[i][2])] == true){
283 set(latticeR, 1);
284 count2++;//count2 is the same value as before, count2 gets increased even if this cell has already been cleaned
285 }
286 }
287 } else {
288 int var = 0;
289 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
290 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop)))==1){
291 var = var+1;
292 }
293 }
294 if(var >= 3){
295 set(latticeR, 1);
296 count2++;//count2 differs from original count2
297 }
298 }
299 }
300 });
301
302 if (verbose){
303 clout << "cleaned "<< count2
304 << " inner boundary voxel(s) of Type " << fromM << std::endl;
305 }
306 return count2;
307}
308
309template<typename T, unsigned D>
311{
312 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
313 T physR[D] { };
314 bool output{};
315 getPhysR(physR, latticeR);
316 domain(&output, physR);
317 if (output) {
318 set(latticeR, 0);
319 }
320 });
321}
322
323template<typename T, unsigned D>
324bool BlockGeometry<T,D>::find(int material, std::vector<unsigned> offset,
325 std::vector<int> var)
326{
327 bool found = false;
328 for (var[0] = 0; var[0] < this->getNx(); var[0]++) {
329 for (var[1] = 0; var[1] < this->getNy(); var[1]++) {
330 if constexpr(D==3){
331 for (var[2] = 0; var[2] < this->getNz(); var[2]++) {
332 found = check(material, var, offset);
333 }
334 } else {
335 found = check(material, var, offset);
336 }
337 if (found) {
338 return found;
339 }
340 }
341 }
342 return found;
343}
344
345template<typename T, unsigned D>
346bool BlockGeometry<T,D>::check(int material, std::vector<int> var,
347 std::vector<unsigned> offset)
348{
349 bool found = true;
350 for (int iOffsetX = -offset[0]; iOffsetX <= (int) offset[0]; ++iOffsetX) {
351 for (int iOffsetY = -offset[1]; iOffsetY <= (int) offset[1]; ++iOffsetY) {
352 if constexpr (D==3){
353 for (int iOffsetZ = -offset[2]; iOffsetZ <= (int) offset[2]; ++iOffsetZ) {
354 if (getMaterial({var[0] + iOffsetX, var[1] + iOffsetY, var[2] + iOffsetZ}) != material) {
355 found = false;
356 }
357 }
358 } else {
359 if (getMaterial({var[0] + iOffsetX, var[1] + iOffsetY}) != material) {
360 found = false;
361 }
362 }
363 }
364 }
365 return found;
366}
367
368template<typename T, unsigned D>
370{
371 bool error = false;
372 using DESCRIPTOR = std::conditional_t<D==2,descriptors::D2Q9<>,descriptors::D3Q27<>>;
373 bool errorFound = false;
374 this->forSpatialLocations([&](LatticeR<D> latticeR)
375 {
376 if (get(latticeR) == 0) {
377 errorFound = false;
378 for(int iPop = 1; iPop < DESCRIPTOR::q; iPop++){
379 if(getMaterial(latticeR + (descriptors::c<DESCRIPTOR>(iPop))) == 1){
380 errorFound = true;
381 }
382 }
383 if(errorFound){
384 error = true;
385 }
386 }
387 });
388
389 if (verbose) {
390 if (error) {
391 clout << "error!" << std::endl;
392 }
393 else {
394 clout << "the model is correct!" << std::endl;
395 }
396 }
397 return error;
398}
399
400template<typename T, unsigned D>
401void BlockGeometry<T,D>::rename(int fromM, int toM)
402{
403 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
404 if (get(latticeR) == fromM) {
405 set(latticeR, toM);
406 }
407 });
408}
409
410template<typename T, unsigned D>
411void BlockGeometry<T, D>::rename(int fromM, int toM, IndicatorF<T, D>& condition)
412{
413 OstreamManager clout("rename");
414
415 Vector<T, D> physR;
416
417 Vector<T, D> min = condition.getMin();
418 Vector<T, D> max = condition.getMax();
419 LatticeR<D> latticeRmin= _cuboid.getLatticeR(min);
420 LatticeR<D> latticeRmax=_cuboid.getLatticeR(max);
421
422 this->forSpatialLocations(latticeRmin, latticeRmax, [&](LatticeR<D> latticeR) {
423 if (get(latticeR) == fromM) {
424 getPhysR(physR, latticeR);
425
426 bool inside[1];
427 condition(inside, physR.data());
428
429 if (inside[0]) {
430 set(latticeR, toM);
431 }
432 }
433 });
434}
435template<typename T, unsigned D>
436void BlockGeometry<T,D>::rename(int fromM, int toM, LatticeR<D> offset)
437{
438 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
439 if (get(latticeR) == fromM) {
440 bool found = true;
441 for (int iOffsetX = -offset[0]; iOffsetX <= (int) offset[0]; ++iOffsetX) {
442 for (int iOffsetY = -offset[1]; iOffsetY <= (int) offset[1]; ++iOffsetY) {
443 if constexpr (D == 3) {
444 for (int iOffsetZ = -offset[2]; iOffsetZ <= (int) offset[2]; ++iOffsetZ) {
445 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY, latticeR[2] + iOffsetZ}) != fromM) {
446 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY, latticeR[2] + iOffsetZ}) != 1245) {
447 found = false;
448 }
449 }
450 }
451 } else {
452 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY}) != fromM) {
453 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY}) != 1245) {
454 found = false;
455 }
456 }
457 }
458 }
459 }
460 if (found) {
461 set(latticeR, 1245); // TODO Replace this embarassing approach
462 }
463 }
464 });
465 rename(1245,toM);
466}
467
468template<typename T, unsigned D>
469void BlockGeometry<T,D>::rename(int fromM, int toM, int testM,
470 std::vector<int> testDirection)
471{
472 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
473 if (get(latticeR) == fromM) {
474 // flag that indicates the renaming of the current voxel, valid voxels are not renamed
475 bool isValid = true;
476 for (int iOffsetX = util::min(testDirection[0],0); iOffsetX <= util::max(testDirection[0],0); ++iOffsetX) {
477 for (int iOffsetY = util::min(testDirection[1],0); iOffsetY <= util::max(testDirection[1],0); ++iOffsetY) {
478 if constexpr (D == 3){
479 for (int iOffsetZ = util::min(testDirection[2],0); iOffsetZ <= util::max(testDirection[2],0); ++iOffsetZ) {
480 if (iOffsetX!=0 || iOffsetY!=0 || iOffsetZ!=0) {
481 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY, latticeR[2] + iOffsetZ}) != testM) {
482 isValid = false;
483 }
484 }
485 }
486 } else {
487 if (iOffsetX!=0 || iOffsetY!=0) {
488 if (getMaterial({latticeR[0] + iOffsetX, latticeR[1] + iOffsetY}) != testM) {
489 isValid = false;
490 }
491 }
492 }
493 }
494 }
495 if (!isValid) {
496 set(latticeR, toM);
497 }
498 }
499 });
500}
501
502
503template<typename T, unsigned D>
504void BlockGeometry<T,D>::rename(int fromM, int toM, int fluidM,
505 IndicatorF<T,D>& condition, Vector<int,D> discreteNormal)
506{
507 rename(fromM, toM, condition);
508 Vector<int,D> testDirection(discreteNormal);
509 Vector<T,D> physR;
510
511 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
512 if (get(latticeR) == toM) {
513 getPhysR(physR, latticeR);
514 bool inside[1];
515
516 condition(inside, physR.data());
517 if (inside[0]) {
518 if constexpr (D==3){
519 if (getMaterial({latticeR[0]+testDirection[0],latticeR[1]+testDirection[1],latticeR[2]+testDirection[2]})!=fluidM ||
520 getMaterial({latticeR[0]+2*testDirection[0],latticeR[1]+2*testDirection[1],latticeR[2]+2*testDirection[2]})!=fluidM ||
521 getMaterial({latticeR[0]-testDirection[0],latticeR[1]-testDirection[1],latticeR[2]-testDirection[2]})!=0 ) {
522 set(latticeR, fromM);
523 }
524 } else {
525 if (getMaterial({latticeR[0]+testDirection[0],latticeR[1]+testDirection[1]}) != fluidM ||
526 getMaterial({latticeR[0]+2*testDirection[0],latticeR[1]+2*testDirection[1]}) != fluidM ||
527 getMaterial({latticeR[0]-testDirection[0],latticeR[1]-testDirection[1]}) != 0) {
528 set(latticeR, fromM);
529 }
530 }
531 }
532 }
533 });
534}
535
536template<typename T, unsigned D>
537void BlockGeometry<T,D>::rename(int fromM, int toM, int fluidM,
538 IndicatorF<T,D>& condition)
539{
540 rename(fromM, toM, condition);
541 std::vector<int> testDirection = getStatistics().computeDiscreteNormal(toM);
542 T physR[D];
543 // values that have been incorrectly changed from "fromM to "toM" get assigned back to "fromM"
544 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
545 if (get(latticeR) == toM) {
546 getPhysR(physR, latticeR);
547 bool inside[1];
548 condition(inside, physR);
549 if (inside[0]) {
550 if constexpr(D==3){
551 if (getMaterial({latticeR[0]+testDirection[0],latticeR[1]+testDirection[1],latticeR[2]+testDirection[2]})!=fluidM ||
552 getMaterial({latticeR[0]+2*testDirection[0],latticeR[1]+2*testDirection[1],latticeR[2]+2*testDirection[2]})!=fluidM ||
553 getMaterial({latticeR[0]-testDirection[0],latticeR[1]-testDirection[1],latticeR[2]-testDirection[2]})!=0 ) {
554 set(latticeR, fromM);
555 }
556 } else {
557 if (getMaterial({latticeR[0]+testDirection[0],latticeR[1]+testDirection[1]})!=fluidM ||
558 getMaterial({latticeR[0]+2*testDirection[0],latticeR[1]+2*testDirection[1]})!=fluidM ||
559 getMaterial({latticeR[0]-testDirection[0],latticeR[1]-testDirection[1]})!=0 ) {
560 set(latticeR, fromM);
561 }
562 }
563 }
564 }
565 });
566}
567
568template<typename T, unsigned D>
569void BlockGeometry<T,D>::copyMaterialLayer(IndicatorF3D<T>& condition, int discreteNormal[D], int numberOfLayers)
570{
571 T physR[D];
572 this->forCoreSpatialLocations([&](LatticeR<D> latticeR) {
573 getPhysR(physR, latticeR);
574 bool inside[1];
575 condition(inside, physR);
576 if (inside[0]) {
577 for (int i = 0; i < numberOfLayers; i++) {
578 if (0 <= latticeR[0] + i * discreteNormal[0] && latticeR[0] + i * discreteNormal[0] < this->getNx() &&
579 0 <= latticeR[1] + i * discreteNormal[1] && latticeR[1] + i * discreteNormal[1] < this->getNy()){
580 if constexpr(D==3){
581 if(0 <= latticeR[2] + i * discreteNormal[2] && latticeR[2] + i * discreteNormal[2] < this->getNz()){
582 set({latticeR[0] + i * discreteNormal[0], latticeR[1] + i * discreteNormal[1], latticeR[2] + i * discreteNormal[2]}, get(latticeR));
583 }
584 } else {
585 set({latticeR[0] + i * discreteNormal[0], latticeR[1] + i * discreteNormal[1]}, get(latticeR));
586 }
587 }
588 }
589 }
590 });
591}
592
593template<typename T, unsigned D>
594void BlockGeometry<T,D>::regionGrowing(int fromM, int toM, LatticeR<D> seed,
595 std::vector<int> offset, std::map<std::vector<int>, int>* tmp)
596{
597 std::map<std::vector<int>, int> tmp2;
598 bool firstCall = false;
599 if (tmp == nullptr) {
600 tmp = &tmp2;
601 firstCall = true;
602 }
603
604 if (getMaterial(seed) == fromM) {
605 std::vector<int> found;
606 found.push_back(seed[0]);
607 found.push_back(seed[1]);
608 if constexpr(D==3){
609 found.push_back(seed[2]);
610 if (tmp->count(found) == 0) {
611 (*tmp)[found] = 2;
612 if (offset[0] != 0) {
613 regionGrowing(fromM, toM, {seed[0] + 1, seed[1], seed[2]}, offset, tmp);
614 regionGrowing(fromM, toM, {seed[0] - 1, seed[1], seed[2]}, offset, tmp);
615 }
616 if (offset[1] != 0) {
617 regionGrowing(fromM, toM, {seed[0], seed[1] + 1, seed[2]}, offset, tmp);
618 regionGrowing(fromM, toM, {seed[0], seed[1] - 1, seed[2]}, offset, tmp);
619 }
620 if (offset[2] != 0) {
621 regionGrowing(fromM, toM, {seed[0], seed[1], seed[2] + 1}, offset, tmp);
622 regionGrowing(fromM, toM, {seed[0], seed[1], seed[2] - 1}, offset, tmp);
623 }
624 }
625 } else {
626 if (tmp->count(found) == 0) {
627 (*tmp)[found] = 2;
628 if (offset[0] != 0) {
629 regionGrowing(fromM, toM, {seed[0] + 1, seed[1]}, offset, tmp);
630 regionGrowing(fromM, toM, {seed[0] - 1, seed[1]}, offset, tmp);
631 }
632 if (offset[1] != 0) {
633 regionGrowing(fromM, toM, {seed[0], seed[1] + 1}, offset, tmp);
634 regionGrowing(fromM, toM, {seed[0], seed[1] - 1}, offset, tmp);
635 }
636 }
637 }
638 }
639 if (firstCall) {
640 std::map<std::vector<int>, int>::iterator iter;
641 for (iter = tmp->begin(); iter != tmp->end(); iter++) {
642 if constexpr(D==3){
643 set((iter->first)[0],(iter->first)[1],(iter->first)[2], toM);
644 } else {
645 set((iter->first)[0],(iter->first)[1], toM);
646 }
647 }
648 }
649 return;
650}
651
652template<typename T, unsigned D>
653void BlockGeometry<T,D>::printLayer(std::vector<int> min, std::vector<int> max, bool linenumber)//each call of this function must be carefully changed(previous:(xo,x1,y0,y1),now:({x0,yo},{x1,z1}))
654{
655 for (int x = min[0]; x <= max[0]; x++) {
656 if (linenumber) {
657 clout << x << ": ";
658 }
659 for (int y = min[1]; y <= max[1]; y++) {
660 if constexpr (D==3){
661 for (int z = min[2]; z <= max[2]; z++) {
662 clout << getMaterial({x, y, z}) << " ";
663 }
664 if (max[1] - min[1] != 0 && max[2] - min[2] != 0) {
665 clout << std::endl;
666 }
667 } else {
668 clout << getMaterial({x, y}) << " ";
669 }
670 }
671 if (max[0] - min[0] != 0) {
672 clout << std::endl;
673 }
674 }
675 clout << std::endl;
676}
677
678template<typename T, unsigned D>
679void BlockGeometry<T,D>::printLayer(int direction, int layer, bool linenumber)
680{
681 assert(direction >= 0 && direction <= 2);
682 if constexpr(D==3){
683 switch (direction) {
684 case 0:
685 printLayer({layer, 0, 0},{layer, this->getNy() - 1, this->getNz() - 1}, linenumber);
686 break;
687 case 1:
688 printLayer({0, layer, 0}, {this->getNx() - 1, layer, this->getNz() - 1}, linenumber);
689 break;
690 case 2:
691 printLayer({0, 0, layer}, {this->getNx() - 1, this->getNy() - 1, layer}, linenumber);
692 break;
693 }
694 } else {
695 switch (direction) {
696 case 0:
697 printLayer({layer, 0}, {layer, this->getNy() - 1}, linenumber);
698 break;
699 case 1:
700 printLayer({0, layer}, {this->getNx() - 1, layer}, linenumber);
701 break;
702 }
703 }
704}
705
706template<typename T, unsigned D>
707void BlockGeometry<T,D>::printNode(std::vector<int> loc, int offset)
708{
709 for (int x = loc[0] - offset; x <= loc[0] + offset; x++) {
710 if constexpr (D==3) {
711 clout << "yz-plane_x=" << x - loc[0] << std::endl;
712 }
713 for (int y = loc[1] - offset; y <= loc[1] + offset; y++) {
714 if constexpr (D==3){
715 for (int z = loc[2] - offset; z <= loc[2] + offset; z++) {
716 clout << getMaterial({x, y, z}) << " ";
717 }
718 clout << std::endl;
719 } else {
720 clout << getMaterial({x, y}) << " ";
721 }
722 }
723 if constexpr (D==2){
724 clout << std::endl;
725 }
726 }
727}
728
729template<typename T, unsigned D>
731{
732 _statistics.getStatisticsStatus() = true;
733}
734
735template<typename T, unsigned D>
737{
738 return _data.getNblock();
739}
740
741template<typename T, unsigned D>
743{
744 return _data.getSerializableSize();
745}
746
747template<typename T, unsigned D>
748bool* BlockGeometry<T,D>::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode)
749{
750 std::size_t currentBlock = 0;
751 bool* dataPtr = nullptr;
752
753 this->registerSerializableOfConstSize(iBlock, sizeBlock, currentBlock, dataPtr, _data, loadingMode);
754
755 return dataPtr;
756}
757
758} // namespace olb
759
760#endif
Representation of the 2D block geometry view – header file.
Representation of a block geometry.
int innerClean(bool verbose=true)
Changes all cell materials which are not 0 or 1 to 1 if there is a non robust constiallation.
void rename(int fromM, int toM)
Replaces all material numbers (fromM) to another (toM)
Vector< T, D > getPhysR(LatticeR< D > latticeR) const
void reset(IndicatorF< T, D > &domain)
Resets all cell materials inside of a domain to 0.
const BlockGeometryStatistics< T, D > & getStatistics() const
Read only access to the associated block statistic.
int getMaterial(LatticeR< D > latticeR) const
returns the (iX,iY) entry in the 2D scalar field
int clean(bool verbose=true, std::vector< int > bulkMaterials={1})
Changes all cell materials which are not in bulkMaterials to 0 if there is no neighbour from bulkMate...
BlockGeometry(Cuboid< T, D > &cuboid, int padding, int iCglob=-1)
bool find(int material, std::vector< unsigned > offset, std::vector< int > var)
Returns the coordinates (iX,iY) of a voxel with a given material number (material) if there exists an...
int outerClean(bool verbose=true, std::vector< int > bulkMaterials={1})
Changes all cell materials from bulkMaterials to 0 if there is a neighbour with material 0.
bool check(int material, std::vector< int > var, std::vector< unsigned > offset)
Returns true if at position (iX,iY) and in a neighbourhood of size (offsetX,offsetY) only voxels with...
int getIcGlob() const
Read only access to the global iC number which is given !=-1 if the block geometries are part of a su...
void regionGrowing(int fromM, int toM, LatticeR< D > seed, std::vector< int > offset, std::map< std::vector< int >, int > *tmp=nullptr)
Replaces all material numbers (fromM) to another (toM) using a seed point and max....
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
T getDeltaR() const
Read only access to the voxel size given in SI units (meter)
void printNode(std::vector< int > loc, int offset=1)
Prints a chosen node and its neighbourhood.
bool checkForErrors(bool verbose=true) const
Checks for errors (searches for all outer voxels (=0) with an inner voxel (=1) as a direct neighbour)
void copyMaterialLayer(IndicatorF3D< T > &condition, int discreteNormal[D], int numberOfLayers)
Copy a layer of material numbers inside an indicator in a discrete normal direction.
bool * getBlock(std::size_t iBlock, std::size_t &sizeBlock, bool loadingMode) override
Return a pointer to the memory of the current block and its size for the serializable interface.
Vector< T, D > getOrigin() const
Read only access to the origin position given in SI units (meter)
Vector< int, D > getExtent() const
Returns the extend of the block in lattice units.
void printLayer(std::vector< int > min, std::vector< int > max, bool linenumber=false)
Prints a chosen part of the block geometry.
void set(LatticeR< D > latticeR, int material)
Write access to a material number.
std::size_t getSerializableSize() const override
Binary size for the serializer.
std::enable_if_t< sizeof...(L)==D, int > get(L... latticeR) const
Read-only access to a material number.
Base of a regular block.
IndicatorF3D is an application from .
Definition aliases.h:244
class for marking output with some text
Plain old scalar vector.
constexpr const T * data() const any_platform
Definition vector.h:172
constexpr int c(unsigned iPop, unsigned iDim) any_platform
Definition functions.h:83
bool isContained(const C &c, U object)
Check, if object is contained in iteratable container c.
Expr min(Expr a, Expr b)
Definition expr.cpp:249
Expr max(Expr a, Expr b)
Definition expr.cpp:245
Top level namespace for all of OpenLB.
Vector(T &&t, Ts &&... ts) -> Vector< std::remove_cvref_t< T >, 1+sizeof...(Ts)>
std::conditional_t< D==2, BlockGeometryStatistics2D< T >, BlockGeometryStatistics3D< T > > BlockGeometryStatistics
Definition aliases.h:167
std::conditional_t< D==2, IndicatorF2D< T >, IndicatorF3D< T > > IndicatorF
Definition aliases.h:247
D3Q27 lattice.
Definition common.h:315
D3Q7 lattice.
Definition common.h:173