Skip to content

Commit 80fc357

Browse files
committed
Improved obj file reading
1 parent 1438b55 commit 80fc357

File tree

9 files changed

+136
-49
lines changed

9 files changed

+136
-49
lines changed

src/obj_geometry.jl

Lines changed: 81 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ Create interpolation functions for leading/trailing edges and area.
112112
- Where le_interp and te_interp are tuples themselves, containing the x, y and z interpolations
113113
"""
114114
function create_interpolations(vertices, circle_center_z, radius, gamma_tip, R=I(3); interp_steps=40)
115-
gamma_range = range(-gamma_tip+1e-6, gamma_tip-1e-6, interp_steps)
115+
gamma_range = range(-gamma_tip+gamma_tip/interp_steps*2,
116+
gamma_tip-gamma_tip/interp_steps*2, interp_steps)
116117
stepsize = gamma_range.step.hi
117118
vz_centered = [v[3] - circle_center_z for v in vertices]
118119

@@ -122,33 +123,91 @@ function create_interpolations(vertices, circle_center_z, radius, gamma_tip, R=I
122123
leading_edges = zeros(3, length(gamma_range))
123124
areas = zeros(length(gamma_range))
124125

126+
n_slices = length(gamma_range)
125127
for (j, gamma) in enumerate(gamma_range)
126128
trailing_edges[1, j] = -Inf
127129
leading_edges[1, j] = Inf
128-
for (i, v) in enumerate(vertices)
129-
# Rotate y coordinate to check box containment
130-
# rotated_y = v[2] * cos(-gamma) - vz_centered[i] * sin(-gamma)
131-
gamma_v = atan(-v[2], vz_centered[i])
132-
if gamma 0 && gamma - stepsize gamma_v gamma
133-
if v[1] > trailing_edges[1, j]
134-
trailing_edges[:, j] .= v
135-
te_gammas[j] = gamma_v
136-
end
137-
if v[1] < leading_edges[1, j]
138-
leading_edges[:, j] .= v
139-
le_gammas[j] = gamma_v
130+
131+
# Determine if this is a tip slice and get search parameters
132+
is_first_tip = (j == 1)
133+
is_last_tip = (j == n_slices)
134+
135+
if is_first_tip || is_last_tip
136+
# Tip slices: use directional search within adjacent slice region
137+
gamma_search = is_first_tip ? gamma_range[1] : gamma_range[end]
138+
max_te_score = -Inf
139+
max_le_score = -Inf
140+
141+
for (i, v) in enumerate(vertices)
142+
gamma_v = atan(-v[2], vz_centered[i])
143+
144+
# Check if vertex is in the adjacent slice region
145+
in_range = if gamma_search 0
146+
gamma_search - stepsize gamma_v gamma_search
147+
else
148+
gamma_search gamma_v gamma_search + stepsize
140149
end
141-
elseif gamma > 0 && gamma gamma_v gamma + stepsize
142-
if v[1] > trailing_edges[1, j]
143-
trailing_edges[:, j] .= v
144-
te_gammas[j] = gamma_v
150+
151+
if in_range
152+
if is_first_tip
153+
# TE: furthest in [X, Y, -Z] direction
154+
te_score = v[1] + v[2] - v[3]
155+
if te_score > max_te_score
156+
trailing_edges[:, j] .= v
157+
te_gammas[j] = gamma_v
158+
max_te_score = te_score
159+
end
160+
# LE: furthest in [-X, Y, -Z] direction
161+
le_score = -v[1] + v[2] - v[3]
162+
if le_score > max_le_score
163+
leading_edges[:, j] .= v
164+
le_gammas[j] = gamma_v
165+
max_le_score = le_score
166+
end
167+
else # is_last_tip
168+
# TE: furthest in [X, -Y, -Z] direction
169+
te_score = v[1] - v[2] - v[3]
170+
if te_score > max_te_score
171+
trailing_edges[:, j] .= v
172+
te_gammas[j] = gamma_v
173+
max_te_score = te_score
174+
end
175+
# LE: furthest in [-X, -Y, -Z] direction
176+
le_score = -v[1] - v[2] - v[3]
177+
if le_score > max_le_score
178+
leading_edges[:, j] .= v
179+
le_gammas[j] = gamma_v
180+
max_le_score = le_score
181+
end
182+
end
145183
end
146-
if v[1] < leading_edges[1, j]
147-
leading_edges[:, j] .= v
148-
le_gammas[j] = gamma_v
184+
end
185+
else
186+
# Interior slices: use standard min/max x-coordinate search
187+
for (i, v) in enumerate(vertices)
188+
gamma_v = atan(-v[2], vz_centered[i])
189+
if gamma 0 && gamma - stepsize gamma_v gamma
190+
if v[1] > trailing_edges[1, j]
191+
trailing_edges[:, j] .= v
192+
te_gammas[j] = gamma_v
193+
end
194+
if v[1] < leading_edges[1, j]
195+
leading_edges[:, j] .= v
196+
le_gammas[j] = gamma_v
197+
end
198+
elseif gamma > 0 && gamma gamma_v gamma + stepsize
199+
if v[1] > trailing_edges[1, j]
200+
trailing_edges[:, j] .= v
201+
te_gammas[j] = gamma_v
202+
end
203+
if v[1] < leading_edges[1, j]
204+
leading_edges[:, j] .= v
205+
le_gammas[j] = gamma_v
206+
end
149207
end
150208
end
151209
end
210+
152211
area = norm(leading_edges[:, j] - trailing_edges[:, j]) * stepsize * radius
153212
last_area = j > 1 ? areas[j-1] : 0.0
154213
areas[j] = last_area + area
@@ -159,9 +218,9 @@ function create_interpolations(vertices, circle_center_z, radius, gamma_tip, R=I
159218
trailing_edges[:, j] .= R * trailing_edges[:, j]
160219
end
161220

162-
le_interp = ntuple(i -> linear_interpolation(te_gammas, leading_edges[i, :],
221+
le_interp = ntuple(i -> linear_interpolation(le_gammas, leading_edges[i, :],
163222
extrapolation_bc=Line()), 3)
164-
te_interp = ntuple(i -> linear_interpolation(le_gammas, trailing_edges[i, :],
223+
te_interp = ntuple(i -> linear_interpolation(te_gammas, trailing_edges[i, :],
165224
extrapolation_bc=Line()), 3)
166225
area_interp = linear_interpolation(gamma_range, areas, extrapolation_bc=Line())
167226

src/wing_geometry.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,8 @@ function deform!(wing::Wing)
462462
local_y .= normalize(section1.LE_point - section2.LE_point)
463463
chord .= section1.TE_point .- section1.LE_point
464464
normal .= chord × local_y
465-
@. wing.refined_sections[i].TE_point = section1.LE_point + cos(wing.theta_dist[i]) * chord - sin(wing.theta_dist[i]) * normal
465+
@. wing.refined_sections[i].TE_point = section1.LE_point +
466+
cos(wing.theta_dist[i]) * chord - sin(wing.theta_dist[i]) * normal
466467
end
467468
return nothing
468469
end

test/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
1313
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1414
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1515
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
16+
VortexStepMethod = "ed3cd733-9f0f-46a9-93e0-89b8d4998dd9"
1617
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"
1718

1819
[compat]

test/TestSupport.jl

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/ram_geometry/test_kite_geometry.jl

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,38 +189,80 @@ using Serialization
189189
# Create an ObjWing for testing
190190
wing = ObjWing(test_obj_path, test_dat_path; remove_nan=true)
191191
body_aero = BodyAerodynamics([wing])
192-
192+
193193
# Store original TE point for comparison
194194
i = length(body_aero.panels) ÷ 2
195195
original_te_point = copy(body_aero.panels[i].TE_point_1)
196-
196+
197197
# Apply deformation with non-zero angles
198198
theta_dist = fill(deg2rad(30.0), wing.n_panels) # 10 degrees twist
199199
delta_dist = fill(deg2rad(5.0), wing.n_panels) # 5 degrees trailing edge deflection
200-
200+
201201
VortexStepMethod.deform!(wing, theta_dist, delta_dist)
202202
VortexStepMethod.reinit!(body_aero)
203-
203+
204204
# Check if TE point changed after deformation
205205
deformed_te_point = copy(body_aero.panels[i].TE_point_1)
206206
@test !isapprox(original_te_point, deformed_te_point, atol=1e-2)
207207
@test deformed_te_point[3] < original_te_point[3] # right hand rule
208208
@test deformed_te_point[2] original_te_point[2] atol=1e-2 # right hand rule
209209
@test deformed_te_point[1] < original_te_point[1] # right hand rule
210210
@test body_aero.panels[i].delta deg2rad(5.0)
211-
211+
212212
# Reset deformation with zero angles
213213
zero_theta_dist = zeros(wing.n_panels)
214214
zero_delta_dist = zeros(wing.n_panels)
215-
215+
216216
VortexStepMethod.deform!(wing, zero_theta_dist, zero_delta_dist)
217217
VortexStepMethod.reinit!(body_aero)
218-
218+
219219
# Check if TE point returned to original position
220220
reset_te_point = copy(body_aero.panels[i].TE_point_1)
221221
@test original_te_point reset_te_point atol=1e-4
222222
end
223+
224+
@testset "First and Last Section Deformation with group_deform!" begin
225+
# Create an ObjWing with a small number of panels and groups
226+
wing = ObjWing(test_obj_path, test_dat_path;
227+
n_panels=4, n_groups=2, remove_nan=true)
228+
229+
# Store original TE points from all refined_sections
230+
# Wing has n_panels+1 sections (5 sections for 4 panels)
231+
n_sections = wing.n_panels + 1
232+
original_te_points = [copy(wing.refined_sections[i].TE_point)
233+
for i in 1:n_sections]
234+
235+
@show wing.refined_sections[1].LE_point
236+
@show wing.refined_sections[1].TE_point
237+
@show wing.refined_sections[end].LE_point
238+
@show wing.refined_sections[end].TE_point
239+
240+
# Apply group_deform! with non-zero angles (2 groups, each controlling 2 panels)
241+
theta_angles = [deg2rad(15.0), deg2rad(20.0)]
242+
delta_angles = [deg2rad(5.0), deg2rad(10.0)]
243+
244+
VortexStepMethod.group_deform!(wing, theta_angles, delta_angles; smooth=false)
245+
246+
# Check that all sections' TE points have been deformed
247+
for i in 1:n_sections
248+
deformed_te = wing.refined_sections[i].TE_point
249+
original_te = original_te_points[i]
250+
251+
if i == 1
252+
# First section should be deformed
253+
@test !isapprox(original_te, deformed_te, atol=1e-6)
254+
@info "Section 1 (first): original=$original_te, deformed=$deformed_te"
255+
elseif i == n_sections
256+
# Last section (n_panels+1) should be deformed
257+
@test !isapprox(original_te, deformed_te, atol=1e-6)
258+
@info "Section $(n_sections) (last): original=$original_te, deformed=$deformed_te"
259+
else
260+
# Intermediate sections should also be deformed
261+
@test !isapprox(original_te, deformed_te, atol=1e-6)
262+
end
263+
end
264+
end
223265

224266
rm(test_obj_path)
225267
rm(test_dat_path)
226-
end
268+
end

test/runtests.jl

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ using Test, VortexStepMethod
22

33
# Make paths robust (avoid cd(".."))
44
cd(@__DIR__) # ensure we're in test/ no matter how tests are launched
5-
include("TestSupport.jl")
6-
using .TestSupport
5+
include("test_data_utils.jl")
76

87
println("Running tests...")
98

test/settings/test_settings.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ using Test
1111
@test vss.wings isa Vector{WingSettings}
1212
@test length(vss.wings) == 2
1313
io = IOBuffer(repr(vss))
14-
@test countlines(io) == 44 # Updated to match new output format
14+
@test countlines(io) == 46 # Updated to match new output format
1515
end
1616
nothing

test/solver/test_group_coefficients.jl

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ using VortexStepMethod
22
using LinearAlgebra
33
using Test
44

5-
# Load test support
6-
include("../TestSupport.jl")
7-
using .TestSupport
8-
95
@testset "Group Coefficient Arrays Tests" begin
106
@testset "Group coefficients with EQUAL_SIZE method" begin
117
# Create a simple wing with groups

test/yaml_geometry/test_yaml_wing_deformation.jl

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,6 @@ using VortexStepMethod
22
using LinearAlgebra
33
using Test
44

5-
# Load TestSupport if not already loaded (for standalone execution)
6-
if !@isdefined(TestSupport)
7-
include(joinpath(@__DIR__, "..", "TestSupport.jl"))
8-
using .TestSupport
9-
end
10-
115
@testset "YAML Wing Deformation Tests" begin
126
@testset "Simple Wing Deformation" begin
137
# Load existing simple_wing.yaml

0 commit comments

Comments
 (0)