Skip to content
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
d953d5b
Pushing from local
danieljvickers Sep 15, 2025
9f6af97
Succesfully added RK time stepping
danieljvickers Oct 2, 2025
8d3941d
Finalizing time-step module
danieljvickers Oct 2, 2025
734b649
Addded handlers for new case file parameters
danieljvickers Oct 2, 2025
e1c3b3f
added hooks for a rotation matrix
danieljvickers Oct 2, 2025
effd324
Added the rotation matrix calculation, which will be needed for ident…
danieljvickers Oct 2, 2025
ac0013d
Finished adding velocity update, but now I need to fix compiler errors
danieljvickers Oct 2, 2025
50799ab
Added some inverse rotation calculations to the square case
danieljvickers Oct 7, 2025
c04cfae
Ready to test with a rotated square
danieljvickers Oct 7, 2025
e80952b
Ran test case and everything appears to be working
danieljvickers Oct 7, 2025
6ddc795
Spelling and formatting run
danieljvickers Oct 7, 2025
ce5f071
Fixed single-precision building
danieljvickers Oct 7, 2025
007949d
Updated patch_IB rotation values
danieljvickers Oct 8, 2025
ddfcd0f
Updated 2D airfoil
danieljvickers Oct 8, 2025
0cabfff
Finished adding support for existing IB geometries. They will all now…
danieljvickers Oct 8, 2025
372ddf0
Fixed compiler issue with airfoil changes. All tests pass locally
danieljvickers Oct 8, 2025
603b42f
Updated rectangle levelset
danieljvickers Oct 8, 2025
ab29c8a
Swapped out Id values
danieljvickers Oct 8, 2025
71437fd
Modified the cuboid levelset to use local coords
danieljvickers Oct 8, 2025
fcccef7
Final levelset calculation updated
danieljvickers Oct 8, 2025
d13de48
Fixed compiling errors'
danieljvickers Oct 8, 2025
91e0f50
Temporary fix for issue involving cuboid normal vector selection. Com…
danieljvickers Oct 8, 2025
42e1177
Fixed airfoil shape, but it is not rotating yet
danieljvickers Oct 9, 2025
367bea6
I am dumb. Do not look at this commit. It has nothing for you.
danieljvickers Oct 9, 2025
24b25ec
Need to generate new golden files for the locations of the airfoil ar…
danieljvickers Oct 9, 2025
c6c55b7
Updated the golden files for this test case after realizing that ther…
danieljvickers Oct 9, 2025
c7c8d8a
Formatting and spelling
danieljvickers Oct 9, 2025
6b1ee94
Changes to the case file to support new rotational system
danieljvickers Oct 9, 2025
3208814
Resolved memory not being reset for rectangles and cuboids. Also fixe…
danieljvickers Oct 10, 2025
9dc62dd
Fixing macOS runners failing due to contera version difference
danieljvickers Oct 10, 2025
6febe45
Ran formatting
danieljvickers Oct 10, 2025
78fd281
Fixed issue with pre-processing not applying correct initial rotation…
danieljvickers Oct 10, 2025
7cf947e
Formatting
danieljvickers Oct 10, 2025
63c87c5
Adding OpenMP/OpenACC tags for vecturs used in paralel loop for GPU s…
danieljvickers Oct 10, 2025
1af3670
found an error in 3d Airfoil case that is unrelated to the frontier C…
danieljvickers Oct 12, 2025
5a60a7f
Merge branch 'master' into add-rotating-mibms
danieljvickers Oct 12, 2025
272ca02
Build with one task for testing
wilfonba Oct 13, 2025
8fc4902
.github
danieljvickers Oct 13, 2025
64fa336
Found my error. Thanks Ben for being a rubber ducky :)
danieljvickers Oct 13, 2025
29db19a
Integrated with new time stepper code
danieljvickers Oct 13, 2025
c29ec88
Resolved error. Ready to merge
danieljvickers Oct 13, 2025
604e1db
Merge branch 'add-rotating-mibms' of github.com:danieljvickers/MFC in…
danieljvickers Oct 13, 2025
cbfb2da
Formatting
danieljvickers Oct 13, 2025
7560a02
Added a tumbling rectangle case
danieljvickers Oct 15, 2025
8906927
Fixed GPU errors on NVHPC
danieljvickers Oct 16, 2025
d4a1280
Generated golden files for totating sphere
danieljvickers Oct 16, 2025
876f16a
Updated case file to be longer
danieljvickers Oct 16, 2025
f1b6fb7
Formatting
danieljvickers Oct 16, 2025
21d0594
Spelling
danieljvickers Oct 16, 2025
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
6 changes: 3 additions & 3 deletions examples/2D_ibm_airfoil/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,12 @@
"patch_ib(1)%t": 0.15,
"patch_ib(1)%p": 0.4,
"patch_ib(1)%m": 0.02,
"patch_ib(1)%theta": 30,
"patch_ib(1)%angles(3)": -0.5235987756, # 30 degrees clockwise rotation, in radians
# Fluids Physical Parameters
# Use the same stiffness as the air bubble
"fluid_pp(1)%gamma": 1.0e00 / (gam_a - 1.0e00), # 2.50(Not 1.40)
"fluid_pp(1)%gamma": 1.0e00 / (gam_a - 1.0e00), # 2.50 (Not 1.40)
"fluid_pp(1)%pi_inf": 0,
"fluid_pp(2)%gamma": 1.0e00 / (gam_b - 1.0e00), # 2.50(Not 1.40)
"fluid_pp(2)%gamma": 1.0e00 / (gam_b - 1.0e00), # 2.50 (Not 1.40)
"fluid_pp(2)%pi_inf": 0,
}
)
Expand Down
294 changes: 141 additions & 153 deletions src/common/m_compute_levelset.fpp

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions src/common/m_derived_types.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,13 @@ module m_derived_types
real(wp) :: x_centroid, y_centroid, z_centroid !<
!! Location of the geometric center, i.e. the centroid, of the patch. It
!! is specified through its x-, y- and z-coordinates, respectively.
real(wp) :: step_x_centroid, step_y_centroid, step_z_centroid !<
!! Centroid locations of intermediate steps in the time_stepper module

