MFC
Exascale flow solver
Loading...
Searching...
No Matches
m_data_output.fpp.f90
Go to the documentation of this file.
1# 1 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
2!>
3!! @file
4!! @brief Contains module m_data_output
5
6!> @brief Writes post-processed grid and flow-variable data to Silo-HDF5 or binary database files
8
12 use m_mpi_proxy
14 use m_helper
16
17 implicit none
18
25
26 ! Include Silo-HDF5 interface library
27 include 'silo_f9x.inc'
28
29 ! Flow variable storage; q_root_sf gathers to rank 0 in 1D parallel runs
30 real(wp), allocatable, dimension(:,:,:), public :: q_sf
31 real(wp), allocatable, dimension(:,:,:) :: q_root_sf
32 real(wp), allocatable, dimension(:,:,:) :: cyl_q_sf
33
34 ! Single precision storage for flow variables
35 real(sp), allocatable, dimension(:,:,:), public :: q_sf_s
36 real(sp), allocatable, dimension(:,:,:) :: q_root_sf_s
37 real(sp), allocatable, dimension(:,:,:) :: cyl_q_sf_s
38
39 ! Spatial and data extents for VisIt visualization
40 real(wp), allocatable, dimension(:,:) :: spatial_extents
41 real(wp), allocatable, dimension(:,:) :: data_extents
42
43 ! Ghost zone layer sizes (lo/hi) for subdomain connectivity in VisIt
44 integer, allocatable, dimension(:) :: lo_offset
45 integer, allocatable, dimension(:) :: hi_offset
46
47 ! Track cell-boundary count per active coordinate direction
48 integer, allocatable, dimension(:) :: dims
49
50 ! Locations of various folders in the case's directory tree, associated with the choice of the formatted database format. These
51 ! include, in order, the location of the folder named after the selected formatted database format, and the locations of two
52 ! sub-directories of the latter, the first of which is named after the local processor rank, while the second is named 'root'.
53 ! The folder associated with the local processor rank contains only the data pertaining to the part of the domain taken care of
54 ! by the local processor. The root directory, on the other hand, will contain either the information about the connectivity
55 ! required to put the entire domain back together, or the actual data associated with the entire computational domain. This all
56 ! depends on dimensionality and the choice of the formatted database format.
57 character(LEN=path_len + name_len) :: dbdir
58 character(LEN=path_len + 2*name_len) :: proc_rank_dir
59 character(LEN=path_len + 2*name_len) :: rootdir
60
61 ! Handles of the formatted database master/root file, slave/local processor file and options list. The list of options is
62 ! explicitly used in the Silo- HDF5 database format to provide additional details about the contents of a formatted database
63 ! file, such as the previously described spatial and data extents.
64 integer :: dbroot
65 integer :: dbfile
66 integer :: optlist
67
68 ! The total number of flow variable(s) to be stored in a formatted database file. Note that this is only needed when using the
69 ! Binary format.
70 integer :: dbvars
71
72 ! Generic error flags utilized in the handling, checking and the reporting of the input and output operations errors with a
73 ! formatted database file
74 integer, private :: err
75
76contains
77
78 !> Allocate storage arrays, configure output directories, and count flow variables for formatted database output.
80
81 character(LEN=len_trim(case_dir) + 2*name_len) :: file_loc
82 logical :: dir_check
83 integer :: i
84
85 allocate (q_sf(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end))
86 if (grid_geometry == 3) then
87 allocate (cyl_q_sf(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end))
88 end if
89
90 if (precision == 1) then
91 allocate (q_sf_s(-offset_x%beg:m + offset_x%end,-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end))
92 if (grid_geometry == 3) then
93 allocate (cyl_q_sf_s(-offset_y%beg:n + offset_y%end,-offset_z%beg:p + offset_z%end,-offset_x%beg:m + offset_x%end))
94 end if
95 end if
96
97 if (n == 0) then
98 allocate (q_root_sf(0:m_root,0:0,0:0))
99 if (precision == 1) then
100 allocate (q_root_sf_s(0:m_root,0:0,0:0))
101 end if
102 end if
103
104 ! Allocating the spatial and data extents and also the variables for the offsets and the one bookkeeping the number of
105 ! cell-boundaries in each active coordinate direction. Note that all these variables are only needed by the Silo-HDF5 format
106 ! for multidimensional data.
107 if (format == 1) then
108 allocate (data_extents(1:2,0:num_procs - 1))
109
110 if (p > 0) then
111 allocate (spatial_extents(1:6,0:num_procs - 1))
112 allocate (lo_offset(1:3))
113 allocate (hi_offset(1:3))
114 allocate (dims(1:3))
115 else if (n > 0) then
116 allocate (spatial_extents(1:4,0:num_procs - 1))
117 allocate (lo_offset(1:2))
118 allocate (hi_offset(1:2))
119 allocate (dims(1:2))
120 else
121 allocate (spatial_extents(1:2,0:num_procs - 1))
122 allocate (lo_offset(1:1))
123 allocate (hi_offset(1:1))
124 allocate (dims(1:1))
125 end if
126 end if
127
128 ! The size of the ghost zone layer in each of the active coordinate directions was set in the module m_mpi_proxy.f90. The
129 ! results are now transferred to the local variables of this module when they are required by the Silo-HDF5 format, for
130 ! multidimensional data sets. With the same, latter, requirements, the variables bookkeeping the number of cell-boundaries
131 ! in each active coordinate direction are also set here.
132 if (format == 1) then
133 if (p > 0) then
134 if (grid_geometry == 3) then
135 lo_offset(:) = (/offset_y%beg, offset_z%beg, offset_x%beg/)
136 hi_offset(:) = (/offset_y%end, offset_z%end, offset_x%end/)
137 else
138 lo_offset(:) = (/offset_x%beg, offset_y%beg, offset_z%beg/)
139 hi_offset(:) = (/offset_x%end, offset_y%end, offset_z%end/)
140 end if
141
142 if (grid_geometry == 3) then
143 dims(:) = (/n + offset_y%beg + offset_y%end + 2, p + offset_z%beg + offset_z%end + 2, &
144 & m + offset_x%beg + offset_x%end + 2/)
145 else
146 dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2, &
147 & p + offset_z%beg + offset_z%end + 2/)
148 end if
149 else if (n > 0) then
150 lo_offset(:) = (/offset_x%beg, offset_y%beg/)
151 hi_offset(:) = (/offset_x%end, offset_y%end/)
152
153 dims(:) = (/m + offset_x%beg + offset_x%end + 2, n + offset_y%beg + offset_y%end + 2/)
154 else
155 lo_offset(:) = (/offset_x%beg/)
156 hi_offset(:) = (/offset_x%end/)
157 dims(:) = (/m + offset_x%beg + offset_x%end + 2/)
158 end if
159 end if
160
161 if (format == 1) then
162 dbdir = trim(case_dir) // '/silo_hdf5'
163
164 write (proc_rank_dir, '(A,I0)') '/p', proc_rank
165
166 proc_rank_dir = trim(dbdir) // trim(proc_rank_dir)
167
168 file_loc = trim(proc_rank_dir) // '/.'
169
170 call my_inquire(file_loc, dir_check)
171 if (dir_check .neqv. .true.) then
173 end if
174
175 if (proc_rank == 0) then
176 rootdir = trim(dbdir) // '/root'
177
178 file_loc = trim(rootdir) // '/.'
179
180 call my_inquire(file_loc, dir_check)
181 if (dir_check .neqv. .true.) then
182 call s_create_directory(trim(rootdir))
183 end if
184 end if
185 else
186 dbdir = trim(case_dir) // '/binary'
187
188 write (proc_rank_dir, '(A,I0)') '/p', proc_rank
189
190 proc_rank_dir = trim(dbdir) // trim(proc_rank_dir)
191
192 file_loc = trim(proc_rank_dir) // '/.'
193
194 call my_inquire(file_loc, dir_check)
195
196 if (dir_check .neqv. .true.) then
198 end if
199
200 if (n == 0 .and. proc_rank == 0) then
201 rootdir = trim(dbdir) // '/root'
202
203 file_loc = trim(rootdir) // '/.'
204
205 call my_inquire(file_loc, dir_check)
206
207 if (dir_check .neqv. .true.) then
208 call s_create_directory(trim(rootdir))
209 end if
210 end if
211 end if
212
213 if (bubbles_lagrange) then ! Lagrangian solver
214 if (lag_txt_wrt) then
215 dbdir = trim(case_dir) // '/lag_bubbles_post_process'
216 file_loc = trim(dbdir) // '/.'
217 call my_inquire(file_loc, dir_check)
218
219 if (dir_check .neqv. .true.) then
220 call s_create_directory(trim(dbdir))
221 end if
222 end if
223 end if
224
225 ! Contrary to the Silo-HDF5 database format, handles of the Binary database master/root and slave/local process files are
226 ! perfectly static throughout post-process. Hence, they are set here so that they do not have to be repetitively computed in
227 ! later procedures.
228 if (format == 2) then
229 if (n == 0 .and. proc_rank == 0) dbroot = 2
230 dbfile = 1
231 end if
232
233 if (format == 2) then
234 dbvars = 0
235
236 if ((model_eqns == 2) .or. (model_eqns == 3)) then
237 do i = 1, num_fluids
238 if (alpha_rho_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then
239 dbvars = dbvars + 1
240 end if
241 end do
242 end if
243
244 if ((rho_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) .and. (.not. relativity)) then
245 dbvars = dbvars + 1
246 end if
247
248 if (relativity .and. (rho_wrt .or. prim_vars_wrt)) dbvars = dbvars + 1
249 if (relativity .and. (rho_wrt .or. cons_vars_wrt)) dbvars = dbvars + 1
250
251 do i = 1, e_idx - mom_idx%beg
252 if (mom_wrt(i) .or. cons_vars_wrt) dbvars = dbvars + 1
253 end do
254
255 do i = 1, e_idx - mom_idx%beg
256 if (vel_wrt(i) .or. prim_vars_wrt) dbvars = dbvars + 1
257 end do
258
259 do i = 1, e_idx - mom_idx%beg
260 if (flux_wrt(i)) dbvars = dbvars + 1
261 end do
262
263 if (e_wrt .or. cons_vars_wrt) dbvars = dbvars + 1
264 if (pres_wrt .or. prim_vars_wrt) dbvars = dbvars + 1
265 if (hypoelasticity) dbvars = dbvars + (num_dims*(num_dims + 1))/2
266 if (cont_damage) dbvars = dbvars + 1
267 if (hyper_cleaning) dbvars = dbvars + 1
268
269 if (mhd) then
270 if (n == 0) then
271 dbvars = dbvars + 2
272 else
273 dbvars = dbvars + 3
274 end if
275 end if
276
277 if ((model_eqns == 2) .or. (model_eqns == 3)) then
278 do i = 1, num_fluids - 1
279 if (alpha_wrt(i) .or. (cons_vars_wrt .or. prim_vars_wrt)) then
280 dbvars = dbvars + 1
281 end if
282 end do
283
284 if (alpha_wrt(num_fluids) .or. (cons_vars_wrt .or. prim_vars_wrt)) then
285 dbvars = dbvars + 1
286 end if
287 end if
288
289 if (gamma_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then
290 dbvars = dbvars + 1
291 end if
292
293 if (heat_ratio_wrt) dbvars = dbvars + 1
294
295 if (pi_inf_wrt .or. (model_eqns == 1 .and. (cons_vars_wrt .or. prim_vars_wrt))) then
296 dbvars = dbvars + 1
297 end if
298
299 if (pres_inf_wrt) dbvars = dbvars + 1
300 if (c_wrt) dbvars = dbvars + 1
301
302 if (p > 0) then
303 do i = 1, num_vels
304 if (omega_wrt(i)) dbvars = dbvars + 1
305 end do
306 else if (n > 0) then
307 do i = 1, num_vels
308 if (omega_wrt(i)) dbvars = dbvars + 1
309 end do
310 end if
311
312 if (schlieren_wrt) dbvars = dbvars + 1
313 end if
314
316
317 !> Compute the cell-index bounds for the user-specified partial output domain in each coordinate direction.
318 impure subroutine s_define_output_region
319
320 integer :: i
321 integer :: lower_bound, upper_bound
322
323# 323 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
324 if (m == 0) return ! Early return for y or z if simulation is 1D or 2D
325
326 lower_bound = -offset_x%beg
327 upper_bound = m + offset_x%end
328
329 do i = lower_bound, upper_bound
330 if (x_cc(i) > x_output%beg) then
331 x_output_idx%beg = i + offset_x%beg
332 exit
333 end if
334 end do
335
336 do i = upper_bound, lower_bound, -1
337 if (x_cc(i) < x_output%end) then
338 x_output_idx%end = i + offset_x%beg
339 exit
340 end if
341 end do
342
343 ! If no grid points are within the output region
344 if ((x_cc(lower_bound) > x_output%end) .or. (x_cc(upper_bound) < x_output%beg)) then
345 x_output_idx%beg = 0
346 x_output_idx%end = 0
347 end if
348# 323 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
349 if (n == 0) return ! Early return for y or z if simulation is 1D or 2D
350
351 lower_bound = -offset_y%beg
352 upper_bound = n + offset_y%end
353
354 do i = lower_bound, upper_bound
355 if (y_cc(i) > y_output%beg) then
356 y_output_idx%beg = i + offset_y%beg
357 exit
358 end if
359 end do
360
361 do i = upper_bound, lower_bound, -1
362 if (y_cc(i) < y_output%end) then
363 y_output_idx%end = i + offset_y%beg
364 exit
365 end if
366 end do
367
368 ! If no grid points are within the output region
369 if ((y_cc(lower_bound) > y_output%end) .or. (y_cc(upper_bound) < y_output%beg)) then
370 y_output_idx%beg = 0
371 y_output_idx%end = 0
372 end if
373# 323 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
374 if (p == 0) return ! Early return for y or z if simulation is 1D or 2D
375
376 lower_bound = -offset_z%beg
377 upper_bound = p + offset_z%end
378
379 do i = lower_bound, upper_bound
380 if (z_cc(i) > z_output%beg) then
381 z_output_idx%beg = i + offset_z%beg
382 exit
383 end if
384 end do
385
386 do i = upper_bound, lower_bound, -1
387 if (z_cc(i) < z_output%end) then
388 z_output_idx%end = i + offset_z%beg
389 exit
390 end if
391 end do
392
393 ! If no grid points are within the output region
394 if ((z_cc(lower_bound) > z_output%end) .or. (z_cc(upper_bound) < z_output%beg)) then
395 z_output_idx%beg = 0
396 z_output_idx%end = 0
397 end if
398# 348 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
399
400 end subroutine s_define_output_region
401
402 !> Open (or create) the Silo-HDF5 or Binary formatted database slave and master files for a given time step.
403 impure subroutine s_open_formatted_database_file(t_step)
404
405 integer, intent(in) :: t_step
406 character(LEN=len_trim(case_dir) + 3*name_len) :: file_loc
407 integer :: ierr
408
409 if (format == 1) then
410 write (file_loc, '(A,I0,A)') '/', t_step, '.silo'
411 file_loc = trim(proc_rank_dir) // trim(file_loc)
412
413 ierr = dbcreate(trim(file_loc), len_trim(file_loc), db_clobber, db_local, 'MFC v3.0', 8, db_hdf5, dbfile)
414
415 if (dbfile == -1) then
416 call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'slave file ' // trim(file_loc) // '. ' // 'Exiting.')
417 end if
418
419 if (proc_rank == 0) then
420 write (file_loc, '(A,I0,A)') '/collection_', t_step, '.silo'
421 file_loc = trim(rootdir) // trim(file_loc)
422
423 ierr = dbcreate(trim(file_loc), len_trim(file_loc), db_clobber, db_local, 'MFC v3.0', 8, db_hdf5, dbroot)
424
425 if (dbroot == -1) then
426 call s_mpi_abort('Unable to create Silo-HDF5 database ' // 'master file ' // trim(file_loc) // '. ' &
427 & // 'Exiting.')
428 end if
429 end if
430 else
431 write (file_loc, '(A,I0,A)') '/', t_step, '.dat'
432 file_loc = trim(proc_rank_dir) // trim(file_loc)
433
434 open (dbfile, iostat=err, file=trim(file_loc), form='unformatted', status='replace')
435
436 if (err /= 0) then
437 call s_mpi_abort('Unable to create Binary database slave ' // 'file ' // trim(file_loc) // '. Exiting.')
438 end if
439
440 if (output_partial_domain) then
441 write (dbfile) x_output_idx%end - x_output_idx%beg, y_output_idx%end - y_output_idx%beg, &
442 & z_output_idx%end - z_output_idx%beg, dbvars
443 else
444 write (dbfile) m, n, p, dbvars
445 end if
446
447 if (n == 0 .and. proc_rank == 0) then
448 write (file_loc, '(A,I0,A)') '/', t_step, '.dat'
449 file_loc = trim(rootdir) // trim(file_loc)
450
451 open (dbroot, iostat=err, file=trim(file_loc), form='unformatted', status='replace')
452
453 if (err /= 0) then
454 call s_mpi_abort('Unable to create Binary database ' // 'master file ' // trim(file_loc) // '. Exiting.')
455 end if
456
457 if (output_partial_domain) then
458 write (dbroot) x_output_idx%end - x_output_idx%beg, 0, 0, dbvars
459 else
460 write (dbroot) m_root, 0, 0, dbvars
461 end if
462 end if
463 end if
464
465 end subroutine s_open_formatted_database_file
466
467 !> Open the interface data file for appending extracted interface coordinates.
468 impure subroutine s_open_intf_data_file()
469
470 character(LEN=path_len + 3*name_len) :: file_path
471
472 write (file_path, '(A)') '/intf_data.dat'
473 file_path = trim(case_dir) // trim(file_path)
474
475 open (211, file=trim(file_path), form='formatted', position='append', status='unknown')
476
477 end subroutine s_open_intf_data_file
478
479 !> Open the energy data file for appending volume-integrated energy budget quantities.
480 impure subroutine s_open_energy_data_file()
481
482 character(LEN=path_len + 3*name_len) :: file_path
483
484 write (file_path, '(A)') '/eng_data.dat'
485 file_path = trim(case_dir) // trim(file_path)
486
487 open (251, file=trim(file_path), form='formatted', position='append', status='unknown')
488
489 end subroutine s_open_energy_data_file
490
491 !> Write the computational grid (cell-boundary coordinates) to the formatted database slave and master files.
493
494 integer, intent(in) :: t_step
495
496 ! NAG compiler requires these to be statically sized
497 character(LEN=4*name_len), dimension(num_procs) :: meshnames
498 integer, dimension(num_procs) :: meshtypes
499 integer :: i
500 integer :: ierr
501
502 if (format == 1) then
503 ! For multidimensional data sets, the spatial extents of all of the grid(s) handled by the local processor(s) are
504 ! recorded so that they may be written, by root processor, to the formatted database master file.
505 if (num_procs > 1) then
507 else if (p > 0) then
508 if (grid_geometry == 3) then
509 spatial_extents(:,0) = (/minval(y_cb), minval(z_cb), minval(x_cb), maxval(y_cb), maxval(z_cb), maxval(x_cb)/)
510 else
511 spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), minval(z_cb), maxval(x_cb), maxval(y_cb), maxval(z_cb)/)
512 end if
513 else if (n > 0) then
514 spatial_extents(:,0) = (/minval(x_cb), minval(y_cb), maxval(x_cb), maxval(y_cb)/)
515 else
516 spatial_extents(:,0) = (/minval(x_cb), maxval(x_cb)/)
517 end if
518
519 ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In
520 ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the
521 ! master file.
522 if (proc_rank == 0) then
523 do i = 1, num_procs
524 write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:rectilinear_grid'
525 end do
526
527 meshtypes = db_quad_rect
528
529 err = dbset2dstrlen(len(meshnames(1)))
530 err = dbmkoptlist(2, optlist)
531 err = dbaddiopt(optlist, dbopt_extents_size, size(spatial_extents, 1))
532 err = dbadddopt(optlist, dbopt_extents, spatial_extents)
533 err = dbputmmesh(dbroot, 'rectilinear_grid', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, optlist, &
534 & ierr)
535 err = dbfreeoptlist(optlist)
536 end if
537
538 ! Finally, the local quadrilateral mesh, either 2D or 3D, along with its offsets that indicate the presence and size of
539 ! ghost zone layer(s), are put in the formatted database slave file.
540
541 if (p > 0) then
542 err = dbmkoptlist(2, optlist)
543 err = dbaddiaopt(optlist, dbopt_lo_offset, size(lo_offset), lo_offset)
544 err = dbaddiaopt(optlist, dbopt_hi_offset, size(hi_offset), hi_offset)
545 if (grid_geometry == 3) then
546 err = dbputqm(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, y_cb, z_cb, x_cb, dims, 3, db_double, &
547 & db_collinear, optlist, ierr)
548 else
549 err = dbputqm(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, z_cb, dims, 3, db_double, &
550 & db_collinear, optlist, ierr)
551 end if
552 err = dbfreeoptlist(optlist)
553 else if (n > 0) then
554 err = dbmkoptlist(2, optlist)
555 err = dbaddiaopt(optlist, dbopt_lo_offset, size(lo_offset), lo_offset)
556 err = dbaddiaopt(optlist, dbopt_hi_offset, size(hi_offset), hi_offset)
557 err = dbputqm(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, y_cb, db_f77null, dims, 2, db_double, &
558 & db_collinear, optlist, ierr)
559 err = dbfreeoptlist(optlist)
560 else
561 err = dbmkoptlist(2, optlist)
562 err = dbaddiaopt(optlist, dbopt_lo_offset, size(lo_offset), lo_offset)
563 err = dbaddiaopt(optlist, dbopt_hi_offset, size(hi_offset), hi_offset)
564 err = dbputqm(dbfile, 'rectilinear_grid', 16, 'x', 1, 'y', 1, 'z', 1, x_cb, db_f77null, db_f77null, dims, 1, &
565 & db_double, db_collinear, optlist, ierr)
566 err = dbfreeoptlist(optlist)
567 end if
568 else if (format == 2) then
569 ! Multidimensional local grid data is written to the formatted database slave file. Recall that no master file to
570 ! maintained in multidimensions.
571 if (p > 0) then
572 if (precision == 1) then
573 write (dbfile) real(x_cb, sp), real(y_cb, sp), real(z_cb, sp)
574 else
575 if (output_partial_domain) then
576 write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end), &
577 & z_cb(z_output_idx%beg - 1:z_output_idx%end)
578 else
579 write (dbfile) x_cb, y_cb, z_cb
580 end if
581 end if
582 else if (n > 0) then
583 if (precision == 1) then
584 write (dbfile) real(x_cb, sp), real(y_cb, sp)
585 else
586 if (output_partial_domain) then
587 write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end), y_cb(y_output_idx%beg - 1:y_output_idx%end)
588 else
589 write (dbfile) x_cb, y_cb
590 end if
591 end if
592
593 ! One-dimensional local grid data is written to the formatted database slave file. In addition, the local grid data
594 ! is put together by the root process and written to the master file.
595 else
596 if (precision == 1) then
597 write (dbfile) real(x_cb, sp)
598 else
599 if (output_partial_domain) then
600 write (dbfile) x_cb(x_output_idx%beg - 1:x_output_idx%end)
601 else
602 write (dbfile) x_cb
603 end if
604 end if
605
606 if (num_procs > 1) then
608 else
609 x_root_cb(:) = x_cb(:)
610 end if
611
612 if (proc_rank == 0) then
613 if (precision == 1) then
614 write (dbroot) real(x_root_cb, wp)
615 else
616 if (output_partial_domain) then
617 write (dbroot) x_root_cb(x_output_idx%beg - 1:x_output_idx%end)
618 else
619 write (dbroot) x_root_cb
620 end if
621 end if
622 end if
623 end if
624 end if
625
627
628 !> Write a single flow variable field to the formatted database slave and master files for a given time step.
629 impure subroutine s_write_variable_to_formatted_database_file(varname, t_step)
630
631 character(LEN=*), intent(in) :: varname
632 integer, intent(in) :: t_step
633
634 ! NAG compiler requires these to be statically sized
635 character(LEN=4*name_len), dimension(num_procs) :: varnames
636 integer, dimension(num_procs) :: vartypes
637 integer :: i, j, k
638 integer :: ierr
639
640 if (format == 1) then
641 ! Determining the extents of the flow variable on each local process and gathering all this information on root process
642 if (num_procs > 1) then
644 else
645 data_extents(:,0) = (/minval(q_sf), maxval(q_sf)/)
646 end if
647
648 if (proc_rank == 0) then
649 do i = 1, num_procs
650 write (varnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname)
651 end do
652
653 vartypes = db_quadvar
654
655 err = dbset2dstrlen(len(varnames(1)))
656 err = dbmkoptlist(2, optlist)
657 err = dbaddiopt(optlist, dbopt_extents_size, 2)
658 err = dbadddopt(optlist, dbopt_extents, data_extents)
659 err = dbputmvar(dbroot, trim(varname), len_trim(varname), num_procs, varnames, len_trim(varnames), vartypes, &
660 & optlist, ierr)
661 err = dbfreeoptlist(optlist)
662 end if
663
664 if (wp == dp) then
665 if (precision == 1) then
666 do i = -offset_x%beg, m + offset_x%end
667 do j = -offset_y%beg, n + offset_y%end
668 do k = -offset_z%beg, p + offset_z%end
669 q_sf_s(i, j, k) = real(q_sf(i, j, k), sp)
670 end do
671 end do
672 end do
673 if (grid_geometry == 3) then
674 do i = -offset_x%beg, m + offset_x%end
675 do j = -offset_y%beg, n + offset_y%end
676 do k = -offset_z%beg, p + offset_z%end
677 cyl_q_sf_s(j, k, i) = q_sf_s(i, j, k)
678 end do
679 end do
680 end do
681 end if
682 else
683 if (grid_geometry == 3) then
684 do i = -offset_x%beg, m + offset_x%end
685 do j = -offset_y%beg, n + offset_y%end
686 do k = -offset_z%beg, p + offset_z%end
687 cyl_q_sf(j, k, i) = q_sf(i, j, k)
688 end do
689 end do
690 end do
691 end if
692 end if
693 else if (wp == sp) then
694 do i = -offset_x%beg, m + offset_x%end
695 do j = -offset_y%beg, n + offset_y%end
696 do k = -offset_z%beg, p + offset_z%end
697 q_sf_s(i, j, k) = q_sf(i, j, k)
698 end do
699 end do
700 end do
701 if (grid_geometry == 3) then
702 do i = -offset_x%beg, m + offset_x%end
703 do j = -offset_y%beg, n + offset_y%end
704 do k = -offset_z%beg, p + offset_z%end
705 cyl_q_sf_s(j, k, i) = q_sf_s(i, j, k)
706 end do
707 end do
708 end do
709 end if
710 end if
711
712# 662 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
713 if (precision == 1) then
714 if (p > 0) then
715 if (grid_geometry == 3) then
716 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, cyl_q_sf_s, &
717 & dims - 1, 3, db_f77null, 0, db_float, db_zonecent, db_f77null, ierr)
718 else
719 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf_s, &
720 & dims - 1, 3, db_f77null, 0, db_float, db_zonecent, db_f77null, ierr)
721 end if
722 else if (n > 0) then
723 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf_s, dims - 1, &
724 & 2, db_f77null, 0, db_float, db_zonecent, db_f77null, ierr)
725 else
726 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf_s, dims - 1, &
727 & 1, db_f77null, 0, db_float, db_zonecent, db_f77null, ierr)
728 end if
729 end if
730# 662 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
731 if (precision == 2) then
732 if (p > 0) then
733 if (grid_geometry == 3) then
734 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, cyl_q_sf, &
735 & dims - 1, 3, db_f77null, 0, db_double, db_zonecent, db_f77null, ierr)
736 else
737 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf, &
738 & dims - 1, 3, db_f77null, 0, db_double, db_zonecent, db_f77null, ierr)
739 end if
740 else if (n > 0) then
741 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf, dims - 1, &
742 & 2, db_f77null, 0, db_double, db_zonecent, db_f77null, ierr)
743 else
744 err = dbputqv1(dbfile, trim(varname), len_trim(varname), 'rectilinear_grid', 16, q_sf, dims - 1, &
745 & 1, db_f77null, 0, db_double, db_zonecent, db_f77null, ierr)
746 end if
747 end if
748# 680 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
749 else
750 ! Writing the name of the flow variable and its data, associated with the local processor, to the formatted database
751 ! slave file
752 if (precision == 1) then
753 write (dbfile) varname, real(q_sf, wp)
754 else
755 write (dbfile) varname, q_sf
756 end if
757
758 ! In 1D, the root process also takes care of gathering the flow variable data from all of the local processor(s) and
759 ! writes it to the formatted database master file.
760 if (n == 0) then
761 if (num_procs > 1) then
763 else
764 q_root_sf(:,:,:) = q_sf(:,:,:)
765 end if
766
767 if (proc_rank == 0) then
768 if (precision == 1) then
769 write (dbroot) varname, real(q_root_sf, wp)
770 else
771 write (dbroot) varname, q_root_sf
772 end if
773 end if
774 end if
775 end if
776
778
779 !> Write the post-processed results in the folder 'lag_bubbles_data'
780 impure subroutine s_write_lag_bubbles_results_to_text(t_step)
781
782 integer, intent(in) :: t_step
783 character(len=len_trim(case_dir) + 3*name_len) :: file_loc
784 integer :: id
785
786#ifdef MFC_MPI
787 real(wp), dimension(20) :: inputvals
788 real(wp) :: time_real
789 integer, dimension(MPI_STATUS_SIZE) :: status
790 integer(KIND=MPI_OFFSET_KIND) :: disp
791 integer :: view
792 logical :: lg_bub_file, file_exist
793 integer, dimension(2) :: gsizes, lsizes, start_idx_part
794 integer :: ifile
795 integer :: ierr
796 real(wp) :: file_time, file_dt
797 integer :: file_num_procs, file_tot_part, tot_part
798 integer :: i
799 integer, dimension(:), allocatable :: proc_bubble_counts
800 real(wp), dimension(1:1,1:lag_io_vars) :: lag_io_null
801
802 lag_io_null = 0._wp
803
804 ! Construct file path
805 write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat'
806 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc)
807
808 ! Check if file exists
809 inquire (file=trim(file_loc), exist=file_exist)
810 if (.not. file_exist) then
811 call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!')
812 end if
813
814 if (.not. parallel_io) return
815
816 if (proc_rank == 0) then
817 call mpi_file_open(mpi_comm_self, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
818
819 call mpi_file_read(ifile, file_tot_part, 1, mpi_integer, status, ierr)
820 call mpi_file_read(ifile, file_time, 1, mpi_p, status, ierr)
821 call mpi_file_read(ifile, file_dt, 1, mpi_p, status, ierr)
822 call mpi_file_read(ifile, file_num_procs, 1, mpi_integer, status, ierr)
823
824 call mpi_file_close(ifile, ierr)
825 end if
826
827 call mpi_bcast(file_tot_part, 1, mpi_integer, 0, mpi_comm_world, ierr)
828 call mpi_bcast(file_time, 1, mpi_p, 0, mpi_comm_world, ierr)
829 call mpi_bcast(file_dt, 1, mpi_p, 0, mpi_comm_world, ierr)
830 call mpi_bcast(file_num_procs, 1, mpi_integer, 0, mpi_comm_world, ierr)
831 time_real = file_time
832
833 allocate (proc_bubble_counts(file_num_procs))
834
835 if (proc_rank == 0) then
836 call mpi_file_open(mpi_comm_self, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
837
838 ! Skip to processor counts position
839 disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), mpi_offset_kind)
840 call mpi_file_seek(ifile, disp, mpi_seek_set, ierr)
841 call mpi_file_read(ifile, proc_bubble_counts, file_num_procs, mpi_integer, status, ierr)
842
843 call mpi_file_close(ifile, ierr)
844 end if
845
846 call mpi_bcast(proc_bubble_counts, file_num_procs, mpi_integer, 0, mpi_comm_world, ierr)
847
848 gsizes(1) = file_tot_part
849 gsizes(2) = lag_io_vars
850 lsizes(1) = file_tot_part
851 lsizes(2) = lag_io_vars
852 start_idx_part(1) = 0
853 start_idx_part(2) = 0
854
855 call mpi_type_create_subarray(2, gsizes, lsizes, start_idx_part, mpi_order_fortran, mpi_p, view, ierr)
856 call mpi_type_commit(view, ierr)
857
858 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
859
860 disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) &
861 & + file_num_procs*sizeof(proc_bubble_counts(1)), mpi_offset_kind)
862 call mpi_file_set_view(ifile, disp, mpi_p, view, 'native', mpi_info_null, ierr)
863
864 allocate (mpi_io_data_lg_bubbles(file_tot_part,1:lag_io_vars))
865
866 call mpi_file_read_all(ifile, mpi_io_data_lg_bubbles, lag_io_vars*file_tot_part, mpi_p, status, ierr)
867
868 write (file_loc, '(A,I0,A)') 'lag_bubbles_post_process_', t_step, '.dat'
869 file_loc = trim(case_dir) // '/lag_bubbles_post_process/' // trim(file_loc)
870
871 if (proc_rank == 0) then
872 open (unit=29, file=file_loc, form='formatted', position='rewind')
873
874 if (lag_header) then
875 write (29, '(A)', advance='no')
876 if (lag_id_wrt) write (29, '(A8)', advance='no') 'id, '
877 if (lag_pos_wrt) write (29, '(3(A17))', advance='no') 'px, ', 'py, ', 'pz, '
878 if (lag_pos_prev_wrt) write (29, '(3(A17))', advance='no') 'pvx, ', 'pvy, ', 'pvz, '
879 if (lag_vel_wrt) write (29, '(3(A17))', advance='no') 'vx, ', 'vy, ', 'vz, '
880 if (lag_rad_wrt) write (29, '(A17)', advance='no') 'radius, '
881 if (lag_rvel_wrt) write (29, '(A17)', advance='no') 'rvel, '
882 if (lag_r0_wrt) write (29, '(A17)', advance='no') 'r0, '
883 if (lag_rmax_wrt) write (29, '(A17)', advance='no') 'rmax, '
884 if (lag_rmin_wrt) write (29, '(A17)', advance='no') 'rmin, '
885 if (lag_dphidt_wrt) write (29, '(A17)', advance='no') 'dphidt, '
886 if (lag_pres_wrt) write (29, '(A17)', advance='no') 'pressure, '
887 if (lag_mv_wrt) write (29, '(A17)', advance='no') 'mv, '
888 if (lag_mg_wrt) write (29, '(A17)', advance='no') 'mg, '
889 if (lag_betat_wrt) write (29, '(A17)', advance='no') 'betaT, '
890 if (lag_betac_wrt) write (29, '(A17)', advance='no') 'betaC, '
891 write (29, '(A15)') 'time'
892 end if
893
894 do i = 1, file_tot_part
895 id = int(mpi_io_data_lg_bubbles(i, 1))
896 inputvals(1:20) = mpi_io_data_lg_bubbles(i,2:21)
897 if (id > 0) then
898 write (29, '(100(A))', advance='no') ''
899 if (lag_id_wrt) write (29, '(I6, A)', advance='no') id, ', '
900 if (lag_pos_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(1), ', ', inputvals(2), ', ', &
901 & inputvals(3), ', '
902 if (lag_pos_prev_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(4), ', ', inputvals(5), ', ', &
903 & inputvals(6), ', '
904 if (lag_vel_wrt) write (29, '(3(E15.7, A))', advance='no') inputvals(7), ', ', inputvals(8), ', ', &
905 & inputvals(9), ', '
906 if (lag_rad_wrt) write (29, '(E15.7, A)', advance='no') inputvals(10), ', '
907 if (lag_rvel_wrt) write (29, '(E15.7, A)', advance='no') inputvals(11), ', '
908 if (lag_r0_wrt) write (29, '(E15.7, A)', advance='no') inputvals(12), ', '
909 if (lag_rmax_wrt) write (29, '(E15.7, A)', advance='no') inputvals(13), ', '
910 if (lag_rmin_wrt) write (29, '(E15.7, A)', advance='no') inputvals(14), ', '
911 if (lag_dphidt_wrt) write (29, '(E15.7, A)', advance='no') inputvals(15), ', '
912 if (lag_pres_wrt) write (29, '(E15.7, A)', advance='no') inputvals(16), ', '
913 if (lag_mv_wrt) write (29, '(E15.7, A)', advance='no') inputvals(17), ', '
914 if (lag_mg_wrt) write (29, '(E15.7, A)', advance='no') inputvals(18), ', '
915 if (lag_betat_wrt) write (29, '(E15.7, A)', advance='no') inputvals(19), ', '
916 if (lag_betac_wrt) write (29, '(E15.7, A)', advance='no') inputvals(20), ', '
917 write (29, '(E15.7)') time_real
918 end if
919 end do
920 close (29)
921 end if
922
923 deallocate (mpi_io_data_lg_bubbles)
924
925 call s_mpi_barrier()
926
927 call mpi_file_close(ifile, ierr)
928#endif
929
931
932 !> Read Lagrangian bubble restart data and write bubble positions and scalar fields to the Silo database.
934
935 integer, intent(in) :: t_step
936 character(len=len_trim(case_dir) + 3*name_len) :: file_loc
937 integer :: id
938
939#ifdef MFC_MPI
940 real(wp), dimension(20) :: inputvals
941 real(wp) :: time_real
942 integer, dimension(MPI_STATUS_SIZE) :: status
943 integer(KIND=MPI_OFFSET_KIND) :: disp
944 integer :: view
945 logical :: lg_bub_file, file_exist
946 integer, dimension(2) :: gsizes, lsizes, start_idx_part
947 integer :: ifile, ierr, tot_data, valid_data, nbub
948 real(wp) :: file_time, file_dt
949 integer :: file_num_procs, file_tot_part
950 integer, dimension(:), allocatable :: proc_bubble_counts
951 real(wp), dimension(1:1,1:lag_io_vars) :: dummy
952 character(LEN=4*name_len), dimension(num_procs) :: meshnames
953 integer, dimension(num_procs) :: meshtypes
954 real(wp) :: dummy_data
955 integer :: i, j
956 real(wp), dimension(:), allocatable :: bub_id
957 real(wp), dimension(:), allocatable :: px, py, pz, ppx, ppy, ppz, vx, vy, vz
958 real(wp), dimension(:), allocatable :: radius, rvel, rnot, rmax, rmin, dphidt
959 real(wp), dimension(:), allocatable :: pressure, mv, mg, betat, betac
960
961 dummy = 0._wp
962 dummy_data = 0._wp
963
964 ! Construct file path
965 write (file_loc, '(A,I0,A)') 'lag_bubbles_', t_step, '.dat'
966 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc)
967
968 ! Check if file exists
969 inquire (file=trim(file_loc), exist=file_exist)
970 if (.not. file_exist) then
971 call s_mpi_abort('Restart file ' // trim(file_loc) // ' does not exist!')
972 end if
973
974 if (.not. parallel_io) return
975
976 if (proc_rank == 0) then
977 call mpi_file_open(mpi_comm_self, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
978
979 call mpi_file_read(ifile, file_tot_part, 1, mpi_integer, status, ierr)
980 call mpi_file_read(ifile, file_time, 1, mpi_p, status, ierr)
981 call mpi_file_read(ifile, file_dt, 1, mpi_p, status, ierr)
982 call mpi_file_read(ifile, file_num_procs, 1, mpi_integer, status, ierr)
983
984 call mpi_file_close(ifile, ierr)
985 end if
986
987 call mpi_bcast(file_tot_part, 1, mpi_integer, 0, mpi_comm_world, ierr)
988 call mpi_bcast(file_time, 1, mpi_p, 0, mpi_comm_world, ierr)
989 call mpi_bcast(file_dt, 1, mpi_p, 0, mpi_comm_world, ierr)
990 call mpi_bcast(file_num_procs, 1, mpi_integer, 0, mpi_comm_world, ierr)
991 time_real = file_time
992
993 allocate (proc_bubble_counts(file_num_procs))
994
995 if (proc_rank == 0) then
996 call mpi_file_open(mpi_comm_self, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
997
998 ! Skip to processor counts position
999 disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs), mpi_offset_kind)
1000 call mpi_file_seek(ifile, disp, mpi_seek_set, ierr)
1001 call mpi_file_read(ifile, proc_bubble_counts, file_num_procs, mpi_integer, status, ierr)
1002
1003 call mpi_file_close(ifile, ierr)
1004 end if
1005
1006 call mpi_bcast(proc_bubble_counts, file_num_procs, mpi_integer, 0, mpi_comm_world, ierr)
1007
1008 ! Set time variables from file
1009
1010 nbub = proc_bubble_counts(proc_rank + 1)
1011
1012 start_idx_part(1) = 0
1013 do i = 1, proc_rank
1014 start_idx_part(1) = start_idx_part(1) + proc_bubble_counts(i)
1015 end do
1016
1017 start_idx_part(2) = 0
1018 lsizes(1) = nbub
1019 lsizes(2) = lag_io_vars
1020
1021 gsizes(1) = file_tot_part
1022 gsizes(2) = lag_io_vars
1023
1024 if (nbub > 0) then
1025# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1026 allocate (bub_id(nbub))
1027# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1028 allocate (px(nbub))
1029# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1030 allocate (py(nbub))
1031# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1032 allocate (pz(nbub))
1033# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1034 allocate (ppx(nbub))
1035# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1036 allocate (ppy(nbub))
1037# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1038 allocate (ppz(nbub))
1039# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1040 allocate (vx(nbub))
1041# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1042 allocate (vy(nbub))
1043# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1044 allocate (vz(nbub))
1045# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1046 allocate (radius(nbub))
1047# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1048 allocate (rvel(nbub))
1049# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1050 allocate (rnot(nbub))
1051# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1052 allocate (rmax(nbub))
1053# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1054 allocate (rmin(nbub))
1055# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1056 allocate (dphidt(nbub))
1057# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1058 allocate (pressure(nbub))
1059# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1060 allocate (mv(nbub))
1061# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1062 allocate (mg(nbub))
1063# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1064 allocate (betat(nbub))
1065# 959 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1066 allocate (betac(nbub))
1067# 961 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1068 allocate (mpi_io_data_lg_bubbles(nbub,1:lag_io_vars))
1069
1070 call mpi_type_create_subarray(2, gsizes, lsizes, start_idx_part, mpi_order_fortran, mpi_p, view, ierr)
1071 call mpi_type_commit(view, ierr)
1072
1073 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
1074
1075 ! Skip extended header
1076 disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) &
1077 & + file_num_procs*sizeof(proc_bubble_counts(1)), mpi_offset_kind)
1078 call mpi_file_set_view(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr)
1079
1080 call mpi_file_read_all(ifile, mpi_io_data_lg_bubbles, lag_io_vars*nbub, mpi_p, status, ierr)
1081
1082 call mpi_file_close(ifile, ierr)
1083 call mpi_type_free(view, ierr)
1084
1085 ! Extract data from MPI_IO_DATA_lg_bubbles array Adjust these indices based on your actual data layout
1086# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1087 bub_id(:) = mpi_io_data_lg_bubbles(:,1)
1088# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1089 px(:) = mpi_io_data_lg_bubbles(:,2)
1090# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1091 py(:) = mpi_io_data_lg_bubbles(:,3)
1092# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1093 pz(:) = mpi_io_data_lg_bubbles(:,4)
1094# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1095 ppx(:) = mpi_io_data_lg_bubbles(:,5)
1096# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1097 ppy(:) = mpi_io_data_lg_bubbles(:,6)
1098# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1099 ppz(:) = mpi_io_data_lg_bubbles(:,7)
1100# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1101 vx(:) = mpi_io_data_lg_bubbles(:,8)
1102# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1103 vy(:) = mpi_io_data_lg_bubbles(:,9)
1104# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1105 vz(:) = mpi_io_data_lg_bubbles(:,10)
1106# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1107 radius(:) = mpi_io_data_lg_bubbles(:,11)
1108# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1109 rvel(:) = mpi_io_data_lg_bubbles(:,12)
1110# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1111 rnot(:) = mpi_io_data_lg_bubbles(:,13)
1112# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1113 rmax(:) = mpi_io_data_lg_bubbles(:,14)
1114# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1115 rmin(:) = mpi_io_data_lg_bubbles(:,15)
1116# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1117 dphidt(:) = mpi_io_data_lg_bubbles(:,16)
1118# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1119 pressure(:) = mpi_io_data_lg_bubbles(:,17)
1120# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1121 mv(:) = mpi_io_data_lg_bubbles(:,18)
1122# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1123 mg(:) = mpi_io_data_lg_bubbles(:,19)
1124# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1125 betat(:) = mpi_io_data_lg_bubbles(:,20)
1126# 983 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1127 betac(:) = mpi_io_data_lg_bubbles(:,21)
1128# 985 "/home/runner/work/MFC/MFC/src/post_process/m_data_output.fpp"
1129
1130 ! Next, the root processor proceeds to record all of the spatial extents in the formatted database master file. In
1131 ! addition, it also records a sub-domain connectivity map so that the entire grid may be reassembled by looking at the
1132 ! master file.
1133 if (proc_rank == 0) then
1134 do i = 1, num_procs
1135 write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles'
1136 meshtypes(i) = db_pointmesh
1137 end do
1138 err = dbset2dstrlen(len(meshnames(1)))
1139 err = dbputmmesh(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, db_f77null, ierr)
1140 end if
1141
1142 err = dbputpm(dbfile, 'lag_bubbles', 11, 3, px, py, pz, nbub, db_double, db_f77null, ierr)
1143
1144 if (lag_id_wrt) call s_write_lag_variable_to_formatted_database_file('part_id', t_step, bub_id, nbub)
1145 if (lag_vel_wrt) then
1146 call s_write_lag_variable_to_formatted_database_file('part_vel1', t_step, vx, nbub)
1147 call s_write_lag_variable_to_formatted_database_file('part_vel2', t_step, vy, nbub)
1148 if (p > 0) call s_write_lag_variable_to_formatted_database_file('part_vel3', t_step, vz, nbub)
1149 end if
1150 if (lag_rad_wrt) call s_write_lag_variable_to_formatted_database_file('part_radius', t_step, radius, nbub)
1151 if (lag_rvel_wrt) call s_write_lag_variable_to_formatted_database_file('part_rdot', t_step, rvel, nbub)
1152 if (lag_r0_wrt) call s_write_lag_variable_to_formatted_database_file('part_r0', t_step, rnot, nbub)
1153 if (lag_rmax_wrt) call s_write_lag_variable_to_formatted_database_file('part_rmax', t_step, rmax, nbub)
1154 if (lag_rmin_wrt) call s_write_lag_variable_to_formatted_database_file('part_rmin', t_step, rmin, nbub)
1155 if (lag_dphidt_wrt) call s_write_lag_variable_to_formatted_database_file('part_dphidt', t_step, dphidt, nbub)
1156 if (lag_pres_wrt) call s_write_lag_variable_to_formatted_database_file('part_pressure', t_step, pressure, nbub)
1157 if (lag_mv_wrt) call s_write_lag_variable_to_formatted_database_file('part_mv', t_step, mv, nbub)
1158 if (lag_mg_wrt) call s_write_lag_variable_to_formatted_database_file('part_mg', t_step, mg, nbub)
1159 if (lag_betat_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaT', t_step, betat, nbub)
1160 if (lag_betac_wrt) call s_write_lag_variable_to_formatted_database_file('part_betaC', t_step, betac, nbub)
1161
1162 deallocate (bub_id, px, py, pz, ppx, ppy, ppz, vx, vy, vz, radius, rvel, rnot, rmax, rmin, dphidt, pressure, mv, mg, &
1163 & betat, betac)
1164 deallocate (mpi_io_data_lg_bubbles)
1165 else
1166 call mpi_type_contiguous(0, mpi_p, view, ierr)
1167 call mpi_type_commit(view, ierr)
1168
1169 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
1170
1171 ! Skip extended header
1172 disp = int(sizeof(file_tot_part) + 2*sizeof(file_time) + sizeof(file_num_procs) &
1173 & + file_num_procs*sizeof(proc_bubble_counts(1)), mpi_offset_kind)
1174 call mpi_file_set_view(ifile, disp, mpi_p, view, 'native', mpi_info_int, ierr)
1175
1176 call mpi_file_read_all(ifile, dummy, 0, mpi_p, status, ierr)
1177
1178 call mpi_file_close(ifile, ierr)
1179 call mpi_type_free(view, ierr)
1180
1181 if (proc_rank == 0) then
1182 do i = 1, num_procs
1183 write (meshnames(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:lag_bubbles'
1184 meshtypes(i) = db_pointmesh
1185 end do
1186 err = dbset2dstrlen(len(meshnames(1)))
1187 err = dbputmmesh(dbroot, 'lag_bubbles', 16, num_procs, meshnames, len_trim(meshnames), meshtypes, db_f77null, ierr)
1188 end if
1189
1190 err = dbsetemptyok(1)
1191 err = dbputpm(dbfile, 'lag_bubbles', 11, 3, dummy_data, dummy_data, dummy_data, 0, db_double, db_f77null, ierr)
1192
1194 if (lag_vel_wrt) then
1195 call s_write_lag_variable_to_formatted_database_file('part_vel1', t_step)
1196 call s_write_lag_variable_to_formatted_database_file('part_vel2', t_step)
1197 if (p > 0) call s_write_lag_variable_to_formatted_database_file('part_vel3', t_step)
1198 end if
1199 if (lag_rad_wrt) call s_write_lag_variable_to_formatted_database_file('part_radius', t_step)
1205 if (lag_pres_wrt) call s_write_lag_variable_to_formatted_database_file('part_pressure', t_step)
1210 end if
1211#endif
1212
1214
1215 !> Write a single Lagrangian bubble point-variable to the Silo database slave and master files.
1216 subroutine s_write_lag_variable_to_formatted_database_file(varname, t_step, data, nBubs)
1217
1218 character(len=*), intent(in) :: varname
1219 integer, intent(in) :: t_step
1220 real(wp), dimension(1:), intent(in), optional :: data
1221 integer, intent(in), optional :: nBubs
1222 character(len=64), dimension(num_procs) :: var_names
1223 integer, dimension(num_procs) :: var_types
1224 real(wp) :: dummy_data
1225 integer :: ierr
1226 integer :: i
1227
1228 dummy_data = 0._wp
1229
1230 if (present(nbubs) .and. present(data)) then
1231 if (proc_rank == 0) then
1232 do i = 1, num_procs
1233 write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname)
1234 var_types(i) = db_pointvar
1235 end do
1236 err = dbset2dstrlen(len(var_names(1)))
1237 err = dbputmvar(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, &
1238 & db_f77null, ierr)
1239 end if
1240
1241 err = dbputpv1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, data, nbubs, db_double, db_f77null, ierr)
1242 else
1243 if (proc_rank == 0) then
1244 do i = 1, num_procs
1245 write (var_names(i), '(A,I0,A,I0,A)') '../p', i - 1, '/', t_step, '.silo:' // trim(varname)
1246 var_types(i) = db_pointvar
1247 end do
1248 err = dbset2dstrlen(len(var_names(1)))
1249 err = dbsetemptyok(1)
1250 err = dbputmvar(dbroot, trim(varname), len_trim(varname), num_procs, var_names, len_trim(var_names), var_types, &
1251 & db_f77null, ierr)
1252 end if
1253
1254 err = dbsetemptyok(1)
1255 err = dbputpv1(dbfile, trim(varname), len_trim(varname), 'lag_bubbles', 11, dummy_data, 0, db_double, db_f77null, ierr)
1256 end if
1257
1259
1260 !> Convert the binary immersed-boundary state file to per-body formatted text files
1261 impure subroutine s_write_ib_state_files()
1262
1263 character(len=len_trim(case_dir) + 4*name_len) :: in_file, out_file, file_loc
1264 integer :: iu_in, ios, i, rec_id
1265 integer, allocatable, dimension(:) :: iu_out
1266 real(wp) :: rec_time
1267 real(wp), dimension(3) :: rec_force, rec_torque
1268 real(wp), dimension(3) :: rec_vel, rec_angular_vel
1269 real(wp), dimension(3) :: rec_angles, rec_centroid
1270
1271 file_loc = trim(case_dir) // '/D'
1272
1273 in_file = trim(file_loc) // '/ib_state.dat'
1274 open (newunit=iu_in, file=trim(in_file), form='unformatted', access='stream', status='old', action='read', iostat=ios)
1275 if (ios /= 0) then
1276 call s_mpi_abort('Cannot open IB state input file: ' // trim(in_file))
1277 end if
1278
1279 allocate (iu_out(num_ibs))
1280 do i = 1, num_ibs
1281 write (out_file, '(A,I0,A)') trim(file_loc) // '/ib_', i, '.txt'
1282 open (newunit=iu_out(i), file=trim(out_file), form='formatted', status='replace', action='write', iostat=ios)
1283 if (ios /= 0) then
1284 call s_mpi_abort('Cannot open IB state output file: ' // trim(out_file))
1285 end if
1286 write (iu_out(i), &
1287 & '(A)') 'mytime fx fy fz Tau_x Tau_y Tau_z vx vy vz omega_x omega_y omega_z angle_x angle_y angle_z x_c y_c z_c'
1288 end do
1289
1290 do
1291 read (iu_in, iostat=ios) rec_time, rec_id, rec_force, rec_torque, rec_vel, rec_angular_vel, rec_angles, &
1292 & rec_centroid(1), rec_centroid(2), rec_centroid(3)
1293 if (ios /= 0) exit
1294
1295 if (rec_id >= 1 .and. rec_id <= num_ibs) then
1296 write (iu_out(rec_id), '(19(ES24.16E3,1X))') rec_time, rec_force(1), rec_force(2), rec_force(3), rec_torque(1), &
1297 & rec_torque(2), rec_torque(3), rec_vel(1), rec_vel(2), rec_vel(3), rec_angular_vel(1), &
1298 & rec_angular_vel(2), rec_angular_vel(3), rec_angles(1), rec_angles(2), rec_angles(3), rec_centroid(1), &
1299 & rec_centroid(2), rec_centroid(3)
1300 end if
1301 end do
1302
1303 close (iu_in)
1304 do i = 1, num_ibs
1305 close (iu_out(i))
1306 end do
1307 deallocate (iu_out)
1308
1309 end subroutine s_write_ib_state_files
1310
1311 !> Extract the volume-fraction interface contour from primitive fields and write the coordinates to the interface data file.
1312 impure subroutine s_write_intf_data_file(q_prim_vf)
1313
1314 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf
1315 integer :: i, j, k, l, cent
1316 integer :: counter, root !< number of data points extracted to fit shape to SH perturbations
1317 real(wp), allocatable :: x_td(:), y_td(:), x_d1(:), y_d1(:), y_d(:), x_d(:)
1318 real(wp) :: axp, axm, ayp, aym, tgp, euc_d, thres, maxalph_loc, maxalph_glb
1319
1320 allocate (x_d1(m*n))
1321 allocate (y_d1(m*n))
1322 counter = 0
1323 maxalph_loc = 0._wp
1324 do k = 0, p
1325 do j = 0, n
1326 do i = 0, m
1327 if (q_prim_vf(e_idx + 2)%sf(i, j, k) > maxalph_loc) then
1328 maxalph_loc = q_prim_vf(e_idx + 2)%sf(i, j, k)
1329 end if
1330 end do
1331 end do
1332 end do
1333
1334 call s_mpi_allreduce_max(maxalph_loc, maxalph_glb)
1335 if (p > 0) then
1336 do l = 0, p
1337 if (z_cc(l) < dz(l) .and. z_cc(l) > 0) then
1338 cent = l
1339 end if
1340 end do
1341 else
1342 cent = 0
1343 end if
1344
1345 thres = 0.9_wp*maxalph_glb
1346 do k = 0, n
1347 do j = 0, m
1348 axp = q_prim_vf(e_idx + 2)%sf(j + 1, k, cent)
1349 axm = q_prim_vf(e_idx + 2)%sf(j, k, cent)
1350 ayp = q_prim_vf(e_idx + 2)%sf(j, k + 1, cent)
1351 aym = q_prim_vf(e_idx + 2)%sf(j, k, cent)
1352 if ((axp > thres .and. axm < thres) .or. (axp < thres .and. axm > thres) .or. (ayp > thres .and. aym < thres) &
1353 & .or. (ayp < thres .and. aym > thres)) then
1354 if (counter == 0) then
1355 counter = counter + 1
1356 x_d1(counter) = x_cc(j)
1357 y_d1(counter) = y_cc(k)
1358 else
1359 tgp = sqrt(dx(j)**2 + dy(k)**2)
1360 do i = 1, counter
1361 euc_d = sqrt((x_cc(j) - x_d1(i))**2 + (y_cc(k) - y_d1(i))**2)
1362 if (euc_d < tgp) then
1363 exit
1364 else if (i == counter) then
1365 counter = counter + 1
1366 x_d1(counter) = x_cc(j)
1367 y_d1(counter) = y_cc(k)
1368 end if
1369 end do
1370 end if
1371 end if
1372 end do
1373 end do
1374
1375 allocate (x_d(counter), y_d(counter))
1376
1377 do i = 1, counter
1378 y_d(i) = y_d1(i)
1379 x_d(i) = x_d1(i)
1380 end do
1381 root = 0
1382
1383 call s_mpi_gather_data(x_d, counter, x_td, root)
1384 call s_mpi_gather_data(y_d, counter, y_td, root)
1385 if (proc_rank == 0) then
1386 do i = 1, size(x_td)
1387 if (i == size(x_td)) then
1388 write (211, '(F12.9,1X,F12.9,1X,I4)') x_td(i), y_td(i), size(x_td)
1389 else
1390 write (211, '(F12.9,1X,F12.9,1X,F3.1)') x_td(i), y_td(i), 0._wp
1391 end if
1392 end do
1393 end if
1394
1395 end subroutine s_write_intf_data_file
1396
1397 !> Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to the energy data file.
1398 impure subroutine s_write_energy_data_file(q_prim_vf, q_cons_vf)
1399
1400 type(scalar_field), dimension(sys_size), intent(in) :: q_prim_vf, q_cons_vf
1401 real(wp) :: elk, egk, elp, egint, vb, vl, pres_av, et
1402 real(wp) :: rho, pres, dv, tmp, gamma, pi_inf, maxma, maxma_glb, maxvel, c, ma, h, qv
1403 real(wp), dimension(num_vels) :: vel
1404 real(wp), dimension(num_fluids) :: adv
1405 integer :: i, j, k, l, s !< looping indices
1406
1407 egk = 0._wp
1408 elp = 0._wp
1409 egint = 0._wp
1410 vb = 0._wp
1411 maxvel = 0._wp
1412 maxma = 0._wp
1413 vl = 0._wp
1414 elk = 0._wp
1415 et = 0._wp
1416 vb = 0._wp
1417 dv = 0._wp
1418 pres_av = 0._wp
1419 pres = 0._wp
1420 c = 0._wp
1421
1422 do k = 0, p
1423 do j = 0, n
1424 do i = 0, m
1425 pres = 0._wp
1426 dv = dx(i)*dy(j)*dz(k)
1427 rho = 0._wp
1428 gamma = 0._wp
1429 pi_inf = 0._wp
1430 qv = 0._wp
1431 pres = q_prim_vf(e_idx)%sf(i, j, k)
1432 egint = egint + q_prim_vf(e_idx + 2)%sf(i, j, k)*(gammas(2)*pres)*dv
1433 do s = 1, num_vels
1434 vel(s) = q_prim_vf(num_fluids + s)%sf(i, j, k)
1435 egk = egk + 0.5_wp*q_prim_vf(e_idx + 2)%sf(i, j, k)*q_prim_vf(2)%sf(i, j, k)*vel(s)*vel(s)*dv
1436 elk = elk + 0.5_wp*q_prim_vf(e_idx + 1)%sf(i, j, k)*q_prim_vf(1)%sf(i, j, k)*vel(s)*vel(s)*dv
1437 if (abs(vel(s)) > maxvel) then
1438 maxvel = abs(vel(s))
1439 end if
1440 end do
1441 do l = 1, adv_idx%end - e_idx
1442 adv(l) = q_prim_vf(e_idx + l)%sf(i, j, k)
1443 gamma = gamma + adv(l)*gammas(l)
1444 pi_inf = pi_inf + adv(l)*pi_infs(l)
1445 rho = rho + adv(l)*q_prim_vf(l)%sf(i, j, k)
1446 qv = qv + adv(l)*q_prim_vf(l)%sf(i, j, k)*qvs(l)
1447 end do
1448
1449 h = ((gamma + 1._wp)*pres + pi_inf + qv)/rho
1450
1451 call s_compute_speed_of_sound(pres, rho, gamma, pi_inf, h, adv, 0._wp, 0._wp, c, qv)
1452
1453 ma = maxvel/c
1454 if (ma > maxma .and. (adv(1) > (1.0_wp - 1.0e-10_wp))) then
1455 maxma = ma
1456 end if
1457 vl = vl + adv(1)*dv
1458 vb = vb + adv(2)*dv
1459 pres_av = pres_av + adv(1)*pres*dv
1460 et = et + q_cons_vf(e_idx)%sf(i, j, k)*dv
1461 end do
1462 end do
1463 end do
1464
1465 tmp = pres_av
1466 call s_mpi_allreduce_sum(tmp, pres_av)
1467 tmp = vl
1468 call s_mpi_allreduce_sum(tmp, vl)
1469
1470 call s_mpi_allreduce_max(maxma, maxma_glb)
1471 tmp = elk
1472 call s_mpi_allreduce_sum(tmp, elk)
1473 tmp = egint
1474 call s_mpi_allreduce_sum(tmp, egint)
1475 tmp = egk
1476 call s_mpi_allreduce_sum(tmp, egk)
1477 tmp = vb
1478 call s_mpi_allreduce_sum(tmp, vb)
1479 tmp = et
1480 call s_mpi_allreduce_sum(tmp, et)
1481
1482 elp = pres_av/vl*vb
1483 if (proc_rank == 0) then
1484 write (251, '(10X, 8F24.8)') elp, egint, elk, egk, et, vb, vl, maxma_glb
1485 end if
1486
1487 end subroutine s_write_energy_data_file
1488
1489 !> Close the formatted database slave file and, for the root process, the master file.
1491
1492 integer :: ierr
1493
1494 if (format == 1) then
1495 ierr = dbclose(dbfile)
1496 if (proc_rank == 0) ierr = dbclose(dbroot)
1497 else
1498 close (dbfile)
1499 if (n == 0 .and. proc_rank == 0) close (dbroot)
1500 end if
1501
1502 end subroutine s_close_formatted_database_file
1503
1504 !> Close the interface data file.
1505 impure subroutine s_close_intf_data_file()
1506
1507 close (211)
1508
1509 end subroutine s_close_intf_data_file
1510
1511 !> Close the energy data file.
1512 impure subroutine s_close_energy_data_file()
1513
1514 close (251)
1515
1516 end subroutine s_close_energy_data_file
1517
1518 !> Deallocate module arrays and release all data-output resources.
1520
1521 deallocate (q_sf)
1522 if (n == 0) deallocate (q_root_sf)
1523 if (grid_geometry == 3) then
1524 deallocate (cyl_q_sf)
1525 end if
1526
1527 ! Deallocating spatial and data extents and also the variables for the offsets and the one bookkeeping the number of
1528 ! cell-boundaries in each active coordinate direction. Note that all these variables were only needed by Silo-HDF5 format
1529 ! for multidimensional data.
1530 if (format == 1) then
1531 deallocate (spatial_extents)
1532 deallocate (data_extents)
1533 deallocate (lo_offset)
1534 deallocate (hi_offset)
1535 deallocate (dims)
1536 end if
1537
1538 end subroutine s_finalize_data_output_module
1539
1540end module m_data_output
type(scalar_field), dimension(sys_size), intent(inout) q_cons_vf
integer, intent(in) k
integer, intent(in) j
integer, intent(in) l
Platform-specific file and directory operations: create, delete, inquire, getcwd, and basename.
impure subroutine my_inquire(fileloc, dircheck)
Inquires on the existence of a directory.
impure subroutine s_create_directory(dir_name)
Create a directory and all its parents if it does not exist.
Writes post-processed grid and flow-variable data to Silo-HDF5 or binary database files.
impure subroutine, public s_write_grid_to_formatted_database_file(t_step)
Write the computational grid (cell-boundary coordinates) to the formatted database slave and master f...
real(wp), dimension(:,:,:), allocatable cyl_q_sf
integer, dimension(:), allocatable hi_offset
real(wp), dimension(:,:), allocatable data_extents
impure subroutine, public s_write_variable_to_formatted_database_file(varname, t_step)
Write a single flow variable field to the formatted database slave and master files for a given time ...
impure subroutine, public s_open_energy_data_file()
Open the energy data file for appending volume-integrated energy budget quantities.
impure subroutine, public s_open_intf_data_file()
Open the interface data file for appending extracted interface coordinates.
character(len=path_len+name_len) dbdir
impure subroutine, public s_write_ib_state_files()
Convert the binary immersed-boundary state file to per-body formatted text files.
impure subroutine, public s_write_energy_data_file(q_prim_vf, q_cons_vf)
Compute volume-integrated kinetic, potential, and internal energies and write the energy budget to th...
impure subroutine, public s_write_lag_bubbles_to_formatted_database_file(t_step)
Read Lagrangian bubble restart data and write bubble positions and scalar fields to the Silo database...
integer, dimension(:), allocatable lo_offset
impure subroutine, public s_write_intf_data_file(q_prim_vf)
Extract the volume-fraction interface contour from primitive fields and write the coordinates to the ...
real(wp), dimension(:,:,:), allocatable q_root_sf
impure subroutine, public s_initialize_data_output_module()
Allocate storage arrays, configure output directories, and count flow variables for formatted databas...
real(wp), dimension(:,:,:), allocatable, public q_sf
impure subroutine, public s_close_energy_data_file()
Close the energy data file.
impure subroutine, public s_close_formatted_database_file()
Close the formatted database slave file and, for the root process, the master file.
real(sp), dimension(:,:,:), allocatable cyl_q_sf_s
impure subroutine, public s_open_formatted_database_file(t_step)
Open (or create) the Silo-HDF5 or Binary formatted database slave and master files for a given time s...
impure subroutine, public s_close_intf_data_file()
Close the interface data file.
impure subroutine, public s_write_lag_bubbles_results_to_text(t_step)
Write the post-processed results in the folder 'lag_bubbles_data'.
impure subroutine, public s_finalize_data_output_module()
Deallocate module arrays and release all data-output resources.
real(sp), dimension(:,:,:), allocatable q_root_sf_s
integer, private err
integer, dimension(:), allocatable dims
real(wp), dimension(:,:), allocatable spatial_extents
impure subroutine, public s_define_output_region
Compute the cell-index bounds for the user-specified partial output domain in each coordinate directi...
character(len=path_len+2 *name_len) proc_rank_dir
subroutine s_write_lag_variable_to_formatted_database_file(varname, t_step, data, nbubs)
Write a single Lagrangian bubble point-variable to the Silo database slave and master files.
real(sp), dimension(:,:,:), allocatable, public q_sf_s
character(len=path_len+2 *name_len) rootdir
Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures.
Computes derived flow quantities (sound speed, vorticity, Schlieren, etc.) from conservative and prim...
Global parameters for the post-process: domain geometry, equation of state, and output database setti...
logical cont_damage
Continuum damage modeling.
logical hypoelasticity
Turn hypoelasticity on.
type(int_bounds_info) offset_y
type(int_bounds_info) mom_idx
Indexes of first & last momentum eqns.
integer num_fluids
Number of different fluids present in the flow.
real(wp), dimension(:,:), allocatable, public mpi_io_data_lg_bubbles
logical, dimension(3) flux_wrt
real(wp), dimension(:), allocatable y_cc
integer proc_rank
Rank of the local processor.
logical output_partial_domain
Specify portion of domain to output for post-processing.
real(wp), dimension(:), allocatable adv
Advection variables.
type(int_bounds_info) z_output_idx
Indices of domain to output for post-processing.
logical dummy
AMDFlang workaround for case-optimization + GPU-kernel bug.
real(wp), dimension(:), allocatable y_cb
character(len=name_len) mpiiofs
real(wp), dimension(:), allocatable dz
logical, dimension(3) mom_wrt
real(wp), dimension(:), allocatable x_root_cb
logical, dimension(num_fluids_max) alpha_wrt
logical, dimension(num_fluids_max) alpha_rho_wrt
integer model_eqns
Multicomponent flow model.
integer precision
Floating point precision of the database file(s).
real(wp), dimension(:), allocatable z_cb
type(bounds_info) z_output
Portion of domain to output for post-processing.
integer num_dims
Number of spatial dimensions.
type(int_bounds_info) x_output_idx
real(wp), dimension(:), allocatable x_cc
integer num_vels
Number of velocity components (different from num_dims for mhd).
real(wp), dimension(:), allocatable x_cb
real(wp), dimension(:), allocatable dy
type(int_bounds_info) offset_x
logical hyper_cleaning
Hyperbolic cleaning for MHD.
real(wp), dimension(:), allocatable z_cc
logical, dimension(3) omega_wrt
integer num_procs
Number of processors.
character(len=path_len) case_dir
Case folder location.
type(int_bounds_info) y_output_idx
type(int_bounds_info) adv_idx
Indexes of first & last advection eqns.
type(int_bounds_info) offset_z
logical mhd
Magnetohydrodynamics.
logical parallel_io
Format of the data files.
integer e_idx
Index of energy equation.
logical, dimension(3) vel_wrt
logical relativity
Relativity for RMHD.
real(wp), dimension(:), allocatable dx
Cell-width distributions in the x-, y- and z-coordinate directions.
integer num_ibs
Number of immersed boundaries.
Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions...
MPI gather and scatter operations for distributing post-process grid and flow-variable data.
impure subroutine s_mpi_defragment_1d_grid_variable
Collect the sub-domain cell-boundary or cell-center location data from all processors and put back to...
impure subroutine s_mpi_defragment_1d_flow_variable(q_sf, q_root_sf)
Gather the sub-domain flow variable data from all processors and reassemble it for the entire computa...
impure subroutine s_mpi_gather_spatial_extents(spatial_extents)
Gather spatial extents from all ranks for Silo database metadata.
impure subroutine s_mpi_gather_data_extents(q_sf, data_extents)
Gather the Silo database metadata for the flow variable's extents to boost performance of the multidi...
Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation.
real(wp), dimension(:), allocatable, public gammas
subroutine s_compute_speed_of_sound(pres, rho, gamma, pi_inf, h, adv, vel_sum, c_c, c, qv)
Compute the speed of sound from thermodynamic state variables, supporting multiple equation-of-state ...
real(wp), dimension(:), allocatable, public qvs
real(wp), dimension(:), allocatable, public pi_infs
Derived type annexing a scalar field (SF).