diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9789ec67d..7b013fe5f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -30,6 +30,10 @@ add_library(IO OBJECT "IO.f90") add_dependencies(IO DAMASK_INTERFACE) list(APPEND OBJECTFILES $) +add_library(CHAINED_LIST OBJECT "list.f90") +add_dependencies(CHAINED_LIST IO) +list(APPEND OBJECTFILES $) + add_library(NUMERICS OBJECT "numerics.f90") add_dependencies(NUMERICS IO) list(APPEND OBJECTFILES $) @@ -61,7 +65,7 @@ elseif ("${PROJECT_NAME}" STREQUAL "DAMASK_FEM") endif() add_library(MATERIAL OBJECT "material.f90") -add_dependencies(MATERIAL MESH) +add_dependencies(MATERIAL MESH CHAINED_LIST) list(APPEND OBJECTFILES $) add_library(DAMASK_HELPERS OBJECT "lattice.f90") diff --git a/src/commercialFEM_fileList.f90 b/src/commercialFEM_fileList.f90 index f57f03467..f1651dea8 100644 --- a/src/commercialFEM_fileList.f90 +++ b/src/commercialFEM_fileList.f90 @@ -4,6 +4,7 @@ !> @details List of files needed by MSC.Marc, Abaqus/Explicit, and Abaqus/Standard !-------------------------------------------------------------------------------------------------- #include "IO.f90" +#include "list.f90" #include "numerics.f90" #include "debug.f90" #include "math.f90" diff --git a/src/list.f90 b/src/list.f90 new file mode 100644 index 000000000..516f001f6 --- /dev/null +++ b/src/list.f90 @@ -0,0 +1,171 @@ +module chained_list + use prec + implicit none + + type tPartitionedString + character(len=:), allocatable :: val + integer(pInt), dimension(:), allocatable :: pos + end type + + type, public :: tPartitionedStringList + type(tPartitionedString) :: string + type(tPartitionedStringList), pointer :: next => null() + contains + procedure :: add => add + procedure :: getFloat => getFloat + procedure :: getFloatArray => getFloatArray + procedure :: getStrings => getStrings + procedure :: keyExists => keyExists + end type tPartitionedStringList + + + contains + subroutine add(self,string,stringPos) + implicit none + class(tPartitionedStringList) :: self + type(tPartitionedStringList), pointer :: new,tmp + character(len=*), intent(in) :: string + integer(pInt), dimension(:), intent(in) :: stringPos + + allocate(new) + + new%string%val=string + new%string%pos=stringPos + + if (.not. associated(self%next)) then + self%next => new + else + tmp => self%next + self%next => new + self%next%next => tmp + end if + + end subroutine add + + +! gets float value, if key is not found exits with error unless default is given + function getFloat(self,key,default) + use IO + + implicit none + real(pReal) :: getFloat + + class(tPartitionedStringList), intent(in) :: self + character(len=*), intent(in) :: key + real(pReal), intent(in), optional :: default + type(tPartitionedStringList), pointer :: tmp + + tmp => self%next + do + if (.not. associated(tmp)) then + if(present(default)) then + getFloat = default + exit + else + call IO_error(1_pInt,ext_msg=key) + endif + endif + if (trim(IO_stringValue(tmp%string%val,tmp%string%pos,1))==trim(key)) then + if (tmp%string%pos(1) > 2) call IO_error(1_pInt,ext_msg=key) + getFloat = IO_FloatValue(tmp%string%val,tmp%string%pos,2) + exit + endif + tmp => tmp%next + end do + end function + +! reports wether a key exists at least once + function keyExists(self,key) + use IO + + implicit none + logical :: keyExists + + class(tPartitionedStringList), intent(in) :: self + character(len=*), intent(in) :: key + type(tPartitionedStringList), pointer :: tmp + + keyExists = .false. + + tmp => self%next + do + if (.not. associated(tmp)) exit + if (trim(IO_stringValue(tmp%string%val,tmp%string%pos,1))==trim(key)) then + keyExists = .true. + exit + endif + tmp => tmp%next + end do + end function + + function getFloatArray(self,key) + use IO + + implicit none + real(pReal),dimension(:),allocatable :: getFloatArray + + class(tPartitionedStringList), intent(in) :: self + character(len=*), intent(in) :: key + type(tPartitionedStringList), pointer :: tmp + integer(pInt) :: i + + allocate(getFloatArray(0)) + + tmp => self%next + do + if (.not. associated(tmp)) exit + if (trim(IO_stringValue(tmp%string%val,tmp%string%pos,1))==trim(key)) then + do i = 2_pInt, tmp%string%pos(1) + getFloatArray = [getFloatArray,IO_FloatValue(tmp%string%val,tmp%string%pos,i)] + enddo + exit + endif + tmp => tmp%next + end do + end function + + + function getStrings(self,key) + use IO + + implicit none + character(len=64),dimension(:),allocatable :: getStrings + character(len=64) :: str + + class(tPartitionedStringList), intent(in) :: self + character(len=*), intent(in) :: key + type(tPartitionedStringList), pointer :: tmp + integer(pInt) :: i + + tmp => self%next + do + if (.not. associated(tmp)) exit + if (trim(IO_stringValue(tmp%string%val,tmp%string%pos,1))==trim(key)) then + if (tmp%string%pos(1) < 2) print*, "NOT WORKKING" + str = IO_StringValue(tmp%string%val,tmp%string%pos,2) + if (.not. allocated(getStrings)) then + getStrings = [str] + else + getStrings = [getStrings,str] + endif + endif + tmp => tmp%next + end do + end function + +! subroutine free_all() +! implicit none +! +! type(node), pointer :: tmp +! +! do +! tmp => first +! +! if (associated(tmp) .eqv. .FALSE.) exit +! +! first => first%next +! deallocate(tmp) +! end do +! end subroutine free_all + +end module chained_list