ParallelIstlInformation.hpp
Go to the documentation of this file.
1/*
2 Copyright 2014, 2015 Dr. Markus Blatt - HPC-Simulation-Software & Services
3 Copyright 2014, 2015 Statoil ASA
4 Copyright 2015 NTNU
5
6 This file is part of the Open Porous Media project (OPM).
7
8 OPM is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
12
13 OPM 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 License
19 along with OPM. If not, see <http://www.gnu.org/licenses/>.
20*/
21#ifndef OPM_PARALLELISTLINFORMATION_HEADER_INCLUDED
22#define OPM_PARALLELISTLINFORMATION_HEADER_INCLUDED
23
24#include <vector>
25
26#if HAVE_MPI && HAVE_DUNE_ISTL
27
28#include <algorithm>
29#include <limits>
30#include <memory>
31#include <tuple>
32#include <type_traits>
33
34#include <dune/istl/owneroverlapcopy.hh>
35
37
38namespace Opm
39{
40
43class ParallelISTLInformation
44{
45public:
47 using ParallelIndexSet = Dune::OwnerOverlapCopyCommunication<int, int>::ParallelIndexSet;
49 using RemoteIndices = Dune::OwnerOverlapCopyCommunication<int, int>::RemoteIndices;
50
52 ParallelISTLInformation();
53
56 explicit ParallelISTLInformation(MPI_Comm communicator);
57
62 ParallelISTLInformation(const std::shared_ptr<ParallelIndexSet>& indexSet,
63 const std::shared_ptr<RemoteIndices>& remoteIndices,
64 MPI_Comm communicator);
65
69 ParallelISTLInformation(const ParallelISTLInformation& other);
70
72 std::shared_ptr<ParallelIndexSet> indexSet() const
73 {
74 return indexSet_;
75 }
76
78 std::shared_ptr<RemoteIndices> remoteIndices() const
79 {
80 return remoteIndices_;
81 }
82
84 Parallel::Communication communicator() const
85 {
86 return communicator_;
87 }
91 void copyValuesTo(ParallelIndexSet& indexSet, RemoteIndices& remoteIndices,
92 std::size_t local_component_size = 0,
93 std::size_t num_components = 1) const;
94
98 template<class T>
99 void copyOwnerToAll (const T& source, T& dest) const;
100
101 template<class T>
102 const std::vector<double>& updateOwnerMask(const T& container) const;
103
109 const std::vector<double>& getOwnerMask() const
110 {
111 return ownerMask_;
112 }
113
133 template<typename Container, typename BinaryOperator, typename T>
134 void computeReduction(const Container& container, BinaryOperator binaryOperator,
135 T& value) const;
136
137private:
138 template<typename... Containers, typename... BinaryOperators, typename... ReturnValues>
139 void computeTupleReduction(const std::tuple<Containers...>& containers,
140 std::tuple<BinaryOperators...>& operators,
141 std::tuple<ReturnValues...>& values) const;
142
143 std::shared_ptr<ParallelIndexSet> indexSet_;
144 std::shared_ptr<RemoteIndices> remoteIndices_;
145 Parallel::Communication communicator_;
146 mutable std::vector<double> ownerMask_;
147};
148
149 namespace Reduction
150 {
155 // the reduction operation.
156 template<typename BinaryOperator>
157 struct MaskIDOperator
158 {
165 template<class T, class T1>
166 T operator()(const T& t1, const T& t2, const T1& mask)
167 {
168 return b_(t1, maskValue(t2, mask));
169 }
170 template<class T, class T1>
171 T maskValue(const T& t, const T1& mask)
172 {
173 return t*mask;
174 }
175 BinaryOperator& localOperator()
176 {
177 return b_;
178 }
179 template<class T>
180 T getInitialValue()
181 {
182 return T{};
183 }
184 private:
185 BinaryOperator b_;
186 };
187
189 template<class T>
190 struct InnerProductFunctor
191 {
198 template<class T1>
199 T operator()(const T& t1, const T& t2, const T1& mask)
200 {
201 T masked = maskValue(t2, mask);
202 return t1 + masked * masked;
203 }
204 template<class T1>
205 T maskValue(const T& t, const T1& mask)
206 {
207 return t*mask;
208 }
209 std::plus<T> localOperator()
210 {
211 return std::plus<T>();
212 }
213 template<class V, std::enable_if_t<std::is_convertible_v<T, V>, int> = 0>
214 V getInitialValue()
215 {
216 return T{};
217 }
218 };
219
224 // the reduction operation.
225 template<typename BinaryOperator>
226 struct MaskToMinOperator
227 {
228 explicit MaskToMinOperator(BinaryOperator b)
229 : b_(b)
230 {}
237 template<class T, class T1>
238 T operator()(const T& t1, const T& t2, const T1& mask)
239 {
240 return b_(t1, maskValue(t2, mask));
241 }
242 template<class T, class T1>
243 T maskValue(const T& t, const T1& mask)
244 {
245 if( mask )
246 {
247 return t;
248 }
249 else
250 {
251 return getInitialValue<T>();
252 }
253 }
254 template<class T>
255 T getInitialValue()
256 {
257 return std::numeric_limits<T>::lowest();
258 }
263 BinaryOperator& localOperator()
264 {
265 return b_;
266 }
267 private:
268 BinaryOperator b_;
269 };
270
274 template<typename BinaryOperator>
275 struct MaskToMaxOperator
276 {
277 explicit MaskToMaxOperator(BinaryOperator b)
278 : b_(b)
279 {}
286 template<class T, class T1>
287 T operator()(const T& t1, const T& t2, const T1& mask)
288 {
289 return b_(t1, maskValue(t2, mask));
290 }
291 template<class T, class T1>
292 T maskValue(const T& t, const T1& mask)
293 {
294 if( mask )
295 {
296 return t;
297 }
298 else
299 {
300 return std::numeric_limits<T>::max();
301 }
302 }
303 BinaryOperator& localOperator()
304 {
305 return b_;
306 }
307 template<class T>
308 T getInitialValue()
309 {
310 return std::numeric_limits<T>::max();
311 }
312 private:
313 BinaryOperator b_;
314 };
318 template<class T>
319 MaskIDOperator<std::plus<T> >
320 makeGlobalSumFunctor()
321 {
322 return MaskIDOperator<std::plus<T> >();
323 }
327 template<class T>
328 auto makeGlobalMaxFunctor()
329 {
330 struct MaxOp
331 {
332 using result_type = T;
333 const result_type& operator()(const T& t1, const T& t2)
334 {
335 return std::max(t1, t2);
336 }
337 };
338 return MaskToMinOperator(MaxOp());
339 }
340
341 namespace detail
342 {
344 template<typename T, typename Enable = void>
345 struct MaxAbsFunctor
346 {
347 using result_type = T;
348 result_type operator()(const T& t1,
349 const T& t2)
350 {
351 return std::max(std::abs(t1), std::abs(t2));
352 }
353 };
354
355 // Specialization for unsigned integers. They need their own
356 // version since abs(x) is ambiguous (as well as somewhat
357 // meaningless).
358 template<typename T>
359 struct MaxAbsFunctor<T, typename std::enable_if<std::is_unsigned<T>::value>::type>
360 {
361 using result_type = T;
362 result_type operator()(const T& t1,
363 const T& t2)
364 {
365 return std::max(t1, t2);
366 }
367 };
368 }
369
373 template<class T>
374 MaskIDOperator<detail::MaxAbsFunctor<T> >
375 makeLInfinityNormFunctor()
376 {
377 return MaskIDOperator<detail::MaxAbsFunctor<T> >();
378 }
382 template<class T>
383 auto
384 makeGlobalMinFunctor()
385 {
386 struct MinOp
387 {
388 using result_type = T;
389 const result_type& operator()(const T& t1, const T& t2)
390 {
391 return std::min(t1, t2);
392 }
393 };
394 return MaskToMaxOperator(MinOp());
395 }
396 template<class T>
397 InnerProductFunctor<T>
398 makeInnerProductFunctor()
399 {
400 return InnerProductFunctor<T>();
401 }
402 } // end namespace Reduction
403} // end namespace Opm
404
405#endif
406
407namespace Opm
408{
415template<class T1>
416auto
417accumulateMaskedValues(const T1& container, const std::vector<double>* maskContainer)
418 -> decltype(container[0]*(*maskContainer)[0]);
419
420} // end namespace Opm
421
422#endif
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilbioeffectsmodules.hh:43
auto accumulateMaskedValues(const T1 &container, const std::vector< double > *maskContainer) -> decltype(container[0] *(*maskContainer)[0])
Accumulates entries masked with 1.