KBE 2026 Python File Study Guide
Bullet-style guide to what each Python file does, why it exists, how to read its parts, and what looks obsolete or
non-active.
How To Read This Guide
- Start with root files and models: they explain the app's state and entry point.
- Then read geometry: it explains how fuselage, wings, tails, and intersections are built.
- Then read analysis: it explains meshes, optimization, plots, and numerical evidence.
- Finish with rules, exports, external tools, and UI: those explain user workflows.
- For each file, read the arrow row first: it gives the main idea before the detailed bullets.
- Then read 'Parts To Understand' from top to bottom: the bullets are ordered like a walkthrough.
- Treat obsolete/non-active notes as review flags, not automatic delete instructions.
Recommended Reading Order
1. [Link]
2. [Link]
3. models/design_state.py
4. models/area_rule.py
5. models/[Link]
6. models/__init__.py
7. geometry/fuselage_parameterization.py
8. geometry/[Link]
9. geometry/parametric_wing.py
10. geometry/constraint_envelopes.py
11. geometry/geometry_manager.py
12. geometry/cross_section_manager.py
13. geometry/intersection_manager.py
14. geometry/intersection_checker.py
15. geometry/optimized_intersection_manager.py
16. geometry/optimized_intersection_checker.py
17. geometry/__init__.py
18. analysis/optimization_result.py
19. analysis/mesh_builder.py
20. analysis/preview_mesh_validation.py
21. analysis/mesh_area_distribution_manager.py
22. analysis/fuselage_data_manager.py
23. analysis/optimization_manager.py
24. analysis/graph_manager.py
25. analysis/__init__.py
26. rules/advisor_summary.py
27. rules/design_advisor.py
28. rules/__init__.py
29. exports/optimized_results.py
30. exports/evidence_workbook.py
31. exports/__init__.py
32. external_tools/wave_drag_tool.py
33. ui/app_palette.py
34. ui/inputs_panel_helpers.py
35. ui/design_state_binding.py
36. ui/advisor_panel.py
37. ui/app_viewer_helpers.py
38. ui/app_workflows.py
39. ui/inputs_panel.py
40. ui/app_layout.py
41. ui/[Link]
42. ui/__init__.py
Root Files
[Link]
Main Idea Flow Run file -> import App -> display App in ParaPy WebGUI
Does - Launches the ParaPy/WebGUI app.
- Imports the root UI component and passes it to ParaPy display().
Why - Keeps one clear entry point for the whole application.
- Lets the rest of the project stay focused on model, geometry, analysis, and UI logic.
Parts To - display import: this is the ParaPy/WebGUI launcher; it is what actually opens the app
Understand (In interface.
Order)
- App import: this points the launcher to the root component where all real UI/state/workflow
logic lives.
- __main__ guard: keeps the app from launching accidentally if another file imports [Link].
- display(App, reload=True): starts the WebGUI and enables a development-friendly reload
behavior.
Obsolete / - No obsolete code found.
Non-Active
- The README confirms this is still the intended launch path.
[Link]
Main Idea Flow Repository location -> shared data folders -> default fuselage/airfoil file paths
Does - Defines shared project paths and default data-file addresses.
- Gives other modules a single place to find default fuselage and airfoil files.
Why - Avoids repeating file paths across model, geometry, and UI code.
- Makes the app less dependent on the current terminal working directory.
Parts To - PROJECT_ROOT: calculates the repository folder from [Link] itself, so file lookup does
Understand (In not depend on where the terminal was opened.
Order)
- DATA_DIR / AIRFOIL_DIR / REFERENCE_DATA_DIR: named folder addresses used to
build default data-file paths.
- DEFAULT_FUSELAGE_FILE: points to the reference fuselage JSON used for
compatibility/file existence paths.
- DEFAULT_WING_FILE / DEFAULT_VERT_TAIL_FILE / DEFAULT_HOR_TAIL_FILE: point
to the default airfoil coordinate files used when the app starts.
Obsolete / - No dead logic.
Non-Active
- Folder constants are not imported directly elsewhere, but they actively build the file
constants.
models/
models/design_state.py
Main Idea Flow Raw UI/model values -> coerce types -> validate ranges -> immutable design snapshot ->
apply back to model
Does - Defines the clean saved snapshot of one aircraft design.
- Validates design values before they are applied to the live ParaPy model.
Why - Keeps many UI/model values together instead of loose variables.
- Makes design changes copyable, serializable, and safer to pass to the advisor or UI.
Parts To - DESIGN_STATE_FIELDS: the official list of settings that are considered part of one aircraft
Understand (In design snapshot.
Order)
- FLOAT_FIELDS: tells from_mapping() which UI/string values must become real numbers
before validation.
- AircraftDesignState fields: the stored values of one design; they are dataclass fields, not
ParaPy Inputs.
- from_model(): reads matching fields from a live model/facade and creates a validated design
snapshot.
- from_mapping(): accepts dictionary-like data from UI/advisor/saved state, merges defaults,
handles old formats, coerces types, and validates.
- to_dict(): converts the frozen snapshot back into a mutable dictionary for UI and workflow
code.
- apply_to_model(): copies validated state values onto AR/PREVIEW_AR or another
compatible model.
- validate() and helper validators: protect the app from impossible geometry ranges, invalid
sections, and malformed constraints.
Obsolete / - Old wing-section sweep support is compatibility logic for older payloads.
Non-Active
- z_offs_vert_tail exists but is forced to 0.0 by the current attachment convention.
- show_constraints is stored, but excluded from to_dict() by default because it is mostly display
state.
models/area_rule.py
Main Idea Flow UI ratios -> dimensional aircraft values -> Aircraft(...) -> AR committed state /
PREVIEW_AR preview state
Does - Acts as the UI-facing design facade.
- Stores normalized slider values and converts them into dimensional aircraft inputs.
Why - The UI works best with ratios; geometry needs metres.
- Separates committed design state (AR) from preview/pending design state (PREVIEW_AR).
Parts To - AircraftDesignFacade Inputs: these are the live ParaPy controls that hold current design
Understand (In values in UI-friendly ratios.
Order)
- design_state / validation_errors: connect the facade back to AircraftDesignState so current
values can be captured and checked.
- Dimensional fuselage helpers: convert reference length, fineness ratio, and nose/tail fractions
into metres.
- actual_* wing/tail helpers: convert chord/span ratios into real dimensions needed by Aircraft
and GeometryManager.
- Modification flags: compare PREVIEW_AR against AR to know whether a preview
component is changed.
- aircraft Part: the key active bridge; validates the facade and creates [Link]
with dimensional inputs.
- ghost_geometry_manager and ghost_* Parts: old ParaPy preview route that likely no longer
feeds the current viewer.
- AR / PREVIEW_AR globals: AR is committed state; PREVIEW_AR is pending/preview state
used by mesh preview and validation.
Obsolete / - ghost_* ParaPy cyan preview Parts appear bypassed by the newer mesh-preview path.
Non-Active
- Helper methods for ghost root curves are likely inactive with those ghost Parts.
- fuselage_file and fuselage_radius remain compatibility-style inputs.
- z_offs_vert_tail exists but the created aircraft forces it to 0.0.
models/[Link]
Main Idea Flow Dimensional inputs -> GeometryManager + analysis managers ->
optimization/plots/checks/exports/advisor
Does - Orchestrates the complete aircraft product model.
- Connects geometry, fuselage data, numerical areas, optimization, graphs, intersections,
exports, and advisor.
Why - Centralizes the major subsystems behind one Aircraft object.
- Lets UI/workflow code ask for [Link], [Link], aircraft.optimized_results,
etc.
Parts To - Inputs: already-dimensional values passed in by area_rule.py; this class is no longer mostly
Understand (In ratio-based.
Order)
- geometry Part: creates GeometryManager, which owns the actual CAD fuselage, wings, tails,
and aircraft compound.
- fuselage_data Part: creates analysis-ready fuselage stations, radii, z-centers, and radius
constraints.
- intersections / cross_sections: heavier CAD validation/debug paths for committed geometry.
- numerical_areas Part: active mesh-based area distribution source used by optimization and
graphs.
- optimization Part: creates OptimizationManager with numerical areas, fuselage constraints,
and target Mach.
- graphs Part: creates GraphManager so evidence plots can use the latest optimization result.
- optimized_results and optimized_intersection_checker: build/export optimized geometry and
validate post-optimization root attachments.
- show_all_plots(): the main optimize-and-plot action used by the UI workflow.
- Shortcut properties: make other code read aircraft.aircraft_solid or aircraft.has_errors instead
of digging through managers.
Obsolete / - cross_sections is kept for CAD validation/debugging, not primary optimization.
Non-Active
- check_all_intersections and export_all_optimized are ParaPy actions, not used by the
custom UI.
- constraint_visualizers may be secondary to newer viewer overlay helpers.
models/__init__.py
Main Idea Flow models package -> optional public export -> AircraftDesignState shortcut
Does - Marks models/ as a package and re-exports AircraftDesignState.
Why - Allows imports like from models import AircraftDesignState.
Parts To - Package docstring: describes the models package.
Understand (In
Order) - AircraftDesignState import: provides an optional shortcut import from models.
- __all__: declares the intended public export if a caller imports from the package level.
Obsolete / - The current code imports AircraftDesignState directly from models.design_state, so the
Non-Active export is a convenience rather than an active dependency.
geometry/
geometry/fuselage_parameterization.py
Main Idea Flow Fuselage sliders -> smooth radius/z-center laws -> CAD arrays + analysis arrays
Does - Defines the smooth mathematical fuselage shape.
- Answers radius_at(x) and z_center_at(x) for any fuselage station.
Why - Gives geometry and analysis the same continuous fuselage definition.
- Separates shape math from CAD solid creation.
Parts To - Shape Inputs: reference length, fineness ratio, nose/tail fractions, sharpness, and vertical
Understand (In bias define the continuous fuselage.
Order)
- Dimension attributes: turn nondimensional shape settings into actual length, radius, nose
length, body length, and tail start.
- cad_xs/cad_radii/cad_z_centers: sparse station arrays used for CAD loft sections.
- analysis_xs/analysis_radii/analysis_z_centers: denser station arrays used for optimization
and numerical analysis.
- radius_at(x): core rule for nose growth, cylindrical body, and tail closure.
- bias_at(x) and z_center_at(x): shift circular sections vertically to represent flat-top/flat-bottom
tendencies.
- segment_arrays(x0, x1): returns local arrays so GeometryManager can build nose, body, and
tail separately.
- _smoothstep and _smooth_power_rise: make the radius transitions smooth rather than
kinked.
Obsolete / - safe_radius is defined but not used in this file.
Non-Active
- Otherwise active and central.
geometry/[Link]
Main Idea Flow Segment stations/radii/z-centers -> hidden circular ribs -> lofted fuselage segment
Does - Turns station/radius/z-center data into one ParaPy lofted fuselage segment.
Why - Converts fuselage math into visible CAD geometry.
- Lets GeometryManager build nose, body, and tail as separate lofts.
Parts To - Modern data path: if stations/radii are supplied, the segment uses them directly from
Understand (In FuselageParameterization.
Order)
- Compatibility data path: if explicit arrays are missing, it falls back to old fuselage_data slicing
behavior.
- sliced_data: decides which local x-stations and radii will define the loft.
- section_z_centers: assigns vertical offsets for the circular ribs; modern path uses explicit
z_centers.
- cross_sections Part: creates hidden Circle objects at each station; these are the loft profiles.
- solid Part: lofts the circles into the visible ParaPy fuselage segment.
- __main__ block: standalone debug display, not part of the normal app launch.
Obsolete / - fuselage_data, start_perc, end_perc, and old slicing logic are compatibility fallback.
Non-Active
- fuselage_file is present but not read here.
- __main__ display block is only a local debug launcher.
geometry/parametric_wing.py
Main Idea Flow Airfoil file -> scaled ribs along span -> fitted curves -> lofted wing/tail solid
Does - Builds CAD lifting surfaces from 2D airfoil coordinates.
- Despite the name, it builds wings, vertical tails, and horizontal tails.
Why - Uses one reusable lifting-surface builder for all airfoil-based surfaces.
- Provides root airfoil point sets for containment and optimization constraints.
Parts To - File input and orientation: wing_file supplies coordinates; is_vertical switches between
Understand (In wing-like and vertical-tail-like axes.
Order)
- normalized_airfoil_points: reads the coordinate file and closes the airfoil loop.
- dense and upper-surface airfoil points: provide richer root geometry for
containment/attachment constraints.
- airfoil_chords: root chord plus each section's tip chord; this determines rib sizes.
- airfoil_station_origins: walks outboard along span using sweep, dihedral, and orientation to
place each rib.
- airfoil_section_points: scales normalized airfoil points into real aircraft coordinates for every
rib.
- root_airfoil_points variants: expose only the root rib for fuselage containment logic.
- airfoil_curves and solid: convert point loops to fitted curves, then loft them into a CAD
wing/tail solid.
Obsolete / - wing_file name is active but misleading because it also stores tail files.
Non-Active
- VERTICAL_TAIL_ROOT_Z_OFFSET is active historical convention.
- fallback airfoil only activates when a file cannot be read.
geometry/constraint_envelopes.py
Main Idea Flow User constraint percentages -> sampled x-window -> envelope radii/z-centers -> drawable
data
Does - Converts user minimum-radius constraints into sampled envelope data.
Why - Keeps constraint visualization numeric and independent from ParaPy primitives.
- Supports both live parameterized fuselages and already-sampled optimized profiles.
Parts To - _constraint_window_sections: converts x_pct/window_pct into actual x stations and makes
Understand (In point-like constraints visible.
Order)
- constraint_envelope_section_data(): used with live FuselageParameterization; asks
radius_at and z_center_at for each sample.
- constraint_envelope_section_data_from_profile(): used with explicit arrays such as
optimized/viewer profiles.
- reference_radii option: lets optimized views size constraints from original radius while placing
them on optimized geometry.
- Constants: control sampling density, maximum visible radius fraction, and minimum visual
thickness.
Obsolete / - No obsolete functions.
Non-Active
- Second top-level string is redundant; only the first is a real module docstring.
geometry/geometry_manager.py
Main Idea Flow Fuselage parameters + lifting-surface inputs -> CAD parts -> mirrored/subtracted parts ->
aircraft compound
Does - Assembles the full CAD aircraft geometry.
- Builds fuselage, wings, tails, mirrored components, subtracted components, and aircraft
compound.
Why - Keeps low-level geometry construction in one place.
- Gives analysis and export code stable access to geometry_manager.right_wing,
fuselage_solid, aircraft_solid, etc.
Parts To - Location attributes: total_fuselage_length, body_start_x, tail_start_x, and tail_end_x divide
Understand (In the fuselage into segments.
Order)
- fuselage_parameters: creates the continuous shape object used by both CAD and analysis
paths.
- nose/main_body/tail: create three Fuselage segment objects from local arrays.
- fuselage_solid: fuses the three CAD segments into one baseline fuselage solid.
- visual_* fuselage parts: denser display version used for smoother visual output.
- right_wing/left_wing/wings_pair: build the wing and mirror it across the aircraft center plane.
- vert_tail and h_tail_*: build vertical and horizontal tail geometry using ParametricWing.
- *_less_fuselage: subtract fuselage volume from lifting surfaces for CAD intersections/cross
sections.
- aircraft_solid: final compound containing fuselage, wings, vertical tail, and optional horizontal
tail.
Obsolete / - fuselage_file input is not used here.
Non-Active
- fuselage_radius is backward-compatible; max radius comes from FuselageParameterization.
- z_offs_vert_tail input is ignored; vertical tail uses abs_z=0.0.
- *_less_fuselage parts are less central now that optimization uses mesh areas, but still useful
for CAD validation.
geometry/cross_section_manager.py
Main Idea Flow CAD aircraft -> slicing planes -> CAD intersections -> face areas -> old smoothed area
curves
Does - Computes old CAD-based cross-sectional area distributions.
Why - Originally sliced CAD solids with planes for area-rule analysis.
- Now mostly retained for validation/debugging because mesh-based areas are the active
optimizer source.
Parts To - planes: creates x-normal slicing planes at fuselage stations.
Understand (In
Order) - CAD Common Parts: intersect planes with wing/tail solids that have fuselage volume
removed.
- fuselage_cross_sectional_area: computes circular fuselage area directly from radii.
- _*_cross_sectional_areas methods: read face areas from CAD section results and handle
failures as zero area.
- smooth_component: smooths noisy CAD area signals using moving averages.
- areas/tail_areas/total/x: expose area curves with names expected by older optimizer/plot
code.
- calculate_* methods: old method-style accessors retained for compatibility.
Obsolete / - Superseded as primary area source by analysis/mesh_area_distribution_manager.py.
Non-Active
- calculate_* methods are compatibility wrappers.
geometry/intersection_manager.py
Main Idea Flow Baseline geometry pieces -> CAD Common operations -> raw intersection objects
Does - Creates baseline CAD intersection objects between aircraft components.
Why - Separates expensive CAD Common operations from boolean error interpretation.
Parts To - geometry_manager input: gives access to fuselage_solid, airfoil root curves, and
Understand (In fuselage-subtracted surfaces.
Order)
- Root/fuselage Common operations: wing, horizontal tail, and vertical tail root curves vs
fuselage solid.
- Surface collision Common operations: wing vs horizontal tail, wing vs vertical tail, vertical tail
vs horizontal tail.
- Important separation: this file creates raw CAD intersection objects; it does not decide
whether they are errors.
Obsolete / - Active for committed CAD validation.
Non-Active
- Live slider preview uses faster mesh validation instead.
geometry/intersection_checker.py
Main Idea Flow Raw baseline intersections -> vertex/wire/count checks -> UI error booleans + summary
Does - Turns baseline CAD intersection results into error booleans and summaries.
Why - UI and aircraft logic need clear true/false statuses, not raw CAD Common objects.
Parts To - Intersection inputs: raw Common objects from IntersectionManager.
Understand (In
Order) - Root checks: treat a clean root/fuselage relationship as exactly one intersection vertex.
- Surface collision checks: treat any intersection wires between external lifting surfaces as an
error.
- Tip checks: use first/last CAD cross-section objects to catch tips entering the fuselage.
- File checks: detect missing fuselage file and wing airfoil read failure.
- Grouped flags: has_intersection_errors, has_tip_errors, has_file_errors, and
overall_error_status.
- Compatibility aliases: older UI names mapped to the newer grouped status attributes.
- get_error_summary(): one dictionary for UI/debugging/reporting.
Obsolete / - Alias attributes are compatibility names.
Non-Active
- File checking here is partly superseded by broader UI pending-file checks.
- lifting_surface_reading_error_status checks the right wing path, not every tail file directly.
geometry/optimized_intersection_manager.py
Main Idea Flow Optimized fuselage + original roots -> CAD Common operations -> optimized raw
intersections
Does - Creates CAD intersections between the optimized fuselage and existing root curves.
Why - Optimization changes the fuselage, so root attachments must be rechecked afterward.
Parts To - Inputs: existing right wing, right horizontal tail, vertical tail, and new optimized fuselage.
Understand (In
Order) - Wing root Common: original wing root curve vs optimized fuselage solid.
- Horizontal-tail root Common: original horizontal-tail root curve vs optimized fuselage solid.
- Vertical-tail root Common: original vertical-tail root curve vs optimized fuselage solid.
- Scope: only rechecks root/fuselage relationships because lifting surfaces did not move during
fuselage optimization.
Obsolete / - Active and focused.
Non-Active
- It intentionally checks fewer relationships because wing/tail mutual intersections were
checked before optimization.
geometry/optimized_intersection_checker.py
Main Idea Flow Optimized raw intersections -> root validity checks -> post-optimization error summary
Does - Interprets optimized-fuselage root intersections as post-optimization error flags.
Why - Advisor and UI need to know whether the optimized fuselage still makes a valid aircraft.
Parts To - optimized_intersections input: points to the manager that owns the actual CAD Common
Understand (In operations.
Order)
- Intersection alias attributes: forward optimized Common results for compatibility with older
code shape.
- Root checks: use vertex counts to decide whether optimized fuselage attachment is valid.
- include_hor_tail guard: bypasses horizontal-tail errors when the horizontal tail is disabled.
- Compatibility error aliases: older names for wing/HT/VT optimized root errors.
- get_optimized_error_summary(): compact dictionary used by UI workflows and advisor.
- get_intersection_comparison(): status plus raw intersection counts for
debugging/comparison.
Obsolete / - Placement inputs are retained for compatibility/dependency tracking.
Non-Active
- error_lifting_surface_* aliases are compatibility names.
geometry/__init__.py
Main Idea Flow geometry directory -> Python package marker
Does - Marks geometry/ as a package.
Why - Lets Python treat the directory as importable geometry modules.
Parts To - Package docstring only.
Understand (In
Order)
Obsolete / - No runtime logic or public exports.
Non-Active
analysis/
analysis/optimization_result.py
Main Idea Flow Optimizer manager outputs -> copied immutable result -> UI/export/advisor metrics
Does - Stores one optimization run as an immutable result snapshot.
Why - Prevents plots, exports, advisor, and UI from reading scattered mutable manager attributes.
Parts To - Status fields: success/message plus normalization scales.
Understand (In
Order) - Area/radius curves: initial, optimized, target total/fuselage area and radius arrays.
- Constraint fields: effective minimum/maximum radius arrays and active-source diagnostics.
- Mach/lifting distribution fields: extra curves for supersonic/Mach-plane evidence.
- Scalar metrics: roughness, volume, external area, and percent changes for UI cards/exports.
- from_manager(): copies values out of OptimizationManager into an immutable snapshot.
- Compatibility properties: expose old names like x, stations, optimizer_success,
optimized_radii.
- metrics_payload(): small dictionary of headline scalar metrics.
Obsolete / - Alias properties and from_manager support older naming/structure.
Non-Active
- No clear dead code.
analysis/mesh_builder.py
Main Idea Flow Airfoil/profile data -> triangle meshes -> clipped viewer/analysis mesh components
Does - Builds triangle-mesh versions of fuselage, wings, tails, and preview aircraft.
Why - Meshes are faster than CAD for preview, numerical areas, validation, and viewer display.
Parts To - TriangleMeshComponent: names one mesh component and marks whether it should be
Understand (In fuselage-clipped.
Order)
- Generic helpers: validate triangle arrays, remove degenerate triangles, and store per-triangle
x bounds.
- Airfoil helpers: read/cache/close/sample airfoil coordinates for mesh generation.
- build_lifting_surface_ribs(): creates mesh ribs from chord/span/sweep/dihedral/thickness
data.
- triangles_from_ribs(): turns ribs into a closed triangle mesh for wings/tails.
- fuselage_profile_from_area_rule(): reconstructs preview fuselage profile from slider state
without CAD.
- Inside/clipping helpers: detect and remove lifting-surface triangles hidden inside the fuselage.
- fuselage_triangles_from_profile(): builds a ring-based fuselage triangle mesh.
- Viewer helpers: convert triangles into nodes/elements for the WebGUI viewer.
- Mesh classes: LiftingSurfaceTriangleMesh, FuselageProfileTriangleMesh,
AircraftTriangleMesh, AreaRuleTriangleMesh.
Obsolete / - AircraftTriangleMesh appears less visibly used than AreaRuleTriangleMesh, but remains
Non-Active useful for shared baseline/optimized mesh workflows.
- Fuselage shape math duplicates other modules; intentional for speed, but a maintenance
risk.
analysis/preview_mesh_validation.py
Main Idea Flow Pending slider values -> preview mesh -> root/tip/collision checks -> slider bounds/errors
Does - Validates live preview geometry using triangle meshes.
Why - Slider movement needs fast checks without rebuilding heavy CAD.
Parts To - Planform helpers: determine how far each surface extends in x and what x-offset range is
Understand (In allowed.
Order)
- Fuselage radius helper: cheaply reproduces radius/z-center at a station for validation math.
- Root bound helpers: compute x and z slider ranges that keep the root airfoil inside the
fuselage.
- Containment helpers: check whether root points are inside and tip points are outside the
fuselage.
- Triangle intersection helpers: fast bounding-box and triangle/segment tests for mesh
collisions.
- LiftingSurfacePlanformBounds: ParaPy wrapper used by UI slider bounds.
- LiftingSurfaceRootBounds: ParaPy wrapper that gives x/z root attachment bounds.
- AreaRulePreviewMesh: wrapper around AreaRuleTriangleMesh for viewer-ready mesh
props.
- PreviewMeshIntersectionChecker: final error_summary for root, tip, and component collision
errors.
Obsolete / - Active current preview validation system.
Non-Active
- Duplicates fuselage math for speed; keep consistent with FuselageParameterization.
analysis/mesh_area_distribution_manager.py
Main Idea Flow Triangle meshes -> x-slices -> loops/polygon areas -> wing/tail/total area distributions
Does - Computes cross-sectional area distributions from triangle meshes.
Why - Replaces the older CAD slicing path for faster optimizer inputs.
- Produces fuselage, wing, tail, and total area curves along x.
Parts To - x/radius/z-center attributes: define the station grid and fuselage area curve.
Understand (In
Order) - LiftingSurfaceTriangleMesh attributes: build mesh data for right/left wing, vertical tail, and
horizontal tails.
- _slice_triangle_x and _slice_mesh_x: cut triangle meshes at each x station.
- Segment/loop helpers: deduplicate slice segments and turn them into closed loops.
- _polygon_area_outside_fuselage: counts only external lifting-surface area where
appropriate.
- _surface_distribution_from_mesh: converts a component mesh into an area-vs-x curve.
- Distribution attributes: wing, vertical tail, horizontal tail, tail, and total area curves.
- Compatibility attributes/methods: areas, tail_areas, total, calculate_* match the old CAD
manager interface.
Obsolete / - Compatibility calculate_* methods mimic old CrossSectionManager API.
Non-Active
- Very active as the optimizer's current area source.
analysis/fuselage_data_manager.py
Main Idea Flow Fuselage parameterization + surface roots + user constraints -> min/max radius arrays for
optimizer
Does - Builds fuselage station/radius data and optimizer radius bounds.
Why - Optimization needs x-stations, initial radii, z-centers, minimum radii, and maximum allowed
radii.
Parts To - Base station data: pulls xs, radii, z_centers, and biases from
Understand (In geometry_manager.fuselage_parameters.
Order)
- min_radii/user_min_radii: apply user-defined minimum-radius constraints along the station
grid.
- max_radii/tip_exclusion_max_radii: cap optimized radius so tips stay outside when needed.
- surface containment arrays: combine wing, horizontal-tail, and vertical-tail root requirements.
- _apply_user_constraint_to_curve: spreads one user constraint over its x-window.
- _constrain_all_points/_constrain_point: convert root airfoil points into required fuselage
radius.
- _exclude_tip_points/_exclude_tip_point: convert tip points into maximum allowed radius
limits.
- Interpolation/bracketing helpers: map arbitrary point x-locations onto the station grid.
Obsolete / - Active and important for optimization safety.
Non-Active
- Some naming reflects older fuselage_data conventions, but the current data source is
geometry_manager.fuselage_parameters.
analysis/optimization_manager.py
Main Idea Flow Area distributions + radius bounds + Mach logic -> solver -> optimized radii + diagnostics +
result
Does - Runs the fuselage area-rule optimization.
- Builds objective curves, constraints, Mach-plane/proxy distributions, diagnostics, and
OptimizationResult.
Why - This is the numerical core: it changes fuselage radii to reduce area-distribution roughness
while respecting constraints.
Parts To - Result pass-through attributes: keep older code able to ask manager.Af_opt_sq even though
Understand (In data lives in OptimizationResult.
Order)
- Smoothing and lobe-model helpers: clean lifting-surface area signals before optimization.
- Mesh sampling helpers: gather component mesh samples for axial and Mach-plane area
distributions.
- Mach projection helpers: build oblique plane frames and compute projected area distributions
for supersonic cases.
- Constraint helpers: clip min radius, enforce max radius, diagnose active radius sources.
- Objective/distribution helpers: calculate roughness and binned area behavior.
- call_optimizator(): main pipeline; gathers inputs, builds constraints/objective, runs SciPy
optimization, computes diagnostics, stores OptimizationResult.
- Timing helpers: print performance timing around expensive optimizer phases.
Obsolete / - Many short attributes are compatibility pass-throughs to result.
Non-Active
- No obvious dead core; file is large because it combines solver setup, diagnostics, and legacy
result exposure.
analysis/graph_manager.py
Main Idea Flow OptimizationResult + area distributions -> normalized comparison plots -> evidence
figures
Does - Creates Matplotlib evidence plots for optimization results.
Why - Users need visual proof of area smoothing, constraints, lifting-surface contributions, and
Mach-plane behavior.
Parts To - Scale helpers: compute finite plot maxima and shared y-limits so plots are comparable.
Understand (In
Order) - Normalization helpers: add area/radius normalized axes for readable evidence plots.
- Snapshot helpers: pull baseline/previous/current curves for before-after comparison.
- Constraint curve helpers: derive lower/upper feasible bands from optimizer result arrays.
- _plot_fuselage_feasible_band: overlays min/max radius or area limits and active sources.
- graph_lifting_surface_x_distribution: shows fixed lifting-surface area contribution along x.
- graph_init_opt_fus_cross_sect_area: compares initial vs optimized fuselage area.
- graph_init_opt_tot_cross_sect_area: compares initial vs optimized total area.
- Mach graph methods: show objective and per-plane distributions when Mach > 1.
Obsolete / - Active after optimization.
Non-Active
- Input comment still says CrossSectionManager, but Aircraft passes NumericalAreaManager
now.
analysis/__init__.py
Main Idea Flow analysis directory -> Python package marker
Does - Marks analysis/ as a package.
Why - Allows importing modules under analysis.
Parts To - Usually structural only.
Understand (In
Order)
Obsolete / - No active logic.
Non-Active
rules/
rules/advisor_summary.py
Main Idea Flow Raw suggestions -> grouped categories -> short summary for UI
Does - Groups advisor suggestions and creates short summary text.
Why - Keeps the advisor panel from needing to understand every raw suggestion shape.
Parts To - categorize_suggestions(): groups raw suggestions so the UI can count/summarize severity or
Understand (In type.
Order)
- summary_from_suggestions(): produces the short human-facing summary sentence based
on suggestions and whether optimization exists.
Obsolete / - Active support helper for design_advisor.py.
Non-Active
rules/design_advisor.py
Main Idea Flow Optimization symptoms -> rule detections -> suggestions/actions -> candidate strategies
-> design-state changes
Does - Generates rule-based design advice from optimization and validation results.
- Can apply advisor strategies back to design-state dictionaries.
Why - Turns numerical symptoms into practical aircraft-design changes.
- Lets users try bounded configuration alternatives instead of guessing manually.
Parts To - ComponentStation dataclass: normalized representation of where wings/tails sit along the
Understand (In fuselage.
Order)
- analyze_design_advice(): main entry point that builds context, runs rule groups, dedupes,
ranks, and summarizes.
- Detection helpers: find area peaks/dips, radius necks, attachment failures, volume growth,
and constraint conflicts.
- Suggestion builders: create readable issue/action dictionaries for root contribution, bumps,
dips, necks, failures, and growth.
- Action builders: propose component moves, component relief, and fuselage constraint edits.
- Strategy builders/rankers: combine individual actions into candidate strategies and suppress
risky variants.
- apply_*_to_design_state helpers: modify a design-state dictionary according to one action or
strategy.
- Evidence/scenario helpers: compare before/after metrics and score whether advice helped.
- Utility helpers: normalize stations, map components, dedupe suggestions/actions, clamp
values, and read mapping/object attributes safely.
Obsolete / - Large number of private helpers, but most support active advisor flows.
Non-Active
- Some actions may be conditionally suppressed by ranking/risk filters rather than dead.
rules/__init__.py
Main Idea Flow rules directory -> Python package marker
Does - Marks rules/ as a package.
Why - Allows importing advisor modules.
Parts To - Structural package file.
Understand (In
Order)
Obsolete / - No active logic.
Non-Active
exports/ and external_tools/
exports/optimized_results.py
Main Idea Flow Optimized arrays -> optimized fuselage CAD -> text/STEP export files
Does - Builds optimized fuselage geometry and exports optimized results.
Why - Separates optimization output geometry/data export from the optimizer itself.
Parts To - OptimizedFuselage: turns optimized station/radius/z-center arrays into a lofted ParaPy
Understand (In fuselage.
Order)
- section_z_centers/safe_radii: prepare stable CAD loft inputs and avoid zero-radius failures.
- OptimizedResults inputs: collect original geometry, optimized radii, radius bounds, and lifting
surfaces.
- optimized_z_centers: carries original/effective fuselage centerline information into optimized
geometry.
- optimized_fuselage_rows/file: build text data rows and write the optimized fuselage data file.
- new_fuselage: creates the optimized fuselage CAD object.
- optimized_aircraft: combines optimized fuselage with existing wings/tails.
- STEP/text export actions: create downloadable/exportable optimized outputs.
Obsolete / - Active through UI workflow export calls.
Non-Active
- Default filenames remain as convenience fallbacks.
exports/evidence_workbook.py
Main Idea Flow Optimization/plot data -> workbook tables -> XLSX zip package
Does - Creates an XLSX evidence workbook from aircraft optimization data.
Why - Gives reviewers numerical tables behind plots and UI cards.
Parts To - Low-level XLSX helpers: manually create workbook XML, cells, worksheets, and zip
Understand (In structure.
Order)
- Normalization helpers: convert x-stations and area values into comparable normalized
columns.
- Snapshot/distribution helpers: align baseline, previous, current, and Mach distributions onto
target stations.
- Label helpers: keep sheet names and headers Excel-safe/readable.
- build_evidence_workbook_tables(): collects tables for geometry, area curves, metrics,
constraints, and distributions.
- export_evidence_workbook(): writes the final XLSX file to the requested or default
destination.
Obsolete / - Active export path.
Non-Active
- Manual XLSX writer avoids a heavier spreadsheet dependency but is more
maintenance-sensitive.
exports/__init__.py
Main Idea Flow exports directory -> Python package marker
Does - Marks exports/ as a package.
Why - Allows importing export modules.
Parts To - Structural package file.
Understand (In
Order)
Obsolete / - No active logic.
Non-Active
external_tools/wave_drag_tool.py
Main Idea Flow JSON payload -> Eminton-Lord fit/drag estimate -> JSON/text report
Does - Standalone external wave-drag evaluator using Eminton-Lord-style fitting.
Why - Runs as a subprocess so wave-drag evaluation is isolated from the WebGUI process.
Parts To - Eminton-Lord kernel helpers: implement the mathematical basis for the wave-drag estimate.
Understand (In
Order) - _eminton_lord_drag(): estimate drag from x/area distributions.
- _eminton_lord_fit_curve(): fit a smooth area curve using control points.
- _evaluate_curve(): sample fitted curves densely for reporting.
- _write_report(): write human-readable output from computed result data.
- evaluate(): main computation function used by the subprocess payload.
- main(): CLI entry point that reads input JSON and writes report/output files.
Obsolete / - Active only through subprocess calls, not normal imports.
Non-Active
- Standalone CLI structure is intentional.
ui/
ui/app_palette.py
Main Idea Flow Named colors -> shared UI/CAD style constants
Does - Defines shared colors and button style dictionaries.
Why - Keeps UI styling consistent across layout, panels, viewer helpers, and geometry colors.
Parts To - APP_COLORS: semantic UI colors for panels, nav, borders, warnings, errors, etc.
Understand (In
Order) - APP_X11_COLORS: geometry/viewer-friendly named colors.
- Button style dictionaries: reused MUI sx styling for primary, secondary, warning, and error
buttons.
Obsolete / - Active style constants.
Non-Active
- Any unused color names are harmless palette inventory.
ui/inputs_panel_helpers.py
Main Idea Flow Tiny UI values/events -> safe formatting/clamping helpers
Does - Small standalone helpers for input panel formatting and event values.
Why - Keeps repeated utility logic out of the large InputsPanel class.
Parts To - clamp(): keep a number inside lower/upper bounds.
Understand (In
Order) - format_slider_value(): produce compact readable slider text.
- safe_constraint_name(): protect constraint labels from blank/invalid names.
- event_value(): safely pull value data out of UI event objects.
Obsolete / - Active if imported by inputs_panel.py.
Non-Active
ui/design_state_binding.py
Main Idea Flow InputsPanel pending fields <-> AircraftDesignState dictionary
Does - Moves values between InputsPanel pending states and AircraftDesignState.
Why - Keeps UI state conversion centralized instead of scattered through [Link].
Parts To - design_state_from_panel(): reads pending panel fields, uses fallback model values where
Understand (In needed, and returns AircraftDesignState.
Order)
- File fields: preserve uploaded/pending file paths or fallback defaults.
- Numeric fields: pass pending slider strings through AircraftDesignState coercion/validation.
- apply_design_state_to_panel(): writes a state dictionary back into pending UI fields.
- Vertical tail z-offset: deliberately written as 0.0 to match the current convention.
Obsolete / - Active.
Non-Active
- z_offs_vert_tail remains forced to 0.0 here too.
ui/advisor_panel.py
Main Idea Flow Advisor result dictionaries -> suggestion/strategy UI cards
Does - Renders the design-advisor suggestion panel.
Why - Keeps advisor UI cards separate from the main app layout.
Parts To - severity_color(): maps advisor severity to panel accent colors.
Understand (In
Order) - action_text(): converts raw action dictionaries into readable button/card text.
- render_card(): builds one issue/suggestion card.
- render_strategy(): builds one multi-action candidate strategy card.
- render_advisor_panel(): assembles compact/full advisor UI based on app state.
Obsolete / - Active when guidance panel is shown.
Non-Active
ui/app_viewer_helpers.py
Main Idea Flow Mesh/constraint/profile data -> viewer shapes, labels, rulers, Mach overlays
Does - Creates viewer-only mesh overlays, rulers, constraint envelopes, labels, and Mach-plane
visuals.
Why - Keeps 3D viewer object construction out of [Link] and layout code.
Parts To - Display normalization helpers: scale/normalize mesh nodes for stable viewer display.
Understand (In
Order) - mach_plane_overlay_objects(): creates inspection plane overlays for supersonic/Mach
analysis.
- _mesh_shapes(): converts AreaRulePreviewMesh components into viewer Mesh objects and
materials.
- Ruler helpers: build fuselage percentile station ruler objects and labels.
- constraint_envelope_objects(): render user constraint windows as viewer geometry.
- constraint_label_objects(): create floating labels for constraints.
- Text/box triangle helpers: build lightweight 3D labels without relying on external font
rendering.
Obsolete / - Active current viewer path.
Non-Active
- Some handcrafted label/ruler mesh helpers are specialized but not obsolete.
ui/app_workflows.py
Main Idea Flow App state + aircraft managers -> optimize/wave-drag/export/advisor workflows
Does - Holds long-running app actions: optimize, wave drag, exports, advisor updates.
Why - Keeps App methods thin and separates workflow side effects from layout/state definitions.
Parts To - Download helpers: stage files under download assets and trigger browser downloads.
Understand (In
Order) - Optimized concept helpers: capture, compare, and construct editable optimized fuselage
profiles.
- Advisor metric helpers: read previous/current optimization result metrics for evidence scoring.
- Wave-drag helpers: build JSON payloads, run external_tools/wave_drag_tool.py, and
parse/store results.
- run_calculation(): main optimization workflow; runs plots, snapshots results, updates advisor,
and flips UI state.
- Export workflows: baseline aircraft STEP, optimized fuselage data, evidence workbook,
optimized fuselage STEP, optimized aircraft STEP.
Obsolete / - Active.
Non-Active
- Some optimized ghost helpers relate to the newer optimized-concept preview, not the old
area_rule ghost Parts.
ui/inputs_panel.py
Main Idea Flow User edits -> pending State fields -> bounds/validation -> PREVIEW_AR sync -> apply
callbacks
Does - Defines the large interactive input/control panel.
Why - This is where users edit aircraft parameters, constraints, uploads, preview sync, and
validation bounds.
Parts To - State declarations: pending values for files, fuselage shape, wing/tail geometry, constraints,
Understand (In and UI error flags.
Order)
- Constraint helpers: name, normalize, add/remove, edit interval/radius, and preserve draft
names.
- Bounds cache/helpers: avoid recomputing expensive slider bounds on every render.
- Fuselage setters: keep reference length and nose/tail fractions consistent.
- Lifting-surface geometry helpers: enforce chord/span/sweep/taper/aspect-ratio limits.
- Root/attachment bounds: call preview_mesh_validation helpers to keep roots inside fuselage.
- _sync_preview_area_rule(): copies pending UI values into PREVIEW_AR.
- preview_mesh_errors(): runs PreviewMeshIntersectionChecker for pending geometry.
- sync_ghost(): legacy name; now refreshes PREVIEW_AR/mesh preview and may schedule
lightweight commit.
- Upload/apply/render methods: handle file uploads, apply/optimize requests, and build the
panel UI.
Obsolete / - Very active but large.
Non-Active
- Function name sync_ghost now updates mesh preview/PREVIEW_AR; name is legacy from
old ghost system.
- pending_z_offs_vert_tail is present but forced to 0.0.
ui/app_layout.py
Main Idea Flow App state -> dialogs + panels + viewer objects + evidence page layout
Does - Builds the main page layout and viewer composition.
Why - Separates UI arrangement from App state and workflow methods.
Parts To - _app_bar(): builds the top navigation.
Understand (In
Order) - render(): central page layout; it also binds InputsPanel callbacks to App methods.
- Preview/committed object selection: chooses mesh viewer objects based on design vs
optimized concept state.
- Constraint/ruler/Mach overlays: adds inspection geometry to the viewer when enabled.
- Dialogs: centralizes geometry, file, post-optimization, and busy dialogs.
- Design page layout: viewer + input/guidance panels.
- Evidence page layout: plots, metric cards, wave-drag controls, and export buttons.
Obsolete / - Active.
Non-Active
- Confirms old area_rule ghost_* Parts are not the current viewer path.
ui/[Link]
Main Idea Flow Root WebGUI state -> preview/commit/apply/optimize/advisor/export/navigation
coordination
Does - Defines the root WebGUI component and central application state.
Why - Coordinates AR/PREVIEW_AR, input panel state, preview meshes, advisor flows,
optimization, exports, dialogs, and page navigation.
Parts To - State fields: app page, busy state, dialogs, panel state, cached figures, advisor state, undo
Understand (In stack, optimized concept state.
Order)
- Preview mesh methods: create current PREVIEW_AR mesh objects for the viewer.
- Committed mesh methods: create cached AR mesh objects after lightweight commits.
- commit/undo/start-new-fuselage: manage lightweight design changes without full
optimization.
- Design-state helpers: read/apply AR, PREVIEW_AR, panel, and advisor pending states.
- apply_changes(): validate pending panel data, check files/mesh errors, commit to AR, or
open dialogs.
- run_calculation(): delegate optimization workflow and then check post-optimization
attachment errors.
- Advisor flow: preview candidate strategy, clamp to slider bounds, apply through panel,
update evidence.
- Export wrappers: delegate actual file creation to app_workflows.py.
- render(): delegates layout construction to app_layout.render(self).
Obsolete / - Active root component.
Non-Active
- Some method names still mention ghost concepts, but current preview path is mesh-based.
- Several compatibility states remain for vertical-tail z-offset, which is fixed at 0.0.
ui/__init__.py
Main Idea Flow ui directory -> Python package marker
Does - Marks ui/ as a package.
Why - Allows importing UI modules.
Parts To - Structural package file.
Understand (In
Order)
Obsolete / - No active logic.
Non-Active
Optimizer Deep Dive
This expands analysis/optimization_manager.py because it is the hardest file to understand. Read it as: data in -> smooth
design variables -> objective + constraints -> SLSQP -> result diagnostics.
Main Optimizer Idea
- Goal in one line: change the fuselage area/radius curve so the total cross-sectional area curve becomes smoother.
- Total area means: fuselage area + fixed lifting-surface area from wings/tails.
- The optimizer does not move the wing or tail positions here; it reshapes the fuselage around the existing layout.
- The optimized variable is fuselage cross-sectional area Af at stations, but it is converted back to radius with r = sqrt(Af / pi).
- Main idea flow: baseline geometry -> mesh area distributions -> fuselage radius bounds -> smooth design variables -> SLSQP
solve -> optimized radii -> plots/exports/advisor.
Inputs Used By The Optimizer
- cross_sections.x: the x-station grid along the aircraft/fuselage.
- cross_sections.fuselage_cross_sectional_area: initial fuselage area Af0 at every station.
- lifting-surface distributions: wing, vertical-tail, and optional horizontal-tail area curves at the same stations.
- fuselage_data.user_min_radii: minimum radius required by user constraints drawn in the UI.
- fuselage_data.surface/wing/horizontal-tail/vertical-tail containment radii: minimum radii needed so roots remain inside the
fuselage.
- fuselage_data.tip_exclusion_max_radii: maximum radii that prevent the fuselage from swallowing wing/tail tips.
- target_mach and Mach proxy settings: decide whether the objective uses normal x-slices or oblique Mach-projected area
distributions.
Design Variables
- The optimizer does not directly choose every station area independently.
- It builds smooth regional Bernstein correction curves over nose, body, and tail.
- The SLSQP variables are weights on those smooth correction curves.
- area_from_design(design_variables) = Af0 + scaled_design_basis @ design_variables.
- This is why the optimized fuselage changes smoothly instead of becoming jagged station-by-station noise.
- Nose and tail endpoints are forced to remain unchanged by setting the first and last basis rows to zero.
Objective Function
- Subsonic/normal case: minimize second-difference roughness of Af + A_lift along x.
- Second difference means the optimizer penalizes sudden bends, bumps, and dents in the total area curve.
- Mach case: for Mach > 1, minimize the average roughness of multiple Mach-projected total area curves.
- The objective is normalized by the initial roughness area_ref, so the initial design is roughly the reference value.
- Final objective = area-rule roughness / area_ref + interface_smoothness_penalty_weight * interface penalty.
- Interface penalty discourages new profile jumps and slope kinks at the nose/body and body/tail boundaries.
- Important: interface smoothness is a soft penalty, not a hard constraint; the optimizer is allowed to trade against it, but it pays a
cost.
Hard Constraints
- Lower area constraint: area_from_design(design_variables) >= pi * r_min^2.
- Upper area constraint: area_from_design(design_variables) <= pi * r_max^2.
- Nose convexity constraint: keeps the optimized nose radius curve bending in the acceptable direction.
- The nose convexity constraint is built from second derivatives of radius in the nose region.
- Constraint functions are normalized by area_scale or curvature scale so SLSQP sees numerically stable values.
- After solving, the candidate is rejected if it increases the total objective or violates constraints beyond tolerance.
Radius Bounds
- r_min starts from the maximum of required user constraints and required root/surface containment constraints.
- A global floor is added: radius_floor = original local radius * global_min_radius_ratio.
- This radius floor avoids collapsing non-tip fuselage stations to zero.
- r_max is normally 1.1 * original local radius, so the fuselage can grow locally by about 10 percent.
- r_max is also limited by tip_exclusion_max_radii, so the fuselage does not expand over wing/tail tips.
- Minimum bounds are clipped so they never exceed the original local max radius or the final upper bound.
- The actual SciPy Bounds are in area space, not radius space: lower = pi*r_min^2, upper = pi*r_max^2.
Mach Plane Creation
- For target Mach <= 1, beta is zero and the optimizer uses ordinary x-normal area curves.
- For target Mach > 1, beta = sqrt(M^2 - 1), which controls the slope of oblique Mach slicing coordinates.
- The code creates theta_values from 0 to pi; each theta is one rotation angle around the aircraft axis.
- Each oblique coordinate is xi = x - beta * (y*sin(theta) + z*cos(theta)) for lifting-surface mesh vertices.
- A Mach slice is represented by the plane normal [1, -beta*sin(theta), -beta*cos(theta)].
- _mach_plane_frame() also creates two in-plane axes so sliced 3D geometry can be projected into 2D and measured.
- For each theta, wing/tail triangle meshes are cut by these oblique planes, projected into the local plane frame, converted into
loops, and measured as area.
- Projected lifting-surface area is clipped against the fuselage so hidden/internal area is not counted.
- The fuselage is projected more smoothly: each fuselage station area is spread onto the Mach proxy grid with a Gaussian-like
kernel.
- The same projection also returns a Jacobian, so SLSQP knows how changing fuselage area affects Mach-projected
roughness.
Solver And Acceptance
- Solver: [Link] with method='SLSQP'.
- Initial guess: all design variables are zero, meaning start from the current fuselage area curve.
- Jacobian: the code provides analytical gradients for the objective and constraints instead of relying only on finite differences.
- Options: maxiter=10000 and ftol=1e-9, so the solve is allowed to work hard for a smooth result.
- After SLSQP returns, the code converts design variables back to Af_candidate.
- The candidate is accepted only if the final objective is not worse than the initial objective and the constraints have acceptable
margin.
- If the candidate fails that safety check, the result falls back to the original fuselage Af0 and reports optimizer_success=False.
Outputs And Diagnostics
- Af_opt_sq: optimized fuselage cross-sectional area curve.
- r_optimized: optimized fuselage radius curve used for optimized geometry and plots.
- tot_in_sq and tot_opt_sq: total baseline/optimized area curves including lifting surfaces.
- mach_area_distributions: the normal or Mach-proxy distributions used to explain the optimization evidence.
- r_min_effective/r_max_effective and active-source arrays: show which bounds controlled the solution.
- constraint_radius_lower_usage and constraint_radius_upper_usage: show how close the optimized radius is to its lower or
upper bounds.
- constraint_nose_convexity_*: show whether the nose convexity constraint is satisfied.
- rough_reduction, volume_change, and ext_area_change: headline metrics used by cards, advisor, exports, and plots.
Obsolete / Non-Active Notes
- Hard interface constraints appear to have been replaced by soft interface penalties; the comments explicitly say interface
smoothness is no longer handled as separate hard SLSQP constraints.
- CAD-based cross_sections compatibility remains, but the active path says the current mesh-only path should call
NumericalAreaManager.
- enable_lifting_surface_parametric_lobes is optional and defaults to False, so the usual path smooths lifting-area arrays rather
than fitting lobe mixtures.
- Some old aggregate area names are retained as fallbacks for compatibility with earlier manager interfaces.
Wave Drag Evaluation Deep Dive
This expands external_tools/wave_drag_tool.py and the UI workflow that calls it. Read it as: optimized area curves ->
Eminton-Lord wave-drag estimate -> report values.
Main Wave-Drag Idea
- Goal in one line: estimate wave drag from the aircraft's total area-distribution curve.
- The app evaluates both baseline and optimized designs so the user can compare whether smoothing the area curve reduced
wave drag.
- Main idea flow: optimizer result -> exported area curves -> standalone Eminton-Lord evaluator -> D/q and CDWave -> UI
report.
- The tool uses area curves, not full CFD; it is an early-design evaluation method for fast comparison.
- The result should be read as conceptual/engineering evidence, not as a replacement for high-fidelity CFD or wind-tunnel
testing.
Where The Evaluation Starts
- The UI calls run_initial_wave_drag() for the baseline aircraft or run_optimized_wave_drag() for the optimized aircraft.
- Both functions read app.wave_drag_mach and clamp it to at least Mach 1.0.
- The workflow builds or retrieves the correct aircraft object, then calls _run_external_wave_drag().
- _run_external_wave_drag() writes an input JSON file, launches the standalone script, then reads the output JSON file.
- The report text file is written to the local temp directory as aircraft_baseline_wave_drag.txt or aircraft_optimized_wave_drag.txt.
Input Payload
- _write_external_wave_drag_input() forces [Link].call_optimizator() first, because the wave-drag tool needs the
optimizer's area curves.
- The JSON payload contains mach, optimized flag, reference_area, dense_points, and curves.
- reference_area is the mirrored wing reference area, computed from wing span and trapezoidal chord sections.
- dense_points is currently 300; it controls how many points are used when reconstructing the smooth Eminton-Lord fitted curve.
- curves are taken from optimization_result.mach_area_distributions when available.
- If Mach distributions are not available, the workflow falls back to normal total-area curves: tot_in_sq for baseline and tot_opt_sq
for optimized.
Which Area Curve Is Evaluated
- For the baseline case, the workflow exports each distribution's initial_area.
- For the optimized case, the workflow exports each distribution's optimized_area.
- Each exported curve stores x, area, label, and theta_degrees.
- For Mach > 1, there can be several curves, one for each Mach-plane rotation angle.
- For Mach 1 or fallback mode, there is usually one x-normal total-area curve.
- The curve area is total area, meaning fuselage plus lifting-surface contribution, because wave drag depends on the combined
area distribution.
Eminton-Lord Core Method
- _eminton_lord_drag(x, area) is the core wave-drag calculation for one area-distribution curve.
- The curve is sorted by x, negative area is clipped to zero, and the body length is computed from first to last station.
- The first and last area values are treated as endpoints; the internal stations are normalized between 0 and 1.
- _eminton_lord_q() builds the endpoint reference basis for each normalized internal station.
- _eminton_lord_pqq() builds the influence term describing how two internal stations interact in the wave-drag system.
- The code assembles a symmetric influence matrix pqq over all internal stations.
- The right-hand side compares the actual internal area curve against the endpoint-based reference curve.
- Solving pqq * controls = rhs gives control values for the fitted area curve.
- If the matrix is near-singular, the code falls back from direct solve to least-squares instead of crashing.
D/q And CDWave
- D/q is the wave-drag force divided by dynamic pressure; it is an area-like drag measure.
- The tool computes D/q from two pieces: endpoint mismatch and the solved internal control contribution.
- The value is divided by length squared, so aircraft length strongly affects the final D/q scale.
- The code clips the final D/q to be non-negative.
- CDWave is computed as D/q divided by reference_area.
- So the report gives both dimensional-style D/q and nondimensional CDWave.
Smooth Fitted Curve And Roughness
- _eminton_lord_fit_curve() reconstructs a smooth area curve from the Eminton-Lord controls.
- The dense fitted curve is useful because the input stations may be sparse or uneven.
- The function also estimates the second derivative of the fitted area curve.
- Roughness is computed as the integral of squared second derivative, normalized by body-length scale.
- Smoothness is reported as 1 / (1 + normalized_roughness), clipped to the 0..1 range.
- max_drag_x is the x-location where the fitted curve has the largest absolute curvature.
- Qualitatively, max_drag_x points to the area-distribution region most responsible for a local wave-drag problem.
Multiple Mach-Plane Curves
- If the optimizer produced multiple Mach-plane area distributions, the wave-drag tool evaluates each curve separately.
- Each curve result contains its own d_over_q, roughness, smoothness, theta_degrees, and max_drag_x.
- evaluate() then averages D/q values across all curves to produce one overall D/q.
- It also averages roughness values across all curves before computing the overall smoothness score.
- This mirrors the optimizer's Mach-proxy logic: the aircraft should be smooth not only in one x-normal view, but across several
oblique supersonic projections.
Outputs And Report
- The JSON output includes mach, optimized, reference_area, d_over_q, cd_wave, roughness, smoothness, curve_count, and
curve_results.
- The plain text report repeats the main scalar values and then lists each evaluated curve.
- The app displays CDWave and D/q in optimized_export_message after the external tool finishes.
- The result JSON also records input_path, output_path, and report_path so the workflow can locate evidence files.
- The per-curve table is useful for debugging: it shows whether one Mach-plane angle is causing more drag or roughness than
the others.
Important Assumptions And Limits
- The evaluator assumes the provided area distribution is the correct total equivalent area curve for the chosen condition.
- It does not directly solve flow physics around the 3D aircraft; it evaluates the area-rule representation.
- Mach influences the evaluated curves indirectly through the optimizer's Mach-projected distributions, not through a full CFD
solver inside wave_drag_tool.py.
- The code averages multiple Mach-plane curve results with a simple mean.
- This makes the method fast and useful for design iteration, but it is still an approximate early-stage wave-drag estimate.
Obsolete / Non-Active Notes
- The wave-drag tool is active through ui/app_workflows.py and is intentionally standalone with no ParaPy imports.
- The fallback path using normal total-area curves remains useful, but the richer active supersonic path uses
mach_area_distributions when present.
- No obviously dead functions were found inside wave_drag_tool.py; most helpers directly support evaluate() or report
generation.
- The report is plain text by design, so it is not obsolete just because it is visually simple.