Add neuralfoil and automatic conversion from obj to yaml#249
Open
1-Bart-1 wants to merge 89 commits into
Open
Conversation
Integrates v3.0.0 changes from main: - Unified Wing type (RamAirWing -> ObjWing) - use_prior_polar feature for polar data reuse - Allocation optimizations (scalar ops, LazyBufferCache) - parse_enum for safe enum parsing - Reference point validation - Backend-agnostic test infrastructure (CairoMakie) - c_ref and q_ref reference quantities Preserves neuralfoil additions: - NeuralFoil exports and integration (kulfan, neuralfoil, obj_slice, polar_generation) - polars_dir parameter for per-section polars in ObjWing - plot_airfoil_slices in Makie extension - Printf dependency for neuralfoil formatting Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The fitter omitted AeroSandbox's leading-edge-modification (LEM) basis and reused the first Bernstein weight as the leading_edge_weight. That feeds the wrong value into NeuralFoil network input #17 and lets the surface weights absorb LE shaping, so predictions (especially near CL_max) drifted from the reference the network was trained on. Rewrite fit_kulfan_parameters as a single least-squares system with the shared LEM column `x*(1-x)^(n+0.5)` and a trailing-edge thickness term, matching aerosandbox.get_kulfan_parameters. Add the LEM term to kulfan_to_coordinates so reconstruction stays consistent. Remove the now-unused per-surface helpers. Validated against aerosandbox 4.2.9 / neuralfoil 0.3.2 on the ram air kite foil: Kulfan parameters agree to ~1e-13 and CL/CD/CM to <1e-6 across alpha = -10..20 deg. Add test/neuralfoil regression tests pinning these reference values, and an examples/neuralfoil_benchmark.jl matching the upstream Python speed benchmark. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
calculate_AIC_matrices\! is now zero-alloc (7 allocs) after the main merge's calc_forces\! work, so the 1.12-specific @test_broken guard unexpectedly passed. Collapse it to a plain @test and drop the now-unused IS_JULIA_1_12_OR_NEWER const. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
obj_to_yaml slices a 3D wing .obj at n_sections spanwise stations and writes the package's native geometry inputs: per-section airfoil .dat files, NeuralFoil polar CSVs, and a geometry.yaml referencing them via wing_sections / wing_airfoils. After conversion everything flows through the standard Wing(geometry_file) path. Each section's LE/TE points are taken from the slice itself (min-x / max-x of the planar y-slice), so the LE/TE, airfoil shape, and polar are all derived from one source of truth rather than mixing the kite circle-arc parameterization with planar slicing. Extend WingAirfoilInfo with an optional dat_file so the airfoil shape stays recoverable from the YAML for re-plotting / re-evaluation. ObjWing is left in place for now (it still builds the full physics wing with mass/inertia). Verified end-to-end on the ram air kite mesh: obj_to_yaml -> Wing(yaml) -> BodyAerodynamics -> solve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Write geometry.yaml in flow style (one-line headers, one line per section/airfoil row) instead of YAML.write_file's verbose block style. Add read_dat_coordinates and airfoils_from_yaml helpers; route generate_polar_from_dat through the shared reader to remove duplication. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
plot_airfoils(geometry_file) plots every airfoil of a YAML wing in a subfigure grid, reading the .dat files referenced by wing_airfoils (a loaded body does not retain airfoil coordinates, so the YAML is the source). plot_section_polars( body_aero, :cl|:cd|:cm) plots one coefficient vs alpha for every POLAR_VECTORS section — the existing plot_polar_data only handles the single-airfoil POLAR_MATRICES surface. Document obj_to_yaml and both plot functions. Verified headless with CairoMakie. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Prepend the standard examples-project activation snippet to every example so they run against examples/Project.toml regardless of how Julia is launched. Add obj_to_yaml_kite.jl demonstrating the .obj -> YAML route plus the new airfoil and per-section polar plots, register it in the menu, and add BenchmarkTools / Interpolations to the examples project for the NeuralFoil benchmark. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
PythonCall/CondaPkg generates .CondaPkg in whichever project initializes it (root, examples), not just the two paths previously listed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lpha,delta) Architecture: VSM core now ingests one standard format (geometry YAML + polar CSVs) and depends on nothing heavy. Generation moves to lib/ sub-packages wired via [sources] (SciML monorepo pattern): - core: solver, geometry, yaml/csv readers, Cp types + IO. Sheds Xfoil, NPZ, Kulfan, NeuralFoil. - lib/AirfoilAero (-> core): kulfan, neuralfoil, xfoil/neuralfoil solvers, deform, polar + cp generation. Owns Xfoil/NPZ. - lib/ObjAdapter (-> AirfoilAero): obj mesh reading, slicing, obj_to_yaml, dat writing. ObjWing/refine_obj_wing! dropped (convert-then-load via Wing(yaml)). Cp core (already validated): read_cp_data/cp.csv -> Section.cp_data -> averaged into Panel.cp_polar in init_aero! -> evaluated per panel at (alpha, delta) in calc_forces! -> VSMSolution.cp_upper_dist/cp_lower_dist + delta_cp(sol). All-or-none Cp + uniform n_chord validated. deform_section gains flip_thickness_neg (kite default true) for negative-flap lower-surface pivot. Pipeline-generated polars (polars_neuralfoil/, polars_CFD_NF_combined/) untracked + gitignored; regenerate via AirfoilAero/ObjAdapter. All three packages precompile and load. Tests/examples not yet repointed. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…foilAero Core AeroModel LEI_AIRFOIL_BREUKELS renamed to POLY (kept as deprecated alias). Sections now carry (cl_coeffs, cd_coeffs, cm_coeffs) instead of (tube_diameter, camber); init_aero! and refinement interpolate the coeff vectors, calculate_cl/ cd/cm evaluate the polynomial. The Breukels (tube_diameter, camber) -> coeffs derivation moves to AirfoilAero.lei_poly_coeffs, so core no longer knows any airfoil-specific model - only generic polynomial evaluation. AeroData union: (tube_diameter, camber) NTuple replaced by the 3-vector poly coeff tuple. Validated: POLY wing (coeffs from lei_poly_coeffs) refines and solves with finite, sensible cl/cd. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…h .dat Move the airfoil-general I/O (read_dat_coordinates, write_dat, write_polar_csv, generate_polar_from_coordinates, generate_polar_from_dat) into AirfoilAero so it has a clean .dat-in / CSV-out interface. ObjAdapter keeps only obj-specific generate_neuralfoil_polars, rewired through AirfoilAero. obj_to_yaml now writes the per-section .dat and generates its polar via AirfoilAero.generate_polar_from_dat, making .dat the actual ObjAdapter->AirfoilAero handoff. Validated end-to-end: obj -> slices -> .dat -> AirfoilAero polar CSVs + geometry YAML -> core Wing(yaml) loads and solves with finite cl. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Foundational step for repointing the test suite to the lib sub-packages. The test files themselves (ObjWing/create_polars/generate_*/LEI callers) still need repointing; suite is red until then. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
awegroup/awesIO already specifies the AWE geometry YAML matching our wing_sections/ wing_airfoils layout, with a type taxonomy (polars/breukels_regression/neuralfoil/ masure_regression/inviscid) that maps onto the converter/core split. Plan to adopt it (add per-section VUP up-vector, type taxonomy, alpha_range/reynolds) rather than a parallel format. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Alignment plan clarifies that awesIO wing_airfoils "type" is a solver/generation concept (AirfoilAero), not an airfoil property; core only sees resolved polars/poly/ inviscid. Plan to adopt awesIO wing_sections VUP up-vector + type taxonomy. Draft (unsubmitted) issue proposes an optional chord-slice Cp format for aero-structural coupling, which awesIO currently lacks. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- neuralfoil: kulfan/neuralfoil symbols now from AirfoilAero. - polars: create_polars from AirfoilAero (read_aero_matrix stays core). - wing_geometry: LEI (t,camber) test rewritten to POLY with coeffs from AirfoilAero.lei_poly_coeffs; asserts refinement interpolates the coeff vectors. The 6 ObjWing-based tests are not repointed: ObjWing built an obj+single-foil XFoil POLAR_MATRICES wing, a converter workflow ObjAdapter does not yet rebuild (obj_to_yaml does per-section NeuralFoil instead). Needs a decision. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Core YAML loader gains POLAR_MATRICES support: wing_airfoils info_dict may carry cl_file_path/cd_file_path/cm_file_path; load_matrix_polar_data reads the three (alpha x delta) matrices via read_aero_matrix. ObjAdapter.obj_to_matrix_yaml slices the mesh for LE/TE (perpendicular_sections), generates one shared airfoil's cl/cd/cm matrices via AirfoilAero.create_polars, and writes the geometry YAML - the convert-then-load replacement for the dropped live ObjWing. Removed tic/toc (Timers) from create_polars. Validated: obj+foil -> yaml -> Wing(yaml) loads POLAR_MATRICES and solves. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add ram_air_matrix_wing() test helper (obj_to_matrix_yaml -> Wing(yaml)) and repoint wake/forwarddiff/results/refinement_validation/plotting to it. kite_geometry: imports split (mesh utils from ObjAdapter, aero_matrix from core); the three ObjWing-internal testsets (radius/gamma_tip/UNCHANGED/obj deform!) are skipped with a redesign TODO since that behavior was intentionally dropped. Numerics of the converted-wing tests still need a full test-env run to confirm (assertions may need tolerance updates). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ups green Verified in the test env: wing_geometry 295/295 (POLY), neuralfoil+polars 27/27 (AirfoilAero), refinement_validation+wake+results+forwarddiff 55/55 (obj+foil -> POLAR_MATRICES -> Wing converter replacement, incl. ForwardDiff). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…d polars - Move neuralfoil/kulfan cross-validation test to lib/AirfoilAero/test/runtests.jl with its own fixture (test/data/test_airfoil.dat = the former midspan foil coords, keeping the hardcoded aerosandbox/neuralfoil reference values valid). AirfoilAero gains [extras]/[targets] so it tests independently (SciML monorepo style). - Remove the kite midspan foil.dat + generated cl/cd/cm foil polars from data/ (regenerated from the .obj); gitignore them. - Remove neuralfoil_benchmark.jl + neuralfoil_polars.jl examples. - Condense multiline inline comments in the yaml loader. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.