dune-fem  2.4.1-rc
blockdiagonal.hh
Go to the documentation of this file.
1 #ifndef DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
2 #define DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
3 
4 #include <cassert>
5 
6 #include <dune/common/fmatrix.hh>
7 #include <dune/common/nullptr.hh>
8 
15 
16 namespace Dune
17 {
18 
19  namespace Fem
20  {
21 
22  // BlockDiagonalLinearOperator
23  // ---------------------------
24 
25  template< class DiscreteFunctionSpace,
26  class LocalBlock = Dune::FieldMatrix< typename DiscreteFunctionSpace ::
27  RangeFieldType, DiscreteFunctionSpace::localBlockSize, DiscreteFunctionSpace::localBlockSize > >
29  : public Fem::AssembledOperator< AdaptiveDiscreteFunction< DiscreteFunctionSpace > >
30  {
33 
34  public:
37 
40 
42  typedef typename RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType;
43 
44  typedef typename DomainSpaceType::EntityType DomainEntityType;
45  typedef typename RangeSpaceType::EntityType RangeEntityType;
46 
47  static const int localBlockSize = DomainSpaceType::localBlockSize;
48 
49  typedef LocalBlock LocalBlockType;
50 
51  // types needed for CommunicationManager to fake DiscreteFunction interface
52  typedef LocalBlockType* DofBlockPtrType;
53  typedef const LocalBlockType* ConstDofBlockPtrType;
54  typedef typename LocalBlockType::row_type DofType ;
55  typedef DomainSpaceType DiscreteFunctionSpaceType ;
56 
57  template< class Operation >
59  {
60  typedef typename DiscreteFunctionSpaceType
63  };
64 
65  private:
66 
67  class LocalMatrixTraits;
68  class LocalMatrix;
70 
71  public:
74 
76 
77 
78  BlockDiagonalLinearOperator ( const std::string &name,
79  const DomainSpaceType &domainSpace,
80  const RangeSpaceType &rangeSpace )
81  : name_( name ),
82  space_( domainSpace ),
83  localMatrixFactory_( *this ),
85  {
86  if( &domainSpace != &rangeSpace )
87  DUNE_THROW( InvalidStateException, "BlockDiagonalLinearOperator must be created with identical spaces." );
88  }
89 
90  void operator() ( const DomainFunctionType &u, RangeFunctionType &w ) const
91  {
92  multiply( u, w );
93  }
94 
95  template < class DomainSpace, class RangeSpace >
98  {
99  multiply( u, w );
100  }
101 
102  template < class DomainSpace, class RangeSpace >
105  {
106  typedef typename std::vector< LocalBlockType >::const_iterator Iterator;
107  const typename DomainSpace :: RangeFieldType *uit = u.leakPointer();
108  typename RangeSpace :: RangeFieldType *wit = w.leakPointer();
109  const Iterator dend = diagonal_.end();
110  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit )
111  {
112  dit->mv( uit, wit );
113  uit += dit->M();
114  wit += dit->N();
115  }
116  assert( uit == u.leakPointer() + u.size() );
117  assert( wit == w.leakPointer() + w.size() );
118  }
119 
120  void clear ()
121  {
122  typedef typename std::vector< LocalBlockType >::iterator Iterator;
123  const Iterator dend = diagonal_.end();
124  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit )
125  *dit = RangeFieldType( 0 );
126  }
127 
128  template< class Functor >
129  void forEach ( const Functor &functor )
130  {
131  typedef typename std::vector< LocalBlockType >::iterator Iterator;
132  const Iterator dend = diagonal_.end();
133  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit )
134  functor( *dit );
135  }
136 
137  void invert ()
138  {
139  typedef typename std::vector< LocalBlockType >::iterator Iterator;
140  const Iterator dend = diagonal_.end();
141  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit )
142  dit->invert();
143  }
144 
145  void rightmultiply( const ThisType& other )
146  {
147  assert( other.diagonal_.size() == diagonal_.size() );
148  typedef typename std::vector< LocalBlockType >::iterator Iterator;
149  typedef typename std::vector< LocalBlockType >::const_iterator ConstIterator;
150  ConstIterator otherIt = other.diagonal_.begin();
151  const Iterator dend = diagonal_.end();
152  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit, ++otherIt )
153  {
154  (*dit).rightmultiply( *otherIt );
155  }
156  }
157 
158  void leftmultiply( const ThisType& other )
159  {
160  assert( other.diagonal_.size() == diagonal_.size() );
161  typedef typename std::vector< LocalBlockType >::iterator Iterator;
162  typedef typename std::vector< LocalBlockType >::const_iterator ConstIterator;
163  ConstIterator otherIt = other.diagonal_.begin();
164  const Iterator dend = diagonal_.end();
165  for( Iterator dit = diagonal_.begin(); dit != dend; ++dit, ++otherIt )
166  {
167  (*dit).leftmultiply( *otherIt );
168  }
169  }
170 
172  DofBlockPtrType block( const size_t block )
173  {
174  assert( block < diagonal_.size() );
175  return &diagonal_[ block ];
176  }
177 
179  ConstDofBlockPtrType block( const size_t block ) const
180  {
181  assert( block < diagonal_.size() );
182  return &diagonal_[ block ];
183  }
184 
189  void communicate ()
190  {
191  domainSpace().communicate( *this );
192  }
193 
197  template< class Operation >
199  dataHandle( const Operation *operation )
200  {
201  return space().createDataHandle( *this, operation );
202  }
203 
204  template< class Stencil >
205  void reserve ( const Stencil &stencil, bool verbose = false )
206  {
207  // note: to use DynamicMatrix as LocalBlockType, also resize local blocks
208  diagonal_.resize( domainSpace().blockMapper().size() );
209  }
210 
211  LocalColumnObjectType localColumn ( const DomainEntityType &domainEntity ) const
212  {
213  return LocalColumnObjectType( *this, domainEntity );
214  }
215 
216  LocalMatrixType localMatrix ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity ) const;
217 
218  const DomainSpaceType &domainSpace () const { return space_; }
219  const RangeSpaceType &rangeSpace () const { return space_; }
220 
222  const DomainSpaceType &space () const { return space_; }
223 
224  const std::string &name () const { return name_; }
225 
226  protected:
227  std::string name_;
228  const RangeSpaceType &space_;
229  std::vector< LocalBlockType > diagonal_;
230 
232  mutable LocalMatrixStackType localMatrixStack_;
233  };
234 
235 
236 
237  // BlockDiagonalLinearOperator::LocalMatrixTraits
238  // ----------------------------------------------
239 
240  template< class DiscreteFunctionSpace, class LocalBlock >
242  {
244 
245  public:
247 
249 
252 
253  typedef RangeFieldType LittleBlockType;
254  };
255 
256 
257 
258  // BlockDiagonalLinearOperator::LocalMatrix
259  // ----------------------------------------
260 
261  template< class DiscreteFunctionSpace, class LocalBlock >
263  : public LocalMatrixInterface< LocalMatrixTraits >
264  {
265  typedef LocalMatrix ThisType;
267 
268  public:
270 
272 
274  typedef typename BaseType::RangeBasisFunctionSetType RangeBasisFunctionSetType;
275 
276  typedef typename BaseType::DomainEntityType DomainEntityType;
277  typedef typename BaseType::RangeEntityType RangeEntityType;
278 
279  private:
280  typedef DomainBasisFunctionSetType BasisFunctionSetType;
282 
283  struct SetLocalBlockFunctor
284  {
285  SetLocalBlockFunctor ( std::vector< LocalBlockType > &diagonal,
286  LocalBlockType *&localBlock )
287  : diagonal_( diagonal ),
288  localBlock_( localBlock )
289  {}
290 
291  void operator() ( int localDoF, std::size_t globalDoF )
292  {
293  assert( localDoF == 0 );
294  assert( globalDoF < diagonal_.size() );
295  localBlock_ = &diagonal_[ globalDoF ];
296  }
297 
298  private:
299  std::vector< LocalBlockType > &diagonal_;
300  LocalBlockType *&localBlock_;
301  };
302 
303  public:
304  explicit LocalMatrix ( OperatorType &op )
305  : op_( &op ),
306  localBlock_( nullptr )
307  {}
308 
309  void init ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity )
310  {
311  basisFunctionSet_ = domainSpace().basisFunctionSet( domainEntity );
312  SetLocalBlockFunctor f( op_->diagonal_, localBlock_ );
313  domainSpace().blockMapper().mapEach( domainEntity, f );
314  if( &domainEntity != &rangeEntity )
315  {
316  static LocalBlockType dummyBlock( 0 );
317 
318  LocalBlockType *otherBlock = 0;
319  SetLocalBlockFunctor f( op_->diagonal_, otherBlock );
320  rangeSpace().blockMapper().mapEach( rangeEntity, f );
321  // check whether the blocks match, otherwise off-diagonal
322  // for off-diagonal we simply use a dummy local matrix
323  if( otherBlock != localBlock_ )
324  localBlock_ = &dummyBlock ;
325  }
326  }
327 
328  void clear () { localBlock() = RangeFieldType( 0 ); }
329  void scale ( const RangeFieldType &a ) { localBlock() *= a; }
330 
331  RangeFieldType get ( int i, int j ) const { return localBlock()[ i ][ j ]; }
332  void add ( int i, int j, const RangeFieldType &value ) { localBlock()[ i ][ j ] += value; }
333  void set ( int i, int j, const RangeFieldType &value ) { localBlock()[ i ][ j ] = value; }
334 
335  void clearRow ( int i ) { localBlock()[ i ] = RangeFieldType( 0 ); }
336 
337  void clearCol ( int j )
338  {
339  for( int i = 0; i < rows(); ++i )
340  localBlock()[ i ][ j ] = RangeFieldType( 0 );
341  }
342 
343  template< class DomainLocalFunction, class RangeLocalFunction >
344  void multiplyAdd ( const DomainLocalFunction &x, RangeLocalFunction &y ) const
345  {
346  localBlock().umv( x, y );
347  }
348 
349  void finalize () {}
350  void resort () {}
351 
352  int rows () const { return localBlock().N(); }
353  int columns () const { return localBlock().M(); }
354 
355  const DomainSpaceType &domainSpace () const { return op_->domainSpace(); }
356  const RangeSpaceType &rangeSpace () const { return op_->rangeSpace(); }
357 
358  const DomainBasisFunctionSetType &domainBasisFunctionSet () const { return basisFunctionSet_; }
359  const RangeBasisFunctionSetType &rangeBasisFunctionSet () const { return basisFunctionSet_; }
360 
361  const DomainEntityType &domainEntity () const { return domainBasisFunctionSet().entity(); }
362  const RangeEntityType &rangeEntity () const { return rangeBasisFunctionSet().entity(); }
363 
364  private:
365  const LocalBlockType &localBlock () const { assert( localBlock_ ); return *localBlock_; }
366  LocalBlockType &localBlock () { assert( localBlock_ ); return *localBlock_; }
367 
368  OperatorType *op_;
369  BasisFunctionSetType basisFunctionSet_;
370  LocalBlockType *localBlock_;
371  };
372 
373 
374 
375  // BlockDiagonalLinearOperator::LocalMatrixFactory
376  // -----------------------------------------------
377 
378  template< class DiscreteFunctionSpace, class LocalBlock >
380  {
383 
384  explicit LocalMatrixFactory ( OperatorType &op )
385  : op_( &op )
386  {}
387 
388  ObjectType *newObject () const { return new ObjectType( *op_ ); }
389 
390  private:
391  OperatorType *op_;
392  };
393 
394 
395 
396  // Implementation of BlockDiagonalLinearOperator
397  // ---------------------------------------------
398 
399  template< class DiscreteFunctionSpace, class LocalBlock >
402  ::localMatrix ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity ) const
403  {
404  return LocalMatrixType( localMatrixStack_, domainEntity, rangeEntity );
405  }
406 
407  } // namespace Fem
408 
409 } // namespace Dune
410 
411 #endif // #ifndef DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
RangeFunctionType::DiscreteFunctionSpaceType RangeSpaceType
Definition: blockdiagonal.hh:42
Traits::DomainSpaceType DomainSpaceType
type of domain discrete function space
Definition: localmatrix.hh:51
AdaptiveDiscreteFunction< DiscreteFunctionSpace > RangeFunctionType
type of discrete function in the operator&#39;s range
Definition: operator.hh:30
void clear()
Definition: blockdiagonal.hh:120
void clear()
Definition: blockdiagonal.hh:328
DomainSpaceType::EntityType DomainEntityType
Definition: blockdiagonal.hh:44
Definition: blockdiagonal.hh:28
Definition: localmatrixwrapper.hh:16
DiscreteFunctionSpaceType::template CommDataHandle< ThisType, Operation >::Type Type
Definition: blockdiagonal.hh:62
default implementation for a general operator stencil
Definition: stencil.hh:31
void add(int i, int j, const RangeFieldType &value)
Definition: blockdiagonal.hh:332
LocalColumnObjectType localColumn(const DomainEntityType &domainEntity) const
Definition: blockdiagonal.hh:211
void communicate()
copy matrices to ghost cells to make this class work in parallel
Definition: blockdiagonal.hh:189
BaseType::RangeFieldType RangeFieldType
Definition: blockdiagonal.hh:271
const std::string & name() const
Definition: blockdiagonal.hh:224
Definition: adaptivefunction/adaptivefunction.hh:34
BaseType::RangeFunctionType RangeFunctionType
Definition: blockdiagonal.hh:36
const DomainSpaceType & domainSpace() const
Definition: blockdiagonal.hh:355
RangeSpaceType::EntityType RangeEntityType
Definition: blockdiagonal.hh:45
void clearRow(int i)
Definition: blockdiagonal.hh:335
void forEach(const Functor &functor)
Definition: blockdiagonal.hh:129
const RangeBasisFunctionSetType & rangeBasisFunctionSet() const
Definition: blockdiagonal.hh:359
LocalBlockType::row_type DofType
Definition: blockdiagonal.hh:54
static const int localBlockSize
Definition: blockdiagonal.hh:47
DomainSpaceType::BasisFunctionSetType DomainBasisFunctionSetType
type of base function sets within domain function space
Definition: localmatrix.hh:58
const RangeSpaceType & space_
Definition: blockdiagonal.hh:228
void leftmultiply(const ThisType &other)
Definition: blockdiagonal.hh:158
const DomainEntityType & domainEntity() const
Definition: blockdiagonal.hh:361
LocalMatrixStackType localMatrixStack_
Definition: blockdiagonal.hh:232
Interface for local matrix classes.
Definition: localmatrix.hh:28
OperatorType::RangeSpaceType RangeSpaceType
Definition: blockdiagonal.hh:251
const DomainSpaceType & domainSpace() const
Definition: blockdiagonal.hh:218
LocalMatrixFactory localMatrixFactory_
Definition: blockdiagonal.hh:231
LocalMatrixFactory(OperatorType &op)
Definition: blockdiagonal.hh:384
BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock > OperatorType
Definition: blockdiagonal.hh:269
SizeType size() const
Return the number of blocks in the block vector.
Definition: discretefunction.hh:740
void rightmultiply(const ThisType &other)
Definition: blockdiagonal.hh:145
BaseType::DomainFieldType DomainFieldType
Definition: blockdiagonal.hh:38
Definition: coordinate.hh:4
ColumnObject< ThisType > LocalColumnObjectType
Definition: blockdiagonal.hh:75
BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock > OperatorType
Definition: blockdiagonal.hh:381
LocalBlock LocalBlockType
Definition: blockdiagonal.hh:49
BaseType::DomainBasisFunctionSetType DomainBasisFunctionSetType
Definition: blockdiagonal.hh:273
void clearCol(int j)
Definition: blockdiagonal.hh:337
DomainSpaceType DiscreteFunctionSpaceType
Definition: blockdiagonal.hh:55
BaseType::DomainEntityType DomainEntityType
Definition: blockdiagonal.hh:276
std::string name_
Definition: blockdiagonal.hh:227
BaseType::RangeFieldType RangeFieldType
Definition: blockdiagonal.hh:39
CommDataHandle< Operation >::Type dataHandle(const Operation *operation)
return reference to data handle object (needed to make this class work with CommunicationManager) ...
Definition: blockdiagonal.hh:199
void invert()
Definition: blockdiagonal.hh:137
DofType * leakPointer()
Definition: adaptivefunction/adaptivefunction.hh:95
void reserve(const Stencil &stencil, bool verbose=false)
Definition: blockdiagonal.hh:205
AdaptiveDiscreteFunction< DiscreteFunctionSpace >::RangeFieldType DomainFieldType
field type of the operator&#39;s domain
Definition: operator.hh:33
Traits::RangeSpaceType RangeSpaceType
type of range discrete function space
Definition: localmatrix.hh:54
AdaptiveDiscreteFunction< DiscreteFunctionSpace >::RangeFieldType RangeFieldType
field type of the operator&#39;s range
Definition: operator.hh:35
OperatorType::DomainSpaceType DomainSpaceType
Definition: blockdiagonal.hh:250
RangeFieldType LittleBlockType
Definition: blockdiagonal.hh:253
BlockDiagonalLinearOperator(const std::string &name, const DomainSpaceType &domainSpace, const RangeSpaceType &rangeSpace)
Definition: blockdiagonal.hh:78
LocalMatrix ObjectType
Definition: blockdiagonal.hh:382
ObjectStack< LocalMatrixFactory > LocalMatrixStackType
Definition: blockdiagonal.hh:69
LocalBlockType * DofBlockPtrType
Definition: blockdiagonal.hh:52
ConstDofBlockPtrType block(const size_t block) const
return block matrix for given block number (== entity number)
Definition: blockdiagonal.hh:179
OperatorType::RangeFieldType RangeFieldType
Definition: blockdiagonal.hh:248
const RangeEntityType & rangeEntity() const
Definition: blockdiagonal.hh:362
void resort()
Definition: blockdiagonal.hh:350
ObjectType * newObject() const
Definition: blockdiagonal.hh:388
OperatorType::LocalMatrix LocalMatrixType
Definition: blockdiagonal.hh:246
LocalMatrixWrapper< LocalMatrixStackType > LocalMatrixType
Definition: blockdiagonal.hh:73
discrete function space
void operator()(const DomainFunctionType &u, RangeFunctionType &w) const
Definition: blockdiagonal.hh:90
abstract matrix operator
Definition: operator.hh:106
DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType
Definition: blockdiagonal.hh:41
DofBlockPtrType block(const size_t block)
return block matrix for given block number (== entity number)
Definition: blockdiagonal.hh:172
void scale(const RangeFieldType &a)
Definition: blockdiagonal.hh:329
BaseType::RangeBasisFunctionSetType RangeBasisFunctionSetType
Definition: blockdiagonal.hh:274
int rows() const
Definition: blockdiagonal.hh:352
void init(const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity)
Definition: blockdiagonal.hh:309
Definition: columnobject.hh:11
void multiply(const AdaptiveDiscreteFunction< DomainSpace > &u, AdaptiveDiscreteFunction< RangeSpace > &w) const
Definition: blockdiagonal.hh:103
BaseType::RangeEntityType RangeEntityType
Definition: blockdiagonal.hh:277
const RangeSpaceType & rangeSpace() const
Definition: blockdiagonal.hh:219
LocalMatrix(OperatorType &op)
Definition: blockdiagonal.hh:304
void multiplyAdd(const DomainLocalFunction &x, RangeLocalFunction &y) const
Definition: blockdiagonal.hh:344
const DomainBasisFunctionSetType & domainBasisFunctionSet() const
Definition: blockdiagonal.hh:358
const RangeSpaceType & rangeSpace() const
Definition: blockdiagonal.hh:356
BaseType::DiscreteFunctionSpaceType DiscreteFunctionSpaceType
Definition: adaptivefunction/adaptivefunction.hh:53
const DomainSpaceType & space() const
return reference to space (needed to make this class work with CommunicationManager) ...
Definition: blockdiagonal.hh:222
LocalMatrixType localMatrix(const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity) const
Definition: blockdiagonal.hh:402
BaseType::DomainFunctionType DomainFunctionType
Definition: blockdiagonal.hh:35
int columns() const
Definition: blockdiagonal.hh:353
Definition: bartonnackmaninterface.hh:15
void finalize()
Definition: blockdiagonal.hh:349
std::vector< LocalBlockType > diagonal_
Definition: blockdiagonal.hh:229
const LocalBlockType * ConstDofBlockPtrType
Definition: blockdiagonal.hh:53