Neko 1.99.9
A portable framework for high-order spectral element flow simulations
Loading...
Searching...
No Matches
average_fields_in_time.f90
Go to the documentation of this file.
1
4 use neko
5 implicit none
6
7 character(len=NEKO_FNAME_LEN) :: in_fname, out_fname, inputchar
8 character(len=80) :: extension
9 real(kind=dp) :: start_time
10 integer :: argc
11
12 argc = command_argument_count()
13
14 if ((argc .lt. 3) .or. (argc .gt. 3)) then
15 call usage()
16 stop
17 end if
18
19 call neko_init
20
21 call get_command_argument(1, inputchar)
22 read(inputchar, *) in_fname
23 call get_command_argument(2, inputchar)
24 read(inputchar, *) start_time
25 call get_command_argument(3, inputchar)
26 read(inputchar, *) out_fname
27
28 call filename_suffix(in_fname, extension)
29 select case (trim(extension))
30 case ("csv")
31 call avg_flds_in_time_csv(in_fname, out_fname, start_time)
32 case ("fld")
33 call avg_flds_in_time_fld(in_fname, out_fname, start_time)
34 case default
35 block
36 character(len=LOG_SIZE) :: log_buf
37 write (log_buf, *) trim(extension), " files not supported!"
38 call neko_warning(log_buf)
39 end block
40
41 call usage()
42 end select
43
44 call neko_finalize
45
46contains
47
48 subroutine usage()
49 if (pe_rank .eq. 0) then
50 write(*,*)
51 write(*,*) 'average_fields_in_time: Computes a weighted average of a '
52 write(*,*) 'set of statistics samples in time.'
53 write(*,*)
54 write(*,*) 'Usage:'
55 write(*,*) '==========================================================='
56 write(*,*) ' ./average_fields_in_time input.fld start_time output.fld'
57 write(*,*) ' ./average_fields_in_time input.csv start_time output.csv'
58 write(*,*)
59 write(*,*) ' start_time is the time at which the first file starts to '
60 write(*,*) ' collect stats.'
61 write(*,*)
62 write(*,*) 'Examples:'
63 write(*,*) '==========================================================='
64 write(*,*) ' ./average_fields_in_time fluid_stats00.fld 103.2 ' // &
65 'mean.fld'
66 write(*,*)
67 write(*,*) ' Computes the average field over the fld files ' // &
68 'described '
69 write(*,*) ' in fluid_stats00.nek5000. The files need to be arranged'
70 write(*,*) ' in chronological order. The average field is then '
71 write(*,*) ' stored in a fld series, i.e. mean0.nek5000 and'
72 write(*,*) ' mean0.f00000'
73 write(*,*)
74
75 write(*,*) ' ./average_fields_in_time ' // &
76 'stats0.csv 103.2 mean_field_avg.csv'
77 write(*,*)
78 write(*,*) ' Computes the average field over the csv file'
79 write(*,*) ' stats0.csv and writes it in mean_field_avg.csv'
80 end if
81 end subroutine usage
82
89 subroutine avg_flds_in_time_fld(fld_fname, output_fname, start_time)
90 character(len=NEKO_FNAME_LEN), intent(in) :: fld_fname, output_fname
91 real(kind=dp), intent(in) :: start_time
92
93 type(file_t) :: fld_file, output_file
94 type(fld_file_data_t) :: fld_data, fld_data_avg
95 character(len=LOG_SIZE) :: log_buf
96 real(kind=rp) :: dt
97 integer :: i
98
99 call fld_file%init(trim(fld_fname))
100
101 call fld_data%init()
102 call fld_data_avg%init()
103
104 call fld_file%read(fld_data_avg)
105
106 write (log_buf, '(A, g0)') "dt: ", fld_data_avg%time - start_time
107 call neko_log%message(log_buf)
108
109 dt = real(fld_data_avg%time - start_time, kind=rp)
110 call fld_data_avg%scale(dt)
111
112 do i = 1, fld_data_avg%meta_nsamples-1
113 call fld_file%read(fld_data)
114
115 dt = real(fld_data%time - fld_data_avg%time, kind=rp)
116 call fld_data%scale(dt)
117 call fld_data_avg%add(fld_data)
118
119 write (log_buf, '(A, g0)') "dt: ", dt
120 call neko_log%message(log_buf)
121
122 fld_data_avg%time = fld_data%time
123 end do
124
125 ! Divide the sum by the total length of the signal
126 dt = real(1.0_dp/(fld_data_avg%time-start_time), kind=rp)
127 call fld_data_avg%scale(dt)
128
129 call output_file%init(trim(output_fname))
130
131 call neko_log%message('Writing file: ' // trim(output_fname))
132 call output_file%write(fld_data_avg, fld_data_avg%time)
133 call neko_log%message('Done')
134
135 call fld_data%free()
136 call fld_data_avg%free()
137
138 end subroutine avg_flds_in_time_fld
139
156 subroutine avg_flds_in_time_csv(in_fname, out_fname, start_time)
157 character(len=NEKO_FNAME_LEN), intent(in) :: in_fname, out_fname
158 real(kind=dp), intent(in) :: start_time
159
160 type(file_t) :: out_file
161 type(matrix_t) :: data, avg_data
162 character(len=LOG_SIZE) :: log_buf
163 integer :: sample_size, n_samples
164
165 if (pe_rank .eq. 0) then
166
167 ! This will initialize and populate the matrix data
168 call populate_matrix(trim(in_fname), data)
169
170 ! Compute the size of a statistics sample
171 sample_size = determine_size_of_csv_sample(data)
172
173 if (mod(data%get_nrows(), sample_size) .ne. 0) then
174 write(log_buf,*) "# of rows in csv file : ", data%get_nrows()
175 call neko_log%message(log_buf)
176 write(log_buf,*) "Size of each sample : ", sample_size
177 call neko_log%message(log_buf)
178
179 call neko_error("The # of rows in the file must be a multiple" // &
180 " of the size of each sample.")
181 end if
182
183 n_samples = data%get_nrows() / sample_size
184 write (log_buf, '(A,I0)') "Size of each sample: ", sample_size
185 call neko_log%message(log_buf)
186 write (log_buf, '(A,I0)') "Number of samples : ", n_samples
187 call neko_log%message(log_buf)
188
189 ! Initialize the matrix for the averaged data
190 call avg_data%init(sample_size, data%get_ncols())
191
192 block
193 integer :: i
194 real(kind=dp) :: ta, tb
195 real(kind=rp) :: dt
196
197 tb = data%x(1,1) ! First time stamp
198 ta = start_time ! User defined
199 dt = real(tb - ta, kind=rp) ! First "sampling length"
200
201 write (log_buf, '(A,I0,A,I0,A,g0)') "Length of sample ", 1, "/", &
202 n_samples, ": ", dt
203 call neko_log%message(log_buf)
204
205 ! First sample, scaled by the starting time
206 avg_data%x(:,1:) = dt*data%x(1:sample_size, :)
207
208 do i = 1, n_samples-1
209
210 ta = data%x(sample_size*(i-1) + 1, 1) ! Previous time stamp
211 tb = data%x(sample_size* i + 1, 1) ! Current time stamp
212 dt = real(tb - ta, kind=rp) ! Sampling time for the current sample
213
214 write (log_buf, '(A,I0,A,I0,A,g0)') "Length of sample ", i+1, "/", &
215 n_samples, ": ", dt
216 call neko_log%message(log_buf)
217
218 avg_data%x = avg_data%x + &
219 dt * data%x(sample_size*i + 1:sample_size * (i+1), :)
220 end do
221
222 ! Final rescaling with the total length of signal
223 avg_data%x = avg_data%x / (data%x(data%get_nrows(), 1) - start_time)
224
225 ! Set the final time
226 avg_data%x(:,1) = data%x(data%get_nrows(), 1)
227
228 ! Load the spatial coordinates in the second column
229 avg_data%x(:, 2) = data%x(1:sample_size, 2)
230
231 end block
232
233 ! Write the final averaged fields
234 call out_file%init(trim(out_fname))
235 call out_file%set_overwrite(.true.)
236 call out_file%write(avg_data)
237 call file_free(out_file)
238
239 call data%free()
240 call avg_data%free()
241
242 end if
243
244 end subroutine avg_flds_in_time_csv
245
247 function determine_size_of_csv_sample(m) result(n)
248 type(matrix_t), intent(in) :: m
249 integer :: n
250
251 ! Guard in case the csv file has only 1 row or no rows at all.
252 if (m%get_nrows() .le. 1) then
253 n = m%get_nrows()
254 return
255 end if
256
257 n = 1
258 ! Increment n while the time stamps (in the first column) have the same value
259 do while ( abscmp(m%x(n,1), m%x(n+1,1)) )
260 n = n + 1
261 if (n+1 > m%get_nrows()) &
262 call neko_error("Out of bounds while searching for sampling size!")
263 end do
264
266
269 subroutine populate_matrix(file_name, m)
270 character(len=*), intent(in) :: file_name
271 type(matrix_t), intent(inout) :: m
272
273 type(file_t) :: f
274 integer :: unit, i, ierr, num_columns, num_lines, ios
275 character(len=1000) :: line
276 character(len=1) :: delimiter
277 character(len=LOG_SIZE) :: log_buf
278 delimiter = ','
279
280 !
281 ! Count lines and columns for initialization
282 !
283 open(newunit = unit, file = trim(file_name), status = 'old', &
284 action = 'read', iostat = ios)
285 if (ios /= 0) then
286 call neko_error("Error opening file " // trim(file_name))
287 end if
288
289 num_columns = 1
290 num_lines = 0
291
292 ! Read the file line by line
293 do
294 read(unit, '(A)', iostat = ios) line
295 if (ios /= 0) exit
296
297 ! If it's the first line, count the columns
298 if (num_lines .eq. 0) then
299
300 ! Count the number of delimiters in the line
301 do i = 1, len_trim(line)
302 if (line(i:i) == delimiter) then
303 num_columns = num_columns + 1
304 end if
305 end do
306
307 end if ! if num_columns .eq. 1
308
309 num_lines = num_lines + 1
310 end do
311
312 ! Close the file
313 close(unit)
314
315 write (log_buf, '(A,A,A,I0,A,I0,A)') "Size of ", trim(file_name), &
316 " : ", num_lines, " rows, ", num_columns, " columns"
317 call neko_log%message(log_buf)
318
319 !
320 ! Reading of the inflow profile
321 !
322 call m%init(num_lines, num_columns)
323
324 ! Read csv file and broadcast to all ranks since csv is only read in serial
325 call f%init(trim(file_name))
326 call f%read(m)
327 call file_free(f)
328
329 end subroutine populate_matrix
330
331
332end program average_fields_in_time
subroutine usage()
subroutine avg_flds_in_time_fld(fld_fname, output_fname, start_time)
Average fields from a series of fld files.
subroutine populate_matrix(file_name, m)
Read a csv file, determine the # of rows and columns, allocate the matrix accordingly and populate th...
subroutine avg_flds_in_time_csv(in_fname, out_fname, start_time)
Average fields from a series of csv files.
integer function determine_size_of_csv_sample(m)
Finds the size of a statistics sample based on when the time stamp changes.
program average_fields_in_time
Program to sum up averaged fields computed for statistics and mean field Martin Karp 27/01-23.
double real
Module for file I/O operations.
Definition file.f90:34
NEKTON fld file format.
Definition fld_file.f90:35
Master module.
Definition neko.f90:34
void neko_finalize()
void neko_init()