Skip to content
Snippets Groups Projects
grid_inline.hh 24.5 KiB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
// Dune includes
#include <dune/common/stdstreams.hh>

// Local includes
#include "alu3dinclude.hh"
#include "entity.hh"
#include "iterator.hh"
#include "datahandle.hh"
#include "grid.hh"

namespace Dune
{

  // Implementation of ALU3dGrid
  // ---------------------------

  template< ALU3dGridElementType elType, class Comm >
  inline ALU3dGrid< elType, Comm >
    ::ALU3dGrid ( const std::string &macroTriangFilename,
                  const MPICommunicatorType mpiComm,
                  const DuneBoundaryProjectionType *bndPrj,
                  const DuneBoundaryProjectionVector *bndVec,
                  const ALUGridRefinementType refinementType ) 
    : mygrid_( 0 )
    , maxlevel_( 0 )
    , coarsenMarked_( 0 )
    , refineMarked_( 0 )
    , geomTypes_() //dim+1, std::vector<GeometryType>(1) )
    , hIndexSet_ (*this)
    , globalIdSet_( 0 )
    , localIdSet_( *this )
    , levelIndexVec_(MAXL,0) , leafIndexSet_(0)
    , referenceElement_( elType == tetra
        ? ReferenceElements< alu3d_ctype, dimension > :: simplex()
        : ReferenceElements< alu3d_ctype, dimension > :: cube() )
    , sizeCache_ ( 0 )
#ifdef USE_SMP_PARALLEL
    , factoryVec_( GridObjectFactoryType :: maxThreads(), GridObjectFactoryType( *this ) )
#else 
    , factory_( *this )
#endif
    , lockPostAdapt_( false )
    , bndPrj_ ( bndPrj )
    , bndVec_ ( (bndVec) ? (new DuneBoundaryProjectionVector( *bndVec )) : 0 )
    , vertexProjection_( (bndPrj || bndVec) ? new ALUGridBoundaryProjectionType( *this ) : 0 )
    , communications_( new Communications( mpiComm ) )
    , refinementType_( refinementType )
  {
    assert( elType == tetra || elType == hexa );

    geomTypes_.resize( dimension+1 );
    GeometryType tmpType;
    for( int codim = 0; codim <= dimension; ++codim ) 
    {
        if (elType == tetra)
            tmpType.makeSimplex( dimension - codim );
        else
            tmpType.makeCube( dimension - codim );
        
        geomTypes_[ codim ].push_back( tmpType );
    }
    
    // check macro grid file for keyword 
    checkMacroGridFile( macroTriangFilename );
   
    mygrid_ = createALUGrid( macroTriangFilename );
    assert( mygrid_ );

    dverb << "************************************************" << std::endl;
    dverb << "Created grid on p=" << comm().rank() << std::endl;
    dverb << "************************************************" << std::endl;
    checkMacroGrid ();
  
    postAdapt();
    calcExtras();
  } // end constructor


  template< ALU3dGridElementType elType, class Comm >
  inline int ALU3dGrid< elType, Comm >::global_size ( int codim ) const 
  {
    // return actual size of hierarchical index set 
    // this is always up to date 
    // maxIndex is the largest index used + 1 
    return myGrid().indexManager(codim).getMaxIndex();
  }


  template< ALU3dGridElementType elType, class Comm >
  inline int ALU3dGrid< elType, Comm >::hierSetSize ( int codim ) const
  {
    // return actual size of hierarchical index set 
    return myGrid().indexManager(codim).getMaxIndex();
  }


  template< ALU3dGridElementType elType, class Comm >
  inline int ALU3dGrid< elType, Comm >::maxLevel () const 
  { 
    return maxlevel_;
  }


  template< ALU3dGridElementType elType, class Comm >
  inline typename ALU3dGrid< elType, Comm >::GitterImplType &
  ALU3dGrid< elType, Comm >::myGrid () const
  {
    assert( mygrid_ );
    return *mygrid_;
  }


