KASKADE 7 development version
multigrid.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2015-2016 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef MG_MULTIGRID_HH
14#define MG_MULTIGRID_HH
15
16#include <memory>
17#include <type_traits>
18
19#include "fem/spaces.hh"
22#include "utilities/memory.hh"
23
24namespace Kaskade
25{
26
39 template <class Entry, class Index, class Space>
40 auto makeMultigrid(NumaBCRSMatrix<Entry,Index> const& A, Space const& space, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
41 {
42 using Matrix = NumaBCRSMatrix<Entry,Index>;
44
45 static_assert(Space::continuity >= 0,"makeMultigrid assumes global continuity of finite element functions");
46
47 // TODO: Consider using cheaper additive multigrid for elastomechanics problems (the difference in contraction rates
48 // appears to be smaller for elastomechanics, and hence the cheaper application pays off).
49
50 // Choose number of pre- and post-smoothings depending on the number of components. Scalar (Laplace) problems tend to
51 // have a better contraction, and hence more smoother iterations pay off compared to, say, elastomechanics. In any case
52 // we use the same number of pre- and post-smoothings.
53 int const nSmooth = Entry::rows > 1? 2: 3;
54
55 int const order = space.mapper().maxOrder();
56 if (order == 1) // these are (assumed to be) P1 elements
57 return std::unique_ptr<Preconditioner>(moveUnique(makeJacobiMultiGrid(A,space.gridManager(),nSmooth,nSmooth,onlyLowerTriangle,directType)));
58
59 if (order == 2) // P2 elements. For those, a Jacobi smoother is cheaper than and almost as efficient as a patch smoother.
60 {
61 auto mg = makeJacobiPMultiGrid(A,space,nSmooth,nSmooth,onlyLowerTriangle,directType);
62 mg.setSmoothings(3,3);
63 return std::unique_ptr<Preconditioner>(moveUnique(std::move(mg)));
64 }
65
66 // Higher order elements. Here, a patch smoother is much more efficient than a Jacobi smoother
67 // (at least from order 4 on, order 3 is probably break even).
68 // The patch smoother is quite effective, but rather expensive. Hence we use a smaller number of
69 // smoothing iterations than for the Jacobi smoother in the h-multigrid part below.
70 auto mg = makeBlockJacobiPMultiGrid(A,space,nSmooth,nSmooth,onlyLowerTriangle,directType);
71 mg.setSmoothings(3,3);
72 return std::unique_ptr<Preconditioner>(moveUnique(std::move(mg)));
73 }
74
75 // ---------------------------------------------------------------------------------------------------------
76
77
78}
79
80#endif
Interface for symmetric preconditioners.
DirectType
Available direct solvers for linear equation systems.
Definition: enums.hh:35
@ MUMPS
MUMPS sparse solver.
auto makeMultigrid(NumaBCRSMatrix< Entry, Index > const &A, Space const &space, bool onlyLowerTriangle=false, DirectType directType=DirectType::MUMPS)
Convenience function for creating a (multiplicative) multigrid preconditioner for elliptic equations.
Definition: multigrid.hh:40
auto moveUnique(A &&a)
Creates a dynamically allocated object from an r-value reference.
Definition: memory.hh:33
Convenience typedefs and creation functions for common function spaces.
void NaturalRange
The natural range type.
Definition: matrixTraits.hh:58