OpenLB 1.7
Loading...
Searching...
No Matches
reductionF3D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2012-2017 Lukas Baron, Tim Dornieden, Mathias J. Krause,
4 * Albert Mink, Fabian Klemens, Benjamin Förster, Marie-Luise Maier,
5 * Adrian Kummerlaender
6 * E-mail contact: info@openlb.net
7 * The most recent release of OpenLB can be downloaded at
8 * <http://www.openlb.net/>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301, USA.
24 */
25
26#ifndef REDUCTION_F_3D_HH
27#define REDUCTION_F_3D_HH
28
29#ifndef M_PI
30#define M_PI 3.14159265358979323846
31#endif
32
33#include <algorithm>
35#include "dynamics/lbm.h" // for computation of lattice rho and velocity
36
37namespace olb {
38
39template<typename T, typename DESCRIPTOR>
43 : SuperLatticeF3D<T, DESCRIPTOR>(sLattice, f->getTargetDim()),
44 _f(std::move(f))
45{
46 this->getName() = "fromAnalyticalF(" + _f->getName() + ")";
47
48 LoadBalancer<T>& load = sLattice.getLoadBalancer();
49 CuboidGeometry3D<T>& cuboid = sLattice.getCuboidGeometry();
50
51 for (int iC = 0; iC < load.size(); ++iC) {
52 this->_blockF.emplace_back(
54 *_f,
55 sLattice.getBlock(iC),
56 cuboid.get(load.glob(iC)))
57 );
58 }
59}
60
61template<typename T, typename DESCRIPTOR>
63 T output[], const int input[])
64{
65 T physR[3] = {};
66 this->_sLattice.getCuboidGeometry().getPhysR(physR,input);
67 return _f(output,physR);
68}
69
70
71template<typename T, typename DESCRIPTOR>
75 Cuboid3D<T>& cuboid)
76 : BlockLatticeF3D<T, DESCRIPTOR>(lattice, f.getTargetDim()),
77 _f(f),
78 _cuboid(cuboid)
79{
80 this->getName() = "blockFfromAnalyticalF(" + _f.getName() + ")";
81}
82
83template<typename T, typename DESCRIPTOR>
85 T output[], const int input[])
86{
87 T physR[3] = {};
88 _cuboid.getPhysR(physR,input);
89 return _f(output,physR);
90}
91
92
95template<typename T, typename DESCRIPTOR>
97 IndicatorF3D<T>& f, T h, T eps, T sigma)
98 : BlockDataF3D<T, T>((int)((f.getMax()[0] - f.getMin()[0]) / h + ( util::round(eps*0.5)*2+2 )),
99 (int)((f.getMax()[1] - f.getMin()[1]) / h + ( util::round(eps*0.5)*2+2 )),
100 (int)((f.getMax()[2] - f.getMin()[2]) / h + ( util::round(eps*0.5)*2+2 ))),
101 _h(h),
102 _sigma(sigma),
103 _eps(util::round(eps*0.5)*2),
104 _wa(_eps+1),
105 _f(f)
106{
107 this->getName() = "SmoothBlockIndicator3D";
108 T value, dx, dy, dz;
109 T weights[this->_wa][this->_wa][this->_wa];
110 T sum = 0;
111 const int iStart = util::floor(this->_wa*0.5);
112 const int iEnd = util::ceil(this->_wa*0.5);
113
114 // calculate weights: they are constants, but calculation here is less error-prone than hardcoding these parameters
115 for (int x = -iStart; x < iEnd; ++x) {
116 for (int y = -iStart; y < iEnd; ++y) {
117 for (int z = -iStart; z < iEnd; ++z) {
118 weights[x+iStart][y+iStart][z+iStart] = util::exp(-(x*x+y*y+z*z)/(2*this->_sigma*this->_sigma)) / (util::pow(this->_sigma,3)*util::sqrt(util::pow(2,3)*util::pow(M_PI,3)));
119 // important because sum of all weigths only equals 1 for this->_wa -> infinity
120 sum += weights[x+iStart][y+iStart][z+iStart];
121 }
122 }
123 }
124 const T invSum = 1./sum;
125
126 for (int iX=0; iX<this->getBlockData().getNx(); ++iX) {
127 for (int iY=0; iY<this->getBlockData().getNy(); ++iY) {
128 for (int iZ=0; iZ<this->getBlockData().getNz(); ++iZ) {
129 bool output[1];
130 value = 0;
131
132 // input: regarded point (center)
133 T input[] = {
134 _f.getMin()[0] + iX*_h,
135 _f.getMin()[1] + iY*_h,
136 _f.getMin()[2] + iZ*_h
137 };
138
139 /*
140 * three loops to look at every point (which weight is not 0) around the regarded point
141 * sum all weighted porosities
142 */
143 for (int x = -iStart; x < iEnd; ++x) {
144 for (int y = -iStart; y < iEnd; ++y) {
145 for (int z = -iStart; z < iEnd; ++z) {
146 dx = x*_h;
147 dy = y*_h;
148 dz = z*_h;
149
150 // move from regarded point to point in neighborhood
151 input[0] += dx;
152 input[1] += dy;
153 input[2] += dz;
154
155 // get porosity
156 _f(output,input);
157
158 // sum porosity
159 value += output[0] * weights[x+iStart][y+iStart][z+iStart];
160
161 // move back to center
162 input[0] -= dx;
163 input[1] -= dy;
164 input[2] -= dz;
165 }
166 }
167 }
168 /*
169 * Round to 3 decimals
170 * See above sum != 1.0, that's the reason for devision, otherwise porosity will never reach 0
171 */
172 this->getBlockData().get({iX,iY,iZ},0) = value*invSum;//nearbyint(1000*value/sum)/1000.0;
173 }
174 }
175 }
176}
177/*
178template<typename T, typename DESCRIPTOR>
179bool SmoothBlockIndicator3D<T, DESCRIPTOR>::operator()(
180 T output[], const int input[])
181{
182 T physR[3] = {};
183 _superGeometry.getPhysR(physR,{input[0],input[1],input[2]} );
184 _f(output,physR);
185 return true;
186}*/
187
188
189template<typename T, typename DESCRIPTOR>
193 : SuperLatticeF3D<T, DESCRIPTOR>(sLattice, 3)
194{
195 this->getName() = "Interp3DegreeVelocity";
196 int maxC = this->_sLattice.getLoadBalancer().size();
197 this->_blockF.reserve(maxC);
198 for (int iC = 0; iC < maxC; iC++) {
201 sLattice.getBlock(iC),
202 conv,
203 &sLattice.getCuboidGeometry().get(this->_sLattice.getLoadBalancer().
204 glob(iC)),
205 range);
206 _bLattices.push_back(foo);
207 }
208}
209
210template<typename T, typename DESCRIPTOR>
212 T output[], const T input[], const int iC)
213{
214 _bLattices[this->_sLattice.getLoadBalancer().loc(iC)]->operator()(output,
215 input);
216}
217
218template<typename T, typename DESCRIPTOR>
222 Cuboid3D<T>* c, int range)
223 : BlockLatticeF3D<T, DESCRIPTOR>(blockLattice, 3),
224 _conv(conv),
225 _cuboid(c),
226 _range(range)
227{
228 this->getName() = "BlockLatticeInterpVelocity3Degree3D";
229}
230
231template<typename T, typename DESCRIPTOR>
235 BlockLatticeF3D<T, DESCRIPTOR>(rhs._blockLattice, 3),
236 _conv(rhs._conv),
237 _cuboid(rhs._cuboid),
238 _range(rhs._range)
239{
240}
241
242template<typename T, typename DESCRIPTOR>
244 T output[3], const T input[3])
245{
246 T u[3], rho, volume;
247 int latIntPos[3] = {0};
248 T latPhysPos[3] = {T()};
249 _cuboid->getFloorLatticeR(latIntPos, &input[0]);
250 _cuboid->getPhysR(latPhysPos, latIntPos);
251
252 volume=T(1);
253 for (int i = -_range; i <= _range+1; ++i) {
254 for (int j = -_range; j <= _range+1; ++j) {
255 for (int k = -_range; k <= _range+1; ++k) {
256
257 this->_blockLattice.get(latIntPos[0]+i, latIntPos[1]+j,
258 latIntPos[2]+k).computeRhoU(rho, u);
259 for (int l = -_range; l <= _range+1; ++l) {
260 if (l != i) {
261 volume *= (input[0] - (latPhysPos[0]+ l *_cuboid->getDeltaR()))
262 / (latPhysPos[0] + i *_cuboid->getDeltaR()
263 - (latPhysPos[0] + l *_cuboid->getDeltaR()));
264 }
265 }
266 for (int m = -_range; m <= _range+1; ++m) {
267 if (m != j) {
268 volume *= (input[1]
269 - (latPhysPos[1] + m *_cuboid->getDeltaR()))
270 / (latPhysPos[1] + j * _cuboid->getDeltaR()
271 - (latPhysPos[1] + m * _cuboid->getDeltaR()));
272 }
273 }
274 for (int n = -_range; n <= _range+1; ++n) {
275 if (n != k) {
276 volume *= (input[2]
277 - (latPhysPos[2] + n * _cuboid->getDeltaR()))
278 / (latPhysPos[2] + k * _cuboid->getDeltaR()
279 - (latPhysPos[2] + n * _cuboid->getDeltaR()));
280 }
281 }
282 output[0] += u[0] * volume;
283 output[1] += u[1] * volume;
284 output[2] += u[2] * volume;
285 volume=T(1);
286 }
287 }
288 }
289
290 output[0] = _conv.getPhysVelocity(output[0]);
291 output[1] = _conv.getPhysVelocity(output[1]);
292 output[2] = _conv.getPhysVelocity(output[2]);
293}
294
295
296template<typename T, typename DESCRIPTOR>
299 UnitConverter<T,DESCRIPTOR>& conv, int range) :
300 SuperLatticeF3D<T, DESCRIPTOR>(sLattice, 3)
301{
302 this->getName() = "Interp3DegreeDensity";
303 int maxC = this->_sLattice.getLoadBalancer().size();
304 this->_blockF.reserve(maxC);
305 for (int lociC = 0; lociC < maxC; lociC++) {
306 int globiC = this->_sLattice.getLoadBalancer().glob(lociC);
307
310 sLattice.getBlock(lociC),
311 sGeometry.getBlockGeometry(lociC),
312 conv,
313 &sLattice.getCuboidGeometry().get(globiC),
314 range);
315 _bLattices.push_back(foo);
316
317 if (sLattice.getOverlap() <= range + 1)
318 std::cout << "lattice overlap has to be larger than (range + 1)"
319 << std::endl;
320 }
321}
322
323template<typename T, typename DESCRIPTOR>
325{
326 // first deconstruct vector elements
327 for ( auto it : _bLattices) {
328 delete it;
329 }
330 // then delete std::vector
331 _bLattices.clear();
332}
333
334template<typename T, typename DESCRIPTOR>
336 const T input[], const int globiC)
337{
338 if (this->_sLattice.getLoadBalancer().rank(globiC) == singleton::mpi().getRank()) {
339 _bLattices[this->_sLattice.getLoadBalancer().loc(globiC)]->operator()(output,
340 input);
341 }
342}
343
344template<typename T, typename DESCRIPTOR>
346 BlockLattice<T, DESCRIPTOR>& blockLattice,
348 Cuboid3D<T>* c, int range) :
349 BlockLatticeF3D<T, DESCRIPTOR>(blockLattice, 3), _blockGeometry(blockGeometry),
350 _conv(conv), _cuboid(c), _range(range)
351{
352 this->getName() = "BlockLatticeInterpDensity3Degree3D";
353}
354
355template<typename T, typename DESCRIPTOR>
358 BlockLatticeF3D<T, DESCRIPTOR>(rhs._blockLattice, 3),
359 _blockGeometry(rhs._blockGeometry),_conv(rhs._conv), _cuboid(
360 rhs._cuboid), _range(rhs._range)
361{
362}
363
364template<typename T, typename DESCRIPTOR>
366 T output[DESCRIPTOR::q], const T input[3])
367{
368 T volume = T(1);
369 T f_iPop = 0.;
373 int latIntPos[3] = { 0 };
374 // neighbor position on grid of input value in physical units
375 T latPhysPos[3] = { T() };
376 // input is physical position on grid
377 _cuboid->getFloorLatticeR(latIntPos, input);
378 // latPhysPos is global physical position on geometry
379 _cuboid->getPhysR(latPhysPos, latIntPos);
380
381 for (unsigned iPop = 0; iPop < DESCRIPTOR::q; ++iPop) {
382 output[iPop] = T(0);
383 for (int i = -_range; i <= _range + 1; ++i) {
384 for (int j = -_range; j <= _range + 1; ++j) {
385 for (int k = -_range; k <= _range + 1; ++k) {
386 f_iPop = 0.;
387 // just if material of cell != 1 there may be information of fluid density
388 if (_blockGeometry.getMaterial({latIntPos[0] + i, latIntPos[1] + j,
389 latIntPos[2] + k}) != 0) {
390 // because of communication it is possible to get density information
391 // from neighboring cuboid
392 f_iPop = this->_blockLattice.get(latIntPos[0] + i, latIntPos[1] + j,
393 latIntPos[2] + k)[iPop];
394 }
395 for (int l = -_range; l <= _range + 1; ++l) {
396 if (l != i) {
397 volume *= (input[0] - (latPhysPos[0] + l * _cuboid->getDeltaR()))
398 / (latPhysPos[0] + i * _cuboid->getDeltaR()
399 - (latPhysPos[0] + l * _cuboid->getDeltaR()));
400 }
401 }
402 for (int m = -_range; m <= _range + 1; ++m) {
403 if (m != j) {
404 volume *= (input[1] - (latPhysPos[1] + m * _cuboid->getDeltaR()))
405 / (latPhysPos[1] + j * _cuboid->getDeltaR()
406 - (latPhysPos[1] + m * _cuboid->getDeltaR()));
407 }
408 }
409 for (int n = -_range; n <= _range + 1; ++n) {
410 if (n != k) {
411 volume *= (input[2] - (latPhysPos[2] + n * _cuboid->getDeltaR()))
412 / (latPhysPos[2] + k * _cuboid->getDeltaR()
413 - (latPhysPos[2] + n * _cuboid->getDeltaR()));
414 }
415 }
416 output[iPop] += f_iPop * volume;
417 volume = T(1);
418 }
419 }
420 }
421 }
422}
423
424template<typename T, typename DESCRIPTOR>
428 SuperLatticeF3D<T, DESCRIPTOR>(sLattice, 3)
429{
430 this->getName() = "SuperLatticeSmoothDiracDelta3D";
431 int maxC = this->_sLattice.getLoadBalancer().size();
432 this->_blockF.reserve(maxC);
433 for (int lociC = 0; lociC < maxC; lociC++) {
434 int globiC = this->_sLattice.getLoadBalancer().glob(lociC);
435
438 sLattice.getBlock(lociC),
439 conv, &sLattice.getCuboidGeometry().get(globiC)
440 );
441 _bLattices.push_back(foo);
442 }
443}
444
445template<typename T, typename DESCRIPTOR>
447{
448 for ( auto it : _bLattices) {
449 delete it;
450 }
451 _bLattices.clear();
452}
453
454template<typename T, typename DESCRIPTOR>
456 const T physPos[3], const int globiC)
457{
458 if (this->_sLattice.getLoadBalancer().rank(globiC) == singleton::mpi().getRank()) {
459 _bLattices[this->_sLattice.getLoadBalancer().loc(globiC)]->operator()(delta,
460 physPos);
461 }
462}
463
464template<typename T, typename DESCRIPTOR>
467 : BlockLatticeF3D<T, DESCRIPTOR>(blockLattice, 3), _conv(conv), _cuboid(cuboid)
468{
469 this->getName() = "BlockLatticeSmoothDiracDelta3D";
470}
471
472template<typename T, typename DESCRIPTOR>
475 :
476 BlockLatticeF3D<T, DESCRIPTOR>(rhs._blockLattice, 3), _conv(rhs._conv), _cuboid(rhs._cuboid)
477{
478}
479
480template<typename T, typename DESCRIPTOR>
482 T delta[4][4][4], const T physPos[])
483{
484 int range = 1;
485 T a, b, c = T();
486 int latticeRoundedPosP[3] = { 0 };
487 T physRoundedPosP[3] = { T() };
488 T physLatticeL = _conv.getConversionFactorLength();
489
490 T counter = 0.;
491
492 _cuboid->getLatticeR(latticeRoundedPosP, physPos);
493 _cuboid->getPhysR(physRoundedPosP, latticeRoundedPosP);
494
495 for (int i = -range; i <= range + 1; ++i) {
496 for (int j = -range; j <= range + 1; ++j) {
497 for (int k = -range; k <= range + 1; ++k) {
498 delta[i+range][j+range][k+range] = T(1);
499 // a, b, c in lattice units cause physical ones get cancelled
500 a = (physRoundedPosP[0] + i * physLatticeL - physPos[0])
501 / physLatticeL;
502 b = (physRoundedPosP[1] + j * physLatticeL - physPos[1])
503 / physLatticeL;
504 c = (physRoundedPosP[2] + k * physLatticeL - physPos[2])
505 / physLatticeL;
506
507 // the for loops already define that a, b, c are smaller than 2
508 delta[i+range][j+range][k+range] *= 1. / 4 * (1 + util::cos(M_PI * a / 2.));
509 delta[i+range][j+range][k+range] *= 1. / 4 * (1 + util::cos(M_PI * b / 2.));
510 delta[i+range][j+range][k+range] *= 1. / 4 * (1 + util::cos(M_PI * c / 2.));
511
512 counter += delta[i+range][j+range][k+range];
513 }
514 }
515 }
516
517 // if (!util::nearZero(counter - T(1))){
518 // // sum of delta has to be one
519 // std::cout << "[" << this->getName() << "] " <<
520 // "Delta summed up does not equal 1 but = " <<
521 // counter << std::endl;
522 // }
523
524}
525
526
527} // end namespace olb
528
529#endif
#define M_PI
AnalyticalF are applications from DD to XD, where X is set by the constructor.
BlockDataF3D can store data of any BlockFunctor3D.
BlockData< 3, T, T > & getBlockData()
returns _blockData
U & get(std::size_t iCell, int iD=0)
Definition blockData.hh:94
Representation of a block geometry.
represents all functors that operate on a DESCRIPTOR in general, e.g. getVelocity(),...
Block level functor for conversion of analytical to lattice functors.
bool operator()(T output[], const int input[]) override
has to be implemented for 'every' derived class
BlockLatticeFfromAnalyticalF3D(AnalyticalF3D< T, T > &f, BlockLattice< T, DESCRIPTOR > &lattice, Cuboid3D< T > &cuboid)
BlockLatticeInterpDensity3Degree3D(BlockLattice< T, DESCRIPTOR > &blockLattice, BlockGeometry< T, 3 > &blockGeometry, UnitConverter< T, DESCRIPTOR > &conv, Cuboid3D< T > *c, int range)
bool operator()(T output[], const int input[]) override
has to be implemented for 'every' derived class
bool operator()(T output[], const int input[]) override
has to be implemented for 'every' derived class
BlockLatticeInterpPhysVelocity3Degree3D(BlockLattice< T, DESCRIPTOR > &blockLattice, UnitConverter< T, DESCRIPTOR > &conv, Cuboid3D< T > *c, int range)
BlockLatticeSmoothDiracDelta3D(BlockLattice< T, DESCRIPTOR > &blockLattice, UnitConverter< T, DESCRIPTOR > &conv, Cuboid3D< T > *c)
bool operator()(T output[], const int input[]) override
has to be implemented for 'every' derived class
Platform-abstracted block lattice for external access and inter-block interaction.
int getNy() const
Read only access to block height.
int getNx() const
Read only access to block width.
int getNz() const
Read only access to block height.
A regular single 3D cuboid is the basic component of a 3D cuboid structure which defines the grid.
Definition cuboid3D.h:58
A cuboid geometry represents a voxel mesh.
Cuboid3D< T > & get(int iC)
Read and write access to a single cuboid.
Smart pointer for managing the various ways of passing functors around.
Definition functorPtr.h:60
std::string & getName()
read and write access to name
Definition genericF.hh:51
IndicatorF3D is an application from .
virtual Vector< S, 3 > & getMin()
Base class for all LoadBalancer.
int glob(int loc) const
const int _wa
size of the matrix of weight coefficients (from 3D Gaussian Function) _wa x _wa x _wa
SmoothBlockIndicator3D(IndicatorF3D< T > &f, T h, T eps, T sigma)
const T _h
Lattice spacing of the particle grid.
IndicatorF3D< T > & _f
_f holds the geometry
const T _sigma
Important parameter for the Gaussian point spread Function (standard deviations)
std::vector< std::unique_ptr< BlockF3D< T > > > _blockF
Super functors may consist of several BlockF3D<W> derived functors.
Representation of a statistic for a parallel 2D geometry.
BlockGeometry< T, D > & getBlockGeometry(int locIC)
Read and write access to a single block geometry.
represents all functors that operate on a SuperLattice in general, e.g. getVelocity(),...
SuperLattice< T, DESCRIPTOR > & _sLattice
bool operator()(T output[], const int input[]) override
FunctorPtr< AnalyticalF3D< T, T > > _f
SuperLatticeFfromAnalyticalF3D(FunctorPtr< AnalyticalF3D< T, T > > &&f, SuperLattice< T, DESCRIPTOR > &sLattice)
SuperLatticeInterpDensity3Degree3D(SuperLattice< T, DESCRIPTOR > &sLattice, SuperGeometry< T, 3 > &sGeometry, UnitConverter< T, DESCRIPTOR > &conv, int range=1)
bool operator()(T output[], const int input[]) override
bool operator()(T output[], const int input[]) override
SuperLatticeInterpPhysVelocity3Degree3D(SuperLattice< T, DESCRIPTOR > &sLattice, UnitConverter< T, DESCRIPTOR > &conv, int range=1)
SuperLatticeSmoothDiracDelta3D(SuperLattice< T, DESCRIPTOR > &sLattice, UnitConverter< T, DESCRIPTOR > &conv, SuperGeometry< T, 3 > &superGeometry)
bool operator()(T output[], const int input[]) override
Super class maintaining block lattices for a cuboid decomposition.
BlockLattice< T, DESCRIPTOR > & getBlock(int locC)
Return BlockLattice with local index locC.
CuboidGeometry< T, D > & getCuboidGeometry()
Read and write access to cuboid geometry.
int getOverlap()
Read and write access to the overlap.
LoadBalancer< T > & getLoadBalancer()
Read and write access to the load balancer.
Conversion between physical and lattice units, as well as discretization.
int getRank() const
Returns the process ID.
platform_constant int c[Q][D]
constexpr T m(unsigned iPop, unsigned jPop, tag::MRT)
MpiManager & mpi()
cpu::simd::Pack< T > sqrt(cpu::simd::Pack< T > value)
Definition pack.h:100
ADf< T, DIM > ceil(const ADf< T, DIM > &a)
Definition aDiff.h:900
ADf< T, DIM > floor(const ADf< T, DIM > &a)
Definition aDiff.h:869
cpu::simd::Pack< T > pow(cpu::simd::Pack< T > base, cpu::simd::Pack< T > exp)
Definition pack.h:112
ADf< T, DIM > exp(const ADf< T, DIM > &a)
Definition aDiff.h:455
ADf< T, DIM > cos(const ADf< T, DIM > &a)
Definition aDiff.h:578
Top level namespace for all of OpenLB.