albertagrid/misc.hh

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   // Exceptions
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     // Import Types
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     // Memory Manipulation Functions
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     // GlobalSpace
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     // NumSubEntities
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     // CodimType
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     // FillFlags
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     // RefinementEdge
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     // Dune2AlbertaNumbering
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     // NumberingMap
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     // NumberingMap::Setup
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     // Twist
00416     // -----
00417 
00418     // ******************************************************************
00419     // Meaning of the twist (same as in ALU)
00420     // -------------------------------------
00421     //
00422     // Consider a fixed ordering of the vertices v_1, ... v_n of a face
00423     // (here, we assume their indices to be increasing). Denote by k the
00424     // local number of a vertex v within the element and by t the twist.
00425     // Then, v = v_j, where j is computed by the following formula:
00426     //
00427     //        / (2n + 1 - k + t) % n, if t < 0
00428     //   j = <
00429     //        \ (k + t) % n,          if t >= 0
00430     //
00431     //  Note: We use the order of the 0-th vertex dof to assign the twist.
00432     //        This is ok for two reasons:
00433     //        - ALBERTA preserves the relative order of the dofs during
00434     //          dof compression.
00435     //        - ALBERTA enforces the first vertex dof admin to be periodic.
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

Generated on Tue Jul 28 22:28:20 2009 for dune-grid by  doxygen 1.5.6