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   // MacroGrid::Impl (for AlbertaGrid)
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 &macroGrid,
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 &macroGrid, 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       // This is a nasty hack: The tetrahedrons generated by make6 are not
00077       // directly useable by ALBERTA. On every second tetrahedron we have to
00078       // switch the last 2 vertices (otherwise ALBERTA causes a segmentation
00079       // fault during refinement).
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       // look for bounaries and insert them
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

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