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