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