MFC
Exascale flow solver
Loading...
Searching...
No Matches
m_collisions.fpp.f90
Go to the documentation of this file.
1# 1 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
2!>
3!! @file
4!! @brief Contains module m_collisions
5
6# 1 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 1
7# 1 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 1
8# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
9# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
10# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
11# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
12# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
13# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
14
15# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
16# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
17# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
18
19# 15 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
20# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
21# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
22
23# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
24
25# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
26
27# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
28
29# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
30
31# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
32
33# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
34
35# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
36
37# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
38! New line at end of file is required for FYPP
39# 2 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
40# 1 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 1
41# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
42# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
43# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
44# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
45# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
46# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
47
48# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
49# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
50# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
51
52# 15 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
53# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
54# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
55
56# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
57
58# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
59
60# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
61
62# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
63
64# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
65
66# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
67
68# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
69
70# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
71! New line at end of file is required for FYPP
72# 2 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 2
73
74# 4 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
75# 5 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
76# 6 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
77# 7 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
78# 8 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
79
80# 20 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
81
82# 43 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
83
84# 48 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
85
86# 53 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
87
88# 58 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
89
90# 63 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
91
92# 68 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
93
94# 81 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
95
96# 86 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
97
98# 91 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
99
100# 96 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
101
102# 101 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
103
104# 106 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
105
106# 111 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
107
108# 116 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
109
110# 121 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
111
112# 126 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
113
114# 156 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
115
116# 197 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
117
118# 211 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
119
120# 236 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
121
122# 247 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
123
124# 249 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
125# 260 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
126
127# 310 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
128
129# 320 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
130
131# 330 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
132
133# 339 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
134
135# 356 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
136
137# 366 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
138
139# 373 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
140
141# 379 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
142
143# 385 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
144
145# 391 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
146
147# 397 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
148
149# 403 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
150! New line at end of file is required for FYPP
151# 3 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
152# 1 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 1
153# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
154# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
155# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
156# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
157# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
158# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
159
160# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
161# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
162# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
163
164# 15 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
165# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
166# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
167
168# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
169
170# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
171
172# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
173
174# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
175
176# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
177
178# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
179
180# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
181
182# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
183! New line at end of file is required for FYPP
184# 2 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 2
185
186# 7 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
187
188# 17 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
189
190# 22 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
191
192# 27 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
193
194# 32 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
195
196# 37 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
197
198# 42 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
199
200# 47 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
201
202# 52 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
203
204# 57 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
205
206# 62 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
207
208# 73 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
209
210# 78 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
211
212# 83 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
213
214# 88 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
215
216# 103 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
217
218# 131 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
219
220# 160 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
221
222# 175 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
223
224# 193 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
225
226# 215 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
227
228# 244 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
229
230# 259 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
231
232# 269 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
233
234# 278 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
235
236# 294 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
237
238# 304 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
239
240# 311 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
241! New line at end of file is required for FYPP
242# 4 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
243
244! GPU parallel region (scalar reductions, maxval/minval)
245# 23 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
246
247! GPU parallel loop over threads (most common GPU macro)
248# 43 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
249
250! Required closing for GPU_PARALLEL_LOOP
251# 55 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
252
253! Mark routine for device compilation
254# 112 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
255
256! Declare device-resident data
257# 130 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
258
259! Inner loop within a GPU parallel region
260# 145 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
261
262! Scoped GPU data region
263# 164 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
264
265! Host code with device pointers (for MPI with GPU buffers)
266# 193 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
267
268! Allocate device memory (unscoped)
269# 207 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
270
271! Free device memory
272# 219 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
273
274! Atomic operation on device
275# 231 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
276
277! End atomic capture block
278# 242 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
279
280! Copy data between host and device
281# 254 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
282
283! Synchronization barrier
284# 266 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
285
286! Import GPU library module (openacc or omp_lib)
287# 275 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
288
289! Emit code only for AMD compiler
290# 282 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
291
292! Emit code for non-Cray compilers
293# 289 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
294
295! Emit code only for Cray compiler
296# 296 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
297
298! Emit code for non-NVIDIA compilers
299# 303 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
300
301# 305 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
302# 306 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
303! New line at end of file is required for FYPP
304# 2 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 2
305
306# 14 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
307
308! Caution: This macro requires the use of a binding script to set CUDA_VISIBLE_DEVICES, such that we have one GPU device per MPI
309! rank. That's because for both cudaMemAdvise (preferred location) and cudaMemPrefetchAsync we use location = device_id = 0. For an
310! example see misc/nvidia_uvm/bind.sh.
311# 52 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
312
313! Allocate and create GPU device memory
314# 72 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
315
316! Free GPU device memory and deallocate
317# 80 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
318
319! Cray-specific GPU pointer setup for vector fields
320# 104 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
321
322! Cray-specific GPU pointer setup for scalar fields
323# 120 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
324
325! Cray-specific GPU pointer setup for acoustic source spatials
326# 145 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
327
328# 151 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
329
330# 158 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
331! New line at end of file is required for FYPP
332# 6 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp" 2
333
334!> @brief Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients, and corrects the
335!! flow state
337
338 use m_derived_types !< definitions of the derived types
339 use m_global_parameters !< definitions of the global parameters
340 use m_helper
341 use m_helper_basic !< functions to compare floating point numbers
342 use m_constants
344 use m_ib_patches
345 use m_model
346 use m_mpi_proxy
347
348 implicit none
349
352 ! overlap distances for computing collisions
353 integer, allocatable, dimension(:,:) :: collision_lookup
354 real(wp), allocatable, dimension(:,:) :: wall_overlap_distances
356
357# 29 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
358#if defined(MFC_OpenACC)
359# 29 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
360!$acc declare create(spring_stiffness, damping_parameter)
361# 29 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
362#elif defined(MFC_OpenMP)
363# 29 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
364!$omp declare target (spring_stiffness, damping_parameter)
365# 29 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
366#endif
367
368# 30 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
369#if defined(MFC_OpenACC)
370# 30 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
371!$acc declare create(collision_lookup, wall_overlap_distances)
372# 30 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
373#elif defined(MFC_OpenMP)
374# 30 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
375!$omp declare target (collision_lookup, wall_overlap_distances)
376# 30 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
377#endif
378
379 integer, dimension(:), allocatable :: ib_gbl_idx_lookup
380
381# 33 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
382#if defined(MFC_OpenACC)
383# 33 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
384!$acc declare create(ib_gbl_idx_lookup)
385# 33 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
386#elif defined(MFC_OpenMP)
387# 33 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
388!$omp declare target (ib_gbl_idx_lookup)
389# 33 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
390#endif
391
392 !> true when any IB-IB or IB-wall contact was detected on this rank since the last adaptive-dt computation
394
395contains
396
398
399 real(wp) :: e
400
401 e = coefficient_of_restitution
402 damping_parameter = -2._wp*log(e)/collision_time
403 spring_stiffness = (pi**2 + log(e)**2)/(collision_time**2)
404
405# 47 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
406#if defined(MFC_OpenACC)
407# 47 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
408!$acc update device(damping_parameter, spring_stiffness)
409# 47 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
410#elif defined(MFC_OpenMP)
411# 47 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
412!$omp target update to(damping_parameter, spring_stiffness)
413# 47 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
414#endif
415
416#ifdef MFC_DEBUG
417# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
418 block
419# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
420 use iso_fortran_env, only: output_unit
421# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
422
423# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
424 print *, 'm_collisions.fpp:49: ', '@:ALLOCATE(collision_lookup(num_local_ibs_max * 27 * 8, 4))'
425# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
426
427# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
428 call flush (output_unit)
429# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
430 end block
431# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
432#endif
433# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
434 allocate (collision_lookup(num_local_ibs_max * 27 * 8, 4))
435# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
436
437# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
438
439# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
440#if defined(MFC_OpenACC)
441# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
442!$acc enter data create(collision_lookup)
443# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
444#elif defined(MFC_OpenMP)
445# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
446!$omp target enter data map(always,alloc:collision_lookup)
447# 49 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
448#endif
449#ifdef MFC_DEBUG
450# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
451 block
452# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
453 use iso_fortran_env, only: output_unit
454# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
455
456# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
457 print *, 'm_collisions.fpp:50: ', '@:ALLOCATE(wall_overlap_distances(num_local_ibs_max*27, 6))'
458# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
459
460# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
461 call flush (output_unit)
462# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
463 end block
464# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
465#endif
466# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
467 allocate (wall_overlap_distances(num_local_ibs_max*27, 6))
468# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
469
470# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
471
472# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
473#if defined(MFC_OpenACC)
474# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
475!$acc enter data create(wall_overlap_distances)
476# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
477#elif defined(MFC_OpenMP)
478# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
479!$omp target enter data map(always,alloc:wall_overlap_distances)
480# 50 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
481#endif
482
484 collisions_active = .false.
485
486# 54 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
487#if defined(MFC_OpenACC)
488# 54 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
489!$acc update device(wall_overlap_distances)
490# 54 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
491#elif defined(MFC_OpenMP)
492# 54 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
493!$omp target update to(wall_overlap_distances)
494# 54 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
495#endif
496
497# 55 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
498#if defined(MFC_OpenACC)
499# 55 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
500!$acc update device(ib_coefficient_of_friction)
501# 55 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
502#elif defined(MFC_OpenMP)
503# 55 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
504!$omp target update to(ib_coefficient_of_friction)
505# 55 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
506#endif
507
508 end subroutine s_initialize_collisions_module
509
510 subroutine s_apply_collision_forces(ghost_points, num_gps, ib_markers, forces, torques)
511
512 type(ghost_point), dimension(:), intent(in) :: ghost_points
513 integer, intent(in) :: num_gps
514 type(integer_field), intent(in) :: ib_markers
515 real(wp), dimension(num_ibs, 3), intent(inout) :: forces, torques
516 integer :: num_considered_collisions
517 logical :: any_wall_collision
518
519 ! return if no collisions
520
521 if (collision_model == 0) return
522
523 ! get is distance used in the force calculation with each IB and each wall
524 call s_detect_wall_collisions(any_wall_collision)
525 call s_detect_ib_collisions(ghost_points, ib_markers, num_gps, num_considered_collisions)
526
527 ! accumulate across RK stages; consumed (and reset) by s_compute_dt once per time step
528 collisions_active = collisions_active .or. any_wall_collision .or. (num_considered_collisions > 0)
529
530 select case (collision_model)
531 case (1) ! soft sphere model
533 call s_apply_ib_collision_forces_soft_sphere(num_considered_collisions, forces, torques)
534 end select
535
536 end subroutine s_apply_collision_forces
537
538 !> @brief applies collision forces to IBs assuming a soft-sphere collision model (all IBs are circles or spheres)
539 subroutine s_apply_ib_collision_forces_soft_sphere(num_considered_collisions, forces, torques)
540
541 integer, intent(in) :: num_considered_collisions
542 real(wp), dimension(num_ibs, 3), intent(inout) :: forces, torques
543 integer :: i, encoded_pid1, encoded_pid2, xp1, xp2, yp1, yp2, zp1, zp2, pid1, pid2, l ! iterators and patch IDs
544 real(wp) :: overlap_distance
545 real(wp), dimension(3) :: normal_vector, centroid_1, centroid_2
546 real(wp), dimension(3) :: normal_velocity, tangential_vector, normal_force, tangential_force, torque, radial_vector, &
547 & rotation_velocity, vel1, vel2
548 real(wp) :: k, eta, effective_mass ! the spring stiffness and damping coefficient and mass of a specific interaction
549
550 if (num_considered_collisions == 0) return
551
552 ! Iterate over all collisions detected
553
554# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
555
556# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
557#if defined(MFC_OpenACC)
558# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
559!$acc parallel loop gang vector default(present) private(i, l, encoded_pid1, encoded_pid2, xp1, xp2, yp1, yp2, zp1, zp2, pid1, pid2, centroid_1, centroid_2, normal_vector, overlap_distance, &
560# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
561!$acc& effective_mass, k, eta, normal_velocity, tangential_vector, normal_force, tangential_force, torque, radial_vector, rotation_velocity, vel1, vel2) copy(forces, torques)
562# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
563#elif defined(MFC_OpenMP)
564# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
565
566# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
567
568# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
569
570# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
571!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) private(i, l, encoded_pid1, &
572# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
573!$omp& encoded_pid2, xp1, xp2, yp1, yp2, zp1, zp2, pid1, pid2, centroid_1, centroid_2, normal_vector, overlap_distance, effective_mass, k, eta, normal_velocity, tangential_vector, normal_force, &
574# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
575!$omp& tangential_force, torque, radial_vector, rotation_velocity, vel1, vel2) map(tofrom:forces, torques)
576# 102 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
577#endif
578# 106 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
579 do i = 1, num_considered_collisions
580 encoded_pid1 = collision_lookup(i, 3)
581 encoded_pid2 = collision_lookup(i, 4)
582 call s_decode_patch_periodicity(encoded_pid1, pid1, xp1, yp1, zp1)
583 call s_decode_patch_periodicity(encoded_pid2, pid2, xp2, yp2, zp2)
584 pid1 = collision_lookup(i, 1)
585 pid2 = collision_lookup(i, 2)
586
587 if (pid1 <= 0 .or. pid2 <= 0) cycle
588
589 centroid_1(1) = patch_ib(pid1)%x_centroid + real(xp1, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg)
590 centroid_1(2) = patch_ib(pid1)%y_centroid + real(yp1, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg)
591 centroid_1(3) = 0._wp
592 centroid_2(1) = patch_ib(pid2)%x_centroid + real(xp2, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg)
593 centroid_2(2) = patch_ib(pid2)%y_centroid + real(yp2, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg)
594 centroid_2(3) = 0._wp
595 if (num_dims == 3) then
596 centroid_1(3) = patch_ib(pid1)%z_centroid + real(zp1, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg)
597 centroid_2(3) = patch_ib(pid2)%z_centroid + real(zp2, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg)
598 end if
599
600 normal_vector = centroid_2 - centroid_1
601 overlap_distance = patch_ib(pid1)%radius + patch_ib(pid2)%radius - norm2(normal_vector)
602 if (overlap_distance > 0._wp) then ! if the two patches are close enough to collide
603 normal_vector = normal_vector/norm2(normal_vector)
604 if (f_local_rank_owns_location(centroid_1, glb_bounds)) then
605 ! compute constants of the collision
606 effective_mass = 1.0_wp/((1.0_wp/patch_ib(pid1)%mass) + (1._wp/(patch_ib(pid2)%mass)))
607 k = spring_stiffness*effective_mass
608 eta = damping_parameter*effective_mass
609
610 ! Get the vectors and velcoities
611 radial_vector = normal_vector*(patch_ib(pid1)%radius - 0.5_wp*overlap_distance)
612 call s_cross_product(patch_ib(pid1)%angular_vel, radial_vector, rotation_velocity)
613 vel1 = patch_ib(pid1)%vel + rotation_velocity
614 radial_vector = normal_vector*(-1.0_wp)*(patch_ib(pid2)%radius - 0.5_wp*overlap_distance)
615 call s_cross_product(patch_ib(pid2)%angular_vel, radial_vector, rotation_velocity)
616 vel2 = patch_ib(pid2)%vel + rotation_velocity
617
618 normal_velocity = dot_product(vel1 - vel2, normal_vector)*normal_vector
619 tangential_vector = (vel1 - vel2) - normal_velocity
620 if (.not. f_approx_equal(norm2(tangential_vector), &
621 & 0._wp)) tangential_vector = tangential_vector/norm2(tangential_vector)
622
623 ! compute force and torque
624 normal_force = -k*overlap_distance*normal_vector - eta*normal_velocity
625 tangential_force = -ib_coefficient_of_friction*norm2(normal_force)*tangential_vector
626 call s_cross_product(normal_vector*patch_ib(pid1)%radius, tangential_force, torque)
627
628 do l = 1, num_dims
629 ! update the first IB
630
631# 157 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
632#if defined(MFC_OpenACC)
633# 157 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
634!$acc atomic update
635# 157 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
636#elif defined(MFC_OpenMP)
637# 157 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
638!$omp atomic update
639# 157 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
640#endif
641 forces(pid1, l) = forces(pid1, l) + (normal_force(l) + tangential_force(l))
642
643# 159 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
644#if defined(MFC_OpenACC)
645# 159 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
646!$acc atomic update
647# 159 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
648#elif defined(MFC_OpenMP)
649# 159 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
650!$omp atomic update
651# 159 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
652#endif
653 torques(pid1, l) = torques(pid1, l) + torque(l)
654
655 ! apply equal and opposite force/torque to second IB
656
657# 163 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
658#if defined(MFC_OpenACC)
659# 163 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
660!$acc atomic update
661# 163 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
662#elif defined(MFC_OpenMP)
663# 163 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
664!$omp atomic update
665# 163 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
666#endif
667 forces(pid2, l) = forces(pid2, l) - (normal_force(l) + tangential_force(l))
668
669# 165 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
670#if defined(MFC_OpenACC)
671# 165 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
672!$acc atomic update
673# 165 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
674#elif defined(MFC_OpenMP)
675# 165 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
676!$omp atomic update
677# 165 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
678#endif
679 torques(pid2, l) = torques(pid2, l) + torque(l)*patch_ib(pid2)%radius/patch_ib(pid1)%radius
680 end do
681 end if
682 end if
683 end do
684
685# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
686#if defined(MFC_OpenACC)
687# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
688!$acc end parallel loop
689# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
690#elif defined(MFC_OpenMP)
691# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
692
693# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
694!$omp end target teams loop
695# 171 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
696#endif
697
699
700 !> @brief applies collision forces to IBs assuming a soft-sphere collision model (all IBs are circles or spheres)
702
703 real(wp), dimension(num_ibs, 3), intent(inout) :: forces, torques
704 integer :: patch_id, i, l
705 real(wp), dimension(3) :: normal_force, tangential_force, normal_vector, normal_velocity, tangential_vector, &
706 & collision_location, torque, radial_vector, rotation_velocity, velocity
707 real(wp) :: k, eta ! the spring stiffness and damping coefficient for a specific IB
708
709
710# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
711
712# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
713#if defined(MFC_OpenACC)
714# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
715!$acc parallel loop collapse(2) gang vector default(present) &
716# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
717!$acc& private(patch_id, i, l, collision_location, normal_vector, k, eta, normal_velocity, tangential_vector, normal_force, tangential_force, torque, radial_vector, rotation_velocity, velocity) &
718# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
719!$acc& copy(forces, torques)
720# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
721#elif defined(MFC_OpenMP)
722# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
723
724# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
725
726# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
727
728# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
729!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) collapse(2) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
730# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
731!$omp& private(patch_id, i, l, collision_location, normal_vector, k, eta, normal_velocity, tangential_vector, normal_force, tangential_force, torque, radial_vector, rotation_velocity, velocity) &
732# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
733!$omp& map(tofrom:forces, torques)
734# 184 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
735#endif
736# 187 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
737 do patch_id = 1, num_ibs
738 do i = 1, num_dims*2
739 ! only compute force contributions if there was an overlap
740 if (f_approx_equal(wall_overlap_distances(patch_id, i), 0._wp)) cycle
741
742 select case (i)
743 case (1) ! x domain left
744 normal_vector = [-1._wp, 0._wp, 0._wp]
745 case (2) ! x domain right
746 normal_vector = [1._wp, 0._wp, 0._wp]
747 case (3) ! y domain bottom
748 normal_vector = [0._wp, -1._wp, 0._wp]
749 case (4) ! y domain top
750 normal_vector = [0._wp, 1._wp, 0._wp]
751 case (5) ! z domain back
752 normal_vector = [0._wp, 0._wp, -1._wp]
753 case (6) ! z domain front
754 normal_vector = [0._wp, 0._wp, 1._wp]
755 end select
756
757 ! ensure the local rank owns that collision before proceeding
758 collision_location = [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, 0._wp]
759 if (num_dims == 3) collision_location(3) = patch_ib(patch_id)%z_centroid
760 if (f_local_rank_owns_location(collision_location, glb_bounds)) then
761 k = spring_stiffness*patch_ib(patch_id)%mass
762 eta = damping_parameter*patch_ib(patch_id)%mass
763
764 ! get the vector that points from the centroid to the point of collision
765 radial_vector = normal_vector*(patch_ib(patch_id)%radius - wall_overlap_distances(patch_id, i))
766 ! convert the angular velocity to linear velocity
767 call s_cross_product(patch_ib(patch_id)%angular_vel, radial_vector, rotation_velocity)
768 velocity = patch_ib(patch_id)%vel + rotation_velocity
769
770 ! standard soft-sphere collision with the wall
771 normal_velocity = dot_product(velocity, normal_vector)*normal_vector
772 tangential_vector = velocity - normal_velocity
773 if (.not. f_approx_equal(norm2(tangential_vector), &
774 & 0._wp)) tangential_vector = tangential_vector/norm2(tangential_vector)
775 normal_force = -k*wall_overlap_distances(patch_id, i)*normal_vector - eta*normal_velocity
776 tangential_force = -ib_coefficient_of_friction*norm2(normal_force)*tangential_vector
777 call s_cross_product(normal_vector*patch_ib(patch_id)%radius, tangential_force, torque)
778
779 do l = 1, num_dims
780
781# 230 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
782#if defined(MFC_OpenACC)
783# 230 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
784!$acc atomic update
785# 230 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
786#elif defined(MFC_OpenMP)
787# 230 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
788!$omp atomic update
789# 230 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
790#endif
791 forces(patch_id, l) = forces(patch_id, l) + (normal_force(l) + tangential_force(l))
792
793# 232 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
794#if defined(MFC_OpenACC)
795# 232 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
796!$acc atomic update
797# 232 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
798#elif defined(MFC_OpenMP)
799# 232 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
800!$omp atomic update
801# 232 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
802#endif
803 torques(patch_id, l) = torques(patch_id, l) + torque(l)
804 end do
805 end if
806 end do
807 end do
808
809# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
810#if defined(MFC_OpenACC)
811# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
812!$acc end parallel loop
813# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
814#elif defined(MFC_OpenMP)
815# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
816
817# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
818!$omp end target teams loop
819# 238 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
820#endif
821
823
824 !> uses ghost-point/image-point information to determine if it is possible if two IBs are colliding, effectively an optimized
825 !! nearest neighbor search
826 subroutine s_detect_ib_collisions(gps, ib_markers, num_gps, num_considered_collisions)
827
828 type(ghost_point), dimension(num_gps), intent(in) :: gps
829 type(integer_field), intent(in) :: ib_markers
830 integer, intent(in) :: num_gps
831 integer, intent(out) :: num_considered_collisions
832 integer :: i, j, k, z_bound, ii, jj, kk
833 integer, dimension(2) :: decoded_pairs
834 integer :: gp_idx, gp_patch_id, neighbor_patch_id
835 integer :: pair_idx, out_idx
836 logical :: already_found
837
838 ! Temporary array to hold all detected pairs (with potential duplicates)
839 integer, dimension(num_gps, 2) :: raw_pairs
840 integer :: num_raw, local_num_raw
841
842 num_raw = 0
843 z_bound = 0; if (num_dims == 3) z_bound = 2
844
845
846# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
847
848# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
849#if defined(MFC_OpenACC)
850# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
851!$acc parallel loop gang vector default(present) private(gp_idx, gp_patch_id, neighbor_patch_id, local_num_raw, i, j, k, ii, jj, kk) copy(raw_pairs, num_raw) copyin(z_bound)
852# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
853#elif defined(MFC_OpenMP)
854# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
855
856# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
857
858# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
859
860# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
861!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
862# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
863!$omp& private(gp_idx, gp_patch_id, neighbor_patch_id, local_num_raw, i, j, k, ii, jj, kk) map(tofrom:raw_pairs, num_raw) map(to:z_bound)
864# 263 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
865#endif
866# 265 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
867 do gp_idx = 1, num_gps
868 i = gps(gp_idx)%loc(1)
869 j = gps(gp_idx)%loc(2)
870 k = 0; if (num_dims == 3) k = gps(gp_idx)%loc(3)
871 gp_patch_id = ib_markers%sf(i, j, k)
872
873 ! search in a cube around the BG for Ib markers belonging to another patch
874 neighbor_search: do ii = i - 2, i + 2
875 do jj = j - 2, j + 2
876 do kk = k - z_bound, k + z_bound
877 neighbor_patch_id = ib_markers%sf(ii, jj, kk)
878
879 ! If any neighbors are of a different/higher marker value, we consider it for possible collision
880 if (gp_patch_id < neighbor_patch_id) then
881
882# 279 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
883#if defined(MFC_OpenACC)
884# 279 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
885!$acc atomic capture
886# 279 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
887#elif defined(MFC_OpenMP)
888# 279 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
889!$omp atomic capture
890# 279 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
891#endif
892 num_raw = num_raw + 1
893 local_num_raw = num_raw
894#if defined(MFC_OpenACC)
895# 282 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
896!$acc end atomic
897# 282 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
898#elif defined(MFC_OpenMP)
899# 282 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
900!$omp end atomic
901# 282 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
902#endif
903
904 ! Store with smaller ID first for consistent ordering
905 raw_pairs(local_num_raw, 1) = gp_patch_id
906 raw_pairs(local_num_raw, 2) = neighbor_patch_id
907 exit neighbor_search
908 end if
909 end do
910 end do
911 end do neighbor_search
912 end do
913
914# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
915#if defined(MFC_OpenACC)
916# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
917!$acc end parallel loop
918# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
919#elif defined(MFC_OpenMP)
920# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
921
922# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
923!$omp end target teams loop
924# 293 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
925#endif
926
927 ! Coalesce collisions unique pairs
928 num_considered_collisions = 0
930 ! for each pair found in the raw collection
931 do pair_idx = 1, num_raw
932 already_found = .false.
933
934 ! get the decoded pairs for checking if they exist, using ii,jj,kk as dummy indices
935 call s_decode_patch_periodicity(raw_pairs(pair_idx, 1), decoded_pairs(1), ii, jj, kk)
936 call s_decode_patch_periodicity(raw_pairs(pair_idx, 2), decoded_pairs(2), ii, jj, kk)
937 decoded_pairs(1) = ib_gbl_idx_lookup(decoded_pairs(1))
938 decoded_pairs(2) = ib_gbl_idx_lookup(decoded_pairs(2))
939
940 ! skip self-collisions (an IB cannot collide with its own periodic image)
941 if (decoded_pairs(1) == decoded_pairs(2)) cycle
942
943 ! need to swap to guarantee the smaller decoded marker value is in index 1 and prevent double-counting
944 if (decoded_pairs(2) < decoded_pairs(1)) then
945 decoded_pairs(1) = decoded_pairs(1) + decoded_pairs(2)
946 decoded_pairs(2) = decoded_pairs(1) - decoded_pairs(2)
947 decoded_pairs(1) = decoded_pairs(1) - decoded_pairs(2)
948 raw_pairs(pair_idx, 1) = raw_pairs(pair_idx, 1) + raw_pairs(pair_idx, 2)
949 raw_pairs(pair_idx, 2) = raw_pairs(pair_idx, 1) - raw_pairs(pair_idx, 2)
950 raw_pairs(pair_idx, 1) = raw_pairs(pair_idx, 1) - raw_pairs(pair_idx, 2)
951 end if
952
953 ! check if it is already in the list
954 do out_idx = 1, num_considered_collisions
955 if (collision_lookup(out_idx, 1) == decoded_pairs(1) .and. collision_lookup(out_idx, 2) == decoded_pairs(2)) then
956 already_found = .true.
957 exit
958 end if
959 end do
960
961 ! and if it is not, append it to the list of pairs
962 if (.not. already_found) then
963 num_considered_collisions = num_considered_collisions + 1
964 if (num_considered_collisions > size(collision_lookup, 1)) then
965# 332 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
966 call s_prohibit_abort("num_considered_collisions > size(collision_lookup, 1)", "More collisions detected than memory to hold them. Consider increasing the size of the collision_lookup array")
967# 332 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
968 end if
969# 334 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
970
971 collision_lookup(num_considered_collisions, 1) = decoded_pairs(1)
972 collision_lookup(num_considered_collisions, 2) = decoded_pairs(2)
973 collision_lookup(num_considered_collisions, 3) = raw_pairs(pair_idx, 1)
974 collision_lookup(num_considered_collisions, 4) = raw_pairs(pair_idx, 2)
975 end if
976 end do
977
978# 341 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
979#if defined(MFC_OpenACC)
980# 341 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
981!$acc update device(collision_lookup)
982# 341 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
983#elif defined(MFC_OpenMP)
984# 341 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
985!$omp target update to(collision_lookup)
986# 341 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
987#endif
988
989 end subroutine s_detect_ib_collisions
990
991 !> @brief uses boundary conditions and particle locations to check for wall conditions
992 subroutine s_detect_wall_collisions(any_wall_collision)
993
994 logical, intent(out) :: any_wall_collision
995 integer :: gp_idx, i, j, k, patch_id
996 real(wp) :: edge_location, overlap_distance, max_overlap
997
998 max_overlap = 0._wp
999
1000# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1001
1002# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1003#if defined(MFC_OpenACC)
1004# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1005!$acc parallel loop gang vector default(present) private(patch_id, edge_location, overlap_distance) reduction(max:max_overlap)
1006# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1007#elif defined(MFC_OpenMP)
1008# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1009
1010# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1011
1012# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1013
1014# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1015!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
1016# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1017!$omp& private(patch_id, edge_location, overlap_distance) reduction(max:max_overlap)
1018# 353 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1019#endif
1020 do patch_id = 1, num_ibs
1021# 356 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1022 ! check if the boundaries are either of the two conditions we should compute collisions with
1023 if (ib_bc_x%beg == bc_slip_wall .or. ib_bc_x%beg == bc_no_slip_wall) then
1024 ! get the location of the true IB surface towards the domain boundary
1025 edge_location = patch_ib(patch_id)%x_centroid - patch_ib(patch_id)%radius
1026 ! check if that edge actually extends out of the comutational domain
1027 if (edge_location < glb_bounds(1)%beg) then
1028 ! the distance that the IB extends out of the domain
1029 overlap_distance = glb_bounds(1)%beg - edge_location
1030 else
1031 overlap_distance = 0._wp
1032 end if
1033 wall_overlap_distances(patch_id, 1) = overlap_distance
1034 max_overlap = max(max_overlap, overlap_distance)
1035 end if
1036
1037 if (ib_bc_x%end == bc_slip_wall .or. ib_bc_x%end == bc_no_slip_wall) then
1038 edge_location = patch_ib(patch_id)%x_centroid + patch_ib(patch_id)%radius
1039 if (edge_location > glb_bounds(1)%end) then
1040 overlap_distance = edge_location - glb_bounds(1)%end
1041 else
1042 overlap_distance = 0._wp
1043 end if
1044 wall_overlap_distances(patch_id, 1 + 1) = overlap_distance
1045 max_overlap = max(max_overlap, overlap_distance)
1046 end if
1047# 356 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1048 ! check if the boundaries are either of the two conditions we should compute collisions with
1049 if (ib_bc_y%beg == bc_slip_wall .or. ib_bc_y%beg == bc_no_slip_wall) then
1050 ! get the location of the true IB surface towards the domain boundary
1051 edge_location = patch_ib(patch_id)%y_centroid - patch_ib(patch_id)%radius
1052 ! check if that edge actually extends out of the comutational domain
1053 if (edge_location < glb_bounds(2)%beg) then
1054 ! the distance that the IB extends out of the domain
1055 overlap_distance = glb_bounds(2)%beg - edge_location
1056 else
1057 overlap_distance = 0._wp
1058 end if
1059 wall_overlap_distances(patch_id, 3) = overlap_distance
1060 max_overlap = max(max_overlap, overlap_distance)
1061 end if
1062
1063 if (ib_bc_y%end == bc_slip_wall .or. ib_bc_y%end == bc_no_slip_wall) then
1064 edge_location = patch_ib(patch_id)%y_centroid + patch_ib(patch_id)%radius
1065 if (edge_location > glb_bounds(2)%end) then
1066 overlap_distance = edge_location - glb_bounds(2)%end
1067 else
1068 overlap_distance = 0._wp
1069 end if
1070 wall_overlap_distances(patch_id, 3 + 1) = overlap_distance
1071 max_overlap = max(max_overlap, overlap_distance)
1072 end if
1073# 356 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1074 ! check if the boundaries are either of the two conditions we should compute collisions with
1075 if (ib_bc_z%beg == bc_slip_wall .or. ib_bc_z%beg == bc_no_slip_wall) then
1076 ! get the location of the true IB surface towards the domain boundary
1077 edge_location = patch_ib(patch_id)%z_centroid - patch_ib(patch_id)%radius
1078 ! check if that edge actually extends out of the comutational domain
1079 if (edge_location < glb_bounds(3)%beg) then
1080 ! the distance that the IB extends out of the domain
1081 overlap_distance = glb_bounds(3)%beg - edge_location
1082 else
1083 overlap_distance = 0._wp
1084 end if
1085 wall_overlap_distances(patch_id, 5) = overlap_distance
1086 max_overlap = max(max_overlap, overlap_distance)
1087 end if
1088
1089 if (ib_bc_z%end == bc_slip_wall .or. ib_bc_z%end == bc_no_slip_wall) then
1090 edge_location = patch_ib(patch_id)%z_centroid + patch_ib(patch_id)%radius
1091 if (edge_location > glb_bounds(3)%end) then
1092 overlap_distance = edge_location - glb_bounds(3)%end
1093 else
1094 overlap_distance = 0._wp
1095 end if
1096 wall_overlap_distances(patch_id, 5 + 1) = overlap_distance
1097 max_overlap = max(max_overlap, overlap_distance)
1098 end if
1099# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1100 end do
1101
1102# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1103#if defined(MFC_OpenACC)
1104# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1105!$acc end parallel loop
1106# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1107#elif defined(MFC_OpenMP)
1108# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1109
1110# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1111!$omp end target teams loop
1112# 383 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1113#endif
1114
1115 any_wall_collision = max_overlap > 0._wp
1116
1117 end subroutine s_detect_wall_collisions
1118
1119 !> @brief function checks if this local MPI processor owns this specific collision
1120 function f_neighborhood_ranks_own_location(location) result(owns_collision)
1121
1122 real(wp), dimension(3), intent(in) :: location
1123 logical :: owns_collision, periodic_owner
1124 real(wp) :: temp_neighbor_domain
1125 integer :: i
1126
1127 owns_collision = .true.
1128
1129#ifdef MFC_MPI
1130 if (num_procs > 2) then
1131 ! catch the edge case where th collision lies just outside the computational domain
1132 owns_collision = .true.
1133# 404 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1134 if (num_dims >= 1) then
1135 if (ib_bc_x%beg == bc_periodic .and. neighbor_domain_x%beg >= neighbor_domain_x%end) then
1136 ! project right side to the left
1137 temp_neighbor_domain = neighbor_domain_x%end + (glb_bounds(1)%end - glb_bounds(1)%beg)
1138 periodic_owner = neighbor_domain_x%beg <= location(1) .and. location(1) < temp_neighbor_domain
1139 ! project the left side to the right
1140 temp_neighbor_domain = neighbor_domain_x%beg - (glb_bounds(1)%end - glb_bounds(1)%beg)
1141 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(1) .and. location(1) &
1142 & < neighbor_domain_x%end)
1143
1144 owns_collision = owns_collision .and. periodic_owner
1145 else
1146 owns_collision = owns_collision .and. neighbor_domain_x%beg <= location(1) .and. location(1) &
1147 & < neighbor_domain_x%end
1148 end if
1149 end if
1150# 404 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1151 if (num_dims >= 2) then
1152 if (ib_bc_y%beg == bc_periodic .and. neighbor_domain_y%beg >= neighbor_domain_y%end) then
1153 ! project right side to the left
1154 temp_neighbor_domain = neighbor_domain_y%end + (glb_bounds(2)%end - glb_bounds(2)%beg)
1155 periodic_owner = neighbor_domain_y%beg <= location(2) .and. location(2) < temp_neighbor_domain
1156 ! project the left side to the right
1157 temp_neighbor_domain = neighbor_domain_y%beg - (glb_bounds(2)%end - glb_bounds(2)%beg)
1158 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(2) .and. location(2) &
1159 & < neighbor_domain_y%end)
1160
1161 owns_collision = owns_collision .and. periodic_owner
1162 else
1163 owns_collision = owns_collision .and. neighbor_domain_y%beg <= location(2) .and. location(2) &
1164 & < neighbor_domain_y%end
1165 end if
1166 end if
1167# 404 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1168 if (num_dims >= 3) then
1169 if (ib_bc_z%beg == bc_periodic .and. neighbor_domain_z%beg >= neighbor_domain_z%end) then
1170 ! project right side to the left
1171 temp_neighbor_domain = neighbor_domain_z%end + (glb_bounds(3)%end - glb_bounds(3)%beg)
1172 periodic_owner = neighbor_domain_z%beg <= location(3) .and. location(3) < temp_neighbor_domain
1173 ! project the left side to the right
1174 temp_neighbor_domain = neighbor_domain_z%beg - (glb_bounds(3)%end - glb_bounds(3)%beg)
1175 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(3) .and. location(3) &
1176 & < neighbor_domain_z%end)
1177
1178 owns_collision = owns_collision .and. periodic_owner
1179 else
1180 owns_collision = owns_collision .and. neighbor_domain_z%beg <= location(3) .and. location(3) &
1181 & < neighbor_domain_z%end
1182 end if
1183 end if
1184# 421 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1185 end if
1186#endif
1187
1189
1191
1192#ifdef MFC_DEBUG
1193# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1194 block
1195# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1196 use iso_fortran_env, only: output_unit
1197# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1198
1199# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1200 print *, 'm_collisions.fpp:428: ', '@:DEALLOCATE(collision_lookup)'
1201# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1202
1203# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1204 call flush (output_unit)
1205# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1206 end block
1207# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1208#endif
1209# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1210
1211# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1212#if defined(MFC_OpenACC)
1213# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1214!$acc exit data delete(collision_lookup)
1215# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1216#elif defined(MFC_OpenMP)
1217# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1218!$omp target exit data map(release:collision_lookup)
1219# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1220#endif
1221# 428 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1222 deallocate (collision_lookup)
1223#ifdef MFC_DEBUG
1224# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1225 block
1226# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1227 use iso_fortran_env, only: output_unit
1228# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1229
1230# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1231 print *, 'm_collisions.fpp:429: ', '@:DEALLOCATE(wall_overlap_distances)'
1232# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1233
1234# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1235 call flush (output_unit)
1236# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1237 end block
1238# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1239#endif
1240# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1241
1242# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1243#if defined(MFC_OpenACC)
1244# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1245!$acc exit data delete(wall_overlap_distances)
1246# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1247#elif defined(MFC_OpenMP)
1248# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1249!$omp target exit data map(release:wall_overlap_distances)
1250# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1251#endif
1252# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1253 deallocate (wall_overlap_distances)
1254
1255 end subroutine s_finalize_collisions_module
1256
1257end module m_collisions
Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients,...
real(wp) damping_parameter
real(wp), dimension(:,:), allocatable wall_overlap_distances
logical, public collisions_active
true when any IB-IB or IB-wall contact was detected on this rank since the last adaptive-dt computati...
subroutine, public s_finalize_collisions_module()
logical function, public f_neighborhood_ranks_own_location(location)
function checks if this local MPI processor owns this specific collision
subroutine s_detect_ib_collisions(gps, ib_markers, num_gps, num_considered_collisions)
uses ghost-point/image-point information to determine if it is possible if two IBs are colliding,...
subroutine s_detect_wall_collisions(any_wall_collision)
uses boundary conditions and particle locations to check for wall conditions
subroutine, public s_initialize_collisions_module()
subroutine s_apply_ib_collision_forces_soft_sphere(num_considered_collisions, forces, torques)
applies collision forces to IBs assuming a soft-sphere collision model (all IBs are circles or sphere...
real(wp) spring_stiffness
subroutine, public s_apply_collision_forces(ghost_points, num_gps, ib_markers, forces, torques)
integer, dimension(:), allocatable, public ib_gbl_idx_lookup
integer, dimension(:,:), allocatable collision_lookup
subroutine s_apply_wall_collision_forces_soft_sphere(forces, torques)
applies collision forces to IBs assuming a soft-sphere collision model (all IBs are circles or sphere...
Computes signed-distance level-set fields and surface normals for immersed-boundary patch geometries.
Compile-time constant parameters: default values, tolerances, and physical constants.
integer, parameter num_local_ibs_max
Maximum number of immersed boundary patches (legacy, not used for patch_ib sizing) Fixed capacity of ...
real(wp), parameter pi
Pi.
Shared derived types for field data, patch geometry, bubble dynamics, and MPI I/O structures.
Global parameters for the computational domain, fluid properties, and simulation algorithm configurat...
Basic floating-point utilities: approximate equality, default detection, and coordinate bounds.
Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions...
Allocate memory and read initial condition data for IC extrusion.
Binary STL file reader and processor for immersed boundary geometry.
MPI halo exchange, domain decomposition, and buffer packing/unpacking for the simulation solver.