5#ifndef DUNE_LOCALFUNCTIONS_NEDELEC_NEDELECSIMPLEX_NEDELECSIMPLEXINTERPOLATION_HH
6#define DUNE_LOCALFUNCTIONS_NEDELEC_NEDELECSIMPLEX_NEDELECSIMPLEXINTERPOLATION_HH
12#include <dune/common/exceptions.hh>
14#include <dune/geometry/quadraturerules.hh>
15#include <dune/geometry/referenceelements.hh>
16#include <dune/geometry/type.hh>
29 template <
unsigned int dim,
class Field >
30 struct NedelecL2InterpolationFactory;
42 template <
class Setter>
45 setter.setLocalKeys(localKey_);
51 return localKey_[ i ];
56 return localKey_.size();
60 std::vector< LocalKey > localKey_;
68 template <
unsigned int dim >
71 typedef std::size_t
Key;
74 template< GeometryType::Id geometryId >
78 if( !supports< geometryId >( key ) )
80 typename InterpolationFactory::Object *interpolation = InterpolationFactory::template create< geometryId >( key );
82 InterpolationFactory::release( interpolation );
86 template< GeometryType::Id geometryId >
89 GeometryType gt = geometryId;
90 return gt.isTriangle() || gt.isTetrahedron() ;
109 template<
unsigned int dim,
class Field >
127 typedef FieldVector< Field, dimension >
Tangent;
130 typedef FieldVector< Field, dimension >
Normal;
131 typedef std::array<FieldVector< Field, dimension >,dim-1>
FaceTangents;
141 for( FaceStructure &f : faceStructure_ )
143 for( EdgeStructure& e : edgeStructure_ )
149 return geometry_.id();
165 return numberOfFaces_;
171 return numberOfEdges_;
184 return faceStructure_[ f ].basis_;
191 return edgeStructure_[ e ].basis_;
197 return edgeStructure_[ e ].tangent_;
203 return faceStructure_[ f ].faceTangents_;
209 return faceStructure_[ f ].normal_;
212 template< GeometryType::Id geometryId >
215 constexpr GeometryType geometry = geometryId;
217 geometry_ = geometry;
232 int requiredOrder =
static_cast<int>(
dimension==3);
233 testBasis_ = (
order > requiredOrder ? TestBasisFactory::template create< geometry >(
order-1-requiredOrder ) :
nullptr);
235 const auto &refElement = ReferenceElements< Field, dimension >::general(
type() );
237 numberOfFaces_ = refElement.size( 1 );
238 faceStructure_.reserve( numberOfFaces_ );
241 for (std::size_t i=0; i<numberOfFaces_; i++)
243 FieldVector<Field,dimension> zero(0);
248 auto vertices = refElement.subEntities(i,1,dim).begin();
249 auto vertex1 = *vertices;
250 for(
int j=1; j<dim;j++)
252 auto vertex2 = vertices[j];
254 faceTangents[j-1] = refElement.position(vertex2,dim) - refElement.position(vertex1,dim);
275 TestFaceBasis *faceBasis = ( dim == 3 &&
order > 0 ? Impl::IfGeometryType< CreateFaceBasis, dimension-1 >::apply( refElement.type( i, 1 ),
order-1 ) :
nullptr);
276 faceStructure_.emplace_back( faceBasis, refElement.integrationOuterNormal(i),
faceTangents );
278 assert( faceStructure_.size() == numberOfFaces_ );
280 numberOfEdges_ = refElement.size( dim-1 );
281 edgeStructure_.reserve( numberOfEdges_ );
284 for (std::size_t i=0; i<numberOfEdges_; i++)
286 auto vertexIterator = refElement.subEntities(i,dim-1,dim).begin();
287 auto v0 = *vertexIterator;
288 auto v1 = *(++vertexIterator);
294 auto tangent = std::move(refElement.position(v1,dim) - refElement.position(v0,dim));
296 TestEdgeBasis *edgeBasis = Impl::IfGeometryType< CreateEdgeBasis, 1 >::apply( refElement.type( i, dim-1 ),
order );
297 edgeStructure_.emplace_back( edgeBasis, tangent );
299 assert( edgeStructure_.size() == numberOfEdges_ );
308 : basis_( teb ), tangent_( t )
312 const Dune::FieldVector< Field, dimension > tangent_;
315 template< GeometryType::Id edgeGeometryId >
316 struct CreateEdgeBasis
318 static TestEdgeBasis *apply ( std::size_t
order ) {
return TestEdgeBasisFactory::template create< edgeGeometryId >(
order ); }
329 const Dune::FieldVector< Field, dimension > normal_;
333 template< GeometryType::Id faceGeometryId >
334 struct CreateFaceBasis
336 static TestFaceBasis *apply ( std::size_t
order ) {
return TestFaceBasisFactory::template create< faceGeometryId >(
order ); }
340 std::vector< FaceStructure > faceStructure_;
341 unsigned int numberOfFaces_;
342 std::vector< EdgeStructure > edgeStructure_;
343 unsigned int numberOfEdges_;
344 GeometryType geometry_;
358 template<
unsigned int dimension,
class F>
375 template<
class Function,
class Vector >
376 auto interpolate (
const Function &function, Vector &coefficients )
const
377 -> std::enable_if_t< std::is_same< decltype(std::declval<Vector>().resize(1) ),
void >
::value,
void>
379 coefficients.resize(
size());
384 template<
class Basis,
class Matrix >
386 -> std::enable_if_t< std::is_same<
387 decltype(std::declval<Matrix>().rowPtr(0)),
typename Matrix::Field* >
::value,
void>
389 matrix.resize(
size(), basis.size() );
403 template <GeometryType::Id geometryId>
424 unsigned int row = 0;
429 keys[row] =
LocalKey(e,dimension-1,i);
441 assert( row ==
size() );
445 template<
class Func,
class Container,
bool type >
450 std::vector<Field> testBasisVal;
452 for (
unsigned int i=0; i<
size(); ++i)
453 for (
unsigned int j=0; j<func.size(); ++j)
456 unsigned int row = 0;
459 typedef Dune::QuadratureRule<Field, 1> EdgeQuadrature;
460 typedef Dune::QuadratureRules<Field, 1> EdgeQuadratureRules;
462 const auto &refElement = Dune::ReferenceElements< Field, dimension >::general( geoType );
470 const auto &geometry = refElement.template geometry< dimension-1 >( e );
471 const Dune::GeometryType subGeoType( geometry.type().id(), 1 );
472 const EdgeQuadrature &edgeQuad = EdgeQuadratureRules::rule( subGeoType, 2*
order_+2 );
474 const unsigned int quadratureSize = edgeQuad.size();
475 for(
unsigned int qi = 0; qi < quadratureSize; ++qi )
480 testBasisVal[0] = 1.;
483 func.evaluate( geometry.global( edgeQuad[qi].position() ) ),
485 edgeQuad[qi].weight(),
493 typedef Dune::QuadratureRule<
Field, dimension-1> FaceQuadrature;
494 typedef Dune::QuadratureRules<
Field, dimension-1> FaceQuadratureRules;
502 const auto &geometry = refElement.template geometry< 1 >( f );
503 const Dune::GeometryType subGeoType( geometry.type().id(), dimension-1 );
504 const FaceQuadrature &faceQuad = FaceQuadratureRules::rule( subGeoType, 2*
order_+2 );
506 const unsigned int quadratureSize = faceQuad.size();
507 for(
unsigned int qi = 0; qi < quadratureSize; ++qi )
512 testBasisVal[0] = 1.;
514 computeFaceDofs( row,
516 func.evaluate( geometry.global( faceQuad[qi].position() ) ),
519 faceQuad[qi].weight(),
532 typedef Dune::QuadratureRule<Field, dimension> Quadrature;
533 typedef Dune::QuadratureRules<Field, dimension> QuadratureRules;
534 const Quadrature &elemQuad = QuadratureRules::rule( geoType, 2*
order_+1 );
536 const unsigned int quadratureSize = elemQuad.size();
537 for(
unsigned int qi = 0; qi < quadratureSize; ++qi )
539 builder_.
testBasis()->template evaluate<0>(elemQuad[qi].position(),testBasisVal);
540 computeInteriorDofs(row,
542 func.evaluate(elemQuad[qi].position()),
543 elemQuad[qi].weight(),
562 template <
class MVal,
class NedVal,
class Matrix>
563 void computeEdgeDofs (
unsigned int startRow,
565 const NedVal &nedVal,
566 const FieldVector<Field,dimension> &tangent,
568 Matrix &matrix)
const
570 const unsigned int endRow = startRow+mVal.size();
571 typename NedVal::const_iterator nedIter = nedVal.begin();
572 for (
unsigned int col = 0; col < nedVal.size() ; ++nedIter,++col)
574 Field cFactor = (*nedIter)*tangent;
575 typename MVal::const_iterator mIter = mVal.begin();
576 for (
unsigned int row = startRow; row!=endRow; ++mIter, ++row )
577 matrix.add(row,col, (weight*cFactor)*(*mIter) );
579 assert( mIter == mVal.end() );
593 template <
class MVal,
class NedVal,
class Matrix>
594 void computeFaceDofs (
unsigned int startRow,
596 const NedVal &nedVal,
598 const FieldVector<Field,dimension> &normal,
600 Matrix &matrix)
const
602 const unsigned int endRow = startRow+mVal.size()*(dimension-1);
603 typename NedVal::const_iterator nedIter = nedVal.begin();
604 for (
unsigned int col = 0; col < nedVal.size() ; ++nedIter,++col)
606 auto const& u=*nedIter;
607 auto const& n=normal;
608 FieldVector<Field,dimension> nedTimesNormal = { u[1]*n[2]-u[2]*n[1],
610 u[0]*n[1]-u[1]*n[0]};
611 typename MVal::const_iterator mIter = mVal.begin();
612 for (
unsigned int row = startRow; row!=endRow; ++mIter)
614 for(
int i=0; i<dimension-1;i++)
616 auto test = *mIter*faceTangents[i];
617 matrix.add(row+i,col, weight*(nedTimesNormal*test) );
622 assert( mIter == mVal.end() );
634 template <
class MVal,
class NedVal,
class Matrix>
635 void computeInteriorDofs (
unsigned int startRow,
637 const NedVal &nedVal,
639 Matrix &matrix)
const
641 const unsigned int endRow = startRow+mVal.size()*dimension;
642 typename NedVal::const_iterator nedIter = nedVal.begin();
643 for (
unsigned int col = 0; col < nedVal.size() ; ++nedIter,++col)
645 typename MVal::const_iterator mIter = mVal.begin();
646 for (
unsigned int row = startRow; row!=endRow; ++mIter,row+=dimension )
647 for (
unsigned int i=0; i<dimension; ++i)
648 matrix.add(row+i,col, (weight*(*mIter))*(*nedIter)[i] );
650 assert( mIter == mVal.end() );
660 template <
unsigned int dim,
class Field >
668 template <GeometryType::Id geometryId>
671 if ( !supports<geometryId>(key) )
674 interpol->template build<geometryId>(key);
678 template <GeometryType::Id geometryId>
681 GeometryType gt = geometryId;
682 return gt.isTriangle() || gt.isTetrahedron() ;
Definition: bdfmcube.hh:18
@ value
Definition: tensor.hh:168
Describe position of one degree of freedom.
Definition: localkey.hh:23
Definition: nedelecsimplexinterpolation.hh:662
static Object * create(const Key &key)
Definition: nedelecsimplexinterpolation.hh:669
const NedelecL2Interpolation< dim, Field > Object
Definition: nedelecsimplexinterpolation.hh:664
NedelecL2InterpolationBuilder< dim, Field > Builder
Definition: nedelecsimplexinterpolation.hh:663
std::size_t Key
Definition: nedelecsimplexinterpolation.hh:665
static bool supports(const Key &key)
Definition: nedelecsimplexinterpolation.hh:679
std::remove_const< Object >::type NonConstObject
Definition: nedelecsimplexinterpolation.hh:666
static void release(Object *object)
Definition: nedelecsimplexinterpolation.hh:684
Definition: nedelecsimplexinterpolation.hh:38
LocalCoefficientsContainer(const Setter &setter)
Definition: nedelecsimplexinterpolation.hh:43
const LocalKey & localKey(const unsigned int i) const
Definition: nedelecsimplexinterpolation.hh:48
std::size_t size() const
Definition: nedelecsimplexinterpolation.hh:54
Definition: nedelecsimplexinterpolation.hh:70
static Object * create(const Key &key)
Definition: nedelecsimplexinterpolation.hh:75
static bool supports(const Key &key)
Definition: nedelecsimplexinterpolation.hh:87
const LocalCoefficientsContainer Object
Definition: nedelecsimplexinterpolation.hh:72
std::size_t Key
Definition: nedelecsimplexinterpolation.hh:71
static void release(Object *object)
Definition: nedelecsimplexinterpolation.hh:92
Definition: nedelecsimplexinterpolation.hh:111
TestEdgeBasis * testEdgeBasis(unsigned int e) const
Definition: nedelecsimplexinterpolation.hh:188
~NedelecL2InterpolationBuilder()
Definition: nedelecsimplexinterpolation.hh:138
GeometryType type() const
Definition: nedelecsimplexinterpolation.hh:152
TestBasisFactory::Object TestBasis
Definition: nedelecsimplexinterpolation.hh:116
FieldVector< Field, dimension > Tangent
Definition: nedelecsimplexinterpolation.hh:127
TestFaceBasisFactory::Object TestFaceBasis
Definition: nedelecsimplexinterpolation.hh:120
TestFaceBasis * testFaceBasis(unsigned int f) const
Definition: nedelecsimplexinterpolation.hh:181
TestEdgeBasisFactory::Object TestEdgeBasis
Definition: nedelecsimplexinterpolation.hh:124
FieldVector< Field, dimension > Normal
Definition: nedelecsimplexinterpolation.hh:130
void build(std::size_t order)
Definition: nedelecsimplexinterpolation.hh:213
OrthonormalBasisFactory< dimension, Field > TestBasisFactory
Definition: nedelecsimplexinterpolation.hh:115
OrthonormalBasisFactory< dimension-1, Field > TestFaceBasisFactory
Definition: nedelecsimplexinterpolation.hh:119
const FaceTangents & faceTangents(unsigned int f) const
Definition: nedelecsimplexinterpolation.hh:200
unsigned int faceSize() const
Definition: nedelecsimplexinterpolation.hh:163
TestBasis * testBasis() const
Definition: nedelecsimplexinterpolation.hh:175
std::array< FieldVector< Field, dimension >, dim-1 > FaceTangents
Definition: nedelecsimplexinterpolation.hh:131
OrthonormalBasisFactory< 1, Field > TestEdgeBasisFactory
Definition: nedelecsimplexinterpolation.hh:123
const Tangent & edgeTangent(unsigned int e) const
Definition: nedelecsimplexinterpolation.hh:194
NedelecL2InterpolationBuilder(NedelecL2InterpolationBuilder &&)=delete
std::size_t order() const
Definition: nedelecsimplexinterpolation.hh:157
unsigned int edgeSize() const
Definition: nedelecsimplexinterpolation.hh:169
unsigned int topologyId() const
Definition: nedelecsimplexinterpolation.hh:147
NedelecL2InterpolationBuilder(const NedelecL2InterpolationBuilder &)=delete
static const unsigned int dimension
Definition: nedelecsimplexinterpolation.hh:112
NedelecL2InterpolationBuilder()=default
const Normal & normal(unsigned int f) const
Definition: nedelecsimplexinterpolation.hh:206
An L2-based interpolation for Nedelec.
Definition: nedelecsimplexinterpolation.hh:361
Builder::FaceTangents FaceTangents
Definition: nedelecsimplexinterpolation.hh:368
F Field
Definition: nedelecsimplexinterpolation.hh:366
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: nedelecsimplexinterpolation.hh:376
std::size_t size() const
Definition: nedelecsimplexinterpolation.hh:398
void interpolate(typename Base::template Helper< Func, Container, type > &func) const
Definition: nedelecsimplexinterpolation.hh:446
std::size_t order_
Definition: nedelecsimplexinterpolation.hh:656
NedelecL2InterpolationBuilder< dimension, Field > Builder
Definition: nedelecsimplexinterpolation.hh:367
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: nedelecsimplexinterpolation.hh:385
std::size_t size_
Definition: nedelecsimplexinterpolation.hh:657
NedelecL2Interpolation()
Definition: nedelecsimplexinterpolation.hh:370
void build(std::size_t order)
Definition: nedelecsimplexinterpolation.hh:404
std::size_t order() const
Definition: nedelecsimplexinterpolation.hh:394
void setLocalKeys(std::vector< LocalKey > &keys) const
Definition: nedelecsimplexinterpolation.hh:421
Builder builder_
Definition: nedelecsimplexinterpolation.hh:655
Definition: orthonormalbasis.hh:20
static void release(Object *object)
Definition: orthonormalbasis.hh:57
Definition: interpolationhelper.hh:22
Definition: interpolationhelper.hh:24
Definition: interpolationhelper.hh:87
Definition: polynomialbasis.hh:65
unsigned int size() const
Definition: polynomialbasis.hh:113