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 : !!***
|