Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
tensor_value.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 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 
31 namespace libMesh
32 {
33 
43 template <typename T>
44 class TensorValue : public TypeTensor<T>
45 {
46 public:
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
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
128 
133  TensorValue (const TypeTensor<Real> & p_re,
134  const TypeTensor<Real> & p_im);
135 #endif
136 
137 
141  template <typename Scalar>
142  typename boostcopy::enable_if_c<
144  TensorValue &>::type
145  operator = (const Scalar & libmesh_dbg_var(p) )
146  { libmesh_assert_equal_to (p, Scalar(0)); this->zero(); return *this; }
147 
167  static TensorValue<Real> intrinsic_rotation_matrix(Real phi, Real theta, Real psi);
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 
204 typedef TensorValue<Real> RealTensorValue;
205 typedef TensorValue<Number> NumberTensorValue;
207 typedef NumberTensorValue Tensor;
208 
209 
210 
211 //------------------------------------------------------
212 // Inline functions
213 template <typename T>
214 inline
216  TypeTensor<T> ()
217 {
218 }
219 
220 
221 
222 template <typename T>
223 inline
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 
238 template <typename T>
239 template <typename Scalar>
240 inline
241 TensorValue<T>::TensorValue (const Scalar & xx,
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
251  const Scalar>::type & zz) :
252  TypeTensor<T> (xx,xy,xz,yx,yy,yz,zx,zy,zz)
253 {
254 }
255 
256 
257 
258 template <typename T>
259 template <typename T2>
260 inline
262  TypeTensor<T> (p)
263 {
264 }
265 
266 
267 
268 template <typename T>
269 template <typename T2>
270 inline
272  TypeTensor<T> (vx)
273 {
274 }
275 
276 
277 
278 template <typename T>
279 template <typename T2>
280 inline
282  const TypeVector<T2> & vy) :
283  TypeTensor<T> (vx, vy)
284 {
285 }
286 
287 
288 
289 template <typename T>
290 template <typename T2>
291 inline
293  const TypeVector<T2> & vy,
294  const TypeVector<T2> & vz) :
295  TypeTensor<T> (vx, vy, vz)
296 {
297 }
298 
299 
300 
301 template <typename T>
302 template <typename T2>
303 inline
305  TypeTensor<T> (p)
306 {
307 }
308 
309 
310 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
311 template <typename T>
312 inline
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 
328 template <typename T>
330 TensorValue<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 
362 template <typename T>
365 {
366  // The inverse of a rotation matrix is just the transpose
367  return TensorValue<T>::intrinsic_rotation_matrix(phi, theta, psi).transpose();
368 }
369 
370 template <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 
402 template <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
415 namespace MetaPhysicL
416 {
417 template <typename T>
418 struct 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 
433 template <typename T, typename U>
434 struct ReplaceAlgebraicType<libMesh::TensorValue<T>, U>
435 {
436  typedef U type;
437 };
438 }
439 #endif
440 
441 #endif // LIBMESH_TENSOR_VALUE_H
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. ...
Definition: tensor_value.h:372
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, e.g.
Definition: tensor_value.h:404
void zero()
Set all entries of the tensor to 0.
Definition: type_tensor.h:1338
static value_type value(const libMesh::TensorValue< T > &in)
Definition: tensor_value.h:422
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, e.g.
Definition: tensor_value.h:364
RealTensorValue RealTensor
The libMesh namespace provides an interface to certain functionality in the library.
boostcopy::enable_if_c< ScalarTraits< Scalar >::value, TensorValue & >::type operator=(const Scalar &libmesh_dbg_var(p))
Assignment-from-scalar operator.
Definition: tensor_value.h:145
libMesh::TensorValue< typename RawType< T >::value_type > value_type
Definition: tensor_value.h:420
This class defines a tensor in LIBMESH_DIM dimensional space of type T.
Definition: tensor_tools.h:36
TensorValue()
Empty constructor.
Definition: tensor_value.h:215
TensorValue< Real > RealTensorValue
Useful typedefs to allow transparent switching between Real and Complex data types.
void libmesh_ignore(const Args &...)
TensorValue< Number > NumberTensorValue
static TensorValue< Real > intrinsic_rotation_matrix(Real phi, Real theta, Real psi)
Generate the intrinsic rotation matrix associated with the provided Euler angles. ...
Definition: tensor_value.h:330
This class defines a vector in LIBMESH_DIM dimensional space of type T.
Definition: tensor_tools.h:34
std::complex< Real > Complex
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
NumberTensorValue Tensor
TensorValue< T2 > other
Definition: tensor_value.h:52
This class defines a tensor in LIBMESH_DIM dimensional Real or Complex space.
const Real pi
.
Definition: libmesh.h:281