LCOV - code coverage report
Current view: top level - src/common - cp_array_utils.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 23 64 35.9 %
Date: 2024-11-21 06:45:46 Functions: 2 44 4.5 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 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) .EQ. 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) .EQ. 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=10) :: 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 1.15