LCOV - code coverage report
Current view: top level - src/aobasis - ai_moments.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:2c0d679) Lines: 99.3 % 592 588
Test Date: 2026-09-25 00:58:37 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Calculation of the moment integrals over Cartesian Gaussian-type
      10              : !>      functions.
      11              : !> \par Literature
      12              : !>      S. Obara and A. Saika, J. Chem. Phys. 84, 3963 (1986)
      13              : !> \par History
      14              : !>      none
      15              : !> \author J. Hutter (16.02.2005)
      16              : ! **************************************************************************************************
      17              : MODULE ai_moments
      18              : 
      19              : ! ax,ay,az  : Angular momentum index numbers of orbital a.
      20              : ! bx,by,bz  : Angular momentum index numbers of orbital b.
      21              : ! coset     : Cartesian orbital set pointer.
      22              : ! dab       : Distance between the atomic centers a and b.
      23              : ! l{a,b}    : Angular momentum quantum number of shell a or b.
      24              : ! l{a,b}_max: Maximum angular momentum quantum number of shell a or b.
      25              : ! l{a,b}_min: Minimum angular momentum quantum number of shell a or b.
      26              : ! rac       : Distance vector between the atomic center a and reference point c.
      27              : ! rbc       : Distance vector between the atomic center b and reference point c.
      28              : ! rpgf{a,b} : Radius of the primitive Gaussian-type function a or b.
      29              : ! zet{a,b}  : Exponents of the Gaussian-type functions a or b.
      30              : ! zetp      : Reciprocal of the sum of the exponents of orbital a and b.
      31              : 
      32              :    USE ai_derivatives,                  ONLY: adbdr,&
      33              :                                               dabdr
      34              :    USE kinds,                           ONLY: dp
      35              :    USE mathconstants,                   ONLY: pi
      36              :    USE orbital_pointers,                ONLY: coset,&
      37              :                                               indco,&
      38              :                                               ncoset
      39              : #include "../base/base_uses.f90"
      40              : 
      41              :    IMPLICIT NONE
      42              : 
      43              :    PRIVATE
      44              : 
      45              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ai_moments'
      46              : 
      47              :    PUBLIC :: cossin, moment, diff_momop, contract_cossin, dipole_force
      48              : 
      49              : CONTAINS
      50              : 
      51              : ! **************************************************************************************************
      52              : !> \brief ...
      53              : !> \param cos_block ...
      54              : !> \param sin_block ...
      55              : !> \param iatom ...
      56              : !> \param ncoa ...
      57              : !> \param nsgfa ...
      58              : !> \param sgfa ...
      59              : !> \param sphi_a ...
      60              : !> \param ldsa ...
      61              : !> \param jatom ...
      62              : !> \param ncob ...
      63              : !> \param nsgfb ...
      64              : !> \param sgfb ...
      65              : !> \param sphi_b ...
      66              : !> \param ldsb ...
      67              : !> \param cosab ...
      68              : !> \param sinab ...
      69              : !> \param ldab ...
      70              : !> \param work ...
      71              : !> \param ldwork ...
      72              : !> \param ordered retain the ordered atom pair instead of mapping to an upper block
      73              : ! **************************************************************************************************
      74      1514470 :    SUBROUTINE contract_cossin(cos_block, sin_block, &
      75      3028940 :                               iatom, ncoa, nsgfa, sgfa, sphi_a, ldsa, &
      76      3028940 :                               jatom, ncob, nsgfb, sgfb, sphi_b, ldsb, &
      77      1514470 :                               cosab, sinab, ldab, work, ldwork, ordered)
      78              : 
      79              :       REAL(dp), DIMENSION(:, :), POINTER                 :: cos_block, sin_block
      80              :       INTEGER, INTENT(IN)                                :: iatom, ncoa, nsgfa, sgfa
      81              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: sphi_a
      82              :       INTEGER, INTENT(IN)                                :: ldsa, jatom, ncob, nsgfb, sgfb
      83              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: sphi_b
      84              :       INTEGER, INTENT(IN)                                :: ldsb
      85              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: cosab, sinab
      86              :       INTEGER, INTENT(IN)                                :: ldab
      87              :       REAL(dp), DIMENSION(:, :)                          :: work
      88              :       INTEGER, INTENT(IN)                                :: ldwork
      89              :       LOGICAL, INTENT(IN), OPTIONAL                      :: ordered
      90              : 
      91              :       LOGICAL                                            :: direct_block
      92              : 
      93      1514470 :       direct_block = iatom <= jatom
      94      1514470 :       IF (PRESENT(ordered)) direct_block = direct_block .OR. ordered
      95              : 
      96              : ! Calculate cosine
      97              : 
      98              :       CALL dgemm("N", "N", ncoa, nsgfb, ncob, &
      99              :                  1.0_dp, cosab(1, 1), ldab, &
     100              :                  sphi_b(1, sgfb), ldsb, &
     101      1514470 :                  0.0_dp, work(1, 1), ldwork)
     102              : 
     103      1514470 :       IF (direct_block) THEN
     104              :          CALL dgemm("T", "N", nsgfa, nsgfb, ncoa, &
     105              :                     1.0_dp, sphi_a(1, sgfa), ldsa, &
     106              :                     work(1, 1), ldwork, &
     107              :                     1.0_dp, cos_block(sgfa, sgfb), &
     108       939576 :                     SIZE(cos_block, 1))
     109              :       ELSE
     110              :          CALL dgemm("T", "N", nsgfb, nsgfa, ncoa, &
     111              :                     1.0_dp, work(1, 1), ldwork, &
     112              :                     sphi_a(1, sgfa), ldsa, &
     113              :                     1.0_dp, cos_block(sgfb, sgfa), &
     114       574894 :                     SIZE(cos_block, 1))
     115              :       END IF
     116              : 
     117              :       ! Calculate sine
     118              :       CALL dgemm("N", "N", ncoa, nsgfb, ncob, &
     119              :                  1.0_dp, sinab(1, 1), ldab, &
     120              :                  sphi_b(1, sgfb), ldsb, &
     121      1514470 :                  0.0_dp, work(1, 1), ldwork)
     122              : 
     123      1514470 :       IF (direct_block) THEN
     124              :          CALL dgemm("T", "N", nsgfa, nsgfb, ncoa, &
     125              :                     1.0_dp, sphi_a(1, sgfa), ldsa, &
     126              :                     work(1, 1), ldwork, &
     127              :                     1.0_dp, sin_block(sgfa, sgfb), &
     128       939576 :                     SIZE(sin_block, 1))
     129              :       ELSE
     130              :          CALL dgemm("T", "N", nsgfb, nsgfa, ncoa, &
     131              :                     1.0_dp, work(1, 1), ldwork, &
     132              :                     sphi_a(1, sgfa), ldsa, &
     133              :                     1.0_dp, sin_block(sgfb, sgfa), &
     134       574894 :                     SIZE(sin_block, 1))
     135              :       END IF
     136              : 
     137      1514470 :    END SUBROUTINE contract_cossin
     138              : 
     139              : ! **************************************************************************************************
     140              : !> \brief ...
     141              : !> \param la_max_set ...
     142              : !> \param npgfa ...
     143              : !> \param zeta ...
     144              : !> \param rpgfa ...
     145              : !> \param la_min_set ...
     146              : !> \param lb_max ...
     147              : !> \param npgfb ...
     148              : !> \param zetb ...
     149              : !> \param rpgfb ...
     150              : !> \param lb_min ...
     151              : !> \param rac ...
     152              : !> \param rbc ...
     153              : !> \param kvec ...
     154              : !> \param cosab ...
     155              : !> \param sinab ...
     156              : !> \param dcosab ...
     157              : !> \param dsinab ...
     158              : ! **************************************************************************************************
     159      1541596 :    SUBROUTINE cossin(la_max_set, npgfa, zeta, rpgfa, la_min_set, &
     160      1541596 :                      lb_max, npgfb, zetb, rpgfb, lb_min, &
     161      1541596 :                      rac, rbc, kvec, cosab, sinab, dcosab, dsinab)
     162              : 
     163              :       INTEGER, INTENT(IN)                                :: la_max_set, npgfa
     164              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zeta, rpgfa
     165              :       INTEGER, INTENT(IN)                                :: la_min_set, lb_max, npgfb
     166              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zetb, rpgfb
     167              :       INTEGER, INTENT(IN)                                :: lb_min
     168              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: rac, rbc, kvec
     169              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: cosab, sinab
     170              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT), &
     171              :          OPTIONAL                                        :: dcosab, dsinab
     172              : 
     173              :       INTEGER :: ax, ay, az, bx, by, bz, cda, cdax, cday, cdaz, coa, coamx, coamy, coamz, coapx, &
     174              :          coapy, coapz, cob, da, da_max, dax, day, daz, i, ipgf, j, jpgf, k, la, la_max, la_min, &
     175              :          la_start, lb, lb_start, na, nb
     176              :       REAL(KIND=dp)                                      :: dab, f0, f1, f2, f3, fax, fay, faz, ftz, &
     177              :                                                             fx, fy, fz, k2, kdp, rab2, s, zetp
     178              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rap, rbp
     179              :       REAL(KIND=dp), DIMENSION(ncoset(la_max_set), &
     180      3083192 :          ncoset(lb_max), 3)                              :: dscos, dssin
     181              :       REAL(KIND=dp), &
     182      1541596 :          DIMENSION(ncoset(la_max_set+1), ncoset(lb_max)) :: sc, ss
     183              : 
     184      6166384 :       rab = rbc - rac
     185      6166384 :       rab2 = SUM(rab**2)
     186      1541596 :       dab = SQRT(rab2)
     187      1541596 :       k2 = kvec(1)*kvec(1) + kvec(2)*kvec(2) + kvec(3)*kvec(3)
     188              : 
     189      1541596 :       IF (PRESENT(dcosab)) THEN
     190        24916 :          da_max = 1
     191        24916 :          la_max = la_max_set + 1
     192        24916 :          la_min = MAX(0, la_min_set - 1)
     193      1041304 :          dscos = 0.0_dp
     194      1041304 :          dssin = 0.0_dp
     195              :       ELSE
     196      1516680 :          da_max = 0
     197      1516680 :          la_max = la_max_set
     198      1516680 :          la_min = la_min_set
     199              :       END IF
     200              : 
     201              :       ! initialize all matrix elements to zero
     202      1541596 :       IF (PRESENT(dcosab)) THEN
     203        24916 :          na = ncoset(la_max - 1)*npgfa
     204              :       ELSE
     205      1516680 :          na = ncoset(la_max)*npgfa
     206              :       END IF
     207      1541596 :       nb = ncoset(lb_max)*npgfb
     208    225011239 :       cosab(1:na, 1:nb) = 0.0_dp
     209    225011239 :       sinab(1:na, 1:nb) = 0.0_dp
     210      1541596 :       IF (PRESENT(dcosab)) THEN
     211      5627902 :          dcosab(1:na, 1:nb, :) = 0.0_dp
     212      5627902 :          dsinab(1:na, 1:nb, :) = 0.0_dp
     213              :       END IF
     214              : !   *** Loop over all pairs of primitive Gaussian-type functions ***
     215              : 
     216      1541596 :       na = 0
     217      5144838 :       DO ipgf = 1, npgfa
     218              : 
     219              :          nb = 0
     220              : 
     221     15128222 :          DO jpgf = 1, npgfb
     222              : 
     223    548012893 :             ss = 0.0_dp
     224    548012893 :             sc = 0.0_dp
     225              : 
     226              : !       *** Screening ***
     227     11524980 :             IF (rpgfa(ipgf) + rpgfb(jpgf) < dab) THEN
     228      7318286 :                nb = nb + ncoset(lb_max)
     229      7318286 :                CYCLE
     230              :             END IF
     231              : 
     232              : !       *** Calculate some prefactors ***
     233              : 
     234      4206694 :             zetp = 1.0_dp/(zeta(ipgf) + zetb(jpgf))
     235              : 
     236      4206694 :             f0 = (pi*zetp)**1.5_dp
     237      4206694 :             f1 = zetb(jpgf)*zetp
     238      4206694 :             f2 = 0.5_dp*zetp
     239              : 
     240     16826776 :             kdp = zetp*DOT_PRODUCT(kvec, zeta(ipgf)*rac + zetb(jpgf)*rbc)
     241              : 
     242              : !       *** Calculate the basic two-center cos/sin integral [s|cos/sin|s] ***
     243              : 
     244      4206694 :             s = f0*EXP(-zeta(ipgf)*f1*rab2)*EXP(-0.25_dp*k2*zetp)
     245      4206694 :             sc(1, 1) = s*COS(kdp)
     246      4206694 :             ss(1, 1) = s*SIN(kdp)
     247              : 
     248              : !       *** Recurrence steps: [s|O|s] -> [a|O|b] ***
     249              : 
     250      4206694 :             IF (la_max > 0) THEN
     251              : 
     252              : !         *** Vertical recurrence steps: [s|O|s] -> [a|O|s] ***
     253              : 
     254     10695380 :                rap(:) = f1*rab(:)
     255              : 
     256              : !         *** [p|O|s] = (Pi - Ai)*[s|O|s] +[s|dO|s]  (i = x,y,z) ***
     257              : 
     258      2673845 :                sc(2, 1) = rap(1)*sc(1, 1) - f2*kvec(1)*ss(1, 1)
     259      2673845 :                sc(3, 1) = rap(2)*sc(1, 1) - f2*kvec(2)*ss(1, 1)
     260      2673845 :                sc(4, 1) = rap(3)*sc(1, 1) - f2*kvec(3)*ss(1, 1)
     261      2673845 :                ss(2, 1) = rap(1)*ss(1, 1) + f2*kvec(1)*sc(1, 1)
     262      2673845 :                ss(3, 1) = rap(2)*ss(1, 1) + f2*kvec(2)*sc(1, 1)
     263      2673845 :                ss(4, 1) = rap(3)*ss(1, 1) + f2*kvec(3)*sc(1, 1)
     264              : 
     265              : !         *** [a|O|s] = (Pi - Ai)*[a-1i|O|s] + f2*Ni(a-1i)*[a-2i|s] ***
     266              : !         ***           + [a-1i|dO|s]                               ***
     267              : 
     268      3200203 :                DO la = 2, la_max
     269              : 
     270              : !           *** Increase the angular momentum component z of function a ***
     271              : 
     272              :                   sc(coset(0, 0, la), 1) = rap(3)*sc(coset(0, 0, la - 1), 1) + &
     273              :                                            f2*REAL(la - 1, dp)*sc(coset(0, 0, la - 2), 1) - &
     274       526358 :                                            f2*kvec(3)*ss(coset(0, 0, la - 1), 1)
     275              :                   ss(coset(0, 0, la), 1) = rap(3)*ss(coset(0, 0, la - 1), 1) + &
     276              :                                            f2*REAL(la - 1, dp)*ss(coset(0, 0, la - 2), 1) + &
     277       526358 :                                            f2*kvec(3)*sc(coset(0, 0, la - 1), 1)
     278              : 
     279              : !           *** Increase the angular momentum component y of function a ***
     280              : 
     281       526358 :                   az = la - 1
     282              :                   sc(coset(0, 1, az), 1) = rap(2)*sc(coset(0, 0, az), 1) - &
     283       526358 :                                            f2*kvec(2)*ss(coset(0, 0, az), 1)
     284              :                   ss(coset(0, 1, az), 1) = rap(2)*ss(coset(0, 0, az), 1) + &
     285       526358 :                                            f2*kvec(2)*sc(coset(0, 0, az), 1)
     286              : 
     287      1065436 :                   DO ay = 2, la
     288       539078 :                      az = la - ay
     289              :                      sc(coset(0, ay, az), 1) = rap(2)*sc(coset(0, ay - 1, az), 1) + &
     290              :                                                f2*REAL(ay - 1, dp)*sc(coset(0, ay - 2, az), 1) - &
     291       539078 :                                                f2*kvec(2)*ss(coset(0, ay - 1, az), 1)
     292              :                      ss(coset(0, ay, az), 1) = rap(2)*ss(coset(0, ay - 1, az), 1) + &
     293              :                                                f2*REAL(ay - 1, dp)*ss(coset(0, ay - 2, az), 1) + &
     294      1065436 :                                                f2*kvec(2)*sc(coset(0, ay - 1, az), 1)
     295              :                   END DO
     296              : 
     297              : !           *** Increase the angular momentum component x of function a ***
     298              : 
     299      1591794 :                   DO ay = 0, la - 1
     300      1065436 :                      az = la - 1 - ay
     301              :                      sc(coset(1, ay, az), 1) = rap(1)*sc(coset(0, ay, az), 1) - &
     302      1065436 :                                                f2*kvec(1)*ss(coset(0, ay, az), 1)
     303              :                      ss(coset(1, ay, az), 1) = rap(1)*ss(coset(0, ay, az), 1) + &
     304      1591794 :                                                f2*kvec(1)*sc(coset(0, ay, az), 1)
     305              :                   END DO
     306              : 
     307      3739281 :                   DO ax = 2, la
     308       539078 :                      f3 = f2*REAL(ax - 1, dp)
     309      1617495 :                      DO ay = 0, la - ax
     310       552059 :                         az = la - ax - ay
     311              :                         sc(coset(ax, ay, az), 1) = rap(1)*sc(coset(ax - 1, ay, az), 1) + &
     312              :                                                    f3*sc(coset(ax - 2, ay, az), 1) - &
     313       552059 :                                                    f2*kvec(1)*ss(coset(ax - 1, ay, az), 1)
     314              :                         ss(coset(ax, ay, az), 1) = rap(1)*ss(coset(ax - 1, ay, az), 1) + &
     315              :                                                    f3*ss(coset(ax - 2, ay, az), 1) + &
     316      1091137 :                                                    f2*kvec(1)*sc(coset(ax - 1, ay, az), 1)
     317              :                      END DO
     318              :                   END DO
     319              : 
     320              :                END DO
     321              : 
     322              : !         *** Recurrence steps: [a|O|s] -> [a|O|b] ***
     323              : 
     324      2673845 :                IF (lb_max > 0) THEN
     325              : 
     326     10494944 :                   DO j = 2, ncoset(lb_max)
     327     59350517 :                      DO i = 1, ncoset(la_max)
     328     48855573 :                         sc(i, j) = 0.0_dp
     329     57313284 :                         ss(i, j) = 0.0_dp
     330              :                      END DO
     331              :                   END DO
     332              : 
     333              : !           *** Horizontal recurrence steps ***
     334              : 
     335      8148932 :                   rbp(:) = rap(:) - rab(:)
     336              : 
     337              : !           *** [a|O|p] = [a+1i|O|s] - (Bi - Ai)*[a|O|s] ***
     338              : 
     339      2037233 :                   IF (lb_max == 1) THEN
     340              :                      la_start = la_min
     341              :                   ELSE
     342       382422 :                      la_start = MAX(0, la_min - 1)
     343              :                   END IF
     344              : 
     345      4047295 :                   DO la = la_start, la_max - 1
     346      6330507 :                      DO ax = 0, la
     347      6852804 :                         DO ay = 0, la - ax
     348      2559530 :                            az = la - ax - ay
     349              :                            sc(coset(ax, ay, az), 2) = sc(coset(ax + 1, ay, az), 1) - &
     350      2559530 :                                                       rab(1)*sc(coset(ax, ay, az), 1)
     351              :                            sc(coset(ax, ay, az), 3) = sc(coset(ax, ay + 1, az), 1) - &
     352      2559530 :                                                       rab(2)*sc(coset(ax, ay, az), 1)
     353              :                            sc(coset(ax, ay, az), 4) = sc(coset(ax, ay, az + 1), 1) - &
     354      2559530 :                                                       rab(3)*sc(coset(ax, ay, az), 1)
     355              :                            ss(coset(ax, ay, az), 2) = ss(coset(ax + 1, ay, az), 1) - &
     356      2559530 :                                                       rab(1)*ss(coset(ax, ay, az), 1)
     357              :                            ss(coset(ax, ay, az), 3) = ss(coset(ax, ay + 1, az), 1) - &
     358      2559530 :                                                       rab(2)*ss(coset(ax, ay, az), 1)
     359              :                            ss(coset(ax, ay, az), 4) = ss(coset(ax, ay, az + 1), 1) - &
     360      4842742 :                                                       rab(3)*ss(coset(ax, ay, az), 1)
     361              :                         END DO
     362              :                      END DO
     363              :                   END DO
     364              : 
     365              : !           *** Vertical recurrence step ***
     366              : 
     367              : !           *** [a|O|p] = (Pi - Bi)*[a|O|s] + f2*Ni(a)*[a-1i|O|s] ***
     368              : !           ***           + [a|dO|s]                              ***
     369              : 
     370      6512888 :                   DO ax = 0, la_max
     371      4475655 :                      fx = f2*REAL(ax, dp)
     372     13835192 :                      DO ay = 0, la_max - ax
     373      7322304 :                         fy = f2*REAL(ay, dp)
     374      7322304 :                         az = la_max - ax - ay
     375      7322304 :                         fz = f2*REAL(az, dp)
     376      7322304 :                         IF (ax == 0) THEN
     377              :                            sc(coset(ax, ay, az), 2) = rbp(1)*sc(coset(ax, ay, az), 1) - &
     378      4475655 :                                                       f2*kvec(1)*ss(coset(ax, ay, az), 1)
     379              :                            ss(coset(ax, ay, az), 2) = rbp(1)*ss(coset(ax, ay, az), 1) + &
     380      4475655 :                                                       f2*kvec(1)*sc(coset(ax, ay, az), 1)
     381              :                         ELSE
     382              :                            sc(coset(ax, ay, az), 2) = rbp(1)*sc(coset(ax, ay, az), 1) + &
     383              :                                                       fx*sc(coset(ax - 1, ay, az), 1) - &
     384      2846649 :                                                       f2*kvec(1)*ss(coset(ax, ay, az), 1)
     385              :                            ss(coset(ax, ay, az), 2) = rbp(1)*ss(coset(ax, ay, az), 1) + &
     386              :                                                       fx*ss(coset(ax - 1, ay, az), 1) + &
     387      2846649 :                                                       f2*kvec(1)*sc(coset(ax, ay, az), 1)
     388              :                         END IF
     389      7322304 :                         IF (ay == 0) THEN
     390              :                            sc(coset(ax, ay, az), 3) = rbp(2)*sc(coset(ax, ay, az), 1) - &
     391      4475655 :                                                       f2*kvec(2)*ss(coset(ax, ay, az), 1)
     392              :                            ss(coset(ax, ay, az), 3) = rbp(2)*ss(coset(ax, ay, az), 1) + &
     393      4475655 :                                                       f2*kvec(2)*sc(coset(ax, ay, az), 1)
     394              :                         ELSE
     395              :                            sc(coset(ax, ay, az), 3) = rbp(2)*sc(coset(ax, ay, az), 1) + &
     396              :                                                       fy*sc(coset(ax, ay - 1, az), 1) - &
     397      2846649 :                                                       f2*kvec(2)*ss(coset(ax, ay, az), 1)
     398              :                            ss(coset(ax, ay, az), 3) = rbp(2)*ss(coset(ax, ay, az), 1) + &
     399              :                                                       fy*ss(coset(ax, ay - 1, az), 1) + &
     400      2846649 :                                                       f2*kvec(2)*sc(coset(ax, ay, az), 1)
     401              :                         END IF
     402     11797959 :                         IF (az == 0) THEN
     403              :                            sc(coset(ax, ay, az), 4) = rbp(3)*sc(coset(ax, ay, az), 1) - &
     404      4475655 :                                                       f2*kvec(3)*ss(coset(ax, ay, az), 1)
     405              :                            ss(coset(ax, ay, az), 4) = rbp(3)*ss(coset(ax, ay, az), 1) + &
     406      4475655 :                                                       f2*kvec(3)*sc(coset(ax, ay, az), 1)
     407              :                         ELSE
     408              :                            sc(coset(ax, ay, az), 4) = rbp(3)*sc(coset(ax, ay, az), 1) + &
     409              :                                                       fz*sc(coset(ax, ay, az - 1), 1) - &
     410      2846649 :                                                       f2*kvec(3)*ss(coset(ax, ay, az), 1)
     411              :                            ss(coset(ax, ay, az), 4) = rbp(3)*ss(coset(ax, ay, az), 1) + &
     412              :                                                       fz*ss(coset(ax, ay, az - 1), 1) + &
     413      2846649 :                                                       f2*kvec(3)*sc(coset(ax, ay, az), 1)
     414              :                         END IF
     415              :                      END DO
     416              :                   END DO
     417              : 
     418              : !           *** Recurrence steps: [a|O|p] -> [a|O|b] ***
     419              : 
     420      2424740 :                   DO lb = 2, lb_max
     421              : 
     422              : !             *** Horizontal recurrence steps ***
     423              : 
     424              : !             *** [a|O|b] = [a+1i|O|b-1i] - (Bi - Ai)*[a|O|b-1i] ***
     425              : 
     426       387507 :                      IF (lb == lb_max) THEN
     427              :                         la_start = la_min
     428              :                      ELSE
     429         5085 :                         la_start = MAX(0, la_min - 1)
     430              :                      END IF
     431              : 
     432       840157 :                      DO la = la_start, la_max - 1
     433      1452879 :                         DO ax = 0, la
     434      1838766 :                            DO ay = 0, la - ax
     435       773394 :                               az = la - ax - ay
     436              : 
     437              : !                   *** Shift of angular momentum component z from a to b ***
     438              : 
     439              :                               sc(coset(ax, ay, az), coset(0, 0, lb)) = &
     440              :                                  sc(coset(ax, ay, az + 1), coset(0, 0, lb - 1)) - &
     441       773394 :                                  rab(3)*sc(coset(ax, ay, az), coset(0, 0, lb - 1))
     442              :                               ss(coset(ax, ay, az), coset(0, 0, lb)) = &
     443              :                                  ss(coset(ax, ay, az + 1), coset(0, 0, lb - 1)) - &
     444       773394 :                                  rab(3)*ss(coset(ax, ay, az), coset(0, 0, lb - 1))
     445              : 
     446              : !                   *** Shift of angular momentum component y from a to b ***
     447              : 
     448      2322861 :                               DO by = 1, lb
     449      1549467 :                                  bz = lb - by
     450              :                                  sc(coset(ax, ay, az), coset(0, by, bz)) = &
     451              :                                     sc(coset(ax, ay + 1, az), coset(0, by - 1, bz)) - &
     452      1549467 :                                     rab(2)*sc(coset(ax, ay, az), coset(0, by - 1, bz))
     453              :                                  ss(coset(ax, ay, az), coset(0, by, bz)) = &
     454              :                                     ss(coset(ax, ay + 1, az), coset(0, by - 1, bz)) - &
     455      2322861 :                                     rab(2)*ss(coset(ax, ay, az), coset(0, by - 1, bz))
     456              :                               END DO
     457              : 
     458              : !                   *** Shift of angular momentum component x from a to b ***
     459              : 
     460      2935583 :                               DO bx = 1, lb
     461      4651080 :                                  DO by = 0, lb - bx
     462      2328219 :                                     bz = lb - bx - by
     463              :                                     sc(coset(ax, ay, az), coset(bx, by, bz)) = &
     464              :                                        sc(coset(ax + 1, ay, az), coset(bx - 1, by, bz)) - &
     465      2328219 :                                        rab(1)*sc(coset(ax, ay, az), coset(bx - 1, by, bz))
     466              :                                     ss(coset(ax, ay, az), coset(bx, by, bz)) = &
     467              :                                        ss(coset(ax + 1, ay, az), coset(bx - 1, by, bz)) - &
     468      3877686 :                                        rab(1)*ss(coset(ax, ay, az), coset(bx - 1, by, bz))
     469              :                                  END DO
     470              :                               END DO
     471              : 
     472              :                            END DO
     473              :                         END DO
     474              :                      END DO
     475              : 
     476              : !             *** Vertical recurrence step ***
     477              : 
     478              : !             *** [a|O|b] = (Pi - Bi)*[a|O|b-1i] + f2*Ni(a)*[a-1i|O|b-1i] + ***
     479              : !             ***           f2*Ni(b-1i)*[a|O|b-2i] + [a|dO|b-1i]            ***
     480              : 
     481      3411383 :                      DO ax = 0, la_max
     482       986643 :                         fx = f2*REAL(ax, dp)
     483      3173520 :                         DO ay = 0, la_max - ax
     484      1799370 :                            fy = f2*REAL(ay, dp)
     485      1799370 :                            az = la_max - ax - ay
     486      1799370 :                            fz = f2*REAL(az, dp)
     487              : 
     488              : !                 *** Increase the angular momentum component z of function b ***
     489              : 
     490      1799370 :                            f3 = f2*REAL(lb - 1, dp)
     491              : 
     492      1799370 :                            IF (az == 0) THEN
     493              :                               sc(coset(ax, ay, az), coset(0, 0, lb)) = &
     494              :                                  rbp(3)*sc(coset(ax, ay, az), coset(0, 0, lb - 1)) + &
     495              :                                  f3*sc(coset(ax, ay, az), coset(0, 0, lb - 2)) - &
     496       986643 :                                  f2*kvec(3)*ss(coset(ax, ay, az), coset(0, 0, lb - 1))
     497              :                               ss(coset(ax, ay, az), coset(0, 0, lb)) = &
     498              :                                  rbp(3)*ss(coset(ax, ay, az), coset(0, 0, lb - 1)) + &
     499              :                                  f3*ss(coset(ax, ay, az), coset(0, 0, lb - 2)) + &
     500       986643 :                                  f2*kvec(3)*sc(coset(ax, ay, az), coset(0, 0, lb - 1))
     501              :                            ELSE
     502              :                               sc(coset(ax, ay, az), coset(0, 0, lb)) = &
     503              :                                  rbp(3)*sc(coset(ax, ay, az), coset(0, 0, lb - 1)) + &
     504              :                                  fz*sc(coset(ax, ay, az - 1), coset(0, 0, lb - 1)) + &
     505              :                                  f3*sc(coset(ax, ay, az), coset(0, 0, lb - 2)) - &
     506       812727 :                                  f2*kvec(3)*ss(coset(ax, ay, az), coset(0, 0, lb - 1))
     507              :                               ss(coset(ax, ay, az), coset(0, 0, lb)) = &
     508              :                                  rbp(3)*ss(coset(ax, ay, az), coset(0, 0, lb - 1)) + &
     509              :                                  fz*ss(coset(ax, ay, az - 1), coset(0, 0, lb - 1)) + &
     510              :                                  f3*ss(coset(ax, ay, az), coset(0, 0, lb - 2)) + &
     511       812727 :                                  f2*kvec(3)*sc(coset(ax, ay, az), coset(0, 0, lb - 1))
     512              :                            END IF
     513              : 
     514              : !                 *** Increase the angular momentum component y of function b ***
     515              : 
     516      1799370 :                            IF (ay == 0) THEN
     517       986643 :                               bz = lb - 1
     518              :                               sc(coset(ax, ay, az), coset(0, 1, bz)) = &
     519              :                                  rbp(2)*sc(coset(ax, ay, az), coset(0, 0, bz)) - &
     520       986643 :                                  f2*kvec(2)*ss(coset(ax, ay, az), coset(0, 0, bz))
     521              :                               ss(coset(ax, ay, az), coset(0, 1, bz)) = &
     522              :                                  rbp(2)*ss(coset(ax, ay, az), coset(0, 0, bz)) + &
     523       986643 :                                  f2*kvec(2)*sc(coset(ax, ay, az), coset(0, 0, bz))
     524      1985520 :                               DO by = 2, lb
     525       998877 :                                  bz = lb - by
     526       998877 :                                  f3 = f2*REAL(by - 1, dp)
     527              :                                  sc(coset(ax, ay, az), coset(0, by, bz)) = &
     528              :                                     rbp(2)*sc(coset(ax, ay, az), coset(0, by - 1, bz)) + &
     529              :                                     f3*sc(coset(ax, ay, az), coset(0, by - 2, bz)) - &
     530       998877 :                                     f2*kvec(2)*ss(coset(ax, ay, az), coset(0, by - 1, bz))
     531              :                                  ss(coset(ax, ay, az), coset(0, by, bz)) = &
     532              :                                     rbp(2)*ss(coset(ax, ay, az), coset(0, by - 1, bz)) + &
     533              :                                     f3*ss(coset(ax, ay, az), coset(0, by - 2, bz)) + &
     534      1985520 :                                     f2*kvec(2)*sc(coset(ax, ay, az), coset(0, by - 1, bz))
     535              :                               END DO
     536              :                            ELSE
     537       812727 :                               bz = lb - 1
     538              :                               sc(coset(ax, ay, az), coset(0, 1, bz)) = &
     539              :                                  rbp(2)*sc(coset(ax, ay, az), coset(0, 0, bz)) + &
     540              :                                  fy*sc(coset(ax, ay - 1, az), coset(0, 0, bz)) - &
     541       812727 :                                  f2*kvec(2)*ss(coset(ax, ay, az), coset(0, 0, bz))
     542              :                               ss(coset(ax, ay, az), coset(0, 1, bz)) = &
     543              :                                  rbp(2)*ss(coset(ax, ay, az), coset(0, 0, bz)) + &
     544              :                                  fy*ss(coset(ax, ay - 1, az), coset(0, 0, bz)) + &
     545       812727 :                                  f2*kvec(2)*sc(coset(ax, ay, az), coset(0, 0, bz))
     546      1634778 :                               DO by = 2, lb
     547       822051 :                                  bz = lb - by
     548       822051 :                                  f3 = f2*REAL(by - 1, dp)
     549              :                                  sc(coset(ax, ay, az), coset(0, by, bz)) = &
     550              :                                     rbp(2)*sc(coset(ax, ay, az), coset(0, by - 1, bz)) + &
     551              :                                     fy*sc(coset(ax, ay - 1, az), coset(0, by - 1, bz)) + &
     552              :                                     f3*sc(coset(ax, ay, az), coset(0, by - 2, bz)) - &
     553       822051 :                                     f2*kvec(2)*ss(coset(ax, ay, az), coset(0, by - 1, bz))
     554              :                                  ss(coset(ax, ay, az), coset(0, by, bz)) = &
     555              :                                     rbp(2)*ss(coset(ax, ay, az), coset(0, by - 1, bz)) + &
     556              :                                     fy*ss(coset(ax, ay - 1, az), coset(0, by - 1, bz)) + &
     557              :                                     f3*ss(coset(ax, ay, az), coset(0, by - 2, bz)) + &
     558      1634778 :                                     f2*kvec(2)*sc(coset(ax, ay, az), coset(0, by - 1, bz))
     559              :                               END DO
     560              :                            END IF
     561              : 
     562              : !                 *** Increase the angular momentum component x of function b ***
     563              : 
     564      2786013 :                            IF (ax == 0) THEN
     565      2972163 :                               DO by = 0, lb - 1
     566      1985520 :                                  bz = lb - 1 - by
     567              :                                  sc(coset(ax, ay, az), coset(1, by, bz)) = &
     568              :                                     rbp(1)*sc(coset(ax, ay, az), coset(0, by, bz)) - &
     569      1985520 :                                     f2*kvec(1)*ss(coset(ax, ay, az), coset(0, by, bz))
     570              :                                  ss(coset(ax, ay, az), coset(1, by, bz)) = &
     571              :                                     rbp(1)*ss(coset(ax, ay, az), coset(0, by, bz)) + &
     572      2972163 :                                     f2*kvec(1)*sc(coset(ax, ay, az), coset(0, by, bz))
     573              :                               END DO
     574      1985520 :                               DO bx = 2, lb
     575       998877 :                                  f3 = f2*REAL(bx - 1, dp)
     576      2996973 :                                  DO by = 0, lb - bx
     577      1011453 :                                     bz = lb - bx - by
     578              :                                     sc(coset(ax, ay, az), coset(bx, by, bz)) = &
     579              :                                        rbp(1)*sc(coset(ax, ay, az), &
     580              :                                                  coset(bx - 1, by, bz)) + &
     581              :                                        f3*sc(coset(ax, ay, az), coset(bx - 2, by, bz)) - &
     582      1011453 :                                        f2*kvec(1)*ss(coset(ax, ay, az), coset(bx - 1, by, bz))
     583              :                                     ss(coset(ax, ay, az), coset(bx, by, bz)) = &
     584              :                                        rbp(1)*ss(coset(ax, ay, az), &
     585              :                                                  coset(bx - 1, by, bz)) + &
     586              :                                        f3*ss(coset(ax, ay, az), coset(bx - 2, by, bz)) + &
     587      2010330 :                                        f2*kvec(1)*sc(coset(ax, ay, az), coset(bx - 1, by, bz))
     588              :                                  END DO
     589              :                               END DO
     590              :                            ELSE
     591      2447505 :                               DO by = 0, lb - 1
     592      1634778 :                                  bz = lb - 1 - by
     593              :                                  sc(coset(ax, ay, az), coset(1, by, bz)) = &
     594              :                                     rbp(1)*sc(coset(ax, ay, az), coset(0, by, bz)) + &
     595              :                                     fx*sc(coset(ax - 1, ay, az), coset(0, by, bz)) - &
     596      1634778 :                                     f2*kvec(1)*ss(coset(ax, ay, az), coset(0, by, bz))
     597              :                                  ss(coset(ax, ay, az), coset(1, by, bz)) = &
     598              :                                     rbp(1)*ss(coset(ax, ay, az), coset(0, by, bz)) + &
     599              :                                     fx*ss(coset(ax - 1, ay, az), coset(0, by, bz)) + &
     600      2447505 :                                     f2*kvec(1)*sc(coset(ax, ay, az), coset(0, by, bz))
     601              :                               END DO
     602      1634778 :                               DO bx = 2, lb
     603       822051 :                                  f3 = f2*REAL(bx - 1, dp)
     604      2466504 :                                  DO by = 0, lb - bx
     605       831726 :                                     bz = lb - bx - by
     606              :                                     sc(coset(ax, ay, az), coset(bx, by, bz)) = &
     607              :                                        rbp(1)*sc(coset(ax, ay, az), &
     608              :                                                  coset(bx - 1, by, bz)) + &
     609              :                                        fx*sc(coset(ax - 1, ay, az), coset(bx - 1, by, bz)) + &
     610              :                                        f3*sc(coset(ax, ay, az), coset(bx - 2, by, bz)) - &
     611       831726 :                                        f2*kvec(1)*ss(coset(ax, ay, az), coset(bx - 1, by, bz))
     612              :                                     ss(coset(ax, ay, az), coset(bx, by, bz)) = &
     613              :                                        rbp(1)*ss(coset(ax, ay, az), &
     614              :                                                  coset(bx - 1, by, bz)) + &
     615              :                                        fx*ss(coset(ax - 1, ay, az), coset(bx - 1, by, bz)) + &
     616              :                                        f3*ss(coset(ax, ay, az), coset(bx - 2, by, bz)) + &
     617      1653777 :                                        f2*kvec(1)*sc(coset(ax, ay, az), coset(bx - 1, by, bz))
     618              :                                  END DO
     619              :                               END DO
     620              :                            END IF
     621              : 
     622              :                         END DO
     623              :                      END DO
     624              : 
     625              :                   END DO
     626              : 
     627              :                END IF
     628              : 
     629              :             ELSE
     630              : 
     631      1532849 :                IF (lb_max > 0) THEN
     632              : 
     633              : !           *** Vertical recurrence steps: [s|O|s] -> [s|O|b] ***
     634              : 
     635      2326360 :                   rbp(:) = (f1 - 1.0_dp)*rab(:)
     636              : 
     637              : !           *** [s|O|p] = (Pi - Bi)*[s|O|s] + [s|dO|s] ***
     638              : 
     639       581590 :                   sc(1, 2) = rbp(1)*sc(1, 1) - f2*kvec(1)*ss(1, 1)
     640       581590 :                   sc(1, 3) = rbp(2)*sc(1, 1) - f2*kvec(2)*ss(1, 1)
     641       581590 :                   sc(1, 4) = rbp(3)*sc(1, 1) - f2*kvec(3)*ss(1, 1)
     642       581590 :                   ss(1, 2) = rbp(1)*ss(1, 1) + f2*kvec(1)*sc(1, 1)
     643       581590 :                   ss(1, 3) = rbp(2)*ss(1, 1) + f2*kvec(2)*sc(1, 1)
     644       581590 :                   ss(1, 4) = rbp(3)*ss(1, 1) + f2*kvec(3)*sc(1, 1)
     645              : 
     646              : !           *** [s|O|b] = (Pi - Bi)*[s|O|b-1i] + f2*Ni(b-1i)*[s|O|b-2i] ***
     647              : !           ***           + [s|dO|b-1i]                                 ***
     648              : 
     649       686669 :                   DO lb = 2, lb_max
     650              : 
     651              : !             *** Increase the angular momentum component z of function b ***
     652              : 
     653              :                      sc(1, coset(0, 0, lb)) = rbp(3)*sc(1, coset(0, 0, lb - 1)) + &
     654              :                                               f2*REAL(lb - 1, dp)*sc(1, coset(0, 0, lb - 2)) - &
     655       105079 :                                               f2*kvec(3)*ss(1, coset(0, 0, lb - 1))
     656              :                      ss(1, coset(0, 0, lb)) = rbp(3)*ss(1, coset(0, 0, lb - 1)) + &
     657              :                                               f2*REAL(lb - 1, dp)*ss(1, coset(0, 0, lb - 2)) + &
     658       105079 :                                               f2*kvec(3)*sc(1, coset(0, 0, lb - 1))
     659              : 
     660              : !             *** Increase the angular momentum component y of function b ***
     661              : 
     662       105079 :                      bz = lb - 1
     663              :                      sc(1, coset(0, 1, bz)) = rbp(2)*sc(1, coset(0, 0, bz)) - &
     664       105079 :                                               f2*kvec(2)*ss(1, coset(0, 0, bz))
     665              :                      ss(1, coset(0, 1, bz)) = rbp(2)*ss(1, coset(0, 0, bz)) + &
     666       105079 :                                               f2*kvec(2)*sc(1, coset(0, 0, bz))
     667              : 
     668       214340 :                      DO by = 2, lb
     669       109261 :                         bz = lb - by
     670              :                         sc(1, coset(0, by, bz)) = rbp(2)*sc(1, coset(0, by - 1, bz)) + &
     671              :                                                   f2*REAL(by - 1, dp)*sc(1, coset(0, by - 2, bz)) - &
     672       109261 :                                                   f2*kvec(2)*ss(1, coset(0, by - 1, bz))
     673              :                         ss(1, coset(0, by, bz)) = rbp(2)*ss(1, coset(0, by - 1, bz)) + &
     674              :                                                   f2*REAL(by - 1, dp)*ss(1, coset(0, by - 2, bz)) + &
     675       214340 :                                                   f2*kvec(2)*sc(1, coset(0, by - 1, bz))
     676              :                      END DO
     677              : 
     678              : !             *** Increase the angular momentum component x of function b ***
     679              : 
     680       319419 :                      DO by = 0, lb - 1
     681       214340 :                         bz = lb - 1 - by
     682              :                         sc(1, coset(1, by, bz)) = rbp(1)*sc(1, coset(0, by, bz)) - &
     683       214340 :                                                   f2*kvec(1)*ss(1, coset(0, by, bz))
     684              :                         ss(1, coset(1, by, bz)) = rbp(1)*ss(1, coset(0, by, bz)) + &
     685       319419 :                                                   f2*kvec(1)*sc(1, coset(0, by, bz))
     686              :                      END DO
     687              : 
     688       795930 :                      DO bx = 2, lb
     689       109261 :                         f3 = f2*REAL(bx - 1, dp)
     690       327918 :                         DO by = 0, lb - bx
     691       113578 :                            bz = lb - bx - by
     692              :                            sc(1, coset(bx, by, bz)) = rbp(1)*sc(1, coset(bx - 1, by, bz)) + &
     693              :                                                       f3*sc(1, coset(bx - 2, by, bz)) - &
     694       113578 :                                                       f2*kvec(1)*ss(1, coset(bx - 1, by, bz))
     695              :                            ss(1, coset(bx, by, bz)) = rbp(1)*ss(1, coset(bx - 1, by, bz)) + &
     696              :                                                       f3*ss(1, coset(bx - 2, by, bz)) + &
     697       222839 :                                                       f2*kvec(1)*sc(1, coset(bx - 1, by, bz))
     698              :                         END DO
     699              :                      END DO
     700              : 
     701              :                   END DO
     702              : 
     703              :                END IF
     704              : 
     705              :             END IF
     706              : 
     707     17699751 :             DO j = ncoset(lb_min - 1) + 1, ncoset(lb_max)
     708     73156133 :                DO i = ncoset(la_min_set - 1) + 1, ncoset(la_max_set)
     709     55456382 :                   cosab(na + i, nb + j) = sc(i, j)
     710     68949439 :                   sinab(na + i, nb + j) = ss(i, j)
     711              :                END DO
     712              :             END DO
     713              : 
     714      4206694 :             IF (PRESENT(dcosab)) THEN
     715              :                la_start = 0
     716              :                lb_start = 0
     717              :             ELSE
     718      4145450 :                la_start = la_min
     719      4145450 :                lb_start = lb_min
     720              :             END IF
     721              : 
     722      4267938 :             DO da = 0, da_max - 1
     723        61244 :                ftz = 2.0_dp*zeta(ipgf)
     724      4329182 :                DO dax = 0, da
     725       183732 :                   DO day = 0, da - dax
     726        61244 :                      daz = da - dax - day
     727        61244 :                      cda = coset(dax, day, daz) - 1
     728        61244 :                      cdax = coset(dax + 1, day, daz) - 1
     729        61244 :                      cday = coset(dax, day + 1, daz) - 1
     730        61244 :                      cdaz = coset(dax, day, daz + 1) - 1
     731              :                      !*** [da/dAi|O|b] = 2*zeta*[a+1i|O|b] - Ni(a)[a-1i|O|b] ***
     732              : 
     733       213755 :                      DO la = la_start, la_max - da - 1
     734       276858 :                         DO ax = 0, la
     735       124347 :                            fax = REAL(ax, dp)
     736       376098 :                            DO ay = 0, la - ax
     737       160484 :                               fay = REAL(ay, dp)
     738       160484 :                               az = la - ax - ay
     739       160484 :                               faz = REAL(az, dp)
     740       160484 :                               coa = coset(ax, ay, az)
     741       160484 :                               coamx = coset(ax - 1, ay, az)
     742       160484 :                               coamy = coset(ax, ay - 1, az)
     743       160484 :                               coamz = coset(ax, ay, az - 1)
     744       160484 :                               coapx = coset(ax + 1, ay, az)
     745       160484 :                               coapy = coset(ax, ay + 1, az)
     746       160484 :                               coapz = coset(ax, ay, az + 1)
     747       533290 :                               DO lb = lb_start, lb_max
     748       754566 :                                  DO bx = 0, lb
     749      1046058 :                                     DO by = 0, lb - bx
     750       451976 :                                        bz = lb - bx - by
     751       451976 :                                        cob = coset(bx, by, bz)
     752       451976 :                                        dscos(coa, cob, cdax) = ftz*sc(coapx, cob) - fax*sc(coamx, cob)
     753       451976 :                                        dscos(coa, cob, cday) = ftz*sc(coapy, cob) - fay*sc(coamy, cob)
     754       451976 :                                        dscos(coa, cob, cdaz) = ftz*sc(coapz, cob) - faz*sc(coamz, cob)
     755       451976 :                                        dssin(coa, cob, cdax) = ftz*ss(coapx, cob) - fax*ss(coamx, cob)
     756       451976 :                                        dssin(coa, cob, cday) = ftz*ss(coapy, cob) - fay*ss(coamy, cob)
     757       797599 :                                        dssin(coa, cob, cdaz) = ftz*ss(coapz, cob) - faz*ss(coamz, cob)
     758              :                                     END DO
     759              :                                  END DO
     760              :                               END DO
     761              :                            END DO
     762              :                         END DO
     763              :                      END DO
     764              : 
     765              :                   END DO
     766              :                END DO
     767              :             END DO
     768              : 
     769      4206694 :             IF (PRESENT(dcosab)) THEN
     770       244976 :                DO k = 1, 3
     771       715556 :                   DO j = 1, ncoset(lb_max)
     772      2010240 :                      DO i = 1, ncoset(la_max_set)
     773      1355928 :                         dcosab(na + i, nb + j, k) = dscos(i, j, k)
     774      1826508 :                         dsinab(na + i, nb + j, k) = dssin(i, j, k)
     775              :                      END DO
     776              :                   END DO
     777              :                END DO
     778              :             END IF
     779              : 
     780      7809936 :             nb = nb + ncoset(lb_max)
     781              : 
     782              :          END DO
     783              : 
     784      5144838 :          na = na + ncoset(la_max_set)
     785              : 
     786              :       END DO
     787              : 
     788      1541596 :    END SUBROUTINE cossin
     789              : 
     790              : ! **************************************************************************************************
     791              : !> \brief ...
     792              : !> \param la_max ...
     793              : !> \param npgfa ...
     794              : !> \param zeta ...
     795              : !> \param rpgfa ...
     796              : !> \param la_min ...
     797              : !> \param lb_max ...
     798              : !> \param npgfb ...
     799              : !> \param zetb ...
     800              : !> \param rpgfb ...
     801              : !> \param lc_max ...
     802              : !> \param rac ...
     803              : !> \param rbc ...
     804              : !> \param mab ...
     805              : ! **************************************************************************************************
     806       648802 :    SUBROUTINE moment(la_max, npgfa, zeta, rpgfa, la_min, &
     807      1297604 :                      lb_max, npgfb, zetb, rpgfb, &
     808       648802 :                      lc_max, rac, rbc, mab)
     809              : 
     810              :       INTEGER, INTENT(IN)                                :: la_max, npgfa
     811              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zeta, rpgfa
     812              :       INTEGER, INTENT(IN)                                :: la_min, lb_max, npgfb
     813              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zetb, rpgfb
     814              :       INTEGER, INTENT(IN)                                :: lc_max
     815              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: rac, rbc
     816              :       REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT)   :: mab
     817              : 
     818              :       INTEGER                                            :: ax, ay, az, bx, by, bz, i, ipgf, j, &
     819              :                                                             jpgf, k, l, l1, l2, la, la_start, lb, &
     820              :                                                             lx, lx1, ly, ly1, lz, lz1, na, nb, ni
     821              :       REAL(KIND=dp)                                      :: dab, f0, f1, f2, f2x, f2y, f2z, f3, fx, &
     822              :                                                             fy, fz, rab2, zetp
     823              :       REAL(KIND=dp), DIMENSION(3)                        :: rab, rap, rbp, rpc
     824              :       REAL(KIND=dp), DIMENSION(ncoset(la_max), ncoset(&
     825       648802 :          lb_max), ncoset(lc_max))                        :: s
     826              : 
     827      2595208 :       rab = rbc - rac
     828      2595208 :       rab2 = SUM(rab**2)
     829       648802 :       dab = SQRT(rab2)
     830              : 
     831              : !   *** Loop over all pairs of primitive Gaussian-type functions ***
     832              : 
     833       648802 :       na = 0
     834              : 
     835      2118772 :       DO ipgf = 1, npgfa
     836              : 
     837      1469970 :          nb = 0
     838              : 
     839      5448011 :          DO jpgf = 1, npgfb
     840              : 
     841   2903726493 :             s = 0.0_dp
     842              : !       *** Screening ***
     843              : 
     844      3978041 :             IF (rpgfa(ipgf) + rpgfb(jpgf) < dab) THEN
     845     24081829 :                DO k = 1, ncoset(lc_max) - 1
     846    195504335 :                   DO j = nb + 1, nb + ncoset(lb_max)
     847   1713647178 :                      DO i = na + 1, na + ncoset(la_max)
     848   1692033881 :                         mab(i, j, k) = 0.0_dp
     849              :                      END DO
     850              :                   END DO
     851              :                END DO
     852      2468532 :                nb = nb + ncoset(lb_max)
     853      2468532 :                CYCLE
     854              :             END IF
     855              : 
     856              : !       *** Calculate some prefactors ***
     857              : 
     858      1509509 :             zetp = 1.0_dp/(zeta(ipgf) + zetb(jpgf))
     859              : 
     860      1509509 :             f0 = (pi*zetp)**1.5_dp
     861      1509509 :             f1 = zetb(jpgf)*zetp
     862      1509509 :             f2 = 0.5_dp*zetp
     863              : 
     864              : !       *** Calculate the basic two-center moment integral [s|M|s] ***
     865              : 
     866      6038036 :             rpc = zetp*(zeta(ipgf)*rac + zetb(jpgf)*rbc)
     867      1509509 :             s(1, 1, 1) = f0*EXP(-zeta(ipgf)*f1*rab2)
     868     12897505 :             DO l = 2, ncoset(lc_max)
     869     11387996 :                lx = indco(1, l)
     870     11387996 :                ly = indco(2, l)
     871     11387996 :                lz = indco(3, l)
     872     11387996 :                l2 = 0
     873     11387996 :                IF (lz > 0) THEN
     874      4939765 :                   l1 = coset(lx, ly, lz - 1)
     875      4939765 :                   IF (lz > 1) l2 = coset(lx, ly, lz - 2)
     876              :                   ni = lz - 1
     877              :                   i = 3
     878      6448231 :                ELSE IF (ly > 0) THEN
     879      3795800 :                   l1 = coset(lx, ly - 1, lz)
     880      3795800 :                   IF (ly > 1) l2 = coset(lx, ly - 2, lz)
     881              :                   ni = ly - 1
     882              :                   i = 2
     883      2652431 :                ELSE IF (lx > 0) THEN
     884      2652431 :                   l1 = coset(lx - 1, ly, lz)
     885      2652431 :                   IF (lx > 1) l2 = coset(lx - 2, ly, lz)
     886              :                   ni = lx - 1
     887              :                   i = 1
     888              :                END IF
     889     11387996 :                s(1, 1, l) = rpc(i)*s(1, 1, l1)
     890     12897505 :                IF (l2 > 0) s(1, 1, l) = s(1, 1, l) + f2*REAL(ni, dp)*s(1, 1, l2)
     891              :             END DO
     892              : 
     893              : !       *** Recurrence steps: [s|M|s] -> [a|M|b] ***
     894              : 
     895     14407014 :             DO l = 1, ncoset(lc_max)
     896              : 
     897     12897505 :                lx = indco(1, l)
     898     12897505 :                ly = indco(2, l)
     899     12897505 :                lz = indco(3, l)
     900     12897505 :                IF (lx > 0) THEN
     901      4939765 :                   lx1 = coset(lx - 1, ly, lz)
     902              :                ELSE
     903              :                   lx1 = -1
     904              :                END IF
     905     12897505 :                IF (ly > 0) THEN
     906      4939765 :                   ly1 = coset(lx, ly - 1, lz)
     907              :                ELSE
     908              :                   ly1 = -1
     909              :                END IF
     910     12897505 :                IF (lz > 0) THEN
     911      4939765 :                   lz1 = coset(lx, ly, lz - 1)
     912              :                ELSE
     913              :                   lz1 = -1
     914              :                END IF
     915     12897505 :                f2x = f2*REAL(lx, dp)
     916     12897505 :                f2y = f2*REAL(ly, dp)
     917     12897505 :                f2z = f2*REAL(lz, dp)
     918              : 
     919     14407014 :                IF (la_max > 0) THEN
     920              : 
     921              : !           *** Vertical recurrence steps: [s|M|s] -> [a|M|s] ***
     922              : 
     923     49122160 :                   rap(:) = f1*rab(:)
     924              : 
     925              : !           *** [p|M|s] = (Pi - Ai)*[s|M|s] + f2*Ni(m-1i)[s|M-1i|s] ***
     926              : 
     927     12280540 :                   s(2, 1, l) = rap(1)*s(1, 1, l)
     928     12280540 :                   s(3, 1, l) = rap(2)*s(1, 1, l)
     929     12280540 :                   s(4, 1, l) = rap(3)*s(1, 1, l)
     930     12280540 :                   IF (lx1 > 0) s(2, 1, l) = s(2, 1, l) + f2x*s(1, 1, lx1)
     931     12280540 :                   IF (ly1 > 0) s(3, 1, l) = s(3, 1, l) + f2y*s(1, 1, ly1)
     932     12280540 :                   IF (lz1 > 0) s(4, 1, l) = s(4, 1, l) + f2z*s(1, 1, lz1)
     933              : 
     934              : !           *** [a|M|s] = (Pi - Ai)*[a-1i|M|s] + f2*Ni(a-1i)*[a-2i|M|s] ***
     935              : !           ***           + f2*Ni(m-1i)*[a-1i|M-1i|s]                   ***
     936              : 
     937     19967452 :                   DO la = 2, la_max
     938              : 
     939              : !             *** Increase the angular momentum component z of function a ***
     940              : 
     941              :                      s(coset(0, 0, la), 1, l) = rap(3)*s(coset(0, 0, la - 1), 1, l) + &
     942      7686912 :                                                 f2*REAL(la - 1, dp)*s(coset(0, 0, la - 2), 1, l)
     943      7686912 :                      IF (lz1 > 0) s(coset(0, 0, la), 1, l) = s(coset(0, 0, la), 1, l) + &
     944      3044463 :                                                              f2z*s(coset(0, 0, la - 1), 1, lz1)
     945              : 
     946              : !             *** Increase the angular momentum component y of function a ***
     947              : 
     948      7686912 :                      az = la - 1
     949      7686912 :                      s(coset(0, 1, az), 1, l) = rap(2)*s(coset(0, 0, az), 1, l)
     950      7686912 :                      IF (ly1 > 0) s(coset(0, 1, az), 1, l) = s(coset(0, 1, az), 1, l) + &
     951      3044463 :                                                              f2y*s(coset(0, 0, az), 1, ly1)
     952              : 
     953     16205838 :                      DO ay = 2, la
     954      8518926 :                         az = la - ay
     955              :                         s(coset(0, ay, az), 1, l) = rap(2)*s(coset(0, ay - 1, az), 1, l) + &
     956      8518926 :                                                     f2*REAL(ay - 1, dp)*s(coset(0, ay - 2, az), 1, l)
     957      8518926 :                         IF (ly1 > 0) s(coset(0, ay, az), 1, l) = s(coset(0, ay, az), 1, l) + &
     958     11062062 :                                                                  f2y*s(coset(0, ay - 1, az), 1, ly1)
     959              :                      END DO
     960              : 
     961              : !             *** Increase the angular momentum component x of function a ***
     962              : 
     963     23892750 :                      DO ay = 0, la - 1
     964     16205838 :                         az = la - 1 - ay
     965     16205838 :                         s(coset(1, ay, az), 1, l) = rap(1)*s(coset(0, ay, az), 1, l)
     966     16205838 :                         IF (lx1 > 0) s(coset(1, ay, az), 1, l) = s(coset(1, ay, az), 1, l) + &
     967     14106525 :                                                                  f2x*s(coset(0, ay, az), 1, lx1)
     968              :                      END DO
     969              : 
     970     28486378 :                      DO ax = 2, la
     971      8518926 :                         f3 = f2*REAL(ax - 1, dp)
     972     25556778 :                         DO ay = 0, la - ax
     973      9350940 :                            az = la - ax - ay
     974              :                            s(coset(ax, ay, az), 1, l) = rap(1)*s(coset(ax - 1, ay, az), 1, l) + &
     975      9350940 :                                                         f3*s(coset(ax - 2, ay, az), 1, l)
     976      9350940 :                            IF (lx1 > 0) s(coset(ax, ay, az), 1, l) = s(coset(ax, ay, az), 1, l) + &
     977     12224763 :                                                                      f2x*s(coset(ax - 1, ay, az), 1, lx1)
     978              :                         END DO
     979              :                      END DO
     980              : 
     981              :                   END DO
     982              : 
     983              : !           *** Recurrence steps: [a|M|s] -> [a|M|b] ***
     984              : 
     985     12280540 :                   IF (lb_max > 0) THEN
     986              : 
     987     97110248 :                      DO j = 2, ncoset(lb_max)
     988    877833488 :                         DO i = 1, ncoset(la_max)
     989    865870592 :                            s(i, j, l) = 0.0_dp
     990              :                         END DO
     991              :                      END DO
     992              : 
     993              : !             *** Horizontal recurrence steps ***
     994              : 
     995     47851584 :                      rbp(:) = rap(:) - rab(:)
     996              : 
     997              : !             *** [a|M|p] = [a+1i|M|s] - (Bi - Ai)*[a|M|s] ***
     998              : 
     999     11962896 :                      IF (lb_max == 1) THEN
    1000      5138462 :                         la_start = la_min
    1001              :                      ELSE
    1002      6824434 :                         la_start = MAX(0, la_min - 1)
    1003              :                      END IF
    1004              : 
    1005     31398210 :                      DO la = la_start, la_max - 1
    1006     59292007 :                         DO ax = 0, la
    1007     84512589 :                            DO ay = 0, la - ax
    1008     37183478 :                               az = la - ax - ay
    1009              :                               s(coset(ax, ay, az), 2, l) = s(coset(ax + 1, ay, az), 1, l) - &
    1010     37183478 :                                                            rab(1)*s(coset(ax, ay, az), 1, l)
    1011              :                               s(coset(ax, ay, az), 3, l) = s(coset(ax, ay + 1, az), 1, l) - &
    1012     37183478 :                                                            rab(2)*s(coset(ax, ay, az), 1, l)
    1013              :                               s(coset(ax, ay, az), 4, l) = s(coset(ax, ay, az + 1), 1, l) - &
    1014     65077275 :                                                            rab(3)*s(coset(ax, ay, az), 1, l)
    1015              :                            END DO
    1016              :                         END DO
    1017              :                      END DO
    1018              : 
    1019              : !             *** Vertical recurrence step ***
    1020              : 
    1021              : !             *** [a|M|p] = (Pi - Bi)*[a|M|s] + f2*Ni(a)*[a-1i|M|s] ***
    1022              : !             ***           + f2*Ni(m)*[a|M-1i|s]                   ***
    1023              : 
    1024     43547522 :                      DO ax = 0, la_max
    1025     31584626 :                         fx = f2*REAL(ax, dp)
    1026    103244198 :                         DO ay = 0, la_max - ax
    1027     59696676 :                            fy = f2*REAL(ay, dp)
    1028     59696676 :                            az = la_max - ax - ay
    1029     59696676 :                            fz = f2*REAL(az, dp)
    1030     59696676 :                            IF (ax == 0) THEN
    1031     31584626 :                               s(coset(ax, ay, az), 2, l) = rbp(1)*s(coset(ax, ay, az), 1, l)
    1032              :                            ELSE
    1033              :                               s(coset(ax, ay, az), 2, l) = rbp(1)*s(coset(ax, ay, az), 1, l) + &
    1034     28112050 :                                                            fx*s(coset(ax - 1, ay, az), 1, l)
    1035              :                            END IF
    1036     59696676 :                            IF (lx1 > 0) s(coset(ax, ay, az), 2, l) = s(coset(ax, ay, az), 2, l) + &
    1037     23484123 :                                                                      f2x*s(coset(ax, ay, az), 1, lx1)
    1038     59696676 :                            IF (ay == 0) THEN
    1039     31584626 :                               s(coset(ax, ay, az), 3, l) = rbp(2)*s(coset(ax, ay, az), 1, l)
    1040              :                            ELSE
    1041              :                               s(coset(ax, ay, az), 3, l) = rbp(2)*s(coset(ax, ay, az), 1, l) + &
    1042     28112050 :                                                            fy*s(coset(ax, ay - 1, az), 1, l)
    1043              :                            END IF
    1044     59696676 :                            IF (ly1 > 0) s(coset(ax, ay, az), 3, l) = s(coset(ax, ay, az), 3, l) + &
    1045     23484123 :                                                                      f2y*s(coset(ax, ay, az), 1, ly1)
    1046     59696676 :                            IF (az == 0) THEN
    1047     31584626 :                               s(coset(ax, ay, az), 4, l) = rbp(3)*s(coset(ax, ay, az), 1, l)
    1048              :                            ELSE
    1049              :                               s(coset(ax, ay, az), 4, l) = rbp(3)*s(coset(ax, ay, az), 1, l) + &
    1050     28112050 :                                                            fz*s(coset(ax, ay, az - 1), 1, l)
    1051              :                            END IF
    1052     59696676 :                            IF (lz1 > 0) s(coset(ax, ay, az), 4, l) = s(coset(ax, ay, az), 4, l) + &
    1053     55068749 :                                                                      f2z*s(coset(ax, ay, az), 1, lz1)
    1054              :                         END DO
    1055              :                      END DO
    1056              : 
    1057              : !             *** Recurrence steps: [a|M|p] -> [a|M|b] ***
    1058              : 
    1059     19618536 :                      DO lb = 2, lb_max
    1060              : 
    1061              : !               *** Horizontal recurrence steps ***
    1062              : 
    1063              : !               *** [a|M|b] = [a+1i|M|b-1i] - (Bi - Ai)*[a|M|b-1i] ***
    1064              : 
    1065      7655640 :                         IF (lb == lb_max) THEN
    1066      6824434 :                            la_start = la_min
    1067              :                         ELSE
    1068       831206 :                            la_start = MAX(0, la_min - 1)
    1069              :                         END IF
    1070              : 
    1071     21558852 :                         DO la = la_start, la_max - 1
    1072     43273880 :                            DO ax = 0, la
    1073     65958818 :                               DO ay = 0, la - ax
    1074     30340578 :                                  az = la - ax - ay
    1075              : 
    1076              : !                     *** Shift of angular momentum component z from a to b ***
    1077              : 
    1078              :                                  s(coset(ax, ay, az), coset(0, 0, lb), l) = &
    1079              :                                     s(coset(ax, ay, az + 1), coset(0, 0, lb - 1), l) - &
    1080     30340578 :                                     rab(3)*s(coset(ax, ay, az), coset(0, 0, lb - 1), l)
    1081              : 
    1082              : !                     *** Shift of angular momentum component y from a to b ***
    1083              : 
    1084     94429112 :                                  DO by = 1, lb
    1085     64088534 :                                     bz = lb - by
    1086              :                                     s(coset(ax, ay, az), coset(0, by, bz), l) = &
    1087              :                                        s(coset(ax, ay + 1, az), coset(0, by - 1, bz), l) - &
    1088     94429112 :                                        rab(2)*s(coset(ax, ay, az), coset(0, by - 1, bz), l)
    1089              :                                  END DO
    1090              : 
    1091              : !                     *** Shift of angular momentum component x from a to b ***
    1092              : 
    1093    116144140 :                                  DO bx = 1, lb
    1094    195672980 :                                     DO by = 0, lb - bx
    1095    101243868 :                                        bz = lb - bx - by
    1096              :                                        s(coset(ax, ay, az), coset(bx, by, bz), l) = &
    1097              :                                           s(coset(ax + 1, ay, az), coset(bx - 1, by, bz), l) - &
    1098    165332402 :                                           rab(1)*s(coset(ax, ay, az), coset(bx - 1, by, bz), l)
    1099              :                                     END DO
    1100              :                                  END DO
    1101              : 
    1102              :                               END DO
    1103              :                            END DO
    1104              :                         END DO
    1105              : 
    1106              : !               *** Vertical recurrence step ***
    1107              : 
    1108              : !               *** [a|M|b] = (Pi - Bi)*[a|M|b-1i] + f2*Ni(a)*[a-1i|M|b-1i] + ***
    1109              : !               ***           f2*Ni(b-1i)*[a|M|b-2i] + f2*Ni(m)[a|M-1i|b-1i]  ***
    1110              : 
    1111     41935015 :                         DO ax = 0, la_max
    1112     22316479 :                            fx = f2*REAL(ax, dp)
    1113     74768514 :                            DO ay = 0, la_max - ax
    1114     44796395 :                               fy = f2*REAL(ay, dp)
    1115     44796395 :                               az = la_max - ax - ay
    1116     44796395 :                               fz = f2*REAL(az, dp)
    1117              : 
    1118              : !                   *** Shift of angular momentum component z from a to b ***
    1119              : 
    1120     44796395 :                               f3 = f2*REAL(lb - 1, dp)
    1121              : 
    1122     44796395 :                               IF (az == 0) THEN
    1123              :                                  s(coset(ax, ay, az), coset(0, 0, lb), l) = &
    1124              :                                     rbp(3)*s(coset(ax, ay, az), coset(0, 0, lb - 1), l) + &
    1125     22316479 :                                     f3*s(coset(ax, ay, az), coset(0, 0, lb - 2), l)
    1126              :                               ELSE
    1127              :                                  s(coset(ax, ay, az), coset(0, 0, lb), l) = &
    1128              :                                     rbp(3)*s(coset(ax, ay, az), coset(0, 0, lb - 1), l) + &
    1129              :                                     fz*s(coset(ax, ay, az - 1), coset(0, 0, lb - 1), l) + &
    1130     22479916 :                                     f3*s(coset(ax, ay, az), coset(0, 0, lb - 2), l)
    1131              :                               END IF
    1132     44796395 :                               IF (lz1 > 0) s(coset(ax, ay, az), coset(0, 0, lb), l) = &
    1133              :                                  s(coset(ax, ay, az), coset(0, 0, lb), l) + &
    1134     17793257 :                                  f2z*s(coset(ax, ay, az), coset(0, 0, lb - 1), lz1)
    1135              : 
    1136              : !                   *** Shift of angular momentum component y from a to b ***
    1137              : 
    1138     44796395 :                               IF (ay == 0) THEN
    1139     22316479 :                                  bz = lb - 1
    1140              :                                  s(coset(ax, ay, az), coset(0, 1, bz), l) = &
    1141     22316479 :                                     rbp(2)*s(coset(ax, ay, az), coset(0, 0, bz), l)
    1142     22316479 :                                  IF (ly1 > 0) s(coset(ax, ay, az), coset(0, 1, bz), l) = &
    1143              :                                     s(coset(ax, ay, az), coset(0, 1, bz), l) + &
    1144      8859592 :                                     f2y*s(coset(ax, ay, az), coset(0, 0, bz), ly1)
    1145     47109156 :                                  DO by = 2, lb
    1146     24792677 :                                     bz = lb - by
    1147     24792677 :                                     f3 = f2*REAL(by - 1, dp)
    1148              :                                     s(coset(ax, ay, az), coset(0, by, bz), l) = &
    1149              :                                        rbp(2)*s(coset(ax, ay, az), coset(0, by - 1, bz), l) + &
    1150     24792677 :                                        f3*s(coset(ax, ay, az), coset(0, by - 2, bz), l)
    1151     24792677 :                                     IF (ly1 > 0) s(coset(ax, ay, az), coset(0, by, bz), l) = &
    1152              :                                        s(coset(ax, ay, az), coset(0, by, bz), l) + &
    1153     32160219 :                                        f2y*s(coset(ax, ay, az), coset(0, by - 1, bz), ly1)
    1154              :                                  END DO
    1155              :                               ELSE
    1156     22479916 :                                  bz = lb - 1
    1157              :                                  s(coset(ax, ay, az), coset(0, 1, bz), l) = &
    1158              :                                     rbp(2)*s(coset(ax, ay, az), coset(0, 0, bz), l) + &
    1159     22479916 :                                     fy*s(coset(ax, ay - 1, az), coset(0, 0, bz), l)
    1160     22479916 :                                  IF (ly1 > 0) s(coset(ax, ay, az), coset(0, 1, bz), l) = &
    1161              :                                     s(coset(ax, ay, az), coset(0, 1, bz), l) + &
    1162      8933665 :                                     f2y*s(coset(ax, ay, az), coset(0, 0, bz), ly1)
    1163     47483978 :                                  DO by = 2, lb
    1164     25004062 :                                     bz = lb - by
    1165     25004062 :                                     f3 = f2*REAL(by - 1, dp)
    1166              :                                     s(coset(ax, ay, az), coset(0, by, bz), l) = &
    1167              :                                        rbp(2)*s(coset(ax, ay, az), coset(0, by - 1, bz), l) + &
    1168              :                                        fy*s(coset(ax, ay - 1, az), coset(0, by - 1, bz), l) + &
    1169     25004062 :                                        f3*s(coset(ax, ay, az), coset(0, by - 2, bz), l)
    1170     25004062 :                                     IF (ly1 > 0) s(coset(ax, ay, az), coset(0, by, bz), l) = &
    1171              :                                        s(coset(ax, ay, az), coset(0, by, bz), l) + &
    1172     32415935 :                                        f2y*s(coset(ax, ay, az), coset(0, by - 1, bz), ly1)
    1173              :                                  END DO
    1174              :                               END IF
    1175              : 
    1176              : !                   *** Shift of angular momentum component x from a to b ***
    1177              : 
    1178     67112874 :                               IF (ax == 0) THEN
    1179     69425635 :                                  DO by = 0, lb - 1
    1180     47109156 :                                     bz = lb - 1 - by
    1181              :                                     s(coset(ax, ay, az), coset(1, by, bz), l) = &
    1182     47109156 :                                        rbp(1)*s(coset(ax, ay, az), coset(0, by, bz), l)
    1183     47109156 :                                     IF (lx1 > 0) s(coset(ax, ay, az), coset(1, by, bz), l) = &
    1184              :                                        s(coset(ax, ay, az), coset(1, by, bz), l) + &
    1185     41019811 :                                        f2x*s(coset(ax, ay, az), coset(0, by, bz), lx1)
    1186              :                                  END DO
    1187     47109156 :                                  DO bx = 2, lb
    1188     24792677 :                                     f3 = f2*REAL(bx - 1, dp)
    1189     74378031 :                                     DO by = 0, lb - bx
    1190     27268875 :                                        bz = lb - bx - by
    1191              :                                        s(coset(ax, ay, az), coset(bx, by, bz), l) = &
    1192              :                                           rbp(1)*s(coset(ax, ay, az), coset(bx - 1, by, bz), l) + &
    1193     27268875 :                                           f3*s(coset(ax, ay, az), coset(bx - 2, by, bz), l)
    1194     27268875 :                                        IF (lx1 > 0) s(coset(ax, ay, az), coset(bx, by, bz), l) = &
    1195              :                                           s(coset(ax, ay, az), coset(bx, by, bz), l) + &
    1196     35620565 :                                           f2x*s(coset(ax, ay, az), coset(bx - 1, by, bz), lx1)
    1197              :                                     END DO
    1198              :                                  END DO
    1199              :                               ELSE
    1200     69963894 :                                  DO by = 0, lb - 1
    1201     47483978 :                                     bz = lb - 1 - by
    1202              :                                     s(coset(ax, ay, az), coset(1, by, bz), l) = &
    1203              :                                        rbp(1)*s(coset(ax, ay, az), coset(0, by, bz), l) + &
    1204     47483978 :                                        fx*s(coset(ax - 1, ay, az), coset(0, by, bz), l)
    1205     47483978 :                                     IF (lx1 > 0) s(coset(ax, ay, az), coset(1, by, bz), l) = &
    1206              :                                        s(coset(ax, ay, az), coset(1, by, bz), l) + &
    1207     41349600 :                                        f2x*s(coset(ax, ay, az), coset(0, by, bz), lx1)
    1208              :                                  END DO
    1209     47483978 :                                  DO bx = 2, lb
    1210     25004062 :                                     f3 = f2*REAL(bx - 1, dp)
    1211     75012186 :                                     DO by = 0, lb - bx
    1212     27528208 :                                        bz = lb - bx - by
    1213              :                                        s(coset(ax, ay, az), coset(bx, by, bz), l) = &
    1214              :                                           rbp(1)*s(coset(ax, ay, az), coset(bx - 1, by, bz), l) + &
    1215              :                                           fx*s(coset(ax - 1, ay, az), coset(bx - 1, by, bz), l) + &
    1216     27528208 :                                           f3*s(coset(ax, ay, az), coset(bx - 2, by, bz), l)
    1217     27528208 :                                        IF (lx1 > 0) s(coset(ax, ay, az), coset(bx, by, bz), l) = &
    1218              :                                           s(coset(ax, ay, az), coset(bx, by, bz), l) + &
    1219     35942435 :                                           f2x*s(coset(ax, ay, az), coset(bx - 1, by, bz), lx1)
    1220              :                                     END DO
    1221              :                                  END DO
    1222              :                               END IF
    1223              : 
    1224              :                            END DO
    1225              :                         END DO
    1226              : 
    1227              :                      END DO
    1228              : 
    1229              :                   END IF
    1230              : 
    1231              :                ELSE
    1232              : 
    1233       616965 :                   IF (lb_max > 0) THEN
    1234              : 
    1235              : !             *** Vertical recurrence steps: [s|M|s] -> [s|M|b] ***
    1236              : 
    1237       843984 :                      rbp(:) = (f1 - 1.0_dp)*rab(:)
    1238              : 
    1239              : !             *** [s|M|p] = (Pi - Bi)*[s|M|s] + f2*Ni(m)*[s|M-1i|s] ***
    1240              : 
    1241       210996 :                      s(1, 2, l) = rbp(1)*s(1, 1, l)
    1242       210996 :                      s(1, 3, l) = rbp(2)*s(1, 1, l)
    1243       210996 :                      s(1, 4, l) = rbp(3)*s(1, 1, l)
    1244       210996 :                      IF (lx1 > 0) s(1, 2, l) = s(1, 2, l) + f2x*s(1, 1, lx1)
    1245       210996 :                      IF (ly1 > 0) s(1, 3, l) = s(1, 3, l) + f2y*s(1, 1, ly1)
    1246       210996 :                      IF (lz1 > 0) s(1, 4, l) = s(1, 4, l) + f2z*s(1, 1, lz1)
    1247              : 
    1248              : !             *** [s|M|b] = (Pi - Bi)*[s|M|b-1i] + f2*Ni(b-1i)*[s|M|b-2i] ***
    1249              : !             ***           + f2*Ni(m)*[s|M-1i|b-1i]                      ***
    1250              : 
    1251       237656 :                      DO lb = 2, lb_max
    1252              : 
    1253              : !               *** Increase the angular momentum component z of function b ***
    1254              : 
    1255              :                         s(1, coset(0, 0, lb), l) = rbp(3)*s(1, coset(0, 0, lb - 1), l) + &
    1256        26660 :                                                    f2*REAL(lb - 1, dp)*s(1, coset(0, 0, lb - 2), l)
    1257        26660 :                         IF (lz1 > 0) s(1, coset(0, 0, lb), l) = s(1, coset(0, 0, lb), l) + &
    1258         6821 :                                                                 f2z*s(1, coset(0, 0, lb - 1), lz1)
    1259              : 
    1260              : !               *** Increase the angular momentum component y of function b ***
    1261              : 
    1262        26660 :                         bz = lb - 1
    1263        26660 :                         s(1, coset(0, 1, bz), l) = rbp(2)*s(1, coset(0, 0, bz), l)
    1264        26660 :                         IF (ly1 > 0) s(1, coset(0, 1, bz), l) = s(1, coset(0, 1, bz), l) + &
    1265         6821 :                                                                 f2y*s(1, coset(0, 0, bz), ly1)
    1266              : 
    1267        53848 :                         DO by = 2, lb
    1268        27188 :                            bz = lb - by
    1269              :                            s(1, coset(0, by, bz), l) = rbp(2)*s(1, coset(0, by - 1, bz), l) + &
    1270        27188 :                                                        f2*REAL(by - 1, dp)*s(1, coset(0, by - 2, bz), l)
    1271        27188 :                            IF (ly1 > 0) s(1, coset(0, by, bz), l) = s(1, coset(0, by, bz), l) + &
    1272        33613 :                                                                     f2y*s(1, coset(0, by - 1, bz), ly1)
    1273              :                         END DO
    1274              : 
    1275              : !             *** Increase the angular momentum component x of function b ***
    1276              : 
    1277        80508 :                         DO by = 0, lb - 1
    1278        53848 :                            bz = lb - 1 - by
    1279        53848 :                            s(1, coset(1, by, bz), l) = rbp(1)*s(1, coset(0, by, bz), l)
    1280        53848 :                            IF (lx1 > 0) s(1, coset(1, by, bz), l) = s(1, coset(1, by, bz), l) + &
    1281        40434 :                                                                     f2x*s(1, coset(0, by, bz), lx1)
    1282              :                         END DO
    1283              : 
    1284       264844 :                         DO bx = 2, lb
    1285        27188 :                            f3 = f2*REAL(bx - 1, dp)
    1286        81564 :                            DO by = 0, lb - bx
    1287        27716 :                               bz = lb - bx - by
    1288              :                               s(1, coset(bx, by, bz), l) = rbp(1)*s(1, coset(bx - 1, by, bz), l) + &
    1289        27716 :                                                            f3*s(1, coset(bx - 2, by, bz), l)
    1290        27716 :                               IF (lx1 > 0) s(1, coset(bx, by, bz), l) = s(1, coset(bx, by, bz), l) + &
    1291        34273 :                                                                         f2x*s(1, coset(bx - 1, by, bz), lx1)
    1292              :                            END DO
    1293              :                         END DO
    1294              : 
    1295              :                      END DO
    1296              : 
    1297              :                   END IF
    1298              : 
    1299              :                END IF
    1300              : 
    1301              :             END DO
    1302              : 
    1303     12897505 :             DO k = 2, ncoset(lc_max)
    1304    101040675 :                DO j = 1, ncoset(lb_max)
    1305    888160476 :                   DO i = 1, ncoset(la_max)
    1306    876772480 :                      mab(na + i, nb + j, k - 1) = s(i, j, k)
    1307              :                   END DO
    1308              :                END DO
    1309              :             END DO
    1310              : 
    1311      2979479 :             nb = nb + ncoset(lb_max)
    1312              : 
    1313              :          END DO
    1314              : 
    1315      2118772 :          na = na + ncoset(la_max)
    1316              : 
    1317              :       END DO
    1318              : 
    1319       648802 :    END SUBROUTINE moment
    1320              : 
    1321              : ! **************************************************************************************************
    1322              : !> \brief This returns the derivative of the moment integrals [a|\mu|b].
    1323              : !>       By default, it differentiates the primitive on the right:
    1324              : !>       [a|\mu|d/dR_bi] =  2*zetb*[a|\mu|b+1i] - Ni(b)[a|\mu|b-1i]
    1325              : !>       A weighted derivative combines the left and right primitive derivatives
    1326              : !>       using deltaR for the corresponding atom centers.
    1327              : !>       order indicates the max order of the moment operator to be calculated
    1328              : !>       1: dipole
    1329              : !>       2: quadrupole
    1330              : !>       ...
    1331              : !> \param la_max ...
    1332              : !> \param npgfa ...
    1333              : !> \param zeta ...
    1334              : !> \param rpgfa ...
    1335              : !> \param la_min ...
    1336              : !> \param lb_max ...
    1337              : !> \param npgfb ...
    1338              : !> \param zetb ...
    1339              : !> \param rpgfb ...
    1340              : !> \param lb_min ...
    1341              : !> \param order ...
    1342              : !> \param rac ...
    1343              : !> \param rbc ...
    1344              : !> \param difmab ...
    1345              : !> \param mab_ext ...
    1346              : !> \param deltaR optional weights for the left and right primitive derivatives
    1347              : !> \param lambda optional atom selector for the factor (iatom == lambda) - (jatom == lambda)
    1348              : !> \param iatom atom associated with the left basis function
    1349              : !> \param jatom atom associated with the right basis function
    1350              : !> \note
    1351              : ! **************************************************************************************************
    1352       600231 :    SUBROUTINE diff_momop(la_max, npgfa, zeta, rpgfa, la_min, &
    1353       600231 :                          lb_max, npgfb, zetb, rpgfb, lb_min, &
    1354       600231 :                          order, rac, rbc, difmab, mab_ext, deltaR, lambda, iatom, jatom)
    1355              : 
    1356              :       INTEGER, INTENT(IN)                                :: la_max, npgfa
    1357              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zeta, rpgfa
    1358              :       INTEGER, INTENT(IN)                                :: la_min, lb_max, npgfb
    1359              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zetb, rpgfb
    1360              :       INTEGER, INTENT(IN)                                :: lb_min, order
    1361              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: rac, rbc
    1362              :       REAL(KIND=dp), DIMENSION(:, :, :, :), INTENT(OUT)  :: difmab
    1363              :       REAL(KIND=dp), DIMENSION(:, :, :), OPTIONAL, &
    1364              :          POINTER                                         :: mab_ext
    1365              :       REAL(KIND=dp), DIMENSION(:, :), OPTIONAL, POINTER  :: deltaR
    1366              :       INTEGER, INTENT(IN), OPTIONAL                      :: lambda, iatom, jatom
    1367              : 
    1368              :       INTEGER                                            :: ider, imom, lda, lda_min, ldb, ldb_min
    1369              :       REAL(KIND=dp)                                      :: dab, rab(3), rab2
    1370       600231 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: difmab_tmp
    1371              :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: mab
    1372              : 
    1373      2400924 :       rab = rbc - rac
    1374      2400924 :       rab2 = SUM(rab**2)
    1375       600231 :       dab = SQRT(rab2)
    1376              : 
    1377       600231 :       lda_min = MAX(0, la_min - 1)
    1378       600231 :       ldb_min = MAX(0, lb_min - 1)
    1379       600231 :       lda = ncoset(la_max)*npgfa
    1380       600231 :       ldb = ncoset(lb_max)*npgfb
    1381      2974323 :       ALLOCATE (difmab_tmp(lda, ldb, 3))
    1382              : 
    1383       600231 :       IF (PRESENT(mab_ext)) THEN
    1384       600231 :          mab => mab_ext
    1385              :       ELSE
    1386              :          ALLOCATE (mab(npgfa*ncoset(la_max + 1), npgfb*ncoset(lb_max + 1), &
    1387            0 :                        ncoset(order) - 1))
    1388            0 :          mab = 0.0_dp
    1389              : !     *** Calculate the primitive overlap integrals ***
    1390              :          CALL moment(la_max + 1, npgfa, zeta, rpgfa, lda_min, &
    1391              :                      lb_max + 1, npgfb, zetb, rpgfb, &
    1392            0 :                      order, rac, rbc, mab)
    1393              : 
    1394              :       END IF
    1395      5982852 :       DO imom = 1, ncoset(order) - 1
    1396              :          CALL adbdr(la_max, npgfa, rpgfa, la_min, &
    1397              :                     lb_max, npgfb, zetb, rpgfb, lb_min, &
    1398              :                     dab, mab(:, :, imom), difmab_tmp(:, :, 1), &
    1399      5382621 :                     difmab_tmp(:, :, 2), difmab_tmp(:, :, 3))
    1400      5982852 :          IF (PRESENT(deltaR)) THEN
    1401         6804 :             CPASSERT(ASSOCIATED(deltaR))
    1402         6804 :             CPASSERT(PRESENT(iatom) .AND. PRESENT(jatom))
    1403        27216 :             DO ider = 1, 3
    1404              :                difmab(1:lda, 1:ldb, imom, ider) = &
    1405      1496880 :                   difmab_tmp(1:lda, 1:ldb, ider)*deltaR(ider, jatom)
    1406              :             END DO
    1407              : 
    1408              :             CALL dabdr(la_max, npgfa, zeta, rpgfa, la_min, &
    1409              :                        lb_max, npgfb, rpgfb, lb_min, &
    1410              :                        dab, mab(:, :, imom), difmab_tmp(:, :, 1), &
    1411         6804 :                        difmab_tmp(:, :, 2), difmab_tmp(:, :, 3))
    1412        27216 :             DO ider = 1, 3
    1413              :                difmab(1:lda, 1:ldb, imom, ider) = difmab(1:lda, 1:ldb, imom, ider) &
    1414      1496880 :                                                   + difmab_tmp(1:lda, 1:ldb, ider)*deltaR(ider, iatom)
    1415              :             END DO
    1416              :          ELSE
    1417   1206943560 :             difmab(1:lda, 1:ldb, imom, :) = difmab_tmp(1:lda, 1:ldb, :)
    1418              :          END IF
    1419              :       END DO
    1420              : 
    1421       600231 :       IF (PRESENT(lambda)) THEN
    1422           27 :          CPASSERT(.NOT. PRESENT(deltaR))
    1423           27 :          CPASSERT(PRESENT(iatom) .AND. PRESENT(jatom))
    1424           27 :          IF (iatom == lambda .AND. jatom == lambda) THEN
    1425         7383 :             difmab = 0.0_dp
    1426           24 :          ELSE IF (iatom == lambda) THEN
    1427              :             ! The right-hand derivative is selected with a positive sign.
    1428           18 :          ELSE IF (jatom == lambda) THEN
    1429        14766 :             difmab = -difmab
    1430              :          ELSE
    1431        29532 :             difmab = 0.0_dp
    1432              :          END IF
    1433              :       END IF
    1434              : 
    1435       600231 :       IF (PRESENT(mab_ext)) THEN
    1436              :          NULLIFY (mab)
    1437              :       ELSE
    1438            0 :          DEALLOCATE (mab)
    1439              :       END IF
    1440       600231 :       DEALLOCATE (difmab_tmp)
    1441              : 
    1442       600231 :    END SUBROUTINE diff_momop
    1443              : 
    1444              : ! **************************************************************************************************
    1445              : !> \brief This returns the derivative of the dipole integrals [a|x|b], with respect
    1446              : !>       to the position of the primitive on the left and right, i.e.
    1447              : !>       [da/dR_ai|\mu|b] =  2*zeta*[a+1i|\mu|b] - Ni(a)[a-1i|\mu|b]
    1448              : !> \param la_max ...
    1449              : !> \param npgfa ...
    1450              : !> \param zeta ...
    1451              : !> \param rpgfa ...
    1452              : !> \param la_min ...
    1453              : !> \param lb_max ...
    1454              : !> \param npgfb ...
    1455              : !> \param zetb ...
    1456              : !> \param rpgfb ...
    1457              : !> \param lb_min ...
    1458              : !> \param order ...
    1459              : !> \param rac ...
    1460              : !> \param rbc ...
    1461              : !> \param pab ...
    1462              : !> \param forcea ...
    1463              : !> \param forceb ...
    1464              : !> \note
    1465              : ! **************************************************************************************************
    1466         2124 :    SUBROUTINE dipole_force(la_max, npgfa, zeta, rpgfa, la_min, &
    1467         2124 :                            lb_max, npgfb, zetb, rpgfb, lb_min, &
    1468         2124 :                            order, rac, rbc, pab, forcea, forceb)
    1469              : 
    1470              :       INTEGER, INTENT(IN)                                :: la_max, npgfa
    1471              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zeta, rpgfa
    1472              :       INTEGER, INTENT(IN)                                :: la_min, lb_max, npgfb
    1473              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: zetb, rpgfb
    1474              :       INTEGER, INTENT(IN)                                :: lb_min, order
    1475              :       REAL(KIND=dp), DIMENSION(3), INTENT(IN)            :: rac, rbc
    1476              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(IN)         :: pab
    1477              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT)      :: forcea, forceb
    1478              : 
    1479              :       INTEGER                                            :: i, imom, ipgf, j, jpgf, lda, lda_min, &
    1480              :                                                             ldb, ldb_min, na, nb
    1481              :       REAL(KIND=dp)                                      :: dab, rab(3), rab2
    1482         2124 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: difmab, mab
    1483              : 
    1484         2124 :       CPASSERT(order == 1)
    1485              :       MARK_USED(order)
    1486              : 
    1487         8496 :       rab = rbc - rac
    1488         8496 :       rab2 = SUM(rab**2)
    1489         2124 :       dab = SQRT(rab2)
    1490              : 
    1491         2124 :       lda_min = MAX(0, la_min - 1)
    1492         2124 :       ldb_min = MAX(0, lb_min - 1)
    1493         2124 :       lda = ncoset(la_max)*npgfa
    1494         2124 :       ldb = ncoset(lb_max)*npgfb
    1495        10620 :       ALLOCATE (difmab(lda, ldb, 3))
    1496        10620 :       ALLOCATE (mab(npgfa*ncoset(la_max + 1), npgfb*ncoset(lb_max + 1), 3))
    1497         2124 :       mab = 0.0_dp
    1498              :       CALL moment(la_max + 1, npgfa, zeta, rpgfa, lda_min, &
    1499         2124 :                   lb_max + 1, npgfb, zetb, rpgfb, 1, rac, rbc, mab)
    1500              : 
    1501         8496 :       DO imom = 1, 3
    1502         6372 :          difmab = 0.0_dp
    1503              :          CALL adbdr(la_max, npgfa, rpgfa, la_min, lb_max, npgfb, zetb, rpgfb, lb_min, &
    1504         6372 :                     dab, mab(:, :, imom), difmab(:, :, 1), difmab(:, :, 2), difmab(:, :, 3))
    1505         6372 :          na = 0
    1506        24360 :          DO ipgf = 1, npgfa
    1507              :             nb = 0
    1508        69429 :             DO jpgf = 1, npgfb
    1509       171363 :                DO j = nb + ncoset(lb_min - 1) + 1, nb + ncoset(lb_max)
    1510       518880 :                   DO i = na + ncoset(la_min - 1) + 1, na + ncoset(la_max)
    1511       347517 :                      forceb(imom, 1) = forceb(imom, 1) + pab(i, j)*difmab(i, j, 1)
    1512       347517 :                      forceb(imom, 2) = forceb(imom, 2) + pab(i, j)*difmab(i, j, 2)
    1513       467439 :                      forceb(imom, 3) = forceb(imom, 3) + pab(i, j)*difmab(i, j, 3)
    1514              :                   END DO
    1515              :                END DO
    1516        69429 :                nb = nb + ncoset(lb_max)
    1517              :             END DO
    1518        24360 :             na = na + ncoset(la_max)
    1519              :          END DO
    1520              : 
    1521         6372 :          difmab = 0.0_dp
    1522              :          CALL dabdr(la_max, npgfa, zeta, rpgfa, la_min, lb_max, npgfb, rpgfb, lb_min, &
    1523         6372 :                     dab, mab(:, :, imom), difmab(:, :, 1), difmab(:, :, 2), difmab(:, :, 3))
    1524         6372 :          na = 0
    1525        26484 :          DO ipgf = 1, npgfa
    1526              :             nb = 0
    1527        69429 :             DO jpgf = 1, npgfb
    1528       171363 :                DO j = nb + ncoset(lb_min - 1) + 1, nb + ncoset(lb_max)
    1529       518880 :                   DO i = na + ncoset(la_min - 1) + 1, na + ncoset(la_max)
    1530       347517 :                      forcea(imom, 1) = forcea(imom, 1) + pab(i, j)*difmab(i, j, 1)
    1531       347517 :                      forcea(imom, 2) = forcea(imom, 2) + pab(i, j)*difmab(i, j, 2)
    1532       467439 :                      forcea(imom, 3) = forcea(imom, 3) + pab(i, j)*difmab(i, j, 3)
    1533              :                   END DO
    1534              :                END DO
    1535        69429 :                nb = nb + ncoset(lb_max)
    1536              :             END DO
    1537        24360 :             na = na + ncoset(la_max)
    1538              :          END DO
    1539              :       END DO
    1540              : 
    1541         2124 :       DEALLOCATE (mab, difmab)
    1542              : 
    1543         2124 :    END SUBROUTINE dipole_force
    1544              : 
    1545              : END MODULE ai_moments
        

Generated by: LCOV version 2.0-1