Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
103 commits
Select commit Hold shift + click to select a range
deb90dd
Improve GPU performance of TLSPH
efaulhaber Mar 6, 2026
a11ce1f
Move source terms timer behind dispatch
efaulhaber Mar 6, 2026
beee2f7
Reformat
efaulhaber Mar 6, 2026
09e04d3
Fix and add tests
efaulhaber Mar 6, 2026
af05303
Fix return types
efaulhaber Mar 6, 2026
4b05263
Remove source terms timer in split integration
efaulhaber Mar 6, 2026
fc688f0
Implement stage-level coupling for split integration
efaulhaber Jan 16, 2026
fa89692
Fix timers
efaulhaber Jan 16, 2026
aae51b0
Fix first stages
efaulhaber Jan 16, 2026
251cb3f
Implement split integration restart and position prediction
efaulhaber Jan 20, 2026
de28fd7
Reformat
efaulhaber Jan 20, 2026
08abdf2
Fix plotting and `SymplecticPositionVerlet`
efaulhaber Feb 23, 2026
144d804
Update docs
efaulhaber Mar 2, 2026
a2c4d3b
Fix memory "leak" issue
efaulhaber Mar 2, 2026
a033c72
Fix rejected steps
efaulhaber Mar 2, 2026
b8f5add
Fix unit tests
efaulhaber Mar 2, 2026
b2a668e
Fix bibtex warnings
efaulhaber Mar 2, 2026
7c66d99
Make position prediction a kwarg
efaulhaber Mar 2, 2026
d0c7f81
Reformat
efaulhaber Mar 2, 2026
8550f23
Remove unused function
efaulhaber Mar 2, 2026
f10b473
Update docs
efaulhaber Mar 2, 2026
44c4a9a
Fix tests
efaulhaber Mar 2, 2026
6691d78
Fix `u_modified`
efaulhaber Mar 2, 2026
9d7cd8a
Add GPU tests
efaulhaber Mar 2, 2026
a929202
Fix lots of errors with unstable split integration
efaulhaber Mar 2, 2026
aaab550
Remove instability warning
efaulhaber Mar 2, 2026
f09608b
Disable stage-level coupling by default
efaulhaber Mar 2, 2026
35e6ee7
Fix split integration tests
efaulhaber Mar 2, 2026
53ece78
Add kwarg `coordinated_eltype` to example file
efaulhaber Mar 3, 2026
bd7b0c6
Fix rebase
efaulhaber Mar 3, 2026
01e7c3d
Fix `count_allocations`
efaulhaber Mar 3, 2026
8159c1d
Fix tests
efaulhaber Mar 3, 2026
f312fab
Reformat
efaulhaber Mar 3, 2026
a3a18e9
Fix n-body tests
efaulhaber Mar 4, 2026
6b81c9e
Fix tests
efaulhaber Mar 4, 2026
6122a37
Fix GPU tests
efaulhaber Mar 4, 2026
f900463
Fix comment
efaulhaber Mar 4, 2026
56ebb1a
Fix `similar(::ThreadedBroadcastArray, dims)`
efaulhaber Feb 27, 2026
af0280f
Verify sizes
efaulhaber Feb 27, 2026
8add7f3
Implement velocity averaging for TLSPH
efaulhaber Feb 17, 2026
56d91f2
Fix averaged velocity
efaulhaber Feb 23, 2026
4d5dfd5
Fix density diffusion on GPUs
efaulhaber Feb 20, 2026
0e1aefe
Fix interpolation on GPUs
efaulhaber Feb 20, 2026
4f2ac4e
Add comment
efaulhaber Feb 20, 2026
f6d2aa7
Add `EnergyCalculatorCallback`
efaulhaber Sep 24, 2025
9ab4a1d
Improve comments
efaulhaber Oct 6, 2025
b8c37f2
Add docstring
efaulhaber Oct 6, 2025
78613c1
Reformat
efaulhaber Oct 6, 2025
bb915ad
Add tests
efaulhaber Oct 6, 2025
854e591
Add function to retrieve calculated energy
efaulhaber Oct 6, 2025
35056b5
Fix for split integration
efaulhaber Oct 6, 2025
1546a5b
Use `OffsetMatrix` instead of `CombinedMatrix` to avoid allocations
efaulhaber Oct 6, 2025
900b132
Fix return value
efaulhaber Oct 6, 2025
0823882
Fix tests
efaulhaber Oct 6, 2025
21944da
Only calculate energy for a single system
efaulhaber Oct 15, 2025
a66e30a
Implement `only_compute_force_on_fluid`
efaulhaber Oct 15, 2025
6cc8e0c
Fix example test
efaulhaber Oct 15, 2025
7867ba7
Add second test with FSI
efaulhaber Oct 15, 2025
8de5f56
Update docs
efaulhaber Oct 15, 2025
8b28456
Fix unit tests
efaulhaber Dec 10, 2025
f8bd080
Reformat
efaulhaber Dec 10, 2025
258a590
Add test for not all particles clamped
efaulhaber Dec 10, 2025
d4c9f65
Export eachparticle
efaulhaber Dec 22, 2025
ee8deb4
Add first fin simulation
efaulhaber Oct 2, 2024
deb764b
Fix fin simulation
efaulhaber Nov 6, 2024
257b1e1
Use flexural rigidity
efaulhaber May 19, 2025
0606303
Add rotation angle
efaulhaber May 19, 2025
4dbe7f5
Update fin example
efaulhaber May 26, 2025
3c2a21e
Move movement code to TrixiParticles module
efaulhaber May 28, 2025
031d0ea
Fix complex shape offset
efaulhaber Jun 6, 2025
751c521
Add TLSPH acceleration for Adami
efaulhaber Jun 6, 2025
a9e9a6b
Model foot pocket
efaulhaber Jun 6, 2025
29853b8
Fix kernel for FSI
efaulhaber Jun 11, 2025
91fa3b6
Fix fin example
efaulhaber Jun 16, 2025
12fc414
Use Molteni-Colagrossi DD
efaulhaber Jun 16, 2025
e6e9ae9
Use higher resolution to fix BC
efaulhaber Jun 16, 2025
3eb5dd7
Reorganize example file
efaulhaber Jun 16, 2025
c1ef4da
Add packing
efaulhaber Jun 27, 2025
4111a23
Disable boundary pressure clipping
efaulhaber Jul 1, 2025
eb0802c
Add fin DXF and packing window
efaulhaber Jul 1, 2025
42ff662
Use artificial viscosity for TLSPH
efaulhaber Jul 31, 2025
88d8b14
Fix fin example
efaulhaber Sep 3, 2025
9fdbbbe
Fix sound speed
efaulhaber Sep 3, 2025
253d4f7
Update fin example file
efaulhaber Sep 24, 2025
e298ab2
Add open boundaries to fin simulation
efaulhaber Dec 22, 2025
06acd08
Optimize time integration and add periodic option
efaulhaber Dec 24, 2025
d510860
Fix foot rotation
efaulhaber Jan 21, 2026
c721015
Disable boundary pressure clipping
efaulhaber Jan 21, 2026
8e8e9f6
Fix velocity averaging
efaulhaber Feb 17, 2026
719f34d
Implement Kelvin-Vogt damping for TLSPH
efaulhaber Feb 17, 2026
305b702
Add pvd argument to interpolation
efaulhaber Feb 17, 2026
dee0824
Update fin with Antuono, velocity averaging, open boundaries and inte…
efaulhaber Feb 17, 2026
3eae93d
Add simplified fin example file
efaulhaber Feb 17, 2026
0179cf5
Add more buffer particles
efaulhaber Feb 20, 2026
263c024
Add code for extracting tip velocity
efaulhaber Feb 20, 2026
7e4b49f
Fix CFL and open boundaries in fin example
efaulhaber Feb 21, 2026
ca54c78
Fix initial condition for inlet/outlet
efaulhaber Feb 25, 2026
e7d6c77
Quick fix for making the `InitialCondition` type safer
efaulhaber Feb 27, 2026
fbde11b
Merge fluid interaction kernels
efaulhaber Feb 27, 2026
4d4765c
Fix type of prescribed motion
efaulhaber Feb 27, 2026
1664ca9
Fix simplified fin example
efaulhaber Feb 27, 2026
5f19664
Make FP64 coordinates work with the fin
efaulhaber Feb 27, 2026
22c5b6d
Fix fin open boundaries and add velocity averaging
efaulhaber Feb 27, 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
4 changes: 0 additions & 4 deletions docs/src/refs.bib
Original file line number Diff line number Diff line change
Expand Up @@ -939,7 +939,3 @@ @article{Zhu2021
doi = {10.1007/s42241-021-0031-y},
publisher = {Springer Science and Business Media LLC},
}

