36 use,
intrinsic :: iso_fortran_env, only : error_unit, output_unit
62 function c_mkdir(path, mode)
bind(C, name="mkdir")
63 import :: c_char, c_int
64 character(kind=c_char),
dimension(*) :: path
65 integer(c_int),
value :: mode
74 character(len=*),
intent(in) :: fname
76 suffix_pos = scan(trim(fname),
'.', back = .true.)
81 character(len=*),
intent(in) :: fname
83 tslash_pos = scan(trim(fname),
'/', back = .true.)
88 character(len=*),
intent(in) :: fname
89 character(len=*),
intent(out) :: path
93 if (tslash_pos .gt. 0)
then
94 path = trim(fname(1:tslash_pos))
103 character(len=*),
intent(in) :: fname
104 character(len=*),
intent(out) :: name
105 integer :: tslash_pos, suffix_pos, start, end
109 if (tslash_pos .eq. 0)
then
112 start = tslash_pos + 1
114 if (suffix_pos .eq. 0)
then
115 end = len_trim(fname)
119 name = trim(fname(start:
end))
124 character(len=*) :: fname
125 character(len=*) :: suffix
131 character(len=*),
intent(in) :: fname
132 character(len=*),
intent(out) :: path, name, suffix
133 integer :: tslash_pos, suffix_pos
138 if (tslash_pos .gt. 0)
then
139 path = trim(fname(1:tslash_pos))
144 if (suffix_pos .gt. 0)
then
145 name = trim(fname(tslash_pos + 1:suffix_pos - 1))
146 suffix = trim(fname(suffix_pos:len_trim(fname)))
148 name = trim(fname(tslash_pos + 1:len_trim(fname)))
156 character(len=*) :: fname
157 character(len=*) :: new_fname
158 character(len=*) :: new_suffix
159 integer :: suffix_pos
162 new_fname = trim(fname(1:suffix_pos))//new_suffix
173 recursive subroutine mkdir(path, mode)
174 character(len=*),
intent(in) :: path
175 integer,
intent(in),
optional :: mode
176 integer :: slash_pos, i, path_len
177 character(kind=c_char),
allocatable :: c_path(:)
178 integer(c_int) :: dir_mode, ierr
180 if (
present(mode))
then
181 dir_mode = int(mode, kind=c_int)
183 dir_mode = int(o
'777', kind=c_int)
186 slash_pos = scan(path,
'/', back = .true.)
187 if (slash_pos .gt. 0)
then
188 call mkdir(trim(path(1:slash_pos-1)), dir_mode)
191 path_len = len_trim(path)
192 allocate(c_path(path_len + 1))
194 c_path(i) = path(i:i)
196 c_path(path_len + 1) = c_null_char
198 ierr =
c_mkdir(c_path, dir_mode)
209 character(len=*),
intent(in) :: fld_filename
210 integer,
intent(in) :: default_index
212 character(len=80) :: suffix
213 integer :: index, fpos, i
222 index = default_index
227 fpos = scan(trim(suffix),
'f')
228 if (fpos .eq. 1)
then
230 do i = 2, len(trim(suffix))
231 if (.not. (iachar(suffix(i:i)) >= iachar(
'0') &
232 .and. iachar(suffix(i:i)) <= iachar(
'9')))
then
241 if (len(trim(suffix)) .ne. 6) valid = .false.
243 if (valid)
read (suffix(2:),
"(I5.5)") index
251 character(len=*) :: string
252 character(len=*) :: delimiter
253 character(len=100),
allocatable :: split_str(:)
254 integer :: length, i, i2, offset, j
258 if (len(trim(string)) .eq. 0)
then
259 allocate(split_str(1))
260 split_str(1) = trim(string)
264 i = scan(string(offset:), delimiter, back = .false.)
270 allocate(split_str(length))
275 i2 = scan(trim(string(offset:)), delimiter, back = .false.)
277 split_str(j) = trim(string(offset:))
280 split_str(j) = trim(string(offset:offset+i2-2))
289 integer,
intent(in) :: i, j, k, l, lx, ly, lz
292 index = (i + lx * ((j - 1) + ly * ((k - 1) + lz * ((l - 1)))))
302 index(4) = lin_idx/(lx*ly*lz)
303 index(3) = (lin_idx-(lx*ly*lz)*index(4))/(lx*ly)
304 index(2) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3))/lx
305 index(1) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3)-lx*index(2))
306 index(1) = index(1) + 1
307 index(2) = index(2) + 1
308 index(3) = index(3) + 1
309 index(4) = index(4) + 1
314 integer,
intent(in) :: i, j, k, lx, ly, lz, facet
320 if (i .eq. 1) is_on = .true.
322 if (i .eq. lx) is_on = .true.
324 if (j .eq. 1) is_on = .true.
326 if (j .eq. ly) is_on = .true.
328 if (k .eq. 1) is_on = .true.
330 if (k .eq. lz) is_on = .true.
338 integer,
optional :: error_code
344 if (
present(error_code))
then
345 write(error_unit, *)
'*** ERROR ***', error_code
349 write(error_unit, *)
'*** ERROR ***'
359 character(len=*) :: error_msg
364 write(error_unit, *)
'*** ERROR: ', trim(error_msg),
' ***'
376 character(len=*),
intent(in) :: base_type
377 character(len=*),
intent(in) :: wrong_type
378 character(len=*),
intent(in) :: known_types(:)
382 write(error_unit, *)
'*** ERROR WHEN SELECTING TYPE ***'
383 write(error_unit, *)
'Type ', wrong_type,
' does not exist for ', base_type
384 write(error_unit, *)
'Valid types are:'
385 do i = 1,
size(known_types)
386 write(error_unit, *)
" ", known_types(i)
393 character(len=*),
intent(in) :: base_type
394 character(len=*),
intent(in) :: wrong_type
395 logical,
intent(in) :: known
398 write(error_unit, *)
'*** ERROR WHEN REGISTERING TYPE ***'
399 write(error_unit, *)
'Type name ', wrong_type, &
400 ' conflicts with and already existing ', base_type,
" type"
402 write(error_unit, *)
'Please rename your custom type.'
404 write(error_unit, *)
'The already existing type is also custom.' // &
405 ' Make all custom type names unique!'
413 character(len=*) :: warning_msg
414 write(output_unit, *)
'*** WARNING: ', trim(warning_msg),
' ***'
424 character(len=*),
intent(in) :: array(:)
425 character(len=*),
intent(in) :: sep
426 logical,
intent(in) :: prepend
427 character(:),
allocatable :: result
430 result = trim(array(1))
431 do i = 2,
size(array)
432 result = result // sep // trim(array(i))
436 result = sep // result
449 character(len=*),
intent(in) :: runtime_string
450 real(kind=rp),
intent(inout) :: runtime_seconds
451 integer,
optional,
intent(out) :: ierr
452 real(kind=dp) :: parsed_seconds
454 if (
present(ierr)) ierr = 0
455 if (len_trim(runtime_string) .eq. 0)
return
459 if (
present(ierr))
then
460 if (ierr .ne. 0)
return
463 runtime_seconds = parsed_seconds
473 character(len=*),
intent(in) :: runtime_string
474 real(kind=rp),
intent(inout) :: runtime_values(:)
475 integer,
optional,
intent(out) :: ierr
476 integer,
parameter :: i64 = selected_int_kind(18)
478 integer(kind=i64) :: total_whole, days, hours, minutes, seconds_whole
479 real(kind=dp) :: parsed_seconds, second_value, frac_seconds
481 if (
present(ierr)) ierr = 0
482 if (len_trim(runtime_string) .eq. 0)
return
484 n_values =
size(runtime_values)
485 if (n_values .lt. 1 .or. n_values .gt. 4)
then
487 'Error parsing duration: output array size must be 1 to 4', ierr)
493 if (
present(ierr))
then
494 if (ierr .ne. 0)
return
497 total_whole = int(parsed_seconds, kind=i64)
498 frac_seconds = parsed_seconds -
real(total_whole, kind=dp)
499 if (frac_seconds .lt. 0.0_dp) frac_seconds = 0.0_dp
501 days = total_whole / 86400_i64
502 total_whole = total_whole - 86400_i64 * days
503 hours = total_whole / 3600_i64
504 total_whole = total_whole - 3600_i64 * hours
505 minutes = total_whole / 60_i64
506 seconds_whole = total_whole - 60_i64 * minutes
508 second_value =
real(seconds_whole, kind=dp) + frac_seconds
509 if (second_value .ge. 60.0_dp)
then
510 second_value = second_value - 60.0_dp
511 minutes = minutes + 1_i64
512 if (minutes .ge. 60_i64)
then
513 minutes = minutes - 60_i64
514 hours = hours + 1_i64
515 if (hours .ge. 24_i64)
then
516 hours = hours - 24_i64
522 select case (n_values)
524 runtime_values(1) =
real(days, kind=rp)
525 runtime_values(2) =
real(hours, kind=rp)
526 runtime_values(3) =
real(minutes, kind=rp)
527 runtime_values(4) =
real(second_value, kind=rp)
529 runtime_values(1) =
real(days * 24_i64 + hours, kind=rp)
530 runtime_values(2) =
real(minutes, kind=rp)
531 runtime_values(3) =
real(second_value, kind=rp)
533 runtime_values(1) =
real((days * 24_i64 + hours) * 60_i64 + &
535 runtime_values(2) =
real(second_value, kind=rp)
537 runtime_values(1) =
real(parsed_seconds, kind=rp)
543 result(runtime_seconds)
544 character(len=*),
intent(in) :: runtime_string
545 integer,
optional,
intent(out) :: ierr
546 character(len=:),
allocatable :: time_string
547 real(kind=dp) :: parsed_seconds, read_real
548 logical :: has_minutes, has_hours, has_days
549 integer :: read_int, ios, sep
551 if (
present(ierr)) ierr = 0
553 runtime_seconds = 0.0_dp
554 time_string = trim(adjustl(runtime_string))
556 sep = index(time_string,
':')
557 has_minutes = sep .gt. 0
559 if (has_minutes .and. sep .lt. len_trim(time_string))
then
560 has_hours = index(time_string(sep + 1:len_trim(time_string)),
':') &
563 has_days = index(time_string,
'-') .gt. 0
565 if ((has_days .and. .not. has_hours) .or. &
566 (has_hours .and. .not. has_minutes))
then
571 parsed_seconds = 0.0_dp
575 sep = index(time_string,
'-')
576 read(time_string(1:sep - 1), *, iostat=ios) read_int
577 if (ios .ne. 0 .or. read_int .lt. 0)
then
579 'Error parsing duration: Invalid days value', ierr)
583 time_string = time_string(sep + 1:)
584 parsed_seconds = parsed_seconds +
real(86400 * read_int, kind=dp)
589 sep = index(time_string,
':')
590 read(time_string(1:sep - 1), *, iostat=ios) read_int
591 if (ios .ne. 0 .or. read_int .lt. 0 .or. &
592 (has_days .and. read_int .gt. 23))
then
594 'Error parsing duration: Invalid hours value', ierr)
598 time_string = time_string(sep + 1:)
599 parsed_seconds = parsed_seconds +
real(3600 * read_int, kind=dp)
603 if (has_minutes)
then
604 sep = index(time_string,
':')
605 read(time_string(1:sep - 1), *, iostat=ios) read_int
606 if (ios .ne. 0 .or. read_int .lt. 0 .or. &
607 (has_hours .and. read_int .gt. 59))
then
609 'Error parsing duration: Invalid minutes value', ierr)
613 time_string = time_string(sep + 1:)
614 parsed_seconds = parsed_seconds +
real(60 * read_int, kind=dp)
618 read(time_string, *, iostat=ios) read_real
619 if (ios .ne. 0 .or. read_real .lt. 0.0_dp .or. &
620 (has_minutes .and. read_real .ge. 60.0_dp))
then
622 'Error parsing duration: Invalid seconds value', ierr)
626 parsed_seconds = parsed_seconds + read_real
627 runtime_seconds = parsed_seconds
629 if (
allocated(time_string))
deallocate(time_string)
634 character(len=*),
intent(in) :: message
635 integer,
optional,
intent(out) :: ierr
637 if (
present(ierr))
then
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
integer, parameter, public dp
integer, parameter, public rp
Global precision used in computations.
integer function, public extract_fld_file_index(fld_filename, default_index)
Extracts the index of a field file. For example, "myfield.f00045" will return 45. If the suffix of th...
character(:) function, allocatable, public concat_string_array(array, sep, prepend)
Concatenate an array of strings into one string with array items separated by spaces.
subroutine, public neko_type_registration_error(base_type, wrong_type, known)
subroutine, public filename_name(fname, name)
Extract the base name of a file (without path and suffix)
subroutine set_error_or_throw(message, ierr)
Raise parser error or set ierr, depending on call mode.
character(len=100) function, dimension(:), allocatable, public split_string(string, delimiter)
Split a string based on delimiter (tokenizer) OBS: very hacky, this should really be improved,...
pure logical function, public index_is_on_facet(i, j, k, lx, ly, lz, facet)
subroutine neko_error_msg(error_msg)
Reports an error and stops execution.
pure integer function, public linear_index(i, j, k, l, lx, ly, lz)
Compute the address of a (i,j,k,l) array with sizes (1:lx, 1:ly, 1:lz, :)
subroutine read_duration_scalar(runtime_string, runtime_seconds, ierr)
Parse runtime string to total seconds. Supported formats are:
integer, parameter, public neko_fname_len
subroutine, public filename_split(fname, path, name, suffix)
Extract file name components.
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
real(kind=dp) function read_duration_internal(runtime_string, ierr)
Parse runtime string to total seconds.
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
subroutine read_duration_components(runtime_string, runtime_values, ierr)
Parse runtime string to components. The output array maps to the largest unit available based on size...
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
subroutine, public neko_type_error(base_type, wrong_type, known_types)
Reports an error allocating a type for a particular base pointer class.
recursive subroutine, public mkdir(path, mode)
Recursively create a directory and all parent directories if they do not exist. This should be safer ...
integer, parameter, public neko_varname_len
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
subroutine neko_error_plain(error_code)
Reports an error and stops execution.
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
subroutine, public filename_path(fname, path)
Extract the path to a file.