DAMASK_EICMD/src/config.f90

265 lines
11 KiB
Fortran
Raw Normal View History

2020-01-27 00:26:30 +05:30
!--------------------------------------------------------------------------------------------------
2018-06-10 14:37:17 +05:30
!> @author Martin Diehl, Max-Planck-Institut für Eisenforschung GmbH
!> @brief Reads in the material configuration from file
!> @details Reads the material configuration file, where solverJobName.materialConfig takes
!! precedence over material.config. Stores the raw strings and the positions of delimiters for the
!! parts 'homogenization', 'crystallite', 'phase', 'texture', and 'microstucture'
!--------------------------------------------------------------------------------------------------
module config
2019-05-15 02:42:32 +05:30
use prec
use DAMASK_interface
use IO
use debug
2019-05-15 02:42:32 +05:30
use list
2020-06-16 22:17:19 +05:30
use YAML_parse
use YAML_types
2019-03-29 13:04:44 +05:30
implicit none
2019-05-15 02:42:32 +05:30
private
2019-05-28 12:57:52 +05:30
type(tPartitionedStringList), public, protected, allocatable, dimension(:) :: &
2019-03-29 13:04:44 +05:30
config_phase, &
config_microstructure, &
config_homogenization, &
config_texture, &
config_crystallite
2020-01-29 19:22:09 +05:30
character(len=pStringLen), public, protected, allocatable, dimension(:) :: &
2019-06-15 17:56:32 +05:30
config_name_phase, & !< name of each phase
config_name_homogenization, & !< name of each homogenization
config_name_crystallite, & !< name of each crystallite setting
config_name_microstructure, & !< name of each microstructure
config_name_texture !< name of each texture
2019-03-29 13:04:44 +05:30
public :: &
config_init, &
config_deallocate
contains
!--------------------------------------------------------------------------------------------------
!> @brief reads material.config and stores its content per part
!--------------------------------------------------------------------------------------------------
subroutine config_init
integer :: i
logical :: verbose
2019-03-29 13:04:44 +05:30
character(len=pStringLen) :: &
line, &
part
character(len=pStringLen), dimension(:), allocatable :: fileContent
2020-06-18 21:44:53 +05:30
class(tNode), pointer :: &
debug_material
logical :: fileExists
2019-03-29 13:04:44 +05:30
write(6,'(/,a)') ' <<<+- config init -+>>>'; flush(6)
2019-03-29 13:04:44 +05:30
2020-06-18 21:44:53 +05:30
debug_material => debug_root%get('material',defaultVal=emptyList)
verbose = debug_material%contains('basic')
2019-03-29 13:04:44 +05:30
inquire(file=trim(getSolverJobName())//'.materialConfig',exist=fileExists)
if(fileExists) then
write(6,'(/,a)') ' reading '//trim(getSolverJobName())//'.materialConfig'; flush(6)
fileContent = read_materialConfig(trim(getSolverJobName())//'.materialConfig')
else
inquire(file='material.config',exist=fileExists)
if(.not. fileExists) call IO_error(100,ext_msg='material.config')
write(6,'(/,a)') ' reading material.config'; flush(6)
fileContent = read_materialConfig('material.config')
endif
do i = 1, size(fileContent)
line = trim(fileContent(i))
part = IO_lc(IO_getTag(line,'<','>'))
select case (trim(part))
2019-03-29 13:04:44 +05:30
case (trim('phase'))
2019-06-15 17:56:32 +05:30
call parse_materialConfig(config_name_phase,config_phase,line,fileContent(i+1:))
if (verbose) write(6,'(a)') ' Phase parsed'; flush(6)
2019-03-29 13:04:44 +05:30
case (trim('microstructure'))
2019-06-15 17:56:32 +05:30
call parse_materialConfig(config_name_microstructure,config_microstructure,line,fileContent(i+1:))
if (verbose) write(6,'(a)') ' Microstructure parsed'; flush(6)
2019-03-29 13:04:44 +05:30
case (trim('crystallite'))
2019-06-15 17:56:32 +05:30
call parse_materialConfig(config_name_crystallite,config_crystallite,line,fileContent(i+1:))
if (verbose) write(6,'(a)') ' Crystallite parsed'; flush(6)
2019-11-24 15:30:47 +05:30
deallocate(config_crystallite)
2019-03-29 13:04:44 +05:30
case (trim('homogenization'))
2019-06-15 17:56:32 +05:30
call parse_materialConfig(config_name_homogenization,config_homogenization,line,fileContent(i+1:))
if (verbose) write(6,'(a)') ' Homogenization parsed'; flush(6)
2019-03-29 13:04:44 +05:30
case (trim('texture'))
2019-06-15 19:00:41 +05:30
call parse_materialConfig(config_name_texture,config_texture,line,fileContent(i+1:))
if (verbose) write(6,'(a)') ' Texture parsed'; flush(6)
2019-03-29 13:04:44 +05:30
end select
2019-03-29 13:04:44 +05:30
enddo
2019-03-08 13:18:06 +05:30
2019-07-16 02:23:34 +05:30
if (.not. allocated(config_homogenization) .or. size(config_homogenization) < 1) &
call IO_error(160,ext_msg='<homogenization>')
if (.not. allocated(config_microstructure) .or. size(config_microstructure) < 1) &
call IO_error(160,ext_msg='<microstructure>')
if (.not. allocated(config_phase) .or. size(config_phase) < 1) &
call IO_error(160,ext_msg='<phase>')
if (.not. allocated(config_texture) .or. size(config_texture) < 1) &
call IO_error(160,ext_msg='<texture>')
2018-06-09 17:18:37 +05:30
2019-03-13 02:18:33 +05:30
contains
!--------------------------------------------------------------------------------------------------
!> @brief reads material.config
!! Recursion is triggered by "{path/to/inputfile}" in a line
!--------------------------------------------------------------------------------------------------
recursive function read_materialConfig(fileName,cnt) result(fileContent)
2020-03-15 17:16:10 +05:30
character(len=*), intent(in) :: fileName !< name of the material configuration file
integer, intent(in), optional :: cnt !< recursion counter
character(len=pStringLen), dimension(:), allocatable :: fileContent !< file content, separated per lines
character(len=pStringLen), dimension(:), allocatable :: includedContent
character(len=pStringLen) :: line
character(len=pStringLen), parameter :: dummy = 'https://damask.mpie.de' !< to fill up remaining array
2019-09-19 23:30:41 +05:30
character(len=:), allocatable :: rawData
integer :: &
2019-03-13 02:18:33 +05:30
startPos, endPos, &
myTotalLines, & !< # lines read from file without include statements
2020-06-16 22:17:19 +05:30
l,i
2019-03-13 02:18:33 +05:30
logical :: warned
if (present(cnt)) then
2019-03-13 02:59:03 +05:30
if (cnt>10) call IO_error(106,ext_msg=trim(fileName))
2019-03-13 02:18:33 +05:30
endif
2020-06-16 22:17:19 +05:30
rawData = IO_read(fileName) ! read data as stream
2019-03-13 02:18:33 +05:30
!--------------------------------------------------------------------------------------------------
! count lines to allocate string array
myTotalLines = 1
do l=1, len(rawData)
2020-01-27 01:45:21 +05:30
if (rawData(l:l) == IO_EOL) myTotalLines = myTotalLines+1
2019-03-13 02:18:33 +05:30
enddo
allocate(fileContent(myTotalLines))
!--------------------------------------------------------------------------------------------------
! split raw data at end of line and handle includes
warned = .false.
startPos = 1
l = 1
2019-03-13 02:18:33 +05:30
do while (l <= myTotalLines)
2020-01-27 01:45:21 +05:30
endPos = merge(startPos + scan(rawData(startPos:),IO_EOL) - 2,len(rawData),l /= myTotalLines)
if (endPos - startPos > pStringLen -1) then
line = rawData(startPos:startPos+pStringLen-1)
2019-03-13 02:18:33 +05:30
if (.not. warned) then
call IO_warning(207,ext_msg=trim(fileName),el=l)
2019-03-13 02:18:33 +05:30
warned = .true.
endif
else
line = rawData(startPos:endpos)
endif
startPos = endPos + 2 ! jump to next line start
2019-03-13 02:18:33 +05:30
recursion: if (scan(trim(adjustl(line)),'{') == 1 .and. scan(trim(line),'}') > 2) then
includedContent = read_materialConfig(trim(line(scan(line,'{')+1:scan(line,'}')-1)), &
merge(cnt,1,present(cnt))) ! to track recursion depth
fileContent = [ fileContent(1:l-1), includedContent, [(dummy,i=1,myTotalLines-l)] ] ! add content and grow array
myTotalLines = myTotalLines - 1 + size(includedContent)
l = l - 1 + size(includedContent)
2019-03-13 02:18:33 +05:30
else recursion
fileContent(l) = line
2019-03-13 02:59:03 +05:30
l = l + 1
2019-03-13 02:18:33 +05:30
endif recursion
enddo
end function read_materialConfig
!--------------------------------------------------------------------------------------------------
!> @brief parses the material.config file
!--------------------------------------------------------------------------------------------------
2019-03-13 02:18:33 +05:30
subroutine parse_materialConfig(sectionNames,part,line, &
fileContent)
2019-05-15 02:42:32 +05:30
character(len=pStringLen), allocatable, dimension(:), intent(out) :: sectionNames
2019-03-29 13:04:44 +05:30
type(tPartitionedStringList), allocatable, dimension(:), intent(inout) :: part
character(len=pStringLen), intent(inout) :: line
character(len=pStringLen), dimension(:), intent(in) :: fileContent
integer, allocatable, dimension(:) :: partPosition !< position of [] tags + last line in section
integer :: i, j
logical :: echo
character(len=pStringLen) :: sectionName
2019-03-29 13:04:44 +05:30
echo = .false.
2019-03-29 13:04:44 +05:30
if (allocated(part)) call IO_error(161,ext_msg=trim(line))
allocate(partPosition(0))
2019-03-29 13:04:44 +05:30
do i = 1, size(fileContent)
line = trim(fileContent(i))
if (IO_getTag(line,'<','>') /= '') exit
nextSection: if (IO_getTag(line,'[',']') /= '') then
partPosition = [partPosition, i]
cycle
endif nextSection
if (size(partPosition) < 1) &
echo = (trim(IO_getTag(line,'/','/')) == 'echo') .or. echo
enddo
allocate(sectionNames(size(partPosition)))
allocate(part(size(partPosition)))
partPosition = [partPosition, i] ! needed when actually storing content
do i = 1, size(partPosition) -1
write(sectionName,'(i0,a,a)') i,'_',trim(IO_getTag(fileContent(partPosition(i)),'[',']'))
sectionNames(i) = sectionName
2019-03-29 13:04:44 +05:30
do j = partPosition(i) + 1, partPosition(i+1) -1
call part(i)%add(trim(adjustl(fileContent(j))))
enddo
if (echo) then
write(6,*) 'section',i, '"'//trim(sectionNames(i))//'"'
call part(i)%show()
endif
enddo
2019-03-13 02:18:33 +05:30
end subroutine parse_materialConfig
end subroutine config_init
!--------------------------------------------------------------------------------------------------
!> @brief deallocates the linked lists that store the content of the configuration files
!--------------------------------------------------------------------------------------------------
subroutine config_deallocate(what)
2019-03-29 13:04:44 +05:30
character(len=*), intent(in) :: what
2019-03-29 13:04:44 +05:30
select case(trim(what))
2019-03-29 13:04:44 +05:30
case('material.config/phase')
deallocate(config_phase)
2019-03-29 13:04:44 +05:30
case('material.config/microstructure')
deallocate(config_microstructure)
2019-03-29 13:04:44 +05:30
case('material.config/homogenization')
deallocate(config_homogenization)
2019-03-29 13:04:44 +05:30
case('material.config/texture')
deallocate(config_texture)
2019-03-29 13:04:44 +05:30
case default
call IO_error(0,ext_msg='config_deallocate')
2019-03-29 13:04:44 +05:30
end select
end subroutine config_deallocate
end module config