@Comment{jabref-meta: databaseType:bibtex;}

@Comment{jabref-meta: saveOrderConfig:specified;bibtexkey;false;date;false;abstract;false;}
11 changes: 2 additions & 9 deletions examples/fluid/periodic_channel_2d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,7 @@ extra_callback = nothing
callbacks = CallbackSet(info_callback, saving_callback, extra_callback)

# Use a Runge-Kutta method with automatic (error based) time step size control.
# Limiting of the maximum stepsize is necessary to prevent crashing.
# When particles are approaching a wall in a uniform way, they can be advanced
# with large time steps. Close to the wall, the stepsize has to be reduced drastically.
# Sometimes, the method fails to do so because forces become extremely large when
# fluid particles are very close to boundary particles, and the time integration method
# interprets this as an instability.
sol = solve(ode, RDPK3SpFSAL35(),
abstol=1e-8, # Default abstol is 1e-6 (may need to be tuned to prevent boundary penetration)
reltol=1e-4, # Default reltol is 1e-3 (may need to be tuned to prevent boundary penetration)
dtmax=1e-2, # Limit stepsize to prevent crashing
abstol=1e-8, # Default abstol is 1e-6
reltol=1e-4, # Default reltol is 1e-3
save_everystep=false, callback=callbacks);
193 changes: 193 additions & 0 deletions examples/fluid/vortex_street.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
using TrixiParticles
using OrdinaryDiffEqLowStorageRK