real(wp), dimension(1:3) :: angles
real(wp), dimension(1:3) :: step_angles
real(wp), dimension(1:3, 1:3) :: rotation_matrix !< matrix that converts from IB reference frame to fluid reference frame
real(wp), dimension(1:3, 1:3) :: rotation_matrix_inverse !< matrix that converts from fluid reference frame to IB reference frame

real(wp) :: c, p, t, m

Expand Down Expand Up @@ -322,6 +329,9 @@ module m_derived_types
!! Patch conditions for moving imersed boundaries
integer :: moving_ibm ! 0 for no moving, 1 for moving, 2 for moving on forced path
real(wp), dimension(1:3) :: vel
real(wp), dimension(1:3) :: step_vel ! velocity array used to store intermediate steps in the time_stepper module
real(wp), dimension(1:3) :: angular_vel
real(wp), dimension(1:3) :: step_angular_vel ! velocity array used to store intermediate steps in the time_stepper module

end type ib_patch_parameters

Expand Down
341 changes: 191 additions & 150 deletions src/common/m_ib_patches.fpp

Large diffs are not rendered by default.

2 changes: 0 additions & 2 deletions src/pre_process/m_data_output.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,6 @@ contains
write (2, FMT) airfoil_grid_l(j)%x, airfoil_grid_l(j)%y
end do
close (2)

print *, "Np", Np
end if
end do
end if
Expand Down
13 changes: 10 additions & 3 deletions src/pre_process/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -541,9 +541,16 @@ contains

