3#ifndef DUNE_LOCALFUNCTIONS_NEDELEC_NEDELEC1STKINDSIMPLEX_HH
4#define DUNE_LOCALFUNCTIONS_NEDELEC_NEDELEC1STKINDSIMPLEX_HH
11#include <dune/geometry/referenceelements.hh>
14#include <dune/localfunctions/common/localbasis.hh>
15#include <dune/localfunctions/common/localfiniteelementtraits.hh>
16#include <dune/localfunctions/common/localinterpolation.hh>
17#include <dune/localfunctions/common/localkey.hh>
33 template<
class D,
class R,
int dim,
int k>
34 class Nedelec1stKindSimplexLocalBasis
37 constexpr static std::size_t numberOfEdges = dim*(dim+1)/2;
40 using Traits = LocalBasisTraits<D,dim,FieldVector<D,dim>,
41 R,dim,FieldVector<R,dim>,
42 FieldMatrix<R,dim,dim> >;
50 Nedelec1stKindSimplexLocalBasis()
52 std::fill(edgeOrientation_.begin(), edgeOrientation_.end(), 1.0);
57 Nedelec1stKindSimplexLocalBasis(std::bitset<numberOfEdges> edgeOrientation)
58 : Nedelec1stKindSimplexLocalBasis()
60 for (std::size_t i=0; i<edgeOrientation_.size(); i++)
61 edgeOrientation_[i] *= edgeOrientation[i] ? -1.0 : 1.0;
65 static constexpr unsigned int size()
67 static_assert(dim==2 || dim==3,
"Nedelec shape functions are implemented only for 2d and 3d simplices.");
71 return k * (k+2) * (k+3) / 2;
80 std::vector<typename Traits::RangeType>& out)
const
82 static_assert(k==1,
"Evaluating Nédélec shape functions is implemented only for first order.");
90 out[0] = {D(1) - in[1], in[0]};
91 out[1] = {in[1], -in[0]+D(1)};
92 out[2] = {-in[1], in[0]};
114 out[0] = { 1 - in[1] - in[2], in[0] , in[0] };
115 out[1] = { in[1] , 1 - in[0] - in[2], in[1]};
116 out[2] = { - in[1] , in[0] , 0 };
117 out[3] = { in[2], in[2], 1 - in[0] - in[1]};
118 out[4] = { -in[2], 0 , in[0] };
119 out[5] = { 0 , -in[2], in[1]};
122 for (std::size_t i=0; i<out.size(); i++)
123 out[i] *= edgeOrientation_[i];
132 std::vector<typename Traits::JacobianType>& out)
const
137 out[0][0] = { 0, -1};
143 out[2][0] = { 0, -1};
148 out[0][0] = { 0,-1,-1};
149 out[0][1] = { 1, 0, 0};
150 out[0][2] = { 1, 0, 0};
152 out[1][0] = { 0, 1, 0};
153 out[1][1] = {-1, 0, -1};
154 out[1][2] = { 0, 1, 0};
156 out[2][0] = { 0, -1, 0};
157 out[2][1] = { 1, 0, 0};
158 out[2][2] = { 0, 0, 0};
160 out[3][0] = { 0, 0, 1};
161 out[3][1] = { 0, 0, 1};
162 out[3][2] = {-1, -1, 0};
164 out[4][0] = { 0, 0, -1};
165 out[4][1] = { 0, 0, 0};
166 out[4][2] = { 1, 0, 0};
168 out[5][0] = { 0, 0, 0};
169 out[5][1] = { 0, 0, -1};
170 out[5][2] = { 0, 1, 0};
173 for (std::size_t i=0; i<out.size(); i++)
174 out[i] *= edgeOrientation_[i];
184 void partial(
const std::array<unsigned int, dim>& order,
186 std::vector<typename Traits::RangeType>& out)
const
189 if (totalOrder == 0) {
190 evaluateFunction(in, out);
191 }
else if (totalOrder == 1) {
192 auto const direction = std::distance(order.begin(), std::find(order.begin(), order.end(), 1));
244 for (std::size_t i=0; i<out.size(); i++)
245 out[i] *= edgeOrientation_[i];
249 for (std::size_t i = 0; i < size(); ++i)
250 for (std::size_t j = 0; j < dim; ++j)
257 unsigned int order()
const
265 std::array<R,numberOfEdges> edgeOrientation_;
273 template <
int dim,
int k>
274 class Nedelec1stKindSimplexLocalCoefficients
278 Nedelec1stKindSimplexLocalCoefficients ()
281 static_assert(k==1,
"Only first-order Nédélec local coefficients are implemented.");
284 for (std::size_t i=0; i<size(); i++)
285 localKey_[i] = LocalKey(i,dim-1,0);
289 std::size_t size()
const
291 static_assert(dim==2 || dim==3,
"Nédélec shape functions are implemented only for 2d and 3d simplices.");
292 return (dim==2) ? k * (k+2)
293 : k * (k+2) * (k+3) / 2;
298 const LocalKey& localKey (std::size_t i)
const
304 std::vector<LocalKey> localKey_;
312 class Nedelec1stKindSimplexLocalInterpolation
314 static constexpr auto dim = LB::Traits::dimDomain;
315 static constexpr auto size = LB::size();
318 constexpr static std::size_t numberOfEdges = dim*(dim+1)/2;
323 Nedelec1stKindSimplexLocalInterpolation (std::bitset<numberOfEdges> s = 0)
327 for (std::size_t i=0; i<numberOfEdges; i++)
328 m_[i] = refElement.position(i,dim-1);
330 for (std::size_t i=0; i<numberOfEdges; i++)
332 auto vertexIterator = refElement.subEntities(i,dim-1,dim).begin();
333 auto v0 = *vertexIterator;
334 auto v1 = *(++vertexIterator);
339 edge_[i] = refElement.position(v1,dim) - refElement.position(v0,dim);
340 edge_[i] *= (s[i]) ? -1.0 : 1.0;
349 template<
typename F,
typename C>
350 void interpolate (
const F& ff, std::vector<C>& out)
const
353 auto&& f = Impl::makeFunctionWithCallOperator<typename LB::Traits::DomainType>(ff);
355 for (std::size_t i=0; i<size; i++)
359 for (
int j=0; j<dim; j++)
360 out[i] += y[j]*edge_[i][j];
366 std::array<typename LB::Traits::DomainType, numberOfEdges> m_;
368 std::array<typename LB::Traits::DomainType, numberOfEdges> edge_;
399 template<
class D,
class R,
int dim,
int k>
404 Impl::Nedelec1stKindSimplexLocalCoefficients<dim,k>,
405 Impl::Nedelec1stKindSimplexLocalInterpolation<Impl::Nedelec1stKindSimplexLocalBasis<D,R,dim,k> > >;
407 static_assert(dim==2 || dim==3,
"Nedelec elements are only implemented for 2d and 3d elements.");
408 static_assert(k==1,
"Nedelec elements of the first kind are currently only implemented for order k==1.");
431 return coefficients_;
436 return interpolation_;
439 static constexpr unsigned int size ()
441 return Traits::LocalBasisType::size();
Nédélec elements of the first kind for simplex elements.
Definition: nedelec1stkindsimplex.hh:401
Nedelec1stKindSimplexLocalFiniteElement()=default
Default constructor.
Nedelec1stKindSimplexLocalFiniteElement(std::bitset< dim *(dim+1)/2 > s)
Constructor with explicitly given edge orientations.
Definition: nedelec1stkindsimplex.hh:419
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:130
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
constexpr GeometryType simplex(unsigned int dim)
Returns a GeometryType representing a simplex of dimension dim.
Definition: type.hh:461
void interpolate(const F &f, const GFS &gfs, XG &xg)
interpolation from a given grid function
Definition: interpolate.hh:177
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:289
Dune namespace.
Definition: alignedallocator.hh:11
D DomainType
domain type
Definition: localbasis.hh:43
traits helper struct
Definition: localfiniteelementtraits.hh:11
LB LocalBasisType
Definition: localfiniteelementtraits.hh:14
LC LocalCoefficientsType
Definition: localfiniteelementtraits.hh:18
LI LocalInterpolationType
Definition: localfiniteelementtraits.hh:22
A unique label for each type of element that can occur in a grid.