HyperHDG
diffusion_advection_reaction_ldg.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>
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  ************************************************************************************************/
34  const param_float_t = 0.)
35  {
36  return 1.;
37  }
38  /*!***********************************************************************************************
39  * \brief The velocity of the advective part of the equation over the diffusion coefficient.
40  ************************************************************************************************/
43  const param_float_t = 0.)
44  {
46  }
47  /*!***********************************************************************************************
48  * \brief The reaction rate for the PDE.
49  ************************************************************************************************/
50  static param_float_t reaction_rate(const Point<space_dimT, param_float_t>&,
51  const param_float_t = 0.)
52  {
53  return 0.;
54  }
55  /*!***********************************************************************************************
56  * \brief Right-hand side in PDE as analytic function.
57  ************************************************************************************************/
59  const param_float_t = 0.)
60  {
61  return 0.;
62  }
63  /*!***********************************************************************************************
64  * \brief Dirichlet values of solution as analytic function.
65  ************************************************************************************************/
67  const param_float_t = 0.)
68  {
69  return 0.;
70  }
71  /*!***********************************************************************************************
72  * \brief Neumann values of solution as analytic function.
73  ************************************************************************************************/
74  static param_float_t neumann_value(const Point<space_dimT, param_float_t>&,
75  const param_float_t = 0.)
76  {
77  return 0.;
78  }
79  /*!***********************************************************************************************
80  * \brief Analytic result of PDE (for convergence tests).
81  ************************************************************************************************/
83  const param_float_t = 0.)
84  {
85  return 0.;
86  }
87 }; // end of struct DiffusionAdvectionReactionParametersDefault
88 
89 /*!*************************************************************************************************
90  * \brief Local solver diffusion equation on hypergraph.
91  *
92  * This class contains the local solver for an isotropic diffusion equation, i.e.,
93  * \f[
94  * - \nabla \cdot ( d \nabla u ) = f \quad \text{ in } \Omega, \qquad
95  * u = u_\text D \quad \text{ on } \partial \Omega_\text D, \qquad
96  * - d \nabla u \cdot \nu = g_\text N \quad \text{ on } \partial \Omega_\text N
97  * \f]
98  * in a spatial domain \f$\Omega \subset \mathbb R^d\f$. Here, \f$d\f$ is the spatial dimension
99  * \c space_dim, \f$\Omega\f$ is a regular graph (\c hyEdge_dimT = 1) or hypergraph whose
100  * hyperedges are surfaces (\c hyEdge_dimT = 2) or volumes (\c hyEdge_dimT = 3) or hypervolumes (in
101  * case of \c hyEdge_dimT > 3). \f$f\f$ and \f$d\f$ are scalars defined in the whole domain, the
102  * Dirichlet and Neumann boundary data needs to be defined on their respective hypernodes.
103  *
104  * Moreover, this class provides the functions that approximate the condensed mass matrix. By this,
105  * it is possible to approximate parabolic problems (in a very bad way) and to find good starting
106  * values for the nonlinear eigenvalue problem.
107  *
108  * \tparam hyEdge_dimT Dimension of a hyperedge, i.e., 1 is for PDEs defined on graphs, 2 is for
109  * PDEs defined on surfaces, and 3 is for PDEs defined on volumes.
110  * \tparam poly_deg The polynomial degree of test and trial functions.
111  * \tparam quad_deg The order of the quadrature rule.
112  * \tparam parametersT Struct depending on templates \c space_dimTP and \c lSol_float_TP that
113  * contains static parameter functions.
114  * Defaults to above functions included in \c
115  *DiffusionAdvectionReactionParametersDefault. \tparam lSol_float_t The floating point type
116  *calculations are executed in. Defaults to double.
117  *
118  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
119  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
120  **************************************************************************************************/
121 template <unsigned int hyEdge_dimT,
122  unsigned int poly_deg,
123  unsigned int quad_deg,
124  template <unsigned int, typename> typename parametersT =
125  DiffusionAdvectionReactionParametersDefault,
126  typename lSol_float_t = double>
128 {
129  public:
130  /*!***********************************************************************************************
131  * \brief Define type of (hyperedge related) data that is stored in HyDataContainer.
132  ************************************************************************************************/
133  struct data_type
134  {
135  };
136  /*!***********************************************************************************************
137  * \brief Define type of node elements, especially with respect to nodal shape functions.
138  ************************************************************************************************/
140  {
141  typedef std::tuple<TPP::ShapeFunction<
144  };
145  /*!***********************************************************************************************
146  * \brief Define how errors are evaluated.
147  ************************************************************************************************/
148  struct error_def
149  {
150  /*!*********************************************************************************************
151  * \brief Define the typename returned by function errors.
152  **********************************************************************************************/
153  typedef std::array<lSol_float_t, 1U> error_t;
154  /*!*********************************************************************************************
155  * \brief Define how initial error is generated.
156  **********************************************************************************************/
158  {
159  std::array<lSol_float_t, 1U> summed_error;
160  summed_error.fill(0.);
161  return summed_error;
162  }
163  /*!*********************************************************************************************
164  * \brief Define how local errors should be accumulated.
165  **********************************************************************************************/
166  static error_t sum_error(error_t& summed_error, const error_t& new_error)
167  {
168  for (unsigned int k = 0; k < summed_error.size(); ++k)
169  summed_error[k] += new_error[k];
170  return summed_error;
171  }
172  /*!*********************************************************************************************
173  * \brief Define how global errors should be postprocessed.
174  **********************************************************************************************/
175  static error_t postprocess_error(error_t& summed_error)
176  {
177  for (unsigned int k = 0; k < summed_error.size(); ++k)
178  summed_error[k] = std::sqrt(summed_error[k]);
179  return summed_error;
180  }
181  };
182 
183  // -----------------------------------------------------------------------------------------------
184  // Public, static constexpr functions
185  // -----------------------------------------------------------------------------------------------
186 
187  /*!***********************************************************************************************
188  * \brief Dimension of hyper edge type that this object solves on.
189  ************************************************************************************************/
190  static constexpr unsigned int hyEdge_dim() { return hyEdge_dimT; }
191  /*!***********************************************************************************************
192  * \brief Evaluate amount of global degrees of freedom per hypernode.
193  *
194  * This number must be equal to HyperNodeFactory::n_dofs_per_node() of the HyperNodeFactory
195  * cooperating with this object.
196  *
197  * \retval n_dofs Number of global degrees of freedom per hypernode.
198  ************************************************************************************************/
199  static constexpr unsigned int n_glob_dofs_per_node()
200  {
201  return Hypercube<hyEdge_dimT - 1>::pow(poly_deg + 1);
202  }
203  /*!***********************************************************************************************
204  * \brief Dimension of of the solution evaluated with respect to a hyperedge.
205  ************************************************************************************************/
206  static constexpr unsigned int system_dimension() { return hyEdge_dimT + 1; }
207  /*!***********************************************************************************************
208  * \brief Dimension of of the solution evaluated with respect to a hypernode.
209  ************************************************************************************************/
210  static constexpr unsigned int node_system_dimension() { return 1; }
211 
212  private:
213  // -----------------------------------------------------------------------------------------------
214  // Private, static constexpr functions
215  // -----------------------------------------------------------------------------------------------
216 
217  /*!***********************************************************************************************
218  * \brief Number of local shape functions (with respect to all spatial dimensions).
219  ************************************************************************************************/
220  static constexpr unsigned int n_shape_fct_ = n_glob_dofs_per_node() * (poly_deg + 1);
221  /*!***********************************************************************************************
222  * \brief Number oflocal shape functions (with respect to a face / hypernode).
223  ************************************************************************************************/
224  static constexpr unsigned int n_shape_bdr_ = n_glob_dofs_per_node();
225  /*!***********************************************************************************************
226  * \brief Number of (local) degrees of freedom per hyperedge.
227  ************************************************************************************************/
228  static constexpr unsigned int n_loc_dofs_ = (hyEdge_dimT + 1) * n_shape_fct_;
229  /*!***********************************************************************************************
230  * \brief Dimension of of the solution evaluated with respect to a hypernode.
231  *
232  * This allows to the use of this quantity as template parameter in member functions.
233  ************************************************************************************************/
234  static constexpr unsigned int system_dim = system_dimension();
235  /*!***********************************************************************************************
236  * \brief Dimension of of the solution evaluated with respect to a hypernode.
237  *
238  * This allows to the use of this quantity as template parameter in member functions.
239  ************************************************************************************************/
240  static constexpr unsigned int node_system_dim = node_system_dimension();
241  /*!***********************************************************************************************
242  * \brief Find out whether a node is of Dirichlet type.
243  ************************************************************************************************/
244  template <typename parameters>
245  static constexpr bool is_dirichlet(const unsigned int node_type)
246  {
247  return std::find(parameters::dirichlet_nodes.begin(), parameters::dirichlet_nodes.end(),
248  node_type) != parameters::dirichlet_nodes.end();
249  }
250 
251  // -----------------------------------------------------------------------------------------------
252  // Private, const members: Parameters and auxiliaries that help assembling matrices, etc.
253  // -----------------------------------------------------------------------------------------------
254 
255  /*!***********************************************************************************************
256  * \brief (Globally constant) penalty parameter for HDG scheme.
257  ************************************************************************************************/
258  const lSol_float_t tau_;
259  /*!***********************************************************************************************
260  * \brief An integrator helps to easily evaluate integrals (e.g. via quadrature).
261  ************************************************************************************************/
265  lSol_float_t>
267 
268  // -----------------------------------------------------------------------------------------------
269  // Private, internal functions for the local solver
270  // -----------------------------------------------------------------------------------------------
271 
272  /*!***********************************************************************************************
273  * \brief Assemble local matrix for the local solver.
274  *
275  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
276  * \param tau Penalty parameter.
277  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
278  * \param time Time, when the local matrix is evaluated.
279  * \retval loc_mat Matrix of the local solver.
280  ************************************************************************************************/
281  template <typename hyEdgeT>
283  assemble_loc_matrix(const lSol_float_t tau, hyEdgeT& hyper_edge, const lSol_float_t time) const;
284  /*!***********************************************************************************************
285  * \brief Assemble local right-hand for the local solver (from skeletal).
286  *
287  * The right hand side needs the values of the global degrees of freedom. Note that we basically
288  * follow the lines of
289  *
290  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
291  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
292  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
293  *
294  * and discriminate between local solvers with respect to the skeletal variable and with respect
295  * to the global right-hand side. This assembles the local right-hand side with respect to the
296  * skeletal variable.
297  *
298  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
299  * \tparam SmallMatT The data type of the \c lambda values.
300  * \param lambda_values Global degrees of freedom associated to the hyperedge.
301  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
302  * \retval loc_rhs Local right hand side of the locasl solver.
303  ************************************************************************************************/
304  template <typename hyEdgeT, typename SmallMatT>
306  const SmallMatT& lambda_values,
307  hyEdgeT& hyper_edge) const;
308  /*!***********************************************************************************************
309  * \brief Assemble local right-hand for the local solver (from global right-hand side).
310  *
311  * Note that we basically follow the lines of
312  *
313  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
314  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
315  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
316  *
317  * and discriminate between local solvers with respect to the skeletal variable and with respect
318  * to the global right-hand side. This assembles the local right-hand side with respect to the
319  * global right-hand side. This function implicitly uses the parameters.
320  *
321  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
322  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
323  * \param time Point of time, rhs is evaluated at
324  * \retval loc_rhs Local right hand side of the locasl solver.
325  ************************************************************************************************/
326  template <typename hyEdgeT>
328  hyEdgeT& hyper_edge,
329  const lSol_float_t time) const;
330  /*!***********************************************************************************************
331  * \brief Assemble local right-hand for the local solver (from volume function coefficients).
332  *
333  * Note that we basically follow the lines of
334  *
335  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
336  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
337  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
338  *
339  * and discriminate between local solvers with respect to the skeletal variable and with respect
340  * to the global right-hand side. This assembles the local right-hand side with respect to the
341  * global right-hand side. This function implicitly uses the parameters.
342  *
343  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
344  * \tparam SmallVecT The data type of the coefficients.
345  * \param coeffs Local coefficients of bulk variable u.
346  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
347  * \retval loc_rhs Local right hand side of the locasl solver.
348  ************************************************************************************************/
349  template <typename hyEdgeT, typename SmallVecT>
350  inline SmallVec<n_loc_dofs_, lSol_float_t> assemble_rhs_from_coeffs(const SmallVecT& coeffs,
351  hyEdgeT& hyper_edge) const;
352  /*!***********************************************************************************************
353  * \brief Solve local problem (with right-hand side from skeletal).
354  *
355  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
356  * \tparam SmallMatT The data type of \c lambda_values.
357  * \param lambda_values Global degrees of freedom associated to the hyperedge.
358  * \param solution_type Type of local problem that is to be solved.
359  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
360  * \param time Point of time the problem is solved.
361  * \retval loc_sol Solution of the local problem.
362  ************************************************************************************************/
363  template <typename hyEdgeT, typename SmallMatT>
364  inline SmallVec<n_loc_dofs_, lSol_float_t> solve_local_problem(const SmallMatT& lambda_values,
365  const unsigned int solution_type,
366  hyEdgeT& hyper_edge,
367  const lSol_float_t time) const
368  {
369  try
370  {
372  if (solution_type == 0)
373  rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge);
374  else if (solution_type == 1)
375  rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge) +
376  assemble_rhs_from_global_rhs(hyper_edge, time);
377  else
378  hy_assert(0 == 1, "This has not been implemented!");
379  return rhs / assemble_loc_matrix(tau_, hyper_edge, time);
380  }
381  catch (Wrapper::LAPACKexception& exc)
382  {
383  hy_assert(0 == 1, exc.what() << std::endl
384  << "This can happen if quadrature is too inaccurate!");
385  throw exc;
386  }
387  }
388  /*!***********************************************************************************************
389  * \brief Solve local problem for mass matrix approximation.
390  *
391  * \note This function is not use for elliptic problems.
392  *
393  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
394  * \tparam SmallMatT The data type for the lambda_values.
395  * \param lambda_values Global degrees of freedom associated to the hyperedge.
396  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
397  * \param time Point of time the local problem is solved at.
398  * \retval loc_sol Solution of the local problem.
399  ************************************************************************************************/
400  template <typename hyEdgeT, typename SmallMatT>
401  inline SmallVec<n_loc_dofs_, lSol_float_t> solve_mass_problem(const SmallMatT& lambda_values,
402  hyEdgeT& hyper_edge,
403  const lSol_float_t time) const
404  {
405  try
406  {
407  SmallVec<n_loc_dofs_, lSol_float_t> rhs = assemble_rhs_from_coeffs(lambda_values, hyper_edge);
408  return rhs / assemble_loc_matrix(tau_, hyper_edge, time);
409  }
410  catch (Wrapper::LAPACKexception& exc)
411  {
412  hy_assert(0 == 1, exc.what() << std::endl
413  << "This can happen if quadrature is too inaccurate!");
414  throw exc;
415  }
416  }
417  /*!***********************************************************************************************
418  * \brief Solve local problem for parabolic approximations.
419  *
420  * \note This function is not use for elliptic problems.
421  ************************************************************************************************/
422  template <typename hyEdgeT, typename SmallMatT, typename SmallVecT>
423  inline SmallVec<n_loc_dofs_, lSol_float_t> solve_loc_prob_cor(const SmallMatT& lambda_values,
424  const SmallVecT& coeffs,
425  hyEdgeT& hyper_edge,
426  const lSol_float_t delta_time,
427  const lSol_float_t time) const
428  {
429  try
430  {
432  rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge) +
433  assemble_rhs_from_global_rhs(hyper_edge, time) +
434  assemble_rhs_from_coeffs(coeffs, hyper_edge);
435  return (rhs / assemble_loc_matrix(tau_, hyper_edge, time));
436  }
437  catch (Wrapper::LAPACKexception& exc)
438  {
439  hy_assert(0 == 1, exc.what() << std::endl
440  << "This can happen if quadrature is too inaccurate!");
441  throw exc;
442  }
443  }
444  /*!***********************************************************************************************
445  * \brief Evaluate primal variable at boundary.
446  *
447  * Function to evaluate primal variable of the solution. This function is needed to calculate
448  * the local numerical fluxes.
449  *
450  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
451  * \param coeffs Coefficients of the local solution.
452  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
453  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
454  ************************************************************************************************/
455  template <typename hyEdgeT>
458  hyEdgeT& hyper_edge) const;
459  /*!***********************************************************************************************
460  * \brief Evaluate dual variable at boundary.
461  *
462  * Function to evaluate dual variable of the solution. This function is needed to calculate the
463  * local numerical fluxes.
464  *
465  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
466  * \param coeffs Coefficients of the local solution.
467  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
468  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
469  ************************************************************************************************/
470  template <typename hyEdgeT>
473  hyEdgeT& hyper_edge) const;
474 
475  public:
476  // -----------------------------------------------------------------------------------------------
477  // Public functions (and one typedef) to be utilized by external functions.
478  // -----------------------------------------------------------------------------------------------
479 
480  /*!***********************************************************************************************
481  * \brief Class is constructed using a single double indicating the penalty parameter.
482  ************************************************************************************************/
483  typedef lSol_float_t constructor_value_type;
484  /*!***********************************************************************************************
485  * \brief Constructor for local solver.
486  *
487  * \param tau Penalty parameter of HDG scheme.
488  ************************************************************************************************/
490  /*!***********************************************************************************************
491  * \brief Evaluate local contribution to matrix--vector multiplication.
492  *
493  * Execute matrix--vector multiplication y = A * x, where x represents the vector containing the
494  * skeletal variable (adjacent to one hyperedge), and A is the condensed matrix arising from the
495  * HDG discretization. This function does this multiplication (locally) for one hyperedge. The
496  * hyperedge is no parameter, since all hyperedges are assumed to have the same properties.
497  *
498  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
499  * \tparam SmallMatInT Data type of \c lambda_values_in.
500  * \tparam SmallMatOutT Data type of \c lambda_values_out.
501  * \param lambda_values_in Local part of vector x.
502  * \param lambda_values_out Local part that will be added to A * x.
503  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
504  * \param time Time.
505  * \retval vecAx Local part of vector A * x.
506  ************************************************************************************************/
507  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
508  SmallMatOutT& trace_to_flux(const SmallMatInT& lambda_values_in,
509  SmallMatOutT& lambda_values_out,
510  hyEdgeT& hyper_edge,
511  const lSol_float_t time = 0.) const
512  {
513  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
514  lambda_values_in.size() == 2 * hyEdge_dimT,
515  "Both matrices must be of same size which corresponds to the number of faces!");
516  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
517  hy_assert(
518  lambda_values_in[i].size() == lambda_values_out[i].size() &&
519  lambda_values_in[i].size() == n_glob_dofs_per_node(),
520  "Both matrices must be of same size which corresponds to the number of dofs per face!");
521 
522  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
524  solve_local_problem(lambda_values_in, 0U, hyper_edge, time);
525 
527  primal_at_boundary(coeffs, hyper_edge)),
528  duals(dual_at_boundary(coeffs, hyper_edge));
529 
530  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
531  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
532  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
533  lambda_values_out[i][j] = 0.;
534  else
535  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
536  lambda_values_out[i][j] =
537  duals(i, j) + tau_ * primals(i, j) -
538  tau_ * lambda_values_in[i][j] * hyper_edge.geometry.face_area(i);
539 
540  return lambda_values_out;
541  }
542  /*!***********************************************************************************************
543  * \brief Fill an array with 1 if the node is Dirichlet and 0 otherwise.
544  ************************************************************************************************/
545  template <typename hyEdgeT>
546  std::array<unsigned int, 2 * hyEdge_dimT> node_types(hyEdgeT& hyper_edge) const
547  {
548  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
549 
550  std::array<unsigned int, 2 * hyEdge_dimT> result;
551  result.fill(0);
552 
553  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
554  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
555  result[i] = 1;
556 
557  return result;
558  }
559  /*!***********************************************************************************************
560  * \brief Evaluate local contribution to residual \f$ A x - b \f$.
561  *
562  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
563  * \tparam SmallMatInT Data type of \c lambda_values_in.
564  * \tparam SmallMatOutT Data type of \c lambda_values_out.
565  * \param lambda_values_in Local part of vector x.
566  * \param lambda_values_out Local part that will be added to A * x.
567  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
568  * \param time Time at which analytic functions are evaluated.
569  * \retval vecAx Local part of vector A * x - b.
570  ************************************************************************************************/
571  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
572  SmallMatOutT& residual_flux(const SmallMatInT& lambda_values_in,
573  SmallMatOutT& lambda_values_out,
574  hyEdgeT& hyper_edge,
575  const lSol_float_t time = 0.) const
576  {
577  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
578  lambda_values_in.size() == 2 * hyEdge_dimT,
579  "Both matrices must be of same size which corresponds to the number of faces!");
580  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
581  hy_assert(
582  lambda_values_in[i].size() == lambda_values_out[i].size() &&
583  lambda_values_in[i].size() == n_glob_dofs_per_node(),
584  "Both matrices must be of same size which corresponds to the number of dofs per face!");
585 
586  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
588  solve_local_problem(lambda_values_in, 1U, hyper_edge, time);
589 
591  primal_at_boundary(coeffs, hyper_edge)),
592  duals(dual_at_boundary(coeffs, hyper_edge));
593 
594  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
595  {
596  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
597  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
598  lambda_values_out[i][j] = 0.;
599  else
600  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
601  lambda_values_out[i][j] =
602  duals(i, j) + tau_ * primals(i, j) -
603  tau_ * lambda_values_in[i][j] * hyper_edge.geometry.face_area(i);
604  }
605 
606  return lambda_values_out;
607  }
608  /*!***********************************************************************************************
609  * \brief Evaluate L2 projected lambda values at initial state.
610  *
611  * \note This function is not used for elliptic problems.
612  *
613  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
614  * \tparam SmallMatT Data type of \c lambda_values.
615  * \param lambda_values Local part of vector x.
616  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
617  * \param time Initial time.
618  * \retval lambda_vakues L2 projected lambda ar initial state.
619  ************************************************************************************************/
620  template <typename hyEdgeT, typename SmallMatT>
621  SmallMatT& make_initial(SmallMatT& lambda_values,
622  hyEdgeT& hyper_edge,
623  const lSol_float_t time = 0.) const
624  {
625  hy_assert(lambda_values.size() == 2 * hyEdge_dimT, "Matrix must have appropriate size!");
626  for (unsigned int i = 0; i < lambda_values.size(); ++i)
627  hy_assert(lambda_values[i].size() == n_glob_dofs_per_node(),
628  "Matrix must have appropriate size!");
629 
630  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
631  for (unsigned int i = 0; i < lambda_values.size(); ++i)
632  {
633  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
634  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
635  lambda_values[i][j] = 0.;
636  else
637  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
638  lambda_values[i][j] =
639  integrator ::template integrate_bdrUni_psifunc<decltype(hyEdgeT::geometry),
640  parameters::initial>(
641  j, i, hyper_edge.geometry, time);
642  }
643 
644  return lambda_values;
645  }
646 
647  /*template < class hyEdgeT >
648  std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > trace_to_mass_flux
649  (
650  const std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > & lambda_values,
651  hyEdgeT & hyper_edge,
652  const lSol_float_t time = 0.
653  ) const
654  {
655  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
656 
657  std::array<lSol_float_t, n_loc_dofs_> coeffs
658  = solve_local_problem(lambda_values, 0U, hyper_edge, time);
659  std::array< std::array<lSol_float_t, n_shape_bdr_> , 2 * hyEdge_dimT > bdr_values;
660 
661  SmallVec<n_shape_fct_, lSol_float_t> u_coeffs, test_coeffs;
662  for (unsigned int i = 0; i < n_shape_fct_; ++i)
663  u_coeffs[i] = coeffs[hyEdge_dimT*n_shape_fct_+i];
664 
665  std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > lambda_values_uni;
666  for (unsigned int i = 0; i < lambda_values.size(); ++i) lambda_values_uni[i].fill(0.);
667  for (unsigned int i = 0; i < lambda_values.size(); ++i)
668  if ( is_dirichlet<parameters>(hyper_edge.node_descriptor[i]) )
669  for (unsigned int j = 0; j < lambda_values[i].size(); ++j) bdr_values[i][j] = 0.;
670  else
671  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
672  {
673  lambda_values_uni[i][j] = 1.;
674  coeffs = solve_local_problem(lambda_values_uni, 0U, hyper_edge, time);
675  for (unsigned int k = 0; k < n_shape_fct_; ++k)
676  test_coeffs[k] = coeffs[hyEdge_dimT*n_shape_fct_+k];
677  bdr_values[i][j] = integrator::integrate_vol_phiphi
678  (u_coeffs.data(), test_coeffs.data(), hyper_edge.geometry);
679  lambda_values_uni[i][j] = 0.;
680  }
681 
682  return bdr_values;
683  }
684  template < class hyEdgeT >
685  std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > total_numerical_flux_mass
686  (
687  const std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > & lambda_values,
688  hyEdgeT & hyper_edge,
689  const lSol_float_t time = 0.
690  ) const
691  {
692  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
693 
694  std::array<lSol_float_t, n_loc_dofs_> coeffs
695  = solve_local_problem(lambda_values, 1U, hyper_edge, time);
696  std::array< std::array<lSol_float_t, n_shape_bdr_> , 2 * hyEdge_dimT > bdr_values;
697 
698  SmallVec<n_shape_fct_, lSol_float_t> u_coeffs, test_coeffs;
699  for (unsigned int i = 0; i < n_shape_fct_; ++i)
700  u_coeffs[i] = coeffs[hyEdge_dimT*n_shape_fct_+i];
701 
702  std::array< std::array<lSol_float_t, n_shape_bdr_>, 2*hyEdge_dimT > lambda_values_uni;
703  for (unsigned int i = 0; i < lambda_values.size(); ++i) lambda_values_uni[i].fill(0.);
704  for (unsigned int i = 0; i < lambda_values.size(); ++i)
705  if ( is_dirichlet<parameters>(hyper_edge.node_descriptor[i]) )
706  for (unsigned int j = 0; j < lambda_values[i].size(); ++j) bdr_values[i][j] = 0.;
707  else
708  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
709  {
710  lambda_values_uni[i][j] = 1.;
711  coeffs = solve_local_problem(lambda_values_uni, 0U, hyper_edge, time);
712  for (unsigned int k = 0; k < n_shape_fct_; ++k)
713  test_coeffs[k] = coeffs[hyEdge_dimT*n_shape_fct_+k];
714  bdr_values[i][j] = integrator::integrate_vol_phiphi
715  (u_coeffs.data(), test_coeffs.data(), hyper_edge.geometry);
716  lambda_values_uni[i][j] = 0.;
717  }
718 
719  return bdr_values;
720  }*/
721 
722  /*!***********************************************************************************************
723  * \brief Evaluate local contribution to mass matrix--vector multiplication.
724  *
725  * \note This function is not used for elliptic problems.
726  *
727  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
728  * \tparam SmallMatInT Data type of \c lambda_values_in.
729  * \tparam SmallMatOutT Data type of \c lambda_values_out.
730  * \param lambda_values_in Local part of vector x.
731  * \param lambda_values_out Local part that will be added to A * x-
732  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
733  * \param time Time at which analytic functions are evaluated.
734  * \retval vecAx Local part of vector A * x.
735  ************************************************************************************************/
736  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
737  SmallMatOutT& trace_to_mass_flux(const SmallMatInT& lambda_values_in,
738  SmallMatOutT& lambda_values_out,
739  hyEdgeT& hyper_edge,
740  const lSol_float_t time = 0.) const
741  {
742  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
743  lambda_values_in.size() == 2 * hyEdge_dimT,
744  "Both matrices must be of same size which corresponds to the number of faces!");
745  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
746  hy_assert(
747  lambda_values_in[i].size() == lambda_values_out[i].size() &&
748  lambda_values_in[i].size() == n_glob_dofs_per_node(),
749  "Both matrices must be of same size which corresponds to the number of dofs per face!");
750 
751  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
753  solve_local_problem(lambda_values_in, 0U, hyper_edge, time);
754  coeffs = solve_mass_problem(coeffs, hyper_edge, time);
755 
757  primal_at_boundary(coeffs, hyper_edge)),
758  duals(dual_at_boundary(coeffs, hyper_edge));
759 
760  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
761  {
762  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
763  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
764  lambda_values_out[i][j] = 0.;
765  else
766  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
767  lambda_values_out[i][j] = duals(i, j) + tau_ * primals(i, j);
768  }
769 
770  return lambda_values_out;
771  }
772  /*!***********************************************************************************************
773  * \brief Evaluate local contribution to mass matrix--vector residual.
774  *
775  * \note This function is not used for elliptic problems.
776  *
777  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
778  * \tparam SmallMatInT Data type of \c lambda_values_in.
779  * \tparam SmallMatOutT Data type of \¢ lambda_values_out
780  * \param lambda_values_in Local part of vector x.
781  * \param lambda_values_out Local part that will be added to A * x.
782  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
783  * \param time Time.
784  * \retval vecAx Local part of mass matrix residual.
785  ************************************************************************************************/
786  template <typename hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
787  SmallMatOutT& total_numerical_flux_mass(const SmallMatInT& lambda_values_in,
788  SmallMatOutT& lambda_values_out,
789  hyEdgeT& hyper_edge,
790  const lSol_float_t time = 0.) const
791  {
792  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
793  lambda_values_in.size() == 2 * hyEdge_dimT,
794  "Both matrices must be of same size which corresponds to the number of faces!");
795  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
796  hy_assert(
797  lambda_values_in[i].size() == lambda_values_out[i].size() &&
798  lambda_values_in[i].size() == n_glob_dofs_per_node(),
799  "Both matrices must be of same size which corresponds to the number of dofs per face!");
800 
801  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
803  solve_local_problem(lambda_values_in, 1U, hyper_edge, time);
804  coeffs = solve_mass_problem(coeffs, hyper_edge, time);
805 
807  primal_at_boundary(coeffs, hyper_edge)),
808  duals(dual_at_boundary(coeffs, hyper_edge));
809 
810  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
811  {
812  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
813  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
814  lambda_values_out[i][j] = 0.;
815  else
816  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
817  lambda_values_out[i][j] = duals(i, j) + tau_ * primals(i, j);
818  }
819 
820  return lambda_values_out;
821  }
822  /*!***********************************************************************************************
823  * \brief Calculate squared local contribution of L2 error.
824  *
825  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
826  * \tparam SmallMatT Data type of \c lambda_values.
827  * \param lambda_values The values of the skeletal variable's coefficients.
828  * \param hy_edge The geometry of the considered hyperedge (of typename GeomT).
829  * \param time Time at which anaytic functions are evaluated.
830  * \retval vec_b Local part of vector b.
831  ************************************************************************************************/
832  template <typename hyEdgeT, typename SmallMatT>
833  std::array<lSol_float_t, 1U> errors(const SmallMatT& lambda_values,
834  hyEdgeT& hy_edge,
835  const lSol_float_t time = 0.) const
836  {
837  hy_assert(lambda_values.size() == 2 * hyEdge_dimT, "Matrix must have appropriate size!");
838  for (unsigned int i = 0; i < lambda_values.size(); ++i)
839  hy_assert(lambda_values[i].size() == n_glob_dofs_per_node(),
840  "Matrix must have appropriate size!");
841 
842  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
844  solve_local_problem(lambda_values, 1U, hy_edge, time);
845  std::array<lSol_float_t, n_shape_fct_> coeffs;
846  for (unsigned int i = 0; i < coeffs.size(); ++i)
847  coeffs[i] = coefficients[i + hyEdge_dimT * n_shape_fct_];
848  return std::array<lSol_float_t, 1U>({integrator::template integrate_vol_diffsquare_discana<
849  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
850  parameters::analytic_result, Point<hyEdge_dimT, lSol_float_t> >(coeffs, hy_edge.geometry,
851  time)});
852  }
853  /*!***********************************************************************************************
854  * \brief Parabolic approximation version of local squared L2 error.
855  *
856  * \note This function is not used for elliptic problems.
857  *
858  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
859  * \tparam SmallMatT Data type of \c lambda_values.
860  * \param lambda_values_new Abscissas of the supporting points.
861  * \param lambda_values_old The values of the skeletal variable's coefficients.
862  * \param hy_edge The geometry of the considered hyperedge (of typename GeomT).
863  * \param delta_t Time step size.
864  * \param time Time.
865  * \retval vec_b Local part of vector b.
866  ************************************************************************************************/
867  template <typename hyEdgeT, typename SmallMatT>
868  lSol_float_t errors_temp(const SmallMatT& lambda_values_new,
869  const SmallMatT& lambda_values_old,
870  hyEdgeT& hy_edge,
871  const lSol_float_t delta_t,
872  const lSol_float_t time) const
873  {
874  hy_assert(lambda_values_new.size() == lambda_values_old.size() &&
875  lambda_values_new.size() == 2 * hyEdge_dimT,
876  "Both matrices must be of same size which corresponds to the number of faces!");
877  for (unsigned int i = 0; i < lambda_values_new.size(); ++i)
878  hy_assert(
879  lambda_values_new[i].size() == lambda_values_old[i].size() &&
880  lambda_values_new[i].size() == n_glob_dofs_per_node(),
881  "Both matrices must be of same size which corresponds to the number of dofs per face!");
882 
883  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
884 
886  solve_local_problem(lambda_values_new, 1U, hy_edge, time);
888  solve_local_problem(lambda_values_old, 1U, hy_edge, time - delta_t);
889  for (unsigned int i = 0; i < coeffs_old.size(); ++i)
890  coeffs_old[i] = (coeffs_old[i] - coeffs_new[i]) / delta_t;
891 
893  solve_loc_prob_cor(lambda_values_new, coeffs_old, hy_edge, delta_t, time);
894  std::array<lSol_float_t, n_shape_fct_> coeffs;
895  for (unsigned int i = 0; i < coeffs.size(); ++i)
896  coeffs[i] = coefficients[i + hyEdge_dimT * n_shape_fct_];
897  return integrator::template integrate_vol_diffsquare_discana<decltype(hyEdgeT::geometry),
898  parameters::analytic_result>(
899  coeffs, hy_edge.geometry, time);
900  }
901  /*!***********************************************************************************************
902  * \brief Evaluate local reconstruction at tensorial products of abscissas.
903  *
904  * \tparam absc_float_t Floating type for the abscissa values.
905  * \tparam abscissas_sizeT Size of the array of array of abscissas.
906  * \tparam input_array_t Type of input array.
907  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
908  * \param abscissas Abscissas of the supporting points.
909  * \param lambda_values The values of the skeletal variable's coefficients.
910  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
911  * \param time Time at which analytic functions are evaluated.
912  * \retval function_values Function values at quadrature points.
913  ************************************************************************************************/
914  template <typename abscissa_float_t,
915  std::size_t abscissas_sizeT,
916  class input_array_t,
917  class hyEdgeT>
918  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>, system_dim>
919  bulk_values(const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
920  const input_array_t& lambda_values,
921  hyEdgeT& hyper_edge,
922  const lSol_float_t time = 0.) const;
923 }; // end of class DiffusionAdvectionReaction
924 
925 // -------------------------------------------------------------------------------------------------
927 // -------------------------------------------------------------------------------------------------
928 
929 // -------------------------------------------------------------------------------------------------
930 // -------------------------------------------------------------------------------------------------
931 //
932 // IMPLEMENTATION OF MEMBER FUNCTIONS OF DiffusionAdvectionReaction
933 //
934 // -------------------------------------------------------------------------------------------------
935 // -------------------------------------------------------------------------------------------------
936 
937 // -------------------------------------------------------------------------------------------------
938 // assemble_loc_matrix
939 // -------------------------------------------------------------------------------------------------
940 
941 template <unsigned int hyEdge_dimT,
942  unsigned int poly_deg,
943  unsigned int quad_deg,
944  template <unsigned int, typename>
945  typename parametersT,
946  typename lSol_float_t>
947 template <typename hyEdgeT>
948 inline SmallSquareMat<
949  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
950  n_loc_dofs_,
951  lSol_float_t>
953  assemble_loc_matrix(const lSol_float_t tau, hyEdgeT& hyper_edge, const lSol_float_t time) const
954 {
955  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
957  lSol_float_t vol_integral, face_integral, helper;
958  SmallVec<hyEdge_dimT, lSol_float_t> grad_int_vec, normal_int_vec;
959 
960  for (unsigned int i = 0; i < n_shape_fct_; ++i)
961  {
962  for (unsigned int j = 0; j < n_shape_fct_; ++j)
963  {
964  // Integral_element phi_i phi_j dx in diagonal blocks
965  vol_integral = integrator::template integrate_vol_phiphifunc<
966  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
967  parameters::inverse_diffusion_coeff, Point<hyEdge_dimT, lSol_float_t> >(
968  i, j, hyper_edge.geometry, time);
969  // Integral_element - nabla phi_i \vec phi_j dx
970  // = Integral_element - div \vec phi_i phi_j dx in right upper and left lower blocks
971  grad_int_vec =
972  integrator::template integrate_vol_nablaphiphi<SmallVec<hyEdge_dimT, lSol_float_t>,
973  decltype(hyEdgeT::geometry)>(
974  i, j, hyper_edge.geometry);
975 
976  face_integral = 0.;
977  normal_int_vec = 0.;
978  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
979  {
980  helper = integrator::template integrate_bdr_phiphi<decltype(hyEdgeT::geometry)>(
981  i, j, face, hyper_edge.geometry);
982  face_integral += helper;
983  normal_int_vec += helper * hyper_edge.geometry.local_normal(face);
984  }
985 
986  local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) +=
987  tau * face_integral + integrator::template integrate_vol_phiphifunc<
988  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>,
989  decltype(hyEdgeT::geometry), parameters::reaction_rate,
990  Point<hyEdge_dimT, lSol_float_t> >(i, j, hyper_edge.geometry, time);
991  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
992  {
993  local_mat(dim * n_shape_fct_ + i, dim * n_shape_fct_ + j) += vol_integral;
994  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= grad_int_vec[dim];
995  local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -= grad_int_vec[dim];
996  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) += normal_int_vec[dim];
997  local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -=
998  integrator::template integrate_vol_phiphivecfunc<
999  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>,
1000  decltype(hyEdgeT::geometry), parameters::advective_velocity,
1001  Point<hyEdge_dimT, lSol_float_t> >(i, j, dim, hyper_edge.geometry);
1002  }
1003  }
1004  }
1005 
1006  return local_mat;
1007 } // end of DiffusionAdvectionReaction::assemble_loc_matrix
1008 
1009 // -------------------------------------------------------------------------------------------------
1010 // assemble_rhs_from_lambda
1011 // -------------------------------------------------------------------------------------------------
1012 
1013 template <unsigned int hyEdge_dimT,
1014  unsigned int poly_deg,
1015  unsigned int quad_deg,
1016  template <unsigned int, typename>
1017  typename parametersT,
1018  typename lSol_float_t>
1019 template <typename hyEdgeT, typename SmallMatT>
1020 inline SmallVec<
1021  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1022  n_loc_dofs_,
1023  lSol_float_t>
1025  assemble_rhs_from_lambda(const SmallMatT& lambda_values, hyEdgeT& hyper_edge) const
1026 {
1027  static_assert(std::is_same<typename SmallMatT::value_type::value_type, lSol_float_t>::value,
1028  "Lambda values should have same floating point arithmetics as local solver!");
1029  hy_assert(lambda_values.size() == 2 * hyEdge_dimT,
1030  "The size of the lambda values should be twice the dimension of a hyperedge.");
1031  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
1032  hy_assert(lambda_values[i].size() == n_shape_bdr_,
1033  "The size of lambda should be the amount of ansatz functions at boundary.");
1034 
1035  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
1036  lSol_float_t integral;
1037 
1038  for (unsigned int i = 0; i < n_shape_fct_; ++i)
1039  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
1040  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
1041  {
1042  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
1043  i, j, face, hyper_edge.geometry);
1044  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] += tau_ * lambda_values[face][j] * integral;
1045  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
1046  right_hand_side[dim * n_shape_fct_ + i] -=
1047  hyper_edge.geometry.local_normal(face).operator[](dim) * lambda_values[face][j] *
1048  integral;
1049  }
1050 
1051  return right_hand_side;
1052 } // end of DiffusionAdvectionReaction::assemble_rhs_from_lambda
1053 
1054 // -------------------------------------------------------------------------------------------------
1055 // assemble_rhs_from_global_rhs
1056 // -------------------------------------------------------------------------------------------------
1057 
1058 template <unsigned int hyEdge_dimT,
1059  unsigned int poly_deg,
1060  unsigned int quad_deg,
1061  template <unsigned int, typename>
1062  typename parametersT,
1063  typename lSol_float_t>
1064 template <typename hyEdgeT>
1065 inline SmallVec<
1066  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1067  n_loc_dofs_,
1068  lSol_float_t>
1070  assemble_rhs_from_global_rhs(hyEdgeT& hyper_edge, const lSol_float_t time) const
1071 {
1072  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
1073  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
1074  lSol_float_t integral;
1075  for (unsigned int i = 0; i < n_shape_fct_; ++i)
1076  {
1077  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] = integrator::template integrate_vol_phifunc<
1078  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
1079  parameters::right_hand_side, Point<hyEdge_dimT, lSol_float_t> >(i, hyper_edge.geometry, time);
1080  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
1081  {
1082  if (!is_dirichlet<parameters>(hyper_edge.node_descriptor[face]))
1083  continue;
1084  integral = integrator::template integrate_bdr_phifunc<
1085  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
1086  parameters::dirichlet_value, Point<hyEdge_dimT, lSol_float_t> >(i, face,
1087  hyper_edge.geometry, time);
1088  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] += tau_ * integral;
1089  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
1090  right_hand_side[dim * n_shape_fct_ + i] -=
1091  hyper_edge.geometry.local_normal(face).operator[](dim) * integral;
1092  }
1093  }
1094 
1095  return right_hand_side;
1096 } // end of DiffusionAdvectionReaction::assemble_rhs_from_global_rhs
1097 
1098 // -------------------------------------------------------------------------------------------------
1099 // assemble_rhs_from_coeffs
1100 // -------------------------------------------------------------------------------------------------
1101 
1102 template <unsigned int hyEdge_dimT,
1103  unsigned int poly_deg,
1104  unsigned int quad_deg,
1105  template <unsigned int, typename>
1106  typename parametersT,
1107  typename lSol_float_t>
1108 template <typename hyEdgeT, typename SmallVecT>
1109 inline SmallVec<
1110  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1111  n_loc_dofs_,
1112  lSol_float_t>
1114  assemble_rhs_from_coeffs(const SmallVecT& coeffs, hyEdgeT& hyper_edge) const
1115 {
1116  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
1117  for (unsigned int i = 0; i < n_shape_fct_; ++i)
1118  for (unsigned int j = 0; j < n_shape_fct_; ++j)
1119  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] +=
1120  coeffs[hyEdge_dimT * n_shape_fct_ + j] *
1121  integrator::template integrate_vol_phiphi(i, j, hyper_edge.geometry);
1122 
1123  return right_hand_side;
1124 } // end of DiffusionAdvectionReaction::assemble_rhs_from_coeffs
1125 
1126 // -------------------------------------------------------------------------------------------------
1127 // primal_at_boundary
1128 // -------------------------------------------------------------------------------------------------
1129 
1130 template <unsigned int hyEdge_dimT,
1131  unsigned int poly_deg,
1132  unsigned int quad_deg,
1133  template <unsigned int, typename>
1134  typename parametersT,
1135  typename lSol_float_t>
1136 template <typename hyEdgeT>
1137 inline SmallMat<
1138  2 * hyEdge_dimT,
1139  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1140  n_shape_bdr_,
1141  lSol_float_t>
1143  primal_at_boundary(const SmallVec<n_loc_dofs_, lSol_float_t>& coeffs, hyEdgeT& hyper_edge) const
1144 {
1146 
1147  for (unsigned int i = 0; i < n_shape_fct_; ++i)
1148  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
1149  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
1150  bdr_values(face, j) +=
1151  coeffs[hyEdge_dimT * n_shape_fct_ + i] *
1152  integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
1153  i, j, face, hyper_edge.geometry);
1154 
1155  return bdr_values;
1156 } // end of DiffusionAdvectionReaction::primal_at_boundary
1157 
1158 // -------------------------------------------------------------------------------------------------
1159 // dual_at_boundary
1160 // -------------------------------------------------------------------------------------------------
1161 
1162 template <unsigned int hyEdge_dimT,
1163  unsigned int poly_deg,
1164  unsigned int quad_deg,
1165  template <unsigned int, typename>
1166  typename parametersT,
1167  typename lSol_float_t>
1168 template <typename hyEdgeT>
1169 inline SmallMat<
1170  2 * hyEdge_dimT,
1171  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1172  n_shape_bdr_,
1173  lSol_float_t>
1175  dual_at_boundary(const SmallVec<n_loc_dofs_, lSol_float_t>& coeffs, hyEdgeT& hyper_edge) const
1176 {
1178  lSol_float_t integral;
1179 
1180  for (unsigned int i = 0; i < n_shape_fct_; ++i)
1181  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
1182  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
1183  {
1184  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
1185  i, j, face, hyper_edge.geometry);
1186  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
1187  bdr_values(face, j) += hyper_edge.geometry.local_normal(face).operator[](dim) * integral *
1188  coeffs[dim * n_shape_fct_ + i];
1189  }
1190 
1191  return bdr_values;
1192 } // end of DiffusionAdvectionReaction::dual_at_boundary
1193 
1194 // -------------------------------------------------------------------------------------------------
1195 // bulk_values
1196 // -------------------------------------------------------------------------------------------------
1197 
1198 template <unsigned int hyEdge_dimT,
1199  unsigned int poly_deg,
1200  unsigned int quad_deg,
1201  template <unsigned int, typename>
1202  typename parametersT,
1203  typename lSol_float_t>
1204 template <typename abscissa_float_t,
1205  std::size_t abscissas_sizeT,
1206  class input_array_t,
1207  typename hyEdgeT>
1208 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
1209  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT, lSol_float_t>::
1210  system_dim>
1212  const std::array<abscissa_float_t, abscissas_sizeT>& abscissas,
1213  const input_array_t& lambda_values,
1214  hyEdgeT& hyper_edge,
1215  const lSol_float_t time) const
1216 {
1218  solve_local_problem(lambda_values, 1U, hyper_edge, time);
1220  SmallVec<static_cast<unsigned int>(abscissas_sizeT), abscissa_float_t> helper(abscissas);
1221 
1222  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(abscissas_sizeT)>,
1223  DiffusionAdvectionReaction<hyEdge_dimT, poly_deg, quad_deg, parametersT,
1224  lSol_float_t>::system_dim>
1225  point_vals;
1226 
1227  for (unsigned int d = 0; d < system_dim; ++d)
1228  {
1229  for (unsigned int i = 0; i < coeffs.size(); ++i)
1230  coeffs[i] = coefficients[d * n_shape_fct_ + i];
1231  for (unsigned int pt = 0; pt < Hypercube<hyEdge_dimT>::pow(abscissas_sizeT); ++pt)
1232  point_vals[d][pt] = integrator::shape_fun_t::template lin_comb_fct_val<float>(
1233  coeffs, Hypercube<hyEdge_dimT>::template tensorial_pt<Point<hyEdge_dimT> >(pt, helper));
1234  }
1235 
1236  return point_vals;
1237 }
1238 // end of DiffusionAdvectionReaction::bulk_values
1239 
1240 // -------------------------------------------------------------------------------------------------
1242 // -------------------------------------------------------------------------------------------------
1243 
1244 } // namespace LocalSolver
shape_function.hxx
LocalSolver::DiffusionAdvectionReaction::n_shape_fct_
static constexpr unsigned int n_shape_fct_
Number of local shape functions (with respect to all spatial dimensions).
Definition: diffusion_advection_reaction_ldg.hxx:220
LocalSolver::DiffusionAdvectionReaction::node_element::functions
std::tuple< TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg >, hyEdge_dimT - 1 > > > functions
Definition: diffusion_advection_reaction_ldg.hxx:143
LocalSolver::DiffusionAdvectionReaction::tau_
const lSol_float_t tau_
(Globally constant) penalty parameter for HDG scheme.
Definition: diffusion_advection_reaction_ldg.hxx:258
LocalSolver::DiffusionAdvectionReactionParametersDefault::dirichlet_nodes
static constexpr std::array< unsigned int, 0U > dirichlet_nodes
Array containing hypernode types corresponding to Dirichlet boundary.
Definition: diffusion_advection_reaction_ldg.hxx:25
LocalSolver::DiffusionAdvectionReactionParametersDefault::right_hand_side
static param_float_t right_hand_side(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Right-hand side in PDE as analytic function.
Definition: diffusion_advection_reaction_ldg.hxx:58
LocalSolver::DiffusionAdvectionReaction::n_shape_bdr_
static constexpr unsigned int n_shape_bdr_
Number oflocal shape functions (with respect to a face / hypernode).
Definition: diffusion_advection_reaction_ldg.hxx:224
LocalSolver::DiffusionAdvectionReaction::data_type
Define type of (hyperedge related) data that is stored in HyDataContainer.
Definition: diffusion_advection_reaction_ldg.hxx:133
LocalSolver::DiffusionAdvectionReaction::error_def::initial_error
static error_t initial_error()
Define how initial error is generated.
Definition: diffusion_advection_reaction_ldg.hxx:157
LocalSolver::DiffusionAdvectionReaction::system_dim
static constexpr unsigned int system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_advection_reaction_ldg.hxx:234
LocalSolver::DiffusionAdvectionReaction::DiffusionAdvectionReaction
DiffusionAdvectionReaction(const constructor_value_type &tau=1.)
Constructor for local solver.
Definition: diffusion_advection_reaction_ldg.hxx:489
Wrapper::LAPACKexception::what
const char * what() const
Definition: lapack.hxx:27
LocalSolver::DiffusionAdvectionReaction::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::DiffusionAdvectionReaction::solve_mass_problem
SmallVec< n_loc_dofs_, lSol_float_t > solve_mass_problem(const SmallMatT &lambda_values, hyEdgeT &hyper_edge, const lSol_float_t time) const
Solve local problem for mass matrix approximation.
Definition: diffusion_advection_reaction_ldg.hxx:401
LocalSolver
A namespace for local solvers.
Definition: advection_parab_ldgh.hxx:11
tensorial.hxx
diffusion_uniform.geometry
geometry
Definition: diffusion_uniform.py:19
LocalSolver::DiffusionAdvectionReaction::errors_temp
lSol_float_t errors_temp(const SmallMatT &lambda_values_new, const SmallMatT &lambda_values_old, hyEdgeT &hy_edge, const lSol_float_t delta_t, const lSol_float_t time) const
Parabolic approximation version of local squared L2 error.
Definition: diffusion_advection_reaction_ldg.hxx:868
LocalSolver::DiffusionAdvectionReactionParametersDefault::analytic_result
static param_float_t analytic_result(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Analytic result of PDE (for convergence tests).
Definition: diffusion_advection_reaction_ldg.hxx:82
LocalSolver::DiffusionAdvectionReactionParametersDefault::neumann_nodes
static constexpr std::array< unsigned int, 0U > neumann_nodes
Array containing hypernode types corresponding to Neumann boundary.
Definition: diffusion_advection_reaction_ldg.hxx:29
LocalSolver::DiffusionAdvectionReaction::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::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:199
LocalSolver::DiffusionAdvectionReaction::node_element
Define type of node elements, especially with respect to nodal shape functions.
Definition: diffusion_advection_reaction_ldg.hxx:139
LocalSolver::DiffusionAdvectionReaction::system_dimension
static constexpr unsigned int system_dimension()
Dimension of of the solution evaluated with respect to a hyperedge.
Definition: diffusion_advection_reaction_ldg.hxx:206
LocalSolver::DiffusionAdvectionReaction::n_loc_dofs_
static constexpr unsigned int n_loc_dofs_
Number of (local) degrees of freedom per hyperedge.
Definition: diffusion_advection_reaction_ldg.hxx:228
LocalSolver::DiffusionAdvectionReactionParametersDefault::dirichlet_value
static param_float_t dirichlet_value(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Dirichlet values of solution as analytic function.
Definition: diffusion_advection_reaction_ldg.hxx:66
LocalSolver::DiffusionAdvectionReaction::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::DiffusionAdvectionReaction
Local solver diffusion equation on hypergraph.
Definition: diffusion_advection_reaction_ldg.hxx:127
LocalSolver::DiffusionAdvectionReaction::total_numerical_flux_mass
SmallMatOutT & total_numerical_flux_mass(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate local contribution to mass matrix–vector residual.
Definition: diffusion_advection_reaction_ldg.hxx:787
LocalSolver::DiffusionAdvectionReaction::node_system_dimension
static constexpr unsigned int node_system_dimension()
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_advection_reaction_ldg.hxx:210
LocalSolver::DiffusionAdvectionReaction::error_def::postprocess_error
static error_t postprocess_error(error_t &summed_error)
Define how global errors should be postprocessed.
Definition: diffusion_advection_reaction_ldg.hxx:175
LocalSolver::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:166
LocalSolver::DiffusionAdvectionReactionParametersDefault::reaction_rate
static param_float_t reaction_rate(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
The reaction rate for the PDE.
Definition: diffusion_advection_reaction_ldg.hxx:50
LocalSolver::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:364
TPP::Quadrature::GaussLegendre
Gauss–Legendre quadrature points and weights in one spatial dimension.
Definition: one_dimensional.hxx:19
LocalSolver::DiffusionAdvectionReaction::hyEdge_dim
static constexpr unsigned int hyEdge_dim()
Dimension of hyper edge type that this object solves on.
Definition: diffusion_advection_reaction_ldg.hxx:190
SmallMat::size
static constexpr unsigned int size()
Return size a SmallMat.
Definition: dense_la.hxx:54
LocalSolver::DiffusionAdvectionReactionParametersDefault::inverse_diffusion_coeff
static param_float_t inverse_diffusion_coeff(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Inverse diffusion coefficient in PDE as analytic function.
Definition: diffusion_advection_reaction_ldg.hxx:33
TPP::ShapeType::Tensorial
Struct that handles the evaluation of tensorial shape functions.
Definition: tensorial.hxx:22
LocalSolver::DiffusionAdvectionReaction::make_initial
SmallMatT & make_initial(SmallMatT &lambda_values, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate L2 projected lambda values at initial state.
Definition: diffusion_advection_reaction_ldg.hxx:621
LocalSolver::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:508
LocalSolver::DiffusionAdvectionReaction::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 L2 error.
Definition: diffusion_advection_reaction_ldg.hxx:833
LocalSolver::DiffusionAdvectionReaction::trace_to_mass_flux
SmallMatOutT & trace_to_mass_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate local contribution to mass matrix–vector multiplication.
Definition: diffusion_advection_reaction_ldg.hxx:737
LocalSolver::DiffusionAdvectionReaction::assemble_loc_matrix
SmallSquareMat< n_loc_dofs_, lSol_float_t > assemble_loc_matrix(const lSol_float_t tau, hyEdgeT &hyper_edge, const lSol_float_t time) const
Assemble local matrix for the local solver.
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::DiffusionAdvectionReaction::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 local reconstruction at tensorial products of abscissas.
LocalSolver::DiffusionAdvectionReaction::node_system_dim
static constexpr unsigned int node_system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: diffusion_advection_reaction_ldg.hxx:240
LocalSolver::DiffusionAdvectionReaction::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::DiffusionAdvectionReaction::error_def::error_t
std::array< lSol_float_t, 1U > error_t
Define the typename returned by function errors.
Definition: diffusion_advection_reaction_ldg.hxx:153
LocalSolver::DiffusionAdvectionReactionParametersDefault::neumann_value
static param_float_t neumann_value(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Neumann values of solution as analytic function.
Definition: diffusion_advection_reaction_ldg.hxx:74
hypercube.hxx
Wrapper::LAPACKexception
Exception to be thrown if LAPACK's solve fails.
Definition: lapack.hxx:25
LocalSolver::DiffusionAdvectionReactionParametersDefault
Default parameters for the diffusion equation, cf. below.
Definition: diffusion_advection_reaction_ldg.hxx:20
Hypercube::pow
static constexpr unsigned int pow(unsigned int base)
Return n to the power dim.
Definition: hypercube.hxx:25
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
LocalSolver::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:266
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::DiffusionAdvectionReaction::solve_loc_prob_cor
SmallVec< n_loc_dofs_, lSol_float_t > solve_loc_prob_cor(const SmallMatT &lambda_values, const SmallVecT &coeffs, hyEdgeT &hyper_edge, const lSol_float_t delta_time, const lSol_float_t time) const
Solve local problem for parabolic approximations.
Definition: diffusion_advection_reaction_ldg.hxx:423
dense_la.hxx
LocalSolver::DiffusionAdvectionReaction::is_dirichlet
static constexpr bool is_dirichlet(const unsigned int node_type)
Find out whether a node is of Dirichlet type.
Definition: diffusion_advection_reaction_ldg.hxx:245
LocalSolver::DiffusionAdvectionReactionParametersDefault::advective_velocity
static SmallVec< space_dimT, param_float_t > advective_velocity(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
The velocity of the advective part of the equation over the diffusion coefficient.
Definition: diffusion_advection_reaction_ldg.hxx:41
LocalSolver::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:546
LocalSolver::DiffusionAdvectionReaction::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::DiffusionAdvectionReaction::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_advection_reaction_ldg.hxx:572
LocalSolver::DiffusionAdvectionReaction::constructor_value_type
lSol_float_t constructor_value_type
Class is constructed using a single double indicating the penalty parameter.
Definition: diffusion_advection_reaction_ldg.hxx:483
LocalSolver::DiffusionAdvectionReaction::error_def
Define how errors are evaluated.
Definition: diffusion_advection_reaction_ldg.hxx:148
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34
Hypercube
Helper class containing numbers and functions related to hypercubes.
Definition: hypercube.hxx:12