Dune Core Modules (2.4.1)

matrixutils.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_ISTL_MATRIXUTILS_HH
4#define DUNE_ISTL_MATRIXUTILS_HH
5
6#include <set>
7#include <vector>
8#include <limits>
13#include <dune/common/unused.hh>
15#include "istlexception.hh"
16
17namespace Dune
18{
19
20#ifndef DOYXGEN
21 template<typename B, typename A>
22 class BCRSMatrix;
23
24 template<typename K, int n, int m>
25 class FieldMatrix;
26
27 template<class T, class A>
28 class Matrix;
29#endif
30
40 namespace
41 {
42
43 template<int i>
44 struct NonZeroCounter
45 {
46 template<class M>
47 static typename M::size_type count(const M& matrix)
48 {
49 typedef typename M::ConstRowIterator RowIterator;
50
51 RowIterator endRow = matrix.end();
52 typename M::size_type nonZeros = 0;
53
54 for(RowIterator row = matrix.begin(); row != endRow; ++row) {
55 typedef typename M::ConstColIterator Entry;
56 Entry endEntry = row->end();
57 for(Entry entry = row->begin(); entry != endEntry; ++entry) {
58 nonZeros += NonZeroCounter<i-1>::count(*entry);
59 }
60 }
61 return nonZeros;
62 }
63 };
64
65 template<>
66 struct NonZeroCounter<1>
67 {
68 template<class M>
69 static typename M::size_type count(const M& matrix)
70 {
71 return matrix.N()*matrix.M();
72 }
73 };
74
75 }
76
81 template<class Matrix, std::size_t blocklevel, std::size_t l=blocklevel>
83 {
88 static void check(const Matrix& mat)
89 {
91#ifdef DUNE_ISTL_WITH_CHECKING
92 typedef typename Matrix::ConstRowIterator Row;
93 typedef typename Matrix::ConstColIterator Entry;
94 for(Row row = mat.begin(); row!=mat.end(); ++row) {
95 Entry diagonal = row->find(row.index());
96 if(diagonal==row->end())
97 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
98 <<" at block recursion level "<<l-blocklevel);
99 else
101 }
102#endif
103 }
104 };
105
106 template<class Matrix, std::size_t l>
107 struct CheckIfDiagonalPresent<Matrix,0,l>
108 {
109 static void check(const Matrix& mat)
110 {
111 typedef typename Matrix::ConstRowIterator Row;
112 for(Row row = mat.begin(); row!=mat.end(); ++row) {
113 if(row->find(row.index())==row->end())
114 DUNE_THROW(ISTLError, "Missing diagonal value in row "<<row.index()
115 <<" at block recursion level "<<l);
116 }
117 }
118 };
119
120 template<typename T1, typename T2, typename T3, typename T4, typename T5,
121 typename T6, typename T7, typename T8, typename T9>
122 class MultiTypeBlockMatrix;
123
124 template<typename T1, typename T2, typename T3, typename T4, typename T5,
125 typename T6, typename T7, typename T8, typename T9, std::size_t blocklevel, std::size_t l>
126 struct CheckIfDiagonalPresent<MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9>,
127 blocklevel,l>
128 {
129 typedef MultiTypeBlockMatrix<T1,T2,T3,T4,T5,T6,T7,T8,T9> Matrix;
130
135 static void check(const Matrix& /* mat */)
136 {
137#ifdef DUNE_ISTL_WITH_CHECKING
138 // TODO Implement check
139#endif
140 }
141 };
142
154 template<class M>
155 inline int countNonZeros(const M& matrix)
156 {
157 return NonZeroCounter<M::blocklevel>::count(matrix);
158 }
159 /*
160 template<class M>
161 struct ProcessOnFieldsOfMatrix
162 */
163
165 namespace
166 {
167 struct CompPair {
168 template<class G,class M>
169 bool operator()(const std::pair<G,M>& p1, const std::pair<G,M>& p2)
170 {
171 return p1.first<p2.first;
172 }
173 };
174
175 }
176 template<class M, class C>
177 void printGlobalSparseMatrix(const M& mat, C& ooc, std::ostream& os)
178 {
179 typedef typename C::ParallelIndexSet::const_iterator IIter;
180 typedef typename C::OwnerSet OwnerSet;
181 typedef typename C::ParallelIndexSet::GlobalIndex GlobalIndex;
182
183 GlobalIndex gmax=0;
184
185 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
186 idx!=eidx; ++idx)
187 gmax=std::max(gmax,idx->global());
188
189 gmax=ooc.communicator().max(gmax);
190 ooc.buildGlobalLookup();
191
192 for(IIter idx=ooc.indexSet().begin(), eidx=ooc.indexSet().end();
193 idx!=eidx; ++idx) {
194 if(OwnerSet::contains(idx->local().attribute()))
195 {
196 typedef typename M::block_type Block;
197
198 std::set<std::pair<GlobalIndex,Block>,CompPair> entries;
199
200 // sort rows
201 typedef typename M::ConstColIterator CIter;
202 for(CIter c=mat[idx->local()].begin(), cend=mat[idx->local()].end();
203 c!=cend; ++c) {
204 const typename C::ParallelIndexSet::IndexPair* pair
205 =ooc.globalLookup().pair(c.index());
206 assert(pair);
207 entries.insert(std::make_pair(pair->global(), *c));
208 }
209
210 //wait until its the rows turn.
211 GlobalIndex rowidx = idx->global();
212 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
213 while(cur!=rowidx)
214 cur=ooc.communicator().min(rowidx);
215
216 // print rows
217 typedef typename std::set<std::pair<GlobalIndex,Block>,CompPair>::iterator SIter;
218 for(SIter s=entries.begin(), send=entries.end(); s!=send; ++s)
219 os<<idx->global()<<" "<<s->first<<" "<<s->second<<std::endl;
220
221
222 }
223 }
224
225 ooc.freeGlobalLookup();
226 // Wait until everybody is finished
227 GlobalIndex cur=std::numeric_limits<GlobalIndex>::max();
228 while(cur!=ooc.communicator().min(cur)) ;
229 }
230
231 template<typename M>
232 struct MatrixDimension
233 {};
234
235
236 template<typename B, typename TA>
237 struct MatrixDimension<BCRSMatrix<B,TA> >
238 {
239 typedef BCRSMatrix<B,TA> Matrix;
240 typedef typename Matrix::block_type block_type;
241 typedef typename Matrix::size_type size_type;
242
243 static size_type rowdim (const Matrix& A, size_type i)
244 {
245 const B* row = A.r[i].getptr();
246 if(row)
247 return MatrixDimension<block_type>::rowdim(*row);
248 else
249 return 0;
250 }
251
252 static size_type coldim (const Matrix& A, size_type c)
253 {
254 // find an entry in column c
255 if (A.nnz_ > 0)
256 {
257 for (size_type k=0; k<A.nnz_; k++) {
258 if (A.j_.get()[k] == c) {
259 return MatrixDimension<block_type>::coldim(A.a[k]);
260 }
261 }
262 }
263 else
264 {
265 for (size_type i=0; i<A.N(); i++)
266 {
267 size_type* j = A.r[i].getindexptr();
268 B* a = A.r[i].getptr();
269 for (size_type k=0; k<A.r[i].getsize(); k++)
270 if (j[k]==c) {
271 return MatrixDimension<block_type>::coldim(a[k]);
272 }
273 }
274 }
275
276 // not found
277 return 0;
278 }
279
280 static size_type rowdim (const Matrix& A){
281 size_type nn=0;
282 for (size_type i=0; i<A.N(); i++)
283 nn += rowdim(A,i);
284 return nn;
285 }
286
287 static size_type coldim (const Matrix& A){
288 typedef typename Matrix::ConstRowIterator ConstRowIterator;
289 typedef typename Matrix::ConstColIterator ConstColIterator;
290
291 // The following code has a complexity of nnz, and
292 // typically a very small constant.
293 //
294 std::vector<size_type> coldims(A.M(),
295 std::numeric_limits<size_type>::max());
296
297 for (ConstRowIterator row=A.begin(); row!=A.end(); ++row)
298 for (ConstColIterator col=row->begin(); col!=row->end(); ++col)
299 // only compute blocksizes we don't already have
300 if (coldims[col.index()]==std::numeric_limits<size_type>::max())
301 coldims[col.index()] = MatrixDimension<block_type>::coldim(*col);
302
303 size_type sum = 0;
304 for (typename std::vector<size_type>::iterator it=coldims.begin();
305 it!=coldims.end(); ++it)
306 // skip rows for which no coldim could be determined
307 if ((*it)>=0)
308 sum += *it;
309
310 return sum;
311 }
312 };
313
314
315 template<typename B, int n, int m, typename TA>
316 struct MatrixDimension<BCRSMatrix<FieldMatrix<B,n,m> ,TA> >
317 {
318 typedef BCRSMatrix<FieldMatrix<B,n,m> ,TA> Matrix;
319 typedef typename Matrix::size_type size_type;
320
321 static size_type rowdim (const Matrix& /*A*/, size_type /*i*/)
322 {
323 return n;
324 }
325
326 static size_type coldim (const Matrix& /*A*/, size_type /*c*/)
327 {
328 return m;
329 }
330
331 static size_type rowdim (const Matrix& A) {
332 return A.N()*n;
333 }
334
335 static size_type coldim (const Matrix& A) {
336 return A.M()*m;
337 }
338 };
339
340 template<typename K, int n, int m>
341 struct MatrixDimension<FieldMatrix<K,n,m> >
342 {
343 typedef FieldMatrix<K,n,m> Matrix;
344 typedef typename Matrix::size_type size_type;
345
346 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
347 {
348 return 1;
349 }
350
351 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
352 {
353 return 1;
354 }
355
356 static size_type rowdim(const Matrix& /*A*/)
357 {
358 return n;
359 }
360
361 static size_type coldim(const Matrix& /*A*/)
362 {
363 return m;
364 }
365 };
366
367 template <class T>
368 struct MatrixDimension<Dune::DynamicMatrix<T> >
369 {
370 typedef Dune::DynamicMatrix<T> MatrixType;
371 typedef typename MatrixType::size_type size_type;
372
373 static size_type rowdim(const MatrixType& /*A*/, size_type /*r*/)
374 {
375 return 1;
376 }
377
378 static size_type coldim(const MatrixType& /*A*/, size_type /*r*/)
379 {
380 return 1;
381 }
382
383 static size_type rowdim(const MatrixType& A)
384 {
385 return A.N();
386 }
387
388 static size_type coldim(const MatrixType& A)
389 {
390 return A.M();
391 }
392 };
393
394 template<typename K, int n, int m, typename TA>
395 struct MatrixDimension<Matrix<FieldMatrix<K,n,m>, TA> >
396 {
397 typedef Matrix<FieldMatrix<K,n,m>, TA> ThisMatrix;
398 typedef typename ThisMatrix::size_type size_type;
399
400 static size_type rowdim(const ThisMatrix& /*A*/, size_type /*r*/)
401 {
402 return n;
403 }
404
405 static size_type coldim(const ThisMatrix& /*A*/, size_type /*r*/)
406 {
407 return m;
408 }
409
410 static size_type rowdim(const ThisMatrix& A)
411 {
412 return A.N()*n;
413 }
414
415 static size_type coldim(const ThisMatrix& A)
416 {
417 return A.M()*m;
418 }
419 };
420
421 template<typename K, int n>
422 struct MatrixDimension<DiagonalMatrix<K,n> >
423 {
424 typedef DiagonalMatrix<K,n> Matrix;
425 typedef typename Matrix::size_type size_type;
426
427 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
428 {
429 return 1;
430 }
431
432 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
433 {
434 return 1;
435 }
436
437 static size_type rowdim(const Matrix& /*A*/)
438 {
439 return n;
440 }
441
442 static size_type coldim(const Matrix& /*A*/)
443 {
444 return n;
445 }
446 };
447
448 template<typename K, int n>
449 struct MatrixDimension<ScaledIdentityMatrix<K,n> >
450 {
451 typedef ScaledIdentityMatrix<K,n> Matrix;
452 typedef typename Matrix::size_type size_type;
453
454 static size_type rowdim(const Matrix& /*A*/, size_type /*r*/)
455 {
456 return 1;
457 }
458
459 static size_type coldim(const Matrix& /*A*/, size_type /*r*/)
460 {
461 return 1;
462 }
463
464 static size_type rowdim(const Matrix& /*A*/)
465 {
466 return n;
467 }
468
469 static size_type coldim(const Matrix& /*A*/)
470 {
471 return n;
472 }
473 };
474
478 template<typename T>
479 struct IsMatrix
480 {
481 enum {
485 value = false
486 };
487 };
488
489 template<typename T>
490 struct IsMatrix<DenseMatrix<T> >
491 {
492 enum {
496 value = true
497 };
498 };
499
500
501 template<typename T, typename A>
502 struct IsMatrix<BCRSMatrix<T,A> >
503 {
504 enum {
508 value = true
509 };
510 };
511
512 template<typename T>
513 struct PointerCompare
514 {
515 bool operator()(const T* l, const T* r)
516 {
517 return *l < *r;
518 }
519 };
520
521}
522#endif
Construct a matrix with a dynamic size.
Definition: dynmatrix.hh:56
derive error class from the base class in common
Definition: istlexception.hh:16
A generic dynamic dense matrix.
Definition: matrix.hh:25
A::size_type size_type
Type for indices and sizes.
Definition: matrix.hh:41
VariableBlockVector< T, A >::ConstIterator ConstRowIterator
Const iterator over the matrix rows.
Definition: matrix.hh:50
row_type::const_iterator ConstColIterator
Const iterator for the entries of each row.
Definition: matrix.hh:53
T block_type
Export the type representing the components.
Definition: matrix.hh:32
ConstIterator class for sequential access.
Definition: vbvector.hh:647
This file implements a quadratic diagonal matrix of fixed size.
This file implements a dense matrix with dynamic numbers of rows and columns.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
#define DUNE_THROW(E, m)
Definition: exceptions.hh:243
int countNonZeros(const M &matrix)
Get the number of nonzero fields in the matrix.
Definition: matrixutils.hh:155
Dune namespace.
Definition: alignment.hh:10
This file implements a quadratic matrix of fixed size which is a multiple of the identity.
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition: matrixutils.hh:83
static void check(const Matrix &mat)
Check whether the a matrix has diagonal values on blocklevel recursion levels.
Definition: matrixutils.hh:88
Test whether a type is an ISTL Matrix.
Definition: matrixutils.hh:480
@ value
True if T is an ISTL matrix.
Definition: matrixutils.hh:485
Traits for type conversions and type information.
Definition of the DUNE_UNUSED macro for the case that config.h is not available.
#define DUNE_UNUSED_PARAMETER(parm)
A macro to mark intentional unused function parameters with.
Definition: unused.hh:18
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Nov 21, 23:30, 2024)