OpenLB 1.7
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/cuboid2D.h"
47#include "io/ostreamManager.h"
48
49namespace olb {
50
51
52template<typename T, unsigned D>
54 LoadBalancer<T>& loadBalancer,
55 int overlap):
56 SuperStructure<T,D>(cuboidGeometry, loadBalancer, overlap),
57 _communicator(new SuperCommunicator<T,SuperGeometry<T,D>>(*this)),
58 _communicationNeeded(false),
59 _statistics(this),
60 clout(std::cout, ("SuperGeometry" + std::to_string(D) + "D"))
61{
62 for (int iCloc=0; iCloc<this->getLoadBalancer().size(); iCloc++) {
63 int iCglob = this->getLoadBalancer().glob(iCloc);
64 _block.emplace_back(
65 new BlockGeometry<T,D>(cuboidGeometry.get(iCglob), overlap, iCglob));
66 }
67
68 _communicator->template requestField<descriptors::MATERIAL>();
69 _communicator->requestOverlap(this->_overlap);
70 _communicator->exchangeRequests();
71
72 _statistics.getStatisticsStatus() = true;
73 _communicationNeeded = true;
74 updateStatistics(false);
75}
76
77template<typename T, unsigned D>
78int SuperGeometry<T,D>::get(int iCglob, LatticeR<D> latticeR) const
79{
80 if ( this->getLoadBalancer().rank(iCglob) == singleton::mpi().getRank() ) {
81 return _block[this->getLoadBalancer().loc(iCglob)]->get(
82 latticeR);
83 } else {
84 throw std::domain_error("read only access to data which is not available locally");
85 }
86}
87
88template<typename T, unsigned D>
89int SuperGeometry<T,D>::get(const int latticeR[D+1]) const
90{
91 if constexpr (D == 3){
92 return get(latticeR[0], {latticeR[1], latticeR[2], latticeR[3]});
93 } else {
94 return get(latticeR[0], {latticeR[1], latticeR[2]});
95 }
96}
97
98template<typename T, unsigned D>
100{
101 if constexpr (D == 3){
102 return get(latticeR[0], {latticeR[1], latticeR[2], latticeR[3]});
103 } else {
104 return get(latticeR[0], {latticeR[1], latticeR[2]});
106}
107
108template<typename T, unsigned D>
111 int material = 0;
112 if ( this->getLoadBalancer().rank(iCglob) == singleton::mpi().getRank() ) {
113 material = _block[this->getLoadBalancer().loc(iCglob)]->get(latticeR);
114 }
115#ifdef PARALLEL_MODE_MPI
116 singleton::mpi().bCast(&material, 1, this->_loadBalancer.rank(iCglob));
117#endif
118 return material;
119}
120
121template<typename T, unsigned D>
123{
124 if constexpr (D == 3){
125 return getAndCommunicate(latticeR[0], {latticeR[1], latticeR[2], latticeR[3]});
126 }else{
127 return getAndCommunicate(latticeR[0], {latticeR[1], latticeR[2]});
129}
131template<typename T, unsigned D>
132std::vector<T> SuperGeometry<T,D>::getPhysR(int iCglob, LatticeR<D> latticeR) const
133{
134 T physRv[D];
135 getPhysR(physRv, iCglob, latticeR);
136 std::vector<T> physR(physRv,physRv + D);
137 return physR;
138}
139
140template<typename T, unsigned D>
141std::vector<T> SuperGeometry<T,D>::getPhysR(LatticeR<D+1> latticeR) const
142{
143 T physRv[D];
144 this->_cuboidGeometry.getPhysR(physRv, latticeR);
145 std::vector<T> physR(physRv,physRv + D);
146 return physR;
148
149template<typename T, unsigned D>
150void SuperGeometry<T,D>::getPhysR(T output[D], const int latticeR[D+1]) const
151{
152 this->_cuboidGeometry.getPhysR(output, latticeR);
153}
154
155template<typename T, unsigned D>
156void SuperGeometry<T,D>::getPhysR(T output[D], const int iCglob, LatticeR<D> latticeR) const
158 this->_cuboidGeometry.getPhysR(output, iCglob, latticeR);
160
161template<typename T, unsigned D>
164 _statistics.getStatisticsStatus() = true;
165 return *_block[locIC];
166}
167
168template<typename T, unsigned D>
170{
171 return *_block[locIC];
172}
173
174template<typename T, unsigned D>
175template <typename BLOCK>
177{
178 _statistics.getStatisticsStatus() = true;
179 return *_block[locIC];
180}
181
182template<typename T, unsigned D>
183template <typename BLOCK>
184const BLOCK& SuperGeometry<T,D>::getBlock(int locIC) const
185{
186 return *_block[locIC];
187}
188
189template<typename T, unsigned D>
191{
192 if (this->_communicationNeeded) {
193 this->communicate();
194 getStatisticsStatus()=true;
195 }
196 return _statistics;
198
199template<typename T, unsigned D>
202 return _statistics;
203}
204
205template<typename T, unsigned D>
207{
208 return _statistics.getStatisticsStatus();
209}
210
211template<typename T, unsigned D>
213{
214 return _statistics.getStatisticsStatus();
215}
216
217template<typename T, unsigned D>
219{
220 if (this->_communicationNeeded) {
221 this->communicate();
222 getStatisticsStatus()=true;
223 }
224 _statistics.update(verbose);
225 for (unsigned iC=0; iC<_block.size(); iC++) {
226 _block[iC]->getStatistics().update(verbose);
227 }
228}
229
230template<typename T, unsigned D>
231template<typename DESCRIPTOR>
232int SuperGeometry<T,D>::clean(bool verbose, std::vector<int> bulkMaterials)
233{
234 this->communicate();
235 int counter=0;
236 for (unsigned iC=0; iC<_block.size(); iC++) {
237 counter+=_block[iC]->template clean <DESCRIPTOR>(false, bulkMaterials);
238 }
239#ifdef PARALLEL_MODE_MPI
240 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
241#endif
242
243 if (verbose) {
244 clout << "cleaned "<< counter << " outer boundary voxel(s)" << std::endl;
245 }
246 _statistics.getStatisticsStatus() = true;
247 this->_communicationNeeded = true;
248 return counter;
249}
250
251template<typename T, unsigned D>
252int SuperGeometry<T,D>::outerClean(bool verbose, std::vector<int> bulkMaterials)
253{
254 this->communicate();
255 int counter=0;
256 for (unsigned iC=0; iC<_block.size(); iC++) {
257 counter+=_block[iC]->outerClean(false, bulkMaterials);
258 }
259#ifdef PARALLEL_MODE_MPI
260 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
261#endif
262
263 if (verbose) {
264 clout << "cleaned "<< counter << " outer fluid voxel(s)" << std::endl;
265 }
266 _statistics.getStatisticsStatus() = true;
267 this->_communicationNeeded = true;
268 return counter;
269}
270
271template<typename T, unsigned D>
273{
274 this->communicate();
275 int counter=0;
276 for (unsigned iC=0; iC<_block.size(); iC++) {
277 counter+=_block[iC]->innerClean(false);
278 }
279#ifdef PARALLEL_MODE_MPI
281 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
282#endif
283
284 if (verbose) {
285 clout << "cleaned "<< counter << " inner boundary voxel(s)" << std::endl;
286 }
287 _statistics.getStatisticsStatus() = true;
288 this->_communicationNeeded = true;
289 return counter;
290}
291
292template<typename T, unsigned D>
293int SuperGeometry<T,D>::innerClean(int bcType, bool verbose)
294{
295 this->communicate();
296 int counter=0;
297 for (unsigned iC=0; iC<_block.size(); iC++) {
298 counter+=_block[iC]->innerClean(bcType,false);
299 }
300#ifdef PARALLEL_MODE_MPI
301 singleton::mpi().reduceAndBcast(counter, MPI_SUM);
302#endif
303
304 if (verbose) {
305 clout << "cleaned "<< counter << " inner boundary voxel(s) of Type " << bcType << std::endl;
306 }
307 _statistics.getStatisticsStatus() = true;
308 this->_communicationNeeded = true;
309 return counter;
310}
311
312template<typename T, unsigned D>
314{
315 updateStatistics(verbose);
316 bool error = false;
317 for (unsigned iC=0; iC<_block.size(); iC++) {
318 if (_block[iC]->checkForErrors(false)) {
319 error = true;
320 }
321 }
322 if (verbose) {
323 if (error) {
324 this->clout << "error!" << std::endl;
325 }
326 else {
327 this->clout << "the model is correct!" << std::endl;
328 }
329 }
330 return error;
331}
332
333template<typename T, unsigned D>
335{
336 this->communicate();
337 for (unsigned iC = 0; iC < _block.size(); ++iC) {
338 _block[iC]->reset(domain);
339 }
340 _statistics.getStatisticsStatus() = true;
341 this->_communicationNeeded = true;
342}
343
344template<typename T, unsigned D>
345void SuperGeometry<T,D>::rename(int fromM, int toM)
346{
347 this->communicate();
348 for (unsigned iC=0; iC<_block.size(); iC++) {
349 _block[iC]->rename(fromM,toM);
350 }
351 _statistics.getStatisticsStatus() = true;
352 this->_communicationNeeded = true;
353}
354
355template<typename T, unsigned D>
356void SuperGeometry<T,D>::rename(int fromM, int toM, FunctorPtr<IndicatorF<T,D>>&& condition)
357{
358 this->communicate();
359 for (unsigned iC=0; iC<_block.size(); iC++) {
360 _block[iC]->rename(fromM,toM,*condition);
361 }
362 _statistics.getStatisticsStatus() = true;
363}
364
365template<typename T, unsigned D>
366void SuperGeometry<T,D>::rename(int fromM, int toM, LatticeR<D> offset)
367{
368 LatticeR<D> overlap (this->_overlap);
369 if ( offset <= overlap ){
370 _communicator->communicate();
371 for (unsigned iC=0; iC<_block.size(); iC++) {
372 _block[iC]->rename(fromM,toM,offset);
373 }
374 _statistics.getStatisticsStatus() = true;
375 this->_communicationNeeded = true;
376 }else{
377 clout << "error rename only implemented for offset<=overlap" << std::endl;
378 }
379}
380
381template<typename T, unsigned D>
382void SuperGeometry<T,D>::rename(int fromM, int toM, int testM, std::vector<int> testDirection)
383{
384 if ( testDirection[0]*testDirection[0]<=(this->_overlap)*(this->_overlap)
385 && testDirection[1]*testDirection[1]<=(this->_overlap)*(this->_overlap) ){
386 if constexpr (D==3){
387 if(testDirection[2]*testDirection[2]<=(this->_overlap)*(this->_overlap)){
388 _communicator->communicate();
389 for (unsigned iC=0; iC<_block.size(); iC++) {
390 _block[iC]->rename(fromM,toM,testM,testDirection);
391 }
392 _statistics.getStatisticsStatus() = true;
393 this->_communicationNeeded = true;
394 }
395 }else{
396 _communicator->communicate();
397 for (unsigned iC=0; iC<_block.size(); iC++) {
398 _block[iC]->rename(fromM,toM,testM,testDirection);
399 }
400 _statistics.getStatisticsStatus() = true;
401 this->_communicationNeeded = true;
402 }
403 }else{
404 clout << "error rename only implemented for |testDirection[i]|<=overlap" << std::endl;
405 }
406}
407
408template<typename T, unsigned D>
409void SuperGeometry<T,D>::rename(int fromBcMat, int toBcMat, int fluidMat,
410 IndicatorF<T,D>& condition)
411{
412 if (this->_overlap>1) {
413 this->communicate();
414 rename(fromBcMat, toBcMat, condition);
415 Vector<int,D> testDirection = this->getStatistics().computeDiscreteNormal(toBcMat);
416 this->communicate();
417 for (unsigned iC=0; iC < _block.size(); iC++) {
418 _block[iC]->rename(fromBcMat,toBcMat,fluidMat,condition,testDirection);
419 }
420 _statistics.getStatisticsStatus() = true;
421 this->_communicationNeeded = true;
422 }
423 else {
424 clout << "error rename only implemented for overlap>=2" << std::endl;
425 }
426}
427
428template<typename T, unsigned D>
429void SuperGeometry<T,D>::rename(int fromBcMat, int toBcMat, int fluidMat,
430 FunctorPtr<IndicatorF<T,D>>&& condition)
431{
432 if (this->_overlap>1) {
433 _communicator->communicate();
434 rename(fromBcMat, toBcMat, *condition);
435 Vector<int,D> testDirection = this->getStatistics().computeDiscreteNormal(toBcMat);
436 _communicator->communicate();
437 for (unsigned iC=0; iC<_block.size(); iC++) {
438 _block[iC]->rename(fromBcMat,toBcMat,fluidMat,*condition,testDirection);
439 }
440 _statistics.getStatisticsStatus() = true;
441 this->_communicationNeeded = true;
442 }
443 else {
444 clout << "error rename only implemented for overlap>=2" << std::endl;
445 }
446}
447
448
449template<typename T, unsigned D>
451{
452 this->_cuboidGeometry.print();
453 getStatistics().print();
454}
455
456template<typename T, unsigned D>
457std::unique_ptr<SuperIndicatorF<T,D>> SuperGeometry<T,D>::getMaterialIndicator(
458 std::vector<int>&& materials)
459{
460 static_assert(std::is_base_of<SuperIndicatorF<T,D>, SuperIndicatorMaterial<T,D>>::value,
461 "Indicator to be constructed is SuperIndicatorF implementation");
462
463 return std::unique_ptr<SuperIndicatorF<T,D>>(
464 new SuperIndicatorMaterial<T,D>(*this, std::forward<std::vector<int>>(materials))
465 );
466}
467
468template<typename T, unsigned D>
469std::unique_ptr<SuperIndicatorF<T,D>> SuperGeometry<T,D>::getMaterialIndicator(int material)
470{
471 return this->getMaterialIndicator(std::vector<int> { material });
472}
473
474template<typename T, unsigned D>
476{
477 return std::accumulate(_block.begin(), _block.end(), size_t(0), [](std::size_t sum, auto& b) -> std::size_t {
478 return sum + b->getNblock();
479 });
480}
481
482
483template<typename T, unsigned D>
485{
486 return std::accumulate(_block.begin(), _block.end(), size_t(0), [](std::size_t sum, auto& b) -> std::size_t {
487 return sum + b->getSerializableSize();
488 });
489}
490
491template<typename T, unsigned D>
492bool* SuperGeometry<T,D>::getBlock(std::size_t iBlock, std::size_t& sizeBlock, bool loadingMode)
493{
494 std::size_t currentBlock = 0;
495 bool* dataPtr = nullptr;
496
497 for (std::size_t iC=0; iC < _block.size(); ++iC) {
498 registerSerializableOfConstSize(iBlock, sizeBlock, currentBlock, dataPtr, getBlock(iC), loadingMode);
499 }
500
501 return dataPtr;
502}
503
504} // namespace olb
505
506#endif
Representation of a block geometry.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
Base class for all LoadBalancer.
Generic communicator for overlaps between blocks of SUPER.
Representation of a statistic for a parallel 2D geometry.
SuperGeometry(CuboidGeometry< T, D > &cuboidGeometry, LoadBalancer< T > &loadBalancer, int overlap=3)
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.
int get(const int latticeR[D+1]) const
int getAndCommunicate(int iCglob, LatticeR< D > latticeR) const
Read only access to the material numbers with global communication to all ranks.
int get(int iCglob, LatticeR< D > latticeR) const
Read only access to the material numbers, error handling: returns 0 if data is not available.
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.
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.
std::vector< T > getPhysR(int iCglob, LatticeR< D > latticeR) const
Transforms a lattice to physical position (SI unites)
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.
Definition vector.h:47
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.
The description of a single 2D cuboid – header file.
The description of a vector of 2D cuboid – header file.
The description of a vector of 3D cuboid – header file.
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:88
std::conditional_t< D==2, CuboidGeometry2D< T >, CuboidGeometry3D< T > > CuboidGeometry
Definition aliases.h:47
std::conditional_t< D==2, SuperIndicatorMaterial2D< T >, SuperIndicatorMaterial3D< T > > SuperIndicatorMaterial
Definition aliases.h:298
std::conditional_t< D==2, IndicatorF2D< T >, IndicatorF3D< T > > IndicatorF
Definition aliases.h:258
Representation of a parallel 2D geometry – header file.