Dune-Functions 2.11
Loading...
Searching...
No Matches
brezzidouglasmarinibasis.hh
Go to the documentation of this file.
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
8#define DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
9
10#include <array>
11#include <dune/common/exceptions.hh>
12#include <dune/geometry/referenceelements.hh>
13
14#include <dune/localfunctions/common/virtualinterface.hh>
15#include <dune/localfunctions/common/virtualwrappers.hh>
16
17#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube2d.hh>
18#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1cube3d.hh>
19#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini1simplex2d.hh>
20#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2cube2d.hh>
21#include <dune/localfunctions/brezzidouglasmarini/brezzidouglasmarini2simplex2d.hh>
22
27
28namespace Dune {
29namespace Functions {
30
31namespace Impl {
32
33 template<int dim, typename D, typename R, std::size_t k>
34 struct BDMSimplexLocalInfo
35 {
36 static_assert((AlwaysFalse<D>::value),"The requested type of BDM element is not implemented, sorry!");
37 };
38
39 template<typename D, typename R>
40 struct BDMSimplexLocalInfo<2,D,R,1>
41 {
42 using FiniteElement = BDM1Simplex2DLocalFiniteElement<D,R>;
43 static const std::size_t Variants = 8;
44 };
45
46 template<typename D, typename R>
47 struct BDMSimplexLocalInfo<2,D,R,2>
48 {
49 using FiniteElement = BDM2Simplex2DLocalFiniteElement<D,R>;
50 static const std::size_t Variants = 8;
51 };
52
53 template<int dim, typename D, typename R, std::size_t k>
54 struct BDMCubeLocalInfo
55 {
56 static_assert((AlwaysFalse<D>::value),"The requested type of BDM element is not implemented, sorry!");
57 };
58
59 template<typename D, typename R>
60 struct BDMCubeLocalInfo<2,D,R,1>
61 {
62 using FiniteElement = BDM1Cube2DLocalFiniteElement<D,R>;
63 static const std::size_t Variants = 16;
64 };
65
66 template<typename D, typename R>
67 struct BDMCubeLocalInfo<2,D,R,2>
68 {
69 using FiniteElement = BDM2Cube2DLocalFiniteElement<D,R>;
70 static const std::size_t Variants = 16;
71 };
72
73 template<typename D, typename R>
74 struct BDMCubeLocalInfo<3,D,R,1>
75 {
76 using FiniteElement = BDM1Cube3DLocalFiniteElement<D,R>;
77 static const std::size_t Variants = 64;
78 };
79
80 template<typename GV, typename R, std::size_t k>
81 class BDMLocalFiniteElementMap
82 {
83 using D = typename GV::ctype;
84 constexpr static auto dim = GV::dimension;
85 using CubeFiniteElement = typename BDMCubeLocalInfo<dim, D, R, k>::FiniteElement;
86 using SimplexFiniteElement = typename BDMSimplexLocalInfo<dim, D, R, k>::FiniteElement;
87
88 public:
89
90 using T = LocalBasisTraits<D, dim, FieldVector<D,dim>, R, dim, FieldVector<R,dim>, FieldMatrix<D,dim,dim> >;
91 using FiniteElement = LocalFiniteElementVirtualInterface<T>;
92
93 BDMLocalFiniteElementMap(const GV& gv)
94 : is_(&(gv.indexSet())), orient_(gv.size(0))
95 {
96 update(gv);
97 }
98
99 void update(const GV& gv)
100 {
101 is_ = &(gv.indexSet());
102 orient_.resize(gv.size(0));
103
104 cubeVariant_.resize(BDMCubeLocalInfo<dim, D, R, k>::Variants);
105 simplexVariant_.resize(BDMSimplexLocalInfo<dim, D, R, k>::Variants);
106
107 // create all variants
108 for (size_t i = 0; i < cubeVariant_.size(); i++)
109 cubeVariant_[i] = std::make_shared<LocalFiniteElementVirtualImp<CubeFiniteElement> >(CubeFiniteElement(i));
110
111 for (size_t i = 0; i < simplexVariant_.size(); i++)
112 simplexVariant_[i] = std::make_shared<LocalFiniteElementVirtualImp<SimplexFiniteElement> >(SimplexFiniteElement(i));
113
114 // compute orientation for all elements
115 // loop once over the grid
116 for(const auto& cell : elements(gv))
117 {
118 unsigned int myId = is_->index(cell);
119 orient_[myId] = 0;
120
121 for (const auto& intersection : intersections(gv,cell))
122 {
123 if (intersection.neighbor() && (is_->index(intersection.outside()) > myId))
124 orient_[myId] |= (1 << intersection.indexInInside());
125 }
126 }
127 }
128
130 template<class EntityType>
131 const FiniteElement& find(const EntityType& e) const
132 {
133 if (e.type().isCube())
134 return *cubeVariant_[orient_[is_->index(e)]];
135 else
136 return *simplexVariant_[orient_[is_->index(e)]];
137 }
138
139 private:
140 std::vector<std::shared_ptr<LocalFiniteElementVirtualImp<CubeFiniteElement> > > cubeVariant_;
141 std::vector<std::shared_ptr<LocalFiniteElementVirtualImp<SimplexFiniteElement> > > simplexVariant_;
142 const typename GV::IndexSet* is_;
143 std::vector<unsigned char> orient_;
144 };
145
146
147} // namespace Impl
148
149
150// *****************************************************************************
151// This is the reusable part of the basis. It contains
152//
153// BrezziDouglasMariniPreBasis
154// BrezziDouglasMariniNode
155//
156// The pre-basis allows to create the others and is the owner of possible shared
157// state. These components do _not_ depend on the global basis and local view
158// and can be used without a global basis.
159// *****************************************************************************
160
161template<typename GV, int k>
163
164template<typename GV, int k>
166 public LeafPreBasisMapperMixin<GV>
167{
168 using Base = LeafPreBasisMapperMixin<GV>;
169 static const int dim = GV::dimension;
170
171 // Degrees of freedom per subentity
172 static MCMGLayout dofLayout()
173 {
174 return [](GeometryType gt, size_t gridDim) -> size_t {
175 if (gt.dim() == gridDim)
176 return dim*(k-1)*3;
177 if (gt.dim() == gridDim-1)
178 return dim+(k-1);
179 return 0;
180 };
181 }
182
183 using FiniteElementMap = typename Impl::BDMLocalFiniteElementMap<GV, double, k>;
184
185public:
186
188 using GridView = GV;
189 using size_type = std::size_t;
190
192
195 Base(gv, dofLayout()),
197 {
198 // There is no inherent reason why the basis shouldn't work for grids with more than one
199 // element types. Somebody simply has to sit down and implement the missing bits.
200 if (gv.indexSet().types(0).size() > 1)
201 DUNE_THROW(Dune::NotImplemented, "Brezzi-Douglas-Marini basis is only implemented for grids with a single element type");
202 }
203
204 /* \brief Update the stored grid view, to be called if the grid has changed */
205 void update (const GridView& gv)
206 {
207 Base::update(gv);
208 finiteElementMap_.update(gv);
209 }
210
215 {
216 return Node{&finiteElementMap_};
217 }
218
219protected:
220 FiniteElementMap finiteElementMap_;
221};
222
223
224
225template<typename GV, int k>
227 public LeafBasisNode
228{
229public:
230
231 using size_type = std::size_t;
232 using Element = typename GV::template Codim<0>::Entity;
233 using FiniteElementMap = typename Impl::BDMLocalFiniteElementMap<GV, double, k>;
234 using FiniteElement = Impl::GlobalValuedLocalFiniteElement<Impl::ContravariantPiolaTransformator,
235 typename FiniteElementMap::FiniteElement,
236 Element>;
237
238 BrezziDouglasMariniNode(const FiniteElementMap* finiteElementMap) :
239 element_(nullptr),
240 finiteElementMap_(finiteElementMap)
241 {}
242
244 const Element& element() const
245 {
246 return *element_;
247 }
248
254 {
255 return finiteElement_;
256 }
257
259 void bind(const Element& e)
260 {
261 element_ = &e;
262 finiteElement_.bind((finiteElementMap_->find(*element_)), e);
263 this->setSize(finiteElement_.size());
264 }
265
266protected:
267
271};
272
273
274
275namespace BasisFactory {
276
284template<std::size_t k>
286{
287 return [](const auto& gridView) {
288 return BrezziDouglasMariniPreBasis<std::decay_t<decltype(gridView)>, k>(gridView);
289 };
290}
291
292} // end namespace BasisFactory
293
294
295
296// *****************************************************************************
297// This is the actual global basis implementation based on the reusable parts.
298// *****************************************************************************
299
307template<typename GV, int k>
309
310} // end namespace Functions
311} // end namespace Dune
312
313
314#endif // DUNE_FUNCTIONS_FUNCTIONSPACEBASES_BREZZIDOUGLASMARINIBASIS_HH
auto brezziDouglasMarini()
Create a pre-basis factory that can create a Brezzi-Douglas-Marini pre-basis.
Definition brezzidouglasmarinibasis.hh:285
auto elements(const SubDomainGridView< HostGridView > &subDomainGridView)
ADL findable access to element range for a SubDomainGridView.
Definition subdomain.hh:487
auto intersections(const SubDomainGridView< HostGridView > &subDomainGridView, const Element &element)
ADL findable access to intersection range for an element of a SubDomainGridView.
Definition subdomain.hh:510
Definition monomialset.hh:19
Definition monomialset.hh:19
DefaultGlobalBasis< BrezziDouglasMariniPreBasis< GV, k > > BrezziDouglasMariniBasis
Basis of a scalar k-th-order BDM finite element space on simplex and cube grids.
Definition brezzidouglasmarinibasis.hh:308
Definition argyrisbasis.hh:926
Definition brezzidouglasmarinibasis.hh:228
const FiniteElement & finiteElement() const
Return the LocalFiniteElement for the element we are bound to.
Definition brezzidouglasmarinibasis.hh:253
typename Impl::BDMLocalFiniteElementMap< GV, double, k > FiniteElementMap
Definition brezzidouglasmarinibasis.hh:233
typename GV::template Codim< 0 >::Entity Element
Definition brezzidouglasmarinibasis.hh:232
Impl::GlobalValuedLocalFiniteElement< Impl::ContravariantPiolaTransformator, typename FiniteElementMap::FiniteElement, Element > FiniteElement
Definition brezzidouglasmarinibasis.hh:234
const FiniteElementMap * finiteElementMap_
Definition brezzidouglasmarinibasis.hh:270
std::size_t size_type
Definition brezzidouglasmarinibasis.hh:231
FiniteElement finiteElement_
Definition brezzidouglasmarinibasis.hh:268
const Element * element_
Definition brezzidouglasmarinibasis.hh:269
void bind(const Element &e)
Bind to element.
Definition brezzidouglasmarinibasis.hh:259
BrezziDouglasMariniNode(const FiniteElementMap *finiteElementMap)
Definition brezzidouglasmarinibasis.hh:238
const Element & element() const
Return current element, throw if unbound.
Definition brezzidouglasmarinibasis.hh:244
Definition brezzidouglasmarinibasis.hh:167
std::size_t size_type
Definition brezzidouglasmarinibasis.hh:189
BrezziDouglasMariniNode< GV, k > Node
Definition brezzidouglasmarinibasis.hh:191
Node makeNode() const
Create tree node.
Definition brezzidouglasmarinibasis.hh:214
GV GridView
The grid view that the FE space is defined on.
Definition brezzidouglasmarinibasis.hh:188
BrezziDouglasMariniPreBasis(const GridView &gv)
Constructor for a given grid view object.
Definition brezzidouglasmarinibasis.hh:194
FiniteElementMap finiteElementMap_
Definition brezzidouglasmarinibasis.hh:220
void update(const GridView &gv)
Definition brezzidouglasmarinibasis.hh:205
Global basis for given pre-basis.
Definition defaultglobalbasis.hh:53
void update(const GridView &gv)
Update the stored GridView.
Definition leafprebasismappermixin.hh:101
LeafPreBasisMapperMixin(const GridView &gv, Dune::MCMGLayout layout)
Construct from GridView and local DOF layout.
Definition leafprebasismappermixin.hh:74
void setSize(const size_type size)
Definition nodes.hh:197
Definition nodes.hh:218