LCOV - code coverage report
Current view: top level - src - min_basis_set.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:b1f098b) Lines: 99 117 84.6 %
Date: 2024-05-05 06:30:09 Functions: 2 2 100.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief generate or use from input minimal basis set
      10             : !> \par History
      11             : !>      03.2023 created [JGH]
      12             : !> \author JGH
      13             : ! **************************************************************************************************
      14             : MODULE min_basis_set
      15             :    USE basis_set_container_types,       ONLY: add_basis_set_to_container
      16             :    USE basis_set_types,                 ONLY: &
      17             :         allocate_sto_basis_set, create_gto_from_sto_basis, create_primitive_basis_set, &
      18             :         deallocate_gto_basis_set, deallocate_sto_basis_set, get_gto_basis_set, gto_basis_set_type, &
      19             :         init_orb_basis_set, set_sto_basis_set, srules, sto_basis_set_type
      20             :    USE cp_control_types,                ONLY: dft_control_type
      21             :    USE kinds,                           ONLY: default_string_length,&
      22             :                                               dp
      23             :    USE periodic_table,                  ONLY: get_ptable_info,&
      24             :                                               ptable
      25             :    USE qs_environment_types,            ONLY: get_qs_env,&
      26             :                                               qs_environment_type
      27             :    USE qs_interactions,                 ONLY: init_interaction_radii_orb_basis
      28             :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      29             :                                               qs_kind_type
      30             : #include "./base/base_uses.f90"
      31             : 
      32             :    IMPLICIT NONE
      33             :    PRIVATE
      34             : 
      35             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'min_basis_set'
      36             : 
      37             :    PUBLIC ::  create_minbas_set
      38             : 
      39             : ! **************************************************************************************************
      40             : 
      41             : CONTAINS
      42             : 
      43             : ! **************************************************************************************************
      44             : !> \brief ...
      45             : !> \param qs_env ...
      46             : !> \param unit_nr ...
      47             : !> \param basis_type ...
      48             : !> \param primitive ...
      49             : ! **************************************************************************************************
      50          38 :    SUBROUTINE create_minbas_set(qs_env, unit_nr, basis_type, primitive)
      51             :       TYPE(qs_environment_type), POINTER                 :: qs_env
      52             :       INTEGER, INTENT(IN)                                :: unit_nr
      53             :       CHARACTER(LEN=*), INTENT(IN), OPTIONAL             :: basis_type
      54             :       INTEGER, INTENT(IN), OPTIONAL                      :: primitive
      55             : 
      56             :       CHARACTER(LEN=2)                                   :: element_symbol
      57             :       CHARACTER(LEN=default_string_length)               :: bname, btype
      58             :       INTEGER                                            :: ikind, lb, mao, ne, ngau, nkind, nprim, &
      59             :                                                             nsgf, ub, z
      60             :       INTEGER, DIMENSION(0:3)                            :: elcon
      61          38 :       INTEGER, DIMENSION(:), POINTER                     :: econf
      62             :       REAL(KIND=dp)                                      :: zval
      63             :       TYPE(dft_control_type), POINTER                    :: dft_control
      64             :       TYPE(gto_basis_set_type), POINTER                  :: pbasis, refbasis
      65          38 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
      66             :       TYPE(qs_kind_type), POINTER                        :: qs_kind
      67             : 
      68          38 :       IF (PRESENT(basis_type)) THEN
      69           4 :          btype = TRIM(basis_type)
      70             :       ELSE
      71          34 :          btype = "MIN"
      72             :       END IF
      73          38 :       IF (PRESENT(primitive)) THEN
      74           4 :          nprim = primitive
      75             :       ELSE
      76             :          nprim = -1
      77             :       END IF
      78             : 
      79             :       ! check for or generate reference basis
      80          38 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
      81          38 :       CALL get_qs_env(qs_env, dft_control=dft_control)
      82          38 :       nkind = SIZE(qs_kind_set)
      83         116 :       DO ikind = 1, nkind
      84          78 :          qs_kind => qs_kind_set(ikind)
      85          78 :          CALL get_qs_kind(qs_kind, zeff=zval, elec_conf=econf, element_symbol=element_symbol)
      86          78 :          CALL get_ptable_info(element_symbol, ielement=z)
      87          78 :          NULLIFY (refbasis, pbasis)
      88          78 :          CALL get_qs_kind(qs_kind=qs_kind, basis_set=refbasis, basis_type=btype)
      89          78 :          IF (.NOT. ASSOCIATED(refbasis)) THEN
      90          74 :             CALL get_qs_kind(qs_kind=qs_kind, mao=mao)
      91             :             ! generate a minimal basis set
      92          74 :             elcon = 0
      93          74 :             lb = LBOUND(econf, 1)
      94          74 :             ub = UBOUND(econf, 1)
      95          74 :             ne = ub - lb
      96         202 :             elcon(0:ne) = econf(lb:ub)
      97          74 :             IF (nprim > 0) THEN
      98           4 :                ngau = nprim
      99           4 :                CALL create_min_basis(refbasis, z, elcon, mao, ngau)
     100           4 :                CALL create_primitive_basis_set(refbasis, pbasis)
     101           4 :                CALL init_interaction_radii_orb_basis(pbasis, dft_control%qs_control%eps_pgf_orb)
     102           4 :                CALL add_basis_set_to_container(qs_kind%basis_sets, pbasis, btype)
     103           4 :                CALL deallocate_gto_basis_set(refbasis)
     104             :             ELSE
     105             :                ! STO-3G
     106          70 :                ngau = 3
     107          70 :                CALL create_min_basis(refbasis, z, elcon, mao, ngau)
     108          70 :                CALL init_interaction_radii_orb_basis(refbasis, dft_control%qs_control%eps_pgf_orb)
     109          70 :                CALL add_basis_set_to_container(qs_kind%basis_sets, refbasis, btype)
     110             :             END IF
     111          74 :             CALL get_qs_kind(qs_kind=qs_kind, basis_set=refbasis, basis_type=btype)
     112             :          END IF
     113         194 :          IF (unit_nr > 0) THEN
     114          39 :             CALL get_gto_basis_set(refbasis, name=bname, nsgf=nsgf)
     115          39 :             WRITE (unit_nr, '(T2,A,A,T14,A,I4,T40,A,A24)') "Kind: ", element_symbol, "NBasFun: ", nsgf, &
     116          78 :                "Reference Basis: ", ADJUSTL(TRIM(bname))
     117             :          END IF
     118             :       END DO
     119             : 
     120          38 :    END SUBROUTINE create_minbas_set
     121             : 
     122             : ! **************************************************************************************************
     123             : !> \brief Creates a minimal basis set based on Slater rules
     124             : !> \param min_basis_set ...
     125             : !> \param zval ...
     126             : !> \param econf ...
     127             : !> \param mao ...
     128             : !> \param ngau ...
     129             : !> \par History
     130             : !>      03.2023 created [JGH]
     131             : ! **************************************************************************************************
     132          74 :    SUBROUTINE create_min_basis(min_basis_set, zval, econf, mao, ngau)
     133             :       TYPE(gto_basis_set_type), POINTER                  :: min_basis_set
     134             :       INTEGER, INTENT(IN)                                :: zval
     135             :       INTEGER, DIMENSION(0:3)                            :: econf
     136             :       INTEGER, INTENT(IN)                                :: mao, ngau
     137             : 
     138             :       CHARACTER(len=1), DIMENSION(0:3), PARAMETER        :: lnam = (/"S", "P", "D", "F"/)
     139             : 
     140             :       CHARACTER(len=6)                                   :: str
     141          74 :       CHARACTER(len=6), DIMENSION(:), POINTER            :: sym
     142             :       CHARACTER(LEN=default_string_length)               :: bname
     143             :       INTEGER                                            :: i, iss, l, lm, n, nmao, nn, nss
     144             :       INTEGER, DIMENSION(0:3)                            :: nae, nco, npe
     145             :       INTEGER, DIMENSION(4, 7)                           :: ne
     146          74 :       INTEGER, DIMENSION(:), POINTER                     :: lq, nq
     147          74 :       REAL(KIND=dp), DIMENSION(:), POINTER               :: zet
     148             :       TYPE(sto_basis_set_type), POINTER                  :: sto_basis_set
     149             : 
     150           0 :       CPASSERT(.NOT. ASSOCIATED(min_basis_set))
     151          74 :       NULLIFY (sto_basis_set)
     152             : 
     153             :       ! electronic configuration
     154          74 :       ne = 0
     155         370 :       DO l = 1, 4
     156         296 :          nn = 2*(l - 1) + 1
     157        1998 :          DO i = l, 7
     158        1628 :             ne(l, i) = ptable(zval)%e_conv(l - 1) - 2*nn*(i - l)
     159        1628 :             ne(l, i) = MAX(ne(l, i), 0)
     160        1924 :             ne(l, i) = MIN(ne(l, i), 2*nn)
     161             :          END DO
     162             :       END DO
     163             :       ! STO definition
     164          74 :       nae = 0
     165          74 :       npe = 0
     166         370 :       DO l = 0, 3
     167         296 :          nn = 2*(2*l + 1)
     168         296 :          nae(l) = ptable(zval)%e_conv(l)/nn
     169         296 :          IF (MOD(ptable(zval)%e_conv(l), nn) /= 0) nae(l) = nae(l) + 1
     170         296 :          npe(l) = econf(l)/nn
     171         370 :          IF (MOD(econf(l), nn) /= 0) npe(l) = npe(l) + 1
     172             :       END DO
     173         370 :       CPASSERT(ALL(nae - npe >= 0))
     174         370 :       nco = nae - npe
     175             :       ! MAO count
     176             :       nmao = 0
     177         370 :       DO l = 0, 3
     178         370 :          nmao = nmao + npe(l)*(2*l + 1)
     179             :       END DO
     180             : 
     181          74 :       IF (mao > nmao) THEN
     182           2 :          nmao = mao - nmao
     183           2 :          SELECT CASE (nmao)
     184             :          CASE (1)
     185           2 :             npe(0) = npe(0) + 1
     186             :          CASE (2)
     187           0 :             npe(0) = npe(0) + 2
     188             :          CASE (3)
     189           0 :             npe(1) = npe(1) + 1
     190             :          CASE (4)
     191           0 :             npe(0) = npe(0) + 1
     192           0 :             npe(1) = npe(1) + 1
     193             :          CASE (5)
     194           0 :             IF (npe(2) == 0) THEN
     195           0 :                npe(2) = npe(2) + 1
     196             :             ELSE
     197           0 :                npe(0) = npe(0) + 2
     198           0 :                npe(1) = npe(1) + 1
     199             :             END IF
     200             :          CASE (6)
     201           0 :             npe(0) = npe(0) + 1
     202           0 :             npe(2) = npe(2) + 1
     203             :          CASE (7)
     204           0 :             npe(0) = npe(0) + 2
     205           0 :             npe(2) = npe(2) + 1
     206             :          CASE (8)
     207           0 :             npe(0) = npe(0) + 3
     208           0 :             npe(2) = npe(2) + 1
     209             :          CASE (9)
     210           0 :             npe(0) = npe(0) + 1
     211           0 :             npe(1) = npe(1) + 1
     212           0 :             npe(2) = npe(2) + 1
     213             :          CASE DEFAULT
     214           2 :             CPABORT("Default setting of minimal basis failed")
     215             :          END SELECT
     216           2 :          CALL cp_warn(__LOCATION__, "Reference basis has been adjusted according to MAO value.")
     217             :       END IF
     218             : 
     219             :       ! All shells should have at least 1 function
     220          74 :       lm = 0
     221         370 :       DO l = 0, 3
     222         370 :          IF (npe(l) > 0) lm = l
     223             :       END DO
     224         188 :       DO l = 0, lm
     225         188 :          IF (npe(l) == 0) npe(l) = 1
     226             :       END DO
     227             : 
     228         370 :       nss = SUM(npe)
     229         592 :       ALLOCATE (sym(nss), lq(nss), nq(nss), zet(nss))
     230          74 :       iss = 0
     231         370 :       DO l = 0, 3
     232         492 :          DO i = 1, npe(l)
     233         122 :             iss = iss + 1
     234         122 :             lq(iss) = l
     235         122 :             n = nco(l) + l
     236         122 :             nq(iss) = n + i
     237         122 :             str = "      "
     238         122 :             WRITE (str(5:5), FMT='(I1)') nq(iss)
     239         122 :             str(6:6) = lnam(l)
     240         122 :             sym(iss) = str
     241         418 :             zet(iss) = srules(zval, ne, nq(iss), lq(iss))
     242             :          END DO
     243             :       END DO
     244             : 
     245          74 :       bname = ADJUSTR(ptable(zval)%symbol)//"_MBas"
     246          74 :       CALL allocate_sto_basis_set(sto_basis_set)
     247             :       CALL set_sto_basis_set(sto_basis_set, name=bname, nshell=nss, nq=nq, &
     248          74 :                              lq=lq, zet=zet, symbol=sym)
     249          74 :       CALL create_gto_from_sto_basis(sto_basis_set, min_basis_set, ngau)
     250          74 :       min_basis_set%norm_type = 2
     251          74 :       CALL init_orb_basis_set(min_basis_set)
     252          74 :       CALL deallocate_sto_basis_set(sto_basis_set)
     253             : 
     254          74 :       DEALLOCATE (sym, lq, nq, zet)
     255             : 
     256          74 :    END SUBROUTINE create_min_basis
     257             : 
     258             : ! **************************************************************************************************
     259             : 
     260             : END MODULE min_basis_set

Generated by: LCOV version 1.15