# ==========================================================================================
# ==== Resolution
fluid_particle_spacing = 0.005

# Change spacing ratio to 3 and boundary layers to 1 when using Monaghan-Kajtar boundary model
boundary_layers = 4
spacing_ratio = 1

# ==========================================================================================
# ==== Experiment Setup
# Boundary geometry and initial fluid particle positions
tank_size = (1.0, 0.5)
# tank_size = (0.6, 0.6)
initial_fluid_size = tank_size

Re = 10000
initial_velocity = (0.0, 0.0)
nu = 1 * 1 / Re

tspan = (0.0, 2.0)

fluid_density = 1000.0
sound_speed = 50.0
state_equation = StateEquationCole(; sound_speed, reference_density=fluid_density,
exponent=1, background_pressure=0.0)

tank = RectangularTank(fluid_particle_spacing, initial_fluid_size, tank_size, fluid_density,
n_layers=boundary_layers, spacing_ratio=spacing_ratio,
faces=(false, false, true, true), velocity=initial_velocity)

center = tank_size ./ 2
hollow_sphere = SphereShape(fluid_particle_spacing, 0.1, center, fluid_density,
n_layers=4, sphere_type=RoundSphere())

filled_sphere = SphereShape(fluid_particle_spacing, 0.1, center, fluid_density,
sphere_type=RoundSphere())

# hollow_sphere = RectangularShape(fluid_particle_spacing, round.(Int, (0.1, 0.3) ./ fluid_particle_spacing), center .- 0.15,
# density=fluid_density)
# filled_sphere = hollow_sphere

# using PythonCall
# using CondaPkg

