LCOV - code coverage report
Current view: top level - src - libgint_wrapper.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:c24029e) Lines: 0.0 % 24 0
Test Date: 2026-07-04 06:36:57 Functions: 0.0 % 8 0

            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 Interface to the LibGint-Library.
      10              : !> \par History
      11              : !>      10.2024 Created
      12              : !> \author Marcello Puligheddu
      13              : ! **************************************************************************************************
      14              : MODULE libGint_wrapper
      15              : 
      16              :    USE kinds, ONLY: dp
      17              : #if(__LIBGINT)
      18              :    USE input_constants, ONLY: do_potential_coulomb, do_potential_truncated
      19              :    USE libGint, ONLY: libgint_init, libgint_set_Potential_Truncated, libgint_set_hf_fac, libgint_set_max_mem, &
      20              :                       libgint_set_P, libgint_set_P_polarized, libgint_set_K, libgint_set_K_polarized, &
      21              :                       libgint_get_K, libgint_get_K_polarized, libgint_set_Atom, libgint_set_Atom_L, &
      22              :                       libgint_set_cell, libgint_set_neighs, &
      23              :                       libgint_add_prm, libgint_add_shell, libgint_add_cell, libgint_add_qrt, &
      24              :                       libgint_add_qrtt, libgint_add_set
      25              :    USE t_c_g0, ONLY: C0
      26              : #endif
      27              :    USE hfx_types, ONLY: hfx_type, hfx_memory_type, hfx_potential_type, &
      28              :                         hfx_screen_coeff_type, hfx_cell_type, hfx_basis_type
      29              : 
      30              :    USE cell_types, ONLY: cell_type
      31              :    USE hfx_pair_list_methods, ONLY: build_pair_list_pbc_pgf, bra_t, allocate_bra
      32              :    USE particle_types, ONLY: particle_type
      33              : 
      34              :    USE iso_C_binding, ONLY: c_ptr
      35              : 
      36              : #include "./base/base_uses.f90"
      37              :    IMPLICIT NONE
      38              :    PRIVATE
      39              :    INTEGER, ALLOCATABLE, DIMENSION(:), SAVE :: first_set_of_atom
      40              :    TYPE(bra_t), TARGET, SAVE :: bra, ket
      41              :    LOGICAL, SAVE :: first_call = .TRUE.
      42              :    TYPE(c_ptr), SAVE :: libGint_handle
      43              :    !$OMP THREADPRIVATE( first_set_of_atom, first_call )
      44              :    !$OMP THREADPRIVATE( bra,ket )
      45              :    !$OMP THREADPRIVATE( libGint_handle )
      46              : 
      47              :    PUBLIC :: cp_libGint_init, libGint_update_env, libGint_set_density, libGint_coulomb4, &
      48              :              libGint_update_fock_matrix, libGint_get_fock_matrix
      49              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'libGint_wrapper'
      50              : 
      51              : ! Comunicates the current density to the libGint engine.
      52              : ! Sets the Fock matrix on the device to zero
      53              :    INTERFACE libGint_set_density
      54              :       MODULE PROCEDURE libGint_set_density_A
      55              :       MODULE PROCEDURE libGint_set_density_AB
      56              :    END INTERFACE
      57              : 
      58              :    INTERFACE libGint_get_fock_matrix
      59              :       MODULE PROCEDURE libGint_get_fock_matrix_A
      60              :       MODULE PROCEDURE libGint_get_fock_matrix_AB
      61              :    END INTERFACE
      62              : 
      63              : CONTAINS
      64              : ! **************************************************************************************************
      65              : !> \brief Sets libGint internal enviroment, must be called at least once before libGint can be used
      66              : !> \param[in] actual_x_data    pointer to hfx_data
      67              : ! **************************************************************************************************
      68            0 :    SUBROUTINE cp_libGint_init(actual_x_data)
      69              : 
      70              :       TYPE(hfx_type), POINTER, INTENT(in) :: actual_x_data
      71              : #if(__LIBGINT)
      72              :       ! Init the offload library, creates an handle unique to this omp thread
      73              :       CALL libgint_init(libGint_handle)
      74              :       ! Comunicate the chosen potential and its parameters to libGint
      75              :       IF (actual_x_data%potential_parameter%potential_type == do_potential_truncated) THEN
      76              :          ! truncated coulomb needs the C0 coefficients. We do not read or compute them,
      77              :          ! they must be already saved in C0 from the t[runcated]_c[oulomb]_g0 module
      78              :          CALL libgint_set_Potential_Truncated(libGint_handle, &
      79              :                                               actual_x_data%potential_parameter%cutoff_radius, &
      80              :                                               C0(:, :))
      81              :       ELSE
      82              :          CPABORT("The selected interaction potential type is not available with libGint")
      83              :       END IF
      84              :       first_call = .FALSE.
      85              : #else
      86              :       MARK_USED(actual_x_data)
      87            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
      88              : #endif
      89            0 :    END SUBROUTINE cp_libGint_init
      90              : ! **************************************************************************************************
      91              : !> \brief Initialize and update the libGint computational environment. Must be called at least once
      92              : !>        after geo_change and before libGint can be used.
      93              : !>
      94              : !> This routine sets up data required by the libGint integral engine, including
      95              : !> Hartree–Fock scaling factors, memory limits, periodic cell information, and
      96              : !> per-atom/basis-set data. It also allocates CPU-side buffers (`bra` and `ket`)
      97              : !> used for storing screened Gaussian primitive pairs.
      98              : !>
      99              : !> \param[in]  fac              Fraction of exact exchange
     100              : !> \param[in]  memory_parameter Pointer to memory configuration
     101              : !> \param[in]  do_periodic      Logical flag: whether to consider pbc
     102              : !> \param[in]  cell             primitive simulation cell
     103              : !> \param[in]  actual_x_data    HF exchange data
     104              : !> \param[in]  nneighbors       Lattice points
     105              : !> \param[in]  max_pgf          Maximum number of primitive Gaussians per shel
     106              : !> \param[in]  natom            Number of atoms in the system
     107              : !> \param[in]  kind_of          Array mapping atom indices to atomic kinds
     108              : !> \param[in]  particle_set     particle set, we extract the positions
     109              : !> \param[in]  basis_parameter  gaussian basis set parameters
     110              : !>
     111              : ! **************************************************************************************************
     112            0 :    SUBROUTINE libGint_update_env(fac, memory_parameter, do_periodic, cell, actual_x_data, nneighbors, max_pgf, &
     113              :                                  natom, kind_of, particle_set, basis_parameter)
     114              : 
     115              :       REAL(dp) :: fac
     116              :       TYPE(hfx_memory_type), POINTER :: memory_parameter
     117              :       LOGICAL :: do_periodic
     118              :       TYPE(cell_type), POINTER :: cell
     119              :       TYPE(hfx_type), POINTER :: actual_x_data
     120              :       INTEGER :: nneighbors, max_pgf, natom
     121              :       INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
     122              :       TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
     123              :       TYPE(hfx_basis_type), DIMENSION(:), POINTER :: basis_parameter
     124              : #if(__LIBGINT)
     125              :       LOGICAL(1) :: do_pbc
     126              :       REAL(dp), DIMENSION(:, :), ALLOCATABLE :: cell_r
     127              :       REAL(dp), DIMENSION(:), ALLOCATABLE :: flat_gcc
     128              :       INTEGER, DIMENSION(:), POINTER :: la_min, la_max, npgfa, nsgfa
     129              :       INTEGER, DIMENSION(:, :), POINTER :: nsgfl_a
     130              :       INTEGER :: i, l, iset, jset, iatom, ikind, nseta, inla, nla
     131              :       REAL(dp) :: ra(3)
     132              :       REAL(dp), DIMENSION(:, :), POINTER :: zeta
     133              :       REAL(dp), DIMENSION(:, :, :), POINTER :: gcc
     134              :       TYPE(bra_t), POINTER                               :: bra_p, ket_p
     135              : 
     136              :       ! Set the multiplicative factor fac (the fraction of exact exchange times the spin factor) for libGint
     137              :       CALL libGint_set_hf_fac(libGint_handle, fac)
     138              :       ! Comunicate max gpu mem per mpi
     139              :       CALL libGint_set_max_mem(libGint_handle, memory_parameter%max_memory)
     140              : 
     141              :       ! Info about periodic cells and neighbouring cells
     142              :       do_pbc = do_periodic
     143              :       ALLOCATE (cell_r(3, nneighbors))
     144              :       DO i = 1, nneighbors
     145              :          cell_r(:, i) = actual_x_data%neighbor_cells(i)%cell_r(:)
     146              :       END DO
     147              :       CALL libgint_set_cell(libGint_handle, do_pbc, cell%hmat, cell%h_inv)
     148              :       CALL libgint_set_neighs(libGint_handle, cell_r, nneighbors)
     149              : 
     150              :       ! CPU side temporary arrays for info about the <AB(g) and CD(n)> pairs
     151              :       bra_p => bra
     152              :       ket_p => ket
     153              :       CALL allocate_bra(bra_p, max_pgf, nneighbors)
     154              :       CALL allocate_bra(ket_p, max_pgf, nneighbors)
     155              : 
     156              :       ! Comunicate atomset and atom info to the engine
     157              :       jset = 1
     158              :       IF (ALLOCATED(first_set_of_atom)) DEALLOCATE (first_set_of_atom)
     159              :       ALLOCATE (first_set_of_atom(natom))
     160              :       DO iatom = 1, natom
     161              :          ikind = kind_of(iatom)
     162              :          ra = particle_set(iatom)%r(:)
     163              :          nseta = basis_parameter(ikind)%nset
     164              :          npgfa => basis_parameter(ikind)%npgf
     165              :          la_min => basis_parameter(ikind)%lmin
     166              :          la_max => basis_parameter(ikind)%lmax
     167              :          zeta => basis_parameter(ikind)%zet
     168              :          nsgfa => basis_parameter(ikind)%nsgf
     169              :          nsgfl_a => basis_parameter(ikind)%nsgfl
     170              :          gcc => basis_parameter(ikind)%gcc
     171              :          first_set_of_atom(iatom) = jset
     172              :          DO iset = 1, nseta
     173              :             CALL libgint_set_Atom(libGint_handle, jset - 1, ra, zeta(:, iset), npgfa(iset))
     174              :             inla = 1
     175              :             DO l = la_min(iset), la_max(iset)
     176              :                nla = nsgfl_a(l, iset)
     177              :                IF (ALLOCATED(flat_gcc)) DEALLOCATE (flat_gcc)
     178              :                ALLOCATE (flat_gcc(npgfa(iset)*nla))
     179              :                flat_gcc = PACK(gcc(1:npgfa(iset), inla:inla + nla - 1, iset), .TRUE.)
     180              :                CALL libgint_set_Atom_L(libGint_handle, jset - 1, l, nla, flat_gcc)
     181              :                inla = inla + nla
     182              :             END DO
     183              :             jset = jset + 1
     184              :          END DO
     185              :       END DO
     186              : #else
     187              :       MARK_USED(fac)
     188              :       MARK_USED(memory_parameter)
     189              :       MARK_USED(do_periodic)
     190              :       MARK_USED(cell)
     191              :       MARK_USED(actual_x_data)
     192              :       MARK_USED(nneighbors)
     193              :       MARK_USED(max_pgf)
     194              :       MARK_USED(natom)
     195              :       MARK_USED(kind_of)
     196              :       MARK_USED(particle_set)
     197              :       MARK_USED(basis_parameter)
     198            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     199              : #endif
     200            0 :    END SUBROUTINE libGint_update_env
     201              : 
     202              : ! **************************************************************************************************
     203              : !> \brief communicates the density to libGint, no spin case
     204              : !>
     205              : !> \param[in]  full_density_alpha       full density matrix array
     206              : ! **************************************************************************************************
     207            0 :    SUBROUTINE libGint_set_density_A(full_density_alpha)
     208              : 
     209              :       REAL(dp), DIMENSION(:, :), POINTER :: full_density_alpha
     210              : #if(__LIBGINT)
     211              :       CALL libgint_set_P(libGint_handle, full_density_alpha(:, 1))
     212              : #else
     213              :       MARK_USED(full_density_alpha)
     214            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     215              : #endif
     216            0 :    END SUBROUTINE libGint_set_density_A
     217              : 
     218              : ! **************************************************************************************************
     219              : !> \brief communicates the density to libGint, spin case
     220              : !>
     221              : !> \param[in]  full_density_alpha       full density matrix array on the alpha channel
     222              : !> \param[in]  full_density_beta        full density matrix array on the beta  channel
     223              : ! **************************************************************************************************
     224            0 :    SUBROUTINE libGint_set_density_AB(full_density_alpha, full_density_beta)
     225              : 
     226              :       REAL(dp), DIMENSION(:, :), POINTER :: full_density_alpha, full_density_beta
     227              : #if(__LIBGINT)
     228              :       CALL libgint_set_P_polarized(libGint_handle, full_density_alpha(:, 1), full_density_beta(:, 1))
     229              : #else
     230              :       MARK_USED(full_density_alpha)
     231              :       MARK_USED(full_density_beta)
     232            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     233              : #endif
     234            0 :    END SUBROUTINE libGint_set_density_AB
     235              : 
     236              : ! **************************************************************************************************
     237              : !> \brief requests the Fock matrix ( hf_fraction * D @@ I ) from libGint. When this function
     238              : !>        returns, full_ks_alpha_from_gpu will contain the fock matrix for this MPI rank.
     239              : !>
     240              : !> \param[out]  full_ks_alpha_from_gpu     location, already allocated, for the Fock matrix
     241              : !> \note assumes full_ks_alpha_from_gpu is already allocated with enough memory
     242              : ! **************************************************************************************************
     243            0 :    SUBROUTINE libGint_get_fock_matrix_A(full_ks_alpha_from_gpu)
     244              : 
     245              :       REAL(dp), DIMENSION(:, :), POINTER :: full_ks_alpha_from_gpu
     246              : #if(__LIBGINT)
     247              :       CALL libGint_get_K(libGint_handle, full_ks_alpha_from_gpu(:, 1))
     248              : #else
     249              :       MARK_USED(full_ks_alpha_from_gpu)
     250            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     251              : #endif
     252            0 :    END SUBROUTINE libGint_get_fock_matrix_A
     253              : 
     254              : ! **************************************************************************************************
     255              : !> \brief requests the Fock matrices from libGint for both channels. When this function
     256              : !>        returns, full_ks_alpha_from_gpu and beta will contain the fock matrix for this MPI rank.
     257              : !>
     258              : !> \param[out]  full_ks_alpha_from_gpu     location, already allocated, for the Fock matrix alpha
     259              : !> \param[out]  full_ks_beta_from_gpu      location, already allocated, for the Fock matrix beta
     260              : !> \note assumes full_ks_alpha_from_gpu and full_ks_beta_from_gpu are already allocated
     261              : ! **************************************************************************************************
     262            0 :    SUBROUTINE libGint_get_fock_matrix_AB(full_ks_alpha_from_gpu, full_ks_beta_from_gpu)
     263              : 
     264              :       REAL(dp), DIMENSION(:, :), POINTER :: full_ks_alpha_from_gpu, full_ks_beta_from_gpu
     265              : #if(__LIBGINT)
     266              :       CALL libgint_get_K_polarized(libGint_handle, full_ks_alpha_from_gpu(:, 1), full_ks_beta_from_gpu(:, 1))
     267              : #else
     268              :       MARK_USED(full_ks_alpha_from_gpu)
     269              :       MARK_USED(full_ks_beta_from_gpu)
     270            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     271              : #endif
     272            0 :    END SUBROUTINE libGint_get_fock_matrix_AB
     273              : 
     274              : ! **************************************************************************************************
     275              : !> \brief Assign two-electron integrals of a quartet/shell to libGint
     276              : !>
     277              : !> First we build a list of ab primitives and cd primitives using build_pair_list_pbc_pgf
     278              : !> These lists will contain (before screening) n_cell * npgf * npgf.
     279              : !> We loop over both and send ab(g) | cd(h) to libgint, which will loop internally over n
     280              : !>
     281              : !> \param[in]  iatom                index of atom I / A
     282              : !> \param[in]  jatom                index of atom J / B
     283              : !> \param[in]  katom                index of atom K / C
     284              : !> \param[in]  latom                index of atom L / D
     285              : !> \param[in]  iset                 index of the set for atom iatom we are adding
     286              : !> \param[in]  jset                 index of the set for atom jatom we are adding
     287              : !> \param[in]  kset                 index of the set for atom katom we are adding
     288              : !> \param[in]  lset                 index of the set for atom latom we are adding
     289              : !> \param[in]  ra                   position of atom iatom
     290              : !> \param[in]  rb                   position of atom jatom
     291              : !> \param[in]  rc                   position of atom katom
     292              : !> \param[in]  rd                   position of atom latom
     293              : !> \param[in]  npgfa                number of gaussians in set iset of atom iatom
     294              : !> \param[in]  npgfb                number of gaussians in set jset of atom jatom
     295              : !> \param[in]  npgfc                number of gaussians in set kset of atom katom
     296              : !> \param[in]  npgfd                number of gaussians in set lset of atom latom
     297              : !> \param[in]  potential_parameter  information about the potential
     298              : !> \param[in]  screen1              screening information for AB pair
     299              : !> \param[in]  screen2              screening information for CD pair
     300              : !> \param[in]  log10_pmax           density screening factor
     301              : !> \param[in]  log10_eps_schwarz    screening tolerance
     302              : !> \param[in]  pgf1                 screening information for each AB pair primitive
     303              : !> \param[in]  pgf2                 screening information for each CD pair primitive
     304              : !> \param[in]  neighbor_cells       array with lattice vectors
     305              : !> \param[in]  cell                 information about the simulation box
     306              : !> \param[in]  do_periodic          flag for pbc
     307              : !> \param[out] screened             whether the whole quartet was screened out
     308              : ! **************************************************************************************************
     309              : 
     310            0 :    SUBROUTINE libGint_coulomb4(iatom, jatom, katom, latom, iset, jset, kset, lset, &
     311              :                                ra, rb, rc, rd, npgfa, npgfb, npgfc, npgfd, &
     312              :                                potential_parameter, &
     313              :                                screen1, screen2, log10_pmax, log10_eps_schwarz, &
     314              :                                pgf1, pgf2, &
     315              :                                neighbor_cells, cell, do_periodic, screened)
     316              : 
     317              :       INTEGER, INTENT(in) :: iatom, jatom, katom, latom, iset, jset, kset, lset
     318              :       REAL(dp), INTENT(IN)                               :: ra(3), rb(3), rc(3), rd(3)
     319              :       INTEGER, INTENT(IN)                                :: npgfa, npgfb, npgfc, npgfd
     320              :       TYPE(hfx_potential_type)                           :: potential_parameter
     321              :       REAL(dp), INTENT(IN)                               :: screen1(2), screen2(2)
     322              :       REAL(dp), INTENT(IN)                               :: log10_pmax, log10_eps_schwarz
     323              :       TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
     324              :          POINTER                                         :: pgf1, pgf2
     325              :       TYPE(hfx_cell_type), DIMENSION(:), POINTER         :: neighbor_cells
     326              :       TYPE(cell_type), POINTER                           :: cell
     327              :       LOGICAL, INTENT(IN)                                :: do_periodic
     328              :       LOGICAL, INTENT(out) :: screened
     329              : 
     330              : #if(__LIBGINT)
     331              :       TYPE(bra_t), POINTER                               :: bra_p, ket_p
     332              :       LOGICAL :: cell_was_screened
     333              :       INTEGER  :: idx_n1, idx_n2, n1, n2, idx_ij, idx_kl, o_ij, n_ij, o_kl, n_kl !, n3
     334              :       INTEGER  :: ipgf, jpgf, kpgf, lpgf, iatom_set, jatom_set, katom_set, latom_set
     335              :       REAL(dp) :: pgf_max_1, pgf_max_2 ! , R1, R2, rpq2
     336              :       INTEGER :: nelements_ij, nelements_kl
     337              : 
     338              :       cell = cell
     339              :       potential_parameter = potential_parameter
     340              :       bra_p => bra
     341              :       ket_p => ket
     342              : 
     343              :       screened = .TRUE.
     344              :       iatom_set = first_set_of_atom(iatom) + iset - 2
     345              :       jatom_set = first_set_of_atom(jatom) + jset - 2
     346              :       katom_set = first_set_of_atom(katom) + kset - 2
     347              :       latom_set = first_set_of_atom(latom) + lset - 2
     348              : 
     349              :       CALL build_pair_list_pbc_pgf(npgfa, npgfb, bra_p, screen1, screen2, &
     350              :                                    pgf1, log10_pmax, log10_eps_schwarz, ra, rb, &
     351              :                                    nelements_ij, neighbor_cells, do_periodic)
     352              : 
     353              :       CALL build_pair_list_pbc_pgf(npgfc, npgfd, ket_p, screen2, screen1, &
     354              :                                    pgf2, log10_pmax, log10_eps_schwarz, rc, rd, &
     355              :                                    nelements_kl, neighbor_cells, do_periodic)
     356              : 
     357              :       ! Note: we use 3 numbers n1 n2 and n3 as indices for the lattice traslantion vectors
     358              :       ! n1 for the AB pair, n2 for the CD pair and n3 for the PQ pair
     359              :       ! so that e.g. B = B0 + ua(n1) means B.x = B0.x + ua(n1).x (and same for y and z)
     360              :       ! the ua, saved in neighbor_cells(:)%cell_r(:), are already computed
     361              :       ! lattice translation vectors T = i a1 + j a2 + k a3
     362              :       ! where a1,a2 and a3 are lattice vectors and i,j and k integers.
     363              :       ! So, B.x = B0.x + n1.i * a1.x + n1.j * a2.x + n1.k * a3.x (and same for y and z)
     364              :       !
     365              : 
     366              :       DO idx_n1 = 1, bra%cell_cnt
     367              : 
     368              :          n1 = bra%cell_idx(1, idx_n1)
     369              :          n_ij = bra%cell_idx(2, idx_n1)
     370              :          o_ij = bra%cell_idx(3, idx_n1)
     371              : 
     372              :          DO idx_n2 = 1, ket%cell_cnt
     373              : 
     374              :             n2 = ket%cell_idx(1, idx_n2)
     375              :             n_kl = ket%cell_idx(2, idx_n2)
     376              :             o_kl = ket%cell_idx(3, idx_n2)
     377              : 
     378              :             cell_was_screened = .TRUE.
     379              :             DO idx_ij = o_ij + 1, o_ij + n_ij
     380              : 
     381              :                ipgf = bra%pgf_idx(1, idx_ij)
     382              :                jpgf = bra%pgf_idx(2, idx_ij)
     383              : 
     384              :                pgf_max_1 = bra%pgf_scr(1, idx_ij)
     385              : 
     386              :                DO idx_kl = o_kl + 1, o_kl + n_kl
     387              :                   kpgf = ket%pgf_idx(1, idx_kl)
     388              :                   lpgf = ket%pgf_idx(2, idx_kl)
     389              : 
     390              :                   pgf_max_2 = ket%pgf_scr(1, idx_kl)
     391              : 
     392              :                   IF (pgf_max_1 + pgf_max_2 + log10_pmax < log10_eps_schwarz) CYCLE
     393              : 
     394              :                   CALL libGint_add_prm(libGint_handle, ipgf - 1, jpgf - 1, kpgf - 1, lpgf - 1)
     395              :                   cell_was_screened = .FALSE.
     396              : 
     397              :                END DO ! ket pgf
     398              :             END DO ! bra pgf
     399              : 
     400              :             IF (.NOT. cell_was_screened) THEN
     401              :                CALL libgint_add_shell(libGint_handle, iatom_set, jatom_set, katom_set, latom_set, n1 - 1, n2 - 1)
     402              :                screened = .FALSE.
     403              :             END IF
     404              : 
     405              :          END DO ! ket n2
     406              :       END DO ! bra n1
     407              : #else
     408              :       MARK_USED(iatom)
     409              :       MARK_USED(jatom)
     410              :       MARK_USED(katom)
     411              :       MARK_USED(latom)
     412              :       MARK_USED(iset)
     413              :       MARK_USED(jset)
     414              :       MARK_USED(kset)
     415              :       MARK_USED(lset)
     416              :       MARK_USED(ra)
     417              :       MARK_USED(rb)
     418              :       MARK_USED(rc)
     419              :       MARK_USED(rd)
     420              :       MARK_USED(npgfa)
     421              :       MARK_USED(npgfb)
     422              :       MARK_USED(npgfc)
     423              :       MARK_USED(npgfd)
     424              :       MARK_USED(potential_parameter)
     425              :       MARK_USED(screen1)
     426              :       MARK_USED(screen2)
     427              :       MARK_USED(log10_pmax)
     428              :       MARK_USED(log10_eps_schwarz)
     429              :       MARK_USED(pgf1)
     430              :       MARK_USED(pgf2)
     431              :       MARK_USED(neighbor_cells)
     432              :       MARK_USED(cell)
     433              :       MARK_USED(do_periodic)
     434              :       MARK_USED(screened)
     435            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     436              : #endif
     437            0 :    END SUBROUTINE libGint_coulomb4
     438              : 
     439              : ! **************************************************************************************************
     440              : !> \brief The previous coulomb_4 function assigned an integral between primitive gaussian.
     441              : !>        Now we assign the nsgfa(iset)*b*c*d gcc integrals form this set,
     442              : !>        along with the Pac Pad Pbc Pbd density to the Kbd Kbc Kad Kac Fock matrix
     443              : !>
     444              : !> \param[in] symm_fac          simmetry factor from iatom=jatom and the like
     445              : !> \param[in] iatom             index of atom A
     446              : !> \param[in] jatom             index of atom B
     447              : !> \param[in] katom             index of atom C
     448              : !> \param[in] latom             index of atom D
     449              : !> \param[in] iset              index of set for atom A
     450              : !> \param[in] jset              index of set for atom B
     451              : !> \param[in] kset              index of set for atom C
     452              : !> \param[in] lset              index of set for atom D
     453              : !> \param[in] atomic_offset_ac  global offset for the pair of A and C atom in the density ( and Fock) matrix
     454              : !> \param[in] atomic_offset_ad  global offset for the pair of A and D atom in the density ( and Fock) matrix
     455              : !> \param[in] atomic_offset_bc  global offset for the pair of B and C atom in the density ( and Fock) matrix
     456              : !> \param[in] atomic_offset_bd  global offset for the pair of B and D atom in the density ( and Fock) matrix
     457              : !> \param[in] offset_ac_set     matrix of sub_offset for sets in atomic_offset_ac
     458              : !> \param[in] offset_ad_set     matrix of sub_offset for sets in atomic_offset_ad
     459              : !> \param[in] offset_bc_set     matrix of sub_offset for sets in atomic_offset_bc
     460              : !> \param[in] offset_bd_set     matrix of sub_offset for sets in atomic_offset_bd
     461              : !> \param[in] nsgfa             total number of (spherical, contracted) integrals for iset.
     462              : !>                              Used as leading dimension of the AC, AD sublock, depending on transposition
     463              : !> \param[in] nsgfb             total number of (spherical, contracted) integrals for jset.
     464              : !>                              Used as leading dimension of the BC, BD sublock, depending on transposition
     465              : !> \param[in] nsgfc             total number of (spherical, contracted) integrals for kset.
     466              : !>                              Used as leading dimension of the AC, BC sublock, depending on transposition
     467              : !> \param[in] nsgfd             total number of (spherical, contracted) integrals for lset.
     468              : !>                              Used as leading dimension of the AD, BD sublock, depending on transposition
     469              : !> \param[in] la_min            minumum angular moment in set iset of atom A
     470              : !> \param[in] la_max            maximum angular moment in set iset of atom A
     471              : !> \param[in] lb_min            minumum angular moment in set iset of atom B
     472              : !> \param[in] lb_max            maximum angular moment in set iset of atom B
     473              : !> \param[in] lc_min            minumum angular moment in set iset of atom C
     474              : !> \param[in] lc_max            maximum angular moment in set iset of atom C
     475              : !> \param[in] ld_min            minumum angular moment in set iset of atom D
     476              : !> \param[in] ld_max            maximum angular moment in set iset of atom D
     477              : !> \param[in] nsgfl_a           matrix with the number of linear combinations of primitive gaussians
     478              : !>                              for each angular moment for each set in atom A. We only read iset
     479              : !> \param[in] nsgfl_b           matrix with the number of linear combinations of primitive gaussians
     480              : !>                              for each angular moment for each set in atom B. We only read jset
     481              : !> \param[in] nsgfl_c           matrix with the number of linear combinations of primitive gaussians
     482              : !>                              for each angular moment for each set in atom C. We only read kset
     483              : !> \param[in] nsgfl_d           matrix with the number of linear combinations of primitive gaussians
     484              : !>                              for each angular moment for each set in atom D. We only read lset
     485              : !> \note
     486              : !>  The atomic_offset_xy, offset_xy_set matrices provide set offsets which are combined with per-L and
     487              : !>    per linear combination offsets to produce the final indices into the dense (but block-sparse)
     488              : !>    density and Fock matrices
     489              : !>  - The routine assumes Fortran column major order and contiguous storage for the per set
     490              : !>    density subblocks as described in the code comments.
     491              : !>  - The code computes transposition flags to only use the lower part of P and K
     492              : !>
     493              : !>
     494              : ! **************************************************************************************************
     495              : 
     496            0 :    SUBROUTINE libGint_update_fock_matrix( &
     497              :       symm_fac, &
     498              :       iatom, jatom, katom, latom, &
     499              :       iset, jset, kset, lset, &
     500              :       atomic_offset_ac, atomic_offset_ad, atomic_offset_bc, atomic_offset_bd, &
     501              :       offset_ac_set, offset_ad_set, offset_bc_set, offset_bd_set, &
     502              :       nsgfa, nsgfb, nsgfc, nsgfd, &
     503              :       la_min, la_max, lb_min, lb_max, &
     504              :       lc_min, lc_max, ld_min, ld_max, &
     505              :       nsgfl_a, nsgfl_b, nsgfl_c, nsgfl_d)
     506              : 
     507              :       REAL(dp) :: symm_fac
     508              :       INTEGER :: iatom, jatom, katom, latom
     509              :       INTEGER :: iset, jset, kset, lset
     510              :       INTEGER :: atomic_offset_ac, atomic_offset_ad, atomic_offset_bc, atomic_offset_bd
     511              :       INTEGER, DIMENSION(:, :), POINTER :: offset_ac_set, offset_ad_set
     512              :       INTEGER, DIMENSION(:, :), POINTER :: offset_bc_set, offset_bd_set
     513              :       INTEGER :: nsgfa, nsgfb, nsgfc, nsgfd
     514              :       INTEGER :: la_min, la_max, lb_min, lb_max
     515              :       INTEGER :: lc_min, lc_max, ld_min, ld_max
     516              :       INTEGER, DIMENSION(:, :), POINTER :: nsgfl_a, nsgfl_b, nsgfl_c, nsgfl_d
     517              : 
     518              : #if(__LIBGINT)
     519              :       !! (Hyp)
     520              :       ! Let a be a set composed of 2 s and 1 p function.
     521              :       ! Let c be a set composed of 1 s and 2 p function.
     522              :       ! (1) The density matrix for the ac pair is a 5 x 7 matrix organized as
     523              :       !
     524              :       !    / -------------------------------------------------------------------------------------------------------------------\
     525              :       !    |   a_s1_0@c_s1_0  || a_s1_0@c_p1_0 | a_s1_0@c_p1_1 | a_s1_0@c_p1_2 || a_s1_0@c_p2_0 | a_s1_0@c_p2_1 | a_s1_0@c_p2_2 |
     526              :       !    |   a_s2_0@c_s1_0  || a_s2_0@c_p1_0 | a_s2_0@c_p1_1 | a_s2_0@c_p1_2 || a_s2_0@c_p2_0 | a_s2_0@c_p2_1 | a_s2_0@c_p2_2 |
     527              :       !    |   a_p1_0@c_s1_0  || a_p1_0@c_p1_0 | a_p1_0@c_p1_1 | a_p1_0@c_p1_2 || a_p1_0@c_p2_0 | a_p1_0@c_p2_1 | a_p1_0@c_p2_2 |
     528              :       !    |   a_p1_1@c_s1_0  || a_p1_1@c_p1_0 | a_p1_1@c_p1_1 | a_p1_1@c_p1_2 || a_p1_1@c_p2_0 | a_p1_1@c_p2_1 | a_p1_1@c_p2_2 |
     529              :       !    |   a_p1_2@c_s1_0  || a_p1_2@c_p1_0 | a_p1_2@c_p1_1 | a_p1_2@c_p1_2 || a_p1_2@c_p2_0 | a_p1_2@c_p2_1 | a_p1_2@c_p2_2 |
     530              :       !    \ -------------------------------------------------------------------------------------------------------------------/
     531              :       !
     532              :       ! where A_LX_Y means the (Y+1) component of the Xth linear combination of the L angular moment for atom A
     533              :       !
     534              :       ! (2) This matrix is dense, rectangular and contigous in memory, in fortran column major order.
     535              :       ! (3) The big matrix with all pairs is block sparse triangular, only the lower part is valid.
     536              : 
     537              :       LOGICAL(1) :: Tac, Tad, Tbc, Tbd
     538              :       INTEGER :: offset_ac_L_set, offset_ad_L_set, offset_bc_L_set, offset_bd_L_set
     539              :       INTEGER :: s_offset_a, s_offset_b, s_offset_c, s_offset_d
     540              :       INTEGER :: s_offset_a_l, s_offset_b_l, s_offset_c_l, s_offset_d_l
     541              :       INTEGER :: s_offset_ac, s_offset_ad, s_offset_bc, s_offset_bd
     542              :       INTEGER :: ld_ac_set, ld_ad_set, ld_bc_set, ld_bd_set
     543              :       INTEGER :: la, lb, lc, ld, nla, nlb, nlc, nld, inla, inlb, inlc, inld
     544              :       ! TODO rewrite as update_fock_matrix_gpu(libGint_handle, iatomset,jatomset,katomset,latomset )
     545              :       ! AFTER TODO communicate (the pointer to) atomic_offset to libGint AND
     546              :       ! AFTER TODO communicate (the pointer to)    set_offset to libGint AND
     547              :       ! AFTER TODO check if this idea makes sense in general for other codes
     548              :       !
     549              :       ! Note: this would not change the need to compute sub offsets and
     550              :       ! the 8 loops, it would just transfer them to libGint
     551              :       ! Except, if libGint can be sure every set has 1  l, it can collapse the l loops
     552              :       ! and/or, if libGint can be sure every l   has 1 nl, it can collapse the n loops
     553              :       IF (jatom >= latom) THEN
     554              :          offset_bd_L_set = offset_bd_set(jset, lset) + atomic_offset_bd - 2
     555              :          ld_bd_set = nsgfb
     556              :          Tbd = .FALSE.
     557              :       ELSE
     558              :          offset_bd_L_set = offset_bd_set(lset, jset) + atomic_offset_bd - 2
     559              :          ld_bd_set = nsgfd
     560              :          Tbd = .TRUE.
     561              :       END IF
     562              :       IF (jatom >= katom) THEN
     563              :          offset_bc_L_set = offset_bc_set(jset, kset) + atomic_offset_bc - 2
     564              :          ld_bc_set = nsgfb
     565              :          Tbc = .FALSE.
     566              :       ELSE
     567              :          offset_bc_L_set = offset_bc_set(kset, jset) + atomic_offset_bc - 2
     568              :          ld_bc_set = nsgfc
     569              :          Tbc = .TRUE.
     570              :       END IF
     571              : 
     572              :       IF (iatom >= latom) THEN
     573              :          offset_ad_L_set = offset_ad_set(iset, lset) + atomic_offset_ad - 2
     574              :          ld_ad_set = nsgfa
     575              :          Tad = .FALSE.
     576              :       ELSE
     577              :          offset_ad_L_set = offset_ad_set(lset, iset) + atomic_offset_ad - 2
     578              :          ld_ad_set = nsgfd
     579              :          Tad = .TRUE.
     580              :       END IF
     581              : 
     582              :       IF (iatom >= katom) THEN
     583              :          offset_ac_L_set = offset_ac_set(iset, kset) + atomic_offset_ac - 2
     584              :          ld_ac_set = nsgfa
     585              :          Tac = .FALSE.
     586              :       ELSE
     587              :          offset_ac_L_set = offset_ac_set(kset, iset) + atomic_offset_ac - 2
     588              :          ld_ac_set = nsgfc
     589              :          Tac = .TRUE.
     590              :       END IF
     591              : 
     592              :       s_offset_a_l = 0
     593              :       DO la = la_min, la_max
     594              :          nla = nsgfl_a(la, iset)
     595              :          s_offset_b_l = 0
     596              :          DO lb = lb_min, lb_max
     597              :             nlb = nsgfl_b(lb, jset)
     598              :             s_offset_c_l = 0
     599              :             DO lc = lc_min, lc_max
     600              :                nlc = nsgfl_c(lc, kset)
     601              :                s_offset_d_l = 0
     602              :                ld_loop: DO ld = ld_min, ld_max
     603              :                   nld = nsgfl_d(ld, lset)
     604              :                   CALL libgint_add_qrt(libGint_handle, la, lb, lc, ld, nla, nlb, nlc, nld)
     605              :                   DO inla = 1, nla
     606              :                      s_offset_a = s_offset_a_l + (inla - 1)*(2*la + 1)
     607              :                      DO inlb = 1, nlb
     608              :                         s_offset_b = s_offset_b_l + (inlb - 1)*(2*lb + 1)
     609              :                         DO inlc = 1, nlc
     610              :                            s_offset_c = s_offset_c_l + (inlc - 1)*(2*lc + 1)
     611              :                            DO inld = 1, nld
     612              :                               s_offset_d = s_offset_d_l + (inld - 1)*(2*ld + 1)
     613              :                               IF (.NOT. Tac) THEN
     614              :                                  s_offset_ac = offset_ac_L_set + s_offset_c*ld_ac_set + s_offset_a
     615              :                               ELSE
     616              :                                  s_offset_ac = offset_ac_L_set + s_offset_a*ld_ac_set + s_offset_c
     617              :                               END IF
     618              : 
     619              :                               IF (.NOT. Tad) THEN
     620              :                                  s_offset_ad = offset_ad_L_set + s_offset_d*ld_ad_set + s_offset_a
     621              :                               ELSE
     622              :                                  s_offset_ad = offset_ad_L_set + s_offset_a*ld_ad_set + s_offset_d
     623              :                               END IF
     624              : 
     625              :                               IF (.NOT. Tbc) THEN
     626              :                                  s_offset_bc = offset_bc_L_set + s_offset_c*ld_bc_set + s_offset_b
     627              :                               ELSE
     628              :                                  s_offset_bc = offset_bc_L_set + s_offset_b*ld_bc_set + s_offset_c
     629              :                               END IF
     630              : 
     631              :                               IF (.NOT. Tbd) THEN
     632              :                                  s_offset_bd = offset_bd_L_set + s_offset_d*ld_bd_set + s_offset_b
     633              :                               ELSE
     634              :                                  s_offset_bd = offset_bd_L_set + s_offset_b*ld_bd_set + s_offset_d
     635              :                               END IF
     636              : 
     637              :                               CALL libgint_add_qrtt(libGint_handle, symm_fac, &
     638              :                                                     la, lb, lc, ld, inla - 1, inlb - 1, inlc - 1, inld - 1, &
     639              :                                                     ld_ac_set, ld_ad_set, ld_bc_set, ld_bd_set, &
     640              :                                                     s_offset_ac, s_offset_ad, s_offset_bc, s_offset_bd, &
     641              :                                                     Tac, Tad, Tbc, Tbd)
     642              : 
     643              :                            END DO
     644              :                         END DO
     645              :                      END DO
     646              :                   END DO
     647              :                   s_offset_d_l = s_offset_d_l + nld*(2*ld + 1)
     648              :                END DO ld_loop
     649              :                s_offset_c_l = s_offset_c_l + nlc*(2*lc + 1)
     650              :             END DO
     651              :             s_offset_b_l = s_offset_b_l + nlb*(2*lb + 1)
     652              :          END DO
     653              :          s_offset_a_l = s_offset_a_l + nla*(2*la + 1)
     654              :       END DO
     655              : 
     656              :       CALL libgint_add_set(libGint_handle)
     657              : 
     658              : #else
     659              :       MARK_USED(symm_fac)
     660              :       MARK_USED(iatom)
     661              :       MARK_USED(jatom)
     662              :       MARK_USED(katom)
     663              :       MARK_USED(latom)
     664              :       MARK_USED(iset)
     665              :       MARK_USED(jset)
     666              :       MARK_USED(kset)
     667              :       MARK_USED(lset)
     668              :       MARK_USED(atomic_offset_ac)
     669              :       MARK_USED(atomic_offset_ad)
     670              :       MARK_USED(atomic_offset_bc)
     671              :       MARK_USED(atomic_offset_bd)
     672              :       MARK_USED(offset_ac_set)
     673              :       MARK_USED(offset_ad_set)
     674              :       MARK_USED(offset_bc_set)
     675              :       MARK_USED(offset_bd_set)
     676              :       MARK_USED(nsgfa)
     677              :       MARK_USED(nsgfb)
     678              :       MARK_USED(nsgfc)
     679              :       MARK_USED(nsgfd)
     680              :       MARK_USED(la_min)
     681              :       MARK_USED(la_max)
     682              :       MARK_USED(lb_min)
     683              :       MARK_USED(lb_max)
     684              :       MARK_USED(lc_min)
     685              :       MARK_USED(lc_max)
     686              :       MARK_USED(ld_min)
     687              :       MARK_USED(ld_max)
     688              :       MARK_USED(nsgfl_a)
     689              :       MARK_USED(nsgfl_b)
     690              :       MARK_USED(nsgfl_c)
     691              :       MARK_USED(nsgfl_d)
     692            0 :       CPABORT("This CP2K executable has not been linked against the required library libGint.")
     693              : #endif
     694            0 :    END SUBROUTINE libGint_update_fock_matrix
     695              : 
     696              : END MODULE libGint_wrapper
        

Generated by: LCOV version 2.0-1