libMesh
Loading...
Searching...
No Matches
tensor_tools.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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#include "metaphysicl/dualnumber_decl.h"
29#endif
30
31namespace libMesh
32{
33// Forward declarations
34template <typename T> class TypeVector;
35template <typename T> class VectorValue;
36template <typename T> class TypeTensor;
37template <typename T> class TensorValue;
38template <unsigned int N, typename T> class TypeNTensor;
39
40namespace TensorTools
41{
42// Any tensor-rank-independent code will need to include
43// tensor_tools.h, so we define a product/dot-product here, starting
44// with the generic case to apply to scalars.
45// Vector specializations will follow.
46
47template <typename T, typename T2>
48inline
49typename std::enable_if<ScalarTraits<T>::value && ScalarTraits<T2>::value,
50 typename CompareTypes<T, T2>::supertype>::type
51inner_product(const T & a, const T2& b)
52{ return a * b; }
53
54template <typename T, typename T2>
55inline
58{ return a * b; }
59
60template <typename T, typename T2>
61inline
64{ return a.contract(b); }
65
66template <unsigned int N, typename T, typename T2>
67inline
70{ return a.contract(b); }
71
72template<typename T>
73inline
74auto norm(const T & a)
75{ using std::abs; return abs(a); }
76
77template<typename T>
78inline
79T norm(std::complex<T> a) { using std::abs; return abs(a); }
80
81template <typename T>
82inline
83auto norm(const TypeVector<T> & a) -> decltype(TensorTools::norm(T()))
84{using std::sqrt; return sqrt(a.norm_sq());}
85
86template <typename T>
87inline
88auto norm(const VectorValue<T> & a) -> decltype(TensorTools::norm(T()))
89{using std::sqrt; return sqrt(a.norm_sq());}
90
91template <typename T>
92inline
93auto norm(const TypeTensor<T> & a) -> decltype(TensorTools::norm(T()))
94{using std::sqrt; return sqrt(a.norm_sq());}
95
96template <typename T>
97inline
98auto norm(const TensorValue<T> & a) -> decltype(TensorTools::norm(T()))
99{using std::sqrt; return sqrt(a.norm_sq());}
100
101
102template<typename T>
103inline
104auto norm_sq(const T & a)
105{ using std::norm; return norm(a); }
106
107template<typename T>
108inline
109T norm_sq(std::complex<T> a) { using std::norm; return norm(a); }
110
111template <typename T>
112inline
113auto norm_sq(const TypeVector<T> & a)
114{return a.norm_sq();}
115
116template <typename T>
117inline
118auto norm_sq(const VectorValue<T> & a)
119{return a.norm_sq();}
120
121template <typename T>
122inline
123auto norm_sq(const TypeTensor<T> & a)
124{return a.norm_sq();}
125
126template <typename T>
127inline
128auto norm_sq(const TensorValue<T> & a)
129{return a.norm_sq();}
130
131
132template<typename T>
133inline
134bool is_zero(const T & a){ return a.is_zero();}
135
136// Any tensor-rank-independent code will need to include
137// tensor_tools.h, so we define rank-increasing and real-to-number type
138// conversion functions here, starting with the generic case to apply
139// to scalars.
140// Tensor(and higher?) specializations will go in the tensor
141// header(s).
142template <typename T>
144{
146};
147
148template <typename T>
150{
152};
153
154
155template <typename T>
157{
159};
160
161template <typename T>
163{
165};
166
167
168template <typename T>
170{
172};
173
174template <unsigned int N, typename T>
176{
178};
179
180
181// Also need rank-decreasing case
182template <typename T>
184{
185 // The default case is typically an error, but for simpler
186 // templated code we need it to be compatible with Number
187 // operations...
188 typedef T type;
189};
190
191template <typename T>
193{
194 typedef T type;
195};
196
197template <typename T>
199{
200 typedef T type;
201};
202
203template <typename T>
205{
207};
208
209template <typename T>
211{
213};
214
215template <unsigned int N, typename T>
217{
218 typedef TypeNTensor<N-1,T> type;
219};
220
221// Handle the complex-valued case
222template <typename T>
224{
225#ifdef LIBMESH_USE_COMPLEX_NUMBERS
226 typedef std::complex<T> type;
227#else
228 typedef T type;
229#endif
230};
231
232template <typename T>
233struct MakeNumber<std::complex<T>>
234{
235 // Should this be a compile-time error? we shouldn't need to make numbers out of
236 // numbers, but then again having the typedef below enables more generic
237 // programming
238 typedef std::complex<T> type;
239};
240
241
242template <typename T>
247
248template <typename T>
253
254template <typename T>
259
260template <typename T>
265
266template <unsigned int N, typename T>
268{
269#ifdef LIBMESH_USE_COMPLEX_NUMBERS
271#else
273#endif
274};
275
276// A utility for determining real-valued (e.g. shape function)
277// types from corresponding complex-valued types
278template <typename T>
280{
281 typedef T type;
282};
283
284template <typename T>
285struct MakeReal<std::complex<T>>
286{
287 typedef T type;
288};
289
290template <typename T>
295
296template <typename T>
301
302template <typename T>
307
308template <typename T>
313
314template <unsigned int N, typename T>
319
320// Needed for ExactSolution to compile
322
325
329
332
335
339
344template <typename T>
346{
347 static constexpr bool value = false;
348};
349
350template <typename T>
352{
353 static constexpr bool value = true;
354};
355
356template <typename T>
358{
359 static constexpr bool value = true;
360};
361
362template <typename T>
364{
365 static constexpr bool value = true;
366};
367
368template <typename T>
370{
371 static constexpr bool value = true;
372};
373
374template <unsigned int N, typename T>
376{
377 static constexpr bool value = true;
378};
379
380template <typename T, typename enable = void> struct MakeBaseNumber {};
381
382template <typename T>
383struct MakeBaseNumber<T, typename std::enable_if<ScalarTraits<T>::value>::type> {
384 typedef typename MakeNumber<T>::type type;
385};
386
387template <template <typename> class Wrapper, typename T>
389 Wrapper<T>,
390 typename std::enable_if<MathWrapperTraits<Wrapper<T>>::value>::type> {
392};
393
394template <typename T, typename Enable = void>
396{
397 static_assert(always_false<T>,
398 "Instantiating the generic template of TensorTraits. You must specialize "
399 "TensorTraits for your type.");
400 static constexpr unsigned char rank = 0;
401};
402
403template <typename T>
404struct TensorTraits<T, typename std::enable_if<ScalarTraits<T>::value>::type>
405{
406 static constexpr unsigned char rank = 0;
407};
408
409template <typename T>
411{
412 static constexpr unsigned char rank = 1;
413};
414
415template <typename T>
417{
418 static constexpr unsigned char rank = 1;
419};
420
421template <typename T>
423{
424 static constexpr unsigned char rank = 2;
425};
426
427template <typename T>
429{
430 static constexpr unsigned char rank = 2;
431};
432
433template <typename T, unsigned int N>
435{
436 static constexpr unsigned char rank = static_cast<unsigned char>(N);
437};
438
439}//namespace TensorTools
440
441}//namespace libMesh
442
443#endif // LIBMESH_TENSOR_TOOLS_H
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
This class will eventually define a rank-N tensor in LIBMESH_DIM dimensional space of type T.
CompareTypes< T, T2 >::supertype contract(const TypeNTensor< N, T2 > &) const
Multiply 2 tensors together to return a scalar, i.e.
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
Definition type_tensor.h:53
auto norm_sq() const
CompareTypes< T, T2 >::supertype contract(const TypeTensor< T2 > &) const
Multiply 2 tensors together to return a scalar, i.e.
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition type_vector.h:63
auto norm_sq() const
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
static const Real b
bool is_zero(const T &a)
Number curl_from_grad(const VectorValue< Number > &)
auto norm(const T &a)
auto norm_sq(const T &a)
std::enable_if< ScalarTraits< T >::value &&ScalarTraits< T2 >::value, typenameCompareTypes< T, T2 >::supertype >::type inner_product(const T &a, const T2 &b)
Number div_from_grad(const VectorValue< Number > &grad)
Dummy. Divergence of a scalar not defined, but is needed for ExactSolution to compile.
The libMesh namespace provides an interface to certain functionality in the library.
auto norm(const libMesh::TypeVector< T > &vector) -> decltype(std::norm(T()))
TypeTensor< typename MakeNumber< T >::type > type
TypeTensor< typename MakeNumber< T >::type > type
TypeVector< typename MakeNumber< T >::type > type
VectorValue< typename MakeNumber< T >::type > type
TypeTensor< typename MakeReal< T >::type > type
TypeNTensor< N, typename MakeReal< T >::type > type
TypeTensor< typename MakeReal< T >::type > type
TypeVector< typename MakeReal< T >::type > type
VectorValue< typename MakeReal< T >::type > type
This helper structure is used to determine whether a template class is one of our mathematical struct...
static constexpr unsigned char rank