Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Calculate the atomic operator matrices
10 : !> \author jgh
11 : !> \date 03.03.2008
12 : !> \version 1.0
13 : !>
14 : ! **************************************************************************************************
15 : MODULE atom_operators
16 : USE ai_onecenter, ONLY: &
17 : sg_coulomb, sg_erf, sg_erfc, sg_exchange, sg_gpot, sg_kinetic, sg_kinnuc, sg_nuclear, &
18 : sg_overlap, sg_proj_ol, sto_kinetic, sto_nuclear, sto_overlap
19 : USE atom_types, ONLY: &
20 : atom_basis_gridrep, atom_basis_type, atom_compare_grids, atom_integrals, &
21 : atom_potential_type, atom_state, cgto_basis, ecp_pseudo, gth_pseudo, gto_basis, lmat, &
22 : no_pseudo, num_basis, release_atom_basis, sgp_pseudo, sto_basis, upf_pseudo
23 : USE atom_utils, ONLY: &
24 : atom_solve, contract2, contract2add, contract4, coulomb_potential_numeric, integrate_grid, &
25 : numpot_matrix, slater_density, wigner_slater_functional
26 : USE dkh_main, ONLY: dkh_atom_transformation
27 : USE input_constants, ONLY: &
28 : barrier_conf, do_dkh0_atom, do_dkh1_atom, do_dkh2_atom, do_dkh3_atom, do_nonrel_atom, &
29 : do_sczoramp_atom, do_zoramp_atom, poly_conf
30 : USE kinds, ONLY: dp
31 : USE mathconstants, ONLY: gamma1,&
32 : sqrt2
33 : USE mathlib, ONLY: jacobi
34 : USE periodic_table, ONLY: ptable
35 : USE physcon, ONLY: c_light_au
36 : USE qs_grid_atom, ONLY: grid_atom_type
37 : #include "./base/base_uses.f90"
38 :
39 : IMPLICIT NONE
40 :
41 : PRIVATE
42 :
43 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom_operators'
44 :
45 : PUBLIC :: atom_int_setup, atom_ppint_setup, atom_int_release, atom_ppint_release
46 : PUBLIC :: atom_relint_setup, atom_relint_release, atom_basis_projection_overlap
47 : PUBLIC :: calculate_model_potential
48 :
49 : CONTAINS
50 :
51 : ! **************************************************************************************************
52 : !> \brief Set up atomic integrals.
53 : !> \param integrals atomic integrals
54 : !> \param basis atomic basis set
55 : !> \param potential pseudo-potential
56 : !> \param eri_coulomb setup one-centre Coulomb Electron Repulsion Integrals
57 : !> \param eri_exchange setup one-centre exchange Electron Repulsion Integrals
58 : !> \param all_nu compute integrals for all even integer parameters [0 .. 2*l]
59 : !> REDUNDANT, AS THIS SUBROUTINE IS NEVER INVOKED WITH all_nu = .TRUE.
60 : ! **************************************************************************************************
61 11304 : SUBROUTINE atom_int_setup(integrals, basis, potential, &
62 : eri_coulomb, eri_exchange, all_nu)
63 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
64 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
65 : TYPE(atom_potential_type), INTENT(IN), OPTIONAL :: potential
66 : LOGICAL, INTENT(IN), OPTIONAL :: eri_coulomb, eri_exchange, all_nu
67 :
68 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_int_setup'
69 :
70 : INTEGER :: handle, i, ii, info, ipiv(1000), l, l1, &
71 : l2, ll, lwork, m, m1, m2, mm1, mm2, n, &
72 : n1, n2, nn1, nn2, nu, nx
73 : REAL(KIND=dp) :: om, rc, ron, sc, x
74 11304 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: cpot, w, work
75 11304 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: omat, vmat
76 11304 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: eri
77 :
78 11304 : CALL timeset(routineN, handle)
79 :
80 11304 : IF (integrals%status == 0) THEN
81 79100 : n = MAXVAL(basis%nbas)
82 79100 : integrals%n = basis%nbas
83 :
84 11300 : IF (PRESENT(eri_coulomb)) THEN
85 11264 : integrals%eri_coulomb = eri_coulomb
86 : ELSE
87 36 : integrals%eri_coulomb = .FALSE.
88 : END IF
89 11300 : IF (PRESENT(eri_exchange)) THEN
90 11266 : integrals%eri_exchange = eri_exchange
91 : ELSE
92 34 : integrals%eri_exchange = .FALSE.
93 : END IF
94 11300 : IF (PRESENT(all_nu)) THEN
95 0 : integrals%all_nu = all_nu
96 : ELSE
97 11300 : integrals%all_nu = .FALSE.
98 : END IF
99 :
100 11300 : NULLIFY (integrals%ovlp, integrals%kin, integrals%core, integrals%conf)
101 1141300 : DO ll = 1, SIZE(integrals%ceri)
102 1141300 : NULLIFY (integrals%ceri(ll)%int, integrals%eeri(ll)%int)
103 : END DO
104 :
105 56488 : ALLOCATE (integrals%ovlp(n, n, 0:lmat))
106 2706296 : integrals%ovlp = 0._dp
107 :
108 33888 : ALLOCATE (integrals%kin(n, n, 0:lmat))
109 2706296 : integrals%kin = 0._dp
110 :
111 11300 : integrals%status = 1
112 :
113 11300 : IF (PRESENT(potential)) THEN
114 11264 : IF (potential%confinement) THEN
115 25906 : ALLOCATE (integrals%conf(n, n, 0:lmat))
116 1072786 : integrals%conf = 0._dp
117 8638 : m = basis%grid%nr
118 25914 : ALLOCATE (cpot(1:m))
119 8638 : IF (potential%conf_type == poly_conf) THEN
120 8418 : rc = potential%rcon
121 8418 : sc = potential%scon
122 3374902 : cpot(1:m) = (basis%grid%rad(1:m)/rc)**sc
123 220 : ELSEIF (potential%conf_type == barrier_conf) THEN
124 220 : om = potential%rcon
125 220 : ron = potential%scon
126 220 : rc = ron + om
127 88220 : DO i = 1, m
128 88220 : IF (basis%grid%rad(i) < ron) THEN
129 75228 : cpot(i) = 0.0_dp
130 12772 : ELSEIF (basis%grid%rad(i) < rc) THEN
131 5652 : x = (basis%grid%rad(i) - ron)/om
132 5652 : x = 1._dp - x
133 5652 : cpot(i) = -6._dp*x**5 + 15._dp*x**4 - 10._dp*x**3 + 1._dp
134 5652 : x = (rc - basis%grid%rad(i))**2/om/(basis%grid%rad(i) - ron)
135 5652 : cpot(i) = cpot(i)*x
136 : ELSE
137 7120 : cpot(i) = 1.0_dp
138 : END IF
139 : END DO
140 : ELSE
141 0 : CPABORT("")
142 : END IF
143 8638 : CALL numpot_matrix(integrals%conf, cpot, basis, 0)
144 8638 : DEALLOCATE (cpot)
145 : END IF
146 : END IF
147 :
148 11300 : SELECT CASE (basis%basis_type)
149 : CASE DEFAULT
150 0 : CPABORT("")
151 : CASE (GTO_BASIS)
152 9842 : DO l = 0, lmat
153 8436 : n = integrals%n(l)
154 8436 : CALL sg_overlap(integrals%ovlp(1:n, 1:n, l), l, basis%am(1:n, l), basis%am(1:n, l))
155 9842 : CALL sg_kinetic(integrals%kin(1:n, 1:n, l), l, basis%am(1:n, l), basis%am(1:n, l))
156 : END DO
157 1406 : IF (integrals%eri_coulomb) THEN
158 42 : ll = 0
159 294 : DO l1 = 0, lmat
160 252 : n1 = integrals%n(l1)
161 252 : nn1 = (n1*(n1 + 1))/2
162 1176 : DO l2 = 0, l1
163 882 : n2 = integrals%n(l2)
164 882 : nn2 = (n2*(n2 + 1))/2
165 882 : IF (integrals%all_nu) THEN
166 0 : nx = MIN(2*l1, 2*l2)
167 : ELSE
168 : nx = 0
169 : END IF
170 2016 : DO nu = 0, nx, 2
171 882 : ll = ll + 1
172 882 : CPASSERT(ll <= SIZE(integrals%ceri))
173 3150 : ALLOCATE (integrals%ceri(ll)%int(nn1, nn2))
174 42697592 : integrals%ceri(ll)%int = 0._dp
175 882 : eri => integrals%ceri(ll)%int
176 1764 : CALL sg_coulomb(eri, nu, basis%am(1:n1, l1), l1, basis%am(1:n2, l2), l2)
177 : END DO
178 : END DO
179 : END DO
180 : END IF
181 1406 : IF (integrals%eri_exchange) THEN
182 22 : ll = 0
183 154 : DO l1 = 0, lmat
184 132 : n1 = integrals%n(l1)
185 132 : nn1 = (n1*(n1 + 1))/2
186 616 : DO l2 = 0, l1
187 462 : n2 = integrals%n(l2)
188 462 : nn2 = (n2*(n2 + 1))/2
189 1826 : DO nu = ABS(l1 - l2), l1 + l2, 2
190 1232 : ll = ll + 1
191 1232 : CPASSERT(ll <= SIZE(integrals%eeri))
192 4156 : ALLOCATE (integrals%eeri(ll)%int(nn1, nn2))
193 40282236 : integrals%eeri(ll)%int = 0._dp
194 1232 : eri => integrals%eeri(ll)%int
195 1694 : CALL sg_exchange(eri, nu, basis%am(1:n1, l1), l1, basis%am(1:n2, l2), l2)
196 : END DO
197 : END DO
198 : END DO
199 : END IF
200 : CASE (CGTO_BASIS)
201 61348 : DO l = 0, lmat
202 52584 : n = integrals%n(l)
203 52584 : m = basis%nprim(l)
204 61348 : IF (n > 0 .AND. m > 0) THEN
205 80772 : ALLOCATE (omat(m, m))
206 :
207 20193 : CALL sg_overlap(omat(1:m, 1:m), l, basis%am(1:m, l), basis%am(1:m, l))
208 20193 : CALL contract2(integrals%ovlp(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
209 20193 : CALL sg_kinetic(omat(1:m, 1:m), l, basis%am(1:m, l), basis%am(1:m, l))
210 20193 : CALL contract2(integrals%kin(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
211 20193 : DEALLOCATE (omat)
212 : END IF
213 : END DO
214 8764 : IF (integrals%eri_coulomb) THEN
215 16 : ll = 0
216 112 : DO l1 = 0, lmat
217 96 : n1 = integrals%n(l1)
218 96 : nn1 = (n1*(n1 + 1))/2
219 96 : m1 = basis%nprim(l1)
220 96 : mm1 = (m1*(m1 + 1))/2
221 448 : DO l2 = 0, l1
222 336 : n2 = integrals%n(l2)
223 336 : nn2 = (n2*(n2 + 1))/2
224 336 : m2 = basis%nprim(l2)
225 336 : mm2 = (m2*(m2 + 1))/2
226 336 : IF (integrals%all_nu) THEN
227 0 : nx = MIN(2*l1, 2*l2)
228 : ELSE
229 : nx = 0
230 : END IF
231 432 : DO nu = 0, nx, 2
232 336 : ll = ll + 1
233 336 : CPASSERT(ll <= SIZE(integrals%ceri))
234 812 : ALLOCATE (integrals%ceri(ll)%int(nn1, nn2))
235 946 : integrals%ceri(ll)%int = 0._dp
236 812 : ALLOCATE (omat(mm1, mm2))
237 :
238 336 : eri => integrals%ceri(ll)%int
239 336 : CALL sg_coulomb(omat, nu, basis%am(1:m1, l1), l1, basis%am(1:m2, l2), l2)
240 336 : CALL contract4(eri, omat, basis%cm(1:m1, 1:n1, l1), basis%cm(1:m2, 1:n2, l2))
241 :
242 336 : DEALLOCATE (omat)
243 : END DO
244 : END DO
245 : END DO
246 : END IF
247 8764 : IF (integrals%eri_exchange) THEN
248 16 : ll = 0
249 112 : DO l1 = 0, lmat
250 96 : n1 = integrals%n(l1)
251 96 : nn1 = (n1*(n1 + 1))/2
252 96 : m1 = basis%nprim(l1)
253 96 : mm1 = (m1*(m1 + 1))/2
254 448 : DO l2 = 0, l1
255 336 : n2 = integrals%n(l2)
256 336 : nn2 = (n2*(n2 + 1))/2
257 336 : m2 = basis%nprim(l2)
258 336 : mm2 = (m2*(m2 + 1))/2
259 432 : DO nu = ABS(l1 - l2), l1 + l2, 2
260 896 : ll = ll + 1
261 896 : CPASSERT(ll <= SIZE(integrals%eeri))
262 2032 : ALLOCATE (integrals%eeri(ll)%int(nn1, nn2))
263 3074 : integrals%eeri(ll)%int = 0._dp
264 2032 : ALLOCATE (omat(mm1, mm2))
265 :
266 896 : eri => integrals%eeri(ll)%int
267 896 : CALL sg_exchange(omat, nu, basis%am(1:m1, l1), l1, basis%am(1:m2, l2), l2)
268 896 : CALL contract4(eri, omat, basis%cm(1:m1, 1:n1, l1), basis%cm(1:m2, 1:n2, l2))
269 :
270 896 : DEALLOCATE (omat)
271 : END DO
272 : END DO
273 : END DO
274 : END IF
275 : CASE (STO_BASIS)
276 7910 : DO l = 0, lmat
277 6780 : n = integrals%n(l)
278 : CALL sto_overlap(integrals%ovlp(1:n, 1:n, l), basis%ns(1:n, l), basis%as(1:n, l), &
279 6780 : basis%ns(1:n, l), basis%as(1:n, l))
280 : CALL sto_kinetic(integrals%kin(1:n, 1:n, l), l, basis%ns(1:n, l), basis%as(1:n, l), &
281 7910 : basis%ns(1:n, l), basis%as(1:n, l))
282 : END DO
283 1130 : CPASSERT(.NOT. integrals%eri_coulomb)
284 1130 : CPASSERT(.NOT. integrals%eri_exchange)
285 : CASE (NUM_BASIS)
286 11300 : CPABORT("")
287 : END SELECT
288 :
289 : ! setup transformation matrix to get an orthogonal basis, remove linear dependencies
290 11300 : NULLIFY (integrals%utrans, integrals%uptrans)
291 79100 : n = MAXVAL(basis%nbas)
292 79076 : ALLOCATE (integrals%utrans(n, n, 0:lmat), integrals%uptrans(n, n, 0:lmat))
293 2706296 : integrals%utrans = 0._dp
294 2706296 : integrals%uptrans = 0._dp
295 79100 : integrals%nne = integrals%n
296 11300 : lwork = 10*n
297 112964 : ALLOCATE (omat(n, n), vmat(n, n), w(n), work(lwork))
298 79100 : DO l = 0, lmat
299 67800 : n = integrals%n(l)
300 79100 : IF (n > 0) THEN
301 1732861 : omat(1:n, 1:n) = integrals%ovlp(1:n, 1:n, l)
302 26237 : CALL jacobi(omat(1:n, 1:n), w(1:n), vmat(1:n, 1:n))
303 1732861 : omat(1:n, 1:n) = vmat(1:n, 1:n)
304 26237 : ii = 0
305 126152 : DO i = 1, n
306 126152 : IF (w(i) > basis%eps_eig) THEN
307 84831 : ii = ii + 1
308 1117378 : integrals%utrans(1:n, ii, l) = omat(1:n, i)/SQRT(w(i))
309 : END IF
310 : END DO
311 26237 : integrals%nne(l) = ii
312 26237 : IF (ii > 0) THEN
313 15331448 : omat(1:ii, 1:ii) = MATMUL(TRANSPOSE(integrals%utrans(1:n, 1:ii, l)), integrals%utrans(1:n, 1:ii, l))
314 111068 : DO i = 1, ii
315 111068 : integrals%uptrans(i, i, l) = 1._dp
316 : END DO
317 2013021 : CALL dgesv(ii, ii, omat(1:ii, 1:ii), ii, ipiv, integrals%uptrans(1:ii, 1:ii, l), ii, info)
318 26237 : CPASSERT(info == 0)
319 : END IF
320 : END IF
321 : END DO
322 11300 : DEALLOCATE (omat, vmat, w, work)
323 : END IF
324 :
325 11304 : CALL timestop(handle)
326 :
327 22608 : END SUBROUTINE atom_int_setup
328 :
329 : ! **************************************************************************************************
330 : !> \brief ...
331 : !> \param integrals ...
332 : !> \param basis ...
333 : !> \param potential ...
334 : ! **************************************************************************************************
335 11626 : SUBROUTINE atom_ppint_setup(integrals, basis, potential)
336 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
337 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
338 : TYPE(atom_potential_type), INTENT(IN) :: potential
339 :
340 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_ppint_setup'
341 :
342 : INTEGER :: handle, i, ii, j, k, l, m, n
343 : REAL(KIND=dp) :: al, alpha, rc
344 11626 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: cpot, xmat
345 11626 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: omat, spmat
346 11626 : REAL(KIND=dp), DIMENSION(:), POINTER :: rad
347 :
348 11626 : CALL timeset(routineN, handle)
349 :
350 11626 : IF (integrals%ppstat == 0) THEN
351 81354 : n = MAXVAL(basis%nbas)
352 81354 : integrals%n = basis%nbas
353 :
354 11622 : NULLIFY (integrals%core, integrals%hnl)
355 :
356 58098 : ALLOCATE (integrals%hnl(n, n, 0:lmat))
357 3462786 : integrals%hnl = 0._dp
358 :
359 34854 : ALLOCATE (integrals%core(n, n, 0:lmat))
360 3462786 : integrals%core = 0._dp
361 :
362 34854 : ALLOCATE (integrals%clsd(n, n, 0:lmat))
363 3462786 : integrals%clsd = 0._dp
364 :
365 11622 : integrals%ppstat = 1
366 :
367 11622 : SELECT CASE (basis%basis_type)
368 : CASE DEFAULT
369 0 : CPABORT("")
370 : CASE (GTO_BASIS)
371 :
372 10568 : SELECT CASE (potential%ppot_type)
373 : CASE (no_pseudo, ecp_pseudo)
374 1638 : DO l = 0, lmat
375 1404 : n = integrals%n(l)
376 1638 : CALL sg_nuclear(integrals%core(1:n, 1:n, l), l, basis%am(1:n, l), basis%am(1:n, l))
377 : END DO
378 : CASE (gth_pseudo)
379 1342 : IF (potential%gth_pot%soc) THEN
380 4 : CPWARN("Atom code: GTH SOC is ignored")
381 : END IF
382 1342 : alpha = 1._dp/potential%gth_pot%rc/SQRT(2._dp)
383 9394 : DO l = 0, lmat
384 8052 : n = integrals%n(l)
385 37488 : ALLOCATE (omat(n, n), spmat(n, 5))
386 :
387 1058720 : omat = 0._dp
388 8052 : CALL sg_erf(omat(1:n, 1:n), l, alpha, basis%am(1:n, l), basis%am(1:n, l))
389 1058720 : integrals%core(1:n, 1:n, l) = -potential%gth_pot%zion*omat(1:n, 1:n)
390 18816 : DO i = 1, potential%gth_pot%ncl
391 2003800 : omat = 0._dp
392 10764 : CALL sg_gpot(omat(1:n, 1:n), i - 1, potential%gth_pot%rc, l, basis%am(1:n, l), basis%am(1:n, l))
393 : integrals%core(1:n, 1:n, l) = integrals%core(1:n, 1:n, l) + &
394 2011852 : potential%gth_pot%cl(i)*omat(1:n, 1:n)
395 : END DO
396 8052 : IF (potential%gth_pot%lpotextended) THEN
397 96 : DO k = 1, potential%gth_pot%nexp_lpot
398 228 : DO i = 1, potential%gth_pot%nct_lpot(k)
399 36036 : omat = 0._dp
400 : CALL sg_gpot(omat(1:n, 1:n), i - 1, potential%gth_pot%alpha_lpot(k), l, &
401 132 : basis%am(1:n, l), basis%am(1:n, l))
402 : integrals%core(1:n, 1:n, l) = integrals%core(1:n, 1:n, l) + &
403 36096 : potential%gth_pot%cval_lpot(i, k)*omat(1:n, 1:n)
404 : END DO
405 : END DO
406 : END IF
407 8052 : IF (potential%gth_pot%lsdpot) THEN
408 0 : DO k = 1, potential%gth_pot%nexp_lsd
409 0 : DO i = 1, potential%gth_pot%nct_lsd(k)
410 0 : omat = 0._dp
411 : CALL sg_gpot(omat(1:n, 1:n), i - 1, potential%gth_pot%alpha_lsd(k), l, &
412 0 : basis%am(1:n, l), basis%am(1:n, l))
413 : integrals%clsd(1:n, 1:n, l) = integrals%clsd(1:n, 1:n, l) + &
414 0 : potential%gth_pot%cval_lsd(i, k)*omat(1:n, 1:n)
415 : END DO
416 : END DO
417 : END IF
418 :
419 306672 : spmat = 0._dp
420 8052 : m = potential%gth_pot%nl(l)
421 13924 : DO i = 1, m
422 13924 : CALL sg_proj_ol(spmat(1:n, i), l, basis%am(1:n, l), i - 1, potential%gth_pot%rcnl(l))
423 : END DO
424 8052 : integrals%hnl(1:n, 1:n, l) = MATMUL(spmat(1:n, 1:m), &
425 2408260 : MATMUL(potential%gth_pot%hnl(1:m, 1:m, l), TRANSPOSE(spmat(1:n, 1:m))))
426 :
427 9394 : DEALLOCATE (omat, spmat)
428 : END DO
429 : CASE (upf_pseudo)
430 4 : CALL upfint_setup(integrals, basis, potential)
431 : CASE (sgp_pseudo)
432 0 : CALL sgpint_setup(integrals, basis, potential)
433 : CASE DEFAULT
434 1580 : CPABORT("")
435 : END SELECT
436 :
437 : CASE (CGTO_BASIS)
438 :
439 11324 : SELECT CASE (potential%ppot_type)
440 : CASE (no_pseudo, ecp_pseudo)
441 8974 : DO l = 0, lmat
442 7692 : n = integrals%n(l)
443 7692 : m = basis%nprim(l)
444 21216 : ALLOCATE (omat(m, m))
445 :
446 7692 : CALL sg_nuclear(omat(1:m, 1:m), l, basis%am(1:m, l), basis%am(1:m, l))
447 7692 : CALL contract2(integrals%core(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
448 :
449 8974 : DEALLOCATE (omat)
450 : END DO
451 : CASE (gth_pseudo)
452 7460 : alpha = 1._dp/potential%gth_pot%rc/SQRT(2._dp)
453 52220 : DO l = 0, lmat
454 44760 : n = integrals%n(l)
455 44760 : m = basis%nprim(l)
456 52220 : IF (n > 0 .AND. m > 0) THEN
457 137736 : ALLOCATE (omat(m, m), spmat(n, 5), xmat(m))
458 :
459 378077 : omat = 0._dp
460 17217 : CALL sg_erf(omat(1:m, 1:m), l, alpha, basis%am(1:m, l), basis%am(1:m, l))
461 378077 : omat(1:m, 1:m) = -potential%gth_pot%zion*omat(1:m, 1:m)
462 17217 : CALL contract2(integrals%core(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
463 50413 : DO i = 1, potential%gth_pot%ncl
464 724748 : omat = 0._dp
465 33196 : CALL sg_gpot(omat(1:m, 1:m), i - 1, potential%gth_pot%rc, l, basis%am(1:m, l), basis%am(1:m, l))
466 724748 : omat(1:m, 1:m) = potential%gth_pot%cl(i)*omat(1:m, 1:m)
467 50413 : CALL contract2add(integrals%core(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
468 : END DO
469 17217 : IF (potential%gth_pot%lpotextended) THEN
470 72 : DO k = 1, potential%gth_pot%nexp_lpot
471 168 : DO i = 1, potential%gth_pot%nct_lpot(k)
472 3128 : omat = 0._dp
473 : CALL sg_gpot(omat(1:m, 1:m), i - 1, potential%gth_pot%alpha_lpot(k), l, &
474 96 : basis%am(1:m, l), basis%am(1:m, l))
475 3128 : omat(1:m, 1:m) = potential%gth_pot%cval_lpot(i, k)*omat(1:m, 1:m)
476 140 : CALL contract2add(integrals%core(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
477 : END DO
478 : END DO
479 : END IF
480 17217 : IF (potential%gth_pot%lsdpot) THEN
481 0 : DO k = 1, potential%gth_pot%nexp_lsd
482 0 : DO i = 1, potential%gth_pot%nct_lsd(k)
483 0 : omat = 0._dp
484 : CALL sg_gpot(omat(1:m, 1:m), i - 1, potential%gth_pot%alpha_lsd(k), l, &
485 0 : basis%am(1:m, l), basis%am(1:m, l))
486 0 : omat(1:m, 1:m) = potential%gth_pot%cval_lsd(i, k)*omat(1:m, 1:m)
487 0 : CALL contract2add(integrals%clsd(1:n, 1:n, l), omat(1:m, 1:m), basis%cm(1:m, 1:n, l))
488 : END DO
489 : END DO
490 : END IF
491 :
492 245882 : spmat = 0._dp
493 17217 : k = potential%gth_pot%nl(l)
494 22596 : DO i = 1, k
495 5379 : CALL sg_proj_ol(xmat(1:m), l, basis%am(1:m, l), i - 1, potential%gth_pot%rcnl(l))
496 22596 : spmat(1:n, i) = MATMUL(TRANSPOSE(basis%cm(1:m, 1:n, l)), xmat(1:m))
497 : END DO
498 17217 : IF (k > 0) THEN
499 4625 : integrals%hnl(1:n, 1:n, l) = MATMUL(spmat(1:n, 1:k), &
500 18500 : MATMUL(potential%gth_pot%hnl(1:k, 1:k, l), &
501 163283 : TRANSPOSE(spmat(1:n, 1:k))))
502 : END IF
503 17217 : DEALLOCATE (omat, spmat, xmat)
504 : END IF
505 : END DO
506 : CASE (upf_pseudo)
507 0 : CALL upfint_setup(integrals, basis, potential)
508 : CASE (sgp_pseudo)
509 12 : CALL sgpint_setup(integrals, basis, potential)
510 : CASE DEFAULT
511 8754 : CPABORT("")
512 : END SELECT
513 :
514 : CASE (STO_BASIS)
515 :
516 2336 : SELECT CASE (potential%ppot_type)
517 : CASE (no_pseudo, ecp_pseudo)
518 7336 : DO l = 0, lmat
519 6288 : n = integrals%n(l)
520 : CALL sto_nuclear(integrals%core(1:n, 1:n, l), basis%ns(1:n, l), basis%as(1:n, l), &
521 7336 : basis%ns(1:n, l), basis%as(1:n, l))
522 : END DO
523 : CASE (gth_pseudo)
524 240 : rad => basis%grid%rad
525 240 : m = basis%grid%nr
526 720 : ALLOCATE (cpot(1:m))
527 240 : rc = potential%gth_pot%rc
528 240 : alpha = 1._dp/rc/SQRT(2._dp)
529 :
530 : ! local pseudopotential, we use erf = 1/r - erfc
531 5040 : integrals%core = 0._dp
532 102640 : DO i = 1, m
533 102640 : cpot(i) = potential%gth_pot%zion*erfc(alpha*rad(i))/rad(i)
534 : END DO
535 720 : DO i = 1, potential%gth_pot%ncl
536 480 : ii = 2*(i - 1)
537 205520 : cpot(1:m) = cpot(1:m) + potential%gth_pot%cl(i)*(rad/rc)**ii*EXP(-0.5_dp*(rad/rc)**2)
538 : END DO
539 240 : IF (potential%gth_pot%lpotextended) THEN
540 0 : DO k = 1, potential%gth_pot%nexp_lpot
541 0 : al = potential%gth_pot%alpha_lpot(k)
542 0 : DO i = 1, potential%gth_pot%nct_lpot(k)
543 0 : ii = 2*(i - 1)
544 0 : cpot(1:m) = cpot(1:m) + potential%gth_pot%cval_lpot(i, k)*(rad/al)**ii*EXP(-0.5_dp*(rad/al)**2)
545 : END DO
546 : END DO
547 : END IF
548 240 : CALL numpot_matrix(integrals%core, cpot, basis, 0)
549 1680 : DO l = 0, lmat
550 1440 : n = integrals%n(l)
551 3560 : ALLOCATE (omat(n, n))
552 2280 : omat = 0._dp
553 : CALL sto_nuclear(omat(1:n, 1:n), basis%ns(1:n, l), basis%as(1:n, l), &
554 1440 : basis%ns(1:n, l), basis%as(1:n, l))
555 2280 : integrals%core(1:n, 1:n, l) = integrals%core(1:n, 1:n, l) - potential%gth_pot%zion*omat(1:n, 1:n)
556 1680 : DEALLOCATE (omat)
557 : END DO
558 :
559 240 : IF (potential%gth_pot%lsdpot) THEN
560 0 : cpot = 0._dp
561 0 : DO k = 1, potential%gth_pot%nexp_lsd
562 0 : al = potential%gth_pot%alpha_lsd(k)
563 0 : DO i = 1, potential%gth_pot%nct_lsd(k)
564 0 : ii = 2*(i - 1)
565 0 : cpot(:) = cpot + potential%gth_pot%cval_lsd(i, k)*(rad/al)**ii*EXP(-0.5_dp*(rad/al)**2)
566 : END DO
567 : END DO
568 0 : CALL numpot_matrix(integrals%clsd, cpot, basis, 0)
569 : END IF
570 :
571 1680 : DO l = 0, lmat
572 1440 : n = integrals%n(l)
573 : ! non local pseudopotential
574 3220 : ALLOCATE (spmat(n, 5))
575 10440 : spmat = 0._dp
576 1440 : k = potential%gth_pot%nl(l)
577 1688 : DO i = 1, k
578 248 : rc = potential%gth_pot%rcnl(l)
579 105848 : cpot(:) = sqrt2/SQRT(gamma1(l + 2*i - 1))*rad**(l + 2*i - 2)*EXP(-0.5_dp*(rad/rc)**2)/rc**(l + 2*i - 0.5_dp)
580 1872 : DO j = 1, basis%nbas(l)
581 432 : spmat(j, i) = integrate_grid(cpot, basis%bf(:, j, l), basis%grid)
582 : END DO
583 : END DO
584 1440 : integrals%hnl(1:n, 1:n, l) = MATMUL(spmat(1:n, 1:k), &
585 3468 : MATMUL(potential%gth_pot%hnl(1:k, 1:k, l), &
586 4768 : TRANSPOSE(spmat(1:n, 1:k))))
587 1680 : DEALLOCATE (spmat)
588 : END DO
589 240 : DEALLOCATE (cpot)
590 :
591 : CASE (upf_pseudo)
592 0 : CALL upfint_setup(integrals, basis, potential)
593 : CASE (sgp_pseudo)
594 0 : CALL sgpint_setup(integrals, basis, potential)
595 : CASE DEFAULT
596 1288 : CPABORT("")
597 : END SELECT
598 :
599 : CASE (NUM_BASIS)
600 11622 : CPABORT("")
601 : END SELECT
602 :
603 : ! add ecp_pseudo using numerical representation of basis
604 11622 : IF (potential%ppot_type == ecp_pseudo) THEN
605 : ! scale 1/r potential
606 60 : IF (ANY(potential%ecp_pot%nrloc(1:potential%ecp_pot%nloc) == 1)) THEN
607 16 : alpha = 0.0_dp
608 80 : DO k = 1, potential%ecp_pot%nloc
609 64 : n = potential%ecp_pot%nrloc(k)
610 80 : IF (n == 1) alpha = alpha + potential%ecp_pot%aloc(k)
611 : END DO
612 688 : integrals%core = (alpha - potential%ecp_pot%zion)*integrals%core
613 : ELSE
614 11022 : integrals%core = -potential%ecp_pot%zion*integrals%core
615 : END IF
616 : ! local potential
617 34 : m = basis%grid%nr
618 34 : rad => basis%grid%rad
619 102 : ALLOCATE (cpot(1:m))
620 13634 : cpot = 0._dp
621 120 : DO k = 1, potential%ecp_pot%nloc
622 86 : n = potential%ecp_pot%nrloc(k)
623 86 : alpha = potential%ecp_pot%bloc(k)
624 120 : IF (n == 1) THEN
625 6416 : cpot(:) = cpot + potential%ecp_pot%aloc(k)/rad*(EXP(-alpha*rad**2) - 1.0_dp)
626 : ELSE
627 28070 : cpot(:) = cpot + potential%ecp_pot%aloc(k)*rad**(n - 2)*EXP(-alpha*rad**2)
628 : END IF
629 : END DO
630 34 : CALL numpot_matrix(integrals%core, cpot, basis, 0)
631 : ! non local pseudopotential
632 132 : DO l = 0, MIN(potential%ecp_pot%lmax, lmat)
633 39298 : cpot = 0._dp
634 372 : DO k = 1, potential%ecp_pot%npot(l)
635 274 : n = potential%ecp_pot%nrpot(k, l)
636 274 : alpha = potential%ecp_pot%bpot(k, l)
637 109972 : cpot(:) = cpot + potential%ecp_pot%apot(k, l)*rad**(n - 2)*EXP(-alpha*rad**2)
638 : END DO
639 644 : DO i = 1, basis%nbas(l)
640 3910 : DO j = i, basis%nbas(l)
641 3300 : integrals%hnl(i, j, l) = integrate_grid(cpot, basis%bf(:, i, l), basis%bf(:, j, l), basis%grid)
642 3812 : integrals%hnl(j, i, l) = integrals%hnl(i, j, l)
643 : END DO
644 : END DO
645 : END DO
646 34 : DEALLOCATE (cpot)
647 : END IF
648 :
649 : END IF
650 :
651 11626 : CALL timestop(handle)
652 :
653 23252 : END SUBROUTINE atom_ppint_setup
654 :
655 : ! **************************************************************************************************
656 : !> \brief ...
657 : !> \param integrals ...
658 : !> \param basis ...
659 : !> \param potential ...
660 : ! **************************************************************************************************
661 4 : SUBROUTINE upfint_setup(integrals, basis, potential)
662 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
663 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
664 : TYPE(atom_potential_type), INTENT(IN) :: potential
665 :
666 : CHARACTER(len=4) :: ptype
667 : INTEGER :: i, j, k1, k2, la, lb, m, n
668 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: spot
669 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: spmat
670 : TYPE(atom_basis_type) :: gbasis
671 :
672 : ! get basis representation on UPF grid
673 4 : CALL atom_basis_gridrep(basis, gbasis, potential%upf_pot%r, potential%upf_pot%rab)
674 :
675 : ! local pseudopotential
676 6556 : integrals%core = 0._dp
677 4 : CALL numpot_matrix(integrals%core, potential%upf_pot%vlocal, gbasis, 0)
678 :
679 4 : ptype = ADJUSTL(TRIM(potential%upf_pot%pseudo_type))
680 4 : IF (ptype(1:2) == "NC" .OR. ptype(1:2) == "US") THEN
681 : ! non local pseudopotential
682 14 : n = MAXVAL(integrals%n(:))
683 2 : m = potential%upf_pot%number_of_proj
684 8 : ALLOCATE (spmat(n, m))
685 36 : spmat = 0.0_dp
686 4 : DO i = 1, m
687 2 : la = potential%upf_pot%lbeta(i)
688 36 : DO j = 1, gbasis%nbas(la)
689 34 : spmat(j, i) = integrate_grid(potential%upf_pot%beta(:, i), gbasis%bf(:, j, la), gbasis%grid)
690 : END DO
691 : END DO
692 4 : DO i = 1, m
693 2 : la = potential%upf_pot%lbeta(i)
694 6 : DO j = 1, m
695 2 : lb = potential%upf_pot%lbeta(j)
696 4 : IF (la == lb) THEN
697 34 : DO k1 = 1, gbasis%nbas(la)
698 546 : DO k2 = 1, gbasis%nbas(la)
699 : integrals%hnl(k1, k2, la) = integrals%hnl(k1, k2, la) + &
700 544 : spmat(k1, i)*potential%upf_pot%dion(i, j)*spmat(k2, j)
701 : END DO
702 : END DO
703 : END IF
704 : END DO
705 : END DO
706 2 : DEALLOCATE (spmat)
707 2 : ELSE IF (ptype(1:2) == "SL") THEN
708 : ! semi local pseudopotential
709 10 : DO la = 0, potential%upf_pot%l_max
710 8 : IF (la == potential%upf_pot%l_local) CYCLE
711 6 : m = SIZE(potential%upf_pot%vsemi(:, la + 1))
712 18 : ALLOCATE (spot(m))
713 2772 : spot(:) = potential%upf_pot%vsemi(:, la + 1) - potential%upf_pot%vlocal(:)
714 6 : n = basis%nbas(la)
715 102 : DO i = 1, n
716 918 : DO j = i, n
717 : integrals%core(i, j, la) = integrals%core(i, j, la) + &
718 : integrate_grid(spot(:), &
719 816 : gbasis%bf(:, i, la), gbasis%bf(:, j, la), gbasis%grid)
720 912 : integrals%core(j, i, la) = integrals%core(i, j, la)
721 : END DO
722 : END DO
723 10 : DEALLOCATE (spot)
724 : END DO
725 : ELSE
726 0 : CPABORT("Pseudopotential type: ["//ADJUSTL(TRIM(ptype))//"] not known")
727 : END IF
728 :
729 : ! release basis representation on UPF grid
730 4 : CALL release_atom_basis(gbasis)
731 :
732 80 : END SUBROUTINE upfint_setup
733 :
734 : ! **************************************************************************************************
735 : !> \brief ...
736 : !> \param integrals ...
737 : !> \param basis ...
738 : !> \param potential ...
739 : ! **************************************************************************************************
740 12 : SUBROUTINE sgpint_setup(integrals, basis, potential)
741 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
742 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
743 : TYPE(atom_potential_type), INTENT(IN) :: potential
744 :
745 : INTEGER :: i, ia, j, l, m, n, na
746 : REAL(KIND=dp) :: a, c, rc, zval
747 12 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: cpot, pgauss
748 12 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: qmat
749 12 : REAL(KIND=dp), DIMENSION(:), POINTER :: rad
750 :
751 12 : rad => basis%grid%rad
752 12 : m = basis%grid%nr
753 :
754 : ! local pseudopotential
755 1524 : integrals%core = 0._dp
756 36 : ALLOCATE (cpot(m))
757 4812 : cpot = 0.0_dp
758 12 : zval = potential%sgp_pot%zion
759 4812 : DO i = 1, m
760 4800 : rc = rad(i)/potential%sgp_pot%ac_local/SQRT(2.0_dp)
761 4812 : cpot(i) = cpot(i) - zval/rad(i)*erf(rc)
762 : END DO
763 156 : DO i = 1, potential%sgp_pot%n_local
764 57756 : cpot(:) = cpot(:) + potential%sgp_pot%c_local(i)*EXP(-potential%sgp_pot%a_local(i)*rad(:)**2)
765 : END DO
766 12 : CALL numpot_matrix(integrals%core, cpot, basis, 0)
767 12 : DEALLOCATE (cpot)
768 :
769 : ! nonlocal pseudopotential
770 1524 : integrals%hnl = 0.0_dp
771 12 : IF (potential%sgp_pot%has_nonlocal) THEN
772 18 : ALLOCATE (pgauss(1:m))
773 6 : n = potential%sgp_pot%n_nonlocal
774 : !
775 12 : DO l = 0, potential%sgp_pot%lmax
776 6 : CPASSERT(l <= UBOUND(basis%nbas, 1))
777 6 : IF (.NOT. potential%sgp_pot%is_nonlocal(l)) CYCLE
778 : ! overlap (a|p)
779 6 : na = basis%nbas(l)
780 24 : ALLOCATE (qmat(na, n))
781 54 : DO i = 1, n
782 19248 : pgauss(:) = 0.0_dp
783 432 : DO j = 1, n
784 384 : a = potential%sgp_pot%a_nonlocal(j)
785 384 : c = potential%sgp_pot%c_nonlocal(j, i, l)
786 154032 : pgauss(:) = pgauss(:) + c*EXP(-a*rad(:)**2)*rad(:)**l
787 : END DO
788 246 : DO ia = 1, na
789 77040 : qmat(ia, i) = SUM(basis%bf(:, ia, l)*pgauss(:)*basis%grid%wr(:))
790 : END DO
791 : END DO
792 30 : DO i = 1, na
793 90 : DO j = i, na
794 540 : DO ia = 1, n
795 : integrals%hnl(i, j, l) = integrals%hnl(i, j, l) &
796 540 : + qmat(i, ia)*qmat(j, ia)*potential%sgp_pot%h_nonlocal(ia, l)
797 : END DO
798 84 : integrals%hnl(j, i, l) = integrals%hnl(i, j, l)
799 : END DO
800 : END DO
801 12 : DEALLOCATE (qmat)
802 : END DO
803 6 : DEALLOCATE (pgauss)
804 : END IF
805 :
806 24 : END SUBROUTINE sgpint_setup
807 :
808 : ! **************************************************************************************************
809 : !> \brief ...
810 : !> \param integrals ...
811 : !> \param basis ...
812 : !> \param reltyp ...
813 : !> \param zcore ...
814 : !> \param alpha ...
815 : ! **************************************************************************************************
816 10048 : SUBROUTINE atom_relint_setup(integrals, basis, reltyp, zcore, alpha)
817 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
818 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
819 : INTEGER, INTENT(IN) :: reltyp
820 : REAL(dp), INTENT(IN) :: zcore
821 : REAL(dp), INTENT(IN), OPTIONAL :: alpha
822 :
823 : CHARACTER(len=*), PARAMETER :: routineN = 'atom_relint_setup'
824 :
825 : INTEGER :: dkhorder, handle, i, k1, k2, l, m, n, nl
826 : REAL(dp) :: ascal
827 10048 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: cpot
828 10048 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: modpot
829 10048 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: ener, sps
830 10048 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: hmat, pvp, sp, tp, vp, wfn
831 :
832 10048 : CALL timeset(routineN, handle)
833 :
834 10048 : SELECT CASE (reltyp)
835 : CASE DEFAULT
836 0 : CPABORT("")
837 : CASE (do_nonrel_atom, do_zoramp_atom, do_sczoramp_atom)
838 9976 : dkhorder = -1
839 : CASE (do_dkh0_atom)
840 2 : dkhorder = 0
841 : CASE (do_dkh1_atom)
842 2 : dkhorder = 1
843 : CASE (do_dkh2_atom)
844 30 : dkhorder = 2
845 : CASE (do_dkh3_atom)
846 10048 : dkhorder = 3
847 : END SELECT
848 :
849 0 : SELECT CASE (reltyp)
850 : CASE DEFAULT
851 0 : CPABORT("")
852 : CASE (do_nonrel_atom)
853 : ! nothing to do
854 9948 : NULLIFY (integrals%tzora, integrals%hdkh)
855 : CASE (do_zoramp_atom, do_sczoramp_atom)
856 :
857 28 : NULLIFY (integrals%hdkh)
858 :
859 28 : IF (integrals%zorastat == 0) THEN
860 196 : n = MAXVAL(basis%nbas)
861 140 : ALLOCATE (integrals%tzora(n, n, 0:lmat))
862 133636 : integrals%tzora = 0._dp
863 28 : m = basis%grid%nr
864 112 : ALLOCATE (modpot(1:m), cpot(1:m))
865 28 : CALL calculate_model_potential(modpot, basis%grid, zcore)
866 : ! Zora potential
867 11228 : cpot(1:m) = modpot(1:m)/(4._dp*c_light_au*c_light_au - 2._dp*modpot(1:m))
868 11228 : cpot(1:m) = cpot(1:m)/basis%grid%rad2(1:m)
869 28 : CALL numpot_matrix(integrals%tzora, cpot, basis, 0)
870 196 : DO l = 0, lmat
871 168 : nl = basis%nbas(l)
872 123660 : integrals%tzora(1:nl, 1:nl, l) = REAL(l*(l + 1), dp)*integrals%tzora(1:nl, 1:nl, l)
873 : END DO
874 11228 : cpot(1:m) = cpot(1:m)*basis%grid%rad2(1:m)
875 28 : CALL numpot_matrix(integrals%tzora, cpot, basis, 2)
876 : !
877 : ! scaled ZORA
878 28 : IF (reltyp == do_sczoramp_atom) THEN
879 168 : ALLOCATE (hmat(n, n, 0:lmat), wfn(n, n, 0:lmat), ener(n, 0:lmat), pvp(n, n, 0:lmat), sps(n, n))
880 31946 : hmat(:, :, :) = integrals%kin + integrals%tzora
881 : ! model potential
882 14 : CALL numpot_matrix(hmat, modpot, basis, 0)
883 : ! eigenvalues and eigenvectors
884 14 : CALL atom_solve(hmat, integrals%utrans, wfn, ener, basis%nbas, integrals%nne, lmat)
885 : ! relativistic kinetic energy
886 5614 : cpot(1:m) = c_light_au*c_light_au/(2._dp*c_light_au*c_light_au - modpot(1:m))**2
887 5614 : cpot(1:m) = cpot(1:m)/basis%grid%rad2(1:m)
888 31946 : pvp = 0.0_dp
889 14 : CALL numpot_matrix(pvp, cpot, basis, 0)
890 98 : DO l = 0, lmat
891 84 : nl = basis%nbas(l)
892 24010 : pvp(1:nl, 1:nl, l) = REAL(l*(l + 1), dp)*pvp(1:nl, 1:nl, l)
893 : END DO
894 5614 : cpot(1:m) = cpot(1:m)*basis%grid%rad2(1:m)
895 14 : CALL numpot_matrix(pvp, cpot, basis, 2)
896 : ! calculate psi*pvp*psi and the scaled orbital energies
897 : ! actually, we directly calculate the energy difference
898 98 : DO l = 0, lmat
899 84 : nl = basis%nbas(l)
900 578 : DO i = 1, integrals%nne(l)
901 564 : IF (ener(i, l) < 0._dp) THEN
902 21276 : ascal = SUM(wfn(1:nl, i, l)*MATMUL(pvp(1:nl, 1:nl, l), wfn(1:nl, i, l)))
903 28 : ener(i, l) = ener(i, l)*ascal/(1.0_dp + ascal)
904 : ELSE
905 452 : ener(i, l) = 0.0_dp
906 : END IF
907 : END DO
908 : END DO
909 : ! correction term is calculated as a projector
910 31946 : hmat = 0.0_dp
911 98 : DO l = 0, lmat
912 84 : nl = basis%nbas(l)
913 564 : DO i = 1, integrals%nne(l)
914 14238 : DO k1 = 1, nl
915 494628 : DO k2 = 1, nl
916 494148 : hmat(k1, k2, l) = hmat(k1, k2, l) + ener(i, l)*wfn(k1, i, l)*wfn(k2, i, l)
917 : END DO
918 : END DO
919 : END DO
920 : ! transform with overlap matrix
921 84 : sps(1:nl, 1:nl) = MATMUL(integrals%ovlp(1:nl, 1:nl, l), &
922 410216 : MATMUL(hmat(1:nl, 1:nl, l), integrals%ovlp(1:nl, 1:nl, l)))
923 : ! add scaling correction to tzora
924 24010 : integrals%tzora(1:nl, 1:nl, l) = integrals%tzora(1:nl, 1:nl, l) - sps(1:nl, 1:nl)
925 : END DO
926 :
927 14 : DEALLOCATE (hmat, wfn, ener, pvp, sps)
928 : END IF
929 : !
930 28 : DEALLOCATE (modpot, cpot)
931 :
932 28 : integrals%zorastat = 1
933 :
934 : END IF
935 :
936 : CASE (do_dkh0_atom, do_dkh1_atom, do_dkh2_atom, do_dkh3_atom)
937 :
938 72 : NULLIFY (integrals%tzora)
939 :
940 10048 : IF (integrals%dkhstat == 0) THEN
941 504 : n = MAXVAL(basis%nbas)
942 360 : ALLOCATE (integrals%hdkh(n, n, 0:lmat))
943 321120 : integrals%hdkh = 0._dp
944 :
945 504 : m = MAXVAL(basis%nprim)
946 792 : ALLOCATE (tp(m, m, 0:lmat), sp(m, m, 0:lmat), vp(m, m, 0:lmat), pvp(m, m, 0:lmat))
947 334608 : tp = 0._dp
948 334608 : sp = 0._dp
949 334608 : vp = 0._dp
950 334608 : pvp = 0._dp
951 :
952 72 : SELECT CASE (basis%basis_type)
953 : CASE DEFAULT
954 0 : CPABORT("")
955 : CASE (GTO_BASIS, CGTO_BASIS)
956 :
957 504 : DO l = 0, lmat
958 432 : m = basis%nprim(l)
959 504 : IF (m > 0) THEN
960 272 : CALL sg_kinetic(tp(1:m, 1:m, l), l, basis%am(1:m, l), basis%am(1:m, l))
961 272 : CALL sg_overlap(sp(1:m, 1:m, l), l, basis%am(1:m, l), basis%am(1:m, l))
962 272 : IF (PRESENT(alpha)) THEN
963 36 : CALL sg_erfc(vp(1:m, 1:m, l), l, alpha, basis%am(1:m, l), basis%am(1:m, l))
964 : ELSE
965 236 : CALL sg_nuclear(vp(1:m, 1:m, l), l, basis%am(1:m, l), basis%am(1:m, l))
966 : END IF
967 272 : CALL sg_kinnuc(pvp(1:m, 1:m, l), l, basis%am(1:m, l), basis%am(1:m, l))
968 223656 : vp(1:m, 1:m, l) = -zcore*vp(1:m, 1:m, l)
969 223656 : pvp(1:m, 1:m, l) = -zcore*pvp(1:m, 1:m, l)
970 : END IF
971 : END DO
972 :
973 : CASE (STO_BASIS)
974 0 : CPABORT("")
975 : CASE (NUM_BASIS)
976 72 : CPABORT("")
977 : END SELECT
978 :
979 72 : CALL dkh_integrals(integrals, basis, dkhorder, sp, tp, vp, pvp)
980 :
981 72 : integrals%dkhstat = 1
982 :
983 72 : DEALLOCATE (tp, sp, vp, pvp)
984 :
985 : ELSE
986 0 : CPASSERT(ASSOCIATED(integrals%hdkh))
987 : END IF
988 :
989 : END SELECT
990 :
991 10048 : CALL timestop(handle)
992 :
993 10048 : END SUBROUTINE atom_relint_setup
994 :
995 : ! **************************************************************************************************
996 : !> \brief ...
997 : !> \param integrals ...
998 : !> \param basis ...
999 : !> \param order ...
1000 : !> \param sp ...
1001 : !> \param tp ...
1002 : !> \param vp ...
1003 : !> \param pvp ...
1004 : ! **************************************************************************************************
1005 72 : SUBROUTINE dkh_integrals(integrals, basis, order, sp, tp, vp, pvp)
1006 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
1007 : TYPE(atom_basis_type), INTENT(INOUT) :: basis
1008 : INTEGER, INTENT(IN) :: order
1009 : REAL(dp), DIMENSION(:, :, 0:) :: sp, tp, vp, pvp
1010 :
1011 : INTEGER :: l, m, n
1012 72 : REAL(dp), DIMENSION(:, :, :), POINTER :: hdkh
1013 :
1014 0 : CPASSERT(order >= 0)
1015 :
1016 72 : hdkh => integrals%hdkh
1017 :
1018 504 : DO l = 0, lmat
1019 432 : n = integrals%n(l)
1020 432 : m = basis%nprim(l)
1021 504 : IF (n > 0) THEN
1022 272 : CALL dkh_atom_transformation(sp(1:m, 1:m, l), vp(1:m, 1:m, l), tp(1:m, 1:m, l), pvp(1:m, 1:m, l), m, order)
1023 272 : SELECT CASE (basis%basis_type)
1024 : CASE DEFAULT
1025 0 : CPABORT("")
1026 : CASE (GTO_BASIS)
1027 222 : CPASSERT(n == m)
1028 219890 : integrals%hdkh(1:n, 1:n, l) = tp(1:n, 1:n, l) + vp(1:n, 1:n, l)
1029 : CASE (CGTO_BASIS)
1030 50 : CALL contract2(integrals%hdkh(1:n, 1:n, l), tp(1:m, 1:m, l), basis%cm(1:m, 1:n, l))
1031 50 : CALL contract2add(integrals%hdkh(1:n, 1:n, l), vp(1:m, 1:m, l), basis%cm(1:m, 1:n, l))
1032 : CASE (STO_BASIS)
1033 0 : CPABORT("")
1034 : CASE (NUM_BASIS)
1035 272 : CPABORT("")
1036 : END SELECT
1037 : ELSE
1038 160 : integrals%hdkh(1:n, 1:n, l) = 0._dp
1039 : END IF
1040 : END DO
1041 :
1042 72 : END SUBROUTINE dkh_integrals
1043 :
1044 : ! **************************************************************************************************
1045 : !> \brief Calculate overlap matrix between two atomic basis sets.
1046 : !> \param ovlap overlap matrix <chi_{a,l} | chi_{b,l}>
1047 : !> \param basis_a first basis set
1048 : !> \param basis_b second basis set
1049 : ! **************************************************************************************************
1050 1 : SUBROUTINE atom_basis_projection_overlap(ovlap, basis_a, basis_b)
1051 : REAL(KIND=dp), DIMENSION(:, :, 0:), INTENT(OUT) :: ovlap
1052 : TYPE(atom_basis_type), INTENT(IN) :: basis_a, basis_b
1053 :
1054 : INTEGER :: i, j, l, ma, mb, na, nb
1055 : LOGICAL :: ebas
1056 1 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: omat
1057 :
1058 1 : ebas = (basis_a%basis_type == basis_b%basis_type)
1059 :
1060 127 : ovlap = 0.0_dp
1061 :
1062 1 : IF (ebas) THEN
1063 0 : SELECT CASE (basis_a%basis_type)
1064 : CASE DEFAULT
1065 0 : CPABORT("")
1066 : CASE (GTO_BASIS)
1067 0 : DO l = 0, lmat
1068 0 : na = basis_a%nbas(l)
1069 0 : nb = basis_b%nbas(l)
1070 0 : CALL sg_overlap(ovlap(1:na, 1:nb, l), l, basis_a%am(1:na, l), basis_b%am(1:nb, l))
1071 : END DO
1072 : CASE (CGTO_BASIS)
1073 7 : DO l = 0, lmat
1074 6 : na = basis_a%nbas(l)
1075 6 : nb = basis_b%nbas(l)
1076 6 : ma = basis_a%nprim(l)
1077 6 : mb = basis_b%nprim(l)
1078 18 : ALLOCATE (omat(ma, mb))
1079 6 : CALL sg_overlap(omat(1:ma, 1:mb), l, basis_a%am(1:ma, l), basis_b%am(1:mb, l))
1080 6 : ovlap(1:na, 1:nb, l) = MATMUL(TRANSPOSE(basis_a%cm(1:ma, 1:na, l)), &
1081 1277 : MATMUL(omat(1:ma, 1:mb), basis_b%cm(1:mb, 1:nb, l)))
1082 7 : DEALLOCATE (omat)
1083 : END DO
1084 : CASE (STO_BASIS)
1085 0 : DO l = 0, lmat
1086 0 : na = basis_a%nbas(l)
1087 0 : nb = basis_b%nbas(l)
1088 : CALL sto_overlap(ovlap(1:na, 1:nb, l), basis_a%ns(1:na, l), basis_b%as(1:nb, l), &
1089 0 : basis_a%ns(1:na, l), basis_b%as(1:nb, l))
1090 : END DO
1091 : CASE (NUM_BASIS)
1092 0 : CPASSERT(atom_compare_grids(basis_a%grid, basis_b%grid))
1093 1 : DO l = 0, lmat
1094 0 : na = basis_a%nbas(l)
1095 0 : nb = basis_b%nbas(l)
1096 0 : DO j = 1, nb
1097 0 : DO i = 1, na
1098 0 : ovlap(i, j, l) = integrate_grid(basis_a%bf(:, i, l), basis_b%bf(:, j, l), basis_a%grid)
1099 : END DO
1100 : END DO
1101 : END DO
1102 : END SELECT
1103 : ELSE
1104 0 : CPASSERT(atom_compare_grids(basis_a%grid, basis_b%grid))
1105 0 : DO l = 0, lmat
1106 0 : na = basis_a%nbas(l)
1107 0 : nb = basis_b%nbas(l)
1108 0 : DO j = 1, nb
1109 0 : DO i = 1, na
1110 0 : ovlap(i, j, l) = integrate_grid(basis_a%bf(:, i, l), basis_b%bf(:, j, l), basis_a%grid)
1111 : END DO
1112 : END DO
1113 : END DO
1114 : END IF
1115 :
1116 1 : END SUBROUTINE atom_basis_projection_overlap
1117 :
1118 : ! **************************************************************************************************
1119 : !> \brief Release memory allocated for atomic integrals (valence electrons).
1120 : !> \param integrals atomic integrals
1121 : ! **************************************************************************************************
1122 11300 : SUBROUTINE atom_int_release(integrals)
1123 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
1124 :
1125 : INTEGER :: ll
1126 :
1127 11300 : IF (ASSOCIATED(integrals%ovlp)) THEN
1128 11300 : DEALLOCATE (integrals%ovlp)
1129 : END IF
1130 11300 : IF (ASSOCIATED(integrals%kin)) THEN
1131 11300 : DEALLOCATE (integrals%kin)
1132 : END IF
1133 11300 : IF (ASSOCIATED(integrals%conf)) THEN
1134 8638 : DEALLOCATE (integrals%conf)
1135 : END IF
1136 1141300 : DO ll = 1, SIZE(integrals%ceri)
1137 1130000 : IF (ASSOCIATED(integrals%ceri(ll)%int)) THEN
1138 1218 : DEALLOCATE (integrals%ceri(ll)%int)
1139 : END IF
1140 1141300 : IF (ASSOCIATED(integrals%eeri(ll)%int)) THEN
1141 2128 : DEALLOCATE (integrals%eeri(ll)%int)
1142 : END IF
1143 : END DO
1144 11300 : IF (ASSOCIATED(integrals%utrans)) THEN
1145 11300 : DEALLOCATE (integrals%utrans)
1146 : END IF
1147 11300 : IF (ASSOCIATED(integrals%uptrans)) THEN
1148 11300 : DEALLOCATE (integrals%uptrans)
1149 : END IF
1150 :
1151 11300 : integrals%status = 0
1152 :
1153 11300 : END SUBROUTINE atom_int_release
1154 :
1155 : ! **************************************************************************************************
1156 : !> \brief Release memory allocated for atomic integrals (core electrons).
1157 : !> \param integrals atomic integrals
1158 : ! **************************************************************************************************
1159 11622 : SUBROUTINE atom_ppint_release(integrals)
1160 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
1161 :
1162 11622 : IF (ASSOCIATED(integrals%hnl)) THEN
1163 11622 : DEALLOCATE (integrals%hnl)
1164 : END IF
1165 11622 : IF (ASSOCIATED(integrals%core)) THEN
1166 11622 : DEALLOCATE (integrals%core)
1167 : END IF
1168 11622 : IF (ASSOCIATED(integrals%clsd)) THEN
1169 11622 : DEALLOCATE (integrals%clsd)
1170 : END IF
1171 :
1172 11622 : integrals%ppstat = 0
1173 :
1174 11622 : END SUBROUTINE atom_ppint_release
1175 :
1176 : ! **************************************************************************************************
1177 : !> \brief Release memory allocated for atomic integrals (relativistic effects).
1178 : !> \param integrals atomic integrals
1179 : ! **************************************************************************************************
1180 11290 : SUBROUTINE atom_relint_release(integrals)
1181 : TYPE(atom_integrals), INTENT(INOUT) :: integrals
1182 :
1183 11290 : IF (ASSOCIATED(integrals%tzora)) THEN
1184 28 : DEALLOCATE (integrals%tzora)
1185 : END IF
1186 11290 : IF (ASSOCIATED(integrals%hdkh)) THEN
1187 72 : DEALLOCATE (integrals%hdkh)
1188 : END IF
1189 :
1190 11290 : integrals%zorastat = 0
1191 11290 : integrals%dkhstat = 0
1192 :
1193 11290 : END SUBROUTINE atom_relint_release
1194 :
1195 : ! **************************************************************************************************
1196 : !> \brief Calculate model potential. It is useful to guess atomic orbitals.
1197 : !> \param modpot model potential
1198 : !> \param grid atomic radial grid
1199 : !> \param zcore nuclear charge
1200 : ! **************************************************************************************************
1201 72 : SUBROUTINE calculate_model_potential(modpot, grid, zcore)
1202 : REAL(dp), DIMENSION(:), INTENT(INOUT) :: modpot
1203 : TYPE(grid_atom_type), INTENT(IN) :: grid
1204 : REAL(dp), INTENT(IN) :: zcore
1205 :
1206 : INTEGER :: i, ii, l, ll, n, z
1207 72 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: pot, rho
1208 : TYPE(atom_state) :: state
1209 :
1210 72 : n = SIZE(modpot)
1211 288 : ALLOCATE (rho(n), pot(n))
1212 :
1213 : ! fill default occupation
1214 5112 : state%core = 0._dp
1215 5112 : state%occ = 0._dp
1216 72 : state%multiplicity = -1
1217 72 : z = NINT(zcore)
1218 360 : DO l = 0, MIN(lmat, UBOUND(ptable(z)%e_conv, 1))
1219 360 : IF (ptable(z)%e_conv(l) /= 0) THEN
1220 156 : state%maxl_occ = l
1221 156 : ll = 2*(2*l + 1)
1222 360 : DO i = 1, SIZE(state%occ, 2)
1223 360 : ii = ptable(z)%e_conv(l) - (i - 1)*ll
1224 360 : IF (ii <= ll) THEN
1225 156 : state%occ(l, i) = ii
1226 156 : EXIT
1227 : ELSE
1228 204 : state%occ(l, i) = ll
1229 : END IF
1230 : END DO
1231 : END IF
1232 : END DO
1233 :
1234 13410 : modpot = -zcore/grid%rad(:)
1235 :
1236 : ! Coulomb potential
1237 72 : CALL slater_density(rho, pot, NINT(zcore), state, grid)
1238 72 : CALL coulomb_potential_numeric(pot, rho, grid)
1239 13410 : modpot = modpot + pot
1240 :
1241 : ! XC potential
1242 72 : CALL wigner_slater_functional(rho, pot)
1243 13410 : modpot = modpot + pot
1244 :
1245 72 : DEALLOCATE (rho, pot)
1246 :
1247 26136 : END SUBROUTINE calculate_model_potential
1248 :
1249 14235 : END MODULE atom_operators
|