13#ifndef PARTITIONEDSPACE_HH
14#define PARTITIONEDSPACE_HH
21#include <boost/compressed_pair.hpp>
22#include <boost/iterator/transform_iterator.hpp>
35 namespace PartitionedSpaceDetail
50 typename Pair::first_const_reference
operator()(Pair
const& pair)
const
60 bool operator()(boost::compressed_pair<size_t,Data>
const& a, boost::compressed_pair<size_t,Data>
const& b)
62 return a.first() < b.first();
74 auto x = cell.geometry().center();
75 return x[0]+x[1] < 1? 0: 1;
92 if(codim==0)
return false;
93 if(codim==1)
return id==localFaceId;
97 if(localFaceId==0)
return (
id==0 ||
id==1);
98 if(localFaceId==1)
return (
id==0 ||
id==2);
99 if(localFaceId==2)
return (
id==2 ||
id==1);
106 if(localFaceId==0)
return (
id>=0 &&
id<3);
107 if(localFaceId==1)
return (
id==0 ||
id==3 ||
id==4);
108 if(localFaceId==2)
return (
id==1 ||
id==3 ||
id==5);
109 if(localFaceId==3)
return (
id==2 ||
id==4 ||
id==5);
114 if(localFaceId==0)
return (
id>=0 &&
id<3);
115 if(localFaceId==1)
return (
id==0 ||
id==1 ||
id==3);
116 if(localFaceId==2)
return (
id==0 ||
id==2 ||
id==3);
117 if(localFaceId==3)
return (
id==1 ||
id==2 ||
id==3);
125 static constexpr int defaultIndex = -94279;
127 template <
class Face>
130 size_t boundarySegmentIndex = face.boundarySegmentIndex();
131 if(boundarySegmentIndex < boundaryIds.size())
return boundaryIds[boundarySegmentIndex];
135 inline bool usedId(
int id, std::vector<int>
const& usedIds)
137 if (
id==defaultIndex)
return false;
138 return std::find(usedIds.begin(), usedIds.end(),
id) != usedIds.end();
141 template <
class Face>
142 inline bool considerFace(
Face const& face, std::vector<int>
const& boundaryIds, std::vector<int>
const& usedIds)
144 if(boundaryIds.empty())
return face.boundary();
155 template <
class Data,
class Gr
idView,
class Cell>
156 void treatBoundary(Data& data, GridView
const& gridView,
Cell const& cell,
int codim,
int subentity)
const
159 assert(cell.type().isSimplex());
161 for(
auto const& face: intersections(gridView,cell))
164 &&
onSimplexFace(GridView::dimension,codim,subentity,face.indexInInside()))
172 template <
class Policy>
175 return std::is_same<Policy,RestrictToBoundary>::value;
181 template <
class Data,
class Gr
idView,
class Cell>
void treatBoundary(Data&, GridView
const&,
Cell const&,
int,
int)
const {}
193 template <
class SFData>
231 template <
class Implementation,
237 typedef typename Implementation::Grid
Grid;
241 typedef typename Implementation::Combiner
Combiner;
242 typedef typename Implementation::Scalar
Scalar;
243 typedef typename Implementation::GridView
GridView;
262 typedef boost::compressed_pair<size_t,SFData> Data;
268 typedef boost::transform_iterator<First,typename std::vector<Data>::const_iterator> GlobalIndexIterator;
271 typedef std::vector<IndexPair>::const_iterator SortedIndexIterator;
273 static constexpr int dim = Grid::dimension;
321 GlobalIndexIterator(globIdx[0].begin(),
First()));
351 GlobalIndexIterator(globIdx[n].end(),
First()));
359 static std::vector<IndexPair> dummy;
455 return std::make_pair(
true, unrestrictedIndex);
473 size_t const nCells = indexSet.size(0);
475 globIdx.resize(nCells);
476 sortedIdx.resize(nCells);
495 using Tag =
decltype(tagger(
Cell()));
496 using Key = std::pair<Tag,Dune::GeometryType>;
497 using IncidenceData = std::tuple<std::vector<size_t>,int,
size_t>;
498 std::map<Key,IncidenceData>
count;
504 for(
auto const& cell : elements(
gridView))
506 size_t const cellIndex = indexSet.index(cell);
507 auto tag = tagger(cell);
513 sfs[cellIndex] = &sf;
519 globIdx[cellIndex].clear();
520 sortedIdx[cellIndex].clear();
527 size_t localNumberOfShapeFunctions = sf.size();
528 globIdx[cellIndex].resize(localNumberOfShapeFunctions);
529 sortedIdx[cellIndex].resize(localNumberOfShapeFunctions);
532 for(
size_t i=0; i<localNumberOfShapeFunctions; ++i)
534 Dune::GeometryType gt;
535 int subentity, codim, indexInSubentity;
537 implementation.entityIndex(cell,sf[i],i,gt,subentity,codim,indexInSubentity,sfData);
544 auto mi =
count.insert(std::pair(Key(tag,gt),
546 assert(mi!=
count.end());
549 std::get<0>(mi->second).push_back(gt_idx);
557 for (
auto& entry:
count)
560 auto& idxs = std::get<0>(entry.second);
561 int const dofPerEntity = std::get<1>(entry.second);
563 std::sort(idxs.begin(),idxs.end());
564 idxs.erase(std::unique(idxs.begin(),idxs.end()),idxs.end());
566 std::get<2>(entry.second) = start;
567 start += dofPerEntity*idxs.size();
575 for(
auto const& cell : elements(
gridView))
577 size_t const cellIndex = indexSet.index(cell);
578 auto tag = tagger(cell);
581 if (globIdx[cellIndex].empty())
585 auto const& localSfs = *sfs[cellIndex];
586 for(
size_t i=0; i<localSfs.size(); ++i)
588 Dune::GeometryType gt;
589 int subentity, codim, indexInSubentity;
591 implementation.entityIndex(cell,localSfs[i],i,gt,subentity,codim,indexInSubentity,sfData);
598 auto mi =
count.find(Key(tag,gt));
599 assert(mi!=
count.end());
601 auto const& [eIdx,dofPerEntity,start] = mi->second;
602 auto pos = std::lower_bound(begin(eIdx),end(eIdx),gt_idx);
603 assert(pos != end(eIdx));
604 int globalIndex = start + (pos-begin(eIdx))*dofPerEntity;
606 globIdx[cellIndex][i] = Data(globalIndex,sfData);
607 sortedIdx[cellIndex][i] = std::make_pair(globIdx[cellIndex][i].first(),i);
612 std::sort(sortedIdx[cellIndex].begin(),sortedIdx[cellIndex].end(),
FirstLess());
621 std::vector<size_t> idx(globIdx[cellIndex].
size());
622 for (
int j=0; j<idx.size(); ++j)
623 idx[j] = globIdx[cellIndex][j].first();
624 std::sort(idx.begin(),idx.end());
625 for (
int j=1; j<idx.size(); ++j)
626 assert(idx[j]>idx[j-1] || idx[j]<0);
637 std::vector<std::vector<Data>> globIdx;
642 std::vector<std::vector<IndexPair>> sortedIdx;
645 std::vector<ShapeFunctionSet const*> sfs;
682 template <
class Tagger,
class GV,
class ScalarType=
double>
A class for representing finite element functions.
A degrees of freedom manager for piecewise continuous FEFunctionSpace s of local polynomials.
Base::ShapeFunctionSet ShapeFunctionSet
static int const continuity
PiecewiseContinuousLagrangeMapper(GridView const &gridView, int order, Tagger const &tagger)
Constructor.
DEPRECATED. Use boost::iterator_range instead.
int count(Cell const &cell, int codim)
Computes the number of subentities of codimension c of a given entity.
typename GridView::template Codim< 0 >::Entity Cell
The type of cells (entities of codimension 0) in the grid view.
typename GridView::Intersection Face
The type of faces in the grid view.
Dune::FieldVector< T, n > max(Dune::FieldVector< T, n > x, Dune::FieldVector< T, n > const &y)
Componentwise maximum.
Lagrange Finite Elements.
constexpr bool isRestriction()
bool considerFace(Face const &face, std::vector< int > const &boundaryIds, std::vector< int > const &usedIds)
int getBoundaryId(Face const &face, std::vector< int > const &boundaryIds)
bool usedId(int id, std::vector< int > const &usedIds)
bool onSimplexFace(int dim, int codim, int id, int localFaceId)
check if a given subentity E is part of a certain simplex face F
RangeView< It > rangeView(It first, It last)
Convenience function for constructing range views on the fly.
typename GetScalar< Type >::type ScalarType
Extracts the scalar field type from linear algebra data types.
A comparator functor that supports sorting std::pair by their first component.
void treatBoundary(Data &, GridView const &, Cell const &, int, int) const
A functor for extracting the first component of a boost compressed pair.
Pair::first_const_reference operator()(Pair const &pair) const
Pair::first_const_reference result_type
bool operator()(boost::compressed_pair< size_t, Data > const &a, boost::compressed_pair< size_t, Data > const &b)
void treatBoundary(Data &data, GridView const &gridView, Cell const &cell, int codim, int subentity) const
std::vector< int > const usedIds
RestrictToBoundary(RestrictToBoundary const &other)
std::vector< int > const boundaryIds
RestrictToBoundary(std::vector< int > const &boundaryIds_, std::vector< int > const &usedIds_)
int operator()(Cell const &cell) const
FunctionSpaceElement< FEFunctionSpace< PiecewiseContinuousLagrangeMapper >, m > type