dune-fem  2.8-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 communication yet
108  }
109 
111  template < class DiscreteFunctionSpace, class Operation >
113  const Operation& operation )
114  {
115  // on serial runs: do nothing
116  if( space_.gridPart().comm().size() <= 1 )
117  return 0.0;
118 
119  // get stopwatch
120  Dune::Timer exchangeT;
121 
122  // PetscDiscreteFunction has it's own communication
123  discreteFunction.dofVector().communicateNow( operation );
124 
125  return exchangeT.elapsed();
126  }
127 
129  template < class DiscreteFunction, class Operation >
130  double receive( DiscreteFunction& discreteFunction, const Operation& operation )
131  {
132  // on serial runs: do nothing
133  if( space_.gridPart().comm().size() <= 1 )
134  return 0.0;
135 
136  // get type of data handle from the discrete function space
137  typedef typename DiscreteFunction
138  :: template CommDataHandle< Operation > :: Type
139  DataHandleType;
140 
141  // get stopwatch
142  Dune::Timer exchangeT;
143 
144  // communicate data
145  DataHandleType dataHandle = discreteFunction.dataHandle( operation );
146  space_.gridPart().communicate( dataHandle, interface_ , dir_ );
147 
148  // store time
149  return exchangeT.elapsed();
150  }
151 
153  template < class DiscreteFunction >
154  double receive( DiscreteFunction& discreteFunction )
155  {
156  // get type of default operation
157  typedef typename DiscreteFunction :: DiscreteFunctionSpaceType
158  :: template CommDataHandle< DiscreteFunction > :: OperationType DefaultOperationType;
159  DefaultOperationType operation;
160  return receive( discreteFunction, operation );
161  }
162 
163  };
164 
166 
167  const InterfaceType interface_;
168  const CommunicationDirection dir_;
169 
170  mutable double exchangeTime_;
171 
172  public:
174 
177  ( const SpaceType &space,
178  const InterfaceType interface,
179  const CommunicationDirection dir)
180  : space_( space ),
181  interface_( interface ),
182  dir_ ( dir ),
183  exchangeTime_(0.0)
184  {}
185 
187 
189  InterfaceType communicationInterface() const {
190  return interface_;
191  }
192 
194  CommunicationDirection communicationDirection() const
195  {
196  return dir_;
197  }
198 
203  double buildTime() const { return 0.0; }
204 
209  double exchangeTime() const { return exchangeTime_; }
210 
216  {
218  }
219 
224  template< class DiscreteFunction >
225  inline void exchange ( DiscreteFunction &discreteFunction ) const
226  {
227  // get type of default operation
228  typedef typename DiscreteFunction :: DiscreteFunctionSpaceType ::
229  template CommDataHandle< DiscreteFunction > :: OperationType DefaultOperationType;
230 
231  DefaultOperationType operation;
232  exchange( discreteFunction, operation );
233  }
234 
243  template< class DiscreteFunction, class Operation >
244  inline void exchange ( DiscreteFunction &discreteFunction,
245  const Operation &operation ) const
246  {
247  // on serial runs: do nothing
248  if( space_.gridPart().comm().size() <= 1 )
249  return;
250 
252 
253  // send data (probably done in receive)
254  nbc.send( discreteFunction );
255 
256  exchangeTime_ = nbc.receive( discreteFunction, operation );
257  }
258  };
259 
260 
261 
262 #ifndef USE_CACHED_COMM_MANAGER
263  // if no ALUGrid found, supply default implementation
265  template <class SpaceImp>
267  : public DefaultCommunicationManager<SpaceImp>
268  {
271  public:
273  CommunicationManager(const SpaceImp & space,
274  const InterfaceType interface,
275  const CommunicationDirection dir)
276  : BaseType(space,interface,dir)
277  {}
279  CommunicationManager(const SpaceImp & space)
280  : BaseType(space,
281  space.communicationInterface(),
282  space.communicationDirection() )
283  {}
284  };
285 
286 
287 
290  {
292  class DiscreteFunctionCommunicatorInterface
293  {
294  protected:
296  public:
298  virtual void exchange () const = 0;
299  virtual bool handles ( IsDiscreteFunction &df ) const = 0;
300  };
301 
303  template <class DiscreteFunctionImp, class Operation>
304  class DiscreteFunctionCommunicator
305  : public DiscreteFunctionCommunicatorInterface
306  {
307  typedef DiscreteFunctionImp DiscreteFunctionType;
308  typedef typename DiscreteFunctionType :: DiscreteFunctionSpaceType DiscreteFunctionSpaceType;
309 
310  typedef CommunicationManager<DiscreteFunctionSpaceType> CommunicationManagerType;
311 
312  DiscreteFunctionType& df_;
313  CommunicationManagerType comm_;
314  const Operation& operation_;
315 
316  public:
318  DiscreteFunctionCommunicator(DiscreteFunctionType& df, const Operation& op)
319  : df_(df), comm_(df_.space()), operation_( op )
320  {
321  }
322 
323  // exchange discrete function
324  void exchange () const
325  {
326  comm_.exchange( df_, operation_ );
327  }
328 
329  bool handles ( IsDiscreteFunction &df ) const { return (&df_ == &df); }
330  };
331 
332  typedef DiscreteFunctionCommunicatorInterface CommObjIFType;
333  typedef std::list < std::unique_ptr< DiscreteFunctionCommunicatorInterface > > CommObjListType;
334  CommObjListType objList_;
335 
337  public:
339 
341  template <class CombinedObjectType>
342  CommunicationManagerList(CombinedObjectType& cObj)
343  {
344  cObj.addToList(*this);
345  }
346 
348  template <class DiscreteFunctionImp, class Operation>
349  void addToList(DiscreteFunctionImp &df, const Operation& operation )
350  {
351  typedef DiscreteFunctionCommunicator<DiscreteFunctionImp, Operation> CommObjType;
352  CommObjType* obj = new CommObjType( df, operation );
353  objList_.push_back( std::unique_ptr< DiscreteFunctionCommunicatorInterface> (obj) );
354  }
355 
357  template <class DiscreteFunctionImp>
358  void addToList(DiscreteFunctionImp &df)
359  {
361  addToList( df, operation );
362  }
363 
364  template< class DiscreteFunction >
365  void removeFromList ( DiscreteFunction &df )
366  {
367  const auto handles = [ &df ] ( const std::unique_ptr< DiscreteFunctionCommunicatorInterface > &commObj ) { return commObj->handles( df ); };
368  CommObjListType::reverse_iterator pos = std::find_if( objList_.rbegin(), objList_.rend(), handles );
369  if( pos != objList_.rend() )
370  objList_.erase( --pos.base() );
371  else
372  DUNE_THROW( RangeError, "Trying to remove discrete function that was never added" );
373  }
374 
377  void exchange() const
378  {
379  typedef CommObjListType :: const_iterator iterator;
380  {
381  iterator end = objList_.end();
382  for(iterator it = objList_.begin(); it != end; ++it)
383  {
384  (*it)->exchange();
385  }
386  }
387  }
388  };
389 
390  // end toggle AULGrid yes/no
391 #endif
393 
394  } // namespace Fem
395 
396 } // namespace Dune
397 
398 #endif // #ifndef DUNE_FEM_COMMUNICATION_MANAGER_HH
const SpaceType & space_
Definition: communicationmanager.hh:165
double buildTime() const
return time needed for last build
Definition: communicationmanager.hh:203
DefaultCommunicationManager(const DefaultCommunicationManager &)=delete
InterfaceType communicationInterface() const
return communication interface
Definition: communicationmanager.hh:189
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:130
void exchange() const
Definition: communicationmanager.hh:324
Space SpaceType
Definition: communicationmanager.hh:79
double exchangeTime_
Definition: communicationmanager.hh:170
DefaultCommunicationManager(const SpaceType &space, const InterfaceType interface, const CommunicationDirection dir)
constructor taking space and communication interface/direction
Definition: communicationmanager.hh:177
CommunicationManager(const SpaceImp &space)
constructor taking space
Definition: communicationmanager.hh:279
NonBlockingCommunication(const SpaceType &space, InterfaceType interface, CommunicationDirection dir)
Definition: communicationmanager.hh:94
const InterfaceType interface_
Definition: communicationmanager.hh:167
void exchange() const
Definition: communicationmanager.hh:377
void exchange(DiscreteFunction &discreteFunction) const
exchange data for a discrete function using the copy operation
Definition: communicationmanager.hh:225
CommunicationDirection communicationDirection() const
return communication direction
Definition: communicationmanager.hh:194
NonBlockingCommunication NonBlockingCommunicationType
Definition: communicationmanager.hh:173
CommunicationManagerList(CombinedObjectType &cObj)
constructor
Definition: communicationmanager.hh:342
NonBlockingCommunicationType nonBlockingCommunication() const
return object for non-blocking communication
Definition: communicationmanager.hh:215
bool handles(IsDiscreteFunction &df) const
Definition: communicationmanager.hh:329
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:244
DiscreteFunctionCommunicator(DiscreteFunctionType &df, const Operation &op)
constructor taking disctete function
Definition: communicationmanager.hh:318
double exchangeTime() const
return time needed for last exchange of data
Definition: communicationmanager.hh:209
double receive(DiscreteFunction &discreteFunction)
receive method with default operation
Definition: communicationmanager.hh:154
const CommunicationDirection dir_
Definition: communicationmanager.hh:168
CommunicationManager(const SpaceImp &space, const InterfaceType interface, const CommunicationDirection dir)
constructor taking space and communication interface/direction
Definition: communicationmanager.hh:273
void addToList(DiscreteFunctionImp &df, const Operation &operation)
add discrete function to communication list
Definition: communicationmanager.hh:349
void removeFromList(DiscreteFunction &df)
Definition: communicationmanager.hh:365
void addToList(DiscreteFunctionImp &df)
add discrete function to communication list
Definition: communicationmanager.hh:358
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:53
Definition: cachedcommmanager.hh:47
just copy data
Definition: commoperations.hh:127
default communication manager using just the grids communicate method
Definition: communicationmanager.hh:77
use Default CommunicationManager as Communication Manager
Definition: communicationmanager.hh:268
Proxy class to DependencyCache which is singleton per space.
Definition: communicationmanager.hh:290