OpenLB 1.7
Loading...
Searching...
No Matches
blockReduction3D2D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2017 Adrian Kummerlaender
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
24#ifndef BLOCK_REDUCTION_3D2D_HH
25#define BLOCK_REDUCTION_3D2D_HH
26
27#include "blockReduction3D2D.h"
28
29#include <limits>
30#include "utilities/omath.h"
31
36
37namespace olb {
38
39
40template <typename T>
41void BlockReduction3D2D<T>::updateBlockAnalytical(BlockData<2,T,T>& block)
42{
43 AnalyticalFfromSuperF3D<T> analyticalF(*_f);
44
45 for ( std::tuple<int,int,int>& pos : _rankLocalSubplane ) {
46 const int& iX = std::get<0>(pos);
47 const int& iY = std::get<1>(pos);
48 const Vector<T,3> physR = this->getPhysR(iX, iY);
49
50 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
51 block.get({iX, iY}, iSize) = T();
52 }
53
54 T output[_f->getTargetDim()];
55 const T input[3] { physR[0], physR[1], physR[2] };
56
57 if (analyticalF(output, input)) {
58 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
59 block.get({iX, iY}, iSize) += output[iSize];
60 }
61 }
62 }
63}
64
65template <typename T>
66void BlockReduction3D2D<T>::updateBlockDiscrete(BlockData<2,T,T>& block)
67{
68 CuboidGeometry3D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
69
70 for ( std::tuple<int,int,int>& pos : _rankLocalSubplane ) {
71 const int& iX = std::get<0>(pos);
72 const int& iY = std::get<1>(pos);
73 const int& iC = std::get<2>(pos);
74 const Vector<T,3> physR = this->getPhysR(iX, iY);
75
76 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
77 block.get({iX, iY}, iSize) = T();
78 }
79
80 T output[_f->getTargetDim()];
81 int input[4] { iC, 0, 0, 0 };
82 geometry.get(iC).getLatticeR(&input[1], physR);
83
84 if (_f(output, input)) {
85 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
86 block.get({iX, iY}, iSize) += output[iSize];
87 }
88 }
89 }
90}
91
92template <typename T>
95 const HyperplaneLattice3D<T>& lattice,
96 BlockDataSyncMode syncMode,
97 BlockDataReductionMode reductionMode)
98 : HyperplaneLattice3D<T>(lattice),
99 BlockDataF2D<T,T>(lattice.getNx(), lattice.getNy(), f->getTargetDim()),
100 _f(std::move(f)),
101 _syncMode(syncMode),
102 _reductionMode(reductionMode)
103{
104 this->getName() = "planeReduction(" + _f->getName() + ")";
105
106 if ( _reductionMode == BlockDataReductionMode::Discrete ) {
107 const CuboidGeometry3D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
108 const Hyperplane3D<T>& hyperplane = this->getHyperplane();
109 const bool spansAxisPlane = hyperplane.isXYPlane() ||
110 hyperplane.isXZPlane() ||
111 hyperplane.isYZPlane();
112 // verify axes alignment and spacing of hyperplane parametrization
113 if ( !spansAxisPlane ||
114 lattice.getPhysSpacing() != geometry.getMinDeltaR() ) {
115 // hyperplane lattice doesn't describe a trivially discretizable plane
116 OstreamManager clerr(std::cerr, "BlockReduction3D2D");
117 clerr << "Given hyperplane is not trivially discretizable. "
118 << "Use BlockDataReductionMode::Analytical instead."
119 << std::endl;
120 exit(-1);
121 }
122 }
123
124 // intialize list of relevant rank local points making up the reduced plane
125 initialize();
126 // first update of data
127 update();
128}
129
130template <typename T>
133 const Hyperplane3D<T>& hyperplane,
134 BlockDataSyncMode syncMode,
135 BlockDataReductionMode reductionMode)
137 std::forward<decltype(f)>(f),
138 HyperplaneLattice3D<T>(f->getSuperStructure().getCuboidGeometry(),
139 hyperplane),
140 syncMode,
141 reductionMode)
142{ }
143
144template <typename T>
147 const Hyperplane3D<T>& hyperplane,
148 int resolution,
149 BlockDataSyncMode syncMode)
151 std::forward<decltype(f)>(f),
152 HyperplaneLattice3D<T>(f->getSuperStructure().getCuboidGeometry(),
153 hyperplane, resolution),
154 syncMode)
155{ }
156
157template <typename T>
160 const Vector<T,3>& origin, const Vector<T,3>& u, const Vector<T,3>& v,
161 int resolution, BlockDataSyncMode syncMode)
163 std::forward<decltype(f)>(f),
164 Hyperplane3D<T>().originAt(origin).spannedBy(u, v),
165 resolution, syncMode)
166{ }
167
168template <typename T>
171 const Vector<T,3>& origin, const Vector<T,3>& normal,
172 int resolution, BlockDataSyncMode syncMode)
174 std::forward<decltype(f)>(f),
175 Hyperplane3D<T>().originAt(origin).normalTo(normal),
176 resolution, syncMode)
177{ }
178
179template <typename T>
182 const Vector<T,3>& normal,
183 int resolution, BlockDataSyncMode syncMode)
185 std::forward<decltype(f)>(f),
186 Hyperplane3D<T>()
187 .centeredIn(f->getSuperStructure().getCuboidGeometry().getMotherCuboid())
188 .normalTo(normal),
189 resolution, syncMode)
190{ }
191
192template <typename T>
194{
195 const CuboidGeometry3D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
196 LoadBalancer<T>& load = _f->getSuperStructure().getLoadBalancer();
197
198 _rankLocalSubplane.clear();
199
200 for ( int iX = 0; iX < this->getNx(); ++iX ) {
201 for ( int iY = 0; iY < this->getNy(); ++iY ) {
202 const Vector<T,3> physR = this->getPhysR(iX, iY);
203
204 // Schedule plane point for storage if its physical position intersects the
205 // mother cuboid and the cuboid of the nearest lattice position is local to
206 // the current rank:
207 int iC;
208 if ( geometry.getC(physR, iC) ) {
209 if ( load.isLocal(iC) ) {
210 _rankLocalSubplane.emplace_back(iX, iY, iC);
211 }
212 }
213 }
214 }
215}
216
217template <typename T>
219{
220 _f->getSuperStructure().communicate();
221
222#ifdef PARALLEL_MODE_MPI
223 std::unique_ptr<BlockData<2,T,T>> localBlockData(
224 new BlockData<2,T,T>({{this->getNx(), this->getNy()}, 0}, _f->getTargetDim()));
225
226 switch ( _reductionMode ) {
228 updateBlockAnalytical(*localBlockData);
229 break;
231 updateBlockDiscrete(*localBlockData);
232 break;
233 }
234
235 switch ( _syncMode ) {
237 singleton::mpi().reduce(*localBlockData, this->getBlockData(), MPI_SUM);
238 singleton::mpi().bCast(this->getBlockData());
239 break;
241 singleton::mpi().reduce(*localBlockData, this->getBlockData(), MPI_SUM);
242 break;
244 if (this->_owning) {
245 delete this->_blockData;
246 }
247 this->_blockData = localBlockData.release();
248 this->_owning = true;
249 break;
250 }
251#else
252 switch ( _reductionMode ) {
254 updateBlockAnalytical(this->getBlockData());
255 break;
257 updateBlockDiscrete(this->getBlockData());
258 break;
259 }
260#endif
261}
262
263template <typename T>
265{
266 return *this->_blockData;
267}
268
269template <typename T>
270const std::vector<std::tuple<int,int,int>>& BlockReduction3D2D<T>::getRankLocalSubplane() const
271{
272 return this->_rankLocalSubplane;
273}
274
275
276} // end namespace olb
277
278#endif
BlockDataF2D can store data of any BlockFunctor2D.
BlockReduction3D2D reduces the data of a SuperF3D functor to the intersection between a given hyperpl...
void initialize()
Initialize rank-local list of plane points to be stored in _blockData.
void update()
Updates and writes the data to _blockData using _rankLocalSubplane.
BlockStructureD< 2 > & getBlockStructure() override
Overload of virtual function from class BlockF2D.
BlockReduction3D2D(FunctorPtr< SuperF3D< T > > &&f, const HyperplaneLattice3D< T > &lattice, BlockDataSyncMode syncMode=BlockDataSyncMode::ReduceAndBcast, BlockDataReductionMode reductionMode=BlockDataReductionMode::Analytical)
Construction using functor and hyperplane lattice.
const std::vector< std::tuple< int, int, int > > & getRankLocalSubplane() const
Base of a regular block.
A cuboid geometry represents a voxel mesh.
bool getC(T physR[3], int &iC) const
Returns true and the cuboid number of the nearest lattice position to the given physical position if ...
T getMinDeltaR() const
Returns the minimum delta in the structure.
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
Parametrization of a hyperplane lattice.
const Hyperplane3D< T > & getHyperplane() const
Base class for all LoadBalancer.
bool isLocal(const int &glob)
returns whether glob is on this process
class for marking output with some text
represents all functors that operate on a SuperStructure<T,3> in general
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 reduce(T &sendVal, T &recvVal, MPI_Op op, int root=0, MPI_Comm=MPI_COMM_WORLD)
Reduction operation toward one processor.
Wrapper functions that simplify the use of MPI.
MpiManager & mpi()
Top level namespace for all of OpenLB.
BlockDataReductionMode
Mode of reducing block data from given, possibly higher dimensional data.
@ Discrete
Read block data from discrete lattice locations.
@ Analytical
Interpolate block data at exact physical locations.
BlockDataSyncMode
Mode of synchronizing functor block data between processes.
@ ReduceOnly
optimize for usage in e.g. BlockGifWriter, full data only available on main rank
@ None
optimize for usage in e.g. SuperLatticeFlux3D, only rank-local data available
@ ReduceAndBcast
default behavior, full block data available on all ranks after update
Definition of a analytical 2D plane embedded in 3D space.
bool isXZPlane() const
bool isYZPlane() const
bool isXYPlane() const