# CondaPkg.add("svgpathtools")
# CondaPkg.add("ezdxf")
# svgpath = pyimport("svgpathtools")

# svg_path = "M509.299 100.016C507.966 91.5871 505.915 85.7111 503.145 82.3879C498.991 77.4031 479.883 60.7871 475.521 58.2947C471.16 55.8023 455.167 49.1559 448.936 47.702C442.705 46.2481 355.471 30.463 339.893 28.8014C329.508 27.6937 287.761 23.5397 214.651 16.3394C199.727 15.7768 185.488 15.1656 171.934 14.5056C151.602 13.5157 106.318 5.19544 82.4982 0.830064C58.6781 -3.53532 3.26262 9.37214 0.279574 38.2664C-2.54326 65.6089 16.5085 89.4186 34.9345 99.2843C49.9801 107.34 58.7166 107.403 71.5338 114.275C101.912 130.564 100.849 169.8 123.353 175.939C145.856 182.078 146.637 180.9 155.986 179.279C162.22 178.199 199.267 168.32 267.129 149.644L359.355 117.398L405.801 102.863C446.849 101.008 472.412 100.061 482.489 100.022C497.605 99.9635 507.524 100.062 509.299 100.016Z"

# path = svgpath.parse_path(svg_path)
# t_range = range(0, 1, length=50 * length(path))
# points = [(pyconvert(Float64, p.real), -pyconvert(Float64, p.imag))
# for p in (path.point(t) for t in t_range)]

# # ezdxf = pyimport("ezdxf")
# # doc = ezdxf.new(dxfversion="R2010")
# # msp = doc.modelspace()
# # msp.add_polyline2d(points)
# # doc.saveas("output.dxf")

# center = tank_size ./ 2
# points_matrix = reinterpret(reshape, Float64, points)
# scaling = 0.3 / maximum(points_matrix, dims=2)[1]
# points_matrix .*= scaling
# points_matrix .+= (-0.15, -points_matrix[2, 1])

# geometry = TrixiParticles.Polygon(points_matrix)

# # trixi2vtk(geometry)

# point_in_geometry_algorithm = WindingNumberJacobson(; geometry,
# winding_number_factor=0.4,
# hierarchical_winding=true)

# # Returns `InitialCondition`
# shape_sampled = ComplexShape(geometry; particle_spacing=fluid_particle_spacing, density=fluid_density,
# store_winding_number=true,
# point_in_geometry_algorithm)

# # angle = pi / 4
# # using StaticArrays
# # rotation_matrix = @SMatrix [cos(angle) -sin(angle)
# # sin(angle) cos(angle)]
# # shape_sampled.initial_condition.coordinates .= rotation_matrix * shape_sampled.initial_condition.coordinates
# shape_sampled.initial_condition.coordinates .+= center

# hollow_sphere = shape_sampled.initial_condition
# filled_sphere = hollow_sphere

# n_particles = round(Int, 0.12 / fluid_particle_spacing)
# cylinder = RectangularShape(fluid_particle_spacing, (n_particles, n_particles), (0.2 - 1.0, 0.24 - 1.0), density=fluid_density)

fluid = setdiff(tank.fluid, filled_sphere)

# ==========================================================================================
# ==== Fluid
smoothing_length = 2 * fluid_particle_spacing
smoothing_kernel = WendlandC2Kernel{2}()

viscosity_fluid = ViscosityAdami(; nu)
# viscosity_fluid = ArtificialViscosityMonaghan(alpha=0.02, beta=0.0)
viscosity_wall = ViscosityAdami(; nu)
density_diffusion = DensityDiffusionMolteniColagrossi(delta=0.1)
fluid_density_calculator = ContinuityDensity()
fluid_system = WeaklyCompressibleSPHSystem(fluid, fluid_density_calculator,
state_equation, smoothing_kernel,
density_diffusion=density_diffusion,
pressure_acceleration=TrixiParticles.tensile_instability_control,
particle_shifting=TrixiParticles.ParticleShiftingSun2019(5.0),
smoothing_length, viscosity=viscosity_fluid)

