1#ifndef DUNE_SPGRID_GEOMETRYCACHE_HH
2#define DUNE_SPGRID_GEOMETRYCACHE_HH
10#include <dune/grid/spgrid/direction.hh>
11#include <dune/grid/spgrid/normal.hh>
19 template<
int dim,
int codim >
20 struct SPGeometryPattern
22 typedef SPDirection< dim > Direction;
25 explicit SPGeometryPattern ( Direction dir );
27 int nonzero (
const int k )
const;
28 int zero (
const int k )
const;
31 int nonzero_[ dim - codim ];
36 struct SPGeometryPattern< dim, 0 >
38 typedef SPDirection< dim > Direction;
40 SPGeometryPattern () =
default;
41 explicit SPGeometryPattern ( Direction ) {}
43 int nonzero (
const int k )
const;
44 int zero (
const int k )
const;
48 struct SPGeometryPattern< dim, dim >
50 typedef SPDirection< dim > Direction;
52 SPGeometryPattern () =
default;
53 explicit SPGeometryPattern ( Direction ) {}
55 int nonzero (
const int k )
const;
56 int zero (
const int k )
const;
60 struct SPGeometryPattern< 0, 0 >
62 typedef SPDirection< 0 > Direction;
64 SPGeometryPattern () =
default;
65 explicit SPGeometryPattern ( Direction ) {}
67 int nonzero (
const int k )
const;
68 int zero (
const int k )
const;
76 template<
class ct,
int dim,
int mydim >
77 class SPJacobianTransposed
78 :
private SPGeometryPattern< dim, dim - mydim >
80 typedef SPGeometryPattern< dim, dim - mydim > Pattern;
83 typedef ct field_type;
84 typedef ct value_type;
86 typedef std::size_t size_type;
88 static const int rows = mydim;
89 static const int cols = dim;
91 typedef FieldVector< field_type, dim > GlobalVector;
95 typedef typename Dune::FieldTraits< field_type >::real_type real_type;
97 SPJacobianTransposed () =
default;
99 SPJacobianTransposed (
const GlobalVector &h, SPDirection< dim > dir )
100 : Pattern(
std::move( dir ) )
102 for(
int k = 0; k < rows; ++k )
103 h_[ k ] = h[ pattern().nonzero( k ) ];
106 operator FieldMatrix ()
const;
108 template<
class X,
class Y >
void mv (
const X &x, Y &y )
const;
109 template<
class X,
class Y >
void mtv (
const X &x, Y &y )
const;
110 template<
class X,
class Y >
void mhv (
const X &x, Y &y )
const;
112 template<
class X,
class Y >
void umv (
const X &x, Y &y )
const;
113 template<
class X,
class Y >
void umtv (
const X &x, Y &y )
const;
114 template<
class X,
class Y >
void umhv (
const X &x, Y &y )
const;
116 template<
class X,
class Y >
void mmv (
const X &x, Y &y )
const;
117 template<
class X,
class Y >
void mmtv (
const X &x, Y &y )
const;
118 template<
class X,
class Y >
void mmhv (
const X &x, Y &y )
const;
120 template<
class X,
class Y >
void usmv (
const field_type &alpha,
const X &x, Y &y )
const;
121 template<
class X,
class Y >
void usmtv (
const field_type &alpha,
const X &x, Y &y )
const;
122 template<
class X,
class Y >
void usmhv (
const field_type &alpha,
const X &x, Y &y )
const;
124 field_type det ()
const;
126 field_type determinant ()
const
131 DUNE_THROW( FMatrixError,
"There is no determinant for a " << rows <<
"x" << cols <<
" matrix" );
134 real_type frobenius_norm ()
const {
return h().two_norm(); }
135 real_type frobenius_norm2 ()
const {
return h().two_norm2(); }
136 real_type infinity_norm ()
const {
return h().infinity_norm(); }
137 real_type infinity_norm_real ()
const {
return h().infinity_norm_real(); }
140 const Pattern &pattern ()
const {
return static_cast< const Pattern &
>( *this ); }
141 const LocalVector &h ()
const {
return h_; }
151 template<
class ct,
int dim,
int mydim >
152 struct FieldTraits< SPJacobianTransposed< ct, dim, mydim > >
154 typedef typename FieldTraits< ct >::field_type field_type;
155 typedef typename FieldTraits< ct >::real_type real_type;
163 template<
class ct,
int dim,
int mydim >
164 class SPJacobianInverseTransposed
165 :
private SPGeometryPattern< dim, dim - mydim >
167 typedef SPGeometryPattern< dim, dim - mydim > Pattern;
170 typedef ct field_type;
171 typedef ct value_type;
173 typedef std::size_t size_type;
175 static const int rows = dim;
176 static const int cols = mydim;
178 typedef FieldVector< field_type, dim > GlobalVector;
182 typedef typename Dune::FieldTraits< field_type >::real_type real_type;
184 SPJacobianInverseTransposed () =
default;
186 SPJacobianInverseTransposed (
const GlobalVector &h, SPDirection< dim > dir )
189 for(
int k = 0; k < cols; ++k )
190 hInv_[ k ] = field_type( 1 ) / h[ pattern().nonzero( k ) ];
193 operator FieldMatrix ()
const;
195 template<
class X,
class Y >
void mv (
const X &x, Y &y )
const;
196 template<
class X,
class Y >
void mtv (
const X &x, Y &y )
const;
197 template<
class X,
class Y >
void mhv (
const X &x, Y &y )
const;
199 template<
class X,
class Y >
void umv (
const X &x, Y &y )
const;
200 template<
class X,
class Y >
void umtv (
const X &x, Y &y )
const;
201 template<
class X,
class Y >
void umhv (
const X &x, Y &y )
const;
203 template<
class X,
class Y >
void usmv (
const field_type &alpha,
const X &x, Y &y )
const;
204 template<
class X,
class Y >
void usmtv (
const field_type &alpha,
const X &x, Y &y )
const;
205 template<
class X,
class Y >
void usmhv (
const field_type &alpha,
const X &x, Y &y )
const;
207 template<
class X,
class Y >
void mmv (
const X &x, Y &y )
const;
208 template<
class X,
class Y >
void mmtv (
const X &x, Y &y )
const;
209 template<
class X,
class Y >
void mmhv (
const X &x, Y &y )
const;
211 field_type det ()
const;
213 field_type determinant ()
const
218 DUNE_THROW( FMatrixError,
"There is no determinant for a " << rows <<
"x" << cols <<
" matrix" );
221 real_type frobenius_norm ()
const {
return hInv().two_norm(); }
222 real_type frobenius_norm2 ()
const {
return hInv().two_norm2(); }
223 real_type infinity_norm ()
const {
return hInv().infinity_norm(); }
224 real_type infinity_norm_real ()
const {
return hInv().infinity_norm_real(); }
227 const Pattern &pattern ()
const {
return static_cast< const Pattern &
>( *this ); }
228 const LocalVector &hInv ()
const {
return hInv_; }
238 template<
class ct,
int dim,
int mydim >
239 struct FieldTraits< SPJacobianInverseTransposed< ct, dim, mydim > >
241 typedef typename FieldTraits< ct >::field_type field_type;
242 typedef typename FieldTraits< ct >::real_type real_type;
250 template<
class ct,
int dim,
int codim >
251 class SPGeometryCache
253 typedef SPGeometryCache< ct, dim, codim > This;
258 static const int dimension = dim;
259 static const int codimension = codim;
260 static const int mydimension = dimension - codimension;
262 typedef SPDirection< dimension > Direction;
265 typedef FieldVector< ctype, mydimension > LocalVector;
267 typedef SPJacobianTransposed< ctype, dimension, mydimension > JacobianTransposed;
268 typedef SPJacobianInverseTransposed< ctype, dimension, mydimension > JacobianInverseTransposed;
270 SPGeometryCache (
const GlobalVector &h, Direction dir )
271 : jacobianTransposed_( h, dir ), jacobianInverseTransposed_( h, dir ), volume_( jacobianTransposed_.det() )
274 const ctype &volume ()
const {
return volume_; }
275 const JacobianTransposed &jacobianTransposed ()
const {
return jacobianTransposed_; }
276 const JacobianInverseTransposed &jacobianInverseTransposed ()
const {
return jacobianInverseTransposed_; }
278 JacobianTransposed jacobianTransposed_;
279 JacobianInverseTransposed jacobianInverseTransposed_;
288 template<
int dim,
int codim >
289 inline SPGeometryPattern< dim, codim >::SPGeometryPattern ()
291 const int mydim = dim - codim;
292 for(
int k = 0; k < mydim; ++k )
294 for(
int k = 0; k < codim; ++k )
295 zero_[ k ] = mydim + k;
298 template<
int dim,
int codim >
299 inline SPGeometryPattern< dim, codim >::SPGeometryPattern ( Direction dir )
302 for(
int j = 0; j < dim; ++j )
309 assert( k == dim - codim );
313 template<
int dim,
int codim >
314 inline int SPGeometryPattern< dim, codim >::nonzero (
const int k )
const
316 assert( (k >= 0) && (k < dim - codim) );
317 return nonzero_[ k ];
322 inline int SPGeometryPattern< dim, 0 >::nonzero (
const int k )
const
324 assert( (k >= 0) && (k < dim) );
330 inline int SPGeometryPattern< dim, dim >::nonzero (
const int k )
const
337 inline int SPGeometryPattern< 0, 0 >::nonzero (
const int k )
const
344 template<
int dim,
int codim >
345 inline int SPGeometryPattern< dim, codim >::zero (
const int k )
const
347 assert( (k >= 0) && (k < codim) );
353 inline int SPGeometryPattern< dim, 0 >::zero (
const int k )
const
361 inline int SPGeometryPattern< dim, dim >::zero (
const int k )
const
363 assert( (k >= 0) && (k < dim) );
368 inline int SPGeometryPattern< 0, 0 >::zero (
const int k )
const
379 template<
class ct,
int dim,
int mydim >
380 inline SPJacobianTransposed< ct, dim, mydim >::operator FieldMatrix ()
const
382 FieldMatrix matrix( field_type( 0 ) );
383 for(
int k = 0; k < rows; ++k )
384 matrix[ k ][ pattern().nonzero( k ) ] = h()[ k ];
389 template<
class ct,
int dim,
int mydim >
390 template<
class X,
class Y >
391 inline void SPJacobianTransposed< ct, dim, mydim >::mv (
const X &x, Y &y )
const
393 for(
int k = 0; k < rows; ++k )
394 y[ k ] = h()[ k ] * x[ pattern().nonzero( k ) ];
398 template<
class ct,
int dim,
int mydim >
399 template<
class X,
class Y >
400 inline void SPJacobianTransposed< ct, dim, mydim >::mtv (
const X &x, Y &y )
const
402 for(
int k = 0; k < rows; ++k )
403 y[ pattern().nonzero( k ) ] = h()[ k ] * x[ k ];
404 for(
int k = 0; k < cols - rows; ++k )
405 y[ pattern().zero( k ) ] = field_type( 0 );
409 template<
class ct,
int dim,
int mydim >
410 template<
class X,
class Y >
411 inline void SPJacobianTransposed< ct, dim, mydim >::mhv (
const X &x, Y &y )
const
413 for(
int k = 0; k < rows; ++k )
415 for(
int k = 0; k < cols - rows; ++k )
416 y[ pattern().zero( k ) ] = field_type( 0 );
420 template<
class ct,
int dim,
int mydim >
421 template<
class X,
class Y >
422 inline void SPJacobianTransposed< ct, dim, mydim >::umv (
const X &x, Y &y )
const
424 for(
int k = 0; k < rows; ++k )
425 y[ k ] += h()[ k ] * x[ pattern().nonzero( k ) ];
429 template<
class ct,
int dim,
int mydim >
430 template<
class X,
class Y >
431 inline void SPJacobianTransposed< ct, dim, mydim >::umtv (
const X &x, Y &y )
const
433 for(
int k = 0; k < rows; ++k )
434 y[ pattern().nonzero( k ) ] += h()[ k ] * x[ k ];
438 template<
class ct,
int dim,
int mydim >
439 template<
class X,
class Y >
440 inline void SPJacobianTransposed< ct, dim, mydim >::umhv (
const X &x, Y &y )
const
442 for(
int k = 0; k < rows; ++k )
447 template<
class ct,
int dim,
int mydim >
448 template<
class X,
class Y >
449 inline void SPJacobianTransposed< ct, dim, mydim >::usmv (
const field_type &alpha,
const X &x, Y &y )
const
451 for(
int k = 0; k < rows; ++k )
452 y[ k ] += alpha * h()[ k ] * x[ pattern().nonzero( k ) ];
456 template<
class ct,
int dim,
int mydim >
457 template<
class X,
class Y >
458 inline void SPJacobianTransposed< ct, dim, mydim >::usmtv (
const field_type &alpha,
const X &x, Y &y )
const
460 for(
int k = 0; k < rows; ++k )
461 y[ pattern().nonzero( k ) ] += alpha * h()[ k ] * x[ k ];
465 template<
class ct,
int dim,
int mydim >
466 template<
class X,
class Y >
467 inline void SPJacobianTransposed< ct, dim, mydim >::usmhv (
const field_type &alpha,
const X &x, Y &y )
const
469 for(
int k = 0; k < rows; ++k )
470 y[ pattern().nonzero( k ) ] += alpha *
conjugateComplex( h()[ k ] ) * x[ k ];
474 template<
class ct,
int dim,
int mydim >
475 template<
class X,
class Y >
476 inline void SPJacobianTransposed< ct, dim, mydim >::mmv (
const X &x, Y &y )
const
478 for(
int k = 0; k < rows; ++k )
479 y[ k ] -= h()[ k ] * x[ pattern().nonzero( k ) ];
483 template<
class ct,
int dim,
int mydim >
484 template<
class X,
class Y >
485 inline void SPJacobianTransposed< ct, dim, mydim >::mmtv (
const X &x, Y &y )
const
487 for(
int k = 0; k < rows; ++k )
488 y[ pattern().nonzero( k ) ] -= h()[ k ] * x[ k ];
492 template<
class ct,
int dim,
int mydim >
493 template<
class X,
class Y >
494 inline void SPJacobianTransposed< ct, dim, mydim >::mmhv (
const X &x, Y &y )
const
496 for(
int k = 0; k < rows; ++k )
501 template<
class ct,
int dim,
int mydim >
502 inline typename SPJacobianTransposed< ct, dim, mydim >::field_type SPJacobianTransposed< ct, dim, mydim >::det ()
const
505 for(
int k = 0; k < rows; ++k )
515 template<
class ct,
int dim,
int mydim >
516 inline SPJacobianInverseTransposed< ct, dim, mydim >::operator FieldMatrix ()
const
518 FieldMatrix matrix( field_type( 0 ) );
519 for(
int k = 0; k < cols; ++k )
520 matrix[ pattern().nonzero( k ) ][ k ] = hInv()[ k ];
525 template<
class ct,
int dim,
int mydim >
526 template<
class X,
class Y >
527 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mv (
const X &x, Y &y )
const
529 for(
int k = 0; k < cols; ++k )
530 y[ pattern().nonzero( k ) ] = hInv()[ k ] * x[ k ];
531 for(
int k = 0; k < rows - cols; ++k )
532 y[ pattern().zero( k ) ] = field_type( 0 );
536 template<
class ct,
int dim,
int mydim >
537 template<
class X,
class Y >
538 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mtv (
const X &x, Y &y )
const
540 for(
int k = 0; k < cols; ++k )
541 y[ k ] = hInv()[ k ] * x[ pattern().nonzero( k ) ];
545 template<
class ct,
int dim,
int mydim >
546 template<
class X,
class Y >
547 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mhv (
const X &x, Y &y )
const
549 for(
int k = 0; k < cols; ++k )
554 template<
class ct,
int dim,
int mydim >
555 template<
class X,
class Y >
556 inline void SPJacobianInverseTransposed< ct, dim, mydim >::umv (
const X &x, Y &y )
const
558 for(
int k = 0; k < cols; ++k )
559 y[ pattern().nonzero( k ) ] += hInv()[ k ] * x[ k ];
563 template<
class ct,
int dim,
int mydim >
564 template<
class X,
class Y >
565 inline void SPJacobianInverseTransposed< ct, dim, mydim >::umtv (
const X &x, Y &y )
const
567 for(
int k = 0; k < cols; ++k )
568 y[ k ] += hInv()[ k ] * x[ pattern().nonzero( k ) ];
572 template<
class ct,
int dim,
int mydim >
573 template<
class X,
class Y >
574 inline void SPJacobianInverseTransposed< ct, dim, mydim >::umhv (
const X &x, Y &y )
const
576 for(
int k = 0; k < cols; ++k )
581 template<
class ct,
int dim,
int mydim >
582 template<
class X,
class Y >
583 inline void SPJacobianInverseTransposed< ct, dim, mydim >::usmv (
const field_type &alpha,
const X &x, Y &y )
const
585 for(
int k = 0; k < cols; ++k )
586 y[ pattern().nonzero( k ) ] += alpha * hInv()[ k ] * x[ k ];
590 template<
class ct,
int dim,
int mydim >
591 template<
class X,
class Y >
592 inline void SPJacobianInverseTransposed< ct, dim, mydim >::usmtv (
const field_type &alpha,
const X &x, Y &y )
const
594 for(
int k = 0; k < cols; ++k )
595 y[ k ] += alpha * hInv()[ k ] * x[ pattern().nonzero( k ) ];
599 template<
class ct,
int dim,
int mydim >
600 template<
class X,
class Y >
601 inline void SPJacobianInverseTransposed< ct, dim, mydim >::usmhv (
const field_type &alpha,
const X &x, Y &y )
const
603 for(
int k = 0; k < cols; ++k )
604 y[ k ] += alpha *
conjugateComplex( hInv()[ k ] ) * x[ pattern().nonzero( k ) ];
608 template<
class ct,
int dim,
int mydim >
609 template<
class X,
class Y >
610 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mmv (
const X &x, Y &y )
const
612 for(
int k = 0; k < cols; ++k )
613 y[ pattern().nonzero( k ) ] -= hInv()[ k ] * x[ k ];
617 template<
class ct,
int dim,
int mydim >
618 template<
class X,
class Y >
619 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mmtv (
const X &x, Y &y )
const
621 for(
int k = 0; k < cols; ++k )
622 y[ k ] -= hInv()[ k ] * x[ pattern().nonzero( k ) ];
626 template<
class ct,
int dim,
int mydim >
627 template<
class X,
class Y >
628 inline void SPJacobianInverseTransposed< ct, dim, mydim >::mmhv (
const X &x, Y &y )
const
630 for(
int k = 0; k < cols; ++k )
635 template<
class ct,
int dim,
int mydim >
636 inline typename SPJacobianInverseTransposed< ct, dim, mydim >::field_type SPJacobianInverseTransposed< ct, dim, mydim >::det ()
const
639 for(
int k = 0; k < cols; ++k )
A dense n x m matrix.
Definition: fmatrix.hh:117
A few common exception classes.
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
Dune namespace.
Definition: alignedallocator.hh:13
K conjugateComplex(const K &x)
compute conjugate complex of x
Definition: math.hh:164