|
MFC
Exascale flow solver
|
Generates particle beds by converting particle_cloud patch specifications into individual immersed boundary patches before writing them to the initial IB state file. Under file_per_process it runs on every rank: each rank computes the same deterministic placement (so no MPI broadcast of particle positions is needed) and keeps only the particles f_local_rank_owns_location says are its own, so every generated particle is written by exactly one rank. Otherwise only rank 0 runs it and keeps every particle. More...
Functions/Subroutines | |
| 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 under file_per_process (see module docs). Each packing method owns and allocates its own per-cloud working array (see s_particle_cloud_lattice / s_particle_cloud_rejection_pack) and hands back only the entries this rank keeps. Only the first num_particle_cloud_ibs of them are actually written - callers must use that count, not size(particle_cloud_ibs), since the remainder of the array is left uninitialized. | |
| 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-centre spacing. Rejection sampling needs every placed particle tracked (regardless of which rank owns it) to detect overlaps deterministically, so cloud_ibs is allocated here to the cloud's full requested particle count and only pared down to this rank's own subdomain afterwards, via s_reduce_particle_cloud_ibs. Only the per-candidate geometry sampling differs between box and hemisphere shell; it is delegated to s_sample_cloud_candidate, and every other step (overlap rejection via the spatial hash, acceptance, reduction) is geometry-independent. | |
| 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. For box geometry the candidate is uniform in the box and never rejected. For a hemisphere shell the candidate is uniform in the shell volume - 2D uses theta uniform on [0, pi] with the sqrt radial CDF; 3D uses uniform phi, uniform cos(polar) on [0, 1], and the cube-root radial CDF - and reject is set when it lands within one particle radius of the flat face (the plane at y_centroid in 2D, z_centroid in 3D), a hard geometric cut applied after sampling that preserves uniformity over the remaining region. | |
| 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, a face-centered cubic lattice in 3D. The lattice spacing is set by the particle density (num_particles over the region area/volume); if that spacing falls below the required centre-to-centre distance (2*radius + min_spacing), the region is too dense and the run is aborted. No two lattice sites can overlap, so unlike rejection packing each site's local ownership (f_local_rank_owns_location) is checked as it is generated and only this rank's sites are stored; cloud_ibs is therefore allocated to a worst-case cap rather than the cloud's full particle count. | |
| 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_owns_location) and updating num_cloud_ibs to the retained count. Used by rejection packing, which cannot filter as it places particles (see s_particle_cloud_rejection_pack), to pare its full, unfiltered placement down to this rank's own subdomain. | |
| subroutine | 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, tagged with its already-assigned, absolute global patch id via glbl_idx. Only the fields s_write_ib_state_0_file writes are set; simulation fills every other property in s_assign_particle_cloud_ib_defaults (src/simulation/m_start_up.fpp). | |
| 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_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 spatial-hash bins. Scans the 3x3(x3) bin neighborhood - O(1) average via hash lookup - and also hands back the candidate's own bin so the caller can insert it without recomputing. | |
| real(wp) function | f_xorshift (seed) |
| Xorshift PRNG. Advances seed in-place and returns a value in [0, 1). | |
| 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 bins across buckets. Hash collisions are benign: the distance check catches false neighbours. | |
Generates particle beds by converting particle_cloud patch specifications into individual immersed boundary patches before writing them to the initial IB state file. Under file_per_process it runs on every rank: each rank computes the same deterministic placement (so no MPI broadcast of particle positions is needed) and keeps only the particles f_local_rank_owns_location says are its own, so every generated particle is written by exactly one rank. Otherwise only rank 0 runs it and keeps every particle.
|
private |
Hash bin coordinates to a 1-indexed slot in [1, hash_size]. Uses large prime multipliers to spread bins across buckets. Hash collisions are benign: the distance check catches false neighbours.
Definition at line 847 of file m_particle_cloud.fpp.f90.
|
private |
Xorshift PRNG. Advances seed in-place and returns a value in [0, 1).
Definition at line 829 of file m_particle_cloud.fpp.f90.
|
private |
Writes a single placed particle into particle_cloud_ibs at the next free slot, advancing ib_idx, tagged with its already-assigned, absolute global patch id via glbl_idx. Only the fields s_write_ib_state_0_file writes are set; simulation fills every other property in s_assign_particle_cloud_ib_defaults (src/simulation/m_start_up.fpp).
Definition at line 703 of file m_particle_cloud.fpp.f90.
|
private |
Check whether a candidate particle centre overlaps any already-placed particle in neighbouring spatial-hash bins. Scans the 3x3(x3) bin neighborhood - O(1) average via hash lookup - and also hands back the candidate's own bin so the caller can insert it without recomputing.
Definition at line 761 of file m_particle_cloud.fpp.f90.
| impure subroutine, public m_particle_cloud::s_generate_particle_clouds | ( | type(bounds_info), dimension(3), intent(in) | glb_bounds, |
| type(ib_patch_parameters), dimension(:), intent(out), allocatable | particle_cloud_ibs, | ||
| integer, intent(out) | num_particle_cloud_ibs ) |
Generate all particle beds and fill particle_cloud_ibs, keeping only the particles this rank owns under file_per_process (see module docs). Each packing method owns and allocates its own per-cloud working array (see s_particle_cloud_lattice / s_particle_cloud_rejection_pack) and hands back only the entries this rank keeps. Only the first num_particle_cloud_ibs of them are actually written - callers must use that count, not size(particle_cloud_ibs), since the remainder of the array is left uninitialized.
Definition at line 361 of file m_particle_cloud.fpp.f90.
|
private |
Convert a candidate particle centre to spatial-hash bin coordinates.
Definition at line 730 of file m_particle_cloud.fpp.f90.
|
private |
Places particles on the optimally dense lattice for the cloud region: a triangular lattice in 2D, a face-centered cubic lattice in 3D. The lattice spacing is set by the particle density (num_particles over the region area/volume); if that spacing falls below the required centre-to-centre distance (2*radius + min_spacing), the region is too dense and the run is aborted. No two lattice sites can overlap, so unlike rejection packing each site's local ownership (f_local_rank_owns_location) is checked as it is generated and only this rank's sites are stored; cloud_ibs is therefore allocated to a worst-case cap rather than the cloud's full particle count.
Definition at line 580 of file m_particle_cloud.fpp.f90.
|
private |
Rejection-samples particle centres into a box or hemisphere-shell region with a minimum centre-to-centre spacing. Rejection sampling needs every placed particle tracked (regardless of which rank owns it) to detect overlaps deterministically, so cloud_ibs is allocated here to the cloud's full requested particle count and only pared down to this rank's own subdomain afterwards, via s_reduce_particle_cloud_ibs. Only the per-candidate geometry sampling differs between box and hemisphere shell; it is delegated to s_sample_cloud_candidate, and every other step (overlap rejection via the spatial hash, acceptance, reduction) is geometry-independent.
Definition at line 423 of file m_particle_cloud.fpp.f90.
|
private |
Compacts cloud_ibs(1:num_cloud_ibs) in place, discarding entries this rank does not own (f_local_rank_owns_location) and updating num_cloud_ibs to the retained count. Used by rejection packing, which cannot filter as it places particles (see s_particle_cloud_rejection_pack), to pare its full, unfiltered placement down to this rank's own subdomain.
Definition at line 679 of file m_particle_cloud.fpp.f90.
|
private |
Draws one rejection-sampling candidate centre (rx, ry, rz) for cloud_idx, advancing seed in place. For box geometry the candidate is uniform in the box and never rejected. For a hemisphere shell the candidate is uniform in the shell volume - 2D uses theta uniform on [0, pi] with the sqrt radial CDF; 3D uses uniform phi, uniform cos(polar) on [0, 1], and the cube-root radial CDF - and reject is set when it lands within one particle radius of the flat face (the plane at y_centroid in 2D, z_centroid in 3D), a hard geometric cut applied after sampling that preserves uniformity over the remaining region.
Definition at line 518 of file m_particle_cloud.fpp.f90.