The Elk Code
gradzfmt.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2002-2009 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: gradzfmt
8 ! !INTERFACE:
9 subroutine gradzfmt(nr,nri,ri,wcr,zfmt,ld,gzfmt)
10 ! !USES:
11 use modmain
12 ! !INPUT/OUTPUT PARAMETERS:
13 ! nr : number of radial mesh points (in,integer)
14 ! nri : number of points on inner part of muffin-tin (in,integer)
15 ! ri : 1/r on the radial mesh (in,real(nr))
16 ! wcr : weights for spline coefficients on radial mesh (in,real(12,nr))
17 ! zfmt : complex muffin-tin function (in,complex(*))
18 ! ld : leading dimension (in,integer)
19 ! gzfmt : gradient of zfmt (out,complex(ld,3))
20 ! !DESCRIPTION:
21 ! Calculates the gradient of a complex muffin-tin function. In other words,
22 ! given the spherical harmonic expansion coefficients, $f_{lm}(r)$, of a
23 ! function $f({\bf r})$, the routine returns ${\bf F}_{lm}$ where
24 ! $$ \sum_{lm}{\bf F}_{lm}(r)Y_{lm}(\hat{\bf r})=\nabla f({\bf r}). $$
25 ! This is done using the gradient formula (see, for example, V. Devanathan,
26 ! {\em Angular Momentum Techniques In Quantum Mechanics})
27 ! \begin{align*}
28 ! \nabla f_{lm}(r)Y_{lm}(\hat{\bf r})&=-\sqrt{\frac{l+1}{2l+1}}
29 ! \left(\frac{d}{dr}-\frac{l}{r}\right)f_{lm}(r)
30 ! {\bf Y}_{lm}^{l+1}(\hat{\bf r})\\
31 ! &+\sqrt{\frac{l}{2l+1}}\left(\frac{d}{dr}+\frac{l+1}{r}\right)f_{lm}(r)
32 ! {\bf Y}_{lm}^{l-1}(\hat{\bf r}),
33 ! \end{align*}
34 ! where the vector spherical harmonics are determined from Clebsch-Gordan
35 ! coefficients as follows:
36 ! $$ {\bf Y}_{lm}^{l'}(\hat{\bf r})=\sum_{m'\mu}
37 ! \begin{bmatrix} l' & 1 & l \\ m' & \mu & m \end{bmatrix}
38 ! Y_{lm}(\hat{\bf r})\hat{\bf e}^{\mu} $$
39 ! and the (contravariant) spherical unit vectors are given by
40 ! $$ \hat{\bf e}_{+1}=-\frac{\hat{\bf x}+i\hat{\bf y}}{\sqrt{2}},
41 ! \qquad\hat{\bf e}_0=\hat{\bf z},\qquad
42 ! \hat{\bf e}_{-1}=\frac{\hat{\bf x}-i\hat{\bf y}}{\sqrt{2}}. $$
43 !
44 ! !REVISION HISTORY:
45 ! Rewritten May 2009 (JKD)
46 ! Modified, February 2020 (JKD)
47 !EOP
48 !BOC
49 implicit none
50 ! arguments
51 integer, intent(in) :: nr,nri
52 real(8), intent(in) :: ri(nr),wcr(12,nr)
53 complex(8), intent(in) :: zfmt(*)
54 integer, intent(in) :: ld
55 complex(8), intent(out) :: gzfmt(ld,3)
56 ! local variables
57 integer nro,iro,ir,mu
58 integer np,npi,i,i1,j
59 integer l,m,lm,lm1
60 ! real constant 1/sqrt(2)
61 real(8), parameter :: c1=0.7071067811865475244d0
62 real(8) t1,t2,t3
63 complex(8) z1
64 ! automatic arrays
65 complex(8) f(nr),df(nr),drmt(ld)
66 ! external functions
67 real(8), external :: clebgor
68 nro=nr-nri
69 iro=nri+1
70 npi=lmmaxi*nri
71 np=npi+lmmaxo*nro
72 !----------------------------------------!
73 ! compute the radial derivatives !
74 !----------------------------------------!
75 do lm=1,lmmaxi
76  i=lm
77  do ir=1,nri
78  f(ir)=zfmt(i)
79  i=i+lmmaxi
80  end do
81  do ir=iro,nr
82  f(ir)=zfmt(i)
83  i=i+lmmaxo
84  end do
85  call splined(nr,wcr,f,df)
86  i=lm
87  do ir=1,nri
88  drmt(i)=df(ir)
89  i=i+lmmaxi
90  end do
91  do ir=iro,nr
92  drmt(i)=df(ir)
93  i=i+lmmaxo
94  end do
95 end do
96 do lm=lmmaxi+1,lmmaxo
97  i=npi+lm
98  do ir=iro,nr
99  f(ir)=zfmt(i)
100  i=i+lmmaxo
101  end do
102  call splined(nro,wcr(1,iro),f(iro),df(iro))
103  i=npi+lm
104  do ir=iro,nr
105  drmt(i)=df(ir)
106  i=i+lmmaxo
107  end do
108 end do
109 !-----------------------------------------------------!
110 ! compute the gradient in the spherical basis !
111 !-----------------------------------------------------!
112 ! zero the gradient array
113 gzfmt(1:np,1:3)=0.d0
114 ! inner part of muffin-tin
115 lm=0
116 do l=0,lmaxi
117  t1=-sqrt(dble(l+1)/dble(2*l+1))
118  if (l > 0) then
119  t2=sqrt(dble(l)/dble(2*l+1))
120  else
121  t2=0.d0
122  end if
123  do m=-l,l
124  lm=lm+1
125  j=1
126  do mu=-1,1
127  if (mu == 0) j=3
128  if (mu == 1) j=2
129  if (l+1 <= lmaxi) then
130 ! index to (l,m) is l*(l+1)+m+1, therefore index to (l+1,m-mu) is
131  lm1=(l+1)*(l+2)+(m-mu)+1
132  t3=t1*clebgor(l+1,1,l,m-mu,mu,m)
133  i=lm; i1=lm1
134  do ir=1,nri
135  gzfmt(i1,j)=gzfmt(i1,j)+t3*(drmt(i)-dble(l)*ri(ir)*zfmt(i))
136  i=i+lmmaxi; i1=i1+lmmaxi
137  end do
138  end if
139  if (abs(m-mu) <= l-1) then
140 ! index to (l-1,m-mu)
141  lm1=(l-1)*l+(m-mu)+1
142  t3=t2*clebgor(l-1,1,l,m-mu,mu,m)
143  i=lm; i1=lm1
144  do ir=1,nri
145  gzfmt(i1,j)=gzfmt(i1,j)+t3*(drmt(i)+dble(l+1)*ri(ir)*zfmt(i))
146  i=i+lmmaxi; i1=i1+lmmaxi
147  end do
148  end if
149  end do
150  end do
151 end do
152 ! outer part of muffin-tin
153 lm=0
154 do l=0,lmaxo
155  t1=-sqrt(dble(l+1)/dble(2*l+1))
156  if (l > 0) then
157  t2=sqrt(dble(l)/dble(2*l+1))
158  else
159  t2=0.d0
160  end if
161  do m=-l,l
162  lm=lm+1
163  j=1
164  do mu=-1,1
165  if (mu == 0) j=3
166  if (mu == 1) j=2
167  if (l+1 <= lmaxo) then
168  lm1=(l+1)*(l+2)+(m-mu)+1
169  t3=t1*clebgor(l+1,1,l,m-mu,mu,m)
170  i=npi+lm; i1=npi+lm1
171  do ir=iro,nr
172  gzfmt(i1,j)=gzfmt(i1,j)+t3*(drmt(i)-dble(l)*ri(ir)*zfmt(i))
173  i=i+lmmaxo; i1=i1+lmmaxo
174  end do
175  end if
176  if (abs(m-mu) <= l-1) then
177  lm1=(l-1)*l+(m-mu)+1
178  t3=t2*clebgor(l-1,1,l,m-mu,mu,m)
179  i=npi+lm; i1=npi+lm1
180  do ir=iro,nr
181  gzfmt(i1,j)=gzfmt(i1,j)+t3*(drmt(i)+dble(l+1)*ri(ir)*zfmt(i))
182  i=i+lmmaxo; i1=i1+lmmaxo
183  end do
184  end if
185  end do
186  end do
187 end do
188 !---------------------------------------------------!
189 ! convert from spherical to Cartesian basis !
190 !---------------------------------------------------!
191 ! note that the gradient transforms as a covariant vector, i.e. y -> -y
192 i=0
193 do ir=1,nri
194  do lm=1,lmmaxi
195  i=i+1
196  z1=gzfmt(i,1)
197  gzfmt(i,1)=c1*(z1-gzfmt(i,2))
198  z1=c1*(z1+gzfmt(i,2))
199  gzfmt(i,2)=cmplx(z1%im,-z1%re,8)
200  end do
201 end do
202 do ir=iro,nr
203  do lm=1,lmmaxo
204  i=i+1
205  z1=gzfmt(i,1)
206  gzfmt(i,1)=c1*(z1-gzfmt(i,2))
207  z1=c1*(z1+gzfmt(i,2))
208  gzfmt(i,2)=cmplx(z1%im,-z1%re,8)
209  end do
210 end do
211 
212 contains
213 
214 pure subroutine splined(n,wc,f,df)
215 implicit none
216 ! arguments
217 integer, intent(in) :: n
218 real(8), intent(in) :: wc(12,n)
219 complex(8), intent(in) :: f(n)
220 complex(8), intent(out) :: df(n)
221 ! local variables
222 integer i
223 complex(8) f1,f2,f3,f4
224 f1=f(1); f2=f(2); f3=f(3); f4=f(4)
225 df(1)=wc(1,1)*f1+wc(2,1)*f2+wc(3,1)*f3+wc(4,1)*f4
226 df(2)=wc(1,2)*f1+wc(2,2)*f2+wc(3,2)*f3+wc(4,2)*f4
227 do i=3,n-2
228  f1=f(i-1); f2=f(i); f3=f(i+1); f4=f(i+2)
229  df(i)=wc(1,i)*f1+wc(2,i)*f2+wc(3,i)*f3+wc(4,i)*f4
230 end do
231 i=n-1
232 df(i)=wc(1,i)*f1+wc(2,i)*f2+wc(3,i)*f3+wc(4,i)*f4
233 df(n)=wc(1,n)*f1+wc(2,n)*f2+wc(3,n)*f3+wc(4,n)*f4
234 end subroutine
235 
236 end subroutine
237 !EOC
238 
integer lmmaxo
Definition: modmain.f90:203
subroutine gradzfmt(nr, nri, ri, wcr, zfmt, ld, gzfmt)
Definition: gradzfmt.f90:10
integer lmaxo
Definition: modmain.f90:201
integer lmmaxi
Definition: modmain.f90:207
pure subroutine splined(n, wc, f, df)
Definition: gensocfr.f90:44
integer lmaxi
Definition: modmain.f90:205