LCOV - code coverage report
Current view: top level - src/input - input_section_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:1525b05) Lines: 561 672 83.5 %
Date: 2024-05-23 07:14:14 Functions: 32 40 80.0 %

          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 objects that represent the structure of input sections and the data
      10             : !>      contained in an input section
      11             : !> \par History
      12             : !>      06.2004 created [fawzi]
      13             : !> \author fawzi
      14             : ! **************************************************************************************************
      15             : MODULE input_section_types
      16             : 
      17             :    USE cp_linked_list_input,            ONLY: &
      18             :         cp_sll_val_create, cp_sll_val_dealloc, cp_sll_val_get_el_at, cp_sll_val_get_length, &
      19             :         cp_sll_val_get_rest, cp_sll_val_insert_el_at, cp_sll_val_next, cp_sll_val_p_type, &
      20             :         cp_sll_val_rm_el_at, cp_sll_val_set_el_at, cp_sll_val_type
      21             :    USE cp_log_handling,                 ONLY: cp_to_string
      22             :    USE cp_parser_types,                 ONLY: default_section_character
      23             :    USE input_keyword_types,             ONLY: keyword_describe,&
      24             :                                               keyword_p_type,&
      25             :                                               keyword_release,&
      26             :                                               keyword_retain,&
      27             :                                               keyword_type,&
      28             :                                               keyword_typo_match,&
      29             :                                               write_keyword_xml
      30             :    USE input_val_types,                 ONLY: lchar_t,&
      31             :                                               no_t,&
      32             :                                               val_create,&
      33             :                                               val_duplicate,&
      34             :                                               val_get,&
      35             :                                               val_release,&
      36             :                                               val_type,&
      37             :                                               val_write
      38             :    USE kinds,                           ONLY: default_path_length,&
      39             :                                               default_string_length,&
      40             :                                               dp
      41             :    USE print_messages,                  ONLY: print_message
      42             :    USE reference_manager,               ONLY: get_citation_key
      43             :    USE string_utilities,                ONLY: a2s,&
      44             :                                               substitute_special_xml_tokens,&
      45             :                                               typo_match,&
      46             :                                               uppercase
      47             : #include "../base/base_uses.f90"
      48             : 
      49             :    IMPLICIT NONE
      50             :    PRIVATE
      51             : 
      52             :    LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
      53             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'input_section_types'
      54             : 
      55             :    PUBLIC :: section_type
      56             :    PUBLIC :: section_create, section_release, section_describe, &
      57             :              section_get_subsection, section_get_keyword, &
      58             :              section_add_keyword, section_add_subsection
      59             :    PUBLIC :: section_get_subsection_index, section_get_keyword_index
      60             : 
      61             :    PUBLIC :: section_vals_type
      62             :    PUBLIC :: section_vals_create, section_vals_retain, section_vals_release, &
      63             :              section_vals_get, section_vals_get_subs_vals, section_vals_val_get, section_vals_list_get, &
      64             :              section_vals_write, section_vals_add_values, section_vals_get_subs_vals2, &
      65             :              section_vals_val_set, section_vals_val_unset, section_vals_get_subs_vals3, &
      66             :              section_vals_set_subs_vals, section_vals_duplicate, section_vals_remove_values
      67             :    PUBLIC :: write_section_xml
      68             : 
      69             :    PUBLIC :: section_get_ival, &
      70             :              section_get_ivals, &
      71             :              section_get_rval, &
      72             :              section_get_lval
      73             :    PUBLIC :: section_typo_match, typo_match_section, typo_matching_rank, typo_matching_line
      74             : 
      75             : ! **************************************************************************************************
      76             : !> \brief represent a pointer to a section (to make arrays of pointers)
      77             : !> \param section the pointer to the section
      78             : !> \author fawzi
      79             : ! **************************************************************************************************
      80             :    TYPE section_p_type
      81             :       TYPE(section_type), POINTER :: section => NULL()
      82             :    END TYPE section_p_type
      83             : 
      84             : ! **************************************************************************************************
      85             : !> \brief represent a section of the input file
      86             : !> \note
      87             : !>      - frozen: if the section has been frozen (and no keyword/subsections
      88             : !>        can be added)
      89             : !>      - repeats: if the section can be repeated more than once in the same
      90             : !>        context
      91             : !>      - ref_count: reference count (see doc/ReferenceCounting.html)
      92             : !>      - n_keywords: the number of keywords in this section
      93             : !>      - name: name of the section
      94             : !>      - location where in the source code (file and line) the section is created
      95             : !>      - description: description of the section
      96             : !>      - citations: references to literature associated to this section
      97             : !>      - keywords: array with the keywords of this section (might be
      98             : !>        oversized)
      99             : !>      - subsections: sections contained in this section
     100             : !> \author fawzi
     101             : ! **************************************************************************************************
     102             :    TYPE section_type
     103             :       LOGICAL :: frozen = .FALSE., repeats = .FALSE.
     104             :       INTEGER :: ref_count = 0, n_keywords = 0, n_subsections = 0
     105             :       CHARACTER(len=default_string_length)        :: name = ""
     106             :       CHARACTER(len=default_string_length)        :: location = ""
     107             :       CHARACTER, DIMENSION(:), POINTER              :: description => Null()
     108             :       INTEGER, POINTER, DIMENSION(:)              :: citations => NULL()
     109             :       TYPE(keyword_p_type), DIMENSION(:), POINTER :: keywords => NULL()
     110             :       TYPE(section_p_type), POINTER, DIMENSION(:) :: subsections => NULL()
     111             :    END TYPE section_type
     112             : 
     113             : ! **************************************************************************************************
     114             : !> \brief repesents a pointer to a parsed section (to make arrays of pointers)
     115             : !> \param section_vals the pointer to the parsed section
     116             : !> \author fawzi
     117             : ! **************************************************************************************************
     118             :    TYPE section_vals_p_type
     119             :       TYPE(section_vals_type), POINTER :: section_vals => NULL()
     120             :    END TYPE section_vals_p_type
     121             : 
     122             : ! **************************************************************************************************
     123             : !> \brief stores the values of a section
     124             : !> \author fawzi
     125             : ! **************************************************************************************************
     126             :    TYPE section_vals_type
     127             :       INTEGER :: ref_count = 0
     128             :       INTEGER, POINTER, DIMENSION(:)                     :: ibackup => NULL()
     129             :       TYPE(section_type), POINTER                         :: section => NULL()
     130             :       TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER   :: values => NULL()
     131             :       TYPE(section_vals_p_type), DIMENSION(:, :), POINTER :: subs_vals => NULL()
     132             :    END TYPE section_vals_type
     133             : 
     134             :    TYPE(section_type), POINTER, SAVE                                :: typo_match_section => NULL()
     135             :    INTEGER, PARAMETER                                               :: n_typo_matches = 5
     136             :    INTEGER, DIMENSION(n_typo_matches)                               :: typo_matching_rank = 0
     137             :    CHARACTER(LEN=default_string_length*5), DIMENSION(n_typo_matches):: typo_matching_line = ""
     138             : 
     139             : CONTAINS
     140             : 
     141             : ! **************************************************************************************************
     142             : !> \brief creates a list of keywords
     143             : !> \param section the list to be created
     144             : !> \param location from where in the source code section_create() is called
     145             : !> \param name ...
     146             : !> \param description ...
     147             : !> \param n_keywords hint about the number of keywords, defaults to 10
     148             : !> \param n_subsections a hint about how many sections will be added to this
     149             : !>        structure, defaults to 0
     150             : !> \param repeats if this section can repeat (defaults to false)
     151             : !> \param citations ...
     152             : !> \author fawzi
     153             : ! **************************************************************************************************
     154    70931388 :    SUBROUTINE section_create(section, location, name, description, n_keywords, &
     155     4313146 :                              n_subsections, repeats, citations)
     156             : 
     157             :       TYPE(section_type), POINTER                        :: section
     158             :       CHARACTER(len=*), INTENT(in)                       :: location, name, description
     159             :       INTEGER, INTENT(in), OPTIONAL                      :: n_keywords, n_subsections
     160             :       LOGICAL, INTENT(in), OPTIONAL                      :: repeats
     161             :       INTEGER, DIMENSION(:), INTENT(IN), OPTIONAL        :: citations
     162             : 
     163             :       INTEGER                                            :: i, my_n_keywords, my_n_subsections, n
     164             : 
     165    70931388 :       CPASSERT(.NOT. ASSOCIATED(section))
     166    70931388 :       my_n_keywords = 10
     167    70931388 :       IF (PRESENT(n_keywords)) my_n_keywords = n_keywords
     168    70931388 :       my_n_subsections = 0
     169    70931388 :       IF (PRESENT(n_subsections)) my_n_subsections = n_subsections
     170             : 
     171    70931388 :       ALLOCATE (section)
     172    70931388 :       section%ref_count = 1
     173             : 
     174             :       section%n_keywords = 0
     175             :       section%n_subsections = 0
     176    70931388 :       section%location = location
     177             : 
     178    70931388 :       CPASSERT(LEN_TRIM(name) > 0)
     179    70931388 :       section%name = name
     180    70931388 :       CALL uppercase(section%name)
     181             : 
     182    70931388 :       n = LEN_TRIM(description)
     183   212676672 :       ALLOCATE (section%description(n))
     184  6335237822 :       DO i = 1, n
     185  6335237822 :          section%description(i) = description(i:i)
     186             :       END DO
     187             : 
     188    70931388 :       section%frozen = .FALSE.
     189    70931388 :       section%repeats = .FALSE.
     190    70931388 :       IF (PRESENT(repeats)) section%repeats = repeats
     191             : 
     192    70931388 :       NULLIFY (section%citations)
     193    70931388 :       IF (PRESENT(citations)) THEN
     194    12939438 :          ALLOCATE (section%citations(SIZE(citations)))
     195    12200847 :          section%citations = citations
     196             :       END IF
     197             : 
     198   732690994 :       ALLOCATE (section%keywords(-1:my_n_keywords))
     199   590828218 :       DO i = -1, my_n_keywords
     200   590828218 :          NULLIFY (section%keywords(i)%keyword)
     201             :       END DO
     202             : 
     203   152631644 :       ALLOCATE (section%subsections(my_n_subsections))
     204    77861970 :       DO i = 1, my_n_subsections
     205    77861970 :          NULLIFY (section%subsections(i)%section)
     206             :       END DO
     207             : 
     208    70931388 :    END SUBROUTINE section_create
     209             : 
     210             : ! **************************************************************************************************
     211             : !> \brief retains the given keyword list (see doc/ReferenceCounting.html)
     212             : !> \param section the list to retain
     213             : !> \author fawzi
     214             : ! **************************************************************************************************
     215   152418824 :    SUBROUTINE section_retain(section)
     216             : 
     217             :       TYPE(section_type), POINTER                        :: section
     218             : 
     219   152418824 :       CPASSERT(ASSOCIATED(section))
     220   152418824 :       CPASSERT(section%ref_count > 0)
     221   152418824 :       section%ref_count = section%ref_count + 1
     222             : 
     223   152418824 :    END SUBROUTINE section_retain
     224             : 
     225             : ! **************************************************************************************************
     226             : !> \brief releases the given keyword list (see doc/ReferenceCounting.html)
     227             : !> \param section the list to release
     228             : !> \author fawzi
     229             : ! **************************************************************************************************
     230   308949359 :    RECURSIVE SUBROUTINE section_release(section)
     231             : 
     232             :       TYPE(section_type), POINTER                        :: section
     233             : 
     234             :       INTEGER                                            :: i
     235             : 
     236   308949359 :       IF (ASSOCIATED(section)) THEN
     237   223350212 :          CPASSERT(section%ref_count > 0)
     238   223350212 :          section%ref_count = section%ref_count - 1
     239   223350212 :          IF (section%ref_count == 0) THEN
     240    70931388 :             IF (ASSOCIATED(section%citations)) THEN
     241     4313146 :                DEALLOCATE (section%citations)
     242             :             END IF
     243    70931388 :             IF (ASSOCIATED(section%keywords)) THEN
     244   921243726 :                DO i = -1, UBOUND(section%keywords, 1)
     245   850312338 :                   CALL keyword_release(section%keywords(i)%keyword)
     246             :                END DO
     247    70931388 :                DEALLOCATE (section%keywords)
     248             :             END IF
     249    70931388 :             section%n_keywords = 0
     250    70931388 :             IF (ASSOCIATED(section%subsections)) THEN
     251   227397560 :                DO i = 1, SIZE(section%subsections)
     252   227397560 :                   CALL section_release(section%subsections(i)%section)
     253             :                END DO
     254    70931388 :                DEALLOCATE (section%subsections)
     255             :             END IF
     256    70931388 :             DEALLOCATE (section%description)
     257    70931388 :             DEALLOCATE (section)
     258             :          END IF
     259   223350212 :          NULLIFY (section)
     260             :       END IF
     261             : 
     262   308949359 :    END SUBROUTINE section_release
     263             : 
     264             : ! **************************************************************************************************
     265             : !> \brief collects additional information on the section for IO + documentation
     266             : !> \param section ...
     267             : !> \return ...
     268             : !> \author fawzi
     269             : ! **************************************************************************************************
     270           1 :    FUNCTION get_section_info(section) RESULT(message)
     271             : 
     272             :       TYPE(section_type), INTENT(IN)                     :: section
     273             :       CHARACTER(LEN=default_path_length)                 :: message
     274             : 
     275             :       INTEGER                                            :: length
     276             : 
     277           1 :       message = " "
     278           1 :       length = LEN_TRIM(a2s(section%description))
     279           1 :       IF (length > 0) THEN
     280           1 :          IF (section%description(length) /= ".") THEN
     281           0 :             message = "."
     282             :          END IF
     283             :       END IF
     284           1 :       IF (section%repeats) THEN
     285           0 :          message = TRIM(message)//" This section can be repeated."
     286             :       ELSE
     287           1 :          message = TRIM(message)//" This section can not be repeated."
     288             :       END IF
     289             : 
     290           1 :    END FUNCTION get_section_info
     291             : 
     292             : ! **************************************************************************************************
     293             : !> \brief prints a description of the given section
     294             : !> \param section the section to describe
     295             : !> \param unit_nr the unit to write to
     296             : !> \param level the level of output: 0: just section name, 1:keywords,
     297             : !>        then see keyword_describe :-)
     298             : !> \param hide_root if the name of the first section should be hidden
     299             : !>        (defaults to false).
     300             : !> \param recurse ...
     301             : !> \author fawzi
     302             : ! **************************************************************************************************
     303           2 :    RECURSIVE SUBROUTINE section_describe(section, unit_nr, level, hide_root, recurse)
     304             : 
     305             :       TYPE(section_type), INTENT(IN), POINTER            :: section
     306             :       INTEGER, INTENT(in)                                :: unit_nr, level
     307             :       LOGICAL, INTENT(in), OPTIONAL                      :: hide_root
     308             :       INTEGER, INTENT(in), OPTIONAL                      :: recurse
     309             : 
     310             :       CHARACTER(LEN=default_path_length)                 :: message
     311             :       INTEGER                                            :: ikeyword, isub, my_recurse
     312             :       LOGICAL                                            :: my_hide_root
     313             : 
     314           2 :       IF (unit_nr > 0) THEN
     315           1 :          my_hide_root = .FALSE.
     316           1 :          IF (PRESENT(hide_root)) my_hide_root = hide_root
     317           1 :          my_recurse = 0
     318           1 :          IF (PRESENT(recurse)) my_recurse = recurse
     319           1 :          IF (ASSOCIATED(section)) THEN
     320           1 :             CPASSERT(section%ref_count > 0)
     321             : 
     322           1 :             IF (.NOT. my_hide_root) &
     323           1 :                WRITE (UNIT=unit_nr, FMT="('*** section &',A,' ***')") TRIM(ADJUSTL(section%name))
     324           1 :             IF (level > 1) THEN
     325           1 :                message = get_section_info(section)
     326           1 :                CALL print_message(TRIM(a2s(section%description))//TRIM(message), unit_nr, 0, 0, 0)
     327             :             END IF
     328           1 :             IF (level > 0) THEN
     329           1 :                IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN
     330             :                   CALL keyword_describe(section%keywords(-1)%keyword, unit_nr, &
     331           0 :                                         level)
     332             :                END IF
     333           1 :                IF (ASSOCIATED(section%keywords(0)%keyword)) THEN
     334             :                   CALL keyword_describe(section%keywords(0)%keyword, unit_nr, &
     335           0 :                                         level)
     336             :                END IF
     337          20 :                DO ikeyword = 1, section%n_keywords
     338             :                   CALL keyword_describe(section%keywords(ikeyword)%keyword, unit_nr, &
     339          20 :                                         level)
     340             :                END DO
     341             :             END IF
     342           1 :             IF (section%n_subsections > 0 .AND. my_recurse >= 0) THEN
     343           1 :                IF (.NOT. my_hide_root) &
     344           1 :                   WRITE (UNIT=unit_nr, FMT="('** subsections **')")
     345          15 :                DO isub = 1, section%n_subsections
     346          15 :                   IF (my_recurse > 0) THEN
     347             :                      CALL section_describe(section%subsections(isub)%section, unit_nr, &
     348           0 :                                            level, recurse=my_recurse - 1)
     349             :                   ELSE
     350          14 :                      WRITE (UNIT=unit_nr, FMT="(1X,A)") section%subsections(isub)%section%name
     351             :                   END IF
     352             :                END DO
     353             :             END IF
     354           1 :             IF (.NOT. my_hide_root) &
     355           1 :                WRITE (UNIT=unit_nr, FMT="('*** &end section ',A,' ***')") TRIM(ADJUSTL(section%name))
     356             :          ELSE
     357           0 :             WRITE (unit_nr, "(a)") '<section *null*>'
     358             :          END IF
     359             :       END IF
     360             : 
     361           2 :    END SUBROUTINE section_describe
     362             : 
     363             : ! **************************************************************************************************
     364             : !> \brief returns the index of requested subsection (-1 if not found)
     365             : !> \param section the root section
     366             : !> \param subsection_name the name of the subsection you want to get
     367             : !> \return ...
     368             : !> \author fawzi
     369             : !> \note
     370             : !>      private utility function
     371             : ! **************************************************************************************************
     372    35212726 :    FUNCTION section_get_subsection_index(section, subsection_name) RESULT(res)
     373             : 
     374             :       TYPE(section_type), INTENT(IN)                     :: section
     375             :       CHARACTER(len=*), INTENT(IN)                       :: subsection_name
     376             :       INTEGER                                            :: res
     377             : 
     378             :       CHARACTER(len=default_string_length)               :: upc_name
     379             :       INTEGER                                            :: isub
     380             : 
     381           0 :       CPASSERT(section%ref_count > 0)
     382    35212726 :       res = -1
     383    35212726 :       upc_name = subsection_name
     384    35212726 :       CALL uppercase(upc_name)
     385   276119313 :       DO isub = 1, section%n_subsections
     386   276119204 :          CPASSERT(ASSOCIATED(section%subsections(isub)%section))
     387   276119313 :          IF (section%subsections(isub)%section%name == upc_name) THEN
     388             :             res = isub
     389             :             EXIT
     390             :          END IF
     391             :       END DO
     392             : 
     393    35212726 :    END FUNCTION section_get_subsection_index
     394             : 
     395             : ! **************************************************************************************************
     396             : !> \brief returns the requested subsection
     397             : !> \param section the root section
     398             : !> \param subsection_name the name of the subsection you want to get
     399             : !> \return ...
     400             : !> \author fawzi
     401             : ! **************************************************************************************************
     402         164 :    FUNCTION section_get_subsection(section, subsection_name) RESULT(res)
     403             : 
     404             :       TYPE(section_type), INTENT(IN)                     :: section
     405             :       CHARACTER(len=*), INTENT(IN)                       :: subsection_name
     406             :       TYPE(section_type), POINTER                        :: res
     407             : 
     408             :       INTEGER                                            :: isub
     409             : 
     410         164 :       isub = section_get_subsection_index(section, subsection_name)
     411         164 :       IF (isub > 0) THEN
     412         164 :          res => section%subsections(isub)%section
     413             :       ELSE
     414             :          NULLIFY (res)
     415             :       END IF
     416             : 
     417         164 :    END FUNCTION section_get_subsection
     418             : 
     419             : ! **************************************************************************************************
     420             : !> \brief returns the index of the requested keyword (or -2 if not found)
     421             : !> \param section the section the keyword is in
     422             : !> \param keyword_name the keyword you are interested in
     423             : !> \return ...
     424             : !> \author fawzi
     425             : !> \note
     426             : !>      private utility function
     427             : ! **************************************************************************************************
     428    36444849 :    FUNCTION section_get_keyword_index(section, keyword_name) RESULT(res)
     429             : 
     430             :       TYPE(section_type), INTENT(IN)                     :: section
     431             :       CHARACTER(len=*), INTENT(IN)                       :: keyword_name
     432             :       INTEGER                                            :: res
     433             : 
     434             :       INTEGER                                            :: ik, in
     435             :       CHARACTER(len=default_string_length)               :: upc_name
     436             : 
     437           0 :       CPASSERT(section%ref_count > 0)
     438    36444849 :       CPASSERT(ASSOCIATED(section%keywords))
     439    36444849 :       res = -2
     440    36444849 :       upc_name = keyword_name
     441    36444849 :       CALL uppercase(upc_name)
     442   109334547 :       DO ik = -1, 0
     443   109334547 :          IF (ASSOCIATED(section%keywords(ik)%keyword)) THEN
     444    24154103 :             IF (section%keywords(ik)%keyword%names(1) == upc_name) THEN
     445     8044641 :                res = ik
     446             :             END IF
     447             :          END IF
     448             :       END DO
     449    36444849 :       IF (res == -2) THEN
     450   132314218 :          k_search_loop: DO ik = 1, section%n_keywords
     451   132031552 :             CPASSERT(ASSOCIATED(section%keywords(ik)%keyword))
     452   252893106 :             DO in = 1, SIZE(section%keywords(ik)%keyword%names)
     453   252610440 :                IF (section%keywords(ik)%keyword%names(in) == upc_name) THEN
     454             :                   res = ik
     455             :                   EXIT k_search_loop
     456             :                END IF
     457             :             END DO
     458             :          END DO k_search_loop
     459             :       END IF
     460             : 
     461    36444849 :    END FUNCTION section_get_keyword_index
     462             : 
     463             : ! **************************************************************************************************
     464             : !> \brief returns the requested keyword
     465             : !> \param section the section the keyword is in
     466             : !> \param keyword_name the keyword you are interested in
     467             : !> \return ...
     468             : !> \author fawzi
     469             : ! **************************************************************************************************
     470       50316 :    RECURSIVE FUNCTION section_get_keyword(section, keyword_name) RESULT(res)
     471             : 
     472             :       TYPE(section_type), INTENT(IN)                     :: section
     473             :       CHARACTER(len=*), INTENT(IN)                       :: keyword_name
     474             :       TYPE(keyword_type), POINTER                        :: res
     475             : 
     476             :       INTEGER                                            :: ik, my_index
     477             : 
     478       50316 :       IF (INDEX(keyword_name, "%") /= 0) THEN
     479        1967 :          my_index = INDEX(keyword_name, "%") + 1
     480        1967 :          CPASSERT(ASSOCIATED(section%subsections))
     481       13389 :          DO ik = LBOUND(section%subsections, 1), UBOUND(section%subsections, 1)
     482        9455 :             IF (section%subsections(ik)%section%name == keyword_name(1:my_index - 2)) EXIT
     483             :          END DO
     484        1967 :          CPASSERT(ik <= UBOUND(section%subsections, 1))
     485        1967 :          res => section_get_keyword(section%subsections(ik)%section, keyword_name(my_index:))
     486             :       ELSE
     487       48349 :          ik = section_get_keyword_index(section, keyword_name)
     488       48349 :          IF (ik == -2) THEN
     489             :             NULLIFY (res)
     490             :          ELSE
     491       48349 :             res => section%keywords(ik)%keyword
     492             :          END IF
     493             :       END IF
     494             : 
     495       50316 :    END FUNCTION section_get_keyword
     496             : 
     497             : ! **************************************************************************************************
     498             : !> \brief adds a keyword to the given section
     499             : !> \param section the section to which the keyword should be added
     500             : !> \param keyword the keyword to add
     501             : !> \author fawzi
     502             : ! **************************************************************************************************
     503   524494334 :    SUBROUTINE section_add_keyword(section, keyword)
     504             : 
     505             :       TYPE(section_type), INTENT(INOUT)                  :: section
     506             :       TYPE(keyword_type), INTENT(IN), POINTER            :: keyword
     507             : 
     508             :       INTEGER                                            :: i, j, k
     509   524494334 :       TYPE(keyword_p_type), DIMENSION(:), POINTER        :: new_keywords
     510             : 
     511           0 :       CPASSERT(section%ref_count > 0)
     512   524494334 :       CPASSERT(.NOT. section%frozen)
     513   524494334 :       CPASSERT(ASSOCIATED(keyword))
     514   524494334 :       CPASSERT(keyword%ref_count > 0)
     515   524494334 :       CALL keyword_retain(keyword)
     516   524494334 :       IF (keyword%names(1) == "_SECTION_PARAMETERS_") THEN
     517    53240910 :          CALL keyword_release(section%keywords(-1)%keyword)
     518    53240910 :          section%keywords(-1)%keyword => keyword
     519   471253424 :       ELSE IF (keyword%names(1) == "_DEFAULT_KEYWORD_") THEN
     520     1850070 :          CALL keyword_release(section%keywords(0)%keyword)
     521     1850070 :          section%keywords(0)%keyword => keyword
     522             :       ELSE
     523   949935445 :          DO k = 1, SIZE(keyword%names)
     524  4197284398 :             DO i = 1, section%n_keywords
     525  7082098342 :                DO j = 1, SIZE(section%keywords(i)%keyword%names)
     526  6601566251 :                   IF (keyword%names(k) == section%keywords(i)%keyword%names(j)) THEN
     527             :                      CALL cp_abort(__LOCATION__, &
     528             :                                    "trying to add a keyword with a name ("// &
     529             :                                    TRIM(keyword%names(k))//") that was already used in section " &
     530           0 :                                    //TRIM(section%name))
     531             :                   END IF
     532             :                END DO
     533             :             END DO
     534             :          END DO
     535             : 
     536   938806708 :          IF (UBOUND(section%keywords, 1) == section%n_keywords) THEN
     537   513927234 :             ALLOCATE (new_keywords(-1:section%n_keywords + 10))
     538   202546290 :             DO i = -1, section%n_keywords
     539   202546290 :                new_keywords(i)%keyword => section%keywords(i)%keyword
     540             :             END DO
     541   311380944 :             DO i = section%n_keywords + 1, UBOUND(new_keywords, 1)
     542   285432532 :                NULLIFY (new_keywords(i)%keyword)
     543             :             END DO
     544    25948412 :             DEALLOCATE (section%keywords)
     545    25948412 :             section%keywords => new_keywords
     546             :          END IF
     547   469403354 :          section%n_keywords = section%n_keywords + 1
     548   469403354 :          section%keywords(section%n_keywords)%keyword => keyword
     549             :       END IF
     550             : 
     551   524494334 :    END SUBROUTINE section_add_keyword
     552             : 
     553             : ! **************************************************************************************************
     554             : !> \brief adds a subsection to the given section
     555             : !> \param section to section to which you want to add a subsection
     556             : !> \param subsection the subsection to add
     557             : !> \author fawzi
     558             : ! **************************************************************************************************
     559    70890660 :    SUBROUTINE section_add_subsection(section, subsection)
     560             : 
     561             :       TYPE(section_type), INTENT(INOUT)                  :: section
     562             :       TYPE(section_type), INTENT(IN), POINTER            :: subsection
     563             : 
     564             :       INTEGER                                            :: i
     565    70890660 :       TYPE(section_p_type), DIMENSION(:), POINTER        :: new_subsections
     566             : 
     567           0 :       CPASSERT(section%ref_count > 0)
     568    70890660 :       CPASSERT(ASSOCIATED(subsection))
     569    70890660 :       CPASSERT(subsection%ref_count > 0)
     570    70890660 :       IF (SIZE(section%subsections) < section%n_subsections + 1) THEN
     571  1749776145 :          ALLOCATE (new_subsections(section%n_subsections + 10))
     572  1570333437 :          DO i = 1, section%n_subsections
     573  1570333437 :             new_subsections(i)%section => section%subsections(i)%section
     574             :          END DO
     575   164489149 :          DO i = section%n_subsections + 1, SIZE(new_subsections)
     576   164489149 :             NULLIFY (new_subsections(i)%section)
     577             :          END DO
     578    14953559 :          DEALLOCATE (section%subsections)
     579    14953559 :          section%subsections => new_subsections
     580             :       END IF
     581 15832927957 :       DO i = 1, section%n_subsections
     582 15762037297 :          IF (subsection%name == section%subsections(i)%section%name) &
     583             :             CALL cp_abort(__LOCATION__, &
     584             :                           "trying to add a subsection with a name ("// &
     585             :                           TRIM(subsection%name)//") that was already used in section " &
     586    70890660 :                           //TRIM(section%name))
     587             :       END DO
     588    70890660 :       CALL section_retain(subsection)
     589    70890660 :       section%n_subsections = section%n_subsections + 1
     590    70890660 :       section%subsections(section%n_subsections)%section => subsection
     591             : 
     592    70890660 :    END SUBROUTINE section_add_subsection
     593             : 
     594             : ! **************************************************************************************************
     595             : !> \brief creates a object where to store the values of a section
     596             : !> \param section_vals the parsed section that will be created
     597             : !> \param section the structure of the section that you want to parse
     598             : !> \author fawzi
     599             : ! **************************************************************************************************
     600    81528164 :    RECURSIVE SUBROUTINE section_vals_create(section_vals, section)
     601             : 
     602             :       TYPE(section_vals_type), POINTER                   :: section_vals
     603             :       TYPE(section_type), POINTER                        :: section
     604             : 
     605             :       INTEGER                                            :: i
     606             : 
     607    81528164 :       CPASSERT(.NOT. ASSOCIATED(section_vals))
     608    81528164 :       ALLOCATE (section_vals)
     609    81528164 :       section_vals%ref_count = 1
     610    81528164 :       CALL section_retain(section)
     611    81528164 :       section_vals%section => section
     612    81528164 :       section%frozen = .TRUE.
     613   163056328 :       ALLOCATE (section_vals%values(-1:section%n_keywords, 0))
     614   338340838 :       ALLOCATE (section_vals%subs_vals(section%n_subsections, 1))
     615   162989850 :       DO i = 1, section%n_subsections
     616    81461686 :          NULLIFY (section_vals%subs_vals(i, 1)%section_vals)
     617             :          CALL section_vals_create(section_vals%subs_vals(i, 1)%section_vals, &
     618   162989850 :                                   section=section%subsections(i)%section)
     619             :       END DO
     620             : 
     621    81528164 :       NULLIFY (section_vals%ibackup)
     622             : 
     623    81528164 :    END SUBROUTINE section_vals_create
     624             : 
     625             : ! **************************************************************************************************
     626             : !> \brief retains the given section values (see doc/ReferenceCounting.html)
     627             : !> \param section_vals the object to retain
     628             : !> \author fawzi
     629             : ! **************************************************************************************************
     630       73633 :    SUBROUTINE section_vals_retain(section_vals)
     631             : 
     632             :       TYPE(section_vals_type), POINTER                   :: section_vals
     633             : 
     634       73633 :       CPASSERT(ASSOCIATED(section_vals))
     635       73633 :       CPASSERT(section_vals%ref_count > 0)
     636       73633 :       section_vals%ref_count = section_vals%ref_count + 1
     637             : 
     638       73633 :    END SUBROUTINE section_vals_retain
     639             : 
     640             : ! **************************************************************************************************
     641             : !> \brief releases the given object
     642             : !> \param section_vals the section_vals to release
     643             : !> \author fawzi
     644             : ! **************************************************************************************************
     645    81615305 :    RECURSIVE SUBROUTINE section_vals_release(section_vals)
     646             : 
     647             :       TYPE(section_vals_type), POINTER                   :: section_vals
     648             : 
     649             :       INTEGER                                            :: i, j
     650             :       TYPE(cp_sll_val_type), POINTER                     :: vals
     651             :       TYPE(val_type), POINTER                            :: el
     652             : 
     653    81615305 :       IF (ASSOCIATED(section_vals)) THEN
     654    81601797 :          CPASSERT(section_vals%ref_count > 0)
     655    81601797 :          section_vals%ref_count = section_vals%ref_count - 1
     656    81601797 :          IF (section_vals%ref_count == 0) THEN
     657    81528164 :             CALL section_release(section_vals%section)
     658    81788490 :             DO j = 1, SIZE(section_vals%values, 2)
     659    85135245 :                DO i = -1, UBOUND(section_vals%values, 1)
     660     3086429 :                   vals => section_vals%values(i, j)%list
     661     3927281 :                   DO WHILE (cp_sll_val_next(vals, el_att=el))
     662      840852 :                      CALL val_release(el)
     663             :                   END DO
     664     3346755 :                   CALL cp_sll_val_dealloc(section_vals%values(i, j)%list)
     665             :                END DO
     666             :             END DO
     667    81528164 :             DEALLOCATE (section_vals%values)
     668   163078692 :             DO j = 1, SIZE(section_vals%subs_vals, 2)
     669   244595834 :                DO i = 1, SIZE(section_vals%subs_vals, 1)
     670   163067670 :                   CALL section_vals_release(section_vals%subs_vals(i, j)%section_vals)
     671             :                END DO
     672             :             END DO
     673    81528164 :             DEALLOCATE (section_vals%subs_vals)
     674    81528164 :             IF (ASSOCIATED(section_vals%ibackup)) THEN
     675        3758 :                DEALLOCATE (section_vals%ibackup)
     676             :             END IF
     677    81528164 :             DEALLOCATE (section_vals)
     678             :          END IF
     679             :       END IF
     680             : 
     681    81615305 :    END SUBROUTINE section_vals_release
     682             : 
     683             : ! **************************************************************************************************
     684             : !> \brief returns various attributes about the section_vals
     685             : !> \param section_vals the section vals you want information from
     686             : !> \param ref_count ...
     687             : !> \param n_repetition number of repetitions of the section
     688             : !> \param n_subs_vals_rep number of repetitions of the subsections values
     689             : !>        (max(1,n_repetition))
     690             : !> \param section ...
     691             : !> \param explicit if the section was explicitly present in
     692             : !> \author fawzi
     693             : !> \note     For the other arguments see the attributes of section_vals_type
     694             : ! **************************************************************************************************
     695     4197887 :    SUBROUTINE section_vals_get(section_vals, ref_count, n_repetition, &
     696             :                                n_subs_vals_rep, section, explicit)
     697             : 
     698             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     699             :       INTEGER, INTENT(out), OPTIONAL                     :: ref_count, n_repetition, n_subs_vals_rep
     700             :       TYPE(section_type), OPTIONAL, POINTER              :: section
     701             :       LOGICAL, INTENT(out), OPTIONAL                     :: explicit
     702             : 
     703     4197887 :       CPASSERT(section_vals%ref_count > 0)
     704     4197887 :       IF (PRESENT(ref_count)) ref_count = section_vals%ref_count
     705     4197887 :       IF (PRESENT(section)) section => section_vals%section
     706     4197887 :       IF (PRESENT(n_repetition)) n_repetition = SIZE(section_vals%values, 2)
     707     4197887 :       IF (PRESENT(n_subs_vals_rep)) n_subs_vals_rep = SIZE(section_vals%subs_vals, 2)
     708     4197887 :       IF (PRESENT(explicit)) explicit = (SIZE(section_vals%values, 2) > 0)
     709             : 
     710     4197887 :    END SUBROUTINE section_vals_get
     711             : 
     712             : ! **************************************************************************************************
     713             : !> \brief returns the values of the requested subsection
     714             : !> \param section_vals the root section
     715             : !> \param subsection_name the name of the requested subsection
     716             : !> \param i_rep_section index of the repetition of section_vals from which
     717             : !>        you want to extract the subsection (defaults to 1)
     718             : !> \param can_return_null if the results can be null (defaults to false)
     719             : !> \return ...
     720             : !> \author fawzi
     721             : ! **************************************************************************************************
     722    34910634 :    RECURSIVE FUNCTION section_vals_get_subs_vals(section_vals, subsection_name, &
     723             :                                                  i_rep_section, can_return_null) RESULT(res)
     724             : 
     725             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     726             :       CHARACTER(len=*), INTENT(IN)                       :: subsection_name
     727             :       INTEGER, INTENT(IN), OPTIONAL                      :: i_rep_section
     728             :       LOGICAL, INTENT(IN), OPTIONAL                      :: can_return_null
     729             :       TYPE(section_vals_type), POINTER                   :: res
     730             : 
     731             :       INTEGER                                            :: irep, isection, my_index
     732             :       LOGICAL                                            :: is_path, my_can_return_null
     733             : 
     734    34910634 :       CPASSERT(section_vals%ref_count > 0)
     735             : 
     736    34910634 :       my_can_return_null = .FALSE.
     737    34910634 :       IF (PRESENT(can_return_null)) my_can_return_null = can_return_null
     738    34910634 :       NULLIFY (res)
     739    34910634 :       irep = 1
     740    34910634 :       IF (PRESENT(i_rep_section)) irep = i_rep_section
     741             : 
     742             :       ! prepare for recursive parsing of subsections. i_rep_section will be used for last section
     743    34910634 :       my_index = INDEX(subsection_name, "%")
     744    34910634 :       IF (my_index .EQ. 0) THEN
     745    20490930 :          is_path = .FALSE.
     746    20490930 :          my_index = LEN_TRIM(subsection_name)
     747             :       ELSE
     748    14419704 :          is_path = .TRUE.
     749    14419704 :          irep = 1
     750    14419704 :          my_index = my_index - 1
     751             :       END IF
     752             : 
     753    34910634 :       CPASSERT(irep <= SIZE(section_vals%subs_vals, 2))
     754             : 
     755    34910634 :       isection = section_get_subsection_index(section_vals%section, subsection_name(1:my_index))
     756    34910634 :       IF (isection > 0) res => section_vals%subs_vals(isection, irep)%section_vals
     757    34910634 :       IF (.NOT. (ASSOCIATED(res) .OR. my_can_return_null)) &
     758             :          CALL cp_abort(__LOCATION__, &
     759             :                        "could not find subsection "//TRIM(subsection_name(1:my_index))//" in section "// &
     760           0 :                        TRIM(section_vals%section%name)//" at ")
     761    34910634 :       IF (is_path .AND. ASSOCIATED(res)) THEN
     762             :          res => section_vals_get_subs_vals(res, subsection_name(my_index + 2:LEN_TRIM(subsection_name)), &
     763    14419704 :                                            i_rep_section, can_return_null)
     764             :       END IF
     765             : 
     766    34910634 :    END FUNCTION section_vals_get_subs_vals
     767             : 
     768             : ! **************************************************************************************************
     769             : !> \brief returns the values of the n-th non default subsection (null if no
     770             : !>      such section exists (not so many non default section))
     771             : !> \param section_vals the root section
     772             : !> \param i_section index of the section
     773             : !> \param i_rep_section index of the repetition of section_vals from which
     774             : !>        you want to extract the subsection (defaults to 1)
     775             : !> \return ...
     776             : !> \author fawzi
     777             : ! **************************************************************************************************
     778      921549 :    FUNCTION section_vals_get_subs_vals2(section_vals, i_section, i_rep_section) RESULT(res)
     779             : 
     780             :       TYPE(section_vals_type), POINTER                   :: section_vals
     781             :       INTEGER, INTENT(in)                                :: i_section
     782             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section
     783             :       TYPE(section_vals_type), POINTER                   :: res
     784             : 
     785             :       INTEGER                                            :: i, irep, isect_att
     786             : 
     787      921549 :       CPASSERT(ASSOCIATED(section_vals))
     788      921549 :       CPASSERT(section_vals%ref_count > 0)
     789      921549 :       NULLIFY (res)
     790      921549 :       irep = 1
     791      921549 :       IF (PRESENT(i_rep_section)) irep = i_rep_section
     792      921549 :       CPASSERT(irep <= SIZE(section_vals%subs_vals, 2))
     793      921549 :       isect_att = 0
     794   473223100 :       DO i = 1, section_vals%section%n_subsections
     795   473223100 :          IF (SIZE(section_vals%subs_vals(i, irep)%section_vals%values, 2) > 0) THEN
     796     1005669 :             isect_att = isect_att + 1
     797     1005669 :             IF (isect_att == i_section) THEN
     798             :                res => section_vals%subs_vals(i, irep)%section_vals
     799             :                EXIT
     800             :             END IF
     801             :          END IF
     802             :       END DO
     803      921549 :    END FUNCTION section_vals_get_subs_vals2
     804             : 
     805             : ! **************************************************************************************************
     806             : !> \brief returns the values of the n-th non default subsection (null if no
     807             : !>      such section exists (not so many non default section))
     808             : !> \param section_vals the root section
     809             : !> \param subsection_name ...
     810             : !> \param i_rep_section index of the repetition of section_vals from which
     811             : !>        you want to extract the subsection (defaults to 1)
     812             : !> \return ...
     813             : !> \author fawzi
     814             : ! **************************************************************************************************
     815       71120 :    FUNCTION section_vals_get_subs_vals3(section_vals, subsection_name, &
     816             :                                         i_rep_section) RESULT(res)
     817             : 
     818             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     819             :       CHARACTER(LEN=*), INTENT(IN)                       :: subsection_name
     820             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section
     821             :       TYPE(section_vals_type), POINTER                   :: res
     822             : 
     823             :       INTEGER                                            :: i_section, irep
     824             : 
     825       71120 :       CPASSERT(section_vals%ref_count > 0)
     826       71120 :       NULLIFY (res)
     827       71120 :       irep = 1
     828       71120 :       IF (PRESENT(i_rep_section)) irep = i_rep_section
     829       71120 :       CPASSERT(irep <= SIZE(section_vals%subs_vals, 2))
     830       71120 :       i_section = section_get_subsection_index(section_vals%section, subsection_name)
     831       71120 :       res => section_vals%subs_vals(i_section, irep)%section_vals
     832             : 
     833       71120 :    END FUNCTION section_vals_get_subs_vals3
     834             : 
     835             : ! **************************************************************************************************
     836             : !> \brief adds the place to store the values of a repetition of the section
     837             : !> \param section_vals the section you want to extend
     838             : !> \author fawzi
     839             : ! **************************************************************************************************
     840      270046 :    SUBROUTINE section_vals_add_values(section_vals)
     841             : 
     842             :       TYPE(section_vals_type), INTENT(INOUT)             :: section_vals
     843             : 
     844             :       INTEGER                                            :: i, j
     845      270046 :       TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER  :: new_values
     846             :       TYPE(section_vals_p_type), DIMENSION(:, :), &
     847      270046 :          POINTER                                         :: new_sps
     848             : 
     849           0 :       CPASSERT(section_vals%ref_count > 0)
     850     5373473 :       ALLOCATE (new_values(-1:UBOUND(section_vals%values, 1), SIZE(section_vals%values, 2) + 1))
     851      327318 :       DO j = 1, SIZE(section_vals%values, 2)
     852     1185989 :          DO i = -1, UBOUND(section_vals%values, 1)
     853      858671 :             new_values(i, j)%list => section_vals%values(i, j)%list
     854             :          END DO
     855             :       END DO
     856      270046 :       DEALLOCATE (section_vals%values)
     857      270046 :       section_vals%values => new_values
     858      270046 :       j = SIZE(new_values, 2)
     859     3704664 :       DO i = -1, UBOUND(new_values, 1)
     860     3434618 :          NULLIFY (new_values(i, j)%list)
     861             :       END DO
     862             : 
     863      270046 :       IF (SIZE(new_values, 2) > 1) THEN
     864             :          ALLOCATE (new_sps(SIZE(section_vals%subs_vals, 1), &
     865      334422 :                            SIZE(section_vals%subs_vals, 2) + 1))
     866       79636 :          DO j = 1, SIZE(section_vals%subs_vals, 2)
     867      203116 :             DO i = 1, SIZE(section_vals%subs_vals, 1)
     868      180752 :                new_sps(i, j)%section_vals => section_vals%subs_vals(i, j)%section_vals
     869             :             END DO
     870             :          END DO
     871       22364 :          DEALLOCATE (section_vals%subs_vals)
     872       22364 :          section_vals%subs_vals => new_sps
     873       22364 :          j = SIZE(new_sps, 2)
     874       77820 :          DO i = 1, SIZE(new_sps, 1)
     875       55456 :             NULLIFY (new_sps(i, j)%section_vals)
     876             :             CALL section_vals_create(new_sps(i, SIZE(new_sps, 2))%section_vals, &
     877       77820 :                                      section=section_vals%section%subsections(i)%section)
     878             :          END DO
     879             :       END IF
     880             : 
     881      270046 :    END SUBROUTINE section_vals_add_values
     882             : 
     883             : ! **************************************************************************************************
     884             : !> \brief removes the values of a repetition of the section
     885             : !> \param section_vals the section you want to extend
     886             : !> \author fawzi
     887             : ! **************************************************************************************************
     888       68087 :    SUBROUTINE section_vals_remove_values(section_vals)
     889             : 
     890             :       TYPE(section_vals_type), POINTER                   :: section_vals
     891             : 
     892             :       INTEGER                                            :: i, j
     893       68087 :       TYPE(cp_sll_val_p_type), DIMENSION(:, :), POINTER  :: new_values
     894             :       TYPE(cp_sll_val_type), POINTER                     :: vals
     895             :       TYPE(val_type), POINTER                            :: el
     896             : 
     897       68087 :       IF (ASSOCIATED(section_vals)) THEN
     898       68087 :          CPASSERT(section_vals%ref_count > 0)
     899       68087 :          NULLIFY (el, vals)
     900             :          ! Allocate a null 0 dimension array of values
     901      204261 :          ALLOCATE (new_values(-1:section_vals%section%n_keywords, 0))
     902             :          ! Release old values
     903       77807 :          DO j = 1, SIZE(section_vals%values, 2)
     904      165670 :             DO i = -1, UBOUND(section_vals%values, 1)
     905       78143 :                vals => section_vals%values(i, j)%list
     906      667902 :                DO WHILE (cp_sll_val_next(vals, el_att=el))
     907      589759 :                   CALL val_release(el)
     908             :                END DO
     909       87863 :                CALL cp_sll_val_dealloc(section_vals%values(i, j)%list)
     910             :             END DO
     911             :          END DO
     912       68087 :          DEALLOCATE (section_vals%values)
     913       68087 :          section_vals%values => new_values
     914             :       END IF
     915             : 
     916       68087 :    END SUBROUTINE section_vals_remove_values
     917             : 
     918             : ! **************************************************************************************************
     919             : !> \brief ...
     920             : !> \param section_vals ...
     921             : !> \param keyword_name ...
     922             : !> \return ...
     923             : ! **************************************************************************************************
     924           0 :    FUNCTION section_get_cval(section_vals, keyword_name) RESULT(res)
     925             : 
     926             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     927             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
     928             :       CHARACTER(LEN=default_string_length)               :: res
     929             : 
     930           0 :       CALL section_vals_val_get(section_vals, keyword_name, c_val=res)
     931             : 
     932           0 :    END FUNCTION section_get_cval
     933             : 
     934             : ! **************************************************************************************************
     935             : !> \brief ...
     936             : !> \param section_vals ...
     937             : !> \param keyword_name ...
     938             : !> \return ...
     939             : ! **************************************************************************************************
     940      440526 :    FUNCTION section_get_rval(section_vals, keyword_name) RESULT(res)
     941             : 
     942             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     943             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
     944             :       REAL(kind=dp)                                      :: res
     945             : 
     946      440526 :       CALL section_vals_val_get(section_vals, keyword_name, r_val=res)
     947             : 
     948      440526 :    END FUNCTION section_get_rval
     949             : 
     950             : ! **************************************************************************************************
     951             : !> \brief ...
     952             : !> \param section_vals ...
     953             : !> \param keyword_name ...
     954             : !> \return ...
     955             : ! **************************************************************************************************
     956           0 :    FUNCTION section_get_rvals(section_vals, keyword_name) RESULT(res)
     957             : 
     958             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     959             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
     960             :       REAL(kind=dp), DIMENSION(:), POINTER               :: res
     961             : 
     962           0 :       CALL section_vals_val_get(section_vals, keyword_name, r_vals=res)
     963             : 
     964           0 :    END FUNCTION section_get_rvals
     965             : 
     966             : ! **************************************************************************************************
     967             : !> \brief ...
     968             : !> \param section_vals ...
     969             : !> \param keyword_name ...
     970             : !> \return ...
     971             : ! **************************************************************************************************
     972      368618 :    FUNCTION section_get_ival(section_vals, keyword_name) RESULT(res)
     973             : 
     974             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     975             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
     976             :       INTEGER                                            :: res
     977             : 
     978      368618 :       CALL section_vals_val_get(section_vals, keyword_name, i_val=res)
     979             : 
     980      368618 :    END FUNCTION section_get_ival
     981             : 
     982             : ! **************************************************************************************************
     983             : !> \brief ...
     984             : !> \param section_vals ...
     985             : !> \param keyword_name ...
     986             : !> \return ...
     987             : ! **************************************************************************************************
     988        3552 :    FUNCTION section_get_ivals(section_vals, keyword_name) RESULT(res)
     989             : 
     990             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
     991             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
     992             :       INTEGER, DIMENSION(:), POINTER                     :: res
     993             : 
     994        3552 :       CALL section_vals_val_get(section_vals, keyword_name, i_vals=res)
     995             : 
     996        3552 :    END FUNCTION section_get_ivals
     997             : 
     998             : ! **************************************************************************************************
     999             : !> \brief ...
    1000             : !> \param section_vals ...
    1001             : !> \param keyword_name ...
    1002             : !> \return ...
    1003             : ! **************************************************************************************************
    1004       87545 :    FUNCTION section_get_lval(section_vals, keyword_name) RESULT(res)
    1005             : 
    1006             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
    1007             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
    1008             :       LOGICAL                                            :: res
    1009             : 
    1010       87545 :       CALL section_vals_val_get(section_vals, keyword_name, l_val=res)
    1011             : 
    1012       87545 :    END FUNCTION section_get_lval
    1013             : 
    1014             : ! **************************************************************************************************
    1015             : !> \brief returns the requested value
    1016             : !> \param section_vals ...
    1017             : !> \param keyword_name the name of the keyword you want
    1018             : !> \param i_rep_section which repetition of the section you are interested in
    1019             : !>        (defaults to 1)
    1020             : !> \param i_rep_val which repetition of the keyword/val you are interested in
    1021             : !>        (defaults to 1)
    1022             : !> \param n_rep_val returns number of val available
    1023             : !> \param val ...
    1024             : !> \param l_val ,i_val,r_val,c_val: returns the logical,integer,real or
    1025             : !>        character value
    1026             : !> \param i_val ...
    1027             : !> \param r_val ...
    1028             : !> \param c_val ...
    1029             : !> \param l_vals ,i_vals,r_vals,c_vals: returns the logical,integer,real or
    1030             : !>        character arrays. The val reamins the owner of the array
    1031             : !> \param i_vals ...
    1032             : !> \param r_vals ...
    1033             : !> \param c_vals ...
    1034             : !> \param explicit ...
    1035             : !> \author fawzi
    1036             : ! **************************************************************************************************
    1037    35330555 :    SUBROUTINE section_vals_val_get(section_vals, keyword_name, i_rep_section, &
    1038             :                                    i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, &
    1039             :                                    c_vals, explicit)
    1040             : 
    1041             :       TYPE(section_vals_type), INTENT(IN), TARGET        :: section_vals
    1042             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
    1043             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section, i_rep_val
    1044             :       INTEGER, INTENT(out), OPTIONAL                     :: n_rep_val
    1045             :       TYPE(val_type), OPTIONAL, POINTER                  :: val
    1046             :       LOGICAL, INTENT(out), OPTIONAL                     :: l_val
    1047             :       INTEGER, INTENT(out), OPTIONAL                     :: i_val
    1048             :       REAL(KIND=DP), INTENT(out), OPTIONAL               :: r_val
    1049             :       CHARACTER(LEN=*), INTENT(out), OPTIONAL            :: c_val
    1050             :       LOGICAL, DIMENSION(:), OPTIONAL, POINTER           :: l_vals
    1051             :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: i_vals
    1052             :       REAL(KIND=DP), DIMENSION(:), OPTIONAL, POINTER     :: r_vals
    1053             :       CHARACTER(LEN=default_string_length), &
    1054             :          DIMENSION(:), OPTIONAL, POINTER                 :: c_vals
    1055             :       LOGICAL, INTENT(out), OPTIONAL                     :: explicit
    1056             : 
    1057             :       INTEGER                                            :: ik, irk, irs, len_key, my_index, &
    1058             :                                                             tmp_index
    1059             :       LOGICAL                                            :: valRequested
    1060             :       TYPE(cp_sll_val_type), POINTER                     :: vals
    1061             :       TYPE(keyword_type), POINTER                        :: keyword
    1062             :       TYPE(section_type), POINTER                        :: section
    1063             :       TYPE(section_vals_type), POINTER                   :: s_vals
    1064             :       TYPE(val_type), POINTER                            :: my_val
    1065             : 
    1066    35330555 :       CPASSERT(section_vals%ref_count > 0)
    1067             : 
    1068    35330555 :       my_index = INDEX(keyword_name, '%') + 1
    1069    35330555 :       len_key = LEN_TRIM(keyword_name)
    1070    35330555 :       IF (my_index > 1) THEN
    1071     2571266 :          DO
    1072    10430735 :             tmp_index = INDEX(keyword_name(my_index:len_key), "%")
    1073    10430735 :             IF (tmp_index <= 0) EXIT
    1074     2571266 :             my_index = my_index + tmp_index
    1075             :          END DO
    1076     7859469 :          s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
    1077             :       ELSE
    1078             :          s_vals => section_vals
    1079             :       END IF
    1080             : 
    1081    35330555 :       irk = 1
    1082    35330555 :       irs = 1
    1083    35330555 :       IF (PRESENT(i_rep_section)) irs = i_rep_section
    1084    35330555 :       IF (PRESENT(i_rep_val)) irk = i_rep_val
    1085    35330555 :       IF (PRESENT(val)) NULLIFY (val)
    1086    35330555 :       IF (PRESENT(explicit)) explicit = .FALSE.
    1087    35330555 :       section => s_vals%section
    1088             :       valRequested = PRESENT(l_val) .OR. PRESENT(i_val) .OR. PRESENT(r_val) .OR. &
    1089             :                      PRESENT(c_val) .OR. PRESENT(l_vals) .OR. PRESENT(i_vals) .OR. &
    1090    35330555 :                      PRESENT(r_vals) .OR. PRESENT(c_vals)
    1091    35330555 :       ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
    1092    35330555 :       IF (ik == -2) &
    1093             :          CALL cp_abort(__LOCATION__, &
    1094             :                        "section "//TRIM(section%name)//" does not contain keyword "// &
    1095           0 :                        TRIM(keyword_name(my_index:len_key)))
    1096    35330555 :       keyword => section%keywords(ik)%keyword
    1097    35330555 :       IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
    1098             :          CALL cp_abort(__LOCATION__, &
    1099             :                        "section repetition requested ("//cp_to_string(irs)// &
    1100             :                        ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
    1101           0 :                        //")")
    1102    35330555 :       NULLIFY (my_val)
    1103    35330555 :       IF (PRESENT(n_rep_val)) n_rep_val = 0
    1104    35330555 :       IF (irs <= SIZE(s_vals%values, 2)) THEN ! the section was parsed
    1105     9893175 :          vals => s_vals%values(ik, irs)%list
    1106     9893175 :          IF (PRESENT(n_rep_val)) n_rep_val = cp_sll_val_get_length(vals)
    1107     9893175 :          IF (.NOT. ASSOCIATED(vals)) THEN
    1108             :             ! this keyword was not parsed
    1109     6459657 :             IF (ASSOCIATED(keyword%default_value)) THEN
    1110     5990834 :                my_val => keyword%default_value
    1111     5990834 :                IF (PRESENT(n_rep_val)) n_rep_val = 1
    1112             :             END IF
    1113             :          ELSE
    1114             :             my_val => cp_sll_val_get_el_at(s_vals%values(ik, irs)%list, &
    1115     3433518 :                                            irk)
    1116     3433518 :             IF (PRESENT(explicit)) explicit = .TRUE.
    1117             :          END IF
    1118    25437380 :       ELSE IF (ASSOCIATED(keyword%default_value)) THEN
    1119    25419104 :          IF (PRESENT(n_rep_val)) n_rep_val = 1
    1120    25419104 :          my_val => keyword%default_value
    1121             :       END IF
    1122    35330555 :       IF (PRESENT(val)) val => my_val
    1123    35330555 :       IF (valRequested) THEN
    1124    32667829 :          IF (.NOT. ASSOCIATED(my_val)) &
    1125             :             CALL cp_abort(__LOCATION__, &
    1126             :                           "Value requested, but no value set getting value from "// &
    1127             :                           "keyword "//TRIM(keyword_name(my_index:len_key))//" of section "// &
    1128           0 :                           TRIM(section%name))
    1129             :          CALL val_get(my_val, l_val=l_val, i_val=i_val, r_val=r_val, &
    1130             :                       c_val=c_val, l_vals=l_vals, i_vals=i_vals, r_vals=r_vals, &
    1131    96115580 :                       c_vals=c_vals)
    1132             :       END IF
    1133             : 
    1134    35330555 :    END SUBROUTINE section_vals_val_get
    1135             : 
    1136             : ! **************************************************************************************************
    1137             : !> \brief returns the requested list
    1138             : !> \param section_vals ...
    1139             : !> \param keyword_name the name of the keyword you want
    1140             : !> \param i_rep_section which repetition of the section you are interested in
    1141             : !>        (defaults to 1)
    1142             : !> \param list ...
    1143             : !> \author Joost VandeVondele
    1144             : !> \note
    1145             : !>      - most useful if the full list is needed anyway, so that faster iteration can be used
    1146             : ! **************************************************************************************************
    1147        8391 :    SUBROUTINE section_vals_list_get(section_vals, keyword_name, i_rep_section, &
    1148             :                                     list)
    1149             : 
    1150             :       TYPE(section_vals_type), INTENT(IN), POINTER       :: section_vals
    1151             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
    1152             :       INTEGER, OPTIONAL                                  :: i_rep_section
    1153             :       TYPE(cp_sll_val_type), POINTER                     :: list
    1154             : 
    1155             :       INTEGER                                            :: ik, irs, len_key, my_index, tmp_index
    1156             :       TYPE(section_type), POINTER                        :: section
    1157             :       TYPE(section_vals_type), POINTER                   :: s_vals
    1158             : 
    1159        8391 :       CPASSERT(ASSOCIATED(section_vals))
    1160        8391 :       CPASSERT(section_vals%ref_count > 0)
    1161        8391 :       NULLIFY (list)
    1162        8391 :       my_index = INDEX(keyword_name, '%') + 1
    1163        8391 :       len_key = LEN_TRIM(keyword_name)
    1164        8391 :       IF (my_index > 1) THEN
    1165           0 :          DO
    1166           0 :             tmp_index = INDEX(keyword_name(my_index:len_key), "%")
    1167           0 :             IF (tmp_index <= 0) EXIT
    1168           0 :             my_index = my_index + tmp_index
    1169             :          END DO
    1170           0 :          s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
    1171             :       ELSE
    1172        8391 :          s_vals => section_vals
    1173             :       END IF
    1174             : 
    1175        8391 :       irs = 1
    1176        8391 :       IF (PRESENT(i_rep_section)) irs = i_rep_section
    1177        8391 :       section => s_vals%section
    1178        8391 :       ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
    1179        8391 :       IF (ik == -2) &
    1180             :          CALL cp_abort(__LOCATION__, &
    1181             :                        "section "//TRIM(section%name)//" does not contain keyword "// &
    1182           0 :                        TRIM(keyword_name(my_index:len_key)))
    1183        8391 :       IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
    1184             :          CALL cp_abort(__LOCATION__, &
    1185             :                        "section repetition requested ("//cp_to_string(irs)// &
    1186             :                        ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
    1187           0 :                        //")")
    1188        8391 :       list => s_vals%values(ik, irs)%list
    1189             : 
    1190        8391 :    END SUBROUTINE section_vals_list_get
    1191             : 
    1192             : ! **************************************************************************************************
    1193             : !> \brief sets the requested value
    1194             : !> \param section_vals ...
    1195             : !> \param keyword_name the name of the keyword you want (can be a path
    1196             : !>        separated by '%')
    1197             : !> \param i_rep_section isection which repetition of the section you are
    1198             : !>        nterested in (defaults to 1)
    1199             : !> \param i_rep_val which repetition of the keyword/val you are interested in
    1200             : !>        (defaults to 1)
    1201             : !> \param val ...
    1202             : !> \param l_val ,i_val,r_val,c_val: sets the logical,integer,real or
    1203             : !>        character value
    1204             : !> \param i_val ...
    1205             : !> \param r_val ...
    1206             : !> \param c_val ...
    1207             : !> \param l_vals_ptr ,i_vals_ptr,r_vals,c_vals: sets the logical,integer,real or
    1208             : !>        character arrays. The val becomes the owner of the array
    1209             : !> \param i_vals_ptr ...
    1210             : !> \param r_vals_ptr ...
    1211             : !> \param c_vals_ptr ...
    1212             : !> \author fawzi
    1213             : ! **************************************************************************************************
    1214      354499 :    SUBROUTINE section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, &
    1215             :                                    val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
    1216             : 
    1217             :       TYPE(section_vals_type), POINTER                   :: section_vals
    1218             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
    1219             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section, i_rep_val
    1220             :       TYPE(val_type), OPTIONAL, POINTER                  :: val
    1221             :       LOGICAL, INTENT(in), OPTIONAL                      :: l_val
    1222             :       INTEGER, INTENT(in), OPTIONAL                      :: i_val
    1223             :       REAL(KIND=DP), INTENT(in), OPTIONAL                :: r_val
    1224             :       CHARACTER(LEN=*), INTENT(in), OPTIONAL             :: c_val
    1225             :       LOGICAL, DIMENSION(:), OPTIONAL, POINTER           :: l_vals_ptr
    1226             :       INTEGER, DIMENSION(:), OPTIONAL, POINTER           :: i_vals_ptr
    1227             :       REAL(KIND=DP), DIMENSION(:), OPTIONAL, POINTER     :: r_vals_ptr
    1228             :       CHARACTER(LEN=default_string_length), &
    1229             :          DIMENSION(:), OPTIONAL, POINTER                 :: c_vals_ptr
    1230             : 
    1231             :       INTEGER                                            :: ik, irk, irs, len_key, my_index, &
    1232             :                                                             tmp_index
    1233             :       LOGICAL                                            :: valSet
    1234             :       TYPE(cp_sll_val_type), POINTER                     :: vals
    1235             :       TYPE(keyword_type), POINTER                        :: keyword
    1236             :       TYPE(section_type), POINTER                        :: section
    1237             :       TYPE(section_vals_type), POINTER                   :: s_vals
    1238             :       TYPE(val_type), POINTER                            :: my_val, old_val
    1239             : 
    1240      354499 :       CPASSERT(ASSOCIATED(section_vals))
    1241      354499 :       CPASSERT(section_vals%ref_count > 0)
    1242             : 
    1243      354499 :       my_index = INDEX(keyword_name, '%') + 1
    1244      354499 :       len_key = LEN_TRIM(keyword_name)
    1245      354499 :       IF (my_index > 1) THEN
    1246        8010 :          DO
    1247       84969 :             tmp_index = INDEX(keyword_name(my_index:len_key), "%")
    1248       84969 :             IF (tmp_index <= 0) EXIT
    1249        8010 :             my_index = my_index + tmp_index
    1250             :          END DO
    1251       76959 :          s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
    1252             :       ELSE
    1253      277540 :          s_vals => section_vals
    1254             :       END IF
    1255             : 
    1256      354499 :       irk = 1
    1257      354499 :       irs = 1
    1258      354499 :       IF (PRESENT(i_rep_section)) irs = i_rep_section
    1259      354499 :       IF (PRESENT(i_rep_val)) irk = i_rep_val
    1260      354499 :       section => s_vals%section
    1261      354499 :       ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
    1262      354499 :       IF (ik == -2) &
    1263             :          CALL cp_abort(__LOCATION__, &
    1264             :                        "section "//TRIM(section%name)//" does not contain keyword "// &
    1265           0 :                        TRIM(keyword_name(my_index:len_key)))
    1266             :       ! Add values..
    1267       25453 :       DO
    1268      379952 :          IF (irs <= SIZE(s_vals%values, 2)) EXIT
    1269       25453 :          CALL section_vals_add_values(s_vals)
    1270             :       END DO
    1271      354499 :       IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
    1272             :          CALL cp_abort(__LOCATION__, &
    1273             :                        "section repetition requested ("//cp_to_string(irs)// &
    1274             :                        ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
    1275           0 :                        //")")
    1276      354499 :       keyword => s_vals%section%keywords(ik)%keyword
    1277      354499 :       NULLIFY (my_val)
    1278      354499 :       IF (PRESENT(val)) my_val => val
    1279             :       valSet = PRESENT(l_val) .OR. PRESENT(i_val) .OR. PRESENT(r_val) .OR. &
    1280             :                PRESENT(c_val) .OR. PRESENT(l_vals_ptr) .OR. PRESENT(i_vals_ptr) .OR. &
    1281      354499 :                PRESENT(r_vals_ptr) .OR. PRESENT(c_vals_ptr)
    1282      354499 :       IF (ASSOCIATED(my_val)) THEN
    1283             :          ! check better?
    1284           0 :          IF (valSet) &
    1285             :             CALL cp_abort(__LOCATION__, &
    1286             :                           " both val and values present, in setting "// &
    1287             :                           "keyword "//TRIM(keyword_name(my_index:len_key))//" of section "// &
    1288           0 :                           TRIM(section%name))
    1289             :       ELSE
    1290             :          ! ignore ?
    1291      354499 :          IF (.NOT. valSet) &
    1292             :             CALL cp_abort(__LOCATION__, &
    1293             :                           " empty value in setting "// &
    1294             :                           "keyword "//TRIM(keyword_name(my_index:len_key))//" of section "// &
    1295           0 :                           TRIM(section%name))
    1296           0 :          CPASSERT(valSet)
    1297      354499 :          IF (keyword%type_of_var == lchar_t) THEN
    1298      104960 :             CALL val_create(my_val, lc_val=c_val, lc_vals_ptr=c_vals_ptr)
    1299             :          ELSE
    1300             :             CALL val_create(my_val, l_val=l_val, i_val=i_val, r_val=r_val, &
    1301             :                             c_val=c_val, l_vals_ptr=l_vals_ptr, i_vals_ptr=i_vals_ptr, &
    1302             :                             r_vals_ptr=r_vals_ptr, &
    1303      900699 :                             c_vals_ptr=c_vals_ptr, enum=keyword%enum)
    1304             :          END IF
    1305      354499 :          CPASSERT(ASSOCIATED(my_val))
    1306      354499 :          CPASSERT(my_val%type_of_var == keyword%type_of_var)
    1307             :       END IF
    1308      354499 :       vals => s_vals%values(ik, irs)%list
    1309      354499 :       IF (irk == -1) THEN
    1310           0 :          CALL cp_sll_val_insert_el_at(vals, my_val, index=-1)
    1311      354499 :       ELSE IF (irk <= cp_sll_val_get_length(vals)) THEN
    1312      211483 :          IF (irk <= 0) &
    1313             :             CALL cp_abort(__LOCATION__, &
    1314             :                           "invalid irk "//TRIM(ADJUSTL(cp_to_string(irk)))// &
    1315             :                           " in keyword "//TRIM(keyword_name(my_index:len_key))//" of section "// &
    1316           0 :                           TRIM(section%name))
    1317      211483 :          old_val => cp_sll_val_get_el_at(vals, index=irk)
    1318      211483 :          CALL val_release(old_val)
    1319      211483 :          CALL cp_sll_val_set_el_at(vals, value=my_val, index=irk)
    1320      143016 :       ELSE IF (irk > cp_sll_val_get_length(vals) + 1) THEN
    1321             :          ! change?
    1322             :          CALL cp_abort(__LOCATION__, &
    1323             :                        "cannot add extra keyword repetitions to keyword" &
    1324             :                        //TRIM(keyword_name(my_index:len_key))//" of section "// &
    1325           0 :                        TRIM(section%name))
    1326             :       ELSE
    1327      143016 :          CALL cp_sll_val_insert_el_at(vals, my_val, index=irk)
    1328             :       END IF
    1329      354499 :       s_vals%values(ik, irs)%list => vals
    1330             :       NULLIFY (my_val)
    1331      354499 :    END SUBROUTINE section_vals_val_set
    1332             : 
    1333             : ! **************************************************************************************************
    1334             : !> \brief unsets (removes) the requested value (if it is a keyword repetitions
    1335             : !>      removes the repetition, so be careful: the repetition indices bigger
    1336             : !>      than the actual change.
    1337             : !> \param section_vals ...
    1338             : !> \param keyword_name the name of the keyword you want (can be a path
    1339             : !>        separated by '%')
    1340             : !> \param i_rep_section which repetition of the section you are interested in
    1341             : !>        (defaults to 1)
    1342             : !> \param i_rep_val which repetition of the keyword/val you are interested in
    1343             : !>        (defaults to 1)
    1344             : !> \author fawzi
    1345             : ! **************************************************************************************************
    1346       37859 :    SUBROUTINE section_vals_val_unset(section_vals, keyword_name, i_rep_section, i_rep_val)
    1347             : 
    1348             :       TYPE(section_vals_type), POINTER                   :: section_vals
    1349             :       CHARACTER(len=*), INTENT(in)                       :: keyword_name
    1350             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section, i_rep_val
    1351             : 
    1352             :       INTEGER                                            :: ik, irk, irs, len_key, my_index, &
    1353             :                                                             tmp_index
    1354             :       TYPE(cp_sll_val_type), POINTER                     :: pos
    1355             :       TYPE(section_type), POINTER                        :: section
    1356             :       TYPE(section_vals_type), POINTER                   :: s_vals
    1357             :       TYPE(val_type), POINTER                            :: old_val
    1358             : 
    1359       37859 :       NULLIFY (pos)
    1360       37859 :       CPASSERT(ASSOCIATED(section_vals))
    1361       37859 :       CPASSERT(section_vals%ref_count > 0)
    1362             : 
    1363       37859 :       my_index = INDEX(keyword_name, '%') + 1
    1364       37859 :       len_key = LEN_TRIM(keyword_name)
    1365       37859 :       IF (my_index > 1) THEN
    1366         316 :          DO
    1367         688 :             tmp_index = INDEX(keyword_name(my_index:len_key), "%")
    1368         688 :             IF (tmp_index <= 0) EXIT
    1369         316 :             my_index = my_index + tmp_index
    1370             :          END DO
    1371         372 :          s_vals => section_vals_get_subs_vals(section_vals, keyword_name(1:my_index - 2))
    1372             :       ELSE
    1373       37487 :          s_vals => section_vals
    1374             :       END IF
    1375             : 
    1376       37859 :       irk = 1
    1377       37859 :       irs = 1
    1378       37859 :       IF (PRESENT(i_rep_section)) irs = i_rep_section
    1379       37859 :       IF (PRESENT(i_rep_val)) irk = i_rep_val
    1380       37859 :       section => s_vals%section
    1381       37859 :       ik = section_get_keyword_index(s_vals%section, keyword_name(my_index:len_key))
    1382       37859 :       IF (ik == -2) &
    1383             :          CALL cp_abort(__LOCATION__, &
    1384             :                        "section "//TRIM(section%name)//" does not contain keyword "// &
    1385           0 :                        TRIM(keyword_name(my_index:len_key)))
    1386             :       ! ignore unset of non set values
    1387       37859 :       IF (irs <= SIZE(s_vals%values, 2)) THEN
    1388       37859 :          IF (.NOT. (irs > 0 .AND. irs <= SIZE(s_vals%subs_vals, 2))) &
    1389             :             CALL cp_abort(__LOCATION__, &
    1390             :                           "section repetition requested ("//cp_to_string(irs)// &
    1391             :                           ") out of bounds (1:"//cp_to_string(SIZE(s_vals%subs_vals, 2)) &
    1392           0 :                           //")")
    1393       37859 :          IF (irk == -1) THEN
    1394           0 :             pos => cp_sll_val_get_rest(s_vals%values(ik, irs)%list, iter=-1)
    1395             :          ELSE
    1396       37859 :             pos => cp_sll_val_get_rest(s_vals%values(ik, irs)%list, iter=irk - 1)
    1397             :          END IF
    1398       37859 :          IF (ASSOCIATED(pos)) THEN
    1399        7333 :             old_val => cp_sll_val_get_el_at(s_vals%values(ik, irs)%list, index=irk)
    1400        7333 :             CALL val_release(old_val)
    1401        7333 :             CALL cp_sll_val_rm_el_at(s_vals%values(ik, irs)%list, index=irk)
    1402             :          END IF
    1403             :       END IF
    1404             : 
    1405       37859 :    END SUBROUTINE section_vals_val_unset
    1406             : 
    1407             : ! **************************************************************************************************
    1408             : !> \brief writes the values in the given section in a way that is suitable to
    1409             : !>      the automatic parsing
    1410             : !> \param section_vals the section to write out
    1411             : !> \param unit_nr the unit where to write to
    1412             : !> \param hide_root ...
    1413             : !> \param hide_defaults ...
    1414             : !> \author fawzi
    1415             : !> \note
    1416             : !>      skips required sections which weren't read
    1417             : ! **************************************************************************************************
    1418     2346858 :    RECURSIVE SUBROUTINE section_vals_write(section_vals, unit_nr, hide_root, hide_defaults)
    1419             : 
    1420             :       TYPE(section_vals_type), INTENT(IN)                :: section_vals
    1421             :       INTEGER, INTENT(in)                                :: unit_nr
    1422             :       LOGICAL, INTENT(in), OPTIONAL                      :: hide_root, hide_defaults
    1423             : 
    1424             :       INTEGER, PARAMETER                                 :: incr = 2
    1425             : 
    1426             :       CHARACTER(len=default_string_length)               :: myfmt
    1427             :       INTEGER                                            :: i_rep_s, ik, isec, ival, nr, nval
    1428             :       INTEGER, SAVE                                      :: indent = 1
    1429             :       LOGICAL                                            :: defaultSection, explicit, &
    1430             :                                                             my_hide_defaults, my_hide_root
    1431             :       TYPE(cp_sll_val_type), POINTER                     :: new_pos, vals
    1432             :       TYPE(keyword_type), POINTER                        :: keyword
    1433             :       TYPE(section_type), POINTER                        :: section
    1434             :       TYPE(section_vals_type), POINTER                   :: sval
    1435             :       TYPE(val_type), POINTER                            :: val
    1436             : 
    1437     2346858 :       my_hide_root = .FALSE.
    1438     2346858 :       my_hide_defaults = .TRUE.
    1439     2346858 :       IF (PRESENT(hide_root)) my_hide_root = hide_root
    1440     2346858 :       IF (PRESENT(hide_defaults)) my_hide_defaults = hide_defaults
    1441             : 
    1442     2346858 :       CPASSERT(section_vals%ref_count > 0)
    1443     2346858 :       IF (unit_nr > 0) THEN
    1444     2346843 :          CALL section_vals_get(section_vals, explicit=explicit, n_repetition=nr, section=section)
    1445     2346843 :          IF (explicit .OR. (.NOT. my_hide_defaults)) THEN
    1446      574788 :             DO i_rep_s = 1, nr
    1447      291684 :                IF (.NOT. my_hide_root) THEN
    1448      283184 :                   WRITE (UNIT=myfmt, FMT="(I0,A1)") indent, "X"
    1449      283184 :                   IF (ASSOCIATED(section%keywords(-1)%keyword)) THEN
    1450             :                      WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//",A)", ADVANCE="NO") &
    1451       57438 :                         default_section_character//TRIM(ADJUSTL(section%name))
    1452             :                   ELSE
    1453             :                      WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//",A)") &
    1454      225746 :                         default_section_character//TRIM(ADJUSTL(section%name))
    1455             :                   END IF
    1456             :                END IF
    1457      291684 :                defaultSection = (SIZE(section_vals%values, 2) == 0)
    1458      291684 :                IF (.NOT. defaultSection) THEN
    1459      291684 :                   IF (.NOT. my_hide_root) indent = indent + incr
    1460      291684 :                   WRITE (UNIT=myfmt, FMT="(I0,A1)") indent, "X"
    1461     3060544 :                   DO ik = -1, section%n_keywords
    1462     2768860 :                      keyword => section%keywords(ik)%keyword
    1463     3060544 :                      IF (ASSOCIATED(keyword)) THEN
    1464     2273756 :                         IF (keyword%type_of_var /= no_t .AND. keyword%names(1) (1:2) /= "__") THEN
    1465             :                            CALL section_vals_val_get(section_vals, keyword%names(1), &
    1466     2214182 :                                                      i_rep_s, n_rep_val=nval)
    1467     2214182 :                            IF (i_rep_s <= SIZE(section_vals%values, 2)) THEN
    1468             :                               ! Section was parsed
    1469     2214182 :                               vals => section_vals%values(ik, i_rep_s)%list
    1470     5561759 :                               DO ival = 1, nval
    1471     3347577 :                                  IF (ival == 1) THEN
    1472             :                                     new_pos => vals
    1473             :                                  ELSE
    1474     1293130 :                                     new_pos => new_pos%rest
    1475             :                                  END IF
    1476     3347577 :                                  IF (.NOT. ASSOCIATED(new_pos)) THEN
    1477             :                                     ! this keyword was not parsed
    1478     1467909 :                                     IF (ASSOCIATED(keyword%default_value)) THEN
    1479     1467909 :                                        val => keyword%default_value
    1480     1467909 :                                        IF (my_hide_defaults) CYCLE
    1481             :                                     END IF
    1482             :                                  ELSE
    1483     1879668 :                                     val => new_pos%first_el
    1484             :                                  END IF
    1485     1886890 :                                  IF (keyword%names(1) /= '_DEFAULT_KEYWORD_' .AND. &
    1486             :                                      keyword%names(1) /= '_SECTION_PARAMETERS_') THEN
    1487             :                                     WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//",A)", ADVANCE="NO") &
    1488      506747 :                                        TRIM(keyword%names(1))
    1489     1380143 :                                  ELSE IF (keyword%names(1) == '_DEFAULT_KEYWORD_' .AND. &
    1490             :                                           keyword%type_of_var /= lchar_t) THEN
    1491      450459 :                                     WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//")", ADVANCE="NO")
    1492             :                                  END IF
    1493     5561759 :                                  CALL val_write(val, unit_nr=unit_nr, unit=keyword%unit, fmt=myfmt)
    1494             :                               END DO
    1495           0 :                            ELSE IF (ASSOCIATED(keyword%default_value)) THEN
    1496             :                               ! Section was not parsed but default for the keywords may exist
    1497           0 :                               IF (my_hide_defaults) CYCLE
    1498           0 :                               val => keyword%default_value
    1499           0 :                               IF (keyword%names(1) /= '_DEFAULT_KEYWORD_' .AND. &
    1500             :                                   keyword%names(1) /= '_SECTION_PARAMETERS_') THEN
    1501             :                                  WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//",A)", ADVANCE="NO") &
    1502           0 :                                     TRIM(keyword%names(1))
    1503           0 :                               ELSE IF (keyword%names(1) == '_DEFAULT_KEYWORD_' .AND. &
    1504             :                                        keyword%type_of_var /= lchar_t) THEN
    1505           0 :                                  WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//")", ADVANCE="NO")
    1506             :                               END IF
    1507           0 :                               CALL val_write(val, unit_nr=unit_nr, unit=keyword%unit, fmt=myfmt)
    1508             :                            END IF
    1509             :                         END IF
    1510             :                      END IF
    1511             :                   END DO
    1512      291684 :                   IF (ASSOCIATED(section_vals%subs_vals)) THEN
    1513     2630027 :                      DO isec = 1, SIZE(section_vals%subs_vals, 1)
    1514     2338343 :                         sval => section_vals%subs_vals(isec, i_rep_s)%section_vals
    1515     2630027 :                         IF (ASSOCIATED(sval)) THEN
    1516     2338343 :                            CALL section_vals_write(sval, unit_nr=unit_nr, hide_defaults=hide_defaults)
    1517             :                         END IF
    1518             :                      END DO
    1519             :                   END IF
    1520             :                END IF
    1521     2638527 :                IF (.NOT. my_hide_root) THEN
    1522      283184 :                   indent = indent - incr
    1523      283184 :                   WRITE (UNIT=myfmt, FMT="(I0,A1)") indent, "X"
    1524             :                   WRITE (UNIT=unit_nr, FMT="("//TRIM(myfmt)//",A)") &
    1525      283184 :                      default_section_character//"END "//TRIM(ADJUSTL(section%name))
    1526             :                END IF
    1527             :             END DO
    1528             :          END IF
    1529             :       END IF
    1530             : 
    1531     2346858 :    END SUBROUTINE section_vals_write
    1532             : 
    1533             : ! **************************************************************************************************
    1534             : !> \brief writes the values in the given section in xml
    1535             : !> \param section ...
    1536             : !> \param level ...
    1537             : !> \param unit_number ...
    1538             : ! **************************************************************************************************
    1539           0 :    RECURSIVE SUBROUTINE write_section_xml(section, level, unit_number)
    1540             : 
    1541             :       TYPE(section_type), POINTER                        :: section
    1542             :       INTEGER, INTENT(IN)                                :: level, unit_number
    1543             : 
    1544             :       CHARACTER(LEN=3)                                   :: repeats
    1545             :       CHARACTER(LEN=8)                                   :: short_string
    1546             :       INTEGER                                            :: i, l0, l1, l2
    1547             : 
    1548           0 :       IF (ASSOCIATED(section)) THEN
    1549             : 
    1550           0 :          CPASSERT(section%ref_count > 0)
    1551             : 
    1552             :          ! Indentation for current level, next level, etc.
    1553             : 
    1554           0 :          l0 = level
    1555           0 :          l1 = level + 1
    1556           0 :          l2 = level + 2
    1557             : 
    1558           0 :          IF (section%repeats) THEN
    1559           0 :             repeats = "yes"
    1560             :          ELSE
    1561           0 :             repeats = "no "
    1562             :          END IF
    1563             : 
    1564           0 :          WRITE (UNIT=unit_number, FMT="(A)") &
    1565           0 :             REPEAT(" ", l0)//"<SECTION repeats="""//TRIM(repeats)//""">", &
    1566           0 :             REPEAT(" ", l1)//"<NAME>"//TRIM(section%name)//"</NAME>", &
    1567             :             REPEAT(" ", l1)//"<DESCRIPTION>"// &
    1568             :             TRIM(substitute_special_xml_tokens(a2s(section%description))) &
    1569           0 :             //"</DESCRIPTION>"
    1570             : 
    1571           0 :          IF (ASSOCIATED(section%citations)) THEN
    1572           0 :             DO i = 1, SIZE(section%citations, 1)
    1573           0 :                short_string = ""
    1574           0 :                WRITE (UNIT=short_string, FMT="(I8)") section%citations(i)
    1575           0 :                WRITE (UNIT=unit_number, FMT="(A)") &
    1576           0 :                   REPEAT(" ", l1)//"<REFERENCE>", &
    1577           0 :                   REPEAT(" ", l2)//"<NAME>"//TRIM(get_citation_key(section%citations(i)))//"</NAME>", &
    1578           0 :                   REPEAT(" ", l2)//"<NUMBER>"//TRIM(ADJUSTL(short_string))//"</NUMBER>", &
    1579           0 :                   REPEAT(" ", l1)//"</REFERENCE>"
    1580             :             END DO
    1581             :          END IF
    1582             : 
    1583           0 :          WRITE (UNIT=unit_number, FMT="(A)") &
    1584           0 :             REPEAT(" ", l1)//"<LOCATION>"//TRIM(section%location)//"</LOCATION>"
    1585             : 
    1586           0 :          DO i = -1, section%n_keywords
    1587           0 :             IF (ASSOCIATED(section%keywords(i)%keyword)) THEN
    1588           0 :                CALL write_keyword_xml(section%keywords(i)%keyword, l1, unit_number)
    1589             :             END IF
    1590             :          END DO
    1591             : 
    1592           0 :          DO i = 1, section%n_subsections
    1593           0 :             CALL write_section_xml(section%subsections(i)%section, l1, unit_number)
    1594             :          END DO
    1595             : 
    1596           0 :          WRITE (UNIT=unit_number, FMT="(A)") REPEAT(" ", l0)//"</SECTION>"
    1597             : 
    1598             :       END IF
    1599             : 
    1600           0 :    END SUBROUTINE write_section_xml
    1601             : 
    1602             : ! **************************************************************************************************
    1603             : !> \brief ...
    1604             : !> \param section ...
    1605             : !> \param section_name ...
    1606             : !> \param unknown_string ...
    1607             : !> \param location_string ...
    1608             : !> \param matching_rank ...
    1609             : !> \param matching_string ...
    1610             : !> \param bonus ...
    1611             : ! **************************************************************************************************
    1612           0 :    RECURSIVE SUBROUTINE section_typo_match(section, section_name, unknown_string, location_string, &
    1613           0 :                                            matching_rank, matching_string, bonus)
    1614             : 
    1615             :       TYPE(section_type), INTENT(IN), POINTER            :: section
    1616             :       CHARACTER(LEN=*)                                   :: section_name, unknown_string, &
    1617             :                                                             location_string
    1618             :       INTEGER, DIMENSION(:), INTENT(INOUT)               :: matching_rank
    1619             :       CHARACTER(LEN=*), DIMENSION(:), INTENT(INOUT)      :: matching_string
    1620             :       INTEGER, INTENT(IN)                                :: bonus
    1621             : 
    1622           0 :       CHARACTER(LEN=LEN(matching_string(1)))             :: line
    1623             :       INTEGER                                            :: i, imatch, imax, irank, newbonus
    1624             : 
    1625           0 :       IF (ASSOCIATED(section)) THEN
    1626           0 :          CPASSERT(section%ref_count > 0)
    1627           0 :          imatch = typo_match(TRIM(section%name), TRIM(unknown_string))
    1628           0 :          IF (imatch > 0) THEN
    1629           0 :             imatch = imatch + bonus
    1630             :             WRITE (UNIT=line, FMT='(T2,A)') &
    1631             :                " subsection "//TRIM(ADJUSTL(section%name))// &
    1632           0 :                " in section "//TRIM(ADJUSTL(location_string))
    1633           0 :             imax = SIZE(matching_rank, 1)
    1634           0 :             irank = imax + 1
    1635           0 :             DO I = imax, 1, -1
    1636           0 :                IF (imatch > matching_rank(I)) irank = i
    1637             :             END DO
    1638           0 :             IF (irank <= imax) THEN
    1639           0 :                matching_rank(irank + 1:imax) = matching_rank(irank:imax - 1)
    1640           0 :                matching_string(irank + 1:imax) = matching_string(irank:imax - 1)
    1641           0 :                matching_rank(irank) = imatch
    1642           0 :                matching_string(irank) = line
    1643             :             END IF
    1644             :          END IF
    1645             : 
    1646           0 :          IF (section_name == section%name) THEN
    1647           0 :             newbonus = 10
    1648             :          ELSE
    1649           0 :             newbonus = 0
    1650             :          END IF
    1651             : 
    1652           0 :          DO i = -1, section%n_keywords
    1653           0 :             IF (ASSOCIATED(section%keywords(i)%keyword)) THEN
    1654             :                CALL keyword_typo_match(section%keywords(i)%keyword, unknown_string, location_string// &
    1655           0 :                                        "%"//TRIM(section%name), matching_rank, matching_string, newbonus)
    1656             :             END IF
    1657             :          END DO
    1658             : 
    1659           0 :          DO i = 1, section%n_subsections
    1660             :             CALL section_typo_match(section%subsections(i)%section, section_name, unknown_string, &
    1661           0 :                                     location_string//"%"//TRIM(section%name), matching_rank, matching_string, newbonus)
    1662             :          END DO
    1663             : 
    1664             :       END IF
    1665             : 
    1666           0 :    END SUBROUTINE section_typo_match
    1667             : 
    1668             : ! **************************************************************************************************
    1669             : !> \brief replaces of the requested subsection with the one given
    1670             : !> \param section_vals the root section
    1671             : !> \param subsection_name the name of the subsection to replace
    1672             : !> \param new_section_vals the new section_vals to use
    1673             : !> \param i_rep_section index of the repetition of section_vals of which
    1674             : !>        you want to replace the subsection (defaults to 1)
    1675             : !> \author fawzi
    1676             : ! **************************************************************************************************
    1677       16933 :    SUBROUTINE section_vals_set_subs_vals(section_vals, subsection_name, &
    1678             :                                          new_section_vals, i_rep_section)
    1679             :       TYPE(section_vals_type), POINTER                   :: section_vals
    1680             :       CHARACTER(len=*), INTENT(in)                       :: subsection_name
    1681             :       TYPE(section_vals_type), POINTER                   :: new_section_vals
    1682             :       INTEGER, INTENT(in), OPTIONAL                      :: i_rep_section
    1683             : 
    1684             :       INTEGER                                            :: irep, isection, len_key, my_index, &
    1685             :                                                             tmp_index
    1686             :       TYPE(section_vals_type), POINTER                   :: s_vals
    1687             : 
    1688       16933 :       CPASSERT(ASSOCIATED(section_vals))
    1689       16933 :       CPASSERT(section_vals%ref_count > 0)
    1690       16933 :       CPASSERT(ASSOCIATED(new_section_vals))
    1691       16933 :       CPASSERT(new_section_vals%ref_count > 0)
    1692             : 
    1693       16933 :       irep = 1
    1694       16933 :       IF (PRESENT(i_rep_section)) irep = i_rep_section
    1695             : 
    1696       16933 :       my_index = INDEX(subsection_name, '%') + 1
    1697       16933 :       len_key = LEN_TRIM(subsection_name)
    1698       16933 :       IF (my_index > 1) THEN
    1699       18167 :          DO
    1700       33272 :             tmp_index = INDEX(subsection_name(my_index:len_key), "%")
    1701       33272 :             IF (tmp_index <= 0) EXIT
    1702       18167 :             my_index = my_index + tmp_index
    1703             :          END DO
    1704       15105 :          s_vals => section_vals_get_subs_vals(section_vals, subsection_name(1:my_index - 2))
    1705             :       ELSE
    1706        1828 :          s_vals => section_vals
    1707             :       END IF
    1708             : 
    1709       16933 :       CPASSERT(irep <= SIZE(s_vals%subs_vals, 2))
    1710             : 
    1711       16933 :       isection = section_get_subsection_index(s_vals%section, subsection_name(my_index:LEN_TRIM(subsection_name)))
    1712       16933 :       IF (isection <= 0) &
    1713             :          CALL cp_abort(__LOCATION__, &
    1714             :                        "could not find subsection "//subsection_name(my_index:LEN_TRIM(subsection_name))//" in section "// &
    1715           0 :                        TRIM(section_vals%section%name)//" at ")
    1716       16933 :       CALL section_vals_retain(new_section_vals)
    1717       16933 :       CALL section_vals_release(s_vals%subs_vals(isection, irep)%section_vals)
    1718       16933 :       s_vals%subs_vals(isection, irep)%section_vals => new_section_vals
    1719             : 
    1720       16933 :    END SUBROUTINE section_vals_set_subs_vals
    1721             : 
    1722             : ! **************************************************************************************************
    1723             : !> \brief creates a deep copy from section_vals_in to section_vals_out
    1724             : !> \param section_vals_in the section_vals to copy
    1725             : !> \param section_vals_out the section_vals to create
    1726             : !> \param i_rep_start ...
    1727             : !> \param i_rep_end ...
    1728             : !> \author fawzi
    1729             : ! **************************************************************************************************
    1730        1605 :    SUBROUTINE section_vals_duplicate(section_vals_in, section_vals_out, &
    1731             :                                      i_rep_start, i_rep_end)
    1732             :       TYPE(section_vals_type), POINTER                   :: section_vals_in, section_vals_out
    1733             :       INTEGER, INTENT(IN), OPTIONAL                      :: i_rep_start, i_rep_end
    1734             : 
    1735        1605 :       CPASSERT(ASSOCIATED(section_vals_in))
    1736        1605 :       CPASSERT(.NOT. ASSOCIATED(section_vals_out))
    1737        1605 :       CALL section_vals_create(section_vals_out, section_vals_in%section)
    1738        1605 :       CALL section_vals_copy(section_vals_in, section_vals_out, i_rep_start, i_rep_end)
    1739        1605 :    END SUBROUTINE section_vals_duplicate
    1740             : 
    1741             : ! **************************************************************************************************
    1742             : !> \brief deep copy from section_vals_in to section_vals_out
    1743             : !> \param section_vals_in the section_vals to copy
    1744             : !> \param section_vals_out the section_vals where to copy
    1745             : !> \param i_rep_low ...
    1746             : !> \param i_rep_high ...
    1747             : !> \author fawzi
    1748             : !> \note
    1749             : !>      private, only works with a newly initialized section_vals_out
    1750             : ! **************************************************************************************************
    1751     4187635 :    RECURSIVE SUBROUTINE section_vals_copy(section_vals_in, section_vals_out, &
    1752             :                                           i_rep_low, i_rep_high)
    1753             :       TYPE(section_vals_type), POINTER                   :: section_vals_in, section_vals_out
    1754             :       INTEGER, INTENT(IN), OPTIONAL                      :: i_rep_low, i_rep_high
    1755             : 
    1756             :       INTEGER                                            :: iend, irep, isec, istart, ival
    1757             :       TYPE(cp_sll_val_type), POINTER                     :: v1, v2
    1758             :       TYPE(val_type), POINTER                            :: el
    1759             : 
    1760     4187635 :       NULLIFY (v2, el)
    1761             : 
    1762     4187635 :       CPASSERT(ASSOCIATED(section_vals_in))
    1763     4187635 :       CPASSERT(ASSOCIATED(section_vals_out))
    1764             :       !  IF(.NOT. ASSOCIATED(section_vals_in%section, section_vals_out%section))&
    1765             :       !     CPABORT("")
    1766             : 
    1767     4187635 :       istart = 1
    1768     4187635 :       iend = SIZE(section_vals_in%values, 2)
    1769     4187635 :       IF (PRESENT(i_rep_low)) istart = i_rep_low
    1770     4187635 :       IF (PRESENT(i_rep_high)) iend = i_rep_high
    1771     4205488 :       DO irep = istart, iend
    1772       17853 :          CALL section_vals_add_values(section_vals_out)
    1773     4412128 :          DO ival = LBOUND(section_vals_in%values, 1), UBOUND(section_vals_in%values, 1)
    1774      170934 :             v1 => section_vals_in%values(ival, irep)%list
    1775      188787 :             IF (ASSOCIATED(v1)) THEN
    1776       36187 :                CALL val_duplicate(v1%first_el, el)
    1777       36187 :                CALL cp_sll_val_create(v2, el)
    1778       36187 :                NULLIFY (el)
    1779       36187 :                section_vals_out%values(ival, irep - istart + 1)%list => v2
    1780       45920 :                DO
    1781       82107 :                   IF (.NOT. ASSOCIATED(v1%rest)) EXIT
    1782       45920 :                   v1 => v1%rest
    1783       45920 :                   CALL val_duplicate(v1%first_el, el)
    1784       45920 :                   CALL cp_sll_val_create(v2%rest, first_el=el)
    1785       45920 :                   NULLIFY (el)
    1786       45920 :                   v2 => v2%rest
    1787             :                END DO
    1788             :             END IF
    1789             :          END DO
    1790             :       END DO
    1791     4187635 :       IF (.NOT. PRESENT(i_rep_low) .AND. (.NOT. PRESENT(i_rep_high))) THEN
    1792     4187131 :          IF (.NOT. (SIZE(section_vals_in%values, 2) == SIZE(section_vals_out%values, 2))) &
    1793           0 :             CPABORT("")
    1794     4187131 :          IF (.NOT. (SIZE(section_vals_in%subs_vals, 2) == SIZE(section_vals_out%subs_vals, 2))) &
    1795           0 :             CPABORT("")
    1796             :       END IF
    1797     4187635 :       iend = SIZE(section_vals_in%subs_vals, 2)
    1798     4187635 :       IF (PRESENT(i_rep_high)) iend = i_rep_high
    1799     8376399 :       DO irep = istart, iend
    1800    12562429 :          DO isec = 1, SIZE(section_vals_in%subs_vals, 1)
    1801             :             CALL section_vals_copy(section_vals_in%subs_vals(isec, irep)%section_vals, &
    1802     8374794 :                                    section_vals_out%subs_vals(isec, irep - istart + 1)%section_vals)
    1803             :          END DO
    1804             :       END DO
    1805             : 
    1806     4187635 :    END SUBROUTINE section_vals_copy
    1807             : 
    1808           0 : END MODULE input_section_types

Generated by: LCOV version 1.15