AMDiS 2.11-git
The Adaptive Multi-Dimensional Simulation Toolbox
 
Loading...
Searching...
No Matches
BlockPreconditioner.hpp
1#pragma once
2
3#include <type_traits>
4#include <vector>
5
6#include <boost/numeric/mtl/utility/irange.hpp>
7#include <boost/numeric/mtl/utility/iset.hpp>
8#include <boost/numeric/mtl/utility/srange.hpp>
9#include <boost/numeric/mtl/vector/strided_vector_ref.hpp>
10
11#include <dune/functions/functionspacebases/basistags.hh>
12
13#include <amdis/functions/BlockedBasisMapping.hpp>
14#include <amdis/linearalgebra/mtl/BlockMatrix.hpp>
15#include <amdis/linearalgebra/mtl/PreconditionerInterface.hpp>
16
17namespace AMDiS
18{
19 namespace Impl
20 {
21 void initMtlIndexSet(std::vector<std::size_t> const& sizes, std::vector<mtl::irange>& indexSet)
22 {
23 indexSet.resize(sizes.size());
24 std::size_t start = 0;
25 for (std::size_t i = 0; i < sizes.size(); ++i) {
26 indexSet[i].set(start, start + sizes[i]);
27 start += sizes[i];
28 }
29 }
30
31 void initMtlIndexSet(std::vector<std::size_t> const& sizes, std::vector<mtl::srange>& indexSet)
32 {
33 // NOTE: Only for PowerPreBasis
34 std::size_t blocks = sizes.size();
35 std::size_t dimension = sizes[0];
36
37 // all blocks have the same size
38 std::for_each(sizes.begin(), sizes.end(), [&](std::size_t s) { assert(s == dimension); });
39
40 for (std::size_t i = 0; i < blocks; ++i)
41 indexSet.emplace_back(i, blocks*dimension, blocks);
42 }
43
44 void initMtlIndexSet(std::vector<std::size_t> const& sizes, std::vector<mtl::iset>& indexSet)
45 {
46 // NOTE: Only for PowerPreBasis
47 std::size_t blocks = sizes.size();
48 std::size_t dimension = sizes[0];
49
50 // all blocks have the same size
51 std::for_each(sizes.begin(), sizes.end(), [&](std::size_t s) { assert(s == dimension); });
52
53 indexSet.resize(blocks);
54 for (std::size_t i = 0; i < dimension; ++i) {
55 for (std::size_t b = 0; b < blocks; ++b)
56 indexSet[b].push_back(i*blocks + b);
57 }
58 }
59
60
61 using IMS_FlatLexicographic = Dune::Functions::BasisFactory::FlatLexicographic;
62 using IMS_FlatInterleaved = Dune::Functions::BasisFactory::FlatInterleaved;
63
64
65 template <class RowBasis, class ColBasis>
66 class BlockPreconditionerImpl
67 {
68 using RowIMS = typename RowBasis::PreBasis::IndexMergingStrategy;
69 using RowIndexSet = std::conditional_t<
70 std::is_same<RowIMS, IMS_FlatLexicographic>::value, mtl::irange, std::conditional_t<
71 std::is_same<RowIMS, IMS_FlatInterleaved>::value, mtl::srange, void>>;
72
73 using ColIMS = typename ColBasis::PreBasis::IndexMergingStrategy;
74 using ColIndexSet = std::conditional_t<
75 std::is_same<ColIMS, IMS_FlatLexicographic>::value, mtl::irange, std::conditional_t<
76 std::is_same<ColIMS, IMS_FlatInterleaved>::value, mtl::srange, void>>;
77
78 public:
79 // extract row and column ranges from block sizes
80 void initIndexSets(std::vector<std::size_t> const& rowSizes, std::vector<std::size_t> const& colSizes)
81 {
82 initMtlIndexSet(rowSizes, rowIndexSet_);
83 initMtlIndexSet(colSizes, colIndexSet_);
84 }
85
86 RowIndexSet const& rowIndices(std::size_t i) const
87 {
88 return rowIndexSet_[i];
89 }
90
91 ColIndexSet const& colIndices(std::size_t i) const
92 {
93 return colIndexSet_[i];
94 }
95
96 private:
97
98 std::vector<RowIndexSet> rowIndexSet_;
99 std::vector<ColIndexSet> colIndexSet_;
100 };
101
102
103 // specialization of row and col basis are the same
104 template <class Basis>
105 class BlockPreconditionerImpl<Basis, Basis>
106 {
107 using IMS = typename Basis::PreBasis::IndexMergingStrategy;
108 using IndexSet = std::conditional_t<
109 std::is_same<IMS, IMS_FlatLexicographic>::value, mtl::irange, std::conditional_t<
110 std::is_same<IMS, IMS_FlatInterleaved>::value, mtl::srange, void>>;
111
112 public:
113 // extract row and column ranges from block sizes
114 void initIndexSets(std::vector<std::size_t> const& rowSizes, std::vector<std::size_t> const& /*colSizes*/)
115 {
116 initMtlIndexSet(rowSizes, indexSet_);
117 }
118
119 IndexSet const& rowIndices(std::size_t i) const
120 {
121 return indexSet_[i];
122 }
123
124 IndexSet const& colIndices(std::size_t i) const
125 {
126 return indexSet_[i];
127 }
128
129 private:
130
131 std::vector<IndexSet> indexSet_;
132 };
133
134 } // end namespace Impl
135
136
138 template <class M, class V, class RowBasis, class ColBasis = RowBasis>
140 : public Impl::BlockPreconditionerImpl<RowBasis, ColBasis>
141 , public PreconditionerInterface<M,V,V>
142 {
143 public:
144
146 BlockPreconditioner(std::shared_ptr<RowBasis> rowBasis, std::shared_ptr<ColBasis> colBasis)
147 : blockMapping_(std::move(rowBasis), std::move(colBasis))
148 {}
149
151 BlockPreconditioner(std::shared_ptr<RowBasis> rowBasis)
152 : blockMapping_(std::move(rowBasis))
153 {}
154
156 void init(M const& A) override
157 {
158 initBlocks(A);
159 }
160
162 void initBlocks(M const& A, bool diagonalsOnly = false)
163 {
164 subMatrix_.copyFrom(A, blockMapping_, diagonalsOnly);
165 this->initIndexSets(subMatrix_.rowSizes_, subMatrix_.colSizes_);
166 }
167
168 public:
169
171 M const& subMatrix(std::size_t i, std::size_t j) const
172 {
173 return subMatrix_[i][j];
174 }
175
177 M& subMatrix(std::size_t i, std::size_t j)
178 {
179 return subMatrix_[i][j];
180 }
181
182 public:
183
185 template <class Vector>
186 auto subVector(Vector&& vec, mtl::irange const& ir) const
187 {
188 return mtl::vec::sub_vector(FWD(vec), ir.start(), ir.finish());
189 }
190
192 using StridedVector = mtl::vec::strided_vector_ref<typename V::value_type>;
193 StridedVector subVector(V& vec, mtl::srange const& sr) const
194 {
195 return StridedVector{sr.size()/sr.stride(), vec.address_data() + sr.start(), sr.stride()};
196 }
197
199 StridedVector const subVector(V const& vec, mtl::srange const& sr) const
200 {
201 return subVector(const_cast<V&>(vec), sr);
202 }
203
204 public:
205
207 std::size_t rows() const
208 {
209 return subMatrix_.rows();
210 }
211
213 std::size_t cols() const
214 {
215 return subMatrix_.cols();
216 }
217
218 protected:
220 BlockMatrix<M> subMatrix_;
221 };
222
223} // end namespace AMDiS
A block matrix supporting assignment from flat matrices.
Definition BlockMatrix.hpp:17
std::size_t rows() const
Return the number of row blocks.
Definition BlockMatrix.hpp:76
std::size_t cols() const
Return the number of columns blocks.
Definition BlockMatrix.hpp:88
Preconditioner for block-preconditioners using row/column sub-ranges.
Definition BlockPreconditioner.hpp:142
void init(M const &A) override
Initialize the preconditioner by initializing all sub precons.
Definition BlockPreconditioner.hpp:156
BlockPreconditioner(std::shared_ptr< RowBasis > rowBasis, std::shared_ptr< ColBasis > colBasis)
Constructor, constructs a block mapping for row and column basis.
Definition BlockPreconditioner.hpp:146
mtl::vec::strided_vector_ref< typename V::value_type > StridedVector
Return a view on a sub-vector block for indices given in a strided range.
Definition BlockPreconditioner.hpp:192
std::size_t rows() const
Return the number of row blocks.
Definition BlockPreconditioner.hpp:207
M & subMatrix(std::size_t i, std::size_t j)
Return the sub-matrix block (i,j)
Definition BlockPreconditioner.hpp:177
BlockPreconditioner(std::shared_ptr< RowBasis > rowBasis)
Constructor, constructs a block mapping for row and column basis.
Definition BlockPreconditioner.hpp:151
M const & subMatrix(std::size_t i, std::size_t j) const
Return the sub-matrix block (i,j)
Definition BlockPreconditioner.hpp:171
StridedVector const subVector(V const &vec, mtl::srange const &sr) const
Return a view on a sub-vector block for indices given in a strided range.
Definition BlockPreconditioner.hpp:199
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
Mapping of a pair of flat bases to the corresponding outer-level blocked bases.
Definition BlockedBasisMapping.hpp:17
Interface for Preconditioner y = M*x.
Definition PreconditionerInterface.hpp:10