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# 167 "/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# 167 "/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# 167 "/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.
299# 55 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
300
301! Allocate and create GPU device memory
302# 75 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
303
304! Free GPU device memory and deallocate
305# 83 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
306
307! Cray-specific GPU pointer setup for vector fields
308# 107 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
309
310! Cray-specific GPU pointer setup for scalar fields
311# 123 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
312
313! Cray-specific GPU pointer setup for acoustic source spatials
314# 148 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
315
316# 154 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
317
318# 161 "/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, tangential_vector, normal_force, tangential_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) private(i, l, encoded_pid1, encoded_pid2, xp1, xp2, yp1, yp2, zp1, zp2, pid1, pid2, centroid_1, centroid_2, normal_vector, overlap_distance, &
542# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
543!$acc& effective_mass, k, eta, normal_velocity, tangential_vector, normal_force, tangential_force, torque, radial_vector, rotation_velocity, vel1, vel2) copy(forces, torques)
544# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
545#elif defined(MFC_OpenMP)
546# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
547
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!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) private(i, l, encoded_pid1, &
554# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
555!$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, &
556# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
557!$omp& tangential_force, torque, radial_vector, rotation_velocity, vel1, vel2) map(tofrom:forces, torques)
558# 96 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
559#endif
560# 100 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
561 do i = 1, num_considered_collisions
562 encoded_pid1 = collision_lookup(i, 3)
563 encoded_pid2 = collision_lookup(i, 4)
564 call s_decode_patch_periodicity(encoded_pid1, pid1, xp1, yp1, zp1)
565 call s_decode_patch_periodicity(encoded_pid2, pid2, xp2, yp2, zp2)
566 pid1 = collision_lookup(i, 1)
567 pid2 = collision_lookup(i, 2)
568
569 ! call s_get_neighborhood_idx(pid1, pid1) ! global patch ID -> local index call s_get_neighborhood_idx(pid2, pid2)
570 if (pid1 <= 0 .or. pid2 <= 0) cycle
571
572 centroid_1(1) = patch_ib(pid1)%x_centroid + real(xp1, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg)
573 centroid_1(2) = patch_ib(pid1)%y_centroid + real(yp1, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg)
574 centroid_1(3) = 0._wp
575 centroid_2(1) = patch_ib(pid2)%x_centroid + real(xp2, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg)
576 centroid_2(2) = patch_ib(pid2)%y_centroid + real(yp2, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg)
577 centroid_2(3) = 0._wp
578 if (num_dims == 3) then
579 centroid_1(3) = patch_ib(pid1)%z_centroid + real(zp1, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg)
580 centroid_2(3) = patch_ib(pid2)%z_centroid + real(zp2, wp)*(glb_bounds(3)%end - glb_bounds(3)%beg)
581 end if
582
583 normal_vector = centroid_2 - centroid_1
584 overlap_distance = patch_ib(pid1)%radius + patch_ib(pid2)%radius - norm2(normal_vector)
585 if (overlap_distance > 0._wp) then ! if the two patches are close enough to collide
586 normal_vector = normal_vector/norm2(normal_vector)
587 if (f_local_rank_owns_location(centroid_1)) then
588 ! compute constants of the collision
589 effective_mass = 1.0_wp/((1.0_wp/patch_ib(pid1)%mass) + (1._wp/(patch_ib(pid2)%mass)))
590 k = spring_stiffness*effective_mass
591 eta = damping_parameter*effective_mass
592
593 ! Get the vectors and velcoities
594 radial_vector = normal_vector*(patch_ib(pid1)%radius - 0.5_wp*overlap_distance)
595 call s_cross_product(patch_ib(pid1)%angular_vel, radial_vector, rotation_velocity)
596 vel1 = patch_ib(pid1)%vel + rotation_velocity
597 radial_vector = normal_vector*(-1.0_wp)*(patch_ib(pid2)%radius - 0.5_wp*overlap_distance)
598 call s_cross_product(patch_ib(pid2)%angular_vel, radial_vector, rotation_velocity)
599 vel2 = patch_ib(pid2)%vel + rotation_velocity
600
601 normal_velocity = dot_product(vel1 - vel2, normal_vector)*normal_vector
602 tangential_vector = (vel1 - vel2) - normal_velocity
603 if (.not. f_approx_equal(norm2(tangential_vector), &
604 & 0._wp)) tangential_vector = tangential_vector/norm2(tangential_vector)
605
606 ! compute force and torque
607 normal_force = -k*overlap_distance*normal_vector - eta*normal_velocity
608 tangential_force = -ib_coefficient_of_friction*norm2(normal_force)*tangential_vector
609 call s_cross_product(normal_vector*patch_ib(pid1)%radius, tangential_force, torque)
610
611 do l = 1, num_dims
612 ! update the first IB
613
614# 152 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
615#if defined(MFC_OpenACC)
616# 152 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
617!$acc atomic update
618# 152 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
619#elif defined(MFC_OpenMP)
620# 152 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
621!$omp atomic update
622# 152 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
623#endif
624 forces(pid1, l) = forces(pid1, l) + (normal_force(l) + tangential_force(l))
625
626# 154 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
627#if defined(MFC_OpenACC)
628# 154 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
629!$acc atomic update
630# 154 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
631#elif defined(MFC_OpenMP)
632# 154 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
633!$omp atomic update
634# 154 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
635#endif
636 torques(pid1, l) = torques(pid1, l) + torque(l)
637
638 ! apply equal and opposite force/torque to second IB
639
640# 158 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
641#if defined(MFC_OpenACC)
642# 158 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
643!$acc atomic update
644# 158 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
645#elif defined(MFC_OpenMP)
646# 158 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
647!$omp atomic update
648# 158 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
649#endif
650 forces(pid2, l) = forces(pid2, l) - (normal_force(l) + tangential_force(l))
651
652# 160 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
653#if defined(MFC_OpenACC)
654# 160 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
655!$acc atomic update
656# 160 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
657#elif defined(MFC_OpenMP)
658# 160 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
659!$omp atomic update
660# 160 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
661#endif
662 torques(pid2, l) = torques(pid2, l) + torque(l)*patch_ib(pid2)%radius/patch_ib(pid1)%radius
663 end do
664 end if
665 end if
666 end do
667
668# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
669#if defined(MFC_OpenACC)
670# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
671!$acc end parallel loop
672# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
673#elif defined(MFC_OpenMP)
674# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
675
676# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
677!$omp end target teams loop
678# 166 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
679#endif
680
682
683 !> @brief applies collision forces to IBs assuming a soft-sphere collision model (all IBs are circles or spheres)
685
686 real(wp), dimension(num_ibs, 3), intent(inout) :: forces, torques
687 integer :: patch_id, i, l
688 real(wp), dimension(3) :: normal_force, tangential_force, normal_vector, normal_velocity, tangential_vector, &
689 & collision_location, torque, radial_vector, rotation_velocity, velocity
690 real(wp) :: k, eta ! the spring stiffness and damping coefficient for a specific IB
691
692
693# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
694
695# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
696#if defined(MFC_OpenACC)
697# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
698!$acc parallel loop collapse(2) gang vector default(present) &
699# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
700!$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) &
701# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
702!$acc& copy(forces, torques)
703# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
704#elif defined(MFC_OpenMP)
705# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
706
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!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) collapse(2) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
713# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
714!$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) &
715# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
716!$omp& map(tofrom:forces, torques)
717# 179 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
718#endif
719# 182 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
720 do patch_id = 1, num_ibs
721 do i = 1, num_dims*2
722 ! only compute force contributions if there was an overlap
723 if (f_approx_equal(wall_overlap_distances(patch_id, i), 0._wp)) cycle
724
725 select case (i)
726 case (1) ! x domain left
727 normal_vector = [-1._wp, 0._wp, 0._wp]
728 case (2) ! x domain right
729 normal_vector = [1._wp, 0._wp, 0._wp]
730 case (3) ! y domain bottom
731 normal_vector = [0._wp, -1._wp, 0._wp]
732 case (4) ! y domain top
733 normal_vector = [0._wp, 1._wp, 0._wp]
734 case (5) ! z domain back
735 normal_vector = [0._wp, 0._wp, -1._wp]
736 case (6) ! z domain front
737 normal_vector = [0._wp, 0._wp, 1._wp]
738 end select
739
740 ! ensure the local rank owns that collision before proceeding
741 collision_location = [patch_ib(patch_id)%x_centroid, patch_ib(patch_id)%y_centroid, 0._wp]
742 if (num_dims == 3) collision_location(3) = patch_ib(patch_id)%z_centroid
743 if (f_local_rank_owns_location(collision_location)) then
744 k = spring_stiffness*patch_ib(patch_id)%mass
745 eta = damping_parameter*patch_ib(patch_id)%mass
746
747 ! get the vector that points from the centroid to the point of collision
748 radial_vector = normal_vector*(patch_ib(patch_id)%radius - wall_overlap_distances(patch_id, i))
749 ! convert the angular velocity to linear velocity
750 call s_cross_product(patch_ib(patch_id)%angular_vel, radial_vector, rotation_velocity)
751 velocity = patch_ib(patch_id)%vel + rotation_velocity
752
753 ! standard soft-sphere collision with the wall
754 normal_velocity = dot_product(velocity, normal_vector)*normal_vector
755 tangential_vector = velocity - normal_velocity
756 if (.not. f_approx_equal(norm2(tangential_vector), &
757 & 0._wp)) tangential_vector = tangential_vector/norm2(tangential_vector)
758 normal_force = -k*wall_overlap_distances(patch_id, i)*normal_vector - eta*normal_velocity
759 tangential_force = -ib_coefficient_of_friction*norm2(normal_force)*tangential_vector
760 call s_cross_product(normal_vector*patch_ib(patch_id)%radius, tangential_force, torque)
761
762 do l = 1, num_dims
763
764# 225 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
765#if defined(MFC_OpenACC)
766# 225 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
767!$acc atomic update
768# 225 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
769#elif defined(MFC_OpenMP)
770# 225 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
771!$omp atomic update
772# 225 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
773#endif
774 forces(patch_id, l) = forces(patch_id, l) + (normal_force(l) + tangential_force(l))
775
776# 227 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
777#if defined(MFC_OpenACC)
778# 227 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
779!$acc atomic update
780# 227 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
781#elif defined(MFC_OpenMP)
782# 227 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
783!$omp atomic update
784# 227 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
785#endif
786 torques(patch_id, l) = torques(patch_id, l) + torque(l)
787 end do
788 end if
789 end do
790 end do
791
792# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
793#if defined(MFC_OpenACC)
794# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
795!$acc end parallel loop
796# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
797#elif defined(MFC_OpenMP)
798# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
799
800# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
801!$omp end target teams loop
802# 233 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
803#endif
804
806
807 !> uses ghost-point/image-point information to determine if it is possible if two IBs are colliding, effectively an optimized
808 !! nearest neighbor search
809 subroutine s_detect_ib_collisions(gps, ib_markers, num_gps, num_considered_collisions)
810
811 type(ghost_point), dimension(num_gps), intent(in) :: gps
812 type(integer_field), intent(in) :: ib_markers
813 integer, intent(in) :: num_gps
814 integer, intent(out) :: num_considered_collisions
815 integer :: i, j, k, z_bound, ii, jj, kk
816 integer, dimension(2) :: decoded_pairs
817 integer :: gp_idx, gp_patch_id, neighbor_patch_id
818 integer :: pair_idx, out_idx
819 logical :: already_found
820
821 ! Temporary array to hold all detected pairs (with potential duplicates)
822 integer, dimension(num_gps, 2) :: raw_pairs
823 integer :: num_raw, local_num_raw
824
825 num_raw = 0
826 z_bound = 0; if (num_dims == 3) z_bound = 1
827
828
829# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
830
831# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
832#if defined(MFC_OpenACC)
833# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
834!$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)
835# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
836#elif defined(MFC_OpenMP)
837# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
838
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!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
845# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
846!$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)
847# 258 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
848#endif
849# 260 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
850 do gp_idx = 1, num_gps
851 i = gps(gp_idx)%loc(1)
852 j = gps(gp_idx)%loc(2)
853 k = 0; if (num_dims == 3) k = gps(gp_idx)%loc(3)
854 gp_patch_id = ib_markers%sf(i, j, k)
855
856 ! search in a cube around the BG for Ib markers belonging to another patch
857 neighbor_search: do ii = i - 1, i + 1
858 do jj = j - 1, j + 1
859 do kk = k - z_bound, k + z_bound
860 neighbor_patch_id = ib_markers%sf(ii, jj, kk)
861
862 ! If any neighbors are of a different/higher marker value, we consider it for possible collision
863 if (gp_patch_id < neighbor_patch_id) then
864
865# 274 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
866#if defined(MFC_OpenACC)
867# 274 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
868!$acc atomic capture
869# 274 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
870#elif defined(MFC_OpenMP)
871# 274 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
872!$omp atomic capture
873# 274 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
874#endif
875 num_raw = num_raw + 1
876 local_num_raw = num_raw
877#if defined(MFC_OpenACC)
878# 277 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
879!$acc end atomic
880# 277 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
881#elif defined(MFC_OpenMP)
882# 277 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
883!$omp end atomic
884# 277 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
885#endif
886
887 ! Store with smaller ID first for consistent ordering
888 raw_pairs(local_num_raw, 1) = gp_patch_id
889 raw_pairs(local_num_raw, 2) = neighbor_patch_id
890 exit neighbor_search
891 end if
892 end do
893 end do
894 end do neighbor_search
895 end do
896
897# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
898#if defined(MFC_OpenACC)
899# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
900!$acc end parallel loop
901# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
902#elif defined(MFC_OpenMP)
903# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
904
905# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
906!$omp end target teams loop
907# 288 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
908#endif
909
910 ! Coalesce collisions unique pairs
911 num_considered_collisions = 0
913 ! for each pair found in the raw collection
914 do pair_idx = 1, num_raw
915 already_found = .false.
916
917 ! get the decoded pairs for checking if they exist, using ii,jj,kk as dummy indices
918 call s_decode_patch_periodicity(raw_pairs(pair_idx, 1), decoded_pairs(1), ii, jj, kk)
919 call s_decode_patch_periodicity(raw_pairs(pair_idx, 2), decoded_pairs(2), ii, jj, kk)
920 decoded_pairs(1) = ib_gbl_idx_lookup(decoded_pairs(1))
921 decoded_pairs(2) = ib_gbl_idx_lookup(decoded_pairs(2))
922
923 ! skip self-collisions (an IB cannot collide with its own periodic image)
924 if (decoded_pairs(1) == decoded_pairs(2)) cycle
925
926 ! need to swap to guarantee the smaller decoded marker value is in index 1 and prevent double-counting
927 if (decoded_pairs(2) < decoded_pairs(1)) then
928 decoded_pairs(1) = decoded_pairs(1) + decoded_pairs(2)
929 decoded_pairs(2) = decoded_pairs(1) - decoded_pairs(2)
930 decoded_pairs(1) = decoded_pairs(1) - decoded_pairs(2)
931 raw_pairs(pair_idx, 1) = raw_pairs(pair_idx, 1) + raw_pairs(pair_idx, 2)
932 raw_pairs(pair_idx, 2) = raw_pairs(pair_idx, 1) - raw_pairs(pair_idx, 2)
933 raw_pairs(pair_idx, 1) = raw_pairs(pair_idx, 1) - raw_pairs(pair_idx, 2)
934 end if
935
936 ! check if it is already in the list
937 do out_idx = 1, num_considered_collisions
938 if (collision_lookup(out_idx, 1) == decoded_pairs(1) .and. collision_lookup(out_idx, 2) == decoded_pairs(2)) then
939 already_found = .true.
940 exit
941 end if
942 end do
943
944 ! and if it is not, append it to the list of pairs
945 if (.not. already_found) then
946 num_considered_collisions = num_considered_collisions + 1
947 collision_lookup(num_considered_collisions, 1) = decoded_pairs(1)
948 collision_lookup(num_considered_collisions, 2) = decoded_pairs(2)
949 collision_lookup(num_considered_collisions, 3) = raw_pairs(pair_idx, 1)
950 collision_lookup(num_considered_collisions, 4) = raw_pairs(pair_idx, 2)
951 end if
952 end do
953
954# 333 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
955#if defined(MFC_OpenACC)
956# 333 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
957!$acc update device(collision_lookup)
958# 333 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
959#elif defined(MFC_OpenMP)
960# 333 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
961!$omp target update to(collision_lookup)
962# 333 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
963#endif
964
965 end subroutine s_detect_ib_collisions
966
967 subroutine s_detect_ib_collisions_n2(num_considered_collisions)
968
969 integer, intent(out) :: num_considered_collisions
970 integer :: pid1, pid2, encoded_pid2, current_collisions
971 integer :: xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper, xp, yp, zp
972 real(wp), dimension(3) :: centroid_1, centroid_2, distance_vec
973
974 num_considered_collisions = 0
975
976 call s_get_periodicities(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper)
977
978
979# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
980
981# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
982#if defined(MFC_OpenACC)
983# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
984!$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) &
985# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
986!$acc& copyin(xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper)
987# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
988#elif defined(MFC_OpenMP)
989# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
990
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!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
997# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
998!$omp& private(pid1, pid2, encoded_pid2, centroid_1, centroid_2, xp, yp, zp, distance_vec, current_collisions) map(tofrom:num_considered_collisions) &
999# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1000!$omp& map(to:xp_lower, xp_upper, yp_lower, yp_upper, zp_lower, zp_upper)
1001# 348 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1002#endif
1003# 350 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1004 do pid1 = 1, num_ibs - 1
1005 centroid_1 = [patch_ib(pid1)%x_centroid, patch_ib(pid1)%y_centroid, 0._wp]
1006 if (num_dims == 3) centroid_1(3) = patch_ib(pid1)%z_centroid
1007 do pid2 = pid1 + 1, num_ibs
1008 periodic_search: do xp = xp_lower, xp_upper
1009 do yp = yp_lower, yp_upper
1010 do zp = zp_lower, zp_upper
1011 centroid_2(1) = patch_ib(pid2)%x_centroid + real(xp, wp)*(glb_bounds(1)%end - glb_bounds(1)%beg)
1012 centroid_2(2) = patch_ib(pid2)%y_centroid + real(yp, wp)*(glb_bounds(2)%end - glb_bounds(2)%beg)
1013 if (num_dims == 3) centroid_2(3) = patch_ib(pid2)%z_centroid + real(zp, &
1014 & wp)*(glb_bounds(3)%end - glb_bounds(3)%beg)
1015 distance_vec = centroid_2 - centroid_1
1016
1017 if (norm2(distance_vec) < patch_ib(pid1)%radius + patch_ib(pid2)%radius) then
1018
1019# 364 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1020#if defined(MFC_OpenACC)
1021# 364 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1022!$acc atomic capture
1023# 364 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1024#elif defined(MFC_OpenMP)
1025# 364 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1026!$omp atomic capture
1027# 364 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1028#endif
1029 num_considered_collisions = num_considered_collisions + 1
1030 current_collisions = num_considered_collisions
1031#if defined(MFC_OpenACC)
1032# 367 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1033!$acc end atomic
1034# 367 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1035#elif defined(MFC_OpenMP)
1036# 367 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1037!$omp end atomic
1038# 367 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1039#endif
1040
1041 call s_encode_patch_periodicity(patch_ib(pid2)%gbl_patch_id, xp, yp, zp, encoded_pid2)
1042
1043 collision_lookup(current_collisions, 1) = pid1
1044 collision_lookup(current_collisions, 2) = pid2
1045 collision_lookup(current_collisions, 3) = patch_ib(pid1)%gbl_patch_id
1046 collision_lookup(current_collisions, 4) = encoded_pid2
1047 exit periodic_search
1048 end if
1049 end do
1050 end do
1051 end do periodic_search
1052 end do
1053 end do
1054
1055# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1056#if defined(MFC_OpenACC)
1057# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1058!$acc end parallel loop
1059# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1060#elif defined(MFC_OpenMP)
1061# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1062
1063# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1064!$omp end target teams loop
1065# 382 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1066#endif
1067
1068 end subroutine s_detect_ib_collisions_n2
1069
1070 !> @brief uses boundary conditions and particle locations to check for wall conditions
1072
1073 integer :: gp_idx, i, j, k, patch_id
1074 real(wp) :: edge_location, overlap_distance
1075
1076 ! iterate over all ghost points to detect the one that is most-overlapping in each direction
1077
1078
1079# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1080
1081# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1082#if defined(MFC_OpenACC)
1083# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1084!$acc parallel loop gang vector default(present) private(patch_id, edge_location, overlap_distance)
1085# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1086#elif defined(MFC_OpenMP)
1087# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1088
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!$omp target teams loop defaultmap(firstprivate:scalar) bind(teams,parallel) defaultmap(tofrom:aggregate) defaultmap(tofrom:allocatable) defaultmap(tofrom:pointer) &
1095# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1096!$omp& private(patch_id, edge_location, overlap_distance)
1097# 394 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1098#endif
1099 do patch_id = 1, num_ibs
1100# 397 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1101 ! check if the boundaries are either of the two conditions we should compute collisions with
1102 if (ib_bc_x%beg == bc_slip_wall .or. ib_bc_x%beg == bc_no_slip_wall) then
1103 ! get the location of the true IB surface towards the domain boundary
1104 edge_location = patch_ib(patch_id)%x_centroid - patch_ib(patch_id)%radius
1105 ! check if that edge actually extends out of the comutational domain
1106 if (edge_location < glb_bounds(1)%beg) then
1107 ! the distance that the IB extends out of the domain
1108 overlap_distance = glb_bounds(1)%beg - edge_location
1109 else
1110 overlap_distance = 0._wp
1111 end if
1112 wall_overlap_distances(patch_id, 1) = overlap_distance
1113 end if
1114
1115 if (ib_bc_x%end == bc_slip_wall .or. ib_bc_x%end == bc_no_slip_wall) then
1116 edge_location = patch_ib(patch_id)%x_centroid + patch_ib(patch_id)%radius
1117 if (edge_location > glb_bounds(1)%end) then
1118 overlap_distance = edge_location - glb_bounds(1)%end
1119 else
1120 overlap_distance = 0._wp
1121 end if
1122 wall_overlap_distances(patch_id, 1 + 1) = overlap_distance
1123 end if
1124# 397 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1125 ! check if the boundaries are either of the two conditions we should compute collisions with
1126 if (ib_bc_y%beg == bc_slip_wall .or. ib_bc_y%beg == bc_no_slip_wall) then
1127 ! get the location of the true IB surface towards the domain boundary
1128 edge_location = patch_ib(patch_id)%y_centroid - patch_ib(patch_id)%radius
1129 ! check if that edge actually extends out of the comutational domain
1130 if (edge_location < glb_bounds(2)%beg) then
1131 ! the distance that the IB extends out of the domain
1132 overlap_distance = glb_bounds(2)%beg - edge_location
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 > glb_bounds(2)%end) then
1142 overlap_distance = edge_location - glb_bounds(2)%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 < glb_bounds(3)%beg) then
1155 ! the distance that the IB extends out of the domain
1156 overlap_distance = glb_bounds(3)%beg - edge_location
1157 else
1158 overlap_distance = 0._wp
1159 end if
1160 wall_overlap_distances(patch_id, 5) = overlap_distance
1161 end if
1162
1163 if (ib_bc_z%end == bc_slip_wall .or. ib_bc_z%end == bc_no_slip_wall) then
1164 edge_location = patch_ib(patch_id)%z_centroid + patch_ib(patch_id)%radius
1165 if (edge_location > glb_bounds(3)%end) then
1166 overlap_distance = edge_location - glb_bounds(3)%end
1167 else
1168 overlap_distance = 0._wp
1169 end if
1170 wall_overlap_distances(patch_id, 5 + 1) = overlap_distance
1171 end if
1172# 421 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1173 end do
1174
1175# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1176#if defined(MFC_OpenACC)
1177# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1178!$acc end parallel loop
1179# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1180#elif defined(MFC_OpenMP)
1181# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1182
1183# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1184!$omp end target teams loop
1185# 422 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1186#endif
1187
1188 end subroutine s_detect_wall_collisions
1189
1190 !> @brief function checks if this local MPI processor owns this specific collision
1191 function f_local_rank_owns_location(location) result(owns_collision)
1192
1193
1194# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1195#if MFC_OpenACC
1196# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1197!$acc routine seq
1198# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1199#elif MFC_OpenMP
1200# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1201
1202# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1203
1204# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1205!$omp declare target device_type(any)
1206# 429 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1207#endif
1208
1209 real(wp), dimension(3), intent(in) :: location
1210 logical :: owns_collision
1211 real(wp), dimension(3) :: projected_location
1212
1213 owns_collision = .true.
1214
1215#ifdef MFC_MPI
1216 if (num_procs > 1) then
1217 projected_location(:) = location(:)
1218
1219 ! catch the edge case where th collision lies just outside the computational domain
1220# 443 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1221 if (num_dims >= 1) then
1222 if (ib_bc_x%beg /= bc_periodic) then
1223 ! if it is outside the domain in one direction, project it somewhere inside so at least one rank owns it
1224 if (location(1) < glb_bounds(1)%beg) then
1225 projected_location(1) = glb_bounds(1)%beg
1226 else if (glb_bounds(1)%end < location(1)) then
1227 projected_location(1) = glb_bounds(1)%end - 1.0e-10_wp
1228 end if
1229 end if
1230 owns_collision = owns_collision .and. x_cb(-1) <= projected_location(1) &
1231 & .and. projected_location(1) < x_cb(m)
1232 end if
1233# 443 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1234 if (num_dims >= 2) then
1235 if (ib_bc_y%beg /= bc_periodic) then
1236 ! if it is outside the domain in one direction, project it somewhere inside so at least one rank owns it
1237 if (location(2) < glb_bounds(2)%beg) then
1238 projected_location(2) = glb_bounds(2)%beg
1239 else if (glb_bounds(2)%end < location(2)) then
1240 projected_location(2) = glb_bounds(2)%end - 1.0e-10_wp
1241 end if
1242 end if
1243 owns_collision = owns_collision .and. y_cb(-1) <= projected_location(2) &
1244 & .and. projected_location(2) < y_cb(n)
1245 end if
1246# 443 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1247 if (num_dims >= 3) then
1248 if (ib_bc_z%beg /= bc_periodic) then
1249 ! if it is outside the domain in one direction, project it somewhere inside so at least one rank owns it
1250 if (location(3) < glb_bounds(3)%beg) then
1251 projected_location(3) = glb_bounds(3)%beg
1252 else if (glb_bounds(3)%end < location(3)) then
1253 projected_location(3) = glb_bounds(3)%end - 1.0e-10_wp
1254 end if
1255 end if
1256 owns_collision = owns_collision .and. z_cb(-1) <= projected_location(3) &
1257 & .and. projected_location(3) < z_cb(p)
1258 end if
1259# 456 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1260 end if
1261#endif
1262
1263 end function f_local_rank_owns_location
1264
1265 !> @brief function checks if this local MPI processor owns this specific collision
1266 function f_neighborhood_ranks_own_location(location) result(owns_collision)
1267
1268 real(wp), dimension(3), intent(in) :: location
1269 logical :: owns_collision, periodic_owner
1270 real(wp) :: temp_neighbor_domain
1271 integer :: i
1272
1273 owns_collision = .true.
1274
1275#ifdef MFC_MPI
1276 if (num_procs > 2) then
1277 ! catch the edge case where th collision lies just outside the computational domain
1278 owns_collision = .true.
1279# 476 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1280 if (num_dims >= 1) then
1281 if (ib_bc_x%beg == bc_periodic .and. neighbor_domain_x%beg >= neighbor_domain_x%end) then
1282 ! project right side to the left
1283 temp_neighbor_domain = neighbor_domain_x%end + (glb_bounds(1)%end - glb_bounds(1)%beg)
1284 periodic_owner = neighbor_domain_x%beg <= location(1) .and. location(1) < temp_neighbor_domain
1285 ! project the left side to the right
1286 temp_neighbor_domain = neighbor_domain_x%beg - (glb_bounds(1)%end - glb_bounds(1)%beg)
1287 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(1) .and. location(1) &
1288 & < neighbor_domain_x%end)
1289
1290 owns_collision = owns_collision .and. periodic_owner
1291 else
1292 owns_collision = owns_collision .and. neighbor_domain_x%beg <= location(1) .and. location(1) &
1293 & < neighbor_domain_x%end
1294 end if
1295 end if
1296# 476 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1297 if (num_dims >= 2) then
1298 if (ib_bc_y%beg == bc_periodic .and. neighbor_domain_y%beg >= neighbor_domain_y%end) then
1299 ! project right side to the left
1300 temp_neighbor_domain = neighbor_domain_y%end + (glb_bounds(2)%end - glb_bounds(2)%beg)
1301 periodic_owner = neighbor_domain_y%beg <= location(2) .and. location(2) < temp_neighbor_domain
1302 ! project the left side to the right
1303 temp_neighbor_domain = neighbor_domain_y%beg - (glb_bounds(2)%end - glb_bounds(2)%beg)
1304 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(2) .and. location(2) &
1305 & < neighbor_domain_y%end)
1306
1307 owns_collision = owns_collision .and. periodic_owner
1308 else
1309 owns_collision = owns_collision .and. neighbor_domain_y%beg <= location(2) .and. location(2) &
1310 & < neighbor_domain_y%end
1311 end if
1312 end if
1313# 476 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1314 if (num_dims >= 3) then
1315 if (ib_bc_z%beg == bc_periodic .and. neighbor_domain_z%beg >= neighbor_domain_z%end) then
1316 ! project right side to the left
1317 temp_neighbor_domain = neighbor_domain_z%end + (glb_bounds(3)%end - glb_bounds(3)%beg)
1318 periodic_owner = neighbor_domain_z%beg <= location(3) .and. location(3) < temp_neighbor_domain
1319 ! project the left side to the right
1320 temp_neighbor_domain = neighbor_domain_z%beg - (glb_bounds(3)%end - glb_bounds(3)%beg)
1321 periodic_owner = periodic_owner .or. (temp_neighbor_domain <= location(3) .and. location(3) &
1322 & < neighbor_domain_z%end)
1323
1324 owns_collision = owns_collision .and. periodic_owner
1325 else
1326 owns_collision = owns_collision .and. neighbor_domain_z%beg <= location(3) .and. location(3) &
1327 & < neighbor_domain_z%end
1328 end if
1329 end if
1330# 493 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1331 end if
1332#endif
1333
1335
1337
1338#ifdef MFC_DEBUG
1339# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1340 block
1341# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1342 use iso_fortran_env, only: output_unit
1343# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1344
1345# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1346 print *, 'm_collisions.fpp:500: ', '@:DEALLOCATE(collision_lookup)'
1347# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1348
1349# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1350 call flush (output_unit)
1351# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1352 end block
1353# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1354#endif
1355# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1356
1357# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1358#if defined(MFC_OpenACC)
1359# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1360!$acc exit data delete(collision_lookup)
1361# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1362#elif defined(MFC_OpenMP)
1363# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1364!$omp target exit data map(release:collision_lookup)
1365# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1366#endif
1367# 500 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1368 deallocate (collision_lookup)
1369#ifdef MFC_DEBUG
1370# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1371 block
1372# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1373 use iso_fortran_env, only: output_unit
1374# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1375
1376# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1377 print *, 'm_collisions.fpp:501: ', '@:DEALLOCATE(wall_overlap_distances)'
1378# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1379
1380# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1381 call flush (output_unit)
1382# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1383 end block
1384# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1385#endif
1386# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1387
1388# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1389#if defined(MFC_OpenACC)
1390# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1391!$acc exit data delete(wall_overlap_distances)
1392# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1393#elif defined(MFC_OpenMP)
1394# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1395!$omp target exit data map(release:wall_overlap_distances)
1396# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1397#endif
1398# 501 "/home/runner/work/MFC/MFC/src/simulation/m_collisions.fpp"
1399 deallocate (wall_overlap_distances)
1400
1401 end subroutine s_finalize_collisions_module
1402
1403end 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.