TABLE OF CONTENTS


ABINIT/m_stress [ Modules ]

[ Top ] [ Modules ]

NAME

  m_stress

FUNCTION

COPYRIGHT

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

SOURCE

16 #if defined HAVE_CONFIG_H
17 #include "config.h"
18 #endif
19 
20 #include "abi_common.h"
21 
22 module m_stress
23 
24  use defs_basis
25  use m_efield
26  use m_abicore
27  use m_errors
28  use m_xmpi
29  use m_extfpmd
30 
31  use defs_abitypes,      only : MPI_type
32  use m_time,             only : timab
33  use m_geometry,         only : metric, stresssym
34  use m_fock,             only : fock_type
35  use m_ewald,            only : ewald2
36  use defs_datatypes,     only : pseudopotential_type
37  use m_pawrad,           only : pawrad_type
38  use m_pawtab,           only : pawtab_type
39  use m_electronpositron, only : electronpositron_type,electronpositron_calctype
40  use m_fft,              only : zerosym, fourdp
41  use m_mpinfo,           only : ptabs_fourdp
42  use m_vdw_dftd2,        only : vdw_dftd2
43  use m_vdw_dftd3,        only : vdw_dftd3
44  use m_atm2fft,          only : atm2fft
45  use m_mklocl,           only : mklocl_recipspace
46  use m_mkcore,           only : mkcore, mkcore_alt
47 
48  implicit none
49 
50  private

ABINIT/stress [ Functions ]

[ Top ] [ Functions ]

NAME

 stress

FUNCTION

 Compute the stress tensor
 strten(i,j) = (1/ucvol)*d(Etot)/(d(eps(i,j)))
 where Etot is energy per unit cell, ucvol is the unstrained unit cell
 volume, r(i,iat) is the ith position of atom iat,
 and eps(i,j) is an infinitesimal strain which maps each
 point r to r(i) -> r(i) + Sum(j) [eps(i,j)*r(j)].

