dune-localfunctions 2.9.1
Loading...
Searching...
No Matches
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 (C) 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
23namespace Dune
24{
25
26 // Internal Forward Declarations
27 // -----------------------------
28
29 template < unsigned int dim, class Field >
30 struct RaviartThomasL2InterpolationFactory;
31
32
33
34 // LocalCoefficientsContainer
35 // --------------------------
36
37 class LocalCoefficientsContainer
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
110 // for the dofs associated to the element
113
114 // for the dofs associated to the faces
117
118 // the normals of the faces
119 typedef FieldVector< Field, dimension > Normal;
120
122
125
127 {
128 TestBasisFactory::release( testBasis_ );
129 for( FaceStructure &f : faceStructure_ )
131 }
132
133 GeometryType type () const { return geometry_; }
134
135 std::size_t order () const { return order_; }
136
137 // number of faces
138 unsigned int faceSize () const { return faceSize_; }
139
140 // basis associated to the element
141 TestBasis *testBasis () const { return testBasis_; }
142
143 // basis associated to face f
144 TestFaceBasis *testFaceBasis ( unsigned int f ) const { assert( f < faceSize() ); return faceStructure_[ f ].basis_; }
145
146 // normal of face f
147 const Normal &normal ( unsigned int f ) const { assert( f < faceSize() ); return *(faceStructure_[ f ].normal_); }
148
149 template< GeometryType::Id geometryId >
150 void build ( std::size_t order )
151 {
152 constexpr GeometryType geometry = geometryId;
153 geometry_ = geometry;
154 order_ = order;
155
156 testBasis_ = (order > 0 ? TestBasisFactory::template create< geometry >( order-1 ) : nullptr);
157
158 const auto &refElement = ReferenceElements< Field, dimension >::general( type() );
159 faceSize_ = refElement.size( 1 );
160 faceStructure_.reserve( faceSize_ );
161 for( unsigned int face = 0; face < faceSize_; ++face )
162 {
163 /* For simplices or cubes of arbitrary dimension you could just use
164 *
165 * ```
166 * GeometryType faceGeometry = Impl::getBase(geometry_);
167 * TestFaceBasis *faceBasis = TestFaceBasisFactory::template create< faceGeometry >( order );
168 * ```
169 *
170 * For i.e. Prisms and Pyramids in 3d this does not work because they contain squares and triangles as faces.
171 * And depending on the dynamic face index a different face geometry is needed.
172 *
173 */
174 TestFaceBasis *faceBasis = Impl::toGeometryTypeIdConstant<dimension-1>(refElement.type( face, 1 ), [&](auto faceGeometryTypeId) {
175 return TestFaceBasisFactory::template create< decltype(faceGeometryTypeId)::value >( order );
176 });
177 faceStructure_.emplace_back( faceBasis, refElement.integrationOuterNormal( face ) );
178 }
179 assert( faceStructure_.size() == faceSize_ );
180 }
181
182 private:
183 struct FaceStructure
184 {
185 FaceStructure( TestFaceBasis *tfb, const Normal &n )
186 : basis_( tfb ), normal_( &n )
187 {}
188
189 TestFaceBasis *basis_;
190 const Dune::FieldVector< Field, dimension > *normal_;
191 };
192
193 std::vector< FaceStructure > faceStructure_;
194 TestBasis *testBasis_ = nullptr;
195 GeometryType geometry_;
196 unsigned int faceSize_;
197 std::size_t order_;
198 };
199
200
201
202 // RaviartThomasL2Interpolation
203 // ----------------------------
204
210 template< unsigned int dimension, class F>
212 : public InterpolationHelper< F ,dimension >
213 {
216
217 public:
218 typedef F Field;
221 : order_(0),
222 size_(0)
223 {}
224
225 template< class Function, class Vector >
226 auto interpolate ( const Function &function, Vector &coefficients ) const
227 -> std::enable_if_t< std::is_same< decltype(std::declval<Vector>().resize(1) ),void >::value,void>
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 auto interpolate ( const Basis &basis, Matrix &matrix ) const
236 -> std::enable_if_t< std::is_same<
237 decltype(std::declval<Matrix>().rowPtr(0)), typename Matrix::Field* >::value,void>
238 {
239 matrix.resize( size(), basis.size() );
240 typename Base::template Helper<Basis,Matrix,false> func( basis,matrix );
241 interpolate(func);
242 }
243
244 std::size_t order() const
245 {
246 return order_;
247 }
248 std::size_t size() const
249 {
250 return size_;
251 }
252 template <GeometryType::Id geometryId>
253 void build( std::size_t order )
254 {
255 size_ = 0;
256 order_ = order;
257 builder_.template build<geometryId>(order_);
258 if (builder_.testBasis())
259 size_ += dimension*builder_.testBasis()->size();
260 for ( unsigned int f=0; f<builder_.faceSize(); ++f )
261 if (builder_.testFaceBasis(f))
262 size_ += builder_.testFaceBasis(f)->size();
263 }
264
265 void setLocalKeys(std::vector< LocalKey > &keys) const
266 {
267 keys.resize(size());
268 unsigned int row = 0;
269 for (unsigned int f=0; f<builder_.faceSize(); ++f)
270 {
271 if (builder_.faceSize())
272 for (unsigned int i=0; i<builder_.testFaceBasis(f)->size(); ++i,++row)
273 keys[row] = LocalKey(f,1,i);
274 }
275 if (builder_.testBasis())
276 for (unsigned int i=0; i<builder_.testBasis()->size()*dimension; ++i,++row)
277 keys[row] = LocalKey(0,0,i);
278 assert( row == size() );
279 }
280
281 protected:
282 template< class Func, class Container, bool type >
283 void interpolate ( typename Base::template Helper<Func,Container,type> &func ) const
284 {
285 const Dune::GeometryType geoType = builder_.type();
286
287 std::vector< Field > testBasisVal;
288
289 for (unsigned int i=0; i<size(); ++i)
290 for (unsigned int j=0; j<func.size(); ++j)
291 func.set(i,j,0);
292
293 unsigned int row = 0;
294
295 // boundary dofs:
296 typedef Dune::QuadratureRule<Field, dimension-1> FaceQuadrature;
297 typedef Dune::QuadratureRules<Field, dimension-1> FaceQuadratureRules;
298
299 const auto &refElement = Dune::ReferenceElements< Field, dimension >::general( geoType );
300
301 for (unsigned int f=0; f<builder_.faceSize(); ++f)
302 {
303 if (!builder_.testFaceBasis(f))
304 continue;
305 testBasisVal.resize(builder_.testFaceBasis(f)->size());
306
307 const auto &geometry = refElement.template geometry< 1 >( f );
308 const Dune::GeometryType subGeoType( geometry.type().id(), dimension-1 );
309 const FaceQuadrature &faceQuad = FaceQuadratureRules::rule( subGeoType, 2*order_+2 );
310
311 const unsigned int quadratureSize = faceQuad.size();
312 for( unsigned int qi = 0; qi < quadratureSize; ++qi )
313 {
314 if (dimension>1)
315 builder_.testFaceBasis(f)->template evaluate<0>(faceQuad[qi].position(),testBasisVal);
316 else
317 testBasisVal[0] = 1.;
318 fillBnd( row, testBasisVal,
319 func.evaluate( geometry.global( faceQuad[qi].position() ) ),
320 builder_.normal(f), faceQuad[qi].weight(),
321 func);
322 }
323
324 row += builder_.testFaceBasis(f)->size();
325 }
326 // element dofs
327 if (builder_.testBasis())
328 {
329 testBasisVal.resize(builder_.testBasis()->size());
330
331 typedef Dune::QuadratureRule<Field, dimension> Quadrature;
332 typedef Dune::QuadratureRules<Field, dimension> QuadratureRules;
333 const Quadrature &elemQuad = QuadratureRules::rule( geoType, 2*order_+1 );
334
335 const unsigned int quadratureSize = elemQuad.size();
336 for( unsigned int qi = 0; qi < quadratureSize; ++qi )
337 {
338 builder_.testBasis()->template evaluate<0>(elemQuad[qi].position(),testBasisVal);
339 fillInterior( row, testBasisVal,
340 func.evaluate(elemQuad[qi].position()),
341 elemQuad[qi].weight(),
342 func );
343 }
344
345 row += builder_.testBasis()->size()*dimension;
346 }
347 assert(row==size());
348 }
349
350 private:
360 template <class MVal, class RTVal,class Matrix>
361 void fillBnd (unsigned int startRow,
362 const MVal &mVal,
363 const RTVal &rtVal,
364 const FieldVector<Field,dimension> &normal,
365 const Field &weight,
366 Matrix &matrix) const
367 {
368 const unsigned int endRow = startRow+mVal.size();
369 typename RTVal::const_iterator rtiter = rtVal.begin();
370 for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
371 {
372 Field cFactor = (*rtiter)*normal;
373 typename MVal::const_iterator miter = mVal.begin();
374 for (unsigned int row = startRow;
375 row!=endRow; ++miter, ++row )
376 {
377 matrix.add(row,col, (weight*cFactor)*(*miter) );
378 }
379 assert( miter == mVal.end() );
380 }
381 }
390 template <class MVal, class RTVal,class Matrix>
391 void fillInterior (unsigned int startRow,
392 const MVal &mVal,
393 const RTVal &rtVal,
394 Field weight,
395 Matrix &matrix) const
396 {
397 const unsigned int endRow = startRow+mVal.size()*dimension;
398 typename RTVal::const_iterator rtiter = rtVal.begin();
399 for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
400 {
401 typename MVal::const_iterator miter = mVal.begin();
402 for (unsigned int row = startRow;
403 row!=endRow; ++miter,row+=dimension )
404 {
405 for (unsigned int i=0; i<dimension; ++i)
406 {
407 matrix.add(row+i,col, (weight*(*miter))*(*rtiter)[i] );
408 }
409 }
410 assert( miter == mVal.end() );
411 }
412 }
413
414 Builder builder_;
415 std::size_t order_;
416 std::size_t size_;
417 };
418
419 template < unsigned int dim, class Field >
421 {
424 typedef std::size_t Key;
425 typedef typename std::remove_const<Object>::type NonConstObject;
426
427 template <GeometryType::Id geometryId>
428 static Object *create( const Key &key )
429 {
430 if ( !supports<geometryId>(key) )
431 return 0;
432 NonConstObject *interpol = new NonConstObject();
433 interpol->template build<geometryId>(key);
434 return interpol;
435 }
436 template< GeometryType::Id geometryId >
437 static bool supports ( const Key &key )
438 {
439 return GeometryType(geometryId).isSimplex();
440 }
441 static void release( Object *object ) { delete object; }
442 };
443
444} // namespace Dune
445
446#endif // #ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
Definition bdfmcube.hh:18
Describe position of one degree of freedom.
Definition localkey.hh:23
Definition nedelecsimplexinterpolation.hh:38
LocalCoefficientsContainer(const Setter &setter)
Definition nedelecsimplexinterpolation.hh:43
const LocalKey & localKey(const unsigned int i) const
Definition raviartthomassimplexinterpolation.hh:48
std::size_t size() const
Definition nedelecsimplexinterpolation.hh:54
Definition orthonormalbasis.hh:20
static void release(Object *object)
Definition orthonormalbasis.hh:57
Definition raviartthomassimplexinterpolation.hh:421
std::remove_const< Object >::type NonConstObject
Definition raviartthomassimplexinterpolation.hh:425
static void release(Object *object)
Definition raviartthomassimplexinterpolation.hh:441
static bool supports(const Key &key)
Definition raviartthomassimplexinterpolation.hh:437
static Object * create(const Key &key)
Definition raviartthomassimplexinterpolation.hh:428
RTL2InterpolationBuilder< dim, Field > Builder
Definition raviartthomassimplexinterpolation.hh:422
const RaviartThomasL2Interpolation< dim, Field > Object
Definition raviartthomassimplexinterpolation.hh:423
std::size_t Key
Definition raviartthomassimplexinterpolation.hh:424
Definition raviartthomassimplexinterpolation.hh:70
std::size_t Key
Definition raviartthomassimplexinterpolation.hh:71
static void release(Object *object)
Definition raviartthomassimplexinterpolation.hh:91
static bool supports(const Key &key)
Definition raviartthomassimplexinterpolation.hh:87
const LocalCoefficientsContainer Object
Definition raviartthomassimplexinterpolation.hh:72
static Object * create(const Key &key)
Definition raviartthomassimplexinterpolation.hh:75
Definition raviartthomassimplexinterpolation.hh:107
TestBasis * testBasis() const
Definition raviartthomassimplexinterpolation.hh:141
FieldVector< Field, dimension > Normal
Definition raviartthomassimplexinterpolation.hh:119
TestBasisFactory::Object TestBasis
Definition raviartthomassimplexinterpolation.hh:112
TestFaceBasisFactory::Object TestFaceBasis
Definition raviartthomassimplexinterpolation.hh:116
unsigned int faceSize() const
Definition raviartthomassimplexinterpolation.hh:138
void build(std::size_t order)
Definition raviartthomassimplexinterpolation.hh:150
TestFaceBasis * testFaceBasis(unsigned int f) const
Definition raviartthomassimplexinterpolation.hh:144
GeometryType type() const
Definition raviartthomassimplexinterpolation.hh:133
const Normal & normal(unsigned int f) const
Definition raviartthomassimplexinterpolation.hh:147
RTL2InterpolationBuilder(const RTL2InterpolationBuilder &)=delete
OrthonormalBasisFactory< dimension-1, Field > TestFaceBasisFactory
Definition raviartthomassimplexinterpolation.hh:115
RTL2InterpolationBuilder(RTL2InterpolationBuilder &&)=delete
OrthonormalBasisFactory< dimension, Field > TestBasisFactory
Definition raviartthomassimplexinterpolation.hh:111
std::size_t order() const
Definition raviartthomassimplexinterpolation.hh:135
static const unsigned int dimension
Definition raviartthomassimplexinterpolation.hh:108
~RTL2InterpolationBuilder()
Definition raviartthomassimplexinterpolation.hh:126
An L2-based interpolation for Raviart Thomas.
Definition raviartthomassimplexinterpolation.hh:213
std::size_t order() const
Definition raviartthomassimplexinterpolation.hh:244
RaviartThomasL2Interpolation()
Definition raviartthomassimplexinterpolation.hh:220
void interpolate(typename Base::template Helper< Func, Container, type > &func) const
Definition raviartthomassimplexinterpolation.hh:283
auto interpolate(const Basis &basis, Matrix &matrix) const -> std::enable_if_t< std::is_same< decltype(std::declval< Matrix >().rowPtr(0)), typename Matrix::Field * >::value, void >
Definition raviartthomassimplexinterpolation.hh:235
RTL2InterpolationBuilder< dimension, Field > Builder
Definition raviartthomassimplexinterpolation.hh:219
F Field
Definition raviartthomassimplexinterpolation.hh:218
void build(std::size_t order)
Definition raviartthomassimplexinterpolation.hh:253
auto interpolate(const Function &function, Vector &coefficients) const -> std::enable_if_t< std::is_same< decltype(std::declval< Vector >().resize(1)), void >::value, void >
Definition raviartthomassimplexinterpolation.hh:226
std::size_t size() const
Definition raviartthomassimplexinterpolation.hh:248
void setLocalKeys(std::vector< LocalKey > &keys) const
Definition raviartthomassimplexinterpolation.hh:265
Definition interpolationhelper.hh:22
Definition interpolationhelper.hh:24
Definition polynomialbasis.hh:65
unsigned int size() const
Definition polynomialbasis.hh:113