Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f85f983
Initial modifications to allow us to use a unified boudns check on pa…
danieljvickers Jun 9, 2026
4c94454
Removed all of the old outdated subroutines and merged them into a mo…
danieljvickers Jun 10, 2026
6f76374
part of the way through adding a secondary loop
danieljvickers Jun 10, 2026
ec363df
Unified some of the patch geometry functions. Finished out the first …
danieljvickers Jun 10, 2026
72529c9
Passes circle tests
danieljvickers Jun 10, 2026
ce800e4
All tests pass, except for STL mdoels
danieljvickers Jun 10, 2026
f5dc0d7
All tests pass on GNU compilers
danieljvickers Jun 10, 2026
3cd4661
Added patch geometries to docs and fixed spelling
danieljvickers Jun 10, 2026
9b0b59d
Missed some spelling in my git add
danieljvickers Jun 10, 2026
aeaa21e
Integrated with icpp patches and update documents to note the depreca…
danieljvickers Jun 10, 2026
4f88e03
Merged with master
danieljvickers Jun 10, 2026
8c2ffb2
Need to hard-code index 0 in ib markers array in 2D to prevent out-of…
danieljvickers Jun 10, 2026
a2a3e8e
Updated a GPU paralellism macro that contained a removed variable
danieljvickers Jun 10, 2026
f168b40
Formatting
danieljvickers Jun 10, 2026
dac7c47
Passes test suite on NVHPC GPU OpenACC Parallelism
danieljvickers Jun 11, 2026
8680a89
Missing length from a private statement
danieljvickers Jun 11, 2026
16ca6d1
Accidentally moved length to a copyin, not private
danieljvickers Jun 11, 2026
471c924
Format
danieljvickers Jun 11, 2026
2741604
Fixed airfoils on cray GPU
Jun 11, 2026
c985fc0
Merge branch 'master' into 1454-projection-optimization
danieljvickers Jun 11, 2026
d99331b
Merge branch 'master' into 1454-projection-optimization
danieljvickers Jun 11, 2026
c31b231
Resolved issues from merge conflict
Jun 11, 2026
4380b0a
Merge branch 'master' into 1454-projection-optimization
danieljvickers Jun 11, 2026
04a5bf0
Some loop optimizations and debug multi-particle periodicity
Jun 11, 2026
f06fefc
Forgot the radius in the private statement of 2D multi-ib parallelism
danieljvickers Jun 12, 2026
ac1681a
Merge origin/master into 1454-projection-optimization
sbryngelson Jun 12, 2026
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
5 changes: 3 additions & 2 deletions docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,8 @@ This is enabled by adding ``'elliptic_smoothing': "T",`` and ``'elliptic_smoothi
| `num_ibs` | Integer | Number of immersed boundary patches |
| `num_stl_models` | Integer | Number of STL/OBJ model entries in the `stl_models` array |
| `num_particle_clouds` | Integer | Number of particle bed specifications to generate immersed boundary patches from |
| `ib_neighborhood_radius` | Integer | Parameter that controls the neighborhood size for IB detection. |
| `ib_neighborhood_radius` | Integer | Parameter that controls the neighborhood size for IB detection. |
| `many_ib_patch_parallelism` | Logical | Parallelize over IB patches instead of grid cells (better for many small patches). |
| `geometry` | Integer | Geometry configuration of the patch.|
| `x[y,z]_centroid` | Real | Centroid of the applied geometry in the [x,y,z]-direction. |
| `length_x[y,z]` | Real | Length, if applicable, in the [x,y,z]-direction. |
Expand Down Expand Up @@ -1248,7 +1249,7 @@ Boundary is at polar angle \f$\theta = \mathrm{atan2}(y - y_{\mathrm{centroid}},
| 3 | 2D Rectangle | 2 |
| 4 | 2D Airfoil | 2 |
| 8 | 3D Sphere | 3 |
| 10 | 3D Cylinder | 3 |
| 10 | 3D Cylinder | 3 | `length_x` sets the axial length of the cylinder. |
| 11 | 3D Airfoil | 3 |

### Acoustic Supports {#acoustic-supports}
Expand Down
3 changes: 2 additions & 1 deletion docs/module_categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@
"m_checker",
"m_checker_common",
"m_sim_helpers",
"m_derived_variables"
"m_derived_variables",
"m_patch_geometries"
]
},
{
Expand Down
1 change: 1 addition & 0 deletions examples/2D_mibm_particle_cloud/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
"ib": "T",
"num_ibs": 0,
"viscous": "T",
"many_ib_patch_parallelism": "T",
# Collision model (soft-sphere, from 3D_mibm_sphere_head_on_collision)
"collision_model": 1,
"coefficient_of_restitution": 0.9,
Expand Down
7 changes: 5 additions & 2 deletions src/common/m_model.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module m_model
real(wp), allocatable, dimension(:,:,:,:) :: gpu_boundary_v
integer, allocatable :: gpu_boundary_edge_count(:)
real(wp), allocatable :: stl_bounding_boxes(:,:,:)
$:GPU_DECLARE(create='[gpu_ntrs, gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count]')
$:GPU_DECLARE(create='[gpu_ntrs, gpu_trs_v, gpu_trs_n, gpu_boundary_v, gpu_boundary_edge_count, stl_bounding_boxes]')

contains

Expand Down Expand Up @@ -877,7 +877,7 @@ contains
#endif
if (num_stl_models == 0) return

allocate (stl_bounding_boxes(num_stl_models,1:3,1:3))
@:ALLOCATE(stl_bounding_boxes(num_stl_models,1:3,1:3))
@:ALLOCATE(models(num_stl_models))

do stl_id = 1, num_stl_models
Expand Down Expand Up @@ -950,6 +950,9 @@ contains
end if
end do

$:GPU_UPDATE(device='[stl_bounding_boxes]')
$:GPU_UPDATE(device='[stl_models(1:num_stl_models)]')

! Pack and upload flat arrays for GPU (AFTER the loop)
block
integer :: mid, max_ntrs
Expand Down
143 changes: 143 additions & 0 deletions src/common/m_patch_geometries.fpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
!>
!! @file
!! @brief Contains module m_ibm

#:include 'macros.fpp'

!> @brief Contains helper functions specific to various patch gemoetries for determining if a grid cell lies inside of or outside of
!! a patch geometry
module m_patch_geometries

use m_derived_types
use m_global_parameters
use m_variables_conversion
use m_helper
use m_helper_basic
use m_constants
use m_model

implicit none

public :: f_is_inside_sphere, f_is_inside_cylinder, f_is_inside_cuboid, f_is_inside_airfoil, f_is_inside_ellipse

contains

!> Check if the x, y, and z coordinates would be located inside a sphere with the patch_id's radius
function f_is_inside_sphere(x, y, z, radius) result(is_inside)

$:GPU_ROUTINE(parallelism='[seq]')

real(wp), intent(in) :: radius, x, y, z
logical :: is_inside

is_inside = x**2 + y**2 + z**2 <= radius**2

end function f_is_inside_sphere

!> Check which length of the cylinder is not default. Use that direction as the height and the other two coordinate
! values as the radius check
function f_is_inside_cylinder(polar_x, polar_y, height, radius, length) result(is_inside)

$:GPU_ROUTINE(parallelism='[seq]')

real(wp), intent(in) :: polar_x, polar_y, height, radius, length
logical :: is_inside

! check if the circular component of the cylinder is correct
is_inside = polar_x**2 + polar_y**2 <= radius**2

! in 3D, also check the length of the cylinder
if (num_dims == 3) is_inside = is_inside .and. -0.5_wp*length <= height .and. 0.5_wp*length >= height

end function f_is_inside_cylinder

!> Check if the x, y, and possibly z coordinates would be located inside a cuboid with the patch_id's lengths
function f_is_inside_cuboid(x, y, z, length) result(is_inside)

$:GPU_ROUTINE(parallelism='[seq]')

real(wp), intent(in) :: x, y, z
real(wp), dimension(3), intent(in) :: length
logical :: is_inside

! check if x and y are inside the rectangle plane at z=0
is_inside = -0.5_wp*length(1) <= x .and. 0.5_wp*length(1) >= x .and. -0.5_wp*length(2) <= y .and. 0.5_wp*length(2) >= y

! if we are in 3D, this is a cuboid and so we must also check the z axis
if (num_dims == 3) is_inside = is_inside .and. -0.5_wp*length(3) <= z .and. 0.5_wp*length(3) >= z

end function f_is_inside_cuboid

!> Check if the x, y, are bounded by a NACA airfoil. Check if the z coordinate is inside the left and right edges of the
!! airfoil, if set.
function f_is_inside_airfoil(x, y, z, length, airfoil_id) result(is_inside)

$:GPU_ROUTINE(parallelism='[seq]')

real(wp), intent(in) :: x, y, z, length
integer, intent(in) :: airfoil_id
logical :: is_inside
integer :: k
real(wp) :: f

is_inside = .false.

! check the initial x bounds of the grid cell
if (.not. (x >= 0._wp .and. x <= ib_airfoil(airfoil_id)%c)) return

! if we are in 3D, we must also check the z axis
if (num_dims == 3 .and. (.not. (-0.5_wp*length <= z .and. 0.5_wp*length >= z))) return

! our check branches for the upper and lower half of the airfoil
if (y >= 0._wp) then
! increment the iterator so we know where in the airfoil arrays to look
k = 1
do while (ib_airfoil_grids(airfoil_id)%upper(k)%x < x)
k = k + 1
end do

! If the values are approximately equivalent, skip the next check
if (f_approx_equal(ib_airfoil_grids(airfoil_id)%upper(k)%x, x)) then
if (y <= ib_airfoil_grids(airfoil_id)%upper(k)%y) is_inside = .true.
else
! check if the y value is below the upper edge of the airfoil
f = (ib_airfoil_grids(airfoil_id)%upper(k)%x - x)/(ib_airfoil_grids(airfoil_id)%upper(k)%x &
& - ib_airfoil_grids(airfoil_id)%upper(k - 1)%x)
if (y <= ((1._wp - f)*ib_airfoil_grids(airfoil_id)%upper(k)%y + f*ib_airfoil_grids(airfoil_id)%upper(k - 1)%y)) &
& is_inside = .true.
end if
else
! increment the iterator so we know where in the airfoil arrays to look
k = 1
do while (ib_airfoil_grids(airfoil_id)%lower(k)%x < x)
k = k + 1
end do

! If the values are approximately equivalent, skip the next check
if (f_approx_equal(ib_airfoil_grids(airfoil_id)%lower(k)%x, x)) then
if (y >= ib_airfoil_grids(airfoil_id)%lower(k)%y) is_inside = .true.
else
! check if the y value is above the lower edge of the airfoil
f = (ib_airfoil_grids(airfoil_id)%lower(k)%x - x)/(ib_airfoil_grids(airfoil_id)%lower(k)%x &
& - ib_airfoil_grids(airfoil_id)%lower(k - 1)%x)
if (y >= ((1._wp - f)*ib_airfoil_grids(airfoil_id)%lower(k)%y + f*ib_airfoil_grids(airfoil_id)%lower(k - 1)%y)) &
& is_inside = .true.
end if
end if

end function f_is_inside_airfoil

function f_is_inside_ellipse(x, y, length) result(is_inside)

$:GPU_ROUTINE(parallelism='[seq]')

real(wp), intent(in) :: x, y
real(wp), dimension(3), intent(in) :: length
logical :: is_inside

! Ellipse condition (x/a)^2 + (y/b)^2 <= 1
is_inside = (x/(0.5_wp*length(1)))**2 + (y/(0.5_wp*length(2)))**2 <= 1._wp

end function f_is_inside_ellipse

end module m_patch_geometries
4 changes: 4 additions & 0 deletions src/post_process/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ module m_global_parameters

! shear_num, shear_indices, shear_BC_flip_num, shear_BC_flip_indices: in m_global_parameters_common
! proc_coords, start_idx, mpiiofs, mpi_info_int: in m_global_parameters_common
type(ib_airfoil_parameters), allocatable, dimension(:) :: ib_airfoil !< Per-airfoil NACA parameters (unused in post_process)
!> Per-airfoil computed surface grids (unused in post_process)
type(ib_airfoil_grid), allocatable, dimension(:) :: ib_airfoil_grids

#ifdef MFC_MPI
type(mpi_io_var), public :: MPI_IO_DATA
type(mpi_io_ib_var), public :: MPI_IO_IB_DATA
Expand Down
5 changes: 5 additions & 0 deletions src/pre_process/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ module m_global_parameters
integer :: nmom !< Number of carried moments
!> @}

