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
340 if (
present(error_code))
then
341 write(error_unit, *)
'*** ERROR ***', error_code
344 write(error_unit, *)
'*** ERROR ***'
353 character(len=*) :: error_msg
354 write(error_unit, *)
'*** ERROR: ', trim(error_msg),
' ***'
365 character(len=*),
intent(in) :: base_type
366 character(len=*),
intent(in) :: wrong_type
367 character(len=*),
intent(in) :: known_types(:)
370 write(error_unit, *)
'*** ERROR WHEN SELECTING TYPE ***'
371 write(error_unit, *)
'Type ', wrong_type,
' does not exist for ', base_type
372 write(error_unit, *)
'Valid types are:'
373 do i = 1,
size(known_types)
374 write(error_unit, *)
" ", known_types(i)
380 character(len=*),
intent(in) :: base_type
381 character(len=*),
intent(in) :: wrong_type
382 logical,
intent(in) :: known
384 write(error_unit, *)
'*** ERROR WHEN REGISTERING TYPE ***'
385 write(error_unit, *)
'Type name ', wrong_type, &
386 ' conflicts with and already existing ', base_type,
" type"
388 write(error_unit, *)
'Please rename your custom type.'
390 write(error_unit, *)
'The already existing type is also custom.' // &
391 ' Make all custom type names unique!'
398 character(len=*) :: warning_msg
399 write(output_unit, *)
'*** WARNING: ', trim(warning_msg),
' ***'
408 character(len=*),
intent(in) :: array(:)
409 character(len=*),
intent(in) :: sep
410 logical,
intent(in) :: prepend
411 character(:),
allocatable :: result
414 result = trim(array(1))
415 do i = 2,
size(array)
416 result = result // sep // trim(array(i))
420 result = sep // result
433 character(len=*),
intent(in) :: runtime_string
434 real(kind=rp),
intent(inout) :: runtime_seconds
435 integer,
optional,
intent(out) :: ierr
436 real(kind=dp) :: parsed_seconds
438 if (
present(ierr)) ierr = 0
439 if (len_trim(runtime_string) .eq. 0)
return
443 if (
present(ierr))
then
444 if (ierr .ne. 0)
return
447 runtime_seconds = parsed_seconds
457 character(len=*),
intent(in) :: runtime_string
458 real(kind=rp),
intent(inout) :: runtime_values(:)
459 integer,
optional,
intent(out) :: ierr
460 integer,
parameter :: i64 = selected_int_kind(18)
462 integer(kind=i64) :: total_whole, days, hours, minutes, seconds_whole
463 real(kind=dp) :: parsed_seconds, second_value, frac_seconds
465 if (
present(ierr)) ierr = 0
466 if (len_trim(runtime_string) .eq. 0)
return
468 n_values =
size(runtime_values)
469 if (n_values .lt. 1 .or. n_values .gt. 4)
then
471 'Error parsing duration: output array size must be 1 to 4', ierr)
477 if (
present(ierr))
then
478 if (ierr .ne. 0)
return
481 total_whole = int(parsed_seconds, kind=i64)
482 frac_seconds = parsed_seconds -
real(total_whole, kind=dp)
483 if (frac_seconds .lt. 0.0_dp) frac_seconds = 0.0_dp
485 days = total_whole / 86400_i64
486 total_whole = total_whole - 86400_i64 * days
487 hours = total_whole / 3600_i64
488 total_whole = total_whole - 3600_i64 * hours
489 minutes = total_whole / 60_i64
490 seconds_whole = total_whole - 60_i64 * minutes
492 second_value =
real(seconds_whole, kind=dp) + frac_seconds
493 if (second_value .ge. 60.0_dp)
then
494 second_value = second_value - 60.0_dp
495 minutes = minutes + 1_i64
496 if (minutes .ge. 60_i64)
then
497 minutes = minutes - 60_i64
498 hours = hours + 1_i64
499 if (hours .ge. 24_i64)
then
500 hours = hours - 24_i64
506 select case (n_values)
508 runtime_values(1) =
real(days, kind=rp)
509 runtime_values(2) =
real(hours, kind=rp)
510 runtime_values(3) =
real(minutes, kind=rp)
511 runtime_values(4) =
real(second_value, kind=rp)
513 runtime_values(1) =
real(days * 24_i64 + hours, kind=rp)
514 runtime_values(2) =
real(minutes, kind=rp)
515 runtime_values(3) =
real(second_value, kind=rp)
517 runtime_values(1) =
real((days * 24_i64 + hours) * 60_i64 + &
519 runtime_values(2) =
real(second_value, kind=rp)
521 runtime_values(1) =
real(parsed_seconds, kind=rp)
527 result(runtime_seconds)
528 character(len=*),
intent(in) :: runtime_string
529 integer,
optional,
intent(out) :: ierr
530 character(len=:),
allocatable :: time_string
531 real(kind=dp) :: parsed_seconds, read_real
532 logical :: has_minutes, has_hours, has_days
533 integer :: read_int, ios, sep
535 if (
present(ierr)) ierr = 0
537 runtime_seconds = 0.0_dp
538 time_string = trim(adjustl(runtime_string))
540 sep = index(time_string,
':')
541 has_minutes = sep .gt. 0
543 if (has_minutes .and. sep .lt. len_trim(time_string))
then
544 has_hours = index(time_string(sep + 1:len_trim(time_string)),
':') &
547 has_days = index(time_string,
'-') .gt. 0
549 if ((has_days .and. .not. has_hours) .or. &
550 (has_hours .and. .not. has_minutes))
then
555 parsed_seconds = 0.0_dp
559 sep = index(time_string,
'-')
560 read(time_string(1:sep - 1), *, iostat=ios) read_int
561 if (ios .ne. 0 .or. read_int .lt. 0)
then
563 'Error parsing duration: Invalid days value', ierr)
567 time_string = time_string(sep + 1:)
568 parsed_seconds = parsed_seconds +
real(86400 * read_int, kind=dp)
573 sep = index(time_string,
':')
574 read(time_string(1:sep - 1), *, iostat=ios) read_int
575 if (ios .ne. 0 .or. read_int .lt. 0 .or. &
576 (has_days .and. read_int .gt. 23))
then
578 'Error parsing duration: Invalid hours value', ierr)
582 time_string = time_string(sep + 1:)
583 parsed_seconds = parsed_seconds +
real(3600 * read_int, kind=dp)
587 if (has_minutes)
then
588 sep = index(time_string,
':')
589 read(time_string(1:sep - 1), *, iostat=ios) read_int
590 if (ios .ne. 0 .or. read_int .lt. 0 .or. &
591 (has_hours .and. read_int .gt. 59))
then
593 'Error parsing duration: Invalid minutes value', ierr)
597 time_string = time_string(sep + 1:)
598 parsed_seconds = parsed_seconds +
real(60 * read_int, kind=dp)
602 read(time_string, *, iostat=ios) read_real
603 if (ios .ne. 0 .or. read_real .lt. 0.0_dp .or. &
604 (has_minutes .and. read_real .ge. 60.0_dp))
then
606 'Error parsing duration: Invalid seconds value', ierr)
610 parsed_seconds = parsed_seconds + read_real
611 runtime_seconds = parsed_seconds
613 if (
allocated(time_string))
deallocate(time_string)
618 character(len=*),
intent(in) :: message
619 integer,
optional,
intent(out) :: ierr
621 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.