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
38namespace Opm {
39namespace Linear {
40
44template <class SeqPreCond, class Overlap>
46 : public Dune::Preconditioner<typename SeqPreCond::domain_type,
47 typename SeqPreCond::range_type>
48{
49public:
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
180private:
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:48
void post(domain_type &x) override
Definition: overlappingpreconditioner.hh:143
void pre(domain_type &x, range_type &y) override
Definition: overlappingpreconditioner.hh:61
typename SeqPreCond::range_type range_type
Definition: overlappingpreconditioner.hh:51
Dune::SolverCategory::Category category() const override
the kind of computations supported by the operator. Either overlapping or non-overlapping
Definition: overlappingpreconditioner.hh:54
void apply(domain_type &x, const range_type &d) override
Definition: overlappingpreconditioner.hh:101
typename SeqPreCond::domain_type domain_type
Definition: overlappingpreconditioner.hh:50
OverlappingPreconditioner(SeqPreCond &seqPreCond, const Overlap &overlap)
Definition: overlappingpreconditioner.hh:57
Definition: blackoilboundaryratevector.hh:37