TABLE OF CONTENTS


ABINIT/vlocalstr [ Functions ]

[ Top ] [ Functions ]

NAME

 vlocalstr

FUNCTION

 Compute strain derivatives of local ionic potential
                second derivative of E wrt xred

COPYRIGHT

 Copyright (C) 1998-2018 ABINIT group (DRH, DCA, XG, GMR)
 This file is distributed under the terms of the
 GNU General Public License, see ~abinit/COPYING
 or http://www.gnu.org/copyleft/gpl.txt .

INPUTS

  gmet(3,3)=reciprocal space metric ($\textrm{Bohr}^{-2}$).
  gprimd(3,3)=reciprocal space dimensional primitive translations
  gsqcut=cutoff on $|G|^2$: see setup1 for definition (doubled sphere).
  istr=1,...6 specifies cartesian strain component 11,22,33,32,31,21
  mgfft=maximum size of 1D FFTs
  mpi_enreg=information about MPI parallelization
  mqgrid=number of grid pts in q array for f(q) spline.
  natom=number of atoms in unit cell.
  nattyp(ntypat)=number of atoms of each type in cell.
  nfft=(effective) number of FFT grid points (for this processor)
  ngfft(18)=contain all needed information about 3D FFT,
    see ~abinit/doc/variables/vargs.htm#ngfft
  ntypat=number of types of atoms.
  ph1d(2,3*(2*mgfft+1)*natom)=1-dim structure factor phase information.
  qgrid(mqgrid)=q grid for spline from 0 to qmax.
  ucvol=unit cell volume ($\textrm{Bohr}^3$).
  vlspl(mqgrid,2,ntypat)=q^2 v(q) spline for each type of atom.

OUTPUT

  vpsp1(nfft)=first-order local crystal pseudopotential in real space.

SIDE EFFECTS

NOTES

 * Note that the present routine is tightly connected to the dfpt_vlocal.f routine,
 that compute the derivative of the local ionic potential
 with respect to one atomic displacement. The argument list
 and the internal loops to be considered were sufficiently different
 as to make the two routines different.
 * The routine was adapted from mklocl.F90

PARENTS

      dfpt_looppert,dfpt_nselt,dfpt_nstpaw

CHILDREN

      fourdp,ptabs_fourdp

SOURCE

 56 #if defined HAVE_CONFIG_H
 57 #include "config.h"
 58 #endif
 59 
 60 #include "abi_common.h"
 61 
 62 
 63 subroutine vlocalstr(gmet,gprimd,gsqcut,istr,mgfft,mpi_enreg,&
 64 &  mqgrid,natom,nattyp,nfft,ngfft,ntypat,paral_kgb,ph1d,qgrid,&
 65 &  ucvol,vlspl,vpsp1)
 66 
 67  use defs_basis
 68  use defs_abitypes
 69  use m_errors
 70  use m_profiling_abi
 71 
 72  use m_mpinfo,   only : ptabs_fourdp
 73 
 74 !This section has been created automatically by the script Abilint (TD).
 75 !Do not modify the following lines by hand.
 76 #undef ABI_FUNC
 77 #define ABI_FUNC 'vlocalstr'
 78  use interfaces_53_ffts
 79 !End of the abilint section
 80 
 81  implicit none
 82 
 83 !Arguments ------------------------------------
 84 !scalars
 85  integer,intent(in) :: istr,mgfft,mqgrid,natom,nfft,ntypat,paral_kgb
 86  real(dp),intent(in) :: gsqcut,ucvol
 87  type(MPI_type),intent(in) :: mpi_enreg
 88 !arrays
 89  integer,intent(in) :: nattyp(ntypat),ngfft(18)
 90  real(dp),intent(in) :: gmet(3,3),gprimd(3,3),ph1d(2,3*(2*mgfft+1)*natom)
 91  real(dp),intent(in) :: qgrid(mqgrid),vlspl(mqgrid,2,ntypat)
 92  real(dp),intent(out) :: vpsp1(nfft)
 93 
 94 !Local variables-------------------------------
 95 !scalars
 96  integer,parameter :: im=2,re=1
 97  integer :: i1,i2,i3,ia,ia1,ia2,id1,id2,id3,ig1,ig2,ig3,ii,itypat,jj
 98  integer :: ka,kb,n1,n2,n3
 99  real(dp),parameter :: tolfix=1.0000001_dp
