KASKADE 7 development version
boundaryspace.hh
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the library KASKADE 7 */
4/* https://www.zib.de/research/projects/kaskade7-finite-element-toolbox */
5/* */
6/* Copyright (C) 2002-2013 Zuse Institute Berlin */
7/* */
8/* KASKADE 7 is distributed under the terms of the ZIB Academic License. */
9/* see $KASKADE/academic.txt */
10/* */
11/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
12
13#ifndef BOUNDARY_SPACE_HH
14#define BOUNDARY_SPACE_HH
15
16#include <map>
17#include <utility>
18
19#include <dune/common/fvector.hh>
20
21#include "fem/scalarspace.hh"
22
33namespace Kaskade
34{
35 // forward declarations
37 template <class,class> class ContinuousLagrangeMapper;
38 template <class,class,class> class ContinuousLagrangeMapperImplementation;
39 template <class,class> class DiscontinuousLagrangeMapper;
40 template <class,class> class ContinuousHierarchicMapper;
41 template <class,class> class DiscontinuousHierarchicMapper;
42 template <class,class,class> class ContinuousHierarchicMapperImplementation;
43 template <class,class> class ContinuousHierarchicExtensionMapper;
44 template <class,class,class> class ContinuousHierarchicExtensionMapperImplementation;
45
46 template <class,int,class> class LagrangeSimplexShapeFunctionSet;
47 template <class,int,class> class HierarchicSimplexShapeFunctionSet;
48 template <class,int,class> class HierarchicExtensionSimplexShapeFunctionSet;
50
51 namespace BoundarySpace_Detail
52 {
53 using namespace ScalarSpaceDetail;
54
56 template <class MapperImplementation> struct ChooseMapper;
57
58 template <class Scalar, class GridView>
59 struct ChooseMapper<ContinuousLagrangeMapper<Scalar,GridView> >
60 {
62 };
63
64 struct BOUNDARY_MAPPERS_ARE_NOT_YET_IMPLEMENTED_FOR_DISCONTINUOUS_SPACES;
65
66 template <class Scalar, class GridView>
67 struct ChooseMapper<DiscontinuousLagrangeMapper<Scalar,GridView> >
68 {
69 typedef BOUNDARY_MAPPERS_ARE_NOT_YET_IMPLEMENTED_FOR_DISCONTINUOUS_SPACES type;
70 };
71
72 template <class Scalar, class GridView>
73 struct ChooseMapper<ContinuousHierarchicMapper<Scalar,GridView> >
74 {
76 };
77
78 template <class Scalar, class GridView>
80 {
82 };
83
84 template <class Scalar, class GridView>
86 {
87 typedef BOUNDARY_MAPPERS_ARE_NOT_YET_IMPLEMENTED_FOR_DISCONTINUOUS_SPACES type;
88 };
89
90 template <class Mapper> struct GetSFDataType;
91
92 template <class Scalar, class GridView>
93 struct GetSFDataType<ContinuousLagrangeMapper<Scalar,GridView> >
94 {
95 typedef boost::compressed_pair<bool,Empty> type;
96 };
97
98 template <class Scalar, class GridView>
99 struct GetSFDataType<ContinuousHierarchicMapper<Scalar,GridView> >
100 {
101 typedef boost::compressed_pair<bool,int> type;
102 };
103
104 template <class Scalar, class GridView>
106 {
107 typedef boost::compressed_pair<bool,int> type;
108 };
109
111 template <class Mapper> struct ShapeFunctionSetRestriction;
112
113 template <class Scalar, class GridView, class Data>
115 {
117 };
118
119 template <class Scalar, class GridView, class Data>
121 {
123 };
124
125 template <class Scalar, class GridView, class Data>
127 {
129 };
130
131 }
132
159 template <template <class,class> class Implementation_, class Scalar_, class GridView_>
160 class [[deprecated]]
161 BoundaryMapper : public UniformScalarMapper<typename BoundarySpace_Detail::ChooseMapper<Implementation_<Scalar_,GridView_>>::type,
162 typename BoundarySpace_Detail::GetSFDataType<Implementation_<Scalar_,GridView_>>::type>
163 {
167
168 public:
169 typedef Scalar_ Scalar;
170 typedef GridView_ GridView;
173 static int const continuity = 0;
174 static constexpr int dim = GridView::dimension;
175
181 template <int m>
182 struct Element
183 {
185 };
186
193 BoundaryMapper(GridView const& gridView, int order):
194 Base(Implementation(gridView,order))
195 {
196 assert(order >= 1);
197 }
198
207 BoundaryMapper(GridView const& gridView, int order, std::vector<int> const& boundaryIds_, std::vector<int> const& usedIds_)
208 : Base(Implementation(gridView,order,ScalarSpaceDetail::RestrictToBoundary(boundaryIds_,usedIds_)))
209 {
210 assert(order>=1);
211 }
212
213 template <class T, class Functor>
214 BoundaryMapper(GridView const& gridView, int order, std::vector<T> const& boundaryIds_, std::vector<T> const& usedIds_, Functor boundaryIdsToInts)
215 : Base(Implementation(gridView,order,ScalarSpaceDetail::RestrictToBoundary(boundaryIdsToInts(boundaryIds_),boundaryIdsToInts(usedIds_))))
216 {
217 assert(order>=1);
218 }
219
220 bool inDomain(typename GridView::Intersection const& face) const
221 {
222 return ScalarSpaceDetail::considerFace(face,this->implementation.boundaryIds,this->implementation.usedIds);
223 }
224
230 int numFaces() {
231 int nFaces = 0;
232 forEachBoundaryFace(this->implementation.gridView(),[&](typename GridView::Intersection const& intersection) {
233 if(inDomain(intersection)) ++nFaces;
234 });
235 return nFaces;
236 }
237 };
238
239
243 namespace ScalarSpaceDetail
244 {
246 template <template <class,class,class> class MapperImplementation, class Scalar_, class GridView_, class SFData>
247 class MapperPolicy<MapperImplementation<Scalar_,GridView_,RestrictToBoundary>, boost::compressed_pair<bool,SFData> >
248 {
249 typedef Scalar_ Scalar;
250 typedef GridView_ GridView;
251 typedef MapperImplementation<Scalar,GridView,RestrictToBoundary> Implementation;
252 typedef typename Implementation::Grid Grid;
253 typedef typename GridView::IndexSet IndexSet;
254 typedef typename Grid::template Codim<0>::Entity Cell;
255 typedef typename Implementation::ShapeFunctionSet ShapeFunctionSet;
256 typedef boost::compressed_pair<bool,SFData> Data;
257 typedef typename BoundarySpace_Detail::ShapeFunctionSetRestriction<Implementation>::type ShapeFunctionSet_Restricted;
258
259 protected:
260 static constexpr bool boundaryPolicy = true;
261
262 explicit MapperPolicy(Implementation const& impl) : implementation(impl),
263 insertionIndex(0), consideredCells(implementation.indexSet().size(0))
264 {}
265
266 template <class GlobalIndices, class SortedIndices>
267 void initIndices(std::map<Dune::GeometryType,size_t>& startIndex, GlobalIndices& globIdx, SortedIndices& sortedIdx)
268 {
269 insertionIndex = 0;
270 globIdx.clear();
271 globIdx.resize(implementation.indexSet().size(0));
272 sortedIdx.clear();
273 sortedIdx.resize(implementation.indexSet().size(0));
274
275 consideredCells.clear();
276 consideredCells.resize(implementation.indexSet().size(0),false);
277 shapeFunctionSets.clear();
278 shapeFunctionSets.resize(implementation.indexSet().size(0));
279
280 size_t n = 0;
281 for (int codim=0; codim<=Grid::dimension; ++codim)
282 for(auto const& geoType: implementation.indexSet().types(codim))
283 {
284 startIndex[geoType] = n;
285 n += implementation.indexSet().size(geoType) * implementation.dofOnEntity(geoType);
286 }
287
288 indexMapper.clear();
289 indexMapper.resize(n,std::make_pair(false,0));
290
291 restrictCells();
292 }
293
294 template <class GlobalIndices, class SortedIndices>
295 void computeIndices(Cell const& cell, std::map<Dune::GeometryType,size_t>& startIndex, GlobalIndices& globIdx, SortedIndices& sortedIdx, size_t cellIndex)
296 {
297 // No evaluation will be done on faces that do not intersect the boundary.
298 // If evaluation should be allowed make sure to set a, possibly empty, vector using setRestriction()
299 std::vector<int> idRestriction;
300 ShapeFunctionSet& sf = static_cast<UniformScalarMapper<Implementation,Data>&>(*this).shapefunctions_non_const(cell);
301 if(!consideredCells[cellIndex])
302 {
303 if(cell.type().isSimplex()) static_cast<ShapeFunctionSet_Restricted&>(sf).setRestriction(idRestriction);
304 return;
305 }
306
307 int nominalOrder; // unused
308
309 // step through all shape functions.
310 Dune::GeometryType gt;
311 int subentity, codim, indexInSubentity;
312 size_t realLocalId = 0;
313 for(size_t i=0; i<sf.size(); ++i)
314 {
315 std::tie(nominalOrder,codim,subentity,indexInSubentity) = sf[i].location();
316
317 if(codim == 0) continue;
318
319 Data data(false);
320 assert(cell.type().isSimplex());
321 implementation.entityIndex(cell,sf[i],i,gt,subentity,codim,indexInSubentity,data);
322 if(data.first())
323 {
324 std::pair<bool,size_t> contains = std::make_pair(false,0);
325 if(codim > 0)
326 {
327 // compute the global index of the subentity to which the shape function is associated
328 int gt_idx = subIndex(implementation.indexSet(),cell,codim,subentity);
329
330 std::map<Dune::GeometryType,size_t>::const_iterator mi = startIndex.find(gt);
331 assert(mi!=startIndex.end());
332
333 // On the boundary codim-0-entities do vanish
334 // Shape functions associated with codim-1-entities are unique
335 // thus we only have to check shape functions associated with entities
336 // of codim > 1
337 size_t unrestrictedIndex = mi->second+gt_idx*implementation.dofOnEntity(gt)+indexInSubentity;
338 if(codim > 1) {
339 contains = indexMapper[unrestrictedIndex];
340 if(!contains.first) indexMapper[unrestrictedIndex] = std::make_pair(true,insertionIndex);
341 } else {
342 // for shapefunctions on codim 1 entities also store the restricted index (originally this map was only provided and used internally for codim >1 shapefunctions),
343 indexMapper[unrestrictedIndex] = std::make_pair(true,insertionIndex);
344 }
345 }
346
347 if(!contains.first) globIdx[cellIndex].push_back( boost::compressed_pair<size_t,Data>(insertionIndex,data) );
348 else globIdx[cellIndex].push_back( boost::compressed_pair<size_t,Data>(contains.second,data) );
349
350 sortedIdx[cellIndex].push_back( std::make_pair(globIdx[cellIndex].back().first(),realLocalId) );
351
352 idRestriction.push_back(i);
353
354 if(!contains.first) ++insertionIndex;
355 ++realLocalId;
356 }
357 }
358
359 if(cell.type().isSimplex()) static_cast<ShapeFunctionSet_Restricted&>(sf).setRestriction(idRestriction);
360 }
361
362 template <class Container, class ShapeFunctionSet>
363 void initShapeFunctionSet(Container& sfs, ShapeFunctionSet const& sf, size_t cellIndex)
364 {
365 // TODO: probably it is not the most efficient idea to create for each cell an own restricted shape function set
366 // the next line was replaced since it caused a memory leak
367 //sfs[cellIndex] = new ShapeFunctionSet_Restricted(static_cast<ShapeFunctionSet_Restricted const&>(sf),nullptr); // cache shape function set
368 assert(cellIndex < shapeFunctionSets.size());
369 shapeFunctionSets[cellIndex] = std::make_unique<ShapeFunctionSet_Restricted>(static_cast<ShapeFunctionSet_Restricted const&>(sf),nullptr);
370 sfs[cellIndex] = shapeFunctionSets[cellIndex].get();
371 }
372
373 Implementation implementation;
374
375 public:
385 std::pair<bool,size_t> unrestrictedToRestrictedIndex(std::vector<std::pair<bool,size_t>>::size_type unrestrictedIndex) const {
386 assert(unrestrictedIndex < indexMapper.size());
387 return indexMapper[unrestrictedIndex];
388 }
389
390 private:
391 void restrictCells()
392 {
393 auto cend = implementation.gridView().template end<0>();
394 for(auto cell = implementation.gridView().template begin<0>(); cell!=cend; ++cell)
395 {
396 size_t cellIndex = implementation.indexSet().index(*cell);
397 auto fend = implementation.gridView().iend(*cell);
398 for(auto face = implementation.gridView().ibegin(*cell); face!=fend; ++face)
399 if(ScalarSpaceDetail::considerFace(*face,implementation.boundaryIds,implementation.usedIds))
400 consideredCells[cellIndex] = true;
401 }
402 }
403
404 size_t insertionIndex;
405 std::vector<bool> consideredCells;
406 // use the global numbering of standard spaces for fast identification of shared degrees of freedoms
407 std::vector<std::pair<bool,size_t> > indexMapper;
408 std::vector<std::unique_ptr<ShapeFunctionSet>> shapeFunctionSets; //store non-const copies of restricted shape function sets
409 };
410
411 } // end namespace ScalarSpaceDetail
415} // end namespace Kaskade
416
417#endif
A local to global mapper implementation for boundary spaces, with functions defined on the domain bou...
BoundarySpace_Detail::ShapeFunctionSetRestriction< Implementation >::type ShapeFunctionSetImplementation
bool inDomain(typename GridView::Intersection const &face) const
BoundaryMapper(GridView const &gridView, int order, std::vector< T > const &boundaryIds_, std::vector< T > const &usedIds_, Functor boundaryIdsToInts)
A degrees of freedom manager for globally continuous FEFunctionSpace s of piecewise polynomials.
A degrees of freedom manager for globally continuous FEFunctionSpace s of piecewise polynomials.
A degrees of freedom manager for globally continuous FEFunctionSpace s of piecewise polynomials.
A degrees of freedom manager for FEFunctionSpace s of piecewise polynomials of order Order.
A degrees of freedom manager for FEFunctionSpace s of piecewise polynomials of order Order.
A class for representing finite element functions.
Restricted shape function set. Introduces a new local ordering for the shape functions....
Base class for uniform scalar local to global mappers.
Definition: scalarspace.hh:205
size_t subIndex(IndexSet const &is, Cell const &cell, int codim, int subentity)
Definition: fixdune.hh:704
int numFaces()
numFaces: Counts number of faces on which this boundaryMapper is defined. This costs some time so use...
BoundaryMapper(GridView const &gridView, int order, std::vector< int > const &boundaryIds_, std::vector< int > const &usedIds_)
BoundaryMapper: Create a boundary mapper over parts of the boundary.
BoundaryMapper(GridView const &gridView, int order)
BoundaryMapper: Create a boundary mapper over the entire boundary.
void forEachBoundaryFace(GridView const &gridView, Functor functor)
iterates over each boundary face and applies functor to face. Each boundary face is visited exactly o...
Definition: forEach.hh:88
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
Definition: gridBasics.hh:35
bool considerFace(Face const &face, std::vector< int > const &boundaryIds, std::vector< int > const &usedIds)
Definition: scalarspace.hh:123
Type of the FunctionSpaceElement, associated to the FEFunctionSpace.
FunctionSpaceElement< FEFunctionSpace< BoundaryMapper >, m > type
ContinuousHierarchicExtensionMapperImplementation< Scalar, GridView, RestrictToBoundary > type
ContinuousHierarchicMapperImplementation< Scalar, GridView, RestrictToBoundary > type
ContinuousLagrangeMapperImplementation< Scalar, GridView, RestrictToBoundary > type
BOUNDARY_MAPPERS_ARE_NOT_YET_IMPLEMENTED_FOR_DISCONTINUOUS_SPACES type
BOUNDARY_MAPPERS_ARE_NOT_YET_IMPLEMENTED_FOR_DISCONTINUOUS_SPACES type
Choose implementation for mapper. Not the best design, but works...
RestrictedShapeFunctionSet< HierarchicSimplexShapeFunctionSet< typename GridView::Grid::ctype, GridView::Grid::dimension, Scalar > > type
RestrictedShapeFunctionSet< HierarchicExtensionSimplexShapeFunctionSet< typename GridView::Grid::ctype, GridView::Grid::dimension, Scalar > > type
RestrictedShapeFunctionSet< LagrangeSimplexShapeFunctionSet< typename GridView::Grid::ctype, GridView::Grid::dimension, Scalar > > type
get restricted shape function set for simplicial grid