The Elk Code
rhomaguk.f90
Go to the documentation of this file.
1 
2 ! Copyright (C) 2017 T. Mueller, J. K. Dewhurst, S. Sharma and E. K. U. Gross.
3 ! This file is distributed under the terms of the GNU General Public License.
4 ! See the file COPYING for license details.
5 
6 subroutine rhomaguk(ik0,evecu,rhormt_,rhorir_,magrmt_,magrir_)
7 use modmain
8 use modulr
9 use modomp
10 implicit none
11 ! arguments
12 integer, intent(in) :: ik0
13 complex(8), intent(in) :: evecu(nstulr,nstulr)
14 real(8), intent(inout) :: rhormt_(npcmtmax,natmtot,nqpt)
15 real(8), intent(inout) :: rhorir_(ngtc,nqpt)
16 real(8), intent(inout) :: magrmt_(npcmtmax,natmtot,ndmag,nqpt)
17 real(8), intent(inout) :: magrir_(ngtc,ndmag,nqpt)
18 ! local variables
19 integer ik,ikpa,jkpa
20 integer nst,ist,jst,i,j
21 integer ngk0,is,ias
22 integer npc,ir,nthd
23 real(8) wo
24 real(8) ts0,ts1
25 ! automatic arrays
26 integer idx(nstsv)
27 complex(8) zfft(nqpt)
28 ! allocatable arrays
29 complex(8), allocatable :: apwalm(:,:,:,:),evecfv(:,:),evecsv(:,:)
30 complex(8), allocatable :: evectv(:,:,:),evecsvt(:,:)
31 complex(8), allocatable :: wfmt(:,:,:,:),wfir(:,:,:)
32 call timesec(ts0)
33 ! central k-point
34 ik=(ik0-1)*nkpa+1
35 ! number of G+k-vectors for central k-point
36 ngk0=ngk(1,ik)
37 ! get the eigenvectors from file
38 allocate(evecfv(nmatmax,nstfv),evecsv(nstsv,nstsv))
39 call getevecfv(filext,ik,vkl(:,ik),vgkl(:,:,:,ik),evecfv)
40 call getevecsv(filext,ik,vkl(:,ik),evecsv)
41 ! find the matching coefficients
42 allocate(apwalm(ngkmax,apwordmax,lmmaxapw,natmtot))
43 call match(ngk0,vgkc(:,:,1,ik),gkc(:,1,ik),sfacgk(:,:,1,ik),apwalm)
44 allocate(evectv(nstsv,nstsv,nqpt))
45 call holdthd(nqpt,nthd)
46 !$OMP PARALLEL DEFAULT(SHARED) &
47 !$OMP PRIVATE(zfft,evecsvt,wfmt,wfir) &
48 !$OMP PRIVATE(ikpa,jkpa,ist,jst,i,j) &
49 !$OMP PRIVATE(ir,wo,ias,is,npc) &
50 !$OMP NUM_THREADS(nthd)
51 allocate(evecsvt(nstsv,nstsv))
52 allocate(wfmt(npcmtmax,natmtot,nspinor,nstsv),wfir(ngtc,nspinor,nstsv))
53 ! loop over long-range states in subsets of size nstsv
54 do jkpa=1,nkpa
55 ! number of and index to occupied states in subset
56 !$OMP BARRIER
57 !$OMP SINGLE
58  nst=0
59  do jst=1,nstsv
60  j=(jkpa-1)*nstsv+jst
61  if (abs(occulr(j,ik0)) < epsocc) cycle
62  nst=nst+1
63  idx(nst)=jst
64  end do
65 !$OMP END SINGLE
66  if (nst == 0) cycle
67 !$OMP DO SCHEDULE(DYNAMIC)
68  do jst=1,nst
69  j=(jkpa-1)*nstsv+idx(jst)
70  do ist=1,nstsv
71  zfft(1:nqpt)=0.d0
72  do ikpa=1,nkpa
73  i=(ikpa-1)*nstsv+ist
74 ! store the long-range state in FFT Q-space
75  zfft(iqfft(ikpa))=evecu(i,j)
76  end do
77 ! Fourier transform to R-space
78  call zfftifc(3,ngridq,1,zfft)
79  evectv(ist,jst,1:nqpt)=zfft(1:nqpt)
80  end do
81  end do
82 !$OMP END DO
83 ! parallel loop over R-points
84 !$OMP DO SCHEDULE(DYNAMIC)
85  do ir=1,nqpt
86 ! convert third-variational states to second-variational states
87  call zgemm('N','N',nstsv,nst,nstsv,zone,evecsv,nstsv,evectv(:,:,ir), &
88  nstsv,zzero,evecsvt,nstsv)
89 ! generate the wavefunctions in single-precision
90  call genwfsv(.false.,.false.,nst,[0],ngdgc,igfc,ngk0,igkig(:,1,ik),apwalm, &
91  evecfv,evecsvt,wfmt,ngtc,wfir)
92 ! loop over second-variational states
93  do jst=1,nst
94  j=(jkpa-1)*nstsv+idx(jst)
95  wo=occulr(j,ik0)*wkpt(ik)
96 ! add to the density and magnetisation
97 ! muffin-tin part
98  do ias=1,natmtot
99  is=idxis(ias)
100  npc=npcmt(is)
101  if (spinpol) then
102  if (ncmag) then
103  call rmk1(npc,wo,wfmt(:,ias,1,jst),wfmt(:,ias,2,jst), &
104  rhormt_(:,ias,ir),magrmt_(:,ias,1,ir),magrmt_(:,ias,2,ir), &
105  magrmt_(:,ias,3,ir))
106  else
107  call rmk2(npc,wo,wfmt(:,ias,1,jst),wfmt(:,ias,2,jst), &
108  rhormt_(:,ias,ir),magrmt_(:,ias,1,ir))
109  end if
110  else
111  call rmk3(npc,wo,wfmt(:,ias,1,jst),rhormt_(:,ias,ir))
112  end if
113  end do
114 ! interstitial part
115  if (spinpol) then
116  if (ncmag) then
117  call rmk1(ngtc,wo,wfir(:,1,jst),wfir(:,2,jst),rhorir_(:,ir), &
118  magrir_(:,1,ir),magrir_(:,2,ir),magrir_(:,3,ir))
119  else
120  call rmk2(ngtc,wo,wfir(:,1,jst),wfir(:,2,jst),rhorir_(:,ir), &
121  magrir_(:,1,ir))
122  end if
123  else
124  call rmk3(ngtc,wo,wfir(:,1,jst),rhorir_(:,ir))
125  end if
126  end do
127 ! end parallel loop over R-points
128  end do
129 !$OMP END DO
130 end do
131 deallocate(evecsvt,wfmt,wfir)
132 !$OMP END PARALLEL
133 call freethd(nthd)
134 deallocate(apwalm,evecfv,evecsv,evectv)
135 call timesec(ts1)
136 !$OMP ATOMIC
137 timerho=timerho+ts1-ts0
138 
139 contains
140 
141 pure subroutine rmk1(n,wo,wf1,wf2,rho,mag1,mag2,mag3)
142 implicit none
143 ! arguments
144 integer, intent(in) :: n
145 real(8), intent(in) :: wo
146 complex(8), intent(in) :: wf1(n),wf2(n)
147 real(8), intent(inout) :: rho(n),mag1(n),mag2(n),mag3(n)
148 ! local variables
149 integer i
150 real(8) wo2,t1,t2
151 real(8) a1,b1,a2,b2
152 wo2=2.d0*wo
153 !$OMP SIMD PRIVATE(a1,b1,a2,b2,t1,t2) SIMDLEN(8)
154 do i=1,n
155  a1=wf1(i)%re; b1=wf1(i)%im
156  a2=wf2(i)%re; b2=wf2(i)%im
157  t1=a1**2+b1**2; t2=a2**2+b2**2
158  mag1(i)=mag1(i)+wo2*(a1*a2+b1*b2)
159  mag2(i)=mag2(i)+wo2*(a1*b2-b1*a2)
160  mag3(i)=mag3(i)+wo*(t1-t2)
161  rho(i)=rho(i)+wo*(t1+t2)
162 end do
163 end subroutine
164 
165 pure subroutine rmk2(n,wo,wf1,wf2,rho,mag)
166 implicit none
167 ! arguments
168 integer, intent(in) :: n
169 real(8), intent(in) :: wo
170 complex(8), intent(in) :: wf1(n),wf2(n)
171 real(8), intent(inout) :: rho(n),mag(n)
172 ! local variables
173 integer i
174 real(8) t1,t2
175 !$OMP SIMD PRIVATE(t1,t2) SIMDLEN(8)
176 do i=1,n
177  t1=wf1(i)%re**2+wf1(i)%im**2
178  t2=wf2(i)%re**2+wf2(i)%im**2
179  mag(i)=mag(i)+wo*(t1-t2)
180  rho(i)=rho(i)+wo*(t1+t2)
181 end do
182 end subroutine
183 
184 pure subroutine rmk3(n,wo,wf,rho)
185 implicit none
186 ! arguments
187 integer, intent(in) :: n
188 real(8), intent(in) :: wo
189 complex(8), intent(in) :: wf(n)
190 real(8), intent(inout) :: rho(n)
191 ! local variables
192 integer i
193 do i=1,n
194  rho(i)=rho(i)+wo*(wf(i)%re**2+wf(i)%im**2)
195 end do
196 end subroutine
197 
198 end subroutine
199 
integer nmatmax
Definition: modmain.f90:854
integer, dimension(maxspecies) npcmt
Definition: modmain.f90:216
subroutine getevecsv(fext, ikp, vpl, evecsv)
Definition: getevecsv.f90:7
character(256) filext
Definition: modmain.f90:1301
subroutine genwfsv(tsh, tgp, nst, idx, ngridg_, igfft_, ngp, igpig, apwalm, evecfv, evecsv, wfmt, ld, wfir)
Definition: genwfsv.f90:11
logical spinpol
Definition: modmain.f90:230
integer lmmaxapw
Definition: modmain.f90:201
integer ngkmax
Definition: modmain.f90:502
subroutine getevecfv(fext, ikp, vpl, vgpl, evecfv)
Definition: getevecfv.f90:10
subroutine match(ngp, vgpc, gpc, sfacgp, apwalm)
Definition: match.f90:10
Definition: modomp.f90:6
real(8) epsocc
Definition: modmain.f90:899
complex(8), parameter zone
Definition: modmain.f90:1240
real(8) timerho
Definition: modmain.f90:1223
complex(8), dimension(:,:,:,:), allocatable sfacgk
Definition: modmain.f90:512
integer, dimension(:), allocatable iqfft
Definition: modmain.f90:540
integer, dimension(:,:), allocatable ngk
Definition: modmain.f90:500
subroutine zfftifc(nd, n, sgn, z)
Definition: zfftifc_fftw.f90:7
real(8), dimension(:), allocatable wkpt
Definition: modmain.f90:478
real(8), dimension(:,:), allocatable occulr
Definition: modulr.f90:101
real(8), dimension(:,:,:,:), allocatable vgkl
Definition: modmain.f90:506
integer, dimension(:), allocatable igfc
Definition: modmain.f90:413
integer nspinor
Definition: modmain.f90:269
real(8), dimension(:,:,:,:), allocatable vgkc
Definition: modmain.f90:508
complex(8), parameter zzero
Definition: modmain.f90:1240
integer, dimension(3) ngridq
Definition: modmain.f90:518
real(8), dimension(:,:), allocatable vkl
Definition: modmain.f90:474
integer apwordmax
Definition: modmain.f90:763
integer, dimension(maxatoms *maxspecies) idxis
Definition: modmain.f90:44
pure subroutine rmk3(n, wo, wf, rho)
Definition: rhomagk.f90:214
subroutine timesec(ts)
Definition: timesec.f90:10
real(8), dimension(:,:,:), allocatable gkc
Definition: modmain.f90:510
integer, dimension(3) ngdgc
Definition: modmain.f90:391
subroutine freethd(nthd)
Definition: modomp.f90:112
subroutine holdthd(nloop, nthd)
Definition: modomp.f90:78
subroutine rhomaguk(ik0, evecu, rhormt_, rhorir_, magrmt_, magrir_)
Definition: rhomaguk.f90:7
pure subroutine rmk1(n, wo, wf1, wf2, rho, mag1, mag2, mag3)
Definition: rhomagk.f90:171
pure subroutine rmk2(n, wo, wf1, wf2, rho, mag)
Definition: rhomagk.f90:195
Definition: modulr.f90:6
logical ncmag
Definition: modmain.f90:242
integer, dimension(:,:,:), allocatable igkig
Definition: modmain.f90:504
integer nkpa
Definition: modulr.f90:24
integer nstfv
Definition: modmain.f90:883