100  real(dp) :: aa,bb,cc,cutoff,dd,dgsquards,diff
101  real(dp) :: dq,dq2div6,dqdiv6,dqm1,ee,ff,gmag,gsquar
102  real(dp) :: sfi,sfr,term,vion1,vion2
103  real(dp) :: xnorm
104  character(len=500) :: message
105 !arrays
106  integer,save :: idx(12)=(/1,1,2,2,3,3,3,2,3,1,2,1/)
107  integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:)
108  integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:)
109  real(dp) :: dgmetds(3,3)
110  real(dp),allocatable :: work1(:,:)
111 
112 ! *************************************************************************
113 
114 !Define G^2 based on G space metric gmet.
115 ! gsq_vl(i1,i2,i3)=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
116 !& dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
117 !& dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
118 
119 !Define dG^2/ds based on G space metric derivative dgmetds.
120 ! dgsqds_vl(i1,i2,i3)=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+&
121 !& dble(i3*i3)*dgmetds(3,3)+&
122 !& dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+&
123 !& dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+&
124 !& dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2))
125 
126 !Real and imaginary parts of phase--statment functions:
127 ! phr_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
128 ! phi_vl(x1,y1,x2,y2,x3,y3)=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
129 ! ph1_vl(nri,i1,ia)=ph1d(nri,i1+1+n1+(ia-1)*(2*n1+1))
130 ! ph2_vl(nri,i2,ia)=ph1d(nri,i2+1+n2+(ia-1)*(2*n2+1)+&
131 !& natom*(2*n1+1))
132 ! ph3_vl(nri,i3,ia)=ph1d(nri,i3+1+n3+(ia-1)*(2*n3+1)+&
133 !& natom*(2*n1+1+2*n2+1))
134 ! phre_vl(i1,i2,i3,ia)=phr_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),&
135 !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia))
136 ! phimag_vl(i1,i2,i3,ia)=phi_vl(ph1_vl(re,i1,ia),ph1_vl(im,i1,ia),ph2_vl(re,i2,ia),&
137 !& ph2_vl(im,i2,ia),ph3_vl(re,i3,ia),ph3_vl(im,i3,ia))
138 
139 !-----
140 !Compute derivative of metric tensor wrt strain component istr
141  if(istr<1 .or. istr>6)then
142    write(message, '(a,i10,a,a,a)' )&
143 &   ' Input istr=',istr,' not allowed.',ch10,&
144 &   ' Possible values are 1,2,3,4,5,6 only.'
145    MSG_BUG(message)
146  end if
147 
148  ka=idx(2*istr-1);kb=idx(2*istr)
149  do ii = 1,3
150    dgmetds(:,ii)=-(gprimd(ka,:)*gprimd(kb,ii)+gprimd(kb,:)*gprimd(ka,ii))
151  end do
152 !For historical reasons:
153  dgmetds(:,:)=0.5_dp*dgmetds(:,:)
154 
155  n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
156 
157 !Get the distrib associated with this fft_grid
158  call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
159 
160 !Zero out array to permit accumulation over atom types below:
161  ABI_ALLOCATE(work1,(2,nfft))
162  work1(:,:)=0.0_dp
163 !
164  dq=(qgrid(mqgrid)-qgrid(1))/dble(mqgrid-1)
165  dqm1=1.0_dp/dq
166  dqdiv6=dq/6.0_dp
167  dq2div6=dq**2/6.0_dp
168  cutoff=gsqcut*tolfix
169  id1=n1/2+2
170  id2=n2/2+2
171  id3=n3/2+2
172 
173  ia1=1
174  do itypat=1,ntypat
175 !  ia1,ia2 sets range of loop over atoms:
176    ia2=ia1+nattyp(itypat)-1
177 
178    ii=0
179    do i3=1,n3
180      ig3=i3-(i3/id3)*n3-1
181      do i2=1,n2
182        if (fftn2_distrib(i2)==mpi_enreg%me_fft) then
183          ig2=i2-(i2/id2)*n2-1
184          do i1=1,n1
185            ig1=i1-(i1/id1)*n1-1
186            ii=ii+1
187 !          ***     GET RID OF THIS THESE IF STATEMENTS (if they slow code)
188 !          Skip G=0:
189 !          if (ii==1) cycle
190            if (ig1==0 .and. ig2==0 .and. ig3==0) cycle
191            gsquar=gsq_vl(ig1,ig2,ig3)
192 
193 !          Skip G**2 outside cutoff:
194            if (gsquar<=cutoff) then
195              gmag=sqrt(gsquar)
196              dgsquards=dgsqds_vl(ig1,ig2,ig3)
197 !            Compute vion(G) for given type of atom
198              jj=1+int(gmag*dqm1)
199              diff=gmag-qgrid(jj)
200 
201 !            Evaluate spline fit from q^2 V(q) to get V(q):
202 !            (p. 86 Numerical Recipes, Press et al;
203 !            NOTE error in book for sign
204 !            of "aa" term in derivative; also see splfit routine).
205 
206              bb = diff*dqm1
207              aa = 1.0_dp-bb
208              cc = aa*(aa**2-1.0_dp)*dq2div6
209              dd = bb*(bb**2-1.0_dp)*dq2div6
210 
211              vion1 = (aa*vlspl(jj,1,itypat)+bb*vlspl(jj+1,1,itypat) +&
212 &             cc*vlspl(jj,2,itypat)+dd*vlspl(jj+1,2,itypat) ) &
213 &             / gsquar
214 
215 !            Also get (dV(q)/dq)/q:
216 !            (note correction of Numerical Recipes sign error
217 !            before (3._dp*aa**2-1._dp)
218              ee= vlspl(jj+1,1,itypat)-vlspl(jj,1,itypat)
219              ff=  (3._dp*bb**2-1._dp)*vlspl(jj+1,2,itypat) &
220 &             - (3._dp*aa**2-1._dp)*vlspl(jj,2,itypat)
221              vion2 = ( ( ee*dqm1 + ff*dqdiv6 )/gmag&
222 &             - 2.0_dp*vion1                 ) / gsquar
223 
224 
225 !            Assemble structure factor over all atoms of given type:
226              sfr=0.0_dp
227              sfi=0.0_dp
228              do ia=ia1,ia2
229                sfr=sfr+phre_vl(ig1,ig2,ig3,ia)
230                sfi=sfi-phimag_vl(ig1,ig2,ig3,ia)
231              end do
232 
233              term=dgsquards*vion2
234 !            Add potential for diagonal strain components
235              if(istr <=3) then
236                term=term-vion1
237              end if
238 
239 !            Multiply structure factor times vion derivatives:
240              work1(re,ii)=work1(re,ii)+sfr*term
241              work1(im,ii)=work1(im,ii)+sfi*term
242 
243 !            End skip G**2 outside cutoff:
244            end if
245 !          End loop on n1, n2, n3. There is a "cycle" inside the loop
246          end do
247        end if
248      end do
249    end do
250 
251    ia1=ia2+1
252 
253 !  End loop on type of atoms
254  end do
255 
256 
257 !Set Vloc(G=0)=0:
258  work1(re,1)=0.0_dp
259  work1(im,1)=0.0_dp
260 
261 
262 !Transform back to real space
263  call fourdp(1,work1,vpsp1,1,mpi_enreg,nfft,ngfft,paral_kgb,0)
264 
265 !Divide by unit cell volume
266  xnorm=1.0_dp/ucvol
267  vpsp1(:)=vpsp1(:)*xnorm
268 
269  ABI_DEALLOCATE(work1)
270 
271  contains
272 
273 !Real and imaginary parts of phase.
274    function phr_vl(x1,y1,x2,y2,x3,y3)
275 
276 
277 !This section has been created automatically by the script Abilint (TD).
278 !Do not modify the following lines by hand.
279 #undef ABI_FUNC
280 #define ABI_FUNC 'phr_vl'
281 !End of the abilint section
282 
283    real(dp) :: phr_vl,x1,x2,x3,y1,y2,y3
284    phr_vl=(x1*x2-y1*y2)*x3-(y1*x2+x1*y2)*y3
285  end function phr_vl
286 
287    function phi_vl(x1,y1,x2,y2,x3,y3)
288 
289 
290 !This section has been created automatically by the script Abilint (TD).
291 !Do not modify the following lines by hand.
292 #undef ABI_FUNC
293 #define ABI_FUNC 'phi_vl'
294 !End of the abilint section
295 
296    real(dp):: phi_vl,x1,x2,x3,y1,y2,y3
297    phi_vl=(x1*x2-y1*y2)*y3+(y1*x2+x1*y2)*x3
298  end function phi_vl
299 
300    function ph1_vl(nri,ig1,ia)
301 
302 
303 !This section has been created automatically by the script Abilint (TD).
304 !Do not modify the following lines by hand.
305 #undef ABI_FUNC
306 #define ABI_FUNC 'ph1_vl'
307 !End of the abilint section
308 
309    real(dp):: ph1_vl 
310    integer :: nri,ig1,ia
311    ph1_vl=ph1d(nri,ig1+1+n1+(ia-1)*(2*n1+1))
312  end function ph1_vl
313 
314    function ph2_vl(nri,ig2,ia)
315 
316 
317 !This section has been created automatically by the script Abilint (TD).
318 !Do not modify the following lines by hand.
319 #undef ABI_FUNC
320 #define ABI_FUNC 'ph2_vl'
321 !End of the abilint section
322 
323    real(dp):: ph2_vl 
324    integer :: nri,ig2,ia
325    ph2_vl=ph1d(nri,ig2+1+n2+(ia-1)*(2*n2+1)+natom*(2*n1+1))
326  end function ph2_vl
327 
328    function ph3_vl(nri,ig3,ia)
329 
330 
331 !This section has been created automatically by the script Abilint (TD).
332 !Do not modify the following lines by hand.
333 #undef ABI_FUNC
334 #define ABI_FUNC 'ph3_vl'
335 !End of the abilint section
336 
337    real(dp):: ph3_vl
338    integer :: nri,ig3,ia
339    ph3_vl=ph1d(nri,ig3+1+n3+(ia-1)*(2*n3+1)+natom*(2*n1+1+2*n2+1))
340  end function ph3_vl
341 
342    function phre_vl(ig1,ig2,ig3,ia)
343 
344 
345 !This section has been created automatically by the script Abilint (TD).
346 !Do not modify the following lines by hand.
347 #undef ABI_FUNC
348 #define ABI_FUNC 'phre_vl'
349 !End of the abilint section
350 
351    real(dp):: phre_vl
352    integer :: ig1,ig2,ig3,ia
353    phre_vl=phr_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
354 &   ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
355  end function phre_vl
356 
357    function phimag_vl(ig1,ig2,ig3,ia)
358 
359 
360 !This section has been created automatically by the script Abilint (TD).
361 !Do not modify the following lines by hand.
362 #undef ABI_FUNC
363 #define ABI_FUNC 'phimag_vl'
364 !End of the abilint section
365 
366    real(dp) :: phimag_vl
367    integer :: ig1,ig2,ig3,ia
368    phimag_vl=phi_vl(ph1_vl(re,ig1,ia),ph1_vl(im,ig1,ia),&
369 &   ph2_vl(re,ig2,ia),ph2_vl(im,ig2,ia),ph3_vl(re,ig3,ia),ph3_vl(im,ig3,ia))
370  end function phimag_vl
371 
372    function gsq_vl(i1,i2,i3)
373 
374 
375 !This section has been created automatically by the script Abilint (TD).
376 !Do not modify the following lines by hand.
377 #undef ABI_FUNC
378 #define ABI_FUNC 'gsq_vl'
379 !End of the abilint section
380 
381    real(dp) :: gsq_vl
382    integer :: i1,i2,i3
383 !Define G^2 based on G space metric gmet.
384    gsq_vl=dble(i1*i1)*gmet(1,1)+dble(i2*i2)*gmet(2,2)+&
385 &   dble(i3*i3)*gmet(3,3)+dble(2*i1*i2)*gmet(1,2)+&
386 &   dble(2*i2*i3)*gmet(2,3)+dble(2*i3*i1)*gmet(3,1)
387  end function gsq_vl
388 
389    function dgsqds_vl(i1,i2,i3)
390 
391 
392 !This section has been created automatically by the script Abilint (TD).
393 !Do not modify the following lines by hand.
394 #undef ABI_FUNC
395 #define ABI_FUNC 'dgsqds_vl'
396 !End of the abilint section
397 
398    real(dp) :: dgsqds_vl 
399    integer :: i1,i2,i3
400 !Define dG^2/ds based on G space metric derivative dgmetds.
401    dgsqds_vl=dble(i1*i1)*dgmetds(1,1)+dble(i2*i2)*dgmetds(2,2)+&
402 &   dble(i3*i3)*dgmetds(3,3)+&
403 &   dble(i1*i2)*(dgmetds(1,2)+dgmetds(2,1))+&
404 &   dble(i1*i3)*(dgmetds(1,3)+dgmetds(3,1))+&
405 &   dble(i2*i3)*(dgmetds(2,3)+dgmetds(3,2))
406  end function dgsqds_vl
407 
408 end subroutine vlocalstr