-
Notifications
You must be signed in to change notification settings - Fork 123
Invicid two-way fluid-structure interaction #1075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
5c3b79a
1f39342
9b687b8
22dba76
42512af
85ea1b1
b38796e
0cbe4b9
9ea3020
3f68040
676aa73
8094216
5d2fc37
b7f00d1
f25e61d
c82a623
25ee314
7c70fd4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,105 @@ | ||||||
| import json | ||||||
| import math | ||||||
|
|
||||||
| Mu = 1.84e-05 | ||||||
| gam_a = 1.4 | ||||||
|
|
||||||
| # Configuring case dictionary | ||||||
| print( | ||||||
| json.dumps( | ||||||
| { | ||||||
| # Logistics | ||||||
| "run_time_info": "T", | ||||||
| # Computational Domain Parameters | ||||||
| # For these computations, the cylinder is placed at the (0,0,0) | ||||||
| # domain origin. | ||||||
| # axial direction | ||||||
| "x_domain%beg": 0.0e00, | ||||||
| "x_domain%end": 6.0e-03, | ||||||
| # r direction | ||||||
| "y_domain%beg": 0.0e00, | ||||||
| "y_domain%end": 6.0e-03, | ||||||
| "cyl_coord": "F", | ||||||
| "m": 200, | ||||||
| "n": 200, | ||||||
| "p": 0, | ||||||
| "dt": 6.0e-6, | ||||||
| "t_step_start": 0, | ||||||
| "t_step_stop": 10000, # 10000, | ||||||
| "t_step_save": 100, | ||||||
| # Simulation Algorithm Parameters | ||||||
| # Only one patches are necessary, the air tube | ||||||
| "num_patches": 1, | ||||||
| # Use the 5 equation model | ||||||
| "model_eqns": 2, | ||||||
| "alt_soundspeed": "F", | ||||||
| # One fluids: air | ||||||
| "num_fluids": 1, | ||||||
| # time step | ||||||
| "mpp_lim": "F", | ||||||
| # Correct errors when computing speed of sound | ||||||
| "mixture_err": "T", | ||||||
| # Use TVD RK3 for time marching | ||||||
| "time_stepper": 3, | ||||||
| # Use WENO5 | ||||||
| "weno_order": 5, | ||||||
| "weno_eps": 1.0e-16, | ||||||
| "weno_Re_flux": "T", | ||||||
| "weno_avg": "T", | ||||||
| "avg_state": 2, | ||||||
| "mapped_weno": "T", | ||||||
| "null_weights": "F", | ||||||
| "mp_weno": "T", | ||||||
| "riemann_solver": 2, | ||||||
| "wave_speeds": 1, | ||||||
| # We use ghost-cell | ||||||
| "bc_x%beg": -3, | ||||||
| "bc_x%end": -3, | ||||||
| "bc_y%beg": -3, | ||||||
| "bc_y%end": -3, | ||||||
| # Set IB to True and add 1 patch | ||||||
| "ib": "T", | ||||||
| "num_ibs": 1, | ||||||
| "viscous": "T", | ||||||
| # Formatted Database Files Structure Parameters | ||||||
| "format": 1, | ||||||
| "precision": 2, | ||||||
| "prim_vars_wrt": "T", | ||||||
| "E_wrt": "T", | ||||||
| "parallel_io": "T", | ||||||
| # Patch: Constant Tube filled with air | ||||||
| # Specify the cylindrical air tube grid geometry | ||||||
| "patch_icpp(1)%geometry": 3, | ||||||
| "patch_icpp(1)%x_centroid": 3.0e-03, | ||||||
| # Uniform medium density, centroid is at the center of the domain | ||||||
| "patch_icpp(1)%y_centroid": 3.0e-03, | ||||||
| "patch_icpp(1)%length_x": 6.0e-03, | ||||||
| "patch_icpp(1)%length_y": 6.0e-03, | ||||||
| # Specify the patch primitive variables | ||||||
| "patch_icpp(1)%vel(1)": 0.05e00, | ||||||
| "patch_icpp(1)%vel(2)": 0.0e00, | ||||||
| "patch_icpp(1)%pres": 1.0e00, | ||||||
| "patch_icpp(1)%alpha_rho(1)": 1.0e00, | ||||||
| "patch_icpp(1)%alpha(1)": 1.0e00, | ||||||
| # Patch: Cylinder Immersed Boundary | ||||||
| "patch_ib(1)%geometry": 2, | ||||||
| "patch_ib(1)%x_centroid": 1.5e-03, | ||||||
| "patch_ib(1)%y_centroid": 4.5e-03, | ||||||
| "patch_ib(1)%radius": 0.3e-03, | ||||||
| "patch_ib(1)%slip": "F", | ||||||
| "patch_ib(1)%moving_ibm": 2, | ||||||
| "patch_ib(1)%vel(2)": -0.1, | ||||||
| "patch_ib(1)%angles(1)": 0.0, # x-axis rotation in radians | ||||||
| "patch_ib(1)%angles(2)": 0.0, # y-axis rotation | ||||||
| "patch_ib(1)%angles(3)": 0.0, # z-axis rotation | ||||||
| "patch_ib(1)%angular_vel(1)": 0.0, # x-axis rotational velocity in radians per second | ||||||
| "patch_ib(1)%angular_vel(2)": 0.0, # y-axis rotation | ||||||
| "patch_ib(1)%angular_vel(3)": 0.0, # z-axis rotation | ||||||
| "patch_ib(1)%mass": 0.0001, # z-axis rotation | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Incorrect comment: The comment Prompt for AI agents
Suggested change
|
||||||
| # Fluids Physical Parameters | ||||||
| "fluid_pp(1)%gamma": 1.0e00 / (gam_a - 1.0e00), # 2.50(Not 1.40) | ||||||
| "fluid_pp(1)%pi_inf": 0, | ||||||
| "fluid_pp(1)%Re(1)": 2500000, | ||||||
| } | ||||||
| ) | ||||||
| ) | ||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -472,6 +472,30 @@ contains | |||||||||
|
|
||||||||||
| end subroutine s_mpi_allreduce_sum | ||||||||||
|
|
||||||||||
| !> This subroutine follows the behavior of the s_mpi_allreduce_sum subroutine | ||||||||||
| !> with the additional feature that it reduces an array of vectors. | ||||||||||
| impure subroutine s_mpi_allreduce_vectors_sum(var_loc, var_glb, num_vectors, vector_length) | ||||||||||
|
|
||||||||||
| integer, intent(in) :: num_vectors, vector_length | ||||||||||
| real(wp), dimension(:, :), intent(in) :: var_loc | ||||||||||
| real(wp), dimension(:, :), intent(out) :: var_glb | ||||||||||
|
|
||||||||||
| #ifdef MFC_MPI | ||||||||||
| integer :: ierr !< Generic flag used to identify and report MPI errors | ||||||||||
|
|
||||||||||
| ! Performing the reduction procedure | ||||||||||
| if (loc(var_loc) == loc(var_glb)) then | ||||||||||
| call MPI_Allreduce(MPI_IN_PLACE, var_glb, num_vectors*vector_length, & | ||||||||||
| mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) | ||||||||||
| else | ||||||||||
| call MPI_Allreduce(var_loc, var_glb, num_vectors*vector_length, & | ||||||||||
| mpi_p, MPI_SUM, MPI_COMM_WORLD, ierr) | ||||||||||
| end if | ||||||||||
|
|
||||||||||
| #endif | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Missing non-MPI fallback: when Prompt for AI agents
Suggested change
|
||||||||||
|
|
||||||||||
| end subroutine s_mpi_allreduce_vectors_sum | ||||||||||
|
|
||||||||||
| !> The following subroutine takes the input local variable | ||||||||||
| !! from all processors and reduces to the sum of all | ||||||||||
| !! values. The reduced variable is recorded back onto the | ||||||||||
|
|
||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. High-level SuggestionThe force and torque calculations in Solution Walkthrough:Before:subroutine s_compute_ib_forces(pressure)
...
do i = 0, m
do j = 0, n
do k = 0, p
...
! Incorrect pressure gradient using cell-center coordinates in denominator
pressure_divergence(1) = (pressure(i+1,j,k) - pressure(i-1,j,k)) / (2._wp * x_cc(i))
pressure_divergence(2) = (pressure(i,j+1,k) - pressure(i,j-1,k)) / (2._wp * y_cc(j))
! Incorrect cell volume calculation using coordinates
cell_volume = x_cc(i) * y_cc(j)
if (num_dims == 3) then
pressure_divergence(3) = (pressure(i,j,k+1) - pressure(i,j,k-1)) / (2._wp * z_cc(k))
cell_volume = cell_volume * z_cc(k)
end if
forces(ib_idx, :) = forces(ib_idx, :) - (pressure_divergence * cell_volume)
...
end do
end do
end do
end subroutine
After:subroutine s_compute_ib_forces(pressure)
...
! Grid spacings (dx, dy, dz) should be available or computed
! e.g., dx = x_cc(1) - x_cc(0) for a uniform grid
do i = 0, m
do j = 0, n
do k = 0, p
...
! Correct pressure gradient using grid spacing
pressure_divergence(1) = (pressure(i+1,j,k) - pressure(i-1,j,k)) / (2._wp * dx)
pressure_divergence(2) = (pressure(i,j+1,k) - pressure(i,j-1,k)) / (2._wp * dy)
! Correct cell volume calculation
cell_volume = dx * dy
if (num_dims == 3) then
pressure_divergence(3) = (pressure(i,j,k+1) - pressure(i,j,k-1)) / (2._wp * dz)
cell_volume = cell_volume * dz
end if
forces(ib_idx, :) = forces(ib_idx, :) - (pressure_divergence * cell_volume)
...
end do
end do
end do
end subroutine
|
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,7 +101,6 @@ contains | |||||||||||||||||
| end if | ||||||||||||||||||
| call s_update_ib_rotation_matrix(i) | ||||||||||||||||||
| end do | ||||||||||||||||||
|
|
||||||||||||||||||
| $:GPU_ENTER_DATA(copyin='[patch_ib]') | ||||||||||||||||||
|
|
||||||||||||||||||
| ! Allocating the patch identities bookkeeping variable | ||||||||||||||||||
|
|
@@ -197,6 +196,21 @@ contains | |||||||||||||||||
| type(ghost_point) :: gp | ||||||||||||||||||
| type(ghost_point) :: innerp | ||||||||||||||||||
|
|
||||||||||||||||||
| ! set the Moving IBM interior Pressure Values | ||||||||||||||||||
| do patch_id = 1, num_ibs | ||||||||||||||||||
| if (patch_ib(patch_id)%moving_ibm == 2) then | ||||||||||||||||||
| do j = 0, m | ||||||||||||||||||
| do k = 0, n | ||||||||||||||||||
| do l = 0, p | ||||||||||||||||||
| if (ib_markers%sf(j, k, l) == patch_id) then | ||||||||||||||||||
| q_prim_vf(E_idx)%sf(j, k, l) = 1._wp | ||||||||||||||||||
| end if | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| end if | ||||||||||||||||||
| end do | ||||||||||||||||||
|
|
||||||||||||||||||
| if (num_gps > 0) then | ||||||||||||||||||
| $:GPU_PARALLEL_LOOP(private='[i,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, radial_vector, rotation_velocity, j,k,l,q,qv_K,c_IP,nbub,patch_id]') | ||||||||||||||||||
| do i = 1, num_gps | ||||||||||||||||||
|
|
@@ -244,6 +258,17 @@ contains | |||||||||||||||||
| if (surface_tension) then | ||||||||||||||||||
| q_prim_vf(c_idx)%sf(j, k, l) = c_IP | ||||||||||||||||||
| end if | ||||||||||||||||||
|
|
||||||||||||||||||
| ! set the pressure | ||||||||||||||||||
| do q = 1, num_fluids | ||||||||||||||||||
| if (patch_ib(patch_id)%moving_ibm == 0) then | ||||||||||||||||||
| q_prim_vf(E_idx)%sf(j, k, l) = pres_IP | ||||||||||||||||||
| else | ||||||||||||||||||
| ! TODO :: improve for two fluid | ||||||||||||||||||
| q_prim_vf(E_idx)%sf(j, k, l) = pres_IP/(1._wp - 2._wp*abs(levelset%sf(j, k, l, patch_id)*alpha_rho_IP(q)/pres_IP)*dot_product(patch_ib(patch_id)%force/patch_ib(patch_id)%mass, levelset_norm%sf(j, k, l, patch_id, :))) | ||||||||||||||||||
| end if | ||||||||||||||||||
| end do | ||||||||||||||||||
|
|
||||||||||||||||||
| if (model_eqns /= 4) then | ||||||||||||||||||
| ! If in simulation, use acc mixture subroutines | ||||||||||||||||||
| if (elasticity) then | ||||||||||||||||||
|
|
@@ -969,6 +994,67 @@ contains | |||||||||||||||||
|
|
||||||||||||||||||
| end subroutine s_update_mib | ||||||||||||||||||
|
|
||||||||||||||||||
| ! compute the surface integrals of the IB via a volume integraion method described in | ||||||||||||||||||
| ! "A coupled IBM/Euler-Lagrange framework for simulating shock-induced particle size segregation" | ||||||||||||||||||
| ! by Archana Sridhar and Jesse Capecelatro | ||||||||||||||||||
| subroutine s_compute_ib_forces(pressure) | ||||||||||||||||||
|
|
||||||||||||||||||
| real(wp), dimension(0:m, 0:n, 0:p), intent(in) :: pressure | ||||||||||||||||||
|
|
||||||||||||||||||
| integer :: i, j, k, ib_idx | ||||||||||||||||||
| real(wp), dimension(num_ibs, 3) :: forces, torques | ||||||||||||||||||
| real(wp), dimension(1:3) :: pressure_divergence, radial_vector | ||||||||||||||||||
| real(wp) :: cell_volume | ||||||||||||||||||
|
|
||||||||||||||||||
| forces = 0._wp | ||||||||||||||||||
| torques = 0._wp | ||||||||||||||||||
|
|
||||||||||||||||||
| ! TODO :: This is currently only valid inviscid, and needs to be extended to add viscocity | ||||||||||||||||||
| $:GPU_PARALLEL_LOOP(private='[ib_idx,radial_vector,pressure_divergence,cell_volume]', copy='[forces,torques]', copyin='[ib_markers]', collapse=3) | ||||||||||||||||||
| do i = 0, m | ||||||||||||||||||
| do j = 0, n | ||||||||||||||||||
| do k = 0, p | ||||||||||||||||||
| ib_idx = ib_markers%sf(i, j, k) | ||||||||||||||||||
| if (ib_idx /= 0) then ! only need to compute the gradient for cells inside a IB | ||||||||||||||||||
| if (patch_ib(ib_idx)%moving_ibm == 2) then | ||||||||||||||||||
| if (num_dims == 3) then | ||||||||||||||||||
| radial_vector = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, patch_ib(ib_idx)%z_centroid] ! get the vector pointing to the grid cell | ||||||||||||||||||
| else | ||||||||||||||||||
| radial_vector = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_idx)%x_centroid, patch_ib(ib_idx)%y_centroid, 0._wp] ! get the vector pointing to the grid cell | ||||||||||||||||||
| end if | ||||||||||||||||||
| pressure_divergence(1) = (pressure(i + 1, j, k) - pressure(i - 1, j, k))/(2._wp*x_cc(i)) | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Pressure gradient calculation uses Prompt for AI agents |
||||||||||||||||||
| pressure_divergence(2) = (pressure(i, j + 1, k) - pressure(i, j - 1, k))/(2._wp*y_cc(j)) | ||||||||||||||||||
| cell_volume = x_cc(i)*y_cc(j) | ||||||||||||||||||
| if (num_dims == 3) then | ||||||||||||||||||
| pressure_divergence(3) = (pressure(i, j, k + 1) - pressure(i, j, k - 1))/(2._wp*z_cc(k)) | ||||||||||||||||||
| cell_volume = cell_volume*z_cc(k) | ||||||||||||||||||
|
Comment on lines
+1025
to
+1030
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical bug: Pressure gradient uses cell centers instead of cell widths. The pressure divergence calculation divides by -pressure_divergence(1) = (pressure(i + 1, j, k) - pressure(i - 1, j, k))/(2._wp*x_cc(i))
-pressure_divergence(2) = (pressure(i, j + 1, k) - pressure(i, j - 1, k))/(2._wp*y_cc(j))
-cell_volume = x_cc(i)*y_cc(j)
+pressure_divergence(1) = (pressure(i + 1, j, k) - pressure(i - 1, j, k))/(x_cc(i + 1) - x_cc(i - 1))
+pressure_divergence(2) = (pressure(i, j + 1, k) - pressure(i, j - 1, k))/(y_cc(j + 1) - y_cc(j - 1))
+cell_volume = dx(i)*dy(j)
if (num_dims == 3) then
- pressure_divergence(3) = (pressure(i, j, k + 1) - pressure(i, j, k - 1))/(2._wp*z_cc(k))
- cell_volume = cell_volume*z_cc(k)
+ pressure_divergence(3) = (pressure(i, j, k + 1) - pressure(i, j, k - 1))/(z_cc(k + 1) - z_cc(k - 1))
+ cell_volume = cell_volume*dz(k)
🤖 Prompt for AI Agents |
||||||||||||||||||
| else | ||||||||||||||||||
| pressure_divergence(3) = 0._wp | ||||||||||||||||||
| end if | ||||||||||||||||||
|
|
||||||||||||||||||
| forces(ib_idx, :) = forces(ib_idx, :) - (pressure_divergence*cell_volume) | ||||||||||||||||||
| torques(ib_idx, :) = torques(ib_idx, :) + (cross_product(radial_vector, pressure_divergence)*cell_volume) | ||||||||||||||||||
| end if | ||||||||||||||||||
| end if | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| $:END_GPU_PARALLEL_LOOP() | ||||||||||||||||||
|
|
||||||||||||||||||
| ! reduce the forces across all MPI ranks | ||||||||||||||||||
| call s_mpi_allreduce_vectors_sum(forces, forces, num_ibs, 3) | ||||||||||||||||||
| call s_mpi_allreduce_vectors_sum(torques, torques, num_ibs, 3) | ||||||||||||||||||
|
|
||||||||||||||||||
| ! apply the summed forces | ||||||||||||||||||
| do i = 1, num_ibs | ||||||||||||||||||
| patch_ib(i)%force(:) = forces(i, :) | ||||||||||||||||||
| patch_ib(i)%torque(:) = matmul(patch_ib(i)%rotation_matrix_inverse, torques(i, :)) ! torques must be computed in the local coordinates of the IB | ||||||||||||||||||
| end do | ||||||||||||||||||
|
|
||||||||||||||||||
| print *, patch_ib(1)%force(1:2) | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove debug print statement. This debug print statement will produce excessive output in production runs and should be removed or guarded by a debug flag. -print *, patch_ib(1)%force(1:2)📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Debug print statement should be removed from production code. Prompt for AI agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P2: Debug print statement should be removed from production code. Prompt for AI agents |
||||||||||||||||||
|
|
||||||||||||||||||
| end subroutine s_compute_ib_forces | ||||||||||||||||||
|
|
||||||||||||||||||
| !> Subroutine to deallocate memory reserved for the IBM module | ||||||||||||||||||
| impure subroutine s_finalize_ibm_module() | ||||||||||||||||||
|
|
||||||||||||||||||
|
|
@@ -978,6 +1064,77 @@ contains | |||||||||||||||||
|
|
||||||||||||||||||
| end subroutine s_finalize_ibm_module | ||||||||||||||||||
|
|
||||||||||||||||||
| subroutine s_compute_moment_of_inertia(ib_marker, axis) | ||||||||||||||||||
|
|
||||||||||||||||||
| real(wp), dimension(3), optional :: axis !< the axis about which we compute the moment. Only required in 3D. | ||||||||||||||||||
| integer, intent(in) :: ib_marker | ||||||||||||||||||
|
|
||||||||||||||||||
| real(wp) :: moment, distance_to_axis, cell_volume | ||||||||||||||||||
| real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis | ||||||||||||||||||
| integer :: i, j, k, count | ||||||||||||||||||
|
|
||||||||||||||||||
| if (p == 0) then | ||||||||||||||||||
| axis = [0, 1, 0] | ||||||||||||||||||
| else if (sqrt(sum(axis**2)) == 0) then | ||||||||||||||||||
| ! if the object is not actually rotating at this time, return a dummy value and exit | ||||||||||||||||||
| patch_ib(ib_marker)%moment = 1._wp | ||||||||||||||||||
| return | ||||||||||||||||||
| else | ||||||||||||||||||
| axis = axis/sqrt(sum(axis)) | ||||||||||||||||||
| end if | ||||||||||||||||||
|
Comment on lines
+1076
to
+1084
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional argument handling issue in 2D case. When -subroutine s_compute_moment_of_inertia(ib_marker, axis)
+subroutine s_compute_moment_of_inertia(ib_marker, axis_in)
- real(wp), dimension(3), optional :: axis !< the axis about which we compute the moment. Only required in 3D.
+ real(wp), dimension(3), intent(in), optional :: axis_in !< the axis about which we compute the moment. Only required in 3D.
integer, intent(in) :: ib_marker
real(wp) :: moment, distance_to_axis, cell_volume
- real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis
+ real(wp), dimension(3) :: position, closest_point_along_axis, vector_to_axis, axis
integer :: i, j, k, count
if (p == 0) then
- axis = [0, 1, 0]
- else if (sqrt(sum(axis**2)) == 0) then
+ axis = [0._wp, 0._wp, 1._wp]
+ else if (.not. present(axis_in) .or. sqrt(sum(axis_in**2)) < 1.e-16_wp) then
! if the object is not actually rotating at this time, return a dummy value and exit
patch_ib(ib_marker)%moment = 1._wp
return
else
- axis = axis/sqrt(sum(axis))
+ axis = axis_in/sqrt(sum(axis_in**2))
end if
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| ! if the IB is in 2D or a 3D sphere, we can compute this exactly | ||||||||||||||||||
| if (patch_ib(ib_marker)%geometry == 2) then ! circle | ||||||||||||||||||
| patch_ib(ib_marker)%moment = 0.5*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 | ||||||||||||||||||
| elseif (patch_ib(ib_marker)%geometry == 3) then ! rectangle | ||||||||||||||||||
| patch_ib(ib_marker)%moment = patch_ib(i)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2)/6._wp | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Variable name typo: Uses Line 1090 references elseif (patch_ib(ib_marker)%geometry == 3) then ! rectangle
- patch_ib(ib_marker)%moment = patch_ib(i)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2)/6._wp
+ patch_ib(ib_marker)%moment = patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%length_x**2 + patch_ib(ib_marker)%length_y**2)/6._wp📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P0: Wrong index variable: Prompt for AI agents
Suggested change
|
||||||||||||||||||
| elseif (patch_ib(ib_marker)%geometry == 8) then ! sphere | ||||||||||||||||||
| patch_ib(ib_marker)%moment = 0.4*patch_ib(ib_marker)%mass*(patch_ib(ib_marker)%radius)**2 | ||||||||||||||||||
|
|
||||||||||||||||||
| else ! we do not have an analytic moment of inertia calculation and need to approximate it directly | ||||||||||||||||||
| count = 0 | ||||||||||||||||||
| moment = 0._wp | ||||||||||||||||||
| cell_volume = (x_cc(1) - x_cc(0))*(y_cc(1) - y_cc(0)) ! computed without grid stretching. Update in the loop to perform with stretching | ||||||||||||||||||
| if (p /= 0) then | ||||||||||||||||||
| cell_volume = cell_volume*(z_cc(1) - z_cc(0)) | ||||||||||||||||||
| end if | ||||||||||||||||||
|
|
||||||||||||||||||
| $:GPU_PARALLEL_LOOP(private='[position,closest_point_along_axis,vector_to_axis,distance_to_axis]', copy='[moment,count]', copyin='[ib_marker,cell_volume,axis]', collapse=3) | ||||||||||||||||||
| do i = 0, m | ||||||||||||||||||
| do j = 0, j | ||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Loop bound typo in the moment-of-inertia grid scan: the inner loop is written Severity Level: Minor
Suggested change
Why it matters? ⭐The inner loop bound "do j = 0, j" is clearly a typo and will not iterate over the intended grid (uses the loop variable as its own bound). Changing it to "0, n" (or appropriate grid size) fixes a logic bug that would otherwise make the loop a no-op or unpredictable. Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/simulation/m_ibm.fpp
**Line:** 1105:1105
**Comment:**
*Logic Error: Loop bound typo in the moment-of-inertia grid scan: the inner loop is written `do j = 0, j` which uses the loop variable `j` as its own bound and is almost certainly incorrect (will either be a no-op or undefined behavior); it should use the grid size (e.g., `n`) instead.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P0: Loop variable Prompt for AI agents
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P0: Loop bound error: Prompt for AI agents
Suggested change
|
||||||||||||||||||
| do k = 0, p | ||||||||||||||||||
|
Comment on lines
+1102
to
+1105
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Loop uses On line 1104, the loop $:GPU_PARALLEL_LOOP(private='[position,closest_point_along_axis,vector_to_axis,distance_to_axis]', copy='[moment,count]', copyin='[ib_marker,cell_volume,axis]', collapse=3)
do i = 0, m
- do j = 0, j
+ do j = 0, n
do k = 0, p📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
| if (ib_markers%sf(i, j, k) == ib_marker) then | ||||||||||||||||||
| $:GPU_ATOMIC(atomic='update') | ||||||||||||||||||
| count = count + 1 ! increment the count of total cells in the boundary | ||||||||||||||||||
|
|
||||||||||||||||||
| ! get the position in local coordinates so that the axis passes through 0, 0, 0 | ||||||||||||||||||
| if (p == 0) then | ||||||||||||||||||
| position = [x_cc(i), y_cc(j), 0._wp] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, 0._wp] | ||||||||||||||||||
| else | ||||||||||||||||||
| position = [x_cc(i), y_cc(j), z_cc(k)] - [patch_ib(ib_marker)%x_centroid, patch_ib(ib_marker)%y_centroid, patch_ib(ib_marker)%z_centroid] | ||||||||||||||||||
| end if | ||||||||||||||||||
|
|
||||||||||||||||||
| ! project the position along the axis to find the closest distance to the rotation axis | ||||||||||||||||||
| closest_point_along_axis = axis*dot_product(axis, position) | ||||||||||||||||||
| vector_to_axis = position - closest_point_along_axis | ||||||||||||||||||
| distance_to_axis = sum(vector_to_axis) ! saves the distance to the axis squared | ||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect distance calculation - missing square root and squaring. The -distance_to_axis = sum(vector_to_axis) ! saves the distance to the axis squared
+distance_to_axis = sum(vector_to_axis**2) ! distance squared to the rotation axis📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Incorrect distance calculation: Prompt for AI agents
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. P1: Incorrect distance calculation: Prompt for AI agents
Suggested change
|
||||||||||||||||||
|
|
||||||||||||||||||
| ! compute the position component of the moment | ||||||||||||||||||
| $:GPU_ATOMIC(atomic='update') | ||||||||||||||||||
| moment = moment + distance_to_axis | ||||||||||||||||||
| end if | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| end do | ||||||||||||||||||
| $:END_GPU_PARALLEL_LOOP() | ||||||||||||||||||
|
|
||||||||||||||||||
| ! write the final moment assuming the points are all uniform density | ||||||||||||||||||
| patch_ib(ib_marker)%moment = moment*patch_ib(ib_marker)%mass/(count*cell_volume) | ||||||||||||||||||
| $:GPU_UPDATE(device='[patch_ib(ib_marker)%moment]') | ||||||||||||||||||
| end if | ||||||||||||||||||
|
|
||||||||||||||||||
| end subroutine s_compute_moment_of_inertia | ||||||||||||||||||
|
|
||||||||||||||||||
| function cross_product(a, b) result(c) | ||||||||||||||||||
| implicit none | ||||||||||||||||||
| real(wp), intent(in) :: a(3), b(3) | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -611,6 +611,8 @@ contains | |||||||||
| 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 | ||||||||||
| call s_compute_ib_forces(q_prim_vf(E_idx)%sf(0:m, 0:n, 0:p)) ! compute the force and torque on the IB from the fluid | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Unsafe use of Severity Level: Critical 🚨
Suggested change
Why it matters? ⭐This is a valid runtime-safety concern: q_prim_vf is only allocated in initialization when (.not. igr). Prompt for AI Agent 🤖This is a comment left during a code review.
**Path:** src/simulation/m_time_steppers.fpp
**Line:** 614:614
**Comment:**
*Possible Bug: Unsafe use of `q_prim_vf` when computing IB forces: `q_prim_vf` is only allocated in initialization when `.not. igr`. Calling `s_compute_ib_forces(q_prim_vf(E_idx)%sf(...))` without guarding for `igr` can dereference an unallocated array and crash when `igr` is true. Wrap the call in a guard so it's only executed when `q_prim_vf` is available.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise. |
||||||||||
|
|
||||||||||
| do i = 1, num_ibs | ||||||||||
| if (s == 1) then | ||||||||||
| patch_ib(i)%step_vel = patch_ib(i)%vel | ||||||||||
|
|
@@ -621,14 +623,22 @@ contains | |||||||||
| 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) | ||||||||||
| if (patch_ib(i)%moving_ibm > 0) then | ||||||||||
| patch_ib(i)%vel = (rk_coef(s, 1)*patch_ib(i)%step_vel + rk_coef(s, 2)*patch_ib(i)%vel)/rk_coef(s, 4) | ||||||||||
| patch_ib(i)%angular_vel = (rk_coef(s, 1)*patch_ib(i)%step_angular_vel + rk_coef(s, 2)*patch_ib(i)%angular_vel)/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 | ||||||||||
| if (patch_ib(i)%moving_ibm == 2) then ! if we are using two-way coupling, apply force and torque | ||||||||||
| ! update the velocity from the force value | ||||||||||
| patch_ib(i)%vel = patch_ib(i)%vel + rk_coef(s, 3)*dt*(patch_ib(i)%force/patch_ib(i)%mass)/rk_coef(s, 4) | ||||||||||
|
|
||||||||||
| ! update the angular velocity with the torque value | ||||||||||
| patch_ib(i)%angular_vel = (patch_ib(i)%angular_vel*patch_ib(i)%moment) + (rk_coef(s, 3)*dt*patch_ib(i)%torque/rk_coef(s, 4)) ! add the torque to the angular momentum | ||||||||||
| call s_compute_moment_of_inertia(i, patch_ib(i)%angular_vel) ! update the moment of inertia to be based on the direction of the angular momentum | ||||||||||
| patch_ib(i)%angular_vel = patch_ib(i)%angular_vel/patch_ib(i)%moment ! convert back to angular velocity with the new moment of inertia | ||||||||||
| end if | ||||||||||
|
|
||||||||||
| ! Update the angle of the IB | ||||||||||
| patch_ib(i)%angles = (rk_coef(s, 1)*patch_ib(i)%step_angles + rk_coef(s, 2)*patch_ib(i)%angles + rk_coef(s, 3)*patch_ib(i)%angular_vel*dt)/rk_coef(s, 4) | ||||||||||
|
|
||||||||||
| ! 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) | ||||||||||
|
|
||||||||||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: Incorrect comment: Comment says "z-axis rotation" but this line sets the
massparameter. This appears to be a copy-paste error.Prompt for AI agents