1# 1 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
8# 1 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 1
9# 1 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 1
10# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
11# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
12# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
13# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
14# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
15# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
17# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
18# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
19# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
21# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
22# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
25# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
26# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
27# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
29# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
30# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
32# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
34# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
36# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
38# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
40# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
42# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
44# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
46# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
48# 2 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
49# 1 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 1
50# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
51# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
52# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
53# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
54# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
55# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
57# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
58# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
59# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
61# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
62# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
65# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
66# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
67# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
69# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
70# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
72# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
74# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
76# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
78# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
80# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
82# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
84# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
86# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
88# 2 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 2
90# 4 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
91# 5 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
92# 6 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
93# 7 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
94# 8 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
96# 20 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
98# 43 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
100# 48 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
102# 53 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
104# 58 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
106# 63 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
108# 68 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
110# 81 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
112# 95 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
114# 100 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
116# 105 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
118# 110 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
120# 115 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
122# 120 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
124# 125 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
126# 130 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
128# 135 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
130# 165 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
132# 219 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
134# 233 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
136# 258 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
138# 269 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
140# 271 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
141# 282 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
143# 332 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
145# 342 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
147# 352 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
149# 361 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
151# 378 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
153# 388 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
155# 395 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
157# 401 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
159# 407 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
161# 413 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
163# 419 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
165# 425 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
167# 3 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
168# 1 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 1
169# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
170# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
171# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
172# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
173# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
174# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
176# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
177# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
178# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
180# 12 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
181# 1 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp" 1
184# 4 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
185# 5 "/home/runner/work/MFC/MFC/src/common/include/defaults/thermochem.fpp"
186# 13 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 2
188# 16 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
189# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
191# 24 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
193# 53 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
195# 65 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
197# 75 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
199# 105 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
201# 117 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
203# 127 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
205# 174 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
207# 2 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 2
209# 7 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
211# 17 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
213# 22 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
215# 27 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
217# 32 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
219# 37 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
221# 42 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
223# 47 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
225# 52 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
227# 57 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
229# 62 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
231# 73 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
233# 78 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
235# 83 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
237# 88 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
239# 103 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
241# 131 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
243# 160 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
245# 175 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
247# 193 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
249# 215 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
251# 244 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
253# 259 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
255# 269 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
257# 278 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
259# 294 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
261# 304 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
263# 311 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
265# 4 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
268# 23 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
271# 43 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
274# 55 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
277# 112 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
280# 130 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
283# 145 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
286# 164 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
289# 193 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
292# 207 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
295# 219 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
298# 231 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
301# 242 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
304# 254 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
307# 266 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
310# 275 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
313# 282 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
316# 289 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
319# 296 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
322# 303 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
324# 305 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
325# 306 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
327# 2 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 2
329# 14 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
334# 52 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
337# 72 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
340# 80 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
343# 104 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
346# 120 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
349# 145 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
351# 151 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
353# 158 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
355# 8 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp" 2
384 type(bounds_info),
dimension(3),
intent(in) :: glb_bounds
385 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: particle_cloud_ibs
386 integer,
intent(out) :: num_particle_cloud_ibs
387 type(ib_patch_parameters),
allocatable :: cloud_ibs(:)
388 integer :: cloud_idx, glbl_idx, num_cloud_ibs, n_total_particles
389 real(wp) :: t_start, t_end
391 if (num_particle_clouds == 0)
then
392 allocate (particle_cloud_ibs(0))
393 num_particle_cloud_ibs = 0
397 call cpu_time(t_start)
399 n_total_particles = 0
400 do cloud_idx = 1, num_particle_clouds
401 n_total_particles = n_total_particles + particle_cloud(cloud_idx)%num_particles
405 num_particle_cloud_ibs = 0
408 do cloud_idx = 1, num_particle_clouds
412 select case (particle_cloud(cloud_idx)%packing_method)
418 call s_mpi_abort(
"Particle cloud packing method is not a known packing method of MFC. Exiting.")
422# 73 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
423 call s_prohibit_abort(
"num_particle_cloud_ibs + num_cloud_ibs > num_ib_patches_max_namelist",
"Too many particle-cloud IBs in one rank's neighborhood. Modify case file or increase num_ib_patches_max_namelist.")
424# 73 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
426# 75 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
427 particle_cloud_ibs(num_particle_cloud_ibs + 1:num_particle_cloud_ibs + num_cloud_ibs) = cloud_ibs(1:num_cloud_ibs)
428 num_particle_cloud_ibs = num_particle_cloud_ibs + num_cloud_ibs
429 deallocate (cloud_ibs)
433 if (
proc_rank == 0) print
'(a,i0,a,f0.3,a)',
'Particle beds placed ', glbl_idx - num_ibs,
' particles in ', &
434 & t_end - t_start,
' seconds.'
446 integer,
intent(in) :: cloud_idx
447 integer,
intent(inout) :: glbl_idx
448 type(bounds_info),
dimension(3),
intent(in) :: glb_bounds
449 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: cloud_ibs
450 integer,
intent(out) :: num_cloud_ibs
451 integer :: ib_idx, n_placed, seed, alloc_stat
452 integer(8) :: n_attempts, max_attempts
453 real(wp) :: min_dist, rx, ry, rz
454 logical :: overlaps, reject, periodic_pack
455 real(wp),
allocatable :: placed(:,:)
456 integer :: hash_size, slot
457 integer :: bx, by, bz, nx_bins, ny_bins, nz_bins
458 integer,
allocatable :: hash_head(:), chain_next(:)
459 real(wp) :: xmin, ymin, zmin, length_x, length_y, length_z
461 allocate (cloud_ibs(particle_cloud(cloud_idx)%num_particles), stat=alloc_stat)
462 if (alloc_stat /= 0)
then
463 call s_mpi_abort(
"Error :: Ran out of CPU memory trying to allocate particle cloud IB array. " &
464 & //
"Current system resources cannot perform rejection packing with the specified number of particles.")
468 min_dist = 2._wp*particle_cloud(cloud_idx)%radius + particle_cloud(cloud_idx)%min_spacing
469 periodic_pack = particle_cloud(cloud_idx)%cloud_geometry == 1 .and. particle_cloud(cloud_idx)%periodic == 1
470 length_x = particle_cloud(cloud_idx)%length_x
471 length_y = particle_cloud(cloud_idx)%length_y
472 length_z = particle_cloud(cloud_idx)%length_z
473 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*length_x
474 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*length_y
475 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*length_z
476 nx_bins = max(1, ceiling(length_x/min_dist))
477 ny_bins = max(1, ceiling(length_y/min_dist))
478 nz_bins = max(1, ceiling(length_z/min_dist))
479 if (num_dims < 3) nz_bins = 1
481 max_attempts = int(particle_cloud(cloud_idx)%num_particles, 8)*1000_8
484 seed = particle_cloud(cloud_idx)%seed
485 if (seed == 0) seed = 1 + cloud_idx*1013904223
487 allocate (placed(3, particle_cloud(cloud_idx)%num_particles))
491 hash_size = max(16, 4*particle_cloud(cloud_idx)%num_particles)
492 allocate (hash_head(hash_size))
493 allocate (chain_next(particle_cloud(cloud_idx)%num_particles))
497 do while (n_placed < particle_cloud(cloud_idx)%num_particles .and. n_attempts < max_attempts)
498 n_attempts = n_attempts + 1
504 & xmin, ymin, zmin, length_x, length_y, length_z, nx_bins, ny_bins, nz_bins, &
505 & overlaps, bx, by, bz)
507 if (.not. overlaps)
then
508 n_placed = n_placed + 1
509 placed(1, n_placed) = rx
510 placed(2, n_placed) = ry
511 placed(3, n_placed) = rz
515 chain_next(n_placed) = hash_head(slot)
516 hash_head(slot) = n_placed
518 glbl_idx = glbl_idx + 1
523 if (n_placed < particle_cloud(cloud_idx)%num_particles)
then
524 call s_mpi_abort(
"Error :: Failed to place all particles in particle bed")
527 deallocate (placed, hash_head, chain_next)
530 num_cloud_ibs = ib_idx
542 integer,
intent(in) :: cloud_idx
543 integer,
intent(inout) :: seed
544 real(wp),
intent(out) :: rx, ry, rz
545 logical,
intent(out) :: reject
546 real(wp) :: xmin, xmax, ymin, ymax, zmin, zmax
547 real(wp) :: theta, phi, r_shell, rho, u, zdir, r_inner, r_outer
551 select case (particle_cloud(cloud_idx)%cloud_geometry)
553 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_x
554 xmax = particle_cloud(cloud_idx)%x_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_x
555 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_y
556 ymax = particle_cloud(cloud_idx)%y_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_y
557 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_z
558 zmax = particle_cloud(cloud_idx)%z_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_z
562 if (num_dims < 3)
then
563 rz = particle_cloud(cloud_idx)%z_centroid
568 r_inner = particle_cloud(cloud_idx)%shell_inner_radius + particle_cloud(cloud_idx)%radius
569 r_outer = particle_cloud(cloud_idx)%shell_outer_radius - particle_cloud(cloud_idx)%radius
571 if (num_dims < 3)
then
574 r_shell = sqrt((r_outer**2 - r_inner**2)*u + r_inner**2)
575 rz = particle_cloud(cloud_idx)%z_centroid
576 if (particle_cloud(cloud_idx)%shell_axis == 1)
then
577 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*sin(theta)
578 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*cos(theta)
579 if (rx < particle_cloud(cloud_idx)%x_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
581 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*cos(theta)
582 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*sin(theta)
583 if (ry < particle_cloud(cloud_idx)%y_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
588 rho = sqrt(max(0._wp, 1._wp - zdir**2))
590 r_shell = ((r_outer**3 - r_inner**3)*u + r_inner**3)**(1._wp/3._wp)
591 select case (particle_cloud(cloud_idx)%shell_axis)
593 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*zdir
594 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*rho*cos(phi)
595 rz = particle_cloud(cloud_idx)%z_centroid + r_shell*rho*sin(phi)
596 if (rx < particle_cloud(cloud_idx)%x_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
598 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*zdir
599 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*rho*cos(phi)
600 rz = particle_cloud(cloud_idx)%z_centroid + r_shell*rho*sin(phi)
601 if (ry < particle_cloud(cloud_idx)%y_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
603 rz = particle_cloud(cloud_idx)%z_centroid + r_shell*zdir
604 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*rho*cos(phi)
605 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*rho*sin(phi)
606 if (rz < particle_cloud(cloud_idx)%z_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
610 call s_mpi_abort(
"Particle cloud geometry is not a known cloud geometry of MFC. Exiting.")
623 integer,
intent(in) :: cloud_idx
624 integer,
intent(inout) :: glbl_idx
625 type(bounds_info),
dimension(3),
intent(in) :: glb_bounds
626 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: cloud_ibs
627 integer,
intent(out) :: num_cloud_ibs
628 integer :: ib_idx, n_placed, n_target
629 integer :: row, col, ncx, ncy, ix, jy, kz, b
630 real(wp) :: xmin, xmax, ymin, ymax, zmin, zmax, min_dist
631 real(wp) :: spacing, row_dy, cell, x0, px, py
632 real(wp),
dimension(4) :: bx_off, by_off, bz_off
633 real(wp),
dimension(3) :: centroid
638 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_x
639 xmax = particle_cloud(cloud_idx)%x_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_x
640 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_y
641 ymax = particle_cloud(cloud_idx)%y_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_y
642 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_z
643 zmax = particle_cloud(cloud_idx)%z_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_z
645 min_dist = 2._wp*particle_cloud(cloud_idx)%radius + particle_cloud(cloud_idx)%min_spacing
646 n_target = particle_cloud(cloud_idx)%num_particles
649 if (num_dims < 3)
then
651 spacing = sqrt(2._wp*(xmax - xmin)*(ymax - ymin)/(sqrt(3._wp)*real(n_target, wp)))
654 spacing = (sqrt(2._wp)*(xmax - xmin)*(ymax - ymin)*(zmax - zmin)/real(n_target, wp))**(1._wp/3._wp)
657 if (spacing < min_dist)
then
658 call s_mpi_abort(
"Error :: Particle cloud is too dense for lattice packing; " &
659 & //
"reduce num_particles or min_spacing, or enlarge the cloud region")
662 if (num_dims < 3)
then
664 row_dy = spacing*sqrt(3._wp)/2._wp
666 do while (n_placed < n_target)
667 py = ymin + real(row, wp)*row_dy
669 if (mod(row, 2) == 1) x0 = xmin + 0.5_wp*spacing
672 do while (px <= xmax .and. n_placed < n_target)
673 glbl_idx = glbl_idx + 1
674 centroid = [px, py, particle_cloud(cloud_idx)%z_centroid]
676 call s_add_cloud_particle(cloud_idx, ib_idx, glbl_idx, centroid(1), centroid(2), centroid(3), cloud_ibs)
678 n_placed = n_placed + 1
680 px = x0 + real(col, wp)*spacing
686 cell = spacing*sqrt(2._wp)
687 bx_off = [0._wp, 0.5_wp, 0.5_wp, 0._wp]*cell
688 by_off = [0._wp, 0.5_wp, 0._wp, 0.5_wp]*cell
689 bz_off = [0._wp, 0._wp, 0.5_wp, 0.5_wp]*cell
690 ncx = max(1, ceiling((xmax - xmin)/cell))
691 ncy = max(1, ceiling((ymax - ymin)/cell))
693 do while (n_placed < n_target)
697 if (n_placed >= n_target)
exit
698 centroid = [xmin + real(ix, wp)*cell + bx_off(b), ymin + real(jy, wp)*cell + by_off(b), &
699 & zmin + real(kz, wp)*cell + bz_off(b)]
700 glbl_idx = glbl_idx + 1
705 n_placed = n_placed + 1
713 num_cloud_ibs = ib_idx
722 type(ib_patch_parameters),
intent(inout),
dimension(:) :: cloud_ibs
723 type(bounds_info),
dimension(3),
intent(in) :: glb_bounds
724 integer,
intent(inout) :: num_cloud_ibs
725 integer :: i, write_idx
726 real(wp),
dimension(3) :: centroid
729 do i = 1, num_cloud_ibs
730 centroid = [cloud_ibs(i)%x_centroid, cloud_ibs(i)%y_centroid, 0._wp]
731 if (num_dims == 3) centroid(3) = cloud_ibs(i)%z_centroid
733 write_idx = write_idx + 1
734 if (write_idx /= i) cloud_ibs(write_idx) = cloud_ibs(i)
737 num_cloud_ibs = write_idx
746 integer,
intent(in) :: cloud_idx, glbl_idx
747 integer,
intent(inout) :: ib_idx
748 real(wp),
intent(in) :: px, py, pz
749 type(ib_patch_parameters),
intent(inout),
dimension(:) :: particle_cloud_ibs
752 if (ib_idx >
size(particle_cloud_ibs))
then
753# 400 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
754 call s_prohibit_abort(
"ib_idx > size(particle_cloud_ibs)",
"Too many particle-cloud IBs on one rank. Modify case file or increase num_ib_patches_max_namelist.")
755# 400 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
757# 402 "/home/runner/work/MFC/MFC/src/pre_process/m_particle_cloud.fpp"
759 particle_cloud_ibs(ib_idx)%gbl_patch_id = glbl_idx
760 particle_cloud_ibs(ib_idx)%x_centroid = px
761 particle_cloud_ibs(ib_idx)%y_centroid = py
762 particle_cloud_ibs(ib_idx)%z_centroid = pz
763 particle_cloud_ibs(ib_idx)%vel(:) = 0._wp
764 particle_cloud_ibs(ib_idx)%angular_vel(:) = 0._wp
765 particle_cloud_ibs(ib_idx)%angles(:) = 0._wp
766 particle_cloud_ibs(ib_idx)%radius = particle_cloud(cloud_idx)%radius
771 subroutine s_get_cloud_bin(px, py, pz, min_dist, periodic_pack, xmin, ymin, zmin, nx_bins, ny_bins, nz_bins, bx, by, bz)
773 real(wp),
intent(in) :: px, py, pz, min_dist
774 logical,
intent(in) :: periodic_pack
775 real(wp),
intent(in) :: xmin, ymin, zmin
776 integer,
intent(in) :: nx_bins, ny_bins, nz_bins
777 integer,
intent(out) :: bx, by, bz
779 if (periodic_pack)
then
780 bx = modulo(int(floor((px - xmin)/min_dist)), nx_bins)
781 by = modulo(int(floor((py - ymin)/min_dist)), ny_bins)
782 if (num_dims < 3)
then
785 bz = modulo(int(floor((pz - zmin)/min_dist)), nz_bins)
788 bx = int(floor(px/min_dist))
789 by = int(floor(py/min_dist))
790 if (num_dims < 3)
then
793 bz = int(floor(pz/min_dist))
803 & xmin, ymin, zmin, length_x, length_y, length_z, nx_bins, ny_bins, nz_bins, overlaps, bx, by, bz)
805 real(wp),
intent(in) :: px, py, pz, min_dist
806 real(wp),
intent(in),
dimension(:,:) :: placed
807 integer,
intent(in),
dimension(:) :: hash_head, chain_next
808 integer,
intent(in) :: hash_size
809 logical,
intent(in) :: periodic_pack
810 real(wp),
intent(in) :: xmin, ymin, zmin, length_x, length_y, length_z
811 integer,
intent(in) :: nx_bins, ny_bins, nz_bins
812 logical,
intent(out) :: overlaps
813 integer,
intent(out) :: bx, by, bz
814 integer :: nbx, nby, nbz, slot
815 integer :: dx_b, dy_b, dz_b, dz_lo, dz_hi, j
816 real(wp) :: dist_sq, min_dist_sq, dx, dy, dz
818 call s_get_cloud_bin(px, py, pz, min_dist, periodic_pack, xmin, ymin, zmin, nx_bins, ny_bins, nz_bins, bx, by, bz)
822 if (num_dims < 3)
then
827 min_dist_sq = min_dist**2
832 do dz_b = dz_lo, dz_hi
836 if (periodic_pack)
then
837 nbx = modulo(nbx, nx_bins)
838 nby = modulo(nby, ny_bins)
839 if (num_dims == 3) nbz = modulo(nbz, nz_bins)
844 dx = abs(px - placed(1, j))
845 dy = abs(py - placed(2, j))
846 if (periodic_pack)
then
847 dx = min(dx, length_x - dx)
848 dy = min(dy, length_y - dy)
850 if (num_dims < 3)
then
851 dist_sq = dx**2 + dy**2
853 dz = abs(pz - placed(3, j))
854 if (periodic_pack) dz = min(dz, length_z - dz)
855 dist_sq = dx**2 + dy**2 + dz**2
857 if (dist_sq < min_dist_sq)
then
872 integer,
intent(inout) :: seed
875 seed = ieor(seed, ishft(seed, 13))
876 seed = ieor(seed, ishft(seed, -17))
877 seed = ieor(seed, ishft(seed, 5))
882 rval = real(iand(seed, huge(seed)), wp)/real(huge(seed), wp)
890 integer,
intent(in) :: bx, by, bz, hash_size
894 key = ieor(ieor(int(bx, 8)*73856093_8, int(by, 8)*19349663_8), int(bz, 8)*83492791_8)
895 slot = int(mod(abs(key), int(hash_size, 8))) + 1
Compile-time constant parameters: default values, tolerances, and physical constants.
integer, parameter num_ib_patches_max_namelist
real(wp), parameter pi
Pi.
Defines global parameters for the computational domain, simulation algorithm, and initial conditions.
integer proc_rank
Rank of the local processor Number of cells in the x-, y- and z-coordinate directions.
Utility routines for bubble model setup, coordinate transforms, array sampling, and special functions...
logical function, public f_local_rank_owns_location(location, glb_bounds_in)
True if location falls within this rank's own subdomain (a strict partition - each location is owned ...
MPI communication layer: domain decomposition, halo exchange, reductions, and parallel I/O setup.
impure subroutine s_mpi_abort(prnt, code)
The subroutine terminates the MPI execution environment.
impure subroutine s_prohibit_abort(condition, message)
Print a case file error with the prohibited condition and message, then abort execution.
Generates particle beds by converting particle_cloud patch specifications into individual immersed bo...
subroutine s_particle_cloud_rejection_pack(cloud_idx, glbl_idx, glb_bounds, cloud_ibs, num_cloud_ibs)
Rejection-samples particle centres into a box or hemisphere-shell region with a minimum centre-to-cen...
impure subroutine, public s_generate_particle_clouds(glb_bounds, particle_cloud_ibs, num_particle_cloud_ibs)
Generate all particle beds and fill particle_cloud_ibs, keeping only the particles this rank owns und...
real(wp) function f_xorshift(seed)
Xorshift PRNG. Advances seed in-place and returns a value in [0, 1).
subroutine s_particle_cloud_lattice(cloud_idx, glbl_idx, glb_bounds, cloud_ibs, num_cloud_ibs)
Places particles on the optimally dense lattice for the cloud region: a triangular lattice in 2D,...
subroutine s_check_cloud_particle_overlap(px, py, pz, placed, hash_head, chain_next, hash_size, min_dist, periodic_pack, xmin, ymin, zmin, length_x, length_y, length_z, nx_bins, ny_bins, nz_bins, overlaps, bx, by, bz)
Check whether a candidate particle centre overlaps any already-placed particle in neighbouring spatia...
subroutine s_reduce_particle_cloud_ibs(cloud_ibs, glb_bounds, num_cloud_ibs)
Compacts cloud_ibs(1:num_cloud_ibs) in place, discarding entries this rank does not own (f_local_rank...
subroutine, public s_add_cloud_particle(cloud_idx, ib_idx, glbl_idx, px, py, pz, particle_cloud_ibs)
Writes a single placed particle into particle_cloud_ibs at the next free slot, advancing ib_idx,...
integer function f_bin_hash(bx, by, bz, hash_size)
Hash bin coordinates to a 1-indexed slot in [1, hash_size]. Uses large prime multipliers to spread bi...
subroutine s_get_cloud_bin(px, py, pz, min_dist, periodic_pack, xmin, ymin, zmin, nx_bins, ny_bins, nz_bins, bx, by, bz)
Convert a candidate particle centre to spatial-hash bin coordinates.
subroutine s_sample_cloud_candidate(cloud_idx, seed, rx, ry, rz, reject)
Draws one rejection-sampling candidate centre (rx, ry, rz) for cloud_idx, advancing seed in place....