dune-istl 2.12-git
Loading...
Searching...
No Matches
matrixutils.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
4// vi: set et ts=4 sw=2 sts=2:
5#ifndef DUNE_ISTL_MATRIXUTILS_HH
6#define DUNE_ISTL_MATRIXUTILS_HH
7
8#include <set>
9#include <vector>
10#include <limits>
17#include "istlexception.hh"
18
19namespace Dune
20{
21
22#ifndef DOYXGEN
23 template<typename B, typename A>
24 class BCRSMatrix;
25
26
27 template<typename K, int n, int m>
28 class FieldMatrix;
29
30 template<class T, class A>
31 class Matrix;
32
33namespace Experimental {
34 template<typename B, typename I, typename A>
35 class BCRSMatrix;
36
37 template <typename B, typename P, typename A>
38 class Matrix;
39}
40
41#endif
42
56 template<class Matrix, std::size_t blocklevel, std::size_t l=blocklevel>
58 {
63 static void check([[maybe_unused]] const Matrix& mat)
64 {
65#ifdef DUNE_ISTL_WITH_CHECKING
66 typedef typename Matrix::ConstRowIterator Row;
67 typedef typename Matrix::ConstColIterator Entry;
68 for(Row row = mat.begin(); row!=mat.end(); ++row) {
69 Entry diagonal = row->find(row.index());
70 if(diagonal==row->end())
71 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
72 <<" at block recursion level "<<l-blocklevel);
73 else{
74 auto m = Impl::asMatrix(*diagonal);
75 CheckIfDiagonalPresent<decltype(m),blocklevel-1,l>::check(m);
76 }
77 }
78#endif
79 }
80 };
81
82 template<class Matrix, std::size_t l>
84 {
85 static void check(const Matrix& mat)
86 {
87 typedef typename Matrix::ConstRowIterator Row;
88 for(Row row = mat.begin(); row!=mat.end(); ++row) {
89 if(row->find(row.index())==row->end())
90 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
91 <<" at block recursion level "<<l);
92 }
93 }
94 };
95
96 template<typename FirstRow, typename... Args>
97 class MultiTypeBlockMatrix;
98
99 template<std::size_t blocklevel, std::size_t l, typename T1, typename... Args>
101 blocklevel,l>
102 {
103 typedef MultiTypeBlockMatrix<T1,Args...> Matrix;
104
109 static void check(const Matrix& /* mat */)
110 {
111#ifdef DUNE_ISTL_WITH_CHECKING
112 // TODO Implement check
113#endif
114 }
115 };
116
128 template<class M>
129 inline auto countNonZeros(const M&,
130 [[maybe_unused]] typename std::enable_if_t<Dune::IsNumber<M>::value>* sfinae = nullptr)
131 {
132 return 1;
133 }
134
135 template<class M>
136 inline auto countNonZeros(const M& matrix,
137 [[maybe_unused]] typename std::enable_if_t<!Dune::IsNumber<M>::value>* sfinae = nullptr)
138 {
139 typename M::size_type nonZeros = 0;
140 for(auto&& row : matrix)
141 for(auto&& entry : row)
142 nonZeros += countNonZeros(entry);
143 return nonZeros;
144 }
145
146 /*
147 template<class M>
148 struct ProcessOnFieldsOfMatrix
149 */
150
152 namespace
153 {
154 struct CompPair {
155 template<class G,class M>
156 bool operator()(const std::pair<G,M>& p1, const std::pair<G,M>& p2) const
157 {
158 return p1.first<p2.first;
159 }
160 };
161
162 }
163 template<class M, class C>
164 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)
165 {
166 typedef typename C::ParallelIndexSet::const_iterator IIter;
167 typedef typename C::OwnerSet OwnerSet;
168 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;
169
170 GlobalIndex gmax=0;
171
172 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
173 idx!=eidx; ++idx)
174 gmax=std::max(gmax,idx->global());
175
176 gmax=ooc.communicator().max(gmax);
177 ooc.buildGlobalLookup();
178
179 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
180 idx!=eidx; ++idx) {
181 if(OwnerSet::contains(idx->local().attribute()))
182 {
183 typedef typename M::block_type Block;
184
186
187 // sort rows
188 typedef typename M::ConstColIterator CIter;
189 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();
190 c!=cend; ++c) {
191 const typename C::ParallelIndexSet::IndexPair* pair
192 =ooc.globalLookup().pair(c.index());
193 assert(pair);
194 entries.insert(std::make_pair(pair->global(), *c));
195 }
196
197 //wait until its the rows turn.
198 GlobalIndex rowidx = idx->global();
200 while(cur!=rowidx)
201 cur=ooc.communicator().min(rowidx);
202
203 // print rows
204 typedef typename std::set<std::pair<GlobalIndex,Block>,CompPair>::iterator SIter;
205 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)
206 os<<idx->global()<<" "<<s->first<<" "<<s->second<<std::endl;
207
208
209 }
210 }
211
212 ooc.freeGlobalLookup();
213 // Wait until everybody is finished
215 while(cur!=ooc.communicator().min(cur)) ;
216 }
217
218 // Default implementation for scalar types
219 template<typename M>
221 {
222 static_assert(IsNumber<M>::value, "MatrixDimension is not implemented for this type!");
223
224 static auto rowdim(const M& /*A*/)
225 {
226 return 1;
227 }
228
229 static auto coldim(const M& /*A*/)
230 {
231 return 1;
232 }
233 };
234
235 // Default implementation for scalar types
236 template<typename B, typename TA>
237 struct MatrixDimension<Matrix<B,TA> >
238 {
241
243 {
245 }
246
248 {
250 }
251
252 static size_type rowdim (const Matrix<B,TA>& A)
253 {
254 size_type nn=0;
255 for (size_type i=0; i<A.N(); i++)
256 nn += rowdim(A,i);
257 return nn;
258 }
259
260 static size_type coldim (const Matrix<B,TA>& A)
261 {
262 size_type nn=0;
263 for (size_type i=0; i<A.M(); i++)
264 nn += coldim(A,i);
265 return nn;
266 }
267 };
268
269
270 template<typename B, typename TA>
272 {
275 typedef typename Matrix::size_type size_type;
276
277 static size_type rowdim (const Matrix& A, size_type i)
278 {
279 const B* row = A.r[i].getptr();
280 if(row)
282 else
283 return 0;
284 }
285
286 static size_type coldim (const Matrix& A, size_type c)
287 {
288 // find an entry in column c
289 if (A.nnz_ > 0)
290 {
291 for (size_type k=0; k<A.nnz_; k++) {
292 if (A.j_.get()[k] == c) {
294 }
295 }
296 }
297 else
298 {
299 for (size_type i=0; i<A.N(); i++)
300 {
301 size_type* j = A.r[i].getindexptr();
302 B* a = A.r[i].getptr();
303 for (size_type k=0; k<A.r[i].getsize(); k++)
304 if (j[k]==c) {
306 }
307 }
308 }
309
310 // not found
311 return 0;
312 }
313
314 static size_type rowdim (const Matrix& A){
315 size_type nn=0;
316 for (size_type i=0; i<A.N(); i++)
317 nn += rowdim(A,i);
318 return nn;
319 }
320
321 static size_type coldim (const Matrix& A){
322 typedef typename Matrix::ConstRowIterator ConstRowIterator;
323 typedef typename Matrix::ConstColIterator ConstColIterator;
324
325 // The following code has a complexity of nnz, and
326 // typically a very small constant.
327 //
328 std::vector<size_type> coldims(A.M(),
330
331 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)
332 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)
333 // only compute blocksizes we don't already have
334 if (coldims[col.index()]==std::numeric_limits<size_type>::max())
335 coldims[col.index()] = MatrixDimension<block_type>::coldim(*col);
336
337 size_type sum = 0;
338 for (typename std::vector<size_type>::iterator it=coldims.begin();
339 it!=coldims.end(); ++it)
340 // skip rows for which no coldim could be determined
341 if ((*it)>=0)
342 sum += *it;
343
344 return sum;
345 }
346 };
347
348
349 template<typename B, int n, int m, typename TA>
351 {
353 typedef typename Matrix::size_type size_type;
354
355 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)
356 {
357 return n;
358 }
359
360 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)
361 {
362 return m;
363 }
364
365 static size_type rowdim (const Matrix& A) {
366 return A.N()*n;
367 }
368
369 static size_type coldim (const Matrix& A) {
370 return A.M()*m;
371 }
372 };
373
374 template<typename K, int n, int m>
376 {
378 typedef typename Matrix::size_type size_type;
379
380 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
381 {
382 return 1;
383 }
384
385 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
386 {
387 return 1;
388 }
389
390 static size_type rowdim(const Matrix& /*A*/)
391 {
392 return n;
393 }
394
395 static size_type coldim(const Matrix& /*A*/)
396 {
397 return m;
398 }
399 };
400
401 template <class T>
403 {
406
407 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)
408 {
409 return 1;
410 }
411
412 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)
413 {
414 return 1;
415 }
416
417 static size_type rowdim(const MatrixType& A)
418 {
419 return A.N();
420 }
421
422 static size_type coldim(const MatrixType& A)
423 {
424 return A.M();
425 }
426 };
427
428 template<typename K, int n, int m, typename TA>
429 struct MatrixDimension<Matrix<FieldMatrix<K,n,m>, TA> >
430 {
433
434 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)
435 {
436 return n;
437 }
438
439 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)
440 {
441 return m;
442 }
443
444 static size_type rowdim(const ThisMatrix& A)
445 {
446 return A.N()*n;
447 }
448
449 static size_type coldim(const ThisMatrix& A)
450 {
451 return A.M()*m;
452 }
453 };
454
455 template<typename K, int n>
457 {
459 typedef typename Matrix::size_type size_type;
460
461 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
462 {
463 return 1;
464 }
465
466 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
467 {
468 return 1;
469 }
470
471 static size_type rowdim(const Matrix& /*A*/)
472 {
473 return n;
474 }
475
476 static size_type coldim(const Matrix& /*A*/)
477 {
478 return n;
479 }
480 };
481
482 template<typename K, int n>
484 {
486 typedef typename Matrix::size_type size_type;
487
488 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
489 {
490 return 1;
491 }
492
493 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
494 {
495 return 1;
496 }
497
498 static size_type rowdim(const Matrix& /*A*/)
499 {
500 return n;
501 }
502
503 static size_type coldim(const Matrix& /*A*/)
504 {
505 return n;
506 }
507 };
508
512 template<typename T>
513 struct IsMatrix
514 {
515 enum {
519 value = false
520 };
521 };
522
523 template<typename T>
525 {
526 enum {
530 value = true
531 };
532 };
533
534
535 template<typename T, typename A>
536 struct IsMatrix<BCRSMatrix<T,A> >
537 {
538 enum {
542 value = true
543 };
544 };
545
546 template<typename T, typename P, typename A>
547 struct IsMatrix<Experimental::BCRSMatrix<T,P,A> >
548 {
549 enum {
553 value = true
554 };
555 };
556}
557#endif
This file implements a quadratic matrix of fixed size which is a multiple of the identity.
Col col
Definition matrixmatrix.hh:351
Matrix & mat
Definition matrixmatrix.hh:347
auto countNonZeros(const M &, typename std::enable_if_t< Dune::IsNumber< M >::value > *sfinae=nullptr)
Get the number of nonzero fields in the matrix.
Definition matrixutils.hh:129
static constexpr size_type M()
const FieldVector< K, n > & diagonal() const
virtual void operator()()=0
#define DUNE_THROW(E,...)
const GlobalIndex & global() const
const IndexPair * pair(const std::size_t &local) const
void printGlobalSparseMatrix(const M &mat, C &ooc, std::ostream &os)
Definition matrixutils.hh:164
typename Base::size_type size_type
Base::size_type size_type
Definition matrixutils.hh:221
static auto coldim(const M &)
Definition matrixutils.hh:229
static auto rowdim(const M &)
Definition matrixutils.hh:224
A sparse block matrix with compressed row storage.
Definition bcrsmatrix.hh:468
std::allocator_traits< A >::size_type size_type
The type for the index access and the size.
Definition bcrsmatrix.hh:496
row_type::ConstIterator ConstColIterator
Const iterator to the entries of a row.
Definition bcrsmatrix.hh:739
B block_type
export the type representing the components
Definition bcrsmatrix.hh:493
Iterator access to matrix rows
Definition bcrsmatrix.hh:577
A Matrix class to support different block types.
Definition multitypeblockmatrix.hh:46
derive error class from the base class in common
Definition istlexception.hh:19
ConstIterator class for sequential access.
Definition matrix.hh:404
A generic dynamic dense matrix.
Definition matrix.hh:561
A::size_type size_type
Type for indices and sizes.
Definition matrix.hh:577
RowIterator end()
Get iterator to one beyond last row.
Definition matrix.hh:616
RowIterator begin()
Get iterator to first row.
Definition matrix.hh:610
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition matrix.hh:589
T block_type
Export the type representing the components.
Definition matrix.hh:568
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition matrixutils.hh:58
static void check(const Matrix &mat)
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition matrixutils.hh:63
static void check(const Matrix &mat)
Definition matrixutils.hh:85
static void check(const Matrix &)
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition matrixutils.hh:109
MultiTypeBlockMatrix< T1, Args... > Matrix
Definition matrixutils.hh:103
static size_type rowdim(const Matrix< B, TA > &A, size_type i)
Definition matrixutils.hh:242
static size_type coldim(const Matrix< B, TA > &A)
Definition matrixutils.hh:260
static size_type rowdim(const Matrix< B, TA > &A)
Definition matrixutils.hh:252
typename Matrix< B, TA >::size_type size_type
Definition matrixutils.hh:240
static size_type coldim(const Matrix< B, TA > &A, size_type c)
Definition matrixutils.hh:247
typename Matrix< B, TA >::block_type block_type
Definition matrixutils.hh:239
BCRSMatrix< B, TA > Matrix
Definition matrixutils.hh:273
static size_type coldim(const Matrix &A)
Definition matrixutils.hh:321
Matrix::block_type block_type
Definition matrixutils.hh:274
static size_type coldim(const Matrix &A, size_type c)
Definition matrixutils.hh:286
Matrix::size_type size_type
Definition matrixutils.hh:275
static size_type rowdim(const Matrix &A, size_type i)
Definition matrixutils.hh:277
static size_type rowdim(const Matrix &A)
Definition matrixutils.hh:314
static size_type coldim(const Matrix &A)
Definition matrixutils.hh:369
static size_type rowdim(const Matrix &, size_type)
Definition matrixutils.hh:355
static size_type rowdim(const Matrix &A)
Definition matrixutils.hh:365
Matrix::size_type size_type
Definition matrixutils.hh:353
BCRSMatrix< FieldMatrix< B, n, m >,TA > Matrix
Definition matrixutils.hh:352
static size_type coldim(const Matrix &, size_type)
Definition matrixutils.hh:360
static size_type rowdim(const Matrix &, size_type)
Definition matrixutils.hh:380
static size_type coldim(const Matrix &)
Definition matrixutils.hh:395
Matrix::size_type size_type
Definition matrixutils.hh:378
FieldMatrix< K, n, m > Matrix
Definition matrixutils.hh:377
static size_type coldim(const Matrix &, size_type)
Definition matrixutils.hh:385
static size_type rowdim(const Matrix &)
Definition matrixutils.hh:390
static size_type coldim(const MatrixType &A)
Definition matrixutils.hh:422
static size_type rowdim(const MatrixType &A)
Definition matrixutils.hh:417
static size_type rowdim(const MatrixType &, size_type)
Definition matrixutils.hh:407
MatrixType::size_type size_type
Definition matrixutils.hh:405
static size_type coldim(const MatrixType &, size_type)
Definition matrixutils.hh:412
Dune::DynamicMatrix< T > MatrixType
Definition matrixutils.hh:404
static size_type coldim(const ThisMatrix &A)
Definition matrixutils.hh:449
static size_type rowdim(const ThisMatrix &A)
Definition matrixutils.hh:444
Matrix< FieldMatrix< K, n, m >, TA > ThisMatrix
Definition matrixutils.hh:431
static size_type coldim(const ThisMatrix &, size_type)
Definition matrixutils.hh:439
static size_type rowdim(const ThisMatrix &, size_type)
Definition matrixutils.hh:434
ThisMatrix::size_type size_type
Definition matrixutils.hh:432
static size_type coldim(const Matrix &, size_type)
Definition matrixutils.hh:466
Matrix::size_type size_type
Definition matrixutils.hh:459
static size_type coldim(const Matrix &)
Definition matrixutils.hh:476
static size_type rowdim(const Matrix &)
Definition matrixutils.hh:471
DiagonalMatrix< K, n > Matrix
Definition matrixutils.hh:458
static size_type rowdim(const Matrix &, size_type)
Definition matrixutils.hh:461
static size_type coldim(const Matrix &)
Definition matrixutils.hh:503
static size_type rowdim(const Matrix &, size_type)
Definition matrixutils.hh:488
static size_type coldim(const Matrix &, size_type)
Definition matrixutils.hh:493
Matrix::size_type size_type
Definition matrixutils.hh:486
ScaledIdentityMatrix< K, n > Matrix
Definition matrixutils.hh:485
static size_type rowdim(const Matrix &)
Definition matrixutils.hh:498
Test whether a type is an ISTL Matrix.
Definition matrixutils.hh:514
@ value
True if T is an ISTL matrix.
Definition matrixutils.hh:519
A multiple of the identity matrix of static size.
Definition scaledidmatrix.hh:42
T begin(T... args)
T end(T... args)
T endl(T... args)
T insert(T... args)
T make_pair(T... args)
T max(T... args)