Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
9d9f125
Added wall detection algorithm for all IBs
danieljvickers Mar 2, 2026
da74f22
Finished wall collisions
danieljvickers Mar 2, 2026
47895c7
Put in all of the collision detection and most of the force calculati…
danieljvickers Mar 3, 2026
45c8584
Initial pass at collisions finished
danieljvickers Mar 4, 2026
6e81d56
Swap logical with a model selection
danieljvickers Mar 4, 2026
87b877f
More debugging
danieljvickers Mar 4, 2026
59f73fd
Compiles, but seg fault
danieljvickers Mar 4, 2026
8585b80
Collisions are working
danieljvickers Mar 4, 2026
a492c91
Fixed various seg fault and allocation bugs occuring at end of program.
danieljvickers Mar 5, 2026
09fcf7a
Works partially on GPU
danieljvickers Mar 5, 2026
b4bafee
Some slight adjustments and verified 3D
danieljvickers Mar 5, 2026
a7b5d28
Collision debugging
danieljvickers Mar 6, 2026
8feb3aa
Found some sign errors that explain odd behavior
danieljvickers Mar 7, 2026
4588c7d
Found an array resizing bug
danieljvickers Mar 7, 2026
51dee59
Improvements to GB-based detection algorithm
danieljvickers Mar 9, 2026
bf87072
First pass at adding periodicity
danieljvickers Mar 9, 2026
5b0560d
Small updates
danieljvickers Mar 9, 2026
8d5ba2f
Found a major MPI error
danieljvickers Mar 9, 2026
0b5a691
Swapping out bc_x with an Ib specific one that is protected from bein…
danieljvickers Mar 10, 2026
0c61be8
Merge branch 'ib-collisions' of github.com:danieljvickers/MFC-Dan int…
danieljvickers Mar 10, 2026
343155a
Significant debugging to prevent seg faults and MPI errors
danieljvickers Mar 10, 2026
24106de
More debugging and rendering of periodic collisions
danieljvickers Mar 10, 2026
50cd221
New example for colliding spheres
danieljvickers Mar 11, 2026
97657be
Verified spring stiffness and coefficient of restitution give sensica…
danieljvickers Mar 11, 2026
6e13913
Added a wall collision example and updated collisions to take in rota…
danieljvickers Mar 13, 2026
4884fe8
Merge branch 'MFlowCode:master' into ib-collisions
danieljvickers Mar 13, 2026
4273c84
Remove interior point conservative variable protection for stationary…
danieljvickers Mar 15, 2026
4b2f519
Merge branch 'master' of github.com:danieljvickers/MFC
danieljvickers Mar 15, 2026
ba0cacb
Merge branch 'MFlowCode:master' into master
danieljvickers Mar 17, 2026
924d49a
merge conflicts with master
danieljvickers Mar 17, 2026
e6988ba
Merge branch 'MFlowCode:master' into master
danieljvickers Mar 17, 2026
c895b6d
Merge branch 'MFlowCode:master' into ib-collisions
danieljvickers Mar 17, 2026
0ce6f11
Merge branch 'MFlowCode:master' into master
danieljvickers Mar 18, 2026
a16ef2b
Merge branch 'MFlowCode:master' into ib-collisions
danieljvickers Mar 18, 2026
f6bc470
Separated max array sizes of ICPP and IB from each other
danieljvickers Mar 18, 2026
8c51cf9
Works on frontier
Mar 18, 2026
711ac53
Small corrections to case file
Mar 18, 2026
fd5a5fa
Spelling
Mar 18, 2026
7f45be1
Fixed sphere bounds checking
Mar 20, 2026
16bd456
Merge branch 'MFlowCode:master' into master
danieljvickers Mar 24, 2026
b41853e
Merge branch 'MFlowCode:master' into ib-collisions
danieljvickers Mar 24, 2026
ad279ba
Make rotational frames consistent across code
danieljvickers Mar 24, 2026
3703741
Restart support and refactored ib state writing
danieljvickers Mar 24, 2026
80df8c9
Moved ib data to restart so that it is copied for batch mode
danieljvickers Mar 26, 2026
38c332f
Add flushing to save Ib state data periodically
danieljvickers Mar 26, 2026
a25c965
This version of restart appears to work
Mar 29, 2026
f0e117d
Merge branch 'MFlowCode:master' into master
danieljvickers Apr 1, 2026
ad545cb
Resolve merge conflicts
danieljvickers Apr 1, 2026
1500d11
fix new example case file
danieljvickers Apr 1, 2026
59f802c
Documentation changes
danieljvickers Apr 1, 2026
3e896dd
Removed left over merge syntax
danieljvickers Apr 1, 2026
c66427f
Some more compile solves, debugging, and added exmaple golden files
danieljvickers Apr 1, 2026
0e3fca9
Another small change to case
danieljvickers Apr 1, 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
12 changes: 12 additions & 0 deletions docs/documentation/case.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ This is enabled by adding ``'elliptic_smoothing': "T",`` and ``'elliptic_smoothi
| `moving_ibm` | Integer | Sets the method used for IB movement. |
| `vel(i)` | Real | Initial velocity of the moving IB in the i-th direction. |
| `angular_vel(i)` | Real | Initial angular velocity of the moving IB in the i-th direction. |
| `coefficient_of_restitution` | Real | A number 0 to 1 describing how elastic IB collisions are |
| `collision_model` | Integer | Integer to select the collision model being used for IB collisions. |
| `collision_time` | Real | Amount of simulation time used to resolve collisions |
| `ib_coefficient_of_friction` | Real | Coefficient of friction used in IB collisions |

