LCOV - code coverage report
Current view: top level - src - atom_energy.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 95.0 % 663 630
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 4 4

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : MODULE atom_energy
       9              :    USE atom_admm_methods,               ONLY: atom_admm
      10              :    USE atom_electronic_structure,       ONLY: calculate_atom
      11              :    USE atom_fit,                        ONLY: atom_fit_density,&
      12              :                                               atom_fit_kgpot
      13              :    USE atom_grb,                        ONLY: atom_grb_construction
      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_output,                     ONLY: atom_print_basis,&
      21              :                                               atom_print_info,&
      22              :                                               atom_print_method,&
      23              :                                               atom_print_orbitals,&
      24              :                                               atom_print_potential,&
      25              :                                               atom_write_pseudo_param
      26              :    USE atom_sgp,                        ONLY: atom_sgp_construction
      27              :    USE atom_types,                      ONLY: &
      28              :         atom_basis_type, atom_gthpot_type, atom_integrals, atom_optimization_type, atom_orbitals, &
      29              :         atom_p_type, atom_potential_type, atom_state, atom_type, create_atom_orbs, &
      30              :         create_atom_type, gth_pseudo, init_atom_basis, init_atom_potential, lmat, &
      31              :         read_atom_opt_section, release_atom_basis, release_atom_potential, release_atom_type, &
      32              :         set_atom
      33              :    USE atom_utils,                      ONLY: &
      34              :         atom_completeness, atom_condnumber, atom_consistent_method, atom_core_density, &
      35              :         atom_density, atom_local_potential, atom_read_external_density, atom_read_external_vxc, &
      36              :         atom_set_occupation, atom_write_zmp_restart, get_maxl_occ, get_maxn_occ
      37              :    USE atom_xc,                         ONLY: calculate_atom_ext_vxc,&
      38              :                                               calculate_atom_zmp
      39              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      40              :                                               cp_logger_type
      41              :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      42              :                                               cp_print_key_unit_nr
      43              :    USE input_constants,                 ONLY: &
      44              :         do_analytic, xc_funct_b3lyp, xc_funct_beefvdw, xc_funct_blyp, xc_funct_bp, &
      45              :         xc_funct_hcth120, xc_funct_no_shortcut, xc_funct_olyp, xc_funct_pade, xc_funct_pbe, &
      46              :         xc_funct_pbe0, xc_funct_tpss, xc_none
      47              :    USE input_section_types,             ONLY: section_vals_get,&
      48              :                                               section_vals_get_subs_vals,&
      49              :                                               section_vals_type,&
      50              :                                               section_vals_val_get
      51              :    USE kinds,                           ONLY: default_string_length,&
      52              :                                               dp
      53              :    USE mathconstants,                   ONLY: dfac,&
      54              :                                               fourpi,&
      55              :                                               gamma1,&
      56              :                                               rootpi
      57              :    USE periodic_table,                  ONLY: nelem,&
      58              :                                               ptable
      59              :    USE physcon,                         ONLY: bohr
      60              : #include "./base/base_uses.f90"
      61              : 
      62              :    IMPLICIT NONE
      63              :    PRIVATE
      64              :    PUBLIC  :: atom_energy_opt
      65              : 
      66              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'atom_energy'
      67              : 
      68              : CONTAINS
      69              : 
      70              : ! **************************************************************************************************
      71              : !> \brief Compute the atomic energy.
      72              : !> \param atom_section  ATOM input section
      73              : !> \par History
      74              : !>    * 11.2016 geometrical response basis set [Juerg Hutter]
      75              : !>    * 07.2016 ADMM analysis [Juerg Hutter]
      76              : !>    * 02.2014 non-additive kinetic energy term [Juerg Hutter]
      77              : !>    * 11.2013 Zhao, Morrison, and Parr (ZMP) potential [Daniele Varsano]
      78              : !>    * 02.2010 unrestricted KS and HF methods [Juerg Hutter]
      79              : !>    * 05.2009 electronic density fit [Juerg Hutter]
      80              : !>    * 04.2009 refactored and renamed to atom_energy_opt() [Juerg Hutter]
      81              : !>    * 08.2008 created as atom_energy() [Juerg Hutter]
      82              : ! **************************************************************************************************
      83          326 :    SUBROUTINE atom_energy_opt(atom_section)
      84              :       TYPE(section_vals_type), POINTER                   :: atom_section
      85              : 
      86              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'atom_energy_opt'
      87              : 
      88              :       CHARACTER(LEN=2)                                   :: elem
      89              :       CHARACTER(LEN=default_string_length)               :: filename, xcfstr
      90              :       CHARACTER(LEN=default_string_length), &
      91          326 :          DIMENSION(:), POINTER                           :: tmpstringlist
      92              :       INTEGER :: do_eric, do_erie, handle, i, im, in, iw, k, maxl, mb, method, mo, n_meth, n_rep, &
      93              :          nder, nr_gh, num_gau, num_gto, num_pol, reltyp, shortcut, zcore, zval, zz
      94              :       INTEGER, DIMENSION(0:lmat)                         :: maxn
      95          326 :       INTEGER, DIMENSION(:), POINTER                     :: cn
      96              :       LOGICAL                                            :: dm, do_gh, do_zmp, doread, eri_c, eri_e, &
      97              :                                                             explicit, graph, had_ae, had_pp, &
      98              :                                                             lcomp, lcond, pp_calc, read_vxc
      99              :       REAL(KIND=dp)                                      :: crad, delta, lambda
     100          326 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: ext_density, ext_vxc
     101              :       REAL(KIND=dp), DIMENSION(0:lmat, 10)               :: pocc
     102              :       TYPE(atom_basis_type), POINTER                     :: ae_basis, pp_basis
     103              :       TYPE(atom_integrals), POINTER                      :: ae_int, pp_int
     104              :       TYPE(atom_optimization_type)                       :: optimization
     105              :       TYPE(atom_orbitals), POINTER                       :: orbitals
     106          326 :       TYPE(atom_p_type), DIMENSION(:, :), POINTER        :: atom_info
     107              :       TYPE(atom_potential_type), POINTER                 :: ae_pot, p_pot
     108              :       TYPE(atom_state), POINTER                          :: state
     109              :       TYPE(cp_logger_type), POINTER                      :: logger
     110              :       TYPE(section_vals_type), POINTER :: admm_section, basis_section, external_vxc_section, &
     111              :          method_section, opt_section, potential_section, powell_section, sgp_section, xc_func, &
     112              :          xc_section, zmp_restart_section, zmp_section
     113              : 
     114          326 :       CALL timeset(routineN, handle)
     115              : 
     116              :       ! What atom do we calculate
     117          326 :       CALL section_vals_val_get(atom_section, "ATOMIC_NUMBER", i_val=zval)
     118          326 :       CALL section_vals_val_get(atom_section, "ELEMENT", c_val=elem)
     119          326 :       zz = 0
     120        11732 :       DO i = 1, nelem
     121        11732 :          IF (ptable(i)%symbol == elem) THEN
     122              :             zz = i
     123              :             EXIT
     124              :          END IF
     125              :       END DO
     126          326 :       IF (zz /= 1) zval = zz
     127              : 
     128              :       ! read and set up inofrmation on the basis sets
     129        12062 :       ALLOCATE (ae_basis, pp_basis)
     130          326 :       basis_section => section_vals_get_subs_vals(atom_section, "AE_BASIS")
     131          326 :       NULLIFY (ae_basis%grid)
     132          326 :       CALL init_atom_basis(ae_basis, basis_section, zval, "AE")
     133          326 :       NULLIFY (pp_basis%grid)
     134          326 :       basis_section => section_vals_get_subs_vals(atom_section, "PP_BASIS")
     135          326 :       CALL init_atom_basis(pp_basis, basis_section, zval, "PP")
     136              : 
     137              :       ! print general and basis set information
     138          326 :       logger => cp_get_default_logger()
     139          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%PROGRAM_BANNER", extension=".log")
     140          326 :       IF (iw > 0) CALL atom_print_info(zval, "Atomic Energy Calculation", iw)
     141          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%PROGRAM_BANNER")
     142          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%BASIS_SET", extension=".log")
     143          326 :       IF (iw > 0) THEN
     144            0 :          CALL atom_print_basis(ae_basis, iw, " All Electron Basis")
     145            0 :          CALL atom_print_basis(pp_basis, iw, " Pseudopotential Basis")
     146              :       END IF
     147          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%BASIS_SET")
     148              : 
     149              :       ! read and setup information on the pseudopotential
     150          326 :       NULLIFY (potential_section)
     151          326 :       potential_section => section_vals_get_subs_vals(atom_section, "POTENTIAL")
     152      3506782 :       ALLOCATE (ae_pot, p_pot)
     153          326 :       CALL init_atom_potential(p_pot, potential_section, zval)
     154          326 :       CALL init_atom_potential(ae_pot, potential_section, -1)
     155              : 
     156              :       ! if the ERI's are calculated analytically, we have to precalculate them
     157          326 :       eri_c = .FALSE.
     158          326 :       CALL section_vals_val_get(atom_section, "COULOMB_INTEGRALS", i_val=do_eric)
     159          326 :       IF (do_eric == do_analytic) eri_c = .TRUE.
     160          326 :       eri_e = .FALSE.
     161          326 :       CALL section_vals_val_get(atom_section, "EXCHANGE_INTEGRALS", i_val=do_erie)
     162          326 :       IF (do_erie == do_analytic) eri_e = .TRUE.
     163          326 :       CALL section_vals_val_get(atom_section, "USE_GAUSS_HERMITE", l_val=do_gh)
     164          326 :       CALL section_vals_val_get(atom_section, "GRID_POINTS_GH", i_val=nr_gh)
     165              : 
     166              :       ! information on the states to be calculated
     167          326 :       CALL section_vals_val_get(atom_section, "MAX_ANGULAR_MOMENTUM", i_val=maxl)
     168          326 :       maxn = 0
     169          326 :       CALL section_vals_val_get(atom_section, "CALCULATE_STATES", i_vals=cn)
     170          688 :       DO in = 1, MIN(SIZE(cn), 4)
     171          688 :          maxn(in - 1) = cn(in)
     172              :       END DO
     173         2282 :       DO in = 0, lmat
     174         1956 :          maxn(in) = MIN(maxn(in), ae_basis%nbas(in))
     175         2282 :          maxn(in) = MIN(maxn(in), pp_basis%nbas(in))
     176              :       END DO
     177              : 
     178              :       ! read optimization section
     179          326 :       opt_section => section_vals_get_subs_vals(atom_section, "OPTIMIZATION")
     180          326 :       CALL read_atom_opt_section(optimization, opt_section)
     181              : 
     182          326 :       had_ae = .FALSE.
     183          326 :       had_pp = .FALSE.
     184              : 
     185              :       ! Check for the total number of electron configurations to be calculated
     186          326 :       CALL section_vals_val_get(atom_section, "ELECTRON_CONFIGURATION", n_rep_val=n_rep)
     187              :       ! Check for the total number of method types to be calculated
     188          326 :       method_section => section_vals_get_subs_vals(atom_section, "METHOD")
     189          326 :       CALL section_vals_get(method_section, n_repetition=n_meth)
     190              : 
     191              :       ! integrals
     192       138550 :       ALLOCATE (ae_int, pp_int)
     193              : 
     194         1962 :       ALLOCATE (atom_info(n_rep, n_meth))
     195              : 
     196          658 :       DO in = 1, n_rep
     197          990 :          DO im = 1, n_meth
     198              : 
     199          332 :             NULLIFY (atom_info(in, im)%atom)
     200          332 :             CALL create_atom_type(atom_info(in, im)%atom)
     201              : 
     202          332 :             atom_info(in, im)%atom%optimization = optimization
     203              : 
     204          332 :             atom_info(in, im)%atom%z = zval
     205              : 
     206          332 :             xc_section => section_vals_get_subs_vals(method_section, "XC", i_rep_section=im)
     207          332 :             atom_info(in, im)%atom%xc_section => xc_section
     208              : 
     209              :             ! Retrieve the XC functional string for upf output
     210              :             ! This does not work within the routine atom_write_upf below for unknown reasons
     211          332 :             xc_func => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     212          332 :             CALL section_vals_get(xc_func, explicit=explicit)
     213          332 :             IF (explicit) THEN
     214          308 :                CALL section_vals_val_get(xc_func, "_SECTION_PARAMETERS_", i_val=shortcut)
     215           78 :                SELECT CASE (shortcut)
     216              :                CASE (xc_funct_no_shortcut, xc_none)
     217           78 :                   xcfstr = "NONE"
     218              :                CASE (xc_funct_pbe0)
     219           26 :                   xcfstr = "PBE0"
     220              :                CASE (xc_funct_beefvdw)
     221            0 :                   xcfstr = "BEEFVDW"
     222              :                CASE (xc_funct_b3lyp)
     223           16 :                   xcfstr = "B3LYP"
     224              :                CASE (xc_funct_blyp)
     225           58 :                   xcfstr = "BLYP"
     226              :                CASE (xc_funct_bp)
     227            0 :                   xcfstr = "BP"
     228              :                CASE (xc_funct_pade)
     229           62 :                   xcfstr = "PADE"
     230              :                CASE (xc_funct_pbe)
     231           54 :                   xcfstr = "PBE"
     232              :                CASE (xc_funct_tpss)
     233           10 :                   xcfstr = "TPSS"
     234              :                CASE (xc_funct_olyp)
     235            2 :                   xcfstr = "OLYP"
     236              :                CASE (xc_funct_hcth120)
     237            2 :                   xcfstr = "HCTH120"
     238              :                CASE DEFAULT
     239          308 :                   xcfstr = "DFT"
     240              :                END SELECT
     241              :             ELSE
     242           24 :                xcfstr = "DFT"
     243              :             END IF
     244              : 
     245              :             ! ZMP Reading input sections if they are found initialize everything
     246              :             do_zmp = .FALSE.
     247              :             doread = .FALSE.
     248              :             read_vxc = .FALSE.
     249              : 
     250          332 :             zmp_section => section_vals_get_subs_vals(method_section, "ZMP")
     251          332 :             CALL section_vals_get(zmp_section, explicit=do_zmp)
     252          332 :             atom_info(in, im)%atom%do_zmp = do_zmp
     253          332 :             CALL section_vals_val_get(zmp_section, "FILE_DENSITY", c_val=filename)
     254          332 :             atom_info(in, im)%atom%ext_file = filename
     255              :             CALL section_vals_val_get(zmp_section, "GRID_TOL", &
     256          332 :                                       r_val=atom_info(in, im)%atom%zmpgrid_tol)
     257          332 :             CALL section_vals_val_get(zmp_section, "LAMBDA", r_val=lambda)
     258          332 :             atom_info(in, im)%atom%lambda = lambda
     259          332 :             CALL section_vals_val_get(zmp_section, "DM", l_val=dm)
     260          332 :             atom_info(in, im)%atom%dm = dm
     261              : 
     262          332 :             zmp_restart_section => section_vals_get_subs_vals(zmp_section, "RESTART")
     263          332 :             CALL section_vals_get(zmp_restart_section, explicit=doread)
     264          332 :             atom_info(in, im)%atom%doread = doread
     265          332 :             CALL section_vals_val_get(zmp_restart_section, "FILE_RESTART", c_val=filename)
     266          332 :             atom_info(in, im)%atom%zmp_restart_file = filename
     267              : 
     268              :             ! ZMP Reading external vxc section, if found initialize
     269          332 :             external_vxc_section => section_vals_get_subs_vals(method_section, "EXTERNAL_VXC")
     270          332 :             CALL section_vals_get(external_vxc_section, explicit=read_vxc)
     271          332 :             atom_info(in, im)%atom%read_vxc = read_vxc
     272          332 :             CALL section_vals_val_get(external_vxc_section, "FILE_VXC", c_val=filename)
     273          332 :             atom_info(in, im)%atom%ext_vxc_file = filename
     274              :             CALL section_vals_val_get(external_vxc_section, "GRID_TOL", &
     275          332 :                                       r_val=atom_info(in, im)%atom%zmpvxcgrid_tol)
     276              : 
     277       120516 :             ALLOCATE (state)
     278              : 
     279              :             ! get the electronic configuration
     280              :             CALL section_vals_val_get(atom_section, "ELECTRON_CONFIGURATION", i_rep_val=in, &
     281          332 :                                       c_vals=tmpstringlist)
     282              : 
     283              :             ! set occupations
     284          332 :             CALL atom_set_occupation(tmpstringlist, state%occ, state%occupation, state%multiplicity)
     285          332 :             state%maxl_occ = get_maxl_occ(state%occ)
     286         2324 :             state%maxn_occ = get_maxn_occ(state%occ)
     287              : 
     288              :             ! set number of states to be calculated
     289          332 :             state%maxl_calc = MAX(maxl, state%maxl_occ)
     290          332 :             state%maxl_calc = MIN(lmat, state%maxl_calc)
     291         2324 :             state%maxn_calc = 0
     292         1534 :             DO k = 0, state%maxl_calc
     293         1534 :                state%maxn_calc(k) = MAX(maxn(k), state%maxn_occ(k))
     294              :             END DO
     295              : 
     296              :             ! is there a pseudo potential
     297         1106 :             pp_calc = ANY(INDEX(tmpstringlist(1:), "CORE") /= 0)
     298          332 :             IF (pp_calc) THEN
     299              :                ! get and set the core occupations
     300           74 :                CALL section_vals_val_get(atom_section, "CORE", c_vals=tmpstringlist)
     301           74 :                CALL atom_set_occupation(tmpstringlist, state%core, pocc)
     302         5254 :                zcore = zval - NINT(SUM(state%core))
     303           74 :                CALL set_atom(atom_info(in, im)%atom, zcore=zcore, pp_calc=.TRUE.)
     304              :             ELSE
     305        18318 :                state%core = 0._dp
     306          258 :                CALL set_atom(atom_info(in, im)%atom, zcore=zval, pp_calc=.FALSE.)
     307              :             END IF
     308              : 
     309          332 :             CALL section_vals_val_get(method_section, "METHOD_TYPE", i_val=method, i_rep_section=im)
     310          332 :             CALL section_vals_val_get(method_section, "RELATIVISTIC", i_val=reltyp, i_rep_section=im)
     311          332 :             CALL set_atom(atom_info(in, im)%atom, method_type=method, relativistic=reltyp)
     312              : 
     313          332 :             IF (atom_consistent_method(method, state%multiplicity)) THEN
     314          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%METHOD_INFO", extension=".log")
     315          332 :                CALL atom_print_method(atom_info(in, im)%atom, iw)
     316          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%METHOD_INFO")
     317              : 
     318          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%POTENTIAL", extension=".log")
     319          332 :                IF (pp_calc) THEN
     320           74 :                   IF (iw > 0) CALL atom_print_potential(p_pot, iw)
     321              :                ELSE
     322          258 :                   IF (iw > 0) CALL atom_print_potential(ae_pot, iw)
     323              :                END IF
     324          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%POTENTIAL")
     325              :             END IF
     326              : 
     327              :             ! calculate integrals
     328          332 :             IF (pp_calc) THEN
     329              :                ! general integrals
     330              :                CALL atom_int_setup(pp_int, pp_basis, &
     331           74 :                                    potential=p_pot, eri_coulomb=eri_c, eri_exchange=eri_e)
     332              :                ! potential
     333           74 :                CALL atom_ppint_setup(pp_int, pp_basis, potential=p_pot)
     334              :                !
     335           74 :                NULLIFY (pp_int%tzora, pp_int%hdkh)
     336              :                !
     337           74 :                CALL set_atom(atom_info(in, im)%atom, basis=pp_basis, integrals=pp_int, potential=p_pot)
     338          962 :                state%maxn_calc(:) = MIN(state%maxn_calc(:), pp_basis%nbas(:))
     339          518 :                CPASSERT(ALL(state%maxn_calc(:) >= state%maxn_occ))
     340              :                had_pp = .TRUE.
     341              :             ELSE
     342              :                ! general integrals
     343              :                CALL atom_int_setup(ae_int, ae_basis, potential=ae_pot, &
     344          258 :                                    eri_coulomb=eri_c, eri_exchange=eri_e)
     345              :                ! potential
     346          258 :                CALL atom_ppint_setup(ae_int, ae_basis, potential=ae_pot)
     347              :                ! relativistic correction terms
     348          258 :                CALL atom_relint_setup(ae_int, ae_basis, reltyp, zcore=REAL(zval, dp))
     349              :                !
     350          258 :                CALL set_atom(atom_info(in, im)%atom, basis=ae_basis, integrals=ae_int, potential=ae_pot)
     351         3354 :                state%maxn_calc(:) = MIN(state%maxn_calc(:), ae_basis%nbas(:))
     352         1806 :                CPASSERT(ALL(state%maxn_calc(:) >= state%maxn_occ))
     353              :                had_ae = .TRUE.
     354              :             END IF
     355              : 
     356          332 :             CALL set_atom(atom_info(in, im)%atom, state=state)
     357              : 
     358              :             CALL set_atom(atom_info(in, im)%atom, coulomb_integral_type=do_eric, &
     359          332 :                           exchange_integral_type=do_erie)
     360          332 :             atom_info(in, im)%atom%hfx_pot%do_gh = do_gh
     361          332 :             atom_info(in, im)%atom%hfx_pot%nr_gh = nr_gh
     362              : 
     363          332 :             NULLIFY (orbitals)
     364         2324 :             mo = MAXVAL(state%maxn_calc)
     365         2324 :             mb = MAXVAL(atom_info(in, im)%atom%basis%nbas)
     366          332 :             CALL create_atom_orbs(orbitals, mb, mo)
     367          332 :             CALL set_atom(atom_info(in, im)%atom, orbitals=orbitals)
     368              : 
     369         2656 :             IF (atom_consistent_method(method, state%multiplicity)) THEN
     370              :                !Calculate the electronic structure
     371          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%SCF_INFO", extension=".log")
     372          332 :                CALL calculate_atom(atom_info(in, im)%atom, iw)
     373          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%SCF_INFO")
     374              : 
     375              :                ! ZMP If we have the external density do zmp
     376          332 :                IF (atom_info(in, im)%atom%do_zmp) THEN
     377            0 :                   CALL atom_write_zmp_restart(atom_info(in, im)%atom)
     378              : 
     379            0 :                   ALLOCATE (ext_density(atom_info(in, im)%atom%basis%grid%nr))
     380            0 :                   ext_density = 0._dp
     381            0 :                   CALL atom_read_external_density(ext_density, atom_info(in, im)%atom, iw)
     382              :                   CALL calculate_atom_zmp(ext_density=ext_density, &
     383              :                                           atom=atom_info(in, im)%atom, &
     384            0 :                                           lprint=.TRUE.)
     385            0 :                   DEALLOCATE (ext_density)
     386              :                END IF
     387              :                ! ZMP If we have the external v_xc calculate KS quantities
     388          332 :                IF (atom_info(in, im)%atom%read_vxc) THEN
     389            0 :                   ALLOCATE (ext_vxc(atom_info(in, im)%atom%basis%grid%nr))
     390            0 :                   ext_vxc = 0._dp
     391            0 :                   CALL atom_read_external_vxc(ext_vxc, atom_info(in, im)%atom, iw)
     392              :                   CALL calculate_atom_ext_vxc(vxc=ext_vxc, &
     393              :                                               atom=atom_info(in, im)%atom, &
     394            0 :                                               lprint=.TRUE.)
     395            0 :                   DEALLOCATE (ext_vxc)
     396              :                END IF
     397              : 
     398              :                ! Print out the orbitals if requested
     399          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ORBITALS", extension=".log")
     400          332 :                CALL section_vals_val_get(atom_section, "PRINT%ORBITALS%XMGRACE", l_val=graph)
     401          332 :                IF (iw > 0) THEN
     402            0 :                   CALL atom_print_orbitals(atom_info(in, im)%atom, iw, xmgrace=graph)
     403              :                END IF
     404          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ORBITALS")
     405              : 
     406              :                ! generate a UPF file
     407              :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%UPF_FILE", extension=".upf", &
     408          332 :                                          file_position="REWIND")
     409          332 :                IF (iw > 0) THEN
     410            3 :                   CALL atom_write_upf(atom_info(in, im)%atom, iw, xcfstr)
     411              :                END IF
     412          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%UPF_FILE")
     413              : 
     414              :                ! perform a fit of the total electronic density
     415          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%FIT_DENSITY", extension=".log")
     416          332 :                IF (iw > 0) THEN
     417            0 :                   CALL section_vals_val_get(atom_section, "PRINT%FIT_DENSITY%NUM_GTO", i_val=num_gto)
     418            0 :                   powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
     419            0 :                   CALL atom_fit_density(atom_info(in, im)%atom, num_gto, 0, iw, powell_section=powell_section)
     420              :                END IF
     421          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%FIT_DENSITY")
     422              : 
     423              :                ! Optimize a local potential for the non-additive kinetic energy term in KG
     424          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%FIT_KGPOT", extension=".log")
     425          332 :                IF (iw > 0) THEN
     426            1 :                   CALL section_vals_val_get(atom_section, "PRINT%FIT_KGPOT%NUM_GAUSSIAN", i_val=num_gau)
     427            1 :                   CALL section_vals_val_get(atom_section, "PRINT%FIT_KGPOT%NUM_POLYNOM", i_val=num_pol)
     428            1 :                   powell_section => section_vals_get_subs_vals(atom_section, "POWELL")
     429            1 :                   CALL atom_fit_kgpot(atom_info(in, im)%atom, num_gau, num_pol, iw, powell_section=powell_section)
     430              :                END IF
     431          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%FIT_KGPOT")
     432              : 
     433              :                ! generate a response basis
     434          332 :                iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%RESPONSE_BASIS", extension=".log")
     435          332 :                IF (iw > 0) THEN
     436            1 :                   CALL section_vals_val_get(atom_section, "PRINT%RESPONSE_BASIS%DELTA_CHARGE", r_val=delta)
     437            1 :                   CALL section_vals_val_get(atom_section, "PRINT%RESPONSE_BASIS%DERIVATIVES", i_val=nder)
     438            1 :                   CALL atom_response_basis(atom_info(in, im)%atom, delta, nder, iw)
     439              :                END IF
     440          332 :                CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%RESPONSE_BASIS")
     441              : 
     442              :             END IF
     443              : 
     444              :          END DO
     445              :       END DO
     446              : 
     447              :       ! generate a geometrical response basis (GRB)
     448          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS", extension=".log")
     449          326 :       IF (iw > 0) THEN
     450            2 :          CALL atom_grb_construction(atom_info, atom_section, iw)
     451              :       END IF
     452          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%GEOMETRICAL_RESPONSE_BASIS")
     453              : 
     454              :       ! Analyze basis sets
     455          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ANALYZE_BASIS", extension=".log")
     456          326 :       IF (iw > 0) THEN
     457            3 :          CALL section_vals_val_get(atom_section, "PRINT%ANALYZE_BASIS%OVERLAP_CONDITION_NUMBER", l_val=lcond)
     458            3 :          CALL section_vals_val_get(atom_section, "PRINT%ANALYZE_BASIS%COMPLETENESS", l_val=lcomp)
     459            3 :          crad = ptable(zval)%covalent_radius*bohr
     460            3 :          IF (had_ae) THEN
     461            2 :             IF (lcond) CALL atom_condnumber(ae_basis, crad, iw)
     462            2 :             IF (lcomp) CALL atom_completeness(ae_basis, zval, iw)
     463              :          END IF
     464            3 :          IF (had_pp) THEN
     465            1 :             IF (lcond) CALL atom_condnumber(pp_basis, crad, iw)
     466            1 :             IF (lcomp) CALL atom_completeness(pp_basis, zval, iw)
     467              :          END IF
     468              :       END IF
     469          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ANALYZE_BASIS")
     470              : 
     471              :       ! Analyse ADMM approximation
     472          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%ADMM", extension=".log")
     473          326 :       admm_section => section_vals_get_subs_vals(atom_section, "PRINT%ADMM")
     474          326 :       IF (iw > 0) THEN
     475            1 :          CALL atom_admm(atom_info, admm_section, iw)
     476              :       END IF
     477          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%ADMM")
     478              : 
     479              :       ! Generate a separable form of the pseudopotential using Gaussian functions
     480          326 :       iw = cp_print_key_unit_nr(logger, atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO", extension=".log")
     481          326 :       sgp_section => section_vals_get_subs_vals(atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO")
     482          326 :       IF (iw > 0) THEN
     483            5 :          CALL atom_sgp_construction(atom_info, sgp_section, iw)
     484              :       END IF
     485          326 :       CALL cp_print_key_finished_output(iw, logger, atom_section, "PRINT%SEPARABLE_GAUSSIAN_PSEUDO")
     486              : 
     487              :       ! clean up
     488          326 :       IF (had_ae) THEN
     489          256 :          CALL atom_int_release(ae_int)
     490          256 :          CALL atom_ppint_release(ae_int)
     491          256 :          CALL atom_relint_release(ae_int)
     492              :       END IF
     493          326 :       IF (had_pp) THEN
     494           72 :          CALL atom_int_release(pp_int)
     495           72 :          CALL atom_ppint_release(pp_int)
     496           72 :          CALL atom_relint_release(pp_int)
     497              :       END IF
     498          326 :       CALL release_atom_basis(ae_basis)
     499          326 :       CALL release_atom_basis(pp_basis)
     500              : 
     501          326 :       CALL release_atom_potential(p_pot)
     502          326 :       CALL release_atom_potential(ae_pot)
     503              : 
     504          658 :       DO in = 1, n_rep
     505          990 :          DO im = 1, n_meth
     506          664 :             CALL release_atom_type(atom_info(in, im)%atom)
     507              :          END DO
     508              :       END DO
     509          326 :       DEALLOCATE (atom_info)
     510              : 
     511          326 :       DEALLOCATE (ae_pot, p_pot, ae_basis, pp_basis, ae_int, pp_int)
     512              : 
     513          326 :       CALL timestop(handle)
     514              : 
     515         2282 :    END SUBROUTINE atom_energy_opt
     516              : 
     517              : ! **************************************************************************************************
     518              : !> \brief Calculate response basis contraction coefficients.
     519              : !> \param atom   information about the atomic kind
     520              : !> \param delta  variation of charge used in finite difference derivative calculation
     521              : !> \param nder   number of wavefunction derivatives to calculate
     522              : !> \param iw     output file unit
     523              : !> \par History
     524              : !>    * 10.2011 Gram-Schmidt orthogonalization [Joost VandeVondele]
     525              : !>    * 05.2009 created [Juerg Hutter]
     526              : ! **************************************************************************************************
     527            1 :    SUBROUTINE atom_response_basis(atom, delta, nder, iw)
     528              : 
     529              :       TYPE(atom_type), POINTER                           :: atom
     530              :       REAL(KIND=dp), INTENT(IN)                          :: delta
     531              :       INTEGER, INTENT(IN)                                :: nder, iw
     532              : 
     533              :       INTEGER                                            :: i, ider, j, k, l, lhomo, m, n, nhomo, &
     534              :                                                             s1, s2
     535              :       REAL(KIND=dp)                                      :: dene, emax, expzet, fhomo, o, prefac, &
     536              :                                                             zeta
     537            1 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: amat
     538            1 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :)     :: rbasis
     539            1 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :)  :: wfn
     540            1 :       REAL(KIND=dp), DIMENSION(:, :, :), POINTER         :: ovlp
     541              :       TYPE(atom_state), POINTER                          :: state
     542              : 
     543            1 :       WRITE (iw, '(/," ",79("*"),/,T30,A,A/," ",79("*"))') "RESPONSE BASIS for ", ptable(atom%z)%symbol
     544              : 
     545            1 :       state => atom%state
     546            1 :       ovlp => atom%integrals%ovlp
     547              : 
     548              :       ! find HOMO
     549            1 :       lhomo = -1
     550            1 :       nhomo = -1
     551            1 :       emax = -HUGE(1._dp)
     552            4 :       DO l = 0, state%maxl_occ
     553            6 :          DO i = 1, state%maxn_occ(l)
     554            5 :             IF (atom%orbitals%ener(i, l) > emax) THEN
     555            1 :                lhomo = l
     556            1 :                nhomo = i
     557            1 :                emax = atom%orbitals%ener(i, l)
     558            1 :                fhomo = state%occupation(l, i)
     559              :             END IF
     560              :          END DO
     561              :       END DO
     562              : 
     563            1 :       s1 = SIZE(atom%orbitals%wfn, 1)
     564            1 :       s2 = SIZE(atom%orbitals%wfn, 2)
     565            6 :       ALLOCATE (wfn(s1, s2, 0:lmat, -nder:nder))
     566            7 :       s2 = MAXVAL(state%maxn_occ) + nder
     567            5 :       ALLOCATE (rbasis(s1, s2, 0:lmat))
     568           91 :       rbasis = 0._dp
     569              : 
     570            4 :       DO ider = -nder, nder
     571            3 :          dene = REAL(ider, KIND=dp)*delta
     572            3 :          CPASSERT(fhomo > ABS(dene))
     573            3 :          state%occupation(lhomo, nhomo) = fhomo + dene
     574            3 :          CALL calculate_atom(atom, iw=0, noguess=.TRUE.)
     575          147 :          wfn(:, :, :, ider) = atom%orbitals%wfn
     576            4 :          state%occupation(lhomo, nhomo) = fhomo
     577              :       END DO
     578              :       ! reset
     579            1 :       CALL calculate_atom(atom, iw=0, noguess=.TRUE.)
     580              : 
     581            4 :       DO l = 0, state%maxl_occ
     582              :          ! occupied states
     583            6 :          DO i = 1, MAX(state%maxn_occ(l), 1)
     584           24 :             rbasis(:, i, l) = wfn(:, i, l, 0)
     585              :          END DO
     586              :          ! differentiation
     587            6 :          DO ider = 1, nder
     588            3 :             i = MAX(state%maxn_occ(l), 1)
     589            3 :             SELECT CASE (ider)
     590              :             CASE (1)
     591           21 :                rbasis(:, i + 1, l) = 0.5_dp*(wfn(:, i, l, 1) - wfn(:, i, l, -1))/delta
     592              :             CASE (2)
     593            0 :                rbasis(:, i + 2, l) = 0.25_dp*(wfn(:, i, l, 2) - 2._dp*wfn(:, i, l, 0) + wfn(:, i, l, -2))/delta**2
     594              :             CASE (3)
     595              :                rbasis(:, i + 3, l) = 0.125_dp*(wfn(:, i, l, 3) - 3._dp*wfn(:, i, l, 1) &
     596            0 :                                                + 3._dp*wfn(:, i, l, -1) - wfn(:, i, l, -3))/delta**3
     597              :             CASE DEFAULT
     598            3 :                CPABORT("")
     599              :             END SELECT
     600              :          END DO
     601              : 
     602              :          ! orthogonalization, use gram-schmidt in order to keep the natural order (semi-core, valence, response) of the wfn.
     603            3 :          n = state%maxn_occ(l) + nder
     604            3 :          m = atom%basis%nbas(l)
     605            8 :          DO i = 1, n
     606            7 :             DO j = 1, i - 1
     607          192 :                o = DOT_PRODUCT(rbasis(1:m, j, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), [m]))
     608           19 :                rbasis(1:m, i, l) = rbasis(1:m, i, l) - o*rbasis(1:m, j, l)
     609              :             END DO
     610          480 :             o = DOT_PRODUCT(rbasis(1:m, i, l), RESHAPE(MATMUL(ovlp(1:m, 1:m, l), rbasis(1:m, i:i, l)), [m]))
     611           38 :             rbasis(1:m, i, l) = rbasis(1:m, i, l)/SQRT(o)
     612              :          END DO
     613              : 
     614              :          ! check
     615           12 :          ALLOCATE (amat(n, n))
     616          578 :          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)))
     617            8 :          DO i = 1, n
     618            8 :             amat(i, i) = amat(i, i) - 1._dp
     619              :          END DO
     620           17 :          IF (MAXVAL(ABS(amat)) > 1.e-12) THEN
     621            0 :             WRITE (iw, '(/,A,G20.10)') " Orthogonality error  ", MAXVAL(ABS(amat))
     622              :          END IF
     623            3 :          DEALLOCATE (amat)
     624              : 
     625              :          ! Quickstep normalization
     626            3 :          WRITE (iw, '(/,A,T30,I3)') " Angular momentum :", l
     627              : 
     628            3 :          WRITE (iw, '(/,A,I0,A,I0,A)') "             Exponent     Coef.(Quickstep Normalization), first ", &
     629            6 :             n - nder, " valence ", nder, " response"
     630            3 :          expzet = 0.25_dp*REAL(2*l + 3, dp)
     631            3 :          prefac = SQRT(rootpi/2._dp**(l + 2)*dfac(2*l + 1))
     632           22 :          DO i = 1, m
     633           18 :             zeta = (2._dp*atom%basis%am(i, l))**expzet
     634           51 :             WRITE (iw, '(4X,F20.10,4X,15ES20.6)') atom%basis%am(i, l), ((prefac*rbasis(i, k, l)/zeta), k=1, n)
     635              :          END DO
     636              : 
     637              :       END DO
     638              : 
     639            1 :       DEALLOCATE (wfn, rbasis)
     640              : 
     641            1 :       WRITE (iw, '(" ",79("*"))')
     642              : 
     643            2 :    END SUBROUTINE atom_response_basis
     644              : 
     645              : ! **************************************************************************************************
     646              : !> \brief Write pseudo-potential in Quantum Espresso UPF format.
     647              : !> \param atom  information about the atomic kind
     648              : !> \param iw    output file unit
     649              : !> \param xcfstr ...
     650              : !> \par History
     651              : !>    * 09.2012 created [Juerg Hutter]
     652              : ! **************************************************************************************************
     653            3 :    SUBROUTINE atom_write_upf(atom, iw, xcfstr)
     654              : 
     655              :       TYPE(atom_type), POINTER                           :: atom
     656              :       INTEGER, INTENT(IN)                                :: iw
     657              :       CHARACTER(LEN=*), INTENT(IN)                       :: xcfstr
     658              : 
     659              :       CHARACTER(LEN=default_string_length)               :: string
     660              :       INTEGER                                            :: i, ibeta, ii, j, k, kk, l, lmax, n0, &
     661              :                                                             nbeta, nr, nwfc, nwfn
     662              :       LOGICAL                                            :: soc, up
     663              :       REAL(KIND=dp)                                      :: occa, occb, pf, rhoatom, rl, rlp, rmax, &
     664              :                                                             vnlm, vnlp
     665            3 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: beta, corden, dens, ef, locpot, rp
     666            3 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: dij
     667              :       TYPE(atom_gthpot_type), POINTER                    :: pot
     668              : 
     669            3 :       IF (.NOT. atom%pp_calc) RETURN
     670            3 :       IF (atom%potential%ppot_type /= gth_pseudo) RETURN
     671            3 :       pot => atom%potential%gth_pot
     672            3 :       CPASSERT(.NOT. pot%lsdpot)
     673            3 :       soc = pot%soc
     674              : 
     675            3 :       WRITE (iw, '(A)') '<UPF version="2.0.1">'
     676              : 
     677            3 :       WRITE (iw, '(T4,A)') '<PP_INFO>'
     678            3 :       WRITE (iw, '(T8,A)') 'Converted from CP2K GTH format'
     679            3 :       WRITE (iw, '(T8,A)') '<PP_INPUTFILE>'
     680            3 :       CALL atom_write_pseudo_param(pot, iw)
     681            3 :       WRITE (iw, '(T8,A)') '</PP_INPUTFILE>'
     682            3 :       WRITE (iw, '(T4,A)') '</PP_INFO>'
     683            3 :       WRITE (iw, '(T4,A)') '<PP_HEADER'
     684            3 :       WRITE (iw, '(T8,A)') 'generated="Generated in analytical, separable form"'
     685            3 :       WRITE (iw, '(T8,A)') 'author="Goedecker/Hartwigsen/Hutter/Teter"'
     686            3 :       WRITE (iw, '(T8,A)') 'date="Phys.Rev.B58, 3641 (1998); B54, 1703 (1996)"'
     687            3 :       WRITE (iw, '(T8,A)') 'comment="This file generated by CP2K ATOM code"'
     688            3 :       CALL compose(string, "element", cval=pot%symbol)
     689            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     690            3 :       WRITE (iw, '(T8,A)') 'pseudo_type="NC"'
     691            3 :       WRITE (iw, '(T8,A)') 'relativistic="no"'
     692            3 :       WRITE (iw, '(T8,A)') 'is_ultrasoft="F"'
     693            3 :       WRITE (iw, '(T8,A)') 'is_paw="F"'
     694            3 :       WRITE (iw, '(T8,A)') 'is_coulomb="F"'
     695            3 :       IF (soc) THEN
     696            1 :          WRITE (iw, '(T8,A)') 'has_so="T"'
     697              :       ELSE
     698            2 :          WRITE (iw, '(T8,A)') 'has_so="F"'
     699              :       END IF
     700            3 :       WRITE (iw, '(T8,A)') 'has_wfc="F"'
     701            3 :       WRITE (iw, '(T8,A)') 'has_gipaw="F"'
     702            3 :       WRITE (iw, '(T8,A)') 'paw_as_gipaw="F"'
     703            3 :       IF (pot%nlcc) THEN
     704            1 :          WRITE (iw, '(T8,A)') 'core_correction="T"'
     705              :       ELSE
     706            2 :          WRITE (iw, '(T8,A)') 'core_correction="F"'
     707              :       END IF
     708            3 :       WRITE (iw, '(T8,A)') 'functional="'//TRIM(ADJUSTL(xcfstr))//'"'
     709            3 :       CALL compose(string, "z_valence", rval=pot%zion)
     710            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     711            3 :       CALL compose(string, "total_psenergy", rval=2._dp*atom%energy%etot)
     712            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     713            3 :       WRITE (iw, '(T8,A)') 'wfc_cutoff="0.0E+00"'
     714            3 :       WRITE (iw, '(T8,A)') 'rho_cutoff="0.0E+00"'
     715            3 :       lmax = -1
     716           21 :       DO l = 0, lmat
     717           21 :          IF (pot%nl(l) > 0) lmax = l
     718              :       END DO
     719            3 :       CALL compose(string, "l_max", ival=lmax)
     720            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     721            3 :       WRITE (iw, '(T8,A)') 'l_max_rho="0"'
     722            3 :       WRITE (iw, '(T8,A)') 'l_local="-3"'
     723            3 :       nr = atom%basis%grid%nr
     724            3 :       CALL compose(string, "mesh_size", ival=nr)
     725            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     726           21 :       nwfc = SUM(atom%state%maxn_occ)
     727            3 :       CALL compose(string, "number_of_wfc", ival=nwfc)
     728            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     729            3 :       IF (soc) THEN
     730            6 :          nbeta = pot%nl(0) + 2*SUM(pot%nl(1:))
     731              :       ELSE
     732           14 :          nbeta = SUM(pot%nl)
     733              :       END IF
     734            3 :       CALL compose(string, "number_of_proj", ival=nbeta)
     735            3 :       WRITE (iw, '(T8,A)') TRIM(string)//'/>'
     736              : 
     737              :       ! Mesh
     738            3 :       up = atom%basis%grid%rad(1) < atom%basis%grid%rad(nr)
     739            3 :       WRITE (iw, '(T4,A)') '<PP_MESH'
     740            3 :       WRITE (iw, '(T8,A)') 'dx="1.E+00"'
     741            3 :       CALL compose(string, "mesh", ival=nr)
     742            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     743            3 :       WRITE (iw, '(T8,A)') 'xmin="1.E+00"'
     744         1206 :       rmax = MAXVAL(atom%basis%grid%rad)
     745            3 :       CALL compose(string, "rmax", rval=rmax)
     746            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     747            3 :       WRITE (iw, '(T8,A)') 'zmesh="1.E+00">'
     748            3 :       WRITE (iw, '(T8,A)') '<PP_R type="real"'
     749            3 :       CALL compose(string, "size", ival=nr)
     750            3 :       WRITE (iw, '(T12,A)') TRIM(string)
     751            3 :       WRITE (iw, '(T12,A)') 'columns="4">'
     752            3 :       IF (up) THEN
     753            0 :          WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%rad(i), i=1, nr)
     754              :       ELSE
     755         1203 :          WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%rad(i), i=nr, 1, -1)
     756              :       END IF
     757            3 :       WRITE (iw, '(T8,A)') '</PP_R>'
     758            3 :       WRITE (iw, '(T8,A)') '<PP_RAB type="real"'
     759            3 :       CALL compose(string, "size", ival=nr)
     760            3 :       WRITE (iw, '(T12,A)') TRIM(string)
     761            3 :       WRITE (iw, '(T12,A)') 'columns="4">'
     762            3 :       IF (up) THEN
     763            0 :          WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%wr(i)/atom%basis%grid%rad2(i), i=1, nr)
     764              :       ELSE
     765         1203 :          WRITE (iw, '(T12,4ES25.12E3)') (atom%basis%grid%wr(i)/atom%basis%grid%rad2(i), i=nr, 1, -1)
     766              :       END IF
     767            3 :       WRITE (iw, '(T8,A)') '</PP_RAB>'
     768            3 :       WRITE (iw, '(T4,A)') '</PP_MESH>'
     769              : 
     770              :       ! NLCC
     771            3 :       IF (pot%nlcc) THEN
     772            1 :          WRITE (iw, '(T4,A)') '<PP_NLCC type="real"'
     773            1 :          CALL compose(string, "size", ival=nr)
     774            1 :          WRITE (iw, '(T8,A)') TRIM(string)
     775            1 :          WRITE (iw, '(T8,A)') 'columns="4">'
     776            3 :          ALLOCATE (corden(nr))
     777          401 :          corden(:) = 0.0_dp
     778            1 :          CALL atom_core_density(corden, atom%potential, "RHO", atom%basis%grid%rad)
     779            1 :          IF (up) THEN
     780            0 :             WRITE (iw, '(T8,4ES25.12E3)') (corden(i), i=1, nr)
     781              :          ELSE
     782            1 :             WRITE (iw, '(T8,4ES25.12E3)') (corden(i), i=nr, 1, -1)
     783              :          END IF
     784            1 :          DEALLOCATE (corden)
     785            1 :          WRITE (iw, '(T4,A)') '</PP_NLCC>'
     786              :       END IF
     787              : 
     788              :       ! local PP
     789            3 :       WRITE (iw, '(T4,A)') '<PP_LOCAL type="real"'
     790            3 :       CALL compose(string, "size", ival=nr)
     791            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     792            3 :       WRITE (iw, '(T8,A)') 'columns="4">'
     793            9 :       ALLOCATE (locpot(nr))
     794         1203 :       locpot(:) = 0.0_dp
     795            3 :       CALL atom_local_potential(locpot, pot, atom%basis%grid%rad)
     796            3 :       IF (up) THEN
     797            0 :          WRITE (iw, '(T8,4ES25.12E3)') (2.0_dp*locpot(i), i=1, nr)
     798              :       ELSE
     799         1203 :          WRITE (iw, '(T8,4ES25.12E3)') (2.0_dp*locpot(i), i=nr, 1, -1)
     800              :       END IF
     801            3 :       DEALLOCATE (locpot)
     802            3 :       WRITE (iw, '(T4,A)') '</PP_LOCAL>'
     803              : 
     804              :       ! nonlocal PP
     805            3 :       WRITE (iw, '(T4,A)') '<PP_NONLOCAL>'
     806           12 :       ALLOCATE (rp(nr), ef(nr), beta(nr))
     807            3 :       ibeta = 0
     808           21 :       DO l = 0, lmat
     809           18 :          IF (pot%nl(l) == 0) CYCLE
     810            6 :          rl = pot%rcnl(l)
     811         2406 :          rp(:) = atom%basis%grid%rad
     812         2406 :          ef(:) = EXP(-0.5_dp*rp*rp/(rl*rl))
     813           20 :          DO i = 1, pot%nl(l)
     814           11 :             pf = rl**(l + 0.5_dp*(4._dp*i - 1._dp))
     815           11 :             j = l + 2*i - 1
     816           11 :             pf = SQRT(2._dp)/(pf*SQRT(gamma1(j)))
     817         4411 :             beta(:) = pf*rp**(l + 2*i - 2)*ef
     818         4411 :             beta(:) = beta*rp
     819              :             !
     820           11 :             ibeta = ibeta + 1
     821           11 :             CALL compose(string, "<PP_BETA", counter=ibeta)
     822           11 :             WRITE (iw, '(T8,A)') TRIM(string)
     823           11 :             CALL compose(string, "angular_momentum", ival=l)
     824           11 :             WRITE (iw, '(T12,A)') TRIM(string)
     825           11 :             WRITE (iw, '(T12,A)') 'type="real"'
     826           11 :             CALL compose(string, "size", ival=nr)
     827           11 :             WRITE (iw, '(T12,A)') TRIM(string)
     828           11 :             WRITE (iw, '(T12,A)') 'columns="4">'
     829           11 :             IF (up) THEN
     830            0 :                WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=1, nr)
     831              :             ELSE
     832         4411 :                WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=nr, 1, -1)
     833              :             END IF
     834           11 :             CALL compose(string, "</PP_BETA", counter=ibeta, isfinal=.TRUE.)
     835           11 :             WRITE (iw, '(T8,A)') TRIM(string)
     836           29 :             IF (soc .AND. l /= 0) THEN
     837            5 :                ibeta = ibeta + 1
     838            5 :                CALL compose(string, "<PP_BETA", counter=ibeta)
     839            5 :                WRITE (iw, '(T8,A)') TRIM(string)
     840            5 :                CALL compose(string, "angular_momentum", ival=l)
     841            5 :                WRITE (iw, '(T12,A)') TRIM(string)
     842            5 :                WRITE (iw, '(T12,A)') 'type="real"'
     843            5 :                CALL compose(string, "size", ival=nr)
     844            5 :                WRITE (iw, '(T12,A)') TRIM(string)
     845            5 :                WRITE (iw, '(T12,A)') 'columns="4">'
     846            5 :                IF (up) THEN
     847            0 :                   WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=1, nr)
     848              :                ELSE
     849         2005 :                   WRITE (iw, '(T12,4ES25.12E3)') (2._dp*beta(j), j=nr, 1, -1)
     850              :                END IF
     851            5 :                CALL compose(string, "</PP_BETA", counter=ibeta, isfinal=.TRUE.)
     852            5 :                WRITE (iw, '(T8,A)') TRIM(string)
     853              :             END IF
     854              :          END DO
     855              :       END DO
     856            3 :       DEALLOCATE (rp, ef, beta)
     857              :       ! nonlocal PP matrix elements
     858           12 :       ALLOCATE (dij(nbeta, nbeta))
     859          193 :       dij = 0._dp
     860            3 :       IF (soc) THEN
     861              :          ! from reverse engineering we guess: hnl, knl, hnl, knl, ...
     862            1 :          n0 = pot%nl(0)
     863            7 :          DO l = 0, lmat
     864            6 :             IF (pot%nl(l) == 0) CYCLE
     865            4 :             IF (l == 0) THEN
     866              :                ! no SO term for l=0
     867           13 :                dij(1:n0, 1:n0) = pot%hnl(1:n0, 1:n0, 0)
     868              :             ELSE
     869            3 :                ibeta = n0 + 2*SUM(pot%nl(1:l - 1))
     870            7 :                DO i = 1, pot%nl(l)
     871            5 :                   ii = 2*(i - 1) + 1
     872           23 :                   DO k = 1, pot%nl(l)
     873           13 :                      kk = 2*(k - 1) + 1
     874           13 :                      vnlp = pot%hnl(i, k, l) + 0.5_dp*l*pot%knl(i, k, l)
     875           13 :                      vnlm = pot%hnl(i, k, l) - 0.5_dp*(l + 1)*pot%knl(i, k, l)
     876           13 :                      dij(ibeta + ii, ibeta + kk) = vnlm
     877           18 :                      dij(ibeta + ii + 1, ibeta + kk + 1) = vnlp
     878              :                   END DO
     879              :                END DO
     880              :             END IF
     881              :          END DO
     882              :       ELSE
     883           14 :          DO l = 0, lmat
     884           12 :             IF (pot%nl(l) == 0) CYCLE
     885            4 :             ibeta = SUM(pot%nl(0:l - 1)) + 1
     886            3 :             i = ibeta + pot%nl(l) - 1
     887           11 :             dij(ibeta:i, ibeta:i) = pot%hnl(1:pot%nl(l), 1:pot%nl(l), l)
     888              :          END DO
     889              :       END IF
     890            3 :       WRITE (iw, '(T8,A)') '<PP_DIJ type="real"'
     891            3 :       WRITE (iw, '(T12,A)') 'columns="4">'
     892          193 :       WRITE (iw, '(T12,4ES25.12E3)') ((0.5_dp*dij(i, j), j=1, nbeta), i=1, nbeta)
     893            3 :       WRITE (iw, '(T8,A)') '</PP_DIJ>'
     894            3 :       DEALLOCATE (dij)
     895            3 :       WRITE (iw, '(T4,A)') '</PP_NONLOCAL>'
     896              : 
     897              :       ! atomic wavefunctions
     898            6 :       ALLOCATE (beta(nr))
     899            3 :       WRITE (iw, '(T4,A)') '<PP_PSWFC>'
     900            3 :       nwfn = 0
     901           21 :       DO l = 0, lmat
     902          201 :          DO i = 1, 10
     903          180 :             IF (ABS(atom%state%occupation(l, i)) == 0._dp) CYCLE
     904            8 :             occa = atom%state%occupation(l, i)
     905            8 :             occb = 0.0_dp
     906            8 :             IF (soc .AND. l /= 0) THEN
     907            2 :                occb = FLOOR(occa/2)
     908            2 :                occa = occa - occb
     909              :             END IF
     910            8 :             nwfn = nwfn + 1
     911            8 :             CALL compose(string, "<PP_CHI", counter=nwfn)
     912            8 :             WRITE (iw, '(T8,A)') TRIM(string)
     913            8 :             CALL compose(string, "l", ival=l)
     914            8 :             WRITE (iw, '(T12,A)') TRIM(string)
     915            8 :             CALL compose(string, "occupation", rval=occa)
     916            8 :             WRITE (iw, '(T12,A)') TRIM(string)
     917            8 :             CALL compose(string, "pseudo_energy", rval=2._dp*atom%orbitals%ener(i, l))
     918            8 :             WRITE (iw, '(T12,A)') TRIM(string)
     919            8 :             WRITE (iw, '(T12,A)') 'columns="4">'
     920         3208 :             beta = 0._dp
     921          143 :             DO k = 1, atom%basis%nbas(l)
     922        54143 :                beta(:) = beta(:) + atom%orbitals%wfn(k, i, l)*atom%basis%bf(:, k, l)
     923              :             END DO
     924         3208 :             beta(:) = beta*atom%basis%grid%rad
     925            8 :             IF (up) THEN
     926            0 :                WRITE (iw, '(T12,4ES25.12E3)') (beta(j), j=1, nr)
     927              :             ELSE
     928            8 :                WRITE (iw, '(T12,4ES25.12E3)') (beta(j), j=nr, 1, -1)
     929              :             END IF
     930            8 :             CALL compose(string, "</PP_CHI", counter=nwfn, isfinal=.TRUE.)
     931            8 :             WRITE (iw, '(T8,A)') TRIM(string)
     932           26 :             IF (soc .AND. l /= 0) THEN
     933            2 :                nwfn = nwfn + 1
     934            2 :                CALL compose(string, "<PP_CHI", counter=nwfn)
     935            2 :                WRITE (iw, '(T8,A)') TRIM(string)
     936            2 :                CALL compose(string, "l", ival=l)
     937            2 :                WRITE (iw, '(T12,A)') TRIM(string)
     938            2 :                CALL compose(string, "occupation", rval=occb)
     939            2 :                WRITE (iw, '(T12,A)') TRIM(string)
     940            2 :                CALL compose(string, "pseudo_energy", rval=2._dp*atom%orbitals%ener(i, l))
     941            2 :                WRITE (iw, '(T12,A)') TRIM(string)
     942            2 :                WRITE (iw, '(T12,A)') 'columns="4">'
     943          802 :                beta = 0._dp
     944           34 :                DO k = 1, atom%basis%nbas(l)
     945        12834 :                   beta(:) = beta(:) + atom%orbitals%wfn(k, i, l)*atom%basis%bf(:, k, l)
     946              :                END DO
     947          802 :                beta(:) = beta*atom%basis%grid%rad
     948            2 :                IF (up) THEN
     949            0 :                   WRITE (iw, '(T12,4ES25.12E3)') (beta(j), j=1, nr)
     950              :                ELSE
     951            2 :                   WRITE (iw, '(T12,4ES25.12E3)') (beta(j), j=nr, 1, -1)
     952              :                END IF
     953            2 :                CALL compose(string, "</PP_CHI", counter=nwfn, isfinal=.TRUE.)
     954            2 :                WRITE (iw, '(T8,A)') TRIM(string)
     955              :             END IF
     956              :          END DO
     957              :       END DO
     958            3 :       WRITE (iw, '(T4,A)') '</PP_PSWFC>'
     959            3 :       DEALLOCATE (beta)
     960              : 
     961              :       ! atomic charge
     962            6 :       ALLOCATE (dens(nr))
     963            3 :       WRITE (iw, '(T4,A)') '<PP_RHOATOM type="real"'
     964            3 :       CALL compose(string, "size", ival=nr)
     965            3 :       WRITE (iw, '(T8,A)') TRIM(string)
     966            3 :       WRITE (iw, '(T8,A)') 'columns="4">'
     967              :       CALL atom_density(dens, atom%orbitals%pmat, atom%basis, atom%state%maxl_occ, &
     968            3 :                         "RHO", atom%basis%grid%rad)
     969            3 :       IF (up) THEN
     970            0 :          WRITE (iw, '(T8,4ES25.12E3)') (fourpi*dens(j)*atom%basis%grid%rad2(j), j=1, nr)
     971              :       ELSE
     972         1203 :          WRITE (iw, '(T8,4ES25.12E3)') (fourpi*dens(j)*atom%basis%grid%rad2(j), j=nr, 1, -1)
     973              :       END IF
     974            3 :       WRITE (iw, '(T4,A)') '</PP_RHOATOM>'
     975              : 
     976              :       ! Check atomic electron count
     977         1203 :       rhoatom = SUM(fourpi*atom%basis%grid%wr(:)*dens(:))
     978            3 :       IF (ABS(pot%zion - rhoatom) > 0.01_dp) THEN
     979            1 :          CALL cp_warn(__LOCATION__, "Valence charge and electron count differ by more than 0.01")
     980              :       END IF
     981              : 
     982            3 :       DEALLOCATE (dens)
     983              :       ! PP SOC information
     984            3 :       IF (soc) THEN
     985            1 :          WRITE (iw, '(T4,A)') '<PP_SPIN_ORB>'
     986              : !        <PP_RELWFC.1 index="1" els="6S" nn="1" lchi="0" jchi="5.000000000000e-1" oc="1.000000000000e0"/>
     987            1 :          nwfn = 0
     988            7 :          DO l = 0, lmat
     989           67 :             DO i = 1, 10
     990           60 :                IF (ABS(atom%state%occupation(l, i)) == 0._dp) CYCLE
     991            4 :                occa = atom%state%occupation(l, i)
     992            4 :                occb = 0.0_dp
     993            4 :                IF (l /= 0) THEN
     994            2 :                   occb = FLOOR(occa/2)
     995            2 :                   occa = occa - occb
     996              :                END IF
     997            4 :                nwfn = nwfn + 1
     998            4 :                CALL compose(string, "<PP_RELWFC", counter=nwfn)
     999            4 :                WRITE (iw, '(T8,A)') TRIM(string)
    1000            4 :                CALL compose(string, "index", ival=nwfn)
    1001            4 :                WRITE (iw, '(T12,A)') TRIM(string)
    1002              :                !!CALL compose(string, "els", cval=xxxx)
    1003              :                !!WRITE (iw, '(T12,A)') TRIM(string)
    1004            4 :                CALL compose(string, "nn", ival=nwfn)
    1005            4 :                WRITE (iw, '(T12,A)') TRIM(string)
    1006            4 :                CALL compose(string, "lchi", ival=l)
    1007            4 :                WRITE (iw, '(T12,A)') TRIM(string)
    1008            4 :                IF (l == 0) THEN
    1009            2 :                   rlp = 0.5_dp
    1010              :                ELSE
    1011            2 :                   rlp = l - 0.5_dp
    1012              :                END IF
    1013            4 :                CALL compose(string, "jchi", rval=rlp)
    1014            4 :                WRITE (iw, '(T12,A)') TRIM(string)
    1015            4 :                CALL compose(string, "oc", rval=occa)
    1016            4 :                WRITE (iw, '(T12,A)') TRIM(string)
    1017            4 :                WRITE (iw, '(T12,A)') '/>'
    1018           10 :                IF (l /= 0) THEN
    1019            2 :                   nwfn = nwfn + 1
    1020            2 :                   CALL compose(string, "<PP_RELWFC", counter=nwfn)
    1021            2 :                   WRITE (iw, '(T8,A)') TRIM(string)
    1022            2 :                   CALL compose(string, "index", ival=nwfn)
    1023            2 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1024              :                   !!CALL compose(string, "els", cval=xxxx)
    1025              :                   !!WRITE (iw, '(T12,A)') TRIM(string)
    1026            2 :                   CALL compose(string, "nn", ival=nwfn)
    1027            2 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1028            2 :                   CALL compose(string, "lchi", ival=l)
    1029            2 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1030            2 :                   rlp = l + 0.5_dp
    1031            2 :                   CALL compose(string, "jchi", rval=rlp)
    1032            2 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1033            2 :                   CALL compose(string, "oc", rval=occa)
    1034            2 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1035            2 :                   WRITE (iw, '(T12,A)') '/>'
    1036              :                END IF
    1037              :             END DO
    1038              :          END DO
    1039            1 :          ibeta = 0
    1040            7 :          DO l = 0, lmat
    1041            6 :             IF (pot%nl(l) == 0) CYCLE
    1042           12 :             DO i = 1, pot%nl(l)
    1043            8 :                ibeta = ibeta + 1
    1044            8 :                CALL compose(string, "<PP_RELBETA", counter=ibeta)
    1045            8 :                WRITE (iw, '(T8,A)') TRIM(string)
    1046            8 :                CALL compose(string, "index", ival=ibeta)
    1047            8 :                WRITE (iw, '(T12,A)') TRIM(string)
    1048            8 :                CALL compose(string, "lll", ival=l)
    1049            8 :                WRITE (iw, '(T12,A)') TRIM(string)
    1050            8 :                IF (l == 0) THEN
    1051            3 :                   rlp = 0.5_dp
    1052              :                ELSE
    1053            5 :                   rlp = l - 0.5_dp
    1054              :                END IF
    1055            8 :                CALL compose(string, "jjj", rval=rlp)
    1056            8 :                WRITE (iw, '(T12,A)') TRIM(string)
    1057            8 :                WRITE (iw, '(T12,A)') '/>'
    1058           14 :                IF (l > 0) THEN
    1059            5 :                   ibeta = ibeta + 1
    1060            5 :                   CALL compose(string, "<PP_RELBETA", counter=ibeta)
    1061            5 :                   WRITE (iw, '(T8,A)') TRIM(string)
    1062            5 :                   CALL compose(string, "index", ival=ibeta)
    1063            5 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1064            5 :                   CALL compose(string, "lll", ival=l)
    1065            5 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1066            5 :                   rlp = l + 0.5_dp
    1067            5 :                   CALL compose(string, "jjj", rval=rlp)
    1068            5 :                   WRITE (iw, '(T12,A)') TRIM(string)
    1069            5 :                   WRITE (iw, '(T12,A)') '/>'
    1070              :                END IF
    1071              :             END DO
    1072              :          END DO
    1073            1 :          WRITE (iw, '(T4,A)') '</PP_SPIN_ORB>'
    1074              :       END IF
    1075              : 
    1076            3 :       WRITE (iw, '(A)') '</UPF>'
    1077              : 
    1078            6 :    END SUBROUTINE atom_write_upf
    1079              : 
    1080              : ! **************************************************************************************************
    1081              : !> \brief Produce an XML attribute string 'tag="counter/rval/ival/cval"'
    1082              : !> \param string   composed string
    1083              : !> \param tag      attribute tag
    1084              : !> \param counter  counter
    1085              : !> \param rval     real variable
    1086              : !> \param ival     integer variable
    1087              : !> \param cval     string variable
    1088              : !> \param isfinal  close the current XML element if this is the last attribute
    1089              : !> \par History
    1090              : !>    * 09.2012 created [Juerg Hutter]
    1091              : ! **************************************************************************************************
    1092          242 :    SUBROUTINE compose(string, tag, counter, rval, ival, cval, isfinal)
    1093              :       CHARACTER(len=*), INTENT(OUT)                      :: string
    1094              :       CHARACTER(len=*), INTENT(IN)                       :: tag
    1095              :       INTEGER, INTENT(IN), OPTIONAL                      :: counter
    1096              :       REAL(KIND=dp), INTENT(IN), OPTIONAL                :: rval
    1097              :       INTEGER, INTENT(IN), OPTIONAL                      :: ival
    1098              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: cval
    1099              :       LOGICAL, INTENT(IN), OPTIONAL                      :: isfinal
    1100              : 
    1101              :       CHARACTER(LEN=default_string_length)               :: str
    1102              :       LOGICAL                                            :: fin
    1103              : 
    1104          242 :       IF (PRESENT(counter)) THEN
    1105           71 :          WRITE (str, "(I12)") counter
    1106          171 :       ELSEIF (PRESENT(rval)) THEN
    1107           54 :          WRITE (str, "(G18.8)") rval
    1108          117 :       ELSEIF (PRESENT(ival)) THEN
    1109          114 :          WRITE (str, "(I12)") ival
    1110            3 :       ELSEIF (PRESENT(cval)) THEN
    1111            3 :          WRITE (str, "(A)") TRIM(ADJUSTL(cval))
    1112              :       ELSE
    1113            0 :          WRITE (str, "(A)") ""
    1114              :       END IF
    1115          242 :       fin = .FALSE.
    1116          242 :       IF (PRESENT(isfinal)) fin = isfinal
    1117          242 :       IF (PRESENT(counter)) THEN
    1118           71 :          IF (fin) THEN
    1119           26 :             WRITE (string, "(A,A1,A,A1)") TRIM(ADJUSTL(tag)), '.', TRIM(ADJUSTL(str)), '>'
    1120              :          ELSE
    1121           45 :             WRITE (string, "(A,A1,A)") TRIM(ADJUSTL(tag)), '.', TRIM(ADJUSTL(str))
    1122              :          END IF
    1123              :       ELSE
    1124          171 :          IF (fin) THEN
    1125            0 :             WRITE (string, "(A,A2,A,A2)") TRIM(ADJUSTL(tag)), '="', TRIM(ADJUSTL(str)), '>"'
    1126              :          ELSE
    1127          171 :             WRITE (string, "(A,A2,A,A1)") TRIM(ADJUSTL(tag)), '="', TRIM(ADJUSTL(str)), '"'
    1128              :          END IF
    1129              :       END IF
    1130          242 :    END SUBROUTINE compose
    1131              : 
    1132           10 : END MODULE atom_energy
        

Generated by: LCOV version 2.0-1