LCOV - code coverage report
Current view: top level - src - qs_fxc.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:9ccafda) Lines: 83.5 % 492 411
Test Date: 2026-10-15 00:55:44 Functions: 100.0 % 7 7

            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 Setup Routine for Fxc Potentials
      10              : !> \par History
      11              : !>     init 17.03.2020
      12              : !>     complete refactoring 08.2026
      13              : !> \author JGH
      14              : ! **************************************************************************************************
      15              : MODULE qs_fxc
      16              : 
      17              :    USE cp_control_types,                ONLY: dft_control_type
      18              :    USE input_constants,                 ONLY: xc_vdw_fun_nonloc
      19              :    USE input_section_types,             ONLY: section_get_ival,&
      20              :                                               section_get_lval,&
      21              :                                               section_get_rval,&
      22              :                                               section_vals_get_subs_vals,&
      23              :                                               section_vals_type,&
      24              :                                               section_vals_val_get
      25              :    USE kinds,                           ONLY: dp
      26              :    USE message_passing,                 ONLY: mp_para_env_type
      27              :    USE pw_env_types,                    ONLY: pw_env_get,&
      28              :                                               pw_env_type
      29              :    USE pw_grids,                        ONLY: pw_grid_compare
      30              :    USE pw_methods,                      ONLY: pw_axpy,&
      31              :                                               pw_scale,&
      32              :                                               pw_transfer,&
      33              :                                               pw_zero
      34              :    USE pw_pool_types,                   ONLY: pw_pool_type
      35              :    USE pw_types,                        ONLY: pw_c1d_gs_type,&
      36              :                                               pw_r3d_rs_type
      37              :    USE qs_dispersion_nonloc,            ONLY: qs_fxc_nlvdw_fdiff
      38              :    USE qs_dispersion_types,             ONLY: qs_dispersion_type
      39              :    USE qs_environment_types,            ONLY: get_qs_env,&
      40              :                                               qs_environment_type
      41              :    USE qs_fxc_atom,                     ONLY: fxc_atom_calc
      42              :    USE qs_kind_types,                   ONLY: qs_kind_type
      43              :    USE qs_ks_types,                     ONLY: qs_ks_env_type
      44              :    USE qs_rho_atom_types,               ONLY: rho_atom_type
      45              :    USE qs_rho_methods,                  ONLY: qs_rho_copy,&
      46              :                                               qs_rho_scale_and_add,&
      47              :                                               qs_rho_transfer
      48              :    USE qs_rho_types,                    ONLY: qs_rho_create,&
      49              :                                               qs_rho_get,&
      50              :                                               qs_rho_release,&
      51              :                                               qs_rho_type
      52              :    USE qs_vxc,                          ONLY: qs_vxc_create
      53              :    USE xc,                              ONLY: xc_calc_2nd_deriv_analytical,&
      54              :                                               xc_calc_2nd_deriv_numerical,&
      55              :                                               xc_prep_2nd_deriv
      56              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      57              :                                               xc_dset_release
      58              :    USE xc_derivatives,                  ONLY: xc_functionals_get_needs
      59              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      60              :    USE xc_rho_set_types,                ONLY: xc_rho_set_create,&
      61              :                                               xc_rho_set_release,&
      62              :                                               xc_rho_set_type,&
      63              :                                               xc_rho_set_update
      64              : #include "./base/base_uses.f90"
      65              : 
      66              :    IMPLICIT NONE
      67              : 
      68              :    PRIVATE
      69              : 
      70              :    ! *** Public subroutines ***
      71              :    PUBLIC :: qs_fxc_create, qs_fxc_prep, qs_fxc_apply
      72              :    PUBLIC :: qs_fxc_fdiff
      73              : 
      74              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_fxc'
      75              : 
      76              : ! **************************************************************************************************
      77              : 
      78              : CONTAINS
      79              : 
      80              : ! **************************************************************************************************
      81              : !> \brief ...
      82              : !> \param qs_env ...
      83              : !> \param rho0_struct ...
      84              : !> \param rho1_struct ...
      85              : !> \param rho0_atom_set ...
      86              : !> \param xc_section ...
      87              : !> \param do_onecenter ...
      88              : !> \param fxc_rho ...
      89              : !> \param fxc_tau ...
      90              : !> \param rho1_atom_set ...
      91              : !> \param do_scale ...
      92              : !> \param is_triplet ...
      93              : !> \param spinflip ...
      94              : !> \param no_weights ...
      95              : !> \param uf_grid_results ...
      96              : !> \param pw_env_ext ...
      97              : !> \param kind_set_external ...
      98              : !> \param para_env_external ...
      99              : !> \param dispersion_env ...
     100              : !> \param compute_virial ...
     101              : !> \param virial_xc ...
     102              : ! **************************************************************************************************
     103         3984 :    SUBROUTINE qs_fxc_create(qs_env, rho0_struct, rho1_struct, rho0_atom_set, &
     104              :                             xc_section, do_onecenter, &
     105              :                             fxc_rho, fxc_tau, rho1_atom_set, &
     106              :                             do_scale, is_triplet, spinflip, no_weights, uf_grid_results, &
     107              :                             pw_env_ext, kind_set_external, para_env_external, &
     108              :                             dispersion_env, compute_virial, virial_xc)
     109              : 
     110              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     111              :       TYPE(qs_rho_type), POINTER                         :: rho0_struct, rho1_struct
     112              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set
     113              :       TYPE(section_vals_type), POINTER                   :: xc_section
     114              :       LOGICAL, INTENT(IN)                                :: do_onecenter
     115              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
     116              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set
     117              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_scale, is_triplet, spinflip, &
     118              :                                                             no_weights, uf_grid_results
     119              :       TYPE(pw_env_type), OPTIONAL, POINTER               :: pw_env_ext
     120              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     121              :          POINTER                                         :: kind_set_external
     122              :       TYPE(mp_para_env_type), INTENT(IN), OPTIONAL       :: para_env_external
     123              :       TYPE(qs_dispersion_type), OPTIONAL, POINTER        :: dispersion_env
     124              :       LOGICAL, INTENT(IN), OPTIONAL                      :: compute_virial
     125              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT), &
     126              :          OPTIONAL                                        :: virial_xc
     127              : 
     128              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_create'
     129              : 
     130              :       INTEGER                                            :: handle, ispin, nspins, nsteps, order, vdw
     131              :       LOGICAL                                            :: do_virial, do_w, ret_uf, uf_grid, vdw_nl
     132              :       REAL(KIND=dp)                                      :: eps_delta, factor
     133              :       TYPE(dft_control_type), POINTER                    :: dft_control
     134         3984 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     135              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g
     136              :       TYPE(pw_env_type), POINTER                         :: pw_env
     137              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     138         3984 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
     139         3984 :                                                             fxc_tau_uf, fxc_vdw, rho1_r, rho_r
     140              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, weights, weights_uf
     141              :       TYPE(qs_rho_type), POINTER                         :: rho0_uf, rho1_uf
     142              : 
     143         3984 :       CALL timeset(routineN, handle)
     144              : 
     145         3984 :       do_virial = .FALSE.
     146         3984 :       IF (PRESENT(compute_virial)) do_virial = compute_virial
     147              : 
     148         3984 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     149              : 
     150         3984 :       IF (PRESENT(pw_env_ext)) THEN
     151            0 :          pw_env => pw_env_ext
     152              :       ELSE
     153         3984 :          CALL get_qs_env(qs_env, pw_env=pw_env)
     154              :       END IF
     155         3984 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
     156         3984 :       uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     157              : 
     158         3984 :       nspins = dft_control%nspins
     159         3984 :       IF (ASSOCIATED(fxc_rho)) THEN
     160            0 :          CPASSERT(nspins == SIZE(fxc_rho))
     161              :       END IF
     162         3984 :       IF (ASSOCIATED(fxc_tau)) THEN
     163            0 :          CPASSERT(nspins == SIZE(fxc_tau))
     164              :       END IF
     165              : 
     166         3984 :       NULLIFY (rho_nlcc, rho_nlcc_g)
     167         3984 :       CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
     168         3984 :       IF (ASSOCIATED(rho_nlcc)) THEN
     169           12 :          NULLIFY (rho_r, rho_g)
     170           12 :          CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
     171           12 :          factor = 1.0_dp
     172           24 :          DO ispin = 1, nspins
     173           12 :             CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     174           24 :             CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     175              :          END DO
     176              :       END IF
     177              : 
     178         3984 :       do_w = .TRUE.
     179         3984 :       IF (PRESENT(no_weights)) do_w = .NOT. no_weights
     180           62 :       IF (do_w) THEN
     181         3922 :          CALL get_qs_env(qs_env, xcint_weights=weights)
     182              :       ELSE
     183           62 :          NULLIFY (weights)
     184              :       END IF
     185              : 
     186         3984 :       NULLIFY (fxc_rho_lo, fxc_tau_lo)
     187         3984 :       IF (uf_grid) THEN
     188           24 :          IF (PRESENT(uf_grid_results)) THEN
     189            8 :             ret_uf = uf_grid_results
     190              :          ELSE
     191              :             ret_uf = .FALSE.
     192              :          END IF
     193           24 :          NULLIFY (weights_uf)
     194           24 :          IF (ASSOCIATED(weights)) THEN
     195           16 :             ALLOCATE (weights_uf)
     196           16 :             CALL xc_pw_pool%create_pw(weights_uf)
     197              :             BLOCK
     198              :                TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
     199           16 :                CALL auxbas_pw_pool%create_pw(weights_g)
     200           16 :                CALL xc_pw_pool%create_pw(weights_g_uf)
     201           16 :                CALL pw_transfer(weights, weights_g)
     202           16 :                CALL pw_transfer(weights_g, weights_g_uf)
     203           16 :                CALL pw_transfer(weights_g_uf, weights_uf)
     204           16 :                CALL xc_pw_pool%give_back_pw(weights_g_uf)
     205           32 :                CALL auxbas_pw_pool%give_back_pw(weights_g)
     206              :             END BLOCK
     207              :          END IF
     208              :          !
     209           24 :          ALLOCATE (rho0_uf, rho1_uf)
     210           24 :          CALL qs_rho_create(rho0_uf)
     211           24 :          CALL qs_rho_create(rho1_uf)
     212           24 :          CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
     213           24 :          CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
     214              :          !
     215           24 :          NULLIFY (fxc_rho_uf, fxc_tau_uf)
     216              :          CALL qs_fxc_calculate(rho0_uf, rho1_uf, xc_section, weights_uf, xc_pw_pool, &
     217              :                                fxc_rho_uf, fxc_tau_uf, &
     218              :                                is_triplet=is_triplet, spinflip=spinflip, &
     219           24 :                                compute_virial=do_virial, virial_xc=virial_xc)
     220              :          !
     221           24 :          CALL qs_rho_release(rho0_uf)
     222           24 :          CALL qs_rho_release(rho1_uf)
     223           24 :          DEALLOCATE (rho0_uf, rho1_uf)
     224           24 :          IF (ASSOCIATED(weights_uf)) THEN
     225           16 :             CALL xc_pw_pool%give_back_pw(weights_uf)
     226           16 :             DEALLOCATE (weights_uf)
     227              :          END IF
     228           24 :          IF (ret_uf) THEN
     229            8 :             fxc_rho_lo => fxc_rho_uf
     230            8 :             fxc_tau_lo => fxc_tau_uf
     231              :          ELSE
     232           16 :             IF (ASSOCIATED(fxc_rho_uf)) THEN
     233           64 :                ALLOCATE (fxc_rho_lo(SIZE(fxc_rho_uf)))
     234           32 :                DO ispin = 1, SIZE(fxc_rho_uf)
     235           16 :                   CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
     236              :                   BLOCK
     237              :                      TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
     238           16 :                      CALL auxbas_pw_pool%create_pw(fxc_g)
     239           16 :                      CALL xc_pw_pool%create_pw(fxc_g_uf)
     240           16 :                      CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
     241           16 :                      CALL pw_transfer(fxc_g_uf, fxc_g)
     242           16 :                      CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
     243           16 :                      CALL xc_pw_pool%give_back_pw(fxc_g_uf)
     244           32 :                      CALL auxbas_pw_pool%give_back_pw(fxc_g)
     245              :                   END BLOCK
     246           32 :                   CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
     247              :                END DO
     248           16 :                DEALLOCATE (fxc_rho_uf)
     249              :             END IF
     250           16 :             IF (ASSOCIATED(fxc_tau_uf)) THEN
     251            0 :                ALLOCATE (fxc_tau_lo(SIZE(fxc_tau_uf)))
     252            0 :                DO ispin = 1, SIZE(fxc_tau_uf)
     253            0 :                   CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
     254              :                   BLOCK
     255              :                      TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
     256            0 :                      CALL auxbas_pw_pool%create_pw(fxc_g)
     257            0 :                      CALL xc_pw_pool%create_pw(fxc_g_uf)
     258            0 :                      CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
     259            0 :                      CALL pw_transfer(fxc_g_uf, fxc_g)
     260            0 :                      CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
     261            0 :                      CALL xc_pw_pool%give_back_pw(fxc_g_uf)
     262            0 :                      CALL auxbas_pw_pool%give_back_pw(fxc_g)
     263              :                   END BLOCK
     264            0 :                   CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
     265              :                END DO
     266            0 :                DEALLOCATE (fxc_tau_uf)
     267              :             END IF
     268              :          END IF
     269              : 
     270              :       ELSE
     271              :          CALL qs_fxc_calculate(rho0_struct, rho1_struct, xc_section, weights, auxbas_pw_pool, &
     272              :                                fxc_rho_lo, fxc_tau_lo, &
     273              :                                is_triplet=is_triplet, spinflip=spinflip, &
     274         3960 :                                compute_virial=do_virial, virial_xc=virial_xc)
     275              :       END IF
     276              : 
     277              :       ! nonlocal vdW functionals
     278         3984 :       vdW_nl = .FALSE.
     279         3984 :       IF (PRESENT(dispersion_env)) THEN
     280         3310 :          CALL section_vals_val_get(xc_section, "VDW_POTENTIAL%POTENTIAL_TYPE", i_val=vdw)
     281         3310 :          vdW_nl = (vdw == xc_vdw_fun_nonloc)
     282         3310 :          IF (vdW_nl) THEN
     283            0 :             nsteps = section_get_ival(xc_section, "NSTEPS")
     284            0 :             order = 2*nsteps
     285            0 :             eps_delta = section_get_rval(xc_section, "STEP_SIZE")
     286            0 :             CALL qs_rho_get(rho1_struct, rho_r=rho1_r)
     287            0 :             ALLOCATE (fxc_vdw(nspins))
     288            0 :             DO ispin = 1, nspins
     289            0 :                CALL auxbas_pw_pool%create_pw(fxc_vdw(ispin))
     290              :             END DO
     291              :             CALL qs_fxc_nlvdw_fdiff(qs_env, dispersion_env, rho_r, rho1_r, &
     292            0 :                                     order, eps_delta, fxc_vdw)
     293              :          END IF
     294              :       END IF
     295              : 
     296              :       ! de-apply NLCC density
     297         3984 :       IF (ASSOCIATED(rho_nlcc)) THEN
     298           12 :          factor = -1.0_dp
     299           24 :          DO ispin = 1, nspins
     300           12 :             CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     301           24 :             CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     302              :          END DO
     303              :       END IF
     304              : 
     305              :       ! return potentials
     306         3984 :       IF (ASSOCIATED(fxc_rho)) THEN
     307            0 :          DO ispin = 1, MIN(SIZE(fxc_rho_lo), SIZE(fxc_rho))
     308            0 :             CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
     309              :          END DO
     310            0 :          DO ispin = 1, SIZE(fxc_rho_lo)
     311            0 :             CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
     312              :          END DO
     313            0 :          DEALLOCATE (fxc_rho_lo)
     314              :       ELSE
     315         3984 :          fxc_rho => fxc_rho_lo
     316              :       END IF
     317         3984 :       IF (ASSOCIATED(fxc_tau)) THEN
     318            0 :          IF (ASSOCIATED(fxc_tau_lo)) THEN
     319            0 :             DO ispin = 1, MIN(SIZE(fxc_tau_lo), SIZE(fxc_tau))
     320            0 :                CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
     321              :             END DO
     322            0 :             DO ispin = 1, SIZE(fxc_tau_lo)
     323            0 :                CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
     324              :             END DO
     325            0 :             DEALLOCATE (fxc_tau_lo)
     326              :          ELSE
     327            0 :             DO ispin = 1, nspins
     328            0 :                CALL pw_zero(fxc_tau(ispin))
     329              :             END DO
     330              :          END IF
     331              :       ELSE
     332         3984 :          fxc_tau => fxc_tau_lo
     333              :       END IF
     334              : 
     335              :       ! Add possible nl-vdW pootential
     336         3984 :       IF (vdW_nl) THEN
     337            0 :          DO ispin = 1, nspins
     338            0 :             CALL pw_axpy(fxc_vdw(ispin), fxc_rho(ispin), 1.0_dp)
     339            0 :             CALL auxbas_pw_pool%give_back_pw(fxc_vdw(ispin))
     340              :          END DO
     341            0 :          DEALLOCATE (fxc_vdw)
     342              :       END IF
     343              : 
     344         3984 :       IF (do_onecenter) THEN
     345              :          CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
     346              :                             do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
     347              :                             para_env_ext=para_env_external, &
     348          370 :                             kind_set_external=kind_set_external)
     349              :       END IF
     350              : 
     351         3984 :       CALL timestop(handle)
     352              : 
     353         3984 :    END SUBROUTINE qs_fxc_create
     354              : 
     355              : ! **************************************************************************************************
     356              : !> \brief ...
     357              : !> \param rho0 ...
     358              : !> \param rho1 ...
     359              : !> \param xc_section ...
     360              : !> \param weights ...
     361              : !> \param auxbas_pw_pool ...
     362              : !> \param fxc_rho ...
     363              : !> \param fxc_tau ...
     364              : !> \param is_triplet ...
     365              : !> \param spinflip ...
     366              : !> \param compute_virial ...
     367              : !> \param virial_xc ...
     368              : ! **************************************************************************************************
     369         3984 :    SUBROUTINE qs_fxc_calculate(rho0, rho1, xc_section, weights, auxbas_pw_pool, &
     370              :                                fxc_rho, fxc_tau, is_triplet, spinflip, &
     371              :                                compute_virial, virial_xc)
     372              : 
     373              :       TYPE(qs_rho_type), POINTER                         :: rho0, rho1
     374              :       TYPE(section_vals_type), POINTER                   :: xc_section
     375              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     376              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     377              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
     378              :       LOGICAL, INTENT(IN), OPTIONAL                      :: is_triplet, spinflip, compute_virial
     379              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT), &
     380              :          OPTIONAL                                        :: virial_xc
     381              : 
     382              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_calculate'
     383              : 
     384              :       INTEGER                                            :: handle, ispin, mspins, nspins
     385              :       INTEGER, DIMENSION(2, 3)                           :: bo
     386              :       LOGICAL                                            :: do_analytic, do_sf, do_triplet, &
     387              :                                                             do_virial, lsd
     388         3984 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: vxg
     389         7968 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho0_g, rho1_g
     390        11952 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho0_r, rho1_r, tau0_r, tau1_r
     391              :       TYPE(qs_rho_type), POINTER                         :: rhot0, rhot1
     392              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     393              :       TYPE(xc_derivative_set_type)                       :: xc_deriv_set
     394              :       TYPE(xc_rho_cflags_type)                           :: needs
     395              :       TYPE(xc_rho_set_type)                              :: rho0_set, rho1_set
     396              : 
     397         3984 :       CALL timeset(routineN, handle)
     398              : 
     399         3984 :       do_triplet = .FALSE.
     400         3984 :       IF (PRESENT(is_triplet)) do_triplet = is_triplet
     401              : 
     402         3984 :       do_sf = .FALSE.
     403         3984 :       IF (PRESENT(spinflip)) do_sf = spinflip
     404              : 
     405         3984 :       do_virial = .FALSE.
     406         3984 :       IF (PRESENT(compute_virial)) do_virial = compute_virial
     407              : 
     408         3984 :       do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
     409              : 
     410         3984 :       CALL qs_rho_get(rho0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
     411         3984 :       CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
     412         3984 :       NULLIFY (rho1_g)
     413              : 
     414         3984 :       mspins = SIZE(rho0_r)
     415         3984 :       nspins = SIZE(rho0_r)
     416         3984 :       lsd = (nspins == 2)
     417         3984 :       IF (nspins == 1 .AND. do_triplet) THEN
     418            6 :          nspins = 2
     419            6 :          lsd = .TRUE.
     420         3978 :       ELSE IF (do_sf) THEN
     421          104 :          nspins = 1
     422          104 :          mspins = 1
     423          104 :          lsd = .TRUE.
     424              :       END IF
     425              : 
     426         3984 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
     427         3984 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
     428         3984 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     429         3984 :       needs = xc_functionals_get_needs(xc_fun_section, lsd, .TRUE.)
     430        16396 :       ALLOCATE (fxc_rho(mspins))
     431         8428 :       DO ispin = 1, mspins
     432         4444 :          CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
     433         8428 :          CALL pw_zero(fxc_rho(ispin))
     434              :       END DO
     435         3984 :       IF (needs%tau .OR. needs%tau_spin) THEN
     436          116 :          IF (.NOT. ASSOCIATED(tau1_r)) THEN
     437            0 :             CPABORT("Tau-dependent functionals requires allocated kinetic energy density grid")
     438              :          END IF
     439          356 :          ALLOCATE (fxc_tau(mspins))
     440          240 :          DO ispin = 1, mspins
     441          124 :             CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
     442         4108 :             CALL pw_zero(fxc_tau(ispin))
     443              :          END DO
     444              :       END IF
     445              : 
     446         3984 :       IF (mspins == 1 .AND. do_triplet) THEN
     447              :          ! split the density and response density arrays for triplet calculation
     448            6 :          ALLOCATE (rhot0)
     449            6 :          CALL qs_rho_create(rhot0)
     450            6 :          CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
     451              :          !
     452            6 :          ALLOCATE (rhot1)
     453            6 :          CALL qs_rho_create(rhot1)
     454            6 :          CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
     455              :          !
     456            6 :          CALL qs_rho_get(rhot0, rho_r=rho0_r, rho_g=rho0_g, tau_r=tau0_r)
     457            6 :          CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
     458              : 
     459              :          CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
     460            6 :                                 xc_section=xc_section, tau_r=tau0_r)
     461           60 :          bo = rho1_r(1)%pw_grid%bounds_local
     462              :          ! create the place where to store the argument for the functionals
     463              :          CALL xc_rho_set_create(rho1_set, bo, &
     464              :                                 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
     465              :                                 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
     466            6 :                                 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
     467              : 
     468              :          ! calculate the arguments needed by the functionals
     469              :          CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
     470              :                                 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
     471              :                                 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
     472            6 :                                 auxbas_pw_pool, spinflip=do_sf)
     473              :       ELSE
     474              :          CALL xc_prep_2nd_deriv(xc_deriv_set, rho0_set, rho0_r, auxbas_pw_pool, weights, &
     475         3978 :                                 xc_section=xc_section, tau_r=tau0_r)
     476        39780 :          bo = rho1_r(1)%pw_grid%bounds_local
     477              :          ! create the place where to store the argument for the functionals
     478              :          CALL xc_rho_set_create(rho1_set, bo, &
     479              :                                 rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
     480              :                                 drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
     481         3978 :                                 tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
     482              : 
     483              :          ! calculate the arguments needed by the functionals
     484              :          CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
     485              :                                 section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
     486              :                                 section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
     487         3978 :                                 auxbas_pw_pool, spinflip=do_sf)
     488              :       END IF
     489              : 
     490         3984 :       IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
     491              : 
     492              :          CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
     493              :                                            rho1_set, auxbas_pw_pool, xc_section, &
     494              :                                            gapw=.FALSE., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
     495            6 :                                            compute_virial=compute_virial, virial_xc=virial_xc)
     496              : 
     497         3978 :       ELSE IF (do_analytic) THEN
     498              : 
     499              :          CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, rho0_set, &
     500              :                                            rho1_set, auxbas_pw_pool, xc_section, &
     501              :                                            gapw=.FALSE., vxg=vxg, spinflip=do_sf, &
     502         3910 :                                            compute_virial=compute_virial, virial_xc=virial_xc)
     503              : 
     504              :       ELSE
     505              : 
     506              :          CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, rho0_set, rho1_r, rho1_g, tau1_r, &
     507              :                                           auxbas_pw_pool, weights, xc_section, &
     508           68 :                                           do_triplet, compute_virial, virial_xc, xc_deriv_set)
     509              : 
     510              :       END IF
     511              : 
     512         3984 :       IF (mspins == 1 .AND. do_triplet) THEN
     513            6 :          CALL qs_rho_release(rhot0)
     514            6 :          DEALLOCATE (rhot0)
     515            6 :          CALL qs_rho_release(rhot1)
     516            6 :          DEALLOCATE (rhot1)
     517              :       END IF
     518              : 
     519         3984 :       CALL xc_dset_release(xc_deriv_set)
     520         3984 :       CALL xc_rho_set_release(rho0_set)
     521         3984 :       CALL xc_rho_set_release(rho1_set)
     522              : 
     523         3984 :       CALL timestop(handle)
     524              : 
     525       171312 :    END SUBROUTINE qs_fxc_calculate
     526              : 
     527              : ! **************************************************************************************************
     528              : !> \brief ...
     529              : !> \param qs_env ...
     530              : !> \param rho0_struct ...
     531              : !> \param xc_rho_set ...
     532              : !> \param xc_deriv_set ...
     533              : !> \param xc_section ...
     534              : !> \param pw_env_ext ...
     535              : !> \param is_triplet ...
     536              : ! **************************************************************************************************
     537         2882 :    SUBROUTINE qs_fxc_prep(qs_env, rho0_struct, xc_rho_set, xc_deriv_set, &
     538              :                           xc_section, pw_env_ext, is_triplet)
     539              : 
     540              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     541              :       TYPE(qs_rho_type), POINTER                         :: rho0_struct
     542              :       TYPE(xc_rho_set_type)                              :: xc_rho_set
     543              :       TYPE(xc_derivative_set_type)                       :: xc_deriv_set
     544              :       TYPE(section_vals_type), POINTER                   :: xc_section
     545              :       TYPE(pw_env_type), OPTIONAL, POINTER               :: pw_env_ext
     546              :       LOGICAL, INTENT(IN), OPTIONAL                      :: is_triplet
     547              : 
     548              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_prep'
     549              : 
     550              :       INTEGER                                            :: handle, ispin, nspins
     551              :       LOGICAL                                            :: uf_grid
     552              :       REAL(KIND=dp)                                      :: factor
     553              :       TYPE(dft_control_type), POINTER                    :: dft_control
     554         2882 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho_g
     555              :       TYPE(pw_c1d_gs_type), POINTER                      :: rho_nlcc_g
     556              :       TYPE(pw_env_type), POINTER                         :: pw_env
     557              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     558         2882 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho_r
     559              :       TYPE(pw_r3d_rs_type), POINTER                      :: rho_nlcc, weights, weights_uf
     560              :       TYPE(qs_rho_type), POINTER                         :: rho0_uf
     561              : 
     562         2882 :       CALL timeset(routineN, handle)
     563              : 
     564         2882 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     565              : 
     566         2882 :       IF (PRESENT(pw_env_ext)) THEN
     567         2882 :          pw_env => pw_env_ext
     568              :       ELSE
     569            0 :          CALL get_qs_env(qs_env, pw_env=pw_env)
     570              :       END IF
     571         2882 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
     572         2882 :       uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     573              : 
     574         2882 :       nspins = dft_control%nspins
     575              : 
     576         2882 :       NULLIFY (rho_nlcc, rho_nlcc_g)
     577         2882 :       CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
     578         2882 :       IF (ASSOCIATED(rho_nlcc)) THEN
     579           38 :          NULLIFY (rho_r, rho_g)
     580           38 :          CALL qs_rho_get(rho0_struct, rho_r=rho_r, rho_g=rho_g)
     581           38 :          factor = 1.0_dp
     582           76 :          DO ispin = 1, nspins
     583           38 :             CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     584           76 :             CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     585              :          END DO
     586              :       END IF
     587              : 
     588         2882 :       NULLIFY (weights)
     589         2882 :       CALL get_qs_env(qs_env, xcint_weights=weights)
     590              : 
     591         2882 :       IF (uf_grid) THEN
     592           30 :          NULLIFY (weights_uf)
     593           30 :          IF (ASSOCIATED(weights)) THEN
     594           30 :             ALLOCATE (weights_uf)
     595           30 :             CALL xc_pw_pool%create_pw(weights_uf)
     596              :             BLOCK
     597              :                TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
     598           30 :                CALL auxbas_pw_pool%create_pw(weights_g)
     599           30 :                CALL xc_pw_pool%create_pw(weights_g_uf)
     600           30 :                CALL pw_transfer(weights, weights_g)
     601           30 :                CALL pw_transfer(weights_g, weights_g_uf)
     602           30 :                CALL pw_transfer(weights_g_uf, weights_uf)
     603           30 :                CALL xc_pw_pool%give_back_pw(weights_g_uf)
     604           60 :                CALL auxbas_pw_pool%give_back_pw(weights_g)
     605              :             END BLOCK
     606              :          END IF
     607              :          !
     608           30 :          ALLOCATE (rho0_uf)
     609           30 :          CALL qs_rho_create(rho0_uf)
     610           30 :          CALL qs_rho_transfer(rho0_struct, rho0_uf, auxbas_pw_pool, xc_pw_pool)
     611              :          !
     612              :          CALL qs_fxc_deriv(rho0_uf, xc_rho_set, xc_deriv_set, &
     613           30 :                            xc_section, weights_uf, xc_pw_pool, is_triplet)
     614              :          !
     615           30 :          CALL qs_rho_release(rho0_uf)
     616           30 :          DEALLOCATE (rho0_uf)
     617           30 :          IF (ASSOCIATED(weights_uf)) THEN
     618           30 :             CALL xc_pw_pool%give_back_pw(weights_uf)
     619           30 :             DEALLOCATE (weights_uf)
     620              :          END IF
     621              :       ELSE
     622              :          CALL qs_fxc_deriv(rho0_struct, xc_rho_set, xc_deriv_set, &
     623         2852 :                            xc_section, weights, auxbas_pw_pool, is_triplet)
     624              :       END IF
     625              : 
     626              :       ! de-apply NLCC density
     627         2882 :       IF (ASSOCIATED(rho_nlcc)) THEN
     628           38 :          factor = -1.0_dp
     629           76 :          DO ispin = 1, nspins
     630           38 :             CALL pw_axpy(rho_nlcc, rho_r(ispin), factor)
     631           76 :             CALL pw_axpy(rho_nlcc_g, rho_g(ispin), factor)
     632              :          END DO
     633              :       END IF
     634              : 
     635         2882 :       CALL timestop(handle)
     636              : 
     637         2882 :    END SUBROUTINE qs_fxc_prep
     638              : 
     639              : ! **************************************************************************************************
     640              : !> \brief ...
     641              : !> \param rho0 ...
     642              : !> \param xc_rho_set ...
     643              : !> \param xc_deriv_set ...
     644              : !> \param xc_section ...
     645              : !> \param weights ...
     646              : !> \param auxbas_pw_pool ...
     647              : !> \param is_triplet ...
     648              : ! **************************************************************************************************
     649         2882 :    SUBROUTINE qs_fxc_deriv(rho0, xc_rho_set, xc_deriv_set, xc_section, weights, auxbas_pw_pool, &
     650              :                            is_triplet)
     651              : 
     652              :       TYPE(qs_rho_type), POINTER                         :: rho0
     653              :       TYPE(xc_rho_set_type)                              :: xc_rho_set
     654              :       TYPE(xc_derivative_set_type)                       :: xc_deriv_set
     655              :       TYPE(section_vals_type), POINTER                   :: xc_section
     656              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     657              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     658              :       LOGICAL, INTENT(IN)                                :: is_triplet
     659              : 
     660              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_deriv'
     661              : 
     662              :       INTEGER                                            :: handle
     663         2882 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho0_r, tau0_r
     664              :       TYPE(qs_rho_type), POINTER                         :: rhot0
     665              : 
     666         2882 :       CALL timeset(routineN, handle)
     667              : 
     668         2882 :       NULLIFY (rho0_r, tau0_r)
     669         2882 :       IF (is_triplet) THEN
     670              :          ! split the density and response density arrays for triplet calculation
     671          110 :          ALLOCATE (rhot0)
     672          110 :          CALL qs_rho_create(rhot0)
     673          110 :          CALL qs_rho_copy(rho0, rhot0, auxbas_pw_pool, 2, factor=2.0_dp)
     674          110 :          CALL qs_rho_get(rhot0, rho_r=rho0_r, tau_r=tau0_r)
     675              :          CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
     676          110 :                                 xc_section=xc_section, tau_r=tau0_r)
     677          110 :          CALL qs_rho_release(rhot0)
     678          110 :          DEALLOCATE (rhot0)
     679              :       ELSE
     680         2772 :          CALL qs_rho_get(rho0, rho_r=rho0_r, tau_r=tau0_r)
     681              :          CALL xc_prep_2nd_deriv(xc_deriv_set, xc_rho_set, rho0_r, auxbas_pw_pool, weights, &
     682         2772 :                                 xc_section=xc_section, tau_r=tau0_r)
     683              :       END IF
     684              : 
     685         2882 :       CALL timestop(handle)
     686              : 
     687         2882 :    END SUBROUTINE qs_fxc_deriv
     688              : 
     689              : ! **************************************************************************************************
     690              : !> \brief ...
     691              : !> \param qs_env ...
     692              : !> \param xc_deriv_set ...
     693              : !> \param xc_rho_set ...
     694              : !> \param rho1_struct ...
     695              : !> \param rho0_atom_set ...
     696              : !> \param xc_section ...
     697              : !> \param do_onecenter ...
     698              : !> \param fxc_rho ...
     699              : !> \param fxc_tau ...
     700              : !> \param rho1_atom_set ...
     701              : !> \param do_scale ...
     702              : !> \param is_triplet ...
     703              : !> \param spinflip ...
     704              : !> \param pw_env_ext ...
     705              : !> \param kind_set_external ...
     706              : !> \param para_env_external ...
     707              : !> \param compute_virial ...
     708              : !> \param virial_xc ...
     709              : ! **************************************************************************************************
     710        22898 :    SUBROUTINE qs_fxc_apply(qs_env, xc_deriv_set, xc_rho_set, rho1_struct, rho0_atom_set, &
     711              :                            xc_section, do_onecenter, fxc_rho, fxc_tau, rho1_atom_set, &
     712              :                            do_scale, is_triplet, spinflip, pw_env_ext, &
     713              :                            kind_set_external, para_env_external, compute_virial, virial_xc)
     714              : 
     715              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     716              :       TYPE(xc_derivative_set_type)                       :: xc_deriv_set
     717              :       TYPE(xc_rho_set_type)                              :: xc_rho_set
     718              :       TYPE(qs_rho_type), POINTER                         :: rho1_struct
     719              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho0_atom_set
     720              :       TYPE(section_vals_type), POINTER                   :: xc_section
     721              :       LOGICAL, INTENT(IN)                                :: do_onecenter
     722              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
     723              :       TYPE(rho_atom_type), DIMENSION(:), POINTER         :: rho1_atom_set
     724              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_scale, is_triplet, spinflip
     725              :       TYPE(pw_env_type), OPTIONAL, POINTER               :: pw_env_ext
     726              :       TYPE(qs_kind_type), DIMENSION(:), OPTIONAL, &
     727              :          POINTER                                         :: kind_set_external
     728              :       TYPE(mp_para_env_type), INTENT(IN), OPTIONAL       :: para_env_external
     729              :       LOGICAL, INTENT(IN), OPTIONAL                      :: compute_virial
     730              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT), &
     731              :          OPTIONAL                                        :: virial_xc
     732              : 
     733              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_apply'
     734              : 
     735              :       INTEGER                                            :: handle, ispin, nspins
     736              :       LOGICAL                                            :: do_virial, uf_grid
     737              :       TYPE(dft_control_type), POINTER                    :: dft_control
     738              :       TYPE(pw_env_type), POINTER                         :: pw_env
     739              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool, xc_pw_pool
     740        22898 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho_lo, fxc_rho_uf, fxc_tau_lo, &
     741        22898 :                                                             fxc_tau_uf
     742              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights, weights_uf
     743              :       TYPE(qs_rho_type), POINTER                         :: rho1_uf
     744              : 
     745        22898 :       CALL timeset(routineN, handle)
     746              : 
     747        22898 :       do_virial = .FALSE.
     748        22898 :       IF (PRESENT(compute_virial)) do_virial = compute_virial
     749              : 
     750        22898 :       CALL get_qs_env(qs_env, dft_control=dft_control)
     751              : 
     752        22898 :       IF (PRESENT(pw_env_ext)) THEN
     753         9786 :          pw_env => pw_env_ext
     754              :       ELSE
     755        13112 :          CALL get_qs_env(qs_env, pw_env=pw_env)
     756              :       END IF
     757        22898 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, xc_pw_pool=xc_pw_pool)
     758        22898 :       uf_grid = .NOT. pw_grid_compare(auxbas_pw_pool%pw_grid, xc_pw_pool%pw_grid)
     759              : 
     760        22898 :       nspins = dft_control%nspins
     761        22898 :       IF (ASSOCIATED(fxc_rho)) THEN
     762         9786 :          CPASSERT(nspins == SIZE(fxc_rho))
     763              :       END IF
     764        22898 :       IF (ASSOCIATED(fxc_tau)) THEN
     765            0 :          CPASSERT(nspins == SIZE(fxc_tau))
     766              :       END IF
     767              : 
     768        22898 :       CALL get_qs_env(qs_env, xcint_weights=weights)
     769              : 
     770        22898 :       NULLIFY (fxc_rho_lo, fxc_tau_lo)
     771        22898 :       IF (uf_grid) THEN
     772          198 :          NULLIFY (weights_uf)
     773          198 :          IF (ASSOCIATED(weights)) THEN
     774          198 :             ALLOCATE (weights_uf)
     775          198 :             CALL xc_pw_pool%create_pw(weights_uf)
     776              :             BLOCK
     777              :                TYPE(pw_c1d_gs_type) :: weights_g, weights_g_uf
     778          198 :                CALL auxbas_pw_pool%create_pw(weights_g)
     779          198 :                CALL xc_pw_pool%create_pw(weights_g_uf)
     780          198 :                CALL pw_transfer(weights, weights_g)
     781          198 :                CALL pw_transfer(weights_g, weights_g_uf)
     782          198 :                CALL pw_transfer(weights_g_uf, weights_uf)
     783          198 :                CALL xc_pw_pool%give_back_pw(weights_g_uf)
     784          396 :                CALL auxbas_pw_pool%give_back_pw(weights_g)
     785              :             END BLOCK
     786              :          END IF
     787              :          !
     788          198 :          ALLOCATE (rho1_uf)
     789          198 :          CALL qs_rho_create(rho1_uf)
     790          198 :          CALL qs_rho_transfer(rho1_struct, rho1_uf, auxbas_pw_pool, xc_pw_pool)
     791              :          !
     792          198 :          NULLIFY (fxc_rho_uf, fxc_tau_uf)
     793              :          CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_uf, xc_section, &
     794              :                           weights_uf, xc_pw_pool, fxc_rho_uf, fxc_tau_uf, &
     795              :                           is_triplet=is_triplet, spinflip=spinflip, &
     796          198 :                           compute_virial=do_virial, virial_xc=virial_xc)
     797              :          !
     798          198 :          CALL qs_rho_release(rho1_uf)
     799          198 :          DEALLOCATE (rho1_uf)
     800          198 :          IF (ASSOCIATED(weights_uf)) THEN
     801          198 :             CALL xc_pw_pool%give_back_pw(weights_uf)
     802          198 :             DEALLOCATE (weights_uf)
     803              :          END IF
     804          198 :          IF (ASSOCIATED(fxc_rho_uf)) THEN
     805          792 :             ALLOCATE (fxc_rho_lo(SIZE(fxc_rho_uf)))
     806          396 :             DO ispin = 1, SIZE(fxc_rho_uf)
     807          198 :                CALL auxbas_pw_pool%create_pw(fxc_rho_lo(ispin))
     808              :                BLOCK
     809              :                   TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
     810          198 :                   CALL auxbas_pw_pool%create_pw(fxc_g)
     811          198 :                   CALL xc_pw_pool%create_pw(fxc_g_uf)
     812          198 :                   CALL pw_transfer(fxc_rho_uf(ispin), fxc_g_uf)
     813          198 :                   CALL pw_transfer(fxc_g_uf, fxc_g)
     814          198 :                   CALL pw_transfer(fxc_g, fxc_rho_lo(ispin))
     815          198 :                   CALL xc_pw_pool%give_back_pw(fxc_g_uf)
     816          396 :                   CALL auxbas_pw_pool%give_back_pw(fxc_g)
     817              :                END BLOCK
     818          396 :                CALL xc_pw_pool%give_back_pw(fxc_rho_uf(ispin))
     819              :             END DO
     820          198 :             DEALLOCATE (fxc_rho_uf)
     821              :          END IF
     822          198 :          IF (ASSOCIATED(fxc_tau_uf)) THEN
     823            0 :             ALLOCATE (fxc_tau_lo(SIZE(fxc_tau_uf)))
     824            0 :             DO ispin = 1, SIZE(fxc_tau_uf)
     825            0 :                CALL auxbas_pw_pool%create_pw(fxc_tau_lo(ispin))
     826              :                BLOCK
     827              :                   TYPE(pw_c1d_gs_type) :: fxc_g, fxc_g_uf
     828            0 :                   CALL auxbas_pw_pool%create_pw(fxc_g)
     829            0 :                   CALL xc_pw_pool%create_pw(fxc_g_uf)
     830            0 :                   CALL pw_transfer(fxc_tau_uf(ispin), fxc_g_uf)
     831            0 :                   CALL pw_transfer(fxc_g_uf, fxc_g)
     832            0 :                   CALL pw_transfer(fxc_g, fxc_tau_lo(ispin))
     833            0 :                   CALL xc_pw_pool%give_back_pw(fxc_g_uf)
     834            0 :                   CALL auxbas_pw_pool%give_back_pw(fxc_g)
     835              :                END BLOCK
     836            0 :                CALL xc_pw_pool%give_back_pw(fxc_tau_uf(ispin))
     837              :             END DO
     838            0 :             DEALLOCATE (fxc_tau_uf)
     839              :          END IF
     840              : 
     841              :       ELSE
     842              :          CALL qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1_struct, xc_section, &
     843              :                           weights, auxbas_pw_pool, fxc_rho_lo, fxc_tau_lo, &
     844              :                           is_triplet=is_triplet, spinflip=spinflip, &
     845        22700 :                           compute_virial=do_virial, virial_xc=virial_xc)
     846              :       END IF
     847              : 
     848              :       ! return potentials
     849        22898 :       IF (ASSOCIATED(fxc_rho)) THEN
     850        21456 :          DO ispin = 1, MIN(SIZE(fxc_rho_lo), SIZE(fxc_rho))
     851        21456 :             CALL pw_transfer(fxc_rho_lo(ispin), fxc_rho(ispin))
     852              :          END DO
     853        21456 :          DO ispin = 1, SIZE(fxc_rho_lo)
     854        21456 :             CALL auxbas_pw_pool%give_back_pw(fxc_rho_lo(ispin))
     855              :          END DO
     856         9786 :          DEALLOCATE (fxc_rho_lo)
     857              :       ELSE
     858        13112 :          fxc_rho => fxc_rho_lo
     859              :       END IF
     860        22898 :       IF (ASSOCIATED(fxc_tau)) THEN
     861            0 :          IF (ASSOCIATED(fxc_tau_lo)) THEN
     862            0 :             DO ispin = 1, MIN(SIZE(fxc_tau_lo), SIZE(fxc_tau))
     863            0 :                CALL pw_transfer(fxc_tau_lo(ispin), fxc_tau(ispin))
     864              :             END DO
     865            0 :             DO ispin = 1, SIZE(fxc_tau_lo)
     866            0 :                CALL auxbas_pw_pool%give_back_pw(fxc_tau_lo(ispin))
     867              :             END DO
     868            0 :             DEALLOCATE (fxc_tau_lo)
     869              :          ELSE
     870            0 :             DO ispin = 1, nspins
     871            0 :                CALL pw_zero(fxc_tau(ispin))
     872              :             END DO
     873              :          END IF
     874              :       ELSE
     875        22898 :          fxc_tau => fxc_tau_lo
     876              :       END IF
     877              : 
     878        22898 :       IF (do_onecenter) THEN
     879              :          CALL fxc_atom_calc(qs_env, rho0_atom_set, rho1_atom_set, xc_section, &
     880              :                             do_scale=do_scale, do_triplet=is_triplet, do_sf=spinflip, &
     881              :                             para_env_ext=para_env_external, &
     882         5816 :                             kind_set_external=kind_set_external)
     883              :       END IF
     884              : 
     885        22898 :       CALL timestop(handle)
     886              : 
     887        22898 :    END SUBROUTINE qs_fxc_apply
     888              : 
     889              : ! **************************************************************************************************
     890              : !> \brief ...
     891              : !> \param xc_deriv_set ...
     892              : !> \param xc_rho_set ...
     893              : !> \param rho1 ...
     894              : !> \param xc_section ...
     895              : !> \param weights ...
     896              : !> \param auxbas_pw_pool ...
     897              : !> \param fxc_rho ...
     898              : !> \param fxc_tau ...
     899              : !> \param is_triplet ...
     900              : !> \param spinflip ...
     901              : !> \param compute_virial ...
     902              : !> \param virial_xc ...
     903              : ! **************************************************************************************************
     904        22898 :    SUBROUTINE qs_fxc_eval(xc_deriv_set, xc_rho_set, rho1, xc_section, weights, auxbas_pw_pool, &
     905              :                           fxc_rho, fxc_tau, is_triplet, spinflip, &
     906              :                           compute_virial, virial_xc)
     907              : 
     908              :       TYPE(xc_derivative_set_type)                       :: xc_deriv_set
     909              :       TYPE(xc_rho_set_type)                              :: xc_rho_set
     910              :       TYPE(qs_rho_type), POINTER                         :: rho1
     911              :       TYPE(section_vals_type), POINTER                   :: xc_section
     912              :       TYPE(pw_r3d_rs_type), POINTER                      :: weights
     913              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
     914              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
     915              :       LOGICAL, INTENT(IN), OPTIONAL                      :: is_triplet, spinflip, compute_virial
     916              :       REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT), &
     917              :          OPTIONAL                                        :: virial_xc
     918              : 
     919              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_eval'
     920              : 
     921              :       INTEGER                                            :: handle, ispin, mspins, nspins
     922              :       INTEGER, DIMENSION(2, 3)                           :: bo
     923              :       LOGICAL                                            :: do_analytic, do_sf, do_triplet, &
     924              :                                                             do_virial, lsd
     925        22898 :       REAL(KIND=dp), DIMENSION(:, :, :, :), POINTER      :: vxg
     926        22898 :       TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER        :: rho1_g
     927        45796 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: rho1_r, tau1_r
     928              :       TYPE(qs_rho_type), POINTER                         :: rhot1
     929              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     930              :       TYPE(xc_rho_cflags_type)                           :: needs
     931              :       TYPE(xc_rho_set_type)                              :: rho1_set
     932              : 
     933        22898 :       CALL timeset(routineN, handle)
     934              : 
     935        22898 :       do_triplet = .FALSE.
     936        22898 :       IF (PRESENT(is_triplet)) do_triplet = is_triplet
     937              : 
     938        22898 :       do_sf = .FALSE.
     939        22898 :       IF (PRESENT(spinflip)) do_sf = spinflip
     940              : 
     941        22898 :       do_virial = .FALSE.
     942        22898 :       IF (PRESENT(compute_virial)) do_virial = compute_virial
     943              : 
     944        22898 :       do_analytic = section_get_lval(xc_section, "2ND_DERIV_ANALYTICAL")
     945              : 
     946        22898 :       CALL qs_rho_get(rho1, rho_r=rho1_r, tau_r=tau1_r)
     947        22898 :       NULLIFY (rho1_g)
     948              : 
     949        22898 :       mspins = SIZE(rho1_r)
     950        22898 :       nspins = SIZE(rho1_r)
     951        22898 :       lsd = (nspins == 2)
     952        22898 :       IF (nspins == 1 .AND. do_triplet) THEN
     953          652 :          nspins = 2
     954          652 :          lsd = .TRUE.
     955        22246 :       ELSE IF (do_sf) THEN
     956          490 :          nspins = 1
     957          490 :          mspins = 1
     958          490 :          lsd = .TRUE.
     959              :       END IF
     960              : 
     961        22898 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
     962        22898 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
     963        22898 :       xc_fun_section => section_vals_get_subs_vals(xc_section, "XC_FUNCTIONAL")
     964        22898 :       needs = xc_functionals_get_needs(xc_fun_section, lsd, .TRUE.)
     965        95316 :       ALLOCATE (fxc_rho(mspins))
     966        49520 :       DO ispin = 1, mspins
     967        26622 :          CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
     968        49520 :          CALL pw_zero(fxc_rho(ispin))
     969              :       END DO
     970        22898 :       IF (needs%tau .OR. needs%tau_spin) THEN
     971          764 :          IF (.NOT. ASSOCIATED(tau1_r)) THEN
     972            0 :             CPABORT("Tau-dependent functionals requires allocated kinetic energy density grid")
     973              :          END IF
     974         2482 :          ALLOCATE (fxc_tau(mspins))
     975         1718 :          DO ispin = 1, mspins
     976          954 :             CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
     977        23852 :             CALL pw_zero(fxc_tau(ispin))
     978              :          END DO
     979              :       END IF
     980              : 
     981        22898 :       IF (mspins == 1 .AND. do_triplet) THEN
     982              :          ! split the density and response density arrays for triplet calculation
     983          652 :          ALLOCATE (rhot1)
     984          652 :          CALL qs_rho_create(rhot1)
     985          652 :          CALL qs_rho_copy(rho1, rhot1, auxbas_pw_pool, 2, factor=2.0_dp)
     986              :          !
     987          652 :          CALL qs_rho_get(rhot1, rho_r=rho1_r, tau_r=tau1_r)
     988              :       END IF
     989              : 
     990       228980 :       bo = rho1_r(1)%pw_grid%bounds_local
     991              :       ! create the place where to store the argument for the functionals
     992              :       CALL xc_rho_set_create(rho1_set, bo, &
     993              :                              rho_cutoff=section_get_rval(xc_section, "DENSITY_CUTOFF"), &
     994              :                              drho_cutoff=section_get_rval(xc_section, "GRADIENT_CUTOFF"), &
     995        22898 :                              tau_cutoff=section_get_rval(xc_section, "TAU_CUTOFF"))
     996              : 
     997              :       ! calculate the arguments needed by the functionals
     998              :       CALL xc_rho_set_update(rho1_set, rho1_r, rho1_g, tau1_r, needs, &
     999              :                              section_get_ival(xc_section, "XC_GRID%XC_DERIV"), &
    1000              :                              section_get_ival(xc_section, "XC_GRID%XC_SMOOTH_RHO"), &
    1001        22898 :                              auxbas_pw_pool, spinflip=do_sf)
    1002              : 
    1003        22898 :       IF (mspins == 1 .AND. do_triplet .AND. do_analytic) THEN
    1004              : 
    1005              :          CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
    1006              :                                            rho1_set, auxbas_pw_pool, xc_section, &
    1007              :                                            gapw=.FALSE., vxg=vxg, tddfpt_fac=-1.0_dp, spinflip=do_sf, &
    1008          632 :                                            compute_virial=compute_virial, virial_xc=virial_xc)
    1009              : 
    1010        22246 :       ELSE IF (do_analytic) THEN
    1011              : 
    1012              :          CALL xc_calc_2nd_deriv_analytical(fxc_rho, fxc_tau, xc_deriv_set, xc_rho_set, &
    1013              :                                            rho1_set, auxbas_pw_pool, xc_section, &
    1014              :                                            gapw=.FALSE., vxg=vxg, spinflip=do_sf, &
    1015        21802 :                                            compute_virial=compute_virial, virial_xc=virial_xc)
    1016              : 
    1017              :       ELSE
    1018              : 
    1019              :          CALL xc_calc_2nd_deriv_numerical(fxc_rho, fxc_tau, xc_rho_set, rho1_r, rho1_g, tau1_r, &
    1020              :                                           auxbas_pw_pool, weights, xc_section, &
    1021          464 :                                           do_triplet, compute_virial, virial_xc, xc_deriv_set)
    1022              : 
    1023              :       END IF
    1024              : 
    1025        22898 :       IF (mspins == 1 .AND. do_triplet) THEN
    1026          652 :          CALL qs_rho_release(rhot1)
    1027          652 :          DEALLOCATE (rhot1)
    1028              :       END IF
    1029        22898 :       CALL xc_rho_set_release(rho1_set)
    1030              : 
    1031        22898 :       CALL timestop(handle)
    1032              : 
    1033       503756 :    END SUBROUTINE qs_fxc_eval
    1034              : 
    1035              : ! **************************************************************************************************
    1036              : !> \brief ...
    1037              : !> \param qs_env ...
    1038              : !> \param rho0_struct ...
    1039              : !> \param rho1_struct ...
    1040              : !> \param xc_section ...
    1041              : !> \param accuracy ...
    1042              : !> \param fxc_rho ...
    1043              : !> \param fxc_tau ...
    1044              : !> \param is_triplet ...
    1045              : !> \param spinflip ...
    1046              : !>
    1047              : !>
    1048              : !>  https://en.wikipedia.org/wiki/Finite_difference_coefficient
    1049              : !>  ---------------------------------------------------------------------------------------------------
    1050              : !>  Derivative    Accuracy            4       3       2       1       0       1       2      3       4
    1051              : !>  ---------------------------------------------------------------------------------------------------
    1052              : !>      1             2                                    -1/2       0     1/2
    1053              : !>                    4                            1/12    -2/3       0     2/3   -1/12
    1054              : !>                    6                   -1/60    3/20    -3/4       0     3/4   -3/20   1/60
    1055              : !>                    8           1/280  -4/105     1/5    -4/5       0     4/5    -1/5  4/105  -1/280
    1056              : !>  ---------------------------------------------------------------------------------------------------
    1057              : !>      2             2                                       1      -2       1
    1058              : !>                    4                           -1/12     4/3    -5/2     4/3   -1/12
    1059              : !>                    6                    1/90   -3/20     3/2  -49/18     3/2   -3/20   1/90
    1060              : !>                    8          -1/560   8/315    -1/5     8/5 -205/72     8/5    -1/5  8/315  -1/560
    1061              : !>  ---------------------------------------------------------------------------------------------------
    1062              : ! **************************************************************************************************
    1063         2296 :    SUBROUTINE qs_fxc_fdiff(qs_env, rho0_struct, rho1_struct, xc_section, accuracy, &
    1064              :                            fxc_rho, fxc_tau, is_triplet, spinflip)
    1065              : 
    1066              :       TYPE(qs_environment_type), POINTER                 :: qs_env
    1067              :       TYPE(qs_rho_type), POINTER                         :: rho0_struct, rho1_struct
    1068              :       TYPE(section_vals_type), POINTER                   :: xc_section
    1069              :       INTEGER, INTENT(IN)                                :: accuracy
    1070              :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: fxc_rho, fxc_tau
    1071              :       LOGICAL, INTENT(IN), OPTIONAL                      :: is_triplet, spinflip
    1072              : 
    1073              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'qs_fxc_fdiff'
    1074              :       REAL(KIND=dp), PARAMETER                           :: epsrho = 5.e-4_dp
    1075              : 
    1076              :       INTEGER                                            :: handle, ispin, istep, nspins, nstep
    1077              :       LOGICAL                                            :: do_sf, do_triplet
    1078              :       REAL(KIND=dp)                                      :: alpha, beta, exc, oeps1
    1079              :       REAL(KIND=dp), DIMENSION(-4:4)                     :: ak
    1080              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1081              :       TYPE(pw_env_type), POINTER                         :: pw_env
    1082              :       TYPE(pw_pool_type), POINTER                        :: auxbas_pw_pool
    1083         2296 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: v_tau_rspace, vxc00
    1084              :       TYPE(qs_ks_env_type), POINTER                      :: ks_env
    1085              :       TYPE(qs_rho_type), POINTER                         :: rhoin
    1086              : 
    1087         2296 :       CALL timeset(routineN, handle)
    1088              : 
    1089         2296 :       CPASSERT(.NOT. ASSOCIATED(fxc_rho))
    1090         2296 :       CPASSERT(.NOT. ASSOCIATED(fxc_tau))
    1091         2296 :       CPASSERT(ASSOCIATED(rho0_struct))
    1092         2296 :       CPASSERT(ASSOCIATED(rho1_struct))
    1093              : 
    1094         2296 :       do_triplet = .FALSE.
    1095         2296 :       IF (PRESENT(is_triplet)) do_triplet = is_triplet
    1096              : 
    1097         2296 :       do_sf = .FALSE.
    1098         2296 :       IF (PRESENT(spinflip)) do_sf = spinflip
    1099            0 :       IF (do_sf) THEN
    1100            0 :          CPABORT("Spin Flip TDDFT only available with analytic 2nd xc derivatives")
    1101              :       END IF
    1102              : 
    1103         2296 :       ak = 0.0_dp
    1104         2296 :       SELECT CASE (accuracy)
    1105              :       CASE (:4)
    1106            0 :          nstep = 2
    1107            0 :          ak(-2:2) = [1.0_dp, -8.0_dp, 0.0_dp, 8.0_dp, -1.0_dp]/12.0_dp
    1108              :       CASE (5:7)
    1109        18368 :          nstep = 3
    1110        18368 :          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
    1111              :       CASE (8:)
    1112            0 :          nstep = 4
    1113              :          ak(-4:4) = [1.0_dp, -32.0_dp/3.0_dp, 56.0_dp, -224.0_dp, 0.0_dp, &
    1114         2296 :                      224.0_dp, -56.0_dp, 32.0_dp/3.0_dp, -1.0_dp]/280.0_dp
    1115              :       END SELECT
    1116              : 
    1117         2296 :       CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, pw_env=pw_env)
    1118         2296 :       CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
    1119              : 
    1120         2296 :       nspins = dft_control%nspins
    1121              :       exc = 0.0_dp
    1122              : 
    1123        18368 :       DO istep = -nstep, nstep
    1124              : 
    1125        18368 :          IF (ak(istep) /= 0.0_dp) THEN
    1126        13776 :             alpha = 1.0_dp
    1127        13776 :             beta = REAL(istep, KIND=dp)*epsrho
    1128              :             NULLIFY (rhoin)
    1129        13776 :             ALLOCATE (rhoin)
    1130        13776 :             CALL qs_rho_create(rhoin)
    1131        13776 :             NULLIFY (vxc00, v_tau_rspace)
    1132        13776 :             IF (do_triplet) THEN
    1133         1176 :                CPASSERT(nspins == 1)
    1134              :                ! rhoin = (0.5 rho0, 0.5 rho0)
    1135         1176 :                CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, 2)
    1136              :                ! rhoin = (0.5 rho0 + 0.5 rho1, 0.5 rho0)
    1137         1176 :                CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, 0.5_dp*beta)
    1138         1176 :                CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
    1139         1176 :                CALL pw_axpy(vxc00(2), vxc00(1), -1.0_dp)
    1140         1176 :                IF (ASSOCIATED(v_tau_rspace)) CALL pw_axpy(v_tau_rspace(2), v_tau_rspace(1), -1.0_dp)
    1141              :             ELSE
    1142        12600 :                CALL qs_rho_copy(rho0_struct, rhoin, auxbas_pw_pool, nspins)
    1143        12600 :                CALL qs_rho_scale_and_add(rhoin, rho1_struct, alpha, beta)
    1144        12600 :                CALL qs_vxc_create(ks_env, rhoin, xc_section, vxc00, v_tau_rspace, exc)
    1145              :             END IF
    1146        13776 :             CALL qs_rho_release(rhoin)
    1147        13776 :             DEALLOCATE (rhoin)
    1148        13776 :             IF (.NOT. ASSOCIATED(fxc_rho)) THEN
    1149         9436 :                ALLOCATE (fxc_rho(nspins))
    1150         4844 :                DO ispin = 1, nspins
    1151         2548 :                   CALL auxbas_pw_pool%create_pw(fxc_rho(ispin))
    1152         4844 :                   CALL pw_zero(fxc_rho(ispin))
    1153              :                END DO
    1154              :             END IF
    1155        29064 :             DO ispin = 1, nspins
    1156        29064 :                CALL pw_axpy(vxc00(ispin), fxc_rho(ispin), ak(istep))
    1157              :             END DO
    1158        30240 :             DO ispin = 1, SIZE(vxc00)
    1159        30240 :                CALL auxbas_pw_pool%give_back_pw(vxc00(ispin))
    1160              :             END DO
    1161        13776 :             DEALLOCATE (vxc00)
    1162        13776 :             IF (ASSOCIATED(v_tau_rspace)) THEN
    1163            0 :                IF (.NOT. ASSOCIATED(fxc_tau)) THEN
    1164            0 :                   ALLOCATE (fxc_tau(nspins))
    1165            0 :                   DO ispin = 1, nspins
    1166            0 :                      CALL auxbas_pw_pool%create_pw(fxc_tau(ispin))
    1167            0 :                      CALL pw_zero(fxc_tau(ispin))
    1168              :                   END DO
    1169              :                END IF
    1170            0 :                DO ispin = 1, nspins
    1171            0 :                   CALL pw_axpy(v_tau_rspace(ispin), fxc_tau(ispin), ak(istep))
    1172              :                END DO
    1173            0 :                DO ispin = 1, SIZE(v_tau_rspace)
    1174            0 :                   CALL auxbas_pw_pool%give_back_pw(v_tau_rspace(ispin))
    1175              :                END DO
    1176            0 :                DEALLOCATE (v_tau_rspace)
    1177              :             END IF
    1178              :          END IF
    1179              : 
    1180              :       END DO
    1181              : 
    1182         2296 :       oeps1 = 1.0_dp/epsrho
    1183         4844 :       DO ispin = 1, nspins
    1184         4844 :          CALL pw_scale(fxc_rho(ispin), oeps1)
    1185              :       END DO
    1186         2296 :       IF (ASSOCIATED(fxc_tau)) THEN
    1187            0 :          DO ispin = 1, nspins
    1188            0 :             CALL pw_scale(fxc_tau(ispin), oeps1)
    1189              :          END DO
    1190              :       END IF
    1191              : 
    1192         2296 :       CALL timestop(handle)
    1193              : 
    1194         2296 :    END SUBROUTINE qs_fxc_fdiff
    1195              : 
    1196              : END MODULE qs_fxc
        

Generated by: LCOV version 2.0-1