From b58489c1c23e674f59b15cd35cee82b105eccc09 Mon Sep 17 00:00:00 2001 From: Martin Diehl Date: Tue, 19 Jun 2018 23:53:14 +0200 Subject: [PATCH] merged all config related data into the config module --- src/CMakeLists.txt | 12 +- src/commercialFEM_fileList.f90 | 1 - src/config.f90 | 462 +++++++++++++++++++++++++++++++- src/linked_list.f90 | 472 --------------------------------- src/material.f90 | 1 - 5 files changed, 464 insertions(+), 484 deletions(-) delete mode 100644 src/linked_list.f90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5cfd30835..9418cd56d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -39,13 +39,9 @@ add_library(DEBUG OBJECT "debug.f90") add_dependencies(DEBUG NUMERICS) list(APPEND OBJECTFILES $) -add_library(CHAINED_LIST OBJECT "linked_list.f90") -add_dependencies(CHAINED_LIST DEBUG) -list(APPEND OBJECTFILES $) - -add_library(CONFIG_MATERIAL OBJECT "config.f90") -add_dependencies(CONFIG_MATERIAL CHAINED_LIST) -list(APPEND OBJECTFILES $) +add_library(CONFIG OBJECT "config.f90") +add_dependencies(CONFIG DEBUG) +list(APPEND OBJECTFILES $) add_library(FEsolving OBJECT "FEsolving.f90") add_dependencies(FEsolving DEBUG) @@ -70,7 +66,7 @@ elseif (PROJECT_NAME STREQUAL "DAMASK_FEM") endif() add_library(MATERIAL OBJECT "material.f90") -add_dependencies(MATERIAL MESH CONFIG_MATERIAL) +add_dependencies(MATERIAL MESH CONFIG) list(APPEND OBJECTFILES $) add_library(DAMASK_HELPERS OBJECT "lattice.f90") diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index 372aeaab4..0d4b55255 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -6,7 +6,6 @@ #include "IO.f90" #include "numerics.f90" #include "debug.f90" -#include "linked_list.f90" #include "config.f90" #include "math.f90" #include "FEsolving.f90" diff --git a/src/config.f90 b/src/config.f90 index 66c2f18bb..3a0099a40 100644 --- a/src/config.f90 +++ b/src/config.f90 @@ -6,13 +6,41 @@ !! parts 'homogenization', 'crystallite', 'phase', 'texture', and 'microstucture' !-------------------------------------------------------------------------------------------------- module config - use linked_list use prec, only: & pReal, & pInt implicit none private + type, private :: tPartitionedString + character(len=:), allocatable :: val + integer(pInt), dimension(:), allocatable :: pos + end type tPartitionedString + + type, public :: tPartitionedStringList + type(tPartitionedString) :: string + type(tPartitionedStringList), pointer :: next => null() + contains + procedure :: add => add + procedure :: show => show + + procedure :: keyExists => exist + procedure :: countKeys => count + + procedure :: getFloat => getFloat + procedure :: getFloats => getFloats + + procedure :: getInt => getInt + procedure :: getInts => getInts + + procedure :: getStringsRaw => strings + procedure :: getString => getString + procedure :: getStrings => getStrings + + end type tPartitionedStringList + + type(tPartitionedStringList), public :: emptyList + type(tPartitionedStringList), public, protected, allocatable, dimension(:) :: & phaseConfig, & microstructureConfig, & @@ -48,7 +76,8 @@ module config MATERIAL_configFile = 'material.config', & !< generic name for material configuration file MATERIAL_localFileExt = 'materialConfig' !< extension of solver job name depending material configuration file - public :: config_init + +public :: config_init contains @@ -202,4 +231,433 @@ subroutine parseFile(line,& end if end subroutine parseFile +!-------------------------------------------------------------------------------------------------- +!> @brief add element +!> @details Adds a string together with the start/end position of chunks in this string. The new +!! element is added at the end of the list. Empty strings are not added. All strings are converted +!! to lower case +!-------------------------------------------------------------------------------------------------- +subroutine add(this,string) + use IO, only: & + IO_isBlank, & + IO_lc, & + IO_stringPos + + implicit none + class(tPartitionedStringList), target, intent(in) :: this + character(len=*), intent(in) :: string + type(tPartitionedStringList), pointer :: new, item + + if (IO_isBlank(string)) return + + allocate(new) + new%string%val = IO_lc (trim(string)) + new%string%pos = IO_stringPos(trim(string)) + + item => this + do while (associated(item%next)) + item => item%next + enddo + item%next => new + +end subroutine add + + +!-------------------------------------------------------------------------------------------------- +!> @brief prints all elements +!> @details Strings are printed in order of insertion (FIFO) +!-------------------------------------------------------------------------------------------------- +subroutine show(this) + + implicit none + class(tPartitionedStringList) :: this + type(tPartitionedStringList), pointer :: item + + item => this%next + do while (associated(item)) + write(6,'(a)') trim(item%string%val) + item => item%next + end do + +end subroutine show + + +!-------------------------------------------------------------------------------------------------- +!> @brief deallocates all elements of a given list +!> @details Strings are printed in order of insertion (FIFO) +!-------------------------------------------------------------------------------------------------- +! subroutine free_all() +! implicit none +! +! type(node), pointer :: item +! +! do +! item => first +! +! if (associated(item) .eqv. .FALSE.) exit +! +! first => first%next +! deallocate(item) +! end do +! end subroutine free_all + + +!-------------------------------------------------------------------------------------------------- +!> @brief reports wether a given key (string value at first position) exists in the list +!-------------------------------------------------------------------------------------------------- +logical function exist(this,key) + use IO, only: & + IO_stringValue + + implicit none + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + type(tPartitionedStringList), pointer :: item + + exist = .false. + + item => this%next + do while (associated(item) .and. .not. exist) + exist = trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key) + item => item%next + end do + +end function exist + + +!-------------------------------------------------------------------------------------------------- +!> @brief count number of key appearances +!> @details traverses list and counts each occurrence of specified key +!-------------------------------------------------------------------------------------------------- +integer(pInt) function count(this,key) + use IO, only: & + IO_stringValue + + implicit none + + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + type(tPartitionedStringList), pointer :: item + + count = 0_pInt + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) & + count = count + 1_pInt + item => item%next + end do + +end function count + + +!-------------------------------------------------------------------------------------------------- +!> @brief returns all strings in the list +!> @details returns raw string without start/end position of chunks +!-------------------------------------------------------------------------------------------------- +function strings(this) + use IO, only: & + IO_error, & + IO_stringValue + + implicit none + class(tPartitionedStringList), intent(in) :: this + character(len=65536), dimension(:), allocatable :: strings + character(len=65536) :: string + type(tPartitionedStringList), pointer :: item + + item => this%next + do while (associated(item)) + string = item%string%val + GfortranBug86033: if (.not. allocated(strings)) then + allocate(strings(1),source=string) + else GfortranBug86033 + strings = [strings,string] + endif GfortranBug86033 + item => item%next + end do + + if (size(strings) < 0_pInt) call IO_error(142_pInt) ! better to check for "allocated"? + +end function strings + + +!-------------------------------------------------------------------------------------------------- +!> @brief gets float value of first string that matches given key (i.e. first chunk) +!> @details gets one float value. If key is not found exits with error unless default is given +!-------------------------------------------------------------------------------------------------- +real(pReal) function getFloat(this,key,defaultVal) + use IO, only : & + IO_error, & + IO_stringValue, & + IO_FloatValue + + implicit none + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + real(pReal), intent(in), optional :: defaultVal + type(tPartitionedStringList), pointer :: item + logical :: found + + if (present(defaultVal)) getFloat = defaultVal + found = present(defaultVal) + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + getFloat = IO_FloatValue(item%string%val,item%string%pos,2) + endif + item => item%next + end do + + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getFloat + + +!-------------------------------------------------------------------------------------------------- +!> @brief gets integer value for given key +!> @details gets one integer value. If key is not found exits with error unless default is given +!-------------------------------------------------------------------------------------------------- +integer(pInt) function getInt(this,key,defaultVal) + use IO, only: & + IO_error, & + IO_stringValue, & + IO_IntValue + + implicit none + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + integer(pInt), intent(in), optional :: defaultVal + type(tPartitionedStringList), pointer :: item + logical :: found + + if (present(defaultVal)) getInt = defaultVal + found = present(defaultVal) + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + getInt = IO_IntValue(item%string%val,item%string%pos,2) + endif + item => item%next + end do + + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getInt + + +!-------------------------------------------------------------------------------------------------- +!> @brief gets string value for given key +!> @details if key is not found exits with error unless default is given +!-------------------------------------------------------------------------------------------------- +character(len=65536) function getString(this,key,defaultVal,raw) + use IO, only: & + IO_error, & + IO_stringValue + + implicit none + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + character(len=65536), intent(in), optional :: defaultVal + logical, intent(in), optional :: raw + type(tPartitionedStringList), pointer :: item + logical :: found, & + split + + if (present(defaultVal)) getString = defaultVal + split = merge(.not. raw,.true.,present(raw)) + found = present(defaultVal) + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + + if (split) then + getString = IO_StringValue(item%string%val,item%string%pos,2) + else + getString = trim(item%string%val(item%string%pos(4):)) ! raw string starting a second chunk + endif + endif + item => item%next + end do + + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getString + + +!-------------------------------------------------------------------------------------------------- +!> @brief ... +!> @details ... +!-------------------------------------------------------------------------------------------------- +function getStrings(this,key,defaultVal,raw) + use IO + + implicit none + character(len=65536),dimension(:), allocatable :: getStrings + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + character(len=65536),dimension(:), intent(in), optional :: defaultVal + logical, intent(in), optional :: raw + type(tPartitionedStringList), pointer :: item + character(len=65536) :: str + integer(pInt) :: i + logical :: found, & + split, & + cumulative + + cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') + split = merge(.not. raw,.true.,present(raw)) + found = .false. + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (allocated(getStrings) .and. .not. cumulative) deallocate(getStrings) + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + + arrayAllocated: if (.not. allocated(getStrings)) then + if (split) then + str = IO_StringValue(item%string%val,item%string%pos,2_pInt) + allocate(getStrings(1),source=str) + do i=3_pInt,item%string%pos(1) + str = IO_StringValue(item%string%val,item%string%pos,i) + getStrings = [getStrings,str] + enddo + else + str = item%string%val(item%string%pos(4):) + getStrings = [str] + endif + else arrayAllocated + if (split) then + do i=2_pInt,item%string%pos(1) + str = IO_StringValue(item%string%val,item%string%pos,i) + getStrings = [getStrings,str] + enddo + else + getStrings = [getStrings,str] + endif + endif arrayAllocated + endif + item => item%next + end do + + if (present(defaultVal) .and. .not. found) then + getStrings = defaultVal + found = .true. + endif + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getStrings + + +!-------------------------------------------------------------------------------------------------- +!> @brief gets array of int values for given key +!> @details if key is not found exits with error unless default is given +!-------------------------------------------------------------------------------------------------- +function getInts(this,key,defaultVal) + use IO, only: & + IO_error, & + IO_stringValue, & + IO_IntValue + + implicit none + integer(pInt), dimension(:), allocatable :: getInts + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + integer(pInt), dimension(:), intent(in), optional :: defaultVal + type(tPartitionedStringList), pointer :: item + integer(pInt) :: i + logical :: found, & + cumulative + + cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') + found = .false. + + allocate(getInts(0)) + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (.not. cumulative) then + deallocate(getInts) ! use here rhs allocation with empty list + allocate(getInts(0)) + endif + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + do i = 2_pInt, item%string%pos(1) + getInts = [getInts,IO_IntValue(item%string%val,item%string%pos,i)] + enddo + endif + item => item%next + end do + + if (present(defaultVal) .and. .not. found) then + getInts = defaultVal + found = .true. + endif + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getInts + + +!-------------------------------------------------------------------------------------------------- +!> @brief gets array of float values for given key +!> @details if key is not found exits with error unless default is given +!-------------------------------------------------------------------------------------------------- +function getFloats(this,key,defaultVal) + use IO, only: & + IO_error, & + IO_stringValue, & + IO_FloatValue + + implicit none + real(pReal), dimension(:), allocatable :: getFloats + class(tPartitionedStringList), intent(in) :: this + character(len=*), intent(in) :: key + integer(pInt), dimension(:), intent(in), optional :: defaultVal + type(tPartitionedStringList), pointer :: item + integer(pInt) :: i + logical :: found, & + cumulative + + cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') + found = .false. + + allocate(getFloats(0)) + + item => this%next + do while (associated(item)) + if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then + found = .true. + if (.not. cumulative) then + deallocate(getFloats) ! use here rhs allocation with empty list + allocate(getFloats(0)) + endif + if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) + do i = 2_pInt, item%string%pos(1) + getFloats = [getFloats,IO_FloatValue(item%string%val,item%string%pos,i)] + enddo + endif + item => item%next + end do + + if (present(defaultVal) .and. .not. found) then + getFloats = defaultVal + found = .true. + endif + if (.not. found) call IO_error(140_pInt,ext_msg=key) + +end function getFloats + + end module config diff --git a/src/linked_list.f90 b/src/linked_list.f90 deleted file mode 100644 index dbde4a295..000000000 --- a/src/linked_list.f90 +++ /dev/null @@ -1,472 +0,0 @@ -!-------------------------------------------------------------------------------------------------- -!> @author Martin Dieh, Max-Planck-Institut für Eisenforschung GmbH -!> @brief Chained list to store string together with position of delimiters -!-------------------------------------------------------------------------------------------------- -module linked_list - use prec, only: & - pReal, & - pInt - - implicit none - private - type, private :: tPartitionedString - character(len=:), allocatable :: val - integer(pInt), dimension(:), allocatable :: pos - end type tPartitionedString - - type, public :: tPartitionedStringList - type(tPartitionedString) :: string - type(tPartitionedStringList), pointer :: next => null() - contains - procedure :: add => add - procedure :: show => show - - procedure :: keyExists => exist - procedure :: countKeys => count - - procedure :: getFloat => getFloat - procedure :: getFloats => getFloats - - procedure :: getInt => getInt - procedure :: getInts => getInts - - procedure :: getStringsRaw => strings - procedure :: getString => getString - procedure :: getStrings => getStrings - - end type tPartitionedStringList - - type(tPartitionedStringList), public :: emptyList - -contains - -!-------------------------------------------------------------------------------------------------- -!> @brief add element -!> @details Adds a string together with the start/end position of chunks in this string. The new -!! element is added at the end of the list. Empty strings are not added. All strings are converted -!! to lower case -!-------------------------------------------------------------------------------------------------- -subroutine add(this,string) - use IO, only: & - IO_isBlank, & - IO_lc, & - IO_stringPos - - implicit none - class(tPartitionedStringList), target, intent(in) :: this - character(len=*), intent(in) :: string - type(tPartitionedStringList), pointer :: new, item - - if (IO_isBlank(string)) return - - allocate(new) - new%string%val = IO_lc (trim(string)) - new%string%pos = IO_stringPos(trim(string)) - - item => this - do while (associated(item%next)) - item => item%next - enddo - item%next => new - -end subroutine add - - -!-------------------------------------------------------------------------------------------------- -!> @brief prints all elements -!> @details Strings are printed in order of insertion (FIFO) -!-------------------------------------------------------------------------------------------------- -subroutine show(this) - - implicit none - class(tPartitionedStringList) :: this - type(tPartitionedStringList), pointer :: item - - item => this%next - do while (associated(item)) - write(6,'(a)') trim(item%string%val) - item => item%next - end do - -end subroutine show - - -!-------------------------------------------------------------------------------------------------- -!> @brief deallocates all elements of a given list -!> @details Strings are printed in order of insertion (FIFO) -!-------------------------------------------------------------------------------------------------- -! subroutine free_all() -! implicit none -! -! type(node), pointer :: item -! -! do -! item => first -! -! if (associated(item) .eqv. .FALSE.) exit -! -! first => first%next -! deallocate(item) -! end do -! end subroutine free_all - - -!-------------------------------------------------------------------------------------------------- -!> @brief reports wether a given key (string value at first position) exists in the list -!-------------------------------------------------------------------------------------------------- -logical function exist(this,key) - use IO, only: & - IO_stringValue - - implicit none - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - type(tPartitionedStringList), pointer :: item - - exist = .false. - - item => this%next - do while (associated(item) .and. .not. exist) - exist = trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key) - item => item%next - end do - -end function exist - - -!-------------------------------------------------------------------------------------------------- -!> @brief count number of key appearances -!> @details traverses list and counts each occurrence of specified key -!-------------------------------------------------------------------------------------------------- -integer(pInt) function count(this,key) - use IO, only: & - IO_stringValue - - implicit none - - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - type(tPartitionedStringList), pointer :: item - - count = 0_pInt - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) & - count = count + 1_pInt - item => item%next - end do - -end function count - - -!-------------------------------------------------------------------------------------------------- -!> @brief returns all strings in the list -!> @details returns raw string without start/end position of chunks -!-------------------------------------------------------------------------------------------------- -function strings(this) - use IO, only: & - IO_error, & - IO_stringValue - - implicit none - class(tPartitionedStringList), intent(in) :: this - character(len=65536), dimension(:), allocatable :: strings - character(len=65536) :: string - type(tPartitionedStringList), pointer :: item - - item => this%next - do while (associated(item)) - string = item%string%val - GfortranBug86033: if (.not. allocated(strings)) then - allocate(strings(1),source=string) - else GfortranBug86033 - strings = [strings,string] - endif GfortranBug86033 - item => item%next - end do - - if (size(strings) < 0_pInt) call IO_error(142_pInt) ! better to check for "allocated"? - -end function strings - - -!-------------------------------------------------------------------------------------------------- -!> @brief gets float value of first string that matches given key (i.e. first chunk) -!> @details gets one float value. If key is not found exits with error unless default is given -!-------------------------------------------------------------------------------------------------- -real(pReal) function getFloat(this,key,defaultVal) - use IO, only : & - IO_error, & - IO_stringValue, & - IO_FloatValue - - implicit none - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - real(pReal), intent(in), optional :: defaultVal - type(tPartitionedStringList), pointer :: item - logical :: found - - if (present(defaultVal)) getFloat = defaultVal - found = present(defaultVal) - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - getFloat = IO_FloatValue(item%string%val,item%string%pos,2) - endif - item => item%next - end do - - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getFloat - - -!-------------------------------------------------------------------------------------------------- -!> @brief gets integer value for given key -!> @details gets one integer value. If key is not found exits with error unless default is given -!-------------------------------------------------------------------------------------------------- -integer(pInt) function getInt(this,key,defaultVal) - use IO, only: & - IO_error, & - IO_stringValue, & - IO_IntValue - - implicit none - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - integer(pInt), intent(in), optional :: defaultVal - type(tPartitionedStringList), pointer :: item - logical :: found - - if (present(defaultVal)) getInt = defaultVal - found = present(defaultVal) - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - getInt = IO_IntValue(item%string%val,item%string%pos,2) - endif - item => item%next - end do - - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getInt - - -!-------------------------------------------------------------------------------------------------- -!> @brief gets string value for given key -!> @details if key is not found exits with error unless default is given -!-------------------------------------------------------------------------------------------------- -character(len=65536) function getString(this,key,defaultVal,raw) - use IO, only: & - IO_error, & - IO_stringValue - - implicit none - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - character(len=65536), intent(in), optional :: defaultVal - logical, intent(in), optional :: raw - type(tPartitionedStringList), pointer :: item - logical :: found, & - split - - if (present(defaultVal)) getString = defaultVal - split = merge(.not. raw,.true.,present(raw)) - found = present(defaultVal) - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - - if (split) then - getString = IO_StringValue(item%string%val,item%string%pos,2) - else - getString = trim(item%string%val(item%string%pos(4):)) ! raw string starting a second chunk - endif - endif - item => item%next - end do - - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getString - - -!-------------------------------------------------------------------------------------------------- -!> @brief ... -!> @details ... -!-------------------------------------------------------------------------------------------------- -function getStrings(this,key,defaultVal,raw) - use IO - - implicit none - character(len=65536),dimension(:), allocatable :: getStrings - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - character(len=65536),dimension(:), intent(in), optional :: defaultVal - logical, intent(in), optional :: raw - type(tPartitionedStringList), pointer :: item - character(len=65536) :: str - integer(pInt) :: i - logical :: found, & - split, & - cumulative - - cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') - split = merge(.not. raw,.true.,present(raw)) - found = .false. - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (allocated(getStrings) .and. .not. cumulative) deallocate(getStrings) - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - - arrayAllocated: if (.not. allocated(getStrings)) then - if (split) then - str = IO_StringValue(item%string%val,item%string%pos,2_pInt) - allocate(getStrings(1),source=str) - do i=3_pInt,item%string%pos(1) - str = IO_StringValue(item%string%val,item%string%pos,i) - getStrings = [getStrings,str] - enddo - else - str = item%string%val(item%string%pos(4):) - getStrings = [str] - endif - else arrayAllocated - if (split) then - do i=2_pInt,item%string%pos(1) - str = IO_StringValue(item%string%val,item%string%pos,i) - getStrings = [getStrings,str] - enddo - else - getStrings = [getStrings,str] - endif - endif arrayAllocated - endif - item => item%next - end do - - if (present(defaultVal) .and. .not. found) then - getStrings = defaultVal - found = .true. - endif - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getStrings - - -!-------------------------------------------------------------------------------------------------- -!> @brief gets array of int values for given key -!> @details if key is not found exits with error unless default is given -!-------------------------------------------------------------------------------------------------- -function getInts(this,key,defaultVal) - use IO, only: & - IO_error, & - IO_stringValue, & - IO_IntValue - - implicit none - integer(pInt), dimension(:), allocatable :: getInts - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - integer(pInt), dimension(:), intent(in), optional :: defaultVal - type(tPartitionedStringList), pointer :: item - integer(pInt) :: i - logical :: found, & - cumulative - - cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') - found = .false. - - allocate(getInts(0)) - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (.not. cumulative) then - deallocate(getInts) ! use here rhs allocation with empty list - allocate(getInts(0)) - endif - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - do i = 2_pInt, item%string%pos(1) - getInts = [getInts,IO_IntValue(item%string%val,item%string%pos,i)] - enddo - endif - item => item%next - end do - - if (present(defaultVal) .and. .not. found) then - getInts = defaultVal - found = .true. - endif - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getInts - - -!-------------------------------------------------------------------------------------------------- -!> @brief gets array of float values for given key -!> @details if key is not found exits with error unless default is given -!-------------------------------------------------------------------------------------------------- -function getFloats(this,key,defaultVal) - use IO, only: & - IO_error, & - IO_stringValue, & - IO_FloatValue - - implicit none - real(pReal), dimension(:), allocatable :: getFloats - class(tPartitionedStringList), intent(in) :: this - character(len=*), intent(in) :: key - integer(pInt), dimension(:), intent(in), optional :: defaultVal - type(tPartitionedStringList), pointer :: item - integer(pInt) :: i - logical :: found, & - cumulative - - cumulative = (key(1:1) == '(' .and. key(len_trim(key):len_trim(key)) == ')') - found = .false. - - allocate(getFloats(0)) - - item => this%next - do while (associated(item)) - if (trim(IO_stringValue(item%string%val,item%string%pos,1)) == trim(key)) then - found = .true. - if (.not. cumulative) then - deallocate(getFloats) ! use here rhs allocation with empty list - allocate(getFloats(0)) - endif - if (item%string%pos(1) < 2_pInt) call IO_error(143_pInt,ext_msg=key) - do i = 2_pInt, item%string%pos(1) - getFloats = [getFloats,IO_FloatValue(item%string%val,item%string%pos,i)] - enddo - endif - item => item%next - end do - - if (present(defaultVal) .and. .not. found) then - getFloats = defaultVal - found = .true. - endif - if (.not. found) call IO_error(140_pInt,ext_msg=key) - -end function getFloats - - -end module linked_list diff --git a/src/material.f90 b/src/material.f90 index 474f10a59..15912741e 100644 --- a/src/material.f90 +++ b/src/material.f90 @@ -8,7 +8,6 @@ !-------------------------------------------------------------------------------------------------- module material use config - use linked_list use prec, only: & pReal, & pInt, &