Flow123d  DF_patch_fe_data_tables-836d647
fem_tools.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file mapping.hh
15  * @brief Class Mapping calculates data related to the mapping
16  * of the reference cell to the actual cell, such as Jacobian
17  * and normal vectors.
18  * @author Jan Stebel
19  */
20 
21 #ifndef MAPPING_HH_
22 #define MAPPING_HH_
23 
24 #include <armadillo>
25 #include <vector>
26 #include <limits>
27 #include "system/fmt/posix.h" // for FMT_UNUSED
28 
29 
30 
31 
32 namespace fe_tools {
33 
34 
35 
36 /**
37  * @brief Calculates determinant of a rectangular matrix.
38  */
39 template<class T>
40 double determinant(const T &M);
41 
42 
43 
44 inline arma::mat::fixed<1,1> normal_matrix(const arma::mat::fixed<1,2> &A) {
45  arma::mat::fixed<1,1> res;
46  res(0,0) = A(0,0)*A(0,0)+A(0,1)*A(0,1);
47  return res;
48 }
49 
50 inline arma::mat::fixed<1,1> normal_matrix(const arma::mat::fixed<2,1> &A) {
51  arma::mat::fixed<1,1> res;
52  res(0,0) = A(0,0)*A(0,0)+A(1,0)*A(1,0);
53  return res;
54 }
55 
56 inline arma::mat::fixed<1,1> normal_matrix(const arma::mat::fixed<1,3> &A) {
57  arma::mat::fixed<1,1> res;
58  res(0,0) = A(0,0)*A(0,0)+A(0,1)*A(0,1)+A(0,2)*A(0,2);
59  return res;
60 }
61 
62 inline arma::mat::fixed<1,1> normal_matrix(const arma::mat::fixed<3,1> &A) {
63  arma::mat::fixed<1,1> res;
64  res(0,0) = A(0,0)*A(0,0)+A(1,0)*A(1,0)+A(2,0)*A(2,0);
65  return res;
66 }
67 
68 inline arma::mat::fixed<2,2> normal_matrix(const arma::mat::fixed<2,3> &A) {
69  arma::mat::fixed<2,2> res;
70  res(0,0) = A(0,0)*A(0,0)+A(0,1)*A(0,1)+A(0,2)*A(0,2);
71  res(0,1) = A(0,0)*A(1,0)+A(0,1)*A(1,1)+A(0,2)*A(1,2);
72  res(1,0) = A(1,0)*A(0,0)+A(1,1)*A(0,1)+A(1,2)*A(0,2);
73  res(1,1) = A(1,0)*A(1,0)+A(1,1)*A(1,1)+A(1,2)*A(1,2);
74  return res;
75 }
76 
77 inline arma::mat::fixed<2,2> normal_matrix(const arma::mat::fixed<3,2> &A) {
78  arma::mat::fixed<2,2> res;
79  res(0,0) = A(0,0)*A(0,0)+A(1,0)*A(1,0)+A(2,0)*A(2,0);
80  res(0,1) = A(0,0)*A(0,1)+A(1,0)*A(1,1)+A(2,0)*A(2,1);
81  res(1,0) = A(0,1)*A(0,0)+A(1,1)*A(1,0)+A(2,1)*A(2,0);
82  res(1,1) = A(0,1)*A(0,1)+A(1,1)*A(1,1)+A(2,1)*A(2,1);
83  return res;
84 }
85 
86 
87 
88 template<> inline double determinant(const arma::mat::fixed<1,1> &M)
89 {
90  return M(0,0);
91 }
92 
93 template<> inline double determinant(const arma::mat::fixed<2,2> &M)
94 {
95  return M(0,0)*M(1,1) - M(1,0)*M(0,1);
96 }
97 
98 template<> inline double determinant(const arma::mat::fixed<3,3> &M)
99 {
100  return ( M(0,0)*M(1,1)*M(2,2) + M(0,1)*M(1,2)*M(2,0) + M(0,2)*M(1,0)*M(2,1) )
101  - ( M(2,0)*M(1,1)*M(0,2) + M(2,1)*M(1,2)*M(0,0) + M(2,2)*M(1,0)*M(0,1) );
102 }
103 
104 template<> inline double determinant(FMT_UNUSED const arma::mat::fixed<0,3> &M)
105 {
106  return 0;
107 }
108 
109 template<> inline double determinant(FMT_UNUSED const arma::mat::fixed<3,0> &M)
110 {
111  return 0;
112 }
113 
114 template<> inline double determinant(const arma::mat::fixed<1,2> &M)
115 {
116  return sqrt( determinant(normal_matrix(M)) );
117 }
118 
119 template<> inline double determinant(const arma::mat::fixed<2,1> &M)
120 {
121  return sqrt( determinant(normal_matrix(M)) );
122 }
123 
124 template<> inline double determinant(const arma::mat::fixed<1,3> &M)
125 {
126  return sqrt( determinant(normal_matrix(M)) );
127 }
128 
129 template<> inline double determinant(const arma::mat::fixed<3,1> &M)
130 {
131  return sqrt( determinant(normal_matrix(M)) );
132 }
133 
134 template<> inline double determinant(const arma::mat::fixed<2,3> &M)
135 {
136  return sqrt( determinant(normal_matrix(M)) );
137 }
138 
139 template<> inline double determinant(const arma::mat::fixed<3,2> &M)
140 {
141  return sqrt( determinant(normal_matrix(M)) );
142 }
143 
144 
145 /**
146  * @brief Calculates inverse of rectangular matrix or pseudoinverse of non-rectangular matrix.
147  */
148 template<arma::uword m, arma::uword n>
149 arma::mat::fixed<n,m> inverse(const arma::mat::fixed<m,n> &A) {
150  if (m<n) return A.t() * inverse(normal_matrix(A));
151  else return inverse(normal_matrix(A)) * A.t();
152 }
153 
154 
155 template<> inline arma::mat::fixed<1,1> inverse(const arma::mat::fixed<1,1> &A)
156 {
157  arma::mat::fixed<1,1> B;
158  B(0,0) = 1/A(0,0);
159  return B;
160 }
161 
162 template<> inline arma::mat::fixed<2,2> inverse(const arma::mat::fixed<2,2> &A)
163 {
164  arma::mat::fixed<2,2> B;
165  double det = determinant(A);
166 
167  B(0,0) = A(1,1) / det;
168  B(0,1) = -A(0,1) / det;
169  B(1,0) = -A(1,0) / det;
170  B(1,1) = A(0,0) / det;
171  return B;
172 }
173 
174 template<> inline arma::mat::fixed<3,3> inverse(const arma::mat::fixed<3,3> &A)
175 {
176  arma::mat::fixed<3,3> B;
177 
178  B(0,0) = A(1,1)*A(2,2) - A(2,1)*A(1,2);
179  B(1,0) = -A(1,0)*A(2,2) + A(2,0)*A(1,2);
180  B(2,0) = A(1,0)*A(2,1) - A(2,0)*A(1,1);
181 
182  double det = A(0,0)*B(0,0) + A(0,1)*B(1,0) + A(0,2)*B(2,0);
183  B(0,0)/=det; B(1,0)/=det; B(2,0)/=det;
184 
185  B(0,1) = (-A(0,1)*A(2,2) + A(2,1)*A(0,2)) / det;
186  B(1,1) = (A(0,0)*A(2,2) - A(2,0)*A(0,2)) / det;
187  B(2,1) = (-A(0,0)*A(2,1) + A(2,0)*A(0,1)) / det;
188 
189  B(0,2) = (A(0,1)*A(1,2) - A(1,1)*A(0,2)) / det;
190  B(1,2) = (-A(0,0)*A(1,2) + A(1,0)*A(0,2)) / det;
191  B(2,2) = (A(0,0)*A(1,1) - A(1,0)*A(0,1)) / det;
192 
193  return B;
194 }
195 
196 
197 } // closing namespace fe_tools
198 
199 
200 
201 #endif /* MAPPING_HH_ */
arma::mat::fixed< n, m > inverse(const arma::mat::fixed< m, n > &A)
Calculates inverse of rectangular matrix or pseudoinverse of non-rectangular matrix.
Definition: fem_tools.hh:149
arma::mat::fixed< 1, 1 > normal_matrix(const arma::mat::fixed< 1, 2 > &A)
Definition: fem_tools.hh:44
double determinant(const T &M)
Calculates determinant of a rectangular matrix.
#define FMT_UNUSED
Definition: posix.h:75