! Variables to handle moving imersed boundaries, defaulting to no movement
patch_ib(i)%moving_ibm = 0
patch_ib(i)%vel(1) = 0._wp
patch_ib(i)%vel(2) = 0._wp
patch_ib(i)%vel(3) = 0._wp
patch_ib(i)%vel(:) = 0._wp
patch_ib(i)%angles(:) = 0._wp
patch_ib(i)%angular_vel(:) = 0._wp

! sets values of a rotation matrix which can be used when calculating rotations
patch_ib(i)%rotation_matrix = 0._wp
patch_ib(i)%rotation_matrix(1, 1) = 1._wp
patch_ib(i)%rotation_matrix(2, 2) = 1._wp
patch_ib(i)%rotation_matrix(3, 3) = 1._wp
patch_ib(i)%rotation_matrix_inverse = patch_ib(i)%rotation_matrix
end do

! Fluids physical parameters
Expand Down
5 changes: 5 additions & 0 deletions src/pre_process/m_initial_condition.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,8 @@ contains
!! primitive variables are converted to conservative ones.
impure subroutine s_generate_initial_condition

integer :: i

! Converting the conservative variables to the primitive ones given
! preexisting initial condition data files were read in on start-up
if (old_ic) then
Expand All @@ -190,6 +192,9 @@ contains
end if

if (ib) then
do i = 1, num_ibs
call s_update_ib_rotation_matrix(i)
end do
call s_apply_ib_patches(ib_markers%sf, levelset, levelset_norm)
end if
call s_apply_icpp_patches(patch_id_fp, q_prim_vf)
Expand Down
4 changes: 4 additions & 0 deletions src/pre_process/m_mpi_proxy.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ contains
call MPI_BCAST(patch_bc(i)%${VAR}$, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
#:endfor

#:for VAR in ['vel', 'angular_vel', 'angles']
call MPI_BCAST(patch_ib(i)%${VAR}$, 3, mpi_p, 0, MPI_COMM_WORLD, ierr)
#:endfor

call MPI_BCAST(patch_bc(i)%radius, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)

#:for VAR in ['centroid', 'length']
Expand Down
61 changes: 30 additions & 31 deletions src/simulation/m_ibm.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ contains
do i = 1, num_ibs
if (patch_ib(i)%moving_ibm /= 0) then
moving_immersed_boundary_flag = .true.
exit

end if
call s_update_ib_rotation_matrix(i)
end do

! Allocating the patch identities bookkeeping variable
Expand All @@ -116,8 +117,8 @@ contains
call s_mpi_allreduce_integer_sum(num_inner_gps, max_num_inner_gps)

$:GPU_UPDATE(device='[num_gps, num_inner_gps]')
@:ALLOCATE(ghost_points(1:int(max_num_gps * 1.2)))
@:ALLOCATE(inner_points(1:int(max_num_inner_gps * 1.2)))
@:ALLOCATE(ghost_points(1:int(max_num_gps * 1.5)))
@:ALLOCATE(inner_points(1:int(max_num_inner_gps * 1.5)))

$:GPU_ENTER_DATA(copyin='[ghost_points,inner_points]')

Expand Down Expand Up @@ -149,7 +150,7 @@ contains
!! @param q_prim_vf Primitive variables
!! @param pb Internal bubble pressure
!! @param mv Mass of vapor in bubble
pure subroutine s_ibm_correct_state(q_cons_vf, q_prim_vf, pb_in, mv_in)
subroutine s_ibm_correct_state(q_cons_vf, q_prim_vf, pb_in, mv_in)

type(scalar_field), &
dimension(sys_size), &
Expand Down Expand Up @@ -182,6 +183,8 @@ contains
real(wp), dimension(3) :: norm !< Normal vector from GP to IP
real(wp), dimension(3) :: physical_loc !< Physical loc of GP
real(wp), dimension(3) :: vel_g !< Velocity of GP
real(wp), dimension(3) :: radial_vector !< vector from centroid to ghost point
real(wp), dimension(3) :: rotation_velocity !< speed of the ghost point due to rotation

real(wp) :: nbub
real(wp) :: buf
Expand All @@ -191,8 +194,8 @@ contains
$:GPU_PARALLEL_LOOP(private='[physical_loc,dyn_pres,alpha_rho_IP, &
& alpha_IP,pres_IP,vel_IP,vel_g,vel_norm_IP,r_IP, &
& v_IP,pb_IP,mv_IP,nmom_IP,presb_IP,massv_IP,rho, &
& gamma,pi_inf,Re_K,G_K,Gs,gp,innerp,norm,buf, &
& j,k,l,q]')
& gamma,pi_inf,Re_K,G_K,Gs,gp,innerp,norm,buf, radial_vector, &
& rotation_velocity, j,k,l,q]')
do i = 1, num_gps

