LCOV - code coverage report
Current view: top level - src/62_poisson - m_barevcoul.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 50.8 % 238 121
Test Date: 2026-11-09 13:21:34 Functions: 33.3 % 3 1
Branches: 42.1 % 361 152

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_barevcoul
       2                 :             : !! NAME
       3                 :             : !!  m_barevcoul
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !! Copyright (C) 1999-2026 ABINIT group ()
       9                 :             : !! This file is distributed under the terms of the
      10                 :             : !! GNU General Public License, see ~abinit/COPYING
      11                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      12                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_barevcoul
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_errors
      27                 :             :  use m_xmpi
      28                 :             : 
      29                 :             :  use m_fstrings,        only : sjoin
      30                 :             :  use defs_abitypes,     only : MPI_type
      31                 :             :  use m_numeric_tools,   only : arth, l2norm, OPERATOR(.x.)
      32                 :             :  use m_geometry,        only : normv
      33                 :             :  use m_crystal,         only : crystal_t
      34                 :             :  use m_fft,             only : zerosym
      35                 :             :  !use m_gsphere,         only : gsphere_t
      36                 :             : 
      37                 :             : ! Cut-off methods modules
      38                 :             :  !use m_cutoff_sphere,   only : cutoff_sphere
      39                 :             :  !use m_cutoff_slab,     only : cutoff_slab
      40                 :             :  !use m_cutoff_cylinder, only : cutoff_cylinder
      41                 :             : 
      42                 :             :  implicit none
      43                 :             : 
      44                 :             :  private
      45                 :             : !!***
      46                 :             : 
      47                 :             : !!****t* m_barevcoul/vcut_t
      48                 :             : !! NAME
      49                 :             : !!  vcoul_t
      50                 :             : !!
      51                 :             : !! FUNCTION
      52                 :             : !!
      53                 :             : !! SOURCE
      54                 :             : 
      55                 :             :  type,public :: vcut_t
      56                 :             : 
      57                 :             :   integer  :: nfft
      58                 :             :   ! Number of points in FFT grid
      59                 :             : 
      60                 :             :   integer  :: ng
      61                 :             :    ! Number of G-vectors
      62                 :             : 
      63                 :             :   real(dp) :: alpha(3)
      64                 :             :    ! Lenght of the finite slab
      65                 :             : 
      66                 :             :   real(dp) :: rcut
      67                 :             :    ! Cutoff radius
      68                 :             : 
      69                 :             :   real(dp) :: i_sz
      70                 :             :    ! Value of the integration of the Coulomb singularity 4\pi/V_BZ \int_BZ d^3q 1/q^2
      71                 :             : 
      72                 :             :   real(dp) :: hcyl
      73                 :             :    ! Length of the finite cylinder along the periodic dimension
      74                 :             : 
      75                 :             :   real(dp) :: ucvol
      76                 :             :     ! Volume of the unit cell
      77                 :             : 
      78                 :             :   character(len=50) :: mode
      79                 :             :    ! String defining the cutoff mode, possible values are: sphere,cylinder,slab,crystal
      80                 :             : 
      81                 :             :   integer :: pdir(3)
      82                 :             :    ! 1 if the system is periodic along this direction
      83                 :             : 
      84                 :             :   real(dp) :: boxcenter(3)
      85                 :             :    ! 1 if the point in inside the cutoff region 0 otherwise
      86                 :             :    ! Reduced coordinates of the center of the box (input variable)
      87                 :             : 
      88                 :             :   real(dp) :: vcutgeo(3)
      89                 :             :     ! For each reduced direction gives the length of the finite system
      90                 :             :     ! 0 if the system is infinite along that particular direction
      91                 :             :     ! negative value to indicate that a finite size has to be used
      92                 :             : 
      93                 :             :   real(dp) :: rprimd(3,3)
      94                 :             :     ! Lattice vectors in real space.
      95                 :             : 
      96                 :             :   real(dp),allocatable :: qibz(:,:)
      97                 :             :    ! qibz(3,nqibz)
      98                 :             :    ! q-points in the IBZ.
      99                 :             : 
     100                 :             :   real(dp),allocatable :: barev(:)
     101                 :             :     ! barev(nfft)
     102                 :             :     ! Bare Coulomb potential on the FFT grid
     103                 :             :     ! A cut might be applied.
     104                 :             : 
     105                 :             :  end type vcut_t
     106                 :             : 
     107                 :             :  public :: barevcoul
     108                 :             : !!***
     109                 :             : 
     110                 :             : contains
     111                 :             : !!***
     112                 :             : 
     113                 :             : !----------------------------------------------------------------------
     114                 :             : 
     115                 :             : !!****f* ABINIT/barevcoul
     116                 :             : !! NAME
     117                 :             : !! barevcoul
     118                 :             : !!
     119                 :             : !! FUNCTION
     120                 :             : !! Compute bare coulomb term in G-space on the FFT mesh i.e. 4pi/(G+q)**2 for a specified q-point
     121                 :             : !!
     122                 :             : !! INPUTS
     123                 :             : !!  qpoint(3)=reduced coordinates for the phonon wavelength
     124                 :             : !!  gsqcut=cutoff value on G**2 for sphere inside fft box. (gsqcut=(boxcut**2)*ecut/(2.d0*(Pi**2))
     125                 :             : !!  icutcoul=Option for the Coulomb potential cutoff technique
     126                 :             : !!  gmet(3,3)=metrix tensor in G space in Bohr**-2.
     127                 :             : !!  izero=if 1, unbalanced components of V(q,g) are set to zero # Used by the PAW library
     128                 :             : !!  nfft=Total number of FFT grid points.
     129                 :             : !!  ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
     130                 :             : !!  comm=MPI communicator.
     131                 :             : !!  [i_sz]=Integral of the q --> 0 singularity, used for the q+G=0 component with icutcoul=6 and 7
     132                 :             : !!         (auxiliary function of Carrier et al. or Gaussian one, computed by carrier_isz_gmet or gb_isz
     133                 :             : !!         in fock_init). Required for icutcoul=6 and 7.
     134                 :             : !!
     135                 :             : !! OUTPUT
     136                 :             : !!  barev(nfft)=4pi/(G+q)**2, q+G=0 component is set carefully
     137                 :             : !!
     138                 :             : !! NOTES
     139                 :             : !!  This routine operates on the full FFT mesh. DO NOT PASS MPI_TYPE
     140                 :             : !!  One can easily implemente MPI-FFT by just calling this routine and then
     141                 :             : !!  extracting the G-vectors treated by the node.
     142                 :             : !!
     143                 :             : !! SOURCE
     144                 :             : 
     145                 :      214670 : subroutine barevcoul(rcut,icutcoul,qpoint,gsqcut,gmet,nfft,nkpt_bz,ngfft,ucvol,izero,barev,shortrange,i_sz)
     146                 :             : 
     147                 :             : !Arguments ------------------------------------
     148                 :             : !scalars
     149                 :             :  integer,intent(in)         :: icutcoul,nfft,nkpt_bz,izero
     150                 :             :  real(dp),intent(in)        :: rcut,gsqcut,ucvol
     151                 :             :  logical,intent(in),optional:: shortrange
     152                 :             :  real(dp),intent(in),optional :: i_sz
     153                 :             : !arrays
     154                 :             :  integer,intent(in)         :: ngfft(18)
     155                 :             :  integer                    :: ng!!!!
     156                 :             :  real(dp),intent(in)        :: qpoint(3)
     157                 :             :  real(dp),intent(inout)     :: gmet(3,3)
     158                 :             :  real(dp),intent(inout)     :: barev(nfft)
     159                 :             :  !real(dp)                   :: a1(3),a2(3),a3(3)
     160                 :             :  real(dp)                   :: b1(3),b2(3),b3(3),rmet(3,3) !,gprimd(3,3),
     161                 :      214670 :  type(MPI_type)             :: mpi_enreg   !!!!
     162   [ +  +  +  +  :    11162840 :  type(crystal_t)            :: Cryst       !!!!
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     163                 :             :  !type(gsphere_t)            :: Gsph
     164                 :             : !Local variables-------------------------------
     165                 :             : !scalars
     166                 :             :  integer,parameter    :: empty(3,3)=zero
     167                 :             :  integer,parameter    :: cplex1=1
     168                 :             :  integer              :: comm
     169                 :             :  integer              :: ii1,i1,i2,i23,i3,id1,id2,id3,icutcoul_local
     170                 :             :  integer              :: ig,ig0,ig1,ig2,ig3,ig1min,ig1max,ig2min,ig2max,ig3min,ig3max
     171                 :             :  integer              :: ii,ing,n1,n2,n3,npar,npt
     172                 :             :  integer              :: opt_cylinder,opt_slab,test
     173                 :             :  integer              :: qeq0,qeq05
     174                 :             :  real(dp),parameter   :: tolfix=1.000000001e0_dp ! Same value as the one used in hartre
     175                 :             :  real(dp)             :: check,step
     176                 :             :  real(dp)             :: cutoff,gqg2p3,gqgm12,gqgm13,gqgm23,gs,gs2,gs3,rcut0
     177                 :             :  real(dp)             :: bz_plane,dx,integ,q0_vol,q0_volsph
     178                 :             :  character(len=500)   :: msg
     179                 :             : !arrays
     180                 :             :  integer              :: id(3), gamma_pt(3,1)
     181                 :      214670 :  real(dp),allocatable :: gq(:,:),gpq(:),gpq2(:)
     182                 :      214670 :  real(dp),allocatable :: vcfit(:,:),xx(:),yy(:)
     183                 :      214670 :  real(dp),allocatable :: cov(:,:),par(:),qfit(:,:),sigma(:),var(:),qcart(:,:)
     184                 :      214670 :  type(vcut_t)               :: vcut        !!!!
     185                 :             : !
     186                 :      214670 :  comm=mpi_enreg%comm_world
     187                 :             : !
     188                 :             : ! === Save dimension and other useful quantities in vcut% ===
     189         [ +  + ]:      858680 :  vcut%nfft      = PRODUCT(ngfft(1:3))  ! Number of points in the FFT mesh.
     190                 :             :  ! ng and gvec are not used yet we don't want to use them without being defined
     191                 :      214670 :  ng = -1
     192                 :      214670 :  vcut%ng        = ng                   ! Number of G-vectors in the Coulomb matrix elements.
     193                 :      214670 :  vcut%rcut      = rcut                 ! Cutoff radius for cylinder.
     194                 :      214670 :  vcut%hcyl      = zero                 ! Length of finite cylinder (Rozzi"s method, default is Beigi).
     195                 :      214670 :  vcut%ucvol     = ucvol                ! Unit cell volume.
     196                 :             : 
     197                 :             :  !FBruneval: comment the definitions below since Cryst and dtset have never been initialized!
     198                 :             :  !vcut%rprimd    = Cryst%rprimd(:,:)    ! Dimensional direct lattice.
     199                 :             :  !vcut%boxcenter = dtset%boxcenter      ! boxcenter at the moment is supposed to be at the origin.
     200                 :             :  !vcut%vcutgeo   = dtset%vcutgeo(:)     ! Info on the orientation and extension of the cutoff region.
     201                 :             : !
     202                 :             : ! === Define geometry and cutoff radius (if used) ===
     203                 :      214670 :  vcut%mode='NONE'
     204                 :      214670 :  icutcoul_local=icutcoul
     205                 :             : 
     206                 :             :  ! for short-range exchange (e.g. HSE06), enforce ERFC
     207         [ +  + ]:      214670 :  if (PRESENT(shortrange)) then
     208         [ -  + ]:       81956 :    if (shortrange) then
     209                 :             :       icutcoul_local=5
     210                 :             :    end if
     211                 :             :  end if
     212                 :             : ! -------------------------------------
     213                 :             : 
     214         [ +  + ]:      132714 :  if (icutcoul_local == 0) vcut%mode = 'SPHERE'
     215         [ -  + ]:      214670 :  if (icutcoul_local == 1) vcut%mode = 'CYLINDER'
     216         [ -  + ]:      214670 :  if (icutcoul_local == 2) vcut%mode = 'SLAB'
     217         [ +  + ]:      214670 :  if (icutcoul_local == 3) vcut%mode = 'CRYSTAL'
     218         [ -  + ]:      214670 :  if (icutcoul_local == 4) vcut%mode = 'ERF'
     219         [ +  + ]:      214670 :  if (icutcoul_local == 5) vcut%mode = 'ERFC'
     220         [ +  + ]:      214670 :  if (icutcoul_local == 6) vcut%mode = 'AUXILIARY_FUNCTION'
     221         [ +  + ]:      214670 :  if (icutcoul_local == 7) vcut%mode = 'AUX_GB'
     222                 :             : 
     223                 :             : !Initialize a few quantities
     224                 :      214670 :  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
     225                 :      214670 :  cutoff = gsqcut * tolfix
     226         [ +  + ]:   909720770 :  barev=zero
     227                 :             : 
     228                 :             : !Some peculiar values of q: q=0 or q on the BZ edge
     229         [ +  + ]:      214670 :  qeq0=0; if (qpoint(1)**2+qpoint(2)**2+qpoint(3)**2<1.d-15) qeq0=1
     230                 :      201633 :  qeq05=0
     231                 :             :  if (qeq0==0) then
     232   [ +  +  +  +  :      201633 :    if (abs(abs(qpoint(1))-half)<tol12.or.abs(abs(qpoint(2))-half)<tol12.or. &
                   +  + ]
     233                 :      103089 : &   abs(abs(qpoint(3))-half)<tol12) qeq05=1
     234                 :             :  end if
     235                 :             : 
     236                 :             : !In order to speed the routine, precompute the components of g+q
     237                 :             : !Also check if the booked space was large enough...
     238                 :             : 
     239   [ -  +  +  -  :      644010 :  ABI_MALLOC(gq,(3,max(n1,n2,n3)))
          +  -  +  -  -  
                +  -  + ]
     240   [ -  +  +  -  :      644010 :  ABI_MALLOC(gpq,(nfft))
          +  -  +  -  -  
                +  -  + ]
     241   [ -  +  +  -  :      429340 :  ABI_MALLOC(gpq2,(nfft))
             -  +  -  + ]
     242                 :             : 
     243         [ +  + ]:      858680 :  do ii=1,3
     244                 :      644010 :    id(ii)=ngfft(ii)/2+2
     245         [ +  + ]:    10771586 :    do ing=1,ngfft(ii)
     246                 :     9912906 :      ig=ing-(ing/id(ii))*ngfft(ii)-1
     247                 :    10556916 :      gq(ii,ing)=ig+qpoint(ii)
     248                 :             :    end do
     249                 :             :  end do
     250                 :      214670 :  ig1max=-1;ig2max=-1;ig3max=-1
     251                 :      214670 :  ig1min=n1;ig2min=n2;ig3min=n3
     252                 :      214670 :  ig0 = 0 ! Index of q+G = 0 (only if q is a reciprocal lattice vector)
     253                 :             : 
     254                 :      214670 :  id1=n1/2+2;id2=n2/2+2;id3=n3/2+2
     255                 :             : 
     256                 :             :  ! Triple loop on each dimension
     257         [ +  + ]:     3514028 :  do i3=1,n3
     258                 :     3299358 :    ig3=i3-(i3/id3)*n3-1
     259                 :             :    ! Precompute some products that do not depend on i2 and i1
     260                 :     3299358 :    gs3=gq(3,i3)*gq(3,i3)*gmet(3,3)
     261                 :     3299358 :    gqgm23=gq(3,i3)*gmet(2,3)*2
     262                 :     3299358 :    gqgm13=gq(3,i3)*gmet(1,3)*2
     263         [ +  + ]:    55986182 :    do i2=1,n2
     264                 :    52472154 :      ig2=i2-(i2/id2)*n2-1
     265                 :    52472154 :      i23=n1*(i2-1 +(n2)*(i3-1))
     266                 :    52472154 :      gs2=gs3+ gq(2,i2)*(gq(2,i2)*gmet(2,2)+gqgm23)
     267                 :    52472154 :      gqgm12=gq(2,i2)*gmet(1,2)*2
     268                 :    52472154 :      gqg2p3=gqgm13+gqgm12
     269                 :             : 
     270         [ +  + ]:   961978254 :      do i1=1,n1
     271                 :   909506100 :         ii=i1+i23
     272                 :   909506100 :         gpq(ii)= gs2 + gq(1,i1)*(gq(1,i1)*gmet(1,1)+gqg2p3)
     273                 :             :         ! q+G = 0 tested in reduced coordinates (no threshold on |q+G|: small q+G occur for large supercells)
     274   [ +  +  +  +  :   961978254 :         if (abs(gq(1,i1))<tol8 .and. abs(gq(2,i2))<tol8 .and. abs(gq(3,i3))<tol8) then
                   +  + ]
     275                 :       13037 :           ig0 = ii
     276                 :       13037 :           gpq2(ii) = zero
     277                 :             :         else
     278                 :             :           ! gpq2 contains 4*pi / |q+G|**2
     279                 :   909493063 :           gpq2(ii) = piinv/gpq(ii)
     280                 :             :         end if
     281                 :             :      end do
     282                 :             : 
     283                 :             :      !
     284                 :             :      ! Next part looks for ig1min,ig1max that are needed by zerosym
     285                 :             :      ! Do the test that eliminates the Gamma point outside of the inner loop
     286                 :    52472154 :      ii1=1
     287   [ +  +  -  + ]:    52472154 :      if (i23==0 .and. qeq0==1  .and. ig2==0 .and. ig3==0) then
     288                 :    52472154 :        ii1=2
     289                 :             :      end if
     290                 :             : 
     291                 :             :      ! Final inner loop on the first dimension (note the lower limit)
     292         [ +  + ]:   965264575 :      do i1=ii1,n1
     293                 :   909493063 :        gs = gs2+ gq(1,i1)*(gq(1,i1)*gmet(1,1)+gqg2p3)
     294                 :             : 
     295                 :             :        !ii=i1+i23
     296                 :             : 
     297         [ +  + ]:   961965217 :        if (gs<=cutoff) then
     298                 :             :          ! Identify min/max indexes (to cancel unbalanced contributions later)
     299                 :             :          ! Count (q+g)-vectors with similar norm
     300   [ +  +  +  + ]:   298177439 :          if ((qeq05==1).and.(izero==1)) then
     301                 :     6790878 :            ig1=i1-(i1/id1)*n1-1
     302                 :     6790878 :            ig1max=max(ig1max,ig1); ig1min=min(ig1min,ig1)
     303                 :     6790878 :            ig2max=max(ig2max,ig2); ig2min=min(ig2min,ig2)
     304                 :     6790878 :            ig3max=max(ig3max,ig3); ig3min=min(ig3min,ig3)
     305                 :             :          end if
     306                 :             : 
     307                 :             :        end if ! Cut-off
     308                 :             :      end do ! End loop on i1
     309                 :             :    end do
     310                 :             :  end do
     311                 :             : 
     312                 :             : 
     313         [ +  + ]:   909720770 :  barev(:)=zero
     314                 :             : 
     315                 :             :  ! MG: This triggers SIGFPE as cryst is not initialized
     316                 :             :  !a1=Cryst%rprimd(:,1); b1=two_pi*gprimd(:,1)
     317                 :             :  !a2=Cryst%rprimd(:,2); b2=two_pi*gprimd(:,2)
     318                 :             :  !a3=Cryst%rprimd(:,3); b3=two_pi*gprimd(:,3)
     319                 :             : 
     320                 :      216398 :  select case(TRIM(vcut%mode))
     321                 :             :  case ('CRYSTAL', 'AUXILIARY_FUNCTION', "AUX_GB")
     322         [ +  + ]:        1728 :    if (vcut%mode == "CRYSTAL") then
     323                 :             :      ! Analytic integration of 4pi/q^2 over the volume element:
     324                 :             :      ! $4pi/V \int_V d^3q 1/q^2 =4pi bz_geometric_factor V^(-2/3)$
     325                 :             :      ! i_sz=4*pi*bz_geometry_factor*q0_vol**(-two_thirds) where q0_vol= V_BZ/N_k
     326                 :             :      ! bz_geometry_factor: sphere=7.79, fcc=7.44, sc=6.188, bcc=6.946, wz=5.255 (see gwa.pdf, appendix A.4)
     327                 :        1296 :      q0_vol = two_pi**3 / (nkpt_bz * ucvol)
     328                 :        1296 :      vcut%i_sz = four_pi*7.44*q0_vol**(-two_thirds)
     329                 :             : 
     330   [ +  +  +  - ]:         432 :    else if (vcut%mode == "AUXILIARY_FUNCTION" .or. vcut%mode == "AUX_GB") then
     331                 :             :      ! Auxiliary function of Carrier et al. [[cite:Carrier2007]] (6) or Gygi-Baldereschi method [[cite:Gygi1986]]
     332                 :             :      ! with the Gaussian auxiliary function of [[cite:Massidda1993]] (7).
     333                 :             :      ! i_sz depends on the q-mesh (k-points of the Fock operator), it is computed once in fock_init
     334                 :             :      ! (carrier_isz_gmet, gb_isz).
     335         [ -  + ]:         432 :      if (.not. present(i_sz)) then
     336                 :           0 :        ABI_BUG(sjoin("icutcoul=6 or 7 (", vcut%mode, ") requires the argument i_sz"))
     337                 :             :      end if
     338                 :         432 :      vcut%i_sz = i_sz
     339                 :             : 
     340                 :             :    else
     341                 :           0 :      ABI_ERROR(sjoin("Need treatment of 1/q^2 singularity! for mode", vcut%mode))
     342                 :             :    end if
     343                 :             : 
     344         [ +  + ]:     7079616 :    do ig=1,nfft
     345         [ +  + ]:     7079616 :      if (ig == ig0) then
     346                 :         216 :        barev(ig) = vcut%i_sz
     347         [ +  + ]:     7077672 :      else if (gpq(ig)<=cutoff) then
     348                 :     2099520 :        barev(ig) = gpq2(ig)
     349                 :             :      end if
     350                 :             :    end do
     351                 :             : 
     352                 :             :  case ('SPHERE') ! Spherical cutoff
     353                 :             : 
     354                 :             :    !
     355                 :             :    ! Treatment of the divergence at q+g=zero
     356                 :             :    !
     357                 :             :    ! rcut is not set (rcut<=0), use the default Spencer-Alavi definition:
     358         [ +  + ]:      130986 :    if ( rcut < tol8 ) then
     359                 :      129594 :      rcut0= (three*nkpt_bz*ucvol/four_pi)**(one/three)
     360                 :             :    else
     361                 :             :      rcut0 = rcut
     362                 :             :    end if
     363                 :             : 
     364         [ +  + ]:   574623786 :    do ig=1,nfft
     365         [ +  + ]:   574623786 :      if (ig == ig0) then
     366                 :        8429 :        barev(ig) = two_pi*rcut0**two
     367         [ +  + ]:   574484371 :      else if (gpq(ig)<=cutoff) then
     368                 :   206086387 :        barev(ig) = gpq2(ig) * (one - cos( rcut0*sqrt(four_pi/gpq2(ig)) ) )
     369                 :             :      end if
     370                 :             :    end do
     371                 :             : 
     372                 :             :  case ('CYLINDER')
     373                 :             :    !FBruneval: not working. For instance, Cryst is never initialized
     374                 :           0 :    ABI_BUG("Cylinder cutoff coding is not finalized")
     375                 :             : 
     376   [ #  #  #  # ]:           0 :    test=COUNT(ABS(vcut%vcutgeo)>tol6)
     377         [ #  # ]:           0 :    ABI_CHECK(test==1,'Wrong cutgeo for cylinder')
     378                 :             : 
     379                 :             :    ! === Beigi method is the default one, i.e infinite cylinder of radius rcut ===
     380                 :             :    ! * Negative values to use Rozzi method with finite cylinder of extent hcyl.
     381         [ #  # ]:           0 :    opt_cylinder=1; vcut%hcyl=zero; vcut%pdir(:)=0
     382         [ #  # ]:           0 :    do ii=1,3
     383                 :           0 :      check=vcut%vcutgeo(ii)
     384         [ #  # ]:           0 :      if (ABS(check)>tol6) then
     385                 :           0 :        vcut%pdir(ii)=1
     386         [ #  # ]:           0 :        if (check<zero) then  ! use Rozzi's method.
     387   [ #  #  #  #  :           0 :          vcut%hcyl=ABS(check)*NORM2(Cryst%rprimd(:,ii))
                   #  # ]
     388                 :           0 :          opt_cylinder=2
     389                 :             :        end if
     390                 :             :      end if
     391                 :             :    end do
     392                 :             : 
     393   [ #  #  #  # ]:           0 :    test=COUNT(vcut%pdir==1)
     394         [ #  # ]:           0 :    ABI_CHECK((test==1),'Wrong pdir for cylinder')
     395         [ #  # ]:           0 :    if (vcut%pdir(3)/=1) then
     396                 :           0 :      ABI_ERROR("The cylinder must be along the z-axis")
     397                 :             :    end if
     398                 :             : 
     399                 :           0 :    ABI_BUG("cutoff cylinder API has changed!")
     400                 :             : 
     401                 :             : !   call cutoff_cylinder(nfft,gq,ng,Gsph%gvec,vcut%rcut,vcut%hcyl,vcut%pdir,&
     402                 :             : !&                       vcut%boxcenter,Cryst%rprimd,barev,opt_cylinder,comm)
     403                 :             : 
     404                 :             :    ! === If Beigi, treat the limit q--> 0 ===
     405         [ #  # ]:           0 :    if (opt_cylinder==1) then
     406                 :           0 :      npar=8; npt=100 ; gamma_pt=RESHAPE((/0,0,0/),(/3,1/))
     407         [ #  # ]:           0 :      ABI_MALLOC(qfit,(3,npt))
     408         [ #  # ]:           0 :      ABI_MALLOC(vcfit,(1,npt))
     409         [ #  # ]:           0 :      if (nfft==1) then
     410                 :           0 :        ABI_ERROR("nfft == 1 not supported when Beigi's method is used")
     411                 :             :      endif
     412   [ #  #  #  # ]:           0 :      qfit(:,:)=zero
     413         [ #  # ]:           0 :      step=half/(npt*(nfft-1))              ; qfit(3,:)=arth(tol6,step,npt)
     414                 :             : 
     415                 :             :      !call cutoff_cylinder(npt,qfit,1,gamma_pt,vcut%rcut,vcut%hcyl,vcut%pdir,&
     416                 :             :      !                    vcut%boxcenter,Cryst%rprimd,vcfit,opt_cylinder,comm)
     417                 :             : 
     418         [ #  # ]:           0 :      ABI_MALLOC(xx,(npt))
     419         [ #  # ]:           0 :      ABI_MALLOC(yy,(npt))
     420         [ #  # ]:           0 :      ABI_MALLOC(sigma,(npt))
     421         [ #  # ]:           0 :      ABI_MALLOC(par,(npar))
     422         [ #  # ]:           0 :      ABI_MALLOC(var,(npar))
     423         [ #  # ]:           0 :      ABI_MALLOC(cov,(npar,npar))
     424         [ #  # ]:           0 :      do ii=1,npt
     425                 :           0 :       xx(ii)=normv(qfit(:,ii),gmet,'G')
     426                 :             :      end do
     427         [ #  # ]:           0 :      ABI_FREE(qfit)
     428   [ #  #  #  # ]:           0 :      sigma=one ; yy(:)=vcfit(1,:)
     429         [ #  # ]:           0 :      ABI_FREE(vcfit)
     430                 :             : 
     431                 :           0 :      bz_plane=l2norm(b1.x.b2)
     432                 :           0 :      dx=(xx(2)-xx(1))
     433                 :           0 :      integ=yy(2)*dx*3.0/2.0
     434         [ #  # ]:           0 :      integ=integ + SUM(yy(3:npt-2))*dx
     435                 :           0 :      integ=integ+yy(npt-1)*dx*3.0/2.0
     436                 :           0 :      write(std_out,*)' simple integral',integ
     437                 :           0 :      q0_volsph=(two_pi)**3/(nkpt_bz*ucvol)
     438                 :           0 :      q0_vol=bz_plane*two*xx(npt)
     439                 :           0 :      write(std_out,*)' q0 sphere : ',q0_volsph,' q0_vol cyl ',q0_vol
     440                 :           0 :      vcut%i_sz=bz_plane*two*integ/q0_vol
     441                 :           0 :      write(std_out,*)' spherical approximation ',four_pi*7.44*q0_volsph**(-two_thirds)
     442                 :           0 :      write(std_out,*)' Cylindrical cutoff value ',vcut%i_sz
     443                 :             : 
     444                 :           0 :      ABI_FREE(xx)
     445                 :           0 :      ABI_FREE(yy)
     446         [ #  # ]:           0 :      ABI_FREE(sigma)
     447         [ #  # ]:           0 :      ABI_FREE(par)
     448         [ #  # ]:           0 :      ABI_FREE(var)
     449         [ #  # ]:           0 :      ABI_FREE(cov)
     450                 :             : 
     451                 :             :    else
     452                 :             :      ! In Rozzi"s method the lim q+G --> 0 is finite.
     453                 :           0 :      vcut%i_sz=barev(1)
     454                 :             :    end if
     455                 :             : 
     456                 :             :  CASE ('SLAB')
     457                 :             :    !FBruneval: not working. For instance, Cryst is never initialized
     458                 :           0 :    ABI_BUG("Slab cutoff coding is not finalized")
     459                 :             : 
     460   [ #  #  #  # ]:           0 :    test=COUNT(vcut%vcutgeo/=zero)
     461         [ #  # ]:           0 :    ABI_CHECK(test==2,"Wrong vcutgeo")
     462                 :             :    !
     463                 :             :    ! Two methods available
     464                 :             :    !
     465                 :             :    ! === Default is Beigi"s method ===
     466         [ #  # ]:           0 :    opt_slab=1; vcut%alpha(:)=zero
     467   [ #  #  #  #  :           0 :    if (ANY(vcut%vcutgeo<zero)) opt_slab=2
                   #  # ]
     468         [ #  # ]:           0 :    vcut%pdir(:)=zero
     469         [ #  # ]:           0 :    do ii=1,3
     470                 :           0 :      check=vcut%vcutgeo(ii)
     471         [ #  # ]:           0 :      if (ABS(check)>zero) then ! Use Rozzi"s method with a finite slab along x-y
     472                 :           0 :        vcut%pdir(ii)=1
     473   [ #  #  #  # ]:           0 :        if (check<zero) vcut%alpha(ii)=normv(check*Cryst%rprimd(:,ii),rmet,'R')
     474                 :             :      end if
     475                 :             :    end do
     476                 :             : 
     477                 :             :    ! Beigi"s method: the slab must be along x-y and R must be L_Z/2.
     478         [ #  # ]:           0 :    if (opt_slab==1) then
     479   [ #  #  #  #  :           0 :      ABI_CHECK(ALL(vcut%pdir == (/1,1,0/)),"Surface must be in the x-y plane")
                   #  # ]
     480                 :             :      !vcut%rcut = half*SQRT(DOT_PRODUCT(a3,a3))
     481                 :             :    end if
     482                 :             : 
     483                 :           0 :    ABI_BUG("cutoff surface API has changed!")
     484                 :             :    !call cutoff_slab(nfft,gq,ng,Gsph%gvec,gprimd,vcut%rcut,&
     485                 :             :    !   vcut%boxcenter,vcut%pdir,vcut%alpha,barev,opt_slab)
     486                 :             : 
     487                 :             :    !
     488                 :             :    ! === If Beigi, treat the limit q--> 0 ===
     489         [ #  # ]:           0 :    if (opt_slab==1) then
     490                 :             :      ! Integrate numerically in the plane close to 0
     491                 :           0 :      npt=100 ! Number of points in 1D
     492                 :             :      gamma_pt=RESHAPE((/0,0,0/),(/3,1/)) ! Gamma point
     493         [ #  # ]:           0 :      ABI_MALLOC(qfit,(3,npt))
     494         [ #  # ]:           0 :      ABI_MALLOC(qcart,(3,npt))
     495         [ #  # ]:           0 :      ABI_MALLOC(vcfit,(1,npt))
     496         [ #  # ]:           0 :      if (nfft==1) then
     497                 :           0 :        ABI_ERROR("nfft == 1 not supported when Beigi's method is used")
     498                 :             :      endif
     499   [ #  #  #  # ]:           0 :      qfit(:,:)=zero
     500   [ #  #  #  # ]:           0 :      qcart(:,:)=zero
     501                 :             :      ! Size of the third vector
     502                 :           0 :      bz_plane=l2norm(b3)
     503                 :           0 :      q0_volsph=(two_pi)**3/(nkpt_bz*ucvol)
     504                 :             :      ! radius that gives the same volume as q0_volsph
     505                 :             :      ! Let's assume that c is perpendicular to the plane
     506                 :             :      ! We also assume isotropic BZ around gamma
     507                 :           0 :      step=sqrt((q0_volsph/bz_plane)/pi)/npt
     508                 :             : 
     509                 :             :      !step=half/(npt*(Qmesh%nibz-1))
     510                 :             :      ! Let's take qpoints along 1 line, the vcut does depend only on the norm
     511         [ #  # ]:           0 :      qcart(1,:)=arth(tol6,step,npt)
     512                 :             : 
     513         [ #  # ]:           0 :      do ii = 1,npt
     514         [ #  # ]:           0 :        qfit(:,ii) = MATMUL(TRANSPOSE(Cryst%rprimd),qcart(:,ii))/(2*pi)
     515                 :             :      end do
     516                 :             : 
     517                 :           0 :      ABI_BUG("cutoff surface API has changed!")
     518                 :             : 
     519                 :             : !     call cutoff_slab(npt,qfit,1,gamma_pt,gprimd,vcut%rcut,&
     520                 :             : !       vcut%boxcenter,vcut%pdir,vcut%alpha,vcfit,opt_slab)
     521                 :             : 
     522         [ #  # ]:           0 :      ABI_MALLOC(xx,(npt))
     523         [ #  # ]:           0 :      ABI_MALLOC(yy,(npt))
     524         [ #  # ]:           0 :      ABI_MALLOC(sigma,(npt))
     525         [ #  # ]:           0 :      do ii=1,npt
     526                 :             :       !xx(ii)=qfit(1,:)
     527                 :           0 :       xx(ii)=normv(qfit(:,ii),gmet,'G')
     528                 :             :      end do
     529         [ #  # ]:           0 :      ABI_FREE(qfit)
     530         [ #  # ]:           0 :      sigma=one
     531         [ #  # ]:           0 :      yy(:)=vcfit(1,:)
     532                 :             :      !yy(:)=one
     533         [ #  # ]:           0 :      ABI_FREE(vcfit)
     534                 :           0 :      dx=(xx(2)-xx(1))
     535                 :             :      ! integ = \int dr r f(r)
     536                 :           0 :      integ=xx(2)*yy(2)*dx*3.0/2.0
     537         [ #  # ]:           0 :      integ=integ + DOT_PRODUCT(xx(3:npt-2),yy(3:npt-2))*dx
     538                 :           0 :      integ=integ+xx(npt-1)*yy(npt-1)*dx*3.0/2.0
     539                 :           0 :      write(std_out,*)' simple integral',integ
     540                 :           0 :      q0_vol=bz_plane*pi*xx(npt)**2
     541                 :           0 :      write(std_out,*)' q0 sphere : ',q0_volsph,' q0_vol cyl ',q0_vol
     542                 :           0 :      vcut%i_sz=bz_plane*2*pi*integ/q0_vol
     543                 :           0 :      write(std_out,*)' spherical approximation ',four_pi*7.44*q0_volsph**(-two_thirds)
     544                 :           0 :      write(std_out,*)' Cylindrical cutoff value ',vcut%i_sz
     545                 :             : 
     546                 :           0 :      ABI_FREE(xx)
     547                 :           0 :      ABI_FREE(yy)
     548                 :             :    else
     549                 :             :      ! In Rozzi"s method the lim q+G --> 0 is finite.
     550                 :           0 :      vcut%i_sz=barev(1)
     551                 :             :    end if
     552                 :             : 
     553                 :             :  CASE ('ERF')
     554                 :             : 
     555         [ #  # ]:           0 :    do ig=1,nfft
     556         [ #  # ]:           0 :      if (abs(gpq(ig))<tol4) then
     557                 :             :         !FIXME FBruneval check this value, ERFC value was wrong, so why not this one.
     558                 :           0 :         barev(ig) = zero ! Stupid definition to remember something should be done here.
     559         [ #  # ]:           0 :      else if (gpq(ig)<=cutoff) then
     560                 :             :        !FIXME FBruneval shortrange does not make sense here (it is an optional argument that may not be present)
     561                 :             :        ! and ERF is long range any way
     562         [ #  # ]:           0 :        if (shortrange) then
     563                 :           0 :          barev(ig) = + gpq2(ig) * exp( -pi * rcut**2 /gpq2(ig) )
     564                 :             :        end if
     565                 :             :     end if
     566                 :             :    end do
     567                 :             : 
     568                 :             :  CASE ('ERFC')
     569                 :             : 
     570         [ +  + ]:   328017368 :    do ig=1,nfft
     571         [ +  + ]:   328017368 :      if (ig == ig0) then
     572                 :             :         !FBruneval there was a wrong value here
     573                 :        4392 :         barev(ig) = pi * rcut**2
     574         [ +  + ]:   327931020 :      else if (gpq(ig)<=cutoff) then
     575                 :             :        ! gpq2 is 4 pi / (q+G)**2
     576                 :             :        ! 4 pi / (q+G)**2 * [ 1 - exp( -1/4 * Rc**2 * (q+G)**2 ) ]
     577                 :    89991532 :        barev(ig) = gpq2(ig) * ( one - exp( -pi * rcut**2 / gpq2(ig) ) )
     578                 :             :     end if
     579                 :             :    end do
     580                 :             : 
     581                 :             :  case default
     582                 :           0 :    write(msg,'(3a)')'No cut-off applied to the Coulomb Potential.', ch10, &
     583                 :           0 :                     'Either icutcoul value not allowed or not defined.'
     584   [ +  +  -  -  :      214670 :    ABI_WARNING(msg)
                -  +  - ]
     585                 :             :  end select
     586                 :             : 
     587         [ +  + ]:      214670 :  if (izero==1) then
     588                 :             :    ! Set contribution of unbalanced components to zero
     589         [ +  + ]:       11980 :    if (qeq0==1) then !q=0
     590                 :        2101 :      call zerosym(barev,cplex1,n1,n2,n3)
     591         [ +  + ]:        9879 :    else if (qeq05==1) then
     592                 :             :      !q=1/2; this doesn't work in parallel
     593         [ +  - ]:        5607 :      ig1=-1;if (mod(n1,2)==0) ig1=1+n1/2
     594         [ +  - ]:        5607 :      ig2=-1;if (mod(n2,2)==0) ig2=1+n2/2
     595         [ +  - ]:        5607 :      ig3=-1;if (mod(n3,2)==0) ig3=1+n3/2
     596         [ +  + ]:        5607 :      if (abs(abs(qpoint(1))-half)<tol12) then
     597         [ +  + ]:        3204 :        if (abs(ig1min)<abs(ig1max)) ig1=abs(ig1max)
     598         [ +  + ]:        3204 :        if (abs(ig1min)>abs(ig1max)) ig1=n1-abs(ig1min)
     599                 :             :      end if
     600         [ +  + ]:        5607 :      if (abs(abs(qpoint(2))-half)<tol12) then
     601         [ +  + ]:        3204 :        if (abs(ig2min)<abs(ig2max)) ig2=abs(ig2max)
     602         [ +  + ]:        3204 :        if (abs(ig2min)>abs(ig2max)) ig2=n2-abs(ig2min)
     603                 :             :      end if
     604         [ +  + ]:        5607 :      if (abs(abs(qpoint(3))-half)<tol12) then
     605         [ +  - ]:        3204 :        if (abs(ig3min)<abs(ig3max)) ig3=abs(ig3max)
     606         [ -  + ]:        3204 :        if (abs(ig3min)>abs(ig3max)) ig3=n3-abs(ig3min)
     607                 :             :      end if
     608                 :        5607 :      call zerosym(barev,cplex1,n1,n2,n3,ig1=ig1,ig2=ig2,ig3=ig3)
     609                 :             :    end if
     610                 :             :  end if
     611                 :             : 
     612         [ -  + ]:      214670 :  ABI_FREE(gq)
     613         [ -  + ]:      214670 :  ABI_FREE(gpq)
     614         [ -  + ]:      214670 :  ABI_FREE(gpq2)
     615                 :             : 
     616   [ -  +  -  +  :      214670 : end subroutine barevcoul
             -  +  -  + ]
     617                 :             : !!***
     618                 :             : 
     619   [ #  #  #  #  :           0 : end module m_barevcoul
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     620                 :             : !!***
        

Generated by: LCOV version 2.3-1