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.h" // for pi
26
27#ifdef LIBMESH_HAVE_METAPHYSICL
28#include "metaphysicl/raw_type.h"
29#endif
30
31namespace libMesh
32{
33
43template <typename T>
44class TensorValue : public TypeTensor<T>
45{
46public:
47 typedef T value_type;
48
49 template <typename T2>
50 struct rebind
51 {
53 };
54
59 TensorValue ();
60
65 explicit TensorValue (const T & xx,
66 const T & xy=0,
67 const T & xz=0,
68 const T & yx=0,
69 const T & yy=0,
70 const T & yz=0,
71 const T & zx=0,
72 const T & zy=0,
73 const T & zz=0);
74
79 template <typename Scalar>
80 explicit TensorValue (const Scalar & xx,
81 const Scalar & xy=0,
82 const Scalar & xz=0,
83 const Scalar & yx=0,
84 const Scalar & yy=0,
85 const Scalar & yz=0,
86 const Scalar & zx=0,
87 const Scalar & zy=0,
88 typename
89 std::enable_if<ScalarTraits<Scalar>::value,
90 const Scalar>::type & zz=0);
91
95 template <typename T2>
96 TensorValue (const TypeVector<T2> & vx);
97
101 template <typename T2>
102 TensorValue (const TypeVector<T2> & vx,
103 const TypeVector<T2> & vy);
104
108 template <typename T2>
109 TensorValue (const TypeVector<T2> & vx,
110 const TypeVector<T2> & vy,
111 const TypeVector<T2> & vz);
112
113
117 template <typename T2>
118 TensorValue (const TensorValue<T2> & p);
119
123 template <typename T2>
124 TensorValue (const TypeTensor<T2> & p);
125
126
127#ifdef LIBMESH_USE_COMPLEX_NUMBERS
133 TensorValue (const TypeTensor<Real> & p_re,
134 const TypeTensor<Real> & p_im);
135#endif
136
137
141 template <typename Scalar>
142 typename std::enable_if<
144 TensorValue &>::type
145 operator = (const Scalar & libmesh_dbg_var(p) )
146 { libmesh_assert_equal_to (p, Scalar(0)); this->zero(); return *this; }
147
168
175
189 static TensorValue<Real>
190 extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg);
191
196 static TensorValue<Real>
197 inverse_extrinsic_rotation_matrix(Real angle1_deg, Real angle2_deg, Real angle3_deg);
198};
199
204typedef TensorValue<Real> RealTensorValue;
205typedef TensorValue<Number> NumberTensorValue;
208
209
210
211//------------------------------------------------------
212// Inline functions
213template <typename T>
214inline
219
220
221
222template <typename T>
223inline
225 const T & xy,
226 const T & xz,
227 const T & yx,
228 const T & yy,
229 const T & yz,
230 const T & zx,
231 const T & zy,
232 const T & zz) :
233 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
234{
235}
236
237
238template <typename T>
239template <typename Scalar>
240inline
242 const Scalar & xy,
243 const Scalar & xz,
244 const Scalar & yx,
245 const Scalar & yy,
246 const Scalar & yz,
247 const Scalar & zx,
248 const Scalar & zy,
249 typename
250 std::enable_if<ScalarTraits<Scalar>::value,
251 const Scalar>::type & zz) :
252 TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
253{
254}
255
256
257
258template <typename T>
259template <typename T2>
260inline
262 TypeTensor<T> (p)
263{
264}
265
266
267
268template <typename T>
269template <typename T2>
270inline
272 TypeTensor<T> (vx)
273{
274}
275
276
277
278template <typename T>
279template <typename T2>
280inline
282 const TypeVector<T2> & vy) :
283 TypeTensor<T> (vx, vy)
284{
285}
286
287
288
289template <typename T>
290template <typename T2>
291inline
293 const TypeVector<T2> & vy,
294 const TypeVector<T2> & vz) :
295 TypeTensor<T> (vx, vy, vz)
296{
297}
298
299
300
301template <typename T>
302template <typename T2>
303inline
305 TypeTensor<T> (p)
306{
307}
308
309
310#ifdef LIBMESH_USE_COMPLEX_NUMBERS
311template <typename T>
312inline
314 const TypeTensor<Real> & p_im) :
315 TypeTensor<T> (Complex (p_re(0,0), p_im(0,0)),
316 Complex (p_re(0,1), p_im(0,1)),
317 Complex (p_re(0,2), p_im(0,2)),
318 Complex (p_re(1,0), p_im(1,0)),
319 Complex (p_re(1,1), p_im(1,1)),
320 Complex (p_re(1,2), p_im(1,2)),
321 Complex (p_re(2,0), p_im(2,0)),
322 Complex (p_re(2,1), p_im(2,1)),
323 Complex (p_re(2,2), p_im(2,2)))
324{
325}
326#endif
327
328template <typename T>
330TensorValue<T>::intrinsic_rotation_matrix(const Real phi, const Real theta, const Real psi)
331{
332#if LIBMESH_DIM == 3
333 // We apply a negative sign here or else we don't get the appearance of
334 // counter-clockwise/right-hand-rule rotation of the bodies with respect to the coordinate axes
335 // (but as explained in the method doxygen we are *actually* rotating the coordinate axes while
336 // leaving the bodies fixed)
337 const Real p = -phi / 180. * pi;
338 const Real t = -theta / 180. * pi;
339 const Real s = -psi / 180. * pi;
340 const Real sp = std::sin(p), cp = std::cos(p);
341 const Real st = std::sin(t), ct = std::cos(t);
342 const Real ss = std::sin(s), cs = std::cos(s);
343
344 return TensorValue<Real>(cp * cs - sp * ct * ss,
345 sp * cs + cp * ct * ss,
346 st * ss,
347 -cp * ss - sp * ct * cs,
348 -sp * ss + cp * ct * cs,
349 st * cs,
350 sp * st,
351 -cp * st,
352 ct);
353#else
354 libmesh_ignore(phi, theta, psi);
355 libmesh_error_msg("TensorValue<T>::intrinsic_rotation_matrix() requires libMesh to be compiled "
356 "with LIBMESH_DIM==3");
357 // We'll never get here
358 return TensorValue<Real>();
359#endif
360}
361
362template <typename T>
365{
366 // The inverse of a rotation matrix is just the transpose
368}
369
370template <typename T>
373 const Real angle2_deg,
374 const Real angle3_deg)
375{
376#if LIBMESH_DIM == 3
377 const auto angle1 = angle1_deg / 180. * pi;
378 const auto angle2 = angle2_deg / 180. * pi;
379 const auto angle3 = angle3_deg / 180. * pi;
380 const auto s1 = std::sin(angle1), c1 = std::cos(angle1);
381 const auto s2 = std::sin(angle2), c2 = std::cos(angle2);
382 const auto s3 = std::sin(angle3), c3 = std::cos(angle3);
383
384 return TensorValue<Real>(c1 * c3 - c2 * s1 * s3,
385 -c1 * s3 - c2 * c3 * s1,
386 s1 * s2,
387 c3 * s1 + c1 * c2 * s3,
388 c1 * c2 * c3 - s1 * s3,
389 -c1 * s2,
390 s2 * s3,
391 c3 * s2,
392 c2);
393#else
394 libmesh_ignore(angle1_deg, angle2_deg, angle3_deg);
395 libmesh_error_msg("TensorValue<T>::extrinsic_rotation_matrix() requires libMesh to be compiled "
396 "with LIBMESH_DIM==3");
397 // We'll never get here
398 return TensorValue<Real>();
399#endif
400}
401
402template <typename T>
405 const Real angle2_deg,
406 const Real angle3_deg)
407{
408 // The inverse of a rotation matrix is just the transpose
409 return TensorValue<T>::extrinsic_rotation_matrix(angle1_deg, angle2_deg, angle3_deg).transpose();
410}
411
412} // namespace libMesh
413
414#ifdef LIBMESH_HAVE_METAPHYSICL
415namespace MetaPhysicL
416{
417template <typename T>
418struct RawType<libMesh::TensorValue<T>>
419{
421
423 {
424 value_type ret;
425 for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
426 for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
427 ret(i,j) = raw_value(in(i,j));
428
429 return ret;
430 }
431};
432
433template <typename T, typename U>
434struct ReplaceAlgebraicType<libMesh::TensorValue<T>, U>
435{
436 typedef U type;
437};
438}
439#endif
440
441#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.
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,...
std::enable_if< ScalarTraits< Scalar >::value, TensorValue & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.
TensorValue()
Empty constructor.
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,...
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:53
void zero()
Set all entries of the tensor to 0.
TypeTensor< T > transpose() const
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition type_vector.h:63
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)