LCOV - code coverage report
Current view: top level - src/62_poisson - m_cutoff_cylinder.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 74.6 % 126 94
Test Date: 2026-11-10 16:57:26 Functions: 87.5 % 8 7
Branches: 64.5 % 121 78

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_cutoff_cylinder
       2                 :             : !! NAME
       3                 :             : !!  m_cutoff_cylinder
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! SOURCE
       8                 :             : 
       9                 :             : #if defined HAVE_CONFIG_H
      10                 :             : #include "config.h"
      11                 :             : #endif
      12                 :             : 
      13                 :             : #include "abi_common.h"
      14                 :             : 
      15                 :             : module m_cutoff_cylinder
      16                 :             : 
      17                 :             :  use defs_basis
      18                 :             :  use m_abicore
      19                 :             :  use m_errors
      20                 :             :  use m_xmpi
      21                 :             :  use m_splines
      22                 :             :  use m_sort
      23                 :             : 
      24                 :             :  use m_fstrings,        only : sjoin, itoa
      25                 :             :  use m_geometry,        only : normv, metric
      26                 :             :  use m_bessel,          only : CALJY0, CALJY1, CALCK0, CALCK1
      27                 :             :  use m_numeric_tools,   only : OPERATOR(.x.), quadrature
      28                 :             :  use m_paw_numeric,     only : paw_jbessel
      29                 :             : 
      30                 :             :  implicit none
      31                 :             : 
      32                 :             :  private
      33                 :             : !!***
      34                 :             : 
      35                 :             :  public :: cutoff_cylinder, K0cos
      36                 :             : 
      37                 :             :  !integer,public,parameter :: CYLINDER_BEIGI = 1
      38                 :             :  !integer,public,parameter :: CYLINDER_ROZZI = 2
      39                 :             : !!***
      40                 :             : 
      41                 :             : ! private variables used for the integration needed by the cylindrical case.
      42                 :             :  integer,save :: npts_,ntrial_,qopt_
      43                 :             :  real(dp),save :: ha_,hb_,r0_
      44                 :             :  real(dp),save :: qpg_perp_,qpg_para_,qpgx_,qpgy_
      45                 :             :  real(dp),save :: zz_,xx_, rho_
      46                 :             :  real(dp),save :: hcyl_,rcut_,accuracy_
      47                 :             : 
      48                 :             : CONTAINS
      49                 :             : !!***
      50                 :             : 
      51                 :             : !----------------------------------------------------------------------
      52                 :             : 
      53                 :             : !!****f* ABINIT/cutoff_cylinder
      54                 :             : !! NAME
      55                 :             : !! cutoff_cylinder
      56                 :             : !!
      57                 :             : !! FUNCTION
      58                 :             : !!  Calculate the Fourier components of an effective Coulomb interaction
      59                 :             : !!  zeroed outside a finite cylindrical region. Two methods are implemented:
      60                 :             : !!
      61                 :             : !!   method==1: The interaction in the (say) x-y plane is truncated outside the Wigner-Seitz
      62                 :             : !!              cell centered on the wire in the x-y plane. The interaction has infinite
      63                 :             : !!              extent along the z axis and the Fourier transform is singular only at the Gamma point.
      64                 :             : !!              Only orthorombic Bravais lattices are supported.
      65                 :             : !!   method==2: The interaction is truncated outside a cylinder of radius rcut. The cylinder has finite
      66                 :             : !!              extent along z. No singularity occurs.
      67                 :             : !!
      68                 :             : !! INPUTS
      69                 :             : !!  boxcenter(3)= center of the wire in the x-y axis
      70                 :             : !!  qpt(3)= q-point
      71                 :             : !!  ng=number of G vectors
      72                 :             : !!  gvec(3,ng)=G vectors in reduced coordinates
      73                 :             : !!  rprimd(3,3)=dimensional real space primitive translations (bohr)
      74                 :             : !!  method=1 for Beigi approach (infinite cylinder with interaction truncated outside the W-S cell)
      75                 :             : !!         2 for Rozzi method (finite cylinder)
      76                 :             : !!  comm=MPI communicator.
      77                 :             : !!
      78                 :             : !! OUTPUT
      79                 :             : !!  vc_cut(ng)= Fourier components of the effective Coulomb interaction
      80                 :             : !!
      81                 :             : !! SOURCE
      82                 :             : 
      83                 :         112 : subroutine cutoff_cylinder(qpt, ng, gvec, rcut, hcyl, pdir, boxcenter, rprimd, vc_cut, method, comm)
      84                 :             : 
      85                 :             : !Arguments ------------------------------------
      86                 :             : !scalars
      87                 :             :  integer,intent(in) :: ng,method,comm
      88                 :             :  real(dp),intent(in) :: rcut,hcyl
      89                 :             : !arrays
      90                 :             :  integer,intent(in) :: gvec(3,ng),pdir(3)
      91                 :             :  real(dp),intent(in) :: boxcenter(3),qpt(3),rprimd(3,3)
      92                 :             :  real(dp),intent(out) :: vc_cut(ng)
      93                 :             : 
      94                 :             : !Local variables-------------------------------
      95                 :             : !scalars
      96                 :             :  integer,parameter :: N0=1000
      97                 :             :  integer :: ig,igs,ierr, my_rank, nproc
      98                 :             :  real(dp) :: j0,j1,k0,k1,qpg2,qpg_xy,tmp
      99                 :             :  real(dp) :: qpg_z,quad,rcut2,hcyl2,c1,c2,ucvol,SMALL
     100                 :             :  logical :: q_is_zero
     101                 :             :  character(len=500) :: msg
     102                 :             : !arrays
     103                 :             :  real(dp) :: qpg(3),b1(3),b2(3),b3(3),gmet(3,3),rmet(3,3),gprimd(3,3),qc(3),gcart(3)
     104                 :             : !************************************************************************
     105                 :             : 
     106                 :             :  ABI_UNUSED(pdir)
     107                 :             :  ABI_UNUSED(boxcenter)
     108                 :             : 
     109                 :             :  ! ===================================================
     110                 :             :  ! === Setup for the quadrature of matrix elements ===
     111                 :             :  ! ===================================================
     112                 :         112 :  qopt_    =6         ! Quadrature method, see quadrature routine.
     113                 :         112 :  ntrial_  =30        ! Max number of attempts.
     114                 :         112 :  accuracy_=0.001     ! Fractional accuracy required.
     115                 :         112 :  npts_    =6         ! Initial number of point (only for Gauss-Legendre method).
     116                 :         112 :  SMALL    =tol4      ! Below this value (q+G)_i is treated as zero.
     117                 :         112 :  rcut_    =rcut      ! Radial cutoff, used only if method==2
     118                 :         112 :  hcyl_    =hcyl      ! Lenght of cylinder along z, only if method==2
     119                 :             : 
     120                 :             :  !write(msg,'(3a,2(a,i5,a),a,f8.5)')ch10,&
     121                 :             :  ! ' cutoff_cylinder: Info on the quadrature method : ',ch10,&
     122                 :             :  ! '  Quadrature scheme      = ',qopt_,ch10,&
     123                 :             :  ! '  Max number of attempts = ',ntrial_,ch10,&
     124                 :             :  ! '  Fractional accuracy    = ',accuracy_
     125                 :             :  !call wrtout(std_out, msg)
     126                 :             : 
     127                 :             :  ! From reduced to Cartesian coordinates.
     128                 :         112 :  call metric(gmet, gprimd, -1, rmet, rprimd, ucvol)
     129         [ +  + ]:         448 :  b1(:) =two_pi*gprimd(:,1)
     130         [ +  + ]:         448 :  b2(:) =two_pi*gprimd(:,2)
     131         [ +  + ]:         448 :  b3(:) =two_pi*gprimd(:,3)
     132                 :             : 
     133         [ +  + ]:         448 :  qc = b1(:)*qpt(1) + b2(:)*qpt(2) + b3(:)*qpt(3)
     134                 :             : 
     135                 :         112 :  my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
     136                 :             : 
     137                 :             :  ! ================================================
     138                 :             :  ! === Different approaches according to method ===
     139                 :             :  ! ================================================
     140         [ +  + ]:        1640 :  vc_cut = zero
     141                 :             : 
     142                 :         112 :  select case (method)
     143                 :             : 
     144                 :             :  case (1)
     145                 :             :    ! Infinite cylinder, interaction is zeroed outside the Wigner-Seitz cell.
     146                 :             :    ! NB: Beigi's expression holds only if the BZ is sampled only along z.
     147                 :             :    !call wrtout(std_out, 'cutoff_cylinder: Using Beigi''s Infinite cylinder')
     148                 :             : 
     149   [ +  +  +  -  :         318 :    if (ANY(qc(1:2) > SMALL)) then
                   -  + ]
     150                 :             :      write(msg,'(5a)')&
     151                 :           0 :       ' found q-points with non zero components in the X-Y plane. ',ch10,&
     152                 :           0 :       ' This is not allowed, see Notes in cutoff_cylinder.F90. ',ch10,&
     153                 :           0 :       ' ACTION: Modify the q-point sampling. '
     154                 :           0 :      ABI_ERROR(msg)
     155                 :             :    end if
     156                 :             : 
     157                 :             :    ! Check if Bravais lattice is orthorombic and parallel to the Cartesian versors.
     158                 :             :    ! In this case the intersection of the WS cell with the x-y plane is a rectangle with -ha_<=x<=ha_ and -hb_<=y<=hb_
     159                 :             :    if ((ANY(ABS(rprimd(2:3,  1)) > tol6)) .or. &
     160   [ +  +  +  -  :         954 :        (ANY(ABS(rprimd(1:3:2,2)) > tol6)) .or. &
          +  +  +  -  +  
          +  +  -  +  -  
                   -  + ]
     161                 :             :        (ANY(ABS(rprimd(1:2,  3)) > tol6))) then
     162                 :           0 :      ABI_ERROR('Bravais lattice should be orthorombic and parallel to the Cartesian versors')
     163                 :             :    end if
     164                 :             : 
     165   [ +  +  +  +  :         424 :    ha_ = half*NORM2(rprimd(:,1))
                   +  - ]
     166   [ +  +  +  +  :         424 :    hb_ = half*NORM2(rprimd(:,2))
                   +  - ]
     167                 :         106 :    r0_ = MIN(ha_,hb_)/N0
     168                 :             : 
     169                 :             :    ! For each (q,G) pair evaluate the integral defining the Coulomb cutoff.
     170                 :             :    ! NB: the code assumes that all q-vectors are non zero and q_xy/=0.
     171                 :         106 :    igs=1
     172                 :             :    ! Skip singularity at Gamma, it will be treated "by hand" in csigme.
     173                 :         106 :    q_is_zero = (normv(qpt, gmet, 'G') < tol4)
     174                 :             : 
     175         [ +  + ]:         920 :    do ig=igs,ng
     176         [ -  + ]:         814 :      if (mod(ig, nproc) /= my_rank) cycle ! MPI parallelism
     177                 :             : 
     178         [ +  + ]:        3256 :      gcart(:)=b1(:)*gvec(1,ig)+b2(:)*gvec(2,ig)+b3(:)*gvec(3,ig)
     179         [ +  + ]:        3256 :      qpg(:)=qc(:)+gcart(:)
     180                 :         814 :      qpgx_=qpg(1); qpgy_=qpg(2); qpg_para_=ABS(qpg(3))
     181                 :             :      !write(std_out,*)"qpgx_=",qpgx_, "qpgy_=",qpgy_, "qpg_para=",qpg_para_
     182                 :             : 
     183                 :             :      ! Avoid singularity in K_0{qpg_para_\rho) by using a small q along the periodic dimension.
     184   [ +  +  +  + ]:         814 :      if (q_is_zero .and. qpg_para_ < tol6) qpg_para_ = tol6
     185                 :             : 
     186                 :             :      ! Calculate $ 2\int_{WS} dxdy K_0{qpg_para_\rho) cos(x.qpg_x + y.qpg_y) $
     187                 :             :      ! where WS is the Wigner-Seitz cell.
     188                 :         814 :      tmp=zero
     189                 :             : 
     190                 :             :      ! Difficult part, integrate on a small cirle of radius r0 using spherical coordinates
     191                 :             :      !call quadrature(K0cos_dth_r0,zero,r0_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     192                 :             :      !ABI_CHECK(ierr == 0, "Accuracy not reached")
     193                 :             :      !write(std_out,'(i8,a,es14.6)')ig,' 1 ',quad
     194                 :             :      !tmp=tmp+quad
     195                 :             :      ! Add region with 0<=x<=r0 and y>=+-(SQRT(r0^2-x^2))since WS is rectangular
     196                 :             :      !call quadrature(K0cos_dy_r0,zero,r0_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     197                 :             :      !ABI_CHECK(ierr == 0, "Accuracy not reached")
     198                 :             :      !write(std_out,'(i8,a,es14.6)')ig,' 2 ',quad
     199                 :             :      !tmp=tmp+quad
     200                 :             :      ! Get the in integral in the rectangle with x>=r0, should be the easiest but sometimes has problems to converge
     201                 :             :      !call quadrature(K0cos_dy,r0_,ha_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     202                 :             :      !ABI_CHECK(ierr == 0, "Accuracy not reached")
     203                 :             :      !write(std_out,'(i8,a,es14.6)')ig,' 3 ',quad
     204                 :             :      !
     205                 :             :      ! More stable method: midpoint integration with Romberg extrapolation ===
     206                 :         814 :      call quadrature(K0cos_dy,zero,ha_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     207                 :             :      !write(std_out,'(i8,a,es14.6)')ig,' 3 ',quad
     208         [ -  + ]:         814 :      ABI_CHECK(ierr == 0, "Accuracy not reached in quadrature!")
     209                 :             : 
     210                 :             :      ! Store final result
     211                 :             :      ! Factor two comes from the replacement WS -> (1,4) quadrant thanks to symmetries of the integrad.
     212                 :         814 :      tmp = tmp+quad
     213                 :         920 :      vc_cut(ig) = two*(tmp*two)
     214                 :             :    end do ! ig
     215                 :             : 
     216                 :             :  case (2)
     217                 :             :    ! Finite cylinder of length hcyl from Rozzi et al.
     218                 :             :    ! TODO add check on hcyl value that should be smaller that 1/deltaq
     219         [ -  + ]:           6 :    if (hcyl_ < zero) then
     220                 :           0 :      write(msg,'(a,f8.4)')' Negative value for cylinder length hcyl_=',hcyl_
     221                 :           0 :      ABI_BUG(msg)
     222                 :             :    end if
     223                 :             : 
     224         [ +  - ]:           6 :    if (ABS(hcyl_) > tol12) then
     225                 :             :      !write(std_out,'(2(a,f8.4))')' cutoff_cylinder: using finite cylinder of length= ',hcyl_,' rcut= ',rcut_
     226                 :           6 :      hcyl2=hcyl_**2
     227                 :           6 :      rcut2=rcut_**2
     228                 :             : 
     229                 :             :      ! No singularity occurs in finite cylinder, thus start from 1.
     230         [ +  + ]:         720 :      do ig=1,ng
     231         [ +  - ]:         714 :        if (mod(ig, nproc) /= my_rank) cycle ! MPI parallelism
     232                 :             : 
     233         [ +  + ]:        2856 :        gcart(:)=b1(:)*gvec(1,ig)+b2(:)*gvec(2,ig)+b3(:)*gvec(3,ig)
     234         [ +  + ]:        2856 :        qpg(:)=qc(:)+gcart(:)
     235                 :         714 :        qpg_para_=ABS(qpg(3)) ; qpg_perp_=SQRT(qpg(1)**2+qpg(2)**2)
     236                 :             : 
     237   [ +  +  +  + ]:         720 :        if (qpg_perp_ /= zero .and. qpg_para_ /= zero) then
     238                 :             :          ! $ 4\pi\int_0^{R_c} d\rho\rho j_o(qpg_perp_.\rho)\int_0^hcyl dz\cos(qpg_para_*z)/sqrt(\rho^2+z^2) $
     239                 :         655 :          call quadrature(F2,zero,rcut_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     240         [ -  + ]:         655 :          ABI_CHECK(ierr == 0, "Accuracy not reached")
     241                 :         655 :          vc_cut(ig) = four_pi*quad
     242                 :             : 
     243   [ +  +  +  + ]:          59 :        else if (qpg_perp_ == zero .and. qpg_para_ /= zero) then
     244                 :             :          ! $ \int_0^h sin(qpg_para_.z)/\sqrt(rcut^2+z^2)dz $
     245                 :          14 :          call quadrature(F3,zero,hcyl_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     246         [ -  + ]:          14 :          ABI_CHECK(ierr == 0, "Accuracy not reached")
     247                 :             : 
     248                 :          14 :          c1=one/qpg_para_**2-COS(qpg_para_*hcyl_)/qpg_para_**2-hcyl_*SIN(qpg_para_*hcyl_)/qpg_para_
     249                 :          14 :          c2=SIN(qpg_para_*hcyl_)*SQRT(hcyl2+rcut2)
     250                 :          14 :          vc_cut(ig) = four_pi*c1+four_pi*(c2-quad)/qpg_para_
     251                 :             : 
     252   [ +  +  +  - ]:          45 :        else if (qpg_perp_ /= zero .and. qpg_para_ == zero) then
     253                 :             :          ! $ 4pi\int_0^rcut d\rho \rho J_o(qpg_perp_.\rho) ln((h+\sqrt(h^2+\rho^2))/\rho) $
     254                 :          44 :          call quadrature(F4,zero,rcut_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     255         [ -  + ]:          44 :          ABI_CHECK(ierr == 0, "Accuracy not reached")
     256                 :          44 :          vc_cut(ig) = four_pi*quad
     257                 :             : 
     258   [ +  -  +  - ]:           1 :        else if (qpg_perp_ == zero .and. qpg_para_ == zero) then
     259                 :             :          ! Use lim q+G --> 0
     260                 :           1 :          vc_cut(ig) = two_pi*(-hcyl2+hcyl_*SQRT(hcyl2+rcut2)+rcut2*LOG((hcyl_+SQRT(hcyl_+SQRT(hcyl2+rcut2)))/rcut_))
     261                 :             : 
     262                 :             :        else
     263                 :           0 :          ABI_BUG('You should not be here!')
     264                 :             :        end if
     265                 :             : 
     266                 :             :      end do !ig
     267                 :             : 
     268                 :             :    else
     269                 :             :      ! Infinite cylinder.
     270                 :             :      !call wrtout(std_out, ' cutoff_cylinder: using Rozzi''s method with infinite cylinder ')
     271                 :             : 
     272         [ #  # ]:           0 :      do ig=1,ng
     273         [ #  # ]:           0 :        if (mod(ig, nproc) /= my_rank) cycle ! MPI parallelism
     274                 :             : 
     275         [ #  # ]:           0 :        gcart(:)=b1(:)*gvec(1,ig)+b2(:)*gvec(2,ig)+b3(:)*gvec(3,ig)
     276         [ #  # ]:           0 :        qpg(:)=qc(:)+gcart(:)
     277         [ #  # ]:           0 :        qpg2  =DOT_PRODUCT(qpg,qpg)
     278                 :           0 :        qpg_z =ABS(qpg(3)) ; qpg_xy=SQRT(qpg(1)**2+qpg(2)**2)
     279                 :             : 
     280         [ #  # ]:           0 :        if (qpg_z > SMALL) then
     281                 :             :          ! Analytic expression.
     282                 :           0 :          call CALCK0(qpg_z *rcut_, k0, 1)
     283                 :           0 :          call CALJY1(qpg_xy*rcut_, j1, 0)
     284                 :           0 :          call CALJY0(qpg_xy*rcut_, j0, 0)
     285                 :           0 :          call CALCK1(qpg_z *rcut_, k1, 1)
     286                 :           0 :          vc_cut(ig) = (four_pi/qpg2)*(one+rcut_*qpg_xy*j1*k0-qpg_z*rcut_*j0*k1)
     287                 :             :        else
     288         [ #  # ]:           0 :          if (qpg_xy > SMALL) then
     289                 :             :            ! Integrate r*Jo(G_xy r)log(r) from 0 up to rcut_
     290                 :           0 :            call quadrature(F5,zero,rcut_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     291         [ #  # ]:           0 :            ABI_CHECK(ierr == 0, "Accuracy not reached")
     292                 :           0 :            vc_cut(ig)=-four_pi*quad
     293                 :             :          else
     294                 :             :            ! Analytic expression
     295                 :           0 :            vc_cut(ig)=-pi*rcut_**2*(two*LOG(rcut_)-one)
     296                 :             :          end if
     297                 :             :        end if
     298                 :             :      end do ! ig
     299                 :             :    end if !finite/infinite
     300                 :             : 
     301                 :             :  case default
     302      [ +  +  - ]:         112 :    ABI_BUG(sjoin('Wrong value for method:',itoa(method)))
     303                 :             :  end select
     304                 :             : 
     305                 :             :  ! Collect vc_cut on each core
     306                 :         112 :  call xmpi_sum(vc_cut, comm, ierr)
     307                 :             : 
     308                 :         112 : end subroutine cutoff_cylinder
     309                 :             : !!***
     310                 :             : 
     311                 :             : !----------------------------------------------------------------------
     312                 :             : 
     313                 :     4297455 : real(dp) function F1(rho)
     314                 :             : 
     315                 :             :  real(dp),intent(in) :: rho
     316                 :             : 
     317                 :             : !Local variables-------------------------------
     318                 :             :  integer,parameter :: order=0,ll=0
     319                 :             :  real(dp) :: arg,bes,besp,bespp
     320                 :             : !************************************************************************
     321                 :             : 
     322                 :             :  ! F1(\rho;z)= \rho*j_o(qpg_perp_*\rho)/sqrt(\rho**2+z**2)
     323                 :     4297455 :  arg=rho*qpg_perp_
     324                 :     4297455 :  call paw_jbessel(bes,besp,bespp,ll,order,arg)
     325                 :             : 
     326         [ -  + ]:     4297455 :  if (zz_==zero) then
     327                 :           0 :    F1=bes
     328                 :             :  else
     329                 :     4297455 :    F1=bes*rho/SQRT(rho**2+zz_**2)
     330                 :             :  end if
     331                 :             : 
     332                 :     4297455 : end function F1
     333                 :             : !!***
     334                 :             : 
     335                 :             : !----------------------------------------------------------------------
     336                 :             : 
     337                 :       53055 : function F2(xx)
     338                 :             : 
     339                 :             :  real(dp),intent(in) :: xx
     340                 :             :  real(dp) :: F2
     341                 :             : 
     342                 :             : !Local variables-------------------------------
     343                 :             : !scalars
     344                 :             :  integer :: ierr
     345                 :             :  real(dp) :: intr
     346                 :             : !************************************************************************
     347                 :             : 
     348                 :       53055 :  zz_=xx
     349                 :       53055 :  call quadrature(F1,zero,rcut_,qopt_,intr,ierr,ntrial_,accuracy_,npts_)
     350         [ -  + ]:       53055 :  ABI_CHECK(ierr == 0, "Accuracy not reached")
     351                 :             : 
     352                 :       53055 :  F2=intr*COS(qpg_para_*xx)
     353                 :             : 
     354                 :       53055 : end function F2
     355                 :             : !!***
     356                 :             : 
     357                 :             : !----------------------------------------------------------------------
     358                 :             : 
     359                 :        1134 : real(dp) pure function F3(xx)
     360                 :             : 
     361                 :             :  real(dp),intent(in) :: xx
     362                 :             : 
     363                 :             : !************************************************************************
     364                 :             : 
     365                 :             :  ! F3(z)=z*\sin(qpg_para_*z)/\sqrt(rcut^2+z^2)
     366                 :        1134 :  F3=xx*SIN(qpg_para_*xx)/SQRT(rcut_**2+xx**2)
     367                 :             : 
     368                 :        1134 : end function F3
     369                 :             : !!***
     370                 :             : 
     371                 :             : !----------------------------------------------------------------------
     372                 :             : 
     373                 :        3564 : real(dp) function F4(rho)
     374                 :             : 
     375                 :             :  real(dp),intent(in) :: rho
     376                 :             : 
     377                 :             : !Local variables-------------------------------
     378                 :             :  integer,parameter :: order=0,ll=0
     379                 :             :  real(dp) :: arg,bes,besp,bespp
     380                 :             : !************************************************************************
     381                 :             : 
     382                 :             :  ! $F4(rho)=\rho*j_o(qpg_perp_.\rho) \ln((hcyl+\sqrt(rho^2+hcyl^2))/\rho)$
     383         [ +  - ]:        3564 :  if (ABS(rho)<tol12) then
     384                 :             :    F4=zero
     385                 :             :  else
     386                 :        3564 :    arg=rho*qpg_perp_
     387                 :        3564 :    call paw_jbessel(bes,besp,bespp,ll,order,arg)
     388                 :        3564 :    F4=bes*rho*LOG((hcyl_+SQRT(rho**2+hcyl_**2))/rho)
     389                 :             :  end if
     390                 :             : 
     391                 :        3564 : end function F4
     392                 :             : !!***
     393                 :             : 
     394                 :             : !----------------------------------------------------------------------
     395                 :             : 
     396                 :           0 : real(dp) function F5(rho)
     397                 :             : 
     398                 :             :  real(dp),intent(in) :: rho
     399                 :             : 
     400                 :             : !Local variables-------------------------------
     401                 :             :  integer,parameter :: order = 0, ll = 0
     402                 :             :  real(dp) :: arg,bes,besp,bespp
     403                 :             : !************************************************************************
     404                 :             : 
     405                 :             :  ! $F5(\rho)=\rho*j_o(G_perp\rho)log(\rho)$
     406         [ #  # ]:           0 :  if (rho==0) then
     407                 :             :    F5=zero
     408                 :             :  else
     409                 :           0 :    arg=rho*qpg_perp_
     410                 :           0 :    call paw_jbessel(bes,besp,bespp,ll,order,arg)
     411                 :           0 :    F5=bes*rho*LOG(rho)
     412                 :             :  end if
     413                 :             : 
     414                 :           0 : end function F5
     415                 :             : !!***
     416                 :             : 
     417                 :             : !----------------------------------------------------------------------
     418                 :             : 
     419                 :     5345190 : real(dp) function K0cos(yy)
     420                 :             : 
     421                 :             :  real(dp),intent(in) :: yy
     422                 :             : 
     423                 :             : !Local variables-------------------------------
     424                 :             :  real(dp) :: k0,rho,arg
     425                 :             : !************************************************************************
     426                 :             : 
     427                 :             :  ! K0cos(y)=K0(\rho*|qpg_z|)*COS(x.qpg_x+y*qpg_y)
     428                 :     5345190 :  rho=SQRT(xx_**2+yy**2) ; arg=qpg_para_*rho
     429                 :     5345190 :  call CALCK0(arg,k0,1)
     430                 :     5345190 :  K0cos=k0*COS(qpgx_*xx_+qpgy_*yy)
     431                 :             : 
     432                 :     5345190 : end function K0cos
     433                 :             : !!***
     434                 :             : 
     435                 :             : !----------------------------------------------------------------------
     436                 :             : 
     437                 :       65934 : real(dp) function K0cos_dy(xx)
     438                 :             : 
     439                 :             :  real(dp),intent(in) :: xx
     440                 :             : 
     441                 :             : !Local variables-------------------------------
     442                 :             :  integer :: ierr
     443                 :             :  real(dp) :: quad
     444                 :             : !************************************************************************
     445                 :             : 
     446                 :             :  !! K0cos_dy(x)=\int_{-b/2}^{b/2} K0(|qpg_z|\rho)cos(x.qpg_x+y.qpg_y)dy$
     447                 :       65934 :  xx_=xx
     448                 :       65934 :  call quadrature(K0cos,-hb_,+hb_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     449         [ -  + ]:       65934 :  ABI_CHECK(ierr == 0, "Accuracy not reached")
     450                 :             : 
     451                 :       65934 :  K0cos_dy=quad
     452                 :             : 
     453                 :       65934 : end function K0cos_dy
     454                 :             : !!***
     455                 :             : 
     456                 :             : 
     457                 :             : 
     458                 :             : 
     459                 :             : !----------------------------------------------------------------------
     460                 :             : 
     461                 :             : real(dp) function K0cos_dy_r0(xx)
     462                 :             : 
     463                 :             :  real(dp),intent(in) :: xx
     464                 :             : 
     465                 :             : !Local variables-------------------------------
     466                 :             : !scalars
     467                 :             :  integer :: ierr
     468                 :             :  real(dp) :: quad,yx
     469                 :             : !************************************************************************
     470                 :             : 
     471                 :             :  ! $ K0cos_dy_r0(x)= \int_{-b/2}^{-y(x)} K0(|qpg_z|\rho) cos(x.qpg_x+y.qpg_y)dy
     472                 :             :  !                  +\int_{y(x)}^{b/2} K0(|qpg_z|\rho)cos(x.qpg_x+y.qpg_y)dy$
     473                 :             :  ! where y(x)=SQRT(r0^2-x^2) and x<=r0
     474                 :             :  !
     475                 :             :  xx_=xx; yx=SQRT(r0_**2-xx**2)
     476                 :             :  call quadrature(K0cos,-hb_,-yx,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     477                 :             :  ABI_CHECK(ierr == 0, "Accuracy not reached in quadrature")
     478                 :             :  K0cos_dy_r0=quad
     479                 :             : 
     480                 :             :  call quadrature(K0cos,+yx,+hb_,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     481                 :             :  ABI_CHECK(ierr == 0, "Accuracy not reached in quadrature")
     482                 :             : 
     483                 :             :  K0cos_dy_r0=quad+K0cos_dy_r0
     484                 :             : 
     485                 :             : end function K0cos_dy_r0
     486                 :             : !!***
     487                 :             : 
     488                 :             : !----------------------------------------------------------------------
     489                 :             : 
     490                 :             : real(dp) function K0cos_dth_r0(rho)
     491                 :             : 
     492                 :             :  real(dp),intent(in) :: rho
     493                 :             : 
     494                 :             : !Local variables-------------------------------
     495                 :             : !scalars
     496                 :             :  integer :: ierr
     497                 :             :  real(dp) :: quad,arg,k0,tmp
     498                 :             : 
     499                 :             : !************************************************************************
     500                 :             : 
     501                 :             :  ! $ K0cos_dth_r0(\rho)=
     502                 :             :  ! \int_{0}^{2pi)} K0(|qpg_z|\rho)cos(\rho.cos(\theta).qpg_x+\rho.sin(\theta).qpg_y) d\theta $
     503                 :             :  !
     504                 :             :  ! where y(x)=SQRT(r0^2-x^2) and x<=r0
     505                 :             :  !
     506                 :             :  rho_=rho
     507                 :             :  call quadrature(Fcos_th,zero,two_pi,qopt_,quad,ierr,ntrial_,accuracy_,npts_)
     508                 :             :  ABI_CHECK(ierr == 0, "Accuracy not reached in quadrature")
     509                 :             : 
     510                 :             :  arg=qpg_para_*rho_
     511                 :             :  tmp=zero
     512                 :             :  if (arg>tol6) then
     513                 :             :    call CALCK0(arg,k0,1)
     514                 :             :    tmp=k0*rho_
     515                 :             :  end if
     516                 :             :  K0cos_dth_r0=quad*tmp
     517                 :             : 
     518                 :             : end function K0cos_dth_r0
     519                 :             : !!***
     520                 :             : 
     521                 :             : !----------------------------------------------------------------------
     522                 :             : 
     523                 :             : pure real(dp) function Fcos_th(theta)
     524                 :             : 
     525                 :             :  real(dp),intent(in) :: theta
     526                 :             : 
     527                 :             : !************************************************************************
     528                 :             : 
     529                 :             :  ! $ Fcos_th(\theta)=rho*K0(\rho*|qpg_z|)*COS(\rho.COS(\theta).qpg_x+\rho.SIN/(\theta)*qpg_y) $
     530                 :             : 
     531                 :             :  !arg=qpg_para_*rho_
     532                 :             :  !call CALCK0(arg,k0,1)
     533                 :             :  !tmp=k0*rho_
     534                 :             :  Fcos_th=COS(rho_*COS(theta)*qpgx_+rho_*SIN(theta)*qpgy_)
     535                 :             : 
     536                 :             : end function Fcos_th
     537                 :             : !!***
     538                 :             : 
     539                 :             : !----------------------------------------------------------------------
     540                 :             : 
     541                 :             : !the following functions should be used to deal with the singularity in the Cylindrical cutoff
     542                 :             : !TODO Not yet used and indeed are still private
     543                 :             : 
     544                 :             : function K0fit(mq,nn) result(vals)
     545                 :             : 
     546                 :             :  integer,intent(in) :: nn
     547                 :             :  real(dp),intent(in) :: mq
     548                 :             :  real(dp) :: vals(nn)
     549                 :             : 
     550                 :             : !Local variables-------------------------------
     551                 :             : !scalars
     552                 :             :  integer :: ii
     553                 :             :  real(dp) :: mqh
     554                 :             : !arrays
     555                 :             :  real(dp),parameter :: cc(7)=(/-0.57721566,0.42278420,0.23069756, &
     556                 :             :                                 0.03488590,0.00262698,0.00010750,0.00000740/)
     557                 :             :  ! *************************************************************************
     558                 :             : 
     559                 :             :  if (nn>8.or.nn<1) then
     560                 :             :    ABI_ERROR("nn>8.or.nn<1 not implemented")
     561                 :             :  end if
     562                 :             : 
     563                 :             :  ! === Eq 9.8.5 in Abramovitz ===
     564                 :             :  vals(1)=-LOG(mq*half)*I0(mq)
     565                 :             :  mqh=mq*half
     566                 :             :  do ii=2,nn
     567                 :             :    vals(ii)=cc(ii-1)*mqh**(2*(ii-2))
     568                 :             :  end do
     569                 :             : 
     570                 :             : end function K0fit
     571                 :             : 
     572                 :             : real(dp) function K0fit_int(mq,par,nn) result(integ)
     573                 :             : 
     574                 :             :  integer,intent(in) :: nn
     575                 :             :  real(dp),intent(in) :: mq
     576                 :             :  real(dp),intent(in) :: par(nn)
     577                 :             : 
     578                 :             : !Local variables-------------------------------
     579                 :             : !scalars
     580                 :             :  integer :: ii,aa
     581                 :             :  real(dp) :: mqh
     582                 :             : !arrays
     583                 :             :  real(dp),parameter :: cc(7)=(/-0.57721566,0.42278420,0.23069756,&
     584                 :             : &                               0.03488590,0.00262698,0.00010750,0.00000740/)
     585                 :             :  ! *************************************************************************
     586                 :             : 
     587                 :             :  if (nn>8.or.nn<1) then
     588                 :             :    ABI_ERROR("nn>8.or.nn<1 not implemented")
     589                 :             :  end if
     590                 :             : 
     591                 :             :  mqh=mq*half
     592                 :             :  integ=-par(1)*int_I0ln(mqh)
     593                 :             :  ! primitive of polynomial \sum_0^{N/2} cc_{2i} (x/2)^{2*i}
     594                 :             :  do ii=2,nn
     595                 :             :   aa=(2*(ii-1)+1)
     596                 :             :   integ=integ+par(ii)*two*cc(ii-1)*(mqh**aa)/aa
     597                 :             :  end do
     598                 :             : 
     599                 :             : end function K0fit_int
     600                 :             : 
     601                 :             : real(dp) function I0(xx)
     602                 :             : 
     603                 :             :  real(dp),intent(in) :: xx
     604                 :             : 
     605                 :             : !Local variables-------------------------------
     606                 :             :  real(dp) :: tt
     607                 :             : 
     608                 :             : ! *************************************************************************
     609                 :             : 
     610                 :             :  ! Eq 9.8.1 of Abramovitz, entering the expansion of K0 -->0
     611                 :             :  ! Expansion holds for |x|<3.75, Error<1.6*10D-07
     612                 :             :  tt=xx/3.75
     613                 :             :  I0=one+3.5156229*tt**2+3.0899424*tt**4 +1.2067492*tt**6 &
     614                 :             :        +0.2659732*tt**8+0.0360768*tt**10+0.0045813*tt**12
     615                 :             : end function I0
     616                 :             : 
     617                 :             : ! Primitive of x^m Ln(x) for m/=-1
     618                 :             : real(dp) function int_xmln(xx,mm)  result(res)
     619                 :             : 
     620                 :             :  integer,intent(in) :: mm
     621                 :             :  real(dp),intent(in) :: xx
     622                 :             : 
     623                 :             : ! *********************************************************************
     624                 :             : 
     625                 :             :  if (mm==-1) then
     626                 :             :    ABI_BUG('invalid value for mm')
     627                 :             :  end if
     628                 :             : 
     629                 :             :  if (xx<=zero) then
     630                 :             :    ABI_BUG(' invalid value for xx')
     631                 :             :  end if
     632                 :             : 
     633                 :             :  res= (xx**(mm+1))/(mm+1) * (LOG(xx) - one/(mm+1))
     634                 :             : 
     635                 :             : end function int_xmln
     636                 :             : 
     637                 :             : ! Primitive function of ln(x/2)*I0(x) = sum_0^{N/2} 2^{2s+1} c_{2s} T(x/2,2s)
     638                 :             : ! where T(x,s)=\int x^s ln(x)dx
     639                 :             : real(dp) function int_I0ln(xx) result(res)
     640                 :             : 
     641                 :             : !Arguments ------------------------------------
     642                 :             :  real(dp),intent(in) :: xx
     643                 :             : 
     644                 :             : !Local variables-------------------------------
     645                 :             :  real(dp) :: yy
     646                 :             : ! *********************************************************************
     647                 :             : 
     648                 :             :  yy=xx*half
     649                 :             :  res =  (       one*2    *int_xmln(yy,0)  &
     650                 :             : &        +3.5156229*2**3 *int_xmln(yy,2)  &
     651                 :             : &        +3.0899424*2**5 *int_xmln(yy,4)  &
     652                 :             : &        +1.2067492*2**7 *int_xmln(yy,6)  &
     653                 :             : &        +0.2659732*2**9 *int_xmln(yy,8)  &
     654                 :             : &        +0.0360768*2**11*int_xmln(yy,10) &
     655                 :             : &        +0.0045813*2**13*int_xmln(yy,12) &
     656                 :             : &       )
     657                 :             : 
     658                 :             : end function int_I0ln
     659                 :             : !!***
     660                 :             : 
     661                 :             : end module m_cutoff_cylinder
     662                 :             : !!***
        

Generated by: LCOV version 2.3-1