!> @name Immersed Boundaries
!> @{
! patch_ib, ib_airfoil, stl_models: auto-generated in generated_decls.fpp
!> Per-airfoil computed surface grids (unused in pre_process)
type(ib_airfoil_grid), allocatable, dimension(:) :: ib_airfoil_grids
!> @}

!> @name Non-polytropic bubble gas compression
!> @{
Expand Down
37 changes: 19 additions & 18 deletions src/pre_process/m_icpp_patches.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
!> @brief Constructs initial condition patch geometries (lines, circles, rectangles, spheres, etc.) on the grid
module m_icpp_patches

use m_patch_geometries
use m_model ! Subroutine(s) related to STL files
use m_derived_types ! Definitions of the derived types
use m_global_parameters
Expand Down Expand Up @@ -323,8 +324,8 @@ contains
& dy)*(sqrt((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2) - radius))*(-0.5_wp) + 0.5_wp
end if

if (((x_cc(i) - x_centroid)**2 + (y_cc(j) - y_centroid)**2 <= radius**2 &
& .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, &
if ((f_is_inside_cylinder(x_cc(i) - x_centroid, y_cc(j) - y_centroid, 0._wp, radius, &
& 0._wp) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, &
& 0) == smooth_patch_id) then
call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp)

Expand Down Expand Up @@ -497,8 +498,8 @@ contains
& + 0.5_wp
end if

if ((((x_cc(i) - x_centroid)/a)**2 + ((y_cc(j) - y_centroid)/b)**2 <= 1._wp &
& .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, &
if ((f_is_inside_ellipse(x_cc(i) - x_centroid, y_cc(j) - y_centroid, [2._wp*a, 2._wp*b, &
& 0._wp]) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) .or. patch_id_fp(i, j, &
& 0) == smooth_patch_id) then
call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp)

Expand Down Expand Up @@ -629,8 +630,7 @@ contains
! Assign patch vars if cell is covered and patch has write permission
do j = 0, n
do i = 0, m
if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) &
& .and. y_boundary%end >= y_cc(j)) then
if (f_is_inside_cuboid(x_cc(i) - x_centroid, y_cc(j) - y_centroid, 0._wp, [length_x, length_y, 0._wp])) then
if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then
call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp)