gp = ghost_points(i)
Expand Down Expand Up @@ -265,9 +268,15 @@ contains
! we know the object is not moving if moving_ibm is 0 (false)
vel_g = 0._wp
else
! get the vector that points from the centroid to the ghost
radial_vector = physical_loc - [patch_ib(patch_id)%x_centroid, &
patch_ib(patch_id)%y_centroid, patch_ib(patch_id)%z_centroid]
! convert the angular velocity from the inertial reference frame to the fluids frame, then convert to linear velocity
rotation_velocity = cross_product(matmul(patch_ib(patch_id)%rotation_matrix, patch_ib(patch_id)%angular_vel), radial_vector)
do q = 1, 3
! if mibm is 1 or 2, then the boundary may be moving
vel_g(q) = patch_ib(patch_id)%vel(q)
vel_g(q) = patch_ib(patch_id)%vel(q) ! add the linear velocity
vel_g(q) = vel_g(q) + rotation_velocity(q) ! add the rotational velocity
end do
end if
end if
Expand Down Expand Up @@ -381,7 +390,7 @@ contains
type(ghost_point) :: gp

integer :: q, dim !< Iterator variables
integer :: i, j, k !< Location indexes
integer :: i, j, k, l !< Location indexes
integer :: patch_id !< IB Patch ID
integer :: dir
integer :: index
Expand Down Expand Up @@ -436,7 +445,6 @@ contains
.or. temp_loc > s_cc(index + 1)))
index = index + dir
if (index < -buff_size .or. index > bound) then
print *, q, index, bound, buff_size
print *, "temp_loc=", temp_loc, " s_cc(index)=", s_cc(index), " s_cc(index+1)=", s_cc(index + 1)
print *, "Increase buff_size further in m_helper_basic (currently set to a minimum of 10)"
error stop "Increase buff_size"
Expand Down Expand Up @@ -896,26 +904,6 @@ contains

end subroutine s_interpolate_image_point

!> Subroutine the updates the moving imersed boundary positions via Euler's method
impure subroutine s_propagate_mib(patch_id)

integer, intent(in) :: patch_id
integer :: i

! start by using euler's method naiively, but eventually incorporate more sophistocation
if (patch_ib(patch_id)%moving_ibm == 1) then
! this continues with euler's method, which is obviously not that great and we need to add acceleration
do i = 1, 3
patch_ib(patch_id)%vel(i) = patch_ib(patch_id)%vel(i) + 0.0*dt ! TODO :: ADD EXTERNAL FORCES HERE
end do

patch_ib(patch_id)%x_centroid = patch_ib(patch_id)%x_centroid + patch_ib(patch_id)%vel(1)*dt
patch_ib(patch_id)%y_centroid = patch_ib(patch_id)%y_centroid + patch_ib(patch_id)%vel(2)*dt
patch_ib(patch_id)%z_centroid = patch_ib(patch_id)%z_centroid + patch_ib(patch_id)%vel(3)*dt
end if

end subroutine s_propagate_mib

