albertagrid/gridfactory.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTA_GRIDFACTORY_HH
00002 #define DUNE_ALBERTA_GRIDFACTORY_HH
00003 
00009 #include <limits>
00010 
00011 #include <dune/grid/common/gridfactory.hh>
00012 
00013 #include <dune/grid/utility/grapedataioformattypes.hh>
00014 
00015 #include <dune/grid/albertagrid/agrid.hh>
00016 
00017 #if HAVE_ALBERTA
00018 
00019 namespace Dune
00020 {
00021 
00037   template< int dim, int dimworld >
00038   class GridFactory< AlbertaGrid< dim, dimworld > >
00039   : public GridFactoryInterface< AlbertaGrid< dim, dimworld > >
00040   {
00041     typedef GridFactory< AlbertaGrid< dim, dimworld > > This;
00042 
00043   public:
00045     typedef AlbertaGrid< dim, dimworld > Grid;
00046 
00048     typedef typename Grid::ctype ctype;
00049 
00051     static const int dimension = Grid::dimension;
00053     static const int dimensionworld = Grid::dimensionworld;
00054 
00056     typedef FieldVector< ctype, dimensionworld > WorldVector;
00058     typedef FieldMatrix< ctype, dimensionworld, dimensionworld > WorldMatrix;
00059 
00060   private:
00061     static const int numVertices
00062       = Alberta::NumSubEntities< dimension, dimension >::value;
00063 
00064     typedef Alberta::MacroData< dimension > MacroData;
00065     typedef Alberta::NumberingMap< dimension > NumberingMap;
00066 
00067   public:
00069     static const bool supportsBoundaryIds = (DUNE_ALBERTA_VERSION >= 0x200);
00071     static const bool supportPeriodicity = MacroData::supportPeriodicity;
00072 
00073   private:
00074     MacroData macroData_;
00075     NumberingMap numberingMap_;
00076 
00077   public:
00079     GridFactory ()
00080     {
00081       macroData_.create();
00082     }
00083 
00084     virtual ~GridFactory ()
00085     {
00086       macroData_.release();
00087     }
00088 
00093     virtual void insertVertex ( const WorldVector &pos )
00094     {
00095       macroData_.insertVertex( pos );
00096     }
00097 
00103     virtual void insertElement ( const GeometryType &type,
00104                                  const std::vector< unsigned int > &vertices )
00105     {
00106       if( (int)type.dim() != dimension )
00107         DUNE_THROW( AlbertaError, "Inserting element of wrong dimension: " << type.dim() );
00108       if( !type.isSimplex() )
00109         DUNE_THROW( AlbertaError, "Alberta supports only simplices." );
00110 
00111       if( vertices.size() != (size_t)numVertices )
00112         DUNE_THROW( AlbertaError, "Wrong number of vertices passed: " << vertices.size() << "." );
00113 
00114       int array[ numVertices ];
00115       for( int i = 0; i < numVertices; ++i )
00116         array[ i ] = vertices[ numberingMap_.alberta2dune( dimension, i ) ];
00117       macroData_.insertElement( array );
00118     }
00119 
00128     virtual void insertBoundary ( int element, int face, int id )
00129     {
00130       if( (id <= 0) || (id > 127) )
00131         DUNE_THROW( AlbertaError, "Invalid boundary id: " << id << "." );
00132       macroData_.boundaryId( element, numberingMap_.dune2alberta( 1, face ) ) = id;
00133     }
00134 
00148     virtual void
00149     insertFaceTransformation ( const WorldMatrix &matrix, const WorldVector &shift )
00150     {
00151       // make sure the matrix is orthogonal
00152       for( int i = 0; i < dimworld; ++i )
00153         for( int j = 0; j < dimworld; ++j )
00154         {
00155           const ctype delta = (i == j ? ctype( 1 ) : ctype( 0 ));
00156           const ctype epsilon = (8*dimworld)*std::numeric_limits< ctype >::epsilon();
00157 
00158           if( std::abs( matrix[ i ] * matrix[ j ] - delta ) > epsilon )
00159           {
00160             DUNE_THROW( AlbertaError,
00161                         "Matrix of face transformation is not orthogonal." );
00162           }
00163         }
00164 
00165       // copy matrix
00166       Alberta::GlobalMatrix M;
00167       for( int i = 0; i < dimworld; ++i )
00168         for( int j = 0; j < dimworld; ++j )
00169           M[ i ][ j ] = matrix[ i ][ j ];
00170 
00171       // copy shift
00172       Alberta::GlobalVector t;
00173       for( int i = 0; i < dimworld; ++i )
00174         t[ i ] = shift[ i ];
00175 
00176       // insert into ALBERTA macro data
00177       macroData_.insertWallTrafo( M, t );
00178     }
00179 
00204     Grid *createGrid ( const std::string &gridName, bool markLongestEdge = false )
00205     {
00206       macroData_.finalize();
00207       if( markLongestEdge )
00208         macroData_.markLongestEdge();
00209       return new Grid( macroData_, gridName );
00210     }
00211 
00221     virtual Grid *createGrid ()
00222     {
00223       return createGrid( "AlbertaGrid", false );
00224     }
00225 
00230     static void destroyGrid ( Grid *grid )
00231     {
00232       delete grid;
00233     }
00234 
00243     template< GrapeIOFileFormatType type >
00244     bool write ( const std::string &filename )
00245     {
00246       dune_static_assert( type != pgm, "AlbertaGridFactory: writing pgm format is not supported." );
00247       macroData_.finalize();
00248       return macroData_.write( filename, (type == xdr) );
00249     }
00250 
00259     virtual bool write ( const std::string &filename )
00260     {
00261       return write< ascii >( filename );
00262     }
00263   };
00264 
00265 }
00266 
00267 #endif // #if HAVE_ALBERTA
00268 
00269 #endif

Generated on Thu Apr 2 10:40:40 2009 for dune-grid by  doxygen 1.5.6