dune-localfunctions  2.11
raviartthomassimplexinterpolation.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 // SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
6 #define DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
7 
8 #include <fstream>
9 #include <utility>
10 
11 #include <dune/common/exceptions.hh>
12 
13 #include <dune/geometry/quadraturerules.hh>
14 #include <dune/geometry/referenceelements.hh>
15 #include <dune/geometry/type.hh>
16 #include <dune/geometry/typeindex.hh>
17 
22 
23 namespace Dune
24 {
25 
26  // Internal Forward Declarations
27  // -----------------------------
28 
29  template < unsigned int dim, class Field >
31 
32 
33 
34  // LocalCoefficientsContainer
35  // --------------------------
36 
38  {
39  typedef LocalCoefficientsContainer This;
40 
41  public:
42  template <class Setter>
43  LocalCoefficientsContainer ( const Setter &setter )
44  {
45  setter.setLocalKeys(localKey_);
46  }
47 
48  const LocalKey &localKey ( const unsigned int i ) const
49  {
50  assert( i < size() );
51  return localKey_[ i ];
52  }
53 
54  std::size_t size () const
55  {
56  return localKey_.size();
57  }
58 
59  private:
60  std::vector< LocalKey > localKey_;
61  };
62 
63 
64 
65  // RaviartThomasCoefficientsFactory
66  // --------------------------------
67 
68  template < unsigned int dim >
70  {
71  typedef std::size_t Key;
73 
74  template< GeometryType::Id geometryId >
75  static Object *create( const Key &key )
76  {
77  typedef RaviartThomasL2InterpolationFactory< dim, double > InterpolationFactory;
78  if( !supports< geometryId >( key ) )
79  return nullptr;
80  typename InterpolationFactory::Object *interpolation = InterpolationFactory::template create< geometryId >( key );
81  Object *localKeys = new Object( *interpolation );
82  InterpolationFactory::release( interpolation );
83  return localKeys;
84  }
85 
86  template< GeometryType::Id geometryId >
87  static bool supports ( const Key &key )
88  {
89  return GeometryType(geometryId).isSimplex();
90  }
91  static void release( Object *object ) { delete object; }
92  };
93 
94 
95 
96  // RTL2InterpolationBuilder
97  // ------------------------
98 
99  // L2 Interpolation requires:
100  // - for element
101  // - test basis
102  // - for each face (dynamic)
103  // - test basis
104  // - normal
105  template< unsigned int dim, class Field >
107  {
108  static const unsigned int dimension = dim;
109 // for the dofs associated to the element
112 
113  // for the dofs associated to the faces
114  typedef OrthonormalBasisFactory< dimension-1, Field, Field, Field > TestFaceBasisFactory;
116 
117  // the normals of the faces
118  typedef FieldVector< Field, dimension > Normal;
119 
120  RTL2InterpolationBuilder () = default;
121 
124 
126  {
127  TestBasisFactory::release( testBasis_ );
128  for( FaceStructure &f : faceStructure_ )
129  TestFaceBasisFactory::release( f.basis_ );
130  }
131 
132  GeometryType type () const { return geometry_; }
133 
134  std::size_t order () const { return order_; }
135 
136  // number of faces
137  unsigned int faceSize () const { return faceSize_; }
138 
139  // basis associated to the element
140  TestBasis *testBasis () const { return testBasis_; }
141 
142  // basis associated to face f
143  TestFaceBasis *testFaceBasis ( unsigned int f ) const { assert( f < faceSize() ); return faceStructure_[ f ].basis_; }
144 
145  // normal of face f
146  const Normal normal ( unsigned int f ) const { assert( f < faceSize() ); return faceStructure_[ f ].normal_; }
147 
148  template< GeometryType::Id geometryId >
149  void build ( std::size_t order )
150  {
151  constexpr GeometryType geometry = geometryId;
152  geometry_ = geometry;
153  order_ = order;
154 
155  testBasis_ = (order > 0 ? TestBasisFactory::template create< geometry >( order-1 ) : nullptr);
156 
157  const auto &refElement = ReferenceElements< Field, dimension >::general( type() );
158  faceSize_ = refElement.size( 1 );
159  faceStructure_.reserve( faceSize_ );
160  for( unsigned int face = 0; face < faceSize_; ++face )
161  {
162  /* For simplices or cubes of arbitrary dimension you could just use
163  *
164  * ```
165  * GeometryType faceGeometry = Impl::getBase(geometry_);
166  * TestFaceBasis *faceBasis = TestFaceBasisFactory::template create< faceGeometry >( order );
167  * ```
168  *
169  * For i.e. Prisms and Pyramids in 3d this does not work because they contain squares and triangles as faces.
170  * And depending on the dynamic face index a different face geometry is needed.
171  *
172  */
173  TestFaceBasis *faceBasis = Impl::toGeometryTypeIdConstant<dimension-1>(refElement.type( face, 1 ), [&](auto faceGeometryTypeId) {
174  return TestFaceBasisFactory::template create< decltype(faceGeometryTypeId)::value >( order );
175  });
176  faceStructure_.emplace_back( faceBasis, refElement.integrationOuterNormal( face ) );
177  }
178  assert( faceStructure_.size() == faceSize_ );
179  }
180 
181  private:
182  struct FaceStructure
183  {
184  FaceStructure( TestFaceBasis *tfb, const Normal n )
185  : basis_( tfb ), normal_( n )
186  {}
187 
188  TestFaceBasis *basis_;
189  const Dune::FieldVector< Field, dimension > normal_;
190  };
191 
192  std::vector< FaceStructure > faceStructure_;
193  TestBasis *testBasis_ = nullptr;
194  GeometryType geometry_;
195  unsigned int faceSize_;
196  std::size_t order_;
197  };
198 
199 
200 
201  // RaviartThomasL2Interpolation
202  // ----------------------------
203 
209  template< unsigned int dimension, class F>
211  : public InterpolationHelper< F ,dimension >
212  {
215 
216  public:
217  typedef F Field;
220  : order_(0),
221  size_(0)
222  {}
223 
224  template< class Function, class Vector,
225  decltype(std::declval<Vector>().size(),bool{}) = true,
226  decltype(std::declval<Vector>().resize(0u),bool{}) = true>
227  void interpolate ( const Function &function, Vector &coefficients ) const
228  {
229  coefficients.resize(size());
230  typename Base::template Helper<Function,Vector,true> func( function,coefficients );
231  interpolate(func);
232  }
233 
234  template< class Basis, class Matrix,
235  decltype(std::declval<Matrix>().rows(),bool{}) = true,
236  decltype(std::declval<Matrix>().cols(),bool{}) = true,
237  decltype(std::declval<Matrix>().resize(0u,0u),bool{}) = true>
238  void interpolate ( const Basis &basis, Matrix &matrix ) const
239  {
240  matrix.resize( size(), basis.size() );
241  typename Base::template Helper<Basis,Matrix,false> func( basis,matrix );
242  interpolate(func);
243  }
244 
245  std::size_t order() const
246  {
247  return order_;
248  }
249  std::size_t size() const
250  {
251  return size_;
252  }
253  template <GeometryType::Id geometryId>
254  void build( std::size_t order )
255  {
256  size_ = 0;
257  order_ = order;
258  builder_.template build<geometryId>(order_);
259  if (builder_.testBasis())
260  size_ += dimension*builder_.testBasis()->size();
261  for ( unsigned int f=0; f<builder_.faceSize(); ++f )
262  if (builder_.testFaceBasis(f))
263  size_ += builder_.testFaceBasis(f)->size();
264  }
265 
266  void setLocalKeys(std::vector< LocalKey > &keys) const
267  {
268  keys.resize(size());
269  unsigned int row = 0;
270  for (unsigned int f=0; f<builder_.faceSize(); ++f)
271  {
272  if (builder_.faceSize())
273  for (unsigned int i=0; i<builder_.testFaceBasis(f)->size(); ++i,++row)
274  keys[row] = LocalKey(f,1,i);
275  }
276  if (builder_.testBasis())
277  for (unsigned int i=0; i<builder_.testBasis()->size()*dimension; ++i,++row)
278  keys[row] = LocalKey(0,0,i);
279  assert( row == size() );
280  }
281 
282  protected:
283  template< class Func, class Container, bool type >
284  void interpolate ( typename Base::template Helper<Func,Container,type> &func ) const
285  {
286  const Dune::GeometryType geoType = builder_.type();
287 
288  std::vector< Field > testBasisVal;
289 
290  for (unsigned int i=0; i<size(); ++i)
291  for (unsigned int j=0; j<func.size(); ++j)
292  func.set(i,j,0);
293 
294  unsigned int row = 0;
295 
296  // boundary dofs:
297  typedef Dune::QuadratureRule<Field, dimension-1> FaceQuadrature;
298  typedef Dune::QuadratureRules<Field, dimension-1> FaceQuadratureRules;
299 
300  const auto &refElement = Dune::ReferenceElements< Field, dimension >::general( geoType );
301 
302  for (unsigned int f=0; f<builder_.faceSize(); ++f)
303  {
304  if (!builder_.testFaceBasis(f))
305  continue;
306  testBasisVal.resize(builder_.testFaceBasis(f)->size());
307 
308  const auto &geometry = refElement.template geometry< 1 >( f );
309  const Dune::GeometryType subGeoType( geometry.type().id(), dimension-1 );
310  const FaceQuadrature &faceQuad = FaceQuadratureRules::rule( subGeoType, 2*order_+2 );
311 
312  const unsigned int quadratureSize = faceQuad.size();
313  for( unsigned int qi = 0; qi < quadratureSize; ++qi )
314  {
315  if (dimension>1)
316  builder_.testFaceBasis(f)->template evaluate<0>(faceQuad[qi].position(),testBasisVal);
317  else
318  testBasisVal[0] = 1.;
319  fillBnd( row, testBasisVal,
320  func.evaluate( geometry.global( faceQuad[qi].position() ) ),
321  builder_.normal(f), faceQuad[qi].weight(),
322  func);
323  }
324 
325  row += builder_.testFaceBasis(f)->size();
326  }
327  // element dofs
328  if (builder_.testBasis())
329  {
330  testBasisVal.resize(builder_.testBasis()->size());
331 
332  typedef Dune::QuadratureRule<Field, dimension> Quadrature;
333  typedef Dune::QuadratureRules<Field, dimension> QuadratureRules;
334  const Quadrature &elemQuad = QuadratureRules::rule( geoType, 2*order_+1 );
335 
336  const unsigned int quadratureSize = elemQuad.size();
337  for( unsigned int qi = 0; qi < quadratureSize; ++qi )
338  {
339  builder_.testBasis()->template evaluate<0>(elemQuad[qi].position(),testBasisVal);
340  fillInterior( row, testBasisVal,
341  func.evaluate(elemQuad[qi].position()),
342  elemQuad[qi].weight(),
343  func );
344  }
345 
346  row += builder_.testBasis()->size()*dimension;
347  }
348  assert(row==size());
349  }
350 
351  private:
361  template <class MVal, class RTVal,class Matrix>
362  void fillBnd (unsigned int startRow,
363  const MVal &mVal,
364  const RTVal &rtVal,
365  const FieldVector<Field,dimension> &normal,
366  const Field &weight,
367  Matrix &matrix) const
368  {
369  const unsigned int endRow = startRow+mVal.size();
370  typename RTVal::const_iterator rtiter = rtVal.begin();
371  for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
372  {
373  Field cFactor = (*rtiter)*normal;
374  typename MVal::const_iterator miter = mVal.begin();
375  for (unsigned int row = startRow;
376  row!=endRow; ++miter, ++row )
377  {
378  matrix.add(row,col, (weight*cFactor)*(*miter) );
379  }
380  assert( miter == mVal.end() );
381  }
382  }
391  template <class MVal, class RTVal,class Matrix>
392  void fillInterior (unsigned int startRow,
393  const MVal &mVal,
394  const RTVal &rtVal,
395  Field weight,
396  Matrix &matrix) const
397  {
398  const unsigned int endRow = startRow+mVal.size()*dimension;
399  typename RTVal::const_iterator rtiter = rtVal.begin();
400  for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
401  {
402  typename MVal::const_iterator miter = mVal.begin();
403  for (unsigned int row = startRow;
404  row!=endRow; ++miter,row+=dimension )
405  {
406  for (unsigned int i=0; i<dimension; ++i)
407  {
408  matrix.add(row+i,col, (weight*(*miter))*(*rtiter)[i] );
409  }
410  }
411  assert( miter == mVal.end() );
412  }
413  }
414 
415  Builder builder_;
416  std::size_t order_;
417  std::size_t size_;
418  };
419 
420  template < unsigned int dim, class Field >
421  struct RaviartThomasL2InterpolationFactory
422  {
425  typedef std::size_t Key;
426  typedef typename std::remove_const<Object>::type NonConstObject;
427 
428  template <GeometryType::Id geometryId>
429  static Object *create( const Key &key )
430  {
431  if ( !supports<geometryId>(key) )
432  return 0;
433  NonConstObject *interpol = new NonConstObject();
434  interpol->template build<geometryId>(key);
435  return interpol;
436  }
437  template< GeometryType::Id geometryId >
438  static bool supports ( const Key &key )
439  {
440  return GeometryType(geometryId).isSimplex();
441  }
442  static void release( Object *object ) { delete object; }
443  };
444 
445 } // namespace Dune
446 
447 #endif // #ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
TestBasisFactory::Object TestBasis
Definition: raviartthomassimplexinterpolation.hh:111
LocalCoefficientsContainer(const Setter &setter)
Definition: raviartthomassimplexinterpolation.hh:43
Definition: polynomialbasis.hh:62
std::size_t Key
Definition: raviartthomassimplexinterpolation.hh:71
TestBasis * testBasis() const
Definition: raviartthomassimplexinterpolation.hh:140
std::size_t size() const
Definition: nedelecsimplexinterpolation.hh:57
OrthonormalBasisFactory< dimension, Field, Field, Field > TestBasisFactory
Definition: raviartthomassimplexinterpolation.hh:110
static void release(Object *object)
Definition: raviartthomassimplexinterpolation.hh:442
Definition: raviartthomassimplexinterpolation.hh:69
static Object * create(const Key &key)
Definition: raviartthomassimplexinterpolation.hh:75
static bool supports(const Key &key)
Definition: raviartthomassimplexinterpolation.hh:438
static Object * create(const Key &key)
Definition: raviartthomassimplexinterpolation.hh:429
static void release(Object *object)
Definition: raviartthomassimplexinterpolation.hh:91
std::size_t Key
Definition: raviartthomassimplexinterpolation.hh:425
F Field
Definition: raviartthomassimplexinterpolation.hh:217
void interpolate(typename Base::template Helper< Func, Container, type > &func) const
Definition: raviartthomassimplexinterpolation.hh:284
Describe position of one degree of freedom.
Definition: localkey.hh:23
OrthonormalBasisFactory< dimension-1, Field, Field, Field > TestFaceBasisFactory
Definition: raviartthomassimplexinterpolation.hh:114
Definition: raviartthomassimplexinterpolation.hh:30
RTL2InterpolationBuilder< dimension, Field > Builder
Definition: raviartthomassimplexinterpolation.hh:218
void build(std::size_t order)
Definition: raviartthomassimplexinterpolation.hh:149
void interpolate(const Function &function, Vector &coefficients) const
Definition: raviartthomassimplexinterpolation.hh:227
GeometryType type() const
Definition: raviartthomassimplexinterpolation.hh:132
const LocalKey & localKey(const unsigned int i) const
Definition: raviartthomassimplexinterpolation.hh:48
Definition: bdfmcube.hh:17
Definition: interpolationhelper.hh:23
const LocalCoefficientsContainer Object
Definition: raviartthomassimplexinterpolation.hh:72
Definition: nedelecsimplexinterpolation.hh:40
RaviartThomasL2Interpolation()
Definition: raviartthomassimplexinterpolation.hh:219
std::size_t order() const
Definition: raviartthomassimplexinterpolation.hh:134
const RaviartThomasL2Interpolation< dim, Field > Object
Definition: raviartthomassimplexinterpolation.hh:424
unsigned int size() const
Definition: polynomialbasis.hh:111
TestFaceBasisFactory::Object TestFaceBasis
Definition: raviartthomassimplexinterpolation.hh:115
void setLocalKeys(std::vector< LocalKey > &keys) const
Definition: raviartthomassimplexinterpolation.hh:266
const Normal normal(unsigned int f) const
Definition: raviartthomassimplexinterpolation.hh:146
static bool supports(const Key &key)
Definition: raviartthomassimplexinterpolation.hh:87
unsigned int faceSize() const
Definition: raviartthomassimplexinterpolation.hh:137
static const unsigned int dimension
Definition: raviartthomassimplexinterpolation.hh:108
FieldVector< Field, dimension > Normal
Definition: raviartthomassimplexinterpolation.hh:118
std::size_t order() const
Definition: raviartthomassimplexinterpolation.hh:245
std::remove_const< Object >::type NonConstObject
Definition: raviartthomassimplexinterpolation.hh:426
Definition: raviartthomassimplexinterpolation.hh:106
Definition: orthonormalbasis.hh:19
~RTL2InterpolationBuilder()
Definition: raviartthomassimplexinterpolation.hh:125
void build(std::size_t order)
Definition: raviartthomassimplexinterpolation.hh:254
std::size_t size() const
Definition: raviartthomassimplexinterpolation.hh:249
Definition: interpolationhelper.hh:20
An L2-based interpolation for Raviart Thomas.
Definition: raviartthomassimplexinterpolation.hh:210
RTL2InterpolationBuilder< dim, Field > Builder
Definition: raviartthomassimplexinterpolation.hh:423
TestFaceBasis * testFaceBasis(unsigned int f) const
Definition: raviartthomassimplexinterpolation.hh:143
static void release(Object *object)
Definition: orthonormalbasis.hh:59