(git:374b731)
Loading...
Searching...
No Matches
pao_linpot_rotinv.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 Rotationally invariant parametrization of Fock matrix.
10!> \author Ole Schuett
11! **************************************************************************************************
13 USE ai_overlap, ONLY: overlap_aab
16 USE cell_types, ONLY: cell_type,&
17 pbc
18 USE kinds, ONLY: dp
19 USE mathconstants, ONLY: gamma1
20 USE mathlib, ONLY: multinomial
21 USE orbital_pointers, ONLY: indco,&
22 ncoset
26 USE qs_kind_types, ONLY: get_qs_kind,&
29#include "./base/base_uses.f90"
30
31 IMPLICIT NONE
32
33 PRIVATE
34
35 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_linpot_rotinv'
36
38
39CONTAINS
40
41! **************************************************************************************************
42!> \brief Count number of terms for given atomic kind
43!> \param qs_env ...
44!> \param ikind ...
45!> \param nterms ...
46! **************************************************************************************************
47 SUBROUTINE linpot_rotinv_count_terms(qs_env, ikind, nterms)
48 TYPE(qs_environment_type), POINTER :: qs_env
49 INTEGER, INTENT(IN) :: ikind
50 INTEGER, INTENT(OUT) :: nterms
51
52 CHARACTER(len=*), PARAMETER :: routinen = 'linpot_rotinv_count_terms'
53
54 INTEGER :: handle, ipot, iset, ishell, ishell_abs, &
55 lmax, lmin, lpot, max_shell, &
56 min_shell, npots, nshells, pot_maxl
57 INTEGER, ALLOCATABLE, DIMENSION(:) :: shell_l
58 TYPE(gto_basis_set_type), POINTER :: basis_set
59 TYPE(pao_potential_type), DIMENSION(:), POINTER :: pao_potentials
60 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
61
62 CALL timeset(routinen, handle)
63
64 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
65 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_potentials=pao_potentials)
66
67 nshells = sum(basis_set%nshell)
68 npots = SIZE(pao_potentials)
69
70 IF (npots == 0) cpwarn("Found no PAO_POTENTIAL section")
71
72 ! fill shell_l
73 ALLOCATE (shell_l(nshells))
74 DO iset = 1, basis_set%nset
75 DO ishell = 1, basis_set%nshell(iset)
76 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
77 shell_l(ishell_abs) = basis_set%l(ishell, iset)
78 END DO
79 END DO
80
81 nterms = 0
82
83 ! terms sensing neighboring atoms
84 DO ipot = 1, npots
85 pot_maxl = pao_potentials(ipot)%maxl ! maxl is taken from central atom
86 IF (pot_maxl < 0) &
87 cpabort("ROTINV parametrization requires non-negative PAO_POTENTIAL%MAXL")
88 IF (mod(pot_maxl, 2) /= 0) &
89 cpabort("ROTINV parametrization requires even-numbered PAO_POTENTIAL%MAXL")
90 DO max_shell = 1, nshells
91 DO min_shell = 1, max_shell
92 DO lpot = 0, pot_maxl, 2
93 lmin = shell_l(min_shell)
94 lmax = shell_l(max_shell)
95 IF (lmin == 0 .AND. lmax == 0) cycle ! covered by central terms
96 nterms = nterms + 1
97 END DO
98 END DO
99 END DO
100 END DO
101
102 ! spherical symmetric terms on central atom
103 DO max_shell = 1, nshells
104 DO min_shell = 1, max_shell
105 IF (shell_l(min_shell) /= shell_l(max_shell)) cycle ! need quadratic block
106 nterms = nterms + 1
107 END DO
108 END DO
109
110 CALL timestop(handle)
111
112 END SUBROUTINE linpot_rotinv_count_terms
113
114! **************************************************************************************************
115!> \brief Calculate all potential terms of the rotinv parametrization
116!> \param qs_env ...
117!> \param iatom ...
118!> \param V_blocks ...
119! **************************************************************************************************
120 SUBROUTINE linpot_rotinv_calc_terms(qs_env, iatom, V_blocks)
121 TYPE(qs_environment_type), POINTER :: qs_env
122 INTEGER, INTENT(IN) :: iatom
123 REAL(dp), DIMENSION(:, :, :), INTENT(OUT), TARGET :: v_blocks
124
125 CHARACTER(len=*), PARAMETER :: routinen = 'linpot_rotinv_calc_terms'
126
127 INTEGER :: handle, i, ic, ikind, ipot, iset, ishell, ishell_abs, jatom, jkind, jset, jshell, &
128 jshell_abs, kterm, la1_max, la1_min, la2_max, la2_min, lb_max, lb_min, lpot, n, na1, na2, &
129 natoms, nb, ncfga1, ncfga2, ncfgb, npgfa1, npgfa2, npgfb, npots, pot_maxl, sgfa1, sgfa2, &
130 sgla1, sgla2
131 REAL(dp) :: coeff, norm2, pot_beta, pot_weight, &
132 rpgfa_max, tab
133 REAL(dp), DIMENSION(3) :: ra, rab, rb
134 REAL(dp), DIMENSION(:), POINTER :: rpgfa1, rpgfa2, rpgfb, zeta1, zeta2, zetb
135 REAL(dp), DIMENSION(:, :), POINTER :: t1, t2, v12, v21
136 REAL(dp), DIMENSION(:, :, :), POINTER :: block_v_full, saab, saal
137 TYPE(cell_type), POINTER :: cell
138 TYPE(gto_basis_set_type), POINTER :: basis_set
139 TYPE(pao_potential_type), DIMENSION(:), POINTER :: ipao_potentials, jpao_potentials
140 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
141 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
142
143 CALL timeset(routinen, handle)
144
145 CALL get_qs_env(qs_env, &
146 natom=natoms, &
147 cell=cell, &
148 particle_set=particle_set, &
149 qs_kind_set=qs_kind_set)
150
151 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
152 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_potentials=ipao_potentials)
153 npots = SIZE(ipao_potentials)
154 n = basis_set%nsgf ! primary basis-size
155 cpassert(SIZE(v_blocks, 1) == n .AND. SIZE(v_blocks, 2) == n)
156 kterm = 0 ! init counter
157
158 DO ipot = 1, npots
159 pot_maxl = ipao_potentials(ipot)%maxl ! taken from central atom
160
161 ! setup description of potential
162 lb_min = 0
163 lb_max = pot_maxl
164 ncfgb = ncoset(lb_max) - ncoset(lb_min - 1)
165 npgfb = 1 ! number of exponents
166 nb = npgfb*ncfgb
167 ALLOCATE (rpgfb(npgfb), zetb(npgfb))
168
169 ! build block_V_full
170 ALLOCATE (block_v_full(n, n, pot_maxl/2 + 1))
171 block_v_full = 0.0_dp
172
173 DO iset = 1, basis_set%nset
174 DO jset = 1, iset
175
176 ! setup iset
177 la1_max = basis_set%lmax(iset)
178 la1_min = basis_set%lmin(iset)
179 npgfa1 = basis_set%npgf(iset)
180 ncfga1 = ncoset(la1_max) - ncoset(la1_min - 1)
181 na1 = npgfa1*ncfga1
182 zeta1 => basis_set%zet(:, iset)
183 rpgfa1 => basis_set%pgf_radius(:, iset)
184
185 ! setup jset
186 la2_max = basis_set%lmax(jset)
187 la2_min = basis_set%lmin(jset)
188 npgfa2 = basis_set%npgf(jset)
189 ncfga2 = ncoset(la2_max) - ncoset(la2_min - 1)
190 na2 = npgfa2*ncfga2
191 zeta2 => basis_set%zet(:, jset)
192 rpgfa2 => basis_set%pgf_radius(:, jset)
193
194 ! radius of most diffuse basis-function
195 rpgfa_max = max(maxval(rpgfa1), maxval(rpgfa2))
196
197 ! allocate space for integrals
198 ALLOCATE (saab(na1, na2, nb), saal(na1, na2, pot_maxl/2 + 1))
199 saal = 0.0_dp
200
201 ! loop over neighbors
202 DO jatom = 1, natoms
203 IF (jatom == iatom) cycle ! no self-interaction
204 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
205 CALL get_qs_kind(qs_kind_set(jkind), pao_potentials=jpao_potentials)
206 IF (SIZE(jpao_potentials) /= npots) &
207 cpabort("Not all KINDs have the same number of PAO_POTENTIAL sections")
208
209 ! initialize exponents
210 pot_weight = jpao_potentials(ipot)%weight ! taken from remote atom
211 pot_beta = jpao_potentials(ipot)%beta ! taken from remote atom
212 rpgfb(1) = jpao_potentials(ipot)%beta_radius ! taken from remote atom
213 zetb(1) = pot_beta
214
215 ! calculate direction
216 ra = particle_set(iatom)%r
217 rb = particle_set(jatom)%r
218 rab = pbc(ra, rb, cell)
219
220 ! distance screening
221 tab = sqrt(sum(rab**2))
222 IF (rpgfa_max + rpgfb(1) < tab) cycle
223
224 ! calculate actual integrals
225 saab = 0.0_dp
226 CALL overlap_aab(la1_max=la1_max, la1_min=la1_min, npgfa1=npgfa1, rpgfa1=rpgfa1, zeta1=zeta1, &
227 la2_max=la2_max, la2_min=la2_min, npgfa2=npgfa2, rpgfa2=rpgfa2, zeta2=zeta2, &
228 lb_max=lb_max, lb_min=lb_min, npgfb=npgfb, rpgfb=rpgfb, zetb=zetb, &
229 rab=rab, saab=saab)
230
231 ! sum neighbor contributions according to remote atom's weight and normalization
232 DO lpot = 0, pot_maxl, 2
233 norm2 = (2.0_dp*pot_beta)**(-0.5_dp - lpot)*gamma1(lpot)
234 ! sum potential terms: POW(x**2 + y**2 + z**2, lpot/2)
235 DO ic = ncoset(lpot - 1) + 1, ncoset(lpot)
236 coeff = multinomial(lpot/2, indco(:, ic)/2)
237 saal(:, :, lpot/2 + 1) = saal(:, :, lpot/2 + 1) + saab(:, :, ic)*coeff*pot_weight/sqrt(norm2)
238 END DO
239 END DO
240 END DO ! jatom
241
242 ! find bounds of set-pair and setup transformation matrices
243 sgfa1 = basis_set%first_sgf(1, iset)
244 sgla1 = sgfa1 + basis_set%nsgf_set(iset) - 1
245 sgfa2 = basis_set%first_sgf(1, jset)
246 sgla2 = sgfa2 + basis_set%nsgf_set(jset) - 1
247 t1 => basis_set%scon(1:na1, sgfa1:sgla1)
248 t2 => basis_set%scon(1:na2, sgfa2:sgla2)
249
250 ! transform into primary basis
251 DO lpot = 0, pot_maxl, 2
252 v12 => block_v_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1)
253 v21 => block_v_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1)
254 v12 = matmul(transpose(t1), matmul(saal(:, :, lpot/2 + 1), t2))
255 v21 = transpose(v12)
256 END DO
257 DEALLOCATE (saab, saal)
258 END DO ! jset
259 END DO ! iset
260 DEALLOCATE (rpgfb, zetb)
261
262 ! block_V_full is ready -------------------------------------------------------------------
263 ! split the full blocks into shell-pair sub-blocks
264 DO iset = 1, basis_set%nset
265 DO jset = 1, iset
266 DO ishell = 1, basis_set%nshell(iset)
267 DO jshell = 1, basis_set%nshell(jset)
268 IF (basis_set%l(ishell, iset) == 0 .AND. basis_set%l(jshell, jset) == 0) cycle ! covered by central terms
269 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
270 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
271 IF (ishell_abs < jshell_abs) cycle
272
273 ! find bounds of shell-pair
274 sgfa1 = basis_set%first_sgf(ishell, iset)
275 sgla1 = basis_set%last_sgf(ishell, iset)
276 sgfa2 = basis_set%first_sgf(jshell, jset)
277 sgla2 = basis_set%last_sgf(jshell, jset)
278
279 DO lpot = 0, pot_maxl, 2
280 kterm = kterm + 1
281 v_blocks(:, :, kterm) = 0.0_dp
282 v_blocks(sgfa1:sgla1, sgfa2:sgla2, kterm) = block_v_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1)
283 v_blocks(sgfa2:sgla2, sgfa1:sgla1, kterm) = block_v_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1)
284 END DO ! lpot
285 END DO ! jshell
286 END DO ! ishell
287 END DO ! jset
288 END DO ! iset
289 DEALLOCATE (block_v_full)
290 END DO ! ipot
291
292 ! terms on central atom ----------------------------------------------------------------------
293
294 DO iset = 1, basis_set%nset
295 DO jset = 1, iset
296 DO ishell = 1, basis_set%nshell(iset)
297 DO jshell = 1, basis_set%nshell(jset)
298 IF (basis_set%l(ishell, iset) /= basis_set%l(jshell, jset)) cycle ! need quadratic block
299 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
300 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
301 IF (ishell_abs < jshell_abs) cycle
302 kterm = kterm + 1
303 sgfa1 = basis_set%first_sgf(ishell, iset)
304 sgla1 = basis_set%last_sgf(ishell, iset)
305 sgfa2 = basis_set%first_sgf(jshell, jset)
306 sgla2 = basis_set%last_sgf(jshell, jset)
307 cpassert((sgla1 - sgfa1) == (sgla2 - sgfa2)) ! should be a quadratic block
308 v_blocks(:, :, kterm) = 0.0_dp
309 DO i = 1, sgla1 - sgfa1 + 1 ! set diagonal of sub-block
310 v_blocks(sgfa1 - 1 + i, sgfa2 - 1 + i, kterm) = 1.0_dp
311 v_blocks(sgfa2 - 1 + i, sgfa1 - 1 + i, kterm) = 1.0_dp
312 END DO
313 norm2 = sum(v_blocks(:, :, kterm)**2)
314 v_blocks(:, :, kterm) = v_blocks(:, :, kterm)/sqrt(norm2) ! normalize
315 END DO ! jshell
316 END DO ! ishell
317 END DO ! jset
318 END DO ! iset
319
320 cpassert(SIZE(v_blocks, 3) == kterm) ! ensure we generated all terms
321
322 CALL timestop(handle)
323 END SUBROUTINE linpot_rotinv_calc_terms
324
325! **************************************************************************************************
326!> \brief Calculate force contribution from rotinv parametrization
327!> \param qs_env ...
328!> \param iatom ...
329!> \param M_blocks ...
330!> \param forces ...
331! **************************************************************************************************
332 SUBROUTINE linpot_rotinv_calc_forces(qs_env, iatom, M_blocks, forces)
333 TYPE(qs_environment_type), POINTER :: qs_env
334 INTEGER, INTENT(IN) :: iatom
335 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: m_blocks
336 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: forces
337
338 CHARACTER(len=*), PARAMETER :: routinen = 'linpot_rotinv_calc_forces'
339
340 INTEGER :: handle, i, ic, ikind, ipot, iset, ishell, ishell_abs, jatom, jkind, jset, jshell, &
341 jshell_abs, kterm, la1_max, la1_min, la2_max, la2_min, lb_max, lb_min, lpot, n, na1, na2, &
342 natoms, nb, ncfga1, ncfga2, ncfgb, npgfa1, npgfa2, npgfb, npots, nshells, pot_maxl, &
343 sgfa1, sgfa2, sgla1, sgla2
344 REAL(dp) :: coeff, f, norm2, pot_beta, pot_weight, &
345 rpgfa_max, tab
346 REAL(dp), DIMENSION(3) :: ra, rab, rb
347 REAL(dp), DIMENSION(:), POINTER :: rpgfa1, rpgfa2, rpgfb, zeta1, zeta2, zetb
348 REAL(dp), DIMENSION(:, :), POINTER :: block_d, t1, t2
349 REAL(dp), DIMENSION(:, :, :), POINTER :: block_m_full, dab
350 REAL(dp), DIMENSION(:, :, :, :), POINTER :: daab
351 TYPE(cell_type), POINTER :: cell
352 TYPE(gto_basis_set_type), POINTER :: basis_set
353 TYPE(pao_potential_type), DIMENSION(:), POINTER :: ipao_potentials, jpao_potentials
354 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
355 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
356
357 CALL timeset(routinen, handle)
358
359 CALL get_qs_env(qs_env, &
360 natom=natoms, &
361 cell=cell, &
362 particle_set=particle_set, &
363 qs_kind_set=qs_kind_set)
364
365 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
366 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_potentials=ipao_potentials)
367 npots = SIZE(ipao_potentials)
368 nshells = sum(basis_set%nshell)
369 n = basis_set%nsgf ! primary basis-size
370 cpassert(SIZE(m_blocks, 1) == n .AND. SIZE(m_blocks, 2) == n)
371 kterm = 0 ! init counter
372 ALLOCATE (block_d(n, n))
373
374 DO ipot = 1, npots
375 pot_maxl = ipao_potentials(ipot)%maxl ! taken from central atom
376
377 ! build block_M_full
378 ALLOCATE (block_m_full(n, n, pot_maxl/2 + 1))
379 block_m_full = 0.0_dp
380 DO iset = 1, basis_set%nset
381 DO jset = 1, iset
382 DO ishell = 1, basis_set%nshell(iset)
383 DO jshell = 1, basis_set%nshell(jset)
384 IF (basis_set%l(ishell, iset) == 0 .AND. basis_set%l(jshell, jset) == 0) cycle ! covered by central terms
385 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
386 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
387 IF (ishell_abs < jshell_abs) cycle
388 ! find bounds of shell-pair
389 sgfa1 = basis_set%first_sgf(ishell, iset)
390 sgla1 = basis_set%last_sgf(ishell, iset)
391 sgfa2 = basis_set%first_sgf(jshell, jset)
392 sgla2 = basis_set%last_sgf(jshell, jset)
393 DO lpot = 0, pot_maxl, 2
394 kterm = kterm + 1
395 block_m_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1) = m_blocks(sgfa1:sgla1, sgfa2:sgla2, kterm)
396 block_m_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1) = m_blocks(sgfa2:sgla2, sgfa1:sgla1, kterm)
397 END DO ! lpot
398 END DO ! jshell
399 END DO ! ishell
400 END DO ! jset
401 END DO ! iset
402
403 ! setup description of potential
404 lb_min = 0
405 lb_max = pot_maxl
406 ncfgb = ncoset(lb_max) - ncoset(lb_min - 1)
407 npgfb = 1 ! number of exponents
408 nb = npgfb*ncfgb
409 ALLOCATE (rpgfb(npgfb), zetb(npgfb))
410
411 DO iset = 1, basis_set%nset
412 DO jset = 1, iset
413
414 ! setup iset
415 la1_max = basis_set%lmax(iset)
416 la1_min = basis_set%lmin(iset)
417 npgfa1 = basis_set%npgf(iset)
418 ncfga1 = ncoset(la1_max) - ncoset(la1_min - 1)
419 na1 = npgfa1*ncfga1
420 zeta1 => basis_set%zet(:, iset)
421 rpgfa1 => basis_set%pgf_radius(:, iset)
422
423 ! setup jset
424 la2_max = basis_set%lmax(jset)
425 la2_min = basis_set%lmin(jset)
426 npgfa2 = basis_set%npgf(jset)
427 ncfga2 = ncoset(la2_max) - ncoset(la2_min - 1)
428 na2 = npgfa2*ncfga2
429 zeta2 => basis_set%zet(:, jset)
430 rpgfa2 => basis_set%pgf_radius(:, jset)
431
432 ! radius of most diffuse basis-function
433 rpgfa_max = max(maxval(rpgfa1), maxval(rpgfa2))
434
435 ! find bounds of set-pair and setup transformation matrices
436 sgfa1 = basis_set%first_sgf(1, iset)
437 sgla1 = sgfa1 + basis_set%nsgf_set(iset) - 1
438 sgfa2 = basis_set%first_sgf(1, jset)
439 sgla2 = sgfa2 + basis_set%nsgf_set(jset) - 1
440 t1 => basis_set%scon(1:na1, sgfa1:sgla1)
441 t2 => basis_set%scon(1:na2, sgfa2:sgla2)
442
443 ! allocate space for integrals
444 ALLOCATE (daab(na1, na2, nb, 3), dab(na1, na2, 3))
445
446 ! loop over neighbors
447 DO jatom = 1, natoms
448 IF (jatom == iatom) cycle ! no self-interaction
449 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
450 CALL get_qs_kind(qs_kind_set(jkind), pao_potentials=jpao_potentials)
451 IF (SIZE(jpao_potentials) /= npots) &
452 cpabort("Not all KINDs have the same number of PAO_POTENTIAL sections")
453
454 ! initialize exponents
455 pot_weight = jpao_potentials(ipot)%weight ! taken from remote atom
456 pot_beta = jpao_potentials(ipot)%beta ! taken from remote atom
457 rpgfb(1) = jpao_potentials(ipot)%beta_radius ! taken from remote atom
458 zetb(1) = pot_beta
459
460 ! calculate direction
461 ra = particle_set(iatom)%r
462 rb = particle_set(jatom)%r
463 rab = pbc(ra, rb, cell)
464
465 ! distance screening
466 tab = sqrt(sum(rab**2))
467 IF (rpgfa_max + rpgfb(1) < tab) cycle
468
469 ! calculate actual integrals
470 daab = 0.0_dp
471 CALL overlap_aab(la1_max=la1_max, la1_min=la1_min, npgfa1=npgfa1, rpgfa1=rpgfa1, zeta1=zeta1, &
472 la2_max=la2_max, la2_min=la2_min, npgfa2=npgfa2, rpgfa2=rpgfa2, zeta2=zeta2, &
473 lb_max=lb_max, lb_min=lb_min, npgfb=npgfb, rpgfb=rpgfb, zetb=zetb, &
474 rab=rab, daab=daab)
475
476 ! sum neighbor contributions according to remote atom's weight and normalization
477 DO lpot = 0, pot_maxl, 2
478 ! sum potential terms: POW(x**2 + y**2 + z**2, lpot/2)
479 dab = 0.0_dp
480 DO ic = ncoset(lpot - 1) + 1, ncoset(lpot)
481 norm2 = (2.0_dp*pot_beta)**(-0.5_dp - lpot)*gamma1(lpot)
482 coeff = multinomial(lpot/2, indco(:, ic)/2)
483 dab = dab + coeff*daab(:, :, ic, :)*pot_weight/sqrt(norm2)
484 END DO
485 DO i = 1, 3
486 ! transform into primary basis
487 block_d = 0.0_dp
488 block_d(sgfa1:sgla1, sgfa2:sgla2) = matmul(transpose(t1), matmul(dab(:, :, i), t2))
489 block_d(sgfa2:sgla2, sgfa1:sgla1) = transpose(block_d(sgfa1:sgla1, sgfa2:sgla2))
490 ! calculate and add forces
491 f = sum(block_m_full(:, :, lpot/2 + 1)*block_d)
492 forces(iatom, i) = forces(iatom, i) - f
493 forces(jatom, i) = forces(jatom, i) + f
494 END DO
495 END DO ! lpot
496 END DO ! jatom
497 DEALLOCATE (dab, daab)
498 END DO ! jset
499 END DO ! iset
500 DEALLOCATE (rpgfb, zetb, block_m_full)
501 END DO ! ipot
502 DEALLOCATE (block_d)
503
504 CALL timestop(handle)
505 END SUBROUTINE linpot_rotinv_calc_forces
506
507END MODULE pao_linpot_rotinv
Calculation of the overlap integrals over Cartesian Gaussian-type functions.
Definition ai_overlap.F:18
subroutine, public overlap_aab(la1_max, la1_min, npgfa1, rpgfa1, zeta1, la2_max, la2_min, npgfa2, rpgfa2, zeta2, lb_max, lb_min, npgfb, rpgfb, zetb, rab, saab, daab, saba, daba)
Calculation of the two-center overlap integrals [aa|b] over Cartesian Gaussian-type functions.
Definition ai_overlap.F:967
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
real(kind=dp), dimension(0:maxfac), parameter, public gamma1
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
pure real(kind=dp) function, public multinomial(n, k)
Calculates the multinomial coefficients.
Definition mathlib.F:254
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :), allocatable, public indco
Rotationally invariant parametrization of Fock matrix.
subroutine, public linpot_rotinv_calc_forces(qs_env, iatom, m_blocks, forces)
Calculate force contribution from rotinv parametrization.
subroutine, public linpot_rotinv_calc_terms(qs_env, iatom, v_blocks)
Calculate all potential terms of the rotinv parametrization.
subroutine, public linpot_rotinv_count_terms(qs_env, ikind, nterms)
Count number of terms for given atomic kind.
Factory routines for potentials used e.g. by pao_param_exp and pao_ml.
Define the data structure for the particle information.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_r3d_rs_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:55
Holds information about a PAO potential.
Provides all information about a quickstep kind.