1 #ifndef DUNE_FEM_CACHED_COMMUNICATION_MANAGER_HH 2 #define DUNE_FEM_CACHED_COMMUNICATION_MANAGER_HH 11 #include <dune/common/math.hh> 12 #include <dune/common/timer.hh> 15 #include <dune/grid/common/grid.hh> 16 #include <dune/grid/common/datahandleif.hh> 17 #include <dune/grid/utility/entitycommhelper.hh> 21 #include <dune/grid/alugrid/3d/alu3dinclude.hh> 22 #elif HAVE_DUNE_ALUGRID 23 #include <dune/alugrid/3d/alu3dinclude.hh> 43 template<
class DiscreteFunctionSpace >
56 #if ALU3DGRID_PARALLEL 63 template<
class Space >
68 typedef Space SpaceType;
71 typedef typename SpaceType :: GridPartType GridPartType;
78 typedef IndexMapType *IndexMapVectorType;
81 typedef std :: set< int > LinkStorageType;
84 typedef ALU3DSPACE ObjectStream ObjectStreamType;
87 typedef ALU3DSPACE MpAccessLocal MPAccessInterfaceType;
89 typedef ALU3DSPACE MpAccessMPI MPAccessImplType;
92 typedef std :: vector< ObjectStreamType > ObjectStreamVectorType;
95 const SpaceType &space_;
96 const GridPartType &gridPart_;
98 const InterfaceType interface_;
99 const CommunicationDirection dir_;
104 LinkStorageType linkStorage_;
106 IndexMapType *recvIndexMap_;
107 IndexMapType *sendIndexMap_;
110 MPAccessInterfaceType *mpAccess_;
113 double exchangeTime_;
120 int nonBlockingObjects_ ;
123 template<
class LinkStorage,
class IndexMapVector, InterfaceType CommInterface >
130 class NonBlockingCommunication
132 typedef DependencyCache < Space > DependencyCacheType ;
134 #if HAVE_DUNE_ALUGRID && ! HAVE_ALUGRID 135 typedef MPAccessInterfaceType :: NonBlockingExchange NonBlockingExchange;
137 template <
class DiscreteFunction>
138 class Pack :
public NonBlockingExchange :: DataHandleIF
141 NonBlockingCommunication& commObj_;
142 const DiscreteFunction& discreteFunction_;
145 Pack( NonBlockingCommunication& commObj,
146 const DiscreteFunction& df )
147 : commObj_( commObj ),
148 discreteFunction_( df )
151 void pack(
const int link, ObjectStreamType& buffer )
153 commObj_.pack( link, buffer, discreteFunction_ );
156 void unpack(
const int link, ObjectStreamType& buffer )
158 DUNE_THROW(InvalidStateException,
"Pack::unpack should not be called!");
162 template <
class DiscreteFunction,
165 :
public NonBlockingExchange :: DataHandleIF
168 NonBlockingCommunication& commObj_;
169 DiscreteFunction& discreteFunction_;
172 const Operation* operation_;
175 Unpack( NonBlockingCommunication& commObj,
176 DiscreteFunction& df )
177 : commObj_( commObj ),
178 discreteFunction_( df ),
182 void pack(
const int link, ObjectStreamType& buffer )
184 DUNE_THROW(InvalidStateException,
"Unpack::pack should not be called!");
187 void unpack(
const int link, ObjectStreamType& buffer )
189 commObj_.unpack( link, buffer, discreteFunction_, operation_ );
192 #else // ALUGRID_HAS_NONBLOCKING_COMM is false 193 typedef int NonBlockingExchange;
197 static int getMessageTag()
199 enum { initial = 665 };
200 static int tagCounter = initial ;
202 int messageTag = tagCounter ;
207 messageTag = initial ;
208 tagCounter = initial ;
214 NonBlockingCommunication( DependencyCacheType& dependencyCache,
216 : dependencyCache_( dependencyCache ),
217 nonBlockingExchange_( 0 ),
219 exchangeTime_( 0.0 ),
223 dependencyCache_.rebuild();
226 dependencyCache_.attachComm();
230 NonBlockingCommunication(
const NonBlockingCommunication& other )
231 : dependencyCache_( other.dependencyCache_ ),
232 nonBlockingExchange_( 0 ),
234 exchangeTime_( 0.0 ),
235 mySize_( other.mySize_ )
238 dependencyCache_.rebuild();
241 dependencyCache_.attachComm();
244 ~NonBlockingCommunication()
247 assert( nonBlockingExchange_ == 0 );
249 dependencyCache_.detachComm() ;
252 template <
class DiscreteFunctionSpace >
258 template <
class DiscreteFunction >
259 void send(
const DiscreteFunction& discreteFunction )
262 assert( nonBlockingExchange_ == 0 );
265 if( mySize_ <= 1 )
return;
268 Dune::Timer sendTimer ;
271 const int nLinks = dependencyCache_.nlinks();
274 buffer_.resize( nLinks );
276 #if HAVE_DUNE_ALUGRID && ! HAVE_ALUGRID 278 nonBlockingExchange_ = dependencyCache_.mpAccess().nonBlockingExchange( getMessageTag() );
281 Pack< DiscreteFunction > packData( *
this, discreteFunction );
284 nonBlockingExchange_->send( buffer_, packData );
287 for(
int link = 0; link < nLinks; ++link )
289 pack( link, buffer_[ link ], discreteFunction );
294 exchangeTime_ = sendTimer.elapsed();
298 template <
class DiscreteFunctionSpace,
class Operation >
300 const Operation* operation )
303 Dune::Timer exchTimer ;
306 discreteFunction.communicate();
308 return exchTimer.elapsed();
312 template <
class DiscreteFunction,
class Operation >
313 double receive( DiscreteFunction& discreteFunction,
const Operation* operation )
316 if( mySize_ <= 1 )
return 0.0;
319 Dune::Timer recvTimer ;
321 #if HAVE_DUNE_ALUGRID && ! HAVE_ALUGRID 323 Unpack< DiscreteFunction, Operation > unpackData( *
this, discreteFunction );
326 nonBlockingExchange_->receive( unpackData );
329 buffer_ = dependencyCache_.mpAccess().exchange( buffer_ );
332 const int nLinks = buffer_.size();
335 for(
int link = 0; link < nLinks; ++link )
337 unpack( link, buffer_[ link ], discreteFunction, operation );
342 exchangeTime_ += recvTimer.elapsed();
344 #if HAVE_DUNE_ALUGRID && ! HAVE_ALUGRID 345 delete nonBlockingExchange_;
346 nonBlockingExchange_ = 0;
348 return exchangeTime_;
352 template <
class DiscreteFunction >
353 double receive( DiscreteFunction& discreteFunction )
356 typedef typename DiscreteFunction :: DiscreteFunctionSpaceType
357 :: template CommDataHandle< DiscreteFunction > :: OperationType DefaultOperationType;
358 return receive( discreteFunction, (DefaultOperationType *) 0 );
362 template <
class DiscreteFunction>
363 void pack(
const int link, ObjectStreamType& buffer,
const DiscreteFunction& discreteFunction )
368 dependencyCache_.writeBuffer( link, buffer, discreteFunction );
371 template <
class DiscreteFunction,
class Operation>
372 void unpack(
const int link, ObjectStreamType& buffer,
373 DiscreteFunction& discreteFunction,
const Operation* operation )
376 dependencyCache_.readBuffer( link, buffer, discreteFunction, operation );
380 DependencyCacheType& dependencyCache_;
381 NonBlockingExchange* nonBlockingExchange_ ;
382 ObjectStreamVectorType buffer_;
383 double exchangeTime_ ;
388 typedef NonBlockingCommunication NonBlockingCommunicationType;
391 NonBlockingCommunicationType nonBlockingCommunication ()
394 return NonBlockingCommunicationType( *
this, mySize_ );
402 DependencyCache (
const SpaceType &space,
403 const InterfaceType interface,
404 const CommunicationDirection dir)
406 gridPart_( space_.gridPart() ),
407 interface_( interface ),
409 myRank_( gridPart_.comm().rank() ),
410 mySize_( gridPart_.comm().size() ),
412 recvIndexMap_( new IndexMapType[ mySize_ ] ),
413 sendIndexMap_( new IndexMapType[ mySize_ ] ),
414 mpAccess_( new MPAccessImplType( MPIHelper::getCommunicator() ) ),
415 exchangeTime_( 0.0 ),
418 nonBlockingObjects_( 0 )
423 DependencyCache (
const DependencyCache & );
427 inline ~DependencyCache ()
432 delete [] sendIndexMap_;
435 delete [] recvIndexMap_;
441 InterfaceType communicationInterface()
const {
446 CommunicationDirection communicationDirection()
const 452 double buildTime()
const {
return buildTime_; }
455 double exchangeTime()
const {
return exchangeTime_; }
458 inline void buildMaps ();
463 ++ nonBlockingObjects_;
469 --nonBlockingObjects_;
470 assert( nonBlockingObjects_ >= 0 );
473 bool noOpenCommunications()
const 479 inline void checkConsistency ();
481 template<
class LS,
class IMV, InterfaceType CI >
482 inline void buildMaps ( LinkBuilder< LS, IMV, CI > &handle );
486 inline int dest(
const int link )
const 488 return mpAccess().dest()[ link ];
492 inline int nlinks ()
const 494 return mpAccess().nlinks();
498 inline void rebuild ()
501 if( mySize_ <= 1 )
return;
504 assert( noOpenCommunications () );
508 int willRebuild = (sequence_ != space_.sequence()) ? 1 : 0;
509 const int myRebuild = willRebuild;
512 gridPart_.comm().broadcast( &willRebuild, 1 , 0);
514 assert( willRebuild == myRebuild );
518 if( sequence_ != space_.sequence() )
521 Dune::Timer buildTime;
524 sequence_ = space_.sequence();
527 buildTime_ = buildTime.elapsed();
532 template<
class DiscreteFunction,
class Operation >
533 inline void exchange ( DiscreteFunction &discreteFunction,
534 const Operation *operation );
537 template<
class DiscreteFunction >
538 inline void writeBuffer ( ObjectStreamVectorType &osv,
539 const DiscreteFunction &discreteFunction )
const;
542 template<
class DiscreteFunctionType,
class Operation >
543 inline void readBuffer ( ObjectStreamVectorType &osv,
544 DiscreteFunctionType &discreteFunction,
545 const Operation *operation )
const;
548 inline MPAccessInterfaceType &mpAccess ()
555 inline const MPAccessInterfaceType &mpAccess ()
const 563 template<
class DiscreteFunctionSpace >
564 inline void writeBuffer (
const int link,
565 ObjectStreamType &str,
568 DUNE_THROW(NotImplemented,
"writeBuffer not implemented for PetscDiscteteFunction" );
573 template<
class DiscreteFunction >
574 inline void writeBuffer (
const int link,
575 ObjectStreamType &str,
576 const DiscreteFunction &discreteFunction )
const 578 assert( sequence_ == space_.sequence() );
579 const IndexMapType &indexMap = sendIndexMap_[ dest( link ) ];
580 const int size = indexMap.size();
582 typedef typename DiscreteFunction :: DofType DofType;
583 typedef typename DiscreteFunction :: ConstDofBlockPtrType ConstDofBlockPtrType;
585 enum { blockSize = DiscreteFunction ::
586 DiscreteFunctionSpaceType :: localBlockSize } ;
589 str.reserve( (size * blockSize *
sizeof( DofType )) );
590 for(
int i = 0; i < size; ++i )
593 ConstDofBlockPtrType blockPtr = discreteFunction.block( indexMap[i] );
596 for(
int k = 0; k < blockSize; ++k )
598 str.writeUnchecked( ((*blockPtr)[ k ]) );
605 template<
class DiscreteFunctionSpace,
class Operation >
606 inline void readBuffer (
const int link,
607 ObjectStreamType &str,
609 const Operation * )
const 611 DUNE_THROW(NotImplemented,
"readBuffer not implemented for PetscDiscteteFunction" );
616 template<
class DiscreteFunction,
class Operation >
617 inline void readBuffer (
const int link,
618 ObjectStreamType &str,
619 DiscreteFunction &discreteFunction,
620 const Operation * )
const 622 assert( sequence_ == space_.sequence() );
623 typedef typename DiscreteFunction :: DofType DofType;
624 typedef typename DiscreteFunction :: DofBlockPtrType DofBlockPtrType;
626 enum { blockSize = DiscreteFunction ::
627 DiscreteFunctionSpaceType :: localBlockSize } ;
630 const IndexMapType &indexMap = recvIndexMap_[ dest( link ) ];
632 const int size = indexMap.size();
634 assert(
size_t(size * blockSize *
sizeof( DofType )) <=
size_t(str.size()) );
637 for(
int i = 0; i < size; ++i )
640 DofBlockPtrType blockPtr = discreteFunction.block( indexMap[i] );
643 for(
int k = 0; k < blockSize; ++k )
645 #if HAVE_DUNE_ALUGRID 646 str.readUnchecked( value );
650 Operation :: apply( value, ((*blockPtr)[ k ]) );
657 template<
class Space >
658 template<
class LinkStorage,
class IndexMapVector, InterfaceType CommInterface >
659 class DependencyCache< Space > :: LinkBuilder
660 :
public CommDataHandleIF
661 < LinkBuilder< LinkStorage, IndexMapVector, CommInterface >,
662 typename SpaceType :: BlockMapperType :: GlobalKeyType >
665 typedef LinkStorage LinkStorageType;
667 typedef IndexMapVector IndexMapVectorType;
669 typedef typename SpaceType :: BlockMapperType BlockMapperType;
670 typedef typename BlockMapperType :: GlobalKeyType GlobalKeyType;
672 typedef GlobalKeyType DataType;
675 const GlobalKeyType myRank_;
676 const GlobalKeyType mySize_;
678 LinkStorageType &linkStorage_;
680 IndexMapVectorType &sendIndexMap_;
681 IndexMapVectorType &recvIndexMap_;
683 const SpaceType &space_;
684 const BlockMapperType &blockMapper_;
687 LinkBuilder ( LinkStorageType &linkStorage,
688 IndexMapVectorType &sendIdxMap,
689 IndexMapVectorType &recvIdxMap,
690 const SpaceType &space )
691 : myRank_( space.gridPart().comm().rank() ),
692 mySize_( space.gridPart().comm().size() ),
693 linkStorage_( linkStorage ),
694 sendIndexMap_( sendIdxMap ),
695 recvIndexMap_( recvIdxMap ),
697 blockMapper_( space.blockMapper() )
702 void sendBackSendMaps()
705 MPAccessImplType mpAccess ( MPIHelper::getCommunicator() );
708 mpAccess.removeLinkage();
710 mpAccess.insertRequestSymetric( linkStorage_ );
712 std::vector<int> dest = mpAccess.dest();
714 const int nlinks = mpAccess.nlinks();
717 ObjectStreamVectorType osv( nlinks );
727 for(
int link=0; link<nlinks; ++link)
729 sendIndexMap_[ dest[link] ].writeToBuffer( osv[link] );
733 osv = mpAccess.exchange( osv );
736 for(
int link=0; link<nlinks; ++link)
738 sendIndexMap_[ dest[link] ].readFromBuffer( osv[link] );
750 bool contains (
int dim,
int codim )
const 752 return space_.blockMapper().contains( codim );
756 bool fixedsize (
int dim,
int codim )
const 762 template<
class MessageBuffer,
class Entity >
763 void gather ( MessageBuffer &buffer,
764 const Entity &entity )
const 767 const PartitionType myPartitionType = entity.partitionType();
768 const bool send = EntityCommHelper< CommInterface > :: send( myPartitionType );
774 buffer.write( myRank_ );
776 const int numDofs = blockMapper_.numEntityDofs( entity );
779 typedef std::vector< GlobalKeyType > IndicesType ;
780 IndicesType indices( numDofs );
786 for(
int i = 0; i < numDofs; ++i )
788 buffer.write( indices[ i ] );
794 template<
class MessageBuffer,
class Entity >
795 void scatter ( MessageBuffer &buffer,
796 const Entity &entity,
797 const size_t dataSize )
805 assert( (rank >= 0) && (rank < mySize_) );
808 const PartitionType myPartitionType = entity.partitionType();
809 const bool receive = EntityCommHelper< CommInterface > :: receive( myPartitionType );
812 linkStorage_.insert( rank );
815 typedef std::vector< GlobalKeyType > IndicesType ;
816 IndicesType indices( dataSize - 1 );
817 for(
size_t i=0; i<dataSize-1; ++i)
819 buffer.read( indices[i] );
835 sendIndexMap_[ rank ].insert( indices );
838 const int numDofs = blockMapper_.numEntityDofs( entity );
839 indices.resize( numDofs );
849 recvIndexMap_[ rank ].insert( indices );
855 template<
class Entity >
856 size_t size (
const Entity &entity )
const 858 const PartitionType myPartitionType = entity.partitionType();
859 const bool send = EntityCommHelper< CommInterface > :: send( myPartitionType );
860 return (send) ? (blockMapper_.numEntityDofs( entity ) + 1) : 0;
866 template<
class Space >
867 inline void DependencyCache< Space > :: buildMaps ()
869 if( interface_ == InteriorBorder_All_Interface )
871 LinkBuilder< LinkStorageType, IndexMapVectorType,
872 InteriorBorder_All_Interface >
873 handle( linkStorage_, sendIndexMap_, recvIndexMap_, space_ );
876 else if( interface_ == InteriorBorder_InteriorBorder_Interface )
878 LinkBuilder< LinkStorageType, IndexMapVectorType,
879 InteriorBorder_InteriorBorder_Interface >
880 handle( linkStorage_, sendIndexMap_, recvIndexMap_, space_ );
883 else if( interface_ == All_All_Interface )
885 LinkBuilder< LinkStorageType, IndexMapVectorType, All_All_Interface >
886 handle( linkStorage_, sendIndexMap_, recvIndexMap_, space_ );
890 DUNE_THROW( NotImplemented,
"DependencyCache for the given interface has" 891 " not been implemented, yet." );
899 template<
class Space >
900 template<
class LS,
class IMV, InterfaceType CI >
901 inline void DependencyCache< Space >
902 :: buildMaps ( LinkBuilder< LS, IMV, CI > &handle )
904 linkStorage_.clear();
905 for(
int i = 0; i < mySize_; ++i )
907 recvIndexMap_[ i ].clear();
908 sendIndexMap_[ i ].clear();
912 gridPart_.communicate( handle, All_All_Interface , ForwardCommunication );
915 mpAccess().removeLinkage();
917 mpAccess().insertRequestSymetric ( linkStorage_ );
920 template<
class Space >
921 inline void DependencyCache< Space >
922 :: checkConsistency ()
927 const int nLinks = nlinks();
929 ObjectStreamVectorType buffer( nLinks );
932 for(
int l=0; l<nLinks; ++l)
935 const int sendSize = sendIndexMap_[ dest( l ) ].size();
936 buffer[l].write( sendSize );
937 for(
int i=0; i<sendSize; ++i)
939 buffer[l].write( i );
944 buffer = mpAccess().exchange( buffer );
947 for(
int l=0; l<nLinks; ++l)
949 const int recvSize = recvIndexMap_[ dest( l ) ].size();
951 buffer[l].read( sendedSize );
954 if( recvSize != sendedSize )
956 DUNE_THROW(InvalidStateException,
"Sizes do not match!" << sendedSize <<
" o|r " << recvSize);
959 for(
int i=0; i<recvSize; ++i)
962 buffer[l].read( idx );
967 DUNE_THROW(InvalidStateException,
"Wrong ordering of send and recv maps!");
973 template<
class Space >
974 template<
class DiscreteFunction,
class Operation >
975 inline void DependencyCache< Space >
976 :: exchange ( DiscreteFunction &discreteFunction,
977 const Operation *operation )
980 if( mySize_ <= 1 )
return;
983 NonBlockingCommunicationType nbc( *
this, mySize_ );
986 nbc.send( discreteFunction );
989 exchangeTime_ = nbc.receive( discreteFunction, operation );
993 template<
class Space >
994 template<
class DiscreteFunction >
995 inline void DependencyCache< Space >
996 :: writeBuffer ( ObjectStreamVectorType &osv,
997 const DiscreteFunction &discreteFunction )
const 999 const int numLinks = nlinks();
1001 for(
int link = 0; link < numLinks; ++link )
1002 writeBuffer( link, osv[ link ], discreteFunction );
1006 template<
class Space >
1007 template<
class DiscreteFunction,
class Operation >
1008 inline void DependencyCache< Space >
1009 :: readBuffer ( ObjectStreamVectorType &osv,
1010 DiscreteFunction &discreteFunction,
1011 const Operation *operation )
const 1013 const int numLinks = nlinks();
1015 for(
int link = 0; link < numLinks; ++link )
1016 readBuffer( link, osv[ link ], discreteFunction, operation );
1022 template <
class SpaceImp>
1023 class CommManagerSingletonKey
1025 const SpaceImp & space_;
1026 const InterfaceType interface_;
1027 const CommunicationDirection dir_;
1030 CommManagerSingletonKey(
const SpaceImp & space,
1031 const InterfaceType interface,
1032 const CommunicationDirection dir)
1033 : space_(space), interface_(interface), dir_(dir) {}
1036 CommManagerSingletonKey(
const CommManagerSingletonKey & org)
1037 : space_(org.space_), interface_(org.interface_), dir_(org.dir_) {}
1039 bool operator == (
const CommManagerSingletonKey & otherKey)
const 1042 return (&(space_.blockMapper()) == & (otherKey.space_.blockMapper()) );
1046 const SpaceImp & space()
const {
return space_; }
1048 InterfaceType interface()
const {
return interface_; }
1050 CommunicationDirection direction()
const {
return dir_; }
1055 template <
class KeyImp,
class ObjectImp>
1056 class CommManagerFactory
1060 static ObjectImp * createObject(
const KeyImp & key )
1062 return new ObjectImp(key.space(),
1068 static void deleteObject( ObjectImp * obj )
1075 template <
class SpaceImp>
1081 typedef DependencyCache<SpaceImp> DependencyCacheType;
1083 typedef CommManagerSingletonKey<SpaceImp> KeyType;
1084 typedef CommManagerFactory<KeyType, DependencyCacheType> FactoryType;
1088 typedef SpaceImp SpaceType;
1089 const SpaceType & space_;
1095 typedef ALU3DSPACE MpAccessLocal MPAccessInterfaceType;
1098 DependencyCacheType &cache_;
1102 typedef typename DependencyCacheType :: NonBlockingCommunicationType NonBlockingCommunicationType;
1106 const InterfaceType interface,
1107 const CommunicationDirection dir)
1109 , key_(space_,interface,dir)
1110 , mySize_(space_.gridPart().comm().size())
1111 , cache_(CommunicationProviderType::getObject(key_))
1118 space.communicationInterface(),
1119 space.communicationDirection())
1120 , mySize_(space_.gridPart().comm().size())
1121 , cache_(CommunicationProviderType::getObject(key_))
1127 CommunicationProviderType::removeObject(cache_);
1131 InterfaceType communicationInterface()
const {
1132 return cache_.communicationInterface();
1136 CommunicationDirection communicationDirection()
const 1138 return cache_.communicationDirection();
1142 double buildTime()
const {
return cache_.buildTime(); }
1145 double exchangeTime()
const {
return cache_.exchangeTime(); }
1147 MPAccessInterfaceType& mpAccess() {
return cache_.mpAccess(); }
1150 NonBlockingCommunicationType nonBlockingCommunication()
const 1152 return cache_.nonBlockingCommunication();
1157 template <
class DiscreteFunctionType>
1158 void exchange(DiscreteFunctionType & df)
const 1161 typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType
1162 :: template CommDataHandle< DiscreteFunctionType > :: OperationType DefaultOperationType;
1164 cache_.exchange( df, (DefaultOperationType *) 0 );
1169 template <
class DiscreteFunctionType,
class OperationImp>
1170 void exchange(DiscreteFunctionType & df,
const OperationImp* )
const 1172 cache_.exchange( df, (OperationImp*) 0 );
1176 template <
class ObjectStreamVectorType,
class DiscreteFunctionType>
1177 void writeBuffer(ObjectStreamVectorType& osv,
1178 const DiscreteFunctionType & df)
const 1180 cache_.writeBuffer(osv, df );
1184 template <
class ObjectStreamVectorType,
class DiscreteFunctionType>
1185 void readBuffer(ObjectStreamVectorType& osv,
1186 DiscreteFunctionType & df)
const 1188 typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType
1189 :: template CommDataHandle<DiscreteFunctionType> :: OperationType OperationType;
1190 readBuffer( osv, df, (OperationType *) 0 );
1194 template <
class ObjectStreamVectorType,
class DiscreteFunctionType,
1195 class OperationType>
1196 void readBuffer(ObjectStreamVectorType& osv,
1197 DiscreteFunctionType & df,
1198 const OperationType* op)
const 1200 cache_.readBuffer(osv, df , op);
1204 void rebuildCache ()
1214 template <
class MPAccessType,
class ObjectStreamVectorType>
1215 class DiscreteFunctionCommunicatorInterface
1218 DiscreteFunctionCommunicatorInterface () {}
1220 virtual ~DiscreteFunctionCommunicatorInterface () {}
1222 virtual MPAccessType& mpAccess() = 0;
1223 virtual void writeBuffer(ObjectStreamVectorType&)
const = 0;
1224 virtual void readBuffer(ObjectStreamVectorType&) = 0;
1225 virtual void rebuildCache() = 0;
1233 template <
class DiscreteFunctionImp,
1235 class ObjectStreamVectorType,
1237 class DiscreteFunctionCommunicator
1238 :
public DiscreteFunctionCommunicatorInterface<MPAccessType,ObjectStreamVectorType>
1240 typedef DiscreteFunctionImp DiscreteFunctionType;
1241 typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
1246 DiscreteFunctionType& df_;
1248 CommunicationManagerType comm_;
1251 DiscreteFunctionCommunicator(DiscreteFunctionType& df)
1252 : df_(df), comm_(df_.space())
1256 virtual MPAccessType& mpAccess() {
return comm_.mpAccess(); }
1259 virtual void writeBuffer(ObjectStreamVectorType& osv)
const 1261 comm_.writeBuffer(osv,df_);
1265 virtual void readBuffer(ObjectStreamVectorType& osv)
1267 comm_.readBuffer(osv,df_, (OperationType *) 0);
1271 virtual void rebuildCache ()
1273 comm_.rebuildCache ();
1280 typedef ALU3DSPACE ObjectStream ObjectStreamType;
1283 typedef std::vector< ObjectStreamType > ObjectStreamVectorType;
1286 typedef ALU3DSPACE MpAccessLocal MPAccessInterfaceType;
1289 typedef DiscreteFunctionCommunicatorInterface<MPAccessInterfaceType,ObjectStreamVectorType>
1290 CommObjInterfaceType;
1293 typedef std::list < CommObjInterfaceType * > CommObjListType;
1294 CommObjListType objList_;
1303 template <
class CombinedObjectType>
1308 cObj.addToList(*
this);
1315 while( !objList_.empty() )
1317 CommObjInterfaceType * obj = objList_.back();
1318 objList_.pop_back();
1324 template <
class DiscreteFunctionImp>
1325 void addToList(DiscreteFunctionImp &df)
1328 typedef DiscreteFunctionCommunicator<DiscreteFunctionImp,
1329 MPAccessInterfaceType,
1330 ObjectStreamVectorType> CommObj;
1331 CommObj * obj =
new CommObj(df);
1332 objList_.push_back(obj);
1338 MPAccessInterfaceType& mpAccess = objList_.front()->mpAccess();
1341 mySize_ = mpAccess.psize();
1345 template<
class DiscreteFunction >
1346 void removeFromList ( DiscreteFunction &df )
1348 const auto handles = [ &df ] (
const CommObjInterfaceType *commObj ) {
return commObj->handles( df ); };
1349 CommObjListType::reverse_iterator pos = std::find_if( objList_.rbegin(), objList_.rend(), handles );
1350 if( pos != objList_.rend() )
1351 objList_.erase( pos.base() );
1353 DUNE_THROW( RangeError,
"Trying to remove discrete function that was never added" );
1361 if( mySize_ <= 1 ) return ;
1364 if(objList_.size() > 0)
1366 typedef CommObjListType :: iterator iterator;
1369 iterator end = objList_.end();
1370 for(iterator it = objList_.begin(); it != end; ++it)
1372 (*it)->rebuildCache();
1377 MPAccessInterfaceType& mpAccess = objList_.front()->mpAccess();
1380 ObjectStreamVectorType osv( mpAccess.nlinks() );
1383 iterator end = objList_.end();
1384 for(iterator it = objList_.begin(); it != end; ++it)
1386 (*it)->writeBuffer(osv);
1390 osv = mpAccess.exchange (osv);
1393 for(iterator it = objList_.begin(); it != end; ++it)
1395 (*it)->readBuffer(osv);
1400 #endif // #if ALU3DGRID_PARALLEL 1406 #endif // #ifndef DUNE_FEM_CACHED_COMMUNICATION_MANAGER_HH
Proxy class to DependencyCache which is singleton per space.
Definition: communicationmanager.hh:294
Singleton list for key/object pairs.
Definition: singletonlist.hh:49
Definition: discretefunction.hh:50
Definition: misc/functor.hh:30
use Default CommunicationManager as Communication Manager
Definition: communicationmanager.hh:271
bool operator==(const Double &a, const Double &b)
Definition: double.hh:589
Definition: coordinate.hh:4
just copy data
Definition: commoperations.hh:263
Definition: commindexmap.hh:17
Definition: cachedcommmanager.hh:44