19#ifndef OPM_SYSTEMPRECONDITIONER_HEADER_INCLUDED
20#define OPM_SYSTEMPRECONDITIONER_HEADER_INCLUDED
29#include <opm/common/ErrorMacros.hpp>
31#include <dune/istl/operators.hh>
32#include <dune/istl/paamg/pinfo.hh>
41template<
typename Scalar>
45using ParResComm = Dune::OwnerOverlapCopyCommunication<int, int>;
46template<
typename Scalar>
60template <
class Scalar,
class ResOp,
class ResComm = Dune::Amg::SequentialInformation>
64 static constexpr bool isParallel = !std::is_same_v<ResComm, Dune::Amg::SequentialInformation>;
70 static constexpr auto _0 = Dune::Indices::_0;
71 static constexpr auto _1 = Dune::Indices::_1;
80 , pressureIndex_(pressureIndex)
82 initSubSolvers(prm, weightsCalculator);
91 const ResComm& resComm)
95 , pressureIndex_(pressureIndex)
97 initSubSolvers(prm, weightsCalculator);
109 Dune::SolverCategory::Category
category()
const override
112 return Dune::SolverCategory::overlapping;
114 return Dune::SolverCategory::sequential;
120 weights_ = weightsCalculator_();
121 cprwStage_->update(weights_);
123 resSolver_->preconditioner().update();
125 resSmoother_->preconditioner().update();
126 wellSolver_->preconditioner().update();
134 weights_ = weightsCalculator_();
135 cprwStage_->buildStructure(weights_);
137 resSolver_->preconditioner().update();
139 resSmoother_->preconditioner().update();
141 resizeWellWorkVectors();
161 const auto& A = S_[
_0][
_0];
162 const auto& C = S_[
_0][
_1];
163 const auto& B = S_[
_1][
_0];
164 const auto& D = S_[
_1][
_1];
177 tmp_resRes_ = resRes_;
178 syncResVector(tmp_resRes_);
179 cprwStage_->apply(tmp_resRes_, wRes_, weights_, dresSol_, dwSol_);
182 A.mmv(dresSol_, resRes_);
184 B.mmv(dresSol_, wRes_);
185 if (cprwStage_->prolongatesWellPressure()) {
188 C.mmv(dwSol_, resRes_);
189 D.mmv(dwSol_, wRes_);
194 tmp_resRes_ = resRes_;
195 syncResVector(tmp_resRes_);
196 resSolver_->apply(dresSol_, tmp_resRes_, res_result);
199 A.mmv(dresSol_, resRes_);
201 B.mmv(dresSol_, wRes_);
209 wellSolver_->apply(dwSol_, tmp_wRes_, well_result);
212 C.mmv(dwSol_, resRes_);
214 D.mmv(dwSol_, wRes_);
218 tmp_resRes_ = resRes_;
219 syncResVector(tmp_resRes_);
220 resSmoother_->apply(dresSol_, tmp_resRes_, res_result);
223 B.mmv(dresSol_, wRes_);
231 wellSolver_->apply(dwSol_, tmp_wRes_, well_result);
235 syncResVector(resSol_);
242 const ResComm* resComm_ =
nullptr;
243 int pressureIndex_ = 0;
244 static constexpr int dummyWellPressureIndex = std::numeric_limits<int>::min();
247 std::unique_ptr<ResOp> rop_;
248 std::unique_ptr<WellOperator> wop_;
249 std::unique_ptr<ResFlexibleSolverType> resSolver_;
250 std::unique_ptr<ResFlexibleSolverType> resSmoother_;
251 std::unique_ptr<WellFlexibleSolverType> wellSolver_;
256 std::unique_ptr<CprwStage> cprwStage_;
257 std::function<SystemVector<Scalar>()> weightsCalculator_;
272 resComm_->copyOwnerToAll(v, v);
276 void initWellSolver()
278 wop_ = std::make_unique<WellOperator>(S_[
_1][
_1]);
279 std::function<WellVector<Scalar>()> weightsCalculatorWell;
280 wellSolver_ = std::make_unique<WellFlexibleSolverType>(
281 *wop_, wellprm_, weightsCalculatorWell, dummyWellPressureIndex);
285 const std::function<SystemVector<Scalar>()>& weightsCalculator)
287 auto resprm = prm.
get_child(
"reservoir_solver");
288 auto resprmsmoother = prm.
get_child(
"reservoir_smoother");
294 const bool addWells = resprm.
get(
"preconditioner.add_wells",
false);
298 std::function<ResVector<Scalar>()> resWeightCalc;
299 if (weightsCalculator) {
300 resWeightCalc = [weightsCalculator]() {
301 return weightsCalculator()[
_0];
306 rop_ = std::make_unique<ResOp>(S_[
_0][
_0], *resComm_);
307 resSmoother_ = std::make_unique<ResFlexibleSolverType>(
308 *rop_, *resComm_, resprmsmoother, resWeightCalc, pressureIndex_);
310 rop_ = std::make_unique<ResOp>(S_[
_0][
_0]);
311 resSmoother_ = std::make_unique<ResFlexibleSolverType>(
312 *rop_, resprmsmoother, resWeightCalc, pressureIndex_);
316 if (!weightsCalculator) {
317 OPM_THROW(std::invalid_argument,
318 "The CPRW pressure stage (add_wells) needs a weights calculator, but "
319 "none was configured. Set reservoir_solver.preconditioner.weight_type.");
321 weightsCalculator_ = weightsCalculator;
322 weights_ = weightsCalculator_();
324 auto coarseprm = resprm.get_child_optional(
"preconditioner.coarsesolver")
325 ? resprm.get_child(
"preconditioner.coarsesolver")
330 prm.
get(
"well_transfer", std::string{
"classic"}));
332 prm.
get(
"well_coarse_diagonal", std::string{
"contract_d"}));
333 cprwStage_ = std::make_unique<CprwStage>(S_, coarseprm, pressureIndex_,
334 wellTransfer, resComm_, diagonal,
335 prm.
get(
"verbosity", 0));
336 cprwStage_->buildStructure(weights_);
339 resSolver_ = std::make_unique<ResFlexibleSolverType>(
340 *rop_, *resComm_, resprm, resWeightCalc, pressureIndex_);
342 resSolver_ = std::make_unique<ResFlexibleSolverType>(
343 *rop_, resprm, resWeightCalc, pressureIndex_);
350 void initWorkVectors()
352 resizeReservoirWorkVectors();
353 resizeWellWorkVectors();
356 void resizeReservoirWorkVectors()
358 const auto numRes = S_[
_0][
_0].
N();
359 resSol_.resize(numRes);
360 dresSol_.resize(numRes);
361 tmp_resRes_.resize(numRes);
362 resRes_.resize(numRes);
365 void resizeWellWorkVectors()
367 const auto numWell = S_[
_1][
_1].
N();
368 wSol_.resize(numWell);
369 dwSol_.resize(numWell);
370 tmp_wRes_.resize(numWell);
371 wRes_.resize(numWell);
Definition: FlexibleSolver.hpp:45
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:34
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:39
T get(const std::string &key) const
PropertyTree get_child(const std::string &key) const
Definition: SystemCprwPressureStage.hpp:131
Definition: SystemTypes.hpp:166
static constexpr size_type N()
Definition: SystemTypes.hpp:171
Definition: SystemPreconditioner.hpp:62
bool hasPerfectUpdate() const override
Definition: SystemPreconditioner.hpp:144
void post(SystemVector< Scalar > &) override
Definition: SystemPreconditioner.hpp:105
void pre(SystemVector< Scalar > &, SystemVector< Scalar > &) override
Definition: SystemPreconditioner.hpp:101
Dune::SolverCategory::Category category() const override
Definition: SystemPreconditioner.hpp:109
void updateForChangedWellStructure()
Definition: SystemPreconditioner.hpp:129
static constexpr auto _0
Definition: SystemPreconditioner.hpp:70
static constexpr auto _1
Definition: SystemPreconditioner.hpp:71
SystemPreconditioner(const SystemMatrix< Scalar > &S, const std::function< SystemVector< Scalar >()> &weightsCalculator, int pressureIndex, const Opm::PropertyTree &prm, const ResComm &resComm)
Definition: SystemPreconditioner.hpp:87
Dune::MatrixAdapter< WWMatrix< Scalar >, WellVector< Scalar >, WellVector< Scalar > > WellOperator
Definition: SystemPreconditioner.hpp:67
static constexpr bool isParallel
Definition: SystemPreconditioner.hpp:64
SystemPreconditioner(const SystemMatrix< Scalar > &S, const std::function< SystemVector< Scalar >()> &weightsCalculator, int pressureIndex, const Opm::PropertyTree &prm)
Definition: SystemPreconditioner.hpp:74
void update() override
Definition: SystemPreconditioner.hpp:117
void apply(SystemVector< Scalar > &v, const SystemVector< Scalar > &d) override
Definition: SystemPreconditioner.hpp:158
Definition: blackoilbioeffectsmodules.hh:45
Dune::MultiTypeBlockVector< ResVector< Scalar >, WellVector< Scalar > > SystemVector
Definition: SystemTypes.hpp:65
Dune::InverseOperatorResult InverseOperatorResult
Definition: GpuBridge.hpp:32
WellCoarseDiagonal wellCoarseDiagonalFromString(const std::string &name)
Definition: SystemCprwPressureStage.hpp:102
Dune::OverlappingSchwarzOperator< RRMatrix< Scalar >, ResVector< Scalar >, ResVector< Scalar >, ParResComm > ParResOperator
Definition: SystemPreconditioner.hpp:47
Dune::OwnerOverlapCopyCommunication< int, int > ParResComm
Definition: SystemPreconditioner.hpp:45
Dune::MatrixAdapter< RRMatrix< Scalar >, ResVector< Scalar >, ResVector< Scalar > > SeqResOperator
Definition: SystemPreconditioner.hpp:42
Dune::BlockVector< Dune::FieldVector< Scalar, numResDofs > > ResVector
Definition: SystemTypes.hpp:61
WellTransfer wellTransferFromString(const std::string &name)
Definition: SystemCprwPressureStage.hpp:112
Dune::BlockVector< Dune::FieldVector< Scalar, numWellDofs > > WellVector
Definition: SystemTypes.hpp:63