Expand Down Expand Up @@ -760,8 +760,8 @@ contains
! Assign patch vars if cell is covered and patch has write permission
do j = 0, n
do i = 0, m
if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= y_cc(j) &
& .and. y_boundary%end >= y_cc(j) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then
if (f_is_inside_cuboid(x_cc(i) - x_centroid, y_cc(j) - y_centroid, 0._wp, [length_x, length_y, &
& 0._wp]) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, 0))) then
call s_assign_patch_primitive_variables(patch_id, i, j, 0, eta, q_prim_vf, patch_id_fp)

@:analytical()
Expand Down Expand Up @@ -1010,8 +1010,8 @@ contains
& - radius))*(-0.5_wp) + 0.5_wp
end if

if ((((x_cc(i) - x_centroid)**2 + (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2 <= radius**2) &
& .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, &
if ((f_is_inside_sphere(x_cc(i) - x_centroid, cart_y - y_centroid, cart_z - z_centroid, &
& radius) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, &
& k) == smooth_patch_id) then
call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp)

Expand Down Expand Up @@ -1076,8 +1076,8 @@ contains
cart_z = z_cc(k)
end if

if (x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i) .and. y_boundary%beg <= cart_y &
& .and. y_boundary%end >= cart_y .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) then
if (f_is_inside_cuboid(x_cc(i) - x_centroid, cart_y - y_centroid, cart_z - z_centroid, [length_x, length_y, &
& length_z])) then
if (patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) then
call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp)