# ==========================================================================================
# ==== Boundary
boundary_density_calculator = AdamiPressureExtrapolation(pressure_offset=10000.0)
boundary_model = BoundaryModelDummyParticles(tank.boundary.density, tank.boundary.mass,
state_equation=state_equation,
boundary_density_calculator,
smoothing_kernel, smoothing_length)

# Movement function
# https://en.wikipedia.org/wiki/Triangle_wave#Harmonics
# triangle_series(t, N) = 8 / pi^2 * sum(i -> (-1)^i / (2i + 1)^2 * sin(2pi * (2i + 1) * t), 0:(N-1))
# movement_function(x, t) = x + SVector(0.4 * triangle_series(2 * t, 5), 0.0)
# is_moving(t) = true
# boundary_movement = BoundaryMovement(movement_function, is_moving)

boundary_movement = TrixiParticles.oscillating_movement(1.0,
SVector(0.4, 0.0),
0.0, center;
ramp_up=0.5)

boundary_system = BoundarySPHSystem(tank.boundary, boundary_model)

boundary_model_cylinder = BoundaryModelDummyParticles(hollow_sphere.density,
hollow_sphere.mass,
state_equation=state_equation,
boundary_density_calculator,
smoothing_kernel, smoothing_length,
viscosity=viscosity_wall)

boundary_system_cylinder = BoundarySPHSystem(hollow_sphere, boundary_model_cylinder,
movement=boundary_movement)

# boundary_system_cylinder = TotalLagrangianSPHSystem(hollow_sphere, smoothing_kernel, smoothing_length,
# 1e5, 0.0;
# n_fixed_particles=nparticles(hollow_sphere), movement=boundary_movement,
# boundary_model=boundary_model)

# ==========================================================================================
# ==== Simulation
min_corner = minimum(fluid.coordinates, dims=2) .- fluid_particle_spacing / 2
max_corner = maximum(fluid.coordinates, dims=2) .+ fluid_particle_spacing / 2
periodic_box = PeriodicBox(; min_corner, max_corner)
cell_list = FullGridCellList(; min_corner, max_corner)
neighborhood_search = GridNeighborhoodSearch{2}(; periodic_box, cell_list)

semi = Semidiscretization(fluid_system, boundary_system_cylinder;
neighborhood_search)
ode = semidiscretize(semi, tspan)

info_callback = InfoCallback(interval=10)
saving_callback = SolutionSavingCallback(dt=0.01, prefix="")
shifting_callback = ParticleShiftingCallback()

stepsize_callback = StepsizeCallback(cfl=1.5)

callbacks = CallbackSet(info_callback, saving_callback, shifting_callback,
stepsize_callback)

# Use a Runge-Kutta method with automatic (error based) time step size control.
# Limiting of the maximum stepsize is necessary to prevent crashing.
# When particles are approaching a wall in a uniform way, they can be advanced
# with large time steps. Close to the wall, the stepsize has to be reduced drastically.
# Sometimes, the method fails to do so because forces become extremely large when
# fluid particles are very close to boundary particles, and the time integration method
# interprets this as an instability.
# fluid_dt = 1e-3
# sol = solve(ode, RDPK3SpFSAL49(),
# # abstol=1.0e-6, # Default abstol is 1e-6 (may need to be tuned to prevent boundary penetration)
# # reltol=1.0e-4, # Default reltol is 1e-3 (may need to be tuned to prevent boundary penetration)
# adaptive=false, dt=fluid_dt,
# save_everystep=false, callback=callbacks);

time_step = 1.0
sol = solve(ode, CarpenterKennedy2N54(williamson_condition=false),
dt=time_step, # This is overwritten by the stepsize callback
save_everystep=false, callback=callbacks);

# plane = interpolate_plane([0.0, -0.25], [1.0, 0.75], 0.0025, semi, fluid_system, sol)
Loading
Loading