opm-simulators
Toggle main menu visibility
Loading...
Searching...
No Matches
PreconditionerWithUpdate.hpp
1
/*
2
Copyright 2019 SINTEF Digital, Mathematics and Cybernetics.
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 3 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
20
#ifndef OPM_PRECONDITIONERWITHUPDATE_HEADER_INCLUDED
21
#define OPM_PRECONDITIONERWITHUPDATE_HEADER_INCLUDED
22
23
#include <dune/istl/preconditioner.hh>
24
#include <memory>
25
26
namespace
Dune
27
{
28
30
template
<
class
X,
class
Y>
31
class
PreconditionerWithUpdate
:
public
Preconditioner<X, Y>
32
{
33
public
:
34
virtual
void
update() = 0;
35
36
// Force derived classes to define if preconditioner has perfect update
37
virtual
bool
hasPerfectUpdate()
const
= 0;
38
};
39
40
template
<
class
OriginalPreconditioner>
41
class
DummyUpdatePreconditioner :
public
PreconditionerWithUpdate
<typename OriginalPreconditioner::domain_type,
42
typename OriginalPreconditioner::range_type>
43
{
44
public
:
45
template
<
class
... Args>
46
explicit
DummyUpdatePreconditioner(Args&&... args)
47
: orig_precond_(std::forward<Args>(args)...)
48
{
49
}
50
51
using
X =
typename
OriginalPreconditioner::domain_type;
52
using
Y =
typename
OriginalPreconditioner::range_type;
53
54
virtual
void
pre(X& x, Y& b)
override
55
{
56
orig_precond_.pre(x, b);
57
}
58
59
virtual
void
apply(X& v,
const
Y& d)
override
60
{
61
orig_precond_.apply(v, d);
62
}
63
64
virtual
void
post(X& x)
override
65
{
66
orig_precond_.post(x);
67
}
68
69
virtual
SolverCategory::Category category()
const override
70
{
71
return
orig_precond_.category();
72
}
73
74
// The update() function does nothing for a wrapped preconditioner.
75
virtual
void
update()
override
76
{
77
}
78
79
virtual
bool
hasPerfectUpdate()
const override
{
80
return
true
;
81
}
82
83
private
:
84
OriginalPreconditioner orig_precond_;
85
};
86
87
template
<
class
OriginalPreconditioner,
class
... Args>
88
std::shared_ptr<DummyUpdatePreconditioner<OriginalPreconditioner>>
89
getDummyUpdateWrapper(Args&&... args)
90
{
91
return
std::make_shared<DummyUpdatePreconditioner<OriginalPreconditioner>>(std::forward<Args>(args)...);
92
}
93
96
template
<
class
OriginalPreconditioner>
97
struct
GeneralPreconditionerMaker
{
98
virtual
std::unique_ptr<
99
Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>>
100
make() = 0;
101
virtual
~GeneralPreconditionerMaker
() =
default
;
102
};
103
108
template
<
class
OriginalPreconditioner,
class
... Args>
109
struct
PreconditionerMaker :
public
GeneralPreconditionerMaker
<OriginalPreconditioner> {
110
using
GenericPreconditioner = Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>;
111
112
explicit
PreconditionerMaker(Args&&... args)
113
: args_(args...)
114
{
115
}
116
117
std::unique_ptr<GenericPreconditioner>
118
make()
override
119
{
120
// return std::unique_ptr<GenericPreconditioner> {new auto(std::make_from_tuple<OriginalPreconditioner>(args_))};
121
return
std::apply(
122
[](
auto
&&... args) {
123
return
std::make_unique<OriginalPreconditioner>(std::forward<Args>(args)...);
124
}, args_);
125
}
126
127
std::tuple<Args...> args_;
128
};
129
132
template
<
class
OriginalPreconditioner>
133
class
RebuildOnUpdatePreconditioner :
public
PreconditionerWithUpdate
<typename OriginalPreconditioner::domain_type,
134
typename OriginalPreconditioner::range_type>
135
{
136
public
:
137
template
<
class
... Args>
138
explicit
RebuildOnUpdatePreconditioner(Args... args)
139
: preconditioner_maker_(std::make_unique<
PreconditionerMaker<OriginalPreconditioner, Args...>
>(std::forward<Args>(args)...))
140
{
141
update();
142
}
143
144
using
X =
typename
OriginalPreconditioner::domain_type;
145
using
Y =
typename
OriginalPreconditioner::range_type;
146
147
void
pre(X& x, Y& b)
override
148
{
149
orig_precond_->pre(x, b);
150
}
151
152
void
apply(X& v,
const
Y& d)
override
153
{
154
orig_precond_->apply(v, d);
155
}
156
157
void
post(X& x)
override
158
{
159
orig_precond_->post(x);
160
}
161
162
SolverCategory::Category category()
const override
163
{
164
return
orig_precond_->category();
165
}
166
167
// Rebuild the preconditioner on update
168
void
update()
override
169
{
170
orig_precond_ = preconditioner_maker_->make();
171
}
172
173
bool
hasPerfectUpdate()
const override
174
{
175
return
true
;
176
}
177
178
private
:
179
using
AbstractMakerType =
GeneralPreconditionerMaker<OriginalPreconditioner>
;
180
using
GenericPreconditioner = Preconditioner<typename OriginalPreconditioner::domain_type, typename OriginalPreconditioner::range_type>;
181
182
std::unique_ptr<AbstractMakerType> preconditioner_maker_;
183
std::unique_ptr<GenericPreconditioner> orig_precond_;
184
};
185
191
template
<
class
OriginalPreconditioner,
class
... Args>
192
auto
193
getRebuildOnUpdateWrapper(Args... args)
194
{
195
return
std::make_shared<RebuildOnUpdatePreconditioner<OriginalPreconditioner>>(
196
std::forward<Args>(args)...);
197
}
198
199
}
// namespace Dune
200
201
#endif
// OPM_PRECONDITIONERWITHUPDATE_HEADER_INCLUDED
Dune::PreconditionerWithUpdate
Interface class adding the update() method to the preconditioner interface.
Definition
PreconditionerWithUpdate.hpp:32
Dune::GeneralPreconditionerMaker
Interface class ensuring make function is overriden.
Definition
PreconditionerWithUpdate.hpp:97
Dune::PreconditionerMaker
Struct implementing a make function which creates a preconditioner Can create arbitrary preconditione...
Definition
PreconditionerWithUpdate.hpp:109
opm
simulators
linalg
PreconditionerWithUpdate.hpp
Generated by
1.17.0