Expand Down Expand Up @@ -1167,12 +1167,13 @@ contains
end if
end if

if (((.not. f_is_default(length_x) .and. (cart_y - y_centroid)**2 + (cart_z - z_centroid)**2 <= radius**2 &
& .and. x_boundary%beg <= x_cc(i) .and. x_boundary%end >= x_cc(i)) .or. (.not. f_is_default(length_y) &
& .and. (x_cc(i) - x_centroid)**2 + (cart_z - z_centroid)**2 <= radius**2 .and. y_boundary%beg <= cart_y &
& .and. y_boundary%end >= cart_y) .or. (.not. f_is_default(length_z) .and. (x_cc(i) - x_centroid)**2 &
& + (cart_y - y_centroid)**2 <= radius**2 .and. z_boundary%beg <= cart_z .and. z_boundary%end >= cart_z) &
& .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, &
if (((.not. f_is_default(length_x) .and. f_is_inside_cylinder(cart_y - y_centroid, cart_z - z_centroid, &
& x_cc(i) - x_centroid, radius, &
& length_x)) .or. (.not. f_is_default(length_y) .and. f_is_inside_cylinder(x_cc(i) - x_centroid, &
& cart_z - z_centroid, cart_y - y_centroid, radius, &
& length_y)) .or. (.not. f_is_default(length_z) .and. f_is_inside_cylinder(x_cc(i) - x_centroid, &
& cart_y - y_centroid, cart_z - z_centroid, radius, &
& length_z)) .and. patch_icpp(patch_id)%alter_patch(patch_id_fp(i, j, k))) .or. patch_id_fp(i, j, &
& k) == smooth_patch_id) then
call s_assign_patch_primitive_variables(patch_id, i, j, k, eta, q_prim_vf, patch_id_fp)

Expand Down
1 change: 1 addition & 0 deletions src/simulation/m_checker.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ contains
call s_check_inputs_time_stepping

@:PROHIBIT(ib_state_wrt .and. .not. ib, "ib_state_wrt requires ib to be enabled")
@:PROHIBIT(many_ib_patch_parallelism .and. .not. ib, "many_ib_patch_parallelism requires ib to be enabled")

if (num_particle_clouds > 0) then
call s_check_inputs_particle_clouds
Expand Down
1 change: 1 addition & 0 deletions src/simulation/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ contains
collision_time = dflt_real
ib_coefficient_of_friction = dflt_real
ib_state_wrt = .false.
many_ib_patch_parallelism = .false.

! Bubble modeling (sim-specific)
bubble_model = 1
Expand Down
Loading
Loading