The Elk Code
wigner3j.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2005 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: wigner3j
8 ! !INTERFACE:
9 real(8) function wigner3j(j1,j2,j3,m1,m2,m3)
10 ! !INPUT/OUTPUT PARAMETERS:
11 ! j1, j2, j3 : angular momentum quantum numbers (in,integer)
12 ! m1, m2, m3 : magnetic quantum numbers (in,integer)
13 ! !DESCRIPTION:
14 ! Returns the Wigner $3j$-symbol. There are many equivalent formulae for
15 ! the $3j$-symbols, the following provides high accuracy for $j\le 50$
16 ! \begin{align*}
17 ! &\begin{pmatrix} j_1 & j_2 & j_3 \\ m_1 & m_2 & m_3 \end{pmatrix}= \\
18 ! &(-1)^{j1+j2+m3}\sqrt{\frac{(j_1+m_1)!\,(j_2+m_2)!\,(j_3+m_3)!\,
19 ! (j_3-m_3)!\,(j_1-m_1)!\,(j_2-m_2)!}{(j_2-j_1+j_3)!\,(j_1-j_2+j_3)!\,
20 ! (j_1+j_2-j_3)!\,(1+j_1+j_2+j_3)!}}\,\sum_k(-1)^k \\
21 ! &\frac{(j_2-j_1+j_3)!\,(j_1-j_2+j_3)!\,(j_1+j_2-j_3)!}{(j_3-j_1-m_2+k)!\,
22 ! (j_3-j_2+m_1+k)!\,(j_1+j_2-j_3-k)!\,k!\,(j_1-m_1-k)!\,(j_2+m_2-k)!},
23 ! \end{align*}
24 ! where the sum is over all integers $k$ for which the factorials in the
25 ! summand are non-negative.
26 !
27 ! !REVISION HISTORY:
28 ! Created November 2002 (JKD)
29 !EOP
30 !BOC
31 implicit none
32 ! arguments
33 integer, intent(in) :: j1,j2,j3
34 integer, intent(in) :: m1,m2,m3
35 ! local variables
36 integer k,k1,k2,l1,l2,l3,n1,n2
37 real(8) sgn,sm,t1
38 ! external functions
39 real(8), external :: factn,factr
40 ! check input variables
41 if ((j1 < 0).or.(j2 < 0).or.(j3 < 0).or.(abs(m1) > j1).or.(abs(m2) > j2) &
42  .or.(abs(m3) > j3)) then
43  write(*,*)
44  write(*,'("Error(wigner3j): invalid arguments :")')
45  write(*,'("j1 = ",I8," j2 = ",I8," j3 = ",I8)') j1,j2,j3
46  write(*,'("m1 = ",I8," m2 = ",I8," m3 = ",I8)') m1,m2,m3
47  write(*,*)
48  stop
49 end if
50 if ((j1 == 0).and.(j2 == 0).and.(j3 == 0)) then
51  wigner3j=1.d0
52  return
53 end if
54 if ((j1 > 50).or.(j2 > 50).or.(j3 > 50)) then
55  write(*,*)
56  write(*,'("Error(wigner3j): angular momenta out of range : ",3I8)') j1,j2,j3
57  write(*,*)
58  stop
59 end if
60 l1=j2-j1+j3
61 l2=j1-j2+j3
62 l3=j1+j2-j3
63 if ((m1+m2+m3 /= 0).or.(l1 < 0).or.(l2 < 0).or.(l3 < 0)) then
64  wigner3j=0.d0
65  return
66 end if
67 n1=j1-m1
68 n2=j2+m2
69 k1=max(0,n1-l2,n2-l1)
70 k2=min(l3,n1,n2)
71 if (mod(k1-j1+j2+m3,2) /= 0) then
72  sgn=-1.d0
73 else
74  sgn=1.d0
75 end if
76 sm=0.d0
77 do k=k1,k2
78  t1=sgn*factr(l1,l1-n2+k)*factr(l2,l2-n1+k)*factr(l3,l3-k)
79  sm=sm+t1/(factn(k)*factn(n1-k)*factn(n2-k))
80  sgn=-sgn
81 end do
82 t1=factr(j1+m1,l1)*factr(j2+m2,l2)*factr(j3+m3,l3)
83 t1=t1*factr(j3-m3,1+j1+j2+j3)*factn(j1-m1)*factn(j2-m2)
84 wigner3j=sm*sqrt(t1)
85 end function
86 !EOC
87 
real(8) function wigner3j(j1, j2, j3, m1, m2, m3)
Definition: wigner3j.f90:10
elemental real(8) function factn(n)
Definition: factn.f90:7
real(8) function factr(n, d)
Definition: factr.f90:10