(git:374b731)
Loading...
Searching...
No Matches
qs_overlap.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Calculation of overlap matrix, its derivatives and forces
10!> \par History
11!> JGH: removed printing routines
12!> JGH: upgraded to unique routine for overlaps
13!> JGH: Add specific routine for 'forces only'
14!> Major refactoring for new overlap routines
15!> JGH: Kpoints
16!> JGH: openMP refactoring
17!> \author Matthias Krack (03.09.2001,25.06.2003)
18! **************************************************************************************************
20 USE ai_contraction, ONLY: block_add,&
24 USE ai_overlap, ONLY: overlap_ab
34 USE dbcsr_api, ONLY: &
35 dbcsr_create, dbcsr_distribution_type, dbcsr_filter, dbcsr_finalize, dbcsr_get_block_p, &
36 dbcsr_p_type, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
37 dbcsr_type_symmetric
38 USE kinds, ONLY: default_string_length,&
39 dp,&
40 int_8
41 USE kpoint_types, ONLY: get_kpoint_info,&
43 USE orbital_pointers, ONLY: indco,&
44 ncoset
52 USE qs_ks_types, ONLY: get_ks_env,&
56 USE string_utilities, ONLY: compress,&
59 USE virial_types, ONLY: virial_type
60
61!$ USE OMP_LIB, ONLY: omp_lock_kind, &
62!$ omp_init_lock, omp_set_lock, &
63!$ omp_unset_lock, omp_destroy_lock
64
65#include "./base/base_uses.f90"
66
67 IMPLICIT NONE
68
69 PRIVATE
70
71! *** Global parameters ***
72
73 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_overlap'
74
75 ! should be a parameter, but this triggers a bug in OMPed code with gfortran 4.9
76 INTEGER, DIMENSION(1:56), SAVE :: ndod = (/0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, &
77 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, &
78 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, &
79 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1/)
80
82 MODULE PROCEDURE create_sab_matrix_1d, create_sab_matrix_2d
83 END INTERFACE
84
85! *** Public subroutines ***
86
89
90CONTAINS
91
92! **************************************************************************************************
93!> \brief Calculation of the overlap matrix over Cartesian Gaussian functions.
94!> \param ks_env the QS env
95!> \param matrix_s The overlap matrix to be calculated (optional)
96!> \param matrixkp_s The overlap matrices to be calculated (kpoints, optional)
97!> \param matrix_name The name of the overlap matrix (i.e. for output)
98!> \param nderivative Derivative with respect to basis origin
99!> \param basis_type_a basis set to be used for bra in <a|b>
100!> \param basis_type_b basis set to be used for ket in <a|b>
101!> \param sab_nl pair list (must be consistent with basis sets!)
102!> \param calculate_forces (optional) ...
103!> \param matrix_p density matrix for force calculation (optional)
104!> \param matrixkp_p density matrix for force calculation with k_points (optional)
105!> \date 11.03.2002
106!> \par History
107!> Enlarged functionality of this routine. Now overlap matrices based
108!> on different basis sets can be calculated, taking into account also
109!> mixed overlaps NOTE: the pointer to the overlap matrix must now be
110!> put into its corresponding env outside of this routine
111!> [Manuel Guidon]
112!> Generalized for derivatives and force calculations [JHU]
113!> Kpoints, returns overlap matrices in real space index form
114!> \author MK
115!> \version 1.0
116! **************************************************************************************************
117 SUBROUTINE build_overlap_matrix(ks_env, matrix_s, matrixkp_s, matrix_name, &
118 nderivative, basis_type_a, basis_type_b, sab_nl, calculate_forces, &
119 matrix_p, matrixkp_p)
120
121 TYPE(qs_ks_env_type), POINTER :: ks_env
122 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
123 POINTER :: matrix_s
124 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
125 POINTER :: matrixkp_s
126 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: matrix_name
127 INTEGER, INTENT(IN), OPTIONAL :: nderivative
128 CHARACTER(LEN=*), INTENT(IN) :: basis_type_a, basis_type_b
129 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
130 POINTER :: sab_nl
131 LOGICAL, INTENT(IN), OPTIONAL :: calculate_forces
132 TYPE(dbcsr_type), OPTIONAL, POINTER :: matrix_p
133 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
134 POINTER :: matrixkp_p
135
136 INTEGER :: natom
137
138 mark_used(int_8)
139
140 CALL get_ks_env(ks_env, natom=natom)
141
142 CALL build_overlap_matrix_low(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, &
143 basis_type_a, basis_type_b, sab_nl, calculate_forces, &
144 matrix_p, matrixkp_p, natom)
145
146 END SUBROUTINE build_overlap_matrix
147
148! **************************************************************************************************
149!> \brief Implementation of build_overlap_matrix with the additional natom argument passed in to
150!> allow for explicitly shaped force_thread array which is needed for OMP REDUCTION.
151!> \param ks_env ...
152!> \param matrix_s ...
153!> \param matrixkp_s ...
154!> \param matrix_name ...
155!> \param nderivative ...
156!> \param basis_type_a ...
157!> \param basis_type_b ...
158!> \param sab_nl ...
159!> \param calculate_forces ...
160!> \param matrix_p ...
161!> \param matrixkp_p ...
162!> \param natom ...
163! **************************************************************************************************
164 SUBROUTINE build_overlap_matrix_low(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, &
165 basis_type_a, basis_type_b, sab_nl, calculate_forces, &
166 matrix_p, matrixkp_p, natom)
167
168 TYPE(qs_ks_env_type), POINTER :: ks_env
169 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL, &
170 POINTER :: matrix_s
171 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
172 POINTER :: matrixkp_s
173 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: matrix_name
174 INTEGER, INTENT(IN), OPTIONAL :: nderivative
175 CHARACTER(LEN=*), INTENT(IN) :: basis_type_a, basis_type_b
176 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
177 POINTER :: sab_nl
178 LOGICAL, INTENT(IN), OPTIONAL :: calculate_forces
179 TYPE(dbcsr_type), OPTIONAL, POINTER :: matrix_p
180 TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
181 POINTER :: matrixkp_p
182 INTEGER, INTENT(IN) :: natom
183
184 CHARACTER(len=*), PARAMETER :: routinen = 'build_overlap_matrix_low'
185
186 INTEGER :: atom_a, handle, i, iatom, ic, icol, ikind, irow, iset, jatom, jkind, jset, ldsab, &
187 maxder, maxs, n1, n2, ncoa, ncob, nder, nimg, nkind, nseta, nsetb, sgfa, sgfb, slot
188 INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
189 INTEGER, DIMENSION(3) :: cell
190 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
191 npgfb, nsgfa, nsgfb
192 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
193 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
194 LOGICAL :: do_forces, do_symmetric, dokp, found, &
195 trans, use_cell_mapping, use_virial
196 REAL(kind=dp) :: dab, f, f0, ff, rab2
197 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: owork, pmat
198 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: oint
199 REAL(kind=dp), DIMENSION(3) :: force_a, rab
200 REAL(kind=dp), DIMENSION(3, 3) :: pv_thread
201 REAL(kind=dp), DIMENSION(3, natom) :: force_thread
202 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
203 REAL(kind=dp), DIMENSION(:, :), POINTER :: p_block, rpgfa, rpgfb, scon_a, scon_b, &
204 zeta, zetb
205 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
206 TYPE(block_p_type), ALLOCATABLE, DIMENSION(:) :: sint
207 TYPE(dft_control_type), POINTER :: dft_control
208 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
209 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
210 TYPE(kpoint_type), POINTER :: kpoints
211 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
212 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
213 TYPE(virial_type), POINTER :: virial
214
215!$ INTEGER(kind=omp_lock_kind), &
216!$ ALLOCATABLE, DIMENSION(:) :: locks
217!$ INTEGER :: lock_num, hash, hash1, hash2
218!$ INTEGER(KIND=int_8) :: iatom8
219!$ INTEGER, PARAMETER :: nlock = 501
220
221 CALL timeset(routinen, handle)
222
223 ! test for matrices (kpoints or standard gamma point)
224 IF (PRESENT(matrix_s)) THEN
225 dokp = .false.
226 use_cell_mapping = .false.
227 ELSEIF (PRESENT(matrixkp_s)) THEN
228 dokp = .true.
229 CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
230 CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
231 use_cell_mapping = (SIZE(cell_to_index) > 1)
232 ELSE
233 cpabort("")
234 END IF
235
236 NULLIFY (atomic_kind_set)
237 CALL get_ks_env(ks_env, &
238 atomic_kind_set=atomic_kind_set, &
239 qs_kind_set=qs_kind_set, &
240 dft_control=dft_control)
241
242 nimg = dft_control%nimages
243 nkind = SIZE(qs_kind_set)
244
245 IF (PRESENT(calculate_forces)) THEN
246 do_forces = calculate_forces
247 ELSE
248 do_forces = .false.
249 END IF
250
251 IF (PRESENT(nderivative)) THEN
252 nder = nderivative
253 ELSE
254 nder = 0
255 END IF
256 maxder = ncoset(nder)
257
258 ! check for symmetry
259 cpassert(SIZE(sab_nl) > 0)
260 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
261 IF (do_symmetric) THEN
262 cpassert(basis_type_a == basis_type_b)
263 END IF
264
265 ! set up basis set lists
266 ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
267 CALL basis_set_list_setup(basis_set_list_a, basis_type_a, qs_kind_set)
268 CALL basis_set_list_setup(basis_set_list_b, basis_type_b, qs_kind_set)
269
270 IF (dokp) THEN
271 CALL dbcsr_allocate_matrix_set(matrixkp_s, maxder, nimg)
272 CALL create_sab_matrix(ks_env, matrixkp_s, matrix_name, basis_set_list_a, basis_set_list_b, &
273 sab_nl, do_symmetric)
274 ELSE
275 CALL dbcsr_allocate_matrix_set(matrix_s, maxder)
276 CALL create_sab_matrix(ks_env, matrix_s, matrix_name, basis_set_list_a, basis_set_list_b, &
277 sab_nl, do_symmetric)
278 END IF
279 maxs = maxder
280
281 use_virial = .false.
282 IF (do_forces) THEN
283 CALL get_ks_env(ks_env=ks_env, force=force, virial=virial)
284 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
285 END IF
286
287 force_thread = 0.0_dp
288 pv_thread = 0.0_dp
289
290 ldsab = get_memory_usage(qs_kind_set, basis_type_a, basis_type_b)
291 IF (do_forces) THEN
292 ! we need density matrix for forces
293 IF (dokp) THEN
294 cpassert(PRESENT(matrixkp_p))
295 ELSE
296 cpassert(PRESENT(matrix_p))
297 END IF
298 nder = max(nder, 1)
299 END IF
300 maxder = ncoset(nder)
301
302!$OMP PARALLEL DEFAULT(NONE) &
303!$OMP SHARED (do_forces, ldsab, maxder, use_cell_mapping, do_symmetric, maxs, dokp, &
304!$OMP ncoset, nder, use_virial, ndod, sab_nl, nimg,&
305!$OMP matrix_s, matrix_p,basis_set_list_a, basis_set_list_b, cell_to_index, &
306!$OMP matrixkp_s, matrixkp_p, locks, natom) &
307!$OMP PRIVATE (oint, owork, pmat, sint, ikind, jkind, iatom, jatom, rab, cell, &
308!$OMP basis_set_a, basis_set_b, &
309!$OMP first_sgfa, la_max, la_min, npgfa, nsgfa, nseta, rpgfa, set_radius_a, ncoa, ncob, force_a, &
310!$OMP zeta, first_sgfb, lb_max, lb_min, npgfb, nsetb, rpgfb, set_radius_b, nsgfb, p_block, dab, f, &
311!$OMP zetb, scon_a, scon_b, ic, irow, icol, f0, ff, found, trans, rab2, n1, n2, sgfa, sgfb, iset, jset, &
312!$OMP hash, hash1, hash2, iatom8, slot ) &
313!$OMP REDUCTION (+ : pv_thread, force_thread )
314
315!$OMP SINGLE
316!$ ALLOCATE (locks(nlock))
317!$OMP END SINGLE
318
319!$OMP DO
320!$ DO lock_num = 1, nlock
321!$ call omp_init_lock(locks(lock_num))
322!$ END DO
323!$OMP END DO
324
325 NULLIFY (p_block)
326 ALLOCATE (oint(ldsab, ldsab, maxder), owork(ldsab, ldsab))
327 IF (do_forces) ALLOCATE (pmat(ldsab, ldsab))
328 ALLOCATE (sint(maxs))
329 DO i = 1, maxs
330 NULLIFY (sint(i)%block)
331 END DO
332
333!$OMP DO SCHEDULE(GUIDED)
334 DO slot = 1, sab_nl(1)%nl_size
335
336 ikind = sab_nl(1)%nlist_task(slot)%ikind
337 jkind = sab_nl(1)%nlist_task(slot)%jkind
338 iatom = sab_nl(1)%nlist_task(slot)%iatom
339 jatom = sab_nl(1)%nlist_task(slot)%jatom
340 cell(:) = sab_nl(1)%nlist_task(slot)%cell(:)
341 rab(1:3) = sab_nl(1)%nlist_task(slot)%r(1:3)
342
343 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
344 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
345 basis_set_b => basis_set_list_b(jkind)%gto_basis_set
346 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
347
348!$ iatom8 = INT(iatom - 1, int_8)*INT(natom, int_8) + INT(jatom, int_8)
349!$ hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
350
351 ! basis ikind
352 first_sgfa => basis_set_a%first_sgf
353 la_max => basis_set_a%lmax
354 la_min => basis_set_a%lmin
355 npgfa => basis_set_a%npgf
356 nseta = basis_set_a%nset
357 nsgfa => basis_set_a%nsgf_set
358 rpgfa => basis_set_a%pgf_radius
359 set_radius_a => basis_set_a%set_radius
360 scon_a => basis_set_a%scon
361 zeta => basis_set_a%zet
362 ! basis jkind
363 first_sgfb => basis_set_b%first_sgf
364 lb_max => basis_set_b%lmax
365 lb_min => basis_set_b%lmin
366 npgfb => basis_set_b%npgf
367 nsetb = basis_set_b%nset
368 nsgfb => basis_set_b%nsgf_set
369 rpgfb => basis_set_b%pgf_radius
370 set_radius_b => basis_set_b%set_radius
371 scon_b => basis_set_b%scon
372 zetb => basis_set_b%zet
373
374 IF (use_cell_mapping) THEN
375 ic = cell_to_index(cell(1), cell(2), cell(3))
376 IF (ic < 1 .OR. ic > nimg) cycle
377 ELSE
378 ic = 1
379 END IF
380
381 IF (do_symmetric) THEN
382 IF (iatom <= jatom) THEN
383 irow = iatom
384 icol = jatom
385 ELSE
386 irow = jatom
387 icol = iatom
388 END IF
389 f0 = 2.0_dp
390 ff = 2.0_dp
391 IF (iatom == jatom) f0 = 1.0_dp
392 ELSE
393 irow = iatom
394 icol = jatom
395 f0 = 1.0_dp
396 ff = 1.0_dp
397 END IF
398 DO i = 1, maxs
399 NULLIFY (sint(i)%block)
400 IF (dokp) THEN
401 CALL dbcsr_get_block_p(matrix=matrixkp_s(i, ic)%matrix, &
402 row=irow, col=icol, block=sint(i)%block, found=found)
403 cpassert(found)
404 ELSE
405 CALL dbcsr_get_block_p(matrix=matrix_s(i)%matrix, &
406 row=irow, col=icol, block=sint(i)%block, found=found)
407 cpassert(found)
408 END IF
409 END DO
410 IF (do_forces) THEN
411 NULLIFY (p_block)
412 IF (dokp) THEN
413 CALL dbcsr_get_block_p(matrix=matrixkp_p(1, ic)%matrix, &
414 row=irow, col=icol, block=p_block, found=found)
415 cpassert(found)
416 ELSE
417 CALL dbcsr_get_block_p(matrix=matrix_p, row=irow, col=icol, &
418 block=p_block, found=found)
419 cpassert(found)
420 END IF
421 END IF
422 trans = do_symmetric .AND. (iatom > jatom)
423
424 rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
425 dab = sqrt(rab2)
426
427 DO iset = 1, nseta
428
429 ncoa = npgfa(iset)*ncoset(la_max(iset))
430 n1 = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
431 sgfa = first_sgfa(1, iset)
432
433 DO jset = 1, nsetb
434
435 IF (set_radius_a(iset) + set_radius_b(jset) < dab) cycle
436
437!$ hash2 = MOD((iset - 1)*nsetb + jset, nlock) + 1
438!$ hash = MOD(hash1 + hash2, nlock) + 1
439
440 ncob = npgfb(jset)*ncoset(lb_max(jset))
441 n2 = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
442 sgfb = first_sgfb(1, jset)
443
444 ! calculate integrals and derivatives
445 SELECT CASE (nder)
446 CASE (0)
447 CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
448 lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
449 rab, sab=oint(:, :, 1))
450 CASE (1)
451 CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
452 lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
453 rab, sab=oint(:, :, 1), dab=oint(:, :, 2:4))
454 CASE (2)
455 CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
456 lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
457 rab, sab=oint(:, :, 1), dab=oint(:, :, 2:4), ddab=oint(:, :, 5:10))
458 CASE DEFAULT
459 cpabort("")
460 END SELECT
461 IF (do_forces .AND. ASSOCIATED(p_block) .AND. ((iatom /= jatom) .OR. use_virial)) THEN
462 ! Decontract P matrix block
463 owork = 0.0_dp
464 CALL block_add("OUT", owork, nsgfa(iset), nsgfb(jset), p_block, sgfa, sgfb, trans=trans)
465 CALL decontraction(owork, pmat, scon_a(:, sgfa:), n1, nsgfa(iset), scon_b(:, sgfb:), n2, &
466 nsgfb(jset), trans=trans)
467 CALL force_trace(force_a, oint(:, :, 2:4), pmat, n1, n2, 3)
468 force_thread(:, iatom) = force_thread(:, iatom) - ff*force_a(:)
469 force_thread(:, jatom) = force_thread(:, jatom) + ff*force_a(:)
470 IF (use_virial) THEN
471 CALL virial_pair_force(pv_thread, -f0, force_a, rab)
472 END IF
473 END IF
474 ! Contraction
475 DO i = 1, maxs
476 f = 1.0_dp
477 IF (ndod(i) == 1 .AND. trans) f = -1.0_dp
478 CALL contraction(oint(:, :, i), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
479 cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=f, trans=trans)
480!$ CALL omp_set_lock(locks(hash))
481 CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(i)%block, &
482 sgfa, sgfb, trans=trans)
483!$ CALL omp_unset_lock(locks(hash))
484 END DO
485
486 END DO
487 END DO
488
489 END DO
490 IF (do_forces) DEALLOCATE (pmat)
491 DEALLOCATE (oint, owork)
492 DEALLOCATE (sint)
493!$OMP DO
494!$ DO lock_num = 1, nlock
495!$ call omp_destroy_lock(locks(lock_num))
496!$ END DO
497!$OMP END DO
498
499!$OMP SINGLE
500!$ DEALLOCATE (locks)
501!$OMP END SINGLE NOWAIT
502
503!$OMP END PARALLEL
504
505 IF (do_forces) THEN
506 CALL get_atomic_kind_set(atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
507!$OMP DO
508 DO iatom = 1, natom
509 atom_a = atom_of_kind(iatom)
510 ikind = kind_of(iatom)
511 force(ikind)%overlap(:, atom_a) = force(ikind)%overlap(:, atom_a) + force_thread(:, iatom)
512 END DO
513!$OMP END DO
514 END IF
515 IF (do_forces .AND. use_virial) THEN
516 virial%pv_overlap = virial%pv_overlap + pv_thread
517 virial%pv_virial = virial%pv_virial + pv_thread
518 END IF
519
520 IF (dokp) THEN
521 DO i = 1, maxs
522 DO ic = 1, nimg
523 CALL dbcsr_finalize(matrixkp_s(i, ic)%matrix)
524 CALL dbcsr_filter(matrixkp_s(i, ic)%matrix, &
525 dft_control%qs_control%eps_filter_matrix)
526 END DO
527 END DO
528 ELSE
529 DO i = 1, maxs
530 CALL dbcsr_finalize(matrix_s(i)%matrix)
531 CALL dbcsr_filter(matrix_s(i)%matrix, &
532 dft_control%qs_control%eps_filter_matrix)
533 END DO
534 END IF
535
536 ! *** Release work storage ***
537 DEALLOCATE (basis_set_list_a, basis_set_list_b)
538
539 CALL timestop(handle)
540
541 END SUBROUTINE build_overlap_matrix_low
542
543! **************************************************************************************************
544!> \brief Calculation of the overlap matrix over Cartesian Gaussian functions.
545!> \param ks_env the QS env
546!> \param matrix_s The overlap matrix to be calculated
547!> \param basis_set_list_a basis set list to be used for bra in <a|b>
548!> \param basis_set_list_b basis set list to be used for ket in <a|b>
549!> \param sab_nl pair list (must be consistent with basis sets!)
550!> \date 11.03.2016
551!> \par History
552!> Simplified version of build_overlap_matrix
553!> \author MK
554!> \version 1.0
555! **************************************************************************************************
556 SUBROUTINE build_overlap_matrix_simple(ks_env, matrix_s, &
557 basis_set_list_a, basis_set_list_b, sab_nl)
558
559 TYPE(qs_ks_env_type), POINTER :: ks_env
560 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
561 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
562 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
563 POINTER :: sab_nl
564
565 CHARACTER(len=*), PARAMETER :: routinen = 'build_overlap_matrix_simple'
566
567 INTEGER :: handle, iatom, icol, ikind, irow, iset, &
568 jatom, jkind, jset, ldsab, m1, m2, n1, &
569 n2, natom, ncoa, ncob, nkind, nseta, &
570 nsetb, sgfa, sgfb, slot
571 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
572 npgfb, nsgfa, nsgfb
573 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
574 LOGICAL :: do_symmetric, found, trans
575 REAL(kind=dp) :: dab, rab2
576 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: owork
577 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: oint
578 REAL(kind=dp), DIMENSION(3) :: rab
579 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
580 REAL(kind=dp), DIMENSION(:, :), POINTER :: rpgfa, rpgfb, scon_a, scon_b, zeta, zetb
581 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
582 TYPE(block_p_type), ALLOCATABLE, DIMENSION(:) :: sint
583 TYPE(dft_control_type), POINTER :: dft_control
584 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
585 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
586
587!$ INTEGER(kind=omp_lock_kind), &
588!$ ALLOCATABLE, DIMENSION(:) :: locks
589!$ INTEGER :: lock_num, hash, hash1, hash2
590!$ INTEGER(KIND=int_8) :: iatom8
591!$ INTEGER, PARAMETER :: nlock = 501
592
593 NULLIFY (dft_control)
594
595 CALL timeset(routinen, handle)
596
597 NULLIFY (atomic_kind_set)
598 CALL get_ks_env(ks_env, &
599 atomic_kind_set=atomic_kind_set, &
600 natom=natom, &
601 qs_kind_set=qs_kind_set, &
602 dft_control=dft_control)
603
604 ! check for symmetry
605 cpassert(SIZE(sab_nl) > 0)
606 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
607
608 nkind = SIZE(qs_kind_set)
609
610 CALL dbcsr_allocate_matrix_set(matrix_s, 1)
611 CALL create_sab_matrix(ks_env, matrix_s, "Matrix", basis_set_list_a, basis_set_list_b, &
612 sab_nl, do_symmetric)
613
614 ldsab = 0
615 DO ikind = 1, nkind
616 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
617 CALL get_gto_basis_set(gto_basis_set=basis_set_a, maxco=m1, nsgf=m2)
618 ldsab = max(m1, m2, ldsab)
619 basis_set_b => basis_set_list_b(ikind)%gto_basis_set
620 CALL get_gto_basis_set(gto_basis_set=basis_set_b, maxco=m1, nsgf=m2)
621 ldsab = max(m1, m2, ldsab)
622 END DO
623
624!$OMP PARALLEL DEFAULT(NONE) &
625!$OMP SHARED (ldsab,sab_nl,do_symmetric,ncoset,natom,&
626!$OMP matrix_s,basis_set_list_a,basis_set_list_b,locks) &
627!$OMP PRIVATE (oint,owork,sint,ikind,jkind,iatom,jatom,rab,basis_set_a,basis_set_b,&
628!$OMP first_sgfa, la_max, la_min, npgfa, nsgfa, nseta, rpgfa, set_radius_a, ncoa, ncob, &
629!$OMP zeta, first_sgfb, lb_max, lb_min, npgfb, nsetb, rpgfb, set_radius_b, nsgfb, dab, &
630!$OMP zetb, scon_a, scon_b, irow, icol, found, trans, rab2, n1, n2, sgfa, sgfb, iset, jset, &
631!$OMP slot, lock_num, hash, hash1, hash2, iatom8 )
632
633!$OMP SINGLE
634!$ ALLOCATE (locks(nlock))
635!$OMP END SINGLE
636
637!$OMP DO
638!$ DO lock_num = 1, nlock
639!$ call omp_init_lock(locks(lock_num))
640!$ END DO
641!$OMP END DO
642
643 ALLOCATE (oint(ldsab, ldsab, 1), owork(ldsab, ldsab))
644 ALLOCATE (sint(1))
645 NULLIFY (sint(1)%block)
646
647!$OMP DO SCHEDULE(GUIDED)
648 DO slot = 1, sab_nl(1)%nl_size
649 ikind = sab_nl(1)%nlist_task(slot)%ikind
650 jkind = sab_nl(1)%nlist_task(slot)%jkind
651 iatom = sab_nl(1)%nlist_task(slot)%iatom
652 jatom = sab_nl(1)%nlist_task(slot)%jatom
653 rab(1:3) = sab_nl(1)%nlist_task(slot)%r(1:3)
654!$ iatom8 = (iatom - 1)*natom + jatom
655!$ hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
656
657 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
658 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
659 basis_set_b => basis_set_list_b(jkind)%gto_basis_set
660 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
661 ! basis ikind
662 first_sgfa => basis_set_a%first_sgf
663 la_max => basis_set_a%lmax
664 la_min => basis_set_a%lmin
665 npgfa => basis_set_a%npgf
666 nseta = basis_set_a%nset
667 nsgfa => basis_set_a%nsgf_set
668 rpgfa => basis_set_a%pgf_radius
669 set_radius_a => basis_set_a%set_radius
670 scon_a => basis_set_a%scon
671 zeta => basis_set_a%zet
672 ! basis jkind
673 first_sgfb => basis_set_b%first_sgf
674 lb_max => basis_set_b%lmax
675 lb_min => basis_set_b%lmin
676 npgfb => basis_set_b%npgf
677 nsetb = basis_set_b%nset
678 nsgfb => basis_set_b%nsgf_set
679 rpgfb => basis_set_b%pgf_radius
680 set_radius_b => basis_set_b%set_radius
681 scon_b => basis_set_b%scon
682 zetb => basis_set_b%zet
683
684 IF (do_symmetric) THEN
685 IF (iatom <= jatom) THEN
686 irow = iatom
687 icol = jatom
688 ELSE
689 irow = jatom
690 icol = iatom
691 END IF
692 ELSE
693 irow = iatom
694 icol = jatom
695 END IF
696
697 NULLIFY (sint(1)%block)
698 CALL dbcsr_get_block_p(matrix=matrix_s(1)%matrix, &
699 row=irow, col=icol, block=sint(1)%block, found=found)
700 cpassert(found)
701 trans = do_symmetric .AND. (iatom > jatom)
702
703 rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
704 dab = sqrt(rab2)
705
706 DO iset = 1, nseta
707
708 ncoa = npgfa(iset)*ncoset(la_max(iset))
709 n1 = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
710 sgfa = first_sgfa(1, iset)
711
712 DO jset = 1, nsetb
713
714 IF (set_radius_a(iset) + set_radius_b(jset) < dab) cycle
715
716!$ hash2 = MOD((iset - 1)*nsetb + jset, nlock) + 1
717!$ hash = MOD(hash1 + hash2, nlock) + 1
718
719 ncob = npgfb(jset)*ncoset(lb_max(jset))
720 n2 = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
721 sgfb = first_sgfb(1, jset)
722
723 ! calculate integrals and derivatives
724 CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
725 lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
726 rab, sab=oint(:, :, 1))
727 ! Contraction
728 CALL contraction(oint(:, :, 1), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
729 cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=1.0_dp, trans=trans)
730!$OMP CRITICAL(blockadd)
731 CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(1)%block, &
732 sgfa, sgfb, trans=trans)
733!$OMP END CRITICAL(blockadd)
734
735 END DO
736 END DO
737
738 END DO
739 DEALLOCATE (oint, owork)
740 DEALLOCATE (sint)
741!$OMP DO
742!$ DO lock_num = 1, nlock
743!$ call omp_destroy_lock(locks(lock_num))
744!$ END DO
745!$OMP END DO
746
747!$OMP SINGLE
748!$ DEALLOCATE (locks)
749!$OMP END SINGLE NOWAIT
750
751!$OMP END PARALLEL
752
753 CALL dbcsr_finalize(matrix_s(1)%matrix)
754 CALL dbcsr_filter(matrix_s(1)%matrix, dft_control%qs_control%eps_filter_matrix)
755
756 CALL timestop(handle)
757
758 END SUBROUTINE build_overlap_matrix_simple
759
760! **************************************************************************************************
761!> \brief Calculation of the force contribution from an overlap matrix
762!> over Cartesian Gaussian functions.
763!> \param ks_env the QS environment
764!> \param force holds the calcuated force Tr(P dS/dR)
765!> \param basis_type_a basis set to be used for bra in <a|b>
766!> \param basis_type_b basis set to be used for ket in <a|b>
767!> \param sab_nl pair list (must be consistent with basis sets!)
768!> \param matrix_p density matrix for force calculation
769!> \param matrixkp_p ...
770!> \date 11.03.2002
771!> \par History
772!> Enlarged functionality of this routine. Now overlap matrices based
773!> on different basis sets can be calculated, taking into account also
774!> mixed overlaps NOTE: the pointer to the overlap matrix must now be
775!> put into its corresponding env outside of this routine
776!> [Manuel Guidon]
777!> Generalized for derivatives and force calculations [JHU]
778!> This special version is only for forces [07.07.2014, JGH]
779!> \author MK/JGH
780!> \version 1.0
781! **************************************************************************************************
782 SUBROUTINE build_overlap_force(ks_env, force, basis_type_a, basis_type_b, &
783 sab_nl, matrix_p, matrixkp_p)
784
785 TYPE(qs_ks_env_type), POINTER :: ks_env
786 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: force
787 CHARACTER(LEN=*), INTENT(IN) :: basis_type_a, basis_type_b
788 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
789 POINTER :: sab_nl
790 TYPE(dbcsr_type), OPTIONAL :: matrix_p
791 TYPE(dbcsr_p_type), DIMENSION(:), OPTIONAL :: matrixkp_p
792
793 CHARACTER(len=*), PARAMETER :: routinen = 'build_overlap_force'
794
795 INTEGER :: handle, iatom, ic, icol, ikind, irow, iset, jatom, jkind, jset, ldsab, n1, n2, &
796 natom, ncoa, ncob, nder, nimg, nkind, nseta, nsetb, sgfa, sgfb, slot
797 INTEGER, DIMENSION(3) :: cell
798 INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, npgfa, &
799 npgfb, nsgfa, nsgfb
800 INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
801 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
802 LOGICAL :: do_symmetric, dokp, found, trans, &
803 use_cell_mapping, use_virial
804 REAL(kind=dp) :: dab, f0, ff, rab2
805 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: pab, sab
806 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: drab
807 REAL(kind=dp), DIMENSION(3) :: force_a, rab
808 REAL(kind=dp), DIMENSION(3, 3) :: virial_thread
809 REAL(kind=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
810 REAL(kind=dp), DIMENSION(3, SIZE(force, 2)) :: force_thread
811 REAL(kind=dp), DIMENSION(:, :), POINTER :: p_block, rpgfa, rpgfb, scon_a, scon_b, &
812 zeta, zetb
813 TYPE(dft_control_type), POINTER :: dft_control
814 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
815 TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
816 TYPE(kpoint_type), POINTER :: kpoints
817 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
818 TYPE(virial_type), POINTER :: virial
819
820 CALL timeset(routinen, handle)
821
822 NULLIFY (qs_kind_set)
823 CALL get_ks_env(ks_env=ks_env, qs_kind_set=qs_kind_set, dft_control=dft_control)
824 nimg = dft_control%nimages
825
826 ! test for matrices (kpoints or standard gamma point)
827 IF (PRESENT(matrix_p)) THEN
828 dokp = .false.
829 use_cell_mapping = .false.
830 ELSEIF (PRESENT(matrixkp_p)) THEN
831 dokp = .true.
832 CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
833 CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
834 use_cell_mapping = (SIZE(cell_to_index) > 1)
835 ELSE
836 cpabort("")
837 END IF
838
839 nkind = SIZE(qs_kind_set)
840 nder = 1
841
842 ! check for symmetry
843 cpassert(SIZE(sab_nl) > 0)
844 CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
845
846 CALL get_ks_env(ks_env=ks_env, virial=virial)
847 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
848 virial_thread = 0.0_dp
849
850 ! set up basis sets
851 ALLOCATE (basis_set_list_a(nkind), basis_set_list_b(nkind))
852 CALL basis_set_list_setup(basis_set_list_a, basis_type_a, qs_kind_set)
853 CALL basis_set_list_setup(basis_set_list_b, basis_type_b, qs_kind_set)
854 ldsab = get_memory_usage(qs_kind_set, basis_type_a, basis_type_b)
855
856 natom = SIZE(force, 2)
857 force_thread = 0.0_dp
858
859!$OMP PARALLEL DEFAULT(NONE) &
860!$OMP SHARED (ldsab, do_symmetric, ncoset, nder, use_virial, force, virial, ndod, sab_nl, cell_to_index, &
861!$OMP matrix_p, basis_set_list_a, basis_set_list_b, dokp, use_cell_mapping, nimg, matrixkp_p) &
862!$OMP PRIVATE (ikind, jkind, iatom, jatom, rab, ic, &
863!$OMP basis_set_a, basis_set_b, sab, pab, drab, &
864!$OMP first_sgfa, la_max, la_min, npgfa, nsgfa, nseta, rpgfa, set_radius_a, ncoa, ncob, force_a, &
865!$OMP zeta, first_sgfb, lb_max, lb_min, npgfb, nsetb, rpgfb, set_radius_b, nsgfb, p_block, dab, &
866!$OMP zetb, scon_a, scon_b, irow, icol, f0, ff, found, trans, rab2, n1, n2, sgfa, sgfb, iset, jset, &
867!$OMP slot, cell) &
868!$OMP REDUCTION (+ : virial_thread, force_thread )
869
870 ! *** Allocate work storage ***
871 ALLOCATE (sab(ldsab, ldsab), pab(ldsab, ldsab))
872 ALLOCATE (drab(ldsab, ldsab, 3))
873
874 ! Loop over neighbor list
875!$OMP DO SCHEDULE(GUIDED)
876 DO slot = 1, sab_nl(1)%nl_size
877 ikind = sab_nl(1)%nlist_task(slot)%ikind
878 jkind = sab_nl(1)%nlist_task(slot)%jkind
879 iatom = sab_nl(1)%nlist_task(slot)%iatom
880 jatom = sab_nl(1)%nlist_task(slot)%jatom
881 cell(:) = sab_nl(1)%nlist_task(slot)%cell(:)
882 rab(1:3) = sab_nl(1)%nlist_task(slot)%r(1:3)
883
884 basis_set_a => basis_set_list_a(ikind)%gto_basis_set
885 IF (.NOT. ASSOCIATED(basis_set_a)) cycle
886 basis_set_b => basis_set_list_b(jkind)%gto_basis_set
887 IF (.NOT. ASSOCIATED(basis_set_b)) cycle
888 ! basis ikind
889 first_sgfa => basis_set_a%first_sgf
890 la_max => basis_set_a%lmax
891 la_min => basis_set_a%lmin
892 npgfa => basis_set_a%npgf
893 nseta = basis_set_a%nset
894 nsgfa => basis_set_a%nsgf_set
895 rpgfa => basis_set_a%pgf_radius
896 set_radius_a => basis_set_a%set_radius
897 scon_a => basis_set_a%scon
898 zeta => basis_set_a%zet
899 ! basis jkind
900 first_sgfb => basis_set_b%first_sgf
901 lb_max => basis_set_b%lmax
902 lb_min => basis_set_b%lmin
903 npgfb => basis_set_b%npgf
904 nsetb = basis_set_b%nset
905 nsgfb => basis_set_b%nsgf_set
906 rpgfb => basis_set_b%pgf_radius
907 set_radius_b => basis_set_b%set_radius
908 scon_b => basis_set_b%scon
909 zetb => basis_set_b%zet
910
911 IF (use_cell_mapping) THEN
912 ic = cell_to_index(cell(1), cell(2), cell(3))
913 IF (ic < 1 .OR. ic > nimg) cycle
914 ELSE
915 ic = 1
916 END IF
917
918 IF (do_symmetric) THEN
919 IF (iatom <= jatom) THEN
920 irow = iatom
921 icol = jatom
922 ELSE
923 irow = jatom
924 icol = iatom
925 END IF
926 f0 = 2.0_dp
927 IF (iatom == jatom) f0 = 1.0_dp
928 ff = 2.0_dp
929 ELSE
930 irow = iatom
931 icol = jatom
932 f0 = 1.0_dp
933 ff = 1.0_dp
934 END IF
935 NULLIFY (p_block)
936 IF (dokp) THEN
937 CALL dbcsr_get_block_p(matrix=matrixkp_p(ic)%matrix, row=irow, col=icol, &
938 block=p_block, found=found)
939 ELSE
940 CALL dbcsr_get_block_p(matrix=matrix_p, row=irow, col=icol, &
941 block=p_block, found=found)
942 END IF
943
944 trans = do_symmetric .AND. (iatom > jatom)
945
946 rab2 = rab(1)*rab(1) + rab(2)*rab(2) + rab(3)*rab(3)
947 dab = sqrt(rab2)
948
949 DO iset = 1, nseta
950
951 ncoa = npgfa(iset)*ncoset(la_max(iset))
952 n1 = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
953 sgfa = first_sgfa(1, iset)
954
955 DO jset = 1, nsetb
956
957 IF (set_radius_a(iset) + set_radius_b(jset) < dab) cycle
958
959 ncob = npgfb(jset)*ncoset(lb_max(jset))
960 n2 = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
961 sgfb = first_sgfb(1, jset)
962
963 IF (ASSOCIATED(p_block) .AND. ((iatom /= jatom) .OR. use_virial)) THEN
964 ! Decontract P matrix block
965 sab = 0.0_dp
966 CALL block_add("OUT", sab, nsgfa(iset), nsgfb(jset), p_block, sgfa, sgfb, trans=trans)
967 CALL decontraction(sab, pab, scon_a(:, sgfa:), n1, nsgfa(iset), scon_b(:, sgfb:), n2, &
968 nsgfb(jset), trans=trans)
969 ! calculate integrals and derivatives
970 CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
971 lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
972 rab, dab=drab)
973 CALL force_trace(force_a, drab, pab, n1, n2, 3)
974 force_thread(1:3, iatom) = force_thread(1:3, iatom) - ff*force_a(1:3)
975 force_thread(1:3, jatom) = force_thread(1:3, jatom) + ff*force_a(1:3)
976 IF (use_virial) THEN
977 CALL virial_pair_force(virial_thread, -f0, force_a, rab)
978 END IF
979 END IF
980
981 END DO
982 END DO
983
984 END DO
985 DEALLOCATE (sab, pab, drab)
986!$OMP END PARALLEL
987
988!$OMP PARALLEL DEFAULT(NONE) &
989!$OMP SHARED(force,force_thread,natom)
990!$OMP WORKSHARE
991 force(1:3, 1:natom) = force(1:3, 1:natom) + force_thread(1:3, 1:natom)
992!$OMP END WORKSHARE
993!$OMP END PARALLEL
994 IF (use_virial) THEN
995 virial%pv_virial = virial%pv_virial + virial_thread
996 virial%pv_overlap = virial%pv_overlap + virial_thread
997 END IF
998
999 DEALLOCATE (basis_set_list_a, basis_set_list_b)
1000
1001 CALL timestop(handle)
1002
1003 END SUBROUTINE build_overlap_force
1004
1005! **************************************************************************************************
1006!> \brief Setup the structure of a sparse matrix based on the overlap
1007!> neighbor list
1008!> \param ks_env The QS environment
1009!> \param matrix_s Matrices to be constructed
1010!> \param matrix_name Matrix base name
1011!> \param basis_set_list_a Basis set used for <a|
1012!> \param basis_set_list_b Basis set used for |b>
1013!> \param sab_nl Overlap neighbor list
1014!> \param symmetric Is symmetry used in the neighbor list?
1015! **************************************************************************************************
1016 SUBROUTINE create_sab_matrix_1d(ks_env, matrix_s, matrix_name, &
1017 basis_set_list_a, basis_set_list_b, sab_nl, symmetric)
1018
1019 TYPE(qs_ks_env_type), POINTER :: ks_env
1020 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1021 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: matrix_name
1022 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
1023 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1024 POINTER :: sab_nl
1025 LOGICAL, INTENT(IN) :: symmetric
1026
1027 CHARACTER(LEN=12) :: cgfsym
1028 CHARACTER(LEN=32) :: symmetry_string
1029 CHARACTER(LEN=default_string_length) :: mname, name
1030 INTEGER :: i, maxs, natom
1031 INTEGER, DIMENSION(:), POINTER :: col_blk_sizes, row_blk_sizes
1032 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
1033 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1034 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1035
1036 CALL get_ks_env(ks_env=ks_env, particle_set=particle_set, &
1037 qs_kind_set=qs_kind_set, dbcsr_dist=dbcsr_dist)
1038
1039 natom = SIZE(particle_set)
1040
1041 IF (PRESENT(matrix_name)) THEN
1042 mname = matrix_name
1043 ELSE
1044 mname = "DUMMY"
1045 END IF
1046
1047 maxs = SIZE(matrix_s)
1048
1049 ALLOCATE (row_blk_sizes(natom), col_blk_sizes(natom))
1050
1051 CALL get_particle_set(particle_set, qs_kind_set, nsgf=row_blk_sizes, &
1052 basis=basis_set_list_a)
1053 CALL get_particle_set(particle_set, qs_kind_set, nsgf=col_blk_sizes, &
1054 basis=basis_set_list_b)
1055
1056 ! prepare for allocation
1057 IF (symmetric) THEN
1058 symmetry_string = dbcsr_type_symmetric
1059 ELSE
1060 symmetry_string = dbcsr_type_no_symmetry
1061 END IF
1062
1063 DO i = 1, maxs
1064 IF (symmetric) THEN
1065 IF (ndod(i) == 1) THEN
1066 ! odd derivatives are anti-symmetric
1067 symmetry_string = dbcsr_type_antisymmetric
1068 ELSE
1069 symmetry_string = dbcsr_type_symmetric
1070 END IF
1071 ELSE
1072 symmetry_string = dbcsr_type_no_symmetry
1073 END IF
1074 cgfsym = cgf_symbol(1, indco(1:3, i))
1075 IF (i == 1) THEN
1076 name = mname
1077 ELSE
1078 name = trim(cgfsym(4:))//" DERIVATIVE OF THE "//trim(mname)// &
1079 " W.R.T. THE NUCLEAR COORDINATES"
1080 END IF
1081 CALL compress(name)
1082 CALL uppercase(name)
1083 ALLOCATE (matrix_s(i)%matrix)
1084 CALL dbcsr_create(matrix=matrix_s(i)%matrix, &
1085 name=trim(name), &
1086 dist=dbcsr_dist, matrix_type=symmetry_string, &
1087 row_blk_size=row_blk_sizes, col_blk_size=col_blk_sizes, &
1088 nze=0)
1089 CALL cp_dbcsr_alloc_block_from_nbl(matrix_s(i)%matrix, sab_nl)
1090 END DO
1091
1092 DEALLOCATE (row_blk_sizes, col_blk_sizes)
1093
1094 END SUBROUTINE create_sab_matrix_1d
1095
1096! **************************************************************************************************
1097!> \brief Setup the structure of a sparse matrix based on the overlap
1098!> neighbor list, 2d version
1099!> \param ks_env The QS environment
1100!> \param matrix_s Matrices to be constructed
1101!> \param matrix_name Matrix base name
1102!> \param basis_set_list_a Basis set used for <a|
1103!> \param basis_set_list_b Basis set used for |b>
1104!> \param sab_nl Overlap neighbor list
1105!> \param symmetric Is symmetry used in the neighbor list?
1106! **************************************************************************************************
1107 SUBROUTINE create_sab_matrix_2d(ks_env, matrix_s, matrix_name, &
1108 basis_set_list_a, basis_set_list_b, sab_nl, symmetric)
1109
1110 TYPE(qs_ks_env_type), POINTER :: ks_env
1111 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
1112 CHARACTER(LEN=*), INTENT(IN), OPTIONAL :: matrix_name
1113 TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list_a, basis_set_list_b
1114 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1115 POINTER :: sab_nl
1116 LOGICAL, INTENT(IN) :: symmetric
1117
1118 CHARACTER(LEN=12) :: cgfsym
1119 CHARACTER(LEN=32) :: symmetry_string
1120 CHARACTER(LEN=default_string_length) :: mname, name
1121 INTEGER :: i1, i2, natom
1122 INTEGER, DIMENSION(:), POINTER :: col_blk_sizes, row_blk_sizes
1123 TYPE(dbcsr_distribution_type), POINTER :: dbcsr_dist
1124 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1125 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1126
1127 CALL get_ks_env(ks_env=ks_env, particle_set=particle_set, &
1128 qs_kind_set=qs_kind_set, dbcsr_dist=dbcsr_dist)
1129
1130 natom = SIZE(particle_set)
1131
1132 IF (PRESENT(matrix_name)) THEN
1133 mname = matrix_name
1134 ELSE
1135 mname = "DUMMY"
1136 END IF
1137
1138 ALLOCATE (row_blk_sizes(natom), col_blk_sizes(natom))
1139
1140 CALL get_particle_set(particle_set, qs_kind_set, nsgf=row_blk_sizes, &
1141 basis=basis_set_list_a)
1142 CALL get_particle_set(particle_set, qs_kind_set, nsgf=col_blk_sizes, &
1143 basis=basis_set_list_b)
1144
1145 ! prepare for allocation
1146 IF (symmetric) THEN
1147 symmetry_string = dbcsr_type_symmetric
1148 ELSE
1149 symmetry_string = dbcsr_type_no_symmetry
1150 END IF
1151
1152 DO i2 = 1, SIZE(matrix_s, 2)
1153 DO i1 = 1, SIZE(matrix_s, 1)
1154 IF (symmetric) THEN
1155 IF (ndod(i1) == 1) THEN
1156 ! odd derivatives are anti-symmetric
1157 symmetry_string = dbcsr_type_antisymmetric
1158 ELSE
1159 symmetry_string = dbcsr_type_symmetric
1160 END IF
1161 ELSE
1162 symmetry_string = dbcsr_type_no_symmetry
1163 END IF
1164 cgfsym = cgf_symbol(1, indco(1:3, i1))
1165 IF (i1 == 1) THEN
1166 name = mname
1167 ELSE
1168 name = trim(cgfsym(4:))//" DERIVATIVE OF THE "//trim(mname)// &
1169 " W.R.T. THE NUCLEAR COORDINATES"
1170 END IF
1171 CALL compress(name)
1172 CALL uppercase(name)
1173 ALLOCATE (matrix_s(i1, i2)%matrix)
1174 CALL dbcsr_create(matrix=matrix_s(i1, i2)%matrix, &
1175 name=trim(name), &
1176 dist=dbcsr_dist, matrix_type=symmetry_string, &
1177 row_blk_size=row_blk_sizes, col_blk_size=col_blk_sizes, &
1178 nze=0)
1179 CALL cp_dbcsr_alloc_block_from_nbl(matrix_s(i1, i2)%matrix, sab_nl)
1180 END DO
1181 END DO
1182
1183 DEALLOCATE (row_blk_sizes, col_blk_sizes)
1184
1185 END SUBROUTINE create_sab_matrix_2d
1186
1187END MODULE qs_overlap
Set of routines to: Contract integrals over primitive Gaussians Decontract (density) matrices Trace m...
Calculation of the overlap integrals over Cartesian Gaussian-type functions.
Definition ai_overlap.F:18
subroutine, public overlap_ab(la_max, la_min, npgfa, rpgfa, zeta, lb_max, lb_min, npgfb, rpgfb, zetb, rab, sab, dab, ddab)
Calculation of the two-center overlap integrals [a|b] over Cartesian Gaussian-type functions....
Definition ai_overlap.F:680
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius)
...
collect pointers to a block of reals
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
DBCSR operations in CP2K.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym)
Retrieve information from a kpoint environment.
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :), allocatable, public indco
orbital_symbols
character(len=12) function, public cgf_symbol(n, lxyz)
Build a Cartesian orbital symbol (orbital labels for printing).
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
Some utility functions for the calculation of integrals.
subroutine, public basis_set_list_setup(basis_set_list, basis_type, qs_kind_set)
Set up an easy accessible list of the basis sets for all kinds.
Define the quickstep kind type and their sub types.
subroutine, public get_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, rho, rho_xc, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, task_list, task_list_soft, kpoints, do_kpoints, atomic_kind_set, qs_kind_set, cell, cell_ref, use_ref_cell, particle_set, energy, force, local_particles, local_molecules, molecule_kind_set, molecule_set, subsys, cp_subsys, virial, results, atprop, nkind, natom, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env, nelectron_total, nelectron_spin)
...
Define the neighbor list data types and the corresponding functionality.
subroutine, public get_neighbor_list_set_p(neighbor_list_sets, nlist, symmetric)
Return the components of the first neighbor list set.
Calculation of overlap matrix, its derivatives and forces.
Definition qs_overlap.F:19
subroutine, public build_overlap_matrix(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, basis_type_a, basis_type_b, sab_nl, calculate_forces, matrix_p, matrixkp_p)
Calculation of the overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:120
subroutine, public build_overlap_force(ks_env, force, basis_type_a, basis_type_b, sab_nl, matrix_p, matrixkp_p)
Calculation of the force contribution from an overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:784
subroutine, public build_overlap_matrix_simple(ks_env, matrix_s, basis_set_list_a, basis_set_list_b, sab_nl)
Calculation of the overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:558
Utilities for string manipulations.
subroutine, public compress(string, full)
Eliminate multiple space characters in a string. If full is .TRUE., then all spaces are eliminated.
elemental subroutine, public uppercase(string)
Convert all lower case characters in a string to upper case.
pure subroutine, public virial_pair_force(pv_virial, f0, force, rab)
Computes the contribution to the stress tensor from two-body pair-wise forces.
Provides all information about an atomic kind.
Contains information about kpoints.
Provides all information about a quickstep kind.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...