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_;
A helper classe that converts a Dune::MultiTypeBlockMatrix into a plain Dune::BCRSMatrix.
Trait checking if linear solvers accept Dune::MultiTypeBlockMatrix or we need to convert the matrix.
The infrastructure to retrieve run-time parameters from Dune::ParameterTrees.
Type traits to be used with vector types.
Manages the handling of time dependent problems.
Some exceptions thrown in DuMux
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.