LCOV - code coverage report
Current view: top level - src/xc - xc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:24d69ee) Lines: 83.6 % 384 321
Test Date: 2026-09-03 07:32:15 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        77274 :    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        77274 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: deriv_data
      96              :       REAL(KIND=dp)                                      :: drho_cutoff
      97              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
      98              : 
      99        77274 :       CALL timeset(routineN, handle)
     100        77274 :       my_only_energy = .FALSE.
     101        77274 :       IF (PRESENT(energy_only)) my_only_energy = energy_only
     102              : 
     103        77274 :       IF (PRESENT(adiabatic_rescale_factor)) THEN
     104        77274 :          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        77274 :                     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        77274 :                                deriv_order=deriv_order)
     118              : 
     119        77274 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     120              : 
     121        77274 :       NULLIFY (deriv_data)
     122              : 
     123              :       !  EXC energy
     124        77274 :       deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
     125        77274 :       exc = 0.0_dp
     126        77274 :       IF (ASSOCIATED(deriv_att)) THEN
     127        77202 :          CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     128      4278382 :          DO ir = 1, nr
     129    214505862 :             DO ia = 1, na
     130    214428660 :                exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
     131              :             END DO
     132              :          END DO
     133        77202 :          NULLIFY (deriv_data)
     134              :       END IF
     135              :       ! Calculate the potential only if needed
     136        77274 :       IF (.NOT. my_only_energy) THEN
     137              :          !  Derivative with respect to the density
     138        74020 :          IF (lsd) THEN
     139         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa])
     140         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     141         9848 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     142     62775616 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     143         9848 :                NULLIFY (deriv_data)
     144              :             END IF
     145         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob])
     146         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     147         9848 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     148     62775616 :                vxc(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     149         9848 :                NULLIFY (deriv_data)
     150              :             END IF
     151         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     152         9852 :             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        64168 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rho])
     160        64168 :             IF (ASSOCIATED(deriv_att)) THEN
     161        64100 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     162    348247000 :                vxc(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     163        64100 :                NULLIFY (deriv_data)
     164              :             END IF
     165              :          END IF ! lsd
     166              : 
     167              :          !  Derivatives with respect to the gradient
     168        74020 :          IF (lsd) THEN
     169         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhoa])
     170         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     171         6344 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     172              : !$OMP PARALLEL DO DEFAULT(NONE) COLLAPSE(2) SCHEDULE(STATIC) &
     173              : !$OMP             PRIVATE(ia, idir, ir) &
     174         6344 : !$OMP             SHARED(deriv_data, drho_cutoff, my_adiabatic_rescale_factor, na, nr, rho_set, vxg, w)
     175              :                DO ir = 1, nr
     176              :                   DO ia = 1, na
     177              :                      DO idir = 1, 3
     178              :                         IF (rho_set%norm_drhoa(ia, ir, 1) > drho_cutoff) THEN
     179              :                            vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
     180              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     181              :                                                   rho_set%norm_drhoa(ia, ir, 1)*my_adiabatic_rescale_factor
     182              :                         ELSE
     183              :                            vxg(idir, ia, ir, 1) = 0.0_dp
     184              :                         END IF
     185              :                      END DO
     186              :                   END DO
     187              :                END DO
     188              : !$OMP END PARALLEL DO
     189         6344 :                NULLIFY (deriv_data)
     190              :             END IF
     191         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drhob])
     192         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     193         6344 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     194              : !$OMP PARALLEL DO DEFAULT(NONE) COLLAPSE(2) SCHEDULE(STATIC) &
     195              : !$OMP             PRIVATE(ia, idir, ir) &
     196         6344 : !$OMP             SHARED(deriv_data, drho_cutoff, my_adiabatic_rescale_factor, na, nr, rho_set, vxg, w)
     197              :                DO ir = 1, nr
     198              :                   DO ia = 1, na
     199              :                      DO idir = 1, 3
     200              :                         IF (rho_set%norm_drhob(ia, ir, 1) > drho_cutoff) THEN
     201              :                            vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
     202              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     203              :                                                   rho_set%norm_drhob(ia, ir, 1)*my_adiabatic_rescale_factor
     204              :                         ELSE
     205              :                            vxg(idir, ia, ir, 2) = 0.0_dp
     206              :                         END IF
     207              :                      END DO
     208              :                   END DO
     209              :                END DO
     210              : !$OMP END PARALLEL DO
     211         6344 :                NULLIFY (deriv_data)
     212              :             END IF
     213              :             ! Cross Terms
     214         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     215         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     216         6056 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     217              : !$OMP PARALLEL DO DEFAULT(NONE) COLLAPSE(2) SCHEDULE(STATIC) &
     218              : !$OMP             PRIVATE(ia, idir, ir) &
     219         6056 : !$OMP             SHARED(deriv_data, drho_cutoff, my_adiabatic_rescale_factor, na, nr, rho_set, vxg, w)
     220              :                DO ir = 1, nr
     221              :                   DO ia = 1, na
     222              :                      DO idir = 1, 3
     223              :                         IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
     224              :                            vxg(idir, ia, ir, 1:2) = &
     225              :                               vxg(idir, ia, ir, 1:2) + ( &
     226              :                               rho_set%drhoa(idir)%array(ia, ir, 1) + &
     227              :                               rho_set%drhob(idir)%array(ia, ir, 1))* &
     228              :                               deriv_data(ia, ir, 1)*w(ia, ir)/rho_set%norm_drho(ia, ir, 1)* &
     229              :                               my_adiabatic_rescale_factor
     230              :                         END IF
     231              :                      END DO
     232              :                   END DO
     233              :                END DO
     234              : !$OMP END PARALLEL DO
     235         6056 :                NULLIFY (deriv_data)
     236              :             END IF
     237              :          ELSE
     238        64168 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_norm_drho])
     239        64168 :             IF (ASSOCIATED(deriv_att)) THEN
     240        40964 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     241              : !$OMP PARALLEL DO DEFAULT(NONE) COLLAPSE(2) SCHEDULE(STATIC) &
     242              : !$OMP             PRIVATE(ia, idir, ir) &
     243        40964 : !$OMP             SHARED(deriv_data, drho_cutoff, my_adiabatic_rescale_factor, na, nr, rho_set, vxg, w)
     244              :                DO ir = 1, nr
     245              :                   DO ia = 1, na
     246              :                      IF (rho_set%norm_drho(ia, ir, 1) > drho_cutoff) THEN
     247              :                         DO idir = 1, 3
     248              :                            vxg(idir, ia, ir, 1) = rho_set%drho(idir)%array(ia, ir, 1)* &
     249              :                                                   deriv_data(ia, ir, 1)*w(ia, ir)/ &
     250              :                                                   rho_set%norm_drho(ia, ir, 1)*my_adiabatic_rescale_factor
     251              :                         END DO
     252              :                      ELSE
     253              :                         vxg(1:3, ia, ir, 1) = 0.0_dp
     254              :                      END IF
     255              :                   END DO
     256              :                END DO
     257              : !$OMP END PARALLEL DO
     258        40964 :                NULLIFY (deriv_data)
     259              :             END IF
     260              :          END IF ! lsd
     261              :          !  Derivative with respect to tau
     262        74020 :          IF (lsd) THEN
     263         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_a])
     264         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     265           16 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     266        81632 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     267           16 :                NULLIFY (deriv_data)
     268              :             END IF
     269         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau_b])
     270         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     271           16 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     272        81632 :                vtau(:, :, 2) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     273           16 :                NULLIFY (deriv_data)
     274              :             END IF
     275         9852 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     276         9852 :             IF (ASSOCIATED(deriv_att)) THEN
     277            0 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     278            0 :                vtau(:, :, 1) = vtau(:, :, 1) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     279            0 :                vtau(:, :, 2) = vtau(:, :, 2) + deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     280            0 :                NULLIFY (deriv_data)
     281              :             END IF
     282              :          ELSE
     283        64168 :             deriv_att => xc_dset_get_derivative(deriv_set, [deriv_tau])
     284        64168 :             IF (ASSOCIATED(deriv_att)) THEN
     285         1604 :                CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     286      8823208 :                vtau(:, :, 1) = deriv_data(:, :, 1)*w(:, :)*my_adiabatic_rescale_factor
     287         1604 :                NULLIFY (deriv_data)
     288              :             END IF
     289              :          END IF ! lsd
     290              :       END IF ! only_energy
     291              : 
     292        77274 :       CALL timestop(handle)
     293              : 
     294        77274 :    END SUBROUTINE vxc_of_r_new
     295              : 
     296              : ! **************************************************************************************************
     297              : !> \brief Specific EPR version of vxc_of_r_new
     298              : !> \param xc_fun_section ...
     299              : !> \param rho_set ...
     300              : !> \param deriv_set ...
     301              : !> \param needs ...
     302              : !> \param w ...
     303              : !> \param lsd ...
     304              : !> \param na ...
     305              : !> \param nr ...
     306              : !> \param exc ...
     307              : !> \param vxc ...
     308              : !> \param vxg ...
     309              : !> \param vtau ...
     310              : ! **************************************************************************************************
     311           30 :    SUBROUTINE vxc_of_r_epr(xc_fun_section, rho_set, deriv_set, needs, w, &
     312              :                            lsd, na, nr, exc, vxc, vxg, vtau)
     313              : 
     314              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     315              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set
     316              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     317              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     318              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: w
     319              :       LOGICAL, INTENT(IN)                                :: lsd
     320              :       INTEGER, INTENT(in)                                :: na, nr
     321              :       REAL(dp)                                           :: exc
     322              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vxc
     323              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg
     324              :       REAL(dp), DIMENSION(:, :, :), POINTER              :: vtau
     325              : 
     326              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'vxc_of_r_epr'
     327              : 
     328              :       INTEGER                                            :: handle, ia, idir, ir, my_deriv_order
     329              :       LOGICAL                                            :: gradient_f
     330              :       REAL(dp)                                           :: my_adiabatic_rescale_factor
     331           30 :       REAL(dp), DIMENSION(:, :, :), POINTER              :: deriv_data
     332              :       REAL(KIND=dp)                                      :: drho_cutoff
     333              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     334              : 
     335           30 :       CALL timeset(routineN, handle)
     336              : 
     337              :       MARK_USED(vxc)
     338              :       MARK_USED(vtau)
     339              : 
     340           30 :       my_adiabatic_rescale_factor = 1.0_dp
     341           30 :       my_deriv_order = 2
     342              : 
     343              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     344           30 :                     needs%drho .OR. needs%norm_drho)
     345              : 
     346              :       !  Calculate the derivatives
     347              :       CALL xc_functionals_eval(xc_fun_section, &
     348              :                                lsd=lsd, &
     349              :                                rho_set=rho_set, &
     350              :                                deriv_set=deriv_set, &
     351           30 :                                deriv_order=my_deriv_order)
     352              : 
     353           30 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     354              : 
     355           30 :       NULLIFY (deriv_data)
     356              : 
     357              :       ! nabla v_xc (using the vxg arrays)
     358              :       ! there's no point doing this when lsd = false
     359           30 :       IF (lsd) THEN
     360           30 :          deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhoa, deriv_rhoa])
     361           30 :          IF (ASSOCIATED(deriv_att)) THEN
     362           30 :             CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     363         1530 :             DO ir = 1, nr
     364        76530 :                DO ia = 1, na
     365       301500 :                   DO idir = 1, 3
     366              :                      vxg(idir, ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)* &
     367       300000 :                                             deriv_data(ia, ir, 1)
     368              :                   END DO !idir
     369              :                END DO !ia
     370              :             END DO !ir
     371           30 :             NULLIFY (deriv_data)
     372              :          END IF
     373           30 :          deriv_att => xc_dset_get_derivative(deriv_set, [deriv_rhob, deriv_rhob])
     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       301500 :                   DO idir = 1, 3
     379              :                      vxg(idir, ia, ir, 2) = rho_set%drhob(idir)%array(ia, ir, 1)* &
     380       300000 :                                             deriv_data(ia, ir, 1)
     381              :                   END DO !idir
     382              :                END DO !ia
     383              :             END DO !ir
     384           30 :             NULLIFY (deriv_data)
     385              :          END IF
     386              :       END IF
     387              :       !  EXC energy ! is that needed for epr?
     388           30 :       deriv_att => xc_dset_get_derivative(deriv_set, [INTEGER::])
     389           30 :       exc = 0.0_dp
     390           30 :       IF (ASSOCIATED(deriv_att)) THEN
     391           30 :          CALL xc_derivative_get(deriv_att, deriv_data=deriv_data)
     392         1530 :          DO ir = 1, nr
     393        76530 :             DO ia = 1, na
     394        76500 :                exc = exc + deriv_data(ia, ir, 1)*w(ia, ir)
     395              :             END DO
     396              :          END DO
     397           30 :          NULLIFY (deriv_data)
     398              :       END IF
     399              : 
     400           30 :       CALL timestop(handle)
     401              : 
     402           30 :    END SUBROUTINE vxc_of_r_epr
     403              : 
     404              : ! **************************************************************************************************
     405              : !> \brief ...
     406              : !> \param rho_set ...
     407              : !> \param rho1_set ...
     408              : !> \param xc_section ...
     409              : !> \param deriv_set ...
     410              : !> \param w ...
     411              : !> \param vxc ...
     412              : !> \param vxg ...
     413              : !> \param vtau ...
     414              : !> \param do_triplet ...
     415              : !> \param do_sf ...
     416              : ! **************************************************************************************************
     417        20732 :    SUBROUTINE xc_2nd_deriv_of_r(rho_set, rho1_set, xc_section, &
     418        20732 :                                 deriv_set, w, vxc, vxg, vtau, do_triplet, do_sf)
     419              : 
     420              : ! As input of this routine one gets rho and drho on a one dimensional grid.
     421              : ! The grid is the angular grid corresponding to a given point ir on the radial grid.
     422              : ! The derivatives are calculated on this one dimensional grid, the results are stored in
     423              : ! vxc(1:na,ir,ispin), vxg(1:na,ir,ispin), vxg_cross(1:na,ir,ispin)
     424              : ! Afterwords the arrays containing the derivatives are put to zero so that the routine
     425              : ! can safely be called for the next radial point ir
     426              : 
     427              :       TYPE(xc_rho_set_type), INTENT(IN)                  :: rho_set, rho1_set
     428              :       TYPE(section_vals_type), POINTER                   :: xc_section
     429              :       TYPE(xc_derivative_set_type), INTENT(INOUT)        :: deriv_set
     430              :       REAL(dp), DIMENSION(:, :), INTENT(IN)              :: w
     431              :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), POINTER  :: vxc
     432              :       REAL(dp), DIMENSION(:, :, :, :), POINTER           :: vxg
     433              :       REAL(dp), CONTIGUOUS, DIMENSION(:, :, :), &
     434              :          OPTIONAL, POINTER                               :: vtau
     435              :       LOGICAL, INTENT(IN), OPTIONAL                      :: do_triplet, do_sf
     436              : 
     437              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'xc_2nd_deriv_of_r'
     438              : 
     439              :       INTEGER                                            :: handle, ispin, nspins
     440              :       LOGICAL                                            :: lsd, my_do_sf
     441              :       REAL(dp)                                           :: drho_cutoff, my_fac_triplet
     442              :       TYPE(cp_sll_xc_deriv_type), POINTER                :: pos
     443              :       TYPE(pw_pool_type), POINTER                        :: pw_pool
     444        20732 :       TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER        :: vxc_pw, vxc_tau_pw
     445              :       TYPE(section_vals_type), POINTER                   :: xc_fun_section
     446              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     447              : 
     448        20732 :       CALL timeset(routineN, handle)
     449              : 
     450        20732 :       nspins = SIZE(vxc, 3)
     451        20732 :       lsd = (nspins == 2)
     452        20732 :       IF (ASSOCIATED(rho_set%rhoa)) THEN
     453         1514 :          lsd = .TRUE.
     454              :       END IF
     455        20732 :       my_fac_triplet = 1.0_dp
     456        20732 :       IF (PRESENT(do_triplet)) THEN
     457        11184 :          IF (do_triplet) my_fac_triplet = -1.0_dp
     458              :       END IF
     459              : 
     460        20732 :       my_do_sf = .FALSE.
     461        20732 :       IF (PRESENT(do_sf)) my_do_sf = do_sf
     462              : 
     463        20732 :       CALL xc_rho_set_get(rho_set, drho_cutoff=drho_cutoff)
     464              :       xc_fun_section => section_vals_get_subs_vals(xc_section, &
     465        20732 :                                                    "XC_FUNCTIONAL")
     466              : 
     467              :       !  Calculate the derivatives
     468              :       CALL xc_functionals_eval(xc_fun_section, &
     469              :                                lsd=lsd, &
     470              :                                rho_set=rho_set, &
     471              :                                deriv_set=deriv_set, &
     472        20732 :                                deriv_order=2)
     473              : 
     474        20732 :       CALL divide_by_norm_drho(deriv_set, rho_set, lsd)
     475              : 
     476              :       ! multiply by w
     477        20732 :       pos => deriv_set%derivs
     478       137552 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     479    298028552 :          deriv_att%deriv_data(:, :, 1) = w(:, :)*deriv_att%deriv_data(:, :, 1)
     480              :       END DO
     481              : 
     482        20732 :       NULLIFY (pw_pool)
     483        83428 :       ALLOCATE (vxc_pw(nspins))
     484        41964 :       DO ispin = 1, nspins
     485        41964 :          vxc_pw(ispin)%array => vxc(:, :, ispin:ispin)
     486              :       END DO
     487              : 
     488        20732 :       NULLIFY (vxc_tau_pw)
     489        20732 :       IF (PRESENT(vtau)) THEN
     490        20732 :          IF (ASSOCIATED(vtau)) THEN
     491            0 :             ALLOCATE (vxc_tau_pw(nspins))
     492            0 :             DO ispin = 1, nspins
     493            0 :                vxc_tau_pw(ispin)%array => vtau(:, :, ispin:ispin)
     494              :             END DO
     495              :          END IF
     496              :       END IF
     497              : 
     498              :       CALL xc_calc_2nd_deriv_analytical(vxc_pw, vxc_tau_pw, deriv_set, rho_set, rho1_set, pw_pool, &
     499              :                                         xc_section, gapw=.TRUE., vxg=vxg, &
     500        20732 :                                         tddfpt_fac=my_fac_triplet, spinflip=do_sf)
     501              : 
     502        20732 :       DEALLOCATE (vxc_pw)
     503        20732 :       IF (ASSOCIATED(vxc_tau_pw)) DEALLOCATE (vxc_tau_pw)
     504              : 
     505              :       ! zero the derivative data for the next call
     506        20732 :       pos => deriv_set%derivs
     507       137552 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     508    298145372 :          deriv_att%deriv_data = 0.0_dp
     509              :       END DO
     510              : 
     511        20732 :       CALL timestop(handle)
     512              : 
     513        41464 :    END SUBROUTINE xc_2nd_deriv_of_r
     514              : 
     515              : ! **************************************************************************************************
     516              : !> \brief ...
     517              : !> \param rho_set ...
     518              : !> \param needs ...
     519              : !> \param nspins ...
     520              : !> \param bo ...
     521              : ! **************************************************************************************************
     522       175197 :    SUBROUTINE xc_rho_set_atom_update(rho_set, needs, nspins, bo)
     523              : 
     524              : !   This routine allocates the storage arrays for rho and drho
     525              : !   In calculate_vxc_atom this is called once for each atomic_kind,
     526              : !   After the loop over all the atoms of the kind and over all the points
     527              : !   of the radial grid for each atom, rho_set is deallocated.
     528              : !   Within the same kind, at each new point on the radial grid, the rho_set
     529              : !   arrays rho and drho are overwritten.
     530              : 
     531              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     532              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     533              :       INTEGER, INTENT(IN)                                :: nspins
     534              :       INTEGER, DIMENSION(2, 3), INTENT(IN)               :: bo
     535              : 
     536              :       INTEGER                                            :: idir
     537              : 
     538       331829 :       SELECT CASE (nspins)
     539              :       CASE (1)
     540              : !     What is this for?
     541       156632 :          IF (needs%rho_1_3) THEN
     542         4031 :             NULLIFY (rho_set%rho_1_3)
     543        20155 :             ALLOCATE (rho_set%rho_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     544         4031 :             rho_set%owns%rho_1_3 = .TRUE.
     545         4031 :             rho_set%has%rho_1_3 = .FALSE.
     546              :          END IF
     547              : !     Allocate the storage space for the density
     548       156632 :          IF (needs%rho) THEN
     549       156632 :             NULLIFY (rho_set%rho)
     550       783160 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     551       156632 :             rho_set%owns%rho = .TRUE.
     552       156632 :             rho_set%has%rho = .FALSE.
     553              :          END IF
     554              : !     Allocate the storage space for  the norm of the gradient of the density
     555       156632 :          IF (needs%norm_drho) THEN
     556       113650 :             NULLIFY (rho_set%norm_drho)
     557       568250 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     558       113650 :             rho_set%owns%norm_drho = .TRUE.
     559       113650 :             rho_set%has%norm_drho = .FALSE.
     560              :          END IF
     561              : !     Allocate the storage space for the three components of the gradient of the density
     562       156632 :          IF (needs%drho) THEN
     563       369200 :             DO idir = 1, 3
     564       276900 :                NULLIFY (rho_set%drho(idir)%array)
     565      1476800 :                ALLOCATE (rho_set%drho(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     566              :             END DO
     567        92300 :             rho_set%owns%drho = .TRUE.
     568        92300 :             rho_set%has%drho = .FALSE.
     569              :          END IF
     570              :       CASE (2)
     571              : !     Allocate the storage space for the total density
     572        18565 :          IF (needs%rho) THEN
     573              :             ! this should never be the case unless you use LDA functionals with LSD
     574            0 :             NULLIFY (rho_set%rho)
     575            0 :             ALLOCATE (rho_set%rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     576            0 :             rho_set%owns%rho = .TRUE.
     577            0 :             rho_set%has%rho = .FALSE.
     578              :          END IF
     579              : !     What is this for?
     580        18565 :          IF (needs%rho_1_3) THEN
     581            0 :             NULLIFY (rho_set%rho_1_3)
     582            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)))
     583            0 :             rho_set%owns%rho_1_3 = .TRUE.
     584            0 :             rho_set%has%rho_1_3 = .FALSE.
     585              :          END IF
     586              : !     What is this for?
     587        18565 :          IF (needs%rho_spin_1_3) THEN
     588         2440 :             NULLIFY (rho_set%rhoa_1_3, rho_set%rhob_1_3)
     589        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)))
     590         9760 :             ALLOCATE (rho_set%rhob_1_3(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     591         2440 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     592         2440 :             rho_set%has%rho_spin_1_3 = .FALSE.
     593              :          END IF
     594              : !     Allocate the storage space for the spin densities rhoa and rhob
     595        18565 :          IF (needs%rho_spin) THEN
     596        18565 :             NULLIFY (rho_set%rhoa, rho_set%rhob)
     597        92825 :             ALLOCATE (rho_set%rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     598        74260 :             ALLOCATE (rho_set%rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     599        18565 :             rho_set%owns%rho_spin = .TRUE.
     600        18565 :             rho_set%has%rho_spin = .FALSE.
     601              :          END IF
     602              : !     Allocate the storage space for the norm of the gradient of the total density
     603        18565 :          IF (needs%norm_drho) THEN
     604        12259 :             NULLIFY (rho_set%norm_drho)
     605        61295 :             ALLOCATE (rho_set%norm_drho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     606        12259 :             rho_set%owns%norm_drho = .TRUE.
     607        12259 :             rho_set%has%norm_drho = .FALSE.
     608              :          END IF
     609              : !     Allocate the storage space for the norm of the gradient of rhoa and of rhob separatedly
     610        18565 :          IF (needs%norm_drho_spin) THEN
     611        12547 :             NULLIFY (rho_set%norm_drhoa, rho_set%norm_drhob)
     612        62735 :             ALLOCATE (rho_set%norm_drhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     613        50188 :             ALLOCATE (rho_set%norm_drhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     614        12547 :             rho_set%owns%norm_drho_spin = .TRUE.
     615        12547 :             rho_set%has%norm_drho_spin = .FALSE.
     616              :          END IF
     617              : !     Allocate the storage space for the components of the gradient for the total rho
     618        18565 :          IF (needs%drho) THEN
     619            0 :             DO idir = 1, 3
     620            0 :                NULLIFY (rho_set%drho(idir)%array)
     621            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)))
     622              :             END DO
     623            0 :             rho_set%owns%drho = .TRUE.
     624            0 :             rho_set%has%drho = .FALSE.
     625              :          END IF
     626              : !     Allocate the storage space for the components of the gradient for rhoa and rhob
     627       193762 :          IF (needs%drho_spin) THEN
     628        46672 :             DO idir = 1, 3
     629        35004 :                NULLIFY (rho_set%drhoa(idir)%array, rho_set%drhob(idir)%array)
     630       175020 :                ALLOCATE (rho_set%drhoa(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     631       151684 :                ALLOCATE (rho_set%drhob(idir)%array(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     632              :             END DO
     633        11668 :             rho_set%owns%drho_spin = .TRUE.
     634        11668 :             rho_set%has%drho_spin = .FALSE.
     635              :          END IF
     636              : !
     637              :       END SELECT
     638              : 
     639              :       ! tau part
     640       175197 :       IF (needs%tau) THEN
     641         2728 :          NULLIFY (rho_set%tau)
     642        13640 :          ALLOCATE (rho_set%tau(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     643         2728 :          rho_set%owns%tau = .TRUE.
     644              :       END IF
     645       175197 :       IF (needs%tau_spin) THEN
     646           34 :          NULLIFY (rho_set%tau_a, rho_set%tau_b)
     647          170 :          ALLOCATE (rho_set%tau_a(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     648          136 :          ALLOCATE (rho_set%tau_b(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     649           34 :          rho_set%owns%tau_spin = .TRUE.
     650           34 :          rho_set%has%tau_spin = .FALSE.
     651              :       END IF
     652              : 
     653              :       ! Laplace part
     654       175197 :       IF (needs%laplace_rho) THEN
     655            0 :          NULLIFY (rho_set%laplace_rho)
     656            0 :          ALLOCATE (rho_set%laplace_rho(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     657            0 :          rho_set%owns%laplace_rho = .TRUE.
     658              :       END IF
     659       175197 :       IF (needs%laplace_rho_spin) THEN
     660            0 :          NULLIFY (rho_set%laplace_rhoa)
     661            0 :          NULLIFY (rho_set%laplace_rhob)
     662            0 :          ALLOCATE (rho_set%laplace_rhoa(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     663            0 :          ALLOCATE (rho_set%laplace_rhob(bo(1, 1):bo(2, 1), bo(1, 2):bo(2, 2), bo(1, 3):bo(2, 3)))
     664            0 :          rho_set%owns%laplace_rho_spin = .TRUE.
     665            0 :          rho_set%has%laplace_rho_spin = .TRUE.
     666              :       END IF
     667              : 
     668       175197 :    END SUBROUTINE xc_rho_set_atom_update
     669              : 
     670              : ! **************************************************************************************************
     671              : !> \brief ...
     672              : !> \param rho_set ...
     673              : !> \param lsd ...
     674              : !> \param nspins ...
     675              : !> \param needs ...
     676              : !> \param rho ...
     677              : !> \param drho ...
     678              : !> \param tau ...
     679              : !> \param na ...
     680              : !> \param ir ...
     681              : ! **************************************************************************************************
     682      6177080 :    SUBROUTINE fill_rho_set(rho_set, lsd, nspins, needs, rho, drho, tau, na, ir)
     683              : 
     684              :       TYPE(xc_rho_set_type), INTENT(INOUT)               :: rho_set
     685              :       LOGICAL, INTENT(IN)                                :: lsd
     686              :       INTEGER, INTENT(IN)                                :: nspins
     687              :       TYPE(xc_rho_cflags_type), INTENT(IN)               :: needs
     688              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: rho
     689              :       REAL(dp), DIMENSION(:, :, :, :), INTENT(IN)        :: drho
     690              :       REAL(dp), DIMENSION(:, :, :), INTENT(IN)           :: tau
     691              :       INTEGER, INTENT(IN)                                :: na, ir
     692              : 
     693              :       REAL(KIND=dp), PARAMETER                           :: f13 = (1.0_dp/3.0_dp)
     694              : 
     695              :       INTEGER                                            :: ia, idir, my_nspins
     696              :       LOGICAL                                            :: gradient_f, tddft_split
     697              : 
     698      6177080 :       my_nspins = nspins
     699      6177080 :       tddft_split = .FALSE.
     700      6177080 :       IF (lsd .AND. nspins == 1) THEN
     701        90600 :          my_nspins = 2
     702        90600 :          tddft_split = .TRUE.
     703              :       END IF
     704              : 
     705              :       ! some checks
     706      6177080 :       IF (lsd) THEN
     707              :       ELSE
     708      5348100 :          CPASSERT(SIZE(rho, 3) == 1)
     709              :       END IF
     710      5348100 :       SELECT CASE (my_nspins)
     711              :       CASE (1)
     712      5348100 :          CPASSERT(.NOT. needs%rho_spin)
     713      5348100 :          CPASSERT(.NOT. needs%drho_spin)
     714      5348100 :          CPASSERT(.NOT. needs%norm_drho_spin)
     715      5348100 :          CPASSERT(.NOT. needs%rho_spin_1_3)
     716              :       CASE (2)
     717              :       CASE default
     718      6177080 :          CPABORT("Unsupported number of spins")
     719              :       END SELECT
     720              : 
     721              :       gradient_f = (needs%drho_spin .OR. needs%norm_drho_spin .OR. &
     722      6177080 :                     needs%drho .OR. needs%norm_drho)
     723              : 
     724      5348100 :       SELECT CASE (my_nspins)
     725              :       CASE (1)
     726              :          ! Give rho to 1/3
     727      5348100 :          IF (needs%rho_1_3) THEN
     728      6735000 :             DO ia = 1, na
     729      6735000 :                rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     730              :             END DO
     731       132200 :             rho_set%owns%rho_1_3 = .TRUE.
     732       132200 :             rho_set%has%rho_1_3 = .TRUE.
     733              :          END IF
     734              :          ! Give the density
     735      5348100 :          IF (needs%rho) THEN
     736    272803500 :             DO ia = 1, na
     737    272803500 :                rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     738              :             END DO
     739      5348100 :             rho_set%owns%rho = .TRUE.
     740      5348100 :             rho_set%has%rho = .TRUE.
     741              :          END IF
     742              :          ! Give the norm of the gradient of the density
     743      5348100 :          IF (needs%norm_drho) THEN
     744    176481900 :             DO ia = 1, na
     745    176481900 :                rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     746              :             END DO
     747      3456900 :             rho_set%owns%norm_drho = .TRUE.
     748      3456900 :             rho_set%has%norm_drho = .TRUE.
     749              :          END IF
     750              :          ! Give the three components of the gradient of the density
     751      5348100 :          IF (needs%drho) THEN
     752     13856400 :             DO idir = 1, 3
     753    533622600 :                DO ia = 1, na
     754    530158500 :                   rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     755              :                END DO
     756              :             END DO
     757      3464100 :             rho_set%owns%drho = .TRUE.
     758      3464100 :             rho_set%has%drho = .TRUE.
     759              :          END IF
     760              :       CASE (2)
     761              :          ! Give the total density
     762       828980 :          IF (needs%rho) THEN
     763              :             ! this should never be the case unless you use LDA functionals with LSD
     764            0 :             IF (.NOT. tddft_split) THEN
     765            0 :                DO ia = 1, na
     766            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1) + rho(ia, ir, 2)
     767              :                END DO
     768              :             ELSE
     769            0 :                DO ia = 1, na
     770            0 :                   rho_set%rho(ia, ir, 1) = rho(ia, ir, 1)
     771              :                END DO
     772              :             END IF
     773            0 :             rho_set%owns%rho = .TRUE.
     774            0 :             rho_set%has%rho = .TRUE.
     775              :          END IF
     776              :          ! Give the total density to 1/3
     777       828980 :          IF (needs%rho_1_3) THEN
     778            0 :             IF (.NOT. tddft_split) THEN
     779            0 :                DO ia = 1, na
     780            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1) + rho(ia, ir, 2), 0.0_dp)**f13
     781              :                END DO
     782              :             ELSE
     783            0 :                DO ia = 1, na
     784            0 :                   rho_set%rho_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     785              :                END DO
     786              :             END IF
     787            0 :             rho_set%owns%rho_1_3 = .TRUE.
     788            0 :             rho_set%has%rho_1_3 = .TRUE.
     789              :          END IF
     790              :          ! Give the spin densities to 1/3
     791       828980 :          IF (needs%rho_spin_1_3) THEN
     792        75480 :             IF (.NOT. tddft_split) THEN
     793      3837960 :                DO ia = 1, na
     794      3762480 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(rho(ia, ir, 1), 0.0_dp)**f13
     795      3837960 :                   rho_set%rhob_1_3(ia, ir, 1) = MAX(rho(ia, ir, 2), 0.0_dp)**f13
     796              :                END DO
     797              :             ELSE
     798            0 :                DO ia = 1, na
     799            0 :                   rho_set%rhoa_1_3(ia, ir, 1) = MAX(0.5_dp*rho(ia, ir, 1), 0.0_dp)**f13
     800            0 :                   rho_set%rhob_1_3(ia, ir, 1) = rho_set%rhoa_1_3(ia, ir, 1)
     801              :                END DO
     802              :             END IF
     803        75480 :             rho_set%owns%rho_spin_1_3 = .TRUE.
     804        75480 :             rho_set%has%rho_spin_1_3 = .TRUE.
     805              :          END IF
     806              :          ! Give the spin densities rhoa and rhob
     807       828980 :          IF (needs%rho_spin) THEN
     808       828980 :             IF (.NOT. tddft_split) THEN
     809     37645860 :                DO ia = 1, na
     810     36907480 :                   rho_set%rhoa(ia, ir, 1) = rho(ia, ir, 1)
     811     37645860 :                   rho_set%rhob(ia, ir, 1) = rho(ia, ir, 2)
     812              :                END DO
     813              :             ELSE
     814      4620600 :                DO ia = 1, na
     815      4530000 :                   rho_set%rhoa(ia, ir, 1) = 0.5_dp*rho(ia, ir, 1)
     816      4620600 :                   rho_set%rhob(ia, ir, 1) = rho_set%rhoa(ia, ir, 1)
     817              :                END DO
     818              :             END IF
     819       828980 :             rho_set%owns%rho_spin = .TRUE.
     820       828980 :             rho_set%has%rho_spin = .TRUE.
     821              :          END IF
     822              :          ! Give the norm of the gradient of the total density
     823       828980 :          IF (needs%norm_drho) THEN
     824       483480 :             IF (.NOT. tddft_split) THEN
     825     21249360 :                DO ia = 1, na
     826              :                   rho_set%norm_drho(ia, ir, 1) = SQRT( &
     827              :                                                  (drho(1, ia, ir, 1) + drho(1, ia, ir, 2))**2 + &
     828              :                                                  (drho(2, ia, ir, 1) + drho(2, ia, ir, 2))**2 + &
     829     21249360 :                                                  (drho(3, ia, ir, 1) + drho(3, ia, ir, 2))**2)
     830              :                END DO
     831              :             ELSE
     832      3396600 :                DO ia = 1, na
     833      3396600 :                   rho_set%norm_drho(ia, ir, 1) = drho(4, ia, ir, 1)
     834              :                END DO
     835              :             END IF
     836       483480 :             rho_set%owns%norm_drho = .TRUE.
     837       483480 :             rho_set%has%norm_drho = .TRUE.
     838              :          END IF
     839              :          ! Give the norm of the gradient of rhoa and of rhob separatedly
     840       828980 :          IF (needs%norm_drho_spin) THEN
     841       497880 :             IF (.NOT. tddft_split) THEN
     842     21983760 :                DO ia = 1, na
     843     21552480 :                   rho_set%norm_drhoa(ia, ir, 1) = drho(4, ia, ir, 1)
     844     21983760 :                   rho_set%norm_drhob(ia, ir, 1) = drho(4, ia, ir, 2)
     845              :                END DO
     846              :             ELSE
     847      3396600 :                DO ia = 1, na
     848      3330000 :                   rho_set%norm_drhoa(ia, ir, 1) = 0.5_dp*drho(4, ia, ir, 1)
     849      3396600 :                   rho_set%norm_drhob(ia, ir, 1) = rho_set%norm_drhoa(ia, ir, 1)
     850              :                END DO
     851              :             END IF
     852       497880 :             rho_set%owns%norm_drho_spin = .TRUE.
     853       497880 :             rho_set%has%norm_drho_spin = .TRUE.
     854              :          END IF
     855              :          ! Give the components of the gradient for the total rho
     856       828980 :          IF (needs%drho) THEN
     857            0 :             IF (.NOT. tddft_split) THEN
     858            0 :                DO idir = 1, 3
     859            0 :                   DO ia = 1, na
     860            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1) + drho(idir, ia, ir, 2)
     861              :                   END DO
     862              :                END DO
     863              :             ELSE
     864            0 :                DO idir = 1, 3
     865            0 :                   DO ia = 1, na
     866            0 :                      rho_set%drho(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     867              :                   END DO
     868              :                END DO
     869              :             END IF
     870            0 :             rho_set%owns%drho = .TRUE.
     871            0 :             rho_set%has%drho = .TRUE.
     872              :          END IF
     873              :          ! Give the components of the gradient for rhoa and rhob
     874      7006060 :          IF (needs%drho_spin) THEN
     875       499380 :             IF (.NOT. tddft_split) THEN
     876      1731120 :                DO idir = 1, 3
     877     66613560 :                   DO ia = 1, na
     878     64882440 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 1)
     879     66180780 :                      rho_set%drhob(idir)%array(ia, ir, 1) = drho(idir, ia, ir, 2)
     880              :                   END DO
     881              :                END DO
     882              :             ELSE
     883       266400 :                DO idir = 1, 3
     884     10256400 :                   DO ia = 1, na
     885      9990000 :                      rho_set%drhoa(idir)%array(ia, ir, 1) = 0.5_dp*drho(idir, ia, ir, 1)
     886     10189800 :                      rho_set%drhob(idir)%array(ia, ir, 1) = rho_set%drhoa(idir)%array(ia, ir, 1)
     887              :                   END DO
     888              :                END DO
     889              :             END IF
     890       499380 :             rho_set%owns%drho_spin = .TRUE.
     891       499380 :             rho_set%has%drho_spin = .TRUE.
     892              :          END IF
     893              :          !
     894              :       END SELECT
     895              : 
     896              :       ! tau part
     897      6177080 :       IF (needs%tau .OR. needs%tau_spin) THEN
     898      6177080 :          CPASSERT(SIZE(tau, 3) == my_nspins)
     899              :       END IF
     900      6177080 :       IF (needs%tau) THEN
     901        90000 :          IF (my_nspins == 2) THEN
     902            0 :             DO ia = 1, na
     903            0 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1) + tau(ia, ir, 2)
     904              :             END DO
     905            0 :             rho_set%owns%tau = .TRUE.
     906            0 :             rho_set%has%tau = .TRUE.
     907              :          ELSE
     908      4647600 :             DO ia = 1, na
     909      4647600 :                rho_set%tau(ia, ir, 1) = tau(ia, ir, 1)
     910              :             END DO
     911        90000 :             rho_set%owns%tau = .TRUE.
     912        90000 :             rho_set%has%tau = .TRUE.
     913              :          END IF
     914              :       END IF
     915      6177080 :       IF (needs%tau_spin) THEN
     916        40800 :          DO ia = 1, na
     917        40000 :             rho_set%tau_a(ia, ir, 1) = tau(ia, ir, 1)
     918        40800 :             rho_set%tau_b(ia, ir, 1) = tau(ia, ir, 2)
     919              :          END DO
     920          800 :          rho_set%owns%tau_spin = .TRUE.
     921          800 :          rho_set%has%tau_spin = .TRUE.
     922              :       END IF
     923              : 
     924      6177080 :    END SUBROUTINE fill_rho_set
     925              : 
     926              : END MODULE xc_atom
        

Generated by: LCOV version 2.0-1