HyperHDG
diffusion_uniform_ldgh.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
3 #include <HyperHDG/dense_la.hxx>
4 #include <HyperHDG/hypercube.hxx>
7 
8 #include <algorithm>
9 #include <tuple>
10 
11 namespace LocalSolver
12 {
13 /*!*************************************************************************************************
14  * \brief Local solver for Poisson's equation on uniform hypergraph.
15  *
16  * This class contains the local solver for Poisson's equation, i.e.,
17  * \f[
18  * - \Delta u = 0 \quad \text{ in } \Omega, \qquad u = u_\text D \quad \text{ on } \partial \Omega
19  * \f]
20  * in a spatial domain \f$\Omega \subset \mathbb R^d\f$. Here, \f$d\f$ is the spatial dimension
21  * \c space_dim, \f$\Omega\f$ is a regular graph (\c hyEdge_dimT = 1), or hypergraph whose
22  * hyperedges are surfaces (\c hyEdge_dimT = 2), or volumes (\c hyEdge_dimT = 3), or higher
23  * dimensional analogues. For this class, all hyperedges are supposed to be uniform (i.e. equal to
24  * the unit hypercube). Thus, no geometrical information is needed by this class.
25  *
26  * \tparam hyEdge_dimT Dimension of a hyperedge, i.e., 1 is for PDEs defined on graphs, 2 is for
27  * PDEs defined on surfaces, and 3 is for PDEs defined on volumes.
28  * \tparam poly_deg The polynomial degree of test and trial functions.
29  * \tparam quad_deg The order of the quadrature rule.
30  * \tparam lSol_float_t The floating point type calculations are executed in. Defaults to double.
31  *
32  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
33  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
34  **************************************************************************************************/
35 template <unsigned int hyEdge_dimT,
36  unsigned int poly_deg,
37  unsigned int quad_deg,
38  typename lSol_float_t = double>
40 {
41  public:
42  /*!***********************************************************************************************
43  * \brief Define type of (hyperedge related) data that is stored in HyDataContainer.
44  ************************************************************************************************/
45  struct data_type
46  {
47  };
48  /*!***********************************************************************************************
49  * \brief Define type of node elements, especially with respect to nodal shape functions.
50  ************************************************************************************************/
51  struct node_element
52  {
53  typedef std::tuple<TPP::ShapeFunction<
56  };
57  /*!***********************************************************************************************
58  * \brief Define how errors are evaluated.
59  ************************************************************************************************/
60  struct error_def
61  {
62  /*!*********************************************************************************************
63  * \brief Define the typename returned by function errors.
64  **********************************************************************************************/
65  typedef std::array<lSol_float_t, 1U> error_t;
66  /*!*********************************************************************************************
67  * \brief Define how initial error is generated.
68  **********************************************************************************************/
70  {
71  std::array<lSol_float_t, 1U> summed_error;
72  summed_error.fill(0.);
73  return summed_error;
74  }
75  /*!*********************************************************************************************
76  * \brief Define how local errors should be accumulated.
77  **********************************************************************************************/
78  static error_t sum_error(error_t& summed_error, const error_t& new_error)
79  {
80  for (unsigned int k = 0; k < summed_error.size(); ++k)
81  summed_error[k] += new_error[k];
82  return summed_error;
83  }
84  /*!*********************************************************************************************
85  * \brief Define how global errors should be postprocessed.
86  **********************************************************************************************/
87  static error_t postprocess_error(error_t& summed_error)
88  {
89  for (unsigned int k = 0; k < summed_error.size(); ++k)
90  summed_error[k] = std::sqrt(summed_error[k]);
91  return summed_error;
92  }
93  };
94  // -----------------------------------------------------------------------------------------------
95  // Public, static constexpr functions
96  // -----------------------------------------------------------------------------------------------
97 
98  /*!***********************************************************************************************
99  * \brief Dimension of hyper edge type that this object solves on.
100  ************************************************************************************************/
101  static constexpr unsigned int hyEdge_dim() { return hyEdge_dimT; }
102  /*!***********************************************************************************************
103  * \brief Evaluate amount of global degrees of freedom per hypernode.
104  *
105  * This number must be equal to HyperNodeFactory::n_dofs_per_node() of the HyperNodeFactory
106  * cooperating with this object.
107  *
108  * \retval n_dofs Number of global degrees of freedom per hypernode.
109  ************************************************************************************************/
110  static constexpr unsigned int n_glob_dofs_per_node()
111  {
112  return Hypercube<hyEdge_dimT - 1>::pow(poly_deg + 1);
113  }
114  /*!***********************************************************************************************
115  * \brief Dimension of of the solution evaluated with respect to a hyperedge.
116  ************************************************************************************************/
117  static constexpr unsigned int system_dimension() { return hyEdge_dimT + 1; }
118  /*!***********************************************************************************************
119  * \brief Dimension of of the solution evaluated with respect to a hypernode.
120  ************************************************************************************************/
121  static constexpr unsigned int node_system_dimension() { return 1; }
122 
123  private:
124  // -----------------------------------------------------------------------------------------------
125  // Private, static constexpr functions
126  // -----------------------------------------------------------------------------------------------
127 
128  /*!***********************************************************************************************
129  * \brief Number of local shape functions (with respect to all spatial dimensions).
130  ************************************************************************************************/
131  static constexpr unsigned int n_shape_fct_ = n_glob_dofs_per_node() * (poly_deg + 1);
132  /*!***********************************************************************************************
133  * \brief Number oflocal shape functions (with respect to a face / hypernode).
134  ************************************************************************************************/
135  static constexpr unsigned int n_shape_bdr_ = n_glob_dofs_per_node();
136  /*!***********************************************************************************************
137  * \brief Number of (local) degrees of freedom per hyperedge.
138  ************************************************************************************************/
139  static constexpr unsigned int n_loc_dofs_ = (hyEdge_dimT + 1) * n_shape_fct_;
140  /*!***********************************************************************************************
141  * \brief Dimension of of the solution evaluated with respect to a hypernode.
142  *
143  * This allows to the use of this quantity as template parameter in member functions.
144  ************************************************************************************************/
145  static constexpr unsigned int system_dim = system_dimension();
146  /*!***********************************************************************************************
147  * \brief Dimension of of the solution evaluated with respect to a hypernode.
148  *
149  * This allows to the use of this quantity as template parameter in member functions.
150  ************************************************************************************************/
151  static constexpr unsigned int node_system_dim = node_system_dimension();
152  /*!***********************************************************************************************
153  * \brief Assemble local matrix for the local solver.
154  *
155  * The local solver neither depends on the geometry, nor on global functions. Thus, its local
156  * matrix is the same for all hyperedges and can be assembled once in the constructor. This is
157  * done in this function.
158  *
159  * The function is static, since it is used in the constructor's initializer list.
160  *
161  * \param tau Penalty parameter for HDG.
162  * \retval loc_mat Matrix of the local solver.
163  ************************************************************************************************/
164  static SmallSquareMat<n_loc_dofs_, lSol_float_t> assemble_loc_matrix(const lSol_float_t tau);
165  /*!***********************************************************************************************
166  * \brief (Globally constant) penalty parameter for HDG scheme.
167  ************************************************************************************************/
168  const lSol_float_t tau_;
169  /*!***********************************************************************************************
170  * \brief Local matrix for the local solver.
171  ************************************************************************************************/
173  /*!***********************************************************************************************
174  * \brief An integrator helps to easily evaluate integrals (e.g. via quadrature).
175  ************************************************************************************************/
179  lSol_float_t>
181 
182  // -----------------------------------------------------------------------------------------------
183  // Private, internal functions for the local solver
184  // -----------------------------------------------------------------------------------------------
185 
186  /*!***********************************************************************************************
187  * \brief Assemble local right hand for the local solver.
188  *
189  * The right hand side needs the values of the global degrees of freedom. Thus, it needs to be
190  * constructed individually for every hyperedge.
191  *
192  * \tparam SmallMatT The data type of the lambda values.
193  * \param lambda_values Global degrees of freedom associated to the hyperedge.
194  * \retval loc_rhs Local right hand side of the locasl solver.
195  ************************************************************************************************/
196  template <typename SmallMatT>
197  inline SmallVec<n_loc_dofs_, lSol_float_t> assemble_rhs(const SmallMatT& lambda_values) const;
198  /*!***********************************************************************************************
199  * \brief Solve local problem.
200  *
201  * \tparam SmallMatT The data type of the lambda values.
202  * \param lambda_values Global degrees of freedom associated to the hyperedge.
203  * \retval loc_sol Solution of the local problem.
204  ************************************************************************************************/
205  template <typename SmallMatT>
206  inline std::array<lSol_float_t, n_loc_dofs_> solve_local_problem(
207  const SmallMatT& lambda_values) const
208  {
209  try
210  {
211  return (assemble_rhs(lambda_values) / loc_mat_).data();
212  }
213  catch (Wrapper::LAPACKexception& exc)
214  {
215  hy_assert(0 == 1, exc.what() << std::endl
216  << "This can happen if quadrature is too inaccurate!");
217  throw exc;
218  }
219  }
220  /*!***********************************************************************************************
221  * \brief Evaluate primal variable at boundary.
222  *
223  * Function to evaluate primal variable of the solution. This function is needed to calculate
224  * the local numerical fluxes.
225  *
226  * \param coeffs Coefficients of the local solution.
227  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
228  ************************************************************************************************/
229  inline std::array<std::array<lSol_float_t, n_shape_bdr_>, 2 * hyEdge_dimT> primal_at_boundary(
230  const std::array<lSol_float_t, n_loc_dofs_>& coeffs) const;
231  /*!***********************************************************************************************
232  * \brief Evaluate dual variable at boundary.
233  *
234  * Function to evaluate dual variable of the solution. This function is needed to calculate the
235  * local numerical fluxes.
236  *
237  * \param coeffs Coefficients of the local solution.
238  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
239  ************************************************************************************************/
240  inline std::array<std::array<lSol_float_t, n_shape_bdr_>, 2 * hyEdge_dimT> dual_at_boundary(
241  const std::array<lSol_float_t, (hyEdge_dimT + 1) * n_shape_fct_>& coeffs) const;
242 
243  public:
244  /*!***********************************************************************************************
245  * \brief Class is constructed using a single double indicating the penalty parameter.
246  ************************************************************************************************/
247  typedef lSol_float_t constructor_value_type;
248  /*!***********************************************************************************************
249  * \brief Constructor for local solver.
250  *
251  * \param tau Penalty parameter of HDG scheme.
252  ************************************************************************************************/
254  : tau_(tau), loc_mat_(assemble_loc_matrix(tau))
255  {
256  }
257  /*!***********************************************************************************************
258  * \brief Evaluate local contribution to matrix--vector multiplication.
259  *
260  * Execute matrix--vector multiplication y = A * x, where x represents the vector containing the
261  * skeletal variable (adjacent to one hyperedge), and A is the condensed matrix arising from the
262  * HDG discretization. This function does this multiplication (locally) for one hyperedge. The
263  * hyperedge is no parameter, since all hyperedges are assumed to have the same properties.
264  *
265  * \tparam SmallMatInT Data type of \c lambda_values_in.
266  * \tparam SmallMatOutT Data type of \c lambda_values_out
267  * \param lambda_values_in Local part of vector x.
268  * \param lambda_values_out Local part that will be added to A * x.
269  * \param time Time --- this parameter is redundant for this local solver.
270  * \retval vecAx Local part of vector A * x.
271  ************************************************************************************************/
272  template <typename SmallMatInT, typename SmallMatOutT>
273  SmallMatOutT& trace_to_flux(const SmallMatInT& lambda_values_in,
274  SmallMatOutT& lambda_values_out,
275  const lSol_float_t UNUSED(time) = 0.) const
276  {
277  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
278  lambda_values_in.size() == 2 * hyEdge_dimT,
279  "Both matrices must be of same size which corresponds to the number of faces!");
280  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
281  hy_assert(
282  lambda_values_in[i].size() == lambda_values_out[i].size() &&
283  lambda_values_in[i].size() == n_glob_dofs_per_node(),
284  "Both matrices must be of same size which corresponds to the number of dofs per face!");
285 
286  std::array<lSol_float_t, n_loc_dofs_> coeffs = solve_local_problem(lambda_values_in);
287 
288  std::array<std::array<lSol_float_t, n_shape_bdr_>, 2 * hyEdge_dimT> primals(
289  primal_at_boundary(coeffs)),
290  duals(dual_at_boundary(coeffs));
291 
292  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
293  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
294  lambda_values_out[i][j] = duals[i][j] + tau_ * (primals[i][j] - lambda_values_in[i][j]);
295 
296  return lambda_values_out;
297  }
298  /*!***********************************************************************************************
299  * \brief Evaluate local contribution to matrix--vector residual.
300  *
301  * \tparam SmallMatInT Data type of \c lambda_values_in.
302  * \tparam SmallMatOutT Data type of \c lambda_values_out
303  * \param lambda_values_in Local part of vector x.
304  * \param lambda_values_out Local part that will be added to A * x.
305  * \param time Time --- this parameter is redundant for this local solver.
306  * \retval vecAx Local part of vector A * x.
307  ************************************************************************************************/
308  template <typename SmallMatInT, typename SmallMatOutT>
309  SmallMatOutT& residual_flux(const SmallMatInT& lambda_values_in,
310  SmallMatOutT& lambda_values_out,
311  const lSol_float_t UNUSED(time) = 0.) const
312  {
313  return lambda_values_out = trace_to_flux(lambda_values_in, lambda_values_out);
314  }
315  /*!***********************************************************************************************
316  * \brief Evaluate local squared L2 error.
317  *
318  * \tparam SmallMatT The typename of \c lambda_values.
319  * \param lambda_values The values of the skeletal variable's coefficients.
320  * \param time Time --- this parameter is redundant for this local solver.
321  * \retval vec_b Local part of vector b.
322  ************************************************************************************************/
323  template <typename SmallMatT>
324  std::array<lSol_float_t, 1U> errors(const SmallMatT& UNUSED(lambda_values),
325  const lSol_float_t UNUSED(time) = 0.) const
326  {
327  return std::array<lSol_float_t, 1U>({0.});
328  }
329  /*!***********************************************************************************************
330  * \brief Evaluate local reconstruction at tensorial products of abscissas.
331  *
332  * \tparam absc_float_t Floating type for the abscissa values.
333  * \tparam abscissas_sizeT Size of the array of array of abscissas.
334  * \tparam input_array_t Type of input array.
335  * \param abscissas Abscissas of the supporting points.
336  * \param lambda_values The values of the skeletal variable's coefficients.
337  * \param time Time --- this parameter is redundant for this local solver.
338  * \retval function_values Function values at quadrature points.
339  ************************************************************************************************/
340  template <typename abscissa_float_t, std::size_t abscissas_sizeT, class input_array_t>
341  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>, system_dim>
342  bulk_values(const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
343  const input_array_t& lambda_values,
344  const lSol_float_t UNUSED(time) = 0.) const;
345 
346 }; // end of class DiffusionUniform
347 
348 // -------------------------------------------------------------------------------------------------
350 // -------------------------------------------------------------------------------------------------
351 
352 // -------------------------------------------------------------------------------------------------
353 // -------------------------------------------------------------------------------------------------
354 //
355 // IMPLEMENTATION OF MEMBER FUNCTIONS OF DiffusionUniform
356 //
357 // -------------------------------------------------------------------------------------------------
358 // -------------------------------------------------------------------------------------------------
359 
360 // -------------------------------------------------------------------------------------------------
361 // assemble_loc_matrix
362 // -------------------------------------------------------------------------------------------------
363 
364 template <unsigned int hyEdge_dimT,
365  unsigned int poly_deg,
366  unsigned int quad_deg,
367  typename lSol_float_t>
369  lSol_float_t>
371  const lSol_float_t tau)
372 {
373  lSol_float_t integral;
374 
376 
377  for (unsigned int i = 0; i < n_shape_fct_; ++i)
378  {
379  for (unsigned int j = 0; j < n_shape_fct_; ++j)
380  {
381  // Integral_element phi_i phi_j dx in diagonal blocks
382  integral = integrator::integrate_vol_phiphi(i, j);
383  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
384  local_mat(dim * n_shape_fct_ + i, dim * n_shape_fct_ + j) += integral;
385 
386  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
387  {
388  // Integral_element - nabla phi_i \vec phi_j dx
389  // = Integral_element - div \vec phi_i phi_j dx in right upper and left lower blocks
390  integral = integrator::integrate_vol_Dphiphi(i, j, dim);
391  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= integral;
392  local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -= integral;
393 
394  // Corresponding boundary integrals from integration by parts in left lower blocks
395  integral = integrator::integrate_bdr_phiphi(i, j, 2 * dim + 1);
396  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) += integral;
397  // and from the penalty in the lower right diagonal block
398  local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
399  // Corresponding boundary integrals from integration by parts in left lower blocks
400  integral = integrator::integrate_bdr_phiphi(i, j, 2 * dim + 0);
401  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= integral;
402  // and from the penalty in the lower right diagonal block
403  local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) += tau * integral;
404  }
405  }
406  }
407 
408  return local_mat;
409 } // end of DiffusionUniform::assemble_loc_matrix
410 
411 // -------------------------------------------------------------------------------------------------
412 // assemble_rhs
413 // -------------------------------------------------------------------------------------------------
414 
415 template <unsigned int hyEdge_dimT,
416  unsigned int poly_deg,
417  unsigned int quad_deg,
418  typename lSol_float_t>
419 template <typename SmallMatT>
421  lSol_float_t>
423  const SmallMatT& lambda_values) const
424 {
425  lSol_float_t integral;
426 
427  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
428 
429  hy_assert(lambda_values.size() == 2 * hyEdge_dimT,
430  "The size of the lambda values should be twice the dimension of a hyperedge.");
431  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
432  hy_assert(lambda_values[i].size() == n_shape_bdr_,
433  "The size of lambda should be the amount of ansatz functions at boundary.");
434 
435  for (unsigned int i = 0; i < n_shape_fct_; ++i)
436  {
437  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
438  {
439  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
440  {
441  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
442  right_hand_side[dim * n_shape_fct_ + i] += lambda_values[2 * dim + 0][j] * integral;
443  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
444  tau_ * lambda_values[2 * dim + 0][j] * integral;
445 
446  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
447  right_hand_side[dim * n_shape_fct_ + i] -= lambda_values[2 * dim + 1][j] * integral;
448  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
449  tau_ * lambda_values[2 * dim + 1][j] * integral;
450  }
451  }
452  }
453 
454  return right_hand_side;
455 } // end of DiffusionUniform::assemble_rhs
456 
457 // -------------------------------------------------------------------------------------------------
458 // primal_at_boundary
459 // -------------------------------------------------------------------------------------------------
460 
461 template <unsigned int hyEdge_dimT,
462  unsigned int poly_deg,
463  unsigned int quad_deg,
464  typename lSol_float_t>
465 inline std::array<
466  std::array<lSol_float_t,
468  2 * hyEdge_dimT>
470  const std::array<lSol_float_t, n_loc_dofs_>& coeffs) const
471 {
472  std::array<std::array<lSol_float_t, n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
473  lSol_float_t integral;
474 
475  for (unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
476  bdr_values[dim_n].fill(0.);
477 
478  for (unsigned int i = 0; i < n_shape_fct_; ++i)
479  {
480  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
481  {
482  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
483  {
484  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
485  bdr_values[2 * dim + 0][j] += coeffs[hyEdge_dimT * n_shape_fct_ + i] * integral;
486 
487  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
488  bdr_values[2 * dim + 1][j] += coeffs[hyEdge_dimT * n_shape_fct_ + i] * integral;
489  }
490  }
491  }
492 
493  return bdr_values;
494 } // end of DiffusionUniform::primal_at_boundary
495 
496 // -------------------------------------------------------------------------------------------------
497 // dual_at_boundary
498 // -------------------------------------------------------------------------------------------------
499 
500 template <unsigned int hyEdge_dimT,
501  unsigned int poly_deg,
502  unsigned int quad_deg,
503  typename lSol_float_t>
504 inline std::array<
505  std::array<lSol_float_t,
507  2 * hyEdge_dimT>
509  const std::array<lSol_float_t, (hyEdge_dimT + 1) * n_shape_fct_>& coeffs) const
510 {
511  std::array<std::array<lSol_float_t, n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
512  lSol_float_t integral;
513 
514  for (unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
515  bdr_values[dim_n].fill(0.);
516 
517  for (unsigned int i = 0; i < n_shape_fct_; ++i)
518  {
519  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
520  {
521  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
522  {
523  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 0);
524  bdr_values[2 * dim + 0][j] -= coeffs[dim * n_shape_fct_ + i] * integral;
525 
526  integral = integrator::integrate_bdr_phipsi(i, j, 2 * dim + 1);
527  bdr_values[2 * dim + 1][j] += coeffs[dim * n_shape_fct_ + i] * integral;
528  }
529  }
530  }
531 
532  return bdr_values;
533 } // end of DiffusionUniform::dual_at_boundary
534 
535 // -------------------------------------------------------------------------------------------------
536 // bulk_values
537 // -------------------------------------------------------------------------------------------------
538 
539 template <unsigned int hyEdge_dimT,
540  unsigned int poly_deg,
541  unsigned int quad_deg,
542  typename lSol_float_t>
543 template <typename abscissa_float_t, std::size_t abscissas_sizeT, class input_array_t>
544 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
547  const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
548  const input_array_t& lambda_values,
549  const lSol_float_t) const
550 {
551  SmallVec<n_loc_dofs_, lSol_float_t> coefficients = solve_local_problem(lambda_values);
553  SmallVec<static_cast<unsigned int>(abscissas_sizeT), abscissa_float_t> helper(abscissas);
554 
555  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
557  point_vals;
558 
559  for (unsigned int d = 0; d < system_dim; ++d)
560  {
561  for (unsigned int i = 0; i < coeffs.size(); ++i)
562  coeffs[i] = coefficients[d * n_shape_fct_ + i];
563  for (unsigned int pt = 0; pt < Hypercube<hyEdge_dimT>::pow(abscissas_sizeT); ++pt)
564  point_vals[d][pt] = integrator::shape_fun_t::template lin_comb_fct_val<float>(
565  coeffs, Hypercube<hyEdge_dimT>::template tensorial_pt<Point<hyEdge_dimT> >(pt, helper));
566  }
567 
568  return point_vals;
569 } // end of DiffusionUniform::bulk_values
570 
571 // -------------------------------------------------------------------------------------------------
573 // -------------------------------------------------------------------------------------------------
574 
575 } // namespace LocalSolver
shape_function.hxx
LocalSolver::DiffusionUniform::node_system_dimension
static constexpr unsigned int node_system_dimension()
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_uniform_ldgh.hxx:121
LocalSolver::DiffusionUniform::residual_flux
SmallMatOutT & residual_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, const lSol_float_t UNUSED(time)=0.) const
Evaluate local contribution to matrix–vector residual.
Definition: diffusion_uniform_ldgh.hxx:309
LocalSolver::DiffusionUniform::integrator
TPP::Quadrature::Tensorial< TPP::Quadrature::GaussLegendre< quad_deg >, TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg >, hyEdge_dimT > >, lSol_float_t > integrator
An integrator helps to easily evaluate integrals (e.g. via quadrature).
Definition: diffusion_uniform_ldgh.hxx:180
LocalSolver::DiffusionUniform::dual_at_boundary
std::array< std::array< lSol_float_t, n_shape_bdr_ >, 2 *hyEdge_dimT > dual_at_boundary(const std::array< lSol_float_t,(hyEdge_dimT+1) *n_shape_fct_ > &coeffs) const
Evaluate dual variable at boundary.
LocalSolver::DiffusionUniform::error_def::error_t
std::array< lSol_float_t, 1U > error_t
Define the typename returned by function errors.
Definition: diffusion_uniform_ldgh.hxx:65
Wrapper::LAPACKexception::what
const char * what() const
Definition: lapack.hxx:27
LocalSolver
A namespace for local solvers.
Definition: advection_parab_ldgh.hxx:11
tensorial.hxx
LocalSolver::DiffusionUniform::error_def
Define how errors are evaluated.
Definition: diffusion_uniform_ldgh.hxx:60
LocalSolver::DiffusionUniform::hyEdge_dim
static constexpr unsigned int hyEdge_dim()
Dimension of hyper edge type that this object solves on.
Definition: diffusion_uniform_ldgh.hxx:101
LocalSolver::DiffusionUniform::loc_mat_
const SmallSquareMat< n_loc_dofs_, lSol_float_t > loc_mat_
Local matrix for the local solver.
Definition: diffusion_uniform_ldgh.hxx:172
LocalSolver::DiffusionUniform::n_glob_dofs_per_node
static constexpr unsigned int n_glob_dofs_per_node()
Evaluate amount of global degrees of freedom per hypernode.
Definition: diffusion_uniform_ldgh.hxx:110
LocalSolver::DiffusionUniform::constructor_value_type
lSol_float_t constructor_value_type
Class is constructed using a single double indicating the penalty parameter.
Definition: diffusion_uniform_ldgh.hxx:247
LocalSolver::DiffusionUniform::node_element
Define type of node elements, especially with respect to nodal shape functions.
Definition: diffusion_uniform_ldgh.hxx:51
LocalSolver::DiffusionUniform
Local solver for Poisson's equation on uniform hypergraph.
Definition: diffusion_uniform_ldgh.hxx:39
LocalSolver::DiffusionUniform::primal_at_boundary
std::array< std::array< lSol_float_t, n_shape_bdr_ >, 2 *hyEdge_dimT > primal_at_boundary(const std::array< lSol_float_t, n_loc_dofs_ > &coeffs) const
Evaluate primal variable at boundary.
TPP::Quadrature::GaussLegendre
Gauss–Legendre quadrature points and weights in one spatial dimension.
Definition: one_dimensional.hxx:19
SmallMat::size
static constexpr unsigned int size()
Return size a SmallMat.
Definition: dense_la.hxx:54
TPP::ShapeType::Tensorial
Struct that handles the evaluation of tensorial shape functions.
Definition: tensorial.hxx:22
LocalSolver::DiffusionUniform::n_loc_dofs_
static constexpr unsigned int n_loc_dofs_
Number of (local) degrees of freedom per hyperedge.
Definition: diffusion_uniform_ldgh.hxx:139
LocalSolver::DiffusionUniform::errors
std::array< lSol_float_t, 1U > errors(const SmallMatT &UNUSED(lambda_values), const lSol_float_t UNUSED(time)=0.) const
Evaluate local squared L2 error.
Definition: diffusion_uniform_ldgh.hxx:324
LocalSolver::DiffusionUniform::error_def::initial_error
static error_t initial_error()
Define how initial error is generated.
Definition: diffusion_uniform_ldgh.hxx:69
LocalSolver::DiffusionUniform::assemble_rhs
SmallVec< n_loc_dofs_, lSol_float_t > assemble_rhs(const SmallMatT &lambda_values) const
Assemble local right hand for the local solver.
LocalSolver::DiffusionUniform::node_system_dim
static constexpr unsigned int node_system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_uniform_ldgh.hxx:151
TPP::ShapeFunction
Struct that handles different types of evaluation of shape functions.
Definition: shape_function.hxx:15
TPP::Quadrature::Tensorial
General integrator class on tensorial hypergraphs.
Definition: tensorial.hxx:24
LocalSolver::DiffusionUniform::solve_local_problem
std::array< lSol_float_t, n_loc_dofs_ > solve_local_problem(const SmallMatT &lambda_values) const
Solve local problem.
Definition: diffusion_uniform_ldgh.hxx:206
LocalSolver::DiffusionUniform::tau_
const lSol_float_t tau_
(Globally constant) penalty parameter for HDG scheme.
Definition: diffusion_uniform_ldgh.hxx:168
hypercube.hxx
LocalSolver::DiffusionUniform::bulk_values
std::array< std::array< lSol_float_t, Hypercube< hyEdge_dimT >::pow(abscissas_sizeT)>, system_dim > bulk_values(const std::array< abscissa_float_t, abscissas_sizeT > &abscissas, const input_array_t &lambda_values, const lSol_float_t UNUSED(time)=0.) const
Evaluate local reconstruction at tensorial products of abscissas.
Wrapper::LAPACKexception
Exception to be thrown if LAPACK's solve fails.
Definition: lapack.hxx:25
Hypercube::pow
static constexpr unsigned int pow(unsigned int base)
Return n to the power dim.
Definition: hypercube.hxx:25
LocalSolver::DiffusionUniform::node_element::functions
std::tuple< TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg >, hyEdge_dimT - 1 > > > functions
Definition: diffusion_uniform_ldgh.hxx:55
LocalSolver::DiffusionUniform::error_def::postprocess_error
static error_t postprocess_error(error_t &summed_error)
Define how global errors should be postprocessed.
Definition: diffusion_uniform_ldgh.hxx:87
LocalSolver::DiffusionUniform::trace_to_flux
SmallMatOutT & trace_to_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, const lSol_float_t UNUSED(time)=0.) const
Evaluate local contribution to matrix–vector multiplication.
Definition: diffusion_uniform_ldgh.hxx:273
hy_assert
#define hy_assert(Expr, Msg)
The assertion to be used within HyperHDG — deactivate using -DNDEBUG compile flag.
Definition: hy_assert.hxx:38
dense_la.hxx
LocalSolver::DiffusionUniform::DiffusionUniform
DiffusionUniform(const constructor_value_type &tau=1.)
Constructor for local solver.
Definition: diffusion_uniform_ldgh.hxx:253
LocalSolver::DiffusionUniform::system_dim
static constexpr unsigned int system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_uniform_ldgh.hxx:145
LocalSolver::DiffusionUniform::error_def::sum_error
static error_t sum_error(error_t &summed_error, const error_t &new_error)
Define how local errors should be accumulated.
Definition: diffusion_uniform_ldgh.hxx:78
UNUSED
#define UNUSED(x)
Unused parametes will neither result in g++, nor in doxygen warnings if wrapped by this.
Definition: compile_time_tricks.hxx:10
LocalSolver::DiffusionUniform::data_type
Define type of (hyperedge related) data that is stored in HyDataContainer.
Definition: diffusion_uniform_ldgh.hxx:45
LocalSolver::DiffusionUniform::n_shape_fct_
static constexpr unsigned int n_shape_fct_
Number of local shape functions (with respect to all spatial dimensions).
Definition: diffusion_uniform_ldgh.hxx:131
LocalSolver::DiffusionUniform::assemble_loc_matrix
static SmallSquareMat< n_loc_dofs_, lSol_float_t > assemble_loc_matrix(const lSol_float_t tau)
Assemble local matrix for the local solver.
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34
LocalSolver::DiffusionUniform::n_shape_bdr_
static constexpr unsigned int n_shape_bdr_
Number oflocal shape functions (with respect to a face / hypernode).
Definition: diffusion_uniform_ldgh.hxx:135
LocalSolver::DiffusionUniform::system_dimension
static constexpr unsigned int system_dimension()
Dimension of of the solution evaluated with respect to a hyperedge.
Definition: diffusion_uniform_ldgh.hxx:117
Hypercube
Helper class containing numbers and functions related to hypercubes.
Definition: hypercube.hxx:12