3#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
4#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
8#include <dune/geometry/referenceelements.hh>
10#include <dune/localfunctions/common/virtualinterface.hh>
11#include <dune/localfunctions/common/virtualwrappers.hh>
13#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube2d.hh>
14#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube3d.hh>
15#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1simplex2d.hh>
16#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2cube2d.hh>
17#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2simplex2d.hh>
19#include <dune/functions/functionspacebases/globalvaluedlocalfiniteelement.hh>
20#include <dune/functions/functionspacebases/nodes.hh>
21#include <dune/functions/functionspacebases/defaultglobalbasis.hh>
22#include <dune/functions/functionspacebases/flatmultiindex.hh>
29 template<
int dim,
typename D,
typename R, std::
size_t k>
30 struct BDMSimplexLocalInfo
32 static_assert((AlwaysFalse<D>::value),
"The requested type of BDM element is not implemented, sorry!");
35 template<
typename D,
typename R>
36 struct BDMSimplexLocalInfo<2,D,R,1>
38 using FiniteElement = BDM1Simplex2DLocalFiniteElement<D,R>;
39 static const std::size_t Variants = 8;
42 template<
typename D,
typename R>
43 struct BDMSimplexLocalInfo<2,D,R,2>
45 using FiniteElement = BDM2Simplex2DLocalFiniteElement<D,R>;
46 static const std::size_t Variants = 8;
49 template<
int dim,
typename D,
typename R, std::
size_t k>
50 struct BDMCubeLocalInfo
52 static_assert((AlwaysFalse<D>::value),
"The requested type of BDM element is not implemented, sorry!");
55 template<
typename D,
typename R>
56 struct BDMCubeLocalInfo<2,D,R,1>
58 using FiniteElement = BDM1Cube2DLocalFiniteElement<D,R>;
59 static const std::size_t Variants = 16;
62 template<
typename D,
typename R>
63 struct BDMCubeLocalInfo<2,D,R,2>
65 using FiniteElement = BDM2Cube2DLocalFiniteElement<D,R>;
66 static const std::size_t Variants = 16;
69 template<
typename D,
typename R>
70 struct BDMCubeLocalInfo<3,D,R,1>
72 using FiniteElement = BDM1Cube3DLocalFiniteElement<D,R>;
73 static const std::size_t Variants = 64;
76 template<
typename GV,
int dim,
typename R, std::
size_t k>
77 class BDMLocalFiniteElementMap
79 using D =
typename GV::ctype;
80 using CubeFiniteElement =
typename BDMCubeLocalInfo<dim, D, R, k>::FiniteElement;
81 using SimplexFiniteElement =
typename BDMSimplexLocalInfo<dim, D, R, k>::FiniteElement;
85 using T = LocalBasisTraits<D, dim, FieldVector<D,dim>, R, dim, FieldVector<R,dim>, FieldMatrix<D,dim,dim> >;
86 using FiniteElement = LocalFiniteElementVirtualInterface<T>;
88 BDMLocalFiniteElementMap(
const GV& gv)
89 : is_(&(gv.indexSet())), orient_(gv.size(0))
91 cubeVariant_.resize(BDMCubeLocalInfo<dim, D, R, k>::Variants);
92 simplexVariant_.resize(BDMSimplexLocalInfo<dim, D, R, k>::Variants);
95 for (
size_t i = 0; i < cubeVariant_.size(); i++)
96 cubeVariant_[i] = std::make_unique<LocalFiniteElementVirtualImp<CubeFiniteElement> >(CubeFiniteElement(i));
98 for (
size_t i = 0; i < simplexVariant_.size(); i++)
99 simplexVariant_[i] = std::make_unique<LocalFiniteElementVirtualImp<SimplexFiniteElement> >(SimplexFiniteElement(i));
103 for(
const auto& cell : elements(gv))
105 unsigned int myId = is_->index(cell);
108 for (
const auto& intersection : intersections(gv,cell))
110 if (intersection.neighbor() && (is_->index(intersection.outside()) > myId))
111 orient_[myId] |= (1 << intersection.indexInInside());
117 template<
class EntityType>
118 const FiniteElement& find(
const EntityType& e)
const
120 if (e.type().isCube())
121 return *cubeVariant_[orient_[is_->index(e)]];
123 return *simplexVariant_[orient_[is_->index(e)]];
127 std::vector<std::unique_ptr<LocalFiniteElementVirtualImp<CubeFiniteElement> > > cubeVariant_;
128 std::vector<std::unique_ptr<LocalFiniteElementVirtualImp<SimplexFiniteElement> > > simplexVariant_;
129 const typename GV::IndexSet* is_;
130 std::vector<unsigned char> orient_;
148template<
typename GV,
int k>
149class BrezziDouglasMariniNode;
151template<
typename GV,
int k,
class MI>
152class BrezziDouglasMariniPreBasis
154 static const int dim = GV::dimension;
155 using FiniteElementMap =
typename Impl::BDMLocalFiniteElementMap<GV, dim, double, k>;
161 using size_type = std::size_t;
163 using Node = BrezziDouglasMariniNode<GV, k>;
166 using IndexSet = Impl::DefaultNodeIndexSet<BrezziDouglasMariniPreBasis>;
169 using MultiIndex = MI;
174 BrezziDouglasMariniPreBasis(
const GridView& gv) :
176 finiteElementMap_(gv)
180 if (gv.indexSet().types(0).size() > 1)
184 void initializeIndices()
187 codimOffset_[1] = codimOffset_[0] + dofsPerCodim_[0] * gridView_.size(0);
193 const GridView& gridView()
const
199 void update (
const GridView& gv)
207 Node makeNode()
const
209 return Node{&finiteElementMap_};
219 [[deprecated(
"Warning: The IndexSet typedef and the makeIndexSet method are deprecated. "\
220 "As a replacement use the indices() method of the PreBasis directly.")]]
221 IndexSet makeIndexSet()
const
223 return IndexSet{*
this};
226 size_type size()
const
228 return dofsPerCodim_[0] * gridView_.size(0) + dofsPerCodim_[1] * gridView_.size(1);
232 size_type size(
const SizePrefix prefix)
const
234 assert(prefix.size() == 0 || prefix.size() == 1);
235 return (prefix.size() == 0) ? size() : 0;
239 size_type dimension()
const
244 size_type maxNodeSize()
const
248 GeometryType elementType = *(gridView_.indexSet().types(0).begin());
250 return dofsPerCodim_[0] + dofsPerCodim_[1] * numFaces;
258 template<
typename It>
259 It indices(
const Node& node, It it)
const
261 const auto& gridIndexSet = gridView().indexSet();
262 const auto& element = node.element();
265 if (not(element.type().isCube()) and not(element.type().isSimplex()))
268 for(std::size_t i=0, end=node.size(); i<end; ++i, ++it)
270 Dune::LocalKey localKey = node.finiteElement().localCoefficients().localKey(i);
274 size_t codim = localKey.
codim();
276 *it = { codimOffset_[codim] +
277 dofsPerCodim_[codim] * gridIndexSet.subIndex(element, subentity, codim) + localKey.
index() };
285 std::array<size_t,dim+1> codimOffset_;
286 FiniteElementMap finiteElementMap_;
288 std::array<int,2> dofsPerCodim_ {{dim*(k-1)*3, dim+(k-1)}};
293template<
typename GV,
int k>
294class BrezziDouglasMariniNode :
297 static const int dim = GV::dimension;
301 using size_type = std::size_t;
302 using Element =
typename GV::template Codim<0>::Entity;
303 using FiniteElementMap =
typename Impl::BDMLocalFiniteElementMap<GV, dim, double, k>;
304 using FiniteElement = Impl::GlobalValuedLocalFiniteElement<Impl::ContravariantPiolaTransformator,
305 typename FiniteElementMap::FiniteElement,
308 BrezziDouglasMariniNode(
const FiniteElementMap* finiteElementMap) :
310 finiteElementMap_(finiteElementMap)
314 const Element& element()
const
323 const FiniteElement& finiteElement()
const
325 return finiteElement_;
329 void bind(
const Element& e)
332 finiteElement_.bind((finiteElementMap_->find(*element_)), e);
333 this->setSize(finiteElement_.size());
338 FiniteElement finiteElement_;
339 const Element* element_;
340 const FiniteElementMap* finiteElementMap_;
345namespace BasisFactory {
349template<std::
size_t k>
350class BrezziDouglasMariniPreBasisFactory
353 static const std::size_t requiredMultiIndexSize=1;
355 template<
class MultiIndex,
class Gr
idView>
356 auto makePreBasis(
const GridView& gridView)
const
357 -> BrezziDouglasMariniPreBasis<GridView, k, MultiIndex>
372template<std::
size_t k>
375 return Imp::BrezziDouglasMariniPreBasisFactory<k>();
393template<
typename GV,
int k>
394using BrezziDouglasMariniBasis = DefaultGlobalBasis<BrezziDouglasMariniPreBasis<GV, k, FlatMultiIndex<std::size_t>> >;
Describe position of one degree of freedom.
Definition: localkey.hh:21
unsigned int index() const
Return offset within subentity.
Definition: localkey.hh:66
unsigned int codim() const
Return codim of associated entity.
Definition: localkey.hh:60
unsigned int subEntity() const
Return number of associated subentity.
Definition: localkey.hh:54
Default exception for dummy implementations.
Definition: exceptions.hh:261
A Vector class with statically reserved memory.
Definition: reservedvector.hh:43
A few common exception classes.
GeometryType
Type representing VTK's entity geometry types.
Definition: common.hh:130
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
auto brezziDouglasMarini()
Create a pre-basis factory that can create a Brezzi-Douglas-Marini pre-basis.
Definition: brezzidouglasmarinibasis.hh:373
Dune namespace.
Definition: alignedallocator.hh:11
static const ReferenceElement & general(const GeometryType &type)
get general reference elements
Definition: referenceelements.hh:196