OpenLB 1.7
Loading...
Searching...
No Matches
blockReduction2D1D.hh
Go to the documentation of this file.
1/* This file is part of the OpenLB library
2 *
3 * Copyright (C) 2018 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_2D1D_HH
25#define BLOCK_REDUCTION_2D1D_HH
26
27#include "blockReduction2D1D.h"
28
29#include <limits>
30#include "utilities/omath.h"
31
37
38
39namespace olb {
40
41
42template <typename T>
43void BlockReduction2D1D<T>::updateBlockAnalytical(BlockData<2,T,T>& block)
44{
45 AnalyticalFfromSuperF2D<T> analyticalF(*_f);
46
47 for ( std::tuple<int,int>& pos : _rankLocalSubplane ) {
48 const int& i = std::get<0>(pos);
49 const Vector<T,2> physR = this->getPhysR(i);
50
51 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
52 block.get({i, 0}, iSize) = T();
53 }
54
55 T output[_f->getTargetDim()];
56 const T input[2] { physR[0], physR[1] };
57
58 if (analyticalF(output, input)) {
59 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
60 block.get({i, 0}, iSize) += output[iSize];
61 }
62 }
63 }
64}
65
66template <typename T>
67void BlockReduction2D1D<T>::updateBlockDiscrete(BlockData<2,T,T>& block)
68{
69 CuboidGeometry2D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
70
71 for ( std::tuple<int,int>& pos : _rankLocalSubplane ) {
72 const int& i = std::get<0>(pos);
73 const int& iC = std::get<1>(pos);
74 const Vector<T,2> physR = this->getPhysR(i);
75
76 for ( int iSize = 0; iSize < _f->getTargetDim(); ++iSize ) {
77 block.get({i, 0}, iSize) = T();
78 }
79
80 T output[_f->getTargetDim()];
81 int input[3] { iC, 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({i, 0}, iSize) += output[iSize];
87 }
88 }
89 }
90}
91
92template <typename T>
95 const HyperplaneLattice2D<T>& lattice,
96 BlockDataSyncMode syncMode,
97 BlockDataReductionMode reductionMode)
98 : HyperplaneLattice2D<T>(lattice),
99 BlockDataF2D<T,T>(lattice.getN(), 1, f->getTargetDim()),
100 _f(std::move(f)),
101 _syncMode(syncMode),
102 _reductionMode(reductionMode)
103{
104 this->getName() = "lineReduction(" + _f->getName() + ")";
105
106 if ( _reductionMode == BlockDataReductionMode::Discrete ) {
107 const CuboidGeometry2D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
108 const Hyperplane2D<T>& hyperplane = this->getHyperplane();
109 const bool spansAxisPlane = hyperplane.isParallelToX() ||
110 hyperplane.isParallelToY();
111 // verify axes alignment and spacing of hyperplane parametrization
112 if ( !spansAxisPlane ||
113 lattice.getPhysSpacing() != geometry.getMinDeltaR() ) {
114 // hyperplane lattice doesn't describe a trivially discretizable plane
115 OstreamManager clerr(std::cerr, "BlockReduction2D1D");
116 clerr << "Given hyperplane is not trivially discretizable. "
117 << "Use BlockDataReductionMode::Analytical instead."
118 << std::endl;
119 exit(-1);
120 }
121 }
122
123 // intialize list of relevant rank local points making up the reduced line
124 initialize();
125 // first update of data
126 update();
127}
128
129template <typename T>
132 const Hyperplane2D<T>& hyperplane,
133 BlockDataSyncMode syncMode,
134 BlockDataReductionMode reductionMode)
136 std::forward<decltype(f)>(f),
137 HyperplaneLattice2D<T>(f->getSuperStructure().getCuboidGeometry(),
138 hyperplane),
139 syncMode,
140 reductionMode)
141{ }
142
143template <typename T>
146 const Hyperplane2D<T>& hyperplane,
147 int resolution, BlockDataSyncMode mode)
149 std::forward<decltype(f)>(f),
150 HyperplaneLattice2D<T>(f->getSuperStructure().getCuboidGeometry(),
151 hyperplane, resolution),
152 mode)
153{ }
154
155template <typename T>
158 const Vector<T,2>& origin, const Vector<T,2>& direction,
159 int resolution, BlockDataSyncMode mode)
161 std::forward<decltype(f)>(f),
162 Hyperplane2D<T>().originAt(origin).parallelTo(direction),
163 resolution, mode) { }
164
165template <typename T>
167{
168 const int input[2] = { i, 0 };
169 return static_cast<BlockDataF2D<T,T>*>(this)->operator()(output, input);
170}
171
172template <typename T>
174{
175 const CuboidGeometry2D<T>& geometry = _f->getSuperStructure().getCuboidGeometry();
176 LoadBalancer<T>& load = _f->getSuperStructure().getLoadBalancer();
177
178 _rankLocalSubplane.clear();
179
180 for ( int i = 0; i < this->getN(); ++i ) {
181 const Vector<T,2> physR = this->getPhysR(i);
182
183 // Schedule line point for storage if its physical position intersects the
184 // mother cuboid and the cuboid of the nearest lattice position is local to
185 // the current rank:
186 int iC;
187 if ( geometry.getC(physR, iC) ) {
188 if ( load.isLocal(iC) ) {
189 _rankLocalSubplane.emplace_back(i, iC);
190 }
191 }
192 }
193}
194
195template <typename T>
197{
198 _f->getSuperStructure().communicate();
199
200#ifdef PARALLEL_MODE_MPI
201 std::unique_ptr<BlockData<2,T,T>> localBlockData(
202 new BlockData<2,T,T>({{this->getN(), 1}, 0}, _f->getTargetDim()));
203
204 switch ( _reductionMode ) {
206 updateBlockAnalytical(*localBlockData);
207 break;
209 updateBlockDiscrete(*localBlockData);
210 break;
211 }
212
213 switch ( _syncMode ) {
215 singleton::mpi().reduce(*localBlockData, this->getBlockData(), MPI_SUM);
216 singleton::mpi().bCast(this->getBlockData());
217 break;
219 singleton::mpi().reduce(*localBlockData, this->getBlockData(), MPI_SUM);
220 break;
222 if (this->_owning) {
223 delete this->_blockData;
224 }
225 this->_blockData = localBlockData.release();
226 this->_owning = true;
227 break;
228 }
229#else
230 switch ( _reductionMode ) {
232 updateBlockAnalytical(this->getBlockData());
233 break;
235 updateBlockDiscrete(this->getBlockData());
236 break;
237 }
238#endif
239}
240
241template <typename T>
243{
244 return *this->_blockData;
245}
246
247template <typename T>
248const std::vector<std::tuple<int,int>>& BlockReduction2D1D<T>::getRankLocalSubplane() const
249{
250 return this->_rankLocalSubplane;
251}
252
253
254} // end namespace olb
255
256#endif
BlockDataF2D can store data of any BlockFunctor2D.
BlockReduction2D1D reduces the data of a SuperF2D functor to the intersection between a given 2D hype...
BlockReduction2D1D(FunctorPtr< SuperF2D< T > > &&f, const HyperplaneLattice2D< T > &lattice, BlockDataSyncMode syncMode=BlockDataSyncMode::ReduceAndBcast, BlockDataReductionMode reductionMode=BlockDataReductionMode::Analytical)
Construction using functor and hyperplane lattice.
const std::vector< std::tuple< int, int > > & getRankLocalSubplane() const
void update()
Updates and writes the data to _blockData using _rankLocalSubplane.
void initialize()
Initialize rank-local list of plane points to be stored in _blockData.
bool operator()(T output[], int i)
Custom operator for easier access to 1-dimensional block data.
BlockStructureD< 2 > & getBlockStructure() override
Overload of virtual function from class BlockF2D.
Base of a regular block.
A cuboid structure represents the grid of a considered domain.
bool getC(std::vector< T > physR, 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 maximum/minimum delata 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 (i.e. a line lattice).
const Hyperplane2D< 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,2> 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, generic template code.
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 line embedded in 2D space.
bool isParallelToY() const
bool isParallelToX() const