KASKADE 7 development version
matrixBlocks.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) 2017-2017 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 MATRIX_BLOCKS_HH
14#define MATRIX_BLOCKS_HH
15
16#include <vector>
17#include <cassert>
18#include <sstream>
19#include <algorithm>
20
21#include <dune/istl/bvector.hh>
22#include <dune/istl/bcrsmatrix.hh>
23#include <dune/istl/matrixindexset.hh>
24
27
28namespace Kaskade
29{
33template <class Index>
35{
36public:
38
43 GlobalLocalIndexRelationship(std::vector<Index> const& localSizes) : offset_(localSizes.size()+1){
44 offset_[0] = 0;
45 for (Index i=0; i<localSizes.size(); ++i) {
46 assert(localSizes[i]>=0);
47 offset_[i+1] = offset_[i] + localSizes[i];
48 }
49 }
50
56 Index offset(Index block) const {
57 assert(block>=0 && block<numberBlocks());
58 return offset_[block];
59 }
60
67 Index globalIndex(Index block, Index localIndex) const {
68 return offset(block) + localIndex;
69 }
70
76 std::pair<Index, Index> localIndex(Index globalIndex) const {
77 std::pair<Index, Index> res = findOffset(globalIndex);
78 res.second = globalIndex - res.second;
79 return res;
80 }
81
87 std::pair<Index, Index> findOffset(Index globalIndex) const {
88 assert(globalIndex>=0);
89 Index block = 0;
90 for(; block<numberBlocks(); ++block) {
91 if(offset_[block+1] > globalIndex) break;
92 assert(block < numberBlocks()-1);
93 }
94 return std::make_pair(block, offset(block));
95 }
96
101 Index globalSize() const {
102 return offset_.back();
103 }
104
110 Index localSize(Index block) const {
111 return -offset(block) + offset_[block+1]; // this way assert in offset() is reused
112 }
113
118 Index numberBlocks() const {
119 return offset_.size()-1;
120 }
121
122private:
123 // contains the global start indices of the blocks, last entry is number of global indices
124 std::vector<Index> offset_ {0};
125};
126
130template <class Entry, class Index>
133// if(globalMatrix.N() < startRow+matrixBlock.N()) {
134// std::ostringstream message;
135// message << "Block (" << matrixBlock.N() << " rows and starting at row " << startRow << ") does not fit in global matrix (" << globalMatrix.N() << " rows). ";
136// throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
137// }
138 if(globalCreator.cols() < startCol+matrixBlock.M()) {
139 std::ostringstream message;
140 message << "Block (" << matrixBlock.M() << " columns and starting at column " << startCol << ") does not fit in global matrix (creator) (" << globalCreator.cols() << " columns). ";
141 throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
142 }
143 if(matrixBlock.getPattern()->isSymmetric() && (startCol != startRow)) {
144 throw LinearAlgebraException("Symmetric stored blocks can only be inserted on diagonal.",__FILE__,__LINE__);
145 }
146 if(matrixBlock.getPattern()->isSymmetric() && !globalCreator.isSymmetric()) {
147 throw LinearAlgebraException("Symmetric stored blocks can only be inserted into symmetric stored Matrices.",__FILE__,__LINE__);
148 }
149 for(Index i=0; i<matrixBlock.N(); ++i) {
150 auto const& rowMb = matrixBlock[i];
151 std::vector<Index> colIdxs(rowMb.size());
152 std::transform(rowMb.getindexptr(), rowMb.getindexptr()+rowMb.size(), colIdxs.begin(), [&](Index const& colIdx) {
153 return startCol+colIdx;
154 });
155 Index rowIdx = startRow+i;
156 globalCreator.addElements(&rowIdx, (&rowIdx)+1, colIdxs.begin(), colIdxs.end());
157 }
158}
159
163template <class Entry>
164void insertMatrixBlockIndices(Dune::MatrixIndexSet & globalIndexSet, Dune::BCRSMatrix<Entry> const& matrixBlock, Dune::MatrixIndexSet::size_type startRow, Dune::MatrixIndexSet::size_type startCol) {
165 if(globalIndexSet.rows() < startRow+matrixBlock.N()) {
166 std::ostringstream message;
167 message << "Block (" << matrixBlock.N() << " rows and starting at row " << startRow << ") does not fit in global matrix (index set)(" << globalIndexSet.rows() << " rows). ";
168 throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
169 }
170// if(globalIndexSet.cols() < startCol+matrixBlock.M()) {
171// std::ostringstream message;
172// message << "Block (" << matrixBlock.M() << " columns and starting at column " << startCol << ") does not fit in global matrix (creator) (" << globalCreator.cols() << " columns). ";
173// throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
174// }
175 globalIndexSet.import(matrixBlock, startRow, startCol);
176}
177
181template <class BMatrix>
182void insertMatrixBlockEntries(BMatrix & globalMatrix, BMatrix const& matrixBlock, typename BMatrix::size_type startRow, typename BMatrix::size_type startCol) {
183 if(globalMatrix.N() < startRow+matrixBlock.N()) {
184 std::ostringstream message;
185 message << "Block (" << matrixBlock.N() << " rows and starting at row " << startRow << ") does not fit in global matrix (" << globalMatrix.N() << " rows). ";
186 throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
187 }
188 if(globalMatrix.M() < startCol+matrixBlock.M()) {
189 std::ostringstream message;
190 message << "Block (" << matrixBlock.M() << " columns and starting at column " << startCol << ") does not fit in global matrix (" << globalMatrix.M() << " columns). ";
191 throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
192 }
193 for(typename BMatrix::size_type i=0; i<matrixBlock.N(); ++i) {
194 auto const& rowMb = matrixBlock[i];
195 if(rowMb.size() > 0) std::copy(rowMb.getptr(), rowMb.getptr()+rowMb.size(), &(globalMatrix[startRow+i][startCol+rowMb.begin().index()]));
196 }
197}
198
202template <class BVector>
203void insertVectorBlock(BVector & globalVector, BVector const& vectorBlock, typename BVector::size_type startIdx) {
204 if(globalVector.N() < startIdx+vectorBlock.N()) {
205 std::ostringstream message;
206 message << "Block (of size " << vectorBlock.N() << " and starting at index " << startIdx << ") does not fit in global vector (of size " << globalVector.N() << "). ";
207 throw LinearAlgebraException(message.str(),__FILE__,__LINE__);
208 }
209 for(typename BVector::size_type i=0; i<vectorBlock.N(); ++i) {
210 globalVector[startIdx+i] = vectorBlock[i];
211 }
212}
213}
214
215#endif
The GlobalLocalIndexRelationship class provides relationships between local indices of (e....
Definition: matrixBlocks.hh:35
std::pair< Index, Index > findOffset(Index globalIndex) const
findOffset
Definition: matrixBlocks.hh:87
Index globalIndex(Index block, Index localIndex) const
globalIndex
Definition: matrixBlocks.hh:67
Index localSize(Index block) const
localSize
Index numberBlocks() const
numberBlocks
Index globalSize() const
globalSize
GlobalLocalIndexRelationship(std::vector< Index > const &localSizes)
GlobalLocalIndexRelationship.
Definition: matrixBlocks.hh:43
std::pair< Index, Index > localIndex(Index globalIndex) const
localIndex
Definition: matrixBlocks.hh:76
Index offset(Index block) const
offset
Definition: matrixBlocks.hh:56
A base class for linear algebra exceptions.
std::shared_ptr< NumaCRSPattern< Index > > getPattern() const
Returns a pointer to the sparsity pattern.
Index M() const
The number of columns.
Index N() const
The number of rows.
A NUMA-aware creator for matrix sparsity patterns.
Index cols() const
The number of columns.
void addElements(IterRow const fromRow, IterRow const toRow, IterCol const fromCol, IterCol const toCol, bool colIsSorted=false)
Enters entries into the sparsity pattern.
bool isSymmetric() const
Returns the symmetry status of the pattern.
void insertMatrixBlockIndices(NumaCRSPatternCreator< Index > &globalCreator, NumaBCRSMatrix< Entry, Index > const &matrixBlock, typename NumaBCRSMatrix< Entry, Index >::size_type startRow, typename NumaBCRSMatrix< Entry, Index >::size_type startCol)
void insertVectorBlock(BVector &globalVector, BVector const &vectorBlock, typename BVector::size_type startIdx)
void insertMatrixBlockEntries(BMatrix &globalMatrix, BMatrix const &matrixBlock, typename BMatrix::size_type startRow, typename BMatrix::size_type startCol)