Branch data Line data Source code
1 : : !!****m* ABINIT/m_pead_nl_loop
2 : : !! NAME
3 : : !! m_pead_nl_loop
4 : : !!
5 : : !! FUNCTION
6 : : !!
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2002-2026 ABINIT group (MVeithen,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_pead_nl_loop
23 : :
24 : : use defs_basis
25 : : use defs_wvltypes
26 : : use m_wffile
27 : : use m_abicore
28 : : use m_xmpi
29 : : use m_hdr
30 : : use m_dtset
31 : : use m_dtfil
32 : : USE_MPI
33 : :
34 : : use defs_datatypes, only : pseudopotential_type
35 : : use defs_abitypes, only : MPI_type
36 : : use m_time, only : timab
37 : : use m_kg, only : getph, mkkpg
38 : : use m_cgtools, only : dotprod_vn, dotprod_g
39 : : use m_fft, only : fourdp, fftpac, fourwf
40 : : use m_ioarr, only : read_rhor
41 : : use m_pawtab, only : pawtab_type
42 : : use m_pawrhoij, only : pawrhoij_type
43 : : use m_pawcprj, only : pawcprj_type
44 : : use m_inwffil, only : inwffil
45 : : use m_spacepar, only : hartre
46 : : use m_initylmg, only : initylmg
47 : : use m_dfpt_mkvxc, only : dfpt_mkvxc
48 : : use m_mkcore, only : dfpt_mkcore
49 : : use m_mklocl, only : dfpt_vlocal
50 : : use m_hamiltonian,only : gs_hamiltonian_type
51 : : use m_mkffnl, only : mkffnl
52 : : use m_mpinfo, only : proc_distrb_cycle
53 : : use m_nonlop, only : nonlop
54 : : use m_dfptnl_pert, only : dfptnl_exc3
55 : :
56 : : implicit none
57 : :
58 : : private
59 : :
60 : : #if defined HAVE_MPI1
61 : : include 'mpif.h'
62 : : #endif
63 : : !!***
64 : :
65 : : public :: pead_nl_loop
66 : : !!***
67 : :
68 : : contains
69 : : !!***
70 : :
71 : : !!****f* ABINIT/pead_nl_loop
72 : : !! NAME
73 : : !! pead_nl_loop
74 : : !!
75 : : !! FUNCTION
76 : : !! Loop over the perturbations j1, j2 and j3
77 : : !!
78 : : !! INPUTS
79 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol) = array for planewave coefficients of wavefunctions
80 : : !! cgindex(nkpt,nsppol) = for each k-point, cgindex tores the location
81 : : !! of the WF in the cg array
82 : : !! dtfil <type(datafiles_type)>=variables related to files
83 : : !! dtset <type(dataset_type)>=all input variables for this dataset
84 : : !! gmet(3,3)=reciprocal space metric tensor in bohr**-2
85 : : !! gprimd(3,3)=dimensional primitive translations for reciprocal space(bohr^-1)
86 : : !! gsqcut=Fourier cutoff on G^2 for "large sphere" of radius double
87 : : !! that of the basis sphere--appropriate for charge density rho(G),
88 : : !! Hartree potential, and pseudopotentials
89 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates
90 : : !! kneigh(30,nkpt) = index of the neighbours of each k-point
91 : : !! kg_neigh(30,nkpt,3) = necessary to construct the vector joining a k-point
92 : : !! to its nearest neighbour in case of a single k-point,
93 : : !! a line of k-points or a plane of k-points.
94 : : !! kptindex(2,nkpt3)= index of the k-points in the reduced BZ
95 : : !! related to a k-point in the full BZ
96 : : !! kpt3(3,nkpt3) = reduced coordinates of k-points in the full BZ
97 : : !! kxc(nfft,nkxc)=exchange-correlation kernel
98 : : !! k3xc(nfft,nk3xc)=third-order exchange-correlation kernel
99 : : !! mband = maximum number of bands
100 : : !! mgfft = maximum single fft dimension
101 : : !! mkmem = Number of k points treated by this node.
102 : : !! mkmem_max = maximal number of k-points on each processor (MPI //)
103 : : !! mk1mem = Number of k points for first-order WF treated by this node.
104 : : !! mpert =maximum number of ipert
105 : : !! mpi_enreg=MPI-parallelisation information
106 : : !! mpw = maximum number of planewaves in basis sphere (large number)
107 : : !! mvwtk(30,nkpt) = weights to compute the finite difference ddk
108 : : !! natom = number of atoms in unit cell
109 : : !! nfft = (effective) number of FFT grid points (for this processor)
110 : : !! nkpt = number of k points
111 : : !! nkpt3 = number of k-points in the full BZ
112 : : !! nkxc=second dimension of the array kxc, see rhohxc.f for a description
113 : : !! nneigh = total number of neighbours required to evaluate the finite
114 : : !! difference formula
115 : : !! nspinor = number of spinorial components of the wavefunctions
116 : : !! nsppol = number of channels for spin-polarization (1 or 2)
117 : : !! npwarr(nkpt) = array holding npw for each k point
118 : : !! occ(mband*nkpt*nsppol) = occupation number for each band and k
119 : : !! psps <type(pseudopotential_type)> = variables related to pseudopotentials
120 : : !! pwind(mpw,nneigh,mkmem) = array used to compute the overlap matrix smat
121 : : !! between k-points
122 : : !! rfpert(3,mpert,3,mpert,3,mpert) = array defining the type of perturbations
123 : : !! that have to be computed
124 : : !! 1 -> element has to be computed explicitely
125 : : !! -1 -> use symmetry operations to obtain the corresponding element
126 : : !! rprimd(3,3)=dimensional primitive translations (bohr)
127 : : !! ucvol = unit cell volume (bohr^3)
128 : : !! xred(3,natom) = reduced atomic coordinates
129 : : !!
130 : : !! OUTPUT
131 : : !! blkflg(3,mpert,3,mpert) = flags for each element of the 3DTE
132 : : !! (=1 if computed)
133 : : !! d3lo(2,3,mpert,3,mpert,3,mpert) = matrix of the 3DTEs
134 : : !!
135 : : !! SIDE EFFECTS
136 : : !! hdr <type(hdr_type)>=the header of wf, den and pot files
137 : : !!
138 : : !! SOURCE
139 : :
140 : 21 : subroutine pead_nl_loop(blkflg,cg,cgindex,dtfil,dtset,d3lo,&
141 : : & gmet,gprimd,gsqcut, &
142 : 21 : & hdr,kg,kneigh,kg_neigh,kptindex,kpt3,kxc,k3xc,mband,mgfft,mkmem,mkmem_max,mk1mem,&
143 : 21 : & mpert,mpi_enreg,mpw,mvwtk,natom,nfft,nkpt,nkpt3,nkxc,nk3xc,nneigh,nspinor,nsppol,&
144 : 21 : & npwarr,occ,psps,pwind,&
145 : 21 : & rfpert,rprimd,ucvol,xred)
146 : :
147 : : !Arguments ------------------------------------
148 : : !scalars
149 : : integer,intent(in) :: mband,mgfft,mk1mem,mkmem,mkmem_max,mpert,mpw,natom,nfft
150 : : integer,intent(in) :: nk3xc,nkpt,nkpt3,nkxc,nneigh,nspinor,nsppol
151 : : real(dp),intent(in) :: gsqcut,ucvol
152 : : type(MPI_type),intent(inout) :: mpi_enreg
153 : : type(datafiles_type),intent(in) :: dtfil
154 : : type(dataset_type),intent(inout) :: dtset
155 : : type(hdr_type),intent(inout) :: hdr
156 : : type(pseudopotential_type),intent(in) :: psps
157 : : !arrays
158 : : integer,intent(in) :: cgindex(nkpt,nsppol),kg(3,mk1mem*mpw),kneigh(30,nkpt)
159 : : integer,intent(in) :: kg_neigh(30,nkpt,3)
160 : : integer,intent(in) :: kptindex(2,nkpt3),npwarr(nkpt),pwind(mpw,nneigh,mkmem)
161 : : integer,intent(in) :: rfpert(3,mpert,3,mpert,3,mpert)
162 : : integer,intent(inout) :: blkflg(3,mpert,3,mpert,3,mpert) !vz_i
163 : : real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol),gmet(3,3)
164 : : real(dp),intent(in) :: gprimd(3,3),k3xc(nfft,nk3xc),kpt3(3,nkpt3)
165 : : real(dp),intent(in) :: kxc(nfft,nkxc),mvwtk(30,nkpt),rprimd(3,3)
166 : : real(dp),intent(in) :: xred(3,natom)
167 : : real(dp),intent(inout) :: occ(mband*nkpt*nsppol)
168 : : real(dp),intent(inout) :: d3lo(2,3,mpert,3,mpert,3,mpert) !vz_i
169 : :
170 : : !Local variables-------------------------------
171 : : !scalars
172 : : integer,parameter :: level=51
173 : : integer :: ask_accurate,counter,cplex,formeig,i1dir
174 : : integer :: i1pert,i2dir,i2pert,i3dir,i3pert,iatom,ierr,index,ir
175 : : integer :: ireadwf,itypat,mcg,mpsang,n1,n2,n3,n3xccc,nfftot,nspden,option,optorth
176 : : integer :: pert1case,pert2case,pert3case,rdwrpaw,timrev,comm_cell
177 : : logical :: nmxc
178 : : real(dp) :: ecut_eff,exc3(2)
179 : : character(len=500) :: message
180 : : character(len=fnlen) :: fiden1i,fiwf1i,fiwf3i
181 : : type(wffile_type) :: wff1,wff2,wfft1,wfft2
182 : 21 : type(wvl_data) :: wvl
183 : 21 : type(hdr_type) :: hdr_den
184 : : !arrays
185 : 21 : integer,allocatable :: atindx(:),atindx1(:),nattyp(:)
186 : : real(dp) :: d3_berry(2,3),rho_dum(1),tsec(2),ylmgr_dum(1)
187 : 21 : real(dp),allocatable :: cg1(:,:),cg3(:,:),eigen1(:),ph1d(:,:),rho1r1(:,:)
188 : 21 : real(dp),allocatable :: rho2g1(:,:),rho2r1(:,:),rho3r1(:,:),vhartr1(:)
189 : 21 : real(dp),allocatable :: vpsp1(:),vtrial1(:,:),vxc1(:,:),work(:)
190 : 21 : real(dp),allocatable :: xccc3d1(:),xccc3d2(:),xccc3d3(:),ylm(:,:,:)
191 : 21 : type(pawrhoij_type),allocatable :: rhoij_dum(:)
192 : :
193 : : ! ***********************************************************************
194 : :
195 : 21 : call timab(502,1,tsec)
196 : :
197 : 21 : comm_cell = mpi_enreg%comm_cell
198 : :
199 : 21 : timrev = 1
200 : 21 : cplex = 2 - timrev
201 : 21 : nspden = dtset%nspden
202 : 21 : ecut_eff = (dtset%ecut)*(dtset%dilatmx)**2
203 : 21 : mpsang = psps%mpsang
204 [ - + ]: 21 : optorth=1;if (psps%usepaw==1) optorth=0
205 : :
206 [ - + + - : 63 : ABI_MALLOC(cg1,(2,dtset%mpw*dtset%nspinor*mband*dtset%mk1mem*dtset%nsppol))
+ - + - -
+ - + ]
207 [ - + + - : 42 : ABI_MALLOC(cg3,(2,dtset%mpw*dtset%nspinor*mband*dtset%mk1mem*dtset%nsppol))
- + - + ]
208 [ + - - + : 63 : ABI_MALLOC(eigen1,(2*dtset%mband*dtset%mband*dtset%nkpt*dtset%nsppol))
+ - + - +
- - + -
+ ]
209 [ - + + - : 84 : ABI_MALLOC(rho1r1,(cplex*nfft,dtset%nspden))
- + + - +
- + - - +
- + ]
210 [ - + + - : 63 : ABI_MALLOC(rho2r1,(cplex*nfft,dtset%nspden))
- + + - -
+ - + ]
211 [ - + + - : 63 : ABI_MALLOC(rho2g1,(2,nfft))
+ - + - -
+ - + ]
212 [ - + + - : 63 : ABI_MALLOC(rho3r1,(cplex*nfft,dtset%nspden))
- + + - -
+ - + ]
213 [ - + + - : 84 : ABI_MALLOC(ylm,(2,dtset%mpw*dtset%mkmem,mpsang*mpsang*psps%useylm))
+ - - - +
- - + - +
- + ]
214 : :
215 : 21 : ask_accurate=1 ; formeig = 1 ; ireadwf = 1
216 : 21 : n1=dtset%ngfft(1) ; n2=dtset%ngfft(2) ; n3=dtset%ngfft(3)
217 : 21 : nfftot=n1*n2*n3
218 : :
219 : : !Generate an index table of atoms, in order for them to be used
220 : : !type after type.
221 [ - + + - : 63 : ABI_MALLOC(atindx,(natom))
+ - + - -
+ - + ]
222 [ - + + - : 42 : ABI_MALLOC(atindx1,(natom))
- + - + ]
223 [ - + + - : 63 : ABI_MALLOC(nattyp,(psps%ntypat))
+ - + - -
+ + - ]
224 : 56 : index=1
225 [ + + ]: 56 : do itypat=1,psps%ntypat
226 : 35 : nattyp(itypat)=0
227 [ + + ]: 126 : do iatom=1,natom
228 [ + + ]: 105 : if(dtset%typat(iatom)==itypat)then
229 : 42 : atindx(iatom)=index
230 : 42 : atindx1(index)=iatom
231 : 42 : index=index+1
232 : 42 : nattyp(itypat)=nattyp(itypat)+1
233 : : end if
234 : : end do
235 : : end do
236 : :
237 : : !Generate the 1-dimensional phases
238 [ + - - + : 63 : ABI_MALLOC(ph1d,(2,3*(2*mgfft+1)*natom))
+ - + - +
- - + -
+ ]
239 : 21 : call getph(atindx,natom,n1,n2,n3,ph1d,xred)
240 : :
241 : : !Set up the Ylm for each k point
242 [ - + ]: 21 : if (psps%useylm==1) then
243 : : call initylmg(gprimd,kg,dtset%kptns,dtset%mkmem,mpi_enreg,psps%mpsang,&
244 : : & dtset%mpw,dtset%nband,dtset%nkpt,&
245 : 0 : & npwarr,dtset%nsppol,0,rprimd,ylm,ylmgr_dum)
246 : : end if
247 : :
248 [ - + + - : 63 : ABI_MALLOC(vpsp1,(cplex*nfft))
+ - + - -
+ - + ]
249 [ - + + - : 42 : ABI_MALLOC(xccc3d1,(cplex*nfft))
- + - + ]
250 [ - + + - : 42 : ABI_MALLOC(xccc3d2,(cplex*nfft))
- + - + ]
251 [ - + + - : 42 : ABI_MALLOC(xccc3d3,(cplex*nfft))
- + - + ]
252 [ - + + - : 42 : ABI_MALLOC(vhartr1,(cplex*nfft))
- + - + ]
253 [ - + + - : 84 : ABI_MALLOC(vxc1,(cplex*nfft,dtset%nspden))
- + + - +
- + - - +
- + ]
254 [ - + + - : 63 : ABI_MALLOC(vtrial1,(cplex*nfft,dtset%nspden))
- + + - -
+ - + ]
255 : :
256 : : !Loop over the perturbations j1, j2, j3
257 : :
258 : 21 : pert1case = 0 ; pert2case = 0 ; pert3case = 0
259 : :
260 [ + + ]: 189 : do i1pert = 1, mpert
261 [ + + ]: 693 : do i1dir = 1, 3
262 : :
263 [ + + + + : 403872 : if ((maxval(rfpert(i1dir,i1pert,:,:,:,:))==1)) then
+ + + + +
+ ]
264 : :
265 : 70 : pert1case = i1dir + (i1pert-1)*3
266 : 70 : counter = pert1case
267 : 70 : call appdig(pert1case,dtfil%fnamewff1,fiwf1i)
268 : :
269 : 70 : mcg=mpw*nspinor*mband*mkmem*nsppol
270 : : call inwffil(ask_accurate,cg1,dtset,dtset%ecut,ecut_eff,eigen1,dtset%exchn2n3d,&
271 : : & formeig,hdr,ireadwf,dtset%istwfk,kg,dtset%kptns,dtset%localrdwf,&
272 : : & dtset%mband,mcg,dtset%mk1mem,mpi_enreg,mpw,&
273 : : & dtset%nband,dtset%ngfft,dtset%nkpt,npwarr,&
274 : : & dtset%nsppol,dtset%nsym,&
275 : : & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
276 : 70 : & dtfil%unkg1,wff1,wfft1,dtfil%unwff1,fiwf1i,wvl)
277 : :
278 : 70 : if (ireadwf==1) then
279 : 70 : call WffClose (wff1,ierr)
280 : : end if
281 : :
282 [ + + + + ]: 690345 : rho1r1(:,:) = 0._dp
283 [ - + - - ]: 70 : if (dtset%get1den /= 0 .or. dtset%ird1den /= 0) then
284 : 70 : rdwrpaw=0
285 : 70 : call appdig(pert1case,dtfil%fildens1in,fiden1i)
286 : :
287 : : call read_rhor(fiden1i, cplex, dtset%nspden, nfft, dtset%ngfft, rdwrpaw, mpi_enreg, rho1r1, &
288 : 70 : hdr_den, rhoij_dum, comm_cell, check_hdr=hdr)
289 : 70 : call hdr_den%free()
290 : : end if
291 : :
292 [ + + ]: 586966 : xccc3d1(:) = 0._dp
293 [ + + + + ]: 70 : if ((psps%n1xccc/=0).and.(i1pert <= natom)) then
294 : : call dfpt_mkcore(cplex,i1dir,i1pert,natom,psps%ntypat,n1,psps%n1xccc,&
295 : : & n2,n3,dtset%qptn,rprimd,dtset%typat,ucvol,&
296 : 22 : & psps%xcccrc,psps%xccc1d,xccc3d1,xred)
297 : : end if ! psps%n1xccc/=0
298 : :
299 [ + + ]: 630 : do i3pert = 1, mpert
300 [ + + ]: 2310 : do i3dir = 1, 3
301 : :
302 [ + + + + : 56000 : if ((maxval(rfpert(i1dir,i1pert,:,:,i3dir,i3pert))==1)) then
+ + ]
303 : :
304 : 145 : pert3case = i3dir + (i3pert-1)*3
305 : 145 : counter = 100*pert3case + pert1case
306 : 145 : call appdig(pert3case,dtfil%fnamewff1,fiwf3i)
307 : :
308 : 145 : mcg=mpw*nspinor*mband*mkmem*nsppol
309 : : call inwffil(ask_accurate,cg3,dtset,dtset%ecut,ecut_eff,eigen1,dtset%exchn2n3d,&
310 : : & formeig,hdr,ireadwf,dtset%istwfk,kg,dtset%kptns,dtset%localrdwf,&
311 : : & dtset%mband,mcg,dtset%mk1mem,mpi_enreg,mpw,&
312 : : & dtset%nband,dtset%ngfft,dtset%nkpt,npwarr,&
313 : : & dtset%nsppol,dtset%nsym,&
314 : : & occ,optorth,dtset%symafm,dtset%symrel,dtset%tnons,&
315 : : & dtfil%unkg1,wff2,wfft2,dtfil%unwff2,&
316 : 145 : & fiwf3i,wvl)
317 : 145 : if (ireadwf==1) then
318 : 145 : call WffClose (wff2,ierr)
319 : : end if
320 : :
321 [ + + + + ]: 1272062 : rho3r1(:,:) = 0._dp
322 [ - + - - ]: 145 : if (dtset%get1den /= 0 .or. dtset%ird1den /= 0) then
323 : 145 : rdwrpaw=0
324 : 145 : call appdig(pert3case,dtfil%fildens1in,fiden1i)
325 : :
326 : : call read_rhor(fiden1i, cplex, dtset%nspden, nfft, dtset%ngfft, rdwrpaw, mpi_enreg, rho3r1, &
327 : 145 : hdr_den, rhoij_dum, comm_cell, check_hdr=hdr)
328 : 145 : call hdr_den%free()
329 : : end if
330 : :
331 [ + + ]: 1076433 : xccc3d3(:) = 0._dp
332 [ + + - + ]: 145 : if ((psps%n1xccc/=0).and.(i3pert <= natom)) then
333 : : call dfpt_mkcore(cplex,i3dir,i3pert,natom,psps%ntypat,n1,psps%n1xccc,&
334 : : & n2,n3,dtset%qptn,rprimd,dtset%typat,ucvol,&
335 : 0 : & psps%xcccrc,psps%xccc1d,xccc3d3,xred)
336 : : end if ! psps%n1xccc/=0
337 : :
338 [ + + ]: 1305 : do i2pert = 1, mpert
339 : :
340 : : ! In case of electric field perturbation, evaluate the ddk
341 : : ! using the finite difference expression of
342 : : ! Marzari and Vanderbilt PRB 56, 12847 (1997) [[cite:Marzari1997]].
343 : :
344 : 1160 : d3_berry(:,:) = 0._dp
345 : :
346 [ + + + + : 4640 : if ((i2pert==dtset%natom+2).and.&
+ - ]
347 : : & (maxval(rfpert(i1dir,i1pert,:,i2pert,i3dir,i3pert)) == 1)) then
348 : :
349 : 145 : call timab(511,1,tsec)
350 : : call pead_nl_mv(cg,cgindex,cg1,cg3,dtset,dtfil,d3_berry,gmet,&
351 : : & i1pert,i3pert,i1dir,i3dir,&
352 : : & kneigh,kg_neigh,kptindex,kpt3,mband,mkmem,mkmem_max,mk1mem,&
353 : 145 : & mpi_enreg,mpw,mvwtk,natom,nkpt,nkpt3,nneigh,npwarr,nspinor,nsppol,pwind)
354 : 145 : call timab(511,2,tsec)
355 : :
356 : : end if
357 : :
358 [ + + ]: 1160 : if (mpi_enreg%me == 0) then
359 : :
360 [ + + + + ]: 3744 : if(sum(rfpert(i1dir,i1pert,:,i2pert,i3dir,i3pert))>0)then
361 : 120 : write(message,'(a,a,a,a,a,a)')ch10,ch10,&
362 : 240 : & ' Decomposition of the third-order energy for the set of perturbations',ch10
363 : 120 : call wrtout(std_out,message,'COLL')
364 : 120 : call wrtout(ab_out,message,'COLL')
365 [ + + ]: 120 : if (i1pert < natom + 1) then
366 : : write(message,'(a,i3,a,i3)') &
367 : 56 : & ' j1 : displacement of atom ',i1pert,' along direction ', i1dir
368 : : end if
369 [ + + ]: 120 : if (i1pert == dtset%natom + 2) then
370 : 64 : write(message,'(a,i4)')' j1 : homogeneous electric field along direction ',i1dir
371 : : end if
372 : 120 : call wrtout(std_out,message,'COLL')
373 : 120 : call wrtout(ab_out,message,'COLL')
374 [ - + ]: 120 : if (i3pert < natom + 1) then
375 : : write(message,'(a,i3,a,i3,a)') &
376 : 0 : & ' j3 : displacement of atom ',i3pert,' along direction ', i3dir,ch10
377 : : end if
378 [ + - ]: 120 : if (i3pert == dtset%natom + 2) then
379 : 120 : write(message,'(a,i4,a)')' j3 : homogeneous electric field along direction ',i3dir,ch10
380 : : end if
381 : 120 : call wrtout(std_out,message,'COLL')
382 : 120 : call wrtout(ab_out,message,'COLL')
383 : : end if
384 : :
385 : : end if ! mpi_enreg%me == 0
386 : :
387 [ + + ]: 4785 : do i2dir = 1, 3
388 : :
389 [ + + ]: 4640 : if (rfpert(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)==1) then
390 : 407 : pert2case = i2dir + (i2pert-1)*3
391 : :
392 : 407 : blkflg(i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = 1
393 : :
394 : : ! Read the first-order densities from disk-files
395 [ + + + + : 10999383 : rho2r1(:,:) = 0._dp ; rho2g1(:,:) = 0._dp
+ + + + ]
396 : :
397 [ - + - - ]: 407 : if (dtset%get1den /= 0 .or. dtset%ird1den /= 0) then
398 : 407 : rdwrpaw=0
399 : 407 : call appdig(pert2case,dtfil%fildens1in,fiden1i)
400 : :
401 : : call read_rhor(fiden1i, cplex, dtset%nspden, nfft, dtset%ngfft, rdwrpaw, mpi_enreg, rho2r1, &
402 : 407 : hdr_den, rhoij_dum, comm_cell, check_hdr=hdr)
403 : 407 : call hdr_den%free()
404 : :
405 : : ! Compute up+down rho1(G) by fft
406 [ - + + - : 814 : ABI_MALLOC(work,(cplex*nfft))
- + + - ]
407 [ + + ]: 2566031 : work(:)=rho2r1(:,1)
408 : 407 : call fourdp(cplex,rho2g1,work,-1,mpi_enreg,nfft,1,dtset%ngfft,0)
409 [ - + ]: 407 : ABI_FREE(work)
410 : :
411 : : end if
412 : :
413 : : ! Compute first-order local potentials
414 : : ! (hartree, xc and pseudopotential)
415 : :
416 [ + + ]: 407 : n3xccc=0; if(psps%n1xccc/=0)n3xccc=nfft
417 [ + + + + ]: 5132062 : xccc3d2(:)=0._dp ; vpsp1(:)=0._dp
418 : :
419 [ + + ]: 407 : if (i2pert <= natom) then
420 : :
421 : : call dfpt_vlocal(atindx,cplex,gmet,gsqcut,dtset%icutcoul,i2dir,i2pert,mpi_enreg,psps%mqgrid_vl,natom,&
422 : : & nattyp,nfft,dtset%ngfft,nkpt,psps%ntypat,n1,n2,n3,ph1d,psps%qgrid_vl,&
423 : 126 : & dtset%qptn,dtset%rcut,rprimd,ucvol,dtset%vcutgeo,psps%vlspl,vpsp1,xred)
424 : :
425 [ + + ]: 126 : if (psps%n1xccc/=0) then
426 : : call dfpt_mkcore(cplex,i2dir,i2pert,natom,psps%ntypat,n1,psps%n1xccc,&
427 : : & n2,n3,dtset%qptn,rprimd,dtset%typat,ucvol,&
428 : 90 : & psps%xcccrc,psps%xccc1d,xccc3d2,xred)
429 : : end if ! psps%n1xccc/=0
430 : :
431 : : end if ! i2pert <= natom
432 : :
433 : : call hartre(cplex,gsqcut,3,0,mpi_enreg,nfft,dtset%ngfft,dtset%nkpt,&
434 : 407 : &dtset%rcut,rho2g1,rprimd,dtset%vcutgeo,vhartr1)
435 [ - + - - ]: 407 : option=1 ; nmxc=(dtset%usepaw==1.and.mod(abs(dtset%usepawu),10)==4)
436 : : call dfpt_mkvxc(cplex,dtset%ixc,kxc,mpi_enreg,nfft,dtset%ngfft,&
437 : : & rho_dum,0,rho_dum,0,nkxc,nmxc,dtset%nspden,n3xccc,option,&
438 : 407 : & dtset%qptn,rho2r1,rprimd,0,vxc1,xccc3d2)
439 : :
440 [ + + ]: 407 : if(dtset%nsppol==1)then
441 : : if(cplex==1)then
442 [ + + ]: 1830365 : do ir=1,nfft
443 : 1830365 : vtrial1(ir,1)=vpsp1(ir)+vhartr1(ir)+vxc1(ir,1)
444 : : end do
445 : : else
446 : : do ir=1,nfft
447 : : vtrial1(2*ir-1,1)=vpsp1(2*ir-1)+vhartr1(2*ir-1)+vxc1(2*ir-1,1)
448 : : vtrial1(2*ir ,1)=vpsp1(2*ir )+vhartr1(2*ir )+vxc1(2*ir ,1)
449 : : end do
450 : : end if
451 : : else
452 : : if(cplex==1)then
453 [ + + ]: 735666 : do ir=1,nfft
454 : 735552 : vtrial1(ir,1)=vpsp1(ir)+vhartr1(ir)+vxc1(ir,1)
455 : 735666 : vtrial1(ir,2)=vpsp1(ir)+vhartr1(ir)+vxc1(ir,2)
456 : : end do
457 : : else
458 : : ! fab: I think there was an error in the definition of vtrial1(2*ir-1,2); I have corrected it...
459 : : do ir=1,nfft
460 : : vtrial1(2*ir-1,1)=vpsp1(2*ir-1)+vhartr1(2*ir-1)+vxc1(2*ir-1,1)
461 : : vtrial1(2*ir ,1)=vpsp1(2*ir )+vhartr1(2*ir )+vxc1(2*ir ,1)
462 : : vtrial1(2*ir-1,2)=vpsp1(2*ir-1)+vhartr1(2*ir-1)+vxc1(2*ir-1 ,2)
463 : : vtrial1(2*ir ,2)=vpsp1(2*ir )+vhartr1(2*ir )+vxc1(2*ir ,2)
464 : : end do
465 : : end if
466 : : end if
467 : :
468 : : ! Compute the third-order xc energy
469 : : call dfptnl_exc3(cplex,exc3,k3xc,mpi_enreg,nk3xc,nfft,nfftot,dtset%nspden,&
470 : 407 : & rho1r1,rho2r1,rho3r1,ucvol,xccc3d1,xccc3d2,xccc3d3)
471 : :
472 : : ! Perform DFPT part of the 3dte calculation
473 : :
474 : 407 : call timab(512,1,tsec)
475 : : call pead_nl_resp(cg,cg1,cg3,cplex,dtfil,dtset,d3lo,i1dir,i2dir,i3dir,i1pert,i2pert,i3pert,&
476 : : & kg,mband,mgfft,mkmem,mk1mem,mpert,mpi_enreg,mpsang,mpw,natom,nfft,nkpt,nspden,&
477 : 407 : & nspinor,nsppol,npwarr,occ,ph1d,psps,rprimd,vtrial1,xred,ylm)
478 : 407 : call timab(512,2,tsec)
479 : :
480 : :
481 : : ! Describe the perturbation and write out the result
482 [ + + ]: 407 : if (mpi_enreg%me == 0) then
483 [ + + ]: 347 : if (i2pert < natom + 1) then
484 : : write(message,'(a,i3,a,i3)') &
485 : 110 : & ' j2 : displacement of atom ',i2pert,&
486 : 220 : & ' along direction ', i2dir
487 : : end if
488 [ + + ]: 347 : if (i2pert == dtset%natom + 2) then
489 : : write(message,'(a,i4)') &
490 : 237 : & ' j2 : homogeneous electric field along direction ',&
491 : 474 : & i2dir
492 : : end if
493 : 347 : call wrtout(std_out,message,'COLL')
494 : 347 : call wrtout(ab_out,message,'COLL')
495 : 347 : write(ab_out,'(20x,a,13x,a)')'real part','imaginary part'
496 : 347 : write(ab_out,'(5x,a2,1x,f22.10,3x,f22.10)')'xc',exc3(1)*sixth,zero
497 [ + + ]: 347 : if (i2pert == natom + 2) then
498 : 237 : write(ab_out,'(5x,a3,f22.10,3x,f22.10)')'ddk',&
499 : 474 : & d3_berry(1,i2dir),d3_berry(2,i2dir)
500 : : end if
501 : 347 : write(ab_out,'(5x,a3,f22.10,3x,f22.10)')'dft',&
502 : 347 : & d3lo(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert),&
503 : 694 : & d3lo(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
504 : 347 : write(ab_out,*)
505 : 347 : write(std_out,'(18x,a,11x,a)')'real part','imaginary part'
506 : 347 : write(std_out,'(5x,a2,1x,f20.10,3x,f20.10)')'xc',exc3(1)*sixth,zero
507 : 347 : write(std_out,'(5x,a3,f22.10,3x,f22.10)')'ddk',&
508 : 694 : & d3_berry(1,i2dir),d3_berry(2,i2dir)
509 : 347 : write(std_out,'(5x,a3,f22.10,3x,f22.10)')'dft',&
510 : 347 : & d3lo(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert),&
511 : 694 : & d3lo(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert)
512 : 347 : write(std_out,*)
513 : : end if ! mpi_enreg%me == 0
514 : :
515 : : d3lo(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = &
516 : 407 : & d3lo(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) + exc3(1)*sixth
517 : : d3lo(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = &
518 [ + + ]: 1221 : & d3lo(:,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) + d3_berry(:,i2dir)
519 : :
520 : : end if !rfpert
521 : : end do !i2dir
522 : : end do ! i2pert
523 : :
524 : : end if ! rfpert
525 : : end do ! i3dir
526 : : end do ! i3pert
527 : :
528 : : end if ! rfpert
529 : : end do ! i1dir
530 : : end do ! i1pert
531 : :
532 : :
533 [ - + ]: 21 : ABI_FREE(cg1)
534 [ - + ]: 21 : ABI_FREE(cg3)
535 [ - + ]: 21 : ABI_FREE(eigen1)
536 [ - + ]: 21 : ABI_FREE(rho1r1)
537 [ - + ]: 21 : ABI_FREE(rho2r1)
538 [ - + ]: 21 : ABI_FREE(rho2g1)
539 [ - + ]: 21 : ABI_FREE(rho3r1)
540 [ - + ]: 21 : ABI_FREE(atindx1)
541 [ - + ]: 21 : ABI_FREE(atindx)
542 [ - + ]: 21 : ABI_FREE(nattyp)
543 [ - + ]: 21 : ABI_FREE(ph1d)
544 [ - + ]: 21 : ABI_FREE(ylm)
545 [ - + ]: 21 : ABI_FREE(vtrial1)
546 [ - + ]: 21 : ABI_FREE(vxc1)
547 [ - + ]: 21 : ABI_FREE(vhartr1)
548 [ - + ]: 21 : ABI_FREE(vpsp1)
549 [ - + ]: 21 : ABI_FREE(xccc3d1)
550 [ - + ]: 21 : ABI_FREE(xccc3d2)
551 [ - + ]: 21 : ABI_FREE(xccc3d3)
552 : :
553 : 21 : call timab(502,2,tsec)
554 : :
555 [ - + - + : 21 : end subroutine pead_nl_loop
- - - - -
- - - - -
- - - - -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - - - -
- - - - -
- - - -
- ]
556 : : !!***
557 : :
558 : : !!****f* ABINIT/pead_nl_resp
559 : : !! NAME
560 : : !! pead_nl_resp
561 : : !!
562 : : !! FUNCTION
563 : : !! Compute the linear response part to the 3dte
564 : : !!
565 : : !! INPUTS
566 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol) = array for planewave
567 : : !! coefficients of wavefunctions
568 : : !! cg1 = first-order wavefunction relative to the perturbations i1pert
569 : : !! cg3 = first-order wavefunction relative to the perturbations i3pert
570 : : !! cplex= if 1, real space 1-order functions on FFT grid are REAL,
571 : : !! if 2, COMPLEX
572 : : !! dtfil <type(datafiles_type)>=variables related to files
573 : : !! dtset <type(dataset_type)>=all input variables for this dataset
574 : : !! i1dir,i2dir,i3dir=directions of the corresponding perturbations
575 : : !! i1pert,i2pert,i3pert = type of perturbation that has to be computed
576 : : !! kg(3,mpw*mkmem)=reduced planewave coordinates
577 : : !! mband = maximum number of bands
578 : : !! mgfft=maximum size of 1D FFTs
579 : : !! mkmem = maximum number of k points which can fit in core memory
580 : : !! mk1mem = maximum number of k points for first-order WF
581 : : !! which can fit in core memory
582 : : !! mpert =maximum number of ipert
583 : : !! mpi_enreg=MPI-parallelisation information
584 : : !! mpsang= 1+maximum angular momentum for nonlocal pseudopotentials
585 : : !! mpw = maximum number of planewaves in basis sphere (large number)
586 : : !! natom = number of atoms in unit cell
587 : : !! nfft = (effective) number of FFT grid points (for this processor)
588 : : !! nkpt = number of k points
589 : : !! nspden = number of spin-density components
590 : : !! nspinor = number of spinorial components of the wavefunctions
591 : : !! nsppol = number of channels for spin-polarization (1 or 2)
592 : : !! npwarr(nkpt) = array holding npw for each k point
593 : : !! occ(mband*nkpt*nsppol) = occupation number for each band and k
594 : : !! ph1d(2,3*(2*mgfft+1)*natom)=one-dimensional structure factor information
595 : : !! psps <type(pseudopotential_type)> = variables related to pseudopotentials
596 : : !! rprimd(3,3) = dimensional primitive translations (bohr)
597 : : !! vtrial1(cplex*nfft,nspden)=firs-order local potential
598 : : !! xred(3,natom) = reduced atomic coordinates
599 : : !! ylm(mpw*mkmem,mpsang*mpsang*useylm)= spherical harmonics for
600 : : !! each G and k point
601 : : !!
602 : : !! OUTPUT
603 : : !! d3lo(2,3,mpert,3,mpert,3,mpert) = matrix of the 3DTEs
604 : : !!
605 : : !! SOURCE
606 : :
607 : 407 : subroutine pead_nl_resp(cg,cg1,cg3,cplex,dtfil,dtset,d3lo,&
608 : : & i1dir,i2dir,i3dir,i1pert,i2pert,i3pert,&
609 : 407 : & kg,mband,mgfft,mkmem,mk1mem,&
610 : : & mpert,mpi_enreg,mpsang,mpw,natom,nfft,nkpt,nspden,nspinor,nsppol,&
611 : 407 : & npwarr,occ,ph1d,psps,rprimd,vtrial1,xred,ylm)
612 : :
613 : : !Arguments ------------------------------------
614 : : !scalars
615 : : integer,intent(in) :: cplex,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert,mband,mgfft
616 : : integer,intent(in) :: mk1mem,mkmem,mpert,mpsang,mpw,natom,nfft,nkpt,nspden
617 : : integer,intent(in) :: nspinor,nsppol
618 : : type(MPI_type),intent(in) :: mpi_enreg
619 : : type(datafiles_type),intent(in) :: dtfil
620 : : type(dataset_type),intent(in) :: dtset
621 : : type(pseudopotential_type),intent(in) :: psps
622 : : !arrays
623 : : integer,intent(in) :: kg(3,mpw*mkmem),npwarr(nkpt)
624 : : real(dp),intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol)
625 : : real(dp),intent(in) :: cg1(2,mpw*nspinor*mband*mk1mem*nsppol)
626 : : real(dp),intent(in) :: cg3(2,mpw*nspinor*mband*mk1mem*nsppol)
627 : : real(dp),intent(in) :: occ(mband*nkpt*nsppol),ph1d(2,3*(2*mgfft+1)*natom),rprimd(3,3)
628 : : real(dp),intent(in) :: xred(3,natom),ylm(mpw*mkmem,mpsang*mpsang*psps%useylm)
629 : : real(dp),intent(inout) :: vtrial1(cplex*nfft,nspden)
630 : : real(dp),intent(inout) :: d3lo(2,3,mpert,3,mpert,3,mpert)
631 : :
632 : : !Local variables-------------------------------
633 : : !scalars
634 : : integer,parameter :: level=52
635 : : integer :: bantot,choice,counter,cpopt,dimffnl,iband,icg0,ider,ierr
636 : : integer :: ii,ikg,ikpt,ilm,ipw,isppol,istwf_k,jband,jj
637 : : integer :: me,n1,n2,n3,n4,n5,n6,nband_k,nkpg,nnlout,npw_k
638 : : integer :: option,paw_opt,signs,spaceComm,tim_fourwf,tim_nonlop
639 : : real(dp) :: dot1i,dot1r,dot2i,dot2r,doti,dotr,lagi,lagr,sumi,sumr,weight
640 : 407 : type(gs_hamiltonian_type) :: gs_hamk
641 : : !arrays
642 : 407 : integer,allocatable :: kg_k(:,:)
643 : : real(dp) :: buffer(2),enlout(3),kpq(3),kpt(3)
644 : : real(dp) :: dum_svectout(1,1),dum(1),rmet(3,3),ylmgr_dum(1,1,1)
645 : 407 : real(dp),allocatable :: cwave0(:,:),cwavef3(:,:),ffnlk(:,:,:,:)
646 : 407 : real(dp),allocatable :: gh0(:,:),gh1(:,:),gvnl(:,:),kpg_k(:,:)
647 : 407 : real(dp),allocatable :: vlocal1(:,:,:),wfraug(:,:,:,:),ylm_k(:,:)
648 [ + + + + : 2849 : type(pawcprj_type) :: cprj_dum(1,1)
+ + + - +
- ]
649 : 407 : type(pawtab_type) :: pawtab_dum(0)
650 : :
651 : : !***********************************************************************
652 : :
653 : : ABI_UNUSED(dtfil%ireadwf)
654 : :
655 : 407 : me = mpi_enreg%me
656 : 407 : spaceComm=mpi_enreg%comm_cell
657 : :
658 : 407 : bantot = 0
659 : 407 : icg0 = 0
660 : 407 : option = 2
661 : 407 : n1=dtset%ngfft(1) ; n2=dtset%ngfft(2) ; n3=dtset%ngfft(3)
662 : 407 : n4=dtset%ngfft(4) ; n5=dtset%ngfft(5) ; n6=dtset%ngfft(6)
663 : :
664 [ - + + - : 2035 : ABI_MALLOC(vlocal1,(cplex*n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
665 [ - + + - : 2035 : ABI_MALLOC(wfraug,(2,n4,n5,n6))
- + + - -
+ + - + -
+ - - + -
+ ]
666 : :
667 : : !Initialize Hamiltonian (k-independent terms) - NCPP only
668 : : call gs_hamk%init(psps,pawtab_dum,nspinor,nsppol,nspden,natom,&
669 : : & dtset%typat,xred,nfft,mgfft,dtset%ngfft,rprimd,dtset%nloalg,ph1d=ph1d,&
670 : 407 : & comm_atom=mpi_enreg%comm_atom,mpi_atmtab=mpi_enreg%my_atmtab,mpi_spintab=mpi_enreg%my_isppoltab)
671 : : !& paw_ij=paw_ij)
672 [ + + + + : 16280 : rmet = MATMUL(TRANSPOSE(rprimd),rprimd)
+ + ]
673 : :
674 : 407 : sumr = zero ; sumi = zero
675 : :
676 : : !Loop over spins
677 : :
678 [ + + ]: 928 : do isppol = 1, nsppol
679 : :
680 : 521 : call fftpac(isppol,mpi_enreg,nspden,cplex*n1,n2,n3,cplex*n4,n5,n6,dtset%ngfft,vtrial1,vlocal1,option)
681 : :
682 : : ! Loop over k-points
683 : :
684 : 521 : ikg = 0
685 [ + + ]: 11130 : do ikpt = 1, nkpt
686 : :
687 [ + + ]: 10202 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,-1,mpi_enreg%me))cycle
688 : :
689 : 9242 : counter = 100*ikpt
690 : :
691 : 9242 : nband_k = dtset%nband(ikpt+(isppol-1)*nkpt)
692 : 9242 : npw_k = npwarr(ikpt)
693 : 9242 : istwf_k = dtset%istwfk(ikpt)
694 : :
695 [ + + ]: 36968 : kpt(:) = dtset%kptns(:,ikpt)
696 : : kpq(:) = dtset%kptns(:,ikpt) ! In case of non zero q, kpt = kpt + q
697 : :
698 [ - + + - : 27726 : ABI_MALLOC(cwave0,(2,npw_k*dtset%nspinor))
+ - + - -
+ - + -
+ ]
699 [ - + + - : 18484 : ABI_MALLOC(cwavef3,(2,npw_k*dtset%nspinor))
- + - + -
+ ]
700 [ - + + - : 18484 : ABI_MALLOC(gh0,(2,npw_k*dtset%nspinor))
- + - + ]
701 [ - + + - : 18484 : ABI_MALLOC(gvnl,(2,npw_k*dtset%nspinor))
- + - + -
+ ]
702 [ - + + - : 18484 : ABI_MALLOC(gh1,(2,npw_k*dtset%nspinor))
- + - + ]
703 : :
704 [ - + + - : 27726 : ABI_MALLOC(kg_k,(3,npw_k))
+ - + - -
+ - + -
+ ]
705 [ - + + - : 36968 : ABI_MALLOC(ylm_k,(npw_k,mpsang*mpsang*psps%useylm))
+ - - - +
- - + - +
- + - + ]
706 [ + + + + ]: 3846766 : kg_k(:,1:npw_k) = kg(:,1+ikg:npw_k+ikg)
707 [ - + ]: 9242 : if (psps%useylm==1) then
708 [ # # ]: 0 : do ilm=1,mpsang*mpsang
709 [ # # ]: 0 : ylm_k(1:npw_k,ilm)=ylm(1+ikg:npw_k+ikg,ilm)
710 : : end do
711 : : end if
712 : :
713 : : ! Compute (k+G) and (k+q+G) vectors (only if useylm=1)
714 [ + + ]: 9242 : nkpg=0;if (i2pert<natom+1) nkpg=3*dtset%nloalg(3)
715 [ - + + - : 36968 : ABI_MALLOC(kpg_k,(npw_k,nkpg))
+ - - - +
- - + - +
- + - + ]
716 [ - + ]: 9242 : if (nkpg>0) then
717 : 0 : call mkkpg(kg_k,kpg_k,kpt,nkpg,npw_k)
718 : : end if
719 : :
720 : : ! Compute nonlocal form factors ffnl at (k+G), for all atoms
721 : 9242 : dimffnl=1
722 [ - + + - : 46210 : ABI_MALLOC(ffnlk,(npw_k,dimffnl,psps%lmnmax,psps%ntypat))
- + + - -
+ + - + -
+ - - + -
+ - + ]
723 [ + + ]: 9242 : if (i2pert<natom+1) then
724 : 2569 : ider=0
725 : : call mkffnl(psps%dimekb,dimffnl,psps%ekb,ffnlk,psps%ffspl,gs_hamk%gmet,gs_hamk%gprimd,&
726 : : & ider,ider,psps%indlmn,kg_k,kpg_k,kpt,psps%lmnmax,psps%lnmax,psps%mpsang,&
727 : : & psps%mqgrid_ff,nkpg,npw_k,psps%ntypat,psps%pspso,psps%qgrid_ff,rmet,&
728 : 2569 : & psps%usepaw,psps%useylm,ylm_k,ylmgr_dum)
729 : : end if
730 : :
731 : : ! Load k-dependent part in the Hamiltonian datastructure
732 : : call gs_hamk%load_k(kpt_k=kpt,npw_k=npw_k,istwf_k=istwf_k,&
733 : 9242 : & kg_k=kg_k,kpg_k=kpg_k,ffnl_k=ffnlk,compute_gbound=.true.)
734 : : ! Load k+q-dependent part in the Hamiltonian datastructure
735 : : ! call load_kprime_hamiltonian... !! To be activated when q/=0
736 : :
737 : : ! Loop over bands
738 : :
739 [ + + ]: 45970 : do iband = 1,nband_k
740 : :
741 : : cwave0(:,:)=cg(:,1+(iband - 1)*npw_k*dtset%nspinor+icg0:&
742 [ + + + + ]: 11068340 : & iband*npw_k*dtset%nspinor+icg0)
743 : : cwavef3(:,:)=cg3(:,1+(iband-1)*npw_k*dtset%nspinor+icg0:&
744 [ + + + + ]: 11068340 : & iband*npw_k*dtset%nspinor+icg0)
745 : :
746 : : ! Compute vtrial1 | cwafef3 >
747 : 36728 : tim_fourwf = 0 ; weight = one
748 : : call fourwf(cplex,vlocal1,cwavef3,gh1,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
749 : : & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,1,dtset%ngfft,npw_k,npw_k,n4,n5,n6,option,&
750 : : & tim_fourwf,weight,weight,&
751 : 36728 : & gpu_option=dtset%gpu_option)
752 : :
753 : : ! In case i2pert = phonon-type perturbation
754 : : ! add first-order change in the nonlocal potential
755 [ + + ]: 36728 : if (i2pert<natom+1) then
756 : 10196 : signs=2 ; choice=2 ; nnlout=3 ; tim_nonlop = 0 ; paw_opt=0 ; cpopt=-1
757 : : call nonlop(choice,cpopt,cprj_dum,enlout,gs_hamk,i2dir,dum,mpi_enreg,1,nnlout,paw_opt,&
758 : 10196 : & signs,dum_svectout,tim_nonlop,cwavef3,gvnl,iatom_only=i2pert)
759 [ + + + + ]: 3364556 : gh1(:,:) = gh1(:,:) + gvnl(:,:)
760 : : end if
761 : :
762 : 36728 : ii = (iband-1)*npw_k*dtset%nspinor + icg0
763 : 36728 : call dotprod_g(dotr,doti,istwf_k,npw_k,2,cg1(:,ii+1:ii+npw_k),gh1,mpi_enreg%me_g0,xmpi_comm_self)
764 : :
765 : : ! Compute vtrial1 | cwave0 >
766 : : tim_fourwf = 0 ; weight = one
767 : : call fourwf(cplex,vlocal1,cwave0,gh0,wfraug,gs_hamk%gbound_k,gs_hamk%gbound_k,&
768 : : & istwf_k,kg_k,kg_k,mgfft,mpi_enreg,1,dtset%ngfft,npw_k,npw_k,n4,n5,n6,option,&
769 : 36728 : & tim_fourwf,weight,weight,gpu_option=dtset%gpu_option)
770 : :
771 : : ! In case i2pert = phonon-type perturbation
772 : : ! add first-order change in the nonlocal potential
773 [ + + ]: 36728 : if (i2pert<natom+1) then
774 : 10196 : signs=2 ; choice=2 ; nnlout=3 ; tim_nonlop = 0 ; paw_opt=0 ; cpopt=-1
775 : : call nonlop(choice,cpopt,cprj_dum,enlout,gs_hamk,i2dir,dum,mpi_enreg,1,nnlout,paw_opt,&
776 : 10196 : & signs,dum_svectout,tim_nonlop,cwave0,gvnl,iatom_only=i2pert)
777 [ + + + + ]: 3364556 : gh0(:,:) = gh0(:,:) + gvnl(:,:)
778 : : end if
779 : :
780 : : ! Compute the dft contribution to the Lagrange multiplier
781 : : ! cwavef3 and cwave0 have been transferred to gh1 and gh0
782 : : ! these vectors will be used to store the wavefunctions of band iband
783 : : ! cg1 and gh0 contain the wavefunctions of band jband
784 : :
785 : 36728 : lagr = zero ; lagi = zero
786 [ + + ]: 183250 : do jband = 1, nband_k
787 : :
788 : 146522 : ii = (jband - 1)*npw_k*dtset%nspinor + icg0
789 : 146522 : jj = (iband - 1)*npw_k*dtset%nspinor + icg0
790 : :
791 : : ! dot1r and dot1i contain < u_mk | v^(1) | u_nk >
792 : : ! dot2r and dot2i contain < u_nk^(1) | u_mk^(1) >
793 : : ! m -> jband and n -> iband
794 : :
795 : 146522 : dot1r = zero ; dot1i = zero
796 : 146522 : dot2r = zero ; dot2i = zero
797 [ + + ]: 14594818 : do ipw = 1, npw_k
798 : 14448296 : ii = ii + 1 ; jj = jj + 1
799 : 14448296 : dot1r = dot1r + cg(1,ii)*gh0(1,ipw) + cg(2,ii)*gh0(2,ipw)
800 : 14448296 : dot1i = dot1i + cg(1,ii)*gh0(2,ipw) - cg(2,ii)*gh0(1,ipw)
801 : : dot2r = dot2r + cg1(1,jj)*cg3(1,ii) + &
802 : 14448296 : & cg1(2,jj)*cg3(2,ii)
803 : : dot2i = dot2i + cg1(1,jj)*cg3(2,ii) - &
804 : 14594818 : & cg1(2,jj)*cg3(1,ii)
805 : : end do ! ipw
806 : :
807 : 146522 : lagr = lagr + dot1r*dot2r - dot1i*dot2i
808 : 183250 : lagi = lagi + dot1r*dot2i + dot1i*dot2r
809 : :
810 : : end do ! jband
811 : :
812 : : sumr = sumr + &
813 : 36728 : & dtset%wtk(ikpt)*occ(bantot+iband)*(dotr-lagr)
814 : : sumi = sumi + &
815 : 45970 : & dtset%wtk(ikpt)*occ(bantot+iband)*(doti-lagi)
816 : :
817 : : end do ! end loop over bands
818 : :
819 : 9242 : bantot = bantot + nband_k
820 : 9242 : icg0 = icg0 + npw_k*dtset%nspinor*nband_k
821 : 9242 : ikg = ikg + npw_k
822 : :
823 [ - + ]: 9242 : ABI_FREE(cwave0)
824 [ - + ]: 9242 : ABI_FREE(cwavef3)
825 [ - + ]: 9242 : ABI_FREE(gh0)
826 [ - + ]: 9242 : ABI_FREE(gh1)
827 [ - + ]: 9242 : ABI_FREE(gvnl)
828 [ - + ]: 9242 : ABI_FREE(kg_k)
829 [ - + ]: 9242 : ABI_FREE(ylm_k)
830 [ - + ]: 9242 : ABI_FREE(ffnlk)
831 [ - + ]: 10723 : ABI_FREE(kpg_k)
832 : :
833 : : end do ! end loop over k-points
834 : :
835 : : end do ! end loop over spins
836 : :
837 : : if (xmpi_paral == 1) then
838 : 407 : buffer(1) = sumr ; buffer(2) = sumi
839 : 407 : call xmpi_sum(buffer,spaceComm,ierr)
840 : 407 : sumr = buffer(1) ; sumi = buffer(2)
841 : : end if
842 : :
843 : :
844 : 407 : d3lo(1,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = sumr
845 : : !d3lo(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = sumi
846 : :
847 : : !In some cases, the imaginary part is /= 0 because of the
848 : : !use of time reversal symmetry
849 : 407 : d3lo(2,i1dir,i1pert,i2dir,i2pert,i3dir,i3pert) = zero
850 : :
851 : 407 : call gs_hamk%free()
852 : :
853 [ - + ]: 407 : ABI_FREE(vlocal1)
854 [ - + ]: 407 : ABI_FREE(wfraug)
855 : :
856 [ - + - + : 407 : end subroutine pead_nl_resp
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + - +
- + - + -
+ - + ]
857 : : !!***
858 : :
859 : : !!****f* ABINIT/pead_nl_mv
860 : : !! NAME
861 : : !! pead_nl_mv
862 : : !!
863 : : !! FUNCTION
864 : : !! Compute the finite difference expression of the k-point derivative
865 : : !! using the PEAD formulation of the third-order energy
866 : : !! (see Nunes and Gonze PRB 63, 155107 (2001) [[cite:Nunes2001]] Eq. 102)
867 : : !! and the finite difference formula of Marzari and Vanderbilt
868 : : !! (see Marzari and Vanderbilt, PRB 56, 12847 (1997) [[cite:Marzari1997]], Appendix B)
869 : : !!
870 : : !! INPUTS
871 : : !! cg(2,mpw*nspinor*mband*mkmem*nsppol) = array for planewave coefficients of wavefunctions
872 : : !! cgindex(nkpt2,nsppol) = for each k-point, cgindex stores the location of the WF in the cg array
873 : : !! cg1 = first-order wavefunction relative to the perturbations i1pert
874 : : !! cg3 = first-order wavefunction relative to the perturbations i3pert
875 : : !! dtfil <type(datafiles_type)>=variables related to files
876 : : !! dtset <type(dataset_type)>=all input variables for this dataset
877 : : !! gmet(3,3)=reciprocal space metric tensor in bohr**-2
878 : : !! i1pert,i3pert = type of perturbation that has to be computed
879 : : !! i1dir,i3dir=directions of the corresponding perturbations
880 : : !! kneigh(30,nkpt2) = index of the neighbours of each k-point
881 : : !! kg_neigh(30,nkpt2,3) = necessary to construct the vector joining a k-point
882 : : !! to its nearest neighbour in case of a single k-point,
883 : : !! a line of k-points or a plane of k-points.
884 : : !! See getshell.F90 for details
885 : : !! kptindex(2,nkpt3)= index of the k-points in the reduced BZ
886 : : !! related to a k-point in the full BZ
887 : : !! kpt3(3,nkpt3) = reduced coordinates of k-points in the full BZ
888 : : !! mband = maximum number of bands
889 : : !! mkmem = maximum number of k points which can fit in core memory
890 : : !! mkmem_max = maximal number of k-points on each processor (MPI //)
891 : : !! mk1mem = maximum number of k points for first-order WF which can fit in core memory
892 : : !! mpi_enreg=MPI-parallelisation information
893 : : !! mpw = maximum number of planewaves in basis sphere (large number)
894 : : !! mvwtk(30,nkpt) = weights to compute the finite difference ddk
895 : : !! natom = number of atoms in unit cell
896 : : !! nkpt2 = number of k-points in the reduced part of the BZ
897 : : !! nkpt2 = nkpt/2 in case of time-reversal symmetry (kptopt = 2)
898 : : !! nkpt3 = number of k-points in the full BZ
899 : : !! nneigh = total number of neighbours required to evaluate the finite difference formula
900 : : !! npwarr(nkpt) = array holding npw for each k point
901 : : !! nspinor = number of spinorial components of the wavefunctions
902 : : !! nsppol = number of channels for spin-polarization (1 or 2)
903 : : !! pwind(mpw,nneigh,mkmem) = array used to compute the overlap matrix smat between k-points
904 : : !!
905 : : !! OUTPUT
906 : : !! d3_berry(2,3) = Berry-phase part of the third-order energy
907 : : !!
908 : : !! SIDE EFFECTS
909 : : !! mpi_enreg=MPI-parallelisation information
910 : : !!
911 : : !! NOTES
912 : : !! For a given set of values of i1pert,i3pert,i1dir and
913 : : !! i3dir, the routine computes the k-point derivatives for
914 : : !! 12dir = 1,2,3
915 : : !!
916 : : !! SOURCE
917 : :
918 : 145 : subroutine pead_nl_mv(cg,cgindex,cg1,cg3,dtset,dtfil,d3_berry,gmet,&
919 : 145 : & i1pert,i3pert,i1dir,i3dir,kneigh,kg_neigh,kptindex,&
920 : 145 : & kpt3,mband,mkmem,mkmem_max,mk1mem,mpi_enreg,&
921 : 145 : & mpw,mvwtk,natom,nkpt2,nkpt3,nneigh,npwarr,nspinor,&
922 : 145 : & nsppol,pwind)
923 : :
924 : : use m_hide_lapack, only : dzgedi, dzgefa
925 : :
926 : : !Arguments ------------------------------------
927 : : !
928 : : !--- Arguments : integer scalars
929 : : integer, intent(in) :: i1dir,i1pert,i3dir,i3pert,mband,mk1mem
930 : : integer, intent(in) :: mkmem,mkmem_max,mpw,natom
931 : : integer, intent(in) :: nkpt2,nkpt3,nneigh,nspinor,nsppol
932 : : !
933 : : !--- Arguments : integer arrays
934 : : integer, intent(in) :: cgindex(nkpt2,nsppol)
935 : : integer, intent(in) :: kneigh(30,nkpt2),kg_neigh(30,nkpt2,3),kptindex(2,nkpt3)
936 : : integer, intent(in) :: npwarr(nkpt2),pwind(mpw,nneigh,mkmem)
937 : : !
938 : : !--- Arguments : real(dp) scalars
939 : : !
940 : : !--- Arguments : real(dp) arrays
941 : : real(dp), intent(in) :: cg(2,mpw*nspinor*mband*mkmem*nsppol)
942 : : real(dp), intent(in) :: cg1(2,mpw*nspinor*mband*mk1mem*nsppol)
943 : : real(dp), intent(in) :: cg3(2,mpw*nspinor*mband*mk1mem*nsppol)
944 : : real(dp), intent(in) :: gmet(3,3),kpt3(3,nkpt3)
945 : : real(dp), intent(in) :: mvwtk(30,nkpt2)
946 : : real(dp), intent(out) :: d3_berry(2,3)
947 : : !
948 : : !--- Arguments : structured datatypes
949 : : type(MPI_type), intent(in) :: mpi_enreg
950 : : type(datafiles_type), intent(in) :: dtfil
951 : : type(dataset_type), intent(in) :: dtset
952 : :
953 : : !Local variables-------------------------------
954 : : !
955 : : !---- Local variables : integer scalars
956 : : integer :: count,counter,count1,iband,icg
957 : : integer :: ierr,ii,ikpt,ikpt_loc,ikpt2
958 : : integer :: ikpt_rbz,ineigh,info,ipw,isppol,jband,jcg,jj,jkpt,job,jpw, jkpt2, jkpt_rbz
959 : : integer :: lband,lpband,nband_occ,npw_k,npw_k1,my_source,his_source,dest,tag
960 : : integer :: spaceComm
961 : : integer,parameter :: level=52
962 : : integer :: bdtot_index
963 : : !
964 : : !---- Local variables : integer arrays
965 : 145 : integer,allocatable :: ipvt(:)
966 : 145 : integer, allocatable :: bd_index(:,:)
967 : : !
968 : : !---- Local variables : real(dp) scalars
969 : : real(dp) :: dotnegi,dotnegr,dotposi,dotposr
970 : : ! real(dp) :: c1,c2 ! appear commented out below
971 : : !
972 : : !---- Local variables : real(dp) arrays
973 : : real(dp) :: d3_aux(2,3),det(2,2),dk(3),dk_(3)
974 : : real(dp) :: z1(2),z2(2)
975 : 145 : real(dp),allocatable :: buffer(:,:),cgq(:,:),cg1q(:,:),cg3q(:,:)
976 : 145 : real(dp),allocatable :: qmat(:,:,:),s13mat(:,:,:),s1mat(:,:,:),s3mat(:,:,:)
977 : 145 : real(dp),allocatable :: smat(:,:,:),zgwork(:,:)
978 : : !
979 : : !---- Local variables : character variables
980 : : character(len=500) :: message
981 : : !
982 : : !---- Local variables : structured datatypes
983 : :
984 : :
985 : : #if defined HAVE_MPI
986 : : integer :: status1(MPI_STATUS_SIZE)
987 : 145 : spaceComm=mpi_enreg%comm_cell
988 : : #endif
989 : :
990 : : ABI_UNUSED(dtfil%ireadwf)
991 : :
992 : : ! ***********************************************************************
993 : :
994 : 145 : write(message,'(8a)') ch10,&
995 : 145 : & ' pead_nl_mv : finite difference expression of the k-point derivative',ch10,&
996 : 145 : & ' is performed using the PEAD formulation of ',&
997 : 145 : & 'the third-order energy',ch10,&
998 : 290 : & ' (see Nunes and Gonze PRB 63, 155107 (2001) [[cite:Nunes2001]] Eq. 102)',ch10
999 : : !call wrtout(ab_out,message,'COLL')
1000 : 145 : call wrtout(std_out, message,'COLL')
1001 : :
1002 : :
1003 : : !fab: I think that the following restriction must be eliminated:
1004 : : !isppol = 1
1005 : :
1006 : 145 : ikpt_loc = 0
1007 : 145 : d3_aux(:,:) = 0_dp
1008 : :
1009 [ - + + - : 580 : ABI_MALLOC(s13mat,(2,mband,mband))
- + + - +
- + - - +
- + ]
1010 [ - + + - : 435 : ABI_MALLOC(smat,(2,mband,mband))
- + + - -
+ - + ]
1011 [ - + + - : 435 : ABI_MALLOC(s1mat,(2,mband,mband))
- + + - -
+ - + ]
1012 [ - + + - : 435 : ABI_MALLOC(qmat,(2,mband,mband))
- + + - -
+ - + ]
1013 [ - + + - : 435 : ABI_MALLOC(ipvt,(mband))
+ - + - -
+ - + ]
1014 [ - + + - : 435 : ABI_MALLOC(s3mat,(2,mband,mband))
- + + - -
+ - + ]
1015 [ - + + - : 435 : ABI_MALLOC(zgwork,(2,mband))
+ - + - -
+ - + ]
1016 [ - + + - : 580 : ABI_MALLOC(bd_index, (nkpt2, nsppol))
- + + - +
- + - - +
- + ]
1017 : :
1018 : 318 : bdtot_index = 0
1019 [ + + ]: 318 : do isppol = 1, nsppol
1020 [ + + ]: 4815 : do ikpt_rbz = 1, nkpt2
1021 : 4497 : bd_index(ikpt_rbz,isppol) = bdtot_index
1022 : 4670 : bdtot_index = bdtot_index + dtset%nband(ikpt_rbz+nkpt2*(isppol-1))
1023 : : end do
1024 : : end do
1025 : :
1026 : : !fab: I think here I have to add the loop over spin
1027 : :
1028 [ + + ]: 318 : do isppol = 1, nsppol
1029 : :
1030 : : ! Loop over k-points
1031 : : ! COMMENT: Every processor has to make mkmem_max iterations
1032 : : ! even if mkmem < mkemem_max. This is due to the fact
1033 : : ! that it still has to communicate its wavefunctions
1034 : : ! to other processors even if it has no more overlap
1035 : : ! matrices to compute.
1036 : :
1037 : 173 : ikpt_loc = 0 ; ikpt = 0
1038 : :
1039 [ + + ]: 4591 : do while (ikpt_loc < mkmem_max)
1040 : :
1041 [ + - ]: 4273 : if (ikpt_loc < mkmem) ikpt = ikpt + 1
1042 : :
1043 : : if (xmpi_paral == 1) then
1044 : : ! if ((minval(abs(mpi_enreg%proc_distrb(ikpt,1:mband,1:dtset%nsppol) &
1045 : : ! & - mpi_enreg%me)) /= 0).and.(ikpt_loc < mkmem)) cycle
1046 [ - + ]: 4273 : if(ikpt>nkpt2)then
1047 : : ikpt_loc=mkmem_max
1048 : : cycle
1049 : : end if
1050 [ + + ]: 4273 : if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,mband,-1,mpi_enreg%me)) then
1051 [ - + ]: 224 : if(ikpt==nkpt2) ikpt_loc=mkmem_max
1052 : : cycle
1053 : : end if
1054 : : end if
1055 : :
1056 : 4049 : ikpt_loc = ikpt_loc + 1
1057 : 4049 : npw_k = npwarr(ikpt)
1058 : 4049 : counter = 100*ikpt
1059 : :
1060 : 4049 : ii = cgindex(ikpt,isppol)
1061 : :
1062 : : ! Loop on the neighbours
1063 : :
1064 [ + + ]: 28516 : do ineigh = 1,nneigh
1065 : :
1066 [ + + + + : 1271622 : s13mat(:,:,:) = zero
+ + ]
1067 [ + + + + : 1271622 : smat(:,:,:) = zero
+ + ]
1068 [ + + + + : 1271622 : s1mat(:,:,:) = zero
+ + ]
1069 [ + + + + : 1271622 : s3mat(:,:,:) = zero
+ + ]
1070 [ + + + + : 1271622 : qmat(:,:,:) = zero
+ + ]
1071 : :
1072 : 24294 : ikpt2 = kneigh(ineigh,ikpt)
1073 : 24294 : ikpt_rbz = kptindex(1,ikpt2) ! index of the k-point in the reduced BZ
1074 : 24294 : jj = cgindex(ikpt_rbz,isppol)
1075 : : ! previous fixed value for nband_k now called nband_occ:
1076 : : !nband_occ = dtset%nband(ikpt_rbz+nkpt2*(isppol-1))
1077 : : ! TODO: check if all these bands are occupied in nsppol = 2 case
1078 : 24294 : nband_occ = 0
1079 [ + + ]: 120510 : do iband = 1, dtset%nband(ikpt_rbz+nkpt2*(isppol-1))
1080 : : !Note, only one image is allowed here (or occ_orig should be the same or all images)
1081 [ + - ]: 120510 : if (dtset%occ_orig(bd_index(ikpt_rbz,isppol) + iband,1) > tol10) nband_occ = nband_occ + 1
1082 : : end do
1083 : 24294 : npw_k1 = npwarr(ikpt_rbz)
1084 [ + + ]: 97176 : dk_(:) = kpt3(:,ikpt2) - dtset%kptns(:,ikpt)
1085 [ + + ]: 97176 : dk(:) = dk_(:) - nint(dk_(:)) + real(kg_neigh(ineigh,ikpt,:),dp)
1086 : :
1087 : 24294 : count = nspinor*mband*npw_k1
1088 [ - + + - : 72882 : ABI_MALLOC(cgq,(2,count))
+ - + - -
+ - + ]
1089 [ - + + - : 48588 : ABI_MALLOC(cg1q,(2,count))
- + - + ]
1090 [ - + + - : 48588 : ABI_MALLOC(cg3q,(2,count))
- + - + ]
1091 : :
1092 : : #if defined HAVE_MPI
1093 : :
1094 : 24294 : my_source = mpi_enreg%proc_distrb(ikpt_rbz,1,1)
1095 : :
1096 : : ! do dest = 0, mpi_enreg%nproc-1
1097 [ + + + + : 31836066 : do dest = 0, maxval(mpi_enreg%proc_distrb(1:nkpt2,1:mband,1:dtset%nsppol))
+ + + + ]
1098 : :
1099 [ + + + - ]: 51276 : if ((dest==mpi_enreg%me).and.(ikpt_loc <= mkmem)) then
1100 : : ! I am dest and have something to do
1101 : :
1102 [ + + ]: 24294 : if (my_source == mpi_enreg%me) then
1103 : : ! I am destination and source
1104 : 23510 : jcg = cgindex(ikpt_rbz,isppol)
1105 : :
1106 [ + + + + ]: 24919310 : cgq(:,1:count) = cg(:,jcg+1:jcg+count)
1107 [ + + + + ]: 24919310 : cg1q(:,1:count) = cg1(:,jcg+1:jcg+count)
1108 [ + + + + ]: 24919310 : cg3q(:,1:count) = cg3(:,jcg+1:jcg+count)
1109 : :
1110 : : else
1111 : : ! I am the destination but not the source -> receive
1112 : :
1113 : 784 : tag = ikpt_rbz
1114 : :
1115 [ + - - + : 2352 : ABI_MALLOC(buffer,(2,3*count))
+ - + - +
- - + -
+ ]
1116 : :
1117 : 784 : call MPI_RECV(buffer,2*3*count,MPI_DOUBLE_PRECISION,my_source,tag,spaceComm,status1,ierr)
1118 : :
1119 [ + + + + ]: 141904 : cgq(:,1:count) = buffer(:,1:count)
1120 [ + + + + ]: 141904 : cg1q(:,1:count) = buffer(:,count+1:2*count)
1121 [ + + + + ]: 141904 : cg3q(:,1:count) = buffer(:,2*count+1:3*count)
1122 [ - + ]: 784 : ABI_FREE(buffer)
1123 : :
1124 : : end if
1125 : :
1126 [ + - ]: 2688 : else if (ikpt_loc <= mpi_enreg%mkmem(dest)) then ! dest != me and the dest has a k-point to treat
1127 : :
1128 : 2688 : jkpt=mpi_enreg%kpt_loc2ibz_sp(dest, ikpt_loc,1)
1129 : 2688 : jkpt2 = kneigh(ineigh,jkpt)
1130 : 2688 : jkpt_rbz = kptindex(1,jkpt2) ! index of the k-point in the reduced BZ
1131 : :
1132 : 2688 : his_source = mpi_enreg%proc_distrb(jkpt_rbz,1,1)
1133 : :
1134 [ + + ]: 2688 : if (his_source == mpi_enreg%me) then
1135 : :
1136 : 784 : jcg = cgindex(jkpt_rbz,isppol)
1137 : :
1138 : 784 : tag = jkpt_rbz
1139 : 784 : count1 = npwarr(jkpt_rbz)*mband*nspinor
1140 [ + - - + : 2352 : ABI_MALLOC(buffer,(2,3*count1))
+ - + - +
- - + -
+ ]
1141 [ + + + + ]: 141904 : buffer(:,1:count1) = cg(:,jcg+1:jcg+count1)
1142 [ + + + + ]: 141904 : buffer(:,count1+1:2*count1) = cg1(:,jcg+1:jcg+count1)
1143 [ + + + + ]: 141904 : buffer(:,2*count1+1:3*count1) = cg3(:,jcg+1:jcg+count1)
1144 : :
1145 : 784 : call MPI_SEND(buffer,2*3*count1,MPI_DOUBLE_PRECISION,dest,tag,spaceComm,ierr)
1146 : :
1147 [ - + ]: 784 : ABI_FREE(buffer)
1148 : :
1149 : : end if
1150 : :
1151 : : end if
1152 : :
1153 : : end do
1154 : : !
1155 : : ! do jkpt = 1, nkpt2
1156 : : !
1157 : : ! if ((jkpt == ikpt_rbz).and.(source /= mpi_enreg%me).and.&
1158 : : ! & (ikpt_loc <= mkmem)) then
1159 : : !
1160 : : ! tag = jkpt
1161 : : !
1162 : : ! allocate(buffer(2,3*count))
1163 : : ! call MPI_RECV(buffer,2*3*count,MPI_DOUBLE_PRECISION,&
1164 : : ! source,tag,spaceComm,status1,ierr)
1165 : : !
1166 : : ! cgq(:,1:count) = buffer(:,1:count)
1167 : : ! cg1q(:,1:count) = buffer(:,count+1:2*count)
1168 : : ! cg3q(:,1:count) = buffer(:,2*count+1:3*count)
1169 : : ! deallocate(buffer)
1170 : : !
1171 : : ! end if
1172 : : !
1173 : : ! ! ----------------------------------------------------------------------------
1174 : : ! ! --------------- Here: send the WF to all the cpus that need it -------------
1175 : : ! ! ----------------------------------------------------------------------------
1176 : : !
1177 : : ! do dest = 1, mpi_enreg%nproc
1178 : : !
1179 : : ! if ((minval(abs(mpi_enreg%proc_distrb(jkpt,1:mband,1:dtset%nsppol) &
1180 : : ! & - mpi_enreg%me)) == 0).and.&
1181 : : ! & (mpi_enreg%kptdstrb(dest,ineigh,ikpt_loc) == jkpt)) then
1182 : : !
1183 : : !
1184 : : !
1185 : : ! jcg = cgindex(jkpt,isppol)
1186 : : !
1187 : : ! if (((dest-1) == mpi_enreg%me)) then
1188 : : !
1189 : : ! cgq(:,1:count) = cg(:,jcg+1:jcg+count)
1190 : : ! cg1q(:,1:count) = cg1(:,jcg+1:jcg+count)
1191 : : ! cg3q(:,1:count) = cg3(:,jcg+1:jcg+count)
1192 : : !
1193 : : ! else
1194 : : !
1195 : : ! tag = jkpt
1196 : : ! count1 = npwarr(jkpt)*mband*nspinor
1197 : : ! allocate(buffer(2,3*count1))
1198 : : ! buffer(:,1:count1) = cg(:,jcg+1:jcg+count1)
1199 : : ! buffer(:,count1+1:2*count1) = cg1(:,jcg+1:jcg+count1)
1200 : : ! buffer(:,2*count1+1:3*count1) = cg3(:,jcg+1:jcg+count1)
1201 : : !
1202 : : ! call MPI_SEND(buffer,2*3*count1,MPI_DOUBLE_PRECISION,(dest-1),tag,spaceComm,ierr)
1203 : : !
1204 : : ! deallocate(buffer)
1205 : : !
1206 : : ! end if
1207 : : !
1208 : : ! end if
1209 : : !
1210 : : ! end do ! loop over dest
1211 : : !
1212 : : ! end do ! loop over jkpt
1213 : :
1214 [ - + ]: 24294 : if (ikpt_loc > mkmem) then
1215 [ # # ]: 0 : ABI_FREE(cgq)
1216 [ # # ]: 0 : ABI_FREE(cg1q)
1217 [ # # ]: 0 : ABI_FREE(cg3q)
1218 : 0 : cycle
1219 : : end if
1220 : :
1221 : : #else
1222 : : ! no // over k-points
1223 : :
1224 : : cgq(:,1:count) = cg(:,jj+1:jj+count)
1225 : : cg1q(:,1:count) = cg1(:,jj+1:jj+count)
1226 : : cg3q(:,1:count) = cg3(:,jj+1:jj+count)
1227 : :
1228 : : #endif
1229 : :
1230 : : ! Compute overlap matrices
1231 : :
1232 [ + + ]: 24294 : if (kptindex(2,ikpt2) == 0) then ! no time-reversal symmetry
1233 : :
1234 [ + + ]: 1827044 : do ipw = 1, npw_k
1235 : :
1236 : 1807602 : jpw = pwind(ipw,ineigh,ikpt_loc)
1237 [ + + ]: 1827044 : if (jpw /= 0) then
1238 : :
1239 [ + + ]: 7912824 : do iband = 1, nband_occ
1240 [ + + ]: 31954392 : do jband = 1, nband_occ
1241 : :
1242 : 24041568 : icg = ii + (iband-1)*npw_k + ipw
1243 : 24041568 : jcg = (jband-1)*npw_k1 + jpw
1244 : :
1245 : : smat(1,iband,jband) = smat(1,iband,jband) + &
1246 : 24041568 : & cg(1,icg)*cgq(1,jcg) + cg(2,icg)*cgq(2,jcg)
1247 : : smat(2,iband,jband) = smat(2,iband,jband) + &
1248 : 24041568 : & cg(1,icg)*cgq(2,jcg) - cg(2,icg)*cgq(1,jcg)
1249 : :
1250 : : s13mat(1,iband,jband) = s13mat(1,iband,jband) + &
1251 : 24041568 : & cg1(1,icg)*cg3q(1,jcg) + cg1(2,icg)*cg3q(2,jcg)
1252 : : s13mat(2,iband,jband) = s13mat(2,iband,jband) + &
1253 : 24041568 : & cg1(1,icg)*cg3q(2,jcg) - cg1(2,icg)*cg3q(1,jcg)
1254 : :
1255 : : s1mat(1,iband,jband) = s1mat(1,iband,jband) + &
1256 : : & cg1(1,icg)*cgq(1,jcg) + cg1(2,icg)*cgq(2,jcg) + &
1257 : 24041568 : & cg(1,icg)*cg1q(1,jcg) + cg(2,icg)*cg1q(2,jcg)
1258 : : s1mat(2,iband,jband) = s1mat(2,iband,jband) + &
1259 : : & cg1(1,icg)*cgq(2,jcg) - cg1(2,icg)*cgq(1,jcg) + &
1260 : 24041568 : & cg(1,icg)*cg1q(2,jcg) - cg(2,icg)*cg1q(1,jcg)
1261 : :
1262 : : s3mat(1,iband,jband) = s3mat(1,iband,jband) + &
1263 : : & cg3(1,icg)*cgq(1,jcg) + cg3(2,icg)*cgq(2,jcg) + &
1264 : 24041568 : & cg(1,icg)*cg3q(1,jcg) + cg(2,icg)*cg3q(2,jcg)
1265 : : s3mat(2,iband,jband) = s3mat(2,iband,jband) + &
1266 : : & cg3(1,icg)*cgq(2,jcg) - cg3(2,icg)*cgq(1,jcg) + &
1267 : 30266304 : & cg(1,icg)*cg3q(2,jcg) - cg(2,icg)*cg3q(1,jcg)
1268 : :
1269 : : end do
1270 : : end do
1271 : :
1272 : : end if
1273 : :
1274 : : end do ! ipw
1275 : :
1276 : : else ! use time-reversal symmetry
1277 : :
1278 [ + + ]: 423940 : do ipw = 1,npw_k
1279 : :
1280 : 419088 : jpw = pwind(ipw,ineigh,ikpt_loc)
1281 [ + + ]: 423940 : if (jpw /= 0) then
1282 : :
1283 [ + + ]: 1901116 : do iband = 1, nband_occ
1284 [ + + ]: 7881324 : do jband = 1, nband_occ
1285 : :
1286 : 5980208 : icg = ii + (iband-1)*npw_k + ipw
1287 : 5980208 : jcg = (jband-1)*npw_k1 + jpw
1288 : :
1289 : : smat(1,iband,jband) = smat(1,iband,jband) + &
1290 : 5980208 : & cg(1,icg)*cgq(1,jcg) - cg(2,icg)*cgq(2,jcg)
1291 : : smat(2,iband,jband) = smat(2,iband,jband) - &
1292 : 5980208 : & cg(1,icg)*cgq(2,jcg) - cg(2,icg)*cgq(1,jcg)
1293 : :
1294 : : s13mat(1,iband,jband) = s13mat(1,iband,jband) + &
1295 : 5980208 : & cg1(1,icg)*cg3q(1,jcg) - cg1(2,icg)*cg3q(2,jcg)
1296 : : s13mat(2,iband,jband) = s13mat(2,iband,jband) - &
1297 : 5980208 : & cg1(1,icg)*cg3q(2,jcg) - cg1(2,icg)*cg3q(1,jcg)
1298 : :
1299 : : s1mat(1,iband,jband) = s1mat(1,iband,jband) + &
1300 : : & cg1(1,icg)*cgq(1,jcg) - cg1(2,icg)*cgq(2,jcg) + &
1301 : 5980208 : & cg(1,icg)*cg1q(1,jcg) - cg(2,icg)*cg1q(2,jcg)
1302 : : s1mat(2,iband,jband) = s1mat(2,iband,jband) - &
1303 : : & cg1(1,icg)*cgq(2,jcg) - cg1(2,icg)*cgq(1,jcg) - &
1304 : 5980208 : & cg(1,icg)*cg1q(2,jcg) - cg(2,icg)*cg1q(1,jcg)
1305 : :
1306 : : s3mat(1,iband,jband) = s3mat(1,iband,jband) + &
1307 : : & cg3(1,icg)*cgq(1,jcg) - cg3(2,icg)*cgq(2,jcg) + &
1308 : 5980208 : & cg(1,icg)*cg3q(1,jcg) - cg(2,icg)*cg3q(2,jcg)
1309 : : s3mat(2,iband,jband) = s3mat(2,iband,jband) - &
1310 : : & cg3(1,icg)*cgq(2,jcg) - cg3(2,icg)*cgq(1,jcg) - &
1311 : 7492576 : & cg(1,icg)*cg3q(2,jcg) - cg(2,icg)*cg3q(1,jcg)
1312 : :
1313 : : end do
1314 : : end do
1315 : :
1316 : : end if
1317 : :
1318 : : end do ! ipw
1319 : :
1320 : : end if
1321 : :
1322 [ - + ]: 24294 : ABI_FREE(cgq)
1323 [ - + ]: 24294 : ABI_FREE(cg1q)
1324 [ - + ]: 24294 : ABI_FREE(cg3q)
1325 : :
1326 : : ! Compute qmat, the inverse of smat
1327 : :
1328 : 24294 : job = 1 ! compute inverse only
1329 [ + + + + : 1271622 : qmat(:,:,:) = smat(:,:,:)
+ + ]
1330 : :
1331 : 24294 : call dzgefa(qmat,mband,nband_occ,ipvt,info)
1332 : 24294 : call dzgedi(qmat,mband,nband_occ,ipvt,det,zgwork,job)
1333 : :
1334 : : ! DEBUG
1335 : : ! write(100,*)
1336 : : ! write(100,*)'ikpt = ',ikpt,'ineigh = ',ineigh
1337 : : ! do iband = 1,nband_occ
1338 : : ! do jband = 1,nband_occ
1339 : : ! c1 = 0_dp ; c2 = 0_dp
1340 : : ! do lband = 1,nband_occ
1341 : : ! c1 = c1 + smat(1,iband,lband)*qmat(1,lband,jband) - &
1342 : : ! & smat(2,iband,lband)*qmat(2,lband,jband)
1343 : : ! c2 = c2 + smat(1,iband,lband)*qmat(2,lband,jband) + &
1344 : : ! & smat(2,iband,lband)*qmat(1,lband,jband)
1345 : : ! end do
1346 : : ! write(100,'(2(2x,i2),2(2x,f16.9))')iband,jband,&
1347 : : ! & c1,c2
1348 : : ! end do
1349 : : ! end do
1350 : : ! ENDDEBUG
1351 : :
1352 : :
1353 : :
1354 : : ! Accumulate sum over bands
1355 : :
1356 : 24294 : dotposr = 0_dp ; dotposi = 0_dp
1357 : 24294 : dotnegr = 0_dp ; dotnegi = 0_dp
1358 [ + + ]: 120510 : do iband = 1, nband_occ
1359 [ + + ]: 503814 : do jband = 1, nband_occ
1360 : :
1361 : : dotposr = dotposr + &
1362 : : & s13mat(1,iband,jband)*qmat(1,jband,iband) - &
1363 : 383304 : & s13mat(2,iband,jband)*qmat(2,jband,iband)
1364 : : dotposi = dotposi + &
1365 : : & s13mat(1,iband,jband)*qmat(2,jband,iband) + &
1366 : 383304 : & s13mat(2,iband,jband)*qmat(1,jband,iband)
1367 : :
1368 : :
1369 [ + + ]: 2009976 : do lband = 1, nband_occ
1370 [ + + ]: 8030424 : do lpband= 1, nband_occ
1371 : :
1372 : : z1(1) = s1mat(1,iband,jband)*qmat(1,jband,lband) - &
1373 : 6116664 : & s1mat(2,iband,jband)*qmat(2,jband,lband)
1374 : : z1(2) = s1mat(1,iband,jband)*qmat(2,jband,lband) + &
1375 : 6116664 : & s1mat(2,iband,jband)*qmat(1,jband,lband)
1376 : :
1377 : : z2(1) = s3mat(1,lband,lpband)*qmat(1,lpband,iband) - &
1378 : 6116664 : & s3mat(2,lband,lpband)*qmat(2,lpband,iband)
1379 : : z2(2) = s3mat(1,lband,lpband)*qmat(2,lpband,iband) + &
1380 : 6116664 : & s3mat(2,lband,lpband)*qmat(1,lpband,iband)
1381 : :
1382 : : dotnegr = dotnegr + &
1383 : 6116664 : & z1(1)*z2(1) - z1(2)*z2(2)
1384 : : dotnegi = dotnegi + &
1385 : 7647120 : & z1(1)*z2(2) + z1(2)*z2(1)
1386 : :
1387 : : end do ! lpband
1388 : : end do ! lband
1389 : :
1390 : : end do ! jband
1391 : : end do ! iband
1392 : :
1393 : : d3_aux(1,:) = d3_aux(1,:) + &
1394 [ + + ]: 97176 : & dk(:)*mvwtk(ineigh,ikpt)*dtset%wtk(ikpt)*(2_dp*dotposr-dotnegr)
1395 : : d3_aux(2,:) = d3_aux(2,:) + &
1396 [ + + ]: 101225 : & dk(:)*mvwtk(ineigh,ikpt)*dtset%wtk(ikpt)*(2_dp*dotposi-dotnegi)
1397 : :
1398 : : end do ! End loop over neighbours
1399 : :
1400 : :
1401 : : end do ! End loop over k-points
1402 : :
1403 : : end do ! fab: end loop over spin
1404 : :
1405 : :
1406 : :
1407 : :
1408 : 145 : call xmpi_sum(d3_aux,spaceComm,ierr)
1409 : :
1410 : :
1411 [ - + ]: 145 : ABI_FREE(s13mat)
1412 [ - + ]: 145 : ABI_FREE(smat)
1413 [ - + ]: 145 : ABI_FREE(s1mat)
1414 [ - + ]: 145 : ABI_FREE(qmat)
1415 [ - + ]: 145 : ABI_FREE(ipvt)
1416 [ - + ]: 145 : ABI_FREE(s3mat)
1417 [ - + ]: 145 : ABI_FREE(zgwork)
1418 [ - + ]: 145 : ABI_FREE(bd_index)
1419 : :
1420 : :
1421 : : !fab: I think that in the following we have to make a distinction:
1422 : : !for the spin unpolarized case we leave the PEAD expression as it is, while
1423 : : !in the spin polarized case we have simply to divide by 2
1424 : : !(see eq.19 di PRB 63,155107 [[cite:Nunes2001]], eq. 7 di PRB 71,125107 [[cite:Veithen2005]]
1425 : : ! and eq 13 di PRB 71, 125107 [[cite:Veithen2005]] ...
1426 : : !in this latter equation the 2 must be simply replaced by the sum over the spin components...
1427 : : !and indeed we have inserted the loop over the spin,
1428 : : !but there was a factor 2 already present in the routine due to spin degenracy that had to be removed)
1429 : :
1430 : :
1431 [ + + ]: 145 : if (nsppol==1) then
1432 : :
1433 : : ! Take minus the imaginary part
1434 : :
1435 [ + + ]: 468 : d3_berry(1,:) = -1_dp*d3_aux(2,:)
1436 [ + + ]: 468 : d3_berry(2,:) = d3_aux(1,:)
1437 : :
1438 [ + + ]: 468 : d3_berry(2,:) = 0_dp
1439 : :
1440 : : else
1441 : :
1442 [ + + ]: 112 : d3_berry(1,:) = -1_dp*d3_aux(2,:)/2._dp
1443 [ + + ]: 112 : d3_berry(2,:) = d3_aux(1,:)/2._dp
1444 : :
1445 [ + + ]: 112 : d3_berry(2,:) = 0_dp/2._dp
1446 : :
1447 : : end if
1448 : :
1449 : : !DEBUG
1450 : : !write(100,*)'pead_nl_mv.f : d3_berry'
1451 : : !write(100,*)'Perturbation',i1dir,i3dir
1452 : : !write(100,*)
1453 : : !write(100,*)'before transformation'
1454 : : !write(100,*)'real part'
1455 : : !write(100,'(3(2x,f20.9))')d3_berry(1,:)
1456 : : !write(100,*)
1457 : : !write(100,*)'imaginary part'
1458 : : !write(100,'(3(2x,f20.9))')d3_berry(2,:)
1459 : : !write(100,*)
1460 : : !write(100,*)'after transformation'
1461 : : !ENDDEBUG
1462 : :
1463 : : !Compute the projection on the basis vectors of
1464 : : !reciprocal space
1465 : :
1466 : 145 : d3_aux(:,:) = 0_dp
1467 [ + + ]: 580 : do ii = 1,3
1468 [ + + ]: 1885 : do jj = 1,3
1469 [ + + ]: 4350 : d3_aux(:,ii) = d3_aux(:,ii) + gmet(ii,jj)*d3_berry(:,jj)
1470 : : end do
1471 : : end do
1472 : 145 : d3_berry(:,:) = d3_aux(:,:)
1473 : :
1474 : : !Write out the berryphase part of the third order energy
1475 : :
1476 [ + + ]: 145 : if (mpi_enreg%me == 0) then
1477 : :
1478 : 117 : write(message,'(a,a,a)')ch10,' Berryphase part of the third-order energy:',ch10
1479 : 117 : call wrtout(std_out, message,'COLL')
1480 : :
1481 [ + + ]: 117 : if (i1pert < natom + 1) then
1482 : : write(message,'(a,i3,a,i3)')&
1483 : 76 : & ' j1: Displacement of atom ',i1pert,&
1484 : 152 : & ' along direction ',i1dir
1485 [ + - ]: 41 : else if (i1pert == natom + 2) then
1486 : : write(message,'(a,i3)')&
1487 : 41 : & ' j1: homogenous electric field along direction ',i1dir
1488 : : end if
1489 : 117 : call wrtout(std_out, message,'COLL')
1490 : :
1491 : : write(message,'(a)')&
1492 : 117 : & ' j2: k-point derivative along direction i2dir '
1493 : 117 : call wrtout(std_out, message,'COLL')
1494 : :
1495 [ - + ]: 117 : if (i3pert < natom + 1) then
1496 : : write(message,'(a,i3,a,i3,a)')&
1497 : 0 : & ' j3: Displacement of atom ',i3pert,&
1498 : 0 : & ' along direction ',i3dir,ch10
1499 [ + - ]: 117 : else if (i3pert == natom + 2) then
1500 : : write(message,'(a,i3,a)')&
1501 : 117 : & ' j3: homogenous electric field along direction ',i3dir,ch10
1502 : : end if
1503 : 117 : call wrtout(std_out, message,'COLL')
1504 : :
1505 : : ! write(ab_out,'(5x,a5,8x,a9,5x,a14)')'i2dir','real part','imaginary part'
1506 : 117 : write(std_out,'(5x,a5,8x,a9,5x,a14)')'i2dir','real part','imaginary part'
1507 [ + + ]: 468 : do ii = 1,3
1508 : 351 : write(std_out,'(7x,i1,3x,f16.9,3x,f16.9)')ii,&
1509 : 702 : & d3_berry(1,ii),d3_berry(2,ii)
1510 : 351 : write(std_out,'(7x,i1,3x,f16.9,3x,f16.9)')ii,&
1511 : 819 : & d3_berry(1,ii),d3_berry(2,ii)
1512 : : end do
1513 : :
1514 : : end if ! mpi_enreg%me == 0
1515 : :
1516 : : !DEBUG
1517 : : !write(100,*)'real part'
1518 : : !write(100,'(3(2x,f20.9))')d3_berry(1,:)
1519 : : !write(100,*)
1520 : : !write(100,*)'imaginary part'
1521 : : !write(100,'(3(2x,f20.9))')d3_berry(2,:)
1522 : : !ENDDEBUG
1523 : :
1524 : 145 : end subroutine pead_nl_mv
1525 : : !!***
1526 : :
1527 : : end module m_pead_nl_loop
1528 : : !!***
|