KASKADE 7 development version
fixdune.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-2020 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#if !defined(FIXDUNE_HH)
14#define FIXDUNE_HH
15
16#include <type_traits>
17
18// Here we'd rather include dune/common/config.h, but this messes around with
19// including "FC.h" without specifying the dune/... path. Fortunately,
20// the grid config header has the common module version defined as well.
21#include "dune/grid/config.h"
22
23#include "dune/common/fmatrix.hh"
24#include "dune/common/fvector.hh"
25#include "dune/common/version.hh"
26#include "dune/geometry/type.hh"
27#include "dune/geometry/referenceelements.hh"
28
29
30#include "dune/istl/matrix.hh"
31#include "dune/istl/bvector.hh"
32#include "dune/istl/bcrsmatrix.hh"
33
35#include "utilities/scalar.hh"
42namespace Dune
43{
44
49 template <class T, int n, class S,
50 class enable = typename std::enable_if_t<std::is_arithmetic_v<S>>>
52 {
53 x *= static_cast<T>(s);
54 return x;
55 }
56
61 template <class T, int n, class S,
62 class enable = typename std::enable_if_t<std::is_arithmetic_v<S>>>
64 {
65 x *= static_cast<typename Kaskade::EntryTraits<T>::field_type>(s);
66 return x;
67 }
68
73 template <class T, int n>
75 {
76 x += y;
77 return x;
78 }
79
84 template <class T, int n>
86 {
87 for (int i=0; i<n; ++i)
88 x[i] += y;
89 return x;
90 }
91
92
97 template <class T, int n>
99 {
100 for (int i=0; i<n; ++i)
101 x[i] = -x[i];
102 return x;
103 }
104
109 template <class T, int n>
111 {
112 for (int i=0; i<n; ++i)
113 x[i] = std::max(x[i],y[i]);
114 return x;
115 }
116
121 template <class T, int n>
123 {
124 for (int i=0; i<n; ++i)
125 x[i] = std::min(x[i],y[i]);
126 return x;
127 }
128
129
134 template <class T, int n, int m>
136 {
138 for (int j=0; j<m; ++j)
139 for (int i=0; i<n; ++i)
140 y[j*n+i] = x[i][j];
141 return y;
142 }
143
148 template <int n, int m, class T>
150 {
152 for (int j=0; j<m; ++j)
153 for (int i=0; i<n; ++i)
154 y[i][j] = x[j*n+i];
155 return y;
156 }
157
158
163 template <class T, int n, int m>
165 {
167 for (int i=0; i<n; ++i)
168 for (int j=0; j<m; ++j)
169 A[i][j] = x[i]*y[j];
170 return A;
171 }
172
177 template <class T, int n>
179 {
180 T nm = x.two_norm();
181 if (nm>0)
182 x /= nm;
183 return x;
184 }
185
190 template <class T, int n, int m>
192 Dune::FieldVector<T,m> const& y)
193 {
195 for (int i=0; i<n; ++i)
196 z[i] = x[i];
197 for (int i=0; i<m; ++i)
198 z[i+n] = y[i];
199 return z;
200 }
201
202
203#ifndef DUNE_ALBERTA_ALGEBRA_HH
208 template <class T>
210 {
211 return x[0]*y[1] - x[1]*y[0];
212 }
213
218 template <class T>
220 {
222 A[0][0] = -x[1];
223 A[0][1] = x[0];
224 }
225
230 template <class T>
232 {
234 for (int i=0; i<3; ++i)
235 t[i] = x[(i+1)%3]*y[(i+2)%3]-x[(i+2)%3]*y[(i+1)%3];
236 return t;
237 }
238
243 template <class T>
245 {
247 for (int i=0; i<3; ++i)
248 {
249 A[i][(i+2)%3] = x[(i+1)%3];
250 A[i][(i+1)%3] = -x[(i+2)%3];
251 }
252 return A;
253 }
254
255#endif
256
257
258
263 template <class T, class S, int n, int m>
265 Dune::FieldVector<S,m> const& x)
266 {
268 //A.umv(x,b);
269 for (int i=0; i<n; ++i)
270 for (int j=0; j<m; ++j)
271 b[i] += A[i][j]*x[j];
272 return b;
273 }
274
279 template <class T, int n, int m>
281 {
283 for (int i=0; i<n; ++i)
284 C[i] = -A[i]; // vector negation of rows
285 return C;
286 }
287
288 template <class T, int n, int m>
290 {
291 if constexpr (n*m==1)
292 return A[0][0];
293 else
294 return A;
295 }
296
297 // Ambiguity with Dune::transpose() as of Dune 2.9.0
298 // Note that Dune::transposed() does not perform a recursive transpose.
299 //
300 // template <class T, typename = std::enable_if_t<std::is_arithmetic<T>::value>>
301 // T transpose(T x)
302 // {
303 // return x;
304 // }
305 //
306 // /**
307 // * \ingroup linalgbasic
308 // * \brief Matrix transposition \f$ A \mapsto A^T \f$
309 // */
310 // template <class T, int n, int m>
311 // Dune::FieldMatrix<T,m,n> transpose(Dune::FieldMatrix<T,n,m> const& A)
312 // {
313 // Dune::FieldMatrix<T,m,n> At;
314 // for (int i=0; i<n; ++i)
315 // for (int j=0; j<m; ++j)
316 // At[j][i] = transpose(A[i][j]);
317 // return At;
318 // }
319} // end of namespace Dune
320
321
322namespace Kaskade
323{
324 // We define horzcat for Dune::FieldVector/Matrix in the Kaskade namespace because there's
325 // also a horzcat() for DynamicMatrix in the Kaskade namespace. This would otherwise
326 // completely hide the definitions here (seen from within the Kaskade namespace).
327 template <class Scalar, int n>
329 {
330 return c1;
331 }
332
340 template <class Scalar, int n, class ... Rest>
341 auto horzcat(Dune::FieldVector<Scalar,n> const& a, Rest ... rest)
342 {
343 // Works, but I think it's way too slow unless the compiler
344 // does some magic...
345
346 auto b = horzcat(rest...);
347 using B = decltype(b);
349
350 // leads to compiler error as of GCC 8.2 - why?
351 // static_assert(rank<B>==1 || rank<B>==2);
352 if constexpr (rank<B> == 1)
353 {
355 for (int i=0; i<n; ++i)
356 {
357 result[i][0] = a[i];
358 result[i][1] = b[i];
359 }
360 return result;
361 }
362 else if constexpr (rank<B> == 2)
363 {
365 for (int i=0; i<n; ++i)
366 {
367 result[i][0] = a[i];
368 for (int j=0; j<B::cols; ++j)
369 result[i][1+j] = b[i][j];
370 }
371 return result;
372 }
373 else
374 {
375 // never get here
376 return 0;
377 }
378 }
379
380 template <class Scalar, int n, int m>
382 {
383 return a;
384 }
385
386 template <class Scalar, int n, int m, class ... Rest>
387 auto horzcat(Dune::FieldMatrix<Scalar,n,m> const& a, Rest ... rest)
388 {
389 // Works, but I think it's way too slow unless the compiler
390 // does some magic...
391
392 auto b = horzcat(rest...);
393 using B = decltype(b);
395
396 if constexpr (rank<B> == 1)
397 {
399 for (int i=0; i<n; ++i)
400 {
401 for (int j=0; j<m; ++j)
402 result[i][j] = a[i][j];
403 result[i][m] = b[i];
404 }
405 return result;
406 }
407 else if constexpr (rank<B> == 2)
408 {
410 for (int i=0; i<n; ++i)
411 {
412 for (int j=0; j<m; ++j)
413 result[i][j] = a[i][j];
414 for (int j=0; j<B::cols; ++j)
415 result[i][m+j] = b[i][j];
416 }
417 return result;
418 }
419 else
420 {
421 // never get here
422 return 0;
423 }
424 }
425
426
427 // TODO: generic version via parameter packs?
428 template <class Scalar, int n>
430 Dune::FieldVector<Scalar,n> const& col2,
431 Dune::FieldVector<Scalar,n> const& col3)
432 {
434 for (int i=0; i<n; ++i)
435 {
436 A[i][0] = col1[i]; A[i][1] = col2[i]; A[i][2] = col3[i];
437 }
438 return A;
439 }
440
444 template <class Scalar, int n, int m>
446 {
447 assert(0<=j && j<m);
449 for (int i=0; i<n; ++i)
450 x[i] = A[i][j];
451 return x;
452 }
453
458 template <class Scalar, int n>
460 {
462
463 for(int i=0; i<n; ++i)
464 for(int j=0; j<n; ++j)
465 result[i+j*n] = A[i][j];
466
467 return result;
468 }
469
474 template <int n, class Scalar>
476 {
478
479 for(int i=0; i<n; ++i)
480 for(int j=0; j<n; ++j)
481 result[i][j] = v[i+j*n];
482
483 return result;
484 }
485
486
487
488
493 template <class T, int n, int m>
495 {
496 T x = 0;
497 for (int i=0; i<n; ++i)
498 for (int j=0; j<m; ++j)
499 x += A[i][j] * B[i][j];
500 return x;
501 }
502
503} // end of namespace Kaskade
504
505namespace Dune
506{
507
514 template <class T, int n>
516 {
517 T x = 0;
518 for (int i=0; i<n; ++i)
519 x += A[i][i];
520 return x;
521 }
522
523}
524
530template <class T, int n>
532{
533 static Kaskade::Deprecated dummy("detrminant(A) is deprecated, use A.determinant() instead",2020);
534 return A.determinant();
535}
536
541template <class T, int n>
543{
545 for (int i=0; i<n; ++i)
546 d[i] = A[i][i];
547 return d;
548}
549
554template <class T, int n>
556{
558 for (int i=0; i<n; ++i)
559 I[i][i] = 1;
560 return I;
561}
562
567template <class T>
569{
571 skew[0][1] = -v[2];
572 skew[0][2] = v[1];
573 skew[1][0] = v[2];
574 skew[1][2] = -v[0];
575 skew[2][0] = -v[1];
576 skew[2][1] = v[0];
577 return skew;
578}
579
584template <class T, int n>
586{
587 assert(0<=i && i<n);
589 ei[i] = 1;
590 return ei;
591}
592
596template <class Matrix, bool transposed>
597struct Transpose {};
598
599template <class Scalar, int n, int m, bool transposed>
600struct Transpose<Dune::FieldMatrix<Scalar,n,m>,transposed>
601{
603};
604
605
613template <class MatrixZ, class Matrix>
614void MatMult(MatrixZ& z, Matrix const& x, Matrix const& y)
615{
616 assert(((void*)&z != (void*)&x) && ((void*)&z != (void*)&y));
617 assert(x.M() == y.N());
618
619 z.setSize(x.N(),y.M());
620
621 for (int i=0; i<z.N(); i++ ) {
622 for (int j=0; j<z.M(); j++ ) {
623 typename MatrixZ::block_type temp = 0.0;
624 for (int k=0; k<x.M(); k++)
625 temp += x[i][k]*y[k][j];
626 z[i][j] = temp;
627 }
628 }
629}
630
631
632//---------------------------------------------------------------------
633
639namespace FixDuneDetail
640{
641
642 //TODO: in Dune 2.0 this is not needed anymore!
643 template <int Codim>
644 struct GetIndexOfSubEntity
645 {
646 template <class Cell, class IS>
647 static int value(Cell const& cell, int codim, int entity, IS const& is)
648 {
649 if (codim==Codim)
650 // return is.template subIndex<Codim>(cell,entity);
651 return is.subIndex(cell,entity,Codim);
652 else
653 return GetIndexOfSubEntity<Codim-1>::value(cell,codim,entity,is);
654 }
655 };
656
657 template <>
658 struct GetIndexOfSubEntity<0>
659 {
660 template <class Cell, class IS>
661 static int value(Cell const& cell, int codim, int entity, IS const& is)
662 {
663 assert (codim==0);
664 // return is.template subIndex<0>(cell,entity);
665 return is.subIndex(cell,entity,0);
666 }
667 };
668
669 template <int Codim>
670 struct GetNumberOfSubEntities
671 {
672 template <class Cell>
673 static int value( Cell const& cell, int codim )
674 {
675 if (codim==Codim)
676 return cell.template count<Codim>() ;
677 else
678 return GetNumberOfSubEntities<Codim-1>::value(cell, codim) ;
679 }
680 } ;
681
682 template <>
683 struct GetNumberOfSubEntities<0>
684 {
685 template <class Cell>
686 static int value( Cell const& cell, int codim )
687 {
688 assert (codim==0);
689 return cell.template count<0>();
690 }
691 };
692
693} // End of namespace FixDuneDetail
695
703template <class IndexSet, class Cell>
704size_t subIndex(IndexSet const& is, Cell const& cell, int codim, int subentity)
705{
706 return FixDuneDetail::GetIndexOfSubEntity<Cell::dimension>::value(cell,codim,subentity,is);
707}
708
715template <class Cell>
716int count(Cell const& cell, int codim)
717{
718 return FixDuneDetail::GetNumberOfSubEntities<Cell::dimension>::value(cell, codim) ;
719}
720
721
722// ---------------------------------------------------------------------
723
740template <class LocalCoordinate>
741typename LocalCoordinate::field_type checkInside(Dune::GeometryType const& gt, LocalCoordinate const& x)
742{
743 if (gt.isSimplex())
744 // The reference simplex is the set defined by componentwise x_i>=0 and 1-sum x_i>=0. Thus we return
745 // the negative of the minimum of these conditions.
746 return -std::min(*std::min_element(x.begin(),x.end()),1-x.one_norm());
747 else if (gt.isCube())
748 // The reference cube is the set defined by componentwise xi>=0 and xi_<=1.
749 return -std::min(*std::min_element(x.begin(),x.end()),1-*std::max_element(x.begin(),x.end()));
750 else
751 // Other elements are not (yet) covered. Fallback to standard Dune implementation
752 return Dune::ReferenceElements<typename LocalCoordinate::field_type,
753 LocalCoordinate::dimension>::general(gt).checkInside(x)? 0: 1;
754}
755
765template <class Cell>
766std::pair<Dune::FieldVector<double,Cell::dimension>,Dune::FieldVector<double,Cell::dimension>> boundingBox(Cell const& cell)
767{
769
770 auto geo = cell.geometry();
771 for(int i=0; i<geo.corners(); ++i)
772 {
773 auto corner = geo.corner(i);
774 for(int d=0; d<Cell::dimension; ++d)
775 {
776 boxmin[d] = std::min(boxmin[d],corner[d]);
777 boxmax[d] = std::max(boxmax[d],corner[d]);
778 }
779 }
780 return std::make_pair(boxmin,boxmax);
781}
782
783
785template <class Scalar, int n, int m, class Allocator1, class Allocator2>
787{
788 to.resize(from.dim()*m);
789 for(size_t i=0; i<from.N(); ++i)
790 for(int j=0; j<n; ++j)
791 to[(i*n+j)/m][(i*n+j)%m] = from[i][j];
792}
793
798template <class Scalar, int n, int m, class Allocator>
799void bcrsPrint(Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,n,m>,Allocator> const& A, std::ostream& os=std::cout)
800{
801 for(size_t i0=0; i0<A.N(); ++i0)
802 for(size_t i1=0; i1<n; ++i1)
803 {
804 for(size_t j0=0; j0<A.M(); ++j0)
805 for(size_t j1=0; j1<m; ++j1)
806 if(A.exists(i0,j0)) os << A[i0][j0][i1][j1] << " ";
807 os << std::endl;
808 }
809 os << std::endl;
810}
811
816template <class Scalar, int n, int m, class Allocator>
817std::ostream& operator<<(std::ostream& os, Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,n,m>,Allocator> const& A)
818{
819 bcrsPrint(A,os);
820 return os;
821}
822
823#endif
Convenience class for marking deprecated functions. A static object of this class can be created insi...
Definition: deprecation.hh:35
std::ostream & operator<<(std::ostream &out, DynamicMatrix< Entry > const &A)
pretty output of dense matrices
void transferBlockVector(Dune::BlockVector< Dune::FieldVector< Scalar, n >, Allocator1 > const &from, Dune::BlockVector< Dune::FieldVector< Scalar, m >, Allocator2 > &to)
copy between two block vectors of different element lengths
Definition: fixdune.hh:786
int count(Cell const &cell, int codim)
Computes the number of subentities of codimension c of a given entity.
Definition: fixdune.hh:716
size_t subIndex(IndexSet const &is, Cell const &cell, int codim, int subentity)
Definition: fixdune.hh:704
void bcrsPrint(Dune::BCRSMatrix< Dune::FieldMatrix< Scalar, n, m >, Allocator > const &A, std::ostream &os=std::cout)
Pretty prints the sparse matrix A to the given output stream.
Definition: fixdune.hh:799
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
Dune::FieldVector< T, n > unitVector(int i)
Returns the unit vector with .
Definition: fixdune.hh:585
Dune::FieldMatrix< T, n, m > outerProduct(Dune::FieldVector< T, n > const &x, Dune::FieldVector< T, m > const &y)
outer vector product .
Definition: fixdune.hh:164
Dune::FieldMatrix< T, n, m > asMatrix(Dune::FieldVector< T, n *m > const &x)
Converts a vector of size nm to a matrix of size n x m by filling columns successively.
Definition: fixdune.hh:149
T trace(Dune::FieldMatrix< T, n, n > const &A)
Matrix trace .
Definition: fixdune.hh:515
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Definition: fixdune.hh:110
Dune::FieldMatrix< T, n, n > unitMatrix()
Returns the identity matrix of size n .
Definition: fixdune.hh:555
Dune::FieldMatrix< T, 3, 3 > skewMatrix(Dune::FieldVector< T, 3 > v)
Returns the skew symmetric matrix related to the cross product with (3d) vector v.
Definition: fixdune.hh:568
Dune::FieldVector< T, n > operator+(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Vector addition .
Definition: fixdune.hh:74
Dune::FieldVector< T, n > normalize(Dune::FieldVector< T, n > x)
returns the normalized vector
Definition: fixdune.hh:178
Dune::FieldMatrix< T, 1, 2 > vectorProductMatrix(Dune::FieldVector< T, 2 > const &x)
the matrix satisfying for all
Definition: fixdune.hh:219
T vectorProduct(Dune::FieldVector< T, 2 > const &x, Dune::FieldVector< T, 2 > const &y)
vector product .
Definition: fixdune.hh:209
Dune::FieldVector< T, n > diag(Dune::FieldMatrix< T, n, n > const &A)
Matrix diagonal as a vector.
Definition: fixdune.hh:542
T determinant(Dune::FieldMatrix< T, n, n > const &A)
Matrix determinant .
Definition: fixdune.hh:531
Dune::FieldVector< Scalar, n *n > vectorize(Dune::FieldMatrix< Scalar, n, n > const &A)
matrix entries as vector, concatenating columns
Definition: fixdune.hh:459
Dune::FieldVector< T, n > operator*(Dune::FieldVector< T, n > x, S s)
Scalar-vector multiplication .
Definition: fixdune.hh:51
Dune::FieldVector< T, n > operator-(Dune::FieldVector< T, n > x)
Vector negation .
Definition: fixdune.hh:98
Dune::FieldMatrix< Scalar, n, n > unvectorize(Dune::FieldVector< Scalar, n *n > const &v)
forming quadratic matrix columns of vector segments
Definition: fixdune.hh:475
void MatMult(MatrixZ &z, Matrix const &x, Matrix const &y)
Computes Z = X*Y. X and Y need to be compatible, i.e. X.M()==Y.N() has to hold. No aliasing may occur...
Definition: fixdune.hh:614
Dune::FieldVector< T, n+m > vertcat(Dune::FieldVector< T, n > const &x, Dune::FieldVector< T, m > const &y)
Concatenation of vectors.
Definition: fixdune.hh:191
T contraction(Dune::FieldMatrix< T, n, m > const &A, Dune::FieldMatrix< T, n, m > const &B)
Matrix contraction (Frobenius product) .
Definition: fixdune.hh:494
Dune::FieldVector< T, n *m > asVector(Dune::FieldMatrix< T, n, m > const &x)
Converts a matrix of size n x m to a vector of size n*m by concatenating all the columns.
Definition: fixdune.hh:135
Dune::FieldVector< T, n > min(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise minimum.
Definition: fixdune.hh:122
std::pair< Dune::FieldVector< double, Cell::dimension >, Dune::FieldVector< double, Cell::dimension > > boundingBox(Cell const &cell)
Computes the bounding box of a cell.
Definition: fixdune.hh:766
LocalCoordinate::field_type checkInside(Dune::GeometryType const &gt, LocalCoordinate const &x)
Checks whether a point is inside or outside the reference element, and how much.
Definition: fixdune.hh:741
auto normalForm(Dune::FieldMatrix< T, n, m > const &A)
Definition: fixdune.hh:289
Dune::FieldVector< Scalar, n > column(Dune::FieldMatrix< Scalar, n, m > const &A, int j)
Extracts the j-th column of the given matrix A.
Definition: fixdune.hh:445
auto horzcat(Dune::FieldVector< Scalar, n > const &c1)
Definition: fixdune.hh:328
Definition: scalar.hh:73
Entry field_type
Definition: scalar.hh:77
Dune::FieldMatrix< Scalar, transposed? m:n, transposed? n:m > type
Definition: fixdune.hh:602
Returns the matrix type or its transposed type, depending on the given transpose flag.
Definition: fixdune.hh:597