Skip to content
Snippets Groups Projects
grid_inline.hh 17.6 KiB
Newer Older
// 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 )
    , factory_( *this )
    , lockPostAdapt_( false )
    , bndPrj_ ( bndPrj )
    , bndVec_ ( (bndVec) ? (new DuneBoundaryProjectionVector( *bndVec )) : 0 )
    , vertexProjection_( (bndPrj || bndVec) ? new ALUGridBoundaryProjectionType( *this ) : 0 )
    , communications_( new Communications( mpiComm ) )
    , refinementType_( refinementType )
    , nonConformingGeoInFatherStorage_( makeGeometries() )
  {
    // check macro grid file for keyword 
    checkMacroGridFile( macroTriangFilename );
   
    mygrid_ = createALUGrid( macroTriangFilename );
    alugrid_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 >
  const typename ALU3dGrid< elType, Comm >::GeometryInFatherStorage& 
  ALU3dGrid< elType, Comm >::makeGeometries()
  {
    alugrid_assert ( elType == tetra || elType == hexa );

    geomTypes_.clear();
    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 );
    }

    // initialize static storage variables 
    ALU3dGridGeometry< 0, 3, const ThisType> :: geoProvider();
    ALU3dGridGeometry< 1, 3, const ThisType> :: geoProvider();
    ALU3dGridGeometry< 2, 3, const ThisType> :: geoProvider();
    ALU3dGridGeometry< 3, 3, const ThisType> :: geoProvider();

    // return non-conforming geometryInFather storage
    // true == non-conforming 
    return GeometryInFatherStorage :: storage( geomTypes_[ 0 ][ 0 ], true );
  }


  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
  {
    alugrid_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
  {
    alugrid_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
  {
    alugrid_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
  {
    alugrid_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
  {
    alugrid_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
  {
    alugrid_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 )
  {
    alugrid_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( factory(), this->maxLevel() ) );
    EntityObject son   ( EntityImp( factory(), 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; }
  }; // 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 )
      {
        // 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.factory(), grid.maxLevel()) );
      EntityObject father ( EntityImp( grid.factory(), grid.maxLevel()) );
      EntityObject son    ( EntityImp( grid.factory(), 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 )
      {
        // 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;
    }
  }; // 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 >::loadBalanceImpl ( DataHandle &data )
  {
    return ALU3dGridCommHelper< elType, Comm >::loadBalance( *this, data );
  }

  template< ALU3dGridElementType elType, class Comm >
  inline void ALU3dGrid< elType, Comm >::finalizeGridCreation()
  {
    // distribute the grid 
    loadBalance();

    // free memory by reinitializing the grid 
    mygrid_ = GitterImplType :: compress( mygrid_ );

Robert Kloefkorn's avatar
Robert Kloefkorn committed
    // update all internal structures 
    updateStatus();

    // call post adapt
    postAdapt();
  }


  // 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