Branch data Line data Source code
1 : : !!****m* ABINIT/m_suscep_stat
2 : : !! NAME
3 : : !! m_suscep_stat
4 : : !!
5 : : !! FUNCTION
6 : : !! Compute the susceptibility matrix
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (XG, AR, MB)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : MODULE m_suscep_stat
23 : :
24 : : use defs_basis
25 : : use m_xmpi
26 : : use m_errors
27 : : use m_abicore
28 : : use m_distribfft
29 : :
30 : : use defs_abitypes, only : MPI_type
31 : : use m_time, only : timab
32 : : use m_pawang, only : pawang_type
33 : : use m_pawtab, only : pawtab_type
34 : : use m_pawcprj, only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_mpi_allgather, pawcprj_free
35 : : use m_mpinfo, only : destroy_mpi_enreg, initmpi_seq, proc_distrb_cycle
36 : : use m_kg, only : ph1d3d
37 : : use m_gsphere, only : symg
38 : : use m_fftcore, only : sphereboundary
39 : : use m_fft, only : fftpac, fourwf
40 : : use m_spacepar, only : symrhg
41 : : use m_paw_finegrid, only : pawgylmg
42 : : use m_paw_nhat, only : pawsushat
43 : :
44 : : implicit none
45 : :
46 : : private
47 : : !!***
48 : :
49 : : public :: suscep_stat ! Compute the susceptibility matrix
50 : :
51 : : CONTAINS !====================================================================================================
52 : : !!***
53 : :
54 : : !!****f* m_suscep_stat/suscep_stat
55 : : !! NAME
56 : : !! suscep_stat
57 : : !!
58 : : !! FUNCTION
59 : : !! Compute the susceptibility matrix
60 : : !! from input wavefunctions, band occupations, and k point wts.
61 : : !! Include the usual sum-over-state terms, but also the
62 : : !! corrections due to the change of the Fermi level in the metallic
63 : : !! case, as well as implicit sum over higher lying conduction
64 : : !! states, thanks to the closure relation (referred to as an extrapolation).
65 : : !!
66 : : !! INPUTS
67 : : !! atindx(natom)=index table for atoms (see scfcv.f)
68 : : !! atindx1(natom)=index table for atoms, inverse of atindx (see scfcv.f)
69 : : !! cg(2,mcg)=wf in G space
70 : : !! cprj(natom,mcg*usecprj)= wave functions projected with non-local projectors:
71 : : !! cprj_nk(i)=<p_i|Cnk> where p_i is a non-local projector.
72 : : !! dielar(7)=input parameters for dielectric matrix and susceptibility:
73 : : !! diecut,dielng,diemac,diemix,diegap,dielam,diemixmag.
74 : : !! dimcprj(natom*usepaw)=array of dimensions of array cprj (ordered by atom-type)
75 : : !! doccde(mband*nkpt*nsppol)=derivative of occupancies wrt
76 : : !! the energy for each band and k point
77 : : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
78 : : !! gbound_diel(2*mgfftdiel+8,2)=G sphere boundary for the dielectric matrix
79 : : !! gprimd(3,3)=dimensional reciprocal space primitive translations
80 : : !! irrzondiel(nfftdiel**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4))=irreducible zone data
81 : : !! istwfk(nkpt)=input option parameter that describes the storage of wfs
82 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates.
83 : : !! kg_diel(3,npwdiel)=reduced planewave coordinates for the dielectric matrix.
84 : : !! lmax_diel=1+max. value of l angular momentum used for dielectric matrix
85 : : !! mband=maximum number of bands
86 : : !! mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
87 : : !! mcprj=size of projected wave-functions array (cprj) =nspinor*mband*mkmem*nsppol
88 : : !! mgfftdiel=maximum size of 1D FFTs, for the computation of the dielectric matrix
89 : : !! mkmem=number of k points treated by this node
90 : : !! mpi_enreg=information about MPI parallelization
91 : : !! mpw=maximum allowed value for npw
92 : : !! natom=number of atoms in cell
93 : : !! nband(nkpt*nsppol)=number of bands to be included in summation
94 : : !! at each k point for each spin channel
95 : : !! neglect_pawhat=1 if PAW contribution from hat density (compensation charge)
96 : : !! has to be neglected (to be used when only an estimation of
97 : : !! suscep. matrix has to be evaluated, i.e. for SCF precondictioning)
98 : : !! nfftdiel=number of fft grid points for the computation of the diel matrix
99 : : !! ngfftdiel(18)=contain all needed information about 3D FFT, for dielectric matrix,
100 : : !! see ~abinit/doc/variables/vargs.htm#ngfft
101 : : !! nkpt=number of k points
102 : : !! npwarr(nkpt)=number of planewaves and boundary planewaves
103 : : !! at each k, for going from the WF sphere to the medium size FFT grid.
104 : : !! npwdiel=third and fifth dimension of the susmat array.
105 : : !! nspden=number of spin-density components
106 : : !! nspinor=number of spinorial components of the wavefunctions
107 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
108 : : !! nsym=number of symmetry elements in group (at least 1 for identity)
109 : : !! ntypat=number of types of atoms in unit cell.
110 : : !! occ(mband*nkpt*nsppol)=
111 : : !! occupation numbers for each band (usually 2.0) at each k point
112 : : !! occopt=option for occupancies
113 : : !! pawang <type(pawang_type)>=paw angular mesh and related data
114 : : !! pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
115 : : !! phnonsdiel(2,nfftdiel**(1-1/nsym),(nspden/nsppol)-3*(nspden/4))=nonsymmorphic translation phases
116 : : !! ph1ddiel(2,3*(2*mgfftdiel+1)*natom*usepaw)=one-dimensional structure factor information
117 : : !! for the dielectric matrix
118 : : !! rprimd(3,3)=dimensional real space primitive translations
119 : : !! symafm(nsym)=(anti)ferromagnetic part of symmetry operations
120 : : !! symrel(3,3,nsym)=symmetry matrices in real space (integers)
121 : : !! tnons(3,nsym)=reduced nonsymmorphic translations
122 : : !! (symrel and tnons are in terms of real space primitive translations)
123 : : !! typat(natom)=type (integer) for each atom
124 : : !! ucvol=unit cell volume (Bohr**3)
125 : : !! unpaw=unit number for cprj PAW data (if used)
126 : : !! usecprj= 1 if cprj array is stored in memory
127 : : !! usepaw=flag for PAW
128 : : !! usetimerev=1 if Time-Reversal symmetry has to be used when symmetrizing susceptibility
129 : : !! wtk(nkpt)=k point weights (they sum to 1.0)
130 : : !! ylmdiel(npwdiel,lmax_diel**2)= real spherical harmonics for each G and k point
131 : : !! for the dielectric matrix
132 : : !!
133 : : !! OUTPUT
134 : : !! susmat(2,npwdiel,nspden,npwdiel,nspden)=
135 : : !! the susceptibility (or density-density response) matrix in reciprocal space
136 : : !!
137 : : !! NOTES
138 : : !! Case of non-collinear magnetism:
139 : : !! In principle, we should compute 16 susceptibility matrix: chi0-(s1,s2),(s3,s4)
140 : : !! (where s1, s2, s3,and s4 are spin indexes)...
141 : : !! But, for the time being, the susceptibility is only used to compute the
142 : : !! dielectric matrix within RPA approximation; in this approximation, only
143 : : !! four susceptibilities are non-zero: chi0-(s1,s1),(s3,s3).
144 : : !! They are stored in susmat(:,ipw1,1:2,ipw2,1:2)
145 : : !!
146 : : !! SOURCE
147 : :
148 : 82 : subroutine suscep_stat(atindx,atindx1,cg,cprj,dielar,dimcprj,doccde,&
149 : 82 : & eigen,gbound_diel,gprimd,irrzondiel,istwfk,kg,&
150 : 82 : & kg_diel,lmax_diel,&
151 : 82 : & mband,mcg,mcprj,mgfftdiel,mkmem,mpi_enreg,mpw,natom,nband,&
152 : 82 : & neglect_pawhat,nfftdiel,ngfftdiel,nkpt,npwarr,&
153 : 82 : & npwdiel,nspden,nspinor,nsppol,nsym,ntypat,occ,occopt,&
154 : 82 : & pawang,pawtab,phnonsdiel,ph1ddiel,rprimd,&
155 : 82 : & susmat,symafm,symrel,tnons,typat,ucvol,unpaw,usecprj,usepaw,usetimerev,&
156 : 82 : & wtk,ylmdiel)
157 : :
158 : : !Arguments ------------------------------------
159 : : !scalars
160 : : integer,intent(in) :: lmax_diel,mband,mcg,mcprj,mgfftdiel,mkmem,mpw,natom,neglect_pawhat
161 : : integer,intent(in) :: nfftdiel,nkpt,npwdiel,nspden,nspinor,nsppol,nsym,ntypat,occopt
162 : : integer,intent(in) :: unpaw,usecprj,usepaw,usetimerev
163 : : real(dp),intent(in) :: ucvol
164 : : type(MPI_type),intent(in) :: mpi_enreg
165 : : type(pawang_type),intent(in) :: pawang
166 : : !arrays
167 : : integer,intent(in) :: atindx(natom),atindx1(natom),dimcprj(natom*usepaw)
168 : : integer,intent(in) :: gbound_diel(2*mgfftdiel+8,2)
169 : : !no_abirules
170 : : !nfftdiel**(1-1/nsym) is 1 if nsym==1, and nfftdiel otherwise
171 : : integer,intent(in) :: irrzondiel(nfftdiel**(1-1/nsym),2,(nspden/nsppol)-3*(nspden/4)),&
172 : : & istwfk(nkpt)
173 : : integer,intent(in) :: kg(3,mpw*mkmem),kg_diel(3,npwdiel),&
174 : : & nband(nkpt*nsppol),ngfftdiel(18)
175 : : integer,intent(in) :: npwarr(nkpt),symafm(nsym),symrel(3,3,nsym),typat(ntypat)
176 : : real(dp),intent(in) :: cg(2,mcg),dielar(7)
177 : : real(dp),intent(in) :: doccde(mband*nkpt*nsppol),eigen(mband*nkpt*nsppol)
178 : : real(dp),intent(in) :: gprimd(3,3),occ(mband*nkpt*nsppol)
179 : : !nfftdiel**(1-1/nsym) is 1 if nsym==1, and nfftdiel otherwise
180 : : real(dp),intent(in) :: phnonsdiel(2,nfftdiel**(1-1/nsym),(nspden/nsppol)-3*(nspden/4)),&
181 : : & tnons(3,nsym),wtk(nkpt)
182 : : real(dp),intent(in) :: ph1ddiel(2,(3*(2*mgfftdiel+1)*natom)*usepaw),rprimd(3,3)
183 : : real(dp),intent(in) :: ylmdiel(npwdiel,lmax_diel**2)
184 : : real(dp),intent(out) :: susmat(2,npwdiel,nspden,npwdiel,nspden)
185 : : type(pawcprj_type) :: cprj(natom,mcprj*usecprj)
186 : : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
187 : :
188 : : !Local variables-------------------------------
189 : : !scalars
190 : : integer :: bdtot_index,diag,extrap,i1,i2,i3,iband,ibg,icg,ier,ierr
191 : : integer :: ifft,ii,ikg,ikpt,indx,iorder_cprj,ipw1,ipw2,isp,isp1,isp2
192 : : integer :: ispinor,istwf_k,isym,j1,j2,j3,jj,jsp,k1,k2,k3
193 : : integer :: my_nspinor,nband_k,nband_loc,ndiel1,ndiel2,ndiel3,ndiel4,ndiel5,ndiel6
194 : : integer :: nkpg_diel,npw_k,npwsp,nspden_eff,nspden_tmp,nsym1,nsym2
195 : : integer :: spaceComm,t1,t2,testocc
196 : : real(dp) :: ai,ai2,ar,ar2,diegap,dielam,emax,invnsym
197 : : real(dp) :: invnsym1,invnsym2,phi1,phi12,phi2,phr1,phr12
198 : : real(dp) :: phr2,sumdocc,weight
199 : : logical :: antiferro
200 : : character(len=500) :: message
201 : 82 : type(MPI_type) :: mpi_enreg_diel
202 : :
203 : : !arrays
204 : 82 : integer,allocatable :: gbound(:,:),kg_k(:,:),sym_g(:,:)
205 : 82 : integer,allocatable :: tmrev_g(:)
206 : : real(dp) :: kpt_diel(3,1),tsec(2)
207 : 82 : real(dp),allocatable :: drhode(:,:,:),drhode_wk(:,:,:)
208 : 82 : real(dp),allocatable :: eig_diel(:),gylmg_diel(:,:,:),kpg_dum(:,:)
209 : 82 : real(dp),allocatable :: occ_deavg(:),ph3d_diel(:,:,:),phdiel(:,:,:)
210 : 82 : real(dp),allocatable :: phkxred_diel(:,:),rhoextrap(:,:,:,:),rhoextrg(:,:)
211 : 82 : real(dp),allocatable :: rhoextrr(:,:),sush(:),sussum(:),susvec(:,:,:)
212 : 82 : real(dp),allocatable :: suswk(:,:,:,:),zhpev1(:,:),zhpev2(:)
213 : 82 : type(pawcprj_type),allocatable :: cprj_k(:,:),cprj_loc(:,:)
214 : :
215 : : ! *************************************************************************
216 : :
217 : 82 : call timab(740,1,tsec)
218 : 82 : call timab(741,1,tsec)
219 : :
220 [ - + ]: 82 : ABI_CHECK(mkmem/=0,"mkmem==0 not supported anymore!")
221 : :
222 : :
223 : : !----- Initialisations -----------------------------------------------------------
224 : : !---------------------------------------------------------------------------------
225 : :
226 [ + - - + ]: 82 : if (usecprj==0.and.usepaw==1) then
227 : : write (message,'(3a)')&
228 : 0 : & ' cprj datastructure must be allocated !',ch10,&
229 : 0 : & ' Action: change pawusecp input keyword.'
230 : 0 : ABI_ERROR(message)
231 : : end if
232 : :
233 [ - + ]: 82 : if (mpi_enreg%paral_spinor==1) then
234 : 0 : message = ' not yet allowed for parallelization over spinors !'
235 : 0 : ABI_ERROR(message)
236 : : end if
237 : :
238 : : !Init mpicomm
239 [ - + ]: 82 : if(mpi_enreg%paral_kgb==1) then
240 : 0 : spaceComm=mpi_enreg%comm_kpt
241 : : else
242 : 82 : spaceComm=mpi_enreg%comm_cell
243 : : end if
244 : :
245 : : !The dielectric stuff is performed in sequential mode.
246 : : !Set mpi_enreg_diel accordingly
247 : 82 : call initmpi_seq(mpi_enreg_diel)
248 : 82 : call MPI_enreg_diel%distribfft%init_seq('c',ngfftdiel(2),ngfftdiel(3),'all')
249 : :
250 : : !testocc to be taken away
251 : 82 : testocc=1
252 : :
253 : 82 : my_nspinor=max(1,nspinor/mpi_enreg%nproc_spinor)
254 : :
255 : 82 : iorder_cprj=0 ! order for the cprj reading...
256 : :
257 : : !Initialize some scalar quantities
258 [ + + + - ]: 82 : antiferro=(nsppol==1.and.nspden==2)
259 : 82 : nspden_eff=min(max(nsppol,nspden),2) ! Size for the computed part of susmat
260 : 82 : bdtot_index=0 ; icg=0 ; ibg=0
261 : 82 : ndiel1=ngfftdiel(1) ; ndiel2=ngfftdiel(2) ; ndiel3=ngfftdiel(3)
262 : :
263 : : !ndiel4,ndiel5,ndiel6 are FFT dimensions, modified to avoid cache trashing
264 : 82 : ndiel4=ngfftdiel(4) ; ndiel5=ngfftdiel(5) ; ndiel6=ngfftdiel(6)
265 : 82 : diegap=dielar(5) ; dielam=dielar(6)
266 : 82 : extrap=0
267 : :
268 : : !If dielam is too small, there is no extrapolation.
269 [ + + ]: 82 : if(dielam>1.0d-6)extrap=1
270 : :
271 : : !Some stuff for symmetries
272 [ + + + - ]: 1006 : nsym1=sum(symafm,mask=symafm==1)
273 : 82 : nsym2=nsym-nsym1
274 : 82 : invnsym =one/dble(nsym)
275 : 82 : invnsym1=one/dble(nsym1)
276 : 82 : invnsym2=one
277 : : !FIXME: make sure this is consistent with following code
278 : : !div by 0 for several v5 tests
279 [ - + ]: 82 : if (nsym2 > 0) invnsym2=one/dble(nsym2)
280 : :
281 : : !Allocations
282 [ - + + - : 246 : ABI_MALLOC(occ_deavg,(mband))
+ - + - -
+ - + ]
283 [ + + ]: 82 : if(occopt>=3) then
284 [ - + + - : 228 : ABI_MALLOC(drhode,(2,npwdiel,nspden_eff))
- + + - +
- + - - +
- + ]
285 : : else
286 [ - + ]: 25 : ABI_MALLOC(drhode,(0,0,0))
287 : : end if
288 [ + + ]: 82 : if(extrap==1) then
289 [ - + + - : 486 : ABI_MALLOC(rhoextrap,(ndiel4,ndiel5,ndiel6,nspinor))
- + + - -
+ + - - +
+ - + - +
- - + -
+ ]
290 : : else
291 [ - + ]: 82 : ABI_MALLOC(rhoextrap,(0,0,0,0))
292 : : end if
293 : :
294 : : !zero the susceptibility matrix and other needed quantities
295 [ + + + + : 8744382 : susmat(:,:,:,:,:)=zero
+ + + + +
+ ]
296 [ + + ]: 82 : if(occopt>=3)then
297 [ + + + + : 16745 : drhode(:,:,:)=zero
+ + ]
298 : 57 : sumdocc=zero
299 : : end if
300 : :
301 : : !PAW additional initializations
302 [ - + ]: 82 : if (usepaw==1) then
303 [ # # # # : 0 : ABI_MALLOC(gylmg_diel,(npwdiel,lmax_diel**2,ntypat))
# # # # #
# # # # #
# # # # #
# ]
304 [ # # # # : 0 : ABI_MALLOC(ph3d_diel,(2,npwdiel,natom))
# # # # #
# # # # #
# # ]
305 [ # # ]: 0 : if (neglect_pawhat==0) then
306 [ # # # # : 0 : ABI_MALLOC(phkxred_diel,(2,natom))
# # # # #
# # # ]
307 [ # # ]: 0 : ABI_MALLOC(kpg_dum,(0,0))
308 [ # # # # ]: 0 : kpt_diel(1:3,1)=zero;phkxred_diel(1,:)=one;phkxred_diel(2,:)=zero;nkpg_diel=0
309 : : ! write(std_out,*) ' lmax_diel ', lmax_diel
310 : 0 : call pawgylmg(gprimd,gylmg_diel,kg_diel,kpg_dum,kpt_diel,lmax_diel,nkpg_diel,npwdiel,ntypat,pawtab,ylmdiel)
311 : 0 : call ph1d3d(1,natom,kg_diel,natom,natom,npwdiel,ndiel1,ndiel2,ndiel3,phkxred_diel,ph1ddiel,ph3d_diel)
312 [ # # ]: 0 : ABI_FREE(phkxred_diel)
313 [ # # ]: 0 : ABI_FREE(kpg_dum)
314 : : else
315 [ # # # # : 0 : gylmg_diel=zero;ph3d_diel=one
# # # # #
# # # ]
316 : : end if
317 : : else
318 [ - + ]: 82 : ABI_MALLOC(gylmg_diel,(0,0,0))
319 [ - + ]: 82 : ABI_MALLOC(ph3d_diel,(0,0,0))
320 : : end if
321 : :
322 : 82 : call timab(741,2,tsec)
323 : :
324 : :
325 : :
326 : : !--BIG loop over spins ------------------------------------------------------------
327 : : !---------------------------------------------------------------------------------
328 : :
329 [ + + ]: 168 : do isp=1,nsppol
330 : 86 : ikg=0
331 : :
332 [ + + + + : 307385 : if(extrap==1)rhoextrap(:,:,:,:)=zero
+ + + + +
+ ]
333 : :
334 : : ! --BIG loop over k-points --------------------------------------------------------
335 : : ! ---------------------------------------------------------------------------------
336 : :
337 [ + + ]: 424 : do ikpt=1,nkpt
338 : :
339 : 338 : nband_k=nband(ikpt+(isp-1)*nkpt)
340 : 338 : istwf_k=istwfk(ikpt)
341 : 338 : npw_k=npwarr(ikpt)
342 : :
343 [ + + ]: 338 : if(proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isp,mpi_enreg%me_kpt)) then
344 : 16 : bdtot_index=bdtot_index+nband_k
345 : 16 : cycle
346 : : end if
347 : :
348 : 322 : call timab(742,1,tsec)
349 : :
350 : :
351 [ + - - + : 1610 : ABI_MALLOC(gbound,(2*mgfftdiel+8,2))
+ - + - +
- + - - +
- + ]
352 [ - + + - : 966 : ABI_MALLOC(kg_k,(3,npw_k))
+ - + - -
+ - + ]
353 : :
354 [ - + ]: 322 : if (usepaw==1) then
355 [ # # # # : 0 : ABI_MALLOC(cprj_k,(natom,my_nspinor*nband_k))
# # # # #
# # # # #
# # # # #
# # # ]
356 [ # # ]: 0 : if (neglect_pawhat==0) then
357 : 0 : call pawcprj_alloc(cprj_k,0,dimcprj)
358 [ # # ]: 0 : if (mpi_enreg%nproc_band==1) then
359 : : call pawcprj_get(atindx1,cprj_k,cprj,natom,1,ibg,ikpt,iorder_cprj,isp,&
360 : : & mband,mkmem,natom,nband_k,nband_k,my_nspinor,nsppol,unpaw,&
361 : 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
362 : : else
363 : 0 : nband_loc=nband_k/mpi_enreg%nproc_band
364 [ # # # # : 0 : ABI_MALLOC(cprj_loc,(natom,my_nspinor*nband_loc))
# # # # #
# # # # #
# # # # #
# # # ]
365 : 0 : call pawcprj_alloc(cprj_loc,0,dimcprj)
366 : : call pawcprj_get(atindx1,cprj_loc,cprj,natom,1,ibg,ikpt,iorder_cprj,isp,&
367 : : & mband/mpi_enreg%nproc_band,mkmem,natom,nband_loc,nband_loc,my_nspinor,nsppol,unpaw,&
368 : 0 : & mpicomm=mpi_enreg%comm_kpt,proc_distrb=mpi_enreg%proc_distrb)
369 : : call pawcprj_mpi_allgather(cprj_loc,cprj_k,natom,my_nspinor*nband_loc,mpi_enreg%bandpp,&
370 : 0 : & dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,ierr,rank_ordered=.true.)
371 : 0 : call pawcprj_free(cprj_loc)
372 [ # # # # : 0 : ABI_FREE(cprj_loc)
# # # # #
# ]
373 : : end if
374 : : else
375 : : !call pawcprj_nullify(cprj_k)
376 : : end if
377 : : else
378 [ - + - + ]: 322 : ABI_MALLOC(cprj_k,(0,0))
379 : : end if
380 : :
381 [ + + + + ]: 562306 : kg_k(:,1:npw_k)=kg(:,1+ikg:npw_k+ikg)
382 : 322 : call sphereboundary(gbound,istwf_k,kg_k,mgfftdiel,npw_k)
383 : :
384 [ + + ]: 322 : if(extrap==1)then
385 : : ! Compute inverse of average dielectric gap for each band
386 : : ! and multiply by occupation factor
387 [ + - - + : 4598 : emax=maxval(eigen(1+bdtot_index:nband_k+bdtot_index))
- - + + ]
388 [ + + ]: 4277 : do iband=1,nband_k
389 : : occ_deavg(iband)= occ(iband+bdtot_index)*dielam &
390 : 4277 : & / ( emax-eigen(iband+bdtot_index) + diegap )
391 : : end do
392 : : else
393 [ + + ]: 21 : occ_deavg(:)=zero
394 : : end if
395 : :
396 : 322 : call timab(742,2,tsec)
397 : 322 : call timab(743,1,tsec)
398 : :
399 : : ! Compute the contribution of each k-point to susmat, rhoextrap, drhode and sumdocc.
400 [ - + ]: 322 : if(mpi_enreg%paral_kgb==1)then !Only this version is in parallel
401 : : ! Use either the simpler implementation
402 : : ! Should provide a test !!!
403 : : call susk(atindx,bdtot_index,cg,cprj_k,doccde,drhode,eigen,extrap,gbound,&
404 : : & gbound_diel,gylmg_diel,icg,ikpt,&
405 : : & isp,istwf_k,kg_diel,kg_k,lmax_diel,mband,mcg,mgfftdiel,mpi_enreg,&
406 : : & natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat,ngfftdiel,nkpt,&
407 : : & npwdiel,npw_k,nspden,nspden_eff,nspinor,nsppol,ntypat,occ,occopt,occ_deavg,&
408 : : & pawang,pawtab,ph3d_diel,rhoextrap,sumdocc,&
409 : 0 : & susmat,typat,ucvol,usepaw,wtk)
410 : : else
411 : : ! Or the more sophisticated one, needed to save memory.
412 : : call suskmm(atindx,bdtot_index,cg,cprj_k,doccde,drhode,eigen,extrap,gbound,&
413 : : & gbound_diel,gylmg_diel,icg,ikpt,&
414 : : & isp,istwf_k,kg_diel,kg_k,lmax_diel,mband,mcg,mgfftdiel,mpi_enreg,&
415 : : & natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat,ngfftdiel,nkpt,&
416 : : & npwdiel,npw_k,nspden,nspden_eff,nspinor,nsppol,ntypat,occ,occopt,occ_deavg,&
417 : : & pawang,pawtab,ph3d_diel,rhoextrap,sumdocc,&
418 : 322 : & susmat,typat,ucvol,usepaw,wtk)
419 : : end if
420 : :
421 : 322 : call timab(743,2,tsec)
422 : :
423 [ - + ]: 322 : ABI_FREE(gbound)
424 [ - + ]: 322 : ABI_FREE(kg_k)
425 : :
426 : 322 : bdtot_index=bdtot_index+nband_k
427 : :
428 [ + - ]: 322 : if (mkmem/=0) then
429 : 322 : ibg=ibg+my_nspinor*nband_k
430 : 322 : icg=icg+my_nspinor*npw_k*nband_k
431 : 322 : ikg=ikg+npw_k
432 : : end if
433 [ - + ]: 322 : if (usepaw==1) then
434 [ # # ]: 0 : if (neglect_pawhat==0) then
435 : 0 : call pawcprj_free(cprj_k)
436 : : end if
437 : : end if
438 [ + - - + : 408 : ABI_FREE(cprj_k)
- - - - -
+ ]
439 : :
440 : : ! End loop on ikpt: --------------------------------------------------------
441 : : end do
442 : :
443 : : ! Here include the contribution from the extrapolation to susmat,
444 : : ! diagonal part
445 [ + + ]: 168 : if(extrap==1)then
446 : :
447 : 85 : call timab(744,1,tsec)
448 : :
449 : : ! Transfer extrapolating density on augmented fft grid to
450 : : ! normal fft grid in real space.
451 : : ! Warning1 : if collinear magnetism, must treat only one spin at a time
452 : : ! Warning2 : if non-collinear magnetism, treat both spins
453 : : ! Warning3 : this is subtle for antiferro magnetism
454 [ - + ]: 85 : nspden_tmp=1;if (antiferro) nspden_tmp=2
455 [ - + + - : 340 : ABI_MALLOC(rhoextrr,(nfftdiel,nspden_tmp))
- + + - +
- + - - +
- + ]
456 [ - + + - : 255 : ABI_MALLOC(rhoextrg,(2,nfftdiel))
+ - + - -
+ - + ]
457 [ + + - + : 85 : if (nspden==1.and.nspinor==2) rhoextrap(:,:,:,1)=rhoextrap(:,:,:,1)+rhoextrap(:,:,:,2)
- - - - -
- ]
458 : :
459 [ + + ]: 170 : do ispinor=1,min(nspinor,nspden)
460 : 85 : jsp=isp+ispinor-1
461 : :
462 : : call fftpac(1,mpi_enreg_diel,1,ndiel1,ndiel2,ndiel3,ndiel4,ndiel5,ndiel6,&
463 : 85 : & ngfftdiel,rhoextrr(:,1),rhoextrap(:,:,:,ispinor),1)
464 : :
465 : : ! Generate the density in reciprocal space, and symmetrize it
466 : : ! (note symrhg also make the reverse FFT, to get symmetrized density;
467 : : ! this is useless here, and should be made an option)
468 : : call symrhg(1,gprimd,irrzondiel,mpi_enreg_diel,nfftdiel,nfftdiel,ngfftdiel,&
469 : 85 : & nspden_tmp,1,nsym,phnonsdiel,rhoextrg,rhoextrr,rprimd,symafm,symrel,tnons)
470 : :
471 [ + + ]: 12559 : do ipw2=1,npwdiel
472 : 12389 : j1=kg_diel(1,ipw2) ; j2=kg_diel(2,ipw2) ; j3=kg_diel(3,ipw2)
473 : : ! static: Only fills lower half of the matrix (here, the susceptibility matrix)
474 : : ! dynamical: fill all, will not affect susopt==2 for which extrap==0
475 [ + + ]: 2872583 : do ipw1=1,npwdiel
476 : 2860109 : i1=kg_diel(1,ipw1) ; i2=kg_diel(2,ipw1) ; i3=kg_diel(3,ipw1)
477 : : ! NOTE that there is a FFT folding (superposition) bias here
478 : : ! Should use kgindex, in the same spirit as in prcref
479 : 2860109 : k1=i1-j1; k1=modulo(k1,ndiel1)
480 : 2860109 : k2=i2-j2; k2=modulo(k2,ndiel2)
481 : 2860109 : k3=i3-j3; k3=modulo(k3,ndiel3)
482 : 2860109 : ifft=k1+1+ndiel1*(k2+ndiel2*k3)
483 : 2860109 : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+rhoextrg(1,ifft)
484 : 2872498 : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+rhoextrg(2,ifft)
485 : : end do
486 : : end do
487 : :
488 : : end do
489 [ - + ]: 85 : ABI_FREE(rhoextrg)
490 [ - + ]: 85 : ABI_FREE(rhoextrr)
491 : :
492 : 85 : call timab(744,2,tsec)
493 : :
494 : : end if
495 : :
496 : : ! End loop over spins ---------------------------------------------------------
497 : : end do
498 : :
499 [ - + ]: 82 : ABI_FREE(occ_deavg)
500 [ - + ]: 82 : ABI_FREE(rhoextrap)
501 [ - + ]: 82 : ABI_FREE(gylmg_diel)
502 [ - + ]: 82 : ABI_FREE(ph3d_diel)
503 : : !end if
504 : :
505 : 82 : call destroy_mpi_enreg(mpi_enreg_diel)
506 : :
507 : : !-- Stuff for parallelism --------------------------------------------------------
508 : : !---------------------------------------------------------------------------------
509 : :
510 : : if(xmpi_paral==1)then
511 : 82 : call timab(746,1,tsec)
512 [ + - - + : 246 : ABI_MALLOC(sussum,(2*npwdiel*nspden*npwdiel*nspden))
+ - + - +
- - + -
+ ]
513 : : ! Recreate full susmat on all proc.
514 : : ! This should be coded more efficiently,
515 : : ! since half of the matrix is still empty, and
516 : : ! it is spin-diagonal.
517 [ + + ]: 164 : sussum(:)=reshape(susmat(:,:,:,:,:),(/2*npwdiel*nspden*npwdiel*nspden/))
518 : 82 : call xmpi_sum(sussum,spaceComm,ierr)
519 [ + + ]: 492 : susmat(:,:,:,:,:)=reshape(sussum(:),(/2,npwdiel,nspden,npwdiel,nspden/))
520 [ - + ]: 82 : ABI_FREE(sussum)
521 : : ! Recreate full drhode on all proc.
522 [ + + ]: 82 : if(occopt>=3 .and. testocc==1)then
523 : 57 : call xmpi_sum(drhode,spaceComm,ierr)
524 : : ! Should use only one mpi-allreduce call instead of the three
525 : 57 : call xmpi_sum(sumdocc,spaceComm,ierr)
526 : : end if
527 : 164 : call timab(746,2,tsec)
528 : : end if
529 : :
530 : : !-- Apply spatial hermitian/symmetries on spin-diagonal susceptibility matrix ----
531 : : !---------------------------------------------------------------------------------
532 : :
533 : 82 : call timab(747,1,tsec)
534 : :
535 : : !If antiferro magnetism, has to divide (spin-diagonal) susceptibility by 2 (due to dble occupations)
536 [ - + ]: 82 : if (antiferro) then
537 [ # # ]: 0 : do ipw2=1,npwdiel
538 [ # # ]: 0 : do ipw1=ipw2,npwdiel
539 [ # # ]: 0 : susmat(:,ipw1,1,ipw2,1)=half*susmat(:,ipw1,1,ipw2,1)
540 : : end do
541 : : end do
542 : : end if
543 : :
544 : : !Generate upper half of the spin-diagonal matrix (still the susceptibility matrix)
545 [ + + ]: 168 : do isp=1,nspden_eff
546 [ + + ]: 12648 : do ipw2=2,npwdiel
547 [ + + ]: 1452002 : do ipw1=1,ipw2-1
548 : 1439436 : susmat(1,ipw1,isp,ipw2,isp)= susmat(1,ipw2,isp,ipw1,isp)
549 : 1451916 : susmat(2,ipw1,isp,ipw2,isp)=-susmat(2,ipw2,isp,ipw1,isp)
550 : : end do
551 : : end do
552 : : end do
553 : :
554 : : !Compute symmetric of G-vectors and eventual phases
555 : : !(either time-reversal or spatial symmetries)
556 [ - + + - : 246 : ABI_MALLOC(tmrev_g,(npwdiel))
+ - + - -
+ - + ]
557 [ - + + - : 328 : ABI_MALLOC(sym_g,(npwdiel,nsym))
- + + - +
- + - - +
- + ]
558 [ - + + - : 328 : ABI_MALLOC(phdiel,(2,npwdiel,nsym))
- + + - +
- + - - +
- + ]
559 : 82 : call symg(kg_diel,npwdiel,nsym,phdiel,sym_g,symrel,tmrev_g,tnons)
560 : :
561 : : !Impose spatial symmetries to the spin-diagonal susceptibility matrix
562 [ - + + - : 410 : ABI_MALLOC(suswk,(2,npwdiel,npwdiel,nspden_eff))
- + + - -
+ + - + -
+ - - + -
+ ]
563 [ + + ]: 168 : do isp=1,nspden_eff
564 [ + + + + : 8687048 : suswk(:,:,:,isp)=susmat(:,:,isp,:,isp) ! Temporary storage
+ + ]
565 : : end do
566 : :
567 [ + + ]: 168 : do isp=1,nspden_eff
568 : 86 : jsp=min(3-isp,nsppol)
569 [ + + ]: 12734 : do ipw2=1,npwdiel
570 [ + + ]: 2904090 : do ipw1=1,npwdiel
571 : 2891438 : ar=suswk(1,ipw1,ipw2,isp)
572 : 2891438 : ai=suswk(2,ipw1,ipw2,isp)
573 : 2891438 : ar2=zero;ai2=zero
574 [ + + ]: 2891438 : if(nsym>1)then
575 [ + + ]: 8888932 : do isym=2,nsym
576 : 8230736 : t1=sym_g(ipw1,isym) ; t2=sym_g(ipw2,isym)
577 : : ! Not all symmetries are non-symmorphic. Should save time here ...
578 : 8230736 : phr1=phdiel(1,ipw1,isym) ; phi1=phdiel(2,ipw1,isym)
579 : 8230736 : phr2=phdiel(1,ipw2,isym) ; phi2=phdiel(2,ipw2,isym)
580 : 8230736 : phr12= phr1*phr2+phi1*phi2 ; phi12=phi1*phr2-phr1*phi2
581 [ + - ]: 8888932 : if (symafm(isym)==1) then
582 : 8230736 : ar=ar+suswk(1,t1,t2,isp)*phr12-suswk(2,t1,t2,isp)*phi12
583 : 8230736 : ai=ai+suswk(2,t1,t2,isp)*phr12+suswk(1,t1,t2,isp)*phi12
584 : : else
585 : 0 : ar2=ar2+suswk(1,t1,t2,jsp)*phr12-suswk(2,t1,t2,jsp)*phi12
586 : 0 : ai2=ai2+suswk(2,t1,t2,jsp)*phr12+suswk(1,t1,t2,jsp)*phi12
587 : : end if
588 : : end do
589 : : end if
590 [ - + ]: 2904004 : if (antiferro) then
591 : 0 : susmat(1,ipw1,1,ipw2,1)=ar*invnsym1
592 : 0 : susmat(2,ipw1,1,ipw2,1)=ai*invnsym1
593 : 0 : susmat(1,ipw1,2,ipw2,2)=ar2*invnsym2
594 : 0 : susmat(2,ipw1,2,ipw2,2)=ai2*invnsym2
595 : : else
596 : 2891438 : susmat(1,ipw1,isp,ipw2,isp)=(ar+ar2)*invnsym
597 : 2891438 : susmat(2,ipw1,isp,ipw2,isp)=(ai+ai2)*invnsym
598 : : end if
599 : : end do
600 : : end do
601 : : end do
602 [ - + ]: 82 : ABI_FREE(suswk)
603 : :
604 : :
605 : : !-- Add contribibution to susceptibility due to change of Fermi level -----------
606 : : !---------------------------------------------------------------------------------
607 : :
608 [ + + ]: 82 : if (occopt>=3.and.testocc==1) then
609 : :
610 : : ! Impose spatial symmetries to drhode
611 [ - + + - : 228 : ABI_MALLOC(drhode_wk,(2,npwdiel,nspden_eff))
- + + - +
- + - - +
- + ]
612 [ + + ]: 116 : do isp=1,nspden_eff
613 : 59 : jsp=min(3-isp,nsppol)
614 [ + + ]: 5659 : do ipw1=1,npwdiel
615 : 5543 : ar=drhode(1,ipw1,isp)
616 : 5543 : ai=drhode(2,ipw1,isp)
617 : 5543 : ar2=zero;ai2=zero
618 [ + - ]: 5543 : if (nsym>1) then
619 [ + + ]: 79744 : do isym=2,nsym
620 : 74201 : t1=sym_g(ipw1,isym)
621 : : ! Not all symmetries are non-symmorphic. Should save time here ...
622 : 74201 : phr1=phdiel(1,ipw1,isym);phi1=phdiel(2,ipw1,isym)
623 [ + - ]: 79744 : if (symafm(isym)==1) then
624 : 74201 : ar=ar+drhode(1,t1,isp)*phr1-drhode(2,t1,isp)*phi1
625 : 74201 : ai=ai+drhode(2,t1,isp)*phr1+drhode(1,t1,isp)*phi1
626 : : else
627 : 0 : ar2=ar2+drhode(1,t1,jsp)*phr1-drhode(2,t1,jsp)*phi1
628 : 0 : ai2=ai2+drhode(2,t1,jsp)*phr1+drhode(1,t1,jsp)*phi1
629 : : end if
630 : : end do
631 : : end if
632 [ - + ]: 5602 : if (antiferro) then ! 1/2 factor due to (dble) occupations
633 : 0 : drhode_wk(1,ipw1,1)=half*ar*invnsym1
634 : 0 : drhode_wk(2,ipw1,1)=half*ai*invnsym1
635 : 0 : drhode_wk(1,ipw1,2)=half*ar2*invnsym2
636 : 0 : drhode_wk(2,ipw1,2)=half*ai2*invnsym2
637 : : else
638 : 5543 : drhode_wk(1,ipw1,isp)=(ar+ar2)*invnsym
639 : 5543 : drhode_wk(2,ipw1,isp)=(ai+ai2)*invnsym
640 : : end if
641 : : end do
642 : : end do
643 : :
644 : : ! Add contribution to non-diagonal susceptibility
645 : : ! Presently fills complete susceptibility matrix, not only lower half
646 : 57 : weight=one/sumdocc
647 [ + + ]: 116 : do isp2=1,nspden_eff
648 [ + + ]: 5659 : do ipw2=1,npwdiel
649 [ + + ]: 11205 : do isp1=1,nspden_eff
650 [ + + ]: 638913 : do ipw1=1,npwdiel
651 : : susmat(1,ipw1,isp1,ipw2,isp2)=susmat(1,ipw1,isp1,ipw2,isp2)- &
652 : : & weight*( drhode_wk(1,ipw1,isp1)*drhode_wk(1,ipw2,isp2) &
653 : 627767 : & +drhode_wk(2,ipw1,isp1)*drhode_wk(2,ipw2,isp2) )
654 : : susmat(2,ipw1,isp1,ipw2,isp2)=susmat(2,ipw1,isp1,ipw2,isp2)- &
655 : : & weight*( drhode_wk(2,ipw1,isp1)*drhode_wk(1,ipw2,isp2) &
656 : 633370 : & -drhode_wk(1,ipw1,isp1)*drhode_wk(2,ipw2,isp2) )
657 : : end do
658 : : end do
659 : : end do
660 : : end do
661 [ - + ]: 57 : ABI_FREE(drhode_wk)
662 : :
663 : : end if
664 : : !if (occopt>=3) then
665 [ - + ]: 82 : ABI_FREE(drhode)
666 : : !end if
667 : :
668 : :
669 : : !--- Impose the time-reversal symmetry to the susceptibility matrix --------------
670 : : !---------------------------------------------------------------------------------
671 : :
672 [ + - ]: 82 : if (usetimerev==1) then
673 [ - + + - : 328 : ABI_MALLOC(suswk,(2,npwdiel,npwdiel,1))
- + + - +
- + - - +
- + ]
674 : :
675 : : ! Impose the time-reversal symmetry to the spin-diagonal susceptibility matrix
676 [ + + ]: 168 : do isp=1,nspden_eff
677 [ + + + + : 8686966 : suswk(:,:,:,1)=susmat(:,:,isp,:,isp) ! Temporary storage
+ + ]
678 [ + + ]: 12734 : do ipw2=1,npwdiel
679 : 12566 : t2=tmrev_g(ipw2)
680 [ + + ]: 2904090 : do ipw1=1,npwdiel
681 : 2891438 : t1=tmrev_g(ipw1)
682 : 2891438 : susmat(1,ipw1,isp,ipw2,isp)=half*(suswk(1,ipw1,ipw2,1)+suswk(1,t1,t2,1))
683 : 2904004 : susmat(2,ipw1,isp,ipw2,isp)=half*(suswk(2,ipw1,ipw2,1)-suswk(2,t1,t2,1))
684 : : end do
685 : : end do
686 : : end do
687 : :
688 : : ! Impose the time-reversal symmetry to the off-diagonal susceptibility matrix
689 [ + + + + ]: 82 : if (nspden_eff/=1.and.occopt>=3.and.testocc==1) then
690 [ + + + + : 1382 : suswk(:,:,:,1)=susmat(:,:,1,:,2) ! Temporary storage
+ + ]
691 [ + + ]: 32 : do ipw2=1,npwdiel
692 : 30 : t2=tmrev_g(ipw2)
693 [ + + ]: 482 : do ipw1=1,npwdiel
694 : 450 : t1=tmrev_g(ipw1)
695 : 450 : ar=half*(suswk(1,ipw1,ipw2,1)+suswk(1,t1,t2,1))
696 : 450 : ai=half*(suswk(2,ipw1,ipw2,1)-suswk(2,t1,t2,1))
697 : 450 : susmat(1,ipw1,1,ipw2,2)= ar
698 : 450 : susmat(2,ipw1,1,ipw2,2)= ai
699 : 450 : susmat(1,ipw1,2,ipw2,1)= ar
700 : 480 : susmat(2,ipw1,2,ipw2,1)=-ai
701 : : end do
702 : : end do
703 : : end if
704 [ - + ]: 82 : ABI_FREE(suswk)
705 : : end if
706 : :
707 [ - + ]: 82 : ABI_FREE(phdiel)
708 [ - + ]: 82 : ABI_FREE(sym_g)
709 [ - + ]: 82 : ABI_FREE(tmrev_g)
710 : :
711 : :
712 : : !-- The full susceptibility matrix is computed -----------------------------------
713 : : !-- Now, eventually diagonalize it and stop --------------------------------------
714 : : !---------------------------------------------------------------------------------
715 : :
716 : : !Must turn on this flag to make the diagonalisation
717 : 82 : diag=0
718 : : if(diag==1)then
719 : :
720 : : npwsp=npwdiel*nspden_eff
721 : : ABI_MALLOC(sush,(npwsp*(npwsp+1)))
722 : : ABI_MALLOC(susvec,(2,npwsp,npwsp))
723 : : ABI_MALLOC(eig_diel,(npwsp))
724 : : ABI_MALLOC(zhpev1,(2,2*npwsp-1))
725 : : ABI_MALLOC(zhpev2,(3*npwsp-2))
726 : : ier=0
727 : :
728 : : ! Store the susceptibility matrix in proper mode before calling zhpev
729 : : indx=1
730 : : do ii=1,npwdiel
731 : : do jj=1,ii
732 : : sush(indx )=susmat(1,jj,1,ii,1)
733 : : sush(indx+1)=susmat(2,jj,1,ii,1)
734 : : indx=indx+2
735 : : end do
736 : : end do
737 : :
738 : : ! If spin-polarized, need to store other parts of the matrix
739 : : if(nspden_eff/=1)then
740 : : do ii=1,npwdiel
741 : : ! Here, spin-flip contribution
742 : : do jj=1,npwdiel
743 : : sush(indx )=susmat(1,jj,1,ii,2)
744 : : sush(indx+1)=susmat(2,jj,1,ii,2)
745 : : indx=indx+2
746 : : end do
747 : : ! Here spin down-spin down upper matrix
748 : : do jj=1,ii
749 : : sush(indx )=susmat(1,jj,2,ii,2)
750 : : sush(indx+1)=susmat(2,jj,2,ii,2)
751 : : indx=indx+2
752 : : end do
753 : : end do
754 : : end if
755 : :
756 : : call ZHPEV ('V','U',npwsp,sush,eig_diel,susvec,npwsp,zhpev1,&
757 : : & zhpev2,ier)
758 : :
759 : : write(std_out,*)' suscep_stat : print eigenvalues of the susceptibility matrix'
760 : : do ii=1,npwsp
761 : : write(std_out,'(i5,es16.6)' )ii,eig_diel(ii)
762 : : end do
763 : :
764 : : ABI_FREE(sush)
765 : : ABI_FREE(susvec)
766 : : ABI_FREE(eig_diel)
767 : : ABI_FREE(zhpev1)
768 : : ABI_FREE(zhpev2)
769 : : ABI_ERROR("Stopping here!")
770 : : end if
771 : :
772 : 82 : call timab(747,2,tsec)
773 : 82 : call timab(740,2,tsec)
774 : :
775 [ - + - + : 82 : end subroutine suscep_stat
- + - + -
+ - + - +
- + - + -
+ - + - +
- - - - -
- - + - -
- - - - ]
776 : : !!***
777 : :
778 : : !!****f* m_suscep_stat/susk
779 : : !! NAME
780 : : !! susk
781 : : !!
782 : : !! FUNCTION
783 : : !! Compute the contribution of one k point to the susceptibility matrix
784 : : !! from input wavefunctions, band occupations, and k point wts.
785 : : !! Include the usual sum-over-state terms, but also the
786 : : !! corrections due to the change of the Fermi level in the metallic
787 : : !! case, as well as implicit sum over higher lying conduction
788 : : !! states, thanks to the closure relation (referred to as an extrapolation).
789 : : !! Compared to the routine suskmm, there is no particular attention
790 : : !! to the use of the memory, so the code is simpler.
791 : : !!
792 : : !! INPUTS
793 : : !! atindx(natom)=index table for atoms
794 : : !! bdtot_index=index for the number of the band
795 : : !! cg(2,mcg)=wfs in G space
796 : : !! cprj_k(natom,nspinor*nband_k)= wave functions projected with non-local projectors:
797 : : !! cprj_k=<p_i|Cnk> where p_i is a non-local projector.
798 : : !! doccde(mband*nkpt*nsppol)=derivative of occupancies wrt
799 : : !! the energy for each band and k point
800 : : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
801 : : !! extrap: if==1, the closure relation (an extrapolation) must be used
802 : : !! gbound(2*mgfftdiel+8,2)=G sphere boundary for going from WF sphere to
803 : : !! medium size FFT grid
804 : : !! gbound_diel(2*mgfftdiel+8,2)=G sphere boundary for going from medium size
805 : : !! FFT grid to small sphere.
806 : : !! gylmg_diel(npwdiel,lmax_diel,ntypat*usepaw)= -PAW only- Fourier transform of g_l(r).Y_ml(r) shape functions
807 : : !! for dielectric matrix
808 : : !! icg=index for cg
809 : : !! ikpt=number of the k point
810 : : !! isp=number of the current spin
811 : : !! istwf_k=input option parameter that describes the storage of wfs
812 : : !! kg_diel(3,npwdiel)=reduced planewave coordinates for the dielectric matrix.
813 : : !! kg_k(3,npw_k)=coordinates of planewaves in basis sphere.
814 : : !! lmax_diel=1+max. value of l angular momentum used for dielectric matrix
815 : : !! mband=maximum number of bands
816 : : !! mcg=dimension of cg
817 : : !! mgfftdiel=maximum size of 1D FFTs, for the computation of
818 : : !! the dielectric matrix
819 : : !! mpi_enreg=information about MPI parallelization
820 : : !! natom=number of atoms in cell
821 : : !! nband_k=number of bands at this k point for that spin polarization
822 : : !! ndiel4,ndiel5,ndiel6= FFT dimensions, modified to avoid cache trashing
823 : : !! neglect_pawhat=1 if PAW contribution from hat density (compensation charge)
824 : : !! has to be neglected (to be used when only an estimation of
825 : : !! suscep. matrix has to be evaluated, i.e. for SCF precondictioning)
826 : : !! ngfftdiel(18)=contain all needed information about 3D FFT, for dielectric matrix,
827 : : !! see ~abinit/doc/variables/vargs.htm#ngfft
828 : : !! nkpt=number of k points
829 : : !! npwdiel=third and fifth dimension of the susmat array.
830 : : !! npw_k=number of plane waves at this k point
831 : : !! nspden=number of spin-density components
832 : : !! nspden_eff=number of spin-density components actually computed in sussceptibility
833 : : !! nspinor=number of spinorial components of the wavefunctions
834 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
835 : : !! ntypat=number of types of atoms in unit cell.
836 : : !! occ(mband*nkpt*nsppol)=
837 : : !! occupation numbers for each band (usually 2.0) at each k point
838 : : !! occopt=option for occupancies
839 : : !! occ_deavg(mband)=factor for extrapolation (occup. divided by an energy gap)
840 : : !! pawang <type(pawang_type)>=paw angular mesh and related data
841 : : !! pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
842 : : !! ph3d_diel(2,npwdiel,natom*usepaw)=3-dim structure factors, for each atom and plane wave, for dielectric matrix
843 : : !! typat(natom)=type (integer) for each atom
844 : : !! ucvol=unit cell volume (Bohr**3)
845 : : !! usepaw=flag for PAW
846 : : !! wtk(nkpt)=k point weights (they sum to 1.0)
847 : : !!
848 : : !! OUTPUT
849 : : !! (see side effects)
850 : : !!
851 : : !! SIDE EFFECTS
852 : : !! These quantities are accumulated in this routine:
853 : : !! drhode(2,npwdiel,nspden_eff)=weighted density, needed to compute the
854 : : !! effect of change of fermi energy
855 : : !! rhoextrap(ndiel4,ndiel5,ndiel6,nspinor)=density-like array, needed for the
856 : : !! extrapolation procedure.
857 : : !! sumdocc=sum of weighted occupation numbers, needed to compute the
858 : : !! effect of change of fermi energy
859 : : !! susmat(2,npwdiel,nspden,npwdiel,nspden)=
860 : : !! the susceptibility (or density-density response) matrix in reciprocal space
861 : : !!
862 : : !! NOTES
863 : : !! Band-fft parallel treatment: Each processor will treat his own band, but susmat will be known by all.
864 : : !! This means that cg will not have the same meaning in sequential or parallel mode.
865 : : !! In parallel mode, it will contain the set of all bands treated by the currrent processor.
866 : : !! To achieve this, the argument cg has been replaced by cg_mpi, with the "target" attribute.
867 : : !! In sequential mode, the pointer cg will point towards cg_mpi. In parallel mode, cg will point
868 : : !! to a new array cg_local, containing the bands treated by the currrent processor.
869 : : !! This allows to minimize the overhead incurred by the parallelization of the sequential version.
870 : : !! A similar treatment is performed on kg_k, npw_k.
871 : : !! A future version might have objects like kg_k_gather as arguments, instead of computing them.
872 : : !! This is in slight violation of programming rules, but I think it is safe, since the pointers remain local
873 : : !! GZ
874 : : !!
875 : : !! SOURCE
876 : :
877 : 0 : subroutine susk(atindx,bdtot_index,cg_mpi,cprj_k,doccde,drhode,eigen,extrap,gbound,&
878 : 0 : & gbound_diel,gylmg_diel,icg_mpi,ikpt,isp,istwf_k,kg_diel,kg_k_mpi,&
879 : : & lmax_diel,mband,mcg,mgfftdiel,mpi_enreg,&
880 : : & natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat,ngfftdiel,nkpt,&
881 : 0 : & npwdiel,npw_k_mpi,nspden,nspden_eff,nspinor,nsppol,ntypat,occ,occopt,occ_deavg,&
882 : 0 : & pawang,pawtab,ph3d_diel,rhoextrap,sumdocc,&
883 : 0 : & susmat,typat,ucvol,usepaw,wtk)
884 : :
885 : : !Arguments ------------------------------------
886 : : !This type is defined in defs_mpi
887 : : !scalars
888 : : integer,intent(in) :: bdtot_index,extrap,ikpt,isp,istwf_k,lmax_diel,mband,mcg
889 : : integer,intent(in) :: mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat
890 : : integer,intent(in) :: nkpt,npwdiel,nspden,nspden_eff,nspinor,nsppol
891 : : integer,intent(in) :: ntypat,occopt,usepaw
892 : : integer,intent(in),target :: icg_mpi,npw_k_mpi
893 : : real(dp),intent(in) :: ucvol
894 : : real(dp),intent(inout) :: sumdocc
895 : : type(MPI_type),intent(in) :: mpi_enreg
896 : : type(pawang_type),intent(in) :: pawang
897 : : !arrays
898 : : integer,intent(in) :: atindx(natom),gbound_diel(2*mgfftdiel+8,2)
899 : : integer,intent(in) :: kg_diel(3,npwdiel),ngfftdiel(18),typat(natom)
900 : : integer,intent(in),target :: kg_k_mpi(3,npw_k_mpi)
901 : : integer,intent(inout) :: gbound(2*mgfftdiel+8,2)
902 : 0 : integer,pointer :: kg_k(:,:)
903 : : real(dp),intent(in) :: doccde(mband*nkpt*nsppol),eigen(mband*nkpt*nsppol)
904 : : real(dp),intent(in) :: gylmg_diel(npwdiel,lmax_diel**2,ntypat*usepaw)
905 : : real(dp),intent(in) :: occ(mband*nkpt*nsppol),occ_deavg(mband)
906 : : real(dp),intent(in) :: ph3d_diel(2,npwdiel,natom*usepaw),wtk(nkpt)
907 : : real(dp),intent(in),target :: cg_mpi(2,mcg)
908 : : real(dp),intent(inout) :: drhode(2,npwdiel,nspden_eff)
909 : : real(dp),intent(inout) :: rhoextrap(ndiel4,ndiel5,ndiel6,nspinor)
910 : : real(dp),intent(inout) :: susmat(2,npwdiel,nspden,npwdiel,nspden)
911 : : type(pawcprj_type) :: cprj_k(natom,nspinor*nband_k*usepaw)
912 : : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
913 : :
914 : : !Local variables-------------------------------
915 : : ! real(dp), allocatable :: cg_disk(:,:)
916 : : !Local variables for MPI
917 : : !scalars
918 : : integer :: blocksize,i1,i2,i3,iband,iband_loc,ibd1,ibd2,ibdblock,ier
919 : : integer :: iproc,iproc_fft,ipw,ipw1,ipw2,isp1,isp2,ispinor,iwf,jsp,me_bandfft
920 : : integer :: nbdblock,ndatarecv,ndiel1,ndiel2,ndiel3
921 : : integer :: sizemax_per_proc,spaceComm,testocc,tim_fourwf
922 : : integer,pointer :: icg,npw_k
923 : : integer,target :: icg_loc=0,npw_k_loc,npw_tot
924 : : real(dp) :: eigdiff,occdiff,tolocc,weight,wght1,wght2
925 : 0 : type(MPI_type) :: mpi_enreg_diel
926 : : !arrays
927 : 0 : integer,allocatable :: band_loc(:),kg_k_gather(:,:),npw_per_proc(:),rdispls(:)
928 : 0 : integer,allocatable :: rdispls_all(:),rdisplsloc(:),recvcounts(:)
929 : 0 : integer,allocatable :: recvcountsloc(:),sdispls(:),sdisplsloc(:),sendcounts(:)
930 : 0 : integer,allocatable :: sendcountsloc(:)
931 : 0 : integer,allocatable,target :: kg_k_gather_all(:,:)
932 : : real(dp) :: tsec(2)
933 : 0 : real(dp),allocatable :: cwavef(:,:),cwavef_alltoall(:,:)
934 : 0 : real(dp),allocatable :: cwavef_alltoall_gather(:,:),dummy(:,:),rhoaug(:,:,:)
935 : 0 : real(dp),allocatable :: susmat_mpi(:,:,:)
936 : 0 : real(dp),allocatable :: wfprod(:,:),wfraug(:,:,:,:),wfrspa(:,:,:,:,:,:)
937 : 0 : real(dp),allocatable,target :: cg_local(:,:)
938 : 0 : real(dp),pointer :: cg(:,:)
939 : 0 : logical,allocatable :: treat_band(:)
940 : :
941 : : ! *************************************************************************
942 : :
943 : : !DEBUG
944 : : !write(std_out,*)' susk : enter '; stop
945 : : !ENDDEBUG
946 : :
947 : 0 : call timab(750,1,tsec)
948 : 0 : call timab(751,1,tsec)
949 : :
950 : 0 : ndiel1=ngfftdiel(1) ; ndiel2=ngfftdiel(2) ; ndiel3=ngfftdiel(3)
951 : :
952 : : !The dielectric stuff is performed in sequential mode.
953 : : !Set mpi_enreg_diel accordingly
954 : 0 : call initmpi_seq(mpi_enreg_diel)
955 : 0 : call mpi_enreg_diel%distribfft%init_seq('c',ngfftdiel(2),ngfftdiel(3),'all')
956 : 0 : me_bandfft=xmpi_comm_rank(mpi_enreg%comm_bandfft)
957 : :
958 : 0 : testocc=1
959 : : !DEBUG
960 : : !write(std_out,*)' susk : set testocc to 0 '
961 : : !testocc=0
962 : : !write(std_out,*)' susk : set extrap to 0 '
963 : : !extrap=0
964 : : !ENDDEBUG
965 : :
966 : : !Allocations, initializations
967 [ # # # # : 0 : ABI_MALLOC(rhoaug,(ndiel4,ndiel5,ndiel6))
# # # # #
# # # # #
# # # # #
# ]
968 [ # # # # : 0 : ABI_MALLOC(wfraug,(2,ndiel4,ndiel5,ndiel6))
# # # # #
# # # # #
# # # # #
# ]
969 [ # # # # : 0 : ABI_MALLOC(wfprod,(2,npwdiel))
# # # # #
# # # ]
970 [ # # # # : 0 : ABI_MALLOC(wfrspa,(2,ndiel4,ndiel5,ndiel6,nspinor,mband))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
971 [ # # ]: 0 : ABI_MALLOC(dummy,(2,1))
972 [ # # # # : 0 : wfrspa(:,:,:,:,:,:)=zero
# # # # #
# # # ]
973 [ # # # # : 0 : ABI_MALLOC(treat_band,(nband_k))
# # # # #
# # # ]
974 [ # # ]: 0 : treat_band(:)=.true.
975 : 0 : isp1=isp;isp2=isp
976 [ # # # # ]: 0 : if (nspden_eff==2.and.nspinor==2) isp2=isp+1
977 : :
978 : : !BAND-FFT parallelism
979 [ # # ]: 0 : if (mpi_enreg%paral_kgb==1) then
980 [ # # ]: 0 : treat_band(:)=.false.
981 : : ! We gather the wavefunctions treated by this proc in cg_local
982 : 0 : spaceComm=mpi_enreg%comm_band
983 : 0 : blocksize=mpi_enreg%nproc_band
984 : 0 : nbdblock=nband_k/blocksize
985 [ # # # # : 0 : ABI_MALLOC(sdispls,(blocksize))
# # # # #
# # # ]
986 [ # # # # : 0 : ABI_MALLOC(sdisplsloc,(blocksize))
# # # # ]
987 [ # # # # : 0 : ABI_MALLOC(sendcounts,(blocksize))
# # # # ]
988 [ # # # # : 0 : ABI_MALLOC(sendcountsloc,(blocksize))
# # # # ]
989 [ # # # # : 0 : ABI_MALLOC(rdispls,(blocksize))
# # # # ]
990 [ # # # # : 0 : ABI_MALLOC(rdisplsloc,(blocksize))
# # # # ]
991 [ # # # # : 0 : ABI_MALLOC(recvcounts,(blocksize))
# # # # ]
992 [ # # # # : 0 : ABI_MALLOC(recvcountsloc,(blocksize))
# # # # ]
993 : : ! First gather the kg_k in kg_k_gather_all
994 : 0 : npw_k_loc=npw_k_mpi
995 : 0 : call xmpi_allgather(npw_k_loc,recvcounts,spaceComm,ier)
996 : 0 : rdispls(1)=0
997 [ # # ]: 0 : do iproc=2,blocksize
998 : 0 : rdispls(iproc)=rdispls(iproc-1)+recvcounts(iproc-1)
999 : : end do
1000 : 0 : ndatarecv=rdispls(blocksize)+recvcounts(blocksize)
1001 [ # # # # : 0 : ABI_MALLOC(kg_k_gather,(3,ndatarecv))
# # # # #
# # # ]
1002 [ # # ]: 0 : recvcountsloc(:)=recvcounts(:)*3
1003 [ # # ]: 0 : rdisplsloc(:)=rdispls(:)*3
1004 : 0 : call xmpi_allgatherv(kg_k_mpi,3*npw_k_loc,kg_k_gather,recvcountsloc(:),rdisplsloc,spaceComm,ier)
1005 [ # # # # : 0 : ABI_MALLOC(npw_per_proc,(mpi_enreg%nproc_fft))
# # # # #
# # # ]
1006 [ # # # # : 0 : ABI_MALLOC(rdispls_all,(mpi_enreg%nproc_fft))
# # # # ]
1007 : 0 : spaceComm=mpi_enreg%comm_fft
1008 : 0 : call xmpi_allgather(ndatarecv,npw_per_proc,spaceComm,ier)
1009 : 0 : rdispls_all(1)=0
1010 [ # # ]: 0 : do iproc=2,mpi_enreg%nproc_fft
1011 : 0 : rdispls_all(iproc)=rdispls_all(iproc-1)+npw_per_proc(iproc-1)
1012 : : end do
1013 : 0 : npw_tot=rdispls_all(mpi_enreg%nproc_fft)+npw_per_proc(mpi_enreg%nproc_fft)
1014 [ # # # # : 0 : ABI_MALLOC(kg_k_gather_all,(3,npw_tot))
# # # # #
# # # ]
1015 [ # # # # : 0 : call xmpi_allgatherv(kg_k_gather,3*ndatarecv,kg_k_gather_all,3*npw_per_proc(:),3*rdispls_all,spaceComm,ier)
# # # # ]
1016 : : ! At this point kg_k_gather_all contains all the kg
1017 : : if(allocated(cwavef)) then
1018 : : ABI_FREE(cwavef)
1019 : : end if
1020 [ # # # # : 0 : ABI_MALLOC(cwavef,(2,npw_k_loc*nspinor*blocksize))
# # # # #
# # # ]
1021 : 0 : sizemax_per_proc=nband_k/(mpi_enreg%nproc_band*mpi_enreg%nproc_fft)+1
1022 [ # # # # : 0 : ABI_MALLOC(band_loc,(sizemax_per_proc))
# # # # #
# # # ]
1023 [ # # # # : 0 : ABI_MALLOC(cg_local,(2,sizemax_per_proc*npw_tot*nspinor))
# # # # #
# # # ]
1024 : 0 : iband_loc=0
1025 [ # # ]: 0 : do ibdblock=1,nbdblock
1026 : : cwavef(:,1:npw_k_loc*nspinor*blocksize)=&
1027 [ # # # # ]: 0 : & cg_mpi(:,1+(ibdblock-1)*npw_k_loc*nspinor*blocksize+icg_mpi:ibdblock*npw_k_loc*nspinor*blocksize+icg_mpi)
1028 [ # # ]: 0 : sendcounts(:)=npw_k_loc
1029 [ # # ]: 0 : do iproc=1,blocksize
1030 : 0 : sdispls(iproc)=(iproc-1)*npw_k_loc
1031 : : end do
1032 [ # # # # : 0 : ABI_MALLOC(cwavef_alltoall,(2,ndatarecv*nspinor))
# # # # #
# # # #
# ]
1033 [ # # ]: 0 : recvcountsloc(:)=recvcounts(:)*2*nspinor
1034 [ # # ]: 0 : rdisplsloc(:)=rdispls(:)*2*nspinor
1035 [ # # ]: 0 : sendcountsloc(:)=sendcounts(:)*2*nspinor
1036 [ # # ]: 0 : sdisplsloc(:)=sdispls(:)*2*nspinor
1037 : 0 : call timab(547,1,tsec)
1038 : 0 : spaceComm=mpi_enreg%comm_band
1039 : 0 : call xmpi_alltoallv(cwavef,sendcountsloc,sdisplsloc,cwavef_alltoall,recvcountsloc,rdisplsloc,spaceComm,ier)
1040 : 0 : call timab(547,2,tsec)
1041 [ # # # # : 0 : ABI_MALLOC(cwavef_alltoall_gather,(2,npw_tot*nspinor))
# # # # #
# # # #
# ]
1042 : 0 : blocksize=mpi_enreg%nproc_band
1043 : 0 : spaceComm=mpi_enreg%comm_fft
1044 : : call xmpi_allgatherv(cwavef_alltoall,2*nspinor*ndatarecv,cwavef_alltoall_gather,&
1045 [ # # # # ]: 0 : & 2*nspinor*npw_per_proc,2*nspinor*rdispls_all,spaceComm,ier)
1046 : 0 : iproc_fft=modulo(ibdblock-1,mpi_enreg%nproc_fft)
1047 [ # # ]: 0 : if(mpi_enreg%me_fft==iproc_fft) then !All nproc_band procs of index me_fft will treat these bands
1048 : 0 : iband_loc=iband_loc+1
1049 : 0 : iband=1+mpi_enreg%me_band+mpi_enreg%nproc_band*mpi_enreg%me_fft+(iband_loc-1)*mpi_enreg%nproc_fft*mpi_enreg%nproc_band
1050 : 0 : treat_band(iband)=.true.
1051 : 0 : band_loc(iband_loc)=iband
1052 [ # # # # ]: 0 : cg_local(:,1+(iband_loc-1)*npw_tot*nspinor:iband_loc*npw_tot*nspinor)=cwavef_alltoall_gather(:,1:npw_tot*nspinor)
1053 : : end if
1054 [ # # ]: 0 : ABI_FREE(cwavef_alltoall_gather)
1055 [ # # ]: 0 : ABI_FREE(cwavef_alltoall)
1056 : : end do
1057 : : ! On exit:
1058 : : ! npw_tot will be npw
1059 : : ! kg_k_gather_all will be kg_k
1060 : : ! cg_local will be cg
1061 : : ! icg will be zero
1062 : 0 : npw_k=>npw_tot
1063 : 0 : kg_k=>kg_k_gather_all(:,:)
1064 : 0 : cg=>cg_local(:,:)
1065 : 0 : icg=>icg_loc
1066 [ # # ]: 0 : call sphereboundary(gbound,istwf_k,kg_k,mgfftdiel,npw_k)
1067 : 0 : ABI_FREE(npw_per_proc)
1068 : 0 : ABI_FREE(rdispls_all)
1069 [ # # ]: 0 : ABI_FREE(sendcounts)
1070 : 0 : ABI_FREE(recvcounts)
1071 [ # # ]: 0 : ABI_FREE(sdispls)
1072 : 0 : ABI_FREE(rdispls)
1073 [ # # ]: 0 : ABI_FREE(sendcountsloc)
1074 [ # # ]: 0 : ABI_FREE(sdisplsloc)
1075 [ # # ]: 0 : ABI_FREE(recvcountsloc)
1076 [ # # ]: 0 : ABI_FREE(rdisplsloc)
1077 [ # # ]: 0 : ABI_FREE(kg_k_gather)
1078 [ # # ]: 0 : ABI_FREE(cwavef)
1079 : : ! Because they will be summed over all procs, and arrive on input, rescale drhode and rhoextrap
1080 [ # # # # : 0 : if(occopt>=3)drhode(:,:,isp1:isp2)=drhode(:,:,isp1:isp2)/real(mpi_enreg%nproc_fft*mpi_enreg%nproc_band,dp)
# # # # ]
1081 [ # # # # : 0 : if(extrap==1)rhoextrap(:,:,:,:)=rhoextrap(:,:,:,:)/real(mpi_enreg%nproc_fft*mpi_enreg%nproc_band,dp)
# # # # #
# ]
1082 [ # # ]: 0 : do i1=isp1,isp2
1083 [ # # # # : 0 : susmat(:,:,i1,:,i1)=susmat(:,:,i1,:,i1)/real(mpi_enreg%nproc_fft*mpi_enreg%nproc_band,dp)
# # ]
1084 : : end do
1085 : :
1086 : : ! No BAND-FFT parallelism
1087 : : else ! use argument variables
1088 : 0 : cg=>cg_mpi
1089 : 0 : kg_k=>kg_k_mpi
1090 : 0 : npw_k=>npw_k_mpi
1091 : 0 : icg=>icg_mpi
1092 : : end if
1093 : 0 : iband_loc=0
1094 : :
1095 : 0 : call timab(751,2,tsec)
1096 : 0 : call timab(752,1,tsec)
1097 : :
1098 : : !Loop over bands to fft and store Fourier transform of wavefunction
1099 [ # # # # : 0 : ABI_MALLOC(cwavef,(2,npw_k))
# # # # #
# # # #
# ]
1100 [ # # ]: 0 : do iband=1,nband_k
1101 [ # # ]: 0 : if(.not. treat_band(iband)) cycle ! I am not treating this band (only for the parallel case)
1102 : 0 : iband_loc=iband_loc+1
1103 : :
1104 : : ! Loop on spinorial components
1105 [ # # ]: 0 : do ispinor=1,nspinor
1106 : 0 : iwf=(ispinor-1)*npw_k+(iband_loc-1)*npw_k*nspinor+icg
1107 [ # # ]: 0 : jsp=isp+ispinor-1;if (nspden_eff==1) jsp=isp
1108 : :
1109 : : ! Obtain Fourier transform in fft box
1110 : 0 : tim_fourwf=8
1111 [ # # # # ]: 0 : cwavef(:,1:npw_k)=cg(:,1+iwf:npw_k+iwf)
1112 : : call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
1113 : : & istwf_k,kg_k,kg_k,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,npw_k,1,ndiel4,ndiel5,ndiel6,&
1114 [ # # # # ]: 0 : & 0,tim_fourwf,weight,weight)
1115 : :
1116 [ # # # # : 0 : wfrspa(:,:,:,:,ispinor,iband)=wfraug(:,:,:,:)
# # # # ]
1117 : :
1118 [ # # # # ]: 0 : if( (occopt>=3 .and. testocc==1) .or. extrap==1 )then
1119 : : ! In the case of metallic occupation, or if the extrapolation
1120 : : ! over higher bands is included, must compute the
1121 : : ! Fourier transform of the density of each band, then
1122 : : ! generate the part of the susceptibility matrix due
1123 : : ! varying occupation numbers.
1124 : :
1125 : 0 : weight=-two*occ_deavg(iband)*wtk(ikpt)/ucvol
1126 [ # # ]: 0 : do i3=1,ndiel3
1127 [ # # ]: 0 : do i2=1,ndiel2
1128 [ # # ]: 0 : do i1=1,ndiel1
1129 : 0 : wfraug(1,i1,i2,i3)=wfraug(1,i1,i2,i3)**2+wfraug(2,i1,i2,i3)**2
1130 : 0 : wfraug(2,i1,i2,i3)=zero
1131 : : end do
1132 : : end do
1133 : : ! If extrapolation, accumulate density in real space
1134 [ # # # # ]: 0 : if(extrap==1.and.usepaw==0)then
1135 [ # # ]: 0 : do i2=1,ndiel2
1136 [ # # ]: 0 : do i1=1,ndiel1
1137 : 0 : rhoextrap(i1,i2,i3,ispinor)=rhoextrap(i1,i2,i3,ispinor)+weight*wfraug(1,i1,i2,i3)
1138 : : end do
1139 : : end do
1140 : : end if
1141 : : end do
1142 : :
1143 : : ! In case of PAW, add compensation charge contribution
1144 [ # # # # : 0 : if (usepaw==1.and.extrap==1.and.neglect_pawhat==0) then
# # ]
1145 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,iband,iband,ispinor,ispinor,1,kg_diel,&
1146 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1147 : : & ngfftdiel,npwdiel,nspinor,ntypat,1,&
1148 : : & pawang,pawtab,ph3d_diel,typat,dummy,wfraug,&
1149 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1150 [ # # # # : 0 : rhoextrap(:,:,:,ispinor)=rhoextrap(:,:,:,ispinor)+weight*wfraug(1,:,:,:)
# # ]
1151 : : end if
1152 : :
1153 : : ! Performs the Fourier Transform of the density of the band,
1154 : : ! and store it in wfprod
1155 : 0 : tim_fourwf=9
1156 : : call fourwf(1,rhoaug,dummy,wfprod,wfraug,gbound_diel,gbound_diel,&
1157 : : & 1,kg_diel,kg_diel,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,1,npwdiel,&
1158 : 0 : & ndiel4,ndiel5,ndiel6,3,tim_fourwf,weight,weight)
1159 : : ! In case of PAW, add compensation charge contribution if not already done
1160 [ # # # # : 0 : if (usepaw==1.and.extrap==0.and.neglect_pawhat==0) then
# # ]
1161 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,ibd1,ibd2,ispinor,ispinor,1,kg_diel,&
1162 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1163 : : & ngfftdiel,npwdiel,nspinor,ntypat,0,&
1164 : : & pawang,pawtab,ph3d_diel,typat,wfprod,dummy,&
1165 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1166 : : end if
1167 : :
1168 : : ! Perform now the summation of terms related to direct change of eigenvalues
1169 : : ! or extrapolation over higher bands
1170 : 0 : wght1=zero ; wght2=zero
1171 [ # # ]: 0 : if(occopt>=3 .and. testocc==1) wght1=doccde(iband+bdtot_index)*wtk(ikpt)/ucvol
1172 [ # # ]: 0 : if(extrap==1) wght2=two*occ_deavg(iband)*wtk(ikpt)/ucvol
1173 : 0 : weight=wght1+wght2
1174 : :
1175 [ # # ]: 0 : if (abs(weight)>tol12) then
1176 [ # # ]: 0 : do ipw2=1,npwdiel
1177 : : ! Only fills lower half of the matrix (here, the susceptibility matrix)
1178 : : ! Note that wfprod of the first index must behave like a density,
1179 : : ! so that it is used as generated by fourwf, while wfprod of the
1180 : : ! second index will be implicitely used to make a scalar product
1181 : : ! with a potential change, meaning that its complex conjugate must be
1182 : : ! used. This explains the following signs...
1183 [ # # ]: 0 : do ipw1=ipw2,npwdiel
1184 : : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+&
1185 : 0 : & weight*(wfprod(1,ipw1)*wfprod(1,ipw2)+wfprod(2,ipw1)*wfprod(2,ipw2))
1186 : : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+&
1187 : 0 : & weight*(wfprod(2,ipw1)*wfprod(1,ipw2)-wfprod(1,ipw1)*wfprod(2,ipw2))
1188 : : end do
1189 : : end do
1190 : : end if
1191 : :
1192 [ # # # # ]: 0 : if( occopt>=3 .and. testocc==1 .and. abs(wght1)>tol12) then
1193 : : ! Accumulate product of band densities by their doccde, for the
1194 : : ! computation of the effect of change of Fermi level.
1195 [ # # ]: 0 : do ipw=1,npwdiel
1196 : 0 : drhode(1,ipw,jsp)=drhode(1,ipw,jsp)+wfprod(1,ipw)*wght1
1197 : 0 : drhode(2,ipw,jsp)=drhode(2,ipw,jsp)+wfprod(2,ipw)*wght1
1198 : : end do
1199 : : ! Also accumulate weighted sum of doccde
1200 : 0 : sumdocc=sumdocc+wght1
1201 : : end if
1202 : :
1203 : : ! End condition of metallic occupancies or extrapolation
1204 : : end if
1205 : :
1206 : : ! End loop on spinorial components
1207 : : end do
1208 : : ! End loop on iband
1209 : : end do
1210 : :
1211 : 0 : call timab(752,2,tsec)
1212 : 0 : call timab(753,1,tsec)
1213 : :
1214 [ # # ]: 0 : ABI_FREE(cwavef)
1215 : :
1216 : : !Stuff for parallelism (bands-FFT)
1217 [ # # ]: 0 : if(mpi_enreg%paral_kgb==1) then
1218 : 0 : call xmpi_sum(wfrspa,mpi_enreg%comm_bandfft,ier)
1219 [ # # ]: 0 : if(occopt>=3) then
1220 : 0 : call xmpi_sum(drhode(:,:,isp1:isp2),mpi_enreg%comm_bandfft,ier)
1221 : : end if
1222 [ # # ]: 0 : if(extrap==1) then
1223 : 0 : call xmpi_sum(rhoextrap,mpi_enreg%comm_bandfft,ier)
1224 : : end if
1225 [ # # ]: 0 : if(occopt>=3) then
1226 : 0 : call xmpi_sum(sumdocc,mpi_enreg%comm_bandfft,ier)
1227 : : end if
1228 [ # # # # : 0 : ABI_MALLOC(susmat_mpi,(2,npwdiel,npwdiel))
# # # # #
# # # # #
# # ]
1229 [ # # ]: 0 : do i1=isp1,isp2
1230 [ # # # # : 0 : susmat_mpi(:,:,:)=susmat(:,:,i1,:,i1)
# # ]
1231 : 0 : call xmpi_sum(susmat_mpi,mpi_enreg%comm_bandfft,ier)
1232 [ # # # # : 0 : susmat(:,:,i1,:,i1)=susmat_mpi(:,:,:)/real(mpi_enreg%nproc_fft*mpi_enreg%nproc_band,dp)
# # ]
1233 : : end do
1234 [ # # ]: 0 : ABI_FREE(susmat_mpi)
1235 : : end if
1236 : 0 : call timab(753,2,tsec)
1237 : :
1238 : : !-- Wavefunctions have been generated in real space ------------------------
1239 : : !-- Now, compute product of wavefunctions for different bands --------------
1240 : 0 : call timab(754,1,tsec)
1241 : : !if (occopt<3) then
1242 : 0 : tolocc=1.0d-3
1243 : : !else
1244 : : !tolocc=1.0d-8
1245 : : !end if
1246 : 0 : iproc=-1
1247 : :
1248 [ # # ]: 0 : if(nband_k>1)then
1249 [ # # ]: 0 : do ibd1=1,nband_k-1
1250 [ # # ]: 0 : do ibd2=ibd1+1,nband_k
1251 : 0 : iproc=iproc+1
1252 [ # # ]: 0 : if(modulo(iproc,mpi_enreg%nproc_fft*mpi_enreg%nproc_band) /= me_bandfft) cycle
1253 : : ! If the occupation numbers are sufficiently different, or
1254 : : ! if extrapolation is used and the corresponding factor is not zero,
1255 : : ! then there is a contribution
1256 : 0 : occdiff=occ(ibd1+bdtot_index)-occ(ibd2+bdtot_index)
1257 [ # # # # : 0 : if( abs(occdiff)>tolocc .or. &
# # ]
1258 : : & ( extrap==1 .and. &
1259 : : & ( abs(occ_deavg(ibd1)) + abs(occ_deavg(ibd2)) ) >tolocc ) &
1260 : 0 : & ) then
1261 : :
1262 : 0 : eigdiff=eigen(ibd1+bdtot_index)-eigen(ibd2+bdtot_index)
1263 : : ! DEBUG
1264 : : ! write(std_out,*)' susk : contribution from bands',ibd1,ibd2
1265 : : ! write(std_out,*)' occ diff =',occdiff
1266 : : ! write(std_out,*)' eig diff =',eigdiff
1267 : : ! ENDDEBUG
1268 : :
1269 : : ! Loop on spinorial components
1270 [ # # ]: 0 : do ispinor=1,nspinor
1271 [ # # ]: 0 : jsp=isp+ispinor-1;if (nspden_eff==1) jsp=isp
1272 : :
1273 : : ! Store the contribution in wfraug
1274 [ # # ]: 0 : do i3=1,ndiel3
1275 [ # # ]: 0 : do i2=1,ndiel2
1276 [ # # ]: 0 : do i1=1,ndiel1
1277 : : wfraug(1,i1,i2,i3)=wfrspa(1,i1,i2,i3,ispinor,ibd1)*wfrspa(1,i1,i2,i3,ispinor,ibd2)&
1278 : 0 : & +wfrspa(2,i1,i2,i3,ispinor,ibd1)*wfrspa(2,i1,i2,i3,ispinor,ibd2)
1279 : : wfraug(2,i1,i2,i3)=wfrspa(2,i1,i2,i3,ispinor,ibd1)*wfrspa(1,i1,i2,i3,ispinor,ibd2)&
1280 : 0 : & -wfrspa(1,i1,i2,i3,ispinor,ibd1)*wfrspa(2,i1,i2,i3,ispinor,ibd2)
1281 : : end do
1282 : : end do
1283 : : end do
1284 : :
1285 : : ! Performs the Fourier Transform of the product, and store it in wfprod
1286 : 0 : tim_fourwf=19
1287 : : call fourwf(1,rhoaug,dummy,wfprod,wfraug,gbound_diel,gbound_diel,&
1288 : : & 1,kg_diel,kg_diel,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,1,npwdiel,&
1289 : 0 : & ndiel4,ndiel5,ndiel6,3,tim_fourwf,weight,weight)
1290 : :
1291 : : ! In case of PAW, add compensation charge contribution
1292 [ # # # # ]: 0 : if (usepaw==1.and.neglect_pawhat==0) then
1293 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,ibd1,ibd2,ispinor,ispinor,1,kg_diel,&
1294 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1295 : : & ngfftdiel,npwdiel,nspinor,ntypat,0,&
1296 : : & pawang,pawtab,ph3d_diel,typat,wfprod,dummy,&
1297 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1298 : : end if
1299 : :
1300 : : ! Perform now the summation
1301 : 0 : wght1=zero ; wght2=zero
1302 [ # # ]: 0 : if(abs(occdiff)>tolocc) wght1= occdiff/eigdiff * two*wtk(ikpt)/ucvol
1303 [ # # ]: 0 : if(extrap==1) wght2=(occ_deavg(ibd1)+occ_deavg(ibd2)) * two*wtk(ikpt)/ucvol
1304 : 0 : weight=wght1+wght2
1305 : :
1306 : : ! DEBUG
1307 : : ! write(std_out,*)' weight =',weight
1308 : : ! norm=zero
1309 : : ! do ipw=1,npwdiel
1310 : : ! norm=norm+wfprod(1,ipw)**2+wfprod(2,ipw)**2
1311 : : ! end do
1312 : : ! write(std_out,*)' norm in reciprocal space =',norm
1313 : : ! ENDDEBUG
1314 : :
1315 [ # # ]: 0 : if (abs(weight)>tol12) then
1316 [ # # ]: 0 : do ipw2=1,npwdiel
1317 : : ! Only fills lower half of the matrix (here, the susceptibility matrix)
1318 : : ! Note that wfprod of the first index must behave like a density,
1319 : : ! so that it is used as generated by fourwf, while wfprod of the
1320 : : ! second index will be implicitely used to make a scalar product
1321 : : ! with a potential change, meaning that its complex conjugate must be
1322 : : ! used. This explains the following signs...
1323 [ # # ]: 0 : do ipw1=ipw2,npwdiel
1324 : : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+&
1325 : 0 : & weight*(wfprod(1,ipw1)*wfprod(1,ipw2)+wfprod(2,ipw1)*wfprod(2,ipw2))
1326 : : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+&
1327 : 0 : & weight*(wfprod(2,ipw1)*wfprod(1,ipw2)-wfprod(1,ipw1)*wfprod(2,ipw2))
1328 : : end do
1329 : : end do
1330 : : end if
1331 : :
1332 : : ! End loop on spinorial components
1333 : : end do
1334 : : ! End condition of different occupation numbers or extrapolation
1335 : : end if
1336 : : ! End internal loop over bands
1337 : : end do
1338 : : ! End external loop over bands
1339 : : end do
1340 : : ! End condition of having more than one band
1341 : : end if
1342 : :
1343 : 0 : call timab(754,2,tsec)
1344 : 0 : call timab(755,1,tsec)
1345 : :
1346 [ # # ]: 0 : if(mpi_enreg%paral_kgb==1) then
1347 [ # # # # : 0 : ABI_MALLOC(susmat_mpi,(2,npwdiel,npwdiel))
# # # # #
# # # # #
# # # # ]
1348 [ # # ]: 0 : do i1=isp1,isp2
1349 [ # # # # : 0 : susmat_mpi(:,:,:)=susmat(:,:,i1,:,i1)
# # ]
1350 : 0 : call xmpi_sum(susmat_mpi,mpi_enreg%comm_bandfft,ier)
1351 [ # # # # : 0 : susmat(:,:,i1,:,i1)=susmat_mpi(:,:,:)
# # ]
1352 : : end do
1353 [ # # ]: 0 : ABI_FREE(susmat_mpi)
1354 [ # # ]: 0 : ABI_FREE(band_loc)
1355 [ # # ]: 0 : ABI_FREE(treat_band)
1356 [ # # ]: 0 : ABI_FREE(cg_local)
1357 [ # # ]: 0 : ABI_FREE(kg_k_gather_all)
1358 : : end if
1359 : :
1360 : 0 : call destroy_mpi_enreg(mpi_enreg_diel)
1361 [ # # ]: 0 : ABI_FREE(dummy)
1362 [ # # ]: 0 : ABI_FREE(rhoaug)
1363 [ # # ]: 0 : ABI_FREE(wfprod)
1364 [ # # ]: 0 : ABI_FREE(wfraug)
1365 [ # # ]: 0 : ABI_FREE(wfrspa)
1366 : :
1367 : 0 : call timab(755,2,tsec)
1368 : 0 : call timab(750,2,tsec)
1369 : :
1370 [ # # # # : 0 : end subroutine susk
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
1371 : : !!***
1372 : :
1373 : : !!****f* m_suscep_stat/suskmm
1374 : : !! NAME
1375 : : !! suskmm
1376 : : !!
1377 : : !! FUNCTION
1378 : : !! Compute the contribution of one k point to the susceptibility matrix
1379 : : !! from input wavefunctions, band occupations, and k point wts.
1380 : : !! Include the usual sum-over-state terms, but also the
1381 : : !! corrections due to the change of the Fermi level in the metallic
1382 : : !! case, as well as implicit sum over higher lying conduction
1383 : : !! states, thanks to the closure relation (referred to as an extrapolation).
1384 : : !!
1385 : : !! This routine is similar to susk, but use blocking on wavefunctions
1386 : : !! to decrease memory requirements, at the expense of CPU time.
1387 : : !!
1388 : : !! NOTES
1389 : : !! There is still room for optimization !!
1390 : : !!
1391 : : !! INPUTS
1392 : : !! atindx(natom)=index table for atoms
1393 : : !! bdtot_index=index for the number of the band
1394 : : !! cg(2,mcg)=wf in G space
1395 : : !! cprj_k(natom,nspinor*nband_k)= wave functions projected with non-local projectors:
1396 : : !! cprj_k=<p_i|Cnk> where p_i is a non-local projector.
1397 : : !! doccde(mband*nkpt*nsppol)=derivative of occupancies wrt
1398 : : !! the energy for each band and k point
1399 : : !! eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
1400 : : !! extrap: if==1, the closure relation (an extrapolation) must be used
1401 : : !! gbound(2*mgfftdiel+8,2)=G sphere boundary for going from WF sphere to
1402 : : !! medium size FFT grid
1403 : : !! gbound_diel(2*mgfftdiel+8,2)=G sphere boundary for going from medium size
1404 : : !! FFT grid to small sphere.
1405 : : !! gylmg_diel(npwdiel,lmax_diel**2,ntypat*usepaw)= -PAW only- Fourier transform of g_l(r).Y_ml(r) shape functions
1406 : : !! for dielectric matrix
1407 : : !! icg=index for cg
1408 : : !! ikpt=number of the k point
1409 : : !! isp=number of the current spin
1410 : : !! istwf_k=input option parameter that describes the storage of wfs
1411 : : !! kg_diel(3,npwdiel)=reduced planewave coordinates for the dielectric matrix.
1412 : : !! kg_k(3,npw)=coordinates of planewaves in basis sphere.
1413 : : !! lmax_diel=1+max. value of l angular momentum used for dielectric matrix
1414 : : !! mband=maximum number of bands
1415 : : !! mcg=dimension of cg
1416 : : !! mgfftdiel=maximum size of 1D FFTs, for the computation of
1417 : : !! the dielectric matrix
1418 : : !! mpi_enreg=information about MPI parallelization
1419 : : !! natom=number of atoms in cell
1420 : : !! nband_k=number of bands at this k point for that spin polarization
1421 : : !! ndiel4,ndiel5,ndiel6= FFT dimensions, modified to avoid cache trashing
1422 : : !! neglect_pawhat=1 if PAW contribution from hat density (compensation charge)
1423 : : !! has to be neglected (to be used when only an estimation of
1424 : : !! suscep. matrix has to be evaluated, i.e. for SCF precondictioning)
1425 : : !! ngfftdiel(18)=contain all needed information about 3D FFT, for dielectric matrix,
1426 : : !! see ~abinit/doc/variables/vargs.htm#ngfft
1427 : : !! nkpt=number of k points
1428 : : !! npwdiel=third and fifth dimension of the susmat array.
1429 : : !! npw_k=number of plane waves at this k point
1430 : : !! nspden=number of spin-density components
1431 : : !! nspden_eff=number of spin-density components actually computed in sussceptibility
1432 : : !! nspinor=number of spinorial components of the wavefunctions
1433 : : !! nsppol=1 for unpolarized, 2 for spin-polarized
1434 : : !! ntypat=number of types of atoms in unit cell.
1435 : : !! occ(mband*nkpt*nsppol)=
1436 : : !! occupation numbers for each band (usually 2.0) at each k point
1437 : : !! occopt=option for occupancies
1438 : : !! occ_deavg(mband)=factor for extrapolation (occup. divided by an energy gap)
1439 : : !! pawang <type(pawang_type)>=paw angular mesh and related data
1440 : : !! pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
1441 : : !! ph3d_diel(2,npwdiel,natom*usepaw)=3-dim structure factors, for each atom and plane wave, for dielectric matrix
1442 : : !! typat(natom)=type (integer) for each atom
1443 : : !! ucvol=unit cell volume (Bohr**3)
1444 : : !! usepaw=flag for PAW
1445 : : !! wtk(nkpt)=k point weights (they sum to 1.0)
1446 : : !!
1447 : : !! OUTPUT
1448 : : !! (see side effects)
1449 : : !!
1450 : : !! SIDE EFFECTS
1451 : : !! drhode(2,npwdiel,nspden_eff)=weighted density, needed to compute the
1452 : : !! effect of change of fermi energy
1453 : : !! rhoextrap(ndiel4,ndiel5,ndiel6,nspinor)=density-like array, needed for the
1454 : : !! extrapolation procedure.
1455 : : !! sumdocc=sum of weighted occupation numbers, needed to compute the
1456 : : !! effect of change of fermi energy
1457 : : !! susmat(2,npwdiel,nspden,npwdiel,nspden)=
1458 : : !! the susceptibility (or density-density response) matrix in reciprocal space
1459 : : !!
1460 : : !! SOURCE
1461 : :
1462 : 322 : subroutine suskmm(atindx,bdtot_index,cg,cprj_k,doccde,drhode,eigen,extrap,gbound,&
1463 : 322 : & gbound_diel,gylmg_diel,icg,ikpt,isp,istwf_k,kg_diel,kg_k,&
1464 : : & lmax_diel,mband,mcg,mgfftdiel,mpi_enreg,&
1465 : : & natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat,ngfftdiel,nkpt,&
1466 : 322 : & npwdiel,npw_k,nspden,nspden_eff,nspinor,nsppol,ntypat,occ,occopt,occ_deavg,&
1467 : 322 : & pawang,pawtab,ph3d_diel,rhoextrap,sumdocc,&
1468 : 322 : & susmat,typat,ucvol,usepaw,wtk)
1469 : :
1470 : : !Arguments ------------------------------------
1471 : : !scalars
1472 : : integer,intent(in) :: bdtot_index,extrap,icg,ikpt,isp,istwf_k,lmax_diel,mband,mcg
1473 : : integer,intent(in) :: mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,neglect_pawhat
1474 : : integer,intent(in) :: nkpt,npw_k,npwdiel,nspden,nspden_eff,nspinor
1475 : : integer,intent(in) :: nsppol,ntypat,occopt,usepaw
1476 : : real(dp),intent(in) :: ucvol
1477 : : real(dp),intent(inout) :: sumdocc
1478 : : type(MPI_type),intent(in) :: mpi_enreg
1479 : : type(pawang_type),intent(in) :: pawang
1480 : : !arrays
1481 : : integer,intent(in) :: atindx(natom),gbound(2*mgfftdiel+8,2)
1482 : : integer,intent(in) :: gbound_diel(2*mgfftdiel+8,2)
1483 : : integer,intent(in) :: kg_diel(3,npwdiel),kg_k(3,npw_k),ngfftdiel(18)
1484 : : integer,intent(in) :: typat(natom)
1485 : : real(dp),intent(in) :: cg(2,mcg),doccde(mband*nkpt*nsppol)
1486 : : real(dp),intent(in) :: eigen(mband*nkpt*nsppol)
1487 : : real(dp),intent(in) :: gylmg_diel(npwdiel,lmax_diel**2,ntypat*usepaw)
1488 : : real(dp),intent(in) :: occ(mband*nkpt*nsppol),occ_deavg(mband)
1489 : : real(dp),intent(in) :: ph3d_diel(2,npwdiel,natom*usepaw),wtk(nkpt)
1490 : : real(dp),intent(inout) :: drhode(2,npwdiel,nspden_eff)
1491 : : real(dp),intent(inout) :: rhoextrap(ndiel4,ndiel5,ndiel6,nspinor)
1492 : : real(dp),intent(inout) :: susmat(2,npwdiel,nspden,npwdiel,nspden)
1493 : : type(pawcprj_type) :: cprj_k(natom,nspinor*nband_k*usepaw)
1494 : : type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
1495 : :
1496 : : !Local variables-------------------------------
1497 : : !scalars
1498 : : integer :: comm_fft,i1,i2,i3,iband,iband_shift,iband_shift2,ibd1,ibd2,ibdshft1,ibdshft2
1499 : : integer :: iblk1,iblk2,ipw,ipw1,ipw2,ispinor,iwf,jsp,mblk
1500 : : integer :: nblk,nbnd_current,nbnd_in_blk,nbnd_in_blk1,ndiel1,ndiel2,ndiel3
1501 : : integer :: testocc,tim_fourwf
1502 : : real(dp) :: eigdiff,occdiff,tolocc,weight,wght1,wght2
1503 : : character(len=500) :: message
1504 : 322 : type(MPI_type) :: mpi_enreg_diel
1505 : : !arrays
1506 : : real(dp) :: tsec(2)
1507 : 322 : real(dp),allocatable :: cwavef(:,:),dummy(:,:),rhoaug(:,:,:),wfprod(:,:)
1508 : 322 : real(dp),allocatable :: wfraug(:,:,:,:),wfrspa1(:,:,:,:,:,:)
1509 : 322 : real(dp),allocatable :: wfrspa2(:,:,:,:,:,:)
1510 : :
1511 : : ! *************************************************************************
1512 : :
1513 : 322 : call timab(760,1,tsec)
1514 : 322 : call timab(761,1,tsec)
1515 : :
1516 : : !Allocations, initializations
1517 : 322 : ndiel1=ngfftdiel(1) ; ndiel2=ngfftdiel(2) ; ndiel3=ngfftdiel(3)
1518 : 322 : testocc=1
1519 [ - + + - : 1610 : ABI_MALLOC(rhoaug,(ndiel4,ndiel5,ndiel6))
- + + - -
+ + - + -
+ - - + -
+ ]
1520 [ - + + - : 1610 : ABI_MALLOC(wfraug,(2,ndiel4,ndiel5,ndiel6))
- + + - -
+ + - + -
+ - - + -
+ ]
1521 [ - + + - : 966 : ABI_MALLOC(wfprod,(2,npwdiel))
+ - + - -
+ - + ]
1522 [ - + ]: 322 : ABI_MALLOC(dummy,(2,1))
1523 : :
1524 : : !The dielectric stuff is performed in sequential mode.
1525 : : !Set mpi_enreg_diel accordingly
1526 : 322 : call initmpi_seq(mpi_enreg_diel)
1527 : 322 : call mpi_enreg_diel%distribfft%init_seq('c',ngfftdiel(2),ngfftdiel(3),'all')
1528 : :
1529 : 322 : comm_fft=mpi_enreg%comm_fft
1530 : :
1531 : : !Prepare the blocking : compute the number of blocks,
1532 : : !the number of bands in each normal block,
1533 : : !and the number in the first one, usually smaller.
1534 : :
1535 : : !Consider that if the number of bands is large, there are at most 8 blocks
1536 : 322 : nbnd_in_blk=0
1537 [ - + ]: 322 : if(nband_k>=48)then
1538 : 0 : mblk=8
1539 : 0 : nbnd_in_blk=(nband_k-1)/mblk+1
1540 : : ! If the number of bands is medium, place 6 bands per block
1541 [ + + ]: 322 : else if(nband_k>=12)then
1542 : : nbnd_in_blk=6
1543 : : ! Otherwise, must have at least 2 blocks
1544 [ + - ]: 174 : else if(nband_k>=2)then
1545 : 174 : mblk=2
1546 : 174 : nbnd_in_blk=(nband_k-1)/mblk+1
1547 : : else
1548 : : write(message, '(a,a,a,i2,a,a,a)')&
1549 : 0 : & ' The number of bands must be larger or equal to 2, in suskmm.',ch10,&
1550 : 0 : & ' It is equal to ',nband_k,'.',ch10,&
1551 : 0 : & ' Action : choose another preconditioner.'
1552 : 0 : ABI_ERROR(message)
1553 : : end if
1554 : :
1555 : : !Compute the effective number of blocks, and the number of bands in
1556 : : !the first block.
1557 : 322 : nblk=(nband_k-1)/nbnd_in_blk+1
1558 : 322 : nbnd_in_blk1=nband_k-(nblk-1)*nbnd_in_blk
1559 : :
1560 : : !DEBUG
1561 : : !write(std_out,*)' suskmm : nband_k,nblk,nbnd_in_blk,nbnd_in_blk1 '
1562 : : !write(std_out,*)nband_k,nblk,nbnd_in_blk,nbnd_in_blk1
1563 : : !stop
1564 : : !ENDDEBUG
1565 : :
1566 : : !wfrspa1 will contain the wavefunctions of the slow sampling (iblk1)
1567 [ - + + - : 2254 : ABI_MALLOC(wfrspa1,(2,ndiel4,ndiel5,ndiel6,nspinor,nbnd_in_blk))
- + + - -
+ + - - +
+ - - + +
- + - + -
- + - + ]
1568 : : !wfrspa2 will contain the wavefunctions of the rapid sampling (iblk2)
1569 [ - + + - : 1932 : ABI_MALLOC(wfrspa2,(2,ndiel4,ndiel5,ndiel6,nspinor,nbnd_in_blk))
- + + - -
+ + - - +
+ - - + +
- - + -
+ ]
1570 : :
1571 [ - + + - : 966 : ABI_MALLOC(cwavef,(2,npw_k))
+ - + - -
+ - + ]
1572 : :
1573 : 322 : call timab(761,2,tsec)
1574 : :
1575 : : !First loop over blocks
1576 [ + + ]: 1146 : do iblk1=1,nblk
1577 : :
1578 : 824 : call timab(762,1,tsec)
1579 : :
1580 : : ! Initialisation
1581 [ + + ]: 824 : if(iblk1==1)then
1582 : :
1583 : 322 : nbnd_current=nbnd_in_blk1
1584 : 322 : iband_shift=0
1585 : : ! Loop over bands to fft and store Fourier transform of wavefunction
1586 [ + + ]: 1518 : do iband=1,nbnd_current
1587 : : ! Loop on spinorial components
1588 [ + + ]: 2714 : do ispinor=1,nspinor
1589 : 1196 : iwf=(ispinor-1)*npw_k+(iband-1)*npw_k*nspinor+icg
1590 : : ! Obtain Fourier transform in fft box
1591 : 1196 : tim_fourwf=21
1592 [ + + + + ]: 1650728 : cwavef(:,1:npw_k)=cg(:,1+iwf:npw_k+iwf)
1593 : : call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
1594 : : & istwf_k,kg_k,kg_k,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,npw_k,1,ndiel4,ndiel5,ndiel6,&
1595 : 1196 : & 0,tim_fourwf,weight,weight)
1596 [ + + + + : 12394496 : wfrspa1(:,:,:,:,ispinor,iband)=wfraug(:,:,:,:)
+ + + + ]
1597 : : end do
1598 : : end do
1599 : :
1600 : : else
1601 : :
1602 : : ! The Fourier transform of wavefunctions have already been obtained
1603 : 502 : nbnd_current=nbnd_in_blk
1604 : 502 : iband_shift=nbnd_in_blk1+(iblk1-2)*nbnd_in_blk
1605 : :
1606 : : end if
1607 : :
1608 : : ! Loop over bands of this block, to generate band-diagonal
1609 [ + + ]: 4800 : do iband=1,nbnd_current
1610 : :
1611 : : ! Loop on spinorial components
1612 [ + + ]: 8776 : do ispinor=1,nspinor
1613 [ + + ]: 3976 : jsp=isp+ispinor-1;if (nspden_eff==1) jsp=isp
1614 : :
1615 [ + + + + ]: 7952 : if( (occopt>=3 .and. testocc==1) .or. extrap==1 )then
1616 : : ! In the case of metallic occupation, or if the extrapolation
1617 : : ! over higher bands is included, must compute the
1618 : : ! Fourier transform of the density of each band, then
1619 : : ! generate the part of the susceptibility matrix due
1620 : : ! varying occupation numbers.
1621 : 3956 : weight=-two*occ_deavg(iband+iband_shift)*wtk(ikpt)/ucvol
1622 [ + + ]: 148632 : do i3=1,ndiel3
1623 [ + + ]: 1371076 : do i2=1,ndiel2
1624 [ + + ]: 11902916 : do i1=1,ndiel1
1625 : : wfraug(1,i1,i2,i3)=wfrspa1(1,i1,i2,i3,ispinor,iband)**2&
1626 : 10531840 : & +wfrspa1(2,i1,i2,i3,ispinor,iband)**2
1627 : 11758240 : wfraug(2,i1,i2,i3)=zero
1628 : : end do
1629 : : end do
1630 : : ! If extrapolation, accumulate density in real space
1631 [ + - + - ]: 148632 : if(extrap==1.and.usepaw==0)then
1632 [ + + ]: 1371076 : do i2=1,ndiel2
1633 [ + + ]: 11902916 : do i1=1,ndiel1
1634 : 11758240 : rhoextrap(i1,i2,i3,ispinor)=rhoextrap(i1,i2,i3,ispinor)+weight*wfraug(1,i1,i2,i3)
1635 : : end do
1636 : : end do
1637 : : end if
1638 : : end do
1639 : :
1640 : : ! In case of PAW, add compensation charge contribution
1641 [ - + - - : 3956 : if (usepaw==1.and.extrap==1.and.neglect_pawhat==0) then
- - ]
1642 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,iband,iband,ispinor,ispinor,1,kg_diel,&
1643 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1644 : : & ngfftdiel,npwdiel,nspinor,ntypat,1,&
1645 : : & pawang,pawtab,ph3d_diel,typat,dummy,wfraug,&
1646 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1647 [ # # # # : 0 : rhoextrap(:,:,:,ispinor)=rhoextrap(:,:,:,ispinor)+weight*wfraug(1,:,:,:)
# # ]
1648 : : end if
1649 : :
1650 : : ! Performs the Fourier Transform of the density of the band,
1651 : : ! and store it in wfprod
1652 : 3956 : tim_fourwf=31
1653 : : call fourwf(1,rhoaug,dummy,wfprod,wfraug,gbound_diel,gbound_diel,&
1654 : : & 1,kg_diel,kg_diel,&
1655 : 3956 : & mgfftdiel,mpi_enreg_diel,1,ngfftdiel,1,npwdiel,ndiel4,ndiel5,ndiel6,3,tim_fourwf,weight,weight)
1656 : : ! In case of PAW, add compensation charge contribution if not already done
1657 [ - + - - : 3956 : if (usepaw==1.and.extrap==0.and.neglect_pawhat==0) then
- - ]
1658 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,iband,iband,1,1,1,kg_diel,&
1659 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1660 : : & ngfftdiel,npwdiel,nspinor,ntypat,0,&
1661 : : & pawang,pawtab,ph3d_diel,typat,wfprod,dummy,&
1662 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1663 : : end if
1664 : :
1665 : : ! Perform now the summation of terms related to direct change of eigenvalues
1666 : : ! or extrapolation over higher bands
1667 : 3956 : wght1=zero ; wght2=zero
1668 [ + + ]: 3956 : if(occopt>=3 .and. testocc==1) wght1=doccde(iband+iband_shift+bdtot_index)*wtk(ikpt)/ucvol
1669 [ + - ]: 3956 : if(extrap==1) wght2=two*occ_deavg(iband+iband_shift)*wtk(ikpt)/ucvol
1670 : 3956 : weight=wght1+wght2
1671 : :
1672 [ + + ]: 3956 : if (abs(weight)>tol12) then
1673 [ + + ]: 534560 : do ipw2=1,npwdiel
1674 : : ! Only fills lower half of the matrix (here, the susceptibility matrix)
1675 : : ! Note that wfprod of the first index must behave like a density,
1676 : : ! so that it is used as generated by fourwf, while wfprod of the
1677 : : ! second index will be implicitely used to make a scalar product
1678 : : ! with a potential change, meaning that its complex conjugate must be
1679 : : ! used. This explains the following signs...
1680 [ + + ]: 58617240 : do ipw1=ipw2,npwdiel
1681 : : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+&
1682 : 58082680 : & weight*(wfprod(1,ipw1)*wfprod(1,ipw2)+wfprod(2,ipw1)*wfprod(2,ipw2))
1683 : : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+&
1684 : 58613559 : & weight*(wfprod(2,ipw1)*wfprod(1,ipw2)-wfprod(1,ipw1)*wfprod(2,ipw2))
1685 : : end do
1686 : : end do
1687 : : end if
1688 : :
1689 [ + + + + ]: 3956 : if( occopt>=3 .and. testocc==1 .and. abs(wght1)>tol12) then
1690 : : ! Accumulate product of band densities by their doccde, for the
1691 : : ! computation of the effect of change of Fermi level.
1692 [ + + ]: 222102 : do ipw=1,npwdiel
1693 : 219926 : drhode(1,ipw,jsp)=drhode(1,ipw,jsp)+wfprod(1,ipw)*wght1
1694 : 222102 : drhode(2,ipw,jsp)=drhode(2,ipw,jsp)+wfprod(2,ipw)*wght1
1695 : : end do
1696 : : ! Also accumulate weighted sum of doccde
1697 : 2176 : sumdocc=sumdocc+wght1
1698 : : end if
1699 : :
1700 : : ! End condition of metallic occupancies or extrapolation
1701 : : end if
1702 : :
1703 : : ! End loop on spinorial components
1704 : : end do
1705 : : ! End loop on iband
1706 : : end do
1707 : :
1708 : 824 : call timab(762,2,tsec)
1709 : :
1710 : : ! -- Compute now off-band-diagonal terms ------------------------------------
1711 : : ! -- Compute product of wavefunctions for different bands, inside the block -
1712 : :
1713 : 824 : call timab(763,1,tsec)
1714 : :
1715 : : ! if (occopt<3) then
1716 : 824 : tolocc=1.0d-3
1717 : : ! else
1718 : : ! tolocc=1.0d-8
1719 : : ! end if
1720 : :
1721 [ + - ]: 824 : if(nbnd_current>1)then
1722 [ + + ]: 3976 : do ibd1=1,nbnd_current-1
1723 : 3152 : ibdshft1=ibd1+iband_shift
1724 [ + + ]: 12304 : do ibd2=ibd1+1,nbnd_current
1725 : 8328 : ibdshft2=ibd2+iband_shift
1726 : :
1727 : : ! If the occupation numbers are sufficiently different, or
1728 : : ! if extrapolation is used and the corresponding factor is not zero,
1729 : : ! then there is a contribution
1730 : 8328 : occdiff=occ(ibdshft1+bdtot_index)-occ(ibdshft2+bdtot_index)
1731 [ + + + + : 8328 : if( abs(occdiff)>tolocc .or. &
+ + ]
1732 : : & ( extrap==1 .and. &
1733 : : & ( abs(occ_deavg(ibdshft1)) + abs(occ_deavg(ibdshft2)) ) >tolocc ) &
1734 : 3152 : & ) then
1735 : :
1736 : 7589 : eigdiff=eigen(ibdshft1+bdtot_index) - eigen(ibdshft2+bdtot_index)
1737 : :
1738 : : ! Loop on spinorial components
1739 [ + + ]: 15178 : do ispinor=1,nspinor
1740 [ + + ]: 7589 : jsp=isp+ispinor-1;if (nspden_eff==1) jsp=isp
1741 : :
1742 : : ! Store the contribution in wfraug
1743 [ + + ]: 291394 : do i3=1,ndiel3
1744 [ + + ]: 2711958 : do i2=1,ndiel2
1745 [ + + ]: 23602921 : do i1=1,ndiel1
1746 : : wfraug(1,i1,i2,i3)=wfrspa1(1,i1,i2,i3,ispinor,ibd1)*wfrspa1(1,i1,i2,i3,ispinor,ibd2)&
1747 : 20898552 : & +wfrspa1(2,i1,i2,i3,ispinor,ibd1)*wfrspa1(2,i1,i2,i3,ispinor,ibd2)
1748 : : wfraug(2,i1,i2,i3)=wfrspa1(2,i1,i2,i3,ispinor,ibd1)*wfrspa1(1,i1,i2,i3,ispinor,ibd2)&
1749 : 23319116 : & -wfrspa1(1,i1,i2,i3,ispinor,ibd1)*wfrspa1(2,i1,i2,i3,ispinor,ibd2)
1750 : : end do
1751 : : end do
1752 : : end do
1753 : :
1754 : : ! Performs the Fourier Transform of the product, and store it in wfprod
1755 : 7589 : tim_fourwf=32
1756 : : call fourwf(1,rhoaug,dummy,wfprod,wfraug,gbound_diel,gbound_diel,&
1757 : : & 1,kg_diel,kg_diel, mgfftdiel,mpi_enreg_diel,1,ngfftdiel,1,npwdiel,&
1758 : 7589 : & ndiel4,ndiel5,ndiel6,3,tim_fourwf,weight,weight)
1759 : :
1760 : : ! In case of PAW, add compensation charge contribution
1761 [ - + - - ]: 7589 : if (usepaw==1.and.neglect_pawhat==0) then
1762 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,ibd1,ibd2,ispinor,ispinor,1,kg_diel,&
1763 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1764 : : & ngfftdiel,npwdiel,nspinor,ntypat,0,&
1765 : : & pawang,pawtab,ph3d_diel,typat,wfprod,dummy,&
1766 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1767 : : end if
1768 : :
1769 : : ! Perform now the summation
1770 : 7589 : wght1=zero ; wght2=zero
1771 [ + + ]: 7589 : if(abs(occdiff)>tolocc) wght1= occdiff/eigdiff * two*wtk(ikpt)/ucvol
1772 [ + + ]: 7589 : if(extrap==1) wght2=(occ_deavg(ibdshft1)+occ_deavg(ibdshft2)) * two*wtk(ikpt)/ucvol
1773 : 7589 : weight=wght1+wght2
1774 : :
1775 [ + - ]: 15917 : if (abs(weight)>tol12) then
1776 [ + + ]: 1136872 : do ipw2=1,npwdiel
1777 : : ! Only fills lower half of the matrix (here, the susceptibility matrix)
1778 : : ! Note that wfprod of the first index must behave like a density,
1779 : : ! so that it is used as generated by fourwf, while wfprod of the
1780 : : ! second index will be implicitely used to make a scalar product
1781 : : ! with a potential change, meaning that its complex conjugate must be
1782 : : ! used. This explains the following signs...
1783 [ + + ]: 128619848 : do ipw1=ipw2,npwdiel
1784 : : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+&
1785 : 127482976 : & weight*(wfprod(1,ipw1)*wfprod(1,ipw2)+wfprod(2,ipw1)*wfprod(2,ipw2))
1786 : : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+&
1787 : 128612259 : & weight*(wfprod(2,ipw1)*wfprod(1,ipw2)-wfprod(1,ipw1)*wfprod(2,ipw2))
1788 : : end do
1789 : : end do
1790 : : end if
1791 : :
1792 : : ! End loop on spinorial components
1793 : : end do
1794 : : ! End condition of different occupation numbers or extrapolation
1795 : : end if
1796 : : ! End internal loop over bands
1797 : : end do
1798 : : ! End external loop over bands
1799 : : end do
1800 : : ! End condition of having more than one band
1801 : : end if
1802 : :
1803 : : ! Loop on secondary block, with fast varying index, in decreasing order.
1804 [ + + ]: 824 : if(iblk1/=nblk)then
1805 [ + + ]: 1228 : do iblk2=nblk,iblk1+1,-1
1806 : 726 : iband_shift2=nbnd_in_blk1+(iblk2-2)*nbnd_in_blk
1807 : :
1808 : : ! Loop over bands to fft and store Fourier transform of wavefunction
1809 : 726 : iband_shift2=nbnd_in_blk1+(iblk2-2)*nbnd_in_blk
1810 [ + + ]: 4850 : do iband=1,nbnd_in_blk
1811 : : ! Loop on spinorial components
1812 [ + + ]: 8974 : do ispinor=1,nspinor
1813 : 4124 : iwf=(ispinor-1)*npw_k+(iband+iband_shift2-1)*npw_k*nspinor+icg
1814 : :
1815 : : ! Obtain Fourier transform in fft box
1816 : 4124 : tim_fourwf=22
1817 [ + + + + ]: 4975922 : cwavef(:,1:npw_k)=cg(:,1+iwf:npw_k+iwf)
1818 : : call fourwf(1,rhoaug,cwavef,dummy,wfraug,gbound,gbound,&
1819 : : & istwf_k,kg_k,kg_k,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,npw_k,1,&
1820 : 4124 : & ndiel4,ndiel5,ndiel6,0,tim_fourwf,weight,weight)
1821 [ + + + + : 41682776 : wfrspa2(:,:,:,:,ispinor,iband)=wfraug(:,:,:,:)
+ + + + ]
1822 : : end do
1823 : : end do
1824 : :
1825 [ + + ]: 4270 : do ibd1=1,nbnd_current
1826 : 3042 : ibdshft1=ibd1+iband_shift
1827 [ + + ]: 21228 : do ibd2=1,nbnd_in_blk
1828 : 17460 : ibdshft2=ibd2+iband_shift2
1829 : :
1830 : : ! If the occupation numbers are sufficiently different, or
1831 : : ! if extrapolation is used and the corresponding factor is not zero,
1832 : : ! then there is a contribution
1833 : 17460 : occdiff=occ(ibdshft1+bdtot_index)-occ(ibdshft2+bdtot_index)
1834 [ + + + + : 17460 : if( abs(occdiff)>tolocc .or. &
+ + ]
1835 : : & ( extrap==1 .and. &
1836 : : & ( abs(occ_deavg(ibdshft1)) + abs(occ_deavg(ibdshft2)) ) >tolocc ) &
1837 : 3042 : & ) then
1838 : :
1839 : 16481 : eigdiff=eigen(ibdshft1+bdtot_index) - eigen(ibdshft2+bdtot_index)
1840 : :
1841 : : ! Loop on spinorial components
1842 [ + + ]: 32962 : do ispinor=1,nspinor
1843 [ + + ]: 16481 : jsp=isp+ispinor-1;if (nspden_eff==1) jsp=isp
1844 : :
1845 : : ! Store the contribution in wfraug
1846 [ + + ]: 608213 : do i3=1,ndiel3
1847 [ + + ]: 5696749 : do i2=1,ndiel2
1848 [ + + ]: 50025916 : do i1=1,ndiel1
1849 : : wfraug(1,i1,i2,i3)=wfrspa1(1,i1,i2,i3,ispinor,ibd1)*wfrspa2(1,i1,i2,i3,ispinor,ibd2)&
1850 : 44345648 : & +wfrspa1(2,i1,i2,i3,ispinor,ibd1)*wfrspa2(2,i1,i2,i3,ispinor,ibd2)
1851 : : wfraug(2,i1,i2,i3)=wfrspa1(2,i1,i2,i3,ispinor,ibd1)*wfrspa2(1,i1,i2,i3,ispinor,ibd2)&
1852 : 49434184 : & -wfrspa1(1,i1,i2,i3,ispinor,ibd1)*wfrspa2(2,i1,i2,i3,ispinor,ibd2)
1853 : : end do
1854 : : end do
1855 : : end do
1856 : :
1857 : : ! Performs the Fourier Transform of the product, and store it in wfprod
1858 : 16481 : tim_fourwf=32
1859 : : call fourwf(1,rhoaug,dummy,wfprod,wfraug,gbound_diel,gbound_diel,&
1860 : : & 1,kg_diel,kg_diel,mgfftdiel,mpi_enreg_diel,1,ngfftdiel,1,npwdiel,&
1861 : 16481 : & ndiel4,ndiel5,ndiel6,3,tim_fourwf,weight,weight)
1862 : :
1863 : : ! In case of PAW, add compensation charge contribution
1864 [ - + - - ]: 16481 : if (usepaw==1.and.neglect_pawhat==0) then
1865 : : call pawsushat(atindx,cprj_k,gbound_diel,gylmg_diel,ibd1,ibdshft2,ispinor,ispinor,1,kg_diel,&
1866 : : & lmax_diel,mgfftdiel,natom,nband_k,ndiel4,ndiel5,ndiel6,&
1867 : : & ngfftdiel,npwdiel,nspinor,ntypat,0,&
1868 : : & pawang,pawtab,ph3d_diel,typat,wfprod,dummy,&
1869 : 0 : & mpi_atmtab=mpi_enreg%my_atmtab,comm_atom=mpi_enreg%comm_atom)
1870 : : end if
1871 : :
1872 : : ! Perform now the summation
1873 : 16481 : wght1=zero ; wght2=zero
1874 [ + + ]: 16481 : if(abs(occdiff)>tolocc) wght1= occdiff/eigdiff * two*wtk(ikpt)/ucvol
1875 [ + + ]: 16481 : if(extrap==1) wght2=(occ_deavg(ibdshft1)+occ_deavg(ibdshft2)) * two*wtk(ikpt)/ucvol
1876 : 16481 : weight=wght1+wght2
1877 : :
1878 [ + - ]: 33941 : if (abs(weight)>tol12) then
1879 [ + + ]: 2417690 : do ipw2=1,npwdiel
1880 : : ! Only fills lower half of the matrix (here, the susceptibility matrix)
1881 : : ! Note that wfprod of the first index must behave like a density,
1882 : : ! so that it is used as generated by fourwf, while wfprod of the
1883 : : ! second index will be implicitely used to make a scalar product
1884 : : ! with a potential change, meaning that its complex conjugate must be
1885 : : ! used. This explains the following signs...
1886 [ + + ]: 284800175 : do ipw1=ipw2,npwdiel
1887 : : susmat(1,ipw1,jsp,ipw2,jsp)=susmat(1,ipw1,jsp,ipw2,jsp)+&
1888 : 282382485 : & weight*(wfprod(1,ipw1)*wfprod(1,ipw2)+wfprod(2,ipw1)*wfprod(2,ipw2))
1889 : : susmat(2,ipw1,jsp,ipw2,jsp)=susmat(2,ipw1,jsp,ipw2,jsp)+&
1890 : 284783694 : & weight*(wfprod(2,ipw1)*wfprod(1,ipw2)-wfprod(1,ipw1)*wfprod(2,ipw2))
1891 : : end do
1892 : : end do
1893 : : end if
1894 : :
1895 : : ! End loop on spinorial components
1896 : : end do
1897 : : ! End condition of different occupation numbers or extrapolation
1898 : : end if
1899 : : ! End internal loop over bands
1900 : : end do
1901 : : ! End external loop over bands
1902 : : end do
1903 : : ! End loop on bloks
1904 : : end do
1905 : :
1906 : : ! Finish the loop on blok with iblk2=iblk1+1, so can use the
1907 : : ! FFTd wavefunctions for the next iblk1.
1908 [ + + ]: 3282 : do iband=1,nbnd_in_blk
1909 [ + + + + : 28652370 : wfrspa1(:,:,:,:,1:nspinor,iband)=wfrspa2(:,:,:,:,1:nspinor,iband)
+ + + + +
+ ]
1910 : : end do
1911 : :
1912 : : ! End condition of iblk1/=nblk
1913 : : end if
1914 : :
1915 : 1146 : call timab(763,2,tsec)
1916 : :
1917 : : ! End loop on iblk1
1918 : : end do
1919 : :
1920 : : !DEBUG
1921 : : !write(std_out,*)' suskmm : exit '
1922 : : !do ipw1=1,npwdiel
1923 : : !write(std_out,*)ipw1,susmat(1,ipw1,1,ipw1,1),susmat(2,ipw1,1,ipw1,1)
1924 : : !end do
1925 : : !write(std_out,*)' suskmm : end of susmat '
1926 : : !stop
1927 : : !ENDDEBUG
1928 : :
1929 : 322 : call destroy_mpi_enreg(mpi_enreg_diel)
1930 [ - + ]: 322 : ABI_FREE(cwavef)
1931 [ - + ]: 322 : ABI_FREE(dummy)
1932 [ - + ]: 322 : ABI_FREE(rhoaug)
1933 [ - + ]: 322 : ABI_FREE(wfprod)
1934 [ - + ]: 322 : ABI_FREE(wfraug)
1935 [ - + ]: 322 : ABI_FREE(wfrspa1)
1936 [ - + ]: 322 : ABI_FREE(wfrspa2)
1937 : :
1938 : 322 : call timab(760,2,tsec)
1939 : :
1940 [ - + - + : 322 : end subroutine suskmm
- + - + -
+ - + - +
- + - + -
+ - + ]
1941 : : !!***
1942 : :
1943 : : end module m_suscep_stat
1944 : : !!***
|