LCOV - code coverage report
Current view: top level - src - atom_grb.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:92574dc) Lines: 98.2 % 703 690
Test Date: 2026-09-24 01:27:39 Functions: 100.0 % 9 9

            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              : MODULE atom_grb
       9              :    USE ai_onecenter,                    ONLY: sg_conf,&
      10              :                                               sg_kinetic,&
      11              :                                               sg_nuclear,&
      12              :                                               sg_overlap
      13              :    USE atom_electronic_structure,       ONLY: calculate_atom
      14              :    USE atom_operators,                  ONLY: atom_int_release,&
      15              :                                               atom_int_setup,&
      16              :                                               atom_ppint_release,&
      17              :                                               atom_ppint_setup,&
      18              :                                               atom_relint_release,&
      19              :                                               atom_relint_setup
      20              :    USE atom_types,                      ONLY: &
      21              :         CGTO_BASIS, GTO_BASIS, atom_basis_type, atom_integrals, atom_orbitals, atom_p_type, &
      22              :         atom_potential_type, atom_state, atom_type, create_atom_orbs, create_atom_type, lmat, &
      23              :         release_atom_basis, release_atom_type, set_atom
      24              :    USE atom_utils,                      ONLY: atom_basis_condnum,&
      25              :                                               atom_density
      26              :    USE cp_files,                        ONLY: close_file,&
      27              :                                               open_file
      28              :    USE input_constants,                 ONLY: barrier_conf,&
      29              :                                               do_analytic,&
      30              :                                               do_rhf_atom,&
      31              :                                               do_rks_atom,&
      32              :                                               do_rohf_atom,&
      33              :                                               do_uhf_atom,&
      34              :                                               do_uks_atom
      35              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      36              :                                               section_vals_type,&
      37              :                                               section_vals_val_get
      38              :    USE kinds,                           ONLY: default_string_length,&
      39              :                                               dp
      40              :    USE mathconstants,                   ONLY: dfac,&
      41              :                                               rootpi
      42              :    USE orbital_pointers,                ONLY: deallocate_orbital_pointers,&
      43              :                                               init_orbital_pointers
      44              :    USE orbital_transformation_matrices, ONLY: deallocate_spherical_harmonics,&
      45              :                                               init_spherical_harmonics
      46              :    USE periodic_table,                  ONLY: ptable
      47              :    USE physcon,                         ONLY: bohr
      48              :    USE powell,                          ONLY: opt_state_type,&
      49              :                                               powell_optimize
      50              :    USE qs_grid_atom,                    ONLY: allocate_grid_atom,&
      51              :                                               create_grid_atom
      52              : #include "./base/base_uses.f90"
      53              : 
      54              :    IMPLICIT NONE
      55              : 
      56              :    TYPE basis_p_type
      57              :       TYPE(atom_basis_type), POINTER                :: basis => NULL()
      58              :    END TYPE basis_p_type
      59              : 
      60              :    PRIVATE
      61              :    PUBLIC  :: atom_grb_construction
      62              : 
      63              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom_grb'
      64              : 
      65              : CONTAINS
      66              : 
      67              : ! **************************************************************************************************
      68              : !> \brief Construct geometrical response basis set.
      69              : !> \param atom_info    information about the atomic kind. Two-dimensional array of size
      70              : !>                     (electronic-configuration, electronic-structure-method)
      71              : !> \param atom_section ATOM input section
      72              : !> \param iw           output file unit
      73              : !> \par History
      74              : !>    * 11.2016 created [Juerg Hutter]
      75              : ! **************************************************************************************************
      76            2 :    SUBROUTINE atom_grb_construction(atom_info, atom_section, iw)
      77              : 
      78              :       TYPE(atom_p_type), DIMENSION(:, :), POINTER        :: atom_info
      79              :       TYPE(section_vals_type), POINTER                   :: atom_section
      80              :       INTEGER, INTENT(IN)                                :: iw
      81              : 
      82              :       REAL(KIND=dp), PARAMETER                           :: error_threshold = 1.0E-12_dp
      83              : 
      84              :       CHARACTER(len=default_string_length)               :: abas, basname
      85              :       CHARACTER(len=default_string_length), DIMENSION(1) :: basline
      86              :       CHARACTER(len=default_string_length), DIMENSION(3) :: headline
      87              :       INTEGER                                            :: i, ider, is, iunit, j, k, l, lhomo, ll, &
      88              :                                                             lval, m, maxl, mb, method, mo, n, &
      89              :                                                             nder, ngp, nhomo, nr, num_gto, &
      90              :                                                             num_pol, quadtype, s1, s2
      91              :       INTEGER, DIMENSION(0:7)                            :: nbas
      92              :       INTEGER, DIMENSION(0:lmat)                         :: next_bas, next_prim
      93            2 :       INTEGER, DIMENSION(:), POINTER                     :: num_bas
      94              :       REAL(KIND=dp) :: al, amin, aval, cnum, crad, cradx, cval, delta, dene, ear, emax, &
      95              :          energy_ex(0:lmat), energy_ref, energy_vb(0:lmat), expzet, fhomo, o, prefac, rconf, rk, &
      96              :          rmax, scon, zeta, zval
      97            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ale, alp, rho
      98            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: amat
      99            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: ebasis, pbasis, qbasis, rbasis
     100            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :)  :: wfn
     101            2 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: ovlp
     102              :       TYPE(atom_basis_type), POINTER                     :: basis, basis_grb, basis_ref, basis_vrb
     103              :       TYPE(atom_integrals), POINTER                      :: atint
     104              :       TYPE(atom_orbitals), POINTER                       :: orbitals
     105              :       TYPE(atom_state), POINTER                          :: state
     106              :       TYPE(atom_type), POINTER                           :: atom, atom_ref, atom_test
     107           24 :       TYPE(basis_p_type), DIMENSION(0:10)                :: vbasis
     108              :       TYPE(section_vals_type), POINTER                   :: grb_section, powell_section
     109              : 
     110            2 :       IF (iw > 0) WRITE (iw, '(/," ",79("*"),/,T28,A,/," ",79("*"))') "GEOMETRICAL RESPONSE BASIS"
     111              : 
     112           24 :       DO i = 0, 10
     113           24 :          NULLIFY (vbasis(i)%basis)
     114              :       END DO
     115              :       ! make some basic checks
     116            6 :       is = SIZE(atom_info)
     117            2 :       IF (iw > 0 .AND. is > 1) THEN
     118            0 :          WRITE (iw, '(/,A,/)') " WARNING: Only use first electronic structure/method for basis set generation"
     119              :       END IF
     120            2 :       atom_ref => atom_info(1, 1)%atom
     121              : 
     122              :       ! check method
     123            2 :       method = atom_ref%method_type
     124            0 :       SELECT CASE (method)
     125              :       CASE (do_rks_atom, do_rhf_atom)
     126              :          ! restricted methods are okay
     127              :       CASE (do_uks_atom, do_uhf_atom, do_rohf_atom)
     128            0 :          CPABORT("Unrestricted methods not allowed for GRB generation")
     129              :       CASE DEFAULT
     130            2 :          CPABORT("Unknown method for GRB generation")
     131              :       END SELECT
     132              : 
     133              :       ! input for basis optimization
     134            2 :       grb_section => section_vals_get_subs_vals(atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS")
     135              : 
     136              :       ! generate an atom type
     137            2 :       NULLIFY (atom)
     138            2 :       CALL create_atom_type(atom)
     139            2 :       CALL copy_atom_basics(atom_ref, atom, state=.TRUE., potential=.TRUE., optimization=.TRUE., xc=.TRUE.)
     140              :       ! set confinement potential
     141            2 :       atom%potential%confinement = .TRUE.
     142            2 :       atom%potential%conf_type = barrier_conf
     143            2 :       atom%potential%acon = 200._dp
     144            2 :       atom%potential%rcon = 4._dp
     145            2 :       CALL section_vals_val_get(grb_section, "CONFINEMENT", r_val=scon)
     146            2 :       atom%potential%scon = scon
     147              :       ! generate main block geometrical exponents
     148            2 :       basis_ref => atom_ref%basis
     149           38 :       ALLOCATE (basis)
     150              :       NULLIFY (basis%am, basis%cm, basis%as, basis%ns, basis%bf, basis%dbf, basis%ddbf)
     151              :       ! get information on quadrature type and number of grid points
     152              :       ! allocate and initialize the atomic grid
     153              :       NULLIFY (basis%grid)
     154            2 :       CALL allocate_grid_atom(basis%grid)
     155            2 :       CALL section_vals_val_get(grb_section, "QUADRATURE", i_val=quadtype)
     156            2 :       CALL section_vals_val_get(grb_section, "GRID_POINTS", i_val=ngp)
     157            2 :       IF (ngp <= 0) THEN
     158            0 :          CPABORT("# point radial grid < 0")
     159              :       END IF
     160            2 :       CALL create_grid_atom(basis%grid, ngp, 1, 1, 0, quadtype)
     161            2 :       basis%grid%nr = ngp
     162              :       !
     163            2 :       maxl = atom%state%maxl_occ
     164            2 :       basis%basis_type = GTO_BASIS
     165            2 :       CALL section_vals_val_get(grb_section, "NUM_GTO_CORE", i_val=num_gto)
     166           14 :       basis%nbas = 0
     167            6 :       basis%nbas(0:maxl) = num_gto
     168           14 :       basis%nprim = basis%nbas
     169            2 :       CALL section_vals_val_get(grb_section, "GEOMETRICAL_FACTOR", r_val=cval)
     170            2 :       CALL section_vals_val_get(grb_section, "GEO_START_VALUE", r_val=aval)
     171           14 :       m = MAXVAL(basis%nbas)
     172            6 :       ALLOCATE (basis%am(m, 0:lmat))
     173           86 :       basis%am = 0._dp
     174           14 :       DO l = 0, lmat
     175           38 :          DO i = 1, basis%nbas(l)
     176           24 :             ll = i - 1
     177           36 :             basis%am(i, l) = aval*cval**(ll)
     178              :          END DO
     179              :       END DO
     180              : 
     181            2 :       basis%eps_eig = basis_ref%eps_eig
     182            2 :       basis%geometrical = .TRUE.
     183            2 :       basis%aval = aval
     184            2 :       basis%cval = cval
     185           14 :       basis%start = 0
     186              : 
     187              :       ! initialize basis function on a radial grid
     188            2 :       nr = basis%grid%nr
     189           14 :       m = MAXVAL(basis%nbas)
     190           10 :       ALLOCATE (basis%bf(nr, m, 0:lmat))
     191            6 :       ALLOCATE (basis%dbf(nr, m, 0:lmat))
     192            6 :       ALLOCATE (basis%ddbf(nr, m, 0:lmat))
     193        28886 :       basis%bf = 0._dp
     194        28886 :       basis%dbf = 0._dp
     195        28886 :       basis%ddbf = 0._dp
     196           14 :       DO l = 0, lmat
     197           38 :          DO i = 1, basis%nbas(l)
     198           24 :             al = basis%am(i, l)
     199         9636 :             DO k = 1, nr
     200         9600 :                rk = basis%grid%rad(k)
     201         9600 :                ear = EXP(-al*basis%grid%rad(k)**2)
     202         9600 :                basis%bf(k, i, l) = rk**l*ear
     203         9600 :                basis%dbf(k, i, l) = (REAL(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
     204              :                basis%ddbf(k, i, l) = (REAL(l*(l - 1), dp)*rk**(l - 2) - &
     205         9624 :                                       2._dp*al*REAL(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
     206              :             END DO
     207              :          END DO
     208              :       END DO
     209              : 
     210            2 :       NULLIFY (orbitals)
     211           14 :       mo = MAXVAL(atom%state%maxn_calc)
     212           14 :       mb = MAXVAL(basis%nbas)
     213            2 :       CALL create_atom_orbs(orbitals, mb, mo)
     214            2 :       CALL set_atom(atom, orbitals=orbitals)
     215              : 
     216            2 :       powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
     217            2 :       CALL atom_fit_grb(atom, basis, iw, powell_section)
     218            2 :       CALL set_atom(atom, basis=basis)
     219              : 
     220              :       ! generate response contractions
     221            2 :       CALL section_vals_val_get(grb_section, "DELTA_CHARGE", r_val=delta)
     222            2 :       CALL section_vals_val_get(grb_section, "DERIVATIVES", i_val=nder)
     223            2 :       IF (iw > 0) THEN
     224            2 :          WRITE (iw, '(/,A,T76,I5)') " Generate Response Basis Sets with Order ", nder
     225              :       END IF
     226              : 
     227            2 :       state => atom%state
     228              :       ! find HOMO
     229            2 :       lhomo = -1
     230            2 :       nhomo = -1
     231            2 :       emax = -HUGE(1._dp)
     232            6 :       DO l = 0, state%maxl_occ
     233           10 :          DO i = 1, state%maxn_occ(l)
     234            8 :             IF (atom%orbitals%ener(i, l) > emax) THEN
     235            4 :                lhomo = l
     236            4 :                nhomo = i
     237            4 :                emax = atom%orbitals%ener(i, l)
     238            4 :                fhomo = state%occupation(l, i)
     239              :             END IF
     240              :          END DO
     241              :       END DO
     242              : 
     243            2 :       s1 = SIZE(atom%orbitals%wfn, 1)
     244            2 :       s2 = SIZE(atom%orbitals%wfn, 2)
     245           12 :       ALLOCATE (wfn(s1, s2, 0:lmat, -nder:nder))
     246           14 :       s2 = MAXVAL(state%maxn_occ) + nder
     247           14 :       ALLOCATE (rbasis(s1, s2, 0:lmat), qbasis(s1, s2, 0:lmat))
     248            2 :       rbasis = 0._dp
     249            2 :       qbasis = 0._dp
     250              : 
     251              :       ! calculate integrals
     252          426 :       ALLOCATE (atint)
     253            2 :       CALL atom_int_setup(atint, basis, potential=atom%potential, eri_coulomb=.FALSE., eri_exchange=.FALSE.)
     254            2 :       CALL atom_ppint_setup(atint, basis, potential=atom%potential)
     255            2 :       IF (atom%pp_calc) THEN
     256            2 :          NULLIFY (atint%tzora, atint%hdkh)
     257              :       ELSE
     258              :          ! relativistic correction terms
     259            0 :          CALL atom_relint_setup(atint, basis, atom%relativistic, zcore=REAL(atom%z, dp))
     260              :       END IF
     261            2 :       CALL set_atom(atom, integrals=atint)
     262              : 
     263            2 :       CALL calculate_atom(atom, iw=0)
     264           16 :       DO ider = -nder, nder
     265           14 :          dene = REAL(ider, KIND=dp)*delta
     266           14 :          CPASSERT(fhomo > ABS(dene))
     267           14 :          state%occupation(lhomo, nhomo) = fhomo + dene
     268           14 :          CALL calculate_atom(atom, iw=0, noguess=.TRUE.)
     269          686 :          wfn(:, :, :, ider) = atom%orbitals%wfn
     270           16 :          state%occupation(lhomo, nhomo) = fhomo
     271              :       END DO
     272            2 :       IF (iw > 0) THEN
     273            2 :          WRITE (iw, '(A,T76,I5)') " Total number of electronic structure calculations ", 2*nder + 1
     274              :       END IF
     275              : 
     276            2 :       ovlp => atom%integrals%ovlp
     277              : 
     278            6 :       DO l = 0, state%maxl_occ
     279            4 :          IF (iw > 0) THEN
     280            4 :             WRITE (iw, '(A,T76,I5)') " Response derivatives for l quantum number ", l
     281              :          END IF
     282              :          ! occupied states
     283            8 :          DO i = 1, MAX(state%maxn_occ(l), 1)
     284           32 :             rbasis(:, i, l) = wfn(:, i, l, 0)
     285              :          END DO
     286              :          ! differentiation
     287           16 :          DO ider = 1, nder
     288           12 :             i = MAX(state%maxn_occ(l), 1)
     289            4 :             SELECT CASE (ider)
     290              :             CASE (1)
     291           28 :                rbasis(:, i + 1, l) = 0.5_dp*(wfn(:, i, l, 1) - wfn(:, i, l, -1))/delta
     292              :             CASE (2)
     293           28 :                rbasis(:, i + 2, l) = 0.25_dp*(wfn(:, i, l, 2) - 2._dp*wfn(:, i, l, 0) + wfn(:, i, l, -2))/delta**2
     294              :             CASE (3)
     295              :                rbasis(:, i + 3, l) = 0.125_dp*(wfn(:, i, l, 3) - 3._dp*wfn(:, i, l, 1) &
     296           28 :                                                + 3._dp*wfn(:, i, l, -1) - wfn(:, i, l, -3))/delta**3
     297              :             CASE DEFAULT
     298           12 :                CPABORT("Only 1, 2, 3 are supported as the number of response derivatives")
     299              :             END SELECT
     300              :          END DO
     301              : 
     302              :          ! orthogonalization, use gram-schmidt in order to keep the natural order (semi-core, valence, response) of the wfn.
     303            4 :          n = state%maxn_occ(l) + nder
     304            4 :          m = atom%basis%nbas(l)
     305           20 :          DO i = 1, n
     306           40 :             DO j = 1, i - 1
     307         2136 :                o = DOT_PRODUCT(rbasis(1:m, j, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), [m]))
     308          184 :                rbasis(1:m, i, l) = rbasis(1:m, i, l) - o*rbasis(1:m, j, l)
     309              :             END DO
     310         1424 :             o = DOT_PRODUCT(rbasis(1:m, i, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), [m]))
     311          116 :             rbasis(1:m, i, l) = rbasis(1:m, i, l)/SQRT(o)
     312              :          END DO
     313              : 
     314              :          ! check
     315           16 :          ALLOCATE (amat(n, n))
     316         2208 :          amat(1:n, 1:n) = MATMUL(TRANSPOSE(rbasis(1:m, 1:n, l)), MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, 1:n, l)))
     317           20 :          DO i = 1, n
     318           20 :             amat(i, i) = amat(i, i) - 1._dp
     319              :          END DO
     320           84 :          IF (MAXVAL(ABS(amat)) > error_threshold) THEN
     321            0 :             IF (iw > 0) WRITE (iw, '(A,G20.10)') " Orthogonality error  ", MAXVAL(ABS(amat))
     322              :          END IF
     323            4 :          DEALLOCATE (amat)
     324              : 
     325              :          ! Quickstep normalization
     326            4 :          expzet = 0.25_dp*REAL(2*l + 3, dp)
     327            4 :          prefac = SQRT(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
     328           30 :          DO i = 1, m
     329           24 :             zeta = (2._dp*atom%basis%am(i, l))**expzet
     330          124 :             qbasis(i, 1:n, l) = rbasis(i, 1:n, l)*prefac/zeta
     331              :          END DO
     332              : 
     333              :       END DO
     334              : 
     335              :       ! check for condition numbers
     336            2 :       IF (iw > 0) WRITE (iw, '(/,A)') " Condition Number of Valence Response Basis Sets"
     337            2 :       CALL init_orbital_pointers(lmat)
     338            2 :       CALL init_spherical_harmonics(lmat, 0)
     339           10 :       DO ider = 0, nder
     340            8 :          NULLIFY (basis_vrb)
     341          152 :          ALLOCATE (basis_vrb)
     342              :          NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
     343              :                   basis_vrb%dbf, basis_vrb%ddbf)
     344              :          ! allocate and initialize the atomic grid
     345              :          NULLIFY (basis_vrb%grid)
     346            8 :          CALL allocate_grid_atom(basis_vrb%grid)
     347            8 :          CALL create_grid_atom(basis_vrb%grid, ngp, 1, 1, 0, quadtype)
     348            8 :          basis_vrb%grid%nr = ngp
     349              :          !
     350            8 :          basis_vrb%eps_eig = basis_ref%eps_eig
     351            8 :          basis_vrb%geometrical = .FALSE.
     352            8 :          basis_vrb%basis_type = CGTO_BASIS
     353          104 :          basis_vrb%nprim = basis%nprim
     354           56 :          basis_vrb%nbas = 0
     355           24 :          DO l = 0, state%maxl_occ
     356           24 :             basis_vrb%nbas(l) = state%maxn_occ(l) + ider
     357              :          END DO
     358           56 :          m = MAXVAL(basis_vrb%nprim)
     359           56 :          n = MAXVAL(basis_vrb%nbas)
     360           24 :          ALLOCATE (basis_vrb%am(m, 0:lmat))
     361          680 :          basis_vrb%am = basis%am
     362              :          ! contractions
     363           40 :          ALLOCATE (basis_vrb%cm(m, n, 0:lmat))
     364           24 :          DO l = 0, state%maxl_occ
     365           16 :             m = basis_vrb%nprim(l)
     366           16 :             n = basis_vrb%nbas(l)
     367          304 :             basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
     368              :          END DO
     369              : 
     370              :          ! initialize basis function on a radial grid
     371            8 :          nr = basis_vrb%grid%nr
     372           56 :          m = MAXVAL(basis_vrb%nbas)
     373           40 :          ALLOCATE (basis_vrb%bf(nr, m, 0:lmat))
     374           24 :          ALLOCATE (basis_vrb%dbf(nr, m, 0:lmat))
     375           24 :          ALLOCATE (basis_vrb%ddbf(nr, m, 0:lmat))
     376        48176 :          basis_vrb%bf = 0._dp
     377        48176 :          basis_vrb%dbf = 0._dp
     378        48176 :          basis_vrb%ddbf = 0._dp
     379           56 :          DO l = 0, lmat
     380          152 :             DO i = 1, basis_vrb%nprim(l)
     381           96 :                al = basis_vrb%am(i, l)
     382        38544 :                DO k = 1, nr
     383        38400 :                   rk = basis_vrb%grid%rad(k)
     384        38400 :                   ear = EXP(-al*basis_vrb%grid%rad(k)**2)
     385       134496 :                   DO j = 1, basis_vrb%nbas(l)
     386        96000 :                      basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
     387              :                      basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
     388        96000 :                                               + (REAL(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
     389              :                      basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
     390              :                                                (REAL(l*(l - 1), dp)*rk**(l - 2) - 2._dp*al*REAL(2*l + 1, dp)*rk**(l) + &
     391       134400 :                                                 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
     392              :                   END DO
     393              :                END DO
     394              :             END DO
     395              :          END DO
     396              : 
     397            8 :          IF (iw > 0) THEN
     398            8 :             CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
     399            8 :             WRITE (iw, '(A,A)') " Basis set     ", TRIM(abas)
     400              :          END IF
     401            8 :          crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
     402            8 :          cradx = crad*1.00_dp
     403            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     404            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     405            8 :          cradx = crad*1.10_dp
     406            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     407            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     408            8 :          cradx = crad*1.20_dp
     409            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     410            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     411           34 :          vbasis(ider)%basis => basis_vrb
     412              :       END DO
     413            2 :       CALL deallocate_orbital_pointers
     414            2 :       CALL deallocate_spherical_harmonics
     415              : 
     416              :       ! get density maximum
     417            6 :       ALLOCATE (rho(basis%grid%nr))
     418            2 :       CALL calculate_atom(atom, iw=0, noguess=.TRUE.)
     419            2 :       CALL atom_density(rho(:), atom%orbitals%pmat, atom%basis, maxl, typ="RHO")
     420          804 :       n = SUM(MAXLOC(rho(:)))
     421            2 :       rmax = basis%grid%rad(n)
     422            2 :       IF (rmax < 0.1_dp) rmax = 1.0_dp
     423            2 :       DEALLOCATE (rho)
     424              : 
     425              :       ! generate polarization sets
     426            2 :       maxl = atom%state%maxl_occ
     427            2 :       CALL section_vals_val_get(grb_section, "NUM_GTO_POLARIZATION", i_val=num_gto)
     428            2 :       num_pol = num_gto
     429            2 :       IF (num_gto > 0) THEN
     430            1 :          IF (iw > 0) THEN
     431            1 :             WRITE (iw, '(/,A)') " Polarization basis set  "
     432              :          END IF
     433            7 :          ALLOCATE (pbasis(num_gto, num_gto, 0:7), alp(num_gto))
     434            1 :          pbasis = 0.0_dp
     435              :          ! optimize exponents
     436            1 :          lval = maxl + 1
     437            1 :          zval = SQRT(REAL(2*lval + 2, dp))*REAL(lval + 1, dp)/(2._dp*rmax)
     438            1 :          aval = atom%basis%am(1, 0)
     439            1 :          cval = 2.5_dp
     440            1 :          rconf = atom%potential%scon
     441            1 :          CALL atom_fit_pol(zval, rconf, lval, aval, cval, num_gto, iw, powell_section)
     442              :          ! calculate contractions
     443            5 :          DO i = 1, num_gto
     444            5 :             alp(i) = aval*cval**(i - 1)
     445              :          END DO
     446            3 :          ALLOCATE (rho(num_gto))
     447            5 :          DO l = maxl + 1, MIN(maxl + num_gto, 7)
     448            4 :             zval = SQRT(REAL(2*l + 2, dp))*REAL(l + 1, dp)/(2._dp*rmax)
     449            4 :             CALL hydrogenic(zval, rconf, l, alp, num_gto, rho, pbasis(:, :, l))
     450            4 :             IF (iw > 0) WRITE (iw, '(T5,A,i5,T66,A,F10.4)') &
     451            5 :                " Polarization basis set contraction for lval=", l, "zval=", zval
     452              :          END DO
     453            1 :          DEALLOCATE (rho)
     454              :       END IF
     455              : 
     456              :       ! generate valence expansion sets
     457            2 :       maxl = atom%state%maxl_occ
     458            2 :       CALL section_vals_val_get(grb_section, "NUM_GTO_EXTENDED", i_val=num_gto)
     459            2 :       CALL section_vals_val_get(grb_section, "EXTENSION_BASIS", i_vals=num_bas)
     460            2 :       next_bas(0:lmat) = 0
     461            2 :       IF (num_bas(1) == -1) THEN
     462            0 :          DO l = 0, maxl
     463            0 :             next_bas(l) = maxl - l + 1
     464              :          END DO
     465              :       ELSE
     466            2 :          n = MIN(SIZE(num_bas, 1), 4)
     467            6 :          next_bas(0:n - 1) = num_bas(1:n)
     468              :       END IF
     469            2 :       next_prim = 0
     470           14 :       DO l = 0, lmat
     471           14 :          IF (next_bas(l) > 0) next_prim(l) = num_gto
     472              :       END DO
     473            2 :       IF (iw > 0) THEN
     474            2 :          CALL basis_label(abas, next_prim, next_bas)
     475            2 :          WRITE (iw, '(/,A,A)') " Extension basis set     ", TRIM(abas)
     476              :       END IF
     477           14 :       n = MAXVAL(next_prim)
     478           14 :       m = MAXVAL(next_bas)
     479           11 :       ALLOCATE (ebasis(n, n, 0:lmat), ale(n))
     480            2 :       basis_vrb => vbasis(0)%basis
     481            2 :       amin = atom%basis%aval/atom%basis%cval**1.5_dp
     482            6 :       DO i = 1, n
     483            6 :          ale(i) = amin*atom%basis%cval**(i - 1)
     484              :       END DO
     485            2 :       ebasis = 0._dp
     486            5 :       ALLOCATE (rho(n))
     487            2 :       rconf = 2.0_dp*atom%potential%scon
     488           14 :       DO l = 0, lmat
     489           12 :          IF (next_bas(l) < 1) CYCLE
     490            2 :          zval = SQRT(REAL(2*l + 2, dp))*REAL(l + 1, dp)/(2._dp*rmax)
     491            2 :          CALL hydrogenic(zval, rconf, l, ale, n, rho, ebasis(:, :, l))
     492            2 :          IF (iw > 0) WRITE (iw, '(T5,A,i5,T66,A,F10.4)') &
     493            4 :             " Extension basis set contraction for lval=", l, "zval=", zval
     494              :       END DO
     495            2 :       DEALLOCATE (rho)
     496              :       ! check for condition numbers
     497            2 :       IF (iw > 0) WRITE (iw, '(/,A)') " Condition Number of Extended Basis Sets"
     498            2 :       CALL init_orbital_pointers(lmat)
     499            2 :       CALL init_spherical_harmonics(lmat, 0)
     500           10 :       DO ider = 0, nder
     501            8 :          NULLIFY (basis_vrb)
     502          152 :          ALLOCATE (basis_vrb)
     503              :          NULLIFY (basis_vrb%am, basis_vrb%cm, basis_vrb%as, basis_vrb%ns, basis_vrb%bf, &
     504              :                   basis_vrb%dbf, basis_vrb%ddbf)
     505              :          ! allocate and initialize the atomic grid
     506              :          NULLIFY (basis_vrb%grid)
     507            8 :          CALL allocate_grid_atom(basis_vrb%grid)
     508            8 :          CALL create_grid_atom(basis_vrb%grid, ngp, 1, 1, 0, quadtype)
     509            8 :          basis_vrb%grid%nr = ngp
     510              :          !
     511            8 :          basis_vrb%eps_eig = basis_ref%eps_eig
     512            8 :          basis_vrb%geometrical = .FALSE.
     513            8 :          basis_vrb%basis_type = CGTO_BASIS
     514          104 :          basis_vrb%nprim = basis%nprim + next_prim
     515           56 :          basis_vrb%nbas = 0
     516           24 :          DO l = 0, state%maxl_occ
     517           24 :             basis_vrb%nbas(l) = state%maxn_occ(l) + ider + next_bas(l)
     518              :          END DO
     519           56 :          m = MAXVAL(basis_vrb%nprim)
     520           24 :          ALLOCATE (basis_vrb%am(m, 0:lmat))
     521              :          ! exponents
     522            8 :          m = SIZE(basis%am, 1)
     523          680 :          basis_vrb%am(1:m, :) = basis%am(1:m, :)
     524            8 :          n = SIZE(ale, 1)
     525           24 :          DO l = 0, state%maxl_occ
     526           56 :             basis_vrb%am(m + 1:m + n, l) = ale(1:n)
     527              :          END DO
     528              :          ! contractions
     529           56 :          m = MAXVAL(basis_vrb%nprim)
     530           56 :          n = MAXVAL(basis_vrb%nbas)
     531           40 :          ALLOCATE (basis_vrb%cm(m, n, 0:lmat))
     532         1664 :          basis_vrb%cm = 0.0_dp
     533           24 :          DO l = 0, state%maxl_occ
     534           16 :             m = basis%nprim(l)
     535           16 :             n = state%maxn_occ(l) + ider
     536          296 :             basis_vrb%cm(1:m, 1:n, l) = rbasis(1:m, 1:n, l)
     537           84 :             basis_vrb%cm(m + 1:m + next_prim(l), n + 1:n + next_bas(l), l) = ebasis(1:next_prim(l), 1:next_bas(l), l)
     538              :          END DO
     539              : 
     540              :          ! initialize basis function on a radial grid
     541            8 :          nr = basis_vrb%grid%nr
     542           56 :          m = MAXVAL(basis_vrb%nbas)
     543           40 :          ALLOCATE (basis_vrb%bf(nr, m, 0:lmat))
     544           24 :          ALLOCATE (basis_vrb%dbf(nr, m, 0:lmat))
     545           24 :          ALLOCATE (basis_vrb%ddbf(nr, m, 0:lmat))
     546        67424 :          basis_vrb%bf = 0._dp
     547        67424 :          basis_vrb%dbf = 0._dp
     548        67424 :          basis_vrb%ddbf = 0._dp
     549           56 :          DO l = 0, lmat
     550          184 :             DO i = 1, basis_vrb%nprim(l)
     551          128 :                al = basis_vrb%am(i, l)
     552        51376 :                DO k = 1, nr
     553        51200 :                   rk = basis_vrb%grid%rad(k)
     554        51200 :                   ear = EXP(-al*basis_vrb%grid%rad(k)**2)
     555       227328 :                   DO j = 1, basis_vrb%nbas(l)
     556       176000 :                      basis_vrb%bf(k, j, l) = basis_vrb%bf(k, j, l) + rk**l*ear*basis_vrb%cm(i, j, l)
     557              :                      basis_vrb%dbf(k, j, l) = basis_vrb%dbf(k, j, l) &
     558       176000 :                                               + (REAL(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear*basis_vrb%cm(i, j, l)
     559              :                      basis_vrb%ddbf(k, j, l) = basis_vrb%ddbf(k, j, l) + &
     560              :                                                (REAL(l*(l - 1), dp)*rk**(l - 2) - 2._dp*al*REAL(2*l + 1, dp)*rk**(l) + &
     561       227200 :                                                 4._dp*al*rk**(l + 2))*ear*basis_vrb%cm(i, j, l)
     562              :                   END DO
     563              :                END DO
     564              :             END DO
     565              :          END DO
     566              : 
     567            8 :          IF (iw > 0) THEN
     568            8 :             CALL basis_label(abas, basis_vrb%nprim, basis_vrb%nbas)
     569            8 :             WRITE (iw, '(A,A)') " Basis set     ", TRIM(abas)
     570              :          END IF
     571            8 :          crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
     572            8 :          cradx = crad*1.00_dp
     573            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     574            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     575            8 :          cradx = crad*1.10_dp
     576            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     577            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     578            8 :          cradx = crad*1.20_dp
     579            8 :          CALL atom_basis_condnum(basis_vrb, cradx, cnum)
     580            8 :          IF (iw > 0) WRITE (iw, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
     581           34 :          vbasis(nder + 1 + ider)%basis => basis_vrb
     582              :       END DO
     583            2 :       CALL deallocate_orbital_pointers
     584            2 :       CALL deallocate_spherical_harmonics
     585              : 
     586              :       ! Tests for energy
     587            2 :       energy_ref = atom_ref%energy%etot
     588            2 :       IF (iw > 0) WRITE (iw, '(/,A,A)') " Basis set tests    "
     589            2 :       IF (iw > 0) WRITE (iw, '(T10,A,T59,F22.9)') " Reference Energy [a.u.]  ", energy_ref
     590           18 :       DO ider = 0, 2*nder + 1
     591              :          ! generate an atom type
     592           16 :          NULLIFY (atom_test)
     593           16 :          CALL create_atom_type(atom_test)
     594              :          CALL copy_atom_basics(atom_ref, atom_test, state=.TRUE., potential=.TRUE., &
     595           16 :                                optimization=.TRUE., xc=.TRUE.)
     596           16 :          basis_grb => vbasis(ider)%basis
     597           16 :          NULLIFY (orbitals)
     598          112 :          mo = MAXVAL(atom_test%state%maxn_calc)
     599          112 :          mb = MAXVAL(basis_grb%nbas)
     600           16 :          CALL create_atom_orbs(orbitals, mb, mo)
     601           16 :          CALL set_atom(atom_test, orbitals=orbitals, basis=basis_grb)
     602              :          ! calculate integrals
     603         3408 :          ALLOCATE (atint)
     604           16 :          CALL atom_int_setup(atint, basis_grb, potential=atom_test%potential, eri_coulomb=.FALSE., eri_exchange=.FALSE.)
     605           16 :          CALL atom_ppint_setup(atint, basis_grb, potential=atom_test%potential)
     606           16 :          IF (atom_test%pp_calc) THEN
     607           16 :             NULLIFY (atint%tzora, atint%hdkh)
     608              :          ELSE
     609              :             ! relativistic correction terms
     610            0 :             CALL atom_relint_setup(atint, basis_grb, atom_test%relativistic, zcore=REAL(atom_test%z, dp))
     611              :          END IF
     612           16 :          CALL set_atom(atom_test, integrals=atint)
     613              :          !
     614           16 :          CALL calculate_atom(atom_test, iw=0)
     615           16 :          IF (ider <= nder) THEN
     616            8 :             energy_vb(ider) = atom_test%energy%etot
     617           16 :             IF (iw > 0) WRITE (iw, '(T10,A,i1,A,T40,F13.9,T59,F22.9)') " GRB (VB)", ider, " Energy [a.u.]  ", &
     618           16 :                energy_ref - energy_vb(ider), energy_vb(ider)
     619              :          ELSE
     620            8 :             i = ider - nder - 1
     621            8 :             energy_ex(i) = atom_test%energy%etot
     622           16 :             IF (iw > 0) WRITE (iw, '(T10,A,i1,A,T40,F13.9,T59,F22.9)') " GRB (EX)", i, " Energy [a.u.]  ", &
     623           16 :                energy_ref - energy_ex(i), energy_ex(i)
     624              :          END IF
     625           16 :          CALL atom_int_release(atint)
     626           16 :          CALL atom_ppint_release(atint)
     627           16 :          CALL atom_relint_release(atint)
     628           16 :          DEALLOCATE (atom_test%state, atom_test%potential, atint)
     629           18 :          CALL release_atom_type(atom_test)
     630              :       END DO
     631              : 
     632              :       ! Quickstep normalization polarization basis
     633           18 :       DO l = 0, 7
     634           16 :          expzet = 0.25_dp*REAL(2*l + 3, dp)
     635           16 :          prefac = SQRT(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
     636           50 :          DO i = 1, num_pol
     637           32 :             zeta = (2._dp*alp(i))**expzet
     638          176 :             pbasis(i, 1:num_pol, l) = pbasis(i, 1:num_pol, l)*prefac/zeta
     639              :          END DO
     640              :       END DO
     641              :       ! Quickstep normalization extended basis
     642           14 :       DO l = 0, lmat
     643           12 :          expzet = 0.25_dp*REAL(2*l + 3, dp)
     644           12 :          prefac = SQRT(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
     645           22 :          DO i = 1, next_prim(l)
     646            8 :             zeta = (2._dp*ale(i))**expzet
     647           32 :             ebasis(i, 1:next_bas(l), l) = ebasis(i, 1:next_bas(l), l)*prefac/zeta
     648              :          END DO
     649              :       END DO
     650              : 
     651              :       ! Print basis sets
     652            2 :       CALL section_vals_val_get(grb_section, "NAME_BODY", c_val=basname)
     653            2 :       CALL open_file(file_name="GRB_BASIS", file_status="UNKNOWN", file_action="WRITE", unit_number=iunit)
     654              :       ! header info
     655            8 :       headline = ""
     656            2 :       headline(1) = "#"
     657            2 :       headline(2) = "# Generated with CP2K Atom Code"
     658            2 :       headline(3) = "#"
     659            2 :       CALL grb_print_basis(header=headline, iunit=iunit)
     660              :       ! valence basis
     661            2 :       basline(1) = ""
     662            2 :       WRITE (basline(1), "(T2,A)") ADJUSTL(ptable(atom_ref%z)%symbol)
     663           10 :       DO ider = 0, nder
     664            8 :          basline(1) = ""
     665            8 :          WRITE (basline(1), "(T2,A,T5,A,I1)") ADJUSTL(ptable(atom_ref%z)%symbol), TRIM(ADJUSTL(basname))//"-VAL-", ider
     666              :          CALL grb_print_basis(header=basline, nprim=vbasis(ider)%basis%nprim(0), nbas=vbasis(ider)%basis%nbas, &
     667           10 :                               al=vbasis(ider)%basis%am(:, 0), gcc=qbasis, iunit=iunit)
     668              :       END DO
     669              :       ! polarization basis
     670            2 :       maxl = atom_ref%state%maxl_occ
     671            6 :       DO l = maxl + 1, MIN(maxl + num_pol, 7)
     672            4 :          nbas = 0
     673           14 :          DO i = maxl + 1, l
     674           14 :             nbas(i) = l - i + 1
     675              :          END DO
     676            4 :          i = l - maxl
     677            4 :          basline(1) = ""
     678            4 :          WRITE (basline(1), "(T2,A,T5,A,I1)") ADJUSTL(ptable(atom_ref%z)%symbol), TRIM(ADJUSTL(basname))//"-POL-", i
     679            6 :          CALL grb_print_basis(header=basline, nprim=num_pol, nbas=nbas, al=alp, gcc=pbasis, iunit=iunit)
     680              :       END DO
     681              :       ! extension set
     682           14 :       IF (SUM(next_bas) > 0) THEN
     683            1 :          basline(1) = ""
     684            1 :          WRITE (basline(1), "(T2,A,T5,A)") ADJUSTL(ptable(atom_ref%z)%symbol), TRIM(ADJUSTL(basname))//"-EXT"
     685            1 :          CALL grb_print_basis(header=basline, nprim=next_prim(0), nbas=next_bas, al=ale, gcc=ebasis, iunit=iunit)
     686              :       END IF
     687              :       !
     688            2 :       CALL close_file(unit_number=iunit)
     689              : 
     690              :       ! clean up
     691            2 :       IF (ALLOCATED(pbasis)) DEALLOCATE (pbasis)
     692            2 :       IF (ALLOCATED(alp)) DEALLOCATE (alp)
     693            2 :       IF (ALLOCATED(ebasis)) DEALLOCATE (ebasis)
     694            2 :       DEALLOCATE (wfn, rbasis, qbasis, ale)
     695              : 
     696           24 :       DO ider = 0, 10
     697           24 :          IF (ASSOCIATED(vbasis(ider)%basis)) THEN
     698           16 :             CALL release_atom_basis(vbasis(ider)%basis)
     699           16 :             DEALLOCATE (vbasis(ider)%basis)
     700              :          END IF
     701              :       END DO
     702              : 
     703            2 :       CALL atom_int_release(atom%integrals)
     704            2 :       CALL atom_ppint_release(atom%integrals)
     705            2 :       CALL atom_relint_release(atom%integrals)
     706            2 :       CALL release_atom_basis(basis)
     707            2 :       DEALLOCATE (atom%potential, atom%state, atom%integrals, basis)
     708            2 :       CALL release_atom_type(atom)
     709              : 
     710            2 :       IF (iw > 0) WRITE (iw, '(" ",79("*"))')
     711              : 
     712           18 :    END SUBROUTINE atom_grb_construction
     713              : 
     714              : ! **************************************************************************************************
     715              : !> \brief Print geometrical response basis set.
     716              : !> \param header  banner to print on top of the basis set
     717              : !> \param nprim   number of primitive exponents
     718              : !> \param nbas    number of basis functions for the given angular momentum
     719              : !> \param al      list of the primitive exponents
     720              : !> \param gcc     array of contraction coefficients of size
     721              : !>                (index-of-the-primitive-exponent, index-of-the-contraction-set, angular-momentum)
     722              : !> \param iunit   output file unit
     723              : !> \par History
     724              : !>    * 11.2016 created [Juerg Hutter]
     725              : ! **************************************************************************************************
     726           15 :    SUBROUTINE grb_print_basis(header, nprim, nbas, al, gcc, iunit)
     727              :       CHARACTER(len=*), DIMENSION(:), INTENT(IN), &
     728              :          OPTIONAL                                        :: header
     729              :       INTEGER, INTENT(IN), OPTIONAL                      :: nprim
     730              :       INTEGER, DIMENSION(0:), INTENT(IN), OPTIONAL       :: nbas
     731              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN), OPTIONAL  :: al
     732              :       REAL(KIND=dp), DIMENSION(:, :, 0:), INTENT(IN), &
     733              :          OPTIONAL                                        :: gcc
     734              :       INTEGER, INTENT(IN)                                :: iunit
     735              : 
     736              :       INTEGER                                            :: i, j, l, lmax, lmin, nval
     737              : 
     738           15 :       IF (PRESENT(header)) THEN
     739           34 :          DO i = 1, SIZE(header, 1)
     740           34 :             IF (header(i) /= "") THEN
     741           19 :                WRITE (iunit, "(A)") TRIM(header(i))
     742              :             END IF
     743              :          END DO
     744              :       END IF
     745              : 
     746           15 :       IF (PRESENT(nprim)) THEN
     747           13 :          IF (nprim > 0) THEN
     748           13 :             CPASSERT(PRESENT(nbas))
     749           13 :             CPASSERT(PRESENT(al))
     750           13 :             CPASSERT(PRESENT(gcc))
     751              : 
     752           34 :             DO i = LBOUND(nbas, 1), UBOUND(nbas, 1)
     753           21 :                IF (nbas(i) > 0) THEN
     754           13 :                   lmin = i
     755           13 :                   EXIT
     756              :                END IF
     757              :             END DO
     758           63 :             DO i = UBOUND(nbas, 1), LBOUND(nbas, 1), -1
     759           63 :                IF (nbas(i) > 0) THEN
     760           13 :                   lmax = i
     761           13 :                   EXIT
     762              :                END IF
     763              :             END DO
     764              : 
     765           13 :             nval = lmax
     766           13 :             WRITE (iunit, *) "  1"
     767           13 :             WRITE (iunit, "(40I3)") nval, lmin, lmax, nprim, (nbas(l), l=lmin, lmax)
     768           81 :             DO i = nprim, 1, -1
     769           68 :                WRITE (iunit, "(G20.12)", advance="no") al(i)
     770          212 :                DO l = lmin, lmax
     771          544 :                   DO j = 1, nbas(l)
     772          476 :                      WRITE (iunit, "(F16.10)", advance="no") gcc(i, j, l)
     773              :                   END DO
     774              :                END DO
     775           81 :                WRITE (iunit, *)
     776              :             END DO
     777           13 :             WRITE (iunit, *)
     778              :          END IF
     779              :       END IF
     780              : 
     781           15 :    END SUBROUTINE grb_print_basis
     782              : 
     783              : ! **************************************************************************************************
     784              : !> \brief Compose the basis set label:
     785              : !>        (np(0)'s'np(1)'p'...) -> [nb(0)'s'nb(1)'p'...] .
     786              : !> \param label  basis set label
     787              : !> \param np     number of primitive basis functions per angular momentum
     788              : !> \param nb     number of contracted basis functions per angular momentum
     789              : !> \par History
     790              : !>    * 11.2016 created [Juerg Hutter]
     791              : ! **************************************************************************************************
     792           18 :    SUBROUTINE basis_label(label, np, nb)
     793              :       CHARACTER(len=*), INTENT(out)                      :: label
     794              :       INTEGER, DIMENSION(0:), INTENT(in)                 :: np, nb
     795              : 
     796              :       INTEGER                                            :: i, l, lmax
     797              :       CHARACTER(len=1), DIMENSION(0:7), PARAMETER :: lq = ["s", "p", "d", "f", "g", "h", "i", "k"]
     798              : 
     799           18 :       label = ""
     800           18 :       lmax = MIN(UBOUND(np, 1), UBOUND(nb, 1), 7)
     801           18 :       i = 1
     802           18 :       label(i:i) = "("
     803          126 :       DO l = 0, lmax
     804          126 :          IF (np(l) > 0) THEN
     805           34 :             i = i + 1
     806           34 :             IF (np(l) > 9) THEN
     807            8 :                WRITE (label(i:i + 1), "(I2)") np(l)
     808            8 :                i = i + 2
     809              :             ELSE
     810           26 :                WRITE (label(i:i), "(I1)") np(l)
     811           26 :                i = i + 1
     812              :             END IF
     813           34 :             label(i:i) = lq(l)
     814              :          END IF
     815              :       END DO
     816           18 :       i = i + 1
     817           18 :       label(i:i + 6) = ") --> ["
     818           18 :       i = i + 6
     819          126 :       DO l = 0, lmax
     820          126 :          IF (nb(l) > 0) THEN
     821           34 :             i = i + 1
     822           34 :             IF (nb(l) > 9) THEN
     823            0 :                WRITE (label(i:i + 1), "(I2)") nb(l)
     824            0 :                i = i + 2
     825              :             ELSE
     826           34 :                WRITE (label(i:i), "(I1)") nb(l)
     827           34 :                i = i + 1
     828              :             END IF
     829           34 :             label(i:i) = lq(l)
     830              :          END IF
     831              :       END DO
     832           18 :       i = i + 1
     833           18 :       label(i:i) = "]"
     834              : 
     835           18 :    END SUBROUTINE basis_label
     836              : 
     837              : ! **************************************************************************************************
     838              : !> \brief Compute the total energy for the given atomic kind and basis set.
     839              : !> \param atom    information about the atomic kind
     840              : !> \param basis   basis set to fit
     841              : !> \param afun    (output) atomic total energy
     842              : !> \param iw      output file unit
     843              : !> \par History
     844              : !>    * 11.2016 created [Juerg Hutter]
     845              : ! **************************************************************************************************
     846          170 :    SUBROUTINE grb_fit(atom, basis, afun, iw)
     847              :       TYPE(atom_type), POINTER                           :: atom
     848              :       TYPE(atom_basis_type), POINTER                     :: basis
     849              :       REAL(dp), INTENT(OUT)                              :: afun
     850              :       INTEGER, INTENT(IN)                                :: iw
     851              : 
     852              :       INTEGER                                            :: do_eric, do_erie, reltyp, zval
     853              :       LOGICAL                                            :: eri_c, eri_e
     854              :       TYPE(atom_integrals), POINTER                      :: atint
     855              :       TYPE(atom_potential_type), POINTER                 :: pot
     856              : 
     857        36890 :       ALLOCATE (atint)
     858              :       ! calculate integrals
     859          170 :       NULLIFY (pot)
     860          170 :       eri_c = .FALSE.
     861          170 :       eri_e = .FALSE.
     862          170 :       pot => atom%potential
     863          170 :       zval = atom%z
     864          170 :       reltyp = atom%relativistic
     865          170 :       do_eric = atom%coulomb_integral_type
     866          170 :       do_erie = atom%exchange_integral_type
     867          170 :       IF (do_eric == do_analytic) eri_c = .TRUE.
     868          170 :       IF (do_erie == do_analytic) eri_e = .TRUE.
     869              :       ! general integrals
     870          170 :       CALL atom_int_setup(atint, basis, potential=pot, eri_coulomb=eri_c, eri_exchange=eri_e)
     871              :       ! potential
     872          170 :       CALL atom_ppint_setup(atint, basis, potential=pot)
     873          170 :       IF (atom%pp_calc) THEN
     874          170 :          NULLIFY (atint%tzora, atint%hdkh)
     875              :       ELSE
     876              :          ! relativistic correction terms
     877            0 :          CALL atom_relint_setup(atint, basis, reltyp, zcore=REAL(zval, dp))
     878              :       END IF
     879          170 :       CALL set_atom(atom, basis=basis)
     880          170 :       CALL set_atom(atom, integrals=atint)
     881          170 :       CALL calculate_atom(atom, iw)
     882          170 :       afun = atom%energy%etot
     883          170 :       CALL atom_int_release(atint)
     884          170 :       CALL atom_ppint_release(atint)
     885          170 :       CALL atom_relint_release(atint)
     886          170 :       DEALLOCATE (atint)
     887          170 :    END SUBROUTINE grb_fit
     888              : 
     889              : ! **************************************************************************************************
     890              : !> \brief Copy basic information about the atomic kind.
     891              : !> \param atom_ref      atom to copy
     892              : !> \param atom          new atom to create
     893              : !> \param state         also copy electronic state and occupation numbers
     894              : !> \param potential     also copy pseudo-potential
     895              : !> \param optimization  also copy optimization procedure
     896              : !> \param xc            also copy the XC input section
     897              : !> \par History
     898              : !>    * 11.2016 created [Juerg Hutter]
     899              : ! **************************************************************************************************
     900           18 :    SUBROUTINE copy_atom_basics(atom_ref, atom, state, potential, optimization, xc)
     901              :       TYPE(atom_type), POINTER                           :: atom_ref, atom
     902              :       LOGICAL, INTENT(IN), OPTIONAL                      :: state, potential, optimization, xc
     903              : 
     904           18 :       atom%z = atom_ref%z
     905           18 :       atom%zcore = atom_ref%zcore
     906           18 :       atom%pp_calc = atom_ref%pp_calc
     907           18 :       atom%method_type = atom_ref%method_type
     908           18 :       atom%relativistic = atom_ref%relativistic
     909           18 :       atom%coulomb_integral_type = atom_ref%coulomb_integral_type
     910           18 :       atom%exchange_integral_type = atom_ref%exchange_integral_type
     911              : 
     912           18 :       NULLIFY (atom%potential, atom%state, atom%xc_section)
     913           18 :       NULLIFY (atom%basis, atom%integrals, atom%orbitals, atom%fmat)
     914              : 
     915           18 :       IF (PRESENT(state)) THEN
     916           18 :          IF (state) THEN
     917         6660 :             ALLOCATE (atom%state)
     918           18 :             atom%state = atom_ref%state
     919              :          END IF
     920              :       END IF
     921              : 
     922           18 :       IF (PRESENT(potential)) THEN
     923           18 :          IF (potential) THEN
     924        97182 :             ALLOCATE (atom%potential)
     925           18 :             atom%potential = atom_ref%potential
     926              :          END IF
     927              :       END IF
     928              : 
     929           18 :       IF (PRESENT(optimization)) THEN
     930           18 :          IF (optimization) THEN
     931           18 :             atom%optimization = atom_ref%optimization
     932              :          END IF
     933              :       END IF
     934              : 
     935           18 :       IF (PRESENT(xc)) THEN
     936           18 :          IF (xc) THEN
     937           18 :             atom%xc_section => atom_ref%xc_section
     938              :          END IF
     939              :       END IF
     940              : 
     941           18 :    END SUBROUTINE copy_atom_basics
     942              : 
     943              : ! **************************************************************************************************
     944              : !> \brief Optimise a geometrical response basis set.
     945              : !> \param atom            information about the atomic kind
     946              : !> \param basis           basis set to fit
     947              : !> \param iunit           output file unit
     948              : !> \param powell_section  POWELL input section
     949              : !> \par History
     950              : !>    * 11.2016 created [Juerg Hutter]
     951              : ! **************************************************************************************************
     952            2 :    SUBROUTINE atom_fit_grb(atom, basis, iunit, powell_section)
     953              :       TYPE(atom_type), POINTER                           :: atom
     954              :       TYPE(atom_basis_type), POINTER                     :: basis
     955              :       INTEGER, INTENT(IN)                                :: iunit
     956              :       TYPE(section_vals_type), POINTER                   :: powell_section
     957              : 
     958              :       INTEGER                                            :: i, k, l, ll, n10, nr
     959              :       REAL(KIND=dp)                                      :: al, cnum, crad, cradx, ear, fopt, rk
     960            2 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: x
     961              :       TYPE(opt_state_type)                               :: ostate
     962              : 
     963            0 :       CPASSERT(basis%geometrical)
     964              : 
     965            2 :       CALL section_vals_val_get(powell_section, "ACCURACY", r_val=ostate%rhoend)
     966            2 :       CALL section_vals_val_get(powell_section, "STEP_SIZE", r_val=ostate%rhobeg)
     967            2 :       CALL section_vals_val_get(powell_section, "MAX_FUN", i_val=ostate%maxfun)
     968              : 
     969            2 :       ostate%nvar = 2
     970            2 :       ALLOCATE (x(2))
     971            2 :       x(1) = SQRT(basis%aval)
     972            2 :       x(2) = SQRT(basis%cval)
     973              : 
     974            2 :       ostate%nf = 0
     975            2 :       ostate%iprint = 1
     976            2 :       ostate%unit = iunit
     977              : 
     978            2 :       ostate%state = 0
     979            2 :       IF (iunit > 0) THEN
     980            2 :          WRITE (iunit, '(/," POWELL| Start optimization procedure")')
     981            2 :          WRITE (iunit, '(" POWELL| Total number of parameters in optimization",T71,I10)') ostate%nvar
     982              :       END IF
     983            2 :       n10 = MAX(ostate%maxfun/100, 1)
     984              : 
     985            2 :       fopt = HUGE(0._dp)
     986              : 
     987              :       DO
     988              : 
     989          176 :          IF (ostate%state == 2) THEN
     990         7310 :             basis%am = 0._dp
     991         1190 :             DO l = 0, lmat
     992         3230 :                DO i = 1, basis%nbas(l)
     993         2040 :                   ll = i - 1 + basis%start(l)
     994         3060 :                   basis%am(i, l) = x(1)*x(1)*(x(2)*x(2))**(ll)
     995              :                END DO
     996              :             END DO
     997          170 :             basis%aval = x(1)*x(1)
     998          170 :             basis%cval = x(2)*x(2)
     999      2455310 :             basis%bf = 0._dp
    1000      2455310 :             basis%dbf = 0._dp
    1001      2455310 :             basis%ddbf = 0._dp
    1002          170 :             nr = basis%grid%nr
    1003         1190 :             DO l = 0, lmat
    1004         3230 :                DO i = 1, basis%nbas(l)
    1005         2040 :                   al = basis%am(i, l)
    1006       819060 :                   DO k = 1, nr
    1007       816000 :                      rk = basis%grid%rad(k)
    1008       816000 :                      ear = EXP(-al*basis%grid%rad(k)**2)
    1009       816000 :                      basis%bf(k, i, l) = rk**l*ear
    1010       816000 :                      basis%dbf(k, i, l) = (REAL(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
    1011              :                      basis%ddbf(k, i, l) = (REAL(l*(l - 1), dp)*rk**(l - 2) - &
    1012       818040 :                                             2._dp*al*REAL(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
    1013              :                   END DO
    1014              :                END DO
    1015              :             END DO
    1016          170 :             CALL grb_fit(atom, basis, ostate%f, 0)
    1017          170 :             fopt = MIN(fopt, ostate%f)
    1018              :          END IF
    1019              : 
    1020          176 :          IF (ostate%state == -1) EXIT
    1021              : 
    1022          174 :          CALL powell_optimize(ostate%nvar, x, ostate)
    1023              : 
    1024          174 :          IF (ostate%nf == 2 .AND. iunit > 0) THEN
    1025            2 :             WRITE (iunit, '(" POWELL| Initial value of function",T61,F20.10)') ostate%f
    1026              :          END IF
    1027          176 :          IF (MOD(ostate%nf, n10) == 0 .AND. iunit > 0) THEN
    1028              :             WRITE (iunit, '(" POWELL| Reached",i4,"% of maximal function calls",T61,F20.10)') &
    1029            2 :                INT(REAL(ostate%nf, dp)/REAL(ostate%maxfun, dp)*100._dp), fopt
    1030              :          END IF
    1031              : 
    1032              :       END DO
    1033              : 
    1034            2 :       ostate%state = 8
    1035            2 :       CALL powell_optimize(ostate%nvar, x, ostate)
    1036              : 
    1037            2 :       IF (iunit > 0) THEN
    1038            2 :          WRITE (iunit, '(" POWELL| Number of function evaluations",T71,I10)') ostate%nf
    1039            2 :          WRITE (iunit, '(" POWELL| Final value of function",T61,F20.10)') ostate%fopt
    1040              :       END IF
    1041              :       ! x->basis
    1042           86 :       basis%am = 0._dp
    1043           14 :       DO l = 0, lmat
    1044           38 :          DO i = 1, basis%nbas(l)
    1045           24 :             ll = i - 1 + basis%start(l)
    1046           36 :             basis%am(i, l) = x(1)*x(1)*(x(2)*x(2))**(ll)
    1047              :          END DO
    1048              :       END DO
    1049            2 :       basis%aval = x(1)*x(1)
    1050            2 :       basis%cval = x(2)*x(2)
    1051        28886 :       basis%bf = 0._dp
    1052        28886 :       basis%dbf = 0._dp
    1053        28886 :       basis%ddbf = 0._dp
    1054            2 :       nr = basis%grid%nr
    1055           14 :       DO l = 0, lmat
    1056           38 :          DO i = 1, basis%nbas(l)
    1057           24 :             al = basis%am(i, l)
    1058         9636 :             DO k = 1, nr
    1059         9600 :                rk = basis%grid%rad(k)
    1060         9600 :                ear = EXP(-al*basis%grid%rad(k)**2)
    1061         9600 :                basis%bf(k, i, l) = rk**l*ear
    1062         9600 :                basis%dbf(k, i, l) = (REAL(l, dp)*rk**(l - 1) - 2._dp*al*rk**(l + 1))*ear
    1063              :                basis%ddbf(k, i, l) = (REAL(l*(l - 1), dp)*rk**(l - 2) - &
    1064         9624 :                                       2._dp*al*REAL(2*l + 1, dp)*rk**(l) + 4._dp*al*rk**(l + 2))*ear
    1065              :             END DO
    1066              :          END DO
    1067              :       END DO
    1068              : 
    1069            2 :       DEALLOCATE (x)
    1070              : 
    1071              :       ! final result
    1072            2 :       IF (iunit > 0) THEN
    1073            2 :          WRITE (iunit, '(/,A)') " Optimized Geometrical GTO basis set"
    1074            2 :          WRITE (iunit, '(A,F15.8,T41,A,F15.8)') " Initial exponent: ", basis%aval, &
    1075            4 :             " Proportionality factor: ", basis%cval
    1076           14 :          DO l = 0, lmat
    1077           14 :             WRITE (iunit, '(T41,A,I2,T76,I5)') " Number of exponents for l=", l, basis%nbas(l)
    1078              :          END DO
    1079              :       END IF
    1080              : 
    1081            2 :       IF (iunit > 0) WRITE (iunit, '(/,A)') " Condition number of uncontracted basis set"
    1082            2 :       crad = 2.0_dp*ptable(atom%z)%covalent_radius*bohr
    1083            2 :       CALL init_orbital_pointers(lmat)
    1084            2 :       CALL init_spherical_harmonics(lmat, 0)
    1085            2 :       cradx = crad*1.00_dp
    1086            2 :       CALL atom_basis_condnum(basis, cradx, cnum)
    1087            2 :       IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
    1088            2 :       cradx = crad*1.10_dp
    1089            2 :       CALL atom_basis_condnum(basis, cradx, cnum)
    1090            2 :       IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
    1091            2 :       cradx = crad*1.20_dp
    1092            2 :       CALL atom_basis_condnum(basis, cradx, cnum)
    1093            2 :       IF (iunit > 0) WRITE (iunit, '(T5,A,F15.3,T50,A,F14.4)') " Lattice constant:", cradx, "Condition number:", cnum
    1094            2 :       CALL deallocate_orbital_pointers
    1095            2 :       CALL deallocate_spherical_harmonics
    1096              : 
    1097            8 :    END SUBROUTINE atom_fit_grb
    1098              : 
    1099              : ! **************************************************************************************************
    1100              : !> \brief Optimize 'aval' and 'cval' parameters which define the geometrical response basis set.
    1101              : !> \param zval            nuclear charge
    1102              : !> \param rconf           confinement radius
    1103              : !> \param lval            angular momentum
    1104              : !> \param aval            (input/output) exponent of the first Gaussian basis function in the series
    1105              : !> \param cval            (input/output) factor of geometrical series
    1106              : !> \param nbas            number of basis functions
    1107              : !> \param iunit           output file unit
    1108              : !> \param powell_section  POWELL input section
    1109              : !> \par History
    1110              : !>    * 11.2016 created [Juerg Hutter]
    1111              : ! **************************************************************************************************
    1112            1 :    SUBROUTINE atom_fit_pol(zval, rconf, lval, aval, cval, nbas, iunit, powell_section)
    1113              :       REAL(KIND=dp), INTENT(IN)                          :: zval, rconf
    1114              :       INTEGER, INTENT(IN)                                :: lval
    1115              :       REAL(KIND=dp), INTENT(INOUT)                       :: aval, cval
    1116              :       INTEGER, INTENT(IN)                                :: nbas, iunit
    1117              :       TYPE(section_vals_type), POINTER                   :: powell_section
    1118              : 
    1119              :       INTEGER                                            :: i, n10
    1120              :       REAL(KIND=dp)                                      :: fopt, x(2)
    1121              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: am, ener
    1122              :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: orb
    1123              :       TYPE(opt_state_type)                               :: ostate
    1124              : 
    1125            7 :       ALLOCATE (am(nbas), ener(nbas), orb(nbas, nbas))
    1126              : 
    1127            1 :       CALL section_vals_val_get(powell_section, "ACCURACY", r_val=ostate%rhoend)
    1128            1 :       CALL section_vals_val_get(powell_section, "STEP_SIZE", r_val=ostate%rhobeg)
    1129            1 :       CALL section_vals_val_get(powell_section, "MAX_FUN", i_val=ostate%maxfun)
    1130              : 
    1131            1 :       ostate%nvar = 2
    1132            1 :       x(1) = SQRT(aval)
    1133            1 :       x(2) = SQRT(cval)
    1134              : 
    1135            1 :       ostate%nf = 0
    1136            1 :       ostate%iprint = 1
    1137            1 :       ostate%unit = iunit
    1138              : 
    1139            1 :       ostate%state = 0
    1140            1 :       IF (iunit > 0) THEN
    1141            1 :          WRITE (iunit, '(/," POWELL| Start optimization procedure")')
    1142            1 :          WRITE (iunit, '(" POWELL| Total number of parameters in optimization",T71,I10)') ostate%nvar
    1143              :       END IF
    1144            1 :       n10 = MAX(ostate%maxfun/100, 1)
    1145              : 
    1146            1 :       fopt = HUGE(0._dp)
    1147              : 
    1148              :       DO
    1149              : 
    1150           81 :          IF (ostate%state == 2) THEN
    1151           78 :             aval = x(1)*x(1)
    1152           78 :             cval = x(2)*x(2)
    1153          390 :             DO i = 1, nbas
    1154          390 :                am(i) = aval*cval**(i - 1)
    1155              :             END DO
    1156           78 :             CALL hydrogenic(zval, rconf, lval, am, nbas, ener, orb)
    1157           78 :             ostate%f = ener(1)
    1158           78 :             fopt = MIN(fopt, ostate%f)
    1159              :          END IF
    1160              : 
    1161           81 :          IF (ostate%state == -1) EXIT
    1162              : 
    1163           80 :          CALL powell_optimize(ostate%nvar, x, ostate)
    1164              : 
    1165           80 :          IF (ostate%nf == 2 .AND. iunit > 0) THEN
    1166            1 :             WRITE (iunit, '(" POWELL| Initial value of function",T61,F20.10)') ostate%f
    1167              :          END IF
    1168           81 :          IF (MOD(ostate%nf, n10) == 0 .AND. iunit > 0) THEN
    1169              :             WRITE (iunit, '(" POWELL| Reached",i4,"% of maximal function calls",T61,F20.10)') &
    1170            1 :                INT(REAL(ostate%nf, dp)/REAL(ostate%maxfun, dp)*100._dp), fopt
    1171              :          END IF
    1172              : 
    1173              :       END DO
    1174              : 
    1175            1 :       ostate%state = 8
    1176            1 :       CALL powell_optimize(ostate%nvar, x, ostate)
    1177              : 
    1178            1 :       IF (iunit > 0) THEN
    1179            1 :          WRITE (iunit, '(" POWELL| Number of function evaluations",T71,I10)') ostate%nf
    1180            1 :          WRITE (iunit, '(" POWELL| Final value of function",T61,F20.10)') ostate%fopt
    1181              :       END IF
    1182              :       ! x->basis
    1183            1 :       aval = x(1)*x(1)
    1184            1 :       cval = x(2)*x(2)
    1185              : 
    1186              :       ! final result
    1187            1 :       IF (iunit > 0) THEN
    1188            1 :          WRITE (iunit, '(/,A,T51,A,T76,I5)') " Optimized Polarization basis set", &
    1189            2 :             " Number of exponents:", nbas
    1190            1 :          WRITE (iunit, '(A,F15.8,T41,A,F15.8)') " Initial exponent: ", aval, &
    1191            2 :             " Proportionality factor: ", cval
    1192              :       END IF
    1193              : 
    1194            1 :       DEALLOCATE (am, ener, orb)
    1195              : 
    1196            1 :    END SUBROUTINE atom_fit_pol
    1197              : 
    1198              : ! **************************************************************************************************
    1199              : !> \brief Calculate orbitals of a hydrogen-like atom.
    1200              : !> \param zval   nuclear charge
    1201              : !> \param rconf  confinement radius
    1202              : !> \param lval   angular momentum
    1203              : !> \param am     list of basis functions' exponents
    1204              : !> \param nbas   number of basis functions
    1205              : !> \param ener   orbital energies
    1206              : !> \param orb    expansion coefficients of atomic wavefunctions
    1207              : !> \par History
    1208              : !>    * 11.2016 created [Juerg Hutter]
    1209              : ! **************************************************************************************************
    1210           84 :    SUBROUTINE hydrogenic(zval, rconf, lval, am, nbas, ener, orb)
    1211              :       REAL(KIND=dp), INTENT(IN)                          :: zval, rconf
    1212              :       INTEGER, INTENT(IN)                                :: lval
    1213              :       REAL(KIND=dp), DIMENSION(:), INTENT(IN)            :: am
    1214              :       INTEGER, INTENT(IN)                                :: nbas
    1215              :       REAL(KIND=dp), DIMENSION(:), INTENT(OUT)           :: ener
    1216              :       REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT)        :: orb
    1217              : 
    1218              :       INTEGER                                            :: info, k, lwork, n
    1219              :       REAL(KIND=dp)                                      :: cf
    1220           84 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: w, work
    1221           84 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: confmat, hmat, potmat, smat, tmat
    1222              : 
    1223           84 :       n = nbas
    1224         1008 :       ALLOCATE (smat(n, n), tmat(n, n), potmat(n, n), confmat(n, n), hmat(n, n))
    1225              :       ! calclulate overlap matrix
    1226           84 :       CALL sg_overlap(smat(1:n, 1:n), lval, am(1:n), am(1:n))
    1227              :       ! calclulate kinetic energy matrix
    1228           84 :       CALL sg_kinetic(tmat(1:n, 1:n), lval, am(1:n), am(1:n))
    1229              :       ! calclulate core potential matrix
    1230           84 :       CALL sg_nuclear(potmat(1:n, 1:n), lval, am(1:n), am(1:n))
    1231              :       ! calclulate confinement potential matrix
    1232           84 :       cf = 0.1_dp
    1233           84 :       k = 10
    1234           84 :       CALL sg_conf(confmat, rconf, k, lval, am(1:n), am(1:n))
    1235              :       ! Hamiltionian
    1236         1764 :       hmat(1:n, 1:n) = tmat(1:n, 1:n) - zval*potmat(1:n, 1:n) + cf*confmat(1:n, 1:n)
    1237              :       ! solve
    1238           84 :       lwork = 100*n
    1239          420 :       ALLOCATE (w(n), work(lwork))
    1240           84 :       CALL dsygv(1, "V", "U", n, hmat, n, smat, n, w, work, lwork, info)
    1241           84 :       CPASSERT(info == 0)
    1242         1764 :       orb(1:n, 1:n) = hmat(1:n, 1:n)
    1243          420 :       ener(1:n) = w(1:n)
    1244           84 :       DEALLOCATE (w, work)
    1245           84 :       DEALLOCATE (smat, tmat, potmat, confmat, hmat)
    1246              : 
    1247           84 :    END SUBROUTINE hydrogenic
    1248              : 
    1249           44 : END MODULE atom_grb
        

Generated by: LCOV version 2.0-1