Skip to content

Commit 12e7818

Browse files
author
LasNikas
committed
Merge branch 'main' into oriented-bbox
2 parents 70860ad + 418c9c2 commit 12e7818

File tree

14 files changed

+6185
-6177
lines changed

14 files changed

+6185
-6177
lines changed

examples/fsi/dam_break_gate_2d.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ clamped_particles = RectangularShape(structure_particle_spacing,
9696
(n_particles_x, 1), (plate_position, 0.0),
9797
density=structure_density, place_on_shell=true)
9898

99-
structure = union(plate, clamped_particles)
99+
structure = union(clamped_particles, plate)
100100

101101
# ==========================================================================================
102102
# ==== Fluid
@@ -147,7 +147,7 @@ structure_system = TotalLagrangianSPHSystem(structure,
147147
structure_smoothing_kernel,
148148
structure_smoothing_length,
149149
E, nu, boundary_model=boundary_model_structure,
150-
n_clamped_particles=n_particles_x,
150+
clamped_particles=1:nparticles(clamped_particles),
151151
acceleration=(0.0, -gravity))
152152

153153
# ==========================================================================================

examples/fsi/dam_break_plate_2d.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ clamped_particles = RectangularShape(structure_particle_spacing,
7070
(n_particles_x, 1), plate_position,
7171
density=structure_density, place_on_shell=true)
7272

73-
structure = union(plate, clamped_particles)
73+
structure = union(clamped_particles, plate)
7474

7575
# ==========================================================================================
7676
# ==== Fluid
@@ -127,7 +127,7 @@ structure_system = TotalLagrangianSPHSystem(structure,
127127
structure_smoothing_kernel,
128128
structure_smoothing_length,
129129
E, nu, boundary_model=boundary_model_structure,
130-
n_clamped_particles=n_particles_x,
130+
clamped_particles=1:nparticles(clamped_particles),
131131
acceleration=(0.0, -gravity),
132132
penalty_force=PenaltyForceGanzenmueller(alpha=0.01))
133133

examples/fsi/falling_water_column_2d.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ structure_system = TotalLagrangianSPHSystem(structure,
6868
smoothing_kernel, smoothing_length,
6969
material.E, material.nu,
7070
boundary_model=boundary_model,
71-
n_clamped_particles=nparticles(clamped_particles),
71+
clamped_particles=1:nparticles(clamped_particles),
7272
acceleration=(0.0, -gravity))
7373

7474
# ==========================================================================================

