OpenLB 1.7
Loading...
Searching...
No Matches
blockGeometryStatistics2D.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 * E-mail contact: info@openlb.net
5 * The most recent release of OpenLB can be downloaded at
6 * <http://www.openlb.net/>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public
19 * License along with this program; if not, write to the Free
20 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 */
23
28#ifndef BLOCK_GEOMETRY_STATISTICS_2D_HH
29#define BLOCK_GEOMETRY_STATISTICS_2D_HH
30
31#include <iostream>
32#include <math.h>
33#include <fstream>
34#include <sstream>
35#include "utilities/omath.h"
36
39
40namespace olb {
41
42template<typename T>
44 : _blockGeometry(blockGeometry),
45 clout(std::cout,"BlockGeometryStatistics2D")
46{
47 _statisticsUpdateNeeded = true;
48}
49
50
51template<typename T>
53{
54 return _statisticsUpdateNeeded;
55}
56
57template<typename T>
59{
60 return _statisticsUpdateNeeded;
61}
62
63
64template<typename T>
66{
67 const_this = const_cast<const BlockGeometryStatistics2D<T>*>(this);
68
69 if (getStatisticsStatus() ) {
70 _material2n.clear();
71 _blockGeometry->forCoreSpatialLocations([&](auto iX, auto iY) {
72 takeStatistics(iX, iY);
73 });
74
75 _nMaterials=int();
76 std::map<int, int>::iterator iter;
77 for (iter = _material2n.begin(); iter != _material2n.end(); iter++) {
78 _nMaterials++;
79 }
80
81 if (verbose) {
82 clout << "updated" << std::endl;
83 }
84 getStatisticsStatus() = false;
85 }
86}
87
88
89template<typename T>
91{
92 update();
93 return const_this->getNmaterials();
94}
95
96template<typename T>
98{
99 return _nMaterials;
100}
101
102template<typename T>
104{
105 update();
106 return const_this->getNvoxel(material);
107}
108
109template<typename T>
111{
112 try {
113 return _material2n.at(material);
114 }
115 catch (std::out_of_range& ex) {
116 return 0;
117 }
118}
119
120template<typename T>
122{
123 update();
124 return const_this->getMaterial2n();
125}
126
127template<typename T>
129{
130 return _material2n;
131}
132
133template<typename T>
135{
136 update();
137 return const_this->getNvoxel();
138}
139
140template<typename T>
142{
143 int total = 0;
144 for (const auto& material : _material2n ) {
145 total += material.second;
146 }
147 return total;
148}
149
150template<typename T>
152{
153 update();
154 return const_this->getMinLatticeR(material);
155}
156
157template<typename T>
158std::vector<int> BlockGeometryStatistics2D<T>::getMinLatticeR(int material) const
159{
160 try {
161 return _material2min.at(material);
162 }
163 catch (std::out_of_range& ex) {
164 std::vector<int> null;
165 return null;
166 }
167}
168
169template<typename T>
171{
172 update();
173 return const_this->getMaxLatticeR(material);
174}
175
176template<typename T>
177std::vector<int> BlockGeometryStatistics2D<T>::getMaxLatticeR(int material) const
178{
179 try {
180 return _material2max.at(material);
181 }
182 catch (std::out_of_range& ex) {
183 std::vector<int> null;
184 return null;
185 }
186}
187
188template<typename T>
189std::vector<T> BlockGeometryStatistics2D<T>::getMinPhysR(int material) const
190{
191 std::vector<T> tmp(2,T());
192 _blockGeometry->getPhysR(&(tmp[0]), &(getMinLatticeR(material)[0]));
193 return tmp;
194}
195
196template<typename T>
197std::vector<T> BlockGeometryStatistics2D<T>::getMaxPhysR(int material) const
198{
199 std::vector<T> tmp(2,T());
200 _blockGeometry->getPhysR(&(tmp[0]), &(getMaxLatticeR(material)[0]));
201 return tmp;
202}
203
204template<typename T>
206{
207 update();
208 return const_this->getLatticeExtend(material);
209}
210
211template<typename T>
212std::vector<T> BlockGeometryStatistics2D<T>::getLatticeExtend(int material) const
213{
214 try {
215 std::vector<T> extend;
216 for (int iDim = 0; iDim < 2; iDim++) {
217 extend.push_back(_material2max.at(material)[iDim] - _material2min.at(material)[iDim]);
218 }
219 return extend;
220 }
221 catch (std::out_of_range& ex) {
222 std::vector<T> null;
223 return null;
224 }
225}
226
227template<typename T>
229{
230 update();
231 return const_this->getPhysExtend(material);
232}
233
234template<typename T>
235std::vector<T> BlockGeometryStatistics2D<T>::getPhysExtend(int material) const
236{
237 std::vector<T> extend;
238 for (int iDim = 0; iDim < 2; iDim++) {
239 extend.push_back(getMaxPhysR(material)[iDim] - getMinPhysR(material)[iDim]);
240 }
241 return extend;
242}
243
244template<typename T>
246{
247 update();
248 return const_this->getPhysRadius(material);
249}
250
251template<typename T>
252std::vector<T> BlockGeometryStatistics2D<T>::getPhysRadius(int material) const
253{
254 std::vector<T> radius;
255 for (int iDim=0; iDim<2; iDim++) {
256 radius.push_back((getMaxPhysR(material)[iDim] - getMinPhysR(material)[iDim])/2.);
257 }
258 return radius;
259}
260
261template<typename T>
263{
264 update();
265 return const_this->getCenterPhysR(material);
266}
267
268template<typename T>
269std::vector<T> BlockGeometryStatistics2D<T>::getCenterPhysR(int material) const
270{
271 std::vector<T> center;
272 for (int iDim=0; iDim<2; iDim++) {
273 center.push_back(getMinPhysR(material)[iDim] + getPhysRadius(material)[iDim]);
274 }
275 return center;
276}
277
278template<typename T>
279std::vector<int> BlockGeometryStatistics2D<T>::getType(const int* input) const
280{
281 return const_this->getType(input[0], input[1]);
282}
283
284template<typename T>
285std::vector<int> BlockGeometryStatistics2D<T>::getType(int iX, int iY) const
286{
287 std::vector<int> discreteNormal(3, 0);
288
289 if (_blockGeometry->getMaterial({iX, iY}) != 1
290 && _blockGeometry->getMaterial({iX, iY}) != 0) {
291
293 if (_blockGeometry->getMaterial({iX, iY + 1}) != 1
294 && _blockGeometry->getMaterial({iX, iY + 1}) != 0
295 && _blockGeometry->getMaterial({iX, iY - 1}) != 1
296 && _blockGeometry->getMaterial({iX, iY - 1}) != 0) {
297
298 if (_blockGeometry->getMaterial({iX + 1, iY}) == 1) {
299 discreteNormal[0] = 0;
300 discreteNormal[1] = -1;
301 discreteNormal[2] = 0;
302 }
303
304 if (_blockGeometry->getMaterial({iX - 1, iY}) == 1) {
305 discreteNormal[0] = 0;
306 discreteNormal[1] = 1;
307 discreteNormal[2] = 0;
308 }
309 }
310
312 if (_blockGeometry->getMaterial({iX + 1, iY}) != 1
313 && _blockGeometry->getMaterial({iX + 1, iY}) != 0
314 && _blockGeometry->getMaterial({iX - 1, iY}) != 1
315 && _blockGeometry->getMaterial({iX - 1, iY}) != 0) {
316
317 if (_blockGeometry->getMaterial({iX, iY + 1}) == 1) {
318 discreteNormal[0] = 0;
319 discreteNormal[1] = 0;
320 discreteNormal[2] = -1;
321 }
322
323 if (_blockGeometry->getMaterial({iX, iY - 1}) == 1) {
324 discreteNormal[0] = 0;
325 discreteNormal[1] = 0;
326 discreteNormal[2] = 1;
327 }
328 }
329
331 if ( _blockGeometry->getMaterial({iX + 1, iY}) != 1
332 && _blockGeometry->getMaterial({iX + 1, iY}) != 0) {
333
334 if (_blockGeometry->getMaterial({iX, iY + 1}) != 1
335 && _blockGeometry->getMaterial({iX, iY + 1}) != 0
336 && _blockGeometry->getMaterial({iX + 1, iY + 1}) == 1) {
337 discreteNormal[0] = 1;
338 discreteNormal[1] = -1;
339 discreteNormal[2] = -1;
340 }
341
342 if (_blockGeometry->getMaterial({iX, iY - 1}) != 1
343 && _blockGeometry->getMaterial({iX, iY - 1}) != 0
344 && _blockGeometry->getMaterial({iX + 1, iY - 1}) == 1) {
345 discreteNormal[0] = 1;
346 discreteNormal[1] = -1;
347 discreteNormal[2] = 1;
348 }
349 }
350
352 if (_blockGeometry->getMaterial({iX - 1, iY}) != 1
353 && _blockGeometry->getMaterial({iX - 1, iY}) != 0) {
354
355 if (_blockGeometry->getMaterial({iX, iY + 1}) != 1
356 && _blockGeometry->getMaterial({iX, iY + 1}) != 0
357 && _blockGeometry->getMaterial({iX - 1, iY + 1}) == 1) {
358 discreteNormal[0] = 1;
359 discreteNormal[1] = 1;
360 discreteNormal[2] = -1;
361 }
362
363 if (_blockGeometry->getMaterial({iX, iY - 1}) != 1
364 && _blockGeometry->getMaterial({iX, iY - 1}) != 0
365 && _blockGeometry->getMaterial({iX - 1, iY - 1}) == 1) {
366 discreteNormal[0] = 1;
367 discreteNormal[1] = 1;
368 discreteNormal[2] = 1;
369 }
370 }
371
373 if (_blockGeometry->getMaterial({iX - 1, iY}) != 1
374 && _blockGeometry->getMaterial({iX - 1, iY}) != 0) {
375
376 if (_blockGeometry->getMaterial({iX, iY - 1}) != 1
377 && _blockGeometry->getMaterial({iX, iY - 1}) != 0
378 && _blockGeometry->getMaterial({iX - 1, iY - 1}) == 0) {
379 discreteNormal[0] = 2;
380 discreteNormal[1] = -1;
381 discreteNormal[2] = -1;
382 }
383
384 if (_blockGeometry->getMaterial({iX, iY + 1}) != 1
385 && _blockGeometry->getMaterial({iX, iY + 1}) != 0
386 && _blockGeometry->getMaterial({iX - 1, iY + 1}) == 0) {
387 discreteNormal[0] = 2;
388 discreteNormal[1] = -1;
389 discreteNormal[2] = 1;
390 }
391 }
392
394 if (_blockGeometry->getMaterial({iX + 1, iY}) != 1
395 && _blockGeometry->getMaterial({iX + 1, iY}) != 0) {
396
397 if (_blockGeometry->getMaterial({iX, iY - 1}) != 1
398 && _blockGeometry->getMaterial({iX, iY - 1}) != 0
399 && _blockGeometry->getMaterial({iX + 1, iY - 1}) == 0) {
400 discreteNormal[0] = 2;
401 discreteNormal[1] = 1;
402 discreteNormal[2] = -1;
403 }
404
405 if (_blockGeometry->getMaterial({iX, iY + 1}) != 1
406 && _blockGeometry->getMaterial({iX, iY + 1}) != 0
407 && _blockGeometry->getMaterial({iX + 1, iY + 1}) == 0) {
408 discreteNormal[0] = 2;
409 discreteNormal[1] = 1;
410 discreteNormal[2] = 1;
411 }
412 }
413 }
414 return discreteNormal;
415}
416
417template<typename T>
418std::vector<int> BlockGeometryStatistics2D<T>::computeNormal(int iX, int iY)
419{
420 return const_this->computeNormal(iX, iY);
421}
422
423template<typename T>
424std::vector<int> BlockGeometryStatistics2D<T>::computeNormal(int iX, int iY) const
425{
426 std::vector<int> normal (2,int(0));
427
428 if (iX != 0) {
429 if (_blockGeometry->getMaterial({iX - 1, iY}) == 1) {
430 normal[0] = -1;
431 }
432 }
433 if (iX != _nX - 1) {
434 if (_blockGeometry->getMaterial({iX + 1, iY}) == 1) {
435 normal[0] = 1;
436 }
437 }
438 if (iY != 0) {
439 if (_blockGeometry->getMaterial({iX, iY - 1}) == 1) {
440 normal[1] = -1;
441 }
442 }
443 if (iY != _nY - 1) {
444 if (_blockGeometry->getMaterial({iX, iY + 1}) == 1) {
445 normal[1] = 1;
446 }
447 }
448 return normal;
449}
450
451template<typename T>
453{
454 return const_this->computeNormal(material);
455}
456
457template<typename T>
458std::vector<T> BlockGeometryStatistics2D<T>::computeNormal(int material) const
459{
460 std::vector<T> normal (2,int(0));
461 std::vector<int> minC = getMinLatticeR(material);
462 std::vector<int> maxC = getMaxLatticeR(material);
463 for (int iX = minC[0]; iX<=maxC[0]; iX++) {
464 for (int iY = minC[1]; iY<=maxC[1]; iY++) {
465 if (_blockGeometry->getMaterial({iX,iY}) == material) {
466 normal[0]+=computeNormal(iX,iY)[0];
467 normal[1]+=computeNormal(iX,iY)[1];
468 }
469 }
470 }
471 T norm = util::sqrt(normal[0]*normal[0]+normal[1]*normal[1]);
472 if (norm>0.) {
473 normal[0]/=norm;
474 normal[1]/=norm;
475 }
476 return normal;
477}
478
479template<typename T>
480std::vector<int> BlockGeometryStatistics2D<T>::computeDiscreteNormal(int material, T maxNorm)
481{
482 return const_this->computeDiscreteNormal(material, maxNorm);
483}
484
485template<typename T>
486std::vector<int> BlockGeometryStatistics2D<T>::computeDiscreteNormal(int material, T maxNorm) const
487{
488 std::vector<T> normal = computeNormal(material);
489 std::vector<int> discreteNormal(2,int(0));
490
491 T smallestAngle = T(0);
492 for (int iX = -1; iX<=1; iX++) {
493 for (int iY = -1; iY<=1; iY++) {
494 T norm = util::sqrt(iX*iX+iY*iY);
495 if (norm>0.&& norm<maxNorm) {
496 T angle = (iX*normal[0] + iY*normal[1])/norm;
497 if (angle>=smallestAngle) {
498 smallestAngle=angle;
499 discreteNormal[0] = iX;
500 discreteNormal[1] = iY;
501 }
502 }
503 }
504 }
505 return discreteNormal;
506}
507
508template<typename T>
509bool BlockGeometryStatistics2D<T>::check(int material, int iX, int iY,
510 unsigned offsetX, unsigned offsetY)
511{
512 return const_this->check(material, iX, iY, offsetX, offsetY);
513}
514
515template<typename T>
516bool BlockGeometryStatistics2D<T>::check(int material, int iX, int iY,
517 unsigned offsetX, unsigned offsetY) const
518{
519 bool found = true;
520 for (int iOffsetX = -offsetX; iOffsetX <= (int) offsetX; ++iOffsetX) {
521 for (int iOffsetY = -offsetY; iOffsetY <= (int) offsetY; ++iOffsetY) {
522 if (_blockGeometry->getMaterial({iX + iOffsetX, iY + iOffsetY}) != material) {
523 found = false;
524 }
525 }
526 }
527 return found;
528}
529
530template<typename T>
531bool BlockGeometryStatistics2D<T>::find(int material, unsigned offsetX,
532 unsigned offsetY, int& foundX, int& foundY)
533{
534 return const_this->find(material, offsetX, offsetY, foundX, foundY);
535}
536
537template<typename T>
538bool BlockGeometryStatistics2D<T>::find(int material, unsigned offsetX,
539 unsigned offsetY, int& foundX, int& foundY) const
540{
541 bool found = false;
542 for (foundX = 0; foundX < _nX; foundX++) {
543 for (foundY = 0; foundY < _nY; foundY++) {
544 found = check(material, foundX, foundY, offsetX, offsetY);
545 if (found) {
546 return found;
547 }
548 }
549 }
550 return found;
551}
552
553template<typename T>
555{
556 update();
557 return const_this->print();
558}
559
560template<typename T>
562{
563 try {
564 std::map<int, int>::iterator iter;
565 for (const auto& material : _material2n) {
566 clout << "materialNumber=" << material.first
567 << "; count=" << material.second
568 << "; minLatticeR=(" << _material2min.at(material.first)[0] <<","<< _material2min.at(material.first)[1] <<")"
569 << "; maxLatticeR=(" << _material2max.at(material.first)[0] <<","<< _material2max.at(material.first)[1] <<")"
570 << std::endl;
571 }
572 }
573 catch (std::out_of_range& ex)
574 { }
575}
576
577template<typename T>
579{
580
581 int type = _blockGeometry->getMaterial({iX, iY});
582 if (_material2n.count(type) == 0) {
583 _material2n[type] = 1;
584 std::vector<int> minCo;
585 std::vector<int> maxCo;
586 minCo.push_back(iX);
587 minCo.push_back(iY);
588 _material2min[type] = minCo;
589 maxCo.push_back(iX);
590 maxCo.push_back(iY);
591 _material2max[type] = maxCo;
592
593 }
594 else {
595 _material2n[type]++;
596 if (iX < _material2min[type][0]) {
597 _material2min[type][0] = iX;
598 }
599 if (iY < _material2min[type][1]) {
600 _material2min[type][1] = iY;
601 }
602 if (iX > _material2max[type][0]) {
603 _material2max[type][0] = iX;
604 }
605 if (iY > _material2max[type][1]) {
606 _material2max[type][1] = iY;
607 }
608 }
609}
610
611// This function compares two discrete normals (discreteNormal, discreteNormal2) in case of a duplicate assignment of boundary types.
612// The goal of this function is to combine these special boundaryVoxels to an existing one (in this case boundary or externalEdge) according to
613// the x-, y- and z-values of their discrete normals.
614// In the following the algorithm is declared only for the x value, but it is also valid for the y and z values.
615//
616// for x1 = x2, the new value of x is x1 (1)
617// for x1*x2 = -1, the new value of x is 0 (2)
618// for x1*x2 = 0, the new value is 0 (3)
619//
620// It may be possible that all three values equal 0. To avoid that the values are tested again (x²+y²+z²==0) and the loosest assumption (3) is
621// redefined to.
622//
623// If x,y and z == 0 --> find those x,y or z which are 0 because of (3) and redefine them to the value !=0
624//
625// Additionally the calculated entries are multiplied with (-1) to get the right existing boundary.
626
627} // namespace olb
628
629#endif
Representation of a statistic for a 2D geometry – header file.
Representation of the 2D block geometry view – header file.
std::vector< int > computeNormal(int iX, int iY)
Returns normal that points into the fluid for paraxial surfaces.
std::vector< int > getMaxLatticeR(int material)
Returns the max. lattice position in each direction.
std::map< int, int > getMaterial2n()
Returns the map with the numbers of voxels for each material.
std::vector< int > getMinLatticeR(int material)
Returns the min. lattice position in each direction.
std::vector< T > getLatticeExtend(int material)
Returns the lattice extend as length in each direction.
bool & getStatisticsStatus()
Read and write access to a flag, which indicates if an uptate is needed (=true)
std::vector< T > getCenterPhysR(int material)
Returns the center position.
bool check(int material, int iX, int iY, unsigned offsetX, unsigned offsetY)
int getNvoxel()
Returns the number of voxels with material!=0.
std::vector< T > getPhysRadius(int material)
Returns the phys radius as length in each direction.
std::vector< T > getPhysExtend(int material)
Returns the phys extend as length in each direction.
std::vector< T > getMaxPhysR(int material) const
Returns the max. phys position in each direction.
std::vector< T > getMinPhysR(int material) const
Returns the min. phys position in each direction.
void update(bool verbose=true)
Updates the statistics if it is really needed.
BlockGeometryStatistics2D(BlockGeometry< T, 2 > *blockGeometry)
int getNmaterials()
Returns the number of different materials.
std::vector< int > getType(const int *input) const
Returns the boundary type which is characterized by a discrete normal (c.f. Zimny)
std::vector< int > computeDiscreteNormal(int material, T maxNorm=1.1)
Returns discrete normal with norm maxNorm that points into the fluid for paraxial surfaces maxNorm=1....
bool find(int material, unsigned offsetX, unsigned offsetY, int &iX, int &iY)
Representation of a block geometry.
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
Top level namespace for all of OpenLB.
constexpr T norm(const ScalarVector< T, D, IMPL > &a)
Euclidean vector norm.