DUNE-FEM (unstable)

p1bubble.hh
1#ifndef SPACE_P1BUBBLE_HH
2#define SPACE_P1BUBBLE_HH
3
4#include <vector>
6#include <dune/geometry/referenceelements.hh>
7#include <dune/grid/common/gridenums.hh>
8
9#include <dune/fem/common/hybrid.hh>
10#include <dune/fem/space/common/functionspace.hh>
11#include <dune/fem/space/common/defaultcommhandler.hh>
12#include <dune/fem/space/common/discretefunctionspace.hh>
13#include <dune/fem/space/common/localrestrictprolong.hh>
14#include <dune/fem/space/mapper/code.hh>
15#include <dune/fem/space/mapper/localkey.hh>
16#include <dune/fem/space/mapper/indexsetdofmapper.hh>
17#include <dune/fem/space/shapefunctionset/simple.hh>
18#include <dune/fem/space/shapefunctionset/selectcaching.hh>
19#include <dune/fem/space/shapefunctionset/vectorial.hh>
20#include <dune/fem/space/basisfunctionset/default.hh>
21
22#include <dune/fem/operator/matrix/istlmatrixadapter.hh>
23
24namespace Dune
25{
26
27 namespace Fem
28 {
29
30 template< class FunctionSpace >
31 struct LocalBubbleElementInterpolation
32 {
33 typedef typename FunctionSpace::DomainType DomainType;
34 typedef typename FunctionSpace::RangeType RangeType;
35 static const int dimDomain = FunctionSpace::dimDomain;
36 static const int dimRange = FunctionSpace::dimRange;
37
38 LocalBubbleElementInterpolation ()
39 : points_( dimDomain + 2, DomainType( 0.0 ) )
40 {
41 for( int i = 0; i < dimDomain; ++i )
42 points_[ i + 1 ][ i ] = 1.0;
43
44 points_[ dimDomain +1 ] = DomainType( 1.0 / ( dimDomain + 1.0 ) );
45 }
46
47 LocalBubbleElementInterpolation ( const LocalBubbleElementInterpolation & ) = default;
48 LocalBubbleElementInterpolation ( LocalBubbleElementInterpolation && ) = default;
49
51 template< class LocalFunction, class LocalDofVector >
52 void operator() ( const LocalFunction &lf, LocalDofVector &ldv ) const
54 {
55 int k = 0;
56 for( const DomainType &x : points_ )
57 {
58 RangeType phi;
59 lf.evaluate( x, phi );
60 for( int i = 0; i < dimRange; ++i )
61 ldv[ k++ ] = phi[ i ];
62 }
63 }
64
65 template <class Entity>
66 void bind( const Entity & ) {}
67 void unbind() {}
68
69 private:
70 std::vector< DomainType > points_;
71 };
72
73
74 template< int dim >
75 struct BubbleElementLocalKeyMap
76 {
78 BubbleElementLocalKeyMap ( int vertices )
79 {
80 for( int i = 0; i < vertices; ++i )
81 map_.emplace_back( i, dim, 0 );
82 map_.emplace_back( 0, 0, 0 );
83 }
85
86 std::size_t size() const { return map_.size(); }
87
88 LocalKey& localKey ( std::size_t i ) { return map_[ i ]; }
89 const LocalKey& localKey ( std::size_t i ) const { return map_[ i ]; }
90
91 private:
92 std::vector< LocalKey > map_;
93 };
94
95 struct BubbleElementDofMapperCodeFactory
96 {
97 // return the shape functions for a given reference element. If this
98 // is not possible an empty DofMapperCode is returned.
99 template< class RefElement,
100 std::enable_if_t< std::is_same< std::decay_t< decltype( std::declval< const RefElement & >().size( 0 ) ) >, int >::value, int > = 0,
101 std::enable_if_t< std::is_same< std::decay_t< decltype( std::declval< const RefElement & >().type( 0, 0 ) ) >, GeometryType >::value, int > = 0 >
102 DofMapperCode operator() ( const RefElement &refElement ) const
103 {
104 static const int dim = RefElement::dimension;
105 if( refElement.type().isSimplex() )
106 return compile( refElement, BubbleElementLocalKeyMap< dim >(dim+1) );
107 if( refElement.type().isCube() && refElement.type().dim() == 2)
108 return compile( refElement, BubbleElementLocalKeyMap< dim >(pow(2,dim)) );
109 else
110 return DofMapperCode();
111 }
112 };
113
114 // SimplexBubbleElementShapeFunctionSet
115 // ----------------------------------
116
117 template< class FunctionSpace >
118 class SimplexBubbleElementShapeFunctionSet
119 {
120 typedef SimplexBubbleElementShapeFunctionSet< FunctionSpace > ThisType;
121 public:
122 static const int dimDomain = FunctionSpace :: dimDomain;
123 static const int polynomialOrder = dimDomain + 1;
124 static const int numShapeFunctions = dimDomain + 2;
125
126 typedef FunctionSpace FunctionSpaceType;
127 typedef typename FunctionSpace :: DomainType DomainType;
128 typedef typename FunctionSpace :: RangeType RangeType;
129 static_assert( RangeType::dimension == 1, "This is a scalar shapefunction set" );
130 typedef typename FunctionSpace :: JacobianRangeType JacobianRangeType;
131 typedef typename FunctionSpace :: HessianRangeType HessianRangeType;
132
133 SimplexBubbleElementShapeFunctionSet () {}
134
135 template<class GeometryType >
136 SimplexBubbleElementShapeFunctionSet ( const GeometryType& gt )
137 {
138 if( !gt.isSimplex() )
139 DUNE_THROW( NotImplemented, "Wrong geometry type for Cube2DBubblelementShapeFunctionSet." );
140 }
141
142 template< class Point, class Functor >
143 void evaluateEach ( const Point &x, Functor functor ) const
144 {
145 DomainType xRef = coordinate( x );
146 RangeType phi(1), phi0(1);
147 for( int i=0; i< dimDomain; ++i )
148 {
149 functor( i+1, RangeType( xRef[ i ] ) );
150 phi0[ 0 ] -= xRef[ i ];
151 phi[ 0 ] *= xRef[ i ] ;
152 }
153
154 phi[ 0 ] *= phi0[ 0 ] / std::pow( ( dimDomain + 1.0 ), dimDomain + 1.0 );
155 functor( 0, phi0 );
156 functor( dimDomain +1, phi );
157 }
158
159 template< class Point, class Functor >
160 void jacobianEach ( const Point &x, Functor functor ) const
161 {
162 DomainType xRef = coordinate( x );
163
164 JacobianRangeType jac(0), jac0( -1 );
165 RangeType phi0( 1 );
166
167 functor( 0, jac0 );
168
169 for( int i=0; i< dimDomain; ++i )
170 {
171 phi0[ 0 ] -= xRef[ i ];
172
173 for( int j=1; j < dimDomain; ++j )
174 jac0[ 0 ][ (i+j)%dimDomain ] *= xRef[ i ];
175
176 jac[ 0 ][ i ] = 1;
177 functor( i+1, jac );
178 jac[ 0 ][ i ] = 0;
179 }
180
181 for( int i=0; i< dimDomain; ++i )
182 jac0[ 0 ][ i ] *= -(phi0[ 0 ] - xRef[ i ]);
183 jac0[ 0 ] *= 1.0 / std::pow( dimDomain + 1.0, dimDomain + 1.0 );
184 functor( dimDomain +1, jac0 );
185 }
186
187 template< class Point, class Functor >
188 void hessianEach ( const Point &x, Functor functor ) const
189 {
190 DUNE_THROW( NotImplemented, "NotImplemented" );
191 DomainType xRef = coordinate( x );
192 HessianRangeType hes;
193 functor( 0, hes );
194 functor( 1, hes );
195 functor( 2, hes );
196 functor( 3, hes );
197 }
198
199 int order () const { return dimDomain + 1; }
200
201 std::size_t size () const { return dimDomain +2; }
202 };
203
204 // 2d cube element taken from
205 // http://arxiv.org/pdf/1507.04417v1.pdf
206 template< class FunctionSpace >
207 class Cube2DBubbleElementShapeFunctionSet
208 {
209 typedef Cube2DBubbleElementShapeFunctionSet< FunctionSpace > ThisType;
210 public:
211 static const int dimDomain = FunctionSpace :: dimDomain;
212 static const int polynomialOrder = dimDomain + 1;
213 static const int numShapeFunctions = dimDomain + 2;
214
215 typedef FunctionSpace FunctionSpaceType;
216 typedef typename FunctionSpace :: DomainType DomainType;
217 typedef typename FunctionSpace :: RangeType RangeType;
218 static_assert( RangeType::dimension == 1, "This is a scalar shapefunction set" );
219 typedef typename FunctionSpace :: JacobianRangeType JacobianRangeType;
220 typedef typename FunctionSpace :: HessianRangeType HessianRangeType;
221
223 Cube2DBubbleElementShapeFunctionSet () {}
224
225 template<class GeometryType >
226 Cube2DBubbleElementShapeFunctionSet ( const GeometryType& gt )
227 {
228 if( !gt.isCube() )
229 DUNE_THROW( NotImplemented, "Wrong geometry type for Cube2DBubblelementShapeFunctionSet." );
230 if( gt.dim() != 2 )
231 DUNE_THROW( NotImplemented, "2DCubeBubbleElementShapeFunctionSet only implemented for dimension = 2." );
232 }
233
234 template< class Point, class Functor >
235 void evaluateEach ( const Point &x, Functor functor ) const
237 {
238 DomainType xRef = coordinate( x );
239 RangeType phi(1), phi0(1);
240 // (1-x)(1-y) -> grad = ( (y-1),(x-1) )
241 phi0[0] = (1.-xRef[0])*(1.-xRef[1]);
242 functor( 0, phi0 );
243 // x(1-y) -> grad = ( (1-y),-x )
244 phi[0] = xRef[0]*(1.-xRef[1]);
245 functor( 1, phi );
246 // (1-x)y -> grad = ( (-y,(1-x) )
247 phi[0] = (1.-xRef[0])*xRef[1];
248 functor( 2, phi );
249 // xy -> grad = ( (y,x) )
250 phi[0] = xRef[0]*xRef[1];
251 functor( 3, phi );
252 // 64 xy phi_0(x,y)^2 -> grad = 128 phi_0 xy grad_0 +
253 // 64 phi_0^2 (y,x)
254 phi[0] = 64.*phi0[0]*phi0[0]*xRef[0]*xRef[1];
255 functor( 4, phi );
256 }
257
258 template< class Point, class Functor >
259 void jacobianEach ( const Point &x, Functor functor ) const
260 {
261 DomainType xRef = coordinate( x );
262
263 JacobianRangeType jac, jac0;
264 RangeType phi0;
265 phi0[0] = (1.-xRef[0])*(1.-xRef[1]);
266 jac0[0] = {xRef[1]-1,xRef[0]-1};
267
268 functor( 0, jac0 );
269 jac[0] = {1-xRef[1],xRef[0]};
270 functor( 1, jac );
271 jac[0] = {xRef[1],1-xRef[0]};
272 functor( 2, jac );
273 jac[0] = {xRef[1],xRef[0]};
274 functor( 3, jac );
275 // 64 xy phi_0(x,y)^2 -> grad = 128 phi_0 xy grad_0 +
276 // 64 phi_0^2 (y,x)
277 jac0[0] *= 128.*phi0*xRef[0]*xRef[1];
278 jac[0] = {xRef[1],xRef[0]};
279 jac[0] *= 64.*phi0*phi0;
280 jac[0] += jac0[0];
281 functor( 4, jac );
282 }
283
284 template< class Point, class Functor >
285 void hessianEach ( const Point &x, Functor functor ) const
286 {
287 DUNE_THROW( NotImplemented, "NotImplemented" );
288 DomainType xRef = coordinate( x );
289 HessianRangeType hes;
290 functor( 0, hes );
291 functor( 1, hes );
292 functor( 2, hes );
293 functor( 3, hes );
294 }
295
296 int order () const { return 4; }
297
298 std::size_t size () const { return 5; }
299 };
300
301 template< class FunctionSpace, class GridPart, class Storage >
302 class BubbleElementSpace;
303
304 // BubbleElementSpaceTraits
305 // ----------------------
306
307 template< class FunctionSpace, class GridPart, class Storage >
308 struct BubbleElementSpaceTraits
309 {
310 typedef BubbleElementSpace< FunctionSpace, GridPart, Storage > DiscreteFunctionSpaceType;
311
312 typedef FunctionSpace FunctionSpaceType;
313 typedef GridPart GridPartType;
314
315 static const int codimension = 0;
316
317 private:
318 typedef typename GridPartType::template Codim< codimension >::EntityType EntityType;
319 public:
320 typedef typename FunctionSpaceType :: ScalarFunctionSpaceType ScalarFunctionSpaceType;
321
322 // defined in shapefunctionset.hh
323 // First check if we have a grid with only one element type
324 // (hybrid // grids are not supported with this space yet)
325 // If it only has one get the topologyId of that element type
326 // (note simplex=0 and cube=2^dim-1)
328 "bubble elements only implemented for grids with a single geometry type" );
329 static const unsigned int topologyId =
331 // now choose either the simplex or the cube implementation of the
332 // bubble space
333 typedef SimplexBubbleElementShapeFunctionSet< ScalarFunctionSpaceType > ScalarSimplexShapeFunctionSetType;
334 typedef Cube2DBubbleElementShapeFunctionSet< ScalarFunctionSpaceType > ScalarCubeShapeFunctionSetType;
335 typedef typename std::conditional< topologyId == 0,
336 ScalarSimplexShapeFunctionSetType, ScalarCubeShapeFunctionSetType >::type
337 ScalarShapeFunctionSetType;
338 // now extend it to a vector valued funcion space
339 typedef VectorialShapeFunctionSet< ScalarShapeFunctionSetType, typename FunctionSpaceType::RangeType > ShapeFunctionSetType;
340 // and add some default functionality
341 typedef DefaultBasisFunctionSet< EntityType, ShapeFunctionSetType > BasisFunctionSetType;
342 // finished with the shape function set
343
344 static const int localBlockSize = FunctionSpaceType::dimRange;
345 static const int polynomialOrder = ScalarShapeFunctionSetType::polynomialOrder;
346
347 typedef IndexSetDofMapper< GridPartType > BlockMapperType;
348 typedef Hybrid::IndexRange< int, FunctionSpaceType::dimRange > LocalBlockIndices;
349
350 template <class DiscreteFunction, class Operation = DFCommunicationOperation::Add >
351 struct CommDataHandle
352 {
353 typedef Operation OperationType;
354 typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
355 };
356 };
357
358 // BubbleElementSpace
359 // ----------------
360
362 template< class FunctionSpace, class GridPart, class Storage = CachingStorage >
364 : public DiscreteFunctionSpaceDefault< BubbleElementSpaceTraits< FunctionSpace, GridPart, Storage > >
366 {
369
370 public:
371 typedef BubbleElementSpaceTraits< FunctionSpace, GridPart, Storage > Traits;
372 typedef typename Traits::ShapeFunctionSetType ShapeFunctionSetType;
373 static const int polynomialOrder = Traits::polynomialOrder;
374
375 typedef typename BaseType::GridPartType GridPartType;
376
377 typedef typename BaseType::BasisFunctionSetType BasisFunctionSetType;
378 typedef typename BaseType::IntersectionType IntersectionType;
379 typedef typename BaseType::EntityType EntityType;
380
381 typedef typename BaseType::BlockMapperType BlockMapperType;
382
383 // type of local interpolation
384 typedef LocalBubbleElementInterpolation< FunctionSpace > InterpolationType;
385
386 // static const InterfaceType defaultInterface = InteriorBorder_InteriorBorder_Interface;
387 static const InterfaceType defaultInterface = GridPartType::indexSetInterfaceType;
388 static const CommunicationDirection defaultDirection = ForwardCommunication;
389
390 BubbleElementSpace ( GridPartType &gridPart,
391 const InterfaceType commInterface = defaultInterface,
392 const CommunicationDirection commDirection = defaultDirection )
393 : BaseType( gridPart, commInterface, commDirection ),
394 blockMapper_( gridPart, BubbleElementDofMapperCodeFactory() )
395 {
396 }
397
399 {
400 }
401
402 bool contains ( const int codim ) const
403 {
404 // forward to mapper since this information is held there
405 return blockMapper().contains( codim );
406 }
407
408 bool continuous () const { return true; }
409
411 bool continuous ( const IntersectionType & intersection ) const
412 {
413 // forward to the subsapces
414 return true;
415 }
416
418 int order () const
419 {
420 return polynomialOrder;
421 }
422
424 template<class Entity>
425 int order ( const Entity &entity ) const
426 {
427 return polynomialOrder;
428 }
429
431 template< class EntityType >
432 BasisFunctionSetType basisFunctionSet ( const EntityType &entity ) const
433 {
434 return BasisFunctionSetType( entity, ShapeFunctionSetType( entity.geometry().type() ) );
435 }
436
440 BlockMapperType &blockMapper () const { return blockMapper_; }
441
442 // Non-interface methods
443
446 InterpolationType interpolation () const
447 {
448 return InterpolationType();
449 }
450
456 [[deprecated]]
457 InterpolationType interpolation ( const EntityType &entity ) const
458 {
459 return interpolation();
460 }
461
462 protected:
463 mutable BlockMapperType blockMapper_;
464 };
465
466 template< class FunctionSpace,
467 class GridPart,
468 class Storage,
469 class NewFunctionSpace >
470 struct DifferentDiscreteFunctionSpace< BubbleElementSpace < FunctionSpace, GridPart, Storage >, NewFunctionSpace >
471 {
472 typedef BubbleElementSpace< NewFunctionSpace, GridPart, Storage > Type;
473 };
474
475 template< class FunctionSpace, class GridPart, class Storage >
476 class DefaultLocalRestrictProlong < BubbleElementSpace< FunctionSpace, GridPart, Storage > >
477 : public EmptyLocalRestrictProlong< BubbleElementSpace< FunctionSpace, GridPart, Storage > >
478 {
479 typedef EmptyLocalRestrictProlong< BubbleElementSpace< FunctionSpace, GridPart, Storage > > BaseType;
480 public:
481 DefaultLocalRestrictProlong( const BubbleElementSpace< FunctionSpace, GridPart, Storage > &space )
482 : BaseType()
483 {}
484 };
485
486 } // namespace Fem
487
488} // namespace Dune
489
490#endif // SPACE_P1BUBBLE_HH
Wrapper class for entities.
Definition: entity.hh:66
[Class definition for new space]
Definition: p1bubble.hh:366
InterpolationType interpolation() const
return local interpolation object for LocalInterpolation
Definition: p1bubble.hh:446
BlockMapperType & blockMapper() const
obtain the DoF block mapper of this space
Definition: p1bubble.hh:440
bool continuous(const IntersectionType &intersection) const
returns true if the space contains only globally continuous functions
Definition: p1bubble.hh:411
int order() const
get global order of space
Definition: p1bubble.hh:418
BasisFunctionSetType basisFunctionSet(const EntityType &entity) const
get basis function set for given entity
Definition: p1bubble.hh:432
int order(const Entity &entity) const
get global order of space
Definition: p1bubble.hh:425
InterpolationType interpolation(const EntityType &entity) const
return local interpolation for given entity
Definition: p1bubble.hh:457
This is the class with default implementations for discrete function. The methods not marked with hav...
Definition: discretefunctionspace.hh:649
Traits::BasisFunctionSetType BasisFunctionSetType
type of basis function set of this space
Definition: discretefunctionspace.hh:201
GridPartType::IntersectionType IntersectionType
type of the intersections
Definition: discretefunctionspace.hh:226
ExplicitFieldVector< FieldMatrix< RangeFieldType, dimDomain, dimDomain >, dimRange > HessianRangeType
Intrinsic type used for the hessian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:79
FunctionSpaceTraits::RangeType RangeType
Type of range vector (using type of range field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:71
@ dimDomain
dimension of domain vector space
Definition: functionspaceinterface.hh:46
@ dimRange
dimension of range vector space
Definition: functionspaceinterface.hh:48
FunctionSpaceTraits::LinearMappingType JacobianRangeType
Intrinsic type used for the jacobian values has a Dune::FieldMatrix type interface.
Definition: functionspaceinterface.hh:75
FunctionSpaceTraits::DomainType DomainType
Type of domain vector (using type of domain field) has a Dune::FieldVector type interface.
Definition: functionspaceinterface.hh:67
FunctionSpaceTraits::ScalarFunctionSpaceType ScalarFunctionSpaceType
corresponding scalar function space
Definition: functionspaceinterface.hh:83
A vector valued function space.
Definition: functionspace.hh:60
A few common exception classes.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
CommunicationDirection
Define a type for communication direction parameter.
Definition: gridenums.hh:170
InterfaceType
Parameter to be used for the communication functions.
Definition: gridenums.hh:86
@ ForwardCommunication
communicate as given in InterfaceType
Definition: gridenums.hh:171
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Specialize with 'true' for if the codimension 0 entity of the grid has only one possible geometry typ...
Definition: capabilities.hh:27
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 27, 22:29, 2024)