LCOV - code coverage report
Current view: top level - src/xc - xc_derivative_set_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 95.0 % 60 57
Test Date: 2026-07-25 06:35:44 Functions: 83.3 % 6 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              : !> \brief represent a group ofunctional derivatives
      10              : !> \par History
      11              : !>      11.2003 created [fawzi]
      12              : !> \author fawzi & thomas
      13              : ! **************************************************************************************************
      14              : MODULE xc_derivative_set_types
      15              :    USE cp_linked_list_xc_deriv,         ONLY: cp_sll_xc_deriv_dealloc,&
      16              :                                               cp_sll_xc_deriv_insert_el,&
      17              :                                               cp_sll_xc_deriv_next,&
      18              :                                               cp_sll_xc_deriv_type
      19              :    USE kinds,                           ONLY: dp
      20              :    USE pw_grid_types,                   ONLY: pw_grid_type
      21              :    USE pw_grids,                        ONLY: pw_grid_create,&
      22              :                                               pw_grid_release
      23              :    USE pw_methods,                      ONLY: pw_zero
      24              :    USE pw_pool_types,                   ONLY: pw_pool_create,&
      25              :                                               pw_pool_release,&
      26              :                                               pw_pool_type
      27              :    USE pw_types,                        ONLY: pw_r3d_rs_type
      28              :    USE xc_derivative_desc,              ONLY: standardize_desc
      29              :    USE xc_derivative_types,             ONLY: xc_derivative_create,&
      30              :                                               xc_derivative_release,&
      31              :                                               xc_derivative_type
      32              : #include "../base/base_uses.f90"
      33              : 
      34              :    IMPLICIT NONE
      35              :    PRIVATE
      36              : 
      37              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      38              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'xc_derivative_set_types'
      39              : 
      40              :    PUBLIC :: xc_derivative_set_type
      41              :    PUBLIC :: xc_dset_create, xc_dset_release, &
      42              :              xc_dset_get_derivative, xc_dset_zero_all, xc_dset_recover_pw
      43              : 
      44              : ! **************************************************************************************************
      45              : !> \brief A derivative set contains the different derivatives of a xc-functional
      46              : !>      in form of a linked list
      47              : ! **************************************************************************************************
      48              :    TYPE xc_derivative_set_type
      49              :       TYPE(pw_pool_type), POINTER, PRIVATE :: pw_pool => NULL()
      50              :       TYPE(cp_sll_xc_deriv_type), POINTER :: derivs => NULL()
      51              :    END TYPE xc_derivative_set_type
      52              : 
      53              : CONTAINS
      54              : 
      55              : ! **************************************************************************************************
      56              : !> \brief returns the requested xc_derivative
      57              : !> \param derivative_set the set where to search for the derivative
      58              : !> \param description the description of the derivative you want to have
      59              : !> \param allocate_deriv if the derivative should be allocated when not present
      60              : !>                        Defaults to false.
      61              : !> \return ...
      62              : ! **************************************************************************************************
      63      3108279 :    FUNCTION xc_dset_get_derivative(derivative_set, description, allocate_deriv) &
      64              :       RESULT(res)
      65              : 
      66              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: derivative_set
      67              :       INTEGER, DIMENSION(:), INTENT(in)                  :: description
      68              :       LOGICAL, INTENT(in), OPTIONAL                      :: allocate_deriv
      69              :       TYPE(xc_derivative_type), POINTER                  :: res
      70              : 
      71      3108279 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: std_deriv_desc
      72              :       LOGICAL                                            :: my_allocate_deriv
      73              :       REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :, :), &
      74      3108279 :          POINTER                                         :: r3d_ptr
      75              :       TYPE(cp_sll_xc_deriv_type), POINTER                :: pos
      76              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
      77              : 
      78      3108279 :       NULLIFY (pos, deriv_att, r3d_ptr)
      79              : 
      80      3108279 :       my_allocate_deriv = .FALSE.
      81      1084416 :       IF (PRESENT(allocate_deriv)) my_allocate_deriv = allocate_deriv
      82      3108279 :       NULLIFY (res)
      83      3108279 :       CALL standardize_desc(description, std_deriv_desc)
      84      3108279 :       pos => derivative_set%derivs
      85     13448488 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
      86     13448488 :          IF (SIZE(deriv_att%split_desc) == SIZE(std_deriv_desc)) THEN
      87      8982123 :          IF (ALL(deriv_att%split_desc == std_deriv_desc)) THEN
      88      1274160 :             res => deriv_att
      89      1274160 :             EXIT
      90              :          END IF
      91              :          END IF
      92              :       END DO
      93      3108279 :       IF (.NOT. ASSOCIATED(res) .AND. my_allocate_deriv) THEN
      94       715381 :          CALL derivative_set%pw_pool%create_cr3d(r3d_ptr)
      95       715381 :          r3d_ptr = 0.0_dp
      96       715381 :          ALLOCATE (res)
      97              :          CALL xc_derivative_create(res, std_deriv_desc, &
      98       715381 :                                    r3d_ptr=r3d_ptr)
      99       715381 :          CALL cp_sll_xc_deriv_insert_el(derivative_set%derivs, res)
     100              :       END IF
     101      6216558 :    END FUNCTION xc_dset_get_derivative
     102              : 
     103              : ! **************************************************************************************************
     104              : !> \brief creates a derivative set object
     105              : !> \param derivative_set the set where to search for the derivative
     106              : !> \param pw_pool pool where to get the cr3d arrays needed to store the
     107              : !>        derivatives
     108              : !> \param local_bounds ...
     109              : ! **************************************************************************************************
     110       243112 :    SUBROUTINE xc_dset_create(derivative_set, pw_pool, local_bounds)
     111              : 
     112              :       TYPE(xc_derivative_set_type), INTENT(OUT)          :: derivative_set
     113              :       TYPE(pw_pool_type), OPTIONAL, POINTER              :: pw_pool
     114              :       INTEGER, DIMENSION(2, 3), INTENT(IN), OPTIONAL     :: local_bounds
     115              : 
     116              :       TYPE(pw_grid_type), POINTER                        :: pw_grid
     117              : 
     118       243112 :       NULLIFY (pw_grid)
     119              : 
     120       243112 :       IF (PRESENT(pw_pool)) THEN
     121       158593 :          derivative_set%pw_pool => pw_pool
     122       158593 :          CALL pw_pool%retain()
     123       158593 :          IF (PRESENT(local_bounds)) THEN
     124            0 :             IF (ANY(pw_pool%pw_grid%bounds_local /= local_bounds)) THEN
     125            0 :                CPABORT("incompatible local_bounds and pw_pool")
     126              :             END IF
     127              :          END IF
     128              :       ELSE
     129              :          !FM ugly hack, should be replaced by a pool only for 3d arrays
     130        84519 :          CPASSERT(PRESENT(local_bounds))
     131        84519 :          CALL pw_grid_create(pw_grid, local_bounds)
     132        84519 :          CALL pw_pool_create(derivative_set%pw_pool, pw_grid)
     133        84519 :          CALL pw_grid_release(pw_grid)
     134              :       END IF
     135              : 
     136       243112 :    END SUBROUTINE xc_dset_create
     137              : 
     138              : ! **************************************************************************************************
     139              : !> \brief releases a derivative set
     140              : !> \param derivative_set the set to release
     141              : ! **************************************************************************************************
     142       243112 :    SUBROUTINE xc_dset_release(derivative_set)
     143              : 
     144              :       TYPE(xc_derivative_set_type)                       :: derivative_set
     145              : 
     146              :       TYPE(cp_sll_xc_deriv_type), POINTER                :: pos
     147              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     148              : 
     149       243112 :       NULLIFY (deriv_att, pos)
     150              : 
     151       243112 :       pos => derivative_set%derivs
     152       958493 :       DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     153       715381 :          CALL xc_derivative_release(deriv_att, pw_pool=derivative_set%pw_pool)
     154       715381 :          DEALLOCATE (deriv_att)
     155              :       END DO
     156       243112 :       CALL cp_sll_xc_deriv_dealloc(derivative_set%derivs)
     157       243112 :       IF (ASSOCIATED(derivative_set%pw_pool)) CALL pw_pool_release(derivative_set%pw_pool)
     158              : 
     159       243112 :    END SUBROUTINE xc_dset_release
     160              : 
     161              : ! **************************************************************************************************
     162              : !> \brief ...
     163              : !> \param deriv_set ...
     164              : ! **************************************************************************************************
     165       101709 :    SUBROUTINE xc_dset_zero_all(deriv_set)
     166              : 
     167              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     168              : 
     169              :       TYPE(cp_sll_xc_deriv_type), POINTER                :: pos
     170              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     171              : 
     172       101709 :       NULLIFY (pos, deriv_att)
     173              : 
     174       101709 :       IF (ASSOCIATED(deriv_set%derivs)) THEN
     175        43695 :          pos => deriv_set%derivs
     176       181384 :          DO WHILE (cp_sll_xc_deriv_next(pos, el_att=deriv_att))
     177    383712521 :             deriv_att%deriv_data = 0.0_dp
     178              :          END DO
     179              :       END IF
     180              : 
     181       101709 :    END SUBROUTINE xc_dset_zero_all
     182              : 
     183              : ! **************************************************************************************************
     184              : !> \brief Recovers a derivative on a pw_r3d_rs_type, the caller is responsible to release the grid later
     185              : !>        If the derivative is not found, either creates a blank pw_r3d_rs_type from pw_pool or leaves it unassociated
     186              : !> \param deriv_set ...
     187              : !> \param description ...
     188              : !> \param pw ...
     189              : !> \param pw_grid ...
     190              : !> \param pw_pool create pw from this pool if derivative not found
     191              : ! **************************************************************************************************
     192       296019 :    SUBROUTINE xc_dset_recover_pw(deriv_set, description, pw, pw_grid, pw_pool)
     193              :       TYPE(xc_derivative_set_type), INTENT(IN)           :: deriv_set
     194              :       INTEGER, DIMENSION(:), INTENT(IN)                  :: description
     195              :       TYPE(pw_r3d_rs_type), INTENT(OUT)                  :: pw
     196              :       TYPE(pw_grid_type), INTENT(IN), POINTER            :: pw_grid
     197              :       TYPE(pw_pool_type), INTENT(IN), OPTIONAL, POINTER  :: pw_pool
     198              : 
     199              :       TYPE(xc_derivative_type), POINTER                  :: deriv_att
     200              : 
     201       296019 :       deriv_att => xc_dset_get_derivative(deriv_set, description)
     202       296019 :       IF (ASSOCIATED(deriv_att)) THEN
     203       295397 :          CALL pw%create(pw_grid=pw_grid, array_ptr=deriv_att%deriv_data)
     204       295397 :          NULLIFY (deriv_att%deriv_data)
     205          622 :       ELSE IF (PRESENT(pw_pool)) THEN
     206          622 :          CALL pw_pool%create_pw(pw)
     207          622 :          CALL pw_zero(pw)
     208              :       END IF
     209              : 
     210       296019 :    END SUBROUTINE xc_dset_recover_pw
     211              : 
     212            0 : END MODULE xc_derivative_set_types
        

Generated by: LCOV version 2.0-1