LCOV - code coverage report
Current view: top level - src - qs_fgxc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 40.8 % 439 179
Test Date: 2026-09-03 07:32:15 Functions: 50.0 % 2 1

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief routines that build the integrals of the Fxc kernel calculated
      10              : !>      for the atomic density in the basis set of spherical primitives
      11              : ! **************************************************************************************************
      12              : MODULE qs_fgxc_atom
      13              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      14              :                                               get_atomic_kind
      15              :    USE basis_set_types,                 ONLY: gto_basis_set_type
      16              :    USE cp_control_types,                ONLY: dft_control_type
      17              :    USE input_constants,                 ONLY: xc_none
      18              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      19              :                                               section_vals_type,&
      20              :                                               section_vals_val_get
      21              :    USE kinds,                           ONLY: dp
      22              :    USE message_passing,                 ONLY: mp_para_env_type
      23              :    USE qs_environment_types,            ONLY: get_qs_env,&
      24              :                                               qs_environment_type
      25              :    USE qs_fxc_atom,                     ONLY: fxc_atom_calc
      26              :    USE qs_grid_atom,                    ONLY: grid_atom_type
      27              :    USE qs_harmonics_atom,               ONLY: harmonics_atom_type
      28              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      29              :                                               has_nlcc,&
      30              :                                               qs_kind_type
      31              :    USE qs_rho_atom_types,               ONLY: get_rho_atom,&
      32              :                                               rho_atom_coeff,&
      33              :                                               rho_atom_type
      34              :    USE qs_vxc_atom_utils,               ONLY: &
      35              :         calc_rho_angular, calc_rho_nlcc, calc_tau_atom, create_tau_basis_cache, dgaVtaudgb, &
      36              :         gaVxcgb_GC, gaVxcgb_noGC, release_tau_basis_cache, tau_basis_cache_type
      37              :    USE util,                            ONLY: get_limit
      38              :    USE xc_atom,                         ONLY: fill_rho_set,&
      39              :                                               vxc_of_r_new,&
      40              :                                               xc_2nd_deriv_of_r,&
      41              :                                               xc_rho_set_atom_update
      42              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      43              :                                               xc_dset_create,&
      44              :                                               xc_dset_release,&
      45              :                                               xc_dset_zero_all
      46              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      47              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      48              :    USE xc_rho_set_types,                ONLY: xc_rho_set_create,&
      49              :                                               xc_rho_set_release,&
      50              :                                               xc_rho_set_type
      51              : #include "./base/base_uses.f90"
      52              : 
      53              :    IMPLICIT NONE
      54              : 
      55              :    PRIVATE
      56              : 
      57              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fgxc_atom'
      58              : 
      59              :    PUBLIC :: fgxc_atom_calc, &
      60              :              fgxc_atom_diff
      61              : 
      62              : ! **************************************************************************************************
      63              : 
      64              : CONTAINS
      65              : 
      66              : ! **************************************************************************************************
      67              : !> \brief ...
      68              : !> \param qs_env ...
      69              : !> \param rho0_atom_set ...
      70              : !> \param rho1_atom_set ...
      71              : !> \param rho2_atom_set ...
      72              : !> \param kind_set ...
      73              : !> \param xc_section ...
      74              : !> \param is_triplet ...
      75              : !> \param accuracy ...
      76              : ! **************************************************************************************************
      77            0 :    SUBROUTINE fgxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
      78              :                              kind_set, xc_section, is_triplet, accuracy)
      79              : 
      80              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      81              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
      82              :                                                             rho2_atom_set
      83              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
      84              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
      85              :       LOGICAL, INTENT(IN)                                :: is_triplet
      86              :       INTEGER, INTENT(IN)                                :: accuracy
      87              : 
      88              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'fgxc_atom_calc'
      89              :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
      90              : 
      91              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
      92              :                                                             istep, mspins, myfun, na, natom, nf, &
      93              :                                                             nr, ns, nspins, nstep, num_pe
      94              :       INTEGER, DIMENSION(2, 3)                           :: bounds
      95            0 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
      96              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
      97              :                                                             paw_atom, tau_f
      98              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, exc_h, &
      99              :                                                             exc_s, gradient_cut, oeps1, oeps2, &
     100              :                                                             tau_cut
     101              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     102              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     103            0 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
     104            0 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
     105            0 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
     106            0 :                                                             tau_h, tau_s, vtau_h, vtau_s, vxc_h, &
     107            0 :                                                             vxc_s
     108            0 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
     109            0 :                                                             drho_h, drho_s, vxg_h, vxg_s
     110              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak, bl
     111            0 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     112              :       TYPE(dft_control_type), POINTER                    :: dft_control
     113              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     114              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     115              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     116              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     117            0 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
     118            0 :                                                             int_ss, r_h, r_s
     119            0 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     120              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
     121              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     122            0 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     123              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     124              :       TYPE(xc_rho_cflags_type)                           :: needs
     125              :       TYPE(xc_rho_set_type)                              :: rho_set_h, rho_set_s
     126              : 
     127            0 :       CALL timeset(routineN, handle)
     128              : 
     129            0 :       NULLIFY (vtau_h, vtau_s)
     130              : 
     131            0 :       ak = 0.0_dp
     132            0 :       bl = 0.0_dp
     133            0 :       SELECT CASE (accuracy)
     134              :       CASE (:4)
     135            0 :          nstep = 2
     136            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
     137            0 :          bl(-2:2) = [-1.0_dp, 16.0_dp, -30.0_dp, 16.0_dp, -1.0_dp]/12.0_dp
     138              :       CASE (5:7)
     139            0 :          nstep = 3
     140            0 :          ak(-3:3) = [-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp]/60.0_dp
     141            0 :          bl(-3:3) = [2.0_dp, -27.0_dp, 270.0_dp, -490.0_dp, 270.0_dp, -27.0_dp, 2.0_dp]/180.0_dp
     142              :       CASE (8:)
     143            0 :          nstep = 4
     144              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
     145            0 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
     146              :          bl(-4:4) = [-1.0_dp, 128.0_dp/9.0_dp, -112.0_dp, 896.0_dp, -14350.0_dp/9.0_dp, &
     147            0 :                      896.0_dp, -112.0_dp, 128.0_dp/9.0_dp, -1.0_dp]/560.0_dp
     148              :       END SELECT
     149            0 :       oeps1 = 1.0_dp/epsrho
     150            0 :       oeps2 = 1.0_dp/(epsrho**2)
     151              : 
     152              :       CALL get_qs_env(qs_env=qs_env, &
     153              :                       dft_control=dft_control, &
     154              :                       para_env=para_env, &
     155            0 :                       atomic_kind_set=atomic_kind_set)
     156              : 
     157            0 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     158            0 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
     159              : 
     160            0 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     161              : 
     162            0 :       IF (myfun == xc_none) THEN
     163              :          ! no action needed?
     164              :       ELSE
     165            0 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
     166            0 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
     167            0 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
     168              : 
     169            0 :          nlcc = has_nlcc(kind_set)
     170            0 :          lsd = dft_control%lsd
     171            0 :          nspins = dft_control%nspins
     172            0 :          mspins = nspins
     173            0 :          IF (is_triplet) THEN
     174            0 :             CPASSERT(nspins == 1)
     175            0 :             lsd = .TRUE.
     176            0 :             mspins = 2
     177              :          END IF
     178            0 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
     179            0 :          gradient_f = (needs%drho .OR. needs%drho_spin)
     180            0 :          tau_f = (needs%tau .OR. needs%tau_spin)
     181              : 
     182              :          ! Here starts the loop over all the atoms
     183            0 :          DO ikind = 1, SIZE(atomic_kind_set)
     184            0 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     185              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
     186            0 :                              harmonics=harmonics, grid_atom=grid_atom)
     187            0 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     188              : 
     189            0 :             IF (.NOT. paw_atom) CYCLE
     190              : 
     191            0 :             nr = grid_atom%nr
     192            0 :             na = grid_atom%ng_sphere
     193              : 
     194              :             ! set integration weights
     195            0 :             IF (accint) THEN
     196            0 :                weight_h => grid_atom%weight
     197            0 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
     198            0 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     199            0 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     200              :                END IF
     201            0 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     202            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     203            0 :                   DO ir = 1, nr
     204            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     205            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     206              :                   END DO
     207            0 :                   grid_atom%gapw_weight_alpha = alpha
     208              :                END IF
     209            0 :                weight_s => grid_atom%gapw_weight_s
     210              :             ELSE
     211            0 :                weight_h => grid_atom%weight
     212            0 :                weight_s => grid_atom%weight
     213              :             END IF
     214              : 
     215              :             ! Prepare the structures needed to calculate and store the xc derivatives
     216              : 
     217              :             ! Array dimension: here only one dimensional arrays are used,
     218              :             ! i.e. only the first column of deriv_data is read.
     219              :             ! The other to dimensions  are set to size equal 1
     220            0 :             bounds(1:2, 1:3) = 1
     221            0 :             bounds(2, 1) = na
     222            0 :             bounds(2, 2) = nr
     223              : 
     224              :             ! create a place where to put the derivatives
     225            0 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
     226              :             ! create the place where to store the argument for the functionals
     227              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     228            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     229              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     230            0 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     231              : 
     232              :             ! allocate the required 3d arrays where to store rho and drho
     233            0 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
     234            0 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
     235              : 
     236              :             ALLOCATE (rho_h(na, nr, mspins), rho_s(na, nr, mspins), &
     237              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
     238            0 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
     239            0 :             ALLOCATE (vxc_h(na, nr, mspins), vxc_s(na, nr, mspins))
     240            0 :             IF (gradient_f) THEN
     241              :                ALLOCATE (drho_h(4, na, nr, mspins), drho_s(4, na, nr, mspins), &
     242              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
     243            0 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
     244            0 :                ALLOCATE (vxg_h(3, na, nr, mspins), vxg_s(3, na, nr, mspins))
     245              :             END IF
     246            0 :             IF (tau_f) THEN
     247            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     248              :                ALLOCATE (tau_h(na, nr, mspins), tau_s(na, nr, mspins), &
     249              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
     250            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
     251            0 :                ALLOCATE (vtau_h(na, nr, mspins), vtau_s(na, nr, mspins))
     252              :             END IF
     253              :             !
     254              :             ! NLCC: prepare rho and drho of the core charge for this KIND
     255            0 :             donlcc = .FALSE.
     256            0 :             IF (nlcc) THEN
     257            0 :                NULLIFY (rho_nlcc)
     258            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
     259            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     260              :             END IF
     261              : 
     262              :             ! Distribute the atoms of this kind
     263            0 :             num_pe = para_env%num_pe
     264            0 :             bo = get_limit(natom, num_pe, para_env%mepos)
     265              : 
     266            0 :             DO iat = bo(1), bo(2)
     267            0 :                iatom = atom_list(iat)
     268              :                !
     269            0 :                NULLIFY (int_hh, int_ss)
     270            0 :                rho0_atom => rho0_atom_set(iatom)
     271            0 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     272            0 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
     273            0 :                DO ns = 1, nspins
     274            0 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
     275            0 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
     276            0 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
     277            0 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
     278              :                END DO
     279              : 
     280              :                ! RHO0
     281            0 :                rho0_h = 0.0_dp
     282            0 :                rho0_s = 0.0_dp
     283            0 :                rho0_atom => rho0_atom_set(iatom)
     284            0 :                IF (gradient_f) THEN
     285            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     286              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
     287            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
     288            0 :                   drho0_h = 0.0_dp
     289            0 :                   drho0_s = 0.0_dp
     290              :                ELSE
     291            0 :                   NULLIFY (r_h, r_s)
     292            0 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     293            0 :                   rho_d = 0.0_dp
     294              :                END IF
     295            0 :                DO ir = 1, nr
     296              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     297              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
     298            0 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
     299            0 :                   IF (donlcc) THEN
     300              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     301            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
     302              :                   END IF
     303              :                END DO
     304            0 :                IF (tau_f) THEN
     305              :                   !compute tau on the grid all at once
     306            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
     307              :                ELSE
     308            0 :                   tau_d = 0.0_dp
     309              :                END IF
     310              :                ! RHO1
     311            0 :                rho1_h = 0.0_dp
     312            0 :                rho1_s = 0.0_dp
     313            0 :                rho1_atom => rho1_atom_set(iatom)
     314            0 :                IF (gradient_f) THEN
     315            0 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     316              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
     317            0 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
     318            0 :                   drho1_h = 0.0_dp
     319            0 :                   drho1_s = 0.0_dp
     320              :                ELSE
     321            0 :                   NULLIFY (r_h, r_s)
     322            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     323              :                END IF
     324            0 :                DO ir = 1, nr
     325              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     326              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
     327            0 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
     328              :                END DO
     329            0 :                IF (tau_f) THEN
     330              :                   !compute tau on the grid all at once
     331            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
     332              :                END IF
     333              :                ! RHO2
     334            0 :                rho2_atom => rho2_atom_set(iatom)
     335              : 
     336            0 :                DO istep = -nstep, nstep
     337              : 
     338            0 :                   beta = REAL(istep, KIND=dp)*epsrho
     339              : 
     340            0 :                   IF (is_triplet) THEN
     341            0 :                      rho_h(:, :, 1) = rho0_h(:, :, 1) + beta*rho1_h(:, :, 1)
     342            0 :                      rho_h(:, :, 2) = rho0_h(:, :, 1)
     343            0 :                      rho_h = 0.5_dp*rho_h
     344            0 :                      rho_s(:, :, 1) = rho0_s(:, :, 1) + beta*rho1_s(:, :, 1)
     345            0 :                      rho_s(:, :, 2) = rho0_s(:, :, 1)
     346            0 :                      rho_s = 0.5_dp*rho_s
     347            0 :                      IF (gradient_f) THEN
     348            0 :                         drho_h(:, :, :, 1) = drho0_h(:, :, :, 1) + beta*drho1_h(:, :, :, 1)
     349            0 :                         drho_h(:, :, :, 2) = drho0_h(:, :, :, 1)
     350            0 :                         drho_h = 0.5_dp*drho_h
     351            0 :                         drho_s(:, :, :, 1) = drho0_s(:, :, :, 1) + beta*drho1_s(:, :, :, 1)
     352            0 :                         drho_s(:, :, :, 2) = drho0_s(:, :, :, 1)
     353            0 :                         drho_s = 0.5_dp*drho_s
     354              :                      END IF
     355            0 :                      IF (tau_f) THEN
     356            0 :                         tau_h(:, :, 1) = tau0_h(:, :, 1) + beta*tau1_h(:, :, 1)
     357            0 :                         tau_h(:, :, 2) = tau0_h(:, :, 1)
     358            0 :                         tau_h = 0.5_dp*tau0_h
     359            0 :                         tau_s(:, :, 1) = tau0_s(:, :, 1) + beta*tau1_s(:, :, 1)
     360            0 :                         tau_s(:, :, 2) = tau0_s(:, :, 1)
     361            0 :                         tau_s = 0.5_dp*tau0_s
     362              :                      END IF
     363              :                   ELSE
     364            0 :                      rho_h = rho0_h + beta*rho1_h
     365            0 :                      rho_s = rho0_s + beta*rho1_s
     366            0 :                      IF (gradient_f) THEN
     367            0 :                         drho_h = drho0_h + beta*drho1_h
     368            0 :                         drho_s = drho0_s + beta*drho1_s
     369              :                      END IF
     370            0 :                      IF (tau_f) THEN
     371            0 :                         tau_h = tau0_h + beta*tau1_h
     372            0 :                         tau_s = tau0_s + beta*tau1_s
     373              :                      END IF
     374              :                   END IF
     375              :                   !
     376            0 :                   IF (gradient_f) THEN
     377            0 :                      drho_h(4, :, :, :) = NORM2(drho_h(1:3, :, :, :), 1)
     378            0 :                      drho_s(4, :, :, :) = NORM2(drho_s(1:3, :, :, :), 1)
     379              :                   END IF
     380              : 
     381            0 :                   DO ir = 1, nr
     382            0 :                      IF (tau_f) THEN
     383            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_h, na, ir)
     384            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_s, na, ir)
     385            0 :                      ELSE IF (gradient_f) THEN
     386            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, drho_h, tau_d, na, ir)
     387            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, drho_s, tau_d, na, ir)
     388              :                      ELSE
     389            0 :                         CALL fill_rho_set(rho_set_h, lsd, mspins, needs, rho_h, rho_d, tau_d, na, ir)
     390            0 :                         CALL fill_rho_set(rho_set_s, lsd, mspins, needs, rho_s, rho_d, tau_d, na, ir)
     391              :                      END IF
     392              :                   END DO
     393              : 
     394              :                   ! hard atom density !
     395            0 :                   CALL xc_dset_zero_all(deriv_set)
     396              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_h, deriv_set, 1, needs, weight_h, &
     397            0 :                                     lsd, na, nr, exc_h, vxc_h, vxg_h, vtau_h)
     398            0 :                   IF (is_triplet) THEN
     399            0 :                      vxc_h(:, :, 1) = vxc_h(:, :, 1) - vxc_h(:, :, 2)
     400            0 :                      IF (gradient_f) THEN
     401            0 :                         vxg_h(:, :, :, 1) = vxg_h(:, :, :, 1) - vxg_h(:, :, :, 2)
     402              :                      END IF
     403            0 :                      IF (tau_f) THEN
     404            0 :                         vtau_h(:, :, 1) = vtau_h(:, :, 1) - vtau_h(:, :, 2)
     405              :                      END IF
     406              :                   END IF
     407              :                   ! soft atom density !
     408            0 :                   CALL xc_dset_zero_all(deriv_set)
     409              :                   CALL vxc_of_r_new(xc_fun_section, rho_set_s, deriv_set, 1, needs, weight_s, &
     410            0 :                                     lsd, na, nr, exc_s, vxc_s, vxg_s, vtau_s)
     411            0 :                   IF (is_triplet) THEN
     412            0 :                      vxc_s(:, :, 1) = vxc_s(:, :, 1) - vxc_s(:, :, 2)
     413            0 :                      IF (gradient_f) THEN
     414            0 :                         vxg_s(:, :, :, 1) = vxg_s(:, :, :, 1) - vxg_s(:, :, :, 2)
     415              :                      END IF
     416            0 :                      IF (tau_f) THEN
     417            0 :                         vtau_s(:, :, 1) = vtau_s(:, :, 1) - vtau_s(:, :, 2)
     418              :                      END IF
     419              :                   END IF
     420              :                   ! potentials
     421            0 :                   DO ns = 1, nspins
     422            0 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
     423            0 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
     424              :                   END DO
     425            0 :                   IF (gradient_f) THEN
     426              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
     427            0 :                                      grid_atom, basis_1c, harmonics, nspins)
     428              :                   ELSE
     429              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
     430            0 :                                        grid_atom, basis_1c, harmonics, nspins)
     431              :                   END IF
     432            0 :                   IF (tau_f) THEN
     433              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
     434            0 :                                      tau_basis_cache, nspins)
     435              :                   END IF
     436              :                   ! first derivative fxc
     437            0 :                   NULLIFY (int_hh, int_ss)
     438            0 :                   CALL get_rho_atom(rho_atom=rho1_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     439            0 :                   DO ns = 1, nspins
     440            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
     441            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
     442              :                   END DO
     443              :                   ! second derivative gxc
     444            0 :                   NULLIFY (int_hh, int_ss)
     445            0 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     446            0 :                   DO ns = 1, nspins
     447            0 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_ss(ns)%r_coef(:, :)
     448            0 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps2*bl(istep)*fint_hh(ns)%r_coef(:, :)
     449              :                   END DO
     450              :                END DO
     451              :                !
     452            0 :                DO ns = 1, nspins
     453            0 :                   DEALLOCATE (fint_ss(ns)%r_coef)
     454            0 :                   DEALLOCATE (fint_hh(ns)%r_coef)
     455              :                END DO
     456            0 :                DEALLOCATE (fint_ss, fint_hh)
     457              : 
     458              :             END DO ! iat
     459              : 
     460              :             ! Release the xc structure used to store the xc derivatives
     461            0 :             CALL xc_dset_release(deriv_set)
     462            0 :             CALL xc_rho_set_release(rho_set_h)
     463            0 :             CALL xc_rho_set_release(rho_set_s)
     464              : 
     465            0 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
     466            0 :             DEALLOCATE (vxc_h, vxc_s)
     467            0 :             IF (gradient_f) THEN
     468            0 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
     469            0 :                DEALLOCATE (vxg_h, vxg_s)
     470              :             END IF
     471            0 :             IF (tau_f) THEN
     472            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
     473            0 :                DEALLOCATE (vtau_h, vtau_s)
     474            0 :                CALL release_tau_basis_cache(tau_basis_cache)
     475              :             END IF
     476              :          END DO ! ikind
     477              : 
     478              :       END IF !xc_none
     479              : 
     480            0 :       CALL timestop(handle)
     481              : 
     482            0 :    END SUBROUTINE fgxc_atom_calc
     483              : 
     484              : ! **************************************************************************************************
     485              : !> \brief ...
     486              : !> \param qs_env ...
     487              : !> \param rho0_atom_set ...
     488              : !> \param rho1_atom_set ...
     489              : !> \param rho2_atom_set ...
     490              : !> \param kind_set ...
     491              : !> \param xc_section ...
     492              : !> \param is_triplet ...
     493              : !> \param accuracy ...
     494              : !> \param epsrho ...
     495              : ! **************************************************************************************************
     496          114 :    SUBROUTINE fgxc_atom_diff(qs_env, rho0_atom_set, rho1_atom_set, rho2_atom_set, &
     497              :                              kind_set, xc_section, is_triplet, accuracy, epsrho)
     498              : 
     499              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     500              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set, rho1_atom_set, &
     501              :                                                             rho2_atom_set
     502              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: kind_set
     503              :       TYPE(section_vals_type), OPTIONAL, POINTER         :: xc_section
     504              :       LOGICAL, INTENT(IN)                                :: is_triplet
     505              :       INTEGER, INTENT(IN)                                :: accuracy
     506              :       REAL(KIND=dp), INTENT(IN)                          :: epsrho
     507              : 
     508              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'fgxc_atom_diff'
     509              : 
     510              :       INTEGER                                            :: bo(2), handle, iat, iatom, ikind, ir, &
     511              :                                                             istep, mspins, myfun, na, natom, nf, &
     512              :                                                             nr, ns, nspins, nstep, num_pe
     513              :       INTEGER, DIMENSION(2, 3)                           :: bounds
     514          114 :       INTEGER, DIMENSION(:), POINTER                     :: atom_list
     515              :       LOGICAL                                            :: accint, donlcc, gradient_f, lsd, nlcc, &
     516              :                                                             paw_atom, tau_f
     517              :       REAL(dp)                                           :: agr, alpha, beta, density_cut, &
     518              :                                                             gradient_cut, oeps1, tau_cut
     519          114 :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER  :: vtau_h, vtau_s, vxc_h, vxc_s
     520              :       REAL(dp), DIMENSION(1, 1, 1)                       :: tau_d
     521              :       REAL(dp), DIMENSION(1, 1, 1, 1)                    :: rho_d
     522          228 :       REAL(dp), DIMENSION(:, :), POINTER                 :: rho_nlcc, weight_h, weight_s
     523          228 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: rho0_h, rho0_s, rho1_h, rho1_s, rho_h, &
     524          228 :                                                             rho_s, tau0_h, tau0_s, tau1_h, tau1_s, &
     525          114 :                                                             tau_h, tau_s
     526          114 :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: drho0_h, drho0_s, drho1_h, drho1_s, &
     527          228 :                                                             drho_h, drho_s, vxg_h, vxg_s
     528              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
     529          114 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     530              :       TYPE(dft_control_type), POINTER                    :: dft_control
     531              :       TYPE(grid_atom_type), POINTER                      :: grid_atom
     532              :       TYPE(gto_basis_set_type), POINTER                  :: basis_1c
     533              :       TYPE(harmonics_atom_type), POINTER                 :: harmonics
     534              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     535          114 :       TYPE(rho_atom_coeff), DIMENSION(:), POINTER        :: dr_h, dr_s, fint_hh, fint_ss, int_hh, &
     536          114 :                                                             int_ss, r_h, r_s
     537          114 :       TYPE(rho_atom_coeff), DIMENSION(:, :), POINTER     :: r_h_d, r_s_d
     538              :       TYPE(rho_atom_type), POINTER                       :: rho0_atom, rho1_atom, rho2_atom
     539              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     540          114 :       TYPE(tau_basis_cache_type)                         :: tau_basis_cache
     541              :       TYPE(xc_derivative_set_type)                       :: deriv_set
     542              :       TYPE(xc_rho_cflags_type)                           :: needs
     543              :       TYPE(xc_rho_set_type)                              :: rho1_set_h, rho1_set_s, rho_set_h, &
     544              :                                                             rho_set_s
     545              : 
     546          114 :       CALL timeset(routineN, handle)
     547              : 
     548          114 :       NULLIFY (vtau_h, vtau_s)
     549              : 
     550          114 :       ak = 0.0_dp
     551          114 :       SELECT CASE (accuracy)
     552              :       CASE (:4)
     553            0 :          nstep = 2
     554            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
     555              :       CASE (5:7)
     556          912 :          nstep = 3
     557          912 :          ak(-3:3) = [-1.0_dp, 9.0_dp, -45.0_dp, 0.0_dp, 45.0_dp, -9.0_dp, 1.0_dp]/60.0_dp
     558              :       CASE (8:)
     559            0 :          nstep = 4
     560              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
     561          114 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
     562              :       END SELECT
     563          114 :       oeps1 = 1.0_dp/epsrho
     564              : 
     565              :       CALL get_qs_env(qs_env=qs_env, &
     566              :                       dft_control=dft_control, &
     567              :                       para_env=para_env, &
     568          114 :                       atomic_kind_set=atomic_kind_set)
     569              : 
     570          114 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     571          114 :       CALL section_vals_val_get(xc_fun_section, "_SECTION_PARAMETERS_", i_val=myfun)
     572              : 
     573          114 :       accint = dft_control%qs_control%gapw_control%accurate_xcint
     574              : 
     575          114 :       IF (myfun == xc_none) THEN
     576              :          ! no action needed?
     577              :       ELSE
     578              :          ! calculate fxc
     579              :          CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, para_env, &
     580          114 :                             do_triplet=is_triplet, kind_set_external=kind_set)
     581              : 
     582          114 :          CALL section_vals_val_get(xc_section, "DENSITY_CUTOFF", r_val=density_cut)
     583          114 :          CALL section_vals_val_get(xc_section, "GRADIENT_CUTOFF", r_val=gradient_cut)
     584          114 :          CALL section_vals_val_get(xc_section, "TAU_CUTOFF", r_val=tau_cut)
     585              : 
     586          114 :          nlcc = has_nlcc(kind_set)
     587          114 :          lsd = dft_control%lsd
     588          114 :          nspins = dft_control%nspins
     589          114 :          mspins = nspins
     590          114 :          IF (is_triplet) THEN
     591           12 :             CPASSERT(nspins == 1)
     592           12 :             lsd = .TRUE.
     593           12 :             mspins = 2
     594              :          END IF
     595          114 :          needs = xc_functionals_get_needs(xc_fun_section, lsd=lsd, calc_potential=.TRUE.)
     596          114 :          gradient_f = (needs%drho .OR. needs%drho_spin)
     597          114 :          tau_f = (needs%tau .OR. needs%tau_spin)
     598              : 
     599              :          ! Here starts the loop over all the atoms
     600          386 :          DO ikind = 1, SIZE(atomic_kind_set)
     601          272 :             CALL get_atomic_kind(atomic_kind_set(ikind), atom_list=atom_list, natom=natom)
     602              :             CALL get_qs_kind(kind_set(ikind), paw_atom=paw_atom, &
     603          272 :                              harmonics=harmonics, grid_atom=grid_atom)
     604          272 :             CALL get_qs_kind(kind_set(ikind), basis_set=basis_1c, basis_type="GAPW_1C")
     605              : 
     606          272 :             IF (.NOT. paw_atom) CYCLE
     607              : 
     608          258 :             nr = grid_atom%nr
     609          258 :             na = grid_atom%ng_sphere
     610              : 
     611              :             ! set integration weights
     612          258 :             IF (accint) THEN
     613          138 :                weight_h => grid_atom%weight
     614          138 :                alpha = dft_control%qs_control%gapw_control%aw(ikind)
     615          138 :                IF (ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     616          138 :                   IF (grid_atom%gapw_weight_alpha /= alpha) DEALLOCATE (grid_atom%gapw_weight_s)
     617              :                END IF
     618          138 :                IF (.NOT. ASSOCIATED(grid_atom%gapw_weight_s)) THEN
     619            0 :                   ALLOCATE (grid_atom%gapw_weight_s(na, nr))
     620            0 :                   DO ir = 1, nr
     621            0 :                      agr = 1.0_dp - EXP(-alpha*grid_atom%rad2(ir))
     622            0 :                      grid_atom%gapw_weight_s(:, ir) = grid_atom%weight(:, ir)*agr
     623              :                   END DO
     624            0 :                   grid_atom%gapw_weight_alpha = alpha
     625              :                END IF
     626          138 :                weight_s => grid_atom%gapw_weight_s
     627              :             ELSE
     628          120 :                weight_h => grid_atom%weight
     629          120 :                weight_s => grid_atom%weight
     630              :             END IF
     631              : 
     632              :             ! Prepare the structures needed to calculate and store the xc derivatives
     633              : 
     634              :             ! Array dimension: here anly one dimensional arrays are used,
     635              :             ! i.e. only the first column of deriv_data is read.
     636              :             ! The other two dimensions are set to size equal 1
     637         2580 :             bounds(1:2, 1:3) = 1
     638          258 :             bounds(2, 1) = na
     639          258 :             bounds(2, 2) = nr
     640              : 
     641              :             ! create a place where to put the derivatives
     642          258 :             CALL xc_dset_create(deriv_set, local_bounds=bounds)
     643              :             ! create the place where to store the argument for the functionals
     644              :             CALL xc_rho_set_create(rho_set_h, bounds, rho_cutoff=density_cut, &
     645          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     646              :             CALL xc_rho_set_create(rho_set_s, bounds, rho_cutoff=density_cut, &
     647          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     648              :             CALL xc_rho_set_create(rho1_set_h, bounds, rho_cutoff=density_cut, &
     649          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     650              :             CALL xc_rho_set_create(rho1_set_s, bounds, rho_cutoff=density_cut, &
     651          258 :                                    drho_cutoff=gradient_cut, tau_cutoff=tau_cut)
     652              : 
     653              :             ! allocate the required 3d arrays where to store rho and drho
     654          258 :             CALL xc_rho_set_atom_update(rho_set_h, needs, mspins, bounds)
     655          258 :             CALL xc_rho_set_atom_update(rho_set_s, needs, mspins, bounds)
     656          258 :             CALL xc_rho_set_atom_update(rho1_set_h, needs, mspins, bounds)
     657          258 :             CALL xc_rho_set_atom_update(rho1_set_s, needs, mspins, bounds)
     658              : 
     659              :             ALLOCATE (rho_h(na, nr, nspins), rho_s(na, nr, nspins), &
     660              :                       rho0_h(na, nr, nspins), rho0_s(na, nr, nspins), &
     661         5160 :                       rho1_h(na, nr, nspins), rho1_s(na, nr, nspins))
     662         1806 :             ALLOCATE (vxc_h(na, nr, nspins), vxc_s(na, nr, nspins))
     663          258 :             IF (gradient_f) THEN
     664              :                ALLOCATE (drho_h(4, na, nr, nspins), drho_s(4, na, nr, nspins), &
     665              :                          drho0_h(4, na, nr, nspins), drho0_s(4, na, nr, nspins), &
     666         3520 :                          drho1_h(4, na, nr, nspins), drho1_s(4, na, nr, nspins))
     667         1408 :                ALLOCATE (vxg_h(3, na, nr, nspins), vxg_s(3, na, nr, nspins))
     668              :             END IF
     669          258 :             IF (tau_f) THEN
     670            0 :                CALL create_tau_basis_cache(tau_basis_cache, grid_atom, basis_1c, harmonics)
     671              :                ALLOCATE (tau_h(na, nr, nspins), tau_s(na, nr, nspins), &
     672              :                          tau0_h(na, nr, nspins), tau0_s(na, nr, nspins), &
     673            0 :                          tau1_h(na, nr, nspins), tau1_s(na, nr, nspins))
     674            0 :                ALLOCATE (vtau_h(na, nr, nspins), vtau_s(na, nr, nspins))
     675              :             END IF
     676              :             !
     677              :             ! NLCC: prepare rho and drho of the core charge for this KIND
     678          258 :             donlcc = .FALSE.
     679          258 :             IF (nlcc) THEN
     680            0 :                NULLIFY (rho_nlcc)
     681            0 :                rho_nlcc => kind_set(ikind)%nlcc_pot
     682            0 :                IF (ASSOCIATED(rho_nlcc)) donlcc = .TRUE.
     683              :             END IF
     684              : 
     685              :             ! Distribute the atoms of this kind
     686          258 :             num_pe = para_env%num_pe
     687          258 :             bo = get_limit(natom, num_pe, para_env%mepos)
     688              : 
     689          441 :             DO iat = bo(1), bo(2)
     690          183 :                iatom = atom_list(iat)
     691              :                !
     692          183 :                NULLIFY (int_hh, int_ss)
     693          183 :                rho0_atom => rho0_atom_set(iatom)
     694          183 :                CALL get_rho_atom(rho_atom=rho0_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     695         1098 :                ALLOCATE (fint_ss(nspins), fint_hh(nspins))
     696          366 :                DO ns = 1, nspins
     697          183 :                   nf = SIZE(int_ss(ns)%r_coef, 1)
     698          732 :                   ALLOCATE (fint_ss(ns)%r_coef(nf, nf))
     699          183 :                   nf = SIZE(int_hh(ns)%r_coef, 1)
     700          915 :                   ALLOCATE (fint_hh(ns)%r_coef(nf, nf))
     701              :                END DO
     702              : 
     703              :                ! RHO0
     704       467016 :                rho0_h = 0.0_dp
     705       467016 :                rho0_s = 0.0_dp
     706          183 :                rho0_atom => rho0_atom_set(iatom)
     707          183 :                IF (gradient_f) THEN
     708          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     709              :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
     710          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
     711      1581552 :                   drho0_h = 0.0_dp
     712      1581552 :                   drho0_s = 0.0_dp
     713              :                ELSE
     714           57 :                   NULLIFY (r_h, r_s)
     715           57 :                   CALL get_rho_atom(rho_atom=rho0_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     716           57 :                   rho_d = 0.0_dp
     717              :                END IF
     718         9333 :                DO ir = 1, nr
     719              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     720              :                                         ir, r_h, r_s, rho0_h, rho0_s, dr_h, dr_s, &
     721         9150 :                                         r_h_d, r_s_d, drho0_h, drho0_s)
     722         9333 :                   IF (donlcc) THEN
     723              :                      CALL calc_rho_nlcc(grid_atom, nspins, gradient_f, &
     724            0 :                                         ir, rho_nlcc(:, 1), rho0_h, rho0_s, rho_nlcc(:, 2), drho0_h, drho0_s)
     725              :                   END IF
     726              :                END DO
     727          183 :                IF (tau_f) THEN
     728              :                   !compute tau on the grid all at once
     729            0 :                   CALL calc_tau_atom(tau0_h, tau0_s, rho0_atom, tau_basis_cache, nspins)
     730              :                ELSE
     731          183 :                   tau_d = 0.0_dp
     732              :                END IF
     733              :                ! RHO1
     734       467016 :                rho1_h = 0.0_dp
     735       467016 :                rho1_s = 0.0_dp
     736          183 :                rho1_atom => rho1_atom_set(iatom)
     737          183 :                IF (gradient_f) THEN
     738          126 :                   NULLIFY (r_h, r_s, dr_h, dr_s, r_h_d, r_s_d)
     739              :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s, drho_rad_h=dr_h, &
     740          126 :                                     drho_rad_s=dr_s, rho_rad_h_d=r_h_d, rho_rad_s_d=r_s_d)
     741      1581552 :                   drho1_h = 0.0_dp
     742      1581552 :                   drho1_s = 0.0_dp
     743              :                ELSE
     744           57 :                   NULLIFY (r_h, r_s)
     745           57 :                   CALL get_rho_atom(rho_atom=rho1_atom, rho_rad_h=r_h, rho_rad_s=r_s)
     746              :                END IF
     747         9333 :                DO ir = 1, nr
     748              :                   CALL calc_rho_angular(grid_atom, harmonics, nspins, gradient_f, &
     749              :                                         ir, r_h, r_s, rho1_h, rho1_s, dr_h, dr_s, &
     750         9333 :                                         r_h_d, r_s_d, drho1_h, drho1_s)
     751              :                END DO
     752          183 :                IF (tau_f) THEN
     753              :                   !compute tau on the grid all at once
     754            0 :                   CALL calc_tau_atom(tau1_h, tau1_s, rho1_atom, tau_basis_cache, nspins)
     755              :                END IF
     756              : 
     757         9333 :                DO ir = 1, nr
     758         9333 :                   IF (tau_f) THEN
     759            0 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau1_h, na, ir)
     760            0 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau1_s, na, ir)
     761         9150 :                   ELSE IF (gradient_f) THEN
     762         6300 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, drho1_h, tau_d, na, ir)
     763         6300 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, drho1_s, tau_d, na, ir)
     764              :                   ELSE
     765         2850 :                      CALL fill_rho_set(rho1_set_h, lsd, nspins, needs, rho1_h, rho_d, tau_d, na, ir)
     766         2850 :                      CALL fill_rho_set(rho1_set_s, lsd, nspins, needs, rho1_s, rho_d, tau_d, na, ir)
     767              :                   END IF
     768              :                END DO
     769              : 
     770              :                ! RHO2
     771          183 :                rho2_atom => rho2_atom_set(iatom)
     772              : 
     773         1464 :                DO istep = -nstep, nstep
     774              : 
     775         1281 :                   beta = REAL(istep, KIND=dp)*epsrho
     776              : 
     777      6536943 :                   rho_h = rho0_h + beta*rho1_h
     778      6536943 :                   rho_s = rho0_s + beta*rho1_s
     779         1281 :                   IF (gradient_f) THEN
     780     22140846 :                      drho_h = drho0_h + beta*drho1_h
     781     22140846 :                      drho_s = drho0_s + beta*drho1_s
     782              :                   END IF
     783         1281 :                   IF (tau_f) THEN
     784            0 :                      tau_h = tau0_h + beta*tau1_h
     785            0 :                      tau_s = tau0_s + beta*tau1_s
     786              :                   END IF
     787              :                   !
     788         1281 :                   IF (gradient_f) THEN
     789      2250864 :                      drho_h(4, :, :, :) = NORM2(drho_h(1:3, :, :, :), 1)
     790      2250864 :                      drho_s(4, :, :, :) = NORM2(drho_s(1:3, :, :, :), 1)
     791              :                   END IF
     792              : 
     793        65331 :                   DO ir = 1, nr
     794        65331 :                      IF (tau_f) THEN
     795            0 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_h, na, ir)
     796            0 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_s, na, ir)
     797        64050 :                      ELSE IF (gradient_f) THEN
     798        44100 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, drho_h, tau_d, na, ir)
     799        44100 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, drho_s, tau_d, na, ir)
     800              :                      ELSE
     801        19950 :                         CALL fill_rho_set(rho_set_h, lsd, nspins, needs, rho_h, rho_d, tau_d, na, ir)
     802        19950 :                         CALL fill_rho_set(rho_set_s, lsd, nspins, needs, rho_s, rho_d, tau_d, na, ir)
     803              :                      END IF
     804              :                   END DO
     805              : 
     806              :                   ! hard atom density !
     807         1281 :                   CALL xc_dset_zero_all(deriv_set)
     808              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
     809              :                                          rho_set=rho_set_h, rho1_set=rho1_set_h, &
     810              :                                          deriv_set=deriv_set, &
     811              :                                          w=weight_h, vxc=vxc_h, vxg=vxg_h, vtau=vtau_h, &
     812         1281 :                                          do_triplet=is_triplet)
     813              :                   ! soft atom density !
     814         1281 :                   CALL xc_dset_zero_all(deriv_set)
     815              :                   CALL xc_2nd_deriv_of_r(xc_section=xc_section, &
     816              :                                          rho_set=rho_set_s, rho1_set=rho1_set_s, &
     817              :                                          deriv_set=deriv_set, &
     818              :                                          w=weight_s, vxc=vxc_s, vxg=vxg_s, vtau=vtau_s, &
     819         1281 :                                          do_triplet=is_triplet)
     820              :                   ! potentials
     821         2562 :                   DO ns = 1, nspins
     822      2410793 :                      fint_hh(ns)%r_coef(:, :) = 0.0_dp
     823      2412074 :                      fint_ss(ns)%r_coef(:, :) = 0.0_dp
     824              :                   END DO
     825         1281 :                   IF (gradient_f) THEN
     826              :                      CALL gaVxcgb_GC(vxc_h, vxc_s, vxg_h, vxg_s, fint_hh, fint_ss, &
     827          882 :                                      grid_atom, basis_1c, harmonics, nspins)
     828              :                   ELSE
     829              :                      CALL gaVxcgb_noGC(vxc_h, vxc_s, fint_hh, fint_ss, &
     830          399 :                                        grid_atom, basis_1c, harmonics, nspins)
     831              :                   END IF
     832         1281 :                   IF (tau_f) THEN
     833              :                      CALL dgaVtaudgb(vtau_h, vtau_s, fint_hh, fint_ss, &
     834            0 :                                      tau_basis_cache, nspins)
     835              :                   END IF
     836              :                   ! second derivative gxc
     837         1281 :                   NULLIFY (int_hh, int_ss)
     838         1281 :                   CALL get_rho_atom(rho_atom=rho2_atom, ga_Vlocal_gb_h=int_hh, ga_Vlocal_gb_s=int_ss)
     839         2745 :                   DO ns = 1, nspins
     840      4820305 :                      int_ss(ns)%r_coef(:, :) = int_ss(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_ss(ns)%r_coef(:, :)
     841      4821586 :                      int_hh(ns)%r_coef(:, :) = int_hh(ns)%r_coef(:, :) + oeps1*ak(istep)*fint_hh(ns)%r_coef(:, :)
     842              :                   END DO
     843              :                END DO
     844              :                !
     845          366 :                DO ns = 1, nspins
     846          183 :                   DEALLOCATE (fint_ss(ns)%r_coef)
     847          366 :                   DEALLOCATE (fint_hh(ns)%r_coef)
     848              :                END DO
     849          441 :                DEALLOCATE (fint_ss, fint_hh)
     850              : 
     851              :             END DO ! iat
     852              : 
     853              :             ! Release the xc structure used to store the xc derivatives
     854          258 :             CALL xc_dset_release(deriv_set)
     855          258 :             CALL xc_rho_set_release(rho_set_h)
     856          258 :             CALL xc_rho_set_release(rho_set_s)
     857          258 :             CALL xc_rho_set_release(rho1_set_h)
     858          258 :             CALL xc_rho_set_release(rho1_set_s)
     859              : 
     860          258 :             DEALLOCATE (rho_h, rho_s, rho0_h, rho0_s, rho1_h, rho1_s)
     861          258 :             DEALLOCATE (vxc_h, vxc_s)
     862          258 :             IF (gradient_f) THEN
     863          176 :                DEALLOCATE (drho_h, drho_s, drho0_h, drho0_s, drho1_h, drho1_s)
     864          176 :                DEALLOCATE (vxg_h, vxg_s)
     865              :             END IF
     866          902 :             IF (tau_f) THEN
     867            0 :                DEALLOCATE (tau_h, tau_s, tau0_h, tau0_s, tau1_h, tau1_s)
     868            0 :                DEALLOCATE (vtau_h, vtau_s)
     869            0 :                CALL release_tau_basis_cache(tau_basis_cache)
     870              :             END IF
     871              :          END DO ! ikind
     872              : 
     873              :       END IF !xc_none
     874              : 
     875          114 :       CALL timestop(handle)
     876              : 
     877         8436 :    END SUBROUTINE fgxc_atom_diff
     878              : 
     879              : END MODULE qs_fgxc_atom
        

Generated by: LCOV version 2.0-1