HyperHDG
diffusion_ldgh_pp.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 Default parameters for the diffusion equation, cf. below.
15  *
16  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
17  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
18  **************************************************************************************************/
19 template <unsigned int space_dimT, typename param_float_t = double>
20 struct DiffusionParametersDefault
21 {
22  /*!***********************************************************************************************
23  * \brief Array containing hypernode types corresponding to Dirichlet boundary.
24  ************************************************************************************************/
25  static constexpr std::array<unsigned int, 0U> dirichlet_nodes{};
26  /*!***********************************************************************************************
27  * \brief Array containing hypernode types corresponding to Neumann boundary.
28  ************************************************************************************************/
29  static constexpr std::array<unsigned int, 0U> neumann_nodes{};
30  /*!***********************************************************************************************
31  * \brief Inverse diffusion coefficient in PDE as analytic function.
32  ************************************************************************************************/
33  static param_float_t inverse_diffusion_coeff(const Point<space_dimT, param_float_t>& point,
34  const param_float_t time = 0.)
35  {
36  return 1.;
37  }
38  /*!***********************************************************************************************
39  * \brief Right-hand side in PDE as analytic function.
40  ************************************************************************************************/
41  static param_float_t right_hand_side(const Point<space_dimT, param_float_t>& point,
42  const param_float_t time = 0.)
43  {
44  return 0.;
45  }
46  /*!***********************************************************************************************
47  * \brief Dirichlet values of solution as analytic function.
48  ************************************************************************************************/
49  static param_float_t dirichlet_value(const Point<space_dimT, param_float_t>& point,
50  const param_float_t time = 0.)
51  {
52  return 0.;
53  }
54  /*!***********************************************************************************************
55  * \brief Neumann values of solution as analytic function.
56  ************************************************************************************************/
57  static param_float_t neumann_value(const Point<space_dimT, param_float_t>& point,
58  const param_float_t time = 0.)
59  {
60  return 0.;
61  }
62  /*!***********************************************************************************************
63  * \brief Analytic result of PDE (for convergence tests).
64  ************************************************************************************************/
65  static param_float_t analytic_result(const Point<space_dimT, param_float_t>& point,
66  const param_float_t time = 0.)
67  {
68  return 0.;
69  }
70 }; // end of struct DiffusionParametersDefault
71 
72 /*!*************************************************************************************************
73  * \brief Local solver diffusion equation on hypergraph.
74  *
75  * This class contains the local solver for an isotropic diffusion equation, i.e.,
76  * \f[
77  * - \nabla \cdot ( d \nabla u ) = f \quad \text{ in } \Omega, \qquad
78  * u = u_\text D \quad \text{ on } \partial \Omega_\text D, \qquad
79  * - d \nabla u \cdot \nu = g_\text N \quad \text{ on } \partial \Omega_\text N
80  * \f]
81  * in a spatial domain \f$\Omega \subset \mathbb R^d\f$. Here, \f$d\f$ is the spatial dimension
82  * \c space_dim, \f$\Omega\f$ is a regular graph (\c hyEdge_dimT = 1) or hypergraph whose
83  * hyperedges are surfaces (\c hyEdge_dimT = 2) or volumes (\c hyEdge_dimT = 3) or hypervolumes (in
84  * case of \c hyEdge_dimT > 3). \f$f\f$ and \f$d\f$ are scalars defined in the whole domain, the
85  * Dirichlet and Neumann boundary data needs to be defined on their respective hypernodes.
86  *
87  * Moreover, this class provides the functions that approximate the condensed mass matrix. By this,
88  * it is possible to approximate parabolic problems (in a very bad way) and to find good starting
89  * values for the nonlinear eigenvalue problem.
90  *
91  * \tparam hyEdge_dimT Dimension of a hyperedge, i.e., 1 is for PDEs defined on graphs, 2 is for
92  * PDEs defined on surfaces, and 3 is for PDEs defined on volumes.
93  * \tparam poly_deg The polynomial degree of test and trial functions.
94  * \tparam quad_deg The order of the quadrature rule.
95  * \tparam parametersT Struct depending on templates \c space_dimTP and \c lSol_float_TP that
96  * contains static parameter functions.
97  * Defaults to above functions included in \c DiffusionParametersDefault.
98  * \tparam lSol_float_t The floating point type calculations are executed in. Defaults to double.
99  *
100  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
101  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
102  **************************************************************************************************/
103 template <unsigned int hyEdge_dimT,
104  unsigned int poly_deg,
105  unsigned int quad_deg,
106  template <unsigned int, typename> typename parametersT = DiffusionParametersDefault,
107  typename lSol_float_t = double>
109 {
110  public:
111  /*!***********************************************************************************************
112  * \brief Define type of (hyperedge related) data that is stored in HyDataContainer.
113  ************************************************************************************************/
114  struct data_type
115  {
116  };
117  /*!***********************************************************************************************
118  * \brief Define type of node elements, especially with respect to nodal shape functions.
119  ************************************************************************************************/
121  {
122  typedef std::tuple<TPP::ShapeFunction<
125  };
126  /*!***********************************************************************************************
127  * \brief Define how errors are evaluated.
128  ************************************************************************************************/
129  struct error_def
130  {
131  /*!*********************************************************************************************
132  * \brief Define the typename returned by function errors.
133  **********************************************************************************************/
134  typedef std::array<lSol_float_t, 1U> error_t;
135  /*!*********************************************************************************************
136  * \brief Define how initial error is generated.
137  **********************************************************************************************/
139  {
140  std::array<lSol_float_t, 1U> summed_error;
141  summed_error.fill(0.);
142  return summed_error;
143  }
144  /*!*********************************************************************************************
145  * \brief Define how local errors should be accumulated.
146  **********************************************************************************************/
147  static error_t sum_error(error_t& summed_error, const error_t& new_error)
148  {
149  for (unsigned int k = 0; k < summed_error.size(); ++k)
150  summed_error[k] += new_error[k];
151  return summed_error;
152  }
153  /*!*********************************************************************************************
154  * \brief Define how global errors should be postprocessed.
155  **********************************************************************************************/
156  static error_t postprocess_error(error_t& summed_error)
157  {
158  for (unsigned int k = 0; k < summed_error.size(); ++k)
159  summed_error[k] = std::sqrt(summed_error[k]);
160  return summed_error;
161  }
162  };
163 
164  // -----------------------------------------------------------------------------------------------
165  // Public, static constexpr functions
166  // -----------------------------------------------------------------------------------------------
167 
168  /*!***********************************************************************************************
169  * \brief Dimension of hyper edge type that this object solves on.
170  ************************************************************************************************/
171  static constexpr unsigned int hyEdge_dim() { return hyEdge_dimT; }
172  /*!***********************************************************************************************
173  * \brief Evaluate amount of global degrees of freedom per hypernode.
174  *
175  * This number must be equal to HyperNodeFactory::n_dofs_per_node() of the HyperNodeFactory
176  * cooperating with this object.
177  *
178  * \retval n_dofs Number of global degrees of freedom per hypernode.
179  ************************************************************************************************/
180  static constexpr unsigned int n_glob_dofs_per_node()
181  {
182  return Hypercube<hyEdge_dimT - 1>::pow(poly_deg + 1);
183  }
184  /*!***********************************************************************************************
185  * \brief Dimension of of the solution evaluated with respect to a hyperedge.
186  ************************************************************************************************/
187  static constexpr unsigned int system_dimension() { return hyEdge_dimT + 1; }
188  /*!***********************************************************************************************
189  * \brief Dimension of of the solution evaluated with respect to a hypernode.
190  ************************************************************************************************/
191  static constexpr unsigned int node_system_dimension() { return 1; }
192 
193  private:
194  // -----------------------------------------------------------------------------------------------
195  // Private, static constexpr functions
196  // -----------------------------------------------------------------------------------------------
197 
198  /*!***********************************************************************************************
199  * \brief Number of local shape functions (with respect to all spatial dimensions).
200  ************************************************************************************************/
201  static constexpr unsigned int n_shape_fct_ = n_glob_dofs_per_node() * (poly_deg + 1);
202  /*!***********************************************************************************************
203  * \brief Number oflocal shape functions (with respect to a face / hypernode).
204  ************************************************************************************************/
205  static constexpr unsigned int n_shape_bdr_ = n_glob_dofs_per_node();
206  /*!***********************************************************************************************
207  * \brief Number of (local) degrees of freedom per hyperedge.
208  ************************************************************************************************/
209  static constexpr unsigned int n_loc_dofs_ = (hyEdge_dimT + 1) * n_shape_fct_;
210  /*!***********************************************************************************************
211  * \brief Dimension of of the solution evaluated with respect to a hypernode.
212  *
213  * This allows to the use of this quantity as template parameter in member functions.
214  ************************************************************************************************/
215  static constexpr unsigned int system_dim = system_dimension();
216  /*!***********************************************************************************************
217  * \brief Dimension of of the solution evaluated with respect to a hypernode.
218  *
219  * This allows to the use of this quantity as template parameter in member functions.
220  ************************************************************************************************/
221  static constexpr unsigned int node_system_dim = node_system_dimension();
222  /*!***********************************************************************************************
223  * \brief Find out whether a node is of Dirichlet type.
224  ************************************************************************************************/
225  template <typename parameters>
226  static constexpr bool is_dirichlet(const unsigned int node_type)
227  {
228  return std::find(parameters::dirichlet_nodes.begin(), parameters::dirichlet_nodes.end(),
229  node_type) != parameters::dirichlet_nodes.end();
230  }
231 
232  // -----------------------------------------------------------------------------------------------
233  // Private, const members: Parameters and auxiliaries that help assembling matrices, etc.
234  // -----------------------------------------------------------------------------------------------
235 
236  /*!***********************************************************************************************
237  * \brief (Globally constant) penalty parameter for HDG scheme.
238  ************************************************************************************************/
239  const lSol_float_t tau_;
240  /*!***********************************************************************************************
241  * \brief An integrator helps to easily evaluate integrals (e.g. via quadrature).
242  ************************************************************************************************/
246  lSol_float_t>
248  /*!***********************************************************************************************
249  * \brief An integrator helps to easily evaluate integrals of postprocessing.
250  ************************************************************************************************/
255  lSol_float_t>
257 
258  // -----------------------------------------------------------------------------------------------
259  // Private, internal functions for the local solver
260  // -----------------------------------------------------------------------------------------------
261 
262  /*!***********************************************************************************************
263  * \brief Assemble local matrix for the local solver.
264  *
265  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
266  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
267  * \param time Time, when the local matrix is evaluated.
268  * \retval loc_mat Matrix of the local solver.
269  ************************************************************************************************/
270  template <typename hyEdgeT>
272  hyEdgeT& hyper_edge,
273  const lSol_float_t time) const;
274  /*!***********************************************************************************************
275  * \brief Assemble local right-hand for the local solver (from skeletal).
276  *
277  * The right hand side needs the values of the global degrees of freedom. Note that we basically
278  * follow the lines of
279  *
280  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
281  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
282  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
283  *
284  * and discriminate between local solvers with respect to the skeletal variable and with respect
285  * to the global right-hand side. This assembles the local right-hand side with respect to the
286  * skeletal variable.
287  *
288  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
289  * \tparam SmallMatT The data type of the \c lambda values.
290  * \param lambda_values Global degrees of freedom associated to the hyperedge.
291  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
292  * \retval loc_rhs Local right hand side of the locasl solver.
293  ************************************************************************************************/
294  template <typename hyEdgeT, typename SmallMatT>
296  const SmallMatT& lambda_values,
297  hyEdgeT& hyper_edge) const;
298  /*!***********************************************************************************************
299  * \brief Assemble local right-hand for the local solver (from global right-hand side).
300  *
301  * Note that we basically follow the lines of
302  *
303  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
304  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
305  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
306  *
307  * and discriminate between local solvers with respect to the skeletal variable and with respect
308  * to the global right-hand side. This assembles the local right-hand side with respect to the
309  * global right-hand side. This function implicitly uses the parameters.
310  *
311  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
312  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
313  * \param time Point of time, rhs is evaluated at
314  * \retval loc_rhs Local right hand side of the locasl solver.
315  ************************************************************************************************/
316  template <typename hyEdgeT>
318  hyEdgeT& hyper_edge,
319  const lSol_float_t time) const;
320  /*!***********************************************************************************************
321  * \brief Assemble local right-hand for the local solver (from volume function coefficients).
322  *
323  * Note that we basically follow the lines of
324  *
325  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
326  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
327  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
328  *
329  * and discriminate between local solvers with respect to the skeletal variable and with respect
330  * to the global right-hand side. This assembles the local right-hand side with respect to the
331  * global right-hand side. This function implicitly uses the parameters.
332  *
333  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
334  * \tparam SmallVecT The data type of the coefficients.
335  * \param coeffs Local coefficients of bulk variable u.
336  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
337  * \retval loc_rhs Local right hand side of the locasl solver.
338  ************************************************************************************************/
339  template <typename hyEdgeT, typename SmallVecT>
340  inline SmallVec<n_loc_dofs_, lSol_float_t> assemble_rhs_from_coeffs(const SmallVecT& coeffs,
341  hyEdgeT& hyper_edge) const;
342  /*!***********************************************************************************************
343  * \brief Solve local problem (with right-hand side from skeletal).
344  *
345  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
346  * \tparam SmallMatT The data type of \c lambda_values.
347  * \param lambda_values Global degrees of freedom associated to the hyperedge.
348  * \param solution_type Type of local problem that is to be solved.
349  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
350  * \param time Point of time the problem is solved.
351  * \retval loc_sol Solution of the local problem.
352  ************************************************************************************************/
353  template <typename hyEdgeT, typename SmallMatT>
354  inline SmallVec<n_loc_dofs_, lSol_float_t> solve_local_problem(const SmallMatT& lambda_values,
355  const unsigned int solution_type,
356  hyEdgeT& hyper_edge,
357  const lSol_float_t time) const
358  {
359  try
360  {
362  if (solution_type == 0)
363  rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge);
364  else if (solution_type == 1)
365  rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge) +
366  assemble_rhs_from_global_rhs(hyper_edge, time);
367  else
368  hy_assert(0 == 1, "This has not been implemented!");
369  return rhs / assemble_loc_matrix(hyper_edge, time);
370  }
371  catch (Wrapper::LAPACKexception& exc)
372  {
373  hy_assert(0 == 1, exc.what() << std::endl
374  << "This can happen if quadrature is too inaccurate!");
375  throw exc;
376  }
377  }
378  /*!***********************************************************************************************
379  * \brief Evaluate primal variable at boundary.
380  *
381  * Function to evaluate primal variable of the solution. This function is needed to calculate
382  * the local numerical fluxes.
383  *
384  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
385  * \param coeffs Coefficients of the local solution.
386  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
387  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
388  ************************************************************************************************/
389  template <typename hyEdgeT>
392  hyEdgeT& hyper_edge) const;
393  /*!***********************************************************************************************
394  * \brief Evaluate dual variable at boundary.
395  *
396  * Function to evaluate dual variable of the solution. This function is needed to calculate the
397  * local numerical fluxes.
398  *
399  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
400  * \param coeffs Coefficients of the local solution.
401  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
402  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
403  ************************************************************************************************/
404  template <typename hyEdgeT>
407  hyEdgeT& hyper_edge) const;
408 
409  public:
410  // -----------------------------------------------------------------------------------------------
411  // Public functions (and one typedef) to be utilized by external functions.
412  // -----------------------------------------------------------------------------------------------
413 
414  /*!***********************************************************************************************
415  * \brief Class is constructed using a single double indicating the penalty parameter.
416  ************************************************************************************************/
417  typedef lSol_float_t constructor_value_type;
418  /*!***********************************************************************************************
419  * \brief Constructor for local solver.
420  *
421  * \param tau Penalty parameter of HDG scheme.
422  ************************************************************************************************/
424  /*!***********************************************************************************************
425  * \brief Evaluate local contribution to matrix--vector multiplication.
426  *
427  * Execute matrix--vector multiplication y = A * x, where x represents the vector containing the
428  * skeletal variable (adjacent to one hyperedge), and A is the condensed matrix arising from the
429  * HDG discretization. This function does this multiplication (locally) for one hyperedge. The
430  * hyperedge is no parameter, since all hyperedges are assumed to have the same properties.
431  *
432  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
433  * \tparam SmallMatInT Data type of \c lambda_values_in.
434  * \tparam SmallMatOutT Data type of \c lambda_values_out.
435  * \param lambda_values_in Local part of vector x.
436  * \param lambda_values_out Local part that will be added to A * x.
437  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
438  * \param time Time.
439  * \retval vecAx Local part of vector A * x.
440  ************************************************************************************************/
441  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
442  SmallMatOutT& trace_to_flux(const SmallMatInT& lambda_values_in,
443  SmallMatOutT& lambda_values_out,
444  hyEdgeT& hyper_edge,
445  const lSol_float_t time = 0.) const
446  {
447  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
448  lambda_values_in.size() == 2 * hyEdge_dimT,
449  "Both matrices must be of same size which corresponds to the number of faces!");
450  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
451  hy_assert(
452  lambda_values_in[i].size() == lambda_values_out[i].size() &&
453  lambda_values_in[i].size() == n_glob_dofs_per_node(),
454  "Both matrices must be of same size which corresponds to the number of dofs per face!");
455 
456  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
458  solve_local_problem(lambda_values_in, 0U, hyper_edge, time);
459 
461  primal_at_boundary(coeffs, hyper_edge)),
462  duals(dual_at_boundary(coeffs, hyper_edge));
463 
464  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
465  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
466  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
467  lambda_values_out[i][j] = 0.;
468  else
469  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
470  lambda_values_out[i][j] =
471  duals(i, j) + tau_ * primals(i, j) -
472  tau_ * lambda_values_in[i][j] * hyper_edge.geometry.face_area(i);
473 
474  return lambda_values_out;
475  }
476  /*!***********************************************************************************************
477  * \brief Fill an array with 1 if the node is Dirichlet and 0 otherwise.
478  ************************************************************************************************/
479  template <typename hyEdgeT>
480  std::array<unsigned int, 2 * hyEdge_dimT> node_types(hyEdgeT& hyper_edge) const
481  {
482  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
483 
484  std::array<unsigned int, 2 * hyEdge_dimT> result;
485  result.fill(0);
486 
487  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
488  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
489  result[i] = 1;
490 
491  return result;
492  }
493  /*!***********************************************************************************************
494  * \brief Evaluate local contribution to residual \f$ A x - b \f$.
495  *
496  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
497  * \tparam SmallMatInT Data type of \c lambda_values_in.
498  * \tparam SmallMatOutT Data type of \c lambda_values_out.
499  * \param lambda_values_in Local part of vector x.
500  * \param lambda_values_out Local part that will be added to A * x.
501  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
502  * \param time Time at which analytic functions are evaluated.
503  * \retval vecAx Local part of vector A * x - b.
504  ************************************************************************************************/
505  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
506  SmallMatOutT& residual_flux(const SmallMatInT& lambda_values_in,
507  SmallMatOutT& lambda_values_out,
508  hyEdgeT& hyper_edge,
509  const lSol_float_t time = 0.) const
510  {
511  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
512  lambda_values_in.size() == 2 * hyEdge_dimT,
513  "Both matrices must be of same size which corresponds to the number of faces!");
514  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
515  hy_assert(
516  lambda_values_in[i].size() == lambda_values_out[i].size() &&
517  lambda_values_in[i].size() == n_glob_dofs_per_node(),
518  "Both matrices must be of same size which corresponds to the number of dofs per face!");
519 
520  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
522  solve_local_problem(lambda_values_in, 1U, hyper_edge, time);
523 
525  primal_at_boundary(coeffs, hyper_edge)),
526  duals(dual_at_boundary(coeffs, hyper_edge));
527 
528  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
529  {
530  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
531  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
532  lambda_values_out[i][j] = 0.;
533  else
534  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
535  lambda_values_out[i][j] =
536  duals(i, j) + tau_ * primals(i, j) -
537  tau_ * lambda_values_in[i][j] * hyper_edge.geometry.face_area(i);
538  }
539 
540  return lambda_values_out;
541  }
542  /*!***********************************************************************************************
543  * \brief Calculate squared local contribution of post-processed L2 error.
544  *
545  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
546  * \tparam SmallMatT Data type of \c lambda_values.
547  * \param lambda_values The values of the skeletal variable's coefficients.
548  * \param hy_edge The geometry of the considered hyperedge (of typename GeomT).
549  * \param time Time at which anaytic functions are evaluated.
550  * \retval vec_b Local part of vector b.
551  ************************************************************************************************/
552  template <typename hyEdgeT, typename SmallMatT>
553  std::array<lSol_float_t, 1U> errors(const SmallMatT& lambda_values,
554  hyEdgeT& hy_edge,
555  const lSol_float_t time = 0.) const
556  {
557  hy_assert(lambda_values.size() == 2 * hyEdge_dimT, "Matrix must have appropriate size!");
558  for (unsigned int i = 0; i < lambda_values.size(); ++i)
559  hy_assert(lambda_values[i].size() == n_glob_dofs_per_node(),
560  "Matrix must have appropriate size!");
561 
562  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
563  constexpr unsigned int n_shape_pp = Hypercube<hyEdge_dimT>::pow(poly_deg + 2);
564 
566  solve_local_problem(lambda_values, 1U, hy_edge, time);
567 
569  for (unsigned int i = 0; i < n_shape_pp; ++i)
570  for (unsigned int j = 0; j < n_shape_pp; ++j)
571  matrix(i, j) = integrator_pp::template integrate_vol_nablaphinablaphifunc<
572  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>,
573  decltype(hyEdgeT::geometry), parameters::diffusion_coeff,
574  Point<hyEdge_dimT, lSol_float_t> >(i, j, hy_edge.geometry, time);
575  matrix(0, 0) = integrator_pp::integrate_vol_phiphi(0, 0, hy_edge.geometry);
576 
579 
580  for (unsigned int i = 0; i < n_shape_pp; ++i)
581  for (unsigned int j = 0; j < n_shape_fct_; ++j)
582  {
583  grad_int_vec = integrator_pp::template integrate_vol_nablaphiphi<
584  Point<hyEdge_dimT, lSol_float_t>, decltype(hyEdgeT::geometry), poly_deg + 1, poly_deg>(
585  i, j, hy_edge.geometry);
586  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
587  vector[i] -= coefficients[dim * n_shape_fct_ + j] * grad_int_vec[dim];
588  }
589  vector[0] = coefficients[hyEdge_dimT * n_shape_fct_] *
590  integrator_pp::integrate_vol_phiphi(0, 0, hy_edge.geometry);
591 
592  sol = vector / matrix;
593 
594  return std::array<lSol_float_t, 1U>({integrator_pp::template integrate_vol_diffsquare_discana<
595  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
596  parameters::analytic_result, Point<hyEdge_dimT, lSol_float_t> >(sol.data(), hy_edge.geometry,
597  time)});
598  }
599  /*!***********************************************************************************************
600  * \brief Evaluate non-post-processed local reconstruction at tensorial products of abscissas.
601  *
602  * \tparam absc_float_t Floating type for the abscissa values.
603  * \tparam abscissas_sizeT Size of the array of array of abscissas.
604  * \tparam input_array_t Type of input array.
605  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
606  * \param abscissas Abscissas of the supporting points.
607  * \param lambda_values The values of the skeletal variable's coefficients.
608  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
609  * \param time Time at which analytic functions are evaluated.
610  * \retval function_values Function values at quadrature points.
611  ************************************************************************************************/
612  template <typename abscissa_float_t,
613  std::size_t abscissas_sizeT,
614  class input_array_t,
615  class hyEdgeT>
616  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>, system_dim>
617  bulk_values(const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
618  const input_array_t& lambda_values,
619  hyEdgeT& hyper_edge,
620  const lSol_float_t time = 0.) const;
621 }; // end of class DiffusionPostprocess
622 
623 // -------------------------------------------------------------------------------------------------
625 // -------------------------------------------------------------------------------------------------
626 
627 // -------------------------------------------------------------------------------------------------
628 // -------------------------------------------------------------------------------------------------
629 //
630 // IMPLEMENTATION OF MEMBER FUNCTIONS OF DiffusionPostprocess
631 //
632 // -------------------------------------------------------------------------------------------------
633 // -------------------------------------------------------------------------------------------------
634 
635 // -------------------------------------------------------------------------------------------------
636 // assemble_loc_matrix
637 // -------------------------------------------------------------------------------------------------
638 
639 template <unsigned int hyEdge_dimT,
640  unsigned int poly_deg,
641  unsigned int quad_deg,
642  template <unsigned int, typename>
643  typename parametersT,
644  typename lSol_float_t>
645 template <typename hyEdgeT>
646 inline SmallSquareMat<
648  lSol_float_t>
650  assemble_loc_matrix(hyEdgeT& hyper_edge, const lSol_float_t time) const
651 {
652  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
654  lSol_float_t vol_integral, face_integral, helper;
655  SmallVec<hyEdge_dimT, lSol_float_t> grad_int_vec, normal_int_vec;
656 
657  for (unsigned int i = 0; i < n_shape_fct_; ++i)
658  {
659  for (unsigned int j = 0; j < n_shape_fct_; ++j)
660  {
661  // Integral_element phi_i phi_j dx in diagonal blocks
662  vol_integral = integrator::template integrate_vol_phiphifunc<
663  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
664  parameters::inverse_diffusion_coeff, Point<hyEdge_dimT, lSol_float_t> >(
665  i, j, hyper_edge.geometry, time);
666  // Integral_element - nabla phi_i \vec phi_j dx
667  // = Integral_element - div \vec phi_i phi_j dx in right upper and left lower blocks
668  grad_int_vec =
669  integrator::template integrate_vol_nablaphiphi<SmallVec<hyEdge_dimT, lSol_float_t>,
670  decltype(hyEdgeT::geometry)>(
671  i, j, hyper_edge.geometry);
672 
673  face_integral = 0.;
674  normal_int_vec = 0.;
675  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
676  {
677  helper = integrator::template integrate_bdr_phiphi<decltype(hyEdgeT::geometry)>(
678  i, j, face, hyper_edge.geometry);
679  face_integral += helper;
680  normal_int_vec += helper * hyper_edge.geometry.local_normal(face);
681  }
682 
683  local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) +=
684  tau_ * face_integral;
685  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
686  {
687  local_mat(dim * n_shape_fct_ + i, dim * n_shape_fct_ + j) += vol_integral;
688  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= grad_int_vec[dim];
689  local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -= grad_int_vec[dim];
690  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) += normal_int_vec[dim];
691  }
692  }
693  }
694 
695  return local_mat;
696 } // end of DiffusionPostprocess::assemble_loc_matrix
697 
698 // -------------------------------------------------------------------------------------------------
699 // assemble_rhs_from_lambda
700 // -------------------------------------------------------------------------------------------------
701 
702 template <unsigned int hyEdge_dimT,
703  unsigned int poly_deg,
704  unsigned int quad_deg,
705  template <unsigned int, typename>
706  typename parametersT,
707  typename lSol_float_t>
708 template <typename hyEdgeT, typename SmallMatT>
709 inline SmallVec<
711  lSol_float_t>
713  assemble_rhs_from_lambda(const SmallMatT& lambda_values, hyEdgeT& hyper_edge) const
714 {
715  static_assert(std::is_same<typename SmallMatT::value_type::value_type, lSol_float_t>::value,
716  "Lambda values should have same floating point arithmetics as local solver!");
717  hy_assert(lambda_values.size() == 2 * hyEdge_dimT,
718  "The size of the lambda values should be twice the dimension of a hyperedge.");
719  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
720  hy_assert(lambda_values[i].size() == n_shape_bdr_,
721  "The size of lambda should be the amount of ansatz functions at boundary.");
722 
723  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
724  lSol_float_t integral;
725 
726  for (unsigned int i = 0; i < n_shape_fct_; ++i)
727  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
728  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
729  {
730  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
731  i, j, face, hyper_edge.geometry);
732  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] += tau_ * lambda_values[face][j] * integral;
733  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
734  right_hand_side[dim * n_shape_fct_ + i] -=
735  hyper_edge.geometry.local_normal(face).operator[](dim) * lambda_values[face][j] *
736  integral;
737  }
738 
739  return right_hand_side;
740 } // end of DiffusionPostprocess::assemble_rhs_from_lambda
741 
742 // -------------------------------------------------------------------------------------------------
743 // assemble_rhs_from_global_rhs
744 // -------------------------------------------------------------------------------------------------
745 
746 template <unsigned int hyEdge_dimT,
747  unsigned int poly_deg,
748  unsigned int quad_deg,
749  template <unsigned int, typename>
750  typename parametersT,
751  typename lSol_float_t>
752 template <typename hyEdgeT>
753 inline SmallVec<
755  lSol_float_t>
757  assemble_rhs_from_global_rhs(hyEdgeT& hyper_edge, const lSol_float_t time) const
758 {
759  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
760  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
761  lSol_float_t integral;
762  for (unsigned int i = 0; i < n_shape_fct_; ++i)
763  {
764  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] = integrator::template integrate_vol_phifunc<
765  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
766  parameters::right_hand_side, Point<hyEdge_dimT, lSol_float_t> >(i, hyper_edge.geometry, time);
767  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
768  {
769  if (!is_dirichlet<parameters>(hyper_edge.node_descriptor[face]))
770  continue;
771  integral = integrator::template integrate_bdr_phifunc<
772  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
773  parameters::dirichlet_value, Point<hyEdge_dimT, lSol_float_t> >(i, face,
774  hyper_edge.geometry, time);
775  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] += tau_ * integral;
776  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
777  right_hand_side[dim * n_shape_fct_ + i] -=
778  hyper_edge.geometry.local_normal(face).operator[](dim) * integral;
779  }
780  }
781 
782  return right_hand_side;
783 } // end of DiffusionPostprocess::assemble_rhs_from_global_rhs
784 
785 // -------------------------------------------------------------------------------------------------
786 // assemble_rhs_from_coeffs
787 // -------------------------------------------------------------------------------------------------
788 
789 template <unsigned int hyEdge_dimT,
790  unsigned int poly_deg,
791  unsigned int quad_deg,
792  template <unsigned int, typename>
793  typename parametersT,
794  typename lSol_float_t>
795 template <typename hyEdgeT, typename SmallVecT>
796 inline SmallVec<
798  lSol_float_t>
800  assemble_rhs_from_coeffs(const SmallVecT& coeffs, hyEdgeT& hyper_edge) const
801 {
802  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
803  for (unsigned int i = 0; i < n_shape_fct_; ++i)
804  for (unsigned int j = 0; j < n_shape_fct_; ++j)
805  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
806  coeffs[hyEdge_dimT * n_shape_fct_ + j] *
807  integrator::template integrate_vol_phiphi(i, j, hyper_edge.geometry);
808 
809  return right_hand_side;
810 } // end of DiffusionPostprocess::assemble_rhs_from_coeffs
811 
812 // -------------------------------------------------------------------------------------------------
813 // primal_at_boundary
814 // -------------------------------------------------------------------------------------------------
815 
816 template <unsigned int hyEdge_dimT,
817  unsigned int poly_deg,
818  unsigned int quad_deg,
819  template <unsigned int, typename>
820  typename parametersT,
821  typename lSol_float_t>
822 template <typename hyEdgeT>
823 inline SmallMat<
824  2 * hyEdge_dimT,
826  lSol_float_t>
828  primal_at_boundary(const SmallVec<n_loc_dofs_, lSol_float_t>& coeffs, hyEdgeT& hyper_edge) const
829 {
831 
832  for (unsigned int i = 0; i < n_shape_fct_; ++i)
833  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
834  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
835  bdr_values(face, j) +=
836  coeffs[hyEdge_dimT * n_shape_fct_ + i] *
837  integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
838  i, j, face, hyper_edge.geometry);
839 
840  return bdr_values;
841 } // end of DiffusionPostprocess::primal_at_boundary
842 
843 // -------------------------------------------------------------------------------------------------
844 // dual_at_boundary
845 // -------------------------------------------------------------------------------------------------
846 
847 template <unsigned int hyEdge_dimT,
848  unsigned int poly_deg,
849  unsigned int quad_deg,
850  template <unsigned int, typename>
851  typename parametersT,
852  typename lSol_float_t>
853 template <typename hyEdgeT>
854 inline SmallMat<
855  2 * hyEdge_dimT,
857  lSol_float_t>
860  hyEdgeT& hyper_edge) const
861 {
863  lSol_float_t integral;
864 
865  for (unsigned int i = 0; i < n_shape_fct_; ++i)
866  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
867  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
868  {
869  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
870  i, j, face, hyper_edge.geometry);
871  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
872  bdr_values(face, j) += hyper_edge.geometry.local_normal(face).operator[](dim) * integral *
873  coeffs[dim * n_shape_fct_ + i];
874  }
875 
876  return bdr_values;
877 } // end of DiffusionPostprocess::dual_at_boundary
878 
879 // -------------------------------------------------------------------------------------------------
880 // bulk_values
881 // -------------------------------------------------------------------------------------------------
882 
883 template <unsigned int hyEdge_dimT,
884  unsigned int poly_deg,
885  unsigned int quad_deg,
886  template <unsigned int, typename>
887  typename parametersT,
888  typename lSol_float_t>
889 template <typename abscissa_float_t,
890  std::size_t abscissas_sizeT,
891  class input_array_t,
892  typename hyEdgeT>
893 std::array<
894  std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
897  const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
898  const input_array_t& lambda_values,
899  hyEdgeT& hyper_edge,
900  const lSol_float_t time) const
901 {
903  solve_local_problem(lambda_values, 1U, hyper_edge, time);
905  SmallVec<static_cast<unsigned int>(abscissas_sizeT), abscissa_float_t> helper(abscissas);
906 
907  std::array<
908  std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
910  point_vals;
911 
912  for (unsigned int d = 0; d < system_dim; ++d)
913  {
914  for (unsigned int i = 0; i < coeffs.size(); ++i)
915  coeffs[i] = coefficients[d * n_shape_fct_ + i];
916  for (unsigned int pt = 0; pt < Hypercube<hyEdge_dimT>::pow(abscissas_sizeT); ++pt)
917  point_vals[d][pt] = integrator::shape_fun_t::template lin_comb_fct_val<float>(
918  coeffs, Hypercube<hyEdge_dimT>::template tensorial_pt<Point<hyEdge_dimT> >(pt, helper));
919  }
920 
921  return point_vals;
922 }
923 // end of DiffusionPostprocess::bulk_values
924 
925 // -------------------------------------------------------------------------------------------------
927 // -------------------------------------------------------------------------------------------------
928 
929 } // namespace LocalSolver
LocalSolver::DiffusionPostprocess::tau_
const lSol_float_t tau_
(Globally constant) penalty parameter for HDG scheme.
Definition: diffusion_ldgh_pp.hxx:239
LocalSolver::DiffusionPostprocess::constructor_value_type
lSol_float_t constructor_value_type
Class is constructed using a single double indicating the penalty parameter.
Definition: diffusion_ldgh_pp.hxx:417
shape_function.hxx
LocalSolver::DiffusionPostprocess::primal_at_boundary
SmallMat< 2 *hyEdge_dimT, n_shape_bdr_, lSol_float_t > primal_at_boundary(const SmallVec< n_loc_dofs_, lSol_float_t > &coeffs, hyEdgeT &hyper_edge) const
Evaluate primal variable at boundary.
LocalSolver::DiffusionPostprocess::hyEdge_dim
static constexpr unsigned int hyEdge_dim()
Dimension of hyper edge type that this object solves on.
Definition: diffusion_ldgh_pp.hxx:171
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
diffusion_uniform.geometry
geometry
Definition: diffusion_uniform.py:19
LocalSolver::DiffusionPostprocess::dual_at_boundary
SmallMat< 2 *hyEdge_dimT, n_shape_bdr_, lSol_float_t > dual_at_boundary(const SmallVec< n_loc_dofs_, lSol_float_t > &coeffs, hyEdgeT &hyper_edge) const
Evaluate dual variable at boundary.
LocalSolver::DiffusionPostprocess::trace_to_flux
SmallMatOutT & trace_to_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate local contribution to matrix–vector multiplication.
Definition: diffusion_ldgh_pp.hxx:442
LocalSolver::DiffusionPostprocess::system_dimension
static constexpr unsigned int system_dimension()
Dimension of of the solution evaluated with respect to a hyperedge.
Definition: diffusion_ldgh_pp.hxx:187
LocalSolver::DiffusionPostprocess::residual_flux
SmallMatOutT & residual_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate local contribution to residual .
Definition: diffusion_ldgh_pp.hxx:506
LocalSolver::DiffusionPostprocess::assemble_rhs_from_coeffs
SmallVec< n_loc_dofs_, lSol_float_t > assemble_rhs_from_coeffs(const SmallVecT &coeffs, hyEdgeT &hyper_edge) const
Assemble local right-hand for the local solver (from volume function coefficients).
LocalSolver::DiffusionPostprocess::assemble_rhs_from_global_rhs
SmallVec< n_loc_dofs_, lSol_float_t > assemble_rhs_from_global_rhs(hyEdgeT &hyper_edge, const lSol_float_t time) const
Assemble local right-hand for the local solver (from global right-hand side).
LocalSolver::DiffusionPostprocess::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, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate non-post-processed local reconstruction at tensorial products of abscissas.
LocalSolver::DiffusionPostprocess::error_def
Define how errors are evaluated.
Definition: diffusion_ldgh_pp.hxx:129
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
LocalSolver::DiffusionPostprocess::node_element
Define type of node elements, especially with respect to nodal shape functions.
Definition: diffusion_ldgh_pp.hxx:120
LocalSolver::DiffusionPostprocess::DiffusionPostprocess
DiffusionPostprocess(const constructor_value_type &tau=1.)
Constructor for local solver.
Definition: diffusion_ldgh_pp.hxx:423
LocalSolver::DiffusionPostprocess::node_element::functions
std::tuple< TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg >, hyEdge_dimT - 1 > > > functions
Definition: diffusion_ldgh_pp.hxx:124
LocalSolver::DiffusionPostprocess::node_system_dimension
static constexpr unsigned int node_system_dimension()
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_ldgh_pp.hxx:191
TPP::ShapeType::Tensorial
Struct that handles the evaluation of tensorial shape functions.
Definition: tensorial.hxx:22
LocalSolver::DiffusionParametersDefault::neumann_value
static param_float_t neumann_value(const Point< space_dimT, param_float_t > &point, const param_float_t time=0.)
Neumann values of solution as analytic function.
Definition: diffusion_ldgh_pp.hxx:57
LocalSolver::DiffusionPostprocess::assemble_loc_matrix
SmallSquareMat< n_loc_dofs_, lSol_float_t > assemble_loc_matrix(hyEdgeT &hyper_edge, const lSol_float_t time) const
Assemble local matrix for the local solver.
LocalSolver::DiffusionPostprocess::integrator_pp
TPP::Quadrature::Tensorial< TPP::Quadrature::GaussLegendre< quad_deg+2 >, TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg+1 >, hyEdge_dimT > >, lSol_float_t > integrator_pp
An integrator helps to easily evaluate integrals of postprocessing.
Definition: diffusion_ldgh_pp.hxx:256
LocalSolver::DiffusionPostprocess::data_type
Define type of (hyperedge related) data that is stored in HyDataContainer.
Definition: diffusion_ldgh_pp.hxx:114
LocalSolver::DiffusionPostprocess::node_types
std::array< unsigned int, 2 *hyEdge_dimT > node_types(hyEdgeT &hyper_edge) const
Fill an array with 1 if the node is Dirichlet and 0 otherwise.
Definition: diffusion_ldgh_pp.hxx:480
LocalSolver::DiffusionPostprocess::node_system_dim
static constexpr unsigned int node_system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_ldgh_pp.hxx:221
TPP::ShapeFunction
Struct that handles different types of evaluation of shape functions.
Definition: shape_function.hxx:15
LocalSolver::DiffusionPostprocess::error_def::initial_error
static error_t initial_error()
Define how initial error is generated.
Definition: diffusion_ldgh_pp.hxx:138
TPP::Quadrature::Tensorial
General integrator class on tensorial hypergraphs.
Definition: tensorial.hxx:24
LocalSolver::DiffusionPostprocess::assemble_rhs_from_lambda
SmallVec< n_loc_dofs_, lSol_float_t > assemble_rhs_from_lambda(const SmallMatT &lambda_values, hyEdgeT &hyper_edge) const
Assemble local right-hand for the local solver (from skeletal).
LocalSolver::DiffusionPostprocess::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_ldgh_pp.hxx:247
LocalSolver::DiffusionParametersDefault::neumann_nodes
static constexpr std::array< unsigned int, 0U > neumann_nodes
Array containing hypernode types corresponding to Neumann boundary.
Definition: advection_parab_ldgh.hxx:29
SmallMat::data
std::array< mat_entry_t, size()> & data()
Return data array that allows to manipulate the SmallMat.
Definition: dense_la.hxx:190
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
hypercube.hxx
LocalSolver::DiffusionPostprocess::system_dim
static constexpr unsigned int system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_ldgh_pp.hxx:215
Wrapper::LAPACKexception
Exception to be thrown if LAPACK's solve fails.
Definition: lapack.hxx:25
LocalSolver::DiffusionPostprocess::is_dirichlet
static constexpr bool is_dirichlet(const unsigned int node_type)
Find out whether a node is of Dirichlet type.
Definition: diffusion_ldgh_pp.hxx:226
LocalSolver::DiffusionParametersDefault::dirichlet_nodes
static constexpr std::array< unsigned int, 0U > dirichlet_nodes
Array containing hypernode types corresponding to Dirichlet boundary.
Definition: advection_parab_ldgh.hxx:25
LocalSolver::DiffusionParametersDefault::dirichlet_value
static param_float_t dirichlet_value(const Point< space_dimT, param_float_t > &point, const param_float_t time=0.)
Dirichlet values of solution as analytic function.
Definition: diffusion_ldgh_pp.hxx:49
Hypercube::pow
static constexpr unsigned int pow(unsigned int base)
Return n to the power dim.
Definition: hypercube.hxx:25
LocalSolver::DiffusionPostprocess::errors
std::array< lSol_float_t, 1U > errors(const SmallMatT &lambda_values, hyEdgeT &hy_edge, const lSol_float_t time=0.) const
Calculate squared local contribution of post-processed L2 error.
Definition: diffusion_ldgh_pp.hxx:553
LocalSolver::DiffusionPostprocess::n_shape_bdr_
static constexpr unsigned int n_shape_bdr_
Number oflocal shape functions (with respect to a face / hypernode).
Definition: diffusion_ldgh_pp.hxx:205
LocalSolver::DiffusionParametersDefault::analytic_result
static param_float_t analytic_result(const Point< space_dimT, param_float_t > &point, const param_float_t time=0.)
Analytic result of PDE (for convergence tests).
Definition: diffusion_ldgh_pp.hxx:65
LocalSolver::DiffusionPostprocess::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_ldgh_pp.hxx:147
parameters
the intent is to exercise the right to control the distribution of derivative or collective works based on the Library In mere aggregation of another work not based on the Library with the you must alter all the notices that refer to this so that they refer to the ordinary GNU General Public instead of to this it is irreversible for that so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy This option is useful when you wish to copy part of the code of the Library into a program that is not a library You may copy and distribute the which must be distributed under the terms of Sections and above on a medium customarily used for software interchange If distribution of object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source even though third parties are not compelled to copy the source along with the object code A program that contains no derivative of any portion of the but is designed to work with the Library by being compiled or linked with is called a work that uses the Library Such a in is not a derivative work of the and therefore falls outside the scope of this License linking a work that uses the Library with the Library creates an executable that is a derivative of the rather than a work that uses the library The executable is therefore covered by this License Section states terms for distribution of such executables When a work that uses the Library uses material from a header file that is part of the the object code for the work may be a derivative work of the Library even though the source code is not Whether this is true is especially significant if the work can be linked without the or if the work is itself a library The threshold for this to be true is not precisely defined by law If such an object file uses only numerical parameters
Definition: License.txt:259
hy_assert
#define hy_assert(Expr, Msg)
The assertion to be used within HyperHDG — deactivate using -DNDEBUG compile flag.
Definition: hy_assert.hxx:38
LocalSolver::DiffusionPostprocess::error_def::error_t
std::array< lSol_float_t, 1U > error_t
Define the typename returned by function errors.
Definition: diffusion_ldgh_pp.hxx:134
dense_la.hxx
LocalSolver::DiffusionPostprocess::error_def::postprocess_error
static error_t postprocess_error(error_t &summed_error)
Define how global errors should be postprocessed.
Definition: diffusion_ldgh_pp.hxx:156
LocalSolver::DiffusionParametersDefault::right_hand_side
static param_float_t right_hand_side(const Point< space_dimT, param_float_t > &point, const param_float_t time=0.)
Right-hand side in PDE as analytic function.
Definition: diffusion_ldgh_pp.hxx:41
LocalSolver::DiffusionPostprocess::solve_local_problem
SmallVec< n_loc_dofs_, lSol_float_t > solve_local_problem(const SmallMatT &lambda_values, const unsigned int solution_type, hyEdgeT &hyper_edge, const lSol_float_t time) const
Solve local problem (with right-hand side from skeletal).
Definition: diffusion_ldgh_pp.hxx:354
LocalSolver::DiffusionPostprocess::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_ldgh_pp.hxx:180
LocalSolver::DiffusionParametersDefault::inverse_diffusion_coeff
static param_float_t inverse_diffusion_coeff(const Point< space_dimT, param_float_t > &point, const param_float_t time=0.)
Inverse diffusion coefficient in PDE as analytic function.
Definition: diffusion_ldgh_pp.hxx:33
LocalSolver::DiffusionPostprocess::n_loc_dofs_
static constexpr unsigned int n_loc_dofs_
Number of (local) degrees of freedom per hyperedge.
Definition: diffusion_ldgh_pp.hxx:209
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34
LocalSolver::DiffusionPostprocess::n_shape_fct_
static constexpr unsigned int n_shape_fct_
Number of local shape functions (with respect to all spatial dimensions).
Definition: diffusion_ldgh_pp.hxx:201
LocalSolver::DiffusionPostprocess
Local solver diffusion equation on hypergraph.
Definition: diffusion_ldgh_pp.hxx:108
Hypercube
Helper class containing numbers and functions related to hypercubes.
Definition: hypercube.hxx:12