MFC
Exascale flow solver
Loading...
Searching...
No Matches
m_start_up.fpp.f90
Go to the documentation of this file.
1# 1 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2!>
3!! @file
4!! @brief Contains module m_start_up
5
6# 1 "/home/runner/work/MFC/MFC/src/common/include/case.fpp" 1
7! This file exists so that Fypp can be run without generating case.fpp files for
8! each target. This is useful when generating documentation, for example. This
9! should also let MFC be built with CMake directly, without invoking mfc.sh.
10
11! For pre-process.
12# 8 "/home/runner/work/MFC/MFC/src/common/include/case.fpp"
13
14! For moving immersed boundaries in simulation
15# 12 "/home/runner/work/MFC/MFC/src/common/include/case.fpp"
16# 6 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp" 2
17# 1 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 1
18# 1 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 1
19# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
20# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
21# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
22# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
23# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
24# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
25
26# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
27# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
28# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
29
30# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
31
32# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
33
34# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
35
36# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
37
38# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
39
40# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
41
42# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
43! New line at end of file is required for FYPP
44# 2 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
45# 1 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 1
46# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
47# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
48# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
49# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
50# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
51# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
52
53# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
54# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
55# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
56
57# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
58
59# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
60
61# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
62
63# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
64
65# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
66
67# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
68
69# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
70! New line at end of file is required for FYPP
71# 2 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 2
72
73# 4 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
74# 5 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
75# 6 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
76# 7 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
77# 8 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
78
79# 20 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
80
81# 43 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
82
83# 48 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
84
85# 53 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
86
87# 58 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
88
89# 63 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
90
91# 68 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
92
93# 76 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
94
95# 81 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
96
97# 86 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
98
99# 91 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
100
101# 96 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
102
103# 101 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
104
105# 106 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
106
107# 111 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
108
109# 116 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
110
111# 121 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
112
113# 151 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
114
115# 192 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
116
117# 206 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
118
119# 231 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
120
121# 242 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
122
123# 244 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
124# 255 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
125
126# 284 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
127
128# 294 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
129
130# 304 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
131
132# 313 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
133
134# 330 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
135
136# 340 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
137
138# 347 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
139
140# 353 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
141
142# 359 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
143
144# 365 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
145
146# 371 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
147
148# 377 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
149! New line at end of file is required for FYPP
150# 3 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
151# 1 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 1
152# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
153# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
154# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
155# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
156# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
157# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
158
159# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
160# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
161# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
162
163# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
164
165# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
166
167# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
168
169# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
170
171# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
172
173# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
174
175# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
176! New line at end of file is required for FYPP
177# 2 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 2
178
179# 7 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
180
181# 17 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
182
183# 22 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
184
185# 27 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
186
187# 32 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
188
189# 37 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
190
191# 42 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
192
193# 47 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
194
195# 52 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
196
197# 57 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
198
199# 62 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
200
201# 73 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
202
203# 78 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
204
205# 83 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
206
207# 88 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
208
209# 103 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
210
211# 131 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
212
213# 160 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
214
215# 175 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
216
217# 193 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
218
219# 215 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
220
221# 244 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
222
223# 259 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
224
225# 269 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
226
227# 278 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
228
229# 294 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
230
231# 304 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
232
233# 311 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
234! New line at end of file is required for FYPP
235# 4 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
236
237! GPU parallel region (scalar reductions, maxval/minval)
238# 23 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
239
240! GPU parallel loop over threads (most common GPU macro)
241# 43 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
242
243! Required closing for GPU_PARALLEL_LOOP
244# 55 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
245
246! Mark routine for device compilation
247# 112 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
248
249! Declare device-resident data
250# 130 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
251
252! Inner loop within a GPU parallel region
253# 145 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
254
255! Scoped GPU data region
256# 164 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
257
258! Host code with device pointers (for MPI with GPU buffers)
259# 193 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
260
261! Allocate device memory (unscoped)
262# 207 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
263
264! Free device memory
265# 219 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
266
267! Atomic operation on device
268# 231 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
269
270! End atomic capture block
271# 242 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
272
273! Copy data between host and device
274# 254 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
275
276! Synchronization barrier
277# 266 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
278
279! Import GPU library module (openacc or omp_lib)
280# 275 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
281
282! Emit code only for AMD compiler
283# 282 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
284
285! Emit code for non-Cray compilers
286# 289 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
287
288! Emit code only for Cray compiler
289# 296 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
290
291! Emit code for non-NVIDIA compilers
292# 303 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
293
294# 305 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
295# 306 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
296! New line at end of file is required for FYPP
297# 2 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 2
298
299# 14 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
300
301! Caution: This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI
302! rank. That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. For an
303! example see misc/nvidia_uvm/bind.sh. NVIDIA unified memory page placement hint
304# 57 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
305
306! Allocate and create GPU device memory
307# 77 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
308
309! Free GPU device memory and deallocate
310# 85 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
311
312! Cray-specific GPU pointer setup for vector fields
313# 109 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
314
315! Cray-specific GPU pointer setup for scalar fields
316# 125 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
317
318! Cray-specific GPU pointer setup for acoustic source spatials
319# 150 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
320
321# 156 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
322
323# 163 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
324! New line at end of file is required for FYPP
325# 7 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp" 2
326
327!> @brief Reads input files, loads initial conditions and grid data, and orchestrates solver initialization and finalization
329
332 use m_mpi_proxy
333 use m_mpi_common
335 use m_weno
336 use m_muscl
337 use m_thinc
339 use m_cbc
342 use m_rhs
343 use m_chemistry
344 use m_data_output
346 use m_qbmm
348 use m_hypoelastic
351 use m_viscous
352 use m_bubbles_ee
353 use m_bubbles_el
354 use ieee_arithmetic
356 use m_helper
357
358#if defined(MFC_OpenACC)
359# 39 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
360 use openacc
361# 39 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
362#elif defined(MFC_OpenMP)
363# 39 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
364 use omp_lib
365# 39 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
366#endif
367
368 use m_nvtx
369 use m_ibm
370 use m_ib_patches
371 use m_model
373 use m_collisions
376 use m_checker
378 use m_body_forces
379 use m_sim_helpers
380 use m_igr
381
382 implicit none
383
387
388 type(scalar_field), allocatable, dimension(:) :: q_cons_temp
389 real(wp) :: dt_init
390
391contains
392
393 !> Read data files. Dispatch subroutine that replaces procedure pointer.
394 impure subroutine s_read_data_files(q_cons_vf)
395
396 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
397
398 if (.not. parallel_io) then
400 else
402 end if
403
404 end subroutine s_read_data_files
405
406 !> Verify the input file exists and read it
407 impure subroutine s_read_input_file
408
409 character(LEN=name_len), parameter :: file_path = './simulation.inp'
410 logical :: file_exist !< Logical used to check the existence of the input file
411 integer :: iostatus
412 ! Integer to check iostat of file read
413
414 character(len=1000) :: line
415
416# 1 "/home/runner/work/MFC/MFC/build/include/simulation/generated_namelist.fpp" 1
417! AUTO-GENERATED - do not edit directly. Regenerate: cmake reconfigure
418!
419# 19 "/home/runner/work/MFC/MFC/build/include/simulation/generated_namelist.fpp"
436# 36 "/home/runner/work/MFC/MFC/build/include/simulation/generated_namelist.fpp"
437# 90 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp" 2
438
439 inquire (file=trim(file_path), exist=file_exist)
440
441 if (file_exist) then
442 open (1, file=trim(file_path), form='formatted', action='read', status='old')
443 read (1, nml=user_inputs, iostat=iostatus)
444
445 if (iostatus /= 0) then
446 backspace(1)
447 read (1, fmt='(A)') line
448 print *, 'Invalid line in namelist: ' // trim(line)
449 call s_mpi_abort('Invalid line in simulation.inp. It is ' // 'likely due to a datatype mismatch. Exiting.')
450 end if
451
452 close (1)
453
454 if ((bf_x) .or. (bf_y) .or. (bf_z)) then
455 bodyforces = .true.
456 end if
457
458 m_glb = m
459 n_glb = n
460 p_glb = p
461
463
464 if (cfl_adap_dt .or. cfl_const_dt) cfl_dt = .true.
465
466 if (any((/bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end/) == -17) .or. num_bc_patches > 0) then
467 bc_io = .true.
468 end if
469 else
470 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
471 end if
472
473 end subroutine s_read_input_file
474
475 !> Validate that all user-provided inputs form a consistent simulation configuration
476 impure subroutine s_check_input_file
477
478 character(LEN=path_len) :: file_path
479 logical :: file_exist
480
481 file_path = trim(case_dir) // '/.'
482
483 call my_inquire(file_path, file_exist)
484
485 if (file_exist .neqv. .true.) then
486 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
487 end if
488
490 call s_check_inputs()
491
492 end subroutine s_check_input_file
493
494 !> Read serial initial condition and grid data files and compute cell-width distributions
495 impure subroutine s_read_serial_data_files(q_cons_vf)
496
497 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
498 character(LEN=path_len + 2*name_len) :: t_step_dir !< Relative path to the starting time-step directory
499 character(LEN=path_len + 3*name_len) :: file_path !< Relative path to the grid and conservative variables data files
500 logical :: file_exist !< Logical used to check the existence of the input file
501 integer :: i, r
502
503 if (cfl_dt) then
504 write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', n_start
505 else
506 write (t_step_dir, '(A,I0,A,I0)') trim(case_dir) // '/p_all/p', proc_rank, '/', t_step_start
507 end if
508
509 file_path = trim(t_step_dir) // '/.'
510 call my_inquire(file_path, file_exist)
511
512 if (file_exist .neqv. .true.) then
513 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
514 end if
515
516 if (bc_io) then
518 else
520 end if
521
522 file_path = trim(t_step_dir) // '/x_cb.dat'
523
524 inquire (file=trim(file_path), exist=file_exist)
525
526 if (file_exist) then
527 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
528 read (2) x_cb(-1:m); close (2)
529 else
530 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
531 end if
532
533 dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1)
534 x_cc(0:m) = x_cb(-1:m - 1) + dx(0:m)/2._wp
535
536 if (n > 0) then
537 file_path = trim(t_step_dir) // '/y_cb.dat'
538
539 inquire (file=trim(file_path), exist=file_exist)
540
541 if (file_exist) then
542 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
543 read (2) y_cb(-1:n); close (2)
544 else
545 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
546 end if
547
548 dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1)
549 y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp
550 end if
551
552 if (p > 0) then
553 file_path = trim(t_step_dir) // '/z_cb.dat'
554
555 inquire (file=trim(file_path), exist=file_exist)
556
557 if (file_exist) then
558 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
559 read (2) z_cb(-1:p); close (2)
560 else
561 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
562 end if
563
564 dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1)
565 z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp
566 end if
567
568 do i = 1, sys_size
569 write (file_path, '(A,I0,A)') trim(t_step_dir) // '/q_cons_vf', i, '.dat'
570 inquire (file=trim(file_path), exist=file_exist)
571 if (file_exist) then
572 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
573 read (2) q_cons_vf(i)%sf(0:m,0:n,0:p); close (2)
574 else
575 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
576 end if
577 end do
578
579 if (bubbles_euler .or. elasticity) then
580 ! Read pb and mv for non-polytropic qbmm
581 if (qbmm .and. .not. polytropic) then
582 do i = 1, nb
583 do r = 1, nnode
584 write (file_path, '(A,I0,A)') trim(t_step_dir) // '/pb', sys_size + (i - 1)*nnode + r, '.dat'
585 inquire (file=trim(file_path), exist=file_exist)
586 if (file_exist) then
587 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
588 read (2) pb_ts(1)%sf(0:m,0:n,0:p,r, i); close (2)
589 else
590 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
591 end if
592 end do
593 end do
594 do i = 1, nb
595 do r = 1, nnode
596 write (file_path, '(A,I0,A)') trim(t_step_dir) // '/mv', sys_size + (i - 1)*nnode + r, '.dat'
597 inquire (file=trim(file_path), exist=file_exist)
598 if (file_exist) then
599 open (2, file=trim(file_path), form='unformatted', action='read', status='old')
600 read (2) mv_ts(1)%sf(0:m,0:n,0:p,r, i); close (2)
601 else
602 call s_mpi_abort(trim(file_path) // ' is missing. Exiting.')
603 end if
604 end do
605 end do
606 end if
607 end if
608
609 end subroutine s_read_serial_data_files
610
611 !> Read parallel initial condition and grid data files via MPI I/O
612 impure subroutine s_read_parallel_data_files(q_cons_vf)
613
614 type(scalar_field), dimension(sys_size), intent(inout) :: q_cons_vf
615
616#ifdef MFC_MPI
617 real(wp), allocatable, dimension(:) :: x_cb_glb, y_cb_glb, z_cb_glb
618 integer :: ifile, ierr, data_size
619 integer, dimension(MPI_STATUS_SIZE) :: status
620 integer(KIND=MPI_OFFSET_KIND) :: disp
621 integer(KIND=MPI_OFFSET_KIND) :: m_mok, n_mok, p_mok
622 integer(KIND=MPI_OFFSET_KIND) :: wp_mok, var_mok
623 integer(KIND=MPI_OFFSET_KIND) :: mok
624 character(LEN=path_len + 2*name_len) :: file_loc
625 logical :: file_exist
626 character(len=10) :: t_step_start_string
627 integer :: i, j
628
629 ! Downsampled data variables
630 integer :: m_ds, n_ds, p_ds
631 integer :: m_glb_ds, n_glb_ds, p_glb_ds
632 integer :: m_glb_read, n_glb_read, p_glb_read !< data size of read
633
634 allocate (x_cb_glb(-1:m_glb))
635 allocate (y_cb_glb(-1:n_glb))
636 allocate (z_cb_glb(-1:p_glb))
637
638 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'x_cb.dat'
639 inquire (file=trim(file_loc), exist=file_exist)
640
641 if (down_sample) then
642 m_ds = int((m + 1)/3) - 1
643 n_ds = int((n + 1)/3) - 1
644 p_ds = int((p + 1)/3) - 1
645
646 m_glb_ds = int((m_glb + 1)/3) - 1
647 n_glb_ds = int((n_glb + 1)/3) - 1
648 p_glb_ds = int((p_glb + 1)/3) - 1
649 end if
650
651 if (file_exist) then
652 data_size = m_glb + 2
653 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
654 call mpi_file_read(ifile, x_cb_glb, data_size, mpi_p, status, ierr)
655 call mpi_file_close(ifile, ierr)
656 else
657 call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.')
658 end if
659
660 x_cb(-1:m) = x_cb_glb((start_idx(1) - 1):(start_idx(1) + m))
661 dx(0:m) = x_cb(0:m) - x_cb(-1:m - 1)
662 x_cc(0:m) = x_cb(-1:m - 1) + dx(0:m)/2._wp
663
664 if (n > 0) then
665 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'y_cb.dat'
666 inquire (file=trim(file_loc), exist=file_exist)
667
668 if (file_exist) then
669 data_size = n_glb + 2
670 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
671 call mpi_file_read(ifile, y_cb_glb, data_size, mpi_p, status, ierr)
672 call mpi_file_close(ifile, ierr)
673 else
674 call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.')
675 end if
676
677 y_cb(-1:n) = y_cb_glb((start_idx(2) - 1):(start_idx(2) + n))
678 dy(0:n) = y_cb(0:n) - y_cb(-1:n - 1)
679 y_cc(0:n) = y_cb(-1:n - 1) + dy(0:n)/2._wp
680
681 if (p > 0) then
682 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // 'z_cb.dat'
683 inquire (file=trim(file_loc), exist=file_exist)
684
685 if (file_exist) then
686 data_size = p_glb + 2
687 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
688 call mpi_file_read(ifile, z_cb_glb, data_size, mpi_p, status, ierr)
689 call mpi_file_close(ifile, ierr)
690 else
691 call s_mpi_abort('File ' // trim(file_loc) // 'is missing. Exiting.')
692 end if
693
694 z_cb(-1:p) = z_cb_glb((start_idx(3) - 1):(start_idx(3) + p))
695 dz(0:p) = z_cb(0:p) - z_cb(-1:p - 1)
696 z_cc(0:p) = z_cb(-1:p - 1) + dz(0:p)/2._wp
697 end if
698 end if
699
700 if (file_per_process) then
701 if (cfl_dt) then
702 call s_int_to_str(n_start, t_step_start_string)
703 write (file_loc, '(I0,A1,I7.7,A)') n_start, '_', proc_rank, '.dat'
704 else
705 call s_int_to_str(t_step_start, t_step_start_string)
706 write (file_loc, '(I0,A1,I7.7,A)') t_step_start, '_', proc_rank, '.dat'
707 end if
708 file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_start_string) // trim(mpiiofs) // trim(file_loc)
709 inquire (file=trim(file_loc), exist=file_exist)
710
711 if (file_exist) then
712 call mpi_file_open(mpi_comm_self, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
713
714 if (down_sample) then
716 else
717 if (ib) then
719 else
721 end if
722 end if
723
724 if (down_sample) then
725 data_size = (m_ds + 3)*(n_ds + 3)*(p_ds + 3)
726 m_glb_read = m_glb_ds + 1
727 n_glb_read = n_glb_ds + 1
728 p_glb_read = p_glb_ds + 1
729 else
730 data_size = (m + 1)*(n + 1)*(p + 1)
731 m_glb_read = m_glb + 1
732 n_glb_read = n_glb + 1
733 p_glb_read = p_glb + 1
734 end if
735
736 m_mok = int(m_glb_read + 1, mpi_offset_kind)
737 n_mok = int(m_glb_read + 1, mpi_offset_kind)
738 p_mok = int(m_glb_read + 1, mpi_offset_kind)
739 wp_mok = int(storage_size(0._stp)/8, mpi_offset_kind)
740 mok = int(1._wp, mpi_offset_kind)
741
742 if (bubbles_euler .or. elasticity) then
743 do i = 1, sys_size
744 var_mok = int(i, mpi_offset_kind)
745
746 call mpi_file_read(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
747 end do
748 ! Read pb and mv for non-polytropic qbmm
749 if (qbmm .and. .not. polytropic) then
750 do i = sys_size + 1, sys_size + 2*nb*nnode
751 var_mok = int(i, mpi_offset_kind)
752
753 call mpi_file_read(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
754 end do
755 end if
756 else
757 if (down_sample) then
758 do i = 1, sys_size
759 var_mok = int(i, mpi_offset_kind)
760
761 call mpi_file_read(ifile, q_cons_temp(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
762 end do
763 else
764 do i = 1, sys_size
765 var_mok = int(i, mpi_offset_kind)
766
767 call mpi_file_read(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
768 end do
769 end if
770 end if
771
772 call s_mpi_barrier()
773
774 call mpi_file_close(ifile, ierr)
775 else
776 call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.')
777 end if
778 else
779 if (cfl_dt) then
780 write (file_loc, '(I0,A)') n_start, '.dat'
781 else
782 write (file_loc, '(I0,A)') t_step_start, '.dat'
783 end if
784 file_loc = trim(case_dir) // '/restart_data' // trim(mpiiofs) // trim(file_loc)
785 inquire (file=trim(file_loc), exist=file_exist)
786
787 if (file_exist) then
788 call mpi_file_open(mpi_comm_world, file_loc, mpi_mode_rdonly, mpi_info_int, ifile, ierr)
789
790 if (ib) then
792 else
794 end if
795
796 data_size = (m + 1)*(n + 1)*(p + 1)
797
798 m_mok = int(m_glb + 1, mpi_offset_kind)
799 n_mok = int(n_glb + 1, mpi_offset_kind)
800 p_mok = int(p_glb + 1, mpi_offset_kind)
801 wp_mok = int(storage_size(0._stp)/8, mpi_offset_kind)
802 mok = int(1._wp, mpi_offset_kind)
803
804 if (bubbles_euler .or. elasticity) then
805 do i = 1, sys_size
806 var_mok = int(i, mpi_offset_kind)
807 disp = m_mok*max(mok, n_mok)*max(mok, p_mok)*wp_mok*(var_mok - 1)
808
809 call mpi_file_set_view(ifile, disp, mpi_io_p, mpi_io_data%view(i), 'native', mpi_info_int, ierr)
810 call mpi_file_read(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
811 end do
812 ! Read pb and mv for non-polytropic qbmm
813 if (qbmm .and. .not. polytropic) then
814 do i = sys_size + 1, sys_size + 2*nb*nnode
815 var_mok = int(i, mpi_offset_kind)
816 disp = m_mok*max(mok, n_mok)*max(mok, p_mok)*wp_mok*(var_mok - 1)
817
818 call mpi_file_set_view(ifile, disp, mpi_io_p, mpi_io_data%view(i), 'native', mpi_info_int, ierr)
819 call mpi_file_read(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
820 end do
821 end if
822 else
823 do i = 1, sys_size
824 var_mok = int(i, mpi_offset_kind)
825
826 disp = m_mok*max(mok, n_mok)*max(mok, p_mok)*wp_mok*(var_mok - 1)
827
828 call mpi_file_set_view(ifile, disp, mpi_io_p, mpi_io_data%view(i), 'native', mpi_info_int, ierr)
829 call mpi_file_read_all(ifile, mpi_io_data%var(i)%sf, data_size*mpi_io_type, mpi_io_p, status, ierr)
830 end do
831 end if
832
833 call s_mpi_barrier()
834
835 call mpi_file_close(ifile, ierr)
836 else
837 call s_mpi_abort('File ' // trim(file_loc) // ' is missing. Exiting.')
838 end if
839 end if
840
841 deallocate (x_cb_glb, y_cb_glb, z_cb_glb)
842
843 if (bc_io) then
845 else
847 end if
848#endif
849
850 end subroutine s_read_parallel_data_files
851
852 !> Initialize internal-energy equations from phase mass, mixture momentum, and total energy
854
855 type(scalar_field), dimension(sys_size), intent(inout) :: v_vf
856 real(wp) :: rho
857 real(wp) :: dyn_pres
858 real(wp) :: gamma
859 real(wp) :: pi_inf
860 real(wp) :: qv
861 real(wp), dimension(2) :: re
862 real(wp) :: pres, t
863 integer :: i, j, k, l, c
864 real(wp), dimension(num_species) :: rhoyks
865 real(wp) :: pres_mag
866
867 pres_mag = 0._wp
868
869 t = dflt_t_guess
870
871 do j = 0, m
872 do k = 0, n
873 do l = 0, p
874 call s_convert_to_mixture_variables(v_vf, j, k, l, rho, gamma, pi_inf, qv, re)
875
876 dyn_pres = 0._wp
877 do i = eqn_idx%mom%beg, eqn_idx%mom%end
878 dyn_pres = dyn_pres + 5.e-1_wp*v_vf(i)%sf(j, k, l)*v_vf(i)%sf(j, k, l)/max(rho, sgm_eps)
879 end do
880
881 if (chemistry) then
882 do c = 1, num_species
883 rhoyks(c) = v_vf(eqn_idx%species%beg + c - 1)%sf(j, k, l)
884 end do
885 end if
886
887 if (mhd) then
888 if (n == 0) then
889 pres_mag = 0.5_wp*(bx0**2 + v_vf(eqn_idx%B%beg)%sf(j, k, l)**2 + v_vf(eqn_idx%B%beg + 1)%sf(j, k, l)**2)
890 else
891 pres_mag = 0.5_wp*(v_vf(eqn_idx%B%beg)%sf(j, k, l)**2 + v_vf(eqn_idx%B%beg + 1)%sf(j, k, &
892 & l)**2 + v_vf(eqn_idx%B%beg + 2)%sf(j, k, l)**2)
893 end if
894 end if
895
896 call s_compute_pressure(v_vf(eqn_idx%E)%sf(j, k, l), 0._stp, dyn_pres, pi_inf, gamma, rho, qv, rhoyks, pres, &
897 & t, pres_mag=pres_mag)
898
899 do i = 1, num_fluids
900 v_vf(i + eqn_idx%int_en%beg - 1)%sf(j, k, l) = v_vf(i + eqn_idx%adv%beg - 1)%sf(j, k, &
901 & l)*(gammas(i)*pres + pi_infs(i)) + v_vf(i + eqn_idx%cont%beg - 1)%sf(j, k, l)*qvs(i)
902 end do
903 end do
904 end do
905 end do
906
908
909 !> Advance the simulation by one time step, handling CFL-based dt and time-stepper dispatch
910 impure subroutine s_perform_time_step(t_step, time_avg)
911
912 integer, intent(inout) :: t_step
913 real(wp), intent(inout) :: time_avg
914 integer :: i, eta_hh, eta_mm, eta_ss
915 real(wp) :: eta_sec
916
917 if (cfl_dt) then
918 if (cfl_const_dt .and. t_step == 0) call s_compute_dt()
919
920 if (cfl_adap_dt) call s_compute_dt()
921
922 if (t_step == 0) dt_init = dt
923
924 if (dt < 1.e-3_wp*dt_init .and. cfl_adap_dt .and. proc_rank == 0) then
925 print *, "Delta t = ", dt
926 call s_mpi_abort("Delta t has become too small")
927 end if
928 end if
929
930 if (cfl_dt) then
931 if ((mytime + dt) >= t_stop) then
932 dt = t_stop - mytime
933
934# 585 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
935#if defined(MFC_OpenACC)
936# 585 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
937!$acc update device(dt)
938# 585 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
939#elif defined(MFC_OpenMP)
940# 585 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
941!$omp target update to(dt)
942# 585 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
943#endif
944 end if
945 else
946 if ((mytime + dt) >= finaltime) then
948
949# 590 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
950#if defined(MFC_OpenACC)
951# 590 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
952!$acc update device(dt)
953# 590 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
954#elif defined(MFC_OpenMP)
955# 590 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
956!$omp target update to(dt)
957# 590 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
958#endif
959 end if
960 end if
961
962 if (cfl_dt) then
963 if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then
964 eta_sec = wall_time_avg*(t_stop - mytime)/max(dt, tiny(dt))
965 eta_hh = int(eta_sec)/3600
966 eta_mm = mod(int(eta_sec), 3600)/60
967 eta_ss = mod(int(eta_sec), 60)
968 print '(" [", I3, "%] Time ", ES16.6, " dt = ", ES16.6, " @ Time Step = ", I8, " Time Avg = ", ES16.6, " Time/step = ", ES12.6, " ETA (HH:MM:SS) = ", I0, ":", I2.2, ":", I2.2)', &
969 & int(ceiling(100._wp*(mytime/t_stop))), mytime, dt, t_step, wall_time_avg, wall_time, eta_hh, eta_mm, eta_ss
970 end if
971 else
972 if (proc_rank == 0 .and. mod(t_step - t_step_start, t_step_print) == 0) then
973 eta_sec = wall_time_avg*real(t_step_stop - t_step, wp)
974 eta_hh = int(eta_sec)/3600
975 eta_mm = mod(int(eta_sec), 3600)/60
976 eta_ss = mod(int(eta_sec), 60)
977 print '(" [", I3, "%] Time step ", I8, " of ", I0, " @ t_step = ", I8, " Time Avg = ", ES12.6, " Time/step= ", ES12.6, " ETA (HH:MM:SS) = ", I0, ":", I2.2, ":", I2.2)', &
978 & int(ceiling(100._wp*(real(t_step - t_step_start)/(t_step_stop - t_step_start + 1)))), &
979 & t_step - t_step_start + 1, t_step_stop - t_step_start + 1, t_step, wall_time_avg, wall_time, eta_hh, &
980 & eta_mm, eta_ss
981 end if
982 end if
983
984 if (probe_wrt) then
985 do i = 1, sys_size
986
987# 618 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
988#if defined(MFC_OpenACC)
989# 618 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
990!$acc update host(q_cons_ts(1)%vf(i)%sf)
991# 618 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
992#elif defined(MFC_OpenMP)
993# 618 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
994!$omp target update from(q_cons_ts(1)%vf(i)%sf)
995# 618 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
996#endif
997 end do
998 end if
999
1000 ! Total-variation-diminishing (TVD) Runge-Kutta (RK) time-steppers
1001 if (any(time_stepper == (/1, 2, 3/))) then
1002 call s_tvd_rk(t_step, time_avg, time_stepper)
1003 end if
1004
1005 ! Advance time after RK so source terms see current-step time
1006 mytime = mytime + dt
1007
1008 if (relax) call s_infinite_relaxation_k(q_cons_ts(1)%vf)
1009
1010 ! Time-stepping loop controls
1011 t_step = t_step + 1
1012
1013 end subroutine s_perform_time_step
1014
1015 !> Collect per-process wall-clock times and write aggregate performance metrics to file
1016 impure subroutine s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, &
1017 & file_exists)
1018
1019 real(wp), intent(inout) :: time_avg, time_final
1020 real(wp), intent(inout) :: io_time_avg, io_time_final
1021 real(wp), dimension(:), intent(inout) :: proc_time
1022 real(wp), dimension(:), intent(inout) :: io_proc_time
1023 logical, intent(inout) :: file_exists
1024 real(wp) :: grind_time
1025
1026 call s_mpi_barrier()
1027
1028 if (num_procs > 1) then
1029 call mpi_bcast_time_step_values(proc_time, time_avg)
1030
1031 call mpi_bcast_time_step_values(io_proc_time, io_time_avg)
1032 end if
1033
1034 if (proc_rank == 0) then
1035 time_final = 0._wp
1036 io_time_final = 0._wp
1037 if (num_procs == 1) then
1038 time_final = time_avg
1039 io_time_final = io_time_avg
1040 else
1041 time_final = maxval(proc_time)
1042 io_time_final = maxval(io_proc_time)
1043 end if
1044
1045 grind_time = time_final*1.0e9_wp/(real(sys_size, wp)*real(maxval((/1, m_glb/)), wp)*real(maxval((/1, n_glb/)), &
1046 & wp)*real(maxval((/1, p_glb/)), wp))
1047
1048 print *, "Performance:", grind_time, "ns/gp/eq/rhs"
1049 inquire (file='time_data.dat', exist=file_exists)
1050 if (file_exists) then
1051 open (1, file='time_data.dat', position='append', status='old')
1052 else
1053 open (1, file='time_data.dat', status='new')
1054 write (1, '(A10, A15, A15)') "Ranks", "s/step", "ns/gp/eq/rhs"
1055 end if
1056
1057 write (1, '(I10, 2(F15.8))') num_procs, time_final, grind_time
1058
1059 close (1)
1060
1061 inquire (file='io_time_data.dat', exist=file_exists)
1062 if (file_exists) then
1063 open (1, file='io_time_data.dat', position='append', status='old')
1064 else
1065 open (1, file='io_time_data.dat', status='new')
1066 write (1, '(A10, A15)') "Ranks", "s/step"
1067 end if
1068
1069 write (1, '(I10, F15.8)') num_procs, io_time_final
1070 close (1)
1071 end if
1072
1073 end subroutine s_save_performance_metrics
1074
1075 !> Save conservative variable data to disk at the current time step
1076 impure subroutine s_save_data(t_step, start, finish, io_time_avg, nt)
1077
1078 integer, intent(inout) :: t_step
1079 real(wp), intent(inout) :: start, finish, io_time_avg
1080 integer, intent(inout) :: nt
1081 integer(kind=8) :: i, j, k, l
1082 integer :: stor
1083 integer :: save_count
1084
1085 if (down_sample) then
1087 end if
1088
1089 stor = 1
1090
1091 if (time_stepper /= 1) then
1092
1093# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1094
1095# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1096#if defined(MFC_OpenACC)
1097# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1098!$acc parallel loop collapse(4) gang vector default(present) copyin(idwbuff)
1099# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1100#elif defined(MFC_OpenMP)
1101# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1102
1103# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1104
1105# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1106
1107# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1108!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) collapse(4) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) map(to:idwbuff)
1109# 714 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1110#endif
1111 do i = 1, sys_size
1112 do l = idwbuff(3)%beg, idwbuff(3)%end
1113 do k = idwbuff(2)%beg, idwbuff(2)%end
1114 do j = idwbuff(1)%beg, idwbuff(1)%end
1115 q_cons_ts(2)%vf(i)%sf(j, k, l) = q_cons_ts(1)%vf(i)%sf(j, k, l)
1116 end do
1117 end do
1118 end do
1119 end do
1120
1121# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1122#if defined(MFC_OpenACC)
1123# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1124!$acc end parallel loop
1125# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1126#elif defined(MFC_OpenMP)
1127# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1128
1129# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1130!$omp end target teams loop
1131# 724 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1132#endif
1133 stor = 2
1134 end if
1135
1136 call cpu_time(start)
1137 call nvtxstartrange("SAVE-DATA")
1138 do i = 1, sys_size
1139#ifndef FRONTIER_UNIFIED
1140
1141# 732 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1142#if defined(MFC_OpenACC)
1143# 732 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1144!$acc update host(q_cons_ts(stor)%vf(i)%sf)
1145# 732 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1146#elif defined(MFC_OpenMP)
1147# 732 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1148!$omp target update from(q_cons_ts(stor)%vf(i)%sf)
1149# 732 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1150#endif
1151#endif
1152 do l = 0, p
1153 do k = 0, n
1154 do j = 0, m
1155 if (ieee_is_nan(real(q_cons_ts(stor)%vf(i)%sf(j, k, l), kind=wp))) then
1156 print *, "NaN(s) in timestep output.", j, k, l, i, proc_rank, t_step, m, n, p
1157 call s_mpi_abort("NaN(s) in timestep output.")
1158 end if
1159 end do
1160 end do
1161 end do
1162 end do
1163
1164 if (qbmm .and. .not. polytropic) then
1165
1166# 747 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1167#if defined(MFC_OpenACC)
1168# 747 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1169!$acc update host(pb_ts(1)%sf)
1170# 747 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1171#elif defined(MFC_OpenMP)
1172# 747 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1173!$omp target update from(pb_ts(1)%sf)
1174# 747 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1175#endif
1176
1177# 748 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1178#if defined(MFC_OpenACC)
1179# 748 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1180!$acc update host(mv_ts(1)%sf)
1181# 748 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1182#elif defined(MFC_OpenMP)
1183# 748 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1184!$omp target update from(mv_ts(1)%sf)
1185# 748 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1186#endif
1187 end if
1188
1189 if (cfl_dt) then
1190 save_count = int(mytime/t_save)
1191 else
1192 save_count = t_step
1193 end if
1194
1195 if (bubbles_lagrange) then
1196
1197# 758 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1198#if defined(MFC_OpenACC)
1199# 758 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1200!$acc update host(lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, intfc_vel, bub_R0, Rmax_stats, Rmin_stats, bub_dphidt, gas_p, gas_mv, gas_mg, gas_betaT, gas_betaC)
1201# 758 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1202#elif defined(MFC_OpenMP)
1203# 758 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1204!$omp target update from(lag_id, mtn_pos, mtn_posPrev, mtn_vel, intfc_rad, intfc_vel, bub_R0, Rmax_stats, Rmin_stats, bub_dphidt, gas_p, gas_mv, gas_mg, gas_betaT, gas_betaC)
1205# 758 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1206#endif
1207# 760 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1208 do i = 1, nbubs
1209 if (ieee_is_nan(intfc_rad(i, 1)) .or. intfc_rad(i, 1) <= 0._wp) then
1210 call s_mpi_abort("Bubble radius is negative or NaN, please reduce dt.")
1211 end if
1212 end do
1213
1214
1215# 766 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1216#if defined(MFC_OpenACC)
1217# 766 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1218!$acc update host(q_beta(1)%sf)
1219# 766 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1220#elif defined(MFC_OpenMP)
1221# 766 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1222!$omp target update from(q_beta(1)%sf)
1223# 766 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1224#endif
1225 call s_write_data_files(q_cons_ts(stor)%vf, q_t_sf, q_prim_vf, save_count, bc_type, q_beta(1))
1226
1227# 768 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1228#if defined(MFC_OpenACC)
1229# 768 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1230!$acc update host(Rmax_stats, Rmin_stats, gas_p, gas_mv, intfc_vel)
1231# 768 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1232#elif defined(MFC_OpenMP)
1233# 768 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1234!$omp target update from(Rmax_stats, Rmin_stats, gas_p, gas_mv, intfc_vel)
1235# 768 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1236#endif
1237 call s_write_restart_lag_bubbles(save_count) ! parallel
1238 if (lag_params%write_bubbles_stats) call s_write_lag_bubble_stats()
1239 else
1240 call s_write_data_files(q_cons_ts(stor)%vf, q_t_sf, q_prim_vf, save_count, bc_type)
1241 end if
1242
1243 ! Write IB kinematic state for restart
1244 if (ib) call s_write_ib_state_file(save_count)
1245
1246 call nvtxendrange
1247 call cpu_time(finish)
1248 if (cfl_dt) then
1249 nt = mytime/t_save
1250 else
1251 nt = int((t_step - t_step_start)/(t_step_save))
1252 end if
1253
1254 if (nt == 1) then
1255 io_time_avg = abs(finish - start)
1256 else
1257 io_time_avg = (abs(finish - start) + io_time_avg*(nt - 1))/nt
1258 end if
1259
1260 end subroutine s_save_data
1261
1262 !> Initialize all simulation sub-modules in the required dependency order
1263 impure subroutine s_initialize_modules
1264
1265 integer :: m_ds, n_ds, p_ds
1266 integer :: i
1267
1269# 811 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1270 if (bubbles_euler .or. bubbles_lagrange) then
1272 end if
1276 if (grid_geometry == 3) call s_initialize_fftw_module()
1277
1279 if (ib) then
1281 end if
1282 if (qbmm) call s_initialize_qbmm_module()
1283
1284 if (acoustic_source) then
1286 end if
1287
1288 if (viscous .and. (.not. igr)) then
1290 end if
1291
1293
1295
1297
1301
1303
1304 if (down_sample) then
1305 m_ds = int((m + 1)/3) - 1
1306 n_ds = int((n + 1)/3) - 1
1307 p_ds = int((p + 1)/3) - 1
1308
1309 allocate (q_cons_temp(1:sys_size))
1310 do i = 1, sys_size
1311 allocate (q_cons_temp(i)%sf(-1:m_ds + 1,-1:n_ds + 1,-1:p_ds + 1))
1312 end do
1313 end if
1314
1315 if (down_sample) then
1318 do i = 1, sys_size
1319
1320# 860 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1321#if defined(MFC_OpenACC)
1322# 860 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1323!$acc update device(q_cons_ts(1)%vf(i)%sf)
1324# 860 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1325#elif defined(MFC_OpenMP)
1326# 860 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1327!$omp target update to(q_cons_ts(1)%vf(i)%sf)
1328# 860 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1329#endif
1330 end do
1331 do i = 1, sys_size
1332 deallocate (q_cons_temp(i)%sf)
1333 end do
1334 deallocate (q_cons_temp)
1335 else
1336 call s_read_data_files(q_cons_ts(1)%vf)
1337 end if
1338
1340
1342 if (ib) then
1343 block
1344 type(ib_patch_parameters), allocatable :: particle_cloud_ibs(:)
1345
1346 if (cfl_dt .and. n_start > 0) then
1348 allocate (particle_cloud_ibs(0))
1349 else if (t_step_start > 0) then
1351 allocate (particle_cloud_ibs(0))
1352 else
1353 call s_generate_particle_clouds(particle_cloud_ibs)
1354 end if
1357 call s_reduce_ib_patch_array(particle_cloud_ibs)
1358 deallocate (particle_cloud_ibs)
1359 end block
1360 call s_ibm_setup()
1361 if (t_step_start == 0 .or. (cfl_dt .and. n_start == 0)) then
1362 call s_write_ib_data_file(0)
1363 call s_write_ib_state_file(0)
1364 end if
1365 end if
1368
1369 ! Initialize the Temperature cache.
1371
1372 ! Computation of parameters, allocation of memory, association of pointers, and/or execution of any other tasks that are
1373 ! needed to properly configure the modules. The preparations below DO DEPEND on the grid being complete.
1374 if (igr) then
1376 end if
1377 if (.not. igr) then
1378 if (recon_type == weno_type) then
1380 else if (recon_type == muscl_type) then
1382 end if
1385 end if
1386 if (int_comp > 0) call s_initialize_thinc_module()
1389
1392
1393 end subroutine s_initialize_modules
1394
1395 !> Set up the MPI execution environment, bind GPUs, and decompose the computational domain
1396 impure subroutine s_initialize_mpi_domain
1397
1398 integer :: ierr
1399
1400#ifdef MFC_GPU
1401 real(wp) :: starttime, endtime
1402 integer :: num_devices, local_size, num_nodes, ppn, my_device_num
1403 integer :: dev, devnum, local_rank
1404#ifdef MFC_MPI
1405 integer :: local_comm
1406#endif
1407#if defined(MFC_OpenACC)
1408 integer(acc_device_kind) :: devtype
1409#endif
1410#endif
1411
1412 call s_mpi_initialize()
1413
1414#ifdef MFC_GPU
1415#ifndef MFC_MPI
1416 local_size = 1
1417 local_rank = 0
1418#else
1419 call mpi_comm_split_type(mpi_comm_world, mpi_comm_type_shared, 0, mpi_info_null, local_comm, ierr)
1420 call mpi_comm_size(local_comm, local_size, ierr)
1421 call mpi_comm_rank(local_comm, local_rank, ierr)
1422#endif
1423#if defined(MFC_OpenACC)
1424 devtype = acc_get_device_type()
1425 devnum = acc_get_num_devices(devtype)
1426 dev = mod(local_rank, devnum)
1427
1428 call acc_set_device_num(dev, devtype)
1429#elif defined(MFC_OpenMP)
1430 devnum = omp_get_num_devices()
1431 dev = mod(local_rank, devnum)
1432 call omp_set_default_device(dev)
1433#endif
1434#endif
1435
1436 if (proc_rank == 0) then
1437 call s_assign_default_values_to_user_inputs()
1438 call s_read_input_file()
1439 call s_check_input_file()
1440
1441 print '(" Simulating a ", A, " ", I0, "x", I0, "x", I0, " case on ", I0, " rank(s) ", A, ".")', &
1442# 974 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1443 "regular", &
1444# 978 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1445 m, n, p, num_procs, &
1446#if defined(MFC_OpenACC)
1447 "with OpenACC offloading"
1448#elif defined(MFC_OpenMP)
1449 "with OpenMP offloading"
1450#else
1451 "on CPUs"
1452#endif
1453 end if
1454
1455 call s_mpi_bcast_user_inputs()
1456
1457 ! Save original BCs before decomposition overwrites them with MPI neighbor ranks
1458 ib_bc_x = bc_x
1459 ib_bc_y = bc_y
1460 ib_bc_z = bc_z
1461
1462 call s_initialize_parallel_io()
1463
1464 call s_mpi_decompose_computational_domain()
1465
1466 end subroutine s_initialize_mpi_domain
1467
1468 !> Transfer initial conservative variable and model parameter data to the GPU device
1470
1471 integer :: i
1472
1473 if (.not. down_sample) then
1474 do i = 1, sys_size
1475
1476# 1008 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1477#if defined(MFC_OpenACC)
1478# 1008 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1479!$acc update device(q_cons_ts(1)%vf(i)%sf)
1480# 1008 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1481#elif defined(MFC_OpenMP)
1482# 1008 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1483!$omp target update to(q_cons_ts(1)%vf(i)%sf)
1484# 1008 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1485#endif
1486 end do
1487 end if
1488
1489 if (qbmm .and. .not. polytropic) then
1490
1491# 1013 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1492#if defined(MFC_OpenACC)
1493# 1013 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1494!$acc update device(pb_ts(1)%sf, mv_ts(1)%sf)
1495# 1013 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1496#elif defined(MFC_OpenMP)
1497# 1013 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1498!$omp target update to(pb_ts(1)%sf, mv_ts(1)%sf)
1499# 1013 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1500#endif
1501 end if
1502 if (chemistry) then
1503
1504# 1016 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1505#if defined(MFC_OpenACC)
1506# 1016 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1507!$acc update device(q_T_sf%sf)
1508# 1016 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1509#elif defined(MFC_OpenMP)
1510# 1016 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1511!$omp target update to(q_T_sf%sf)
1512# 1016 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1513#endif
1514 end if
1515
1516
1517# 1019 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1518#if defined(MFC_OpenACC)
1519# 1019 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1520!$acc update device(chem_params)
1521# 1019 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1522#elif defined(MFC_OpenMP)
1523# 1019 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1524!$omp target update to(chem_params)
1525# 1019 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1526#endif
1527
1528
1529# 1021 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1530#if defined(MFC_OpenACC)
1531# 1021 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1532!$acc update device(R0ref, p0ref, rho0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, R_v, R_g, Tw, cp_v, cp_g, k_vl, k_gl, gam, gam_m, Eu, Ca, Web, Re_inv, Pe_c, phi_vg, phi_gv, omegaN, bubbles_euler, polytropic, polydisperse, qbmm, ptil, bubble_model, thermal, poly_sigma, adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, eqn_idx%n, pi_fac, low_Mach)
1533# 1021 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1534#elif defined(MFC_OpenMP)
1535# 1021 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1536!$omp target update to(R0ref, p0ref, rho0ref, ss, pv, vd, mu_l, mu_v, mu_g, gam_v, gam_g, M_v, M_g, R_v, R_g, Tw, cp_v, cp_g, k_vl, k_gl, gam, gam_m, Eu, Ca, Web, Re_inv, Pe_c, phi_vg, phi_gv, omegaN, bubbles_euler, polytropic, polydisperse, qbmm, ptil, bubble_model, thermal, poly_sigma, adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, eqn_idx%n, pi_fac, low_Mach)
1537# 1021 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1538#endif
1539# 1025 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1540
1541 if (bubbles_euler) then
1542
1543# 1027 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1544#if defined(MFC_OpenACC)
1545# 1027 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1546!$acc update device(weight, R0)
1547# 1027 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1548#elif defined(MFC_OpenMP)
1549# 1027 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1550!$omp target update to(weight, R0)
1551# 1027 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1552#endif
1553 if (.not. polytropic) then
1554
1555# 1029 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1556#if defined(MFC_OpenACC)
1557# 1029 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1558!$acc update device(pb0, Pe_T, k_g, k_v, mass_g0, mass_v0, Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c)
1559# 1029 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1560#elif defined(MFC_OpenMP)
1561# 1029 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1562!$omp target update to(pb0, Pe_T, k_g, k_v, mass_g0, mass_v0, Re_trans_T, Re_trans_c, Im_trans_T, Im_trans_c)
1563# 1029 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1564#endif
1565 else if (qbmm) then
1566
1567# 1031 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1568#if defined(MFC_OpenACC)
1569# 1031 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1570!$acc update device(pb0)
1571# 1031 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1572#elif defined(MFC_OpenMP)
1573# 1031 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1574!$omp target update to(pb0)
1575# 1031 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1576#endif
1577 end if
1578 end if
1579
1580
1581# 1035 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1582#if defined(MFC_OpenACC)
1583# 1035 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1584!$acc update device(adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, pi_fac, low_Mach)
1585# 1035 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1586#elif defined(MFC_OpenMP)
1587# 1035 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1588!$omp target update to(adv_n, adap_dt, adap_dt_tol, adap_dt_max_iters, pi_fac, low_Mach)
1589# 1035 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1590#endif
1591
1592
1593# 1037 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1594#if defined(MFC_OpenACC)
1595# 1037 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1596!$acc update device(acoustic_source, num_source)
1597# 1037 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1598#elif defined(MFC_OpenMP)
1599# 1037 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1600!$omp target update to(acoustic_source, num_source)
1601# 1037 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1602#endif
1603
1604# 1038 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1605#if defined(MFC_OpenACC)
1606# 1038 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1607!$acc update device(sigma, surface_tension)
1608# 1038 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1609#elif defined(MFC_OpenMP)
1610# 1038 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1611!$omp target update to(sigma, surface_tension)
1612# 1038 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1613#endif
1614
1615
1616# 1040 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1617#if defined(MFC_OpenACC)
1618# 1040 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1619!$acc update device(dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc)
1620# 1040 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1621#elif defined(MFC_OpenMP)
1622# 1040 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1623!$omp target update to(dx, dy, dz, x_cb, x_cc, y_cb, y_cc, z_cb, z_cc)
1624# 1040 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1625#endif
1626
1627# 1041 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1628#if defined(MFC_OpenACC)
1629# 1041 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1630!$acc update device(bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end)
1631# 1041 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1632#elif defined(MFC_OpenMP)
1633# 1041 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1634!$omp target update to(bc_x%beg, bc_x%end, bc_y%beg, bc_y%end, bc_z%beg, bc_z%end)
1635# 1041 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1636#endif
1637
1638# 1042 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1639#if defined(MFC_OpenACC)
1640# 1042 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1641!$acc update device(bc_x%vb1, bc_x%vb2, bc_x%vb3, bc_x%ve1, bc_x%ve2, bc_x%ve3)
1642# 1042 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1643#elif defined(MFC_OpenMP)
1644# 1042 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1645!$omp target update to(bc_x%vb1, bc_x%vb2, bc_x%vb3, bc_x%ve1, bc_x%ve2, bc_x%ve3)
1646# 1042 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1647#endif
1648
1649# 1043 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1650#if defined(MFC_OpenACC)
1651# 1043 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1652!$acc update device(bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3)
1653# 1043 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1654#elif defined(MFC_OpenMP)
1655# 1043 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1656!$omp target update to(bc_y%vb1, bc_y%vb2, bc_y%vb3, bc_y%ve1, bc_y%ve2, bc_y%ve3)
1657# 1043 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1658#endif
1659
1660# 1044 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1661#if defined(MFC_OpenACC)
1662# 1044 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1663!$acc update device(bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3)
1664# 1044 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1665#elif defined(MFC_OpenMP)
1666# 1044 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1667!$omp target update to(bc_z%vb1, bc_z%vb2, bc_z%vb3, bc_z%ve1, bc_z%ve2, bc_z%ve3)
1668# 1044 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1669#endif
1670
1671
1672# 1046 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1673#if defined(MFC_OpenACC)
1674# 1046 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1675!$acc update device(bc_x%grcbc_in, bc_x%grcbc_out, bc_x%grcbc_vel_out)
1676# 1046 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1677#elif defined(MFC_OpenMP)
1678# 1046 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1679!$omp target update to(bc_x%grcbc_in, bc_x%grcbc_out, bc_x%grcbc_vel_out)
1680# 1046 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1681#endif
1682
1683# 1047 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1684#if defined(MFC_OpenACC)
1685# 1047 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1686!$acc update device(bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out)
1687# 1047 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1688#elif defined(MFC_OpenMP)
1689# 1047 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1690!$omp target update to(bc_y%grcbc_in, bc_y%grcbc_out, bc_y%grcbc_vel_out)
1691# 1047 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1692#endif
1693
1694# 1048 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1695#if defined(MFC_OpenACC)
1696# 1048 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1697!$acc update device(bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out)
1698# 1048 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1699#elif defined(MFC_OpenMP)
1700# 1048 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1701!$omp target update to(bc_z%grcbc_in, bc_z%grcbc_out, bc_z%grcbc_vel_out)
1702# 1048 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1703#endif
1704
1705
1706# 1050 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1707#if defined(MFC_OpenACC)
1708# 1050 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1709!$acc update device(bc_x%isothermal_in, bc_x%isothermal_out)
1710# 1050 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1711#elif defined(MFC_OpenMP)
1712# 1050 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1713!$omp target update to(bc_x%isothermal_in, bc_x%isothermal_out)
1714# 1050 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1715#endif
1716
1717# 1051 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1718#if defined(MFC_OpenACC)
1719# 1051 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1720!$acc update device(bc_y%isothermal_in, bc_y%isothermal_out)
1721# 1051 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1722#elif defined(MFC_OpenMP)
1723# 1051 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1724!$omp target update to(bc_y%isothermal_in, bc_y%isothermal_out)
1725# 1051 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1726#endif
1727
1728# 1052 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1729#if defined(MFC_OpenACC)
1730# 1052 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1731!$acc update device(bc_z%isothermal_in, bc_z%isothermal_out)
1732# 1052 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1733#elif defined(MFC_OpenMP)
1734# 1052 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1735!$omp target update to(bc_z%isothermal_in, bc_z%isothermal_out)
1736# 1052 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1737#endif
1738
1739# 1053 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1740#if defined(MFC_OpenACC)
1741# 1053 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1742!$acc update device(bc_x%Twall_in, bc_x%Twall_out, bc_y%Twall_in, bc_y%Twall_out, bc_z%Twall_in, bc_z%Twall_out)
1743# 1053 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1744#elif defined(MFC_OpenMP)
1745# 1053 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1746!$omp target update to(bc_x%Twall_in, bc_x%Twall_out, bc_y%Twall_in, bc_y%Twall_out, bc_z%Twall_in, bc_z%Twall_out)
1747# 1053 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1748#endif
1749
1750
1751# 1055 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1752#if defined(MFC_OpenACC)
1753# 1055 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1754!$acc update device(relax, relax_model)
1755# 1055 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1756#elif defined(MFC_OpenMP)
1757# 1055 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1758!$omp target update to(relax, relax_model)
1759# 1055 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1760#endif
1761 if (relax) then
1762
1763# 1057 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1764#if defined(MFC_OpenACC)
1765# 1057 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1766!$acc update device(palpha_eps, ptgalpha_eps)
1767# 1057 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1768#elif defined(MFC_OpenMP)
1769# 1057 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1770!$omp target update to(palpha_eps, ptgalpha_eps)
1771# 1057 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1772#endif
1773 end if
1774
1775 if (ib) then
1776
1777# 1061 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1778#if defined(MFC_OpenACC)
1779# 1061 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1780!$acc update device(ib_markers%sf)
1781# 1061 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1782#elif defined(MFC_OpenMP)
1783# 1061 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1784!$omp target update to(ib_markers%sf)
1785# 1061 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1786#endif
1787 end if
1788# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1789
1790# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1791#if defined(MFC_OpenACC)
1792# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1793!$acc update device(igr, nb, igr_order)
1794# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1795#elif defined(MFC_OpenMP)
1796# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1797!$omp target update to(igr, nb, igr_order)
1798# 1064 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1799#endif
1800# 1066 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1801
1802 end subroutine s_initialize_gpu_vars
1803
1804 !> Finalize and deallocate all simulation sub-modules in reverse initialization order
1805 impure subroutine s_finalize_modules
1806
1807 call s_finalize_time_steppers_module()
1808 if (hypoelasticity) call s_finalize_hypoelastic_module()
1809 if (hyperelasticity) call s_finalize_hyperelastic_module()
1810 call s_finalize_derived_variables_module()
1811 call s_finalize_data_output_module()
1812 call s_finalize_rhs_module()
1813 if (igr) then
1814 call s_finalize_igr_module()
1815 else
1816 call s_finalize_cbc_module()
1817 call s_finalize_riemann_solvers_module()
1818 if (recon_type == weno_type) then
1819 call s_finalize_weno_module()
1820 else if (recon_type == muscl_type) then
1821 call s_finalize_muscl_module()
1822 end if
1823 end if
1824 if (int_comp > 0) call s_finalize_thinc_module()
1825 call s_finalize_variables_conversion_module()
1826 if (grid_geometry == 3) call s_finalize_fftw_module
1827 call s_finalize_mpi_common_module()
1828 call s_finalize_global_parameters_module()
1829 call s_finalize_boundary_common_module()
1830 if (relax) call s_finalize_relaxation_solver_module()
1831 if (bubbles_lagrange) call s_finalize_lagrangian_solver()
1832 if (viscous .and. (.not. igr)) then
1833 call s_finalize_viscous_module()
1834 end if
1835 call s_finalize_mpi_proxy_module()
1836
1837 if (surface_tension) call s_finalize_surface_tension_module()
1838 if (bodyforces) call s_finalize_body_forces_module()
1839 if (ib) call s_finalize_ibm_module()
1840
1841 call s_mpi_finalize()
1842
1843 end subroutine s_finalize_modules
1844
1845 !> @brief Reads IB kinematic state from restart_data/ib_state.dat on restart. Rank 0 reads the last num_ibs records and
1846 !! broadcasts to all ranks. Overwrites patch_ib vel, angular_vel, angles, and centroid.
1847 impure subroutine s_read_ib_restart_data(t_step)
1848
1849 integer, intent(in) :: t_step
1850 character(len=path_len + 2*name_len) :: file_loc
1851 integer :: i, ios, file_unit, ierr
1852 integer :: r, nlocal, gbl_id
1853 integer, parameter :: nfields_per_ib = 20
1854 real(wp) :: ib_buf(nfields_per_ib)
1855 logical :: file_exist
1856 character(len=10) :: t_step_string
1857
1858 if (file_per_process) then
1859 call s_int_to_str(t_step, t_step_string)
1860
1861 do r = 0, num_procs - 1
1862 write (file_loc, '(A,I0,A,i7.7,A)') 'ib_state_', t_step, '_', r, '.dat'
1863 file_loc = trim(case_dir) // '/restart_data/lustre_' // trim(t_step_string) // '/' // trim(file_loc)
1864
1865 inquire (file=trim(file_loc), exist=file_exist)
1866 if (.not. file_exist) call s_mpi_abort('Cannot open IB state file for restart: ' // trim(file_loc))
1867
1868 open (newunit=file_unit, file=trim(file_loc), form='unformatted', access='stream', status='old', iostat=ios)
1869 if (ios /= 0) call s_mpi_abort('Error opening IB state restart file: ' // trim(file_loc))
1870
1871 read (file_unit, iostat=ios) nlocal
1872 if (ios /= 0) call s_mpi_abort('Error reading IB state file header: ' // trim(file_loc))
1873
1874 do i = 1, nlocal
1875 read (file_unit, iostat=ios) gbl_id
1876 if (ios /= 0) call s_mpi_abort('Error reading IB patch ID: ' // trim(file_loc))
1877 read (file_unit, iostat=ios) ib_buf
1878 if (ios /= 0) call s_mpi_abort('Error reading IB state data: ' // trim(file_loc))
1879
1880 patch_ib(gbl_id)%vel = ib_buf(8:10)
1881 patch_ib(gbl_id)%angular_vel = ib_buf(11:13)
1882 patch_ib(gbl_id)%angles = ib_buf(14:16)
1883 patch_ib(gbl_id)%x_centroid = ib_buf(17)
1884 patch_ib(gbl_id)%y_centroid = ib_buf(18)
1885 patch_ib(gbl_id)%z_centroid = ib_buf(19)
1886 end do
1887
1888 close (file_unit)
1889 end do
1890 else
1891 write (file_loc, '(A,I0,A)') '/restart_data/ib_state_', t_step, '.dat'
1892 file_loc = trim(case_dir) // trim(file_loc)
1893
1894 if (proc_rank == 0) then
1895 inquire (file=trim(file_loc), exist=file_exist)
1896 if (.not. file_exist) then
1897 call s_mpi_abort('Cannot open IB state file for restart: ' // trim(file_loc))
1898 end if
1899
1900 open (newunit=file_unit, file=trim(file_loc), form='unformatted', access='stream', status='old', iostat=ios)
1901 if (ios /= 0) call s_mpi_abort('Error opening IB state restart file: ' // trim(file_loc))
1902
1903 do i = 1, num_ibs
1904 read (file_unit, iostat=ios) ib_buf
1905 if (ios /= 0) call s_mpi_abort('Error reading IB state restart file')
1906
1907 patch_ib(i)%vel = ib_buf(8:10)
1908 patch_ib(i)%angular_vel = ib_buf(11:13)
1909 patch_ib(i)%angles = ib_buf(14:16)
1910 patch_ib(i)%x_centroid = ib_buf(17)
1911 patch_ib(i)%y_centroid = ib_buf(18)
1912 patch_ib(i)%z_centroid = ib_buf(19)
1913 end do
1914
1915 close (file_unit)
1916 end if
1917
1918#ifdef MFC_MPI
1919 do i = 1, num_ibs
1920 call mpi_bcast(patch_ib(i)%vel, 3, mpi_p, 0, mpi_comm_world, ierr)
1921 call mpi_bcast(patch_ib(i)%angular_vel, 3, mpi_p, 0, mpi_comm_world, ierr)
1922 call mpi_bcast(patch_ib(i)%angles, 3, mpi_p, 0, mpi_comm_world, ierr)
1923 call mpi_bcast(patch_ib(i)%x_centroid, 1, mpi_p, 0, mpi_comm_world, ierr)
1924 call mpi_bcast(patch_ib(i)%y_centroid, 1, mpi_p, 0, mpi_comm_world, ierr)
1925 call mpi_bcast(patch_ib(i)%z_centroid, 1, mpi_p, 0, mpi_comm_world, ierr)
1926 end do
1927#endif
1928 end if
1929
1930 end subroutine s_read_ib_restart_data
1931
1932 !> @brief Merges patch_ib (namelist patches, fixed at num_ib_patches_max_namelist) with particle_cloud_ibs (CPU-only, exact
1933 !! size) and reduces to only the patches in or near the local computational domain. patch_ib is never reallocated; the local
1934 !! subset is written in-place from the front. particle_cloud_ibs is owned by the caller and freed there after this returns.
1935 subroutine s_reduce_ib_patch_array(particle_cloud_ibs)
1936
1937 type(ib_patch_parameters), intent(in), dimension(:) :: particle_cloud_ibs
1938 real(wp), dimension(3) :: centroid
1939 integer :: i
1940 integer :: num_namelist_ibs, num_bed_ibs
1941
1942 num_namelist_ibs = num_ibs
1943 num_bed_ibs = 0
1944 do i = 1, num_particle_clouds
1945 num_bed_ibs = num_bed_ibs + particle_cloud(i)%num_particles
1946 end do
1947
1948 ! Check for moving IBs across both namelist and particle bed patches.
1949 moving_immersed_boundary_flag = .false.
1950 do i = 1, num_namelist_ibs
1951 if (patch_ib(i)%moving_ibm /= 0) then
1952 moving_immersed_boundary_flag = .true.
1953 exit
1954 end if
1955 end do
1956 if (.not. moving_immersed_boundary_flag) then
1957 do i = 1, num_bed_ibs
1958 if (particle_cloud_ibs(i)%moving_ibm /= 0) then
1959 moving_immersed_boundary_flag = .true.
1960 exit
1961 end if
1962 end do
1963 end if
1964
1965 call get_neighbor_bounds()
1967
1968 num_gbl_ibs = num_namelist_ibs + num_bed_ibs
1969
1970#ifdef MFC_MPI
1971 if (num_procs == 1) then
1972 ! single-rank: all patches are local; append particle bed entries directly into patch_ib.
1973 if (num_gbl_ibs > num_ib_patches_max_namelist) then
1974# 1238 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1975 call s_prohibit_abort("num_gbl_ibs > num_ib_patches_max_namelist", "Total IB count exceeds patch_ib capacity. Increase num_ib_patches_max_namelist.")
1976# 1238 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1977 end if
1978# 1240 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
1979 do i = 1, num_bed_ibs
1980 patch_ib(num_namelist_ibs + i) = particle_cloud_ibs(i)
1981 patch_ib(num_namelist_ibs + i)%gbl_patch_id = num_namelist_ibs + i
1982 end do
1983 num_ibs = num_gbl_ibs
1984 num_local_ibs = num_gbl_ibs
1985 do i = 1, num_gbl_ibs
1986 local_ib_patch_ids(i) = i
1987 end do
1988 else
1989 ! multi-rank: compact namelist patches in-place (write_idx <= read_idx, no aliasing), then append local particle beds.
1990 num_ibs = 0
1991 num_local_ibs = 0
1992 do i = 1, num_namelist_ibs
1993 centroid = [patch_ib(i)%x_centroid, patch_ib(i)%y_centroid, 0._wp]
1994 if (num_dims == 3) centroid(3) = patch_ib(i)%z_centroid
1995 if (f_neighborhood_ranks_own_location(centroid)) then
1996 num_ibs = num_ibs + 1
1997 patch_ib(num_ibs) = patch_ib(i)
1998 patch_ib(num_ibs)%gbl_patch_id = i
1999 if (f_local_rank_owns_location(centroid)) then
2000 num_local_ibs = num_local_ibs + 1
2001 local_ib_patch_ids(num_local_ibs) = num_ibs
2002 end if
2003 end if
2004 end do
2005 do i = 1, num_bed_ibs
2006 centroid = [particle_cloud_ibs(i)%x_centroid, particle_cloud_ibs(i)%y_centroid, 0._wp]
2007 if (num_dims == 3) centroid(3) = particle_cloud_ibs(i)%z_centroid
2008 if (f_neighborhood_ranks_own_location(centroid)) then
2009 num_ibs = num_ibs + 1
2010 if (num_ibs > num_ib_patches_max_namelist) then
2011# 1271 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2012 call s_prohibit_abort("num_ibs > num_ib_patches_max_namelist", "Local IB count exceeds patch_ib capacity. Increase num_ib_patches_max_namelist.")
2013# 1271 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2014 end if
2015# 1273 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2016 patch_ib(num_ibs) = particle_cloud_ibs(i)
2017 patch_ib(num_ibs)%gbl_patch_id = num_namelist_ibs + i
2018 if (f_local_rank_owns_location(centroid)) then
2019 num_local_ibs = num_local_ibs + 1
2020 local_ib_patch_ids(num_local_ibs) = num_ibs
2021 end if
2022 end if
2023 end do
2024 if (num_local_ibs > num_local_ibs_max) then
2025# 1281 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2026 call s_prohibit_abort("num_local_ibs > num_local_ibs_max", "Too many IBs on a single processor rank. Modify case file or increase limit of num_local_ibs_max to resolve.")
2027# 1281 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2028 end if
2029# 1283 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2030 end if
2031#else
2032 ! no-MPI: all patches are local; append particle bed entries directly into patch_ib.
2033 if (num_gbl_ibs > num_ib_patches_max_namelist) then
2034# 1286 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2035 call s_prohibit_abort("num_gbl_ibs > num_ib_patches_max_namelist", "Total IB count exceeds patch_ib capacity. Increase num_ib_patches_max_namelist.")
2036# 1286 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2037 end if
2038# 1288 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2039 do i = 1, num_bed_ibs
2040 patch_ib(num_namelist_ibs + i) = particle_cloud_ibs(i)
2041 patch_ib(num_namelist_ibs + i)%gbl_patch_id = num_namelist_ibs + i
2042 end do
2043 num_ibs = num_gbl_ibs
2044 num_local_ibs = num_gbl_ibs
2045 do i = 1, num_gbl_ibs
2046 local_ib_patch_ids(i) = i
2047 end do
2048#endif
2049
2050#ifdef MFC_DEBUG
2051# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2052 block
2053# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2054 use iso_fortran_env, only: output_unit
2055# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2056
2057# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2058 print *, 'm_start_up.fpp:1299: ', '@:ALLOCATE(ib_gbl_idx_lookup(1:num_gbl_ibs))'
2059# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2060
2061# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2062 call flush (output_unit)
2063# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2064 end block
2065# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2066#endif
2067# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2068 allocate (ib_gbl_idx_lookup(1:num_gbl_ibs))
2069# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2070
2071# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2072
2073# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2074#if defined(MFC_OpenACC)
2075# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2076!$acc enter data create(ib_gbl_idx_lookup)
2077# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2078#elif defined(MFC_OpenMP)
2079# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2080!$omp target enter data map(always,alloc:ib_gbl_idx_lookup)
2081# 1299 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2082#endif
2083
2084 end subroutine s_reduce_ib_patch_array
2085
2086 !> Build ib_neighbor_ranks(-1:1,-1:1,-1:1): MPI ranks of all neighbor domains. Uses two rounds of MPI_SENDRECV cascades - face
2087 !! neighbors are known from bc_*, edge neighbors are obtained in round 1, and (3D) corner neighbors in round 2.
2089
2090 integer :: ax, k, nbr_idx, nreqs, sx, sy, sz, dx, dy, dz
2091 integer, allocatable :: send_table(:,:,:), recv_tables(:,:,:,:)
2092 integer, dimension(52) :: requests
2093
2094#ifdef MFC_MPI
2095 integer :: ierr
2096 integer, dimension(4) :: buf4, rbuf4
2097 integer, dimension(2) :: buf2, rbuf2
2098
2099 ax = ib_neighborhood_radius
2100
2101 if (allocated(ib_neighbor_ranks)) deallocate (ib_neighbor_ranks)
2102 allocate (ib_neighbor_ranks(-ax:ax,-ax:ax,-ax:ax))
2103 ib_neighbor_ranks = mpi_proc_null
2104 ib_neighbor_ranks(0, 0, 0) = proc_rank
2105
2106 ! Fill radius-1 entries: face neighbors are known from domain decomposition
2107 ib_neighbor_ranks(-1, 0, 0) = bc_x%beg
2108 ib_neighbor_ranks(+1, 0, 0) = bc_x%end
2109 if (num_dims >= 2) then
2110 ib_neighbor_ranks(0, -1, 0) = bc_y%beg
2111 ib_neighbor_ranks(0, +1, 0) = bc_y%end
2112 end if
2113 if (num_dims == 3) then
2114 ib_neighbor_ranks(0, 0, -1) = bc_z%beg
2115 ib_neighbor_ranks(0, 0, +1) = bc_z%end
2116 end if
2117
2118 if (num_dims >= 2) then
2119 ! Round 1a: exchange y/z face ranks with +/-x face neighbors -> xy and xz edge ranks
2120 buf4 = [bc_y%beg, bc_y%end, bc_z%beg, bc_z%end]
2121
2122 ! Send to -x, receive from +x -> edges (+1,+/-1,0) and (+1,0,+/-1)
2123 call mpi_sendrecv(buf4, 4, mpi_integer, merge(bc_x%beg, mpi_proc_null, bc_x%beg >= 0), 310, rbuf4, 4, mpi_integer, &
2124 & merge(bc_x%end, mpi_proc_null, bc_x%end >= 0), 310, mpi_comm_world, mpi_status_ignore, ierr)
2125 if (bc_x%end >= 0) then
2126 ib_neighbor_ranks(+1, -1, 0) = rbuf4(1)
2127 ib_neighbor_ranks(+1, +1, 0) = rbuf4(2)
2128 ib_neighbor_ranks(+1, 0, -1) = rbuf4(3)
2129 ib_neighbor_ranks(+1, 0, +1) = rbuf4(4)
2130 end if
2131
2132 call mpi_sendrecv(buf4, 4, mpi_integer, merge(bc_x%end, mpi_proc_null, bc_x%end >= 0), 311, rbuf4, 4, mpi_integer, &
2133 & merge(bc_x%beg, mpi_proc_null, bc_x%beg >= 0), 311, mpi_comm_world, mpi_status_ignore, ierr)
2134 if (bc_x%beg >= 0) then
2135 ib_neighbor_ranks(-1, -1, 0) = rbuf4(1)
2136 ib_neighbor_ranks(-1, +1, 0) = rbuf4(2)
2137 ib_neighbor_ranks(-1, 0, -1) = rbuf4(3)
2138 ib_neighbor_ranks(-1, 0, +1) = rbuf4(4)
2139 end if
2140 end if
2141
2142 if (num_dims == 3) then
2143 ! Round 1b: exchange z face ranks with +/-y face neighbors -> yz edge ranks
2144 buf2 = [bc_z%beg, bc_z%end]
2145
2146 call mpi_sendrecv(buf2, 2, mpi_integer, merge(bc_y%beg, mpi_proc_null, bc_y%beg >= 0), 312, rbuf2, 2, mpi_integer, &
2147 & merge(bc_y%end, mpi_proc_null, bc_y%end >= 0), 312, mpi_comm_world, mpi_status_ignore, ierr)
2148 if (bc_y%end >= 0) then
2149 ib_neighbor_ranks(0, +1, -1) = rbuf2(1)
2150 ib_neighbor_ranks(0, +1, +1) = rbuf2(2)
2151 end if
2152
2153 call mpi_sendrecv(buf2, 2, mpi_integer, merge(bc_y%end, mpi_proc_null, bc_y%end >= 0), 313, rbuf2, 2, mpi_integer, &
2154 & merge(bc_y%beg, mpi_proc_null, bc_y%beg >= 0), 313, mpi_comm_world, mpi_status_ignore, ierr)
2155 if (bc_y%beg >= 0) then
2156 ib_neighbor_ranks(0, -1, -1) = rbuf2(1)
2157 ib_neighbor_ranks(0, -1, +1) = rbuf2(2)
2158 end if
2159
2160 ! Round 2: exchange z face ranks with xy-diagonal edge neighbors -> corner ranks. Each of the 4 xy diagonals gives 2
2161 ! corners (the +/-z variants). Pattern: send buf2 to mirror diagonal, receive from this diagonal -> that edge's z face
2162 ! ranks.
2163# 1381 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2164 call mpi_sendrecv(buf2, 2, mpi_integer, merge(ib_neighbor_ranks(-1, -1, 0), mpi_proc_null, &
2165 & ib_neighbor_ranks(-1, -1, 0) >= 0), 320, rbuf2, 2, mpi_integer, &
2166 & merge(ib_neighbor_ranks(1, 1, 0), mpi_proc_null, ib_neighbor_ranks(1, 1, &
2167 & 0) >= 0), 320, mpi_comm_world, mpi_status_ignore, ierr)
2168 if (ib_neighbor_ranks(1, 1, 0) >= 0) then
2169 ib_neighbor_ranks(1, 1, -1) = rbuf2(1)
2170 ib_neighbor_ranks(1, 1, +1) = rbuf2(2)
2171 end if
2172# 1381 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2173 call mpi_sendrecv(buf2, 2, mpi_integer, merge(ib_neighbor_ranks(-1, 1, 0), mpi_proc_null, &
2174 & ib_neighbor_ranks(-1, 1, 0) >= 0), 321, rbuf2, 2, mpi_integer, &
2175 & merge(ib_neighbor_ranks(1, -1, 0), mpi_proc_null, ib_neighbor_ranks(1, -1, &
2176 & 0) >= 0), 321, mpi_comm_world, mpi_status_ignore, ierr)
2177 if (ib_neighbor_ranks(1, -1, 0) >= 0) then
2178 ib_neighbor_ranks(1, -1, -1) = rbuf2(1)
2179 ib_neighbor_ranks(1, -1, +1) = rbuf2(2)
2180 end if
2181# 1381 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2182 call mpi_sendrecv(buf2, 2, mpi_integer, merge(ib_neighbor_ranks(1, -1, 0), mpi_proc_null, &
2183 & ib_neighbor_ranks(1, -1, 0) >= 0), 322, rbuf2, 2, mpi_integer, &
2184 & merge(ib_neighbor_ranks(-1, 1, 0), mpi_proc_null, ib_neighbor_ranks(-1, 1, &
2185 & 0) >= 0), 322, mpi_comm_world, mpi_status_ignore, ierr)
2186 if (ib_neighbor_ranks(-1, 1, 0) >= 0) then
2187 ib_neighbor_ranks(-1, 1, -1) = rbuf2(1)
2188 ib_neighbor_ranks(-1, 1, +1) = rbuf2(2)
2189 end if
2190# 1381 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2191 call mpi_sendrecv(buf2, 2, mpi_integer, merge(ib_neighbor_ranks(1, 1, 0), mpi_proc_null, &
2192 & ib_neighbor_ranks(1, 1, 0) >= 0), 323, rbuf2, 2, mpi_integer, &
2193 & merge(ib_neighbor_ranks(-1, -1, 0), mpi_proc_null, ib_neighbor_ranks(-1, -1, &
2194 & 0) >= 0), 323, mpi_comm_world, mpi_status_ignore, ierr)
2195 if (ib_neighbor_ranks(-1, -1, 0) >= 0) then
2196 ib_neighbor_ranks(-1, -1, -1) = rbuf2(1)
2197 ib_neighbor_ranks(-1, -1, +1) = rbuf2(2)
2198 end if
2199# 1390 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2200 end if
2201
2202 ! For radius > 1: extend the table by iterative 26-neighbor full-table exchanges. In each round, every rank broadcasts its
2203 ! current table to all 26 immediate neighbors. Their entry at offset (dx,dy,dz) from them = our entry at
2204 ! (dx+sx,dy+sy,dz+sz). One extension round fills the entire next shell, so ax-1 rounds suffice.
2205 if (ax > 1) then
2206 allocate (send_table(-ax:ax,-ax:ax,-ax:ax))
2207 allocate (recv_tables(-ax:ax,-ax:ax,-ax:ax,1:26))
2208
2209 do k = 2, ax
2210 send_table = ib_neighbor_ranks
2211
2212 nreqs = 0
2213 nbr_idx = 0
2214 do sz = -1, 1
2215 do sy = -1, 1
2216 do sx = -1, 1
2217 if (sx == 0 .and. sy == 0 .and. sz == 0) cycle
2218 nbr_idx = nbr_idx + 1
2219 if (ib_neighbor_ranks(sx, sy, sz) < 0) cycle
2220 nreqs = nreqs + 1
2221 call mpi_irecv(recv_tables(:,:,:,nbr_idx), (2*ax + 1)**3, mpi_integer, ib_neighbor_ranks(sx, sy, sz), &
2222 & 400, mpi_comm_world, requests(nreqs), ierr)
2223 end do
2224 end do
2225 end do
2226
2227 do sz = -1, 1
2228 do sy = -1, 1
2229 do sx = -1, 1
2230 if (sx == 0 .and. sy == 0 .and. sz == 0) cycle
2231 if (ib_neighbor_ranks(sx, sy, sz) < 0) cycle
2232 nreqs = nreqs + 1
2233 call mpi_isend(send_table, (2*ax + 1)**3, mpi_integer, ib_neighbor_ranks(sx, sy, sz), 400, &
2234 & mpi_comm_world, requests(nreqs), ierr)
2235 end do
2236 end do
2237 end do
2238
2239 call mpi_waitall(nreqs, requests, mpi_statuses_ignore, ierr)
2240
2241 nbr_idx = 0
2242 do sz = -1, 1
2243 do sy = -1, 1
2244 do sx = -1, 1
2245 if (sx == 0 .and. sy == 0 .and. sz == 0) cycle
2246 nbr_idx = nbr_idx + 1
2247 if (ib_neighbor_ranks(sx, sy, sz) < 0) cycle
2248 do dz = -ax, ax
2249 do dy = -ax, ax
2250 do dx = -ax, ax
2251 if (recv_tables(dx, dy, dz, nbr_idx) == mpi_proc_null) cycle
2252 if (dx + sx < -ax .or. dx + sx > ax) cycle
2253 if (dy + sy < -ax .or. dy + sy > ax) cycle
2254 if (dz + sz < -ax .or. dz + sz > ax) cycle
2255 if (ib_neighbor_ranks(dx + sx, dy + sy, dz + sz) /= mpi_proc_null) cycle
2256 ib_neighbor_ranks(dx + sx, dy + sy, dz + sz) = recv_tables(dx, dy, dz, nbr_idx)
2257 end do
2258 end do
2259 end do
2260 end do
2261 end do
2262 end do
2263 end do
2264
2265 deallocate (send_table, recv_tables)
2266 end if
2267#endif
2268
2269 end subroutine s_compute_ib_neighbor_ranks
2270
2272
2273 real(wp) :: beg_val, end_val, recv_val
2274 integer :: k, send_neighbor, recv_neighbor, ierr
2275
2276 ! Default: unbounded in all directions (covers single-rank and no-MPI cases)
2277
2278 neighbor_domain_x%beg = -huge(0._wp)
2279 neighbor_domain_x%end = huge(0._wp)
2280 neighbor_domain_y%beg = -huge(0._wp)
2281 neighbor_domain_y%end = huge(0._wp)
2282 neighbor_domain_z%beg = -huge(0._wp)
2283 neighbor_domain_z%end = huge(0._wp)
2284
2285#ifdef MFC_MPI
2286 ! For each direction, propagate the left/right boundary edges outward ib_neighborhood_radius hops. After k rounds: beg_val =
2287 ! left edge of the rank k hops to the left; end_val = right edge of the rank k hops to the right.
2288# 1479 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2289 if (num_dims >= 1) then
2290 beg_val = x_cb(-1)
2291 end_val = x_cb(m)
2292 do k = 1, ib_neighborhood_radius
2293 send_neighbor = merge(bc_x%end, mpi_proc_null, bc_x%end >= 0)
2294 recv_neighbor = merge(bc_x%beg, mpi_proc_null, bc_x%beg >= 0)
2295 recv_val = -huge(0._wp)
2296 call mpi_sendrecv(beg_val, 1, mpi_p, send_neighbor, 100, recv_val, 1, mpi_p, recv_neighbor, 100, &
2297 & mpi_comm_world, mpi_status_ignore, ierr)
2298 beg_val = recv_val
2299
2300 send_neighbor = merge(bc_x%beg, mpi_proc_null, bc_x%beg >= 0)
2301 recv_neighbor = merge(bc_x%end, mpi_proc_null, bc_x%end >= 0)
2302 recv_val = huge(0._wp)
2303 call mpi_sendrecv(end_val, 1, mpi_p, send_neighbor, 101, recv_val, 1, mpi_p, recv_neighbor, &
2304 & 101, mpi_comm_world, mpi_status_ignore, ierr)
2305 end_val = recv_val
2306 end do
2307 neighbor_domain_x%beg = beg_val
2308 neighbor_domain_x%end = end_val
2309 end if
2310# 1479 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2311 if (num_dims >= 2) then
2312 beg_val = y_cb(-1)
2313 end_val = y_cb(n)
2314 do k = 1, ib_neighborhood_radius
2315 send_neighbor = merge(bc_y%end, mpi_proc_null, bc_y%end >= 0)
2316 recv_neighbor = merge(bc_y%beg, mpi_proc_null, bc_y%beg >= 0)
2317 recv_val = -huge(0._wp)
2318 call mpi_sendrecv(beg_val, 1, mpi_p, send_neighbor, 102, recv_val, 1, mpi_p, recv_neighbor, 102, &
2319 & mpi_comm_world, mpi_status_ignore, ierr)
2320 beg_val = recv_val
2321
2322 send_neighbor = merge(bc_y%beg, mpi_proc_null, bc_y%beg >= 0)
2323 recv_neighbor = merge(bc_y%end, mpi_proc_null, bc_y%end >= 0)
2324 recv_val = huge(0._wp)
2325 call mpi_sendrecv(end_val, 1, mpi_p, send_neighbor, 103, recv_val, 1, mpi_p, recv_neighbor, &
2326 & 103, mpi_comm_world, mpi_status_ignore, ierr)
2327 end_val = recv_val
2328 end do
2329 neighbor_domain_y%beg = beg_val
2330 neighbor_domain_y%end = end_val
2331 end if
2332# 1479 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2333 if (num_dims >= 3) then
2334 beg_val = z_cb(-1)
2335 end_val = z_cb(p)
2336 do k = 1, ib_neighborhood_radius
2337 send_neighbor = merge(bc_z%end, mpi_proc_null, bc_z%end >= 0)
2338 recv_neighbor = merge(bc_z%beg, mpi_proc_null, bc_z%beg >= 0)
2339 recv_val = -huge(0._wp)
2340 call mpi_sendrecv(beg_val, 1, mpi_p, send_neighbor, 104, recv_val, 1, mpi_p, recv_neighbor, 104, &
2341 & mpi_comm_world, mpi_status_ignore, ierr)
2342 beg_val = recv_val
2343
2344 send_neighbor = merge(bc_z%beg, mpi_proc_null, bc_z%beg >= 0)
2345 recv_neighbor = merge(bc_z%end, mpi_proc_null, bc_z%end >= 0)
2346 recv_val = huge(0._wp)
2347 call mpi_sendrecv(end_val, 1, mpi_p, send_neighbor, 105, recv_val, 1, mpi_p, recv_neighbor, &
2348 & 105, mpi_comm_world, mpi_status_ignore, ierr)
2349 end_val = recv_val
2350 end do
2351 neighbor_domain_z%beg = beg_val
2352 neighbor_domain_z%end = end_val
2353 end if
2354# 1501 "/home/runner/work/MFC/MFC/src/simulation/m_start_up.fpp"
2355#endif
2356
2357 end subroutine get_neighbor_bounds
2358
2359end module m_start_up
type(scalar_field), dimension(sys_size), intent(inout) q_cons_vf
One-way acoustic source injection, Maeda and Colonius JCP (2017).
impure subroutine, public s_precalculate_acoustic_spatial_sources
Pre-compute non-zero spatial source weights before time-stepping.
impure subroutine, public s_initialize_acoustic_src
Initialize the acoustic source module.
Computes gravitational and body force source terms for the momentum equations.
impure subroutine, public s_initialize_body_forces_module
Initialize the body forces module.
Noncharacteristic and processor boundary condition application for ghost cells and buffer regions.
impure subroutine, public s_initialize_boundary_common_module()
Allocate and set up boundary condition buffer arrays for all coordinate directions.
subroutine, public s_read_parallel_boundary_condition_files(bc_type)
Read boundary condition type and buffer data from per-rank parallel files using MPI I/O.
subroutine, public s_populate_grid_variables_buffers
Populate the buffers of the grid variables, which are constituted of the cell-boundary locations and ...
impure subroutine, public s_populate_variables_buffers(bc_type, q_prim_vf, pb_in, mv_in, q_t_sf)
Populate the buffers of the primitive variables based on the selected boundary conditions.
subroutine, public s_read_serial_boundary_condition_files(step_dirpath, bc_type)
Read boundary condition type and buffer data from serial (unformatted) restart files.
subroutine, public s_assign_default_bc_type(bc_type)
Initialize the per-cell boundary condition type arrays with the global default BC values.
Computes ensemble-averaged (Euler–Euler) bubble source terms for radius, velocity,...
impure subroutine s_initialize_bubbles_ee_module
Initialize the Euler-Euler bubble module.
Tracks Lagrangian bubbles and couples their dynamics to the Eulerian flow via volume averaging.
impure subroutine s_write_lag_bubble_stats()
Write the maximum and minimum radius statistics for each bubble.
impure subroutine s_write_restart_lag_bubbles(t_step)
Write restart files for the Lagrangian bubble solver.
integer nbubs
Number of bubbles in the local domain.
impure subroutine s_initialize_bubbles_el_module(q_cons_vf)
Initializes the lagrangian subgrid bubble solver.
type(scalar_field), dimension(:), allocatable q_beta
Projection of the lagrangian particles in the Eulerian framework.
real(wp), dimension(:,:), allocatable intfc_rad
Bubble radius.
Characteristic boundary conditions (CBC) for slip walls, non-reflecting subsonic inflow/outflow,...
impure subroutine, public s_initialize_cbc_module
Initialize the CBC module.
Shared input validation checks for grid dimensions and AMD GPU compiler limits.
impure subroutine, public s_check_inputs_common
Checks compatibility of parameters in the input file. Used by all three stages.
Validates simulation input parameters for consistency and supported configurations.
impure subroutine, public s_check_inputs
Checks compatibility of parameters in the input file. Used by the simulation stage.
Multi-species chemistry interface for thermodynamic properties, reaction rates, and transport coeffic...
subroutine s_compute_q_t_sf(q_t_sf, q_cons_vf, bounds)
Initialize the temperature field from conservative variables by inverting the energy equation.
Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients,...
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.
Writes solution data, run-time stability diagnostics (ICFL, VCFL, CCFL, Rc), and probe/center-of-mass...
impure subroutine, public s_initialize_data_output_module
Initialize the data output module.
impure subroutine, public s_write_data_files(q_cons_vf, q_t_sf, q_prim_vf, t_step, bc_type, beta)
Write data files. Dispatch subroutine that replaces procedure pointer.
impure subroutine, public s_write_ib_state_file(time_step)
Writes IB state records to restart_data/ib_state.dat. Must be called only on rank 0.
subroutine, public s_write_ib_data_file(time_step)
Dispatch immersed boundary data output to the serial or parallel writer.
Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures.
Derives diagnostic flow quantities (vorticity, speed of sound, numerical Schlieren,...
impure subroutine, public s_initialize_derived_variables
Allocate and open derived variables. Computing FD coefficients.
impure subroutine, public s_initialize_derived_variables_module
Computation of parameters, allocation procedures, and/or any other tasks needed to properly setup the...
Global parameters for the computational domain, fluid properties, and simulation algorithm configurat...
real(wp) mytime
Current simulation time.
type(ib_stl_parameters), dimension(num_stl_models_max) stl_models
Per-STL model parameters (namelist).
type(int_bounds_info), dimension(1:3) idwint
real(wp), dimension(:), allocatable, target z_cb
logical, parameter chemistry
Chemistry modeling.
type(bubbles_lagrange_parameters) lag_params
Lagrange bubbles' parameters.
integer proc_rank
Rank of the local processor.
character(len=name_len) mpiiofs
integer, dimension(:), allocatable start_idx
Starting cell-center index of local processor in global grid.
type(vec3_dt), dimension(num_probes_max) probe
integer sys_size
Number of unknowns in system of eqns.
type(ib_airfoil_parameters), dimension(num_ib_airfoils_max) ib_airfoil
Per-airfoil NACA user inputs (namelist).
type(int_bounds_info), dimension(1:3) idwbuff
type(particle_cloud_parameters), dimension(num_particle_clouds_max) particle_cloud
Particle bed specifications.
type(physical_parameters), dimension(num_fluids_max) fluid_pp
Stiffened gas EOS parameters and Reynolds numbers per fluid.
impure subroutine s_initialize_global_parameters_module
Initialize the global parameters module.
real(wp), dimension(:), allocatable, target y_cc
type(pres_field), dimension(:), allocatable pb_ts
type(pres_field), dimension(:), allocatable mv_ts
type(chemistry_parameters) chem_params
type(ib_patch_parameters), dimension(num_ib_patches_max_namelist) patch_ib
Immersed boundary patch parameters.
real(wp), dimension(:), allocatable, target z_cc
real(wp), dimension(:), allocatable qvs
real(wp), dimension(:), allocatable pi_infs
integer num_procs
Number of processors.
character(len=path_len) case_dir
real(wp), dimension(:), allocatable, target x_cc
type(acoustic_parameters), dimension(num_probes_max) acoustic
Acoustic source parameters.
type(integral_parameters), dimension(num_probes_max) integral
real(wp), dimension(:), allocatable, target y_cb
type(cell_num_bounds) cells_bounds
logical elasticity
elasticity modeling, true for hyper or hypo
type(mpi_io_var), public mpi_io_data
real(wp), dimension(:), allocatable, target dy
type(subgrid_bubble_physical_parameters) bub_pp
real(wp), dimension(:), allocatable gammas
real(wp) finaltime
Final simulation time.
real(wp), dimension(:), allocatable, target dz
real(wp), dimension(:), allocatable, target dx
type(eqn_idx_info) eqn_idx
All conserved-variable equation index ranges and scalars.
real(wp), dimension(:), allocatable, target x_cb
Basic floating-point utilities: approximate equality, default detection, and coordinate bounds.
elemental subroutine, public s_update_cell_bounds(bounds, m, n, p)
Updates the min and max number of cells in each set of axes.
Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions...
subroutine, public s_upsample_data(q_cons_vf, q_cons_temp)
Upsample conservative variable fields from a coarsened grid back to the original resolution using int...
impure subroutine, public s_initialize_bubbles_model()
Initialize bubble model arrays for Euler or Lagrangian bubbles with polytropic or non-polytropic gas.
elemental subroutine, public s_int_to_str(i, res)
Convert an integer to its trimmed string representation.
Computes the left Cauchy–Green deformation tensor and hyperelastic stress source terms.
impure subroutine, public s_initialize_hyperelastic_module
Initialize the hyperelastic module.
Computes hypoelastic stress-rate source terms and damage-state evolution.
impure subroutine, public s_initialize_hypoelastic_module
Initialize the hypoelastic module.
Allocate memory and read initial condition data for IC extrusion.
subroutine, public s_initialize_ib_airfoils()
Initialize the NACA surface grids for all airfoil IB patches. Must be called after the grid is establ...
Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients,...
impure subroutine, public s_ibm_setup()
Initializes the values of various IBM variables, such as ghost points and image points.
type(integer_field), public ib_markers
impure subroutine, public s_initialize_ibm_module()
Allocates memory for the variables in the IBM module.
Iterative ghost rasterization (IGR) for sharp immersed boundary treatment.
subroutine, public s_initialize_igr_module()
Initialize the IGR module.
integer(kind=8) j
integer(kind=8) i
integer(kind=8) l
integer(kind=8) r
integer(kind=8) k
Binary STL file reader and processor for immersed boundary geometry.
subroutine, public s_instantiate_stl_models()
Load, transform, and register STL/OBJ immersed-boundary models onto the simulation grid.
MPI communication layer: domain decomposition, halo exchange, reductions, and parallel I/O setup.
impure subroutine s_mpi_abort(prnt, code)
The subroutine terminates the MPI execution environment.
impure subroutine s_initialize_mpi_common_module
Initialize the module.
impure subroutine s_mpi_barrier
Halts all processes until all have reached barrier.
impure subroutine s_initialize_mpi_data(q_cons_vf, ib_markers, beta)
Set up MPI I/O data views and variable pointers for parallel file output.
subroutine s_initialize_mpi_data_ds(q_cons_vf)
Set up MPI I/O data views for downsampled (coarsened) parallel file output.
impure subroutine mpi_bcast_time_step_values(proc_time, time_avg)
Gather per-rank time step wall-clock times onto rank 0 for performance reporting.
MPI halo exchange, domain decomposition, and buffer packing/unpacking for the simulation solver.
subroutine s_initialize_mpi_proxy_module()
Initialize the MPI proxy module.
MUSCL reconstruction with interface sharpening for contact-preserving advection.
subroutine, public s_initialize_muscl_module()
Allocate and initialize MUSCL reconstruction working arrays.
NVIDIA NVTX profiling API bindings for GPU performance instrumentation.
Definition m_nvtx.f90:6
subroutine nvtxstartrange(name, id)
Push a named NVTX range for GPU profiling, optionally with a color based on the given identifier.
Definition m_nvtx.f90:62
subroutine nvtxendrange
Pop the current NVTX range to end the GPU profiling region.
Definition m_nvtx.f90:83
Generates particle beds by converting particle_cloud patch specifications into individual immersed bo...
impure subroutine, public s_generate_particle_clouds(particle_cloud_ibs)
Generate all particle beds and fill particle_cloud_ibs. Called on all ranks before s_reduce_ib_patch_...
Phase transition relaxation solvers for liquid-vapor flows with cavitation and boiling.
subroutine, public s_infinite_relaxation_k(q_cons_vf)
Apply pT- or pTg-equilibrium relaxation with mass depletion based on the incoming state conditions.
impure subroutine, public s_initialize_phasechange_module
Initialize the phase change module by setting saturation curve coefficients for pT- or pTg-equilibriu...
Quadrature-based moment methods (QBMM) for polydisperse bubble moment inversion and transport.
impure subroutine, public s_initialize_qbmm_module
Initialize the QBMM module.
Assembles the right-hand side of the governing equations using finite-volume flux differencing,...
impure subroutine, public s_initialize_rhs_module
Initialize the RHS module.
Approximate and exact Riemann solvers (HLL, HLLC, HLLD, exact) for the multicomponent Navier–Stokes e...
impure subroutine, public s_initialize_riemann_solvers_module
Initialize the Riemann solvers module.
Simulation helper routines for enthalpy computation, CFL calculation, and stability checks.
Reads input files, loads initial conditions and grid data, and orchestrates solver initialization and...
impure subroutine s_read_ib_restart_data(t_step)
Reads IB kinematic state from restart_data/ib_state.dat on restart. Rank 0 reads the last num_ibs rec...
impure subroutine, public s_read_serial_data_files(q_cons_vf)
Read serial initial condition and grid data files and compute cell-width distributions.
impure subroutine, public s_initialize_modules
Initialize all simulation sub-modules in the required dependency order.
impure subroutine, public s_read_data_files(q_cons_vf)
Read data files. Dispatch subroutine that replaces procedure pointer.
impure subroutine, public s_read_parallel_data_files(q_cons_vf)
Read parallel initial condition and grid data files via MPI I/O.
subroutine, public s_initialize_internal_energy_equations(v_vf)
Initialize internal-energy equations from phase mass, mixture momentum, and total energy.
impure subroutine, public s_save_performance_metrics(time_avg, time_final, io_time_avg, io_time_final, proc_time, io_proc_time, file_exists)
Collect per-process wall-clock times and write aggregate performance metrics to file.
subroutine get_neighbor_bounds()
subroutine s_compute_ib_neighbor_ranks()
Build ib_neighbor_ranks(-1:1,-1:1,-1:1): MPI ranks of all neighbor domains. Uses two rounds of MPI_SE...
subroutine s_reduce_ib_patch_array(particle_cloud_ibs)
Merges patch_ib (namelist patches, fixed at num_ib_patches_max_namelist) with particle_cloud_ibs (CPU...
impure subroutine, public s_save_data(t_step, start, finish, io_time_avg, nt)
Save conservative variable data to disk at the current time step.
type(scalar_field), dimension(:), allocatable q_cons_temp
subroutine, public s_initialize_gpu_vars
Transfer initial conservative variable and model parameter data to the GPU device.
impure subroutine, public s_initialize_mpi_domain
Set up the MPI execution environment, bind GPUs, and decompose the computational domain.
impure subroutine, public s_finalize_modules
Finalize and deallocate all simulation sub-modules in reverse initialization order.
impure subroutine, public s_read_input_file
Verify the input file exists and read it.
impure subroutine, public s_check_input_file
Validate that all user-provided inputs form a consistent simulation configuration.
impure subroutine, public s_perform_time_step(t_step, time_avg)
Advance the simulation by one time step, handling CFL-based dt and time-stepper dispatch.
Computes capillary source fluxes and color-function gradients for the diffuse-interface surface tensi...
impure subroutine, public s_initialize_surface_tension_module
Allocate and initialize surface tension module arrays.
THINC and MTHINC interface compression for volume fraction sharpening. THINC (int_comp=1): 1D directi...
subroutine, public s_initialize_thinc_module()
real(wp), dimension(:,:,:), allocatable position
Total-variation-diminishing (TVD) Runge–Kutta time integrators (1st-, 2nd-, and 3rd-order SSP).
type(scalar_field) q_t_sf
Cell-average temperature variables at the current time-stage.
type(integer_field), dimension(:,:), allocatable bc_type
Boundary condition identifiers.
impure subroutine s_initialize_time_steppers_module
Initialize the time steppers module.
type(vector_field), dimension(:), allocatable q_cons_ts
Cell-average conservative variables at each time-stage (TS).
type(scalar_field), dimension(:), allocatable q_prim_vf
Cell-average primitive variables at the current time-stage.
impure subroutine s_compute_dt()
Compute the global time step size from CFL stability constraints across all cells.
impure subroutine s_tvd_rk(t_step, time_avg, nstage)
Advance the solution one full step using a TVD Runge-Kutta time integrator.
integer stor
storage index
Conservative-to-primitive variable conversion, mixture property evaluation, and pressure computation.
subroutine, public s_compute_pressure(energy, alf, dyn_p, pi_inf, gamma, rho, qv, rhoyks, pres, t, stress, mom, g, pres_mag)
Compute the pressure from the appropriate equation of state.
impure subroutine, public s_initialize_variables_conversion_module
Initialize the variables conversion module.
subroutine, public s_convert_to_mixture_variables(q_vf, i, j, k, rho, gamma, pi_inf, qv, re_k, g_k, g)
Dispatch to the s_convert_mixture_to_mixture_variables and s_convert_species_to_mixture_variables sub...
Computes viscous stress tensors and diffusive flux contributions for the Navier–Stokes equations.
impure subroutine, public s_initialize_viscous_module
Initialize the viscous module.
WENO/WENO-Z/TENO reconstruction with optional monotonicity-preserving bounds and mapped weights.
impure subroutine, public s_initialize_weno_module
Initialize the WENO module.
Derived type annexing a scalar field (SF).