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
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
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
00172 Alberta::GlobalVector t;
00173 for( int i = 0; i < dimworld; ++i )
00174 t[ i ] = shift[ i ];
00175
00176
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