libMesh
tensor_tools.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_TENSOR_TOOLS_H
21 #define LIBMESH_TENSOR_TOOLS_H
22 
23 // Local includes
24 #include "libmesh/libmesh_common.h"
25 #include "libmesh/compare_types.h"
26 
27 #ifdef LIBMESH_HAVE_METAPHYSICL
28 namespace MetaPhysicL
29 {
30 template <typename, typename>
31 class DualNumber;
32 }
33 namespace std
34 {
35 template <typename T, typename D>
37 template <typename T, typename D>
39 }
40 #endif
41 
42 namespace libMesh
43 {
44 // Forward declarations
45 template <typename T> class TypeVector;
46 template <typename T> class VectorValue;
47 template <typename T> class TypeTensor;
48 template <typename T> class TensorValue;
49 template <unsigned int N, typename T> class TypeNTensor;
50 
51 namespace TensorTools
52 {
53 // Any tensor-rank-independent code will need to include
54 // tensor_tools.h, so we define a product/dot-product here, starting
55 // with the generic case to apply to scalars.
56 // Vector specializations will follow.
57 
58 template <typename T, typename T2>
59 inline
61  typename CompareTypes<T, T2>::supertype>::type
62 inner_product(const T & a, const T2& b)
63 { return a * b; }
64 
65 template <typename T, typename T2>
66 inline
69 { return a * b; }
70 
71 template <typename T, typename T2>
72 inline
75 { return a.contract(b); }
76 
77 template <unsigned int N, typename T, typename T2>
78 inline
81 { return a.contract(b); }
82 
83 template<typename T>
84 inline
85 T norm_sq(std::complex<T> a) { return std::norm(a); }
86 
87 template<typename T>
88 inline
89 auto norm_sq(const T & a) -> decltype(std::norm(a))
90 { return std::norm(a); }
91 
92 template <typename T>
93 inline
94 auto norm_sq(const TypeVector<T> & a) -> decltype(std::norm(T()))
95 {return a.norm_sq();}
96 
97 template <typename T>
98 inline
99 auto norm_sq(const VectorValue<T> & a) -> decltype(std::norm(T()))
100 {return a.norm_sq();}
101 
102 template<typename T>
103 inline
104 bool is_zero(const T & a){ return a.is_zero();}
105 
106 // Any tensor-rank-independent code will need to include
107 // tensor_tools.h, so we define rank-increasing and real-to-number type
108 // conversion functions here, starting with the generic case to apply
109 // to scalars.
110 // Tensor(and higher?) specializations will go in the tensor
111 // header(s).
112 template <typename T>
114 {
116 };
117 
118 template <typename T>
120 {
122 };
123 
124 
125 template <typename T>
127 {
129 };
130 
131 template <typename T>
133 {
135 };
136 
137 
138 template <typename T>
140 {
142 };
143 
144 template <unsigned int N, typename T>
146 {
148 };
149 
150 
151 // Also need rank-decreasing case
152 template <typename T>
154 {
155  // The default case is typically an error, but for simpler
156  // templated code we need it to be compatible with Number
157  // operations...
158  typedef T type;
159 };
160 
161 template <typename T>
163 {
164  typedef T type;
165 };
166 
167 template <typename T>
169 {
170  typedef T type;
171 };
172 
173 template <typename T>
175 {
177 };
178 
179 template <typename T>
181 {
183 };
184 
185 template <unsigned int N, typename T>
187 {
188  typedef TypeNTensor<N-1,T> type;
189 };
190 
191 // Handle the complex-valued case
192 template <typename T>
194 {
195 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
196  typedef std::complex<T> type;
197 #else
198  typedef T type;
199 #endif
200 };
201 
202 template <typename T>
203 struct MakeNumber<std::complex<T>>
204 {
205  // Compile-time error: we shouldn't need to make numbers out of
206  // numbers
207  //typedef std::complex<T> type;
208 };
209 
210 
211 template <typename T>
213 {
215 };
216 
217 template <typename T>
219 {
221 };
222 
223 template <typename T>
225 {
227 };
228 
229 template <typename T>
231 {
233 };
234 
235 template <unsigned int N, typename T>
237 {
238 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
240 #else
242 #endif
243 };
244 
245 // A utility for determining real-valued (e.g. shape function)
246 // types from corresponding complex-valued types
247 template <typename T>
248 struct MakeReal
249 {
250  typedef T type;
251 };
252 
253 template <typename T>
254 struct MakeReal<std::complex<T>>
255 {
256  typedef T type;
257 };
258 
259 template <typename T>
261 {
263 };
264 
265 template <typename T>
267 {
269 };
270 
271 template <typename T>
273 {
275 };
276 
277 template <typename T>
279 {
281 };
282 
283 template <unsigned int N, typename T>
284 struct MakeReal<TypeNTensor<N,T>>
285 {
287 };
288 
289 // Needed for ExactSolution to compile
291 
294 
298 
301 
304 
308 
309 }//namespace TensorTools
310 
311 }//namespace libMesh
312 
313 #endif // LIBMESH_TENSOR_TOOLS_H
Number div_from_grad(const VectorValue< Number > &grad)
Dummy. Divergence of a scalar not defined, but is needed for ExactSolution to compile.
TypeTensor< typename MakeNumber< T >::type > type
Definition: tensor_tools.h:232
bool is_zero(const T &a)
Definition: tensor_tools.h:104
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
TypeVector< typename MakeNumber< T >::type > type
Definition: tensor_tools.h:214
TypeTensor< typename MakeReal< T >::type > type
Definition: tensor_tools.h:280
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
Definition: tensor_tools.h:47
T norm_sq(std::complex< T > a)
Definition: tensor_tools.h:85
TypeVector< typename MakeReal< T >::type > type
Definition: tensor_tools.h:262
TypeTensor< typename MakeReal< T >::type > type
Definition: tensor_tools.h:274
VectorValue< typename MakeReal< T >::type > type
Definition: tensor_tools.h:268
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition: tensor_tools.h:45
TypeNTensor< N, typename MakeReal< T >::type > type
Definition: tensor_tools.h:286
CompareTypes< T, T2 >::supertype contract(const TypeTensor< T2 > &) const
Multiply 2 tensors together to return a scalar, i.e.
Definition: type_tensor.h:1264
This class will eventually define a rank-N tensor in LIBMESH_DIM dimensional space of type T...
Definition: tensor_tools.h:49
MetaPhysicL::DualNumber< T, D > norm(const MetaPhysicL::DualNumber< T, D > &in)
TypeTensor< typename MakeNumber< T >::type > type
Definition: tensor_tools.h:226
VectorValue< typename MakeNumber< T >::type > type
Definition: tensor_tools.h:220
boostcopy::enable_if_c< ScalarTraits< T >::value &&ScalarTraits< T2 >::value, typename CompareTypes< T, T2 >::supertype >::type inner_product(const T &a, const T2 &b)
Definition: tensor_tools.h:62
Number curl_from_grad(const VectorValue< Number > &)
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
CompareTypes< T, T2 >::supertype contract(const TypeNTensor< N, T2 > &) const
Multiply 2 tensors together to return a scalar, i.e.