opm-simulators
ParallelIstlInformation.hpp
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
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 
36 #include <opm/simulators/utils/ParallelCommunication.hpp>
37 
38 namespace Opm
39 {
40 
43 class ParallelISTLInformation
44 {
45 public:
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 
137 private:
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 
407 namespace Opm
408 {
415 template<class T1>
416 auto
417 accumulateMaskedValues(const T1& container, const std::vector<double>* maskContainer)
418  -> decltype(container[0]*(*maskContainer)[0]);
419 
420 } // end namespace Opm
421 
422 #endif
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
auto accumulateMaskedValues(const T1 &container, const std::vector< double > *maskContainer) -> decltype(container[0] *(*maskContainer)[0])
Accumulates entries masked with 1.