Neko 1.99.3
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=rp) :: 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=rp), 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 integer :: i
97
98 call fld_file%init(trim(fld_fname))
99
100 call fld_data%init()
101 call fld_data_avg%init()
102
103 call fld_file%read(fld_data_avg)
104
105 write (log_buf, '(A, g0)') "dt: ", fld_data_avg%time - start_time
106 call neko_log%message(log_buf)
107
108 call fld_data_avg%scale(fld_data_avg%time-start_time)
109
110 do i = 1, fld_data_avg%meta_nsamples-1
111 call fld_file%read(fld_data)
112 call fld_data%scale(fld_data%time-fld_data_avg%time)
113 call fld_data_avg%add(fld_data)
114
115 write (log_buf, '(A, g0)') "dt: ", fld_data%time - fld_data_avg%time
116 call neko_log%message(log_buf)
117
118 fld_data_avg%time = fld_data%time
119 end do
120 call fld_data_avg%scale(1.0_rp/(fld_data_avg%time-start_time))
121
122 call output_file%init(trim(output_fname))
123
124 call neko_log%message('Writing file: ' // trim(output_fname))
125 call output_file%write(fld_data_avg, fld_data_avg%time)
126 call neko_log%message('Done')
127
128 call fld_data%free()
129 call fld_data_avg%free()
130
131 end subroutine avg_flds_in_time_fld
132
149 subroutine avg_flds_in_time_csv(in_fname, out_fname, start_time)
150 character(len=NEKO_FNAME_LEN), intent(in) :: in_fname, out_fname
151 real(kind=rp), intent(in) :: start_time
152
153 type(file_t) :: out_file
154 type(matrix_t) :: data, avg_data
155 character(len=LOG_SIZE) :: log_buf
156 integer :: sample_size, n_samples
157
158 if (pe_rank .eq. 0) then
159
160 ! This will initialize and populate the matrix data
161 call populate_matrix(trim(in_fname), data)
162
163 ! Compute the size of a statistics sample
164 sample_size = determine_size_of_csv_sample(data)
165
166 if (mod(data%get_nrows(), sample_size) .ne. 0) then
167 write(log_buf,*) "# of rows in csv file : ", data%get_nrows()
168 call neko_log%message(log_buf)
169 write(log_buf,*) "Size of each sample : ", sample_size
170 call neko_log%message(log_buf)
171
172 call neko_error("The # of rows in the file must be a multiple" // &
173 " of the size of each sample.")
174 end if
175
176 n_samples = data%get_nrows() / sample_size
177 write (log_buf, '(A,I0)') "Size of each sample: ", sample_size
178 call neko_log%message(log_buf)
179 write (log_buf, '(A,I0)') "Number of samples : ", n_samples
180 call neko_log%message(log_buf)
181
182 ! Initialize the matrix for the averaged data
183 call avg_data%init(sample_size, data%get_ncols())
184
185 block
186 integer :: i
187 real(kind=rp) :: dt, ta, tb
188
189 tb = data%x(1,1) ! First time stamp
190 ta = start_time ! User defined
191 dt = tb - ta ! First "sampling length"
192 write (log_buf, '(A,I0,A,I0,A,g0)') "Length of sample ", 1, "/", &
193 n_samples, ": ", dt
194 call neko_log%message(log_buf)
195
196 ! First sample, scaled by the starting time
197 avg_data%x(:,1:) = dt*data%x(1:sample_size, :)
198
199 do i = 1, n_samples-1
200
201 ta = data%x(sample_size*(i-1) + 1, 1) ! Previous time stamp
202 tb = data%x(sample_size* i + 1, 1) ! Current time stamp
203 dt = tb - ta ! Sampling time for the current sample
204
205 write (log_buf, '(A,I0,A,I0,A,g0)') "Length of sample ", i+1, "/", &
206 n_samples, ": ", dt
207 call neko_log%message(log_buf)
208
209 avg_data%x = avg_data%x + &
210 dt * data%x(sample_size*i + 1:sample_size * (i+1), :)
211 end do
212
213 ! Final rescaling with the total length of signal
214 avg_data%x = avg_data%x / (data%x(data%get_nrows(), 1) - start_time)
215
216 ! Set the final time
217 avg_data%x(:,1) = data%x(data%get_nrows(), 1)
218
219 ! Load the spatial coordinates in the second column
220 avg_data%x(:, 2) = data%x(1:sample_size, 2)
221
222 end block
223
224 ! Write the final averaged fields
225 call out_file%init(trim(out_fname))
226 call out_file%set_overwrite(.true.)
227 call out_file%write(avg_data)
228 call file_free(out_file)
229
230 call data%free()
231 call avg_data%free()
232
233 end if
234
235 end subroutine avg_flds_in_time_csv
236
238 function determine_size_of_csv_sample(m) result(n)
239 type(matrix_t), intent(in) :: m
240 integer :: n
241
242 ! Guard in case the csv file has only 1 row or no rows at all.
243 if (m%get_nrows() .le. 1) then
244 n = m%get_nrows()
245 return
246 end if
247
248 n = 1
249 ! Increment n while the time stamps (in the first column) have the same value
250 do while ( abscmp(m%x(n,1), m%x(n+1,1)) )
251 n = n + 1
252 if (n+1 > m%get_nrows()) &
253 call neko_error("Out of bounds while searching for sampling size!")
254 end do
255
257
260 subroutine populate_matrix(file_name, m)
261 character(len=*), intent(in) :: file_name
262 type(matrix_t), intent(inout) :: m
263
264 type(file_t) :: f
265 integer :: unit, i, ierr, num_columns, num_lines, ios
266 character(len=1000) :: line
267 character(len=1) :: delimiter
268 character(len=LOG_SIZE) :: log_buf
269 delimiter = ','
270
271 !
272 ! Count lines and columns for initialization
273 !
274 open(newunit = unit, file = trim(file_name), status = 'old', &
275 action = 'read', iostat = ios)
276 if (ios /= 0) then
277 call neko_error("Error opening file " // trim(file_name))
278 end if
279
280 num_columns = 1
281 num_lines = 0
282
283 ! Read the file line by line
284 do
285 read(unit, '(A)', iostat = ios) line
286 if (ios /= 0) exit
287
288 ! If it's the first line, count the columns
289 if (num_lines .eq. 0) then
290
291 ! Count the number of delimiters in the line
292 do i = 1, len_trim(line)
293 if (line(i:i) == delimiter) then
294 num_columns = num_columns + 1
295 end if
296 end do
297
298 end if ! if num_columns .eq. 1
299
300 num_lines = num_lines + 1
301 end do
302
303 ! Close the file
304 close(unit)
305
306 write (log_buf, '(A,A,A,I0,A,I0,A)') "Size of ", trim(file_name), &
307 " : ", num_lines, " rows, ", num_columns, " columns"
308 call neko_log%message(log_buf)
309
310 !
311 ! Reading of the inflow profile
312 !
313 call m%init(num_lines, num_columns)
314
315 ! Read csv file and broadcast to all ranks since csv is only read in serial
316 call f%init(trim(file_name))
317 call f%read(m)
318 call file_free(f)
319
320 end subroutine populate_matrix
321
322
323end 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.
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()