LCOV - code coverage report
Current view: top level - hybrid - hsefunctional.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 0 771 0.0 %
Date: 2024-04-24 04:44:14 Functions: 0 26 0.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2016 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : 
       7             : ! Provides all procedures needed to implement the HSE-exchange functional
       8             : ! within a FLAPW framework
       9             : ! Author: M. Schlipf 2009
      10             : MODULE m_hsefunctional
      11             :    USE m_judft
      12             :    USE m_types_hybdat
      13             :    IMPLICIT NONE
      14             : 
      15             : #ifdef __PGI
      16             :    REAL, EXTERNAL ::erfc
      17             : #endif
      18             :    ! Constant omega of the HSE exchange functional
      19             :    REAL, PARAMETER :: omega_HSE = 0.11
      20             : 
      21             :    ! Constant for the maximum number of G points
      22             :    INTEGER, PARAMETER :: maxNoGPts = 50
      23             : 
      24             :    ! these arrays are calculated once and then reused
      25             :    LOGICAL, ALLOCATABLE   :: already_known(:)
      26             :    REAL, ALLOCATABLE      :: known_potential(:, :)
      27             : #ifdef CPP_INVERSION
      28             :    REAL, ALLOCATABLE      :: known_fourier_trafo(:, :, :)
      29             : #else
      30             :    COMPLEX, ALLOCATABLE   :: known_fourier_trafo(:, :, :)
      31             : #endif
      32             : 
      33             :    ! variables needed for fourier transformation
      34             :    PRIVATE already_known, known_potential, known_fourier_trafo
      35             : 
      36             :    ! functions needed internally
      37             :    PRIVATE calcYlm, calcSphBes, my_dot_product3x1, my_dot_product3x3, my_dot_product4x1, &
      38             :       my_dot_product4x4, my_sum3d, my_sum4d, gPtsSummation, approximateIntegral, generateIntegrals, &
      39             :       integrateY1ExpErfc, integrateY3ExpErfc, integrateY5ExpErfc, integrateY7ExpErfc, &
      40             :       integrateY9ExpErfc, calculateF, calculateG, calculateH
      41             : 
      42             :    INTERFACE my_sum
      43             :       MODULE PROCEDURE my_sum3d, my_sum4d
      44             :    END INTERFACE
      45             : 
      46             :    INTERFACE my_dot_product
      47             :       MODULE PROCEDURE my_dot_product4x1, my_dot_product4x4, my_dot_product3x1, my_dot_product3x3
      48             :    END INTERFACE
      49             : 
      50             :    INTERFACE gPtsSummation
      51             :       MODULE PROCEDURE crc_gPtsSummation, rrr_gPtsSummation
      52             :    END INTERFACE
      53             : 
      54             : CONTAINS
      55             : 
      56             :    ! Calculate the enhancement factor of the HSE03 functional
      57             :    ! References:
      58             :    ! [1] Heyd, Scuseria, Ernzerhof: hybinp functionals based on a screened Coulomb potential,
      59             :    !     J. Chem. Phys. 118 (2003) 8207-8215
      60             :    ! [2] Heyd, Scuseria: Assessment and validation of a screened Coulomb hybinp density
      61             :    !     functional, J. Chem. Phys. 120 (2004) 7274-7280
      62             :    ! [3] Ernzerhof, Perdew: Generalized gradient approximation to the angle- and system-
      63             :    !     averaged exchange hole, J. Chem. Phys. 109 (1998) 3313-3319
      64             :    ! Input:  kF       - kF = (3 pi^2 rho) ** 1/3
      65             :    !         s_inp    - reduced gradient = |grad rho| / 2 kF rho
      66             :    ! Output: F_x      - HSE03 enhancement factor
      67             :    !         dFx_ds   - derivative of this factor with respect to s
      68             :    !         d2Fx_ds2 - second derivative with respect to s
      69           0 :    SUBROUTINE calculateEnhancementFactor(kF, s_inp, F_x, dFx_Ds, d2Fx_Ds2, dFx_dkF, d2Fx_dsdkF)
      70             :       use m_constants
      71             :       IMPLICIT NONE
      72             : 
      73             :       REAL, INTENT(IN)  :: kF, s_inp
      74             :       REAL, INTENT(INOUT) :: F_x, dFx_ds, d2Fx_ds2
      75             :       REAL, INTENT(INOUT) :: dFx_dkF, d2Fx_dsdkF
      76             : 
      77             :       ! Helper variables
      78             :       REAL :: r1_kF, &                   ! 1 / kF
      79             :               omega_kF, omega_kF_Sqr, &      ! omega_HSE / kF, (omega/kF)^2
      80             :               s, s2, &                      ! reduced gradient s and s^2
      81             :               s_si2, r2s_si3, r6s_si4, &    ! quotient s_chg / s_inp^n (n = 2,3,4)
      82             :               F, G, H, &                    ! results of the functions F, G, and H defined in [3]
      83             :               Hs2, dHs2_ds, d2Hs2_ds2, &    ! H * s^2 and derivatives with respect to s
      84             :               Fs2, dFs2_ds, d2Fs2_ds2, &    ! F * s^2 and derivatives with respect to s
      85             :               dGs2_ds, d2Gs2_ds2, &         ! derivatives with respect to s of G s^2
      86             :               C_term, dCt_ds, d2Ct_ds2, &   ! C * (1 + F(s) s^2) and derivatives with respect to s
      87             :               E_term, dEt_ds, d2Et_ds2, &   ! E * (1 + G(s) s^2) and derivatives with respect to s
      88             :               D_term                        ! D + H s^2
      89             : 
      90             :       ! integrals of y^n Exp(-ay^2) Erfc(w/k y) for n = 1, 3, 5, 7, 9
      91             :       REAL :: intY1ExpErfc, intY3ExpErfc, intY5ExpErfc, intY7ExpErfc, intY9ExpErfc
      92             :       ! integrals of 2/sqrt(pi) y^n Exp(-arg*y^2) for n = 2, 4, 6, 8
      93             :       REAL :: r1_arg, intY2Gauss, intY4Gauss, intY6Gauss, intY8Gauss
      94             : 
      95             :       ! approximation of the not analytical part of the integral and derivatives
      96             :       REAL :: appInt, dAppInt_ds, d2AppInt_ds2
      97             :       REAL :: dAppInt_dkF, d2AppInt_dsdkF
      98             : 
      99             :       REAL, PARAMETER :: r8_9 = 8.0/9.0  ! 8/9
     100             :       REAL, PARAMETER :: &               ! Parameters of the exchange hole as defined in [3]
     101             :          B = -0.37170836, C = -0.077215461, &
     102             :          D = 0.57786348, E = -0.051955731
     103             : 
     104             :       REAL, PARAMETER :: &               ! Correction of the reduced gradient to ensure Lieb-Oxford bound [2]
     105             :          s_thresh = 8.3, s_max = 8.572844, s_chg = 18.796223
     106             :       LOGICAL :: correction              ! Has the value of s been corrected
     107             : 
     108             :       ! If a large value of s would violate the Lieb-Oxford bound, the value of s is reduced,
     109             :       ! so that this condition is fullfilled
     110           0 :       F_x=REAL_NOT_INITALIZED; dFx_ds=REAL_NOT_INITALIZED; d2Fx_ds2=REAL_NOT_INITALIZED
     111           0 :       dFx_dkF=REAL_NOT_INITALIZED;d2Fx_dsdkF=REAL_NOT_INITALIZED
     112             : 
     113           0 :       correction = s_inp > s_thresh
     114           0 :       IF (correction) THEN
     115           0 :          s_si2 = s_chg/(s_inp*s_inp)
     116           0 :          s = s_max - s_si2
     117             :       ELSE
     118           0 :          s = s_inp
     119             :       END IF
     120             : 
     121             :       ! Calculate different helper variables
     122           0 :       r1_kF = 1.0/kF
     123           0 :       omega_kF = omega_hse*r1_kF !was omega_VHSE()
     124           0 :       omega_kF_Sqr = omega_kF*omega_kF
     125             : 
     126             :       ! calculate the functions H and F in [3] and its derivatives
     127           0 :       CALL calculateH(s, H, dHs2_ds, d2Hs2_ds2)
     128           0 :       CALL calculateF(s, H, dHs2_ds, d2Hs2_ds2, F, dFs2_ds, d2Fs2_ds2)
     129           0 :       s2 = s*s
     130           0 :       Hs2 = H*s2
     131           0 :       Fs2 = F*s2
     132             :       CALL calculateG(s2, Fs2, dFs2_ds, d2Fs2_ds2, Hs2, dHs2_ds, d2Hs2_ds2, & !Input
     133           0 :                       G, dGs2_ds, d2Gs2_ds2)                                 !Output
     134             : 
     135           0 :       C_term = C*(1 + s2*F)
     136           0 :       dCt_ds = C*dFs2_ds
     137           0 :       d2Ct_ds2 = C*d2Fs2_ds2
     138           0 :       E_term = E*(1 + s2*G)
     139           0 :       dEt_ds = E*dGs2_ds
     140           0 :       d2Et_ds2 = E*d2Gs2_ds2
     141           0 :       D_term = D + Hs2
     142             : 
     143             :       ! approximate the integral using an expansion of the error function (cf. [2])
     144             :       CALL approximateIntegral(omega_kF, Hs2, D_term, dHs2_ds, d2Hs2_ds2, & !Input
     145           0 :                                appInt, dAppInt_ds, d2AppInt_ds2, dAppInt_dkF, d2AppInt_dsdkF)  !Output
     146             : 
     147             :       ! Calculate the integrals
     148             :       !
     149             :       ! inf
     150             :       !   /                2   2      /       \
     151             :       !  |     n  -(D+H(s)s ) y      | omega   |
     152             :       !  | dy y  e               Erfc| ----- y |
     153             :       !  |                           |   k     |
     154             :       ! /                             \   F   /
     155             :       !  0
     156             :       ! for n = 1, 3, 5, 7, and 9
     157             :       !
     158           0 :       intY1ExpErfc = integrateY1ExpErfc(omega_kf, omega_kf_Sqr, D_term)
     159           0 :       intY3ExpErfc = integrateY3ExpErfc(omega_kf, omega_kf_Sqr, D_term)
     160           0 :       intY5ExpErfc = integrateY5ExpErfc(omega_kf, omega_kf_Sqr, D_term)
     161           0 :       intY7ExpErfc = integrateY7ExpErfc(omega_kf, omega_kf_Sqr, D_term)
     162           0 :       intY9ExpErfc = integrateY9ExpErfc(omega_kf, omega_kf_Sqr, D_term)
     163             : 
     164             :       ! Calculate the integrals
     165             :       !
     166             :       !       inf
     167             :       !         /          /                      2    \
     168             :       !   2    |     n    |          2   2   omega   2  |
     169             :       ! -----  | dy y  Exp| -(D+H(s)s ) y  - ------ y   |
     170             :       !  ____  |          |                   k ^2      |
     171             :       ! V Pi  /            \                   F       /
     172             :       !        0
     173             :       ! for n = 2, 4, 6, 8
     174             :       !
     175           0 :       r1_arg = 1.0/(D_term + omega_kF_Sqr)
     176           0 :       intY2Gauss = 0.5*SQRT(r1_arg)*r1_arg
     177           0 :       intY4Gauss = 1.5*intY2Gauss*r1_arg
     178           0 :       intY6Gauss = 2.5*intY4Gauss*r1_arg
     179           0 :       intY8Gauss = 3.5*intY6Gauss*r1_arg
     180             : 
     181             :       ! Calculate the integral
     182             :       !  inf
     183             :       !    /                 /       \
     184             :       !   |                 | omega   |
     185             :       !   | dy y J(s,y) Erfc| ----- y |
     186             :       !   |                 |   k     |
     187             :       !  /                   \   F   /
     188             :       !   0
     189             :       ! where J(s, y) is the exchange hole defined in [3]
     190             :       ! the exchange factor is proportional to this integral
     191           0 :       F_x = -r8_9*(appInt + B*intY1ExpErfc + C_term*intY3ExpErfc + E_term*intY5ExpErfc)
     192             : 
     193             :       ! Calculate the derivatives with respect to s using that the derivatative of the integral
     194             :       ! yields higher orders of the same kind of integral intY1 -> -intY3 -> intY5 ... times
     195             :       ! the derivative of the exponent
     196             :       dFx_ds = -r8_9*(dAppInt_ds - (B*intY3ExpErfc + C_term*intY5ExpErfc + E_term*intY7ExpErfc)*dHs2_ds &
     197           0 :                       + dCt_ds*intY3ExpErfc + dEt_ds*intY5ExpErfc)
     198             :       d2Fx_ds2 = -r8_9*(d2AppInt_ds2 + (B*intY5ExpErfc + C_term*intY7ExpErfc + E_term*intY9ExpErfc)*dHs2_ds**2 &
     199             :                         - (B*intY3ExpErfc + C_term*intY5ExpErfc + E_term*intY7ExpErfc)*d2Hs2_ds2 &
     200             :                         - 2.0*(dCt_ds*intY5ExpErfc + dEt_ds*intY7ExpErfc)*dHs2_ds &
     201           0 :                         + d2Ct_ds2*intY3ExpErfc + d2Et_ds2*intY5ExpErfc)
     202             : 
     203           0 :       dFx_dkF = -r8_9*r1_kF*(omega_kF*(B*intY2Gauss + C_term*intY4Gauss + E_term*intY6Gauss) + dAppInt_dkF)
     204             :       d2Fx_dsdkF = -r8_9*r1_kF*(d2AppInt_dsdkF + omega_kF*(dCt_ds*intY4Gauss + dEt_ds*intY6Gauss &
     205           0 :                                                            - (B*intY4Gauss + C_term*intY6Gauss + E_term*intY8Gauss)*dHs2_ds))
     206             : 
     207             :       ! Correction to the derivatives, if s_inp > s_thresh
     208           0 :       IF (correction) THEN
     209           0 :          r2s_si3 = 2.0*s_si2/s_inp
     210           0 :          r6s_si4 = 3.0*r2s_si3/s_inp
     211           0 :          d2Fx_ds2 = d2Fx_ds2*r2s_si3**2 - dFx_ds*r6s_si4
     212           0 :          d2Fx_dsdkF = d2Fx_dsdkF*r2s_si3
     213           0 :          dFx_ds = dFx_ds*r2s_si3
     214             :       END IF
     215             : 
     216           0 :    END SUBROUTINE calculateEnhancementFactor
     217             : 
     218             :    ! Approximation for the first part of the exchange hole integral
     219             :    ! Calculated using the algorithm described in [2].
     220             :    ! Additionally the first and second derivative of this approximation with
     221             :    ! respect to s are calculated
     222             :    ! Input:  omega_kF       - omega / kF
     223             :    !         Hs2            - H s^2
     224             :    !         D_Hs2          - D + H s^2
     225             :    !         dHs2_ds        - d (H s^2) / ds
     226             :    !         d2Hs2_ds2      - d^2 (H s^2) / ds^2
     227             :    ! Output: appInt         - approximation for one part of the exchange hole integral
     228             :    !         dAppInt_ds     - first derivative with respect to s
     229             :    !         d2AppInt_ds2   - second derivative with respect to s
     230             :    !         dAppInt_dkF    - first derivative with respect to kF
     231             :    !         d2AppInt_dsdkF - mixed derivative with respect to s and kF
     232           0 :    SUBROUTINE approximateIntegral(omega_kF, Hs2, D_Hs2, dHs2_ds, d2Hs2_ds2, &
     233             :                                   appInt, dAppInt_ds, d2AppInt_ds2, dAppInt_dkF, d2AppInt_dsdkF)
     234             : 
     235             :       USE m_exponential_integral, ONLY: calculateExponentialIntegral, gauss_laguerre
     236             :       use m_constants, only: REAL_NOT_INITALIZED
     237             :       IMPLICIT NONE
     238             : 
     239             :       REAL, INTENT(IN)  :: omega_kF, Hs2, D_Hs2, dHs2_ds, d2Hs2_ds2
     240             :       REAL, INTENT(INOUT) :: appInt, dAppInt_ds, d2AppInt_ds2
     241             :       REAL, INTENT(INOUT) :: dAppInt_dkF, d2AppInt_dsdkF
     242             : 
     243             :       REAL    :: w2, bw, r2bw, bw_Hs2, bw_D_Hs2
     244             :       ! variables for temporary storage of the integrals, the prefactors and the dot_product
     245             :       REAL    :: integral(0:12), a_omegaI(0:8), aI_omegaI(0:8), dotpr, dotpr2
     246             :       INTEGER :: i
     247             : 
     248             :       REAL    :: r2w2, r4w2, r2w2_Hs2, r2w2_D_Hs2, arg, exp_e1, dAppInt_dh, d2AppInt_dh2
     249             : 
     250             :       ! parameters of the erfc fit as given in [2]
     251             :       REAL, PARAMETER :: A_2 = 0.5080572, scale = 1.125/A_2, &
     252             :                          a(1:8) = (/-1.128223946706117, 1.452736265762971, &
     253             :                                     -1.243162299390327, 0.971824836115601, &
     254             :                                     -0.568861079687373, 0.246880514820192, &
     255             :                                     -0.065032363850763, 0.008401793031216/), &
     256             :                          b = 1.455915450052607, cutoff = 14.0
     257             : 
     258           0 :       appInt=REAL_NOT_INITALIZED; dAppInt_ds=REAL_NOT_INITALIZED;
     259           0 :       d2AppInt_ds2=REAL_NOT_INITALIZED; dAppInt_dkF=REAL_NOT_INITALIZED;
     260           0 :       d2AppInt_dsdkF=REAL_NOT_INITALIZED
     261             :       ! Calculate helper variables
     262           0 :       w2 = omega_kF**2
     263           0 :       bw = b*w2
     264           0 :       r2bw = 2.0*bw
     265           0 :       bw_Hs2 = bw + Hs2
     266           0 :       bw_D_Hs2 = bw + D_Hs2
     267             : 
     268           0 :       IF (bw_Hs2 < cutoff) THEN
     269             :          ! integrate the erfc approximation times the exchange hole
     270           0 :          CALL generateIntegrals(bw_Hs2, bw_D_Hs2, integral)
     271             : 
     272             :          ! combine the solutions of the integrals with the appropriate prefactors
     273           0 :          a_omegaI(0) = 1.0
     274           0 :          a_omegaI(1:8) = a*[(omega_kF**i, i=1, 8)]
     275           0 :          aI_omegaI = [(i*a_omegaI(i), i=0, 8)]
     276           0 :          appInt = DOT_PRODUCT(a_omegaI, integral(0:8))
     277           0 :          dotpr = DOT_PRODUCT(a_omegaI, integral(2:10))
     278           0 :          dAppInt_ds = -dotpr*dHs2_ds
     279           0 :          dAppInt_dkF = r2bw*dotpr - DOT_PRODUCT(aI_omegaI, integral(0:8))
     280           0 :          dotpr2 = DOT_PRODUCT(a_omegaI, integral(4:12))
     281           0 :          d2AppInt_ds2 = dotpr2*dHs2_ds**2 - dotpr*d2Hs2_ds2
     282           0 :          d2AppInt_dsdkF = -(r2bw*dotpr2 - DOT_PRODUCT(aI_omegaI, integral(2:10)))*dHs2_ds
     283             :       ELSE
     284           0 :          r2w2 = 2.0*w2
     285           0 :          r4w2 = 4.0*w2
     286           0 :          r2w2_Hs2 = r2w2 + Hs2
     287           0 :          r2w2_D_Hs2 = r2w2 + D_Hs2
     288           0 :          arg = scale*r2w2_Hs2
     289           0 :          exp_e1 = gauss_laguerre(arg)
     290           0 :          appInt = A_2*(LOG(r2w2_Hs2/r2w2_D_Hs2) + exp_e1)
     291           0 :          dAppInt_dh = -A_2/r2w2_D_Hs2 + 1.125*exp_e1
     292           0 :          d2AppInt_dh2 = 1.125/r2w2_Hs2 - A_2/r2w2_D_Hs2**2 - 1.265625/A_2*exp_e1
     293           0 :          dAppInt_ds = dAppInt_dh*dHs2_ds
     294           0 :          dAppInt_dkF = -dAppInt_dh*r4w2
     295           0 :          d2AppInt_ds2 = d2AppInt_dh2*dHs2_ds**2 + dAppInt_dh*d2Hs2_ds2
     296           0 :          d2AppInt_dsdkF = d2AppInt_dh2*dHs2_ds*r4w2
     297             :       END IF
     298             : 
     299           0 :    END SUBROUTINE approximateIntegral
     300             : 
     301             :    ! Generate the integrals for n = 0, 1, ..., 12
     302             :    !
     303             :    ! inf
     304             :    !   /        /        2                  \      /                        \
     305             :    !  |     n  |  A   -Dy           A        |    |    /   omega      2\   2 |
     306             :    !  | dy y   | --- e     - --------------  | Exp| - (  b ----- + H s  ) y  |
     307             :    !  |        |  y            /    4   2\   |    |    \     k         /     |
     308             :    ! /          \            y( 1 + - Ay  ) /      \          F             /
     309             :    !  0                        \    9    /
     310             :    !
     311             :    ! Input:  bw_Hs2   - b (omega/kF)^2 + H s^2
     312             :    !         bw_D_Hs2 - b (omega/kF)^2 + D + H s^2
     313             :    ! Output: integral - array with the calculated integrals
     314             :    ! To simplify the calculation use integral(n+2) = - d(integral(n))/d(b omega/kF)
     315           0 :    SUBROUTINE generateIntegrals(bw_Hs2, bw_D_Hs2, integral)
     316             :       USE m_exponential_integral, ONLY: calculateExponentialIntegral, gauss_laguerre, series_laguerre
     317             :       USE m_constants
     318             :       IMPLICIT NONE
     319             : 
     320             :       REAL, INTENT(IN)  :: bw_Hs2, bw_D_Hs2
     321             :       REAL, INTENT(INOUT) :: integral(0:12)
     322             : 
     323             :       ! Helper variables
     324             :       REAL :: bw_Hs2_Sqr, bw_Hs2_Cub, sqrt_bw_Hs2, &
     325             :               bw_D_Hs2_Sqr, bw_D_Hs2_Cub, bw_D_Hs2_Tet, sqrt_bw_D_Hs2, &
     326             :               arg, sqrt_arg, r1_arg, e1_arg, exp_arg, exp_erfc, &
     327             :               term1, factor2, term2, arg_n, sum_term, add_term, half_i2_1
     328             :       INTEGER :: i
     329             : 
     330             :       ! A is an exchange hole parameter [3] and b the fit parameter for erfc [2]
     331             :       REAL, PARAMETER :: &
     332             :          A = 1.0161144, A_2 = A/2.0, scale = 2.25/A, sqrtA = 1.008025, & !sqrt(A)
     333             :          b = 1.455915450052607
     334             : 
     335           0 :       integral = 0.0
     336             : 
     337             :       ! Calculate many helper variables
     338           0 :       bw_Hs2_Sqr = bw_Hs2*bw_Hs2
     339           0 :       bw_Hs2_Cub = bw_Hs2*bw_Hs2_Sqr
     340           0 :       sqrt_bw_Hs2 = SQRT(bw_Hs2)
     341           0 :       bw_D_Hs2_Sqr = bw_D_Hs2*bw_D_Hs2
     342           0 :       bw_D_Hs2_Cub = bw_D_Hs2*bw_D_Hs2_Sqr
     343           0 :       bw_D_Hs2_Tet = bw_D_Hs2_Sqr*bw_D_Hs2_Sqr
     344           0 :       sqrt_bw_D_Hs2 = SQRT(bw_D_Hs2)
     345             : 
     346             :       ! arg = 9/4 * (b omega/kF + H s^2) / A
     347           0 :       arg = scale*bw_Hs2
     348           0 :       sqrt_arg = SQRT(arg)
     349           0 :       r1_arg = 1.0/arg
     350             : 
     351             :       ! calculate e^(arg), E1(arg), and erfc(sqrt(arg))
     352           0 :       exp_arg = EXP(arg)
     353           0 :       exp_erfc = exp_arg*erfc(sqrt_arg)
     354             : 
     355           0 :       IF (arg > series_laguerre) THEN
     356           0 :          term2 = gauss_laguerre(arg)
     357             :       ELSE
     358           0 :          CALL calculateExponentialIntegral(arg, e1_arg)
     359           0 :          term2 = exp_arg*e1_arg
     360             :       END IF
     361             : 
     362             :       ! The n = 0 integral is
     363             :       ! A/2 ( ln((b omega/kF + H s^2) / (b omega/kF + D + H s^2))
     364             :       !     + e^(arg) E1(arg) )
     365           0 :       integral(0) = A_2*(LOG(bw_Hs2/bw_D_Hs2) + term2)
     366             : 
     367             :       ! Calculate now all even n's by successive derivation
     368             :       ! The log(...) term gives term proportional to 1/(b omega/kF + D + H s^2)^i
     369             :       ! The e^(arg) E1(arg) term reproduces itself with a prefactor and
     370             :       ! generates an additional 1/arg term which produces higher 1/arg^i terms
     371             :       ! when further deriviated
     372           0 :       term1 = A_2/bw_D_Hs2
     373           0 :       factor2 = -1.125
     374           0 :       arg_n = -1.0/arg
     375           0 :       integral(2) = term1 + factor2*term2
     376             : 
     377           0 :       DO i = 1, 5
     378           0 :          term1 = term1/bw_D_Hs2*REAL(i)
     379           0 :          factor2 = -factor2*scale
     380           0 :          term2 = term2 + arg_n
     381             : 
     382           0 :          integral(2*(i + 1)) = term1 + factor2*term2
     383             : 
     384           0 :          arg_n = -arg_n*REAL(i)/arg
     385             :       END DO
     386             : 
     387             :       ! The n = 1 integral is
     388             :       ! A/2 ( sqrt(pi) / sqrt( b omega/kF + D + H s2 )
     389             :       ! - 3/4 sqrt(A) pi e^(arg) erfc(sqrt(arg))
     390           0 :       term1 = A_2*SQRT(PI_const)/sqrt_bw_D_Hs2
     391           0 :       term2 = PI_const*exp_erfc
     392           0 :       factor2 = -0.75*sqrtA
     393             : 
     394           0 :       integral(1) = term1 + factor2*term2
     395             : 
     396             :       ! Calculate now all uneven n's by successive derivation
     397             :       ! The 1 / sqrt(...) term gives higher orders of 1 / (...)^((2i+1)/2)
     398             :       ! The e^(arg) erfc(sqrt(arg)) term reproduces itself with a prefactor
     399             :       ! and generates an additional 1/sqrt(arg) term which produces higher
     400             :       ! 1/(arg)^((2i+1)/2) terms when further deriviated
     401           0 :       sum_term = -1.125*SQRT(pi_const)/sqrt_bw_Hs2
     402           0 :       add_term = sum_term
     403           0 :       half_i2_1 = -0.5
     404             : 
     405           0 :       DO i = 3, 11, 2
     406           0 :          factor2 = -factor2*scale
     407           0 :          term1 = -term1*half_i2_1/bw_D_Hs2
     408           0 :          integral(i) = term1 + term2*factor2 + sum_term
     409             : 
     410           0 :          add_term = -add_term*half_i2_1/bw_Hs2
     411           0 :          sum_term = -sum_term*scale + add_term
     412           0 :          half_i2_1 = half_i2_1 - 1.0
     413             :       ENDDO
     414             : 
     415           0 :    END SUBROUTINE generateIntegrals
     416             : 
     417             :    ! Calculate the integral
     418             :    !
     419             :    ! inf
     420             :    !   /                  /       \         /                 ________________ \
     421             :    !  |       -a y^2     | omega   |    1  |     omega   /   /     / omega \2   |
     422             :    !  | dy y e       Erfc| ----- y | = --- | 1 - -----  /   / a + (  -----  )   |
     423             :    !  |                  |   k     |   2 a |       k   /   V       \   k   /    |
     424             :    ! /                    \   F   /         \       F                   F      /
     425             :    !  0
     426             :    !
     427             :    ! Input:  omega_kF     - omega / kF
     428             :    !         omega_kF_Sqr - (omega / kF)^2
     429             :    !         a            - factor of the gaussian function
     430             :    ! Return: result of the integration
     431           0 :    REAL FUNCTION integrateY1ExpErfc(omega_kF, omega_kF_Sqr, a)
     432             :       IMPLICIT NONE
     433             : 
     434             :       REAL, INTENT(IN)  :: omega_kF, omega_kF_Sqr, a
     435             : 
     436             :       ! helper variable sqrt(a + (omega/kF)^2)
     437             :       REAL :: sqrt_term
     438             : 
     439             :       ! calculate helper variable
     440           0 :       sqrt_term = SQRT(a + omega_kF_Sqr)
     441             : 
     442             :       ! calculate the integral
     443           0 :       integrateY1ExpErfc = 0.5*(1 - omega_kF/sqrt_term)/a
     444             : 
     445             :    END FUNCTION integrateY1ExpErfc
     446             : 
     447             :    ! Calculate the integral
     448             :    !
     449             :    ! inf
     450             :    !   /                   /       \           /                   ________________                   ________________3 \
     451             :    !  |     3  -a y^2     | omega   |     1   |       omega   /   /     / omega \2       omega   /   /     / omega \2    |
     452             :    !  | dy y  e       Erfc| ----- y | = ----- | 2 - 2 -----  /   / a + (  -----  )  - a  -----  /   / a + (  -----  )    |
     453             :    !  |                   |   k     |   4 a^2 |         k   /   V       \   k   /          k   /   V       \   k   /     |
     454             :    ! /                     \   F   /           \         F                   F              F                   F       /
     455             :    !  0
     456             :    !
     457             :    ! Input:  omega_kF     - omega / kF
     458             :    !         omega_kF_Sqr - (omega / kF)^2
     459             :    !         a            - factor of the gaussian function
     460             :    ! Return: result of the integration
     461           0 :    REAL FUNCTION integrateY3ExpErfc(omega_kF, omega_kF_Sqr, a)
     462             :       IMPLICIT NONE
     463             : 
     464             :       REAL, INTENT(IN)  :: omega_kF, omega_kF_Sqr, a
     465             : 
     466             :       ! helper variables
     467             :       REAL :: term, sqrt_term, sqrt_term_3
     468             : 
     469             :       ! calculate helper variables
     470           0 :       term = a + omega_kF_Sqr
     471           0 :       sqrt_term = SQRT(term)
     472           0 :       sqrt_term_3 = term*sqrt_term
     473             : 
     474             :       ! calculate the integral
     475           0 :       integrateY3ExpErfc = 0.25*(2.0 - a*omega_kF/sqrt_term_3 - 2.0*omega_kF/sqrt_term)/(a*a)
     476             : 
     477           0 :    END FUNCTION integrateY3ExpErfc
     478             : 
     479             :    ! Calculate the integral
     480             :    !
     481             :    ! inf                                     /                                   \
     482             :    !   /                   /       \        |                  /              2\  |
     483             :    !  |     5  -a y^2     | omega   |    1  |       omega     |      a     3 a  | |
     484             :    !  | dy y  e       Erfc| ----- y | = --- | 1 - ----------  | 1 + --- + ----- | |
     485             :    !  |                   |   k     |   a^3 |     k  sqrt(x)  |     2 x   8 x^2 | |
     486             :    ! /                     \   F   /        |      F           \               /  |
     487             :    !  0                                      \                                   /
     488             :    ! where
     489             :    !          /     \ 2
     490             :    !         | omega |
     491             :    ! x = a + | ----- |
     492             :    !         |   k   |
     493             :    !          \   F /
     494             :    !
     495             :    ! Input:  omega_kF     - omega / kF
     496             :    !         omega_kF_Sqr - (omega / kF)^2
     497             :    !         a            - factor of the gaussian function
     498             :    ! Return: result of the integration
     499           0 :    REAL FUNCTION integrateY5ExpErfc(omega_kF, omega_kF_Sqr, a)
     500             :       IMPLICIT NONE
     501             : 
     502             :       REAL, INTENT(IN)  :: omega_kF, omega_kF_Sqr, a
     503             : 
     504             :       ! helper variables
     505             :       REAL :: term, sqrt_term, a_Sqr
     506             : 
     507             :       ! calculate helper variables
     508           0 :       term = a + omega_kF_Sqr
     509           0 :       sqrt_term = SQRT(term)
     510           0 :       a_Sqr = a*a
     511             : 
     512             :       ! calculate the integral
     513           0 :       integrateY5ExpErfc = (1.0 - (0.375*a_Sqr/(term*term) + a/(2.0*term) + 1.0)*omega_kF/sqrt_term)/(a_Sqr*a)
     514             : 
     515           0 :    END FUNCTION integrateY5ExpErfc
     516             : 
     517             :    ! Calculate the integral
     518             :    !
     519             :    ! inf                                     /                                            \
     520             :    !   /                   /       \        |                  /              2       3 \  |
     521             :    !  |     7  -a y^2     | omega   |    3  |       omega     |      a     3 a     5 a   | |
     522             :    !  | dy y  e       Erfc| ----- y | = --- | 1 - ----------  | 1 + --- + ----- + ------ | |
     523             :    !  |                   |   k     |   a^4 |     k  sqrt(x)  |     2 x   8 x^2   16 x^3 | |
     524             :    ! /                     \   F   /        |      F           \                        /  |
     525             :    !  0                                      \                                            /
     526             :    ! where
     527             :    !          /     \ 2
     528             :    !         | omega |
     529             :    ! x = a + | ----- |
     530             :    !         |   k   |
     531             :    !          \   F /
     532             :    !
     533             :    ! Input:  omega_kF     - omega / kF
     534             :    !         omega_kF_Sqr - (omega / kF)^2
     535             :    !         a            - factor of the gaussian function
     536             :    ! Return: result of the integration
     537           0 :    REAL FUNCTION integrateY7ExpErfc(omega_kF, omega_kF_Sqr, a)
     538             :       IMPLICIT NONE
     539             : 
     540             :       REAL, INTENT(IN)  :: omega_kF, omega_kF_Sqr, a
     541             : 
     542             :       ! helper variables
     543             :       REAL :: term2, term, sqrt_term, a_Sqr
     544             : 
     545             :       ! calculate helper variables
     546           0 :       term = a + omega_kF_Sqr
     547           0 :       term2 = term*term
     548           0 :       sqrt_term = SQRT(term)
     549           0 :       a_Sqr = a*a
     550             : 
     551             :       ! calculate the integral
     552             :       integrateY7ExpErfc = 3.0/(a_Sqr*a_Sqr)*(1.0 - omega_kF/sqrt_term* &
     553           0 :                                               (0.3125*(a_Sqr*a)/(term2*term) + 0.375*a_Sqr/term2 + a/(2.0*term) + 1.0))
     554             : 
     555           0 :    END FUNCTION integrateY7ExpErfc
     556             : 
     557             :    ! Calculate the integral
     558             :    !
     559             :    ! inf                                     /                                                      \
     560             :    !   /                   /       \        |                  /              2       3           \  |
     561             :    !  |     9  -a y^2     | omega   |    12 |       omega     |      a     3 a     5 a      35 a^4 | |
     562             :    !  | dy y  e       Erfc| ----- y | = --- | 1 - ----------  | 1 + --- + ----- + ------ + ------- | |
     563             :    !  |                   |   k     |   a^5 |     k  sqrt(x)  |     2 x   8 x^2   16 x^3   128 x^4 | |
     564             :    ! /                     \   F   /        |      F           \                                  /  |
     565             :    !  0                                      \                                                      /
     566             :    ! where
     567             :    !          /     \ 2
     568             :    !         | omega |
     569             :    ! x = a + | ----- |
     570             :    !         |   k   |
     571             :    !          \   F /
     572             :    !
     573             :    ! Input:  omega_kF     - omega / kF
     574             :    !         omega_kF_Sqr - (omega / kF)^2
     575             :    !         a            - factor of the gaussian function
     576             :    ! Return: result of the integration
     577           0 :    REAL FUNCTION integrateY9ExpErfc(omega_kF, omega_kF_Sqr, a)
     578             :       IMPLICIT NONE
     579             : 
     580             :       REAL, INTENT(IN)  :: omega_kF, omega_kF_Sqr, a
     581             : 
     582             :       ! helper variables
     583             :       REAL :: term2, term, sqrt_term, a_Sqr, a_Tet
     584             : 
     585             :       ! calculate helper variables
     586           0 :       term = a + omega_kF_Sqr
     587           0 :       term2 = term*term
     588           0 :       sqrt_term = SQRT(term)
     589           0 :       a_Sqr = a*a
     590           0 :       a_Tet = a_Sqr*a_Sqr
     591             : 
     592             :       ! calculate the integral
     593             :       integrateY9ExpErfc = 12.0*(1.0 - (0.2734375*a_Tet/(term2*term2) + 0.3125*(a_Sqr*a)/(term2*term) &
     594           0 :                                         + 0.375*a_Sqr/term2 + a/(2.0*term) + 1.0)*omega_kF/sqrt_term)/(a_Tet*a)
     595             : 
     596           0 :    END FUNCTION integrateY9ExpErfc
     597             : 
     598             :    ! Calculate the function F(s) given in [3]
     599             :    ! Input:  s         - reduced gradient
     600             :    !         H         - value of the function H(s)
     601             :    !         dHs2_ds   - first derivative of H(s)s^2
     602             :    !         dsHs2_ds2 - second derivative of H(s)s^2
     603             :    ! Output: F         - value of the function F
     604             :    !         dFs2_ds   - first derivative of F(s)s^2
     605             :    !         d2Fs2_ds2 - second derivative of F(s)s^2
     606           0 :    SUBROUTINE calculateF(s, H, dHs2_ds, d2Hs2_ds2, F, dFs2_ds, d2Fs2_ds2)
     607             :       IMPLICIT NONE
     608             : 
     609             :       REAL, INTENT(IN)  :: s, H, dHs2_ds, d2Hs2_ds2
     610             :       REAL, INTENT(INOUT) :: F, dFs2_ds, d2Fs2_ds2
     611             : 
     612             :       REAL, PARAMETER   :: slope = 6.4753871
     613             :       REAL, PARAMETER   :: shift = 0.4796583
     614             : 
     615             :       ! calculate the function F(s), d(s^2F(s))/ds, and d^2(s^2F(s))/ds^2
     616           0 :       F = slope*H + shift
     617           0 :       dFs2_ds = slope*dHs2_ds + 2.0*s*shift
     618           0 :       d2Fs2_ds2 = slope*d2Hs2_ds2 + 2.0*shift
     619             :    END SUBROUTINE calculateF
     620             : 
     621             :    ! Calculate the function G(s) given in [3]
     622             :    ! Input:  s2        - s^2 where s is the reduced gradient
     623             :    !         Fs2       - F(s) s^2
     624             :    !         dFs2_ds   - first derivative of F(s)s^2 with respect to s
     625             :    !         d2Fs2_ds2 - second derivative of F(s)s^2
     626             :    !         Hs2       - H(s) s^2
     627             :    !         dHs2_ds   - first derivative of H(s)s^2 with respect to s
     628             :    !         d2Hs2_ds2 - second derivative of H(s)s^2
     629             :    ! Output: G         - value of the function G
     630             :    !         dGs2_ds   - first derivative of G(s)s^2 with respect to s
     631             :    !         d2Gs2_ds2 - second derivative of G(s)s^2
     632           0 :    SUBROUTINE calculateG(s2, Fs2, dFs2_ds, d2Fs2_ds2, Hs2, dHs2_ds, d2Hs2_ds2, G, dGs2_ds, d2Gs2_ds2)
     633             :       use m_constants, only: REAL_NOT_INITALIZED
     634             :       IMPLICIT NONE
     635             : 
     636             :       REAL, INTENT(IN)  :: s2, Fs2, dFs2_ds, d2Fs2_ds2, Hs2, dHs2_ds, d2Hs2_ds2
     637             :       REAL, INTENT(INOUT) :: G, dGs2_ds, d2Gs2_ds2
     638             : 
     639             :       ! helper variables
     640             :       REAL :: AHs2_1_2, AHs2_3_2, r1_Fs2, D_Hs2, D_Hs2Sqr, D_Hs2Cub, &
     641             :               D_Hs2_5_2, D_Hs2_7_2, D_Hs2_9_2, D_Hs2_11_2
     642             :       REAL :: part1, dpart1_dh, d2part1_dh2
     643             :       REAL :: arg1, arg2, exp_erfc, &
     644             :               part2, dpart2_dh, d2part2_dh2
     645             :       REAL :: alpha, Ebeta, r3Pi_4_alpha, beta_s2, Ebeta_s2, &
     646             :               dalpha_dh, d2alpha_dh2, dalpha_df, d2alpha_dfdh, dbeta_dh, d2beta_dh2
     647             : 
     648             :       ! parameters of the exchange hole given in [3]
     649             :       REAL, PARAMETER :: PI_75 = 2.356194490192344929, SQRT_PI = 1.77245385090551602729816748334, &
     650             :                          A = 1.0161144, sqrtA = 1.008025, r9_4A = 2.25/A, & !sqrt(A), 9/4A
     651             :                          B = -0.37170836, &
     652             :                          C = -0.077215461, &
     653             :                          D = 0.57786348, &
     654             :                          E = -0.051955731
     655             : 
     656             :        G=REAL_NOT_INITALIZED; dGs2_ds=REAL_NOT_INITALIZED; d2Gs2_ds2=REAL_NOT_INITALIZED
     657             :       ! calculate the helper variables
     658           0 :       AHs2_1_2 = sqrtA*SQRT(Hs2)
     659           0 :       AHs2_3_2 = AHs2_1_2*A*Hs2
     660           0 :       r1_Fs2 = 1.0 + Fs2
     661           0 :       D_Hs2 = D + Hs2
     662           0 :       D_Hs2Sqr = D_Hs2*D_Hs2
     663           0 :       D_Hs2Cub = D_Hs2*D_Hs2Sqr
     664           0 :       D_Hs2_5_2 = D_Hs2Sqr*SQRT(D_Hs2)
     665           0 :       D_Hs2_7_2 = D_Hs2_5_2*D_Hs2
     666           0 :       D_Hs2_9_2 = D_Hs2_5_2*D_Hs2Sqr
     667           0 :       D_Hs2_11_2 = D_Hs2_5_2*D_Hs2Cub
     668             : 
     669             :       ! calculate first part of the term called 'a' in [3] eq. (A2) and its derivatives with respect to H(s)s^2 and F(s)s^2
     670             :       !
     671             :       !                          2      2           2 2          2 3
     672             :       !          __ 15E + 6C(1+Fs )(D+Hs ) + 4B(D+Hs )  + 8A(D+Hs )
     673             :       ! part1 = VPi ------------------------------------------------
     674             :       !                                    2  7/2
     675             :       !                        16 ( D + H s  )
     676             :       !
     677           0 :       part1 = SQRT_PI*(15.0*E + 6.0*C*r1_Fs2*D_Hs2 + 4.0*B*D_Hs2Sqr + 8.0*A*D_Hs2Cub)/(16.0*D_Hs2_7_2)
     678             :       !
     679             :       !                               2      2            2 2          2 3
     680             :       ! d part1     __ 105E + 30C(1+Fs )(D+Hs ) + 12B(D+Hs )  + 8A(D+Hs )
     681             :       ! ------- = -VPi ---------------------------------------------------
     682             :       ! d(Hs^2)                                  2  9/2
     683             :       !                              32 ( D + H s  )
     684             :       !
     685           0 :       dpart1_dh = -SQRT_PI*(105.0*E + 30.0*C*r1_Fs2*D_Hs2 + 12.0*B*D_Hs2Sqr + 8.0*A*D_Hs2Cub)/(32.0*D_Hs2_9_2)
     686             :       !
     687             :       !  2                             2      2            2 2           2 3
     688             :       ! d  part1    __ 945E + 210C(1+Fs )(D+Hs ) + 60B(D+Hs )  + 24A(D+Hs )
     689             :       ! -------- = VPi -----------------------------------------------------
     690             :       !        2                                   2  11/2
     691             :       ! d(Hs^2)                        64 ( D + H s  )
     692             :       !
     693           0 :       d2part1_dh2 = SQRT_PI*(945.0*E + 210.0*C*r1_Fs2*D_Hs2 + 60.0*B*D_Hs2Sqr + 24.0*A*D_Hs2Cub)/(64.0*D_Hs2_11_2)
     694             :       !
     695             :       ! d part1    __       3 C
     696             :       ! ------- = VPi -----------------
     697             :       ! d(Fs^2)                  2  5/2
     698             :       !               8 ( D + H s  )
     699             :       !
     700           0 :       dalpha_df = SQRT_PI*0.375*C/D_Hs2_5_2
     701             :       !
     702             :       !      2
     703             :       !     d part1         __       15 C
     704             :       ! --------------- = -VPi ------------------
     705             :       ! d(Fs^2) d(Hs^2)                    2  7/2
     706             :       !                        16 ( D + H s  )
     707             :       !
     708           0 :       d2alpha_dfdh = -2.5*dalpha_df/D_Hs2
     709             : 
     710             :       ! calculate second part of the term called 'a' in [3] eq. (A2) and its derivatives
     711             :       !                                            ________
     712             :       !                       /     2 \       /   /     2   \
     713             :       !         3 Pi  ___    | 9 H s   |     |   / 9 H s     |
     714             :       ! part2 = ---- V A  Exp| ------- | Erfc|  /  -------   |
     715             :       !          4           |   4 A   |     | V     4 A     |
     716             :       !                       \       /       \             /
     717             :       !
     718           0 :       arg1 = r9_4A*Hs2
     719           0 :       arg2 = SQRT(arg1)
     720           0 :       exp_erfc = EXP(arg1)*erfc(arg2)
     721           0 :       part2 = PI_75*sqrtA*exp_erfc
     722             :       !
     723             :       !                      /                                \
     724             :       ! d part2   3 Pi  ___ |  9                    3          |
     725             :       ! ------- = ---- V A  | --- exp_erfc - ----------------  |
     726             :       ! d(Hs^2)    4        | 4 A                          2   |
     727             :       !                      \               2 sqrt(Pi A Hs ) /
     728             :       !
     729           0 :       dpart2_dh = PI_75*sqrtA*(r9_4A*exp_erfc - 1.5/(SQRT_PI*AHs2_1_2))
     730             :       !
     731             :       !  2                    /                                 2    \
     732             :       ! d  part2   3 Pi  ___ |   81                  6 A - 27 Hs      |
     733             :       ! -------- = ---- V A  | ------ exp_erfc + -------------------- |
     734             :       !        2    4        | 16 A^2                           2 3/2 |
     735             :       ! d(Hs^2)               \                  8 sqrt(Pi)(A Hs )   /
     736             :       !
     737           0 :       d2part2_dh2 = PI_75*sqrtA*(r9_4A**2*exp_erfc + (6.0*A - 27.0*Hs2)/(8.0*SQRT_PI*AHs2_3_2))
     738             : 
     739             :       ! calculate the 'a' and 'b' terms ([3] eq. (A2) and (A3) )
     740             :       !
     741             :       ! a = part1 - part2
     742             :       !
     743             :       !             __  2
     744             :       !         15 VPi s
     745             :       ! b = -----------------
     746             :       !                2  7/2
     747             :       !     16 (D + H s  )
     748             :       !
     749           0 :       alpha = part1 - part2
     750           0 :       beta_s2 = 0.9375*SQRT_PI/D_Hs2_7_2
     751           0 :       Ebeta = E*beta_s2*s2
     752             : 
     753             :       ! the derivatives of a with respect to Fs^2 and Hs^2
     754             :       !
     755             :       !    da      d part1   d part2
     756             :       ! -------- = ------- - -------
     757             :       ! d (Hs^2)   d(Hs^2)   d(Hs^2)
     758             :       !
     759           0 :       dalpha_dh = dpart1_dh - dpart2_dh
     760             :       !
     761             :       !    2        2          2
     762             :       !   d a      d part1    d part2
     763             :       ! -------- = -------- - --------
     764             :       !        2          2          2
     765             :       ! d(Hs^2)    d(Hs^2)    d(Hs^2)
     766             :       !
     767           0 :       d2alpha_dh2 = d2part1_dh2 - d2part2_dh2
     768             :       !
     769             :       !    da      d part1
     770             :       ! -------- = -------
     771             :       ! d (Fs^2)   d(Fs^2)
     772             :       !
     773             :       !        2               2
     774             :       !       d a             d part1
     775             :       ! --------------- = ---------------
     776             :       ! d(Fs^2) d(Hs^2)   d(Fs^2) d(Hs^2)
     777             :       !
     778             :       ! (this expressions are already defined earlier)
     779             :       !
     780             :       ! and the derivatives of b/s^2 with respect to Hs^2
     781             :       !                        __
     782             :       ! d(b/s^2)          105 VPi          7  b / s^2
     783             :       ! -------- = - ----------------- = - -  --------
     784             :       ! d (Hs^2)                2  9/2     2         2
     785             :       !              32 (D + H s  )           D + H s
     786             :       !
     787           0 :       dbeta_dh = -3.5*beta_s2/D_Hs2
     788             :       !
     789             :       !  2                     __
     790             :       ! d (b/s^2)         945 VPi          9  d(b/s^2)
     791             :       ! --------- = ------------------ = - -  --------
     792             :       !         2              2  11/2     2  d (Hs^2)
     793             :       ! d (Hs^2)    64 (D + H s  )
     794             :       !
     795           0 :       d2beta_dh2 = -4.5*dbeta_dh/D_Hs2
     796             : 
     797             :       ! calculate the function G(s) and its derivatives
     798             :       !
     799             :       !       3Pi/4 + a
     800             :       ! G = - ---------
     801             :       !          E b
     802             :       !
     803           0 :       r3Pi_4_alpha = PI_75 + alpha
     804           0 :       Ebeta_s2 = E*beta_s2
     805           0 :       G = -r3Pi_4_alpha/Ebeta
     806             :       !
     807             :       !             /  /3 Pi    \  d(b/s^2)   /           d a    \  d(Hs^2)       d a   d(Fs^2)
     808             :       !            <  ( ---- + a ) -------   /  b/s^2  - -------  > -------  -  ------- -------
     809             :       ! d (Gs^2)    \  \ 4      /  d(Hs^2)  /            d(Hs^2) /    d s       d(Fs^2)   ds
     810             :       ! -------- = ----------------------------------------------------------------------------
     811             :       !    ds                                     E b/s^2
     812             :       !
     813           0 :       dGs2_ds = ((r3Pi_4_alpha*dbeta_dh/beta_s2 - dalpha_dh)*dHs2_ds - dalpha_df*dFs2_ds)/Ebeta_s2
     814             :       !
     815             :       !                                                     /3Pi    \  /             2\           /           \
     816             :       !                                                    ( --- + a )( b  h" + b   h' ) + 2b  h'( f'a  + h'a  ) + ...
     817             :       !                                            2        \ 4     /  \ h       hh   /      h    \   f      h/
     818             :       !  2         -f" a  - h" a  - 2 f' h' a   - h' a   + -----------------------------------------------------------
     819             :       ! d (Gs^2)        f       h            fh       hh                                b/s^2
     820             :       ! -------- = ---------------------------------------------------------------------------------------------------
     821             :       !   ds^2                                               E b/s^2
     822             :       !
     823             :       !            /3Pi    \   2  2
     824             :       !           ( --- + a ) b  h'
     825             :       !            \ 4     /   h
     826             :       ! ... = - 2 -----------------
     827             :       !                  b/s^2
     828             :       !
     829             :       ! where the primes indicate derivative with respect to s and the subscripts derivatives with respect to the subscript
     830             :       ! and f and h are abbrevations for f = Fs^2 and h = Hs^2
     831             :       !
     832             :       d2Gs2_ds2 = (-d2Fs2_ds2*dalpha_df - d2Hs2_ds2*dalpha_dh &
     833             :                    - 2.0*dFs2_ds*dHs2_ds*d2alpha_dfdh - dHs2_ds**2*d2alpha_dh2 &
     834             :                    + (r3Pi_4_alpha*(dbeta_dh*d2Hs2_ds2 + d2beta_dh2*dHs2_ds**2) &
     835             :                       + 2.0*dbeta_dh*dHs2_ds*(dFs2_ds*dalpha_df + dHs2_ds*dalpha_dh) &
     836           0 :                       - 2.0*r3Pi_4_alpha*(dbeta_dh*dHs2_ds)**2/beta_s2)/beta_s2)/Ebeta_s2
     837           0 :    END SUBROUTINE calculateG
     838             : 
     839             :    ! Calculate the function H(s) given in [3]
     840             :    ! Input:  s         - reduced gradient
     841             :    ! Output: H         - value of the function H
     842             :    !         dHs2_ds   - first derivative d(s^2*H(s))/ds
     843             :    !         d2Hs2_ds2 - second derivative d^2(s^2H(s))/ds^2
     844           0 :    SUBROUTINE calculateH(s, H, dHs2_ds, d2Hs2_ds2)
     845             :       use m_constants, only: REAL_NOT_INITALIZED
     846             :       IMPLICIT NONE
     847             : 
     848             :       REAL, INTENT(IN)  :: s
     849             :       REAL, INTENT(INOUT) :: H, dHs2_ds, d2Hs2_ds2
     850             : 
     851             :       ! helper variables
     852             :       REAL :: s2, s3, s4, s5, s6
     853             :       REAL :: numer, denom
     854             :       REAL :: dnum_ds, dden_ds
     855             :       REAL :: d2num_ds2, d2den_ds2
     856             : 
     857             :       ! parameters given in [3]
     858             :       REAL, PARAMETER :: &
     859             :          a1 = 0.00979681, &
     860             :          a2 = 0.0410834, &
     861             :          a3 = 0.187440, &
     862             :          a4 = 0.00120824, &
     863             :          a5 = 0.0347188
     864             : 
     865             :       H=REAL_NOT_INITALIZED; dHs2_ds=REAL_NOT_INITALIZED; d2Hs2_ds2=REAL_NOT_INITALIZED
     866             :       ! calculate helper variables
     867           0 :       s2 = s*s
     868           0 :       s3 = s2*s
     869           0 :       s4 = s2*s2
     870           0 :       s5 = s3*s2
     871           0 :       s6 = s4*s2
     872             : 
     873             :       ! calculate function H(s) with [3] eq. (A5)
     874             :       !
     875             :       !            2         4
     876             :       !        a  s   +  a  s
     877             :       !         1         2
     878             :       ! H = -------------------------
     879             :       !             4       5       6
     880             :       !     1 + a  s  + a  s  + a  s
     881             :       !          3       4       5
     882             :       !
     883           0 :       numer = a1*s2 + a2*s4
     884           0 :       denom = 1.0 + a3*s4 + a4*s5 + a5*s6
     885           0 :       H = numer/denom
     886             : 
     887             :       ! calculate the first derivative of s^2 H(s)
     888             :       !
     889             :       !     /    \
     890             :       !  d | f(x) |   f'(x) - f(x)g'(x) / g(x)
     891             :       ! -- | ---- | = ------------------------
     892             :       ! dx | g(x) |            g(x)
     893             :       !     \    /
     894             :       !
     895           0 :       numer = numer*s2
     896           0 :       dnum_ds = 4.0*s3*a1 + 6.0*s5*a2
     897           0 :       dden_ds = 4.0*s3*a3 + 5.0*s4*a4 + 6.0*s5*a5
     898           0 :       dHs2_ds = (dnum_ds - (dden_ds*numer)/denom)/denom
     899             : 
     900             :       ! calculate the second derivative of s^2 H(s)
     901             :       !
     902             :       !                                                               2
     903             :       !                         2 f'(x)g'(x) + f(x)g"(x) - 2 f(x)g'(x) /g(x)
     904             :       !    2  /    \    f"(x) - --------------------------------------------
     905             :       !   d  | f(x) |                              g(x)
     906             :       ! ---- | ---- | = ----------------------------------------------------
     907             :       ! dx^2 | g(x) |                          g(x)
     908             :       !       \    /
     909             :       !
     910           0 :       d2num_ds2 = 12.0*s2*a1 + 30.0*s4*a2
     911           0 :       d2den_ds2 = 12.0*s2*a3 + 20.0*s3*a4 + 30.0*s4*a5
     912           0 :       d2Hs2_ds2 = (d2num_ds2 - (2.0*dnum_ds*dden_ds + numer*d2den_ds2 - 2.0*numer*dden_ds**2/denom)/denom)/denom
     913           0 :    END SUBROUTINE calculateH
     914             : 
     915             :    ! Calculate several Fourier transformations
     916             :    ! a) the Fourier transformed potential
     917             :    !                                                 /          \
     918             :    !          /      | erf |       \     4 Pi       |   |k+G|^2  |
     919             :    ! V (k) = ( k + G | --- | k + G  ) = -------  Exp| - -------  |                             [1]
     920             :    !  G       \      |  r  |       /    |k+G|^2     |    4 w^2   |
     921             :    !                                                 \          /
     922             :    !
     923             :    ! b) muffin-tin basis function
     924             :    !                                                            R
     925             :    !                                     -L                      /
     926             :    !           /      |      \     4 Pi i         ^     -i G R  |     2
     927             :    ! MT (k) = ( k + G | M     ) = ---------- Y ( k+G ) e        | dr r  Phi(r) j ( |k+G| r )  [2]
     928             :    !   G,I     \      |  k,I /     Sqrt(Om)   LM                |               L
     929             :    !                                                           /
     930             :    !                                                            0
     931             :    !
     932             :    ! c) interstitial basis function
     933             :    !                                                      -----
     934             :    !          /      |      \                       4 Pi   \     -i(G - G_I)R_a  Sin(|G_I - G| R_a) - |G_I - G| R_a Cos(|G_I - G| R_a)
     935             :    ! IN    = ( k + G | M     ) = kronecker(G,G ) - ------   )   e               ------------------------------------------------------- [3]
     936             :    !   G,I    \      |  k,I /                 I      Om    /                                          |G_I - G|^3
     937             :    !                                                      -----
     938             :    !                                                        a
     939             :    !                                                                            \_________________________ ___________________________/
     940             :    !                                                                                                      V
     941             :    !                                                                                                     I_a
     942             :    !
     943             :    ! In the code:
     944             :    ! V_G(k):  potential
     945             :    ! MT_G(k): muffintin
     946             :    ! IN_G:    interstitial
     947             :    ! I_a:     inter_atom
     948             :    !
     949             :    ! Input:
     950             :    ! rmsh        - array of radial mesh points
     951             :    ! rmt         - radius of the muffin tin
     952             :    ! dx          - logarithmic increment of radial mesh
     953             :    ! jri         - number of radial mesh points
     954             :    ! jmtd        - dimension of radial mesh points
     955             :    ! bk          - one(!) k-vector for which FT is calculated
     956             :    ! bmat        - reciprocal lattice vector for all directions
     957             :    ! vol         - volume of the unit cell
     958             :    ! ntype       - number of atom types
     959             :    ! neq         - number of symmetry-equivalent atoms of atom type i
     960             :    ! natd        - dimesion of atoms in unit cell
     961             :    ! taual       - vector of atom positions (internal coordinates)
     962             :    ! lcutm       - l cutoff for mixed basis
     963             :    ! maxlcutm    - maximum of all these l cutoffs
     964             :    ! nindxm      - number of radial functions of mixed basis
     965             :    ! maxindxm    - maximum of these numbers
     966             :    ! g        - reciprocal lattice vectors of the mixed basis (internal coord.)
     967             :    ! ngptm       - number of vectors (for treated k-vector)
     968             :    ! pgptm       - pointer to the appropriate g-vector (for treated k-vector)
     969             :    ! gptmd       - dimension of g
     970             :    ! basm        - mixed basis functions (mt + inter) for treated k-vector
     971             :    ! lexp        - cutoff of spherical harmonics expansion of plane wave
     972             :    ! noGPts      - no g-vectors used for Fourier trafo
     973             :    ! Output:
     974             :    ! potential   - Fourier transformation of the potential
     975             :    ! muffintin   - Fourier transformation of all MT functions
     976             :    ! interstital - Fourier transformation of all IR functions
     977           0 :    SUBROUTINE calculate_fourier_transform( &
     978             :       ! Input
     979           0 :       rmsh, rmt, dx, jri, jmtd, bk, &
     980           0 :       bmat, vol, ntype, neq, natd, taual, lcutm, maxlcutm, &
     981           0 :       nindxm, maxindxm, g, ngptm, pgptm, gptmd, &
     982           0 :       basm, noGPts, irank, &
     983             :       ! Output
     984           0 :       potential, muffintin, interstitial)
     985             : 
     986             :       USE m_constants
     987             :       USE m_types_hybdat, ONLY: gptnorm
     988             :       USE m_util, ONLY: sphbessel
     989             :       use m_intgrf, only: pure_intgrf, intgrf_init, intgrf_out,NEGATIVE_EXPONENT_WARNING, NEGATIVE_EXPONENT_ERROR
     990             :       IMPLICIT NONE
     991             : 
     992             :       ! scalar input
     993             :       INTEGER, INTENT(IN)    :: natd, ntype, maxlcutm
     994             :       INTEGER, INTENT(IN)    :: jmtd, irank
     995             :       INTEGER, INTENT(IN)    :: maxindxm
     996             :       INTEGER, INTENT(IN)    :: gptmd, noGPts
     997             :       REAL, INTENT(IN)       :: vol
     998             : 
     999             :       ! array input
    1000             :       INTEGER, INTENT(IN)    :: lcutm(:)
    1001             :       INTEGER, INTENT(IN)    :: nindxm(0:maxlcutm, ntype), neq(ntype)
    1002             :       INTEGER, INTENT(IN)    :: jri(:)
    1003             :       INTEGER, INTENT(IN)    :: g(:,:)
    1004             :       INTEGER, INTENT(IN)    :: ngptm
    1005             :       INTEGER, INTENT(IN)    :: pgptm(:)
    1006             : 
    1007             :       REAL, INTENT(IN)       :: bk(:)
    1008             :       REAL, INTENT(IN)       :: rmsh(:,:), rmt(:), dx(:)
    1009             :       REAL, INTENT(IN)       :: basm(jmtd, maxindxm, 0:maxlcutm, ntype)
    1010             :       REAL, INTENT(IN)       :: bmat(:,:)!,amat(3,3)
    1011             :       REAL, INTENT(IN)       :: taual(:,:)
    1012             : 
    1013             :       ! array output
    1014             :       REAL, INTENT(INOUT)    :: potential(noGPts)                           ! Fourier transformed potential
    1015             :       COMPLEX, INTENT(INOUT) :: muffintin(noGPts, maxindxm, &                 ! muffin-tin overlap integral
    1016             :                                           (maxlcutm + 1)**2, ntype, MAXVAL(neq))
    1017             :       COMPLEX, INTENT(INOUT) :: interstitial(noGPts, gptmd)                  ! interstistial overlap intergral
    1018             : 
    1019             :       ! private scalars
    1020             :       INTEGER                :: cg, cg2, ci, cl, cn, cr                      ! counter variables
    1021             :       REAL                   ::  r2Pi, r4Pi, pi_omega2                       !  2*Pi, 4*Pi, Pi/omega^2
    1022             :       REAL                   :: sVol, r4Pi_sVol, r4Pi_Vol                    ! sqrt(vol), 4*Pi/sqrt(Vol), 4*Pi/Vol
    1023             :       REAL                   :: omega, r1_omega2, r1_4omega2
    1024             : !     REAL,    PARAMETER     :: omega = omega_VHSE()                         ! omega of the HSE functional
    1025             : !     REAL,    PARAMETER     :: r1_omega2  = 1.0 / omega**2                  ! 1/omega^2
    1026             : !     REAL,    PARAMETER     :: r1_4omega2 = 0.25 * r1_omega2                ! 1/(4 omega^2)
    1027             :       COMPLEX, PARAMETER     :: img = (0.0, 1.0)                             ! i
    1028             : 
    1029             :       ! private arrays
    1030           0 :       INTEGER                :: gPts(3, noGPts)                              ! g vectors (internal units)
    1031           0 :       INTEGER                :: gPts_gptm(3, noGpts, gptmd)                  ! gPts - g
    1032           0 :       INTEGER                :: natdPtr(ntype + 1)                           ! pointer to all atoms of one type
    1033           0 :       REAL, ALLOCATABLE   :: gridf(:, :)                                     ! grid for radial integration
    1034           0 :       REAL                   :: k_G(3, noGPts)                               ! k + G
    1035           0 :       REAL                   :: AbsK_G(noGPts), AbsK_G2(noGPts)              ! abs(k+G), abs(k+G)^2
    1036           0 :       REAL                   :: arg(noGPts)                                  ! abs(k+G)^2 / (4*omega^2)
    1037           0 :       REAL                   :: sphbesK_Gr(noGPts, jmtd, 0:maxlcutm, ntype)  ! spherical bessel function of abs(k+G)r
    1038           0 :       TYPE(intgrf_out)       :: intgrMT(noGPts, maxindxm, 0:maxlcutm, ntype) ! integration in muffin-tin
    1039           0 :       REAL                   :: abs_dg(noGPts, gptmd)                        ! abs(gPts - g)
    1040           0 :       COMPLEX                :: imgl(0:maxlcutm)                             ! i^l
    1041           0 :       COMPLEX                :: Ylm(noGPts, (maxlcutm + 1)**2)               ! spherical harmonics for k+G and all lm
    1042           0 :       COMPLEX                :: expIGR(noGPts, ntype, MAXVAL(neq))           ! exp(-iGR) for all atom types
    1043           0 :       COMPLEX                :: sumInter_atom(noGPts, gptmd)                 ! sum over inter-atom factors
    1044             : 
    1045             :       ! Calculate helper variables
    1046           0 :       r2Pi = 2.0*pi_const
    1047           0 :       r4Pi = 4.0*pi_const
    1048           0 :       sVol = SQRT(vol)
    1049           0 :       r4Pi_sVol = r4Pi/sVol
    1050           0 :       r4Pi_Vol = r4Pi/Vol
    1051           0 :       omega = omega_hse!omega_VHSE()
    1052           0 :       r1_omega2 = 1.0/omega**2
    1053           0 :       r1_4omega2 = 0.25*r1_omega2
    1054           0 :       pi_omega2 = pi_const*r1_omega2
    1055             : 
    1056             :       ! calculate pointers for all atom-types to all atoms
    1057           0 :       natdPtr(ntype + 1) = natd
    1058           0 :       DO cn = ntype, 1, -1
    1059           0 :          natdPtr(cn) = natdPtr(cn + 1) - neq(cn)
    1060             :       END DO
    1061             : 
    1062             :       ! Define imgl(l) = img**l
    1063           0 :       imgl(0) = 1.0
    1064           0 :       DO ci = 1, maxlcutm
    1065           0 :          imgl(ci) = imgl(ci - 1)*img
    1066             :       END DO
    1067             : 
    1068             :       ! generate grid for fast radial integration
    1069           0 :       CALL intgrf_init(ntype, jmtd, jri, dx, rmsh, gridf)
    1070             : 
    1071             :       ! Set all arrays to 0
    1072           0 :       gPts = 0
    1073           0 :       k_G = 0
    1074           0 :       AbsK_G = 0
    1075           0 :       arg = 0
    1076           0 :       sphbesK_Gr = 0
    1077           0 :       intgrMT%value = 0
    1078           0 :       intgrMT%ierror = 0
    1079           0 :       Ylm = 0
    1080           0 :       expIGR = 0
    1081           0 :       gPts_gptm = 0
    1082           0 :       abs_dg = 0
    1083           0 :       sumInter_atom = 0
    1084           0 :       potential = 0
    1085           0 :       muffintin = 0
    1086           0 :       interstitial = 0
    1087             : 
    1088             : ! Calculate the muffin-tin basis function overlap integral
    1089             : !                                                            R
    1090             : !                                     -L                      /
    1091             : !           /      |      \     4 Pi i         ^     -i G R  |     2
    1092             : ! MT (k) = ( k + G | M     ) = ---------- Y ( k+G ) e        | dr r  Phi(r) j ( |k+G| r )  [2]
    1093             : !   G,I     \      |  k,I /     Sqrt(Om)   LM                |               L
    1094             : !                                                           /
    1095             : !                                                            0
    1096           0 :       IF (ngptm < noGpts) call juDFT_error( 'hsefunctional: error calculating Fourier coefficients, noGpts too large')
    1097             : 
    1098           0 :       gPts(:, :) = g(:, pgptm(1:noGPts))
    1099             : #ifndef __PGI
    1100           0 :       gpoints: DO cg=1, noGPts
    1101           0 :          ntypesA: DO cn=1, ntype
    1102             :          ! Calculate the phase factor exp(-iGR) for all atoms
    1103           0 :          DO ci=1,neq(cn)
    1104           0 :          expIGR(cg, cn, ci) = EXP(-r2Pi*img*DOT_PRODUCT(taual(:, natdPtr(cn) + ci), gPts(:, cg)))
    1105           0 :          muffintin(cg, :, :, cn, ci) = r4Pi_sVol*expIGR(cg, cn, ci)
    1106             :          END DO
    1107             : 
    1108             :          ! Multiplication with i^-L
    1109           0 :          DO cl=0,lcutm(cn)
    1110           0 :          muffintin(cg, :, cl*cl + 1:(cl + 1)*(cl + 1), cn, :) = muffintin(cg, :, cl*cl + 1:(cl + 1)*(cl + 1), cn, :)/imgl(cl)
    1111             :          END DO
    1112             :          END DO ntypesA
    1113             : 
    1114             :          ! Calculate the k+G, abs(k+G), and abs(k+G)^2
    1115           0 :          k_G(:, cg) = MATMUL(gPts(:, cg) + bk(:), bmat(:, :))
    1116           0 :          AbsK_G2(cg) = SUM(k_G(:, cg)**2)
    1117           0 :          AbsK_G(cg) = SQRT(AbsK_G2(cg))
    1118             : 
    1119             :          ! Spherical harmonics are calculated for all lm's and k+G's
    1120           0 :          Ylm(cg, :) = calcYlm(k_G(:, cg), maxlcutm)
    1121             : 
    1122             :          ! Perform the integration in eq.[2] for all muffin-tins
    1123           0 :          ntypesB:DO cn=1,ntype
    1124             : 
    1125             :             ! Multiplication with the spherical harmonic
    1126           0 :             DO cl=1,(lcutm(cn) + 1)**2
    1127           0 :                muffintin(cg, :, cl, cn, :) = muffintin(cg, :, cl, cn, :)*Ylm(cg, cl)
    1128             :             END DO
    1129             : 
    1130             :          ! Calculate the spherical bessel function
    1131           0 :             DO cr=1,jri(cn)
    1132           0 :                sphbesK_Gr(cg, cr, :, cn) = calcSphBes(AbsK_G(cg)*rmsh(cr, cn), maxlcutm)
    1133             :             END DO
    1134             :          ! integrate the function and multiplicate to the result
    1135           0 :             DO cl=0,lcutm(cn)
    1136           0 :                DO ci=1,nindxm(cl, cn)
    1137             :                   intgrMT(cg, ci, cl, cn) = pure_intgrf(rmsh(:, cn)*basm(:, ci, cl, cn)* &
    1138           0 :                                              sphbesK_Gr(cg, :, cl, cn), jri, jmtd, rmsh, dx, ntype, cn, gridf)
    1139             :                   muffintin(cg, ci, cl*cl + 1:(cl + 1)*(cl + 1), cn, :) = &
    1140           0 :                      muffintin(cg, ci, cl*cl + 1:(cl + 1)*(cl + 1), cn, :)*intgrMT(cg, ci, cl, cn)%value
    1141             :                END DO
    1142             :             END DO
    1143             : 
    1144             :          END DO ntypesB
    1145             : 
    1146             : ! calculate the overlap with the interstitial basis function
    1147             : !                                                      -----
    1148             : !          /      |      \                       4 Pi   \     -i(G - G_I)R_a  Sin(|G_I - G| R_a) - |G_I - G| R_a Cos(|G_I - G| R_a)
    1149             : ! IN    = ( k + G | M     ) = kronecker(G,G ) - ------   )   e               ------------------------------------------------------- [3]
    1150             : !   G,I    \      |  k,I /                 I      Om    /                                          |G_I - G|^3
    1151             : !                                                      -----
    1152             : !                                                        a
    1153             : !                                                                            \_________________________ ___________________________/
    1154             : !                                                                                                      V
    1155             : !                                                                                                     I_a
    1156             :       ! Calculate the difference of the G vectors and its absolute value
    1157           0 :       DO cg2=1,gptmd
    1158             : 
    1159           0 :       gPts_gptm(:, cg, cg2) = gPts(:, cg) - g(:, cg2)
    1160           0 :       abs_dg(cg, cg2) = gptnorm(gPts_gptm(:, cg, cg2), bmat)
    1161             : 
    1162             :       END DO
    1163             : 
    1164             :       END DO gpoints
    1165             : 
    1166             :       ! Check if any of the integrations failed and abort if one did
    1167           0 :       IF (ANY(intgrMT%ierror == NEGATIVE_EXPONENT_ERROR)) THEN
    1168           0 :          IF (irank == 0) WRITE (oUnit, *) 'intgrf: Warning! Negative exponent x in extrapolation a+c*r**x'
    1169           0 :       ELSEIF (ANY(intgrMT%ierror == NEGATIVE_EXPONENT_WARNING)) THEN
    1170           0 :          IF (irank == 0) WRITE (oUnit, *) 'intgrf: Negative exponent x in extrapolation a+c*r**x'
    1171           0 :          call juDFT_error( 'intgrf: Negative exponent x in extrapolation a+c*r**x')
    1172             :       END IF
    1173             : 
    1174             :       ! Calculate the interstitial value with eq.[3] using the limit
    1175             :       !           3
    1176             :       !        R_a
    1177             :       ! I_a = ------
    1178             :       !         3
    1179             :       ! if there's no difference of the two G vectors
    1180           0 :       WHERE (abs_dg == 0)
    1181             :       sumInter_atom = DOT_PRODUCT(rmt**3, neq)/3.0
    1182             :       interstitial = 1.0 - r4Pi_Vol*sumInter_atom
    1183             :       ELSEWHERE
    1184             :       sumInter_atom = calculateSummation(abs_dg, gPts_gptm)
    1185             :       interstitial = -r4Pi_Vol*sumInter_atom
    1186             :       END WHERE
    1187             : 
    1188             : ! Calculate the Fourier transformed potential
    1189             : !                                                 /          \
    1190             : !          /      | erf |       \      4 Pi      |   |k+G|^2  |
    1191             : ! V (k) = ( k + G | --- | k + G' ) = -------  Exp| - -------  | kronecker(G,G')             [1]
    1192             : !  G       \      |  r  |       /    |k+G|^2     |    4 w^2   |
    1193             : !                                                 \          /
    1194           0 :       WHERE (absK_G /= 0)
    1195             :       ! Calculate (k+G)^2 / 4*w^2
    1196             :       arg = -r1_4omega2*AbsK_G2
    1197             : 
    1198             :       ! The potential is calculated using eq.[1]
    1199             :       potential = r4Pi/AbsK_G2*EXP(arg)
    1200             : 
    1201             : ! Calculate the Fourier transformed potential for the full(!) potential
    1202             : !
    1203             : !          /          | erfc |          \      Pi
    1204             : ! V (k) = ( k + G = 0 | ---- | k + G = 0 ) = -----
    1205             : !  G       \          |   r  |          /     w^2
    1206             : !
    1207             :       ELSEWHERE
    1208             :       ! the negative sign is added to compensate the sign when the
    1209             :       ! contribution is added to the Coulomb matrix
    1210             :       potential = -pi_omega2
    1211             :       endwhere
    1212             : 
    1213           0 :       deallocate(gridf)
    1214             : #else
    1215             :       call judft_error("hsefunctional not implemented for PGI")
    1216             : #endif
    1217             :    CONTAINS
    1218             : 
    1219             :       ! Calculates the inter-atom parts and the summation over all atoms:
    1220             :       ! -----
    1221             :       !  \     -i(G - G_I)R_a  Sin(|G_I - G| R_a) - |G_I - G| R_a Cos(|G_I - G| R_a)
    1222             :       !   )   e               -------------------------------------------------------
    1223             :       !  /                                          |G_I - G|^3
    1224             :       ! -----
    1225             :       !   a
    1226             :       ! Input:  abs_dg    - absolute value |G_I - G|
    1227             :       !         gPts_gptm - vector G - G_I
    1228           0 :       PURE FUNCTION calculateSummation(abs_dg, gPts_gptm)
    1229             :          IMPLICIT NONE
    1230             :          INTEGER, INTENT(IN) :: gPts_gptm(:,:,:)
    1231             :          REAL, INTENT(IN)    :: abs_dg(:,:)
    1232             :          COMPLEX             :: calculateSummation(noGPts, gptmd)
    1233             :          INTEGER             :: cn, ci                                     ! counter variables
    1234           0 :          REAL                :: masked(noGPts, gptmd)
    1235           0 :          REAL                :: abs_dgR(noGPts, gptmd, ntype)               ! abs(gPts - g)*R (R: radius MT)
    1236           0 :          REAL                :: inter_atom(noGPts, gptmd, ntype)            ! inter-atom interaction for interstitial
    1237           0 :          COMPLEX             :: expIdGR(noGPts, gptmd, ntype, MAXVAL(neq))   ! exp(-i(gPts-g)R)
    1238           0 :          COMPLEX             :: sumExpIdGR(noGPts, gptmd, ntype)            ! sum over atom of same type
    1239           0 :          WHERE (abs_dg /= 0)
    1240             :             masked = abs_dg
    1241             :          ELSEWHERE
    1242             :             masked = 1.0
    1243             :          END WHERE
    1244             : 
    1245           0 :          atoms:DO cn=1,ntype
    1246             :             !                                                         -i(G-G_I)R_a
    1247             :             ! Calculate for all similar atoms (same type) the factor e
    1248             :             ! use that the G vectors and atomic positions are given in internal units
    1249           0 :             DO ci=1,neq(cn)
    1250           0 :                expIdGR(:, :, cn, ci) = EXP(-r2pi*img*my_dot_product(gPts_gptm(:, :, :), taual(:, natdPtr(cn) + ci)))
    1251             :             END DO
    1252             :             ! Add all factors for atoms of the same type
    1253           0 :             sumExpIdGR(:, :, cn) = my_sum(expIdGR(:, :, cn, :))
    1254             :          
    1255             :             ! Calculate the inter-atom factor which is the same for all atoms of the same type
    1256           0 :             abs_dgR(:, :, cn) = abs_dg*rmt(cn)
    1257           0 :             inter_atom(:, :, cn) = (SIN(abs_dgR(:, :, cn)) - abs_dgR(:, :, cn)*COS(abs_dgR(:, :, cn)))/masked**3
    1258             :          END DO atoms
    1259             :          ! Add the factors of all atoms together
    1260           0 :          calculateSummation = my_dot_product(sumExpIdGR, inter_atom)
    1261             :       END FUNCTION calculateSummation
    1262             : 
    1263             :    END SUBROUTINE calculate_fourier_transform
    1264             : 
    1265             :    ! Calculate several Fourier transformations
    1266             :    ! a) the Fourier transformed potential
    1267             :    !                                                 /          \
    1268             :    !          /      | erf |       \     4 Pi       |   |k+G|^2  |
    1269             :    ! V (k) = ( k + G | --- | k + G  ) = -------  Exp| - -------  |                             [1]
    1270             :    !  G       \      |  r  |       /    |k+G|^2     |    4 w^2   |
    1271             :    !                                                 \          /
    1272             :    !
    1273             :    ! b) muffin-tin basis function
    1274             :    !                                                            R
    1275             :    !                                     -L                      /
    1276             :    !           /      |      \     4 Pi i         ^     -i G R  |     2
    1277             :    ! MT (k) = ( k + G | M     ) = ---------- Y ( k+G ) e        | dr r  Phi(r) j ( |k+G| r )  [2]
    1278             :    !   G,I     \      |  k,I /     Sqrt(Om)   LM                |               L
    1279             :    !                                                           /
    1280             :    !                                                            0
    1281             :    !
    1282             :    ! In the code:
    1283             :    ! V_G(k):  potential
    1284             :    ! MT_G(k): muffintin
    1285             :    !
    1286             :    ! Input:
    1287             :    ! rmsh        - array of radial mesh points
    1288             :    ! rmt         - radius of the muffin tin
    1289             :    ! dx          - logarithmic increment of radial mesh
    1290             :    ! jri         - number of radial mesh points
    1291             :    ! jmtd        - dimension of radial mesh points
    1292             :    ! bk          - one(!) k-vector for which FT is calculated
    1293             :    ! bmat        - reciprocal lattice vector for all directions
    1294             :    ! vol         - volume of the unit cell
    1295             :    ! ntype       - number of atom types
    1296             :    ! neq         - number of symmetry-equivalent atoms of atom type i
    1297             :    ! natd        - dimesion of atoms in unit cell
    1298             :    ! taual       - vector of atom positions (internal coordinates)
    1299             :    ! lcutm       - l cutoff for mixed basis
    1300             :    ! maxlcutm    - maximum of all these l cutoffs
    1301             :    ! nindxm      - number of radial functions of mixed basis
    1302             :    ! maxindxm    - maximum of these numbers
    1303             :    ! g        - reciprocal lattice vectors of the mixed basis (internal coord.)
    1304             :    ! ngptm       - number of vectors (for treated k-vector)
    1305             :    ! pgptm       - pointer to the appropriate g-vector (for treated k-vector)
    1306             :    ! gptmd       - dimension of g
    1307             :    ! basm        - mixed basis functions (mt + inter) for treated k-vector
    1308             :    ! lexp        - cutoff of spherical harmonics expansion of plane wave
    1309             :    ! noGPts      - no g-vectors used for Fourier trafo
    1310             :    ! Output:
    1311             :    ! potential   - Fourier transformation of the potential
    1312             :    ! muffintin   - Fourier transformation of all MT functions
    1313           0 :    SUBROUTINE calculate_fourier_transform_once( &
    1314             :       ! Input
    1315           0 :       atoms, bk, ikpt, nkptf, &
    1316           0 :       bmat, vol, lcutm, maxlcutm, &
    1317           0 :       nindxm, maxindxm, g, ngptm, pgptm, gptmd, &
    1318           0 :       nbasp, basm, noGPts, sym, irank, &
    1319             :       ! Output
    1320           0 :       potential, fourier_trafo)
    1321             : 
    1322             :       USE m_constants
    1323             :       USE m_util, ONLY: sphbessel
    1324             :       use m_intgrf, only: pure_intgrf, intgrf_init, intgrf_out,  NEGATIVE_EXPONENT_WARNING, NEGATIVE_EXPONENT_ERROR
    1325             :       USE m_trafo, ONLY: symmetrize
    1326             :       USE m_types_atoms
    1327             :       USE m_types_sym
    1328             : 
    1329             :       IMPLICIT NONE
    1330             : 
    1331             :       TYPE(t_atoms), INTENT(IN) :: atoms
    1332             :       TYPE(t_sym), INTENT(IN)   :: sym
    1333             : 
    1334             :       ! scalar input
    1335             :       INTEGER, INTENT(IN)    :: maxlcutm
    1336             :       INTEGER, INTENT(IN)    :: ikpt, nkptf
    1337             :       INTEGER, INTENT(IN)    :: maxindxm, irank
    1338             :       INTEGER, INTENT(IN)    :: gptmd, noGPts
    1339             :       REAL, INTENT(IN)       :: vol
    1340             : 
    1341             :       ! array input
    1342             :       INTEGER, INTENT(IN)    :: lcutm(:)
    1343             :       INTEGER, INTENT(IN)    :: nindxm(0:maxlcutm, atoms%ntype)
    1344             :       INTEGER, INTENT(IN)    :: g(:,:)
    1345             :       INTEGER, INTENT(IN)    :: ngptm, nbasp
    1346             :       INTEGER, INTENT(IN)    :: pgptm(:)
    1347             : 
    1348             :       REAL, INTENT(IN)       :: bk(:)
    1349             :       REAL, INTENT(IN)       :: basm(atoms%jmtd, maxindxm, 0:maxlcutm, atoms%ntype)
    1350             :       REAL, INTENT(IN)       :: bmat(:,:)
    1351             : 
    1352             :       ! array output
    1353             :       REAL, INTENT(INOUT)      :: potential(noGPts)                           ! Fourier transformed potential
    1354             : #ifdef CPP_INVERSION
    1355             :       REAL, INTENT(INOUT)      :: fourier_trafo(nbasp, noGPts) !muffintin_out(nbasp,noGPts)
    1356             : #else
    1357             :       COMPLEX, INTENT(INOUT)   :: fourier_trafo(nbasp, noGPts) !muffintin_out(nbasp,noGPts)
    1358             : #endif
    1359             : 
    1360             :       ! private scalars
    1361             :       INTEGER                :: cg, cg2, ci, cl, cm, cn, cr                       ! counter variables
    1362             :       REAL                   :: r2Pi, r4Pi, pi_omega2                   ! Pi, 2*Pi, 4*Pi, Pi/omega^2
    1363             :       REAL                   :: sVol, r4Pi_sVol, r4Pi_Vol                   ! sqrt(vol), 4*Pi/sqrt(Vol), 4*Pi/Vol
    1364             :       REAL                   :: omega, r1_omega2, r1_4omega2
    1365             : !     REAL,    PARAMETER     :: omega = omega_VHSE()                        ! omega of the HSE functional
    1366             : !     REAL,    PARAMETER     :: r1_omega2  = 1.0 / omega**2                 ! 1/omega^2
    1367             : !     REAL,    PARAMETER     :: r1_4omega2 = 0.25 * r1_omega2               ! 1/(4 omega^2)
    1368             :       COMPLEX, PARAMETER     :: img = (0.0, 1.0)                             ! i
    1369             : 
    1370             :       ! private arrays
    1371           0 :       INTEGER                :: gPts(3, noGPts)                              ! g vectors (internal units)
    1372           0 :       INTEGER                :: natdPtr(atoms%ntype + 1)                            ! pointer to all atoms of one type
    1373           0 :       INTEGER                :: ptrType(nbasp), ptrEq(nbasp), &               ! pointer from ibasp to corresponding
    1374           0 :                                 ptrLM(nbasp), ptrN(nbasp)                    ! type, atom, l and m, and n
    1375           0 :       REAL, ALLOCATABLE   :: gridf(:, :)                                  ! grid for radial integration
    1376           0 :       REAL                   :: k_G(3, noGPts)                               ! k + G
    1377           0 :       REAL                   :: AbsK_G(noGPts), AbsK_G2(noGPts)              ! abs(k+G), abs(k+G)^2
    1378           0 :       REAL                   :: arg(noGPts)                                 ! abs(k+G)^2 / (4*omega^2)
    1379           0 :       REAL                   :: sphbesK_Gr(noGPts, atoms%jmtd, 0:maxlcutm, atoms%ntype)    ! spherical bessel function of abs(k+G)r
    1380           0 :       TYPE(intgrf_out)       :: intgrMT(noGPts, maxindxm, 0:maxlcutm, atoms%ntype)   ! integration in muffin-tin
    1381           0 :       COMPLEX                :: imgl(0:maxlcutm)                            ! i^l
    1382           0 :       COMPLEX                :: Ylm(noGPts, (maxlcutm + 1)**2)                 ! spherical harmonics for k+G and all lm
    1383           0 :       COMPLEX                :: expIGR(noGPts, atoms%ntype, MAXVAL(atoms%neq))            ! exp(-iGR) for all atom types
    1384             :       COMPLEX                :: muffintin(noGPts, maxindxm, &                 ! muffin-tin overlap integral
    1385           0 :                                           (maxlcutm + 1)**2, atoms%ntype, MAXVAL(atoms%neq))
    1386             : 
    1387           0 :       COMPLEX                :: sym_muffintin(nbasp, noGPts)                 ! symmetrized muffin tin
    1388           0 :       COMPLEX                :: transposed_sym_mt(noGPts, nbasp)
    1389             :       LOGICAL, SAVE          :: first_entry = .TRUE.                        ! allocate arrays in first entry
    1390             : 
    1391             :       ! allocate arrays in first entry reuse later
    1392           0 :       IF (first_entry) THEN
    1393           0 :          allocate(already_known(nkptf), &            ! stores which elements are known
    1394           0 :                    known_potential(maxNoGPts, nkptf), &            ! stores the potential for all k-points
    1395           0 :                    known_fourier_trafo(nbasp, maxNoGPts, nkptf))            ! stores the fourier transform of the mixed basis
    1396             :          ! initialization
    1397           0 :          already_known = .FALSE.
    1398           0 :          known_potential = 0.0
    1399           0 :          known_fourier_trafo = 0.0
    1400             :          ! unset flag as arrays are allocated
    1401           0 :          first_entry = .FALSE.
    1402             :       ELSE
    1403             :          ! check if size of arrays has changed and st--op with error if they did
    1404           0 :          IF (SIZE(already_known) /= nkptf) call juDFT_error('hsefunctional: Array size changed!')
    1405           0 :          IF (SIZE(known_fourier_trafo, 1) /= nbasp) call juDFT_error( 'hsefunctional: Array size changed!')
    1406             :       END IF
    1407             : 
    1408             :       ! if the current k-point was not calculated yet
    1409           0 :       IF (.NOT. (already_known(ikpt))) THEN
    1410             : 
    1411             :          ! Calculate helper variables
    1412           0 :          r2Pi = 2.0*pi_const
    1413           0 :          r4Pi = 4.0*pi_const
    1414           0 :          sVol = SQRT(vol)
    1415           0 :          r4Pi_sVol = r4Pi/sVol
    1416           0 :          r4Pi_Vol = r4Pi/Vol
    1417           0 :          omega = omega_hse!omega_VHSE()
    1418           0 :          r1_omega2 = 1.0/omega**2
    1419           0 :          r1_4omega2 = 0.25*r1_omega2
    1420           0 :          pi_omega2 = pi_const*r1_omega2
    1421             : 
    1422             :          ! calculate pointers for all atom-types to all atoms
    1423           0 :          natdPtr(atoms%ntype + 1) = atoms%nat
    1424           0 :          DO cn = atoms%ntype, 1, -1
    1425           0 :             natdPtr(cn) = natdPtr(cn + 1) - atoms%neq(cn)
    1426             :          END DO
    1427             : 
    1428             :          ! Define imgl(l) = img**l
    1429           0 :          imgl(0) = 1.0
    1430           0 :          DO ci = 1, maxlcutm
    1431           0 :             imgl(ci) = imgl(ci - 1)*img
    1432             :          END DO
    1433             : 
    1434             :          ! generate grid for fast radial integration
    1435           0 :          CALL intgrf_init(atoms%ntype, atoms%jmtd, atoms%jri, atoms%dx, atoms%rmsh, gridf)
    1436             : 
    1437             :          ! Set all arrays to 0
    1438           0 :          gPts = 0
    1439           0 :          k_G = 0
    1440           0 :          AbsK_G = 0
    1441           0 :          arg = 0
    1442           0 :          sphbesK_Gr = 0
    1443           0 :          intgrMT%value = 0
    1444           0 :          intgrMT%ierror = 0
    1445           0 :          Ylm = 0
    1446           0 :          expIGR = 0
    1447           0 :          potential = 0
    1448           0 :          muffintin = 0
    1449             : 
    1450             : ! Calculate the muffin-tin basis function overlap integral
    1451             : !                                                            R
    1452             : !                                     -L                      /
    1453             : !           /      |      \     4 Pi i         ^     -i G R  |     2
    1454             : ! MT (k) = ( k + G | M     ) = ---------- Y ( k+G ) e        | dr r  Phi(r) j ( |k+G| r )  [2]
    1455             : !   G,I     \      |  k,I /     Sqrt(Om)   LM                |               L
    1456             : !                                                           /
    1457             : !                                                            0
    1458           0 :          IF (ngptm < noGpts) call juDFT_error( 'hsefunctional: error calculating Fourier coefficients, noGpts too large')
    1459             : 
    1460           0 :          gPts(:, :) = g(:, pgptm(1:noGPts))
    1461             : 
    1462           0 :          gpoints:DO cg=1,noGPts
    1463           0 :          ntypesA:DO cn=1,atoms%ntype
    1464             : 
    1465             :          ! Calculate the phase factor exp(-iGR) for all atoms
    1466           0 :          DO ci=1,atoms%neq(cn)
    1467           0 :          expIGR(cg, cn, ci) = EXP(-r2Pi*img*DOT_PRODUCT(atoms%taual(:, natdPtr(cn) + ci), gPts(:, cg)))
    1468           0 :          muffintin(cg, :, :, cn, ci) = r4Pi_sVol*expIGR(cg, cn, ci)
    1469             :          END DO
    1470             : 
    1471             :          ! Multiplication with i^-L
    1472           0 :          DO cl=0,lcutm(cn)
    1473           0 :          muffintin(cg, :, cl*cl + 1:(cl + 1)*(cl + 1), cn, :) = muffintin(cg, :, cl*cl + 1:(cl + 1)*(cl + 1), cn, :)/imgl(cl)
    1474             :          END DO
    1475             : 
    1476             :          END DO ntypesA
    1477             : 
    1478             :          ! Calculate the k+G, abs(k+G), and abs(k+G)^2
    1479           0 :          k_G(:, cg) = MATMUL(gPts(:, cg) + bk(:), bmat(:, :))
    1480           0 :          AbsK_G2(cg) = SUM(k_G(:, cg)**2)
    1481           0 :          AbsK_G(cg) = SQRT(AbsK_G2(cg))
    1482             : 
    1483             :          ! Spherical harmonics are calculated for all lm's and k+G's
    1484           0 :          Ylm(cg, :) = calcYlm(k_G(:, cg), maxlcutm)
    1485             : 
    1486             :          ! Perform the integration in eq.[2] for all muffin-tins
    1487           0 :          ntypesB:DO cn=1,atoms%ntype
    1488             : 
    1489             :          ! Multiplication with the spherical harmonic
    1490           0 :          DO cl=1,(lcutm(cn) + 1)**2
    1491           0 :          muffintin(cg, :, cl, cn, :) = muffintin(cg, :, cl, cn, :)*Ylm(cg, cl)
    1492             :          END DO
    1493             : 
    1494             :          ! Calculate the spherical bessel function
    1495           0 :          DO cr=1,atoms%jri(cn)
    1496           0 :          sphbesK_Gr(cg, cr, :, cn) = calcSphBes(AbsK_G(cg)*atoms%rmsh(cr, cn), maxlcutm)
    1497             :          END DO
    1498             :          ! integrate the function and multiplicate to the result
    1499           0 :          DO cl=0,lcutm(cn)
    1500           0 :          DO ci=1,nindxm(cl, cn)
    1501             :          intgrMT(cg, ci, cl, cn) = pure_intgrf(atoms%rmsh(:, cn)*basm(:, ci, cl, cn)* &
    1502           0 :                                                sphbesK_Gr(cg, :, cl, cn), atoms%jri, atoms%jmtd, atoms%rmsh, atoms%dx, atoms%ntype, cn, gridf)
    1503             :          muffintin(cg, ci, cl*cl + 1:(cl + 1)*(cl + 1), cn, :) = &
    1504           0 :             muffintin(cg, ci, cl*cl + 1:(cl + 1)*(cl + 1), cn, :)*intgrMT(cg, ci, cl, cn)%value
    1505             :          END DO
    1506             :          END DO
    1507             : 
    1508             :          END DO ntypesB
    1509             : 
    1510             :          END DO gpoints
    1511             : 
    1512             :          ! Check if any of the integrations failed and abort if one did
    1513           0 :          IF (ANY(intgrMT%ierror == NEGATIVE_EXPONENT_ERROR)) THEN
    1514           0 :             IF (irank == 0) WRITE (oUnit, *) 'intgrf: Warning! Negative exponent x in extrapolation a+c*r**x'
    1515           0 :          ELSEIF (ANY(intgrMT%ierror == NEGATIVE_EXPONENT_WARNING)) THEN
    1516           0 :             IF (irank == 0) WRITE (oUnit, *) 'intgrf: Negative exponent x in extrapolation a+c*r**x'
    1517           0 :             call juDFT_error( 'intgrf: Negative exponent x in extrapolation a+c*r**x')
    1518             :          END IF
    1519             : 
    1520             : ! Calculate the Fourier transformed potential
    1521             : !                                                 /          \
    1522             : !          /      | erf |       \      4 Pi      |   |k+G|^2  |
    1523             : ! V (k) = ( k + G | --- | k + G' ) = -------  Exp| - -------  | kronecker(G,G')             [1]
    1524             : !  G       \      |  r  |       /    |k+G|^2     |    4 w^2   |
    1525             : !                                                 \          /
    1526           0 :          WHERE (absK_G /= 0)
    1527             :          ! Calculate (k+G)^2 / 4*w^2
    1528             :          arg = -r1_4omega2*AbsK_G2
    1529             : 
    1530             :          ! The potential is calculated using eq.[1]
    1531             :          potential = r4Pi/AbsK_G2*EXP(arg)
    1532             : 
    1533             : ! Calculate the Fourier transformed potential for the full(!) potential
    1534             : !
    1535             : !          /          | erfc |          \      Pi
    1536             : ! V (k) = ( k + G = 0 | ---- | k + G = 0 ) = -----
    1537             : !  G       \          |   r  |          /     w^2
    1538             : !
    1539             :          ELSEWHERE
    1540             :          ! the negative sign is added to compensate the sign when the
    1541             :          ! contribution is added to the Coulomb matrix
    1542             :          potential = -pi_omega2
    1543             :          endwhere
    1544             : 
    1545           0 :          deallocate(gridf)
    1546             : 
    1547             :          !
    1548             :          ! Create pointer which correlate the position in the array with the
    1549             :          ! appropriate indices of the MT mixed basis function
    1550             :          !
    1551           0 :          cg = 0
    1552           0 :          DO cn = 1, atoms%ntype
    1553           0 :             DO ci = 1, atoms%neq(cn)
    1554           0 :                DO cl = 0, lcutm(cn)
    1555           0 :                   DO cm = -cl, cl
    1556           0 :                      DO cr = 1, nindxm(cl, cn)
    1557           0 :                         cg = cg + 1
    1558           0 :                         ptrType(cg) = cn
    1559           0 :                         ptrEq(cg) = ci
    1560           0 :                         ptrLM(cg) = (cl + 1)*cl + cm + 1
    1561           0 :                         ptrN(cg) = cr
    1562             :                      END DO
    1563             :                   END DO
    1564             :                END DO
    1565             :             END DO
    1566             :          END DO
    1567           0 :          IF (nbasp /= cg) call juDFT_error( 'hsefunctional: wrong array size: nbasp')
    1568             :          
    1569           0 :          IF (sym%invs) THEN
    1570             :             ! Symmetrize muffin tin fourier transform
    1571           0 :             DO ci = 1, nbasp
    1572           0 :                sym_muffintin(ci, :noGPts) = muffintin(:, ptrN(ci), ptrLM(ci), ptrType(ci), ptrEq(ci))
    1573             :             END DO
    1574           0 :             transposed_sym_mt = TRANSPOSE(sym_muffintin)
    1575           0 :             DO cg = 1, noGPts
    1576             :                CALL symmetrize(transposed_sym_mt(cg:cg, :), 1, nbasp, 2, &
    1577             :                             atoms, lcutm, maxlcutm, &
    1578           0 :                             nindxm, sym)
    1579             :             END DO
    1580           0 :             sym_muffintin = TRANSPOSE(transposed_sym_mt)
    1581             :             ! store the fourier transform of the muffin tin basis
    1582           0 :             known_fourier_trafo(:, :, ikpt) = REAL(sym_muffintin)
    1583             :          ELSE
    1584             :             ! store the fourier transform of the muffin tin basis
    1585           0 :             DO ci = 1, nbasp
    1586           0 :                known_fourier_trafo(ci, :noGPts, ikpt) = CONJG(muffintin(:, ptrN(ci), ptrLM(ci), ptrType(ci), ptrEq(ci)))
    1587             :             END DO
    1588             :          ENDIF
    1589             :          ! store the fourier transform of the potential
    1590           0 :          known_potential(:noGPts, ikpt) = potential
    1591             :          ! set the flag so that the fourier transform is not calculated again
    1592           0 :          already_known(ikpt) = .TRUE.
    1593           0 :          IF (MINVAL(ABS(potential)) > 1e-12) THEN
    1594           0 :             WRITE (*, *) 'hsefunctional: Warning! Smallest potential bigger than numerical precision!', MINVAL(ABS(potential))
    1595           0 :             WRITE (*, *) 'Perhaps you should increase the number of g-Points used and recompile!'
    1596             :          END IF
    1597             : 
    1598             :       END IF
    1599             : 
    1600             :       ! return the fourier transform
    1601           0 :       potential = known_potential(:noGPts, ikpt)
    1602           0 :       fourier_trafo = known_fourier_trafo(:, :noGPts, ikpt)
    1603             : 
    1604           0 :    END SUBROUTINE calculate_fourier_transform_once
    1605             : 
    1606             :    ! Correct the pure Coulomb Matrix with by subtracting the long-range component
    1607             :    !
    1608             :    !  /     |      |      \     /     |       |      \     /     |     |      \
    1609             :    ! ( M    | V    | M     ) = ( M    | V     | M     ) - ( M    | V   | M     )
    1610             :    !  \ k,I |  HSE |  k,J /     \ k,I |  coul |  k,J /     \ k,I |  LR |  k,J /
    1611             :    !
    1612             :    ! The long-range component is given py the potential
    1613             :    !
    1614             :    !         erf( w r )
    1615             :    ! V (r) = ----------
    1616             :    !  LR         r
    1617             :    !
    1618             :    ! Input:
    1619             :    ! rmsh     - array of radial mesh points
    1620             :    ! rmt      - radius of the muffin tin
    1621             :    ! dx       - logarithmic increment of radial mesh
    1622             :    ! jri      - number of radial mesh points
    1623             :    ! jmtd     - dimension of radial mesh points
    1624             :    ! nkptf    - number of total k-points
    1625             :    ! nkptd    - dimension of k-points
    1626             :    ! nkpti    - number of irreducible k-points in window (in KPTS)
    1627             :    ! bk       - k-vector for all irreduble k-points
    1628             :    ! bmat     - reciprocal lattice vector for all directions
    1629             :    ! vol      - volume of unit cell
    1630             :    ! ntype    - number of atom types
    1631             :    ! neq      - number of symmetry-equivalent atoms of atom type i
    1632             :    ! natd     - dimension of atoms in unit cell
    1633             :    ! taual    - vector of atom positions (internal coordinates)
    1634             :    ! lcutm    - l cutoff for mixed basis
    1635             :    ! maxlcutm - maximum of all these l cutoffs
    1636             :    ! nindxm   - number of radial functions of mixed basis
    1637             :    ! maxindxm - maximum of these numbers
    1638             :    ! g     - reciprocal lattice vectors of the mixed basis (internal coord.)
    1639             :    ! ngptm    - number of vectors
    1640             :    ! pgptm    - pointer to the appropriate g-vector
    1641             :    ! gptmd    - dimension of g
    1642             :    ! basm     - radial mixed basis functions (mt + inter)
    1643             :    ! lexp     - cutoff of spherical harmonics expansion of plane wave
    1644             :    ! maxbasm  - maximum number of mixed basis functions
    1645             :    ! nbasm    - number of mixed basis function
    1646             :    ! invsat   - number of inversion-symmetric atom
    1647             :    ! invsatnr - number of inversion-symmetric atom
    1648             :    ! Inout:
    1649             :    ! coulomb  - Coulomb matrix which is changed
    1650           0 :    SUBROUTINE change_coulombmatrix( &
    1651             :       ! Input
    1652           0 :       atoms, nkptf, nkpti, bk, &
    1653           0 :       bmat, vol, lcutm, maxlcutm, &
    1654           0 :       nindxm, maxindxm, g, ngptm, pgptm, gptmd, &
    1655           0 :       basm, lexp, maxbasm, nbasm, sym, irank, &
    1656             :       ! Input & output
    1657             :       coul)
    1658             : 
    1659             :       USE m_trafo, ONLY: symmetrize
    1660             :       USE m_wrapper, ONLY: packmat, unpackmat
    1661             :       USE m_olap, ONLY: olap_pw
    1662             :       USE m_types_atoms
    1663             :       USE m_types_mat
    1664             :       USE m_types_sym
    1665             : 
    1666             :       IMPLICIT NONE
    1667             :       
    1668             :       TYPE(t_atoms), INTENT(IN) :: atoms
    1669             :       TYPE(t_sym), INTENT(IN)  :: sym
    1670             : 
    1671             :       ! scalar input
    1672             :       INTEGER, INTENT(IN)    :: maxlcutm, lexp
    1673             :       INTEGER, INTENT(IN)    :: nkptf, nkpti
    1674             :       INTEGER, INTENT(IN)    :: maxindxm
    1675             :       INTEGER, INTENT(IN)    :: gptmd, irank
    1676             :       INTEGER, INTENT(IN)    :: maxbasm
    1677             :       REAL, INTENT(IN)       :: vol
    1678             : 
    1679             :       ! array input
    1680             :       INTEGER, INTENT(IN)    :: lcutm(:)
    1681             :       INTEGER, INTENT(IN)    :: nindxm(0:maxlcutm, atoms%ntype)
    1682             :       INTEGER, INTENT(IN)    :: g(:,:)
    1683             :       INTEGER, INTENT(IN)    :: ngptm(:)
    1684             :       INTEGER, INTENT(IN)    :: pgptm(:,:)
    1685             :       INTEGER, INTENT(IN)    :: nbasm(:)
    1686             : 
    1687             :       REAL, INTENT(IN)       :: bk(:,:)
    1688             :       REAL, INTENT(IN)       :: basm(atoms%jmtd, maxindxm, 0:maxlcutm, atoms%ntype)
    1689             :       REAL, INTENT(IN)       :: bmat(:,:)
    1690             : 
    1691             :       !  inout
    1692             :       CLASS(t_mat), INTENT(INOUT), ALLOCATABLE :: coul(:)
    1693             :       
    1694             :       ! private scalars
    1695             :       INTEGER                :: ikpt, itype, ieq, il, im, iindxm, idum, n1, n2, ok    ! counters and other helper variables
    1696             :       INTEGER                :: noGPts, nbasp                                 ! no used g-vectors, no MT functions
    1697             : 
    1698             :       ! private arrays
    1699           0 :       INTEGER, ALLOCATABLE   :: ptrType(:), ptrEq(:), ptrL(:), ptrM(:), ptrN(:)  ! Pointer
    1700             :       REAL                   :: potential(maxNoGPts)                         ! Fourier transformed potential
    1701             :       COMPLEX                :: muffintin(maxNoGPts, maxindxm, &               ! muffin-tin overlap integral
    1702           0 :                                           (maxlcutm + 1)**2, atoms%ntype, MAXVAL(atoms%neq))
    1703           0 :       COMPLEX                :: interstitial(maxNoGPts, gptmd)                ! interstistial overlap intergral
    1704           0 :       COMPLEX, ALLOCATABLE   :: coulmat(:, :)                                 ! helper array to symmetrize coulomb
    1705             : 
    1706             :       ! Check size of arrays
    1707           0 :       nbasp = maxbasm - MAXVAL(ngptm)
    1708           0 :       IF (ANY(nbasm - ngptm /= nbasp)) call juDFT_error( 'hsefunctional: wrong assignment of nbasp')
    1709             : 
    1710             :       !
    1711             :       ! Create pointer which correlate the position in the array with the
    1712             :       ! appropriate indices of the MT mixed basis function
    1713             :       !
    1714           0 :       CALL timestart("index array for MT mixed basis function")
    1715           0 :       allocate(ptrType(nbasp), ptrEq(nbasp), ptrL(nbasp), ptrM(nbasp), ptrN(nbasp))
    1716           0 :       nbasp = 0
    1717           0 :       DO itype = 1, atoms%ntype
    1718           0 :          DO ieq = 1, atoms%neq(itype)
    1719           0 :             DO il = 0, lcutm(itype)
    1720           0 :                DO im = -il, il
    1721           0 :                   DO iindxm = 1, nindxm(il, itype)
    1722           0 :                      nbasp = nbasp + 1
    1723           0 :                      ptrType(nbasp) = itype
    1724           0 :                      ptrEq(nbasp) = ieq
    1725           0 :                      ptrL(nbasp) = il
    1726           0 :                      ptrM(nbasp) = im
    1727           0 :                      ptrN(nbasp) = iindxm
    1728             :                   END DO
    1729             :                END DO
    1730             :             END DO
    1731             :          END DO
    1732             :       END DO
    1733           0 :       CALL timestop("index array for MT mixed basis function")
    1734             : 
    1735             :       !
    1736             :       ! Change the Coulomb matrix for all k-points
    1737             :       !
    1738           0 :       CALL timestart("calc coulomb change for all k")
    1739           0 :       DO ikpt = 1, nkpti
    1740             :          ! use the same g-vectors as in the mixed basis
    1741             :          ! adjust the limit of the array if necessary
    1742           0 :          IF (ngptm(ikpt) < maxNoGPts) THEN
    1743           0 :             noGPts = ngptm(ikpt)
    1744             :          ELSE
    1745           0 :             noGPts = maxNoGPts
    1746             :          END IF
    1747             : 
    1748             :          !
    1749             :          ! Calculate the Fourier transform of the mixed basis and the potential
    1750             :          !
    1751           0 :          CALL timestart("fourier of MB and pot")
    1752             :          CALL calculate_fourier_transform( &
    1753             :             ! Input
    1754             :             atoms%rmsh, atoms%rmt, atoms%dx, atoms%jri, atoms%jmtd, bk(:, ikpt), &
    1755             :             bmat, vol, atoms%ntype, atoms%neq, atoms%nat, atoms%taual, lcutm, maxlcutm, &
    1756             :             nindxm, maxindxm, g, ngptm(ikpt), pgptm(:, ikpt), gptmd, &
    1757             :             basm, noGPts, irank, &
    1758             :             ! Output
    1759           0 :             potential, muffintin, interstitial)
    1760           0 :          interstitial = CONJG(interstitial)
    1761           0 :          CALL timestop("fourier of MB and pot")
    1762             :          ! Helper matrix for temporary storage of the attenuated Coulomb matrix
    1763           0 :          allocate(coulmat(nbasm(ikpt), nbasm(ikpt)), stat=ok)
    1764           0 :          IF (ok /= 0) call juDFT_error( 'hsefunctional: failure at matrix allocation')
    1765           0 :          coulmat = 0
    1766             :          !
    1767             :          ! Calculate the difference of the Coulomb matrix by the attenuation
    1768             :          !
    1769           0 :          CALL timestart("diff of coulomb mat by attenuation")
    1770           0 :          CALL timestart("MT - MT")
    1771           0 :          DO n1 = 1, nbasp
    1772           0 :             DO n2 = 1, n1
    1773             :                ! muffin tin - muffin tin contribution
    1774             :                coulmat(n2, n1) = -gPtsSummation(noGpts, &
    1775             :                                                 muffintin(:, ptrN(n2), (ptrL(n2) + 1)*ptrL(n2) + ptrM(n2) + 1, ptrType(n2), ptrEq(n2)), potential, &
    1776           0 :                                                 CONJG(muffintin(:, ptrN(n1), (ptrL(n1) + 1)*ptrL(n1) + ptrM(n1) + 1, ptrType(n1), ptrEq(n1))))
    1777           0 :                coulmat(n1, n2) = CONJG(coulmat(n2, n1))
    1778             :             END DO
    1779             :          END DO
    1780           0 :          CALL timestop("MT - MT")
    1781           0 :          CALL timestart("MT - IR + IR - IR")
    1782           0 :          DO n1 = nbasp + 1, nbasm(ikpt)
    1783           0 :             DO n2 = 1, n1
    1784           0 :                IF (n2 <= nbasp) THEN
    1785             :                   ! muffin tin - interstitial contribution
    1786           0 :                   CALL timestart("MT - IR")
    1787             :                   coulmat(n2, n1) = -gPtsSummation(noGPts, &
    1788             :                                                    muffintin(:, ptrN(n2), (ptrL(n2) + 1)*ptrL(n2) + ptrM(n2) + 1, ptrType(n2), ptrEq(n2)), &
    1789           0 :                                                    potential, CONJG(interstitial(:, pgptm(n1 - nbasp, ikpt))))
    1790           0 :                   coulmat(n1, n2) = CONJG(coulmat(n2, n1))
    1791           0 :                   CALL timestop("MT - IR")
    1792             :                ELSE
    1793             :                   ! interstitial - interstitial contribution
    1794           0 :                   CALL timestart("IR - IR")
    1795             :                   coulmat(n2, n1) = -gPtsSummation(noGPts, &
    1796             :                                                    interstitial(:, pgptm(n2 - nbasp, ikpt)), potential, &
    1797           0 :                                                    CONJG(interstitial(:, pgptm(n1 - nbasp, ikpt))))
    1798           0 :                   coulmat(n1, n2) = CONJG(coulmat(n2, n1))
    1799           0 :                   CALL timestop("IR - IR")
    1800             :                END IF
    1801             :             END DO
    1802             :          END DO
    1803           0 :          CALL timestop("MT - IR + IR - IR")
    1804           0 :          CALL timestop("diff of coulomb mat by attenuation")
    1805             : 
    1806           0 :          CALL timestart("symmetrize if inversion symmetric")
    1807           0 :          IF (sym%invs) THEN
    1808             :             ! symmetrize matrix if system has inversion symmetry
    1809             :             CALL symmetrize(coulmat, nbasm(ikpt), nbasm(ikpt), 3, &
    1810             :                          atoms, lcutm, maxlcutm, &
    1811           0 :                          nindxm, sym)
    1812             :          ENDIF
    1813           0 :          CALL timestop("symmetrize if inversion symmetric")
    1814             :          ! add the changes to the Coulomb matrix
    1815           0 :          coul(ikpt)%data_c = coulmat + coul(ikpt)%data_c
    1816             : 
    1817           0 :          deallocate(coulmat)
    1818             : 
    1819             :       END DO
    1820           0 :       CALL timestop("calc coulomb change for all k")
    1821             : 
    1822           0 :       deallocate(ptrType, ptrEq, ptrL, ptrM, ptrN)
    1823             : 
    1824           0 :    END SUBROUTINE change_coulombmatrix
    1825             : 
    1826             :    ! Correct the pure Coulomb Matrix with by subtracting the long-range component
    1827             :    ! during execution time
    1828             :    !
    1829             :    !  /     |      |      \     /     |       |      \     /     |     |      \
    1830             :    ! ( M    | V    | M     ) = ( M    | V     | M     ) - ( M    | V   | M     )
    1831             :    !  \ k,I |  HSE |  k,J /     \ k,I |  coul |  k,J /     \ k,I |  LR |  k,J /
    1832             :    !
    1833             :    ! The long-range component is given py the potential
    1834             :    !
    1835             :    !         erf( w r )
    1836             :    ! V (r) = ----------
    1837             :    !  LR         r
    1838             :    !
    1839             :    ! Input:
    1840             :    ! rmsh     - array of radial mesh points
    1841             :    ! rmt      - radius of the muffin tin
    1842             :    ! dx       - logarithmic increment of radial mesh
    1843             :    ! jri      - number of radial mesh points
    1844             :    ! jmtd     - dimension of radial mesh points
    1845             :    ! bk       - k-vector for this k-point
    1846             :    ! ikpt     - number of this k-point
    1847             :    ! nkptf    - number of total k-points
    1848             :    ! bmat     - reciprocal lattice vector for all directions
    1849             :    ! vol      - volume of unit cell
    1850             :    ! ntype    - number of atom types
    1851             :    ! neq      - number of symmetry-equivalent atoms of atom type i
    1852             :    ! natd     - dimension of atoms in unit cell
    1853             :    ! taual    - vector of atom positions (internal coordinates)
    1854             :    ! lcutm    - l cutoff for mixed basis
    1855             :    ! maxlcutm - maximum of all these l cutoffs
    1856             :    ! nindxm   - number of radial functions of mixed basis
    1857             :    ! maxindxm - maximum of these numbers
    1858             :    ! g     - reciprocal lattice vectors of the mixed basis (internal coord.)
    1859             :    ! ngptm    - number of vectors
    1860             :    ! pgptm    - pointer to the appropriate g-vector
    1861             :    ! gptmd    - dimension of g
    1862             :    ! basm     - radial mixed basis functions (mt + inter)
    1863             :    ! nbasm    - number of mixed basis function
    1864             :    ! nobd     - dimension of occupied bands
    1865             :    ! nbands   - number of bands
    1866             :    ! nsst     - size of indx
    1867             :    ! indx     - pointer to bands
    1868             :    ! invsat   - number of inversion-symmetric atom
    1869             :    ! invsatnr - number of inversion-symmetric atom
    1870             :    ! cprod    - scalar product of mixed basis and wavefunction product basis
    1871             :    ! wl_iks   -
    1872             :    ! n_q      -
    1873             :    ! Return:
    1874             :    ! Change of the Coulomb matrix
    1875           0 :    FUNCTION dynamic_hse_adjustment( &
    1876           0 :       atoms, bk, ikpt, nkptf, bmat, vol, &
    1877           0 :       lcutm, maxlcutm, nindxm, maxindxm, &
    1878           0 :       g, ngptm, pgptm, gptmd, basm, nbasm, &
    1879           0 :       nobd, nbands, nsst, ibando, psize, indx, sym, irank, &
    1880           0 :       cprod_r, cprod_c, l_real, wl_iks, n_q)
    1881             : 
    1882             :       USE m_trafo, ONLY: symmetrize
    1883             :       USE m_olap, ONLY: olap_pw, olap_pwp
    1884             :       USE m_wrapper, ONLY: packmat
    1885             :       USE m_types_atoms
    1886             :       USE m_types_sym
    1887             : 
    1888             :       IMPLICIT NONE
    1889             : 
    1890             :       TYPE(t_atoms), INTENT(IN) :: atoms
    1891             :       TYPE(t_sym), INTENT(IN)   :: sym
    1892             : 
    1893             :       ! scalar input
    1894             :       INTEGER, INTENT(IN)  :: maxlcutm
    1895             :       INTEGER, INTENT(IN)  :: ikpt, nkptf
    1896             :       INTEGER, INTENT(IN)  :: maxindxm
    1897             :       INTEGER, INTENT(IN)  :: gptmd, irank
    1898             :       INTEGER, INTENT(IN)  :: nbasm, nobd, nbands, ibando, psize
    1899             :       INTEGER, INTENT(IN)  :: n_q
    1900             :       REAL, INTENT(IN)     :: vol
    1901             : 
    1902             :       ! array input
    1903             :       INTEGER, INTENT(IN)  :: lcutm(:)
    1904             :       INTEGER, INTENT(IN)  :: nindxm(0:maxlcutm, atoms%ntype)
    1905             :       INTEGER, INTENT(IN)  :: g(:,:)
    1906             :       INTEGER, INTENT(IN)  :: ngptm
    1907             :       INTEGER, INTENT(IN)  :: pgptm(:)
    1908             :       INTEGER, INTENT(IN)  :: nsst(:), indx(:,:)
    1909             :       REAL, INTENT(IN)     :: bk(:)
    1910             :       REAL, INTENT(IN)     :: basm(atoms%jmtd, maxindxm, 0:maxlcutm, atoms%ntype)
    1911             :       REAL, INTENT(IN)     :: bmat(:,:)
    1912             :       REAL, INTENT(IN)     :: wl_iks(:)
    1913             :       REAL, INTENT(IN)     :: cprod_r(:,:)
    1914             :       COMPLEX, INTENT(IN)  :: cprod_c(:,:)
    1915             :       LOGICAL, INTENT(IN)   :: l_real
    1916             : 
    1917             :       ! return type definition
    1918             :       COMPLEX              :: dynamic_hse_adjustment(nbands, nbands)
    1919             : 
    1920             :       ! private scalars
    1921             :       INTEGER              :: noGpts, nbasp
    1922             :       INTEGER              :: itype, ieq, il, im, iindxm, ibasp
    1923             :       INTEGER              :: igpt, iobd, iobd0, isst, iband1, iband2
    1924             :       COMPLEX              :: cdum, gPtsSum
    1925             : 
    1926             :       ! private arrays
    1927             :       INTEGER, ALLOCATABLE :: ptrType(:), ptrEq(:), ptrL(:), ptrM(:), ptrN(:) ! pointer to reference muffintin-array
    1928             :       REAL                 :: potential(maxNoGPts)                        ! Fourier transformed potential
    1929             :       COMPLEX              :: muffintin(maxNoGPts, maxindxm, &              ! muffin-tin overlap integral
    1930             :                                         (maxlcutm + 1)**2, atoms%ntype, MAXVAL(atoms%neq))
    1931             :       COMPLEX              :: interstitial(maxNoGPts, gptmd)               ! interstistial overlap intergral
    1932             : #ifdef CPP_INVERSION
    1933             :       REAL                 :: fourier_trafo(nbasm - ngptm, maxNoGPts)        ! Fourier trafo of all mixed basis functions
    1934             : #else
    1935           0 :       COMPLEX              :: fourier_trafo(nbasm - ngptm, maxNoGPts)        ! Fourier trafo of all mixed basis functions
    1936             : #endif
    1937             : 
    1938           0 :       REAL                 :: cprod_fourier_trafo_r(maxNoGpts, psize, nbands)  ! Product of cprod and Fourier trafo
    1939           0 :       COMPLEX              :: cprod_fourier_trafo_c(maxNoGpts, psize, nbands)  ! Product of cprod and Fourier trafo
    1940             : 
    1941             :       ! Initialisation
    1942           0 :       dynamic_hse_adjustment = 0.0
    1943           0 :       potential = 0.0
    1944           0 :       fourier_trafo = 0.0
    1945           0 :       cprod_fourier_trafo_r = 0.0
    1946           0 :       cprod_fourier_trafo_c = 0.0
    1947           0 :       noGPts = MIN(ngptm, maxNoGPts)
    1948           0 :       nbasp = nbasm - ngptm
    1949             : 
    1950             :       !
    1951             :       ! Calculate the fourier transform of the mixed basis once
    1952             :       ! If it was already calculated load the old results
    1953             :       !
    1954             :       CALL calculate_fourier_transform_once( &
    1955             :          atoms, bk, ikpt, nkptf, &
    1956             :          bmat, vol, lcutm, maxlcutm, &
    1957             :          nindxm, maxindxm, g, ngptm, pgptm, gptmd, &
    1958             :          nbasp, basm, noGPts, sym, irank, &
    1959           0 :          potential, fourier_trafo)
    1960             : 
    1961             :       ! Calculate the Fourier transform of the 'normal' basis
    1962             :       ! by summing over the mixed basis
    1963           0 :       DO igpt = 1, noGPts
    1964           0 :          DO iobd0 = 1, psize!ibando,min(ibando+psize,nobd)
    1965           0 :             iobd = iobd0 + ibando - 1
    1966           0 :             IF (iobd > nobd) CYCLE
    1967           0 :             DO iband1 = 1, nbands
    1968           0 :                if (l_real) THEN
    1969             :                   cprod_fourier_trafo_r(igpt, iobd0, iband1) = &
    1970             :                      ! muffin tin contribution
    1971             :                      dot_product(fourier_trafo(:nbasp, igpt), cprod_r(:nbasp, iobd0 + psize * (iband1 - 1))) &
    1972             :                      ! interstitial contribution (interstitial is kronecker_G,G')
    1973           0 :                      + cprod_r(nbasp + igpt, iobd0 + psize * (iband1 - 1))
    1974             :                else
    1975             :                   cprod_fourier_trafo_c(igpt, iobd0, iband1) = &
    1976             :                      ! muffin tin contribution
    1977             :                      dot_product(cprod_c(:nbasp, iobd0 + psize * (iband1 - 1)), fourier_trafo(:nbasp, igpt)) &
    1978             :                      ! interstitial contribution (interstitial is kronecker_G,G')
    1979           0 :                      + CONJG(cprod_c(nbasp + igpt, iobd0 + psize *(iband1 - 1)))
    1980             :                endif
    1981             :             END DO
    1982             :          END DO
    1983             :       END DO
    1984             : 
    1985             :       ! Summation over all G-vectors
    1986           0 :       DO iband1 = 1, nbands
    1987           0 :          DO iobd0 = 1, psize!ibando,min(ibando+psize,nobd)
    1988           0 :             iobd = iobd0 + ibando - 1
    1989           0 :             IF (iobd > nobd) CYCLE
    1990             :             ! prefactor for all elements
    1991           0 :             cdum = wl_iks(iobd)/n_q
    1992           0 :             DO isst = 1, nsst(iband1)
    1993           0 :                iband2 = indx(isst, iband1)
    1994             :                ! do summation over G-vectors
    1995           0 :                if (l_real) THEN
    1996             :                   gPtsSum = cdum*gPtsSummation(noGPts, &
    1997             :                                                cprod_fourier_trafo_r(:, iobd0, iband1), &
    1998           0 :                                                potential, cprod_fourier_trafo_r(:, iobd0, iband2))
    1999             :                ELSE
    2000             :                   gPtsSum = cdum*gPtsSummation(noGPts, &
    2001             :                                                conjg(cprod_fourier_trafo_c(:, iobd0, iband1)), &
    2002           0 :                                                potential, cprod_fourier_trafo_c(:, iobd0, iband2))
    2003             :                endif
    2004             :                dynamic_hse_adjustment(iband2, iband1) = &
    2005           0 :                   dynamic_hse_adjustment(iband2, iband1) - gPtsSum
    2006             :             END DO
    2007             :          END DO
    2008             :       END DO
    2009             : 
    2010             :    END FUNCTION dynamic_hse_adjustment
    2011             : 
    2012             :    ! Helper function needed to use forall statements instead of do loop's
    2013             :    ! calls the harmonicsr subroutine from 'util.F'
    2014           0 :    PURE FUNCTION calcYlm(rvec, ll)
    2015             :       USE m_util, ONLY: harmonicsr
    2016             :       IMPLICIT NONE
    2017             :       REAL, INTENT(IN)    :: rvec(:)
    2018             :       INTEGER, INTENT(IN) :: ll
    2019             :       COMPLEX             :: calcYlm((ll + 1)**2)
    2020           0 :       CALL harmonicsr(calcYlm, rvec, ll)
    2021             :    END FUNCTION calcYlm
    2022             : 
    2023             :    ! Helper function needed to use forall statements instead of do loop's
    2024             :    ! calls the sphbessel subroutine from 'util.F'
    2025           0 :    PURE FUNCTION calcSphBes(x, l)
    2026             :       USE m_util, ONLY: sphbessel
    2027             :       IMPLICIT NONE
    2028             :       REAL, INTENT(IN)    :: x
    2029             :       INTEGER, INTENT(IN) :: l
    2030             :       REAL                :: calcSphBes(0:l)
    2031           0 :       CALL sphbessel(calcSphBes, x, l)
    2032             :    END FUNCTION calcSphBes
    2033             : 
    2034             :    ! Dot_product definition for two arrays (3d x 1d) with common size of first dimension
    2035           0 :    PURE FUNCTION my_dot_product3x1(first, second)
    2036             :       IMPLICIT NONE
    2037             :       INTEGER, INTENT(IN) :: first(:, :, :)
    2038             :       REAL, INTENT(IN)    :: second(:)
    2039             :       REAL                :: my_dot_product3x1(SIZE(first, 2), SIZE(first, 3))
    2040             :       INTEGER             :: ci, cj
    2041             : 
    2042           0 :       FORALL (ci=1:SIZE(first, 2), cj=1:SIZE(first, 3))
    2043             :       my_dot_product3x1(ci, cj) = DOT_PRODUCT(first(:, ci, cj), second)
    2044             :       END FORALL
    2045             :    END FUNCTION my_dot_product3x1
    2046             : 
    2047             :    ! Dot_product definition for two arrays (4d x 1d) with common size of first dimension
    2048           0 :    PURE FUNCTION my_dot_product4x1(first, second)
    2049             :       IMPLICIT NONE
    2050             :       INTEGER, INTENT(IN) :: first(:, :, :, :)
    2051             :       REAL, INTENT(IN)    :: second(:)
    2052             :       REAL                :: my_dot_product4x1(SIZE(first, 2), SIZE(first, 3), SIZE(first, 4))
    2053             :       INTEGER             :: ci, cj, ck
    2054             : 
    2055           0 :       FORALL (ci=1:SIZE(first, 2), cj=1:SIZE(first, 3), ck=1:SIZE(first, 4))
    2056             :       my_dot_product4x1(ci, cj, ck) = DOT_PRODUCT(first(:, ci, cj, ck), second)
    2057             :       END FORALL
    2058             :    END FUNCTION my_dot_product4x1
    2059             : 
    2060             :    ! Dot_product definition for two arrays (3d x 3d) with common size of all dimensions,
    2061             :    ! The scalar product is evaluated over the last index
    2062           0 :    PURE FUNCTION my_dot_product3x3(first, second)
    2063             :       IMPLICIT NONE
    2064             :       COMPLEX, INTENT(IN) :: first(:, :, :)
    2065             :       REAL, INTENT(IN) :: second(:,:,:)
    2066             :       COMPLEX             :: my_dot_product3x3(SIZE(first, 1), SIZE(first, 2))
    2067             :       INTEGER             :: ci, cj
    2068             : 
    2069           0 :       FORALL (ci=1:SIZE(first, 1), cj=1:SIZE(first, 2))
    2070             :       my_dot_product3x3(ci, cj) = DOT_PRODUCT(first(ci, cj, :), second(ci, cj, :))
    2071             :       END FORALL
    2072             :    END FUNCTION my_dot_product3x3
    2073             : 
    2074             :    ! Dot_product definition for two arrays (4d x 4d) with common size of all dimensions,
    2075             :    ! The scalar product is evaluated over the last index
    2076           0 :    PURE FUNCTION my_dot_product4x4(first, second)
    2077             :       IMPLICIT NONE
    2078             :       COMPLEX, INTENT(IN) :: first(:, :, :, :)
    2079             :       REAL, INTENT(IN) :: second(:,:,:,:)
    2080             :       COMPLEX             :: my_dot_product4x4(SIZE(first, 1), SIZE(first, 2), SIZE(first, 3))
    2081             :       INTEGER             :: ci, cj, ck
    2082             : 
    2083           0 :       FORALL (ci=1:SIZE(first, 1), cj=1:SIZE(first, 2), ck=1:SIZE(first, 3))
    2084             :       my_dot_product4x4(ci, cj, ck) = DOT_PRODUCT(first(ci, cj, ck, :), second(ci, cj, ck, :))
    2085             :       END FORALL
    2086             :    END FUNCTION my_dot_product4x4
    2087             : 
    2088             :    ! Sum over last index of 4d array
    2089           0 :    PURE FUNCTION my_sum3d(array)
    2090             :       IMPLICIT NONE
    2091             :       COMPLEX, INTENT(IN) :: array(:, :, :)
    2092             :       COMPLEX             :: my_sum3d(SIZE(array, 1), SIZE(array, 2))
    2093             :       INTEGER             :: ci, cj
    2094             : 
    2095           0 :       FORALL (ci=1:SIZE(array, 1), cj=1:SIZE(array, 2))
    2096             :       my_sum3d(ci, cj) = SUM(array(ci, cj, :))
    2097             :       END FORALL
    2098             :    END FUNCTION my_sum3d
    2099             : 
    2100             :    ! Sum over last index of 4d array
    2101           0 :    PURE FUNCTION my_sum4d(array)
    2102             :       IMPLICIT NONE
    2103             :       COMPLEX, INTENT(IN) :: array(:, :, :, :)
    2104             :       COMPLEX             :: my_sum4d(SIZE(array, 1), SIZE(array, 2), SIZE(array, 3))
    2105             :       INTEGER             :: ci, cj, ck
    2106             : 
    2107           0 :       FORALL (ci=1:SIZE(array, 1), cj=1:SIZE(array, 2), ck=1:SIZE(array, 3))
    2108             :       my_sum4d(ci, cj, ck) = SUM(array(ci, cj, ck, :))
    2109             :       END FORALL
    2110             :    END FUNCTION my_sum4d
    2111             : 
    2112             :    ! Sum product of three vectors
    2113           0 :    COMPLEX PURE FUNCTION crc_gPtsSummation(noGpts, vec1, vec2, vec3)
    2114             :       IMPLICIT NONE
    2115             :       INTEGER, INTENT(IN) :: noGPts
    2116             :       COMPLEX, INTENT(IN) :: vec1(:)
    2117             :       REAL, INTENT(IN)    :: vec2(:)
    2118             :       COMPLEX, INTENT(IN) :: vec3(:)
    2119           0 :       COMPLEX             :: temp(noGPts)
    2120           0 :       temp = vec1*vec3
    2121           0 :       crc_gPtsSummation = DOT_PRODUCT(temp, vec2)
    2122           0 :    END FUNCTION crc_gPtsSummation
    2123           0 :    REAL PURE FUNCTION rrr_gPtsSummation(noGpts, vec1, vec2, vec3)
    2124             :       IMPLICIT NONE
    2125             :       INTEGER, INTENT(IN) :: noGPts
    2126             :       REAL, INTENT(IN)    :: vec1(:)
    2127             :       REAL, INTENT(IN)    :: vec2(:)
    2128             :       REAL, INTENT(IN)    :: vec3(:)
    2129           0 :       REAL                :: temp(noGPts)
    2130           0 :       temp = vec1*vec3
    2131           0 :       rrr_gPtsSummation = DOT_PRODUCT(temp, vec2)
    2132           0 :    END FUNCTION rrr_gPtsSummation
    2133             : 
    2134             :    ! Include the core valence exchange for the HSE functional
    2135             :    ! The HSE potential is the Coulomb one attenuated with the complementary
    2136             :    ! error function which can be expanded in Legendre polynomials (r' > r)
    2137             :    !
    2138             :    !                      -----                l+2n
    2139             :    ! erfc( w |r - r'| )    \                  r           /         \
    2140             :    ! ------------------ =   )    d  (w r')  ---------  P ( cos(r,r') )
    2141             :    !    | r - r' |         /      ln          l+2n+1    l \         /
    2142             :    !                      -----              r'
    2143             :    !                       l,n
    2144             :    !
    2145             :    ! Then an analytical integration of the angular part of the exchange
    2146             :    ! potential is possible and only the radial part remains
    2147             :    !
    2148             :    !          R                        r                              R
    2149             :    !           /   -----  /  d (w r)    /                              /           d  (w r')  \
    2150             :    !  4 Pi    |     \    |    ln       |            l+2n+2      l+2n  |             ln         |
    2151             :    ! -------  | dr   )   |  ---------  | dr' f(r') r'       +  r      | dr' f(r') -----------  |
    2152             :    ! 2 l + 1  |     /    |    l+2n+1   |                              |              l+2n-1    |
    2153             :    !         /     -----  \  r        /                              /              r'        /
    2154             :    !          0      n                 0                              r
    2155             :    !
    2156             :    ! The function f is a product of core and valence function
    2157             :    ! (note: in the code f is defined with an additional 1/r factor)
    2158             :    !
    2159           0 :    SUBROUTINE exchange_vccvHSE(nk, fi, mpdata, hybdat, jsp, lapw, nsymop, &
    2160           0 :                                nsest, indx_sest, irank, a_ex, results, cmt, mat_ex)
    2161             : 
    2162             :       USE m_types_fleurinput
    2163             :       USE m_types_mpdata
    2164             :       USE m_types_hybdat
    2165             :       USE m_types_lapw
    2166             :       USE m_types_misc
    2167             :       USE m_types_mat
    2168             : 
    2169             :       USE m_constants
    2170             :       USE m_util
    2171             :       USE m_intgrf
    2172             :       USE m_wrapper
    2173             : 
    2174             :       IMPLICIT NONE
    2175             : 
    2176             :       TYPE(t_fleurinput), INTENT(IN) :: fi
    2177             :       TYPE(t_mpdata), INTENT(IN)     :: mpdata
    2178             :       TYPE(t_hybdat), INTENT(IN)     :: hybdat
    2179             :       TYPE(t_lapw), INTENT(IN)       :: lapw
    2180             :       TYPE(t_results), INTENT(INOUT) :: results
    2181             :       TYPE(t_mat), INTENT(INOUT)     :: mat_ex
    2182             : 
    2183             : !   -scalars -
    2184             :       INTEGER, INTENT(IN)      ::  nk, nsymop, jsp
    2185             :       INTEGER, INTENT(IN)      ::  irank
    2186             :       REAL, INTENT(IN)         ::  a_ex
    2187             : 
    2188             : !   - arrays -
    2189             :       INTEGER, INTENT(IN)      ::  nsest(:), indx_sest(:,:)
    2190             :       COMPLEX, INTENT(IN)      ::  cmt(:, :, :)
    2191             : 
    2192             : !   - local scalars -
    2193             :       INTEGER, PARAMETER      ::  ncut = 5                  ! cut-off value of n-summation
    2194             :       INTEGER                 ::  cn                        ! counter for n-summation
    2195           0 :       REAL                    ::  d_ln(fi%atoms%jmtd, 0:fi%atoms%lmaxd, 0:ncut) ! expansion coefficients of erfc(wr)/r
    2196             :       ! in Legendre polynomials
    2197             : 
    2198             :       INTEGER                 ::  iatom, ieq, itype, ic, l, l1, l2, &
    2199             :                                  ll, lm, m, m1, m2, p1, p2, n, n1, n2, nn2, i, j
    2200             :       INTEGER                 ::  iband1, iband2, ndb1, ndb2, ic1, ic2
    2201             :       REAL                    ::  rdum
    2202             :       COMPLEX                 ::  cdum
    2203             : 
    2204             : !   - local arrays -
    2205           0 :       INTEGER, ALLOCATABLE     ::  larr(:), larr2(:)
    2206           0 :       INTEGER, ALLOCATABLE     ::  parr(:), parr2(:)
    2207             : 
    2208           0 :       REAL                    ::  sum_primf(fi%atoms%jmtd), integrand(fi%atoms%jmtd)
    2209           0 :       REAL                    ::  primf1(fi%atoms%jmtd), primf2(fi%atoms%jmtd)
    2210           0 :       REAL, ALLOCATABLE        ::  fprod(:, :), fprod2(:, :)
    2211           0 :       REAL, ALLOCATABLE        ::  integral(:, :)
    2212             : 
    2213           0 :       COMPLEX                 ::  exchange(hybdat%nbands(nk,jsp), hybdat%nbands(nk,jsp))
    2214           0 :       COMPLEX, ALLOCATABLE     ::  carr(:, :), carr2(:, :), carr3(:, :)
    2215             : 
    2216             :       LOGICAL                 ::  ldum(hybdat%nbands(nk,jsp), hybdat%nbands(nk,jsp))
    2217             : 
    2218             :       ! check if a_ex is consistent
    2219             : !     IF ( a_ex /= aMix_HSE ) st--op 'hsefunctional: inconsistent mixing!'
    2220             : 
    2221             :       ! print out screening parameter
    2222           0 :       WRITE (*,*) 'Screening parameter: ', omega_HSE
    2223             : 
    2224           0 :       allocate(fprod(fi%atoms%jmtd, 5), larr(5), parr(5))
    2225             : 
    2226           0 :       exchange = 0
    2227           0 :       iatom = 0
    2228           0 :       rdum = 0
    2229           0 :       DO itype = 1, fi%atoms%ntype
    2230             :          ! Calculate the expansion coefficients of the potential in Legendre polynomials
    2231           0 :          CALL timestart("calc legendre polys")
    2232           0 :          d_ln(:, :fi%hybinp%lcutm1(itype), :) = calculate_coefficients(fi%atoms%rmsh(:, itype), fi%hybinp%lcutm1(itype), ncut, hybdat%fac)
    2233           0 :          CALL timestop("calc legendre polys")
    2234           0 :          CALL timestart("core-valence prod + integration")
    2235           0 :          DO ieq = 1, fi%atoms%neq(itype)
    2236           0 :             iatom = iatom + 1
    2237           0 :             DO l1 = 0, hybdat%lmaxc(itype)
    2238           0 :                DO p1 = 1, hybdat%nindxc(l1, itype)
    2239             : 
    2240           0 :                   DO l = 0, fi%hybinp%lcutm1(itype)
    2241             :                      
    2242             :                      ! Define core-valence product functions
    2243           0 :                      CALL timestart("core-valence prod")
    2244             : 
    2245           0 :                      n = 0
    2246           0 :                      DO l2 = 0, fi%atoms%lmax(itype)
    2247           0 :                         IF (l < ABS(l1 - l2) .OR. l > l1 + l2) CYCLE
    2248             : 
    2249           0 :                         DO p2 = 1, mpdata%num_radfun_per_l(l2, itype)
    2250           0 :                            n = n + 1
    2251           0 :                            m = SIZE(fprod, 2)
    2252           0 :                            IF (n > m) THEN
    2253           0 :                               allocate(fprod2(fi%atoms%jmtd, m), larr2(m), parr2(m))
    2254           0 :                               fprod2 = fprod; larr2 = larr; parr2 = parr
    2255           0 :                               deallocate(fprod, larr, parr)
    2256           0 :                               allocate(fprod(fi%atoms%jmtd, m + 5), larr(m + 5), parr(m + 5))
    2257           0 :                               fprod(:, :m) = fprod2
    2258           0 :                               larr(:m) = larr2
    2259           0 :                               parr(:m) = parr2
    2260           0 :                               deallocate(fprod2, larr2, parr2)
    2261             :                            END IF
    2262             :                            fprod(:, n) = (hybdat%core1(:, p1, l1, itype) &
    2263             :                                           *hybdat%bas1(:, p2, l2, itype) &
    2264             :                                           + hybdat%core2(:, p1, l1, itype) &
    2265           0 :                                           *hybdat%bas2(:, p2, l2, itype))/fi%atoms%rmsh(:, itype)
    2266           0 :                            larr(n) = l2
    2267           0 :                            parr(n) = p2
    2268             :                         END DO
    2269             :                      END DO
    2270             :                       
    2271           0 :                      CALL timestop("core-valence prod")
    2272             :                      ! Evaluate radial integrals (special part of Coulomb matrix : contribution from single MT)
    2273           0 :                      CALL timestart("radial integration of single MT")
    2274             : 
    2275           0 :                      allocate(integral(n, n), carr(n, hybdat%nbands(nk,jsp)), &
    2276           0 :                                carr2(n, lapw%nv(jsp)), carr3(n, lapw%nv(jsp)))
    2277             : 
    2278           0 :                      DO i = 1, n
    2279             :                         ! Initialization of n Summation
    2280           0 :                         sum_primf = 0.0
    2281             :                         ! Integration over r'
    2282           0 :                         DO cn = 0, ncut ! Summation over Legendre polynomials
    2283           0 :                            primf1 = 0.0
    2284           0 :                            primf2 = 0.0
    2285             :                            ! Calculate integral for 0 < r' < r
    2286             :                            CALL primitivef(primf1, fprod(:, i)*fi%atoms%rmsh(:, itype)**(l + 2*cn + 1), &
    2287           0 :                                            fi%atoms%rmsh, fi%atoms%dx, fi%atoms%jri, fi%atoms%jmtd, itype, fi%atoms%ntype)
    2288             :                            ! Calculate integral for r < r' < R
    2289             :                            CALL primitivef(primf2, d_ln(:, l, cn)*fprod(:, i)/fi%atoms%rmsh(:, itype)**(l + 2*cn), &
    2290           0 :                                            fi%atoms%rmsh, fi%atoms%dx, fi%atoms%jri, fi%atoms%jmtd, -itype, fi%atoms%ntype)  ! -itype is to enforce inward integration
    2291             :                            ! Multiplication with appropriate prefactors
    2292           0 :                            primf1 = primf1/fi%atoms%rmsh(:, itype)**(l + 2*cn)*d_ln(:, l, cn)
    2293           0 :                            primf2 = primf2*fi%atoms%rmsh(:, itype)**(l + 2*cn + 1)
    2294             :                            ! Summation over n
    2295           0 :                            sum_primf = sum_primf + primf1 + primf2
    2296             :                         END DO
    2297           0 :                         DO j = 1, n
    2298             :                            ! Integration over r
    2299           0 :                            integrand = fprod(:, j)*sum_primf
    2300           0 :                            integral(i, j) = fpi_const/(2*l + 1) * intgrf(integrand, fi%atoms, itype, hybdat%gridf)
    2301             :                         END DO
    2302             : 
    2303             :                      END DO
    2304           0 :                      CALL timestop("radial integration of single MT")
    2305             :                      ! Add everything up
    2306           0 :                      CALL timestart("add to exchange")
    2307           0 :                      DO m1 = -l1, l1
    2308           0 :                         DO m = -l, l
    2309           0 :                            m2 = m1 + m
    2310             : 
    2311           0 :                            carr = 0
    2312           0 :                            ic = 0
    2313           0 :                            DO n1 = 1, hybdat%nbands(nk,jsp)
    2314             : 
    2315           0 :                               DO i = 1, n
    2316           0 :                                  ll = larr(i)
    2317           0 :                                  IF (ABS(m2) > ll) CYCLE
    2318             : 
    2319             :                                  lm = SUM([((2*l2 + 1)*mpdata%num_radfun_per_l(l2, itype), l2=0, ll - 1)]) &
    2320           0 :                                       + (m2 + ll)*mpdata%num_radfun_per_l(ll, itype) + parr(i)
    2321             : 
    2322             :                                  carr(i, n1) = cmt(n1, lm, iatom) &
    2323           0 :                                                *gaunt(l1, ll, l, m1, m2, m, hybdat%maxfac, hybdat%fac, hybdat%sfac)
    2324             : 
    2325             :                               END DO
    2326           0 :                               DO n2 = 1, nsest(n1)!n1
    2327           0 :                                  nn2 = indx_sest(n2, n1)
    2328             :                                  exchange(nn2, n1) = exchange(nn2, n1) &
    2329           0 :                                                      + DOT_PRODUCT(carr(:, n1), MATMUL(integral, carr(:, nn2)))
    2330             :                               END DO
    2331             :                            END DO
    2332             :                         END DO
    2333             :                      END DO
    2334           0 :                      deallocate(integral, carr, carr2, carr3)
    2335           0 :                      CALL timestop("add to exchange")
    2336             : 
    2337             :                   END DO
    2338             :                END DO
    2339             :             END DO
    2340             :          END DO
    2341           0 :          CALL timestop("core-valence prod + integration")
    2342             :       END DO
    2343             : 
    2344           0 :       IF (fi%sym%invs) THEN
    2345           0 :          IF (ANY(ABS(aimag(exchange)) > 10.0**(-10))) THEN
    2346           0 :             IF (irank == 0) WRITE (oUnit, '(A)') 'exchangeCore: Warning Unusually large imaginary component.'
    2347           0 :             WRITE (*, *) MAXVAL(ABS(aimag(exchange)))
    2348           0 :             call juDFT_error( 'exchangeCore: Unusually large imaginary component.')
    2349             :          END IF
    2350             :       ENDIF
    2351             : 
    2352           0 :       DO n1 = 1, hybdat%nobd(nk,jsp)
    2353           0 :          results%te_hfex%core =results%te_hfex%core - a_ex*results%w_iks(n1, nk, jsp)*exchange(n1, n1)
    2354             :       END DO
    2355             : 
    2356             :       ! add the core-valence contribution to the exchange matrix mat_ex
    2357             : 
    2358           0 :       IF (mat_ex%l_real) THEN
    2359           0 :          mat_ex%data_r = mat_ex%data_r + exchange/nsymop
    2360             :       ELSE
    2361           0 :          mat_ex%data_c = mat_ex%data_c + CONJG(exchange)/nsymop
    2362             :       END IF
    2363             : 
    2364           0 :    END SUBROUTINE exchange_vccvHSE
    2365             : 
    2366             :    ! Include the core core exchange for the HSE functional
    2367             :    ! The HSE potential is the Coulomb one attenuated with the complementary
    2368             :    ! error function which can be expanded in Legendre polynomials (r' > r)
    2369             :    !
    2370             :    !                      -----                l+2n
    2371             :    ! erfc( w |r - r'| )    \                  r           /         \
    2372             :    ! ------------------ =   )    d  (w r')  ---------  P ( cos(r,r') )
    2373             :    !    | r - r' |         /      ln          l+2n+1    l \         /
    2374             :    !                      -----              r'
    2375             :    !                       l,n
    2376             :    !
    2377             :    ! Then an analytical integration of the angular part of the exchange
    2378             :    ! potential is possible and only the radial part remains
    2379             :    !
    2380             :    !          R                        r                              R
    2381             :    !           /   -----  /  d (w r)    /                              /           d  (w r')  \
    2382             :    !  4 Pi    |     \    |    ln       |            l+2n+2      l+2n  |             ln         |
    2383             :    ! -------  | dr   )   |  ---------  | dr' f(r') r'       +  r      | dr' f(r') -----------  |
    2384             :    ! 2 l + 1  |     /    |    l+2n+1   |                              |              l+2n-1    |
    2385             :    !         /     -----  \  r        /                              /              r'        /
    2386             :    !          0      n                 0                              r
    2387             :    !
    2388             :    ! The function f is a product of core and valence function
    2389             :    ! (note: in the code f is defined with an additional 1/r factor)
    2390             :    !
    2391           0 :    SUBROUTINE exchange_ccccHSE(nk, fi, hybdat, ncstd, a_ex, results)
    2392             : 
    2393             :       USE m_types_fleurinput
    2394             :       USE m_types_hybdat
    2395             :       USE m_types_misc
    2396             : 
    2397             :       USE m_constants
    2398             :       USE m_util
    2399             :       use m_intgrf
    2400             :       USE m_wrapper
    2401             :       USE m_gaunt
    2402             :       USE m_trafo
    2403             : 
    2404             :       IMPLICIT NONE
    2405             :       
    2406             :       TYPE(t_fleurinput), INTENT(IN) :: fi
    2407             :       TYPE(t_hybdat), INTENT(IN)     :: hybdat
    2408             :       TYPE(t_results), INTENT(INOUT) :: results
    2409             :       ! - scalars -
    2410             :       INTEGER, INTENT(IN)    ::  nk, ncstd
    2411             : 
    2412             :       REAL, INTENT(IN)    ::  a_ex
    2413             : 
    2414             :       ! - local scalars -
    2415             :       INTEGER               ::  itype, ieq, icst, icst1, icst2, iatom, iatom0
    2416             :       INTEGER               ::  l1, l2, l, ll, llmax
    2417             :       INTEGER               ::  m1, m2, m, mm
    2418             :       INTEGER               ::  n1, n2, n
    2419             : 
    2420             :       REAL                  ::  rdum, rdum1
    2421             :       ! - local arrays -
    2422           0 :       INTEGER               ::  point(hybdat%maxindxc, -hybdat%lmaxcd:hybdat%lmaxcd, 0:hybdat%lmaxcd, fi%atoms%nat)
    2423           0 :       REAL                  ::  rprod(fi%atoms%jmtd), primf1(fi%atoms%jmtd), primf2(fi%atoms%jmtd), sum_primf(fi%atoms%jmtd), integrand(fi%atoms%jmtd)
    2424           0 :       COMPLEX               ::  exch(ncstd, ncstd)
    2425             : 
    2426             :       INTEGER, PARAMETER    ::  ncut = 5                     ! cut-off value of n-summation
    2427             :       INTEGER               ::  cn                           ! counter for n-summation
    2428           0 :       REAL                  ::  d_ln(fi%atoms%jmtd, 0:2*hybdat%lmaxcd, 0:ncut) ! expansion coefficients of erfc(wr)/r
    2429             :       ! in Legendre polynomials
    2430             :       CHARACTER*100         :: outtext
    2431             : 
    2432             : !   IF ( a_ex /= aMix_HSE ) st--op 'hsefunctional: mixing parameter inconsistent'
    2433             : 
    2434             : !   IF ( irank == 0 ) THEN
    2435             : !     WRITE(outtext,'(A)') new_line('n') // new_line('n') // '### core-core-core-core exchange ###'
    2436             : !     CALL writeout(outtext,irank)
    2437             : !     WRITE(outtext,'(A)') new_line('n') // '        k-point       band    exchange'
    2438             : !     CALL writeout(outtext,irank)
    2439             : !   END IF
    2440             : 
    2441             :       ! set up point
    2442           0 :       CALL timestart("set up point")
    2443           0 :       icst = 0
    2444           0 :       iatom = 0
    2445           0 :       DO itype = 1, fi%atoms%ntype
    2446           0 :          DO ieq = 1, fi%atoms%neq(itype)
    2447           0 :             iatom = iatom + 1
    2448           0 :             DO l = 0, hybdat%lmaxc(itype)
    2449           0 :                DO m = -l, l
    2450           0 :                   DO n = 1, hybdat%nindxc(l, itype)
    2451           0 :                      icst = icst + 1
    2452           0 :                      point(n, m, l, iatom) = icst
    2453             :                   END DO
    2454             :                END DO
    2455             :             END DO
    2456             :          END DO
    2457             :       END DO
    2458           0 :       CALL timestop("set up point")
    2459             : 
    2460           0 :       CALL timestart("main calculation")
    2461           0 :       llmax = 2*hybdat%lmaxcd
    2462           0 :       exch = 0
    2463           0 :       iatom0 = 0
    2464           0 :       DO itype = 1, fi%atoms%ntype
    2465           0 :          CALL timestart("calc legendre polys")
    2466             :          ! Calculate the expansion coefficients of the potential in Legendre polynomials
    2467           0 :          d_ln(:, 0:2*hybdat%lmaxc(itype), :) = calculate_coefficients(fi%atoms%rmsh(:, itype), 2*hybdat%lmaxc(itype), ncut, hybdat%fac)
    2468             : 
    2469           0 :          CALL timestop("calc legendre polys")
    2470             : 
    2471           0 :          DO l1 = 0, hybdat%lmaxc(itype)  ! left core state
    2472             : 
    2473           0 :             DO l2 = 0, hybdat%lmaxc(itype)  ! right core state
    2474           0 :                DO l = 0, hybdat%lmaxc(itype)   ! occupied core state
    2475             : 
    2476           0 :                   DO ll = ABS(l1 - l), l1 + l
    2477           0 :                      IF (ll < ABS(l - l2) .OR. ll > l + l2) CYCLE
    2478           0 :                      IF (MOD(l + l1 + ll, 2) /= 0) CYCLE
    2479           0 :                      IF (MOD(l + l2 + ll, 2) /= 0) CYCLE
    2480             : 
    2481           0 :                      DO m1 = -l1, l1
    2482           0 :                         m2 = m1
    2483           0 :                         IF (ABS(m2) > l2) CYCLE
    2484           0 :                         DO m = -l, l
    2485           0 :                            mm = m - m1
    2486           0 :                            IF (ABS(mm) > ll) CYCLE
    2487           0 :                            rdum = fpi_const/(2*ll + 1)*gaunt1(l, ll, l1, m, mm, m1, llmax)*gaunt1(l, ll, l2, m, mm, m2, llmax)
    2488             : 
    2489           0 :                            DO n = 1, hybdat%nindxc(l, itype)
    2490           0 :                               DO n2 = 1, hybdat%nindxc(l2, itype)
    2491             :                                  rprod(:) = (hybdat%core1(:, n, l, itype)*hybdat%core1(:, n2, l2, itype) &
    2492           0 :                                              + hybdat%core2(:, n, l, itype)*hybdat%core2(:, n2, l2, itype))/fi%atoms%rmsh(:, itype)
    2493             : 
    2494             :                                  ! Initialization of n Summation
    2495           0 :                                  sum_primf = 0.0
    2496             :                                  ! Integration over r'
    2497           0 :                                  DO cn = 0, ncut ! Summation over Legendre polynomials
    2498           0 :                                     primf1 = 0.0
    2499           0 :                                     primf2 = 0.0
    2500             :                                     ! Calculate integral for 0 < r' < r
    2501           0 :                                     CALL primitivef(primf1, rprod(:)*fi%atoms%rmsh(:, itype)**(ll + 2*cn + 1), fi%atoms%rmsh, fi%atoms%dx, fi%atoms%jri, fi%atoms%jmtd, itype, fi%atoms%ntype)
    2502             :                                     ! Calculate integral for r < r' < R
    2503             :                                     !-itype is to enforce inward integration
    2504           0 :                                     CALL primitivef(primf2, d_ln(:, ll, cn)*rprod(:)/fi%atoms%rmsh(:, itype)**(ll + 2*cn), fi%atoms%rmsh, fi%atoms%dx, fi%atoms%jri, fi%atoms%jmtd, -itype, fi%atoms%ntype)
    2505             :                                     ! Multiplication with appropriate prefactors
    2506           0 :                                     primf1 = primf1/fi%atoms%rmsh(:, itype)**(ll + 2*cn)*d_ln(:, ll, cn)
    2507           0 :                                     primf2 = primf2*fi%atoms%rmsh(:, itype)**(ll + 2*cn + 1)
    2508             :                                     ! Summation over n
    2509           0 :                                     sum_primf = sum_primf + primf1 + primf2
    2510             :                                  END DO
    2511             : 
    2512           0 :                                  DO n1 = 1, hybdat%nindxc(l1, itype)
    2513             : 
    2514             :                                     rprod(:) = (hybdat%core1(:, n, l, itype)*hybdat%core1(:, n1, l1, itype) &
    2515           0 :                                                 + hybdat%core2(:, n, l, itype)*hybdat%core2(:, n1, l1, itype))/fi%atoms%rmsh(:, itype)
    2516             : 
    2517           0 :                                     integrand = rprod*sum_primf
    2518             : 
    2519           0 :                                     rdum1 = rdum*intgrf(integrand, fi%atoms, itype, hybdat%gridf)
    2520             : 
    2521           0 :                                     iatom = iatom0
    2522           0 :                                     DO ieq = 1, fi%atoms%neq(itype)
    2523           0 :                                        iatom = iatom + 1
    2524           0 :                                        icst1 = point(n1, m1, l1, iatom)
    2525           0 :                                        icst2 = point(n2, m2, l2, iatom)
    2526           0 :                                        exch(icst1, icst2) = exch(icst1, icst2) + rdum1
    2527             :                                     END DO
    2528             :                                  END DO  !n1
    2529             : 
    2530             :                               END DO  !n2
    2531             :                            END DO  !n
    2532             : 
    2533             :                         END DO  !m
    2534             :                      END DO  !m1
    2535             : 
    2536             :                   END DO  !ll
    2537             : 
    2538             :                END DO  !l
    2539             :             END DO  !l2
    2540             :          END DO  !l1
    2541           0 :          iatom0 = iatom0 + fi%atoms%neq(itype)
    2542             :       END DO  !itype
    2543           0 :       CALL timestop("main calculation")
    2544             : 
    2545           0 :       IF (fi%sym%invs) THEN
    2546             :          CALL symmetrize(exch, ncstd, ncstd, 3, &
    2547             :                       fi%atoms, hybdat%lmaxc, hybdat%lmaxcd, &
    2548           0 :                       hybdat%nindxc, fi%sym)
    2549           0 :          IF (ANY(ABS(aimag(exch)) > 1E-6)) call juDFT_error( 'exchange_cccc: exch possesses significant imaginary part')
    2550             :       ENDIF
    2551             : !   DO icst = 1,ncstd
    2552             : !     IF ( irank == 0 ) &
    2553             : !       WRITE(oUnit,'(    ''  ('',F5.3,'','',F5.3,'','',F5.3,'')'',I4,1X,F12.5)')fi%kpts%bkpt,icst,REAL(exch(icst,icst))*(-27.211608)
    2554             : !   END DO
    2555             : 
    2556             :       ! add core exchange contributions to the te_hfex
    2557             : 
    2558           0 :       DO icst1 = 1, ncstd
    2559           0 :          results%te_hfex%core = results%te_hfex%core - a_ex*fi%kpts%wtkpt(nk)*exch(icst1, icst1)
    2560             :       END DO
    2561             : 
    2562           0 :    END SUBROUTINE exchange_ccccHSE
    2563             : 
    2564             :    ! The expansion coefficients of the attenuated Coulomb interaction in Legendre polynomials are calculated.
    2565             :    ! The attenuation is expressed in terms of a complementary error function
    2566             :    !
    2567             :    !                    -----              l+2n
    2568             :    !  erfc(w|r-r'|)      \                r           /           \
    2569             :    ! --------------- =    )    d  (wr') ---------  P (  cos(r,r')  )
    2570             :    !     |r-r'|          /      ln        l+2n+1    l \           /
    2571             :    !                    -----            r'
    2572             :    !                     l,n
    2573             :    ! where w is omega of the HSE functional, P_l are the Legendre polynomials and r' > r
    2574             :    !
    2575             :    ! The coefficients are given as
    2576             :    !                                    l-1
    2577             :    !                                2  -----   i+1  2i+1
    2578             :    !                       1      -x    \     2    x
    2579             :    !  d (x) = erfc(x) + -------  e       )   ------------
    2580             :    !   l,0                ____          /     (2i + 1)!!
    2581             :    !                     V Pi          -----
    2582             :    !                                    i=0
    2583             :    !
    2584             :    !                                       n-1
    2585             :    !               n     2                -----      i+1  l+i+1  2l+2n+2i+1
    2586             :    !           (-1)    -x        2l+1      \     (-1)    2      x
    2587             :    ! d (x)  = ------- e     -------------   )   ----------------------------
    2588             :    !  l,n>0     ____         n (2l+2n+1)   /      i! (n-i-1)! (2l+2i+1)!!
    2589             :    !           V Pi                       -----
    2590             :    !                                       i=0
    2591             :    !
    2592             :    ! Input:  rmsh - grid of radial position
    2593             :    !         lmax - maximum l value
    2594             :    !         ncut - maximum value for which coefficients are calculated
    2595             :    !         fac  - (optional) known factorials
    2596             :    ! Return: d_ln's for all r in rmsh, all 0 <= l <= lmax and all n <= ncut
    2597           0 :    FUNCTION calculate_coefficients(rmsh, lmax, ncut, fac) RESULT(d_ln)
    2598             : 
    2599             :       USE m_constants
    2600             : 
    2601             :       IMPLICIT NONE
    2602             : 
    2603             :       REAL, INTENT(IN)           :: rmsh(:)
    2604             :       INTEGER, INTENT(IN)        :: lmax, ncut
    2605             :       REAL, INTENT(IN), OPTIONAL :: fac(0:)
    2606             : 
    2607             :       INTEGER :: ci, cn, cl, fac_size
    2608             :       REAL    :: r1_spi, r2l_1, ri, r2l_2i_1, rn, r2l_2n_1
    2609           0 :       REAL    :: fn(0:MAX(0, ncut - 1))
    2610           0 :       REAL    :: rx(SIZE(rmsh)), x2(SIZE(rmsh)), x2n(SIZE(rmsh))
    2611           0 :       REAL    :: init(SIZE(rmsh)), addend(SIZE(rmsh))
    2612           0 :       REAL    :: erfc_x(SIZE(rmsh)), exp_x2(SIZE(rmsh))
    2613             :       REAL    :: d_ln(SIZE(rmsh), 0:lmax, 0:ncut)
    2614             : 
    2615             :       ! Initialize factorials
    2616           0 :       IF (PRESENT(fac)) THEN
    2617           0 :          fac_size = MIN(ncut, SIZE(fac))
    2618           0 :          fn(0:fac_size - 1) = fac(0:fac_size - 1)
    2619             :       ELSE
    2620           0 :          fac_size = 1
    2621           0 :          fn(0) = 1.0
    2622             :       END IF
    2623           0 :       DO cn = fac_size, ncut - 1
    2624           0 :          fn(cn) = fn(cn - 1)*cn
    2625             :       END DO
    2626             : 
    2627             :       ! Initialize 1 / sqrt(pi)
    2628             :       r1_spi = 1.0/SQRT(pi_const)
    2629             : 
    2630             :       ! Calculate x and x^2 and the functions erfc(x) and exp(x^2)
    2631           0 :       rx = omega_HSe*rmsh
    2632           0 :       x2 = rx**2
    2633           0 :       erfc_x = erfc(rx)
    2634           0 :       exp_x2 = EXP(-x2)
    2635             : 
    2636             :       ! Calculate the first coefficient
    2637             :       !                                    l-1
    2638             :       !                                2  -----   i+1  2i+1
    2639             :       !                       1      -x    \     2    x
    2640             :       !  d (x) = erfc(x) + -------  e       )   ------------
    2641             :       !   l,0                ____          /     (2i + 1)!!
    2642             :       !                     V Pi          -----
    2643             :       !                                    i=0
    2644             :       ! Initialize the first coefficient
    2645           0 :       r2l_1 = 1.0
    2646           0 :       init = 2.0*rx*r1_spi*exp_x2
    2647           0 :       addend = init
    2648           0 :       IF (lmax >= 0) d_ln(:, 0, 0) = erfc_x
    2649           0 :       IF (lmax >= 1) d_ln(:, 1, 0) = addend
    2650             :       ! Iterative calculation of the other coefficients
    2651           0 :       DO cl = 2, lmax
    2652           0 :          r2l_1 = r2l_1 + 2.0
    2653           0 :          addend = 2.0*addend*x2/r2l_1
    2654           0 :          d_ln(:, cl, 0) = d_ln(:, cl - 1, 0) + addend
    2655             :       END DO
    2656             :       ! Adding the erfc(x) term which is present in all coefficients
    2657           0 :       FORALL (cl=1:lmax)
    2658             :       d_ln(:, cl, 0) = erfc_x + d_ln(:, cl, 0)
    2659             :       END FORALL
    2660             : 
    2661             :       ! Calculate all other coefficients
    2662             :       !                                       n-1
    2663             :       !               n     2                -----      i+1  l+i+1  2l+2n+2i+1
    2664             :       !           (-1)    -x        2l+1      \     (-1)    2      x
    2665             :       ! d (x)  = ------- e     -------------   )   ----------------------------
    2666             :       !  l,n>0     ____         n (2l+2n+1)   /      i! (n-i-1)! (2l+2i+1)!!
    2667             :       !           V Pi                       -----
    2668             :       !                                       i=0
    2669             :       ! Initialize helper variables
    2670             :       r2l_1 = -1.0
    2671           0 :       DO cl = 0, lmax
    2672             :          ! Calculation of the l-dependent part
    2673           0 :          r2l_1 = r2l_1 + 2.0
    2674           0 :          addend = init*x2               ! addend ~ 2^(l+1) x^(2l+1) / (2l-1)!!
    2675           0 :          init = 2.0*addend/r2l_1
    2676             :          ! Summation over all i
    2677             :          ! i = 0 term
    2678           0 :          DO cn = 1, ncut
    2679           0 :             d_ln(:, cl, cn) = addend/fn(cn - 1)
    2680             :          END DO
    2681             :          ! higher values of i
    2682             :          ri = 0.0
    2683             :          r2l_2i_1 = r2l_1
    2684           0 :          DO ci = 1, ncut - 1
    2685           0 :             ri = ri + 1.0
    2686           0 :             r2l_2i_1 = r2l_2i_1 + 2.0
    2687           0 :             addend = -2.0*addend*x2/(ri*r2l_2i_1)       ! addend ~ (-1)^i+1 2^(l+i+1) x^(2l+2i+1) (2l+1) / i!(2l+2i+1)!!
    2688           0 :             DO cn = ci + 1, ncut
    2689           0 :                d_ln(:, cl, cn) = d_ln(:, cl, cn) + addend/fn(cn - ci - 1)
    2690             :             END DO
    2691             :          END DO
    2692             :          r2l_2n_1 = r2l_1
    2693             :          ! Divide by n and l dependent part
    2694           0 :          DO cn = 1, ncut
    2695           0 :             r2l_2n_1 = r2l_2n_1 + 2.0
    2696           0 :             d_ln(:, cl, cn) = d_ln(:, cl, cn)/r2l_2n_1
    2697             :          END DO
    2698             :       END DO
    2699             :       ! Resolve only-n dependent part
    2700           0 :       rn = 1.0
    2701           0 :       x2n = x2
    2702           0 :       IF (ncut >= 1) THEN
    2703           0 :          FORALL (cl=0:lmax)
    2704             :          d_ln(:, cl, 1) = d_ln(:, cl, 1)*x2
    2705             :          END FORALL
    2706             :       END IF
    2707           0 :       DO cn = 2, ncut
    2708           0 :          rn = rn + 1.0
    2709           0 :          x2n = -x2n*x2
    2710           0 :          FORALL (cl=0:lmax)
    2711             :          d_ln(:, cl, cn) = d_ln(:, cl, cn)*x2n/rn
    2712             :          END FORALL
    2713             :       END DO
    2714             : 
    2715           0 :    END FUNCTION calculate_coefficients
    2716             : 
    2717           0 : END MODULE m_hsefunctional

Generated by: LCOV version 1.14