HyperHDG
tensorial.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
4 #include <tpp/tpp_assert.hxx>
5 
6 #include <array>
7 #include <cmath>
8 #include <numeric>
9 
10 namespace TPP
11 {
12 namespace Quadrature
13 {
14 /*!*************************************************************************************************
15  * \brief General integrator class on tensorial hypergraphs.
16  *
17  * \tparam quadrature_t The one-dimensional quadrature rule applied.
18  * \param shape_t Type of shape functions.
19  * \tparam return_t Floating type specification. Default is double.
20  *
21  * \authors Andreas Rupp, Heidelberg University, 2021.
22  **************************************************************************************************/
23 template <typename quadrature_t, typename shape_t, typename return_t = double>
24 class Tensorial
25 {
26  public:
27  /*!***********************************************************************************************
28  * \brief Make type of shape functions publicly available.
29  ************************************************************************************************/
30  typedef shape_t shape_fun_t;
31  /*!***********************************************************************************************
32  * \brief The dimension of the Lebesque measure with respect to which we integrate.
33  ************************************************************************************************/
34  static constexpr unsigned int dim() { return shape_t::dim(); }
35  /*!***********************************************************************************************
36  * \brief Calculate the amount of quadrature points.
37  ************************************************************************************************/
38  static constexpr unsigned int n_quad_points()
39  {
40  return Hypercube<dim()>::pow(quadrature_t::n_quad_points());
41  }
42 
43  /*!***********************************************************************************************
44  * \brief Quadrature points on one-dimensional unit interval.
45  ************************************************************************************************/
46  static constexpr std::array<return_t, quadrature_t::n_points()> quad_points =
47  quadrature_t::template points<return_t>();
48  /*!***********************************************************************************************
49  * \brief Quadrature weights on one-dimensional unit interval.
50  ************************************************************************************************/
51  static constexpr std::array<return_t, quadrature_t::n_points()> quad_weights =
52  quadrature_t::template weights<return_t>();
53 
54  private:
55  /*!***********************************************************************************************
56  * \brief Amount of shape functions with respect to a single spatial dimension.
57  ************************************************************************************************/
58  static constexpr unsigned int n_fun_1D = shape_t::shape_fun_t::shape_fun_1d::n_fun();
59  /*!***********************************************************************************************
60  * \brief Shape functions evaluated at quadrature points of unit interval.
61  ************************************************************************************************/
62  static constexpr std::array<std::array<return_t, quadrature_t::n_points()>, n_fun_1D>
64  {
65  std::array<std::array<return_t, quadrature_t::n_points()>, n_fun_1D> result;
66 
67  for (unsigned int fct = 0; fct < n_fun_1D; ++fct)
68  for (unsigned int pt = 0; pt < quadrature_t::n_points(); ++pt)
69  result[fct][pt] = shape_t::shape_fun_t::shape_fun_1d::template fct_val<return_t>(
70  fct, quadrature_t::points()[pt]);
71 
72  return result;
73  }
74  /*!***********************************************************************************************
75  * \brief Derivatives of shape functions evaluated at quadrature points of unit interval.
76  ************************************************************************************************/
77  std::array<std::array<return_t, quadrature_t::n_points()>,
78  n_fun_1D> static constexpr shape_ders_at_quad_points()
79  {
80  std::array<std::array<return_t, quadrature_t::n_points()>, n_fun_1D> result;
81 
82  for (unsigned int fct = 0; fct < n_fun_1D; ++fct)
83  for (unsigned int pt = 0; pt < quadrature_t::n_points(); ++pt)
84  result[fct][pt] = shape_t::shape_fun_t::shape_fun_1d::template der_val<return_t>(
85  fct, quadrature_t::points()[pt]);
86 
87  return result;
88  }
89  /*!***********************************************************************************************
90  * \brief Shape functions evaluated at boundaries of unit interval.
91  ************************************************************************************************/
92  std::array<std::array<return_t, 2>, n_fun_1D> static constexpr shape_fcts_at_bdrs()
93  {
94  std::array<std::array<return_t, 2>, n_fun_1D> result;
95 
96  for (unsigned int fct = 0; fct < n_fun_1D; ++fct)
97  for (unsigned int pt = 0; pt < 2; ++pt)
98  result[fct][pt] = shape_t::shape_fun_t::shape_fun_1d::template fct_val<return_t>(fct, pt);
99 
100  return result;
101  }
102  /*!***********************************************************************************************
103  * \brief Derivatives of shape functions evaluated at boundaries of unit interval.
104  ************************************************************************************************/
105  std::array<std::array<return_t, 2>, n_fun_1D> static constexpr shape_ders_at_bdrs()
106  {
107  std::array<std::array<return_t, 2>, n_fun_1D> result;
108 
109  for (unsigned int fct = 0; fct < n_fun_1D; ++fct)
110  for (unsigned int pt = 0; pt < 2; ++pt)
111  result[fct][pt] = shape_t::shape_fun_t::shape_fun_1d::template der_val<return_t>(fct, pt);
112 
113  return result;
114  }
115 
116  public:
117  /*!***********************************************************************************************
118  * \brief Shape functions evaluated at quadrature points of unit interval.
119  ************************************************************************************************/
120  static constexpr std::array<std::array<return_t, quadrature_t::n_points()>, n_fun_1D>
122  /*!***********************************************************************************************
123  * \brief Derivatives of shape functions evaluated at quadrature points of unit interval.
124  ************************************************************************************************/
125  static constexpr std::array<std::array<return_t, quadrature_t::n_points()>, n_fun_1D>
127  /*!***********************************************************************************************
128  * \brief Shape functions evaluated at boundaries of unit interval.
129  ************************************************************************************************/
130  static constexpr std::array<std::array<return_t, 2>, n_fun_1D> shape_fcts_at_bdr =
132  /*!***********************************************************************************************
133  * \brief Derivatives of shape functions evaluated at boundaries of unit interval.
134  ************************************************************************************************/
135  static constexpr std::array<std::array<return_t, 2>, n_fun_1D> shape_ders_at_bdr =
137  /*!***********************************************************************************************
138  * \brief Integrate product of one-dimensional shape functions.
139  *
140  * \param i Local index of local one-dimensional shape function.
141  * \param j Local index of local one-dimensional shape function.
142  * \retval integral Integral of product of both shape functions.
143  ************************************************************************************************/
144  static constexpr return_t integrate_1D_phiphi(const unsigned int i, const unsigned int j)
145  {
146  tpp_assert(i < n_fun_1D && j < n_fun_1D,
147  "Indices of shape functions must be smaller than amount of shape functions.");
148  return_t result = 0.;
149 
150  for (unsigned int q = 0; q < quad_weights.size(); ++q)
151  result += quad_weights[q] * shape_fcts_at_quad[i][q] * shape_fcts_at_quad[j][q];
152 
153  return result;
154  }
155  /*!***********************************************************************************************
156  * \brief Integrate product of one-dimensional shape function and one derivative.
157  *
158  * \param i Local index of local one-dimensional shape function.
159  * \param j Local index of local one-dimensional shape function (with derivative).
160  * \retval integral Integral of product of both shape functions.
161  ************************************************************************************************/
162  static constexpr return_t integrate_1D_phiDphi(const unsigned int i, const unsigned int j)
163  {
164  tpp_assert(i < n_fun_1D && j < n_fun_1D,
165  "Indices of shape functions must be smaller than amount of shape functions.");
166  return_t result = 0.;
167 
168  for (unsigned int q = 0; q < quad_weights.size(); ++q)
169  result += quad_weights[q] * shape_fcts_at_quad[i][q] * shape_ders_at_quad[j][q];
170 
171  return result;
172  }
173  /*!***********************************************************************************************
174  * \brief Integrate product of one-dimensional shape function and one derivative.
175  *
176  * \param i Local index of local one-dimensional shape function (with derivative).
177  * \param j Local index of local one-dimensional shape function.
178  * \retval integral Integral of product of both shape functions.
179  ************************************************************************************************/
180  static constexpr return_t integrate_1D_Dphiphi(const unsigned int i, const unsigned int j)
181  {
182  tpp_assert(i < n_fun_1D && j < n_fun_1D,
183  "Indices of shape functions must be smaller than amount of shape functions.");
184  return_t result = 0.;
185 
186  for (unsigned int q = 0; q < quad_weights.size(); ++q)
187  result += quad_weights[q] * shape_ders_at_quad[i][q] * shape_fcts_at_quad[j][q];
188 
189  return result;
190  }
191  /*!***********************************************************************************************
192  * \brief Integrate product of two one-dimensional shape functions' derivatives.
193  *
194  * \param i Local index of local one-dimensional shape function (with derivative).
195  * \param j Local index of local one-dimensional shape function (with derivative).
196  * \retval integral Integral of product of both shape functions.
197  ************************************************************************************************/
198  static constexpr return_t integrate_1D_DphiDphi(const unsigned int i, const unsigned int j)
199  {
200  tpp_assert(i < n_fun_1D && j < n_fun_1D,
201  "Indices of shape functions must be smaller than amount of shape functions.");
202  return_t result = 0.;
203 
204  for (unsigned int q = 0; q < quad_weights.size(); ++q)
205  result += quad_weights[q] * shape_ders_at_quad[i][q] * shape_ders_at_quad[j][q];
206 
207  return result;
208  }
209  /*!***********************************************************************************************
210  * \brief Integrate product of shape functions over dimT-dimensional unit volume.
211  *
212  * \param i Local index of local shape function.
213  * \param j Local index of local shape function.
214  * \retval integral Integral of product of both shape functions.
215  ************************************************************************************************/
216  static constexpr return_t integrate_vol_phiphi(const unsigned int i, const unsigned int j)
217  {
218  return_t integral = 1.;
219  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
220  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
221  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
222  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
223  return integral;
224  }
225  /*!***********************************************************************************************
226  * \brief Integrate product of shape function amd derivative over dimT-dimensional unit volume.
227  *
228  * \param i Local index of local shape function.
229  * \param j Local index of local shape function (with derivative).
230  * \param dim_der Dimension of the derivative.
231  * \retval integral Integral of product of both shape functions.
232  ************************************************************************************************/
233  static constexpr return_t integrate_vol_phiDphi(const unsigned int i,
234  const unsigned int j,
235  const unsigned int dim_der)
236  {
237  return_t integral = 1.;
238  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
239  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
240  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
241  if (dim_der == dim_fct)
242  integral *= integrate_1D_phiDphi(dec_i[dim_fct], dec_j[dim_fct]);
243  else
244  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
245  return integral;
246  }
247  /*!***********************************************************************************************
248  * \brief Integrate product of shape function and derivative over dimT-dimensional unit volume.
249  *
250  * \param i Local index of local shape function (with derivative).
251  * \param j Local index of local shape function.
252  * \param dim_der Dimension of the derivative.
253  * \retval integral Integral of product of both shape functions.
254  ************************************************************************************************/
255  static constexpr return_t integrate_vol_Dphiphi(const unsigned int i,
256  const unsigned int j,
257  const unsigned int dim_der)
258  {
259  return_t integral = 1.;
260  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
261  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
262  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
263  if (dim_der == dim_fct)
264  integral *= integrate_1D_Dphiphi(dec_i[dim_fct], dec_j[dim_fct]);
265  else
266  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
267  return integral;
268  }
269  /*!***********************************************************************************************
270  * \brief Integrate product of shape functions over dimT-dimensional volume's boundary.
271  *
272  * \param i Local index of local shape function.
273  * \param j Local index of local shape function.
274  * \param bdr Boundary face index.
275  * \retval integral Integral of product of both shape functions.
276  ************************************************************************************************/
277  static constexpr return_t integrate_bdr_phiphi(const unsigned int i,
278  const unsigned int j,
279  const unsigned int bdr)
280  {
281  return_t integral = 1.;
282  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
283  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
284  unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
285  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
286  if (bdr_dim == dim_fct)
287  integral *=
288  shape_fcts_at_bdr[dec_i[dim_fct]][bdr_ind] * shape_fcts_at_bdr[dec_j[dim_fct]][bdr_ind];
289  else
290  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
291  return integral;
292  }
293  /*!***********************************************************************************************
294  * \brief Integrate product of shape function of volume times shape function of volume's face
295  * over dimT-dimensional volume's boundary.
296  *
297  * \param i Local index of local volume shape function.
298  * \param j Local index of local boundary shape function.
299  * \param bdr Boundary face index.
300  * \retval integral Integral of product of both shape functions.
301  ************************************************************************************************/
302  static constexpr return_t integrate_bdr_phipsi(const unsigned int i,
303  const unsigned int j,
304  const unsigned int bdr)
305  {
306  return_t integral = 1.;
307  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
308  std::array<unsigned int, std::max(dim() - 1, 1U)> dec_j =
309  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
310  unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
311  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
312  if (bdr_dim == dim_fct)
313  integral *= shape_fcts_at_bdr[dec_i[dim_fct]][bdr_ind];
314  else
315  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct - (dim_fct > bdr_dim)]);
316  return integral;
317  }
318 
319  /*!***********************************************************************************************
320  * \brief Integrate product of shape functions times some function over some geometry.
321  *
322  * \tparam point_t Type of point which is the first argument of the function.
323  * \tparam geom_t Geometry which is the integration domain.
324  * \tparam fun Function that is also to be integrated.
325  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
326  * \param i Local index of local shape function.
327  * \param j Local index of local shape function.
328  * \param geom Geometrical information.
329  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
330  * \retval integral Integral of product of both shape functions.
331  ************************************************************************************************/
332  template <typename point_t,
333  typename geom_t,
334  return_t fun(const point_t&, const return_t),
335  typename smallVec_t = point_t>
336  static return_t integrate_vol_phiphifunc(const unsigned int i,
337  const unsigned int j,
338  geom_t& geom,
339  const return_t f_param = 0.)
340  {
341  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
342  return_t integral = 0., quad_val;
343  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
344  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
345  std::array<unsigned int, dim()> dec_q;
346  smallVec_t quad_pt;
347 
348  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
349  {
350  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
351  quad_val = 1.;
352  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
353  {
354  quad_pt[dim] = quad_points[dec_q[dim]];
355  quad_val *= quad_weights[dec_q[dim]] * shape_fcts_at_quad[dec_i[dim]][dec_q[dim]] *
356  shape_fcts_at_quad[dec_j[dim]][dec_q[dim]];
357  }
358  integral += fun(geom.map_ref_to_phys(quad_pt), f_param) * quad_val;
359  }
360  return integral * geom.area();
361  }
362  /*!***********************************************************************************************
363  * \brief Integrate product of shape functions times some function over some geometry.
364  *
365  * \tparam smallVec_t Type of vector which is returned by the function.
366  * \tparam point_t Type of point which is the first argument of the function.
367  * \tparam geom_t Geometry which is the integration domain.
368  * \tparam fun Function that is also to be integrated.
369  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
370  * \param i Local index of local shape function.
371  * \param j Local index of local shape function.
372  * \param dimension Local dimension with respect to which the vector-function is integrated.
373  * \param geom Geometrical information.
374  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
375  * \retval integral Integral of product of both shape functions.
376  ************************************************************************************************/
377  template <typename point_t,
378  typename geom_t,
379  point_t fun(const point_t&, const return_t),
380  typename smallVec_t = point_t>
381  static return_t integrate_vol_phiphivecfunc(const unsigned int i,
382  const unsigned int j,
383  const unsigned int dimension,
384  geom_t& geom,
385  const return_t f_param = 0.)
386  {
387  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
388  return_t integral = 0., quad_val;
389  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
390  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
391  std::array<unsigned int, dim()> dec_q;
392  smallVec_t quad_pt;
393  const auto mat_q = geom.mat_q();
394 
395  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
396  {
397  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
398  quad_val = 1.;
399  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
400  {
401  quad_pt[dim] = quad_points[dec_q[dim]];
402  quad_val *= quad_weights[dec_q[dim]] * shape_fcts_at_quad[dec_i[dim]][dec_q[dim]] *
403  shape_fcts_at_quad[dec_j[dim]][dec_q[dim]];
404  }
405  integral +=
406  scalar_product(fun(geom.map_ref_to_phys(quad_pt), f_param), mat_q.get_column(dimension)) *
407  quad_val;
408  }
409  return integral * geom.area();
410  }
411  /*!***********************************************************************************************
412  * \brief Integrate product of shape functions over some geometry.
413  *
414  * \tparam geom_t Geometry which is the integration domain.
415  * \param i Local index of local shape function.
416  * \param j Local index of local shape function.
417  * \param geom Geometrical information.
418  * \retval integral Integral of product of both shape functions.
419  ************************************************************************************************/
420  template <typename geom_t>
421  static return_t integrate_vol_phiphi(const unsigned int i, const unsigned int j, geom_t& geom)
422  {
423  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
424  return_t integral = 1.;
425  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
426  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
427  for (unsigned int dim_fct = 0; dim_fct < dim(); ++dim_fct)
428  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
429  return integral * geom.area();
430  }
431  /*!***********************************************************************************************
432  * \brief Integrate product of linear combinations of shape functions over some geometry.
433  *
434  * \tparam geom_t Geometry which is the integration domain.
435  * \tparam array_size Size of arrays containing coefficients of linear combinations.
436  * \tparam floating_t The floating point type for the calculation.
437  * \param is Coefficients of local shape functions.
438  * \param js Coefficients of local shape functions.
439  * \param geom Geometrical information.
440  * \retval integral Integral of product of lineat combinations of shape functions.
441  ************************************************************************************************/
442  template <typename geom_t, std::size_t array_size, typename floating_t>
443  static return_t integrate_vol_phiphi(const std::array<floating_t, array_size>& is,
444  const std::array<floating_t, array_size>& js,
445  geom_t& geom)
446  {
447  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
448  return_t integral = 0., quad_val, is_val, js_val, val_helper;
449 
450  std::array<unsigned int, dim()> dec_k, dec_q;
451 
452  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
453  {
454  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
455  quad_val = 1.;
456  is_val = 0.;
457  js_val = 0.;
458 
459  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
460  quad_val *= quad_weights[dec_q[dim]];
461 
462  for (unsigned int k = 0; k < array_size; ++k)
463  {
464  dec_k = Hypercube<dim()>::index_decompose(k, n_fun_1D);
465  val_helper = 1.;
466  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
467  val_helper *= shape_fcts_at_quad[dec_k[dim]][dec_q[dim]];
468  is_val += is[k] * val_helper;
469  js_val += js[k] * val_helper;
470  }
471  integral += quad_val * is_val * js_val;
472  }
473  return integral * geom.area();
474  }
475  /*!***********************************************************************************************
476  * \brief Integrate product of shape function times some function over some geometry.
477  *
478  * \tparam point_t Type of point which is the first argument of the function.
479  * \tparam geom_t Geometry which is the integration domain.
480  * \tparam fun Function whose product with shape function is integrated.
481  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
482  * \param i Local index of local shape function.
483  * \param geom Geometrical information.
484  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
485  * \retval integral Integral of product of both shape functions.
486  ************************************************************************************************/
487  template <typename point_t,
488  typename geom_t,
489  return_t fun(const point_t&, const return_t),
490  typename smallVec_t = point_t>
491  static return_t integrate_vol_phifunc(const unsigned int i,
492  geom_t& geom,
493  const return_t f_param = 0.)
494  {
495  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
496  return_t integral = 0., quad_val;
497  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
498  std::array<unsigned int, dim()> dec_q;
499  smallVec_t quad_pt;
500 
501  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
502  {
503  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
504  quad_val = 1.;
505  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
506  {
507  quad_pt[dim] = quad_points[dec_q[dim]];
508  quad_val *= quad_weights[dec_q[dim]] * shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
509  }
510  integral += fun(geom.map_ref_to_phys(quad_pt), f_param) * quad_val;
511  }
512  return integral * geom.area();
513  }
514  /*!***********************************************************************************************
515  * \brief Average integral of product of shape function times some function over some geometry.
516  *
517  * \tparam point_t Type of point which is the first argument of the function.
518  * \tparam geom_t Geometry which is the integration domain.
519  * \tparam fun Function whose product with shape function is integrated.
520  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
521  * \param i Local index of local shape function.
522  * \param geom Geometrical information.
523  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
524  * \retval integral Integral of product of both shape functions.
525  ************************************************************************************************/
526  template <typename point_t,
527  typename geom_t,
528  return_t fun(const point_t&, const return_t),
529  typename smallVec_t = point_t>
530  static return_t integrate_volUni_phifunc(const unsigned int i,
531  geom_t& geom,
532  const return_t f_param = 0.)
533  {
534  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
535  return_t integral = 0., quad_val;
536  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
537  std::array<unsigned int, dim()> dec_q;
538  smallVec_t quad_pt;
539 
540  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
541  {
542  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
543  quad_val = 1.;
544  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
545  {
546  quad_pt[dim] = quad_points[dec_q[dim]];
547  quad_val *= quad_weights[dec_q[dim]] * shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
548  }
549  integral += fun(geom.map_ref_to_phys(quad_pt), f_param) * quad_val;
550  }
551  return integral;
552  }
553  /*!***********************************************************************************************
554  * \brief Integrate gradient of shape function times other shape function over some geometry.
555  *
556  * \note poly_deg_i and poly_deg_j must be set to the maximum polynomial degree (which is also
557  * their default value) if the basis is not hierarchical.
558  *
559  * \tparam smallVec_t Type of the return value.
560  * \tparam geom_t Geometry which is the integration domain.
561  * \tparam poly_deg_i Polynomial degree of shape functions associated to i.
562  * \tparam poly_deg_j Polynomial degree of shape functions associated to j.
563  * \param i Local index of local shape function with gradient.
564  * \param j Local index of local shape function.
565  * \param geom Geometrical information.
566  * \retval integral Integral of product of both shape functions.
567  ************************************************************************************************/
568  template <typename smallVec_t,
569  typename geom_t,
570  unsigned int poly_deg_i = shape_t::degree(),
571  unsigned int poly_deg_j = shape_t::degree()>
572  static smallVec_t integrate_vol_nablaphiphi(const unsigned int i,
573  const unsigned int j,
574  geom_t& geom)
575  {
576  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
577  static_assert(poly_deg_i <= shape_t::degree() && poly_deg_j <= shape_t::degree(),
578  "The maximum polynomial degrees must be larger than or equal to the given ones.");
579  smallVec_t integral(1.);
580  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, poly_deg_i + 1);
581  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, poly_deg_j + 1);
582  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
583  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
584  if (dim == dim_fct)
585  integral[dim] *= integrate_1D_Dphiphi(dec_i[dim_fct], dec_j[dim_fct]);
586  else
587  integral[dim] *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
588  return geom.area() * integral / transposed(geom.mat_r());
589  }
590  /*!***********************************************************************************************
591  * \brief Integrate gradient of shape functions times other function over some geometry.
592  *
593  * \tparam point_t Type of point which is the first argument of the function.
594  * \tparam geom_t Geometry which is the integration domain.
595  * \tparam fun Weight function that is additionally integrated.
596  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
597  * \param i Local index of local shape function.
598  * \param j Local index of local shape function.
599  * \param geom Geometrical information.
600  * \param f_param Time at which fun is evaluated.
601  * \retval integral Integral of product of both shape function's weighted gradients.
602  ************************************************************************************************/
603  template <typename point_t,
604  typename geom_t,
605  return_t fun(const point_t&, const return_t),
606  typename smallVec_t = point_t>
607  static return_t integrate_vol_nablaphinablaphifunc(const unsigned int i,
608  const unsigned int j,
609  geom_t& geom,
610  return_t f_param = 0.)
611  {
612  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
613  return_t integral = 0., quad_weight;
614  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
615  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
616  std::array<unsigned int, dim()> dec_q;
617  smallVec_t quad_pt, nabla_phi_i, nabla_phi_j;
618  const auto rrT = mat_times_transposed_mat(geom.mat_r(), geom.mat_r());
619 
620  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
621  {
622  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
623  quad_weight = 1.;
624  nabla_phi_i = 1.;
625  nabla_phi_j = 1.;
626  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
627  {
628  quad_pt[dim] = quad_points[dec_q[dim]];
629  quad_weight *= quad_weights[dec_q[dim]];
630  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
631  {
632  if (dim == dim_fct)
633  {
634  nabla_phi_i[dim_fct] *= shape_ders_at_quad[dec_i[dim]][dec_q[dim]];
635  nabla_phi_j[dim_fct] *= shape_ders_at_quad[dec_j[dim]][dec_q[dim]];
636  }
637  else
638  {
639  nabla_phi_i[dim_fct] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
640  nabla_phi_j[dim_fct] *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim]];
641  }
642  }
643  }
644  integral += quad_weight * fun(geom.map_ref_to_phys(quad_pt), f_param) *
645  scalar_product(nabla_phi_i, nabla_phi_j / rrT);
646  }
647  return geom.area() * integral;
648  }
649  /*!***********************************************************************************************
650  * \brief Integrate derivative of shape function times other function over some geometry.
651  *
652  * \tparam point_t Type of point which is the first argument of the function.
653  * \tparam geom_t Geometry which is the integration domain.
654  * \tparam fun Weight function that is additionally integrated.
655  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
656  * \param i Local index of local shape function.
657  * \param dim_der Dimension with respect to which derivative is calculated.
658  * \param geom Geometrical information.
659  * \param f_param Time at which fun is evaluated.
660  * \retval integral Integral of product of both shape function's weighted gradients.
661  ************************************************************************************************/
662  template <typename point_t,
663  typename geom_t,
664  return_t fun(const point_t&, const return_t),
665  typename smallVec_t = point_t>
666  static return_t integrate_vol_derphifunc(const unsigned int i,
667  const unsigned int dim_der,
668  geom_t& geom,
669  return_t f_param = 0.)
670  {
671  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
672  return_t integral = 0., quad_weight;
673  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
674  std::array<unsigned int, dim()> dec_q;
675  smallVec_t quad_pt, nabla_phi_i;
676  const auto rT = transposed(geom.mat_r());
677 
678  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
679  {
680  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
681  quad_weight = 1.;
682  nabla_phi_i = 1.;
683  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
684  {
685  quad_pt[dim] = quad_points[dec_q[dim]];
686  quad_weight *= quad_weights[dec_q[dim]];
687  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
688  {
689  if (dim == dim_fct)
690  nabla_phi_i[dim_fct] *= shape_ders_at_quad[dec_i[dim]][dec_q[dim]];
691  else
692  nabla_phi_i[dim_fct] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
693  }
694  }
695  integral +=
696  quad_weight * fun(geom.map_ref_to_phys(quad_pt), f_param) * (nabla_phi_i / rT)[dim_der];
697  }
698  return geom.area() * integral;
699  }
700 
701  /*!***********************************************************************************************
702  * \brief Integrate gradient of shape function times other shape function times vector function.
703  *
704  * \tparam smallVec_t Type of vector which is returned by the function.
705  * \tparam point_t Type of point which is the first argument of the function.
706  * \tparam geom_t Geometry which is the integration domain.
707  * \tparam fun Function that is also to be integrated.
708  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
709  * \param i Local index of local gradient shape function.
710  * \param j Local index of local shape function.
711  * \param geom Geometrical information.
712  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
713  * \retval integral Integral of product of both shape functions.
714  ************************************************************************************************/
715  template <typename point_t,
716  typename geom_t,
717  point_t fun(const point_t&, const return_t),
718  typename smallVec_t = point_t>
719  static return_t integrate_vol_nablaphiphivecfunc(const unsigned int i,
720  const unsigned int j,
721  geom_t& geom,
722  const return_t f_param = 0.)
723  {
724  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
725  return_t integral = 0., quad_val;
726  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
727  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
728  std::array<unsigned int, dim()> dec_q;
729  smallVec_t quad_pt, nabla_phi_i;
730  point_t fun_val;
731  const auto qT = transposed(geom.mat_q());
732  const auto rT = transposed(geom.mat_r());
733 
734  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
735  {
736  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
737  quad_val = 1.;
738  nabla_phi_i = 1.;
739  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
740  {
741  quad_pt[dim] = quad_points[dec_q[dim]];
742  quad_val *= quad_weights[dec_q[dim]] * shape_fcts_at_quad[dec_j[dim]][dec_q[dim]];
743  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
744  {
745  if (dim == dim_fct)
746  nabla_phi_i[dim_fct] *= shape_ders_at_quad[dec_i[dim]][dec_q[dim]];
747  else
748  nabla_phi_i[dim_fct] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
749  }
750  }
751  nabla_phi_i = nabla_phi_i / rT;
752  fun_val = qT * fun(geom.map_ref_to_phys(quad_pt), f_param);
753  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
754  integral += fun_val[dim] * nabla_phi_i[dim] * quad_val;
755  }
756  return integral * geom.area();
757  }
758  /*!***********************************************************************************************
759  * \brief Integrate shape function times shape function times vector function times normal.
760  *
761  * \tparam point_t Type of point which is the first argument of the function.
762  * \tparam geom_t Geometry which is the integration domain.
763  * \tparam fun Weight function that is additionally integrated.
764  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
765  * \param i Local index of local shape function with gradient.
766  * \param j Local index of local shape function.
767  * \param bdr Index of the boundatry face to integrate over.
768  * \param geom Geometrical information.
769  * \param f_param Time at which fun is evaluated.
770  * \retval integral Integral of product of both shape function's weighted gradients.
771  ************************************************************************************************/
772  template <typename point_t,
773  typename geom_t,
774  point_t fun(const point_t&, const return_t),
775  typename smallVec_t = point_t>
776  static return_t integrate_bdr_phiphinuvecfunc_cutwind(const unsigned int i,
777  const unsigned int j,
778  const unsigned int bdr,
779  geom_t& geom,
780  return_t f_param = 0.)
781  {
782  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
783  return_t integral = 0., quad_weight, phi_i, phi_j, winding;
784  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
785  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
786  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
787  smallVec_t quad_pt;
788  point_t normal = geom.inner_normal(bdr);
789  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
790 
791  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
792  {
793  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
794  quad_weight = 1.;
795  phi_i = 1.;
796  phi_j = 1.;
797  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
798  {
799  if (dim == bdr_dim)
800  {
801  quad_pt[dim] = (return_t)bdr_ind;
802  phi_i *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
803  phi_j *= shape_fcts_at_bdr[dec_j[dim]][bdr_ind];
804  }
805  else
806  {
807  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
808  phi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
809  phi_j *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim - (dim > bdr_dim)]];
810  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
811  }
812  }
813  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
814  if (winding > 0)
815  integral += geom.face_area(bdr) * quad_weight * phi_i * phi_j * winding;
816  }
817 
818  return integral;
819  }
820 
821  /*!***********************************************************************************************
822  * \brief Integrate cut upwind of product of shape functions.
823  *
824  * \tparam point_t Type of point which is the first argument of the function.
825  * \tparam geom_t Geometry which is the integration domain.
826  * \tparam fun Weight function that is additionally integrated.
827  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
828  * \param i Local index of local shape function with gradient.
829  * \param j Local index of local shape function.
830  * \param bdr Index of the boundatry face to integrate over.
831  * \param geom Geometrical information.
832  * \param f_param Time at which fun is evaluated.
833  * \retval integral Integral of product of both shape function's weighted gradients.
834  ************************************************************************************************/
835  template <typename point_t,
836  typename geom_t,
837  point_t fun(const point_t&, const return_t),
838  typename smallVec_t = point_t>
839  static return_t integrate_bdr_phiphi_cutwind(const unsigned int i,
840  const unsigned int j,
841  const unsigned int bdr,
842  geom_t& geom,
843  return_t f_param = 0.)
844  {
845  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
846  return_t integral = 0., quad_weight, phi_i, phi_j, winding;
847  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
848  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
849  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
850  smallVec_t quad_pt;
851  point_t normal = geom.inner_normal(bdr);
852  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
853 
854  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
855  {
856  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
857  quad_weight = 1.;
858  phi_i = 1.;
859  phi_j = 1.;
860  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
861  {
862  if (dim == bdr_dim)
863  {
864  quad_pt[dim] = (return_t)bdr_ind;
865  phi_i *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
866  phi_j *= shape_fcts_at_bdr[dec_j[dim]][bdr_ind];
867  }
868  else
869  {
870  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
871  phi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
872  phi_j *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim - (dim > bdr_dim)]];
873  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
874  }
875  }
876  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
877  if (winding > 0)
878  integral += geom.face_area(bdr) * quad_weight * phi_i * phi_j;
879  }
880 
881  return integral;
882  }
883 
884  /*!***********************************************************************************************
885  * \brief Integrate cut upwind of shape function times skeletal shape function.
886  *
887  * \tparam point_t Type of point which is the first argument of the function.
888  * \tparam geom_t Geometry which is the integration domain.
889  * \tparam fun Weight function that is additionally integrated.
890  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
891  * \param i Local index of local shape function with gradient.
892  * \param j Local index of local shape function.
893  * \param bdr Index of the boundatry face to integrate over.
894  * \param geom Geometrical information.
895  * \param f_param Time at which fun is evaluated.
896  * \retval integral Integral of product of both shape function's weighted gradients.
897  ************************************************************************************************/
898  template <typename point_t,
899  typename geom_t,
900  point_t fun(const point_t&, const return_t),
901  typename smallVec_t = point_t>
902  static return_t integrate_bdr_phipsinuvecfunc_cutwind(const unsigned int i,
903  const unsigned int j,
904  const unsigned int bdr,
905  geom_t& geom,
906  return_t f_param = 0.)
907  {
908  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
909  return_t integral = 0., quad_weight, phi_i, psi_j, winding;
910  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
911  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
912  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
913  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
914  smallVec_t quad_pt;
915  point_t normal = geom.inner_normal(bdr);
916  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
917 
918  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
919  {
920  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
921  quad_weight = 1.;
922  phi_i = 1.;
923  psi_j = 1.;
924  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
925  {
926  if (dim == bdr_dim)
927  {
928  quad_pt[dim] = (return_t)bdr_ind;
929  phi_i *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
930  }
931  else
932  {
933  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
934  phi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
935  psi_j *= shape_fcts_at_quad[dec_j[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
936  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
937  }
938  }
939  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
940 
941  if (winding < 0)
942  integral += geom.face_area(bdr) * quad_weight * phi_i * psi_j * winding;
943  }
944 
945  return integral;
946  }
947 
948  /*!***********************************************************************************************
949  * \brief Integrate cut downwind of shape function times skeletal shape function.
950  *
951  * \tparam point_t Type of point which is the first argument of the function.
952  * \tparam geom_t Geometry which is the integration domain.
953  * \tparam fun Weight function that is additionally integrated.
954  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
955  * \param i Local index of local shape function with gradient.
956  * \param j Local index of local shape function.
957  * \param bdr Index of the boundatry face to integrate over.
958  * \param geom Geometrical information.
959  * \param f_param Time at which fun is evaluated.
960  * \retval integral Integral of product of both shape function's weighted gradients.
961  ************************************************************************************************/
962  template <typename point_t,
963  typename geom_t,
964  point_t fun(const point_t&, const return_t),
965  typename smallVec_t = point_t>
966  static return_t integrate_bdr_phipsi_cutdownwind(const unsigned int i,
967  const unsigned int j,
968  const unsigned int bdr,
969  geom_t& geom,
970  return_t f_param = 0.)
971  {
972  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
973  return_t integral = 0., quad_weight, phi_i, psi_j, winding;
974  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
975  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
976  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
977  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
978  smallVec_t quad_pt;
979  point_t normal = geom.inner_normal(bdr);
980  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
981 
982  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
983  {
984  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
985  quad_weight = 1.;
986  phi_i = 1.;
987  psi_j = 1.;
988  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
989  {
990  if (dim == bdr_dim)
991  {
992  quad_pt[dim] = (return_t)bdr_ind;
993  phi_i *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
994  }
995  else
996  {
997  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
998  phi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
999  psi_j *= shape_fcts_at_quad[dec_j[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1000  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1001  }
1002  }
1003  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1004 
1005  if (winding > 0)
1006  integral += geom.face_area(bdr) * quad_weight * phi_i * psi_j;
1007  }
1008 
1009  return integral;
1010  }
1011 
1012  /*!***********************************************************************************************
1013  * \brief Integrate cut upwind of skeletal shape function times shape function times vector fct.
1014  *
1015  * \tparam point_t Type of point which is the first argument of the function.
1016  * \tparam geom_t Geometry which is the integration domain.
1017  * \tparam fun Weight function that is additionally integrated.
1018  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1019  * \param i Local index of local shape function with gradient.
1020  * \param j Local index of local shape function.
1021  * \param bdr Index of the boundatry face to integrate over.
1022  * \param geom Geometrical information.
1023  * \param f_param Time at which fun is evaluated.
1024  * \retval integral Integral of product of both shape function's weighted gradients.
1025  ************************************************************************************************/
1026  template <typename point_t,
1027  typename geom_t,
1028  point_t fun(const point_t&, const return_t),
1029  typename smallVec_t = point_t>
1030  static return_t integrate_bdr_psiphinuvecfunc_cutwind(const unsigned int i,
1031  const unsigned int j,
1032  const unsigned int bdr,
1033  geom_t& geom,
1034  return_t f_param = 0.)
1035  {
1036  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1037  return_t integral = 0., quad_weight, psi_i, phi_j, winding;
1038  std::array<unsigned int, std::max(1U, dim() - 1)> dec_i =
1039  Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1040  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
1041  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1042  smallVec_t quad_pt;
1043  point_t normal = geom.inner_normal(bdr);
1044  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1045 
1046  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1047  {
1048  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1049  quad_weight = 1.;
1050  psi_i = 1.;
1051  phi_j = 1.;
1052  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1053  {
1054  if (dim == bdr_dim)
1055  {
1056  quad_pt[dim] = (return_t)bdr_ind;
1057  phi_j *= shape_fcts_at_bdr[dec_j[dim]][bdr_ind];
1058  }
1059  else
1060  {
1061  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1062  psi_i *= shape_fcts_at_quad[dec_i[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1063  phi_j *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim - (dim > bdr_dim)]];
1064  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1065  }
1066  }
1067  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1068  if (winding > 0)
1069  integral += geom.face_area(bdr) * quad_weight * psi_i * phi_j * winding;
1070  }
1071  return integral;
1072  }
1073 
1074  /*!***********************************************************************************************
1075  * \brief Integrate cut upwind of skeletal shape function times shape function.
1076  *
1077  * \tparam point_t Type of point which is the first argument of the function.
1078  * \tparam geom_t Geometry which is the integration domain.
1079  * \tparam fun Weight function that is additionally integrated.
1080  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1081  * \param i Local index of local shape function with gradient.
1082  * \param j Local index of local shape function.
1083  * \param bdr Index of the boundatry face to integrate over.
1084  * \param geom Geometrical information.
1085  * \param f_param Time at which fun is evaluated.
1086  * \retval integral Integral of product of both shape function's weighted gradients.
1087  ************************************************************************************************/
1088  template <typename point_t,
1089  typename geom_t,
1090  point_t fun(const point_t&, const return_t),
1091  typename smallVec_t = point_t>
1092  static return_t integrate_bdr_psiphi_cutwind(const unsigned int i,
1093  const unsigned int j,
1094  const unsigned int bdr,
1095  geom_t& geom,
1096  return_t f_param = 0.)
1097  {
1098  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1099  return_t integral = 0., quad_weight, psi_i, phi_j, winding;
1100  std::array<unsigned int, std::max(1U, dim() - 1)> dec_i =
1101  Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1102  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
1103  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1104  smallVec_t quad_pt;
1105  point_t normal = geom.inner_normal(bdr);
1106  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1107 
1108  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1109  {
1110  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1111  quad_weight = 1.;
1112  psi_i = 1.;
1113  phi_j = 1.;
1114  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1115  {
1116  if (dim == bdr_dim)
1117  {
1118  quad_pt[dim] = (return_t)bdr_ind;
1119  phi_j *= shape_fcts_at_bdr[dec_j[dim]][bdr_ind];
1120  }
1121  else
1122  {
1123  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1124  psi_i *= shape_fcts_at_quad[dec_i[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1125  phi_j *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim - (dim > bdr_dim)]];
1126  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1127  }
1128  }
1129  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1130  if (winding > 0)
1131  integral += geom.face_area(bdr) * quad_weight * psi_i * phi_j;
1132  }
1133  return integral;
1134  }
1135 
1136  /*!***********************************************************************************************
1137  * \brief Integrate cut upwind of product of skeltal shape functions times vector function.
1138  *
1139  * \tparam point_t Type of point which is the first argument of the function.
1140  * \tparam geom_t Geometry which is the integration domain.
1141  * \tparam fun Weight function that is additionally integrated.
1142  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1143  * \param i Local index of local shape function with gradient.
1144  * \param j Local index of local shape function.
1145  * \param bdr Index of the boundatry face to integrate over.
1146  * \param geom Geometrical information.
1147  * \param f_param Time at which fun is evaluated.
1148  * \retval integral Integral of product of both shape function's weighted gradients.
1149  ************************************************************************************************/
1150  template <typename point_t,
1151  typename geom_t,
1152  point_t fun(const point_t&, const return_t),
1153  typename smallVec_t = point_t>
1154  static return_t integrate_bdr_psipsinuvecfunc_cutwind(const unsigned int i,
1155  const unsigned int j,
1156  const unsigned int bdr,
1157  geom_t& geom,
1158  return_t f_param = 0.)
1159  {
1160  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1161  return_t integral = 0., quad_weight, psi_i, psi_j, winding;
1162  std::array<unsigned int, std::max(1U, dim() - 1)> dec_i =
1163  Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1164  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
1165  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
1166  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1167  smallVec_t quad_pt;
1168  point_t normal = geom.inner_normal(bdr);
1169  unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1170 
1171  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1172  {
1173  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1174  quad_weight = 1.;
1175  psi_i = 1.;
1176  psi_j = 1.;
1177  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1178  {
1179  if (dim == bdr_dim)
1180  {
1181  quad_pt[dim] = (return_t)bdr_ind;
1182  }
1183  else
1184  {
1185  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1186  psi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1187  psi_j *= shape_fcts_at_quad[dec_j[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1188  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1189  }
1190  }
1191  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1192  if (winding < 0)
1193  integral += geom.face_area(bdr) * quad_weight * psi_i * psi_j * winding;
1194  }
1195  return integral;
1196  }
1197  /*!***********************************************************************************************
1198  * \brief Integrate cut downwind product of skeletal shape functions.
1199  *
1200  * \tparam point_t Type of point which is the first argument of the function.
1201  * \tparam geom_t Geometry which is the integration domain.
1202  * \tparam fun Weight function that is additionally integrated.
1203  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1204  * \param i Local index of local shape function with gradient.
1205  * \param j Local index of local shape function.
1206  * \param bdr Index of the boundatry face to integrate over.
1207  * \param geom Geometrical information.
1208  * \param f_param Time at which fun is evaluated.
1209  * \retval integral Integral of product of both shape function's weighted gradients.
1210  ************************************************************************************************/
1211  template <typename point_t,
1212  typename geom_t,
1213  point_t fun(const point_t&, const return_t),
1214  typename smallVec_t = point_t>
1215  static return_t integrate_bdr_psipsi_cutdownwind(const unsigned int i,
1216  const unsigned int j,
1217  const unsigned int bdr,
1218  geom_t& geom,
1219  return_t f_param = 0.)
1220  {
1221  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1222  return_t integral = 0., quad_weight, psi_i, psi_j, winding;
1223  std::array<unsigned int, std::max(1U, dim() - 1)> dec_i =
1224  Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1225  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
1226  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
1227  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1228  smallVec_t quad_pt;
1229  point_t normal = geom.inner_normal(bdr);
1230  unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1231 
1232  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1233  {
1234  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1235  quad_weight = 1.;
1236  psi_i = 1.;
1237  psi_j = 1.;
1238  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1239  {
1240  if (dim == bdr_dim)
1241  {
1242  quad_pt[dim] = (return_t)bdr_ind;
1243  }
1244  else
1245  {
1246  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1247  psi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1248  psi_j *= shape_fcts_at_quad[dec_j[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1249  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1250  }
1251  }
1252  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1253  if (winding > 0)
1254  integral += geom.face_area(bdr) * quad_weight * psi_i * psi_j;
1255  }
1256  return integral;
1257  }
1258  /*!***********************************************************************************************
1259  * \brief Integrate cut upwind of shape function times function times vector function.
1260  *
1261  * \tparam point_t Type of point which is the first argument of the function.
1262  * \tparam geom_t Geometry which is the integration domain.
1263  * \tparam fun Weight function that is additionally integrated.
1264  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1265  * \param i Local index of local shape function with gradient.
1266  * \param bdr Index of the boundatry face to integrate over.
1267  * \param geom Geometrical information.
1268  * \param f_param Time at which fun is evaluated.
1269  * \retval integral Integral of product of both shape function's weighted gradients.
1270  ************************************************************************************************/
1271  template <typename point_t,
1272  typename geom_t,
1273  return_t func(const point_t&, const return_t),
1274  point_t fun(const point_t&, const return_t),
1275  typename smallVec_t = point_t>
1276  static return_t integrate_bdr_phifuncnuvecfunc_cutwind(const unsigned int i,
1277  const unsigned int bdr,
1278  geom_t& geom,
1279  return_t f_param = 0.)
1280  {
1281  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1282  return_t integral = 0., quad_weight, phi_i, winding;
1283  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1284  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1285  smallVec_t quad_pt;
1286  point_t normal = geom.inner_normal(bdr);
1287  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1288 
1289  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1290  {
1291  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1292  quad_weight = 1.;
1293  phi_i = 1.;
1294  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1295  {
1296  if (dim == bdr_dim)
1297  {
1298  quad_pt[dim] = (return_t)bdr_ind;
1299  phi_i *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
1300  }
1301  else
1302  {
1303  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1304  phi_i *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1305  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1306  }
1307  }
1308  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1309  if (winding < 0)
1310  integral += geom.face_area(bdr) * quad_weight * phi_i *
1311  func(geom.map_ref_to_phys(quad_pt), f_param) * winding;
1312  }
1313  return integral;
1314  }
1315  /*!***********************************************************************************************
1316  * \brief Integrate cut upwind of skeletal shape function times function times vector function.
1317  *
1318  * \tparam point_t Type of point which is the first argument of the function.
1319  * \tparam geom_t Geometry which is the integration domain.
1320  * \tparam fun Weight function that is additionally integrated.
1321  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1322  * \param i Local index of local shape function with gradient.
1323  * \param bdr Index of the boundatry face to integrate over.
1324  * \param geom Geometrical information.
1325  * \param f_param Time at which fun is evaluated.
1326  * \retval integral Integral of product of both shape function's weighted gradients.
1327  ************************************************************************************************/
1328  template <typename point_t,
1329  typename geom_t,
1330  return_t func(const point_t&, const return_t),
1331  point_t fun(const point_t&, const return_t),
1332  typename smallVec_t = point_t>
1333  static return_t integrate_bdr_psifuncnuvecfunc_cutwind(const unsigned int i,
1334  const unsigned int bdr,
1335  geom_t& geom,
1336  return_t f_param = 0.)
1337  {
1338  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1339  return_t integral = 0., quad_weight, psi_i, winding;
1340  std::array<unsigned int, std::max(1U, dim() - 1)> dec_i =
1341  Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1342  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1343  smallVec_t quad_pt;
1344  point_t normal = geom.inner_normal(bdr);
1345  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1346 
1347  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1348  {
1349  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1350  quad_weight = 1.;
1351  psi_i = 1.;
1352  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1353  {
1354  if (dim == bdr_dim)
1355  {
1356  quad_pt[dim] = (return_t)bdr_ind;
1357  }
1358  else
1359  {
1360  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1361  psi_i *= shape_fcts_at_quad[dec_i[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1362  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1363  }
1364  }
1365  winding = scalar_product(normal, fun(geom.map_ref_to_phys(quad_pt), f_param));
1366  if (winding < 0)
1367  integral += geom.face_area(bdr) * quad_weight * psi_i *
1368  func(geom.map_ref_to_phys(quad_pt), f_param) * winding;
1369  }
1370  return integral;
1371  }
1372 
1373  /*!***********************************************************************************************
1374  * \brief Integrate gradient of shape function times shape function times other function times
1375  * normal over some geometry's boundary.
1376  *
1377  * \tparam point_t Type of point which is the first argument of the function.
1378  * \tparam geom_t Geometry which is the integration domain.
1379  * \tparam fun Weight function that is additionally integrated.
1380  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1381  * \param i Local index of local shape function with gradient.
1382  * \param j Local index of local shape function.
1383  * \param bdr Index of the boundatry face to integrate over.
1384  * \param geom Geometrical information.
1385  * \param f_param Time at which fun is evaluated.
1386  * \retval integral Integral of product of both shape function's weighted gradients.
1387  ************************************************************************************************/
1388  template <typename point_t,
1389  typename geom_t,
1390  return_t fun(const point_t&, const return_t),
1391  typename smallVec_t = point_t>
1392  static return_t integrate_bdr_nablaphiphinufunc(const unsigned int i,
1393  const unsigned int j,
1394  const unsigned int bdr,
1395  geom_t& geom,
1396  return_t f_param = 0.)
1397  {
1398  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1399  return_t integral = 0., quad_weight, phi_j;
1400  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1401  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
1402  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1403  smallVec_t quad_pt, nabla_phi_i, normal;
1404  const auto rT = transposed(geom.mat_r());
1405  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1406 
1407  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1408  {
1409  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1410  quad_weight = 1.;
1411  phi_j = 1.;
1412  nabla_phi_i = 1.;
1413  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1414  {
1415  if (dim == bdr_dim)
1416  {
1417  normal[dim] = 2. * bdr_ind - 1.;
1418  quad_pt[dim] = (return_t)bdr_ind;
1419  phi_j *= shape_fcts_at_bdr[dec_j[dim]][bdr_ind];
1420  }
1421  else
1422  {
1423  normal[dim] = 0.;
1424  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1425  phi_j *= shape_fcts_at_quad[dec_j[dim]][dec_q[dim - (dim > bdr_dim)]];
1426  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1427  }
1428  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
1429  {
1430  if (dim == dim_fct && dim == bdr_dim)
1431  nabla_phi_i[dim_fct] *= shape_ders_at_bdr[dec_i[dim]][bdr_ind];
1432  else if (dim == dim_fct)
1433  nabla_phi_i[dim_fct] *= shape_ders_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1434  else if (dim == bdr_dim)
1435  nabla_phi_i[dim_fct] *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
1436  else
1437  nabla_phi_i[dim_fct] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr)]];
1438  }
1439  }
1440  integral += quad_weight * fun(geom.map_ref_to_phys(quad_pt), f_param) * phi_j *
1441  scalar_product(normal, nabla_phi_i / rT);
1442  }
1443  return geom.face_area(bdr) * integral;
1444  }
1445 
1446  /*!***********************************************************************************************
1447  * \brief Integrate gradient of shape function times shape function times other function times
1448  * normal over some geometry's boundary.
1449  *
1450  * \tparam point_t Type of point which is the first argument of the function.
1451  * \tparam geom_t Geometry which is the integration domain.
1452  * \tparam fun Weight function that is additionally integrated.
1453  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1454  * \param i Local index of local shape function with gradient.
1455  * \param j Local index of local shape function.
1456  * \param bdr Index of the boundatry face to integrate over.
1457  * \param geom Geometrical information.
1458  * \param f_param Time at which fun is evaluated.
1459  * \retval integral Integral of product of both shape function's weighted gradients.
1460  ************************************************************************************************/
1461  template <typename point_t,
1462  typename geom_t,
1463  return_t fun(const point_t&, const return_t),
1464  typename smallVec_t = point_t>
1465  static return_t integrate_bdr_nablaphipsinufunc(const unsigned int i,
1466  const unsigned int j,
1467  const unsigned int bdr,
1468  geom_t& geom,
1469  return_t f_param = 0.)
1470  {
1471  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1472  return_t integral = 0., quad_weight, phi_j;
1473  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1474  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
1475  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
1476  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1477  smallVec_t quad_pt, nabla_phi_i, normal;
1478  const auto rT = transposed(geom.mat_r());
1479  const unsigned int bdr_dim = bdr / 2, bdr_ind = bdr % 2;
1480 
1481  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1482  {
1483  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1484  quad_weight = 1.;
1485  phi_j = 1.;
1486  nabla_phi_i = 1.;
1487  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1488  {
1489  if (dim == bdr_dim)
1490  {
1491  normal[dim] = 2. * bdr_ind - 1.;
1492  quad_pt[dim] = (return_t)bdr_ind;
1493  }
1494  else
1495  {
1496  normal[dim] = 0.;
1497  quad_pt[dim] = quad_points[dec_q[dim - (dim > bdr_dim)]];
1498  phi_j *= shape_fcts_at_quad[dec_j[dim - (dim > bdr_dim)]][dec_q[dim - (dim > bdr_dim)]];
1499  quad_weight *= quad_weights[dec_q[dim - (dim > bdr_dim)]];
1500  }
1501  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
1502  {
1503  if (dim == dim_fct && dim == bdr_dim)
1504  nabla_phi_i[dim_fct] *= shape_ders_at_bdr[dec_i[dim]][bdr_ind];
1505  else if (dim == dim_fct)
1506  nabla_phi_i[dim_fct] *= shape_ders_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1507  else if (dim == bdr_dim)
1508  nabla_phi_i[dim_fct] *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
1509  else
1510  nabla_phi_i[dim_fct] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > bdr_dim)]];
1511  }
1512  }
1513  integral += quad_weight * fun(geom.map_ref_to_phys(quad_pt), f_param) * phi_j *
1514  scalar_product(normal, nabla_phi_i / rT);
1515  }
1516  return geom.face_area(bdr) * integral;
1517  }
1518 
1519  /*!***********************************************************************************************
1520  * \brief Integrate product of shape functions over boundary face.
1521  *
1522  * \tparam geom_t Geometry which is the integration domain.
1523  * \param i Local index of local shape function.
1524  * \param j Local index of local shape function.
1525  * \param bdr Boundary face index.
1526  * \param geom Geometrical information.
1527  * \retval integral Integral of product of both shape functions.
1528  ************************************************************************************************/
1529  template <typename geom_t>
1530  static return_t integrate_bdr_phiphi(const unsigned int i,
1531  const unsigned int j,
1532  const unsigned int bdr,
1533  geom_t& geom)
1534  {
1535  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1536  return_t integral = 1.;
1537  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1538  std::array<unsigned int, dim()> dec_j = Hypercube<dim()>::index_decompose(j, n_fun_1D);
1539  unsigned int dim = bdr / 2, bdr_ind = bdr % 2;
1540  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
1541  if (dim == dim_fct)
1542  integral *=
1543  shape_fcts_at_bdr[dec_i[dim_fct]][bdr_ind] * shape_fcts_at_bdr[dec_j[dim_fct]][bdr_ind];
1544  else
1545  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct]);
1546  return integral * geom.face_area(bdr);
1547  }
1548  /*!***********************************************************************************************
1549  * \brief Integrate product of shape functions of volumen and skeletal over boundary face.
1550  *
1551  * \tparam geom_t Geometry which is the integration domain.
1552  * \param i Local index of local volumne shape function.
1553  * \param j Local index of local skeletal shape function.
1554  * \param bdr Boundary face index.
1555  * \param geom Geometrical information.
1556  * \retval integral Integral of product of both shape functions.
1557  ************************************************************************************************/
1558  template <typename geom_t>
1559  static return_t integrate_bdr_phipsi(const unsigned int i,
1560  const unsigned int j,
1561  const unsigned int bdr,
1562  geom_t& geom)
1563  {
1564  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1565  return_t integral = 1.;
1566  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1567  std::array<unsigned int, std::max(1U, dim() - 1)> dec_j =
1568  Hypercube<dim() - 1>::index_decompose(j, n_fun_1D);
1569  unsigned int dim = bdr / 2, bdr_ind = bdr % 2;
1570  for (unsigned int dim_fct = 0; dim_fct < geom_t::hyEdge_dim(); ++dim_fct)
1571  if (dim == dim_fct)
1572  integral *= shape_fcts_at_bdr[dec_i[dim_fct]][bdr_ind];
1573  else
1574  integral *= integrate_1D_phiphi(dec_i[dim_fct], dec_j[dim_fct - (dim_fct > dim)]);
1575  return integral * geom.face_area(bdr);
1576  }
1577  /*!***********************************************************************************************
1578  * \brief Integrate product of shape functions times some function over boundary face.
1579  *
1580  * \tparam geom_t Geometry which is the integration domain.
1581  * \tparam fun Function that is multiplied by shape function.
1582  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1583  * \param i Local index of local shape function.
1584  * \param bdr Boundary face index.
1585  * \param geom Geometrical information.
1586  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
1587  * \retval integral Integral of product of both shape functions.
1588  ************************************************************************************************/
1589  template <typename point_t,
1590  typename geom_t,
1591  return_t fun(const point_t&, const return_t),
1592  typename smallVec_t = point_t>
1593  static return_t integrate_bdr_phifunc(const unsigned int i,
1594  const unsigned int bdr,
1595  geom_t& geom,
1596  const return_t f_param = 0.)
1597  {
1598  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1599  return_t integral = 0., quad_val;
1600  std::array<unsigned int, dim()> dec_i = Hypercube<dim()>::index_decompose(i, n_fun_1D);
1601  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q;
1602  smallVec_t quad_pt;
1603  unsigned int dim_bdr = bdr / 2, bdr_ind = bdr % 2;
1604 
1605  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1606  {
1607  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1608  quad_val = 1.;
1609  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1610  {
1611  if (dim == dim_bdr)
1612  {
1613  quad_pt[dim] = bdr_ind;
1614  quad_val *= shape_fcts_at_bdr[dec_i[dim]][bdr_ind];
1615  }
1616  else
1617  {
1618  quad_pt[dim] = quad_points[dec_q[dim - (dim > dim_bdr)]];
1619  quad_val *= quad_weights[dec_q[dim - (dim > dim_bdr)]] *
1620  shape_fcts_at_quad[dec_i[dim]][dec_q[dim - (dim > dim_bdr)]];
1621  }
1622  }
1623  integral += fun(geom.map_ref_to_phys(quad_pt), f_param) * quad_val;
1624  }
1625  return integral * geom.face_area(bdr);
1626  }
1627  /*!***********************************************************************************************
1628  * \brief Average integral of product of skeletal shape functions times some function.
1629  *
1630  * \tparam geom_t Geometry which is the integration domain.
1631  * \tparam fun Function that is multiplied by shape function.
1632  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1633  * \param i Local index of local shape function.
1634  * \param bdr Boundary face index.
1635  * \param geom Geometrical information.
1636  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
1637  * \retval integral Integral of product of both shape functions.
1638  ************************************************************************************************/
1639  template <typename point_t,
1640  typename geom_t,
1641  return_t fun(const point_t&, const return_t),
1642  typename smallVec_t = point_t>
1643  static return_t integrate_bdrUni_psifunc(const unsigned int i,
1644  const unsigned int bdr,
1645  geom_t& geom,
1646  const return_t f_param = 0.)
1647  {
1648  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1649  return_t integral = 0., quad_val;
1650  std::array<unsigned int, std::max(1U, dim() - 1)> dec_q,
1651  dec_i = Hypercube<dim() - 1>::index_decompose(i, n_fun_1D);
1652  smallVec_t quad_pt;
1653  unsigned int dim_bdr = bdr / 2, bdr_ind = bdr % 2;
1654 
1655  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim() - 1); ++q)
1656  {
1657  dec_q = Hypercube<dim() - 1>::index_decompose(q, quadrature_t::n_points());
1658  quad_val = 1.;
1659  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1660  {
1661  if (dim == dim_bdr)
1662  quad_pt[dim] = bdr_ind;
1663  else
1664  {
1665  quad_pt[dim] = quad_points[dec_q[dim - (dim > dim_bdr)]];
1666  quad_val *=
1667  quad_weights[dec_q[dim - (dim > dim_bdr)]] *
1668  shape_fcts_at_quad[dec_i[dim - (dim > dim_bdr)]][dec_q[dim - (dim > dim_bdr)]];
1669  }
1670  }
1671  integral += fun(geom.map_ref_to_phys(quad_pt), f_param) * quad_val;
1672  }
1673  return integral;
1674  }
1675  /*!***********************************************************************************************
1676  * \brief Squared L2 distance of some function and an discrete function on volume.
1677  *
1678  * \tparam geom_t Geometry which is the integration domain.
1679  * \tparam fun Function whose distance is measured.
1680  * \tparam smallVec_t Type of local point with respect to hyperedge. Defaults to point_t.
1681  * \param coeffs Coefficients of discrete function.
1682  * \param geom Geometrical information.
1683  * \param f_param Function parameter (e.g. time) with respect to which it is evaluated.
1684  * \retval integral Squared distance of functions.
1685  ************************************************************************************************/
1686  template <typename point_t,
1687  typename geom_t,
1688  return_t fun(const point_t&, const return_t),
1689  typename smallVec_t = point_t,
1690  std::size_t n_coeff>
1691  static return_t integrate_vol_diffsquare_discana(const std::array<return_t, n_coeff> coeffs,
1692  geom_t& geom,
1693  const return_t f_param = 0.)
1694  {
1695  static_assert(geom_t::hyEdge_dim() == dim(), "Dimension of hyperedge must fit to quadrature!");
1696  return_t integral = 0., quad_weight;
1697  std::array<unsigned int, dim()> dec_i, dec_q;
1698  std::array<return_t, n_coeff> quad_val;
1699  smallVec_t quad_pt;
1700 
1701  for (unsigned int q = 0; q < std::pow(quad_weights.size(), geom_t::hyEdge_dim()); ++q)
1702  {
1703  dec_q = Hypercube<dim()>::index_decompose(q, quadrature_t::n_points());
1704  quad_weight = 1.;
1705  quad_val = coeffs;
1706  for (unsigned int dim = 0; dim < geom_t::hyEdge_dim(); ++dim)
1707  {
1708  quad_pt[dim] = quad_points[dec_q[dim]];
1709  quad_weight *= quad_weights[dec_q[dim]];
1710  for (unsigned int i = 0; i < n_coeff; ++i)
1711  {
1712  dec_i = Hypercube<geom_t::hyEdge_dim()>::index_decompose(i, n_fun_1D);
1713  quad_val[i] *= shape_fcts_at_quad[dec_i[dim]][dec_q[dim]];
1714  }
1715  }
1716  integral += quad_weight * std::pow(fun(geom.map_ref_to_phys(quad_pt), f_param) -
1717  std::accumulate(quad_val.begin(), quad_val.end(), 0.),
1718  2);
1719  }
1720  return integral * geom.area();
1721  }
1722 }; // end of class Integrator
1723 
1724 } // end of namespace Quadrature
1725 
1726 } // end of namespace TPP
TPP::Quadrature::Tensorial::integrate_bdr_phipsi
static constexpr return_t integrate_bdr_phipsi(const unsigned int i, const unsigned int j, const unsigned int bdr)
Integrate product of shape function of volume times shape function of volume's face over dimT-dimensi...
Definition: tensorial.hxx:302
TPP::Quadrature::Tensorial::integrate_bdr_phifunc
static return_t integrate_bdr_phifunc(const unsigned int i, const unsigned int bdr, geom_t &geom, const return_t f_param=0.)
Integrate product of shape functions times some function over boundary face.
Definition: tensorial.hxx:1593
TPP::Quadrature::Tensorial::integrate_bdr_phipsi
static return_t integrate_bdr_phipsi(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom)
Integrate product of shape functions of volumen and skeletal over boundary face.
Definition: tensorial.hxx:1559
TPP::Quadrature::Tensorial::integrate_1D_phiDphi
static constexpr return_t integrate_1D_phiDphi(const unsigned int i, const unsigned int j)
Integrate product of one-dimensional shape function and one derivative.
Definition: tensorial.hxx:162
TPP::Quadrature::Tensorial::shape_ders_at_quad
static constexpr std::array< std::array< return_t, quadrature_t::n_points()>, n_fun_1D > shape_ders_at_quad
Derivatives of shape functions evaluated at quadrature points of unit interval.
Definition: tensorial.hxx:126
TPP::Quadrature::Tensorial::integrate_vol_diffsquare_discana
static return_t integrate_vol_diffsquare_discana(const std::array< return_t, n_coeff > coeffs, geom_t &geom, const return_t f_param=0.)
Squared L2 distance of some function and an discrete function on volume.
Definition: tensorial.hxx:1691
TPP::Quadrature::Tensorial::integrate_bdr_nablaphiphinufunc
static return_t integrate_bdr_nablaphiphinufunc(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate gradient of shape function times shape function times other function times normal over some...
Definition: tensorial.hxx:1392
TPP::Quadrature::Tensorial::integrate_bdr_psiphi_cutwind
static return_t integrate_bdr_psiphi_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of skeletal shape function times shape function.
Definition: tensorial.hxx:1092
TPP::Quadrature::Tensorial::shape_ders_at_bdrs
static constexpr std::array< std::array< return_t, 2 >, n_fun_1D > shape_ders_at_bdrs()
Derivatives of shape functions evaluated at boundaries of unit interval.
Definition: tensorial.hxx:105
TPP::Quadrature::Tensorial::integrate_bdr_psiphinuvecfunc_cutwind
static return_t integrate_bdr_psiphinuvecfunc_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of skeletal shape function times shape function times vector fct.
Definition: tensorial.hxx:1030
TPP::Quadrature::Tensorial::integrate_volUni_phifunc
static return_t integrate_volUni_phifunc(const unsigned int i, geom_t &geom, const return_t f_param=0.)
Average integral of product of shape function times some function over some geometry.
Definition: tensorial.hxx:530
TPP::Quadrature::Tensorial::integrate_bdr_phiphi_cutwind
static return_t integrate_bdr_phiphi_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of product of shape functions.
Definition: tensorial.hxx:839
TPP::Quadrature::Tensorial::shape_fcts_at_bdr
static constexpr std::array< std::array< return_t, 2 >, n_fun_1D > shape_fcts_at_bdr
Shape functions evaluated at boundaries of unit interval.
Definition: tensorial.hxx:130
tpp_assert
#define tpp_assert(Expr, Msg)
The assertion to be used within tpp — deactivate using -DNDEBUG compile flag.
Definition: tpp_assert.hxx:33
TPP::Quadrature::Tensorial::integrate_bdrUni_psifunc
static return_t integrate_bdrUni_psifunc(const unsigned int i, const unsigned int bdr, geom_t &geom, const return_t f_param=0.)
Average integral of product of skeletal shape functions times some function.
Definition: tensorial.hxx:1643
TPP::Quadrature::Tensorial::integrate_bdr_psipsi_cutdownwind
static return_t integrate_bdr_psipsi_cutdownwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut downwind product of skeletal shape functions.
Definition: tensorial.hxx:1215
TPP::Quadrature::Tensorial::integrate_bdr_nablaphipsinufunc
static return_t integrate_bdr_nablaphipsinufunc(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate gradient of shape function times shape function times other function times normal over some...
Definition: tensorial.hxx:1465
TPP::Quadrature::Tensorial::integrate_bdr_phifuncnuvecfunc_cutwind
static return_t integrate_bdr_phifuncnuvecfunc_cutwind(const unsigned int i, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of shape function times function times vector function.
Definition: tensorial.hxx:1276
TPP::Quadrature::Tensorial::n_fun_1D
static constexpr unsigned int n_fun_1D
Amount of shape functions with respect to a single spatial dimension.
Definition: tensorial.hxx:58
TPP::Quadrature::Tensorial::integrate_vol_phifunc
static return_t integrate_vol_phifunc(const unsigned int i, geom_t &geom, const return_t f_param=0.)
Integrate product of shape function times some function over some geometry.
Definition: tensorial.hxx:491
TPP::Quadrature::Tensorial::integrate_vol_nablaphiphivecfunc
static return_t integrate_vol_nablaphiphivecfunc(const unsigned int i, const unsigned int j, geom_t &geom, const return_t f_param=0.)
Integrate gradient of shape function times other shape function times vector function.
Definition: tensorial.hxx:719
TPP::Quadrature::Tensorial::integrate_vol_Dphiphi
static constexpr return_t integrate_vol_Dphiphi(const unsigned int i, const unsigned int j, const unsigned int dim_der)
Integrate product of shape function and derivative over dimT-dimensional unit volume.
Definition: tensorial.hxx:255
TPP::Quadrature::Tensorial::integrate_vol_nablaphinablaphifunc
static return_t integrate_vol_nablaphinablaphifunc(const unsigned int i, const unsigned int j, geom_t &geom, return_t f_param=0.)
Integrate gradient of shape functions times other function over some geometry.
Definition: tensorial.hxx:607
TPP::Quadrature::Tensorial::integrate_vol_phiphivecfunc
static return_t integrate_vol_phiphivecfunc(const unsigned int i, const unsigned int j, const unsigned int dimension, geom_t &geom, const return_t f_param=0.)
Integrate product of shape functions times some function over some geometry.
Definition: tensorial.hxx:381
TPP::Quadrature::Tensorial::integrate_bdr_phipsi_cutdownwind
static return_t integrate_bdr_phipsi_cutdownwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut downwind of shape function times skeletal shape function.
Definition: tensorial.hxx:966
TPP::Hypercube
Helper class containing numbers and functions related to hypercubes.
Definition: hypercube.hxx:16
TPP::Quadrature::Tensorial::integrate_1D_DphiDphi
static constexpr return_t integrate_1D_DphiDphi(const unsigned int i, const unsigned int j)
Integrate product of two one-dimensional shape functions' derivatives.
Definition: tensorial.hxx:198
one_dimensional.hxx
TPP::Quadrature::Tensorial::shape_ders_at_bdr
static constexpr std::array< std::array< return_t, 2 >, n_fun_1D > shape_ders_at_bdr
Derivatives of shape functions evaluated at boundaries of unit interval.
Definition: tensorial.hxx:135
TPP::Quadrature::Tensorial::integrate_bdr_psifuncnuvecfunc_cutwind
static return_t integrate_bdr_psifuncnuvecfunc_cutwind(const unsigned int i, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of skeletal shape function times function times vector function.
Definition: tensorial.hxx:1333
tpp_assert.hxx
This file provides the function tpp_assert.
TPP
Contains the functionalities to evaluate and integrate tensor product type polynomials.
Definition: compile_time_tricks.hxx:7
TPP::Quadrature::Tensorial::integrate_1D_Dphiphi
static constexpr return_t integrate_1D_Dphiphi(const unsigned int i, const unsigned int j)
Integrate product of one-dimensional shape function and one derivative.
Definition: tensorial.hxx:180
TPP::Quadrature::Tensorial::shape_fcts_at_quad_points
static constexpr std::array< std::array< return_t, quadrature_t::n_points()>, n_fun_1D > shape_fcts_at_quad_points()
Shape functions evaluated at quadrature points of unit interval.
Definition: tensorial.hxx:63
TPP::Quadrature::Tensorial::integrate_vol_derphifunc
static return_t integrate_vol_derphifunc(const unsigned int i, const unsigned int dim_der, geom_t &geom, return_t f_param=0.)
Integrate derivative of shape function times other function over some geometry.
Definition: tensorial.hxx:666
TPP::Quadrature::Tensorial::n_quad_points
static constexpr unsigned int n_quad_points()
Calculate the amount of quadrature points.
Definition: tensorial.hxx:38
TPP::Quadrature::Tensorial::integrate_vol_phiDphi
static constexpr return_t integrate_vol_phiDphi(const unsigned int i, const unsigned int j, const unsigned int dim_der)
Integrate product of shape function amd derivative over dimT-dimensional unit volume.
Definition: tensorial.hxx:233
TPP::Quadrature::Tensorial::shape_fcts_at_bdrs
static constexpr std::array< std::array< return_t, 2 >, n_fun_1D > shape_fcts_at_bdrs()
Shape functions evaluated at boundaries of unit interval.
Definition: tensorial.hxx:92
TPP::Quadrature::Tensorial
General integrator class on tensorial hypergraphs.
Definition: tensorial.hxx:24
TPP::Quadrature::Tensorial::integrate_1D_phiphi
static constexpr return_t integrate_1D_phiphi(const unsigned int i, const unsigned int j)
Integrate product of one-dimensional shape functions.
Definition: tensorial.hxx:144
TPP::Quadrature::Tensorial::integrate_bdr_psipsinuvecfunc_cutwind
static return_t integrate_bdr_psipsinuvecfunc_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of product of skeltal shape functions times vector function.
Definition: tensorial.hxx:1154
TPP::Quadrature::Tensorial::integrate_bdr_phipsinuvecfunc_cutwind
static return_t integrate_bdr_phipsinuvecfunc_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate cut upwind of shape function times skeletal shape function.
Definition: tensorial.hxx:902
mat_times_transposed_mat
SmallMat< n_rowsA, n_rowsB, mat_entry_t > mat_times_transposed_mat(const SmallMat< n_rowsA, n_colsA, mat_entry_t > &A, const SmallMat< n_rowsB, n_colsA, mat_entry_t > &B)
Multiply first matrix with transposed of second second.
Definition: dense_la.hxx:714
TPP::Quadrature::Tensorial::integrate_bdr_phiphi
static constexpr return_t integrate_bdr_phiphi(const unsigned int i, const unsigned int j, const unsigned int bdr)
Integrate product of shape functions over dimT-dimensional volume's boundary.
Definition: tensorial.hxx:277
TPP::Quadrature::Tensorial::quad_weights
static constexpr std::array< return_t, quadrature_t::n_points()> quad_weights
Quadrature weights on one-dimensional unit interval.
Definition: tensorial.hxx:51
TPP::Quadrature::Tensorial::integrate_bdr_phiphinuvecfunc_cutwind
static return_t integrate_bdr_phiphinuvecfunc_cutwind(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom, return_t f_param=0.)
Integrate shape function times shape function times vector function times normal.
Definition: tensorial.hxx:776
TPP::Quadrature::Tensorial::integrate_vol_phiphi
static constexpr return_t integrate_vol_phiphi(const unsigned int i, const unsigned int j)
Integrate product of shape functions over dimT-dimensional unit volume.
Definition: tensorial.hxx:216
TPP::Quadrature::Tensorial::shape_fcts_at_quad
static constexpr std::array< std::array< return_t, quadrature_t::n_points()>, n_fun_1D > shape_fcts_at_quad
Shape functions evaluated at quadrature points of unit interval.
Definition: tensorial.hxx:121
TPP::Quadrature::Tensorial::integrate_vol_phiphifunc
static return_t integrate_vol_phiphifunc(const unsigned int i, const unsigned int j, geom_t &geom, const return_t f_param=0.)
Integrate product of shape functions times some function over some geometry.
Definition: tensorial.hxx:336
scalar_product
mat_entry_t scalar_product(const SmallMat< n_rows, n_cols, mat_entry_t > &left, const SmallMat< n_rows, n_cols, mat_entry_t > &right)
Euclidean scalar product of two SmallVecs / Frobenius scalar product for two SmallMats.
Definition: dense_la.hxx:571
TPP::Quadrature::Tensorial::quad_points
static constexpr std::array< return_t, quadrature_t::n_points()> quad_points
Quadrature points on one-dimensional unit interval.
Definition: tensorial.hxx:46
TPP::Quadrature::Tensorial::integrate_vol_phiphi
static return_t integrate_vol_phiphi(const unsigned int i, const unsigned int j, geom_t &geom)
Integrate product of shape functions over some geometry.
Definition: tensorial.hxx:421
TPP::Quadrature::Tensorial::integrate_bdr_phiphi
static return_t integrate_bdr_phiphi(const unsigned int i, const unsigned int j, const unsigned int bdr, geom_t &geom)
Integrate product of shape functions over boundary face.
Definition: tensorial.hxx:1530
TPP::Quadrature::Tensorial::shape_ders_at_quad_points
static constexpr std::array< std::array< return_t, quadrature_t::n_points()>, n_fun_1D > shape_ders_at_quad_points()
Derivatives of shape functions evaluated at quadrature points of unit interval.
Definition: tensorial.hxx:78
TPP::Quadrature::Tensorial::dim
static constexpr unsigned int dim()
The dimension of the Lebesque measure with respect to which we integrate.
Definition: tensorial.hxx:34
TPP::Quadrature::Tensorial::integrate_vol_phiphi
static return_t integrate_vol_phiphi(const std::array< floating_t, array_size > &is, const std::array< floating_t, array_size > &js, geom_t &geom)
Integrate product of linear combinations of shape functions over some geometry.
Definition: tensorial.hxx:443
TPP::Quadrature::Tensorial::integrate_vol_nablaphiphi
static smallVec_t integrate_vol_nablaphiphi(const unsigned int i, const unsigned int j, geom_t &geom)
Integrate gradient of shape function times other shape function over some geometry.
Definition: tensorial.hxx:572
transposed
SmallMat< n_cols, n_rows, mat_entry_t > transposed(SmallMat< n_rows, n_cols, mat_entry_t > mat)
Transpose given matrix.
Definition: dense_la.hxx:554
TPP::Quadrature::Tensorial::shape_fun_t
shape_t shape_fun_t
Make type of shape functions publicly available.
Definition: tensorial.hxx:30