libMesh
Loading...
Searching...
No Matches
tensor_value.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_VALUE_H
21#define LIBMESH_TENSOR_VALUE_H
22
23// Local includes
24#include "libmesh/type_tensor.h"
25#include "libmesh/libmesh_device.h"
26#include "libmesh/libmesh.h" // for pi
27
28#ifdef LIBMESH_HAVE_METAPHYSICL
29#include "metaphysicl/raw_type.h"
30#endif
31
32namespace libMesh
33{
34
44template <typename T>
45class TensorValue : public TypeTensor<T>
46{
47public:
48 typedef T value_type;
49
50 template <typename T2>
51 struct rebind
52 {
54 };
55
60 TensorValue ();
61
66 explicit TensorValue (const T & xx,
67 const T & xy=0,
68 const T & xz=0,
69 const T & yx=0,
70 const T & yy=0,
71 const T & yz=0,
72 const T & zx=0,
73 const T & zy=0,
74 const T & zz=0);
75
80 template <typename Scalar>
81 explicit TensorValue (const Scalar & xx,
82 const Scalar & xy=0,
83 const Scalar & xz=0,
84 const Scalar & yx=0,
85 const Scalar & yy=0,
86 const Scalar & yz=0,
87 const Scalar & zx=0,
88 const Scalar & zy=0,
89 typename
90 std::enable_if<ScalarTraits<Scalar>::value,
91 const Scalar>::type & zz=0);
92
96 template <typename T2>
97 LIBMESH_DEVICE_INLINE
98 TensorValue (const TypeVector<T2> & vx);
99
103 template <typename T2>
104 LIBMESH_DEVICE_INLINE
105 TensorValue (const TypeVector<T2> & vx,
106 const TypeVector<T2> & vy);
107
111 template <typename T2>
112 LIBMESH_DEVICE_INLINE
113 TensorValue (const TypeVector<T2> & vx,
114 const TypeVector<T2> & vy,
115 const TypeVector<T2> & vz);
116
117
121 template <typename T2>
123
127 template <typename T2>
129
130
131#ifdef LIBMESH_USE_COMPLEX_NUMBERS
137 TensorValue (const TypeTensor<Real> & p_re,
138 const TypeTensor<Real> & p_im);
139#endif
140
144 template <typename Scalar>
145 LIBMESH_DEVICE_INLINE
146 typename std::enable_if<
148 TensorValue &>::type
149 operator = (const Scalar & libmesh_dbg_var(p) )
150 { libmesh_assert_equal_to (p, Scalar(0)); this->zero(); return *this; }
151
172
179
193 static TensorValue<Real>
194 extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg);
195
200 static TensorValue<Real>
201 inverse_extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg);
202};
203
208typedef TensorValue<Real> RealTensorValue;
209typedef TensorValue<Number> NumberTensorValue;
212
213
214
215//------------------------------------------------------
216// Inline functions
217template <typename T>
218LIBMESH_DEVICE_INLINE
223
224
225
226template <typename T>
227LIBMESH_DEVICE_INLINE
229 const T & xy,
230 const T & xz,
231 const T & yx,
232 const T & yy,
233 const T & yz,
234 const T & zx,
235 const T & zy,
236 const T & zz) :
237 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
238{
239}
240
241
242template <typename T>
243template <typename Scalar>
244LIBMESH_DEVICE_INLINE
246 const Scalar & xy,
247 const Scalar & xz,
248 const Scalar & yx,
249 const Scalar & yy,
250 const Scalar & yz,
251 const Scalar & zx,
252 const Scalar & zy,
253 typename
254 std::enable_if<ScalarTraits<Scalar>::value,
255 const Scalar>::type & zz) :
256 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
257{
258}
259
260
261
262template <typename T>
263template <typename T2>
264LIBMESH_DEVICE_INLINE
266 TypeTensor<T> (p)
267{
268}
269
270
271
272template <typename T>
273template <typename T2>
274LIBMESH_DEVICE_INLINE
276 TypeTensor<T> (vx)
277{
278}
279
280
281
282template <typename T>
283template <typename T2>
284LIBMESH_DEVICE_INLINE
286 const TypeVector<T2> & vy) :
287 TypeTensor<T> (vx, vy)
288{
289}
290
291
292
293template <typename T>
294template <typename T2>
295LIBMESH_DEVICE_INLINE
297 const TypeVector<T2> & vy,
298 const TypeVector<T2> & vz) :
299 TypeTensor<T> (vx, vy, vz)
300{
301}
302
303
304
305template <typename T>
306template <typename T2>
307LIBMESH_DEVICE_INLINE
309 TypeTensor<T> (p)
310{
311}
312
313
314#ifdef LIBMESH_USE_COMPLEX_NUMBERS
315template <typename T>
316LIBMESH_DEVICE_INLINE
318 const TypeTensor<Real> & p_im) :
319 TypeTensor<T> (Complex (p_re(0,0), p_im(0,0)),
320 Complex (p_re(0,1), p_im(0,1)),
321 Complex (p_re(0,2), p_im(0,2)),
322 Complex (p_re(1,0), p_im(1,0)),
323 Complex (p_re(1,1), p_im(1,1)),
324 Complex (p_re(1,2), p_im(1,2)),
325 Complex (p_re(2,0), p_im(2,0)),
326 Complex (p_re(2,1), p_im(2,1)),
327 Complex (p_re(2,2), p_im(2,2)))
328{
329}
330#endif
331
332template <typename T>
334TensorValue<T>::intrinsic_rotation_matrix(const Real phi, const Real theta, const Real psi)
335{
336#if LIBMESH_DIM == 3
337 // We apply a negative sign here or else we don't get the appearance of
338 // counter-clockwise/right-hand-rule rotation of the bodies with respect to the coordinate axes
339 // (but as explained in the method doxygen we are *actually* rotating the coordinate axes while
340 // leaving the bodies fixed)
341 const Real p = -phi / 180. * pi;
342 const Real t = -theta / 180. * pi;
343 const Real s = -psi / 180. * pi;
344 const Real sp = std::sin(p), cp = std::cos(p);
345 const Real st = std::sin(t), ct = std::cos(t);
346 const Real ss = std::sin(s), cs = std::cos(s);
347
348 return TensorValue<Real>(cp * cs - sp * ct * ss,
349 sp * cs + cp * ct * ss,
350 st * ss,
351 -cp * ss - sp * ct * cs,
352 -sp * ss + cp * ct * cs,
353 st * cs,
354 sp * st,
355 -cp * st,
356 ct);
357#else
358 libmesh_ignore(phi, theta, psi);
359 libmesh_error_msg("TensorValue<T>::intrinsic_rotation_matrix() requires libMesh to be compiled "
360 "with LIBMESH_DIM==3");
361 // We'll never get here
362 return TensorValue<Real>();
363#endif
364}
365
366template <typename T>
369{
370 // The inverse of a rotation matrix is just the transpose
372}
373
374template <typename T>
377 const Real angle2_deg,
378 const Real angle3_deg)
379{
380#if LIBMESH_DIM == 3
381 const auto angle1 = angle1_deg / 180. * pi;
382 const auto angle2 = angle2_deg / 180. * pi;
383 const auto angle3 = angle3_deg / 180. * pi;
384 const auto s1 = std::sin(angle1), c1 = std::cos(angle1);
385 const auto s2 = std::sin(angle2), c2 = std::cos(angle2);
386 const auto s3 = std::sin(angle3), c3 = std::cos(angle3);
387
388 return TensorValue<Real>(c1 * c3 - c2 * s1 * s3,
389 -c1 * s3 - c2 * c3 * s1,
390 s1 * s2,
391 c3 * s1 + c1 * c2 * s3,
392 c1 * c2 * c3 - s1 * s3,
393 -c1 * s2,
394 s2 * s3,
395 c3 * s2,
396 c2);
397#else
398 libmesh_ignore(angle1_deg, angle2_deg, angle3_deg);
399 libmesh_error_msg("TensorValue<T>::extrinsic_rotation_matrix() requires libMesh to be compiled "
400 "with LIBMESH_DIM==3");
401 // We'll never get here
402 return TensorValue<Real>();
403#endif
404}
405
406template <typename T>
409 const Real angle2_deg,
410 const Real angle3_deg)
411{
412 // The inverse of a rotation matrix is just the transpose
413 return TensorValue<T>::extrinsic_rotation_matrix(angle1_deg, angle2_deg, angle3_deg).transpose();
414}
415
416} // namespace libMesh
417
418#ifdef LIBMESH_HAVE_METAPHYSICL
419namespace MetaPhysicL
420{
421template <typename T>
422struct RawType<libMesh::TensorValue<T>>
423{
425
427 {
428 value_type ret;
429 for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
430 for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
431 ret(i,j) = raw_value(in(i,j));
432
433 return ret;
434 }
435};
436
437template <typename T, typename U>
438struct ReplaceAlgebraicType<libMesh::TensorValue<T>, U>
439{
440 typedef U type;
441};
442}
443#endif
444
445#endif // LIBMESH_TENSOR_VALUE_H
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
static TensorValue< Real > extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg)
Generate the extrinsic rotation matrix associated with the provided Euler angles.
TensorValue(const Scalar &xx, const Scalar &xy=0, const Scalar &xz=0, const Scalar &yx=0, const Scalar &yy=0, const Scalar &yz=0, const Scalar &zx=0, const Scalar &zy=0, typename std::enable_if< ScalarTraits< Scalar >::value, const Scalar >::type &zz=0)
Constructor-from-scalars.
static TensorValue< Real > inverse_extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg)
Invert the rotation that would occur if the same angles were provided to extrinsic_rotation_matrix,...
static TensorValue< Real > inverse_intrinsic_rotation_matrix(Real phi, Real theta, Real psi)
Invert the rotation that would occur if the same angles were provided to intrinsic_rotation_matrix,...
TensorValue(const TypeTensor< T2 > &p)
Copy-constructor.
TensorValue(const TensorValue< T2 > &p)
Copy-constructor.
TensorValue()
Empty constructor.
LIBMESH_DEVICE_INLINE std::enable_if< ScalarTraits< Scalar >::value, TensorValue & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.
static TensorValue< Real > intrinsic_rotation_matrix(Real phi, Real theta, Real psi)
Generate the intrinsic rotation matrix associated with the provided Euler angles.
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
Definition type_tensor.h:54
TypeTensor< T > transpose() const
LIBMESH_DEVICE_INLINE void zero()
Set all entries of the tensor to 0.
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition type_vector.h:64
The libMesh namespace provides an interface to certain functionality in the library.
TensorValue< Number > NumberTensorValue
std::complex< Real > Complex
void libmesh_ignore(const Args &...)
TensorValue< Real > RealTensorValue
Useful typedefs to allow transparent switching between Real and Complex data types.
NumberTensorValue Tensor
const Real pi
.
Definition libmesh.h:292
RealTensorValue RealTensor
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
libMesh::TensorValue< typename RawType< T >::value_type > value_type
static value_type value(const libMesh::TensorValue< T > &in)