LCOV - code coverage report
Current view: top level - src/67_common - m_stress.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 86.9 % 305 265
Test Date: 2026-09-19 15:24:51 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_stress
       2              : !! NAME
       3              : !!  m_stress
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 1998-2026 ABINIT group (DCA, XG, GMR, FJ, MT)
      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              : ! nvtx related macro definition
      23              : #include "nvtx_macros.h"
      24              : 
      25              : module m_stress
      26              : 
      27              :  use defs_basis
      28              :  use m_efield
      29              :  use m_abicore
      30              :  use m_errors
      31              :  use m_xmpi
      32              :  use m_extfpmd
      33              : 
      34              :  use defs_abitypes,      only : MPI_type
      35              :  use m_time,             only : timab
      36              :  use m_geometry,         only : metric, stresssym
      37              :  use m_fock,             only : fock_type
      38              :  use m_ewald,            only : ewald2
      39              :  use defs_datatypes,     only : pseudopotential_type
      40              :  use m_pawrad,           only : pawrad_type
      41              :  use m_pawtab,           only : pawtab_type
      42              :  use m_electronpositron, only : electronpositron_type,electronpositron_calctype
      43              :  use m_fft,              only : zerosym, fourdp
      44              :  use m_mpinfo,           only : ptabs_fourdp
      45              :  use m_vdw_dftd2,        only : vdw_dftd2
      46              :  use m_vdw_dftd3,        only : vdw_dftd3
      47              :  use m_atm2fft,          only : atm2fft
      48              :  use m_mklocl,           only : mklocl_recipspace
      49              :  use m_mkcore,           only : mkcore, mkcore_alt
      50              : 
      51              : #if defined(HAVE_GPU_MARKERS)
      52              :  use m_nvtx_data
      53              : #endif
      54              : 
      55              :  implicit none
      56              : 
      57              :  private
      58              : !!***
      59              : 
      60              :  public :: stress
      61              : !!***
      62              : 
      63              : contains
      64              : !!***
      65              : 
      66              : !!****f* ABINIT/stress
      67              : !!
      68              : !! NAME
      69              : !! stress
      70              : !!
      71              : !! FUNCTION
      72              : !! Compute the stress tensor
      73              : !! strten(i,j) = (1/ucvol)*d(Etot)/(d(eps(i,j)))
      74              : !! where Etot is energy per unit cell, ucvol is the unstrained unit cell
      75              : !! volume, r(i,iat) is the ith position of atom iat,
      76              : !! and eps(i,j) is an infinitesimal strain which maps each
      77              : !! point r to r(i) -> r(i) + Sum(j) [eps(i,j)*r(j)].
      78              : !!
      79              : !! INPUTS
      80              : !!  atindx1(natom)=index table for atoms, inverse of atindx
      81              : !! berryopt    =  4/14: electric field is on -> add the contribution of the
      82              : !!                      -ebar_i p_i - Omega/(8*pi) (g^{-1})_ij ebar_i ebar_j  terms to the total energy
      83              : !!     = 6/16, or 7/17: electric displacement field is on  -> add the contribution of the
      84              : !!                      Omega/(8*pi) (g^{-1})_ij ebar_i ebar_j  terms to the total energy
      85              : !!   from Etot(npw) data (at fixed geometry), used for making
      86              : !!   Pulay correction to stress tensor (hartree).  Should be <=0.
      87              : !!  dtefield <type(efield_type)> = variables related to Berry phase
      88              : !!  eei=local pseudopotential part of Etot (hartree)
      89              : !!  efield = cartesian coordinates of the electric field in atomic units
      90              : !!  ehart=Hartree energy (hartree)
      91              : !!  eii=pseudoion core correction energy part of Etot (hartree)
      92              : !!  extfpmd <type(extfpmd_type)>=extended first-principles molecular dynamics type
      93              : !!  fock <type(fock_type)>= quantities to calculate Fock exact exchange
      94              : !!  gsqcut=cutoff value on G**2 for (large) sphere inside FFT box.
      95              : !!                       gsqcut=(boxcut**2)*ecut/(2._dp*(Pi**2)
      96              : !!  ixc = choice of exchange-correlation functional
      97              : !!  kinstr(6)=kinetic energy part of stress tensor
      98              : !!  mggastr(6)=meta-GGA part of stress tensor (hartree/bohr^3)
      99              : !!             Only non-local contribution from Div(V_tau.Grad(Psi))
     100              : !!  mgfft=maximum size of 1D FFTs
     101              : !!  mpi_enreg=information about MPI parallelization
     102              : !!  mqgrid=dimensioned number of q grid points for local psp spline
     103              : !!  n1xccc=dimension of xccc1d ; 0 if no XC core correction is used
     104              : !!  n3xccc=dimension of the xccc3d array (0 or nfft).
     105              : !!  natom=number of atoms in cell
     106              : !!  nattyp(ntypat)=number of atoms of each type
     107              : !!  nfft=(effective) number of FFT grid points (for this processor)
     108              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     109              : !!  nlstr(6)=nonlocal part of stress tensor
     110              : !!  nspden=number of spin-density components
     111              : !!  nsym=number of symmetries in space group
     112              : !!  ntypat=number of types of atoms
     113              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     114              : !!  pawrad(ntypat*usepaw) <type(pawrad_type)>=paw radial mesh and related data
     115              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     116              : !!  ph1d(2,3*(2*mgfft+1)*natom)=1-dim phase (structure factor) array
     117              : !!  prtvol=integer controlling volume of printed output
     118              : !!  qgrid(mqgrid)=q point array for local psp spline fits
     119              : !!  red_efieldbar(3) = efield in reduced units relative to reciprocal lattice
     120              : !!  rhog(2,nfft)=Fourier transform of charge density (bohr^-3)
     121              : !!  rprimd(3,3)=dimensional primitive translations in real space (bohr)
     122              : !!  strscondft(6)=cDFT correction to stress
     123              : !!  strsxc(6)=xc correction to stress
     124              : !!  symrec(3,3,nsym)=symmetries in reciprocal space, reduced coordinates
     125              : !!  typat(natom)=type integer for each atom in cell
     126              : !!  usefock=1 if fock operator is used; 0 otherwise.
     127              : !!  usekden=1 is kinetic energy density has to be taken into account, 0 otherwise
     128              : !!  usepaw= 0 for non paw calculation; =1 for paw calculation
     129              : !!  usevxctau=1 if if XC functional depends on kinetic energy density
     130              : !!  vdw_tol= Van der Waals tolerance
     131              : !!  vdw_tol_3bt= Van der Waals tolerance on the 3-body term (only effective
     132              : !!               vdw_xc=6)
     133              : !!  vdw_xc= Van der Waals correction flag
     134              : !!  vlspl(mqgrid,2,ntypat)=local psp spline
     135              : !!  vxc(nfft,nspden)=exchange-correlation potential (hartree) in real space
     136              : !!  vxctau(nfft,nspden,4*usevxctau)=(only for meta-GGA) derivative of XC energy density
     137              : !!                                wrt kinetic energy density (depsxcdtau)
     138              : !!  vxc_hf(nfft,nspden)=exchange-correlation potential (hartree) in real space for Hartree-Fock corrections
     139              : !!  xccc1d(n1xccc*(1-usepaw),6,ntypat)=1D core charge function and five derivatives,
     140              : !!                          for each type of atom, from psp (used in Norm-conserving only)
     141              : !!  xccc3d(n3xccc)=3D core electron density for XC core correction, bohr^-3
     142              : !!  xcctau3d(n3xccc*usekden)=(only for meta-GGA): 3D core electron kinetic energy density for XC core correction
     143              : !!  xcccrc(ntypat)=XC core correction cutoff radius (bohr) for each atom type
     144              : !!  xred(3,natom)=reduced dimensionless atomic coordinates
     145              : !!  zion(ntypat)=valence charge of each type of atom
     146              : !!  znucl(ntypat)=atomic number of atom type
     147              : !!
     148              : !! OUTPUT
     149              : !!  strten(6)=components of the stress tensor (hartree/bohr^3) for the
     150              : !!    6 unique components of this symmetric 3x3 tensor:
     151              : !!    Given in order (1,1), (2,2), (3,3), (3,2), (3,1), (2,1).
     152              : !!    The diagonal components of the returned stress tensor are
     153              : !!    CORRECTED for the Pulay stress.
     154              : !!
     155              : !! SIDE EFFECTS
     156              : !!  electronpositron <type(electronpositron_type)>=quantities for the electron-positron annihilation (optional argument)
     157              : !!
     158              : !! NOTES
     159              : !! * Concerning the stress tensor:
     160              : !!   See O. H. Nielsen and R. M. Martin, PRB 32, 3792 (1985) [[cite:Nielsen1985a]].
     161              : !!   Note that first term in equation (2) should have minus sign
     162              : !!   (for kinetic energy contribution to stress tensor).
     163              : !!   Normalizations in this code differ somewhat from those employed
     164              : !!   by Nielsen and Martin.
     165              : !!   For the stress tensor contribution from the nonlocal Kleinman-Bylander
     166              : !!   separable pseudopotential, see D. M. Bylander, L. Kleinman, and
     167              : !!   S. Lee, PRB 42, 1394 (1990) [[cite:Bylander1990]].
     168              : !!   Again normalization conventions differ somewhat.
     169              : !!   See Doug Allan s notes starting page 795 (13 Jan 1992).
     170              : !! * This subroutine calls different subroutines to compute the stress
     171              : !!   tensor contributions from the following parts of the total energy:
     172              : !!   (1) kinetic energy, (2) exchange-correlation energy,
     173              : !!   (3) Hartree energy, (4) local pseudopotential energy,
     174              : !!   (5) pseudoion core correction energy, (6) nonlocal pseudopotential energy,
     175              : !!   (7) Ewald energy.
     176              : !!
     177              : !! SOURCE
     178              : 
     179         6302 :  subroutine stress(atindx1,berryopt,dtefield,eei,efield,ehart,eii,fock,gsqcut,extfpmd,&
     180         6302 : &                  ixc,kinstr,mggastr,mgfft,mpi_enreg,mqgrid,n1xccc,n3xccc,natom,nattyp,&
     181         6302 : &                  nfft,ngfft,nlstr,nspden,nsym,ntypat,psps,pawrad,pawtab,ph1d,&
     182         6302 : &                  prtvol,qgrid,red_efieldbar,rhog,rprimd,strten,strscondft,strsxc,symrec,&
     183         6302 : &                  typat,usefock,usekden,usepaw,usevxctau,vdw_tol,vdw_tol_3bt,vdw_xc,&
     184         6302 : &                  vlspl,vxc,vxctau,vxc_hf,xccc1d,xccc3d,xcctau3d,xcccrc,xred,zion,znucl,qvpotzero,&
     185              : &                  electronpositron) ! optional argument
     186              : 
     187              : !Arguments ------------------------------------
     188              : !scalars
     189              :  integer,intent(in) :: berryopt,ixc,mgfft,mqgrid,n1xccc,n3xccc,natom,nfft,nspden
     190              :  integer,intent(in) :: nsym,ntypat,prtvol,usefock,usekden,usepaw,usevxctau,vdw_xc
     191              :  real(dp),intent(in) :: eei,ehart,eii,gsqcut,vdw_tol,vdw_tol_3bt,qvpotzero
     192              :  type(efield_type),intent(in) :: dtefield
     193              :  type(extfpmd_type),pointer,intent(inout) :: extfpmd
     194              :  type(pseudopotential_type),intent(in) :: psps
     195              :  type(electronpositron_type),pointer,optional :: electronpositron
     196              :  type(MPI_type),intent(in) :: mpi_enreg
     197              :  type(fock_type),pointer, intent(inout) :: fock
     198              : !arrays
     199              :  integer,intent(in) :: atindx1(natom),nattyp(ntypat),ngfft(18),symrec(3,3,nsym)
     200              :  integer,intent(in) :: typat(natom)
     201              :  real(dp),intent(in) :: efield(3),kinstr(6),mggastr(6),nlstr(6)
     202              :  real(dp),intent(in) :: ph1d(2,3*(2*mgfft+1)*natom),qgrid(mqgrid)
     203              :  real(dp),intent(in) :: red_efieldbar(3),rhog(2,nfft),strscondft(6),strsxc(6)
     204              :  real(dp),intent(in) :: vlspl(mqgrid,2,ntypat),vxc(nfft,nspden),vxctau(nfft,nspden,4*usevxctau)
     205              :  real(dp),allocatable,intent(in) :: vxc_hf(:,:)
     206              :  real(dp),intent(in) :: xccc1d(n1xccc*(1-usepaw),6,ntypat),xcccrc(ntypat)
     207              :  real(dp),intent(in) :: xred(3,natom),zion(ntypat),znucl(ntypat)
     208              :  real(dp),intent(inout) :: xccc3d(n3xccc),xcctau3d(n3xccc*usekden),rprimd(3,3)
     209              :  real(dp),intent(out) :: strten(6)
     210              :  type(pawrad_type),intent(in) :: pawrad(ntypat*usepaw)
     211              :  type(pawtab_type),intent(in) :: pawtab(ntypat*usepaw)
     212              : 
     213              : !Local variables-------------------------------
     214              : !scalars
     215              :  integer :: coredens_method,coretau_method,iatom,icoulomb,idir,ii,ipositron,mu,nkpt=1
     216              :  integer :: optatm,optdyfr,opteltfr,opt_hybr,optgr,option,optn,optn2,optstr,optv,sdir,vloc_method
     217              :  real(dp),parameter :: tol=1.0d-15
     218              :  real(dp) :: e_dum,dum_rcut=zero,strsii,ucvol,vol_element
     219              :  character(len=500) :: message
     220              :  logical :: calc_epaw3_stress, efield_flag
     221              : !arrays
     222              :  integer :: qprtrb_dum(3),icutcoul=3
     223              :  real(dp) :: corstr(6),dumstr(6),ep3(3),epaws3red(6),ewestr(6),gmet(3,3),vcutgeo(3)
     224              :  real(dp) :: gprimd(3,3),harstr(6),lpsstr(6),rmet(3,3),taustr(6),tsec(2),uncorr(3)
     225              :  real(dp) :: vdwstr(6),vprtrb_dum(2)
     226              :  real(dp) :: Maxstr(6),ModE !Maxwell-stress constribution, and magnitude of efield
     227              :  real(dp) :: dummy_in(0)
     228              :  real(dp) :: dummy_out1(0),dummy_out2(0),dummy_out3(0),dummy_out4(0),dummy_out5(0),dummy_out6(0),dummy_out7(0)
     229         6302 :  real(dp),allocatable :: dummy(:),dyfr_dum(:,:,:),gr_dum(:,:),rhog_ep(:,:),v_dum(:)
     230         6302 :  real(dp),allocatable :: vxctotg(:,:)
     231              :  character(len=10) :: EPName(1:2)=(/"Electronic","Positronic"/)
     232              : ! *************************************************************************
     233              : 
     234         6302 :  call timab(37,1,tsec)
     235              :  ABI_NVTX_START_RANGE(NVTX_STRESS)
     236              : 
     237              : !Compute different geometric tensor, as well as ucvol, from rprimd
     238         6302 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     239              : 
     240         6302 :  opt_hybr=0;if (allocated(vxc_hf)) opt_hybr=1
     241         6302 :  icoulomb=0 ! not yet compatible with icoulomb
     242              : 
     243              : !=======================================================================
     244              : !========= Local pseudopotential and core charge contributions =========
     245              : !=======================================================================
     246              : 
     247              : !Determine by which method the local ionic potential and/or the pseudo core charge density
     248              : ! contributions have to be computed
     249              : !Local ionic potential:
     250              : ! Method 1: PAW
     251              : ! Method 2: Norm-conserving PP, icoulomb>0, wavelets
     252         6302 :  vloc_method=1;if (usepaw==0) vloc_method=2
     253         6302 :  if (psps%usewvl==1) vloc_method=2
     254              : !Pseudo core charge density:
     255              : ! Method 1: PAW, nc_xccc_gspace
     256              : ! Method 2: Norm-conserving PP, wavelets
     257              :  coredens_method=1;if (usepaw==0) coredens_method=2
     258         6302 :  if (psps%nc_xccc_gspace==1) coredens_method=1
     259         6302 :  if (psps%nc_xccc_gspace==0) coredens_method=2
     260         6302 :  if (psps%usewvl==1) coredens_method=2
     261         6302 :  coretau_method=0
     262         6302 :  if (usekden==1) then
     263           60 :    coretau_method=1;if (psps%nc_xccc_gspace==0) coretau_method=2
     264              :  end if
     265              : 
     266              : !Local ionic potential and/or pseudo core charge by method 1
     267         6302 :  if (vloc_method==1.or.coredens_method==1.or.coretau_method==1) then
     268         1398 :    call timab(551,1,tsec)
     269              : !  Compute Vxc in reciprocal space
     270         1398 :    if (coredens_method==1.and.n3xccc>0) then
     271         2823 :      ABI_MALLOC(v_dum,(nfft))
     272         2823 :      ABI_MALLOC(vxctotg,(2,nfft))
     273     34572887 :      v_dum(:)=vxc(:,1);if (nspden>=2) v_dum(:)=0.5_dp*(v_dum(:)+vxc(:,2))
     274          941 :      call fourdp(1,vxctotg,v_dum,-1,mpi_enreg,nfft,1,ngfft,0)
     275              :      call zerosym(vxctotg,2,ngfft(1),ngfft(2),ngfft(3),&
     276          941 : &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     277          941 :      ABI_FREE(v_dum)
     278              :    else
     279          457 :      ABI_MALLOC(vxctotg,(0,0))
     280              :    end if
     281              : !  Compute contribution to stresses from Vloc and/or pseudo core density
     282         1398 :    optv=0;if (vloc_method==1) optv=1
     283         1398 :    optn=0;if (coredens_method==1) optn=n3xccc/nfft
     284         1398 :    optatm=0;optdyfr=0;opteltfr=0;optgr=0;optstr=1;optn2=1
     285         1398 :    if (vloc_method==1.or.coredens_method==1) then
     286              :      call atm2fft(atindx1,dummy_out1,dummy_out2,dummy_out3,dummy_out4,&
     287              : &     dummy_out5,dummy_in,gmet,gprimd,dummy_out6,dummy_out7,gsqcut,&
     288              : &     mgfft,mqgrid,natom,nattyp,nfft,ngfft,ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,&
     289              : &     psps,pawtab,ph1d,qgrid,qprtrb_dum,dum_rcut,rhog,rprimd,corstr,lpsstr,ucvol,usepaw,vxctotg,vxctotg,vxctotg,vprtrb_dum,vlspl,&
     290              : &     comm_fft=mpi_enreg%comm_fft,me_g0=mpi_enreg%me_g0,&
     291         1398 : &     paral_kgb=mpi_enreg%paral_kgb,distribfft=mpi_enreg%distribfft)
     292              :    end if
     293         1398 :    if (n3xccc==0.and.coredens_method==1) corstr=zero
     294         1398 :    ABI_FREE(vxctotg)
     295         1398 :    if (usekden==1.and.usevxctau==1.and.coretau_method==1..and.n3xccc>0) then
     296              : !    Compute contribution to stresses from pseudo kinetic energy core density
     297           29 :      optv=0;optn=1;optn2=4
     298           87 :      ABI_MALLOC(v_dum,(nfft))
     299           87 :      ABI_MALLOC(vxctotg,(2,nfft))
     300      1353053 :      v_dum(:)=vxctau(:,1,1);if (nspden>=2) v_dum(:)=0.5_dp*(v_dum(:)+vxctau(:,2,1))
     301           29 :      call fourdp(1,vxctotg,v_dum,-1,mpi_enreg,nfft,1,ngfft,0)
     302              :      call zerosym(vxctotg,2,ngfft(1),ngfft(2),ngfft(3),&
     303           29 : &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     304           29 :      ABI_FREE(v_dum)
     305              :      call atm2fft(atindx1,dummy_out1,dummy_out2,dummy_out3,dummy_out4,&
     306              : &     dummy_out5,dummy_in,gmet,gprimd,dummy_out6,dummy_out7,gsqcut,&
     307              : &     mgfft,mqgrid,natom,nattyp,nfft,ngfft,ntypat,optatm,optdyfr,opteltfr,optgr,optn,optn2,optstr,optv,&
     308              : &     psps,pawtab,ph1d,qgrid,qprtrb_dum,dum_rcut,rhog,rprimd,taustr,dumstr,ucvol,usepaw,vxctotg,vxctotg,vxctotg,vprtrb_dum,vlspl,&
     309              : &     comm_fft=mpi_enreg%comm_fft,me_g0=mpi_enreg%me_g0,&
     310           29 : &     paral_kgb=mpi_enreg%paral_kgb,distribfft=mpi_enreg%distribfft)
     311          203 :      corstr(1:6)=corstr(1:6)+taustr(1:6)
     312           29 :      ABI_FREE(vxctotg)
     313              :    end if
     314         1398 :    call timab(551,2,tsec)
     315              :  end if
     316              : 
     317              : !Local ionic potential by method 2
     318         6302 :  if (vloc_method==2) then
     319         4907 :    option=3
     320        14721 :    ABI_MALLOC(dyfr_dum,(3,3,natom))
     321        14721 :    ABI_MALLOC(gr_dum,(3,natom))
     322        14721 :    ABI_MALLOC(v_dum,(nfft))
     323              :    call mklocl_recipspace(dyfr_dum,eei,gmet,gprimd,gr_dum,gsqcut,icutcoul,lpsstr,mgfft,&
     324              : &   mpi_enreg,mqgrid,natom,nattyp,nfft,ngfft,nkpt,ntypat,option,ph1d,qgrid,&
     325         4907 : &   qprtrb_dum,dum_rcut,rhog,rprimd,ucvol,vcutgeo,vlspl,vprtrb_dum,v_dum)
     326         4907 :    ABI_FREE(dyfr_dum)
     327         4907 :    ABI_FREE(gr_dum)
     328         4907 :    ABI_FREE(v_dum)
     329              :  end if
     330              : 
     331              : !Pseudo core electron density by method 2
     332         6302 :  if (coredens_method==2.or.coretau_method==2) then
     333         4904 :    if (n1xccc/=0) then
     334         1809 :      call timab(55,1,tsec)
     335         1809 :      option=3
     336         5427 :      ABI_MALLOC(dyfr_dum,(3,3,natom))
     337         5427 :      ABI_MALLOC(gr_dum,(3,natom))
     338         5427 :      ABI_MALLOC(v_dum,(nfft))
     339         1809 :      if (coredens_method==2) then
     340         1809 :        if (psps%usewvl==0.and.usepaw==0.and.icoulomb==0) then
     341         1809 :          if(opt_hybr==0) then
     342              :            call mkcore(corstr,dyfr_dum,gr_dum,mpi_enreg,natom,nfft,nspden,ntypat,ngfft(1),&
     343              : &           n1xccc,ngfft(2),ngfft(3),option,rprimd,typat,ucvol,vxc,&
     344         1779 : &           xcccrc,xccc1d,xccc3d,xred)
     345              :          else
     346              :            call mkcore(corstr,dyfr_dum,gr_dum,mpi_enreg,natom,nfft,nspden,ntypat,ngfft(1),&
     347              : &           n1xccc,ngfft(2),ngfft(3),option,rprimd,typat,ucvol,vxc_hf,&
     348           30 : &           xcccrc,xccc1d,xccc3d,xred)
     349              :          end if
     350            0 :        else if (psps%usewvl==0.and.(usepaw==1.or.icoulomb==1)) then
     351              :          call mkcore_alt(atindx1,corstr,dyfr_dum,gr_dum,icoulomb,mpi_enreg,natom,nfft,&
     352              : &         nspden,nattyp,ntypat,ngfft(1),n1xccc,ngfft(2),ngfft(3),option,rprimd,&
     353            0 : &         ucvol,vxc,xcccrc,xccc1d,xccc3d,xred,pawrad,pawtab,usepaw)
     354              :        end if
     355              :      end if
     356         1809 :      if (usekden==1.and.usevxctau==1.and.coretau_method==2) then
     357              :        call mkcore_alt(atindx1,taustr,dyfr_dum,gr_dum,icoulomb,mpi_enreg,natom,nfft,&
     358              : &       nspden,nattyp,ntypat,ngfft(1),n1xccc,ngfft(2),ngfft(3),option,rprimd,&
     359              : &       ucvol,vxctau(:,:,1),xcccrc,xccc1d,xcctau3d,xred,pawrad,pawtab,usepaw,&
     360            3 : &       usekden=.true.)
     361              :      end if
     362         1809 :      ABI_FREE(dyfr_dum)
     363         1809 :      ABI_FREE(gr_dum)
     364         1809 :      ABI_FREE(v_dum)
     365         1809 :      call timab(55,2,tsec)
     366              :    else
     367         3095 :      corstr(:)=zero
     368              :    end if
     369              :  end if
     370              : 
     371              : !=======================================================================
     372              : !======================= Hartree energy contribution ===================
     373              : !=======================================================================
     374              : 
     375         6302 :  call strhar(ehart,gsqcut,harstr,mpi_enreg,nfft,ngfft,rhog,rprimd)
     376              : 
     377              : !=======================================================================
     378              : !======================= Ewald contribution ============================
     379              : !=======================================================================
     380              : 
     381         6302 :  call timab(38,1,tsec)
     382         6302 :  call ewald2(gmet,natom,ntypat,rmet,rprimd,ewestr,typat,ucvol,xred,zion)
     383              : 
     384              : !=======================================================================
     385              : !================== VdW DFT-D contribution ============================
     386              : !=======================================================================
     387              : 
     388         6302 :  if (vdw_xc==5) then
     389              :    call vdw_dftd2(e_dum,ixc,natom,ntypat,0,typat,rprimd,vdw_tol,&
     390           10 : &   xred,znucl,str_vdw_dftd2=vdwstr)
     391         6292 :  elseif (vdw_xc==6.or.vdw_xc==7) then
     392              :    call vdw_dftd3(e_dum,ixc,natom,ntypat,0,typat,rprimd,vdw_xc,&
     393            7 : &   vdw_tol,vdw_tol_3bt,xred,znucl,str_vdw_dftd3=vdwstr)
     394              :  end if
     395              : 
     396         6302 :  call timab(38,2,tsec)
     397              : 
     398              : !HONG  no Berry phase contribution if using reduced ebar or d according to
     399              : !HONG  PRL 89, 117602 (2002) [[cite:Souza2002]]
     400              : !HONG  Nature Physics: M. Stengel et.al. (2009)) [[cite:Stengel1999]]
     401              : !=======================================================================
     402              : !=================== Berry phase contribution ==========================
     403              : !=======================================================================
     404              : 
     405              : !if (berryopt==4) then
     406              : !berrystr_tmp(:,:) = zero
     407              : !Diagonal:
     408              : !do mu = 1, 3
     409              : !do ii = 1, 3
     410              : !berrystr_tmp(mu,mu) = berrystr_tmp(mu,mu) - &
     411              : !&       efield(mu)*rprimd(mu,ii)*(pel(ii) + pion(ii))/ucvol
     412              : !end do
     413              : !end do
     414              : !Off-diagonal (symmetrized before adding it to strten):
     415              : !do ii = 1, 3
     416              : !berrystr_tmp(3,2) = berrystr_tmp(3,2) &
     417              : !&     - efield(3)*rprimd(2,ii)*(pel(ii) + pion(ii))/ucvol
     418              : !berrystr_tmp(2,3) = berrystr_tmp(2,3) &
     419              : !&     - efield(2)*rprimd(3,ii)*(pel(ii) + pion(ii))/ucvol
     420              : !berrystr_tmp(3,1) = berrystr_tmp(3,1) &
     421              : !&     - efield(3)*rprimd(1,ii)*(pel(ii) + pion(ii))/ucvol
     422              : !berrystr_tmp(1,3) = berrystr_tmp(1,3) &
     423              : !&     - efield(1)*rprimd(3,ii)*(pel(ii) + pion(ii))/ucvol
     424              : !berrystr_tmp(2,1) = berrystr_tmp(2,1) &
     425              : !&     - efield(2)*rprimd(1,ii)*(pel(ii) + pion(ii))/ucvol
     426              : !berrystr_tmp(1,2) = berrystr_tmp(1,2) &
     427              : !&     - efield(1)*rprimd(2,ii)*(pel(ii) + pion(ii))/ucvol
     428              : !end do
     429              : !berrystr(1) = berrystr_tmp(1,1)
     430              : !berrystr(2) = berrystr_tmp(2,2)
     431              : !berrystr(3) = berrystr_tmp(3,3)
     432              : !berrystr(4) = (berrystr_tmp(3,2) + berrystr_tmp(2,3))/two
     433              : !berrystr(5) = (berrystr_tmp(3,1) + berrystr_tmp(1,3))/two
     434              : !berrystr(6) = (berrystr_tmp(2,1) + berrystr_tmp(1,2))/two
     435              : !end if
     436              : 
     437              : !=======================================================================
     438              : !================= Other (trivial) contributions =======================
     439              : !=======================================================================
     440              : 
     441              : !Nonlocal part of stress has already been computed
     442              : !(in forstrnps(norm-conserving) or pawgrnl(PAW))
     443              : 
     444              : !Kinetic part of stress has already been computed
     445              : !(in forstrnps)
     446              : 
     447              : !cDFT part of stress tensor has already been computed in "constrained_residual"
     448              : 
     449              : !XC part of stress tensor has already been computed in "strsxc"
     450              : 
     451              : !ii part of stress (diagonal) is trivial!
     452         6302 :  strsii=-eii/ucvol
     453              : !qvpotzero is non zero, only when usepotzero=1
     454         6302 :  strsii=strsii+qvpotzero/ucvol
     455              : 
     456              : !======================================================================
     457              : !HONG  Maxwell stress when electric/displacement field is non-zero=====
     458              : !======================================================================
     459              :  efield_flag = (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or. &
     460         6302 : & berryopt==14 .or. berryopt==16 .or. berryopt==17)
     461         6343 :  calc_epaw3_stress = (efield_flag .and. usepaw == 1)
     462              :  if ( efield_flag ) then
     463          100 :    ModE=dot_product(efield,efield)
     464          100 :    do ii=1,3
     465          100 :      Maxstr(ii)=two*efield(ii)*efield(ii)-ModE
     466              :    end do
     467           25 :    Maxstr(4)=two*efield(3)*efield(2)
     468           25 :    Maxstr(5)=two*efield(3)*efield(1)
     469           25 :    Maxstr(6)=two*efield(2)*efield(1)
     470              : !  Converting to units of Ha/Bohr^3
     471              : !  Maxstr(:)=Maxstr(:)*e_Cb*Bohr_Ang*1.0d-10/(Ha_J*8.0d0*pi)
     472              : 
     473          175 :    Maxstr(:)=Maxstr(:)*eps0*Ha_J*Bohr_Ang*1.0d-10/(8.0d0*pi*e_Cb**2)
     474              : 
     475           25 :    write(message, '(a,a)' )ch10,&
     476           50 : &   ' Cartesian components of Maxwell stress tensor (hartree/bohr^3)'
     477           25 :    call wrtout(ab_out,message,'COLL')
     478           25 :    call wrtout(std_out,  message,'COLL')
     479              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     480           25 : &   ' Maxstr(1 1)=',Maxstr(1),' Maxstr(3 2)=',Maxstr(4)
     481           25 :    call wrtout(ab_out,message,'COLL')
     482           25 :    call wrtout(std_out,  message,'COLL')
     483              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     484           25 : &   ' Maxstr(2 2)=',Maxstr(2),' Maxstr(3 1)=',Maxstr(5)
     485           25 :    call wrtout(ab_out,message,'COLL')
     486           25 :    call wrtout(std_out,  message,'COLL')
     487              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     488           25 : &   ' Maxstr(3 3)=',Maxstr(3),' Maxstr(2 1)=',Maxstr(6)
     489           25 :    call wrtout(ab_out,message,'COLL')
     490           25 :    call wrtout(std_out,  message,'COLL')
     491           25 :    write(message, '(a)' ) ' '
     492           25 :    call wrtout(ab_out,message,'COLL')
     493           25 :    call wrtout(std_out,  message,'COLL')
     494              : 
     495              :  end if
     496              : 
     497              : ! compute additional F3-type stress due to projectors for electric field with PAW
     498           25 :  if ( efield_flag .and. calc_epaw3_stress ) then
     499           63 :    do sdir = 1, 6
     500           54 :      ep3(:) = zero
     501          216 :      do idir = 1, 3
     502          162 :        vol_element=one/(ucvol*dtefield%nstr(idir)*dtefield%nkstr(idir))
     503          540 :        do iatom = 1, natom
     504          486 :          ep3(idir) = ep3(idir) + vol_element*dtefield%epaws3(iatom,idir,sdir)
     505              :        end do ! end loop over atoms
     506              :      end do ! end loop over idir (components of P)
     507              : ! note no appearance of ucvol here unlike in forces, stress definition includes
     508              : ! division by ucvol, which cancels the factor in -ucvol e . p
     509          225 :      epaws3red(sdir) = -dot_product(red_efieldbar(1:3),ep3(1:3))
     510              :    end do
     511              : 
     512              : !   write(message, '(a,a)' )ch10,&
     513              : !&   ' Cartesian components of PAW sigma_3 stress tensor (hartree/bohr^3)'
     514              : !   call wrtout(ab_out,message,'COLL')
     515              : !   call wrtout(std_out,  message,'COLL')
     516              : !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     517              : !&   ' epaws3red(1 1)=',epaws3red(1),' epaws3red(3 2)=',epaws3red(4)
     518              : !   call wrtout(ab_out,message,'COLL')
     519              : !   call wrtout(std_out,  message,'COLL')
     520              : !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     521              : !&   ' epaws3red(2 2)=',epaws3red(2),' epaws3red(3 1)=',epaws3red(5)
     522              : !   call wrtout(ab_out,message,'COLL')
     523              : !   call wrtout(std_out,  message,'COLL')
     524              : !   write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     525              : !&   ' epaws3red(3 3)=',epaws3red(3),' epaws3red(2 1)=',epaws3red(6)
     526              : !   call wrtout(ab_out,message,'COLL')
     527              : !   call wrtout(std_out,  message,'COLL')
     528              : !   write(message, '(a)' ) ' '
     529              : !   call wrtout(ab_out,message,'COLL')
     530              : !   call wrtout(std_out,  message,'COLL')
     531              : 
     532              :  end if
     533              : 
     534              : !=======================================================================
     535              : !===== Assemble the various contributions to the stress tensor =========
     536              : !=======================================================================
     537              : !In cartesian coordinates (symmetric storage)
     538              : 
     539        44114 :  strten(:)=kinstr(:)+ewestr(:)+corstr(:)+strscondft(:)+strsxc(:)+harstr(:)+lpsstr(:)+nlstr(:)+mggastr(:)
     540              : 
     541         6302 :  if (usefock==1 .and. associated(fock)) then
     542          121 :    if (fock%fock_common%optstr) then
     543          847 :      strten(:)=strten(:)+fock%fock_common%stress(:)
     544              :    end if
     545              :  end if
     546              : 
     547              : !Add contributions for constant E or D calculation.
     548         6302 :  if ( efield_flag ) then
     549          175 :    strten(:)=strten(:)+Maxstr(:)
     550           79 :    if ( calc_epaw3_stress ) strten(:) = strten(:) + epaws3red(:)
     551              :  end if
     552         6404 :  if (vdw_xc>=5.and.vdw_xc<=7) strten(:)=strten(:)+vdwstr(:)
     553              : 
     554              : !Additional stuff for electron-positron
     555         6302 :  ipositron=0
     556         6302 :  if (present(electronpositron)) then
     557         6302 :    if (associated(electronpositron)) then
     558            1 :      if (allocated(electronpositron%stress_ep)) ipositron=electronpositron_calctype(electronpositron)
     559              :    end if
     560              :  end if
     561            1 :  if (abs(ipositron)==1) then
     562            7 :    strten(:)=strten(:)-harstr(:)-ewestr(:)-corstr(:)-lpsstr(:)
     563            1 :    harstr(:)=zero;ewestr(:)=zero;corstr(:)=zero;strsii=zero
     564           10 :    lpsstr(:)=-lpsstr(:);lpsstr(1:3)=lpsstr(1:3)-two*eei/ucvol
     565            7 :    strten(:)=strten(:)+lpsstr(:)
     566            1 :    if (vdw_xc>=5.and.vdw_xc<=7) strten(:)=strten(:)-vdwstr(:)
     567            1 :    if (vdw_xc>=5.and.vdw_xc<=7) vdwstr(:)=zero
     568              :  end if
     569         6302 :  if (abs(ipositron)==2) then
     570            0 :    ABI_MALLOC(rhog_ep,(2,nfft))
     571            0 :    ABI_MALLOC(dummy,(6))
     572            0 :    call fourdp(1,rhog_ep,electronpositron%rhor_ep,-1,mpi_enreg,nfft,1,ngfft,0)
     573            0 :    rhog_ep=-rhog_ep
     574            0 :    call strhar(electronpositron%e_hartree,gsqcut,dummy,mpi_enreg,nfft,ngfft,rhog_ep,rprimd)
     575            0 :    strten(:)=strten(:)+dummy(:);harstr(:)=harstr(:)+dummy(:)
     576            0 :    ABI_FREE(rhog_ep)
     577            0 :    ABI_FREE(dummy)
     578              :  end if
     579         6308 :  if (ipositron>0) strten(:)=strten(:)+electronpositron%stress_ep(:)
     580              : 
     581              : !Symmetrize resulting tensor if nsym>1
     582         6302 :  if (nsym>1) then
     583         4850 :    call stresssym(gprimd,nsym,strten,symrec)
     584              :  end if
     585              : 
     586              : !Set to zero very small values of stress
     587        44114 :  do mu=1,6
     588        44114 :    if (abs(strten(mu))<tol) strten(mu)=zero
     589              :  end do
     590              : 
     591              : !Include diagonal terms, save uncorrected stress for output
     592        25208 :  do mu=1,3
     593        18906 :    uncorr(mu)=strten(mu)+strsii
     594        25208 :    strten(mu)=uncorr(mu)
     595              :  end do
     596              : 
     597              : !Adding the extfpmd continous contribution to stress tensor
     598         6302 :  if(associated(extfpmd)) then
     599           28 :    strten(1:3)=strten(1:3)-(2./3.)*extfpmd%e_kinetic/extfpmd%ucvol
     600              :  end if
     601              : 
     602              : !=======================================================================
     603              : !================ Print out info about stress tensor ===================
     604              : !=======================================================================
     605         6302 :  if (prtvol>=10.and.ipositron>=0) then
     606          244 :    write(message, '(a)' ) ' '
     607          244 :    call wrtout(std_out,message,'COLL')
     608         1708 :    do mu=1,6
     609              :      write(message, '(a,i5,a,1p,e22.12)' )&
     610         1464 : &     ' stress: component',mu,' of hartree stress is',harstr(mu)
     611         1708 :      call wrtout(std_out,message,'COLL')
     612              :    end do
     613          244 :    write(message, '(a)' ) ' '
     614          244 :    call wrtout(std_out,message,'COLL')
     615         1708 :    do mu=1,6
     616              :      write(message, '(a,i5,a,1p,e22.12)' )&
     617         1464 : &     ' stress: component',mu,' of loc psp stress is',lpsstr(mu)
     618         1708 :      call wrtout(std_out,message,'COLL')
     619              :    end do
     620          244 :    write(message, '(a)' ) ' '
     621          244 :    call wrtout(std_out,message,'COLL')
     622         1708 :    do mu=1,6
     623              :      write(message, '(a,i5,a,1p,e22.12)' )&
     624         1464 : &     ' stress: component',mu,&
     625         2928 : &     ' of kinetic stress is',kinstr(mu)
     626         1708 :      call wrtout(std_out,message,'COLL')
     627              :    end do
     628          244 :    if (usekden>0) then
     629            0 :      write(message, '(a)' ) ' '
     630            0 :      call wrtout(std_out,message,'COLL')
     631            0 :      do mu=1,6
     632              :        write(message, '(a,i5,a,1p,e22.12)' )&
     633            0 : &       ' stress: component',mu,&
     634            0 : &       ' of metaGGA stress is',mggastr(mu)
     635            0 :        call wrtout(std_out,message,'COLL')
     636              :      end do
     637              :    end if
     638          244 :    write(message, '(a)' ) ' '
     639          244 :    call wrtout(std_out,message,'COLL')
     640         1708 :    do mu=1,6
     641              :      write(message, '(a,i5,a,1p,e22.12)' )&
     642         1464 : &     ' stress: component',mu,' of nonlocal ps stress is',nlstr(mu)
     643         1708 :      call wrtout(std_out,message,'COLL')
     644              :    end do
     645          244 :    write(message, '(a)' ) ' '
     646          244 :    call wrtout(std_out,message,'COLL')
     647         1708 :    do mu=1,6
     648              :      write(message, '(a,i5,a,1p,e22.12)' )&
     649         1464 : &     ' stress: component',mu,' of     core xc stress is',corstr(mu)
     650         1708 :      call wrtout(std_out,message,'COLL')
     651              :    end do
     652          244 :    write(message, '(a)' ) ' '
     653          244 :    call wrtout(std_out,message,'COLL')
     654         1708 :    do mu=1,6
     655              :      write(message, '(a,i5,a,1p,e22.12)' )&
     656         1464 : &     ' stress: component',mu,&
     657         2928 : &     ' of Ewald energ stress is',ewestr(mu)
     658         1708 :      call wrtout(std_out,message,'COLL')
     659              :    end do
     660          244 :    write(message, '(a)' ) ' '
     661          244 :    call wrtout(std_out,message,'COLL')
     662         1708 :    do mu=1,6
     663              :      write(message, '(a,i5,a,1p,e22.12)' ) &
     664         1464 : &     ' stress: component',mu,' of xc stress is',strsxc(mu)
     665         1708 :      call wrtout(std_out,message,'COLL')
     666              :    end do
     667              : 
     668         1708 :    if( any( abs(strscondft(:))>tol8 ) )then
     669            0 :      write(message, '(a)' ) ' '
     670            0 :      call wrtout(std_out,message,'COLL')
     671            0 :      do mu=1,6
     672              :        write(message, '(a,i5,a,1p,e22.12)' ) &
     673            0 : &       ' stress: component',mu,' of cDFT stress is',strscondft(mu)
     674            0 :        call wrtout(std_out,message,'COLL')
     675              :      end do
     676              :    endif
     677              : 
     678          244 :    if (vdw_xc>=5.and.vdw_xc<=7) then
     679            0 :      write(message, '(a)' ) ' '
     680            0 :      call wrtout(std_out,message,'COLL')
     681            0 :      do mu=1,6
     682              :        write(message, '(a,i5,a,1p,e22.12)' )&
     683            0 : &       ' stress: component',mu,&
     684            0 : &       ' of VdW DFT-D stress is',vdwstr(mu)
     685            0 :        call wrtout(std_out,message,'COLL')
     686              :      end do
     687              :    end if
     688          244 :    write(message, '(a)' ) ' '
     689          244 :    call wrtout(std_out,message,'COLL')
     690              :    write(message, '(a,1p,e22.12)' ) &
     691          244 : &   ' stress: ii (diagonal) part is',strsii
     692          244 :    call wrtout(std_out,message,'COLL')
     693              :    if (berryopt==4 .or. berryopt==6 .or. berryopt==7 .or.  &
     694              : &   berryopt==14 .or. berryopt==16 .or. berryopt==17) then  !!HONG
     695            0 :      write(message, '(a)' ) ' '
     696            0 :      call wrtout(std_out,message,'COLL')
     697            0 :      do mu = 1, 6
     698              :        write(message, '(a,i2,a,1p,e22.12)' )&
     699            0 : &       ' stress: component',mu,' of Maxwell stress is',&
     700            0 : &       Maxstr(mu)
     701            0 :        call wrtout(std_out,message,'COLL')
     702              :      end do
     703              :    end if
     704          244 :    if (ipositron/=0) then
     705            0 :      write(message, '(a)' ) ' '
     706            0 :      call wrtout(std_out,message,'COLL')
     707            0 :      do mu=1,6
     708              :        write(message, '(a,i5,3a,1p,e22.12)' ) &
     709            0 : &       ' stress: component',mu,' of ',EPName(abs(ipositron)), &
     710            0 : &       ' stress is',electronpositron%stress_ep(mu)
     711            0 :        call wrtout(std_out,message,'COLL')
     712              :      end do
     713              :    end if
     714              : 
     715              :  end if ! prtvol
     716         6058 :  if (ipositron>=0) then
     717         6302 :    write(message, '(a,a)' )ch10,&
     718        12604 : &   ' Cartesian components of stress tensor (hartree/bohr^3)'
     719         6302 :    call wrtout(ab_out,message,'COLL')
     720         6302 :    call wrtout(std_out,  message,'COLL')
     721              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     722         6302 : &   '  sigma(1 1)=',strten(1),'  sigma(3 2)=',strten(4)
     723         6302 :    call wrtout(ab_out,message,'COLL')
     724         6302 :    call wrtout(std_out,  message,'COLL')
     725              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     726         6302 : &   '  sigma(2 2)=',strten(2),'  sigma(3 1)=',strten(5)
     727         6302 :    call wrtout(ab_out,message,'COLL')
     728         6302 :    call wrtout(std_out,  message,'COLL')
     729              :    write(message, '(a,1p,e16.8,a,1p,e16.8)' ) &
     730         6302 : &   '  sigma(3 3)=',strten(3),'  sigma(2 1)=',strten(6)
     731         6302 :    call wrtout(ab_out,message,'COLL')
     732         6302 :    call wrtout(std_out,  message,'COLL')
     733         6302 :    write(message, '(a)' ) ' '
     734         6302 :    call wrtout(ab_out,message,'COLL')
     735         6302 :    call wrtout(std_out,  message,'COLL')
     736              :  end if
     737              :  ABI_NVTX_END_RANGE()
     738         6302 :  call timab(37,2,tsec)
     739              : 
     740         6302 : end subroutine stress
     741              : !!***
     742              : 
     743              : !!****f* ABINIT/strhar
     744              : !!
     745              : !! NAME
     746              : !! strhar
     747              : !!
     748              : !! FUNCTION
     749              : !! Compute Hartree energy contribution to stress tensor (Cartesian coordinates).
     750              : !!
     751              : !! INPUTS
     752              : !!  ehart=Hartree energy (hartree)
     753              : !!  gsqcut=cutoff value on $G^2$ for (large) sphere inside fft box.
     754              : !!  $gsqcut=(boxcut^2)*ecut/(2._dp*(\pi^2))$
     755              : !!  mpi_enreg=information about MPI parallelization
     756              : !!  nfft=(effective) number of FFT grid points (for this processor)
     757              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     758              : !!  rhog(2,nfft)=Fourier transform of charge density (bohr^-3)
     759              : !!  rhog(2,nfft)= optional argument: Fourier transform of a second charge density (bohr^-3)
     760              : !!  rprimd(3,3)=dimensional primitive translations in real space (bohr)
     761              : !!
     762              : !! OUTPUT
     763              : !!  harstr(6)=components of Hartree part of stress tensor
     764              : !!   (Cartesian coordinates, symmetric tensor) in hartree/bohr^3
     765              : !!   Definition of symmetric tensor storage: store 6 unique components
     766              : !!   in the order 11, 22, 33, 32, 31, 21 (suggested by Xavier Gonze).
     767              : !!
     768              : !! SOURCE
     769              : 
     770         6302 : subroutine strhar(ehart,gsqcut,harstr,mpi_enreg,nfft,ngfft,rhog,rprimd,&
     771              : &                 rhog2) ! optional argument
     772              : 
     773              : !Arguments ------------------------------------
     774              : !scalars
     775              :  integer,intent(in) :: nfft
     776              :  real(dp),intent(in) :: ehart,gsqcut
     777              :  type(MPI_type),intent(in) :: mpi_enreg
     778              : !arrays
     779              :  integer,intent(in) :: ngfft(18)
     780              :  real(dp),intent(in) :: rprimd(3,3),rhog(2,nfft)
     781              :  real(dp),intent(in),optional :: rhog2(2,nfft)
     782              :  real(dp),intent(out) :: harstr(6)
     783              : 
     784              : !Local variables-------------------------------
     785              : !scalars
     786              :  integer,parameter :: im=2,re=1
     787              :  integer :: i1,i2,i3,id1,id2,id3,ierr,ig1,ig2,ig3,ii,irho2,me_fft,n1,n2,n3,nproc_fft
     788              :  real(dp) :: cutoff,gsquar,rhogsq,tolfix=1.000000001_dp,ucvol
     789              : !arrays
     790              :  real(dp) :: gcart(3),gmet(3,3),gprimd(3,3),rmet(3,3),tsec(2)
     791         6302 :  integer, contiguous, pointer :: fftn2_distrib(:),ffti2_local(:)
     792         6302 :  integer, contiguous, pointer :: fftn3_distrib(:),ffti3_local(:)
     793              : ! *************************************************************************
     794              : 
     795         6302 :  call timab(568,1,tsec)
     796              : 
     797         6302 :  harstr(:)=zero
     798              : !ehtest=0.0_dp (used for testing)
     799              : 
     800         6302 :  call metric(gmet,gprimd,-1,rmet,rprimd,ucvol)
     801              : 
     802         6302 :  irho2=0;if (present(rhog2)) irho2=1
     803              : 
     804              : !Conduct looping over all fft grid points to find G vecs inside gsqcut
     805              : !Include G**2 on surface of cutoff sphere as well as inside:
     806         6302 :  cutoff=gsqcut*tolfix
     807         6302 :  n1=ngfft(1) ; n2=ngfft(2) ; n3=ngfft(3)
     808         6302 :  me_fft=ngfft(11)
     809         6302 :  nproc_fft=ngfft(10)
     810         6302 :  id1=n1/2+2
     811         6302 :  id2=n2/2+2
     812         6302 :  id3=n3/2+2
     813         6302 :  ii=0
     814              : 
     815              :  ! Get the distrib associated with this fft_grid
     816         6302 :  call ptabs_fourdp(mpi_enreg,n2,n3,fftn2_distrib,ffti2_local,fftn3_distrib,ffti3_local)
     817              : 
     818       147626 :  do i3=1,n3
     819       141324 :    ig3=i3-(i3/id3)*n3-1
     820      3993293 :    do i2=1,n2
     821      3845667 :      ig2=i2-(i2/id2)*n2-1
     822      3986991 :      if (fftn2_distrib(i2)==me_fft) then
     823    140673931 :        do i1=1,n1
     824    137080160 :          ig1=i1-(i1/id1)*n1-1
     825              : !        ii=ii+1
     826    137080160 :          ii=i1+n1*(ffti2_local(i2)-1+(n2/nproc_fft)*(i3-1))
     827              : !        **     GET RID OF THIS IF STATEMENT LATER for speed if needed
     828              : !        Avoid G=0:
     829              : !        if (ii>1) then
     830    137080160 :          if (ig1==0 .and. ig2==0 .and. ig3==0) cycle
     831              : !        Compute cartesian components of G
     832    137074080 :          gcart(1)=gprimd(1,1)*dble(ig1)+gprimd(1,2)*dble(ig2)+gprimd(1,3)*dble(ig3)
     833    137074080 :          gcart(2)=gprimd(2,1)*dble(ig1)+gprimd(2,2)*dble(ig2)+gprimd(2,3)*dble(ig3)
     834    137074080 :          gcart(3)=gprimd(3,1)*dble(ig1)+gprimd(3,2)*dble(ig2)+gprimd(3,3)*dble(ig3)
     835              : !        Compute |G|^2
     836    137074080 :          gsquar=gcart(1)**2+gcart(2)**2+gcart(3)**2
     837              : 
     838              : !        Keep only G**2 inside larger cutoff (not sure this is needed):
     839    140667851 :          if (gsquar<=cutoff) then
     840              : !          take |rho(G)|^2 for complex rhog
     841     55483159 :            if (irho2==0) then
     842     55483159 :              rhogsq=rhog(re,ii)**2+rhog(im,ii)**2
     843              :            else
     844            0 :              rhogsq=rhog(re,ii)*rhog2(re,ii)+rhog(im,ii)*rhog2(im,ii)
     845              :            end if
     846     55483159 :            harstr(1)=harstr(1)+(rhogsq/gsquar**2)*gcart(1)*gcart(1)
     847     55483159 :            harstr(2)=harstr(2)+(rhogsq/gsquar**2)*gcart(2)*gcart(2)
     848     55483159 :            harstr(3)=harstr(3)+(rhogsq/gsquar**2)*gcart(3)*gcart(3)
     849     55483159 :            harstr(4)=harstr(4)+(rhogsq/gsquar**2)*gcart(3)*gcart(2)
     850     55483159 :            harstr(5)=harstr(5)+(rhogsq/gsquar**2)*gcart(3)*gcart(1)
     851     55483159 :            harstr(6)=harstr(6)+(rhogsq/gsquar**2)*gcart(2)*gcart(1)
     852              :          end if
     853              : !        end if
     854              :        end do
     855              :      end if
     856              :    end do
     857              :  end do
     858              : 
     859              : !DO not remove : seems needed to avoid problem with pathscale compiler, in parallel
     860              : #ifdef FC_IBM
     861              :  write(std_out,*)' strhar : before mpi_comm, harstr=',harstr
     862              : #endif
     863              : 
     864              : !Init mpi_comm
     865         6302 :  if(mpi_enreg%nproc_fft>1)then
     866          436 :    call timab(48,1,tsec)
     867          436 :    call xmpi_sum(harstr,mpi_enreg%comm_fft ,ierr)
     868          436 :    call timab(48,2,tsec)
     869              :  end if
     870              : 
     871              : #ifdef FC_IBM
     872              : !DO not remove : seems needed to avoid problem with pathscale compiler, in parallel
     873              :  write(std_out,*)' strhar : after mpi_comm, harstr=',harstr
     874              :  write(std_out,*)' strhar : ehart,ucvol=',ehart,ucvol
     875              : #endif
     876              : 
     877              : !Normalize and add term -ehart/ucvol on diagonal
     878         6302 :  harstr(1)=harstr(1)/pi-ehart/ucvol
     879         6302 :  harstr(2)=harstr(2)/pi-ehart/ucvol
     880         6302 :  harstr(3)=harstr(3)/pi-ehart/ucvol
     881         6302 :  harstr(4)=harstr(4)/pi
     882         6302 :  harstr(5)=harstr(5)/pi
     883         6302 :  harstr(6)=harstr(6)/pi
     884              : 
     885         6302 :  call timab(568,2,tsec)
     886              : 
     887         6302 : end subroutine strhar
     888              : !!***
     889              : 
     890              : end module m_stress
     891              : !!***
        

Generated by: LCOV version 2.3-1