opm-simulators
Loading...
Searching...
No Matches
ISTLSolverTPSA.hpp
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 Copyright 2025 NORCE AS
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 2 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 Consult the COPYING file in the top-level source directory of this
22 module for the precise wording of the license and the list of
23 copyright holders.
24*/
25#ifndef ISTL_SOLVER_TPSA_HPP
26#define ISTL_SOLVER_TPSA_HPP
27
28#include <dune/istl/owneroverlapcopy.hh>
29
30#include <opm/common/CriticalError.hpp>
31#include <opm/common/ErrorMacros.hpp>
32#include <opm/common/Exceptions.hpp>
33
34#include <opm/models/tpsa/tpsabaseproperties.hpp>
37
38#include <opm/simulators/linalg/AbstractISTLSolver.hpp>
39#include <opm/simulators/linalg/ExtractParallelGridInformationToISTL.hpp>
40#include <opm/simulators/linalg/ISTLSolver.hpp>
41#include <opm/simulators/linalg/PropertyTree.hpp>
42#include <opm/simulators/linalg/setupPropertyTree.hpp>
43#include <opm/simulators/linalg/TPSALinearSolverParameters.hpp>
44#include <opm/simulators/linalg/WriteSystemMatrixHelper.hpp>
45
46#include <algorithm>
47#include <any>
48#include <cctype>
49#include <memory>
50#include <stdexcept>
51#include <string>
52#include <utility>
53#include <vector>
54
55#include <fmt/format.h>
56
57
58namespace Opm {
59
65template <class TypeTag>
66class ISTLSolverTPSA : public AbstractISTLSolver<GetPropType<TypeTag, Properties::SparseMatrixAdapterTPSA>,
67 GetPropType<TypeTag, Properties::GlobalEqVectorTPSA>>
68{
73
74 using Matrix = typename SparseMatrixAdapter::IstlMatrix;
75
76
77#if HAVE_MPI
78 using CommunicationType = Dune::OwnerOverlapCopyCommunication<int,int>;
79#else
80 using CommunicationType = Dune::Communication<int>;
81#endif
82
83public:
89 ISTLSolverTPSA(const Simulator& simulator)
90 : simulator_(simulator)
91 , solveCount_(0)
92 , iterations_(0)
93 , matrix_(nullptr)
94 , rhs_(nullptr)
95 {
96 // Init parameters
97 parameters_.init();
98
99 // Initialize linear solver
100 initialize();
101 }
102
110
115 {
116 // Setup property tree for FlexibleSolver
117 prm_ = setupPropertyTree(parameters_, false, false, /*tpsaSetup=*/true);
118
119 // Reset comm_ pointer
120#if HAVE_MPI
121 comm_.reset( new CommunicationType( simulator_.vanguard().grid().comm() ) );
122#endif
123
124 // Extract and copy parallel grid information
125 extractParallelGridInformationToISTL(simulator_.vanguard().grid(), parallelInformation_);
126#if HAVE_MPI
127 if (isParallel()) {
128 const std::size_t size = simulator_.vanguard().grid().leafGridView().size(0);
129 detail::copyParValues(parallelInformation_, size, *comm_);
130 }
131#endif
132
133 // Get info on overlapping rows
134 ElementMapper elemMapper(simulator_.vanguard().gridView(), Dune::mcmgElementLayout());
135 std::vector<int> dummyInteriorRows;
136 detail::findOverlapAndInterior(simulator_.vanguard().grid(), elemMapper, overlapRows_, dummyInteriorRows);
137
138 // Set number of interior cells in FlexibleSolverInfo
139 flexibleSolver_.interiorCellNum_ = detail::numMatrixRowsToUseInSolver(simulator_.vanguard().grid(), true);
140
141 // Print parameters to PRT/DBG logs.
142 detail::printLinearSolverParameters(parameters_, prm_, simulator_.gridView().comm());
143 }
144
151 void initPrepare(const Matrix& M, Vector& b)
152 {
153 // Update matrix entries if it has not been initialized yet
154 const bool firstcall = (matrix_ == nullptr);
155 if (firstcall) {
156 // Model will not change the matrix object. Hence simply store a pointer to the original one with a deleter
157 // that does nothing.
158 // OBS: We need to be able to scale the linear system, hence const_cast
159 matrix_ = const_cast<Matrix*>(&M);
160 }
161 else {
162 // Pointers should not change; throw if the case
163 if (&M != matrix_) {
164 OPM_THROW(std::logic_error, "TPSA: Matrix objects are expected to be reused when reassembling!");
165 }
166
167 }
168
169 // Set right-hand side vector
170 rhs_ = &b;
171
172 // Zero out the overlapping cells in matrix (not in ilu0 case)
173 std::string type = prm_.template get<std::string>("preconditioner.type", "paroverilu0");
174 std::transform(type.begin(), type.end(), type.begin(), ::tolower);
175 if (isParallel() && type != "paroverilu0") {
176 detail::makeOverlapRowsInvalid(getMatrix(), overlapRows_);
177 }
178 }
179
183 void prepare(const Matrix& M, Vector& b) override
184 {
185 try {
186 initPrepare(M, b);
187
189 }
190 OPM_CATCH_AND_RETHROW_AS_CRITICAL_ERROR
191 ("TPSA: Failure likely due to a faulty linear solver JSON specification. "
192 "Check for errors related to missing nodes.");
193 }
194
198 void prepare(const SparseMatrixAdapter& M, Vector& b) override
199 {
200 prepare(M.istlMatrix(), b);
201 }
202
210 {
211 // Create solver or just update preconditioner
212 if (!flexibleSolver_.solver_) {
213 // Dummy weights calculator
214 // TODO: TPSA specific weights calculation for AMG preconditioner
215 std::function<Vector()> weightCalculator;
216
217 // Create FlexibleSolver
218 flexibleSolver_.create(getMatrix(),
219 isParallel(),
220 prm_,
221 /*pressureIndex=*/0,
222 weightCalculator,
223 /*forceSerial_=*/false,
224 comm_.get());
225 }
226 else {
227 // Update preconditioner
228 flexibleSolver_.pre_->update();
229 }
230 }
231
235 bool solve(Vector& x) override
236 {
237 // Increase solver count
238 ++solveCount_;
239
240 // Write system matrix if verbosity level is high
241 const int verbosity = prm_.get("verbosity", 0);
242 if (verbosity > 10) {
243 // simulator_ is only used to get names
244 Helper::writeSystem(simulator_,
245 getMatrix(),
246 *rhs_,
247 comm_.get());
248 }
249
250 // Solve linear system
251 Dune::InverseOperatorResult result;
252 assert(flexibleSolver_.solver_);
253 flexibleSolver_.solver_->apply(x, *rhs_, result);
254
255 // Store no. linear iterations
256 iterations_ = result.iterations;
257
258 // Return result for convergence check (boolean)
259 return checkConvergence(result);
260 }
261
266 {
267 solveCount_ = 0;
268 }
269
270 // ////
271 // Unused AbstractISTLSolver functions
272 // ////
276 void eraseMatrix() override
277 { }
278
282 void setActiveSolver(int /*num*/) override
283 { }
284
288 int numAvailableSolvers() const override
289 {
290 return 1;
291 }
292
296 void setResidual(Vector& /*b*/) override
297 { }
298
302 void setMatrix(const SparseMatrixAdapter& /*M*/) override
303 { }
304
305 // ///
306 // Public get functions
307 // ///
311 void getResidual(Vector& b) const override
312 {
313 b = *rhs_;
314 }
315
319 int getSolveCount() const override
320 {
321 return solveCount_;
322 }
323
327 int iterations() const override
328 {
329 return iterations_;
330 }
331
335 const CommunicationType* comm() const override
336 {
337 return comm_.get();
338 }
339
340protected:
348 bool isParallel() const
349 {
350#if HAVE_MPI
351 return comm_->communicator().size() > 1;
352#else
353 return false;
354#endif
355 }
356
363 bool checkConvergence(const Dune::InverseOperatorResult& result) const
364 {
366 }
367
368 // ///
369 // Protected get functions
370 // ///
376 Matrix& getMatrix()
377 {
378 if (!matrix_) {
379 OPM_THROW(std::runtime_error, "TPSA: System matrix \"M\" not defined!");
380 }
381 return *matrix_;
382 }
383
389 const Matrix& getMatrix() const
390 {
391 if (!matrix_) {
392 OPM_THROW(std::runtime_error, "TPSA: System matrix \"M\" not defined!");
393 }
394 return *matrix_;
395 }
396
397 const Simulator& simulator_;
398 std::any parallelInformation_;
399 int solveCount_;
400 int iterations_;
401
403 TpsaLinearSolverParameters parameters_;
404 PropertyTree prm_;
405
406 Matrix* matrix_;
407 Vector* rhs_;
408
409 std::shared_ptr<CommunicationType> comm_;
410 std::vector<int> overlapRows_;
411};
412
413} // namespace Opm
414
415#endif
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
const CommunicationType * comm() const override
Get the communication object used by the solver.
Definition ISTLSolverTPSA.hpp:335
static void registerParameters()
Register runtime/default parameters for linear solver.
Definition ISTLSolverTPSA.hpp:106
void setActiveSolver(int) override
Set the active solver by its index.
Definition ISTLSolverTPSA.hpp:282
void eraseMatrix() override
Signals that the memory for the matrix internally in the solver could be erased.
Definition ISTLSolverTPSA.hpp:276
void prepare(const SparseMatrixAdapter &M, Vector &b) override
Prepare the solver with the given matrix and right-hand side vector.
Definition ISTLSolverTPSA.hpp:198
void initialize()
Setup linear solver object based on runtime/default parameters.
Definition ISTLSolverTPSA.hpp:114
void initPrepare(const Matrix &M, Vector &b)
Prepare matix and rhs vector for linear solve.
Definition ISTLSolverTPSA.hpp:151
const Matrix & getMatrix() const
Get reference to system matrix object.
Definition ISTLSolverTPSA.hpp:389
int numAvailableSolvers() const override
Get the number of available solvers.
Definition ISTLSolverTPSA.hpp:288
int getSolveCount() const override
Get the count of how many times the solver has been called.
Definition ISTLSolverTPSA.hpp:319
ISTLSolverTPSA(const Simulator &simulator)
Constructor.
Definition ISTLSolverTPSA.hpp:89
void setResidual(Vector &) override
Set the residual vector.
Definition ISTLSolverTPSA.hpp:296
bool solve(Vector &x) override
Solve the system of equations Ax = b.
Definition ISTLSolverTPSA.hpp:235
void resetSolveCount()
Reset number of solver calls to zero.
Definition ISTLSolverTPSA.hpp:265
void getResidual(Vector &b) const override
Get the residual vector.
Definition ISTLSolverTPSA.hpp:311
void prepare(const Matrix &M, Vector &b) override
Prepare the solver with the given matrix and right-hand side vector.
Definition ISTLSolverTPSA.hpp:183
bool checkConvergence(const Dune::InverseOperatorResult &result) const
Check for linear solver convergence.
Definition ISTLSolverTPSA.hpp:363
void setMatrix(const SparseMatrixAdapter &) override
Set the matrix for the solver.
Definition ISTLSolverTPSA.hpp:302
Matrix & getMatrix()
Get reference to system matrix object.
Definition ISTLSolverTPSA.hpp:376
void prepareFlexibleSolver()
Prepare linear solver.
Definition ISTLSolverTPSA.hpp:209
bool isParallel() const
Check for parallel session.
Definition ISTLSolverTPSA.hpp:348
int iterations() const override
Get the number of iterations used in the last solve.
Definition ISTLSolverTPSA.hpp:327
Hierarchical collection of key/value pairs.
Definition PropertyTree.hpp:39
Manages the initializing and running of time dependent problems.
Definition simulator.hh:84
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:45
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
PropertyTree setupPropertyTree(FlowLinearSolverParameters p, bool linearSolverMaxIterSet, bool linearSolverReductionSet, bool tpsaSetup)
Set up a property tree intended for FlexibleSolver by either reading the tree from a JSON file or cre...
Definition setupPropertyTree.cpp:182
void extractParallelGridInformationToISTL(const Dune::CpGrid &, std::any &)
Extracts the information about the data decomposition from the grid for dune-istl.
Definition ExtractParallelGridInformationToISTL.cpp:46
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
Parametern for linear solver and preconditioner.
Definition TPSALinearSolverParameters.hpp:56
static void registerParameters()
Register TPSA linear solver runtime parameters.
Definition TPSALinearSolverParameters.cpp:59
Definition ISTLSolver.hpp:101