(git:e90df42)
Loading...
Searching...
No Matches
hfx_pair_list_methods.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 Routines for optimizing load balance between processes in HFX calculations
10!> \par History
11!> 04.2008 created [Manuel Guidon]
12!> 11.2019 fixed initial value for potential_id (A. Bussy)
13!> \author Manuel Guidon
14! **************************************************************************************************
16 USE cell_types, ONLY: cell_type,&
17 pbc
18 USE hfx_types, ONLY: &
26 USE kinds, ONLY: dp
28 USE mathconstants, ONLY: pi
32#include "./base/base_uses.f90"
33
34 IMPLICIT NONE
35 PRIVATE
36
37 PUBLIC :: build_pair_list, &
45
46 ! an initial estimate for the size of the product list
47 INTEGER, SAVE :: pgf_product_list_size = 128
48
49 ! Store screened primitive gaussian function pairs between two shells (A and B)
50 TYPE :: bra_t
51 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: pgf_scr
52 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: pgf_idx, cell_idx
53 INTEGER :: cell_cnt = 0, pgf_cnt = 0
54 END TYPE bra_t
55
56CONTAINS
57
58! **************************************************************************************************
59!> \brief Allocates all arrays within a Bra_t structure.
60!>
61!> This subroutine ensures that a given `Bra_t` pointer has allocated memory
62!> for storing primitive Gaussian pair indices, screening data, and cell indices.
63!> Existing allocations are safely deallocated first.
64!>
65!> \param[in,out] bra Pointer to the Bra_t structure to allocate.
66!> \param[in] max_npgf Maximum number of primitives per shell.
67!> \param[in] max_ncell Maximum number of neighbor cells.
68!>
69!> \note The arrays are allocated as follows:
70!> - `pgf_idx(3, max_npgf^2 * max_ncell)`
71!> - `pgf_scr(5, max_npgf^2 * max_ncell)`
72!> - `cell_idx(3, max_ncell)`
73!>
74! **************************************************************************************************
75 SUBROUTINE allocate_bra(bra, max_npgf, max_ncell)
76 TYPE(bra_t), POINTER :: bra
77 INTEGER :: max_npgf, max_ncell
78
79 IF (ALLOCATED(bra%pgf_idx)) DEALLOCATE (bra%pgf_idx) ! TODO add if n_prm changed
80 IF (ALLOCATED(bra%pgf_scr)) DEALLOCATE (bra%pgf_scr) ! TODO add if n_prm changed
81 IF (ALLOCATED(bra%cell_idx)) DEALLOCATE (bra%cell_idx) ! TODO add if n_prm changed
82 ALLOCATE (bra%pgf_idx(3, max_npgf*max_npgf*max_ncell))
83 ALLOCATE (bra%pgf_scr(5, max_npgf*max_npgf*max_ncell))
84 ALLOCATE (bra%cell_idx(3, max_ncell))
85 END SUBROUTINE allocate_bra
86
87! **************************************************************************************************
88!> \brief Builds a screened list of primitives from centers A and B, intersecting with another shell
89!>
90!> This subroutine populates the `Bra_t` structure with indices and screening data
91!> for primitive Gaussian pairs (ipgf,jpgf,n3) that pass the Schwarz screening criterion
92!>
93!> \param[in] npgfa Number of primitives in shell A
94!> \param[in] npgfb Number of primitives in shell B
95!> \param[out] bra Pointer to Bra_t structure to populate
96!> \param[in] screen1 Screening coeffiecients for the AB pair based on most diffuse pgf
97!> \param[in] screen2 Screening coeffiecients for the CD pair based on most diffuse pgf
98!> \param[in] pgf Screening coeeficents for primitive gaussians
99!> \param[in] log10_pmax Log10 of maximum integral prefactor
100!> \param[in] log10_eps_schwarz Log10 of Schwarz screening threshold
101!> \param[in] ra Cartesian coordinates of center A
102!> \param[in] rb Cartesian coordinates of center B
103!> \param[out] nelements Total number of valid primitives found
104!> \param[in] neighbor_cells Array of lattice vectors
105!> \param[in] do_periodic Logical flag for periodic boundary conditions on B
106!>
107!> \note Loops over all cells, shifting the B shell position accordingly
108!> Only pairs satisfying the screening condition are stored.
109!>
110!> \note Each valid cell contributes a block of pairs stored contiguously in
111!> bra%pgf_idx, with cell metadata stored in bra%cell_idx
112!> \note screening primitive pairs (ipgf, jpgf) using both coarse and fine screening thresholds
113! **************************************************************************************************
114 SUBROUTINE build_pair_list_pbc_pgf(npgfa, npgfb, bra, screen1, screen2, pgf, &
115 log10_pmax, log10_eps_schwarz, ra, rb, nelements, &
116 neighbor_cells, do_periodic)
117
118 INTEGER, INTENT(IN) :: npgfa, npgfb
119 TYPE(bra_t), POINTER :: bra
120 REAL(dp), INTENT(IN) :: screen1(2), screen2(2)
121 TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
122 POINTER :: pgf
123 REAL(dp), INTENT(IN) :: log10_pmax, log10_eps_schwarz, ra(3), &
124 rb(3)
125 INTEGER, INTENT(OUT) :: nelements
126 TYPE(hfx_cell_type), DIMENSION(:), POINTER :: neighbor_cells
127 LOGICAL, INTENT(IN) :: do_periodic
128
129 INTEGER :: cell_cnt, cell_idx, element_cnt, &
130 element_idx, element_off, ipgf, jpgf
131 REAL(dp) :: ab(3), im_b(3), pgf_max, rab2
132
133 element_idx = 0
134 element_off = 0
135 cell_cnt = 0
136 DO cell_idx = 1, SIZE(neighbor_cells)
137 ! move B to this cell while keeping A fixed
138 ! NOTE rb has already been moved by build_pair_list
139 ! so that when cell_r is (000) AB is in the pbc cell
140 IF (do_periodic) THEN
141 im_b = rb + neighbor_cells(cell_idx)%cell_r(:)
142 ELSE
143 im_b = rb
144 END IF
145 ab = ra - im_b
146 rab2 = ab(1)**2 + ab(2)**2 + ab(3)**2
147 ! First screening on the most diffuse AB gaussians along with the most diffuse CD gaussian
148 IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) cycle
149
150 element_cnt = 0
151 DO ipgf = 1, npgfa
152 DO jpgf = 1, npgfb
153
154 ! Second screening on this actual AB pair and the most diffuse CD from before
155 pgf_max = pgf(jpgf, ipgf)%x(1)*rab2 + pgf(jpgf, ipgf)%x(2)
156 IF (pgf_max + screen2(2) + log10_pmax < log10_eps_schwarz) cycle
157 ! This pair passed screening. Add it to the bra.
158 element_idx = element_idx + 1
159 bra%pgf_idx(:, element_idx) = [ipgf, jpgf, cell_idx]
160 bra%pgf_scr(1, element_idx) = pgf_max
161 element_cnt = element_cnt + 1
162 END DO
163 END DO
164
165 ! If this cell produced any pair, add this cell to the bra
166 IF (element_cnt == 0) cycle
167 cell_cnt = cell_cnt + 1
168 bra%cell_idx(:, cell_cnt) = [cell_idx, element_cnt, element_off]
169 element_off = element_off + element_cnt
170
171 END DO ! cell
172 bra%cell_cnt = cell_cnt
173 nelements = element_idx
174 bra%pgf_cnt = nelements
175
176 END SUBROUTINE build_pair_list_pbc_pgf
177
178! **************************************************************************************************
179!> \brief ...
180!> \param list1 ...
181!> \param list2 ...
182!> \param product_list ...
183!> \param nproducts ...
184!> \param log10_pmax ...
185!> \param log10_eps_schwarz ...
186!> \param neighbor_cells ...
187!> \param cell ...
188!> \param potential_parameter ...
189!> \param m_max ...
190!> \param do_periodic ...
191! **************************************************************************************************
192 SUBROUTINE build_pgf_product_list(list1, list2, product_list, nproducts, &
193 log10_pmax, log10_eps_schwarz, neighbor_cells, &
194 cell, potential_parameter, m_max, do_periodic)
195
196 TYPE(hfx_pgf_list) :: list1, list2
197 TYPE(hfx_pgf_product_list), ALLOCATABLE, &
198 DIMENSION(:), INTENT(INOUT) :: product_list
199 INTEGER, INTENT(OUT) :: nproducts
200 REAL(dp), INTENT(IN) :: log10_pmax, log10_eps_schwarz
201 TYPE(hfx_cell_type), DIMENSION(:), POINTER :: neighbor_cells
202 TYPE(cell_type), POINTER :: cell
203 TYPE(hfx_potential_type) :: potential_parameter
204 INTEGER, INTENT(IN) :: m_max
205 LOGICAL, INTENT(IN) :: do_periodic
206
207 REAL(dp), PARAMETER :: r_cutoff_eps = 1.0e-12_dp
208
209 INTEGER :: i, j, k, k_max, l, nimages1, nimages2, &
210 tmp_i4
211 LOGICAL :: has_r_cutoff
212 REAL(dp) :: c11(3), den, eta, etainv, fundamentals_work(prim_data_f_size), g(3), &
213 min_img_delta, normalization, num, p(3), pgf_max_1, pgf_max_2, pq(3), pq2, prefactor, &
214 q(3), r1, r2, r_cutoff_sq, r_cutoff_sq_guard, ra(3), rb(3), rc(3), rcut_eff, rd(3), rho, &
215 rhoinv, rpq2, s1234, s1234a, s1234b, shift(3), ssss, t, temp(3), temp_cc(3), temp_dd(3), &
216 tmp_d(3), w(3), zeta1, zeta_c, zeta_d, zetapetainv
217 TYPE(hfx_pgf_product_list), ALLOCATABLE, &
218 DIMENSION(:) :: tmp_product_list
219
220 nimages1 = list1%nimages
221 nimages2 = list2%nimages
222 nproducts = 0
223 zeta1 = list1%zetapzetb
224 eta = list2%zetapzetb
225 etainv = list2%ZetaInv
226 zeta_c = list2%zeta
227 zeta_d = list2%zetb
228 temp_cc = 0.0_dp
229 temp_dd = 0.0_dp
230 r_cutoff_sq = 0.0_dp
231 r_cutoff_sq_guard = 0.0_dp
232 SELECT CASE (potential_parameter%potential_type)
234 has_r_cutoff = .true.
235 rcut_eff = potential_parameter%cutoff_radius
237 has_r_cutoff = .true.
238 rcut_eff = potential_parameter%cutoff_radius*2.0_dp
239 CASE DEFAULT
240 has_r_cutoff = .false.
241 rcut_eff = 0.0_dp
242 END SELECT
243 DO i = 1, nimages1
244 p = list1%image_list(i)%P
245 r1 = list1%image_list(i)%R
246 s1234a = list1%image_list(i)%S1234
247 pgf_max_1 = list1%image_list(i)%pgf_max
248 ra = list1%image_list(i)%ra
249 rb = list1%image_list(i)%rb
250 DO j = 1, nimages2
251 pgf_max_2 = list2%image_list(j)%pgf_max
252 IF (pgf_max_1 + pgf_max_2 + log10_pmax < log10_eps_schwarz) cycle
253 q = list2%image_list(j)%P
254 r2 = list2%image_list(j)%R
255 s1234b = list2%image_list(j)%S1234
256 rc = list2%image_list(j)%ra
257 rd = list2%image_list(j)%rb
258
259 IF (has_r_cutoff) THEN
260 r_cutoff_sq = (r1 + r2 + rcut_eff)**2
261 r_cutoff_sq_guard = r_cutoff_sq*(1.0_dp + r_cutoff_eps)
262 END IF
263 k_max = SIZE(neighbor_cells)
264 IF (do_periodic) THEN
265 temp = p - q
266 pq = pbc(temp, cell)
267 IF (has_r_cutoff .AND. cell%orthorhombic .AND. all(cell%perd == 1) .AND. k_max >= 1) THEN
268 IF (all(neighbor_cells(1)%cell_r == 0.0_dp)) THEN
269 pq2 = pq(1)**2 + pq(2)**2 + pq(3)**2
270 IF (pq2 > r_cutoff_sq_guard) cycle
271 min_img_delta = min_image_gap_sq(pq, cell%hmat)
272 IF (min_img_delta >= 0.0_dp .AND. pq2 + min_img_delta > r_cutoff_sq_guard) k_max = 1
273 END IF
274 END IF
275 shift = -pq + temp
276 temp_cc = rc + shift
277 temp_dd = rd + shift
278 END IF
279
280 zetapetainv = zeta1 + eta
281 zetapetainv = 1.0_dp/zetapetainv
282 rho = zeta1*eta*zetapetainv
283 rhoinv = 1.0_dp/rho
284 s1234 = exp(s1234a + s1234b)
285
286 DO k = 1, k_max
287 IF (do_periodic) THEN
288 IF (has_r_cutoff .AND. k_max > 1) THEN
289 IF ((pq(1) - neighbor_cells(k)%cell_r(1))**2 + &
290 (pq(2) - neighbor_cells(k)%cell_r(2))**2 + &
291 (pq(3) - neighbor_cells(k)%cell_r(3))**2 > r_cutoff_sq_guard) cycle
292 END IF
293 c11 = temp_cc + neighbor_cells(k)%cell_r(:)
294 tmp_d = temp_dd + neighbor_cells(k)%cell_r(:)
295 ELSE
296 c11 = rc
297 tmp_d = rd
298 END IF
299 q = (zeta_c*c11 + zeta_d*tmp_d)*etainv
300 rpq2 = (p(1) - q(1))**2 + (p(2) - q(2))**2 + (p(3) - q(3))**2
301 IF (has_r_cutoff) THEN
302 IF (rpq2 > r_cutoff_sq) cycle
303 END IF
304 nproducts = nproducts + 1
305
306 ! allocate size as needed,
307 ! updating the global size estimate to make this a rare event in longer simulations
308 IF (nproducts > SIZE(product_list)) THEN
309!$OMP ATOMIC READ
310 tmp_i4 = pgf_product_list_size
311 tmp_i4 = max(pgf_product_list_size, (3*nproducts + 1)/2)
312!$OMP ATOMIC WRITE
313 pgf_product_list_size = tmp_i4
314 ALLOCATE (tmp_product_list(SIZE(product_list)))
315 tmp_product_list(:) = product_list
316 DEALLOCATE (product_list)
317 ALLOCATE (product_list(tmp_i4))
318 product_list(1:SIZE(tmp_product_list)) = tmp_product_list
319 DEALLOCATE (tmp_product_list)
320 END IF
321
322 t = rho*rpq2
323 IF (potential_parameter%potential_type == do_potential_id) THEN
324 num = list1%zeta*list1%zetb
325 den = list1%zeta + list1%zetb
326 ssss = -num/den*sum((ra - rb)**2)
327
328 num = den*zeta_c
329 den = den + zeta_c
330 ssss = ssss - num/den*sum((p - rc)**2)
331
332 g(:) = (list1%zeta*ra(:) + list1%zetb*rb(:) + zeta_c*rc(:))/den
333 num = den*zeta_d
334 den = den + zeta_d
335 ssss = ssss - num/den*sum((g - rd)**2)
336
337 product_list(nproducts)%Fm(:) = exp(ssss)
338 ! The ID seed already contains the four-Gaussian attenuation.
339 normalization = 1.0_dp
340 IF (s1234 > epsilon(0.0_dp)) normalization = 1.0_dp/s1234
341 ELSE
342 CALL compute_r12_fundamentals(product_list(nproducts)%Fm, normalization, m_max, &
343 potential_parameter%potential_type, rho, t, fundamentals_work, &
344 omega=potential_parameter%omega, &
345 cutoff_radius=potential_parameter%cutoff_radius, &
346 scale_coulomb=potential_parameter%scale_coulomb, &
347 scale_longrange=potential_parameter%scale_longrange, &
348 scale_gaussian=potential_parameter%scale_gaussian)
349 END IF
350
351 prefactor = normalization*s1234*sqrt((pi*zetapetainv)**3)
352
353 DO l = 1, m_max + 1
354 product_list(nproducts)%Fm(l) = product_list(nproducts)%Fm(l)*prefactor
355 END DO
356
357 w = (zeta1*p + eta*q)*zetapetainv
358 product_list(nproducts)%ra = ra
359 product_list(nproducts)%rb = rb
360 product_list(nproducts)%rc = c11
361 product_list(nproducts)%rd = tmp_d
362 product_list(nproducts)%ZetapEtaInv = zetapetainv
363 product_list(nproducts)%Rho = rho
364 product_list(nproducts)%RhoInv = rhoinv
365 product_list(nproducts)%P = p
366 product_list(nproducts)%Q = q
367 product_list(nproducts)%W = w
368 product_list(nproducts)%AB = ra - rb
369 product_list(nproducts)%CD = c11 - tmp_d
370 END DO
371 END DO
372 END DO
373
374 END SUBROUTINE build_pgf_product_list
375
376! **************************************************************************************************
377!> \brief ...
378!> \param npgfa ...
379!> \param npgfb ...
380!> \param list ...
381!> \param zeta ...
382!> \param zetb ...
383!> \param screen1 ...
384!> \param screen2 ...
385!> \param pgf ...
386!> \param R_pgf ...
387!> \param log10_pmax ...
388!> \param log10_eps_schwarz ...
389!> \param ra ...
390!> \param rb ...
391!> \param nelements ...
392!> \param neighbor_cells ...
393!> \param nimages ...
394!> \param do_periodic ...
395!> \param cell ...
396! **************************************************************************************************
397 SUBROUTINE build_pair_list_pgf(npgfa, npgfb, list, zeta, zetb, screen1, screen2, pgf, R_pgf, &
398 log10_pmax, log10_eps_schwarz, ra, rb, nelements, &
399 neighbor_cells, nimages, do_periodic, cell)
400 INTEGER, INTENT(IN) :: npgfa, npgfb
401 TYPE(hfx_pgf_list), DIMENSION(npgfa*npgfb) :: list
402 REAL(dp), DIMENSION(1:npgfa), INTENT(IN) :: zeta
403 REAL(dp), DIMENSION(1:npgfb), INTENT(IN) :: zetb
404 REAL(dp), INTENT(IN) :: screen1(2), screen2(2)
405 TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
406 POINTER :: pgf, r_pgf
407 REAL(dp), INTENT(IN) :: log10_pmax, log10_eps_schwarz, ra(3), &
408 rb(3)
409 INTEGER, INTENT(OUT) :: nelements
410 TYPE(hfx_cell_type), DIMENSION(:), POINTER :: neighbor_cells
411 INTEGER :: nimages(npgfa*npgfb)
412 LOGICAL, INTENT(IN) :: do_periodic
413 TYPE(cell_type), POINTER :: cell
414
415 REAL(dp), PARAMETER :: min_img_eps = 1.0e-12_dp
416
417 INTEGER :: element_counter, i, i_max, ipgf, j, jpgf
418 REAL(dp) :: ab(3), im_b(3), min_img_delta, pgf_max, &
419 rab2, zeta1, zeta_a, zeta_b, zetainv
420
421 i_max = SIZE(neighbor_cells)
422 IF (do_periodic) THEN
423 IF (cell%orthorhombic .AND. screen1(1) <= 0.0_dp .AND. i_max > 1) THEN
424 IF (all(cell%perd == 1) .AND. all(neighbor_cells(1)%cell_r == 0.0_dp)) THEN
425 ab = ra - rb
426 rab2 = ab(1)**2 + ab(2)**2 + ab(3)**2
427 min_img_delta = min_image_gap_sq(ab, cell%hmat)
428 IF (min_img_delta >= 0.0_dp) THEN
429 IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) THEN
430 nelements = 0
431 RETURN
432 END IF
433 IF (screen1(1)*(rab2 + min_img_delta)*(1.0_dp - min_img_eps) + &
434 screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) i_max = 1
435 END IF
436 END IF
437 END IF
438 ELSE
439 i_max = min(i_max, 1)
440 END IF
441 nimages = 0
442 ! ** inner loop may never be reached
443 nelements = npgfa*npgfb
444 DO i = 1, i_max
445 IF (do_periodic) THEN
446 im_b = rb + neighbor_cells(i)%cell_r(:)
447 ELSE
448 im_b = rb
449 END IF
450 ab = ra - im_b
451 rab2 = ab(1)**2 + ab(2)**2 + ab(3)**2
452 IF (screen1(1)*rab2 + screen1(2) + screen2(2) + log10_pmax < log10_eps_schwarz) cycle
453 element_counter = 0
454 DO ipgf = 1, npgfa
455 DO jpgf = 1, npgfb
456 element_counter = element_counter + 1
457 pgf_max = pgf(jpgf, ipgf)%x(1)*rab2 + pgf(jpgf, ipgf)%x(2)
458 IF (pgf_max + screen2(2) + log10_pmax < log10_eps_schwarz) THEN
459 cycle
460 END IF
461 nimages(element_counter) = nimages(element_counter) + 1
462 list(element_counter)%image_list(nimages(element_counter))%pgf_max = pgf_max
463 list(element_counter)%image_list(nimages(element_counter))%ra = ra
464 list(element_counter)%image_list(nimages(element_counter))%rb = im_b
465 list(element_counter)%image_list(nimages(element_counter))%rab2 = rab2
466
467 zeta_a = zeta(ipgf)
468 zeta_b = zetb(jpgf)
469 zeta1 = zeta_a + zeta_b
470 zetainv = 1.0_dp/zeta1
471
472 IF (nimages(element_counter) == 1) THEN
473 list(element_counter)%ipgf = ipgf
474 list(element_counter)%jpgf = jpgf
475 list(element_counter)%zetaInv = zetainv
476 list(element_counter)%zetapzetb = zeta1
477 list(element_counter)%zeta = zeta_a
478 list(element_counter)%zetb = zeta_b
479 END IF
480
481 list(element_counter)%image_list(nimages(element_counter))%S1234 = (-zeta_a*zeta_b*zetainv*rab2)
482 list(element_counter)%image_list(nimages(element_counter))%P = (zeta_a*ra + zeta_b*im_b)*zetainv
483 list(element_counter)%image_list(nimages(element_counter))%R = &
484 max(0.0_dp, r_pgf(jpgf, ipgf)%x(1)*rab2 + r_pgf(jpgf, ipgf)%x(2))
485 list(element_counter)%image_list(nimages(element_counter))%ra = ra
486 list(element_counter)%image_list(nimages(element_counter))%rb = im_b
487 list(element_counter)%image_list(nimages(element_counter))%rab2 = rab2
488 list(element_counter)%image_list(nimages(element_counter))%bcell = neighbor_cells(i)%cell
489 END DO
490 END DO
491 nelements = max(nelements, element_counter)
492 END DO
493 DO j = 1, nelements
494 list(j)%nimages = nimages(j)
495 END DO
496 ! ** Remove unused elements
497
498 element_counter = 0
499 DO j = 1, nelements
500 IF (list(j)%nimages == 0) cycle
501 element_counter = element_counter + 1
502 list(element_counter)%nimages = list(j)%nimages
503 list(element_counter)%zetapzetb = list(j)%zetapzetb
504 list(element_counter)%ZetaInv = list(j)%ZetaInv
505 list(element_counter)%zeta = list(j)%zeta
506 list(element_counter)%zetb = list(j)%zetb
507 list(element_counter)%ipgf = list(j)%ipgf
508 list(element_counter)%jpgf = list(j)%jpgf
509 DO i = 1, list(j)%nimages
510 list(element_counter)%image_list(i) = list(j)%image_list(i)
511 END DO
512 END DO
513
514 nelements = element_counter
515
516 END SUBROUTINE build_pair_list_pgf
517
518! **************************************************************************************************
519!> \brief ...
520!> \param natom ...
521!> \param list ...
522!> \param set_list ...
523!> \param i_start ...
524!> \param i_end ...
525!> \param j_start ...
526!> \param j_end ...
527!> \param kind_of ...
528!> \param basis_parameter ...
529!> \param particle_set ...
530!> \param do_periodic ...
531!> \param coeffs_set ...
532!> \param coeffs_kind ...
533!> \param coeffs_kind_max0 ...
534!> \param log10_eps_schwarz ...
535!> \param cell ...
536!> \param pmax_blocks ...
537!> \param atomic_pair_list ...
538! **************************************************************************************************
539 SUBROUTINE build_pair_list(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, &
540 do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
541 pmax_blocks, atomic_pair_list)
542
543 INTEGER, INTENT(IN) :: natom
544 TYPE(pair_list_type), INTENT(INOUT) :: list
545 TYPE(pair_set_list_type), DIMENSION(:), &
546 INTENT(OUT) :: set_list
547 INTEGER, INTENT(IN) :: i_start, i_end, j_start, j_end, &
548 kind_of(*)
549 TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
550 POINTER :: basis_parameter
551 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
552 POINTER :: particle_set
553 LOGICAL, INTENT(IN) :: do_periodic
554 TYPE(hfx_screen_coeff_type), &
555 DIMENSION(:, :, :, :), INTENT(IN), POINTER :: coeffs_set
556 TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
557 INTENT(IN) :: coeffs_kind
558 REAL(kind=dp), INTENT(IN) :: coeffs_kind_max0, log10_eps_schwarz
559 TYPE(cell_type), POINTER :: cell
560 REAL(dp), INTENT(IN) :: pmax_blocks
561 LOGICAL, DIMENSION(natom, natom), INTENT(IN) :: atomic_pair_list
562
563 INTEGER :: iatom, ikind, iset, jatom, jkind, jset, &
564 n_element, nset_ij, nseta, nsetb
565 REAL(kind=dp) :: rab2
566 REAL(kind=dp), DIMENSION(3) :: b11, pbc_b, ra, rb, temp
567
568 n_element = 0
569 nset_ij = 0
570
571 DO iatom = i_start, i_end
572 DO jatom = j_start, j_end
573 IF (atomic_pair_list(jatom, iatom) .EQV. .false.) cycle
574
575 ikind = kind_of(iatom)
576 nseta = basis_parameter(ikind)%nset
577 ra = particle_set(iatom)%r(:)
578
579 IF (jatom < iatom) cycle
580 jkind = kind_of(jatom)
581 nsetb = basis_parameter(jkind)%nset
582 rb = particle_set(jatom)%r(:)
583
584 IF (do_periodic) THEN
585 temp = rb - ra
586 pbc_b = pbc(temp, cell)
587 b11 = ra + pbc_b
588 rab2 = (ra(1) - b11(1))**2 + (ra(2) - b11(2))**2 + (ra(3) - b11(3))**2
589 ELSE
590 rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
591 b11 = rb ! ra - rb
592 END IF
593 IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
594 coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) cycle
595
596 n_element = n_element + 1
597 list%elements(n_element)%pair = [iatom, jatom]
598 list%elements(n_element)%kind_pair = [ikind, jkind]
599 list%elements(n_element)%r1 = ra
600 list%elements(n_element)%r2 = b11
601 list%elements(n_element)%dist2 = rab2
602 ! build a list of guaranteed overlapping sets
603 list%elements(n_element)%set_bounds(1) = nset_ij + 1
604 DO iset = 1, nseta
605 DO jset = 1, nsetb
606 IF (coeffs_set(jset, iset, jkind, ikind)%x(1)*rab2 + coeffs_set(jset, iset, jkind, ikind)%x(2) + &
607 coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) cycle
608 nset_ij = nset_ij + 1
609 set_list(nset_ij)%pair = [iset, jset]
610 END DO
611 END DO
612 list%elements(n_element)%set_bounds(2) = nset_ij
613 END DO
614 END DO
615
616 list%n_element = n_element
617
618 END SUBROUTINE build_pair_list
619
620! **************************************************************************************************
621!> \brief ...
622!> \param natom ...
623!> \param atomic_pair_list ...
624!> \param kind_of ...
625!> \param basis_parameter ...
626!> \param particle_set ...
627!> \param do_periodic ...
628!> \param coeffs_kind ...
629!> \param coeffs_kind_max0 ...
630!> \param log10_eps_schwarz ...
631!> \param cell ...
632!> \param blocks ...
633! **************************************************************************************************
634 SUBROUTINE build_atomic_pair_list(natom, atomic_pair_list, kind_of, basis_parameter, particle_set, &
635 do_periodic, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
636 blocks)
637 INTEGER, INTENT(IN) :: natom
638 LOGICAL, DIMENSION(natom, natom) :: atomic_pair_list
639 INTEGER, INTENT(IN) :: kind_of(*)
640 TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
641 POINTER :: basis_parameter
642 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
643 POINTER :: particle_set
644 LOGICAL, INTENT(IN) :: do_periodic
645 TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
646 INTENT(IN) :: coeffs_kind
647 REAL(kind=dp), INTENT(IN) :: coeffs_kind_max0, log10_eps_schwarz
648 TYPE(cell_type), POINTER :: cell
649 TYPE(hfx_block_range_type), DIMENSION(:), &
650 INTENT(IN), POINTER :: blocks
651
652 INTEGER :: iatom, iatom_end, iatom_start, iblock, &
653 ikind, jatom, jatom_end, jatom_start, &
654 jblock, jkind, nseta, nsetb
655 REAL(kind=dp) :: rab2
656 REAL(kind=dp), DIMENSION(3) :: b11, pbc_b, ra, rb, temp
657
658 atomic_pair_list = .false.
659
660 DO iblock = 1, SIZE(blocks)
661 iatom_start = blocks(iblock)%istart
662 iatom_end = blocks(iblock)%iend
663 DO jblock = 1, SIZE(blocks)
664 jatom_start = blocks(jblock)%istart
665 jatom_end = blocks(jblock)%iend
666
667 DO iatom = iatom_start, iatom_end
668 ikind = kind_of(iatom)
669 nseta = basis_parameter(ikind)%nset
670 ra = particle_set(iatom)%r(:)
671 DO jatom = jatom_start, jatom_end
672 IF (jatom < iatom) cycle
673 jkind = kind_of(jatom)
674 nsetb = basis_parameter(jkind)%nset
675 rb = particle_set(jatom)%r(:)
676
677 IF (do_periodic) THEN
678 temp = rb - ra
679 pbc_b = pbc(temp, cell)
680 b11 = ra + pbc_b
681 rab2 = (ra(1) - b11(1))**2 + (ra(2) - b11(2))**2 + (ra(3) - b11(3))**2
682 ELSE
683 rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
684 b11 = rb ! ra - rb
685 END IF
686 IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
687 coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 < log10_eps_schwarz) cycle
688
689 atomic_pair_list(jatom, iatom) = .true.
690 atomic_pair_list(iatom, jatom) = .true.
691 END DO
692 END DO
693 END DO
694 END DO
695
696 END SUBROUTINE build_atomic_pair_list
697
698! **************************************************************************************************
699!> \brief ...
700!> \param natom ...
701!> \param list ...
702!> \param set_list ...
703!> \param i_start ...
704!> \param i_end ...
705!> \param j_start ...
706!> \param j_end ...
707!> \param kind_of ...
708!> \param basis_parameter ...
709!> \param particle_set ...
710!> \param do_periodic ...
711!> \param coeffs_set ...
712!> \param coeffs_kind ...
713!> \param coeffs_kind_max0 ...
714!> \param log10_eps_schwarz ...
715!> \param cell ...
716!> \param pmax_blocks ...
717!> \param atomic_pair_list ...
718!> \param skip_atom_symmetry ...
719! **************************************************************************************************
720 SUBROUTINE build_pair_list_mp2(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, &
721 do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
722 pmax_blocks, atomic_pair_list, skip_atom_symmetry)
723
724 INTEGER, INTENT(IN) :: natom
725 TYPE(pair_list_type_mp2), INTENT(INOUT) :: list
726 TYPE(pair_set_list_type), DIMENSION(:), &
727 INTENT(OUT) :: set_list
728 INTEGER, INTENT(IN) :: i_start, i_end, j_start, j_end, &
729 kind_of(*)
730 TYPE(hfx_basis_type), DIMENSION(:), INTENT(IN), &
731 POINTER :: basis_parameter
732 TYPE(particle_type), DIMENSION(:), INTENT(IN), &
733 POINTER :: particle_set
734 LOGICAL, INTENT(IN) :: do_periodic
735 TYPE(hfx_screen_coeff_type), &
736 DIMENSION(:, :, :, :), INTENT(IN), POINTER :: coeffs_set
737 TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
738 INTENT(IN) :: coeffs_kind
739 REAL(kind=dp), INTENT(IN) :: coeffs_kind_max0, log10_eps_schwarz
740 TYPE(cell_type), POINTER :: cell
741 REAL(dp), INTENT(IN) :: pmax_blocks
742 LOGICAL, DIMENSION(natom, natom), INTENT(IN) :: atomic_pair_list
743 LOGICAL, INTENT(IN), OPTIONAL :: skip_atom_symmetry
744
745 INTEGER :: iatom, ikind, iset, jatom, jkind, jset, &
746 n_element, nset_ij, nseta, nsetb
747 LOGICAL :: my_skip_atom_symmetry
748 REAL(kind=dp) :: rab2
749 REAL(kind=dp), DIMENSION(3) :: b11, pbc_b, ra, rb, temp
750
751 n_element = 0
752 nset_ij = 0
753
754 my_skip_atom_symmetry = .false.
755 IF (PRESENT(skip_atom_symmetry)) my_skip_atom_symmetry = skip_atom_symmetry
756
757 DO iatom = i_start, i_end
758 DO jatom = j_start, j_end
759 IF (atomic_pair_list(jatom, iatom) .EQV. .false.) cycle
760
761 ikind = kind_of(iatom)
762 nseta = basis_parameter(ikind)%nset
763 ra = particle_set(iatom)%r(:)
764
765 IF (jatom < iatom .AND. (.NOT. my_skip_atom_symmetry)) cycle
766 jkind = kind_of(jatom)
767 nsetb = basis_parameter(jkind)%nset
768 rb = particle_set(jatom)%r(:)
769
770 IF (do_periodic) THEN
771 temp = rb - ra
772 pbc_b = pbc(temp, cell)
773 b11 = ra + pbc_b
774 rab2 = (ra(1) - b11(1))**2 + (ra(2) - b11(2))**2 + (ra(3) - b11(3))**2
775 ELSE
776 rab2 = (ra(1) - rb(1))**2 + (ra(2) - rb(2))**2 + (ra(3) - rb(3))**2
777 b11 = rb ! ra - rb
778 END IF
779 IF ((coeffs_kind(jkind, ikind)%x(1)*rab2 + &
780 coeffs_kind(jkind, ikind)%x(2)) + coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) cycle
781
782 n_element = n_element + 1
783 list%elements(n_element)%pair = [iatom, jatom]
784 list%elements(n_element)%kind_pair = [ikind, jkind]
785 list%elements(n_element)%r1 = ra
786 list%elements(n_element)%r2 = b11
787 list%elements(n_element)%dist2 = rab2
788 ! build a list of guaranteed overlapping sets
789 list%elements(n_element)%set_bounds(1) = nset_ij + 1
790 DO iset = 1, nseta
791 DO jset = 1, nsetb
792 IF (coeffs_set(jset, iset, jkind, ikind)%x(1)*rab2 + coeffs_set(jset, iset, jkind, ikind)%x(2) + &
793 coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) cycle
794 nset_ij = nset_ij + 1
795 set_list(nset_ij)%pair = [iset, jset]
796 END DO
797 END DO
798 list%elements(n_element)%set_bounds(2) = nset_ij
799 END DO
800 END DO
801
802 list%n_element = n_element
803
804 END SUBROUTINE build_pair_list_mp2
805
806! **************************************************************************************************
807!> \brief Smallest increase of |r|**2 when r is moved to any other periodic image of an
808!> orthorhombic, fully periodic cell, i.e. min over n /= 0 of |r - hmat*n|**2 - |r|**2.
809!> Exact if r is a minimum-image vector (|r(i)| <= |hmat(i,i)|/2); negative otherwise.
810!> \param r displacement vector
811!> \param hmat cell matrix; its diagonal entries are signed cell-vector components
812!> \return the squared-distance gap to the nearest other periodic image
813! **************************************************************************************************
814 PURE FUNCTION min_image_gap_sq(r, hmat) RESULT(gap)
815 REAL(dp), DIMENSION(3), INTENT(IN) :: r
816 REAL(dp), DIMENSION(3, 3), INTENT(IN) :: hmat
817 REAL(dp) :: gap
818
819 REAL(dp), DIMENSION(3) :: cell_len
820
821 cell_len = [abs(hmat(1, 1)), abs(hmat(2, 2)), abs(hmat(3, 3))]
822 gap = minval(cell_len*(cell_len - 2.0_dp*abs(r)))
823
824 END FUNCTION min_image_gap_sq
825
826END MODULE hfx_pair_list_methods
Handles all functions related to the CELL.
Definition cell_types.F:15
Routines for optimizing load balance between processes in HFX calculations.
subroutine, public build_pgf_product_list(list1, list2, product_list, nproducts, log10_pmax, log10_eps_schwarz, neighbor_cells, cell, potential_parameter, m_max, do_periodic)
...
subroutine, public build_atomic_pair_list(natom, atomic_pair_list, kind_of, basis_parameter, particle_set, do_periodic, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, blocks)
...
subroutine, public build_pair_list(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, pmax_blocks, atomic_pair_list)
...
pure real(dp) function, public min_image_gap_sq(r, hmat)
Smallest increase of |r|**2 when r is moved to any other periodic image of an orthorhombic,...
subroutine, public build_pair_list_mp2(natom, list, set_list, i_start, i_end, j_start, j_end, kind_of, basis_parameter, particle_set, do_periodic, coeffs_set, coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, pmax_blocks, atomic_pair_list, skip_atom_symmetry)
...
subroutine, public build_pair_list_pgf(npgfa, npgfb, list, zeta, zetb, screen1, screen2, pgf, r_pgf, log10_pmax, log10_eps_schwarz, ra, rb, nelements, neighbor_cells, nimages, do_periodic, cell)
...
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.
integer, save, public pgf_product_list_size
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_id
integer, parameter, public do_potential_short
integer, parameter, public do_potential_mix_cl_trunc
integer, parameter, public do_potential_tshpsc
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the Libint-Library or a c++ wrapper.
integer, parameter, public prim_data_f_size
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Definition list.F:24
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
Types needed for MP2 calculations.
Definition mp2_types.F:14
Define the data structure for the particle information.
Radial fundamentals for Gaussian two-electron integrals. Entry m+1 stores order m....
subroutine, public compute_r12_fundamentals(f, normalization, m_max, potential_type, rho, t, work, omega, cutoff_radius, scale_coulomb, scale_longrange, scale_gaussian)
Compose radial kernels before applying their common normalization.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60