LCOV - code coverage report
Current view: top level - src/62_poisson - m_barevcoul.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 49.8 % 231 115
Test Date: 2026-11-08 00:10:28 Functions: 33.3 % 3 1
Branches: 40.5 % 353 143

             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                 :             : !!
     132                 :             : !! OUTPUT
     133                 :             : !!  barev(nfft)=4pi/(G+q)**2, q+G=0 component is set carefully
     134                 :             : !!
     135                 :             : !! NOTES
     136                 :             : !!  This routine operates on the full FFT mesh. DO NOT PASS MPI_TYPE
     137                 :             : !!  One can easily implemente MPI-FFT by just calling this routine and then
     138                 :             : !!  extracting the G-vectors treated by the node.
     139                 :             : !!
     140                 :             : !! SOURCE
     141                 :             : 
     142                 :      214238 : subroutine barevcoul(rcut,icutcoul,qpoint,gsqcut,gmet,nfft,nkpt_bz,ngfft,ucvol,izero,barev,shortrange)
     143                 :             : 
     144                 :             : !Arguments ------------------------------------
     145                 :             : !scalars
     146                 :             :  integer,intent(in)         :: icutcoul,nfft,nkpt_bz,izero
     147                 :             :  real(dp),intent(in)        :: rcut,gsqcut,ucvol
     148                 :             :  logical,intent(in),optional:: shortrange
     149                 :             : !arrays
     150                 :             :  integer,intent(in)         :: ngfft(18)
     151                 :             :  integer                    :: ng!!!!
     152                 :             :  real(dp),intent(in)        :: qpoint(3)
     153                 :             :  real(dp),intent(inout)     :: gmet(3,3)
     154                 :             :  real(dp),intent(inout)     :: barev(nfft)
     155                 :             :  !real(dp)                   :: a1(3),a2(3),a3(3)
     156                 :             :  real(dp)                   :: b1(3),b2(3),b3(3),rmet(3,3) !,gprimd(3,3),
     157                 :      214238 :  type(MPI_type)             :: mpi_enreg   !!!!
     158   [ +  +  +  +  :    13496994 :  type(crystal_t)            :: Cryst       !!!!
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
     159                 :             :  !type(gsphere_t)            :: Gsph
     160                 :             : !Local variables-------------------------------
     161                 :             : !scalars
     162                 :             :  integer,parameter    :: empty(3,3)=zero
     163                 :             :  integer,parameter    :: cplex1=1
     164                 :             :  integer              :: comm
     165                 :             :  integer              :: ii1,i1,i2,i23,i3,id1,id2,id3,icutcoul_local
     166                 :             :  integer              :: ig,ig1,ig2,ig3,ig1min,ig1max,ig2min,ig2max,ig3min,ig3max
     167                 :             :  integer              :: ii,ing,n1,n2,n3,npar,npt
     168                 :             :  integer              :: opt_cylinder,opt_slab,test
     169                 :             :  integer              :: qeq0,qeq05
     170                 :             :  real(dp),parameter   :: tolfix=1.000000001e0_dp ! Same value as the one used in hartre
     171                 :             :  real(dp)             :: check,step
     172                 :             :  real(dp)             :: cutoff,gqg2p3,gqgm12,gqgm13,gqgm23,gs,gs2,gs3,rcut0
     173                 :             :  real(dp)             :: bz_plane,dx,integ,q0_vol,q0_volsph
     174                 :             :  character(len=500)   :: msg
     175                 :             : !arrays
     176                 :             :  integer              :: id(3), gamma_pt(3,1)
     177                 :      214238 :  real(dp),allocatable :: gq(:,:),gpq(:),gpq2(:)
     178                 :      214238 :  real(dp),allocatable :: vcfit(:,:),xx(:),yy(:)
     179                 :      214238 :  real(dp),allocatable :: cov(:,:),par(:),qfit(:,:),sigma(:),var(:),qcart(:,:)
     180                 :      214238 :  type(vcut_t)               :: vcut        !!!!
     181                 :             : !
     182                 :      214238 :  comm=mpi_enreg%comm_world
     183                 :             : !
     184                 :             : ! === Save dimension and other useful quantities in vcut% ===
     185         [ +  + ]:      856952 :  vcut%nfft      = PRODUCT(ngfft(1:3))  ! Number of points in the FFT mesh.
     186                 :             :  ! ng and gvec are not used yet we don't want to use them without being defined
     187                 :      214238 :  ng = -1
     188                 :      214238 :  vcut%ng        = ng                   ! Number of G-vectors in the Coulomb matrix elements.
     189                 :      214238 :  vcut%rcut      = rcut                 ! Cutoff radius for cylinder.
     190                 :      214238 :  vcut%hcyl      = zero                 ! Length of finite cylinder (Rozzi"s method, default is Beigi).
     191                 :      214238 :  vcut%ucvol     = ucvol                ! Unit cell volume.
     192                 :             : 
     193                 :             :  !FBruneval: comment the definitions below since Cryst and dtset have never been initialized!
     194                 :             :  !vcut%rprimd    = Cryst%rprimd(:,:)    ! Dimensional direct lattice.
     195                 :             :  !vcut%boxcenter = dtset%boxcenter      ! boxcenter at the moment is supposed to be at the origin.
     196                 :             :  !vcut%vcutgeo   = dtset%vcutgeo(:)     ! Info on the orientation and extension of the cutoff region.
     197                 :             : !
     198                 :             : ! === Define geometry and cutoff radius (if used) ===
     199                 :      214238 :  vcut%mode='NONE'
     200                 :      214238 :  icutcoul_local=icutcoul
     201                 :             : 
     202                 :             :  ! for short-range exchange (e.g. HSE06), enforce ERFC
     203         [ +  + ]:      214238 :  if (PRESENT(shortrange)) then
     204         [ -  + ]:       81956 :    if (shortrange) then
     205                 :             :       icutcoul_local=5
     206                 :             :    end if
     207                 :             :  end if
     208                 :             : ! -------------------------------------
     209                 :             : 
     210         [ +  + ]:      132282 :  if (icutcoul_local == 0) vcut%mode = 'SPHERE'
     211         [ -  + ]:      214238 :  if (icutcoul_local == 1) vcut%mode = 'CYLINDER'
     212         [ -  + ]:      214238 :  if (icutcoul_local == 2) vcut%mode = 'SLAB'
     213         [ +  + ]:      214238 :  if (icutcoul_local == 3) vcut%mode = 'CRYSTAL'
     214         [ -  + ]:      214238 :  if (icutcoul_local == 4) vcut%mode = 'ERF'
     215         [ +  + ]:      214238 :  if (icutcoul_local == 5) vcut%mode = 'ERFC'
     216         [ -  + ]:      214238 :  if (icutcoul_local == 6) vcut%mode = 'AUXILIARY_FUNCTION'
     217         [ -  + ]:      214238 :  if (icutcoul_local == 7) vcut%mode = 'AUX_GB'
     218                 :             : 
     219                 :             : !Initialize a few quantities
     220                 :      214238 :  n1=ngfft(1); n2=ngfft(2); n3=ngfft(3)
     221                 :      214238 :  cutoff = gsqcut * tolfix
     222         [ +  + ]:   907950866 :  barev=zero
     223                 :             : 
     224                 :             : !Some peculiar values of q: q=0 or q on the BZ edge
     225         [ +  + ]:      214238 :  qeq0=0; if (qpoint(1)**2+qpoint(2)**2+qpoint(3)**2<1.d-15) qeq0=1
     226                 :      201255 :  qeq05=0
     227                 :             :  if (qeq0==0) then
     228   [ +  +  +  +  :      201255 :    if (abs(abs(qpoint(1))-half)<tol12.or.abs(abs(qpoint(2))-half)<tol12.or. &
                   +  + ]
     229                 :      102711 : &   abs(abs(qpoint(3))-half)<tol12) qeq05=1
     230                 :             :  end if
     231                 :             : 
     232                 :             : !In order to speed the routine, precompute the components of g+q
     233                 :             : !Also check if the booked space was large enough...
     234                 :             : 
     235   [ -  +  +  -  :      642714 :  ABI_MALLOC(gq,(3,max(n1,n2,n3)))
          +  -  +  -  -  
                +  -  + ]
     236   [ -  +  +  -  :      642714 :  ABI_MALLOC(gpq,(nfft))
          +  -  +  -  -  
                +  -  + ]
     237   [ -  +  +  -  :      428476 :  ABI_MALLOC(gpq2,(nfft))
             -  +  -  + ]
     238                 :             : 
     239         [ +  + ]:      856952 :  do ii=1,3
     240                 :      642714 :    id(ii)=ngfft(ii)/2+2
     241         [ +  + ]:    10749122 :    do ing=1,ngfft(ii)
     242                 :     9892170 :      ig=ing-(ing/id(ii))*ngfft(ii)-1
     243                 :    10534884 :      gq(ii,ing)=ig+qpoint(ii)
     244                 :             :    end do
     245                 :             :  end do
     246                 :      214238 :  ig1max=-1;ig2max=-1;ig3max=-1
     247                 :      214238 :  ig1min=n1;ig2min=n2;ig3min=n3
     248                 :             : 
     249                 :      214238 :  id1=n1/2+2;id2=n2/2+2;id3=n3/2+2
     250                 :             : 
     251                 :             :  ! Triple loop on each dimension
     252         [ +  + ]:     3506684 :  do i3=1,n3
     253                 :     3292446 :    ig3=i3-(i3/id3)*n3-1
     254                 :             :    ! Precompute some products that do not depend on i2 and i1
     255                 :     3292446 :    gs3=gq(3,i3)*gq(3,i3)*gmet(3,3)
     256                 :     3292446 :    gqgm23=gq(3,i3)*gmet(2,3)*2
     257                 :     3292446 :    gqgm13=gq(3,i3)*gmet(1,3)*2
     258         [ +  + ]:    55868246 :    do i2=1,n2
     259                 :    52361562 :      ig2=i2-(i2/id2)*n2-1
     260                 :    52361562 :      i23=n1*(i2-1 +(n2)*(i3-1))
     261                 :    52361562 :      gs2=gs3+ gq(2,i2)*(gq(2,i2)*gmet(2,2)+gqgm23)
     262                 :    52361562 :      gqgm12=gq(2,i2)*gmet(1,2)*2
     263                 :    52361562 :      gqg2p3=gqgm13+gqgm12
     264                 :             : 
     265         [ +  + ]:   960098190 :      do i1=1,n1
     266                 :   907736628 :         ii=i1+i23
     267                 :   907736628 :         gpq(ii)= gs2 + gq(1,i1)*(gq(1,i1)*gmet(1,1)+gqg2p3)
     268         [ +  + ]:   960098190 :         if (gpq(ii)>=tol4) then
     269                 :             :           ! gpq2 contains 4*pi / |q+G|**2
     270                 :   907723645 :           gpq2(ii) = piinv/gpq(ii)
     271                 :             :         end if
     272                 :             :      end do
     273                 :             : 
     274                 :             :      !
     275                 :             :      ! Next part looks for ig1min,ig1max that are needed by zerosym
     276                 :             :      ! Do the test that eliminates the Gamma point outside of the inner loop
     277                 :    52361562 :      ii1=1
     278   [ +  +  -  + ]:    52361562 :      if (i23==0 .and. qeq0==1  .and. ig2==0 .and. ig3==0) then
     279                 :    52361562 :        ii1=2
     280                 :             :      end if
     281                 :             : 
     282                 :             :      ! Final inner loop on the first dimension (note the lower limit)
     283         [ +  + ]:   963377653 :      do i1=ii1,n1
     284                 :   907723645 :        gs = gs2+ gq(1,i1)*(gq(1,i1)*gmet(1,1)+gqg2p3)
     285                 :             : 
     286                 :             :        !ii=i1+i23
     287                 :             : 
     288         [ +  + ]:   960085207 :        if (gs<=cutoff) then
     289                 :             :          ! Identify min/max indexes (to cancel unbalanced contributions later)
     290                 :             :          ! Count (q+g)-vectors with similar norm
     291   [ +  +  +  + ]:   297652559 :          if ((qeq05==1).and.(izero==1)) then
     292                 :     6333066 :            ig1=i1-(i1/id1)*n1-1
     293                 :     6333066 :            ig1max=max(ig1max,ig1); ig1min=min(ig1min,ig1)
     294                 :     6333066 :            ig2max=max(ig2max,ig2); ig2min=min(ig2min,ig2)
     295                 :     6333066 :            ig3max=max(ig3max,ig3); ig3min=min(ig3min,ig3)
     296                 :             :          end if
     297                 :             : 
     298                 :             :        end if ! Cut-off
     299                 :             :      end do ! End loop on i1
     300                 :             :    end do
     301                 :             :  end do
     302                 :             : 
     303                 :             : 
     304         [ +  + ]:   907950866 :  barev(:)=zero
     305                 :             : 
     306                 :             :  ! MG: This triggers SIGFPE as cryst is not initialized
     307                 :             :  !a1=Cryst%rprimd(:,1); b1=two_pi*gprimd(:,1)
     308                 :             :  !a2=Cryst%rprimd(:,2); b2=two_pi*gprimd(:,2)
     309                 :             :  !a3=Cryst%rprimd(:,3); b3=two_pi*gprimd(:,3)
     310                 :             : 
     311                 :      215534 :  select case(TRIM(vcut%mode))
     312                 :             :  case ('CRYSTAL', 'AUXILIARY_FUNCTION', "AUX_GB")
     313         [ +  - ]:        1296 :    if (vcut%mode == "CRYSTAL") then
     314                 :             :      ! Analytic integration of 4pi/q^2 over the volume element:
     315                 :             :      ! $4pi/V \int_V d^3q 1/q^2 =4pi bz_geometric_factor V^(-2/3)$
     316                 :             :      ! i_sz=4*pi*bz_geometry_factor*q0_vol**(-two_thirds) where q0_vol= V_BZ/N_k
     317                 :             :      ! bz_geometry_factor: sphere=7.79, fcc=7.44, sc=6.188, bcc=6.946, wz=5.255 (see gwa.pdf, appendix A.4)
     318                 :        1296 :      q0_vol = two_pi**3 / (nkpt_bz * ucvol)
     319                 :        1296 :      vcut%i_sz = four_pi*7.44*q0_vol**(-two_thirds)
     320                 :             : 
     321                 :             :    !TODO FBruneval: cryst is not available here, find a workaround!
     322                 :             :    !else if (vcut%mode == "AUXILIARY_FUNCTION") then
     323                 :             :    !  ! Numerical integration of the exact-exchange divergence through the
     324                 :             :    !  ! auxiliary function of Carrier et al. PRB 75, 205126 (2007) [[cite:Carrier2007]].
     325                 :             :    !  vcut%i_sz = carrier_isz(cryst, 1, qpoint, rcut, comm)
     326                 :             : 
     327                 :             :    !else if (vcut%mode == "AUX_GB") then
     328                 :             :    !  ! We use the auxiliary function of a Gygi-Baldereschi variant [[cite:Gigy1986]]
     329                 :             :    !  vcut%i_sz = gygi_baldereschi_isz(cryst, 1, qpoint, vc_ecut, ng, gvec)
     330                 :             : 
     331                 :             :    else
     332                 :           0 :      ABI_ERROR(sjoin("Need treatment of 1/q^2 singularity! for mode", vcut%mode))
     333                 :             :    end if
     334                 :             : 
     335         [ +  + ]:     5309712 :    do ig=1,nfft
     336         [ +  + ]:     5309712 :      if (abs(gpq(ig))<tol4) then
     337                 :         162 :        barev(ig) = vcut%i_sz
     338         [ +  + ]:     5308254 :      else if (gpq(ig)<=cutoff) then
     339                 :     1574640 :        barev(ig) = gpq2(ig)
     340                 :             :      end if
     341                 :             :    end do
     342                 :             : 
     343                 :             : 
     344                 :             :  case('SPHERE') ! Spherical cutoff
     345                 :             : 
     346                 :             :    !
     347                 :             :    ! Treatment of the divergence at q+g=zero
     348                 :             :    !
     349                 :             :    ! rcut is not set (rcut<=0), use the default Spencer-Alavi definition:
     350         [ +  + ]:      130986 :    if ( rcut < tol8 ) then
     351                 :      129594 :      rcut0= (three*nkpt_bz*ucvol/four_pi)**(one/three)
     352                 :             :    else
     353                 :             :      rcut0 = rcut
     354                 :             :    end if
     355                 :             : 
     356         [ +  + ]:   574623786 :    do ig=1,nfft
     357         [ +  + ]:   574623786 :      if (abs(gpq(ig))<tol4) then
     358                 :        8429 :        barev(ig) = two_pi*rcut0**two
     359         [ +  + ]:   574484371 :      else if (gpq(ig)<=cutoff) then
     360                 :   206086387 :        barev(ig) = gpq2(ig) * (one - cos( rcut0*sqrt(four_pi/gpq2(ig)) ) )
     361                 :             :      end if
     362                 :             :    end do
     363                 :             : 
     364                 :             :  case('CYLINDER')
     365                 :             :    !FBruneval: not working. For instance, Cryst is never initialized
     366                 :           0 :    ABI_BUG("Cylinder cutoff coding is not finalized")
     367                 :             : 
     368   [ #  #  #  # ]:           0 :    test=COUNT(ABS(vcut%vcutgeo)>tol6)
     369         [ #  # ]:           0 :    ABI_CHECK(test==1,'Wrong cutgeo for cylinder')
     370                 :             : 
     371                 :             :    ! === Beigi method is the default one, i.e infinite cylinder of radius rcut ===
     372                 :             :    ! * Negative values to use Rozzi method with finite cylinder of extent hcyl.
     373         [ #  # ]:           0 :    opt_cylinder=1; vcut%hcyl=zero; vcut%pdir(:)=0
     374         [ #  # ]:           0 :    do ii=1,3
     375                 :           0 :      check=vcut%vcutgeo(ii)
     376         [ #  # ]:           0 :      if (ABS(check)>tol6) then
     377                 :           0 :        vcut%pdir(ii)=1
     378         [ #  # ]:           0 :        if (check<zero) then  ! use Rozzi's method.
     379   [ #  #  #  #  :           0 :          vcut%hcyl=ABS(check)*NORM2(Cryst%rprimd(:,ii))
                   #  # ]
     380                 :           0 :          opt_cylinder=2
     381                 :             :        end if
     382                 :             :      end if
     383                 :             :    end do
     384                 :             : 
     385   [ #  #  #  # ]:           0 :    test=COUNT(vcut%pdir==1)
     386         [ #  # ]:           0 :    ABI_CHECK((test==1),'Wrong pdir for cylinder')
     387         [ #  # ]:           0 :    if (vcut%pdir(3)/=1) then
     388                 :           0 :      ABI_ERROR("The cylinder must be along the z-axis")
     389                 :             :    end if
     390                 :             : 
     391                 :           0 :    ABI_BUG("cutoff cylinder API has changed!")
     392                 :             : 
     393                 :             : !   call cutoff_cylinder(nfft,gq,ng,Gsph%gvec,vcut%rcut,vcut%hcyl,vcut%pdir,&
     394                 :             : !&                       vcut%boxcenter,Cryst%rprimd,barev,opt_cylinder,comm)
     395                 :             : 
     396                 :             :    ! === If Beigi, treat the limit q--> 0 ===
     397         [ #  # ]:           0 :    if (opt_cylinder==1) then
     398                 :           0 :      npar=8; npt=100 ; gamma_pt=RESHAPE((/0,0,0/),(/3,1/))
     399         [ #  # ]:           0 :      ABI_MALLOC(qfit,(3,npt))
     400         [ #  # ]:           0 :      ABI_MALLOC(vcfit,(1,npt))
     401         [ #  # ]:           0 :      if (nfft==1) then
     402                 :           0 :        ABI_ERROR("nfft == 1 not supported when Beigi's method is used")
     403                 :             :      endif
     404   [ #  #  #  # ]:           0 :      qfit(:,:)=zero
     405         [ #  # ]:           0 :      step=half/(npt*(nfft-1))              ; qfit(3,:)=arth(tol6,step,npt)
     406                 :             : 
     407                 :             :      !call cutoff_cylinder(npt,qfit,1,gamma_pt,vcut%rcut,vcut%hcyl,vcut%pdir,&
     408                 :             :      !                    vcut%boxcenter,Cryst%rprimd,vcfit,opt_cylinder,comm)
     409                 :             : 
     410         [ #  # ]:           0 :      ABI_MALLOC(xx,(npt))
     411         [ #  # ]:           0 :      ABI_MALLOC(yy,(npt))
     412         [ #  # ]:           0 :      ABI_MALLOC(sigma,(npt))
     413         [ #  # ]:           0 :      ABI_MALLOC(par,(npar))
     414         [ #  # ]:           0 :      ABI_MALLOC(var,(npar))
     415         [ #  # ]:           0 :      ABI_MALLOC(cov,(npar,npar))
     416         [ #  # ]:           0 :      do ii=1,npt
     417                 :           0 :       xx(ii)=normv(qfit(:,ii),gmet,'G')
     418                 :             :      end do
     419         [ #  # ]:           0 :      ABI_FREE(qfit)
     420   [ #  #  #  # ]:           0 :      sigma=one ; yy(:)=vcfit(1,:)
     421         [ #  # ]:           0 :      ABI_FREE(vcfit)
     422                 :             : 
     423                 :           0 :      bz_plane=l2norm(b1.x.b2)
     424                 :           0 :      dx=(xx(2)-xx(1))
     425                 :           0 :      integ=yy(2)*dx*3.0/2.0
     426         [ #  # ]:           0 :      integ=integ + SUM(yy(3:npt-2))*dx
     427                 :           0 :      integ=integ+yy(npt-1)*dx*3.0/2.0
     428                 :           0 :      write(std_out,*)' simple integral',integ
     429                 :           0 :      q0_volsph=(two_pi)**3/(nkpt_bz*ucvol)
     430                 :           0 :      q0_vol=bz_plane*two*xx(npt)
     431                 :           0 :      write(std_out,*)' q0 sphere : ',q0_volsph,' q0_vol cyl ',q0_vol
     432                 :           0 :      vcut%i_sz=bz_plane*two*integ/q0_vol
     433                 :           0 :      write(std_out,*)' spherical approximation ',four_pi*7.44*q0_volsph**(-two_thirds)
     434                 :           0 :      write(std_out,*)' Cylindrical cutoff value ',vcut%i_sz
     435                 :             : 
     436                 :           0 :      ABI_FREE(xx)
     437                 :           0 :      ABI_FREE(yy)
     438         [ #  # ]:           0 :      ABI_FREE(sigma)
     439         [ #  # ]:           0 :      ABI_FREE(par)
     440         [ #  # ]:           0 :      ABI_FREE(var)
     441         [ #  # ]:           0 :      ABI_FREE(cov)
     442                 :             : 
     443                 :             :    else
     444                 :             :      ! In Rozzi"s method the lim q+G --> 0 is finite.
     445                 :           0 :      vcut%i_sz=barev(1)
     446                 :             :    end if
     447                 :             : 
     448                 :             :  CASE('SLAB')
     449                 :             :    !FBruneval: not working. For instance, Cryst is never initialized
     450                 :           0 :    ABI_BUG("Slab cutoff coding is not finalized")
     451                 :             : 
     452   [ #  #  #  # ]:           0 :    test=COUNT(vcut%vcutgeo/=zero)
     453         [ #  # ]:           0 :    ABI_CHECK(test==2,"Wrong vcutgeo")
     454                 :             :    !
     455                 :             :    ! Two methods available
     456                 :             :    !
     457                 :             :    ! === Default is Beigi"s method ===
     458         [ #  # ]:           0 :    opt_slab=1; vcut%alpha(:)=zero
     459   [ #  #  #  #  :           0 :    if (ANY(vcut%vcutgeo<zero)) opt_slab=2
                   #  # ]
     460         [ #  # ]:           0 :    vcut%pdir(:)=zero
     461         [ #  # ]:           0 :    do ii=1,3
     462                 :           0 :      check=vcut%vcutgeo(ii)
     463         [ #  # ]:           0 :      if (ABS(check)>zero) then ! Use Rozzi"s method with a finite slab along x-y
     464                 :           0 :        vcut%pdir(ii)=1
     465   [ #  #  #  # ]:           0 :        if (check<zero) vcut%alpha(ii)=normv(check*Cryst%rprimd(:,ii),rmet,'R')
     466                 :             :      end if
     467                 :             :    end do
     468                 :             : 
     469                 :             :    ! Beigi"s method: the slab must be along x-y and R must be L_Z/2.
     470         [ #  # ]:           0 :    if (opt_slab==1) then
     471   [ #  #  #  #  :           0 :      ABI_CHECK(ALL(vcut%pdir == (/1,1,0/)),"Surface must be in the x-y plane")
                   #  # ]
     472                 :             :      !vcut%rcut = half*SQRT(DOT_PRODUCT(a3,a3))
     473                 :             :    end if
     474                 :             : 
     475                 :           0 :    ABI_BUG("cutoff surface API has changed!")
     476                 :             :    !call cutoff_slab(nfft,gq,ng,Gsph%gvec,gprimd,vcut%rcut,&
     477                 :             :    !   vcut%boxcenter,vcut%pdir,vcut%alpha,barev,opt_slab)
     478                 :             : 
     479                 :             :    !
     480                 :             :    ! === If Beigi, treat the limit q--> 0 ===
     481         [ #  # ]:           0 :    if (opt_slab==1) then
     482                 :             :      ! Integrate numerically in the plane close to 0
     483                 :           0 :      npt=100 ! Number of points in 1D
     484                 :             :      gamma_pt=RESHAPE((/0,0,0/),(/3,1/)) ! Gamma point
     485         [ #  # ]:           0 :      ABI_MALLOC(qfit,(3,npt))
     486         [ #  # ]:           0 :      ABI_MALLOC(qcart,(3,npt))
     487         [ #  # ]:           0 :      ABI_MALLOC(vcfit,(1,npt))
     488         [ #  # ]:           0 :      if (nfft==1) then
     489                 :           0 :        ABI_ERROR("nfft == 1 not supported when Beigi's method is used")
     490                 :             :      endif
     491   [ #  #  #  # ]:           0 :      qfit(:,:)=zero
     492   [ #  #  #  # ]:           0 :      qcart(:,:)=zero
     493                 :             :      ! Size of the third vector
     494                 :           0 :      bz_plane=l2norm(b3)
     495                 :           0 :      q0_volsph=(two_pi)**3/(nkpt_bz*ucvol)
     496                 :             :      ! radius that gives the same volume as q0_volsph
     497                 :             :      ! Let's assume that c is perpendicular to the plane
     498                 :             :      ! We also assume isotropic BZ around gamma
     499                 :           0 :      step=sqrt((q0_volsph/bz_plane)/pi)/npt
     500                 :             : 
     501                 :             :      !step=half/(npt*(Qmesh%nibz-1))
     502                 :             :      ! Let's take qpoints along 1 line, the vcut does depend only on the norm
     503         [ #  # ]:           0 :      qcart(1,:)=arth(tol6,step,npt)
     504                 :             : 
     505         [ #  # ]:           0 :      do ii = 1,npt
     506         [ #  # ]:           0 :        qfit(:,ii) = MATMUL(TRANSPOSE(Cryst%rprimd),qcart(:,ii))/(2*pi)
     507                 :             :      end do
     508                 :             : 
     509                 :           0 :      ABI_BUG("cutoff surface API has changed!")
     510                 :             : 
     511                 :             : !     call cutoff_slab(npt,qfit,1,gamma_pt,gprimd,vcut%rcut,&
     512                 :             : !       vcut%boxcenter,vcut%pdir,vcut%alpha,vcfit,opt_slab)
     513                 :             : 
     514         [ #  # ]:           0 :      ABI_MALLOC(xx,(npt))
     515         [ #  # ]:           0 :      ABI_MALLOC(yy,(npt))
     516         [ #  # ]:           0 :      ABI_MALLOC(sigma,(npt))
     517         [ #  # ]:           0 :      do ii=1,npt
     518                 :             :       !xx(ii)=qfit(1,:)
     519                 :           0 :       xx(ii)=normv(qfit(:,ii),gmet,'G')
     520                 :             :      end do
     521         [ #  # ]:           0 :      ABI_FREE(qfit)
     522         [ #  # ]:           0 :      sigma=one
     523         [ #  # ]:           0 :      yy(:)=vcfit(1,:)
     524                 :             :      !yy(:)=one
     525         [ #  # ]:           0 :      ABI_FREE(vcfit)
     526                 :           0 :      dx=(xx(2)-xx(1))
     527                 :             :      ! integ = \int dr r f(r)
     528                 :           0 :      integ=xx(2)*yy(2)*dx*3.0/2.0
     529         [ #  # ]:           0 :      integ=integ + DOT_PRODUCT(xx(3:npt-2),yy(3:npt-2))*dx
     530                 :           0 :      integ=integ+xx(npt-1)*yy(npt-1)*dx*3.0/2.0
     531                 :           0 :      write(std_out,*)' simple integral',integ
     532                 :           0 :      q0_vol=bz_plane*pi*xx(npt)**2
     533                 :           0 :      write(std_out,*)' q0 sphere : ',q0_volsph,' q0_vol cyl ',q0_vol
     534                 :           0 :      vcut%i_sz=bz_plane*2*pi*integ/q0_vol
     535                 :           0 :      write(std_out,*)' spherical approximation ',four_pi*7.44*q0_volsph**(-two_thirds)
     536                 :           0 :      write(std_out,*)' Cylindrical cutoff value ',vcut%i_sz
     537                 :             : 
     538                 :           0 :      ABI_FREE(xx)
     539                 :           0 :      ABI_FREE(yy)
     540                 :             :    else
     541                 :             :      ! In Rozzi"s method the lim q+G --> 0 is finite.
     542                 :           0 :      vcut%i_sz=barev(1)
     543                 :             :    end if
     544                 :             : 
     545                 :             :  CASE('ERF')
     546                 :             : 
     547         [ #  # ]:           0 :    do ig=1,nfft
     548         [ #  # ]:           0 :      if (abs(gpq(ig))<tol4) then
     549                 :             :         !FIXME FBruneval check this value, ERFC value was wrong, so why not this one.
     550                 :           0 :         barev(ig) = zero ! Stupid definition to remember something should be done here.
     551         [ #  # ]:           0 :      else if (gpq(ig)<=cutoff) then
     552                 :             :        !FIXME FBruneval shortrange does not make sense here (it is an optional argument that may not be present)
     553                 :             :        ! and ERF is long range any way
     554         [ #  # ]:           0 :        if (shortrange) then
     555                 :           0 :          barev(ig) = + gpq2(ig) * exp( -pi * rcut**2 /gpq2(ig) )
     556                 :             :        end if
     557                 :             :     end if
     558                 :             :    end do
     559                 :             : 
     560                 :             :  CASE('ERFC')
     561                 :             : 
     562         [ +  + ]:   328017368 :    do ig=1,nfft
     563         [ +  + ]:   328017368 :      if (abs(gpq(ig))<tol4) then
     564                 :             :         !FBruneval there was a wrong value here
     565                 :        4392 :         barev(ig) = pi * rcut**2
     566         [ +  + ]:   327931020 :      else if (gpq(ig)<=cutoff) then
     567                 :             :        ! gpq2 is 4 pi / (q+G)**2
     568                 :             :        ! 4 pi / (q+G)**2 * [ 1 - exp( -1/4 * Rc**2 * (q+G)**2 ) ]
     569                 :    89991532 :        barev(ig) = gpq2(ig) * ( one - exp( -pi * rcut**2 / gpq2(ig) ) )
     570                 :             :     end if
     571                 :             :    end do
     572                 :             : 
     573                 :             :  case default
     574                 :           0 :    write(msg,'(3a)')'No cut-off applied to the Coulomb Potential.', ch10, &
     575                 :           0 :                     'Either icutcoul value not allowed or not defined.'
     576   [ +  +  -  -  :      214238 :    ABI_WARNING(msg)
                -  +  - ]
     577                 :             :  end select
     578                 :             : 
     579         [ +  + ]:      214238 :  if (izero==1) then
     580                 :             :    ! Set contribution of unbalanced components to zero
     581         [ +  + ]:       11548 :    if (qeq0==1) then !q=0
     582                 :        2047 :      call zerosym(barev,cplex1,n1,n2,n3)
     583         [ +  + ]:        9501 :    else if (qeq05==1) then
     584                 :             :      !q=1/2; this doesn't work in parallel
     585         [ +  - ]:        5229 :      ig1=-1;if (mod(n1,2)==0) ig1=1+n1/2
     586         [ +  - ]:        5229 :      ig2=-1;if (mod(n2,2)==0) ig2=1+n2/2
     587         [ +  - ]:        5229 :      ig3=-1;if (mod(n3,2)==0) ig3=1+n3/2
     588         [ +  + ]:        5229 :      if (abs(abs(qpoint(1))-half)<tol12) then
     589         [ +  + ]:        2988 :        if (abs(ig1min)<abs(ig1max)) ig1=abs(ig1max)
     590         [ +  + ]:        2988 :        if (abs(ig1min)>abs(ig1max)) ig1=n1-abs(ig1min)
     591                 :             :      end if
     592         [ +  + ]:        5229 :      if (abs(abs(qpoint(2))-half)<tol12) then
     593         [ +  + ]:        2988 :        if (abs(ig2min)<abs(ig2max)) ig2=abs(ig2max)
     594         [ +  + ]:        2988 :        if (abs(ig2min)>abs(ig2max)) ig2=n2-abs(ig2min)
     595                 :             :      end if
     596         [ +  + ]:        5229 :      if (abs(abs(qpoint(3))-half)<tol12) then
     597         [ +  - ]:        2988 :        if (abs(ig3min)<abs(ig3max)) ig3=abs(ig3max)
     598         [ -  + ]:        2988 :        if (abs(ig3min)>abs(ig3max)) ig3=n3-abs(ig3min)
     599                 :             :      end if
     600                 :        5229 :      call zerosym(barev,cplex1,n1,n2,n3,ig1=ig1,ig2=ig2,ig3=ig3)
     601                 :             :    end if
     602                 :             :  end if
     603                 :             : 
     604         [ -  + ]:      214238 :  ABI_FREE(gq)
     605         [ -  + ]:      214238 :  ABI_FREE(gpq)
     606         [ -  + ]:      214238 :  ABI_FREE(gpq2)
     607                 :             : 
     608   [ -  +  -  +  :      214238 : end subroutine barevcoul
             -  +  -  + ]
     609                 :             : !!***
     610                 :             : 
     611   [ #  #  #  #  :           0 : end module m_barevcoul
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     612                 :             : !!***
        

Generated by: LCOV version 2.3-1