00001 #ifndef DUNE_ALBERTA_MISC_HH
00002 #define DUNE_ALBERTA_MISC_HH
00003
00004 #include <cassert>
00005
00006 #include <dune/common/exceptions.hh>
00007
00008 #include <dune/grid/genericgeometry/codimtable.hh>
00009 #include <dune/grid/genericgeometry/misc.hh>
00010
00011 #include <dune/grid/albertagrid/albertaheader.hh>
00012 #include <dune/grid/albertagrid/referencetopo.hh>
00013
00014 #if HAVE_ALBERTA
00015
00016 namespace Dune
00017 {
00018
00019
00020
00021
00022 class AlbertaError
00023 : public Exception
00024 {};
00025
00026 class AlbertaIOError
00027 : public IOError
00028 {};
00029
00030
00031
00032 namespace Alberta
00033 {
00034
00035
00036
00037
00038 using GenericGeometry::ForLoop;
00039 using GenericGeometry::ProtectedIf;
00040 using GenericGeometry::CodimTable;
00041
00042 static const int dimWorld = DIM_OF_WORLD;
00043 #if DUNE_ALBERTA_VERSION < 0x200
00044 static const int dimGrid = DIM;
00045 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00046
00047 typedef ALBERTA REAL Real;
00048 typedef ALBERTA REAL_D GlobalVector;
00049 typedef ALBERTA REAL_DD GlobalMatrix;
00050
00051 #if DUNE_ALBERTA_VERSION >= 0x201
00052 typedef ALBERTA AFF_TRAFO AffineTransformation;
00053 #else
00054 struct AffineTransformation
00055 {
00056 GlobalMatrix M;
00057 GlobalVector t;
00058 };
00059 #endif
00060
00061 typedef ALBERTA MESH Mesh;
00062 typedef ALBERTA MACRO_EL MacroElement;
00063 typedef ALBERTA EL Element;
00064
00065 static const int meshRefined = MESH_REFINED;
00066 static const int meshCoarsened = MESH_COARSENED;
00067
00068 static const int InteriorBoundary = INTERIOR;
00069 static const int DirichletBoundary = DIRICHLET;
00070 #if DUNE_ALBERTA_VERSION >= 0x201
00071 typedef ALBERTA BNDRY_TYPE BoundaryId;
00072 #else
00073 typedef S_CHAR BoundaryId;
00074 #endif
00075 #if DUNE_ALBERTA_VERSION < 0x200
00076 typedef ALBERTA BOUNDARY Boundary;
00077 #endif
00078
00079 typedef ALBERTA FE_SPACE DofSpace;
00080
00081
00082
00083
00084
00085
00086 template< class Data >
00087 inline Data *memAlloc ( size_t size )
00088 {
00089 return MEM_ALLOC( size, Data );
00090 }
00091
00092 template< class Data >
00093 inline Data *memCAlloc ( size_t size )
00094 {
00095 return MEM_CALLOC( size, Data );
00096 }
00097
00098 template< class Data >
00099 inline Data *memReAlloc ( Data *ptr, size_t oldSize, size_t newSize )
00100 {
00101 return MEM_REALLOC( ptr, oldSize, newSize, Data );
00102 }
00103
00104 template< class Data >
00105 inline void memFree ( Data *ptr, size_t size )
00106 {
00107 return MEM_FREE( ptr, size, Data );
00108 }
00109
00110
00111
00112
00113
00114
00115 class GlobalSpace
00116 {
00117 typedef GlobalSpace This;
00118
00119 public:
00120 typedef GlobalMatrix Matrix;
00121 typedef GlobalVector Vector;
00122
00123 private:
00124 Matrix identityMatrix_;
00125 Vector nullVector_;
00126
00127 GlobalSpace ()
00128 {
00129 for( int i = 0; i < dimWorld; ++i )
00130 {
00131 for( int j = 0; j < dimWorld; ++j )
00132 identityMatrix_[ i ][ j ] = Real( 0 );
00133 identityMatrix_[ i ][ i ] = Real( 1 );
00134 nullVector_[ i ] = Real( 0 );
00135 }
00136 }
00137
00138 static This &instance ()
00139 {
00140 static This theInstance;
00141 return theInstance;
00142 }
00143
00144 public:
00145 static const Matrix &identityMatrix ()
00146 {
00147 return instance().identityMatrix_;
00148 }
00149
00150 static const Vector &nullVector ()
00151 {
00152 return instance().nullVector_;
00153 }
00154 };
00155
00156
00157
00158
00159
00160
00161 template< int dim, int codim >
00162 struct NumSubEntities;
00163
00164 template< int dim >
00165 struct NumSubEntities< dim, 0 >
00166 {
00167 static const int value = 1;
00168 };
00169
00170 template< int dim >
00171 struct NumSubEntities< dim, dim >
00172 {
00173 static const int value = dim+1;
00174 };
00175
00176 template<>
00177 struct NumSubEntities< 0, 0 >
00178 {
00179 static const int value = 1;
00180 };
00181
00182 template<>
00183 struct NumSubEntities< 2, 1 >
00184 {
00185 static const int value = 3;
00186 };
00187
00188 template<>
00189 struct NumSubEntities< 3, 1 >
00190 {
00191 static const int value = 4;
00192 };
00193
00194 template<>
00195 struct NumSubEntities< 3, 2 >
00196 {
00197 static const int value = 6;
00198 };
00199
00200
00201
00202
00203
00204
00205 template< int dim, int codim >
00206 struct CodimType;
00207
00208 template< int dim >
00209 struct CodimType< dim, 0 >
00210 {
00211 static const int value = CENTER;
00212 };
00213
00214 template< int dim >
00215 struct CodimType< dim, dim >
00216 {
00217 static const int value = VERTEX;
00218 };
00219
00220 template<>
00221 struct CodimType< 2, 1 >
00222 {
00223 static const int value = EDGE;
00224 };
00225
00226 #if (DUNE_ALBERTA_VERSION >= 0x200) || (DIM == 3)
00227 template<>
00228 struct CodimType< 3, 1 >
00229 {
00230 static const int value = FACE;
00231 };
00232
00233 template<>
00234 struct CodimType< 3, 2 >
00235 {
00236 static const int value = EDGE;
00237 };
00238 #endif
00239
00240
00241
00242
00243
00244
00245 template< int dim >
00246 struct FillFlags
00247 {
00248 typedef ALBERTA FLAGS Flags;
00249
00250 static const Flags nothing = FILL_NOTHING;
00251
00252 static const Flags coords = FILL_COORDS;
00253
00254 static const Flags neighbor = FILL_NEIGH;
00255
00256 static const Flags orientation = (dim == 3 ? FILL_ORIENTATION : FILL_NOTHING);
00257
00258 #if DUNE_ALBERTA_VERSION >= 0x201
00259 static const Flags elementType = FILL_NOTHING;
00260 #else
00261 static const Flags elementType = (dim == 3 ? FILL_EL_TYPE : FILL_NOTHING);
00262 #endif
00263
00264 #if DUNE_ALBERTA_VERSION >= 0x201
00265 static const Flags boundaryId = FILL_MACRO_WALLS;
00266 #else
00267 static const Flags boundaryId = FILL_BOUND;
00268 #endif
00269
00270 #if DUNE_ALBERTA_VERSION >= 0x201
00271 static const Flags nonPeriodic = FILL_NON_PERIODIC;
00272 #else
00273 static const Flags nonPeriodic = FILL_NOTHING;
00274 #endif
00275
00276 static const Flags all = coords | neighbor | boundaryId | nonPeriodic
00277 | orientation | elementType;
00278
00279 #if CALC_COORD
00280 static const Flags standard = all & ~nonPeriodic;
00281 #else
00282 static const Flags standard = all & ~nonPeriodic & ~coords;
00283 #endif
00284 };
00285
00286
00287
00288
00289
00290
00291 template< int dim >
00292 struct RefinementEdge
00293 {
00294 static const int value = 0;
00295 };
00296
00297 template<>
00298 struct RefinementEdge< 2 >
00299 {
00300 static const int value = 2;
00301 };
00302
00303
00304
00305
00306
00307
00308 template< int dim, int codim >
00309 struct Dune2AlbertaNumbering
00310 {
00311 static int apply ( int i )
00312 {
00313 assert( (i >= 0) && (i < NumSubEntities< dim, codim >::value) );
00314 return i;
00315 }
00316 };
00317
00318 template<>
00319 struct Dune2AlbertaNumbering< 3, 2 >
00320 {
00321 static const int numSubEntities = NumSubEntities< 3, 2 >::value;
00322
00323 static int apply ( int i )
00324 {
00325 assert( (i >= 0) && (i < numSubEntities) );
00326 static int dune2alberta[ numSubEntities ] = { 0, 3, 1, 2, 4, 5 };
00327 return dune2alberta[ i ];
00328 }
00329 };
00330
00331
00332
00333
00334
00335
00336 template< int dim >
00337 class NumberingMap
00338 {
00339 typedef NumberingMap< dim > This;
00340
00341 template< int codim >
00342 struct Initialize;
00343
00344 int *dune2alberta_[ dim+1 ];
00345 int *alberta2dune_[ dim+1 ];
00346 int numSubEntities_[ dim+1 ];
00347
00348 NumberingMap ( const This & );
00349 This &operator= ( const This & );
00350
00351 public:
00352 NumberingMap ()
00353 {
00354 ForLoop< Initialize, 0, dim >::apply( *this );
00355 }
00356
00357 ~NumberingMap ()
00358 {
00359 for( int codim = 0; codim <= dim; ++codim )
00360 {
00361 delete[]( dune2alberta_[ codim ] );
00362 delete[]( alberta2dune_[ codim ] );
00363 }
00364 }
00365
00366 int dune2alberta ( int codim, int i ) const
00367 {
00368 assert( (codim >= 0) && (codim <= dim) );
00369 assert( (i >= 0) && (i < numSubEntities( codim )) );
00370 return dune2alberta_[ codim ][ i ];
00371 }
00372
00373 int alberta2dune ( int codim, int i ) const
00374 {
00375 assert( (codim >= 0) && (codim <= dim) );
00376 assert( (i >= 0) && (i < numSubEntities( codim )) );
00377 return alberta2dune_[ codim ][ i ];
00378 }
00379
00380 int numSubEntities ( int codim ) const
00381 {
00382 assert( (codim >= 0) && (codim <= dim) );
00383 return numSubEntities_[ codim ];
00384 }
00385 };
00386
00387
00388
00389
00390
00391
00392 template< int dim >
00393 template< int codim >
00394 struct NumberingMap< dim >::Initialize
00395 {
00396 static const int numSubEntities = NumSubEntities< dim, codim >::value;
00397
00398 static void apply ( NumberingMap< dim > &map )
00399 {
00400 map.numSubEntities_[ codim ] = numSubEntities;
00401 map.dune2alberta_[ codim ] = new int[ numSubEntities ];
00402 map.alberta2dune_[ codim ] = new int[ numSubEntities ];
00403
00404 for( int i = 0; i < numSubEntities; ++i )
00405 {
00406 const int j = Dune2AlbertaNumbering< dim, codim >::apply( i );
00407 map.dune2alberta_[ codim ][ i ] = j;
00408 map.alberta2dune_[ codim ][ j ] = i;
00409 }
00410 }
00411 };
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438 template< int dim >
00439 struct Twist;
00440
00441 template<>
00442 struct Twist< 1 >
00443 {
00444 static int faceTwist ( const Element *element, int face )
00445 {
00446 assert( (face >= 0) && (face < NumSubEntities< 1, 1 >::value) );
00447 return 0;
00448 }
00449 };
00450
00451 template<>
00452 struct Twist< 2 >
00453 {
00454 static const int dim = 2;
00455
00456 static int faceTwist ( const Element *element, int face )
00457 {
00458 assert( (face >= 0) && (face < NumSubEntities< dim, 1 >::value) );
00459 int dof[ dim ];
00460 for( int i = 0; i < dim; ++i )
00461 {
00462 const int j = ALBERTA AlbertHelp::MapVertices< dim-1, dim >::mapVertices( face, i );
00463 dof[ i ] = element->dof[ j ][ 0 ];
00464 }
00465 return (dof[ 0 ] < dof[ 1 ] ? 0 : 1);
00466 }
00467 };
00468
00469 template<>
00470 struct Twist< 3 >
00471 {
00472 static const int dim = 3;
00473
00474 static int faceTwist ( const Element *element, int face )
00475 {
00476 assert( (face >= 0) && (face < NumSubEntities< dim, 1 >::value) );
00477 int dof[ dim ];
00478 for( int i = 0; i < dim; ++i )
00479 {
00480 const int j = ALBERTA AlbertHelp::MapVertices< dim-1, dim >::mapVertices( face, i );
00481 dof[ i ] = element->dof[ j ][ 0 ];
00482 }
00483
00484 const int twist[ 8 ] = { -2, 1, 666, -1, 2, 666, -3, 0 };
00485 const int k = int( dof[ 0 ] < dof[ 1 ] )
00486 | (int( dof[ 0 ] < dof[ 2 ] ) << 1)
00487 | (int( dof[ 1 ] < dof[ 2 ] ) << 2);
00488 assert( twist[ k ] != 666 );
00489 return twist[ k ];
00490 }
00491 };
00492
00493
00494
00495 template< int dim >
00496 inline int applyTwist ( int twist, int i )
00497 {
00498 const int numCorners = NumSubEntities< dim, dim >::value;
00499 return (twist < 0 ? (2*numCorners + 1 - i + twist) : i + twist) % numCorners;
00500 }
00501
00502 template< int dim >
00503 inline int applyInverseTwist ( int twist, int i )
00504 {
00505 const int numCorners = NumSubEntities< dim, dim >::value;
00506 return (twist < 0 ? (2*numCorners + 1 - i + twist) : numCorners + i - twist) % numCorners;
00507 }
00508
00509 }
00510
00511 }
00512
00513 #endif // #if HAVE_ALBERTA
00514
00515 #endif