OpenLB 1.8.1
Loading...
Searching...
No Matches
superGeometry.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2013, 2014 Mathias J. Krause, Peter Weisbrod
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 SUPER_GEOMETRY_HH
29#define SUPER_GEOMETRY_HH
30
31#include "utilities/omath.h"
32#include <math.h>
33#include <iostream>
34#include <string>
35#include <vector>
36
37#include "geometry/cuboid.h"
40
43
48
49#include "io/ostreamManager.h"
50#include "io/superVtmWriter2D.h"
51#include "io/superVtmWriter3D.h"
52
53namespace olb {
54
55
56template<typename T, unsigned D>
58 LoadBalancer<T>& loadBalancer,
59 int overlap):
60 SuperStructure<T,D>(cuboidDecomposition, loadBalancer, overlap),
61 _communicator(new SuperCommunicator<T,SuperGeometry<T,D>>(*this)),
62 _communicationNeeded(false),
63 _statistics(this),
64 _clout(std::cout, ("SuperGeometry" + std::to_string(D) + "D")),
65 _iConstructionT{0},
66 _writeIncrementalVtkEnabled{true}
67{
68 for (int iCloc=0; iCloc < this->getLoadBalancer().size(); iCloc++) {
69 int iCglob = this->getLoadBalancer().glob(iCloc);
70 _block.emplace_back(
71 new BlockGeometry<T,D>(cuboidDecomposition.get(iCglob), overlap, iCglob));
72 }
73
74 _communicator->template requestField<descriptors::MATERIAL>();
75 _communicator->requestOverlap(this->_overlap);
76 _communicator->exchangeRequests();
77
78 _statistics.getStatisticsStatus() = true;
79 _communicationNeeded = true;
80 updateStatistics(false);
81
82 //writeIncrementalVTK();
83}
84
85template<typename T, unsigned D>
87{
88 if (_writeIncrementalVtkEnabled) {
89 SuperVTMwriter<T,D> writer("geometry");
90 if (_iConstructionT == 0) {
91 writer.createMasterFile();
92 }
93 SuperGeometryF<T,D> geometryF(*this);
94 writer.addFunctor(geometryF);
95 writer.write(_iConstructionT++);
96 }
97}
98
99template<typename T, unsigned D>
101{
102 if ( this->getLoadBalancer().rank(latticeR[0]) == singleton::mpi().getRank() ) {
103 return _block[this->getLoadBalancer().loc(latticeR[0])]->get(latticeR.data()+1);
104 } else {
105 throw std::domain_error("read only access to data which is not available locally");
106 }
107}
109template<typename T, unsigned D>
112 int material = 0;
113 if ( this->getLoadBalancer().rank(latticeR[0]) == singleton::mpi().getRank() ) {
114 material = _block[this->getLoadBalancer().loc(latticeR[0])]->get(latticeR.data()+1);
115 }
116#ifdef PARALLEL_MODE_MPI
117 singleton::mpi().bCast(&material, 1, this->_loadBalancer.rank(latticeR[0]));
118#endif
119 return material;
120}
121
122template<typename T, unsigned D>
124{
125 return this->_cuboidDecomposition.getPhysR(latticeR);
126}
127
128template<typename T, unsigned D>
129void SuperGeometry<T,D>::getPhysR(T output[D], const int latticeR[D+1]) const
131 auto physR = this->_cuboidDecomposition.getPhysR(latticeR);
132 std::copy(physR.data(), physR.data() + D, output);
133}
135template<typename T, unsigned D>
137{
138 _statistics.getStatisticsStatus() = true;
139 return *_block[locIC];
140}
142template<typename T, unsigned D>
144{
145 return *_block[locIC];
146}
148template<typename T, unsigned D>
149template <typename BLOCK>
151{
152 _statistics.getStatisticsStatus() = true;
153 return *_block[locIC];
154}
156template<typename T, unsigned D>
157template <typename BLOCK>
158const BLOCK& SuperGeometry<T,D>::getBlock(int locIC) const
160 return *_block[locIC];
162
163template<typename T, unsigned D>
166 if (this->_communicationNeeded) {
167 this->communicate();
168 getStatisticsStatus()=true;
170 return _statistics;
171}
172
173template<typename T, unsigned D>
175{
176 return _statistics;
177}
178
179template<typename T, unsigned D>
181{
182 return _statistics.getStatisticsStatus();
183}
184
185template<typename T, unsigned D>
187{
188 return _statistics.getStatisticsStatus();
190
191template<typename T, unsigned D>
193{
194 if (this->_communicationNeeded) {
195 this->communicate();
196 getStatisticsStatus()=true;
198 _statistics.update(verbose);
199 for (unsigned iC=0; iC<_block.size(); iC++) {
200 _block[iC]->getStatistics().update(verbose);
201 }
202}
203
204template<typename T, unsigned D>
205template<typename DESCRIPTOR>
206int SuperGeometry<T,D>::clean(bool verbose, std::vector<int> bulkMaterials)
207{
208 this->communicate();
209 int counter=0;
210 for (unsigned iC=0; iC<_block.size(); iC++) {
211 counter+=_block[iC]->template clean <DESCRIPTOR>(false, bulkMaterials);
213#ifdef PARALLEL_MODE_MPI
214 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
215#endif
216
217 if (verbose) {
218 _clout << "cleaned "<< counter << " outer boundary voxel(s)" << std::endl;
219 }
220 _statistics.getStatisticsStatus() = true;
221 this->_communicationNeeded = true;
222 writeIncrementalVTK();
223 return counter;
224}
225
226template<typename T, unsigned D>
227int SuperGeometry<T,D>::outerClean(bool verbose, std::vector<int> bulkMaterials)
228{
229 this->communicate();
230 int counter=0;
231 for (unsigned iC=0; iC<_block.size(); iC++) {
232 counter+=_block[iC]->outerClean(false, bulkMaterials);
233 }
234#ifdef PARALLEL_MODE_MPI
235 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
236#endif
237
238 if (verbose) {
239 _clout << "cleaned "<< counter << " outer fluid voxel(s)" << std::endl;
240 }
241 _statistics.getStatisticsStatus() = true;
242 this->_communicationNeeded = true;
243 writeIncrementalVTK();
244 return counter;
245}
246
247template<typename T, unsigned D>
249{
250 this->communicate();
251 int counter=0;
252 for (unsigned iC=0; iC<_block.size(); iC++) {
253 counter+=_block[iC]->innerClean(false);
254 }
255#ifdef PARALLEL_MODE_MPI
257 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
258#endif
259
260 if (verbose) {
261 _clout << "cleaned "<< counter << " inner boundary voxel(s)" << std::endl;
262 }
263 _statistics.getStatisticsStatus() = true;
264 this->_communicationNeeded = true;
265 writeIncrementalVTK();
266 return counter;
267}
268
269template<typename T, unsigned D>
270int SuperGeometry<T,D>::innerClean(int bcType, bool verbose)
271{
272 this->communicate();
273 int counter=0;
274 for (unsigned iC=0; iC<_block.size(); iC++) {
275 counter+=_block[iC]->innerClean(bcType,false);
276 }
277#ifdef PARALLEL_MODE_MPI
278 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
279#endif
280
281 if (verbose) {
282 _clout << "cleaned "<< counter << " inner boundary voxel(s) of Type " << bcType << std::endl;
283 }
284 _statistics.getStatisticsStatus() = true;
285 this->_communicationNeeded = true;
286 writeIncrementalVTK();
287 return counter;
288}
289
290template<typename T, unsigned D>
292{
293 updateStatistics(verbose);
294 bool error = false;
295 for (unsigned iC=0; iC<_block.size(); iC++) {
296 if (_block[iC]->checkForErrors(false)) {
297 error = true;
298 }
299 }
300 if (verbose) {
301 if (error) {
302 this->_clout << "error!" << std::endl;
303 }
304 else {
305 this->_clout << "the model is correct!" << std::endl;
306 }
307 }
308 return error;
309}
310
311template<typename T, unsigned D>
313{
314 this->communicate();
315 for (unsigned iC = 0; iC < _block.size(); ++iC) {
316 _block[iC]->reset(domain);
317 }
318 _statistics.getStatisticsStatus() = true;
319 this->_communicationNeeded = true;
320 writeIncrementalVTK();
321}
322
323template<typename T, unsigned D>
324void SuperGeometry<T,D>::rename(int fromM, int toM)
325{
326 this->communicate();
327 for (unsigned iC=0; iC<_block.size(); iC++) {
328 _block[iC]->rename(fromM,toM);
329 }
330 _statistics.getStatisticsStatus() = true;
331 this->_communicationNeeded = true;
332 writeIncrementalVTK();
333}
334
335template<typename T, unsigned D>
336void SuperGeometry<T,D>::rename(int fromM, int toM, FunctorPtr<IndicatorF<T,D>>&& condition)
337{
338 this->communicate();
339 for (unsigned iC=0; iC<_block.size(); iC++) {
340 _block[iC]->rename(fromM,toM,*condition);
341 }
342 _statistics.getStatisticsStatus() = true;
343 writeIncrementalVTK();
344}
345
346template<typename T, unsigned D>
347void SuperGeometry<T,D>::rename(int fromM, int toM, LatticeR<D> offset)
348{
349 LatticeR<D> overlap (this->_overlap);
350 if ( offset <= overlap ){
351 _communicator->communicate();
352 for (unsigned iC=0; iC<_block.size(); iC++) {
353 _block[iC]->rename(fromM,toM,offset);
354 }
355 _statistics.getStatisticsStatus() = true;
356 this->_communicationNeeded = true;
357 writeIncrementalVTK();
358 }else{
359 _clout << "error rename only implemented for offset<=overlap" << std::endl;
360 }
361}
362
363template<typename T, unsigned D>
364void SuperGeometry<T,D>::rename(int fromM, int toM, int testM, Vector<int,D> testDirection)
365{
366 if ( testDirection[0]*testDirection[0]<=(this->_overlap)*(this->_overlap)
367 && testDirection[1]*testDirection[1]<=(this->_overlap)*(this->_overlap) ){
368 if constexpr (D==3){
369 if(testDirection[2]*testDirection[2]<=(this->_overlap)*(this->_overlap)){
370 _communicator->communicate();
371 for (unsigned iC=0; iC<_block.size(); iC++) {
372 _block[iC]->rename(fromM,toM,testM,testDirection);
373 }
374 _statistics.getStatisticsStatus() = true;
375 this->_communicationNeeded = true;
376 }
377 }else{
378 _communicator->communicate();
379 for (unsigned iC=0; iC<_block.size(); iC++) {
380 _block[iC]->rename(fromM,toM,testM,testDirection);
381 }
382 _statistics.getStatisticsStatus() = true;
383 this->_communicationNeeded = true;
384 }
385 writeIncrementalVTK();
386 } else {
387 _clout << "error rename only implemented for |testDirection[i]|<=overlap" << std::endl;
388 }
389}
390
391template<typename T, unsigned D>
392void SuperGeometry<T,D>::rename(int fromBcMat, int toBcMat, int fluidMat,
393 IndicatorF<T,D>& condition)
394{
395 if (this->_overlap>1) {
396 this->communicate();
397 rename(fromBcMat, toBcMat, condition);
398 Vector<int,D> testDirection = this->getStatistics().computeDiscreteNormal(toBcMat);
399 this->communicate();
400 for (unsigned iC=0; iC < _block.size(); iC++) {
401 _block[iC]->rename(fromBcMat,toBcMat,fluidMat,condition,testDirection);
402 }
403 _statistics.getStatisticsStatus() = true;
404 this->_communicationNeeded = true;
405 writeIncrementalVTK();
406 }
407 else {
408 _clout << "error rename only implemented for overlap>=2" << std::endl;
409 }
410}
411
412template<typename T, unsigned D>
413void SuperGeometry<T,D>::rename(int fromBcMat, int toBcMat, int fluidMat,
414 FunctorPtr<IndicatorF<T,D>>&& condition)
415{
416 if (this->_overlap>1) {
417 _communicator->communicate();
418 rename(fromBcMat, toBcMat, *condition);
419 Vector<int,D> testDirection = this->getStatistics().computeDiscreteNormal(toBcMat);
420 _communicator->communicate();
421 for (unsigned iC=0; iC<_block.size(); iC++) {
422 _block[iC]->rename(fromBcMat,toBcMat,fluidMat,*condition,testDirection);
423 }
424 _statistics.getStatisticsStatus() = true;
425 this->_communicationNeeded = true;
426 writeIncrementalVTK();
427 }
428 else {
429 _clout << "error rename only implemented for overlap>=2" << std::endl;
430 }
431}
432
433
434template<typename T, unsigned D>
436{
437 this->_cuboidDecomposition.print();
438 getStatistics().print();
439}
440
441
442template<typename T, unsigned D>
443void SuperGeometry<T,D>::print(const T physR[D], int offset)
444{
445 if (offset >= this->_overlap) {
446 _clout << "Warning! the offset is larger than overlap, set offset to _overlap = " << this->_overlap << std::endl;
447 offset=this->_overlap;
448 }
449 int latticeR[D+1];
450
451 if ( this->_cuboidDecomposition.getLatticeR(latticeR, physR) ) {
452 int iCglob = latticeR[0];
453
454 std::vector<int> loc(D, 0);
455 if constexpr (D==3) {
456 loc[0] = latticeR[1];
457 loc[1] = latticeR[2];
458 loc[2] = latticeR[3];
459 _clout << "physR(center)" << "=" << "{" << latticeR[1] << "," << latticeR[2] << "," << latticeR[3] << "}" << std::endl;
460 }
461 else {
462 loc[0] = latticeR[1];
463 loc[1] = latticeR[2];
464 _clout << "physR(center)" << "=" << "{" << latticeR[1] << "," << latticeR[2] << "}" << std::endl;
465 }
466
467 _block[this->getLoadBalancer().loc(iCglob)]->printNode(loc,offset);
468
469 }
470 else {
471 _clout << "this point isn't inside the geometry" << std::endl;
472 }
473}
474
475template<typename T, unsigned D>
476std::unique_ptr<SuperIndicatorF<T,D>> SuperGeometry<T,D>::getMaterialIndicator(
477 std::vector<int>&& materials)
478{
479 static_assert(std::is_base_of<SuperIndicatorF<T,D>, SuperIndicatorMaterial<T,D>>::value,
480 "Indicator to be constructed is SuperIndicatorF implementation");
481
482 return std::unique_ptr<SuperIndicatorF<T,D>>(
483 new SuperIndicatorMaterial<T,D>(*this, std::forward<std::vector<int>>(materials))
484 );
485}
486
487template<typename T, unsigned D>
488std::unique_ptr<SuperIndicatorF<T,D>> SuperGeometry<T,D>::getMaterialIndicator(int material)
489{
490 return this->getMaterialIndicator(std::vector<int> { material });
491}
492
493template<typename T, unsigned D>
495{
496 return std::accumulate(_block.begin(), _block.end(), size_t(0), [](std::size_t sum, auto& b) -> std::size_t {
497 return sum + b->getNblock();
498 });
499}
500
501
502template<typename T, unsigned D>
504{
505 return std::accumulate(_block.begin(), _block.end(), size_t(0), [](std::size_t sum, auto& b) -> std::size_t {
506 return sum + b->getSerializableSize();
507 });
508}
509
510template<typename T, unsigned D>
511bool* SuperGeometry<T,D>::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode)
512{
513 std::size_t currentBlock = 0;
514 bool* dataPtr = nullptr;
515
516 for (std::size_t iC=0; iC < _block.size(); ++iC) {
517 registerSerializableOfConstSize(iBlock, sizeBlock, currentBlock, dataPtr, getBlock(iC), loadingMode);
518 }
519
520 return dataPtr;
521}
522
523} // namespace olb
524
525#endif
Representation of a block geometry.
Decomposition of a physical volume into a set of disjoint cuboids.
const Cuboid< T, D > & get(int iC) const
Read access to a single cuboid.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
Base class for all LoadBalancer.
Definition vtiWriter.h:42
Generic communicator for overlaps between blocks of SUPER.
Representation of a statistic for a parallel 2D geometry.
int get(LatticeR< D+1 > latticeR) const
Read only access to the material numbers, error handling: returns 0 if data is not available.
std::size_t getSerializableSize() const override
Binary size for the serializer.
int clean(bool verbose=true, std::vector< int > bulkMaterials={1})
Executes an outer cleaning: Sets all material numbers which are not bulk-materials to 0 if there is n...
bool & getStatisticsStatus()
Read and write access to the statistic status flag, update needed = true.
SuperGeometry(CuboidDecomposition< T, D > &cuboidDecomposition, LoadBalancer< T > &loadBalancer, int overlap=3)
Vector< T, D > getPhysR(LatticeR< D+1 > latticeR) const
Transforms a lattice to physical position (SI units)
void print()
Prints some information about the super geometry.
void updateStatistics(bool verbose=true)
Updates the super geometry at the boundaries if needed and afterwards the statisics if needed.
void reset(IndicatorF< T, D > &domain)
reset all cell materials inside of a domain to 0
bool checkForErrors(bool verbose=true)
check for errors (searches for all outer voxels (=0) with an inner voxel (=1) as a direct neighbour)
int innerClean(bool verbose=true)
inner cleaning for all boundary types
SuperGeometryStatistics< T, D > & getStatistics()
Returns the statistics object.
void rename(int fromM, int toM)
replace one material with another
std::unique_ptr< SuperIndicatorF< T, D > > getMaterialIndicator(std::vector< int > &&materials)
Returns a material indicator using the given vector of materials.
std::size_t getNblock() const override
Number of data blocks for the serializable interface.
int getAndCommunicate(LatticeR< D+1 > latticeR) const
Read only access to the material numbers with global communication to all ranks.
BlockGeometry< T, D > & getBlockGeometry(int locIC)
Read and write access to a single block geometry.
BLOCK & getBlock(int locIC)
Read and write access to a single extended block geometry.
int outerClean(bool verbose=true, std::vector< int > bulkMaterials={1})
Removes not needed fluid cells from the outer domain.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
int _overlap
Size of ghost cell layer (must be greater than 1 and greater_overlapBC, default =1)
Plain old scalar vector.
constexpr const T * data() const any_platform
Definition vector.h:172
void bCast(T *sendBuf, int sendCount, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Broadcast data from one processor to multiple processors.
void reduceAndBcast(T &reductVal, MPI_Op op, int root=0, MPI_Comm comm=MPI_COMM_WORLD)
Reduction operation, followed by a broadcast.
void barrier(MPI_Comm comm=MPI_COMM_WORLD)
Synchronizes the processes.
This file contains indicator functions.
This file contains indicator functions.
MpiManager & mpi()
Top level namespace for all of OpenLB.
std::conditional_t< DIM==2, SuperGeometryStatistics2D< T >, SuperGeometryStatistics3D< T > > SuperGeometryStatistics
Definition aliases.h:68
std::conditional_t< D==2, SuperIndicatorMaterial2D< T >, SuperIndicatorMaterial3D< T > > SuperIndicatorMaterial
Definition aliases.h:287
std::conditional_t< D==2, IndicatorF2D< T >, IndicatorF3D< T > > IndicatorF
Definition aliases.h:247
std::conditional_t< DIM==2, SuperVTMwriter2D< T, OUT_T, W >, SuperVTMwriter3D< T, OUT_T, W > > SuperVTMwriter
Definition aliases.h:78
std::conditional_t< D==2, SuperGeometryF2D< T >, SuperGeometryF3D< T > > SuperGeometryF
Definition aliases.h:88
Representation of a parallel 2D geometry – header file.
A method to write vtk data for cuboid geometries (only for uniform grids) – header file.
A method to write vtk data for cuboid geometries (only for uniform grids) – header file.