Dune Core Modules (unstable)

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 © 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 
21 namespace Dune
22 {
23  template<class D, class R, int dim>
24  class HierarchicalSimplexP2WithElementBubbleLocalBasis
25  {
26  public:
27  HierarchicalSimplexP2WithElementBubbleLocalBasis()
28  {
29  DUNE_THROW(Dune::NotImplemented,"HierarchicalSimplexP2LocalBasis not implemented for dim > 3.");
30  }
31  };
32 
47  template<class D, class R>
48  class HierarchicalSimplexP2WithElementBubbleLocalBasis<D,R,1>
49  {
50  public:
54 
56  unsigned int size () const
57  {
58  return 3;
59  }
60 
62  inline void evaluateFunction (const typename Traits::DomainType& in,
63  std::vector<typename Traits::RangeType>& out) const
64  {
65  out.resize(3);
66 
67  out[0] = 1-in[0];
68  out[1] = in[0];
69  out[2] = 1-4*(in[0]-0.5)*(in[0]-0.5);
70  }
71 
73  inline void
74  evaluateJacobian (const typename Traits::DomainType& in, // position
75  std::vector<typename Traits::JacobianType>& out) const // return value
76  {
77  out.resize(3);
78 
79  out[0][0][0] = -1;
80  out[1][0][0] = 1;
81  out[2][0][0] = 4-8*in[0];
82  }
83 
85  void partial (const std::array<unsigned int, 1>& order,
86  const typename Traits::DomainType& in, // position
87  std::vector<typename Traits::RangeType>& out) const // return value
88  {
89  auto totalOrder = order[0];
90  if (totalOrder == 0) {
91  evaluateFunction(in, out);
92  } else if (totalOrder == 1) {
93  out.resize(size());
94  out[0] = -1;
95  out[1] = 1;
96  out[2] = 4-8*in[0];
97  } else if (totalOrder == 2) {
98  out.resize(size());
99  out[0] = 0;
100  out[1] = 0;
101  out[2] =-8;
102  } else {
103  out.resize(size());
104  out[0] = out[1] = out[2] = 0;
105  }
106  }
107 
110  unsigned int order () const
111  {
112  return 2;
113  }
114 
115  };
116 
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 
261  template<class D, class R>
262  class HierarchicalSimplexP2WithElementBubbleLocalBasis<D,R,3>
263  {
264  public:
268 
270  unsigned int size () const
271  {
272  return 11;
273  }
274 
276  void evaluateFunction (const typename Traits::DomainType& in,
277  std::vector<typename Traits::RangeType>& out) const
278  {
279  out.resize(10);
280 
281  out[0] = 1 - in[0] - in[1] - in[2];
282  out[1] = 4 * in[0] * (1 - in[0] - in[1] - in[2]);
283  out[2] = in[0];
284  out[3] = 4 * in[1] * (1 - in[0] - in[1] - in[2]);
285  out[4] = 4 * in[0] * in[1];
286  out[5] = in[1];
287  out[6] = 4 * in[2] * (1 - in[0] - in[1] - in[2]);
288  out[7] = 4 * in[0] * in[2];
289  out[8] = 4 * in[1] * in[2];
290  out[9] = in[2];
291 
292  // quartic element bubble
293  out[10] = 81*in[0]*in[1]*in[2]*(1-in[0]-in[1]-in[2]);
294  }
295 
297  void evaluateJacobian (const typename Traits::DomainType& in, // position
298  std::vector<typename Traits::JacobianType>& out) const // return value
299  {
300  out.resize(10);
301 
302  out[0][0][0] = -1; out[0][0][1] = -1; out[0][0][2] = -1;
303  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];
304  out[2][0][0] = 1; out[2][0][1] = 0; out[2][0][2] = 0;
305  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];
306  out[4][0][0] = 4*in[1]; out[4][0][1] = 4*in[0]; out[4][0][2] = 0;
307  out[5][0][0] = 0; out[5][0][1] = 1; out[5][0][2] = 0;
308  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];
309  out[7][0][0] = 4*in[2]; out[7][0][1] = 0; out[7][0][2] = 4*in[0];
310  out[8][0][0] = 0; out[8][0][1] = 4*in[2]; out[8][0][2] = 4*in[1];
311  out[9][0][0] = 0; out[9][0][1] = 0; out[9][0][2] = 1;
312 
313  out[10][0][0] = 81 * in[1] * in[2] * (1 - 2*in[0] - in[1] - in[2]);
314  out[10][0][1] = 81 * in[0] * in[2] * (1 - in[0] - 2*in[1] - in[2]);
315  out[10][0][2] = 81 * in[0] * in[1] * (1 - in[0] - in[1] - 2*in[2]);
316  }
317 
319  void partial (const std::array<unsigned int, 3>& order,
320  const typename Traits::DomainType& in, // position
321  std::vector<typename Traits::RangeType>& out) const // return value
322  {
323  auto totalOrder = std::accumulate(order.begin(), order.end(), 0);
324  if (totalOrder == 0) {
325  evaluateFunction(in, out);
326  } else if (totalOrder == 1) {
327  out.resize(size());
328  auto const direction = std::distance(order.begin(), std::find(order.begin(), order.end(), 1));
329 
330  switch (direction) {
331  case 0:
332  out[0] = -1;
333  out[1] = 4-8*in[0]-4*in[1]-4*in[2];
334  out[2] = 1;
335  out[3] = -4*in[1];
336  out[4] = 4*in[1];
337  out[5] = 0;
338  out[6] = -4*in[2];
339  out[7] = 4*in[2];
340  out[8] = 0;
341  out[9] = 0;
342  out[10] = 81 * in[1] * in[2] * (1 - 2*in[0] - in[1] - in[2]);
343  break;
344  case 1:
345  out[0] = -1;
346  out[1] = -4*in[0];
347  out[2] = 0;
348  out[3] = 4-4*in[0]-8*in[1]-4*in[2];
349  out[4] = 4*in[0];
350  out[5] = 1;
351  out[6] = -4*in[2];
352  out[7] = 0;
353  out[8] = 4*in[2];
354  out[9] = 0;
355  out[10] = 81 * in[0] * in[2] * (1 - in[0] - 2*in[1] - in[2]);
356  break;
357  case 2:
358  out[0] = -1;
359  out[1] = -4*in[0];
360  out[2] = 0;
361  out[3] = -4*in[1];
362  out[4] = 0;
363  out[5] = 0;
364  out[6] = 4-4*in[0]-4*in[1]-8*in[2];
365  out[7] = 4*in[0];
366  out[8] = 4*in[1];
367  out[9] = 1;
368  out[10] = 81 * in[0] * in[1] * (1 - in[0] - in[1] - 2*in[2]);
369  break;
370  default:
371  DUNE_THROW(RangeError, "Component out of range.");
372  }
373  } else {
374  DUNE_THROW(NotImplemented, "Desired derivative order is not implemented");
375  }
376  }
377 
380  unsigned int order () const
381  {
382  return 4;
383  }
384 
385  };
386 
387 
414  template <int dim>
416  {
417  // The binomial coefficient: dim+1 over 1
418  static const int numVertices = dim+1;
419 
420  // The binomial coefficient: dim+1 over 2
421  static const int numEdges = (dim+1)*dim / 2;
422 
423  public:
426  : li(numVertices+numEdges + 1)
427  {
428  if (dim!=2)
429  DUNE_THROW(NotImplemented, "only for 2d");
430 
431  li[0] = Dune::LocalKey(0,2,0); // Vertex (0,0)
432  li[1] = Dune::LocalKey(0,1,0); // Edge (0.5, 0)
433  li[2] = Dune::LocalKey(1,2,0); // Vertex (1,0)
434  li[3] = Dune::LocalKey(1,1,0); // Edge (0, 0.5)
435  li[4] = Dune::LocalKey(2,1,0); // Edge (0.5, 0.5)
436  li[5] = Dune::LocalKey(2,2,0); // Vertex (0,1)
437  li[6] = Dune::LocalKey(0,0,0); // Element (1/3, 1/3)
438  }
439 
441  size_t size () const
442  {
443  return numVertices+numEdges + 1;
444  }
445 
447  const Dune::LocalKey& localKey (size_t i) const
448  {
449  return li[i];
450  }
451 
452  private:
453  std::vector<Dune::LocalKey> li;
454  };
455 
459  template<class LB>
460  class HierarchicalSimplexP2WithElementBubbleLocalInterpolation
461  {
462  public:
463 
465  template<typename F, typename C>
466  void interpolate (const F& f, std::vector<C>& out) const
467  {
468  typename LB::Traits::DomainType x;
469  typename LB::Traits::RangeType y;
470 
471  out.resize(7);
472 
473  // vertices
474  x[0] = 0.0; x[1] = 0.0; out[0] = f(x);
475  x[0] = 1.0; x[1] = 0.0; out[2] = f(x);
476  x[0] = 0.0; x[1] = 1.0; out[5] = f(x);
477 
478  // edge bubbles
479  x[0] = 0.5; x[1] = 0.0; y = f(x);
480  out[1] = y - out[0]*(1-x[0]) - out[2]*x[0];
481 
482  x[0] = 0.0; x[1] = 0.5; y = f(x);
483  out[3] = y - out[0]*(1-x[1]) - out[5]*x[1];
484 
485  x[0] = 0.5; x[1] = 0.5; y = f(x);
486  out[4] = y - out[2]*x[0] - out[5]*x[1];
487 
488  // element bubble
489  x[0] = 1.0/3; x[1] = 1.0/3; y = f(x);
490 
492  HierarchicalSimplexP2WithElementBubbleLocalBasis<double,double,2> shapeFunctions;
493  std::vector<typename LB::Traits::RangeType> sfValues;
494  shapeFunctions.evaluateFunction(x, sfValues);
495 
496  out[6] = y;
497  for (int i=0; i<6; i++)
498  out[6] -= out[i]*sfValues[i];
499 
500  }
501 
502  };
503 
504 
505 }
506 #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:74
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:53
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:62
unsigned int order() const
Polynomial order of the shape functions (2, in this case)
Definition: hierarchicalsimplexp2withelementbubble.hh:110
unsigned int size() const
number of shape functions
Definition: hierarchicalsimplexp2withelementbubble.hh:56
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:85
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:270
void evaluateFunction(const typename Traits::DomainType &in, std::vector< typename Traits::RangeType > &out) const
Evaluate all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:276
unsigned int order() const
Polynomial order of the shape functions (4 in this case)
Definition: hierarchicalsimplexp2withelementbubble.hh:380
void evaluateJacobian(const typename Traits::DomainType &in, std::vector< typename Traits::JacobianType > &out) const
Evaluate Jacobian of all shape functions.
Definition: hierarchicalsimplexp2withelementbubble.hh:297
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:319
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:267
The local finite element needed for the Zou-Kornhuber estimator for Signorini problems.
Definition: hierarchicalsimplexp2withelementbubble.hh:416
size_t size() const
number of coefficients
Definition: hierarchicalsimplexp2withelementbubble.hh:441
const Dune::LocalKey & localKey(size_t i) const
get i'th index
Definition: hierarchicalsimplexp2withelementbubble.hh:447
HierarchicalSimplexP2WithElementBubbleLocalCoefficients()
Standard constructor.
Definition: hierarchicalsimplexp2withelementbubble.hh:425
Describe position of one degree of freedom.
Definition: localkey.hh:24
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:279
Dune namespace.
Definition: alignedallocator.hh:13
constexpr std::integral_constant< std::size_t, sizeof...(II)> size(std::integer_sequence< T, II... >)
Return the size of the sequence.
Definition: integersequence.hh:75
Type traits for LocalBasisVirtualInterface.
Definition: localbasis.hh:35
D DomainType
domain type
Definition: localbasis.hh:43
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (Apr 27, 22:29, 2024)