!> Resets the current indexes of immersed boundaries and replaces them after updating
!> the position of each moving immersed boundary
impure subroutine s_update_mib(num_ibs, levelset, levelset_norm)
Expand All @@ -924,14 +912,15 @@ contains
type(levelset_field), intent(inout) :: levelset
type(levelset_norm_field), intent(inout) :: levelset_norm

integer :: i
integer :: i, ierr

! Clears the existing immersed boundary indices
ib_markers%sf = 0

! recalulcate the rotation matrix based upon the new angles
do i = 1, num_ibs
if (patch_ib(i)%moving_ibm /= 0) then
call s_propagate_mib(i) ! TODO :: THIS IS DONE TERRIBLY WITH EULER METHOD
call s_update_ib_rotation_matrix(i)
end if
end do

Expand Down Expand Up @@ -963,4 +952,14 @@ contains

end subroutine s_finalize_ibm_module

function cross_product(a, b) result(c)
implicit none
real(wp), intent(in) :: a(3), b(3)
real(wp) :: c(3)

c(1) = a(2)*b(3) - a(3)*b(2)
c(2) = a(3)*b(1) - a(1)*b(3)
c(3) = a(1)*b(2) - a(2)*b(1)
end function cross_product

end module m_ibm
9 changes: 6 additions & 3 deletions src/simulation/m_mpi_proxy.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,14 @@ contains

