KASKADE 7 development version
morleyspace.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) 2014-2020 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 MORLEYSPACE_HH
14#define MORLEYSPACE_HH
15
16#include <numeric>
17
18#include "fem/converter.hh"
19#include "fem/functionspace.hh"
21#include "fem/views.hh"
22
23//---------------------------------------------------------------------
24
25namespace Kaskade
26{
37 template <class ScalarType, class GV>
39 {
40 public:
42
43
44 typedef GV GridView;
45 typedef typename GridView::Grid Grid;
46 typedef typename GridView::IndexSet IndexSet;
47
48 static int const dim = Grid::dimension;
49 static_assert(dim==2, "Morley elements implemented just for 2D problems.");
50 static int const dimw = Grid::template Codim<0>::Entity::Geometry::coorddimension;
51
52
56 static bool const globalSupport = false;
57
58
60 static int const continuity = -1;
62
63 typedef std::pair<size_t,int> IndexPair;
64 typedef std::vector<IndexPair>::const_iterator SortedIndexIterator;
66
67 typedef typename Grid::template Codim<0>::Entity Cell;
69
71
75 MorleyMapper(GridView const& gridView_)
76 : gridView(gridView_)
77 , indexSet(gridView_.indexSet())
78 {
79 update();
80 }
81
82 virtual ~MorleyMapper() {}
83
87 int maxOrder() const
88 {
89 return 2;
90 }
91
92 ShapeFunctionSet const& shapefunctions(Cell const& cell) const
93 {
94 assert(cell.type().isSimplex());
95 return lagrangeShapeFunctionSet<typename Grid::ctype,dim,Scalar>(cell.type(),2);
96 }
97
98 ShapeFunctionSet const& shapefunctions(size_t /*n*/) const
99 {
100 return lagrangeShapeFunctionSet<typename Grid::ctype,dim,Scalar>(Dune::GeometryType(Dune::GeometryType::simplex,dim),2);
101 }
102
107 {
108 return GlobalIndexRange(globIdx[0].begin(),globIdx[0].end());
109 }
110
117 {
118 return globalIndices(indexSet.index(cell));
119 }
120
127 {
128 return GlobalIndexRange(globIdx[n].begin(),globIdx[n].end());
129 }
130
135 {
136 static std::vector<IndexPair> dummy; // empty
137 return SortedIndexRange(dummy.begin(),dummy.end());
138 }
139
144 {
145 return sortedIndices(indexSet().index(cell));
146 }
147
152 {
153 return SortedIndexRange(sortedIdx[n].begin(),sortedIdx[n].end());
154 }
155
161 size_t size() const
162 {
163 return indexSet.size(dim-1) + indexSet.size(dim);
164 }
165
173
174
175
185 {
186 public:
189 Combiner(Cell const& cell, GridView const& gv, IndexSet const& is)
190 {
191 // Compute K by solving the interpolation problem. First evaluate the quadratic
192 // shape functions and their gradients at the vertices and the edge midpoints.
193 Converter psi(cell);
194 ShapeFunctionSet const& sfs = lagrangeShapeFunctionSet<typename Grid::ctype,dim,Scalar>(cell.type(),2);
195 assert(sfs.size() == 6); // we expect 6 shape functions for 2D quadratic Morley elements
196
197 auto const& refTriangle = Dune::ReferenceElements<typename Grid::ctype,dim>::simplex();
198 auto cellIndex = is.index(cell);
199
200 // We evaluate normal derivatives of global shape functions on edge midpoints and their
201 // values on vertices, and enter that into the evaluation matrix K. This is later inverted
202 // to give the interpolation matrix.
203 // Start with gradients at edge midpoints.
204 for (auto edge=gv.ibegin(cell); edge!=gv.iend(cell); ++edge)
205 {
206 int const j = edge->indexInInside();
207 auto const xi = refTriangle.position(j,1); // edge midpoint in cell local coordinates
208 psi.setLocalPosition(xi);
209
210 // Compute a globally unique normal of the edge, by switching the outer normal
211 // orientation if the neighbor cell's index is less than ours.
212 auto normal = edge->centerUnitOuterNormal();
213 if (edge->neighbor() && is.index(edge->outside()) < cellIndex)
214 normal *= -1;
215
216 for (int i=0; i<sfs.size(); ++i)
217 {
218 // Evaluate the shape function's gradient at the edge midpoint, and convert it to
219 // the gradient of the global shape function on the actual element.
220 VariationalArg<Scalar,dim,1> dsf(0,sfs[i].evaluateDerivative(xi));
222
223 // Compute and enter the directional derivative.
224 K[j][i] = dsfw.derivative[0] * normal;
225 }
226 }
227
228 // Next evaluate values at vertices.
229 for (int j=0; j<3; ++j)
230 {
231 auto xi = refTriangle.position(j,2); // vertex position in local coordinates
232 psi.setLocalPosition(xi);
233
234 for (int i=0; i<sfs.size(); ++i)
235 {
236 // Evaluate the shape function's value at the vertex, and convert it to
237 // the value of the global shape function on the actual element.
238 VariationalArg<Scalar,dim,1> sf(sfs[i].evaluateFunction(xi));
240 K[j+3][i] = sfw.value;
241 }
242 }
243
244 K.invert();
245 }
246
251 template <class Matrix>
252 void rightTransform(Matrix& A) const
253 {
254 // multiply from right -> modify columns
255 A.rightmultiply(K);
256 }
257
259 template <int n, int m>
260 void rightTransform(std::vector<VariationalArg<Scalar,n,m>>& vs) const
261 {
262 assert(vs.size()==6);
263 std::vector<VariationalArg<Scalar,n,m>> phis(6);
264
265 for (int i=0; i<6; ++i)
266 {
267 phis[i].value = 0;
268 phis[i].derivative = 0;
269 phis[i].hessian = 0;
270
271 // form linear combinations of shape functions leading to global ansatz functions
272 for (int j=0; j<6; ++j)
273 {
274 phis[i].value += K[j][i] * vs[j].value;
275 phis[i].derivative += K[j][i] * vs[j].derivative;
276 phis[i].hessian += K[j][i] * vs[j].hessian;
277 }
278 }
279
280 // return result
281 vs.swap(phis);
282 }
283
288 template <class Matrix>
289 void leftPseudoInverse(Matrix& A) const
290 {
292 Kinv.invert();
293 A.leftmultiply(Kinv);
294 }
295
297 operator Dune::BCRSMatrix<Dune::FieldMatrix<Scalar,1,1>>() const
298 {
299 std::cerr << "not implemented yet\n";
300 abort();
301 }
302
303 private:
304 Dune::FieldMatrix<Scalar,6,6> K; // the interpolation matrix K
305 };
306
312 Combiner combiner(Cell const& cell, size_t index) const
313 {
314 assert(indexSet.index(cell) ==index);
315 return Combiner(cell,gridView,indexSet);
316 }
317
323 void update()
324 {
325 // Precompute and cache all the global indices. First allocate the
326 // memory needed to prevent frequent reallocation.
327 globIdx.resize(indexSet.size(0));
328 sortedIdx.resize(globIdx.size());
329
330 size_t const ne = indexSet.size(1); // number of edges
331
332 // Step through all cells.
333 for (auto const& cell: entities(gridView,Dune::Codim<0>()))
334 {
335 size_t const k = indexSet.index(cell); // cell number
336 std::vector<size_t>& gidx = globIdx[k]; // global inices on the cell
337 // Allocate needed memory.
338 gidx.resize(6); // 2D Morley elements of second order have 6 local DOFs
339 sortedIdx[k].resize(gidx.size());
340
341 for (int i=0; i<3; ++i)
342 {
343 gidx[i] = indexSet.subIndex(cell,i,1); // edge ansatz functions
344 sortedIdx[k][i] = std::make_pair(gidx[i],i);
345
346 gidx[i+3] = indexSet.subIndex(cell,i,2) + ne; // vertex ansatz functions
347 sortedIdx[k][i+3] = std::make_pair(gidx[i+3],i+3);
348 }
349
350 std::sort(sortedIdx[k].begin(),sortedIdx[k].end());
351 }
352 }
353
354 private:
355 GridView gridView;
356 IndexSet const& indexSet;
357
358 // For each cell, this vector contains a collection with global
359 // indices of each shape function on the cell.
360 std::vector<std::vector<std::size_t>> globIdx;
361
362 // In sortedIdx, for each cell there is a vector of (global index, local index) pairs, sorted ascendingly
363 // by the global index. This could be computed outside on demand, but the sorting takes time and may be
364 // amortized over multiple assembly passes/matrix blocks if cached here.
365 std::vector<std::vector<IndexPair>> sortedIdx;
366 };
367} // end of namespace Kaskade
368
369
370
371#endif
A container of Lagrange shape functions of order Ord on the unit simplex of grid dimension....
A combiner class implementing a matrix mapping a subset of global degrees of freedom (those given by...
Definition: morleyspace.hh:185
void rightTransform(Matrix &A) const
In-place computation of .
Definition: morleyspace.hh:252
void leftPseudoInverse(Matrix &A) const
In-place computation of .
Definition: morleyspace.hh:289
Combiner(Cell const &cell, GridView const &gv, IndexSet const &is)
Definition: morleyspace.hh:189
void rightTransform(std::vector< VariationalArg< Scalar, n, m > > &vs) const
In-place computation of row vectors .
Definition: morleyspace.hh:260
Degrees of freedom manager for Morley nonconforming elements.
Definition: morleyspace.hh:39
RangeView< std::vector< size_t >::const_iterator > GlobalIndexRange
Definition: morleyspace.hh:61
void update()
(Re)computes the internal data.
Definition: morleyspace.hh:323
std::vector< IndexPair >::const_iterator SortedIndexIterator
Definition: morleyspace.hh:64
static int const dim
Definition: morleyspace.hh:48
size_t size() const
Returns the number of global degrees of freedom managed.
Definition: morleyspace.hh:161
GlobalIndexRange globalIndices(Cell const &cell) const
Definition: morleyspace.hh:116
static int const dimw
Definition: morleyspace.hh:50
MorleyMapper(GridView const &gridView_)
Constructs a MorleyMapper for a given grid view.
Definition: morleyspace.hh:75
LagrangeSimplexShapeFunctionSet< typename Grid::ctype, dim, ScalarType > ShapeFunctionSetImplementation
Definition: morleyspace.hh:70
Combiner combiner(Cell const &cell, size_t index) const
Definition: morleyspace.hh:312
int maxOrder() const
Returns the maximal polynomial order of shape functions encountered in any cell.
Definition: morleyspace.hh:87
GlobalIndexRange globalIndices(size_t n) const
Returns a const sequence containing the global indices of the shape functions associated to this cell...
Definition: morleyspace.hh:126
static bool const globalSupport
Whether the ansatz functions have global support (i.e. lead to dense matrices).
Definition: morleyspace.hh:56
ShapeFunctionSet const & shapefunctions(Cell const &cell) const
Definition: morleyspace.hh:92
LagrangeShapeFunctionSetContainer< typenameGrid::ctype, dim, Scalar >::value_type ShapeFunctionSet
Definition: morleyspace.hh:68
GridView::IndexSet IndexSet
Definition: morleyspace.hh:46
SortedIndexRange sortedIndices(size_t n) const
Returns an immutable sequence of (global index, local index) pairs sorted in ascending global index o...
Definition: morleyspace.hh:151
ScalarConverter< Cell, Scalar > Converter
The converter type.
Definition: morleyspace.hh:172
std::pair< size_t, int > IndexPair
Definition: morleyspace.hh:63
SortedIndexRange sortedIndices(Cell const &cell) const
Returns an immutable sequence of (global index, local index) pairs sorted in ascending global index o...
Definition: morleyspace.hh:143
static SortedIndexRange initSortedIndexRange()
Returns an empty range just for initialization, since RangeView is not default constructible.
Definition: morleyspace.hh:134
static int const continuity
Definition: morleyspace.hh:60
Grid::template Codim< 0 >::Entity Cell
Definition: morleyspace.hh:67
GridView::Grid Grid
Definition: morleyspace.hh:45
ShapeFunctionSet const & shapefunctions(size_t) const
Definition: morleyspace.hh:98
RangeView< SortedIndexIterator > SortedIndexRange
Definition: morleyspace.hh:65
GlobalIndexRange initGlobalIndexRange() const
Returns an empty range just for initialization purposes, since RangeView is not default constructible...
Definition: morleyspace.hh:106
DEPRECATED. Use boost::iterator_range instead.
Definition: views.hh:25
A Converter for scalar shape functions that do not change their value under transformation from refer...
Definition: converter.hh:62
Dune::FieldMatrix< Scalar, 1, 1 > global(Dune::FieldMatrix< Scalar, 1, 1 > const &sf) const
Applies the transformation to shape function value.
Definition: converter.hh:83
void setLocalPosition(Dune::FieldVector< typename Cell::Geometry::ctype, dim > const &xi)
Definition: converter.hh:76
A set of shape functions.
virtual int size() const
Number of shape functions in the set.
FEFunctionSpace and FunctionSpaceElement and the like.
define Lagrange type shape functions for simplicial elements of arbitrary dimension and order
typename GetScalar< Type >::type ScalarType
Extracts the scalar field type from linear algebra data types.
A class that stores values, gradients, and Hessians of evaluated shape functions.
Dune::FieldMatrix< Scalar, components, dim > derivative
The shape function's spatial derivative, a components x dim matrix.
ValueType value
The shape function's value, a vector of dimension components