KASKADE 7 development version
pshapefunctions.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-2024 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 PSHAPEFUNCTIONS_HH
14#define PSHAPEFUNCTIONS_HH
15
16#include "fem/barycentric.hh"
17#include "fem/fixdune.hh"
18#include "fem/mllgeometry.hh"
21#include "linalg/tensor.hh"
22
23#include <boost/multi_array.hpp>
24
25#include <tuple>
26#include <vector>
27#include <cmath>
28#include <iomanip>
29#include <iostream>
30#include <memory>
31
32
33
34namespace Kaskade
35{
56 template <class ctype, int dim, class T=double, int comp=1>
58 {
59 public:
60 virtual ~ShapeFunction() {}
61
66
71
76 {
77 std::cerr << "NOT IMPLEMENTED: " << __FILE__ << ":" << __LINE__ << "\n";
78 abort();
79 }
80
94 virtual std::tuple<int,int,int,int> location() const = 0;
95 };
96
97 //---------------------------------------------------------------------
107 template <class ctype, int dimension, class T, int comp=1>
109 {
110 public:
112 typedef T Scalar;
115
120
122 ShapeFunctionSet(Dune::GeometryType gt)
123 : order_(-1), size_(-1),
124 gt_(gt)
125 {}
126
127 ShapeFunctionSet(ShapeFunctionSet const& other) = default;
128
132 static int const comps = comp;
133
134
135 virtual ~ShapeFunctionSet() {}
136
137
139 virtual value_type const& operator[](int i) const = 0;
140
144 virtual int size() const { return size_; }
145
149 int order() const { return order_; }
150
152 Dune::GeometryType type() const { return gt_; }
153
158 auto referenceElement() const
159 {
160 return Dune::referenceElement<ctype,dimension>(gt_);
161 }
162
164 typedef std::vector<Dune::FieldVector<ctype,dimension>> InterpolationNodes;
165
169
175 {
176 // If no lower order shape function set is given, we assume an
177 // empty set, i.e. the projection is just zero.
178 if (!sfl || size()==0) {
180// projection = 0 // causes compilation error with dune-2.4.0 and clang++ on OS X (Darwin)
181 projection.fill(0);
182 return;
183 }
184
185 // Compute the hierarchic projection P = I_h E_l(x_h) I_l E_h(x_l),
186 // where E_h(x_l) the evaluation of high order shape functions at
187 // low order nodes, I_l the low order interpolation, E_l(x_h) the
188 // evaluation of low order shape functions at high order nodes,
189 // and I_h the high order shape function evaluation.
190
191 // Compute the local restriction matrix A
192 SfValueArray Ehxl;
193 evaluate(sfl->interpolationNodes(),Ehxl); // E_h(x_l)
194 Matrix A;
195 sfl->interpolate(Ehxl,A); // I_l E_h(x_l)
196
197 // Compute the local prolongation matrix B
198 SfValueArray Elxh;
199 sfl->evaluate(interpolationNodes(),Elxh); // E_l(x_h)
200 Matrix B;
201 interpolate(Elxh,B); // I_h E_l(x_h)
202
203 // Compute projection P=B*A
204 projection = B*A;
205 }
206
207
208
219 {
220 return iNodes;
221 }
222
223
241 virtual void interpolate(SfValueArray const& A, Matrix& IA) const = 0;
242
254 {
255 int s = size();
256 phi.setSize(iNodes.size(),s);
257
258 for (int j=0; j<s; ++j) {
259 value_type const& sf = (*this)[j];
260 for (int i=0; i<iNodes.size(); ++i) {
262 for (int k=0; k<comp; ++k)
263 phi[i][j][k] = v[k]; // todo: improve efficiency! cache directly!
264 }
265 }
266 }
267
277 {
278 // check that the projection has been properly initialized.
279 assert(projection.N()==size() && projection.M()==size());
280
281 return projection;
282 }
283
284 virtual void removeShapeFunction(size_t index) {}
285
286 protected:
290 int size_;
291
292 private:
293 Dune::GeometryType gt_;
294 };
295
296 //---------------------------------------------------------------------
297
298 template <class ctype, int dimension, class T, int comp=1>
299 class EmptyShapeFunctionSet: public ShapeFunctionSet<ctype,dimension,T,comp>
300 {
302 public:
303 EmptyShapeFunctionSet(Dune::GeometryType const& gt)
304 : Base(gt)
305 {
306 this->size_ = 0;
307 }
308 virtual typename Base::value_type const& operator[](int i) const { abort(); }
309 virtual void interpolate(typename Base::SfValueArray const& A, typename Base::Matrix& IA) const
310 {
311 IA.resize(0,A.M());
312 }
313 };
314
315 //---------------------------------------------------------------------
316
322 template <class ShapeFunctionSet_>
323 class RestrictedShapeFunctionSet: public ShapeFunctionSet_
324 {
325 public:
327 //typedef typename ShapeFunctionSet_::Grid Grid; causes compiler error
329 typedef typename ShapeFunctionSet_::Scalar Scalar;
331 typedef typename ShapeFunctionSet_::value_type value_type;
332
333 explicit RestrictedShapeFunctionSet(int order) : ShapeFunctionSet_(order) {}
334
335 RestrictedShapeFunctionSet(ShapeFunctionSet_ const& other) : ShapeFunctionSet_(other) {}
336 RestrictedShapeFunctionSet(RestrictedShapeFunctionSet const& other) : ShapeFunctionSet_(other) {}
338 RestrictedShapeFunctionSet(RestrictedShapeFunctionSet const& other, std::vector<int>* ids_) : ShapeFunctionSet_(other) {}
339
341
345 void setRestriction(std::vector<int> const& ids_)
346 {
347 if(ids_.size()==0)
348 {
349 this->sf.clear();
350 this->iNodes.clear();
351 this->size_ = 0;
352 return;
353 }
354
355
356 for(int i=this->sf.size()-1; i>-1; --i)
357 if(std::find(ids_.begin(),ids_.end(),i)==ids_.end()) this->removeShapeFunction(i);
358
359 this->size_ = ids_.size();
360 }
361 };
362
363 //---------------------------------------------------------------------
364
373 template <class ctype, int dimension, class T, int comp=1>
375 {
376 public:
378
380
381
383 virtual value_type const& operator() (Dune::GeometryType type, int order) const = 0;
384 };
385
386 //---------------------------------------------------------------------
387 //---------------------------------------------------------------------
388
400 template <class ShapeFunctionSet>
402 int const* vPermutation,
403 int* sfPermutation,
404 int* sign)
405 {
406 assert(vPermutation);
407 assert(sfPermutation);
408 assert(sign);
409
410 // Ok, we rely on the evaluation & interpolation of the shape
411 // function set. First we evaluate the shape functions on the
412 // interpolation nodes transformed by f, then we interpolate these
413 // values. This gives us a matrix which, if the shape function set
414 // indeed allows simple coupling, is a signed permutation
415 // matrix. Finally we extract the signs and the permutation from
416 // this matrix.
417
418 // Get the interpolation nodes. Make a copy because we need to
419 // modify them.
420 typedef typename ShapeFunctionSet::InterpolationNodes InterpolationNodes;
421 InterpolationNodes in = sfs.interpolationNodes();
422
423
424 // Transform the nodes. This is done by permuting their barycentric
425 // coordinates. Remember that the interpolation nodes are given in
426 // Cartesian, not in barycentric coordinates. This determines the
427 // loop termination for j.
428 for (int i=0; i<in.size(); ++i) {
430 for (int j=0; j<ShapeFunctionSet::Grid::dimension; ++j)
431 in[i][j] = b[vPermutation[j]];
432 }
433
434
435 // Evaluate the shape functions at the transformed nodes.
436 typename ShapeFunctionSet::SfValueArray phi(in.size(),sfs.size());
437 sfs.evaluate(in,phi);
438
439 // Interpolate the shape function values.
440 typename ShapeFunctionSet::Matrix P(sfs.size(),sfs.size());
441 sfs.interpolate(phi,P);
442
443
444#ifndef NDEBUG
445 // Check that the permutation matrix is indeed a signed permutation
446 bool ok = true;
447 for (int i=0; i<sfs.size(); ++i) {
448 double rowSum = 0;
449 double colSum = 0;
450 for (int j=0; j<sfs.size(); ++j) {
451 if (std::abs(P[i][j])>1e-8 && std::abs(1-std::abs(P[i][j]))>1e-8) ok = false;
452 rowSum += std::abs(P[i][j]);
453 colSum += std::abs(P[j][i]);
454 }
455 if (std::abs(rowSum-1)>1e-8 || std::abs(colSum-1)>1e-8) ok = false;
456 }
457 if (!ok) {
458 std::cout << "\nPermutation matrix:\n";
459 for (int i=0; i<P.N(); ++i) {
460 for (int j=0; j<P.M(); ++j)
461 std::cout << std::setw(2) << P[i][j] << " ";
462 std::cout << "\n";
463 }
464 }
465#endif
466
467
468 // Extract the permutation and the sign.
469 for (int i=0; i<sfs.size(); ++i)
470 for (int j=0; j<sfs.size(); ++j)
471 if (std::abs(P[j][i])>0.5) {
472 sfPermutation[i] = j; // XXX or the other way round?
473 sign[i] = P[j][i]>0? 1: -1;
474 break;
475 }
476
477 }
478} // end of namespace Kaskade
479
480#endif
A LAPACK-compatible dense matrix class with shape specified at runtime.
void setSize(size_type r, size_type c)
Resizes the matrix to r x c, leaving the entries in an undefined state.
void resize(size_type r, size_type c)
Resizes the matrix to r x c, leaving the entries in an undefined state.
EmptyShapeFunctionSet(Dune::GeometryType const &gt)
virtual void interpolate(typename Base::SfValueArray const &A, typename Base::Matrix &IA) const
virtual Base::value_type const & operator[](int i) const
Random access to a shape function.
Restricted shape function set. Introduces a new local ordering for the shape functions....
RestrictedShapeFunctionSet(ShapeFunctionSet_ const &other)
RestrictedShapeFunctionSet(RestrictedShapeFunctionSet const &other)
void setRestriction(std::vector< int > const &ids_)
ShapeFunctionSet_::value_type value_type
type of one shape function
ShapeFunctionSet_::Scalar Scalar
Grid type.
RestrictedShapeFunctionSet(RestrictedShapeFunctionSet const &other, std::vector< int > *ids_)
Copy constructor. Resets restriction ids.
virtual Tensor< T, comp, dim, dim > evaluate2ndDerivative(Dune::FieldVector< ctype, dim > const &xi) const
Evaluates the second derivative of the shape function (all components and all directions at once).
virtual Dune::FieldMatrix< T, comp, dim > evaluateDerivative(Dune::FieldVector< ctype, dim > const &xi) const =0
Evaluates the derivative of the shape function (all components and all directions at once).
virtual Dune::FieldVector< T, comp > evaluateFunction(Dune::FieldVector< ctype, dim > const &xi) const =0
Evaluates the shape function (all components at once).
virtual std::tuple< int, int, int, int > location() const =0
Returns a tuple (nominalOrder,codim,entity,index) giving detailed information about the location of t...
Base class for sets of shape function containers.
ShapeFunctionSet< ctype, dimension, T, comp > value_type
virtual value_type const & operator()(Dune::GeometryType type, int order) const =0
access a shape function via type and order
A set of shape functions.
virtual void removeShapeFunction(size_t index)
ShapeFunctionSet(ShapeFunctionSet const &other)=default
ShapeFunctionSet(Dune::GeometryType gt)
Constructor.
T Scalar
Scalar field type.
void evaluate(InterpolationNodes const &iNodes, SfValueArray &phi) const
Evaluate shape function set at a set of points. In notation of the LocalToGlobalMapperConcept,...
Dune::GeometryType type() const
Type of geometry on which the shape functions are defined.
DynamicMatrix< Dune::FieldMatrix< T, 1, 1 > > Matrix
A matrix type mapping one-component coefficient vectors.
static int const comps
Number of components of the shape function values.
InterpolationNodes const & interpolationNodes() const
Interpolation points.
InterpolationNodes iNodes
virtual int size() const
Number of shape functions in the set.
int order() const
Maximal polynomial order of shape functions.
void initHierarchicalProjection(ShapeFunctionSet< ctype, dimension, T, comp > const *sfl)
Initialize the hierarchical projection matrix based on the given lower order shape function set.
virtual value_type const & operator[](int i) const =0
Random access to a shape function.
std::vector< Dune::FieldVector< ctype, dimension > > InterpolationNodes
A container type for holding interpolation points in the reference elements.
DynamicMatrix< Dune::FieldMatrix< T, comp, 1 > > SfValueArray
ShapeFunction< ctype, dimension, T, comp > value_type
type of one shape function
virtual void interpolate(SfValueArray const &A, Matrix &IA) const =0
Left-multiplies the provided matrix with the interpolation matrix of the shape function set.
Matrix const & hierarchicProjection() const
Returns a square matrix that projects shape function coefficients to a subspace spanned by shape func...
A class for representing tensors of arbitrary static rank and extents.
Definition: tensor.hh:86
This file contains various utility functions that augment the basic functionality of Dune.
Dune::FieldVector< CoordType, dim+1 > barycentric(Dune::FieldVector< CoordType, dim > const &x)
Computes the barycentric coordinates of a point in the unit simplex.
Definition: barycentric.hh:32
Class for transformations between ancestors and their children.
void computeSimplexSfPermutation(ShapeFunctionSet const &sfs, int const *vPermutation, int *sfPermutation, int *sign)
T sign(T x)
Definition: sign.hh:21