Skip to content

Commit 0afee2d

Browse files
authored
Fix branch 3 direction (#241)
* Fix branch 3 direction * Fix tests
1 parent b1e4d4d commit 0afee2d

3 files changed

Lines changed: 133 additions & 20 deletions

File tree

src/filament.jl

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,19 @@ function velocity_3D_bound_vortex!(
8484
@debug "inside core radius"
8585
@debug "distance from control point to filament: $(nr1Xr0 / nr0)"
8686

87-
# Project onto core radius
88-
cross3!(r2Xr0, r2, r0)
8987
nr0sq = nr0 * nr0
90-
nr2Xr0 = norm3(r2Xr0)
9188
d_r1_r0 = dot3(r1, r0)
9289
d_r2_r0 = dot3(r2, r0)
90+
r_rad = r1Xr0
91+
@inbounds for k in 1:3
92+
r_rad[k] = r1[k] - d_r1_r0 * r0[k] / nr0sq
93+
end
94+
nr_rad = norm3(r_rad)
9395
@inbounds for k in 1:3
9496
r1_proj[k] = d_r1_r0 * r0[k] / nr0sq +
95-
epsilon * r1Xr0[k] / nr1Xr0
97+
epsilon * r_rad[k] / nr_rad
9698
r2_proj[k] = d_r2_r0 * r0[k] / nr0sq +
97-
epsilon * r2Xr0[k] / nr2Xr0
99+
epsilon * r_rad[k] / nr_rad
98100
end
99101
cross3!(r1_projXr2_proj, r1_proj, r2_proj)
100102

@@ -289,13 +291,13 @@ function velocity_3D_trailing_vortex_semiinfinite!(
289291
else
290292
r1_proj = work_vectors[4]
291293
cross_tmp = work_vectors[5]
292-
# temp = r1/nr1 - Vf
294+
nVfsq = nVf * nVf
293295
@inbounds for k in 1:3
294-
cross_tmp[k] = r1[k]/nr1 - Vf[k]
296+
cross_tmp[k] = r1[k] - d_r1_Vf * Vf[k] / nVfsq
295297
end
296298
n_tmp = norm3(cross_tmp)
297299
@inbounds for k in 1:3
298-
r1_proj[k] = d_r1_Vf * Vf[k] +
300+
r1_proj[k] = d_r1_Vf * Vf[k] / nVfsq +
299301
epsilon * cross_tmp[k] / n_tmp
300302
end
301303
cross3!(cross_tmp, r1_proj, Vf)

test/filament/test_bound_filament.jl

Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ end
7474
filament = BoundFilament{Float64}()
7575
reinit!(filament, [0.0, 0.0, 0.0], [1e6, 0.0, 0.0])
7676
control_point = [5e5, 1.0, 0.0]
77-
77+
7878
velocity_3D_bound_vortex!(
7979
induced_velocity,
8080
filament,
@@ -85,8 +85,8 @@ end
8585
)
8686
@test !any(isnan.(induced_velocity))
8787
@test isapprox(induced_velocity[1], 0.0, atol=1e-8)
88-
@test abs(induced_velocity[2]) < 1e-8
89-
@test isapprox(induced_velocity[3], 0.0)
88+
@test isapprox(induced_velocity[2], 0.0, atol=1e-8)
89+
@test abs(induced_velocity[3]) > 1e-10
9090
end
9191

9292
@testset "Point Far from Filament" begin
@@ -133,35 +133,35 @@ end
133133
@testset "Around Core Radius" begin
134134
filament = create_test_filament()
135135
delta = 1e-5
136-
136+
137137
points = [
138138
[0.5, core_radius_fraction - delta, 0.0],
139139
[0.5, core_radius_fraction, 0.0],
140140
[0.5, core_radius_fraction + delta, 0.0]
141141
]
142-
142+
143143
velocities = [zeros(3) for p in points]
144144
[
145145
velocity_3D_bound_vortex!(velocities[i], filament, p, gamma, core_radius_fraction, work_vectors)
146146
for (i, p) in enumerate(points)
147147
]
148-
148+
149149
# Check for NaN and finite values
150150
@test all(!any(isnan.(v)) for v in velocities)
151151
@test all(all(isfinite.(v)) for v in velocities)
152-
152+
153153
# Check magnitude is maximum at core radius
154154
@test norm(velocities[2]) > norm(velocities[1])
155155
@test norm(velocities[2]) > norm(velocities[3])
156-
156+
157157
# Check continuity around core radius
158158
@test isapprox(velocities[1], velocities[2], rtol=1e-2)
159-
159+
160160
# Check non-zero velocities
161161
@test !all(isapprox.(velocities[1], zeros(3), atol=1e-10))
162162
@test !all(isapprox.(velocities[2], zeros(3), atol=1e-10))
163163
@test !all(isapprox.(velocities[3], zeros(3), atol=1e-10))
164-
164+
165165
# Check symmetry
166166
v_neg = zeros(3)
167167
velocity_3D_bound_vortex!(
@@ -174,4 +174,80 @@ end
174174
)
175175
@test isapprox(velocities[2], -v_neg)
176176
end
177+
178+
@testset "Velocity is azimuthal (perpendicular to axis and radius)" begin
179+
filament = create_test_filament()
180+
r0 = [1.0, 0.0, 0.0]
181+
182+
for d in (0.25, 0.5, 0.99, 1.0, 1.01, 2.0) .* core_radius_fraction
183+
for phi in (0.0, π/4, π/2, π, -π/3)
184+
p = [0.5, d * cos(phi), d * sin(phi)]
185+
v = zeros(3)
186+
velocity_3D_bound_vortex!(
187+
v, filament, p, gamma,
188+
core_radius_fraction, work_vectors)
189+
190+
r_radial = [0.0, p[2], p[3]]
191+
@test isapprox(dot(v, r0), 0.0; atol=1e-10)
192+
@test isapprox(dot(v, r_radial), 0.0; atol=1e-8)
193+
end
194+
end
195+
end
196+
197+
@testset "Solid-body rotation inside core" begin
198+
filament = create_test_filament()
199+
200+
v_half = zeros(3)
201+
v_quarter = zeros(3)
202+
velocity_3D_bound_vortex!(
203+
v_half, filament,
204+
[0.5, 0.5 * core_radius_fraction, 0.0],
205+
gamma, core_radius_fraction, work_vectors)
206+
velocity_3D_bound_vortex!(
207+
v_quarter, filament,
208+
[0.5, 0.25 * core_radius_fraction, 0.0],
209+
gamma, core_radius_fraction, work_vectors)
210+
211+
@test isapprox(norm(v_quarter), 0.5 * norm(v_half); rtol=1e-3)
212+
@test isapprox(normalize(v_quarter), normalize(v_half); atol=1e-8)
213+
end
214+
215+
@testset "Branch 1 / Branch 3 agree at core boundary" begin
216+
filament = create_test_filament()
217+
delta = 0.05 * core_radius_fraction
218+
v_inside = zeros(3)
219+
v_outside = zeros(3)
220+
velocity_3D_bound_vortex!(
221+
v_inside, filament,
222+
[0.5, core_radius_fraction - delta, 0.0],
223+
gamma, core_radius_fraction, work_vectors)
224+
velocity_3D_bound_vortex!(
225+
v_outside, filament,
226+
[0.5, core_radius_fraction + delta, 0.0],
227+
gamma, core_radius_fraction, work_vectors)
228+
229+
@test isapprox(norm(v_inside), norm(v_outside); rtol=0.1)
230+
@test isapprox(normalize(v_inside), normalize(v_outside); atol=1e-2)
231+
end
232+
233+
@testset "Matches Rankine vortex profile inside core" begin
234+
L = 1e6
235+
r_c = 0.01 * L
236+
filament_long = BoundFilament{Float64}()
237+
reinit!(filament_long, [0.0, 0.0, 0.0], [L, 0.0, 0.0])
238+
239+
for r in (1.0, 10.0, 100.0, 1000.0)
240+
v = zeros(3)
241+
velocity_3D_bound_vortex!(
242+
v, filament_long, [L/2, r, 0.0],
243+
gamma, 0.01, work_vectors)
244+
245+
expected_mag = gamma * r / (2π * r_c^2)
246+
247+
@test isapprox(v[1], 0.0; atol=expected_mag * 1e-4)
248+
@test isapprox(v[2], 0.0; atol=expected_mag * 1e-4)
249+
@test isapprox(abs(v[3]), expected_mag; rtol=1e-3)
250+
@test v[3] > 0
251+
end
252+
end
177253
end

test/filament/test_semi_infinite_filament.jl

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ end
118118
filament = create_test_filament2()
119119
vel_pos = zeros(3)
120120
vel_neg = zeros(3)
121-
121+
122122
velocity_3D_trailing_vortex_semiinfinite!(
123123
vel_pos,
124124
filament,
@@ -137,7 +137,42 @@ end
137137
filament.vel_mag,
138138
work_vectors
139139
)
140-
140+
141141
@test isapprox(vel_pos, -vel_neg)
142142
end
143+
144+
@testset "Velocity is azimuthal (perpendicular to axis and radius)" begin
145+
filament = create_test_filament2()
146+
direction = filament.direction
147+
148+
for d in (1e-4, 1e-3, 5e-3, 1e-2, 1e-1)
149+
for phi in (0.0, π/4, π/2, π, -π/3)
150+
p = [0.5, d * cos(phi), d * sin(phi)]
151+
v = zeros(3)
152+
velocity_3D_trailing_vortex_semiinfinite!(
153+
v, filament, direction, p, gamma,
154+
filament.vel_mag, work_vectors)
155+
156+
r_radial = [0.0, p[2], p[3]]
157+
@test isapprox(dot(v, direction), 0.0; atol=1e-10)
158+
@test isapprox(dot(v, r_radial) / norm(v), 0.0; atol=1e-6)
159+
end
160+
end
161+
end
162+
163+
@testset "Constant azimuthal direction inside core" begin
164+
filament = create_test_filament2()
165+
v_a = filament.vel_mag
166+
167+
d_inside = 1e-4
168+
v1 = zeros(3); v2 = zeros(3)
169+
velocity_3D_trailing_vortex_semiinfinite!(
170+
v1, filament, filament.direction,
171+
[0.5, d_inside, 0.0], gamma, v_a, work_vectors)
172+
velocity_3D_trailing_vortex_semiinfinite!(
173+
v2, filament, filament.direction,
174+
[0.5, 2 * d_inside, 0.0], gamma, v_a, work_vectors)
175+
176+
@test isapprox(normalize(v2), normalize(v1); atol=1e-8)
177+
end
143178
end

0 commit comments

Comments
 (0)