Dune Core Modules (2.9.0)

hierarchicalsimplexp2withelementbubble.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 // SPDX-FileCopyrightInfo: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
4 // SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
5 #ifndef DUNE_HIERARCHICAL_SIMPLEX_P2_WITH_ELEMENT_BUBBLE_LOCALBASIS_HH
6 #define DUNE_HIERARCHICAL_SIMPLEX_P2_WITH_ELEMENT_BUBBLE_LOCALBASIS_HH
7 
12 #include <numeric>
13 #include <vector>
14 
15 #include <dune/common/fvector.hh>
16 #include <dune/common/fmatrix.hh>
17 
18 #include <dune/localfunctions/common/localbasis.hh>
19 #include <dune/localfunctions/common/localkey.hh>
20 #include <dune/localfunctions/common/localinterpolation.hh>
21 
22 namespace Dune
23 {
24  template<class D, class R, int dim>
25  class HierarchicalSimplexP2WithElementBubbleLocalBasis
26  {
27  public:
28  HierarchicalSimplexP2WithElementBubbleLocalBasis()
29  {
30  DUNE_THROW(Dune::NotImplemented,"HierarchicalSimplexP2LocalBasis not implemented for dim > 3.");
31  }
32  };
33 
48  template<class D, class R>
49  class HierarchicalSimplexP2WithElementBubbleLocalBasis<D,R,1>
50  {
51  public:
55 
57  unsigned int size () const
58  {
59  return 3;
60  }
61 
63  inline void evaluateFunction (const typename Traits::DomainType& in,
64  std::vector<typename Traits::RangeType>& out) const
65  {
66  out.resize(3);
67 
68  out[0] = 1-in[0];
69  out[1] = in[0];
70  out[2] = 1-4*(in[0]-0.5)*(in[0]-0.5);
71  }
72 
74  inline void
75  evaluateJacobian (const typename Traits::DomainType& in, // position
76  std::vector<typename Traits::JacobianType>& out) const // return value
77  {
78  out.resize(3);
79 
80  out[0][0][0] = -1;
81  out[1][0][0] = 1;
82  out[2][0][0] = 4-8*in[0];
83  }
84 
86  void partial (const std::array<unsigned int, 1>& order,
87  const typename Traits::DomainType& in, // position
88  std::vector<typename Traits::RangeType>& out) const // return value
89  {
90  auto totalOrder = order[0];
91  if (totalOrder == 0) {
92  evaluateFunction(in, out);
93  } else if (totalOrder == 1) {
94  out.resize(size());
95  out[0] = -1;
96  out[1] = 1;
97  out[2] = 4-8*in[0];
98  } else if (totalOrder == 2) {
99  out.resize(size());
100  out[0] = 0;
101  out[1] = 0;
102  out[2] =-8;
103  } else {
104  out.resize(size());
105  out[0] = out[1] = out[2] = 0;
106  }
107  }
108 
111  unsigned int order () const
112  {
113  return 2;
114  }
115 
116  };
117 
138  template<class D, class R>
139  class HierarchicalSimplexP2WithElementBubbleLocalBasis<D,R,2>
140  {
141  public:
145 
147  unsigned int size () const
148  {
149  return 7;
150  }
151 
153  inline void evaluateFunction (const typename Traits::DomainType& in,
154  std::vector<typename Traits::RangeType>& out) const
155  {
156  out.resize(7);
157 
158  out[0] = 1 - in[0] - in[1];
159  out[1] = 4*in[0]*(1-in[0]-in[1]);
160  out[2] = in[0];
161  out[3] = 4*in[1]*(1-in[0]-in[1]);
162  out[4] = 4*in[0]*in[1];
163  out[5] = in[1];
164  out[6] = 27*in[0]*in[1]*(1-in[0]-in[1]);
165 
166  }
167 
169  inline void
170  evaluateJacobian (const typename Traits::DomainType& in, // position
171  std::vector<typename Traits::JacobianType>& out) const // return value
172  {
173  out.resize(7);
174 
175  out[0][0][0] = -1; out[0][0][1] = -1;
176  out[1][0][0] = 4-8*in[0]-4*in[1]; out[1][0][1] = -4*in[0];
177  out[2][0][0] = 1; out[2][0][1] = 0;
178  out[3][0][0] = -4*in[1]; out[3][0][1] = 4-4*in[0]-8*in[1];
179  out[4][0][0] = 4*in[1]; out[4][0][1] = 4*in[0];
180  out[5][0][0] = 0; out[5][0][1] = 1;
181 
182  // Cubic bubble
183  out[6][0][0] = 27 * in[1] * (1 - 2*in[0] - in[1]);
184  out[6][0][1] = 27 * in[0] * (1 - 2*in[1] - in[0]);
185 
186  }
187 
189  void partial (const std::array<unsigned int, 2>& order,
190  const typename Traits::DomainType& in, // position
191  std::vector<typename Traits::RangeType>& out) const // return value
192  {
193  auto totalOrder = std::accumulate(order.begin(), order.end(), 0);
194  if (totalOrder == 0) {
195  evaluateFunction(in, out);
196  } else if (totalOrder == 1) {
197  out.resize(size());
198  auto const direction = std::distance(order.begin(), std::find(order.begin(), order.end(), 1));
199 
200  switch (direction) {
201  case 0:
202  out[0] = -1;
203  out[1] = 4-8*in[0]-4*in[1];
204  out[2] = 1;
205  out[3] = -4*in[1];
206  out[4] = 4*in[1];
207  out[5] = 0;
208  out[6] = 27 * in[1] * (1 - 2*in[0] - in[1]);
209  break;
210  case 1:
211  out[0] = -1;
212  out[1] = -4*in[0];
213  out[2] = 0;
214  out[3] = 4-4*in[0]-8*in[1];
215  out[4] = 4*in[0];
216  out[5] = 1;
217  out[6] = 27 * in[0] * (1 - 2*in[1] - in[0]);
218  break;
219  default:
220  DUNE_THROW(RangeError, "Component out of range.");
221  }
222  } else {
223  DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
224  }
225  }
226 
229  unsigned int order () const
230  {
231  return 3;
232  }
233 
234  };
235 
260  template<class D, class R>
261  class HierarchicalSimplexP2WithElementBubbleLocalBasis<D,R,3>
262  {
263  public:
267 
269  unsigned int size () const
270  {
271  return 11;
272  }
273 
275  void evaluateFunction (const typename Traits::DomainType& in,
276  std::vector<typename Traits::RangeType>& out) const
277  {
278  out.resize(10);
279 
280  out[0] = 1 - in[0] - in[1] - in[2];
281  out[1] = 4 * in[0] * (1 - in[0] - in[1] - in[2]);
282  out[2] = in[0];
283  out[3] = 4 * in[1] * (1 - in[0] - in[1] - in[2]);
284  out[4] = 4 * in[0] * in[1];
285  out[5] = in[1];
286  out[6] = 4 * in[2] * (1 - in[0] - in[1] - in[2]);
287  out[7] = 4 * in[0] * in[2];
288  out[8] = 4 * in[1] * in[2];
289  out[9] = in[2];
290 
291  // quartic element bubble
292  out[10] = 81*in[0]*in[1]*in[2]*(1-in[0]-in[1]-in[2]);
293  }
294 
296  void evaluateJacobian (const typename Traits::DomainType& in, // position
297  std::vector<typename Traits::JacobianType>& out) const // return value
298  {
299  out.resize(10);
300 
301  out[0][0][0] = -1; out[0][0][1] = -1; out[0][0][2] = -1;
302  out[1][0][0] = 4-8*in[0]-4*in[1]-4*in[2]; out[1][0][1] = -4*in[0]; out[1][0][2] = -4*in[0];
303  out[2][0][0] = 1; out[2][0][1] = 0; out[2][0][2] = 0;
304  out[3][0][0] = -4*in[1]; out[3][0][1] = 4-4*in[0]-8*in[1]-4*in[2]; out[3][0][2] = -4*in[1];
305  out[4][0][0] = 4*in[1]; out[4][0][1] = 4*in[0]; out[4][0][2] = 0;
306  out[5][0][0] = 0; out[5][0][1] = 1; out[5][0][2] = 0;
307  out[6][0][0] = -4*in[2]; out[6][0][1] = -4*in[2]; out[6][0][2] = 4-4*in[0]-4*in[1]-8*in[2];
308  out[7][0][0] = 4*in[2]; out[7][0][1] = 0; out[7][0][2] = 4*in[0];
309  out[8][0][0] = 0; out[8][0][1] = 4*in[2]; out[8][0][2] = 4*in[1];
310  out[9][0][0] = 0; out[9][0][1] = 0; out[9][0][2] = 1;
311 
312  out[10][0][0] = 81 * in[1] * in[2] * (1 - 2*in[0] - in[1] - in[2]);
313  out[10][0][1] = 81 * in[0] * in[2] * (1 - in[0] - 2*in[1] - in[2]);
314  out[10][0][2] = 81 * in[0] * in[1] * (1 - in[0] - in[1] - 2*in[2]);
315  }
316 
318  void partial (const std::array<unsigned int, 3>& order,
319  const typename Traits::DomainType& in, // position
320  std::vector<typename Traits::RangeType>& out) const // return value
321  {
322  auto totalOrder = std::accumulate(order.begin(), order.end(), 0);
323  if (totalOrder == 0) {
324  evaluateFunction(in, out);
325  } else if (totalOrder == 1) {
326  out.resize(size());
327  auto const direction = std::distance(order.begin(), std::find(order.begin(), order.end(), 1));
328 
329  switch (direction) {
330  case 0:
331  out[0] = -1;
332  out[1] = 4-8*in[0]-4*in[1]-4*in[2];
333  out[2] = 1;
334  out[3] = -4*in[1];
335  out[4] = 4*in[1];
336  out[5] = 0;
337  out[6] = -4*in[2];
338  out[7] = 4*in[2];
339  out[8] = 0;
340  out[9] = 0;
341  out[10] = 81 * in[1] * in[2] * (1 - 2*in[0] - in[1] - in[2]);
342  break;
343  case 1:
344  out[0] = -1;
345  out[1] = -4*in[0];
346  out[2] = 0;
347  out[3] = 4-4*in[0]-8*in[1]-4*in[2];
348  out[4] = 4*in[0];
349  out[5] = 1;
350  out[6] = -4*in[2];
351  out[7] = 0;
352  out[8] = 4*in[2];
353  out[9] = 0;
354  out[10] = 81 * in[0] * in[2] * (1 - in[0] - 2*in[1] - in[2]);
355  break;
356  case 2:
357  out[0] = -1;
358  out[1] = -4*in[0];
359  out[2] = 0;
360  out[3] = -4*in[1];
361  out[4] = 0;
362  out[5] = 0;
363  out[6] = 4-4*in[0]-4*in[1]-8*in[2];
364  out[7] = 4*in[0];
365  out[8] = 4*in[1];
366  out[9] = 1;
367  out[10] = 81 * in[0] * in[1] * (1 - in[0] - in[1] - 2*in[2]);
368  break;
369  default:
370  DUNE_THROW(RangeError, "Component out of range.");
371  }
372  } else {
373  DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
374  }
375  }
376 
379  unsigned int order () const
380  {
381  return 4;
382  }
383 
384  };
385 
386 
412  template <int dim>
414  {
415  // The binomial coefficient: dim+1 over 1
416  static const int numVertices = dim+1;
417 
418  // The binomial coefficient: dim+1 over 2
419  static const int numEdges = (dim+1)*dim / 2;
420 
421  public:
424  : li(numVertices+numEdges + 1)
425  {
426  if (dim!=2)
427  DUNE_THROW(NotImplemented, "only for 2d");
428 
429  li[0] = Dune::LocalKey(0,2,0); // Vertex (0,0)
430  li[1] = Dune::LocalKey(0,1,0); // Edge (0.5, 0)
431  li[2] = Dune::LocalKey(1,2,0); // Vertex (1,0)
432  li[3] = Dune::LocalKey(1,1,0); // Edge (0, 0.5)
433  li[4] = Dune::LocalKey(2,1,0); // Edge (0.5, 0.5)
434  li[5] = Dune::LocalKey(2,2,0); // Vertex (0,1)
435  li[6] = Dune::LocalKey(0,0,0); // Element (1/3, 1/3)
436  }
437 
439  size_t size () const
440  {
441  return numVertices+numEdges + 1;
442  }
443 
445  const Dune::LocalKey& localKey (size_t i) const
446  {
447  return li[i];
448  }
449 
450  private:
451  std::vector<Dune::LocalKey> li;
452  };
453 
454  template<class LB>
455  class HierarchicalSimplexP2WithElementBubbleLocalInterpolation
456  {
457  public:
458 
460  template<typename F, typename C>
461  void interpolate (const F& ff, std::vector<C>& out) const
462  {
463  typename LB::Traits::DomainType x;
464  typename LB::Traits::RangeType y;
465 
466  out.resize(7);
467 
468  auto&& f = Impl::makeFunctionWithCallOperator<decltype(x)>(ff);
469 
470  // vertices
471  x[0] = 0.0; x[1] = 0.0; out[0] = f(x);
472  x[0] = 1.0; x[1] = 0.0; out[2] = f(x);
473  x[0] = 0.0; x[1] = 1.0; out[5] = f(x);
474 
475  // edge bubbles
476  x[0] = 0.5; x[1] = 0.0; y = f(x);
477  out[1] = y - out[0]*(1-x[0]) - out[2]*x[0];
478 
479  x[0] = 0.0; x[1] = 0.5; y = f(x);
480  out[3] = y - out[0]*(1-x[1]) - out[5]*x[1];
481 
482  x[0] = 0.5; x[1] = 0.5; y = f(x);
483  out[4] = y - out[2]*x[0] - out[5]*x[1];
484 
485  // element bubble
486  x[0] = 1.0/3; x[1] = 1.0/3; y = f(x);
487 
489  HierarchicalSimplexP2WithElementBubbleLocalBasis<double,double,2> shapeFunctions;
490  std::vector<typename LB::Traits::RangeType> sfValues;
491  shapeFunctions.evaluateFunction(x, sfValues);
492 
493  out[6] = y;
494  for (int i=0; i<6; i++)
495  out[6] -= out[i]*sfValues[i];
496 
497  }
498 
499  };
500 
501 
502 }
503 #endif
A dense n x m matrix.
Definition: fmatrix.hh:117
vector space out of a tensor product of fields.
Definition: fvector.hh:95
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:75
LocalBasisTraits< D, 1, Dune::FieldVector< D, 1 >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, 1 > > Traits
export type traits for function signature
Definition: hierarchicalsimplexp2withelementbubble.hh:54
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:63
unsigned int order() const
Polynomial order of the shape functions (2, in this case)
Definition: hierarchicalsimplexp2withelementbubble.hh:111
unsigned int size() const
number of shape functions
Definition: hierarchicalsimplexp2withelementbubble.hh:57
void partial(const std::array< unsigned int, 1 > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:86
unsigned int size() const
number of shape functions
Definition: hierarchicalsimplexp2withelementbubble.hh:147
unsigned int order() const
Polynomial order of the shape functions (3 in this case)
Definition: hierarchicalsimplexp2withelementbubble.hh:229
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:153
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:170
void partial(const std::array< unsigned int, 2 > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:189
LocalBasisTraits< D, 2, Dune::FieldVector< D, 2 >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, 2 > > Traits
export type traits for function signature
Definition: hierarchicalsimplexp2withelementbubble.hh:144
unsigned int size() const
number of shape functions
Definition: hierarchicalsimplexp2withelementbubble.hh:269
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:275
unsigned int order() const
Polynomial order of the shape functions (4 in this case)
Definition: hierarchicalsimplexp2withelementbubble.hh:379
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:296
void partial(const std::array< unsigned int, 3 > &order, const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate partial derivatives of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:318
LocalBasisTraits< D, 3, Dune::FieldVector< D, 3 >, R, 1, Dune::FieldVector< R, 1 >, Dune::FieldMatrix< R, 1, 3 > > Traits
export type traits for function signature
Definition: hierarchicalsimplexp2withelementbubble.hh:266
The local finite element needed for the Zou-Kornhuber estimator for Signorini problems.
Definition: hierarchicalsimplexp2withelementbubble.hh:414
size_t size() const
number of coefficients
Definition: hierarchicalsimplexp2withelementbubble.hh:439
const Dune::LocalKey & localKey(size_t i) const
get i'th index
Definition: hierarchicalsimplexp2withelementbubble.hh:445
HierarchicalSimplexP2WithElementBubbleLocalCoefficients()
Standard constructor.
Definition: hierarchicalsimplexp2withelementbubble.hh:423
Describe position of one degree of freedom.
Definition: localkey.hh:23
Default exception for dummy implementations.
Definition: exceptions.hh:263
Default exception class for range errors.
Definition: exceptions.hh:254
Implements a matrix constructed from a given type representing a field and compile-time given number ...
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:218
constexpr T accumulate(Range &&range, T value, F &&f)
Accumulate values.
Definition: hybridutilities.hh:291
Dune namespace.
Definition: alignedallocator.hh:13
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:34
D DomainType
domain type
Definition: localbasis.hh:42
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 1, 22:29, 2024)