dune-fem  2.6-git
communicationmanager.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_COMMUNICATION_MANAGER_HH
2 #define DUNE_FEM_COMMUNICATION_MANAGER_HH
3 
4 #include <iostream>
5 #include <map>
6 #include <memory>
7 #include <vector>
8 
9 #include <dune/common/timer.hh>
10 #include <dune/grid/common/datahandleif.hh>
11 #include <dune/grid/common/grid.hh>
12 
16 
17 // include ALUGrid to check whether the
18 // parallel version is avaiable
19 #if HAVE_DUNE_ALUGRID
20 #include <dune/alugrid/3d/alugrid.hh>
21 #endif
22 
23 // default is: enabled
24 #ifndef WANT_CACHED_COMM_MANAGER
25 #define WANT_CACHED_COMM_MANAGER 1
26 #endif
27 
28 #if ALU3DGRID_PARALLEL && WANT_CACHED_COMM_MANAGER
29 #define USE_CACHED_COMM_MANAGER
30 #else
31 #ifndef NDEBUG
32 #if HAVE_MPI == 0
33  #ifdef DUNE_DEVEL_MODE
34  #warning "HAVE_MPI == 0, therefore default CommunicationManager is used!"
35  #endif
36 #elif !ALU3DGRID_PARALLEL
37  #warning "No Parallel ALUGrid found, using default CommunicationManager!"
38 #elif ! WANT_CACHED_COMM_MANAGER
39  #warning "CachedCommunication Manager disabled by WANT_CACHED_COMM_MANAGER=0!"
40 #endif
41 #endif
42 #endif
43 
44 #undef WANT_CACHED_COMM_MANAGER
45 
46 #ifdef USE_CACHED_COMM_MANAGER
47 #include "cachedcommmanager.hh"
48 #endif
49 
50 namespace Dune
51 {
52 
53  namespace Fem
54  {
55 
56  // External Forward Declarations
57  // -----------------------------
58 
59  template< class DiscreteFunctionSpace >
60  class PetscDiscreteFunction;
61 
62  class IsDiscreteFunction;
63 
64 
65 
75  template< class Space >
77  {
78  public:
79  typedef Space SpaceType;
80 
81  protected:
83 
85  // begin NonBlockingCommunication
88  {
89  const SpaceType& space_;
90  const InterfaceType interface_;
91  const CommunicationDirection dir_;
92 
93  public:
95  InterfaceType interface,
96  CommunicationDirection dir )
97  : space_( space ),
98  interface_( interface ),
99  dir_ ( dir )
100  {}
101 
103  template < class DiscreteFunction >
104  void send( const DiscreteFunction& discreteFunction )
105  {
106  // nothing to do here, since DUNE does not support
107  // non-blocking communcation yet
108  }
109 
111  template < class DiscreteFunctionSpace, class Operation >
113  const Operation& operation )
114  {
115  // get stopwatch
116  Dune::Timer exchangeT;
117 
118  // PetscDiscreteFunction has it's own communication
119  discreteFunction.communicate();
120 
121  return exchangeT.elapsed();
122  }
123 
125  template < class DiscreteFunction, class Operation >
126  double receive( DiscreteFunction& discreteFunction, const Operation& operation )
127  {
128  // get type of data handle from the discrete function space
129  typedef typename DiscreteFunction
130  :: template CommDataHandle< Operation > :: Type
131  DataHandleType;
132 
133  // on serial runs: do nothing
134  if( space_.gridPart().comm().size() <= 1 )
135  return 0.0;
136 
137  // get stopwatch
138  Dune::Timer exchangeT;
139 
140  // communicate data
141  DataHandleType dataHandle = discreteFunction.dataHandle( operation );
142  space_.gridPart().communicate( dataHandle, interface_ , dir_ );
143 
144  // store time
145  return exchangeT.elapsed();
146  }
147 
149  template < class DiscreteFunction >
150  double receive( DiscreteFunction& discreteFunction )
151  {
152  // get type of default operation
153  typedef typename DiscreteFunction :: DiscreteFunctionSpaceType
154  :: template CommDataHandle< DiscreteFunction > :: OperationType DefaultOperationType;
155  DefaultOperationType operation;
156  return receive( discreteFunction, operation );
157  }
158 
159  };
160 
162 
163  const InterfaceType interface_;
164  const CommunicationDirection dir_;
165 
166  mutable double exchangeTime_;
167 
168  public:
169  typedef NonBlockingCommunication NonBlockingCommunicationType;
170 
173  ( const SpaceType &space,
174  const InterfaceType interface,
175  const CommunicationDirection dir)
176  : space_( space ),
177  interface_( interface ),
178  dir_ ( dir ),
179  exchangeTime_(0.0)
180  {}
181 
183 
185  InterfaceType communicationInterface() const {
186  return interface_;
187  }
188 
190  CommunicationDirection communicationDirection() const
191  {
192  return dir_;
193  }
194 
199  double buildTime() const { return 0.0; }
200 
205  double exchangeTime() const { return exchangeTime_; }
206 
212  {
214  }
215 
220  template< class DiscreteFunction >
221  inline void exchange ( DiscreteFunction &discreteFunction ) const
222  {
223  // get type of default operation
224  typedef typename DiscreteFunction :: DiscreteFunctionSpaceType ::
225  template CommDataHandle< DiscreteFunction > :: OperationType DefaultOperationType;
226 
227  DefaultOperationType operation;
228  exchange( discreteFunction, operation );
229  }
230 
239  template< class DiscreteFunction, class Operation >
240  inline void exchange ( DiscreteFunction &discreteFunction,
241  const Operation &operation ) const
242  {
243  // on serial runs: do nothing
244  if( space_.gridPart().comm().size() <= 1 )
245  return;
246 
248 
249  // send data (probably done in receive)
250  nbc.send( discreteFunction );
251 
252  exchangeTime_ = nbc.receive( discreteFunction, operation );
253  }
254  };
255 
256 
257 
258 #ifndef USE_CACHED_COMM_MANAGER
259  // if no ALUGrid found, supply default implementation
261  template <class SpaceImp>
263  : public DefaultCommunicationManager<SpaceImp>
264  {
267  public:
269  CommunicationManager(const SpaceImp & space,
270  const InterfaceType interface,
271  const CommunicationDirection dir)
272  : BaseType(space,interface,dir)
273  {}
275  CommunicationManager(const SpaceImp & space)
276  : BaseType(space,
277  space.communicationInterface(),
278  space.communicationDirection() )
279  {}
280  };
281 
282 
283 
286  {
288  class DiscreteFunctionCommunicatorInterface
289  {
290  protected:
292  public:
294  virtual void exchange () const = 0;
295  virtual bool handles ( IsDiscreteFunction &df ) const = 0;
296  };
297 
299  template <class DiscreteFunctionImp, class Operation>
300  class DiscreteFunctionCommunicator
301  : public DiscreteFunctionCommunicatorInterface
302  {
303  typedef DiscreteFunctionImp DiscreteFunctionType;
304  typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
305 
306  typedef CommunicationManager<DiscreteFunctionSpaceType> CommunicationManagerType;
307 
308  DiscreteFunctionType& df_;
309  CommunicationManagerType comm_;
310  const Operation& operation_;
311 
312  public:
314  DiscreteFunctionCommunicator(DiscreteFunctionType& df, const Operation& op)
315  : df_(df), comm_(df_.space()), operation_( op )
316  {
317  }
318 
319  // exchange discrete function
320  void exchange () const
321  {
322  comm_.exchange( df_, operation_ );
323  }
324 
325  bool handles ( IsDiscreteFunction &df ) const { return (&df_ == &df); }
326  };
327 
328  typedef DiscreteFunctionCommunicatorInterface CommObjIFType;
329  typedef std::list < std::unique_ptr< DiscreteFunctionCommunicatorInterface > > CommObjListType;
330  CommObjListType objList_;
331 
333  public:
335 
337  template <class CombinedObjectType>
338  CommunicationManagerList(CombinedObjectType& cObj)
339  {
340  cObj.addToList(*this);
341  }
342 
344  template <class DiscreteFunctionImp, class Operation>
345  void addToList(DiscreteFunctionImp &df, const Operation& operation )
346  {
347  typedef DiscreteFunctionCommunicator<DiscreteFunctionImp, Operation> CommObjType;
348  CommObjType* obj = new CommObjType( df, operation );
349  objList_.push_back( std::unique_ptr< DiscreteFunctionCommunicatorInterface> (obj) );
350  }
351 
353  template <class DiscreteFunctionImp>
354  void addToList(DiscreteFunctionImp &df)
355  {
357  addToList( df, operation );
358  }
359 
360  template< class DiscreteFunction >
361  void removeFromList ( DiscreteFunction &df )
362  {
363  const auto handles = [ &df ] ( const std::unique_ptr< DiscreteFunctionCommunicatorInterface > &commObj ) { return commObj->handles( df ); };
364  CommObjListType::reverse_iterator pos = std::find_if( objList_.rbegin(), objList_.rend(), handles );
365  if( pos != objList_.rend() )
366  objList_.erase( --pos.base() );
367  else
368  DUNE_THROW( RangeError, "Trying to remove discrete function that was never added" );
369  }
370 
373  void exchange() const
374  {
375  typedef CommObjListType :: const_iterator iterator;
376  {
377  iterator end = objList_.end();
378  for(iterator it = objList_.begin(); it != end; ++it)
379  {
380  (*it)->exchange();
381  }
382  }
383  }
384  };
385 
386  // end toggle AULGrid yes/no
387 #endif
389 
390  } // namespace Fem
391 
392 } // namespace Dune
393 
394 #endif // #ifndef DUNE_FEM_COMMUNICATION_MANAGER_HH
const SpaceType & space_
Definition: communicationmanager.hh:161
double buildTime() const
return time needed for last build
Definition: communicationmanager.hh:199
DefaultCommunicationManager(const DefaultCommunicationManager &)=delete
InterfaceType communicationInterface() const
return communication interface
Definition: communicationmanager.hh:185
DefaultCommunicationManager< Space > ThisType
Definition: communicationmanager.hh:82
double receive(DiscreteFunction &discreteFunction, const Operation &operation)
receive data for discrete function and given operation
Definition: communicationmanager.hh:126
void exchange() const
Definition: communicationmanager.hh:320
Space SpaceType
Definition: communicationmanager.hh:79
double exchangeTime_
Definition: communicationmanager.hh:166
DefaultCommunicationManager(const SpaceType &space, const InterfaceType interface, const CommunicationDirection dir)
constructor taking space and communication interface/direction
Definition: communicationmanager.hh:173
CommunicationManager(const SpaceImp &space)
constructor taking space
Definition: communicationmanager.hh:275
NonBlockingCommunication(const SpaceType &space, InterfaceType interface, CommunicationDirection dir)
Definition: communicationmanager.hh:94
const InterfaceType interface_
Definition: communicationmanager.hh:163
void exchange() const
Definition: communicationmanager.hh:373
void exchange(DiscreteFunction &discreteFunction) const
exchange data for a discrete function using the copy operation
Definition: communicationmanager.hh:221
CommunicationDirection communicationDirection() const
return communication direction
Definition: communicationmanager.hh:190
NonBlockingCommunication NonBlockingCommunicationType
Definition: communicationmanager.hh:169
CommunicationManagerList(CombinedObjectType &cObj)
constructor
Definition: communicationmanager.hh:338
NonBlockingCommunicationType nonBlockingCommunication() const
return object for non-blocking communication
Definition: communicationmanager.hh:211
bool handles(IsDiscreteFunction &df) const
Definition: communicationmanager.hh:325
void send(const DiscreteFunction &discreteFunction)
send data for given discrete function
Definition: communicationmanager.hh:104
void exchange(DiscreteFunction &discreteFunction, const Operation &operation) const
exchange data for a discrete function using the given operation
Definition: communicationmanager.hh:240
DiscreteFunctionCommunicator(DiscreteFunctionType &df, const Operation &op)
constructor taking disctete function
Definition: communicationmanager.hh:314
double exchangeTime() const
return time needed for last exchange of data
Definition: communicationmanager.hh:205
double receive(DiscreteFunction &discreteFunction)
receive method with default operation
Definition: communicationmanager.hh:150
const CommunicationDirection dir_
Definition: communicationmanager.hh:164
CommunicationManager(const SpaceImp &space, const InterfaceType interface, const CommunicationDirection dir)
constructor taking space and communication interface/direction
Definition: communicationmanager.hh:269
void addToList(DiscreteFunctionImp &df, const Operation &operation)
add discrete function to communication list
Definition: communicationmanager.hh:345
void removeFromList(DiscreteFunction &df)
Definition: communicationmanager.hh:361
void addToList(DiscreteFunctionImp &df)
add discrete function to communication list
Definition: communicationmanager.hh:354
double receive(PetscDiscreteFunction< DiscreteFunctionSpace > &discreteFunction, const Operation &operation)
receive data for discrete function and given operation
Definition: communicationmanager.hh:112
Definition: bindguard.hh:11
base class for determing whether a class is a discrete function or not
Definition: common/discretefunction.hh:52
Definition: cachedcommmanager.hh:47
just copy data
Definition: commoperations.hh:128
default communication manager using just the grids communicate method
Definition: communicationmanager.hh:77
use Default CommunicationManager as Communication Manager
Definition: communicationmanager.hh:264
Proxy class to DependencyCache which is singleton per space.
Definition: communicationmanager.hh:286