HyperHDG
bilaplacian_eigs_ldgh.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
3 #include <HyperHDG/dense_la.hxx>
4 #include <HyperHDG/hypercube.hxx>
7 
8 #include <algorithm>
9 #include <tuple>
10 
11 namespace LocalSolver
12 {
13 /*!*************************************************************************************************
14  * \brief 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 Dirichlet boundary of Laplacian.
28  ************************************************************************************************/
29  static constexpr std::array<unsigned int, 0U> dirichlet_laplacian_nodes{};
30  /*!***********************************************************************************************
31  * \brief Array containing hypernode types corresponding to Neumann boundary.
32  ************************************************************************************************/
33  static constexpr std::array<unsigned int, 0U> neumann_nodes{};
34  /*!***********************************************************************************************
35  * \brief Array containing hypernode types corresponding to Neumann boundary of Laplacian.
36  ************************************************************************************************/
37  static constexpr std::array<unsigned int, 0U> neumann_laplacian_nodes{};
38  /*!***********************************************************************************************
39  * \brief Inverse bilaplacian coefficient in PDE as analytic function.
40  ************************************************************************************************/
42  const param_float_t = 0.)
43  {
44  return 1.;
45  }
46  /*!***********************************************************************************************
47  * \brief Right-hand side in PDE as analytic function.
48  ************************************************************************************************/
50  const param_float_t = 0.)
51  {
52  return 0.;
53  }
54  /*!***********************************************************************************************
55  * \brief Dirichlet values of solution as analytic function.
56  ************************************************************************************************/
58  const param_float_t = 0.)
59  {
60  return 0.;
61  }
62  /*!***********************************************************************************************
63  * \brief Dirichlet values of solution's Laplacian as analytic function.
64  ************************************************************************************************/
66  const param_float_t = 0.)
67  {
68  return 0.;
69  }
70  /*!***********************************************************************************************
71  * \brief Neumann values of solution as analytic function.
72  ************************************************************************************************/
73  static param_float_t neumann_value(const Point<space_dimT, param_float_t>&,
74  const param_float_t = 0.)
75  {
76  return 0.;
77  }
78  /*!***********************************************************************************************
79  * \brief Neumann values of solution's Laplacian as analytic function.
80  ************************************************************************************************/
82  const param_float_t = 0.)
83  {
84  return 0.;
85  }
86  /*!***********************************************************************************************
87  * \brief Analytic result of PDE (for convergence tests).
88  ************************************************************************************************/
90  const param_float_t = 0.)
91  {
92  return 0.;
93  }
94 }; // end of struct Bilaplacian_parameters_default
95 
96 /*!*************************************************************************************************
97  * \brief Local solver for bilaplacian equation on uniform hypergraph.
98  *
99  * \tparam hyEdge_dimT Dimension of a hyperedge, i.e., 1 is for PDEs defined on graphs, 2 is for
100  * PDEs defined on surfaces, and 3 is for PDEs defined on volumes.
101  * \tparam space_dimT The dimension of the surrounding space.
102  * \tparam poly_deg The polynomial degree of test and trial functions.
103  * \tparam quad_deg The order of the quadrature rule.
104  * \tparam parametersT Struct depending on templates \c space_dimTP and \c lSol_float_TP that
105  * contains static parameter functions.
106  * Defaults to above functions included in \c DiffusionParametersDefault.
107  * \tparam lSol_float_t The floating point type calculations are executed in. Defaults to double.
108  *
109  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
110  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
111  **************************************************************************************************/
112 template <unsigned int hyEdge_dimT,
113  unsigned int poly_deg,
114  unsigned int quad_deg,
115  template <unsigned int, typename>
116  typename parametersT,
117  typename lSol_float_t = double>
119 {
120  public:
121  /*!***********************************************************************************************
122  * \brief Define type of (hyperedge related) data that is stored in HyDataContainer.
123  ************************************************************************************************/
124  struct data_type
125  {
126  };
127  /*!***********************************************************************************************
128  * \brief Define type of node elements, especially with respect to nodal shape functions.
129  ************************************************************************************************/
131  {
132  typedef std::tuple<TPP::ShapeFunction<
135  };
136  /*!***********************************************************************************************
137  * \brief Define how errors are evaluated.
138  ************************************************************************************************/
139  struct error_def
140  {
141  /*!*********************************************************************************************
142  * \brief Define the typename returned by function errors.
143  **********************************************************************************************/
144  typedef std::array<lSol_float_t, 1U> error_t;
145  /*!*********************************************************************************************
146  * \brief Define how initial error is generated.
147  **********************************************************************************************/
149  {
150  std::array<lSol_float_t, 1U> summed_error;
151  summed_error.fill(0.);
152  return summed_error;
153  }
154  /*!*********************************************************************************************
155  * \brief Define how local errors should be accumulated.
156  **********************************************************************************************/
157  static error_t sum_error(error_t& summed_error, const error_t& new_error)
158  {
159  for (unsigned int k = 0; k < summed_error.size(); ++k)
160  summed_error[k] += new_error[k];
161  return summed_error;
162  }
163  /*!*********************************************************************************************
164  * \brief Define how global errors should be postprocessed.
165  **********************************************************************************************/
166  static error_t postprocess_error(error_t& summed_error)
167  {
168  for (unsigned int k = 0; k < summed_error.size(); ++k)
169  summed_error[k] = std::sqrt(summed_error[k]);
170  return summed_error;
171  }
172  };
173 
174  // -----------------------------------------------------------------------------------------------
175  // Public, static constexpr functions
176  // -----------------------------------------------------------------------------------------------
177 
178  /*!***********************************************************************************************
179  * \brief Dimension of hyper edge type that this object solves on.
180  ************************************************************************************************/
181  static constexpr unsigned int hyEdge_dim() { return hyEdge_dimT; }
182  /*!***********************************************************************************************
183  * \brief Evaluate amount of global degrees of freedom per hypernode.
184  *
185  * This number must be equal to HyperNodeFactory::n_dofs_per_node() of the HyperNodeFactory
186  * cooperating with this object.
187  *
188  * \retval n_dofs Number of global degrees of freedom per hypernode.
189  ************************************************************************************************/
190  static constexpr unsigned int n_glob_dofs_per_node()
191  {
192  return 2 * Hypercube<hyEdge_dimT - 1>::pow(poly_deg + 1);
193  }
194  /*!***********************************************************************************************
195  * \brief Dimension of of the solution evaluated with respect to a hyperedge.
196  ************************************************************************************************/
197  static constexpr unsigned int system_dimension() { return hyEdge_dimT + 1; }
198  /*!***********************************************************************************************
199  * \brief Dimension of of the solution evaluated with respect to a hypernode.
200  ************************************************************************************************/
201  static constexpr unsigned int node_system_dimension() { return 1; }
202 
203  private:
204  // -----------------------------------------------------------------------------------------------
205  // Private, static constexpr functions
206  // -----------------------------------------------------------------------------------------------
207 
208  /*!***********************************************************************************************
209  * \brief Number of local shape functions (with respect to all spatial dimensions).
210  ************************************************************************************************/
211  static constexpr unsigned int n_shape_fct_ = n_glob_dofs_per_node() * (poly_deg + 1) / 2;
212  /*!***********************************************************************************************
213  * \brief Number oflocal shape functions (with respect to a face / hypernode).
214  ************************************************************************************************/
215  static constexpr unsigned int n_shape_bdr_ = n_glob_dofs_per_node() / 2;
216  /*!***********************************************************************************************
217  * \brief Number of (local) degrees of freedom per hyperedge.
218  ************************************************************************************************/
219  static constexpr unsigned int n_loc_dofs_ = 2 * (hyEdge_dimT + 1) * n_shape_fct_;
220  /*!***********************************************************************************************
221  * \brief Dimension of of the solution evaluated with respect to a hypernode.
222  *
223  * This allows to the use of this quantity as template parameter in member functions.
224  ************************************************************************************************/
225  static constexpr unsigned int system_dim = system_dimension();
226  /*!***********************************************************************************************
227  * \brief Dimension of of the solution evaluated with respect to a hypernode.
228  *
229  * This allows to the use of this quantity as template parameter in member functions.
230  ************************************************************************************************/
231  static constexpr unsigned int node_system_dim = node_system_dimension();
232  /*!***********************************************************************************************
233  * \brief Find out whether a node is of Dirichlet type.
234  ************************************************************************************************/
235  template <typename parameters>
236  static constexpr bool is_dirichlet(const unsigned int node_type)
237  {
238  return std::find(parameters::dirichlet_nodes.begin(), parameters::dirichlet_nodes.end(),
239  node_type) != parameters::dirichlet_nodes.end();
240  }
241  template <typename parameters>
242  static constexpr bool is_dirichlet_laplacian(const unsigned int node_type)
243  {
244  return std::find(parameters::dirichlet_laplacian_nodes.begin(),
245  parameters::dirichlet_laplacian_nodes.end(),
246  node_type) != parameters::dirichlet_laplacian_nodes.end();
247  }
248 
249  // -----------------------------------------------------------------------------------------------
250  // Private, const members: Parameters and auxiliaries that help assembling matrices, etc.
251  // -----------------------------------------------------------------------------------------------
252 
253  /*!***********************************************************************************************
254  * \brief (Globally constant) penalty parameter for HDG scheme.
255  ************************************************************************************************/
256  const lSol_float_t tau_;
257  /*!***********************************************************************************************
258  * \brief An integrator helps to easily evaluate integrals (e.g. via quadrature).
259  ************************************************************************************************/
263  lSol_float_t>
265 
266  // -----------------------------------------------------------------------------------------------
267  // Private, internal functions for the local solver
268  // -----------------------------------------------------------------------------------------------
269 
270  /*!***********************************************************************************************
271  * \brief Assemble local matrix for the local solver.
272  *
273  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
274  * \param tau Penalty parameter.
275  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
276  * \param eig Eigenvalue for which the matrix is assembled.
277  * \retval loc_mat Matrix of the local solver.
278  ************************************************************************************************/
279  template <typename hyEdgeT>
281  assemble_loc_matrix(const lSol_float_t tau, hyEdgeT& hyper_edge, const lSol_float_t eig) const;
282  /*!***********************************************************************************************
283  * \brief Assemble local right-hand for the local solver (from skeletal).
284  *
285  * The right hand side needs the values of the global degrees of freedom. Note that we basically
286  * follow the lines of
287  *
288  * B. Cockburn, J. Gopalakrishnan, and R. Lazarov.
289  * Unified hybridization of discontinuous Galerkin, mixed, and continuous Galerkin methods for
290  * second order elliptic problems. SIAM Journal on Numerical Analysis, 47(2):1319–1365, 2009
291  *
292  * and discriminate between local solvers with respect to the skeletal variable and with respect
293  * to the global right-hand side. This assembles the local right-hand side with respect to the
294  * skeletal variable.
295  *
296  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
297  * \tparam SmallMatT The typename of \c lambda_values.
298  * \param lambda_values Global degrees of freedom associated to the hyperedge.
299  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
300  * \retval loc_rhs Local right hand side of the locasl solver.
301  ************************************************************************************************/
302  template <typename hyEdgeT, typename SmallMatT>
304  const SmallMatT& lambda_values,
305  hyEdgeT& hyper_edge) const;
306  /*!***********************************************************************************************
307  * \brief Solve local problem (with right-hand side from skeletal).
308  *
309  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
310  * \tparam SmallMatT The data type of \c lambda_values.
311  * \param lambda_values Global degrees of freedom associated to the hyperedge.
312  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
313  * \param eig Eigenvalue for which the local problem is solved.
314  * \retval loc_sol Solution of the local problem.
315  ************************************************************************************************/
316  template <typename hyEdgeT, typename SmallMatT>
317  inline std::array<lSol_float_t, n_loc_dofs_> solve_local_problem(const SmallMatT& lambda_values,
318  hyEdgeT& hyper_edge,
319  const lSol_float_t eig) const
320  {
321  try
322  {
323  SmallVec<n_loc_dofs_, lSol_float_t> rhs = assemble_rhs_from_lambda(lambda_values, hyper_edge);
324  return (rhs / assemble_loc_matrix(tau_, hyper_edge, eig)).data();
325  }
326  catch (Wrapper::LAPACKexception& exc)
327  {
328  hy_assert(0 == 1, exc.what() << std::endl
329  << "This can happen if quadrature is too inaccurate!");
330  throw exc;
331  }
332  }
333  /*!***********************************************************************************************
334  * \brief Evaluate primal variable at boundary.
335  *
336  * Function to evaluate primal variable of the solution. This function is needed to calculate
337  * the local numerical fluxes.
338  *
339  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
340  * \param coeffs Coefficients of the local solution.
341  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
342  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
343  ************************************************************************************************/
344  template <typename hyEdgeT>
345  inline std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> primal_at_boundary(
346  const std::array<lSol_float_t, n_loc_dofs_>& coeffs,
347  hyEdgeT& hyper_edge) const;
348  /*!***********************************************************************************************
349  * \brief Evaluate dual variable at boundary.
350  *
351  * Function to evaluate dual variable of the solution. This function is needed to calculate the
352  * local numerical fluxes.
353  *
354  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
355  * \param coeffs Coefficients of the local solution.
356  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
357  * \retval bdr_coeffs Coefficients of respective (dim-1) dimensional function at boundaries.
358  ************************************************************************************************/
359  template <typename hyEdgeT>
360  inline std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> dual_at_boundary(
361  const std::array<lSol_float_t, n_loc_dofs_>& coeffs,
362  hyEdgeT& hyper_edge) const;
363 
364  public:
365  // -----------------------------------------------------------------------------------------------
366  // Public functions (and one typedef) to be utilized by external functions.
367  // -----------------------------------------------------------------------------------------------
368 
369  /*!***********************************************************************************************
370  * \brief Class is constructed using a single double indicating the penalty parameter.
371  ************************************************************************************************/
372  typedef lSol_float_t constructor_value_type;
373  /*!***********************************************************************************************
374  * \brief Constructor for local solver.
375  *
376  * \param tau Penalty parameter of HDG scheme.
377  ************************************************************************************************/
378  BilaplacianEigs(const constructor_value_type& tau = 1.) : tau_(tau) {}
379  /*!***********************************************************************************************
380  * \brief Evaluate local contribution to matrix--vector multiplication.
381  *
382  * This corresponds to an evaluation of the residual in the nonlinear context
383  *
384  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
385  * \tparam SmallMatInT Data type of \c lambda_values_in.
386  * \tparam SmallMatOutT Data type of \c lambda_values_out.
387  * \param lambda_values_in Local part of vector x.
388  * \param lambda_values_out Local part that will be added to A * x.
389  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
390  * \param eig Eigenvalue.
391  * \retval vecAx Local part of vector A * x.
392  ************************************************************************************************/
393  template <class hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
394  SmallMatOutT& trace_to_flux(const SmallMatInT& lambda_values_in,
395  SmallMatOutT& lambda_values_out,
396  hyEdgeT& hyper_edge,
397  const lSol_float_t eig) const
398  {
399  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
400  lambda_values_in.size() == 2 * hyEdge_dimT,
401  "Both matrices must be of same size which corresponds to the number of faces!");
402  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
403  hy_assert(
404  lambda_values_in[i].size() == lambda_values_out[i].size() &&
405  lambda_values_in[i].size() == n_glob_dofs_per_node(),
406  "Both matrices must be of same size which corresponds to the number of dofs per face!");
407 
408  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
409  std::array<lSol_float_t, n_loc_dofs_> coeffs =
410  solve_local_problem(lambda_values_in, hyper_edge, eig);
411 
412  std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> primals(
413  primal_at_boundary(coeffs, hyper_edge)),
414  duals(dual_at_boundary(coeffs, hyper_edge));
415 
416  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
417  {
418  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
419  lambda_values_out[i][j] =
420  duals[i][j] + tau_ * primals[i][j] -
421  tau_ * lambda_values_in[i][j < n_shape_bdr_ ? j + n_shape_bdr_ : j - n_shape_bdr_] *
422  hyper_edge.geometry.face_area(i);
423  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
424  for (unsigned int j = 0; j < lambda_values_out[i].size() / 2; ++j)
425  lambda_values_out[i][j] = 0.;
426  if (is_dirichlet_laplacian<parameters>(hyper_edge.node_descriptor[i]))
427  for (unsigned int j = lambda_values_out[i].size() / 2; j < lambda_values_out[i].size(); ++j)
428  lambda_values_out[i][j] = 0.;
429  }
430 
431  return lambda_values_out;
432  }
433  /*!***********************************************************************************************
434  * \brief Fill array with 1 if the node is of Dirichlet type and 0 elsewhen.
435  *
436  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
437  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
438  * \retval result Array encoding edge types.
439  ************************************************************************************************/
440  template <class hyEdgeT>
441  std::array<unsigned int, 2 * hyEdge_dimT> node_types(hyEdgeT& hyper_edge) const
442  {
443  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
444 
445  std::array<unsigned int, 2 * hyEdge_dimT> result;
446  result.fill(0);
447 
448  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
449  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
450  result[i] = 1;
451 
452  return result;
453  }
454  /*!***********************************************************************************************
455  * \brief L2 project given analytical functio to skeletal space.
456  *
457  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
458  * \tparam SmallMatT The data type of \c lambda_values.
459  * \param lambda_values Local part of vector x. (Redundant)
460  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
461  * \param time Time. (Redundant)
462  * \retval bdr_values Coefficients of L2 projection.
463  ************************************************************************************************/
464  template <class hyEdgeT, typename SmallMatT>
465  SmallMatT& make_initial(SmallMatT& lambda_values,
466  hyEdgeT& hyper_edge,
467  const lSol_float_t time = 0.) const
468  {
469  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
470 
471  for (unsigned int i = 0; i < lambda_values.size(); ++i)
472  {
473  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
474  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
475  lambda_values[i][j] = 0.;
476  else
477  {
478  for (unsigned int j = 0; j < lambda_values[i].size() / 2; ++j)
479  lambda_values[i][j] = integrator::template integrate_bdrUni_psifunc<
480  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>,
481  decltype(hyEdgeT::geometry), parameters::initial, Point<hyEdge_dimT, lSol_float_t> >(
482  j, i, hyper_edge.geometry, time);
483  for (unsigned int j = lambda_values[i].size() / 2; j < lambda_values[i].size(); ++j)
484  lambda_values[i][j] = integrator::template integrate_bdrUni_psifunc<
485  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>,
486  decltype(hyEdgeT::geometry), parameters::initial_laplace,
487  Point<hyEdge_dimT, lSol_float_t> >(j, i, hyper_edge.geometry, time);
488  }
489  }
490 
491  return lambda_values;
492  }
493  /*!***********************************************************************************************
494  * \brief Evaluate local contribution to matrix--vector multiplication.
495  *
496  * This corresponds to the evaluation of the Jacobian evaluated at \c lambda_vals, \c eig_val in
497  * the direction \c lambda_values, \c eig.
498  *
499  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
500  * \tparam SmallMatInT Data type of \c lambda_values_in.
501  * \tparam SmallMatOutT Data type of \c lambda_values_out.
502  * \param lambda_values_in Local part of vector x.
503  * \param lambda_values_out Local part that will be added to A * x.
504  * \param eig Eigenvalue in whose direction Jacobian is evaluated.
505  * \param lambda_vals Lambda at which Jacobian is evaluated.
506  * \param eig_val Eigenvalue at which Jacobian is evaluated.
507  * \param hyper_edge The geometry of the considered hyperedge (of typename hyEdgeT).
508  * \retval vecAx Local part of vector A * x.
509  ************************************************************************************************/
510  template <class hyEdgeT, typename SmallMatInT, typename SmallMatOutT>
511  SmallMatOutT& jacobian_of_trace_to_flux(const SmallMatInT& lambda_values_in,
512  SmallMatOutT& lambda_values_out,
513  const lSol_float_t eig,
514  const SmallMatInT& lambda_vals,
515  const lSol_float_t eig_val,
516  hyEdgeT& hyper_edge) const
517  {
518  hy_assert(lambda_values_in.size() == lambda_values_out.size() &&
519  lambda_values_in.size() == 2 * hyEdge_dimT,
520  "Both matrices must be of same size which corresponds to the number of faces!");
521  for (unsigned int i = 0; i < lambda_values_in.size(); ++i)
522  hy_assert(
523  lambda_values_in[i].size() == lambda_values_out[i].size() &&
524  lambda_values_in[i].size() == n_glob_dofs_per_node(),
525  "Both matrices must be of same size which corresponds to the number of dofs per face!");
526 
527  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
528  std::array<lSol_float_t, n_loc_dofs_> coeffs =
529  solve_local_problem(lambda_values_in, hyper_edge, eig_val); // f_mu(eta,lambda_)
530 
531  std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> primals(
532  primal_at_boundary(coeffs, hyper_edge)),
533  duals(dual_at_boundary(coeffs, hyper_edge));
534 
535  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
536  {
537  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
538  lambda_values_out[i][j] =
539  duals[i][j] + tau_ * primals[i][j] -
540  tau_ * lambda_values_in[i][j < n_shape_bdr_ ? j + n_shape_bdr_ : j - n_shape_bdr_] *
541  hyper_edge.geometry.face_area(i);
542  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
543  for (unsigned int j = 0; j < lambda_values_out[i].size() / 2; ++j)
544  lambda_values_out[i][j] = 0.;
545  if (is_dirichlet_laplacian<parameters>(hyper_edge.node_descriptor[i]))
546  for (unsigned int j = lambda_values_out[i].size() / 2; j < lambda_values_out[i].size(); ++j)
547  lambda_values_out[i][j] = 0.;
548  }
549 
550  coeffs = solve_local_problem(lambda_vals, hyper_edge, eig_val);
551 
552  // for (unsigned int i = 0; i < n_loc_dofs_ / 2 + hyEdge_dimT * n_shape_fct_; ++i) coeffs[i] =
553  // 0.; for (unsigned int i = 0; i < n_shape_fct_; ++i) coeffs[n_loc_dofs_ / 2 + hyEdge_dimT *
554  // n_shape_fct_ + i] *= eig * hyper_edge.geometry.area();
555 
556  for (unsigned int i = 0; i < n_shape_fct_; ++i)
557  coeffs[n_loc_dofs_ / 2 + hyEdge_dimT * n_shape_fct_ + i] =
558  eig * coeffs[hyEdge_dimT * n_shape_fct_ + i] * hyper_edge.geometry.area();
559  for (unsigned int i = 0; i < n_loc_dofs_ / 2 + hyEdge_dimT * n_shape_fct_; ++i)
560  coeffs[i] = 0.;
561 
562  coeffs = (SmallVec<coeffs.size(), lSol_float_t>(coeffs) /
563  assemble_loc_matrix(tau_, hyper_edge, eig_val))
564  .data();
565 
566  primals = primal_at_boundary(coeffs, hyper_edge);
567  duals = dual_at_boundary(coeffs, hyper_edge);
568 
569  for (unsigned int i = 0; i < lambda_values_out.size(); ++i)
570  {
571  for (unsigned int j = 0; j < lambda_values_out[i].size(); ++j)
572  lambda_values_out[i][j] += duals[i][j] + tau_ * primals[i][j];
573  if (is_dirichlet<parameters>(hyper_edge.node_descriptor[i]))
574  for (unsigned int j = 0; j < lambda_values_out[i].size() / 2; ++j)
575  lambda_values_out[i][j] = 0.;
576  if (is_dirichlet_laplacian<parameters>(hyper_edge.node_descriptor[i]))
577  for (unsigned int j = lambda_values_out[i].size() / 2; j < lambda_values_out[i].size(); ++j)
578  lambda_values_out[i][j] = 0.;
579  }
580 
581  return lambda_values_out;
582  }
583  /*!***********************************************************************************************
584  * \brief Local squared contribution to the L2 error.
585  *
586  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
587  * \tparam SmallMatT The data type of \c lambda_values.
588  * \param lambda_values The values of the skeletal variable's coefficients.
589  * \param hy_edge The geometry of the considered hyperedge (of typename GeomT).
590  * \param eig Approximated eigenvalue.
591  * \retval vec_b Local part of vector b.
592  ************************************************************************************************/
593  template <class hyEdgeT, typename SmallMatT>
594  std::array<lSol_float_t, 1U> errors(SmallMatT& lambda_values,
595  hyEdgeT& hy_edge,
596  const lSol_float_t eig = 0.) const
597  {
598  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
599 
600  for (unsigned int i = 0; i < lambda_values.size(); ++i)
601  for (unsigned int j = 0; j < lambda_values[i].size(); ++j)
602  hy_assert(lambda_values[i][j] == lambda_values[i][j],
603  "Lambda value wit index " << i << "," << j << " is NaN!");
604 
605  std::array<lSol_float_t, n_loc_dofs_> coefficients =
606  solve_local_problem(lambda_values, hy_edge, eig);
607  std::array<lSol_float_t, n_shape_fct_> coeffs;
608  for (unsigned int i = 0; i < coeffs.size(); ++i)
609  coeffs[i] = coefficients[i + hyEdge_dimT * n_shape_fct_];
610 
611  for (unsigned int i = 0; i < coeffs.size(); ++i)
612  hy_assert(coeffs[i] == coeffs[i], "The " << i << "-th coeff is NaN!");
613 
614  lSol_float_t result = integrator::template integrate_vol_diffsquare_discana<
615  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
616  parameters::analytic_result, Point<hyEdge_dimT, lSol_float_t> >(coeffs, hy_edge.geometry,
617  time);
618  hy_assert(result >= 0., "The squared error must be non-negative, but was " << result);
619  return std::array<lSol_float_t, 1U>({result});
620  }
621 
622  /*!***********************************************************************************************
623  * \brief Evaluate local local reconstruction at tensorial products of abscissas.
624  *
625  * \tparam absc_float_t Floating type for the abscissa values.
626  * \tparam abscissas_sizeT Size of the array of array of abscissas.
627  * \tparam input_array_t Type of input array.
628  * \tparam hyEdgeT The geometry type / typename of the considered hyEdge's geometry.
629  * \param abscissas Abscissas of the supporting points.
630  * \param lambda_values The values of the skeletal variable's coefficients.
631  * \param hyper_edge The geometry of the considered hyperedge (of typename GeomT).
632  * \param time Time.
633  * \retval func_values Function values at tensorial points.
634  ************************************************************************************************/
635  template <typename abscissa_float_t, std::size_t sizeT, class input_array_t, class hyEdgeT>
636  std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>, system_dim> bulk_values(
637  const std::array<abscissa_float_t, sizeT>& abscissas,
638  const input_array_t& lambda_values,
639  hyEdgeT& hyper_edge,
640  const lSol_float_t time = 0.) const;
641 }; // end of class BilaplacianEigs
642 
643 // -------------------------------------------------------------------------------------------------
645 // -------------------------------------------------------------------------------------------------
646 
647 // -------------------------------------------------------------------------------------------------
648 // -------------------------------------------------------------------------------------------------
649 //
650 // IMPLEMENTATION OF MEMBER FUNCTIONS OF BilaplacianEigs
651 //
652 // -------------------------------------------------------------------------------------------------
653 // -------------------------------------------------------------------------------------------------
654 
655 // -------------------------------------------------------------------------------------------------
656 // assemble_loc_matrix
657 // -------------------------------------------------------------------------------------------------
658 
659 template <unsigned int hyEdge_dimT,
660  unsigned int poly_deg,
661  unsigned int quad_deg,
662  template <unsigned int, typename>
663  typename parametersT,
664  typename lSol_float_t>
665 template <typename hyEdgeT>
666 inline SmallSquareMat<
668  lSol_float_t>
670  const lSol_float_t tau,
671  hyEdgeT& hyper_edge,
672  const lSol_float_t eig) const
673 {
674  using parameters = parametersT<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>;
675  constexpr unsigned int n_dofs_lap = n_loc_dofs_ / 2;
676 
678  lSol_float_t vol_integral, vol_func_integral, face_integral, helper;
679  SmallVec<hyEdge_dimT, lSol_float_t> grad_int_vec, normal_int_vec;
680 
681  for (unsigned int i = 0; i < n_shape_fct_; ++i)
682  {
683  for (unsigned int j = 0; j < n_shape_fct_; ++j)
684  {
685  // Integral_element phi_i phi_j dx in diagonal blocks
686  vol_integral = integrator::template integrate_vol_phiphi(i, j, hyper_edge.geometry);
687  vol_func_integral = integrator::template integrate_vol_phiphifunc<
688  Point<decltype(hyEdgeT::geometry)::space_dim(), lSol_float_t>, decltype(hyEdgeT::geometry),
689  parameters::inverse_bilaplacian_coefficient, Point<hyEdge_dimT, lSol_float_t> >(
690  i, j, hyper_edge.geometry, eig);
691  // Integral_element - nabla phi_i \vec phi_j dx
692  // = Integral_element - div \vec phi_i phi_j dx in right upper and left lower blocks
693  grad_int_vec =
694  integrator::template integrate_vol_nablaphiphi<SmallVec<hyEdge_dimT, lSol_float_t>,
695  decltype(hyEdgeT::geometry)>(
696  i, j, hyper_edge.geometry);
697 
698  face_integral = 0.;
699  normal_int_vec = 0.;
700  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
701  {
702  helper = integrator::template integrate_bdr_phiphi<decltype(hyEdgeT::geometry)>(
703  i, j, face, hyper_edge.geometry);
704  face_integral += helper;
705  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
706  normal_int_vec[dim] += hyper_edge.geometry.local_normal(face).operator[](dim) * helper;
707  }
708 
709  local_mat(hyEdge_dimT * n_shape_fct_ + i, n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) -=
710  vol_func_integral;
711 
712  local_mat(hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) +=
713  tau * face_integral;
714  local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
715  n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) += tau * face_integral;
716 
717  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
718  {
719  local_mat(dim * n_shape_fct_ + i, dim * n_shape_fct_ + j) += vol_integral;
720  local_mat(n_dofs_lap + dim * n_shape_fct_ + i, n_dofs_lap + dim * n_shape_fct_ + j) +=
721  vol_integral;
722 
723  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) -= grad_int_vec[dim];
724  local_mat(dim * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -= grad_int_vec[dim];
725  local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
726  n_dofs_lap + dim * n_shape_fct_ + j) -= grad_int_vec[dim];
727  local_mat(n_dofs_lap + dim * n_shape_fct_ + i,
728  n_dofs_lap + hyEdge_dimT * n_shape_fct_ + j) -= grad_int_vec[dim];
729 
730  local_mat(hyEdge_dimT * n_shape_fct_ + i, dim * n_shape_fct_ + j) += normal_int_vec[dim];
731  local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i,
732  n_dofs_lap + dim * n_shape_fct_ + j) += normal_int_vec[dim];
733  }
734 
735  local_mat(n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i, hyEdge_dimT * n_shape_fct_ + j) -=
736  eig * integrator::template integrate_vol_phiphi<decltype(hyEdgeT::geometry)>(
737  i, j, hyper_edge.geometry);
738  }
739  }
740 
741  return local_mat;
742 } // end of BilaplacianEigs::assemble_loc_matrix
743 
744 // -------------------------------------------------------------------------------------------------
745 // assemble_rhs_from_lambda
746 // -------------------------------------------------------------------------------------------------
747 
748 template <unsigned int hyEdge_dimT,
749  unsigned int poly_deg,
750  unsigned int quad_deg,
751  template <unsigned int, typename>
752  typename parametersT,
753  typename lSol_float_t>
754 template <typename hyEdgeT, typename SmallMatT>
755 inline SmallVec<
757  lSol_float_t>
759  assemble_rhs_from_lambda(const SmallMatT& lambda_values, hyEdgeT& hyper_edge) const
760 {
761  constexpr unsigned int n_dofs_lap = n_loc_dofs_ / 2;
762  hy_assert(lambda_values.size() == 2 * hyEdge_dimT,
763  "The size of the lambda values should be twice the dimension of a hyperedge.");
764  for (unsigned int i = 0; i < 2 * hyEdge_dimT; ++i)
765  hy_assert(lambda_values[i].size() == 2 * n_shape_bdr_,
766  "The size of lambda should be the amount of ansatz functions at boundary.");
767 
768  SmallVec<n_loc_dofs_, lSol_float_t> right_hand_side;
769  lSol_float_t integral;
770 
771  for (unsigned int i = 0; i < n_shape_fct_; ++i)
772  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
773  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
774  {
775  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
776  i, j, face, hyper_edge.geometry);
777  right_hand_side[hyEdge_dimT * n_shape_fct_ + i] += tau_ * lambda_values[face][j] * integral;
778  right_hand_side[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] +=
779  tau_ * lambda_values[face][n_shape_bdr_ + j] * integral;
780 
781  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
782  {
783  right_hand_side[dim * n_shape_fct_ + i] -=
784  hyper_edge.geometry.local_normal(face).operator[](dim) * lambda_values[face][j] *
785  integral;
786  right_hand_side[n_dofs_lap + dim * n_shape_fct_ + i] -=
787  hyper_edge.geometry.local_normal(face).operator[](dim) *
788  lambda_values[face][n_shape_bdr_ + j] * integral;
789  }
790  }
791 
792  return right_hand_side;
793 } // end of BilaplacianEigs::assemble_rhs_from_lambda
794 
795 // -------------------------------------------------------------------------------------------------
796 // primal_at_boundary
797 // -------------------------------------------------------------------------------------------------
798 
799 template <unsigned int hyEdge_dimT,
800  unsigned int poly_deg,
801  unsigned int quad_deg,
802  template <unsigned int, typename>
803  typename parametersT,
804  typename lSol_float_t>
805 template <typename hyEdgeT>
806 inline std::array<
807  std::array<
808  lSol_float_t,
810  2 * hyEdge_dimT>
812  const std::array<lSol_float_t, n_loc_dofs_>& coeffs,
813  hyEdgeT& hyper_edge) const
814 {
815  constexpr unsigned int n_dofs_lap = n_loc_dofs_ / 2;
816  std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
817 
818  for (unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
819  bdr_values[dim_n].fill(0.);
820 
821  for (unsigned int i = 0; i < n_shape_fct_; ++i)
822  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
823  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
824  {
825  bdr_values[face][n_shape_bdr_ + j] +=
826  coeffs[hyEdge_dimT * n_shape_fct_ + i] *
827  integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
828  i, j, face, hyper_edge.geometry);
829 
830  bdr_values[face][j] +=
831  coeffs[n_dofs_lap + hyEdge_dimT * n_shape_fct_ + i] *
832  integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
833  i, j, face, hyper_edge.geometry);
834  }
835 
836  return bdr_values;
837 } // end of BilaplacianEigs::primal_at_boundary
838 
839 // -------------------------------------------------------------------------------------------------
840 // dual_at_boundary
841 // -------------------------------------------------------------------------------------------------
842 
843 template <unsigned int hyEdge_dimT,
844  unsigned int poly_deg,
845  unsigned int quad_deg,
846  template <unsigned int, typename>
847  typename parametersT,
848  typename lSol_float_t>
849 template <typename hyEdgeT>
850 inline std::array<
851  std::array<
852  lSol_float_t,
854  2 * hyEdge_dimT>
856  const std::array<lSol_float_t, n_loc_dofs_>& coeffs,
857  hyEdgeT& hyper_edge) const
858 {
859  constexpr unsigned int n_dofs_lap = n_loc_dofs_ / 2;
860  std::array<std::array<lSol_float_t, 2 * n_shape_bdr_>, 2 * hyEdge_dimT> bdr_values;
861  lSol_float_t integral;
862 
863  for (unsigned int dim_n = 0; dim_n < 2 * hyEdge_dimT; ++dim_n)
864  bdr_values[dim_n].fill(0.);
865 
866  for (unsigned int i = 0; i < n_shape_fct_; ++i)
867  for (unsigned int j = 0; j < n_shape_bdr_; ++j)
868  for (unsigned int face = 0; face < 2 * hyEdge_dimT; ++face)
869  {
870  integral = integrator::template integrate_bdr_phipsi<decltype(hyEdgeT::geometry)>(
871  i, j, face, hyper_edge.geometry);
872  for (unsigned int dim = 0; dim < hyEdge_dimT; ++dim)
873  {
874  bdr_values[face][n_shape_bdr_ + j] +=
875  hyper_edge.geometry.local_normal(face).operator[](dim) * integral *
876  coeffs[dim * n_shape_fct_ + i];
877 
878  bdr_values[face][j] += hyper_edge.geometry.local_normal(face).operator[](dim) * integral *
879  coeffs[n_dofs_lap + dim * n_shape_fct_ + i];
880  }
881  }
882 
883  return bdr_values;
884 } // end of BilaplacianEigs::dual_at_boundary
885 
886 // -------------------------------------------------------------------------------------------------
887 // bulk_values
888 // -------------------------------------------------------------------------------------------------
889 
890 template <unsigned int hyEdge_dimT,
891  unsigned int poly_deg,
892  unsigned int quad_deg,
893  template <unsigned int, typename>
894  typename parametersT,
895  typename lSol_float_t>
896 template <typename abscissa_float_t, std::size_t sizeT, class input_array_t, typename hyEdgeT>
897 std::array<std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
900  const std::array<abscissa_float_t, sizeT>& abscissas,
901  const input_array_t& lambda_values,
902  hyEdgeT& hyper_edge,
903  const lSol_float_t time) const
904 {
906  solve_local_problem(lambda_values, hyper_edge, time);
908  SmallVec<static_cast<unsigned int>(sizeT), abscissa_float_t> helper(abscissas);
909 
910  std::array<
911  std::array<lSol_float_t, Hypercube<hyEdge_dimT>::pow(sizeT)>,
913  point_vals;
914 
915  for (unsigned int d = 0; d < system_dim; ++d)
916  {
917  for (unsigned int i = 0; i < coeffs.size(); ++i)
918  coeffs[i] = coefficients[d * n_shape_fct_ + i];
919  for (unsigned int pt = 0; pt < Hypercube<hyEdge_dimT>::pow(sizeT); ++pt)
920  point_vals[d][pt] = integrator::shape_fun_t::template lin_comb_fct_val<float>(
921  coeffs, Hypercube<hyEdge_dimT>::template tensorial_pt<Point<hyEdge_dimT> >(pt, helper));
922  }
923 
924  return point_vals;
925 } // end of BilaplacianEigs::bulk_values
926 
927 // -------------------------------------------------------------------------------------------------
929 // -------------------------------------------------------------------------------------------------
930 
931 } // namespace LocalSolver
LocalSolver::Bilaplacian_parameters_default::inverse_bilaplacian_coefficient
static param_float_t inverse_bilaplacian_coefficient(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Inverse bilaplacian coefficient in PDE as analytic function.
Definition: bilaplacian_eigs_ldgh.hxx:41
shape_function.hxx
LocalSolver::BilaplacianEigs::node_types
std::array< unsigned int, 2 *hyEdge_dimT > node_types(hyEdgeT &hyper_edge) const
Fill array with 1 if the node is of Dirichlet type and 0 elsewhen.
Definition: bilaplacian_eigs_ldgh.hxx:441
LocalSolver::BilaplacianEigs::n_shape_fct_
static constexpr unsigned int n_shape_fct_
Number of local shape functions (with respect to all spatial dimensions).
Definition: bilaplacian_eigs_ldgh.hxx:211
LocalSolver::BilaplacianEigs::is_dirichlet
static constexpr bool is_dirichlet(const unsigned int node_type)
Find out whether a node is of Dirichlet type.
Definition: bilaplacian_eigs_ldgh.hxx:236
LocalSolver::Bilaplacian_parameters_default::dirichlet_laplacian_nodes
static constexpr std::array< unsigned int, 0U > dirichlet_laplacian_nodes
Array containing hypernode types corresponding to Dirichlet boundary of Laplacian.
Definition: bilaplacian_eigs_ldgh.hxx:29
LocalSolver::BilaplacianEigs::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: bilaplacian_eigs_ldgh.hxx:264
Wrapper::LAPACKexception::what
const char * what() const
Definition: lapack.hxx:27
LocalSolver
A namespace for local solvers.
Definition: advection_parab_ldgh.hxx:11
tensorial.hxx
LocalSolver::BilaplacianEigs::error_def
Define how errors are evaluated.
Definition: bilaplacian_eigs_ldgh.hxx:139
diffusion_uniform.geometry
geometry
Definition: diffusion_uniform.py:19
LocalSolver::BilaplacianEigs::node_element
Define type of node elements, especially with respect to nodal shape functions.
Definition: bilaplacian_eigs_ldgh.hxx:130
LocalSolver::BilaplacianEigs::dual_at_boundary
std::array< std::array< lSol_float_t, 2 *n_shape_bdr_ >, 2 *hyEdge_dimT > dual_at_boundary(const std::array< lSol_float_t, n_loc_dofs_ > &coeffs, hyEdgeT &hyper_edge) const
Evaluate dual variable at boundary.
LocalSolver::BilaplacianEigs::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: bilaplacian_eigs_ldgh.hxx:157
LocalSolver::BilaplacianEigs::n_loc_dofs_
static constexpr unsigned int n_loc_dofs_
Number of (local) degrees of freedom per hyperedge.
Definition: bilaplacian_eigs_ldgh.hxx:219
LocalSolver::Bilaplacian_parameters_default::dirichlet_nodes
static constexpr std::array< unsigned int, 0U > dirichlet_nodes
Array containing hypernode types corresponding to Dirichlet boundary.
Definition: bilaplacian_eigs_ldgh.hxx:25
LocalSolver::BilaplacianEigs::bulk_values
std::array< std::array< lSol_float_t, Hypercube< hyEdge_dimT >::pow(sizeT)>, system_dim > bulk_values(const std::array< abscissa_float_t, sizeT > &abscissas, const input_array_t &lambda_values, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
Evaluate local local reconstruction at tensorial products of abscissas.
LocalSolver::BilaplacianEigs::tau_
const lSol_float_t tau_
(Globally constant) penalty parameter for HDG scheme.
Definition: bilaplacian_eigs_ldgh.hxx:256
LocalSolver::BilaplacianEigs::system_dim
static constexpr unsigned int system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: bilaplacian_eigs_ldgh.hxx:225
LocalSolver::BilaplacianEigs::is_dirichlet_laplacian
static constexpr bool is_dirichlet_laplacian(const unsigned int node_type)
Definition: bilaplacian_eigs_ldgh.hxx:242
LocalSolver::BilaplacianEigs::node_element::functions
std::tuple< TPP::ShapeFunction< TPP::ShapeType::Tensorial< TPP::ShapeType::Legendre< poly_deg >, hyEdge_dimT - 1 > > > functions
Definition: bilaplacian_eigs_ldgh.hxx:134
LocalSolver::BilaplacianEigs::node_system_dimension
static constexpr unsigned int node_system_dimension()
Dimension of of the solution evaluated with respect to a hypernode.
Definition: bilaplacian_eigs_ldgh.hxx:201
LocalSolver::Bilaplacian_parameters_default::neumann_laplacian_nodes
static constexpr std::array< unsigned int, 0U > neumann_laplacian_nodes
Array containing hypernode types corresponding to Neumann boundary of Laplacian.
Definition: bilaplacian_eigs_ldgh.hxx:37
LocalSolver::BilaplacianEigs::BilaplacianEigs
BilaplacianEigs(const constructor_value_type &tau=1.)
Constructor for local solver.
Definition: bilaplacian_eigs_ldgh.hxx:378
TPP::Quadrature::GaussLegendre
Gauss–Legendre quadrature points and weights in one spatial dimension.
Definition: one_dimensional.hxx:19
LocalSolver::Bilaplacian_parameters_default::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: bilaplacian_eigs_ldgh.hxx:57
SmallMat::size
static constexpr unsigned int size()
Return size a SmallMat.
Definition: dense_la.hxx:54
LocalSolver::Bilaplacian_parameters_default::neumann_nodes
static constexpr std::array< unsigned int, 0U > neumann_nodes
Array containing hypernode types corresponding to Neumann boundary.
Definition: bilaplacian_eigs_ldgh.hxx:33
LocalSolver::Bilaplacian_parameters_default
Default parameters for the diffusion equation, cf. below.
Definition: bilaplacian_eigs_ldgh.hxx:20
LocalSolver::Bilaplacian_parameters_default::dirichlet_laplace_value
static param_float_t dirichlet_laplace_value(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Dirichlet values of solution's Laplacian as analytic function.
Definition: bilaplacian_eigs_ldgh.hxx:65
TPP::ShapeType::Tensorial
Struct that handles the evaluation of tensorial shape functions.
Definition: tensorial.hxx:22
LocalSolver::BilaplacianEigs::error_def::error_t
std::array< lSol_float_t, 1U > error_t
Define the typename returned by function errors.
Definition: bilaplacian_eigs_ldgh.hxx:144
LocalSolver::BilaplacianEigs::trace_to_flux
SmallMatOutT & trace_to_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, hyEdgeT &hyper_edge, const lSol_float_t eig) const
Evaluate local contribution to matrix–vector multiplication.
Definition: bilaplacian_eigs_ldgh.hxx:394
LocalSolver::BilaplacianEigs::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).
TPP::ShapeFunction
Struct that handles different types of evaluation of shape functions.
Definition: shape_function.hxx:15
LocalSolver::BilaplacianEigs::node_system_dim
static constexpr unsigned int node_system_dim
Dimension of of the solution evaluated with respect to a hypernode.
Definition: bilaplacian_eigs_ldgh.hxx:231
LocalSolver::BilaplacianEigs::system_dimension
static constexpr unsigned int system_dimension()
Dimension of of the solution evaluated with respect to a hyperedge.
Definition: bilaplacian_eigs_ldgh.hxx:197
TPP::Quadrature::Tensorial
General integrator class on tensorial hypergraphs.
Definition: tensorial.hxx:24
LocalSolver::BilaplacianEigs::make_initial
SmallMatT & make_initial(SmallMatT &lambda_values, hyEdgeT &hyper_edge, const lSol_float_t time=0.) const
L2 project given analytical functio to skeletal space.
Definition: bilaplacian_eigs_ldgh.hxx:465
LocalSolver::BilaplacianEigs::n_shape_bdr_
static constexpr unsigned int n_shape_bdr_
Number oflocal shape functions (with respect to a face / hypernode).
Definition: bilaplacian_eigs_ldgh.hxx:215
LocalSolver::BilaplacianEigs::error_def::postprocess_error
static error_t postprocess_error(error_t &summed_error)
Define how global errors should be postprocessed.
Definition: bilaplacian_eigs_ldgh.hxx:166
LocalSolver::BilaplacianEigs::error_def::initial_error
static error_t initial_error()
Define how initial error is generated.
Definition: bilaplacian_eigs_ldgh.hxx:148
hypercube.hxx
Wrapper::LAPACKexception
Exception to be thrown if LAPACK's solve fails.
Definition: lapack.hxx:25
LocalSolver::BilaplacianEigs::jacobian_of_trace_to_flux
SmallMatOutT & jacobian_of_trace_to_flux(const SmallMatInT &lambda_values_in, SmallMatOutT &lambda_values_out, const lSol_float_t eig, const SmallMatInT &lambda_vals, const lSol_float_t eig_val, hyEdgeT &hyper_edge) const
Evaluate local contribution to matrix–vector multiplication.
Definition: bilaplacian_eigs_ldgh.hxx:511
LocalSolver::BilaplacianEigs::hyEdge_dim
static constexpr unsigned int hyEdge_dim()
Dimension of hyper edge type that this object solves on.
Definition: bilaplacian_eigs_ldgh.hxx:181
Hypercube::pow
static constexpr unsigned int pow(unsigned int base)
Return n to the power dim.
Definition: hypercube.hxx:25
LocalSolver::BilaplacianEigs::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 eig) const
Assemble local matrix for the local solver.
LocalSolver::BilaplacianEigs::errors
std::array< lSol_float_t, 1U > errors(SmallMatT &lambda_values, hyEdgeT &hy_edge, const lSol_float_t eig=0.) const
Local squared contribution to the L2 error.
Definition: bilaplacian_eigs_ldgh.hxx:594
LocalSolver::Bilaplacian_parameters_default::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: bilaplacian_eigs_ldgh.hxx:89
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::Bilaplacian_parameters_default::neumann_laplace_value
static param_float_t neumann_laplace_value(const Point< space_dimT, param_float_t > &, const param_float_t=0.)
Neumann values of solution's Laplacian as analytic function.
Definition: bilaplacian_eigs_ldgh.hxx:81
hy_assert
#define hy_assert(Expr, Msg)
The assertion to be used within HyperHDG — deactivate using -DNDEBUG compile flag.
Definition: hy_assert.hxx:38
dense_la.hxx
LocalSolver::BilaplacianEigs
Local solver for bilaplacian equation on uniform hypergraph.
Definition: bilaplacian_eigs_ldgh.hxx:118
LocalSolver::BilaplacianEigs::solve_local_problem
std::array< lSol_float_t, n_loc_dofs_ > solve_local_problem(const SmallMatT &lambda_values, hyEdgeT &hyper_edge, const lSol_float_t eig) const
Solve local problem (with right-hand side from skeletal).
Definition: bilaplacian_eigs_ldgh.hxx:317
LocalSolver::Bilaplacian_parameters_default::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: bilaplacian_eigs_ldgh.hxx:73
LocalSolver::BilaplacianEigs::data_type
Define type of (hyperedge related) data that is stored in HyDataContainer.
Definition: bilaplacian_eigs_ldgh.hxx:124
LocalSolver::BilaplacianEigs::constructor_value_type
lSol_float_t constructor_value_type
Class is constructed using a single double indicating the penalty parameter.
Definition: bilaplacian_eigs_ldgh.hxx:372
LocalSolver::Bilaplacian_parameters_default::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: bilaplacian_eigs_ldgh.hxx:49
LocalSolver::BilaplacianEigs::n_glob_dofs_per_node
static constexpr unsigned int n_glob_dofs_per_node()
Evaluate amount of global degrees of freedom per hypernode.
Definition: bilaplacian_eigs_ldgh.hxx:190
LocalSolver::BilaplacianEigs::primal_at_boundary
std::array< std::array< lSol_float_t, 2 *n_shape_bdr_ >, 2 *hyEdge_dimT > primal_at_boundary(const std::array< lSol_float_t, n_loc_dofs_ > &coeffs, hyEdgeT &hyper_edge) const
Evaluate primal variable at boundary.
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