The Elk Code
 
Loading...
Searching...
No Matches
rotaxang.f90
Go to the documentation of this file.
1
2! Copyright (C) 2006 J. K. Dewhurst, S. Sharma and C. Ambrosch-Draxl.
3! This file is distributed under the terms of the GNU Lesser General Public
4! License. See the file COPYING for license details.
5
6!BOP
7! !ROUTINE: rotaxang
8! !INTERFACE:
9subroutine rotaxang(eps,rot,det,v,th)
10! !INPUT/OUTPUT PARAMETERS:
11! eps : zero vector tolerance (in,real)
12! rot : rotation matrix (in,real(3,3))
13! det : matrix determinant (out,real)
14! v : normalised axis vector (out,real(3))
15! th : rotation angle (out,real)
16! !DESCRIPTION:
17! Given a rotation matrix
18! $$ R(\hat{\bf v},\theta)=
19! \left(\begin{matrix}
20! \cos\theta+x^2(1-\cos\theta) &
21! xy(1-\cos\theta)+z\sin\theta &
22! xz(1-\cos\theta)-y\sin\theta \\
23! xy(1-\cos\theta)-z\sin\theta &
24! \cos\theta+y^2(1-\cos\theta) &
25! yz(1-\cos\theta)+x\sin\theta \\
26! xz(1-\cos\theta)+y\sin\theta &
27! yz(1-\cos\theta)-x\sin\theta &
28! \cos\theta+z^2(1-\cos\theta)
29! \end{matrix}\right), $$
30! this routine determines the axis of rotation $\hat{\bf v}$ and the angle of
31! rotation $\theta$. If $R$ corresponds to an improper rotation then only the
32! proper part is used and {\tt det} is set to $-1$. The rotation convention
33! follows the `right-hand rule'.
34!
35! !REVISION HISTORY:
36! Created December 2006 (JKD)
37!EOP
38!BOC
39implicit none
40! arguments
41real(8), intent(in) :: eps,rot(3,3)
42real(8), intent(out) :: det,v(3),th
43! local variables
44real(8), parameter :: pi=3.1415926535897932385d0
45real(8) rotp(3,3),t1,t2
46! find the determinant and proper rotation matrix
47det=rot(1,1)*(rot(2,2)*rot(3,3)-rot(3,2)*rot(2,3)) &
48 +rot(2,1)*(rot(3,2)*rot(1,3)-rot(1,2)*rot(3,3)) &
49 +rot(3,1)*(rot(1,2)*rot(2,3)-rot(2,2)*rot(1,3))
50if (abs(det-1.d0) < eps) then
51 det=1.d0
52 rotp(1:3,1:3)=rot(1:3,1:3)
53else if (abs(det+1.d0) < eps) then
54 det=-1.d0
55 rotp(1:3,1:3)=-rot(1:3,1:3)
56else
57 goto 10
58end if
59v(1)=0.5d0*(rotp(2,3)-rotp(3,2))
60v(2)=0.5d0*(rotp(3,1)-rotp(1,3))
61v(3)=0.5d0*(rotp(1,2)-rotp(2,1))
62t1=sqrt(v(1)**2+v(2)**2+v(3)**2)
63t2=0.5d0*(rotp(1,1)+rotp(2,2)+rotp(3,3)-1.d0)
64if (abs(abs(t2)-1.d0) > eps) then
65! theta not equal to 0 or pi
66 th=-atan2(t1,t2)
67 v(1:3)=v(1:3)/t1
68else
69! special case of sin(th)=0
70 if (t2 > 0.d0) then
71! zero angle: axis arbitrary
72 th=0.d0
73 v(1)=0.d0; v(2)=0.d0; v(3)=1.d0
74 else
75! rotation by pi
76 th=pi
77 if ((rotp(1,1) >= rotp(2,2)).and.(rotp(1,1) >= rotp(3,3))) then
78 if (rotp(1,1) < (-1.d0+eps)) goto 10
79 v(1)=sqrt(0.5d0*abs(rotp(1,1)+1.d0))
80 v(2)=(rotp(2,1)+rotp(1,2))/(4.d0*v(1))
81 v(3)=(rotp(3,1)+rotp(1,3))/(4.d0*v(1))
82 else if ((rotp(2,2) >= rotp(1,1)).and.(rotp(2,2) >= rotp(3,3))) then
83 if (rotp(2,2) < (-1.d0+eps)) goto 10
84 v(2)=sqrt(0.5d0*abs(rotp(2,2)+1.d0))
85 v(3)=(rotp(3,2)+rotp(2,3))/(4.d0*v(2))
86 v(1)=(rotp(1,2)+rotp(2,1))/(4.d0*v(2))
87 else
88 if (rotp(3,3) < (-1.d0+eps)) goto 10
89 v(3)=sqrt(0.5d0*abs(rotp(3,3)+1.d0))
90 v(1)=(rotp(1,3)+rotp(3,1))/(4.d0*v(3))
91 v(2)=(rotp(2,3)+rotp(3,2))/(4.d0*v(3))
92 end if
93 end if
94end if
95return
9610 continue
97write(*,*)
98write(*,'("Error(rotaxang): invalid rotation matrix:")')
99write(*,'(3G18.10)') rot(1,1:3)
100write(*,'(3G18.10)') rot(2,1:3)
101write(*,'(3G18.10)') rot(3,1:3)
102write(*,*)
103stop
104end subroutine
105!EOC
106
subroutine rotaxang(eps, rot, det, v, th)
Definition rotaxang.f90:10