INPUTS

  atindx1(natom)=index table for atoms, inverse of atindx
 berryopt    =  4/14: electric field is on -> add the contribution of the
                      -ebar_i p_i - Omega/(8*pi) (g^{-1})_ij ebar_i ebar_j  terms to the total energy
     = 6/16, or 7/17: electric displacement field is on  -> add the contribution of the
                      Omega/(8*pi) (g^{-1})_ij ebar_i ebar_j  terms to the total energy
   from Etot(npw) data (at fixed geometry), used for making
   Pulay correction to stress tensor (hartree).  Should be <=0.
  dtefield <type(efield_type)> = variables related to Berry phase
  eei=local pseudopotential part of Etot (hartree)
  efield = cartesian coordinates of the electric field in atomic units
  ehart=Hartree energy (hartree)
  eii=pseudoion core correction energy part of Etot (hartree)
  fock <type(fock_type)>= quantities to calculate Fock exact exchange
  gsqcut=cutoff value on G**2 for (large) sphere inside FFT box.
                       gsqcut=(boxcut**2)*ecut/(2._dp*(Pi**2)
  ixc = choice of exchange-correlation functional
  kinstr(6)=kinetic energy part of stress tensor
  mgfft=maximum size of 1D FFTs
  mpi_enreg=information about MPI parallelization
  mqgrid=dimensioned number of q grid points for local psp spline
  n1xccc=dimension of xccc1d ; 0 if no XC core correction is used
  n3xccc=dimension of the xccc3d array (0 or nfft).
  natom=number of atoms in cell
  nattyp(ntypat)=number of atoms of each type
  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
  nlstr(6)=nonlocal part of stress tensor
  nspden=number of spin-density components
  nsym=number of symmetries in space group
  ntypat=number of types of atoms
  psps <type(pseudopotential_type)>=variables related to pseudopotentials
  pawrad(ntypat*usepaw) <type(pawrad_type)>=paw radial mesh and related data
  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
  ph1d(2,3*(2*mgfft+1)*natom)=1-dim phase (structure factor) array
  prtvol=integer controlling volume of printed output
  qgrid(mqgrid)=q point array for local psp spline fits
  red_efieldbar(3) = efield in reduced units relative to reciprocal lattice
  rhog(2,nfft)=Fourier transform of charge density (bohr^-3)
  rprimd(3,3)=dimensional primitive translations in real space (bohr)
  strscondft(6)=cDFT correction to stress
  strsxc(6)=xc correction to stress
  symrec(3,3,nsym)=symmetries in reciprocal space, reduced coordinates
  typat(natom)=type integer for each atom in cell
  usefock=1 if fock operator is used; 0 otherwise.
  usekden=1 is kinetic energy density has to be taken into account, 0 otherwise
  usepaw= 0 for non paw calculation; =1 for paw calculation
  vdw_tol= Van der Waals tolerance
  vdw_tol_3bt= Van der Waals tolerance on the 3-body term (only effective
               vdw_xc=6)
  vdw_xc= Van der Waals correction flag
  vlspl(mqgrid,2,ntypat)=local psp spline
  vxc(nfft,nspden)=exchange-correlation potential (hartree) in real space
  vxctau(nfft,nspden,4*usekden)=(only for meta-GGA) derivative of XC energy density
                                wrt kinetic energy density (depsxcdtau)
  vxc_hf(nfft,nspden)=exchange-correlation potential (hartree) in real space for Hartree-Fock corrections
  xccc1d(n1xccc*(1-usepaw),6,ntypat)=1D core charge function and five derivatives,
                          for each type of atom, from psp (used in Norm-conserving only)
  xccc3d(n3xccc)=3D core electron density for XC core correction, bohr^-3
  xcctau3d(n3xccc*usekden)=(only for meta-GGA): 3D core electron kinetic energy density for XC core correction
  xcccrc(ntypat)=XC core correction cutoff radius (bohr) for each atom type
  xred(3,natom)=reduced dimensionless atomic coordinates
  zion(ntypat)=valence charge of each type of atom
  znucl(ntypat)=atomic number of atom type

OUTPUT

  strten(6)=components of the stress tensor (hartree/bohr^3) for the
    6 unique components of this symmetric 3x3 tensor:
    Given in order (1,1), (2,2), (3,3), (3,2), (3,1), (2,1).
    The diagonal components of the returned stress tensor are
    CORRECTED for the Pulay stress.

SIDE EFFECTS

  electronpositron <type(electronpositron_type)>=quantities for the electron-positron annihilation (optional argument)

NOTES

 * Concerning the stress tensor:
   See O. H. Nielsen and R. M. Martin, PRB 32, 3792 (1985) [[cite:Nielsen1985a]].
   Note that first term in equation (2) should have minus sign
   (for kinetic energy contribution to stress tensor).
   Normalizations in this code differ somewhat from those employed
   by Nielsen and Martin.
   For the stress tensor contribution from the nonlocal Kleinman-Bylander
   separable pseudopotential, see D. M. Bylander, L. Kleinman, and
   S. Lee, PRB 42, 1394 (1990) [[cite:Bylander1990]].
   Again normalization conventions differ somewhat.
   See Doug Allan s notes starting page 795 (13 Jan 1992).
 * This subroutine calls different subroutines to compute the stress
   tensor contributions from the following parts of the total energy:
   (1) kinetic energy, (2) exchange-correlation energy,
   (3) Hartree energy, (4) local pseudopotential energy,
   (5) pseudoion core correction energy, (6) nonlocal pseudopotential energy,
   (7) Ewald energy.

SOURCE

168  subroutine stress(atindx1,berryopt,dtefield,eei,efield,ehart,eii,fock,gsqcut,extfpmd,&
169 &                  ixc,kinstr,mgfft,mpi_enreg,mqgrid,n1xccc,n3xccc,natom,nattyp,&
170 &                  nfft,ngfft,nlstr,nspden,nsym,ntypat,psps,pawrad,pawtab,ph1d,&
171 &                  prtvol,qgrid,red_efieldbar,rhog,rprimd,strten,strscondft,strsxc,symrec,&
172 &                  typat,usefock,usekden,usepaw,vdw_tol,vdw_tol_3bt,vdw_xc,&
173 &                  vlspl,vxc,vxctau,vxc_hf,xccc1d,xccc3d,xcctau3d,xcccrc,xred,zion,znucl,qvpotzero,&
174 &                  electronpositron) ! optional argument
175 
176 !Arguments ------------------------------------
177 !scalars
178  integer,intent(in) :: berryopt,ixc,mgfft,mqgrid,n1xccc,n3xccc,natom,nfft,nspden
179  integer,intent(in) :: nsym,ntypat,prtvol,usefock,usekden,usepaw,vdw_xc
180  real(dp),intent(in) :: eei,ehart,eii,gsqcut,vdw_tol,vdw_tol_3bt,qvpotzero
181  type(efield_type),intent(in) :: dtefield
182  type(extfpmd_type),pointer,intent(inout) :: extfpmd
183  type(pseudopotential_type),intent(in) :: psps
184  type(electronpositron_type),pointer,optional :: electronpositron
185  type(MPI_type),intent(in) :: mpi_enreg
186  type(fock_type),pointer, intent(inout) :: fock
187 !arrays
188  integer,intent(in) :: atindx1(natom),nattyp(ntypat),ngfft(18),symrec(3,3,nsym)
189  integer,intent(in) :: typat(natom)
190  real(dp),intent(in) :: efield(3),kinstr(6),nlstr(6)
191  real(dp),intent(in) :: ph1d(2,3*(2*mgfft+1)*natom),qgrid(mqgrid)
192  real(dp),intent(in) :: red_efieldbar(3),rhog(2,nfft),strscondft(6),strsxc(6)
193  real(dp),intent(in) :: vlspl(mqgrid,2,ntypat),vxc(nfft,nspden),vxctau(nfft,nspden,4*usekden)
194  real(dp),allocatable,intent(in) :: vxc_hf(:,:)
195  real(dp),intent(in) :: xccc1d(n1xccc*(1-usepaw),6,ntypat),xcccrc(ntypat)
196  real(dp),intent(in) :: xred(3,natom),zion(ntypat),znucl(ntypat)
197  real(dp),intent(inout) :: xccc3d(n3xccc),xcctau3d(n3xccc*usekden),rprimd(3,3)
198  real(dp),intent(out) :: strten(6)
199  type(pawrad_type),intent(in) :: pawrad(ntypat*usepaw)
200  type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
201 
202 !Local variables-------------------------------
203 !scalars
204  integer :: coredens_method,coretau_method,iatom,icoulomb,idir,ii,ipositron,mu,nkpt=1
205  integer :: optatm,optdyfr,opteltfr,opt_hybr,optgr,option,optn,optn2,optstr,optv,sdir,vloc_method
206  real(dp),parameter :: tol=1.0d-15
207  real(dp) :: e_dum,dum_rcut=zero,strsii,ucvol,vol_element
208  character(len=500) :: message
209  logical :: calc_epaw3_stress, efield_flag
210 !arrays
211  integer :: qprtrb_dum(3),icutcoul=3
212  real(dp) :: corstr(6),dumstr(6),ep3(3),epaws3red(6),ewestr(6),gmet(3,3),vcutgeo(3)
213  real(dp) :: gprimd(3,3),harstr(6),lpsstr(6),rmet(3,3),taustr(6),tsec(2),uncorr(3)
214  real(dp) :: vdwstr(6),vprtrb_dum(2)
215  real(dp) :: Maxstr(6),ModE !Maxwell-stress constribution, and magnitude of efield
216  real(dp) :: dummy_in(0)
217  real(dp) :: dummy_out1(0),dummy_out2(0),dummy_out3(0),dummy_out4(0),dummy_out5(0),dummy_out6(0),dummy_out7(0)
218  real(dp),allocatable :: dummy(:),dyfr_dum(:,:,:),gr_dum(:,:),rhog_ep(:,:),v_dum(:)
219  real(dp),allocatable :: vxctotg(:,:)
220  character(len=10) :: EPName(1:2)=(/"Electronic","Positronic"/)
221 
222 ! *************************************************************************
223 
224  call timab(37,1,tsec)
225 
226 !Compute different geometric tensor, as well as ucvol, from rprimd
227  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
228 
229  opt_hybr=0;if (allocated(vxc_hf)) opt_hybr=1
230  icoulomb=0 ! not yet compatible with icoulomb
231 
232 !=======================================================================
233 !========= Local pseudopotential and core charge contributions =========
234 !=======================================================================
235 
236 !Determine by which method the local ionic potential and/or the pseudo core charge density
237 ! contributions have to be computed
238 !Local ionic potential:
239 ! Method 1: PAW
240 ! Method 2: Norm-conserving PP, icoulomb>0, wavelets
241  vloc_method=1;if (usepaw==0) vloc_method=2
242  if (psps%usewvl==1) vloc_method=2
243 !Pseudo core charge density:
244 ! Method 1: PAW, nc_xccc_gspace
245 ! Method 2: Norm-conserving PP, wavelets
246  coredens_method=1;if (usepaw==0) coredens_method=2
247  if (psps%nc_xccc_gspace==1) coredens_method=1
248  if (psps%nc_xccc_gspace==0) coredens_method=2
249  if (psps%usewvl==1) coredens_method=2
250  coretau_method=0
251  if (usekden==1.and.psps%usepaw==1) then
252    coretau_method=1;if (psps%nc_xccc_gspace==0) coretau_method=2
253  end if
254 
255 !Local ionic potential and/or pseudo core charge by method 1
256  if (vloc_method==1.or.coredens_method==1.or.coretau_method==1) then
257    call timab(551,1,tsec)
258 !  Compute Vxc in reciprocal space
259    if (coredens_method==1.and.n3xccc>0) then
260      ABI_MALLOC(v_dum,(nfft))
261      ABI_MALLOC(vxctotg,(2,nfft))
262      v_dum(:)=vxc(:,1);if (nspden>=2) v_dum(:)=0.5_dp*(v_dum(:)+vxc(:,2))
263      call fourdp(1,vxctotg,v_dum,-1,mpi_enreg,nfft,1,ngfft,0)
264      call zerosym(vxctotg,2,ngfft(1),ngfft(2),ngfft(3),&
265 &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
266      ABI_FREE(v_dum)
267    else
268      ABI_MALLOC(vxctotg,(0,0))
269    end if
270 !  Compute contribution to stresses from Vloc and/or pseudo core density
271    optv=0;if (vloc_method==1) optv=1
272    optn=0;if (coredens_method==1) optn=n3xccc/nfft
273    optatm=0;optdyfr=0;opteltfr=0;optgr=0;optstr=1;optn2=1
274    if (vloc_method==1.or.coredens_method==1) then
275      call atm2fft(atindx1,dummy_out1,dummy_out2,dummy_out3,dummy_out4,&
276 &     dummy_out5,dummy_in,gmet,gprimd,dummy_out6,dummy_out7,gsqcut,&
277 &     mgfft,mqgrid,natom,nattyp,nfft,ngfft,ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,&
278 &     psps,pawtab,ph1d,qgrid,qprtrb_dum,dum_rcut,rhog,rprimd,corstr,lpsstr,ucvol,usepaw,vxctotg,vxctotg,vxctotg,vprtrb_dum,vlspl,&
279 &     comm_fft=mpi_enreg%comm_fft,me_g0=mpi_enreg%me_g0,&
280 &     paral_kgb=mpi_enreg%paral_kgb,distribfft=mpi_enreg%distribfft)
281    end if
282    if (n3xccc==0.and.coredens_method==1) corstr=zero
283    ABI_FREE(vxctotg)
284    if (usekden==1.and.coretau_method==1..and.n3xccc>0) then
285 !    Compute contribution to stresses from pseudo kinetic energy core density
286      optv=0;optn=1;optn2=4
287      ABI_MALLOC(v_dum,(nfft))
288      ABI_MALLOC(vxctotg,(2,nfft))
289      v_dum(:)=vxctau(:,1,1);if (nspden>=2) v_dum(:)=0.5_dp*(v_dum(:)+vxctau(:,2,1))
290      call fourdp(1,vxctotg,v_dum,-1,mpi_enreg,nfft,1,ngfft,0)
291      call zerosym(vxctotg,2,ngfft(1),ngfft(2),ngfft(3),&
292 &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
293      ABI_FREE(v_dum)
294      call atm2fft(atindx1,dummy_out1,dummy_out2,dummy_out3,dummy_out4,&
295 &     dummy_out5,dummy_in,gmet,gprimd,dummy_out6,dummy_out7,gsqcut,&
296 &     mgfft,mqgrid,natom,nattyp,nfft,ngfft,ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,&
297 &     psps,pawtab,ph1d,qgrid,qprtrb_dum,dum_rcut,rhog,rprimd,taustr,dumstr,ucvol,usepaw,vxctotg,vxctotg,vxctotg,vprtrb_dum,vlspl,&
298 &     comm_fft=mpi_enreg%comm_fft,me_g0=mpi_enreg%me_g0,&
299 &     paral_kgb=mpi_enreg%paral_kgb,distribfft=mpi_enreg%distribfft)
300      corstr(1:6)=corstr(1:6)+taustr(1:6)
301      ABI_FREE(vxctotg)
302    end if
303    call timab(551,2,tsec)
304  end if
305 
306 !Local ionic potential by method 2
307  if (vloc_method==2) then
308    option=3
309    ABI_MALLOC(dyfr_dum,(3,3,natom))
310    ABI_MALLOC(gr_dum,(3,natom))
311    ABI_MALLOC(v_dum,(nfft))
312    call mklocl_recipspace(dyfr_dum,eei,gmet,gprimd,gr_dum,gsqcut,icutcoul,lpsstr,mgfft,&
313 &   mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,nkpt,ntypat,option,ph1d,qgrid,&
314 &   qprtrb_dum,dum_rcut,rhog,rprimd,ucvol,vcutgeo,vlspl,vprtrb_dum,v_dum)
315    ABI_FREE(dyfr_dum)
316    ABI_FREE(gr_dum)
317    ABI_FREE(v_dum)
318  end if
319 
320 !Pseudo core electron density by method 2
321  if (coredens_method==2.or.coretau_method==2) then
322    if (n1xccc/=0) then
323      call timab(55,1,tsec)
324      option=3
325      ABI_MALLOC(dyfr_dum,(3,3,natom))
326      ABI_MALLOC(gr_dum,(3,natom))
327      ABI_MALLOC(v_dum,(nfft))
328      if (coredens_method==2) then
329        if (psps%usewvl==0.and.usepaw==0.and.icoulomb==0) then
330          if(opt_hybr==0) then
331            call mkcore(corstr,dyfr_dum,gr_dum,mpi_enreg,natom,nfft,nspden,ntypat,ngfft(1),&
332 &           n1xccc,ngfft(2),ngfft(3),option,rprimd,typat,ucvol,vxc,&
333 &           xcccrc,xccc1d,xccc3d,xred)
334          else
335            call mkcore(corstr,dyfr_dum,gr_dum,mpi_enreg,natom,nfft,nspden,ntypat,ngfft(1),&
336 &           n1xccc,ngfft(2),ngfft(3),option,rprimd,typat,ucvol,vxc_hf,&
337 &           xcccrc,xccc1d,xccc3d,xred)
338          end if
339        else if (psps%usewvl==0.and.(usepaw==1.or.icoulomb==1)) then
340          call mkcore_alt(atindx1,corstr,dyfr_dum,gr_dum,icoulomb,mpi_enreg,natom,nfft,&
341 &         nspden,nattyp,ntypat,ngfft(1),n1xccc,ngfft(2),ngfft(3),option,rprimd,&
342 &         ucvol,vxc,xcccrc,xccc1d,xccc3d,xred,pawrad,pawtab,usepaw)
343        end if
344      end if
345      if (usekden==1.and.coretau_method==2) then
346        call mkcore_alt(atindx1,taustr,dyfr_dum,gr_dum,icoulomb,mpi_enreg,natom,nfft,&
347 &       nspden,nattyp,ntypat,ngfft(1),n1xccc,ngfft(2),ngfft(3),option,rprimd,&
348 &       ucvol,vxctau(:,:,1),xcccrc,xccc1d,xcctau3d,xred,pawrad,pawtab,usepaw,&
349 &       usekden=.true.)
350 
351      end if
352      ABI_FREE(dyfr_dum)
353      ABI_FREE(gr_dum)
354      ABI_FREE(v_dum)
355      call timab(55,2,tsec)
356    else
357      corstr(:)=zero
358    end if
359  end if
360 
361 !=======================================================================
362 !======================= Hartree energy contribution ===================
363 !=======================================================================
364 
365  call strhar(ehart,gsqcut,harstr,mpi_enreg,nfft,ngfft,rhog,rprimd)
366 
367 !=======================================================================
368 !======================= Ewald contribution ============================
369 !=======================================================================
370 
371  call timab(38,1,tsec)
372  call ewald2(gmet,natom,ntypat,rmet,rprimd,ewestr,typat,ucvol,xred,zion)
373 
374 !=======================================================================
375 !================== VdW DFT-D contribution ============================
376 !=======================================================================
377 
378  if (vdw_xc==5) then
379    call vdw_dftd2(e_dum,ixc,natom,ntypat,0,typat,rprimd,vdw_tol,&
380 &   xred,znucl,str_vdw_dftd2=vdwstr)
381  elseif (vdw_xc==6.or.vdw_xc==7) then
382    call vdw_dftd3(e_dum,ixc,natom,ntypat,0,typat,rprimd,vdw_xc,&
383 &   vdw_tol,vdw_tol_3bt,xred,znucl,str_vdw_dftd3=vdwstr)
384  end if
385 
386  call timab(38,2,tsec)
387 
388 !HONG  no Berry phase contribution if using reduced ebar or d according to
389 !HONG  PRL 89, 117602 (2002) [[cite:Souza2002]]
390 !HONG  Nature Physics: M. Stengel et.al. (2009)) [[cite:Stengel1999]]
391 !=======================================================================
392 !=================== Berry phase contribution ==========================
393 !=======================================================================
394 
395 !if (berryopt==4) then
396 !berrystr_tmp(:,:) = zero
397 !Diagonal:
398 !do mu = 1, 3
399 !do ii = 1, 3
400 !berrystr_tmp(mu,mu) = berrystr_tmp(mu,mu) - &
401 !&       efield(mu)*rprimd(mu,ii)*(pel(ii) + pion(ii))/ucvol
402 !end do
403 !end do
404 !Off-diagonal (symmetrized before adding it to strten):
405 !do ii = 1, 3
406 !berrystr_tmp(3,2) = berrystr_tmp(3,2) &
407 !&     - efield(3)*rprimd(2,ii)*(pel(ii) + pion(ii))/ucvol
408 !berrystr_tmp(2,3) = berrystr_tmp(2,3) &
409 !&     - efield(2)*rprimd(3,ii)*(pel(ii) + pion(ii))/ucvol
410 !berrystr_tmp(3,1) = berrystr_tmp(3,1) &
411 !&     - efield(3)*rprimd(1,ii)*(pel(ii) + pion(ii))/ucvol
412 !berrystr_tmp(1,3) = berrystr_tmp(1,3) &
413 !&     - efield(1)*rprimd(3,ii)*(pel(ii) + pion(ii))/ucvol
414 !berrystr_tmp(2,1) = berrystr_tmp(2,1) &
415 !&     - efield(2)*rprimd(1,ii)*(pel(ii) + pion(ii))/ucvol
416 !berrystr_tmp(1,2) = berrystr_tmp(1,2) &
417 !&     - efield(1)*rprimd(2,ii)*(pel(ii) + pion(ii))/ucvol
418 !end do
419 !berrystr(1) = berrystr_tmp(1,1)
420 !berrystr(2) = berrystr_tmp(2,2)
421 !berrystr(3) = berrystr_tmp(3,3)
422 !berrystr(4) = (berrystr_tmp(3,2) + berrystr_tmp(2,3))/two
423 !berrystr(5) = (berrystr_tmp(3,1) + berrystr_tmp(1,3))/two
424 !berrystr(6) = (berrystr_tmp(2,1) + berrystr_tmp(1,2))/two
425 !end if
426 
427 !=======================================================================
428 !================= Other (trivial) contributions =======================
429 !=======================================================================
430 
431 !Nonlocal part of stress has already been computed
432 !(in forstrnps(norm-conserving) or pawgrnl(PAW))
433 
434 !Kinetic part of stress has already been computed
435 !(in forstrnps)
436 
437 !cDFT part of stress tensor has already been computed in "constrained_residual"
438 
439 !XC part of stress tensor has already been computed in "strsxc"
440 
441 !ii part of stress (diagonal) is trivial!
442  strsii=-eii/ucvol
443 !qvpotzero is non zero, only when usepotzero=1
444  strsii=strsii+qvpotzero/ucvol
445 
446 !======================================================================
447 !HONG  Maxwell stress when electric/displacement field is non-zero=====
448 !======================================================================
449  efield_flag = (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or. &
450 & berryopt==14 .or. berryopt==16 .or. berryopt==17)
451  calc_epaw3_stress = (efield_flag .and. usepaw == 1)
452  if ( efield_flag ) then
453    ModE=dot_product(efield,efield)
454    do ii=1,3
455      Maxstr(ii)=two*efield(ii)*efield(ii)-ModE
456    end do
457    Maxstr(4)=two*efield(3)*efield(2)
458    Maxstr(5)=two*efield(3)*efield(1)
459    Maxstr(6)=two*efield(2)*efield(1)
460 !  Converting to units of Ha/Bohr^3
461 !  Maxstr(:)=Maxstr(:)*e_Cb*Bohr_Ang*1.0d-10/(Ha_J*8.0d0*pi)
462 
463    Maxstr(:)=Maxstr(:)*eps0*Ha_J*Bohr_Ang*1.0d-10/(8.0d0*pi*e_Cb**2)
464 
465    write(message, '(a,a)' )ch10,&
466 &   ' Cartesian components of Maxwell stress tensor (hartree/bohr^3)'
467    call wrtout(ab_out,message,'COLL')
468    call wrtout(std_out,  message,'COLL')
469    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
470 &   ' Maxstr(1 1)=',Maxstr(1),' Maxstr(3 2)=',Maxstr(4)
471    call wrtout(ab_out,message,'COLL')
472    call wrtout(std_out,  message,'COLL')
473    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
474 &   ' Maxstr(2 2)=',Maxstr(2),' Maxstr(3 1)=',Maxstr(5)
475    call wrtout(ab_out,message,'COLL')
476    call wrtout(std_out,  message,'COLL')
477    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
478 &   ' Maxstr(3 3)=',Maxstr(3),' Maxstr(2 1)=',Maxstr(6)
479    call wrtout(ab_out,message,'COLL')
480    call wrtout(std_out,  message,'COLL')
481    write(message, '(a)' ) ' '
482    call wrtout(ab_out,message,'COLL')
483    call wrtout(std_out,  message,'COLL')
484 
485  end if
486 
487 ! compute additional F3-type stress due to projectors for electric field with PAW
488  if ( efield_flag .and. calc_epaw3_stress ) then
489    do sdir = 1, 6
490      ep3(:) = zero
491      do idir = 1, 3
492        vol_element=one/(ucvol*dtefield%nstr(idir)*dtefield%nkstr(idir))
493        do iatom = 1, natom
494          ep3(idir) = ep3(idir) + vol_element*dtefield%epaws3(iatom,idir,sdir)
495        end do ! end loop over atoms
496      end do ! end loop over idir (components of P)
497 ! note no appearance of ucvol here unlike in forces, stress definition includes
498 ! division by ucvol, which cancels the factor in -ucvol e . p
499      epaws3red(sdir) = -dot_product(red_efieldbar(1:3),ep3(1:3))
500    end do
501 
502 !   write(message, '(a,a)' )ch10,&
503 !&   ' Cartesian components of PAW sigma_3 stress tensor (hartree/bohr^3)'
504 !   call wrtout(ab_out,message,'COLL')
505 !   call wrtout(std_out,  message,'COLL')
506 !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
507 !&   ' epaws3red(1 1)=',epaws3red(1),' epaws3red(3 2)=',epaws3red(4)
508 !   call wrtout(ab_out,message,'COLL')
509 !   call wrtout(std_out,  message,'COLL')
510 !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
511 !&   ' epaws3red(2 2)=',epaws3red(2),' epaws3red(3 1)=',epaws3red(5)
512 !   call wrtout(ab_out,message,'COLL')
513 !   call wrtout(std_out,  message,'COLL')
514 !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
515 !&   ' epaws3red(3 3)=',epaws3red(3),' epaws3red(2 1)=',epaws3red(6)
516 !   call wrtout(ab_out,message,'COLL')
517 !   call wrtout(std_out,  message,'COLL')
518 !   write(message, '(a)' ) ' '
519 !   call wrtout(ab_out,message,'COLL')
520 !   call wrtout(std_out,  message,'COLL')
521 
522  end if
523 
524 !=======================================================================
525 !===== Assemble the various contributions to the stress tensor =========
526 !=======================================================================
527 !In cartesian coordinates (symmetric storage)
528 
529  strten(:)=kinstr(:)+ewestr(:)+corstr(:)+strscondft(:)+strsxc(:)+harstr(:)+lpsstr(:)+nlstr(:)
530 
531  if (usefock==1 .and. associated(fock)) then
532    if (fock%fock_common%optstr) then
533      strten(:)=strten(:)+fock%fock_common%stress(:)
534    end if
535  end if
536 
537 !Add contributions for constant E or D calculation.
538  if ( efield_flag ) then
539    strten(:)=strten(:)+Maxstr(:)
540    if ( calc_epaw3_stress ) strten(:) = strten(:) + epaws3red(:)
541  end if
542  if (vdw_xc>=5.and.vdw_xc<=7) strten(:)=strten(:)+vdwstr(:)
543 
544 !Additional stuff for electron-positron
545  ipositron=0
546  if (present(electronpositron)) then
547    if (associated(electronpositron)) then
548      if (allocated(electronpositron%stress_ep)) ipositron=electronpositron_calctype(electronpositron)
549    end if
550  end if
551  if (abs(ipositron)==1) then
552    strten(:)=strten(:)-harstr(:)-ewestr(:)-corstr(:)-lpsstr(:)
553    harstr(:)=zero;ewestr(:)=zero;corstr(:)=zero;strsii=zero
554    lpsstr(:)=-lpsstr(:);lpsstr(1:3)=lpsstr(1:3)-two*eei/ucvol
555    strten(:)=strten(:)+lpsstr(:)
556    if (vdw_xc>=5.and.vdw_xc<=7) strten(:)=strten(:)-vdwstr(:)
557    if (vdw_xc>=5.and.vdw_xc<=7) vdwstr(:)=zero
558  end if
559  if (abs(ipositron)==2) then
560    ABI_MALLOC(rhog_ep,(2,nfft))
561    ABI_MALLOC(dummy,(6))
562    call fourdp(1,rhog_ep,electronpositron%rhor_ep,-1,mpi_enreg,nfft,1,ngfft,0)
563    rhog_ep=-rhog_ep
564    call strhar(electronpositron%e_hartree,gsqcut,dummy,mpi_enreg,nfft,ngfft,rhog_ep,rprimd)
565    strten(:)=strten(:)+dummy(:);harstr(:)=harstr(:)+dummy(:)
566    ABI_FREE(rhog_ep)
567    ABI_FREE(dummy)
568  end if
569  if (ipositron>0) strten(:)=strten(:)+electronpositron%stress_ep(:)
570 
571 !Symmetrize resulting tensor if nsym>1
572  if (nsym>1) then
573    call stresssym(gprimd,nsym,strten,symrec)
574  end if
575 
576 !Set to zero very small values of stress
577  do mu=1,6
578    if (abs(strten(mu))<tol) strten(mu)=zero
579  end do
580 
581 !Include diagonal terms, save uncorrected stress for output
582  do mu=1,3
583    uncorr(mu)=strten(mu)+strsii
584    strten(mu)=uncorr(mu)
585  end do
586 
587 !Adding the extfpmd continous contribution to stress tensor
588  if(associated(extfpmd)) then
589    strten(1:3)=strten(1:3)-(2./3.)*extfpmd%e_kinetic/extfpmd%ucvol
590  end if
591 
592 !=======================================================================
593 !================ Print out info about stress tensor ===================
594 !=======================================================================
595  if (prtvol>=10.and.ipositron>=0) then
596    write(message, '(a)' ) ' '
597    call wrtout(std_out,message,'COLL')
598    do mu=1,6
599      write(message, '(a,i5,a,1p,e22.12)' )&
600 &     ' stress: component',mu,' of hartree stress is',harstr(mu)
601      call wrtout(std_out,message,'COLL')
602    end do
603    write(message, '(a)' ) ' '
604    call wrtout(std_out,message,'COLL')
605    do mu=1,6
606      write(message, '(a,i5,a,1p,e22.12)' )&
607 &     ' stress: component',mu,' of loc psp stress is',lpsstr(mu)
608      call wrtout(std_out,message,'COLL')
609    end do
610    write(message, '(a)' ) ' '
611    call wrtout(std_out,message,'COLL')
612    do mu=1,6
613      write(message, '(a,i5,a,1p,e22.12)' )&
614 &     ' stress: component',mu,&
615 &     ' of kinetic stress is',kinstr(mu)
616      call wrtout(std_out,message,'COLL')
617    end do
618    write(message, '(a)' ) ' '
619    call wrtout(std_out,message,'COLL')
620    do mu=1,6
621      write(message, '(a,i5,a,1p,e22.12)' )&
622 &     ' stress: component',mu,' of nonlocal ps stress is',nlstr(mu)
623      call wrtout(std_out,message,'COLL')
624    end do
625    write(message, '(a)' ) ' '
626    call wrtout(std_out,message,'COLL')
627    do mu=1,6
628      write(message, '(a,i5,a,1p,e22.12)' )&
629 &     ' stress: component',mu,' of     core xc stress is',corstr(mu)
630      call wrtout(std_out,message,'COLL')
631    end do
632    write(message, '(a)' ) ' '
633    call wrtout(std_out,message,'COLL')
634    do mu=1,6
635      write(message, '(a,i5,a,1p,e22.12)' )&
636 &     ' stress: component',mu,&
637 &     ' of Ewald energ stress is',ewestr(mu)
638      call wrtout(std_out,message,'COLL')
639    end do
640    write(message, '(a)' ) ' '
641    call wrtout(std_out,message,'COLL')
642    do mu=1,6
643      write(message, '(a,i5,a,1p,e22.12)' ) &
644 &     ' stress: component',mu,' of xc stress is',strsxc(mu)
645      call wrtout(std_out,message,'COLL')
646    end do
647 
648    if( any( abs(strscondft(:))>tol8 ) )then
649      write(message, '(a)' ) ' '
650      call wrtout(std_out,message,'COLL')
651      do mu=1,6
652        write(message, '(a,i5,a,1p,e22.12)' ) &
653 &       ' stress: component',mu,' of cDFT stress is',strscondft(mu)
654        call wrtout(std_out,message,'COLL')
655      end do
656    endif
657 
658    if (vdw_xc>=5.and.vdw_xc<=7) then
659      write(message, '(a)' ) ' '
660      call wrtout(std_out,message,'COLL')
661      do mu=1,6
662        write(message, '(a,i5,a,1p,e22.12)' )&
663 &       ' stress: component',mu,&
664 &       ' of VdW DFT-D stress is',vdwstr(mu)
665        call wrtout(std_out,message,'COLL')
666      end do
667    end if
668    write(message, '(a)' ) ' '
669    call wrtout(std_out,message,'COLL')
670    write(message, '(a,1p,e22.12)' ) &
671 &   ' stress: ii (diagonal) part is',strsii
672    call wrtout(std_out,message,'COLL')
673    if (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or.  &
674 &   berryopt==14 .or. berryopt==16 .or. berryopt==17) then  !!HONG
675      write(message, '(a)' ) ' '
676      call wrtout(std_out,message,'COLL')
677      do mu = 1, 6
678        write(message, '(a,i2,a,1p,e22.12)' )&
679 &       ' stress: component',mu,' of Maxwell stress is',&
680 &       Maxstr(mu)
681        call wrtout(std_out,message,'COLL')
682      end do
683    end if
684    if (ipositron/=0) then
685      write(message, '(a)' ) ' '
686      call wrtout(std_out,message,'COLL')
687      do mu=1,6
688        write(message, '(a,i5,3a,1p,e22.12)' ) &
689 &       ' stress: component',mu,' of ',EPName(abs(ipositron)), &
690 &       ' stress is',electronpositron%stress_ep(mu)
691        call wrtout(std_out,message,'COLL')
692      end do
693    end if
694 
695  end if ! prtvol
696  if (ipositron>=0) then
697    write(message, '(a,a)' )ch10,&
698 &   ' Cartesian components of stress tensor (hartree/bohr^3)'
699    call wrtout(ab_out,message,'COLL')
700    call wrtout(std_out,  message,'COLL')
701    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
702 &   '  sigma(1 1)=',strten(1),'  sigma(3 2)=',strten(4)
703    call wrtout(ab_out,message,'COLL')
704    call wrtout(std_out,  message,'COLL')
705    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
706 &   '  sigma(2 2)=',strten(2),'  sigma(3 1)=',strten(5)
707    call wrtout(ab_out,message,'COLL')
708    call wrtout(std_out,  message,'COLL')
709    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
710 &   '  sigma(3 3)=',strten(3),'  sigma(2 1)=',strten(6)
711    call wrtout(ab_out,message,'COLL')
712    call wrtout(std_out,  message,'COLL')
713    write(message, '(a)' ) ' '
714    call wrtout(ab_out,message,'COLL')
715    call wrtout(std_out,  message,'COLL')
716  end if
717  call timab(37,2,tsec)
718 
719 end subroutine stress

ABINIT/strhar [ Functions ]

[ Top ] [ Functions ]

NAME

 strhar

FUNCTION

 Compute Hartree energy contribution to stress tensor (Cartesian coordinates).

INPUTS

  ehart=Hartree energy (hartree)
  gsqcut=cutoff value on $G^2$ for (large) sphere inside fft box.
  $gsqcut=(boxcut^2)*ecut/(2._dp*(\pi^2))$
  mpi_enreg=information about MPI parallelization
  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
  rhog(2,nfft)=Fourier transform of charge density (bohr^-3)
  rhog(2,nfft)= optional argument: Fourier transform of a second charge density (bohr^-3)
  rprimd(3,3)=dimensional primitive translations in real space (bohr)

OUTPUT

  harstr(6)=components of Hartree part of stress tensor
   (Cartesian coordinates, symmetric tensor) in hartree/bohr^3
   Definition of symmetric tensor storage: store 6 unique components
   in the order 11, 22, 33, 32, 31, 21 (suggested by Xavier Gonze).

SOURCE

749 subroutine strhar(ehart,gsqcut,harstr,mpi_enreg,nfft,ngfft,rhog,rprimd,&
750 &                 rhog2) ! optional argument
751 
752 !Arguments ------------------------------------
753 !scalars
754  integer,intent(in) :: nfft
755  real(dp),intent(in) :: ehart,gsqcut
756  type(MPI_type),intent(in) :: mpi_enreg
757 !arrays
758  integer,intent(in) :: ngfft(18)
759  real(dp),intent(in) :: rprimd(3,3),rhog(2,nfft)
760  real(dp),intent(in),optional :: rhog2(2,nfft)
761  real(dp),intent(out) :: harstr(6)
762 
763 !Local variables-------------------------------
764 !scalars
765  integer,parameter :: im=2,re=1
766  integer :: i1,i2,i3,id1,id2,id3,ierr,ig1,ig2,ig3,ii,irho2,me_fft,n1,n2,n3,nproc_fft
767  real(dp) :: cutoff,gsquar,rhogsq,tolfix=1.000000001_dp,ucvol
768 !arrays
769  real(dp) :: gcart(3),gmet(3,3),gprimd(3,3),rmet(3,3),tsec(2)
770  integer, ABI_CONTIGUOUS pointer :: fftn2_distrib(:),ffti2_local(:)
771  integer, ABI_CONTIGUOUS pointer :: fftn3_distrib(:),ffti3_local(:)
772 
773 ! *************************************************************************
774 
775  call timab(568,1,tsec)
776 
777  harstr(:)=zero
778 !ehtest=0.0_dp (used for testing)
779 
780  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
781 
782  irho2=0;if (present(rhog2)) irho2=1
783 
784 !Conduct looping over all fft grid points to find G vecs inside gsqcut
785 !Include G**2 on surface of cutoff sphere as well as inside:
786  cutoff=gsqcut*tolfix
787  n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
788  me_fft=ngfft(11)
789  nproc_fft=ngfft(10)
790  id1=n1/2+2
791  id2=n2/2+2
792  id3=n3/2+2
793  ii=0
794 
795  ! Get the distrib associated with this fft_grid
796  call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
797 
798  do i3=1,n3
799    ig3=i3-(i3/id3)*n3-1
800    do i2=1,n2
801      ig2=i2-(i2/id2)*n2-1
802      if (fftn2_distrib(i2)==me_fft) then
803        do i1=1,n1
804          ig1=i1-(i1/id1)*n1-1
805 !        ii=ii+1
806          ii=i1+n1*(ffti2_local(i2)-1+(n2/nproc_fft)*(i3-1))
807 !        **     GET RID OF THIS IF STATEMENT LATER for speed if needed
808 !        Avoid G=0:
809 !        if (ii>1) then
810          if (ig1==0 .and. ig2==0 .and. ig3==0) cycle
811 !        Compute cartesian components of G
812          gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+gprimd(1,3)*dble(ig3)
813          gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+gprimd(2,3)*dble(ig3)
814          gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+gprimd(3,3)*dble(ig3)
815 !        Compute |G|^2
816          gsquar=gcart(1)**2+gcart(2)**2+gcart(3)**2
817 
818 !        Keep only G**2 inside larger cutoff (not sure this is needed):
819          if (gsquar<=cutoff) then
820 !          take |rho(G)|^2 for complex rhog
821            if (irho2==0) then
822              rhogsq=rhog(re,ii)**2+rhog(im,ii)**2
823            else
824              rhogsq=rhog(re,ii)*rhog2(re,ii)+rhog(im,ii)*rhog2(im,ii)
825            end if
826            harstr(1)=harstr(1)+(rhogsq/gsquar**2)*gcart(1)*gcart(1)
827            harstr(2)=harstr(2)+(rhogsq/gsquar**2)*gcart(2)*gcart(2)
828            harstr(3)=harstr(3)+(rhogsq/gsquar**2)*gcart(3)*gcart(3)
829            harstr(4)=harstr(4)+(rhogsq/gsquar**2)*gcart(3)*gcart(2)
830            harstr(5)=harstr(5)+(rhogsq/gsquar**2)*gcart(3)*gcart(1)
831            harstr(6)=harstr(6)+(rhogsq/gsquar**2)*gcart(2)*gcart(1)
832          end if
833 !        end if
834        end do
835      end if
836    end do
837  end do
838 
839 !DO not remove : seems needed to avoid problem with pathscale compiler, in parallel
840 #ifdef FC_IBM
841  write(std_out,*)' strhar : before mpi_comm, harstr=',harstr
842 #endif
843 
844 !Init mpi_comm
845  if(mpi_enreg%nproc_fft>1)then
846    call timab(48,1,tsec)
847    call xmpi_sum(harstr,mpi_enreg%comm_fft ,ierr)
848    call timab(48,2,tsec)
849  end if
850 
851 #ifdef FC_IBM
852 !DO not remove : seems needed to avoid problem with pathscale compiler, in parallel
853  write(std_out,*)' strhar : after mpi_comm, harstr=',harstr
854  write(std_out,*)' strhar : ehart,ucvol=',ehart,ucvol
855 #endif
856 
857 !Normalize and add term -ehart/ucvol on diagonal
858  harstr(1)=harstr(1)/pi-ehart/ucvol
859  harstr(2)=harstr(2)/pi-ehart/ucvol
860  harstr(3)=harstr(3)/pi-ehart/ucvol
861  harstr(4)=harstr(4)/pi
862  harstr(5)=harstr(5)/pi
863  harstr(6)=harstr(6)/pi
864 
865  call timab(568,2,tsec)
866 
867 end subroutine strhar