do i = 1, num_ibs
#:for VAR in [ 'radius', 'length_x', 'length_y', &
& 'x_centroid', 'y_centroid', 'c', 'm', 'p', 't', 'theta', 'slip', &
'moving_ibm', 'vel',]
& 'x_centroid', 'y_centroid', 'c', 'm', 'p', 't', 'theta', 'slip']
call MPI_BCAST(patch_ib(i)%${VAR}$, 1, mpi_p, 0, MPI_COMM_WORLD, ierr)
#:endfor
call MPI_BCAST(patch_ib(i)%geometry, 2, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
#:for VAR in ['vel', 'angular_vel', 'angles']
call MPI_BCAST(patch_ib(i)%${VAR}$, 3, mpi_p, 0, MPI_COMM_WORLD, ierr)
#:endfor
call MPI_BCAST(patch_ib(i)%geometry, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
call MPI_BCAST(patch_ib(i)%moving_ibm, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
end do

do j = 1, num_probes_max
Expand Down
7 changes: 0 additions & 7 deletions src/simulation/m_start_up.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,6 @@ contains
if (patch_ib(i)%c > 0) then
Np = int((patch_ib(i)%p*patch_ib(i)%c/dx(0))*20) + int(((patch_ib(i)%c - patch_ib(i)%p*patch_ib(i)%c)/dx(0))*20) + 1
allocate (MPI_IO_airfoil_IB_DATA%var(1:2*Np))
print *, "HERE Np", Np
end if
end do
end if
Expand Down Expand Up @@ -943,8 +942,6 @@ contains
do j = 1, num_ibs
if (patch_ib(j)%c > 0) then

print *, "HERE Np", Np

allocate (airfoil_grid_u(1:Np))
allocate (airfoil_grid_l(1:Np))

Expand Down Expand Up @@ -1135,10 +1132,6 @@ contains
end do
end if

if (moving_immersed_boundary_flag) then
call s_update_mib(num_ibs, levelset, levelset_norm)
end if

call s_compute_derived_variables(t_step)


Expand Down
29 changes: 29 additions & 0 deletions src/simulation/m_time_steppers.fpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

High-level Suggestion

The logic for updating Immersed Boundary (IB) motion is duplicated across several time-stepping subroutines in m_time_steppers.fpp. This should be refactored into a single, parameterized subroutine to improve code maintainability. [High-level, importance: 7]

Solution Walkthrough:

Before:

subroutine s_tvd_rk2(...)
  ...
  ! Step 1
  if (moving_immersed_boundary_flag) then
    do i = 1, num_ibs
      if (patch_ib(i)%moving_ibm == 1) then
        ! ... save state and perform Euler step ...
      end if
    end do
    call s_update_mib(...)
  end if
  ...
  ! Step 2
  if (moving_immersed_boundary_flag) then
    do i = 1, num_ibs
      if (patch_ib(i)%moving_ibm == 1) then
        ! ... perform RK2 update step ...
      end if
    end do
    call s_update_mib(...)
  end if
end subroutine

After:

subroutine s_update_ib_position(rk_stage, rk_order)
  ! Logic to update IB position based on RK stage and order
  if (moving_immersed_boundary_flag) then
    do i = 1, num_ibs
      if (patch_ib(i)%moving_ibm == 1) then
        ! ... unified update logic using rk_stage/order ...
      end if
    end do
    call s_update_mib(...)
  end if
end subroutine

subroutine s_tvd_rk2(...)
  ...
  call s_update_ib_position(rk_stage=1, rk_order=2)
  ...
  call s_update_ib_position(rk_stage=2, rk_order=2)
end subroutine

Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,35 @@ contains
if (adv_n) call s_comp_alpha_from_n(q_cons_ts(1)%vf)

if (ib) then
! check if any IBMS are moving, and if so, update the markers, ghost points, levelsets, and levelset norms
if (moving_immersed_boundary_flag) then
do i = 1, num_ibs
if (s == 1) then
patch_ib(i)%step_vel = patch_ib(i)%vel
patch_ib(i)%step_angular_vel = patch_ib(i)%angular_vel
patch_ib(i)%step_angles = patch_ib(i)%angles
patch_ib(i)%step_x_centroid = patch_ib(i)%x_centroid
patch_ib(i)%step_y_centroid = patch_ib(i)%y_centroid
patch_ib(i)%step_z_centroid = patch_ib(i)%z_centroid
end if

if (patch_ib(i)%moving_ibm == 1) then
do j = 1, 3
patch_ib(i)%vel(j) = (rk_coef(s, 1)*patch_ib(i)%step_vel(j) + rk_coef(s, 2)*patch_ib(i)%vel(j) + rk_coef(s, 3)*0._wp*dt)/rk_coef(s, 4) ! 0.0 is a placeholder for accelerations
patch_ib(i)%angular_vel(j) = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel(j) + rk_coef(s, 2)*patch_ib(i)%angular_vel(j) + rk_coef(s, 3)*0._wp*dt)/rk_coef(s, 4)

! Update the angle of the IB
patch_ib(i)%angles(j) = (rk_coef(s, 1)*patch_ib(i)%step_angles(j) + rk_coef(s, 2)*patch_ib(i)%angles(j) + rk_coef(s, 3)*patch_ib(i)%angular_vel(j)*dt)/rk_coef(s, 4)
end do

! Update the position of the IB
patch_ib(i)%x_centroid = (rk_coef(s, 1)*patch_ib(i)%step_x_centroid + rk_coef(s, 2)*patch_ib(i)%x_centroid + rk_coef(s, 3)*patch_ib(i)%vel(1)*dt)/rk_coef(s, 4)
patch_ib(i)%y_centroid = (rk_coef(s, 1)*patch_ib(i)%step_y_centroid + rk_coef(s, 2)*patch_ib(i)%y_centroid + rk_coef(s, 3)*patch_ib(i)%vel(2)*dt)/rk_coef(s, 4)
patch_ib(i)%z_centroid = (rk_coef(s, 1)*patch_ib(i)%step_z_centroid + rk_coef(s, 2)*patch_ib(i)%z_centroid + rk_coef(s, 3)*patch_ib(i)%vel(3)*dt)/rk_coef(s, 4)
end if
end do
call s_update_mib(num_ibs, levelset, levelset_norm)
end if
if (qbmm .and. .not. polytropic) then
call s_ibm_correct_state(q_cons_ts(1)%vf, q_prim_vf, pb_ts(1)%sf, mv_ts(1)%sf)
else
Expand Down
Loading
Loading