examples/structure/oscillating_beam_2d.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ n_particles_per_dimension = (round(Int, elastic_beam.length / particle_spacing)
5252
beam = RectangularShape(particle_spacing, n_particles_per_dimension,
5353
(0.0, 0.0), density=material.density, place_on_shell=true)
5454

55-
structure = union(beam, clamped_particles)
55+
structure = union(clamped_particles, beam)
5656

5757
# ==========================================================================================
5858
# ==== Structure
@@ -61,7 +61,7 @@ smoothing_kernel = WendlandC2Kernel{2}()
6161

6262
structure_system = TotalLagrangianSPHSystem(structure, smoothing_kernel, smoothing_length,
6363
material.E, material.nu,
64-
n_clamped_particles=nparticles(clamped_particles),
64+
clamped_particles=1:nparticles(clamped_particles),
6565
acceleration=(0.0, -gravity),
6666
penalty_force=nothing, viscosity=nothing,
6767
clamped_particles_motion=nothing)

src/general/initial_condition.jl

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,3 +415,35 @@ function find_too_close_particles(coords, min_distance)
415415

416416
return result
417417
end
418+
419+
function move_particles_to_end!(ic::InitialCondition, particle_ids_to_move)
420+
invalid_id = findfirst(i -> i <= 0 || i > nparticles(ic), particle_ids_to_move)
421+
isnothing(invalid_id) || throw(BoundsError(ic, invalid_id))
422+
423+
sort_key = [i in particle_ids_to_move ? 1 : 0 for i in eachparticle(ic)]
424+
# Determine a permutation that sorts 'sort_key' in ascending order
425+
permutation = sortperm(sort_key)
426+
427+
ic.coordinates .= ic.coordinates[:, permutation]
428+
ic.velocity .= ic.velocity[:, permutation]
429+
ic.mass .= ic.mass[permutation]
430+
ic.density .= ic.density[permutation]
431+
ic.pressure .= ic.pressure[permutation]
432+
433+
return ic
434+
end
435+
436+
function move_particles_to_end!(a::AbstractVector, particle_ids_to_move)
437+
invalid_id = findfirst(i -> i <= 0 || i > length(a), particle_ids_to_move)
438+
isnothing(invalid_id) || throw(BoundsError(a, invalid_id))
439+
440+
sort_key = [i in particle_ids_to_move ? 1 : 0 for i in eachindex(a)]
441+
# determine a permutation that sorts 'sort_key' in ascending order
442+
permutation = sortperm(sort_key)
443+
444+
a .= a[permutation]
445+
446+
return a
447+
end
448+
449+
move_particles_to_end!(a::Real, particle_ids_to_move) = a

src/general/interpolation.jl

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,7 @@ function interpolate_plane_3d(point1, point2, point3, resolution, semi, ref_syst
300300
throw(ArgumentError("`interpolate_plane_3d` requires a 3D simulation"))
301301
end
302302

303-
points_coords, resolution_ = sample_plane((point1, point2, point3), resolution)
304-
305-
if !isapprox(resolution, resolution_, rtol=5e-2)
306-
@info "The desired plane size is not a multiple of the resolution $resolution." *
307-
"\nNew resolution is set to $resolution_."
308-
end
303+
points_coords = sample_face_with_fixed_size((point1, point2, point3), resolution)
309304

310305
# Interpolate using the generated points
311306
results = interpolate_points(points_coords, semi, ref_system, v_ode, u_ode;
@@ -766,3 +761,49 @@ function divide_by_shepard_coefficient!(field::AbstractArray{T, 3}, shepard_coef
766761

767762
return field
768763
end
764+
765+
function sample_face_with_fixed_size(face_points::NTuple{3}, resolution)
766+
# Verify that points are in 3D space
767+
if any(length.(face_points) .!= 3)
768+
throw(ArgumentError("all points must be 3D coordinates"))
769+
end
770+
771+
point1_ = SVector{3}(face_points[1])
772+
point2_ = SVector{3}(face_points[2])
773+
point3_ = SVector{3}(face_points[3])
774+
775+
# Vectors defining the edges of the parallelogram
776+
edge1 = point2_ - point1_
777+
edge2 = point3_ - point1_
778+
779+
# Check if the points are collinear
780+
if isapprox(norm(cross(edge1, edge2)), 0; atol=eps())
781+
throw(ArgumentError("the vectors `AB` and `AC` must not be collinear"))
782+
end
783+
784+
# Determine the number of points along each edge
785+
num_points_edge1 = ceil(Int, norm(edge1) / resolution)
786+
num_points_edge2 = ceil(Int, norm(edge2) / resolution)
787+
788+
coords = zeros(3, (num_points_edge1 + 1) * (num_points_edge2 + 1))
789+
790+
index = 1
791+
for i in 0:num_points_edge1
792+
for j in 0:num_points_edge2
793+
point_on_plane = point1_ + (i / num_points_edge1) * edge1 +
794+
(j / num_points_edge2) * edge2
795+
coords[:, index] = point_on_plane
796+
index += 1
797+
end
798+
end
799+
800+
resolution_new = min(norm(edge1 / num_points_edge1),
801+
norm(edge2 / num_points_edge2))
802+
803+
if !isapprox(resolution, resolution_new, rtol=sqrt(eps(resolution)))
804+
@info "The desired face size is not a multiple of the resolution $resolution." *
805+
"\nNew resolution is set to $resolution_new."
806+
end
807+
808+
return coords
809+
end

src/schemes/structure/total_lagrangian_sph/system.jl

Lines changed: 62 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
@doc raw"""
22
TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing_length,
33
young_modulus, poisson_ratio;
4-
n_clamped_particles=0, clamped_particles_motion=nothing,
5-
boundary_model=nothing,
4+
n_clamped_particles=0,
5+
clamped_particles=Int[],
6+
clamped_particles_motion=nothing,
67
acceleration=ntuple(_ -> 0.0, NDIMS),
7-
penalty_force=nothing, source_terms=nothing)
8+
penalty_force=nothing, viscosity=nothing,
9+
source_terms=nothing, boundary_model=nothing)
810
911
System for particles of an elastic structure.
1012
@@ -23,9 +25,13 @@ See [Total Lagrangian SPH](@ref tlsph) for more details on the method.
2325
See [Smoothing Kernels](@ref smoothing_kernel).
2426
2527
# Keywords
26-
- `n_clamped_particles`: Number of clamped particles which are fixed and not integrated
27-
to clamp the structure. Note that the clamped particles must be the **last**
28-
particles in the `InitialCondition`. See the info box below.
28+
- `n_clamped_particles` (deprecated): Number of clamped particles that are fixed and not integrated
29+
to clamp the structure. Note that the clamped particles must be the **last**
30+
particles in the `InitialCondition`. See the info box below.
31+
This keyword is deprecated and will be removed in a future release.
32+
Instead pass `clamped_particles` with the explicit particle indices to be clamped.
33+
- `clamped_particles`: Indices specifying the clamped particles that are fixed
34+
and not integrated to clamp the structure.
2935
- `clamped_particles_motion`: Prescribed motion of the clamped particles.
3036
If `nothing` (default), the clamped particles are fixed.
3137
See [`PrescribedMotion`](@ref) for details.
@@ -43,7 +49,8 @@ See [Total Lagrangian SPH](@ref tlsph) for more details on the method.
4349
See, for example, [`SourceTermDamping`](@ref).
4450
4551
!!! note
46-
The clamped particles must be the **last** particles in the `InitialCondition`.
52+
If specifying the clamped particles manually (via `n_clamped_particles`),
53+
the clamped particles must be the **last** particles in the `InitialCondition`.
4754
To do so, e.g. use the `union` function:
4855
```jldoctest; output = false, setup = :(clamped_particles = RectangularShape(0.1, (1, 4), (0.0, 0.0), density=1.0); beam = RectangularShape(0.1, (3, 4), (0.1, 0.0), density=1.0))
4956
structure = union(beam, clamped_particles)
@@ -90,12 +97,13 @@ end
9097

9198
function TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing_length,
9299
young_modulus, poisson_ratio;
93-
n_clamped_particles=0, clamped_particles_motion=nothing,
94-
boundary_model=nothing,
100+
n_clamped_particles=0,
101+
clamped_particles=Int[],
102+
clamped_particles_motion=nothing,
95103
acceleration=ntuple(_ -> 0.0,
96104
ndims(smoothing_kernel)),
97105
penalty_force=nothing, viscosity=nothing,
98-
source_terms=nothing)
106+
source_terms=nothing, boundary_model=nothing)
99107
NDIMS = ndims(initial_condition)
100108
ELTYPE = eltype(initial_condition)
101109
n_particles = nparticles(initial_condition)
@@ -110,30 +118,63 @@ function TotalLagrangianSPHSystem(initial_condition, smoothing_kernel, smoothing
110118
throw(ArgumentError("`acceleration` must be of length $NDIMS for a $(NDIMS)D problem"))
111119
end
112120

113-
initial_coordinates = copy(initial_condition.coordinates)
114-
current_coordinates = copy(initial_condition.coordinates)
115-
mass = copy(initial_condition.mass)
116-
material_density = copy(initial_condition.density)
121+
# Backwards compatibility: `n_clamped_particles` is deprecated.
122+
# Emit a deprecation warning and (if the user didn't supply explicit indices)
123+
# convert the old `n_clamped_particles` convention to `clamped_particles`.
124+
if n_clamped_particles != 0
125+
Base.depwarn("keyword `n_clamped_particles` is deprecated and will be removed in a future release; " *
126+
"pass `clamped_particles` (Vector{Int} of indices) instead.",
127+
:n_clamped_particles)
128+
if isempty(clamped_particles)
129+
clamped_particles = collect((n_particles - n_clamped_particles + 1):n_particles)
130+
else
131+
throw(ArgumentError("Either `n_clamped_particles` or `clamped_particles` can be specified, not both."))
132+
end
133+
end
134+
135+
# Handle clamped particles
136+
if !isempty(clamped_particles)
137+
@assert allunique(clamped_particles) "`clamped_particles` contains duplicate particle indices"
138+
139+
n_clamped_particles = length(clamped_particles)
140+
initial_condition_sorted = deepcopy(initial_condition)
141+
young_modulus_sorted = copy(young_modulus)
142+
poisson_ratio_sorted = copy(poisson_ratio)
143+
move_particles_to_end!(initial_condition_sorted, clamped_particles)
144+
move_particles_to_end!(young_modulus_sorted, clamped_particles)
145+
move_particles_to_end!(poisson_ratio_sorted, clamped_particles)
146+
else
147+
initial_condition_sorted = initial_condition
148+
young_modulus_sorted = young_modulus
149+
poisson_ratio_sorted = poisson_ratio
150+
end
151+
152+
initial_coordinates = copy(initial_condition_sorted.coordinates)
153+
current_coordinates = copy(initial_condition_sorted.coordinates)
154+
mass = copy(initial_condition_sorted.mass)
155+
material_density = copy(initial_condition_sorted.density)
117156
correction_matrix = Array{ELTYPE, 3}(undef, NDIMS, NDIMS, n_particles)
118157
pk1_corrected = Array{ELTYPE, 3}(undef, NDIMS, NDIMS, n_particles)
119158
deformation_grad = Array{ELTYPE, 3}(undef, NDIMS, NDIMS, n_particles)
120159

121160
n_integrated_particles = n_particles - n_clamped_particles
122161

123-
lame_lambda = @. young_modulus * poisson_ratio /
124-
((1 + poisson_ratio) * (1 - 2 * poisson_ratio))
125-
lame_mu = @. (young_modulus / 2) / (1 + poisson_ratio)
162+
lame_lambda = @. young_modulus_sorted * poisson_ratio_sorted /
163+
((1 + poisson_ratio_sorted) *
164+
(1 - 2 * poisson_ratio_sorted))
165+
lame_mu = @. (young_modulus_sorted / 2) / (1 + poisson_ratio_sorted)
126166

127167
ismoving = Ref(!isnothing(clamped_particles_motion))
128-
initialize_prescribed_motion!(clamped_particles_motion, initial_condition,
168+
initialize_prescribed_motion!(clamped_particles_motion, initial_condition_sorted,
129169
n_clamped_particles)
130170

131-
cache = create_cache_tlsph(clamped_particles_motion, initial_condition)
171+
cache = create_cache_tlsph(clamped_particles_motion, initial_condition_sorted)
132172

133-
return TotalLagrangianSPHSystem(initial_condition, initial_coordinates,
173+
return TotalLagrangianSPHSystem(initial_condition_sorted, initial_coordinates,
134174
current_coordinates, mass, correction_matrix,
135175
pk1_corrected, deformation_grad, material_density,
136-
n_integrated_particles, young_modulus, poisson_ratio,
176+
n_integrated_particles, young_modulus_sorted,
177+
poisson_ratio_sorted,
137178
lame_lambda, lame_mu, smoothing_kernel,
138179
smoothing_length, acceleration_, boundary_model,
139180
penalty_force, viscosity, source_terms,

0 commit comments

Comments
 (0)