@@ -297,25 +297,20 @@ function Wing(n_panels::Int;
297297end
298298
299299"""
300- reinit!(wing::AbstractWing; refine_mesh=true, recompute_mapping=true, sort_sections=true )
300+ reinit!(wing::AbstractWing)
301301
302- Reinitialize wing geometry and panel properties.
302+ Reinitialize wing panel properties based on current refined_sections geometry .
303303
304- # Keyword Arguments
305- - `refine_mesh::Bool=true`: Whether to refine the mesh. Set to `false` after
306- `deform!()` to preserve deformed geometry while updating panel properties.
307- - `recompute_mapping::Bool=true`: Whether to recompute the refined panel mapping.
308- Set to `false` to skip mapping computation when it hasn't changed.
309- - `sort_sections::Bool=true`: Whether to sort sections by spanwise position.
310- Set to `false` for REFINE wings where section order is determined by structural connectivity.
311- """
312- function reinit! (wing:: AbstractWing ; refine_mesh= true , recompute_mapping= true , sort_sections= true )
313- # Refine mesh unless explicitly disabled (e.g., to preserve deformation)
314- if refine_mesh
315- refine_aerodynamic_mesh! (wing; recompute_mapping, sort_sections)
316- end
304+ This function only updates panel properties (chord, area, etc.) from the existing
305+ refined_sections. It does NOT refine the mesh - call refine_aerodynamic_mesh!(wing)
306+ first if needed.
317307
318- # Calculate panel properties
308+ # Note
309+ After deformation via `unrefined_deform!()` or `deform!()`, call `reinit!` to update
310+ panel properties while preserving the deformed geometry.
311+ """
312+ function reinit! (wing:: AbstractWing )
313+ # Calculate panel properties from refined sections
319314 update_panel_properties! (
320315 wing. panel_props,
321316 wing. refined_sections,
@@ -620,54 +615,99 @@ end
620615
621616Create non_deformed_sections to match refined_sections.
622617This enables deformation support for all wings (YAML and OBJ).
623- Should be called after refined_sections are populated for the FIRST time only .
618+ Should be called after refined_sections are populated.
624619Once populated, non_deformed_sections serves as the undeformed reference geometry.
625620"""
626621function update_non_deformed_sections! (wing:: AbstractWing )
627622 n_sections = wing. n_panels + 1
628623
629- # Only populate non_deformed_sections if it's empty (initial setup)
630- # Once populated, it serves as the undeformed reference and should not be overwritten
624+ # Populate or update non_deformed_sections
631625 if isempty (wing. non_deformed_sections)
626+ @show length (wing. refined_sections) n_sections
627+ # Initial setup
632628 wing. non_deformed_sections = [Section () for _ in 1 : n_sections]
633629 for i in 1 : n_sections
634630 reinit! (wing. non_deformed_sections[i], wing. refined_sections[i])
635631 end
632+ elseif length (wing. non_deformed_sections) != n_sections
633+ # Size mismatch - error
634+ throw (ArgumentError (
635+ " non_deformed_sections has incorrect size. " *
636+ " Expected $(n_sections) sections (n_panels+1), got $(length (wing. non_deformed_sections)) . " *
637+ " This indicates an inconsistent wing state."
638+ ))
639+ else
640+ # Correct size - update all sections
641+ for i in 1 : n_sections
642+ reinit! (wing. non_deformed_sections[i], wing. refined_sections[i])
643+ end
636644 end
637645 return nothing
638646end
639647
640648"""
641- refine_aerodynamic_mesh!(wing::AbstractWing; recompute_mapping=true, sort_sections=true)
642-
643- Refine the aerodynamic mesh of the wing based on spanwise panel distribution.
649+ refine!(wing::AbstractWing; recompute_mapping=true, sort_sections=true)
650+
651+ Refine the wing aerodynamic mesh from unrefined sections to refined sections.
652+
653+ This function interpolates the wing geometry from a coarse set of unrefined sections
654+ to a fine mesh of refined sections (n_panels+1 sections) based on the wing's
655+ spanwise_distribution setting. It also populates non_deformed_sections which
656+ enables deformation support via `unrefined_deform!`.
657+
658+ # Required Workflow
659+ Must be called after wing construction and before creating `BodyAerodynamics`:
660+ ```julia
661+ wing = Wing("wing.yaml"; n_panels=40) # or ObjWing(...) or manual Wing
662+ refine!(wing) # Refine mesh
663+ body_aero = BodyAerodynamics([wing]) # Create aerodynamics
664+ ```
665+
666+ # Distribution Methods
667+ - `LINEAR`: Linear interpolation between sections
668+ - `COSINE`: Cosine spacing (more panels near tips)
669+ - `COSINE_VAN_GARREL`: van Garrel cosine distribution
670+ - `SPLIT_PROVIDED`: Split each unrefined section into sub-panels
671+ - `UNCHANGED`: 1:1 copy when n_unrefined_sections == n_panels+1
644672
645673# Keyword Arguments
646- - `recompute_mapping::Bool=true`: Whether to recompute the refined panel mapping.
647- Set to `false` to skip mapping computation when it hasn't changed.
648- - `sort_sections::Bool=true`: Whether to sort sections by spanwise position (y-coordinate).
649- Set to `false` for REFINE wings where section order is determined by structural connectivity.
674+ - `recompute_mapping::Bool=true`: Recompute the mapping from refined panels to unrefined sections
675+ - `sort_sections::Bool=true`: Sort sections by spanwise position (disable for structural ordering)
650676
651- Returns:
652- Vector{Section}: List of refined sections
677+ # Effects
678+ 1. Populates `wing.refined_sections` (n_panels+1 sections)
679+ 2. Populates `wing.non_deformed_sections` (copy of refined_sections for deformation reference)
680+ 3. Computes `wing.refined_panel_mapping` (panel → unrefined section mapping)
681+ 4. Resizes `wing.theta_dist` and `wing.delta_dist` to n_panels
682+
683+ # Example
684+ ```julia
685+ # YAML wing
686+ wing = Wing("wing.yaml"; n_panels=40)
687+ refine!(wing)
688+ body_aero = BodyAerodynamics([wing])
689+
690+ # After refinement, deformation is supported
691+ unrefined_deform!(wing, theta_angles, delta_angles)
692+ ```
653693"""
654- function refine_aerodynamic_mesh! (wing:: AbstractWing ; recompute_mapping= true , sort_sections= true )
694+ function refine! (wing:: AbstractWing ; recompute_mapping= true , sort_sections= true )
695+ # Validate unrefined_sections exist
696+ if isempty (wing. unrefined_sections)
697+ throw (ArgumentError (
698+ " Cannot refine mesh: wing has no unrefined_sections. " *
699+ " Add sections using add_section! or check wing construction."
700+ ))
701+ end
702+
655703 # Only sort sections if requested (skip for REFINE wings with fixed structural order)
656704 sort_sections && sort! (wing. unrefined_sections, by= s -> s. LE_point[2 ], rev= true )
657705 n_sections = wing. n_panels + 1
658706
659- # Handle NONE distribution - sections already refined, just compute mapping
660- if wing. spanwise_distribution == NONE
661- if length (wing. refined_sections) != n_sections
662- throw (ArgumentError (" NONE distribution requires refined_sections to be pre-populated" ))
663- end
664- recompute_mapping && compute_refined_panel_mapping! (wing)
665- update_non_deformed_sections! (wing)
666- return nothing
667- end
668-
669707 if length (wing. refined_sections) == 0
670- if wing. spanwise_distribution == UNCHANGED || length (wing. unrefined_sections) == n_sections
708+ @show wing. spanwise_distribution
709+ if wing. spanwise_distribution == UNCHANGED ||
710+ length (wing. unrefined_sections) == n_sections
671711 wing. refined_sections = wing. unrefined_sections
672712 update_non_deformed_sections! (wing)
673713 return nothing
0 commit comments