LCOV - code coverage report
Current view: top level - src/xc - xc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 82.1 % 396 325
Test Date: 2025-12-04 06:27:48 Functions: 100.0 % 5 5

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : MODULE xc_atom
      10              : 
      11              :    USE cp_linked_list_xc_deriv,         ONLY: cp_sll_xc_deriv_next,&
      12              :                                               cp_sll_xc_deriv_type
      13              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      14              :                                               section_vals_type
      15              :    USE kinds,                           ONLY: dp
      16              :    USE pw_pool_types,                   ONLY: pw_pool_type
      17              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      18              :    USE xc,                              ONLY: divide_by_norm_drho,&
      19              :                                               xc_calc_2nd_deriv_analytical
      20              :    USE xc_derivative_desc,              ONLY: &
      21              :         deriv_norm_drho, deriv_norm_drhoa, deriv_norm_drhob, deriv_rho, deriv_rhoa, deriv_rhob, &
      22              :         deriv_tau, deriv_tau_a, deriv_tau_b
      23              :    USE xc_derivative_set_types,         ONLY: xc_derivative_set_type,&
      24              :                                               xc_dset_get_derivative
      25              :    USE xc_derivative_types,             ONLY: xc_derivative_get,&
      26              :                                               xc_derivative_type
      27              :    USE xc_derivatives,                  ONLY: xc_functionals_eval
      28              :    USE xc_rho_cflags_types,             ONLY: xc_rho_cflags_type
      29              :    USE xc_rho_set_types,                ONLY: xc_rho_set_get,&
      30              :                                               xc_rho_set_type
      31              : #include "../base/base_uses.f90"
      32              : 
      33              :    IMPLICIT NONE
      34              : 
      35              :    PRIVATE
      36              : 
      37              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_atom'
      38              : 
      39              :    PUBLIC :: vxc_of_r_new, vxc_of_r_epr, xc_rho_set_atom_update, xc_2nd_deriv_of_r, fill_rho_set
      40              : 
      41              : CONTAINS
      42              : 
      43              : ! **************************************************************************************************
      44              : !> \brief ...
      45              : !> \param xc_fun_section ...
      46              : !> \param rho_set ...
      47              : !> \param deriv_set ...
      48              : !> \param deriv_order ...
      49              : !> \param needs ...
      50              : !> \param w ...
      51              : !> \param lsd ...
      52              : !> \param na ...
      53              : !> \param nr ...
      54              : !> \param exc ...
      55              : !> \param vxc ...
      56              : !> \param vxg ...
      57              : !> \param vtau ...
      58              : !> \param energy_only ...
      59              : !> \param adiabatic_rescale_factor ...
      60              : ! **************************************************************************************************
      61       104360 :    SUBROUTINE vxc_of_r_new(xc_fun_section, rho_set, deriv_set, deriv_order, needs, w, &
      62              :                            lsd, na, nr, exc, vxc, vxg, vtau, &
      63              :                            energy_only, adiabatic_rescale_factor)
      64              : 
      65              : ! This routine updates rho_set by giving to it the rho and drho that are needed.
      66              : ! Since for the local densities rho1_h and rho1_s local grids are used it is not possible
      67              : ! to call xc_rho_set_update.
      68              : ! As input of this routine one gets rho and drho on a one dimensional grid.
      69              : ! The grid is the angular grid corresponding to a given point ir_pnt on the radial grid.
      70              : ! The derivatives are calculated on this one dimensional grid, the results are stored in
      71              : ! exc, vxc(1:na,ir_pnt,ispin), vxg(1:na,ir_pnt,ispin), vxg_cross(1:na,ir_pnt,ispin)
      72              : ! Afterwords the arrays containing the derivatives are put to zero so that the routine
      73              : ! can safely be called for the next radial point ir_pnt
      74              : 
      75              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
      76              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
      77              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
      78              :       INTEGER, INTENT(in)                                :: deriv_order
      79              :       TYPE(xc_rho_cflags_type), INTENT(in)               :: needs
      80              :       REAL(dp), DIMENSION(:, :), POINTER                 :: w
      81              :       LOGICAL, INTENT(IN)                                :: lsd
      82              :       INTEGER, INTENT(in)                                :: na, nr
      83              :       REAL(dp)                                           :: exc
      84              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc
      85              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg
      86              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vtau
      87              :       LOGICAL, INTENT(IN), OPTIONAL                      :: energy_only
      88              :       REAL(dp), INTENT(IN), OPTIONAL                     :: adiabatic_rescale_factor
      89              : 
      90              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'vxc_of_r_new'
      91              : 
      92              :       INTEGER                                            :: handle, ia, idir, ir
      93              :       LOGICAL                                            :: gradient_f, my_only_energy
      94              :       REAL(dp)                                           :: my_adiabatic_rescale_factor
      95        52180 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: deriv_data
      96              :       REAL(KIND=dp)                                      :: drho_cutoff
      97              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
      98              : 
      99        52180 :       CALL timeset(routineN, handle)
     100        52180 :       my_only_energy = .FALSE.
     101        52180 :       IF (PRESENT(energy_only)) my_only_energy = energy_only
     102              : 
     103        52180 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     104        52180 :          my_adiabatic_rescale_factor = adiabatic_rescale_factor
     105              :       ELSE
     106              :          my_adiabatic_rescale_factor = 1.0_dp
     107              :       END IF
     108              : 
     109              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     110        52180 :                     needs%drho .OR. needs%norm_drho)
     111              : 
     112              :       !  Calculate the derivatives
     113              :       CALL xc_functionals_eval(xc_fun_section, &
     114              :                                lsd=lsd, &
     115              :                                rho_set=rho_set, &
     116              :                                deriv_set=deriv_set, &
     117        52180 :                                deriv_order=deriv_order)
     118              : 
     119        52180 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     120              : 
     121        52180 :       NULLIFY (deriv_data)
     122              : 
     123              :       !  EXC energy
     124        52180 :       deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
     125        52180 :       exc = 0.0_dp
     126        52180 :       IF (ASSOCIATED(deriv_att)) THEN
     127        52108 :          CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     128      2998588 :          DO ir = 1, nr
     129    150491068 :             DO ia = 1, na
     130    150438960 :                exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
     131              :             END DO
     132              :          END DO
     133        52108 :          NULLIFY (deriv_data)
     134              :       END IF
     135              :       ! Calculate the potential only if needed
     136        52180 :       IF (.NOT. my_only_energy) THEN
     137              :          !  Derivative with respect to the density
     138        49156 :          IF (lsd) THEN
     139         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
     140         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     141         8136 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     142     54040992 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     143         8136 :                NULLIFY (deriv_data)
     144              :             END IF
     145         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
     146         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     147         8136 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     148     54040992 :                vxc(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     149         8136 :                NULLIFY (deriv_data)
     150              :             END IF
     151         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     152         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     153            0 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     154            0 :                vxc(:, :, 1) = vxc(:, :, 1) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     155            0 :                vxc(:, :, 2) = vxc(:, :, 2) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     156            0 :                NULLIFY (deriv_data)
     157              :             END IF
     158              :          ELSE
     159        41016 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     160        41016 :             IF (ASSOCIATED(deriv_att)) THEN
     161        40948 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     162    230125496 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     163        40948 :                NULLIFY (deriv_data)
     164              :             END IF
     165              :          END IF ! lsd
     166              : 
     167              :          !  Derivatives with respect to the gradient
     168        49156 :          IF (lsd) THEN
     169         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
     170         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     171         4838 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     172       262018 :                DO ir = 1, nr
     173     13109498 :                   DO ia = 1, na
     174     51647100 :                      DO idir = 1, 3
     175     51389920 :                         IF (rho_set%norm_drhoa(ia, ir, 1) > drho_cutoff) THEN
     176              :                            vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
     177              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     178     33048696 :                                                   rho_set%norm_drhoa(ia, ir, 1)*my_adiabatic_rescale_factor
     179              :                         ELSE
     180      5493744 :                            vxg(idir, ia, ir, 1) = 0.0_dp
     181              :                         END IF
     182              :                      END DO
     183              :                   END DO
     184              :                END DO
     185         4838 :                NULLIFY (deriv_data)
     186              :             END IF
     187         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
     188         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     189         4838 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     190       262018 :                DO ir = 1, nr
     191     13109498 :                   DO ia = 1, na
     192     51647100 :                      DO idir = 1, 3
     193     51389920 :                         IF (rho_set%norm_drhob(ia, ir, 1) > drho_cutoff) THEN
     194              :                            vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
     195              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     196     32393400 :                                                   rho_set%norm_drhob(ia, ir, 1)*my_adiabatic_rescale_factor
     197              :                         ELSE
     198      6149040 :                            vxg(idir, ia, ir, 2) = 0.0_dp
     199              :                         END IF
     200              :                      END DO
     201              :                   END DO
     202              :                END DO
     203         4838 :                NULLIFY (deriv_data)
     204              :             END IF
     205              :             ! Cross Terms
     206         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     207         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     208         4790 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     209       259570 :                DO ir = 1, nr
     210     12987050 :                   DO ia = 1, na
     211     51164700 :                      DO idir = 1, 3
     212     50909920 :                         IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
     213              :                            vxg(idir, ia, ir, 1:2) = &
     214              :                               vxg(idir, ia, ir, 1:2) + ( &
     215              :                               rho_set%drhoa(idir)%array(ia, ir, 1) + &
     216              :                               rho_set%drhob(idir)%array(ia, ir, 1))* &
     217              :                               deriv_data(ia, ir, 1)*w(ia, ir)/rho_set%norm_drho(ia, ir, 1)* &
     218     98313444 :                               my_adiabatic_rescale_factor
     219              :                         END IF
     220              :                      END DO
     221              :                   END DO
     222              :                END DO
     223         4790 :                NULLIFY (deriv_data)
     224              :             END IF
     225              :          ELSE
     226        41016 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     227        41016 :             IF (ASSOCIATED(deriv_att)) THEN
     228        23372 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     229      1211572 :                DO ir = 1, nr
     230     60801572 :                   DO ia = 1, na
     231     60778200 :                      IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
     232    205929656 :                         DO idir = 1, 3
     233              :                            vxg(idir, ia, ir, 1) = rho_set%drho(idir)%array(ia, ir, 1)* &
     234              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     235    205929656 :                                                   rho_set%norm_drho(ia, ir, 1)*my_adiabatic_rescale_factor
     236              :                         END DO
     237              :                      ELSE
     238     32430344 :                         vxg(1:3, ia, ir, 1) = 0.0_dp
     239              :                      END IF
     240              :                   END DO
     241              :                END DO
     242        23372 :                NULLIFY (deriv_data)
     243              :             END IF
     244              :          END IF ! lsd
     245              :          !  Derivative with respect to tau
     246        49156 :          IF (lsd) THEN
     247         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a])
     248         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     249            0 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     250            0 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     251            0 :                NULLIFY (deriv_data)
     252              :             END IF
     253         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b])
     254         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     255            0 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     256            0 :                vtau(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     257            0 :                NULLIFY (deriv_data)
     258              :             END IF
     259         8140 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     260         8140 :             IF (ASSOCIATED(deriv_att)) THEN
     261            0 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     262            0 :                vtau(:, :, 1) = vtau(:, :, 1) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     263            0 :                vtau(:, :, 2) = vtau(:, :, 2) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     264            0 :                NULLIFY (deriv_data)
     265              :             END IF
     266              :          ELSE
     267        41016 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     268        41016 :             IF (ASSOCIATED(deriv_att)) THEN
     269          712 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     270      4272224 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     271          712 :                NULLIFY (deriv_data)
     272              :             END IF
     273              :          END IF ! lsd
     274              :       END IF ! only_energy
     275              : 
     276        52180 :       CALL timestop(handle)
     277              : 
     278        52180 :    END SUBROUTINE vxc_of_r_new
     279              : 
     280              : ! **************************************************************************************************
     281              : !> \brief Specific EPR version of vxc_of_r_new
     282              : !> \param xc_fun_section ...
     283              : !> \param rho_set ...
     284              : !> \param deriv_set ...
     285              : !> \param needs ...
     286              : !> \param w ...
     287              : !> \param lsd ...
     288              : !> \param na ...
     289              : !> \param nr ...
     290              : !> \param exc ...
     291              : !> \param vxc ...
     292              : !> \param vxg ...
     293              : !> \param vtau ...
     294              : ! **************************************************************************************************
     295           60 :    SUBROUTINE vxc_of_r_epr(xc_fun_section, rho_set, deriv_set, needs, w, &
     296              :                            lsd, na, nr, exc, vxc, vxg, vtau)
     297              : 
     298              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     299              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     300              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     301              :       TYPE(xc_rho_cflags_type), INTENT(in)               :: needs
     302              :       REAL(dp), DIMENSION(:, :), POINTER                 :: w
     303              :       LOGICAL, INTENT(IN)                                :: lsd
     304              :       INTEGER, INTENT(in)                                :: na, nr
     305              :       REAL(dp)                                           :: exc
     306              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc
     307              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg
     308              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vtau
     309              : 
     310              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'vxc_of_r_epr'
     311              : 
     312              :       INTEGER                                            :: handle, ia, idir, ir, my_deriv_order
     313              :       LOGICAL                                            :: gradient_f
     314              :       REAL(dp)                                           :: my_adiabatic_rescale_factor
     315           30 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: deriv_data
     316              :       REAL(KIND=dp)                                      :: drho_cutoff
     317              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     318              : 
     319           30 :       CALL timeset(routineN, handle)
     320              : 
     321              :       MARK_USED(vxc)
     322              :       MARK_USED(vtau)
     323              : 
     324           30 :       my_adiabatic_rescale_factor = 1.0_dp
     325           30 :       my_deriv_order = 2
     326              : 
     327              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     328           30 :                     needs%drho .OR. needs%norm_drho)
     329              : 
     330              :       !  Calculate the derivatives
     331              :       CALL xc_functionals_eval(xc_fun_section, &
     332              :                                lsd=lsd, &
     333              :                                rho_set=rho_set, &
     334              :                                deriv_set=deriv_set, &
     335           30 :                                deriv_order=my_deriv_order)
     336              : 
     337           30 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     338              : 
     339           30 :       NULLIFY (deriv_data)
     340              : 
     341              :       ! nabla v_xc (using the vxg arrays)
     342              :       ! there's no point doing this when lsd = false
     343           30 :       IF (lsd) THEN
     344           30 :          deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
     345           30 :          IF (ASSOCIATED(deriv_att)) THEN
     346           30 :             CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     347         1530 :             DO ir = 1, nr
     348        76530 :                DO ia = 1, na
     349       301500 :                   DO idir = 1, 3
     350              :                      vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
     351       300000 :                                             deriv_data(ia, ir, 1)
     352              :                   END DO !idir
     353              :                END DO !ia
     354              :             END DO !ir
     355           30 :             NULLIFY (deriv_data)
     356              :          END IF
     357           30 :          deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
     358           30 :          IF (ASSOCIATED(deriv_att)) THEN
     359           30 :             CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     360         1530 :             DO ir = 1, nr
     361        76530 :                DO ia = 1, na
     362       301500 :                   DO idir = 1, 3
     363              :                      vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
     364       300000 :                                             deriv_data(ia, ir, 1)
     365              :                   END DO !idir
     366              :                END DO !ia
     367              :             END DO !ir
     368           30 :             NULLIFY (deriv_data)
     369              :          END IF
     370              :       END IF
     371              :       !  EXC energy ! is that needed for epr?
     372           30 :       deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
     373           30 :       exc = 0.0_dp
     374           30 :       IF (ASSOCIATED(deriv_att)) THEN
     375           30 :          CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     376         1530 :          DO ir = 1, nr
     377        76530 :             DO ia = 1, na
     378        76500 :                exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
     379              :             END DO
     380              :          END DO
     381           30 :          NULLIFY (deriv_data)
     382              :       END IF
     383              : 
     384           30 :       CALL timestop(handle)
     385              : 
     386           30 :    END SUBROUTINE vxc_of_r_epr
     387              : 
     388              : ! **************************************************************************************************
     389              : !> \brief ...
     390              : !> \param rho_set ...
     391              : !> \param rho1_set ...
     392              : !> \param xc_section ...
     393              : !> \param deriv_set ...
     394              : !> \param w ...
     395              : !> \param vxc ...
     396              : !> \param vxg ...
     397              : !> \param do_triplet ...
     398              : !> \param do_sf ...
     399              : ! **************************************************************************************************
     400        11166 :    SUBROUTINE xc_2nd_deriv_of_r(rho_set, rho1_set, xc_section, &
     401              :                                 deriv_set, w, vxc, vxg, do_triplet, do_sf)
     402              : 
     403              : ! As input of this routine one gets rho and drho on a one dimensional grid.
     404              : ! The grid is the angular grid corresponding to a given point ir on the radial grid.
     405              : ! The derivatives are calculated on this one dimensional grid, the results are stored in
     406              : ! vxc(1:na,ir,ispin), vxg(1:na,ir,ispin), vxg_cross(1:na,ir,ispin)
     407              : ! Afterwords the arrays containing the derivatives are put to zero so that the routine
     408              : ! can safely be called for the next radial point ir
     409              : 
     410              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set, rho1_set
     411              :       TYPE(section_vals_type), POINTER                   :: xc_section
     412              :       TYPE(xc_derivative_set_type), INTENT(INOUT)        :: deriv_set
     413              :       REAL(dp), DIMENSION(:, :), POINTER                 :: w
     414              :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER  :: vxc
     415              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg
     416              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_triplet, do_sf
     417              : 
     418              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'xc_2nd_deriv_of_r'
     419              : 
     420              :       INTEGER                                            :: handle, ispin, nspins
     421              :       LOGICAL                                            :: lsd, my_do_sf
     422              :       REAL(dp)                                           :: drho_cutoff, my_fac_triplet
     423              :       TYPE(cp_sll_xc_deriv_type), POINTER                :: pos
     424              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     425        11166 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: vxc_pw, vxc_tau_pw
     426              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     427              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     428              : 
     429        11166 :       CALL timeset(routineN, handle)
     430              : 
     431        11166 :       nspins = SIZE(vxc, 3)
     432        11166 :       lsd = (nspins == 2)
     433        11166 :       IF (ASSOCIATED(rho_set%rhoa)) THEN
     434          902 :          lsd = .TRUE.
     435              :       END IF
     436        11166 :       my_fac_triplet = 1.0_dp
     437        11166 :       IF (PRESENT(do_triplet)) THEN
     438        10930 :          IF (do_triplet) my_fac_triplet = -1.0_dp
     439              :       END IF
     440              : 
     441        11166 :       my_do_sf = .FALSE.
     442        11166 :       IF (PRESENT(do_sf)) my_do_sf = do_sf
     443              : 
     444        11166 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     445              :       xc_fun_section => section_vals_get_subs_vals(xc_section, &
     446        11166 :                                                    "XC_FUNCTIONAL")
     447              : 
     448              :       !  Calculate the derivatives
     449              :       CALL xc_functionals_eval(xc_fun_section, &
     450              :                                lsd=lsd, &
     451              :                                rho_set=rho_set, &
     452              :                                deriv_set=deriv_set, &
     453        11166 :                                deriv_order=2)
     454              : 
     455        11166 :       CALL divide_by_norm_drho(deriv_set, rho_set, lsd)
     456              : 
     457              :       ! multiply by w
     458        11166 :       pos => deriv_set%derivs
     459        75548 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     460    328488130 :          deriv_att%deriv_data(:, :, 1) = w(:, :)*deriv_att%deriv_data(:, :, 1)
     461              :       END DO
     462              : 
     463        11166 :       NULLIFY (pw_pool)
     464        45032 :       ALLOCATE (vxc_pw(nspins))
     465        22700 :       DO ispin = 1, nspins
     466        22700 :          vxc_pw(ispin)%array => vxc(:, :, ispin:ispin)
     467              :       END DO
     468              : 
     469        11166 :       NULLIFY (vxc_tau_pw)
     470              : 
     471              :       CALL xc_calc_2nd_deriv_analytical(vxc_pw, vxc_tau_pw, deriv_set, rho_set, rho1_set, pw_pool, &
     472        11166 :                                         xc_section, gapw=.TRUE., vxg=vxg, tddfpt_fac=my_fac_triplet, spinflip=do_sf)
     473              : 
     474        11166 :       DEALLOCATE (vxc_pw)
     475              : 
     476              :       ! zero the derivative data for the next call
     477        11166 :       pos => deriv_set%derivs
     478        75548 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     479    164314030 :          deriv_att%deriv_data = 0.0_dp
     480              :       END DO
     481              : 
     482        11166 :       CALL timestop(handle)
     483              : 
     484        22332 :    END SUBROUTINE xc_2nd_deriv_of_r
     485              : 
     486              : ! **************************************************************************************************
     487              : !> \brief ...
     488              : !> \param rho_set ...
     489              : !> \param needs ...
     490              : !> \param nspins ...
     491              : !> \param bo ...
     492              : ! **************************************************************************************************
     493       116550 :    SUBROUTINE xc_rho_set_atom_update(rho_set, needs, nspins, bo)
     494              : 
     495              : !   This routine allocates the storage arrays for rho and drho
     496              : !   In calculate_vxc_atom this is called once for each atomic_kind,
     497              : !   After the loop over all the atoms of the kind and over all the points
     498              : !   of the radial grid for each atom, rho_set is deallocated.
     499              : !   Within the same kind, at each new point on the radial grid, the rho_set
     500              : !   arrays rho and drho are overwritten.
     501              : 
     502              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     503              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     504              :       INTEGER, INTENT(IN)                                :: nspins
     505              :       INTEGER, DIMENSION(2, 3), INTENT(IN)               :: bo
     506              : 
     507              :       INTEGER                                            :: idir
     508              : 
     509       217963 :       SELECT CASE (nspins)
     510              :       CASE (1)
     511              : !     What is this for?
     512       101413 :          IF (needs%rho_1_3) THEN
     513         4055 :             NULLIFY (rho_set%rho_1_3)
     514        20275 :             ALLOCATE (rho_set%rho_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     515         4055 :             rho_set%owns%rho_1_3 = .TRUE.
     516         4055 :             rho_set%has%rho_1_3 = .FALSE.
     517              :          END IF
     518              : !     Allocate the storage space for the density
     519       101413 :          IF (needs%rho) THEN
     520       101413 :             NULLIFY (rho_set%rho)
     521       507065 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     522       101413 :             rho_set%owns%rho = .TRUE.
     523       101413 :             rho_set%has%rho = .FALSE.
     524              :          END IF
     525              : !     Allocate the storage space for  the norm of the gradient of the density
     526       101413 :          IF (needs%norm_drho) THEN
     527        72439 :             NULLIFY (rho_set%norm_drho)
     528       362195 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     529        72439 :             rho_set%owns%norm_drho = .TRUE.
     530        72439 :             rho_set%has%norm_drho = .FALSE.
     531              :          END IF
     532              : !     Allocate the storage space for the three components of the gradient of the density
     533       101413 :          IF (needs%drho) THEN
     534       204592 :             DO idir = 1, 3
     535       153444 :                NULLIFY (rho_set%drho(idir)%array)
     536       818368 :                ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     537              :             END DO
     538        51148 :             rho_set%owns%drho = .TRUE.
     539        51148 :             rho_set%has%drho = .FALSE.
     540              :          END IF
     541              :       CASE (2)
     542              : !     Allocate the storage space for the total density
     543        15137 :          IF (needs%rho) THEN
     544              :             ! this should never be the case unless you use LDA functionals with LSD
     545            0 :             NULLIFY (rho_set%rho)
     546            0 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     547            0 :             rho_set%owns%rho = .TRUE.
     548            0 :             rho_set%has%rho = .FALSE.
     549              :          END IF
     550              : !     What is this for?
     551        15137 :          IF (needs%rho_1_3) THEN
     552            0 :             NULLIFY (rho_set%rho_1_3)
     553            0 :             ALLOCATE (rho_set%rho_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     554            0 :             rho_set%owns%rho_1_3 = .TRUE.
     555            0 :             rho_set%has%rho_1_3 = .FALSE.
     556              :          END IF
     557              : !     What is this for?
     558        15137 :          IF (needs%rho_spin_1_3) THEN
     559         2440 :             NULLIFY (rho_set%rhoa_1_3, rho_set%rhob_1_3)
     560        12200 :             ALLOCATE (rho_set%rhoa_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     561        12200 :             ALLOCATE (rho_set%rhob_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     562         2440 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     563         2440 :             rho_set%has%rho_spin_1_3 = .FALSE.
     564              :          END IF
     565              : !     Allocate the storage space for the spin densities rhoa and rhob
     566        15137 :          IF (needs%rho_spin) THEN
     567        15137 :             NULLIFY (rho_set%rhoa, rho_set%rhob)
     568        75685 :             ALLOCATE (rho_set%rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     569        75685 :             ALLOCATE (rho_set%rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     570        15137 :             rho_set%owns%rho_spin = .TRUE.
     571        15137 :             rho_set%has%rho_spin = .FALSE.
     572              :          END IF
     573              : !     Allocate the storage space for the norm of the gradient of the total density
     574        15137 :          IF (needs%norm_drho) THEN
     575         9763 :             NULLIFY (rho_set%norm_drho)
     576        48815 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     577         9763 :             rho_set%owns%norm_drho = .TRUE.
     578         9763 :             rho_set%has%norm_drho = .FALSE.
     579              :          END IF
     580              : !     Allocate the storage space for the norm of the gradient of rhoa and of rhob separatedly
     581        15137 :          IF (needs%norm_drho_spin) THEN
     582         9811 :             NULLIFY (rho_set%norm_drhoa, rho_set%norm_drhob)
     583        49055 :             ALLOCATE (rho_set%norm_drhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     584        49055 :             ALLOCATE (rho_set%norm_drhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     585         9811 :             rho_set%owns%norm_drho_spin = .TRUE.
     586         9811 :             rho_set%has%norm_drho_spin = .FALSE.
     587              :          END IF
     588              : !     Allocate the storage space for the components of the gradient for the total rho
     589        15137 :          IF (needs%drho) THEN
     590            0 :             DO idir = 1, 3
     591            0 :                NULLIFY (rho_set%drho(idir)%array)
     592            0 :                ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     593              :             END DO
     594            0 :             rho_set%owns%drho = .TRUE.
     595            0 :             rho_set%has%drho = .FALSE.
     596              :          END IF
     597              : !     Allocate the storage space for the components of the gradient for rhoa and rhob
     598       131687 :          IF (needs%drho_spin) THEN
     599        35728 :             DO idir = 1, 3
     600        26796 :                NULLIFY (rho_set%drhoa(idir)%array, rho_set%drhob(idir)%array)
     601       133980 :                ALLOCATE (rho_set%drhoa(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     602       142912 :                ALLOCATE (rho_set%drhob(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     603              :             END DO
     604         8932 :             rho_set%owns%drho_spin = .TRUE.
     605         8932 :             rho_set%has%drho_spin = .FALSE.
     606              :          END IF
     607              : !
     608              :       END SELECT
     609              : 
     610              :       ! tau part
     611       116550 :       IF (needs%tau) THEN
     612         1092 :          NULLIFY (rho_set%tau)
     613         5460 :          ALLOCATE (rho_set%tau(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     614         1092 :          rho_set%owns%tau = .TRUE.
     615              :       END IF
     616       116550 :       IF (needs%tau_spin) THEN
     617            2 :          NULLIFY (rho_set%tau_a, rho_set%tau_b)
     618           10 :          ALLOCATE (rho_set%tau_a(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     619           10 :          ALLOCATE (rho_set%tau_b(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     620            2 :          rho_set%owns%tau_spin = .TRUE.
     621            2 :          rho_set%has%tau_spin = .FALSE.
     622              :       END IF
     623              : 
     624              :       ! Laplace part
     625       116550 :       IF (needs%laplace_rho) THEN
     626            0 :          NULLIFY (rho_set%laplace_rho)
     627            0 :          ALLOCATE (rho_set%laplace_rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     628            0 :          rho_set%owns%laplace_rho = .TRUE.
     629              :       END IF
     630       116550 :       IF (needs%laplace_rho_spin) THEN
     631            0 :          NULLIFY (rho_set%laplace_rhoa)
     632            0 :          NULLIFY (rho_set%laplace_rhob)
     633            0 :          ALLOCATE (rho_set%laplace_rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     634            0 :          ALLOCATE (rho_set%laplace_rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     635            0 :          rho_set%owns%laplace_rho_spin = .TRUE.
     636            0 :          rho_set%has%laplace_rho_spin = .TRUE.
     637              :       END IF
     638              : 
     639       116550 :    END SUBROUTINE xc_rho_set_atom_update
     640              : 
     641              : ! **************************************************************************************************
     642              : !> \brief ...
     643              : !> \param rho_set ...
     644              : !> \param lsd ...
     645              : !> \param nspins ...
     646              : !> \param needs ...
     647              : !> \param rho ...
     648              : !> \param drho ...
     649              : !> \param tau ...
     650              : !> \param na ...
     651              : !> \param ir ...
     652              : ! **************************************************************************************************
     653      4017180 :    SUBROUTINE fill_rho_set(rho_set, lsd, nspins, needs, rho, drho, tau, na, ir)
     654              : 
     655              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     656              :       LOGICAL, INTENT(IN)                                :: lsd
     657              :       INTEGER, INTENT(IN)                                :: nspins
     658              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     659              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: rho
     660              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(IN)        :: drho
     661              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: tau
     662              :       INTEGER, INTENT(IN)                                :: na, ir
     663              : 
     664              :       REAL(KIND=dp), PARAMETER                           :: f13 = (1.0_dp/3.0_dp)
     665              : 
     666              :       INTEGER                                            :: ia, idir, my_nspins
     667              :       LOGICAL                                            :: gradient_f, tddft_split
     668              : 
     669      4017180 :       my_nspins = nspins
     670      4017180 :       tddft_split = .FALSE.
     671      4017180 :       IF (lsd .AND. nspins == 1) THEN
     672        48000 :          my_nspins = 2
     673        48000 :          tddft_split = .TRUE.
     674              :       END IF
     675              : 
     676              :       ! some checks
     677      4017180 :       IF (lsd) THEN
     678              :       ELSE
     679      3334900 :          CPASSERT(SIZE(rho, 3) == 1)
     680              :       END IF
     681      3334900 :       SELECT CASE (my_nspins)
     682              :       CASE (1)
     683      3334900 :          CPASSERT(.NOT. needs%rho_spin)
     684      3334900 :          CPASSERT(.NOT. needs%drho_spin)
     685      3334900 :          CPASSERT(.NOT. needs%norm_drho_spin)
     686      3334900 :          CPASSERT(.NOT. needs%rho_spin_1_3)
     687              :       CASE (2)
     688              :       CASE default
     689      4017180 :          CPABORT("Unsupported number of spins")
     690              :       END SELECT
     691              : 
     692              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     693      4017180 :                     needs%drho .OR. needs%norm_drho)
     694              : 
     695      3334900 :       SELECT CASE (my_nspins)
     696              :       CASE (1)
     697              :          ! Give rho to 1/3
     698      3334900 :          IF (needs%rho_1_3) THEN
     699      6765600 :             DO ia = 1, na
     700      6765600 :                rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     701              :             END DO
     702       132800 :             rho_set%owns%rho_1_3 = .TRUE.
     703       132800 :             rho_set%has%rho_1_3 = .TRUE.
     704              :          END IF
     705              :          ! Give the density
     706      3334900 :          IF (needs%rho) THEN
     707    170259900 :             DO ia = 1, na
     708    170259900 :                rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     709              :             END DO
     710      3334900 :             rho_set%owns%rho = .TRUE.
     711      3334900 :             rho_set%has%rho = .TRUE.
     712              :          END IF
     713              :          ! Give the norm of the gradient of the density
     714      3334900 :          IF (needs%norm_drho) THEN
     715    101511900 :             DO ia = 1, na
     716    101511900 :                rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     717              :             END DO
     718      1986900 :             rho_set%owns%norm_drho = .TRUE.
     719      1986900 :             rho_set%has%norm_drho = .TRUE.
     720              :          END IF
     721              :          ! Give the three components of the gradient of the density
     722      3334900 :          IF (needs%drho) THEN
     723      7947600 :             DO idir = 1, 3
     724    306522600 :                DO ia = 1, na
     725    304535700 :                   rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     726              :                END DO
     727              :             END DO
     728      1986900 :             rho_set%owns%drho = .TRUE.
     729      1986900 :             rho_set%has%drho = .TRUE.
     730              :          END IF
     731              :       CASE (2)
     732              :          ! Give the total density
     733       682280 :          IF (needs%rho) THEN
     734              :             ! this should never be the case unless you use LDA functionals with LSD
     735            0 :             IF (.NOT. tddft_split) THEN
     736            0 :                DO ia = 1, na
     737            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1) + rho(ia, ir, 2)
     738              :                END DO
     739              :             ELSE
     740            0 :                DO ia = 1, na
     741            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     742              :                END DO
     743              :             END IF
     744            0 :             rho_set%owns%rho = .TRUE.
     745            0 :             rho_set%has%rho = .TRUE.
     746              :          END IF
     747              :          ! Give the total density to 1/3
     748       682280 :          IF (needs%rho_1_3) THEN
     749            0 :             IF (.NOT. tddft_split) THEN
     750            0 :                DO ia = 1, na
     751            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1) + rho(ia, ir, 2), 0.0_dp)**f13
     752              :                END DO
     753              :             ELSE
     754            0 :                DO ia = 1, na
     755            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     756              :                END DO
     757              :             END IF
     758            0 :             rho_set%owns%rho_1_3 = .TRUE.
     759            0 :             rho_set%has%rho_1_3 = .TRUE.
     760              :          END IF
     761              :          ! Give the spin densities to 1/3
     762       682280 :          IF (needs%rho_spin_1_3) THEN
     763        75480 :             IF (.NOT. tddft_split) THEN
     764      3837960 :                DO ia = 1, na
     765      3762480 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     766      3837960 :                   rho_set%rhob_1_3(ia, ir, 1) = MAX(rho(ia, ir, 2), 0.0_dp)**f13
     767              :                END DO
     768              :             ELSE
     769            0 :                DO ia = 1, na
     770            0 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(0.5_dp*rho(ia, ir, 1), 0.0_dp)**f13
     771            0 :                   rho_set%rhob_1_3(ia, ir, 1) = rho_set%rhoa_1_3(ia, ir, 1)
     772              :                END DO
     773              :             END IF
     774        75480 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     775        75480 :             rho_set%has%rho_spin_1_3 = .TRUE.
     776              :          END IF
     777              :          ! Give the spin densities rhoa and rhob
     778       682280 :          IF (needs%rho_spin) THEN
     779       682280 :             IF (.NOT. tddft_split) THEN
     780     32336760 :                DO ia = 1, na
     781     31702480 :                   rho_set%rhoa(ia, ir, 1) = rho(ia, ir, 1)
     782     32336760 :                   rho_set%rhob(ia, ir, 1) = rho(ia, ir, 2)
     783              :                END DO
     784              :             ELSE
     785      2448000 :                DO ia = 1, na
     786      2400000 :                   rho_set%rhoa(ia, ir, 1) = 0.5_dp*rho(ia, ir, 1)
     787      2448000 :                   rho_set%rhob(ia, ir, 1) = rho_set%rhoa(ia, ir, 1)
     788              :                END DO
     789              :             END IF
     790       682280 :             rho_set%owns%rho_spin = .TRUE.
     791       682280 :             rho_set%has%rho_spin = .TRUE.
     792              :          END IF
     793              :          ! Give the norm of the gradient of the total density
     794       682280 :          IF (needs%norm_drho) THEN
     795       373080 :             IF (.NOT. tddft_split) THEN
     796     17179560 :                DO ia = 1, na
     797              :                   rho_set%norm_drho(ia, ir, 1) = SQRT( &
     798              :                                                  (drho(1, ia, ir, 1) + drho(1, ia, ir, 2))**2 + &
     799              :                                                  (drho(2, ia, ir, 1) + drho(2, ia, ir, 2))**2 + &
     800     17179560 :                                                  (drho(3, ia, ir, 1) + drho(3, ia, ir, 2))**2)
     801              :                END DO
     802              :             ELSE
     803      1836000 :                DO ia = 1, na
     804      1836000 :                   rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     805              :                END DO
     806              :             END IF
     807       373080 :             rho_set%owns%norm_drho = .TRUE.
     808       373080 :             rho_set%has%norm_drho = .TRUE.
     809              :          END IF
     810              :          ! Give the norm of the gradient of rhoa and of rhob separatedly
     811       682280 :          IF (needs%norm_drho_spin) THEN
     812       375480 :             IF (.NOT. tddft_split) THEN
     813     17301960 :                DO ia = 1, na
     814     16962480 :                   rho_set%norm_drhoa(ia, ir, 1) = drho(4, ia, ir, 1)
     815     17301960 :                   rho_set%norm_drhob(ia, ir, 1) = drho(4, ia, ir, 2)
     816              :                END DO
     817              :             ELSE
     818      1836000 :                DO ia = 1, na
     819      1800000 :                   rho_set%norm_drhoa(ia, ir, 1) = 0.5_dp*drho(4, ia, ir, 1)
     820      1836000 :                   rho_set%norm_drhob(ia, ir, 1) = rho_set%norm_drhoa(ia, ir, 1)
     821              :                END DO
     822              :             END IF
     823       375480 :             rho_set%owns%norm_drho_spin = .TRUE.
     824       375480 :             rho_set%has%norm_drho_spin = .TRUE.
     825              :          END IF
     826              :          ! Give the components of the gradient for the total rho
     827       682280 :          IF (needs%drho) THEN
     828            0 :             IF (.NOT. tddft_split) THEN
     829            0 :                DO idir = 1, 3
     830            0 :                   DO ia = 1, na
     831            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1) + drho(idir, ia, ir, 2)
     832              :                   END DO
     833              :                END DO
     834              :             ELSE
     835            0 :                DO idir = 1, 3
     836            0 :                   DO ia = 1, na
     837            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     838              :                   END DO
     839              :                END DO
     840              :             END IF
     841            0 :             rho_set%owns%drho = .TRUE.
     842            0 :             rho_set%has%drho = .TRUE.
     843              :          END IF
     844              :          ! Give the components of the gradient for rhoa and rhob
     845      4699460 :          IF (needs%drho_spin) THEN
     846       376980 :             IF (.NOT. tddft_split) THEN
     847      1363920 :                DO idir = 1, 3
     848     52476360 :                   DO ia = 1, na
     849     51112440 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     850     52135380 :                      rho_set%drhob(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 2)
     851              :                   END DO
     852              :                END DO
     853              :             ELSE
     854       144000 :                DO idir = 1, 3
     855      5544000 :                   DO ia = 1, na
     856      5400000 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = 0.5_dp*drho(idir, ia, ir, 1)
     857      5508000 :                      rho_set%drhob(idir)%array(ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)
     858              :                   END DO
     859              :                END DO
     860              :             END IF
     861       376980 :             rho_set%owns%drho_spin = .TRUE.
     862       376980 :             rho_set%has%drho_spin = .TRUE.
     863              :          END IF
     864              :          !
     865              :       END SELECT
     866              : 
     867              :       ! tau part
     868      4017180 :       IF (needs%tau .OR. needs%tau_spin) THEN
     869      4017180 :          CPASSERT(SIZE(tau, 3) == my_nspins)
     870              :       END IF
     871      4017180 :       IF (needs%tau) THEN
     872        38200 :          IF (my_nspins == 2) THEN
     873            0 :             DO ia = 1, na
     874            0 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1) + tau(ia, ir, 2)
     875              :             END DO
     876            0 :             rho_set%owns%tau = .TRUE.
     877            0 :             rho_set%has%tau = .TRUE.
     878              :          ELSE
     879      2135400 :             DO ia = 1, na
     880      2135400 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1)
     881              :             END DO
     882        38200 :             rho_set%owns%tau = .TRUE.
     883        38200 :             rho_set%has%tau = .TRUE.
     884              :          END IF
     885              :       END IF
     886      4017180 :       IF (needs%tau_spin) THEN
     887            0 :          DO ia = 1, na
     888            0 :             rho_set%tau_a(ia, ir, 1) = tau(ia, ir, 1)
     889            0 :             rho_set%tau_b(ia, ir, 1) = tau(ia, ir, 2)
     890              :          END DO
     891            0 :          rho_set%owns%tau_spin = .TRUE.
     892            0 :          rho_set%has%tau_spin = .TRUE.
     893              :       END IF
     894              : 
     895      4017180 :    END SUBROUTINE fill_rho_set
     896              : 
     897              : END MODULE xc_atom
        

Generated by: LCOV version 2.0-1