HyperHDG
linear.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/hy_assert.hxx>
5 
6 namespace Mapping
7 {
8 /*!*************************************************************************************************
9  * \brief Mapping of a unit hypercube to a parallelotope --- can also be used for simplices.
10  *
11  * The affine-linear mapping of a \c hyEdge_dimT dimensional unit square to an parallelotope which
12  * lives in \c space_dimT dimensions.
13  *
14  * \authors Guido Kanschat, Heidelberg University, 2019--2020.
15  * \authors Andreas Rupp, Heidelberg University, 2019--2020.
16  **************************************************************************************************/
17 template <unsigned int hyEdge_dimT, unsigned int space_dimT, typename map_float_t>
18 class Linear
19 {
20  public:
21  /*!***********************************************************************************************
22  * \brief Returns the template parameter representing the dimension of a hyperedge.
23  *
24  * \retval hyEdge_dimT The dimension of a hyperedge.
25  ************************************************************************************************/
26  static constexpr unsigned int hyEdge_dim() { return hyEdge_dimT; }
27  /*!***********************************************************************************************
28  * \brief Returns the template parameter representing the dimension of the space.
29  *
30  * \retval space_dimT The dimension of the space.
31  ************************************************************************************************/
32  static constexpr unsigned int space_dim() { return space_dimT; }
33 
34  private:
35  /*!***********************************************************************************************
36  * \brief The translation of the affine mapping from reference to physical element.
37  ************************************************************************************************/
39  /*!***********************************************************************************************
40  * \brief The matrix of the affine mapping from reference to physical element.
41  ************************************************************************************************/
43  /*!***********************************************************************************************
44  * \brief Matrix Q of QR decomposition of the matrix of the affine transformation.
45  *
46  * This matrix is normalized to have det(Q) = +1.
47  ************************************************************************************************/
49  /*!***********************************************************************************************
50  * \brief Matrix R of QR decomposition of the matrix of the affine transformation.
51  *
52  * This matrix actually is a rectangular matrix. Due to our assumption that the space dimension
53  * is larger than or equal to the dimension of a hyperedge, the matrix \c matrix and its R of
54  * the QR decomposition have at least as many rows, as they have columns. Nonetheless, R is an
55  * upper triangular matrix. This allows to remove the zero rows (actually below our saved R)
56  * without loss of generality, but saving some space.
57  *
58  * This matrix is normalized to have non-negative diagonal entries, except for the very first.
59  ************************************************************************************************/
61 
62  public:
63  /*!***********************************************************************************************
64  * \brief Construct affine-linear mapping.
65  ************************************************************************************************/
66  Linear() = default;
67  /*!***********************************************************************************************
68  * \brief Construct affine-linear mapping.
69  *
70  * \param translation The translation of the afine-linear mapping.
71  * \param matrix The matrix of the affine-linear mapping.
72  ************************************************************************************************/
76  {
78  }
79  /*!***********************************************************************************************
80  * \brief The functional determinant of the affine-linear mappring.
81  *
82  * The determinant, in general is only defined for square matrices. In our case, the determinant
83  * is related to the ratio of Lebesque measure of the reference cell and the Haussdorff measure
84  * of the physical cell. This induces a natural generalization to rectangular matrices (with at
85  * least as many rows as columns), where the generalized determinant can be defined as the
86  * product of the diagonal entries of matrix R of the QR decomposition if normalized as it is
87  * described above.
88  *
89  * This determinant corresponds (up to its sign) to the general Haussdorff transformation
90  * formula of measures by a factor of g = sqrt( (D Phi)^T (D Phi) ).
91  * The difference in the sign will become important for the transformation of gradients.
92  ************************************************************************************************/
93  map_float_t functional_determinant_hyEdge() const
94  {
95  map_float_t determinant = 1.;
96  for (unsigned int i = 0; i < hyEdge_dimT; ++i)
97  determinant *= matrix_r_(i, i);
98  return determinant;
99  }
100  /*!***********************************************************************************************
101  * \brief The functional determinant of the affine-linear mapping of a hypernode.
102  *
103  * For details consider the description of \c functional_determinant_hyEdge(), and that a
104  * hypernode is spanned by all, but one columns of the matrix for the affine-linear mapping.
105  *
106  * \param index Index of the vector in the matrix which is \b not related to the node.
107  ************************************************************************************************/
108  map_float_t functional_determinant_hyNode(const unsigned int index) const
109  {
110  if constexpr (hyEdge_dimT == 1)
111  return 1.;
112  else
113  {
114  SmallMat<space_dimT, hyEdge_dimT - 1, map_float_t> mat_face;
115  for (unsigned int i = 0; i < hyEdge_dimT; ++i)
116  if (i != index)
117  mat_face.set_column(i - (i > index), matrix_.get_column(i));
118  return determinant(mat_face);
119  }
120  }
121  /*!***********************************************************************************************
122  * \brief Return vector representing matrix column of specified index.
123  *
124  * \param col The index of the column that is to be returned.
125  ************************************************************************************************/
126  SmallVec<space_dimT, map_float_t> matrix_column(const unsigned int col) const
127  {
128  return matrix_.get_column(col);
129  }
130 
131  /*!***********************************************************************************************
132  * \brief Map n_vec points from reference to physical element.
133  *
134  * \param points Matrix whose columns consist of the points to be mapped.
135  * \retval phy_points Matrix whose columns consist of the mapped points.
136  ************************************************************************************************/
137  template <unsigned int n_vec>
139  const SmallMat<hyEdge_dimT, n_vec, map_float_t>& points) const
140  {
141  return matrix_ * points + translation_;
142  }
143  /*!***********************************************************************************************
144  * \brief Map n_vec points from physical to element.
145  *
146  * \param phy_points Matrix whose columns consist of the mapped points.
147  * \retval points Matrix whose columns consist of the points to be mapped.
148  ************************************************************************************************/
149  template <unsigned int n_vec>
151  const SmallMat<space_dimT, n_vec, map_float_t>& phy_points) const
152  {
153  return (phy_points - translation_) / matrix_;
154  }
155  /*!***********************************************************************************************
156  * \brief Return matrix Q of the QR decomposition.
157  ************************************************************************************************/
159  /*!***********************************************************************************************
160  * \brief Return matrix R of the QR decomposition.
161  ************************************************************************************************/
163  /*!***********************************************************************************************
164  * \brief Return local normal of given index.
165  *
166  * Return outer unit normal with respect to the hypernode which is spanned by all columns of R,
167  * but the column of the given index. This is an element of the same dimension as the reference
168  * square.
169  *
170  * \param index Index of the vector in the matrix which is \b not related to the node.
171  ************************************************************************************************/
173  {
174  hy_assert(index < hyEdge_dimT,
175  "The index of the searched normal must not be bigger than their amount.");
176  if constexpr (hyEdge_dimT == 1)
177  {
178  if (matrix_r_(0, 0) > 0)
180  else
182  }
183  else
184  {
185  SmallMat<hyEdge_dimT, hyEdge_dimT - 1, map_float_t> other_vectors;
186  for (unsigned int i = 0; i < hyEdge_dimT; ++i)
187  if (i != index)
188  other_vectors.set_column(i - (i > index), matrix_r_.get_column(i));
189 
191  qr_decomp_q(other_vectors).get_column(hyEdge_dimT - 1);
192  map_float_t scalar_pdct = scalar_product(normal, matrix_r_.get_column(index));
193  hy_assert(scalar_pdct != 0., "Scalar product must not be zero!");
194  if (scalar_pdct > 0.)
195  normal *= -1.;
196  return normal;
197  }
198  }
199  /*!***********************************************************************************************
200  * \brief Return inner normal of given index.
201  *
202  * Return outer unit normal with respect to the hypernode which is spanned by all columns of the
203  * transformation matrix but the column of the given index. The vector has to be in the span of
204  * the columns of the transformation matrix. This is an element of the same dimension as the
205  * full space.
206  *
207  * \param index Index of the vector in the matrix which is \b not related to the node.
208  ************************************************************************************************/
210  {
211  hy_assert(index < hyEdge_dimT,
212  "The index of the inner normal must not be bigger than their amount.");
213  if constexpr (space_dimT == 1)
215 
216  SmallMat<space_dimT, space_dimT - 1, map_float_t> other_vectors;
217  for (unsigned int i = 0; i < space_dimT - hyEdge_dimT; ++i)
218  other_vectors.set_column(i, outer_normal(i));
219  for (unsigned int i = 0; i < hyEdge_dimT; ++i)
220  if (i != index)
221  other_vectors.set_column(i + space_dimT - hyEdge_dimT - (i > index), matrix_.get_column(i));
222 
224  qr_decomp_q(other_vectors).get_column(space_dimT - 1);
225  map_float_t scalar_pdct = scalar_product(normal, matrix_.get_column(index));
226  hy_assert(scalar_pdct != 0., "Scalar product must not be zero.");
227  if (scalar_pdct > 0)
228  normal *= -1.;
229  return normal;
230  }
231  /*!***********************************************************************************************
232  * \brief Return outer normal of given index.
233  *
234  * Return unit normal with respect to the hyperedge within the full space.
235  *
236  * \param index Index of the normal.
237  ************************************************************************************************/
239  {
240  hy_assert(index < space_dimT - hyEdge_dimT,
241  "The index of the outer normal must not be bigger than their amount.");
242 
243  return matrix_q_.get_column(index + hyEdge_dimT);
244  }
245  /*!***********************************************************************************************
246  * \brief Return matrix associated to affine-linear transformation.
247  ************************************************************************************************/
249  /*!***********************************************************************************************
250  * \brief Return shifting vector associated to affine-linear transformation.
251  ************************************************************************************************/
253 }; // end class File
254 
255 } // end of namespace Mapping
hy_assert.hxx
This file provides the function hy_assert.
qr_decomp
void qr_decomp(SmallMat< n_rows, n_cols, mat_entry_t > &mat, SmallSquareMat< n_rows, mat_entry_t > &mat_q, SmallSquareMat< n_cols, mat_entry_t > &mat_r)
Normalized QR decomposition.
Definition: dense_la.hxx:1039
check_push_test.index
index
Definition: check_push_test.py:10
Mapping::Linear::local_normal
SmallVec< hyEdge_dimT, map_float_t > local_normal(const unsigned int index) const
Return local normal of given index.
Definition: linear.hxx:172
Mapping::Linear::inner_normal
SmallVec< space_dimT, map_float_t > inner_normal(const unsigned int index) const
Return inner normal of given index.
Definition: linear.hxx:209
Mapping::Linear::map_physical_to_reference
SmallMat< hyEdge_dimT, n_vec, map_float_t > map_physical_to_reference(const SmallMat< space_dimT, n_vec, map_float_t > &phy_points) const
Map n_vec points from physical to element.
Definition: linear.hxx:150
Mapping::Linear::matrix
const SmallMat< space_dimT, hyEdge_dimT, map_float_t > & matrix() const
Return matrix associated to affine-linear transformation.
Definition: linear.hxx:248
Mapping::Linear::functional_determinant_hyEdge
map_float_t functional_determinant_hyEdge() const
The functional determinant of the affine-linear mappring.
Definition: linear.hxx:93
Mapping::Linear::matrix_
SmallMat< space_dimT, hyEdge_dimT, map_float_t > matrix_
The matrix of the affine mapping from reference to physical element.
Definition: linear.hxx:42
Mapping::Linear::hyEdge_dim
static constexpr unsigned int hyEdge_dim()
Returns the template parameter representing the dimension of a hyperedge.
Definition: linear.hxx:26
Mapping::Linear::mat_r
const SmallSquareMat< hyEdge_dimT, map_float_t > & mat_r() const
Return matrix R of the QR decomposition.
Definition: linear.hxx:162
Mapping::Linear::Linear
Linear(const Point< space_dimT, map_float_t > &translation, const SmallMat< space_dimT, hyEdge_dimT, map_float_t > &matrix)
Construct affine-linear mapping.
Definition: linear.hxx:73
Mapping::Linear::matrix_column
SmallVec< space_dimT, map_float_t > matrix_column(const unsigned int col) const
Return vector representing matrix column of specified index.
Definition: linear.hxx:126
Mapping::Linear::translation
const SmallVec< space_dimT, map_float_t > & translation() const
Return shifting vector associated to affine-linear transformation.
Definition: linear.hxx:252
Mapping::Linear::mat_q
const SmallSquareMat< space_dimT, map_float_t > & mat_q() const
Return matrix Q of the QR decomposition.
Definition: linear.hxx:158
Mapping::Linear::outer_normal
SmallVec< space_dimT, map_float_t > outer_normal(const unsigned int index) const
Return outer normal of given index.
Definition: linear.hxx:238
Mapping::Linear::Linear
Linear()=default
Construct affine-linear mapping.
Mapping::Linear::functional_determinant_hyNode
map_float_t functional_determinant_hyNode(const unsigned int index) const
The functional determinant of the affine-linear mapping of a hypernode.
Definition: linear.hxx:108
Mapping::Linear
Mapping of a unit hypercube to a parallelotope — can also be used for simplices.
Definition: linear.hxx:18
Mapping::Linear::map_reference_to_physical
SmallMat< space_dimT, n_vec, map_float_t > map_reference_to_physical(const SmallMat< hyEdge_dimT, n_vec, map_float_t > &points) const
Map n_vec points from reference to physical element.
Definition: linear.hxx:138
Mapping::Linear::space_dim
static constexpr unsigned int space_dim()
Returns the template parameter representing the dimension of the space.
Definition: linear.hxx:32
Mapping::Linear::matrix_q_
SmallSquareMat< space_dimT, map_float_t > matrix_q_
Matrix Q of QR decomposition of the matrix of the affine transformation.
Definition: linear.hxx:48
scalar_product
mat_entry_t scalar_product(const SmallMat< n_rows, n_cols, mat_entry_t > &left, const SmallMat< n_rows, n_cols, mat_entry_t > &right)
Euclidean scalar product of two SmallVecs / Frobenius scalar product for two SmallMats.
Definition: dense_la.hxx:571
Mapping::Linear::translation_
SmallVec< space_dimT, map_float_t > translation_
The translation of the affine mapping from reference to physical element.
Definition: linear.hxx:38
Mapping
Namespace for mappings from reference elements to physical elements, etc.
Definition: linear.hxx:6
Mapping::Linear::matrix_r_
SmallSquareMat< hyEdge_dimT, map_float_t > matrix_r_
Matrix R of QR decomposition of the matrix of the affine transformation.
Definition: linear.hxx:60
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
qr_decomp_q
SmallMat< n_rows, n_rows, mat_entry_t > qr_decomp_q(SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Matrix Q of Householder QR decomposition.
Definition: dense_la.hxx:1009
SmallMat::get_column
SmallMat< n_rowsT, 1, mat_entry_t > get_column(const unsigned int col) const
Return a column of a SmallMat.
Definition: dense_la.hxx:206
determinant
mat_entry_t determinant(SmallMat< n_rows, n_cols, mat_entry_t > &mat)
Determinant of a rectangular system.
Definition: dense_la.hxx:1121
SmallMat::set_column
void set_column(const unsigned int col, const SmallMat< n_rowsT, 1, mat_entry_t > col_vec)
Set column of a SmallMat.
Definition: dense_la.hxx:220
SmallMat
This class implements a small/dense matrix.
Definition: dense_la.hxx:34