LCOV - code coverage report
Current view: top level - src/eri_mme - eri_mme_lattice_summation.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 543 681 79.7 %
Date: 2024-11-21 06:45:46 Functions: 152 281 54.1 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Ewald sums to represent integrals in direct and reciprocal lattice.
      10             : !> \par History
      11             : !>       2015 09 created
      12             : !> \author Patrick Seewald
      13             : ! **************************************************************************************************
      14             : 
      15             : MODULE eri_mme_lattice_summation
      16             :    #:include "eri_mme_unroll.fypp"
      17             : 
      18             :    USE ao_util, ONLY: exp_radius
      19             :    USE eri_mme_gaussian, ONLY: create_gaussian_overlap_dist_to_hermite, &
      20             :                                create_hermite_to_cartesian, &
      21             :                                eri_mme_coulomb, eri_mme_yukawa, &
      22             :                                eri_mme_longrange
      23             :    USE kinds, ONLY: dp, &
      24             :                     int_8
      25             :    USE mathconstants, ONLY: gaussi, &
      26             :                             pi, &
      27             :                             twopi
      28             :    USE orbital_pointers, ONLY: coset, &
      29             :                                indco, &
      30             :                                ncoset
      31             : #include "../base/base_uses.f90"
      32             : 
      33             :    IMPLICIT NONE
      34             : 
      35             :    PRIVATE
      36             : 
      37             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .FALSE.
      38             : 
      39             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eri_mme_lattice_summation'
      40             : 
      41             :    PUBLIC :: &
      42             :       ellipsoid_bounds, &
      43             :       eri_mme_2c_get_bounds, &
      44             :       eri_mme_2c_get_rads, &
      45             :       eri_mme_3c_get_bounds, &
      46             :       eri_mme_3c_get_rads, &
      47             :       get_l, &
      48             :       pgf_sum_2c_gspace_1d, &
      49             :       pgf_sum_2c_gspace_1d_deltal, &
      50             :       pgf_sum_2c_gspace_3d, &
      51             :       pgf_sum_2c_rspace_1d, &
      52             :       pgf_sum_2c_rspace_3d, &
      53             :       pgf_sum_3c_1d, &
      54             :       pgf_sum_3c_3d
      55             : 
      56             :    INTEGER, PARAMETER, PRIVATE :: exp_w = 50, div_w = 10
      57             : 
      58             : CONTAINS
      59             : 
      60             : ! **************************************************************************************************
      61             : !> \brief Get summation radii for 2c integrals
      62             : !> \param la_max ...
      63             : !> \param lb_max ...
      64             : !> \param zeta ...
      65             : !> \param zetb ...
      66             : !> \param a_mm ...
      67             : !> \param G_min ...
      68             : !> \param R_min ...
      69             : !> \param sum_precision ...
      70             : !> \param G_rad ...
      71             : !> \param R_rad ...
      72             : ! **************************************************************************************************
      73      948038 :    SUBROUTINE eri_mme_2c_get_rads(la_max, lb_max, zeta, zetb, a_mm, G_min, R_min, sum_precision, G_rad, R_rad)
      74             :       INTEGER, INTENT(IN)                                :: la_max, lb_max
      75             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, a_mm, G_min, R_min, &
      76             :                                                             sum_precision
      77             :       REAL(KIND=dp), INTENT(OUT), OPTIONAL               :: G_rad, R_rad
      78             : 
      79             :       INTEGER                                            :: l_max
      80             :       REAL(KIND=dp)                                      :: alpha_G, alpha_R, G_res, R_res
      81             : 
      82      948038 :       l_max = la_max + lb_max
      83      948038 :       alpha_G = a_mm + 0.25_dp/zeta + 0.25_dp/zetb
      84      948038 :       alpha_R = 0.25_dp/alpha_G
      85             : 
      86      948038 :       G_res = 0.5_dp*G_min
      87      948038 :       R_res = 0.5_dp*R_min
      88             : 
      89      948038 :       IF (PRESENT(G_rad)) G_rad = exp_radius(l_max, alpha_G, sum_precision, 1.0_dp, epsabs=G_res)
      90      948038 :       IF (PRESENT(R_rad)) R_rad = exp_radius(l_max, alpha_R, sum_precision, 1.0_dp, epsabs=R_res)
      91             : 
      92      948038 :    END SUBROUTINE
      93             : 
      94             : ! **************************************************************************************************
      95             : !> \brief Get summation radii for 3c integrals
      96             : !> \param la_max ...
      97             : !> \param lb_max ...
      98             : !> \param lc_max ...
      99             : !> \param zeta ...
     100             : !> \param zetb ...
     101             : !> \param zetc ...
     102             : !> \param a_mm ...
     103             : !> \param G_min ...
     104             : !> \param R_min ...
     105             : !> \param sum_precision ...
     106             : !> \param G_rads_1 ...
     107             : !> \param R_rads_2 ...
     108             : !> \param R_rads_3 ...
     109             : ! **************************************************************************************************
     110     2411094 :    SUBROUTINE eri_mme_3c_get_rads(la_max, lb_max, lc_max, zeta, zetb, zetc, a_mm, G_min, R_min, &
     111             :                                   sum_precision, G_rads_1, R_rads_2, R_rads_3)
     112             :       INTEGER, INTENT(IN)                                :: la_max, lb_max, lc_max
     113             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, zetc, a_mm
     114             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: G_min, R_min
     115             :       REAL(KIND=dp), INTENT(IN)                          :: sum_precision
     116             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT), OPTIONAL :: G_rads_1, R_rads_2
     117             :       REAL(KIND=dp), DIMENSION(2), INTENT(OUT), OPTIONAL :: R_rads_3
     118             : 
     119             :       REAL(KIND=dp)                                      :: alpha, alpha_R, beta, G_res, gamma, R_res
     120             : 
     121             :       ! exponents in G space
     122     2411094 :       alpha = 0.25_dp/zeta
     123     2411094 :       beta = 0.25_dp/zetb
     124     2411094 :       gamma = 0.25_dp/zetc + a_mm
     125             : 
     126             :       ! Summation radii and number of summands for all lattice summation methods
     127             :       ! sum method 1
     128     2411094 :       IF (PRESENT(G_rads_1)) THEN
     129     2411094 :          G_res = 0.5_dp*G_min
     130     2411094 :          G_rads_1(1) = exp_radius(la_max, alpha, sum_precision, 1.0_dp, G_res)
     131     2411094 :          G_rads_1(2) = exp_radius(lb_max, beta, sum_precision, 1.0_dp, G_res)
     132     2411094 :          G_rads_1(3) = exp_radius(lc_max, gamma, sum_precision, 1.0_dp, G_res)
     133             :       END IF
     134             : 
     135             :       ! sum method 2
     136     2411094 :       IF (PRESENT(R_rads_2)) THEN
     137     2256540 :          R_res = 0.5_dp*R_min
     138     2256540 :          R_rads_2(1) = exp_radius(lb_max + lc_max, 0.25_dp/(beta + gamma), sum_precision, 1.0_dp, epsabs=R_res)
     139     2256540 :          R_rads_2(2) = exp_radius(lc_max + la_max, 0.25_dp/(alpha + gamma), sum_precision, 1.0_dp, epsabs=R_res)
     140     2256540 :          R_rads_2(3) = exp_radius(lb_max + la_max, 0.25_dp/(alpha + beta), sum_precision, 1.0_dp, epsabs=R_res)
     141             :       END IF
     142             : 
     143             :       ! sum method 3
     144             : 
     145     2411094 :       IF (PRESENT(R_rads_3)) THEN
     146     2256540 :          R_res = 0.5_dp*R_min
     147     2256540 :          alpha_R = 1.0_dp/((zeta + zetb + zetc)/((zeta + zetb)*zetc) + 4.0_dp*a_mm)
     148     2256540 :          R_rads_3(1) = exp_radius(la_max + lb_max, zeta*zetb/(zeta + zetb), sum_precision, 1.0_dp, R_res)
     149     2256540 :          R_rads_3(2) = exp_radius(la_max + lb_max + lc_max, alpha_R, sum_precision, 1.0_dp, R_res)
     150             :       END IF
     151             : 
     152     2411094 :    END SUBROUTINE
     153             : 
     154             : ! **************************************************************************************************
     155             : !> \brief Get summation bounds for 2c integrals
     156             : !> \param hmat ...
     157             : !> \param h_inv ...
     158             : !> \param vol ...
     159             : !> \param is_ortho ...
     160             : !> \param G_min ...
     161             : !> \param R_min ...
     162             : !> \param la_max ...
     163             : !> \param lb_max ...
     164             : !> \param zeta ...
     165             : !> \param zetb ...
     166             : !> \param a_mm ...
     167             : !> \param sum_precision ...
     168             : !> \param n_sum_1d ...
     169             : !> \param n_sum_3d ...
     170             : !> \param G_bounds ...
     171             : !> \param G_rad ...
     172             : !> \param R_bounds ...
     173             : !> \param R_rad ...
     174             : ! **************************************************************************************************
     175      892104 :    SUBROUTINE eri_mme_2c_get_bounds(hmat, h_inv, vol, is_ortho, G_min, R_min, la_max, lb_max, &
     176             :                                     zeta, zetb, a_mm, sum_precision, n_sum_1d, n_sum_3d, &
     177             :                                     G_bounds, G_rad, R_bounds, R_rad)
     178             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
     179             :       REAL(KIND=dp), INTENT(IN)                          :: vol
     180             :       LOGICAL, INTENT(IN)                                :: is_ortho
     181             :       REAL(KIND=dp), INTENT(IN)                          :: G_min, R_min
     182             :       INTEGER, INTENT(IN)                                :: la_max, lb_max
     183             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, a_mm, sum_precision
     184             :       INTEGER(KIND=int_8), DIMENSION(2, 3), INTENT(OUT)  :: n_sum_1d
     185             :       INTEGER(KIND=int_8), DIMENSION(2), INTENT(OUT)     :: n_sum_3d
     186             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: G_bounds
     187             :       REAL(KIND=dp), INTENT(OUT)                         :: G_rad
     188             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: R_bounds
     189             :       REAL(KIND=dp), INTENT(OUT)                         :: R_rad
     190             : 
     191             :       INTEGER                                            :: i_xyz
     192             :       REAL(KIND=dp)                                      :: ns_G, ns_R, vol_G
     193             : 
     194      892104 :       CALL eri_mme_2c_get_rads(la_max, lb_max, zeta, zetb, a_mm, G_min, R_min, sum_precision, G_rad, R_rad)
     195             : 
     196    11597352 :       G_bounds = ellipsoid_bounds(G_rad, TRANSPOSE(hmat)/(2.0_dp*pi))
     197      892104 :       R_bounds = ellipsoid_bounds(R_rad, h_inv)
     198             : 
     199      892104 :       vol_G = twopi**3/vol
     200             : 
     201      892104 :       IF (is_ortho) THEN
     202     2981984 :          DO i_xyz = 1, 3
     203     2236488 :             ns_G = 2.0_dp*G_bounds(i_xyz)
     204     2236488 :             ns_R = 2.0_dp*R_bounds(i_xyz)
     205     2236488 :             n_sum_1d(1, i_xyz) = nsum_2c_gspace_1d(ns_G, la_max, lb_max)
     206     2981984 :             n_sum_1d(2, i_xyz) = nsum_2c_rspace_1d(ns_R, la_max, lb_max)
     207             :          END DO
     208             :       ELSE
     209      146608 :          ns_G = 4._dp/3._dp*pi*G_rad**3/vol_G
     210      146608 :          ns_R = 4._dp/3._dp*pi*R_rad**3/vol
     211      146608 :          n_sum_3d(1) = nsum_2c_gspace_3d(ns_G, la_max, lb_max)
     212      146608 :          n_sum_3d(2) = nsum_2c_rspace_3d(ns_R, la_max, lb_max)
     213             :       END IF
     214             : 
     215      892104 :    END SUBROUTINE
     216             : 
     217             : ! **************************************************************************************************
     218             : !> \brief Get summation bounds for 3c integrals
     219             : !> \param hmat ...
     220             : !> \param h_inv ...
     221             : !> \param vol ...
     222             : !> \param is_ortho ...
     223             : !> \param G_min ...
     224             : !> \param R_min ...
     225             : !> \param la_max ...
     226             : !> \param lb_max ...
     227             : !> \param lc_max ...
     228             : !> \param zeta ...
     229             : !> \param zetb ...
     230             : !> \param zetc ...
     231             : !> \param a_mm ...
     232             : !> \param sum_precision ...
     233             : !> \param n_sum_1d ...
     234             : !> \param n_sum_3d ...
     235             : !> \param G_bounds_1 ...
     236             : !> \param G_rads_1 ...
     237             : !> \param R_bounds_2 ...
     238             : !> \param R_rads_2 ...
     239             : !> \param R_bounds_3 ...
     240             : !> \param R_rads_3 ...
     241             : ! **************************************************************************************************
     242     2256540 :    SUBROUTINE eri_mme_3c_get_bounds(hmat, h_inv, vol, is_ortho, G_min, R_min, la_max, lb_max, lc_max, &
     243             :                                     zeta, zetb, zetc, a_mm, sum_precision, n_sum_1d, n_sum_3d, &
     244             :                                     G_bounds_1, G_rads_1, R_bounds_2, R_rads_2, R_bounds_3, R_rads_3)
     245             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
     246             :       REAL(KIND=dp), INTENT(IN)                          :: vol
     247             :       LOGICAL, INTENT(IN)                                :: is_ortho
     248             :       REAL(KIND=dp), INTENT(IN)                          :: G_min, R_min
     249             :       INTEGER, INTENT(IN)                                :: la_max, lb_max, lc_max
     250             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, zetc, a_mm, sum_precision
     251             :       INTEGER(KIND=int_8), DIMENSION(3, 3), INTENT(OUT)  :: n_sum_1d
     252             :       INTEGER(KIND=int_8), DIMENSION(3), INTENT(OUT)     :: n_sum_3d
     253             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: G_bounds_1
     254             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: G_rads_1
     255             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: R_bounds_2
     256             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: R_rads_2
     257             :       REAL(KIND=dp), DIMENSION(2, 3)                     :: R_bounds_3
     258             :       REAL(KIND=dp), DIMENSION(2), INTENT(OUT)           :: R_rads_3
     259             : 
     260             :       INTEGER                                            :: i, i_xyz, order_1, order_2
     261             :       REAL(KIND=dp)                                      :: ns1_G1, ns1_G2, ns2_G, ns2_R, ns3_R1, &
     262             :                                                             ns3_R2, vol_G
     263             :       CALL eri_mme_3c_get_rads(la_max, lb_max, lc_max, zeta, zetb, zetc, a_mm, G_min, R_min, sum_precision, &
     264     2256540 :                                G_rads_1=G_rads_1, R_rads_2=R_rads_2, R_rads_3=R_rads_3)
     265             : 
     266     2256540 :       vol_G = twopi**3/vol
     267             : 
     268     9026160 :       order_1 = MAXLOC(G_rads_1, DIM=1)
     269     9026160 :       order_2 = MINLOC(G_rads_1, DIM=1)
     270             : 
     271     9026160 :       DO i = 1, 3
     272   110570460 :          G_bounds_1(i, :) = ellipsoid_bounds(G_rads_1(i), TRANSPOSE(hmat)/(2.0_dp*pi))
     273             :       END DO
     274             : 
     275     9026160 :       DO i = 1, 3
     276    29335020 :          R_bounds_2(i, :) = ellipsoid_bounds(R_rads_2(i), h_inv)
     277             :       END DO
     278             : 
     279     6769620 :       DO i = 1, 2
     280    20308860 :          R_bounds_3(i, :) = ellipsoid_bounds(R_rads_3(i), h_inv)
     281             :       END DO
     282             : 
     283     2256540 :       IF (is_ortho) THEN
     284     8432160 :          DO i_xyz = 1, 3
     285             : 
     286     6324120 :             ns3_R1 = 2.0_dp*R_bounds_3(1, i_xyz)
     287     6324120 :             ns3_R2 = 2.0_dp*R_bounds_3(2, i_xyz)
     288             : 
     289     8432160 :             n_sum_1d(3, i_xyz) = nsum_3c_rspace_1d(ns3_R1, ns3_R2)
     290             :          END DO
     291             : 
     292             :       ELSE
     293             : 
     294      594000 :          order_1 = MAXLOC(G_rads_1, DIM=1)
     295      594000 :          order_2 = MINLOC(G_rads_1, DIM=1)
     296             : 
     297       71062 :          SELECT CASE (order_1)
     298             :          CASE (1)
     299       71062 :             ns1_G1 = 4._dp/3._dp*pi*G_rads_1(2)**3/vol_G
     300       71062 :             ns1_G2 = 4._dp/3._dp*pi*G_rads_1(3)**3/vol_G
     301             :          CASE (2)
     302       53482 :             ns1_G1 = 4._dp/3._dp*pi*G_rads_1(1)**3/vol_G
     303       53482 :             ns1_G2 = 4._dp/3._dp*pi*G_rads_1(3)**3/vol_G
     304             :          CASE (3)
     305       23956 :             ns1_G1 = 4._dp/3._dp*pi*G_rads_1(1)**3/vol_G
     306      148500 :             ns1_G2 = 4._dp/3._dp*pi*G_rads_1(2)**3/vol_G
     307             :          END SELECT
     308             : 
     309      148500 :          n_sum_3d(1) = nsum_3c_gspace_3d(ns1_G1, ns1_G2, la_max, lb_max, lc_max)
     310             : 
     311      148500 :          ns2_G = 4._dp/3._dp*pi*G_rads_1(order_2)**3/vol_G
     312      148500 :          ns2_R = 4._dp/3._dp*pi*R_rads_2(order_2)**3/vol
     313             : 
     314      148500 :          ns3_R1 = 4._dp/3._dp*pi*R_rads_3(1)**3/vol
     315      148500 :          ns3_R2 = 4._dp/3._dp*pi*R_rads_3(2)**3/vol
     316             : 
     317       30492 :          SELECT CASE (order_2)
     318             :          CASE (1)
     319       30492 :             n_sum_3d(2) = nsum_product_3c_gspace_3d(ns2_G, ns2_R, la_max, lb_max, lc_max)
     320             :          CASE (2)
     321       24372 :             n_sum_3d(2) = nsum_product_3c_gspace_3d(ns2_G, ns2_R, lb_max, la_max, lc_max)
     322             :          CASE (3)
     323      148500 :             n_sum_3d(2) = nsum_product_3c_gspace_3d(ns2_G, ns2_R, lc_max, lb_max, la_max)
     324             :          END SELECT
     325             : 
     326      148500 :          n_sum_3d(3) = nsum_3c_rspace_3d(ns3_R1, ns3_R2, la_max, lb_max, lc_max)
     327             :       END IF
     328             : 
     329     2256540 :    END SUBROUTINE
     330             : 
     331             : ! **************************************************************************************************
     332             : !> \brief Roughly estimated number of floating point operations
     333             : !> \param ns_G ...
     334             : !> \param l ...
     335             : !> \param m ...
     336             : !> \return ...
     337             : ! **************************************************************************************************
     338     2236488 :    PURE FUNCTION nsum_2c_gspace_1d(ns_G, l, m)
     339             :       REAL(KIND=dp), INTENT(IN)                          :: ns_G
     340             :       INTEGER, INTENT(IN)                                :: l, m
     341             :       INTEGER(KIND=int_8)                                :: nsum_2c_gspace_1d
     342             : 
     343     2236488 :       nsum_2c_gspace_1d = NINT(ns_G*(2*exp_w + (l + m + 1)*5), KIND=int_8)
     344     2236488 :    END FUNCTION
     345             : 
     346             : ! **************************************************************************************************
     347             : !> \brief Compute Ewald-like sum for 2-center ERIs in G space in 1 dimension
     348             : !>        S_G(l, alpha) = (-i)^l*inv_lgth*sum_G( C(l, alpha, G) exp(iGR) ), with
     349             : !>                        C(l, alpha, r) = r^l exp(-alpha*r^2),
     350             : !>        dG = inv_lgth*twopi and G = -G_bound*dG, (-G_bound + 1)*dG, ..., G_bound*dG
     351             : !>             for all l < = l_max.
     352             : !> \param S_G ...
     353             : !> \param R ...
     354             : !> \param alpha ...
     355             : !> \param inv_lgth ...
     356             : !> \param G_c ...
     357             : !> \note  S_G is real.
     358             : ! **************************************************************************************************
     359      202238 :    PURE SUBROUTINE pgf_sum_2c_gspace_1d(S_G, R, alpha, inv_lgth, G_c)
     360             :       REAL(KIND=dp), DIMENSION(0:), INTENT(OUT)          :: S_G
     361             :       REAL(KIND=dp), INTENT(IN)                          :: R, alpha, inv_lgth, G_c
     362             : 
     363             :       COMPLEX(KIND=dp)                                   :: exp_tot
     364      202238 :       COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:)        :: S_G_c
     365             :       INTEGER                                            :: gg, l, l_max
     366             :       REAL(KIND=dp)                                      :: dG, G, G_pow_l
     367             : 
     368      202238 :       dG = inv_lgth*twopi
     369      202238 :       l_max = UBOUND(S_G, 1)
     370             : 
     371      606714 :       ALLOCATE (S_G_c(0:l_max))
     372     1025491 :       S_G_c(:) = 0.0_dp
     373     1079898 :       DO gg = -FLOOR(G_c), FLOOR(G_c)
     374      877660 :          G = gg*dG
     375      877660 :          exp_tot = EXP(-alpha*G**2)*EXP(gaussi*G*R) ! cost: 2 exp_w flops
     376      877660 :          G_pow_l = 1.0_dp
     377     4490891 :          DO l = 0, l_max
     378     3410993 :             S_G_c(l) = S_G_c(l) + G_pow_l*(-1.0_dp)**l*exp_tot ! cost: 4 flops
     379     4288653 :             G_pow_l = G_pow_l*G ! cost: 1 flop
     380             :          END DO
     381             :       END DO
     382             : 
     383     1848744 :       S_G(:) = REAL(S_G_c(0:l_max)*i_pow((/(l, l=0, l_max)/)))*inv_lgth
     384      202238 :    END SUBROUTINE pgf_sum_2c_gspace_1d
     385             : 
     386             : ! **************************************************************************************************
     387             : !> \brief Roughly estimated number of floating point operations
     388             : !> \param ns_G ...
     389             : !> \param l ...
     390             : !> \param m ...
     391             : !> \return ...
     392             : ! **************************************************************************************************
     393      146608 :    PURE FUNCTION nsum_2c_gspace_3d(ns_G, l, m)
     394             :       REAL(KIND=dp), INTENT(IN)                          :: ns_G
     395             :       INTEGER, INTENT(IN)                                :: l, m
     396             :       INTEGER(KIND=int_8)                                :: nsum_2c_gspace_3d
     397             : 
     398      146608 :       nsum_2c_gspace_3d = NINT(ns_G*(2*exp_w + ncoset(l + m)*7), KIND=int_8)
     399      146608 :    END FUNCTION
     400             : 
     401             : ! **************************************************************************************************
     402             : !> \brief As pgf_sum_2c_gspace_1d but 3d sum required for non-orthorhombic cells
     403             : !> \param S_G ...
     404             : !> \param l_max ...
     405             : !> \param R ...
     406             : !> \param alpha ...
     407             : !> \param h_inv ...
     408             : !> \param G_c ...
     409             : !> \param G_rad ...
     410             : !> \param vol ...
     411             : !> \param coulomb ...
     412             : !> \note  MMME Method is not very efficient for non-orthorhombic cells
     413             : ! **************************************************************************************************
     414       27581 :    PURE SUBROUTINE pgf_sum_2c_gspace_3d(S_G, l_max, R, alpha, h_inv, G_c, G_rad, vol, potential, pot_par)
     415             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: S_G
     416             :       INTEGER, INTENT(IN)                                :: l_max
     417             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R
     418             :       REAL(KIND=dp), INTENT(IN)                          :: alpha
     419             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: h_inv
     420             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G_c
     421             :       REAL(KIND=dp), INTENT(IN)                          :: G_rad, vol
     422             :       INTEGER, INTENT(IN), OPTIONAL                      :: potential
     423             :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: pot_par
     424             : 
     425             :       COMPLEX(KIND=dp)                                   :: exp_tot
     426             :       INTEGER, DIMENSION(3)                              :: l_xyz
     427             :       INTEGER                                            :: gx, gy, gz, k, l, lco, lx, ly, lz
     428       55162 :       COMPLEX(KIND=dp), DIMENSION(ncoset(l_max))         :: Ig
     429             :       REAL(KIND=dp)                                      :: G_rads_sq, G_sq
     430             :       REAL(KIND=dp), DIMENSION(3)                        :: G, G_x, G_y, G_z
     431       27581 :       REAL(KIND=dp), DIMENSION(3, 0:l_max)               :: G_pow_l
     432             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: ht
     433             : 
     434      358553 :       ht = twopi*TRANSPOSE(h_inv)
     435      660268 :       Ig(:) = 0.0_dp
     436             : 
     437       27581 :       G_rads_sq = G_rad**2
     438             : 
     439      231084 :       DO gx = -FLOOR(G_c(1)), FLOOR(G_c(1))
     440      814012 :          G_x = ht(:, 1)*gx
     441     1913121 :          DO gy = -FLOOR(G_c(2)), FLOOR(G_c(2))
     442     6728148 :             G_y = ht(:, 2)*gy
     443    18506843 :             DO gz = -FLOOR(G_c(3)), FLOOR(G_c(3))
     444    66485212 :                G_z = ht(:, 3)*gz
     445             : 
     446    66485212 :                G = G_x + G_y + G_z
     447    16621303 :                G_sq = G(1)**2 + G(2)**2 + G(3)**2
     448    16621303 :                IF (G_sq .GT. G_rads_sq) CYCLE
     449             : 
     450     6396767 :                IF (PRESENT(potential)) THEN
     451     1033920 :                   IF (gx .EQ. 0 .AND. gy .EQ. 0 .AND. gz .EQ. 0) CYCLE
     452             :                END IF
     453             : 
     454    25586300 :                exp_tot = EXP(-alpha*G_sq)*EXP(gaussi*DOT_PRODUCT(G, R)) ! cost: 2 exp_w flops
     455     6396575 :                IF (PRESENT(potential)) THEN
     456     1378304 :                   SELECT CASE (potential)
     457             :                   CASE (eri_mme_coulomb)
     458      344576 :                      exp_tot = exp_tot/G_sq
     459             :                   CASE (eri_mme_yukawa)
     460      344576 :                      exp_tot = exp_tot/(G_sq + pot_par**2)
     461             :                      !exp_tot = exp_tot/G_sq
     462             :                   CASE (eri_mme_longrange)
     463     1033728 :                      exp_tot = exp_tot/G_sq*EXP(-G_sq/pot_par**2)
     464             :                   END SELECT
     465             :                END IF
     466    25586300 :                DO k = 1, 3
     467    19189725 :                   G_pow_l(k, 0) = 1.0_dp
     468   110227076 :                   DO l = 1, l_max
     469   103830501 :                      G_pow_l(k, l) = G_pow_l(k, l - 1)*G(k)
     470             :                   END DO
     471             :                END DO
     472   466764837 :                DO lco = 1, ncoset(l_max)
     473   458686225 :                   CALL get_l(lco, l, lx, ly, lz)
     474  1834744900 :                   l_xyz = [lx, ly, lz]
     475             :                   Ig(coset(lx, ly, lz)) = Ig(coset(lx, ly, lz)) + & ! cost: 7 flops
     476             :                                           G_pow_l(1, lx)*G_pow_l(2, ly)*G_pow_l(3, lz)* &
     477   475307528 :                                           exp_tot*(-1.0_dp)**l*i_pow(l)
     478             :                END DO
     479             :             END DO
     480             :          END DO
     481             :       END DO
     482      660268 :       S_G(:) = REAL(Ig(:), KIND=dp)/vol
     483       27581 :    END SUBROUTINE pgf_sum_2c_gspace_3d
     484             : 
     485             : ! **************************************************************************************************
     486             : !> \brief Roughly estimated number of floating point operations
     487             : !> \param ns_R ...
     488             : !> \param l ...
     489             : !> \param m ...
     490             : !> \return ...
     491             : ! **************************************************************************************************
     492     2236488 :    PURE FUNCTION nsum_2c_rspace_1d(ns_R, l, m)
     493             :       REAL(KIND=dp), INTENT(IN)                          :: ns_R
     494             :       INTEGER, INTENT(IN)                                :: l, m
     495             :       INTEGER(KIND=int_8)                                :: nsum_2c_rspace_1d
     496             : 
     497     2236488 :       nsum_2c_rspace_1d = NINT(ns_R*(exp_w + (l + m + 1)*3), KIND=int_8)
     498     2236488 :    END FUNCTION
     499             : 
     500             : ! **************************************************************************************************
     501             : !> \brief Compute Ewald-like sum for 2-center ERIs in R space in 1 dimension
     502             : !>        S_R(l, alpha) = SQRT(alpha/pi) sum_R'( H(l, alpha, R-R') ),
     503             : !>        with H(l, alpha, R) = (-d/dR)^l exp(-alpha*R^2),
     504             : !>        dR = lgth and R' = -R_min*dR, (-R_min + 1)*dR, ..., R_max*dR,
     505             : !>        for all l < = l_max.
     506             : !> \param S_R ...
     507             : !> \param R ...
     508             : !> \param alpha ...
     509             : !> \param lgth ...
     510             : !> \param R_c ...
     511             : !> \note  result is equivalent to pgf_sum_2c_gspace_1d with
     512             : !>              S_R(l, alpha) = S_G(l, 1/(4*alpha))
     513             : ! **************************************************************************************************
     514     2212684 :    PURE SUBROUTINE pgf_sum_2c_rspace_1d(S_R, R, alpha, lgth, R_c)
     515             :       REAL(KIND=dp), DIMENSION(0:), INTENT(OUT)          :: S_R
     516             :       REAL(KIND=dp), INTENT(IN)                          :: R, alpha, lgth, R_c
     517             : 
     518             :       INTEGER                                            :: l, l_max, rr
     519             :       REAL(KIND=dp)                                      :: dR, exp_tot, R_pow_l, Rp
     520     2212684 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: h_to_c
     521             : 
     522     2212684 :       dR = lgth
     523     2212684 :       l_max = UBOUND(S_R, 1)
     524             : 
     525             :       ! 1) compute sum over C(l, alpha, R - R') instead of H(l, alpha, R - R')
     526     9453605 :       S_R(:) = 0.0_dp
     527     2212684 :       Rp = R - R_c*dR
     528     9268511 :       DO rr = CEILING(-R_c - R/dR), FLOOR(R_c - R/dR)
     529     7055827 :          Rp = R + rr*dR
     530     7055827 :          exp_tot = EXP(-alpha*Rp**2) ! cost: exp_w flops
     531     7055827 :          R_pow_l = 1.0_dp
     532    32695273 :          DO l = 0, l_max
     533    23426762 :             S_R(l) = S_R(l) + R_pow_l*exp_tot ! cost: 2 flops
     534    30482589 :             R_pow_l = R_pow_l*Rp ! cost: 1 flop
     535             :          END DO
     536             :       END DO
     537             : 
     538             :       ! 2) C --> H
     539             :       CALL create_hermite_to_cartesian(alpha, l_max, h_to_c)
     540     9453605 :       S_R = MATMUL(TRANSPOSE(h_to_c(0:l_max, 0:l_max)), S_R)*SQRT(alpha/pi)
     541     4425368 :    END SUBROUTINE pgf_sum_2c_rspace_1d
     542             : 
     543             : ! **************************************************************************************************
     544             : !> \brief Roughly estimated number of floating point operations
     545             : !> \param ns_R ...
     546             : !> \param l ...
     547             : !> \param m ...
     548             : !> \return ...
     549             : ! **************************************************************************************************
     550      146608 :    PURE FUNCTION nsum_2c_rspace_3d(ns_R, l, m)
     551             :       REAL(KIND=dp), INTENT(IN)                          :: ns_R
     552             :       INTEGER, INTENT(IN)                                :: l, m
     553             :       INTEGER(KIND=int_8)                                :: nsum_2c_rspace_3d
     554             : 
     555      146608 :       nsum_2c_rspace_3d = NINT(ns_R*(exp_w + ncoset(l + m)*(4 + ncoset(l + m)*4)), KIND=int_8)
     556      146608 :    END FUNCTION
     557             : 
     558             : ! **************************************************************************************************
     559             : !> \brief As pgf_sum_2c_rspace_1d but 3d sum required for non-orthorhombic cells
     560             : !> \param S_R ...
     561             : !> \param l_max ...
     562             : !> \param R ...
     563             : !> \param alpha ...
     564             : !> \param hmat ...
     565             : !> \param h_inv ...
     566             : !> \param R_c ...
     567             : !> \param R_rad ...
     568             : !> \note  MMME Method is not very efficient for non-orthorhombic cells
     569             : ! **************************************************************************************************
     570      128219 :    PURE SUBROUTINE pgf_sum_2c_rspace_3d(S_R, l_max, R, alpha, hmat, h_inv, R_c, R_rad)
     571             :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: S_R
     572             :       INTEGER, INTENT(IN)                                :: l_max
     573             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R
     574             :       REAL(KIND=dp), INTENT(IN)                          :: alpha
     575             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
     576             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R_c
     577             :       REAL(KIND=dp), INTENT(IN)                          :: R_rad
     578             : 
     579             :       INTEGER                                            :: k, l, lco, llx, lly, llz, lx, ly, lz, &
     580             :                                                             sx, sy, sz
     581             :       REAL(KIND=dp)                                      :: exp_tot, R_rad_sq, R_sq
     582      128219 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: h_to_c
     583             :       REAL(KIND=dp), DIMENSION(3)                        :: R_l, R_r, Rp, Rx, Ry, Rz, s_shift
     584      256438 :       REAL(KIND=dp), DIMENSION(3, 0:l_max)               :: R_pow_l
     585      128219 :       REAL(KIND=dp), DIMENSION(ncoset(l_max))            :: S_R_C
     586             : 
     587     2057776 :       S_R(:) = 0.0_dp
     588     2057776 :       S_R_C(:) = 0.0_dp
     589             : 
     590     2051504 :       s_shift = MATMUL(h_inv, -R)
     591      512876 :       R_l = -R_c + s_shift
     592      512876 :       R_r = R_c + s_shift
     593             : 
     594      128219 :       R_rad_sq = R_rad**2
     595             : 
     596      432234 :       DO sx = CEILING(R_l(1)), FLOOR(R_r(1))
     597     1216060 :          Rx = hmat(:, 1)*sx
     598     1470931 :          DO sy = CEILING(R_l(2)), FLOOR(R_r(2))
     599     4154788 :             Ry = hmat(:, 2)*sy
     600     5870059 :             DO sz = CEILING(R_l(3)), FLOOR(R_r(3))
     601    18109388 :                Rz = hmat(:, 3)*sz
     602    18109388 :                Rp = Rx + Ry + Rz
     603     4527347 :                R_sq = (Rp(1) + R(1))**2 + (Rp(2) + R(2))**2 + (Rp(3) + R(3))**2
     604     4527347 :                IF (R_sq .GT. R_rad_sq) CYCLE
     605     1814156 :                exp_tot = EXP(-alpha*R_sq) ! cost: exp_w flops
     606     7256624 :                DO k = 1, 3
     607     5442468 :                   R_pow_l(k, 0) = 1.0_dp
     608    16096739 :                   DO l = 1, l_max
     609    14282583 :                      R_pow_l(k, l) = R_pow_l(k, l - 1)*(Rp(k) + R(k))
     610             :                   END DO
     611             :                END DO
     612    22199618 :                DO lco = 1, ncoset(l_max)
     613    19346765 :                   CALL get_l(lco, l, lx, ly, lz)
     614    23874112 :                   S_R_C(coset(lx, ly, lz)) = S_R_C(coset(lx, ly, lz)) + R_pow_l(1, lx)*R_pow_l(2, ly)*R_pow_l(3, lz)*exp_tot ! cost: 4 flops
     615             :                END DO
     616             :             END DO
     617             :          END DO
     618             :       END DO
     619             : 
     620             :       CALL create_hermite_to_cartesian(alpha, l_max, h_to_c)
     621             : 
     622     2057776 :       DO lco = 1, ncoset(l_max)
     623     1929557 :          CALL get_l(lco, l, lx, ly, lz)
     624             : 
     625     5692372 :          DO llx = 0, lx
     626    11963703 :          DO lly = 0, ly
     627    20729884 :          DO llz = 0, lz
     628             :             S_R(coset(lx, ly, lz)) = S_R(coset(lx, ly, lz)) + & ! cost: 4 flops
     629             :                                      h_to_c(llx, lx)*h_to_c(lly, ly)*h_to_c(llz, lz)* &
     630    17095288 :                                      S_R_C(coset(llx, lly, llz))
     631             :          END DO
     632             :          END DO
     633             :          END DO
     634             :       END DO
     635     2057776 :       S_R(:) = S_R(:)*(alpha/pi)**1.5_dp
     636             : 
     637      256438 :    END SUBROUTINE pgf_sum_2c_rspace_3d
     638             : 
     639             : ! **************************************************************************************************
     640             : !> \brief Compute 1d sum
     641             : !>        S_G(l, alpha) = inv_lgth*sum_G( C(l, alpha, delta_l, G) ) with
     642             : !>          C(l, alpha, delta_l, G) = prefactor*|G|^(l-delta_l) exp(-alpha*G^2)
     643             : !>          if G not equal 0
     644             : !>          C(l = 0, alpha, delta_l, 0) = 1, C(l>0, alpha, delta_l, 0) = 0
     645             : !>        dG = inv_lgth*twopi and G = -G_bound*dG, (-G_bound + 1)*dG, ..., G_bound*dG
     646             : !>        for all l < = l_max.
     647             : !> \param S_G ...
     648             : !> \param alpha ...
     649             : !> \param inv_lgth ...
     650             : !> \param G_min ...
     651             : !> \param G_c ...
     652             : !> \param delta_l ...
     653             : !> \param prefactor ...
     654             : !> \note  needed for cutoff error estimate
     655             : ! **************************************************************************************************
     656      295044 :    PURE SUBROUTINE pgf_sum_2c_gspace_1d_deltal(S_G, alpha, inv_lgth, G_min, G_c, delta_l, prefactor)
     657             :       REAL(KIND=dp), DIMENSION(0:), INTENT(OUT)          :: S_G
     658             :       REAL(KIND=dp), INTENT(IN)                          :: alpha, inv_lgth
     659             :       INTEGER, INTENT(IN)                                :: G_min, G_c
     660             :       REAL(KIND=dp), INTENT(IN)                          :: delta_l, prefactor
     661             : 
     662             :       INTEGER                                            :: k, k0, k1, l, l_max
     663             :       REAL(KIND=dp)                                      :: dG, exp_tot, G, prefac
     664             : 
     665      295044 :       prefac = prefactor*inv_lgth
     666      295044 :       dG = inv_lgth*twopi ! positive
     667      295044 :       l_max = UBOUND(S_G, 1)
     668             : 
     669     1660104 :       S_G(:) = 0.0_dp
     670      295044 :       IF (0 .LT. G_min) THEN
     671             :          k0 = G_min; k1 = 0
     672       73761 :       ELSE IF (G_c .LT. 0) THEN
     673             :          k0 = 0; k1 = G_c
     674             :       ELSE ! Gmin <= 0 /\ 0 <= Gc
     675       73761 :          S_G(0) = prefac
     676             :          k0 = 1; k1 = -1
     677             :       END IF
     678             :       ! positive range
     679             :       IF (0 .LT. k0) THEN
     680    14185303 :          DO k = k0, G_c
     681    13890259 :             G = k*dG; exp_tot = EXP(-alpha*G**2)*prefac
     682    83043248 :             DO l = 0, l_max
     683    82748204 :                S_G(l) = S_G(l) + G**(l - delta_l)*exp_tot
     684             :             END DO
     685             :          END DO
     686             :       END IF
     687             :       ! negative range
     688      295044 :       IF (k1 .LT. 0) THEN
     689     4816941 :          DO k = G_min, k1
     690     4743180 :             G = k*dG; exp_tot = EXP(-alpha*G**2)*prefac
     691    27823869 :             DO l = 0, l_max
     692    27750108 :                S_G(l) = S_G(l) + ABS(G)**(l - delta_l)*exp_tot
     693             :             END DO
     694             :          END DO
     695             :       END IF
     696      295044 :    END SUBROUTINE pgf_sum_2c_gspace_1d_deltal
     697             : 
     698             : ! **************************************************************************************************
     699             : !> \brief Compute Ewald-like sum for 3-center integrals in 1 dimension
     700             : !>        S_G(l, m, n, alpha, beta, gamma) = i^(l+m+n)*(-1)^(l+m)*inv_lgth^2*
     701             : !>                                           sum_G sum_G'( exp(i G R1)
     702             : !>                                           C(l,alpha,G) C(m,beta,G'-G) C(n,gamma,G') exp(i G' R2) )
     703             : !>        for all l < = l_max, m <= m_max, n <= n_max.
     704             : !>        a_mm is the minimax exponent.
     705             : !>        alpha =  1/(4 zeta), beta = 1/(4 zetb), gamma = 1/(4 zetc) + a_mm
     706             : !>        R1 = RB-RA; R2 = RC-RB
     707             : !>        Note on method / order arguments:
     708             : !>        Three equivalent methods (Poisson summation) to compute this sum over
     709             : !>        Cartesian Gaussians C or Hermite Gaussians H and
     710             : !>        reciprocal lattice vectors G or direct lattice vectors R:
     711             : !>        - method 1: sum_G sum_G' C(G) C(G,G') C(G')
     712             : !>        - method 2: sum_G sum_R C(G) C(R)
     713             : !>        - method 3: sum_R sum_R' H(R, R')
     714             : !>        The order parameter selects the Gaussian functions over which the sum is performed
     715             : !>        method 1: order = 1, 2, 3
     716             : !>        method 2: order = 1, 2, 3
     717             : !>        method 3: order = 1
     718             : !>        If method and order are not present, the method / order that converges fastest is
     719             : !>        automatically chosen.
     720             : !> \param S_G ...
     721             : !> \param RA ...
     722             : !> \param RB ...
     723             : !> \param RC ...
     724             : !> \param zeta ...
     725             : !> \param zetb ...
     726             : !> \param zetc ...
     727             : !> \param a_mm ...
     728             : !> \param lgth ...
     729             : !> \param G_bounds_1 ...
     730             : !> \param R_bounds_2 ...
     731             : !> \param R_bounds_3 ...
     732             : !> \param method ...
     733             : !> \param method_out ...
     734             : !> \param order ...
     735             : ! **************************************************************************************************
     736     6324120 :    SUBROUTINE pgf_sum_3c_1d(S_G, RA, RB, RC, zeta, zetb, zetc, a_mm, lgth, R_bounds_3)
     737             :       REAL(KIND=dp), DIMENSION(0:, 0:, 0:), INTENT(OUT)  :: S_G
     738             :       REAL(KIND=dp), INTENT(IN)                          :: RA, RB, RC, zeta, zetb, zetc, a_mm, lgth
     739             :       REAL(KIND=dp), DIMENSION(2), INTENT(IN)            :: R_bounds_3
     740             : 
     741             :       INTEGER                                            :: l_max, m_max, n_max
     742             :       INTEGER                                            :: nR1, nR2
     743             :       INTEGER                                            :: prop_exp
     744             : 
     745     6324120 :       l_max = UBOUND(S_G, 1)
     746     6324120 :       m_max = UBOUND(S_G, 2)
     747     6324120 :       n_max = UBOUND(S_G, 3)
     748             : 
     749     6324120 :       nR1 = 2*FLOOR(R_bounds_3(1)) + 1
     750     6324120 :       nR2 = 2*FLOOR(R_bounds_3(2)) + 1
     751             : 
     752     6324120 :       IF (nR1*nR2 > 1 + nR1*2) THEN
     753             :          prop_exp = 1
     754             :       ELSE
     755     2997690 :          prop_exp = 0
     756             :       END IF
     757             : 
     758    25296480 :       IF (MAXVAL([l_max, m_max, n_max]) .GT. ${lmax_unroll}$) THEN
     759       92160 :          CALL pgf_sum_3c_rspace_1d_generic(S_G, RA, RB, RC, zeta, zetb, zetc, a_mm, lgth, R_bounds_3)
     760             :       ELSE
     761             :          #:for l_max in range(0,lmax_unroll+1)
     762     6231960 :             IF (l_max == ${l_max}$) THEN
     763             :                #:for m_max in range(0,lmax_unroll+1)
     764     6231960 :                   IF (m_max == ${m_max}$) THEN
     765             :                      #:for n_max in range(0, lmax_unroll+1)
     766     6231960 :                         IF (n_max == ${n_max}$) THEN
     767             :                            #:for prop_exp in range(0,2)
     768     6231960 :                               IF (prop_exp == ${prop_exp}$) THEN
     769             :                                  CALL pgf_sum_3c_rspace_1d_${l_max}$_${m_max}$_${n_max}$_exp_${prop_exp}$ (S_G, RA, RB, RC, &
     770     6231960 :                                                                                            zeta, zetb, zetc, a_mm, lgth, R_bounds_3)
     771     6231960 :                                  RETURN
     772             :                               END IF
     773             :                            #:endfor
     774             :                         END IF
     775             :                      #:endfor
     776             :                   END IF
     777             :                #:endfor
     778             :             END IF
     779             :          #:endfor
     780             :       END IF
     781             : 
     782             :    END SUBROUTINE pgf_sum_3c_1d
     783             : 
     784             : ! **************************************************************************************************
     785             : !> \brief Roughly estimated number of floating point operations
     786             : !> \param ns_G1 ...
     787             : !> \param ns_G2 ...
     788             : !> \param l ...
     789             : !> \param m ...
     790             : !> \param n ...
     791             : !> \return ...
     792             : ! **************************************************************************************************
     793           0 :    PURE FUNCTION nsum_3c_gspace_1d()
     794             :       INTEGER(KIND=int_8)                                :: nsum_3c_gspace_1d
     795             : 
     796           0 :       nsum_3c_gspace_1d = 15
     797           0 :    END FUNCTION
     798             : 
     799             : ! **************************************************************************************************
     800             : !> \brief Roughly estimated number of floating point operations
     801             : !> \param ns_G ...
     802             : !> \param ns_R ...
     803             : !> \param l ...
     804             : !> \param m ...
     805             : !> \param n ...
     806             : !> \return ...
     807             : ! **************************************************************************************************
     808           0 :    PURE FUNCTION nsum_product_3c_gspace_1d(ns_G, ns_R)
     809             :       REAL(KIND=dp), INTENT(IN) :: ns_G, ns_R
     810             :       INTEGER(KIND=int_8)                                :: nsum_product_3c_gspace_1d
     811             : 
     812           0 :       nsum_product_3c_gspace_1d = MIN(19, NINT(ns_G*(3 + ns_R*2)))
     813           0 :    END FUNCTION
     814             : 
     815             : ! **************************************************************************************************
     816             : !> \brief Roughly estimated number of floating point operations
     817             : !> \param ns_R1 ...
     818             : !> \param ns_R2 ...
     819             : !> \param l ...
     820             : !> \param m ...
     821             : !> \param n ...
     822             : !> \return ...
     823             : ! **************************************************************************************************
     824     6324120 :    PURE FUNCTION nsum_3c_rspace_1d(ns_R1, ns_R2)
     825             :       REAL(KIND=dp), INTENT(IN)                          :: ns_R1, ns_R2
     826             :       INTEGER(KIND=int_8)                                :: nsum_3c_rspace_1d
     827             : 
     828     6324120 :       nsum_3c_rspace_1d = NINT(MIN((4 + ns_R1*2), ns_R1*(ns_R2 + 1)), KIND=int_8)
     829     6324120 :    END FUNCTION
     830             : 
     831             : ! **************************************************************************************************
     832             : !> \brief Helper routine: compute SQRT(alpha/pi) (-1)^n sum_(R, R') sum_{t=0}^{l+m} E(t,l,m) H(RC - P(R) - R', t + n, alpha)
     833             : !> with alpha = 1.0_dp/((a + b + c)/((a + b)*c) + 4.0_dp*a_mm),
     834             : !> P(R) = (a*(RA + R) + b*RB)/(a + b)
     835             : !> \param S_R ...
     836             : !> \param RA ...
     837             : !> \param RB ...
     838             : !> \param RC ...
     839             : !> \param zeta ...
     840             : !> \param zetb ...
     841             : !> \param zetc ...
     842             : !> \param a_mm ...
     843             : !> \param lgth ...
     844             : !> \param R_c ...
     845             : ! **************************************************************************************************
     846       92160 :    PURE SUBROUTINE pgf_sum_3c_rspace_1d_generic(S_R, RA, RB, RC, zeta, zetb, zetc, a_mm, lgth, R_c)
     847             :       REAL(KIND=dp), DIMENSION(0:, 0:, 0:), INTENT(OUT)  :: S_R
     848             :       REAL(KIND=dp), INTENT(IN)                          :: RA, RB, RC, zeta, zetb, zetc, a_mm, lgth
     849             :       REAL(KIND=dp), DIMENSION(2), INTENT(IN)            :: R_c
     850             : 
     851             :       INTEGER                                            :: ll, mm, l, k, l_max, m, m_max, n, n_max, rr1, rr2, t, l_tot_max
     852             :       REAL(KIND=dp)                                      :: alpha, dR, exp_tot, R, R1, R2, R_offset, &
     853             :                                                             R_pow_t, R_tmp, rr1_delta, rr2_delta, c1, c2, c3
     854             :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: S_R_t
     855       92160 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: h_to_c
     856       92160 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: E
     857             : 
     858       92160 :       dR = lgth
     859       92160 :       alpha = 1.0_dp/((zeta + zetb + zetc)/((zeta + zetb)*zetc) + 4.0_dp*a_mm)
     860       92160 :       l_max = UBOUND(S_R, 1)
     861       92160 :       m_max = UBOUND(S_R, 2)
     862       92160 :       n_max = UBOUND(S_R, 3)
     863       92160 :       l_tot_max = l_max + m_max + n_max
     864             : 
     865      276480 :       ALLOCATE (S_R_t(0:l_max + m_max + n_max))
     866      460800 :       ALLOCATE (E(-1:l_max + m_max + 1, -1:l_max, -1:m_max))
     867             : 
     868     2903040 :       S_R(:, :, :) = 0.0_dp
     869             : 
     870       92160 :       R_offset = RC - (zeta*RA + zetb*RB)/(zeta + zetb)
     871             : 
     872             :       ! inline CALL create_hermite_to_cartesian(alpha, l_tot_max, h_to_c)
     873      368640 :       ALLOCATE (h_to_c(-1:l_tot_max + 1, 0:l_tot_max))
     874     8202240 :       h_to_c(:, :) = 0.0_dp
     875       92160 :       h_to_c(0, 0) = 1.0_dp
     876      737280 :       DO l = 0, l_tot_max - 1
     877     3962880 :          DO k = 0, l + 1
     878     3870720 :             h_to_c(k, l + 1) = -(k + 1)*h_to_c(k + 1, l) + 2.0_dp*alpha*h_to_c(k - 1, l)
     879             :          END DO
     880             :       END DO
     881             : 
     882       92160 :       rr1_delta = (RA - RB)/dR
     883     1428480 :       DO rr1 = CEILING(-R_c(1) + rr1_delta), FLOOR(R_c(1) + rr1_delta)
     884    12026880 :          S_R_t(:) = 0.0_dp
     885     1336320 :          R1 = rr1*dR
     886     1336320 :          R_tmp = R_offset + R1*zeta/(zeta + zetb)
     887     1336320 :          rr2_delta = -R_tmp/dR
     888    15398400 :          DO rr2 = CEILING(-R_c(2) + rr2_delta), FLOOR(R_c(2) + rr2_delta)
     889    14062080 :             R2 = rr2*dR
     890    14062080 :             R = R_tmp + R2
     891    14062080 :             exp_tot = EXP(-alpha*R**2) ! cost: exp_w flops
     892    14062080 :             R_pow_t = 1.0_dp
     893   127895040 :             DO t = 0, l_max + m_max + n_max
     894   112496640 :                S_R_t(t) = S_R_t(t) + R_pow_t*exp_tot ! cost: 2 flops
     895   126558720 :                R_pow_t = R_pow_t*R ! cost: 1 flop
     896             :             END DO
     897             :          END DO
     898             : 
     899             :          ! C --> H
     900    12026880 :          S_R_t(:) = MATMUL(TRANSPOSE(h_to_c(0:l_max + m_max + n_max, 0:l_max + m_max + n_max)), S_R_t)*SQRT(alpha/pi)
     901             : 
     902             :          ! H --> HH
     903             :          !inline CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, zeta, zetb, RA-R1, RB, 2, E)
     904             : 
     905   183191040 :          E(:, :, :) = 0.0_dp
     906     1336320 :          E(0, 0, 0) = EXP(-zeta*zetb/(zeta + zetb)*(RA - R1 - RB)**2)
     907             : 
     908     1336320 :          c1 = 1.0_dp/(zeta + zetb)
     909     1336320 :          c2 = 2.0_dp*(zetb/(zeta + zetb))*(RB - (RA - R1))
     910     1336320 :          c3 = 2.0_dp*(zeta/(zeta + zetb))*(RA - R1 - RB)
     911             : 
     912     7948800 :          DO mm = 0, m_max - 1
     913     8179200 :             DO ll = 0, l_max - 1
     914     7879680 :                DO t = 0, ll + mm + 1
     915             :                   E(t, ll + 1, mm) = zeta*(c1*E(t - 1, ll, mm) + &
     916             :                                            c2*E(t, ll, mm) + &
     917             :                                            2*(t + 1)*E(t + 1, ll, mm) - &
     918     1036800 :                                            2*ll*E(t, ll - 1, mm))
     919             :                   E(t, ll, mm + 1) = zetb*(c1*E(t - 1, ll, mm) + &
     920             :                                            c3*E(t, ll, mm) + &
     921             :                                            2*(t + 1)*E(t + 1, ll, mm) - &
     922     1267200 :                                            2*mm*E(t, ll, mm - 1))
     923             :                END DO
     924             :             END DO
     925             :          END DO
     926             : 
     927     1451520 :          DO ll = 0, l_max - 1
     928     2142720 :             DO t = 0, ll + m_max + 1
     929             :                E(t, ll + 1, m_max) = zeta*(c1*E(t - 1, ll, m_max) + &
     930             :                                            c2*E(t, ll, m_max) + &
     931             :                                            2*(t + 1)*E(t + 1, ll, m_max) - &
     932      806400 :                                            2*ll*E(t, ll - 1, m_max))
     933             :             END DO
     934             :          END DO
     935             : 
     936     7948800 :          DO mm = 0, m_max - 1
     937    34560000 :             DO t = 0, l_max + mm + 1
     938             :                E(t, l_max, mm + 1) = zetb*(c1*E(t - 1, l_max, mm) + &
     939             :                                            c3*E(t, l_max, mm) + &
     940             :                                            2*(t + 1)*E(t + 1, l_max, mm) - &
     941    33223680 :                                            2*mm*E(t, l_max, mm - 1))
     942             :             END DO
     943             :          END DO
     944             : 
     945     5391360 :          DO n = 0, n_max
     946    29007360 :             DO m = 0, m_max
     947    51724800 :                DO l = 0, l_max
     948   132364800 :                   DO t = 0, l + m
     949   108656640 :                      S_R(l, m, n) = S_R(l, m, n) + E(t, l, m)*(-1)**n*S_R_t(t + n) ! cost: 5 flops
     950             :                   END DO
     951             :                END DO
     952             :             END DO
     953             :          END DO
     954             :       END DO
     955             : 
     956     2903040 :       S_R = S_R*pi**(-0.5_dp)*((zeta + zetb)/(zeta*zetb))**(-0.5_dp)
     957       92160 :    END SUBROUTINE
     958             : 
     959             : ! **************************************************************************************************
     960             : !> \brief Helper routine: compute SQRT(alpha/pi) (-1)^n sum_(R, R') sum_{t=0}^{l+m} E(t,l,m) H(RC - P(R) - R', t + n, alpha)
     961             : !> with alpha = 1.0_dp/((a + b + c)/((a + b)*c) + 4.0_dp*a_mm),
     962             : !> P(R) = (a*(RA + R) + b*RB)/(a + b)
     963             : !> \param S_R ...
     964             : !> \param RA ...
     965             : !> \param RB ...
     966             : !> \param RC ...
     967             : !> \param zeta ...
     968             : !> \param zetb ...
     969             : !> \param zetc ...
     970             : !> \param a_mm ...
     971             : !> \param lgth ...
     972             : !> \param R_c ...
     973             : ! **************************************************************************************************
     974             :    #:for prop_exp in range(0,2)
     975             :       #:for l_max in range(0, lmax_unroll+1)
     976             :          #:for m_max in range(0, lmax_unroll+1)
     977             :             #:for n_max in range(0, lmax_unroll+1)
     978             :                #:set l_tot_max = l_max + m_max + n_max
     979     6231960 :                PURE SUBROUTINE pgf_sum_3c_rspace_1d_${l_max}$_${m_max}$_${n_max}$_exp_${prop_exp}$ ( &
     980     6231960 :                   S_R, RA, RB, RC, zeta, zetb, zetc, a_mm, lgth, R_c)
     981             :                   REAL(KIND=dp), DIMENSION(0:, 0:, 0:), INTENT(OUT)  :: S_R
     982             :                   REAL(KIND=dp), INTENT(IN)                          :: RA, RB, RC, zeta, zetb, zetc, a_mm, lgth
     983             :                   REAL(KIND=dp), DIMENSION(2), INTENT(IN)            :: R_c
     984             :                   INTEGER                                            :: rr1, rr2, rr2_l, rr2_r, rr1_l, rr1_r
     985             :                   REAL(KIND=dp)                                      :: alpha, alpha_E, dR, exp2_Rsq, R, R1, R_offset, &
     986             :                                                                         R_pow_t, R_tmp, rr1_delta, rr2_delta
     987             : 
     988             :                   #:if l_tot_max > 0
     989             :                      REAL(KIND=dp)                                      :: c1, c2, c3
     990             :                   #:endif
     991             :                   REAL(KIND=dp) :: ${", ".join(["S_R_t_{}".format(t) for t in range(0,l_tot_max+1)])}$
     992             :                   REAL(KIND=dp) :: ${", ".join(["S_R_t2_{}".format(t) for t in range(0,l_tot_max+1)])}$
     993             :   REAL(KIND=dp) :: ${", ".join([", ".join(["h_to_c_{}_{}".format(l1,l2) for l1 in range(0,l2+1)]) for l2 in range(0,l_tot_max+1)])}$
     994             :       REAL(KIND=dp) :: ${", ".join([", ".join([", ".join(["E_{}_{}_{}".format(t,l,m) for t in range(0,l+m+1)]) for l in range(0,l_max+1)]) for m in range(0,m_max+1)])}$
     995             : 
     996             :                   #:if prop_exp
     997             :                      REAL(KIND=dp) :: exp2_2RdR, exp_dRsq, exp_2dRsq !exp_E_dRsq, exp_E_2dRsq, exp_E_2RdR, exp_E_Rsq
     998             :                   #:endif
     999             : 
    1000     6231960 :                   dR = lgth
    1001     6231960 :                   alpha = 1.0_dp/((zeta + zetb + zetc)/((zeta + zetb)*zetc) + 4.0_dp*a_mm)
    1002             : 
    1003   113325552 :                   S_R(:, :, :) = 0.0_dp
    1004             : 
    1005     6231960 :                   R_offset = RC - (zeta*RA + zetb*RB)/(zeta + zetb)
    1006             : 
    1007     6231960 :                   h_to_c_0_0 = SQRT(alpha/pi)
    1008             : 
    1009             :                   #:for l in range(0, l_tot_max)
    1010             :                      #:for k in range(0, l+2)
    1011             :                         #:if k<l or k>0
    1012     5509656 :                            h_to_c_${k}$_${l+1}$ = #{if k<l}#-${k+1}$*h_to_c_${k+1}$_${l}$#{endif}# #{if k > 0}#+2*alpha*h_to_c_${k-1}$_${l}$#{endif}#
    1013             :                         #:else
    1014     5509656 :                            h_to_c_${k}$_${l+1}$ = 0.0_dp
    1015             :                         #:endif
    1016             :                      #:endfor
    1017             :                   #:endfor
    1018             : 
    1019             :                   #:if prop_exp
    1020     3268062 :                      exp_dRsq = exp(-alpha*dR*dR)
    1021     3268062 :                      exp_2dRsq = exp_dRsq*exp_dRsq
    1022             :                   #:endif
    1023             : 
    1024     6231960 :                   rr1_delta = (RA - RB)/dR
    1025             : 
    1026     6231960 :                   rr1_l = CEILING(-R_c(1) + rr1_delta)
    1027     6231960 :                   rr1_r = FLOOR(R_c(1) + rr1_delta)
    1028             : 
    1029     6231960 :                   R1 = rr1_l*dR
    1030             : 
    1031     6231960 :                   alpha_E = zeta*zetb/(zeta + zetb)
    1032             : 
    1033    20231352 :                   DO rr1 = rr1_l, rr1_r
    1034             :                      #:for t in range(0, l_tot_max + 1)
    1035    13999392 :                         S_R_t_${t}$ = 0.0_dp
    1036    13999392 :                         S_R_t2_${t}$ = 0.0_dp
    1037             :                      #:endfor
    1038    13999392 :                      R_tmp = R_offset + R1*zeta/(zeta + zetb)
    1039    13999392 :                      rr2_delta = -R_tmp/dR
    1040             : 
    1041    13999392 :                      rr2_l = CEILING(-R_c(2) + rr2_delta)
    1042    13999392 :                      rr2_r = FLOOR(R_c(2) + rr2_delta)
    1043             : 
    1044    13999392 :                      R = R_tmp + (rr2_l)*dR
    1045             : 
    1046             :                      #:if prop_exp
    1047     9119092 :                         exp2_2RdR = exp(-2*alpha*R*dR)
    1048     9119092 :                         exp2_Rsq = exp(-alpha*R*R)
    1049             :                      #:endif
    1050             : 
    1051    71598485 :                      DO rr2 = rr2_l, rr2_r
    1052    57599093 :                         R_pow_t = 1.0_dp
    1053             :                         #:if not prop_exp
    1054     7179779 :                            exp2_Rsq = exp(-alpha*R*R)
    1055             :                         #:endif
    1056             :                         #:for t in range(0, l_tot_max + 1)
    1057    57599093 :                            S_R_t_${t}$ = S_R_t_${t}$+R_pow_t*exp2_Rsq
    1058             :                            #:if t<l_tot_max
    1059    51468255 :                               R_pow_t = R_pow_t*R
    1060             :                            #:endif
    1061             :                         #:endfor
    1062             : 
    1063             :                         #:if prop_exp
    1064    50419314 :                            exp2_Rsq = exp2_Rsq*exp_dRsq*exp2_2RdR
    1065    50419314 :                            exp2_2RdR = exp2_2RdR*exp_2dRsq
    1066             :                         #:endif
    1067    71598485 :                         R = R + dR
    1068             :                      END DO
    1069             : 
    1070             :                      ! C --> H
    1071             :                      #:for l in range(0, l_tot_max+1)
    1072             :                         #:for k in range(0, l+1)
    1073    13999392 :                            S_R_t2_${l}$ = S_R_t2_${l}$+h_to_c_${k}$_${l}$*S_R_t_${k}$
    1074             :                         #:endfor
    1075             :                      #:endfor
    1076             : 
    1077             :                      ! H --> HH
    1078    13999392 :                      E_0_0_0 = exp(-alpha_E*(RA - RB - R1)*(RA - RB - R1))
    1079             : 
    1080             :                      #:if l_tot_max > 0
    1081    12382032 :                         c1 = 1.0_dp/(zeta + zetb)
    1082    12382032 :                         c2 = 2.0_dp*(zetb/(zeta + zetb))*(RB - (RA - R1))
    1083    12382032 :                         c3 = 2.0_dp*(zeta/(zeta + zetb))*(RA - R1 - RB)
    1084             :                      #:endif
    1085             : 
    1086             :                      #:for m in range(0,m_max+1)
    1087             :                         #:for l in range(0,l_max+1)
    1088             :                            #:for t in range(0,l+m+2)
    1089             :                               #:if l < l_max
    1090             :                                  E_${t}$_${l+1}$_${m}$ = zeta*(#{if t>0}# c1*E_${t-1}$_${l}$_${m}$#{endif}# &
    1091             :                                  #{if t<=l+m}# +c2*E_${t}$_${l}$_${m}$&#{endif}#
    1092             :                                  #{if t<l+m}# +${2*(t+1)}$*E_${t+1}$_${l}$_${m}$ &#{endif}#
    1093     8760456 :                                  #{if l>0 and t<=l-1+m}#-${2*l}$*E_${t}$_${l-1}$_${m}$#{endif}#)
    1094             :                               #:endif
    1095             :                               #:if m < m_max
    1096             :                                  E_${t}$_${l}$_${m+1}$ = zetb*(#{if t>0}# c1*E_${t-1}$_${l}$_${m}$#{endif}# &
    1097             :                                  #{if t<=l+m}#+c3*E_${t}$_${l}$_${m}$&#{endif}#
    1098             :                                  #{if t<l+m}# +${2*(t+1)}$*E_${t+1}$_${l}$_${m}$ &#{endif}#
    1099     8761656 :                                  #{if m>0 and t<=m-1+l}#-${2*m}$*E_${t}$_${l}$_${m-1}$#{endif}#)
    1100             :                               #:endif
    1101             :                            #:endfor
    1102             :                         #:endfor
    1103             :                      #:endfor
    1104             : 
    1105             :                      #:for n in range(0, n_max+1)
    1106             :                         #:for m in range(0, m_max+1)
    1107             :                            #:for l in range(0, l_max+1)
    1108             :                               #:for t in range(0, l+m+1)
    1109    13999392 :               S_R(${l}$, ${m}$, ${n}$) = S_R(${l}$, ${m}$, ${n}$) + E_${t}$_${l}$_${m}$*(${(-1)**n}$)*S_R_t2_${t+n}$ ! cost: 5 flops
    1110             :                               #:endfor
    1111             :                            #:endfor
    1112             :                         #:endfor
    1113             :                      #:endfor
    1114    20231352 :                      R1 = R1 + dR
    1115             :                   END DO
    1116             : 
    1117   113325552 :                   S_R = S_R*pi**(-0.5_dp)*((zeta + zetb)/(zeta*zetb))**(-0.5_dp)
    1118     6231960 :                END SUBROUTINE
    1119             :             #:endfor
    1120             :          #:endfor
    1121             :       #:endfor
    1122             :    #:endfor
    1123             : 
    1124             : ! **************************************************************************************************
    1125             : !> \brief As pgf_sum_3c_1d but 3d sum required for non-orthorhombic cells
    1126             : !> \param S_G ...
    1127             : !> \param la_max ...
    1128             : !> \param lb_max ...
    1129             : !> \param lc_max ...
    1130             : !> \param RA ...
    1131             : !> \param RB ...
    1132             : !> \param RC ...
    1133             : !> \param zeta ...
    1134             : !> \param zetb ...
    1135             : !> \param zetc ...
    1136             : !> \param a_mm ...
    1137             : !> \param hmat ...
    1138             : !> \param h_inv ...
    1139             : !> \param vol ...
    1140             : !> \param G_bounds_1 ...
    1141             : !> \param R_bounds_2 ...
    1142             : !> \param R_bounds_3 ...
    1143             : !> \param G_rads_1 ...
    1144             : !> \param R_rads_2 ...
    1145             : !> \param R_rads_3 ...
    1146             : !> \param method ...
    1147             : !> \param method_out ...
    1148             : !> \param order ...
    1149             : ! **************************************************************************************************
    1150      148500 :    SUBROUTINE pgf_sum_3c_3d(S_G, la_max, lb_max, lc_max, RA, RB, RC, &
    1151             :                             zeta, zetb, zetc, a_mm, hmat, h_inv, vol, &
    1152             :                             G_bounds_1, R_bounds_2, R_bounds_3, &
    1153             :                             G_rads_1, R_rads_2, R_rads_3, &
    1154             :                             method, method_out, order)
    1155             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)     :: S_G
    1156             :       INTEGER, INTENT(IN)                                :: la_max, lb_max, lc_max
    1157             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: RA, RB, RC
    1158             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, zetc, a_mm
    1159             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
    1160             :       REAL(KIND=dp), INTENT(IN)                          :: vol
    1161             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: G_bounds_1, R_bounds_2
    1162             :       REAL(KIND=dp), DIMENSION(2, 3), INTENT(IN)         :: R_bounds_3
    1163             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G_rads_1, R_rads_2
    1164             :       REAL(KIND=dp), DIMENSION(2), INTENT(IN)            :: R_rads_3
    1165             :       INTEGER, INTENT(IN)                                :: method
    1166             :       INTEGER, INTENT(OUT), OPTIONAL                     :: method_out
    1167             :       INTEGER, INTENT(IN), OPTIONAL                      :: order
    1168             : 
    1169             :       INTEGER                                            :: l_max, m_max, n_max, sum_method, &
    1170             :                                                             sum_order
    1171             :       LOGICAL                                            :: assert_stm
    1172             :       REAL(KIND=dp)                                      :: alpha, beta, G_rad, gamma, R_rad
    1173      148500 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: S_G_tmp
    1174             :       REAL(KIND=dp), DIMENSION(3)                        :: G_bound, R1, R2, R_bound
    1175             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: ht
    1176             : 
    1177      148500 :       IF (PRESENT(order)) THEN
    1178           0 :          sum_order = order
    1179             :       ELSE
    1180      148500 :          sum_order = 0
    1181             :       END IF
    1182             : 
    1183      148500 :       sum_method = method
    1184             : 
    1185      148500 :       alpha = 0.25_dp/zeta
    1186      148500 :       beta = 0.25_dp/zetb
    1187      148500 :       gamma = 0.25_dp/zetc + a_mm
    1188             : 
    1189      148500 :       l_max = la_max
    1190      148500 :       m_max = lb_max
    1191      148500 :       n_max = lc_max
    1192             : 
    1193      594000 :       R1 = RB - RA
    1194      594000 :       R2 = RC - RB
    1195             : 
    1196     1930500 :       ht = twopi*TRANSPOSE(h_inv)
    1197             : 
    1198           0 :       SELECT CASE (sum_method)
    1199             :       CASE (1) ! sum_G sum_G' C(G) C(G,G') C(G')
    1200             : 
    1201           0 :          IF (sum_order .EQ. 0) THEN
    1202           0 :             sum_order = MAXLOC(G_bounds_1(:, 1), DIM=1)
    1203             :             assert_stm = MINLOC(G_bounds_1(:, 1), DIM=1) == &
    1204             :                MINLOC(G_bounds_1(:, 2), DIM=1) .AND. &
    1205             :                MINLOC(G_bounds_1(:, 1), DIM=1) == &
    1206           0 :                MINLOC(G_bounds_1(:, 3), DIM=1)
    1207           0 :             CPASSERT(assert_stm)
    1208             :          END IF
    1209             : 
    1210           0 :          CALL pgf_sum_3c_gspace_3d(S_G, l_max, m_max, n_max, R1, R2, alpha, beta, gamma, ht, vol, G_bounds_1, G_rads_1, sum_order)
    1211             : 
    1212             :       CASE (2) ! sum_G sum_R C(G) C(R)
    1213        5846 :          IF (sum_order .EQ. 0) THEN
    1214       23384 :             sum_order = MINLOC(G_bounds_1(:, 1), DIM=1)
    1215             :             assert_stm = MINLOC(G_bounds_1(:, 1), DIM=1) == &
    1216             :                MINLOC(G_bounds_1(:, 2), DIM=1) .AND. &
    1217             :                MINLOC(G_bounds_1(:, 1), DIM=1) == &
    1218       93536 :                MINLOC(G_bounds_1(:, 3), DIM=1)
    1219           0 :             CPASSERT(assert_stm)
    1220             :          END IF
    1221        5846 :          R_rad = R_rads_2(sum_order)
    1222        5846 :          G_rad = G_rads_1(sum_order)
    1223       23384 :          R_bound = R_bounds_2(sum_order, :)
    1224       23384 :          G_bound = G_bounds_1(sum_order, :)
    1225      142654 :          SELECT CASE (sum_order)
    1226             :          CASE (1)
    1227           0 :             ALLOCATE (S_G_tmp(ncoset(l_max), ncoset(m_max), ncoset(n_max)))
    1228             :             CALL pgf_sum_product_3c_gspace_3d(S_G_tmp, l_max, m_max, n_max, R1, R2, alpha, beta, gamma, hmat, h_inv, vol, &
    1229           0 :                                               R_bound, G_bound, R_rad, G_rad)
    1230           0 :             S_G = RESHAPE(S_G_tmp, SHAPE(S_G), order=[1, 2, 3])
    1231             :          CASE (2)
    1232           0 :             ALLOCATE (S_G_tmp(ncoset(m_max), ncoset(l_max), ncoset(n_max)))
    1233             :             CALL pgf_sum_product_3c_gspace_3d(S_G_tmp, m_max, l_max, n_max, -R1, R1 + R2, beta, alpha, gamma, hmat, h_inv, vol, &
    1234           0 :                                               R_bound, G_bound, R_rad, G_rad)
    1235           0 :             S_G = RESHAPE(S_G_tmp, SHAPE(S_G), order=[2, 1, 3])
    1236             :          CASE (3)
    1237       29230 :             ALLOCATE (S_G_tmp(ncoset(n_max), ncoset(m_max), ncoset(l_max)))
    1238             :             CALL pgf_sum_product_3c_gspace_3d(S_G_tmp, n_max, m_max, l_max, -R2, -R1, gamma, beta, alpha, hmat, h_inv, vol, &
    1239       40922 :                                               R_bound, G_bound, R_rad, G_rad)
    1240       23384 :             S_G = RESHAPE(S_G_tmp, SHAPE(S_G), order=[3, 2, 1])
    1241             :          END SELECT
    1242             :       CASE (3) ! sum_R sum_R' H(R, R')
    1243             :          CALL pgf_sum_3c_rspace_3d(S_G, l_max, m_max, n_max, RA, RB, RC, zeta, zetb, zetc, a_mm, hmat, h_inv, &
    1244      142654 :                                    R_bounds_3, R_rads_3)
    1245    24412738 :          S_G = S_G*pi**(-1.5_dp)*((zeta + zetb)/(zeta*zetb))**(-1.5_dp)
    1246             :       END SELECT
    1247             : 
    1248      148500 :       IF (PRESENT(method_out)) method_out = sum_method
    1249             : 
    1250      148500 :    END SUBROUTINE pgf_sum_3c_3d
    1251             : 
    1252             : ! **************************************************************************************************
    1253             : !> \brief Roughly estimated number of floating point operations
    1254             : !> \param ns_G1 ...
    1255             : !> \param ns_G2 ...
    1256             : !> \param l ...
    1257             : !> \param m ...
    1258             : !> \param n ...
    1259             : !> \return ...
    1260             : ! **************************************************************************************************
    1261      148500 :    PURE FUNCTION nsum_3c_gspace_3d(ns_G1, ns_G2, l, m, n)
    1262             :       REAL(KIND=dp), INTENT(IN)                          :: ns_G1, ns_G2
    1263             :       INTEGER, INTENT(IN)                                :: l, m, n
    1264             :       INTEGER(KIND=int_8)                                :: nsum_3c_gspace_3d
    1265             : 
    1266      148500 :       nsum_3c_gspace_3d = NINT(ns_G1*ns_G2*(5*exp_w + ncoset(l)*ncoset(m)*ncoset(n)*4), KIND=int_8)
    1267             : 
    1268      148500 :    END FUNCTION
    1269             : 
    1270             : ! **************************************************************************************************
    1271             : !> \brief ...
    1272             : !> \param S_G ...
    1273             : !> \param l_max ...
    1274             : !> \param m_max ...
    1275             : !> \param n_max ...
    1276             : !> \param R1 ...
    1277             : !> \param R2 ...
    1278             : !> \param alpha ...
    1279             : !> \param beta ...
    1280             : !> \param gamma ...
    1281             : !> \param ht ...
    1282             : !> \param vol ...
    1283             : !> \param G_c ...
    1284             : !> \param G_rad ...
    1285             : !> \param sum_order ...
    1286             : !> \param coulomb ...
    1287             : ! **************************************************************************************************
    1288           0 :    PURE SUBROUTINE pgf_sum_3c_gspace_3d(S_G, l_max, m_max, n_max, R1, R2, alpha, beta, gamma, &
    1289             :                                         ht, vol, G_c, G_rad, sum_order, coulomb)
    1290             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)     :: S_G
    1291             :       INTEGER, INTENT(IN)                                :: l_max, m_max, n_max
    1292             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R1, R2
    1293             :       REAL(KIND=dp), INTENT(IN)                          :: alpha, beta, gamma
    1294             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: ht
    1295             :       REAL(KIND=dp), INTENT(IN)                          :: vol
    1296             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: G_c
    1297             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G_rad
    1298             :       INTEGER, INTENT(IN)                                :: sum_order
    1299             :       LOGICAL, INTENT(IN), OPTIONAL                      :: coulomb
    1300             : 
    1301             :       INTEGER, DIMENSION(3)                              :: G1c, G2c, G3c
    1302             :       INTEGER                                            :: g1x, g1y, g1z, g2x, g2y, g2z, g3x, g3y, &
    1303             :                                                             g3z
    1304             :       COMPLEX(KIND=dp), DIMENSION(ncoset(l_max), ncoset( &
    1305           0 :                                   m_max), ncoset(n_max))                          :: S_G_c
    1306             :       LOGICAL                                            :: use_coulomb
    1307             :       REAL(KIND=dp)                                      :: G1_sq, G2_sq, G3_sq
    1308             :       REAL(KIND=dp), DIMENSION(3)                        :: G1, G1_x, G1_y, G1_z, G2, G2_x, G2_y, &
    1309             :                                                             G2_z, G3, G3_x, G3_y, G3_z, G_rads_sq
    1310             : 
    1311           0 :       S_G_c(:, :, :) = 0.0_dp
    1312             : 
    1313           0 :       G1c = FLOOR(G_c(1, :))
    1314           0 :       G2c = FLOOR(G_c(2, :))
    1315           0 :       G3c = FLOOR(G_c(3, :))
    1316             : 
    1317             :       ! we can not precompute exponentials for general cell
    1318             :       ! Perform double G sum
    1319           0 :       G_rads_sq = G_rad**2
    1320             : 
    1321           0 :       IF (PRESENT(coulomb)) THEN
    1322           0 :          use_coulomb = coulomb
    1323             :       ELSE
    1324           0 :          use_coulomb = .FALSE.
    1325             :       END IF
    1326             : 
    1327           0 :       SELECT CASE (sum_order)
    1328             :       CASE (1)
    1329           0 :          DO g2x = -G2c(1), G2c(1)
    1330           0 :             G2_x = ht(:, 1)*g2x
    1331           0 :             DO g2y = -G2c(2), G2c(2)
    1332           0 :                G2_y = ht(:, 2)*g2y
    1333           0 :                DO g2z = -G2c(3), G2c(3)
    1334           0 :                   G2_z = ht(:, 3)*g2z
    1335           0 :                   G2 = G2_x + G2_y + G2_z
    1336           0 :                   G2_sq = G2(1)**2 + G2(2)**2 + G2(3)**2
    1337           0 :                   IF (G2_sq .GT. G_rads_sq(2)) CYCLE
    1338           0 :                   DO g3x = -G3c(1), G3c(1)
    1339           0 :                      G3_x = ht(:, 1)*g3x
    1340           0 :                      DO g3y = -G3c(2), G3c(2)
    1341           0 :                         G3_y = ht(:, 2)*g3y
    1342           0 :                         DO g3z = -G3c(3), G3c(3)
    1343           0 :                            G3_z = ht(:, 3)*g3z
    1344           0 :                            G3 = G3_x + G3_y + G3_z
    1345           0 :                            G3_sq = G3(1)**2 + G3(2)**2 + G3(3)**2
    1346           0 :                            IF (G3_sq .GT. G_rads_sq(3)) CYCLE
    1347           0 :                            G1 = G3 - G2
    1348           0 :                            G1_sq = G1(1)**2 + G1(2)**2 + G1(3)**2
    1349           0 :                            IF (G1_sq .GT. G_rads_sq(1)) CYCLE
    1350           0 :                            IF (use_coulomb) THEN
    1351           0 :                               IF (g3x == 0 .AND. g3y == 0 .AND. g3z == 0) CYCLE
    1352             :                            END IF
    1353             :                            CALL pgf_product_3c_gspace_3d(S_G_c, G1, G1_sq, G2, G2_sq, G3, G3_sq, l_max, m_max, n_max, &
    1354           0 :                                                          alpha, beta, gamma, R1, R2, use_coulomb)
    1355             :                         END DO
    1356             :                      END DO
    1357             :                   END DO
    1358             :                END DO
    1359             :             END DO
    1360             :          END DO
    1361             :       CASE (2)
    1362           0 :          DO g1x = -G1c(1), G1c(1)
    1363           0 :             G1_x = ht(:, 1)*g1x
    1364           0 :             DO g1y = -G1c(2), G1c(2)
    1365           0 :                G1_y = ht(:, 2)*g1y
    1366           0 :                DO g1z = -G1c(3), G1c(3)
    1367           0 :                   G1_z = ht(:, 3)*g1z
    1368           0 :                   G1 = G1_x + G1_y + G1_z
    1369           0 :                   G1_sq = G1(1)**2 + G1(2)**2 + G1(3)**2
    1370           0 :                   IF (G1_sq .GT. G_rads_sq(1)) CYCLE
    1371           0 :                   DO g3x = -G3c(1), G3c(1)
    1372           0 :                      G3_x = ht(:, 1)*g3x
    1373           0 :                      DO g3y = -G3c(2), G3c(2)
    1374           0 :                         G3_y = ht(:, 2)*g3y
    1375           0 :                         DO g3z = -G3c(3), G3c(3)
    1376           0 :                            G3_z = ht(:, 3)*g3z
    1377           0 :                            G3 = G3_x + G3_y + G3_z
    1378           0 :                            G3_sq = G3(1)**2 + G3(2)**2 + G3(3)**2
    1379           0 :                            IF (G3_sq .GT. G_rads_sq(3)) CYCLE
    1380           0 :                            G2 = G3 - G1
    1381           0 :                            G2_sq = G2(1)**2 + G2(2)**2 + G2(3)**2
    1382           0 :                            IF (G2_sq .GT. G_rads_sq(2)) CYCLE
    1383           0 :                            IF (use_coulomb) THEN
    1384           0 :                               IF (g3x == 0 .AND. g3y == 0 .AND. g3z == 0) CYCLE
    1385             :                            END IF
    1386             :                            CALL pgf_product_3c_gspace_3d(S_G_c, G1, G1_sq, G2, G2_sq, G3, G3_sq, l_max, m_max, n_max, &
    1387           0 :                                                          alpha, beta, gamma, R1, R2, use_coulomb)
    1388             :                         END DO
    1389             :                      END DO
    1390             :                   END DO
    1391             :                END DO
    1392             :             END DO
    1393             :          END DO
    1394             :       CASE (3)
    1395           0 :          DO g1x = -G1c(1), G1c(1)
    1396           0 :             G1_x = ht(:, 1)*g1x
    1397           0 :             DO g1y = -G1c(2), G1c(2)
    1398           0 :                G1_y = ht(:, 2)*g1y
    1399           0 :                DO g1z = -G1c(3), G1c(3)
    1400           0 :                   G1_z = ht(:, 3)*g1z
    1401           0 :                   G1 = G1_x + G1_y + G1_z
    1402           0 :                   G1_sq = G1(1)**2 + G1(2)**2 + G1(3)**2
    1403           0 :                   IF (G1_sq .GT. G_rads_sq(1)) CYCLE
    1404           0 :                   DO g2x = -G2c(1), G2c(1)
    1405           0 :                      G2_x = ht(:, 1)*g2x
    1406           0 :                      DO g2y = -G2c(2), G2c(2)
    1407           0 :                         G2_y = ht(:, 2)*g2y
    1408           0 :                         DO g2z = -G2c(3), G2c(3)
    1409           0 :                            G2_z = ht(:, 3)*g2z
    1410           0 :                            G2 = G2_x + G2_y + G2_z
    1411           0 :                            G2_sq = G2(1)**2 + G2(2)**2 + G2(3)**2
    1412           0 :                            IF (G2_sq .GT. G_rads_sq(2)) CYCLE
    1413           0 :                            G3 = G1 + G2
    1414           0 :                            G3_sq = G3(1)**2 + G3(2)**2 + G3(3)**2
    1415           0 :                            IF (G3_sq .GT. G_rads_sq(3)) CYCLE
    1416           0 :                            IF (use_coulomb) THEN
    1417           0 :                               IF (g1x + g2x == 0 .AND. g1y + g2y == 0 .AND. g1z + g2z == 0) CYCLE
    1418             :                            END IF
    1419             :                            CALL pgf_product_3c_gspace_3d(S_G_c, G1, G1_sq, G2, G2_sq, G3, G3_sq, l_max, m_max, n_max, &
    1420           0 :                                                          alpha, beta, gamma, R1, R2, use_coulomb)
    1421             :                         END DO
    1422             :                      END DO
    1423             :                   END DO
    1424             :                END DO
    1425             :             END DO
    1426             :          END DO
    1427             :       END SELECT
    1428           0 :       S_G = REAL(S_G_c, KIND=dp)/vol**2
    1429             : 
    1430           0 :    END SUBROUTINE
    1431             : 
    1432             : ! **************************************************************************************************
    1433             : !> \brief ...
    1434             : !> \param S_G ...
    1435             : !> \param G1 ...
    1436             : !> \param G1_sq ...
    1437             : !> \param G2 ...
    1438             : !> \param G2_sq ...
    1439             : !> \param G3 ...
    1440             : !> \param G3_sq ...
    1441             : !> \param l_max ...
    1442             : !> \param m_max ...
    1443             : !> \param n_max ...
    1444             : !> \param alpha ...
    1445             : !> \param beta ...
    1446             : !> \param gamma ...
    1447             : !> \param R1 ...
    1448             : !> \param R2 ...
    1449             : !> \param coulomb ...
    1450             : ! **************************************************************************************************
    1451           0 :    PURE SUBROUTINE pgf_product_3c_gspace_3d(S_G, G1, G1_sq, G2, G2_sq, G3, G3_sq, l_max, m_max, n_max, &
    1452             :                                             alpha, beta, gamma, R1, R2, coulomb)
    1453             : 
    1454             :       COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)  :: S_G
    1455             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G1
    1456             :       REAL(KIND=dp), INTENT(IN)                          :: G1_sq
    1457             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G2
    1458             :       REAL(KIND=dp), INTENT(IN)                          :: G2_sq
    1459             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G3
    1460             :       REAL(KIND=dp), INTENT(IN)                          :: G3_sq
    1461             :       INTEGER, INTENT(IN)                                :: l_max, m_max, n_max
    1462             :       REAL(KIND=dp), INTENT(IN)                          :: alpha, beta, gamma
    1463             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R1, R2
    1464             :       LOGICAL, INTENT(IN)                                :: coulomb
    1465             : 
    1466             :       COMPLEX(KIND=dp)                                   :: exp_tot
    1467             :       INTEGER                                            :: k, l, lco, lx, ly, lz, m, mco, mx, my, &
    1468             :                                                             mz, n, nco, nx, ny, nz
    1469           0 :       COMPLEX(KIND=dp), DIMENSION(ncoset(n_max))         :: S_G_n
    1470           0 :       COMPLEX(KIND=dp), DIMENSION(ncoset(m_max))         :: S_G_m
    1471           0 :       COMPLEX(KIND=dp), DIMENSION(ncoset(l_max))         :: S_G_l
    1472           0 :       REAL(KIND=dp), DIMENSION(3, 0:l_max)               :: G1_pow_l
    1473           0 :       REAL(KIND=dp), DIMENSION(3, 0:m_max)               :: G2_pow_m
    1474           0 :       REAL(KIND=dp), DIMENSION(3, 0:n_max)               :: G3_pow_n
    1475             : 
    1476             :       exp_tot = EXP(gaussi*DOT_PRODUCT(G1, R1))*EXP(-alpha*G1_sq)* & ! cost: 5 exp_w flops
    1477             :                 EXP(-beta*G2_sq)* &
    1478           0 :                 EXP(-gamma*G3_sq)*EXP(gaussi*DOT_PRODUCT(G3, R2))
    1479             : 
    1480           0 :       IF (coulomb) exp_tot = exp_tot/G3_sq
    1481             : 
    1482           0 :       DO k = 1, 3
    1483           0 :          G1_pow_l(k, 0) = 1.0_dp
    1484           0 :          DO l = 1, l_max
    1485           0 :             G1_pow_l(k, l) = G1_pow_l(k, l - 1)*G1(k)
    1486             :          END DO
    1487           0 :          G2_pow_m(k, 0) = 1.0_dp
    1488           0 :          DO m = 1, m_max
    1489           0 :             G2_pow_m(k, m) = G2_pow_m(k, m - 1)*G2(k)
    1490             :          END DO
    1491           0 :          G3_pow_n(k, 0) = 1.0_dp
    1492           0 :          DO n = 1, n_max
    1493           0 :             G3_pow_n(k, n) = G3_pow_n(k, n - 1)*G3(k)
    1494             :          END DO
    1495             :       END DO
    1496             : 
    1497           0 :       DO lco = 1, ncoset(l_max)
    1498           0 :          CALL get_l(lco, l, lx, ly, lz)
    1499           0 :          S_G_l(lco) = G1_pow_l(1, lx)*G1_pow_l(2, ly)*G1_pow_l(3, lz)*(-1.0_dp)**l*i_pow(l)
    1500             :       END DO
    1501             : 
    1502           0 :       DO mco = 1, ncoset(m_max)
    1503           0 :          CALL get_l(mco, m, mx, my, mz)
    1504           0 :          S_G_m(mco) = G2_pow_m(1, mx)*G2_pow_m(2, my)*G2_pow_m(3, mz)*(-1.0_dp)**m*i_pow(m)
    1505             :       END DO
    1506             : 
    1507           0 :       DO nco = 1, ncoset(n_max)
    1508           0 :          CALL get_l(nco, n, nx, ny, nz)
    1509           0 :          S_G_n(nco) = G3_pow_n(1, nx)*G3_pow_n(2, ny)*G3_pow_n(3, nz)*i_pow(n)
    1510             :       END DO
    1511             : 
    1512           0 :       DO nco = 1, ncoset(n_max)
    1513           0 :          DO mco = 1, ncoset(m_max)
    1514           0 :             DO lco = 1, ncoset(l_max)
    1515             :                S_G(lco, mco, nco) = S_G(lco, mco, nco) + & ! cost: 4 flops
    1516             :                                     S_G_l(lco)*S_G_m(mco)*S_G_n(nco)* &
    1517           0 :                                     exp_tot
    1518             :             END DO
    1519             :          END DO
    1520             :       END DO
    1521             : 
    1522           0 :    END SUBROUTINE pgf_product_3c_gspace_3d
    1523             : 
    1524             : ! **************************************************************************************************
    1525             : !> \brief Roughly estimated number of floating point operations
    1526             : !> \param ns_G ...
    1527             : !> \param ns_R ...
    1528             : !> \param l ...
    1529             : !> \param m ...
    1530             : !> \param n ...
    1531             : !> \return ...
    1532             : ! **************************************************************************************************
    1533      148500 :    PURE FUNCTION nsum_product_3c_gspace_3d(ns_G, ns_R, l, m, n)
    1534             :       REAL(KIND=dp), INTENT(IN)                          :: ns_G, ns_R
    1535             :       INTEGER, INTENT(IN)                                :: l, m, n
    1536             :       INTEGER(KIND=int_8)                                :: nsum_product_3c_gspace_3d
    1537             : 
    1538             :       nsum_product_3c_gspace_3d = &
    1539             :          NINT( &
    1540             :          ns_G*( &
    1541             :          (exp_w*2) + &
    1542             :          ns_R*(exp_w*2 + ncoset(l + m)*7) + &
    1543             :          3*nsum_gaussian_overlap(l, m, 1) + &
    1544             :          ncoset(l)*ncoset(m)*(ncoset(l + m)*4 + ncoset(n)*8)), &
    1545      148500 :          KIND=int_8)
    1546      148500 :    END FUNCTION
    1547             : 
    1548             : ! **************************************************************************************************
    1549             : !> \brief ...
    1550             : !> \param S_G ...
    1551             : !> \param l_max ...
    1552             : !> \param m_max ...
    1553             : !> \param n_max ...
    1554             : !> \param R1 ...
    1555             : !> \param R2 ...
    1556             : !> \param alpha ...
    1557             : !> \param beta ...
    1558             : !> \param gamma ...
    1559             : !> \param hmat ...
    1560             : !> \param h_inv ...
    1561             : !> \param vol ...
    1562             : !> \param R_c ...
    1563             : !> \param G_c ...
    1564             : !> \param R_rad ...
    1565             : !> \param G_rad ...
    1566             : ! **************************************************************************************************
    1567        5846 :    PURE SUBROUTINE pgf_sum_product_3c_gspace_3d(S_G, l_max, m_max, n_max, R1, R2, alpha, beta, gamma, &
    1568             :                                                 hmat, h_inv, vol, R_c, G_c, R_rad, G_rad)
    1569             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)     :: S_G
    1570             :       INTEGER, INTENT(IN)                                :: l_max, m_max, n_max
    1571             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R1, R2
    1572             :       REAL(KIND=dp), INTENT(IN)                          :: alpha, beta, gamma
    1573             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
    1574             :       REAL(KIND=dp), INTENT(IN)                          :: vol
    1575             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R_c, G_c
    1576             :       REAL(KIND=dp), INTENT(IN)                          :: R_rad, G_rad
    1577             : 
    1578             :       COMPLEX(KIND=dp)                                   :: exp_tot
    1579             :       INTEGER                                            :: gx, gy, gz, k, l, lco, lnco, lx, ly, lz, &
    1580             :                                                             m, mco, n, nco
    1581             :       COMPLEX(KIND=dp), &
    1582       11692 :          DIMENSION(ncoset(m_max), ncoset(n_max))         :: S_R
    1583             :       COMPLEX(KIND=dp), DIMENSION(ncoset(l_max), ncoset( &
    1584       11692 :                                   m_max), ncoset(n_max))                          :: S_G_c
    1585             :       REAL(KIND=dp)                                      :: G_rad_sq, G_sq, R_rad_sq
    1586             :       REAL(KIND=dp), DIMENSION(3)                        :: G, G_x, G_y, G_z
    1587       11692 :       REAL(KIND=dp), DIMENSION(3, 0:l_max)               :: G_pow_l
    1588             :       REAL(KIND=dp), DIMENSION(3, 3)                     :: ht
    1589        5846 :       REAL(KIND=dp), DIMENSION(ncoset(l_max))            :: S_G_c_l
    1590             : 
    1591      276845 :       S_G_c(:, :, :) = 0.0_dp
    1592             : 
    1593        5846 :       G_rad_sq = G_rad**2
    1594        5846 :       R_rad_sq = R_rad**2
    1595             : 
    1596        5846 :       lnco = ncoset(l_max)
    1597             : 
    1598       75998 :       ht = twopi*TRANSPOSE(h_inv)
    1599       36078 :       DO gx = -FLOOR(G_c(1)), FLOOR(G_c(1))
    1600      120928 :          G_x = ht(:, 1)*gx
    1601      194252 :          DO gy = -FLOOR(G_c(2)), FLOOR(G_c(2))
    1602      632696 :             G_y = ht(:, 2)*gy
    1603     1028374 :             DO gz = -FLOOR(G_c(3)), FLOOR(G_c(3))
    1604     3359872 :                G_z = ht(:, 3)*gz
    1605     3359872 :                G = G_x + G_y + G_z
    1606      839968 :                G_sq = G(1)**2 + G(2)**2 + G(3)**2
    1607      839968 :                IF (G_sq .GT. G_rad_sq) CYCLE
    1608             : 
    1609     1350880 :                exp_tot = EXP(-alpha*G_sq)*EXP(gaussi*DOT_PRODUCT(G, R1)) ! cost: exp_w*2 flops
    1610             : 
    1611     1350880 :                DO k = 1, 3
    1612     1013160 :                   G_pow_l(k, 0) = 1.0_dp
    1613     2236258 :                   DO l = 1, l_max
    1614     1898538 :                      G_pow_l(k, l) = G_pow_l(k, l - 1)*G(k)
    1615             :                   END DO
    1616             :                END DO
    1617             : 
    1618      337720 :                CALL pgf_sum_product_3c_rspace_3d(S_R, m_max, n_max, G, R2, beta, gamma, hmat, h_inv, vol, R_c, R_rad_sq)
    1619             : 
    1620     1947011 :                DO lco = 1, ncoset(l_max)
    1621     1609291 :                   CALL get_l(lco, l, lx, ly, lz)
    1622     1947011 :                   S_G_c_l(lco) = G_pow_l(1, lx)*G_pow_l(2, ly)*G_pow_l(3, lz)*(-1.0_dp)**l
    1623             :                END DO
    1624             : 
    1625     1519228 :                DO nco = 1, ncoset(n_max)
    1626     1023334 :                   CALL get_l(nco, n)
    1627     4612179 :                   DO mco = 1, ncoset(m_max)
    1628     2748877 :                      CALL get_l(mco, m)
    1629    15176745 :                      DO lco = 1, ncoset(l_max)
    1630    11404534 :                         CALL get_l(lco, l)
    1631             :                         S_G_c(lco, mco, nco) = & ! cost: 8 flops
    1632             :                            S_G_c(lco, mco, nco) + &
    1633             :                            S_G_c_l(lco)* &
    1634    14153411 :                            exp_tot*i_pow(l + m + n)*(-1.0_dp)**m*S_R(mco, nco)
    1635             :                      END DO
    1636             :                   END DO
    1637             :                END DO
    1638             :             END DO
    1639             :          END DO
    1640             :       END DO
    1641      276845 :       S_G = REAL(S_G_c, KIND=dp)/vol**2
    1642             : 
    1643        5846 :    END SUBROUTINE pgf_sum_product_3c_gspace_3d
    1644             : 
    1645             : ! **************************************************************************************************
    1646             : !> \brief ...
    1647             : !> \param S_R ...
    1648             : !> \param l_max ...
    1649             : !> \param m_max ...
    1650             : !> \param G ...
    1651             : !> \param R ...
    1652             : !> \param alpha ...
    1653             : !> \param beta ...
    1654             : !> \param hmat ...
    1655             : !> \param h_inv ...
    1656             : !> \param vol ...
    1657             : !> \param R_c ...
    1658             : !> \param R_rad_sq ...
    1659             : ! **************************************************************************************************
    1660      337720 :    PURE SUBROUTINE pgf_sum_product_3c_rspace_3d(S_R, l_max, m_max, G, R, alpha, beta, hmat, h_inv, vol, R_c, R_rad_sq)
    1661             :       COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(OUT)     :: S_R
    1662             :       INTEGER, INTENT(IN)                                :: l_max, m_max
    1663             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: G, R
    1664             :       REAL(KIND=dp), INTENT(IN)                          :: alpha, beta
    1665             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
    1666             :       REAL(KIND=dp), INTENT(IN)                          :: vol
    1667             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: R_c
    1668             :       REAL(KIND=dp), INTENT(IN)                          :: R_rad_sq
    1669             : 
    1670             :       COMPLEX(KIND=dp)                                   :: exp_tot
    1671             :       INTEGER                                            :: k, l, lco, lx, ly, lz, m, mco, mx, my, &
    1672             :                                                             mz, sx, sy, sz, t, tco, tx, ty, tz
    1673      675440 :       COMPLEX(KIND=dp), DIMENSION(ncoset(l_max + m_max))   :: S_R_t
    1674             :       REAL(KIND=dp)                                      :: c1, c2, Rp_sq
    1675             :       REAL(KIND=dp), &
    1676      675440 :          DIMENSION(-1:l_max + m_max + 1, -1:l_max, -1:m_max) :: E1, E2, E3
    1677             :       REAL(KIND=dp), DIMENSION(3)                        :: R_l, R_r, Rp, Rx, Ry, Rz, s_shift
    1678      675440 :       REAL(KIND=dp), DIMENSION(3, 0:l_max + m_max)         :: R_pow_t
    1679             : 
    1680      337720 :       c1 = 0.25_dp/(alpha + beta)
    1681      337720 :       c2 = alpha/(alpha + beta)
    1682             : 
    1683     2198096 :       S_R_t(:) = 0.0_dp
    1684     4109931 :       S_R(:, :) = 0.0_dp
    1685             : 
    1686     4390360 :       s_shift = MATMUL(h_inv, R)
    1687     1350880 :       R_l = -R_c + s_shift
    1688     1350880 :       R_r = R_c + s_shift
    1689             : 
    1690     1084696 :       DO sx = CEILING(R_l(1)), FLOOR(R_r(1))
    1691     2987904 :          Rx = hmat(:, 1)*sx
    1692     3046393 :          DO sy = CEILING(R_l(2)), FLOOR(R_r(2))
    1693     7846788 :             Ry = hmat(:, 2)*sy
    1694     8205714 :             DO sz = CEILING(R_l(3)), FLOOR(R_r(3))
    1695    21988164 :                Rz = hmat(:, 3)*sz
    1696    21988164 :                Rp = Rx + Ry + Rz - R
    1697     5497041 :                Rp_sq = Rp(1)**2 + Rp(2)**2 + Rp(3)**2
    1698     5497041 :                IF (Rp_sq .GT. R_rad_sq) CYCLE
    1699             : 
    1700     8361484 :                exp_tot = EXP(-c1*Rp_sq)*EXP(-gaussi*c2*DOT_PRODUCT(Rp, G)) ! cost: exp_w*2 flops
    1701     8361484 :                DO k = 1, 3
    1702     6271113 :                   R_pow_t(k, 0) = 1.0_dp
    1703    13292668 :                   DO t = 1, l_max + m_max
    1704    11202297 :                      R_pow_t(k, t) = R_pow_t(k, t - 1)*Rp(k)
    1705             :                   END DO
    1706             :                END DO
    1707             : 
    1708    13088657 :                DO tco = 1, ncoset(l_max + m_max)
    1709     9036589 :                   CALL get_l(tco, t, tx, ty, tz)
    1710             :                   S_R_t(tco) = S_R_t(tco) + & ! cost: 7 flops
    1711             :                                R_pow_t(1, tx)*R_pow_t(2, ty)*R_pow_t(3, tz)* &
    1712    14533630 :                                (-1.0_dp)**t*i_pow(t)*exp_tot
    1713             :                END DO
    1714             : 
    1715             :             END DO
    1716             :          END DO
    1717             :       END DO
    1718             : 
    1719      337720 :       CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, alpha, beta, G(1), 0.0_dp, 1, E1)
    1720      337720 :       CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, alpha, beta, G(2), 0.0_dp, 1, E2)
    1721      337720 :       CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, alpha, beta, G(3), 0.0_dp, 1, E3)
    1722             : 
    1723     1361054 :       DO mco = 1, ncoset(m_max)
    1724     1023334 :          CALL get_l(mco, m, mx, my, mz)
    1725     4109931 :          DO lco = 1, ncoset(l_max)
    1726     2748877 :             CALL get_l(lco, l, lx, ly, lz)
    1727     8010112 :             DO tx = 0, lx + mx
    1728    13267665 :             DO ty = 0, ly + my
    1729    19515063 :             DO tz = 0, lz + mz
    1730     8996275 :                tco = coset(tx, ty, tz)
    1731             :                S_R(lco, mco) = S_R(lco, mco) + & ! cost: 4 flops
    1732    15277162 :                                E1(tx, lx, mx)*E2(ty, ly, my)*E3(tz, lz, mz)*S_R_t(tco)
    1733             : 
    1734             :             END DO
    1735             :             END DO
    1736             :             END DO
    1737             :          END DO
    1738             :       END DO
    1739             : 
    1740     4109931 :       S_R(:, :) = S_R(:, :)*vol/(twopi)**3*(pi/(alpha + beta))**1.5_dp
    1741             : 
    1742      337720 :    END SUBROUTINE pgf_sum_product_3c_rspace_3d
    1743             : 
    1744             : ! **************************************************************************************************
    1745             : !> \brief Roughly estimated number of floating point operations
    1746             : !> \param ns_R1 ...
    1747             : !> \param ns_R2 ...
    1748             : !> \param l ...
    1749             : !> \param m ...
    1750             : !> \param n ...
    1751             : !> \return ...
    1752             : ! **************************************************************************************************
    1753      148500 :    PURE FUNCTION nsum_3c_rspace_3d(ns_R1, ns_R2, l, m, n)
    1754             :       REAL(KIND=dp), INTENT(IN)                          :: ns_R1, ns_R2
    1755             :       INTEGER, INTENT(IN)                                :: l, m, n
    1756             :       INTEGER(KIND=int_8)                                :: nsum_3c_rspace_3d
    1757             : 
    1758             :       nsum_3c_rspace_3d = &
    1759             :          NINT( &
    1760             :          ns_R1*( &
    1761             :          ns_R2*(exp_w + ncoset(l + m + n)*4) + &
    1762             :          3*nsum_gaussian_overlap(l, m, 2) + &
    1763             :          ncoset(m)*ncoset(l)*( &
    1764             :          ncoset(l + m)*2 + ncoset(n)*ncoset(l + m)*4)), &
    1765      148500 :          KIND=int_8)
    1766             : 
    1767      148500 :    END FUNCTION
    1768             : 
    1769             : ! **************************************************************************************************
    1770             : !> \brief ...
    1771             : !> \param S_R ...
    1772             : !> \param l_max ...
    1773             : !> \param m_max ...
    1774             : !> \param n_max ...
    1775             : !> \param RA ...
    1776             : !> \param RB ...
    1777             : !> \param RC ...
    1778             : !> \param zeta ...
    1779             : !> \param zetb ...
    1780             : !> \param zetc ...
    1781             : !> \param a_mm ...
    1782             : !> \param hmat ...
    1783             : !> \param h_inv ...
    1784             : !> \param R_c ...
    1785             : !> \param R_rad ...
    1786             : ! **************************************************************************************************
    1787      142654 :    SUBROUTINE pgf_sum_3c_rspace_3d(S_R, l_max, m_max, n_max, RA, RB, RC, zeta, zetb, zetc, a_mm, &
    1788             :                                    hmat, h_inv, R_c, R_rad)
    1789             :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(OUT)     :: S_R
    1790             :       INTEGER, INTENT(IN)                                :: l_max, m_max, n_max
    1791             :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: RA, RB, RC
    1792             :       REAL(KIND=dp), INTENT(IN)                          :: zeta, zetb, zetc, a_mm
    1793             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: hmat, h_inv
    1794             :       REAL(KIND=dp), DIMENSION(2, 3), INTENT(IN)         :: R_c
    1795             :       REAL(KIND=dp), DIMENSION(2), INTENT(IN)            :: R_rad
    1796             : 
    1797             :       INTEGER                                            :: k, l, lco, lx, ly, lz, m, mco, mx, my, &
    1798             :                                                             mz, n, nco, nx, ny, nz, s1x, s1y, s1z, &
    1799             :                                                             s2x, s2y, s2z, t, tco, tnco, ttco, &
    1800             :                                                             ttx, tty, ttz, tx, ty, tz
    1801             :       REAL(KIND=dp)                                      :: alpha, exp_tot, R1_sq, R_sq
    1802      142654 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: h_to_c
    1803             :       REAL(KIND=dp), &
    1804      285308 :          DIMENSION(-1:l_max + m_max + 1, -1:l_max, -1:m_max) :: E1, E2, E3
    1805             :       REAL(KIND=dp), DIMENSION(2)                        :: R_rad_sq
    1806             :       REAL(KIND=dp), DIMENSION(3)                        :: R, R1, R1_l, R1_r, R1_tmp, R1x, R1y, &
    1807             :                                                             R1z, R2_l, R2_r, R2x, R2y, R2z, &
    1808             :                                                             R_offset, R_tmp, s1_shift, s2_shift
    1809      285308 :       REAL(KIND=dp), DIMENSION(3, 0:l_max + m_max + n_max)   :: R_pow_t
    1810             :       REAL(KIND=dp), DIMENSION(ncoset(l_max + m_max), &
    1811      285308 :                                ncoset(l_max), ncoset(m_max))                   :: Eco
    1812             :       REAL(KIND=dp), &
    1813      285308 :          DIMENSION(ncoset(l_max + m_max + n_max))            :: S_R_t
    1814             :       REAL(KIND=dp), DIMENSION(ncoset(l_max + m_max + n_max) &
    1815      285308 :                                , ncoset(l_max + m_max + n_max))                    :: h_to_c_tco
    1816             : 
    1817      142654 :       alpha = 1.0_dp/((zeta + zetb + zetc)/((zeta + zetb)*zetc) + 4.0_dp*a_mm)
    1818             : 
    1819    71800162 :       Eco(:, :, :) = 0.0_dp
    1820    24264238 :       S_R(:, :, :) = 0.0_dp
    1821   157194456 :       h_to_c_tco(:, :) = 0.0_dp
    1822             : 
    1823      570616 :       R_offset = RC - (zeta*RA + zetb*RB)/(zeta + zetb)
    1824             : 
    1825      142654 :       CALL create_hermite_to_cartesian(alpha, l_max + m_max + n_max, h_to_c)
    1826             : 
    1827     2682070 :       DO tco = 1, ncoset(l_max + m_max + n_max)
    1828     2539416 :          CALL get_l(tco, t, tx, ty, tz)
    1829     8078511 :          DO ttx = 0, tx
    1830    18802080 :          DO tty = 0, ty
    1831    37176724 :          DO ttz = 0, tz
    1832    20914060 :             ttco = coset(ttx, tty, ttz)
    1833    31780283 :             h_to_c_tco(ttco, tco) = h_to_c(ttx, tx)*h_to_c(tty, ty)*h_to_c(ttz, tz)
    1834             :          END DO
    1835             :          END DO
    1836             :          END DO
    1837             :       END DO
    1838             : 
    1839     2282464 :       s1_shift = MATMUL(h_inv, RA - RB)
    1840      570616 :       R1_l = -R_c(1, :) + s1_shift
    1841      570616 :       R1_r = R_c(1, :) + s1_shift
    1842             : 
    1843      427962 :       R_rad_sq = R_rad**2
    1844             : 
    1845      348524 :       DO s1x = CEILING(R1_l(1)), FLOOR(R1_r(1))
    1846      823480 :          R1x = hmat(:, 1)*s1x
    1847      741859 :          DO s1y = CEILING(R1_l(2)), FLOOR(R1_r(2))
    1848     1573340 :             R1y = hmat(:, 2)*s1y
    1849     1532744 :             DO s1z = CEILING(R1_l(3)), FLOOR(R1_r(3))
    1850     3734156 :                R1z = hmat(:, 3)*s1z
    1851     3734156 :                R1 = R1x + R1y + R1z
    1852    13798961 :                S_R_t(:) = 0.0_dp
    1853     3734156 :                R1_tmp = R1 - (RA - RB)
    1854      933539 :                R1_sq = R1_tmp(1)**2 + R1_tmp(2)**2 + R1_tmp(3)**2
    1855             : 
    1856      933539 :                IF (R1_sq .GT. R_rad_sq(1)) CYCLE
    1857             : 
    1858     1625580 :                R_tmp = R_offset + R1*zeta/(zeta + zetb)
    1859     6502320 :                s2_shift = -MATMUL(h_inv, R_tmp)
    1860     1625580 :                R2_l = -R_c(2, :) + s2_shift
    1861     1625580 :                R2_r = R_c(2, :) + s2_shift
    1862     1468530 :                DO s2x = CEILING(R2_l(1)), FLOOR(R2_r(1))
    1863     4248540 :                   R2x = hmat(:, 1)*s2x
    1864     6145785 :                   DO s2y = CEILING(R2_l(2)), FLOOR(R2_r(2))
    1865    18709020 :                      R2y = hmat(:, 2)*s2y
    1866    34911377 :                      DO s2z = CEILING(R2_l(3)), FLOOR(R2_r(3))
    1867   116687948 :                         R2z = hmat(:, 3)*s2z
    1868   116687948 :                         R = R_tmp + R2x + R2y + R2z
    1869    29171987 :                         R_sq = R(1)**2 + R(2)**2 + R(3)**2
    1870             : 
    1871    29171987 :                         IF (R_sq .GT. R_rad_sq(2)) CYCLE
    1872             : 
    1873    14475027 :                         exp_tot = EXP(-alpha*R_sq) ! cost: exp_w flops
    1874    57900108 :                         DO k = 1, 3
    1875    43425081 :                            R_pow_t(k, 0) = 1.0_dp
    1876   156067857 :                            DO t = 1, l_max + m_max + n_max
    1877   141592830 :                               R_pow_t(k, t) = R_pow_t(k, t - 1)*R(k)
    1878             :                            END DO
    1879             :                         END DO
    1880   272529341 :                         DO tco = 1, ncoset(l_max + m_max + n_max)
    1881   253377059 :                            CALL get_l(tco, t, tx, ty, tz)
    1882   282549046 :                            S_R_t(tco) = S_R_t(tco) + R_pow_t(1, tx)*R_pow_t(2, ty)*R_pow_t(3, tz)*exp_tot ! cost: 4 flops
    1883             :                         END DO
    1884             :                      END DO
    1885             :                   END DO
    1886             :                END DO
    1887             : 
    1888     5981328 :                S_R_t(:) = MATMUL(TRANSPOSE(h_to_c_tco), S_R_t)*(alpha/pi)**1.5_dp
    1889             : 
    1890      406395 :                CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, zeta, zetb, RA(1) - R1(1), RB(1), 2, E1)
    1891      406395 :                CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, zeta, zetb, RA(2) - R1(2), RB(2), 2, E2)
    1892      406395 :                CALL create_gaussian_overlap_dist_to_hermite(l_max, m_max, zeta, zetb, RA(3) - R1(3), RB(3), 2, E3)
    1893             : 
    1894     1416942 :                DO mco = 1, ncoset(m_max)
    1895     1010547 :                   CALL get_l(mco, m, mx, my, mz)
    1896     5054628 :                   DO lco = 1, ncoset(l_max)
    1897     3637686 :                      CALL get_l(lco, l, lx, ly, lz)
    1898    10890282 :                      DO tx = 0, lx + mx
    1899    20345458 :                      DO ty = 0, ly + my
    1900    33814276 :                      DO tz = 0, lz + mz
    1901    17106504 :                         tco = coset(tx, ty, tz)
    1902    27572227 :                         Eco(tco, lco, mco) = E1(tx, lx, mx)*E2(ty, ly, my)*E3(tz, lz, mz) ! cost: 2 flops
    1903             :                      END DO
    1904             :                      END DO
    1905             :                      END DO
    1906             :                   END DO
    1907             :                END DO
    1908             : 
    1909     3040511 :                DO nco = 1, ncoset(n_max)
    1910     2240781 :                   CALL get_l(nco, n, nx, ny, nz)
    1911    17172306 :                   DO tco = 1, ncoset(l_max + m_max)
    1912    14525130 :                      CALL get_l(tco, t, tx, ty, tz)
    1913    14525130 :                      tnco = coset(tx + nx, ty + ny, tz + nz)
    1914             :                      S_R(:, :, nco) = S_R(:, :, nco) + & ! cost: 4 flops
    1915             :                                       Eco(tco, :, :)* &
    1916  1070960721 :                                       (-1)**n*S_R_t(tnco)
    1917             : 
    1918             :                   END DO
    1919             :                END DO
    1920             :             END DO
    1921             :          END DO
    1922             :       END DO
    1923      142654 :    END SUBROUTINE pgf_sum_3c_rspace_3d
    1924             : 
    1925             : ! **************************************************************************************************
    1926             : !> \brief Compute bounding box for ellipsoid. This is needed in order to find summation bounds for
    1927             : !>        sphere for sums over non-orthogonal lattice vectors.
    1928             : !> \param s_rad sphere radius
    1929             : !> \param s_to_e sphere to ellipsoid trafo
    1930             : !> \return ...
    1931             : ! **************************************************************************************************
    1932    19854720 :    PURE FUNCTION ellipsoid_bounds(s_rad, s_to_e)
    1933             :       REAL(KIND=dp), INTENT(IN)                          :: s_rad
    1934             :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(IN)         :: s_to_e
    1935             :       REAL(KIND=dp), DIMENSION(3)                        :: ellipsoid_bounds
    1936             : 
    1937             :       INTEGER                                            :: i_xyz
    1938             : 
    1939    79418880 :       DO i_xyz = 1, 3
    1940    79418880 :          ellipsoid_bounds(i_xyz) = SQRT(s_to_e(i_xyz, 1)**2 + s_to_e(i_xyz, 2)**2 + s_to_e(i_xyz, 3)**2)*s_rad
    1941             :       END DO
    1942             : 
    1943             :    END FUNCTION ellipsoid_bounds
    1944             : 
    1945             : ! **************************************************************************************************
    1946             : !> \brief Roughly estimated number of floating point operations
    1947             : !> \param l ...
    1948             : !> \param m ...
    1949             : !> \param H_or_C_product ...
    1950             : !> \return ...
    1951             : ! **************************************************************************************************
    1952      297000 :    PURE FUNCTION nsum_gaussian_overlap(l, m, H_or_C_product)
    1953             :       INTEGER, INTENT(IN)                                :: l, m, H_or_C_product
    1954             :       INTEGER                                            :: nsum_gaussian_overlap
    1955             : 
    1956             :       INTEGER                                            :: loop
    1957             : 
    1958      297000 :       nsum_gaussian_overlap = exp_w
    1959      297000 :       loop = (m + 1)*(l + 1)*(m + l + 2)
    1960      297000 :       IF (H_or_C_product .EQ. 1) THEN
    1961      148500 :          nsum_gaussian_overlap = nsum_gaussian_overlap + loop*16
    1962             :       ELSE
    1963      148500 :          nsum_gaussian_overlap = nsum_gaussian_overlap + loop*32
    1964             :       END IF
    1965      297000 :    END FUNCTION
    1966             : 
    1967             : ! **************************************************************************************************
    1968             : !> \brief ...
    1969             : !> \param lco ...
    1970             : !> \param l ...
    1971             : !> \param lx ...
    1972             : !> \param ly ...
    1973             : !> \param lz ...
    1974             : ! **************************************************************************************************
    1975   843147983 :    PURE ELEMENTAL SUBROUTINE get_l(lco, l, lx, ly, lz)
    1976             :       INTEGER, INTENT(IN)                                :: lco
    1977             :       INTEGER, INTENT(OUT)                               :: l
    1978             :       INTEGER, INTENT(OUT), OPTIONAL                     :: lx, ly, lz
    1979             : 
    1980  3372591932 :       l = SUM(indco(:, lco))
    1981   843147983 :       IF (PRESENT(lx)) lx = indco(1, lco)
    1982   843147983 :       IF (PRESENT(ly)) ly = indco(2, lco)
    1983   843147983 :       IF (PRESENT(lz)) lz = indco(3, lco)
    1984   843147983 :    END SUBROUTINE
    1985             : 
    1986             : ! **************************************************************************************************
    1987             : !> \brief ...
    1988             : !> \param i ...
    1989             : !> \return ...
    1990             : ! **************************************************************************************************
    1991   479950601 :    PURE ELEMENTAL FUNCTION i_pow(i)
    1992             :       INTEGER, INTENT(IN)                                :: i
    1993             :       COMPLEX(KIND=dp)                                   :: i_pow
    1994             : 
    1995             :       COMPLEX(KIND=dp), DIMENSION(0:3), PARAMETER :: &
    1996             :          ip = (/(1.0_dp, 0.0_dp), (0.0_dp, 1.0_dp), (-1.0_dp, 0.0_dp), (0.0_dp, -1.0_dp)/)
    1997             : 
    1998   479950601 :       i_pow = ip(MOD(i, 4))
    1999             : 
    2000   479950601 :    END FUNCTION
    2001             : 
    2002     3955399 : END MODULE eri_mme_lattice_summation

Generated by: LCOV version 1.15