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 
16 namespace 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  {}
200  SimpleStencil()
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
const LocalStencilType & localStencil(const RangeGlobalKeyType &key) const
Return stencil for a given row of the matrix.
Definition: stencil.hh:109
void update()
clear previously computed entries such that a re-compute happens when used again
Definition: stencil.hh:137
const GlobalStencilType & globalStencil() const
Return the full stencil.
Definition: stencil.hh:116
virtual void setupStencil() const =0
method to setup stencil depending on entity set defined in derived class
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
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
concept Entity
Model of a grid entity.
Definition: entity.hh:107
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
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:259
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:237
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.80.0 (May 16, 22:29, 2024)