1#ifndef SPACE_P1BUBBLE_HH
2#define SPACE_P1BUBBLE_HH
6#include <dune/geometry/referenceelements.hh>
7#include <dune/grid/common/gridenums.hh>
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>
22#include <dune/fem/operator/matrix/istlmatrixadapter.hh>
35 constexpr int bubbleNormalization(
int dimDomain) {
return factorial(2*dimDomain + 1); }
38 struct BubbleElementLocalKeyMap
41 BubbleElementLocalKeyMap (
int vertices )
43 for(
int i = 0; i < vertices; ++i )
44 map_.emplace_back( i, dim, 0 );
45 map_.emplace_back( 0, 0, 0 );
49 std::size_t
size()
const {
return map_.size(); }
51 LocalKey& localKey ( std::size_t i ) {
return map_[ i ]; }
52 const LocalKey& localKey ( std::size_t i )
const {
return map_[ i ]; }
55 std::vector< LocalKey > map_;
58 struct BubbleElementDofMapperCodeFactory
62 template<
class RefElement,
63 std::enable_if_t< std::is_same< std::decay_t< decltype( std::declval< const RefElement & >().size( 0 ) ) >,
int >::value,
int > = 0,
64 std::enable_if_t< std::is_same< std::decay_t<
decltype( std::declval< const RefElement & >().type( 0, 0 ) ) >, GeometryType >::value,
int > = 0 >
65 DofMapperCode
operator() (
const RefElement &refElement )
const
67 static const int dim = RefElement::dimension;
68 if( refElement.type().isSimplex() )
69 return compile( refElement, BubbleElementLocalKeyMap< dim >(dim+1) );
70 if( refElement.type().isCube() && refElement.type().dim() == 2)
71 return compile( refElement, BubbleElementLocalKeyMap< dim >(pow(2,dim)) );
73 return DofMapperCode();
80 template<
class FunctionSpace >
81 class SimplexBubbleElementShapeFunctionSet
83 typedef SimplexBubbleElementShapeFunctionSet< FunctionSpace > ThisType;
86 static const int polynomialOrder = dimDomain + 1;
87 static const int numShapeFunctions = dimDomain + 2;
92 static_assert( RangeType::dimension == 1,
"This is a scalar shapefunction set" );
96 SimplexBubbleElementShapeFunctionSet () {}
98 template<
class GeometryType >
99 SimplexBubbleElementShapeFunctionSet (
const GeometryType&
gt )
101 if( !
gt.isSimplex() )
102 DUNE_THROW( NotImplemented,
"Wrong geometry type for Cube2DBubblelementShapeFunctionSet." );
105 template<
class Po
int,
class Functor >
106 void evaluateEach (
const Point &x, Functor functor )
const
108 DomainType xRef = coordinate( x );
109 RangeType phi(1), phi0(1);
110 for(
int i=0; i< dimDomain; ++i )
112 functor( i+1, RangeType( xRef[ i ] ) );
113 phi0[ 0 ] -= xRef[ i ];
114 phi[ 0 ] *= xRef[ i ] ;
117 phi[ 0 ] *= phi0[ 0 ] / bubbleNormalization(dimDomain);
119 functor( dimDomain +1, phi );
122 template<
class Po
int,
class Functor >
123 void jacobianEach (
const Point &x, Functor functor )
const
125 DomainType xRef = coordinate( x );
127 JacobianRangeType jac(0), jac0( -1 );
132 for(
int i=0; i< dimDomain; ++i )
134 phi0[ 0 ] -= xRef[ i ];
136 for(
int j=1; j < dimDomain; ++j )
137 jac0[ 0 ][ (i+j)%dimDomain ] *= xRef[ i ];
144 for(
int i=0; i< dimDomain; ++i )
145 jac0[ 0 ][ i ] *= -(phi0[ 0 ] - xRef[ i ]);
146 jac0[ 0 ] *= 1.0 / bubbleNormalization(dimDomain);
147 functor( dimDomain +1, jac0 );
150 template<
class Po
int,
class Functor >
151 void hessianEach (
const Point &x, Functor functor )
const
153 DUNE_THROW( NotImplemented,
"NotImplemented" );
154 DomainType xRef = coordinate( x );
155 HessianRangeType hes;
162 int order ()
const {
return dimDomain + 1; }
164 std::size_t
size ()
const {
return dimDomain +2; }
169 template<
class FunctionSpace >
170 class Cube2DBubbleElementShapeFunctionSet
172 typedef Cube2DBubbleElementShapeFunctionSet< FunctionSpace > ThisType;
175 static const int polynomialOrder = dimDomain + 1;
176 static const int numShapeFunctions = dimDomain + 2;
181 static_assert( RangeType::dimension == 1,
"This is a scalar shapefunction set" );
186 Cube2DBubbleElementShapeFunctionSet () {}
188 template<
class GeometryType >
189 Cube2DBubbleElementShapeFunctionSet (
const GeometryType&
gt )
192 DUNE_THROW( NotImplemented,
"Wrong geometry type for Cube2DBubblelementShapeFunctionSet." );
194 DUNE_THROW( NotImplemented,
"2DCubeBubbleElementShapeFunctionSet only implemented for dimension = 2." );
197 template<
class Po
int,
class Functor >
198 void evaluateEach (
const Point &x, Functor functor )
const
201 DomainType xRef = coordinate( x );
202 RangeType phi(1), phi0(1);
204 phi0[0] = (1.-xRef[0])*(1.-xRef[1]);
207 phi[0] = xRef[0]*(1.-xRef[1]);
210 phi[0] = (1.-xRef[0])*xRef[1];
213 phi[0] = xRef[0]*xRef[1];
217 phi[0] = 64.*phi0[0]*phi0[0]*xRef[0]*xRef[1];
221 template<
class Po
int,
class Functor >
222 void jacobianEach (
const Point &x, Functor functor )
const
224 DomainType xRef = coordinate( x );
226 JacobianRangeType jac, jac0;
228 phi0[0] = (1.-xRef[0])*(1.-xRef[1]);
229 jac0[0] = {xRef[1]-1,xRef[0]-1};
232 jac[0] = {1-xRef[1],xRef[0]};
234 jac[0] = {xRef[1],1-xRef[0]};
236 jac[0] = {xRef[1],xRef[0]};
240 jac0[0] *= 128.*phi0*xRef[0]*xRef[1];
241 jac[0] = {xRef[1],xRef[0]};
242 jac[0] *= 64.*phi0*phi0;
247 template<
class Po
int,
class Functor >
248 void hessianEach (
const Point &x, Functor functor )
const
250 DUNE_THROW( NotImplemented,
"NotImplemented" );
251 DomainType xRef = coordinate( x );
252 HessianRangeType hes;
259 int order ()
const {
return 4; }
261 std::size_t
size ()
const {
return 5; }
264 template<
class FunctionSpace,
class Gr
idPart,
class Storage >
265 class BubbleElementSpace;
270 template<
class FunctionSpace,
class Gr
idPart,
class Storage >
271 struct BubbleElementSpaceTraits
273 typedef BubbleElementSpace< FunctionSpace, GridPart, Storage > DiscreteFunctionSpaceType;
276 typedef GridPart GridPartType;
278 static const int codimension = 0;
281 typedef typename GridPartType::template Codim< codimension >::EntityType EntityType;
291 "bubble elements only implemented for grids with a single geometry type" );
292 static const unsigned int topologyId =
296 typedef SimplexBubbleElementShapeFunctionSet< ScalarFunctionSpaceType > ScalarSimplexShapeFunctionSetType;
297 typedef Cube2DBubbleElementShapeFunctionSet< ScalarFunctionSpaceType > ScalarCubeShapeFunctionSetType;
298 typedef typename std::conditional< topologyId == 0,
299 ScalarSimplexShapeFunctionSetType, ScalarCubeShapeFunctionSetType >::type
300 ScalarShapeFunctionSetType;
302 typedef VectorialShapeFunctionSet< ScalarShapeFunctionSetType, typename FunctionSpaceType::RangeType > ShapeFunctionSetType;
304 typedef DefaultBasisFunctionSet< EntityType, ShapeFunctionSetType > BasisFunctionSetType;
308 static const int polynomialOrder = ScalarShapeFunctionSetType::polynomialOrder;
310 typedef IndexSetDofMapper< GridPartType > BlockMapperType;
311 typedef Hybrid::IndexRange< int, FunctionSpaceType::dimRange > LocalBlockIndices;
313 template <
class DiscreteFunction,
class Operation = DFCommunicationOperation::Add >
314 struct CommDataHandle
316 typedef Operation OperationType;
317 typedef DefaultCommunicationHandler< DiscreteFunction, Operation > Type;
321 template<
class FunctionSpace,
class Gr
idPart,
class Storage >
322 struct LocalBubbleElementInterpolation
324 typedef BubbleElementSpaceTraits< FunctionSpace, GridPart, Storage > TraitsType;
332 LocalBubbleElementInterpolation ()
333 : points_( dimDomain + 2, DomainType( 0.0 ) )
335 for (
int i = 0; i < dimDomain; ++i )
336 points_[ i + 1 ][ i ] = 1.0;
338 points_[ dimDomain +1 ] = DomainType( 1.0 / ( dimDomain + 1.0 ) );
341 LocalBubbleElementInterpolation (
const LocalBubbleElementInterpolation & ) =
default;
342 LocalBubbleElementInterpolation ( LocalBubbleElementInterpolation && ) =
default;
345 template<
class LocalFunction,
class LocalDofVector >
346 void operator() (
const LocalFunction &lf, LocalDofVector &ldv )
const
349 static_assert( TraitsType::topologyId == 0,
"p1Bubble interpolation is only implemented for simplicial grids.");
354 for (
int dof = 0; dof < dimDomain + 1; ++dof) {
355 const auto& x = points_[dof];
357 lf.evaluate( x, phi );
358 for(
int i = 0; i < dimRange; ++i ) {
359 ldv[ dimRange * dof + i ] = phi[ i ];
370 RangeType centerValue;
371 lf.evaluate(points_[dimDomain+1], centerValue);
372 int dof = dimDomain + 1;
373 for(
int i = 0; i < dimRange; ++i ) {
375 ldv[ dimRange * dof + i ] = centerValue[i] - mean[i] / (dimDomain + 1.0);
379 template <
class Entity>
380 void bind(
const Entity& entity ) {}
384 std::vector< DomainType > points_;
385 mutable DomainFieldType entityVolume_;
392 template<
class FunctionSpace,
class Gr
idPart,
class Storage = CachingStorage >
401 typedef BubbleElementSpaceTraits< FunctionSpace, GridPart, Storage > Traits;
402 typedef typename Traits::ShapeFunctionSetType ShapeFunctionSetType;
403 static const int polynomialOrder = Traits::polynomialOrder;
405 typedef typename BaseType::GridPartType GridPartType;
409 typedef typename BaseType::EntityType EntityType;
411 typedef typename BaseType::BlockMapperType BlockMapperType;
414 typedef LocalBubbleElementInterpolation< FunctionSpace, GridPart, Storage > InterpolationType;
417 static const InterfaceType defaultInterface = GridPartType::indexSetInterfaceType;
424 blockMapper_(
gridPart, BubbleElementDofMapperCodeFactory() )
432 bool contains (
const int codim )
const
438 bool continuous ()
const {
return true; }
441 bool continuous (
const IntersectionType & intersection )
const
450 return polynomialOrder;
454 template<
class Entity>
457 return polynomialOrder;
461 template<
class EntityType >
464 return BasisFunctionSetType( entity, ShapeFunctionSetType( entity.geometry().type() ) );
478 return InterpolationType();
493 mutable BlockMapperType blockMapper_;
496 template<
class FunctionSpace,
499 class NewFunctionSpace >
500 struct DifferentDiscreteFunctionSpace< BubbleElementSpace < FunctionSpace, GridPart, Storage >, NewFunctionSpace >
502 typedef BubbleElementSpace< NewFunctionSpace, GridPart, Storage > Type;
505 template<
class FunctionSpace,
class Gr
idPart,
class Storage >
506 class DefaultLocalRestrictProlong < BubbleElementSpace< FunctionSpace, GridPart, Storage > >
507 :
public EmptyLocalRestrictProlong< BubbleElementSpace< FunctionSpace, GridPart, Storage > >
514 typedef EmptyLocalRestrictProlong< BubbleElementSpace< FunctionSpace, GridPart, Storage > > BaseType;
516 typedef BubbleElementSpaceTraits< FunctionSpace, GridPart, Storage > SpaceTraitsType;
519 DefaultLocalRestrictProlong(
const BubbleElementSpace< FunctionSpace, GridPart, Storage > &space )
520 : BaseType(), points_( dimDomain + 2, DomainType( 0.0 ) ), childCounter_(-1)
522 for (
int i = 0; i < dimDomain; ++i )
523 points_[ i + 1 ][ i ] = 1.0;
525 points_[ dimDomain +1 ] = DomainType( 1.0 / ( dimDomain + 1.0 ) );
528 template<
class LFParent,
class LFChild,
class LocalGeometry >
529 void restrictLocal ( LFParent &lfParent,
530 const LFChild &lfChild,
531 const LocalGeometry &geometryInParent,
532 const bool initialize )
const
534 static_assert( SpaceTraitsType::topologyId == 0,
"p1Bubble restriction and prolongation is only implemented for simplicial grids.");
547 int dof = dimDomain + 1;
550 for(
int coordinate = 0; coordinate < dimRange; ++coordinate ) {
551 lfParent[ dimRange * dof + coordinate ] = lfChild[ dimRange * dof + coordinate ];
555 for(
int coordinate = 0; coordinate < dimRange; ++coordinate ) {
556 lfParent[ dimRange * dof + coordinate ] += lfChild[ dimRange * dof + coordinate ];
561 template<
class LFParent >
562 void restrictFinalize ( LFParent &lfParent )
const
564 int dof = dimDomain + 1;
565 for(
int coordinate = 0; coordinate < dimRange; ++coordinate ) {
566 lfParent[ dimRange * dof + coordinate ] /= (double)childCounter_;
573 template<
class LFParent,
class LFChild,
class LocalGeometry >
574 void prolongLocal (
const LFParent &lfParent, LFChild &lfChild,
575 const LocalGeometry &geometryInParent,
576 bool initialize )
const
578 static_assert( SpaceTraitsType::topologyId == 0,
"p1Bubble restriction and prolongation is only implemented for simplicial grids.");
581 for (
int dof = 0; dof < dimDomain + 1; ++dof) {
582 const DomainType &pointInChild = points_[dof];
583 const DomainType pointInParent = geometryInParent.global( pointInChild );
585 lfParent.evaluate( pointInParent, phi );
586 for(
int coordinate = 0; coordinate < dimRange; ++coordinate ) {
587 lfChild[ dimRange * dof + coordinate ] = phi[ coordinate ];
592 int dof = dimDomain + 1;
593 for(
int coordinate = 0; coordinate < dimRange; ++coordinate ) {
594 lfChild[ dimRange * dof + coordinate ] = lfParent[ dimRange * dof + coordinate ];
598 bool needCommunication ()
const {
return true; }
600 std::vector< DomainType > points_;
601 mutable int childCounter_;
Wrapper class for entities.
Definition: entity.hh:66
[Class definition for new space]
Definition: p1bubble.hh:396
InterpolationType interpolation() const
return local interpolation object for LocalInterpolation
Definition: p1bubble.hh:476
BlockMapperType & blockMapper() const
obtain the DoF block mapper of this space
Definition: p1bubble.hh:470
bool continuous(const IntersectionType &intersection) const
returns true if the space contains only globally continuous functions
Definition: p1bubble.hh:441
int order() const
get global order of space
Definition: p1bubble.hh:448
BasisFunctionSetType basisFunctionSet(const EntityType &entity) const
get basis function set for given entity
Definition: p1bubble.hh:462
int order(const Entity &entity) const
get global order of space
Definition: p1bubble.hh:455
InterpolationType interpolation(const EntityType &entity) const
return local interpolation for given entity
Definition: p1bubble.hh:487
This is the class with default implementations for discrete function. The methods not marked with hav...
Definition: discretefunctionspace.hh:649
GridPartType & gridPart() const
Definition: discretefunctionspace.hh:766
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::DomainFieldType DomainFieldType
Intrinsic type used for values in the domain field (usually a double)
Definition: functionspaceinterface.hh:60
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,...)
Definition: exceptions.hh:314
bool gt(const T &first, const T &second, typename EpsilonType< T >::Type epsilon)
test if first greater than second
Definition: float_cmp.cc:158
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
static constexpr T factorial(const T &n) noexcept
calculate the factorial of n as a constexpr
Definition: math.hh:93
Specialize with 'true' for if the codimension 0 entity of the grid has only one possible geometry typ...
Definition: capabilities.hh:27