https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Functions
RotationMatrix Namespace Reference

Utility functions to return rotations matrics. More...

Functions

template<bool is_ad = false>
GenericRealTensorValue< is_ad > rotVecToZ (GenericRealVectorValue< is_ad > vec)
 provides a rotation matrix that will rotate the vector vec to the z axis (the "2" direction)
 
template<bool is_ad = false>
GenericRealTensorValue< is_ad > rotVec1ToVec2 (GenericRealVectorValue< is_ad > vec1, GenericRealVectorValue< is_ad > vec2)
 provides a rotation matrix that will rotate the vector vec1 to vec2
 
template<bool is_ad = false>
GenericRealTensorValue< is_ad > rotVec2DToX (const GenericRealVectorValue< is_ad > &vec)
 provides a rotation matrix that will rotate the vector vec1 to the [1,0,0], assuming vec1[2]==0
 
template<bool is_ad = false>
GenericRealTensorValue< is_ad > rodriguesRotationMatrix (GenericRealVectorValue< is_ad > vec1, GenericRealVectorValue< is_ad > vec2)
 Provides rotatiom matrix for rotating from vec1 to vec2 using Rodrigues' rotation forumula.
 

Detailed Description

Utility functions to return rotations matrics.

Function Documentation

◆ rodriguesRotationMatrix()

template<bool is_ad = false>
GenericRealTensorValue< is_ad > RotationMatrix::rodriguesRotationMatrix ( GenericRealVectorValue< is_ad >  vec1,
GenericRealVectorValue< is_ad >  vec2 
)

Provides rotatiom matrix for rotating from vec1 to vec2 using Rodrigues' rotation forumula.

See https://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula#Matrix_notation

Parameters
vec1starting vector – must have 3 components!
vec2ending vector – must have 3 components!
Returns
3x3 rotation tensor (matrix)

Definition at line 96 of file RotationMatrix.h.

97{
98 // normalize input vectors
99 GenericRealVectorValue<is_ad> u = vec1 / vec1.norm();
100 GenericRealVectorValue<is_ad> v = vec2 / vec2.norm();
101
102 if ((u - v).norm() < libMesh::TOLERANCE)
103 return GenericRealTensorValue<is_ad>(1, 0, 0, 0, 1, 0, 0, 0, 1); // identity matrix
104
105 GenericRealVectorValue<is_ad> k_vec = u.cross(v); // calculate rotation axis
106
107 // test for exactly opposite vectors to avoid divide by zero
108 if (k_vec.norm() < libMesh::TOLERANCE)
109 {
111 if ((u - GenericRealVectorValue<is_ad>(1, 0, 0)).norm() < TOLERANCE)
112 rot_matrix = GenericRealTensorValue<is_ad>(-1, 0, 0, 0, -1, 0, 0, 0, 1);
113 else
114 mooseError("Rotation matrix cannot be generated for opposite-facing vectors at this time!");
115 return rot_matrix;
116 }
117
118 k_vec /= k_vec.norm(); // normalize
119 Real cos_theta = u * v;
120 Real theta = std::acos(cos_theta);
121 Real sin_theta = std::sin(theta);
122
124 0, -k_vec(2), k_vec(1), k_vec(2), 0, -k_vec(0), -k_vec(1), k_vec(0), 0);
125 GenericRealTensorValue<is_ad> I(1, 0, 0, 0, 1, 0, 0, 0, 1); // identity matrix
126
127 // construct rotation matrix
129 rot_matrix = I + sin_theta * K_matrix + (1 - cos_theta) * K_matrix * K_matrix;
130 return rot_matrix;
131}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
Moose::GenericType< RealTensorValue, is_ad > GenericRealTensorValue
Definition MooseTypes.h:704
Moose::GenericType< RealVectorValue, is_ad > GenericRealVectorValue
Definition MooseTypes.h:702
static constexpr Real TOLERANCE

◆ rotVec1ToVec2()

template<bool is_ad = false>
GenericRealTensorValue< is_ad > RotationMatrix::rotVec1ToVec2 ( GenericRealVectorValue< is_ad >  vec1,
GenericRealVectorValue< is_ad >  vec2 
)

provides a rotation matrix that will rotate the vector vec1 to vec2

Definition at line 66 of file RotationMatrix.h.

68{
69 GenericRealTensorValue<is_ad> rot1_to_z = rotVecToZ<is_ad>(vec1);
70 GenericRealTensorValue<is_ad> rot2_to_z = rotVecToZ<is_ad>(vec2);
71 return rot2_to_z.transpose() * rot1_to_z;
72}

◆ rotVec2DToX()

template<bool is_ad = false>
GenericRealTensorValue< is_ad > RotationMatrix::rotVec2DToX ( const GenericRealVectorValue< is_ad > &  vec)

provides a rotation matrix that will rotate the vector vec1 to the [1,0,0], assuming vec1[2]==0

Definition at line 77 of file RotationMatrix.h.

79{
80 using std::atan2, std::sin, std::cos;
81 const GenericReal<is_ad> theta = atan2(vec(1), vec(0));
82 const GenericReal<is_ad> st = sin(theta);
83 const GenericReal<is_ad> ct = cos(theta);
84 return GenericRealTensorValue<is_ad>(ct, st, 0., -st, ct, 0., 0., 0., 1.);
85}
Moose::GenericType< Real, is_ad > GenericReal
Definition MooseTypes.h:698

◆ rotVecToZ()

template<bool is_ad = false>
GenericRealTensorValue< is_ad > RotationMatrix::rotVecToZ ( GenericRealVectorValue< is_ad >  vec)

provides a rotation matrix that will rotate the vector vec to the z axis (the "2" direction)

Definition at line 24 of file RotationMatrix.h.

26{
27 using std::sqrt, std::abs;
28 // ensure that vec is normalised
29 vec /= sqrt(vec * vec);
30
31 // construct v0 and v1 to be orthonormal to vec
32 // and form a RH basis, that is, so v1 x vec = v0
33
34 // Use Gram-Schmidt method to find v1.
36 // Need a prototype for v1 first, and this is done by looking at the smallest component of vec
37 GenericRealVectorValue<is_ad> w(abs(vec(0)), abs(vec(1)), abs(vec(2)));
38 if ((w(2) >= w(1) && w(1) >= w(0)) || (w(1) >= w(2) && w(2) >= w(0)))
39 // vec(0) is the smallest component
40 v1(0) = 1;
41 else if ((w(2) >= w(0) && w(0) >= w(1)) || (w(0) >= w(2) && w(2) >= w(1)))
42 // vec(1) is the smallest component
43 v1(1) = 1;
44 else
45 // vec(2) is the smallest component
46 v1(2) = 1;
47 // now Gram-Schmidt
48 v1 -= (v1 * vec) * vec;
49 v1 /= sqrt(v1 * v1);
50
51 // now use v0 = v1 x vec
53 v0(0) = v1(1) * vec(2) - v1(2) * vec(1);
54 v0(1) = v1(2) * vec(0) - v1(0) * vec(2);
55 v0(2) = v1(0) * vec(1) - v1(1) * vec(0);
56
57 // the desired rotation matrix is just
59 v0(0), v0(1), v0(2), v1(0), v1(1), v1(2), vec(0), vec(1), vec(2));
60 return rot;
61}

Referenced by SolutionUserObjectBase::SolutionUserObjectBase().