WellOperators.hpp
Go to the documentation of this file.
1/*
2 Copyright 2016 IRIS AS
3 Copyright 2019, 2020 Equinor ASA
4 Copyright 2020 SINTEF
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
22#ifndef OPM_WELLOPERATORS_HEADER_INCLUDED
23#define OPM_WELLOPERATORS_HEADER_INCLUDED
24
25#include <dune/common/parallel/communication.hh>
26#include <dune/istl/operators.hh>
27#include <dune/istl/bcrsmatrix.hh>
28
29#include <opm/common/TimingMacros.hpp>
30
31#include <opm/simulators/linalg/matrixblock.hh>
32
33#include <cstddef>
34
35namespace Opm
36{
37
38
39//=====================================================================
40// Implementation for ISTL-matrix based operators
41// Note: the classes WellModelMatrixAdapter and
42// WellModelGhostLastMatrixAdapter were moved from ISTLSolver.hpp
43// and subsequently modified.
44//=====================================================================
45
55template <class X, class Y>
56class LinearOperatorExtra : public Dune::LinearOperator<X, Y>
57{
58public:
59 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<double, 1, 1>>;
60 virtual void addWellPressureEquations(PressureMatrix& jacobian, const X& weights,const bool use_well_weights) const = 0;
61 virtual void addWellPressureEquationsStruct(PressureMatrix& jacobian) const = 0;
62 virtual int getNumberOfExtraEquations() const = 0;
63};
64
65template <class WellModel, class X, class Y>
67{
68public:
70 using field_type = typename Base::field_type;
72 explicit WellModelAsLinearOperator(const WellModel& wm)
73 : wellMod_(wm)
74 {
75 }
80 void apply(const X& x, Y& y) const override
81 {
82 OPM_TIMEBLOCK(apply);
83 wellMod_.apply(x, y);
84 }
85
87 virtual void applyscaleadd(field_type alpha, const X& x, Y& y) const override
88 {
89 OPM_TIMEBLOCK(applyscaleadd);
90 wellMod_.applyScaleAdd(alpha, x, y);
91 }
92
98 Dune::SolverCategory::Category category() const override
99 {
100 return Dune::SolverCategory::sequential;
101 }
102 void addWellPressureEquations(PressureMatrix& jacobian, const X& weights,const bool use_well_weights) const override
103 {
104 OPM_TIMEBLOCK(addWellPressureEquations);
105 wellMod_.addWellPressureEquations(jacobian, weights, use_well_weights);
106 }
107 void addWellPressureEquationsStruct(PressureMatrix& jacobian) const override
108 {
109 OPM_TIMEBLOCK(addWellPressureEquationsStruct);
110 wellMod_.addWellPressureEquationsStruct(jacobian);
111 }
112 int getNumberOfExtraEquations() const override
113 {
114 return wellMod_.numLocalWellsEnd();
115 }
116
117private:
118 const WellModel& wellMod_;
119};
120
132template<class M, class X, class Y, bool overlapping >
133class WellModelMatrixAdapter : public Dune::AssembledLinearOperator<M,X,Y>
134{
135public:
136 typedef M matrix_type;
137 typedef X domain_type;
138 typedef Y range_type;
139 typedef typename X::field_type field_type;
140 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<double, 1, 1>>;
141#if HAVE_MPI
142 typedef Dune::OwnerOverlapCopyCommunication<int,int> communication_type;
143#else
144 typedef Dune::CollectiveCommunication< int > communication_type;
145#endif
146
147 Dune::SolverCategory::Category category() const override
148 {
149 return overlapping ?
150 Dune::SolverCategory::overlapping : Dune::SolverCategory::sequential;
151 }
152
155 const Opm::LinearOperatorExtra<X, Y>& wellOper,
156 const std::shared_ptr< communication_type >& comm = std::shared_ptr< communication_type >())
157 : A_( A ), wellOper_( wellOper ), comm_(comm)
158 {}
159
160
161 virtual void apply( const X& x, Y& y ) const override
162 {
163 OPM_TIMEBLOCK(apply);
164 A_.mv( x, y );
165
166 // add well model modification to y
167 wellOper_.apply(x, y );
168
169#if HAVE_MPI
170 if( comm_ )
171 comm_->project( y );
172#endif
173 }
174
175 // y += \alpha * A * x
176 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const override
177 {
178 OPM_TIMEBLOCK(applyscaleadd);
179 A_.usmv(alpha,x,y);
180
181 // add scaled well model modification to y
182 wellOper_.applyscaleadd( alpha, x, y );
183
184#if HAVE_MPI
185 if( comm_ )
186 comm_->project( y );
187#endif
188 }
189
190 virtual const matrix_type& getmat() const override { return A_; }
191
192 void addWellPressureEquations(PressureMatrix& jacobian, const X& weights,const bool use_well_weights) const
193 {
194 OPM_TIMEBLOCK(addWellPressureEquations);
195 wellOper_.addWellPressureEquations(jacobian, weights, use_well_weights);
196 }
198 {
199 OPM_TIMEBLOCK(addWellPressureEquations);
200 wellOper_.addWellPressureEquationsStruct(jacobian);
201 }
203 {
204 return wellOper_.getNumberOfExtraEquations();
205 }
206
207protected:
210 std::shared_ptr< communication_type > comm_;
211};
212
213
222template<class M, class X, class Y, bool overlapping >
223class WellModelGhostLastMatrixAdapter : public Dune::AssembledLinearOperator<M,X,Y>
224{
225public:
226 typedef M matrix_type;
227 typedef X domain_type;
228 typedef Y range_type;
229 typedef typename X::field_type field_type;
230 using PressureMatrix = Dune::BCRSMatrix<Opm::MatrixBlock<double, 1, 1>>;
231#if HAVE_MPI
232 typedef Dune::OwnerOverlapCopyCommunication<int,int> communication_type;
233#else
234 typedef Dune::CollectiveCommunication< int > communication_type;
235#endif
236
237
238 Dune::SolverCategory::Category category() const override
239 {
240 return overlapping ?
241 Dune::SolverCategory::overlapping : Dune::SolverCategory::sequential;
242 }
243
246 const Opm::LinearOperatorExtra<X, Y>& wellOper,
247 const std::size_t interiorSize )
248 : A_( A ), wellOper_( wellOper ), interiorSize_(interiorSize)
249 {}
250
251 virtual void apply( const X& x, Y& y ) const override
252 {
253 OPM_TIMEBLOCK(apply);
254 for (auto row = A_.begin(); row.index() < interiorSize_; ++row)
255 {
256 y[row.index()]=0;
257 auto endc = (*row).end();
258 for (auto col = (*row).begin(); col != endc; ++col)
259 (*col).umv(x[col.index()], y[row.index()]);
260 }
261
262 // add well model modification to y
263 wellOper_.apply(x, y );
264
265 ghostLastProject( y );
266 }
267
268 // y += \alpha * A * x
269 virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const override
270 {
271 OPM_TIMEBLOCK(applyscaleadd);
272 for (auto row = A_.begin(); row.index() < interiorSize_; ++row)
273 {
274 auto endc = (*row).end();
275 for (auto col = (*row).begin(); col != endc; ++col)
276 (*col).usmv(alpha, x[col.index()], y[row.index()]);
277 }
278 // add scaled well model modification to y
279 wellOper_.applyscaleadd( alpha, x, y );
280
281 ghostLastProject( y );
282 }
283
284 virtual const matrix_type& getmat() const override { return A_; }
285
286 void addWellPressureEquations(PressureMatrix& jacobian, const X& weights,const bool use_well_weights) const
287 {
288 OPM_TIMEBLOCK(addWellPressureEquations);
289 wellOper_.addWellPressureEquations(jacobian, weights, use_well_weights);
290 }
292 {
293 OPM_TIMEBLOCK(addWellPressureEquationsStruct);
294 wellOper_.addWellPressureEquationsStruct(jacobian);
295 }
297 {
298 return wellOper_.getNumberOfExtraEquations();
299 }
300
301protected:
302 void ghostLastProject(Y& y) const
303 {
304 std::size_t end = y.size();
305 for (std::size_t i = interiorSize_; i < end; ++i)
306 y[i] = 0;
307 }
308
311 std::size_t interiorSize_;
312};
313
314} // namespace Opm
315
316#endif // OPM_WELLOPERATORS_HEADER_INCLUDED
317
Definition: WellOperators.hpp:57
virtual void addWellPressureEquationsStruct(PressureMatrix &jacobian) const =0
virtual void addWellPressureEquations(PressureMatrix &jacobian, const X &weights, const bool use_well_weights) const =0
Dune::BCRSMatrix< Opm::MatrixBlock< double, 1, 1 > > PressureMatrix
Definition: WellOperators.hpp:59
virtual int getNumberOfExtraEquations() const =0
Definition: WellOperators.hpp:67
void apply(const X &x, Y &y) const override
apply operator to x: The input vector is consistent and the output must also be consistent on the in...
Definition: WellOperators.hpp:80
WellModelAsLinearOperator(const WellModel &wm)
Definition: WellOperators.hpp:72
typename Base::field_type field_type
Definition: WellOperators.hpp:70
void addWellPressureEquations(PressureMatrix &jacobian, const X &weights, const bool use_well_weights) const override
Definition: WellOperators.hpp:102
virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const override
apply operator to x, scale and add:
Definition: WellOperators.hpp:87
Dune::SolverCategory::Category category() const override
Definition: WellOperators.hpp:98
int getNumberOfExtraEquations() const override
Definition: WellOperators.hpp:112
void addWellPressureEquationsStruct(PressureMatrix &jacobian) const override
Definition: WellOperators.hpp:107
Adapter to combine a matrix and another linear operator into a combined linear operator.
Definition: WellOperators.hpp:224
virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const override
Definition: WellOperators.hpp:269
virtual void apply(const X &x, Y &y) const override
Definition: WellOperators.hpp:251
void addWellPressureEquationsStruct(PressureMatrix &jacobian) const
Definition: WellOperators.hpp:291
Dune::BCRSMatrix< Opm::MatrixBlock< double, 1, 1 > > PressureMatrix
Definition: WellOperators.hpp:230
X domain_type
Definition: WellOperators.hpp:227
Y range_type
Definition: WellOperators.hpp:228
void addWellPressureEquations(PressureMatrix &jacobian, const X &weights, const bool use_well_weights) const
Definition: WellOperators.hpp:286
const Opm::LinearOperatorExtra< X, Y > & wellOper_
Definition: WellOperators.hpp:310
const matrix_type & A_
Definition: WellOperators.hpp:309
Dune::SolverCategory::Category category() const override
Definition: WellOperators.hpp:238
virtual const matrix_type & getmat() const override
Definition: WellOperators.hpp:284
Dune::OwnerOverlapCopyCommunication< int, int > communication_type
Definition: WellOperators.hpp:232
int getNumberOfExtraEquations() const
Definition: WellOperators.hpp:296
std::size_t interiorSize_
Definition: WellOperators.hpp:311
M matrix_type
Definition: WellOperators.hpp:226
X::field_type field_type
Definition: WellOperators.hpp:229
void ghostLastProject(Y &y) const
Definition: WellOperators.hpp:302
WellModelGhostLastMatrixAdapter(const M &A, const Opm::LinearOperatorExtra< X, Y > &wellOper, const std::size_t interiorSize)
constructor: just store a reference to a matrix
Definition: WellOperators.hpp:245
Adapter to combine a matrix and another linear operator into a combined linear operator.
Definition: WellOperators.hpp:134
X domain_type
Definition: WellOperators.hpp:137
const matrix_type & A_
Definition: WellOperators.hpp:208
Y range_type
Definition: WellOperators.hpp:138
virtual const matrix_type & getmat() const override
Definition: WellOperators.hpp:190
int getNumberOfExtraEquations() const
Definition: WellOperators.hpp:202
M matrix_type
Definition: WellOperators.hpp:136
const Opm::LinearOperatorExtra< X, Y > & wellOper_
Definition: WellOperators.hpp:209
void addWellPressureEquationsStruct(PressureMatrix &jacobian) const
Definition: WellOperators.hpp:197
virtual void applyscaleadd(field_type alpha, const X &x, Y &y) const override
Definition: WellOperators.hpp:176
virtual void apply(const X &x, Y &y) const override
Definition: WellOperators.hpp:161
std::shared_ptr< communication_type > comm_
Definition: WellOperators.hpp:210
X::field_type field_type
Definition: WellOperators.hpp:139
WellModelMatrixAdapter(const M &A, const Opm::LinearOperatorExtra< X, Y > &wellOper, const std::shared_ptr< communication_type > &comm=std::shared_ptr< communication_type >())
constructor: just store a reference to a matrix
Definition: WellOperators.hpp:154
Dune::SolverCategory::Category category() const override
Definition: WellOperators.hpp:147
Dune::BCRSMatrix< Opm::MatrixBlock< double, 1, 1 > > PressureMatrix
Definition: WellOperators.hpp:140
void addWellPressureEquations(PressureMatrix &jacobian, const X &weights, const bool use_well_weights) const
Definition: WellOperators.hpp:192
Dune::OwnerOverlapCopyCommunication< int, int > communication_type
Definition: WellOperators.hpp:142
Definition: BlackoilPhases.hpp:27