AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
BlockDiagonalPreconditioner.hpp
1#pragma once
2
3#include <memory>
4#include <string>
5#include <utility>
6#include <vector>
7
8#include <boost/numeric/mtl/utility/property_map.hpp>
9#include <boost/numeric/mtl/utility/range_wrapper.hpp>
10
11#include <amdis/CreatorInterface.hpp>
12#include <amdis/CreatorMap.hpp>
13#include <amdis/Initfile.hpp>
14#include <amdis/linearalgebra/mtl/BlockPreconditioner.hpp>
15#include <amdis/linearalgebra/mtl/MatrixBackend.hpp>
16#include <amdis/linearalgebra/mtl/VectorBackend.hpp>
17
18namespace AMDiS
19{
21 template <class M, class V, class Basis>
23 : public BlockPreconditioner<M, V, Basis>
24 {
27
28 using X = V;
29 using Y = V;
31
32 public:
34 struct Creator : CreatorInterfaceName<PreconBase>
35 {
36 using Interface = PreconBase;
37
38 Creator(std::shared_ptr<Basis> basis)
39 : basis_(std::move(basis))
40 {}
41
42 std::unique_ptr<Interface> createWithString(std::string prefix) override
43 {
44 return std::make_unique<Self>(std::move(prefix), basis_);
45 }
46
47 std::shared_ptr<Basis> basis_;
48 };
49
50 public:
52 BlockDiagonalPreconditioner(std::string prefix, std::shared_ptr<Basis> basis)
53 : Super(std::move(basis))
54 , prefix_(std::move(prefix))
55 {}
56
58 void init(M const& A) override
59 {
60 assert(rows() == cols());
61 Super::initBlocks(A, true);
62 initSubPrecons();
63 }
64
65 void initSubPrecons()
66 {
67 // create preconditioners for the diagonal blocks
68 subPrecon_.resize(rows());
69 for (std::size_t i = 0; i < subPrecon_.size(); ++i) {
70 std::string subPreconName = "default";
71 std::string subPreconPrefix = prefix_ + "->sub precon[" + std::to_string(i) + "]";
72 Parameters::get(subPreconPrefix, subPreconName);
73
74 auto* subCreator = CreatorMap<PreconBase>::get(subPreconName, subPreconPrefix);
75 subPrecon_[i] = named(subCreator)->createWithString(subPreconPrefix);
76 subPrecon_[i]->init(Super::subMatrix(i,i));
77 }
78 }
79
80 void finish() override
81 {
82 finishSubPrecons();
83 }
84
85 void finishSubPrecons()
86 {
87 for (std::size_t i = 0; i < subPrecon_.size(); ++i)
88 subPrecon_[i]->finish();
89 }
90
92
96 void solve(X const& x, Y& y) const override
97 {
98 y.checked_change_resource(x);
99
100 for (std::size_t i = 0; i < rows(); ++i)
101 {
102 X const x_i(Super::subVector(x, Super::rowIndices(i)));
103 Y y_i(resource(x_i));
104
105 subPrecon_[i]->solve(x_i, y_i);
106 Super::subVector(y, Super::colIndices(i)) = y_i;
107 }
108 }
109
111
115 void adjoint_solve(X const& x, Y& y) const override
116 {
117 y.checked_change_resource(x);
118
119 for (std::size_t i = 0; i < cols(); ++i)
120 {
121 X const x_i(Super::subVector(x, Super::colIndices(i)));
122 Y y_i(resource(x_i));
123
124 subPrecon_[i]->adjoint_solve(x_i, y_i);
125 Super::subVector(y, Super::rowIndices(i)) = y_i;
126 }
127 }
128
129 protected:
130 using Super::rows;
131 using Super::cols;
132
133 protected:
134 std::string prefix_;
135 std::vector<std::shared_ptr<PreconBase>> subPrecon_;
136 };
137
138
139 template <class T = double, class Basis>
140 void registerBlockDiagonalPreconditioner(std::shared_ptr<Basis> const& basis, std::string name = "block_diag")
141 {
142 using M = typename MTLSparseMatrix<T>::BaseMatrix;
143 using V = typename MTLVector<T>::BaseVector;
144 using Creator = typename BlockDiagonalPreconditioner<M, V, Basis>::Creator;
146 }
147
148} // end namespace AMDiS
Preconditioner that applies a precon for each diagonal block.
Definition BlockDiagonalPreconditioner.hpp:24
void init(M const &A) override
Extract the diagonal blocks of the fullMatrix into new matrices.
Definition BlockDiagonalPreconditioner.hpp:58
BlockDiagonalPreconditioner(std::string prefix, std::shared_ptr< Basis > basis)
Constructor.
Definition BlockDiagonalPreconditioner.hpp:52
void finish() override
Is called at the end of a solution procedure.
Definition BlockDiagonalPreconditioner.hpp:80
void adjoint_solve(X const &x, Y &y) const override
Apply the adjoint preconditioners block-wise.
Definition BlockDiagonalPreconditioner.hpp:115
void solve(X const &x, Y &y) const override
Apply the preconditioners block-wise.
Definition BlockDiagonalPreconditioner.hpp:96
Preconditioner for block-preconditioners using row/column sub-ranges.
Definition BlockPreconditioner.hpp:142
std::size_t rows() const
Return the number of row blocks.
Definition BlockPreconditioner.hpp:207
M const & subMatrix(std::size_t i, std::size_t j) const
Return the sub-matrix block (i,j)
Definition BlockPreconditioner.hpp:171
auto subVector(Vector &&vec, mtl::irange const &ir) const
Return a view on a sub-vector block for indices given in a range.
Definition BlockPreconditioner.hpp:186
std::size_t cols() const
Return the number of columns blocks.
Definition BlockPreconditioner.hpp:213
void initBlocks(M const &A, bool diagonalsOnly=false)
Fill block matrices from fullMatrix.
Definition BlockPreconditioner.hpp:162
Interface for creators with name.
Definition CreatorInterface.hpp:44
static CreatorInterface< BaseClass > * get(std::string key, std::string initFileStr)
Creates a object of the type corresponding to key.
Definition CreatorMap.hpp:44
static void addCreator(std::string key, CreatorInterface< BaseClass > *creator)
Adds a new creator together with the given key to the map.
Definition CreatorMap.hpp:36
static std::optional< T > get(std::string const &key)
Get parameter-values from parameter-tree.
Definition Initfile.hpp:31
mtl::compressed2D< T > BaseMatrix
The matrix type of the underlying base matrix.
Definition MatrixBackend.hpp:28
mtl::dense_vector< T > BaseVector
The type of the base vector.
Definition VectorBackend.hpp:25
Interface for Preconditioner y = M*x.
Definition PreconditionerInterface.hpp:10
A creator to be used instead of the constructor.
Definition BlockDiagonalPreconditioner.hpp:35
std::unique_ptr< Interface > createWithString(std::string prefix) override
Must be implemented by sub classes of CreatorInterfaceName. Creates a new instance of the sub class o...
Definition BlockDiagonalPreconditioner.hpp:42