Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 : ! **************************************************************************************************
8 : !> \brief Calculation of the nuclear attraction contribution to the core Hamiltonian
9 : !> <a|erfc|b> :we only calculate the non-screened part
10 : !> \par History
11 : !> - core_ppnl refactored from qs_core_hamiltonian [Joost VandeVondele, 2008-11-01]
12 : !> - adapted for nuclear attraction [jhu, 2009-02-24]
13 : ! **************************************************************************************************
14 : MODULE core_ae
15 : USE ai_verfc, ONLY: verfc
16 : USE ao_util, ONLY: exp_radius
17 : USE atomic_kind_types, ONLY: atomic_kind_type,&
18 : get_atomic_kind_set
19 : USE basis_set_types, ONLY: gto_basis_set_p_type,&
20 : gto_basis_set_type
21 : USE cp_dbcsr_api, ONLY: dbcsr_add,&
22 : dbcsr_get_block_p,&
23 : dbcsr_p_type
24 : USE external_potential_types, ONLY: all_potential_type,&
25 : get_potential,&
26 : sgp_potential_type
27 : USE kinds, ONLY: dp,&
28 : int_8
29 : USE orbital_pointers, ONLY: coset,&
30 : indco,&
31 : init_orbital_pointers,&
32 : ncoset
33 : USE particle_types, ONLY: particle_type
34 : USE qs_force_types, ONLY: qs_force_type
35 : USE qs_kind_types, ONLY: get_qs_kind,&
36 : get_qs_kind_set,&
37 : qs_kind_type
38 : USE qs_neighbor_list_types, ONLY: get_iterator_info,&
39 : neighbor_list_iterator_create,&
40 : neighbor_list_iterator_p_type,&
41 : neighbor_list_iterator_release,&
42 : neighbor_list_set_p_type,&
43 : nl_set_sub_iterator,&
44 : nl_sub_iterate
45 : USE virial_methods, ONLY: virial_pair_force
46 : USE virial_types, ONLY: virial_type
47 :
48 : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
49 : !$ USE OMP_LIB, ONLY: omp_lock_kind, &
50 : !$ omp_init_lock, omp_set_lock, &
51 : !$ omp_unset_lock, omp_destroy_lock
52 :
53 : #include "./base/base_uses.f90"
54 :
55 : IMPLICIT NONE
56 :
57 : PRIVATE
58 :
59 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'core_ae'
60 :
61 : PUBLIC :: build_core_ae, build_erfc, verfc_force
62 :
63 : CONTAINS
64 :
65 : ! **************************************************************************************************
66 : !> \brief ...
67 : !> \param matrix_h ...
68 : !> \param matrix_p ...
69 : !> \param force ...
70 : !> \param virial ...
71 : !> \param calculate_forces ...
72 : !> \param use_virial ...
73 : !> \param nder ...
74 : !> \param qs_kind_set ...
75 : !> \param atomic_kind_set ...
76 : !> \param particle_set ...
77 : !> \param sab_orb ...
78 : !> \param sac_ae ...
79 : !> \param nimages ...
80 : !> \param cell_to_index ...
81 : !> \param basis_type ...
82 : !> \param atcore ...
83 : ! **************************************************************************************************
84 1260 : SUBROUTINE build_core_ae(matrix_h, matrix_p, force, virial, calculate_forces, use_virial, nder, &
85 : qs_kind_set, atomic_kind_set, particle_set, sab_orb, sac_ae, &
86 1260 : nimages, cell_to_index, basis_type, atcore)
87 :
88 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_p
89 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
90 : TYPE(virial_type), POINTER :: virial
91 : LOGICAL, INTENT(IN) :: calculate_forces
92 : LOGICAL :: use_virial
93 : INTEGER :: nder
94 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
95 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
96 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
97 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
98 : POINTER :: sab_orb, sac_ae
99 : INTEGER, INTENT(IN) :: nimages
100 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
101 : CHARACTER(LEN=*), INTENT(IN) :: basis_type
102 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT), &
103 : OPTIONAL :: atcore
104 :
105 : CHARACTER(LEN=*), PARAMETER :: routineN = 'build_core_ae'
106 :
107 : INTEGER :: atom_a, handle, iatom, icol, ikind, img, irow, iset, jatom, jkind, jset, katom, &
108 : kkind, ldai, ldsab, maxco, maxl, maxnset, maxsgf, mepos, na_plus, natom, nb_plus, ncoa, &
109 : ncob, nij, nkind, nseta, nsetb, nthread, sgfa, sgfb, slot
110 1260 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
111 : INTEGER, DIMENSION(3) :: cellind
112 1260 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
113 1260 : npgfb, nsgfa, nsgfb
114 1260 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
115 : LOGICAL :: doat, dokp, found
116 1260 : LOGICAL, ALLOCATABLE, DIMENSION(:) :: active_set_pair, has_core_potential
117 : REAL(KIND=dp) :: alpha_c, atk0, atk1, core_charge, core_radius, dab, dac, dbc, f0, rab2, &
118 : rac2, rbc2, set_radius_a_max, set_radius_b_max, zeta_c
119 1260 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: alpha_core_kind, core_charge_kind, &
120 1260 : core_radius_kind, ff, zeta_core_kind
121 1260 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: habd, work
122 1260 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: hab, pab, verf, vnuc
123 : REAL(KIND=dp), DIMENSION(3) :: force_a, force_b, rab, rac, rbc
124 : REAL(KIND=dp), DIMENSION(3, 3) :: pv_thread
125 : TYPE(neighbor_list_iterator_p_type), &
126 1260 : DIMENSION(:), POINTER :: ap_iterator
127 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
128 1260 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
129 : TYPE(all_potential_type), POINTER :: all_potential
130 2520 : REAL(KIND=dp), DIMENSION(SIZE(particle_set)) :: at_thread
131 1260 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: h_block, p_block, rpgfa, rpgfb, sphi_a, &
132 1260 : sphi_b, zeta, zetb
133 1260 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
134 2520 : REAL(KIND=dp), DIMENSION(3, SIZE(particle_set)) :: force_thread
135 : TYPE(sgp_potential_type), POINTER :: sgp_potential
136 :
137 : !$ INTEGER(kind=omp_lock_kind), &
138 1260 : !$ ALLOCATABLE, DIMENSION(:) :: locks
139 : !$ INTEGER :: lock_num, hash, hash1, hash2
140 : !$ INTEGER(KIND=int_8) :: iatom8
141 : !$ INTEGER, PARAMETER :: nlock = 501
142 :
143 : MARK_USED(int_8)
144 :
145 2520 : IF (calculate_forces) THEN
146 336 : CALL timeset(routineN//"_forces", handle)
147 : ELSE
148 924 : CALL timeset(routineN, handle)
149 : END IF
150 :
151 1260 : nkind = SIZE(atomic_kind_set)
152 1260 : natom = SIZE(particle_set)
153 :
154 1260 : doat = PRESENT(atcore)
155 1260 : dokp = (nimages > 1)
156 :
157 1260 : IF (calculate_forces .OR. doat) THEN
158 340 : IF (SIZE(matrix_p, 1) == 2) THEN
159 344 : DO img = 1, nimages
160 : CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
161 252 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
162 : CALL dbcsr_add(matrix_p(2, img)%matrix, matrix_p(1, img)%matrix, &
163 344 : alpha_scalar=-2.0_dp, beta_scalar=1.0_dp)
164 : END DO
165 : END IF
166 : END IF
167 :
168 17564 : force_thread = 0.0_dp
169 5336 : at_thread = 0.0_dp
170 1260 : pv_thread = 0.0_dp
171 :
172 6120 : ALLOCATE (basis_set_list(nkind))
173 0 : ALLOCATE (has_core_potential(nkind), alpha_core_kind(nkind), zeta_core_kind(nkind), &
174 8820 : core_charge_kind(nkind), core_radius_kind(nkind))
175 3600 : has_core_potential(:) = .FALSE.
176 3600 : alpha_core_kind(:) = 0.0_dp
177 3600 : zeta_core_kind(:) = 0.0_dp
178 3600 : core_charge_kind(:) = 0.0_dp
179 3600 : core_radius_kind(:) = 0.0_dp
180 3600 : DO ikind = 1, nkind
181 2340 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set_a, basis_type=basis_type)
182 2340 : IF (ASSOCIATED(basis_set_a)) THEN
183 2340 : basis_set_list(ikind)%gto_basis_set => basis_set_a
184 : ELSE
185 0 : NULLIFY (basis_set_list(ikind)%gto_basis_set)
186 : END IF
187 : CALL get_qs_kind(qs_kind_set(ikind), all_potential=all_potential, &
188 2340 : sgp_potential=sgp_potential)
189 3600 : IF (ASSOCIATED(all_potential)) THEN
190 : CALL get_potential(potential=all_potential, &
191 : alpha_core_charge=alpha_core_kind(ikind), zeff=zeta_core_kind(ikind), &
192 2218 : ccore_charge=core_charge_kind(ikind), core_charge_radius=core_radius_kind(ikind))
193 2218 : has_core_potential(ikind) = .TRUE.
194 122 : ELSE IF (ASSOCIATED(sgp_potential)) THEN
195 : CALL get_potential(potential=sgp_potential, &
196 : alpha_core_charge=alpha_core_kind(ikind), zeff=zeta_core_kind(ikind), &
197 72 : ccore_charge=core_charge_kind(ikind), core_charge_radius=core_radius_kind(ikind))
198 72 : has_core_potential(ikind) = .TRUE.
199 : END IF
200 : END DO
201 :
202 : CALL get_qs_kind_set(qs_kind_set, basis_type=basis_type, &
203 1260 : maxco=maxco, maxlgto=maxl, maxsgf=maxsgf, maxnset=maxnset)
204 1260 : CALL init_orbital_pointers(maxl + nder + 1)
205 1260 : ldsab = MAX(maxco, maxsgf)
206 1260 : ldai = ncoset(maxl + nder + 1)
207 :
208 : nthread = 1
209 1260 : !$ nthread = omp_get_max_threads()
210 :
211 : ! iterator for basis/potential list
212 1260 : CALL neighbor_list_iterator_create(ap_iterator, sac_ae, search=.TRUE., nthread=nthread)
213 :
214 : !$OMP PARALLEL &
215 : !$OMP DEFAULT (NONE) &
216 : !$OMP SHARED (ap_iterator, basis_set_list, calculate_forces, use_virial, &
217 : !$OMP matrix_h, matrix_p, atomic_kind_set, qs_kind_set, particle_set, &
218 : !$OMP sab_orb, sac_ae, nthread, ncoset, nkind, cell_to_index, &
219 : !$OMP slot, ldsab, maxnset, ldai, nder, maxl, maxco, dokp, doat, locks, natom, &
220 : !$OMP has_core_potential, alpha_core_kind, zeta_core_kind, core_charge_kind, &
221 : !$OMP core_radius_kind) &
222 : !$OMP PRIVATE (ikind, jkind, iatom, jatom, rab, basis_set_a, basis_set_b, &
223 : !$OMP first_sgfa, la_max, la_min, npgfa, nsgfa, sphi_a, lock_num, &
224 : !$OMP zeta, first_sgfb, lb_max, lb_min, npgfb, nsetb, rpgfb, set_radius_b, sphi_b, &
225 : !$OMP zetb, zeta_c, alpha_c, core_charge, dab, irow, icol, h_block, found, iset, ncoa, &
226 : !$OMP sgfa, jset, ncob, sgfb, nsgfb, p_block, work, pab, hab, kkind, nseta, &
227 : !$OMP rac, dac, rbc, rab2, rac2, rbc2, dbc, na_plus, nb_plus, verf, vnuc, &
228 : !$OMP set_radius_a, core_radius, set_radius_a_max, set_radius_b_max, rpgfa, force_a, force_b, mepos, &
229 : !$OMP atk0, atk1, habd, f0, katom, cellind, img, nij, ff, &
230 : !$OMP active_set_pair, sgp_potential, all_potential, hash, hash1, hash2, iatom8) &
231 1260 : !$OMP REDUCTION (+ : pv_thread, force_thread, at_thread )
232 :
233 : !$OMP SINGLE
234 : !$ ALLOCATE (locks(nlock))
235 : !$OMP END SINGLE
236 :
237 : !$OMP DO
238 : !$ DO lock_num = 1, nlock
239 : !$ call omp_init_lock(locks(lock_num))
240 : !$ END DO
241 : !$OMP END DO
242 :
243 : mepos = 0
244 : !$ mepos = omp_get_thread_num()
245 :
246 : ALLOCATE (hab(ldsab, ldsab, maxnset*maxnset), work(ldsab, ldsab))
247 : ALLOCATE (verf(ldai, ldai, 2*maxl + nder + 1), vnuc(ldai, ldai, 2*maxl + nder + 1), ff(0:2*maxl + nder))
248 : ALLOCATE (active_set_pair(maxnset*maxnset))
249 : IF (calculate_forces .OR. doat) THEN
250 : ALLOCATE (pab(maxco, maxco, maxnset*maxnset))
251 : END IF
252 :
253 : !$OMP DO SCHEDULE(GUIDED)
254 : DO slot = 1, sab_orb(1)%nl_size
255 :
256 : ikind = sab_orb(1)%nlist_task(slot)%ikind
257 : jkind = sab_orb(1)%nlist_task(slot)%jkind
258 : iatom = sab_orb(1)%nlist_task(slot)%iatom
259 : jatom = sab_orb(1)%nlist_task(slot)%jatom
260 : cellind(:) = sab_orb(1)%nlist_task(slot)%cell(:)
261 : rab(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
262 :
263 : basis_set_a => basis_set_list(ikind)%gto_basis_set
264 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
265 : basis_set_b => basis_set_list(jkind)%gto_basis_set
266 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
267 : !$ iatom8 = INT(iatom - 1, int_8)*INT(natom, int_8) + INT(jatom, int_8)
268 : !$ hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
269 : ! basis ikind
270 : first_sgfa => basis_set_a%first_sgf
271 : la_max => basis_set_a%lmax
272 : la_min => basis_set_a%lmin
273 : npgfa => basis_set_a%npgf
274 : nseta = basis_set_a%nset
275 : nsgfa => basis_set_a%nsgf_set
276 : rpgfa => basis_set_a%pgf_radius
277 : set_radius_a => basis_set_a%set_radius
278 : sphi_a => basis_set_a%sphi
279 : zeta => basis_set_a%zet
280 : set_radius_a_max = MAXVAL(set_radius_a(1:nseta))
281 : ! basis jkind
282 : first_sgfb => basis_set_b%first_sgf
283 : lb_max => basis_set_b%lmax
284 : lb_min => basis_set_b%lmin
285 : npgfb => basis_set_b%npgf
286 : nsetb = basis_set_b%nset
287 : nsgfb => basis_set_b%nsgf_set
288 : rpgfb => basis_set_b%pgf_radius
289 : set_radius_b => basis_set_b%set_radius
290 : sphi_b => basis_set_b%sphi
291 : zetb => basis_set_b%zet
292 : set_radius_b_max = MAXVAL(set_radius_b(1:nsetb))
293 :
294 : dab = SQRT(SUM(rab*rab))
295 : rab2 = dab*dab
296 :
297 : DO iset = 1, nseta
298 : DO jset = 1, nsetb
299 : nij = jset + (iset - 1)*maxnset
300 : active_set_pair(nij) = set_radius_a(iset) + set_radius_b(jset) >= dab
301 : END DO
302 : END DO
303 :
304 : IF (dokp) THEN
305 : img = cell_to_index(cellind(1), cellind(2), cellind(3))
306 : ELSE
307 : img = 1
308 : END IF
309 :
310 : ! *** Use the symmetry of the first derivatives ***
311 : IF (iatom == jatom) THEN
312 : f0 = 1.0_dp
313 : ELSE
314 : f0 = 2.0_dp
315 : END IF
316 :
317 : ! *** Create matrix blocks for a new matrix block column ***
318 : IF (iatom <= jatom) THEN
319 : irow = iatom
320 : icol = jatom
321 : ELSE
322 : irow = jatom
323 : icol = iatom
324 : END IF
325 : NULLIFY (h_block)
326 : CALL dbcsr_get_block_p(matrix=matrix_h(1, img)%matrix, &
327 : row=irow, col=icol, BLOCK=h_block, found=found)
328 : IF (calculate_forces .OR. doat) THEN
329 : NULLIFY (p_block)
330 : CALL dbcsr_get_block_p(matrix=matrix_p(1, img)%matrix, &
331 : row=irow, col=icol, BLOCK=p_block, found=found)
332 : CPASSERT(ASSOCIATED(p_block))
333 : ! *** Decontract density matrix block ***
334 : DO iset = 1, nseta
335 : ncoa = npgfa(iset)*ncoset(la_max(iset))
336 : sgfa = first_sgfa(1, iset)
337 : DO jset = 1, nsetb
338 : nij = jset + (iset - 1)*maxnset
339 : IF (.NOT. active_set_pair(nij)) CYCLE
340 : ncob = npgfb(jset)*ncoset(lb_max(jset))
341 : sgfb = first_sgfb(1, jset)
342 : ! *** Decontract density matrix block ***
343 : IF (iatom <= jatom) THEN
344 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1), &
345 : p_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1))
346 : ELSE
347 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1), &
348 : TRANSPOSE(p_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1)))
349 : END IF
350 : pab(1:ncoa, 1:ncob, nij) = MATMUL(work(1:ncoa, 1:nsgfb(jset)), &
351 : TRANSPOSE(sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1)))
352 : END DO
353 : END DO
354 : END IF
355 :
356 : ! loop over all kinds for pseudopotential atoms
357 : DO iset = 1, nseta
358 : ncoa = npgfa(iset)*ncoset(la_max(iset))
359 : DO jset = 1, nsetb
360 : nij = jset + (iset - 1)*maxnset
361 : IF (.NOT. active_set_pair(nij)) CYCLE
362 : ncob = npgfb(jset)*ncoset(lb_max(jset))
363 : hab(1:ncoa, 1:ncob, nij) = 0._dp
364 : END DO
365 : END DO
366 : DO kkind = 1, nkind
367 : IF (.NOT. has_core_potential(kkind)) CYCLE
368 : alpha_c = alpha_core_kind(kkind)
369 : zeta_c = zeta_core_kind(kkind)
370 : core_charge = core_charge_kind(kkind)
371 : core_radius = core_radius_kind(kkind)
372 :
373 : CALL nl_set_sub_iterator(ap_iterator, ikind, kkind, iatom, mepos=mepos)
374 :
375 : DO WHILE (nl_sub_iterate(ap_iterator, mepos=mepos) == 0)
376 : CALL get_iterator_info(ap_iterator, jatom=katom, r=rac, mepos=mepos)
377 :
378 : dac = SQRT(SUM(rac*rac))
379 : rbc(:) = rac(:) - rab(:)
380 : dbc = SQRT(SUM(rbc*rbc))
381 : rac2 = dac*dac
382 : rbc2 = dbc*dbc
383 : IF ((set_radius_a_max + core_radius < dac) .OR. &
384 : (set_radius_b_max + core_radius < dbc)) THEN
385 : CYCLE
386 : END IF
387 :
388 : DO iset = 1, nseta
389 : IF (set_radius_a(iset) + core_radius < dac) CYCLE
390 : ncoa = npgfa(iset)*ncoset(la_max(iset))
391 : sgfa = first_sgfa(1, iset)
392 : DO jset = 1, nsetb
393 : nij = jset + (iset - 1)*maxnset
394 : IF (.NOT. active_set_pair(nij)) CYCLE
395 : IF (set_radius_b(jset) + core_radius < dbc) CYCLE
396 : ncob = npgfb(jset)*ncoset(lb_max(jset))
397 : sgfb = first_sgfb(1, jset)
398 : ! *** Calculate the GTH pseudo potential forces ***
399 : IF (doat) THEN
400 : atk0 = f0*SUM(hab(1:ncoa, 1:ncob, nij)*pab(1:ncoa, 1:ncob, nij))
401 : END IF
402 : IF (calculate_forces) THEN
403 : na_plus = npgfa(iset)*ncoset(la_max(iset) + nder)
404 : nb_plus = npgfb(jset)*ncoset(lb_max(jset))
405 : ALLOCATE (habd(na_plus, nb_plus))
406 : habd = 0._dp
407 : CALL verfc( &
408 : la_max(iset) + nder, npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
409 : lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
410 : alpha_c, core_radius, zeta_c, core_charge, &
411 : rab, rab2, rac, rac2, rbc2, hab(:, :, nij), verf, vnuc, ff(0:), &
412 : nder, habd)
413 :
414 : ! *** The derivatives w.r.t. atomic center c are ***
415 : ! *** calculated using the translational invariance ***
416 : ! *** of the first derivatives ***
417 : CALL verfc_force(habd, pab(:, :, nij), force_a, force_b, nder, &
418 : la_max(iset), la_min(iset), npgfa(iset), zeta(:, iset), &
419 : lb_max(jset), lb_min(jset), npgfb(jset), zetb(:, jset), rab)
420 :
421 : DEALLOCATE (habd)
422 :
423 : force_thread(1, iatom) = force_thread(1, iatom) + f0*force_a(1)
424 : force_thread(2, iatom) = force_thread(2, iatom) + f0*force_a(2)
425 : force_thread(3, iatom) = force_thread(3, iatom) + f0*force_a(3)
426 :
427 : force_thread(1, jatom) = force_thread(1, jatom) + f0*force_b(1)
428 : force_thread(2, jatom) = force_thread(2, jatom) + f0*force_b(2)
429 : force_thread(3, jatom) = force_thread(3, jatom) + f0*force_b(3)
430 :
431 : force_thread(1, katom) = force_thread(1, katom) - f0*force_a(1) - f0*force_b(1)
432 : force_thread(2, katom) = force_thread(2, katom) - f0*force_a(2) - f0*force_b(2)
433 : force_thread(3, katom) = force_thread(3, katom) - f0*force_a(3) - f0*force_b(3)
434 :
435 : IF (use_virial) THEN
436 : CALL virial_pair_force(pv_thread, f0, force_a, rac)
437 : CALL virial_pair_force(pv_thread, f0, force_b, rbc)
438 : END IF
439 : ELSE
440 : CALL verfc( &
441 : la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
442 : lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
443 : alpha_c, core_radius, zeta_c, core_charge, &
444 : rab, rab2, rac, rac2, rbc2, hab(:, :, nij), verf, vnuc, ff(0:))
445 : END IF
446 : ! calculate atomic contributions
447 : IF (doat) THEN
448 : atk1 = f0*SUM(hab(1:ncoa, 1:ncob, nij)*pab(1:ncoa, 1:ncob, nij))
449 : at_thread(katom) = at_thread(katom) + (atk1 - atk0)
450 : END IF
451 : END DO
452 : END DO
453 : END DO
454 : END DO
455 : ! *** Contract nuclear attraction integrals
456 : DO iset = 1, nseta
457 : sgfa = first_sgfa(1, iset)
458 : ncoa = npgfa(iset)*ncoset(la_max(iset))
459 : DO jset = 1, nsetb
460 : nij = jset + (iset - 1)*maxnset
461 : IF (.NOT. active_set_pair(nij)) CYCLE
462 : ncob = npgfb(jset)*ncoset(lb_max(jset))
463 : sgfb = first_sgfb(1, jset)
464 : !$ hash2 = MOD((iset - 1)*nsetb + jset, nlock) + 1
465 : !$ hash = MOD(hash1 + hash2, nlock) + 1
466 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(hab(1:ncoa, 1:ncob, nij), &
467 : sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1))
468 : !$ CALL omp_set_lock(locks(hash))
469 : IF (iatom <= jatom) THEN
470 : h_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) = &
471 : h_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) + &
472 : MATMUL(TRANSPOSE(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1)), work(1:ncoa, 1:nsgfb(jset)))
473 : ELSE
474 : h_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) = &
475 : h_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) + &
476 : MATMUL(TRANSPOSE(work(1:ncoa, 1:nsgfb(jset))), sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1))
477 : END IF
478 : !$ CALL omp_unset_lock(locks(hash))
479 : END DO
480 : END DO
481 :
482 : END DO
483 :
484 : DEALLOCATE (hab, work, verf, vnuc, ff, active_set_pair)
485 : IF (calculate_forces .OR. doat) THEN
486 : DEALLOCATE (pab)
487 : END IF
488 :
489 : !$OMP DO
490 : !$ DO lock_num = 1, nlock
491 : !$ call omp_destroy_lock(locks(lock_num))
492 : !$ END DO
493 : !$OMP END DO
494 :
495 : !$OMP SINGLE
496 : !$ DEALLOCATE (locks)
497 : !$OMP END SINGLE NOWAIT
498 :
499 : !$OMP END PARALLEL
500 :
501 1260 : CALL neighbor_list_iterator_release(ap_iterator)
502 :
503 0 : DEALLOCATE (basis_set_list, has_core_potential, alpha_core_kind, zeta_core_kind, &
504 1260 : core_charge_kind, core_radius_kind)
505 :
506 1260 : IF (calculate_forces .OR. doat) THEN
507 : ! *** If LSD, then recover alpha density and beta density ***
508 : ! *** from the total density (1) and the spin density (2) ***
509 340 : IF (SIZE(matrix_p, 1) == 2) THEN
510 344 : DO img = 1, nimages
511 : CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
512 252 : alpha_scalar=0.5_dp, beta_scalar=0.5_dp)
513 : CALL dbcsr_add(matrix_p(2, img)%matrix, matrix_p(1, img)%matrix, &
514 344 : alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
515 : END DO
516 : END IF
517 : END IF
518 :
519 1260 : IF (calculate_forces) THEN
520 336 : CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
521 : !$OMP DO
522 : DO iatom = 1, natom
523 1020 : atom_a = atom_of_kind(iatom)
524 1020 : ikind = kind_of(iatom)
525 4080 : force(ikind)%all_potential(:, atom_a) = force(ikind)%all_potential(:, atom_a) + force_thread(:, iatom)
526 : END DO
527 : !$OMP END DO
528 : END IF
529 1260 : IF (doat) THEN
530 16 : atcore(1:natom) = atcore(1:natom) + at_thread(1:natom)
531 : END IF
532 :
533 1260 : IF (calculate_forces .AND. use_virial) THEN
534 130 : virial%pv_ppl = virial%pv_ppl + pv_thread
535 130 : virial%pv_virial = virial%pv_virial + pv_thread
536 : END IF
537 :
538 1260 : CALL timestop(handle)
539 :
540 3780 : END SUBROUTINE build_core_ae
541 :
542 : ! **************************************************************************************************
543 : !> \brief ...
544 : !> \param habd ...
545 : !> \param pab ...
546 : !> \param fa ...
547 : !> \param fb ...
548 : !> \param nder ...
549 : !> \param la_max ...
550 : !> \param la_min ...
551 : !> \param npgfa ...
552 : !> \param zeta ...
553 : !> \param lb_max ...
554 : !> \param lb_min ...
555 : !> \param npgfb ...
556 : !> \param zetb ...
557 : !> \param rab ...
558 : ! **************************************************************************************************
559 2230832 : SUBROUTINE verfc_force(habd, pab, fa, fb, nder, la_max, la_min, npgfa, zeta, lb_max, lb_min, npgfb, zetb, rab)
560 :
561 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: habd, pab
562 : REAL(KIND=dp), DIMENSION(3), INTENT(OUT) :: fa, fb
563 : INTEGER, INTENT(IN) :: nder, la_max, la_min, npgfa
564 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: zeta
565 : INTEGER, INTENT(IN) :: lb_max, lb_min, npgfb
566 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: zetb
567 : REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: rab
568 :
569 : INTEGER :: ic_a, ic_b, icam1, icam2, icam3, icap1, &
570 : icap2, icap3, icax, icbm1, icbm2, &
571 : icbm3, icbx, icoa, icob, ipgfa, ipgfb, &
572 : na, nap, nb
573 : INTEGER, DIMENSION(3) :: la, lb
574 : REAL(KIND=dp) :: zax2, zbx2
575 :
576 2230832 : fa = 0.0_dp
577 2230832 : fb = 0.0_dp
578 :
579 2230832 : na = ncoset(la_max)
580 2230832 : nap = ncoset(la_max + nder)
581 2230832 : nb = ncoset(lb_max)
582 5579981 : DO ipgfa = 1, npgfa
583 3349149 : zax2 = zeta(ipgfa)*2.0_dp
584 10682217 : DO ipgfb = 1, npgfb
585 5102236 : zbx2 = zetb(ipgfb)*2.0_dp
586 21301357 : DO ic_a = ncoset(la_min - 1) + 1, ncoset(la_max)
587 51399888 : la(1:3) = indco(1:3, ic_a)
588 12849972 : icap1 = coset(la(1) + 1, la(2), la(3))
589 12849972 : icap2 = coset(la(1), la(2) + 1, la(3))
590 12849972 : icap3 = coset(la(1), la(2), la(3) + 1)
591 12849972 : icam1 = coset(la(1) - 1, la(2), la(3))
592 12849972 : icam2 = coset(la(1), la(2) - 1, la(3))
593 12849972 : icam3 = coset(la(1), la(2), la(3) - 1)
594 12849972 : icoa = ic_a + (ipgfa - 1)*na
595 12849972 : icax = (ipgfa - 1)*nap
596 :
597 50603667 : DO ic_b = ncoset(lb_min - 1) + 1, ncoset(lb_max)
598 130605836 : lb(1:3) = indco(1:3, ic_b)
599 32651459 : icbm1 = coset(lb(1) - 1, lb(2), lb(3))
600 32651459 : icbm2 = coset(lb(1), lb(2) - 1, lb(3))
601 32651459 : icbm3 = coset(lb(1), lb(2), lb(3) - 1)
602 32651459 : icob = ic_b + (ipgfb - 1)*nb
603 32651459 : icbx = (ipgfb - 1)*nb
604 :
605 : fa(1) = fa(1) - pab(icoa, icob)*(-zax2*habd(icap1 + icax, icob) + &
606 32651459 : REAL(la(1), KIND=dp)*habd(icam1 + icax, icob))
607 : fa(2) = fa(2) - pab(icoa, icob)*(-zax2*habd(icap2 + icax, icob) + &
608 32651459 : REAL(la(2), KIND=dp)*habd(icam2 + icax, icob))
609 : fa(3) = fa(3) - pab(icoa, icob)*(-zax2*habd(icap3 + icax, icob) + &
610 32651459 : REAL(la(3), KIND=dp)*habd(icam3 + icax, icob))
611 :
612 : fb(1) = fb(1) - pab(icoa, icob)*( &
613 : -zbx2*(habd(icap1 + icax, icob) - rab(1)*habd(ic_a + icax, icob)) + &
614 32651459 : REAL(lb(1), KIND=dp)*habd(ic_a + icax, icbm1 + icbx))
615 : fb(2) = fb(2) - pab(icoa, icob)*( &
616 : -zbx2*(habd(icap2 + icax, icob) - rab(2)*habd(ic_a + icax, icob)) + &
617 32651459 : REAL(lb(2), KIND=dp)*habd(ic_a + icax, icbm2 + icbx))
618 : fb(3) = fb(3) - pab(icoa, icob)*( &
619 : -zbx2*(habd(icap3 + icax, icob) - rab(3)*habd(ic_a + icax, icob)) + &
620 45501431 : REAL(lb(3), KIND=dp)*habd(ic_a + icax, icbm3 + icbx))
621 :
622 : END DO ! ic_b
623 : END DO ! ic_a
624 : END DO ! ipgfb
625 : END DO ! ipgfa
626 :
627 2230832 : END SUBROUTINE verfc_force
628 :
629 : ! **************************************************************************************************
630 : !> \brief Integrals = -Z*erfc(a*r)/r
631 : !> \param matrix_h ...
632 : !> \param matrix_p ...
633 : !> \param qs_kind_set ...
634 : !> \param atomic_kind_set ...
635 : !> \param particle_set ...
636 : !> \param calpha ...
637 : !> \param ccore ...
638 : !> \param eps_core_charge ...
639 : !> \param sab_orb ...
640 : !> \param sac_ae ...
641 : !> \param atcore ...
642 : ! **************************************************************************************************
643 4 : SUBROUTINE build_erfc(matrix_h, matrix_p, qs_kind_set, atomic_kind_set, particle_set, &
644 8 : calpha, ccore, eps_core_charge, sab_orb, sac_ae, atcore)
645 :
646 : TYPE(dbcsr_p_type) :: matrix_h
647 : TYPE(dbcsr_p_type), DIMENSION(:) :: matrix_p
648 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
649 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
650 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
651 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: calpha, ccore
652 : REAL(KIND=dp), INTENT(IN) :: eps_core_charge
653 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
654 : POINTER :: sab_orb, sac_ae
655 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT), &
656 : OPTIONAL :: atcore
657 :
658 : CHARACTER(LEN=*), PARAMETER :: routineN = 'build_erfc'
659 :
660 : INTEGER :: handle, iatom, icol, ikind, img, irow, iset, jatom, jkind, jset, katom, kkind, &
661 : ldai, ldsab, maxco, maxl, maxnset, maxsgf, mepos, na_plus, natom, nb_plus, ncoa, ncob, &
662 : nij, nkind, nseta, nsetb, nthread, sgfa, sgfb, slot
663 : INTEGER, DIMENSION(3) :: cellind
664 4 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
665 4 : npgfb, nsgfa, nsgfb
666 4 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
667 : LOGICAL :: doat, found
668 : REAL(KIND=dp) :: alpha_c, atk0, atk1, core_charge, &
669 : core_radius, dab, dac, dbc, f0, rab2, &
670 : rac2, rbc2, zeta_c
671 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ff
672 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: habd, work
673 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: hab, pab, verf, vnuc
674 : REAL(KIND=dp), DIMENSION(3) :: rab, rac, rbc
675 4 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
676 4 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: h_block, p_block, rpgfa, rpgfb, sphi_a, &
677 4 : sphi_b, zeta, zetb
678 : TYPE(neighbor_list_iterator_p_type), &
679 4 : DIMENSION(:), POINTER :: ap_iterator
680 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
681 4 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
682 : TYPE(all_potential_type), POINTER :: all_potential
683 8 : REAL(KIND=dp), DIMENSION(SIZE(particle_set)) :: at_thread
684 : TYPE(sgp_potential_type), POINTER :: sgp_potential
685 :
686 : !$ INTEGER(kind=omp_lock_kind), &
687 4 : !$ ALLOCATABLE, DIMENSION(:) :: locks
688 : !$ INTEGER :: lock_num, hash, hash1, hash2
689 : !$ INTEGER(KIND=int_8) :: iatom8
690 : !$ INTEGER, PARAMETER :: nlock = 501
691 :
692 : MARK_USED(int_8)
693 :
694 4 : CALL timeset(routineN, handle)
695 :
696 4 : nkind = SIZE(atomic_kind_set)
697 4 : natom = SIZE(particle_set)
698 :
699 4 : doat = PRESENT(atcore)
700 :
701 4 : IF (doat) THEN
702 4 : IF (SIZE(matrix_p, 1) == 2) THEN
703 : CALL dbcsr_add(matrix_p(1)%matrix, matrix_p(2)%matrix, &
704 0 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
705 : CALL dbcsr_add(matrix_p(2)%matrix, matrix_p(1)%matrix, &
706 0 : alpha_scalar=-2.0_dp, beta_scalar=1.0_dp)
707 : END IF
708 : END IF
709 :
710 16 : at_thread = 0.0_dp
711 :
712 20 : ALLOCATE (basis_set_list(nkind))
713 12 : DO ikind = 1, nkind
714 8 : CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set_a)
715 12 : IF (ASSOCIATED(basis_set_a)) THEN
716 8 : basis_set_list(ikind)%gto_basis_set => basis_set_a
717 : ELSE
718 0 : NULLIFY (basis_set_list(ikind)%gto_basis_set)
719 : END IF
720 : END DO
721 :
722 : CALL get_qs_kind_set(qs_kind_set, &
723 4 : maxco=maxco, maxlgto=maxl, maxsgf=maxsgf, maxnset=maxnset)
724 4 : CALL init_orbital_pointers(maxl + 1)
725 4 : ldsab = MAX(maxco, maxsgf)
726 4 : ldai = ncoset(maxl + 1)
727 :
728 : nthread = 1
729 4 : !$ nthread = omp_get_max_threads()
730 :
731 : ! iterator for basis/potential list
732 4 : CALL neighbor_list_iterator_create(ap_iterator, sac_ae, search=.TRUE., nthread=nthread)
733 :
734 : !$OMP PARALLEL &
735 : !$OMP DEFAULT (NONE) &
736 : !$OMP SHARED (ap_iterator, basis_set_list, &
737 : !$OMP matrix_h, matrix_p, atomic_kind_set, qs_kind_set, particle_set, &
738 : !$OMP sab_orb, sac_ae, nthread, ncoset, nkind, calpha, ccore, eps_core_charge, &
739 : !$OMP slot, ldsab, maxnset, ldai, maxl, maxco, doat, locks, natom) &
740 : !$OMP PRIVATE (ikind, jkind, iatom, jatom, rab, basis_set_a, basis_set_b, &
741 : !$OMP first_sgfa, la_max, la_min, npgfa, nsgfa, sphi_a, lock_num, &
742 : !$OMP zeta, first_sgfb, lb_max, lb_min, npgfb, nsetb, rpgfb, set_radius_b, sphi_b, &
743 : !$OMP zetb, zeta_c, alpha_c, core_charge, dab, irow, icol, h_block, found, iset, ncoa, &
744 : !$OMP sgfa, jset, ncob, sgfb, nsgfb, p_block, work, pab, hab, kkind, nseta, &
745 : !$OMP rac, dac, rbc, rab2, rac2, rbc2, dbc, na_plus, nb_plus, verf, vnuc, &
746 : !$OMP set_radius_a, core_radius, rpgfa, mepos, &
747 : !$OMP atk0, atk1, habd, f0, katom, cellind, img, nij, ff, &
748 : !$OMP sgp_potential, all_potential, hash, hash1, hash2, iatom8) &
749 4 : !$OMP REDUCTION (+ : at_thread )
750 :
751 : !$OMP SINGLE
752 : !$ ALLOCATE (locks(nlock))
753 : !$OMP END SINGLE
754 :
755 : !$OMP DO
756 : !$ DO lock_num = 1, nlock
757 : !$ call omp_init_lock(locks(lock_num))
758 : !$ END DO
759 : !$OMP END DO
760 :
761 : mepos = 0
762 : !$ mepos = omp_get_thread_num()
763 :
764 : ALLOCATE (hab(ldsab, ldsab, maxnset*maxnset), work(ldsab, ldsab))
765 : ALLOCATE (verf(ldai, ldai, 2*maxl + 1), vnuc(ldai, ldai, 2*maxl + 1), ff(0:2*maxl))
766 : IF (doat) THEN
767 : ALLOCATE (pab(maxco, maxco, maxnset*maxnset))
768 : END IF
769 :
770 : !$OMP DO SCHEDULE(GUIDED)
771 : DO slot = 1, sab_orb(1)%nl_size
772 :
773 : ikind = sab_orb(1)%nlist_task(slot)%ikind
774 : jkind = sab_orb(1)%nlist_task(slot)%jkind
775 : iatom = sab_orb(1)%nlist_task(slot)%iatom
776 : jatom = sab_orb(1)%nlist_task(slot)%jatom
777 : cellind(:) = sab_orb(1)%nlist_task(slot)%cell(:)
778 : rab(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
779 :
780 : basis_set_a => basis_set_list(ikind)%gto_basis_set
781 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
782 : basis_set_b => basis_set_list(jkind)%gto_basis_set
783 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
784 : !$ iatom8 = INT(iatom - 1, int_8)*INT(natom, int_8) + INT(jatom, int_8)
785 : !$ hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
786 : ! basis ikind
787 : first_sgfa => basis_set_a%first_sgf
788 : la_max => basis_set_a%lmax
789 : la_min => basis_set_a%lmin
790 : npgfa => basis_set_a%npgf
791 : nseta = basis_set_a%nset
792 : nsgfa => basis_set_a%nsgf_set
793 : rpgfa => basis_set_a%pgf_radius
794 : set_radius_a => basis_set_a%set_radius
795 : sphi_a => basis_set_a%sphi
796 : zeta => basis_set_a%zet
797 : ! basis jkind
798 : first_sgfb => basis_set_b%first_sgf
799 : lb_max => basis_set_b%lmax
800 : lb_min => basis_set_b%lmin
801 : npgfb => basis_set_b%npgf
802 : nsetb = basis_set_b%nset
803 : nsgfb => basis_set_b%nsgf_set
804 : rpgfb => basis_set_b%pgf_radius
805 : set_radius_b => basis_set_b%set_radius
806 : sphi_b => basis_set_b%sphi
807 : zetb => basis_set_b%zet
808 :
809 : dab = SQRT(SUM(rab*rab))
810 : img = 1
811 :
812 : ! *** Use the symmetry of the first derivatives ***
813 : IF (iatom == jatom) THEN
814 : f0 = 1.0_dp
815 : ELSE
816 : f0 = 2.0_dp
817 : END IF
818 :
819 : ! *** Create matrix blocks for a new matrix block column ***
820 : IF (iatom <= jatom) THEN
821 : irow = iatom
822 : icol = jatom
823 : ELSE
824 : irow = jatom
825 : icol = iatom
826 : END IF
827 : NULLIFY (h_block)
828 : CALL dbcsr_get_block_p(matrix=matrix_h%matrix, &
829 : row=irow, col=icol, BLOCK=h_block, found=found)
830 : IF (doat) THEN
831 : NULLIFY (p_block)
832 : CALL dbcsr_get_block_p(matrix=matrix_p(1)%matrix, &
833 : row=irow, col=icol, BLOCK=p_block, found=found)
834 : CPASSERT(ASSOCIATED(p_block))
835 : ! *** Decontract density matrix block ***
836 : DO iset = 1, nseta
837 : ncoa = npgfa(iset)*ncoset(la_max(iset))
838 : sgfa = first_sgfa(1, iset)
839 : DO jset = 1, nsetb
840 : ncob = npgfb(jset)*ncoset(lb_max(jset))
841 : sgfb = first_sgfb(1, jset)
842 : nij = jset + (iset - 1)*maxnset
843 : ! *** Decontract density matrix block ***
844 : IF (iatom <= jatom) THEN
845 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1), &
846 : p_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1))
847 : ELSE
848 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1), &
849 : TRANSPOSE(p_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1)))
850 : END IF
851 : pab(1:ncoa, 1:ncob, nij) = MATMUL(work(1:ncoa, 1:nsgfb(jset)), &
852 : TRANSPOSE(sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1)))
853 : END DO
854 : END DO
855 : END IF
856 :
857 : ! loop over all kinds of atoms
858 : hab = 0._dp
859 : DO kkind = 1, nkind
860 : CALL get_qs_kind(qs_kind_set(kkind), zeff=zeta_c)
861 : alpha_c = calpha(kkind)
862 : core_charge = ccore(kkind)
863 : core_radius = exp_radius(0, alpha_c, eps_core_charge, core_charge)
864 : core_radius = MAX(core_radius, 10.0_dp)
865 :
866 : CALL nl_set_sub_iterator(ap_iterator, ikind, kkind, iatom, mepos=mepos)
867 :
868 : DO WHILE (nl_sub_iterate(ap_iterator, mepos=mepos) == 0)
869 : CALL get_iterator_info(ap_iterator, jatom=katom, r=rac, mepos=mepos)
870 :
871 : dac = SQRT(SUM(rac*rac))
872 : rbc(:) = rac(:) - rab(:)
873 : dbc = SQRT(SUM(rbc*rbc))
874 : IF ((MAXVAL(set_radius_a(:)) + core_radius < dac) .OR. &
875 : (MAXVAL(set_radius_b(:)) + core_radius < dbc)) THEN
876 : CYCLE
877 : END IF
878 :
879 : DO iset = 1, nseta
880 : IF (set_radius_a(iset) + core_radius < dac) CYCLE
881 : ncoa = npgfa(iset)*ncoset(la_max(iset))
882 : sgfa = first_sgfa(1, iset)
883 : DO jset = 1, nsetb
884 : IF (set_radius_b(jset) + core_radius < dbc) CYCLE
885 : ncob = npgfb(jset)*ncoset(lb_max(jset))
886 : sgfb = first_sgfb(1, jset)
887 : IF (set_radius_a(iset) + set_radius_b(jset) < dab) CYCLE
888 : rab2 = dab*dab
889 : rac2 = dac*dac
890 : rbc2 = dbc*dbc
891 : nij = jset + (iset - 1)*maxnset
892 : IF (doat) THEN
893 : atk0 = f0*SUM(hab(1:ncoa, 1:ncob, nij)*pab(1:ncoa, 1:ncob, nij))
894 : END IF
895 : !
896 : CALL verfc( &
897 : la_max(iset), npgfa(iset), zeta(:, iset), rpgfa(:, iset), la_min(iset), &
898 : lb_max(jset), npgfb(jset), zetb(:, jset), rpgfb(:, jset), lb_min(jset), &
899 : alpha_c, core_radius, zeta_c, core_charge, &
900 : rab, rab2, rac, rac2, rbc2, hab(:, :, nij), verf, vnuc, ff(0:))
901 : !
902 : IF (doat) THEN
903 : atk1 = f0*SUM(hab(1:ncoa, 1:ncob, nij)*pab(1:ncoa, 1:ncob, nij))
904 : at_thread(katom) = at_thread(katom) + (atk1 - atk0)
905 : END IF
906 : END DO
907 : END DO
908 : END DO
909 : END DO
910 : ! *** Contract nuclear attraction integrals
911 : DO iset = 1, nseta
912 : ncoa = npgfa(iset)*ncoset(la_max(iset))
913 : sgfa = first_sgfa(1, iset)
914 : DO jset = 1, nsetb
915 : ncob = npgfb(jset)*ncoset(lb_max(jset))
916 : sgfb = first_sgfb(1, jset)
917 : nij = jset + (iset - 1)*maxnset
918 : !$ hash2 = MOD((iset - 1)*nsetb + jset, nlock) + 1
919 : !$ hash = MOD(hash1 + hash2, nlock) + 1
920 : work(1:ncoa, 1:nsgfb(jset)) = MATMUL(hab(1:ncoa, 1:ncob, nij), &
921 : sphi_b(1:ncob, sgfb:sgfb + nsgfb(jset) - 1))
922 : !$ CALL omp_set_lock(locks(hash))
923 : IF (iatom <= jatom) THEN
924 : h_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) = &
925 : h_block(sgfa:sgfa + nsgfa(iset) - 1, sgfb:sgfb + nsgfb(jset) - 1) + &
926 : MATMUL(TRANSPOSE(sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1)), work(1:ncoa, 1:nsgfb(jset)))
927 : ELSE
928 : h_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) = &
929 : h_block(sgfb:sgfb + nsgfb(jset) - 1, sgfa:sgfa + nsgfa(iset) - 1) + &
930 : MATMUL(TRANSPOSE(work(1:ncoa, 1:nsgfb(jset))), sphi_a(1:ncoa, sgfa:sgfa + nsgfa(iset) - 1))
931 : END IF
932 : !$ CALL omp_unset_lock(locks(hash))
933 : END DO
934 : END DO
935 :
936 : END DO
937 :
938 : DEALLOCATE (hab, work, verf, vnuc, ff)
939 :
940 : !$OMP DO
941 : !$ DO lock_num = 1, nlock
942 : !$ call omp_destroy_lock(locks(lock_num))
943 : !$ END DO
944 : !$OMP END DO
945 :
946 : !$OMP SINGLE
947 : !$ DEALLOCATE (locks)
948 : !$OMP END SINGLE NOWAIT
949 :
950 : !$OMP END PARALLEL
951 :
952 4 : CALL neighbor_list_iterator_release(ap_iterator)
953 :
954 4 : DEALLOCATE (basis_set_list)
955 :
956 4 : IF (doat) THEN
957 : ! *** If LSD, then recover alpha density and beta density ***
958 : ! *** from the total density (1) and the spin density (2) ***
959 4 : IF (SIZE(matrix_p, 1) == 2) THEN
960 : CALL dbcsr_add(matrix_p(1)%matrix, matrix_p(2)%matrix, &
961 0 : alpha_scalar=0.5_dp, beta_scalar=0.5_dp)
962 : CALL dbcsr_add(matrix_p(2)%matrix, matrix_p(1)%matrix, &
963 0 : alpha_scalar=-1.0_dp, beta_scalar=1.0_dp)
964 : END IF
965 : END IF
966 :
967 : IF (doat) THEN
968 16 : atcore(1:natom) = atcore(1:natom) + at_thread(1:natom)
969 : END IF
970 :
971 4 : CALL timestop(handle)
972 :
973 12 : END SUBROUTINE build_erfc
974 :
975 : ! **************************************************************************************************
976 :
977 : END MODULE core_ae
|