5#ifndef DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH 
    6#define DUNE_LOCALFUNCTIONS_RAVIARTTHOMAS_RAVIARTTHOMASSIMPLEX_RAVIARTTHOMASSIMPLEXINTERPOLATION_HH 
   14#include <dune/geometry/referenceelements.hh> 
   18#include <dune/localfunctions/common/localkey.hh> 
   19#include <dune/localfunctions/utility/interpolationhelper.hh> 
   20#include <dune/localfunctions/utility/polynomialbasis.hh> 
   21#include <dune/localfunctions/orthonormal/orthonormalbasis.hh> 
   29  template < 
unsigned int dim, 
class Field >
 
   30  struct RaviartThomasL2InterpolationFactory;
 
   37  class LocalCoefficientsContainer
 
   39    typedef LocalCoefficientsContainer This;
 
   42    template <
class Setter>
 
   43    LocalCoefficientsContainer ( 
const Setter &setter )
 
   45      setter.setLocalKeys(localKey_);
 
   48    const LocalKey &localKey ( 
const unsigned int i )
 const 
   51      return localKey_[ i ];
 
   54    std::size_t 
size ()
 const 
   56      return localKey_.size();
 
   60    std::vector< LocalKey > localKey_;
 
   68  template < 
unsigned int dim >
 
   69  struct RaviartThomasCoefficientsFactory
 
   71    typedef std::size_t Key;
 
   72    typedef const LocalCoefficientsContainer Object;
 
   74    template< GeometryType::Id geometryId >
 
   75    static Object *create( 
const Key &key )
 
   77      typedef RaviartThomasL2InterpolationFactory< dim, double > InterpolationFactory;
 
   78      if( !supports< geometryId >( key ) )
 
   80      typename InterpolationFactory::Object *interpolation = InterpolationFactory::template create< geometryId >( key );
 
   81      Object *localKeys = 
new Object( *interpolation );
 
   82      InterpolationFactory::release( interpolation );
 
   86    template< GeometryType::Id geometryId >
 
   87    static bool supports ( 
const Key &key )
 
   91    static void release( Object *
object ) { 
delete object; }
 
  105  template< 
unsigned int dim, 
class Field >
 
  106  struct RTL2InterpolationBuilder
 
  108    static const unsigned int dimension = dim;
 
  110    typedef OrthonormalBasisFactory< dimension, Field, Field, Field > TestBasisFactory;
 
  111    typedef typename TestBasisFactory::Object TestBasis;
 
  114    typedef OrthonormalBasisFactory< dimension-1, Field, Field, Field > TestFaceBasisFactory;
 
  115    typedef typename TestFaceBasisFactory::Object TestFaceBasis;
 
  120    RTL2InterpolationBuilder () = 
default;
 
  122    RTL2InterpolationBuilder ( 
const RTL2InterpolationBuilder & ) = 
delete;
 
  123    RTL2InterpolationBuilder ( RTL2InterpolationBuilder && ) = 
