LCOV - code coverage report
Current view: top level - src/xc - xc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:70636b1) Lines: 84.9 % 397 337
Test Date: 2026-02-11 07:00:35 Functions: 100.0 % 5 5

            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              : 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        65908 :    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(:, :), INTENT(IN)              :: 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        65908 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: deriv_data
      96              :       REAL(KIND=dp)                                      :: drho_cutoff
      97              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
      98              : 
      99        65908 :       CALL timeset(routineN, handle)
     100        65908 :       my_only_energy = .FALSE.
     101        65908 :       IF (PRESENT(energy_only)) my_only_energy = energy_only
     102              : 
     103        65908 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     104        65908 :          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        65908 :                     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        65908 :                                deriv_order=deriv_order)
     118              : 
     119        65908 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     120              : 
     121        65908 :       NULLIFY (deriv_data)
     122              : 
     123              :       !  EXC energy
     124        65908 :       deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
     125        65908 :       exc = 0.0_dp
     126        65908 :       IF (ASSOCIATED(deriv_att)) THEN
     127        65836 :          CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     128      3698716 :          DO ir = 1, nr
     129    185511196 :             DO ia = 1, na
     130    185445360 :                exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
     131              :             END DO
     132              :          END DO
     133        65836 :          NULLIFY (deriv_data)
     134              :       END IF
     135              :       ! Calculate the potential only if needed
     136        65908 :       IF (.NOT. my_only_energy) THEN
     137              :          !  Derivative with respect to the density
     138        62884 :          IF (lsd) THEN
     139         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
     140         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     141         8288 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     142     54816496 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     143         8288 :                NULLIFY (deriv_data)
     144              :             END IF
     145         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
     146         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     147         8288 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     148     54816496 :                vxc(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     149         8288 :                NULLIFY (deriv_data)
     150              :             END IF
     151         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     152         8292 :             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        54592 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     160        54592 :             IF (ASSOCIATED(deriv_att)) THEN
     161        54524 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     162    299390248 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     163        54524 :                NULLIFY (deriv_data)
     164              :             END IF
     165              :          END IF ! lsd
     166              : 
     167              :          !  Derivatives with respect to the gradient
     168        62884 :          IF (lsd) THEN
     169         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
     170         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     171         4854 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     172       262834 :                DO ir = 1, nr
     173     13150314 :                   DO ia = 1, na
     174     51807900 :                      DO idir = 1, 3
     175     51549920 :                         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     33153096 :                                                   rho_set%norm_drhoa(ia, ir, 1)*my_adiabatic_rescale_factor
     179              :                         ELSE
     180      5509344 :                            vxg(idir, ia, ir, 1) = 0.0_dp
     181              :                         END IF
     182              :                      END DO
     183              :                   END DO
     184              :                END DO
     185         4854 :                NULLIFY (deriv_data)
     186              :             END IF
     187         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
     188         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     189         4854 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     190       262834 :                DO ir = 1, nr
     191     13150314 :                   DO ia = 1, na
     192     51807900 :                      DO idir = 1, 3
     193     51549920 :                         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     32497800 :                                                   rho_set%norm_drhob(ia, ir, 1)*my_adiabatic_rescale_factor
     197              :                         ELSE
     198      6164640 :                            vxg(idir, ia, ir, 2) = 0.0_dp
     199              :                         END IF
     200              :                      END DO
     201              :                   END DO
     202              :                END DO
     203         4854 :                NULLIFY (deriv_data)
     204              :             END IF
     205              :             ! Cross Terms
     206         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     207         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     208         4806 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     209       260386 :                DO ir = 1, nr
     210     13027866 :                   DO ia = 1, na
     211     51325500 :                      DO idir = 1, 3
     212     51069920 :                         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     98627004 :                               my_adiabatic_rescale_factor
     219              :                         END IF
     220              :                      END DO
     221              :                   END DO
     222              :                END DO
     223         4806 :                NULLIFY (deriv_data)
     224              :             END IF
     225              :          ELSE
     226        54592 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     227        54592 :             IF (ASSOCIATED(deriv_att)) THEN
     228        33554 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     229      1730854 :                DO ir = 1, nr
     230     86775854 :                   DO ia = 1, na
     231     86742300 :                      IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
     232    293366904 :                         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    293366904 :                                                   rho_set%norm_drho(ia, ir, 1)*my_adiabatic_rescale_factor
     236              :                         END DO
     237              :                      ELSE
     238     46813096 :                         vxg(1:3, ia, ir, 1) = 0.0_dp
     239              :                      END IF
     240              :                   END DO
     241              :                END DO
     242        33554 :                NULLIFY (deriv_data)
     243              :             END IF
     244              :          END IF ! lsd
     245              :          !  Derivative with respect to tau
     246        62884 :          IF (lsd) THEN
     247         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a])
     248         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     249           16 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     250        81632 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     251           16 :                NULLIFY (deriv_data)
     252              :             END IF
     253         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b])
     254         8292 :             IF (ASSOCIATED(deriv_att)) THEN
     255           16 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     256        81632 :                vtau(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     257           16 :                NULLIFY (deriv_data)
     258              :             END IF
     259         8292 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     260         8292 :             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        54592 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     268        54592 :             IF (ASSOCIATED(deriv_att)) THEN
     269          936 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     270      5415072 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     271          936 :                NULLIFY (deriv_data)
     272              :             END IF
     273              :          END IF ! lsd
     274              :       END IF ! only_energy
     275              : 
     276        65908 :       CALL timestop(handle)
     277              : 
     278        65908 :    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           30 :    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(:, :), INTENT(IN)              :: 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        19068 :    SUBROUTINE xc_2nd_deriv_of_r(rho_set, rho1_set, xc_section, &
     401        19068 :                                 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(:, :), INTENT(IN)              :: 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        19068 :       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        19068 :       CALL timeset(routineN, handle)
     430              : 
     431        19068 :       nspins = SIZE(vxc, 3)
     432        19068 :       lsd = (nspins == 2)
     433        19068 :       IF (ASSOCIATED(rho_set%rhoa)) THEN
     434         1402 :          lsd = .TRUE.
     435              :       END IF
     436        19068 :       my_fac_triplet = 1.0_dp
     437        19068 :       IF (PRESENT(do_triplet)) THEN
     438        18720 :          IF (do_triplet) my_fac_triplet = -1.0_dp
     439              :       END IF
     440              : 
     441        19068 :       my_do_sf = .FALSE.
     442        19068 :       IF (PRESENT(do_sf)) my_do_sf = do_sf
     443              : 
     444        19068 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     445              :       xc_fun_section => section_vals_get_subs_vals(xc_section, &
     446        19068 :                                                    "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        19068 :                                deriv_order=2)
     454              : 
     455        19068 :       CALL divide_by_norm_drho(deriv_set, rho_set, lsd)
     456              : 
     457              :       ! multiply by w
     458        19068 :       pos => deriv_set%derivs
     459       125768 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     460    272210768 :          deriv_att%deriv_data(:, :, 1) = w(:, :)*deriv_att%deriv_data(:, :, 1)
     461              :       END DO
     462              : 
     463        19068 :       NULLIFY (pw_pool)
     464        76660 :       ALLOCATE (vxc_pw(nspins))
     465        38524 :       DO ispin = 1, nspins
     466        38524 :          vxc_pw(ispin)%array => vxc(:, :, ispin:ispin)
     467              :       END DO
     468              : 
     469        19068 :       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              :                                         xc_section, gapw=.TRUE., vxg=vxg, &
     473        19068 :                                         tddfpt_fac=my_fac_triplet, spinflip=do_sf)
     474              : 
     475        19068 :       DEALLOCATE (vxc_pw)
     476              : 
     477              :       ! zero the derivative data for the next call
     478        19068 :       pos => deriv_set%derivs
     479       125768 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     480    272317468 :          deriv_att%deriv_data = 0.0_dp
     481              :       END DO
     482              : 
     483        19068 :       CALL timestop(handle)
     484              : 
     485        38136 :    END SUBROUTINE xc_2nd_deriv_of_r
     486              : 
     487              : ! **************************************************************************************************
     488              : !> \brief ...
     489              : !> \param rho_set ...
     490              : !> \param needs ...
     491              : !> \param nspins ...
     492              : !> \param bo ...
     493              : ! **************************************************************************************************
     494       156044 :    SUBROUTINE xc_rho_set_atom_update(rho_set, needs, nspins, bo)
     495              : 
     496              : !   This routine allocates the storage arrays for rho and drho
     497              : !   In calculate_vxc_atom this is called once for each atomic_kind,
     498              : !   After the loop over all the atoms of the kind and over all the points
     499              : !   of the radial grid for each atom, rho_set is deallocated.
     500              : !   Within the same kind, at each new point on the radial grid, the rho_set
     501              : !   arrays rho and drho are overwritten.
     502              : 
     503              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     504              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     505              :       INTEGER, INTENT(IN)                                :: nspins
     506              :       INTEGER, DIMENSION(2, 3), INTENT(IN)               :: bo
     507              : 
     508              :       INTEGER                                            :: idir
     509              : 
     510       295543 :       SELECT CASE (nspins)
     511              :       CASE (1)
     512              : !     What is this for?
     513       139499 :          IF (needs%rho_1_3) THEN
     514         4055 :             NULLIFY (rho_set%rho_1_3)
     515        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)))
     516         4055 :             rho_set%owns%rho_1_3 = .TRUE.
     517         4055 :             rho_set%has%rho_1_3 = .FALSE.
     518              :          END IF
     519              : !     Allocate the storage space for the density
     520       139499 :          IF (needs%rho) THEN
     521       139499 :             NULLIFY (rho_set%rho)
     522       697495 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     523       139499 :             rho_set%owns%rho = .TRUE.
     524       139499 :             rho_set%has%rho = .FALSE.
     525              :          END IF
     526              : !     Allocate the storage space for  the norm of the gradient of the density
     527       139499 :          IF (needs%norm_drho) THEN
     528        99557 :             NULLIFY (rho_set%norm_drho)
     529       497785 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     530        99557 :             rho_set%owns%norm_drho = .TRUE.
     531        99557 :             rho_set%has%norm_drho = .FALSE.
     532              :          END IF
     533              : !     Allocate the storage space for the three components of the gradient of the density
     534       139499 :          IF (needs%drho) THEN
     535       312960 :             DO idir = 1, 3
     536       234720 :                NULLIFY (rho_set%drho(idir)%array)
     537      1251840 :                ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     538              :             END DO
     539        78240 :             rho_set%owns%drho = .TRUE.
     540        78240 :             rho_set%has%drho = .FALSE.
     541              :          END IF
     542              :       CASE (2)
     543              : !     Allocate the storage space for the total density
     544        16545 :          IF (needs%rho) THEN
     545              :             ! this should never be the case unless you use LDA functionals with LSD
     546            0 :             NULLIFY (rho_set%rho)
     547            0 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     548            0 :             rho_set%owns%rho = .TRUE.
     549            0 :             rho_set%has%rho = .FALSE.
     550              :          END IF
     551              : !     What is this for?
     552        16545 :          IF (needs%rho_1_3) THEN
     553            0 :             NULLIFY (rho_set%rho_1_3)
     554            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)))
     555            0 :             rho_set%owns%rho_1_3 = .TRUE.
     556            0 :             rho_set%has%rho_1_3 = .FALSE.
     557              :          END IF
     558              : !     What is this for?
     559        16545 :          IF (needs%rho_spin_1_3) THEN
     560         2440 :             NULLIFY (rho_set%rhoa_1_3, rho_set%rhob_1_3)
     561        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)))
     562        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)))
     563         2440 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     564         2440 :             rho_set%has%rho_spin_1_3 = .FALSE.
     565              :          END IF
     566              : !     Allocate the storage space for the spin densities rhoa and rhob
     567        16545 :          IF (needs%rho_spin) THEN
     568        16545 :             NULLIFY (rho_set%rhoa, rho_set%rhob)
     569        82725 :             ALLOCATE (rho_set%rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     570        82725 :             ALLOCATE (rho_set%rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     571        16545 :             rho_set%owns%rho_spin = .TRUE.
     572        16545 :             rho_set%has%rho_spin = .FALSE.
     573              :          END IF
     574              : !     Allocate the storage space for the norm of the gradient of the total density
     575        16545 :          IF (needs%norm_drho) THEN
     576        10547 :             NULLIFY (rho_set%norm_drho)
     577        52735 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     578        10547 :             rho_set%owns%norm_drho = .TRUE.
     579        10547 :             rho_set%has%norm_drho = .FALSE.
     580              :          END IF
     581              : !     Allocate the storage space for the norm of the gradient of rhoa and of rhob separatedly
     582        16545 :          IF (needs%norm_drho_spin) THEN
     583        10595 :             NULLIFY (rho_set%norm_drhoa, rho_set%norm_drhob)
     584        52975 :             ALLOCATE (rho_set%norm_drhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     585        52975 :             ALLOCATE (rho_set%norm_drhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     586        10595 :             rho_set%owns%norm_drho_spin = .TRUE.
     587        10595 :             rho_set%has%norm_drho_spin = .FALSE.
     588              :          END IF
     589              : !     Allocate the storage space for the components of the gradient for the total rho
     590        16545 :          IF (needs%drho) THEN
     591            0 :             DO idir = 1, 3
     592            0 :                NULLIFY (rho_set%drho(idir)%array)
     593            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)))
     594              :             END DO
     595            0 :             rho_set%owns%drho = .TRUE.
     596            0 :             rho_set%has%drho = .FALSE.
     597              :          END IF
     598              : !     Allocate the storage space for the components of the gradient for rhoa and rhob
     599       172589 :          IF (needs%drho_spin) THEN
     600        38864 :             DO idir = 1, 3
     601        29148 :                NULLIFY (rho_set%drhoa(idir)%array, rho_set%drhob(idir)%array)
     602       145740 :                ALLOCATE (rho_set%drhoa(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     603       155456 :                ALLOCATE (rho_set%drhob(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     604              :             END DO
     605         9716 :             rho_set%owns%drho_spin = .TRUE.
     606         9716 :             rho_set%has%drho_spin = .FALSE.
     607              :          END IF
     608              : !
     609              :       END SELECT
     610              : 
     611              :       ! tau part
     612       156044 :       IF (needs%tau) THEN
     613         1508 :          NULLIFY (rho_set%tau)
     614         7540 :          ALLOCATE (rho_set%tau(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     615         1508 :          rho_set%owns%tau = .TRUE.
     616              :       END IF
     617       156044 :       IF (needs%tau_spin) THEN
     618           34 :          NULLIFY (rho_set%tau_a, rho_set%tau_b)
     619          170 :          ALLOCATE (rho_set%tau_a(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     620          170 :          ALLOCATE (rho_set%tau_b(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     621           34 :          rho_set%owns%tau_spin = .TRUE.
     622           34 :          rho_set%has%tau_spin = .FALSE.
     623              :       END IF
     624              : 
     625              :       ! Laplace part
     626       156044 :       IF (needs%laplace_rho) THEN
     627            0 :          NULLIFY (rho_set%laplace_rho)
     628            0 :          ALLOCATE (rho_set%laplace_rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     629            0 :          rho_set%owns%laplace_rho = .TRUE.
     630              :       END IF
     631       156044 :       IF (needs%laplace_rho_spin) THEN
     632            0 :          NULLIFY (rho_set%laplace_rhoa)
     633            0 :          NULLIFY (rho_set%laplace_rhob)
     634            0 :          ALLOCATE (rho_set%laplace_rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     635            0 :          ALLOCATE (rho_set%laplace_rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     636            0 :          rho_set%owns%laplace_rho_spin = .TRUE.
     637            0 :          rho_set%has%laplace_rho_spin = .TRUE.
     638              :       END IF
     639              : 
     640       156044 :    END SUBROUTINE xc_rho_set_atom_update
     641              : 
     642              : ! **************************************************************************************************
     643              : !> \brief ...
     644              : !> \param rho_set ...
     645              : !> \param lsd ...
     646              : !> \param nspins ...
     647              : !> \param needs ...
     648              : !> \param rho ...
     649              : !> \param drho ...
     650              : !> \param tau ...
     651              : !> \param na ...
     652              : !> \param ir ...
     653              : ! **************************************************************************************************
     654      5440980 :    SUBROUTINE fill_rho_set(rho_set, lsd, nspins, needs, rho, drho, tau, na, ir)
     655              : 
     656              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     657              :       LOGICAL, INTENT(IN)                                :: lsd
     658              :       INTEGER, INTENT(IN)                                :: nspins
     659              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     660              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: rho
     661              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(IN)        :: drho
     662              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: tau
     663              :       INTEGER, INTENT(IN)                                :: na, ir
     664              : 
     665              :       REAL(KIND=dp), PARAMETER                           :: f13 = (1.0_dp/3.0_dp)
     666              : 
     667              :       INTEGER                                            :: ia, idir, my_nspins
     668              :       LOGICAL                                            :: gradient_f, tddft_split
     669              : 
     670      5440980 :       my_nspins = nspins
     671      5440980 :       tddft_split = .FALSE.
     672      5440980 :       IF (lsd .AND. nspins == 1) THEN
     673        90600 :          my_nspins = 2
     674        90600 :          tddft_split = .TRUE.
     675              :       END IF
     676              : 
     677              :       ! some checks
     678      5440980 :       IF (lsd) THEN
     679              :       ELSE
     680      4706500 :          CPASSERT(SIZE(rho, 3) == 1)
     681              :       END IF
     682      4706500 :       SELECT CASE (my_nspins)
     683              :       CASE (1)
     684      4706500 :          CPASSERT(.NOT. needs%rho_spin)
     685      4706500 :          CPASSERT(.NOT. needs%drho_spin)
     686      4706500 :          CPASSERT(.NOT. needs%norm_drho_spin)
     687      4706500 :          CPASSERT(.NOT. needs%rho_spin_1_3)
     688              :       CASE (2)
     689              :       CASE default
     690      5440980 :          CPABORT("Unsupported number of spins")
     691              :       END SELECT
     692              : 
     693              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     694      5440980 :                     needs%drho .OR. needs%norm_drho)
     695              : 
     696      4706500 :       SELECT CASE (my_nspins)
     697              :       CASE (1)
     698              :          ! Give rho to 1/3
     699      4706500 :          IF (needs%rho_1_3) THEN
     700      6765600 :             DO ia = 1, na
     701      6765600 :                rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     702              :             END DO
     703       132800 :             rho_set%owns%rho_1_3 = .TRUE.
     704       132800 :             rho_set%has%rho_1_3 = .TRUE.
     705              :          END IF
     706              :          ! Give the density
     707      4706500 :          IF (needs%rho) THEN
     708    240211500 :             DO ia = 1, na
     709    240211500 :                rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     710              :             END DO
     711      4706500 :             rho_set%owns%rho = .TRUE.
     712      4706500 :             rho_set%has%rho = .TRUE.
     713              :          END IF
     714              :          ! Give the norm of the gradient of the density
     715      4706500 :          IF (needs%norm_drho) THEN
     716    151211400 :             DO ia = 1, na
     717    151211400 :                rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     718              :             END DO
     719      2961400 :             rho_set%owns%norm_drho = .TRUE.
     720      2961400 :             rho_set%has%norm_drho = .TRUE.
     721              :          END IF
     722              :          ! Give the three components of the gradient of the density
     723      4706500 :          IF (needs%drho) THEN
     724     11845600 :             DO idir = 1, 3
     725    456595600 :                DO ia = 1, na
     726    453634200 :                   rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     727              :                END DO
     728              :             END DO
     729      2961400 :             rho_set%owns%drho = .TRUE.
     730      2961400 :             rho_set%has%drho = .TRUE.
     731              :          END IF
     732              :       CASE (2)
     733              :          ! Give the total density
     734       734480 :          IF (needs%rho) THEN
     735              :             ! this should never be the case unless you use LDA functionals with LSD
     736            0 :             IF (.NOT. tddft_split) THEN
     737            0 :                DO ia = 1, na
     738            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1) + rho(ia, ir, 2)
     739              :                END DO
     740              :             ELSE
     741            0 :                DO ia = 1, na
     742            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     743              :                END DO
     744              :             END IF
     745            0 :             rho_set%owns%rho = .TRUE.
     746            0 :             rho_set%has%rho = .TRUE.
     747              :          END IF
     748              :          ! Give the total density to 1/3
     749       734480 :          IF (needs%rho_1_3) THEN
     750            0 :             IF (.NOT. tddft_split) THEN
     751            0 :                DO ia = 1, na
     752            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1) + rho(ia, ir, 2), 0.0_dp)**f13
     753              :                END DO
     754              :             ELSE
     755            0 :                DO ia = 1, na
     756            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     757              :                END DO
     758              :             END IF
     759            0 :             rho_set%owns%rho_1_3 = .TRUE.
     760            0 :             rho_set%has%rho_1_3 = .TRUE.
     761              :          END IF
     762              :          ! Give the spin densities to 1/3
     763       734480 :          IF (needs%rho_spin_1_3) THEN
     764        75480 :             IF (.NOT. tddft_split) THEN
     765      3837960 :                DO ia = 1, na
     766      3762480 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     767      3837960 :                   rho_set%rhob_1_3(ia, ir, 1) = MAX(rho(ia, ir, 2), 0.0_dp)**f13
     768              :                END DO
     769              :             ELSE
     770            0 :                DO ia = 1, na
     771            0 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(0.5_dp*rho(ia, ir, 1), 0.0_dp)**f13
     772            0 :                   rho_set%rhob_1_3(ia, ir, 1) = rho_set%rhoa_1_3(ia, ir, 1)
     773              :                END DO
     774              :             END IF
     775        75480 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     776        75480 :             rho_set%has%rho_spin_1_3 = .TRUE.
     777              :          END IF
     778              :          ! Give the spin densities rhoa and rhob
     779       734480 :          IF (needs%rho_spin) THEN
     780       734480 :             IF (.NOT. tddft_split) THEN
     781     32826360 :                DO ia = 1, na
     782     32182480 :                   rho_set%rhoa(ia, ir, 1) = rho(ia, ir, 1)
     783     32826360 :                   rho_set%rhob(ia, ir, 1) = rho(ia, ir, 2)
     784              :                END DO
     785              :             ELSE
     786      4620600 :                DO ia = 1, na
     787      4530000 :                   rho_set%rhoa(ia, ir, 1) = 0.5_dp*rho(ia, ir, 1)
     788      4620600 :                   rho_set%rhob(ia, ir, 1) = rho_set%rhoa(ia, ir, 1)
     789              :                END DO
     790              :             END IF
     791       734480 :             rho_set%owns%rho_spin = .TRUE.
     792       734480 :             rho_set%has%rho_spin = .TRUE.
     793              :          END IF
     794              :          ! Give the norm of the gradient of the total density
     795       734480 :          IF (needs%norm_drho) THEN
     796       404480 :             IF (.NOT. tddft_split) THEN
     797     17220360 :                DO ia = 1, na
     798              :                   rho_set%norm_drho(ia, ir, 1) = SQRT( &
     799              :                                                  (drho(1, ia, ir, 1) + drho(1, ia, ir, 2))**2 + &
     800              :                                                  (drho(2, ia, ir, 1) + drho(2, ia, ir, 2))**2 + &
     801     17220360 :                                                  (drho(3, ia, ir, 1) + drho(3, ia, ir, 2))**2)
     802              :                END DO
     803              :             ELSE
     804      3396600 :                DO ia = 1, na
     805      3396600 :                   rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     806              :                END DO
     807              :             END IF
     808       404480 :             rho_set%owns%norm_drho = .TRUE.
     809       404480 :             rho_set%has%norm_drho = .TRUE.
     810              :          END IF
     811              :          ! Give the norm of the gradient of rhoa and of rhob separatedly
     812       734480 :          IF (needs%norm_drho_spin) THEN
     813       406880 :             IF (.NOT. tddft_split) THEN
     814     17342760 :                DO ia = 1, na
     815     17002480 :                   rho_set%norm_drhoa(ia, ir, 1) = drho(4, ia, ir, 1)
     816     17342760 :                   rho_set%norm_drhob(ia, ir, 1) = drho(4, ia, ir, 2)
     817              :                END DO
     818              :             ELSE
     819      3396600 :                DO ia = 1, na
     820      3330000 :                   rho_set%norm_drhoa(ia, ir, 1) = 0.5_dp*drho(4, ia, ir, 1)
     821      3396600 :                   rho_set%norm_drhob(ia, ir, 1) = rho_set%norm_drhoa(ia, ir, 1)
     822              :                END DO
     823              :             END IF
     824       406880 :             rho_set%owns%norm_drho_spin = .TRUE.
     825       406880 :             rho_set%has%norm_drho_spin = .TRUE.
     826              :          END IF
     827              :          ! Give the components of the gradient for the total rho
     828       734480 :          IF (needs%drho) THEN
     829            0 :             IF (.NOT. tddft_split) THEN
     830            0 :                DO idir = 1, 3
     831            0 :                   DO ia = 1, na
     832            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1) + drho(idir, ia, ir, 2)
     833              :                   END DO
     834              :                END DO
     835              :             ELSE
     836            0 :                DO idir = 1, 3
     837            0 :                   DO ia = 1, na
     838            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     839              :                   END DO
     840              :                END DO
     841              :             END IF
     842            0 :             rho_set%owns%drho = .TRUE.
     843            0 :             rho_set%has%drho = .TRUE.
     844              :          END IF
     845              :          ! Give the components of the gradient for rhoa and rhob
     846      6175460 :          IF (needs%drho_spin) THEN
     847       408380 :             IF (.NOT. tddft_split) THEN
     848      1367120 :                DO idir = 1, 3
     849     52599560 :                   DO ia = 1, na
     850     51232440 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     851     52257780 :                      rho_set%drhob(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 2)
     852              :                   END DO
     853              :                END DO
     854              :             ELSE
     855       266400 :                DO idir = 1, 3
     856     10256400 :                   DO ia = 1, na
     857      9990000 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = 0.5_dp*drho(idir, ia, ir, 1)
     858     10189800 :                      rho_set%drhob(idir)%array(ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)
     859              :                   END DO
     860              :                END DO
     861              :             END IF
     862       408380 :             rho_set%owns%drho_spin = .TRUE.
     863       408380 :             rho_set%has%drho_spin = .TRUE.
     864              :          END IF
     865              :          !
     866              :       END SELECT
     867              : 
     868              :       ! tau part
     869      5440980 :       IF (needs%tau .OR. needs%tau_spin) THEN
     870      5440980 :          CPASSERT(SIZE(tau, 3) == my_nspins)
     871              :       END IF
     872      5440980 :       IF (needs%tau) THEN
     873        49400 :          IF (my_nspins == 2) THEN
     874            0 :             DO ia = 1, na
     875            0 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1) + tau(ia, ir, 2)
     876              :             END DO
     877            0 :             rho_set%owns%tau = .TRUE.
     878            0 :             rho_set%has%tau = .TRUE.
     879              :          ELSE
     880      2706600 :             DO ia = 1, na
     881      2706600 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1)
     882              :             END DO
     883        49400 :             rho_set%owns%tau = .TRUE.
     884        49400 :             rho_set%has%tau = .TRUE.
     885              :          END IF
     886              :       END IF
     887      5440980 :       IF (needs%tau_spin) THEN
     888        40800 :          DO ia = 1, na
     889        40000 :             rho_set%tau_a(ia, ir, 1) = tau(ia, ir, 1)
     890        40800 :             rho_set%tau_b(ia, ir, 1) = tau(ia, ir, 2)
     891              :          END DO
     892          800 :          rho_set%owns%tau_spin = .TRUE.
     893          800 :          rho_set%has%tau_spin = .TRUE.
     894              :       END IF
     895              : 
     896      5440980 :    END SUBROUTINE fill_rho_set
     897              : 
     898              : END MODULE xc_atom
        

Generated by: LCOV version 2.0-1