DUNE-FEM (unstable)

stencil.hh
1#ifndef DUNE_FEM_STENCIL_HH
2#define DUNE_FEM_STENCIL_HH
3
4#include <algorithm>
5#include <map>
6#include <numeric>
7#include <set>
8#include <type_traits>
9#include <unordered_map>
10
11#include <dune/grid/common/gridenums.hh>
12#include <dune/grid/common/rangegenerators.hh>
13#include <dune/fem/misc/functor.hh>
14#include <dune/fem/common/utility.hh>
15
16namespace Dune
17{
18 namespace Fem
19 {
33 template <class DomainSpace, class RangeSpace>
34 class Stencil
35 {
36 // Domain = Row
37 typedef typename DomainSpace::IteratorType DomainIteratorType;
38 typedef typename DomainSpace::BlockMapperType DomainBlockMapper;
39
40 // Range = Column
41 typedef typename RangeSpace::IteratorType RangeIteratorType;
42 typedef typename RangeSpace::BlockMapperType RangeBlockMapper;
43
44 public:
45 typedef typename DomainIteratorType::Entity DomainEntityType;
46 typedef typename RangeIteratorType::Entity RangeEntityType;
47 typedef typename DomainBlockMapper::GlobalKeyType DomainGlobalKeyType;
48 typedef typename RangeBlockMapper::GlobalKeyType RangeGlobalKeyType;
49
51 typedef std::set< DomainGlobalKeyType > LocalStencilType;
52
54 typedef typename std::vector< std::size_t > :: size_type IndexType;
55
56 static const bool indexIsSimple = std::is_convertible< RangeGlobalKeyType, IndexType >::value;
57 //static const bool indexIsPOD = false ;//std::is_convertible< RangeGlobalKeyType, IndexType >::value;
58 typedef typename std::conditional< indexIsSimple,
59 std::unordered_map< RangeGlobalKeyType, LocalStencilType >,
60 std::map< RangeGlobalKeyType, LocalStencilType > > :: type GlobalStencilType;
61
62 public:
69 Stencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
70 : domainSpace_(dSpace), rangeSpace_(rSpace)
71 , domainBlockMapper_( dSpace.blockMapper() )
72 , rangeBlockMapper_( rSpace.blockMapper() )
73 {
74 }
75 virtual ~Stencil() {}
76
77 const DomainSpace &domainSpace() const
78 {
79 return domainSpace_;
80 }
81 const RangeSpace &rangeSpace() const
82 {
83 return rangeSpace_;
84 }
85
93 void fill ( const DomainEntityType &dEntity, const RangeEntityType &rEntity,
94 bool fillGhost=true ) const
95 {
96 if( (dEntity.partitionType() == GhostEntity) && !fillGhost )
97 return;
98
99 rangeBlockMapper_.mapEach( rEntity, [ this, &dEntity ] ( int localRow, auto globalRow ) {
100 domainBlockMapper_.mapEach( dEntity, RowFillFunctor( globalStencil_[ globalRow ] ) );
101 } );
102 }
103
109 const LocalStencilType &localStencil(const RangeGlobalKeyType &key) const
110 {
111 return globalStencil()[ key ];
112 }
113
116 const GlobalStencilType &globalStencil() const
117 {
118 return globalStencil_;
119 }
120
124 {
125 int maxNZ = 0;
126 for( const auto& entry : globalStencil_ )
127 {
128 maxNZ = std::max( maxNZ, static_cast<int>( entry.second.size() ) );
129 }
130 return maxNZ;
131 }
132
133 int rows () const { return rangeBlockMapper_.size(); }
134 int cols () const { return domainBlockMapper_.size(); }
135
137 void update()
138 {
139 globalStencil_.clear();
140 // compute stencil based on overloaded implementation
141 setupStencil();
142 }
143
144 [[deprecated("Use Stencil::update instead()")]]
145 void setup() {
146 update();
147 }
148
149 protected:
151 virtual void setupStencil() const = 0;
152
153 private:
154 struct RowFillFunctor
155 {
156 explicit RowFillFunctor ( LocalStencilType &localStencil )
157 : localStencil_( localStencil )
158 {}
159
160 void operator() ( const std::size_t, const DomainGlobalKeyType &domainGlobal ) const
161 {
162 localStencil_.insert( domainGlobal );
163 }
164
165 private:
166 LocalStencilType &localStencil_;
167 };
168
169 protected:
170 const DomainSpace &domainSpace_;
171 const RangeSpace &rangeSpace_;
172 const DomainBlockMapper &domainBlockMapper_;
173 const RangeBlockMapper &rangeBlockMapper_;
174
175 mutable GlobalStencilType globalStencil_;
176 };
177
185 template <class DomainSpace, class RangeSpace>
187 {
189 public:
190 typedef typename StencilType::DomainEntityType DomainEntityType;
191 typedef typename StencilType::RangeEntityType RangeEntityType;
192 typedef typename StencilType::DomainGlobalKeyType DomainGlobalKeyType;
193 typedef typename StencilType::RangeGlobalKeyType RangeGlobalKeyType;
194 typedef typename StencilType::LocalStencilType LocalStencilType;
195 typedef typename StencilType::GlobalStencilType GlobalStencilType;
196
197 SimpleStencil(int maxNZ)
198 : maxNZ_(maxNZ)
199 {}
201 {
202 maxNZ_ = 1;
203 }
204 int maxNonZerosEstimate() const
205 {
206 return maxNZ_;
207 }
208 const LocalStencilType &localStencil(const DomainGlobalKeyType &key) const
209 {
210 DUNE_THROW( Dune::NotImplemented, "SimpleStencil: exact stencil information is unavailable." );
211 return localStencil_;
212 }
213 const GlobalStencilType &globalStencil() const
214 {
215 DUNE_THROW( Dune::NotImplemented, "SimpleStencil: global stencil is unavailable." );
216 return stencil_;
217 }
218 protected:
219 int maxNZ_;
220 GlobalStencilType stencil_;
221 LocalStencilType localStencil_;
222 };
223
224
232 template <class DomainSpace, class RangeSpace, class LocalStencil>
234 {
237 public:
238 typedef typename StencilType::DomainEntityType DomainEntityType;
239 typedef typename StencilType::RangeEntityType RangeEntityType;
240 typedef typename StencilType::DomainGlobalKeyType DomainGlobalKeyType;
241 typedef typename StencilType::RangeGlobalKeyType RangeGlobalKeyType;
242
243 static_assert( Std::is_pod< DomainGlobalKeyType > :: value, "StencilWrapper only works for POD DomainGlobalKeyType");
244
245 typedef LocalStencil LocalStencilType;
246 typedef std::vector< LocalStencilType > GlobalStencilType;
247
248 struct Iterator
249 {
250 typedef std::pair< DomainGlobalKeyType, const LocalStencilType& > ItemType;
251
252 DomainGlobalKeyType index_;
253 const GlobalStencilType& stencil_;
254
255
256 Iterator( const DomainGlobalKeyType& init, const GlobalStencilType& stencil )
257 : index_( init ), stencil_( stencil ) {}
258
259 Iterator& operator++ ()
260 {
261 ++ index_ ;
262 return *this;
263 }
264
265 ItemType operator*() const
266 {
267 assert( index_ < stencil_.size() );
268 return ItemType( index_, stencil_[ index_ ] );
269 }
270
271 bool operator == ( const Iterator& other ) const
272 {
273 return index_ == other.index_;
274 }
275
276 bool operator != ( const Iterator& other ) const
277 {
278 return !this->operator==( other );
279 }
280 };
281
282 StencilWrapper(const GlobalStencilType& stencil)
283 : stencil_( stencil )
284 , maxNZ_( computeMaxNZ() )
285 {
286 }
287
288 int maxNonZerosEstimate() const
289 {
290 return maxNZ_;
291 }
292
293 const LocalStencilType &localStencil(const DomainGlobalKeyType &key) const
294 {
295 return stencil_[ key ];
296 }
297
298 const ThisType& globalStencil() const
299 {
300 return *this;
301 }
302
310 void fill ( const DomainEntityType &dEntity, const RangeEntityType &rEntity,
311 bool fillGhost=true )
312 {
313 }
314
315 Iterator begin() const { return Iterator(0, stencil_); }
316 Iterator end() const { return Iterator(stencil_.size(), stencil_); }
317 Iterator find( const DomainGlobalKeyType &key) const
318 {
319 assert( key < stencil_.size() );
320 return Iterator( key, stencil_);
321 }
322
323 protected:
324 int computeMaxNZ() const
325 {
326 int maxNZ = 0;
327 for( const auto& row : stencil_ )
328 {
329 maxNZ = std::max( maxNZ, int(row.size()) );
330 }
331 return maxNZ;
332 }
333
334 const GlobalStencilType& stencil_;
335 int maxNZ_;
336 };
337
338
347 template <class DomainSpace, class RangeSpace, class Partition = Dune::Partitions::InteriorBorder>
348 struct DiagonalStencil : public Stencil<DomainSpace,RangeSpace>
349 {
351 public:
352 typedef Partition PartitionType;
353 typedef typename BaseType::DomainEntityType DomainEntityType;
354 typedef typename BaseType::RangeEntityType RangeEntityType;
355 typedef typename BaseType::DomainGlobalKeyType DomainGlobalKeyType;
356 typedef typename BaseType::RangeGlobalKeyType RangeGlobalKeyType;
358 typedef typename BaseType::GlobalStencilType GlobalStencilType;
359
360 DiagonalStencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
361 : BaseType( dSpace, rSpace )
362 {
363 setupStencil();
364 }
365 virtual ~DiagonalStencil() {}
366
367 protected:
368 virtual void setupStencil () const override
369 {
370 const DomainSpace &dSpace = BaseType::domainSpace();
371 for (const auto& entity : elements( dSpace.gridPart(), PartitionType{} ) )
372 BaseType::fill(entity,entity);
373 }
374 };
375
385 template <class DomainSpace, class RangeSpace, class Partition = Dune::Partitions::InteriorBorder>
386 struct DiagonalAndNeighborStencil : public Stencil<DomainSpace,RangeSpace>
387 {
389 public:
390 typedef Partition PartitionType;
391 typedef typename BaseType::DomainEntityType DomainEntityType;
392 typedef typename BaseType::RangeEntityType RangeEntityType;
393 typedef typename BaseType::DomainGlobalKeyType DomainGlobalKeyType;
394 typedef typename BaseType::RangeGlobalKeyType RangeGlobalKeyType;
396 typedef typename BaseType::GlobalStencilType GlobalStencilType;
397
398 DiagonalAndNeighborStencil(const DomainSpace &dSpace, const RangeSpace &rSpace,
399 bool onlyNonContinuousNeighbors = false)
400 : BaseType( dSpace, rSpace ),
401 onlyNonContinuousNeighbors_(onlyNonContinuousNeighbors)
402 {
403 setupStencil();
404 }
405 virtual ~DiagonalAndNeighborStencil() {}
406
407 protected:
408 virtual void setupStencil() const override
409 {
410 const DomainSpace &dSpace = BaseType::domainSpace();
411 const RangeSpace &rSpace = BaseType::rangeSpace();
412 for (const auto & entity: elements( dSpace.gridPart(), PartitionType{} ) )
413 {
414 BaseType::fill(entity,entity);
415 for (const auto & intersection: intersections(dSpace.gridPart(), entity) )
416 {
417 if ( onlyNonContinuousNeighbors_
418 && rSpace.continuous(intersection) && dSpace.continuous(intersection) )
419 continue;
420 if( intersection.neighbor() )
421 {
422 auto neighbor = intersection.outside();
423 BaseType::fill(neighbor,entity);
424 }
425 }
426 }
427 }
428
429 bool onlyNonContinuousNeighbors_;
430 };
431
432 } // namespace Fem
433
434} // namespace Dune
435
436#endif // #if defined DUNE_FEM_STENCIL_HH
437
a watered down stencil providing only the upper bound for the non-zero entries per row.
Definition: stencil.hh:187
a simple wrapper class for sparsity patterns provide as vector< set< size_t > >
Definition: stencil.hh:234
void fill(const DomainEntityType &dEntity, const RangeEntityType &rEntity, bool fillGhost=true)
Create stencil entries for (dEntity,rEntity) pair.
Definition: stencil.hh:310
default implementation for a general operator stencil
Definition: stencil.hh:35
void update()
clear previously computed entries such that a re-compute happens when used again
Definition: stencil.hh:137
virtual void setupStencil() const =0
method to setup stencil depending on entity set defined in derived class
const GlobalStencilType & globalStencil() const
Return the full stencil.
Definition: stencil.hh:116
std::set< DomainGlobalKeyType > LocalStencilType
type for storing the stencil of one row
Definition: stencil.hh:51
void fill(const DomainEntityType &dEntity, const RangeEntityType &rEntity, bool fillGhost=true) const
Create stencil entries for (dEntity,rEntity) pair.
Definition: stencil.hh:93
std::vector< std::size_t >::size_type IndexType
type of std::vector for indexing
Definition: stencil.hh:54
int maxNonZerosEstimate() const
Return an upper bound for the maximum number of non-zero entries in all rows.
Definition: stencil.hh:123
Stencil(const DomainSpace &dSpace, const RangeSpace &rSpace)
Constructor.
Definition: stencil.hh:69
const LocalStencilType & localStencil(const RangeGlobalKeyType &key) const
Return stencil for a given row of the matrix.
Definition: stencil.hh:109
Default exception for dummy implementations.
Definition: exceptions.hh:263
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
@ GhostEntity
ghost entities
Definition: gridenums.hh:35
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:238
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:260
Dune namespace.
Definition: alignedallocator.hh:13
Stencil contaning the entries (en,en) and (en,nb) for all entities en in the space and neighbors nb o...
Definition: stencil.hh:387
virtual void setupStencil() const override
method to setup stencil depending on entity set defined in derived class
Definition: stencil.hh:408
Stencil contaning the entries (en,en) for all entities in the space. Defailt for an operator over a L...
Definition: stencil.hh:349
virtual void setupStencil() const override
method to setup stencil depending on entity set defined in derived class
Definition: stencil.hh:368
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)