Skip to content

Commit f314552

Browse files
LasNikasLasNikas
andauthored
Fix extrude_geometry (#967)
* fix * fix tests * fix tests * fix test * fix doc tests --------- Co-authored-by: LasNikas <[email protected]>
1 parent 2dbaa50 commit f314552

File tree

7 files changed

+5986
-6149
lines changed

7 files changed

+5986
-6149
lines changed

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/setups/extrude_geometry.jl

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ direction = [0.0, 0.0, 1.0]
6464
shape = extrude_geometry(shape; direction, particle_spacing=0.1, n_extrude=4, density=1000.0)
6565
6666
# output
67-
┌ Info: The desired size is not a multiple of the particle spacing 0.1.
68-
└ New particle spacing is set to 0.09387239731236392.
69-
┌ Info: The desired size is not a multiple of the particle spacing 0.1.
70-
└ New particle spacing is set to 0.09198039027185569.
67+
┌ Info: The desired line length 1.314213562373095 is not a multiple of the particle spacing 0.1.
68+
└ New line length is set to 1.3.
69+
┌ Info: The desired edge 1 length 1.0180339887498948 is not a multiple of the particle spacing 0.1.
70+
└ New edge 1 length is set to 1.0.
71+
┌ Info: The desired edge 2 length 0.9198039027185568 is not a multiple of the particle spacing 0.1.
72+
└ New edge 2 length is set to 0.9.
7173
┌──────────────────────────────────────────────────────────────────────────────────────────────────┐
7274
│ InitialCondition{Float64} │
7375
│ ═════════════════════════ │
@@ -99,16 +101,9 @@ function extrude_geometry(geometry; particle_spacing=-1, direction, n_extrude::I
99101

100102
geometry = shift_plane_corners(geometry, direction_, particle_spacing, place_on_shell)
101103

102-
face_coords,
103-
particle_spacing_ = sample_plane(geometry, particle_spacing;
104-
place_on_shell=place_on_shell)
104+
face_coords = sample_plane(geometry, particle_spacing; place_on_shell=place_on_shell)
105105

106-
if !isapprox(particle_spacing, particle_spacing_, rtol=5e-2)
107-
@info "The desired size is not a multiple of the particle spacing $particle_spacing." *
108-
"\nNew particle spacing is set to $particle_spacing_."
109-
end
110-
111-
coords = (face_coords .+ i * particle_spacing_ * direction_ for i in 0:(n_extrude - 1))
106+
coords = (face_coords .+ i * particle_spacing * direction_ for i in 0:(n_extrude - 1))
112107

113108
# In this context, `stack` is faster than `hcat(coords...)`
114109
coordinates = reshape(stack(coords), (NDIMS, size(face_coords, 2) * n_extrude))
@@ -118,7 +113,7 @@ function extrude_geometry(geometry; particle_spacing=-1, direction, n_extrude::I
118113
end
119114

120115
return InitialCondition(; coordinates, velocity, density, mass, pressure,
121-
particle_spacing=particle_spacing_)
116+
particle_spacing=particle_spacing)
122117
end
123118

124119
# For corners/endpoints of a plane/line, sample the plane/line with particles.
@@ -132,10 +127,10 @@ function sample_plane(geometry::AbstractMatrix, particle_spacing; place_on_shell
132127
fill(place_on_shell ? 0 : particle_spacing / 2, size(geometry, 2))')
133128

134129
# TODO: 2D shapes not only in x-y plane but in any user-defined plane
135-
return coords, particle_spacing
130+
return coords
136131
end
137132

138-
return geometry, particle_spacing
133+
return geometry
139134
end
140135

141136
function sample_plane(shape::InitialCondition, particle_spacing; place_on_shell)
@@ -148,10 +143,10 @@ function sample_plane(shape::InitialCondition, particle_spacing; place_on_shell)
148143
size(shape.coordinates, 2))')
149144

150145
# TODO: 2D shapes not only in x-y plane but in any user-defined plane
151-
return coords, particle_spacing
146+
return coords
152147
end
153148

154-
return shape.coordinates, particle_spacing
149+
return shape.coordinates
155150
end
156151

157152
function sample_plane(plane_points, particle_spacing; place_on_shell=nothing)
@@ -166,12 +161,19 @@ function sample_plane(plane_points::NTuple{2}, particle_spacing; place_on_shell=
166161
throw(ArgumentError("all points must be 2D coordinates"))
167162
end
168163

169-
n_points = ceil(Int, norm(plane_points[2] - plane_points[1]) / particle_spacing) + 1
164+
p1 = plane_points[1]
165+
p2 = plane_points[2]
166+
167+
line_dir = p2 - p1
168+
line_length = norm(line_dir)
170169

171-
coords = stack(range(plane_points[1], plane_points[2], length=n_points))
172-
particle_spacing_new = norm(coords[:, 1] - coords[:, 2])
170+
n_particles,
171+
new_length = round_n_particles(line_length, particle_spacing,
172+
"line length")
173173

174-
return coords, particle_spacing_new
174+
coords = stack([p1 + i * particle_spacing * normalize(line_dir) for i in 0:n_particles])
175+
176+
return coords
175177
end
176178

177179
function sample_plane(plane_points::NTuple{3}, particle_spacing; place_on_shell=nothing)
@@ -194,25 +196,28 @@ function sample_plane(plane_points::NTuple{3}, particle_spacing; place_on_shell=
194196
end
195197

196198
# Determine the number of points along each edge
197-
num_points_edge1 = ceil(Int, norm(edge1) / particle_spacing)
198-
num_points_edge2 = ceil(Int, norm(edge2) / particle_spacing)
199-
199+
num_points_edge1,
200+
new_length = round_n_particles(norm(edge1), particle_spacing,
201+
"edge 1 length")
202+
num_points_edge2,
203+
new_length = round_n_particles(norm(edge2), particle_spacing,
204+
"edge 2 length")
205+
206+
dir1 = normalize(edge1)
207+
dir2 = normalize(edge2)
200208
coords = zeros(3, (num_points_edge1 + 1) * (num_points_edge2 + 1))
201209

202210
index = 1
203211
for i in 0:num_points_edge1
204212
for j in 0:num_points_edge2
205-
point_on_plane = point1_ + (i / num_points_edge1) * edge1 +
206-
(j / num_points_edge2) * edge2
213+
point_on_plane = point1_ + i * particle_spacing * dir1 +
214+
j * particle_spacing * dir2
207215
coords[:, index] = point_on_plane
208216
index += 1
209217
end
210218
end
211219

212-
particle_spacing_new = min(norm(edge1 / num_points_edge1),
213-
norm(edge2 / num_points_edge2))
214-
215-
return coords, particle_spacing_new
220+
return coords
216221
end
217222

218223
# Shift corners of the plane/line inwards by half a particle spacing with `place_on_shell=false`

test/examples/examples.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@
184184
r"WARNING: using deprecated binding PlotUtils.*\n",
185185
r"WARNING: Makie.* is deprecated.*\n",
186186
r" likely near none:1\n",
187-
r", use .* instead.\n"
187+
r", use .* instead.\n",
188+
r"┌ Info: The desired face size is not a multiple of the resolution [0-9.]+\.\n└ New resolution is set to [0-9.]+\.\n"
188189
]
189190
@test sol.retcode == ReturnCode.Success
190191
end

test/schemes/boundary/open_boundary/characteristic_variables.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
particle_spacing = 0.1
33

44
# Number of boundary particles in the influence of fluid particles
5-
influenced_particles = [20, 52, 26]
5+
influenced_particles = [20, 50, 26]
66

77
open_boundary_layers = 8
88
sound_speed = 20.0

0 commit comments

Comments
 (0)