Skip to content

Commit f35ebe2

Browse files
efaulhaberLasNikassvchb
authored
Implement PrescribedMotion for clamped TLSPH particles (#896)
* Prepare for moving clamped particles * Implement prescribed motion for clamped particles * Fix * Add test * Add docs * Reformat * Fix tests * Fix `current_velocity` * Fix * Fix `system_data` * Fix GPU tests * Implement suggestions --------- Co-authored-by: Niklas Neher <[email protected]> Co-authored-by: Sven Berger <[email protected]>
1 parent e9ae581 commit f35ebe2

File tree

8 files changed

+233
-112
lines changed

8 files changed

+233
-112
lines changed

examples/structure/oscillating_beam_2d.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ structure_system = TotalLagrangianSPHSystem(structure, smoothing_kernel, smoothi
6363
material.E, material.nu,
6464
n_clamped_particles=nparticles(clamped_particles),
6565
acceleration=(0.0, -gravity),
66-
penalty_force=nothing, viscosity=nothing)
66+
penalty_force=nothing, viscosity=nothing,
67+
clamped_particles_motion=nothing)
6768

6869
# ==========================================================================================
6970
# ==== Simulation

src/general/semidiscretization.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,14 @@ end
402402
function initialize_neighborhood_searches!(semi)
403403
foreach_system(semi) do system
404404
foreach_system(semi) do neighbor
405+
# TODO Initialize after adapting to the GPU.
406+
# Currently, this cannot use `semi.parallelization_backend`
407+
# because data is still on the CPU.
405408
PointNeighbors.initialize!(get_neighborhood_search(system, neighbor, semi),
406409
initial_coordinates(system),
407410
initial_coordinates(neighbor),
408-
eachindex_y=each_active_particle(neighbor))
411+
eachindex_y=each_active_particle(neighbor),
412+
parallelization_backend=PolyesterBackend())
409413
end
410414
end
411415

src/io/write_vtk.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,9 @@ function write2vtk!(vtk, v, u, t, system::TotalLagrangianSPHSystem)
381381
initial_coords(system, particle)
382382
for particle in eachparticle(system)]
383383

384+
vtk["is_clamped"] = vcat(fill(0, system.n_integrated_particles),
385+
fill(1, nparticles(system) - system.n_integrated_particles))
386+
384387
vtk["lame_lambda"] = system.lame_lambda
385388
vtk["lame_mu"] = system.lame_mu
386389
vtk["young_modulus"] = system.young_modulus

