ISTLSolver.hpp
Go to the documentation of this file.
1/*
2 Copyright 2016 IRIS AS
3 Copyright 2019, 2020 Equinor ASA
4 Copyright 2020 SINTEF Digital, Mathematics and Cybernetics
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_ISTLSOLVER_HEADER_INCLUDED
23#define OPM_ISTLSOLVER_HEADER_INCLUDED
24
25#include <dune/istl/owneroverlapcopy.hh>
26#include <dune/istl/solver.hh>
27
28#include <opm/common/CriticalError.hpp>
29#include <opm/common/ErrorMacros.hpp>
30#include <opm/common/Exceptions.hpp>
31#include <opm/common/TimingMacros.hpp>
32
33#include <opm/grid/utility/ElementChunks.hpp>
34
54
55#include <fmt/format.h>
56
57#include <any>
58#include <cstddef>
59#include <functional>
60#include <memory>
61#include <set>
62#include <sstream>
63#include <string>
64#include <tuple>
65#include <vector>
66
67namespace Opm::Properties {
68
69namespace TTag {
71 using InheritsFrom = std::tuple<FlowIstlSolverParams>;
72};
73}
74
75template <class TypeTag, class MyTypeTag>
76struct WellModel;
77
80template<class TypeTag>
81struct SparseMatrixAdapter<TypeTag, TTag::FlowIstlSolver>
82{
83private:
85 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
87
88public:
90};
91
92} // namespace Opm::Properties
93
94namespace Opm
95{
96
97
98namespace detail
99{
100
101template<class Matrix, class Vector, class Comm>
103{
104 using AbstractSolverType = Dune::InverseOperator<Vector, Vector>;
105 using AbstractOperatorType = Dune::AssembledLinearOperator<Matrix, Vector, Vector>;
107
108 void create(const Matrix& matrix,
109 bool parallel,
110 const PropertyTree& prm,
111 std::size_t pressureIndex,
112 std::function<Vector()> weightCalculator,
113 const bool forceSerial,
114 Comm* comm);
115
116 std::unique_ptr<AbstractSolverType> solver_;
117 std::unique_ptr<AbstractOperatorType> op_;
118 std::unique_ptr<LinearOperatorExtra<Vector,Vector>> wellOperator_;
120 std::size_t interiorCellNum_ = 0;
121};
122
123
124#ifdef HAVE_MPI
126void copyParValues(std::any& parallelInformation, std::size_t size,
127 Dune::OwnerOverlapCopyCommunication<int,int>& comm);
128#endif
129
132template<class Matrix>
133void makeOverlapRowsInvalid(Matrix& matrix,
134 const std::vector<int>& overlapRows);
135
138template<class Matrix, class Grid>
139std::unique_ptr<Matrix> blockJacobiAdjacency(const Grid& grid,
140 const std::vector<int>& cell_part,
141 std::size_t nonzeroes,
142 const std::vector<std::set<int>>& wellConnectionsGraph);
143}
144
149 template <class TypeTag>
150 class ISTLSolver : public AbstractISTLSolver<GetPropType<TypeTag, Properties::SparseMatrixAdapter>,
151 GetPropType<TypeTag, Properties::GlobalEqVector>>
152 {
153 protected:
161 using Matrix = typename SparseMatrixAdapter::IstlMatrix;
164 using AbstractSolverType = Dune::InverseOperator<Vector, Vector>;
165 using AbstractOperatorType = Dune::AssembledLinearOperator<Matrix, Vector, Vector>;
169 using ElementChunksType = ElementChunks<GridView, Dune::Partitions::All>;
171
173
174 static constexpr bool enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>();
176
177 // The analytic true-IMPES weights are built from black-oil formation volume factors.
178 constexpr static bool hasAnalyticImpesWeights = requires (const FluidState& fs) { fs.invB(0); };
179
180#if HAVE_MPI
181 using CommunicationType = Dune::OwnerOverlapCopyCommunication<int,int>;
182#else
183 using CommunicationType = Dune::Communication<int>;
184#endif
185
186 public:
187 using AssembledLinearOperatorType = Dune::AssembledLinearOperator< Matrix, Vector, Vector >;
188
189 static void registerParameters()
190 {
192 }
193
201 ISTLSolver(const Simulator& simulator,
202 const FlowLinearSolverParameters& parameters,
203 bool forceSerial = false)
204 : simulator_(simulator),
205 iterations_( 0 ),
206 matrix_(nullptr),
207 parameters_{parameters},
208 forceSerial_(forceSerial)
209 {
210 initialize();
211 }
212
215 explicit ISTLSolver(const Simulator& simulator)
216 : simulator_(simulator),
217 iterations_( 0 ),
218 solveCount_(0),
219 matrix_(nullptr)
220 {
221 parameters_.resize(1);
222 parameters_[0].init(simulator_.vanguard().eclState().getSimulationConfig().useCPR());
223 initialize();
224 }
225
227 {
228 OPM_TIMEBLOCK(IstlSolver);
229
231 // Polymer injectivity is incompatible with the CPRW linear solver.
232 // Instead of aborting the run, emit a warning and fall back to ILU0
233 // so that polymer injectivity cases work with default parameters.
234 if (parameters_[0].linsolver_ == "cprw" || parameters_[0].linsolver_ == "hybrid") {
235 const bool on_io_rank = (simulator_.gridView().comm().rank() == 0);
236 const std::string msg =
237 fmt::format("The polymer injectivity model is incompatible with the '{}' "
238 "linear solver. Falling back to --linear-solver=ilu0.",
239 parameters_[0].linsolver_);
240 if (on_io_rank) {
241 OpmLog::warning(msg);
242 }
243 parameters_[0].linsolver_ = "ilu0";
244 }
245 }
246
247 if (parameters_[0].linsolver_ == "hybrid") {
248 // Experimental hybrid configuration.
249 // When chosen, will set up two solvers, one with CPRW
250 // and the other with ILU0 preconditioner. More general
251 // options may be added later.
252 prm_.clear();
253 parameters_.clear();
254 {
256 para.init(false);
257 para.linsolver_ = "cprw";
258 parameters_.push_back(para);
260 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
261 Parameters::IsSet<Parameters::LinearSolverReduction>()));
262 }
263 {
265 para.init(false);
266 para.linsolver_ = "ilu0";
267 parameters_.push_back(para);
269 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
270 Parameters::IsSet<Parameters::LinearSolverReduction>()));
271 }
272 // ------------
273 } else {
274 assert(parameters_.size() == 1);
275 assert(prm_.empty());
276
277 // Do a normal linear solver setup.
278 if (parameters_[0].is_nldd_local_solver_) {
280 Parameters::IsSet<Parameters::NlddLocalLinearSolverMaxIter>(),
281 Parameters::IsSet<Parameters::NlddLocalLinearSolverReduction>()));
282 }
283 else {
285 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
286 Parameters::IsSet<Parameters::LinearSolverReduction>()));
287 }
288 }
289 flexibleSolver_.resize(prm_.size());
290
291 const bool on_io_rank = (simulator_.gridView().comm().rank() == 0);
292#if HAVE_MPI
293 comm_.reset( new CommunicationType( simulator_.vanguard().grid().comm() ) );
294#endif
296
297 // For some reason simulator_.model().elementMapper() is not initialized at this stage
298 //const auto& elemMapper = simulator_.model().elementMapper(); //does not work.
299 // Set it up manually
300 ElementMapper elemMapper(simulator_.vanguard().gridView(), Dune::mcmgElementLayout());
302 useWellConn_ = Parameters::Get<Parameters::MatrixAddWellContributions>();
303 const bool ownersFirst = Parameters::Get<Parameters::OwnerCellsFirst>();
304 if (!ownersFirst) {
305 const std::string msg = "The linear solver no longer supports --owner-cells-first=false.";
306 if (on_io_rank) {
307 OpmLog::error(msg);
308 }
309 OPM_THROW_NOLOG(std::runtime_error, msg);
310 }
311
312 const int interiorCellNum_ = detail::numMatrixRowsToUseInSolver(simulator_.vanguard().grid(), true);
313 for (auto& f : flexibleSolver_) {
314 f.interiorCellNum_ = interiorCellNum_;
315 }
316
317#if HAVE_MPI
318 if (isParallel()) {
319 const std::size_t size = simulator_.vanguard().grid().leafGridView().size(0);
321 }
322#endif
323
324 // Print parameters to PRT/DBG logs.
326
327 element_chunks_ = std::make_unique<ElementChunksType>(simulator_.vanguard().gridView(), Dune::Partitions::all, ThreadManager::maxThreads());
328 }
329
330 // Drop the cached matrix pointer so initPrepare() sees the next matrix
331 // as a new object. Callers that rebuild the linear system mid-run rely
332 // on this - opm-flowgeomechanics does it from FlowProblemMech when
333 // fracture connections change.
334 void eraseMatrix() override
335 {
336 matrix_ = nullptr;
337 rhs_ = nullptr;
338 iterations_ = 0;
339 solveCount_ = 0;
340
341 for (auto& solverInfo : flexibleSolver_) {
342 solverInfo.pre_ = nullptr;
343 solverInfo.solver_.reset();
344 solverInfo.op_.reset();
345 }
346 }
347
348 void setActiveSolver(const int num) override
349 {
350 if (num > static_cast<int>(prm_.size()) - 1) {
351 OPM_THROW(std::logic_error, "Solver number " + std::to_string(num) + " not available.");
352 }
353 activeSolverNum_ = num;
354 if (simulator_.gridView().comm().rank() == 0) {
355 OpmLog::debug("Active solver = " + std::to_string(activeSolverNum_)
356 + " (" + parameters_[activeSolverNum_].linsolver_ + ")");
357 }
358 }
359
360 int numAvailableSolvers() const override
361 {
362 return flexibleSolver_.size();
363 }
364
365 void initPrepare(const Matrix& M, Vector& b)
366 {
367 // matrix_ starts out null, so this also covers the first call.
368 const bool matrix_changed = &M != matrix_;
369
370 if (matrix_changed) {
371 // The matrix object is no longer the one the solver was built
372 // for, so the solver has to be rebuilt rather than updated.
373 force_recreate_ = true;
374
375 // model will not change the matrix object. Hence simply store a pointer
376 // to the original one with a deleter that does nothing.
377 // Outch! We need to be able to scale the linear system! Hence const_cast
378 matrix_ = const_cast<Matrix*>(&M);
379
380 useWellConn_ = Parameters::Get<Parameters::MatrixAddWellContributions>();
381 // setup sparsity pattern for jacobi matrix for preconditioner (only used for openclSolver)
382 }
383 rhs_ = &b;
384
385 // TODO: check all solvers, not just one.
386 // We use lower case as the internal canonical representation of solver names
387 std::string type = prm_[activeSolverNum_].template get<std::string>("preconditioner.type", "paroverilu0");
388 std::ranges::transform(type, type.begin(), ::tolower);
389 if (isParallel() && type != "paroverilu0") {
391 }
392 }
393
394 void prepare(const SparseMatrixAdapter& M, Vector& b) override
395 {
396 prepare(M.istlMatrix(), b);
397 }
398
399 void prepare(const Matrix& M, Vector& b) override
400 {
401 OPM_TIMEBLOCK(istlSolverPrepare);
402 try {
403 initPrepare(M,b);
404
406 }
407 catch (const Dune::MatrixBlockError&) {
408 // Construction or update may have left a partial preconditioner.
409 // Rebuild it on the next attempt, independently of state rollback.
410 eraseMatrix();
411 // A singular matrix block found while building the
412 // preconditioner is recoverable: rethrow it unchanged so that
413 // the adaptive time stepping can chop the time step instead of
414 // aborting the run.
415 throw;
416 }
417 OPM_CATCH_AND_RETHROW_AS_CRITICAL_ERROR("This is likely due to a faulty linear solver JSON specification. Check for errors related to missing nodes.");
418 }
419
420
421 void setResidual(Vector& /* b */) override
422 {
423 // rhs_ = &b; // Must be handled in prepare() instead.
424 }
425
426 void getResidual(Vector& b) const override
427 {
428 b = *rhs_;
429 }
430
431 void setMatrix(const SparseMatrixAdapter& /* M */) override
432 {
433 // matrix_ = &M.istlMatrix(); // Must be handled in prepare() instead.
434 }
435
436 int getSolveCount() const override {
437 return solveCount_;
438 }
439
441 solveCount_ = 0;
442 }
443
444 bool solve(Vector& x) override
445 {
446 OPM_TIMEBLOCK(istlSolverSolve);
447 ++solveCount_;
448 // Write linear system if asked for.
449 const int verbosity = prm_[activeSolverNum_].get("verbosity", 0);
450 const bool write_matrix = verbosity > 10;
451 if (write_matrix) {
452 Helper::writeSystem(simulator_, //simulator is only used to get names
453 getMatrix(),
454 *rhs_,
455 comm_.get());
456 }
457
458 // Solve system.
460 {
461 OPM_TIMEBLOCK(flexibleSolverApply);
462 assert(flexibleSolver_[activeSolverNum_].solver_);
463 flexibleSolver_[activeSolverNum_].solver_->apply(x, *rhs_, result);
464 }
465
466 iterations_ = result.iterations;
467
468 // Check convergence, iterations etc.
469 return checkConvergence(result);
470 }
471
472
478
480 int iterations () const override { return iterations_; }
481
483 const std::any& parallelInformation() const { return parallelInformation_; }
484
485 const CommunicationType* comm() const override { return comm_.get(); }
486
487 void setDomainIndex(const int index)
488 {
489 domainIndex_ = index;
490 }
491
492 bool isNlddLocalSolver() const
493 {
494 return parameters_[activeSolverNum_].is_nldd_local_solver_;
495 }
496
498 {
499 return prm_[activeSolverNum_];
500 }
501
502 protected:
503#if HAVE_MPI
504 using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
505#endif
506
508 {
510 }
511
512 bool isParallel() const {
513#if HAVE_MPI
514 return !forceSerial_ && comm_->communicator().size() > 1;
515#else
516 return false;
517#endif
518 }
519
521 {
522 OPM_TIMEBLOCK(flexibleSolverPrepare);
523 if (shouldCreateSolver()) {
524 if (!useWellConn_) {
525 if (isNlddLocalSolver()) {
526 auto wellOp = std::make_unique<DomainWellModelAsLinearOperator<WellModel, Vector, Vector>>(simulator_.problem().wellModel());
527 wellOp->setDomainIndex(domainIndex_);
528 flexibleSolver_[activeSolverNum_].wellOperator_ = std::move(wellOp);
529 }
530 else {
531 auto wellOp = std::make_unique<WellModelOperator>(simulator_.problem().wellModel());
532 flexibleSolver_[activeSolverNum_].wellOperator_ = std::move(wellOp);
533 }
534 }
535 std::function<Vector()> weightCalculator
536 = this->getWeightsCalculator(prm_[activeSolverNum_], pressureIndex);
537 OPM_TIMEBLOCK(flexibleSolverCreate);
539 isParallel(),
542 weightCalculator,
544 comm_.get());
546 }
547 else
548 {
549 OPM_TIMEBLOCK(flexibleSolverUpdate);
550 flexibleSolver_[activeSolverNum_].pre_->update();
551 }
552 }
553
554
557 {
558 return useWellConn_
559 ? 0
560 : simulator_.problem().wellModel().numLocalWellsEnd();
561 }
562
566 {
567 // Decide if we should recreate the solver or just do
568 // a minimal preconditioner update.
569 if (force_recreate_) {
570 force_recreate_ = false; // one-shot trigger set by initPrepare
571 return true;
572 }
573
574 if (flexibleSolver_.empty()) {
575 return true;
576 }
577
578 if (!flexibleSolver_[activeSolverNum_].solver_) {
579 return true;
580 }
581
582 // The CPRW coarse system reserves a row per well, so its size is
583 // fixed when the solver is built. A well drilled by an ACTIONX
584 // block changes the well count mid-run; updating in place would
585 // then write past the end of the coarse matrix.
586 if (this->numWellEquations() != numWellEquations_) {
587 return true;
588 }
589
590 if (flexibleSolver_[activeSolverNum_].pre_->hasPerfectUpdate()) {
591 return false;
592 }
593
594 // For AMG based preconditioners, the hierarchy depends on the matrix values
595 // so it is recreated at certain intervals
596 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 0) {
597 // Always recreate solver.
598 return true;
599 }
600 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 1) {
601 // Recreate solver on the first iteration of every timestep.
602 return this->simulator_.problem().iterationContext().isFirstGlobalIteration();
603 }
604 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 2) {
605 // Recreate solver if the last solve used more than 10 iterations.
606 return this->iterations() > 10;
607 }
608 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 3) {
609 // Never recreate the solver
610 return false;
611 }
612 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 4) {
613 // Recreate solver every 'step' solve calls.
614 const int step = this->parameters_[activeSolverNum_].cpr_reuse_interval_;
615 const bool create = ((solveCount_ % step) == 0);
616 return create;
617 }
618 // If here, we have an invalid parameter.
619 const bool on_io_rank = (simulator_.gridView().comm().rank() == 0);
620 std::string msg = "Invalid value: " + std::to_string(this->parameters_[activeSolverNum_].cpr_reuse_setup_)
621 + " for --cpr-reuse-setup parameter, run with --help to see allowed values.";
622 if (on_io_rank) {
623 OpmLog::error(msg);
624 }
625 throw std::runtime_error(msg);
626
627 return false;
628 }
629
630
631 // Weights to make approximate pressure equations.
632 // Calculated from the storage terms (only) of the
633 // conservation equations, ignoring all other terms.
634 std::function<Vector()> getWeightsCalculator(const PropertyTree& prm,
635 std::size_t pressIndex) const
636 {
637 std::function<Vector()> weightsCalculator;
638
639 using namespace std::string_literals;
640
641 auto preconditionerType = prm.get("preconditioner.type"s, "cpr"s);
642 // We use lower case as the internal canonical representation of solver names
643 std::ranges::transform(preconditionerType, preconditionerType.begin(), ::tolower);
644 if (preconditionerType == "cpr" || preconditionerType == "cprt"
645 || preconditionerType == "cprw" || preconditionerType == "cprwt") {
646 const bool transpose = preconditionerType == "cprt" || preconditionerType == "cprwt";
647 const bool enableThreadParallel = this->parameters_[0].cpr_weights_thread_parallel_;
648 const auto weightsType = prm.get("preconditioner.weight_type"s, "quasiimpes"s);
649 if (weightsType == "quasiimpes") {
650 // Use the current matrix: preconditioner updates call this
651 // without rebuilding the solver.
652 weightsCalculator = [this, transpose, pressIndex, enableThreadParallel]() {
653 return Amg::getQuasiImpesWeights<Matrix, Vector>(
654 getMatrix(), pressIndex, transpose, enableThreadParallel);
655 };
656 } else if ( weightsType == "trueimpes" ) {
657 weightsCalculator =
658 [this, pressIndex, enableThreadParallel]
659 {
660 Vector weights(rhs_->size());
661 ElementContext elemCtx(simulator_);
662 Amg::getTrueImpesWeights(pressIndex,
663 weights,
664 elemCtx,
665 simulator_.model(),
667 enableThreadParallel
668 );
669 return weights;
670 };
671 } else if (weightsType == "trueimpesanalytic" ) {
672 if constexpr (hasAnalyticImpesWeights) {
673 weightsCalculator =
674 [this, pressIndex, enableThreadParallel]
675 {
676 Vector weights(rhs_->size());
677 ElementContext elemCtx(simulator_);
679 weights,
680 elemCtx,
681 simulator_.model(),
683 enableThreadParallel
684 );
685 return weights;
686 };
687 } else {
688 OPM_THROW(std::invalid_argument,
689 "Weights type trueimpesanalytic needs the black-oil model."
690 " Please use quasiimpes or trueimpes.");
691 }
692 } else {
693 OPM_THROW(std::invalid_argument,
694 "Weights type " + weightsType +
695 "not implemented for cpr."
696 " Please use quasiimpes, trueimpes or trueimpesanalytic.");
697 }
698 }
699 return weightsCalculator;
700 }
701
702
704 {
705 return *matrix_;
706 }
707
708 const Matrix& getMatrix() const
709 {
710 return *matrix_;
711 }
712
714 mutable int iterations_;
715 mutable int solveCount_;
717
718 // non-const to be able to scale the linear system
721
723 std::vector<detail::FlexibleSolverInfo<Matrix,Vector,CommunicationType>> flexibleSolver_;
724 std::vector<int> overlapRows_;
725 std::vector<int> interiorRows_;
726
727 int domainIndex_ = -1;
728
729 // Number of well equations the current solver was built for, or -1 if
730 // no solver has been built yet. See shouldCreateSolver().
732
734
735 std::vector<FlowLinearSolverParameters> parameters_;
736 bool forceSerial_ = false;
737 std::vector<PropertyTree> prm_;
738
739 std::shared_ptr< CommunicationType > comm_;
740 std::unique_ptr<ElementChunksType> element_chunks_;
741 // set when initPrepare detects a different matrix object; cleared by
742 // shouldCreateSolver() (hence mutable in an otherwise const query)
743 mutable bool force_recreate_ = false;
744 }; // end ISTLSolver
745
746} // namespace Opm
747
748#endif // OPM_ISTLSOLVER_HEADER_INCLUDED
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: FlexibleSolver_impl.hpp:404
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:34
Abstract interface for ISTL solvers.
Definition: AbstractISTLSolver.hpp:45
static bool checkConvergence(const Dune::InverseOperatorResult &result, const FlowLinearSolverParameters &parameters)
Check the convergence of the linear solver.
Definition: AbstractISTLSolver.hpp:192
Definition: ISTLSolver.hpp:152
void getResidual(Vector &b) const override
Definition: ISTLSolver.hpp:426
void initialize()
Definition: ISTLSolver.hpp:226
const Matrix & getMatrix() const
Definition: ISTLSolver.hpp:708
ElementChunks< GridView, Dune::Partitions::All > ElementChunksType
Definition: ISTLSolver.hpp:169
ISTLSolver(const Simulator &simulator, const FlowLinearSolverParameters &parameters, bool forceSerial=false)
Definition: ISTLSolver.hpp:201
void setDomainIndex(const int index)
Definition: ISTLSolver.hpp:487
int iterations() const override
Definition: ISTLSolver.hpp:480
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: ISTLSolver.hpp:155
bool force_recreate_
Definition: ISTLSolver.hpp:743
std::shared_ptr< CommunicationType > comm_
Definition: ISTLSolver.hpp:739
static constexpr bool isIncompatibleWithCprw
Definition: ISTLSolver.hpp:175
std::vector< FlowLinearSolverParameters > parameters_
Definition: ISTLSolver.hpp:735
void setActiveSolver(const int num) override
Set the active solver by its index.
Definition: ISTLSolver.hpp:348
GetPropType< TypeTag, Properties::GridView > GridView
Definition: ISTLSolver.hpp:154
Dune::InverseOperator< Vector, Vector > AbstractSolverType
Definition: ISTLSolver.hpp:164
std::function< Vector()> getWeightsCalculator(const PropertyTree &prm, std::size_t pressIndex) const
Definition: ISTLSolver.hpp:634
void setMatrix(const SparseMatrixAdapter &) override
Definition: ISTLSolver.hpp:431
void prepare(const Matrix &M, Vector &b) override
Definition: ISTLSolver.hpp:399
typename SparseMatrixAdapter::IstlMatrix Matrix
Definition: ISTLSolver.hpp:161
int numWellEquations() const
Number of extra equations the well operator contributes.
Definition: ISTLSolver.hpp:556
GetPropType< TypeTag, Properties::WellModel > WellModel
Definition: ISTLSolver.hpp:159
int solveCount_
Definition: ISTLSolver.hpp:715
bool isNlddLocalSolver() const
Definition: ISTLSolver.hpp:492
Matrix & getMatrix()
Definition: ISTLSolver.hpp:703
int numAvailableSolvers() const override
Get the number of available solvers.
Definition: ISTLSolver.hpp:360
GetPropType< TypeTag, Properties::SparseMatrixAdapter > SparseMatrixAdapter
Definition: ISTLSolver.hpp:156
void prepare(const SparseMatrixAdapter &M, Vector &b) override
Definition: ISTLSolver.hpp:394
Dune::OwnerOverlapCopyCommunication< int, int > CommunicationType
Definition: ISTLSolver.hpp:181
int getSolveCount() const override
Get the count of how many times the solver has been called.
Definition: ISTLSolver.hpp:436
Matrix * matrix_
Definition: ISTLSolver.hpp:719
bool useWellConn_
Definition: ISTLSolver.hpp:733
bool shouldCreateSolver() const
Definition: ISTLSolver.hpp:565
const PropertyTree & activeSolverPrm() const
Definition: ISTLSolver.hpp:497
bool checkConvergence(const Dune::InverseOperatorResult &result) const
Definition: ISTLSolver.hpp:507
static constexpr std::size_t pressureIndex
Definition: ISTLSolver.hpp:172
void prepareFlexibleSolver()
Definition: ISTLSolver.hpp:520
GetPropType< TypeTag, Properties::ThreadManager > ThreadManager
Definition: ISTLSolver.hpp:162
GetPropType< TypeTag, Properties::ElementMapper > ElementMapper
Definition: ISTLSolver.hpp:168
void resetSolveCount()
Definition: ISTLSolver.hpp:440
GetPropType< TypeTag, Properties::GlobalEqVector > Vector
Definition: ISTLSolver.hpp:157
const std::any & parallelInformation() const
Definition: ISTLSolver.hpp:483
void initPrepare(const Matrix &M, Vector &b)
Definition: ISTLSolver.hpp:365
std::vector< detail::FlexibleSolverInfo< Matrix, Vector, CommunicationType > > flexibleSolver_
Definition: ISTLSolver.hpp:723
void eraseMatrix() override
Signals that the memory for the matrix internally in the solver could be erased.
Definition: ISTLSolver.hpp:334
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AbstractOperatorType
Definition: ISTLSolver.hpp:165
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AssembledLinearOperatorType
Definition: ISTLSolver.hpp:187
ISTLSolver(const Simulator &simulator)
Definition: ISTLSolver.hpp:215
int iterations_
Definition: ISTLSolver.hpp:714
int domainIndex_
Definition: ISTLSolver.hpp:727
std::any parallelInformation_
Definition: ISTLSolver.hpp:716
GetPropType< TypeTag, Properties::Simulator > Simulator
Definition: ISTLSolver.hpp:160
Vector * rhs_
Definition: ISTLSolver.hpp:720
int activeSolverNum_
Definition: ISTLSolver.hpp:722
std::vector< int > overlapRows_
Definition: ISTLSolver.hpp:724
std::unique_ptr< ElementChunksType > element_chunks_
Definition: ISTLSolver.hpp:740
GetPropType< TypeTag, Properties::Indices > Indices
Definition: ISTLSolver.hpp:158
static constexpr bool enablePolymerMolarWeight
Definition: ISTLSolver.hpp:174
const Simulator & simulator_
Definition: ISTLSolver.hpp:713
std::vector< int > interiorRows_
Definition: ISTLSolver.hpp:725
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: ISTLSolver.hpp:504
bool forceSerial_
Definition: ISTLSolver.hpp:736
bool solve(Vector &x) override
Definition: ISTLSolver.hpp:444
typename GetPropType< TypeTag, Properties::IntensiveQuantities >::FluidState FluidState
Definition: ISTLSolver.hpp:170
int numWellEquations_
Definition: ISTLSolver.hpp:731
static void registerParameters()
Definition: ISTLSolver.hpp:189
std::vector< PropertyTree > prm_
Definition: ISTLSolver.hpp:737
GetPropType< TypeTag, Properties::ElementContext > ElementContext
Definition: ISTLSolver.hpp:163
void setResidual(Vector &) override
Definition: ISTLSolver.hpp:421
static constexpr bool hasAnalyticImpesWeights
Definition: ISTLSolver.hpp:178
const CommunicationType * comm() const override
Get the communication object used by the solver.
Definition: ISTLSolver.hpp:485
bool isParallel() const
Definition: ISTLSolver.hpp:512
A sparse matrix interface backend for BCRSMatrix from dune-istl.
Definition: istlsparsematrixadapter.hh:43
Definition: matrixblock.hh:256
Hierarchical collection of key/value pairs.
Definition: PropertyTree.hpp:39
T get(const std::string &key) const
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
Definition: WellOperators.hpp:71
Declare the properties used by the infrastructure code of the finite volume discretizations.
Defines the common properties required by the porous medium multi-phase models.
void getTrueImpesWeights(int pressureVarIndex, Vector &weights, const ElementContext &elemCtx, const Model &model, const ElementChunksType &element_chunks, bool enable_thread_parallel)
Definition: getQuasiImpesWeights.hpp:165
void getTrueImpesWeightsAnalytic(int, Vector &weights, const ElementContext &elemCtx, const Model &model, const ElementChunksType &element_chunks, bool enable_thread_parallel)
Definition: getQuasiImpesWeights.hpp:260
void writeSystem(const SimulatorType &simulator, const MatrixType &matrix, const VectorType &rhs, const std::string &sysName, const Communicator *comm)
Definition: WriteSystemMatrixHelper.hpp:197
Definition: blackoilmodel.hh:74
std::unique_ptr< Matrix > blockJacobiAdjacency(const Grid &grid, const std::vector< int > &cell_part, std::size_t nonzeroes, const std::vector< std::set< int > > &wellConnectionsGraph)
void copyParValues(std::any &parallelInformation, std::size_t size, Dune::OwnerOverlapCopyCommunication< int, int > &comm)
Copy values in parallel.
std::size_t numMatrixRowsToUseInSolver(const Grid &grid, bool ownerFirst)
If ownerFirst=true, returns the number of interior cells in grid, else just numCells().
Definition: findOverlapRowsAndColumns.hpp:122
void makeOverlapRowsInvalid(Matrix &matrix, const std::vector< int > &overlapRows)
void findOverlapAndInterior(const Grid &grid, const Mapper &mapper, std::vector< int > &overlapRows, std::vector< int > &interiorRows)
Find the rows corresponding to overlap cells.
Definition: findOverlapRowsAndColumns.hpp:92
void printLinearSolverParameters(const FlowLinearSolverParameters &parameters, const VectorOrSingle &prm, const Comm &comm)
Print the linear solver parameters to the log if requested.
Definition: printlinearsolverparameter.hpp:61
Definition: blackoilbioeffectsmodules.hh:45
Dune::InverseOperatorResult InverseOperatorResult
Definition: GpuBridge.hpp:32
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
void extractParallelGridInformationToISTL(const Dune::CpGrid &grid, std::any &anyComm)
Extracts the information about the data decomposition from the grid for dune-istl.
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
PropertyTree setupPropertyTree(FlowLinearSolverParameters p, bool linearSolverMaxIterSet, bool linearSolverReductionSet, bool tpsaSetup=false)
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
This class carries all parameters for the NewtonIterationBlackoilInterleaved class.
Definition: FlowLinearSolverParameters.hpp:98
void init(bool cprRequestedInDataFile)
std::string linsolver_
Definition: FlowLinearSolverParameters.hpp:113
typename Linear::IstlSparseMatrixAdapter< Block > type
Definition: ISTLSolver.hpp:89
The class that allows to manipulate sparse matrices.
Definition: linalgproperties.hh:50
Definition: ISTLSolver.hpp:70
std::tuple< FlowIstlSolverParams > InheritsFrom
Definition: ISTLSolver.hpp:71
Definition: FlowBaseProblemProperties.hpp:99
Definition: ISTLSolver.hpp:103
std::unique_ptr< AbstractSolverType > solver_
Definition: ISTLSolver.hpp:116
std::size_t interiorCellNum_
Definition: ISTLSolver.hpp:120
Dune::InverseOperator< Vector, Vector > AbstractSolverType
Definition: ISTLSolver.hpp:104
AbstractPreconditionerType * pre_
Definition: ISTLSolver.hpp:119
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AbstractOperatorType
Definition: ISTLSolver.hpp:105
void create(const Matrix &matrix, bool parallel, const PropertyTree &prm, std::size_t pressureIndex, std::function< Vector()> weightCalculator, const bool forceSerial, Comm *comm)
std::unique_ptr< LinearOperatorExtra< Vector, Vector > > wellOperator_
Definition: ISTLSolver.hpp:118
std::unique_ptr< AbstractOperatorType > op_
Definition: ISTLSolver.hpp:117