LCOV - code coverage report
Current view: top level - src - hfx_pair_list_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 87.8 % 409 359
Test Date: 2026-10-15 00:55:44 Functions: 60.0 % 10 6

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Routines for optimizing load balance between processes in HFX calculations
      10              : !> \par History
      11              : !>      04.2008 created [Manuel Guidon]
      12              : !>      11.2019 fixed initial value for potential_id (A. Bussy)
      13              : !> \author Manuel Guidon
      14              : ! **************************************************************************************************
      15              : MODULE hfx_pair_list_methods
      16              :    USE cell_types,                      ONLY: cell_type,&
      17              :                                               pbc
      18              :    USE gamma,                           ONLY: fgamma => fgamma_0
      19              :    USE hfx_types,                       ONLY: &
      20              :         hfx_basis_type, hfx_block_range_type, hfx_cell_type, hfx_pgf_list, hfx_pgf_product_list, &
      21              :         hfx_potential_type, hfx_screen_coeff_type, pair_list_type, pair_set_list_type
      22              :    USE input_constants,                 ONLY: &
      23              :         do_potential_TShPSC, do_potential_coulomb, do_potential_gaussian, do_potential_id, &
      24              :         do_potential_long, do_potential_mix_cl, do_potential_mix_cl_trunc, do_potential_mix_lg, &
      25              :         do_potential_short, do_potential_truncated
      26              :    USE kinds,                           ONLY: dp
      27              :    USE libint_wrapper,                  ONLY: prim_data_f_size
      28              :    USE mathconstants,                   ONLY: pi
      29              :    USE mp2_types,                       ONLY: pair_list_type_mp2
      30              :    USE particle_types,                  ONLY: particle_type
      31              :    USE t_c_g0,                          ONLY: t_c_g0_n
      32              :    USE t_sh_p_s_c,                      ONLY: trunc_CS_poly_n20
      33              : #include "./base/base_uses.f90"
      34              : 
      35              :    IMPLICIT NONE
      36              :    PRIVATE
      37              : 
      38              :    PUBLIC :: build_pair_list, &
      39              :              build_pair_list_mp2, &
      40              :              build_pair_list_pgf, &
      41              :              build_pgf_product_list, &
      42              :              build_atomic_pair_list, &
      43              :              pgf_product_list_size, &
      44              :              build_pair_list_pbc_pgf, &
      45              :              bra_t, allocate_bra, min_image_gap_sq
      46              : 
      47              :    ! an initial estimate for the size of the product list
      48              :    INTEGER, SAVE :: pgf_product_list_size = 128
      49              : 
      50              :    ! Store screened primitive gaussian function pairs between two shells (A and B)
      51              :    TYPE :: Bra_t
      52              :       REAL(dp), ALLOCATABLE, DIMENSION(:, :)    :: pgf_scr
      53              :       INTEGER, ALLOCATABLE, DIMENSION(:, :)     :: pgf_idx, cell_idx
      54              :       INTEGER :: cell_cnt = 0, pgf_cnt = 0
      55              :    END TYPE Bra_t
      56              : 
      57              : CONTAINS
      58              : 
      59              : ! **************************************************************************************************
      60              : !> \brief Allocates all arrays within a Bra_t structure.
      61              : !>
      62              : !> This subroutine ensures that a given `Bra_t` pointer has allocated memory
      63              : !> for storing primitive Gaussian pair indices, screening data, and cell indices.
      64              : !> Existing allocations are safely deallocated first.
      65              : !>
      66              : !> \param[in,out] bra         Pointer to the Bra_t structure to allocate.
      67              : !> \param[in]     max_npgf    Maximum number of primitives per shell.
      68              : !> \param[in]     max_ncell   Maximum number of neighbor cells.
      69              : !>
      70              : !> \note The arrays are allocated as follows:
      71              : !>       - `pgf_idx(3, max_npgf^2 * max_ncell)`
      72              : !>       - `pgf_scr(5, max_npgf^2 * max_ncell)`
      73              : !>       - `cell_idx(3, max_ncell)`
      74              : !>
      75              : ! **************************************************************************************************
      76            0 :    SUBROUTINE allocate_Bra(bra, max_npgf, max_ncell)
      77              :       TYPE(bra_t), POINTER                               :: bra
      78              :       INTEGER                                            :: max_npgf, max_ncell
      79              : 
      80            0 :       IF (ALLOCATED(bra%pgf_idx)) DEALLOCATE (bra%pgf_idx)  ! TODO add if n_prm changed
      81            0 :       IF (ALLOCATED(bra%pgf_scr)) DEALLOCATE (bra%pgf_scr)  ! TODO add if n_prm changed
      82            0 :       IF (ALLOCATED(bra%cell_idx)) DEALLOCATE (bra%cell_idx) ! TODO add if n_prm changed
      83            0 :       ALLOCATE (bra%pgf_idx(3, max_npgf*max_npgf*max_ncell))
      84            0 :       ALLOCATE (bra%pgf_scr(5, max_npgf*max_npgf*max_ncell))
      85            0 :       ALLOCATE (bra%cell_idx(3, max_ncell))
      86            0 :    END SUBROUTINE allocate_Bra
      87              : 
      88              : ! **************************************************************************************************
      89              : !> \brief Builds a screened list of primitives from centers A and B, intersecting with another shell
      90              : !>
      91              : !> This subroutine populates the `Bra_t` structure with indices and screening data
      92              : !> for primitive Gaussian pairs (ipgf,jpgf,n3) that pass the Schwarz screening criterion
      93              : !>
      94              : !> \param[in]  npgfa              Number of primitives in shell A
      95              : !> \param[in]  npgfb              Number of primitives in shell B
      96              : !> \param[out] bra                Pointer to Bra_t structure to populate
      97              : !> \param[in]  screen1            Screening coeffiecients for the AB pair based on most diffuse pgf
      98              : !> \param[in]  screen2            Screening coeffiecients for the CD pair based on most diffuse pgf
      99              : !> \param[in]  pgf                Screening coeeficents for primitive gaussians
     100              : !> \param[in]  log10_pmax         Log10 of maximum integral prefactor
     101              : !> \param[in]  log10_eps_schwarz  Log10 of Schwarz screening threshold
     102              : !> \param[in]  ra                 Cartesian coordinates of center A
     103              : !> \param[in]  rb                 Cartesian coordinates of center B
     104              : !> \param[out] nelements          Total number of valid primitives found
     105              : !> \param[in]  neighbor_cells     Array of lattice vectors
     106              : !> \param[in]  do_periodic        Logical flag for periodic boundary conditions on B
     107              : !>
     108              : !> \note Loops over all cells, shifting the B shell position accordingly
     109              : !>       Only pairs satisfying the screening condition are stored.
     110              : !>
     111              : !> \note Each valid cell contributes a block of pairs stored contiguously in
     112              : !>       bra%pgf_idx, with cell metadata stored in bra%cell_idx
     113              : !> \note screening primitive pairs (ipgf, jpgf) using both coarse and fine screening thresholds
     114              : ! **************************************************************************************************
     115            0 :    SUBROUTINE build_pair_list_pbc_pgf(npgfa, npgfb, bra, screen1, screen2, pgf, &
     116              :                                       log10_pmax, log10_eps_schwarz, ra, rb, nelements, &
     117              :                                       neighbor_cells, do_periodic)
     118              : 
     119              :       INTEGER, INTENT(IN)                                :: npgfa, npgfb
     120              :       TYPE(bra_t), POINTER                               :: bra
     121              :       REAL(dp), INTENT(IN)                               :: screen1(2), screen2(2)
     122              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     123              :          POINTER                                         :: pgf
     124              :       REAL(dp), INTENT(IN)                               :: log10_pmax, log10_eps_schwarz, ra(3), &
     125              :                                                             rb(3)
     126              :       INTEGER, INTENT(OUT)                               :: nelements
     127              :       TYPE(hfx_cell_type), DIMENSION(:), POINTER         :: neighbor_cells
     128              :       LOGICAL, INTENT(IN)                                :: do_periodic
     129              : 
     130              :       INTEGER                                            :: cell_cnt, cell_idx, element_cnt, &
     131              :                                                             element_idx, element_off, ipgf, jpgf
     132              :       REAL(dp)                                           :: AB(3), im_B(3), pgf_max, rab2
     133              : 
     134            0 :       element_idx = 0
     135            0 :       element_off = 0
     136            0 :       cell_cnt = 0
     137            0 :       DO cell_idx = 1, SIZE(neighbor_cells)
     138              :          ! move B to this cell while keeping A fixed
     139              :          ! NOTE rb has already been moved by build_pair_list
     140              :          !      so that when cell_r is (000) AB is in the pbc cell
     141            0 :          IF (do_periodic) THEN
     142            0 :             im_B = rb + neighbor_cells(cell_idx)%cell_r(:)
     143              :          ELSE
     144            0 :             im_B = rb
     145              :          END IF
     146            0 :          AB = ra - im_B
     147            0 :          rab2 = AB(1)**2 + AB(2)**2 + AB(3)**2
     148              :          ! First screening on the most diffuse AB gaussians along with the most diffuse CD gaussian
     149            0 :          IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) CYCLE
     150              : 
     151            0 :          element_cnt = 0
     152            0 :          DO ipgf = 1, npgfa
     153            0 :             DO jpgf = 1, npgfb
     154              : 
     155              :                ! Second screening on this actual AB pair and the most diffuse CD from before
     156            0 :                pgf_max = pgf(jpgf, ipgf)%x(1)*rab2 + pgf(jpgf, ipgf)%x(2)
     157            0 :                IF (pgf_max + screen2(2) + log10_pmax < log10_eps_schwarz) CYCLE
     158              :                ! This pair passed screening. Add it to the bra.
     159            0 :                element_idx = element_idx + 1
     160            0 :                bra%pgf_idx(:, element_idx) = [ipgf, jpgf, cell_idx]
     161            0 :                bra%pgf_scr(1, element_idx) = pgf_max
     162            0 :                element_cnt = element_cnt + 1
     163              :             END DO
     164              :          END DO
     165              : 
     166              :          ! If this cell produced any pair, add this cell to the bra
     167            0 :          IF (element_cnt == 0) CYCLE
     168            0 :          cell_cnt = cell_cnt + 1
     169            0 :          bra%cell_idx(:, cell_cnt) = [cell_idx, element_cnt, element_off]
     170            0 :          element_off = element_off + element_cnt
     171              : 
     172              :       END DO ! cell
     173            0 :       bra%cell_cnt = cell_cnt
     174            0 :       nelements = element_idx
     175            0 :       bra%pgf_cnt = nelements
     176              : 
     177            0 :    END SUBROUTINE build_pair_list_pbc_pgf
     178              : 
     179              : ! **************************************************************************************************
     180              : !> \brief ...
     181              : !> \param list1 ...
     182              : !> \param list2 ...
     183              : !> \param product_list ...
     184              : !> \param nproducts ...
     185              : !> \param log10_pmax ...
     186              : !> \param log10_eps_schwarz ...
     187              : !> \param neighbor_cells ...
     188              : !> \param cell ...
     189              : !> \param potential_parameter ...
     190              : !> \param m_max ...
     191              : !> \param do_periodic ...
     192              : ! **************************************************************************************************
     193     92588479 :    SUBROUTINE build_pgf_product_list(list1, list2, product_list, nproducts, &
     194              :                                      log10_pmax, log10_eps_schwarz, neighbor_cells, &
     195              :                                      cell, potential_parameter, m_max, do_periodic)
     196              : 
     197              :       TYPE(hfx_pgf_list)                                 :: list1, list2
     198              :       TYPE(hfx_pgf_product_list), ALLOCATABLE, &
     199              :          DIMENSION(:), INTENT(INOUT)                     :: product_list
     200              :       INTEGER, INTENT(OUT)                               :: nproducts
     201              :       REAL(dp), INTENT(IN)                               :: log10_pmax, log10_eps_schwarz
     202              :       TYPE(hfx_cell_type), DIMENSION(:), POINTER         :: neighbor_cells
     203              :       TYPE(cell_type), POINTER                           :: cell
     204              :       TYPE(hfx_potential_type)                           :: potential_parameter
     205              :       INTEGER, INTENT(IN)                                :: m_max
     206              :       LOGICAL, INTENT(IN)                                :: do_periodic
     207              : 
     208              :       REAL(dp), PARAMETER                                :: r_cutoff_eps = 1.0E-12_dp
     209              : 
     210              :       INTEGER                                            :: i, j, k, k_max, l, nimages1, nimages2, &
     211              :                                                             tmp_i4
     212              :       LOGICAL                                            :: has_r_cutoff, use_gamma
     213              :       REAL(dp) :: C11(3), den, Eta, EtaInv, factor, Fm(prim_data_f_size), G(3), min_img_delta, &
     214              :          num, omega2, omega_corr, omega_corr2, P(3), pgf_max_1, pgf_max_2, PQ(3), pq2, Q(3), R, &
     215              :          R1, R2, r_cutoff_sq, r_cutoff_sq_guard, ra(3), rb(3), rc(3), rcut_eff, rd(3), Rho, &
     216              :          RhoInv, rpq2, S1234, S1234a, S1234b, shift(3), ssss, T, temp(3), temp_CC(3), temp_DD(3), &
     217              :          tmp, tmp_D(3), W(3), Zeta1, Zeta_C, Zeta_D, ZetapEtaInv
     218              :       TYPE(hfx_pgf_product_list), ALLOCATABLE, &
     219     92588479 :          DIMENSION(:)                                    :: tmp_product_list
     220              : 
     221     92588479 :       nimages1 = list1%nimages
     222     92588479 :       nimages2 = list2%nimages
     223     92588479 :       nproducts = 0
     224     92588479 :       Zeta1 = list1%zetapzetb
     225     92588479 :       Eta = list2%zetapzetb
     226     92588479 :       EtaInv = list2%ZetaInv
     227     92588479 :       Zeta_C = list2%zeta
     228     92588479 :       Zeta_D = list2%zetb
     229     92588479 :       temp_CC = 0.0_dp
     230     92588479 :       temp_DD = 0.0_dp
     231     92588479 :       r_cutoff_sq = 0.0_dp
     232     92588479 :       r_cutoff_sq_guard = 0.0_dp
     233    104475808 :       SELECT CASE (potential_parameter%potential_type)
     234              :       CASE (do_potential_truncated, do_potential_short, do_potential_mix_cl_trunc)
     235     11887329 :          has_r_cutoff = .TRUE.
     236     11887329 :          rcut_eff = potential_parameter%cutoff_radius
     237              :       CASE (do_potential_TShPSC)
     238      1253728 :          has_r_cutoff = .TRUE.
     239      1253728 :          rcut_eff = potential_parameter%cutoff_radius*2.0_dp
     240              :       CASE DEFAULT
     241              :          has_r_cutoff = .FALSE.
     242     92588479 :          rcut_eff = 0.0_dp
     243              :       END SELECT
     244    196953673 :       DO i = 1, nimages1
     245    417460776 :          P = list1%image_list(i)%P
     246    104365194 :          R1 = list1%image_list(i)%R
     247    104365194 :          S1234a = list1%image_list(i)%S1234
     248    104365194 :          pgf_max_1 = list1%image_list(i)%pgf_max
     249    417460776 :          ra = list1%image_list(i)%ra
     250    417460776 :          rb = list1%image_list(i)%rb
     251    351645024 :          DO j = 1, nimages2
     252    154691351 :             pgf_max_2 = list2%image_list(j)%pgf_max
     253    154691351 :             IF (pgf_max_1 + pgf_max_2 + log10_pmax < log10_eps_schwarz) CYCLE
     254    416817092 :             Q = list2%image_list(j)%P
     255    104204273 :             R2 = list2%image_list(j)%R
     256    104204273 :             S1234b = list2%image_list(j)%S1234
     257    416817092 :             rc = list2%image_list(j)%ra
     258    416817092 :             rd = list2%image_list(j)%rb
     259              : 
     260    104204273 :             IF (has_r_cutoff) THEN
     261     32612694 :                r_cutoff_sq = (R1 + R2 + rcut_eff)**2
     262     32612694 :                r_cutoff_sq_guard = r_cutoff_sq*(1.0_dp + r_cutoff_eps)
     263              :             END IF
     264    104204273 :             k_max = SIZE(neighbor_cells)
     265    104204273 :             IF (do_periodic) THEN
     266    201056652 :                temp = P - Q
     267     50264163 :                PQ = pbc(temp, cell)
     268    200902918 :                IF (has_r_cutoff .AND. cell%orthorhombic .AND. ALL(cell%perd == 1) .AND. k_max >= 1) THEN
     269    102865072 :                   IF (ALL(neighbor_cells(1)%cell_r == 0.0_dp)) THEN
     270     25716268 :                      pq2 = PQ(1)**2 + PQ(2)**2 + PQ(3)**2
     271     25716268 :                      IF (pq2 > r_cutoff_sq_guard) CYCLE
     272     25549582 :                      min_img_delta = min_image_gap_sq(PQ, cell%hmat)
     273     25549582 :                      IF (min_img_delta >= 0.0_dp .AND. pq2 + min_img_delta > r_cutoff_sq_guard) k_max = 1
     274              :                   END IF
     275              :                END IF
     276    200389908 :                shift = -PQ + temp
     277    200389908 :                temp_CC = rc + shift
     278    200389908 :                temp_DD = rd + shift
     279              :             END IF
     280              : 
     281    104037587 :             ZetapEtaInv = Zeta1 + Eta
     282    104037587 :             ZetapEtaInv = 1.0_dp/ZetapEtaInv
     283    104037587 :             Rho = Zeta1*Eta*ZetapEtaInv
     284    104037587 :             RhoInv = 1.0_dp/Rho
     285    104037587 :             S1234 = EXP(S1234a + S1234b)
     286              : 
     287   2627621190 :             DO k = 1, k_max
     288   2419218409 :                IF (do_periodic) THEN
     289   2365278299 :                   IF (has_r_cutoff .AND. k_max > 1) THEN
     290   2334829497 :                      IF ((PQ(1) - neighbor_cells(k)%cell_r(1))**2 + &
     291              :                          (PQ(2) - neighbor_cells(k)%cell_r(2))**2 + &
     292              :                          (PQ(3) - neighbor_cells(k)%cell_r(3))**2 > r_cutoff_sq_guard) CYCLE
     293              :                   END IF
     294   1014087992 :                   C11 = temp_CC + neighbor_cells(k)%cell_r(:)
     295   1014087992 :                   tmp_D = temp_DD + neighbor_cells(k)%cell_r(:)
     296              :                ELSE
     297     53940110 :                   C11 = rc
     298     53940110 :                   tmp_D = rd
     299              :                END IF
     300   1229848432 :                Q = (Zeta_C*C11 + Zeta_D*tmp_D)*EtaInv
     301    307462108 :                rpq2 = (P(1) - Q(1))**2 + (P(2) - Q(2))**2 + (P(3) - Q(3))**2
     302    307462108 :                IF (has_r_cutoff) THEN
     303    235870529 :                   IF (rpq2 > r_cutoff_sq) CYCLE
     304              :                END IF
     305    307462091 :                nproducts = nproducts + 1
     306              : 
     307              :                ! allocate size as needed,
     308              :                ! updating the global size estimate to make this a rare event in longer simulations
     309    307462091 :                IF (nproducts > SIZE(product_list)) THEN
     310          580 : !$OMP              ATOMIC READ
     311              :                   tmp_i4 = pgf_product_list_size
     312          580 :                   tmp_i4 = MAX(pgf_product_list_size, (3*nproducts + 1)/2)
     313          580 : !$OMP              ATOMIC WRITE
     314              :                   pgf_product_list_size = tmp_i4
     315      2130040 :                   ALLOCATE (tmp_product_list(SIZE(product_list)))
     316      2101040 :                   tmp_product_list(:) = product_list
     317          580 :                   DEALLOCATE (product_list)
     318      3181296 :                   ALLOCATE (product_list(tmp_i4))
     319      2101040 :                   product_list(1:SIZE(tmp_product_list)) = tmp_product_list
     320          580 :                   DEALLOCATE (tmp_product_list)
     321              :                END IF
     322              : 
     323    307462091 :                T = Rho*rpq2
     324    529680173 :                SELECT CASE (potential_parameter%potential_type)
     325              :                CASE (do_potential_truncated)
     326    222218082 :                   R = potential_parameter%cutoff_radius*SQRT(Rho)
     327    222218082 :                   CALL t_c_g0_n(product_list(nproducts)%Fm(1), use_gamma, R, T, m_max)
     328    222218082 :                   IF (use_gamma) CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     329    222218082 :                   factor = 2.0_dp*Pi*RhoInv
     330              :                CASE (do_potential_TShPSC)
     331      1160672 :                   R = potential_parameter%cutoff_radius*SQRT(Rho)
     332     25534784 :                   product_list(nproducts)%Fm = 0.0_dp
     333      1160672 :                   CALL trunc_CS_poly_n20(product_list(nproducts)%Fm(1), R, T, m_max)
     334      1160672 :                   factor = 2.0_dp*Pi*RhoInv
     335              :                CASE (do_potential_coulomb)
     336     69074202 :                   CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     337     69074202 :                   factor = 2.0_dp*Pi*RhoInv
     338              :                CASE (do_potential_short)
     339      6542868 :                   CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     340      6542868 :                   omega2 = potential_parameter%omega**2
     341      6542868 :                   omega_corr2 = omega2/(omega2 + Rho)
     342      6542868 :                   omega_corr = SQRT(omega_corr2)
     343      6542868 :                   T = T*omega_corr2
     344      6542868 :                   CALL fgamma(m_max, T, Fm)
     345      6542868 :                   tmp = -omega_corr
     346     29789508 :                   DO l = 1, m_max + 1
     347     23246640 :                      product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l) + Fm(l)*tmp
     348     29789508 :                      tmp = tmp*omega_corr2
     349              :                   END DO
     350      6542868 :                   factor = 2.0_dp*Pi*RhoInv
     351              :                CASE (do_potential_long)
     352      1092553 :                   omega2 = potential_parameter%omega**2
     353      1092553 :                   omega_corr2 = omega2/(omega2 + Rho)
     354      1092553 :                   omega_corr = SQRT(omega_corr2)
     355      1092553 :                   T = T*omega_corr2
     356      1092553 :                   CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     357      1092553 :                   tmp = omega_corr
     358      3846231 :                   DO l = 1, m_max + 1
     359      2753678 :                      product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l)*tmp
     360      3846231 :                      tmp = tmp*omega_corr2
     361              :                   END DO
     362      1092553 :                   factor = 2.0_dp*Pi*RhoInv
     363              :                CASE (do_potential_mix_cl)
     364      1343210 :                   CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     365      1343210 :                   omega2 = potential_parameter%omega**2
     366      1343210 :                   omega_corr2 = omega2/(omega2 + Rho)
     367      1343210 :                   omega_corr = SQRT(omega_corr2)
     368      1343210 :                   T = T*omega_corr2
     369      1343210 :                   CALL fgamma(m_max, T, Fm)
     370      1343210 :                   tmp = omega_corr
     371      5215847 :                   DO l = 1, m_max + 1
     372              :                      product_list(nproducts)%Fm(l) = &
     373              :                         product_list(nproducts)%Fm(l)*potential_parameter%scale_coulomb &
     374      3872637 :                         + Fm(l)*tmp*potential_parameter%scale_longrange
     375      5215847 :                      tmp = tmp*omega_corr2
     376              :                   END DO
     377      1343210 :                   factor = 2.0_dp*Pi*RhoInv
     378              :                CASE (do_potential_mix_cl_trunc)
     379              : 
     380              :                   ! truncated
     381      5948890 :                   R = potential_parameter%cutoff_radius*SQRT(rho)
     382      5948890 :                   CALL t_c_g0_n(product_list(nproducts)%Fm(1), use_gamma, R, T, m_max)
     383      5948890 :                   IF (use_gamma) CALL fgamma(m_max, T, product_list(nproducts)%Fm(1))
     384              : 
     385              :                   ! Coulomb
     386      5948890 :                   CALL fgamma(m_max, T, Fm)
     387              : 
     388     23047065 :                   DO l = 1, m_max + 1
     389              :                      product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l)* &
     390              :                                                      (potential_parameter%scale_coulomb + potential_parameter%scale_longrange) - &
     391     23047065 :                                                      Fm(l)*potential_parameter%scale_longrange
     392              :                   END DO
     393              : 
     394              :                   ! longrange
     395      5948890 :                   omega2 = potential_parameter%omega**2
     396      5948890 :                   omega_corr2 = omega2/(omega2 + Rho)
     397      5948890 :                   omega_corr = SQRT(omega_corr2)
     398      5948890 :                   T = T*omega_corr2
     399      5948890 :                   CALL fgamma(m_max, T, Fm)
     400      5948890 :                   tmp = omega_corr
     401     23047065 :                   DO l = 1, m_max + 1
     402     17098175 :                      product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l) + Fm(l)*tmp*potential_parameter%scale_longrange
     403     23047065 :                      tmp = tmp*omega_corr2
     404              :                   END DO
     405      5948890 :                   factor = 2.0_dp*Pi*RhoInv
     406              : 
     407              :                CASE (do_potential_gaussian)
     408            0 :                   omega2 = potential_parameter%omega**2
     409            0 :                   T = -omega2*T/(Rho + omega2)
     410            0 :                   tmp = 1.0_dp
     411            0 :                   DO l = 1, m_max + 1
     412            0 :                      product_list(nproducts)%Fm(l) = EXP(T)*tmp
     413            0 :                      tmp = tmp*omega2/(Rho + omega2)
     414              :                   END DO
     415            0 :                   factor = (Pi/(Rho + omega2))**(1.5_dp)
     416              :                CASE (do_potential_mix_lg)
     417        29282 :                   omega2 = potential_parameter%omega**2
     418        29282 :                   omega_corr2 = omega2/(omega2 + Rho)
     419        29282 :                   omega_corr = SQRT(omega_corr2)
     420        29282 :                   T = T*omega_corr2
     421        29282 :                   CALL fgamma(m_max, T, Fm)
     422        29282 :                   tmp = omega_corr*2.0_dp*Pi*RhoInv*potential_parameter%scale_longrange
     423       122452 :                   DO l = 1, m_max + 1
     424        93170 :                      Fm(l) = Fm(l)*tmp
     425       122452 :                      tmp = tmp*omega_corr2
     426              :                   END DO
     427              :                   T = Rho*rpq2
     428        29282 :                   T = -omega2*T/(Rho + omega2)
     429        29282 :                   tmp = (Pi/(Rho + omega2))**(1.5_dp)*potential_parameter%scale_gaussian
     430       122452 :                   DO l = 1, m_max + 1
     431        93170 :                      product_list(nproducts)%Fm(l) = EXP(T)*tmp + Fm(l)
     432       122452 :                      tmp = tmp*omega2/(Rho + omega2)
     433              :                   END DO
     434        52332 :                   factor = 1.0_dp
     435              :                CASE (do_potential_id)
     436        52332 :                   num = list1%zeta*list1%zetb
     437        52332 :                   den = list1%zeta + list1%zetb
     438       209328 :                   ssss = -num/den*SUM((ra - rb)**2)
     439              : 
     440        52332 :                   num = den*Zeta_C
     441        52332 :                   den = den + Zeta_C
     442       209328 :                   ssss = ssss - num/den*SUM((P - rc)**2)
     443              : 
     444       209328 :                   G(:) = (list1%zeta*ra(:) + list1%zetb*rb(:) + Zeta_C*rc(:))/den
     445        52332 :                   num = den*Zeta_D
     446        52332 :                   den = den + Zeta_D
     447       209328 :                   ssss = ssss - num/den*SUM((G - rd)**2)
     448              : 
     449      1151304 :                   product_list(nproducts)%Fm(:) = EXP(ssss)
     450        52332 :                   factor = 1.0_dp
     451    307514423 :                   IF (S1234 > EPSILON(0.0_dp)) factor = 1.0_dp/S1234
     452              :                END SELECT
     453              : 
     454    307462091 :                tmp = (Pi*ZetapEtaInv)**3
     455    307462091 :                factor = factor*S1234*SQRT(tmp)
     456              : 
     457   1102349504 :                DO l = 1, m_max + 1
     458   1102349504 :                   product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l)*factor
     459              :                END DO
     460              : 
     461   1229848364 :                W = (Zeta1*P + Eta*Q)*ZetapEtaInv
     462   1229848364 :                product_list(nproducts)%ra = ra
     463   1229848364 :                product_list(nproducts)%rb = rb
     464   1229848364 :                product_list(nproducts)%rc = C11
     465   1229848364 :                product_list(nproducts)%rd = tmp_D
     466    307462091 :                product_list(nproducts)%ZetapEtaInv = ZetapEtaInv
     467    307462091 :                product_list(nproducts)%Rho = Rho
     468    307462091 :                product_list(nproducts)%RhoInv = RhoInv
     469   1229848364 :                product_list(nproducts)%P = P
     470   1229848364 :                product_list(nproducts)%Q = Q
     471   1229848364 :                product_list(nproducts)%W = W
     472   1229848364 :                product_list(nproducts)%AB = ra - rb
     473   3496296033 :                product_list(nproducts)%CD = C11 - tmp_D
     474              :             END DO
     475              :          END DO
     476              :       END DO
     477              : 
     478     92588479 :    END SUBROUTINE build_pgf_product_list
     479              : 
     480              : ! **************************************************************************************************
     481              : !> \brief ...
     482              : !> \param npgfa ...
     483              : !> \param npgfb ...
     484              : !> \param list ...
     485              : !> \param zeta ...
     486              : !> \param zetb ...
     487              : !> \param screen1 ...
     488              : !> \param screen2 ...
     489              : !> \param pgf ...
     490              : !> \param R_pgf ...
     491              : !> \param log10_pmax ...
     492              : !> \param log10_eps_schwarz ...
     493              : !> \param ra ...
     494              : !> \param rb ...
     495              : !> \param nelements ...
     496              : !> \param neighbor_cells ...
     497              : !> \param nimages ...
     498              : !> \param do_periodic ...
     499              : !> \param cell ...
     500              : ! **************************************************************************************************
     501     20917836 :    SUBROUTINE build_pair_list_pgf(npgfa, npgfb, list, zeta, zetb, screen1, screen2, pgf, R_pgf, &
     502              :                                   log10_pmax, log10_eps_schwarz, ra, rb, nelements, &
     503     20917836 :                                   neighbor_cells, nimages, do_periodic, cell)
     504              :       INTEGER, INTENT(IN)                                :: npgfa, npgfb
     505              :       TYPE(hfx_pgf_list), DIMENSION(npgfa*npgfb)         :: list
     506              :       REAL(dp), DIMENSION(1:npgfa), INTENT(IN)           :: zeta
     507              :       REAL(dp), DIMENSION(1:npgfb), INTENT(IN)           :: zetb
     508              :       REAL(dp), INTENT(IN)                               :: screen1(2), screen2(2)
     509              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     510              :          POINTER                                         :: pgf, R_pgf
     511              :       REAL(dp), INTENT(IN)                               :: log10_pmax, log10_eps_schwarz, ra(3), &
     512              :                                                             rb(3)
     513              :       INTEGER, INTENT(OUT)                               :: nelements
     514              :       TYPE(hfx_cell_type), DIMENSION(:), POINTER         :: neighbor_cells
     515              :       INTEGER                                            :: nimages(npgfa*npgfb)
     516              :       LOGICAL, INTENT(IN)                                :: do_periodic
     517              :       TYPE(cell_type), POINTER                           :: cell
     518              : 
     519              :       REAL(dp), PARAMETER                                :: min_img_eps = 1.0E-12_dp
     520              : 
     521              :       INTEGER                                            :: element_counter, i, i_max, ipgf, j, jpgf
     522              :       REAL(dp)                                           :: AB(3), im_B(3), min_img_delta, pgf_max, &
     523              :                                                             rab2, Zeta1, Zeta_A, Zeta_B, ZetaInv
     524              : 
     525     20917836 :       i_max = SIZE(neighbor_cells)
     526     20917836 :       IF (do_periodic) THEN
     527      8004402 :          IF (cell%orthorhombic .AND. screen1(1) <= 0.0_dp .AND. i_max > 1) THEN
     528     10961260 :             IF (ALL(cell%perd == 1) .AND. ALL(neighbor_cells(1)%cell_r == 0.0_dp)) THEN
     529      6225784 :                AB = ra - rb
     530      1556446 :                rab2 = AB(1)**2 + AB(2)**2 + AB(3)**2
     531      1556446 :                min_img_delta = min_image_gap_sq(AB, cell%hmat)
     532      1556446 :                IF (min_img_delta >= 0.0_dp) THEN
     533      1556446 :                   IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) THEN
     534            0 :                      nelements = 0
     535            0 :                      RETURN
     536              :                   END IF
     537      1556446 :                   IF (screen1(1)*(rab2 + min_img_delta)*(1.0_dp - min_img_eps) + &
     538       824058 :                       screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) i_max = 1
     539              :                END IF
     540              :             END IF
     541              :          END IF
     542              :       ELSE
     543     12913434 :          i_max = MIN(i_max, 1)
     544              :       END IF
     545     77661623 :       nimages = 0
     546              :       ! ** inner loop may never be reached
     547     20917836 :       nelements = npgfa*npgfb
     548    115381922 :       DO i = 1, i_max
     549     94464086 :          IF (do_periodic) THEN
     550    326202608 :             im_B = rb + neighbor_cells(i)%cell_r(:)
     551              :          ELSE
     552     12913434 :             im_B = rb
     553              :          END IF
     554    377856344 :          AB = ra - im_B
     555     94464086 :          rab2 = AB(1)**2 + AB(2)**2 + AB(3)**2
     556     94464086 :          IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) CYCLE
     557              :          element_counter = 0
     558     69169424 :          DO ipgf = 1, npgfa
     559    137686166 :             DO jpgf = 1, npgfb
     560     68516742 :                element_counter = element_counter + 1
     561     68516742 :                pgf_max = pgf(jpgf, ipgf)%x(1)*rab2 + pgf(jpgf, ipgf)%x(2)
     562     68516742 :                IF (pgf_max + screen2(2) + log10_pmax < log10_eps_schwarz) THEN
     563              :                   CYCLE
     564              :                END IF
     565     57720747 :                nimages(element_counter) = nimages(element_counter) + 1
     566     57720747 :                list(element_counter)%image_list(nimages(element_counter))%pgf_max = pgf_max
     567    230882988 :                list(element_counter)%image_list(nimages(element_counter))%ra = ra
     568    230882988 :                list(element_counter)%image_list(nimages(element_counter))%rb = im_B
     569     57720747 :                list(element_counter)%image_list(nimages(element_counter))%rab2 = rab2
     570              : 
     571     57720747 :                Zeta_A = zeta(ipgf)
     572     57720747 :                Zeta_B = zetb(jpgf)
     573     57720747 :                Zeta1 = Zeta_A + Zeta_B
     574     57720747 :                ZetaInv = 1.0_dp/Zeta1
     575              : 
     576     57720747 :                IF (nimages(element_counter) == 1) THEN
     577     50311536 :                   list(element_counter)%ipgf = ipgf
     578     50311536 :                   list(element_counter)%jpgf = jpgf
     579     50311536 :                   list(element_counter)%zetaInv = ZetaInv
     580     50311536 :                   list(element_counter)%zetapzetb = Zeta1
     581     50311536 :                   list(element_counter)%zeta = Zeta_A
     582     50311536 :                   list(element_counter)%zetb = Zeta_B
     583              :                END IF
     584              : 
     585     57720747 :                list(element_counter)%image_list(nimages(element_counter))%S1234 = (-Zeta_A*Zeta_B*ZetaInv*rab2)
     586    230882988 :                list(element_counter)%image_list(nimages(element_counter))%P = (Zeta_A*ra + Zeta_B*im_B)*ZetaInv
     587              :                list(element_counter)%image_list(nimages(element_counter))%R = &
     588     57720747 :                   MAX(0.0_dp, R_pgf(jpgf, ipgf)%x(1)*rab2 + R_pgf(jpgf, ipgf)%x(2))
     589    230882988 :                list(element_counter)%image_list(nimages(element_counter))%ra = ra
     590    230882988 :                list(element_counter)%image_list(nimages(element_counter))%rb = im_B
     591     57720747 :                list(element_counter)%image_list(nimages(element_counter))%rab2 = rab2
     592    284159570 :                list(element_counter)%image_list(nimages(element_counter))%bcell = neighbor_cells(i)%cell
     593              :             END DO
     594              :          END DO
     595    115381922 :          nelements = MAX(nelements, element_counter)
     596              :       END DO
     597     77661623 :       DO j = 1, nelements
     598     77661623 :          list(j)%nimages = nimages(j)
     599              :       END DO
     600              :       ! ** Remove unused elements
     601              : 
     602              :       element_counter = 0
     603     77661623 :       DO j = 1, nelements
     604     56743787 :          IF (list(j)%nimages == 0) CYCLE
     605     50311536 :          element_counter = element_counter + 1
     606     50311536 :          list(element_counter)%nimages = list(j)%nimages
     607     50311536 :          list(element_counter)%zetapzetb = list(j)%zetapzetb
     608     50311536 :          list(element_counter)%ZetaInv = list(j)%ZetaInv
     609     50311536 :          list(element_counter)%zeta = list(j)%zeta
     610     50311536 :          list(element_counter)%zetb = list(j)%zetb
     611     50311536 :          list(element_counter)%ipgf = list(j)%ipgf
     612     50311536 :          list(element_counter)%jpgf = list(j)%jpgf
     613    128950119 :          DO i = 1, list(j)%nimages
     614    114464534 :             list(element_counter)%image_list(i) = list(j)%image_list(i)
     615              :          END DO
     616              :       END DO
     617              : 
     618     20917836 :       nelements = element_counter
     619              : 
     620              :    END SUBROUTINE build_pair_list_pgf
     621              : 
     622              : ! **************************************************************************************************
     623              : !> \brief ...
     624              : !> \param natom ...
     625              : !> \param list ...
     626              : !> \param set_list ...
     627              : !> \param i_start ...
     628              : !> \param i_end ...
     629              : !> \param j_start ...
     630              : !> \param j_end ...
     631              : !> \param kind_of ...
     632              : !> \param basis_parameter ...
     633              : !> \param particle_set ...
     634              : !> \param do_periodic ...
     635              : !> \param coeffs_set ...
     636              : !> \param coeffs_kind ...
     637              : !> \param coeffs_kind_max0 ...
     638              : !> \param log10_eps_schwarz ...
     639              : !> \param cell ...
     640              : !> \param pmax_blocks ...
     641              : !> \param atomic_pair_list ...
     642              : ! **************************************************************************************************
     643     52678956 :    SUBROUTINE build_pair_list(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, &
     644      3801644 :                               do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
     645      3801644 :                               pmax_blocks, atomic_pair_list)
     646              : 
     647              :       INTEGER, INTENT(IN)                                :: natom
     648              :       TYPE(pair_list_type), INTENT(INOUT)                :: list
     649              :       TYPE(pair_set_list_type), DIMENSION(:), &
     650              :          INTENT(OUT)                                     :: set_list
     651              :       INTEGER, INTENT(IN)                                :: i_start, i_end, j_start, j_end, &
     652              :                                                             kind_of(*)
     653              :       TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
     654              :          POINTER                                         :: basis_parameter
     655              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
     656              :          POINTER                                         :: particle_set
     657              :       LOGICAL, INTENT(IN)                                :: do_periodic
     658              :       TYPE(hfx_screen_coeff_type), &
     659              :          DIMENSION(:, :, :, :), INTENT(IN), POINTER      :: coeffs_set
     660              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     661              :          INTENT(IN)                                      :: coeffs_kind
     662              :       REAL(KIND=dp), INTENT(IN)                          :: coeffs_kind_max0, log10_eps_schwarz
     663              :       TYPE(cell_type), POINTER                           :: cell
     664              :       REAL(dp), INTENT(IN)                               :: pmax_blocks
     665              :       LOGICAL, DIMENSION(natom, natom), INTENT(IN)       :: atomic_pair_list
     666              : 
     667              :       INTEGER                                            :: iatom, ikind, iset, jatom, jkind, jset, &
     668              :                                                             n_element, nset_ij, nseta, nsetb
     669              :       REAL(KIND=dp)                                      :: rab2
     670              :       REAL(KIND=dp), DIMENSION(3)                        :: B11, pbc_B, ra, rb, temp
     671              : 
     672      3801644 :       n_element = 0
     673      3801644 :       nset_ij = 0
     674              : 
     675      7603288 :       DO iatom = i_start, i_end
     676     11404932 :          DO jatom = j_start, j_end
     677      3801644 :             IF (atomic_pair_list(jatom, iatom) .EQV. .FALSE.) CYCLE
     678              : 
     679      3667994 :             ikind = kind_of(iatom)
     680      3667994 :             nseta = basis_parameter(ikind)%nset
     681     14671976 :             ra = particle_set(iatom)%r(:)
     682              : 
     683      3667994 :             IF (jatom < iatom) CYCLE
     684      3667994 :             jkind = kind_of(jatom)
     685      3667994 :             nsetb = basis_parameter(jkind)%nset
     686     14671976 :             rb = particle_set(jatom)%r(:)
     687              : 
     688      3667994 :             IF (do_periodic) THEN
     689      4695560 :                temp = rb - ra
     690      1173890 :                pbc_B = pbc(temp, cell)
     691      4695560 :                B11 = ra + pbc_B
     692      1173890 :                rab2 = (ra(1) - B11(1))**2 + (ra(2) - B11(2))**2 + (ra(3) - B11(3))**2
     693              :             ELSE
     694      2494104 :                rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
     695      2494104 :                B11 = rb ! ra - rb
     696              :             END IF
     697      3667994 :             IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
     698              :                  coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) CYCLE
     699              : 
     700      3661524 :             n_element = n_element + 1
     701     10984572 :             list%elements(n_element)%pair = [iatom, jatom]
     702     10984572 :             list%elements(n_element)%kind_pair = [ikind, jkind]
     703     14646096 :             list%elements(n_element)%r1 = ra
     704     14646096 :             list%elements(n_element)%r2 = B11
     705      3661524 :             list%elements(n_element)%dist2 = rab2
     706              :             ! build a list of guaranteed overlapping sets
     707      3661524 :             list%elements(n_element)%set_bounds(1) = nset_ij + 1
     708     12364554 :             DO iset = 1, nseta
     709     36779176 :                DO jset = 1, nsetb
     710     24414622 :                   IF (coeffs_set(jset, iset, jkind, ikind)%x(1)*rab2 + coeffs_set(jset, iset, jkind, ikind)%x(2) + &
     711              :                       coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) CYCLE
     712     23210674 :                   nset_ij = nset_ij + 1
     713     79539000 :                   set_list(nset_ij)%pair = [iset, jset]
     714              :                END DO
     715              :             END DO
     716      7603288 :             list%elements(n_element)%set_bounds(2) = nset_ij
     717              :          END DO
     718              :       END DO
     719              : 
     720      3801644 :       list%n_element = n_element
     721              : 
     722      3801644 :    END SUBROUTINE build_pair_list
     723              : 
     724              : ! **************************************************************************************************
     725              : !> \brief ...
     726              : !> \param natom ...
     727              : !> \param atomic_pair_list ...
     728              : !> \param kind_of ...
     729              : !> \param basis_parameter ...
     730              : !> \param particle_set ...
     731              : !> \param do_periodic ...
     732              : !> \param coeffs_kind ...
     733              : !> \param coeffs_kind_max0 ...
     734              : !> \param log10_eps_schwarz ...
     735              : !> \param cell ...
     736              : !> \param blocks ...
     737              : ! **************************************************************************************************
     738         6238 :    SUBROUTINE build_atomic_pair_list(natom, atomic_pair_list, kind_of, basis_parameter, particle_set, &
     739         6238 :                                      do_periodic, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
     740              :                                      blocks)
     741              :       INTEGER, INTENT(IN)                                :: natom
     742              :       LOGICAL, DIMENSION(natom, natom)                   :: atomic_pair_list
     743              :       INTEGER, INTENT(IN)                                :: kind_of(*)
     744              :       TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
     745              :          POINTER                                         :: basis_parameter
     746              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
     747              :          POINTER                                         :: particle_set
     748              :       LOGICAL, INTENT(IN)                                :: do_periodic
     749              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     750              :          INTENT(IN)                                      :: coeffs_kind
     751              :       REAL(KIND=dp), INTENT(IN)                          :: coeffs_kind_max0, log10_eps_schwarz
     752              :       TYPE(cell_type), POINTER                           :: cell
     753              :       TYPE(hfx_block_range_type), DIMENSION(:), &
     754              :          INTENT(IN), POINTER                             :: blocks
     755              : 
     756              :       INTEGER                                            :: iatom, iatom_end, iatom_start, iblock, &
     757              :                                                             ikind, jatom, jatom_end, jatom_start, &
     758              :                                                             jblock, jkind, nseta, nsetb
     759              :       REAL(KIND=dp)                                      :: rab2
     760              :       REAL(KIND=dp), DIMENSION(3)                        :: B11, pbc_B, ra, rb, temp
     761              : 
     762        93482 :       atomic_pair_list = .FALSE.
     763              : 
     764        25080 :       DO iblock = 1, SIZE(blocks)
     765        18842 :          iatom_start = blocks(iblock)%istart
     766        18842 :          iatom_end = blocks(iblock)%iend
     767        93482 :          DO jblock = 1, SIZE(blocks)
     768        68402 :             jatom_start = blocks(jblock)%istart
     769        68402 :             jatom_end = blocks(jblock)%iend
     770              : 
     771       155646 :             DO iatom = iatom_start, iatom_end
     772        68402 :                ikind = kind_of(iatom)
     773        68402 :                nseta = basis_parameter(ikind)%nset
     774       273608 :                ra = particle_set(iatom)%r(:)
     775       205206 :                DO jatom = jatom_start, jatom_end
     776        68402 :                   IF (jatom < iatom) CYCLE
     777        43622 :                   jkind = kind_of(jatom)
     778        43622 :                   nsetb = basis_parameter(jkind)%nset
     779       174488 :                   rb = particle_set(jatom)%r(:)
     780              : 
     781        43622 :                   IF (do_periodic) THEN
     782        50504 :                      temp = rb - ra
     783        12626 :                      pbc_B = pbc(temp, cell)
     784        50504 :                      B11 = ra + pbc_B
     785        12626 :                      rab2 = (ra(1) - B11(1))**2 + (ra(2) - B11(2))**2 + (ra(3) - B11(3))**2
     786              :                   ELSE
     787        30996 :                      rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
     788        30996 :                      B11 = rb ! ra - rb
     789              :                   END IF
     790        43622 :                   IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
     791              :                        coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 < log10_eps_schwarz) CYCLE
     792              : 
     793        43166 :                   atomic_pair_list(jatom, iatom) = .TRUE.
     794       136804 :                   atomic_pair_list(iatom, jatom) = .TRUE.
     795              :                END DO
     796              :             END DO
     797              :          END DO
     798              :       END DO
     799              : 
     800         6238 :    END SUBROUTINE build_atomic_pair_list
     801              : 
     802              : ! **************************************************************************************************
     803              : !> \brief ...
     804              : !> \param natom ...
     805              : !> \param list ...
     806              : !> \param set_list ...
     807              : !> \param i_start ...
     808              : !> \param i_end ...
     809              : !> \param j_start ...
     810              : !> \param j_end ...
     811              : !> \param kind_of ...
     812              : !> \param basis_parameter ...
     813              : !> \param particle_set ...
     814              : !> \param do_periodic ...
     815              : !> \param coeffs_set ...
     816              : !> \param coeffs_kind ...
     817              : !> \param coeffs_kind_max0 ...
     818              : !> \param log10_eps_schwarz ...
     819              : !> \param cell ...
     820              : !> \param pmax_blocks ...
     821              : !> \param atomic_pair_list ...
     822              : !> \param skip_atom_symmetry ...
     823              : ! **************************************************************************************************
     824       595568 :    SUBROUTINE build_pair_list_mp2(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, &
     825         2994 :                                   do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
     826         2994 :                                   pmax_blocks, atomic_pair_list, skip_atom_symmetry)
     827              : 
     828              :       INTEGER, INTENT(IN)                                :: natom
     829              :       TYPE(pair_list_type_mp2), INTENT(INOUT)            :: list
     830              :       TYPE(pair_set_list_type), DIMENSION(:), &
     831              :          INTENT(OUT)                                     :: set_list
     832              :       INTEGER, INTENT(IN)                                :: i_start, i_end, j_start, j_end, &
     833              :                                                             kind_of(*)
     834              :       TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
     835              :          POINTER                                         :: basis_parameter
     836              :       TYPE(particle_type), DIMENSION(:), INTENT(IN), &
     837              :          POINTER                                         :: particle_set
     838              :       LOGICAL, INTENT(IN)                                :: do_periodic
     839              :       TYPE(hfx_screen_coeff_type), &
     840              :          DIMENSION(:, :, :, :), INTENT(IN), POINTER      :: coeffs_set
     841              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     842              :          INTENT(IN)                                      :: coeffs_kind
     843              :       REAL(KIND=dp), INTENT(IN)                          :: coeffs_kind_max0, log10_eps_schwarz
     844              :       TYPE(cell_type), POINTER                           :: cell
     845              :       REAL(dp), INTENT(IN)                               :: pmax_blocks
     846              :       LOGICAL, DIMENSION(natom, natom), INTENT(IN)       :: atomic_pair_list
     847              :       LOGICAL, INTENT(IN), OPTIONAL                      :: skip_atom_symmetry
     848              : 
     849              :       INTEGER                                            :: iatom, ikind, iset, jatom, jkind, jset, &
     850              :                                                             n_element, nset_ij, nseta, nsetb
     851              :       LOGICAL                                            :: my_skip_atom_symmetry
     852              :       REAL(KIND=dp)                                      :: rab2
     853              :       REAL(KIND=dp), DIMENSION(3)                        :: B11, pbc_B, ra, rb, temp
     854              : 
     855         2994 :       n_element = 0
     856         2994 :       nset_ij = 0
     857              : 
     858         2994 :       my_skip_atom_symmetry = .FALSE.
     859         2994 :       IF (PRESENT(skip_atom_symmetry)) my_skip_atom_symmetry = skip_atom_symmetry
     860              : 
     861         6076 :       DO iatom = i_start, i_end
     862         9454 :          DO jatom = j_start, j_end
     863         3378 :             IF (atomic_pair_list(jatom, iatom) .EQV. .FALSE.) CYCLE
     864              : 
     865         3378 :             ikind = kind_of(iatom)
     866         3378 :             nseta = basis_parameter(ikind)%nset
     867        13512 :             ra = particle_set(iatom)%r(:)
     868              : 
     869         3378 :             IF (jatom < iatom .AND. (.NOT. my_skip_atom_symmetry)) CYCLE
     870         3230 :             jkind = kind_of(jatom)
     871         3230 :             nsetb = basis_parameter(jkind)%nset
     872        12920 :             rb = particle_set(jatom)%r(:)
     873              : 
     874         3230 :             IF (do_periodic) THEN
     875            0 :                temp = rb - ra
     876            0 :                pbc_B = pbc(temp, cell)
     877            0 :                B11 = ra + pbc_B
     878            0 :                rab2 = (ra(1) - B11(1))**2 + (ra(2) - B11(2))**2 + (ra(3) - B11(3))**2
     879              :             ELSE
     880         3230 :                rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
     881         3230 :                B11 = rb ! ra - rb
     882              :             END IF
     883         3230 :             IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
     884              :                  coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) CYCLE
     885              : 
     886         3230 :             n_element = n_element + 1
     887         9690 :             list%elements(n_element)%pair = [iatom, jatom]
     888         9690 :             list%elements(n_element)%kind_pair = [ikind, jkind]
     889        12920 :             list%elements(n_element)%r1 = ra
     890        12920 :             list%elements(n_element)%r2 = B11
     891         3230 :             list%elements(n_element)%dist2 = rab2
     892              :             ! build a list of guaranteed overlapping sets
     893         3230 :             list%elements(n_element)%set_bounds(1) = nset_ij + 1
     894        13988 :             DO iset = 1, nseta
     895        52586 :                DO jset = 1, nsetb
     896        38598 :                   IF (coeffs_set(jset, iset, jkind, ikind)%x(1)*rab2 + coeffs_set(jset, iset, jkind, ikind)%x(2) + &
     897              :                       coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) CYCLE
     898        38526 :                   nset_ij = nset_ij + 1
     899       126408 :                   set_list(nset_ij)%pair = [iset, jset]
     900              :                END DO
     901              :             END DO
     902         6460 :             list%elements(n_element)%set_bounds(2) = nset_ij
     903              :          END DO
     904              :       END DO
     905              : 
     906         2994 :       list%n_element = n_element
     907              : 
     908         2994 :    END SUBROUTINE build_pair_list_mp2
     909              : 
     910              : ! **************************************************************************************************
     911              : !> \brief Smallest increase of |r|**2 when r is moved to any other periodic image of an
     912              : !>        orthorhombic, fully periodic cell, i.e. min over n /= 0 of |r - hmat*n|**2 - |r|**2.
     913              : !>        Exact if r is a minimum-image vector (|r(i)| <= |hmat(i,i)|/2); negative otherwise.
     914              : !> \param r displacement vector
     915              : !> \param hmat cell matrix; its diagonal entries are signed cell-vector components
     916              : !> \return the squared-distance gap to the nearest other periodic image
     917              : ! **************************************************************************************************
     918     27145334 :    PURE FUNCTION min_image_gap_sq(r, hmat) RESULT(gap)
     919              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: r
     920              :       REAL(dp), DIMENSION(3, 3), INTENT(IN)              :: hmat
     921              :       REAL(dp)                                           :: gap
     922              : 
     923              :       REAL(dp), DIMENSION(3)                             :: cell_len
     924              : 
     925    108581336 :       cell_len = [ABS(hmat(1, 1)), ABS(hmat(2, 2)), ABS(hmat(3, 3))]
     926    108581336 :       gap = MINVAL(cell_len*(cell_len - 2.0_dp*ABS(r)))
     927              : 
     928     27145334 :    END FUNCTION min_image_gap_sq
     929              : 
     930            0 : END MODULE hfx_pair_list_methods
        

Generated by: LCOV version 2.0-1