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/common/ErrorMacros.hpp>
34 
35 #include <dune/istl/preconditioners.hh>
36 
37 namespace Ewoms {
38 namespace Linear {
39 
43 template <class SeqPreCond, class Overlap>
45  : public Dune::Preconditioner<typename SeqPreCond::domain_type,
46  typename SeqPreCond::range_type>
47 {
48 public:
49  typedef typename SeqPreCond::domain_type domain_type;
50  typedef typename SeqPreCond::range_type range_type;
51 
52  enum { category = Dune::SolverCategory::overlapping };
53 
54  OverlappingPreconditioner(SeqPreCond& seqPreCond, const Overlap& overlap)
55  : seqPreCond_(seqPreCond), overlap_(&overlap)
56  {}
57 
58  void pre(domain_type& x, range_type& y)
59  {
60 #if HAVE_MPI
61  short success;
62  try
63  {
64  seqPreCond_.pre(x, y);
65  short localSuccess = 1;
66  MPI_Allreduce(&localSuccess, // source buffer
67  &success, // destination buffer
68  1, // number of objects in buffers
69  MPI_SHORT, // data type
70  MPI_MIN, // operation
71  MPI_COMM_WORLD); // communicator
72  }
73  catch (...)
74  {
75  short localSuccess = 0;
76  MPI_Allreduce(&localSuccess, // source buffer
77  &success, // destination buffer
78  1, // number of objects in buffers
79  MPI_SHORT, // data type
80  MPI_MIN, // operation
81  MPI_COMM_WORLD); // communicator
82  }
83 
84  if (success) {
85  x.sync();
86  }
87  else
88  OPM_THROW(Opm::NumericalProblem,
89  "Preconditioner threw an exception in pre() method on some process.");
90 #else
91  seqPreCond_.pre(x, y);
92 #endif
93 
94  // communicate the results on the overlap
95  x.sync();
96  y.sync();
97  }
98 
99  void apply(domain_type& x, const range_type& d)
100  {
101 #if HAVE_MPI
102  if (overlap_->peerSet().size() > 0) {
103  // make sure that all processes react the same if the
104  // sequential preconditioner on one process throws an
105  // exception
106  short success;
107  try
108  {
109  // execute the sequential preconditioner
110  seqPreCond_.apply(x, d);
111  short localSuccess = 1;
112  MPI_Allreduce(&localSuccess, // source buffer
113  &success, // destination buffer
114  1, // number of objects in buffers
115  MPI_SHORT, // data type
116  MPI_MIN, // operation
117  MPI_COMM_WORLD); // communicator
118  }
119  catch (...)
120  {
121  short localSuccess = 0;
122  MPI_Allreduce(&localSuccess, // source buffer
123  &success, // destination buffer
124  1, // number of objects in buffers
125  MPI_SHORT, // data type
126  MPI_MIN, // operation
127  MPI_COMM_WORLD); // communicator
128  }
129 
130  if (success) {
131  x.sync();
132  }
133  else
134  OPM_THROW(Opm::NumericalProblem,
135  "Preconditioner threw an exception on some process.");
136  }
137  else
138 #endif // HAVE_MPI
139  seqPreCond_.apply(x, d);
140  }
141 
142  void post(domain_type& x)
143  {
144 #if HAVE_MPI
145  short success;
146  try
147  {
148  seqPreCond_.post(x);
149  short localSuccess = 1;
150  MPI_Allreduce(&localSuccess, // source buffer
151  &success, // destination buffer
152  1, // number of objects in buffers
153  MPI_SHORT, // data type
154  MPI_MIN, // operation
155  MPI_COMM_WORLD); // communicator
156  }
157  catch (...)
158  {
159  short localSuccess = 0;
160  MPI_Allreduce(&localSuccess, // source buffer
161  &success, // destination buffer
162  1, // number of objects in buffers
163  MPI_SHORT, // data type
164  MPI_MIN, // operation
165  MPI_COMM_WORLD); // communicator
166  }
167 
168  if (success) {
169  x.sync();
170  }
171  else
172  OPM_THROW(Opm::NumericalProblem, "Preconditioner threw an "
173  "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 Ewoms
187 
188 #endif
Definition: baseauxiliarymodule.hh:37
An overlap aware preconditioner for any ISTL linear solver.
Definition: overlappingpreconditioner.hh:44
An overlap aware ISTL scalar product.