DUNE PDELab (2.7)

raviartthomassimplexinterpolation.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
4#define DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
5
6#include <fstream>
7#include <utility>
8
10
12#include <dune/geometry/referenceelements.hh>
13#include <dune/geometry/type.hh>
14
15#include <dune/localfunctions/common/localkey.hh>
16#include <dune/localfunctions/utility/interpolationhelper.hh>
17#include <dune/localfunctions/utility/polynomialbasis.hh>
18#include <dune/localfunctions/orthonormal/orthonormalbasis.hh>
19
20namespace Dune
21{
22
23 // Internal Forward Declarations
24 // -----------------------------
25
26 template < unsigned int dim, class Field >
27 struct RaviartThomasL2InterpolationFactory;
28
29
30
31 // LocalCoefficientsContainer
32 // --------------------------
33
34 class LocalCoefficientsContainer
35 {
36 typedef LocalCoefficientsContainer This;
37
38 public:
39 template <class Setter>
40 LocalCoefficientsContainer ( const Setter &setter )
41 {
42 setter.setLocalKeys(localKey_);
43 }
44
45 const LocalKey &localKey ( const unsigned int i ) const
46 {
47 assert( i < size() );
48 return localKey_[ i ];
49 }
50
51 std::size_t size () const
52 {
53 return localKey_.size();
54 }
55
56 private:
57 std::vector< LocalKey > localKey_;
58 };
59
60
61
62 // RaviartThomasCoefficientsFactory
63 // --------------------------------
64
65 template < unsigned int dim >
66 struct RaviartThomasCoefficientsFactory
67 {
68 typedef std::size_t Key;
69 typedef const LocalCoefficientsContainer Object;
70
71 template< class Topology >
72 static Object *create( const Key &key )
73 {
74 typedef RaviartThomasL2InterpolationFactory< dim, double > InterpolationFactory;
75 if( !supports< Topology >( key ) )
76 return nullptr;
77 typename InterpolationFactory::Object *interpolation = InterpolationFactory::template create< Topology >( key );
78 Object *localKeys = new Object( *interpolation );
79 InterpolationFactory::release( interpolation );
80 return localKeys;
81 }
82
83 template< class Topology >
84 static bool supports ( const Key &key )
85 {
86 return Impl::IsSimplex< Topology >::value;
87 }
88 static void release( Object *object ) { delete object; }
89 };
90
91
92
93 // RTL2InterpolationBuilder
94 // ------------------------
95
96 // L2 Interpolation requires:
97 // - for element
98 // - test basis
99 // - for each face (dynamic)
100 // - test basis
101 // - normal
102 template< unsigned int dim, class Field >
103 struct RTL2InterpolationBuilder
104 {
105 static const unsigned int dimension = dim;
106 typedef OrthonormalBasisFactory< dimension, Field > TestBasisFactory;
107 typedef typename TestBasisFactory::Object TestBasis;
108 typedef OrthonormalBasisFactory< dimension-1, Field > TestFaceBasisFactory;
109 typedef typename TestFaceBasisFactory::Object TestFaceBasis;
110 typedef FieldVector< Field, dimension > Normal;
111
112 RTL2InterpolationBuilder () = default;
113
114 RTL2InterpolationBuilder ( const RTL2InterpolationBuilder & ) = delete;
115 RTL2InterpolationBuilder ( RTL2InterpolationBuilder && ) = delete;
116
117 ~RTL2InterpolationBuilder ()
118 {
119 TestBasisFactory::release( testBasis_ );
120 for( FaceStructure &f : faceStructure_ )
121 TestFaceBasisFactory::release( f.basis_ );
122 }
123
124 unsigned int topologyId () const { return topologyId_; }
125
126 GeometryType type () const { return GeometryType( topologyId(), dimension ); }
127
128 std::size_t order () const { return order_; }
129
130 unsigned int faceSize () const { return faceSize_; }
131
132 TestBasis *testBasis () const { return testBasis_; }
133 TestFaceBasis *testFaceBasis ( unsigned int f ) const { assert( f < faceSize() ); return faceStructure_[ f ].basis_; }
134
135 const Normal &normal ( unsigned int f ) const { assert( f < faceSize() ); return *(faceStructure_[ f ].normal_); }
136
137 template< class Topology >
138 void build ( std::size_t order )
139 {
140 order_ = order;
141 topologyId_ = Topology::id;
142
143 testBasis_ = (order > 0 ? TestBasisFactory::template create< Topology >( order-1 ) : nullptr);
144
145 const auto &refElement = ReferenceElements< Field, dimension >::general( type() );
146 faceSize_ = refElement.size( 1 );
147 faceStructure_.reserve( faceSize_ );
148 for( unsigned int face = 0; face < faceSize_; ++face )
149 {
150 TestFaceBasis *faceBasis = Impl::IfTopology< CreateFaceBasis, dimension-1 >::apply( refElement.type( face, 1 ).id(), order );
151 faceStructure_.emplace_back( faceBasis, refElement.integrationOuterNormal( face ) );
152 }
153 assert( faceStructure_.size() == faceSize_ );
154 }
155
156 private:
157 struct FaceStructure
158 {
159 FaceStructure( TestFaceBasis *tfb, const Normal &n )
160 : basis_( tfb ), normal_( &n )
161 {}
162
163 TestFaceBasis *basis_;
165 };
166
167 template< class FaceTopology >
168 struct CreateFaceBasis
169 {
170 static TestFaceBasis *apply ( std::size_t order ) { return TestFaceBasisFactory::template create< FaceTopology >( order ); }
171 };
172
173 std::vector< FaceStructure > faceStructure_;
174 TestBasis *testBasis_ = nullptr;
175 unsigned int topologyId_, faceSize_;
176 std::size_t order_;
177 };
178
179
180
181 // RaviartThomasL2Interpolation
182 // ----------------------------
183
189 template< unsigned int dimension, class F>
191 : public InterpolationHelper< F ,dimension >
192 {
194 typedef InterpolationHelper<F,dimension> Base;
195
196 public:
197 typedef F Field;
198 typedef RTL2InterpolationBuilder<dimension,Field> Builder;
200 : order_(0),
201 size_(0)
202 {}
203
204 template< class Function, class Vector >
205 auto interpolate ( const Function &function, Vector &coefficients ) const
206 -> std::enable_if_t< std::is_same< decltype(std::declval<Vector>().resize(1) ),void >::value,void>
207 {
208 coefficients.resize(size());
209 typename Base::template Helper<Function,Vector,true> func( function,coefficients );
210 interpolate(func);
211 }
212
213 template< class Basis, class Matrix >
214 auto interpolate ( const Basis &basis, Matrix &matrix ) const
215 -> std::enable_if_t< std::is_same<
216 decltype(std::declval<Matrix>().rowPtr(0)), typename Matrix::Field* >::value,void>
217 {
218 matrix.resize( size(), basis.size() );
219 typename Base::template Helper<Basis,Matrix,false> func( basis,matrix );
220 interpolate(func);
221 }
222
223 std::size_t order() const
224 {
225 return order_;
226 }
227 std::size_t size() const
228 {
229 return size_;
230 }
231 template <class Topology>
232 void build( std::size_t order )
233 {
234 size_ = 0;
235 order_ = order;
236 builder_.template build<Topology>(order_);
237 if (builder_.testBasis())
238 size_ += dimension*builder_.testBasis()->size();
239 for ( unsigned int f=0; f<builder_.faceSize(); ++f )
240 if (builder_.testFaceBasis(f))
241 size_ += builder_.testFaceBasis(f)->size();
242 }
243
244 void setLocalKeys(std::vector< LocalKey > &keys) const
245 {
246 keys.resize(size());
247 unsigned int row = 0;
248 for (unsigned int f=0; f<builder_.faceSize(); ++f)
249 {
250 if (builder_.faceSize())
251 for (unsigned int i=0; i<builder_.testFaceBasis(f)->size(); ++i,++row)
252 keys[row] = LocalKey(f,1,i);
253 }
254 if (builder_.testBasis())
255 for (unsigned int i=0; i<builder_.testBasis()->size()*dimension; ++i,++row)
256 keys[row] = LocalKey(0,0,i);
257 assert( row == size() );
258 }
259
260 protected:
261 template< class Func, class Container, bool type >
262 void interpolate ( typename Base::template Helper<Func,Container,type> &func ) const
263 {
264 const Dune::GeometryType geoType( builder_.topologyId(), dimension );
265
266 std::vector< Field > testBasisVal;
267
268 for (unsigned int i=0; i<size(); ++i)
269 for (unsigned int j=0; j<func.size(); ++j)
270 func.set(i,j,0);
271
272 unsigned int row = 0;
273
274 // boundary dofs:
275 typedef Dune::QuadratureRule<Field, dimension-1> FaceQuadrature;
276 typedef Dune::QuadratureRules<Field, dimension-1> FaceQuadratureRules;
277
278 const auto &refElement = Dune::ReferenceElements< Field, dimension >::general( geoType );
279
280 for (unsigned int f=0; f<builder_.faceSize(); ++f)
281 {
282 if (!builder_.testFaceBasis(f))
283 continue;
284 testBasisVal.resize(builder_.testFaceBasis(f)->size());
285
286 const auto &geometry = refElement.template geometry< 1 >( f );
287 const Dune::GeometryType subGeoType( geometry.type().id(), dimension-1 );
288 const FaceQuadrature &faceQuad = FaceQuadratureRules::rule( subGeoType, 2*order_+2 );
289
290 const unsigned int quadratureSize = faceQuad.size();
291 for( unsigned int qi = 0; qi < quadratureSize; ++qi )
292 {
293 if (dimension>1)
294 builder_.testFaceBasis(f)->template evaluate<0>(faceQuad[qi].position(),testBasisVal);
295 else
296 testBasisVal[0] = 1.;
297 fillBnd( row, testBasisVal,
298 func.evaluate( geometry.global( faceQuad[qi].position() ) ),
299 builder_.normal(f), faceQuad[qi].weight(),
300 func);
301 }
302
303 row += builder_.testFaceBasis(f)->size();
304 }
305 // element dofs
306 if (builder_.testBasis())
307 {
308 testBasisVal.resize(builder_.testBasis()->size());
309
312 const Quadrature &elemQuad = QuadratureRules::rule( geoType, 2*order_+1 );
313
314 const unsigned int quadratureSize = elemQuad.size();
315 for( unsigned int qi = 0; qi < quadratureSize; ++qi )
316 {
317 builder_.testBasis()->template evaluate<0>(elemQuad[qi].position(),testBasisVal);
318 fillInterior( row, testBasisVal,
319 func.evaluate(elemQuad[qi].position()),
320 elemQuad[qi].weight(),
321 func );
322 }
323
324 row += builder_.testBasis()->size()*dimension;
325 }
326 assert(row==size());
327 }
328
329 private:
331 template <class MVal, class RTVal,class Matrix>
332 void fillBnd (unsigned int startRow,
333 const MVal &mVal,
334 const RTVal &rtVal,
335 const FieldVector<Field,dimension> &normal,
336 const Field &weight,
337 Matrix &matrix) const
338 {
339 const unsigned int endRow = startRow+mVal.size();
340 typename RTVal::const_iterator rtiter = rtVal.begin();
341 for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
342 {
343 Field cFactor = (*rtiter)*normal;
344 typename MVal::const_iterator miter = mVal.begin();
345 for (unsigned int row = startRow;
346 row!=endRow; ++miter, ++row )
347 {
348 matrix.add(row,col, (weight*cFactor)*(*miter) );
349 }
350 assert( miter == mVal.end() );
351 }
352 }
353 template <class MVal, class RTVal,class Matrix>
354 void fillInterior (unsigned int startRow,
355 const MVal &mVal,
356 const RTVal &rtVal,
357 Field weight,
358 Matrix &matrix) const
359 {
360 const unsigned int endRow = startRow+mVal.size()*dimension;
361 typename RTVal::const_iterator rtiter = rtVal.begin();
362 for ( unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
363 {
364 typename MVal::const_iterator miter = mVal.begin();
365 for (unsigned int row = startRow;
366 row!=endRow; ++miter,row+=dimension )
367 {
368 for (unsigned int i=0; i<dimension; ++i)
369 {
370 matrix.add(row+i,col, (weight*(*miter))*(*rtiter)[i] );
371 }
372 }
373 assert( miter == mVal.end() );
374 }
375 }
376
377 Builder builder_;
378 std::size_t order_;
379 std::size_t size_;
380 };
381
382 template < unsigned int dim, class Field >
383 struct RaviartThomasL2InterpolationFactory
384 {
385 typedef RTL2InterpolationBuilder<dim,Field> Builder;
386 typedef const RaviartThomasL2Interpolation<dim,Field> Object;
387 typedef std::size_t Key;
388 typedef typename std::remove_const<Object>::type NonConstObject;
389 template <class Topology>
390 static Object *create( const Key &key )
391 {
392 if ( !supports<Topology>(key) )
393 return 0;
394 NonConstObject *interpol = new NonConstObject();
395 interpol->template build<Topology>(key);
396 return interpol;
397 }
398 template< class Topology >
399 static bool supports ( const Key &key )
400 {
401 return Impl::IsSimplex<Topology>::value;
402 }
403 static void release( Object *object ) { delete object; }
404 };
405
406} // namespace Dune
407
408#endif // #ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH
Iterator begin()
begin iterator
Definition: densevector.hh:348
Base class template for function classes.
Definition: function.hh:29
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:280
Describe position of one degree of freedom.
Definition: localkey.hh:21
A generic dynamic dense matrix.
Definition: matrix.hh:558
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:126
A container for all quadrature rules of dimension dim
Definition: quadraturerules.hh:172
static const QuadratureRule & rule(const GeometryType &t, int p, QuadratureType::Enum qt=QuadratureType::GaussLegendre)
select the appropriate QuadratureRule for GeometryType t and order p
Definition: quadraturerules.hh:254
An L2-based interpolation for Raviart Thomas.
Definition: raviartthomassimplexinterpolation.hh:192
A few common exception classes.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:180
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:46
Dune namespace.
Definition: alignedallocator.hh:14
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:196
A unique label for each type of element that can occur in a grid.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)