19 #ifndef OPM_SYSTEMPRECONDITIONER_HEADER_INCLUDED 20 #define OPM_SYSTEMPRECONDITIONER_HEADER_INCLUDED 22 #include <opm/simulators/linalg/system/MultiComm.hpp> 23 #include <opm/simulators/linalg/system/SystemTypes.hpp> 24 #include <opm/simulators/linalg/FlexibleSolver.hpp> 25 #include <opm/simulators/linalg/PreconditionerWithUpdate.hpp> 26 #include <opm/simulators/linalg/PropertyTree.hpp> 28 #include <dune/istl/operators.hh> 29 #include <dune/istl/paamg/pinfo.hh> 36 template<
typename Scalar>
37 using SeqResOperator = Dune::MatrixAdapter<RRMatrix<Scalar>, ResVector<Scalar>, ResVector<Scalar>>;
40 using ParResComm = Dune::OwnerOverlapCopyCommunication<int, int>;
41 template<
typename Scalar>
42 using ParResOperator = Dune::OverlappingSchwarzOperator<RRMatrix<Scalar>, ResVector<Scalar>, ResVector<Scalar>, ParResComm>;
55 template <
class Scalar,
class ResOp,
class ResComm = Dune::Amg::SequentialInformation>
59 static constexpr
bool isParallel = !std::is_same_v<ResComm, Dune::Amg::SequentialInformation>;
62 using WellOperator = Dune::MatrixAdapter<WWMatrix<Scalar>, WellVector<Scalar>, WellVector<Scalar>>;
65 static constexpr
auto _0 = Dune::Indices::_0;
66 static constexpr
auto _1 = Dune::Indices::_1;
70 const std::function<ResVector<Scalar>()>& weightsCalculator,
73 requires (!isParallel)
75 , pressureIndex_(pressureIndex)
77 initSubSolvers(prm, weightsCalculator);
83 const std::function<ResVector<Scalar>()>& weightsCalculator,
86 const ResComm& resComm)
90 , pressureIndex_(pressureIndex)
92 initSubSolvers(prm, weightsCalculator);
96 void pre(SystemVector<Scalar>&, SystemVector<Scalar>&)
override 100 void post(SystemVector<Scalar>&)
override 104 Dune::SolverCategory::Category category()
const override 106 if constexpr (isParallel)
107 return Dune::SolverCategory::overlapping;
109 return Dune::SolverCategory::sequential;
112 void update()
override 114 resSolver_->preconditioner().update();
115 resSmoother_->preconditioner().update();
116 wellSolver_->preconditioner().update();
119 void updateForChangedWellStructure()
121 resSolver_->preconditioner().update();
122 resSmoother_->preconditioner().update();
124 resizeWellWorkVectors();
127 bool hasPerfectUpdate()
const override 141 void apply(SystemVector<Scalar>& v,
const SystemVector<Scalar>& d)
override 144 const auto& A = S_[_0][_0];
145 const auto& C = S_[_0][_1];
146 const auto& B = S_[_1][_0];
147 const auto& D = S_[_1][_1];
156 Dune::InverseOperatorResult res_result;
158 tmp_resRes_ = resRes_;
159 syncResVector(tmp_resRes_);
160 resSolver_->apply(dresSol_, tmp_resRes_, res_result);
163 A.mmv(dresSol_, resRes_);
165 B.mmv(dresSol_, wRes_);
170 Dune::InverseOperatorResult well_result;
173 wellSolver_->apply(dwSol_, tmp_wRes_, well_result);
176 C.mmv(dwSol_, resRes_);
178 D.mmv(dwSol_, wRes_);
180 Dune::InverseOperatorResult res_result;
182 tmp_resRes_ = resRes_;
183 syncResVector(tmp_resRes_);
184 resSmoother_->apply(dresSol_, tmp_resRes_, res_result);
187 B.mmv(dresSol_, wRes_);
192 Dune::InverseOperatorResult well_result;
195 wellSolver_->apply(dwSol_, tmp_wRes_, well_result);
199 syncResVector(resSol_);
206 const ResComm* resComm_ =
nullptr;
207 int pressureIndex_ = 0;
208 static constexpr
int dummyWellPressureIndex = std::numeric_limits<int>::min();
211 std::unique_ptr<ResOp> rop_;
212 std::unique_ptr<WellOperator> wop_;
213 std::unique_ptr<ResFlexibleSolverType> resSolver_;
214 std::unique_ptr<ResFlexibleSolverType> resSmoother_;
215 std::unique_ptr<WellFlexibleSolverType> wellSolver_;
217 WellVector<Scalar> wSol_;
218 ResVector<Scalar> resSol_;
219 ResVector<Scalar> dresSol_;
220 WellVector<Scalar> dwSol_;
221 ResVector<Scalar> tmp_resRes_;
222 WellVector<Scalar> tmp_wRes_;
223 ResVector<Scalar> resRes_;
224 WellVector<Scalar> wRes_;
226 void syncResVector(ResVector<Scalar>& v)
228 if constexpr (isParallel) {
229 resComm_->copyOwnerToAll(v, v);
233 void initWellSolver()
235 wop_ = std::make_unique<WellOperator>(S_[_1][_1]);
236 std::function<WellVector<Scalar>()> weightsCalculatorWell;
237 wellSolver_ = std::make_unique<WellFlexibleSolverType>(
238 *wop_, wellprm_, weightsCalculatorWell, dummyWellPressureIndex);
242 const std::function<ResVector<Scalar>()>& weightsCalculator)
244 auto resprm = prm.
get_child(
"reservoir_solver");
245 auto resprmsmoother = prm.
get_child(
"reservoir_smoother");
248 if constexpr (isParallel) {
249 rop_ = std::make_unique<ResOp>(S_[_0][_0], *resComm_);
250 resSolver_ = std::make_unique<ResFlexibleSolverType>(
251 *rop_, *resComm_, resprm, weightsCalculator, pressureIndex_);
252 resSmoother_ = std::make_unique<ResFlexibleSolverType>(
253 *rop_, *resComm_, resprmsmoother, weightsCalculator, pressureIndex_);
255 rop_ = std::make_unique<ResOp>(S_[_0][_0]);
256 resSolver_ = std::make_unique<ResFlexibleSolverType>(
257 *rop_, resprm, weightsCalculator, pressureIndex_);
258 resSmoother_ = std::make_unique<ResFlexibleSolverType>(
259 *rop_, resprmsmoother, weightsCalculator, pressureIndex_);
265 void initWorkVectors()
267 resizeReservoirWorkVectors();
268 resizeWellWorkVectors();
271 void resizeReservoirWorkVectors()
273 const auto numRes = S_[_0][_0].N();
274 resSol_.resize(numRes);
275 dresSol_.resize(numRes);
276 tmp_resRes_.resize(numRes);
277 resRes_.resize(numRes);
280 void resizeWellWorkVectors()
282 const auto numWell = S_[_1][_1].N();
283 wSol_.resize(numWell);
284 dwSol_.resize(numWell);
285 tmp_wRes_.resize(numWell);
286 wRes_.resize(numWell);
292 #endif // OPM_SYSTEMPRECONDITIONER_HEADER_INCLUDED PropertyTree get_child(const std::string &key) const
Retrieve copy of sub tree rooted at node.
Definition: PropertyTree.cpp:82
Definition: SystemTypes.hpp:76
A solver class that encapsulates all needed objects for a linear solver (operator, scalar product, iterative solver and preconditioner) and sets them up based on runtime parameters, using the PreconditionerFactory for setting up preconditioners.
Definition: FlexibleSolver.hpp:43
Definition: SystemPreconditioner.hpp:56
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:33
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:38