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