LCOV - code coverage report
Current view: top level - src/xc - xc_atom.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:42dac4a) Lines: 81.7 % 388 317
Test Date: 2025-07-25 12:55:17 Functions: 100.0 % 4 4

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

Generated by: LCOV version 2.0-1