Dune Core Modules (2.9.0)

refinement.hh
1 #ifndef DUNE_SPGRID_REFINEMENT_HH
2 #define DUNE_SPGRID_REFINEMENT_HH
3 
4 #include <algorithm>
5 #include <bitset>
6 
7 #include <dune/common/fvector.hh>
8 #include <dune/common/iostream.hh>
9 
10 #include <dune/grid/common/grid.hh>
11 
12 #include <dune/grid/spgrid/declaration.hh>
13 #include <dune/grid/spgrid/misc.hh>
14 #include <dune/grid/spgrid/multiindex.hh>
15 
16 namespace Dune
17 {
18 
19  // SPIsotropicRefinementPolicy
20  // ---------------------------
21 
22  template< int dim >
23  class SPIsotropicRefinementPolicy
24  {
25  typedef SPIsotropicRefinementPolicy< dim > This;
26 
27  public:
28  static const int dimension = dim;
29 
30  unsigned int weight () const
31  {
32  return dimension;
33  }
34 
35  unsigned int factor ( const int i ) const
36  {
37  return 2;
38  }
39 
40  static std::string type () { return "isotropic"; }
41 
42  template< class char_type, class traits >
43  friend std::basic_ostream< char_type, traits > &
44  operator<< ( std::basic_ostream< char_type, traits > &out, const This &policy )
45  {
46  return out << ((1 << dimension)-1);
47  }
48 
49  template< class char_type, class traits >
50  friend std::basic_istream< char_type, traits > &
51  operator>> ( std::basic_istream< char_type, traits > &in, This &policy )
52  {
53  in >> match( (1 << dimension)-1 );
54  return in;
55  }
56  };
57 
58 
59 
60  // SPAnisotropicRefinementPolicy
61  // -----------------------------
62 
63  template< int dim >
64  class SPAnisotropicRefinementPolicy
65  {
66  typedef SPAnisotropicRefinementPolicy< dim > This;
67 
68  friend class SPAnisotropicRefinement< dim >;
69 
70  public:
71  static const int dimension = dim;
72 
73  SPAnisotropicRefinementPolicy ()
74  : refDir_( (1u << dimension) - 1u )
75  {}
76 
77  SPAnisotropicRefinementPolicy ( std::bitset< dimension > refDir )
78  : refDir_( refDir )
79  {}
80 
81  unsigned int weight () const
82  {
83  return refDir_.count();
84  }
85 
86  unsigned int factor ( const int i ) const
87  {
88  assert( (i >= 0) && (i < dimension) );
89  return refDir_[ i ]+1;
90  }
91 
92  static std::string type () { return "anisotropic"; }
93 
94  template< class char_type, class traits >
95  friend std::basic_ostream< char_type, traits > &
96  operator<< ( std::basic_ostream< char_type, traits > &out, const This &policy )
97  {
98  return out << policy.refDir_.to_ulong();
99  }
100 
101  template< class char_type, class traits >
102  friend std::basic_istream< char_type, traits > &
103  operator>> ( std::basic_istream< char_type, traits > &in, This &policy )
104  {
105  unsigned long refDir;
106  in >> refDir;
107  if( !in.fail() )
108  policy.refDir_ = refDir;
109  return in;
110  }
111 
112  private:
113  std::bitset< dimension > refDir_;
114  };
115 
116 
117 
118  // SPBisectionRefinementPolicy
119  // ---------------------------
120 
121  template< int dim >
122  class SPBisectionRefinementPolicy
123  {
124  typedef SPBisectionRefinementPolicy< dim > This;
125 
126  friend class SPBisectionRefinement< dim >;
127 
128  public:
129  static const int dimension = dim;
130 
131  SPBisectionRefinementPolicy ()
132  : dir_( -1 )
133  {}
134 
135  explicit SPBisectionRefinementPolicy ( int dir )
136  : dir_( dir )
137  {
138  if( (dir < 0) || (dir >= dimension) )
139  DUNE_THROW( GridError, "Trying to create bisection refinement policy for invalid direction " << dir << "." );
140  }
141 
142  private:
143  SPBisectionRefinementPolicy ( const This &father, const This &policy )
144  : dir_( policy.dir_ < 0 ? (father.dir_ + 1) % dimension : policy.dir_ )
145  {}
146 
147  public:
148  unsigned int weight () const
149  {
150  return 1;
151  }
152 
153  unsigned int factor ( const int i ) const
154  {
155  assert( (i >= 0) && (i < dimension) );
156  return (i == dir_ ? 2 : 1);
157  }
158 
159  static std::string type () { return "bisection"; }
160 
161  template< class char_type, class traits >
162  friend std::basic_ostream< char_type, traits > &
163  operator<< ( std::basic_ostream< char_type, traits > &out, const This &policy )
164  {
165  assert( (policy.dir_ >= 0) && (policy.dir_ < dimension) );
166  return out << (1u << policy.dir_);
167  }
168 
169  template< class char_type, class traits >
170  friend std::basic_istream< char_type, traits > &
171  operator>> ( std::basic_istream< char_type, traits > &in, This &policy )
172  {
173  unsigned long rd( 0 );
174  in >> rd;
175  std::bitset< dimension > refDir( rd );
176  if( !in.fail() )
177  {
178  if( refDir.count() != 1 )
179  DUNE_THROW( GridError, "Trying to create bisection refinement with multiple refined directions." );
180  for( policy.dir_ = 0; !refDir[ policy.dir_ ]; ++policy.dir_ )
181  continue;
182  }
183  return in;
184  }
185 
186  private:
187  int dir_;
188  };
189 
190 
191 
192  // SPArbitratyRefinementPolicy
193  // ---------------------------
194 
195  template< int dim >
196  class SPArbitraryRefinementPolicy
197  {
198  typedef SPArbitraryRefinementPolicy< dim > This;
199 
200  public:
201  static const int dimension = dim;
202 
203  typedef SPMultiIndex< dimension > MultiIndex;
204 
205  explicit SPArbitraryRefinementPolicy ( int factor = 2 )
206  {
207  if( factor <= 0 )
208  DUNE_THROW( GridError, "Trying to create arbitrary refinement policy with non-positive factor." );
209  for( int i = 0; i < dimension; ++i )
210  factor_[ i ] = factor;
211  }
212 
213  explicit SPArbitraryRefinementPolicy ( const MultiIndex &factor )
214  : factor_( factor )
215  {
216  for( int i = 0; i < dimension; ++i )
217  {
218  if( factor_[ i ] <= 0 )
219  DUNE_THROW( GridError, "Trying to create arbitrary refinement policy with non-positive factor." );
220  }
221  }
222 
223  constexpr unsigned int weight () const { return dimension; }
224 
225  unsigned int factor ( int i ) const { return factor_[ i ]; }
226 
227  static std::string type () { return "arbitrary"; }
228 
229  template< class char_type, class traits >
230  friend std::basic_ostream< char_type, traits > &
231  operator<< ( std::basic_ostream< char_type, traits > &out, const This &policy )
232  {
233  return out << policy.factor_;
234  }
235 
236  template< class char_type, class traits >
237  friend std::basic_istream< char_type, traits > &
238  operator>> ( std::basic_istream< char_type, traits > &in, This &policy )
239  {
240  return in >> policy.factor_;
241  }
242 
243  private:
244  MultiIndex factor_;
245  };
246 
247 
248 
249  // SPDefaultRefinement
250  // -------------------
251 
252  template< class P >
253  class SPDefaultRefinement
254  {
255  typedef SPDefaultRefinement< P > This;
256 
257  public:
258  typedef P Policy;
259 
260  static const int dimension = Policy::dimension;
261 
262  typedef SPMultiIndex< dimension > MultiIndex;
263 
264  explicit SPDefaultRefinement ( const Policy &policy = Policy() ) : policy_( policy ) {}
265 
266  SPDefaultRefinement ( const This &father, const Policy &policy ) : policy_( policy ) {}
267 
268  static std::string type () { return Policy::type(); }
269 
270  unsigned int factor ( int i ) const { return policy().factor( i ); }
271 
272  unsigned int numChildren () const
273  {
274  unsigned int numChildren = 1;
275  for( int i = 0; i < dimension; ++i )
276  numChildren *= factor( i );
277  return numChildren;
278  }
279 
280  void father ( MultiIndex &id ) const
281  {
282  for( int i = 0; i < dimension; ++i )
283  id[ i ] = (id[ i ] / factor( i )) | (id[ i ] & 1);
284  }
285 
286  bool hasFather ( const MultiIndex &id ) const
287  {
288  bool hasFather = true;
289  for( int i = 0; i < dimension; ++i )
290  hasFather &= (id[ i ] & 1) | ((id[ i ] % (2*factor( i ))) == 0);
291  return hasFather;
292  }
293 
294  void child ( MultiIndex &id, unsigned int index ) const
295  {
296  assert( index < numChildren() );
297  for( int i = 0; i < dimension; ++i )
298  {
299  const unsigned int alpha = factor( i );
300  id[ i ] = ((id[ i ] + (index % alpha)) * alpha) - (alpha - 1);
301  index /= alpha;
302  }
303  }
304 
305  unsigned int childIndex ( const MultiIndex &id ) const
306  {
307  unsigned int index = 0;
308  for( int i = dimension-1; i >= 0; --i )
309  {
310  const unsigned int alpha = factor( i );
311  index = (index * alpha) + ((id[ i ] >> 1) % alpha);
312  }
313  assert( index < numChildren() );
314  return index;
315  }
316 
317  void firstChild ( MultiIndex &id ) const
318  {
319  for( int i = 0; i < dimension; ++i )
320  id[ i ] = (factor( i ) * (id[ i ] & ~1)) | (id[ i ] & 1);
321  }
322 
323  bool nextChild ( MultiIndex &id ) const
324  {
325  for( int i = 0; i < dimension; ++i )
326  {
327  const unsigned int alpha = factor( i );
328  const int step = 2*(id[ i ] & 1);
329  id[ i ] += step;
330  if( ((id[ i ] % (2*alpha)) & ~1) != 0 )
331  return true;
332  id[ i ] -= alpha*step;
333  }
334  return false;
335  }
336 
337  bool isCopy ( const MultiIndex id ) const
338  {
339  bool copy = true;
340  for( int i = 0; i < dimension; ++i )
341  {
342  const unsigned int alpha = factor( i );
343  copy &= (alpha == 1) | ((id[ i ] % (2*alpha)) == 0);
344  }
345  return copy;
346  }
347 
348  template< class ctype >
349  FieldVector< ctype, dimension > hInFather () const
350  {
352  for( int i = 0; i < dimension; ++i )
353  h[ i ] = ctype( 1 ) / ctype( factor( i ) );
354  return h;
355  }
356 
357  template< class ctype >
358  FieldVector< ctype, dimension > originInFather ( unsigned int index ) const
359  {
361  for( int i = 0; i < dimension; ++i )
362  {
363  const unsigned int alpha = factor( i );
364  origin[ i ] = ctype( index % alpha ) / ctype( alpha );
365  index /= alpha;
366  }
367  return origin;
368  }
369 
370  const Policy &policy () const { return policy_; }
371 
372  private:
373  Policy policy_;
374  };
375 
376 
377 
378  // SPBinaryRefinement
379  // ------------------
380 
381  template< class P >
382  class SPBinaryRefinement
383  : public SPDefaultRefinement< P >
384  {
385  typedef SPBinaryRefinement< P > This;
386  typedef SPDefaultRefinement< P > Base;
387 
388  public:
389  using Base::dimension;
390 
391  typedef typename Base::Policy Policy;
392  typedef typename Base::MultiIndex MultiIndex;
393 
394  explicit SPBinaryRefinement ( const Policy &policy = Policy() ) : Base ( policy ) {}
395 
396  SPBinaryRefinement ( const This &father, const Policy &policy ) : Base( father, policy ) {}
397 
398  using Base::factor;
399 
400  bool hasFather ( const MultiIndex &id ) const
401  {
402  bool hasFather = true;
403  for( int i = 0; i < dimension; ++i )
404  hasFather &= ((id[ i ] & 3) != 2);
405  return hasFather;
406  }
407 
408  void firstChild ( MultiIndex &id ) const
409  {
410  for( int i = 0; i < dimension; ++i )
411  {
412  const unsigned int alpha = factor( i );
413  id[ i ] = alpha*id[ i ] - (alpha / 2)*(id[ i ] & 1);
414  }
415  }
416 
417  bool nextChild ( MultiIndex &id ) const
418  {
419  for( int i = 0; i < dimension; ++i )
420  {
421  if( factor( i ) < 2 )
422  continue;
423  id[ i ] ^= 2*(id[ i ] & 1);
424  if( (id[ i ] & 2) != 0 )
425  return true;
426  }
427  return false;
428  }
429 
430  bool isCopy ( const MultiIndex id ) const
431  {
432  bool copy = true;
433  for( int i = 0; i < dimension; ++i )
434  copy &= (factor( i ) == 1) | ((id[ i ] & 3) == 0);
435  return copy;
436  }
437  };
438 
439 
440 
441  // SPIsotropicRefinement
442  // ---------------------
443 
450  template< int dim >
452  : public SPBinaryRefinement< SPIsotropicRefinementPolicy< dim > >
453  {
454  typedef SPIsotropicRefinement< dim > This;
455  typedef SPBinaryRefinement< SPIsotropicRefinementPolicy< dim > > Base;
456 
457  public:
458  using Base::dimension;
459 
460  typedef typename Base::Policy Policy;
461 
462  SPIsotropicRefinement () : Base( Policy() ) {}
463 
464  explicit SPIsotropicRefinement ( const This &father, const Policy &policy ) : Base( policy ) {}
465 
466  constexpr unsigned int numChildren () const { return (1 << dimension); }
467  };
468 
469 
470 
471  // SPAnisotropicRefinement
472  // -----------------------
473 
480  template< int dim >
482  : public SPBinaryRefinement< SPAnisotropicRefinementPolicy< dim > >
483  {
484  typedef SPAnisotropicRefinement< dim > This;
485  typedef SPBinaryRefinement< SPAnisotropicRefinementPolicy< dim > > Base;
486 
487  public:
488  using Base::dimension;
489 
490  typedef typename Base::Policy Policy;
491 
492  SPAnisotropicRefinement () : Base( Policy() ) {}
493 
494  explicit SPAnisotropicRefinement ( const This &father, const Policy &policy ) : Base( policy ) {}
495 
496  using Base::policy;
497 
498  unsigned int numChildren () const { return (1u << policy().refDir_.count()); }
499  };
500 
501 
502 
503  // SPBisectionRefinement
504  // ---------------------
505 
514  template< int dim >
516  : public SPDefaultRefinement< SPBisectionRefinementPolicy< dim > >
517  {
518  typedef SPBisectionRefinement< dim > This;
519  typedef SPDefaultRefinement< SPBisectionRefinementPolicy< dim > > Base;
520 
521  public:
522  using Base::dimension;
523 
524  typedef typename Base::MultiIndex MultiIndex;
525  typedef typename Base::Policy Policy;
526 
527  SPBisectionRefinement () : Base( Policy() ) {}
528 
529  SPBisectionRefinement ( const This &father, const Policy &policy )
530  : Base( Policy( father.policy(), policy ) )
531  {}
532 
533  using Base::policy;
534 
535  unsigned int numChildren () const
536  {
537  return 2;
538  }
539 
540  void father ( MultiIndex &id ) const
541  {
542  const int dir = policy().dir_;
543  assert( dir >= 0 );
544  id[ dir ] = (id[ dir ] / 2) | (id[ dir ] & 1);
545  }
546 
547  bool hasFather ( const MultiIndex &id ) const
548  {
549  const int dir = policy().dir_;
550  assert( dir >= 0 );
551  return ((id[ dir ] & 3) != 2);
552  }
553 
554  void child ( MultiIndex &id, unsigned int index ) const
555  {
556  assert( index < numChildren() );
557  const int dir = policy().dir_;
558  assert( dir >= 0 );
559  id[ dir ] = 2*(id[ dir ] + index) - 1;
560  }
561 
562  unsigned int childIndex ( const MultiIndex &id ) const
563  {
564  const int dir = policy().dir_;
565  assert( dir >= 0 );
566  const unsigned int index = (id[ dir ] >> 1) % 2;
567  assert( index < numChildren() );
568  return index;
569  }
570 
571  void firstChild ( MultiIndex &id ) const
572  {
573  const int dir = policy().dir_;
574  assert( dir >= 0 );
575  id[ dir ] = 2*id[ dir ] - (id[ dir ] & 1);
576  }
577 
578  bool nextChild ( MultiIndex &id ) const
579  {
580  const int dir = policy().dir_;
581  assert( dir >= 0 );
582  id[ dir ] ^= 2*(id[ dir ] & 1);
583  return ((id[ dir ] & 2) != 0);
584  }
585 
586  bool isCopy ( const MultiIndex id ) const
587  {
588  const int dir = policy().dir_;
589  assert( dir >= 0 );
590  return ((id[ dir ] & 3) == 0);
591  }
592  };
593 
594 
595 
596  // SPArbitratyRefinement
597  // ---------------------
598 
599  template< int dim >
600  class SPArbitraryRefinement
601  : public SPDefaultRefinement< SPArbitraryRefinementPolicy< dim > >
602  {
603  typedef SPArbitraryRefinement< dim > This;
604  typedef SPDefaultRefinement< SPArbitraryRefinementPolicy< dim > > Base;
605 
606  public:
607  typedef typename Base::Policy Policy;
608 
609  SPArbitraryRefinement () : Base( Policy() ) {}
610 
611  explicit SPArbitraryRefinement ( const This &father, const Policy &policy ) : Base( policy ) {}
612  };
613 
614 } // namespace Dune
615 
616 #endif // #ifndef DUNE_SPGRID_REFINEMENT_HH
the user may choose freely along which axes the grid should be refined
Definition: refinement.hh:483
each element is split into 2 children.
Definition: refinement.hh:517
each element is split into 2dim children.
Definition: refinement.hh:453
Different resources needed by all grid implementations.
miscellaneous helper functions
Implements a vector constructed from a given type representing a field and a compile-time given size.
Stream & operator>>(Stream &stream, std::tuple< Ts... > &t)
Read a std::tuple.
Definition: streamoperators.hh:43
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
ImplementationDefined child(Node &&node, Indices... indices)
Extracts the child of a node given by a sequence of compile-time and run-time indices.
Definition: childextraction.hh:126
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 30, 22:37, 2024)