(git:374b731)
Loading...
Searching...
No Matches
ai_oneelectron.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 general three-center integrals over Cartesian
10!> Gaussian-type functions and a spherical operator centered at position C
11!>
12!> <a|V(local)|b> = <a|F(|r-C|)|b>
13!> \par Literature
14!> S. Obara and A. Saika, J. Chem. Phys. 84, 3963 (1986)
15!> \par History
16!> - Based in part on code by MK
17!> \par Parameters
18!> - ax,ay,az : Angular momentum index numbers of orbital a.
19!> - bx,by,bz : Angular momentum index numbers of orbital b.
20!> - coset : Cartesian orbital set pointer.
21!> - dab : Distance between the atomic centers a and b.
22!> - dac : Distance between the atomic centers a and c.
23!> - dbc : Distance between the atomic centers b and c.
24!> - l{a,b} : Angular momentum quantum number of shell a or b.
25!> - l{a,b}_max : Maximum angular momentum quantum number of shell a or b.
26!> - ncoset : Number of Cartesian orbitals up to l.
27!> - rab : Distance vector between the atomic centers a and b.
28!> - rac : Distance vector between the atomic centers a and c.
29!> - rbc : Distance vector between the atomic centers b and c.
30!> - rpgf{a,b,c}: Radius of the primitive Gaussian-type function a or b.
31!> - zet{a,b} : Exponents of the Gaussian-type functions a or b.
32!> \author jhu (05.2011)
33! **************************************************************************************************
35
36 USE kinds, ONLY: dp
37 USE orbital_pointers, ONLY: coset,&
38 ncoset
39#include "../base/base_uses.f90"
40
41 IMPLICIT NONE
42
43 PRIVATE
44
45 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ai_oneelectron'
46
47! *** Public subroutines ***
48
49 PUBLIC :: os_3center, os_2center
50
51CONTAINS
52
53! **************************************************************************************************
54!> \brief Calculation of three-center integrals <a|c|b> over
55!> Cartesian Gaussian functions and a spherical potential
56!>
57!> \param la_max_set ...
58!> \param la_min_set ...
59!> \param npgfa ...
60!> \param rpgfa ...
61!> \param zeta ...
62!> \param lb_max_set ...
63!> \param lb_min_set ...
64!> \param npgfb ...
65!> \param rpgfb ...
66!> \param zetb ...
67!> \param auxint ...
68!> \param rpgfc ...
69!> \param rab ...
70!> \param dab ...
71!> \param rac ...
72!> \param dac ...
73!> \param rbc ...
74!> \param dbc ...
75!> \param vab ...
76!> \param s ...
77!> \param pab ...
78!> \param force_a ...
79!> \param force_b ...
80!> \param fs ...
81!> \param vab2 The derivative of the 3-center integrals according to the weighting factors.
82!> \param vab2_work ...
83!> \param deltaR DIMENSION(3, natoms), weighting factors of the derivatives for each atom and direction
84!> \param iatom ...
85!> \param jatom ...
86!> \param katom ...
87!> \date May 2011
88!> \author Juerg Hutter
89!> \version 1.0
90!> \note Extended by the derivatives for DFPT [Sandra Luber, Edward Ditler, 2021]
91! **************************************************************************************************
92 SUBROUTINE os_3center(la_max_set, la_min_set, npgfa, rpgfa, zeta, &
93 lb_max_set, lb_min_set, npgfb, rpgfb, zetb, auxint, rpgfc, &
94 rab, dab, rac, dac, rbc, dbc, vab, s, pab, force_a, force_b, fs, &
95 vab2, vab2_work, deltaR, iatom, jatom, katom)
96 INTEGER, INTENT(IN) :: la_max_set, la_min_set, npgfa
97 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: rpgfa, zeta
98 INTEGER, INTENT(IN) :: lb_max_set, lb_min_set, npgfb
99 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: rpgfb, zetb
100 REAL(kind=dp), DIMENSION(0:, :), INTENT(IN) :: auxint
101 REAL(kind=dp), INTENT(IN) :: rpgfc
102 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rab
103 REAL(kind=dp), INTENT(IN) :: dab
104 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rac
105 REAL(kind=dp), INTENT(IN) :: dac
106 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rbc
107 REAL(kind=dp), INTENT(IN) :: dbc
108 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT) :: vab
109 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT) :: s
110 REAL(kind=dp), DIMENSION(:, :), INTENT(IN), &
111 OPTIONAL :: pab
112 REAL(kind=dp), DIMENSION(3), INTENT(OUT), OPTIONAL :: force_a, force_b
113 REAL(kind=dp), DIMENSION(:, :, :), INTENT(INOUT), &
114 OPTIONAL :: fs, vab2, vab2_work
115 REAL(kind=dp), DIMENSION(:, :), INTENT(IN), &
116 OPTIONAL :: deltar
117 INTEGER, INTENT(IN), OPTIONAL :: iatom, jatom, katom
118
119 INTEGER :: ax, ay, az, bx, by, bz, cda, cdax, cday, cdaz, cdb, cdbx, cdby, cdbz, coa, coamx, &
120 coamy, coamz, coapx, coapy, coapz, cob, cobmx, cobmy, cobmz, cobpx, cobpy, cobpz, da, &
121 da_max, dax, day, daz, db, db_max, dbx, dby, dbz, i, ia, iap, iax, iay, iaz, ib, ibm, &
122 ibx, iby, ibz, idir, ii(3), iim(3), ij, ipgf, ir, ir1, ir2, irm(3), irr(3), irx, iry, &
123 irz, ix, ixx(1), j, jj(3), jjp(3), jpgf, la, la_max, la_min, lb, lb_max, lb_min, llr, m, &
124 ma, mb, mmax, na, nb
125 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: iiap
126 LOGICAL :: calculate_force_a, calculate_force_b
127 REAL(kind=dp) :: aai, abx, fax, fay, faz, fbx, fby, fbz, &
128 ftz, orho, rho, s1, s2
129 REAL(kind=dp), DIMENSION(3) :: pai, pbi, pci
130
131 IF (PRESENT(pab)) THEN
132 cpassert(PRESENT(fs))
133 IF (PRESENT(force_a)) THEN
134 calculate_force_a = .true.
135 ELSE
136 calculate_force_a = .false.
137 END IF
138 IF (PRESENT(force_b)) THEN
139 calculate_force_b = .true.
140 ELSE
141 calculate_force_b = .false.
142 END IF
143 ELSE
144 calculate_force_a = .false.
145 calculate_force_b = .false.
146 END IF
147
148 IF (calculate_force_a) THEN
149 da_max = 1
150 force_a = 0.0_dp
151 ELSE
152 da_max = 0
153 END IF
154
155 IF (calculate_force_b) THEN
156 db_max = 1
157 force_b = 0.0_dp
158 ELSE
159 db_max = 0
160 END IF
161
162 IF (PRESENT(vab2)) THEN
163 da_max = 1
164 db_max = 1
165 END IF
166
167 la_max = la_max_set + da_max
168 la_min = max(0, la_min_set - da_max)
169
170 lb_max = lb_max_set + db_max
171 lb_min = max(0, lb_min_set - db_max)
172
173 mmax = la_max + lb_max
174
175 ! precalculate indices for horizontal recursion
176 ALLOCATE (iiap(ncoset(mmax), 3))
177 DO ma = 0, mmax
178 DO iax = 0, ma
179 DO iay = 0, ma - iax
180 iaz = ma - iax - iay
181 ia = coset(iax, iay, iaz)
182 jj(1) = iax; jj(2) = iay; jj(3) = iaz
183 jjp = jj
184 jjp(1) = jjp(1) + 1
185 iap = coset(jjp(1), jjp(2), jjp(3))
186 iiap(ia, 1) = iap
187 jjp = jj
188 jjp(2) = jjp(2) + 1
189 iap = coset(jjp(1), jjp(2), jjp(3))
190 iiap(ia, 2) = iap
191 jjp = jj
192 jjp(3) = jjp(3) + 1
193 iap = coset(jjp(1), jjp(2), jjp(3))
194 iiap(ia, 3) = iap
195 END DO
196 END DO
197 END DO
198
199! *** Loop over all pairs of primitive Gaussian-type functions ***
200
201 na = 0
202
203 DO ipgf = 1, npgfa
204
205! *** Screening ***
206 IF (rpgfa(ipgf) + rpgfc < dac) THEN
207 na = na + ncoset(la_max_set)
208 cycle
209 END IF
210
211 nb = 0
212
213 DO jpgf = 1, npgfb
214
215! *** Screening ***
216 IF ((rpgfb(jpgf) + rpgfc < dbc) .OR. &
217 (rpgfa(ipgf) + rpgfb(jpgf) < dab)) THEN
218 nb = nb + ncoset(lb_max_set)
219 cycle
220 END IF
221
222! *** Calculate some prefactors ***
223 rho = zeta(ipgf) + zetb(jpgf)
224 pai(:) = zetb(jpgf)/rho*rab(:)
225 pbi(:) = -zeta(ipgf)/rho*rab(:)
226 pci(:) = -(zeta(ipgf)*rac(:) + zetb(jpgf)*rbc(:))/rho
227 orho = 0.5_dp/rho
228
229 ij = (ipgf - 1)*npgfb + jpgf
230 s(1, 1, 1:mmax + 1) = auxint(0:mmax, ij)
231
232 IF (la_max > 0) THEN
233! *** Recurrence steps: [s|c|s] -> [a|c|s] ***
234! *** [a|c|s](m) = (Pi - Ai)*[a-1i|c|s](m) - ***
235! *** (Pi - Ci)*[a-1i|c|s](m+1)) + ***
236! *** Ni(a-1i)/2(a+b)*[a-2i|c|s](m) - ***
237! *** Ni(a-1i)/2(a+b)*[a-2i|c|s](m+1) ***
238 DO llr = 1, mmax
239 IF (llr == 1) THEN
240 DO m = 0, mmax - llr
241 s1 = s(1, 1, m + 1)
242 s2 = s(1, 1, m + 2)
243 s(2, 1, m + 1) = pai(1)*s1 - pci(1)*s2 ! [px|o|s]
244 s(3, 1, m + 1) = pai(2)*s1 - pci(2)*s2 ! [py|o|s]
245 s(4, 1, m + 1) = pai(3)*s1 - pci(3)*s2 ! [pz|o|s]
246 END DO
247 ELSE IF (llr == 2) THEN
248 DO m = 0, mmax - llr
249 s1 = s(1, 1, m + 1) - s(1, 1, m + 2)
250 s(5, 1, m + 1) = pai(1)*s(2, 1, m + 1) - pci(1)*s(2, 1, m + 2) + orho*s1 ! [dx2|o|s]
251 s(6, 1, m + 1) = pai(1)*s(3, 1, m + 1) - pci(1)*s(3, 1, m + 2) ! [dxy|o|s]
252 s(7, 1, m + 1) = pai(1)*s(4, 1, m + 1) - pci(1)*s(4, 1, m + 2) ! [dxz|o|s]
253 s(8, 1, m + 1) = pai(2)*s(3, 1, m + 1) - pci(2)*s(3, 1, m + 2) + orho*s1 ! [dy2|o|s]
254 s(9, 1, m + 1) = pai(2)*s(4, 1, m + 1) - pci(2)*s(4, 1, m + 2) ! [dyz|o|s]
255 s(10, 1, m + 1) = pai(3)*s(4, 1, m + 1) - pci(3)*s(4, 1, m + 2) + orho*s1 ! [dz2|o|s]
256 END DO
257 ELSE IF (llr == 3) THEN
258 DO m = 0, mmax - llr
259 s(11, 1, m + 1) = pai(1)*s(5, 1, m + 1) - pci(1)*s(5, 1, m + 2) & ! [fx3 |o|s]
260 + 2._dp*orho*(s(2, 1, m + 1) - s(2, 1, m + 2))
261 s(12, 1, m + 1) = pai(1)*s(6, 1, m + 1) - pci(1)*s(6, 1, m + 2) & ! [fx2y|o|s]
262 + orho*(s(3, 1, m + 1) - s(3, 1, m + 2))
263 s(13, 1, m + 1) = pai(1)*s(7, 1, m + 1) - pci(1)*s(7, 1, m + 2) & ! [fx2z|o|s]
264 + orho*(s(4, 1, m + 1) - s(4, 1, m + 2))
265 s(14, 1, m + 1) = pai(2)*s(6, 1, m + 1) - pci(2)*s(6, 1, m + 2) & ! [fxy2|o|s]
266 + orho*(s(2, 1, m + 1) - s(2, 1, m + 2))
267 s(15, 1, m + 1) = pai(1)*s(9, 1, m + 1) - pci(1)*s(9, 1, m + 2) ! [fxyz|o|s]
268 s(16, 1, m + 1) = pai(3)*s(7, 1, m + 1) - pci(3)*s(7, 1, m + 2) & ! [fxz2|o|s]
269 + orho*(s(2, 1, m + 1) - s(2, 1, m + 2))
270 s(17, 1, m + 1) = pai(2)*s(8, 1, m + 1) - pci(2)*s(8, 1, m + 2) & ! [fy3 |o|s]
271 + 2._dp*orho*(s(3, 1, m + 1) - s(3, 1, m + 2))
272 s(18, 1, m + 1) = pai(2)*s(9, 1, m + 1) - pci(2)*s(9, 1, m + 2) & ! [fy2z|o|s]
273 + orho*(s(4, 1, m + 1) - s(4, 1, m + 2))
274 s(19, 1, m + 1) = pai(3)*s(9, 1, m + 1) - pci(3)*s(9, 1, m + 2) & ! [fyz2|o|s]
275 + orho*(s(3, 1, m + 1) - s(3, 1, m + 2))
276 s(20, 1, m + 1) = pai(3)*s(10, 1, m + 1) - pci(3)*s(10, 1, m + 2) & ! [fz3 |o|s]
277 + 2._dp*orho*(s(4, 1, m + 1) - s(4, 1, m + 2))
278 END DO
279 ELSE IF (llr == 4) THEN
280 DO m = 0, mmax - llr
281 s(21, 1, m + 1) = pai(1)*s(11, 1, m + 1) - pci(1)*s(11, 1, m + 2) & ! [gx4 |s|s]
282 + 3._dp*orho*(s(5, 1, m + 1) - s(5, 1, m + 2))
283 s(22, 1, m + 1) = pai(1)*s(12, 1, m + 1) - pci(1)*s(12, 1, m + 2) & ! [gx3y |s|s]
284 + 2._dp*orho*(s(6, 1, m + 1) - s(6, 1, m + 2))
285 s(23, 1, m + 1) = pai(1)*s(13, 1, m + 1) - pci(1)*s(13, 1, m + 2) & ! [gx3z |s|s]
286 + 2._dp*orho*(s(7, 1, m + 1) - s(7, 1, m + 2))
287 s(24, 1, m + 1) = pai(1)*s(14, 1, m + 1) - pci(1)*s(14, 1, m + 2) & ! [gx2y2|s|s]
288 + orho*(s(8, 1, m + 1) - s(8, 1, m + 2))
289 s(25, 1, m + 1) = pai(1)*s(15, 1, m + 1) - pci(1)*s(15, 1, m + 2) & ! [gx2yz|s|s]
290 + orho*(s(9, 1, m + 1) - s(9, 1, m + 2))
291 s(26, 1, m + 1) = pai(1)*s(16, 1, m + 1) - pci(1)*s(16, 1, m + 2) & ! [gx2z2|s|s]
292 + orho*(s(10, 1, m + 1) - s(10, 1, m + 2))
293 s(27, 1, m + 1) = pai(1)*s(17, 1, m + 1) - pci(1)*s(17, 1, m + 2) ! [gxy3 |s|s]
294 s(28, 1, m + 1) = pai(1)*s(18, 1, m + 1) - pci(1)*s(18, 1, m + 2) ! [gxy2z|s|s]
295 s(29, 1, m + 1) = pai(1)*s(19, 1, m + 1) - pci(1)*s(19, 1, m + 2) ! [gxyz2|s|s]
296 s(30, 1, m + 1) = pai(1)*s(20, 1, m + 1) - pci(1)*s(20, 1, m + 2) ! [gxz3 |s|s]
297 s(31, 1, m + 1) = pai(2)*s(17, 1, m + 1) - pci(2)*s(17, 1, m + 2) & ! [gy4 |s|s]
298 + 3._dp*orho*(s(8, 1, m + 1) - s(8, 1, m + 2))
299 s(32, 1, m + 1) = pai(2)*s(18, 1, m + 1) - pci(2)*s(18, 1, m + 2) & ! [gy3z |s|s]
300 + 2._dp*orho*(s(9, 1, m + 1) - s(9, 1, m + 2))
301 s(33, 1, m + 1) = pai(2)*s(19, 1, m + 1) - pci(2)*s(19, 1, m + 2) & ! [gy2z2|s|s]
302 + orho*(s(10, 1, m + 1) - s(10, 1, m + 2))
303 s(34, 1, m + 1) = pai(2)*s(20, 1, m + 1) - pci(2)*s(20, 1, m + 2) ! [gyz3 |s|s]
304 s(35, 1, m + 1) = pai(3)*s(20, 1, m + 1) - pci(3)*s(20, 1, m + 2) & ! [gz4 |s|s]
305 + 3._dp*orho*(s(10, 1, m + 1) - s(10, 1, m + 2))
306 END DO
307 ELSE
308 DO irx = 0, llr
309 DO iry = 0, llr - irx
310 irz = llr - irx - iry
311 irr(1) = irx; irr(2) = iry; irr(3) = irz
312 ixx = maxloc(irr)
313 ix = ixx(1)
314 ir = coset(irx, iry, irz)
315 irm = irr
316 irm(ix) = irm(ix) - 1
317 aai = real(max(irm(ix), 0), dp)*orho
318 ir1 = coset(irm(1), irm(2), irm(3))
319 irm(ix) = irm(ix) - 1
320 ir2 = coset(irm(1), irm(2), irm(3))
321 DO m = 0, mmax - llr
322 s(ir, 1, m + 1) = pai(ix)*s(ir1, 1, m + 1) - pci(ix)*s(ir1, 1, m + 2) &
323 + aai*(s(ir2, 1, m + 1) - s(ir2, 1, m + 2))
324 END DO
325 END DO
326 END DO
327 END IF
328 END DO
329
330! *** Horizontal recurrence steps ***
331! *** [a|c|b+1i] = [a+1i|c|b] + (Ai - Bi)*[a|c|b] ***
332
333 DO mb = 1, lb_max
334 DO ibx = 0, mb
335 DO iby = 0, mb - ibx
336 ibz = mb - ibx - iby
337 ib = coset(ibx, iby, ibz)
338 ii(1) = ibx; ii(2) = iby; ii(3) = ibz
339 ixx = maxloc(ii)
340 ix = ixx(1)
341 abx = -rab(ix)
342 iim = ii
343 iim(ix) = iim(ix) - 1
344 ibm = coset(iim(1), iim(2), iim(3))
345 DO ia = 1, ncoset(mmax - mb)
346 iap = iiap(ia, ix)
347 s(ia, ib, 1) = s(iap, ibm, 1) + abx*s(ia, ibm, 1)
348 END DO
349 END DO
350 END DO
351 END DO
352
353 ELSE IF (lb_max > 0) THEN
354
355! *** Recurrence steps: [s|c|s] -> [s|c|b] ***
356! *** [s|c|b](m) = (Pi - Bi)*[s|c|b-1i](m) - ***
357! *** (Pi - Ci)*[s|c|b-1i](m+1)) + ***
358! *** Ni(b-1i)/2(a+b)*[s|c|b-2i](m) - ***
359! *** Ni(b-1i)/2(a+b)*[s|c|b-2i](m+1) ***
360 DO llr = 1, lb_max
361 IF (llr == 1) THEN
362 DO m = 0, lb_max - llr
363 s1 = s(1, 1, m + 1)
364 s2 = s(1, 1, m + 2)
365 s(1, 2, m + 1) = pbi(1)*s1 - pci(1)*s2 ! [px|o|s]
366 s(1, 3, m + 1) = pbi(2)*s1 - pci(2)*s2 ! [py|o|s]
367 s(1, 4, m + 1) = pbi(3)*s1 - pci(3)*s2 ! [pz|o|s]
368 END DO
369 ELSE IF (llr == 2) THEN
370 DO m = 0, lb_max - llr
371 s1 = s(1, 1, m + 1) - s(1, 1, m + 2)
372 s(1, 5, m + 1) = pbi(1)*s(1, 2, m + 1) - pci(1)*s(1, 2, m + 2) + orho*s1 ! [dx2|o|s]
373 s(1, 6, m + 1) = pbi(1)*s(1, 3, m + 1) - pci(1)*s(1, 3, m + 2) ! [dxy|o|s]
374 s(1, 7, m + 1) = pbi(1)*s(1, 4, m + 1) - pci(1)*s(1, 4, m + 2) ! [dxz|o|s]
375 s(1, 8, m + 1) = pbi(2)*s(1, 3, m + 1) - pci(2)*s(1, 3, m + 2) + orho*s1 ! [dy2|o|s]
376 s(1, 9, m + 1) = pbi(2)*s(1, 4, m + 1) - pci(2)*s(1, 4, m + 2) ! [dyz|o|s]
377 s(1, 10, m + 1) = pbi(3)*s(1, 4, m + 1) - pci(3)*s(1, 4, m + 2) + orho*s1 ! [dz2|o|s]
378 END DO
379 ELSE IF (llr == 3) THEN
380 DO m = 0, lb_max - llr
381 s(1, 11, m + 1) = pbi(1)*s(1, 5, m + 1) - pci(1)*s(1, 5, m + 2) & ! [fx3 |o|s]
382 + 2._dp*orho*(s(1, 2, m + 1) - s(1, 2, m + 2))
383 s(1, 12, m + 1) = pbi(1)*s(1, 6, m + 1) - pci(1)*s(1, 6, m + 2) & ! [fx2y|o|s]
384 + orho*(s(1, 3, m + 1) - s(1, 3, m + 2))
385 s(1, 13, m + 1) = pbi(1)*s(1, 7, m + 1) - pci(1)*s(1, 7, m + 2) & ! [fx2z|o|s]
386 + orho*(s(1, 4, m + 1) - s(1, 4, m + 2))
387 s(1, 14, m + 1) = pbi(2)*s(1, 6, m + 1) - pci(2)*s(1, 6, m + 2) & ! [fxy2|o|s]
388 + orho*(s(1, 2, m + 1) - s(1, 2, m + 2))
389 s(1, 15, m + 1) = pbi(1)*s(1, 9, m + 1) - pci(1)*s(1, 9, m + 2) ! [fxyz|o|s]
390 s(1, 16, m + 1) = pbi(3)*s(1, 7, m + 1) - pci(3)*s(1, 7, m + 2) & ! [fxz2|o|s]
391 + orho*(s(1, 2, m + 1) - s(1, 2, m + 2))
392 s(1, 17, m + 1) = pbi(2)*s(1, 8, m + 1) - pci(2)*s(1, 8, m + 2) & ! [fy3 |o|s]
393 + 2._dp*orho*(s(1, 3, m + 1) - s(1, 3, m + 2))
394 s(1, 18, m + 1) = pbi(2)*s(1, 9, m + 1) - pci(2)*s(1, 9, m + 2) & ! [fy2z|o|s]
395 + orho*(s(1, 4, m + 1) - s(1, 4, m + 2))
396 s(1, 19, m + 1) = pbi(3)*s(1, 9, m + 1) - pci(3)*s(1, 9, m + 2) & ! [fyz2|o|s]
397 + orho*(s(1, 3, m + 1) - s(1, 3, m + 2))
398 s(1, 20, m + 1) = pbi(3)*s(1, 10, m + 1) - pci(3)*s(1, 10, m + 2) & ! [fz3 |o|s]
399 + 2._dp*orho*(s(1, 4, m + 1) - s(1, 4, m + 2))
400 END DO
401 ELSE
402 DO irx = 0, llr
403 DO iry = 0, llr - irx
404 irz = llr - irx - iry
405 irr(1) = irx; irr(2) = iry; irr(3) = irz
406 ixx = maxloc(irr)
407 ix = ixx(1)
408 ir = coset(irx, iry, irz)
409 irm = irr
410 irm(ix) = irm(ix) - 1
411 aai = real(max(irm(ix), 0), dp)
412 ir1 = coset(irm(1), irm(2), irm(3))
413 irm(ix) = irm(ix) - 1
414 ir2 = coset(irm(1), irm(2), irm(3))
415 DO m = 0, lb_max - llr
416 s(1, ir, m + 1) = pbi(ix)*s(1, ir1, m + 1) - pci(ix)*s(1, ir1, m + 2) &
417 + aai*orho*(s(1, ir2, m + 1) - s(1, ir2, m + 2))
418 END DO
419 END DO
420 END DO
421 END IF
422 END DO
423
424 END IF
425
426! *** Store the primitive three-center overlap integrals ***
427 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
428 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
429 vab(na + i, nb + j) = vab(na + i, nb + j) + s(i, j, 1)
430 END DO
431 END DO
432
433! *** Calculate the requested derivatives with respect ***
434! *** to the nuclear coordinates of the atomic center a ***
435
436 DO da = 0, da_max - 1
437 ftz = 2.0_dp*zeta(ipgf)
438 DO dax = 0, da
439 DO day = 0, da - dax
440 daz = da - dax - day
441 cda = coset(dax, day, daz)
442 cdax = coset(dax + 1, day, daz)
443 cday = coset(dax, day + 1, daz)
444 cdaz = coset(dax, day, daz + 1)
445
446! *** [da/dAi|c|b] = 2*zeta*[a+1i|c|b] - Ni(a)[a-1i|c|b] ***
447
448 DO la = la_min_set, la_max - da - 1
449 DO ax = 0, la
450 fax = real(ax, dp)
451 DO ay = 0, la - ax
452 fay = real(ay, dp)
453 az = la - ax - ay
454 faz = real(az, dp)
455 coa = coset(ax, ay, az)
456 coamx = coset(ax - 1, ay, az)
457 coamy = coset(ax, ay - 1, az)
458 coamz = coset(ax, ay, az - 1)
459 coapx = coset(ax + 1, ay, az)
460 coapy = coset(ax, ay + 1, az)
461 coapz = coset(ax, ay, az + 1)
462 DO cob = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
463 fs(coa, cob, cdax) = ftz*s(coapx, cob, cda) - fax*s(coamx, cob, cda)
464 fs(coa, cob, cday) = ftz*s(coapy, cob, cda) - fay*s(coamy, cob, cda)
465 fs(coa, cob, cdaz) = ftz*s(coapz, cob, cda) - faz*s(coamz, cob, cda)
466 END DO
467 END DO
468 END DO
469 END DO
470 END DO
471
472 END DO
473 END DO
474
475 ! DFPT for APTs
476 IF (PRESENT(vab2_work)) THEN
477 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
478 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
479 vab2_work(na + i, nb + j, 1) = vab2_work(na + i, nb + j, 1) + fs(i, j, 2)
480 vab2_work(na + i, nb + j, 2) = vab2_work(na + i, nb + j, 2) + fs(i, j, 3)
481 vab2_work(na + i, nb + j, 3) = vab2_work(na + i, nb + j, 3) + fs(i, j, 4)
482 END DO
483 END DO
484 END IF
485
486! *** Calculate the force contribution for the atomic center a ***
487
488 IF (calculate_force_a) THEN
489 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
490 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
491 force_a(1) = force_a(1) + pab(na + i, nb + j)*fs(i, j, 2)
492 force_a(2) = force_a(2) + pab(na + i, nb + j)*fs(i, j, 3)
493 force_a(3) = force_a(3) + pab(na + i, nb + j)*fs(i, j, 4)
494 END DO
495 END DO
496 END IF
497
498! *** Calculate the requested derivatives with respect ***
499! *** to the nuclear coordinates of the atomic center b ***
500
501 DO db = 0, db_max - 1
502 ftz = 2.0_dp*zetb(jpgf)
503 DO dbx = 0, db
504 DO dby = 0, db - dbx
505 dbz = db - dbx - dby
506 cdb = coset(dbx, dby, dbz)
507 cdbx = coset(dbx + 1, dby, dbz)
508 cdby = coset(dbx, dby + 1, dbz)
509 cdbz = coset(dbx, dby, dbz + 1)
510
511! *** [a|c|db/dBi] = 2*zetb*[a|c|b+1i] - Ni(b)[a|c|b-1i] ***
512
513 DO lb = lb_min_set, lb_max - db - 1
514 DO bx = 0, lb
515 fbx = real(bx, dp)
516 DO by = 0, lb - bx
517 fby = real(by, dp)
518 bz = lb - bx - by
519 fbz = real(bz, dp)
520 cob = coset(bx, by, bz)
521 cobmx = coset(bx - 1, by, bz)
522 cobmy = coset(bx, by - 1, bz)
523 cobmz = coset(bx, by, bz - 1)
524 cobpx = coset(bx + 1, by, bz)
525 cobpy = coset(bx, by + 1, bz)
526 cobpz = coset(bx, by, bz + 1)
527 DO coa = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
528 fs(coa, cob, cdbx) = ftz*s(coa, cobpx, cdb) - fbx*s(coa, cobmx, cdb)
529 fs(coa, cob, cdby) = ftz*s(coa, cobpy, cdb) - fby*s(coa, cobmy, cdb)
530 fs(coa, cob, cdbz) = ftz*s(coa, cobpz, cdb) - fbz*s(coa, cobmz, cdb)
531 END DO
532 END DO
533 END DO
534 END DO
535
536 END DO
537 END DO
538 END DO
539
540 ! DFPT for APTs
541 IF (PRESENT(vab2_work)) THEN
542 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
543 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
544 vab2_work(na + i, nb + j, 4) = vab2_work(na + i, nb + j, 4) + fs(i, j, 2)
545 vab2_work(na + i, nb + j, 5) = vab2_work(na + i, nb + j, 5) + fs(i, j, 3)
546 vab2_work(na + i, nb + j, 6) = vab2_work(na + i, nb + j, 6) + fs(i, j, 4)
547 END DO
548 END DO
549
550 DO idir = 1, 3
551 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
552 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
553 vab2(na + i, nb + j, idir) = vab2(na + i, nb + j, idir) &
554 + vab2_work(na + i, nb + j, idir)*deltar(idir, iatom) &
555 - vab2_work(na + i, nb + j, idir)*deltar(idir, katom) &
556 + vab2_work(na + i, nb + j, idir + 3)*deltar(idir, jatom) &
557 - vab2_work(na + i, nb + j, idir + 3)*deltar(idir, katom)
558 END DO
559 END DO
560 END DO
561 END IF
562
563! *** Calculate the force contribution for the atomic center b ***
564
565 IF (calculate_force_b) THEN
566 DO j = ncoset(lb_min_set - 1) + 1, ncoset(lb_max_set)
567 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
568 force_b(1) = force_b(1) + pab(na + i, nb + j)*fs(i, j, 2)
569 force_b(2) = force_b(2) + pab(na + i, nb + j)*fs(i, j, 3)
570 force_b(3) = force_b(3) + pab(na + i, nb + j)*fs(i, j, 4)
571 END DO
572 END DO
573 END IF
574
575 nb = nb + ncoset(lb_max_set)
576
577 END DO
578
579 na = na + ncoset(la_max_set)
580
581 END DO
582
583 DEALLOCATE (iiap)
584
585 END SUBROUTINE os_3center
586! **************************************************************************************************
587!> \brief Calculation of two-center integrals <a|c> over
588!> Cartesian Gaussian functions and a spherical potential
589!>
590!> \param la_max_set ...
591!> \param la_min_set ...
592!> \param npgfa ...
593!> \param rpgfa ...
594!> \param zeta ...
595!> \param auxint ...
596!> \param rpgfc ...
597!> \param rac ...
598!> \param dac ...
599!> \param va ...
600!> \param dva ...
601!> \date December 2017
602!> \author Juerg Hutter
603!> \version 1.0
604! **************************************************************************************************
605 SUBROUTINE os_2center(la_max_set, la_min_set, npgfa, rpgfa, zeta, &
606 auxint, rpgfc, rac, dac, va, dva)
607 INTEGER, INTENT(IN) :: la_max_set, la_min_set, npgfa
608 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: rpgfa, zeta
609 REAL(kind=dp), DIMENSION(0:, :), INTENT(IN) :: auxint
610 REAL(kind=dp), INTENT(IN) :: rpgfc
611 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rac
612 REAL(kind=dp), INTENT(IN) :: dac
613 REAL(kind=dp), DIMENSION(:), INTENT(INOUT) :: va
614 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT), &
615 OPTIONAL :: dva
616
617 INTEGER :: ax, ay, az, coa, coamx, coamy, coamz, coapx, coapy, coapz, da_max, i, ipgf, ir, &
618 ir1, ir2, irm(3), irr(3), irx, iry, irz, ix, ixx(1), la, la_max, la_min, llr, m, mmax, na
619 REAL(kind=dp) :: aai, fax, fay, faz, ftz, orho, s1
620 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: s
621
622 IF (PRESENT(dva)) THEN
623 da_max = 1
624 ELSE
625 da_max = 0
626 END IF
627
628 la_max = la_max_set + da_max
629 la_min = max(0, la_min_set - da_max)
630
631 mmax = la_max
632
633 ALLOCATE (s(ncoset(mmax), mmax + 1))
634 na = 0
635 DO ipgf = 1, npgfa
636 IF (rpgfa(ipgf) + rpgfc < dac) THEN
637 na = na + ncoset(la_max_set)
638 cycle
639 END IF
640 s(1, 1:mmax + 1) = auxint(0:mmax, ipgf)
641 IF (la_max > 0) THEN
642 ! Recurrence steps: [s|c] -> [a|c]
643 ! [a|c](m) = (Ci - Ai)*[a-1i|c](m+1) +
644 ! Ni(a-1i)/2a*[a-2i|c](m) -
645 ! Ni(a-1i)/2a*[a-2i|c](m+1)
646 !
647
648 orho = 0.5_dp/zeta(ipgf)
649
650 DO llr = 1, mmax
651 IF (llr == 1) THEN
652 DO m = 0, mmax - llr
653 s1 = s(1, m + 2)
654 s(2, m + 1) = -rac(1)*s1 ! [px|o]
655 s(3, m + 1) = -rac(2)*s1 ! [py|o]
656 s(4, m + 1) = -rac(3)*s1 ! [pz|o]
657 END DO
658 ELSE IF (llr == 2) THEN
659 DO m = 0, mmax - llr
660 s1 = s(1, m + 1) - s(1, m + 2)
661 s(5, m + 1) = -rac(1)*s(2, m + 2) + orho*s1 ! [dx2|o]
662 s(6, m + 1) = -rac(1)*s(3, m + 2) ! [dxy|o]
663 s(7, m + 1) = -rac(1)*s(4, m + 2) ! [dxz|o]
664 s(8, m + 1) = -rac(2)*s(3, m + 2) + orho*s1 ! [dy2|o]
665 s(9, m + 1) = -rac(2)*s(4, m + 2) ! [dyz|o]
666 s(10, m + 1) = -rac(3)*s(4, m + 2) + orho*s1 ! [dz2|o]
667 END DO
668 ELSE IF (llr == 3) THEN
669 DO m = 0, mmax - llr
670 s(11, m + 1) = -rac(1)*s(5, m + 2) + 2._dp*orho*(s(2, m + 1) - s(2, m + 2)) ! [fx3 |o]
671 s(12, m + 1) = -rac(1)*s(6, m + 2) + orho*(s(3, m + 1) - s(3, m + 2)) ! [fx2y|o]
672 s(13, m + 1) = -rac(1)*s(7, m + 2) + orho*(s(4, m + 1) - s(4, m + 2)) ! [fx2z|o]
673 s(14, m + 1) = -rac(2)*s(6, m + 2) + orho*(s(2, m + 1) - s(2, m + 2)) ! [fxy2|o]
674 s(15, m + 1) = -rac(1)*s(9, m + 2) ! [fxyz|o]
675 s(16, m + 1) = -rac(3)*s(7, m + 2) + orho*(s(2, m + 1) - s(2, m + 2)) ! [fxz2|o]
676 s(17, m + 1) = -rac(2)*s(8, m + 2) + 2._dp*orho*(s(3, m + 1) - s(3, m + 2)) ! [fy3 |o]
677 s(18, m + 1) = -rac(2)*s(9, m + 2) + orho*(s(4, m + 1) - s(4, m + 2)) ! [fy2z|o]
678 s(19, m + 1) = -rac(3)*s(9, m + 2) + orho*(s(3, m + 1) - s(3, m + 2)) ! [fyz2|o]
679 s(20, m + 1) = -rac(3)*s(10, m + 2) + 2._dp*orho*(s(4, m + 1) - s(4, m + 2)) ! [fz3 |o]
680 END DO
681 ELSE IF (llr == 4) THEN
682 DO m = 0, mmax - llr
683 s(21, m + 1) = -rac(1)*s(11, m + 2) + 3._dp*orho*(s(5, m + 1) - s(5, m + 2)) ! [gx4 |s]
684 s(22, m + 1) = -rac(1)*s(12, m + 2) + 2._dp*orho*(s(6, m + 1) - s(6, m + 2)) ! [gx3y |s]
685 s(23, m + 1) = -rac(1)*s(13, m + 2) + 2._dp*orho*(s(7, m + 1) - s(7, m + 2)) ! [gx3z |s]
686 s(24, m + 1) = -rac(1)*s(14, m + 2) + orho*(s(8, m + 1) - s(8, m + 2)) ! [gx2y2|s]
687 s(25, m + 1) = -rac(1)*s(15, m + 2) + orho*(s(9, m + 1) - s(9, m + 2)) ! [gx2yz|s]
688 s(26, m + 1) = -rac(1)*s(16, m + 2) + orho*(s(10, m + 1) - s(10, m + 2)) ! [gx2z2|s]
689 s(27, m + 1) = -rac(1)*s(17, m + 2) ! [gxy3 |s]
690 s(28, m + 1) = -rac(1)*s(18, m + 2) ! [gxy2z|s]
691 s(29, m + 1) = -rac(1)*s(19, m + 2) ! [gxyz2|s]
692 s(30, m + 1) = -rac(1)*s(20, m + 2) ! [gxz3 |s]
693 s(31, m + 1) = -rac(2)*s(17, m + 2) + 3._dp*orho*(s(8, m + 1) - s(8, m + 2)) ! [gy4 |s]
694 s(32, m + 1) = -rac(2)*s(18, m + 2) + 2._dp*orho*(s(9, m + 1) - s(9, m + 2)) ! [gy3z |s]
695 s(33, m + 1) = -rac(2)*s(19, m + 2) + orho*(s(10, m + 1) - s(10, m + 2)) ! [gy2z2|s]
696 s(34, m + 1) = -rac(2)*s(20, m + 2) ! [gyz3 |s]
697 s(35, m + 1) = -rac(3)*s(20, m + 2) + 3._dp*orho*(s(10, m + 1) - s(10, m + 2)) ! [gz4 |s]
698 END DO
699 ELSE
700 DO irx = 0, llr
701 DO iry = 0, llr - irx
702 irz = llr - irx - iry
703 irr(1) = irx; irr(2) = iry; irr(3) = irz
704 ixx = maxloc(irr)
705 ix = ixx(1)
706 ir = coset(irx, iry, irz)
707 irm = irr
708 irm(ix) = irm(ix) - 1
709 aai = real(max(irm(ix), 0), dp)*orho
710 ir1 = coset(irm(1), irm(2), irm(3))
711 irm(ix) = irm(ix) - 1
712 ir2 = coset(irm(1), irm(2), irm(3))
713 DO m = 0, mmax - llr
714 s(ir, m + 1) = -rac(ix)*s(ir1, m + 2) + aai*(s(ir2, m + 1) - s(ir2, m + 2))
715 END DO
716 END DO
717 END DO
718 END IF
719 END DO
720
721 END IF
722
723 ! Store the primitive three-center overlap integrals
724 DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
725 va(na + i) = va(na + i) + s(i, 1)
726 END DO
727
728 ! Calculate the requested derivatives with respect ***
729 ! to the nuclear coordinates of the atomic center a ***
730 ! [da/dAi|c] = 2*zeta*[a+1i|c] - Ni(a)[a-1i|c] ***
731 IF (PRESENT(dva)) THEN
732 ftz = 2.0_dp*zeta(ipgf)
733 DO la = la_min_set, la_max_set
734 DO ax = 0, la
735 fax = real(ax, dp)
736 DO ay = 0, la - ax
737 fay = real(ay, dp)
738 az = la - ax - ay
739 faz = real(az, dp)
740 coa = coset(ax, ay, az)
741 coamx = coset(ax - 1, ay, az)
742 coamy = coset(ax, ay - 1, az)
743 coamz = coset(ax, ay, az - 1)
744 coapx = coset(ax + 1, ay, az)
745 coapy = coset(ax, ay + 1, az)
746 coapz = coset(ax, ay, az + 1)
747 dva(na + coa, 1) = dva(na + coa, 1) + ftz*s(coapx, 1) - fax*s(coamx, 1)
748 dva(na + coa, 2) = dva(na + coa, 2) + ftz*s(coapy, 1) - fay*s(coamy, 1)
749 dva(na + coa, 3) = dva(na + coa, 3) + ftz*s(coapz, 1) - faz*s(coamz, 1)
750 END DO
751 END DO
752 END DO
753 END IF
754
755 na = na + ncoset(la_max_set)
756
757 END DO
758
759 DEALLOCATE (s)
760
761 END SUBROUTINE os_2center
762! **************************************************************************************************
763
764END MODULE ai_oneelectron
Calculation of general three-center integrals over Cartesian Gaussian-type functions and a spherical ...
subroutine, public os_3center(la_max_set, la_min_set, npgfa, rpgfa, zeta, lb_max_set, lb_min_set, npgfb, rpgfb, zetb, auxint, rpgfc, rab, dab, rac, dac, rbc, dbc, vab, s, pab, force_a, force_b, fs, vab2, vab2_work, deltar, iatom, jatom, katom)
Calculation of three-center integrals <a|c|b> over Cartesian Gaussian functions and a spherical poten...
subroutine, public os_2center(la_max_set, la_min_set, npgfa, rpgfa, zeta, auxint, rpgfc, rac, dac, va, dva)
Calculation of two-center integrals <a|c> over Cartesian Gaussian functions and a spherical potential...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Provides Cartesian and spherical orbital pointers and indices.
integer, dimension(:), allocatable, public ncoset
integer, dimension(:, :, :), allocatable, public coset