(git:374b731)
Loading...
Searching...
No Matches
semi_empirical_int_utils.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 Utilities for Integrals for semi-empiric methods
10!> \author Teodoro Laino (03.2008) [tlaino] - University of Zurich
11! **************************************************************************************************
13
16 USE kinds, ONLY: dp
20 USE semi_empirical_int_arrays, ONLY: &
28#include "./base/base_uses.f90"
29
30 IMPLICIT NONE
31 PRIVATE
32
33
34! **************************************************************************************************
35!> \brief Debug the derivatives of the the rotational matrices
36!>
37!> \author Teodoro Laino [tlaino] - University of Zurich
38!> \date 04.2008 [tlaino]
39! **************************************************************************************************
40INTERFACE
41 SUBROUTINE check_rotmat_der(sepi, sepj, rjiv, ij_matrix, do_invert)
42 USE kinds, ONLY: dp
45 TYPE(semi_empirical_type), POINTER :: sepi, sepj
46 REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: rjiv
47 TYPE(rotmat_type), POINTER :: ij_matrix
48 LOGICAL, INTENT(IN) :: do_invert
49
50 END SUBROUTINE check_rotmat_der
51END INTERFACE
52
53! **************************************************************************************************
54!> \brief Check Numerical Vs Analytical NUCINT ssss
55!> \note
56!> Debug routine
57!> \par History
58!> 04.2008 created [tlaino]
59!> \author Teodoro Laino - Zurich University
60! **************************************************************************************************
61INTERFACE
62 SUBROUTINE check_dssss_nucint_ana(sepi, sepj, r, dssss, itype, se_int_control, &
63 se_taper)
64 USE kinds, ONLY: dp
68 TYPE(semi_empirical_type), POINTER :: sepi, sepj
69 REAL(dp), INTENT(IN) :: r, dssss
70 INTEGER, INTENT(IN) :: itype
71 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
72 TYPE(se_taper_type), POINTER :: se_taper
73
74 END SUBROUTINE check_dssss_nucint_ana
75END INTERFACE
76
77! **************************************************************************************************
78!> \brief Check Numerical Vs Analytical NUCINT core
79!> \note
80!> Debug routine
81!> \par History
82!> 04.2008 created [tlaino]
83!> \author Teodoro Laino - Zurich University
84! **************************************************************************************************
85INTERFACE
86 SUBROUTINE check_dcore_nucint_ana(sepi, sepj, r, dcore, itype, se_int_control, &
87 se_taper)
88 USE kinds, ONLY: dp
92 TYPE(semi_empirical_type), POINTER :: sepi, sepj
93 REAL(dp), INTENT(IN) :: r
94 REAL(dp), DIMENSION(10, 2), INTENT(IN) :: dcore
95 INTEGER, INTENT(IN) :: itype
96 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
97 TYPE(se_taper_type), POINTER :: se_taper
98
99 END SUBROUTINE check_dcore_nucint_ana
100END INTERFACE
101
102! **************************************************************************************************
103!> \brief Check Numerical Vs Analytical ROTNUC
104!> \note
105!> Debug routine
106!> \par History
107!> 04.2008 created [tlaino]
108!> \author Teodoro Laino - Zurich University
109! **************************************************************************************************
110INTERFACE
111 SUBROUTINE check_drotnuc_ana(sepi, sepj, rijv, itype, se_int_control, se_taper, &
112 e1b, e2a, de1b, de2a)
113 USE kinds, ONLY: dp
117 TYPE(semi_empirical_type), POINTER :: sepi, sepj
118 REAL(dp), DIMENSION(3), INTENT(IN) :: rijv
119 INTEGER, INTENT(IN) :: itype
120 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
121 TYPE(se_taper_type), POINTER :: se_taper
122 REAL(dp), DIMENSION(45), INTENT(IN), OPTIONAL :: e1b, e2a
123 REAL(dp), DIMENSION(45, 3), INTENT(IN), OPTIONAL :: de1b, de2a
124
125 END SUBROUTINE check_drotnuc_ana
126END INTERFACE
127
128! **************************************************************************************************
129!> \brief Check Numerical Vs Analytical CORECORE
130!> \note
131!> Debug routine
132!> \par History
133!> 04.2008 created [tlaino]
134!> \author Teodoro Laino - Zurich University
135! **************************************************************************************************
136INTERFACE
137 SUBROUTINE check_dcorecore_ana(sepi, sepj, rijv, itype, se_int_control, &
138 se_taper, enuc, denuc)
139 USE kinds, ONLY: dp
143 TYPE(semi_empirical_type), POINTER :: sepi, sepj
144 REAL(dp), DIMENSION(3), INTENT(IN) :: rijv
145 INTEGER, INTENT(IN) :: itype
146 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
147 TYPE(se_taper_type), POINTER :: se_taper
148 REAL(dp), INTENT(IN), OPTIONAL :: enuc
149 REAL(dp), DIMENSION(3), INTENT(IN), OPTIONAL :: denuc
150
151 END SUBROUTINE check_dcorecore_ana
152
153END INTERFACE
154
155! **************************************************************************************************
156!> \brief Check Numerical Vs Analytical rot_2el_2c_first
157!> \note
158!> Debug routine
159!> \par History
160!> 04.2008 created [tlaino]
161!> \author Teodoro Laino - Zurich University
162! **************************************************************************************************
163INTERFACE
164 SUBROUTINE rot_2el_2c_first_debug(sepi, sepj, rijv, se_int_control, se_taper, &
165 invert, ii, kk, v_d)
166 USE kinds, ONLY: dp
170 TYPE(semi_empirical_type), POINTER :: sepi, sepj
171 REAL(KIND=dp), DIMENSION(3), INTENT(IN) :: rijv
172 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
173 TYPE(se_taper_type), POINTER :: se_taper
174 LOGICAL, INTENT(IN) :: invert
175 INTEGER, INTENT(IN) :: ii, kk
176 REAL(KIND=dp), DIMENSION(45, 45, 3), INTENT(IN) :: v_d
177
178 END SUBROUTINE rot_2el_2c_first_debug
179END INTERFACE
180
181! **************************************************************************************************
182!> \brief Check Numerical Vs Analytical check_dterep_ana
183!> \note
184!> Debug routine
185!> \par History
186!> 04.2008 created [tlaino]
187!> \author Teodoro Laino - Zurich University
188! **************************************************************************************************
189INTERFACE
190 SUBROUTINE check_dterep_ana(sepi, sepj, r, ri, dri, se_int_control, se_taper, lgrad)
191 USE kinds, ONLY: dp
195 TYPE(semi_empirical_type), POINTER :: sepi, sepj
196 REAL(dp), INTENT(IN) :: r
197 REAL(dp), DIMENSION(491), INTENT(IN) :: ri, dri
198 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
199 TYPE(se_taper_type), POINTER :: se_taper
200 LOGICAL, INTENT(IN) :: lgrad
201
202 END SUBROUTINE check_dterep_ana
203END INTERFACE
204
205! **************************************************************************************************
206!> \brief Check Numerical Vs Analytical check_rotint_ana
207!> \note
208!> Debug routine
209!> \par History
210!> 04.2008 created [tlaino]
211!> \author Teodoro Laino - Zurich University
212! **************************************************************************************************
213INTERFACE
214 SUBROUTINE check_rotint_ana(sepi, sepj, rijv, w, dw, se_int_control, se_taper)
215 USE kinds, ONLY: dp
219 TYPE(semi_empirical_type), POINTER :: sepi, sepj
220 REAL(dp), DIMENSION(3), INTENT(IN) :: rijv
221 REAL(dp), DIMENSION(2025), INTENT(IN), OPTIONAL :: w
222 REAL(dp), DIMENSION(2025, 3), INTENT(IN), OPTIONAL :: dw
223 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
224 TYPE(se_taper_type), POINTER :: se_taper
225
226 END SUBROUTINE check_rotint_ana
227END INTERFACE
228
229 LOGICAL, PARAMETER, PRIVATE :: debug_this_module = .false.
230 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'semi_empirical_int_utils'
231
234
235 abstract INTERFACE
236! **************************************************************************************************
237!> \brief ...
238!> \param r ...
239!> \param l1_i ...
240!> \param l2_i ...
241!> \param m1_i ...
242!> \param m2_i ...
243!> \param da_i ...
244!> \param db_i ...
245!> \param add0 ...
246!> \param fact_screen ...
247!> \return ...
248! **************************************************************************************************
249 FUNCTION eval_func_sp(r, l1_i, l2_i, m1_i, m2_i, da_i, db_i, add0, fact_screen) RESULT(charg)
250 USE kinds, ONLY: dp
251 REAL(KIND=dp), INTENT(IN) :: r
252 INTEGER, INTENT(IN) :: l1_i, l2_i, m1_i, m2_i
253 REAL(KIND=dp), INTENT(IN) :: da_i, db_i, add0, fact_screen
254 REAL(KIND=dp) :: charg
255
256 END FUNCTION eval_func_sp
257 END INTERFACE
258
259 abstract INTERFACE
260! **************************************************************************************************
261!> \brief ...
262!> \param r ...
263!> \param l1_i ...
264!> \param l2_i ...
265!> \param m ...
266!> \param da_i ...
267!> \param db_i ...
268!> \param add0 ...
269!> \param fact_screen ...
270!> \return ...
271! **************************************************************************************************
272 FUNCTION eval_func_d(r, l1_i, l2_i, m, da_i, db_i, add0, fact_screen) RESULT(charg)
273 USE kinds, ONLY: dp
274 REAL(KIND=dp), INTENT(IN) :: r
275 INTEGER, INTENT(IN) :: l1_i, l2_i, m
276 REAL(KIND=dp), INTENT(IN) :: da_i, db_i, add0, fact_screen
277 REAL(KIND=dp) :: charg
278
279 END FUNCTION eval_func_d
280 END INTERFACE
281
282CONTAINS
283
284! **************************************************************************************************
285!> \brief General driver for computing semi-empirical integrals <ij|kl> with
286!> sp basis set. This code uses the old definitions of quadrupoles and
287!> therefore cannot be used for integrals involving d-orbitals (which
288!> require a definition of quadrupoles based on the rotational invariant
289!> property)
290!>
291!> \param sepi ...
292!> \param sepj ...
293!> \param ij ...
294!> \param kl ...
295!> \param li ...
296!> \param lj ...
297!> \param lk ...
298!> \param ll ...
299!> \param ic ...
300!> \param r ...
301!> \param se_int_control ...
302!> \param se_int_screen ...
303!> \param itype ...
304!> \return ...
305!> \date 04.2008 [tlaino]
306!> \author Teodoro Laino [tlaino] - University of Zurich
307! **************************************************************************************************
308 FUNCTION ijkl_sp(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, &
309 se_int_screen, itype) RESULT(res)
310 TYPE(semi_empirical_type), POINTER :: sepi, sepj
311 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
312 REAL(kind=dp), INTENT(IN) :: r
313 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
314 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
315 INTEGER, INTENT(IN) :: itype
316 REAL(kind=dp) :: res
317
318 res = ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
319 se_int_control%integral_screening, se_int_control%shortrange, &
320 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
321 itype, charg_int_nri)
322
323 ! If only the shortrange component is requested we can skip the rest
324 IF ((.NOT. se_int_control%pc_coulomb_int) .AND. (itype /= do_method_pchg)) THEN
325 ! Handle the 1/r^3 term, this term is ALWAYS false for KDSO-D integrals
326 IF (se_int_control%shortrange .AND. se_int_control%do_ewald_r3) THEN
327 res = res - ijkl_low_3(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, &
328 itype, charg_int_3)
329 END IF
330 END IF
331 END FUNCTION ijkl_sp
332
333! **************************************************************************************************
334!> \brief General driver for computing derivatives of semi-empirical integrals
335!> <ij|kl> with sp basis set.
336!> This code uses the old definitions of quadrupoles and therefore
337!> cannot be used for integrals involving d-orbitals (which requires a
338!> definition of quadrupoles based on the rotational invariant property)
339!>
340!> \param sepi ...
341!> \param sepj ...
342!> \param ij ...
343!> \param kl ...
344!> \param li ...
345!> \param lj ...
346!> \param lk ...
347!> \param ll ...
348!> \param ic ...
349!> \param r ...
350!> \param se_int_control ...
351!> \param se_int_screen ...
352!> \param itype ...
353!> \return ...
354!> \date 05.2008 [tlaino]
355!> \author Teodoro Laino [tlaino] - University of Zurich
356! **************************************************************************************************
357 FUNCTION d_ijkl_sp(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, &
358 se_int_screen, itype) RESULT(res)
359 TYPE(semi_empirical_type), POINTER :: sepi, sepj
360 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
361 REAL(kind=dp), INTENT(IN) :: r
362 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
363 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
364 INTEGER, INTENT(IN) :: itype
365 REAL(kind=dp) :: res
366
367 REAL(kind=dp) :: dfs, srd
368
369 IF (se_int_control%integral_screening == do_se_is_kdso_d) THEN
370 res = ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
371 se_int_control%integral_screening, .false., &
372 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
373 itype, dcharg_int_nri)
374
375 IF (.NOT. se_int_control%pc_coulomb_int) THEN
376 dfs = ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
377 se_int_control%integral_screening, .false., .false., &
378 se_int_control%max_multipole, itype, dcharg_int_nri_fs)
379 res = res + dfs*se_int_screen%dft
380
381 ! In case we need the shortrange part we have to evaluate an additional derivative
382 ! to handle the derivative of the Tapering term
383 IF (se_int_control%shortrange) THEN
384 srd = ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
385 se_int_control%integral_screening, .false., .true., &
386 se_int_control%max_multipole, itype, dcharg_int_nri)
387 res = res - srd
388 END IF
389 END IF
390 ELSE
391 res = ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
392 se_int_control%integral_screening, se_int_control%shortrange, &
393 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
394 itype, dcharg_int_nri)
395 END IF
396
397 ! If only the shortrange component is requested we can skip the rest
398 IF ((.NOT. se_int_control%pc_coulomb_int) .AND. (itype /= do_method_pchg)) THEN
399 ! Handle the 1/r^3 term, this term is ALWAYS false for KDSO-D integrals
400 IF (se_int_control%shortrange .AND. se_int_control%do_ewald_r3) THEN
401 res = res - ijkl_low_3(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, &
402 itype, dcharg_int_3)
403 END IF
404 END IF
405
406 END FUNCTION d_ijkl_sp
407
408! **************************************************************************************************
409!> \brief Low level general driver for computing semi-empirical integrals
410!> <ij|kl> and their derivatives with sp basis set only.
411!> This code uses the old definitions of quadrupoles and
412!> therefore cannot be used for integrals involving d-orbitals (which
413!> require a definition of quadrupoles based on the rotational invariant
414!> property)
415!>
416!> \param sepi ...
417!> \param sepj ...
418!> \param ij ...
419!> \param kl ...
420!> \param li ...
421!> \param lj ...
422!> \param lk ...
423!> \param ll ...
424!> \param ic ...
425!> \param r ...
426!> \param se_int_screen ...
427!> \param iscreen ...
428!> \param shortrange ...
429!> \param pc_coulomb_int ...
430!> \param max_multipole ...
431!> \param itype ...
432!> \param eval a function without explicit interface
433!> \return ...
434!> \date 05.2008 [tlaino]
435!> \author Teodoro Laino [tlaino] - University of Zurich
436! **************************************************************************************************
437 FUNCTION ijkl_sp_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
438 iscreen, shortrange, pc_coulomb_int, max_multipole, itype, eval) RESULT(res)
439 TYPE(semi_empirical_type), POINTER :: sepi, sepj
440 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
441 REAL(kind=dp), INTENT(IN) :: r
442 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
443 INTEGER, INTENT(IN) :: iscreen
444 LOGICAL, INTENT(IN) :: shortrange, pc_coulomb_int
445 INTEGER, INTENT(IN) :: max_multipole, itype
446
447 PROCEDURE(eval_func_sp) :: eval
448 REAL(kind=dp) :: res
449
450 INTEGER :: ccc, l1, l1max, l1min, l2, l2max, l2min, &
451 lij, lkl, lmin, m
452 REAL(kind=dp) :: add, chrg, dij, dkl, fact_ij, fact_kl, &
453 fact_screen, pij, pkl, s1, sum
454
455 l1min = abs(li - lj)
456 l1max = li + lj
457 lij = indexb(li + 1, lj + 1)
458 l2min = abs(lk - ll)
459 l2max = lk + ll
460 lkl = indexb(lk + 1, ll + 1)
461
462 l1max = min(l1max, 2)
463 l1min = min(l1min, 2)
464 l2max = min(l2max, 2)
465 l2min = min(l2min, 2)
466 sum = 0.0_dp
467 dij = 0.0_dp
468 dkl = 0.0_dp
469 fact_ij = 1.0_dp
470 fact_kl = 1.0_dp
471 fact_screen = 1.0_dp
472 IF (lij == 3) fact_ij = sqrt(2.0_dp)
473 IF (lkl == 3) fact_kl = sqrt(2.0_dp)
474 IF (.NOT. pc_coulomb_int) THEN
475 IF (iscreen == do_se_is_kdso_d) fact_screen = se_int_screen%ft
476 ! Standard value of the integral
477 DO l1 = l1min, l1max
478 IF (l1 == 0) THEN
479 IF (lij == 1) THEN
480 pij = sepi%ko(1)
481 IF (ic == -1 .OR. ic == 1) THEN
482 pij = sepi%ko(9)
483 END IF
484 ELSE IF (lij == 3) THEN
485 pij = sepi%ko(7)
486 END IF
487 ELSE
488 dij = sepi%cs(lij)*fact_ij
489 pij = sepi%ko(lij)
490 END IF
491 !
492 DO l2 = l2min, l2max
493 IF (l2 == 0) THEN
494 IF (lkl == 1) THEN
495 pkl = sepj%ko(1)
496 IF (ic == -1 .OR. ic == 2) THEN
497 pkl = sepj%ko(9)
498 END IF
499 ELSE IF (lkl == 3) THEN
500 pkl = sepj%ko(7)
501 END IF
502 ELSE
503 dkl = sepj%cs(lkl)*fact_kl
504 pkl = sepj%ko(lkl)
505 END IF
506 IF (itype == do_method_pchg) THEN
507 add = 0.0_dp
508 ELSE
509 add = (pij + pkl)**2
510 END IF
511 lmin = max(l1, l2)
512 s1 = 0.0_dp
513 DO m = -lmin, lmin
514 ccc = clm_sp(ij, l1, m)*clm_sp(kl, l2, m)
515 IF (abs(ccc) > epsilon(0.0_dp)) THEN
516 chrg = eval(r, l1, l2, clm_sp(ij, l1, m), clm_sp(kl, l2, m), dij, dkl, add, fact_screen)
517 s1 = s1 + chrg
518 END IF
519 END DO
520 sum = sum + s1
521 END DO
522 END DO
523 res = sum
524 END IF
525 ! Shortrange: Possibly computes pure Coulomb and subtract from the original integral value
526 IF (shortrange .OR. pc_coulomb_int) THEN
527 sum = 0.0_dp
528 dij = 0.0_dp
529 dkl = 0.0_dp
530 add = 0.0_dp
531 fact_screen = 0.0_dp
532 DO l1 = l1min, l1max
533 IF (l1 > max_multipole) cycle
534 IF (l1 /= 0) THEN
535 dij = sepi%cs(lij)*fact_ij
536 END IF
537 !
538 DO l2 = l2min, l2max
539 IF (l2 > max_multipole) cycle
540 IF (l2 /= 0) THEN
541 dkl = sepj%cs(lkl)*fact_kl
542 END IF
543 lmin = max(l1, l2)
544 s1 = 0.0_dp
545 DO m = -lmin, lmin
546 ccc = clm_sp(ij, l1, m)*clm_sp(kl, l2, m)
547 IF (abs(ccc) > epsilon(0.0_dp)) THEN
548 chrg = eval(r, l1, l2, clm_sp(ij, l1, m), clm_sp(kl, l2, m), dij, dkl, add, fact_screen)
549 s1 = s1 + chrg
550 END IF
551 END DO
552 sum = sum + s1
553 END DO
554 END DO
555 IF (pc_coulomb_int) res = sum
556 IF (shortrange) res = res - sum
557 END IF
558 END FUNCTION ijkl_sp_low
559
560! **************************************************************************************************
561!> \brief Interaction function between two point-charge configurations NDDO sp-code
562!> Non-Rotational Invariant definition of quadrupoles
563!> r - Distance r12
564!> l1,m - Quantum numbers for multipole of configuration 1
565!> l2,m - Quantum numbers for multipole of configuration 2
566!> da - charge separation of configuration 1
567!> db - charge separation of configuration 2
568!> add - additive term
569!>
570!> \param r ...
571!> \param l1_i ...
572!> \param l2_i ...
573!> \param m1_i ...
574!> \param m2_i ...
575!> \param da_i ...
576!> \param db_i ...
577!> \param add0 ...
578!> \param fact_screen ...
579!> \return ...
580!> \date 04.2008 [tlaino]
581!> \author Teodoro Laino [tlaino] - University of Zurich
582! **************************************************************************************************
583 FUNCTION charg_int_nri(r, l1_i, l2_i, m1_i, m2_i, da_i, db_i, add0, fact_screen) RESULT(charg)
584 REAL(kind=dp), INTENT(in) :: r
585 INTEGER, INTENT(in) :: l1_i, l2_i, m1_i, m2_i
586 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
587 REAL(kind=dp) :: charg
588
589 INTEGER :: l1, l2, m1, m2
590 REAL(kind=dp) :: add, da, db, dxdx, dxqxz, dzdz, dzqxx, &
591 dzqzz, fact, qqxx, qqzz, qxxqxx, &
592 qxxqyy, qxzqxz, xyxy, zzzz
593
594! Computing only Integral Values
595
596 IF (l1_i < l2_i) THEN
597 l1 = l1_i
598 l2 = l2_i
599 m1 = m1_i
600 m2 = m2_i
601 da = da_i
602 db = db_i
603 fact = 1.0_dp
604 ELSE IF (l1_i > l2_i) THEN
605 l1 = l2_i
606 l2 = l1_i
607 m1 = m2_i
608 m2 = m1_i
609 da = db_i
610 db = da_i
611 fact = (-1.0_dp)**(l1 + l2)
612 ELSE IF (l1_i == l2_i) THEN
613 l1 = l1_i
614 l2 = l2_i
615 IF (m1_i <= m2_i) THEN
616 m1 = m1_i
617 m2 = m2_i
618 da = da_i
619 db = db_i
620 ELSE
621 m1 = m2_i
622 m2 = m1_i
623 da = db_i
624 db = da_i
625 END IF
626 fact = 1.0_dp
627 END IF
628 add = add0*fact_screen
629 charg = 0.0_dp
630 ! Q - Q.
631 IF (l1 == 0 .AND. l2 == 0) THEN
632 charg = fact/sqrt(r**2 + add)
633 RETURN
634 END IF
635 ! Q - Z.
636 IF (l1 == 0 .AND. l2 == 1 .AND. m2 == clmz) THEN
637 charg = 1.0_dp/sqrt((r + db)**2 + add) - 1.0_dp/sqrt((r - db)**2 + add)
638 charg = charg*0.5_dp*fact
639 RETURN
640 END IF
641 ! Z - Z.
642 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmz .AND. m2 == clmz) THEN
643 dzdz = &
644 +1.0_dp/sqrt((r + da - db)**2 + add) + 1.0_dp/sqrt((r - da + db)**2 + add) &
645 - 1.0_dp/sqrt((r - da - db)**2 + add) - 1.0_dp/sqrt((r + da + db)**2 + add)
646 charg = dzdz*0.25_dp*fact
647 RETURN
648 END IF
649 ! X - X
650 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmp .AND. m2 == clmp) THEN
651 dxdx = 2.0_dp/sqrt(r**2 + (da - db)**2 + add) - 2.0_dp/sqrt(r**2 + (da + db)**2 + add)
652 charg = dxdx*0.25_dp*fact
653 RETURN
654 END IF
655 ! Q - ZZ
656 IF (l1 == 0 .AND. l2 == 2 .AND. m2 == clmzz) THEN
657 qqzz = 1.0_dp/sqrt((r - db)**2 + add) - 2.0_dp/sqrt(r**2 + add) + 1.0_dp/sqrt((r + db)**2 + add)
658 charg = qqzz*0.25_dp*fact
659 RETURN
660 END IF
661 ! Q - XX
662 IF (l1 == 0 .AND. l2 == 2 .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
663 qqxx = -1.0_dp/sqrt(r**2 + add) + 1.0_dp/sqrt(r**2 + add + db**2)
664 charg = qqxx*0.5_dp*fact
665 RETURN
666 END IF
667 ! Z - ZZ
668 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. m2 == clmzz) THEN
669 dzqzz = &
670 +1.0_dp/sqrt((r - da - db)**2 + add) - 2.0_dp/sqrt((r - da)**2 + add) &
671 + 1.0_dp/sqrt((r - da + db)**2 + add) - 1.0_dp/sqrt((r + da - db)**2 + add) &
672 + 2.0_dp/sqrt((r + da)**2 + add) - 1.0_dp/sqrt((r + da + db)**2 + add)
673 charg = dzqzz*0.125_dp*fact
674 RETURN
675 END IF
676 ! Z - XX
677 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
678 dzqxx = &
679 +1.0_dp/sqrt((r + da)**2 + add) - 1.0_dp/sqrt((r + da)**2 + add + db**2) &
680 - 1.0_dp/sqrt((r - da)**2 + add) + 1.0_dp/sqrt((r - da)**2 + add + db**2)
681 charg = dzqxx*0.25_dp*fact
682 RETURN
683 END IF
684 ! ZZ - ZZ
685 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. m2 == clmzz) THEN
686 zzzz = &
687 +1.0_dp/sqrt((r - da - db)**2 + add) + 1.0_dp/sqrt((r + da + db)**2 + add) &
688 + 1.0_dp/sqrt((r - da + db)**2 + add) + 1.0_dp/sqrt((r + da - db)**2 + add)
689 xyxy = &
690 +1.0_dp/sqrt((r - da)**2 + add) + 1.0_dp/sqrt((r + da)**2 + add) &
691 + 1.0_dp/sqrt((r - db)**2 + add) + 1.0_dp/sqrt((r + db)**2 + add) &
692 - 2.0_dp/sqrt(r**2 + add)
693 charg = (zzzz*0.0625_dp - xyxy*0.125_dp)*fact
694 RETURN
695 END IF
696 ! ZZ - XX
697 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. (m2 == clmxx .OR. m2 == clmyy)) THEN
698 zzzz = &
699 -1.0_dp/sqrt((r + da)**2 + add) + 1.0_dp/sqrt((r + da)**2 + db**2 + add) &
700 - 1.0_dp/sqrt((r - da)**2 + add) + 1.0_dp/sqrt((r - da)**2 + db**2 + add)
701 xyxy = &
702 +1.0_dp/sqrt(r**2 + db**2 + add) - 1.0_dp/sqrt(r**2 + add)
703 charg = (zzzz*0.125_dp - xyxy*0.25_dp)*fact
704 RETURN
705 END IF
706 ! X - ZX
707 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmp .AND. m2 == clmzp) THEN
708 db = db/2.0_dp
709 dxqxz = &
710 -1.0_dp/sqrt((r - db)**2 + (da - db)**2 + add) + 1.0_dp/sqrt((r + db)**2 + (da - db)**2 + add) &
711 + 1.0_dp/sqrt((r - db)**2 + (da + db)**2 + add) - 1.0_dp/sqrt((r + db)**2 + (da + db)**2 + add)
712 charg = dxqxz*0.25_dp*fact
713 RETURN
714 END IF
715 ! ZX - ZX
716 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzp .AND. m2 == clmzp) THEN
717 da = da/2.0_dp
718 db = db/2.0_dp
719 qxzqxz = &
720 +1.0_dp/sqrt((r + da - db)**2 + (da - db)**2 + add) - 1.0_dp/sqrt((r + da + db)**2 + (da - db)**2 + add) &
721 - 1.0_dp/sqrt((r - da - db)**2 + (da - db)**2 + add) + 1.0_dp/sqrt((r - da + db)**2 + (da - db)**2 + add) &
722 - 1.0_dp/sqrt((r + da - db)**2 + (da + db)**2 + add) + 1.0_dp/sqrt((r + da + db)**2 + (da + db)**2 + add) &
723 + 1.0_dp/sqrt((r - da - db)**2 + (da + db)**2 + add) - 1.0_dp/sqrt((r - da + db)**2 + (da + db)**2 + add)
724 charg = qxzqxz*0.125_dp*fact
725 RETURN
726 END IF
727 ! XX - XX
728 IF (l1 == 2 .AND. l2 == 2 .AND. (((m1 == clmyy) .AND. (m2 == clmyy)) .OR. ((m1 == clmxx) .AND. (m2 == clmxx)))) THEN
729 qxxqxx = &
730 +2.0_dp/sqrt(r**2 + add) + 1.0_dp/sqrt(r**2 + (da - db)**2 + add) &
731 + 1.0_dp/sqrt(r**2 + (da + db)**2 + add) - 2.0_dp/sqrt(r**2 + da**2 + add) &
732 - 2.0_dp/sqrt(r**2 + db**2 + add)
733 charg = qxxqxx*0.125_dp*fact
734 RETURN
735 END IF
736 ! XX - YY
737 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmyy .AND. m2 == clmxx) THEN
738 qxxqyy = &
739 +1.0_dp/sqrt(r**2 + add) - 1.0_dp/sqrt(r**2 + da**2 + add) &
740 - 1.0_dp/sqrt(r**2 + db**2 + add) + 1.0_dp/sqrt(r**2 + da**2 + db**2 + add)
741 charg = qxxqyy*0.25_dp*fact
742 RETURN
743 END IF
744 ! XY - XY
745 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmxy .AND. m2 == clmxy) THEN
746 qxxqxx = &
747 +2.0_dp/sqrt(r**2 + add) + 1.0_dp/sqrt(r**2 + (da - db)**2 + add) &
748 + 1.0_dp/sqrt(r**2 + (da + db)**2 + add) - 2.0_dp/sqrt(r**2 + da**2 + add) &
749 - 2.0_dp/sqrt(r**2 + db**2 + add)
750 qxxqyy = &
751 +1.0_dp/sqrt(r**2 + add) - 1.0_dp/sqrt(r**2 + da**2 + add) &
752 - 1.0_dp/sqrt(r**2 + db**2 + add) + 1.0_dp/sqrt(r**2 + da**2 + db**2 + add)
753 charg = 0.5_dp*(qxxqxx*0.125_dp - qxxqyy*0.25_dp)*fact
754 RETURN
755 END IF
756 ! We should NEVER reach this point
757 cpabort("")
758 END FUNCTION charg_int_nri
759
760! **************************************************************************************************
761!> \brief Derivatives of interaction function between two point-charge
762!> configurations NDDO sp-code.
763!> Non-Rotational Invariant definition of quadrupoles
764!>
765!> r - Distance r12
766!> l1,m - Quantum numbers for multipole of configuration 1
767!> l2,m - Quantum numbers for multipole of configuration 2
768!> da - charge separation of configuration 1
769!> db - charge separation of configuration 2
770!> add - additive term
771!>
772!> \param r ...
773!> \param l1_i ...
774!> \param l2_i ...
775!> \param m1_i ...
776!> \param m2_i ...
777!> \param da_i ...
778!> \param db_i ...
779!> \param add0 ...
780!> \param fact_screen ...
781!> \return ...
782!> \date 04.2008 [tlaino]
783!> \author Teodoro Laino [tlaino] - University of Zurich
784! **************************************************************************************************
785 FUNCTION dcharg_int_nri(r, l1_i, l2_i, m1_i, m2_i, da_i, db_i, add0, fact_screen) RESULT(charg)
786 REAL(kind=dp), INTENT(in) :: r
787 INTEGER, INTENT(in) :: l1_i, l2_i, m1_i, m2_i
788 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
789 REAL(kind=dp) :: charg
790
791 INTEGER :: l1, l2, m1, m2
792 REAL(kind=dp) :: add, da, db, dxdx, dxqxz, dzdz, dzqxx, &
793 dzqzz, fact, qqxx, qqzz, qxxqxx, &
794 qxxqyy, qxzqxz, xyxy, zzzz
795
796! Computing only Integral Derivatives
797
798 IF (l1_i < l2_i) THEN
799 l1 = l1_i
800 l2 = l2_i
801 m1 = m1_i
802 m2 = m2_i
803 da = da_i
804 db = db_i
805 fact = 1.0_dp
806 ELSE IF (l1_i > l2_i) THEN
807 l1 = l2_i
808 l2 = l1_i
809 m1 = m2_i
810 m2 = m1_i
811 da = db_i
812 db = da_i
813 fact = (-1.0_dp)**(l1 + l2)
814 ELSE IF (l1_i == l2_i) THEN
815 l1 = l1_i
816 l2 = l2_i
817 IF (m1_i <= m2_i) THEN
818 m1 = m1_i
819 m2 = m2_i
820 da = da_i
821 db = db_i
822 ELSE
823 m1 = m2_i
824 m2 = m1_i
825 da = db_i
826 db = da_i
827 END IF
828 fact = 1.0_dp
829 END IF
830 charg = 0.0_dp
831 add = add0*fact_screen
832 ! Q - Q.
833 IF (l1 == 0 .AND. l2 == 0) THEN
834 charg = r/sqrt(r**2 + add)**3
835 charg = -charg*fact
836 RETURN
837 END IF
838 ! Q - Z.
839 IF (l1 == 0 .AND. l2 == 1 .AND. m2 == clmz) THEN
840 charg = (r + db)/sqrt((r + db)**2 + add)**3 - (r - db)/sqrt((r - db)**2 + add)**3
841 charg = -charg*0.5_dp*fact
842 RETURN
843 END IF
844 ! Z - Z.
845 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmz .AND. m2 == clmz) THEN
846 dzdz = &
847 +(r + da - db)/sqrt((r + da - db)**2 + add)**3 + (r - da + db)/sqrt((r - da + db)**2 + add)**3 &
848 - (r - da - db)/sqrt((r - da - db)**2 + add)**3 - (r + da + db)/sqrt((r + da + db)**2 + add)**3
849 charg = -dzdz*0.25_dp*fact
850 RETURN
851 END IF
852 ! X - X
853 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmp .AND. m2 == clmp) THEN
854 dxdx = 2.0_dp*r/sqrt(r**2 + (da - db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + (da + db)**2 + add)**3
855 charg = -dxdx*0.25_dp*fact
856 RETURN
857 END IF
858 ! Q - ZZ
859 IF (l1 == 0 .AND. l2 == 2 .AND. m2 == clmzz) THEN
860 qqzz = (r - db)/sqrt((r - db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + add)**3 + (r + db)/sqrt((r + db)**2 + add)**3
861 charg = -qqzz*0.25_dp*fact
862 RETURN
863 END IF
864 ! Q - XX
865 IF (l1 == 0 .AND. l2 == 2 .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
866 qqxx = -r/sqrt(r**2 + add)**3 + r/sqrt(r**2 + add + db**2)**3
867 charg = -qqxx*0.5_dp*fact
868 RETURN
869 END IF
870 ! Z - ZZ
871 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. m2 == clmzz) THEN
872 dzqzz = &
873 +(r - da - db)/sqrt((r - da - db)**2 + add)**3 - 2.0_dp*(r - da)/sqrt((r - da)**2 + add)**3 &
874 + (r - da + db)/sqrt((r - da + db)**2 + add)**3 - (r + da - db)/sqrt((r + da - db)**2 + add)**3 &
875 + 2.0_dp*(r + da)/sqrt((r + da)**2 + add)**3 - (r + da + db)/sqrt((r + da + db)**2 + add)**3
876 charg = -dzqzz*0.125_dp*fact
877 RETURN
878 END IF
879 ! Z - XX
880 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
881 dzqxx = &
882 +(r + da)/sqrt((r + da)**2 + add)**3 - (r + da)/sqrt((r + da)**2 + add + db**2)**3 &
883 - (r - da)/sqrt((r - da)**2 + add)**3 + (r - da)/sqrt((r - da)**2 + add + db**2)**3
884 charg = -dzqxx*0.25_dp*fact
885 RETURN
886 END IF
887 ! ZZ - ZZ
888 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. m2 == clmzz) THEN
889 zzzz = &
890 +(r - da - db)/sqrt((r - da - db)**2 + add)**3 + (r + da + db)/sqrt((r + da + db)**2 + add)**3 &
891 + (r - da + db)/sqrt((r - da + db)**2 + add)**3 + (r + da - db)/sqrt((r + da - db)**2 + add)**3
892 xyxy = &
893 +(r - da)/sqrt((r - da)**2 + add)**3 + (r + da)/sqrt((r + da)**2 + add)**3 &
894 + (r - db)/sqrt((r - db)**2 + add)**3 + (r + db)/sqrt((r + db)**2 + add)**3 &
895 - 2.0_dp*r/sqrt(r**2 + add)**3
896 charg = -(zzzz*0.0625_dp - xyxy*0.125_dp)*fact
897 RETURN
898 END IF
899 ! ZZ - XX
900 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. (m2 == clmxx .OR. m2 == clmyy)) THEN
901 zzzz = &
902 -(r + da)/sqrt((r + da)**2 + add)**3 + (r + da)/sqrt((r + da)**2 + db**2 + add)**3 &
903 - (r - da)/sqrt((r - da)**2 + add)**3 + (r - da)/sqrt((r - da)**2 + db**2 + add)**3
904 xyxy = r/sqrt(r**2 + db**2 + add)**3 - r/sqrt(r**2 + add)**3
905 charg = -(zzzz*0.125_dp - xyxy*0.25_dp)*fact
906 RETURN
907 END IF
908 ! X - ZX
909 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmp .AND. m2 == clmzp) THEN
910 db = db/2.0_dp
911 dxqxz = &
912 -(r - db)/sqrt((r - db)**2 + (da - db)**2 + add)**3 + (r + db)/sqrt((r + db)**2 + (da - db)**2 + add)**3 &
913 + (r - db)/sqrt((r - db)**2 + (da + db)**2 + add)**3 - (r + db)/sqrt((r + db)**2 + (da + db)**2 + add)**3
914 charg = -dxqxz*0.25_dp*fact
915 RETURN
916 END IF
917 ! ZX - ZX
918 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzp .AND. m2 == clmzp) THEN
919 da = da/2.0_dp
920 db = db/2.0_dp
921 qxzqxz = &
922 +(r + da - db)/sqrt((r + da - db)**2 + (da - db)**2 + add)**3 - (r + da + db)/sqrt((r + da + db)**2 + (da - db)**2 + add)**3 &
923 - (r - da - db)/sqrt((r - da - db)**2 + (da - db)**2 + add)**3 + (r - da + db)/sqrt((r - da + db)**2 + (da - db)**2 + add)**3 &
924 - (r + da - db)/sqrt((r + da - db)**2 + (da + db)**2 + add)**3 + (r + da + db)/sqrt((r + da + db)**2 + (da + db)**2 + add)**3 &
925 + (r - da - db)/sqrt((r - da - db)**2 + (da + db)**2 + add)**3 - (r - da + db)/sqrt((r - da + db)**2 + (da + db)**2 + add)**3
926 charg = -qxzqxz*0.125_dp*fact
927 RETURN
928 END IF
929 ! XX - XX
930 IF (l1 == 2 .AND. l2 == 2 .AND. (((m1 == clmyy) .AND. (m2 == clmyy)) .OR. ((m1 == clmxx) .AND. (m2 == clmxx)))) THEN
931 qxxqxx = &
932 +2.0_dp*r/sqrt(r**2 + add)**3 + r/sqrt(r**2 + (da - db)**2 + add)**3 &
933 + r/sqrt(r**2 + (da + db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + da**2 + add)**3 &
934 - 2.0_dp*r/sqrt(r**2 + db**2 + add)**3
935 charg = -qxxqxx*0.125_dp*fact
936 RETURN
937 END IF
938 ! XX - YY
939 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmyy .AND. m2 == clmxx) THEN
940 qxxqyy = &
941 +r/sqrt(r**2 + add)**3 - r/sqrt(r**2 + da**2 + add)**3 &
942 - r/sqrt(r**2 + db**2 + add)**3 + r/sqrt(r**2 + da**2 + db**2 + add)**3
943 charg = -qxxqyy*0.25_dp*fact
944 RETURN
945 END IF
946 ! XY - XY
947 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmxy .AND. m2 == clmxy) THEN
948 qxxqxx = &
949 +2.0_dp*r/sqrt(r**2 + add)**3 + r/sqrt(r**2 + (da - db)**2 + add)**3 &
950 + r/sqrt(r**2 + (da + db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + da**2 + add)**3 &
951 - 2.0_dp*r/sqrt(r**2 + db**2 + add)**3
952 qxxqyy = &
953 +r/sqrt(r**2 + add)**3 - r/sqrt(r**2 + da**2 + add)**3 &
954 - r/sqrt(r**2 + db**2 + add)**3 + r/sqrt(r**2 + da**2 + db**2 + add)**3
955 charg = -0.5_dp*(qxxqxx*0.125_dp - qxxqyy*0.25_dp)*fact
956 RETURN
957 END IF
958 ! We should NEVER reach this point
959 cpabort("")
960 END FUNCTION dcharg_int_nri
961
962! **************************************************************************************************
963!> \brief Derivatives of interaction function between two point-charge
964!> configurations NDDO sp-code. The derivative takes care of the screening
965!> term only.
966!> Non-Rotational Invariant definition of quadrupoles
967!>
968!> r - Distance r12
969!> l1,m - Quantum numbers for multipole of configuration 1
970!> l2,m - Quantum numbers for multipole of configuration 2
971!> da - charge separation of configuration 1
972!> db - charge separation of configuration 2
973!> add - additive term
974!>
975!> \param r ...
976!> \param l1_i ...
977!> \param l2_i ...
978!> \param m1_i ...
979!> \param m2_i ...
980!> \param da_i ...
981!> \param db_i ...
982!> \param add0 ...
983!> \param fact_screen ...
984!> \return ...
985!> \date 04.2008 [tlaino]
986!> \author Teodoro Laino [tlaino] - University of Zurich
987! **************************************************************************************************
988 FUNCTION dcharg_int_nri_fs(r, l1_i, l2_i, m1_i, m2_i, da_i, db_i, add0, fact_screen) RESULT(charg)
989 REAL(kind=dp), INTENT(in) :: r
990 INTEGER, INTENT(in) :: l1_i, l2_i, m1_i, m2_i
991 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
992 REAL(kind=dp) :: charg
993
994 INTEGER :: l1, l2, m1, m2
995 REAL(kind=dp) :: add, da, db, dxdx, dxqxz, dzdz, dzqxx, &
996 dzqzz, fact, qqxx, qqzz, qxxqxx, &
997 qxxqyy, qxzqxz, xyxy, zzzz
998
999! Computing only Integral Derivatives
1000
1001 IF (l1_i < l2_i) THEN
1002 l1 = l1_i
1003 l2 = l2_i
1004 m1 = m1_i
1005 m2 = m2_i
1006 da = da_i
1007 db = db_i
1008 fact = 1.0_dp
1009 ELSE IF (l1_i > l2_i) THEN
1010 l1 = l2_i
1011 l2 = l1_i
1012 m1 = m2_i
1013 m2 = m1_i
1014 da = db_i
1015 db = da_i
1016 fact = (-1.0_dp)**(l1 + l2)
1017 ELSE IF (l1_i == l2_i) THEN
1018 l1 = l1_i
1019 l2 = l2_i
1020 IF (m1_i <= m2_i) THEN
1021 m1 = m1_i
1022 m2 = m2_i
1023 da = da_i
1024 db = db_i
1025 ELSE
1026 m1 = m2_i
1027 m2 = m1_i
1028 da = db_i
1029 db = da_i
1030 END IF
1031 fact = 1.0_dp
1032 END IF
1033 charg = 0.0_dp
1034 add = add0*fact_screen
1035 ! The 0.5 factor handles the derivative of the SQRT
1036 fact = fact*0.5_dp
1037 ! Q - Q.
1038 IF (l1 == 0 .AND. l2 == 0) THEN
1039 charg = add0/sqrt(r**2 + add)**3
1040 charg = -charg*fact
1041 RETURN
1042 END IF
1043 ! Q - Z.
1044 IF (l1 == 0 .AND. l2 == 1 .AND. m2 == clmz) THEN
1045 charg = add0/sqrt((r + db)**2 + add)**3 - add0/sqrt((r - db)**2 + add)**3
1046 charg = -charg*0.5_dp*fact
1047 RETURN
1048 END IF
1049 ! Z - Z.
1050 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmz .AND. m2 == clmz) THEN
1051 dzdz = &
1052 +add0/sqrt((r + da - db)**2 + add)**3 + add0/sqrt((r - da + db)**2 + add)**3 &
1053 - add0/sqrt((r - da - db)**2 + add)**3 - add0/sqrt((r + da + db)**2 + add)**3
1054 charg = -dzdz*0.25_dp*fact
1055 RETURN
1056 END IF
1057 ! X - X
1058 IF (l1 == 1 .AND. l2 == 1 .AND. m1 == clmp .AND. m2 == clmp) THEN
1059 dxdx = 2.0_dp*add0/sqrt(r**2 + (da - db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + (da + db)**2 + add)**3
1060 charg = -dxdx*0.25_dp*fact
1061 RETURN
1062 END IF
1063 ! Q - ZZ
1064 IF (l1 == 0 .AND. l2 == 2 .AND. m2 == clmzz) THEN
1065 qqzz = add0/sqrt((r - db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + add)**3 + add0/sqrt((r + db)**2 + add)**3
1066 charg = -qqzz*0.25_dp*fact
1067 RETURN
1068 END IF
1069 ! Q - XX
1070 IF (l1 == 0 .AND. l2 == 2 .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
1071 qqxx = -add0/sqrt(r**2 + add)**3 + add0/sqrt(r**2 + add + db**2)**3
1072 charg = -qqxx*0.5_dp*fact
1073 RETURN
1074 END IF
1075 ! Z - ZZ
1076 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. m2 == clmzz) THEN
1077 dzqzz = &
1078 +add0/sqrt((r - da - db)**2 + add)**3 - 2.0_dp*add0/sqrt((r - da)**2 + add)**3 &
1079 + add0/sqrt((r - da + db)**2 + add)**3 - add0/sqrt((r + da - db)**2 + add)**3 &
1080 + 2.0_dp*add0/sqrt((r + da)**2 + add)**3 - add0/sqrt((r + da + db)**2 + add)**3
1081 charg = -dzqzz*0.125_dp*fact
1082 RETURN
1083 END IF
1084 ! Z - XX
1085 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmz .AND. (m2 == clmyy .OR. m2 == clmxx)) THEN
1086 dzqxx = &
1087 +add0/sqrt((r + da)**2 + add)**3 - add0/sqrt((r + da)**2 + add + db**2)**3 &
1088 - add0/sqrt((r - da)**2 + add)**3 + add0/sqrt((r - da)**2 + add + db**2)**3
1089 charg = -dzqxx*0.25_dp*fact
1090 RETURN
1091 END IF
1092 ! ZZ - ZZ
1093 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. m2 == clmzz) THEN
1094 zzzz = &
1095 +add0/sqrt((r - da - db)**2 + add)**3 + add0/sqrt((r + da + db)**2 + add)**3 &
1096 + add0/sqrt((r - da + db)**2 + add)**3 + add0/sqrt((r + da - db)**2 + add)**3
1097 xyxy = &
1098 +add0/sqrt((r - da)**2 + add)**3 + add0/sqrt((r + da)**2 + add)**3 &
1099 + add0/sqrt((r - db)**2 + add)**3 + add0/sqrt((r + db)**2 + add)**3 &
1100 - 2.0_dp*add0/sqrt(r**2 + add)**3
1101 charg = -(zzzz*0.0625_dp - xyxy*0.125_dp)*fact
1102 RETURN
1103 END IF
1104 ! ZZ - XX
1105 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzz .AND. (m2 == clmxx .OR. m2 == clmyy)) THEN
1106 zzzz = &
1107 -add0/sqrt((r + da)**2 + add)**3 + add0/sqrt((r + da)**2 + db**2 + add)**3 &
1108 - add0/sqrt((r - da)**2 + add)**3 + add0/sqrt((r - da)**2 + db**2 + add)**3
1109 xyxy = add0/sqrt(r**2 + db**2 + add)**3 - add0/sqrt(r**2 + add)**3
1110 charg = -(zzzz*0.125_dp - xyxy*0.25_dp)*fact
1111 RETURN
1112 END IF
1113 ! X - ZX
1114 IF (l1 == 1 .AND. l2 == 2 .AND. m1 == clmp .AND. m2 == clmzp) THEN
1115 db = db/2.0_dp
1116 dxqxz = &
1117 -add0/sqrt((r - db)**2 + (da - db)**2 + add)**3 + add0/sqrt((r + db)**2 + (da - db)**2 + add)**3 &
1118 + add0/sqrt((r - db)**2 + (da + db)**2 + add)**3 - add0/sqrt((r + db)**2 + (da + db)**2 + add)**3
1119 charg = -dxqxz*0.25_dp*fact
1120 RETURN
1121 END IF
1122 ! ZX - ZX
1123 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmzp .AND. m2 == clmzp) THEN
1124 da = da/2.0_dp
1125 db = db/2.0_dp
1126 qxzqxz = &
1127 +add0/sqrt((r + da - db)**2 + (da - db)**2 + add)**3 - add0/sqrt((r + da + db)**2 + (da - db)**2 + add)**3 &
1128 - add0/sqrt((r - da - db)**2 + (da - db)**2 + add)**3 + add0/sqrt((r - da + db)**2 + (da - db)**2 + add)**3 &
1129 - add0/sqrt((r + da - db)**2 + (da + db)**2 + add)**3 + add0/sqrt((r + da + db)**2 + (da + db)**2 + add)**3 &
1130 + add0/sqrt((r - da - db)**2 + (da + db)**2 + add)**3 - add0/sqrt((r - da + db)**2 + (da + db)**2 + add)**3
1131 charg = -qxzqxz*0.125_dp*fact
1132 RETURN
1133 END IF
1134 ! XX - XX
1135 IF (l1 == 2 .AND. l2 == 2 .AND. (((m1 == clmyy) .AND. (m2 == clmyy)) .OR. ((m1 == clmxx) .AND. (m2 == clmxx)))) THEN
1136 qxxqxx = &
1137 +2.0_dp*add0/sqrt(r**2 + add)**3 + add0/sqrt(r**2 + (da - db)**2 + add)**3 &
1138 + add0/sqrt(r**2 + (da + db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + da**2 + add)**3 &
1139 - 2.0_dp*add0/sqrt(r**2 + db**2 + add)**3
1140 charg = -qxxqxx*0.125_dp*fact
1141 RETURN
1142 END IF
1143 ! XX - YY
1144 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmyy .AND. m2 == clmxx) THEN
1145 qxxqyy = &
1146 +add0/sqrt(r**2 + add)**3 - add0/sqrt(r**2 + da**2 + add)**3 &
1147 - add0/sqrt(r**2 + db**2 + add)**3 + add0/sqrt(r**2 + da**2 + db**2 + add)**3
1148 charg = -qxxqyy*0.25_dp*fact
1149 RETURN
1150 END IF
1151 ! XY - XY
1152 IF (l1 == 2 .AND. l2 == 2 .AND. m1 == clmxy .AND. m2 == clmxy) THEN
1153 qxxqxx = &
1154 +2.0_dp*add0/sqrt(r**2 + add)**3 + add0/sqrt(r**2 + (da - db)**2 + add)**3 &
1155 + add0/sqrt(r**2 + (da + db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + da**2 + add)**3 &
1156 - 2.0_dp*add0/sqrt(r**2 + db**2 + add)**3
1157 qxxqyy = &
1158 +add0/sqrt(r**2 + add)**3 - add0/sqrt(r**2 + da**2 + add)**3 &
1159 - add0/sqrt(r**2 + db**2 + add)**3 + add0/sqrt(r**2 + da**2 + db**2 + add)**3
1160 charg = -0.5_dp*(qxxqxx*0.125_dp - qxxqyy*0.25_dp)*fact
1161 RETURN
1162 END IF
1163 ! We should NEVER reach this point
1164 cpabort("")
1165 END FUNCTION dcharg_int_nri_fs
1166
1167! **************************************************************************************************
1168!> \brief General driver for computing semi-empirical integrals <ij|kl>
1169!> involving d-orbitals.
1170!> The choice of the linear quadrupole was REALLY unhappy
1171!> in the first development of the NDDO codes. That choice makes
1172!> impossible the merging of the integral code with or without d-orbitals
1173!> unless a reparametrization of all NDDO codes for s and p orbitals will
1174!> be performed.. more over the choice of the linear quadrupole does not make
1175!> calculations rotational invariants (of course the rotational invariant
1176!> can be forced). The definitions of quadrupoles for d-orbitals is the
1177!> correct one in order to have the rotational invariant property by
1178!> construction..
1179!>
1180!> \param sepi ...
1181!> \param sepj ...
1182!> \param ij ...
1183!> \param kl ...
1184!> \param li ...
1185!> \param lj ...
1186!> \param lk ...
1187!> \param ll ...
1188!> \param ic ...
1189!> \param r ...
1190!> \param se_int_control ...
1191!> \param se_int_screen ...
1192!> \param itype ...
1193!> \return ...
1194!> \date 03.2008 [tlaino]
1195!> \author Teodoro Laino [tlaino] - University of Zurich
1196! **************************************************************************************************
1197 FUNCTION ijkl_d(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, &
1198 se_int_screen, itype) RESULT(res)
1199 TYPE(semi_empirical_type), POINTER :: sepi, sepj
1200 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
1201 REAL(kind=dp), INTENT(IN) :: r
1202 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
1203 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
1204 INTEGER, INTENT(IN) :: itype
1205 REAL(kind=dp) :: res
1206
1207 res = ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1208 se_int_control%integral_screening, se_int_control%shortrange, &
1209 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
1210 itype, charg_int_ri)
1211
1212 ! If only the shortrange component is requested we can skip the rest
1213 IF ((.NOT. se_int_control%pc_coulomb_int) .AND. (itype /= do_method_pchg)) THEN
1214 ! Handle the 1/r^3 term, this term is ALWAYS false for KDSO-D integrals
1215 IF (se_int_control%shortrange .AND. se_int_control%do_ewald_r3) THEN
1216 res = res - ijkl_low_3(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, &
1217 itype, charg_int_3)
1218 END IF
1219 END IF
1220 END FUNCTION ijkl_d
1221
1222! **************************************************************************************************
1223!> \brief General driver for computing the derivatives of semi-empirical integrals <ij|kl>
1224!> involving d-orbitals.
1225!> The choice of the linear quadrupole was REALLY unhappy
1226!> in the first development of the NDDO codes. That choice makes
1227!> impossible the merging of the integral code with or without d-orbitals
1228!> unless a reparametrization of all NDDO codes for s and p orbitals will
1229!> be performed.. more over the choice of the linear quadrupole does not make
1230!> calculations rotational invariants (of course the rotational invariant
1231!> can be forced). The definitions of quadrupoles for d-orbitals is the
1232!> correct one in order to have the rotational invariant property by
1233!> construction..
1234!>
1235!> \param sepi ...
1236!> \param sepj ...
1237!> \param ij ...
1238!> \param kl ...
1239!> \param li ...
1240!> \param lj ...
1241!> \param lk ...
1242!> \param ll ...
1243!> \param ic ...
1244!> \param r ...
1245!> \param se_int_control ...
1246!> \param se_int_screen ...
1247!> \param itype ...
1248!> \return ...
1249!> \date 03.2008 [tlaino]
1250!> \author Teodoro Laino [tlaino] - University of Zurich
1251! **************************************************************************************************
1252 FUNCTION d_ijkl_d(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, &
1253 se_int_screen, itype) RESULT(res)
1254 TYPE(semi_empirical_type), POINTER :: sepi, sepj
1255 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
1256 REAL(kind=dp), INTENT(IN) :: r
1257 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
1258 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
1259 INTEGER, INTENT(IN) :: itype
1260 REAL(kind=dp) :: res
1261
1262 REAL(kind=dp) :: dfs, srd
1263
1264 IF (se_int_control%integral_screening == do_se_is_kdso_d) THEN
1265 res = ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1266 se_int_control%integral_screening, .false., &
1267 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
1268 itype, dcharg_int_ri)
1269
1270 IF (.NOT. se_int_control%pc_coulomb_int) THEN
1271 dfs = ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1272 se_int_control%integral_screening, .false., .false., &
1273 se_int_control%max_multipole, itype, dcharg_int_ri_fs)
1274 res = res + dfs*se_int_screen%dft
1275
1276 ! In case we need the shortrange part we have to evaluate an additional derivative
1277 ! to handle the derivative of the Tapering term
1278 IF (se_int_control%shortrange) THEN
1279 srd = ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1280 se_int_control%integral_screening, .false., .true., &
1281 se_int_control%max_multipole, itype, dcharg_int_ri)
1282 res = res - srd
1283 END IF
1284 END IF
1285 ELSE
1286 res = ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1287 se_int_control%integral_screening, se_int_control%shortrange, &
1288 se_int_control%pc_coulomb_int, se_int_control%max_multipole, &
1289 itype, dcharg_int_ri)
1290 END IF
1291
1292 ! If only the shortrange component is requested we can skip the rest
1293 IF ((.NOT. se_int_control%pc_coulomb_int) .AND. (itype /= do_method_pchg)) THEN
1294 ! Handle the 1/r^3 term, this term is ALWAYS false for KDSO-D integrals
1295 IF (se_int_control%shortrange .AND. se_int_control%do_ewald_r3) THEN
1296 res = res - ijkl_low_3(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, &
1297 itype, dcharg_int_3)
1298 END IF
1299 END IF
1300
1301 END FUNCTION d_ijkl_d
1302
1303! **************************************************************************************************
1304!> \brief Low level general driver for computing semi-empirical integrals <ij|kl>
1305!> and their derivatives involving d-orbitals.
1306!> The choice of the linear quadrupole was REALLY unhappy
1307!> in the first development of the NDDO codes. That choice makes
1308!> impossible the merging of the integral code with or without d-orbitals
1309!> unless a reparametrization of all NDDO codes for s and p orbitals will
1310!> be performed.. more over the choice of the linear quadrupole does not make
1311!> calculations rotational invariants (of course the rotational invariant
1312!> can be forced). The definitions of quadrupoles for d-orbitals is the
1313!> correct one in order to have the rotational invariant property by
1314!> construction..
1315!>
1316!> \param sepi ...
1317!> \param sepj ...
1318!> \param ij ...
1319!> \param kl ...
1320!> \param li ...
1321!> \param lj ...
1322!> \param lk ...
1323!> \param ll ...
1324!> \param ic ...
1325!> \param r ...
1326!> \param se_int_screen ...
1327!> \param iscreen ...
1328!> \param shortrange ...
1329!> \param pc_coulomb_int ...
1330!> \param max_multipole ...
1331!> \param itype ...
1332!> \param eval a function without explicit interface
1333!> \return ...
1334!> \date 03.2008 [tlaino]
1335!> \author Teodoro Laino [tlaino] - University of Zurich
1336! **************************************************************************************************
1337 FUNCTION ijkl_d_low(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_screen, &
1338 iscreen, shortrange, pc_coulomb_int, max_multipole, itype, eval) RESULT(res)
1339 TYPE(semi_empirical_type), POINTER :: sepi, sepj
1340 INTEGER, INTENT(IN) :: ij, kl, li, lj, lk, ll, ic
1341 REAL(kind=dp), INTENT(IN) :: r
1342 TYPE(se_int_screen_type), INTENT(IN) :: se_int_screen
1343 INTEGER, INTENT(IN) :: iscreen
1344 LOGICAL, INTENT(IN) :: shortrange, pc_coulomb_int
1345 INTEGER, INTENT(IN) :: max_multipole, itype
1346
1347 PROCEDURE(eval_func_d) :: eval
1348 REAL(kind=dp) :: res
1349
1350 INTEGER :: l1, l1max, l1min, l2, l2max, l2min, lij, &
1351 lkl, lmin, m, mm
1352 REAL(kind=dp) :: add, ccc, chrg, dij, dkl, fact_screen, &
1353 pij, pkl, s1, sum
1354
1355 l1min = abs(li - lj)
1356 l1max = li + lj
1357 lij = indexb(li + 1, lj + 1)
1358 l2min = abs(lk - ll)
1359 l2max = lk + ll
1360 lkl = indexb(lk + 1, ll + 1)
1361
1362 l1max = min(l1max, 2)
1363 l1min = min(l1min, 2)
1364 l2max = min(l2max, 2)
1365 l2min = min(l2min, 2)
1366 sum = 0.0_dp
1367 dij = 0.0_dp
1368 dkl = 0.0_dp
1369 fact_screen = 1.0_dp
1370 IF (.NOT. pc_coulomb_int) THEN
1371 IF (iscreen == do_se_is_kdso_d) fact_screen = se_int_screen%ft
1372 ! Standard value of the integral
1373 DO l1 = l1min, l1max
1374 IF (l1 == 0) THEN
1375 IF (lij == 1) THEN
1376 pij = sepi%ko(1)
1377 IF (ic == 1) THEN
1378 pij = sepi%ko(9)
1379 END IF
1380 ELSE IF (lij == 3) THEN
1381 pij = sepi%ko(7)
1382 ELSE IF (lij == 6) THEN
1383 pij = sepi%ko(8)
1384 END IF
1385 ELSE
1386 dij = sepi%cs(lij)
1387 pij = sepi%ko(lij)
1388 END IF
1389 !
1390 DO l2 = l2min, l2max
1391 IF (l2 == 0) THEN
1392 IF (lkl == 1) THEN
1393 pkl = sepj%ko(1)
1394 IF (ic == 2) THEN
1395 pkl = sepj%ko(9)
1396 END IF
1397 ELSE IF (lkl == 3) THEN
1398 pkl = sepj%ko(7)
1399 ELSE IF (lkl == 6) THEN
1400 pkl = sepj%ko(8)
1401 END IF
1402 ELSE
1403 dkl = sepj%cs(lkl)
1404 pkl = sepj%ko(lkl)
1405 END IF
1406 IF (itype == do_method_pchg) THEN
1407 add = 0.0_dp
1408 ELSE
1409 add = (pij + pkl)**2
1410 END IF
1411 lmin = min(l1, l2)
1412 s1 = 0.0_dp
1413 DO m = -lmin, lmin
1414 ccc = clm_d(ij, l1, m)*clm_d(kl, l2, m)
1415 IF (abs(ccc) > epsilon(0.0_dp)) THEN
1416 mm = abs(m)
1417 chrg = eval(r, l1, l2, mm, dij, dkl, add, fact_screen)
1418 s1 = s1 + chrg*ccc
1419 END IF
1420 END DO
1421 sum = sum + s1
1422 END DO
1423 END DO
1424 res = sum
1425 END IF
1426 ! Shortrange: Possibly computes pure Coulomb and subtract from the original integral valeu
1427 IF (shortrange .OR. pc_coulomb_int) THEN
1428 sum = 0.0_dp
1429 dij = 0.0_dp
1430 dkl = 0.0_dp
1431 add = 0.0_dp
1432 fact_screen = 0.0_dp
1433 DO l1 = l1min, l1max
1434 IF (l1 > max_multipole) cycle
1435 IF (l1 /= 0) THEN
1436 dij = sepi%cs(lij)
1437 END IF
1438 !
1439 DO l2 = l2min, l2max
1440 IF (l2 > max_multipole) cycle
1441 IF (l2 /= 0) THEN
1442 dkl = sepj%cs(lkl)
1443 END IF
1444 lmin = min(l1, l2)
1445 s1 = 0.0_dp
1446 DO m = -lmin, lmin
1447 ccc = clm_d(ij, l1, m)*clm_d(kl, l2, m)
1448 IF (abs(ccc) > epsilon(0.0_dp)) THEN
1449 mm = abs(m)
1450 chrg = eval(r, l1, l2, mm, dij, dkl, add, fact_screen)
1451 s1 = s1 + chrg*ccc
1452 END IF
1453 END DO
1454 sum = sum + s1
1455 END DO
1456 END DO
1457 IF (pc_coulomb_int) res = sum
1458 IF (shortrange) res = res - sum
1459 END IF
1460 END FUNCTION ijkl_d_low
1461
1462! **************************************************************************************************
1463!> \brief Interaction function between two point-charge configurations (MNDO/d)
1464!> Rotational invariant property built-in in the quadrupole definition
1465!> r - Distance r12
1466!> l1,m - Quantum numbers for multipole of configuration 1
1467!> l2,m - Quantum numbers for multipole of configuration 2
1468!> da - charge separation of configuration 1
1469!> db - charge separation of configuration 2
1470!> add - additive term
1471!>
1472!> \param r ...
1473!> \param l1_i ...
1474!> \param l2_i ...
1475!> \param m ...
1476!> \param da_i ...
1477!> \param db_i ...
1478!> \param add0 ...
1479!> \param fact_screen ...
1480!> \return ...
1481!> \date 03.2008 [tlaino]
1482!> \author Teodoro Laino [tlaino] - University of Zurich
1483! **************************************************************************************************
1484 FUNCTION charg_int_ri(r, l1_i, l2_i, m, da_i, db_i, add0, fact_screen) RESULT(charg)
1485 REAL(kind=dp), INTENT(in) :: r
1486 INTEGER, INTENT(in) :: l1_i, l2_i, m
1487 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
1488 REAL(kind=dp) :: charg
1489
1490 INTEGER :: l1, l2
1491 REAL(kind=dp) :: aa, ab, add, da, db, dxdx, dxqxz, dzdz, &
1492 dzqzz, fact, qqzz, qxzqxz, xyxy, zzzz
1493
1494 IF (l1_i <= l2_i) THEN
1495 l1 = l1_i
1496 l2 = l2_i
1497 da = da_i
1498 db = db_i
1499 fact = 1.0_dp
1500 ELSE IF (l1_i > l2_i) THEN
1501 l1 = l2_i
1502 l2 = l1_i
1503 da = db_i
1504 db = da_i
1505 fact = (-1.0_dp)**(l1 + l2)
1506 END IF
1507 charg = 0.0_dp
1508 add = add0*fact_screen
1509 ! Q - Q.
1510 IF (l1 == 0 .AND. l2 == 0) THEN
1511 charg = fact/sqrt(r**2 + add)
1512 RETURN
1513 END IF
1514 ! Q - Z.
1515 IF (l1 == 0 .AND. l2 == 1) THEN
1516 charg = 1.0_dp/sqrt((r + db)**2 + add) - 1.0_dp/sqrt((r - db)**2 + add)
1517 charg = charg*0.5_dp*fact
1518 RETURN
1519 END IF
1520 ! Z - Z.
1521 IF (l1 == 1 .AND. l2 == 1 .AND. m == 0) THEN
1522 dzdz = &
1523 +1.0_dp/sqrt((r + da - db)**2 + add) + 1.0_dp/sqrt((r - da + db)**2 + add) &
1524 - 1.0_dp/sqrt((r - da - db)**2 + add) - 1.0_dp/sqrt((r + da + db)**2 + add)
1525 charg = dzdz*0.25_dp*fact
1526 RETURN
1527 END IF
1528 ! X - X
1529 IF (l1 == 1 .AND. l2 == 1 .AND. m == 1) THEN
1530 dxdx = 2.0_dp/sqrt(r**2 + (da - db)**2 + add) - 2.0_dp/sqrt(r**2 + (da + db)**2 + add)
1531 charg = dxdx*0.25_dp*fact
1532 RETURN
1533 END IF
1534 ! Q - ZZ
1535 IF (l1 == 0 .AND. l2 == 2) THEN
1536 qqzz = 1.0_dp/sqrt((r - db)**2 + add) - 2.0_dp/sqrt(r**2 + db**2 + add) + 1.0_dp/sqrt((r + db)**2 + add)
1537 charg = qqzz*0.25_dp*fact
1538 RETURN
1539 END IF
1540 ! Z - ZZ
1541 IF (l1 == 1 .AND. l2 == 2 .AND. m == 0) THEN
1542 dzqzz = &
1543 +1.0_dp/sqrt((r - da - db)**2 + add) - 2.0_dp/sqrt((r - da)**2 + db**2 + add) &
1544 + 1.0_dp/sqrt((r + db - da)**2 + add) - 1.0_dp/sqrt((r - db + da)**2 + add) &
1545 + 2.0_dp/sqrt((r + da)**2 + db**2 + add) - 1.0_dp/sqrt((r + da + db)**2 + add)
1546 charg = dzqzz*0.125_dp*fact
1547 RETURN
1548 END IF
1549 ! ZZ - ZZ
1550 IF (l1 == 2 .AND. l2 == 2 .AND. m == 0) THEN
1551 zzzz = &
1552 +1.0_dp/sqrt((r - da - db)**2 + add) + 1.0_dp/sqrt((r + da + db)**2 + add) &
1553 + 1.0_dp/sqrt((r - da + db)**2 + add) + 1.0_dp/sqrt((r + da - db)**2 + add) &
1554 - 2.0_dp/sqrt((r - da)**2 + db**2 + add) - 2.0_dp/sqrt((r - db)**2 + da**2 + add) &
1555 - 2.0_dp/sqrt((r + da)**2 + db**2 + add) - 2.0_dp/sqrt((r + db)**2 + da**2 + add) &
1556 + 2.0_dp/sqrt(r**2 + (da - db)**2 + add) + 2.0_dp/sqrt(r**2 + (da + db)**2 + add)
1557 xyxy = &
1558 +4.0_dp/sqrt(r**2 + (da - db)**2 + add) + 4.0_dp/sqrt(r**2 + (da + db)**2 + add) &
1559 - 8.0_dp/sqrt(r**2 + da**2 + db**2 + add)
1560 charg = (zzzz*0.0625_dp - xyxy*0.015625_dp)*fact
1561 RETURN
1562 END IF
1563 ! X - ZX
1564 IF (l1 == 1 .AND. l2 == 2 .AND. m == 1) THEN
1565 ab = db/sqrt(2.0_dp)
1566 dxqxz = &
1567 -2.0_dp/sqrt((r - ab)**2 + (da - ab)**2 + add) + 2.0_dp/sqrt((r + ab)**2 + (da - ab)**2 + add) &
1568 + 2.0_dp/sqrt((r - ab)**2 + (da + ab)**2 + add) - 2.0_dp/sqrt((r + ab)**2 + (da + ab)**2 + add)
1569 charg = dxqxz*0.125_dp*fact
1570 RETURN
1571 END IF
1572 ! ZX - ZX
1573 IF (l1 == 2 .AND. l2 == 2 .AND. m == 1) THEN
1574 aa = da/sqrt(2.0_dp)
1575 ab = db/sqrt(2.0_dp)
1576 qxzqxz = &
1577 +2.0_dp/sqrt((r + aa - ab)**2 + (aa - ab)**2 + add) - 2.0_dp/sqrt((r + aa + ab)**2 + (aa - ab)**2 + add) &
1578 - 2.0_dp/sqrt((r - aa - ab)**2 + (aa - ab)**2 + add) + 2.0_dp/sqrt((r - aa + ab)**2 + (aa - ab)**2 + add) &
1579 - 2.0_dp/sqrt((r + aa - ab)**2 + (aa + ab)**2 + add) + 2.0_dp/sqrt((r + aa + ab)**2 + (aa + ab)**2 + add) &
1580 + 2.0_dp/sqrt((r - aa - ab)**2 + (aa + ab)**2 + add) - 2.0_dp/sqrt((r - aa + ab)**2 + (aa + ab)**2 + add)
1581 charg = qxzqxz*0.0625_dp*fact
1582 RETURN
1583 END IF
1584 ! XX - XX
1585 IF (l1 == 2 .AND. l2 == 2 .AND. m == 2) THEN
1586 xyxy = 4.0_dp/sqrt(r**2 + (da - db)**2 + add) + 4.0_dp/sqrt(r**2 + (da + db)**2 + add) - 8.0_dp/sqrt(r**2 + da**2 + db**2 + add)
1587 charg = xyxy*0.0625_dp*fact
1588 RETURN
1589 END IF
1590 ! We should NEVER reach this point
1591 cpabort("")
1592 END FUNCTION charg_int_ri
1593
1594! **************************************************************************************************
1595!> \brief Derivatives of the interaction function between two point-charge
1596!> configurations (MNDO/d)
1597!> Rotational invariant property built-in in the quadrupole definition
1598!> r - Distance r12
1599!> l1,m - Quantum numbers for multipole of configuration 1
1600!> l2,m - Quantum numbers for multipole of configuration 2
1601!> da - charge separation of configuration 1
1602!> db - charge separation of configuration 2
1603!> add - additive term
1604!>
1605!> \param r ...
1606!> \param l1_i ...
1607!> \param l2_i ...
1608!> \param m ...
1609!> \param da_i ...
1610!> \param db_i ...
1611!> \param add0 ...
1612!> \param fact_screen ...
1613!> \return ...
1614!> \date 03.2008 [tlaino]
1615!> \author Teodoro Laino [tlaino] - University of Zurich
1616! **************************************************************************************************
1617 FUNCTION dcharg_int_ri(r, l1_i, l2_i, m, da_i, db_i, add0, fact_screen) RESULT(charg)
1618 REAL(kind=dp), INTENT(in) :: r
1619 INTEGER, INTENT(in) :: l1_i, l2_i, m
1620 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
1621 REAL(kind=dp) :: charg
1622
1623 INTEGER :: l1, l2
1624 REAL(kind=dp) :: aa, ab, add, da, db, dxdx, dxqxz, dzdz, &
1625 dzqzz, fact, qqzz, qxzqxz, xyxy, zzzz
1626
1627 IF (l1_i <= l2_i) THEN
1628 l1 = l1_i
1629 l2 = l2_i
1630 da = da_i
1631 db = db_i
1632 fact = 1.0_dp
1633 ELSE IF (l1_i > l2_i) THEN
1634 l1 = l2_i
1635 l2 = l1_i
1636 da = db_i
1637 db = da_i
1638 fact = (-1.0_dp)**(l1 + l2)
1639 END IF
1640 charg = 0.0_dp
1641 add = add0*fact_screen
1642 ! Q - Q.
1643 IF (l1 == 0 .AND. l2 == 0) THEN
1644 charg = r/sqrt(r**2 + add)**3
1645 charg = -fact*charg
1646 RETURN
1647 END IF
1648 ! Q - Z.
1649 IF (l1 == 0 .AND. l2 == 1) THEN
1650 charg = (r + db)/sqrt((r + db)**2 + add)**3 - (r - db)/sqrt((r - db)**2 + add)**3
1651 charg = -charg*0.5_dp*fact
1652 RETURN
1653 END IF
1654 ! Z - Z.
1655 IF (l1 == 1 .AND. l2 == 1 .AND. m == 0) THEN
1656 dzdz = &
1657 +(r + da - db)/sqrt((r + da - db)**2 + add)**3 + (r - da + db)/sqrt((r - da + db)**2 + add)**3 &
1658 - (r - da - db)/sqrt((r - da - db)**2 + add)**3 - (r + da + db)/sqrt((r + da + db)**2 + add)**3
1659 charg = -dzdz*0.25_dp*fact
1660 RETURN
1661 END IF
1662 ! X - X
1663 IF (l1 == 1 .AND. l2 == 1 .AND. m == 1) THEN
1664 dxdx = 2.0_dp*r/sqrt(r**2 + (da - db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + (da + db)**2 + add)**3
1665 charg = -dxdx*0.25_dp*fact
1666 RETURN
1667 END IF
1668 ! Q - ZZ
1669 IF (l1 == 0 .AND. l2 == 2) THEN
1670 qqzz = (r - db)/sqrt((r - db)**2 + add)**3 - 2.0_dp*r/sqrt(r**2 + db**2 + add)**3 + (r + db)/sqrt((r + db)**2 + add)**3
1671 charg = -qqzz*0.25_dp*fact
1672 RETURN
1673 END IF
1674 ! Z - ZZ
1675 IF (l1 == 1 .AND. l2 == 2 .AND. m == 0) THEN
1676 dzqzz = &
1677 +(r - da - db)/sqrt((r - da - db)**2 + add)**3 - 2.0_dp*(r - da)/sqrt((r - da)**2 + db**2 + add)**3 &
1678 + (r + db - da)/sqrt((r + db - da)**2 + add)**3 - (r - db + da)/sqrt((r - db + da)**2 + add)**3 &
1679 + 2.0_dp*(r + da)/sqrt((r + da)**2 + db**2 + add)**3 - (r + da + db)/sqrt((r + da + db)**2 + add)**3
1680 charg = -dzqzz*0.125_dp*fact
1681 RETURN
1682 END IF
1683 ! ZZ - ZZ
1684 IF (l1 == 2 .AND. l2 == 2 .AND. m == 0) THEN
1685 zzzz = &
1686 +(r - da - db)/sqrt((r - da - db)**2 + add)**3 + (r + da + db)/sqrt((r + da + db)**2 + add)**3 &
1687 + (r - da + db)/sqrt((r - da + db)**2 + add)**3 + (r + da - db)/sqrt((r + da - db)**2 + add)**3 &
1688 - 2.0_dp*(r - da)/sqrt((r - da)**2 + db**2 + add)**3 - 2.0_dp*(r - db)/sqrt((r - db)**2 + da**2 + add)**3 &
1689 - 2.0_dp*(r + da)/sqrt((r + da)**2 + db**2 + add)**3 - 2.0_dp*(r + db)/sqrt((r + db)**2 + da**2 + add)**3 &
1690 + 2.0_dp*r/sqrt(r**2 + (da - db)**2 + add)**3 + 2.0_dp*r/sqrt(r**2 + (da + db)**2 + add)**3
1691 xyxy = &
1692 +4.0_dp*r/sqrt(r**2 + (da - db)**2 + add)**3 + 4.0_dp*r/sqrt(r**2 + (da + db)**2 + add)**3 &
1693 - 8.0_dp*r/sqrt(r**2 + da**2 + db**2 + add)**3
1694 charg = -(zzzz*0.0625_dp - xyxy*0.015625_dp)*fact
1695 RETURN
1696 END IF
1697 ! X - ZX
1698 IF (l1 == 1 .AND. l2 == 2 .AND. m == 1) THEN
1699 ab = db/sqrt(2.0_dp)
1700 dxqxz = &
1701 -2.0_dp*(r - ab)/sqrt((r - ab)**2 + (da - ab)**2 + add)**3 + 2.0_dp*(r + ab)/sqrt((r + ab)**2 + (da - ab)**2 + add)**3 &
1702 + 2.0_dp*(r - ab)/sqrt((r - ab)**2 + (da + ab)**2 + add)**3 - 2.0_dp*(r + ab)/sqrt((r + ab)**2 + (da + ab)**2 + add)**3
1703 charg = -dxqxz*0.125_dp*fact
1704 RETURN
1705 END IF
1706 ! ZX - ZX
1707 IF (l1 == 2 .AND. l2 == 2 .AND. m == 1) THEN
1708 aa = da/sqrt(2.0_dp)
1709 ab = db/sqrt(2.0_dp)
1710 qxzqxz = &
1711 +2.0_dp*(r+aa-ab)/sqrt((r+aa-ab)**2+(aa-ab)**2+add)**3-2.0_dp*(r+aa+ab)/sqrt((r+aa+ab)**2+(aa-ab)**2+add)**3 &
1712 -2.0_dp*(r-aa-ab)/sqrt((r-aa-ab)**2+(aa-ab)**2+add)**3+2.0_dp*(r-aa+ab)/sqrt((r-aa+ab)**2+(aa-ab)**2+add)**3 &
1713 -2.0_dp*(r+aa-ab)/sqrt((r+aa-ab)**2+(aa+ab)**2+add)**3+2.0_dp*(r+aa+ab)/sqrt((r+aa+ab)**2+(aa+ab)**2+add)**3 &
1714 +2.0_dp*(r-aa-ab)/sqrt((r-aa-ab)**2+(aa+ab)**2+add)**3-2.0_dp*(r-aa+ab)/sqrt((r-aa+ab)**2+(aa+ab)**2+add)**3
1715 charg = -qxzqxz*0.0625_dp*fact
1716 RETURN
1717 END IF
1718 ! XX - XX
1719 IF (l1 == 2 .AND. l2 == 2 .AND. m == 2) THEN
1720 xyxy = 4.0_dp*r/sqrt(r**2+(da-db)**2+add)**3+4.0_dp*r/sqrt(r**2+(da+db)**2+add)**3-8.0_dp*r/sqrt(r**2+da**2+db**2+add)**3
1721 charg = -xyxy*0.0625_dp*fact
1722 RETURN
1723 END IF
1724 ! We should NEVER reach this point
1725 cpabort("")
1726 END FUNCTION dcharg_int_ri
1727
1728! **************************************************************************************************
1729!> \brief Derivatives of the interaction function between two point-charge
1730!> configurations (MNDO/d). This derivative takes into account only the
1731!> tapering term
1732!> Rotational invariant property built-in in the quadrupole definition
1733!> r - Distance r12
1734!> l1,m - Quantum numbers for multipole of configuration 1
1735!> l2,m - Quantum numbers for multipole of configuration 2
1736!> da - charge separation of configuration 1
1737!> db - charge separation of configuration 2
1738!> add - additive term
1739!>
1740!> \param r ...
1741!> \param l1_i ...
1742!> \param l2_i ...
1743!> \param m ...
1744!> \param da_i ...
1745!> \param db_i ...
1746!> \param add0 ...
1747!> \param fact_screen ...
1748!> \return ...
1749!> \date 03.2008 [tlaino]
1750!> \author Teodoro Laino [tlaino] - University of Zurich
1751! **************************************************************************************************
1752 FUNCTION dcharg_int_ri_fs(r, l1_i, l2_i, m, da_i, db_i, add0, fact_screen) RESULT(charg)
1753 REAL(kind=dp), INTENT(in) :: r
1754 INTEGER, INTENT(in) :: l1_i, l2_i, m
1755 REAL(kind=dp), INTENT(in) :: da_i, db_i, add0, fact_screen
1756 REAL(kind=dp) :: charg
1757
1758 INTEGER :: l1, l2
1759 REAL(kind=dp) :: aa, ab, add, da, db, dxdx, dxqxz, dzdz, &
1760 dzqzz, fact, qqzz, qxzqxz, xyxy, zzzz
1761
1762 IF (l1_i <= l2_i) THEN
1763 l1 = l1_i
1764 l2 = l2_i
1765 da = da_i
1766 db = db_i
1767 fact = 1.0_dp
1768 ELSE IF (l1_i > l2_i) THEN
1769 l1 = l2_i
1770 l2 = l1_i
1771 da = db_i
1772 db = da_i
1773 fact = (-1.0_dp)**(l1 + l2)
1774 END IF
1775 charg = 0.0_dp
1776 add = add0*fact_screen
1777 ! The 0.5 factor handles the derivative of the SQRT
1778 fact = fact*0.5_dp
1779 ! Q - Q.
1780 IF (l1 == 0 .AND. l2 == 0) THEN
1781 charg = add0/sqrt(r**2 + add)**3
1782 charg = -fact*charg
1783 RETURN
1784 END IF
1785 ! Q - Z.
1786 IF (l1 == 0 .AND. l2 == 1) THEN
1787 charg = add0/sqrt((r + db)**2 + add)**3 - add0/sqrt((r - db)**2 + add)**3
1788 charg = -charg*0.5_dp*fact
1789 RETURN
1790 END IF
1791 ! Z - Z.
1792 IF (l1 == 1 .AND. l2 == 1 .AND. m == 0) THEN
1793 dzdz = &
1794 +add0/sqrt((r + da - db)**2 + add)**3 + add0/sqrt((r - da + db)**2 + add)**3 &
1795 - add0/sqrt((r - da - db)**2 + add)**3 - add0/sqrt((r + da + db)**2 + add)**3
1796 charg = -dzdz*0.25_dp*fact
1797 RETURN
1798 END IF
1799 ! X - X
1800 IF (l1 == 1 .AND. l2 == 1 .AND. m == 1) THEN
1801 dxdx = 2.0_dp*add0/sqrt(r**2 + (da - db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + (da + db)**2 + add)**3
1802 charg = -dxdx*0.25_dp*fact
1803 RETURN
1804 END IF
1805 ! Q - ZZ
1806 IF (l1 == 0 .AND. l2 == 2) THEN
1807 qqzz = add0/sqrt((r - db)**2 + add)**3 - 2.0_dp*add0/sqrt(r**2 + db**2 + add)**3 + add0/sqrt((r + db)**2 + add)**3
1808 charg = -qqzz*0.25_dp*fact
1809 RETURN
1810 END IF
1811 ! Z - ZZ
1812 IF (l1 == 1 .AND. l2 == 2 .AND. m == 0) THEN
1813 dzqzz = &
1814 +add0/sqrt((r - da - db)**2 + add)**3 - 2.0_dp*add0/sqrt((r - da)**2 + db**2 + add)**3 &
1815 + add0/sqrt((r + db - da)**2 + add)**3 - add0/sqrt((r - db + da)**2 + add)**3 &
1816 + 2.0_dp*add0/sqrt((r + da)**2 + db**2 + add)**3 - add0/sqrt((r + da + db)**2 + add)**3
1817 charg = -dzqzz*0.125_dp*fact
1818 RETURN
1819 END IF
1820 ! ZZ - ZZ
1821 IF (l1 == 2 .AND. l2 == 2 .AND. m == 0) THEN
1822 zzzz = &
1823 +add0/sqrt((r - da - db)**2 + add)**3 + add0/sqrt((r + da + db)**2 + add)**3 &
1824 + add0/sqrt((r - da + db)**2 + add)**3 + add0/sqrt((r + da - db)**2 + add)**3 &
1825 - 2.0_dp*add0/sqrt((r - da)**2 + db**2 + add)**3 - 2.0_dp*add0/sqrt((r - db)**2 + da**2 + add)**3 &
1826 - 2.0_dp*add0/sqrt((r + da)**2 + db**2 + add)**3 - 2.0_dp*add0/sqrt((r + db)**2 + da**2 + add)**3 &
1827 + 2.0_dp*add0/sqrt(r**2 + (da - db)**2 + add)**3 + 2.0_dp*add0/sqrt(r**2 + (da + db)**2 + add)**3
1828 xyxy = &
1829 +4.0_dp*add0/sqrt(r**2 + (da - db)**2 + add)**3 + 4.0_dp*add0/sqrt(r**2 + (da + db)**2 + add)**3 &
1830 - 8.0_dp*add0/sqrt(r**2 + da**2 + db**2 + add)**3
1831 charg = -(zzzz*0.0625_dp - xyxy*0.015625_dp)*fact
1832 RETURN
1833 END IF
1834 ! X - ZX
1835 IF (l1 == 1 .AND. l2 == 2 .AND. m == 1) THEN
1836 ab = db/sqrt(2.0_dp)
1837 dxqxz = &
1838 -2.0_dp*add0/sqrt((r - ab)**2 + (da - ab)**2 + add)**3 + 2.0_dp*add0/sqrt((r + ab)**2 + (da - ab)**2 + add)**3 &
1839 + 2.0_dp*add0/sqrt((r - ab)**2 + (da + ab)**2 + add)**3 - 2.0_dp*add0/sqrt((r + ab)**2 + (da + ab)**2 + add)**3
1840 charg = -dxqxz*0.125_dp*fact
1841 RETURN
1842 END IF
1843 ! ZX - ZX
1844 IF (l1 == 2 .AND. l2 == 2 .AND. m == 1) THEN
1845 aa = da/sqrt(2.0_dp)
1846 ab = db/sqrt(2.0_dp)
1847 qxzqxz = &
1848 +2.0_dp*add0/sqrt((r + aa - ab)**2 + (aa - ab)**2 + add)**3 - 2.0_dp*add0/sqrt((r + aa + ab)**2 + (aa - ab)**2 + add)**3 &
1849 - 2.0_dp*add0/sqrt((r - aa - ab)**2 + (aa - ab)**2 + add)**3 + 2.0_dp*add0/sqrt((r - aa + ab)**2 + (aa - ab)**2 + add)**3 &
1850 - 2.0_dp*add0/sqrt((r + aa - ab)**2 + (aa + ab)**2 + add)**3 + 2.0_dp*add0/sqrt((r + aa + ab)**2 + (aa + ab)**2 + add)**3 &
1851 + 2.0_dp*add0/sqrt((r - aa - ab)**2 + (aa + ab)**2 + add)**3 - 2.0_dp*add0/sqrt((r - aa + ab)**2 + (aa + ab)**2 + add)**3
1852 charg = -qxzqxz*0.0625_dp*fact
1853 RETURN
1854 END IF
1855 ! XX - XX
1856 IF (l1 == 2 .AND. l2 == 2 .AND. m == 2) THEN
1857 xyxy = 4.0_dp*add0/sqrt(r**2 + (da - db)**2 + add)**3 + 4.0_dp*add0/sqrt(r**2 + (da + db)**2 + add)**3 - &
1858 8.0_dp*add0/sqrt(r**2 + da**2 + db**2 + add)**3
1859 charg = -xyxy*0.0625_dp*fact
1860 RETURN
1861 END IF
1862 ! We should NEVER reach this point
1863 cpabort("")
1864 END FUNCTION dcharg_int_ri_fs
1865
1866! **************************************************************************************************
1867!> \brief Computes the general rotation matrices for the integrals
1868!> between I and J (J>=I)
1869!>
1870!> \param sepi ...
1871!> \param sepj ...
1872!> \param rjiv ...
1873!> \param r ...
1874!> \param ij_matrix ...
1875!> \param do_derivatives ...
1876!> \param do_invert ...
1877!> \param debug_invert ...
1878!> \date 04.2008 [tlaino]
1879!> \author Teodoro Laino [tlaino] - University of Zurich
1880! **************************************************************************************************
1881 RECURSIVE SUBROUTINE rotmat(sepi, sepj, rjiv, r, ij_matrix, do_derivatives, &
1882 do_invert, debug_invert)
1883 TYPE(semi_empirical_type), POINTER :: sepi, sepj
1884 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rjiv
1885 REAL(kind=dp), INTENT(IN) :: r
1886 TYPE(rotmat_type), POINTER :: ij_matrix
1887 LOGICAL, INTENT(IN) :: do_derivatives
1888 LOGICAL, INTENT(OUT), OPTIONAL :: do_invert
1889 LOGICAL, INTENT(IN), OPTIONAL :: debug_invert
1890
1891 INTEGER :: imap(3), k, l
1892 LOGICAL :: dbg_inv, eval
1893 REAL(kind=dp) :: b, c2a, c2b, ca, ca2, cb, cb2, check, &
1894 pt5sq3, r2i, s2a, s2b, sa, sb, sb2, &
1895 sqb, sqb2i, x11, x22, x33
1896 REAL(kind=dp), DIMENSION(3) :: b_d, c2a_d, c2b_d, ca2_d, ca_d, cb2_d, &
1897 cb_d, r_d, s2a_d, s2b_d, sa_d, sb2_d, &
1898 sb_d, sqb_d, x11_d, x22_d, x33_d
1899 REAL(kind=dp), DIMENSION(3, 3) :: p
1900 REAL(kind=dp), DIMENSION(3, 3, 3) :: p_d
1901 REAL(kind=dp), DIMENSION(3, 5, 5) :: d_d
1902 REAL(kind=dp), DIMENSION(5, 5) :: d
1903
1904 cpassert(ASSOCIATED(ij_matrix))
1905 IF (PRESENT(do_invert)) do_invert = .false.
1906 IF ((sepi%natorb > 1) .OR. (sepj%natorb > 1)) THEN
1907 ! Compute Geomtric data and interatomic distance
1908 ! CA = COS(PHI) , SA = SIN(PHI)
1909 ! CB = COS(THETA) , SB = SIN(THETA)
1910 ! C2A = COS(2*PHI) , S2A = SIN(2*PHI)
1911 ! C2B = COS(2*THETA), S2B = SIN(2*PHI)
1912 eval = .true.
1913 dbg_inv = .false.
1914 pt5sq3 = 0.5_dp*sqrt(3.0_dp)
1915 imap(1) = 1
1916 imap(2) = 2
1917 imap(3) = 3
1918 check = rjiv(3)/r
1919 IF (PRESENT(debug_invert)) dbg_inv = debug_invert
1920 ! Check for special case: both atoms lie on the Z Axis
1921 IF (abs(check) > 0.99999999_dp) THEN
1922 IF (PRESENT(do_invert)) THEN
1923 imap(1) = 3
1924 imap(2) = 2
1925 imap(3) = 1
1926 eval = .true.
1927 do_invert = .true.
1928 ELSE
1929 sa = 0.0_dp
1930 sb = 0.0_dp
1931 IF (check < 0.0_dp) THEN
1932 ca = -1.0_dp
1933 cb = -1.0_dp
1934 ELSE IF (check > 0.0_dp) THEN
1935 ca = 1.0_dp
1936 cb = 1.0_dp
1937 ELSE
1938 ca = 0.0_dp
1939 cb = 0.0_dp
1940 END IF
1941 eval = .false.
1942 END IF
1943 END IF
1944 IF (dbg_inv) THEN
1945 ! When debugging the derivatives of the rotation matrix we must possibly force
1946 ! the inversion of the reference frame
1947 cpassert(.NOT. do_derivatives)
1948 imap(1) = 3
1949 imap(2) = 2
1950 imap(3) = 1
1951 eval = .true.
1952 END IF
1953 IF (eval) THEN
1954 x11 = rjiv(imap(1))
1955 x22 = rjiv(imap(2))
1956 x33 = rjiv(imap(3))
1957 cb = x33/r
1958 b = x11**2 + x22**2
1959 sqb = sqrt(b)
1960 ca = x11/sqb
1961 sa = x22/sqb
1962 sb = sqb/r
1963 END IF
1964 ! Calculate rotation matrix elements
1965 p(1, 1) = ca*sb
1966 p(2, 1) = ca*cb
1967 p(3, 1) = -sa
1968 p(1, 2) = sa*sb
1969 p(2, 2) = sa*cb
1970 p(3, 2) = ca
1971 p(1, 3) = cb
1972 p(2, 3) = -sb
1973 p(3, 3) = 0.0_dp
1974 IF (sepi%dorb .OR. sepj%dorb) THEN
1975 ca2 = ca**2
1976 cb2 = cb**2
1977 sb2 = sb**2
1978 c2a = 2.0_dp*ca2 - 1.0_dp
1979 c2b = 2.0_dp*cb2 - 1.0_dp
1980 s2a = 2.0_dp*sa*ca
1981 s2b = 2.0_dp*sb*cb
1982 d(1, 1) = pt5sq3*c2a*sb2
1983 d(2, 1) = 0.5_dp*c2a*s2b
1984 d(3, 1) = -s2a*sb
1985 d(4, 1) = c2a*(cb2 + 0.5_dp*sb2)
1986 d(5, 1) = -s2a*cb
1987 d(1, 2) = pt5sq3*ca*s2b
1988 d(2, 2) = ca*c2b
1989 d(3, 2) = -sa*cb
1990 d(4, 2) = -0.5_dp*ca*s2b
1991 d(5, 2) = sa*sb
1992 d(1, 3) = cb2 - 0.5_dp*sb2
1993 d(2, 3) = -pt5sq3*s2b
1994 d(3, 3) = 0.0_dp
1995 d(4, 3) = pt5sq3*sb2
1996 d(5, 3) = 0.0_dp
1997 d(1, 4) = pt5sq3*sa*s2b
1998 d(2, 4) = sa*c2b
1999 d(3, 4) = ca*cb
2000 d(4, 4) = -0.5_dp*sa*s2b
2001 d(5, 4) = -ca*sb
2002 d(1, 5) = pt5sq3*s2a*sb2
2003 d(2, 5) = 0.5_dp*s2a*s2b
2004 d(3, 5) = c2a*sb
2005 d(4, 5) = s2a*(cb2 + 0.5_dp*sb2)
2006 d(5, 5) = c2a*cb
2007 END IF
2008 ! Rotation Elements for : S-P
2009 DO k = 1, 3
2010 DO l = 1, 3
2011 ij_matrix%sp(k, l) = p(k, l)
2012 END DO
2013 END DO
2014 ! Rotation Elements for : P-P
2015 DO k = 1, 3
2016 ij_matrix%pp(1, k, k) = p(k, 1)*p(k, 1)
2017 ij_matrix%pp(2, k, k) = p(k, 2)*p(k, 2)
2018 ij_matrix%pp(3, k, k) = p(k, 3)*p(k, 3)
2019 ij_matrix%pp(4, k, k) = p(k, 1)*p(k, 2)
2020 ij_matrix%pp(5, k, k) = p(k, 1)*p(k, 3)
2021 ij_matrix%pp(6, k, k) = p(k, 2)*p(k, 3)
2022 IF (k /= 1) THEN
2023 DO l = 1, k - 1
2024 ij_matrix%pp(1, k, l) = 2.0_dp*p(k, 1)*p(l, 1)
2025 ij_matrix%pp(2, k, l) = 2.0_dp*p(k, 2)*p(l, 2)
2026 ij_matrix%pp(3, k, l) = 2.0_dp*p(k, 3)*p(l, 3)
2027 ij_matrix%pp(4, k, l) = p(k, 1)*p(l, 2) + p(k, 2)*p(l, 1)
2028 ij_matrix%pp(5, k, l) = p(k, 1)*p(l, 3) + p(k, 3)*p(l, 1)
2029 ij_matrix%pp(6, k, l) = p(k, 2)*p(l, 3) + p(k, 3)*p(l, 2)
2030 END DO
2031 END IF
2032 END DO
2033 IF (sepi%dorb .OR. sepj%dorb) THEN
2034 ! Rotation Elements for : S-D
2035 DO k = 1, 5
2036 DO l = 1, 5
2037 ij_matrix%sd(k, l) = d(k, l)
2038 END DO
2039 END DO
2040 ! Rotation Elements for : D-P
2041 DO k = 1, 5
2042 DO l = 1, 3
2043 ij_matrix%pd(1, k, l) = d(k, 1)*p(l, 1)
2044 ij_matrix%pd(2, k, l) = d(k, 1)*p(l, 2)
2045 ij_matrix%pd(3, k, l) = d(k, 1)*p(l, 3)
2046 ij_matrix%pd(4, k, l) = d(k, 2)*p(l, 1)
2047 ij_matrix%pd(5, k, l) = d(k, 2)*p(l, 2)
2048 ij_matrix%pd(6, k, l) = d(k, 2)*p(l, 3)
2049 ij_matrix%pd(7, k, l) = d(k, 3)*p(l, 1)
2050 ij_matrix%pd(8, k, l) = d(k, 3)*p(l, 2)
2051 ij_matrix%pd(9, k, l) = d(k, 3)*p(l, 3)
2052 ij_matrix%pd(10, k, l) = d(k, 4)*p(l, 1)
2053 ij_matrix%pd(11, k, l) = d(k, 4)*p(l, 2)
2054 ij_matrix%pd(12, k, l) = d(k, 4)*p(l, 3)
2055 ij_matrix%pd(13, k, l) = d(k, 5)*p(l, 1)
2056 ij_matrix%pd(14, k, l) = d(k, 5)*p(l, 2)
2057 ij_matrix%pd(15, k, l) = d(k, 5)*p(l, 3)
2058 END DO
2059 END DO
2060 ! Rotation Elements for : D-D
2061 DO k = 1, 5
2062 ij_matrix%dd(1, k, k) = d(k, 1)*d(k, 1)
2063 ij_matrix%dd(2, k, k) = d(k, 2)*d(k, 2)
2064 ij_matrix%dd(3, k, k) = d(k, 3)*d(k, 3)
2065 ij_matrix%dd(4, k, k) = d(k, 4)*d(k, 4)
2066 ij_matrix%dd(5, k, k) = d(k, 5)*d(k, 5)
2067 ij_matrix%dd(6, k, k) = d(k, 1)*d(k, 2)
2068 ij_matrix%dd(7, k, k) = d(k, 1)*d(k, 3)
2069 ij_matrix%dd(8, k, k) = d(k, 2)*d(k, 3)
2070 ij_matrix%dd(9, k, k) = d(k, 1)*d(k, 4)
2071 ij_matrix%dd(10, k, k) = d(k, 2)*d(k, 4)
2072 ij_matrix%dd(11, k, k) = d(k, 3)*d(k, 4)
2073 ij_matrix%dd(12, k, k) = d(k, 1)*d(k, 5)
2074 ij_matrix%dd(13, k, k) = d(k, 2)*d(k, 5)
2075 ij_matrix%dd(14, k, k) = d(k, 3)*d(k, 5)
2076 ij_matrix%dd(15, k, k) = d(k, 4)*d(k, 5)
2077 IF (k /= 1) THEN
2078 DO l = 1, k - 1
2079 ij_matrix%dd(1, k, l) = 2.0_dp*d(k, 1)*d(l, 1)
2080 ij_matrix%dd(2, k, l) = 2.0_dp*d(k, 2)*d(l, 2)
2081 ij_matrix%dd(3, k, l) = 2.0_dp*d(k, 3)*d(l, 3)
2082 ij_matrix%dd(4, k, l) = 2.0_dp*d(k, 4)*d(l, 4)
2083 ij_matrix%dd(5, k, l) = 2.0_dp*d(k, 5)*d(l, 5)
2084 ij_matrix%dd(6, k, l) = d(k, 1)*d(l, 2) + d(k, 2)*d(l, 1)
2085 ij_matrix%dd(7, k, l) = d(k, 1)*d(l, 3) + d(k, 3)*d(l, 1)
2086 ij_matrix%dd(8, k, l) = d(k, 2)*d(l, 3) + d(k, 3)*d(l, 2)
2087 ij_matrix%dd(9, k, l) = d(k, 1)*d(l, 4) + d(k, 4)*d(l, 1)
2088 ij_matrix%dd(10, k, l) = d(k, 2)*d(l, 4) + d(k, 4)*d(l, 2)
2089 ij_matrix%dd(11, k, l) = d(k, 3)*d(l, 4) + d(k, 4)*d(l, 3)
2090 ij_matrix%dd(12, k, l) = d(k, 1)*d(l, 5) + d(k, 5)*d(l, 1)
2091 ij_matrix%dd(13, k, l) = d(k, 2)*d(l, 5) + d(k, 5)*d(l, 2)
2092 ij_matrix%dd(14, k, l) = d(k, 3)*d(l, 5) + d(k, 5)*d(l, 3)
2093 ij_matrix%dd(15, k, l) = d(k, 4)*d(l, 5) + d(k, 5)*d(l, 4)
2094 END DO
2095 END IF
2096 END DO
2097 END IF
2098 ! Evaluate Derivatives if required
2099 IF (do_derivatives) THEN
2100 ! This condition is necessary because derivatives uses the invertion of the
2101 ! axis for treating the divergence point along z-axis
2102 cpassert(eval)
2103 x11_d = 0.0_dp; x11_d(1) = 1.0_dp
2104 x22_d = 0.0_dp; x22_d(2) = 1.0_dp
2105 x33_d = 0.0_dp; x33_d(3) = 1.0_dp
2106 r_d = (/x11, x22, x33/)/r
2107 b_d = 2.0_dp*(x11*x11_d + x22*x22_d)
2108 sqb_d = (0.5_dp/sqb)*b_d
2109 r2i = 1.0_dp/r**2
2110 sqb2i = 1.0_dp/sqb**2
2111 cb_d = (x33_d*r - x33*r_d)*r2i
2112 ca_d = (x11_d*sqb - x11*sqb_d)*sqb2i
2113 sa_d = (x22_d*sqb - x22*sqb_d)*sqb2i
2114 sb_d = (sqb_d*r - sqb*r_d)*r2i
2115 ! Calculate derivatives of rotation matrix elements
2116 p_d(:, 1, 1) = ca_d*sb + ca*sb_d
2117 p_d(:, 2, 1) = ca_d*cb + ca*cb_d
2118 p_d(:, 3, 1) = -sa_d
2119 p_d(:, 1, 2) = sa_d*sb + sa*sb_d
2120 p_d(:, 2, 2) = sa_d*cb + sa*cb_d
2121 p_d(:, 3, 2) = ca_d
2122 p_d(:, 1, 3) = cb_d
2123 p_d(:, 2, 3) = -sb_d
2124 p_d(:, 3, 3) = 0.0_dp
2125 IF (sepi%dorb .OR. sepj%dorb) THEN
2126 ca2_d = 2.0_dp*ca*ca_d
2127 cb2_d = 2.0_dp*cb*cb_d
2128 sb2_d = 2.0_dp*sb*sb_d
2129 c2a_d = 2.0_dp*ca2_d
2130 c2b_d = 2.0_dp*cb2_d
2131 s2a_d = 2.0_dp*(sa_d*ca + sa*ca_d)
2132 s2b_d = 2.0_dp*(sb_d*cb + sb*cb_d)
2133 d_d(:, 1, 1) = pt5sq3*(c2a_d*sb2 + c2a*sb2_d)
2134 d_d(:, 2, 1) = 0.5_dp*(c2a_d*s2b + c2a*s2b_d)
2135 d_d(:, 3, 1) = -s2a_d*sb - s2a*sb_d
2136 d_d(:, 4, 1) = c2a_d*(cb2 + 0.5_dp*sb2) + c2a*(cb2_d + 0.5_dp*sb2_d)
2137 d_d(:, 5, 1) = -s2a_d*cb - s2a*cb_d
2138 d_d(:, 1, 2) = pt5sq3*(ca_d*s2b + ca*s2b_d)
2139 d_d(:, 2, 2) = ca_d*c2b + ca*c2b_d
2140 d_d(:, 3, 2) = -sa_d*cb - sa*cb_d
2141 d_d(:, 4, 2) = -0.5_dp*(ca_d*s2b + ca*s2b_d)
2142 d_d(:, 5, 2) = sa_d*sb + sa*sb_d
2143 d_d(:, 1, 3) = cb2_d - 0.5_dp*sb2_d
2144 d_d(:, 2, 3) = -pt5sq3*s2b_d
2145 d_d(:, 3, 3) = 0.0_dp
2146 d_d(:, 4, 3) = pt5sq3*sb2_d
2147 d_d(:, 5, 3) = 0.0_dp
2148 d_d(:, 1, 4) = pt5sq3*(sa_d*s2b + sa*s2b_d)
2149 d_d(:, 2, 4) = sa_d*c2b + sa*c2b_d
2150 d_d(:, 3, 4) = ca_d*cb + ca*cb_d
2151 d_d(:, 4, 4) = -0.5_dp*(sa_d*s2b + sa*s2b_d)
2152 d_d(:, 5, 4) = -ca_d*sb - ca*sb_d
2153 d_d(:, 1, 5) = pt5sq3*(s2a_d*sb2 + s2a*sb2_d)
2154 d_d(:, 2, 5) = 0.5_dp*(s2a_d*s2b + s2a*s2b_d)
2155 d_d(:, 3, 5) = c2a_d*sb + c2a*sb_d
2156 d_d(:, 4, 5) = s2a_d*(cb2 + 0.5_dp*sb2) + s2a*(cb2_d + 0.5_dp*sb2_d)
2157 d_d(:, 5, 5) = c2a_d*cb + c2a*cb_d
2158 END IF
2159 ! Derivative for Rotation Elements for : S-P
2160 DO k = 1, 3
2161 DO l = 1, 3
2162 ij_matrix%sp_d(:, k, l) = p_d(:, k, l)
2163 END DO
2164 END DO
2165 ! Derivative for Rotation Elements for : P-P
2166 DO k = 1, 3
2167 ij_matrix%pp_d(:, 1, k, k) = p_d(:, k, 1)*p(k, 1) + p(k, 1)*p_d(:, k, 1)
2168 ij_matrix%pp_d(:, 2, k, k) = p_d(:, k, 2)*p(k, 2) + p(k, 2)*p_d(:, k, 2)
2169 ij_matrix%pp_d(:, 3, k, k) = p_d(:, k, 3)*p(k, 3) + p(k, 3)*p_d(:, k, 3)
2170 ij_matrix%pp_d(:, 4, k, k) = p_d(:, k, 1)*p(k, 2) + p(k, 1)*p_d(:, k, 2)
2171 ij_matrix%pp_d(:, 5, k, k) = p_d(:, k, 1)*p(k, 3) + p(k, 1)*p_d(:, k, 3)
2172 ij_matrix%pp_d(:, 6, k, k) = p_d(:, k, 2)*p(k, 3) + p(k, 2)*p_d(:, k, 3)
2173 IF (k /= 1) THEN
2174 DO l = 1, k - 1
2175 ij_matrix%pp_d(:, 1, k, l) = 2.0_dp*(p_d(:, k, 1)*p(l, 1) + p(k, 1)*p_d(:, l, 1))
2176 ij_matrix%pp_d(:, 2, k, l) = 2.0_dp*(p_d(:, k, 2)*p(l, 2) + p(k, 2)*p_d(:, l, 2))
2177 ij_matrix%pp_d(:, 3, k, l) = 2.0_dp*(p_d(:, k, 3)*p(l, 3) + p(k, 3)*p_d(:, l, 3))
2178 ij_matrix%pp_d(:, 4, k, l) = (p_d(:, k, 1)*p(l, 2) + p(k, 1)*p_d(:, l, 2)) + &
2179 (p_d(:, k, 2)*p(l, 1) + p(k, 2)*p_d(:, l, 1))
2180 ij_matrix%pp_d(:, 5, k, l) = (p_d(:, k, 1)*p(l, 3) + p(k, 1)*p_d(:, l, 3)) + &
2181 (p_d(:, k, 3)*p(l, 1) + p(k, 3)*p_d(:, l, 1))
2182 ij_matrix%pp_d(:, 6, k, l) = (p_d(:, k, 2)*p(l, 3) + p(k, 2)*p_d(:, l, 3)) + &
2183 (p_d(:, k, 3)*p(l, 2) + p(k, 3)*p_d(:, l, 2))
2184 END DO
2185 END IF
2186 END DO
2187 IF (sepi%dorb .OR. sepj%dorb) THEN
2188 ! Rotation Elements for : S-D
2189 DO k = 1, 5
2190 DO l = 1, 5
2191 ij_matrix%sd_d(:, k, l) = d_d(:, k, l)
2192 END DO
2193 END DO
2194 ! Rotation Elements for : D-P
2195 DO k = 1, 5
2196 DO l = 1, 3
2197 ij_matrix%pd_d(:, 1, k, l) = (d_d(:, k, 1)*p(l, 1) + d(k, 1)*p_d(:, l, 1))
2198 ij_matrix%pd_d(:, 2, k, l) = (d_d(:, k, 1)*p(l, 2) + d(k, 1)*p_d(:, l, 2))
2199 ij_matrix%pd_d(:, 3, k, l) = (d_d(:, k, 1)*p(l, 3) + d(k, 1)*p_d(:, l, 3))
2200 ij_matrix%pd_d(:, 4, k, l) = (d_d(:, k, 2)*p(l, 1) + d(k, 2)*p_d(:, l, 1))
2201 ij_matrix%pd_d(:, 5, k, l) = (d_d(:, k, 2)*p(l, 2) + d(k, 2)*p_d(:, l, 2))
2202 ij_matrix%pd_d(:, 6, k, l) = (d_d(:, k, 2)*p(l, 3) + d(k, 2)*p_d(:, l, 3))
2203 ij_matrix%pd_d(:, 7, k, l) = (d_d(:, k, 3)*p(l, 1) + d(k, 3)*p_d(:, l, 1))
2204 ij_matrix%pd_d(:, 8, k, l) = (d_d(:, k, 3)*p(l, 2) + d(k, 3)*p_d(:, l, 2))
2205 ij_matrix%pd_d(:, 9, k, l) = (d_d(:, k, 3)*p(l, 3) + d(k, 3)*p_d(:, l, 3))
2206 ij_matrix%pd_d(:, 10, k, l) = (d_d(:, k, 4)*p(l, 1) + d(k, 4)*p_d(:, l, 1))
2207 ij_matrix%pd_d(:, 11, k, l) = (d_d(:, k, 4)*p(l, 2) + d(k, 4)*p_d(:, l, 2))
2208 ij_matrix%pd_d(:, 12, k, l) = (d_d(:, k, 4)*p(l, 3) + d(k, 4)*p_d(:, l, 3))
2209 ij_matrix%pd_d(:, 13, k, l) = (d_d(:, k, 5)*p(l, 1) + d(k, 5)*p_d(:, l, 1))
2210 ij_matrix%pd_d(:, 14, k, l) = (d_d(:, k, 5)*p(l, 2) + d(k, 5)*p_d(:, l, 2))
2211 ij_matrix%pd_d(:, 15, k, l) = (d_d(:, k, 5)*p(l, 3) + d(k, 5)*p_d(:, l, 3))
2212 END DO
2213 END DO
2214 ! Rotation Elements for : D-D
2215 DO k = 1, 5
2216 ij_matrix%dd_d(:, 1, k, k) = (d_d(:, k, 1)*d(k, 1) + d(k, 1)*d_d(:, k, 1))
2217 ij_matrix%dd_d(:, 2, k, k) = (d_d(:, k, 2)*d(k, 2) + d(k, 2)*d_d(:, k, 2))
2218 ij_matrix%dd_d(:, 3, k, k) = (d_d(:, k, 3)*d(k, 3) + d(k, 3)*d_d(:, k, 3))
2219 ij_matrix%dd_d(:, 4, k, k) = (d_d(:, k, 4)*d(k, 4) + d(k, 4)*d_d(:, k, 4))
2220 ij_matrix%dd_d(:, 5, k, k) = (d_d(:, k, 5)*d(k, 5) + d(k, 5)*d_d(:, k, 5))
2221 ij_matrix%dd_d(:, 6, k, k) = (d_d(:, k, 1)*d(k, 2) + d(k, 1)*d_d(:, k, 2))
2222 ij_matrix%dd_d(:, 7, k, k) = (d_d(:, k, 1)*d(k, 3) + d(k, 1)*d_d(:, k, 3))
2223 ij_matrix%dd_d(:, 8, k, k) = (d_d(:, k, 2)*d(k, 3) + d(k, 2)*d_d(:, k, 3))
2224 ij_matrix%dd_d(:, 9, k, k) = (d_d(:, k, 1)*d(k, 4) + d(k, 1)*d_d(:, k, 4))
2225 ij_matrix%dd_d(:, 10, k, k) = (d_d(:, k, 2)*d(k, 4) + d(k, 2)*d_d(:, k, 4))
2226 ij_matrix%dd_d(:, 11, k, k) = (d_d(:, k, 3)*d(k, 4) + d(k, 3)*d_d(:, k, 4))
2227 ij_matrix%dd_d(:, 12, k, k) = (d_d(:, k, 1)*d(k, 5) + d(k, 1)*d_d(:, k, 5))
2228 ij_matrix%dd_d(:, 13, k, k) = (d_d(:, k, 2)*d(k, 5) + d(k, 2)*d_d(:, k, 5))
2229 ij_matrix%dd_d(:, 14, k, k) = (d_d(:, k, 3)*d(k, 5) + d(k, 3)*d_d(:, k, 5))
2230 ij_matrix%dd_d(:, 15, k, k) = (d_d(:, k, 4)*d(k, 5) + d(k, 4)*d_d(:, k, 5))
2231 IF (k /= 1) THEN
2232 DO l = 1, k - 1
2233 ij_matrix%dd_d(:, 1, k, l) = 2.0_dp*(d_d(:, k, 1)*d(l, 1) + d(k, 1)*d_d(:, l, 1))
2234 ij_matrix%dd_d(:, 2, k, l) = 2.0_dp*(d_d(:, k, 2)*d(l, 2) + d(k, 2)*d_d(:, l, 2))
2235 ij_matrix%dd_d(:, 3, k, l) = 2.0_dp*(d_d(:, k, 3)*d(l, 3) + d(k, 3)*d_d(:, l, 3))
2236 ij_matrix%dd_d(:, 4, k, l) = 2.0_dp*(d_d(:, k, 4)*d(l, 4) + d(k, 4)*d_d(:, l, 4))
2237 ij_matrix%dd_d(:, 5, k, l) = 2.0_dp*(d_d(:, k, 5)*d(l, 5) + d(k, 5)*d_d(:, l, 5))
2238 ij_matrix%dd_d(:, 6, k, l) = (d_d(:, k, 1)*d(l, 2) + d(k, 1)*d_d(:, l, 2)) + &
2239 (d_d(:, k, 2)*d(l, 1) + d(k, 2)*d_d(:, l, 1))
2240 ij_matrix%dd_d(:, 7, k, l) = (d_d(:, k, 1)*d(l, 3) + d(k, 1)*d_d(:, l, 3)) + &
2241 (d_d(:, k, 3)*d(l, 1) + d(k, 3)*d_d(:, l, 1))
2242 ij_matrix%dd_d(:, 8, k, l) = (d_d(:, k, 2)*d(l, 3) + d(k, 2)*d_d(:, l, 3)) + &
2243 (d_d(:, k, 3)*d(l, 2) + d(k, 3)*d_d(:, l, 2))
2244 ij_matrix%dd_d(:, 9, k, l) = (d_d(:, k, 1)*d(l, 4) + d(k, 1)*d_d(:, l, 4)) + &
2245 (d_d(:, k, 4)*d(l, 1) + d(k, 4)*d_d(:, l, 1))
2246 ij_matrix%dd_d(:, 10, k, l) = (d_d(:, k, 2)*d(l, 4) + d(k, 2)*d_d(:, l, 4)) + &
2247 (d_d(:, k, 4)*d(l, 2) + d(k, 4)*d_d(:, l, 2))
2248 ij_matrix%dd_d(:, 11, k, l) = (d_d(:, k, 3)*d(l, 4) + d(k, 3)*d_d(:, l, 4)) + &
2249 (d_d(:, k, 4)*d(l, 3) + d(k, 4)*d_d(:, l, 3))
2250 ij_matrix%dd_d(:, 12, k, l) = (d_d(:, k, 1)*d(l, 5) + d(k, 1)*d_d(:, l, 5)) + &
2251 (d_d(:, k, 5)*d(l, 1) + d(k, 5)*d_d(:, l, 1))
2252 ij_matrix%dd_d(:, 13, k, l) = (d_d(:, k, 2)*d(l, 5) + d(k, 2)*d_d(:, l, 5)) + &
2253 (d_d(:, k, 5)*d(l, 2) + d(k, 5)*d_d(:, l, 2))
2254 ij_matrix%dd_d(:, 14, k, l) = (d_d(:, k, 3)*d(l, 5) + d(k, 3)*d_d(:, l, 5)) + &
2255 (d_d(:, k, 5)*d(l, 3) + d(k, 5)*d_d(:, l, 3))
2256 ij_matrix%dd_d(:, 15, k, l) = (d_d(:, k, 4)*d(l, 5) + d(k, 4)*d_d(:, l, 5)) + &
2257 (d_d(:, k, 5)*d(l, 4) + d(k, 5)*d_d(:, l, 4))
2258 END DO
2259 END IF
2260 END DO
2261 END IF
2262 IF (debug_this_module) THEN
2263 CALL check_rotmat_der(sepi, sepj, rjiv, ij_matrix, do_invert=do_invert)
2264 END IF
2265 END IF
2266 END IF
2267 END SUBROUTINE rotmat
2268
2269! **************************************************************************************************
2270!> \brief First Step of the rotation of the two-electron two-center integrals in
2271!> SPD basis
2272!>
2273!> \param sepi ...
2274!> \param sepj ...
2275!> \param rijv ...
2276!> \param se_int_control ...
2277!> \param se_taper ...
2278!> \param invert ...
2279!> \param ii ...
2280!> \param kk ...
2281!> \param rep ...
2282!> \param logv ...
2283!> \param ij_matrix ...
2284!> \param v ...
2285!> \param lgrad ...
2286!> \param rep_d ...
2287!> \param v_d ...
2288!> \param logv_d ...
2289!> \param drij ...
2290!> \date 04.2008 [tlaino]
2291!> \author Teodoro Laino [tlaino] - University of Zurich
2292! **************************************************************************************************
2293 RECURSIVE SUBROUTINE rot_2el_2c_first(sepi, sepj, rijv, se_int_control, se_taper, &
2294 invert, ii, kk, rep, logv, ij_matrix, v, lgrad, rep_d, v_d, logv_d, drij)
2295 TYPE(semi_empirical_type), POINTER :: sepi, sepj
2296 REAL(kind=dp), DIMENSION(3), INTENT(IN) :: rijv
2297 TYPE(se_int_control_type), INTENT(IN) :: se_int_control
2298 TYPE(se_taper_type), POINTER :: se_taper
2299 LOGICAL, INTENT(IN) :: invert
2300 INTEGER, INTENT(IN) :: ii, kk
2301 REAL(kind=dp), DIMENSION(491), INTENT(IN) :: rep
2302 LOGICAL, DIMENSION(45, 45), INTENT(OUT) :: logv
2303 TYPE(rotmat_type), POINTER :: ij_matrix
2304 REAL(kind=dp), DIMENSION(45, 45), INTENT(OUT) :: v
2305 LOGICAL, INTENT(IN) :: lgrad
2306 REAL(kind=dp), DIMENSION(491), INTENT(IN), &
2307 OPTIONAL :: rep_d
2308 REAL(kind=dp), DIMENSION(3, 45, 45), INTENT(OUT), &
2309 OPTIONAL :: v_d
2310 LOGICAL, DIMENSION(45, 45), INTENT(OUT), OPTIONAL :: logv_d
2311 REAL(kind=dp), DIMENSION(3), INTENT(IN), OPTIONAL :: drij
2312
2313 INTEGER :: i, i1, ij, j1, k, k1, kl, l, l1, limkl, &
2314 ll, mm, nd
2315 REAL(kind=dp) :: wrepp, wrepp_d(3)
2316
2317 IF (lgrad) THEN
2318 cpassert(PRESENT(rep_d))
2319 cpassert(PRESENT(v_d))
2320 cpassert(PRESENT(logv_d))
2321 cpassert(PRESENT(drij))
2322 END IF
2323 limkl = indexb(kk, kk)
2324 DO k = 1, limkl
2325 DO i = 1, 45
2326 logv(i, k) = .false.
2327 v(i, k) = 0.0_dp
2328 END DO
2329 END DO
2330 !
2331 DO i1 = 1, ii
2332 DO j1 = 1, i1
2333 ij = indexa(i1, j1)
2334 !
2335 DO k1 = 1, kk
2336 !
2337 DO l1 = 1, k1
2338 kl = indexa(k1, l1)
2339 nd = ijkl_ind(ij, kl)
2340 IF (nd /= 0) THEN
2341 !
2342 wrepp = rep(nd)
2343 ll = indexb(k1, l1)
2344 mm = int2c_type(ll)
2345 !
2346 IF (mm == 1) THEN
2347 v(ij, 1) = wrepp
2348 ELSE IF (mm == 2) THEN
2349 k = k1 - 1
2350 v(ij, 2) = v(ij, 2) + ij_matrix%sp(k, 1)*wrepp
2351 v(ij, 4) = v(ij, 4) + ij_matrix%sp(k, 2)*wrepp
2352 v(ij, 7) = v(ij, 7) + ij_matrix%sp(k, 3)*wrepp
2353 ELSE IF (mm == 3) THEN
2354 k = k1 - 1
2355 l = l1 - 1
2356 v(ij, 3) = v(ij, 3) + ij_matrix%pp(1, k, l)*wrepp
2357 v(ij, 6) = v(ij, 6) + ij_matrix%pp(2, k, l)*wrepp
2358 v(ij, 10) = v(ij, 10) + ij_matrix%pp(3, k, l)*wrepp
2359 v(ij, 5) = v(ij, 5) + ij_matrix%pp(4, k, l)*wrepp
2360 v(ij, 8) = v(ij, 8) + ij_matrix%pp(5, k, l)*wrepp
2361 v(ij, 9) = v(ij, 9) + ij_matrix%pp(6, k, l)*wrepp
2362 ELSE IF (mm == 4) THEN
2363 k = k1 - 4
2364 v(ij, 11) = v(ij, 11) + ij_matrix%sd(k, 1)*wrepp
2365 v(ij, 16) = v(ij, 16) + ij_matrix%sd(k, 2)*wrepp
2366 v(ij, 22) = v(ij, 22) + ij_matrix%sd(k, 3)*wrepp
2367 v(ij, 29) = v(ij, 29) + ij_matrix%sd(k, 4)*wrepp
2368 v(ij, 37) = v(ij, 37) + ij_matrix%sd(k, 5)*wrepp
2369 ELSE IF (mm == 5) THEN
2370 k = k1 - 4
2371 l = l1 - 1
2372 v(ij, 12) = v(ij, 12) + ij_matrix%pd(1, k, l)*wrepp
2373 v(ij, 13) = v(ij, 13) + ij_matrix%pd(2, k, l)*wrepp
2374 v(ij, 14) = v(ij, 14) + ij_matrix%pd(3, k, l)*wrepp
2375 v(ij, 17) = v(ij, 17) + ij_matrix%pd(4, k, l)*wrepp
2376 v(ij, 18) = v(ij, 18) + ij_matrix%pd(5, k, l)*wrepp
2377 v(ij, 19) = v(ij, 19) + ij_matrix%pd(6, k, l)*wrepp
2378 v(ij, 23) = v(ij, 23) + ij_matrix%pd(7, k, l)*wrepp
2379 v(ij, 24) = v(ij, 24) + ij_matrix%pd(8, k, l)*wrepp
2380 v(ij, 25) = v(ij, 25) + ij_matrix%pd(9, k, l)*wrepp
2381 v(ij, 30) = v(ij, 30) + ij_matrix%pd(10, k, l)*wrepp
2382 v(ij, 31) = v(ij, 31) + ij_matrix%pd(11, k, l)*wrepp
2383 v(ij, 32) = v(ij, 32) + ij_matrix%pd(12, k, l)*wrepp
2384 v(ij, 38) = v(ij, 38) + ij_matrix%pd(13, k, l)*wrepp
2385 v(ij, 39) = v(ij, 39) + ij_matrix%pd(14, k, l)*wrepp
2386 v(ij, 40) = v(ij, 40) + ij_matrix%pd(15, k, l)*wrepp
2387 ELSE IF (mm == 6) THEN
2388 k = k1 - 4
2389 l = l1 - 4
2390 v(ij, 15) = v(ij, 15) + ij_matrix%dd(1, k, l)*wrepp
2391 v(ij, 21) = v(ij, 21) + ij_matrix%dd(2, k, l)*wrepp
2392 v(ij, 28) = v(ij, 28) + ij_matrix%dd(3, k, l)*wrepp
2393 v(ij, 36) = v(ij, 36) + ij_matrix%dd(4, k, l)*wrepp
2394 v(ij, 45) = v(ij, 45) + ij_matrix%dd(5, k, l)*wrepp
2395 v(ij, 20) = v(ij, 20) + ij_matrix%dd(6, k, l)*wrepp
2396 v(ij, 26) = v(ij, 26) + ij_matrix%dd(7, k, l)*wrepp
2397 v(ij, 27) = v(ij, 27) + ij_matrix%dd(8, k, l)*wrepp
2398 v(ij, 33) = v(ij, 33) + ij_matrix%dd(9, k, l)*wrepp
2399 v(ij, 34) = v(ij, 34) + ij_matrix%dd(10, k, l)*wrepp
2400 v(ij, 35) = v(ij, 35) + ij_matrix%dd(11, k, l)*wrepp
2401 v(ij, 41) = v(ij, 41) + ij_matrix%dd(12, k, l)*wrepp
2402 v(ij, 42) = v(ij, 42) + ij_matrix%dd(13, k, l)*wrepp
2403 v(ij, 43) = v(ij, 43) + ij_matrix%dd(14, k, l)*wrepp
2404 v(ij, 44) = v(ij, 44) + ij_matrix%dd(15, k, l)*wrepp
2405 END IF
2406 END IF
2407 END DO
2408 END DO
2409 DO kl = 1, limkl
2410 logv(ij, kl) = (abs(v(ij, kl)) > 0.0_dp)
2411 END DO
2412 END DO
2413 END DO
2414 ! Gradients
2415 IF (lgrad) THEN
2416 DO k = 1, limkl
2417 DO i = 1, 45
2418 logv_d(i, k) = .false.
2419 v_d(1, i, k) = 0.0_dp
2420 v_d(2, i, k) = 0.0_dp
2421 v_d(3, i, k) = 0.0_dp
2422 END DO
2423 END DO
2424 DO i1 = 1, ii
2425 DO j1 = 1, i1
2426 ij = indexa(i1, j1)
2427 !
2428 DO k1 = 1, kk
2429 !
2430 DO l1 = 1, k1
2431 kl = indexa(k1, l1)
2432 nd = ijkl_ind(ij, kl)
2433 IF (nd /= 0) THEN
2434 !
2435 wrepp = rep(nd)
2436 wrepp_d = rep_d(nd)*drij
2437 ll = indexb(k1, l1)
2438 mm = int2c_type(ll)
2439 !
2440 IF (mm == 1) THEN
2441 v_d(1, ij, 1) = wrepp_d(1)
2442 v_d(2, ij, 1) = wrepp_d(2)
2443 v_d(3, ij, 1) = wrepp_d(3)
2444 ELSE IF (mm == 2) THEN
2445 k = k1 - 1
2446 v_d(1, ij, 2) = v_d(1, ij, 2) + ij_matrix%sp_d(1, k, 1)*wrepp + ij_matrix%sp(k, 1)*wrepp_d(1)
2447 v_d(1, ij, 4) = v_d(1, ij, 4) + ij_matrix%sp_d(1, k, 2)*wrepp + ij_matrix%sp(k, 2)*wrepp_d(1)
2448 v_d(1, ij, 7) = v_d(1, ij, 7) + ij_matrix%sp_d(1, k, 3)*wrepp + ij_matrix%sp(k, 3)*wrepp_d(1)
2449
2450 v_d(2, ij, 2) = v_d(2, ij, 2) + ij_matrix%sp_d(2, k, 1)*wrepp + ij_matrix%sp(k, 1)*wrepp_d(2)
2451 v_d(2, ij, 4) = v_d(2, ij, 4) + ij_matrix%sp_d(2, k, 2)*wrepp + ij_matrix%sp(k, 2)*wrepp_d(2)
2452 v_d(2, ij, 7) = v_d(2, ij, 7) + ij_matrix%sp_d(2, k, 3)*wrepp + ij_matrix%sp(k, 3)*wrepp_d(2)
2453
2454 v_d(3, ij, 2) = v_d(3, ij, 2) + ij_matrix%sp_d(3, k, 1)*wrepp + ij_matrix%sp(k, 1)*wrepp_d(3)
2455 v_d(3, ij, 4) = v_d(3, ij, 4) + ij_matrix%sp_d(3, k, 2)*wrepp + ij_matrix%sp(k, 2)*wrepp_d(3)
2456 v_d(3, ij, 7) = v_d(3, ij, 7) + ij_matrix%sp_d(3, k, 3)*wrepp + ij_matrix%sp(k, 3)*wrepp_d(3)
2457 ELSE IF (mm == 3) THEN
2458 k = k1 - 1
2459 l = l1 - 1
2460 v_d(1, ij, 3) = v_d(1, ij, 3) + ij_matrix%pp_d(1, 1, k, l)*wrepp + ij_matrix%pp(1, k, l)*wrepp_d(1)
2461 v_d(1, ij, 6) = v_d(1, ij, 6) + ij_matrix%pp_d(1, 2, k, l)*wrepp + ij_matrix%pp(2, k, l)*wrepp_d(1)
2462 v_d(1, ij, 10) = v_d(1, ij, 10) + ij_matrix%pp_d(1, 3, k, l)*wrepp + ij_matrix%pp(3, k, l)*wrepp_d(1)
2463 v_d(1, ij, 5) = v_d(1, ij, 5) + ij_matrix%pp_d(1, 4, k, l)*wrepp + ij_matrix%pp(4, k, l)*wrepp_d(1)
2464 v_d(1, ij, 8) = v_d(1, ij, 8) + ij_matrix%pp_d(1, 5, k, l)*wrepp + ij_matrix%pp(5, k, l)*wrepp_d(1)
2465 v_d(1, ij, 9) = v_d(1, ij, 9) + ij_matrix%pp_d(1, 6, k, l)*wrepp + ij_matrix%pp(6, k, l)*wrepp_d(1)
2466
2467 v_d(2, ij, 3) = v_d(2, ij, 3) + ij_matrix%pp_d(2, 1, k, l)*wrepp + ij_matrix%pp(1, k, l)*wrepp_d(2)
2468 v_d(2, ij, 6) = v_d(2, ij, 6) + ij_matrix%pp_d(2, 2, k, l)*wrepp + ij_matrix%pp(2, k, l)*wrepp_d(2)
2469 v_d(2, ij, 10) = v_d(2, ij, 10) + ij_matrix%pp_d(2, 3, k, l)*wrepp + ij_matrix%pp(3, k, l)*wrepp_d(2)
2470 v_d(2, ij, 5) = v_d(2, ij, 5) + ij_matrix%pp_d(2, 4, k, l)*wrepp + ij_matrix%pp(4, k, l)*wrepp_d(2)
2471 v_d(2, ij, 8) = v_d(2, ij, 8) + ij_matrix%pp_d(2, 5, k, l)*wrepp + ij_matrix%pp(5, k, l)*wrepp_d(2)
2472 v_d(2, ij, 9) = v_d(2, ij, 9) + ij_matrix%pp_d(2, 6, k, l)*wrepp + ij_matrix%pp(6, k, l)*wrepp_d(2)
2473
2474 v_d(3, ij, 3) = v_d(3, ij, 3) + ij_matrix%pp_d(3, 1, k, l)*wrepp + ij_matrix%pp(1, k, l)*wrepp_d(3)
2475 v_d(3, ij, 6) = v_d(3, ij, 6) + ij_matrix%pp_d(3, 2, k, l)*wrepp + ij_matrix%pp(2, k, l)*wrepp_d(3)
2476 v_d(3, ij, 10) = v_d(3, ij, 10) + ij_matrix%pp_d(3, 3, k, l)*wrepp + ij_matrix%pp(3, k, l)*wrepp_d(3)
2477 v_d(3, ij, 5) = v_d(3, ij, 5) + ij_matrix%pp_d(3, 4, k, l)*wrepp + ij_matrix%pp(4, k, l)*wrepp_d(3)
2478 v_d(3, ij, 8) = v_d(3, ij, 8) + ij_matrix%pp_d(3, 5, k, l)*wrepp + ij_matrix%pp(5, k, l)*wrepp_d(3)
2479 v_d(3, ij, 9) = v_d(3, ij, 9) + ij_matrix%pp_d(3, 6, k, l)*wrepp + ij_matrix%pp(6, k, l)*wrepp_d(3)
2480 ELSE IF (mm == 4) THEN
2481 k = k1 - 4
2482 v_d(1, ij, 11) = v_d(1, ij, 11) + ij_matrix%sd_d(1, k, 1)*wrepp + ij_matrix%sd(k, 1)*wrepp_d(1)
2483 v_d(1, ij, 16) = v_d(1, ij, 16) + ij_matrix%sd_d(1, k, 2)*wrepp + ij_matrix%sd(k, 2)*wrepp_d(1)
2484 v_d(1, ij, 22) = v_d(1, ij, 22) + ij_matrix%sd_d(1, k, 3)*wrepp + ij_matrix%sd(k, 3)*wrepp_d(1)
2485 v_d(1, ij, 29) = v_d(1, ij, 29) + ij_matrix%sd_d(1, k, 4)*wrepp + ij_matrix%sd(k, 4)*wrepp_d(1)
2486 v_d(1, ij, 37) = v_d(1, ij, 37) + ij_matrix%sd_d(1, k, 5)*wrepp + ij_matrix%sd(k, 5)*wrepp_d(1)
2487
2488 v_d(2, ij, 11) = v_d(2, ij, 11) + ij_matrix%sd_d(2, k, 1)*wrepp + ij_matrix%sd(k, 1)*wrepp_d(2)
2489 v_d(2, ij, 16) = v_d(2, ij, 16) + ij_matrix%sd_d(2, k, 2)*wrepp + ij_matrix%sd(k, 2)*wrepp_d(2)
2490 v_d(2, ij, 22) = v_d(2, ij, 22) + ij_matrix%sd_d(2, k, 3)*wrepp + ij_matrix%sd(k, 3)*wrepp_d(2)
2491 v_d(2, ij, 29) = v_d(2, ij, 29) + ij_matrix%sd_d(2, k, 4)*wrepp + ij_matrix%sd(k, 4)*wrepp_d(2)
2492 v_d(2, ij, 37) = v_d(2, ij, 37) + ij_matrix%sd_d(2, k, 5)*wrepp + ij_matrix%sd(k, 5)*wrepp_d(2)
2493
2494 v_d(3, ij, 11) = v_d(3, ij, 11) + ij_matrix%sd_d(3, k, 1)*wrepp + ij_matrix%sd(k, 1)*wrepp_d(3)
2495 v_d(3, ij, 16) = v_d(3, ij, 16) + ij_matrix%sd_d(3, k, 2)*wrepp + ij_matrix%sd(k, 2)*wrepp_d(3)
2496 v_d(3, ij, 22) = v_d(3, ij, 22) + ij_matrix%sd_d(3, k, 3)*wrepp + ij_matrix%sd(k, 3)*wrepp_d(3)
2497 v_d(3, ij, 29) = v_d(3, ij, 29) + ij_matrix%sd_d(3, k, 4)*wrepp + ij_matrix%sd(k, 4)*wrepp_d(3)
2498 v_d(3, ij, 37) = v_d(3, ij, 37) + ij_matrix%sd_d(3, k, 5)*wrepp + ij_matrix%sd(k, 5)*wrepp_d(3)
2499 ELSE IF (mm == 5) THEN
2500 k = k1 - 4
2501 l = l1 - 1
2502 v_d(1, ij, 12) = v_d(1, ij, 12) + ij_matrix%pd_d(1, 1, k, l)*wrepp + ij_matrix%pd(1, k, l)*wrepp_d(1)
2503 v_d(1, ij, 13) = v_d(1, ij, 13) + ij_matrix%pd_d(1, 2, k, l)*wrepp + ij_matrix%pd(2, k, l)*wrepp_d(1)
2504 v_d(1, ij, 14) = v_d(1, ij, 14) + ij_matrix%pd_d(1, 3, k, l)*wrepp + ij_matrix%pd(3, k, l)*wrepp_d(1)
2505 v_d(1, ij, 17) = v_d(1, ij, 17) + ij_matrix%pd_d(1, 4, k, l)*wrepp + ij_matrix%pd(4, k, l)*wrepp_d(1)
2506 v_d(1, ij, 18) = v_d(1, ij, 18) + ij_matrix%pd_d(1, 5, k, l)*wrepp + ij_matrix%pd(5, k, l)*wrepp_d(1)
2507 v_d(1, ij, 19) = v_d(1, ij, 19) + ij_matrix%pd_d(1, 6, k, l)*wrepp + ij_matrix%pd(6, k, l)*wrepp_d(1)
2508 v_d(1, ij, 23) = v_d(1, ij, 23) + ij_matrix%pd_d(1, 7, k, l)*wrepp + ij_matrix%pd(7, k, l)*wrepp_d(1)
2509 v_d(1, ij, 24) = v_d(1, ij, 24) + ij_matrix%pd_d(1, 8, k, l)*wrepp + ij_matrix%pd(8, k, l)*wrepp_d(1)
2510 v_d(1, ij, 25) = v_d(1, ij, 25) + ij_matrix%pd_d(1, 9, k, l)*wrepp + ij_matrix%pd(9, k, l)*wrepp_d(1)
2511 v_d(1, ij, 30) = v_d(1, ij, 30) + ij_matrix%pd_d(1, 10, k, l)*wrepp + ij_matrix%pd(10, k, l)*wrepp_d(1)
2512 v_d(1, ij, 31) = v_d(1, ij, 31) + ij_matrix%pd_d(1, 11, k, l)*wrepp + ij_matrix%pd(11, k, l)*wrepp_d(1)
2513 v_d(1, ij, 32) = v_d(1, ij, 32) + ij_matrix%pd_d(1, 12, k, l)*wrepp + ij_matrix%pd(12, k, l)*wrepp_d(1)
2514 v_d(1, ij, 38) = v_d(1, ij, 38) + ij_matrix%pd_d(1, 13, k, l)*wrepp + ij_matrix%pd(13, k, l)*wrepp_d(1)
2515 v_d(1, ij, 39) = v_d(1, ij, 39) + ij_matrix%pd_d(1, 14, k, l)*wrepp + ij_matrix%pd(14, k, l)*wrepp_d(1)
2516 v_d(1, ij, 40) = v_d(1, ij, 40) + ij_matrix%pd_d(1, 15, k, l)*wrepp + ij_matrix%pd(15, k, l)*wrepp_d(1)
2517
2518 v_d(2, ij, 12) = v_d(2, ij, 12) + ij_matrix%pd_d(2, 1, k, l)*wrepp + ij_matrix%pd(1, k, l)*wrepp_d(2)
2519 v_d(2, ij, 13) = v_d(2, ij, 13) + ij_matrix%pd_d(2, 2, k, l)*wrepp + ij_matrix%pd(2, k, l)*wrepp_d(2)
2520 v_d(2, ij, 14) = v_d(2, ij, 14) + ij_matrix%pd_d(2, 3, k, l)*wrepp + ij_matrix%pd(3, k, l)*wrepp_d(2)
2521 v_d(2, ij, 17) = v_d(2, ij, 17) + ij_matrix%pd_d(2, 4, k, l)*wrepp + ij_matrix%pd(4, k, l)*wrepp_d(2)
2522 v_d(2, ij, 18) = v_d(2, ij, 18) + ij_matrix%pd_d(2, 5, k, l)*wrepp + ij_matrix%pd(5, k, l)*wrepp_d(2)
2523 v_d(2, ij, 19) = v_d(2, ij, 19) + ij_matrix%pd_d(2, 6, k, l)*wrepp + ij_matrix%pd(6, k, l)*wrepp_d(2)
2524 v_d(2, ij, 23) = v_d(2, ij, 23) + ij_matrix%pd_d(2, 7, k, l)*wrepp + ij_matrix%pd(7, k, l)*wrepp_d(2)
2525 v_d(2, ij, 24) = v_d(2, ij, 24) + ij_matrix%pd_d(2, 8, k, l)*wrepp + ij_matrix%pd(8, k, l)*wrepp_d(2)
2526 v_d(2, ij, 25) = v_d(2, ij, 25) + ij_matrix%pd_d(2, 9, k, l)*wrepp + ij_matrix%pd(9, k, l)*wrepp_d(2)
2527 v_d(2, ij, 30) = v_d(2, ij, 30) + ij_matrix%pd_d(2, 10, k, l)*wrepp + ij_matrix%pd(10, k, l)*wrepp_d(2)
2528 v_d(2, ij, 31) = v_d(2, ij, 31) + ij_matrix%pd_d(2, 11, k, l)*wrepp + ij_matrix%pd(11, k, l)*wrepp_d(2)
2529 v_d(2, ij, 32) = v_d(2, ij, 32) + ij_matrix%pd_d(2, 12, k, l)*wrepp + ij_matrix%pd(12, k, l)*wrepp_d(2)
2530 v_d(2, ij, 38) = v_d(2, ij, 38) + ij_matrix%pd_d(2, 13, k, l)*wrepp + ij_matrix%pd(13, k, l)*wrepp_d(2)
2531 v_d(2, ij, 39) = v_d(2, ij, 39) + ij_matrix%pd_d(2, 14, k, l)*wrepp + ij_matrix%pd(14, k, l)*wrepp_d(2)
2532 v_d(2, ij, 40) = v_d(2, ij, 40) + ij_matrix%pd_d(2, 15, k, l)*wrepp + ij_matrix%pd(15, k, l)*wrepp_d(2)
2533
2534 v_d(3, ij, 12) = v_d(3, ij, 12) + ij_matrix%pd_d(3, 1, k, l)*wrepp + ij_matrix%pd(1, k, l)*wrepp_d(3)
2535 v_d(3, ij, 13) = v_d(3, ij, 13) + ij_matrix%pd_d(3, 2, k, l)*wrepp + ij_matrix%pd(2, k, l)*wrepp_d(3)
2536 v_d(3, ij, 14) = v_d(3, ij, 14) + ij_matrix%pd_d(3, 3, k, l)*wrepp + ij_matrix%pd(3, k, l)*wrepp_d(3)
2537 v_d(3, ij, 17) = v_d(3, ij, 17) + ij_matrix%pd_d(3, 4, k, l)*wrepp + ij_matrix%pd(4, k, l)*wrepp_d(3)
2538 v_d(3, ij, 18) = v_d(3, ij, 18) + ij_matrix%pd_d(3, 5, k, l)*wrepp + ij_matrix%pd(5, k, l)*wrepp_d(3)
2539 v_d(3, ij, 19) = v_d(3, ij, 19) + ij_matrix%pd_d(3, 6, k, l)*wrepp + ij_matrix%pd(6, k, l)*wrepp_d(3)
2540 v_d(3, ij, 23) = v_d(3, ij, 23) + ij_matrix%pd_d(3, 7, k, l)*wrepp + ij_matrix%pd(7, k, l)*wrepp_d(3)
2541 v_d(3, ij, 24) = v_d(3, ij, 24) + ij_matrix%pd_d(3, 8, k, l)*wrepp + ij_matrix%pd(8, k, l)*wrepp_d(3)
2542 v_d(3, ij, 25) = v_d(3, ij, 25) + ij_matrix%pd_d(3, 9, k, l)*wrepp + ij_matrix%pd(9, k, l)*wrepp_d(3)
2543 v_d(3, ij, 30) = v_d(3, ij, 30) + ij_matrix%pd_d(3, 10, k, l)*wrepp + ij_matrix%pd(10, k, l)*wrepp_d(3)
2544 v_d(3, ij, 31) = v_d(3, ij, 31) + ij_matrix%pd_d(3, 11, k, l)*wrepp + ij_matrix%pd(11, k, l)*wrepp_d(3)
2545 v_d(3, ij, 32) = v_d(3, ij, 32) + ij_matrix%pd_d(3, 12, k, l)*wrepp + ij_matrix%pd(12, k, l)*wrepp_d(3)
2546 v_d(3, ij, 38) = v_d(3, ij, 38) + ij_matrix%pd_d(3, 13, k, l)*wrepp + ij_matrix%pd(13, k, l)*wrepp_d(3)
2547 v_d(3, ij, 39) = v_d(3, ij, 39) + ij_matrix%pd_d(3, 14, k, l)*wrepp + ij_matrix%pd(14, k, l)*wrepp_d(3)
2548 v_d(3, ij, 40) = v_d(3, ij, 40) + ij_matrix%pd_d(3, 15, k, l)*wrepp + ij_matrix%pd(15, k, l)*wrepp_d(3)
2549 ELSE IF (mm == 6) THEN
2550 k = k1 - 4
2551 l = l1 - 4
2552 v_d(1, ij, 15) = v_d(1, ij, 15) + ij_matrix%dd_d(1, 1, k, l)*wrepp + ij_matrix%dd(1, k, l)*wrepp_d(1)
2553 v_d(1, ij, 21) = v_d(1, ij, 21) + ij_matrix%dd_d(1, 2, k, l)*wrepp + ij_matrix%dd(2, k, l)*wrepp_d(1)
2554 v_d(1, ij, 28) = v_d(1, ij, 28) + ij_matrix%dd_d(1, 3, k, l)*wrepp + ij_matrix%dd(3, k, l)*wrepp_d(1)
2555 v_d(1, ij, 36) = v_d(1, ij, 36) + ij_matrix%dd_d(1, 4, k, l)*wrepp + ij_matrix%dd(4, k, l)*wrepp_d(1)
2556 v_d(1, ij, 45) = v_d(1, ij, 45) + ij_matrix%dd_d(1, 5, k, l)*wrepp + ij_matrix%dd(5, k, l)*wrepp_d(1)
2557 v_d(1, ij, 20) = v_d(1, ij, 20) + ij_matrix%dd_d(1, 6, k, l)*wrepp + ij_matrix%dd(6, k, l)*wrepp_d(1)
2558 v_d(1, ij, 26) = v_d(1, ij, 26) + ij_matrix%dd_d(1, 7, k, l)*wrepp + ij_matrix%dd(7, k, l)*wrepp_d(1)
2559 v_d(1, ij, 27) = v_d(1, ij, 27) + ij_matrix%dd_d(1, 8, k, l)*wrepp + ij_matrix%dd(8, k, l)*wrepp_d(1)
2560 v_d(1, ij, 33) = v_d(1, ij, 33) + ij_matrix%dd_d(1, 9, k, l)*wrepp + ij_matrix%dd(9, k, l)*wrepp_d(1)
2561 v_d(1, ij, 34) = v_d(1, ij, 34) + ij_matrix%dd_d(1, 10, k, l)*wrepp + ij_matrix%dd(10, k, l)*wrepp_d(1)
2562 v_d(1, ij, 35) = v_d(1, ij, 35) + ij_matrix%dd_d(1, 11, k, l)*wrepp + ij_matrix%dd(11, k, l)*wrepp_d(1)
2563 v_d(1, ij, 41) = v_d(1, ij, 41) + ij_matrix%dd_d(1, 12, k, l)*wrepp + ij_matrix%dd(12, k, l)*wrepp_d(1)
2564 v_d(1, ij, 42) = v_d(1, ij, 42) + ij_matrix%dd_d(1, 13, k, l)*wrepp + ij_matrix%dd(13, k, l)*wrepp_d(1)
2565 v_d(1, ij, 43) = v_d(1, ij, 43) + ij_matrix%dd_d(1, 14, k, l)*wrepp + ij_matrix%dd(14, k, l)*wrepp_d(1)
2566 v_d(1, ij, 44) = v_d(1, ij, 44) + ij_matrix%dd_d(1, 15, k, l)*wrepp + ij_matrix%dd(15, k, l)*wrepp_d(1)
2567
2568 v_d(2, ij, 15) = v_d(2, ij, 15) + ij_matrix%dd_d(2, 1, k, l)*wrepp + ij_matrix%dd(1, k, l)*wrepp_d(2)
2569 v_d(2, ij, 21) = v_d(2, ij, 21) + ij_matrix%dd_d(2, 2, k, l)*wrepp + ij_matrix%dd(2, k, l)*wrepp_d(2)
2570 v_d(2, ij, 28) = v_d(2, ij, 28) + ij_matrix%dd_d(2, 3, k, l)*wrepp + ij_matrix%dd(3, k, l)*wrepp_d(2)
2571 v_d(2, ij, 36) = v_d(2, ij, 36) + ij_matrix%dd_d(2, 4, k, l)*wrepp + ij_matrix%dd(4, k, l)*wrepp_d(2)
2572 v_d(2, ij, 45) = v_d(2, ij, 45) + ij_matrix%dd_d(2, 5, k, l)*wrepp + ij_matrix%dd(5, k, l)*wrepp_d(2)
2573 v_d(2, ij, 20) = v_d(2, ij, 20) + ij_matrix%dd_d(2, 6, k, l)*wrepp + ij_matrix%dd(6, k, l)*wrepp_d(2)
2574 v_d(2, ij, 26) = v_d(2, ij, 26) + ij_matrix%dd_d(2, 7, k, l)*wrepp + ij_matrix%dd(7, k, l)*wrepp_d(2)
2575 v_d(2, ij, 27) = v_d(2, ij, 27) + ij_matrix%dd_d(2, 8, k, l)*wrepp + ij_matrix%dd(8, k, l)*wrepp_d(2)
2576 v_d(2, ij, 33) = v_d(2, ij, 33) + ij_matrix%dd_d(2, 9, k, l)*wrepp + ij_matrix%dd(9, k, l)*wrepp_d(2)
2577 v_d(2, ij, 34) = v_d(2, ij, 34) + ij_matrix%dd_d(2, 10, k, l)*wrepp + ij_matrix%dd(10, k, l)*wrepp_d(2)
2578 v_d(2, ij, 35) = v_d(2, ij, 35) + ij_matrix%dd_d(2, 11, k, l)*wrepp + ij_matrix%dd(11, k, l)*wrepp_d(2)
2579 v_d(2, ij, 41) = v_d(2, ij, 41) + ij_matrix%dd_d(2, 12, k, l)*wrepp + ij_matrix%dd(12, k, l)*wrepp_d(2)
2580 v_d(2, ij, 42) = v_d(2, ij, 42) + ij_matrix%dd_d(2, 13, k, l)*wrepp + ij_matrix%dd(13, k, l)*wrepp_d(2)
2581 v_d(2, ij, 43) = v_d(2, ij, 43) + ij_matrix%dd_d(2, 14, k, l)*wrepp + ij_matrix%dd(14, k, l)*wrepp_d(2)
2582 v_d(2, ij, 44) = v_d(2, ij, 44) + ij_matrix%dd_d(2, 15, k, l)*wrepp + ij_matrix%dd(15, k, l)*wrepp_d(2)
2583
2584 v_d(3, ij, 15) = v_d(3, ij, 15) + ij_matrix%dd_d(3, 1, k, l)*wrepp + ij_matrix%dd(1, k, l)*wrepp_d(3)
2585 v_d(3, ij, 21) = v_d(3, ij, 21) + ij_matrix%dd_d(3, 2, k, l)*wrepp + ij_matrix%dd(2, k, l)*wrepp_d(3)
2586 v_d(3, ij, 28) = v_d(3, ij, 28) + ij_matrix%dd_d(3, 3, k, l)*wrepp + ij_matrix%dd(3, k, l)*wrepp_d(3)
2587 v_d(3, ij, 36) = v_d(3, ij, 36) + ij_matrix%dd_d(3, 4, k, l)*wrepp + ij_matrix%dd(4, k, l)*wrepp_d(3)
2588 v_d(3, ij, 45) = v_d(3, ij, 45) + ij_matrix%dd_d(3, 5, k, l)*wrepp + ij_matrix%dd(5, k, l)*wrepp_d(3)
2589 v_d(3, ij, 20) = v_d(3, ij, 20) + ij_matrix%dd_d(3, 6, k, l)*wrepp + ij_matrix%dd(6, k, l)*wrepp_d(3)
2590 v_d(3, ij, 26) = v_d(3, ij, 26) + ij_matrix%dd_d(3, 7, k, l)*wrepp + ij_matrix%dd(7, k, l)*wrepp_d(3)
2591 v_d(3, ij, 27) = v_d(3, ij, 27) + ij_matrix%dd_d(3, 8, k, l)*wrepp + ij_matrix%dd(8, k, l)*wrepp_d(3)
2592 v_d(3, ij, 33) = v_d(3, ij, 33) + ij_matrix%dd_d(3, 9, k, l)*wrepp + ij_matrix%dd(9, k, l)*wrepp_d(3)
2593 v_d(3, ij, 34) = v_d(3, ij, 34) + ij_matrix%dd_d(3, 10, k, l)*wrepp + ij_matrix%dd(10, k, l)*wrepp_d(3)
2594 v_d(3, ij, 35) = v_d(3, ij, 35) + ij_matrix%dd_d(3, 11, k, l)*wrepp + ij_matrix%dd(11, k, l)*wrepp_d(3)
2595 v_d(3, ij, 41) = v_d(3, ij, 41) + ij_matrix%dd_d(3, 12, k, l)*wrepp + ij_matrix%dd(12, k, l)*wrepp_d(3)
2596 v_d(3, ij, 42) = v_d(3, ij, 42) + ij_matrix%dd_d(3, 13, k, l)*wrepp + ij_matrix%dd(13, k, l)*wrepp_d(3)
2597 v_d(3, ij, 43) = v_d(3, ij, 43) + ij_matrix%dd_d(3, 14, k, l)*wrepp + ij_matrix%dd(14, k, l)*wrepp_d(3)
2598 v_d(3, ij, 44) = v_d(3, ij, 44) + ij_matrix%dd_d(3, 15, k, l)*wrepp + ij_matrix%dd(15, k, l)*wrepp_d(3)
2599 END IF
2600 END IF
2601 END DO
2602 END DO
2603 DO kl = 1, limkl
2604 logv_d(ij, kl) = (any(abs(v_d(1:3, ij, kl)) > 0.0_dp))
2605 END DO
2606 END DO
2607 END DO
2608 IF (debug_this_module) THEN
2609 CALL rot_2el_2c_first_debug(sepi, sepj, rijv, se_int_control, se_taper, invert, ii, kk, v_d)
2610 END IF
2611 END IF
2612 END SUBROUTINE rot_2el_2c_first
2613
2614! **************************************************************************************************
2615!> \brief Store the two-electron two-center integrals in diagonal form
2616!>
2617!> \param limij ...
2618!> \param limkl ...
2619!> \param ww ...
2620!> \param w ...
2621!> \param ww_dx ...
2622!> \param ww_dy ...
2623!> \param ww_dz ...
2624!> \param dw ...
2625!> \date 04.2008 [tlaino]
2626!> \author Teodoro Laino [tlaino] - University of Zurich
2627! **************************************************************************************************
2628 SUBROUTINE store_2el_2c_diag(limij, limkl, ww, w, ww_dx, ww_dy, ww_dz, dw)
2629
2630 INTEGER, INTENT(IN) :: limij, limkl
2631 REAL(kind=dp), DIMENSION(limkl, limij), &
2632 INTENT(IN), OPTIONAL :: ww
2633 REAL(kind=dp), DIMENSION(:), INTENT(INOUT), &
2634 OPTIONAL :: w
2635 REAL(kind=dp), DIMENSION(limkl, limij), &
2636 INTENT(IN), OPTIONAL :: ww_dx, ww_dy, ww_dz
2637 REAL(kind=dp), DIMENSION(:, :), INTENT(INOUT), &
2638 OPTIONAL :: dw
2639
2640 INTEGER :: ij, kl, l
2641
2642 l = 0
2643 IF (PRESENT(ww) .AND. PRESENT(w)) THEN
2644 DO ij = 1, limij
2645 DO kl = 1, limkl
2646 l = l + 1
2647 w(l) = ww(kl, ij)
2648 END DO
2649 END DO
2650 ELSE IF (PRESENT(ww_dx) .AND. PRESENT(ww_dy) .AND. PRESENT(ww_dz) .AND. PRESENT(dw)) THEN
2651 DO ij = 1, limij
2652 DO kl = 1, limkl
2653 l = l + 1
2654 dw(1, l) = ww_dx(kl, ij)
2655 dw(2, l) = ww_dy(kl, ij)
2656 dw(3, l) = ww_dz(kl, ij)
2657 END DO
2658 END DO
2659 ELSE
2660 cpabort("")
2661 END IF
2662
2663 END SUBROUTINE store_2el_2c_diag
2664
2665END MODULE semi_empirical_int_utils
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_method_pchg
integer, parameter, public do_se_is_kdso_d
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Utilities for evaluating the residual part (1/r^3) of Integrals for semi-empiric methods.
real(kind=dp) function, public charg_int_3(r, l1, l2, add)
Evaluates the residual Interaction function between two point-charges The term evaluated is the 1/r^3...
real(kind=dp) function, public ijkl_low_3(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, itype, eval)
Low level general driver for computing residual part of semi-empirical integrals <ij|kl> and their de...
real(kind=dp) function, public dcharg_int_3(r, l1, l2, add)
Derivatives of residual interaction function between two point-charges.
Arrays of parameters used in the semi-empirical calculations \References Everywhere in this module TC...
integer, dimension(9, 9), public indexb
integer, dimension(45), parameter, public int2c_type
integer, parameter, public clmz
integer, dimension(45, 0:2, -2:2), public clm_sp
integer, parameter, public clmzp
integer, parameter, public clmxy
integer, parameter, public clmzz
integer, parameter, public clmyy
real(kind=dp), dimension(45, 0:2, -2:2), public clm_d
integer, parameter, public clmp
integer, parameter, public clmxx
integer, dimension(9, 9), public indexa
integer, dimension(45, 45), public ijkl_ind
Utilities for Integrals for semi-empiric methods.
real(kind=dp) function, public d_ijkl_sp(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, se_int_screen, itype)
General driver for computing derivatives of semi-empirical integrals <ij|kl> with sp basis set....
real(kind=dp) function, public ijkl_sp(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, se_int_screen, itype)
General driver for computing semi-empirical integrals <ij|kl> with sp basis set. This code uses the o...
subroutine, public store_2el_2c_diag(limij, limkl, ww, w, ww_dx, ww_dy, ww_dz, dw)
Store the two-electron two-center integrals in diagonal form.
recursive subroutine, public rotmat(sepi, sepj, rjiv, r, ij_matrix, do_derivatives, do_invert, debug_invert)
Computes the general rotation matrices for the integrals between I and J (J>=I)
recursive subroutine, public rot_2el_2c_first(sepi, sepj, rijv, se_int_control, se_taper, invert, ii, kk, rep, logv, ij_matrix, v, lgrad, rep_d, v_d, logv_d, drij)
First Step of the rotation of the two-electron two-center integrals in SPD basis.
real(kind=dp) function, public ijkl_d(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, se_int_screen, itype)
General driver for computing semi-empirical integrals <ij|kl> involving d-orbitals....
real(kind=dp) function, public d_ijkl_d(sepi, sepj, ij, kl, li, lj, lk, ll, ic, r, se_int_control, se_int_screen, itype)
General driver for computing the derivatives of semi-empirical integrals <ij|kl> involving d-orbitals...
Definition of the semi empirical parameter types.
subroutine check_rotmat_der(sepi, sepj, rjiv, ij_matrix, do_invert)
Debug the derivatives of the the rotational matrices.
subroutine rot_2el_2c_first_debug(sepi, sepj, rijv, se_int_control, se_taper, invert, ii, kk, v_d)
Check Numerical Vs Analytical.
subroutine check_dssss_nucint_ana(sepi, sepj, r, dssss, itype, se_int_control, se_taper)
Check Numerical Vs Analytical ssss.
subroutine check_dcorecore_ana(sepi, sepj, rijv, itype, se_int_control, se_taper, enuc, denuc)
Check Numerical Vs Analytical CORE-CORE.
subroutine check_rotint_ana(sepi, sepj, rijv, w, dw, se_int_control, se_taper)
Check Numerical Vs Analytical ROTINT_ANA.
subroutine check_drotnuc_ana(sepi, sepj, rijv, itype, se_int_control, se_taper, e1b, e2a, de1b, de2a)
Check Numerical Vs Analytical.
subroutine check_dcore_nucint_ana(sepi, sepj, r, dcore, itype, se_int_control, se_taper)
Check Numerical Vs Analytical core.
subroutine check_dterep_ana(sepi, sepj, r, ri, dri, se_int_control, se_taper, lgrad)
Check Numerical Vs Analytical DTEREP_ANA.
Store the value of the tapering function and possibly its derivative for screened integrals.
Taper type use in semi-empirical calculations.