DUNE-FEM (unstable)

blockdiagonal.hh
1#ifndef DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
2#define DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
3
4// system includes
5#include <cassert>
6#include <string>
7#include <vector>
8
9// local includes
11#include <dune/fem/function/adaptivefunction.hh>
12#include <dune/fem/operator/common/localmatrix.hh>
13#include <dune/fem/operator/common/localmatrixwrapper.hh>
14#include <dune/fem/operator/common/operator.hh>
15#include <dune/fem/operator/matrix/columnobject.hh>
16#include <dune/fem/storage/objectstack.hh>
17
18namespace Dune
19{
20
21 namespace Fem
22 {
23
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:
35 typedef typename BaseType::DomainFunctionType DomainFunctionType;
36 typedef typename BaseType::RangeFunctionType RangeFunctionType;
37
38 typedef typename BaseType::DomainFieldType DomainFieldType;
39 typedef typename BaseType::RangeFieldType RangeFieldType;
40
41 typedef typename DomainFunctionType::DiscreteFunctionSpaceType DomainSpaceType;
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 >
58 struct CommDataHandle
59 {
60 typedef typename DiscreteFunctionSpaceType
61 :: template CommDataHandle< ThisType, Operation > :: Type
62 Type;
63 };
64
65 private:
66
67 class LocalMatrixTraits;
68 class LocalMatrix;
69 struct LocalMatrixFactory;
70
71 public:
73 typedef LocalMatrixWrapper< LocalMatrixStackType > LocalMatrixType;
74
75 typedef ColumnObject< ThisType > LocalColumnObjectType;
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 ),
84 localMatrixStack_( localMatrixFactory_ )
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 >
96 void operator() ( const AdaptiveDiscreteFunction< DomainSpace > &u,
98 {
99 multiply( u, w );
100 }
101
102 template < class DomainSpace, class RangeSpace >
103 void multiply( const AdaptiveDiscreteFunction< DomainSpace > &u,
105 {
106 const auto uit = u.leakPointer();
107 auto wit = w.leakPointer();
108 for( auto& entry : diagonal_ )
109 {
110 entry.mv( uit, wit );
111 uit += entry.M();
112 wit += entry.N();
113 }
114 assert( uit == u.leakPointer() + u.size() );
115 assert( wit == w.leakPointer() + w.size() );
116 }
117
118 virtual void clear ()
119 {
120 for( auto& entry : diagonal_ )
121 entry = RangeFieldType( 0 );
122 }
123
124 template< class Functor >
125 void forEach ( const Functor &functor )
126 {
127 for( auto& entry : diagonal_ )
128 functor( entry );
129 }
130
131 void invert ()
132 {
133 for( auto& entry : diagonal_ )
134 entry.invert();
135 }
136
137 void rightmultiply( const ThisType& other )
138 {
139 assert( other.diagonal_.size() == diagonal_.size() );
140 auto it = other.diagonal_.begin();
141 for( auto& entry : diagonal_ )
142 {
143 entry.rightmultiply( *it );
144 ++it;
145 }
146 }
147
148 void leftmultiply( const ThisType& other )
149 {
150 assert( other.diagonal_.size() == diagonal_.size() );
151 auto it = other.diagonal_.begin();
152 for( auto& entry : diagonal_ )
153 {
154 entry.leftmultiply( *it );
155 ++it;
156 }
157 }
158
160 DofBlockPtrType block( const std::size_t block )
161 {
162 assert( block < diagonal_.size() );
163 return &diagonal_[ block ];
164 }
165
167 ConstDofBlockPtrType block( const std::size_t block ) const
168 {
169 assert( block < diagonal_.size() );
170 return &diagonal_[ block ];
171 }
172
178 {
179 domainSpace().communicate( *this );
180 }
181
185 template< class Operation >
186 typename CommDataHandle< Operation > :: Type
187 dataHandle( const Operation &operation )
188 {
189 return space().createDataHandle( *this, operation );
190 }
191
192 template< class Stencil >
193 void reserve ( const Stencil &stencil, bool verbose = false )
194 {
195 // note: to use DynamicMatrix as LocalBlockType, also resize local blocks
196 diagonal_.resize( domainSpace().blockMapper().size() );
197 }
198
199 LocalColumnObjectType localColumn ( const DomainEntityType &domainEntity ) const
200 {
201 return LocalColumnObjectType( *this, domainEntity );
202 }
203
204 LocalMatrixType localMatrix ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity ) const;
205
206 const DomainSpaceType &domainSpace () const
207 {
208 return space_;
209 }
210 const RangeSpaceType &rangeSpace () const
211 {
212 return space_;
213 }
214
216 const DomainSpaceType &space () const
217 {
218 return space_;
219 }
220
221 const std::string &name () const
222 {
223 return name_;
224 }
225
226 protected:
227 std::string name_;
228 const RangeSpaceType &space_;
229 std::vector< LocalBlockType > diagonal_;
230 LocalMatrixFactory localMatrixFactory_;
231 mutable LocalMatrixStackType localMatrixStack_;
232 };
233
234
235
236 // BlockDiagonalLinearOperator::LocalMatrixTraits
237 // ----------------------------------------------
238
239 template< class DiscreteFunctionSpace, class LocalBlock >
240 class BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock >::LocalMatrixTraits
241 {
242 typedef BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock > OperatorType;
243
244 public:
245 typedef typename OperatorType::LocalMatrix LocalMatrixType;
246
247 typedef typename OperatorType::RangeFieldType RangeFieldType;
248
249 typedef typename OperatorType::DomainSpaceType DomainSpaceType;
250 typedef typename OperatorType::RangeSpaceType RangeSpaceType;
251
252 typedef RangeFieldType LittleBlockType;
253 };
254
255
256
257 // BlockDiagonalLinearOperator::LocalMatrix
258 // ----------------------------------------
259
260 template< class DiscreteFunctionSpace, class LocalBlock >
261 class BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock >::LocalMatrix
262 : public LocalMatrixInterface< LocalMatrixTraits >
263 {
264 typedef LocalMatrix ThisType;
265 typedef LocalMatrixInterface< LocalMatrixTraits > BaseType;
266
267 public:
268 typedef BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock > OperatorType;
269
270 typedef typename BaseType::RangeFieldType RangeFieldType;
271
272 typedef typename BaseType::DomainBasisFunctionSetType DomainBasisFunctionSetType;
273 typedef typename BaseType::RangeBasisFunctionSetType RangeBasisFunctionSetType;
274
275 typedef typename BaseType::DomainEntityType DomainEntityType;
276 typedef typename BaseType::RangeEntityType RangeEntityType;
277
278 private:
279 typedef DomainBasisFunctionSetType BasisFunctionSetType;
280 typedef typename OperatorType::LocalBlockType LocalBlockType;
281
282 struct SetLocalBlockFunctor
283 {
284 SetLocalBlockFunctor ( std::vector< LocalBlockType > &diagonal,
285 LocalBlockType *&localBlock )
286 : diagonal_( diagonal ),
287 localBlock_( localBlock )
288 {}
289
290 void operator() ( int localDoF, std::size_t globalDoF )
291 {
292 assert( localDoF == 0 );
293 assert( globalDoF < diagonal_.size() );
294 localBlock_ = &diagonal_[ globalDoF ];
295 }
296
297 private:
298 std::vector< LocalBlockType > &diagonal_;
299 LocalBlockType *&localBlock_;
300 };
301
302 public:
303 explicit LocalMatrix ( OperatorType &op )
304 : op_( &op ),
305 localBlock_( nullptr )
306 {}
307
308 void init ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity )
309 {
310 basisFunctionSet_ = domainSpace().basisFunctionSet( domainEntity );
311 SetLocalBlockFunctor f( op_->diagonal_, localBlock_ );
312 domainSpace().blockMapper().mapEach( domainEntity, f );
313 if( &domainEntity != &rangeEntity )
314 {
315 static LocalBlockType dummyBlock( 0 );
316
317 LocalBlockType *otherBlock = 0;
318 SetLocalBlockFunctor f( op_->diagonal_, otherBlock );
319 rangeSpace().blockMapper().mapEach( rangeEntity, f );
320 // check whether the blocks match, otherwise off-diagonal
321 // for off-diagonal we simply use a dummy local matrix
322 if( otherBlock != localBlock_ )
323 localBlock_ = &dummyBlock ;
324 }
325 }
326
327 void clear ()
328 {
329 localBlock() = RangeFieldType( 0 );
330 }
331 void scale ( const RangeFieldType &a )
332 {
333 localBlock() *= a;
334 }
335
336 RangeFieldType get ( int i, int j ) const
337 {
338 return localBlock()[ i ][ j ];
339 }
340 void add ( int i, int j, const RangeFieldType &value )
341 {
342 localBlock()[ i ][ j ] += value;
343 }
344 void set ( int i, int j, const RangeFieldType &value )
345 {
346 localBlock()[ i ][ j ] = value;
347 }
348
349 void clearRow ( int i )
350 {
351 localBlock()[ i ] = RangeFieldType( 0 );
352 }
353
354 void clearCol ( int j )
355 {
356 for( int i = 0; i < rows(); ++i )
357 localBlock()[ i ][ j ] = RangeFieldType( 0 );
358 }
359
360 template< class DomainLocalFunction, class RangeLocalFunction >
361 void multiplyAdd ( const DomainLocalFunction &x, RangeLocalFunction &y ) const
362 {
363 localBlock().umv( x, y );
364 }
365
366 void finalize ()
367 {}
368 void resort ()
369 {}
370
371 int rows () const
372 {
373 return localBlock().N();
374 }
375 int columns () const
376 {
377 return localBlock().M();
378 }
379
380 const DomainSpaceType &domainSpace () const
381 {
382 return op_->domainSpace();
383 }
384 const RangeSpaceType &rangeSpace () const
385 { return op_->rangeSpace();
386 }
387
388 const DomainBasisFunctionSetType &domainBasisFunctionSet () const
389 {
390 return basisFunctionSet_;
391 }
392 const RangeBasisFunctionSetType &rangeBasisFunctionSet () const
393 {
394 return basisFunctionSet_;
395 }
396
397 const DomainEntityType &domainEntity () const
398 {
399 return domainBasisFunctionSet().entity();
400 }
401 const RangeEntityType &rangeEntity () const
402 {
403 return rangeBasisFunctionSet().entity();
404 }
405
406 private:
407 const LocalBlockType &localBlock () const
408 {
409 assert( localBlock_ );
410 return *localBlock_;
411 }
412 LocalBlockType &localBlock ()
413 {
414 assert( localBlock_ );
415 return *localBlock_;
416 }
417
418 OperatorType *op_;
419 BasisFunctionSetType basisFunctionSet_;
420 LocalBlockType *localBlock_;
421 };
422
423
424
425 // BlockDiagonalLinearOperator::LocalMatrixFactory
426 // -----------------------------------------------
427
428 template< class DiscreteFunctionSpace, class LocalBlock >
429 struct BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock >::LocalMatrixFactory
430 {
431 typedef BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock > OperatorType;
432 typedef LocalMatrix ObjectType;
433
434 explicit LocalMatrixFactory ( OperatorType &op )
435 : op_( &op )
436 {}
437
438 ObjectType *newObject () const
439 {
440 return new ObjectType( *op_ );
441 }
442
443 private:
444 OperatorType *op_;
445 };
446
447
448
449 // Implementation of BlockDiagonalLinearOperator
450 // ---------------------------------------------
451
452 template< class DiscreteFunctionSpace, class LocalBlock >
453 inline typename BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock >::LocalMatrixType
454 BlockDiagonalLinearOperator< DiscreteFunctionSpace, LocalBlock >
455 ::localMatrix ( const DomainEntityType &domainEntity, const RangeEntityType &rangeEntity ) const
456 {
457 return LocalMatrixType( localMatrixStack_, domainEntity, rangeEntity );
458 }
459
460 } // namespace Fem
461
462} // namespace Dune
463
464#endif // #ifndef DUNE_FEM_OPERATOR_LINEAR_BLOCKDIAGONAL_HH
discrete function space
Definition: adaptivefunction.hh:48
abstract matrix operator
Definition: operator.hh:133
BlockDiagonalLinearOperator.
Definition: blockdiagonal.hh:30
CommDataHandle< Operation >::Type dataHandle(const Operation &operation)
return reference to data handle object (needed to make this class work with CommunicationManager)
Definition: blockdiagonal.hh:187
ConstDofBlockPtrType block(const std::size_t block) const
return block matrix for given block number (== entity number)
Definition: blockdiagonal.hh:167
void communicate()
copy matrices to ghost cells to make this class work in parallel
Definition: blockdiagonal.hh:177
const DomainSpaceType & space() const
return reference to space (needed to make this class work with CommunicationManager)
Definition: blockdiagonal.hh:216
DofBlockPtrType block(const std::size_t block)
return block matrix for given block number (== entity number)
Definition: blockdiagonal.hh:160
SizeType size() const
Return the number of blocks in the block vector.
Definition: discretefunction.hh:755
default implementation for a general operator stencil
Definition: stencil.hh:35
A dense n x m matrix.
Definition: fmatrix.hh:117
Default exception if a function was called while the object is not in a valid state for that function...
Definition: exceptions.hh:281
Implements a matrix constructed from a given type representing a field and compile-time given number ...
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:256
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
constexpr auto get(std::integer_sequence< T, II... >, std::integral_constant< std::size_t, pos >={})
Return the entry at position pos of the given sequence.
Definition: integersequence.hh:22
AdaptiveDiscreteFunction< DiscreteFunctionSpace > DomainFunctionType
type of discrete function in the operator's domain
Definition: operator.hh:36
RangeFunction::RangeFieldType RangeFieldType
field type of the operator's range
Definition: operator.hh:43
DomainFunction::RangeFieldType DomainFieldType
field type of the operator's domain
Definition: operator.hh:41
AdaptiveDiscreteFunction< DiscreteFunctionSpace > RangeFunctionType
type of discrete function in the operator's range
Definition: operator.hh:38
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)