Skip to content

Remove ControlPlots; migrate plotting to Makie + MakieControlPlots#248

Closed
1-Bart-1 wants to merge 73 commits into
mainfrom
rm-controlplots
Closed

Remove ControlPlots; migrate plotting to Makie + MakieControlPlots#248
1-Bart-1 wants to merge 73 commits into
mainfrom
rm-controlplots

Conversation

@1-Bart-1

Copy link
Copy Markdown
Member

Removes the ControlPlots plotting backend and migrates all plotting to Makie, using MakieControlPlots where it fits.

Changes

  • Removed the ControlPlots extension, examples_cp/, and the PythonCall/Matplotlib setup (bin/install_controlplots, CI matplotlib/PyCall steps, LocalPreferences CondaPkg defaults).
  • Collapsed the plot-backend dispatch (PlotBackend/MakieBackend/ControlPlotsBackend/set_plot_backend!). Plotting works as soon as a Makie backend and MakieControlPlots are loaded. Also dropped the never-implemented plot_circulation_distribution.
  • VortexStepMethodMakieExt now triggers on ["Makie", "MakieControlPlots"] and renders plot_section_polars via MakieControlPlots.plot. Everything else (geometry, distributions, polars, 3D surfaces, airfoil grids) stays native Makie — MakieControlPlots' standalone-figure API can't compose those.
  • Examples load GLMakie/CairoMakie + MakieControlPlots.
  • Docs/README updated (two-backend table, MakieControlPlots mention).
  • Regenerated the 1.11 and 1.12 default manifests; removed dead :PyCall Aqua ignores.

Validation (headless)

  • Aqua: 10/10
  • Plotting tests: 58/58
  • New plot_section_polars / plot_airfoils tests: 4/4

🤖 Generated with Claude Code

1-Bart-1 and others added 21 commits December 7, 2025 21:55
…ged alpha_geometric to angle between va and chord, changed settings_jl to default the corrected_aoa to false
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>
…Plots

- Delete the ControlPlots extension, examples_cp/, and the PythonCall/
  Matplotlib setup (bin/install_controlplots, CI matplotlib/PyCall steps).
- Collapse the plot-backend dispatch (PlotBackend/MakieBackend/
  ControlPlotsBackend/set_plot_backend\!); plotting works once a Makie backend
  and MakieControlPlots are loaded. Drop the never-implemented
  plot_circulation_distribution.
- VortexStepMethodMakieExt now triggers on ["Makie", "MakieControlPlots"] and
  renders plot_section_polars via MakieControlPlots; other plots stay native
  Makie.
- Examples load GLMakie/CairoMakie + MakieControlPlots.
- Add tests for plot_section_polars and plot_airfoils; regenerate the 1.11 and
  1.12 default manifests; drop dead PyCall Aqua ignores.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ufechner7

ufechner7 commented Jun 30, 2026

Copy link
Copy Markdown
Member

You write: "Everything else (geometry, distributions, polars, 3D surfaces, airfoil grids) stays native Makie — MakieControlPlots' standalone-figure API can't compose those."

This is not sufficient. It must be possible to create each of the subplots of the large diagrams using MakieControlPlots.jl

It might be a good idea to have a separate plot_results.jl script with a sub-menu to select the plots you want to see, but each plot should be in a separate window. If you write a paper, selecting and combining plots should be done in the LaTeX document.

@1-Bart-1

1-Bart-1 commented Jul 1, 2026

Copy link
Copy Markdown
Member Author

Feel free to fix this @ufechner7 , but this is the same as it was when using ControlPlots. This PR is just kept as simple as possible.

@1-Bart-1 1-Bart-1 force-pushed the neuralfoil branch 2 times, most recently from 240f6fa to e63322b Compare July 1, 2026 14:35
Base automatically changed from neuralfoil to main July 13, 2026 08:25
@1-Bart-1

Copy link
Copy Markdown
Member Author

Superseded by #253, which re-applies this change (remove ControlPlots, migrate to Makie + MakieControlPlots) as a single clean commit on current main. This branch predated main's NeuralFoil reorganization into the AirfoilAero/ObjAdapter submodules and could not be merged cleanly. Closing in favor of #253.

@1-Bart-1 1-Bart-1 closed this Jul 13, 2026
1-Bart-1 added a commit that referenced this pull request Jul 13, 2026
)

* Remove ControlPlots; migrate plotting to Makie + MakieControlPlots

Redone fresh on current main (the original PR #248 branch predated main's
NeuralFoil reorganization into the AirfoilAero/ObjAdapter submodules and could
not be merged cleanly).

- Remove the ControlPlots extension, examples_cp/, and the PythonCall/Matplotlib
  setup (bin/install_controlplots, CondaPkg LocalPreferences defaults).
- Collapse the PlotBackend/MakieBackend/ControlPlotsBackend/set_plot_backend\!
  dispatch; plotting works once a Makie backend and MakieControlPlots are loaded.
  Drop the never-implemented plot_circulation_distribution.
- VortexStepMethodMakieExt now triggers on ["Makie", "MakieControlPlots"] and
  renders plot_section_polars through MakieControlPlots.plot; everything else
  stays native Makie.
- Examples/docs/tests load GLMakie/CairoMakie + MakieControlPlots.
- Regenerate the 1.11 and 1.12 default manifests; drop dead :PyCall Aqua ignores.

Validation (headless, Julia 1.12): plotting 58/58, Aqua 10/10; package loads on
1.11 and 1.12 with the regenerated manifests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* CI: run GLMakie/MakieControlPlots under a virtual display

MakieControlPlots activates GLMakie on load, whose OpenGL init fails on the
headless Linux runners (no DISPLAY). Install xvfb + libgl1-mesa-dri and run the
Linux test jobs under `xvfb-run -a`; give the docs job a background Xvfb via
DISPLAY. Windows/macOS runners keep their own display context (no prefix).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* CI: give the setup-test example run a display too

test/test_setup.sh runs every example via menu.jl --run-all, which now loads
MakieControlPlots (→ GLMakie). Add libgl1-mesa-dri and run the script under
xvfb-run so GLMakie can initialize headlessly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Examples self-import GLMakie + MakieControlPlots; drop backend-agnostic wiring

With ControlPlots gone there is only one plotting backend family, so examples no
longer need to stay backend-agnostic for a separate menu_cp() launcher. Every
plotting example now imports GLMakie + MakieControlPlots directly (bench/cleanup
don't plot, so they don't). Remove the now-meaningless "backend-agnostic" check
from test/test_setup.sh and stale two-backend comments in test_plotting.jl.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Qualify save() as GLMakie.save() in examples

MakieControlPlots exports its own JLD2-based `save`, which clashes with Makie's
figure `save` once an example does `using GLMakie` + `using MakieControlPlots`.
Qualify the raw figure-save calls (ram_air_kite, V3_neuralfoil) as GLMakie.save.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Run plotting tests on Linux only

GLMakie's PrecompileTools workload creates a screen (glfwInit), which fails on
the headless macOS/Windows CI runners (no GPU/display, and xvfb is Linux-only).
Loading MakieControlPlots pulls in GLMakie, so gate the plotting test include on
Sys.islinux(); the Linux jobs run them under xvfb. All other tests still run on
every platform (Windows showed 5111 passing with only the plotting set erroring).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants