LCOV - code coverage report
Current view: top level - src - libint_2c_3c.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:123285f) Lines: 94.3 % 315 297
Test Date: 2026-11-04 00:58:17 Functions: 100.0 % 6 6

            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 2- and 3-center electron repulsion integral routines based on libint2
      10              : !>        Currently available operators: Coulomb, Truncated Coulomb, Short Range (erfc), Overlap
      11              : !> \author A. Bussy (05.2019)
      12              : ! **************************************************************************************************
      13              : 
      14              : MODULE libint_2c_3c
      15              :    USE input_constants,                 ONLY: do_potential_coulomb,&
      16              :                                               do_potential_id,&
      17              :                                               do_potential_mix_cl_trunc,&
      18              :                                               do_potential_short,&
      19              :                                               do_potential_truncated
      20              :    USE integral_library_types,          ONLY: compare_potential_types,&
      21              :                                               coulomb_operator_type,&
      22              :                                               libint_potential_type => coulomb_operator_type
      23              :    USE kinds,                           ONLY: dp
      24              :    USE libint_wrapper,                  ONLY: &
      25              :         cp_libint_get_2eri_derivs, cp_libint_get_2eris, cp_libint_get_3eri_derivs, &
      26              :         cp_libint_get_3eris, cp_libint_set_params_eri, cp_libint_set_params_eri_deriv, &
      27              :         cp_libint_t, eri_primitive_data_type, prim_data_f_size
      28              :    USE mathconstants,                   ONLY: pi
      29              :    USE orbital_pointers,                ONLY: nco,&
      30              :                                               ncoset
      31              :    USE r12_fundamentals,                ONLY: compute_r12_fundamentals
      32              :    USE t_c_g0,                          ONLY: get_lmax_init
      33              : #include "./base/base_uses.f90"
      34              : 
      35              :    IMPLICIT NONE
      36              :    PRIVATE
      37              : 
      38              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'libint_2c_3c'
      39              : 
      40              :    PUBLIC :: eri_2center, eri_3center, cutoff_screen_factor, libint_potential_type, &
      41              :              eri_3center_derivs, eri_2center_derivs, compare_potential_types
      42              : 
      43              :    ! For screening of integrals with a truncated potential, it is important to use a slightly larger
      44              :    ! cutoff radius due to the discontinuity of the truncated Coulomb potential at the cutoff radius.
      45              :    REAL(KIND=dp), PARAMETER :: cutoff_screen_factor = 1.0001_dp
      46              : 
      47              : CONTAINS
      48              : 
      49              : ! **************************************************************************************************
      50              : !> \brief Computes the 3-center electron repulsion integrals (ab|c) for a given set of cartesian
      51              : !>        gaussian orbitals
      52              : !> \param int_abc the integrals as array of cartesian orbitals (allocated before hand)
      53              : !> \param la_min ...
      54              : !> \param la_max ...
      55              : !> \param npgfa ...
      56              : !> \param zeta ...
      57              : !> \param rpgfa ...
      58              : !> \param ra ...
      59              : !> \param lb_min ...
      60              : !> \param lb_max ...
      61              : !> \param npgfb ...
      62              : !> \param zetb ...
      63              : !> \param rpgfb ...
      64              : !> \param rb ...
      65              : !> \param lc_min ...
      66              : !> \param lc_max ...
      67              : !> \param npgfc ...
      68              : !> \param zetc ...
      69              : !> \param rpgfc ...
      70              : !> \param rc ...
      71              : !> \param dab ...
      72              : !> \param dac ...
      73              : !> \param dbc ...
      74              : !> \param lib the libint_t object for evaluation (assume that it is initialized outside)
      75              : !> \param potential_parameter the info about the potential
      76              : !> \param int_abc_ext the extremal value of int_abc, i.e., MAXVAL(ABS(int_abc))
      77              : !> \note Prior to calling this routine, the cp_libint_t type passed as argument must be initialized,
      78              : !>       the libint library must be static initialized, and in case of truncated Coulomb operator,
      79              : !>       the latter must be initialized too
      80              : ! **************************************************************************************************
      81      9668738 :    SUBROUTINE eri_3center(int_abc, la_min, la_max, npgfa, zeta, rpgfa, ra, &
      82      9668738 :                           lb_min, lb_max, npgfb, zetb, rpgfb, rb, &
      83      9668738 :                           lc_min, lc_max, npgfc, zetc, rpgfc, rc, &
      84              :                           dab, dac, dbc, lib, potential_parameter, &
      85              :                           int_abc_ext)
      86              : 
      87              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: int_abc
      88              :       INTEGER, INTENT(IN)                                :: la_min, la_max, npgfa
      89              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zeta, rpgfa
      90              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: ra
      91              :       INTEGER, INTENT(IN)                                :: lb_min, lb_max, npgfb
      92              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetb, rpgfb
      93              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rb
      94              :       INTEGER, INTENT(IN)                                :: lc_min, lc_max, npgfc
      95              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetc, rpgfc
      96              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rc
      97              :       REAL(KIND=dp), INTENT(IN)                          :: dab, dac, dbc
      98              :       TYPE(cp_libint_t), INTENT(INOUT)                   :: lib
      99              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     100              :       REAL(dp), INTENT(INOUT), OPTIONAL                  :: int_abc_ext
     101              : 
     102              :       INTEGER :: a_mysize(1), a_offset, a_start, b_offset, b_start, c_offset, c_start, i, ipgf, j, &
     103              :          jpgf, k, kpgf, li, lj, lk, ncoa, ncob, ncoc, op, p1, p2, p3
     104              :       REAL(dp)                                           :: dr_ab, dr_ac, dr_bc, zeti, zetj, zetk
     105      9668738 :       REAL(dp), DIMENSION(:), POINTER                    :: p_work
     106              :       TYPE(eri_primitive_data_type)                      :: params
     107              : 
     108      9668738 :       NULLIFY (p_work)
     109              : 
     110      9668738 :       dr_ab = 0.0_dp
     111      9668738 :       dr_bc = 0.0_dp
     112      9668738 :       dr_ac = 0.0_dp
     113              : 
     114      9668738 :       op = potential_parameter%potential_type
     115              : 
     116              :       IF (op == do_potential_truncated .OR. op == do_potential_short &
     117      1269736 :           .OR. op == do_potential_mix_cl_trunc) THEN
     118      8690143 :          dr_bc = potential_parameter%cutoff_radius*cutoff_screen_factor
     119      8690143 :          dr_ac = potential_parameter%cutoff_radius*cutoff_screen_factor
     120       978595 :       ELSE IF (op == do_potential_coulomb) THEN
     121       158765 :          dr_bc = 1000000.0_dp
     122       158765 :          dr_ac = 1000000.0_dp
     123              :       END IF
     124              : 
     125      9668738 :       IF (PRESENT(int_abc_ext)) THEN
     126      9497196 :          int_abc_ext = 0.0_dp
     127              :       END IF
     128              : 
     129              :       !Note: we want to compute all possible integrals based on the 3-centers (ab|c) before
     130              :       !      having to switch to (ba|c) (or the other way around) due to angular momenta in libint
     131              :       !      For a triplet of centers (k|ji), we can only compute integrals for which lj >= li
     132              : 
     133              :       !Looping over the pgfs
     134     30114868 :       DO ipgf = 1, npgfa
     135     20446130 :          zeti = zeta(ipgf)
     136     20446130 :          a_start = (ipgf - 1)*ncoset(la_max)
     137              : 
     138     86207078 :          DO jpgf = 1, npgfb
     139              : 
     140              :             ! screening
     141     56092210 :             IF (rpgfa(ipgf) + rpgfb(jpgf) + dr_ab < dab) CYCLE
     142              : 
     143     26190984 :             zetj = zetb(jpgf)
     144     26190984 :             b_start = (jpgf - 1)*ncoset(lb_max)
     145              : 
     146     85844343 :             DO kpgf = 1, npgfc
     147              : 
     148              :                ! screening
     149     39207229 :                IF (rpgfb(jpgf) + rpgfc(kpgf) + dr_bc < dbc) CYCLE
     150     28673481 :                IF (rpgfa(ipgf) + rpgfc(kpgf) + dr_ac < dac) CYCLE
     151              : 
     152     23890360 :                zetk = zetc(kpgf)
     153     23890360 :                c_start = (kpgf - 1)*ncoset(lc_max)
     154              : 
     155              :                !start with all the (c|ba) integrals (standard order) and keep to lb >= la
     156              :                CALL prepare_3c_primitive(ra, rb, rc, zeti, zetj, zetk, &
     157     23890360 :                                          la_max + lb_max + lc_max, potential_parameter, params)
     158     23890360 :                CALL cp_libint_set_params_eri(lib, params, [1, 2, 3, 4], params%prepared_max_order)
     159              : 
     160     56153381 :                DO li = la_min, la_max
     161     32263021 :                   a_offset = a_start + ncoset(li - 1)
     162     32263021 :                   ncoa = nco(li)
     163     90703755 :                   DO lj = MAX(li, lb_min), lb_max
     164     34550374 :                      b_offset = b_start + ncoset(lj - 1)
     165     34550374 :                      ncob = nco(lj)
     166    110994170 :                      DO lk = lc_min, lc_max
     167     44180775 :                         c_offset = c_start + ncoset(lk - 1)
     168     44180775 :                         ncoc = nco(lk)
     169              : 
     170     44180775 :                         a_mysize(1) = ncoa*ncob*ncoc
     171     44180775 :                         CALL cp_libint_get_3eris(li, lj, lk, lib, p_work, a_mysize)
     172              : 
     173     78731149 :                         IF (PRESENT(int_abc_ext)) THEN
     174    159421579 :                            DO k = 1, ncoc
     175    116465516 :                               p1 = (k - 1)*ncob
     176    424762066 :                               DO j = 1, ncob
     177    265340487 :                                  p2 = (p1 + j - 1)*ncoa
     178    835441538 :                                  DO i = 1, ncoa
     179    453635535 :                                     p3 = p2 + i
     180    453635535 :                                     int_abc(a_offset + i, b_offset + j, c_offset + k) = p_work(p3)
     181    718976022 :                                     int_abc_ext = MAX(int_abc_ext, ABS(p_work(p3)))
     182              :                                  END DO
     183              :                               END DO
     184              :                            END DO
     185              :                         ELSE
     186      5588697 :                            DO k = 1, ncoc
     187      4363985 :                               p1 = (k - 1)*ncob
     188     15128846 :                               DO j = 1, ncob
     189      9540149 :                                  p2 = (p1 + j - 1)*ncoa
     190     29175759 :                                  DO i = 1, ncoa
     191     15271625 :                                     p3 = p2 + i
     192     24811774 :                                     int_abc(a_offset + i, b_offset + j, c_offset + k) = p_work(p3)
     193              :                                  END DO
     194              :                               END DO
     195              :                            END DO
     196              :                         END IF
     197              : 
     198              :                      END DO !lk
     199              :                   END DO !lj
     200              :                END DO !li
     201              : 
     202              :                !swap centers 3 and 4 to compute (c|ab) with lb < la
     203     23890360 :                CALL cp_libint_set_params_eri(lib, params, [1, 2, 4, 3], params%prepared_max_order)
     204              : 
     205    112256621 :                DO lj = lb_min, lb_max
     206     32274051 :                   b_offset = b_start + ncoset(lj - 1)
     207     32274051 :                   ncob = nco(lj)
     208     82851190 :                   DO li = MAX(lj + 1, la_min), la_max
     209     11369910 :                      a_offset = a_start + ncoset(li - 1)
     210     11369910 :                      ncoa = nco(li)
     211     58324069 :                      DO lk = lc_min, lc_max
     212     14680108 :                         c_offset = c_start + ncoset(lk - 1)
     213     14680108 :                         ncoc = nco(lk)
     214              : 
     215     14680108 :                         a_mysize(1) = ncoa*ncob*ncoc
     216     14680108 :                         CALL cp_libint_get_3eris(lj, li, lk, lib, p_work, a_mysize)
     217              : 
     218     26050018 :                         IF (PRESENT(int_abc_ext)) THEN
     219     52991527 :                            DO k = 1, ncoc
     220     38684442 :                               p1 = (k - 1)*ncoa
     221    198382643 :                               DO i = 1, ncoa
     222    145391116 :                                  p2 = (p1 + i - 1)*ncob
     223    375956234 :                                  DO j = 1, ncob
     224    191880676 :                                     p3 = p2 + j
     225    191880676 :                                     int_abc(a_offset + i, b_offset + j, c_offset + k) = p_work(p3)
     226    337271792 :                                     int_abc_ext = MAX(int_abc_ext, ABS(p_work(p3)))
     227              :                                  END DO
     228              :                               END DO
     229              :                            END DO
     230              :                         ELSE
     231      1726525 :                            DO k = 1, ncoc
     232      1353502 :                               p1 = (k - 1)*ncoa
     233      6998668 :                               DO i = 1, ncoa
     234      5272143 :                                  p2 = (p1 + i - 1)*ncob
     235     13612648 :                                  DO j = 1, ncob
     236      6987003 :                                     p3 = p2 + j
     237     12259146 :                                     int_abc(a_offset + i, b_offset + j, c_offset + k) = p_work(p3)
     238              :                                  END DO
     239              :                               END DO
     240              :                            END DO
     241              :                         END IF
     242              : 
     243              :                      END DO !lk
     244              :                   END DO !li
     245              :                END DO !lj
     246              : 
     247              :             END DO !kpgf
     248              :          END DO !jpgf
     249              :       END DO !ipgf
     250              : 
     251    541449328 :    END SUBROUTINE eri_3center
     252              : 
     253              : ! **************************************************************************************************
     254              : !> \brief Prepare geometry and radial seeds for 3-center integrals at the requested order.
     255              : !> \param ri ...
     256              : !> \param rj ...
     257              : !> \param rk ...
     258              : !> \param zeti ...
     259              : !> \param zetj ...
     260              : !> \param zetk ...
     261              : !> \param m_max maximum radial order, including any derivative increment
     262              : !> \param potential_parameter radial operator parameters
     263              : !> \param params reusable primitive parameter cache
     264              : ! **************************************************************************************************
     265     25762487 :    SUBROUTINE prepare_3c_primitive(ri, rj, rk, zeti, zetj, zetk, m_max, potential_parameter, params)
     266              :       REAL(dp), INTENT(IN)                               :: ri(3), rj(3), rk(3), zeti, zetj, zetk
     267              :       INTEGER, INTENT(IN)                                :: m_max
     268              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     269              :       TYPE(eri_primitive_data_type), INTENT(INOUT)       :: params
     270              : 
     271              :       REAL(dp) :: fundamentals_work(prim_data_f_size), gammaq, normalization, prefac, S1234, T
     272              : 
     273     25762487 :       CPASSERT(m_max < prim_data_f_size)
     274              : 
     275              :       ! Libint layout: (k, dummy k | j, i).
     276    103049948 :       params%centers(:, 1) = rk
     277    103049948 :       params%centers(:, 2) = rk
     278    103049948 :       params%centers(:, 3) = rj
     279    103049948 :       params%centers(:, 4) = ri
     280    128812435 :       params%exponents = [zetk, 0.0_dp, zetj, zeti]
     281    103049948 :       params%P = rk
     282              : 
     283     25762487 :       params%prepared_max_order = m_max
     284     25762487 :       gammaq = zeti + zetj
     285     25762487 :       params%ZetaInv = 1._dp/zetk; params%EtaInv = 1._dp/gammaq
     286     25762487 :       params%ZetapEtaInv = 1._dp/(zetk + gammaq)
     287              : 
     288    103049948 :       params%Q = (zeti*ri + zetj*rj)*params%EtaInv
     289    103049948 :       params%W = (zetk*rk + gammaq*params%Q)*params%ZetapEtaInv
     290     25762487 :       params%Rho = zetk*gammaq/(zetk + gammaq)
     291              : 
     292    566774714 :       params%Fm = 0.0_dp
     293     49396307 :       SELECT CASE (potential_parameter%potential_type)
     294              :       CASE (do_potential_coulomb, do_potential_truncated, do_potential_short, do_potential_mix_cl_trunc)
     295     23633820 :          IF (potential_parameter%potential_type == do_potential_truncated .OR. &
     296              :              potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
     297     20590854 :             CPASSERT(get_lmax_init() >= params%prepared_max_order)
     298              :          END IF
     299     94535280 :          T = params%Rho*SUM((params%Q - rk)**2)
     300     94535280 :          S1234 = EXP(-zeti*zetj*params%EtaInv*SUM((rj - ri)**2))
     301              :          CALL compute_r12_fundamentals(params%Fm, normalization, params%prepared_max_order, potential_parameter%potential_type, &
     302              :                                        params%Rho, T, fundamentals_work, &
     303              :                                        omega=potential_parameter%omega, &
     304              :                                        cutoff_radius=potential_parameter%cutoff_radius, &
     305              :                                        scale_coulomb=potential_parameter%scale_coulomb, &
     306              :                                        scale_longrange=potential_parameter%scale_longrange, &
     307     23633820 :                                        scale_gaussian=0.0_dp)
     308     23633820 :          prefac = normalization*SQRT((pi*params%ZetapEtaInv)**3)*S1234
     309    519944040 :          params%Fm = prefac*params%Fm
     310              :       CASE (do_potential_id)
     311              :          S1234 = EXP(-zeti*zetj*params%EtaInv*SUM((rj - ri)**2) &
     312     14900669 :                      - gammaq*zetk*params%ZetapEtaInv*SUM((params%Q - rk)**2))
     313      2128667 :          prefac = SQRT((pi*params%ZetapEtaInv)**3)*S1234
     314              : 
     315     46830674 :          params%Fm(:) = prefac
     316              :       CASE DEFAULT
     317     25762487 :          CPABORT("Requested operator NYI")
     318              :       END SELECT
     319     25762487 :    END SUBROUTINE prepare_3c_primitive
     320              : 
     321              : ! **************************************************************************************************
     322              : !> \brief Computes the derivatives of the 3-center electron repulsion integrals (ab|c) for a given
     323              : !>        set of cartesian gaussian orbitals. Returns x,y,z derivatives for 1st and 2nd center
     324              : !> \param der_abc_1 the derivatives for the 1st center (allocated before hand)
     325              : !> \param der_abc_2 the derivatives for the 2nd center (allocated before hand)
     326              : !> \param la_min ...
     327              : !> \param la_max ...
     328              : !> \param npgfa ...
     329              : !> \param zeta ...
     330              : !> \param rpgfa ...
     331              : !> \param ra ...
     332              : !> \param lb_min ...
     333              : !> \param lb_max ...
     334              : !> \param npgfb ...
     335              : !> \param zetb ...
     336              : !> \param rpgfb ...
     337              : !> \param rb ...
     338              : !> \param lc_min ...
     339              : !> \param lc_max ...
     340              : !> \param npgfc ...
     341              : !> \param zetc ...
     342              : !> \param rpgfc ...
     343              : !> \param rc ...
     344              : !> \param dab ...
     345              : !> \param dac ...
     346              : !> \param dbc ...
     347              : !> \param lib the libint_t object for evaluation (assume that it is initialized outside)
     348              : !> \param potential_parameter the info about the potential
     349              : !> \param der_abc_1_ext the extremal value of der_abc_1, i.e., MAXVAL(ABS(der_abc_1))
     350              : !> \param der_abc_2_ext ...
     351              : !> \note Prior to calling this routine, the cp_libint_t type passed as argument must be initialized,
     352              : !>       the libint library must be static initialized, and in case of truncated Coulomb operator,
     353              : !>       the latter must be initialized too. Note that the derivative wrt to the third center
     354              : !>       can be obtained via translational invariance
     355              : ! **************************************************************************************************
     356       345920 :    SUBROUTINE eri_3center_derivs(der_abc_1, der_abc_2, &
     357       345920 :                                  la_min, la_max, npgfa, zeta, rpgfa, ra, &
     358       345920 :                                  lb_min, lb_max, npgfb, zetb, rpgfb, rb, &
     359       345920 :                                  lc_min, lc_max, npgfc, zetc, rpgfc, rc, &
     360              :                                  dab, dac, dbc, lib, potential_parameter, &
     361              :                                  der_abc_1_ext, der_abc_2_ext)
     362              : 
     363              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(INOUT)     :: der_abc_1, der_abc_2
     364              :       INTEGER, INTENT(IN)                                :: la_min, la_max, npgfa
     365              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zeta, rpgfa
     366              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: ra
     367              :       INTEGER, INTENT(IN)                                :: lb_min, lb_max, npgfb
     368              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetb, rpgfb
     369              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rb
     370              :       INTEGER, INTENT(IN)                                :: lc_min, lc_max, npgfc
     371              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetc, rpgfc
     372              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rc
     373              :       REAL(KIND=dp), INTENT(IN)                          :: dab, dac, dbc
     374              :       TYPE(cp_libint_t), INTENT(INOUT)                   :: lib
     375              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     376              :       REAL(dp), DIMENSION(3), INTENT(OUT), OPTIONAL      :: der_abc_1_ext, der_abc_2_ext
     377              : 
     378              :       INTEGER :: a_mysize(1), a_offset, a_start, b_offset, b_start, c_offset, c_start, i, i_deriv, &
     379              :          ipgf, j, jpgf, k, kpgf, li, lj, lk, ncoa, ncob, ncoc, op, p1, p2, p3
     380              :       INTEGER, DIMENSION(3)                              :: permute_1, permute_2
     381              :       LOGICAL                                            :: do_ext
     382              :       REAL(dp)                                           :: dr_ab, dr_ac, dr_bc, zeti, zetj, zetk
     383              :       REAL(dp), DIMENSION(3)                             :: der_abc_1_ext_prv, der_abc_2_ext_prv
     384       345920 :       REAL(dp), DIMENSION(:, :), POINTER                 :: p_deriv
     385              :       TYPE(eri_primitive_data_type)                      :: params
     386              : 
     387       345920 :       NULLIFY (p_deriv)
     388              : 
     389       345920 :       permute_1 = [4, 5, 6]
     390       345920 :       permute_2 = [7, 8, 9]
     391              : 
     392       345920 :       dr_ab = 0.0_dp
     393       345920 :       dr_bc = 0.0_dp
     394       345920 :       dr_ac = 0.0_dp
     395              : 
     396       345920 :       op = potential_parameter%potential_type
     397              : 
     398              :       IF (op == do_potential_truncated .OR. op == do_potential_short &
     399       226113 :           .OR. op == do_potential_mix_cl_trunc) THEN
     400       119807 :          dr_bc = potential_parameter%cutoff_radius*cutoff_screen_factor
     401       119807 :          dr_ac = potential_parameter%cutoff_radius*cutoff_screen_factor
     402       226113 :       ELSE IF (op == do_potential_coulomb) THEN
     403         9988 :          dr_bc = 1000000.0_dp
     404         9988 :          dr_ac = 1000000.0_dp
     405              :       END IF
     406              : 
     407       345920 :       do_ext = .FALSE.
     408       345920 :       IF (PRESENT(der_abc_1_ext) .OR. PRESENT(der_abc_2_ext)) do_ext = .TRUE.
     409       345920 :       der_abc_1_ext_prv = 0.0_dp
     410       345920 :       der_abc_2_ext_prv = 0.0_dp
     411              : 
     412              :       !Note: we want to compute all possible integrals based on the 3-centers (ab|c) before
     413              :       !      having to switch to (ba|c) (or the other way around) due to angular momenta in libint
     414              :       !      For a triplet of centers (k|ji), we can only compute integrals for which lj >= li
     415              : 
     416              :       !Looping over the pgfs
     417      1189313 :       DO ipgf = 1, npgfa
     418       843393 :          zeti = zeta(ipgf)
     419       843393 :          a_start = (ipgf - 1)*ncoset(la_max)
     420              : 
     421      4761715 :          DO jpgf = 1, npgfb
     422              : 
     423              :             ! screening
     424      3572402 :             IF (rpgfa(ipgf) + rpgfb(jpgf) + dr_ab < dab) CYCLE
     425              : 
     426      1134892 :             zetj = zetb(jpgf)
     427      1134892 :             b_start = (jpgf - 1)*ncoset(lb_max)
     428              : 
     429      8323219 :             DO kpgf = 1, npgfc
     430              : 
     431              :                ! screening
     432      6344934 :                IF (rpgfb(jpgf) + rpgfc(kpgf) + dr_bc < dbc) CYCLE
     433      2667789 :                IF (rpgfa(ipgf) + rpgfc(kpgf) + dr_ac < dac) CYCLE
     434              : 
     435      1872127 :                zetk = zetc(kpgf)
     436      1872127 :                c_start = (kpgf - 1)*ncoset(lc_max)
     437              : 
     438              :                !start with all the (c|ba) integrals (standard order) and keep to lb >= la
     439              :                CALL prepare_3c_primitive(ra, rb, rc, zeti, zetj, zetk, &
     440      1872127 :                                          la_max + lb_max + lc_max + 1, potential_parameter, params)
     441      1872127 :                CALL cp_libint_set_params_eri_deriv(lib, params, [1, 2, 3, 4], params%prepared_max_order)
     442              : 
     443      4310369 :                DO li = la_min, la_max
     444      2438242 :                   a_offset = a_start + ncoset(li - 1)
     445      2438242 :                   ncoa = nco(li)
     446      6913203 :                   DO lj = MAX(li, lb_min), lb_max
     447      2602834 :                      b_offset = b_start + ncoset(lj - 1)
     448      2602834 :                      ncob = nco(lj)
     449      8806530 :                      DO lk = lc_min, lc_max
     450      3765454 :                         c_offset = c_start + ncoset(lk - 1)
     451      3765454 :                         ncoc = nco(lk)
     452              : 
     453      3765454 :                         a_mysize(1) = ncoa*ncob*ncoc
     454              : 
     455      3765454 :                         CALL cp_libint_get_3eri_derivs(li, lj, lk, lib, p_deriv, a_mysize)
     456              : 
     457      3765454 :                         IF (do_ext) THEN
     458     15061816 :                            DO i_deriv = 1, 3
     459     42689449 :                               DO k = 1, ncoc
     460     27627633 :                                  p1 = (k - 1)*ncob
     461     90942462 :                                  DO j = 1, ncob
     462     52018467 :                                     p2 = (p1 + j - 1)*ncoa
     463    158128833 :                                     DO i = 1, ncoa
     464     78482733 :                                        p3 = p2 + i
     465              : 
     466              :                                        der_abc_1(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     467     78482733 :                                           p_deriv(p3, permute_2(i_deriv))
     468              :                                        der_abc_1_ext_prv(i_deriv) = MAX(der_abc_1_ext_prv(i_deriv), &
     469     78482733 :                                                                         ABS(p_deriv(p3, permute_2(i_deriv))))
     470              : 
     471              :                                        der_abc_2(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     472     78482733 :                                           p_deriv(p3, permute_1(i_deriv))
     473              :                                        der_abc_2_ext_prv(i_deriv) = MAX(der_abc_2_ext_prv(i_deriv), &
     474    130501200 :                                                                         ABS(p_deriv(p3, permute_1(i_deriv))))
     475              : 
     476              :                                     END DO
     477              :                                  END DO
     478              :                               END DO
     479              :                            END DO
     480              :                         ELSE
     481            0 :                            DO i_deriv = 1, 3
     482            0 :                               DO k = 1, ncoc
     483            0 :                                  p1 = (k - 1)*ncob
     484            0 :                                  DO j = 1, ncob
     485            0 :                                     p2 = (p1 + j - 1)*ncoa
     486            0 :                                     DO i = 1, ncoa
     487            0 :                                        p3 = p2 + i
     488              : 
     489              :                                        der_abc_1(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     490            0 :                                           p_deriv(p3, permute_2(i_deriv))
     491              : 
     492              :                                        der_abc_2(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     493            0 :                                           p_deriv(p3, permute_1(i_deriv))
     494              :                                     END DO
     495              :                                  END DO
     496              :                               END DO
     497              :                            END DO
     498              :                         END IF
     499              : 
     500      6368288 :                         DEALLOCATE (p_deriv)
     501              :                      END DO !lk
     502              :                   END DO !lj
     503              :                END DO !li
     504              : 
     505              :                !swap centers 3 and 4 to compute (c|ab) with lb < la
     506      1872127 :                CALL cp_libint_set_params_eri_deriv(lib, params, [1, 2, 4, 3], params%prepared_max_order)
     507              : 
     508      7891974 :                DO lj = lb_min, lb_max
     509      2447445 :                   b_offset = b_start + ncoset(lj - 1)
     510      2447445 :                   ncob = nco(lj)
     511      9456389 :                   DO li = MAX(lj + 1, la_min), la_max
     512       664010 :                      a_offset = a_start + ncoset(li - 1)
     513       664010 :                      ncoa = nco(li)
     514      4084604 :                      DO lk = lc_min, lc_max
     515       973149 :                         c_offset = c_start + ncoset(lk - 1)
     516       973149 :                         ncoc = nco(lk)
     517              : 
     518       973149 :                         a_mysize(1) = ncoa*ncob*ncoc
     519       973149 :                         CALL cp_libint_get_3eri_derivs(lj, li, lk, lib, p_deriv, a_mysize)
     520              : 
     521       973149 :                         IF (do_ext) THEN
     522      3892596 :                            DO i_deriv = 1, 3
     523     11259984 :                               DO k = 1, ncoc
     524      7367388 :                                  p1 = (k - 1)*ncoa
     525     34471833 :                                  DO i = 1, ncoa
     526     24184998 :                                     p2 = (p1 + i - 1)*ncob
     527     59225208 :                                     DO j = 1, ncob
     528     27672822 :                                        p3 = p2 + j
     529              : 
     530              :                                        der_abc_1(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     531     27672822 :                                           p_deriv(p3, permute_1(i_deriv))
     532              : 
     533              :                                        der_abc_1_ext_prv(i_deriv) = MAX(der_abc_1_ext_prv(i_deriv), &
     534     27672822 :                                                                         ABS(p_deriv(p3, permute_1(i_deriv))))
     535              : 
     536              :                                        der_abc_2(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     537     27672822 :                                           p_deriv(p3, permute_2(i_deriv))
     538              : 
     539              :                                        der_abc_2_ext_prv(i_deriv) = MAX(der_abc_2_ext_prv(i_deriv), &
     540     51857820 :                                                                         ABS(p_deriv(p3, permute_2(i_deriv))))
     541              :                                     END DO
     542              :                                  END DO
     543              :                               END DO
     544              :                            END DO
     545              :                         ELSE
     546            0 :                            DO i_deriv = 1, 3
     547            0 :                               DO k = 1, ncoc
     548            0 :                                  p1 = (k - 1)*ncoa
     549            0 :                                  DO i = 1, ncoa
     550            0 :                                     p2 = (p1 + i - 1)*ncob
     551            0 :                                     DO j = 1, ncob
     552            0 :                                        p3 = p2 + j
     553              : 
     554              :                                        der_abc_1(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     555            0 :                                           p_deriv(p3, permute_1(i_deriv))
     556              : 
     557              :                                        der_abc_2(a_offset + i, b_offset + j, c_offset + k, i_deriv) = &
     558            0 :                                           p_deriv(p3, permute_2(i_deriv))
     559              :                                     END DO
     560              :                                  END DO
     561              :                               END DO
     562              :                            END DO
     563              :                         END IF
     564              : 
     565      1637159 :                         DEALLOCATE (p_deriv)
     566              :                      END DO !lk
     567              :                   END DO !li
     568              :                END DO !lj
     569              : 
     570              :             END DO !kpgf
     571              :          END DO !jpgf
     572              :       END DO !ipgf
     573              : 
     574       345920 :       IF (PRESENT(der_abc_1_ext)) der_abc_1_ext = der_abc_1_ext_prv
     575       345920 :       IF (PRESENT(der_abc_2_ext)) der_abc_2_ext = der_abc_2_ext_prv
     576              : 
     577     19371520 :    END SUBROUTINE eri_3center_derivs
     578              : 
     579              : ! **************************************************************************************************
     580              : !> \brief Computes the 2-center electron repulsion integrals (a|b) for a given set of cartesian
     581              : !>        gaussian orbitals
     582              : !> \param int_ab the integrals as array of cartesian orbitals (allocated before hand)
     583              : !> \param la_min ...
     584              : !> \param la_max ...
     585              : !> \param npgfa ...
     586              : !> \param zeta ...
     587              : !> \param rpgfa ...
     588              : !> \param ra ...
     589              : !> \param lb_min ...
     590              : !> \param lb_max ...
     591              : !> \param npgfb ...
     592              : !> \param zetb ...
     593              : !> \param rpgfb ...
     594              : !> \param rb ...
     595              : !> \param dab ...
     596              : !> \param lib the libint_t object for evaluation (assume that it is initialized outside)
     597              : !> \param potential_parameter the info about the potential
     598              : !> \note Prior to calling this routine, the cp_libint_t type passed as argument must be initialized,
     599              : !>       the libint library must be static initialized, and in case of truncated Coulomb operator,
     600              : !>       the latter must be initialized too
     601              : ! **************************************************************************************************
     602       596701 :    SUBROUTINE eri_2center(int_ab, la_min, la_max, npgfa, zeta, rpgfa, ra, &
     603       596701 :                           lb_min, lb_max, npgfb, zetb, rpgfb, rb, &
     604              :                           dab, lib, potential_parameter)
     605              : 
     606              :       REAL(dp), DIMENSION(:, :), INTENT(INOUT)           :: int_ab
     607              :       INTEGER, INTENT(IN)                                :: la_min, la_max, npgfa
     608              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zeta, rpgfa
     609              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: ra
     610              :       INTEGER, INTENT(IN)                                :: lb_min, lb_max, npgfb
     611              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetb, rpgfb
     612              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rb
     613              :       REAL(dp), INTENT(IN)                               :: dab
     614              :       TYPE(cp_libint_t), INTENT(INOUT)                   :: lib
     615              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     616              : 
     617              :       INTEGER                                            :: a_mysize(1), a_offset, a_start, &
     618              :                                                             b_offset, b_start, i, ipgf, j, jpgf, &
     619              :                                                             li, lj, ncoa, ncob, p1, p2
     620              :       REAL(dp)                                           :: dr_ab, zeti, zetj
     621       596701 :       REAL(dp), DIMENSION(:), POINTER                    :: p_work
     622              :       TYPE(eri_primitive_data_type)                      :: params
     623              : 
     624       596701 :       NULLIFY (p_work)
     625              : 
     626       596701 :       dr_ab = 0.0_dp
     627              : 
     628              :       IF (potential_parameter%potential_type == do_potential_truncated .OR. &
     629       313423 :           potential_parameter%potential_type == do_potential_short .OR. &
     630              :           potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
     631       295914 :          dr_ab = potential_parameter%cutoff_radius*cutoff_screen_factor
     632       300787 :       ELSE IF (potential_parameter%potential_type == do_potential_coulomb) THEN
     633       124370 :          dr_ab = 1000000.0_dp
     634              :       END IF
     635              : 
     636              :       !Looping over the pgfs
     637      1695576 :       DO ipgf = 1, npgfa
     638      1098875 :          zeti = zeta(ipgf)
     639      1098875 :          a_start = (ipgf - 1)*ncoset(la_max)
     640              : 
     641      6361038 :          DO jpgf = 1, npgfb
     642      4665462 :             zetj = zetb(jpgf)
     643      4665462 :             b_start = (jpgf - 1)*ncoset(lb_max)
     644              : 
     645              :             !screening
     646      4665462 :             IF (rpgfa(ipgf) + rpgfb(jpgf) + dr_ab < dab) CYCLE
     647              : 
     648              :             CALL prepare_2c_primitive(ra, rb, zeti, zetj, la_max + lb_max, &
     649      3049683 :                                       potential_parameter, params)
     650      3049683 :             CALL cp_libint_set_params_eri(lib, params, [1, 2, 3, 4], params%prepared_max_order)
     651              : 
     652      9647647 :             DO li = la_min, la_max
     653      5499089 :                a_offset = a_start + ncoset(li - 1)
     654      5499089 :                ncoa = nco(li)
     655     20869017 :                DO lj = lb_min, lb_max
     656     10704466 :                   b_offset = b_start + ncoset(lj - 1)
     657     10704466 :                   ncob = nco(lj)
     658              : 
     659     10704466 :                   a_mysize(1) = ncoa*ncob
     660     10704466 :                   CALL cp_libint_get_2eris(li, lj, lib, p_work, a_mysize)
     661              : 
     662     48899708 :                   DO j = 1, ncob
     663     32696153 :                      p1 = (j - 1)*ncoa
     664    145169550 :                      DO i = 1, ncoa
     665    101768931 :                         p2 = p1 + i
     666    134465084 :                         int_ab(a_offset + i, b_offset + j) = p_work(p2)
     667              :                      END DO
     668              :                   END DO
     669              : 
     670              :                END DO
     671              :             END DO
     672              : 
     673              :          END DO
     674              :       END DO
     675              : 
     676     33415256 :    END SUBROUTINE eri_2center
     677              : 
     678              : ! **************************************************************************************************
     679              : !> \brief Prepare geometry and radial seeds for 2-center integrals at the requested order.
     680              : !> \param rj ...
     681              : !> \param rk ...
     682              : !> \param zetj ...
     683              : !> \param zetk ...
     684              : !> \param m_max maximum radial order, including any derivative increment
     685              : !> \param potential_parameter radial operator parameters
     686              : !> \param params reusable primitive parameter cache
     687              : ! **************************************************************************************************
     688      5225304 :    SUBROUTINE prepare_2c_primitive(rj, rk, zetj, zetk, m_max, potential_parameter, params)
     689              :       REAL(dp), INTENT(IN)                               :: rj(3), rk(3), zetj, zetk
     690              :       INTEGER, INTENT(IN)                                :: m_max
     691              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     692              :       TYPE(eri_primitive_data_type), INTENT(INOUT)       :: params
     693              : 
     694              :       REAL(dp) :: fundamentals_work(prim_data_f_size), normalization, prefac, T
     695              : 
     696      5225304 :       CPASSERT(m_max < prim_data_f_size)
     697              : 
     698              :       ! Libint layout: (k, dummy k | j, dummy j).
     699     20901216 :       params%centers(:, 1) = rk
     700     20901216 :       params%centers(:, 2) = rk
     701     20901216 :       params%centers(:, 3) = rj
     702     20901216 :       params%centers(:, 4) = rj
     703     26126520 :       params%exponents = [zetk, 0.0_dp, zetj, 0.0_dp]
     704     20901216 :       params%P = rk
     705     20901216 :       params%Q = rj
     706              : 
     707      5225304 :       params%prepared_max_order = m_max
     708      5225304 :       params%ZetaInv = 1._dp/zetk; params%EtaInv = 1._dp/zetj
     709      5225304 :       params%ZetapEtaInv = 1._dp/(zetk + zetj)
     710              : 
     711     20901216 :       params%W = (zetk*rk + zetj*rj)*params%ZetapEtaInv
     712      5225304 :       params%Rho = zetk*zetj/(zetk + zetj)
     713              : 
     714    114956688 :       params%Fm = 0.0_dp
     715     10282162 :       SELECT CASE (potential_parameter%potential_type)
     716              :       CASE (do_potential_coulomb, do_potential_truncated, do_potential_short, do_potential_mix_cl_trunc)
     717      5056858 :          IF (potential_parameter%potential_type == do_potential_truncated .OR. &
     718              :              potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
     719       351319 :             CPASSERT(get_lmax_init() >= params%prepared_max_order)
     720              :          END IF
     721     20227432 :          T = params%Rho*SUM((rj - rk)**2)
     722              :          CALL compute_r12_fundamentals(params%Fm, normalization, params%prepared_max_order, potential_parameter%potential_type, &
     723              :                                        params%Rho, T, fundamentals_work, &
     724              :                                        omega=potential_parameter%omega, &
     725              :                                        cutoff_radius=potential_parameter%cutoff_radius, &
     726              :                                        scale_coulomb=potential_parameter%scale_coulomb, &
     727              :                                        scale_longrange=potential_parameter%scale_longrange, &
     728      5056858 :                                        scale_gaussian=0.0_dp)
     729      5056858 :          prefac = normalization*SQRT((pi*params%ZetapEtaInv)**3)
     730    111250876 :          params%Fm = prefac*params%Fm
     731              :       CASE (do_potential_id)
     732              : 
     733       673784 :          prefac = SQRT((pi*params%ZetapEtaInv)**3)*EXP(-zetj*zetk*params%ZetapEtaInv*SUM((rk - rj)**2))
     734      3705812 :          params%Fm(:) = prefac
     735              :       CASE DEFAULT
     736      5225304 :          CPABORT("Requested operator NYI")
     737              :       END SELECT
     738      5225304 :    END SUBROUTINE prepare_2c_primitive
     739              : 
     740              : !> \brief Computes the 2-center derivatives of the electron repulsion integrals (a|b) for a given
     741              : !>        set of cartesian gaussian orbitals. Returns the derivatives wrt to the first center
     742              : !> \param der_ab the derivatives as array of cartesian orbitals (allocated before hand)
     743              : !> \param la_min ...
     744              : !> \param la_max ...
     745              : !> \param npgfa ...
     746              : !> \param zeta ...
     747              : !> \param rpgfa ...
     748              : !> \param ra ...
     749              : !> \param lb_min ...
     750              : !> \param lb_max ...
     751              : !> \param npgfb ...
     752              : !> \param zetb ...
     753              : !> \param rpgfb ...
     754              : !> \param rb ...
     755              : !> \param dab ...
     756              : !> \param lib the libint_t object for evaluation (assume that it is initialized outside)
     757              : !> \param potential_parameter the info about the potential
     758              : !> \note Prior to calling this routine, the cp_libint_t type passed as argument must be initialized,
     759              : !>       the libint library must be static initialized, and in case of truncated Coulomb operator,
     760              : !>       the latter must be initialized too
     761              : ! **************************************************************************************************
     762       144239 :    SUBROUTINE eri_2center_derivs(der_ab, la_min, la_max, npgfa, zeta, rpgfa, ra, &
     763       144239 :                                  lb_min, lb_max, npgfb, zetb, rpgfb, rb, &
     764              :                                  dab, lib, potential_parameter)
     765              : 
     766              :       REAL(dp), DIMENSION(:, :, :), INTENT(INOUT)        :: der_ab
     767              :       INTEGER, INTENT(IN)                                :: la_min, la_max, npgfa
     768              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zeta, rpgfa
     769              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: ra
     770              :       INTEGER, INTENT(IN)                                :: lb_min, lb_max, npgfb
     771              :       REAL(dp), DIMENSION(:), INTENT(IN)                 :: zetb, rpgfb
     772              :       REAL(dp), DIMENSION(3), INTENT(IN)                 :: rb
     773              :       REAL(dp), INTENT(IN)                               :: dab
     774              :       TYPE(cp_libint_t), INTENT(INOUT)                   :: lib
     775              :       TYPE(coulomb_operator_type), INTENT(IN)            :: potential_parameter
     776              : 
     777              :       INTEGER                                            :: a_mysize(1), a_offset, a_start, &
     778              :                                                             b_offset, b_start, i, i_deriv, ipgf, &
     779              :                                                             j, jpgf, li, lj, ncoa, ncob, p1, p2
     780              :       INTEGER, DIMENSION(3)                              :: permute
     781              :       REAL(dp)                                           :: dr_ab, zeti, zetj
     782       144239 :       REAL(dp), DIMENSION(:, :), POINTER                 :: p_deriv
     783              :       TYPE(eri_primitive_data_type)                      :: params
     784              : 
     785       144239 :       NULLIFY (p_deriv)
     786              : 
     787       144239 :       permute = [4, 5, 6]
     788              : 
     789       144239 :       dr_ab = 0.0_dp
     790              : 
     791              :       IF (potential_parameter%potential_type == do_potential_truncated .OR. &
     792        80471 :           potential_parameter%potential_type == do_potential_short .OR. &
     793              :           potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
     794        64460 :          dr_ab = potential_parameter%cutoff_radius*cutoff_screen_factor
     795        79779 :       ELSE IF (potential_parameter%potential_type == do_potential_coulomb) THEN
     796         9831 :          dr_ab = 1000000.0_dp
     797              :       END IF
     798              : 
     799              :       !Looping over the pgfs
     800       641174 :       DO ipgf = 1, npgfa
     801       496935 :          zeti = zeta(ipgf)
     802       496935 :          a_start = (ipgf - 1)*ncoset(la_max)
     803              : 
     804      3875095 :          DO jpgf = 1, npgfb
     805      3233921 :             zetj = zetb(jpgf)
     806      3233921 :             b_start = (jpgf - 1)*ncoset(lb_max)
     807              : 
     808              :             !screening
     809      3233921 :             IF (rpgfa(ipgf) + rpgfb(jpgf) + dr_ab < dab) CYCLE
     810              : 
     811              :             CALL prepare_2c_primitive(ra, rb, zeti, zetj, la_max + lb_max + 1, &
     812      2175621 :                                       potential_parameter, params)
     813      2175621 :             CALL cp_libint_set_params_eri_deriv(lib, params, [1, 2, 3, 4], params%prepared_max_order)
     814              : 
     815      6321018 :             DO li = la_min, la_max
     816      3648462 :                a_offset = a_start + ncoset(li - 1)
     817      3648462 :                ncoa = nco(li)
     818     13051067 :                DO lj = lb_min, lb_max
     819      6168684 :                   b_offset = b_start + ncoset(lj - 1)
     820      6168684 :                   ncob = nco(lj)
     821              : 
     822      6168684 :                   a_mysize(1) = ncoa*ncob
     823      6168684 :                   CALL cp_libint_get_2eri_derivs(li, lj, lib, p_deriv, a_mysize)
     824              : 
     825     24674736 :                   DO i_deriv = 1, 3
     826     75355947 :                      DO j = 1, ncob
     827     50681211 :                         p1 = (j - 1)*ncoa
     828    208451331 :                         DO i = 1, ncoa
     829    139264068 :                            p2 = p1 + i
     830    189945279 :                            der_ab(a_offset + i, b_offset + j, i_deriv) = p_deriv(p2, permute(i_deriv))
     831              :                         END DO
     832              :                      END DO
     833              :                   END DO
     834              : 
     835      9817146 :                   DEALLOCATE (p_deriv)
     836              :                END DO
     837              :             END DO
     838              : 
     839              :          END DO
     840              :       END DO
     841              : 
     842      8077384 :    END SUBROUTINE eri_2center_derivs
     843              : 
     844              : END MODULE libint_2c_3c
        

Generated by: LCOV version 2.0-1