These parameters should be prepended with `patch_ib(j)%` where $j$ is the patch index.

Expand Down Expand Up @@ -361,6 +365,14 @@ Additional details on this specification can be found in [NACA airfoil](https://

- `angular_vel(i)` is the initial angular velocity of the IB about the x, y, z axes for i=1, 2, 3 in radians per second. When `moving_ibm` equals 2, this rotation rate is just the starting rate of the object, which will then change due to external torques. If `moving_ibm` equals 1, then this is constant if it is a number, or can be described analytically with an expression.

- `coefficient_of_restitution` is a number from 0 (exclusive) to 1 (inclusive) describing how elastic IB collisions are. 0 is for perfectly inellastic collisions while 1 is for perfectly ellastic collisions.

- `collision_model` is an integer to select the collision model being used for IB collisions. Using 0 disables collisions and collisiono checking. 1 enables the soft-sphere collision model, where all IBs must be circles or sphere and those IBs can collide with each other as well as walls.

- `collision_time` is approximately the amount of simulation time used to resolve collisions. This is handled by modifying the spring gonstant used to apply collision forces.

- `ib_coefficient_of_friction` is the coefficient of friction used in IB collisions.

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

| Parameter | Type | Description |
Expand Down
3 changes: 2 additions & 1 deletion docs/module_categories.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"m_chemistry",
"m_acoustic_src",
"m_body_forces",
"m_pressure_relaxation"
"m_pressure_relaxation",
"m_collisions"
]
},
{
Expand Down
129 changes: 129 additions & 0 deletions examples/3D_mibm_sphere_head_on_collision/case.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import json
import math

# This case file is based on verification cases run in
# "Analytical solution for the problem of frictional-elastic collisions
# of spherical particles using the linear model"
# by Francesco Paolo Di Maio and Alberto Di Renzo

# This can be used to check collision rebound angles to recreate
# figure 4 of that paper

Mu = 1.84e-05
gam_a = 1.4

# lead-up-properties
velocity = 3.9
dt = 5.0e-6
collision_time = 20.0 * dt

# parerticle properties
radius = 5e-3
collision_angle_degrees = 30.0
collision_angle_radians = collision_angle_degrees * math.pi / 180.0
domain_size = 3.0 * radius
lead_distance = 0.02 * radius

# simulation runs long enough to collide and travel about lead distance away again
simulation_time = 2.0 * (lead_distance / velocity) + collision_time
num_time_steps = int(simulation_time / dt)
num_saves = 10
t_step_save = int(num_time_steps / num_saves)

# Configuring case dictionary
print(
json.dumps(
{
# Logistics
"run_time_info": "T",
# Computational Domain Parameters
"x_domain%beg": 0.0,
"x_domain%end": domain_size,
"y_domain%beg": 0.0,
"y_domain%end": domain_size,
"z_domain%beg": 0.0,
"z_domain%end": domain_size,
"cyl_coord": "F",
"m": 60,
"n": 60,
"p": 60,
"dt": dt,
"t_step_start": 0,
"t_step_stop": num_time_steps,
"t_step_save": t_step_save,
# Simulation Algorithm Parameters
"num_patches": 1,
# Use the 5 equation model
"model_eqns": 2,
"alt_soundspeed": "F",
# One fluids: air
"num_fluids": 1,
"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_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": -15,
"bc_y%end": -15,
"bc_z%beg": -3,
"bc_z%end": -3,
# Set IB to True and add 1 patch
"ib": "T",
"num_ibs": 1,
# 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": 9,
"patch_icpp(1)%x_centroid": 0.5 * domain_size,
"patch_icpp(1)%y_centroid": 0.5 * domain_size,
"patch_icpp(1)%z_centroid": 0.5 * domain_size,
"patch_icpp(1)%length_x": domain_size,
"patch_icpp(1)%length_y": domain_size,
"patch_icpp(1)%length_z": domain_size,
# Specify the patch primitive variables
"patch_icpp(1)%vel(1)": 0.0e00,
"patch_icpp(1)%vel(2)": 0.0e00,
"patch_icpp(1)%vel(3)": 0.0e00,
"patch_icpp(1)%pres": 1.0e00,
"patch_icpp(1)%alpha_rho(1)": 1.0e00,
"patch_icpp(1)%alpha(1)": 1.0e00,
# Patch: Sphere Immersed Boundary
"patch_ib(1)%geometry": 8,
"patch_ib(1)%x_centroid": -1.0 * lead_distance * math.sin(collision_angle_radians), # get a lead up distance to the collision
"patch_ib(1)%y_centroid": radius + lead_distance * math.sin(collision_angle_radians),
"patch_ib(1)%z_centroid": 0.0,
"patch_ib(1)%radius": radius,
"patch_ib(1)%slip": "F",
"patch_ib(1)%mass": 1.0e6, # arbitrarily high mass to ignore fluid
"patch_ib(1)%vel(1)": velocity * math.sin(collision_angle_radians),
"patch_ib(1)%vel(2)": -velocity * math.cos(collision_angle_radians),
"patch_ib(1)%moving_ibm": 2,
# Collisions
"collision_model": 1, # soft-sphere collision model
"ib_coefficient_of_friction": 0.092,
"collision_time": collision_time,
"coefficient_of_restitution": 0.98, # almost perfectly elastic
# Fluids Physical Parameters
"fluid_pp(1)%gamma": 1.0e00 / (gam_a - 1.0e00), # 2.50(Not 1.40)
"fluid_pp(1)%pi_inf": 0,
}
)
)
3 changes: 2 additions & 1 deletion src/common/m_constants.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ module m_constants
integer, parameter :: fourier_rings = 5 !< Fourier filter ring limit
integer, parameter :: num_fluids_max = 10 !< Maximum number of fluids in the simulation
integer, parameter :: num_probes_max = 10 !< Maximum number of flow probes in the simulation
integer, parameter :: num_patches_max = 1000 !< Maximum number of IC patches
integer, parameter :: num_patches_max = 10 !< Maximum number of IC patches
integer, parameter :: num_ib_patches_max = 50000 !< Maximum number of immersed boundary patches (patch_ib)
integer, parameter :: num_bc_patches_max = 10 !< Maximum number of boundary condition patches
integer, parameter :: max_2d_fourier_modes = 10 !< Max Fourier mode index for 2D modal patch (geometry 13)
integer, parameter :: max_sph_harm_degree = 5 !< Max degree L for 3D spherical harmonic patch (geometry 14)
Expand Down
19 changes: 17 additions & 2 deletions src/common/m_helper.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module m_helper
public :: s_comp_n_from_prim, s_comp_n_from_cons, s_initialize_bubbles_model, s_initialize_nonpoly, s_simpson, s_transcoeff, &
& s_int_to_str, s_transform_vec, s_transform_triangle, s_transform_model, s_swap, f_cross, f_create_transform_matrix, &
& f_create_bbox, s_print_2D_array, f_xor, f_logical_to_int, associated_legendre, real_ylm, double_factorial, factorial, &
& f_cut_on, f_cut_off, s_downsample_data, s_upsample_data
& f_cut_on, f_cut_off, s_downsample_data, s_upsample_data, s_cross_product

contains

Expand Down Expand Up @@ -297,7 +297,22 @@ contains

end function f_cross

!> Swap two real numbers.
!> @brief Computes the cross product c = a x b of two 3D vectors.
subroutine s_cross_product(a, b, c)

$:GPU_ROUTINE(parallelism='[seq]')
real(wp), intent(in) :: a(3), b(3)
real(wp), intent(out) :: 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 subroutine s_cross_product

!> This procedure swaps two real numbers.
!! @param lhs Left-hand side.
!! @param rhs Right-hand side.
elemental subroutine s_swap(lhs, rhs)

real(wp), intent(inout) :: lhs, rhs
Expand Down
4 changes: 2 additions & 2 deletions src/pre_process/m_global_parameters.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ module m_global_parameters
logical :: ib !< Turn immersed boundaries on
integer :: num_ibs !< Number of immersed boundaries
integer :: Np
type(ib_patch_parameters), dimension(num_patches_max) :: patch_ib !< Immersed boundary patch parameters
type(ib_patch_parameters), dimension(num_ib_patches_max) :: patch_ib !< Immersed boundary patch parameters
type(vec3_dt), allocatable, dimension(:) :: airfoil_grid_u, airfoil_grid_l
!> @}

Expand Down Expand Up @@ -462,7 +462,7 @@ contains
ib = .false.
num_ibs = dflt_int

do i = 1, num_patches_max
do i = 1, num_ib_patches_max
patch_ib(i)%geometry = dflt_int
patch_ib(i)%x_centroid = dflt_real
patch_ib(i)%y_centroid = dflt_real
Expand Down
5 changes: 3 additions & 2 deletions src/pre_process/m_mpi_proxy.fpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ contains
if (chemistry) then
call MPI_BCAST(patch_icpp(i)%Y, size(patch_icpp(i)%Y), mpi_p, 0, MPI_COMM_WORLD, ierr)
end if
! Broadcast IB variables: patch_ib is indexed 1:num_patches_max, not 1:num_bc_patches_max, so these must live in the
! num_patches_max loop.
end do

do i = 1, num_ibs
#:for VAR in ['vel', 'angular_vel', 'angles']
call MPI_BCAST(patch_ib(i)%${VAR}$, size(patch_ib(i)%${VAR}$), mpi_p, 0, MPI_COMM_WORLD, ierr)
#:endfor
Expand Down
Loading
Loading