(git:1f9fd2c)
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 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
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
54 MODULE PROCEDURE libgint_set_density_a
55 MODULE PROCEDURE libgint_set_density_ab
56 END INTERFACE
57
59 MODULE PROCEDURE libgint_get_fock_matrix_a
60 MODULE PROCEDURE libgint_get_fock_matrix_ab
61 END INTERFACE
62
63CONTAINS
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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
88#endif
89 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
199#endif
200 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
215#endif
216 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
233#endif
234 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
251#endif
252 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
271#endif
272 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 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 cpabort("This CP2K executable has not been linked against the required library libGint.")
436#endif
437 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
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 cpabort("This CP2K executable has not been linked against the required library libGint.")
693#endif
694 END SUBROUTINE libgint_update_fock_matrix
695
696END 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