delete;
 
  125    ~RTL2InterpolationBuilder ()
 
  127      TestBasisFactory::release( testBasis_ );
 
  128      for( FaceStructure &f : faceStructure_ )
 
  129        TestFaceBasisFactory::release( f.basis_ );
 
  134    std::size_t order ()
 const { 
return order_; }
 
  137    unsigned int faceSize ()
 const { 
return faceSize_; }
 
  140    TestBasis *testBasis ()
 const { 
return testBasis_; }
 
  143    TestFaceBasis *testFaceBasis ( 
unsigned int f )
 const { assert( f < faceSize() ); 
return faceStructure_[ f ].basis_; }
 
  146    const Normal normal ( 
unsigned int f )
 const { assert( f < faceSize() ); 
return faceStructure_[ f ].normal_; }
 
  148    template< GeometryType::Id geometryId >
 
  149    void build ( std::size_t order )
 
  152      geometry_ = geometry;
 
  155      testBasis_ = (order > 0 ? TestBasisFactory::template create< geometry >( order-1 ) : nullptr);
 
  158      faceSize_ = refElement.size( 1 );
 
  159      faceStructure_.reserve( faceSize_ );
 
  160      for( 
unsigned int face = 0; face < faceSize_; ++face )
 
  173        TestFaceBasis *faceBasis = Impl::toGeometryTypeIdConstant<dimension-1>(refElement.type( face, 1 ), [&](
auto faceGeometryTypeId) {
 
  174            return TestFaceBasisFactory::template create< decltype(faceGeometryTypeId)::value >( order );
 
  176        faceStructure_.emplace_back( faceBasis, refElement.integrationOuterNormal( face ) );
 
  178      assert( faceStructure_.size() == faceSize_ );
 
  184      FaceStructure( TestFaceBasis *tfb, 
const Normal n )
 
  185        : basis_( tfb ), normal_( n )
 
  188      TestFaceBasis *basis_;
 
  192    std::vector< FaceStructure > faceStructure_;
 
  193    TestBasis *testBasis_ = 
nullptr;
 
  195    unsigned int faceSize_;
 
  209  template< 
unsigned int dimension, 
class F>
 
  211    : 
public InterpolationHelper< F ,dimension >
 
  214    typedef InterpolationHelper<F,dimension> Base;
 
  218    typedef RTL2InterpolationBuilder<dimension,Field> Builder;
 
  224    template< 
class Function, 
class Vector,
 
  225      decltype(std::declval<Vector>().size(),
bool{}) = 
true,
 
  226      decltype(std::declval<Vector>().resize(0u),
bool{}) = 
true>
 
  227    void interpolate ( 
const Function &function, Vector &coefficients ) 
const 
  229      coefficients.resize(size());
 
  230      typename Base::template Helper<Function,Vector,true> func( function,coefficients );
 
  234    template< 
class Basis, 
class Matrix,
 
  235      decltype(std::declval<Matrix>().rows(),
bool{}) = 
true,
 
  236      decltype(std::declval<Matrix>().cols(),
bool{}) = 
true,
 
  237      decltype(std::declval<Matrix>().resize(0u,0u),
bool{}) = 
true>
 
  238    void interpolate ( 
const Basis &basis, 
Matrix &matrix ) 
const 
  240      matrix.resize( size(), basis.size() );
 
  241      typename Base::template Helper<Basis,Matrix,false> func( basis,matrix );
 
  245    std::size_t order()
 const 
  249    std::size_t size()
 const 
  253    template <GeometryType::Id geometryId>
 
  254    void build( std::size_t order )
 
  258      builder_.template build<geometryId>(order_);
 
  259      if (builder_.testBasis())
 
  260        size_ += dimension*builder_.testBasis()->size();
 
  261      for ( 
unsigned int f=0; f<builder_.faceSize(); ++f )
 
  262        if (builder_.testFaceBasis(f))
 
  263          size_ += builder_.testFaceBasis(f)->size();
 
  266    void setLocalKeys(std::vector< LocalKey > &keys)
 const 
  269      unsigned int row = 0;
 
  270      for (
unsigned int f=0; f<builder_.faceSize(); ++f)
 
  272        if (builder_.faceSize())
 
  273          for (
unsigned int i=0; i<builder_.testFaceBasis(f)->size(); ++i,++row)
 
  276      if (builder_.testBasis())
 
  277        for (
unsigned int i=0; i<builder_.testBasis()->size()*dimension; ++i,++row)
 
  279      assert( row == size() );
 
  283    template< 
class Func, 
class Container, 
bool type >
 
  284    void interpolate ( 
typename Base::template Helper<Func,Container,type> &func )
 const 
  288      std::vector< Field > testBasisVal;
 
  290      for (
unsigned int i=0; i<size(); ++i)
 
  291        for (
unsigned int j=0; j<func.size(); ++j)
 
  294      unsigned int row = 0;
 
  302      for (
unsigned int f=0; f<builder_.faceSize(); ++f)
 
  304        if (!builder_.testFaceBasis(f))
 
  306        testBasisVal.resize(builder_.testFaceBasis(f)->size());
 
  308        const auto &geometry = refElement.template geometry< 1 >( f );
 
  310        const FaceQuadrature &faceQuad = FaceQuadratureRules::rule( subGeoType, 2*order_+2 );
 
  312        const unsigned int quadratureSize = faceQuad.size();
 
  313        for( 
unsigned int qi = 0; qi < quadratureSize; ++qi )
 
  316            builder_.testFaceBasis(f)->template evaluate<0>(faceQuad[qi].position(),testBasisVal);
 
  318            testBasisVal[0] = 1.;
 
  319          fillBnd( row, testBasisVal,
 
  320                   func.evaluate( geometry.global( faceQuad[qi].position() ) ),
 
  321                   builder_.normal(f), faceQuad[qi].weight(),
 
  325        row += builder_.testFaceBasis(f)->size();
 
  328      if (builder_.testBasis())
 
  330        testBasisVal.resize(builder_.testBasis()->size());
 
  336        const unsigned int quadratureSize = elemQuad.size();
 
  337        for( 
unsigned int qi = 0; qi < quadratureSize; ++qi )
 
  339          builder_.testBasis()->template evaluate<0>(elemQuad[qi].position(),testBasisVal);
 
  340          fillInterior( row, testBasisVal,
 
  341                        func.evaluate(elemQuad[qi].position()),
 
  342                        elemQuad[qi].weight(),
 
  346        row += builder_.testBasis()->size()*dimension;
 
  361    template <
class MVal, 
class RTVal,
class Matrix>
 
  362    void fillBnd (
unsigned int startRow,
 
  369      const unsigned int endRow = startRow+mVal.size();
 
  370      typename RTVal::const_iterator rtiter = rtVal.begin();
 
  371      for ( 
unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
 
  373        Field cFactor = (*rtiter)*normal;
 
  374        typename MVal::const_iterator miter = mVal.
begin();
 
  375        for (
unsigned int row = startRow;
 
  376             row!=endRow; ++miter, ++row )
 
  378          matrix.add(row,col, (weight*cFactor)*(*miter) );
 
  380        assert( miter == mVal.end() );
 
  391    template <
class MVal, 
class RTVal,
class Matrix>
 
  392    void fillInterior (
unsigned int startRow,
 
  398      const unsigned int endRow = startRow+mVal.size()*dimension;
 
  399      typename RTVal::const_iterator rtiter = rtVal.begin();
 
  400      for ( 
unsigned int col = 0; col < rtVal.size() ; ++rtiter,++col)
 
  402        typename MVal::const_iterator miter = mVal.begin();
 
  403        for (
unsigned int row = startRow;
 
  404             row!=endRow; ++miter,row+=dimension )
 
  406          for (
unsigned int i=0; i<dimension; ++i)
 
  408            matrix.add(row+i,col, (weight*(*miter))*(*rtiter)[i] );
 
  411        assert( miter == mVal.end() );
 
  420  template < 
unsigned int dim, 
class Field >
 
  421  struct RaviartThomasL2InterpolationFactory
 
  423    typedef RTL2InterpolationBuilder<dim,Field> Builder;
 
  425    typedef std::size_t Key;
 
  426    typedef typename std::remove_const<Object>::type NonConstObject;
 
  428    template <GeometryType::Id geometryId>
 
  429    static Object *create( 
const Key &key )
 
  431      if ( !supports<geometryId>(key) )
 
  433      NonConstObject *interpol = 
new NonConstObject();
 
  434      interpol->template build<geometryId>(key);
 
  437    template< GeometryType::Id geometryId >
 
  438    static bool supports ( 
const Key &key )
 
  440      return GeometryType(geometryId).isSimplex();
 
  442    static void release( Object *
object ) { 
delete object; }
 
constexpr Iterator begin()
begin iterator
Definition: densevector.hh:348
 
Unique label for each type of entities that can occur in DUNE grids.
Definition: type.hh:114
 
Describe position of one degree of freedom.
Definition: localkey.hh:24
 
A generic dynamic dense matrix.
Definition: matrix.hh:561
 
Abstract base class for quadrature rules.
Definition: quadraturerules.hh:214
 
A container for all quadrature rules of dimension dim
Definition: quadraturerules.hh:260
 
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:326
 
An L2-based interpolation for Raviart Thomas.
Definition: raviartthomassimplexinterpolation.hh:212
 
A few common exception classes.
 
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:132
 
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 const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:156
 
A unique label for each type of element that can occur in a grid.
 
Helper classes to provide indices for geometrytypes for use in a vector.