albertagrid/dgfparser.hh
00001 #ifndef DUNE_ALBERTA_DGFPARSER_HH
00002 #define DUNE_ALBERTA_DGFPARSER_HH
00003
00004 #include <dune/grid/albertagrid.hh>
00005 #include <dune/grid/albertagrid/gridfactory.hh>
00006
00007 #include <dune/grid/io/file/dgfparser/dgfparser.hh>
00008
00009 #if HAVE_ALBERTA
00010
00011 namespace Dune
00012 {
00013
00014
00015
00016
00017 template< int dim, int dimworld >
00018 class MacroGrid::Impl< AlbertaGrid< dim, dimworld > >
00019 {
00020 typedef MPIHelper::MPICommunicator MPICommunicatorType;
00021
00022 typedef AlbertaGrid< dim, dimworld > Grid;
00023 typedef Dune::GridFactory< Grid > GridFactory;
00024
00025 static const int dimension = Grid::dimension;
00026
00027 public:
00028 static Grid *
00029 generate( MacroGrid ¯oGrid,
00030 const std::string &filename,
00031 MPICommunicatorType MPICOMM = MPIHelper::getCommunicator() );
00032 };
00033
00034
00035 template< int dim, int dimworld >
00036 inline typename MacroGrid::Impl< AlbertaGrid< dim, dimworld > >::Grid *
00037 MacroGrid::Impl< AlbertaGrid< dim, dimworld > >
00038 ::generate( MacroGrid ¯oGrid, const std::string &filename, MPICommunicatorType )
00039 {
00040 macroGrid.element = Simplex;
00041 macroGrid.dimgrid = dim;
00042 macroGrid.dimw = dimworld;
00043
00044 std::ifstream file( filename.c_str() );
00045 if( !macroGrid.readDuneGrid( file, dim, dimworld ) )
00046 return new AlbertaGrid< dim, dimworld >( filename.c_str() );
00047
00048 macroGrid.setOrientation( 0, 1 );
00049 macroGrid.setRefinement( 0, 1, -1, -1 );
00050
00051 dgf::GridParameterBlock parameter( file );
00052 std::string gridName = parameter.name( "AlbertaGrid" );
00053
00054 if( !GridFactory::supportsBoundaryIds )
00055 {
00056 std::string albertaFileName = filename + ".albertagrid";
00057 std::ofstream out( albertaFileName.c_str() );
00058 macroGrid.writeAlberta( out );
00059 out.close();
00060 return new Grid( albertaFileName, gridName );
00061 }
00062
00063 GridFactory factory;
00064 for( int n = 0; n < macroGrid.nofvtx; ++n )
00065 {
00066 typename GridFactory::WorldVector coord;
00067 for( int i = 0; i < dimworld; ++i )
00068 coord[ i ] = macroGrid.vtx[ n ][ i ];
00069 factory.insertVertex( coord );
00070 }
00071
00072 GeometryType type( GeometryType::simplex, dimension );
00073 std::vector< unsigned int > elementId( dimension+1 );
00074 for( int n = 0; n < macroGrid.nofelements; ++n )
00075 {
00076
00077
00078
00079
00080 if( (dimension == 3) && macroGrid.cube2simplex && (n % 2 == 0) )
00081 {
00082 const int flip[ 4 ] = { 0, 1, 3, 2 };
00083 for( int i = 0; i <= dimension; ++i )
00084 elementId[ i ] = macroGrid.elements[ n ][ flip[ i ] ];
00085 }
00086 else
00087 {
00088 for( int i = 0; i <= dimension; ++i )
00089 elementId[ i ] = macroGrid.elements[ n ][ i ];
00090 }
00091
00092 factory.insertElement( type, elementId );
00093
00094
00095 for( int face = 0; face <= dimension; ++face )
00096 {
00097 typedef typename MacroGrid::facemap_t::key_type Key;
00098 typedef typename MacroGrid::facemap_t::iterator Iterator;
00099
00100 const Key key( elementId, dimension, face+1 );
00101 const Iterator it = macroGrid.facemap.find( key );
00102 if( it != macroGrid.facemap.end() )
00103 factory.insertBoundary( n, face, it->second );
00104 }
00105 }
00106
00107 if( GridFactory::supportPeriodicity )
00108 {
00109 typedef dgf::PeriodicFaceTransformationBlock::AffineTransformation Transformation;
00110 dgf::PeriodicFaceTransformationBlock block( file, dimworld );
00111 const int size = block.numTransformations();
00112 for( int k = 0; k < size; ++k )
00113 {
00114 const Transformation &trafo = block.transformation( k );
00115
00116 typename GridFactory::WorldMatrix matrix;
00117 for( int i = 0; i < dimworld; ++i )
00118 for( int j = 0; j < dimworld; ++j )
00119 matrix[ i ][ j ] = trafo.matrix( i, j );
00120
00121 typename GridFactory::WorldVector shift;
00122 for( int i = 0; i < dimworld; ++i )
00123 shift[ i ] = trafo.shift[ i ];
00124
00125 factory.insertFaceTransformation( matrix, shift );
00126 }
00127 }
00128
00129 return factory.createGrid( gridName, parameter.markLongestEdge() );
00130 }
00131
00132
00133
00134 template< int dim, int dimworld >
00135 struct DGFGridInfo< AlbertaGrid< dim, dimworld > >
00136 {
00137 static int refineStepsForHalf ()
00138 {
00139 return dim;
00140 }
00141
00142 static double refineWeight ()
00143 {
00144 return 0.5;
00145 }
00146 };
00147
00148 }
00149
00150 #endif // #if HAVE_ALBERTA
00151
00152 #endif