opm-simulators
overlappingpreconditioner.hh
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef EWOMS_OVERLAPPING_PRECONDITIONER_HH
28 #define EWOMS_OVERLAPPING_PRECONDITIONER_HH
29 
31 
32 #include <opm/common/Exceptions.hpp>
33 #include <opm/simulators/linalg/ilufirstelement.hh> //definitions needed in next header
34 #include <dune/istl/preconditioner.hh>
35 
36 #include <dune/common/version.hh>
37 
38 namespace Opm {
39 namespace Linear {
40 
44 template <class SeqPreCond, class Overlap>
46  : public Dune::Preconditioner<typename SeqPreCond::domain_type,
47  typename SeqPreCond::range_type>
48 {
49 public:
50  using domain_type = typename SeqPreCond::domain_type;
51  using range_type = typename SeqPreCond::range_type;
52 
54  Dune::SolverCategory::Category category() const override
55  { return Dune::SolverCategory::overlapping; }
56 
57  OverlappingPreconditioner(SeqPreCond& seqPreCond, const Overlap& overlap)
58  : seqPreCond_(seqPreCond), overlap_(&overlap)
59  {}
60 
61  void pre(domain_type& x, range_type& y) override
62  {
63 #if HAVE_MPI
64  short success;
65  try
66  {
67  seqPreCond_.pre(x, y);
68  short localSuccess = 1;
69  MPI_Allreduce(&localSuccess, // source buffer
70  &success, // destination buffer
71  1, // number of objects in buffers
72  MPI_SHORT, // data type
73  MPI_MIN, // operation
74  MPI_COMM_WORLD); // communicator
75  }
76  catch (...)
77  {
78  short localSuccess = 0;
79  MPI_Allreduce(&localSuccess, // source buffer
80  &success, // destination buffer
81  1, // number of objects in buffers
82  MPI_SHORT, // data type
83  MPI_MIN, // operation
84  MPI_COMM_WORLD); // communicator
85  }
86 
87  if (success) {
88  x.sync();
89  }
90  else
91  throw NumericalProblem("Preconditioner threw an exception in pre() method on some process.");
92 #else
93  seqPreCond_.pre(x, y);
94 #endif
95 
96  // communicate the results on the overlap
97  x.sync();
98  y.sync();
99  }
100 
101  void apply(domain_type& x, const range_type& d) override
102  {
103 #if HAVE_MPI
104  if (overlap_->peerSet().size() > 0) {
105  // make sure that all processes react the same if the
106  // sequential preconditioner on one process throws an
107  // exception
108  short success;
109  try
110  {
111  // execute the sequential preconditioner
112  seqPreCond_.apply(x, d);
113  short localSuccess = 1;
114  MPI_Allreduce(&localSuccess, // source buffer
115  &success, // destination buffer
116  1, // number of objects in buffers
117  MPI_SHORT, // data type
118  MPI_MIN, // operation
119  MPI_COMM_WORLD); // communicator
120  }
121  catch (...)
122  {
123  short localSuccess = 0;
124  MPI_Allreduce(&localSuccess, // source buffer
125  &success, // destination buffer
126  1, // number of objects in buffers
127  MPI_SHORT, // data type
128  MPI_MIN, // operation
129  MPI_COMM_WORLD); // communicator
130  }
131 
132  if (success) {
133  x.sync();
134  }
135  else
136  throw NumericalProblem("Preconditioner threw an exception on some process.");
137  }
138  else
139 #endif // HAVE_MPI
140  seqPreCond_.apply(x, d);
141  }
142 
143  void post(domain_type& x) override
144  {
145 #if HAVE_MPI
146  short success;
147  try
148  {
149  seqPreCond_.post(x);
150  short localSuccess = 1;
151  MPI_Allreduce(&localSuccess, // source buffer
152  &success, // destination buffer
153  1, // number of objects in buffers
154  MPI_SHORT, // data type
155  MPI_MIN, // operation
156  MPI_COMM_WORLD); // communicator
157  }
158  catch (...)
159  {
160  short localSuccess = 0;
161  MPI_Allreduce(&localSuccess, // source buffer
162  &success, // destination buffer
163  1, // number of objects in buffers
164  MPI_SHORT, // data type
165  MPI_MIN, // operation
166  MPI_COMM_WORLD); // communicator
167  }
168 
169  if (success) {
170  x.sync();
171  }
172  else
173  throw NumericalProblem("Preconditioner threw an exception in post() method on "
174  "some process.");
175 #else
176  seqPreCond_.post(x);
177 #endif
178  }
179 
180 private:
181  SeqPreCond& seqPreCond_;
182  const Overlap *overlap_;
183 };
184 
185 } // namespace Linear
186 } // namespace Opm
187 
188 #endif
An overlap aware preconditioner for any ISTL linear solver.
Definition: overlappingpreconditioner.hh:45
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
Dune::SolverCategory::Category category() const override
the kind of computations supported by the operator. Either overlapping or non-overlapping ...
Definition: overlappingpreconditioner.hh:54
An overlap aware ISTL scalar product.