Neko  0.8.99
A portable framework for high-order spectral element flow simulations
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 !
35 module utils
36  implicit none
37  private
38 
39  integer, parameter :: neko_fname_len = 1024
40 
41  interface neko_error
42  module procedure neko_error_plain, neko_error_msg
43  end interface neko_error
44 
49 
50 
51 contains
52 
54  pure function filename_suffix_pos(fname) result(suffix_pos)
55  character(len=*), intent(in) :: fname
56  integer :: suffix_pos
57  suffix_pos = scan(trim(fname), '.', back=.true.)
58  end function filename_suffix_pos
59 
61  pure function filename_tslash_pos(fname) result(tslash_pos)
62  character(len=*), intent(in) :: fname
63  integer :: tslash_pos
64  tslash_pos = scan(trim(fname), '/', back=.true.)
65  end function filename_tslash_pos
66 
68  subroutine filename_suffix(fname, suffix)
69  character(len=*) :: fname
70  character(len=*) :: suffix
71  suffix = trim(fname(filename_suffix_pos(fname) + 1:len_trim(fname)))
72  end subroutine filename_suffix
73 
75  subroutine filename_chsuffix(fname, new_fname, new_suffix)
76  character(len=*) :: fname
77  character(len=*) :: new_fname
78  character(len=*) :: new_suffix
79  integer :: suffix_pos
80 
81  suffix_pos = filename_suffix_pos(fname)
82  new_fname = trim(fname(1:suffix_pos))//new_suffix
83 
84  end subroutine filename_chsuffix
85 
88  function split_string(string, delimiter) result(split_str)
89  character(len=*) :: string
90  character(len=*) :: delimiter
91  character(len=100), allocatable :: split_str(:)
92  integer :: length, i, i2,offset, j
93  i = 0
94  offset = 1
95  length = 1
96  if (len(trim(string)) .eq. 0) then
97  allocate(split_str(1))
98  split_str(1) = trim(string)
99  return
100  end if
101  do while( .true.)
102  i = scan(string(offset:), delimiter, back=.false.)
103  if (i .eq. 0) exit
104  length = length + 1
105  offset = offset + i
106  end do
107 
108  allocate(split_str(length))
109  i = 0
110  j = 1
111  offset=1
112  do while( .true.)
113  i2 = scan(trim(string(offset:)), delimiter, back=.false.)
114  if (i2 .eq. 0) then
115  split_str(j) = trim(string(offset:))
116  exit
117  end if
118  split_str(j) = trim(string(offset:offset+i2-2))
119  offset = offset+i2
120  j = j + 1
121  end do
122  end function split_string
123 
124 
125 
126 
129  pure function linear_index(i,j,k,l,lx,ly,lz) result(index)
130  integer, intent(in) :: i, j, k, l, lx, ly, lz
131  integer :: index
132 
133  index = (i + lx * ((j - 1) + ly * ((k - 1) + lz * ((l - 1)))))
134  end function linear_index
135 
136  pure function index_is_on_facet(i, j, k, lx, ly, lz, facet) result(is_on)
137  integer, intent(in) :: i, j, k, lx, ly, lz, facet
138  logical :: is_on
139 
140  is_on = .false.
141  select case(facet)
142  case(1)
143  if (i .eq. 1) is_on = .true.
144  case(2)
145  if (i .eq. lx) is_on = .true.
146  case(3)
147  if (j .eq. 1) is_on = .true.
148  case(4)
149  if (j .eq. ly) is_on = .true.
150  case(5)
151  if (k .eq. 1) is_on = .true.
152  case(6)
153  if (k .eq. lz) is_on = .true.
154  end select
155 
156 
157  end function index_is_on_facet
158 
159 
162  pure function nonlinear_index(linear_index,lx,ly,lz) result(index)
163  integer, intent(in) :: linear_index, lx, ly, lz
164  integer :: index(4)
165  integer :: lin_idx
166  lin_idx = linear_index -1
167  index(4) = lin_idx/(lx*ly*lz)
168  index(3) = (lin_idx-(lx*ly*lz)*index(4))/(lx*ly)
169  index(2) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3))/lx
170  index(1) = (lin_idx-(lx*ly*lz)*index(4)-(lx*ly)*index(3)-lx*index(2))
171  index(1) = index(1) + 1
172  index(2) = index(2) + 1
173  index(3) = index(3) + 1
174  index(4) = index(4) + 1
175 
176  end function nonlinear_index
177 
178  subroutine neko_error_plain(error_code)
179  integer, optional :: error_code
180 
181  if (present(error_code)) then
182  write(*,*) '*** ERROR ***', error_code
183  error stop
184  else
185  write(*,*) '*** ERROR ***'
186  error stop
187  end if
188 
189  end subroutine neko_error_plain
190 
191  subroutine neko_error_msg(error_msg)
192  character(len=*) :: error_msg
193  write(*,*) '*** ERROR: ', error_msg,' ***'
194  error stop
195  end subroutine neko_error_msg
196 
197  subroutine neko_warning(warning_msg)
198  character(len=*) :: warning_msg
199  write(*,*) '*** WARNING: ', warning_msg,' ***'
200  end subroutine neko_warning
201 
207  function concat_string_array(array, sep, prepend) result(result)
208  character(len=*), intent(in) :: array(:)
209  character(len=*), intent(in) :: sep
210  logical, intent(in) :: prepend
211  character(:), allocatable :: result
212  integer :: i
213 
214  result = trim(array(1))
215  do i=2, size(array)
216  result = result // sep // trim(array(i))
217  end do
218 
219  if (prepend .eqv. .true.) then
220  result = sep // result
221  end if
222 
223  end function concat_string_array
224 
225 end module utils
__device__ void nonlinear_index(const int idx, const int lx, int *index)
Utilities.
Definition: utils.f90:35
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:208
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:89
pure logical function, public index_is_on_facet(i, j, k, lx, ly, lz, facet)
Definition: utils.f90:137
subroutine neko_error_msg(error_msg)
Definition: utils.f90:192
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:130
integer, parameter, public neko_fname_len
Definition: utils.f90:39
subroutine, public neko_warning(warning_msg)
Definition: utils.f90:198
subroutine, public filename_chsuffix(fname, new_fname, new_suffix)
Change a filename's suffix.
Definition: utils.f90:76
subroutine, public filename_suffix(fname, suffix)
Extract a filename's suffix.
Definition: utils.f90:69
pure integer function, public filename_tslash_pos(fname)
Find position (in the string) of a filename's trailing slash.
Definition: utils.f90:62
subroutine neko_error_plain(error_code)
Definition: utils.f90:179
pure integer function, public filename_suffix_pos(fname)
Find position (in the string) of a filename's suffix.
Definition: utils.f90:55