1
#ifndef DUNE_ALBERTA_MISC_HH
2
#define DUNE_ALBERTA_MISC_HH
6
#include <dune/common/exceptions.hh>
7
#include <dune/common/typetraits.hh>
8
#include <dune/common/forloop.hh>
10
#include <dune/grid/albertagrid/albertaheader.hh>
14
// should the coordinates be cached in a vector (required for ALBERTA 2.0)?
15
#ifndef DUNE_ALBERTA_CACHE_COORDINATES
16
#define DUNE_ALBERTA_CACHE_COORDINATES 1
19
// set to 1 to use generic geometries in AlbertaGrid
20
#ifndef DUNE_ALBERTA_USE_GENERICGEOMETRY
21
#define DUNE_ALBERTA_USE_GENERICGEOMETRY 0
46
static const int dimWorld = DIM_OF_WORLD;
48
typedef ALBERTA REAL Real;
49
typedef ALBERTA REAL_B LocalVector; // in barycentric coordinates
50
typedef ALBERTA REAL_D GlobalVector;
51
typedef ALBERTA REAL_DD GlobalMatrix;
53
#if DUNE_ALBERTA_VERSION >= 0x300
54
typedef ALBERTA AFF_TRAFO AffineTransformation;
56
struct AffineTransformation
63
typedef ALBERTA MESH Mesh;
64
typedef ALBERTA EL Element;
66
static const int meshRefined = MESH_REFINED;
67
static const int meshCoarsened = MESH_COARSENED;
69
static const int InteriorBoundary = INTERIOR;
70
static const int DirichletBoundary = DIRICHLET;
71
#if DUNE_ALBERTA_VERSION >= 0x300
72
typedef ALBERTA BNDRY_TYPE BoundaryId;
74
typedef S_CHAR BoundaryId;
77
typedef U_CHAR ElementType;
79
typedef ALBERTA FE_SPACE DofSpace;
83
// Memory Manipulation Functions
84
// -----------------------------
86
template< class Data >
87
inline Data *memAlloc ( size_t size )
89
return MEM_ALLOC( size, Data );
92
template< class Data >
93
inline Data *memCAlloc ( size_t size )
95
return MEM_CALLOC( size, Data );
98
template< class Data >
99
inline Data *memReAlloc ( Data *ptr, size_t oldSize, size_t newSize )
101
return MEM_REALLOC( ptr, oldSize, newSize, Data );
104
template< class Data >
105
inline void memFree ( Data *ptr, size_t size )
107
return MEM_FREE( ptr, size, Data );
117
typedef GlobalSpace This;
120
typedef GlobalMatrix Matrix;
121
typedef GlobalVector Vector;
124
Matrix identityMatrix_;
129
for( int i = 0; i < dimWorld; ++i )
131
for( int j = 0; j < dimWorld; ++j )
132
identityMatrix_[ i ][ j ] = Real( 0 );
133
identityMatrix_[ i ][ i ] = Real( 1 );
134
nullVector_[ i ] = Real( 0 );
138
static This &instance ()
140
static This theInstance;
145
static const Matrix &identityMatrix ()
147
return instance().identityMatrix_;
150
static const Vector &nullVector ()
152
return instance().nullVector_;
161
template< int dim, int codim >
162
struct NumSubEntities;
165
struct NumSubEntities< dim, 0 >
167
static const int value = 1;
171
struct NumSubEntities< dim, dim >
173
static const int value = dim+1;
177
struct NumSubEntities< 0, 0 >
179
static const int value = 1;
183
struct NumSubEntities< 2, 1 >
185
static const int value = 3;
189
struct NumSubEntities< 3, 1 >
191
static const int value = 4;
195
struct NumSubEntities< 3, 2 >
197
static const int value = 6;
205
template< int dim, int codim >
209
struct CodimType< dim, 0 >
211
static const int value = CENTER;
215
struct CodimType< dim, dim >
217
static const int value = VERTEX;
221
struct CodimType< 2, 1 >
223
static const int value = EDGE;
227
struct CodimType< 3, 1 >
229
static const int value = FACE;
233
struct CodimType< 3, 2 >
235
static const int value = EDGE;
246
typedef ALBERTA FLAGS Flags;
248
static const Flags nothing = FILL_NOTHING;
250
static const Flags coords = FILL_COORDS;
252
static const Flags neighbor = FILL_NEIGH;
254
static const Flags orientation = (dim == 3 ? FILL_ORIENTATION : FILL_NOTHING);
256
static const Flags projection = FILL_PROJECTION;
258
#if DUNE_ALBERTA_VERSION >= 0x300
259
static const Flags elementType = FILL_NOTHING;
261
static const Flags elementType = (dim == 3 ? FILL_EL_TYPE : FILL_NOTHING);
264
#if DUNE_ALBERTA_VERSION >= 0x300
265
static const Flags boundaryId = FILL_MACRO_WALLS;
267
static const Flags boundaryId = FILL_BOUND;
270
#if DUNE_ALBERTA_VERSION >= 0x300
271
static const Flags nonPeriodic = FILL_NON_PERIODIC;
273
static const Flags nonPeriodic = FILL_NOTHING;
276
static const Flags all = coords | neighbor | boundaryId | nonPeriodic
277
| orientation | projection | elementType;
279
#if DUNE_ALBERTA_VERSION >= 0x300
280
static const Flags standardWithCoords = all & ~nonPeriodic & ~projection;
282
static const Flags standardWithCoords = all;
285
#if DUNE_ALBERTA_CACHE_COORDINATES
286
static const Flags standard = standardWithCoords & ~coords;
288
static const Flags standard = standardWithCoords;
298
struct RefinementEdge
300
static const int value = 0;
304
struct RefinementEdge< 2 >
306
static const int value = 2;
311
// Dune2AlbertaNumbering
312
// ---------------------
314
template< int dim, int codim >
315
struct Dune2AlbertaNumbering
317
static int apply ( const int i )
319
assert( (i >= 0) && (i < NumSubEntities< dim, codim >::value) );
325
struct Dune2AlbertaNumbering< 3, 2 >
327
static const int numSubEntities = NumSubEntities< 3, 2 >::value;
329
static int apply ( const int i )
331
assert( (i >= 0) && (i < numSubEntities) );
332
static int dune2alberta[ numSubEntities ] = { 0, 3, 1, 2, 4, 5 };
333
return dune2alberta[ i ];
339
// Generic2AlbertaNumbering
340
// ------------------------
342
template< int dim, int codim >
343
struct Generic2AlbertaNumbering
345
static int apply ( const int i )
347
assert( (i >= 0) && (i < NumSubEntities< dim, codim >::value) );
353
struct Generic2AlbertaNumbering< dim, 1 >
355
static int apply ( const int i )
357
assert( (i >= 0) && (i < NumSubEntities< dim, 1 >::value) );
363
struct Generic2AlbertaNumbering< 1, 1 >
365
static int apply ( const int i )
367
assert( (i >= 0) && (i < NumSubEntities< 1, 1 >::value) );
373
struct Generic2AlbertaNumbering< 3, 2 >
375
static const int numSubEntities = NumSubEntities< 3, 2 >::value;
377
static int apply ( const int i )
379
assert( (i >= 0) && (i < numSubEntities) );
380
static int generic2alberta[ numSubEntities ] = { 0, 1, 3, 2, 4, 5 };
381
return generic2alberta[ i ];
390
template< int dim, template< int, int > class Numbering = Generic2AlbertaNumbering >
393
typedef NumberingMap< dim, Numbering > This;
395
template< int codim >
398
int *dune2alberta_[ dim+1 ];
399
int *alberta2dune_[ dim+1 ];
400
int numSubEntities_[ dim+1 ];
402
NumberingMap ( const This & );
403
This &operator= ( const This & );
408
ForLoop< Initialize, 0, dim >::apply( *this );
413
for( int codim = 0; codim <= dim; ++codim )
415
delete[]( dune2alberta_[ codim ] );
416
delete[]( alberta2dune_[ codim ] );
420
int dune2alberta ( int codim, int i ) const
422
assert( (codim >= 0) && (codim <= dim) );
423
assert( (i >= 0) && (i < numSubEntities( codim )) );
424
return dune2alberta_[ codim ][ i ];
427
int alberta2dune ( int codim, int i ) const
429
assert( (codim >= 0) && (codim <= dim) );
430
assert( (i >= 0) && (i < numSubEntities( codim )) );
431
return alberta2dune_[ codim ][ i ];
434
int numSubEntities ( int codim ) const
436
assert( (codim >= 0) && (codim <= dim) );
437
return numSubEntities_[ codim ];
443
// NumberingMap::Initialize
444
// ------------------------
446
template< int dim, template< int, int > class Numbering >
447
template< int codim >
448
struct NumberingMap< dim, Numbering >::Initialize
450
static const int numSubEntities = NumSubEntities< dim, codim >::value;
452
static void apply ( NumberingMap< dim, Numbering > &map )
454
map.numSubEntities_[ codim ] = numSubEntities;
455
map.dune2alberta_[ codim ] = new int[ numSubEntities ];
456
map.alberta2dune_[ codim ] = new int[ numSubEntities ];
458
for( int i = 0; i < numSubEntities; ++i )
460
const int j = Numbering< dim, codim >::apply( i );
461
map.dune2alberta_[ codim ][ i ] = j;
462
map.alberta2dune_[ codim ][ j ] = i;
472
template< int dim, int codim >
476
struct MapVertices< dim, 0 >
478
static int apply ( int subEntity, int vertex )
480
assert( subEntity == 0 );
481
assert( (vertex >= 0) && (vertex <= NumSubEntities< dim, dim >::value) );
487
struct MapVertices< 2, 1 >
489
static int apply ( int subEntity, int vertex )
491
assert( (subEntity >= 0) && (subEntity < 3) );
492
assert( (vertex >= 0) && (vertex < 2) );
493
//static const int map[ 3 ][ 2 ] = { {1,2}, {2,0}, {0,1} };
494
static const int map[ 3 ][ 2 ] = { {1,2}, {0,2}, {0,1} };
495
return map[ subEntity ][ vertex ];
500
struct MapVertices< 3, 1 >
502
static int apply ( int subEntity, int vertex )
504
assert( (subEntity >= 0) && (subEntity < 4) );
505
assert( (vertex >= 0) && (vertex < 3) );
506
//static const int map[ 4 ][ 3 ] = { {1,2,3}, {0,3,2}, {0,1,3}, {0,2,1} };
507
static const int map[ 4 ][ 3 ] = { {1,2,3}, {0,2,3}, {0,1,3}, {0,1,2} };
508
return map[ subEntity ][ vertex ];
513
struct MapVertices< 3, 2 >
515
static int apply ( int subEntity, int vertex )
517
assert( (subEntity >= 0) && (subEntity < 6) );
518
assert( (vertex >= 0) && (vertex < 2) );
519
static const int map[ 6 ][ 2 ] = { {0,1}, {0,2}, {0,3}, {1,2}, {1,3}, {2,3} };
520
return map[ subEntity ][ vertex ];
525
struct MapVertices< dim, dim >
527
static int apply ( int subEntity, int vertex )
529
assert( (subEntity >= 0) && (subEntity < NumSubEntities< dim, 1 >::value) );
530
assert( vertex == 0 );
540
// ******************************************************************
541
// Meaning of the twist (same as in ALU)
542
// -------------------------------------
544
// Consider a fixed ordering of the vertices v_1, ... v_n of a face
545
// (here, we assume their indices to be increasing). Denote by k the
546
// local number of a vertex v within the element and by t the twist.
547
// Then, v = v_j, where j is computed by the following formula:
549
// / (2n + 1 - k + t) % n, if t < 0
551
// \ (k + t) % n, if t >= 0
553
// Note: We use the order of the 0-th vertex dof to assign the twist.
554
// This is ok for two reasons:
555
// - ALBERTA preserves the relative order of the dofs during
557
// - ALBERTA enforces the first vertex dof admin to be periodic.
558
// ******************************************************************
560
template< int dim, int subdim >
563
static const int numSubEntities = NumSubEntities< dim, dim-subdim >::value;
565
static const int minTwist = 0;
566
static const int maxTwist = 0;
568
static int twist ( const Element *element, int subEntity )
570
assert( (subEntity >= 0) && (subEntity < numSubEntities) );
576
struct Twist< dim, 1 >
578
static const int numSubEntities = NumSubEntities< dim, dim-1 >::value;
580
static const int minTwist = 0;
581
static const int maxTwist = 1;
583
static int twist ( const Element *element, int subEntity )
585
assert( (subEntity >= 0) && (subEntity < numSubEntities) );
586
const int numVertices = NumSubEntities< 1, 1 >::value;
587
int dof[ numVertices ];
588
for( int i = 0; i < numVertices; ++i )
590
const int j = MapVertices< dim, dim-1 >::apply( subEntity, i );
591
dof[ i ] = element->dof[ j ][ 0 ];
593
return (dof[ 0 ] < dof[ 1 ] ? 0 : 1);
601
static const int minTwist = 0;
602
static const int maxTwist = 0;
604
static int twist ( const Element *element, int subEntity )
606
assert( subEntity == 0 );
613
struct Twist< dim, 2 >
615
static const int numSubEntities = NumSubEntities< dim, dim-2 >::value;
617
static const int minTwist = -3;
618
static const int maxTwist = 2;
620
static int twist ( const Element *element, int subEntity )
622
assert( (subEntity >= 0) && (subEntity < numSubEntities) );
623
const int numVertices = NumSubEntities< 2, 2 >::value;
624
int dof[ numVertices ];
625
for( int i = 0; i < numVertices; ++i )
627
const int j = MapVertices< dim, dim-2 >::apply( subEntity, i );
628
dof[ i ] = element->dof[ j ][ 0 ];
631
const int twist[ 8 ] = { -2, 1, 666, -1, 2, 666, -3, 0 };
632
const int k = int( dof[ 0 ] < dof[ 1 ] )
633
| (int( dof[ 0 ] < dof[ 2 ] ) << 1)
634
| (int( dof[ 1 ] < dof[ 2 ] ) << 2);
635
assert( twist[ k ] != 666 );
644
static const int minTwist = 0;
645
static const int maxTwist = 0;
647
static int twist ( const Element *element, int subEntity )
649
assert( subEntity == 0 );
657
inline int applyTwist ( int twist, int i )
659
const int numCorners = NumSubEntities< dim, dim >::value;
660
return (twist < 0 ? (2*numCorners + 1 - i + twist) : i + twist) % numCorners;
664
inline int applyInverseTwist ( int twist, int i )
666
const int numCorners = NumSubEntities< dim, dim >::value;
667
return (twist < 0 ? (2*numCorners + 1 - i + twist) : numCorners + i - twist) % numCorners;
674
#endif // #if HAVE_ALBERTA
676
#endif // #ifndef DUNE_ALBERTA_MISC_HH