LCOV - code coverage report
Current view: top level - src/common - cp_array_utils.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 35.9 % 64 23
Test Date: 2025-12-04 06:27:48 Functions: 4.5 % 44 2

            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              : #:include 'cp_array_utils.fypp'
       9              : 
      10              : ! **************************************************************************************************
      11              : !> \brief various utilities that regard array of different kinds:
      12              : !>      output, allocation,...
      13              : !>      maybe it is not a good idea mixing output and memeory utils...
      14              : !> \par History
      15              : !>      12.2001 first version [fawzi]
      16              : !>      3.2002 templatized [fawzi]
      17              : !> \author Fawzi Mohamed
      18              : ! **************************************************************************************************
      19              : MODULE cp_array_utils
      20              :    USE machine, ONLY: m_flush
      21              :    USE cp_log_handling, ONLY: cp_to_string
      22              : 
      23              :    USE kinds, ONLY: ${uselist(usekinds)}$
      24              : 
      25              : #include "../base/base_uses.f90"
      26              :    IMPLICIT NONE
      27              :    PRIVATE
      28              : 
      29              :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      30              :    CHARACTER(len=*), PRIVATE, PARAMETER :: moduleN = 'cp_array_utils'
      31              : 
      32              :    #:for nametype in nametype1
      33              :       PUBLIC :: cp_1d_${nametype}$_p_type, &
      34              :                 cp_2d_${nametype}$_p_type, &
      35              :                 cp_3d_${nametype}$_p_type, &
      36              :                 cp_1d_${nametype}$_cp_type, &
      37              :                 cp_2d_${nametype}$_cp_type, &
      38              :                 cp_3d_${nametype}$_cp_type, &
      39              :                 cp_1d_${nametype}$_guarantee_size, &
      40              :                 cp_1d_${nametype}$_write, &
      41              :                 cp_2d_${nametype}$_write, &
      42              :                 cp_2d_${nametype}$_guarantee_size, &
      43              :                 cp_1d_${nametype}$_bsearch
      44              :    #:endfor
      45              : 
      46              :    ! generic interfaces
      47              :    PUBLIC :: cp_guarantee_size
      48              : 
      49              :    INTERFACE cp_guarantee_size
      50              :       #:for nametype in nametype1
      51              :          MODULE PROCEDURE cp_1d_${nametype}$_guarantee_size, &
      52              :             cp_2d_${nametype}$_guarantee_size
      53              :       #:endfor
      54              :    END INTERFACE
      55              : 
      56              : !***
      57              : 
      58              :    #:for nametype1, type1, defaultFormatType1, lessQ in inst_params
      59              : 
      60              : ! **************************************************************************************************
      61              : !> \brief represent a pointer to a 1d array
      62              : !> \par History
      63              : !>      02.2003 created [fawzi]
      64              : !> \author fawzi
      65              : ! **************************************************************************************************
      66              :       type cp_1d_${nametype1}$_p_type
      67              :          ${type1}$, dimension(:), pointer :: array => NULL()
      68              :       end type cp_1d_${nametype1}$_p_type
      69              : 
      70              : ! **************************************************************************************************
      71              : !> \brief represent a pointer to a 2d array
      72              : !> \par History
      73              : !>      02.2003 created [fawzi]
      74              : !> \author fawzi
      75              : ! **************************************************************************************************
      76              :       type cp_2d_${nametype1}$_p_type
      77              :          ${type1}$, dimension(:, :), pointer :: array => NULL()
      78              :       end type cp_2d_${nametype1}$_p_type
      79              : 
      80              : ! **************************************************************************************************
      81              : !> \brief represent a pointer to a 3d array
      82              : !> \par History
      83              : !>      02.2003 created [fawzi]
      84              : !> \author fawzi
      85              : ! **************************************************************************************************
      86              :       type cp_3d_${nametype1}$_p_type
      87              :          ${type1}$, dimension(:, :, :), pointer :: array => NULL()
      88              :       end type cp_3d_${nametype1}$_p_type
      89              : 
      90              : ! **************************************************************************************************
      91              : !> \brief represent a pointer to a contiguous 1d array
      92              : !> \par History
      93              : !>      02.2003 created [fawzi]
      94              : !> \author fawzi
      95              : ! **************************************************************************************************
      96              :       type cp_1d_${nametype1}$_cp_type
      97              :          ${type1}$, dimension(:), contiguous, pointer :: array => NULL()
      98              :       end type cp_1d_${nametype1}$_cp_type
      99              : 
     100              : ! **************************************************************************************************
     101              : !> \brief represent a pointer to a contiguous 2d array
     102              : !> \par History
     103              : !>      02.2003 created [fawzi]
     104              : !> \author fawzi
     105              : ! **************************************************************************************************
     106              :       type cp_2d_${nametype1}$_cp_type
     107              :          ${type1}$, dimension(:, :), contiguous, pointer :: array => NULL()
     108              :       end type cp_2d_${nametype1}$_cp_type
     109              : 
     110              : ! **************************************************************************************************
     111              : !> \brief represent a pointer to a contiguous 3d array
     112              : !> \par History
     113              : !>      02.2003 created [fawzi]
     114              : !> \author fawzi
     115              : ! **************************************************************************************************
     116              :       type cp_3d_${nametype1}$_cp_type
     117              :          ${type1}$, dimension(:, :, :), contiguous, pointer :: array => NULL()
     118              :       end type cp_3d_${nametype1}$_cp_type
     119              : 
     120              :    #:endfor
     121              : 
     122              : CONTAINS
     123              : 
     124              :    #:for nametype1, type1, defaultFormatType1, lessQ in inst_params
     125              : ! **************************************************************************************************
     126              : !> \brief writes an array to the given unit
     127              : !> \param array the array to write
     128              : !> \param unit_nr the unit to write to (defaults to the standard out)
     129              : !> \param el_format the format of a single element
     130              : !> \par History
     131              : !>      4.2002 created [fawzi]
     132              : !> \author Fawzi Mohamed
     133              : !> \note
     134              : !>      maybe I will move to a comma separated paretized list
     135              : ! **************************************************************************************************
     136          216 :       SUBROUTINE cp_1d_${nametype1}$_write(array, unit_nr, el_format)
     137              :          ${type1}$, INTENT(in) :: array(:)
     138              :          INTEGER, INTENT(in) :: unit_nr
     139              :          CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
     140              : 
     141              :          INTEGER :: iostat, i
     142              :          CHARACTER(len=*), PARAMETER :: defaultFormat = ${defaultFormatType1}$
     143              : 
     144          216 :          WRITE (unit=unit_nr, fmt="('( ')", advance="no", iostat=iostat)
     145          216 :          CPASSERT(iostat == 0)
     146          216 :          IF (PRESENT(el_format)) THEN
     147            0 :             DO i = 1, SIZE(array) - 1
     148            0 :                WRITE (unit=unit_nr, fmt=el_format, advance="no") array(i)
     149            0 :                IF (MOD(i, 5) == 0) THEN  ! only a few elements per line
     150            0 :                   WRITE (unit=unit_nr, fmt="(',')")
     151              :                ELSE
     152            0 :                   WRITE (unit=unit_nr, fmt="(',')", advance="no")
     153              :                END IF
     154              :             END DO
     155            0 :             IF (SIZE(array) > 0) &
     156            0 :                WRITE (unit=unit_nr, fmt=el_format, advance="no") array(SIZE(array))
     157              :          ELSE
     158          807 :             DO i = 1, SIZE(array) - 1
     159          591 :                WRITE (unit=unit_nr, fmt=defaultFormat, advance="no") array(i)
     160          807 :                IF (MOD(i, 5) == 0) THEN  ! only a few elements per line
     161           88 :                   WRITE (unit=unit_nr, fmt="(',')")
     162              :                ELSE
     163          503 :                   WRITE (unit=unit_nr, fmt="(',')", advance="no")
     164              :                END IF
     165              :             END DO
     166          216 :             IF (SIZE(array) > 0) &
     167          190 :                WRITE (unit=unit_nr, fmt=defaultFormat, advance="no") array(SIZE(array))
     168              :          END IF
     169          216 :          WRITE (unit=unit_nr, fmt="(' )')")
     170          216 :          call m_flush(unit_nr)
     171              : 
     172          216 :       END SUBROUTINE cp_1d_${nametype1}$_write
     173              : 
     174              : ! **************************************************************************************************
     175              : !> \brief writes an array to the given unit
     176              : !> \param array the array to write
     177              : !> \param unit_nr the unit to write to (defaults to the standard out)
     178              : !> \param el_format the format of a single element
     179              : !> \par History
     180              : !>      4.2002 created [fawzi]
     181              : !> \author Fawzi Mohamed
     182              : !> \note
     183              : !>      maybe I will move to a comma separated parentized list
     184              : ! **************************************************************************************************
     185           70 :       SUBROUTINE cp_2d_${nametype1}$_write(array, unit_nr, el_format)
     186              :          ${type1}$, INTENT(in) :: array(:, :)
     187              :          INTEGER, INTENT(in) :: unit_nr
     188              :          CHARACTER(len=*), INTENT(in), OPTIONAL :: el_format
     189              : 
     190              :          INTEGER :: iostat, i
     191              :          CHARACTER(len=*), PARAMETER :: defaultFormat = ${defaultFormatType1}$
     192              :          CHARACTER(len=200) :: fmtstr
     193              :          CHARACTER(len=25) :: nRiga
     194              : 
     195           70 :          nRiga = cp_to_string(SIZE(array, 2))
     196          206 :          DO i = 1, SIZE(array, 1)
     197          136 :             IF (PRESENT(el_format)) THEN
     198            0 :                fmtstr = '(" ",'//nRiga//el_format//')'
     199            0 :                WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
     200              :             ELSE
     201          136 :                fmtstr = '(" ",'//nRiga//defaultFormat//')'
     202          136 :                WRITE (unit=unit_nr, fmt=fmtstr, iostat=iostat) array(i, :)
     203              :             END IF
     204          206 :             CPASSERT(iostat == 0)
     205              :          END DO
     206           70 :          call m_flush(unit_nr)
     207           70 :       END SUBROUTINE cp_2d_${nametype1}$_write
     208              : 
     209              : ! **************************************************************************************************
     210              : !> \brief If the size of the array is changes reallocate it.
     211              : !>      Issues a warning when the size changes (but not on allocation
     212              : !>      and deallocation).
     213              : !>
     214              : !>      The data is NOT preserved (if you want to preserve the data see
     215              : !>      the realloc in the module memory_utilities)
     216              : !> \param array the array to reallocate if necessary
     217              : !> \param n the wanted size
     218              : !> \par History
     219              : !>      12.2001 first version [fawzi]
     220              : !>      3.2002 templatized [fawzi]
     221              : !> \author Fawzi Mohamed
     222              : !> \note
     223              : !>      this is a different behaviour than the realloc in the module
     224              : !>      memory_utilities. It is quite low level
     225              : ! **************************************************************************************************
     226            0 :       SUBROUTINE cp_1d_${nametype1}$_guarantee_size(array, n)
     227              :          ${type1}$, POINTER :: array(:)
     228              :          INTEGER, INTENT(in) :: n
     229              : 
     230            0 :          CPASSERT(n >= 0)
     231            0 :          IF (ASSOCIATED(array)) THEN
     232            0 :             IF (SIZE(array) /= n) THEN
     233            0 :                CPWARN('size has changed')
     234            0 :                DEALLOCATE (array)
     235              :             END IF
     236              :          END IF
     237            0 :          IF (.NOT. ASSOCIATED(array)) THEN
     238            0 :             ALLOCATE (array(n))
     239              :          END IF
     240            0 :       END SUBROUTINE cp_1d_${nametype1}$_guarantee_size
     241              : 
     242              : ! **************************************************************************************************
     243              : !> \brief If the size of the array is changes reallocate it.
     244              : !>      Issues a warning when the size changes (but not on allocation
     245              : !>      and deallocation).
     246              : !>
     247              : !>      The data is NOT preserved (if you want to preserve the data see
     248              : !>      the realloc in the module memory_utilities)
     249              : !> \param array the array to reallocate if necessary
     250              : !> \param n_rows the wanted number of rows
     251              : !> \param n_cols the wanted number of cols
     252              : !> \par History
     253              : !>      5.2001 first version [fawzi]
     254              : !> \author Fawzi Mohamed
     255              : !> \note
     256              : !>      this is a different behaviour than the realloc in the module
     257              : !>      memory_utilities. It is quite low level
     258              : ! **************************************************************************************************
     259            0 :       SUBROUTINE cp_2d_${nametype1}$_guarantee_size(array, n_rows, n_cols)
     260              :          ${type1}$, POINTER :: array(:, :)
     261              :          INTEGER, INTENT(in) :: n_rows, n_cols
     262              : 
     263            0 :          CPASSERT(n_cols >= 0)
     264            0 :          CPASSERT(n_rows >= 0)
     265            0 :          IF (ASSOCIATED(array)) THEN
     266            0 :             IF (SIZE(array, 1) /= n_rows .OR. SIZE(array, 2) /= n_cols) THEN
     267            0 :                CPWARN('size has changed')
     268            0 :                DEALLOCATE (array)
     269              :             END IF
     270              :          END IF
     271            0 :          IF (.NOT. ASSOCIATED(array)) THEN
     272            0 :             ALLOCATE (array(n_rows, n_cols))
     273              :          END IF
     274            0 :       END SUBROUTINE cp_2d_${nametype1}$_guarantee_size
     275              : 
     276              : ! **************************************************************************************************
     277              : !> \brief returns the index at which the element el should be inserted in the
     278              : !>      array to keep it ordered (array(i)>=el).
     279              : !>      If the element is bigger than all the elements in the array returns
     280              : !>      the last index+1.
     281              : !> \param array the array to search
     282              : !> \param el the element to look for
     283              : !> \param l_index the lower index for binary search (defaults to 1)
     284              : !> \param u_index the upper index for binary search (defaults to size(array))
     285              : !> \return ...
     286              : !> \par History
     287              : !>      06.2003 created [fawzi]
     288              : !> \author Fawzi Mohamed
     289              : !> \note
     290              : !>      the array should be ordered in growing order
     291              : ! **************************************************************************************************
     292            0 :       FUNCTION cp_1d_${nametype1}$_bsearch(array, el, l_index, u_index) &
     293              :          result(res)
     294              :          ${type1}$, intent(in) :: array(:)
     295              :          ${type1}$, intent(in) :: el
     296              :          INTEGER, INTENT(in), OPTIONAL :: l_index, u_index
     297              :          integer :: res
     298              : 
     299              :          INTEGER :: lindex, uindex, aindex
     300              : 
     301            0 :          lindex = 1
     302            0 :          uindex = size(array)
     303            0 :          if (present(l_index)) lindex = l_index
     304            0 :          if (present(u_index)) uindex = u_index
     305            0 :          DO WHILE (lindex <= uindex)
     306            0 :             aindex = (lindex + uindex)/2
     307            0 :             IF (@{lessQ(array(aindex),el)}@) THEN
     308            0 :                lindex = aindex + 1
     309              :             ELSE
     310            0 :                uindex = aindex - 1
     311              :             END IF
     312              :          END DO
     313            0 :          res = lindex
     314            0 :       END FUNCTION cp_1d_${nametype1}$_bsearch
     315              :    #:endfor
     316              : 
     317            0 : END MODULE cp_array_utils
        

Generated by: LCOV version 2.0-1