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/ErrorMacros.hpp>
29#include <opm/common/Exceptions.hpp>
30#include <opm/common/TimingMacros.hpp>
31
49
50#include <any>
51#include <cstddef>
52#include <functional>
53#include <memory>
54#include <set>
55#include <sstream>
56#include <string>
57#include <tuple>
58#include <vector>
59
60namespace Opm::Properties {
61
62namespace TTag {
64 using InheritsFrom = std::tuple<FlowIstlSolverParams>;
65};
66}
67
68template <class TypeTag, class MyTypeTag>
69struct WellModel;
70
73template<class TypeTag>
74struct SparseMatrixAdapter<TypeTag, TTag::FlowIstlSolver>
75{
76private:
78 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
80
81public:
83};
84
85} // namespace Opm::Properties
86
87namespace Opm
88{
89
90
91namespace detail
92{
93
94template<class Matrix, class Vector, class Comm>
96{
97 using AbstractSolverType = Dune::InverseOperator<Vector, Vector>;
98 using AbstractOperatorType = Dune::AssembledLinearOperator<Matrix, Vector, Vector>;
100
101 void create(const Matrix& matrix,
102 bool parallel,
103 const PropertyTree& prm,
104 std::size_t pressureIndex,
105 std::function<Vector()> weightCalculator,
106 const bool forceSerial,
107 Comm& comm);
108
109 std::unique_ptr<AbstractSolverType> solver_;
110 std::unique_ptr<AbstractOperatorType> op_;
111 std::unique_ptr<LinearOperatorExtra<Vector,Vector>> wellOperator_;
113 std::size_t interiorCellNum_ = 0;
114};
115
116
117#ifdef HAVE_MPI
119void copyParValues(std::any& parallelInformation, std::size_t size,
120 Dune::OwnerOverlapCopyCommunication<int,int>& comm);
121#endif
122
125template<class Matrix>
126void makeOverlapRowsInvalid(Matrix& matrix,
127 const std::vector<int>& overlapRows);
128
131template<class Matrix, class Grid>
132std::unique_ptr<Matrix> blockJacobiAdjacency(const Grid& grid,
133 const std::vector<int>& cell_part,
134 std::size_t nonzeroes,
135 const std::vector<std::set<int>>& wellConnectionsGraph);
136}
137
142 template <class TypeTag>
144 {
145 protected:
153 using Matrix = typename SparseMatrixAdapter::IstlMatrix;
156 using AbstractSolverType = Dune::InverseOperator<Vector, Vector>;
157 using AbstractOperatorType = Dune::AssembledLinearOperator<Matrix, Vector, Vector>;
162
163 enum { enableMICP = getPropValue<TypeTag, Properties::EnableMICP>() };
164 enum { enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>() };
166
167#if HAVE_MPI
168 using CommunicationType = Dune::OwnerOverlapCopyCommunication<int,int>;
169#else
170 using CommunicationType = Dune::Communication<int>;
171#endif
172
173 public:
174 using AssembledLinearOperatorType = Dune::AssembledLinearOperator< Matrix, Vector, Vector >;
175
176 static void registerParameters()
177 {
179 }
180
188 ISTLSolver(const Simulator& simulator,
189 const FlowLinearSolverParameters& parameters,
190 bool forceSerial = false)
191 : simulator_(simulator),
192 iterations_( 0 ),
193 converged_(false),
194 matrix_(nullptr),
195 parameters_{parameters},
196 forceSerial_(forceSerial)
197 {
198 initialize();
199 }
200
203 explicit ISTLSolver(const Simulator& simulator)
204 : simulator_(simulator),
205 iterations_( 0 ),
206 solveCount_(0),
207 converged_(false),
208 matrix_(nullptr)
209 {
210 parameters_.resize(1);
211 parameters_[0].init(simulator_.vanguard().eclState().getSimulationConfig().useCPR());
212 initialize();
213 }
214
216 {
217 OPM_TIMEBLOCK(IstlSolver);
218
220 // Some model variants are incompatible with the CPRW linear solver.
221 if (parameters_[0].linsolver_ == "cprw" || parameters_[0].linsolver_ == "hybrid") {
222 std::string incompatible_model = "Unknown";
223 if (enableMICP) {
224 incompatible_model = "MICP";
225 } else if (enablePolymerMolarWeight) {
226 incompatible_model = "Polymer injectivity";
227 }
228 OPM_THROW(std::runtime_error,
229 incompatible_model + " model is incompatible with the CPRW linear solver.\n"
230 "Choose a different option, for example --linear-solver=ilu0");
231 }
232 }
233
234 if (parameters_[0].linsolver_ == "hybrid") {
235 // Experimental hybrid configuration.
236 // When chosen, will set up two solvers, one with CPRW
237 // and the other with ILU0 preconditioner. More general
238 // options may be added later.
239 prm_.clear();
240 parameters_.clear();
241 {
243 para.init(false);
244 para.linsolver_ = "cprw";
245 parameters_.push_back(para);
247 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
248 Parameters::IsSet<Parameters::LinearSolverReduction>()));
249 }
250 {
252 para.init(false);
253 para.linsolver_ = "ilu0";
254 parameters_.push_back(para);
256 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
257 Parameters::IsSet<Parameters::LinearSolverReduction>()));
258 }
259 // ------------
260 } else {
261 assert(parameters_.size() == 1);
262 assert(prm_.empty());
263
264 // Do a normal linear solver setup.
265 if (parameters_[0].is_nldd_local_solver_) {
267 Parameters::IsSet<Parameters::NlddLocalLinearSolverMaxIter>(),
268 Parameters::IsSet<Parameters::NlddLocalLinearSolverReduction>()));
269 }
270 else {
272 Parameters::IsSet<Parameters::LinearSolverMaxIter>(),
273 Parameters::IsSet<Parameters::LinearSolverReduction>()));
274 }
275 }
276 flexibleSolver_.resize(prm_.size());
277
278 const bool on_io_rank = (simulator_.gridView().comm().rank() == 0);
279#if HAVE_MPI
280 comm_.reset( new CommunicationType( simulator_.vanguard().grid().comm() ) );
281#endif
282 extractParallelGridInformationToISTL(simulator_.vanguard().grid(), parallelInformation_);
283
284 // For some reason simulator_.model().elementMapper() is not initialized at this stage
285 //const auto& elemMapper = simulator_.model().elementMapper(); //does not work.
286 // Set it up manually
287 ElementMapper elemMapper(simulator_.vanguard().gridView(), Dune::mcmgElementLayout());
289 useWellConn_ = Parameters::Get<Parameters::MatrixAddWellContributions>();
290 const bool ownersFirst = Parameters::Get<Parameters::OwnerCellsFirst>();
291 if (!ownersFirst) {
292 const std::string msg = "The linear solver no longer supports --owner-cells-first=false.";
293 if (on_io_rank) {
294 OpmLog::error(msg);
295 }
296 OPM_THROW_NOLOG(std::runtime_error, msg);
297 }
298
299 const int interiorCellNum_ = detail::numMatrixRowsToUseInSolver(simulator_.vanguard().grid(), true);
300 for (auto& f : flexibleSolver_) {
301 f.interiorCellNum_ = interiorCellNum_;
302 }
303
304#if HAVE_MPI
305 if (isParallel()) {
306 const std::size_t size = simulator_.vanguard().grid().leafGridView().size(0);
308 }
309#endif
310
311 // Print parameters to PRT/DBG logs.
312 if (on_io_rank && parameters_[activeSolverNum_].linear_solver_print_json_definition_) {
313 std::ostringstream os;
314 os << "Property tree for linear solvers:\n";
315 for (std::size_t i = 0; i<prm_.size(); i++) {
316 prm_[i].write_json(os, true);
317 }
318 OpmLog::note(os.str());
319 }
320 }
321
322 // nothing to clean here
324 {
325 }
326
327 void setActiveSolver(const int num)
328 {
329 if (num > static_cast<int>(prm_.size()) - 1) {
330 OPM_THROW(std::logic_error, "Solver number " + std::to_string(num) + " not available.");
331 }
332 activeSolverNum_ = num;
333 if (simulator_.gridView().comm().rank() == 0) {
334 OpmLog::debug("Active solver = " + std::to_string(activeSolverNum_)
335 + " (" + parameters_[activeSolverNum_].linsolver_ + ")");
336 }
337 }
338
340 {
341 return flexibleSolver_.size();
342 }
343
344 void initPrepare(const Matrix& M, Vector& b)
345 {
346 const bool firstcall = (matrix_ == nullptr);
347
348 // update matrix entries for solvers.
349 if (firstcall) {
350 // model will not change the matrix object. Hence simply store a pointer
351 // to the original one with a deleter that does nothing.
352 // Outch! We need to be able to scale the linear system! Hence const_cast
353 matrix_ = const_cast<Matrix*>(&M);
354
355 useWellConn_ = Parameters::Get<Parameters::MatrixAddWellContributions>();
356 // setup sparsity pattern for jacobi matrix for preconditioner (only used for openclSolver)
357 } else {
358 // Pointers should not change
359 if ( &M != matrix_ ) {
360 OPM_THROW(std::logic_error,
361 "Matrix objects are expected to be reused when reassembling!");
362 }
363 }
364 rhs_ = &b;
365
366 // TODO: check all solvers, not just one.
367 if (isParallel() && prm_[activeSolverNum_].template get<std::string>("preconditioner.type") != "ParOverILU0") {
369 }
370 }
371
373 {
374 prepare(M.istlMatrix(), b);
375 }
376
377 void prepare(const Matrix& M, Vector& b)
378 {
379 OPM_TIMEBLOCK(istlSolverPrepare);
380
381 initPrepare(M,b);
382
384 }
385
386
387 void setResidual(Vector& /* b */)
388 {
389 // rhs_ = &b; // Must be handled in prepare() instead.
390 }
391
392 void getResidual(Vector& b) const
393 {
394 b = *rhs_;
395 }
396
397 void setMatrix(const SparseMatrixAdapter& /* M */)
398 {
399 // matrix_ = &M.istlMatrix(); // Must be handled in prepare() instead.
400 }
401
402 int getSolveCount() const {
403 return solveCount_;
404 }
405
407 solveCount_ = 0;
408 }
409
410 bool solve(Vector& x)
411 {
412 OPM_TIMEBLOCK(istlSolverSolve);
413 ++solveCount_;
414 // Write linear system if asked for.
415 const int verbosity = prm_[activeSolverNum_].get("verbosity", 0);
416 const bool write_matrix = verbosity > 10;
417 if (write_matrix) {
418 Helper::writeSystem(simulator_, //simulator is only used to get names
419 getMatrix(),
420 *rhs_,
421 comm_.get());
422 }
423
424 // Solve system.
426 {
427 OPM_TIMEBLOCK(flexibleSolverApply);
428 assert(flexibleSolver_[activeSolverNum_].solver_);
429 flexibleSolver_[activeSolverNum_].solver_->apply(x, *rhs_, result);
430 }
431
432 // Check convergence, iterations etc.
433 checkConvergence(result);
434
435 return converged_;
436 }
437
438
444
446 int iterations () const { return iterations_; }
447
449 const std::any& parallelInformation() const { return parallelInformation_; }
450
451 const CommunicationType* comm() const { return comm_.get(); }
452
453 protected:
454#if HAVE_MPI
455 using Comm = Dune::OwnerOverlapCopyCommunication<int, int>;
456#endif
457
459 {
460 // store number of iterations
461 iterations_ = result.iterations;
462 converged_ = result.converged;
463 if(!converged_){
464 if(result.reduction < parameters_[activeSolverNum_].relaxed_linear_solver_reduction_){
465 std::stringstream ss;
466 ss<< "Full linear solver tolerance not achieved. The reduction is:" << result.reduction
467 << " after " << result.iterations << " iterations ";
468 OpmLog::warning(ss.str());
469 converged_ = true;
470 }
471 }
472 // Check for failure of linear solver.
473 if (!parameters_[activeSolverNum_].ignoreConvergenceFailure_ && !converged_) {
474 const std::string msg("Convergence failure for linear solver.");
475 OPM_THROW_NOLOG(NumericalProblem, msg);
476 }
477 }
478 protected:
479
480 bool isParallel() const {
481#if HAVE_MPI
482 return !forceSerial_ && comm_->communicator().size() > 1;
483#else
484 return false;
485#endif
486 }
487
489 {
490 OPM_TIMEBLOCK(flexibleSolverPrepare);
491 if (shouldCreateSolver()) {
492 if (!useWellConn_) {
493 auto wellOp = std::make_unique<WellModelOperator>(simulator_.problem().wellModel());
494 flexibleSolver_[activeSolverNum_].wellOperator_ = std::move(wellOp);
495 }
496 std::function<Vector()> weightCalculator = this->getWeightsCalculator(prm_[activeSolverNum_], getMatrix(), pressureIndex);
497 OPM_TIMEBLOCK(flexibleSolverCreate);
499 isParallel(),
502 weightCalculator,
504 *comm_);
505 }
506 else
507 {
508 OPM_TIMEBLOCK(flexibleSolverUpdate);
509 flexibleSolver_[activeSolverNum_].pre_->update();
510 }
511 }
512
513
517 {
518 // Decide if we should recreate the solver or just do
519 // a minimal preconditioner update.
520 if (flexibleSolver_.empty()) {
521 return true;
522 }
523 if (!flexibleSolver_[activeSolverNum_].solver_) {
524 return true;
525 }
526
527 if (flexibleSolver_[activeSolverNum_].pre_->hasPerfectUpdate()) {
528 return false;
529 }
530
531 // For AMG based preconditioners, the hierarchy depends on the matrix values
532 // so it is recreated at certain intervals
533 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 0) {
534 // Always recreate solver.
535 return true;
536 }
537 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 1) {
538 // Recreate solver on the first iteration of every timestep.
539 const int newton_iteration = this->simulator_.model().newtonMethod().numIterations();
540 return newton_iteration == 0;
541 }
542 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 2) {
543 // Recreate solver if the last solve used more than 10 iterations.
544 return this->iterations() > 10;
545 }
546 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 3) {
547 // Never recreate the solver
548 return false;
549 }
550 if (this->parameters_[activeSolverNum_].cpr_reuse_setup_ == 4) {
551 // Recreate solver every 'step' solve calls.
552 const int step = this->parameters_[activeSolverNum_].cpr_reuse_interval_;
553 const bool create = ((solveCount_ % step) == 0);
554 return create;
555 }
556 // If here, we have an invalid parameter.
557 const bool on_io_rank = (simulator_.gridView().comm().rank() == 0);
558 std::string msg = "Invalid value: " + std::to_string(this->parameters_[activeSolverNum_].cpr_reuse_setup_)
559 + " for --cpr-reuse-setup parameter, run with --help to see allowed values.";
560 if (on_io_rank) {
561 OpmLog::error(msg);
562 }
563 throw std::runtime_error(msg);
564
565 return false;
566 }
567
568
569 // Weights to make approximate pressure equations.
570 // Calculated from the storage terms (only) of the
571 // conservation equations, ignoring all other terms.
572 std::function<Vector()> getWeightsCalculator(const PropertyTree& prm,
573 const Matrix& matrix,
574 std::size_t pressIndex) const
575 {
576 std::function<Vector()> weightsCalculator;
577
578 using namespace std::string_literals;
579
580 auto preconditionerType = prm.get("preconditioner.type"s, "cpr"s);
581 if (preconditionerType == "cpr" || preconditionerType == "cprt"
582 || preconditionerType == "cprw" || preconditionerType == "cprwt") {
583 const bool transpose = preconditionerType == "cprt" || preconditionerType == "cprwt";
584 const auto weightsType = prm.get("preconditioner.weight_type"s, "quasiimpes"s);
585 if (weightsType == "quasiimpes") {
586 // weights will be created as default in the solver
587 // assignment p = pressureIndex prevent compiler warning about
588 // capturing variable with non-automatic storage duration
589 weightsCalculator = [matrix, transpose, pressIndex]() {
590 return Amg::getQuasiImpesWeights<Matrix, Vector>(matrix,
591 pressIndex,
592 transpose);
593 };
594 } else if ( weightsType == "trueimpes" ) {
595 weightsCalculator =
596 [this, pressIndex]
597 {
598 Vector weights(rhs_->size());
599 ElementContext elemCtx(simulator_);
600 Amg::getTrueImpesWeights(pressIndex, weights,
601 simulator_.vanguard().gridView(),
602 elemCtx, simulator_.model(),
604 return weights;
605 };
606 } else if (weightsType == "trueimpesanalytic" ) {
607 weightsCalculator =
608 [this, pressIndex]
609 {
610 Vector weights(rhs_->size());
611 ElementContext elemCtx(simulator_);
612 Amg::getTrueImpesWeightsAnalytic(pressIndex, weights,
613 simulator_.vanguard().gridView(),
614 elemCtx, simulator_.model(),
616 return weights;
617 };
618 } else {
619 OPM_THROW(std::invalid_argument,
620 "Weights type " + weightsType +
621 "not implemented for cpr."
622 " Please use quasiimpes, trueimpes or trueimpesanalytic.");
623 }
624 }
625 return weightsCalculator;
626 }
627
628
630 {
631 return *matrix_;
632 }
633
634 const Matrix& getMatrix() const
635 {
636 return *matrix_;
637 }
638
640 mutable int iterations_;
641 mutable int solveCount_;
642 mutable bool converged_;
644
645 // non-const to be able to scale the linear system
648
650 std::vector<detail::FlexibleSolverInfo<Matrix,Vector,CommunicationType>> flexibleSolver_;
651 std::vector<int> overlapRows_;
652 std::vector<int> interiorRows_;
653
655
656 std::vector<FlowLinearSolverParameters> parameters_;
657 bool forceSerial_ = false;
658 std::vector<PropertyTree> prm_;
659
660 std::shared_ptr< CommunicationType > comm_;
661 }; // end ISTLSolver
662
663} // namespace Opm
664
665#endif // OPM_ISTLSOLVER_HEADER_INCLUDED
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: FlexibleSolver_impl.hpp:285
Interface class adding the update() method to the preconditioner interface.
Definition: PreconditionerWithUpdate.hpp:32
Definition: ISTLSolver.hpp:144
void initialize()
Definition: ISTLSolver.hpp:215
const Matrix & getMatrix() const
Definition: ISTLSolver.hpp:634
ISTLSolver(const Simulator &simulator, const FlowLinearSolverParameters &parameters, bool forceSerial=false)
Definition: ISTLSolver.hpp:188
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: ISTLSolver.hpp:147
std::shared_ptr< CommunicationType > comm_
Definition: ISTLSolver.hpp:660
static constexpr bool isIncompatibleWithCprw
Definition: ISTLSolver.hpp:165
void setActiveSolver(const int num)
Definition: ISTLSolver.hpp:327
std::vector< FlowLinearSolverParameters > parameters_
Definition: ISTLSolver.hpp:656
GetPropType< TypeTag, Properties::GridView > GridView
Definition: ISTLSolver.hpp:146
void setMatrix(const SparseMatrixAdapter &)
Definition: ISTLSolver.hpp:397
Dune::InverseOperator< Vector, Vector > AbstractSolverType
Definition: ISTLSolver.hpp:156
typename SparseMatrixAdapter::IstlMatrix Matrix
Definition: ISTLSolver.hpp:153
GetPropType< TypeTag, Properties::WellModel > WellModel
Definition: ISTLSolver.hpp:151
int solveCount_
Definition: ISTLSolver.hpp:641
Matrix & getMatrix()
Definition: ISTLSolver.hpp:629
GetPropType< TypeTag, Properties::SparseMatrixAdapter > SparseMatrixAdapter
Definition: ISTLSolver.hpp:148
Dune::OwnerOverlapCopyCommunication< int, int > CommunicationType
Definition: ISTLSolver.hpp:168
Matrix * matrix_
Definition: ISTLSolver.hpp:646
int iterations() const
Definition: ISTLSolver.hpp:446
void eraseMatrix()
Definition: ISTLSolver.hpp:323
bool useWellConn_
Definition: ISTLSolver.hpp:654
bool shouldCreateSolver() const
Definition: ISTLSolver.hpp:516
static constexpr std::size_t pressureIndex
Definition: ISTLSolver.hpp:161
void prepareFlexibleSolver()
Definition: ISTLSolver.hpp:488
GetPropType< TypeTag, Properties::ThreadManager > ThreadManager
Definition: ISTLSolver.hpp:154
GetPropType< TypeTag, Properties::ElementMapper > ElementMapper
Definition: ISTLSolver.hpp:160
int getSolveCount() const
Definition: ISTLSolver.hpp:402
void resetSolveCount()
Definition: ISTLSolver.hpp:406
GetPropType< TypeTag, Properties::GlobalEqVector > Vector
Definition: ISTLSolver.hpp:149
const std::any & parallelInformation() const
Definition: ISTLSolver.hpp:449
void initPrepare(const Matrix &M, Vector &b)
Definition: ISTLSolver.hpp:344
std::vector< detail::FlexibleSolverInfo< Matrix, Vector, CommunicationType > > flexibleSolver_
Definition: ISTLSolver.hpp:650
int numAvailableSolvers()
Definition: ISTLSolver.hpp:339
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AbstractOperatorType
Definition: ISTLSolver.hpp:157
@ enableMICP
Definition: ISTLSolver.hpp:163
std::function< Vector()> getWeightsCalculator(const PropertyTree &prm, const Matrix &matrix, std::size_t pressIndex) const
Definition: ISTLSolver.hpp:572
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AssembledLinearOperatorType
Definition: ISTLSolver.hpp:174
void checkConvergence(const Dune::InverseOperatorResult &result) const
Definition: ISTLSolver.hpp:458
ISTLSolver(const Simulator &simulator)
Definition: ISTLSolver.hpp:203
int iterations_
Definition: ISTLSolver.hpp:640
void prepare(const Matrix &M, Vector &b)
Definition: ISTLSolver.hpp:377
std::any parallelInformation_
Definition: ISTLSolver.hpp:643
GetPropType< TypeTag, Properties::Simulator > Simulator
Definition: ISTLSolver.hpp:152
Vector * rhs_
Definition: ISTLSolver.hpp:647
int activeSolverNum_
Definition: ISTLSolver.hpp:649
std::vector< int > overlapRows_
Definition: ISTLSolver.hpp:651
GetPropType< TypeTag, Properties::Indices > Indices
Definition: ISTLSolver.hpp:150
const Simulator & simulator_
Definition: ISTLSolver.hpp:639
void setResidual(Vector &)
Definition: ISTLSolver.hpp:387
bool converged_
Definition: ISTLSolver.hpp:642
const CommunicationType * comm() const
Definition: ISTLSolver.hpp:451
std::vector< int > interiorRows_
Definition: ISTLSolver.hpp:652
Dune::OwnerOverlapCopyCommunication< int, int > Comm
Definition: ISTLSolver.hpp:455
bool forceSerial_
Definition: ISTLSolver.hpp:657
void prepare(const SparseMatrixAdapter &M, Vector &b)
Definition: ISTLSolver.hpp:372
bool solve(Vector &x)
Definition: ISTLSolver.hpp:410
@ enablePolymerMolarWeight
Definition: ISTLSolver.hpp:164
void getResidual(Vector &b) const
Definition: ISTLSolver.hpp:392
static void registerParameters()
Definition: ISTLSolver.hpp:176
std::vector< PropertyTree > prm_
Definition: ISTLSolver.hpp:658
GetPropType< TypeTag, Properties::ElementContext > ElementContext
Definition: ISTLSolver.hpp:155
bool isParallel() const
Definition: ISTLSolver.hpp:480
A sparse matrix interface backend for BCRSMatrix from dune-istl.
Definition: istlsparsematrixadapter.hh:43
Definition: matrixblock.hh:227
Definition: PropertyTree.hpp:37
T get(const std::string &key) const
static unsigned threadId()
Return the index of the current OpenMP thread.
Definition: WellOperators.hpp:70
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 getTrueImpesWeightsAnalytic(int, Vector &weights, const GridView &gridView, ElementContext &elemCtx, const Model &model, std::size_t threadId)
Definition: getQuasiImpesWeights.hpp:137
void getTrueImpesWeights(int pressureVarIndex, Vector &weights, const GridView &gridView, ElementContext &elemCtx, const Model &model, std::size_t threadId)
Definition: getQuasiImpesWeights.hpp:91
void writeSystem(const SimulatorType &simulator, const MatrixType &matrix, const VectorType &rhs, const Communicator *comm)
Definition: WriteSystemMatrixHelper.hpp:34
Definition: blackoilmodel.hh:72
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
Definition: blackoilboundaryratevector.hh:37
Dune::InverseOperatorResult InverseOperatorResult
Definition: BdaBridge.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:235
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
PropertyTree setupPropertyTree(FlowLinearSolverParameters p, bool linearSolverMaxIterSet, bool linearSolverReductionSet)
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:95
void init(bool cprRequestedInDataFile)
std::string linsolver_
Definition: FlowLinearSolverParameters.hpp:110
typename Linear::IstlSparseMatrixAdapter< Block > type
Definition: ISTLSolver.hpp:82
The class that allows to manipulate sparse matrices.
Definition: linalgproperties.hh:50
Definition: ISTLSolver.hpp:63
std::tuple< FlowIstlSolverParams > InheritsFrom
Definition: ISTLSolver.hpp:64
Definition: FlowBaseProblemProperties.hpp:82
Definition: ISTLSolver.hpp:96
std::unique_ptr< AbstractSolverType > solver_
Definition: ISTLSolver.hpp:109
void create(const Matrix &matrix, bool parallel, const PropertyTree &prm, std::size_t pressureIndex, std::function< Vector()> weightCalculator, const bool forceSerial, Comm &comm)
std::size_t interiorCellNum_
Definition: ISTLSolver.hpp:113
Dune::InverseOperator< Vector, Vector > AbstractSolverType
Definition: ISTLSolver.hpp:97
AbstractPreconditionerType * pre_
Definition: ISTLSolver.hpp:112
Dune::AssembledLinearOperator< Matrix, Vector, Vector > AbstractOperatorType
Definition: ISTLSolver.hpp:98
std::unique_ptr< LinearOperatorExtra< Vector, Vector > > wellOperator_
Definition: ISTLSolver.hpp:111
std::unique_ptr< AbstractOperatorType > op_
Definition: ISTLSolver.hpp:110