src/schemes/boundary/prescribed_motion.jl

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
are moving or not. Its boolean return value determines
1111
if the neighborhood search will be updated.
1212
13-
# Keywords
14-
- `moving_particles`: Indices of moving particles. Default is each particle in the system.
13+
# Keyword Arguments
14+
- `moving_particles`: Indices of moving particles. Default is each particle in the system
15+
for the [`WallBoundarySystem`](@ref) and all clamped particles
16+
for the [`TotalLagrangianSPHSystem`](@ref).
1517
1618
# Examples
1719
```jldoctest; output = false
@@ -48,7 +50,9 @@ function PrescribedMotion(movement_function, is_moving; moving_particles=nothing
4850
return PrescribedMotion(movement_function, is_moving, moving_particles)
4951
end
5052

51-
function initialize!(prescribed_motion::PrescribedMotion, initial_condition)
53+
function initialize_prescribed_motion!(prescribed_motion::PrescribedMotion,
54+
initial_condition,
55+
n_clamped_particles=nparticles(initial_condition))
5256
# Test `movement_function` return type
5357
pos = extract_svector(initial_condition.coordinates,
5458
Val(size(initial_condition.coordinates, 1)), 1)
@@ -57,23 +61,34 @@ function initialize!(prescribed_motion::PrescribedMotion, initial_condition)
5761
"Returning regular `Vector`s causes allocations and significant performance overhead."
5862
end
5963

60-
# Empty `moving_particles` means all particles are moving
64+
# Empty `moving_particles` means all clamped particles are moving.
65+
# For boundaries, all particles are considered clamped.
6166
if isempty(prescribed_motion.moving_particles)
6267
# Default is an empty vector, since the number of particles is not known when
6368
# instantiating `PrescribedMotion`.
64-
resize!(prescribed_motion.moving_particles, nparticles(initial_condition))
65-
prescribed_motion.moving_particles .= collect(1:nparticles(initial_condition))
69+
resize!(prescribed_motion.moving_particles, n_clamped_particles)
70+
71+
# Clamped particles for TLSPH are the last `n_clamped_particles` in the system
72+
first_particle = nparticles(initial_condition) - n_clamped_particles + 1
73+
clamped_particles = first_particle:nparticles(initial_condition)
74+
prescribed_motion.moving_particles .= collect(clamped_particles)
6675
end
76+
77+
return prescribed_motion
78+
end
79+
80+
function initialize_prescribed_motion!(::Nothing, initial_condition,
81+
n_clamped_particles=nparticles(initial_condition))
82+
return nothing
6783
end
6884

69-
function (prescribed_motion::PrescribedMotion)(system, t, semi)
70-
(; coordinates, cache) = system
85+
function (prescribed_motion::PrescribedMotion)(coordinates, velocity, acceleration,
86+
ismoving, system, semi, t)
7187
(; movement_function, is_moving, moving_particles) = prescribed_motion
72-
(; acceleration, velocity) = cache
7388

74-
system.ismoving[] = is_moving(t)
89+
ismoving[] = is_moving(t)
7590

76-
is_moving(t) || return system
91+
is_moving(t) || return nothing
7792

7893
@threaded semi for particle in moving_particles
7994
pos_original = initial_coords(system, particle)
@@ -90,13 +105,7 @@ function (prescribed_motion::PrescribedMotion)(system, t, semi)
90105
end
91106
end
92107

93-
return system
94-
end
95-
96-
function (prescribed_motion::Nothing)(system::AbstractSystem, t, semi)
97-
system.ismoving[] = false
98-
99-
return system
108+
return nothing
100109
end
101110

102111
"""

src/schemes/boundary/wall_boundary/system.jl

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,11 @@ function WallBoundarySystem(initial_condition, model; prescribed_motion=nothing,
4242
coordinates = copy(initial_condition.coordinates)
4343

4444
ismoving = Ref(!isnothing(prescribed_motion))
45-
initialize!(prescribed_motion, initial_condition)
45+
initialize_prescribed_motion!(prescribed_motion, initial_condition)
4646

4747
cache = create_cache_boundary(prescribed_motion, initial_condition)
4848
cache = (cache..., color=Int(color_value))
4949

50-
# Because of dispatches boundary model needs to be first!
5150
return WallBoundarySystem(initial_condition, coordinates, model, prescribed_motion,
5251
ismoving, adhesion_coefficient, cache)
5352
end
@@ -105,7 +104,7 @@ end
105104
return current_velocity(v, system, system.prescribed_motion, particle)
106105
end
107106

108-
@inline function current_velocity(v, system, movement, particle)
107+
@inline function current_velocity(v, system, prescribed_motion, particle)
109108
(; cache, ismoving) = system
110109

111110
if ismoving[]
@@ -115,7 +114,7 @@ end
115114
return zero(SVector{ndims(system), eltype(system)})
116115
end
117116

118-
@inline function current_velocity(v, system, movement::Nothing, particle)
117+
@inline function current_velocity(v, system, prescribed_motion::Nothing, particle)
119118
return zero(SVector{ndims(system), eltype(system)})
120119
end
121120

@@ -127,7 +126,8 @@ end
127126
return current_acceleration(system, system.prescribed_motion, particle)
128127
end
129128

130-
@inline function current_acceleration(system, ::PrescribedMotion, particle)
129+
@inline function current_acceleration(system::WallBoundarySystem, ::PrescribedMotion,
130+
particle)
131131
(; cache, ismoving) = system
132132

133133
if ismoving[]
@@ -137,7 +137,7 @@ end
137137
return zero(SVector{ndims(system), eltype(system)})
138138
end
139139

140-
@inline function current_acceleration(system, ::Nothing, particle)
140+
@inline function current_acceleration(system::WallBoundarySystem, ::Nothing, particle)
141141
return zero(SVector{ndims(system), eltype(system)})
142142
end
143143

@@ -177,7 +177,21 @@ end
177177
function update_positions!(system::WallBoundarySystem, v, u, v_ode, u_ode, semi, t)
178178
(; prescribed_motion) = system
179179

180-
prescribed_motion(system, t, semi)
180+
apply_prescribed_motion!(system, prescribed_motion, semi, t)
181+
end
182+
183+
function apply_prescribed_motion!(system::WallBoundarySystem,
184+
prescribed_motion::PrescribedMotion, semi, t)
185+
(; ismoving, coordinates, cache) = system
186+
(; acceleration, velocity) = cache
187+
188+
prescribed_motion(coordinates, velocity, acceleration, ismoving, system, semi, t)
189+
190+
return system
191+
end
192+
193+
function apply_prescribed_motion!(system::WallBoundarySystem, ::Nothing, semi, t)
194+
return system
181195
end
182196

183197
function update_quantities!(system::WallBoundarySystem, v, u, v_ode, u_ode, semi, t)

0 commit comments

Comments
 (0)