3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_RAVIARTTHOMASBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_RAVIARTTHOMASBASIS_HH
7#include <dune/common/exceptions.hh>
9#include <dune/grid/common/capabilities.hh>
10#include <dune/grid/common/mcmgmapper.hh>
12#include <dune/localfunctions/common/localfiniteelementvariant.hh>
13#include <dune/localfunctions/raviartthomas.hh>
14#include <dune/localfunctions/raviartthomas/raviartthomas0cube2d.hh>
15#include <dune/localfunctions/raviartthomas/raviartthomas0cube3d.hh>
16#include <dune/localfunctions/raviartthomas/raviartthomas02d.hh>
17#include <dune/localfunctions/raviartthomas/raviartthomas03d.hh>
18#include <dune/localfunctions/raviartthomas/raviartthomas1cube2d.hh>
19#include <dune/localfunctions/raviartthomas/raviartthomas1cube3d.hh>
20#include <dune/localfunctions/raviartthomas/raviartthomas12d.hh>
21#include <dune/localfunctions/raviartthomas/raviartthomas2cube2d.hh>
33 template<
int dim,
typename D,
typename R, std::
size_t k>
34 struct RaviartThomasSimplexLocalInfo
37 using FiniteElement =
void*;
40 template<
typename D,
typename R>
41 struct RaviartThomasSimplexLocalInfo<2,D,R,0>
43 using FiniteElement = RT02DLocalFiniteElement<D,R>;
46 template<
typename D,
typename R>
47 struct RaviartThomasSimplexLocalInfo<2,D,R,1>
49 using FiniteElement = RT12DLocalFiniteElement<D,R>;
52 template<
typename D,
typename R>
53 struct RaviartThomasSimplexLocalInfo<3,D,R,0>
55 using FiniteElement = RT03DLocalFiniteElement<D,R>;
58 template<
int dim,
typename D,
typename R, std::
size_t k>
59 struct RaviartThomasCubeLocalInfo
62 using FiniteElement =
void*;
65 template<
typename D,
typename R>
66 struct RaviartThomasCubeLocalInfo<2,D,R,0>
68 using FiniteElement = RT0Cube2DLocalFiniteElement<D,R>;
71 template<
typename D,
typename R>
72 struct RaviartThomasCubeLocalInfo<2,D,R,1>
74 using FiniteElement = RT1Cube2DLocalFiniteElement<D,R>;
77 template<
typename D,
typename R>
78 struct RaviartThomasCubeLocalInfo<2,D,R,2>
80 using FiniteElement = RT2Cube2DLocalFiniteElement<D,R>;
83 template<
typename D,
typename R>
84 struct RaviartThomasCubeLocalInfo<3,D,R,0>
86 using FiniteElement = RT0Cube3DLocalFiniteElement<D,R>;
89 template<
typename D,
typename R>
90 struct RaviartThomasCubeLocalInfo<3,D,R,1>
92 using FiniteElement = RT1Cube3DLocalFiniteElement<D,R>;
95 template<
typename GV,
int dim,
typename R, std::
size_t k>
96 class RaviartThomasLocalFiniteElementMap
98 using D =
typename GV::ctype;
99 constexpr static bool hasFixedElementType = Capabilities::hasSingleGeometryType<typename GV::Grid>::v;
101 using CubeFiniteElement =
typename RaviartThomasCubeLocalInfo<dim, D, R, k>::FiniteElement;
102 using SimplexFiniteElement =
typename RaviartThomasSimplexLocalInfo<dim, D, R, k>::FiniteElement;
106 using T = LocalBasisTraits<D, dim, FieldVector<D,dim>, R, dim, FieldVector<R,dim>, FieldMatrix<D,dim,dim> >;
108 constexpr static unsigned int topologyId = Capabilities::hasSingleGeometryType<typename GV::Grid>::topologyId;
109 constexpr static GeometryType type = GeometryType(topologyId, GV::dimension);
111 using FiniteElement = std::conditional_t<hasFixedElementType,
112 std::conditional_t<type.isCube(),CubeFiniteElement,SimplexFiniteElement>,
113 LocalFiniteElementVariant<CubeFiniteElement, SimplexFiniteElement> >;
117 static std::size_t numVariants(GeometryType type)
119 auto numFacets = referenceElement<D,dim>(type).size(1);
120 return power(2,numFacets);
123 RaviartThomasLocalFiniteElementMap(
const GV& gv)
124 : elementMapper_(gv, mcmgElementLayout()),
127 if constexpr (hasFixedElementType)
129 variants_.resize(numVariants(type));
130 for (
size_t i = 0; i < numVariants(type); i++)
131 variants_[i] = FiniteElement(i);
136 variants_.resize(numVariants(GeometryTypes::simplex(dim)) + numVariants(GeometryTypes::cube(dim)));
137 for (
size_t i = 0; i < numVariants(GeometryTypes::simplex(dim)); i++)
138 variants_[i] = SimplexFiniteElement(i);
139 for (
size_t i = 0; i < numVariants(GeometryTypes::cube(dim)); i++)
140 variants_[i + numVariants(GeometryTypes::simplex(dim))] = CubeFiniteElement(i);
143 for(
const auto& cell : elements(gv))
145 unsigned int myId = elementMapper_.index(cell);
148 for (
const auto& intersection : intersections(gv,cell))
150 if (intersection.neighbor() && (elementMapper_.index(intersection.outside()) > myId))
151 orient_[myId] |= (1 << intersection.indexInInside());
155 if constexpr (!hasFixedElementType)
156 if (cell.type().isCube())
157 orient_[myId] += numVariants(GeometryTypes::simplex(dim));
161 template<
class EntityType>
162 const FiniteElement& find(
const EntityType& e)
const
164 return variants_[orient_[elementMapper_.index(e)]];
168 std::vector<FiniteElement> variants_;
169 const Dune::MultipleCodimMultipleGeomTypeMapper<GV> elementMapper_;
170 std::vector<unsigned char> orient_;
188template<
typename GV,
int k>
189class RaviartThomasNode;
191template<
typename GV,
int k,
class MI>
194 static const int dim = GV::dimension;
195 using FiniteElementMap =
typename Impl::RaviartThomasLocalFiniteElementMap<GV, dim, double, k>;
206 using IndexSet = Impl::DefaultNodeIndexSet<RaviartThomasPreBasis>;
219 if (gv.indexSet().types(0).size() > 1 and k>0)
220 DUNE_THROW(Dune::NotImplemented,
"Raviart-Thomas basis with index k>0 is only implemented for grids with a single element type");
222 for(
auto type : gv.indexSet().types(0))
223 if (!type.isSimplex() && !type.isCube())
224 DUNE_THROW(Dune::NotImplemented,
"Raviart-Thomas elements are only implemented for grids with simplex or cube elements.");
226 GeometryType type = gv.template begin<0>()->type();
227 const static int dofsPerElement = type.isCube() ? ((dim == 2) ? k*(k+1)*dim : k*(k+1)*(k+1)*dim) : k*dim;
228 const static int dofsPerFace = type.isCube() ? (dim-2)*2*k+k+1 : (dim-1)*k+1 ;
267 [[deprecated(
"Warning: The IndexSet typedef and the makeIndexSet method are deprecated. "\
268 "As a replacement use the indices() method of the PreBasis directly.")]]
282 assert(prefix.size() == 0 || prefix.size() == 1);
283 return (prefix.size() == 0) ?
size() : 0;
295 for (
auto&& type :
gridView_.indexSet().types(0))
297 size_t numFaces = ReferenceElements<double,dim>::general(type).size(1);
298 const static int dofsPerElement = type.isCube() ? ((dim == 2) ? k*(k+1)*dim : k*(k+1)*(k+1)*dim) : k*dim;
299 const static int dofsPerFace = type.isCube() ? (dim-2)*2*k+k+1 : (dim-1)*k+1 ;
300 result = std::max(result, dofsPerElement + dofsPerFace * numFaces);
311 template<
typename It>
314 const auto& gridIndexSet =
gridView().indexSet();
315 const auto& element = node.
element();
318 if (not(element.type().isCube()) and not(element.type().isSimplex()))
319 DUNE_THROW(Dune::NotImplemented,
"RaviartThomasBasis only implemented for cube and simplex elements.");
321 for(std::size_t i=0, end=node.
size(); i<end; ++i, ++it)
323 Dune::LocalKey localKey = node.
finiteElement().localCoefficients().localKey(i);
326 size_t subentity = localKey.subEntity();
327 size_t codim = localKey.codim();
329 if (not(codim==0 or codim==1))
330 DUNE_THROW(Dune::NotImplemented,
"Grid contains elements not supported for the RaviartThomasBasis");
333 dofsPerCodim_[codim] * gridIndexSet.subIndex(element, subentity, codim) + localKey.index() };
349template<
typename GV,
int k>
353 static const int dim = GV::dimension;
358 using Element =
typename GV::template Codim<0>::Entity;
359 using FiniteElementMap =
typename Impl::RaviartThomasLocalFiniteElementMap<GV, dim, double, k>;
360 using FiniteElement = Impl::GlobalValuedLocalFiniteElement<Impl::ContravariantPiolaTransformator,
361 typename FiniteElementMap::FiniteElement,
399namespace BasisFactory {
403template<std::
size_t k>
404class RaviartThomasPreBasisFactory
407 static const std::size_t requiredMultiIndexSize=1;
409 template<
class MultiIndex,
class Gr
idView>
410 auto makePreBasis(
const GridView& gridView)
const
426template<std::
size_t k>
429 return Imp::RaviartThomasPreBasisFactory<k>();
447template<
typename GV,
int k>
auto power(ChildPreBasisFactory &&childPreBasisFactory, const IndexMergingStrategy &ims)
Create a pre-basis factory that can build a PowerPreBasis.
Definition: powerbasis.hh:425
auto raviartThomas()
Create a pre-basis factory that can create a Raviart-Thomas pre-basis.
Definition: raviartthomasbasis.hh:427
Definition: polynomial.hh:10
Global basis for given pre-basis.
Definition: defaultglobalbasis.hh:47
size_type size() const
Definition: nodes.hh:140
void setSize(const size_type size)
Definition: nodes.hh:162
Definition: raviartthomasbasis.hh:352
typename Impl::RaviartThomasLocalFiniteElementMap< GV, dim, double, k > FiniteElementMap
Definition: raviartthomasbasis.hh:359
void bind(const Element &e)
Bind to element.
Definition: raviartthomasbasis.hh:385
Impl::GlobalValuedLocalFiniteElement< Impl::ContravariantPiolaTransformator, typename FiniteElementMap::FiniteElement, Element > FiniteElement
Definition: raviartthomasbasis.hh:362
typename GV::template Codim< 0 >::Entity Element
Definition: raviartthomasbasis.hh:358
const Element * element_
Definition: raviartthomasbasis.hh:395
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition: raviartthomasbasis.hh:379
std::size_t size_type
Definition: raviartthomasbasis.hh:357
RaviartThomasNode(const FiniteElementMap *finiteElementMap)
Definition: raviartthomasbasis.hh:364
const Element & element() const
Return current element, throw if unbound.
Definition: raviartthomasbasis.hh:370
FiniteElement finiteElement_
Definition: raviartthomasbasis.hh:394
const FiniteElementMap * finiteElementMap_
Definition: raviartthomasbasis.hh:396
Definition: raviartthomasbasis.hh:193
Node makeNode() const
Create tree node.
Definition: raviartthomasbasis.hh:255
std::size_t size_type
Definition: raviartthomasbasis.hh:201
std::array< size_t, dim+1 > codimOffset_
Definition: raviartthomasbasis.hh:341
Dune::ReservedVector< size_type, 1 > SizePrefix
Definition: raviartthomasbasis.hh:211
void update(const GridView &gv)
Definition: raviartthomasbasis.hh:247
void initializeIndices()
Definition: raviartthomasbasis.hh:233
RaviartThomasPreBasis(const GridView &gv)
Constructor for a given grid view object.
Definition: raviartthomasbasis.hh:214
std::array< int, dim+1 > dofsPerCodim_
Definition: raviartthomasbasis.hh:344
It indices(const Node &node, It it) const
Maps from subtree index set [0..size-1] to a globally unique multi index in global basis.
Definition: raviartthomasbasis.hh:312
GV GridView
The grid view that the FE space is defined on.
Definition: raviartthomasbasis.hh:200
FiniteElementMap finiteElementMap_
Definition: raviartthomasbasis.hh:342
size_type dimension() const
Definition: raviartthomasbasis.hh:287
size_type size() const
Definition: raviartthomasbasis.hh:274
GridView gridView_
Definition: raviartthomasbasis.hh:340
size_type maxNodeSize() const
Definition: raviartthomasbasis.hh:292
IndexSet makeIndexSet() const
Create tree node index set.
Definition: raviartthomasbasis.hh:269
Impl::DefaultNodeIndexSet< RaviartThomasPreBasis > IndexSet
Type of created tree node index set.
Definition: raviartthomasbasis.hh:206
const GridView & gridView() const
Obtain the grid view that the basis is defined on.
Definition: raviartthomasbasis.hh:241
size_type size(const SizePrefix prefix) const
Return number possible values for next position in multi index.
Definition: raviartthomasbasis.hh:280
MI MultiIndex
Type used for global numbering of the basis vectors.
Definition: raviartthomasbasis.hh:209