24#ifndef DUMUX_LINEAR_PDE_SOLVER_HH
25#define DUMUX_LINEAR_PDE_SOLVER_HH
32#include <dune/common/timer.hh>
33#include <dune/common/exceptions.hh>
34#include <dune/common/parallel/mpicollectivecommunication.hh>
35#include <dune/common/parallel/mpihelper.hh>
36#include <dune/common/std/type_traits.hh>
37#include <dune/istl/bvector.hh>
38#include <dune/istl/multitypeblockvector.hh>
60template <
class Assembler,
class LinearSolver>
64 using Scalar =
typename Assembler::Scalar;
65 using JacobianMatrix =
typename Assembler::JacobianMatrix;
66 using SolutionVector =
typename Assembler::ResidualType;
88 void solve(SolutionVector& uCurrentIter)
override
90 Dune::Timer assembleTimer(
false);
91 Dune::Timer solveTimer(
false);
92 Dune::Timer updateTimer(
false);
95 std::cout <<
"Assemble: r(x^k) = dS/dt + div F - q; M = grad r"
104 assembleTimer.start();
105 this->
assembler().assembleJacobianAndResidual(uCurrentIter);
106 assembleTimer.stop();
115 const char clearRemainingLine[] = { 0x1b,
'[',
'K', 0 };
118 std::cout <<
"\rSolve: M deltax^k = r";
119 std::cout << clearRemainingLine
127 SolutionVector deltaU(uCurrentIter);
132 bool converged = solveLinearSystem_(deltaU);
142 std::cout <<
"\rUpdate: x^(k+1) = x^k - deltax^k";
143 std::cout << clearRemainingLine;
149 uCurrentIter -= deltaU;
150 this->
assembler().updateGridVariables(uCurrentIter);
154 const auto elapsedTot = assembleTimer.elapsed() + solveTimer.elapsed() + updateTimer.elapsed();
155 std::cout <<
"Assemble/solve/update time: "
156 << assembleTimer.elapsed() <<
"(" << 100*assembleTimer.elapsed()/elapsedTot <<
"%)/"
157 << solveTimer.elapsed() <<
"(" << 100*solveTimer.elapsed()/elapsedTot <<
"%)/"
158 << updateTimer.elapsed() <<
"(" << 100*updateTimer.elapsed()/elapsedTot <<
"%)"
167 void report(std::ostream& sout = std::cout)
const
189 {
return verbose_ ; }
195 {
return paramGroup_; }
199 virtual bool solveLinearSystem_(SolutionVector& deltaU)
216 template<
class V = SolutionVector>
217 typename std::enable_if_t<!isMultiTypeBlockVector<V>(),
bool>
218 solveLinearSystemImpl_(LinearSolver& ls,
229 constexpr auto blockSize = JacobianMatrix::block_type::rows;
230 using BlockType = Dune::FieldVector<Scalar, blockSize>;
231 Dune::BlockVector<BlockType> xTmp; xTmp.resize(b.size());
232 Dune::BlockVector<BlockType> bTmp(xTmp);
233 for (
unsigned int i = 0; i < b.size(); ++i)
234 for (
unsigned int j = 0; j < blockSize; ++j)
235 bTmp[i][j] = b[i][j];
237 const int converged = ls.solve(A, xTmp, bTmp);
239 for (
unsigned int i = 0; i < x.size(); ++i)
240 for (
unsigned int j = 0; j < blockSize; ++j)
241 x[i][j] = xTmp[i][j];
257 template<
class LS = LinearSolver,
class V = SolutionVector>
258 typename std::enable_if_t<linearSolverAcceptsMultiTypeMatrix<LS>() &&
259 isMultiTypeBlockVector<V>(),
bool>
260 solveLinearSystemImpl_(LinearSolver& ls,
266 assert(checkMatrix_(A) &&
"Sub blocks of MultiType matrix have wrong sizes!");
269 return ls.template
solve<2>(A, x, b);
282 template<
class LS = LinearSolver,
class V = SolutionVector>
283 typename std::enable_if_t<!linearSolverAcceptsMultiTypeMatrix<LS>() &&
284 isMultiTypeBlockVector<V>(),
bool>
285 solveLinearSystemImpl_(LinearSolver& ls,
291 assert(checkMatrix_(A) &&
"Sub blocks of MultiType matrix have wrong sizes!");
297 const std::size_t numRows = M.N();
298 assert(numRows == M.M());
302 assert(bTmp.size() == numRows);
305 using VectorBlock =
typename Dune::FieldVector<Scalar, 1>;
306 using BlockVector =
typename Dune::BlockVector<VectorBlock>;
307 BlockVector y(numRows);
310 const bool converged = ls.solve(M, y, bTmp);
320 template<
class M = JacobianMatrix>
321 typename std::enable_if_t<!isBCRSMatrix<M>(),
bool>
322 checkMatrix_(
const JacobianMatrix& A)
324 bool matrixHasCorrectSize =
true;
325 using namespace Dune::Hybrid;
327 forEach(A, [&matrixHasCorrectSize](
const auto& rowOfMultiTypeMatrix)
329 const auto numRowsLeftMostBlock = rowOfMultiTypeMatrix[_0].N();
331 forEach(rowOfMultiTypeMatrix, [&matrixHasCorrectSize, &numRowsLeftMostBlock](
const auto& subBlock)
333 if (subBlock.N() != numRowsLeftMostBlock)
334 matrixHasCorrectSize =
false;
337 return matrixHasCorrectSize;
341 void initParams_(
const std::string& group =
"")
343 verbose_ = (Dune::MPIHelper::getCollectiveCommunication().rank() == 0);
350 std::string paramGroup_;
Type traits to be used with vector types.
Some exceptions thrown in DuMux
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Manages the handling of time dependent problems.
Trait checking if linear solvers accept Dune::MultiTypeBlockMatrix or we need to convert the matrix.
A helper classe that converts a Dune::MultiTypeBlockMatrix into a plain Dune::BCRSMatrix.
make the local view function available whenever we use the grid geometry
Definition: adapt.hh:29
Property tag Indices
Definition: porousmediumflow/sequential/properties.hh:59
Exception thrown if a fixable numerical problem occurs.
Definition: exceptions.hh:39
A high-level interface for a PDESolver.
Definition: common/pdesolver.hh:46
const Assembler & assembler() const
Access the assembler.
Definition: common/pdesolver.hh:83
const LinearSolver & linearSolver() const
Access the linear solver.
Definition: common/pdesolver.hh:95
Manages the handling of time dependent problems.
Definition: timeloop.hh:65
static auto multiTypeToBCRSMatrix(const MultiTypeBlockMatrix &A)
Converts the matrix to a type the IterativeSolverBackend can handle.
Definition: matrixconverter.hh:59
static void retrieveValues(MultiTypeBlockVector &x, const BlockVector &y)
Copys the entries of a Dune::BlockVector to a Dune::MultiTypeBlockVector.
Definition: matrixconverter.hh:242
static auto multiTypeToBlockVector(const MultiTypeBlockVector &b)
Converts a Dune::MultiTypeBlockVector to a plain 1x1 Dune::BlockVector.
Definition: matrixconverter.hh:214
An implementation of a linear PDE solver.
Definition: linear/pdesolver.hh:62
const std::string & paramGroup() const
Returns the parameter group.
Definition: linear/pdesolver.hh:194
void setVerbose(bool val)
Specifies if the solver ought to be chatty.
Definition: linear/pdesolver.hh:182
LinearPDESolver(std::shared_ptr< Assembler > assembler, std::shared_ptr< LinearSolver > linearSolver, const std::string ¶mGroup="")
The Constructor.
Definition: linear/pdesolver.hh:73
void solve(SolutionVector &uCurrentIter) override
Solve a linear PDE system.
Definition: linear/pdesolver.hh:88
void report(std::ostream &sout=std::cout) const
output statistics / report
Definition: linear/pdesolver.hh:167
Scalar suggestTimeStepSize(Scalar oldTimeStep) const
Suggest a new time-step size based on the old time-step size.
Definition: linear/pdesolver.hh:174
bool verbose() const
Returns true if the solver ought to be chatty.
Definition: linear/pdesolver.hh:188
Defines a high-level interface for a PDESolver.