KASKADE 7 development version
assemblerMatrixExtraction.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) 2024-2024 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 ASSEMBLERMATRIXEXTRACTION_HH
14#define ASSEMBLERMATRIXEXTRACTION_HH
15
16#include "dune/common/config.h"
17
18#include "linalg/triplet.hh"
19
21// forward declarations
22namespace Dune
23{
24 template <class Entry, class Allocator>
25 class BCRSMatrix;
26}
27
28namespace Kaskade
29{
30 template <class Entry, class Index>
31 class NumaBCRSMatrix;
32}
34
36{
45 template <class IdxOutIter, class DataOutIter>
46 struct BlockToTriplet
47 {
48 BlockToTriplet(size_t firstRowBlock_, size_t firstColumnBlock_, std::vector<size_t> const& rowOff_, std::vector<size_t> const& colOff_,
49 IdxOutIter& ri_, IdxOutIter& ci_, DataOutIter& xi_, bool onlyLowerTriangle_):
50 firstRowBlock(firstRowBlock_), firstColumnBlock(firstColumnBlock_), rowOff(rowOff_), colOff(colOff_),
51 ri(ri_), ci(ci_), xi(xi_), onlyLowerTriangle(onlyLowerTriangle_)
52 {}
53
54 template <class MatrixBlock>
55 void operator()(MatrixBlock const& mb) const
56 {
57 // Check if block is in requested range
58 if (inRange(mb.rowId,mb.colId))
60 rowOff[MatrixBlock::rowId-firstRowBlock],colOff[MatrixBlock::colId-firstColumnBlock],
61 mb.rowId==mb.colId && onlyLowerTriangle,
62 mb.symmetric);
63 // For mirror blocks, the transposed block needs to be written
64 // if the transposed block is in the requested
65 // range. Transposition is implicitly achieved by swapping
66 // column and row index output iterators.
67 if (MatrixBlock::mirror && inRange(mb.colId,mb.rowId) && onlyLowerTriangle==false)
69 colOff[MatrixBlock::rowId-firstColumnBlock],rowOff[MatrixBlock::colId-firstRowBlock],
70 false,
71 mb.symmetric);
72 }
73
74 bool inRange(size_t r, size_t c) const
75 {
76 return r>=firstRowBlock && r<firstRowBlock+rowOff.size() && c>=firstColumnBlock && c<firstColumnBlock+colOff.size();
77 }
78
79
80 size_t firstRowBlock, firstColumnBlock;
81 std::vector<size_t> const& rowOff;
82 std::vector<size_t> const& colOff;
83 IdxOutIter& ri;
84 IdxOutIter& ci;
85 DataOutIter& xi;
86 bool onlyLowerTriangle;
87 };
88
93 // ----------------------------------------------------------------------------------------------
94 // ----------------------------------------------------------------------------------------------
95
114 template <class Matrix> struct Fill;
115
116 // ----------------------------------------------------------------------------------------------
117 // ----------------------------------------------------------------------------------------------
118
124 template <class Scalar, class SparseIndexInt>
125 struct Fill<MatrixAsTriplet<Scalar,SparseIndexInt>>
126 {
128
129 template <class MatrixBlockArray>
130 static Matrix apply(MatrixBlockArray const& block,
131 size_t firstRowBlock, size_t firstColumnBlock,
132 std::vector<size_t> const& rowOff, std::vector<size_t> const& colOff,
133 bool extractOnlyLowerTriangle, size_t nnz, size_t, size_t)
134 {
135 Matrix result(nnz);
136
137 typename Matrix::index_iterator rowIterator = result.ridx.begin(),
138 columnIterator = result.cidx.begin();
139 typename Matrix::iterator dataIterator = result.data.begin();
140 for_each(block,BlockToTriplet<typename Matrix::index_iterator,
141 typename Matrix::iterator>(firstRowBlock,firstColumnBlock,
142 rowOff,colOff,
143 rowIterator,columnIterator,dataIterator, extractOnlyLowerTriangle));
144
145 return result;
146 }
147 };
148
149 // ----------------------------------------------------------------------------------------------
150 // ----------------------------------------------------------------------------------------------
151
157 template <class Scalar, class Allocator>
158 struct Fill<Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1>,Allocator> >
159 {
160 typedef Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1>,Allocator> Matrix;
161
162 template <class MatrixBlockArray>
163 static Matrix apply(MatrixBlockArray const& block, size_t firstRowBlock, size_t firstColumnBlock,
164 std::vector<size_t> const& rowOff, std::vector<size_t> const& colOff,
165 bool onlyLowerTriangle, size_t nnz, size_t nrows, size_t ncols)
166 {
167 // read as triplet
168 typedef MatrixAsTriplet<Scalar,size_t> Triplet;
169 Triplet triplet( Fill<Triplet>::apply(block, firstRowBlock, firstColumnBlock, rowOff, colOff, onlyLowerTriangle, nnz, nrows, ncols) );
170
171 // get column indices for each row
172 auto bcrsids = getBCRSIndicesFromTriplet(nrows, triplet.ridx, triplet.cidx);
173
174 Matrix result(nrows,ncols,nnz,Matrix::row_wise);
175 // create sparsity pattern
176 for (typename Matrix::CreateIterator row=result.createbegin(); row!=result.createend(); ++row)
177 for(size_t col = 0; col < bcrsids[row.index()].size(); ++col)
178 row.insert(bcrsids[row.index()][col]);
179
180 // fill matrix
181 for (size_t i=0; i<nnz; ++i)
182 result[triplet.ridx[i]][triplet.cidx[i]] = triplet.data[i];
183 return result;
184 }
185 };
186
187 // ----------------------------------------------------------------------------------------------
188 // ----------------------------------------------------------------------------------------------
189
195 template <class Scalar, class Index>
196 struct Fill<NumaBCRSMatrix<Dune::FieldMatrix<Scalar,1,1>,Index>>
197 {
199
200 template <class MatrixBlockArray>
201 static Matrix apply(MatrixBlockArray const& block, size_t firstRowBlock, size_t firstColumnBlock,
202 std::vector<size_t> const& rowOff, std::vector<size_t> const& colOff,
203 bool onlyLowerTriangle, size_t nnz, size_t nrows, size_t ncols)
204 {
205 // read as triplet
206 typedef MatrixAsTriplet<Scalar,size_t> Triplet;
207 Triplet triplet( Fill<Triplet>::apply(block, firstRowBlock, firstColumnBlock, rowOff, colOff, onlyLowerTriangle, nnz, nrows, ncols) );
208
209 // convert to Numa matrix
210 return Matrix(triplet,onlyLowerTriangle,false,onlyLowerTriangle);
211 }
212 };
213
214
215} // end of namespace AssemblyDetail
216
217#endif
std::vector< SparseIndexInt > ridx
row indices
Definition: triplet.hh:669
std::vector< SparseIndexInt > cidx
column indices
Definition: triplet.hh:671
std::vector< Scalar > data
data
Definition: triplet.hh:673
std::vector< SparseIndexInt >::iterator index_iterator
Definition: triplet.hh:63
std::vector< Scalar >::iterator iterator
Definition: triplet.hh:61
A NUMA-aware compressed row storage matrix adhering mostly to the Dune ISTL interface (to complete....
std::vector< std::vector< SparseInt > > getBCRSIndicesFromTriplet(SparseInt nrows, std::vector< SparseInt > const &ridx, std::vector< SparseInt > const &cidx, int nr=1, int nc=1)
Sorts the sparse matrix nonzero positions into row buckets.
Definition: crsutil.hh:456
static Matrix apply(MatrixBlockArray const &block, size_t firstRowBlock, size_t firstColumnBlock, std::vector< size_t > const &rowOff, std::vector< size_t > const &colOff, bool onlyLowerTriangle, size_t nnz, size_t nrows, size_t ncols)
static Matrix apply(MatrixBlockArray const &block, size_t firstRowBlock, size_t firstColumnBlock, std::vector< size_t > const &rowOff, std::vector< size_t > const &colOff, bool extractOnlyLowerTriangle, size_t nnz, size_t, size_t)
static Matrix apply(MatrixBlockArray const &block, size_t firstRowBlock, size_t firstColumnBlock, std::vector< size_t > const &rowOff, std::vector< size_t > const &colOff, bool onlyLowerTriangle, size_t nnz, size_t nrows, size_t ncols)
Specialize this template for your matrix type in order to use it with VariationalFunctionalAssembler:...
A class template that supports converting certain Dune matrices into the coordinate (triplet) format.
Definition: crsutil.hh:177