  // lbegin methods 
  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LevelIterator
  ALU3dGrid< elType, Comm >::lbegin ( int level ) const
  {
    assert( level >= 0 );
    // if we dont have this level return empty iterator 
    if( level > maxlevel_ )
      return this->template lend<cd,pitype> (level);

    return ALU3dGridLevelIterator< cd, pitype, const ThisType >( factory(), level, true );
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LevelIterator
  ALU3dGrid< elType, Comm >::lend ( int level ) const
  {
    assert( level >= 0 );
    return ALU3dGridLevelIterator< cd, pitype, const ThisType >( factory(), level );
  }


  // lbegin methods 
  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< All_Partition >::LevelIterator
  ALU3dGrid< elType, Comm >::lbegin ( int level ) const
  {
    return this->template lbegin<cd,All_Partition>( level );
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< All_Partition >::LevelIterator
  ALU3dGrid< elType, Comm >::lend ( int level ) const
  {
    assert( level >= 0 );
    return this->template lend<cd,All_Partition>( level );
  }


  //***********************************************************
  //
  // leaf methods , first all begin methods 
  //
  //***********************************************************
  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::createLeafIteratorBegin ( int level ) const
  {
    assert( level >= 0 );
    return ALU3dGridLeafIterator< cd, pitype, const ThisType >( factory(), level, true );
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::leafbegin ( int level ) const
  {
    return createLeafIteratorBegin<cd, pitype> (level) ;
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::LeafIterator
  ALU3dGrid< elType, Comm >::leafbegin ( int level ) const
  {
    return createLeafIteratorBegin<cd, All_Partition> (level) ;
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::leafbegin () const
  {
    return createLeafIteratorBegin< cd, pitype > (maxlevel_) ;
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::LeafIterator
  ALU3dGrid< elType, Comm >::leafbegin () const
  {
    return createLeafIteratorBegin< cd, All_Partition> (maxlevel_) ;
  }


  template< ALU3dGridElementType elType, class Comm >
  inline typename ALU3dGrid< elType, Comm >::LeafIteratorType
  ALU3dGrid< elType, Comm >::leafbegin ( int level ) const
  {
    return createLeafIteratorBegin<0, All_Partition> (level) ;
  }


  template< ALU3dGridElementType elType, class Comm >
  inline typename ALU3dGrid< elType, Comm >::LeafIteratorType
  ALU3dGrid< elType, Comm >::leafbegin () const
  {
    return createLeafIteratorBegin<0, All_Partition> (maxlevel_) ;
  }


  //****************************************************************
  //
  // all leaf end methods 
  //
  //****************************************************************
  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::createLeafIteratorEnd ( int level ) const
  {
    assert( level >= 0 );
    return ALU3dGridLeafIterator<cd, pitype, const MyType> ( factory() , level);
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::leafend ( int level ) const
  {
    return createLeafIteratorEnd < cd, pitype> (level);
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::LeafIterator
  ALU3dGrid< elType, Comm >::leafend ( int level ) const
  {
    return createLeafIteratorEnd < cd, All_Partition> (level);
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd, PartitionIteratorType pitype >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::template Partition< pitype >::LeafIterator
  ALU3dGrid< elType, Comm >::leafend () const
  {
    return createLeafIteratorEnd < cd, pitype> (maxlevel_);
  }


  template< ALU3dGridElementType elType, class Comm >
  template< int cd >
  inline typename ALU3dGrid< elType, Comm >::Traits::template Codim< cd >::LeafIterator
  ALU3dGrid< elType, Comm >::leafend () const
  {
    return createLeafIteratorEnd < cd, All_Partition> (maxlevel_);
  }


  template< ALU3dGridElementType elType, class Comm >
  inline typename ALU3dGrid< elType, Comm >::LeafIteratorType
  ALU3dGrid< elType, Comm >::leafend ( int level ) const
  {
    return createLeafIteratorEnd <0, All_Partition> (level);
  }


  template< ALU3dGridElementType elType, class Comm >
  inline typename ALU3dGrid< elType, Comm >::LeafIteratorType
  ALU3dGrid< elType, Comm >::leafend () const
  {
    return createLeafIteratorEnd <0,All_Partition> (maxlevel_);
  }


  //*****************************************************************

  // mark given entity  
  template< ALU3dGridElementType elType, class Comm >
  inline bool ALU3dGrid< elType, Comm >
    ::mark ( int ref, const typename Traits::template Codim< 0 >::Entity &entity )
  {
    bool marked = (this->getRealImplementation( entity )).mark(ref);
    if(marked) 
      {
        if(ref > 0) ++refineMarked_;
        if(ref < 0) ++coarsenMarked_;
      }
    return marked;
  }


  // get Mark of given entity  
  template< ALU3dGridElementType elType, class Comm >
  inline int ALU3dGrid< elType, Comm >
    ::getMark ( const typename Traits::template Codim< 0 >::Entity &entity ) const
  {
    return this->getRealImplementation( entity ).getMark();
  }


  // global refine 
  template< ALU3dGridElementType elType, class Comm >
  template< class GridImp, class DataHandle >
  inline 
  void ALU3dGrid< elType, Comm >
    ::globalRefine ( int refCount, AdaptDataHandleInterface< GridImp, DataHandle > &handle )
  {
    assert( (refCount + maxLevel()) < MAXL ); 
    
    for( int count = refCount; count > 0; --count )
    {
      const LeafIteratorType end = leafend();
      for( LeafIteratorType it = leafbegin(); it != end; ++it )
        mark( 1 , *it );
      adapt( handle );
    }
  }


  // adapt grid  
  // --adapt
  template< ALU3dGridElementType elType, class Comm >
  template< class GridImp, class DataHandle >
  inline  
  bool ALU3dGrid< elType, Comm >
    ::adapt ( AdaptDataHandleInterface< GridImp, DataHandle > &handle )
  {
    typedef AdaptDataHandleInterface< GridImp, DataHandle > AdaptDataHandle;

    typedef typename EntityObject::ImplementationType EntityImp;
    EntityObject father( EntityImp( *this, this->maxLevel() ) );
    EntityObject son( EntityImp( *this, this->maxLevel() ) );

    int defaultChunk = newElementsChunk_;
    int actChunk     = refineEstimate_ * refineMarked_; 

    // guess how many new elements we get 
    int newElements = std::max( actChunk , defaultChunk ); 

    // true if at least one element was marked for coarsening
    bool mightCoarse = preAdapt();
    // reserve memory
    handle.preAdapt( newElements );
    
    bool refined = false ; 
    if(globalIdSet_)
    {
      // if global id set exists then include into 
      // prolongation process 
      ALU3DSPACE AdaptRestrictProlongGlSet< MyType, AdaptDataHandle, GlobalIdSetImp >
      rp(*this,
         father,this->getRealImplementation(father), 
         son,   this->getRealImplementation(son),
         handle,
         *globalIdSet_);

      refined = myGrid().duneAdapt(rp); // adapt grid 
    }
    else 
    {
       ALU3DSPACE AdaptRestrictProlongImpl< MyType, AdaptDataHandle >
       rp(*this,
          father,this->getRealImplementation(father), 
          son,   this->getRealImplementation(son),
          handle);

      refined = myGrid().duneAdapt(rp); // adapt grid 
    }
  
    if(refined || mightCoarse)
    {
      // only calc extras and skip maxLevel calculation, because of
      // refinement maxLevel was calculated already 
      updateStatus();

      // no need to call postAdapt here, because markers 
      // are cleand during refinement callback
    }

    // check whether we have balance 
    handle.postAdapt();

    // here postAdapt is not called, because 
    // reset of refinedTag is done in preCoarsening and postRefinement
    // methods of datahandle (see datahandle.hh) 
    
    return refined;
  }



  //*****************************************************************

  template< ALU3dGridElementType elType, class Comm >
  struct ALU3dGridCommHelper;

  template< ALU3dGridElementType elType >
Robert Kloefkorn's avatar
Robert Kloefkorn committed
  struct ALU3dGridCommHelper< elType, ALUGridNoComm >
Robert Kloefkorn's avatar
Robert Kloefkorn committed
    typedef ALU3dGrid< elType, ALUGridNoComm > Grid;

    static bool loadBalance ( Grid &grid ) { return false; }

    template< class DataHandle >
    static bool loadBalance ( Grid &grid, DataHandle &data ) { return false; }

    template< class DataHandle, class DataType >
    static void communicate ( const Grid &grid, 
                              const CommDataHandleIF< DataHandle, DataType > &data,
                              const InterfaceType iftype, 
                              const CommunicationDirection dir, 
                              const int level )
    {}

    template< class DataHandle, class DataType >
    static void communicate ( const Grid &grid, 
                              const CommDataHandleIF< DataHandle, DataType > &data,
                              const InterfaceType iftype, 
                              const CommunicationDirection dir )
    {}
  }; // ALU3dGridCommHelper

  template< ALU3dGridElementType elType >
Robert Kloefkorn's avatar
Robert Kloefkorn committed
  struct ALU3dGridCommHelper< elType, ALUGridMPIComm >
Robert Kloefkorn's avatar
Robert Kloefkorn committed
    typedef ALU3dGrid< elType, ALUGridMPIComm > Grid;
    typedef ALU3DSPACE GatherScatter GatherScatterType;

    static bool loadBalance ( Grid &grid )
    {
      if( grid.comm().size() <= 1 )
        return false;

      const bool changed = grid.myGrid().duneLoadBalance();
      if( changed )
      {
        // some exchanges on ALUGrid side 
        grid.myGrid().duneExchangeDynamicState();

        // calculate new maxlevel 
        // reset size and things  
        grid.updateStatus();
        
        // build new Id Set. Only do that after updateStatus, because here
        // the item lists are needed 
        if( grid.globalIdSet_ )
          grid.globalIdSet_->updateIdSet();
      
        // unset all leaf markers
        grid.postAdapt();
      }

      return changed;
    }


    template< class DataHandle >
    static bool loadBalance ( Grid &grid, DataHandle &data )
    {
      if( grid.comm().size() <= 1 )
        return false;

      typedef typename Grid :: EntityObject EntityObject;
      typedef typename EntityObject::ImplementationType EntityImp;
      EntityObject en     ( EntityImp( grid, grid.maxLevel()) );
      EntityObject father ( EntityImp( grid, grid.maxLevel()) );
      EntityObject son    ( EntityImp( grid, grid.maxLevel()) );

      typedef ALU3DSPACE LoadBalanceElementCount< Grid, DataHandle > LDBElCountType;

      // elCount is the adaption restPro operator used during the refinement
      // cause be creating new elements on processors  
      LDBElCountType elCount( grid,
                              father, Grid::getRealImplementation( father ),
                              son, Grid::getRealImplementation( son ),
                              data );

      ALU3DSPACE GatherScatterLoadBalance< Grid, DataHandle, LDBElCountType >
        gs( grid, en, Grid::getRealImplementation( en ), data, elCount );
    
      // call load Balance 
      const bool changed = grid.myGrid().duneLoadBalance( gs, elCount );

      if( changed )
      {
        // exchange some data for internal useage
        grid.myGrid().duneExchangeDynamicState();

        // calculate new maxlevel 
        // reset size and things  
        grid.updateStatus();

        // build new Id Set. Only do that after updateStatus, because here
        // the item lists are needed 
        if( grid.globalIdSet_ )
          grid.globalIdSet_->updateIdSet();
        
        // compress data, wrapper for dof manager
        gs.compress();

        grid.postAdapt();
      }
      return changed;
    }


    template< class DataHandle, class DataType >
    static void communicate ( const Grid &grid, 
                              CommDataHandleIF< DataHandle, DataType > &data,
                              const InterfaceType iftype, 
                              const CommunicationDirection dir, 
                              const int level )
    {
      typedef CommDataHandleIF< DataHandle, DataType > DataHandleType;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 3 >::Entity > VertexObject;
      typedef typename VertexObject::ImplementationType VertexImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 2 >::Entity > EdgeObject;
      typedef typename EdgeObject::ImplementationType EdgeImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 1 >::Entity > FaceObject;
      typedef typename FaceObject::ImplementationType FaceImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 0 >::Entity> ElementObject;
      typedef typename ElementObject::ImplementationType ElementImp;

      if( grid.comm().size() > 1 )
      {
        // for level communication the level index set is needed. 
        // if non-existent, then create for communicaton
        const typename Grid::LevelIndexSetImp *levelISet;
        if( !grid.levelIndexVec_[ level ] )
          levelISet = new typename Grid::LevelIndexSetImp(
              grid, 
              grid.template lbegin<0>( level ),
              grid.template lend<0>( level ), level );
        else 
          levelISet = grid.levelIndexVec_[ level ];
        
        VertexObject vx( VertexImp( grid, level ) );    
        ALU3DSPACE GatherScatterLevelData< Grid, DataHandleType, 3 >
          vertexData( grid, vx, Grid::getRealImplementation( vx ), data, *levelISet, level );
        
        EdgeObject edge( EdgeImp( grid, level ) );
        ALU3DSPACE GatherScatterLevelData< Grid, DataHandleType, 2 >
          edgeData( grid, edge, Grid::getRealImplementation( edge ), data, *levelISet, level );
        
        FaceObject face( FaceImp( grid, level ) );
        ALU3DSPACE GatherScatterLevelData< Grid, DataHandleType, 1 >
          faceData( grid, face, Grid::getRealImplementation( face ), data, *levelISet, level );

        ElementObject element( ElementImp( grid, level ) );    
        ALU3DSPACE GatherScatterLevelData< Grid, DataHandleType, 0 >
          elementData( grid, element, Grid::getRealImplementation( element ), data, *levelISet, level );

        doCommunication( grid, vertexData, edgeData, faceData, elementData, iftype, dir );

        if( !grid.levelIndexVec_[ level ] )
          delete levelISet;
      }
    }

    template< class DataHandle, class DataType >
    static void communicate ( const Grid &grid, 
                              CommDataHandleIF< DataHandle, DataType > &data,
                              const InterfaceType iftype, 
                              const CommunicationDirection dir )
    {
      typedef CommDataHandleIF< DataHandle, DataType > DataHandleType;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 3 >::Entity > VertexObject;
      typedef typename VertexObject::ImplementationType VertexImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 2 >::Entity > EdgeObject;
      typedef typename EdgeObject::ImplementationType EdgeImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 1 >::Entity > FaceObject;
      typedef typename FaceObject::ImplementationType FaceImp;
      typedef MakeableInterfaceObject< typename Grid::Traits::template Codim< 0 >::Entity> ElementObject;
      typedef typename ElementObject::ImplementationType ElementImp;

      if( grid.comm().size() > 1 )
      {
        VertexObject vx( VertexImp( grid, grid.maxLevel() ) );
        ALU3DSPACE GatherScatterLeafData< Grid, DataHandleType, 3 >
          vertexData( grid, vx, Grid::getRealImplementation( vx ), data );
        
        EdgeObject edge( EdgeImp( grid, grid.maxLevel() ) );
        ALU3DSPACE GatherScatterLeafData< Grid, DataHandleType, 2 >
          edgeData( grid, edge, Grid::getRealImplementation( edge ), data );
        
        FaceObject face( FaceImp( grid, grid.maxLevel()) );    
        ALU3DSPACE GatherScatterLeafData< Grid, DataHandleType, 1 >
          faceData( grid, face, Grid::getRealImplementation( face ), data );

        ElementObject element( ElementImp( grid, grid.maxLevel() ) );
        ALU3DSPACE GatherScatterLeafData< Grid, DataHandleType, 0 >
          elementData( grid, element, Grid::getRealImplementation( element ), data );

        doCommunication( grid, vertexData, edgeData, faceData, elementData, iftype, dir );
      }
    }

    static void
    doCommunication ( const Grid &grid,
                      GatherScatterType &vertexData, GatherScatterType &edgeData,
                      GatherScatterType &faceData, GatherScatterType &elementData,
                      InterfaceType iftype, CommunicationDirection dir )
    {
      // check interface types 
      if( (iftype == Overlap_OverlapFront_Interface) || (iftype == Overlap_All_Interface) )
      {
        dverb << "ALUGrid contains no overlap, therefore no communication for" << std::endl;
        dverb << "Overlap_OverlapFront_Interface or Overlap_All_Interface interfaces!" << std::endl;
      }
      // communication from border to border 
      else if( iftype == InteriorBorder_InteriorBorder_Interface )
        grid.myGrid().borderBorderCommunication(vertexData,edgeData,faceData,elementData);
      // communication from interior to ghost including border 
      else if( iftype == InteriorBorder_All_Interface )
      {
        if( dir == ForwardCommunication )
          grid.myGrid().interiorGhostCommunication(vertexData,edgeData,faceData,elementData);
        // reverse communiction interface (here All_InteriorBorder) 
        else if( dir == BackwardCommunication )
          grid.myGrid().ghostInteriorCommunication(vertexData,edgeData,faceData,elementData);
      }
      // communication from interior to ghost including border 
      else if( iftype == All_All_Interface )
        grid.myGrid().allAllCommunication(vertexData,edgeData,faceData,elementData);
      else
        DUNE_THROW( GridError, "Wrong set of parameters in ALUGridCommHelper::doCommunication" );
    }
  }; // ALU3dGridCommHelper

  template< ALU3dGridElementType elType, class Comm >
  inline bool ALU3dGrid< elType, Comm >::loadBalance ()
  {
    return ALU3dGridCommHelper< elType, Comm >::loadBalance( *this );
  }


  // load balance grid  
  template< ALU3dGridElementType elType, class Comm >
  template< class DataHandle >
  inline bool ALU3dGrid< elType, Comm >::loadBalance ( DataHandle &data )
  {
    return ALU3dGridCommHelper< elType, Comm >::loadBalance( *this, data );
  }


  // communicate level data   
  template< ALU3dGridElementType elType, class Comm >
  template <class DataHandleImp,class DataType> 
  inline void ALU3dGrid< elType, Comm >::
  communicate (CommDataHandleIF<DataHandleImp,DataType> &data, 
               InterfaceType iftype, CommunicationDirection dir, int level ) const
  {
    ALU3dGridCommHelper< elType, Comm >::communicate( *this, data, iftype, dir, level );
  }


  // communicate data   
  template< ALU3dGridElementType elType, class Comm >
  template <class DataHandleImp, class DataType> 
  inline void ALU3dGrid< elType, Comm >::
  communicate (CommDataHandleIF<DataHandleImp,DataType> & data, 
               InterfaceType iftype, CommunicationDirection dir) const
  {
    ALU3dGridCommHelper< elType, Comm >::communicate( *this, data, iftype, dir );
  }


  // return Grid name 
  template< ALU3dGridElementType elType, class Comm >
  inline std::string ALU3dGrid< elType, Comm >::name ()
  {
    if( elType == hexa )
      return "ALUCubeGrid";
    else
      return "ALUSimplexGrid";
  }

} // end namespace Dune