Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,18 +425,25 @@ A particle cloud is a compact specification of a bed of identical circular (2D)
| Parameter | Type | Description |
| ---: | :----: | :--- |
| `x[y,z]_centroid` | Real | Centre of the cloud region in the [x,y,z]-direction. |
| `length_x[y,z]` | Real | Extent of the cloud region in the [x,y,z]-direction. |
| `length_x[y,z]` | Real | Extent of the cloud region in the [x,y,z]-direction for `cloud_geometry = 1`; ignored by `cloud_geometry = 2`. |
| `num_particles` | Integer | Number of particles to place in the region. |
| `radius` | Real | Radius of every particle in the cloud. |
| `mass` | Real | Mass of every particle in the cloud. |
| `min_spacing` | Real | Minimum surface-to-surface gap between particles (centres are `2*radius + min_spacing` apart). |
| `cloud_geometry` | Integer | Shape of the cloud region. |
| `shell_inner_radius` | Real | Inner radius for hemisphere-shell clouds (`cloud_geometry = 2`). |
| `shell_outer_radius` | Real | Outer radius for hemisphere-shell clouds (`cloud_geometry = 2`). |
| `moving_ibm` | Integer | Motion flag applied to every particle (see `patch_ib(j)%%moving_ibm`). |
| `seed` | Integer | Random seed for reproducible placement (used by `packing_method = 1`). |
| `packing_method` | Integer | Algorithm used to place the particles. |

- `cloud_geometry` selects the cloud region:
- `1` (box) uses `x[y,z]_centroid` and `length_x[y,z]` to define the region.
- `2` uses `x[y,z]_centroid`, `shell_inner_radius`, and `shell_outer_radius` to define a half-annulus in 2D and a hemisphere shell in 3D. Particle centres are sampled between `shell_inner_radius + radius` and `shell_outer_radius - radius`, and the flat plane is kept clear by one particle radius. The flat face is fixed at `y_centroid` in 2D and `z_centroid` in 3D; the filled region opens toward positive `y` in 2D and positive `z` in 3D.
- `packing_method` selects how the `num_particles` are positioned within the cloud region:
- `1` (rejection sampling) draws random positions and rejects any that violate `min_spacing`, producing a disordered bed. `seed` makes the placement reproducible.
- `2` (lattice) places the particles on the optimally dense lattice for the geometry — a triangular lattice in 2D and a face-centered cubic lattice in 3D. The lattice spacing is derived from the particle density (`num_particles` over the region area/volume); if that spacing is below the required `2*radius + min_spacing`, the region is too dense and the run aborts.
- Hemisphere-shell clouds currently support rejection sampling only; `cloud_geometry = 2` with `packing_method = 2` is rejected during input validation.

### 5. Fluid Material's {#sec-fluid-materials}

Expand Down
3 changes: 3 additions & 0 deletions src/common/m_derived_types.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,11 @@ module m_derived_types
real(wp) :: radius !< Particle radius
real(wp) :: mass !< Particle mass
real(wp) :: min_spacing !< Minimum surface-to-surface gap (particle centers are 2*radius + min_spacing apart)
real(wp) :: shell_inner_radius !< Inner radius for shell packing
real(wp) :: shell_outer_radius !< Outer radius for shell packing
integer :: moving_ibm !< Motion flag: 0=static, 1=moving (forces), 2=forced path
integer :: seed !< Random seed for reproducible placement
integer :: cloud_geometry !< Cloud region geometry: 1=box, 2=hemisphere shell
integer :: packing_method !< Packing algorithm: 1=rejection sampling, 2=lattice
end type particle_cloud_parameters

Expand Down
13 changes: 12 additions & 1 deletion src/simulation/m_checker.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,19 +183,30 @@ contains

end subroutine s_check_inputs_ib_injection

!> Checks that each active particle cloud has a valid packing_method specified
!> Checks that each active particle cloud has a valid geometry and packing_method specified
impure subroutine s_check_inputs_particle_clouds

integer :: i
character(len=5) :: idxStr

do i = 1, num_particle_clouds
call s_int_to_str(i, idxStr)
@:PROHIBIT(particle_cloud(i)%cloud_geometry /= 1 .and. particle_cloud(i)%cloud_geometry /= 2, &
& "particle_cloud("//trim(idxStr) //")%cloud_geometry must be 1 (box) or 2 (hemisphere shell)")
@:PROHIBIT(particle_cloud(i)%packing_method == dflt_int, &
& "particle_cloud("//trim(idxStr) &
& //")%packing_method must be specified (1 = rejection sampling, 2 = lattice)")
@:PROHIBIT(particle_cloud(i)%packing_method /= 1 .and. particle_cloud(i)%packing_method /= 2, &
& "particle_cloud("//trim(idxStr) //")%packing_method must be 1 (rejection sampling) or 2 (lattice)")
@:PROHIBIT(particle_cloud(i)%cloud_geometry == 2 .and. particle_cloud(i)%shell_inner_radius < 0._wp, &
& "particle_cloud("//trim(idxStr) //") hemisphere shell requires shell_inner_radius >= 0")
@:PROHIBIT(particle_cloud(i)%cloud_geometry == 2 &
& .and. particle_cloud(i)%shell_outer_radius <= particle_cloud(i)%shell_inner_radius &
& + 2._wp*particle_cloud(i)%radius, &
& "particle_cloud("//trim(idxStr) &
& //") hemisphere shell requires shell_outer_radius > shell_inner_radius + 2*radius")
@:PROHIBIT(particle_cloud(i)%cloud_geometry == 2 .and. particle_cloud(i)%packing_method == 2, &
& "particle_cloud("//trim(idxStr) //") hemisphere-shell lattice packing is not implemented")
end do

end subroutine s_check_inputs_particle_clouds
Expand Down
3 changes: 3 additions & 0 deletions src/simulation/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,11 @@ contains
particle_cloud(i)%radius = dflt_real
particle_cloud(i)%mass = dflt_real
particle_cloud(i)%min_spacing = 0._wp
particle_cloud(i)%shell_inner_radius = dflt_real
particle_cloud(i)%shell_outer_radius = dflt_real
particle_cloud(i)%moving_ibm = 0
particle_cloud(i)%seed = 0
particle_cloud(i)%cloud_geometry = 1
particle_cloud(i)%packing_method = dflt_int
end do

Expand Down
3 changes: 2 additions & 1 deletion src/simulation/m_mpi_proxy.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,12 +200,13 @@ contains
! manual: particle_cloud (runtime loop to num_particle_clouds; irregular member subset)
do i = 1, num_particle_clouds
#:for VAR in ['x_centroid', 'y_centroid', 'z_centroid', 'length_x', 'length_y', 'length_z', &
& 'radius', 'mass', 'min_spacing']
& 'radius', 'mass', 'min_spacing', 'shell_inner_radius', 'shell_outer_radius']
call MPI_BCAST(particle_cloud(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
#:endfor
call MPI_BCAST(particle_cloud(i)%num_particles, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(particle_cloud(i)%moving_ibm, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(particle_cloud(i)%seed, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(particle_cloud(i)%cloud_geometry, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(particle_cloud(i)%packing_method, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
end do

Expand Down
Loading
Loading