1# 1 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
7# 1 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 1
8# 1 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 1
9# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
10# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
11# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
12# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
13# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
14# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
16# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
17# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
18# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
20# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
22# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
24# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
26# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
28# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
30# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
32# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
34# 167 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
36# 2 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
37# 1 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 1
38# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
39# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
40# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
41# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
42# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
43# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
45# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
46# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
47# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
49# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
51# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
53# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
55# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
57# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
59# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
61# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
63# 167 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
65# 2 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp" 2
67# 4 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
68# 5 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
69# 6 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
70# 7 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
71# 8 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
73# 20 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
75# 43 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
77# 48 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
79# 53 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
81# 58 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
83# 63 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
85# 68 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
87# 76 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
89# 81 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
91# 86 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
93# 91 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
95# 96 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
97# 101 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
99# 106 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
101# 111 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
103# 116 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
105# 121 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
107# 151 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
109# 192 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
111# 206 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
113# 231 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
115# 242 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
117# 244 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
118# 255 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
120# 284 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
122# 294 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
124# 304 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
126# 313 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
128# 330 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
130# 340 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
132# 347 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
134# 353 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
136# 359 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
138# 365 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
140# 371 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
142# 377 "/home/runner/work/MFC/MFC/src/common/include/omp_macros.fpp"
144# 3 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
145# 1 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 1
146# 1 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp" 1
147# 2 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
148# 3 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
149# 4 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
150# 5 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
151# 6 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
153# 8 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
154# 9 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
155# 10 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
157# 17 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
159# 46 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
161# 58 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
163# 68 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
165# 98 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
167# 110 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
169# 120 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
171# 167 "/home/runner/work/MFC/MFC/src/common/include/shared_parallel_macros.fpp"
173# 2 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp" 2
175# 7 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
177# 17 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
179# 22 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
181# 27 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
183# 32 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
185# 37 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
187# 42 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
189# 47 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
191# 52 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
193# 57 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
195# 62 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
197# 73 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
199# 78 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
201# 83 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
203# 88 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
205# 103 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
207# 131 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
209# 160 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
211# 175 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
213# 193 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
215# 215 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
217# 244 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
219# 259 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
221# 269 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
223# 278 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
225# 294 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
227# 304 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
229# 311 "/home/runner/work/MFC/MFC/src/common/include/acc_macros.fpp"
231# 4 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp" 2
234# 23 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
237# 43 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
240# 55 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
243# 112 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
246# 130 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
249# 145 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
252# 164 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
255# 193 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
258# 207 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
261# 219 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
264# 231 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
267# 242 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
270# 254 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
273# 266 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
276# 275 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
279# 282 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
282# 289 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
285# 296 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
288# 303 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
290# 305 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
291# 306 "/home/runner/work/MFC/MFC/src/common/include/parallel_macros.fpp"
293# 2 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp" 2
295# 14 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
300# 55 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
303# 75 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
306# 83 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
309# 107 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
312# 123 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
315# 148 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
317# 154 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
319# 161 "/home/runner/work/MFC/MFC/src/common/include/macros.fpp"
321# 7 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp" 2
347 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: particle_cloud_ibs
348 integer,
intent(out) :: num_particle_cloud_ibs
349 type(ib_patch_parameters),
allocatable :: cloud_ibs(:)
350 integer :: cloud_idx, glbl_idx, num_cloud_ibs, n_total_particles
351 real(wp) :: t_start, t_end
353 if (num_particle_clouds == 0)
then
354 allocate (particle_cloud_ibs(0))
355 num_particle_cloud_ibs = 0
359 call cpu_time(t_start)
361 n_total_particles = 0
362 do cloud_idx = 1, num_particle_clouds
363 n_total_particles = n_total_particles + particle_cloud(cloud_idx)%num_particles
367 num_particle_cloud_ibs = 0
370 do cloud_idx = 1, num_particle_clouds
374 select case (particle_cloud(cloud_idx)%packing_method)
380 call s_mpi_abort(
"Particle cloud packing method is not a known packing method of MFC. Exiting.")
384# 68 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
385 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.")
386# 68 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
388# 70 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
389 particle_cloud_ibs(num_particle_cloud_ibs + 1:num_particle_cloud_ibs + num_cloud_ibs) = cloud_ibs(1:num_cloud_ibs)
390 num_particle_cloud_ibs = num_particle_cloud_ibs + num_cloud_ibs
391 deallocate (cloud_ibs)
395 if (
proc_rank == 0) print
'(a,i0,a,f0.3,a)',
'Particle beds placed ', glbl_idx - num_ibs,
' particles in ', &
396 & t_end - t_start,
' seconds.'
408 integer,
intent(in) :: cloud_idx
409 integer,
intent(inout) :: glbl_idx
410 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: cloud_ibs
411 integer,
intent(out) :: num_cloud_ibs
412 integer :: ib_idx, n_placed, geom, seed, alloc_stat
413 integer(8) :: n_attempts, max_attempts
414 real(wp) :: min_dist, rx, ry, rz
415 logical :: overlaps, reject, periodic_pack
416 real(wp),
allocatable :: placed(:,:)
417 integer :: hash_size, slot
418 integer :: bx, by, bz, nx_bins, ny_bins, nz_bins
419 integer,
allocatable :: hash_head(:), chain_next(:)
420 real(wp) :: xmin, ymin, zmin, length_x, length_y, length_z
422 allocate (cloud_ibs(particle_cloud(cloud_idx)%num_particles), stat=alloc_stat)
423 if (alloc_stat /= 0)
then
424 call s_mpi_abort(
"Error :: Ran out of CPU memory trying to allocate particle cloud IB array. " &
425 & //
"Current system resources cannot perform rejection packing with the specified number of particles.")
429 min_dist = 2._wp*particle_cloud(cloud_idx)%radius + particle_cloud(cloud_idx)%min_spacing
430 periodic_pack = particle_cloud(cloud_idx)%cloud_geometry == 1 .and. particle_cloud(cloud_idx)%periodic == 1
431 length_x = particle_cloud(cloud_idx)%length_x
432 length_y = particle_cloud(cloud_idx)%length_y
433 length_z = particle_cloud(cloud_idx)%length_z
434 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*length_x
435 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*length_y
436 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*length_z
437 nx_bins = max(1, ceiling(length_x/min_dist))
438 ny_bins = max(1, ceiling(length_y/min_dist))
439 nz_bins = max(1, ceiling(length_z/min_dist))
440 if (num_dims < 3) nz_bins = 1
442 if (num_dims < 3)
then
448 max_attempts = int(particle_cloud(cloud_idx)%num_particles, 8)*1000_8
451 seed = particle_cloud(cloud_idx)%seed
452 if (seed == 0) seed = 1 + cloud_idx*1013904223
454 allocate (placed(3, particle_cloud(cloud_idx)%num_particles))
458 hash_size = max(16, 4*particle_cloud(cloud_idx)%num_particles)
459 allocate (hash_head(hash_size))
460 allocate (chain_next(particle_cloud(cloud_idx)%num_particles))
464 do while (n_placed < particle_cloud(cloud_idx)%num_particles .and. n_attempts < max_attempts)
465 n_attempts = n_attempts + 1
471 & xmin, ymin, zmin, length_x, length_y, length_z, nx_bins, ny_bins, nz_bins, &
472 & overlaps, bx, by, bz)
474 if (.not. overlaps)
then
475 n_placed = n_placed + 1
476 placed(1, n_placed) = rx
477 placed(2, n_placed) = ry
478 placed(3, n_placed) = rz
482 chain_next(n_placed) = hash_head(slot)
483 hash_head(slot) = n_placed
485 glbl_idx = glbl_idx + 1
490 if (n_placed < particle_cloud(cloud_idx)%num_particles)
then
491 call s_mpi_abort(
"Error :: Failed to place all particles in particle bed")
494 deallocate (placed, hash_head, chain_next)
497 num_cloud_ibs = ib_idx
508 integer,
intent(in) :: cloud_idx
509 integer,
intent(inout) :: seed
510 real(wp),
intent(out) :: rx, ry, rz
511 logical,
intent(out) :: reject
512 real(wp) :: xmin, xmax, ymin, ymax, zmin, zmax
513 real(wp) :: theta, phi, r_shell, rho, u, zdir, r_inner, r_outer
517 select case (particle_cloud(cloud_idx)%cloud_geometry)
519 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_x
520 xmax = particle_cloud(cloud_idx)%x_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_x
521 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_y
522 ymax = particle_cloud(cloud_idx)%y_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_y
523 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_z
524 zmax = particle_cloud(cloud_idx)%z_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_z
528 if (num_dims < 3)
then
529 rz = particle_cloud(cloud_idx)%z_centroid
534 r_inner = particle_cloud(cloud_idx)%shell_inner_radius + particle_cloud(cloud_idx)%radius
535 r_outer = particle_cloud(cloud_idx)%shell_outer_radius - particle_cloud(cloud_idx)%radius
537 if (num_dims < 3)
then
540 r_shell = sqrt((r_outer**2 - r_inner**2)*u + r_inner**2)
541 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*cos(theta)
542 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*sin(theta)
543 rz = particle_cloud(cloud_idx)%z_centroid
544 if (ry < particle_cloud(cloud_idx)%y_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
548 rho = sqrt(max(0._wp, 1._wp - zdir**2))
550 r_shell = ((r_outer**3 - r_inner**3)*u + r_inner**3)**(1._wp/3._wp)
551 rx = particle_cloud(cloud_idx)%x_centroid + r_shell*rho*cos(phi)
552 ry = particle_cloud(cloud_idx)%y_centroid + r_shell*rho*sin(phi)
553 rz = particle_cloud(cloud_idx)%z_centroid + r_shell*zdir
554 if (rz < particle_cloud(cloud_idx)%z_centroid + particle_cloud(cloud_idx)%radius) reject = .true.
557 call s_mpi_abort(
"Particle cloud geometry is not a known cloud geometry of MFC. Exiting.")
570 integer,
intent(in) :: cloud_idx
571 integer,
intent(inout) :: glbl_idx
572 type(ib_patch_parameters),
allocatable,
intent(out),
dimension(:) :: cloud_ibs
573 integer,
intent(out) :: num_cloud_ibs
574 integer :: ib_idx, n_placed, n_target, geom
575 integer :: row, col, ncx, ncy, ix, jy, kz, b
576 real(wp) :: xmin, xmax, ymin, ymax, zmin, zmax, min_dist
577 real(wp) :: spacing, row_dy, cell, x0, px, py
578 real(wp),
dimension(4) :: bx_off, by_off, bz_off
579 real(wp),
dimension(3) :: centroid
584 xmin = particle_cloud(cloud_idx)%x_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_x
585 xmax = particle_cloud(cloud_idx)%x_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_x
586 ymin = particle_cloud(cloud_idx)%y_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_y
587 ymax = particle_cloud(cloud_idx)%y_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_y
588 zmin = particle_cloud(cloud_idx)%z_centroid - 0.5_wp*particle_cloud(cloud_idx)%length_z
589 zmax = particle_cloud(cloud_idx)%z_centroid + 0.5_wp*particle_cloud(cloud_idx)%length_z
591 min_dist = 2._wp*particle_cloud(cloud_idx)%radius + particle_cloud(cloud_idx)%min_spacing
592 n_target = particle_cloud(cloud_idx)%num_particles
595 if (num_dims < 3)
then
598 spacing = sqrt(2._wp*(xmax - xmin)*(ymax - ymin)/(sqrt(3._wp)*real(n_target, wp)))
602 spacing = (sqrt(2._wp)*(xmax - xmin)*(ymax - ymin)*(zmax - zmin)/real(n_target, wp))**(1._wp/3._wp)
605 if (spacing < min_dist)
then
606 call s_mpi_abort(
"Error :: Particle cloud is too dense for lattice packing; " &
607 & //
"reduce num_particles or min_spacing, or enlarge the cloud region")
610 if (num_dims < 3)
then
612 row_dy = spacing*sqrt(3._wp)/2._wp
614 do while (n_placed < n_target)
615 py = ymin + real(row, wp)*row_dy
617 if (mod(row, 2) == 1) x0 = xmin + 0.5_wp*spacing
620 do while (px <= xmax .and. n_placed < n_target)
621 glbl_idx = glbl_idx + 1
622 centroid = [px, py, particle_cloud(cloud_idx)%z_centroid]
624 call s_add_cloud_particle(cloud_idx, ib_idx, glbl_idx, geom, centroid(1), centroid(2), centroid(3), &
627 n_placed = n_placed + 1
629 px = x0 + real(col, wp)*spacing
635 cell = spacing*sqrt(2._wp)
636 bx_off = [0._wp, 0.5_wp, 0.5_wp, 0._wp]*cell
637 by_off = [0._wp, 0.5_wp, 0._wp, 0.5_wp]*cell
638 bz_off = [0._wp, 0._wp, 0.5_wp, 0.5_wp]*cell
639 ncx = max(1, ceiling((xmax - xmin)/cell))
640 ncy = max(1, ceiling((ymax - ymin)/cell))
642 do while (n_placed < n_target)
646 if (n_placed >= n_target)
exit
647 centroid = [xmin + real(ix, wp)*cell + bx_off(b), ymin + real(jy, wp)*cell + by_off(b), &
648 & zmin + real(kz, wp)*cell + bz_off(b)]
649 glbl_idx = glbl_idx + 1
652 & centroid(3), cloud_ibs)
654 n_placed = n_placed + 1
662 num_cloud_ibs = ib_idx
673 integer,
intent(in) :: cloud_idx, glbl_idx, geom
674 integer,
intent(inout) :: ib_idx
675 real(wp),
intent(in) :: px, py, pz
676 type(ib_patch_parameters),
intent(inout),
dimension(:) :: particle_cloud_ibs
679 if (ib_idx >
size(particle_cloud_ibs))
then
680# 360 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
681 call s_prohibit_abort(
"ib_idx > size(particle_cloud_ibs)",
"Too many particle-cloud IBs in one rank's neighborhood. Modify case file or increase num_ib_patches_max_namelist.")
682# 360 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
684# 362 "/home/runner/work/MFC/MFC/src/simulation/m_particle_cloud.fpp"
686 particle_cloud_ibs(ib_idx)%gbl_patch_id = glbl_idx
687 particle_cloud_ibs(ib_idx)%geometry = geom
688 particle_cloud_ibs(ib_idx)%x_centroid = px
689 particle_cloud_ibs(ib_idx)%y_centroid = py
690 particle_cloud_ibs(ib_idx)%z_centroid = pz
691 particle_cloud_ibs(ib_idx)%step_x_centroid = px
692 particle_cloud_ibs(ib_idx)%step_y_centroid = py
693 particle_cloud_ibs(ib_idx)%step_z_centroid = pz
694 particle_cloud_ibs(ib_idx)%angles(:) = 0._wp
695 particle_cloud_ibs(ib_idx)%step_angles(:) = 0._wp
696 particle_cloud_ibs(ib_idx)%vel(:) = 0._wp
697 particle_cloud_ibs(ib_idx)%step_vel(:) = 0._wp
698 particle_cloud_ibs(ib_idx)%angular_vel(:) = 0._wp
699 particle_cloud_ibs(ib_idx)%step_angular_vel(:) = 0._wp
700 particle_cloud_ibs(ib_idx)%force(:) = 0._wp
701 particle_cloud_ibs(ib_idx)%torque(:) = 0._wp
702 particle_cloud_ibs(ib_idx)%centroid_offset(:) = 0._wp
703 particle_cloud_ibs(ib_idx)%rotation_matrix = 0._wp
704 particle_cloud_ibs(ib_idx)%rotation_matrix(1, 1) = 1._wp
705 particle_cloud_ibs(ib_idx)%rotation_matrix(2, 2) = 1._wp
706 particle_cloud_ibs(ib_idx)%rotation_matrix(3, 3) = 1._wp
707 particle_cloud_ibs(ib_idx)%rotation_matrix_inverse = particle_cloud_ibs(ib_idx)%rotation_matrix
708 particle_cloud_ibs(ib_idx)%radius = particle_cloud(cloud_idx)%radius
709 particle_cloud_ibs(ib_idx)%mass = particle_cloud(cloud_idx)%mass
710 particle_cloud_ibs(ib_idx)%moment =
dflt_real
711 particle_cloud_ibs(ib_idx)%moving_ibm = particle_cloud(cloud_idx)%moving_ibm
712 particle_cloud_ibs(ib_idx)%slip = .false.
720 particle_cloud_ibs(ib_idx)%v_blow = 0._wp
721 particle_cloud_ibs(ib_idx)%inj_species = 0
722 particle_cloud_ibs(ib_idx)%burn_rate_exp = 0._wp
723 particle_cloud_ibs(ib_idx)%burn_rate_pref = 0._wp
728 subroutine s_get_cloud_bin(px, py, pz, min_dist, periodic_pack, xmin, ymin, zmin, nx_bins, ny_bins, nz_bins, bx, by, bz)
730 real(wp),
intent(in) :: px, py, pz, min_dist
731 logical,
intent(in) :: periodic_pack
732 real(wp),
intent(in) :: xmin, ymin, zmin
733 integer,
intent(in) :: nx_bins, ny_bins, nz_bins
734 integer,
intent(out) :: bx, by, bz
736 if (periodic_pack)
then
737 bx = modulo(int(floor((px - xmin)/min_dist)), nx_bins)
738 by = modulo(int(floor((py - ymin)/min_dist)), ny_bins)
739 if (num_dims < 3)
then
742 bz = modulo(int(floor((pz - zmin)/min_dist)), nz_bins)
745 bx = int(floor(px/min_dist))
746 by = int(floor(py/min_dist))
747 if (num_dims < 3)
then
750 bz = int(floor(pz/min_dist))
760 & xmin, ymin, zmin, length_x, length_y, length_z, nx_bins, ny_bins, nz_bins, overlaps, bx, by, bz)
762 real(wp),
intent(in) :: px, py, pz, min_dist
763 real(wp),
intent(in),
dimension(:,:) :: placed
764 integer,
intent(in),
dimension(:) :: hash_head, chain_next
765 integer,
intent(in) :: hash_size
766 logical,
intent(in) :: periodic_pack
767 real(wp),
intent(in) :: xmin, ymin, zmin, length_x, length_y, length_z
768 integer,
intent(in) :: nx_bins, ny_bins, nz_bins
769 logical,
intent(out) :: overlaps
770 integer,
intent(out) :: bx, by, bz
771 integer :: nbx, nby, nbz, slot
772 integer :: dx_b, dy_b, dz_b, dz_lo, dz_hi, j
773 real(wp) :: dist_sq, min_dist_sq, dx, dy, dz
775 call s_get_cloud_bin(px, py, pz, min_dist, periodic_pack, xmin, ymin, zmin, nx_bins, ny_bins, nz_bins, bx, by, bz)
779 if (num_dims < 3)
then
784 min_dist_sq = min_dist**2
789 do dz_b = dz_lo, dz_hi
793 if (periodic_pack)
then
794 nbx = modulo(nbx, nx_bins)
795 nby = modulo(nby, ny_bins)
796 if (num_dims == 3) nbz = modulo(nbz, nz_bins)
801 dx = abs(px - placed(1, j))
802 dy = abs(py - placed(2, j))
803 if (periodic_pack)
then
804 dx = min(dx, length_x - dx)
805 dy = min(dy, length_y - dy)
807 if (num_dims < 3)
then
808 dist_sq = dx**2 + dy**2
810 dz = abs(pz - placed(3, j))
811 if (periodic_pack) dz = min(dz, length_z - dz)
812 dist_sq = dx**2 + dy**2 + dz**2
814 if (dist_sq < min_dist_sq)
then
831 type(ib_patch_parameters),
intent(inout),
dimension(:) :: cloud_ibs
832 integer,
intent(inout) :: num_cloud_ibs
833 integer :: i, write_idx
834 real(wp),
dimension(3) :: centroid
837 do i = 1, num_cloud_ibs
838 centroid = [cloud_ibs(i)%x_centroid, cloud_ibs(i)%y_centroid, 0._wp]
839 if (num_dims == 3) centroid(3) = cloud_ibs(i)%z_centroid
841 write_idx = write_idx + 1
842 if (write_idx /= i) cloud_ibs(write_idx) = cloud_ibs(i)
845 num_cloud_ibs = write_idx
852 integer,
intent(inout) :: seed
855 seed = ieor(seed, ishft(seed, 13))
856 seed = ieor(seed, ishft(seed, -17))
857 seed = ieor(seed, ishft(seed, 5))
862 rval = real(iand(seed, huge(seed)), wp)/real(huge(seed), wp)
870 integer,
intent(in) :: bx, by, bz, hash_size
874 key = ieor(ieor(int(bx, 8)*73856093_8, int(by, 8)*19349663_8), int(bz, 8)*83492791_8)
875 slot = int(mod(abs(key), int(hash_size, 8))) + 1
Ghost-node immersed boundary method: locates ghost/image points, computes interpolation coefficients,...
logical function, public f_neighborhood_ranks_own_location(location)
function checks if this local MPI processor owns this specific collision
Compile-time constant parameters: default values, tolerances, and physical constants.
integer, parameter num_ib_patches_max_namelist
real(wp), parameter dflt_real
Default real value.
real(wp), parameter pi
Pi.
Global parameters for the computational domain, fluid properties, and simulation algorithm configurat...
integer proc_rank
Rank of the local processor.
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_add_cloud_particle(cloud_idx, ib_idx, glbl_idx, geom, px, py, pz, particle_cloud_ibs)
Writes a single placed particle into particle_cloud_ibs at the next free slot, advancing ib_idx....
subroutine s_reduce_particle_cloud_ibs(cloud_ibs, num_cloud_ibs)
Compacts cloud_ibs(1:num_ibs) in place, discarding entries outside this rank's IB neighborhood (get_n...
real(wp) function f_xorshift(seed)
Xorshift PRNG. Advances seed in-place and returns a value in [0, 1).
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...
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...
impure subroutine, public s_generate_particle_clouds(particle_cloud_ibs, num_particle_cloud_ibs)
Generate all particle beds and fill particle_cloud_ibs. Called on all ranks before s_reduce_ib_patch_...
subroutine s_particle_cloud_lattice(cloud_idx, glbl_idx, cloud_ibs, num_cloud_ibs)
Places particles on the optimally dense lattice for the cloud region: a triangular lattice in 2D,...
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_particle_cloud_rejection_pack(cloud_idx, glbl_idx, cloud_ibs, num_cloud_ibs)
Rejection-samples particle centres into a box or hemisphere-shell region with a minimum centre-to-cen...
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....