LCOV - code coverage report
Current view: top level - src/input - input_enumeration_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 62 77 80.5 %
Date: 2024-12-21 06:28:57 Functions: 5 7 71.4 %

          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             : ! **************************************************************************************************
       9             : !> \brief represents an enumeration, i.e. a mapping between integers and strings
      10             : !> \par History
      11             : !>      08.2004 created [fawzi]
      12             : !> \author fawzi
      13             : ! **************************************************************************************************
      14             : MODULE input_enumeration_types
      15             : 
      16             :    USE cp_log_handling,                 ONLY: cp_to_string
      17             :    USE kinds,                           ONLY: default_string_length
      18             :    USE string_utilities,                ONLY: a2s,&
      19             :                                               uppercase
      20             : #include "../base/base_uses.f90"
      21             : 
      22             :    IMPLICIT NONE
      23             :    PRIVATE
      24             : 
      25             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      26             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_enumeration_types'
      27             : 
      28             :    PUBLIC :: enumeration_type
      29             :    PUBLIC :: enum_create, enum_retain, enum_release, enum_i2c, enum_c2i
      30             : 
      31             : ! **************************************************************************************************
      32             : !> \brief represents an enumaration, i.e. a mapping between strings and numbers
      33             : !> \param ref_count reference count
      34             : !> \param c_vals string values
      35             : !> \param i_vals integer values
      36             : !> \param strict if integer values not in the list should be accepted
      37             : !> \author fawzi
      38             : ! **************************************************************************************************
      39             :    TYPE char_array
      40             :       CHARACTER, DIMENSION(:), POINTER :: chars => Null()
      41             :    END TYPE char_array
      42             : 
      43             :    TYPE enumeration_type
      44             :       INTEGER :: ref_count = 0
      45             :       CHARACTER(len=default_string_length), DIMENSION(:), POINTER :: c_vals => NULL()
      46             :       TYPE(char_array), DIMENSION(:), POINTER :: desc => Null()
      47             :       INTEGER, DIMENSION(:), POINTER :: i_vals => NULL()
      48             :       LOGICAL :: strict = .FALSE.
      49             :    END TYPE enumeration_type
      50             : 
      51             : CONTAINS
      52             : 
      53             : ! **************************************************************************************************
      54             : !> \brief creates an enumeration
      55             : !> \param enum the enumeration to be created
      56             : !> \param c_vals string values
      57             : !> \param i_vals integer values
      58             : !> \param desc ...
      59             : !> \param strict if integer values not in the list should be accepted,
      60             : !>        defaults defaults to true
      61             : !> \author fawzi
      62             : ! **************************************************************************************************
      63    22619422 :    SUBROUTINE enum_create(enum, c_vals, i_vals, desc, strict)
      64             :       TYPE(enumeration_type), POINTER                    :: enum
      65             :       CHARACTER(len=*), DIMENSION(:), INTENT(in)         :: c_vals
      66             :       INTEGER, DIMENSION(:), INTENT(in)                  :: i_vals
      67             :       CHARACTER(len=*), DIMENSION(:), INTENT(in), &
      68             :          OPTIONAL                                        :: desc
      69             :       LOGICAL, INTENT(in), OPTIONAL                      :: strict
      70             : 
      71             :       INTEGER                                            :: i, j, n
      72             : 
      73    22619422 :       CPASSERT(.NOT. ASSOCIATED(enum))
      74    22619422 :       CPASSERT(SIZE(c_vals) == SIZE(i_vals))
      75    22619422 :       ALLOCATE (enum)
      76    22619422 :       enum%ref_count = 1
      77    67858266 :       ALLOCATE (enum%c_vals(SIZE(c_vals)))
      78   126667777 :       DO i = 1, SIZE(enum%c_vals)
      79   104048355 :          CPASSERT(LEN_TRIM(c_vals(i)) > 0)
      80   104048355 :          enum%c_vals(i) = c_vals(i)
      81   126667777 :          CALL uppercase(enum%c_vals(i))
      82             :       END DO
      83    67858266 :       ALLOCATE (enum%i_vals(SIZE(i_vals)))
      84   126667777 :       enum%i_vals = i_vals
      85    22619422 :       enum%strict = .TRUE.
      86    22619422 :       IF (PRESENT(strict)) enum%strict = strict
      87   171906621 :       ALLOCATE (enum%desc(SIZE(c_vals)))
      88    22619422 :       IF (PRESENT(desc)) THEN
      89    14223614 :          CPASSERT(SIZE(enum%desc) == SIZE(desc))
      90    64294150 :          DO i = 1, SIZE(enum%desc)
      91    50070536 :             n = LEN_TRIM(desc(i))
      92   150211608 :             ALLOCATE (enum%desc(i)%chars(n))
      93  2468103822 :             DO j = 1, n
      94  2453880208 :                enum%desc(i)%chars(j) = desc(i) (j:j)
      95             :             END DO
      96             :          END DO
      97             :       ELSE
      98    62373627 :          DO i = 1, SIZE(enum%desc)
      99    53977819 :             ALLOCATE (enum%desc(i)%chars(1))
     100   116351446 :             enum%desc(i)%chars(1:1) = ' '
     101             :          END DO
     102             :       END IF
     103    22619422 :    END SUBROUTINE enum_create
     104             : 
     105             : ! **************************************************************************************************
     106             : !> \brief retains the given enumeration
     107             : !> \param enum the obect to retain
     108             : !> \author fawzi
     109             : ! **************************************************************************************************
     110    29162836 :    SUBROUTINE enum_retain(enum)
     111             :       TYPE(enumeration_type), POINTER                    :: enum
     112             : 
     113    29162836 :       CPASSERT(ASSOCIATED(enum))
     114    29162836 :       CPASSERT(enum%ref_count > 0)
     115    29162836 :       enum%ref_count = enum%ref_count + 1
     116    29162836 :    END SUBROUTINE enum_retain
     117             : 
     118             : ! **************************************************************************************************
     119             : !> \brief releases the given enumeration
     120             : !> \param enum the obect to release
     121             : !> \author fawzi
     122             : ! **************************************************************************************************
     123  1741209420 :    SUBROUTINE enum_release(enum)
     124             :       TYPE(enumeration_type), POINTER                    :: enum
     125             : 
     126             :       INTEGER                                            :: i
     127             : 
     128  1741209420 :       IF (ASSOCIATED(enum)) THEN
     129    51782258 :          CPASSERT(enum%ref_count > 0)
     130    51782258 :          enum%ref_count = enum%ref_count - 1
     131    51782258 :          IF (enum%ref_count == 0) THEN
     132    22619422 :             DEALLOCATE (enum%c_vals)
     133    22619422 :             DEALLOCATE (enum%i_vals)
     134   126667777 :             DO i = 1, SIZE(enum%desc)
     135   126667777 :                DEALLOCATE (enum%desc(i)%chars)
     136             :             END DO
     137    22619422 :             DEALLOCATE (enum%desc)
     138    22619422 :             DEALLOCATE (enum)
     139             :          END IF
     140             :       END IF
     141  1741209420 :       NULLIFY (enum)
     142  1741209420 :    END SUBROUTINE enum_release
     143             : 
     144             : ! **************************************************************************************************
     145             : !> \brief maps an integer to a string
     146             : !> \param enum the enumeration to use for the mapping
     147             : !> \param i the value to map
     148             : !> \return ...
     149             : !> \author fawzi
     150             : ! **************************************************************************************************
     151      160516 :    FUNCTION enum_i2c(enum, i) RESULT(res)
     152             :       TYPE(enumeration_type), POINTER                    :: enum
     153             :       INTEGER, INTENT(in)                                :: i
     154             :       CHARACTER(len=default_string_length)               :: res
     155             : 
     156             :       INTEGER                                            :: j
     157             :       LOGICAL                                            :: found
     158             : 
     159      160516 :       CPASSERT(ASSOCIATED(enum))
     160      160516 :       CPASSERT(enum%ref_count > 0)
     161      160516 :       res = " "
     162      160516 :       found = .FALSE.
     163      500960 :       DO j = 1, SIZE(enum%i_vals)
     164      500960 :          IF (enum%i_vals(j) == i) THEN
     165      160516 :             res = enum%c_vals(j)
     166             :             found = .TRUE.
     167             :             EXIT
     168             :          END IF
     169             :       END DO
     170             :       IF (.NOT. found) THEN
     171           0 :          IF (enum%strict) THEN
     172           0 :             DO j = 1, SIZE(enum%desc)
     173           0 :                PRINT *, TRIM(a2s(enum%desc(j)%chars))
     174           0 :                PRINT *, TRIM(enum%c_vals(j))
     175             :             END DO
     176           0 :             PRINT *, enum%i_vals
     177             :          END IF
     178           0 :          IF (enum%strict) &
     179           0 :             CPABORT("invalid value for enumeration:"//cp_to_string(i))
     180           0 :          res = ADJUSTL(cp_to_string(i))
     181             :       END IF
     182      160516 :    END FUNCTION enum_i2c
     183             : 
     184             : ! **************************************************************************************************
     185             : !> \brief maps a string to an integer
     186             : !> \param enum the enumeration to use for the mapping
     187             : !> \param c the value to map
     188             : !> \return ...
     189             : !> \author fawzi
     190             : ! **************************************************************************************************
     191       94602 :    FUNCTION enum_c2i(enum, c) RESULT(res)
     192             :       TYPE(enumeration_type), POINTER                    :: enum
     193             :       CHARACTER(len=*), INTENT(in)                       :: c
     194             :       INTEGER                                            :: res
     195             : 
     196             :       CHARACTER(len=default_string_length)               :: upc
     197             :       INTEGER                                            :: iostat, j
     198             :       LOGICAL                                            :: found
     199             : 
     200           0 :       CPASSERT(ASSOCIATED(enum))
     201       94602 :       CPASSERT(enum%ref_count > 0)
     202       94602 :       upc = TRIM(ADJUSTL(c)) !MK Ignore leading and trailing blanks
     203       94602 :       CALL uppercase(upc)
     204       94602 :       found = .FALSE.
     205      348444 :       DO j = 1, SIZE(enum%c_vals)
     206      348444 :          IF (enum%c_vals(j) == upc) THEN
     207       94602 :             res = enum%i_vals(j)
     208             :             found = .TRUE.
     209             :             EXIT
     210             :          END IF
     211             :       END DO
     212             : 
     213             :       IF (.NOT. found) THEN
     214           0 :          IF (enum%strict) &
     215           0 :             CPABORT("invalid value for enumeration:"//TRIM(c))
     216           0 :          READ (c, "(i10)", iostat=iostat) res
     217           0 :          IF (iostat /= 0) &
     218           0 :             CPABORT("invalid value for enumeration2:"//TRIM(c))
     219             :       END IF
     220       94602 :    END FUNCTION enum_c2i
     221             : 
     222           0 : END MODULE input_enumeration_types

Generated by: LCOV version 1.15