1 #ifndef DUNE_FEM_DOFMANAGER_HH 2 #define DUNE_FEM_DOFMANAGER_HH 3 4 #include <cassert> 5 #include <string> 6 #include <list> 7 8 #include <dune/common/exceptions.hh> 9 #include <dune/common/stdstreams.hh> 10 #include <dune/common/version.hh> 11 12 #if HAVE_DUNE_ALUGRID 13 #include <dune/alugrid/common/interfaces.hh> 14 #endif 15 16 #include <dune/fem/gridpart/common/indexset.hh> 17 #include <dune/fem/io/parameter.hh> 18 #include <dune/fem/io/streams/standardstreams.hh> 19 #include <dune/fem/misc/gridobjectstreams.hh> 20 #include <dune/fem/misc/threads/threadmanager.hh> 21 #include <dune/fem/space/common/datacollector.hh> 22 #include <dune/fem/space/common/restrictprolonginterface.hh> 23 #include <dune/fem/space/mapper/dofmapper.hh> 24 #include <dune/fem/storage/dynamicarray.hh> 25 #include <dune/fem/storage/singletonlist.hh> 26 27 #include <dune/grid/common/datahandleif.hh> 28 #if HAVE_DUNE_ALUGRID 29 #include <dune/alugrid/common/ldbhandleif.hh> 30 #endif 31 32 namespace Dune 33 { 34 35 namespace Fem 36 { 37 38 /** @addtogroup DofManager 39 40 @{ 41 **/ 42 43 // forward declaration 44 template <class GridType> class DofManager; 45 template <class DofManagerImp> class DofManagerFactory; 46 47 48 /////////////////////////////////////////////////////////////////////// 49 // 50 // ManagedIndexSetInterface 51 // 52 /////////////////////////////////////////////////////////////////////// 53 /*! This class is the virtual interface for the index sets managed by 54 the DofManager. The derived classes are of the type ManagedIndexSet<IndexSet>. 55 This means we don't have to inherit every index set we want to use with 56 this DofManager. 57 */ 58 class ManagedIndexSetInterface 59 { 60 ManagedIndexSetInterface(const ManagedIndexSetInterface& org); 61 protected: 62 // use address of object as id 63 typedef const void * IdentifierType; 64 // pointer to compare index sets 65 IdentifierType setPtr_; 66 // reference counter 67 size_t referenceCounter_; 68 69 template< class IndexSet > ManagedIndexSetInterface(const IndexSet & iset)70 explicit ManagedIndexSetInterface ( const IndexSet &iset ) 71 : setPtr_( getIdentifier( iset ) ), 72 referenceCounter_( 1 ) 73 { 74 } 75 76 public: 77 virtual ~ManagedIndexSetInterface () = default; 78 79 //! resize of index set 80 virtual void resize () = 0; 81 //! compress of index set 82 virtual bool compress () = 0; 83 84 /** \copydoc Dune::PersistentObject :: backup */ 85 virtual void backup() const = 0; 86 /** \copydoc Dune::PersistentObject :: restore */ 87 virtual void restore() = 0; 88 89 //! new read/write methods using binary streams 90 virtual void write( StandardOutStream& out ) const = 0; 91 virtual void read( StandardInStream& out ) = 0; 92 93 //! increase reference counter addReference()94 void addReference ( ) { ++referenceCounter_; } 95 96 //! decrease reference counter and return true if zero reached removeReference()97 bool removeReference ( ) 98 { 99 return (--referenceCounter_ == 0); 100 } 101 102 template< class IndexSet > equals(const IndexSet & iset) const103 bool equals ( const IndexSet &iset ) const 104 { 105 return (getIdentifier( iset ) == setPtr_); 106 } 107 108 private: 109 template< class IndexSet > getIdentifier(const IndexSet & iset) const110 IdentifierType getIdentifier ( const IndexSet &iset ) const 111 { 112 return static_cast< IdentifierType >( &iset ); 113 } 114 }; 115 116 template <class IndexSetType, class EntityType> class RemoveIndicesFromSet; 117 template <class IndexSetType, class EntityType> class InsertIndicesToSet; 118 119 template <class IndexSetType, class EntityType> 120 class ManagedIndexSet : 121 public ManagedIndexSetInterface , 122 public LocalInlinePlus < ManagedIndexSet<IndexSetType,EntityType> , EntityType > 123 { 124 typedef LocalInterface<EntityType> LocalIndexSetObjectsType; 125 protected: 126 // the dof set stores number of dofs on entity for each codim 127 IndexSetType & indexSet_; 128 129 // insertion and removal of indices 130 InsertIndicesToSet <IndexSetType, EntityType> insertIdxObj_; 131 RemoveIndicesFromSet <IndexSetType, EntityType> removeIdxObj_; 132 133 LocalIndexSetObjectsType & indexSetList_; 134 LocalIndexSetObjectsType & insertList_; 135 LocalIndexSetObjectsType & removeList_; 136 137 public: 138 //! type of base class 139 typedef ManagedIndexSetInterface BaseType; 140 141 //! Constructor of MemObject, only to call from DofManager ManagedIndexSet(const IndexSetType & iset,LocalIndexSetObjectsType & indexSetList,LocalIndexSetObjectsType & insertList,LocalIndexSetObjectsType & removeList)142 ManagedIndexSet ( const IndexSetType & iset, 143 LocalIndexSetObjectsType & indexSetList, 144 LocalIndexSetObjectsType & insertList, 145 LocalIndexSetObjectsType & removeList ) 146 : BaseType( iset ) 147 , indexSet_ (const_cast<IndexSetType &> (iset)) 148 , insertIdxObj_(indexSet_), removeIdxObj_(indexSet_) 149 , indexSetList_(indexSetList) 150 , insertList_(insertList) 151 , removeList_(removeList) 152 { 153 this->setPtr_ = (void *) &indexSet_; 154 155 indexSetList_ += *this; 156 if( Capabilities::isConsecutiveIndexSet<IndexSetType>::v ) 157 { 158 insertList_ += insertIdxObj_; 159 removeList_ += removeIdxObj_; 160 } 161 } 162 163 //! desctructor ~ManagedIndexSet()164 ~ManagedIndexSet () 165 { 166 indexSetList_.remove( *this ); 167 if( Capabilities::isConsecutiveIndexSet<IndexSetType>::v ) 168 { 169 insertList_.remove( insertIdxObj_ ); 170 removeList_.remove( removeIdxObj_ ); 171 } 172 } 173 174 //! wrap resize of index set resize()175 void resize () 176 { 177 indexSet_.resize(); 178 } 179 180 //! wrap compress of index set compress()181 bool compress () 182 { 183 return indexSet_.compress(); 184 } 185 186 // forward backup call to indexSet backup() const187 virtual void backup () const 188 { 189 indexSet_.backup(); 190 } 191 192 // forward restore call to indexSet restore()193 virtual void restore () 194 { 195 indexSet_.restore(); 196 } 197 198 //! new write method read(StandardInStream & in)199 virtual void read( StandardInStream& in ) { indexSet_.read( in ); } 200 201 //! new write method write(StandardOutStream & out) const202 virtual void write( StandardOutStream& out ) const { indexSet_.write( out ); } 203 }; 204 205 ///////////////////////////////////////////////////////////// 206 // 207 // DofStorageInterface 208 // 209 ///////////////////////////////////////////////////////////// 210 /** \brief Interface class for a dof storage object to be stored in 211 discrete functions */ 212 class DofStorageInterface 213 { 214 protected: 215 //! do not allow to create explicit instances 216 DofStorageInterface() = default; 217 218 public: 219 //! destructor 220 virtual ~DofStorageInterface() = default; 221 222 //! enable dof compression for dof storage (default is empty) enableDofCompression()223 virtual void enableDofCompression() { } 224 225 //! size of space, i.e. mapper.size() 226 virtual int size () const = 0; 227 }; 228 229 230 /** \brief Interface class for a dof storage object that can be managed 231 (resized and compressed) by the DofManager 232 */ 233 class ManagedDofStorageInterface : public DofStorageInterface 234 { 235 protected: 236 //! do not allow to create explicit instances 237 ManagedDofStorageInterface() = default; 238 239 public: 240 //! destructor 241 virtual ~ManagedDofStorageInterface() = default; 242 243 //! resize memory 244 virtual void resize ( const bool enlargeOnly ) = 0; 245 //! resize memory 246 virtual void reserve (int newSize) = 0; 247 //! compressed the underlying dof vector and clear the array if it's 248 //! temporary and clearresizedarrays is enabled (default) 249 virtual void dofCompress ( const bool clearResizedArrays ) = 0; 250 //! return size of mem used by MemObject 251 virtual size_t usedMemorySize() const = 0; 252 }; 253 254 255 template <class MemObjectType> class ResizeMemoryObjects; 256 template <class MemObjectType> class ReserveMemoryObjects; 257 258 /*! 259 A ManagedDofStorage holds the memory for one DiscreteFunction and the 260 corresponding DofArrayMemory. ManagedDofStorageImplementation implements the 261 basic features such as resize and dof compression. If a DiscreteFunction is signed in by a 262 function space, then such a MemObject is created by the DofManager. 263 The MemObject also knows the DofMapper from the function space which the 264 discrete function belongs to. Here we dont know the exact type of the dof 265 mapper therefore the methods newSize and calcInsertPoints of the mappers 266 have to be virtual. This isnt a problem because this methods should only 267 be called during memory reorganizing which is only once per timestep. 268 */ 269 template <class GridImp, class MapperType , class DofArrayType> 270 class ManagedDofStorageImplementation : public ManagedDofStorageInterface 271 { 272 // interface for MemObject lists 273 typedef LocalInterface< int > MemObjectCheckType; 274 protected: 275 // type of this class 276 typedef ManagedDofStorageImplementation <GridImp, MapperType , DofArrayType> ThisType; 277 278 typedef DofManager<GridImp> DofManagerType; 279 280 // reference to dof manager 281 DofManagerType &dm_; 282 283 // the dof set stores number of dofs on entity for each codim 284 MapperType &mapper_; 285 286 // Array which the dofs are stored in 287 DofArrayType& array_; 288 289 typedef ResizeMemoryObjects < ThisType > ResizeMemoryObjectType; 290 typedef ReserveMemoryObjects < ThisType > ReserveMemoryObjectType; 291 ResizeMemoryObjectType resizeMemObj_; 292 ReserveMemoryObjectType reserveMemObj_; 293 294 // true if data need to be compressed 295 bool dataCompressionEnabled_; 296 297 public: 298 ManagedDofStorageImplementation(const ManagedDofStorageImplementation& ) = delete; 299 300 protected: 301 //! Constructor of ManagedDofStorageImplementation, only to call from derived classes ManagedDofStorageImplementation(const GridImp & grid,const MapperType & mapper,DofArrayType & array)302 ManagedDofStorageImplementation ( const GridImp& grid, 303 const MapperType& mapper, 304 DofArrayType& array ) 305 : dm_( DofManagerType :: instance( grid ) ), 306 mapper_ ( const_cast<MapperType& >(mapper)), 307 array_( array ), 308 resizeMemObj_(*this), 309 reserveMemObj_(*this), 310 dataCompressionEnabled_(false) 311 { 312 // add to dof manager 313 dm_.addDofStorage( *this ); 314 315 // set memory over estimate factor, only for DofArray 316 array_.setMemoryFactor( dm_.memoryFactor() ); 317 } 318 319 //! \brief destructor deleting MemObject from resize and reserve List ~ManagedDofStorageImplementation()320 ~ManagedDofStorageImplementation() 321 { 322 // remove from dof manager 323 dm_.removeDofStorage( *this ); 324 } 325 326 public: 327 //! return object that calls resize of this memory object resizeMemoryObject()328 ResizeMemoryObjectType& resizeMemoryObject() { return resizeMemObj_; } 329 330 //! return object that calls reserve of this memory object reserveMemoryObject()331 ReserveMemoryObjectType& reserveMemoryObject() { return reserveMemObj_; } 332 333 //! return size of underlying array size() const334 int size () const { return array_.size(); } 335 336 //! resize the memory with the new size resize(const bool enlargeOnly)337 void resize ( const bool enlargeOnly ) 338 { 339 resize( std::integral_constant< bool, Capabilities::isAdaptiveDofMapper< MapperType >::v >(), enlargeOnly ); 340 } 341 342 //! reserve memory for what is comming reserve(const int needed)343 inline void reserve ( const int needed ) 344 { 345 // if index set is compressible, then add requested size 346 if( mapper().consecutive() ) 347 { 348 const int nSize = size() + (needed * mapper().maxNumDofs()); 349 array_.reserve( nSize ); 350 } 351 else 352 { 353 // if compress is not needed just resize with given size 354 // therefore use newSize to enleage array 355 assert( ! mapper().consecutive() ); 356 // resize array 357 resize ( false ); 358 } 359 } 360 361 //! copy the dof from the rear section of the vector to the holes dofCompress(const bool clearResizedArrays)362 void dofCompress ( const bool clearResizedArrays ) 363 { 364 // get current size 365 const int nSize = mapper().size(); 366 367 // if data is non-temporary do data compression 368 if( dataCompressionEnabled_ ) 369 { 370 // get old size (which we still have in array) 371 const int oldSize = array_.size(); 372 373 // NOTE: new size can also be larger than old size 374 // e.g. during loadBalancing when ghosts where 375 // introduced before compressing the index set 376 377 // begin with block zero since closing of holes 378 // has to be done anyway if the mapper is consecutive 379 const int numBlocks = mapper().numBlocks(); 380 for( int block = 0; block < numBlocks; ++block ) 381 { 382 // move memory 383 moveToFront( oldSize, block ); 384 385 // only close holes for consecutive mappers 386 if( mapper().consecutive () ) 387 { 388 // run over all holes and copy array vules to new place 389 const int holes = mapper().numberOfHoles( block ); 390 for( int i = 0; i < holes; ++i ) 391 { 392 const int oldIndex = mapper().oldIndex( i, block ); 393 const int newIndex = mapper().newIndex( i, block ); 394 395 assert( newIndex < nSize ); 396 // implements array_[ newIndex ] = array_[ oldIndex ] ; 397 array_.copyContent( newIndex, oldIndex ); 398 } 399 } 400 } 401 } 402 403 // store new size, which should be smaller then actual size 404 array_.resize( nSize ); 405 406 if( clearResizedArrays && ! dataCompressionEnabled_ ) 407 { 408 // if enabled clear temporary data to avoid occasionally NaN values 409 array_.clear(); 410 } 411 } 412 413 //! return used memory size usedMemorySize() const414 size_t usedMemorySize() const 415 { 416 return ((size_t) sizeof(ThisType) + array_.usedMemorySize()); 417 } 418 419 //! enable dof compression for this MemObject enableDofCompression()420 void enableDofCompression() 421 { 422 dataCompressionEnabled_ = true; 423 } 424 425 //! return reference to array for DiscreteFunction getArray()426 DofArrayType & getArray() { return array_; } 427 428 protected: mapper() const429 inline MapperType &mapper () const 430 { 431 return mapper_; 432 } 433 434 // resize for non-adaptive mappers resize(std::false_type,const bool enlargeOnly)435 void resize ( std::false_type, const bool enlargeOnly ) 436 { 437 // note: The mapper might already have been updated, so do not use 438 // it to obtain old array size. 439 mapper().update(); // make sure the mapper is up2date 440 441 const int newSize = mapper().size(); 442 const int oldSize = array_.size(); 443 444 if( enlargeOnly && newSize < oldSize ) return ; 445 446 if( newSize != oldSize ) 447 array_.resize( newSize ); 448 } 449 450 // resize for adaptive mappers resize(std::true_type,const bool enlargeOnly)451 void resize ( std::true_type, const bool enlargeOnly ) 452 { 453 // note: The mapper is adaptive and has been updated automatically, so 454 // do not use it to obtain old array size. 455 const int oldSize = array_.size(); 456 457 // get current size 458 const int nSize = mapper().size(); 459 460 // if enlarge only option is given only resize 461 // if new size if larger than old size 462 if( enlargeOnly && nSize <= oldSize ) return ; 463 464 // if nothing changed do nothing 465 if( nSize == oldSize ) return ; 466 467 // resize memory to current value 468 array_.resize( nSize ); 469 470 // if data is only temporary data, don't adjust memory 471 if( ! dataCompressionEnabled_ || enlargeOnly ) return ; 472 473 // now check all blocks beginning with the largest 474 const int numBlocks = mapper().numBlocks(); 475 476 // initialize upperBound 477 int upperBound = oldSize ; 478 479 // make sure offset of block 0 is zero 480 assert( mapper().offSet( 0 ) == 0 ); 481 assert( mapper().oldOffSet( 0 ) == 0 ); 482 483 // skip block 0 (since offset == 0) 484 for( int block = numBlocks-1; block >= 1; --block ) 485 { 486 // get offsets 487 const int newOffSet = mapper().offSet( block ); 488 const int oldOffSet = mapper().oldOffSet( block ); 489 490 // make sure new offset is larger 491 assert( newOffSet >= oldOffSet ); 492 493 // if off set is not zero 494 if( newOffSet > oldOffSet ) 495 { 496 // calculate block size 497 const int blockSize = upperBound - oldOffSet; 498 // move block backward 499 array_.memMoveBackward( blockSize, oldOffSet, newOffSet ); 500 501 // update upper bound 502 upperBound = oldOffSet; 503 } 504 } 505 } 506 507 // move array to rear insertion points resizeAndMoveToRear()508 void resizeAndMoveToRear () 509 { 510 } 511 512 //! move block to front again moveToFront(const int oldSize,const int block)513 void moveToFront ( const int oldSize, const int block ) 514 { 515 // get insertion point from block 516 const int oldOffSet = mapper().oldOffSet( block ); 517 518 // get new off set 519 const int newOffSet = mapper().offSet( block ); 520 521 // here we should have at least the same offsets 522 assert( newOffSet <= oldOffSet ); 523 524 // only if block is not starting from zero 525 if( newOffSet < oldOffSet ) 526 { 527 // get number of blocks 528 const int numBlocks = mapper().numBlocks(); 529 530 // for last section upperBound is size 531 const int upperBound 532 = (block == numBlocks - 1) ? oldSize : mapper().oldOffSet( block + 1 ); 533 const int blockSize = upperBound - oldOffSet; 534 535 // move block forward 536 array_.memMoveForward( blockSize, oldOffSet, newOffSet ); 537 } 538 } 539 }; 540 541 /*! A ManagedDofStorage holds the memory for one DiscreteFunction. */ 542 template <class GridImp, class MapperType , class DofArrayType> 543 class ManagedDofStorage : public ManagedDofStorageImplementation< GridImp, MapperType, DofArrayType > 544 { 545 typedef ManagedDofStorageImplementation< GridImp, MapperType, DofArrayType > BaseType; 546 protected: 547 DofArrayType myArray_; 548 public: 549 //! Constructor of ManagedDofStorage ManagedDofStorage(const GridImp & grid,const MapperType & mapper)550 ManagedDofStorage( const GridImp& grid, 551 const MapperType& mapper ) 552 : BaseType( grid, mapper, myArray_ ), 553 myArray_( mapper.size() ) 554 { 555 } 556 }; 557 558 //! default implementation for creating a managed dof storage 559 template< class DofStorageType, class GridType, class MapperType > 560 static inline std::pair< DofStorageInterface* , DofStorageType* > allocateManagedDofStorage(const GridType & grid,const MapperType & mapper,const DofStorageType * =0)561 allocateManagedDofStorage( const GridType& grid, 562 const MapperType& mapper, 563 const DofStorageType * = 0 ) 564 { 565 // create managed dof storage 566 typedef ManagedDofStorage< GridType, MapperType, 567 DofStorageType > ManagedDofStorageType; 568 569 ManagedDofStorageType* mds = new ManagedDofStorageType( grid, mapper ); 570 assert( mds ); 571 572 // return pair with dof storage pointer and array pointer 573 return std::pair< DofStorageInterface* , DofStorageType* > 574 ( mds , & mds->getArray () ); 575 } 576 577 578 579 /////////////////////////////////////////////////////////////// 580 // 581 // RestrictPorlong for Index Sets 582 // 583 /////////////////////////////////////////////////////////////// 584 585 template <class IndexSetType, class EntityType> 586 class RemoveIndicesFromSet 587 : public LocalInlinePlus < RemoveIndicesFromSet<IndexSetType,EntityType> , EntityType > 588 { 589 private: 590 // the dof set stores number of dofs on entity for each codim 591 IndexSetType & indexSet_; 592 593 public: 594 // Constructor of MemObject, only to call from DofManager RemoveIndicesFromSet(IndexSetType & iset)595 explicit RemoveIndicesFromSet ( IndexSetType & iset ) : indexSet_ (iset) {} 596 597 //! apply wraps the removeEntity Method of the index set apply(EntityType & entity)598 inline void apply ( EntityType & entity ) 599 { 600 indexSet_.removeEntity( entity ); 601 } 602 }; 603 604 template <class IndexSetType, class EntityType> 605 class InsertIndicesToSet 606 : public LocalInlinePlus < InsertIndicesToSet< IndexSetType, EntityType > , EntityType > 607 { 608 private: 609 // the dof set stores number of dofs on entity for each codim 610 IndexSetType & indexSet_; 611 612 public: 613 // Constructor of MemObject, only to call from DofManager InsertIndicesToSet(IndexSetType & iset)614 explicit InsertIndicesToSet ( IndexSetType & iset ) : indexSet_ (iset) {} 615 616 //! apply wraps the insertEntity method of the index set apply(EntityType & entity)617 inline void apply ( EntityType & entity ) 618 { 619 indexSet_.insertEntity( entity ); 620 } 621 }; 622 623 template <class MemObjectType> 624 class ResizeMemoryObjects 625 : public LocalInlinePlus < ResizeMemoryObjects < MemObjectType > , int > 626 { 627 private: 628 // the dof set stores number of dofs on entity for each codim 629 MemObjectType & memobj_; 630 631 public: 632 // Constructor of MemObject, only to call from DofManager ResizeMemoryObjects(MemObjectType & mo)633 ResizeMemoryObjects ( MemObjectType & mo ) : memobj_ (mo) {} ResizeMemoryObjects(const ResizeMemoryObjects & org)634 ResizeMemoryObjects ( const ResizeMemoryObjects& org ) 635 : memobj_(org.memobj_) 636 {} 637 638 // resize mem object, parameter not needed apply(int & enlargeOnly)639 inline void apply ( int& enlargeOnly ) 640 { 641 memobj_.resize( bool(enlargeOnly) ); 642 } 643 }; 644 645 // this class is the object for a single MemObject to 646 template <class MemObjectType> 647 class ReserveMemoryObjects 648 : public LocalInlinePlus < ReserveMemoryObjects < MemObjectType > , int > 649 { 650 private: 651 // the dof set stores number of dofs on entity for each codim 652 MemObjectType & memobj_; 653 654 public: 655 // Constructor of MemObject, only to call from DofManager ReserveMemoryObjects(MemObjectType & mo)656 ReserveMemoryObjects ( MemObjectType & mo ) : memobj_ (mo) {} 657 658 // reserve for at least chunkSize new values apply(int & chunkSize)659 inline void apply ( int & chunkSize ) 660 { 661 memobj_.reserve( chunkSize ); 662 } 663 }; 664 665 666 // this is the dofmanagers object which is being used during restriction 667 // and prolongation process for adding and removing indices to and from 668 // index sets which belong to functions that belong to that dofmanager 669 template <class DofManagerType , class RestrictProlongIndexSetType, bool doResize > 670 class IndexSetRestrictProlong : 671 public RestrictProlongInterface< 672 RestrictProlongTraits< 673 IndexSetRestrictProlong<DofManagerType,RestrictProlongIndexSetType,doResize>, double > > 674 { 675 DofManagerType & dm_; 676 677 RestrictProlongIndexSetType & insert_; 678 RestrictProlongIndexSetType & remove_; 679 public: 680 IndexSetRestrictProlong(DofManagerType & dm,RestrictProlongIndexSetType & is,RestrictProlongIndexSetType & rm)681 IndexSetRestrictProlong ( DofManagerType & dm , RestrictProlongIndexSetType & is, RestrictProlongIndexSetType & rm ) 682 : dm_(dm) , insert_( is ), remove_( rm ) {} 683 684 //! restrict data to father and resize memory if doResize is true 685 template <class EntityType> restrictLocal(const EntityType & father,const EntityType & son,bool initialize) const686 inline void restrictLocal ( const EntityType & father, const EntityType & son , bool initialize ) const 687 { 688 // insert index of father 689 insert_.apply( father ); 690 // mark index of son for removal 691 remove_.apply( son ); 692 693 // resize memory if doResize is true 694 if ( doResize ) 695 { 696 dm_.resizeMemory(); 697 } 698 } 699 700 template <class EntityType> restrictFinalize(const EntityType & father) const701 inline void restrictFinalize( const EntityType &father ) const 702 {} 703 704 //! prolong data to children and resize memory if doResize is true 705 template <class EntityType> prolongLocal(const EntityType & father,const EntityType & son,bool initialize) const706 inline void prolongLocal ( const EntityType & father, const EntityType & son , bool initialize ) const 707 { 708 // mark index of father for removal 709 remove_.apply( father ); 710 // insert index of son 711 insert_.apply( son ); 712 713 // resize memory if doResize is true 714 if ( doResize ) 715 { 716 dm_.resizeMemory(); 717 } 718 } 719 }; 720 721 // empty restrict prolong operator 722 class EmptyIndexSetRestrictProlong : 723 public RestrictProlongInterface< RestrictProlongTraits< EmptyIndexSetRestrictProlong, double > > 724 { 725 public: EmptyIndexSetRestrictProlong()726 EmptyIndexSetRestrictProlong() {} 727 //! restrict data to father and resize memory if doResize is true 728 template <class EntityType> restrictLocal(EntityType & father,EntityType & son,bool initialize) const729 inline void restrictLocal ( EntityType & father, EntityType & son , bool initialize ) const {} 730 //! prolong data to children and resize memory if doResize is true 731 template <class EntityType> prolongLocal(EntityType & father,EntityType & son,bool initialize) const732 inline void prolongLocal ( EntityType & father, EntityType & son , bool initialize ) const {} 733 }; 734 735 736 class DofManError : public Exception {}; 737 738 /*! 739 The DofManager is responsible for managing memory allocation and freeing 740 for all discrete functions living on the grid the manager belongs to. 741 There is only one DofManager per grid. 742 Each discrete function knows its dofmanager and can sign in. 743 If the grid is adapted, then the 744 dofmanager reorganizes the memory if necessary. The DofManager holds a 745 list of MemObjects which manage the memory and the corresponding 746 mapper so they can determine the size of new memory. 747 Furthermore the DofManager holds an IndexSet which the DofMapper needs for 748 calculating the indices in the dof vector for a given entity and local dof 749 number. This IndexSet is delivered to the mapper when a function space is 750 created. The default value for the IndexSet is the DefaultIndexSet class 751 which is mostly a wrapper for the grid indices. 752 */ 753 // --DofManager 754 template< class Grid > 755 class DofManager : 756 #if HAVE_DUNE_ALUGRID 757 public IsDofManager, 758 public LoadBalanceHandleWithReserveAndCompress, 759 #endif 760 // DofManager behaves like a communication data handle for load balancing 761 public CommDataHandleIF< DofManager< Grid >, char > 762 { 763 typedef DofManager< Grid > ThisType; 764 765 friend struct DefaultSingletonFactory< const Grid*, ThisType >; 766 friend class DofManagerFactory< ThisType >; 767 768 public: 769 //! type of Grid this DofManager belongs to 770 typedef Grid GridType; 771 772 typedef typename GridObjectStreamTraits< GridType >::InStreamType XtractStreamImplType; 773 typedef typename GridObjectStreamTraits< GridType >::OutStreamType InlineStreamImplType; 774 public: 775 // types of inlining and xtraction stream types 776 typedef MessageBufferIF< XtractStreamImplType > XtractStreamType; 777 typedef MessageBufferIF< InlineStreamImplType > InlineStreamType; 778 779 // types of data collectors 780 typedef DataCollectorInterface<GridType, XtractStreamType > DataXtractorType; 781 typedef DataCollectorInterface<GridType, InlineStreamType > DataInlinerType; 782 783 typedef typename GridType :: template Codim< 0 > :: Entity ElementType ; 784 785 private: 786 typedef std::list< ManagedDofStorageInterface* > ListType; 787 typedef LocalInterface< int > MemObjectCheckType; 788 typedef std::list< ManagedIndexSetInterface * > IndexListType; 789 790 // list with MemObjects, for each DiscreteFunction we have one MemObject 791 ListType memList_; 792 793 // list of all different indexsets 794 IndexListType indexList_; 795 796 // the dofmanager belong to one grid only 797 const GridType &grid_; 798 799 // index set for mapping 800 mutable DataInlinerType dataInliner_; 801 mutable DataXtractorType dataXtractor_; 802 803 //! type of IndexSet change interfaces 804 //// use const Entities as parameters (typedef here to avoid confusion) 805 typedef const ElementType ConstElementType; 806 typedef LocalInterface< ConstElementType > LocalIndexSetObjectsType; 807 808 mutable LocalIndexSetObjectsType indexSets_; 809 810 mutable LocalIndexSetObjectsType insertIndices_; 811 mutable LocalIndexSetObjectsType removeIndices_; 812 813 // lists containing all MemObjects 814 // to have fast access during resize and reserve 815 mutable MemObjectCheckType resizeMemObjs_; 816 mutable MemObjectCheckType reserveMemObjs_; 817 818 //! if chunk size if small then defaultChunkSize is used 819 const int defaultChunkSize_; 820 821 //! number of sequence, incremented every resize is called 822 int sequence_; 823 824 public: 825 typedef IndexSetRestrictProlong< ThisType, LocalIndexSetObjectsType , true > 826 NewIndexSetRestrictProlongType; 827 typedef IndexSetRestrictProlong< ThisType, LocalIndexSetObjectsType , false > 828 IndexSetRestrictProlongNoResizeType; 829 830 // old type 831 typedef EmptyIndexSetRestrictProlong IndexSetRestrictProlongType; 832 833 // this class needs to call resizeMemory 834 friend class IndexSetRestrictProlong< ThisType , LocalIndexSetObjectsType , true > ; 835 friend class IndexSetRestrictProlong< ThisType , LocalIndexSetObjectsType , false > ; 836 837 private: 838 // combine object holding all index set for restrict and prolong 839 NewIndexSetRestrictProlongType indexSetRestrictProlong_; 840 IndexSetRestrictProlongNoResizeType indexSetRestrictProlongNoResize_; 841 842 // old type 843 IndexSetRestrictProlongType indexRPop_; 844 845 //! memory over estimation factor for re-allocation 846 double memoryFactor_; 847 848 //! true if temporary arrays should be reset to zero after resize 849 const bool clearResizedArrays_; 850 851 //********************************************************** 852 //********************************************************** 853 //! Constructor DofManager(const GridType * grid)854 inline explicit DofManager ( const GridType *grid ) 855 : grid_( *grid ), 856 defaultChunkSize_( 128 ), 857 sequence_( 0 ), 858 indexSetRestrictProlong_( *this, insertIndices_ , removeIndices_ ), 859 indexSetRestrictProlongNoResize_( *this, insertIndices_ , removeIndices_ ), 860 indexRPop_(), 861 memoryFactor_( Parameter :: getValidValue( "fem.dofmanager.memoryfactor", double( 1.1 ), 862 [] ( double value ) { return value >= 1.0; } ) ), 863 clearResizedArrays_( Parameter :: getValue("fem.dofmanager.clearresizedarrays", bool( true ) ) ) 864 { 865 // only print memory factor if it deviates from the default value 866 if( std::abs( memoryFactor_ - 1.1 ) > 1e-12 ) 867 if( Parameter::verbose() && (grid_.comm().rank() == 0) ) 868 std::cout << "Created DofManager with memory factor " << memoryFactor_ << "." << std::endl; 869 } 870 871 //! Desctructor, removes all MemObjects and IndexSetObjects 872 ~DofManager (); 873 874 public: 875 DofManager( const ThisType& ) = delete; 876 877 //! return factor to over estimate new memory allocation memoryFactor() const878 double memoryFactor() const { return memoryFactor_; } 879 880 /** \brief add index set to dof manager's list of index sets 881 * 882 * During adaptation, all index sets known to the dof manager are notified 883 * of the changes. 884 * 885 * To register an index set with the dof manager, it has to satisfy the 886 * following interface: 887 * \code 888 * void insertEntity ( const Element & ); 889 * void removeEntity ( const Element & ); 890 * void resize(); 891 * bool compress(); 892 * void write( OutStreamInterface<Traits>& ); 893 * void read( InStreamInterface<Traits>& ) 894 * \endcode 895 * 896 * \param[in] iset index set to add to list 897 */ 898 template <class IndexSetType> 899 inline void addIndexSet (const IndexSetType &iset ); 900 901 /** \brief removed index set from dof manager's list of index sets 902 * 903 * During adaptation, all index sets known to the dof manager are notified 904 * of the changes. 905 * 906 * \param[in] iset index set to add to list 907 */ 908 template <class IndexSetType> 909 inline void removeIndexSet (const IndexSetType &iset ); 910 911 /** \brief add a managed dof storage to the dof manager. 912 \param dofStorage dof storage to add which must fulfill the 913 ManagedDofStorageInterface 914 */ 915 template <class ManagedDofStorageImp> 916 void addDofStorage(ManagedDofStorageImp& dofStorage); 917 918 /** \brief remove a managed dof storage from the dof manager. 919 \param dofStorage dof storage to remove which must fulfill the 920 ManagedDofStorageInterface 921 */ 922 template <class ManagedDofStorageImp> 923 void removeDofStorage(ManagedDofStorageImp& dofStorage); 924 925 //! returns the index set restriction and prolongation operator indexSetRestrictProlong()926 NewIndexSetRestrictProlongType & indexSetRestrictProlong () 927 { 928 // hier muss statt dessen ein Combiniertes Object erzeugt werden. 929 // dafuer sollte bei einhaengen der IndexSets ein Methoden Pointer 930 // erzeugt werden, welcher die den IndexSet mit einem anderen Object 931 // kombiniert 932 return indexSetRestrictProlong_; 933 } 934 935 //! returns the index set restriction and prolongation operator indexSetRestrictProlongNoResize()936 IndexSetRestrictProlongNoResizeType& indexSetRestrictProlongNoResize() 937 { 938 // return index set restrict/prolong operator that is only inserting 939 // and mark for removal indices but not doing resize 940 return indexSetRestrictProlongNoResize_; 941 } 942 943 //! if dofmanagers list is not empty return true hasIndexSets() const944 bool hasIndexSets() const 945 { 946 return ! insertIndices_.empty(); 947 } 948 949 /** \brief return used memory size of all MemObjects in bytes. */ usedMemorySize() const950 size_t usedMemorySize () const 951 { 952 size_t used = 0; 953 for(auto memObjectPtr : memList_) 954 used += memObjectPtr->usedMemorySize(); 955 return used; 956 } 957 958 /** \brief resize memory before data restriction 959 during grid adaptation is done. 960 */ resizeForRestrict()961 void resizeForRestrict () 962 { 963 resizeMemory(); 964 } 965 966 /** \brief reserve memory for at least nsize elements, 967 * dummy is needed for dune-grid ALUGrid version */ reserveMemory(int nsize,bool dummy=false)968 void reserveMemory ( int nsize, bool dummy = false ) 969 { 970 int localChunkSize = std::max(nsize, defaultChunkSize_ ); 971 assert( localChunkSize > 0 ); 972 973 // reserves (size + chunkSize * elementMemory), see above 974 reserveMemObjs_.apply ( localChunkSize ); 975 } 976 977 /** \brief return number of sequence, if dofmanagers memory was changed by 978 calling some method like resize, then also this number will increase 979 \note The increase of this number could be larger than 1 980 */ sequence() const981 int sequence () const { return sequence_; } 982 983 /** \brief Resize index sets and memory due to what the mapper has as new size. 984 \note This will increase the sequence counter by 1. 985 */ resize()986 void resize() 987 { 988 for(auto indexSetPtr : indexList_) 989 indexSetPtr->resize(); 990 resizeMemory(); 991 } 992 993 /** \brief Inserts entity to all index sets added to dof manager. */ insertEntity(ConstElementType & element)994 inline void insertEntity( ConstElementType & element ) 995 { 996 // insert new index 997 insertIndices_.apply( element ); 998 999 // resize memory 1000 resizeMemory(); 1001 } 1002 1003 /** \brief Removes entity from all index sets added to dof manager. */ removeEntity(ConstElementType & element)1004 inline void removeEntity( ConstElementType & element ) 1005 { 1006 removeIndices_.apply( element ); 1007 } 1008 1009 //! resize the MemObject if necessary resizeMemory()1010 void resizeMemory() 1011 { 1012 int enlargeOnly = 0; 1013 // pass dummy parameter 1014 resizeMemObjs_.apply ( enlargeOnly ); 1015 } 1016 1017 //! resize the MemObject if necessary enlargeMemory()1018 void enlargeMemory() 1019 { 1020 int enlargeOnly = 1; 1021 // pass dummy parameter 1022 resizeMemObjs_.apply ( enlargeOnly ); 1023 } 1024 1025 /** \brief increase the DofManagers internal sequence number 1026 \note This will increase the sequence counter by 1. 1027 */ incrementSequenceNumber()1028 void incrementSequenceNumber () 1029 { 1030 // mark next sequence 1031 ++sequence_; 1032 1033 // check that sequence number is the same for all processes 1034 assert( sequence_ == grid_.comm().max( sequence_ ) ); 1035 } 1036 1037 //- --compress 1038 /** \brief Compress all data that is hold by this dofmanager 1039 \note This will increase the sequence counter by 1. 1040 */ compress()1041 void compress() 1042 { 1043 // mark next sequence 1044 incrementSequenceNumber (); 1045 1046 // compress indexsets first 1047 for(auto indexSetPtr : indexList_) 1048 { 1049 // reset compressed so the next time compress of index set is called 1050 indexSetPtr->compress(); 1051 } 1052 1053 // compress all data now 1054 for(auto memObjectPtr : memList_) 1055 { 1056 // if correponding index was not compressed yet, this is called in 1057 // the MemObject dofCompress, if index has not changes, nothing happens 1058 // if IndexSet actual needs no compress, nothing happens to the 1059 // data either 1060 // also data is resized, which means the vector is getting shorter 1061 memObjectPtr->dofCompress ( clearResizedArrays_ ); 1062 } 1063 } 1064 1065 //! communicate new sequence number notifyGlobalChange(const bool wasChanged) const1066 bool notifyGlobalChange( const bool wasChanged ) const 1067 { 1068 // make sure that wasChanged is the same on all cores 1069 int wasChangedCounter = int( wasChanged ); 1070 return bool( grid_.comm().max( wasChangedCounter ) ); 1071 } 1072 1073 //! add data handler for data inlining to dof manager 1074 template <class DataCollType> addDataInliner(DataCollType & d)1075 void addDataInliner ( DataCollType & d) 1076 { 1077 dataInliner_ += d; 1078 } 1079 1080 //! clear data inliner list clearDataInliners()1081 void clearDataInliners () 1082 { 1083 dataInliner_.clear(); 1084 } 1085 1086 //! add data handler for data xtracting to dof manager 1087 template <class DataCollType> addDataXtractor(DataCollType & d)1088 void addDataXtractor ( DataCollType & d) 1089 { 1090 dataXtractor_ += d; 1091 } 1092 1093 //! clear data xtractor list clearDataXtractors()1094 void clearDataXtractors () 1095 { 1096 dataXtractor_.clear(); 1097 } 1098 1099 ////////////////////////////////////////////////////////// 1100 // CommDataHandleIF methods 1101 ////////////////////////////////////////////////////////// 1102 1103 //! the dof manager only transfers element data during load balancing contains(const int dim,const int codim) const1104 bool contains( const int dim, const int codim ) const 1105 { 1106 return ( codim == 0 ); 1107 } 1108 1109 //! fixed size is false fixedSize(const int dim,const int codim) const1110 bool fixedSize( const int dim, const int codim ) const 1111 { 1112 return false; 1113 } 1114 1115 //! for convenience 1116 template <class Entity> size(const Entity &) const1117 size_t size( const Entity& ) const 1118 { 1119 DUNE_THROW(NotImplemented,"DofManager::size should not be called!"); 1120 return 0; 1121 } 1122 1123 //! packs all data attached to this entity gather(InlineStreamType & str,ConstElementType & element) const1124 void gather( InlineStreamType& str, ConstElementType& element ) const 1125 { 1126 dataInliner_.apply(str, element); 1127 1128 // remove entity from index sets 1129 const_cast< ThisType & >( *this ).removeEntity( element ); 1130 } 1131 1132 template <class MessageBuffer, class Entity> gather(MessageBuffer & str,const Entity & entity) const1133 void gather( MessageBuffer& str, const Entity& entity ) const 1134 { 1135 DUNE_THROW(NotImplemented,"DofManager::gather( entity ) with codim > 0 not implemented"); 1136 } 1137 1138 //! unpacks all data attached of this entity from message buffer scatter(XtractStreamType & str,ConstElementType & element,size_t)1139 void scatter ( XtractStreamType& str, ConstElementType& element, size_t ) 1140 { 1141 // insert entity into index sets 1142 insertEntity( element ); 1143 1144 // here the elements already have been created 1145 // that means we can xtract data 1146 dataXtractor_.apply(str, element); 1147 } 1148 1149 //! unpacks all data of this entity from message buffer 1150 template <class MessageBuffer, class Entity> scatter(MessageBuffer & str,const Entity & entity,size_t)1151 void scatter ( MessageBuffer & str, const Entity& entity, size_t ) 1152 { 1153 DUNE_THROW(NotImplemented,"DofManager::scatter( entity ) with codim > 0 not implemented"); 1154 } 1155 1156 //******************************************************** 1157 // Interface for PersistentObjects 1158 //******************************************************** 1159 1160 /** \copydoc Dune::PersistentObject :: backup */ backup() const1161 void backup () const 1162 { 1163 for(auto indexSetPtr : indexList_) 1164 indexSetPtr->backup(); 1165 } 1166 1167 /** \copydoc Dune::PersistentObject :: restore */ restore()1168 void restore () 1169 { 1170 for(auto indexSetPtr : indexList_) 1171 indexSetPtr->restore(); 1172 1173 // make all index sets consistent 1174 // before any data is read this can be 1175 // assured since DofManager is an 1176 // AutoPersistentObject and thus in the 1177 // beginning of the list, fater the grid of course 1178 resize(); 1179 } 1180 1181 //******************************************************** 1182 // read/write using fem streams 1183 //******************************************************** 1184 /** \brief write all index sets to a given stream 1185 * 1186 * \param[out] out stream to write to 1187 */ 1188 template < class OutStream > write(OutStream & out) const1189 void write( OutStream& out ) const 1190 { 1191 for(auto indexSetPtr : indexList_) 1192 indexSetPtr->write( out ); 1193 } 1194 1195 /** \brief read all index sets from a given stream 1196 * 1197 * \param[in] in stream to read from 1198 */ 1199 template < class InStream > read(InStream & in)1200 void read( InStream& in ) 1201 { 1202 for(auto indexSetPtr : indexList_) 1203 indexSetPtr->read( in ); 1204 } 1205 1206 //******************************************************** 1207 // Interface for DofManager access 1208 //******************************************************** 1209 1210 /** \brief obtain a reference to the DofManager for a given grid 1211 * 1212 * \param[in] grid grid for which the DofManager is desired 1213 * 1214 * \returns a reference to the singleton instance of the DofManager 1215 */ instance(const GridType & grid)1216 static inline ThisType& instance( const GridType& grid ) 1217 { 1218 typedef DofManagerFactory< ThisType > DofManagerFactoryType; 1219 return DofManagerFactoryType :: instance( grid ); 1220 } 1221 }; 1222 1223 //*************************************************************************** 1224 // 1225 // inline implemenations 1226 // 1227 //*************************************************************************** 1228 1229 template <class GridType> ~DofManager()1230 inline DofManager<GridType>::~DofManager () 1231 { 1232 if(memList_.size() > 0) 1233 { 1234 while( memList_.rbegin() != memList_.rend()) 1235 { 1236 DofStorageInterface * mobj = (* memList_.rbegin() ); 1237 dverb << "Removing '" << mobj << "' from DofManager!\n"; 1238 memList_.pop_back(); 1239 } 1240 } 1241 1242 if(indexList_.size() > 0) 1243 { 1244 #ifndef NDEBUG 1245 std::cerr << "ERROR: Not all index sets have been removed from DofManager yet!" << std::endl; 1246 #endif 1247 while ( indexList_.rbegin() != indexList_.rend()) 1248 { 1249 ManagedIndexSetInterface* iobj = (* indexList_.rbegin() ); 1250 indexList_.pop_back(); 1251 if(iobj) delete iobj; 1252 } 1253 } 1254 } 1255 1256 template <class GridType> 1257 template <class IndexSetType> 1258 inline void DofManager<GridType>:: addIndexSet(const IndexSetType & iset)1259 addIndexSet (const IndexSetType &iset ) 1260 { 1261 assert( Fem :: ThreadManager:: singleThreadMode() ); 1262 1263 typedef ManagedIndexSet< IndexSetType, ConstElementType > ManagedIndexSetType; 1264 ManagedIndexSetType * indexSet = 0; 1265 1266 // search index set list in reverse order to find latest index sets faster 1267 auto endit = indexList_.rend(); 1268 for(auto it = indexList_.rbegin(); it != endit; ++it ) 1269 { 1270 ManagedIndexSetInterface *set = *it; 1271 if( set->equals( iset ) ) 1272 { 1273 set->addReference(); 1274 1275 indexSet = static_cast< ManagedIndexSetType * >( set ); 1276 break; 1277 } 1278 } 1279 1280 if( !indexSet ) 1281 { 1282 indexSet = new ManagedIndexSetType ( iset, indexSets_ , insertIndices_ , removeIndices_ ); 1283 indexList_.push_back( static_cast< ManagedIndexSetInterface * >( indexSet ) ); 1284 } 1285 } 1286 1287 template <class GridType> 1288 template <class IndexSetType> removeIndexSet(const IndexSetType & iset)1289 inline void DofManager<GridType>::removeIndexSet ( const IndexSetType &iset ) 1290 { 1291 assert( Fem :: ThreadManager:: singleThreadMode() ); 1292 1293 // search index set list in reverse order to find latest index sets faster 1294 auto endit = indexList_.rend(); 1295 for( auto it = indexList_.rbegin(); it != endit; ++it ) 1296 { 1297 ManagedIndexSetInterface *set = *it; 1298 if( set->equals( iset ) ) 1299 { 1300 if( set->removeReference() ) 1301 { 1302 // reverse iterators cannot be erased directly, so erase the base 1303 // (forward) iterator 1304 // Note: see, e.g., Stroustrup, section 16.3.2 about the decrement 1305 auto fit = it.base(); 1306 indexList_.erase( --fit ); 1307 // delete proxy 1308 delete set; 1309 } 1310 return; 1311 } 1312 } 1313 1314 // we should never get here 1315 DUNE_THROW(InvalidStateException,"Could not remove index from DofManager set!"); 1316 } 1317 1318 template <class GridType> 1319 template <class ManagedDofStorageImp> addDofStorage(ManagedDofStorageImp & dofStorage)1320 void DofManager<GridType>::addDofStorage(ManagedDofStorageImp& dofStorage) 1321 { 1322 // make sure we got an ManagedDofStorage 1323 ManagedDofStorageInterface* obj = &dofStorage; 1324 1325 // push_front, makes search faster 1326 memList_.push_front( obj ); 1327 1328 // add the special object to the memResize list object 1329 resizeMemObjs_ += dofStorage.resizeMemoryObject(); 1330 1331 // the same for the reserve call 1332 reserveMemObjs_ += dofStorage.reserveMemoryObject(); 1333 } 1334 1335 1336 template <class GridType> 1337 template <class ManagedDofStorageImp> removeDofStorage(ManagedDofStorageImp & dofStorage)1338 void DofManager<GridType>::removeDofStorage(ManagedDofStorageImp& dofStorage) 1339 { 1340 // make sure we got an ManagedDofStorage 1341 auto obj = &dofStorage; 1342 1343 // search list starting from tail 1344 auto endit = memList_.end(); 1345 for( auto it = memList_.begin();it != endit ; ++it) 1346 { 1347 if(*it == obj) 1348 { 1349 // alloc new mem and copy old mem 1350 memList_.erase( it ); 1351 1352 // remove from list 1353 resizeMemObjs_.remove( dofStorage.resizeMemoryObject() ); 1354 reserveMemObjs_.remove( dofStorage.reserveMemoryObject() ); 1355 1356 return ; 1357 } 1358 } 1359 } 1360 1361 //@} 1362 1363 1364 /** \class DofManagerFactory 1365 * \ingroup DofManager 1366 * \brief Singleton provider for the DofManager 1367 * 1368 * DofManagerFactory guarantees that at most one instance of DofManager 1369 * is generated for each grid. 1370 */ 1371 template< class DofManagerImp > 1372 class DofManagerFactory 1373 { 1374 typedef DofManagerFactory< DofManagerImp > ThisType; 1375 1376 public: 1377 typedef DofManagerImp DofManagerType; 1378 typedef typename DofManagerType :: GridType GridType; 1379 1380 private: 1381 typedef const GridType *KeyType; 1382 1383 typedef SingletonList< KeyType, DofManagerType > DMProviderType; 1384 1385 // declare friendship becase of methods instance 1386 friend class DofManager< GridType >; 1387 1388 protected: 1389 /** \brief obtain a reference to the DofManager for a given grid 1390 * 1391 * \param[in] grid grid for which the DofManager is desired 1392 * 1393 * \returns a reference to the singleton instance of the DofManager 1394 */ instance(const GridType & grid)1395 inline static DofManagerType &instance ( const GridType &grid ) 1396 { 1397 DofManagerType *dm = getDmFromList( grid ); 1398 if( !dm ) 1399 return DMProviderType :: getObject( &grid ); 1400 return *dm; 1401 } 1402 1403 //! writes DofManager of corresponding grid, when DofManager exists 1404 inline static bool writeDofManagerNew(const GridType & grid,const std::string & filename,int timestep)1405 writeDofManagerNew ( const GridType &grid, 1406 const std :: string &filename, 1407 int timestep ) 1408 { 1409 DofManagerType *dm = getDmFromList( grid ); 1410 /* 1411 if( dm ) 1412 return dm->writeIndexSets( filename, timestep ); 1413 */ 1414 return false; 1415 } 1416 1417 //! reads DofManager of corresponding grid, when DofManager exists 1418 inline static bool readDofManagerNew(const GridType & grid,const std::string & filename,int timestep)1419 readDofManagerNew ( const GridType &grid, 1420 const std :: string &filename, 1421 int timestep ) 1422 { 1423 DofManagerType *dm = getDmFromList( grid ); 1424 /* 1425 if( dm ) 1426 return dm->readIndexSets( filename, timestep ); 1427 */ 1428 return false; 1429 } 1430 1431 public: 1432 //! delete the dof manager that belong to the given grid deleteDofManager(DofManagerType & dm)1433 inline static void deleteDofManager ( DofManagerType &dm ) 1434 { 1435 DMProviderType :: removeObject( &dm ); 1436 } 1437 1438 private: 1439 // return pointer to dof manager for given grid getDmFromList(const GridType & grid)1440 inline static DofManagerType *getDmFromList( const GridType &grid ) 1441 { 1442 return (DMProviderType :: getObjFromList( &grid )).first; 1443 } 1444 }; 1445 1446 } // namespace Fem 1447 1448 } // namespace Dune 1449 1450 #endif // #ifndef DUNE_FEM_DOFMANAGER_HH 1451