Neko 1.99.1
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
utils.f90
Go to the documentation of this file.
1! Copyright (c) 2019-2021, The Neko Authors
2! All rights reserved.
3!
4! Redistribution and use in source and binary forms, with or without
5! modification, are permitted provided that the following conditions
6! are met:
7!
8! * Redistributions of source code must retain the above copyright
9! notice, this list of conditions and the following disclaimer.
10!
11! * Redistributions in binary form must reproduce the above
12! copyright notice, this list of conditions and the following
13! disclaimer in the documentation and/or other materials provided
14! with the distribution.
15!
16! * Neither the name of the authors nor the names of its
17! contributors may be used to endorse or promote products derived
18! from this software without specific prior written permission.
19!
20! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23! FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24! COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25! INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26! BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27! LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28! CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29! LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30! ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31! POSSIBILITY OF SUCH DAMAGE.
32!
35module utils
36 use, intrinsic :: iso_fortran_env, only: error_unit, output_unit
37 implicit none
38 private
39
40 integer, parameter :: neko_fname_len = 1024
41
42 interface neko_error
43 module procedure neko_error_plain, neko_error_msg
44 end interface neko_error
45
51
52
53contains
54
56 pure function filename_suffix_pos(fname) result(suffix_pos)
57 character(len=*), intent(in) :: fname
58 integer :: suffix_pos
59 suffix_pos = scan(trim(fname), '.', back = .true.)
60 end function filename_suffix_pos
61
63 pure function filename_tslash_pos(fname) result(tslash_pos)
64 character(len=*), intent(in) :: fname
65 integer :: tslash_pos
66 tslash_pos = scan(trim(fname), '/', back = .true.)
67 end function filename_tslash_pos
68
70 subroutine filename_suffix(fname, suffix)
71 character(len=*) :: fname
72 character(len=*) :: suffix
73 suffix = trim(fname(filename_suffix_pos(fname) + 1:len_trim(fname)))
74 end subroutine filename_suffix
75
77 subroutine filename_chsuffix(fname, new_fname, new_suffix)
78 character(len=*) :: fname
79 character(len=*) :: new_fname
80 character(len=*) :: new_suffix
81 integer :: suffix_pos
82
83 suffix_pos = filename_suffix_pos(fname)
84 new_fname = trim(fname(1:suffix_pos))//new_suffix
85
86 end subroutine filename_chsuffix
87
94 function extract_fld_file_index(fld_filename, default_index) result(index)
95 character(len=*), intent(in) :: fld_filename
96 integer, intent(in) :: default_index
97
98 character(len=80) :: suffix
99 integer :: index, fpos, i
100 logical :: valid
101
102 call filename_suffix(fld_filename, suffix)
103
104 valid = .true.
105
106 ! This value will be modified when reading the file name extension
107 ! e.g. "field0.f00035" will set sample_idx = 35
108 index = default_index
109
110 !
111 ! Try to extract the index of the field file from the suffix "fxxxxx"
112 !
113 fpos = scan(trim(suffix), 'f')
114 if (fpos .eq. 1) then
115 ! Make sure that the suffix only contains integers from 0 to 9
116 do i = 2, len(trim(suffix))
117 if (.not. (iachar(suffix(i:i)) >= iachar('0') &
118 .and. iachar(suffix(i:i)) <= iachar('9'))) then
119 valid = .false.
120 end if
121 end do
122 else
123 valid = .false.
124 end if
125
126 ! Must be exactly 6 characters long, i.e. an 'f' with 5 integers after
127 if (len(trim(suffix)) .ne. 6) valid = .false.
128
129 if (valid) read (suffix(2:), "(I5.5)") index
130
131 end function extract_fld_file_index
132
136 function split_string(string, delimiter) result(split_str)
137 character(len=*) :: string
138 character(len=*) :: delimiter
139 character(len=100), allocatable :: split_str(:)
140 integer :: length, i, i2, offset, j
141 i = 0
142 offset = 1
143 length = 1
144 if (len(trim(string)) .eq. 0) then
145 allocate(split_str(1))
146 split_str(1) = trim(string)
147 return
148 end if
149 do while (.true.)
150 i = scan(string(offset:), delimiter, back = .false.)
151 if (i .eq. 0) exit
152 length = length + 1
153 offset = offset + i
154 end do
155
156 allocate(split_str(length))
157 i = 0
158 j = 1
159 offset = 1
160 do while (.true.)
161 i2 = scan(trim(string(offset:)), delimiter, back = .false.)
162 if (i2 .eq. 0) then
163 split_str(j) = trim(string(offset:))
164 exit
165 end if
166 split_str(j) = trim(string(offset:offset+i2-2))
167 offset = offset+i2
168 j = j + 1
169 end do
170 end function split_string
171
174 pure function linear_index(i, j, k, l, lx, ly, lz) result(index)
175 integer, intent(in) :: i, j, k, l, lx, ly, lz
176 integer :: index
177
178 index = (i + lx * ((j - 1) + ly * ((k - 1) + lz * ((l - 1)))))
179 end function linear_index
180
183 pure function nonlinear_index(linear_index, lx, ly, lz) result(index)
184 integer, intent(in) :: linear_index, lx, ly, lz
185 integer :: index(4)
186 integer :: lin_idx
187 lin_idx = linear_index -1
188 index(4) = lin_idx/(lx*ly*lz)
189 index(3) = (lin_idx-(lx*ly*lz)*index(4))/(lx*ly)
190 index(2) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3))/lx
191 index(1) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3)-lx*index(2))
192 index(1) = index(1) + 1
193 index(2) = index(2) + 1
194 index(3) = index(3) + 1
195 index(4) = index(4) + 1
196
197 end function nonlinear_index
198
199 pure function index_is_on_facet(i, j, k, lx, ly, lz, facet) result(is_on)
200 integer, intent(in) :: i, j, k, lx, ly, lz, facet
201 logical :: is_on
202
203 is_on = .false.
204 select case (facet)
205 case (1)
206 if (i .eq. 1) is_on = .true.
207 case (2)
208 if (i .eq. lx) is_on = .true.
209 case (3)
210 if (j .eq. 1) is_on = .true.
211 case (4)
212 if (j .eq. ly) is_on = .true.
213 case (5)
214 if (k .eq. 1) is_on = .true.
215 case (6)
216 if (k .eq. lz) is_on = .true.
217 end select
218
219 end function index_is_on_facet
220
223 subroutine neko_error_plain(error_code)
224 integer, optional :: error_code
225
226 if (present(error_code)) then
227 write(error_unit, *) '*** ERROR ***', error_code
228 error stop
229 else
230 write(error_unit, *) '*** ERROR ***'
231 error stop
232 end if
233
234 end subroutine neko_error_plain
235
238 subroutine neko_error_msg(error_msg)
239 character(len=*) :: error_msg
240 write(error_unit, *) '*** ERROR: ', error_msg, ' ***'
241 error stop
242 end subroutine neko_error_msg
243
250 subroutine neko_type_error(base_type, wrong_type, known_types)
251 character(len=*), intent(in) :: base_type
252 character(len=*), intent(in) :: wrong_type
253 character(len=*), intent(in) :: known_types(:)
254 integer :: i
255
256 write(error_unit, *) '*** ERROR WHEN SELECTING TYPE ***'
257 write(error_unit, *) 'Type ', wrong_type, ' does not exist for ', base_type
258 write(error_unit, *) 'Valid types are:'
259 do i = 1, size(known_types)
260 write(error_unit, *) " ", known_types(i)
261 end do
262 error stop
263 end subroutine neko_type_error
264
265 subroutine neko_type_registration_error(base_type, wrong_type, known)
266 character(len=*), intent(in) :: base_type
267 character(len=*),intent(in) :: wrong_type
268 logical, intent(in) :: known
269
270 write(error_unit, *) '*** ERROR WHEN REGISTERING TYPE ***'
271 write(error_unit, *) 'Type name ', wrong_type, &
272 ' conflicts with and already existing ', base_type, " type"
273 if (known) then
274 write(error_unit, *) 'Please rename your custom type.'
275 else
276 write(error_unit, *) 'The already existing type is also custom.' // &
277 ' Make all custom type names unique!'
278 end if
279 error stop
280 end subroutine neko_type_registration_error
281
283 subroutine neko_warning(warning_msg)
284 character(len=*) :: warning_msg
285 write(output_unit, *) '*** WARNING: ', warning_msg, ' ***'
286 end subroutine neko_warning
287
293 function concat_string_array(array, sep, prepend) result(result)
294 character(len=*), intent(in) :: array(:)
295 character(len=*), intent(in) :: sep
296 logical, intent(in) :: prepend
297 character(:), allocatable :: result
298 integer :: i
299
300 result = trim(array(1))
301 do i = 2, size(array)
302 result = result // sep // trim(array(i))
303 end do
304
305 if (prepend .eqv. .true.) then
306 result = sep // result
307 end if
308
309 end function concat_string_array
310
311end module utils
__inline__ __device__ void nonlinear_index(const int idx, const int lx, int *index)
Definition bc_utils.h:44
Utilities.
Definition utils.f90:35
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...
Definition utils.f90:95
character(:) function, allocatable, public concat_string_array(array, sep, prepend)
Concatenate an array of strings into one string with array items separated by spaces.
Definition utils.f90:294
subroutine, public neko_type_registration_error(base_type, wrong_type, known)
Definition utils.f90:266
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,...
Definition utils.f90:137
pure logical function, public index_is_on_facet(i, j, k, lx, ly, lz, facet)
Definition utils.f90:200
subroutine neko_error_msg(error_msg)
Reports an error and stops execution.
Definition utils.f90:239
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, :)
Definition utils.f90:175
integer, parameter, public neko_fname_len
Definition utils.f90:40
subroutine, public neko_warning(warning_msg)
Reports a warning to standard output.
Definition utils.f90:284
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Definition utils.f90:78
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
Definition utils.f90:71
subroutine, public neko_type_error(base_type, wrong_type, known_types)
Reports an error allocating a type for a particular base pointer class.
Definition utils.f90:251
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
Definition utils.f90:64
subroutine neko_error_plain(error_code)
Reports an error and stops execution.
Definition utils.f90:224
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition utils.f90:57