(git:15c7cac)
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-2026 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 cpwarn_if(npots == 0, "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) THEN
87 cpabort("ROTINV parametrization requires non-negative PAO_POTENTIAL%MAXL")
88 END IF
89 IF (mod(pot_maxl, 2) /= 0) THEN
90 cpabort("ROTINV parametrization requires even-numbered PAO_POTENTIAL%MAXL")
91 END IF
92 DO max_shell = 1, nshells
93 DO min_shell = 1, max_shell
94 DO lpot = 0, pot_maxl, 2
95 lmin = shell_l(min_shell)
96 lmax = shell_l(max_shell)
97 IF (lmin == 0 .AND. lmax == 0) cycle ! covered by central terms
98 nterms = nterms + 1
99 END DO
100 END DO
101 END DO
102 END DO
103
104 ! spherical symmetric terms on central atom
105 DO max_shell = 1, nshells
106 DO min_shell = 1, max_shell
107 IF (shell_l(min_shell) /= shell_l(max_shell)) cycle ! need quadratic block
108 nterms = nterms + 1
109 END DO
110 END DO
111
112 CALL timestop(handle)
113
114 END SUBROUTINE linpot_rotinv_count_terms
115
116! **************************************************************************************************
117!> \brief Calculate all potential terms of the rotinv parametrization
118!> \param qs_env ...
119!> \param iatom ...
120!> \param V_blocks ...
121! **************************************************************************************************
122 SUBROUTINE linpot_rotinv_calc_terms(qs_env, iatom, V_blocks)
123 TYPE(qs_environment_type), POINTER :: qs_env
124 INTEGER, INTENT(IN) :: iatom
125 REAL(dp), DIMENSION(:, :, :), INTENT(OUT), TARGET :: v_blocks
126
127 CHARACTER(len=*), PARAMETER :: routinen = 'linpot_rotinv_calc_terms'
128
129 INTEGER :: handle, i, ic, ikind, ipot, iset, ishell, ishell_abs, jatom, jkind, jset, jshell, &
130 jshell_abs, kterm, la1_max, la1_min, la2_max, la2_min, lb_max, lb_min, lpot, n, na1, na2, &
131 natoms, nb, ncfga1, ncfga2, ncfgb, npgfa1, npgfa2, npgfb, npots, pot_maxl, sgfa1, sgfa2, &
132 sgla1, sgla2
133 REAL(dp) :: coeff, norm2, pot_beta, pot_weight, &
134 rpgfa_max, tab
135 REAL(dp), DIMENSION(3) :: ra, rab, rb
136 REAL(dp), DIMENSION(:), POINTER :: rpgfa1, rpgfa2, rpgfb, zeta1, zeta2, zetb
137 REAL(dp), DIMENSION(:, :), POINTER :: t1, t2, v12, v21
138 REAL(dp), DIMENSION(:, :, :), POINTER :: block_v_full, saab, saal
139 TYPE(cell_type), POINTER :: cell
140 TYPE(gto_basis_set_type), POINTER :: basis_set
141 TYPE(pao_potential_type), DIMENSION(:), POINTER :: ipao_potentials, jpao_potentials
142 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
143 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
144
145 CALL timeset(routinen, handle)
146
147 CALL get_qs_env(qs_env, &
148 natom=natoms, &
149 cell=cell, &
150 particle_set=particle_set, &
151 qs_kind_set=qs_kind_set)
152
153 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
154 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_potentials=ipao_potentials)
155 npots = SIZE(ipao_potentials)
156 n = basis_set%nsgf ! primary basis-size
157 cpassert(SIZE(v_blocks, 1) == n .AND. SIZE(v_blocks, 2) == n)
158 kterm = 0 ! init counter
159
160 DO ipot = 1, npots
161 pot_maxl = ipao_potentials(ipot)%maxl ! taken from central atom
162
163 ! setup description of potential
164 lb_min = 0
165 lb_max = pot_maxl
166 ncfgb = ncoset(lb_max) - ncoset(lb_min - 1)
167 npgfb = 1 ! number of exponents
168 nb = npgfb*ncfgb
169 ALLOCATE (rpgfb(npgfb), zetb(npgfb))
170
171 ! build block_V_full
172 ALLOCATE (block_v_full(n, n, pot_maxl/2 + 1))
173 block_v_full = 0.0_dp
174
175 DO iset = 1, basis_set%nset
176 DO jset = 1, iset
177
178 ! setup iset
179 la1_max = basis_set%lmax(iset)
180 la1_min = basis_set%lmin(iset)
181 npgfa1 = basis_set%npgf(iset)
182 ncfga1 = ncoset(la1_max) - ncoset(la1_min - 1)
183 na1 = npgfa1*ncfga1
184 zeta1 => basis_set%zet(:, iset)
185 rpgfa1 => basis_set%pgf_radius(:, iset)
186
187 ! setup jset
188 la2_max = basis_set%lmax(jset)
189 la2_min = basis_set%lmin(jset)
190 npgfa2 = basis_set%npgf(jset)
191 ncfga2 = ncoset(la2_max) - ncoset(la2_min - 1)
192 na2 = npgfa2*ncfga2
193 zeta2 => basis_set%zet(:, jset)
194 rpgfa2 => basis_set%pgf_radius(:, jset)
195
196 ! radius of most diffuse basis-function
197 rpgfa_max = max(maxval(rpgfa1), maxval(rpgfa2))
198
199 ! allocate space for integrals
200 ALLOCATE (saab(na1, na2, nb), saal(na1, na2, pot_maxl/2 + 1))
201 saal = 0.0_dp
202
203 ! loop over neighbors
204 DO jatom = 1, natoms
205 IF (jatom == iatom) cycle ! no self-interaction
206 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
207 CALL get_qs_kind(qs_kind_set(jkind), pao_potentials=jpao_potentials)
208 IF (SIZE(jpao_potentials) /= npots) THEN
209 cpabort("Not all KINDs have the same number of PAO_POTENTIAL sections")
210 END IF
211
212 ! initialize exponents
213 pot_weight = jpao_potentials(ipot)%weight ! taken from remote atom
214 pot_beta = jpao_potentials(ipot)%beta ! taken from remote atom
215 rpgfb(1) = jpao_potentials(ipot)%beta_radius ! taken from remote atom
216 zetb(1) = pot_beta
217
218 ! calculate direction
219 ra = particle_set(iatom)%r
220 rb = particle_set(jatom)%r
221 rab = pbc(ra, rb, cell)
222
223 ! distance screening
224 tab = sqrt(sum(rab**2))
225 IF (rpgfa_max + rpgfb(1) < tab) cycle
226
227 ! calculate actual integrals
228 saab = 0.0_dp
229 CALL overlap_aab(la1_max=la1_max, la1_min=la1_min, npgfa1=npgfa1, rpgfa1=rpgfa1, zeta1=zeta1, &
230 la2_max=la2_max, la2_min=la2_min, npgfa2=npgfa2, rpgfa2=rpgfa2, zeta2=zeta2, &
231 lb_max=lb_max, lb_min=lb_min, npgfb=npgfb, rpgfb=rpgfb, zetb=zetb, &
232 rab=rab, saab=saab)
233
234 ! sum neighbor contributions according to remote atom's weight and normalization
235 DO lpot = 0, pot_maxl, 2
236 norm2 = (2.0_dp*pot_beta)**(-0.5_dp - lpot)*gamma1(lpot)
237 ! sum potential terms: POW(x**2 + y**2 + z**2, lpot/2)
238 DO ic = ncoset(lpot - 1) + 1, ncoset(lpot)
239 coeff = multinomial(lpot/2, indco(:, ic)/2)
240 saal(:, :, lpot/2 + 1) = saal(:, :, lpot/2 + 1) + saab(:, :, ic)*coeff*pot_weight/sqrt(norm2)
241 END DO
242 END DO
243 END DO ! jatom
244
245 ! find bounds of set-pair and setup transformation matrices
246 sgfa1 = basis_set%first_sgf(1, iset)
247 sgla1 = sgfa1 + basis_set%nsgf_set(iset) - 1
248 sgfa2 = basis_set%first_sgf(1, jset)
249 sgla2 = sgfa2 + basis_set%nsgf_set(jset) - 1
250 t1 => basis_set%scon(1:na1, sgfa1:sgla1)
251 t2 => basis_set%scon(1:na2, sgfa2:sgla2)
252
253 ! transform into primary basis
254 DO lpot = 0, pot_maxl, 2
255 v12 => block_v_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1)
256 v21 => block_v_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1)
257 v12 = matmul(transpose(t1), matmul(saal(:, :, lpot/2 + 1), t2))
258 v21 = transpose(v12)
259 END DO
260 DEALLOCATE (saab, saal)
261 END DO ! jset
262 END DO ! iset
263 DEALLOCATE (rpgfb, zetb)
264
265 ! block_V_full is ready -------------------------------------------------------------------
266 ! split the full blocks into shell-pair sub-blocks
267 DO iset = 1, basis_set%nset
268 DO jset = 1, iset
269 DO ishell = 1, basis_set%nshell(iset)
270 DO jshell = 1, basis_set%nshell(jset)
271 IF (basis_set%l(ishell, iset) == 0 .AND. basis_set%l(jshell, jset) == 0) cycle ! covered by central terms
272 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
273 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
274 IF (ishell_abs < jshell_abs) cycle
275
276 ! find bounds of shell-pair
277 sgfa1 = basis_set%first_sgf(ishell, iset)
278 sgla1 = basis_set%last_sgf(ishell, iset)
279 sgfa2 = basis_set%first_sgf(jshell, jset)
280 sgla2 = basis_set%last_sgf(jshell, jset)
281
282 DO lpot = 0, pot_maxl, 2
283 kterm = kterm + 1
284 v_blocks(:, :, kterm) = 0.0_dp
285 v_blocks(sgfa1:sgla1, sgfa2:sgla2, kterm) = block_v_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1)
286 v_blocks(sgfa2:sgla2, sgfa1:sgla1, kterm) = block_v_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1)
287 END DO ! lpot
288 END DO ! jshell
289 END DO ! ishell
290 END DO ! jset
291 END DO ! iset
292 DEALLOCATE (block_v_full)
293 END DO ! ipot
294
295 ! terms on central atom ----------------------------------------------------------------------
296
297 DO iset = 1, basis_set%nset
298 DO jset = 1, iset
299 DO ishell = 1, basis_set%nshell(iset)
300 DO jshell = 1, basis_set%nshell(jset)
301 IF (basis_set%l(ishell, iset) /= basis_set%l(jshell, jset)) cycle ! need quadratic block
302 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
303 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
304 IF (ishell_abs < jshell_abs) cycle
305 kterm = kterm + 1
306 sgfa1 = basis_set%first_sgf(ishell, iset)
307 sgla1 = basis_set%last_sgf(ishell, iset)
308 sgfa2 = basis_set%first_sgf(jshell, jset)
309 sgla2 = basis_set%last_sgf(jshell, jset)
310 cpassert((sgla1 - sgfa1) == (sgla2 - sgfa2)) ! should be a quadratic block
311 v_blocks(:, :, kterm) = 0.0_dp
312 DO i = 1, sgla1 - sgfa1 + 1 ! set diagonal of sub-block
313 v_blocks(sgfa1 - 1 + i, sgfa2 - 1 + i, kterm) = 1.0_dp
314 v_blocks(sgfa2 - 1 + i, sgfa1 - 1 + i, kterm) = 1.0_dp
315 END DO
316 norm2 = sum(v_blocks(:, :, kterm)**2)
317 v_blocks(:, :, kterm) = v_blocks(:, :, kterm)/sqrt(norm2) ! normalize
318 END DO ! jshell
319 END DO ! ishell
320 END DO ! jset
321 END DO ! iset
322
323 cpassert(SIZE(v_blocks, 3) == kterm) ! ensure we generated all terms
324
325 CALL timestop(handle)
326 END SUBROUTINE linpot_rotinv_calc_terms
327
328! **************************************************************************************************
329!> \brief Calculate force contribution from rotinv parametrization
330!> \param qs_env ...
331!> \param iatom ...
332!> \param M_blocks ...
333!> \param forces ...
334! **************************************************************************************************
335 SUBROUTINE linpot_rotinv_calc_forces(qs_env, iatom, M_blocks, forces)
336 TYPE(qs_environment_type), POINTER :: qs_env
337 INTEGER, INTENT(IN) :: iatom
338 REAL(dp), DIMENSION(:, :, :), INTENT(IN) :: m_blocks
339 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: forces
340
341 CHARACTER(len=*), PARAMETER :: routinen = 'linpot_rotinv_calc_forces'
342
343 INTEGER :: handle, i, ic, ikind, ipot, iset, ishell, ishell_abs, jatom, jkind, jset, jshell, &
344 jshell_abs, kterm, la1_max, la1_min, la2_max, la2_min, lb_max, lb_min, lpot, n, na1, na2, &
345 natoms, nb, ncfga1, ncfga2, ncfgb, npgfa1, npgfa2, npgfb, npots, nshells, pot_maxl, &
346 sgfa1, sgfa2, sgla1, sgla2
347 REAL(dp) :: coeff, f, norm2, pot_beta, pot_weight, &
348 rpgfa_max, tab
349 REAL(dp), DIMENSION(3) :: ra, rab, rb
350 REAL(dp), DIMENSION(:), POINTER :: rpgfa1, rpgfa2, rpgfb, zeta1, zeta2, zetb
351 REAL(dp), DIMENSION(:, :), POINTER :: block_d, t1, t2
352 REAL(dp), DIMENSION(:, :, :), POINTER :: block_m_full, dab
353 REAL(dp), DIMENSION(:, :, :, :), POINTER :: daab
354 TYPE(cell_type), POINTER :: cell
355 TYPE(gto_basis_set_type), POINTER :: basis_set
356 TYPE(pao_potential_type), DIMENSION(:), POINTER :: ipao_potentials, jpao_potentials
357 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
358 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
359
360 CALL timeset(routinen, handle)
361
362 CALL get_qs_env(qs_env, &
363 natom=natoms, &
364 cell=cell, &
365 particle_set=particle_set, &
366 qs_kind_set=qs_kind_set)
367
368 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
369 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_potentials=ipao_potentials)
370 npots = SIZE(ipao_potentials)
371 nshells = sum(basis_set%nshell)
372 n = basis_set%nsgf ! primary basis-size
373 cpassert(SIZE(m_blocks, 1) == n .AND. SIZE(m_blocks, 2) == n)
374 kterm = 0 ! init counter
375 ALLOCATE (block_d(n, n))
376
377 DO ipot = 1, npots
378 pot_maxl = ipao_potentials(ipot)%maxl ! taken from central atom
379
380 ! build block_M_full
381 ALLOCATE (block_m_full(n, n, pot_maxl/2 + 1))
382 block_m_full = 0.0_dp
383 DO iset = 1, basis_set%nset
384 DO jset = 1, iset
385 DO ishell = 1, basis_set%nshell(iset)
386 DO jshell = 1, basis_set%nshell(jset)
387 IF (basis_set%l(ishell, iset) == 0 .AND. basis_set%l(jshell, jset) == 0) cycle ! covered by central terms
388 ishell_abs = sum(basis_set%nshell(1:iset - 1)) + ishell
389 jshell_abs = sum(basis_set%nshell(1:jset - 1)) + jshell
390 IF (ishell_abs < jshell_abs) cycle
391 ! find bounds of shell-pair
392 sgfa1 = basis_set%first_sgf(ishell, iset)
393 sgla1 = basis_set%last_sgf(ishell, iset)
394 sgfa2 = basis_set%first_sgf(jshell, jset)
395 sgla2 = basis_set%last_sgf(jshell, jset)
396 DO lpot = 0, pot_maxl, 2
397 kterm = kterm + 1
398 block_m_full(sgfa1:sgla1, sgfa2:sgla2, lpot/2 + 1) = m_blocks(sgfa1:sgla1, sgfa2:sgla2, kterm)
399 block_m_full(sgfa2:sgla2, sgfa1:sgla1, lpot/2 + 1) = m_blocks(sgfa2:sgla2, sgfa1:sgla1, kterm)
400 END DO ! lpot
401 END DO ! jshell
402 END DO ! ishell
403 END DO ! jset
404 END DO ! iset
405
406 ! setup description of potential
407 lb_min = 0
408 lb_max = pot_maxl
409 ncfgb = ncoset(lb_max) - ncoset(lb_min - 1)
410 npgfb = 1 ! number of exponents
411 nb = npgfb*ncfgb
412 ALLOCATE (rpgfb(npgfb), zetb(npgfb))
413
414 DO iset = 1, basis_set%nset
415 DO jset = 1, iset
416
417 ! setup iset
418 la1_max = basis_set%lmax(iset)
419 la1_min = basis_set%lmin(iset)
420 npgfa1 = basis_set%npgf(iset)
421 ncfga1 = ncoset(la1_max) - ncoset(la1_min - 1)
422 na1 = npgfa1*ncfga1
423 zeta1 => basis_set%zet(:, iset)
424 rpgfa1 => basis_set%pgf_radius(:, iset)
425
426 ! setup jset
427 la2_max = basis_set%lmax(jset)
428 la2_min = basis_set%lmin(jset)
429 npgfa2 = basis_set%npgf(jset)
430 ncfga2 = ncoset(la2_max) - ncoset(la2_min - 1)
431 na2 = npgfa2*ncfga2
432 zeta2 => basis_set%zet(:, jset)
433 rpgfa2 => basis_set%pgf_radius(:, jset)
434
435 ! radius of most diffuse basis-function
436 rpgfa_max = max(maxval(rpgfa1), maxval(rpgfa2))
437
438 ! find bounds of set-pair and setup transformation matrices
439 sgfa1 = basis_set%first_sgf(1, iset)
440 sgla1 = sgfa1 + basis_set%nsgf_set(iset) - 1
441 sgfa2 = basis_set%first_sgf(1, jset)
442 sgla2 = sgfa2 + basis_set%nsgf_set(jset) - 1
443 t1 => basis_set%scon(1:na1, sgfa1:sgla1)
444 t2 => basis_set%scon(1:na2, sgfa2:sgla2)
445
446 ! allocate space for integrals
447 ALLOCATE (daab(na1, na2, nb, 3), dab(na1, na2, 3))
448
449 ! loop over neighbors
450 DO jatom = 1, natoms
451 IF (jatom == iatom) cycle ! no self-interaction
452 CALL get_atomic_kind(particle_set(jatom)%atomic_kind, kind_number=jkind)
453 CALL get_qs_kind(qs_kind_set(jkind), pao_potentials=jpao_potentials)
454 IF (SIZE(jpao_potentials) /= npots) THEN
455 cpabort("Not all KINDs have the same number of PAO_POTENTIAL sections")
456 END IF
457
458 ! initialize exponents
459 pot_weight = jpao_potentials(ipot)%weight ! taken from remote atom
460 pot_beta = jpao_potentials(ipot)%beta ! taken from remote atom
461 rpgfb(1) = jpao_potentials(ipot)%beta_radius ! taken from remote atom
462 zetb(1) = pot_beta
463
464 ! calculate direction
465 ra = particle_set(iatom)%r
466 rb = particle_set(jatom)%r
467 rab = pbc(ra, rb, cell)
468
469 ! distance screening
470 tab = sqrt(sum(rab**2))
471 IF (rpgfa_max + rpgfb(1) < tab) cycle
472
473 ! calculate actual integrals
474 daab = 0.0_dp
475 CALL overlap_aab(la1_max=la1_max, la1_min=la1_min, npgfa1=npgfa1, rpgfa1=rpgfa1, zeta1=zeta1, &
476 la2_max=la2_max, la2_min=la2_min, npgfa2=npgfa2, rpgfa2=rpgfa2, zeta2=zeta2, &
477 lb_max=lb_max, lb_min=lb_min, npgfb=npgfb, rpgfb=rpgfb, zetb=zetb, &
478 rab=rab, daab=daab)
479
480 ! sum neighbor contributions according to remote atom's weight and normalization
481 DO lpot = 0, pot_maxl, 2
482 ! sum potential terms: POW(x**2 + y**2 + z**2, lpot/2)
483 dab = 0.0_dp
484 DO ic = ncoset(lpot - 1) + 1, ncoset(lpot)
485 norm2 = (2.0_dp*pot_beta)**(-0.5_dp - lpot)*gamma1(lpot)
486 coeff = multinomial(lpot/2, indco(:, ic)/2)
487 dab = dab + coeff*daab(:, :, ic, :)*pot_weight/sqrt(norm2)
488 END DO
489 DO i = 1, 3
490 ! transform into primary basis
491 block_d = 0.0_dp
492 block_d(sgfa1:sgla1, sgfa2:sgla2) = matmul(transpose(t1), matmul(dab(:, :, i), t2))
493 block_d(sgfa2:sgla2, sgfa1:sgla1) = transpose(block_d(sgfa1:sgla1, sgfa2:sgla2))
494 ! calculate and add forces
495 f = sum(block_m_full(:, :, lpot/2 + 1)*block_d)
496 forces(iatom, i) = forces(iatom, i) - f
497 forces(jatom, i) = forces(jatom, i) + f
498 END DO
499 END DO ! lpot
500 END DO ! jatom
501 DEALLOCATE (dab, daab)
502 END DO ! jset
503 END DO ! iset
504 DEALLOCATE (rpgfb, zetb, block_m_full)
505 END DO ! ipot
506 DEALLOCATE (block_d)
507
508 CALL timestop(handle)
509 END SUBROUTINE linpot_rotinv_calc_forces
510
511END 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:968
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:263
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, mimic, 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_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, harris_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, eeq, rhs, do_rixs, tb_tblite)
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, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, 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_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, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
Holds information about a PAO potential.
Provides all information about a quickstep kind.