Skip to content

Commit d3bc096

Browse files
committed
Move Obj to refinement method
1 parent 56f219e commit d3bc096

File tree

2 files changed

+96
-24
lines changed

2 files changed

+96
-24
lines changed

src/obj_geometry.jl

Lines changed: 93 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,94 @@ function create_interpolations(vertices, circle_center_z, radius, gamma_tip, R=I
227227
return (le_interp, te_interp, area_interp)
228228
end
229229

230+
"""
231+
refine_obj_wing!(wing::AbstractWing; recompute_mapping=true)
232+
233+
Refine OBJ wing by computing position deltas and applying them to refined sections.
234+
235+
This method enables deformation support for OBJ wings by:
236+
1. Recalculating evenly-spaced gammas for unrefined sections
237+
2. Computing what unrefined sections SHOULD be (from interpolations)
238+
3. Computing deltas between current and interpolated positions
239+
4. Creating refined sections from interpolations + interpolated deltas
240+
5. Computing panel mapping
241+
242+
# Arguments
243+
- `wing::AbstractWing`: OBJ wing with le_interp/te_interp
244+
- `recompute_mapping::Bool=true`: Whether to recompute refined_panel_mapping
245+
246+
# Effects
247+
Updates wing.refined_sections and wing.non_deformed_sections in-place.
248+
"""
249+
function refine_obj_wing!(wing::AbstractWing; recompute_mapping=true)
250+
n_unrefined = wing.n_unrefined_sections
251+
n_refined = wing.n_panels + 1
252+
253+
# 1. Calculate evenly spaced gammas for unrefined sections
254+
unrefined_gammas = range(-wing.gamma_tip, wing.gamma_tip, n_unrefined)
255+
256+
# 2. Recalculate what unrefined sections SHOULD be from interpolations
257+
interpolated_unrefined_le = Matrix{Float64}(undef, n_unrefined, 3)
258+
interpolated_unrefined_te = Matrix{Float64}(undef, n_unrefined, 3)
259+
for (i, gamma) in enumerate(unrefined_gammas)
260+
interpolated_unrefined_le[i, :] .= [wing.le_interp[j](gamma) for j in 1:3]
261+
interpolated_unrefined_te[i, :] .= [wing.te_interp[j](gamma) for j in 1:3]
262+
end
263+
264+
# 3. Compute deltas: current - interpolated
265+
deltas_le = Matrix{Float64}(undef, n_unrefined, 3)
266+
deltas_te = Matrix{Float64}(undef, n_unrefined, 3)
267+
for i in 1:n_unrefined
268+
deltas_le[i, :] .= wing.unrefined_sections[i].LE_point -
269+
interpolated_unrefined_le[i, :]
270+
deltas_te[i, :] .= wing.unrefined_sections[i].TE_point -
271+
interpolated_unrefined_te[i, :]
272+
end
273+
274+
# 4. Create refined sections with interpolated deltas
275+
refined_gammas = range(-wing.gamma_tip, wing.gamma_tip, n_refined)
276+
if isempty(wing.refined_sections)
277+
wing.refined_sections = [Section() for _ in 1:n_refined]
278+
end
279+
280+
for (idx, gamma) in enumerate(refined_gammas)
281+
# Get base position from interpolation
282+
base_le = [wing.le_interp[i](gamma) for i in 1:3]
283+
base_te = [wing.te_interp[i](gamma) for i in 1:3]
284+
285+
# Find surrounding unrefined sections for delta interpolation
286+
unrefined_idx = searchsortedlast(collect(unrefined_gammas), gamma)
287+
unrefined_idx = clamp(unrefined_idx, 1, n_unrefined - 1)
288+
289+
# Linear interpolation weight
290+
gamma_left = unrefined_gammas[unrefined_idx]
291+
gamma_right = unrefined_gammas[unrefined_idx + 1]
292+
t = (gamma - gamma_left) / (gamma_right - gamma_left)
293+
294+
# Interpolate deltas
295+
delta_le = (1 - t) * deltas_le[unrefined_idx, :] +
296+
t * deltas_le[unrefined_idx + 1, :]
297+
delta_te = (1 - t) * deltas_te[unrefined_idx, :] +
298+
t * deltas_te[unrefined_idx + 1, :]
299+
300+
# Apply deltas to get final position
301+
final_le = base_le + delta_le
302+
final_te = base_te + delta_te
303+
304+
# Update refined section
305+
aero_model = wing.unrefined_sections[1].aero_model
306+
aero_data = wing.unrefined_sections[1].aero_data
307+
VortexStepMethod.reinit!(wing.refined_sections[idx], final_le, final_te,
308+
aero_model, aero_data)
309+
end
310+
311+
# 5. Compute panel mapping and update non_deformed_sections
312+
recompute_mapping && VortexStepMethod.compute_refined_panel_mapping!(wing)
313+
VortexStepMethod.update_non_deformed_sections!(wing)
314+
315+
return nothing
316+
end
317+
230318
"""
231319
center_to_com!(vertices, faces)
232320
@@ -487,34 +575,18 @@ function ObjWing(
487575
push!(sections, Section(LE_point, TE_point, POLAR_MATRICES, aero_data))
488576
end
489577

490-
# Create refined sections (evenly spaced including both tips)
491-
refined_sections = Section[]
492-
for gamma in range(-gamma_tip, gamma_tip, n_panels+1)
493-
LE_point = [le_interp[i](gamma) for i in 1:3]
494-
TE_point = [te_interp[i](gamma) for i in 1:3]
495-
push!(refined_sections, Section(LE_point, TE_point, POLAR_MATRICES, aero_data))
496-
end
497-
498-
# Create non_deformed_sections as copy of refined_sections for deformation support
499-
non_deformed_sections = [Section() for _ in 1:n_panels+1]
500-
for i in 1:n_panels+1
501-
reinit!(non_deformed_sections[i], refined_sections[i])
502-
end
503-
504578
panel_props = PanelProperties{n_panels}()
505579
cache = [PreallocationTools.LazyBufferCache()]
506580

507581
wing = Wing(n_panels, Int16(n_unrefined_sections), spanwise_distribution, panel_props, MVec3(spanwise_direction),
508-
sections, refined_sections, remove_nan,
509-
Int16[],
510-
non_deformed_sections, zeros(n_panels), zeros(n_panels),
582+
sections, Section[], remove_nan, # refined_sections empty
583+
Int16[], # refined_panel_mapping empty
584+
Section[], zeros(n_panels), zeros(n_panels), # non_deformed, theta, delta
511585
mass, gamma_tip, inertia_tensor, T_cad_body, R_cad_body, radius,
512586
le_interp, te_interp, area_interp, cache)
513587

514-
# Compute panel mapping for deformation support
515-
VortexStepMethod.compute_refined_panel_mapping!(wing)
516-
517-
# Update panel properties
588+
# Auto-refine for backward compatibility
589+
refine_obj_wing!(wing; recompute_mapping=true)
518590
reinit!(wing)
519591

520592
wing

src/wing_geometry.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -580,14 +580,15 @@ Add a new section to the wing.
580580
- `aero_model`::AeroModel: [AeroModel](@ref)
581581
- `aero_data`::AeroData: See [AeroData](@ref)
582582
"""
583-
function add_section!(wing::Wing, LE_point,
583+
function add_section!(wing::Wing, LE_point,
584584
TE_point, aero_model::AeroModel, aero_data::AeroData=nothing)
585585
if aero_model == POLAR_VECTORS && wing.remove_nan
586586
aero_data = remove_vector_nans(aero_data)
587587
elseif aero_model == POLAR_MATRICES && wing.remove_nan
588588
interpolate_matrix_nans!.(aero_data[3:5])
589589
end
590590
push!(wing.unrefined_sections, Section(LE_point, TE_point, aero_model, aero_data))
591+
wing.n_unrefined_sections = Int16(length(wing.unrefined_sections))
591592
return nothing
592593
end
593594

@@ -623,7 +624,6 @@ function update_non_deformed_sections!(wing::AbstractWing)
623624

624625
# Populate or update non_deformed_sections
625626
if isempty(wing.non_deformed_sections)
626-
@show length(wing.refined_sections) n_sections
627627
# Initial setup
628628
wing.non_deformed_sections = [Section() for _ in 1:n_sections]
629629
for i in 1:n_sections
@@ -705,10 +705,10 @@ function refine!(wing::AbstractWing; recompute_mapping=true, sort_sections=true)
705705
n_sections = wing.n_panels + 1
706706

707707
if length(wing.refined_sections) == 0
708-
@show wing.spanwise_distribution
709708
if wing.spanwise_distribution == UNCHANGED ||
710709
length(wing.unrefined_sections) == n_sections
711710
wing.refined_sections = wing.unrefined_sections
711+
recompute_mapping && compute_refined_panel_mapping!(wing)
712712
update_non_deformed_sections!(wing)
713713
return nothing
714714
else

0 commit comments

Comments
 (0)