HyperHDG
prototype.hxx
Go to the documentation of this file.
1 #pragma once // Ensure that file is included only once in a single compilation.
2 
3 /*!*************************************************************************************************
4  * \brief Macro that allows to use an implemented a matrix--vector multpilication.
5  *
6  * This macro implements a condensed matrix--vector multiplication commonly used in HyperHDG.
7  * However, several requirements have to be meet for the macro to be used. That is:
8  * - LargeVecT has to define the typename of the large vector,
9  * - dof_value_t is the typename of a dof value,
10  * - SmallVec of file dense_la has to be available,
11  * - hyEdge_dim and n_dofs_per_node need to be constexpr variables,
12  * - the algortihm library needs to be included,
13  * - hyper_graph_ is an instance of HDGHyperGraph,
14  * - has_fun_name is constructed via the macro HAS_MEMBER_FUNCTION,
15  * - local_solver_ is a LocalSolverT,
16  * - ... .
17  **************************************************************************************************/
18 #define prototype_mat_vec_multiply(fun_name, has_fun_name) \
19  [&]() { \
20  LargeVecT vec_Ax(x_vec.size(), 0.); \
21  SmallVec<2 * hyEdge_dim, hyNode_index_t> hyNodes; \
22  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim> dofs_old, dofs_new; \
23  \
24  std::for_each(hyper_graph_.begin(), hyper_graph_.end(), [&](auto hyper_edge) { \
25  hyNodes = hyper_edge.topology.get_hyNode_indices(); \
26  for (unsigned int node = 0; node < hyNodes.size(); ++node) \
27  { \
28  hyper_graph_.hyNode_factory().get_dof_values(hyNodes[node], x_vec, dofs_old[node]); \
29  dofs_new[node].fill(0.); \
30  } \
31  \
32  if constexpr (has_fun_name< \
33  LocalSolverT, \
34  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&( \
35  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&, \
36  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&, \
37  dof_value_t)>::value) \
38  local_solver_.fun_name(dofs_old, dofs_new, time); \
39  else if constexpr ( \
40  has_fun_name<LocalSolverT, \
41  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&( \
42  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&, \
43  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim>&, \
44  decltype(hyper_edge)&, dof_value_t)>::value) \
45  local_solver_.fun_name(dofs_old, dofs_new, hyper_edge, time); \
46  else \
47  hy_assert(false, "Function seems not to be implemented!"); \
48  \
49  for (unsigned int node = 0; node < hyNodes.size(); ++node) \
50  hyper_graph_.hyNode_factory().add_to_dof_values(hyNodes[node], vec_Ax, dofs_new[node]); \
51  }); \
52  \
53  return vec_Ax; \
54  }()
55 
56 /*!*************************************************************************************************
57  * \brief Macro that allows to use an implemented error evaluation.
58  *
59  * This macro implements a condensed matrix--vector multiplication commonly used in HyperHDG.
60  * However, several requirements have to be meet for the macro to be used. That is:
61  * - LargeVecT has to define the typename of the large vector,
62  * - dof_value_t is the typename of a dof value,
63  * - SmallVec of file dense_la has to be available,
64  * - hyEdge_dim and n_dofs_per_node need to be constexpr variables,
65  * - the algortihm library needs to be included,
66  * - hyper_graph_ is an instance of HDGHyperGraph,
67  * - has_fun_name is constructed via the macro HAS_MEMBER_FUNCTION,
68  * - local_solver_ is a LocalSolverT,
69  * - ... .
70  **************************************************************************************************/
71 #define prototype_errors(fun_name, has_fun_name) \
72  [&]() { \
73  typedef typename LocalSolverT::error_def::error_t error_t; \
74  error_t result = LocalSolverT::error_def::initial_error(); \
75  \
76  SmallVec<2 * hyEdge_dim, hyNode_index_t> hyNodes; \
77  std::array<std::array<dof_value_t, n_dofs_per_node>, 2 * hyEdge_dim> dofs; \
78  \
79  std::for_each(hyper_graph_.begin(), hyper_graph_.end(), [&](auto hyper_edge) { \
80  hyNodes = hyper_edge.topology.get_hyNode_indices(); \
81  for (unsigned int node = 0; node < hyNodes.size(); ++node) \
82  hyper_graph_.hyNode_factory().get_dof_values(hyNodes[node], x_vec, dofs[node]); \
83  \
84  if constexpr (has_fun_name<LocalSolverT, \
85  error_t(std::array<std::array<dof_value_t, n_dofs_per_node>, \
86  2 * hyEdge_dim>&, \
87  dof_value_t)>::value) \
88  result = LocalSolverT::error_def::sum_error(result, local_solver_.fun_name(dofs, time)); \
89  else if constexpr (has_fun_name<LocalSolverT, \
90  error_t(std::array<std::array<dof_value_t, n_dofs_per_node>, \
91  2 * hyEdge_dim>&, \
92  decltype(hyper_edge)&, dof_value_t)>::value) \
93  result = LocalSolverT::error_def::sum_error( \
94  result, local_solver_.fun_name(dofs, hyper_edge, time)); \
95  else \
96  hy_assert(false, "Function seems not to be ímplemented"); \
97  }); \
98  \
99  return LocalSolverT::error_def::postprocess_error(result); \
100  }()