KASKADE 7 development version
crsutil.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) 2002-2015 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 CRSUTIL_HH
14#define CRSUTIL_HH
15
16#include <vector>
17
18#include <dune/common/fvector.hh>
19#include <dune/common/fmatrix.hh>
20#include <dune/istl/bvector.hh>
21#include <dune/istl/bcrsmatrix.hh>
22
23#include "fem/fixdune.hh"
24
25//---------------------------------------------------------------------
26
27namespace Kaskade
28{
29 template <class OutIter>
30 OutIter vectorToSequence(double x, OutIter iter)
31 {
32 *iter = x;
33 return ++iter;
34 }
35
36 template <class OutIter>
37 OutIter vectorToSequence(float x, OutIter iter)
38 {
39 *iter = x;
40 return ++iter;
41 }
42
43
44 template <class K, int size, class OutIter>
45 OutIter vectorToSequence(Dune::FieldVector<K,size> const& v, OutIter iter)
46 {
47 for (size_t i=0; i<size; ++i)
48 {
49 #ifndef NDEBUG
50 if (std::isinf(v[i]))
51 {
52 std::cerr << __FILE__ << ':' << __LINE__ << ":VectorToSequence::call v[" << i << "] = inf\n" << std::flush;
53 throw -111;
54 }
55 if (std::isnan(v[i]))
56 {
57 std::cerr << __FILE__ << ':' << __LINE__ << ":VectorToSequence::call v[" << i << "] = nan\n" << std::flush;
58 throw -111;
59 }
60 #endif
61 iter = vectorToSequence(v[i],iter);
62 }
63 return iter;
64 }
65
75 template <class B, class A, class OutIter>
76 OutIter vectorToSequence(Dune::BlockVector<B,A> const& v, OutIter iter)
77 {
78 for (int i=0; i<v.N(); ++i)
79 iter = vectorToSequence(v[i],iter);
80 return iter;
81 }
82
83 template <class K, class OutIter>
84 OutIter vectorToSequence(std::vector<K> const& v, OutIter iter)
85 {
86 for (auto const& x: v)
87 iter = vectorToSequence(x,iter);
88 return iter;
89 }
90
91
92 //---------------------------------------------------------------------
93
94
95
96 template <class InIter>
97 InIter vectorFromSequence(double& x, InIter iter)
98 {
99 x = *iter;
100 return ++iter;
101 }
102
103 template <class InIter>
104 InIter vectorFromSequence(float& x, InIter iter)
105 {
106 x = *iter;
107 return ++iter;
108 }
109
110 template <class K, int size, class InIter>
112 {
113 for (size_t i=0; i<v.N(); ++i)
114 iter = vectorFromSequence(v[i],iter);
115 return iter;
116 }
117
126 template <class B, class A, class InIter>
128 {
129 for (int i=0; i<v.N(); ++i)
130 in = vectorFromSequence(v[i],in);
131 return in;
132 }
133
134 template <class K, class InIter>
135 InIter vectorFromSequence(std::vector<K>& v, InIter iter)
136 {
137 for (auto& x: v)
138 iter = vectorFromSequence(x,iter);
139 return iter;
140 }
141
142 //---------------------------------------------------------------------
143 //---------------------------------------------------------------------
144
145 namespace Crsutil_Detail
146 {
147 template <class Vec>
149 {
150 static const bool contiguous = std::is_arithmetic_v<Vec>;
151 };
152
153 template <class Entry>
155 {
157 };
158
159 template <class Entry, int n>
160 struct VectorTraits<Dune::FieldVector<Entry,n>>
161 {
163 };
164 }
165
166 template <class Vec>
168
169 //---------------------------------------------------------------------
170 //---------------------------------------------------------------------
171
176 template <class Matrix>
178
179 template <class K, int N, int M, class Allocator>
180 struct Matrix_to_Triplet<Dune::BCRSMatrix<Dune::FieldMatrix<K,N,M>,Allocator> >
181 {
182 private:
183 typedef Dune::BCRSMatrix<Dune::FieldMatrix<K,N,M>,Allocator> Matrix;
184 typedef typename Matrix::ConstRowIterator RI;
185 typedef typename Matrix::ConstColIterator CI;
186
187 public:
212 template <class OutIteratorI, class OutIteratorD>
213 static void call(Matrix const& a,
214 OutIteratorI& i, OutIteratorI& j,
215 OutIteratorD& z,
216 int startrow, int const startcol,
217 bool onlyLowerTriangle = false,
218 bool symmetric = false)
219 {
220 for (RI row=a.begin(); row!=a.end(); ++row)
221 for (CI col=row->begin() ; col!=row->end(); ++col)
222 {
223 if (!onlyLowerTriangle || (row.index()>=col.index()))
224 Matrix_to_Triplet<typename Matrix::block_type>::call(*col,i,j,z,startrow+row.index()*N,startcol+col.index()*M,
225 (row.index()==col.index()) && onlyLowerTriangle);
226 if (symmetric && !onlyLowerTriangle && row.index()>col.index())
227 Matrix_to_Triplet<typename Matrix::block_type>::call(*col,j,i,z,startcol+row.index()*N,startrow+col.index()*M);
228 }
229 }
230
244 static size_t nnz(Matrix const& a,
245 bool onlyLowerTriangle = false,
246 bool symmetric = false)
247 {
248 size_t size = 0;
249 RI rend = a.end();
250 for (RI row=a.begin(); row!=rend; ++row)
251 {
252 CI cend = row->end();
253 for (CI col=row->begin(); col!=cend; ++col)
254 {
255 if (!onlyLowerTriangle || (row.index()>=col.index()))
256 size += Matrix_to_Triplet<typename Matrix::block_type>::nnz(*col,(row.index()==col.index()) && onlyLowerTriangle);
257
258 if (symmetric && !onlyLowerTriangle && row.index()>col.index())
260 }
261 }
262 return size;
263 }
264 };
265
266 template <class Entry, class Index> // forward declaration
267 class NumaBCRSMatrix;
268
269 template <class K, int N, int M, class Index>
270 struct Matrix_to_Triplet<NumaBCRSMatrix<Dune::FieldMatrix<K,N,M>,Index> >
271 {
272 private:
274
275 public:
300 template <class OutIteratorI, class OutIteratorD>
301 static void call(Matrix const& a,
302 OutIteratorI& i, OutIteratorI& j,
303 OutIteratorD& z,
304 int startrow, int const startcol,
305 bool onlyLowerTriangle = false,
306 bool symmetric = false)
307 {
308 auto rend = a.end();
309 for (auto row=a.begin(); row!=rend; ++row)
310 {
311 auto cend = row->end();
312 for (auto col=row->begin() ; col!=cend; ++col)
313 {
314 if (!onlyLowerTriangle || (row.index()>=col.index()))
315 Matrix_to_Triplet<typename Matrix::block_type>::call(*col,i,j,z,startrow+row.index()*N,startcol+col.index()*M,
316 (row.index()==col.index()) && onlyLowerTriangle);
317 if (symmetric && !onlyLowerTriangle && row.index()>col.index())
318 Matrix_to_Triplet<typename Matrix::block_type>::call(*col,j,i,z,startcol+row.index()*N,startrow+col.index()*M);
319 }
320 }
321 }
322
336 static size_t nnz(Matrix const& a,
337 bool onlyLowerTriangle = false,
338 bool symmetric = false)
339 {
340 size_t size = 0;
341 auto rend = a.end();
342 for (auto row=a.begin(); row!=rend; ++row)
343 {
344 auto cend = row->end();
345 for (auto col=row->begin(); col!=cend; ++col)
346 {
347 if (!onlyLowerTriangle || (row.index()>=col.index()))
348 size += Matrix_to_Triplet<typename Matrix::block_type>::nnz(*col,(row.index()==col.index()) && onlyLowerTriangle);
349
350 if (symmetric && !onlyLowerTriangle && row.index()>col.index())
352 }
353 }
354 return size;
355 }
356 };
357
358 template <class K, int n, int m>
359 struct Matrix_to_Triplet<Dune::FieldMatrix<K,n,m> >
360 {
361 template <class OutIteratorI, class OutIteratorD>
362 static void call(Dune::FieldMatrix<K,n,m> const& a,
363 OutIteratorI& i, OutIteratorI& j,
364 OutIteratorD& z,
365 int startrow, int const startcol,
366 bool onlyLowerTriangle = false)
367 {
368 if (onlyLowerTriangle)
369 {
370 assert(n==m);
371 for (int row=0; row<n; ++row)
372 for (int col=0; col<=row; ++col) {
373 *i++ = row + startrow;
374 *j++ = col + startcol;
375 *z++ = a[row][col];
376 }
377 }
378 else
379 for (int row=0; row<n; ++row)
380 for (int col=0; col<m; ++col) {
381 *i++ = row + startrow;
382 *j++ = col + startcol;
383 *z++ = a[row][col];
384 }
385 }
386
387 template <class OutIteratorI, class OutIteratorD>
389 OutIteratorI& i, OutIteratorI& j,
390 OutIteratorD& z,
391 int startrow, int const startcol)
392 {
393 for (int row=0; row<n; ++row)
394 for (int col=0; col<m; ++col) {
395 *i++ = col + startrow;
396 *j++ = row + startcol;
397 *z++ = a[row][col];
398 }
399 }
400
401 static size_t nnz(Dune::FieldMatrix<K,n,m> const& a,
402 bool onlyLowerTriangle = false)
403 {
404 if (onlyLowerTriangle) {
405 assert(n==m);
406 return n*(n+1)/2;
407 } else return n*m;
408 }
409 };
410
411
417 template <class Matrix, class OutIteratorI, class OutIteratorD>
418 void matrix_to_triplet(Matrix const& a,
419 OutIteratorI i, OutIteratorI j,
420 OutIteratorD z)
421 {
423 }
424
425// /**
426// * \brief Sorts the sparse matrix nonzero positions into row buckets.
427// * \param nrows number of rows
428// * \param ridx vector of row indices
429// * \param cidx vector of column indices
430// * \param[out] rowColumnIndices stores the column indices for each row
431// */
432// template <class SparseInt>
433// void getBCRSIndicesFromTriplet(SparseInt nrows, std::vector<SparseInt> const& ridx, std::vector<SparseInt> const& cidx,
434// std::vector<std::vector<SparseInt>>& rowColumnIndices)
435// {
436// rowColumnIndices.clear();
437// rowColumnIndices.resize(nrows);
438// for(SparseInt i=0; i<ridx.size(); ++i)
439// rowColumnIndices[ridx[i]].push_back(cidx[i]);
440// }
441
455 template <class SparseInt>
456 std::vector<std::vector<SparseInt>> getBCRSIndicesFromTriplet(SparseInt nrows, std::vector<SparseInt> const& ridx, std::vector<SparseInt> const& cidx,
457 int nr=1, int nc=1)
458 {
459 std::vector<std::vector<SparseInt>> rowColumnIndices(nrows);
460 for(SparseInt i=0; i<ridx.size(); ++i) // sort entries into rows
461 rowColumnIndices[ridx[i]/nr].push_back(cidx[i]/nc); // respect nr-by-nc blocking
462 for (auto& r: rowColumnIndices) // sort column entries in ascending order
463 { // and remove multiple entries
464 std::sort(begin(r),end(r)); // (e.g. created by nr,nc > 1
465 r.erase(std::unique(begin(r),end(r)),end(r));
466 }
467 return rowColumnIndices;
468 }
469
470 //---------------------------------------------------------------------
471
472
473 template <class B, class A>
474 std::ostream& operator << (std::ostream& out, Dune::BCRSMatrix<B,A> const& a)
475 {
476 typedef typename Dune::BCRSMatrix<B,A>::ConstRowIterator RI;
477 typedef typename Dune::BCRSMatrix<B,A>::ConstColIterator CI;
478
479 int const prec = 6;
480 int const width = prec + 3;
481
482 out << "[\n";
483 for (RI row=a.begin(); row!=a.end(); ++row) {
484 int oldidx = -1;
485 for (CI col=row->begin() ; col!=row->end(); ++col) {
486 out.width((col.index()-oldidx-1)*(width+1)); out << "";
487 out.setf(std::ios_base::fixed,std::ios_base::floatfield);
488 out.width(width); out.precision(prec); out << *col << ' ';
489 oldidx = col.index();
490 }
491 out << '\n';
492 }
493 out << "\n]";
494
495 return out;
496 }
497
498 //---------------------------------------------------------------------
499
500} // namespace Kaskade
501#endif
A NUMA-aware compressed row storage matrix adhering mostly to the Dune ISTL interface (to complete....
iterator end()
returns an iterator to the first row
iterator begin()
returns an iterator to the first row
This file contains various utility functions that augment the basic functionality of Dune.
Dune::BlockVector< Dune::FieldVector< Scalar, n >, Allocator > BlockVector
void matrix_to_triplet(Matrix const &a, OutIteratorI i, OutIteratorI j, OutIteratorD z)
converts a matrix to the coordinate (triplet) format.
Definition: crsutil.hh:418
std::ostream & operator<<(std::ostream &s, std::vector< Scalar > const &vec)
Definition: dune_bridge.hh:47
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
OutIter vectorToSequence(double x, OutIter iter)
Definition: crsutil.hh:30
constexpr bool contiguousStorage
Definition: crsutil.hh:167
InIter vectorFromSequence(FunctionSpaceElement< Space, m > &v, InIter in)
static size_t nnz(Matrix const &a, bool onlyLowerTriangle=false, bool symmetric=false)
returns the number of structurally nonzero scalars in the matrix
Definition: crsutil.hh:244
static void call(Matrix const &a, OutIteratorI &i, OutIteratorI &j, OutIteratorD &z, int startrow, int const startcol, bool onlyLowerTriangle=false, bool symmetric=false)
converts a Dune matrix into triplet format
Definition: crsutil.hh:213
static size_t nnz(Dune::FieldMatrix< K, n, m > const &a, bool onlyLowerTriangle=false)
Definition: crsutil.hh:401
static void callTransposed(Dune::FieldMatrix< K, n, m > const &a, OutIteratorI &i, OutIteratorI &j, OutIteratorD &z, int startrow, int const startcol)
Definition: crsutil.hh:388
static void call(Dune::FieldMatrix< K, n, m > const &a, OutIteratorI &i, OutIteratorI &j, OutIteratorD &z, int startrow, int const startcol, bool onlyLowerTriangle=false)
Definition: crsutil.hh:362
static void call(Matrix const &a, OutIteratorI &i, OutIteratorI &j, OutIteratorD &z, int startrow, int const startcol, bool onlyLowerTriangle=false, bool symmetric=false)
converts a Dune matrix into triplet format
Definition: crsutil.hh:301
static size_t nnz(Matrix const &a, bool onlyLowerTriangle=false, bool symmetric=false)
returns the number of structurally nonzero scalars in the matrix
Definition: crsutil.hh:336
A class template that supports converting certain Dune matrices into the coordinate (triplet) format.
Definition: crsutil.hh:177