Line data Source code
1 : !!****m* ABINIT/m_mklocl
2 : !! NAME
3 : !! m_mklocl
4 : !!
5 : !! FUNCTION
6 : !! Routines related to the local part of the pseudopotentials.
7 : !!
8 : !! COPYRIGHT
9 : !! Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, MM, DRH)
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_mklocl
23 :
24 : use defs_basis
25 : use defs_wvltypes
26 : use m_abicore
27 : use m_errors
28 : use m_xmpi
29 : use m_dtset
30 :
31 : use defs_datatypes, only : pseudopotential_type
32 : use defs_abitypes, only : MPI_type
33 : use m_time, only : timab
34 : use m_geometry, only : xred2xcart
35 : use m_mpinfo, only : ptabs_fourdp
36 : use m_pawtab, only : pawtab_type
37 : use m_mklocl_realspace, only : mklocl_realspace, mklocl_wavelets
38 : use m_fft, only : fourdp
39 : use m_gtermcutoff,only : termcutoff
40 :
41 : use m_splines, only : splfit
42 : use m_dfpt_mkvxc, only : dfpt_mkvxcgga_n0met
43 :
44 : #if defined HAVE_BIGDFT
45 : use BigDFT_API, only : ELECTRONIC_DENSITY
46 : use m_abi2big, only : wvl_rho_abi2big
47 : #endif
48 :
49 : implicit none
50 :
51 : private
52 : !!***
53 :
54 : public :: mklocl
55 : public :: mklocl_recipspace
56 : public :: dfpt_vlocal ! Local part of 1st-order potential due to atomic displacement.
57 : public :: vlocalstr ! Compute strain derivatives of local ionic potential
58 : public :: dfpt_vlocaldq ! Compute the first q-gradient of the 1st-order potential due to atomic displacement.
59 : public :: dfpt_vlocaldqdq ! Compute the second q-gradient of the 1st-order potential due to atomic displacement.
60 : public :: dfpt_vmetdqdq ! Compute the second q-gradient of the 1st-order potential due to a metric perturbation.
61 : !!***
62 :
63 : contains
64 : !!***
65 :
66 : !!****f* ABINIT/mklocl
67 : !! NAME
68 : !! mklocl
69 : !!
70 : !! FUNCTION
71 : !! This method is a wrapper for mklocl_recipspace and mklocl_realspace.
72 : !! It does some consistency checks before calling one of the two methods.
73 : !!
74 : !! Optionally compute :
75 : !! option=1 : local ionic potential throughout unit cell
76 : !! option=2 : contribution of local ionic potential to E gradient wrt xred
77 : !! option=3 : contribution of local ionic potential to
78 : !! stress tensor (only with reciprocal space computations)
79 : !! option=4 : contribution of local ionic potential to
80 : !! second derivative of E wrt xred (only with reciprocal space computations)
81 : !!
82 : !! INPUTS
83 : !! if(option==3) eei=local pseudopotential part of total energy (hartree)
84 : !! gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$).
85 : !! gprimd(3,3)=reciprocal space dimensional primitive translations
86 : !! gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere).
87 : !! mgfft=maximum size of 1D FFTs
88 : !! mpi_enreg=information about MPI parallelization
89 : !! natom=number of atoms in unit cell.
90 : !! nattyp(ntypat)=number of atoms of each type in cell.
91 : !! nfft=(effective) number of FFT grid points (for this processor)
92 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
93 : !! nspden=number of spin-density components
94 : !! ntypat=number of types of atoms.
95 : !! option= (see above)
96 : !! pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
97 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
98 : !! psps <type(pseudopotential_type)>=variables related to pseudopotentials
99 : !! qprtrb(3)= integer wavevector of possible perturbing potential
100 : !! in basis of reciprocal lattice translations
101 : !! rhog(2,nfft)=electron density rho(G) (electrons/$\textrm{Bohr}^3$)
102 : !! (needed if option==2 or if option==4)
103 : !! rhor(nfft,nspden)=electron density in electrons/bohr**3.
104 : !! (needed if option==2 or if option==4)
105 : !! rprimd(3,3)=dimensional primitive translations in real space (bohr)
106 : !! ucvol=unit cell volume ($\textrm{Bohr}^3$).
107 : !! vprtrb(2)=complex amplitude of possible perturbing potential; if nonzero,
108 : !! perturbing potential is added of the form
109 : !! $V(G)=(vprtrb(1)+I*vprtrb(2))/2$ at the values G=qprtrb and
110 : !! $(vprtrb(1)-I*vprtrb(2))/2$ at $G=-qprtrb$ (integers)
111 : !! xred(3,natom)=reduced dimensionless atomic coordinates
112 : !!
113 : !! OUTPUT
114 : !! (if option==1) vpsp(nfft)=local crystal pseudopotential in real space.
115 : !! (if option==2) grtn(3,natom)=grads of Etot wrt tn.
116 : !! (if option==3) lpsstr(6)=components of local psp part of stress tensor
117 : !! (Cartesian coordinates, symmetric tensor) in hartree/$\textrm{bohr}^3$
118 : !! Store 6 unique components in order 11, 22, 33, 32, 31, 21
119 : !! (if option==4) dyfrlo(3,3,natom)=d2 Eei/d tn(i)/d tn(j). (Hartrees)
120 : !!
121 : !! NOTES
122 : !! Note that the present routine is tightly connected to the dfpt_vlocal.f routine,
123 : !! that compute the derivative of the local ionic potential
124 : !! with respect to one atomic displacement. The argument list
125 : !! and the internal loops to be considered were sufficiently different
126 : !! as to make the two routine different.
127 : !!
128 : !! SOURCE
129 :
130 23934 : subroutine mklocl(dtset, dyfrlo,eei,gmet,gprimd,grtn,gsqcut,lpsstr,mgfft,&
131 23934 : & mpi_enreg,natom,nattyp,nfft,ngfft,nspden,ntypat,option,pawtab,ph1d,psps,qprtrb,&
132 23934 : & rhog,rhor,rprimd,ucvol,vprtrb,vpsp,wvl,wvl_den,xred)
133 :
134 : !Arguments ------------------------------------
135 : !scalars
136 : integer,intent(in) :: mgfft,natom,nfft,nspden,ntypat,option
137 : real(dp),intent(in) :: eei,gsqcut,ucvol
138 : type(MPI_type),intent(in) :: mpi_enreg
139 : type(dataset_type),intent(in) :: dtset
140 : type(pseudopotential_type),intent(in) :: psps
141 : type(wvl_internal_type), intent(in) :: wvl
142 : type(wvl_denspot_type), intent(inout) :: wvl_den
143 : type(pawtab_type),intent(in) :: pawtab(ntypat*psps%usepaw)
144 : !arrays
145 : integer,intent(in) :: nattyp(ntypat),ngfft(18),qprtrb(3)
146 : real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom)
147 : real(dp),intent(in) :: rhog(2,nfft),rprimd(3,3)
148 : real(dp),intent(in) :: vprtrb(2),xred(3,natom)
149 : real(dp),intent(in),target :: rhor(nfft,nspden)
150 : real(dp),intent(out) :: dyfrlo(3,3,natom),grtn(3,natom),lpsstr(6)
151 : real(dp),intent(inout) :: vpsp(nfft)
152 :
153 : !Local variables-------------------------------
154 : !scalars
155 : character(len=500) :: message
156 : !arrays
157 23934 : real(dp),allocatable :: xcart(:,:)
158 : #if defined HAVE_BIGDFT
159 : real(dp),pointer :: rhor_ptr(:,:)
160 : #endif
161 :
162 : ! *************************************************************************
163 :
164 23934 : if (option < 1 .or. option > 4) then
165 : write(message,'(a,i0,a,a)')&
166 0 : & 'From the calling routine, option=',option,ch10,&
167 0 : & 'The only allowed values are between 1 and 4.'
168 0 : ABI_ERROR(message)
169 : end if
170 23934 : if (option > 2 .and. .not.psps%vlspl_recipSpace) then
171 : write(message,'(a,i0,a,a,a,a)')&
172 0 : & 'From the calling routine, option=',option,ch10,&
173 0 : & 'but the local part of the pseudo-potential is in real space.',ch10,&
174 0 : & 'Action: set icoulomb = 0 to turn-off real space computations.'
175 0 : ABI_ERROR(message)
176 : end if
177 23934 : if (option > 2 .and. dtset%usewvl == 1) then
178 : write(message,'(a,i0,a,a)')&
179 0 : & 'From the calling routine, option=',option,ch10,&
180 0 : & 'but this is not implemented yet from wavelets.'
181 0 : ABI_ERROR(message)
182 : end if
183 :
184 23934 : if (dtset%usewvl == 0) then
185 : ! Plane wave case
186 23934 : if (psps%vlspl_recipSpace) then
187 : call mklocl_recipspace(dyfrlo,eei,gmet,gprimd,grtn,gsqcut,&
188 : & dtset%icutcoul,lpsstr,mgfft,mpi_enreg,psps%mqgrid_vl,natom,nattyp, &
189 : & nfft,ngfft,dtset%nkpt,ntypat,option,ph1d,psps%qgrid_vl,qprtrb,dtset%rcut,&
190 23934 : & rhog,rprimd,ucvol,dtset%vcutgeo,psps%vlspl,vprtrb,vpsp)
191 : else
192 : call mklocl_realspace(grtn,dtset%icoulomb,mpi_enreg,natom,nattyp,nfft, &
193 : & ngfft,dtset%nscforder,nspden,ntypat,option,pawtab,psps,rhog,rhor, &
194 0 : & rprimd,dtset%typat,ucvol,dtset%usewvl,vpsp,xred)
195 : end if
196 : else
197 : ! Store xcart for each atom
198 0 : ABI_MALLOC(xcart,(3, dtset%natom))
199 0 : call xred2xcart(dtset%natom, rprimd, xcart, xred)
200 : ! Eventually retrieve density
201 : #if defined HAVE_BIGDFT
202 : if (option>1.and.wvl_den%denspot%rhov_is/=ELECTRONIC_DENSITY) then
203 : rhor_ptr => rhor ! Just to bypass intent(inout)
204 : call wvl_rho_abi2big(1,rhor_ptr,wvl_den)
205 : end if
206 : #endif
207 : ! Wavelets case
208 : call mklocl_wavelets(dtset%efield, grtn, mpi_enreg, dtset%natom, &
209 : & nfft, nspden, option, rprimd, vpsp, &
210 0 : & wvl_den, wvl, xcart)
211 0 : ABI_FREE(xcart)
212 : end if
213 :
214 23934 : end subroutine mklocl
215 : !!***
216 :
217 : !!****f* ABINIT/mklocl_recipspace
218 : !! NAME
219 : !! mklocl_recipspace
220 : !!
221 : !! FUNCTION
222 : !! Optionally compute :
223 : !! option=1 : local ionic potential throughout unit cell
224 : !! option=2 : contribution of local ionic potential to E gradient wrt xred
225 : !! option=3 : contribution of local ionic potential to stress tensor
226 : !! option=4 : contribution of local ionic potential to
227 : !! second derivative of E wrt xred
228 : !!
229 : !! INPUTS
230 : !! if(option==3) eei=local pseudopotential part of total energy (hartree)
231 : !! gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$).
232 : !! gprimd(3,3)=reciprocal space dimensional primitive translations
233 : !! gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere).
234 : !! mgfft=maximum size of 1D FFTs
235 : !! mpi_enreg=information about MPI parallelization
236 : !! mqgrid=number of grid pts in q array for f(q) spline.
237 : !! natom=number of atoms in unit cell.
238 : !! nattyp(ntypat)=number of atoms of each type in cell.
239 : !! nfft=(effective) number of FFT grid points (for this processor)
240 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
241 : !! ntypat=number of types of atoms.
242 : !! option= (see above)
243 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
244 : !! qgrid(mqgrid)=q grid for spline from 0 to qmax.
245 : !! qprtrb(3)= integer wavevector of possible perturbing potential
246 : !! in basis of reciprocal lattice translations
247 : !! rhog(2,nfft)=electron density rho(G) (electrons/$\textrm{Bohr}^3$)
248 : !! (needed if option==2 or if option==4)
249 : !! ucvol=unit cell volume ($\textrm{Bohr}^3$).
250 : !! vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom.
251 : !! vprtrb(2)=complex amplitude of possible perturbing potential; if nonzero,
252 : !! perturbing potential is added of the form
253 : !! $V(G)=(vprtrb(1)+I*vprtrb(2))/2$ at the values G=qprtrb and
254 : !! $(vprtrb(1)-I*vprtrb(2))/2$ at $G=-qprtrb$ (integers)
255 : !!
256 : !! OUTPUT
257 : !! (if option==1) vpsp(nfft)=local crystal pseudopotential in real space.
258 : !! (if option==2) grtn(3,natom)=grads of Etot wrt tn.
259 : !! (if option==3) lpsstr(6)=components of local psp part of stress tensor
260 : !! (Cartesian coordinates, symmetric tensor) in hartree/$\textrm{bohr}^3$
261 : !! Store 6 unique components in order 11, 22, 33, 32, 31, 21
262 : !! (if option==4) dyfrlo(3,3,natom)=d2 Eei/d tn(i)/d tn(j). (Hartrees)
263 : !!
264 : !! NOTES
265 : !! Note that the present routine is tightly connected to the dfpt_vlocal.f routine,
266 : !! that compute the derivative of the local ionic potential
267 : !! with respect to one atomic displacement. The argument list
268 : !! and the internal loops to be considered were sufficiently different
269 : !! as to make the two routine different.
270 : !!
271 : !! SOURCE
272 :
273 29246 : subroutine mklocl_recipspace(dyfrlo,eei,gmet,gprimd,grtn,gsqcut,icutcoul,lpsstr,mgfft,&
274 29246 : & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,nkpt,ntypat,option,ph1d,qgrid,qprtrb,&
275 29246 : & rcut,rhog,rprimd,ucvol,vcutgeo,vlspl,vprtrb,vpsp)
276 :
277 : !Arguments ------------------------------------
278 : !scalars
279 : integer,intent(in) :: mgfft,mqgrid,natom,nfft,nkpt,ntypat,option,icutcoul
280 : real(dp),intent(in) :: eei,gsqcut,rcut,rprimd(3,3),ucvol,vcutgeo(3)
281 : type(MPI_type),intent(in) :: mpi_enreg
282 : !arrays
283 : integer,intent(in) :: nattyp(ntypat),ngfft(18),qprtrb(3)
284 : real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom)
285 : real(dp),intent(in) :: qgrid(mqgrid),rhog(2,nfft),vlspl(mqgrid,2,ntypat)
286 : real(dp),intent(in) :: vprtrb(2)
287 : real(dp),intent(out) :: dyfrlo(3,3,natom),grtn(3,natom),lpsstr(6) !vz_i
288 : real(dp),intent(inout) :: vpsp(nfft) !vz_i
289 :
290 : !Local variables-------------------------------
291 : !scalars
292 : integer,parameter :: im=2,re=1
293 : integer :: i1,i2,i3,ia,ia1,ia2,id1,id2,id3,ierr,ig1,ig2,ig3,ii,itypat
294 : integer :: jj,me_fft,me_g0,n1,n2,n3,nproc_fft,shift1
295 : integer :: shift2,shift3
296 : #ifdef FC_NVHPC
297 : !Silly trick to prevent NVHPC optimization issue
298 : logical :: nothing=.false.
299 : #endif
300 : real(dp),parameter :: tolfix=1.0000001_dp
301 : real(dp) :: aa,bb,cc,cutoff,dbl_ig1,dbl_ig2,dbl_ig3,dd,diff,dq,dq2div6,dqdiv6
302 : real(dp) :: dqm1,ee,ff,gmag,gsquar!beta,gcart_para,gcart_perp
303 : real(dp) :: ph12i,ph12r,ph1i,ph1r,ph2i,ph2r
304 : real(dp) :: ph3i,ph3r,phimag_igia,phre_igia,rcut_loc,sfi,sfr
305 : real(dp) :: svion,svioni,svionr,term,vion1,vion2,xnorm
306 : character(len=500) :: message
307 : !arrays
308 29246 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
309 29246 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
310 : real(dp) :: gcart(3),tsec(2)
311 29246 : real(dp),allocatable :: gcutoff(:)
312 29246 : real(dp),allocatable :: work1(:,:)
313 : ! *************************************************************************
314 :
315 : !Define G^2 based on G space metric gmet.
316 : ! gsq(i1,i2,i3)=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
317 : !& dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
318 : !& dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
319 :
320 : !Real and imaginary parts of phase--statment functions:
321 : ! phr(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
322 : ! phi(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
323 : ! ph1(nri,i1,ia)=ph1d(nri,i1+1+n1+(ia-1)*(2*n1+1))
324 : ! ph2(nri,i2,ia)=ph1d(nri,i2+1+n2+(ia-1)*(2*n2+1)+&
325 : !& natom*(2*n1+1))
326 : ! ph3(nri,i3,ia)=ph1d(nri,i3+1+n3+(ia-1)*(2*n3+1)+&
327 : !& natom*(2*n1+1+2*n2+1))
328 : ! phre(i1,i2,i3,ia)=phr(ph1(re,i1,ia),ph1(im,i1,ia),ph2(re,i2,ia),&
329 : !& ph2(im,i2,ia),ph3(re,i3,ia),ph3(im,i3,ia))
330 : ! phimag(i1,i2,i3,ia)=phi(ph1(re,i1,ia),ph1(im,i1,ia),ph2(re,i2,ia),&
331 : !& ph2(im,i2,ia),ph3(re,i3,ia),ph3(im,i3,ia))
332 :
333 : !-----
334 :
335 : !Keep track of total time spent in mklocl
336 29246 : if(option==2)then
337 17073 : call timab(72,1,tsec)
338 : end if
339 29246 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
340 29246 : me_fft=ngfft(11)
341 29246 : nproc_fft=ngfft(10)
342 :
343 : !Get the distrib associated with this fft_grid
344 29246 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
345 :
346 : !Zero out array to permit accumulation over atom types below:
347 29246 : if(option==1)then
348 20583 : ABI_MALLOC(work1,(2,nfft))
349 341143209 : work1(:,:)=zero
350 : end if
351 :
352 : !
353 29246 : dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1)
354 29246 : dqm1=1.0_dp/dq
355 29246 : dqdiv6=dq/6.0_dp
356 29246 : dq2div6=dq**2/6.0_dp
357 29246 : cutoff=gsqcut*tolfix
358 29246 : id1=n1/2+2
359 29246 : id2=n2/2+2
360 29246 : id3=n3/2+2
361 349194 : grtn(:,:)=zero
362 29246 : lpsstr(:)=zero
363 1069077 : dyfrlo(:,:,:)=zero
364 29246 : me_g0=0
365 29246 : ia1=1
366 :
367 : !Initialize Gcut-off array from m_gtermcutoff
368 29246 : call termcutoff(gcutoff,gsqcut,icutcoul,ngfft,nkpt,rcut,rprimd,vcutgeo)
369 29246 : rcut_loc = half*SQRT(DOT_PRODUCT(rprimd(:,3),rprimd(:,3)))
370 :
371 72544 : do itypat=1,ntypat
372 : ! ia1,ia2 sets range of loop over atoms:
373 43298 : ia2=ia1+nattyp(itypat)-1
374 :
375 43298 : ii=0
376 831004 : do i3=1,n3
377 787706 : ig3=i3-(i3/id3)*n3-1
378 19051151 : do i2=1,n2
379 18220147 : ig2=i2-(i2/id2)*n2-1
380 19007853 : if(fftn2_distrib(i2) == me_fft ) then
381 636226579 : do i1=1,n1
382 618410760 : ig1=i1-(i1/id1)*n1-1
383 :
384 618410760 : ii=ii+1
385 : ! *** GET RID OF THIS THESE IF STATEMENTS (if they slow code)
386 : ! Skip G=0:
387 : ! if (ii==1) cycle
388 618410760 : if (ig1==0 .and. ig2==0 .and. ig3==0) me_g0=1
389 618410760 : if (ig1==0 .and. ig2==0 .and. ig3==0) cycle
390 :
391 618368130 : gsquar=gsq_mk(ig1,ig2,ig3)
392 : ! Skip G**2 outside cutoff:
393 636183949 : if (gsquar<=cutoff) then
394 258249564 : gmag=sqrt(gsquar)
395 :
396 : ! Compute vion(G) for given type of atom
397 258249564 : jj=1+int(gmag*dqm1)
398 258249564 : diff=gmag-qgrid(jj)
399 :
400 : ! Evaluate spline fit from q^2 V(q) to get V(q):
401 : ! (p. 86 Numerical Recipes, Press et al;
402 : ! NOTE error in book for sign
403 : ! of "aa" term in derivative; also see splfit routine).
404 :
405 258249564 : bb = diff*dqm1
406 258249564 : aa = 1.0_dp-bb
407 258249564 : cc = aa*(aa**2-1.0_dp)*dq2div6
408 258249564 : dd = bb*(bb**2-1.0_dp)*dq2div6
409 :
410 : vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) +&
411 258249564 : & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) / gsquar * gcutoff(ii)
412 :
413 258249564 : if(option==1)then
414 :
415 : ! Assemble structure factor over all atoms of given type:
416 58652841 : sfr=zero
417 58652841 : sfi=zero
418 193614974 : do ia=ia1,ia2
419 134962133 : sfr=sfr+phre_mk(ig1,ig2,ig3,ia)
420 193614974 : sfi=sfi-phimag_mk(ig1,ig2,ig3,ia)
421 : end do
422 : ! Multiply structure factor times vion:
423 58652841 : work1(re,ii)=work1(re,ii)+sfr*vion1
424 58652841 : work1(im,ii)=work1(im,ii)+sfi*vion1
425 :
426 199596723 : else if(option==2 .or. option==4)then
427 :
428 : ! Compute Re and Im part of (2Pi)*Vion(G)*rho(G):
429 152077859 : svionr=(two_pi*vion1)*rhog(re,ii)
430 152077859 : svioni=(two_pi*vion1)*rhog(im,ii)
431 :
432 : ! Loop over all atoms of this type:
433 433820355 : do ia=ia1,ia2
434 : #ifdef FC_NVHPC
435 : !Silly trick to prevent NVHPC optimization issue
436 : if(nothing) write(100,*) shift1,shift2,shift3
437 : #endif
438 :
439 281742496 : shift1=1+n1+(ia-1)*(2*n1+1)
440 281742496 : shift2=1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1)
441 281742496 : shift3=1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1)
442 281742496 : ph1r=ph1d(1,ig1+shift1)
443 281742496 : ph1i=ph1d(2,ig1+shift1)
444 281742496 : ph2r=ph1d(1,ig2+shift2)
445 281742496 : ph2i=ph1d(2,ig2+shift2)
446 281742496 : ph3r=ph1d(1,ig3+shift3)
447 281742496 : ph3i=ph1d(2,ig3+shift3)
448 281742496 : ph12r=ph1r*ph2r-ph1i*ph2i
449 281742496 : ph12i=ph1r*ph2i+ph1i*ph2r
450 281742496 : phre_igia=ph12r*ph3r-ph12i*ph3i
451 281742496 : phimag_igia=ph12r*ph3i+ph12i*ph3r
452 :
453 433820355 : if(option==2)then
454 :
455 : ! Compute "Vion" part of gradient
456 : ! svion=svioni*phre(ig1,ig2,ig3,ia)+svionr*phimag(ig1,ig2,ig3,ia)
457 277926218 : svion=svioni*phre_igia+svionr*phimag_igia
458 :
459 : ! Open loop over 3-index for speed:
460 277926218 : grtn(1,ia)=grtn(1,ia)-dble(ig1)*svion
461 277926218 : grtn(2,ia)=grtn(2,ia)-dble(ig2)*svion
462 277926218 : grtn(3,ia)=grtn(3,ia)-dble(ig3)*svion
463 :
464 : else
465 :
466 : ! Compute "Vion" part of the second derivative
467 : ! svion=two_pi*
468 : ! (svionr*phre(ig1,ig2,ig3,ia)-svioni*phimag(ig1,ig2,ig3,ia))
469 3816278 : svion=two_pi*(svionr*phre_igia-svioni*phimag_igia)
470 :
471 : ! Open loop over 3-index for speed
472 3816278 : dbl_ig1=dble(ig1) ; dbl_ig2=dble(ig2) ; dbl_ig3=dble(ig3)
473 3816278 : dyfrlo(1,1,ia)=dyfrlo(1,1,ia)-dbl_ig1*dbl_ig1*svion
474 3816278 : dyfrlo(1,2,ia)=dyfrlo(1,2,ia)-dbl_ig1*dbl_ig2*svion
475 3816278 : dyfrlo(1,3,ia)=dyfrlo(1,3,ia)-dbl_ig1*dbl_ig3*svion
476 3816278 : dyfrlo(2,2,ia)=dyfrlo(2,2,ia)-dbl_ig2*dbl_ig2*svion
477 3816278 : dyfrlo(2,3,ia)=dyfrlo(2,3,ia)-dbl_ig2*dbl_ig3*svion
478 3816278 : dyfrlo(3,3,ia)=dyfrlo(3,3,ia)-dbl_ig3*dbl_ig3*svion
479 :
480 : end if
481 :
482 : end do
483 :
484 47518864 : else if(option==3)then
485 : ! if(icutcoul .ne. 2) then
486 : ! Also get (dV(q)/dq)/q:
487 : ! (note correction of Numerical Recipes sign error
488 : ! before (3._dp*aa**2-1._dp)
489 : ! ee*dqm1 + ff*dqdiv6 is the best estimate of dV(q)/dq from splines
490 47518864 : ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat)
491 : ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) &
492 47518864 : & - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat)
493 : vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag&
494 47518864 : & - 2.0_dp*vion1 ) / gsquar
495 :
496 : gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+&
497 47518864 : & gprimd(1,3)*dble(ig3)
498 : gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+&
499 47518864 : & gprimd(2,3)*dble(ig3)
500 : gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+&
501 47518864 : & gprimd(3,3)*dble(ig3)
502 : ! Assemble structure over all atoms of given type
503 47518864 : sfr=zero
504 47518864 : sfi=zero
505 156467745 : do ia=ia1,ia2
506 108948881 : sfr=sfr+phre_mk(ig1,ig2,ig3,ia)
507 156467745 : sfi=sfi-phimag_mk(ig1,ig2,ig3,ia)
508 : end do
509 : ! Compute Re( rho^*(G)* sf ) * [(dV(G)/dG)/|G|]
510 47518864 : term=(rhog(re,ii)*sfr+rhog(im,ii)*sfi)*vion2
511 : ! Compute contribution to stress tensor
512 47518864 : lpsstr(1)=lpsstr(1)-term*gcart(1)*gcart(1)
513 47518864 : lpsstr(2)=lpsstr(2)-term*gcart(2)*gcart(2)
514 47518864 : lpsstr(3)=lpsstr(3)-term*gcart(3)*gcart(3)
515 47518864 : lpsstr(4)=lpsstr(4)-term*gcart(3)*gcart(2)
516 47518864 : lpsstr(5)=lpsstr(5)-term*gcart(3)*gcart(1)
517 47518864 : lpsstr(6)=lpsstr(6)-term*gcart(2)*gcart(1)
518 : ! else if (icutcoul .eq. 2) then
519 : !! Also get (dV(q)/dq)/q:
520 : !! (note correction of Numerical Recipes sign error
521 : !! before (3._dp*aa**2-1._dp)
522 : !! ee*dqm1 + ff*dqdiv6 is the best estimate of dV(q)/dq from splines
523 : ! ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat)
524 : ! ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) &
525 : !& - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat)
526 : ! vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag&
527 : !& - 2.0_dp*vion1 ) / gsquar
528 : !
529 : ! gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+&
530 : !& gprimd(1,3)*dble(ig3)
531 : ! gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+&
532 : !& gprimd(2,3)*dble(ig3)
533 : ! gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+&
534 : !& gprimd(3,3)*dble(ig3)
535 : !! Assemble structure over all atoms of given type
536 : ! sfr=zero
537 : ! sfi=zero
538 : ! do ia=ia1,ia2
539 : ! sfr=sfr+phre_mk(ig1,ig2,ig3,ia)
540 : ! sfi=sfi-phimag_mk(ig1,ig2,ig3,ia)
541 : ! end do
542 : ! !Implement beta correction as in eq. 62 (PRB 96 075448 2017)
543 : ! gcart_para = sqrt(gcart(1)**2+gcart(2)**2)
544 : ! gcart_perp = gcart(3)
545 : ! gsquar = gcart(1)**2+gcart(2)**2+gcart(3)**2
546 : ! if(gcart_para .gt. tol12) then
547 : ! beta = gsquar*rcut_loc/(two*gcart_para)* &
548 : ! & exp(-gcart_para*rcut_loc)* &
549 : ! &cos(gcart_perp*rcut_loc)/(one-exp(-gcart_para*rcut_loc)*cos(gcart_perp*rcut_loc))
550 : ! else
551 : ! beta = zero
552 : ! end if
553 : !! Compute Re( rho^*(G)* sf ) * [(dV(G)/dG)/|G|]
554 : ! term=(rhog(re,ii)*sfr+rhog(im,ii)*sfi)*vion2
555 : !! Compute contribution to stress tensor
556 : ! lpsstr(1)=lpsstr(1)-term*(gcart(1)*gcart(1))*(1+beta)
557 : ! lpsstr(2)=lpsstr(2)-term*(gcart(2)*gcart(2))*(1+beta)
558 : ! lpsstr(3)=lpsstr(3)-term*(gcart(3)*gcart(3)-gsquar)
559 : ! lpsstr(4)=lpsstr(4)-term*gcart(3)*gcart(2)
560 : ! lpsstr(5)=lpsstr(5)-term*gcart(3)*gcart(1)
561 : ! lpsstr(6)=lpsstr(6)-term*gcart(2)*gcart(1)
562 : ! endif
563 :
564 : else
565 0 : write(message, '(a,i0,a)' )' mklocl: Option=',option,' not allowed.'
566 0 : ABI_BUG(message)
567 : end if ! End option choice
568 :
569 : ! End skip G**2 outside cutoff:
570 : end if
571 :
572 : ! End loop on n1, n2, n3. There is a "cycle" inside the loop
573 : end do
574 : end if ! this plane is for me_fft
575 : end do
576 : end do
577 :
578 : ! Symmetrize the dynamical matrix with respect to indices
579 123285 : do ia=ia1,ia2
580 79987 : dyfrlo(2,1,ia)=dyfrlo(1,2,ia)
581 79987 : dyfrlo(3,1,ia)=dyfrlo(1,3,ia)
582 123285 : dyfrlo(3,2,ia)=dyfrlo(2,3,ia)
583 : end do
584 :
585 72544 : ia1=ia2+1
586 :
587 : ! End loop on type of atoms
588 : end do
589 :
590 29246 : if(option==1)then
591 : ! Dont't change work1 on g=0 if Poisson solver is used since work1
592 : ! hold not the potential but the density generated by the pseudo.
593 6861 : if(me_g0 == 1) then
594 : ! Set Vloc(G=0)=0:
595 6757 : work1(re,1)=zero
596 6757 : work1(im,1)=zero
597 : end if
598 : ! write(std_out,*) ' mklocl_recipspace : will add potential with strength vprtrb(:)=',vprtrb(:)
599 :
600 : ! Allow for the addition of a perturbing potential
601 6861 : if ((vprtrb(1)**2+vprtrb(2)**2) > 1.d-30) then
602 : ! Find the linear indices which correspond with the input
603 : ! wavevector qprtrb
604 : ! The double modulus handles both i>=n and i<0, mapping into [0,n-1];
605 : ! then add 1 to get range [1,n] for each
606 8 : i3=1+mod(n3+mod(qprtrb(3),n3),n3)
607 8 : i2=1+mod(n2+mod(qprtrb(2),n2),n2)
608 8 : i1=1+mod(n1+mod(qprtrb(1),n1),n1)
609 : ! Compute the linear index in the 3 dimensional array
610 8 : ii=i1+n1*((ffti2_local(i2)-1)+(n2/nproc_fft)*(i3-1))
611 : ! Add in the perturbation at G=qprtrb
612 8 : work1(re,ii)=work1(re,ii)+0.5_dp*vprtrb(1)
613 8 : work1(im,ii)=work1(im,ii)+0.5_dp*vprtrb(2)
614 : ! Same thing for G=-qprtrb
615 8 : i3=1+mod(n3+mod(-qprtrb(3),n3),n3)
616 8 : i2=1+mod(n2+mod(-qprtrb(2),n2),n2)
617 8 : i1=1+mod(n1+mod(-qprtrb(1),n1),n1)
618 : ! ii=i1+n1*((i2-1)+n2*(i3-1))
619 8 : work1(re,ii)=work1(re,ii)+0.5_dp*vprtrb(1)
620 8 : work1(im,ii)=work1(im,ii)-0.5_dp*vprtrb(2)
621 : write(message, '(a,1p,2e12.4,a,0p,3i4,a)' )&
622 8 : & ' mklocl: perturbation of vprtrb=', vprtrb,&
623 16 : & ' and q=',qprtrb,' has been added'
624 8 : call wrtout(std_out,message,'COLL')
625 : end if
626 :
627 : ! Transform back to real space
628 6861 : call fourdp(1,work1,vpsp,1,mpi_enreg,nfft,1,ngfft,0)
629 :
630 : ! Divide by unit cell volume
631 6861 : xnorm=1.0_dp/ucvol
632 113718977 : vpsp(:)=vpsp(:)*xnorm
633 :
634 6861 : ABI_FREE(work1)
635 :
636 : end if
637 :
638 29246 : ABI_FREE(gcutoff)
639 :
640 29246 : if(option==2)then
641 : ! Init mpi_comm
642 17073 : if(mpi_enreg%nproc_fft>1)then
643 904 : call timab(48,1,tsec)
644 904 : call xmpi_sum(grtn,mpi_enreg%comm_fft ,ierr)
645 904 : call timab(48,2,tsec)
646 : end if
647 17073 : call timab(72,2,tsec)
648 : end if
649 :
650 29246 : if(option==3)then
651 : ! Init mpi_comm
652 4907 : if(mpi_enreg%nproc_fft>1)then
653 200 : call timab(48,1,tsec)
654 200 : call xmpi_sum(lpsstr,mpi_enreg%comm_fft ,ierr)
655 200 : call timab(48,2,tsec)
656 : end if
657 :
658 : ! Normalize and add term -eei/ucvol on diagonal
659 : ! (see page 802 of notes)
660 : ! if(icutcoul .ne. 2) then
661 4907 : lpsstr(1)=(lpsstr(1)-eei)/ucvol
662 4907 : lpsstr(2)=(lpsstr(2)-eei)/ucvol
663 4907 : lpsstr(3)=(lpsstr(3)-eei)/ucvol
664 4907 : lpsstr(4)=lpsstr(4)/ucvol
665 4907 : lpsstr(5)=lpsstr(5)/ucvol
666 4907 : lpsstr(6)=lpsstr(6)/ucvol
667 : ! elseif (icutcoul .eq. 2) then
668 : ! lpsstr(1)=(lpsstr(1)-eei)/ucvol
669 : ! lpsstr(2)=(lpsstr(2)-eei)/ucvol
670 : ! lpsstr(3)=(lpsstr(3)-eei)/ucvol
671 : ! lpsstr(4)=lpsstr(4)/ucvol
672 : ! lpsstr(5)=lpsstr(5)/ucvol
673 : ! lpsstr(6)=lpsstr(6)/ucvol
674 : !lpsstr=lpsstr/ucvol
675 : ! endif
676 :
677 : end if
678 :
679 58897 : if(option==4)then
680 : ! Init mpi_comm
681 405 : if(mpi_enreg%nproc_fft>1)then
682 0 : call timab(48,1,tsec)
683 0 : call xmpi_sum(dyfrlo,mpi_enreg%comm_fft ,ierr)
684 0 : call timab(48,2,tsec)
685 : end if
686 : end if
687 :
688 : contains
689 :
690 : !Real and imaginary parts of phase--statment functions:
691 243911014 : function phr_mk(x1,y1,x2,y2,x3,y3)
692 :
693 : real(dp) :: phr_mk,x1,x2,x3,y1,y2,y3
694 243911014 : phr_mk=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
695 : end function phr_mk
696 :
697 243911014 : function phi_mk(x1,y1,x2,y2,x3,y3)
698 :
699 : real(dp):: phi_mk,x1,x2,x3,y1,y2,y3
700 243911014 : phi_mk=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
701 : end function phi_mk
702 :
703 975644056 : function ph1_mk(nri,ig1,ia)
704 :
705 : real(dp):: ph1_mk
706 : integer :: nri,ig1,ia
707 975644056 : ph1_mk=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1))
708 975644056 : end function ph1_mk
709 :
710 975644056 : function ph2_mk(nri,ig2,ia)
711 :
712 : real(dp):: ph2_mk
713 : integer :: nri,ig2,ia
714 975644056 : ph2_mk=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1))
715 975644056 : end function ph2_mk
716 :
717 975644056 : function ph3_mk(nri,ig3,ia)
718 :
719 : real(dp):: ph3_mk
720 : integer :: nri,ig3,ia
721 975644056 : ph3_mk=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
722 975644056 : end function ph3_mk
723 :
724 243911014 : function phre_mk(ig1,ig2,ig3,ia)
725 :
726 : real(dp):: phre_mk
727 : integer :: ig1,ig2,ig3,ia
728 : phre_mk=phr_mk(ph1_mk(re,ig1,ia),ph1_mk(im,ig1,ia),&
729 243911014 : & ph2_mk(re,ig2,ia),ph2_mk(im,ig2,ia),ph3_mk(re,ig3,ia),ph3_mk(im,ig3,ia))
730 243911014 : end function phre_mk
731 :
732 243911014 : function phimag_mk(ig1,ig2,ig3,ia)
733 :
734 : real(dp) :: phimag_mk
735 : integer :: ig1,ig2,ig3,ia
736 : phimag_mk=phi_mk(ph1_mk(re,ig1,ia),ph1_mk(im,ig1,ia),&
737 243911014 : & ph2_mk(re,ig2,ia),ph2_mk(im,ig2,ia),ph3_mk(re,ig3,ia),ph3_mk(im,ig3,ia))
738 243911014 : end function phimag_mk
739 :
740 618368130 : function gsq_mk(i1,i2,i3)
741 :
742 : real(dp) :: gsq_mk
743 : integer :: i1,i2,i3
744 : gsq_mk=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
745 : & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
746 618368130 : & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
747 618368130 : end function gsq_mk
748 :
749 : end subroutine mklocl_recipspace
750 : !!***
751 :
752 : !!****f* ABINIT/dfpt_vlocal
753 : !! NAME
754 : !! dfpt_vlocal
755 : !!
756 : !! FUNCTION
757 : !! Compute local part of 1st-order potential from the appropriate
758 : !! atomic pseudopotential with structure and derivative factor.
759 : !! In case of derivative with respect to k or
760 : !! electric (magnetic Zeeman) field perturbation, the 1st-order local potential vanishes.
761 : !!
762 : !! INPUTS
763 : !! atindx(natom)=index table for atoms (see gstate.f)
764 : !! cplex: if 1, real space 1-order functions on FFT grid
765 : !! are REAL, if 2, COMPLEX
766 : !! gmet(3,3)=reciprocal space metric (Bohr**-2)
767 : !! gsqcut=cutoff G**2 for included G s in fft box.
768 : !! icutcoul= type of Coulomb cutoff to apply
769 : !! idir=direction of atomic displacement (=1,2 or 3 : displacement of
770 : !! atom ipert along the 1st, 2nd or 3rd axis).
771 : !! ipert=number of the atom being displaced in the frozen-phonon
772 : !! mpi_enreg=information about MPI parallelization
773 : !! mqgrid=dimension of q grid for pseudopotentials
774 : !! natom=number of atoms in cell.
775 : !! nattyp(ntypat)=number of atoms of each type in cell.
776 : !! nfft=(effective) number of FFT grid points (for this processor)
777 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
778 : !! ntypat=number of types of atoms in cell.
779 : !! n1,n2,n3=fft grid.
780 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
781 : !! qgrid(mqgrid)=grid of q points from 0 to qmax.
782 : !! qphon(3)=wavevector of the phonon
783 : !! rprimd(3,3)=dimensional primitive translations in real space (bohr)
784 : !! ucvol=unit cell volume (Bohr**3).
785 : !! vcutgeo(3)= array to describe the geometry of the Coulomb cutoff
786 : !! vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
787 : !! xred(3,natom)=reduced atomic coordinates
788 : !!
789 : !! OUTPUT
790 : !! vpsp1(cplex*nfft)=first-order local crystal pseudopotential in real space
791 : !! (including the minus sign, forgotten in the paper non-linear..
792 : !!
793 : !! SOURCE
794 :
795 11870 : subroutine dfpt_vlocal(atindx,cplex,gmet,gsqcut,icutcoul,idir,ipert,&
796 11870 : & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,nkpt,&
797 11870 : & ntypat,n1,n2,n3,ph1d,qgrid,qphon,rcut,rprimd,ucvol,vcutgeo,vlspl,vpsp1,xred,&
798 : & zion) !Optional
799 :
800 : !Arguments -------------------------------
801 : !scalars
802 : integer,intent(in) :: cplex,icutcoul,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,nkpt,ntypat
803 : real(dp),intent(in) :: gsqcut,rcut,ucvol
804 : type(MPI_type),intent(in) :: mpi_enreg
805 : !arrays
806 : integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18)
807 : real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom)
808 : real(dp),intent(in) :: qgrid(mqgrid),qphon(3),rprimd(3,3),vcutgeo(3),vlspl(mqgrid,2,ntypat)
809 : real(dp),intent(in) :: xred(3,natom)
810 : real(dp),intent(in),optional :: zion(ntypat)
811 : real(dp),intent(out) :: vpsp1(cplex*nfft)
812 :
813 : !Local variables -------------------------
814 : !scalars
815 : integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1,im=2
816 : integer :: itypat,jj,re=1
817 : real(dp),parameter :: tolfix=1.000000001_dp
818 : real(dp) :: aa,bb,cc,cutoff,dd,diff,dq,dq2div6,dqdiv6,dqm1,facg0,gmag,gq1
819 : real(dp) :: gq2,gq3,gsquar,phqim,phqre
820 : real(dp) :: qxred2pi,sfi,sfr,vion1,xnorm
821 : logical :: qeq0
822 : !arrays
823 11870 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
824 11870 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
825 : real(dp) :: gq(3)
826 11870 : real(dp),allocatable :: gcutoff(:)
827 11870 : real(dp),allocatable :: work1(:,:)
828 : ! *********************************************************************
829 :
830 11870 : iatom=ipert
831 :
832 : if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 &
833 23740 : & .or. iatom==natom+5 .or. iatom==natom+6 .or. iatom==natom+6 .or. (iatom>natom+11.and.iatom<=2*natom+11))then
834 :
835 : ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb )
836 4537224 : vpsp1(1:cplex*nfft)=zero
837 :
838 : else
839 :
840 : ! (In case of a phonon perturbation)
841 33681 : ABI_MALLOC(work1,(2,nfft))
842 350520388 : work1(1:2,1:nfft)=0.0_dp
843 :
844 11227 : dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1)
845 11227 : dqm1=1.0_dp/dq
846 11227 : dqdiv6=dq/6.0_dp
847 11227 : dq2div6=dq**2/6.0_dp
848 11227 : cutoff=gsqcut*tolfix
849 11227 : id1=n1/2+2
850 11227 : id2=n2/2+2
851 11227 : id3=n3/2+2
852 :
853 : ! Get the distrib associated with this fft_grid
854 11227 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
855 :
856 : ! This is to allow q=0
857 11227 : qeq0=.false.
858 11227 : if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15)qeq0=.true.
859 :
860 : ! Determination of the atom type
861 11227 : ia1=0
862 11227 : itypat=0
863 27447 : do ii=1,ntypat
864 16220 : ia1=ia1+nattyp(ii)
865 32440 : if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii
866 : end do
867 :
868 : ! Determination of phase qxred*
869 : qxred2pi=2.0_dp*pi*(qphon(1)*xred(1,iatom)+ &
870 : & qphon(2)*xred(2,iatom)+ &
871 11227 : & qphon(3)*xred(3,iatom) )
872 11227 : phqre=cos(qxred2pi)
873 11227 : phqim=sin(qxred2pi)
874 11227 : ii=0
875 :
876 : ! Initialize Gcut-off array from m_gtermcutoff
877 11227 : call termcutoff(gcutoff,gsqcut,icutcoul,ngfft,nkpt,rcut,rprimd,vcutgeo,qpt=qphon)
878 :
879 228538 : do i3=1,n3
880 217311 : ig3=i3-(i3/id3)*n3-1
881 217311 : gq3=dble(ig3)+qphon(3)
882 217311 : gq(3)=gq3
883 4639861 : do i2=1,n2
884 4628634 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
885 4411323 : ig2=i2-(i2/id2)*n2-1
886 4411323 : gq2=dble(ig2)+qphon(2)
887 4411323 : gq(2)=gq2
888 :
889 : ! Note the lower limit of the next loop
890 4411323 : ii1=1
891 4411323 : facg0=zero
892 4411323 : if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then
893 6696 : ii1=2
894 6696 : ii=ii+1
895 : end if
896 4411323 : if(i3==1 .and. i2==1 .and. (.not.qeq0) .and. icutcoul==55 .and. ig2==0 .and. ig3==0)then
897 36 : facg0 = four_pi * zion(itypat) / (two_pi)**2
898 : end if
899 121241014 : do i1=ii1,n1
900 116829691 : ig1=i1-(i1/id1)*n1-1
901 116829691 : gq1=dble(ig1)+qphon(1)
902 116829691 : gq(1)=gq1
903 116829691 : ii=ii+1
904 116829691 : gsquar=gsq_vl3(gq1,gq2,gq3)
905 : ! Skip G**2 outside cutoff:
906 121241014 : if (gsquar<=cutoff) then
907 41986670 : gmag=sqrt(gsquar)
908 :
909 : ! Compute vion(G) for given type of atom
910 41986670 : jj=1+int(gmag*dqm1)
911 41986670 : diff=gmag-qgrid(jj)
912 :
913 : ! Evaluate spline fit from q^2 V(q) to get V(q):
914 : ! (p. 86 Numerical Recipes, Press et al; NOTE error in book for sign
915 : ! of "aa" term in derivative; also see splfit routine.
916 : ! This bug fixed here 27 Jan 1992.)
917 :
918 41986670 : bb = diff*dqm1
919 41986670 : aa = 1.0_dp-bb
920 41986670 : cc = aa*(aa**2-1.0_dp)*dq2div6
921 41986670 : dd = bb*(bb**2-1.0_dp)*dq2div6
922 : vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) + &
923 : & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) + facg0 ) &
924 41986670 : & / gsquar*gcutoff(ii)
925 :
926 : ! Phase G*xred (complex conjugate) * -i *2pi*(g+q)*vion
927 41986670 : sfr=-phimag_vl3(ig1,ig2,ig3,iatom)*2.0_dp*pi*gq(idir)*vion1
928 41986670 : sfi=-phre_vl3(ig1,ig2,ig3,iatom)*2.0_dp*pi*gq(idir)*vion1
929 :
930 : ! Phase q*xred (complex conjugate)
931 41986670 : work1(re,ii)=sfr*phqre+sfi*phqim
932 41986670 : work1(im,ii)=-sfr*phqim+sfi*phqre
933 :
934 41986670 : facg0=zero
935 : end if
936 :
937 : end do
938 : end if
939 : end do
940 : end do
941 :
942 : ! Transform back to real space
943 11227 : call fourdp(cplex,work1,vpsp1,1,mpi_enreg,nfft,1,ngfft,0)
944 :
945 11227 : xnorm=1.0_dp/ucvol
946 150557733 : vpsp1(1:cplex*nfft)=vpsp1(1:cplex*nfft)*xnorm
947 :
948 11227 : ABI_FREE(work1)
949 11227 : ABI_FREE(gcutoff)
950 :
951 : ! End the condition of non-electric-field
952 : end if
953 :
954 : contains
955 :
956 : !Real and imaginary parts of phase.
957 41986670 : function phr_vl3(x1,y1,x2,y2,x3,y3)
958 :
959 : real(dp) :: phr_vl3
960 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
961 41986670 : phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
962 : end function phr_vl3
963 :
964 41986670 : function phi_vl3(x1,y1,x2,y2,x3,y3)
965 :
966 : real(dp) :: phi_vl3
967 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
968 41986670 : phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
969 : end function phi_vl3
970 :
971 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
972 167946680 : function ph1_vl3(nri,ig1,ia)
973 :
974 : real(dp) :: ph1_vl3
975 : integer,intent(in) :: nri,ig1,ia
976 167946680 : ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1))
977 167946680 : end function ph1_vl3
978 :
979 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
980 167946680 : function ph2_vl3(nri,ig2,ia)
981 :
982 : real(dp) :: ph2_vl3
983 : integer,intent(in) :: nri,ig2,ia
984 167946680 : ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1))
985 167946680 : end function ph2_vl3
986 :
987 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
988 167946680 : function ph3_vl3(nri,ig3,ia)
989 :
990 : real(dp) :: ph3_vl3
991 : integer,intent(in) :: nri,ig3,ia
992 167946680 : ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
993 167946680 : end function ph3_vl3
994 :
995 41986670 : function phre_vl3(ig1,ig2,ig3,ia)
996 :
997 : real(dp) :: phre_vl3
998 : integer,intent(in) :: ig1,ig2,ig3,ia
999 : phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1000 41986670 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1001 41986670 : end function phre_vl3
1002 :
1003 41986670 : function phimag_vl3(ig1,ig2,ig3,ia)
1004 :
1005 : real(dp) :: phimag_vl3
1006 : integer,intent(in) :: ig1,ig2,ig3,ia
1007 : phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1008 41986670 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1009 41986670 : end function phimag_vl3
1010 :
1011 116829691 : function gsq_vl3(g1,g2,g3)
1012 :
1013 : real(dp) :: gsq_vl3
1014 : real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions
1015 : !Define G^2 based on G space metric gmet.
1016 : gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+&
1017 : & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+&
1018 116829691 : & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1)
1019 116829691 : end function gsq_vl3
1020 :
1021 : end subroutine dfpt_vlocal
1022 : !!***
1023 :
1024 : !!****f* ABINIT/vlocalstr
1025 : !! NAME
1026 : !! vlocalstr
1027 : !!
1028 : !! FUNCTION
1029 : !! Compute strain derivatives of local ionic potential
1030 : !! second derivative of E wrt xred
1031 : !!
1032 : !! INPUTS
1033 : !! gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$).
1034 : !! gprimd(3,3)=reciprocal space dimensional primitive translations
1035 : !! gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere).
1036 : !! istr=1,...6 specifies cartesian strain component 11,22,33,32,31,21
1037 : !! mgfft=maximum size of 1D FFTs
1038 : !! mpi_enreg=information about MPI parallelization
1039 : !! mqgrid=number of grid pts in q array for f(q) spline.
1040 : !! natom=number of atoms in unit cell.
1041 : !! nattyp(ntypat)=number of atoms of each type in cell.
1042 : !! nfft=(effective) number of FFT grid points (for this processor)
1043 : !! ngfft(18)=contain all needed information about 3D FFT,
1044 : !! see ~abinit/doc/variables/vargs.htm#ngfft
1045 : !! ntypat=number of types of atoms.
1046 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
1047 : !! qgrid(mqgrid)=q grid for spline from 0 to qmax.
1048 : !! ucvol=unit cell volume ($\textrm{Bohr}^3$).
1049 : !! vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom.
1050 : !! [g0term]= optional, if present an alternative treatment of the G=0 term,
1051 : !! adopoted for the flexoelectric tensor calculation, is performed.
1052 : !!
1053 : !! OUTPUT
1054 : !! vpsp1(nfft)=first-order local crystal pseudopotential in real space.
1055 : !!
1056 : !! NOTES
1057 : !! * Note that the present routine is tightly connected to the dfpt_vlocal.f routine,
1058 : !! that compute the derivative of the local ionic potential
1059 : !! with respect to one atomic displacement. The argument list
1060 : !! and the internal loops to be considered were sufficiently different
1061 : !! as to make the two routines different.
1062 : !! * The routine was adapted from mklocl.F90
1063 : !!
1064 : !! SOURCE
1065 :
1066 672 : subroutine vlocalstr(gmet,gprimd,gsqcut,istr,mgfft,mpi_enreg,&
1067 672 : & mqgrid,natom,nattyp,nfft,ngfft,ntypat,ph1d,qgrid,&
1068 672 : & ucvol,vlspl,vpsp1,g0term)
1069 :
1070 : !Arguments ------------------------------------
1071 : !scalars
1072 : integer,intent(in) :: istr,mgfft,mqgrid,natom,nfft,ntypat
1073 : integer,optional,intent(in) :: g0term
1074 : real(dp),intent(in) :: gsqcut,ucvol
1075 : type(MPI_type),intent(in) :: mpi_enreg
1076 : !arrays
1077 : integer,intent(in) :: nattyp(ntypat),ngfft(18)
1078 : real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom)
1079 : real(dp),intent(in) :: qgrid(mqgrid),vlspl(mqgrid,2,ntypat)
1080 : real(dp),intent(out) :: vpsp1(nfft)
1081 :
1082 : !Local variables-------------------------------
1083 : !scalars
1084 : integer,parameter :: im=2,re=1
1085 : integer :: g0term_
1086 : integer :: i1,i2,i3,ia,ia1,ia2,id1,id2,id3,ig1,ig2,ig3,ii,itypat,jj
1087 : integer :: ka,kb,n1,n2,n3
1088 : real(dp),parameter :: tolfix=1.0000001_dp
1089 : real(dp) :: aa,bb,cc,cutoff,dd,dgsquards,diff
1090 : real(dp) :: dq,dq2div6,dqdiv6,dqm1,ee,ff,gmag,gsquar
1091 : real(dp) :: sfi,sfr,term,vion1,vion2,vlocg0
1092 : real(dp) :: xnorm
1093 : character(len=500) :: message
1094 : !arrays
1095 : integer,save :: idx(12)=(/1,1,2,2,3,3,3,2,3,1,2,1/)
1096 672 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
1097 672 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
1098 : real(dp) :: dgmetds(3,3)
1099 672 : real(dp),allocatable :: work1(:,:)
1100 : ! *************************************************************************
1101 :
1102 : !Define G^2 based on G space metric gmet.
1103 : ! gsq_vl(i1,i2,i3)=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
1104 : !& dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
1105 : !& dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
1106 :
1107 : !Define dG^2/ds based on G space metric derivative dgmetds.
1108 : ! dgsqds_vl(i1,i2,i3)=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+&
1109 : !& dble(i3*i3)*dgmetds(3,3)+&
1110 : !& dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+&
1111 : !& dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+&
1112 : !& dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2))
1113 :
1114 : !Real and imaginary parts of phase--statment functions:
1115 : ! phr_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
1116 : ! phi_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
1117 : ! ph1_vl(nri,i1,ia)=ph1d(nri,i1+1+n1+(ia-1)*(2*n1+1))
1118 : ! ph2_vl(nri,i2,ia)=ph1d(nri,i2+1+n2+(ia-1)*(2*n2+1)+&
1119 : !& natom*(2*n1+1))
1120 : ! ph3_vl(nri,i3,ia)=ph1d(nri,i3+1+n3+(ia-1)*(2*n3+1)+&
1121 : !& natom*(2*n1+1+2*n2+1))
1122 : ! phre_vl(i1,i2,i3,ia)=phr_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),&
1123 : !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia))
1124 : ! phimag_vl(i1,i2,i3,ia)=phi_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),&
1125 : !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia))
1126 :
1127 : !-----
1128 : !Compute derivative of metric tensor wrt strain component istr
1129 672 : if(istr<1 .or. istr>6)then
1130 : write(message, '(a,i10,a,a,a)' )&
1131 0 : & ' Input istr=',istr,' not allowed.',ch10,&
1132 0 : & ' Possible values are 1,2,3,4,5,6 only.'
1133 0 : ABI_BUG(message)
1134 : end if
1135 :
1136 672 : ka=idx(2*istr-1);kb=idx(2*istr)
1137 2688 : do ii = 1,3
1138 8736 : dgmetds(:,ii)=-(gprimd(ka,:)*gprimd(kb,ii)+gprimd(kb,:)*gprimd(ka,ii))
1139 : end do
1140 : !For historical reasons:
1141 8736 : dgmetds(:,:)=0.5_dp*dgmetds(:,:)
1142 :
1143 672 : n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
1144 :
1145 : !Get the distrib associated with this fft_grid
1146 672 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
1147 :
1148 : !Zero out array to permit accumulation over atom types below:
1149 2016 : ABI_MALLOC(work1,(2,nfft))
1150 8074584 : work1(:,:)=0.0_dp
1151 : !
1152 672 : dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1)
1153 672 : dqm1=1.0_dp/dq
1154 672 : dqdiv6=dq/6.0_dp
1155 672 : dq2div6=dq**2/6.0_dp
1156 672 : cutoff=gsqcut*tolfix
1157 672 : id1=n1/2+2
1158 672 : id2=n2/2+2
1159 672 : id3=n3/2+2
1160 :
1161 672 : ia1=1
1162 1757 : do itypat=1,ntypat
1163 : ! ia1,ia2 sets range of loop over atoms:
1164 1085 : ia2=ia1+nattyp(itypat)-1
1165 :
1166 1085 : ii=0
1167 19859 : do i3=1,n3
1168 18774 : ig3=i3-(i3/id3)*n3-1
1169 303415 : do i2=1,n2
1170 302330 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
1171 283556 : ig2=i2-(i2/id2)*n2-1
1172 4723124 : do i1=1,n1
1173 4439568 : ig1=i1-(i1/id1)*n1-1
1174 4439568 : ii=ii+1
1175 : ! *** GET RID OF THIS THESE IF STATEMENTS (if they slow code)
1176 : ! Skip G=0:
1177 : ! if (ii==1) cycle
1178 4439568 : if (ig1==0 .and. ig2==0 .and. ig3==0) cycle
1179 4438483 : gsquar=gsq_vl(ig1,ig2,ig3)
1180 :
1181 : ! Skip G**2 outside cutoff:
1182 4722039 : if (gsquar<=cutoff) then
1183 1420174 : gmag=sqrt(gsquar)
1184 1420174 : dgsquards=dgsqds_vl(ig1,ig2,ig3)
1185 : ! Compute vion(G) for given type of atom
1186 1420174 : jj=1+int(gmag*dqm1)
1187 1420174 : diff=gmag-qgrid(jj)
1188 :
1189 : ! Evaluate spline fit from q^2 V(q) to get V(q):
1190 : ! (p. 86 Numerical Recipes, Press et al;
1191 : ! NOTE error in book for sign
1192 : ! of "aa" term in derivative; also see splfit routine).
1193 :
1194 1420174 : bb = diff*dqm1
1195 1420174 : aa = 1.0_dp-bb
1196 1420174 : cc = aa*(aa**2-1.0_dp)*dq2div6
1197 1420174 : dd = bb*(bb**2-1.0_dp)*dq2div6
1198 :
1199 : vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) +&
1200 : & cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) &
1201 1420174 : & / gsquar
1202 :
1203 : ! Also get (dV(q)/dq)/q:
1204 : ! (note correction of Numerical Recipes sign error
1205 : ! before (3._dp*aa**2-1._dp)
1206 1420174 : ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat)
1207 : ff= (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) &
1208 1420174 : & - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat)
1209 : vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag&
1210 1420174 : & - 2.0_dp*vion1 ) / gsquar
1211 :
1212 :
1213 : ! Assemble structure factor over all atoms of given type:
1214 1420174 : sfr=0.0_dp
1215 1420174 : sfi=0.0_dp
1216 3609368 : do ia=ia1,ia2
1217 2189194 : sfr=sfr+phre_vl(ig1,ig2,ig3,ia)
1218 3609368 : sfi=sfi-phimag_vl(ig1,ig2,ig3,ia)
1219 : end do
1220 :
1221 1420174 : term=dgsquards*vion2
1222 : ! Add potential for diagonal strain components
1223 1420174 : if(istr <=3) then
1224 718770 : term=term-vion1
1225 : end if
1226 :
1227 : ! Multiply structure factor times vion derivatives:
1228 1420174 : work1(re,ii)=work1(re,ii)+sfr*term
1229 1420174 : work1(im,ii)=work1(im,ii)+sfi*term
1230 :
1231 : ! End skip G**2 outside cutoff:
1232 : end if
1233 : ! End loop on n1, n2, n3. There is a "cycle" inside the loop
1234 : end do
1235 : end if
1236 : end do
1237 : end do
1238 :
1239 1757 : ia1=ia2+1
1240 :
1241 : ! End loop on type of atoms
1242 : end do
1243 :
1244 :
1245 : !Set Vloc(G=0)=0:
1246 672 : work1(re,1)=0.0_dp
1247 672 : work1(im,1)=0.0_dp
1248 :
1249 : !Alternative treatment of Vloc(G=0) for the flexoelectric tensor calculation
1250 672 : g0term_=0; if (present(g0term)) g0term_=g0term
1251 672 : if (g0term_==1) then
1252 126 : vlocg0=zero
1253 126 : if (istr<=3) then
1254 126 : ia1=1
1255 126 : do itypat=1,ntypat
1256 : ! ia1,ia2 sets range of loop over atoms:
1257 :
1258 63 : ia2=ia1+nattyp(itypat)-1
1259 252 : do ia=ia1,ia2
1260 189 : vlocg0=vlocg0+vlspl(1,2,itypat)
1261 : end do
1262 : end do
1263 63 : work1(re,1)=-half*vlocg0
1264 : end if
1265 : end if
1266 :
1267 : !Transform back to real space
1268 672 : call fourdp(1,work1,vpsp1,1,mpi_enreg,nfft,1,ngfft,0)
1269 :
1270 : !Divide by unit cell volume
1271 672 : xnorm=1.0_dp/ucvol
1272 2691976 : vpsp1(:)=vpsp1(:)*xnorm
1273 :
1274 672 : ABI_FREE(work1)
1275 :
1276 : contains
1277 :
1278 : !Real and imaginary parts of phase.
1279 2189194 : function phr_vl(x1,y1,x2,y2,x3,y3)
1280 :
1281 : real(dp) :: phr_vl,x1,x2,x3,y1,y2,y3
1282 2189194 : phr_vl=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
1283 : end function phr_vl
1284 :
1285 2189194 : function phi_vl(x1,y1,x2,y2,x3,y3)
1286 :
1287 : real(dp):: phi_vl,x1,x2,x3,y1,y2,y3
1288 2189194 : phi_vl=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
1289 : end function phi_vl
1290 :
1291 8756776 : function ph1_vl(nri,ig1,ia)
1292 :
1293 : real(dp):: ph1_vl
1294 : integer :: nri,ig1,ia
1295 8756776 : ph1_vl=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1))
1296 8756776 : end function ph1_vl
1297 :
1298 8756776 : function ph2_vl(nri,ig2,ia)
1299 :
1300 : real(dp):: ph2_vl
1301 : integer :: nri,ig2,ia
1302 8756776 : ph2_vl=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1))
1303 8756776 : end function ph2_vl
1304 :
1305 8756776 : function ph3_vl(nri,ig3,ia)
1306 :
1307 : real(dp):: ph3_vl
1308 : integer :: nri,ig3,ia
1309 8756776 : ph3_vl=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
1310 8756776 : end function ph3_vl
1311 :
1312 2189194 : function phre_vl(ig1,ig2,ig3,ia)
1313 :
1314 : real(dp):: phre_vl
1315 : integer :: ig1,ig2,ig3,ia
1316 : phre_vl=phr_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
1317 2189194 : & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
1318 2189194 : end function phre_vl
1319 :
1320 2189194 : function phimag_vl(ig1,ig2,ig3,ia)
1321 :
1322 : real(dp) :: phimag_vl
1323 : integer :: ig1,ig2,ig3,ia
1324 : phimag_vl=phi_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
1325 2189194 : & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
1326 2189194 : end function phimag_vl
1327 :
1328 4438483 : function gsq_vl(i1,i2,i3)
1329 :
1330 : real(dp) :: gsq_vl
1331 : integer :: i1,i2,i3
1332 : !Define G^2 based on G space metric gmet.
1333 : gsq_vl=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
1334 : & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
1335 4438483 : & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
1336 4438483 : end function gsq_vl
1337 :
1338 1420174 : function dgsqds_vl(i1,i2,i3)
1339 :
1340 : real(dp) :: dgsqds_vl
1341 : integer :: i1,i2,i3
1342 : !Define dG^2/ds based on G space metric derivative dgmetds.
1343 : dgsqds_vl=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+&
1344 : & dble(i3*i3)*dgmetds(3,3)+&
1345 : & dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+&
1346 : & dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+&
1347 1420174 : & dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2))
1348 1420174 : end function dgsqds_vl
1349 :
1350 : end subroutine vlocalstr
1351 : !!***
1352 :
1353 : !!****f* ABINIT/dfpt_vlocaldq
1354 : !! NAME
1355 : !! dfpt_vlocaldq
1356 : !!
1357 : !! FUNCTION
1358 : !! Compute q-gradient (at q=0) of the local part of 1st-order
1359 : !! atomic displacement local potential or pseudocore density from the appropriate
1360 : !! atomic pseudopotential data with structure and derivative factor.
1361 : !!
1362 : !! INPUTS
1363 : !! atindx(natom)=index table for atoms (see gstate.f)
1364 : !! cplex: if 1, real space 1-order functions on FFT grid
1365 : !! are REAL, if 2, COMPLEX
1366 : !! gmet(3,3)=reciprocal space metric (Bohr**-2)
1367 : !! gsqcut=cutoff G**2 for included G s in fft box.
1368 : !! idir=direction of atomic displacement (=1,2 or 3 : displacement of
1369 : !! atom ipert along the 1st, 2nd or 3rd axis).
1370 : !! ipert=number of the atom being displaced in the frozen-phonon
1371 : !! mpi_enreg=information about MPI parallelization
1372 : !! mqgrid=dimension of q grid for pseudopotentials
1373 : !! natom=number of atoms in cell.
1374 : !! nattyp(ntypat)=number of atoms of each type in cell.
1375 : !! nfft=(effective) number of FFT grid points (for this processor)
1376 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft
1377 : !! ntypat=number of types of atoms in cell.
1378 : !! n1,n2,n3=fft grid.
1379 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
1380 : !! qdir=direction of the q-gradient
1381 : !! qgrid(mqgrid)=grid of q points from 0 to qmax.
1382 : !! qphon(3)=wavevector of the phonon
1383 : !! ucvol=unit cell volume (Bohr**3).
1384 : !! vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
1385 : !! if optnc=1-> spline fit of n_c(q) for each type of atom.
1386 : !! optnc= (OPTIONAL) if present and equal to 1, does the calculation assuming a
1387 : !! pseudocore density
1388 : !!
1389 : !! OUTPUT
1390 : !! vpsp1dq(cplex*nfft)=q-gradient (at q=0) of the first-order local
1391 : !! crystal pseudopotential in real space
1392 : !! (including the minus sign, forgotten in the paper non-linear..
1393 : !!
1394 : !! NOTES
1395 : !! * IMPORTANT: the formalism followed in this routine
1396 : !! assumes a phase factor for the perturbation that
1397 : !! is different to the one used elsewhere in the code (See M.Stengel paper):
1398 : !!
1399 : !! here: e^{i q (R_l + \tau_{\kappa})}
1400 : !! rest of ABINIT: e^{i q R_l}
1401 : !!
1402 : !! **A -i factor has been factorized out in all the contributions of the first
1403 : !! q-gradient of the atomic displacement Hamiltonian. This is lately included
1404 : !! in the matrix element calculation.
1405 : !!
1406 : !! SOURCE
1407 :
1408 799 : subroutine dfpt_vlocaldq(atindx,cplex,gmet,gsqcut,idir,ipert,&
1409 799 : & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,&
1410 799 : & ntypat,n1,n2,n3,ph1d,qdir,qgrid,qphon,ucvol,vlspl,vpsp1dq,&
1411 : & optnc) !optional
1412 :
1413 : !Arguments -------------------------------
1414 : !scalars
1415 : integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,ntypat
1416 : integer,intent(in) :: qdir
1417 : integer,optional,intent(in) :: optnc
1418 : real(dp),intent(in) :: gsqcut,ucvol
1419 : type(MPI_type),intent(in) :: mpi_enreg
1420 : !arrays
1421 : integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18)
1422 : real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom)
1423 : real(dp),intent(in) :: qgrid(mqgrid),qphon(3),vlspl(mqgrid,2,ntypat)
1424 : real(dp),intent(out) :: vpsp1dq(cplex*nfft)
1425 :
1426 : !Local variables -------------------------
1427 : !scalars
1428 : integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1
1429 : integer :: itypat, optnc_
1430 : integer, parameter :: im=2, re=1
1431 : real(dp),parameter :: tolfix=1.000000001_dp
1432 : real(dp) :: cutoff,gfact,gmag,gq1
1433 : real(dp) :: gq2,gq3,gsquar
1434 : real(dp) :: sfi,sfr,xnorm
1435 : logical :: qeq0
1436 : character(len=500) :: msg
1437 : !arrays
1438 799 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
1439 799 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
1440 : real(dp) :: gq(3),gvec(3),vion1(1),vion1dq(1)
1441 799 : real(dp),allocatable :: work1(:,:)
1442 : ! *********************************************************************
1443 :
1444 799 : iatom=ipert
1445 :
1446 27 : optnc_=0; if (present(optnc)) optnc_=optnc
1447 : if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 &
1448 826 : & .or. iatom==natom+5 .or. iatom==natom+6 .or. (iatom>natom+11.and.iatom<=2*natom+11))then
1449 :
1450 : ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb )
1451 0 : vpsp1dq(1:cplex*nfft)=zero
1452 :
1453 : else
1454 :
1455 : ! (In case of a phonon perturbation)
1456 2397 : ABI_MALLOC(work1,(2,nfft))
1457 10394170 : work1(1:2,1:nfft)=0.0_dp
1458 :
1459 799 : cutoff=gsqcut*tolfix
1460 799 : id1=n1/2+2
1461 799 : id2=n2/2+2
1462 799 : id3=n3/2+2
1463 :
1464 : ! Get the distrib associated with this fft_grid
1465 799 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
1466 :
1467 : ! This is to allow q=0
1468 799 : qeq0=.false.
1469 799 : if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then
1470 : qeq0=.true.
1471 : else
1472 0 : msg='This routine cannot be used for q/=0'
1473 0 : ABI_BUG(msg)
1474 : end if
1475 :
1476 : ! Determination of the atom type
1477 799 : ia1=0
1478 799 : itypat=0
1479 1728 : do ii=1,ntypat
1480 929 : ia1=ia1+nattyp(ii)
1481 1858 : if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii
1482 : end do
1483 :
1484 : ii=0
1485 :
1486 13216 : do i3=1,n3
1487 12417 : ig3=i3-(i3/id3)*n3-1
1488 12417 : gq3=dble(ig3)+qphon(3)
1489 12417 : gq(3)=gq3
1490 213223 : do i2=1,n2
1491 212424 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
1492 200007 : ig2=i2-(i2/id2)*n2-1
1493 200007 : gq2=dble(ig2)+qphon(2)
1494 200007 : gq(2)=gq2
1495 :
1496 : ! Note the lower limit of the next loop
1497 200007 : ii1=1
1498 200007 : if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then
1499 799 : ii1=2
1500 799 : ii=ii+1
1501 : end if
1502 3663665 : do i1=ii1,n1
1503 3463658 : ig1=i1-(i1/id1)*n1-1
1504 3463658 : gq1=dble(ig1)+qphon(1)
1505 3463658 : gq(1)=gq1
1506 3463658 : ii=ii+1
1507 3463658 : gsquar=gsq_vl3(gq1,gq2,gq3)
1508 : ! Skip G**2 outside cutoff:
1509 3663665 : if (gsquar<=cutoff) then
1510 958320 : gmag=sqrt(gsquar)
1511 :
1512 : ! Evaluate spline fit to get V(q) and V(q)':
1513 1916640 : call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1)
1514 :
1515 958320 : if (optnc_==0) then
1516 1814616 : vion1=vion1/gsquar
1517 1814616 : vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar
1518 : end if
1519 :
1520 3833280 : gvec=(/ig1,ig2,ig3/)
1521 3833280 : gfact=dot_product(gmet(qdir,:),gvec(:))/gmag
1522 :
1523 : ! Phase G*xred (complex conjugate) *2*pi*(g_idir)*vion1dq*gfact
1524 958320 : sfr=phre_vl3(ig1,ig2,ig3,iatom)*two_pi*gq(idir)*vion1dq(1)*gfact
1525 958320 : sfi=-phimag_vl3(ig1,ig2,ig3,iatom)*two_pi*gq(idir)*vion1dq(1)*gfact
1526 : ! Phase G*xred (complex conjugate) *2*pi*(\delta_{idir,qdir})*vion1
1527 958320 : if (idir==qdir) then
1528 390504 : sfr=sfr + phre_vl3(ig1,ig2,ig3,iatom)*two_pi*vion1(1)
1529 390504 : sfi=sfi - phimag_vl3(ig1,ig2,ig3,iatom)*two_pi*vion1(1)
1530 : end if
1531 :
1532 958320 : work1(re,ii)=sfr
1533 958320 : work1(im,ii)=sfi
1534 : end if
1535 :
1536 : end do
1537 : end if
1538 : end do
1539 : end do
1540 :
1541 : ! Consider the macroscopic term in the case of the pseudocore density
1542 799 : if (optnc_==1.and.idir==qdir) then
1543 11 : work1(re,1)= two_pi*vlspl(1,1,itypat)
1544 : end if
1545 :
1546 : ! Transform back to real space
1547 799 : call fourdp(cplex,work1,vpsp1dq,1,mpi_enreg,nfft,1,ngfft,0)
1548 :
1549 799 : xnorm=1.0_dp/ucvol
1550 6929713 : vpsp1dq(1:cplex*nfft)=vpsp1dq(1:cplex*nfft)*xnorm
1551 :
1552 799 : ABI_FREE(work1)
1553 :
1554 : ! End the condition of non-electric-field
1555 : end if
1556 :
1557 : contains
1558 :
1559 : !Real and imaginary parts of phase.
1560 958320 : function phr_vl3(x1,y1,x2,y2,x3,y3)
1561 : real(dp) :: phr_vl3
1562 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
1563 958320 : phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
1564 : end function phr_vl3
1565 :
1566 958320 : function phi_vl3(x1,y1,x2,y2,x3,y3)
1567 : real(dp) :: phi_vl3
1568 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
1569 958320 : phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
1570 : end function phi_vl3
1571 :
1572 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1573 3833280 : function ph1_vl3(nri,ig1,ia)
1574 : real(dp) :: ph1_vl3
1575 : integer,intent(in) :: nri,ig1,ia
1576 3833280 : ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1))
1577 3833280 : end function ph1_vl3
1578 :
1579 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1580 3833280 : function ph2_vl3(nri,ig2,ia)
1581 : real(dp) :: ph2_vl3
1582 : integer,intent(in) :: nri,ig2,ia
1583 3833280 : ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1))
1584 3833280 : end function ph2_vl3
1585 :
1586 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1587 3833280 : function ph3_vl3(nri,ig3,ia)
1588 : real(dp) :: ph3_vl3
1589 : integer,intent(in) :: nri,ig3,ia
1590 3833280 : ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
1591 3833280 : end function ph3_vl3
1592 :
1593 958320 : function phre_vl3(ig1,ig2,ig3,ia)
1594 : real(dp) :: phre_vl3
1595 : integer,intent(in) :: ig1,ig2,ig3,ia
1596 : phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1597 958320 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1598 958320 : end function phre_vl3
1599 :
1600 958320 : function phimag_vl3(ig1,ig2,ig3,ia)
1601 : real(dp) :: phimag_vl3
1602 : integer,intent(in) :: ig1,ig2,ig3,ia
1603 : phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1604 958320 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1605 958320 : end function phimag_vl3
1606 :
1607 3463658 : function gsq_vl3(g1,g2,g3)
1608 : real(dp) :: gsq_vl3
1609 : real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions
1610 : !Define G^2 based on G space metric gmet.
1611 : gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+&
1612 : & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+&
1613 3463658 : & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1)
1614 3463658 : end function gsq_vl3
1615 :
1616 : end subroutine dfpt_vlocaldq
1617 : !!***
1618 :
1619 : !!****f* ABINIT/dfpt_vlocaldqdq
1620 : !! NAME
1621 : !! dfpt_vlocaldqdq
1622 : !!
1623 : !! FUNCTION
1624 : !! Compute 2nd q-gradient (at q=0) of the local part of 1st-order
1625 : !! atomic displacement potential from the appropriate
1626 : !! atomic pseudopotential with structure and derivative factor.
1627 : !!
1628 : !! INPUTS
1629 : !! atindx(natom)=index table for atoms (see gstate.f)
1630 : !! cplex: if 1, real space 1-order functions on FFT grid
1631 : !! are REAL, if 2, COMPLEX
1632 : !! gmet(3,3)=reciprocal space metric (Bohr**-2)
1633 : !! gsqcut=cutoff G**2 for included G s in fft box.
1634 : !! idir=direction of atomic displacement (=1,2 or 3 : displacement of
1635 : !! atom ipert along the 1st, 2nd or 3rd axis).
1636 : !! ipert=number of the atom being displaced in the frozen-phonon
1637 : !! mpi_enreg=information about MPI parallelization
1638 : !! mqgrid=dimension of q grid for pseudopotentials
1639 : !! natom=number of atoms in cell.
1640 : !! nattyp(ntypat)=number of atoms of each type in cell.
1641 : !! nfft=(effective) number of FFT grid points (for this processor)
1642 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft
1643 : !! ntypat=number of types of atoms in cell.
1644 : !! n1,n2,n3=fft grid.
1645 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
1646 : !! qdir1=direction of the first q-gradient
1647 : !! qdir2=direction of the second q-gradient
1648 : !! qgrid(mqgrid)=grid of q points from 0 to qmax.
1649 : !! qphon(3)=wavevector of the phonon
1650 : !! ucvol=unit cell volume (Bohr**3).
1651 : !! vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
1652 : !!
1653 : !! OUTPUT
1654 : !! vpsp1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the first-order local
1655 : !! crystal pseudopotential in real space
1656 : !!
1657 : !! NOTES
1658 : !! * IMPORTANT: the formalism followed in this routine
1659 : !! assumes a phase factor for the perturbation that
1660 : !! is different to the one used elsewhere in the code (See M.Stengel paper):
1661 : !!
1662 : !! here: e^{i q (R_l + \tau_{\kappa})}
1663 : !! rest of ABINIT: e^{i q R_l}
1664 : !!
1665 : !! **A -i factor has been factorized out in all the contributions of the second
1666 : !! q-gradient of the atomic displacement Hamiltonian. This is lately included
1667 : !! in the whole frozen contribution to the q-gradient of the
1668 : !! 2nd order energy wrt an atomic displacement and a strain:
1669 : !! \Delta E^{\tau_{\kappa\alpha}^* (\beta)}_{m\kvec,\gamma\delta}
1670 : !!
1671 : !!
1672 : !! SOURCE
1673 :
1674 486 : subroutine dfpt_vlocaldqdq(atindx,cplex,gmet,gsqcut,idir,ipert,&
1675 486 : & mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,&
1676 486 : & ntypat,n1,n2,n3,ph1d,qdir1,qdir2,qgrid,qphon,ucvol,vlspl,vpsp1dqdq)
1677 :
1678 : !Arguments -------------------------------
1679 : !scalars
1680 : integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,ntypat
1681 : integer,intent(in) :: qdir1,qdir2
1682 : real(dp),intent(in) :: gsqcut,ucvol
1683 : type(MPI_type),intent(in) :: mpi_enreg
1684 : !arrays
1685 : integer,intent(in) :: atindx(natom),nattyp(ntypat),ngfft(18)
1686 : real(dp),intent(in) :: gmet(3,3),ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom)
1687 : real(dp),intent(in) :: qgrid(mqgrid),qphon(3),vlspl(mqgrid,2,ntypat)
1688 : real(dp),intent(out) :: vpsp1dqdq(cplex*nfft)
1689 :
1690 : !Local variables -------------------------
1691 : !scalars
1692 : integer :: alpha, delta, gamma
1693 : integer :: i1,i2,i3,ia1,iatom,id1,id2,id3,ig1,ig2,ig3,ii,ii1,im=2
1694 : integer :: itypat,re=1
1695 : real(dp),parameter :: tolfix=1.000000001_dp
1696 : real(dp) :: cutoff,delad,delag,gfact,gfact1,gfact2,gmag,gq1
1697 : real(dp) :: gq2,gq3,gsquar
1698 : real(dp) :: sfi,sfr,term1,term2,xnorm
1699 : logical :: qeq0
1700 : character(len=500) :: msg
1701 : !arrays
1702 486 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
1703 486 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
1704 : real(dp) :: gq(3),gvec(3),vion1(1),vion1dq(1),vion1dqdq(1)
1705 486 : real(dp),allocatable :: work1(:,:)
1706 : ! *********************************************************************
1707 :
1708 486 : iatom=ipert
1709 :
1710 : if(iatom==natom+1 .or. iatom==natom+2 .or. iatom==natom+10 .or. iatom==natom+11 &
1711 486 : & .or. iatom==natom+5 .or. iatom==natom+6 .or. (iatom>natom+11.and.iatom<=2*natom+11))then
1712 :
1713 : ! (In case of d/dk or an electric field, or magnetic (Zeeman) field->[natom+5] SPr deb )
1714 0 : vpsp1dqdq(1:cplex*nfft)=zero
1715 :
1716 : else
1717 :
1718 486 : alpha=idir; delta=qdir2; gamma=qdir1
1719 :
1720 : !Kronecker deltas
1721 486 : delad=0.0_dp; delag=0.0_dp
1722 486 : if (alpha==delta) delad=1.0_dp
1723 486 : if (alpha==gamma) delag=1.0_dp
1724 :
1725 : ! (In case of a phonon perturbation)
1726 1458 : ABI_MALLOC(work1,(2,nfft))
1727 4921236 : work1(1:2,1:nfft)=0.0_dp
1728 :
1729 486 : cutoff=gsqcut*tolfix
1730 486 : id1=n1/2+2
1731 486 : id2=n2/2+2
1732 486 : id3=n3/2+2
1733 :
1734 : ! Get the distrib associated with this fft_grid
1735 486 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
1736 :
1737 : ! This is to allow q=0
1738 486 : qeq0=.false.
1739 486 : if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then
1740 : qeq0=.true.
1741 : else
1742 0 : msg='This routine cannot be used for q/=0'
1743 0 : ABI_BUG(msg)
1744 : end if
1745 :
1746 : ! Determination of the atom type
1747 486 : ia1=0
1748 486 : itypat=0
1749 972 : do ii=1,ntypat
1750 486 : ia1=ia1+nattyp(ii)
1751 972 : if(atindx(iatom)<=ia1.and.itypat==0)itypat=ii
1752 : end do
1753 :
1754 : ii=0
1755 :
1756 7776 : do i3=1,n3
1757 7290 : ig3=i3-(i3/id3)*n3-1
1758 7290 : gq3=dble(ig3)+qphon(3)
1759 7290 : gq(3)=gq3
1760 117126 : do i2=1,n2
1761 116640 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
1762 109350 : ig2=i2-(i2/id2)*n2-1
1763 109350 : gq2=dble(ig2)+qphon(2)
1764 109350 : gq(2)=gq2
1765 :
1766 : ! Note the lower limit of the next loop
1767 109350 : ii1=1
1768 109350 : if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then
1769 486 : ii1=2
1770 486 : ii=ii+1
1771 : end if
1772 1749114 : do i1=ii1,n1
1773 1639764 : ig1=i1-(i1/id1)*n1-1
1774 1639764 : gq1=dble(ig1)+qphon(1)
1775 1639764 : gq(1)=gq1
1776 1639764 : ii=ii+1
1777 1639764 : gsquar=gsq_vl3(gq1,gq2,gq3)
1778 : ! Skip G**2 outside cutoff:
1779 1749114 : if (gsquar<=cutoff) then
1780 363528 : gmag=sqrt(gsquar)
1781 :
1782 : ! Evaluate spline fit to get first V(q) and V(q)' and later V(q)'':
1783 727056 : call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1)
1784 727056 : vion1=vion1/gsquar
1785 727056 : vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar
1786 :
1787 727056 : call splfit(qgrid,vion1dqdq,vlspl(:,:,itypat),2,(/gmag/),vion1,mqgrid,1)
1788 727056 : vion1dqdq=(vion1dqdq-4.0_dp*gmag*vion1dq-2.0_dp*vion1)/gsquar
1789 :
1790 1454112 : gvec=(/ig1,ig2,ig3/)
1791 1454112 : gfact1=dot_product(gmet(gamma,:),gvec(:))
1792 1454112 : gfact2=dot_product(gmet(delta,:),gvec(:))
1793 363528 : gfact=gvec(alpha)*gfact1*gfact2/gsquar
1794 :
1795 363528 : term1=delag*gfact2+delad*gfact1+gvec(alpha)*gmet(gamma,delta)
1796 363528 : term1=term1-gfact
1797 363528 : term1=term1*vion1dq(1)/gmag
1798 :
1799 363528 : term2=vion1dqdq(1)*gfact
1800 :
1801 : ! structure factors
1802 363528 : sfr=phre_vl3(ig1,ig2,ig3,iatom)
1803 363528 : sfi=-phimag_vl3(ig1,ig2,ig3,iatom)
1804 :
1805 : ! Multiply structure factor times vion derivatives:
1806 363528 : work1(re,ii)=sfr*(term1+term2)*two_pi
1807 363528 : work1(im,ii)=sfi*(term1+term2)*two_pi
1808 :
1809 : end if
1810 :
1811 : end do
1812 : end if
1813 : end do
1814 : end do
1815 :
1816 : ! Transform back to real space
1817 486 : call fourdp(cplex,work1,vpsp1dqdq,1,mpi_enreg,nfft,1,ngfft,0)
1818 :
1819 486 : xnorm=1.0_dp/ucvol
1820 3280986 : vpsp1dqdq(1:cplex*nfft)=vpsp1dqdq(1:cplex*nfft)*xnorm
1821 :
1822 486 : ABI_FREE(work1)
1823 :
1824 : ! End the condition of non-electric-field
1825 : end if
1826 :
1827 : contains
1828 :
1829 : !Real and imaginary parts of phase.
1830 363528 : function phr_vl3(x1,y1,x2,y2,x3,y3)
1831 : real(dp) :: phr_vl3
1832 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
1833 363528 : phr_vl3=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
1834 : end function phr_vl3
1835 :
1836 363528 : function phi_vl3(x1,y1,x2,y2,x3,y3)
1837 : real(dp) :: phi_vl3
1838 : real(dp),intent(in) :: x1,x2,x3,y1,y2,y3
1839 363528 : phi_vl3=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
1840 : end function phi_vl3
1841 :
1842 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1843 1454112 : function ph1_vl3(nri,ig1,ia)
1844 : real(dp) :: ph1_vl3
1845 : integer,intent(in) :: nri,ig1,ia
1846 1454112 : ph1_vl3=ph1d(nri,ig1+1+n1+(atindx(ia)-1)*(2*n1+1))
1847 1454112 : end function ph1_vl3
1848 :
1849 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1850 1454112 : function ph2_vl3(nri,ig2,ia)
1851 : real(dp) :: ph2_vl3
1852 : integer,intent(in) :: nri,ig2,ia
1853 1454112 : ph2_vl3=ph1d(nri,ig2+1+n2+(atindx(ia)-1)*(2*n2+1)+natom*(2*n1+1))
1854 1454112 : end function ph2_vl3
1855 :
1856 : ! Warning : this function differ from similar ones for ground-state calculations : note the atindx !!
1857 1454112 : function ph3_vl3(nri,ig3,ia)
1858 : real(dp) :: ph3_vl3
1859 : integer,intent(in) :: nri,ig3,ia
1860 1454112 : ph3_vl3=ph1d(nri,ig3+1+n3+(atindx(ia)-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
1861 1454112 : end function ph3_vl3
1862 :
1863 363528 : function phre_vl3(ig1,ig2,ig3,ia)
1864 : real(dp) :: phre_vl3
1865 : integer,intent(in) :: ig1,ig2,ig3,ia
1866 : phre_vl3=phr_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1867 363528 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1868 363528 : end function phre_vl3
1869 :
1870 363528 : function phimag_vl3(ig1,ig2,ig3,ia)
1871 : real(dp) :: phimag_vl3
1872 : integer,intent(in) :: ig1,ig2,ig3,ia
1873 : phimag_vl3=phi_vl3(ph1_vl3(re,ig1,ia),ph1_vl3(im,ig1,ia),&
1874 363528 : & ph2_vl3(re,ig2,ia),ph2_vl3(im,ig2,ia),ph3_vl3(re,ig3,ia),ph3_vl3(im,ig3,ia))
1875 363528 : end function phimag_vl3
1876 :
1877 1639764 : function gsq_vl3(g1,g2,g3)
1878 : real(dp) :: gsq_vl3
1879 : real(dp),intent(in) :: g1,g2,g3 ! Note that they are real, unlike in other similar function definitions
1880 : !Define G^2 based on G space metric gmet.
1881 : gsq_vl3=g1*g1*gmet(1,1)+g2*g2*gmet(2,2)+&
1882 : & g3*g3*gmet(3,3)+2.0_dp*g1*g2*gmet(1,2)+&
1883 1639764 : & 2.0_dp*g2*g3*gmet(2,3)+2.0_dp*g3*g1*gmet(3,1)
1884 1639764 : end function gsq_vl3
1885 :
1886 : end subroutine dfpt_vlocaldqdq
1887 : !!***
1888 :
1889 :
1890 : !!****f* ABINIT/dfpt_vmetdqdq
1891 : !! NAME
1892 : !! dfpt_vmetdqdq
1893 : !!
1894 : !! FUNCTION
1895 : !! Compute second q-gradient (at q=0) of the local part of 1st-order
1896 : !! metric potential from the appropriate atomic pseudopotential
1897 : !! with structure and derivative factor. Additionaly, compute the
1898 : !! second q-gradient (at q=0) of the Hartree and XC (if GGA) potentials of the metric
1899 : !! perturbation.
1900 : !! Cartesian coordinates are employed to define the direction of the
1901 : !! metric perturbation and the two q-gradients.
1902 : !!
1903 : !! INPUTS
1904 : !! cplex: if 1, real space 1-order functions on FFT grid
1905 : !! are REAL, if 2, COMPLEX
1906 : !! gmet(3,3)=reciprocal space metric (Bohr**-2)
1907 : !! gsqcut=cutoff G**2 for included G s in fft box.
1908 : !! gprimd(3,3)=dimensional reciprocal space primitive translations
1909 : !! idir= strain perturbation direction
1910 : !! ipert=number of the atom being displaced in the frozen-phonon
1911 : !! kxc(nfft,nkxc)=exchange and correlation kernel
1912 : !! mpi_enreg=information about MPI parallelization
1913 : !! mqgrid=dimension of q grid for pseudopotentials
1914 : !! natom=number of atoms in cell.
1915 : !! nattyp(ntypat)=number of atoms of each type in cell.
1916 : !! nfft=(effective) number of FFT grid points (for this processor)
1917 : !! ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/input_variables/vargs.htm#ngfft
1918 : !! nkxc=second dimension of the kxc array. If /=0, the XC kernel must be computed.
1919 : !! nspden=number of spin-density components
1920 : !! ntypat=number of types of atoms in cell.
1921 : !! n1,n2,n3=fft grid.
1922 : !! opthartdqdq= if 1 activates the calculation 2nd q-gradient of the Hartree potential
1923 : !! ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
1924 : !! qdir=direction of the q-gradient
1925 : !! qgrid(mqgrid)=grid of q points from 0 to qmax.
1926 : !! qphon(3)=wavevector of the phonon
1927 : !! rhog(2,nfft)=array for Fourier transform of GS electron density
1928 : !! rhor(nfftf,nspden)=array for GS electron density in electrons/bohr**3.
1929 : !! ucvol=unit cell volume (Bohr**3).
1930 : !! vlspl(mqgrid,2,ntypat)=spline fit of q^2 V(q) for each type of atom.
1931 : !!
1932 : !! OUTPUT
1933 : !! vhart1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the GS density Hartree potential from the metric perturbation
1934 : !! vpsp1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the first-order metric local
1935 : !! crystal pseudopotential in real space
1936 : !! vxc1dqdq(cplex*nfft)=2nd q-gradient (at q=0) of the GS density XC potential from the metric perturbation (only finite if GGA)
1937 : !!
1938 : !! NOTES
1939 : !! ** IMPORTANT: the formalism followed in this routine
1940 : !! assumes a phase factor for the perturbation that
1941 : !! is different to the one used elsewhere in the code (See M.Stengel paper):
1942 : !!
1943 : !! here: e^{i q (R_l + \tau_{\kappa})}
1944 : !! rest of ABINIT: e^{i q R_l}
1945 : !!
1946 : !! **Since the 2nd derivative w.r.t q-vector is calculated along cartesian
1947 : !! directions, the 1/twopi**2 factor (that in the rest of the code is applied
1948 : !! in the reduced to cartesian derivative conversion process) is here
1949 : !! explicictly included in the formulas.
1950 : !!
1951 : !! **Notice that idir=1-9, in contrast to the strain perturbation (idir=1-6),
1952 : !! because this term is not symmetric w.r.t permutations of the two strain
1953 : !! indices.
1954 : !!
1955 : !! **A -i factor has been factorized out in all the contributions of the second
1956 : !! q-gradient of the metric Hamiltonian. This is lately included in the contribution
1957 : !! of the corresponing term (T4) to the flexoelectric tensor in dfpt_flexoout.F90
1958 : !!
1959 : !! SOURCE
1960 :
1961 729 : subroutine dfpt_vmetdqdq(cplex,gmet,gprimd,gsqcut,idir,ipert,&
1962 729 : & kxc,mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,&
1963 729 : & ntypat,n1,n2,n3,nkxc,nspden,opthartdqdq,ph1d,qdir,qgrid,qphon,rhog,rhor,&
1964 729 : & ucvol,vlspl,vhart1dqdq,vpsp1dqdq,vxc1dqdq)
1965 :
1966 : !Arguments -------------------------------
1967 : !scalars
1968 : integer,intent(in) :: cplex,idir,ipert,mqgrid,n1,n2,n3,natom,nfft,nkxc,ntypat
1969 : integer,intent(in) :: nspden,opthartdqdq,qdir
1970 : real(dp),intent(in) :: gsqcut,ucvol
1971 : type(MPI_type),intent(in) :: mpi_enreg
1972 : !arrays
1973 : integer,intent(in) :: nattyp(ntypat),ngfft(18)
1974 : real(dp),intent(in) :: gmet(3,3),gprimd(3,3), kxc(nfft,nkxc)
1975 : real(dp),intent(in) :: ph1d(2,(2*n1+1+2*n2+1+2*n3+1)*natom)
1976 : real(dp),intent(in) :: qgrid(mqgrid),qphon(3),rhog(2,nfft),rhor(cplex*nfft,nspden)
1977 : real(dp),intent(in) :: vlspl(mqgrid,2,ntypat)
1978 : real(dp),intent(out) :: vhart1dqdq(cplex*nfft),vpsp1dqdq(cplex*nfft)
1979 : real(dp),intent(out) :: vxc1dqdq(cplex*nfft)
1980 :
1981 : !Local variables -------------------------
1982 : !scalars
1983 : integer :: beta, delta, gamma
1984 : integer :: ia,i1,i2,i3,ia1,ia2,id1,id2,id3,ig1,ig2,ig3,ii,ii1
1985 : integer :: itypat,jj
1986 : integer, parameter :: im=2, re=1
1987 : real(dp),parameter :: tolfix=1.000000001_dp
1988 : real(dp) :: cutoff,delbd,delbg,deldg,gfact,gmag,gq1
1989 : real(dp) :: gq2,gq3,gsquar,pisqrinv
1990 : real(dp) :: sfi,sfr,term1,term2,tmpre,tmpim,uogsquar,work1re,xnorm
1991 : logical :: qeq0
1992 : character(len=500) :: msg
1993 : !arrays
1994 : integer,save :: idx(18)=(/1,1,2,2,3,3,3,2,3,1,2,1,2,3,1,3,1,2/)
1995 729 : integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
1996 729 : integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
1997 : real(dp) :: gq(3),gqc(3),vion1(1),vion1dq(1),vion1dqdq(1)
1998 729 : real(dp),allocatable :: work1(:,:)
1999 : ! *********************************************************************
2000 :
2001 729 : if(ipert/=natom+3 .and. ipert/=natom+4)then
2002 :
2003 0 : vpsp1dqdq(1:cplex*nfft)=zero
2004 :
2005 : else
2006 :
2007 729 : beta=idx(2*idir-1); delta=idx(2*idir); gamma=qdir
2008 :
2009 : !Kronecker deltas
2010 729 : delbd=0.0_dp; delbg=0.0_dp; deldg=0.0_dp
2011 729 : if (beta==delta) delbd=1.0_dp
2012 729 : if (beta==gamma) delbg=1.0_dp
2013 729 : if (delta==gamma) deldg=1.0_dp
2014 :
2015 2187 : ABI_MALLOC(work1,(2,nfft))
2016 7381854 : work1(1:2,1:nfft)=0.0_dp
2017 :
2018 729 : cutoff=gsqcut*tolfix
2019 729 : id1=n1/2+2
2020 729 : id2=n2/2+2
2021 729 : id3=n3/2+2
2022 :
2023 : !Get the distrib associated with this fft_grid
2024 729 : call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
2025 :
2026 : ! This is to allow q=0
2027 729 : qeq0=.false.
2028 729 : if(qphon(1)**2+qphon(2)**2+qphon(3)**2<1.d-15) then
2029 : qeq0=.true.
2030 : else
2031 0 : msg='This routine cannot be used for q/=0'
2032 0 : ABI_BUG(msg)
2033 : end if
2034 :
2035 729 : ia1=1
2036 1458 : do itypat=1,ntypat
2037 : ! ia1,ia2 sets range of loop over atoms:
2038 729 : ia2=ia1+nattyp(itypat)-1
2039 :
2040 729 : ii=0
2041 :
2042 11664 : do i3=1,n3
2043 10935 : ig3=i3-(i3/id3)*n3-1
2044 10935 : gq3=dble(ig3)+qphon(3)
2045 10935 : gq(3)=gq3
2046 175689 : do i2=1,n2
2047 174960 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
2048 164025 : ig2=i2-(i2/id2)*n2-1
2049 164025 : gq2=dble(ig2)+qphon(2)
2050 164025 : gq(2)=gq2
2051 :
2052 : ! Note the lower limit of the next loop
2053 164025 : ii1=1
2054 164025 : if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then
2055 729 : ii1=2
2056 729 : ii=ii+1
2057 : end if
2058 2623671 : do i1=ii1,n1
2059 2459646 : ig1=i1-(i1/id1)*n1-1
2060 2459646 : gq1=dble(ig1)+qphon(1)
2061 2459646 : gq(1)=gq1
2062 2459646 : ii=ii+1
2063 2459646 : gsquar=gsq_vl(ig1,ig2,ig3)
2064 : ! Skip G**2 outside cutoff:
2065 2623671 : if (gsquar<=cutoff) then
2066 545292 : gmag=sqrt(gsquar)
2067 :
2068 : ! Obtain G in cartesian coordinates
2069 545292 : gqc(1)=gprimd(1,1)*gq(1)+gprimd(1,2)*gq(2)+gprimd(1,3)*gq(3)
2070 545292 : gqc(2)=gprimd(2,1)*gq(1)+gprimd(2,2)*gq(2)+gprimd(2,3)*gq(3)
2071 545292 : gqc(3)=gprimd(3,1)*gq(1)+gprimd(3,2)*gq(2)+gprimd(3,3)*gq(3)
2072 :
2073 : ! Evaluate spline fit to get first V(q) and V(q)' and later V(q)'':
2074 1090584 : call splfit(qgrid,vion1dq,vlspl(:,:,itypat),1,(/gmag/),vion1,mqgrid,1)
2075 1090584 : vion1=vion1/gsquar
2076 1090584 : vion1dq=(vion1dq-2.0_dp*gmag*vion1)/gsquar
2077 :
2078 1090584 : call splfit(qgrid,vion1dqdq,vlspl(:,:,itypat),2,(/gmag/),vion1,mqgrid,1)
2079 1090584 : vion1dqdq=(vion1dqdq-4.0_dp*gmag*vion1dq-2.0_dp*vion1)/gsquar
2080 :
2081 : ! Assemble structure factor over all atoms of given type:
2082 545292 : sfr=0.0_dp
2083 545292 : sfi=0.0_dp
2084 1635876 : do ia=ia1,ia2
2085 1090584 : sfr=sfr+phre_vl(ig1,ig2,ig3,ia)
2086 1635876 : sfi=sfi-phimag_vl(ig1,ig2,ig3,ia)
2087 : end do
2088 :
2089 545292 : gfact=gqc(beta)*gqc(delta)*gqc(gamma)/gsquar
2090 :
2091 545292 : term1=delbd*gqc(gamma)+delbg*gqc(delta)+deldg*gqc(beta)
2092 545292 : term1=term1-gfact
2093 545292 : term1=term1*vion1dq(1)/gmag
2094 :
2095 545292 : term2=vion1dqdq(1)*gfact
2096 :
2097 : ! Multiply structure factor times vion derivatives:
2098 545292 : work1(re,ii)=work1(re,ii)+sfr*(term1+term2)
2099 545292 : work1(im,ii)=work1(im,ii)+sfi*(term1+term2)
2100 :
2101 : ! End skip G**2 outside cutoff:
2102 : end if
2103 :
2104 : end do
2105 : end if
2106 : end do
2107 : end do
2108 :
2109 1458 : ia1=ia2+1
2110 :
2111 : ! End loop on type of atoms
2112 : end do
2113 :
2114 : ! Set Vloc(G=0)=0:
2115 729 : work1(re,1)=0.0_dp
2116 729 : work1(im,1)=0.0_dp
2117 :
2118 : ! Transform back to real space
2119 729 : call fourdp(cplex,work1,vpsp1dqdq,1,mpi_enreg,nfft,1,ngfft,0)
2120 :
2121 729 : xnorm=1.0_dp/ucvol/two_pi
2122 4921479 : vpsp1dqdq(1:cplex*nfft)=vpsp1dqdq(1:cplex*nfft)*xnorm
2123 :
2124 7381854 : work1=0.0_dp
2125 :
2126 : ! Calculate the GS density Hartree contribution
2127 729 : if (opthartdqdq==1) then
2128 :
2129 : pisqrinv=1.0_dp/pi**2
2130 :
2131 : ii=0
2132 11664 : do i3=1,n3
2133 10935 : ig3=i3-(i3/id3)*n3-1
2134 10935 : gq3=dble(ig3)+qphon(3)
2135 10935 : gq(3)=gq3
2136 175689 : do i2=1,n2
2137 174960 : if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
2138 164025 : ig2=i2-(i2/id2)*n2-1
2139 164025 : gq2=dble(ig2)+qphon(2)
2140 164025 : gq(2)=gq2
2141 :
2142 : ! Note the lower limit of the next loop
2143 164025 : ii1=1
2144 164025 : if(i3==1 .and. i2==1 .and. qeq0 .and. ig2==0 .and. ig3==0)then
2145 729 : ii1=2
2146 729 : ii=ii+1
2147 : end if
2148 2623671 : do i1=ii1,n1
2149 2459646 : ig1=i1-(i1/id1)*n1-1
2150 2459646 : gq1=dble(ig1)+qphon(1)
2151 2459646 : gq(1)=gq1
2152 2459646 : ii=ii+1
2153 2459646 : gsquar=gsq_vl(ig1,ig2,ig3)
2154 : ! Skip G**2 outside cutoff:
2155 2623671 : if (gsquar<=cutoff) then
2156 :
2157 : ! Precalculate quotient of G powers
2158 545292 : uogsquar= 1.0_dp/gsquar
2159 :
2160 : ! Obtain G in cartesian coordinates
2161 545292 : gqc(1)=gprimd(1,1)*gq(1)+gprimd(1,2)*gq(2)+gprimd(1,3)*gq(3)
2162 545292 : gqc(2)=gprimd(2,1)*gq(1)+gprimd(2,2)*gq(2)+gprimd(2,3)*gq(3)
2163 545292 : gqc(3)=gprimd(3,1)*gq(1)+gprimd(3,2)*gq(2)+gprimd(3,3)*gq(3)
2164 :
2165 545292 : term1=4.0_dp*gqc(beta)*gqc(gamma)*gqc(delta)*uogsquar*uogsquar
2166 545292 : term2=delbd*gqc(gamma)+delbg*gqc(delta)+deldg*gqc(beta)
2167 545292 : term2=-term2*uogsquar
2168 :
2169 545292 : work1re=pisqrinv*uogsquar*(term1+term2)
2170 545292 : work1(re,ii)=rhog(re,ii)*work1re
2171 545292 : work1(im,ii)=rhog(im,ii)*work1re
2172 :
2173 : ! End skip G**2 outside cutoff:
2174 : end if
2175 :
2176 : end do
2177 : end if
2178 : end do
2179 : end do
2180 :
2181 : ! Set V(G=0)=0:
2182 729 : work1(re,1)=0.0_dp
2183 729 : work1(im,1)=0.0_dp
2184 :
2185 : ! Transform back to real space
2186 729 : call fourdp(cplex,work1,vhart1dqdq,1,mpi_enreg,nfft,1,ngfft,0)
2187 :
2188 : ! End the calculation of the Hartree contribution
2189 : end if
2190 :
2191 729 : ABI_FREE(work1)
2192 :
2193 : ! Calculate the GS density XC contribution (if GGA)
2194 4921479 : vxc1dqdq(:)=zero
2195 729 : if (nkxc == 7) then
2196 : call dfpt_mkvxcgga_n0met(beta,1,delta,gamma,gprimd,kxc,mpi_enreg, &
2197 243 : & nfft,ngfft,nkxc,nspden,rhor,vxc1dqdq)
2198 :
2199 : !Fictitious i factor temporarily applied.
2200 : !It is later canceled by the (-i) factor of the total matrix element
2201 820368 : do ii=1,nfft
2202 820125 : jj=ii*2
2203 820125 : tmpre=vxc1dqdq(jj-1); tmpim=vxc1dqdq(jj)
2204 820368 : vxc1dqdq(jj-1)=-tmpim; vxc1dqdq(jj)=tmpre
2205 : end do
2206 : end if
2207 :
2208 : !End the condition of non-electric-field
2209 : end if
2210 :
2211 : contains
2212 :
2213 : !Real and imaginary parts of phase.
2214 1090584 : function phr_vl(x1,y1,x2,y2,x3,y3)
2215 : real(dp) :: phr_vl,x1,x2,x3,y1,y2,y3
2216 1090584 : phr_vl=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
2217 : end function phr_vl
2218 :
2219 1090584 : function phi_vl(x1,y1,x2,y2,x3,y3)
2220 : real(dp):: phi_vl,x1,x2,x3,y1,y2,y3
2221 1090584 : phi_vl=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
2222 : end function phi_vl
2223 :
2224 4362336 : function ph1_vl(nri,ig1,ia)
2225 : real(dp):: ph1_vl
2226 : integer :: nri,ig1,ia
2227 4362336 : ph1_vl=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1))
2228 4362336 : end function ph1_vl
2229 :
2230 4362336 : function ph2_vl(nri,ig2,ia)
2231 : real(dp):: ph2_vl
2232 : integer :: nri,ig2,ia
2233 4362336 : ph2_vl=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1))
2234 4362336 : end function ph2_vl
2235 :
2236 4362336 : function ph3_vl(nri,ig3,ia)
2237 : real(dp):: ph3_vl
2238 : integer :: nri,ig3,ia
2239 4362336 : ph3_vl=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
2240 4362336 : end function ph3_vl
2241 :
2242 1090584 : function phre_vl(ig1,ig2,ig3,ia)
2243 : real(dp):: phre_vl
2244 : integer :: ig1,ig2,ig3,ia
2245 : phre_vl=phr_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
2246 1090584 : & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
2247 1090584 : end function phre_vl
2248 :
2249 1090584 : function phimag_vl(ig1,ig2,ig3,ia)
2250 : real(dp) :: phimag_vl
2251 : integer :: ig1,ig2,ig3,ia
2252 : phimag_vl=phi_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
2253 1090584 : & ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
2254 1090584 : end function phimag_vl
2255 :
2256 4919292 : function gsq_vl(i1,i2,i3)
2257 : real(dp) :: gsq_vl
2258 : integer :: i1,i2,i3
2259 : !Define G^2 based on G space metric gmet.
2260 : gsq_vl=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
2261 : & dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
2262 4919292 : & dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
2263 4919292 : end function gsq_vl
2264 :
2265 : end subroutine dfpt_vmetdqdq
2266 :
2267 : end module m_mklocl
2268 : !!***
|