Skip to content

Commit 79fa657

Browse files
committed
Improve plotting dispatch
1 parent 4480a2b commit 79fa657

3 files changed

Lines changed: 47 additions & 41 deletions

File tree

.github/workflows/CI.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ jobs:
8888
BUILD_IS_PRODUCTION_BUILD: false
8989
- name: Install matplotlib
9090
run: sudo apt-get install -y python3-matplotlib
91-
- name: Build PyCall
92-
run: julia --project=test -e 'ENV["PYTHON"]=""; using Pkg; Pkg.add("PyCall"); Pkg.build("PyCall")'
93-
- name: Test Makie plotting
94-
run: julia --project=test test/plotting/test_plotting.jl Makie
91+
- name: Build PyCall with system Python
92+
run: julia -e 'ENV["PYTHON"]="python3"; using Pkg; Pkg.add("PyCall"); Pkg.build("PyCall")'
9593
- name: Test ControlPlots plotting
96-
run: julia --project=test --threads=1 test/plotting/test_plotting.jl ControlPlots
94+
env:
95+
JULIA_NUM_THREADS: 1
96+
run: julia -e 'using Pkg; Pkg.test("VortexStepMethod", test_args=["plot-controlplots"], coverage=true)'
9797
- uses: julia-actions/julia-processcoverage@v1
9898
- uses: codecov/codecov-action@v5
9999
with:

test/plotting/test_plotting.jl

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
backend = length(ARGS) >= 1 ? ARGS[1] : "Makie"
2-
if backend == "Makie"
3-
using CairoMakie
4-
elseif backend == "ControlPlots"
1+
backend = if "plot-controlplots" in ARGS
52
using ControlPlots
3+
"ControlPlots"
64
else
7-
error("Unknown plotting backend: $backend. Use \"Makie\" or \"ControlPlots\".")
5+
using CairoMakie
6+
"Makie"
87
end
98

109
using VortexStepMethod
1110
using Test
1211

1312
# Resolve repo data directory for ram air kite assets
14-
const _ram_data_dir = joinpath(dirname(dirname(@__DIR__)), "data", "ram_air_kite")
13+
const _ram_data_dir = joinpath(dirname(dirname(@__DIR__)),
14+
"data", "ram_air_kite")
1515

1616
# Helper to robustly delete files on platforms with occasional file locks
1717
safe_rm(path) = begin
@@ -43,18 +43,15 @@ if !@isdefined ram_wing
4343
end
4444

4545
function create_body_aero()
46-
# Step 1: Define wing parameters
4746
n_panels = 20 # Number of panels
4847
span = 20.0 # Wing span [m]
4948
chord = 1.0 # Chord length [m]
5049
v_a = 20.0 # Magnitude of inflow velocity [m/s]
5150
alpha_deg = 30.0 # Angle of attack [degrees]
5251
alpha = deg2rad(alpha_deg)
5352

54-
# Step 2: Create wing geometry with linear panel distribution
5553
wing = Wing(n_panels, spanwise_distribution=LINEAR)
5654

57-
# Add wing sections
5855
add_section!(wing,
5956
[0.0, span/2, 0.0],
6057
[chord, span/2, 0.0],
@@ -64,7 +61,6 @@ function create_body_aero()
6461
[chord, -span/2, 0.0],
6562
INVISCID)
6663

67-
# Step 3: Initialize aerodynamics
6864
refine!(wing)
6965
body_aero = BodyAerodynamics([wing])
7066
vel_app = [cos(alpha), 0.0, sin(alpha)] .* v_a
@@ -105,15 +101,15 @@ end
105101
safe_rm(joinpath(save_dir,
106102
"Rectangular_wing_geometry_top_view.png"))
107103

108-
# Step 5: Initialize the solvers
104+
# Initialize the solvers
109105
vsm_solver = Solver(body_aero; aerodynamic_model_type=VSM)
110106
llt_solver = Solver(body_aero; aerodynamic_model_type=LLT)
111107

112-
# Step 6: Solve the VSM and LLT
108+
# Solve the VSM and LLT
113109
results_vsm = solve(vsm_solver, body_aero)
114110
results_llt = solve(llt_solver, body_aero)
115111

116-
# Step 7: Plot spanwise distributions
112+
# Plot spanwise distributions
117113
y_coordinates = [panel.aero_center[2]
118114
for panel in body_aero.panels]
119115

@@ -130,7 +126,7 @@ end
130126
@test fig !== nothing
131127
end
132128

133-
# Step 8: Plot polar curves
129+
# Plot polar curves
134130
v_a = 20.0
135131
angle_range = range(0, 20, 20)
136132
fig = plot_polars(
@@ -154,7 +150,7 @@ end
154150
@test isfile(joinpath(save_dir, "Rectangular_Wing_Polars.png"))
155151
safe_rm(joinpath(save_dir, "Rectangular_Wing_Polars.png"))
156152

157-
# Step 9: Test polar data plotting
153+
# Test polar data plotting
158154
body_aero = BodyAerodynamics([ram_wing])
159155
fig = plot_polar_data(body_aero; is_show=false)
160156
if backend == "Makie"

test/runtests.jl

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ using Test, VortexStepMethod
44
cd(@__DIR__) # ensure we're in test/ no matter how tests are launched
55
include("test_data_utils.jl")
66

7-
# Support selective test execution via ]test test_args=["pattern"]
8-
const test_patterns = isempty(ARGS) ? String[] : ARGS
7+
# ControlPlots must run in a separate single-threaded process
8+
const _plot_controlplots = "plot-controlplots" in ARGS
9+
10+
# Filter special args from pattern matching
11+
const test_patterns = filter(a -> a != "plot-controlplots", ARGS)
912

1013
println("Running tests...")
11-
if !isempty(test_patterns)
14+
if _plot_controlplots
15+
println("Running plotting tests with ControlPlots backend")
16+
elseif !isempty(test_patterns)
1217
println("Filtering tests matching: ", test_patterns)
1318
end
1419

@@ -32,25 +37,30 @@ const build_is_production_build = let v = get(ENV, build_is_production_build_env
3237
end::Bool
3338

3439
@testset verbose = true "Testing VortexStepMethod..." begin
35-
if build_is_production_build && should_run_test("bench")
36-
include("bench.jl")
40+
if _plot_controlplots
41+
include("plotting/test_plotting.jl")
42+
else
43+
if build_is_production_build && should_run_test("bench")
44+
include("bench.jl")
45+
end
46+
should_run_test("body_aerodynamics/test_body_aerodynamics.jl") && include("body_aerodynamics/test_body_aerodynamics.jl")
47+
should_run_test("body_aerodynamics/test_results.jl") && include("body_aerodynamics/test_results.jl")
48+
should_run_test("test_refinement_validation.jl") && include("test_refinement_validation.jl")
49+
should_run_test("filament/test_bound_filament.jl") && include("filament/test_bound_filament.jl")
50+
should_run_test("filament/test_semi_infinite_filament.jl") && include("filament/test_semi_infinite_filament.jl")
51+
should_run_test("panel/test_panel.jl") && include("panel/test_panel.jl")
52+
should_run_test("plotting/test_plotting.jl") && include("plotting/test_plotting.jl")
53+
should_run_test("polars/test_polars.jl") && include("polars/test_polars.jl")
54+
should_run_test("ram_geometry/test_kite_geometry.jl") && include("ram_geometry/test_kite_geometry.jl")
55+
should_run_test("settings/test_settings.jl") && include("settings/test_settings.jl")
56+
should_run_test("solver/test_solver.jl") && include("solver/test_solver.jl")
57+
should_run_test("solver/test_unrefined_dist.jl") && include("solver/test_unrefined_dist.jl")
58+
should_run_test("VortexStepMethod/test_VortexStepMethod.jl") && include("VortexStepMethod/test_VortexStepMethod.jl")
59+
should_run_test("wake/test_wake.jl") && include("wake/test_wake.jl")
60+
should_run_test("wing_geometry/test_wing_geometry.jl") && include("wing_geometry/test_wing_geometry.jl")
61+
should_run_test("yaml_geometry/test_yaml_geometry.jl") && include("yaml_geometry/test_yaml_geometry.jl")
62+
should_run_test("Aqua.jl") && include("Aqua.jl")
3763
end
38-
should_run_test("body_aerodynamics/test_body_aerodynamics.jl") && include("body_aerodynamics/test_body_aerodynamics.jl")
39-
should_run_test("body_aerodynamics/test_results.jl") && include("body_aerodynamics/test_results.jl")
40-
should_run_test("test_refinement_validation.jl") && include("test_refinement_validation.jl")
41-
should_run_test("filament/test_bound_filament.jl") && include("filament/test_bound_filament.jl")
42-
should_run_test("filament/test_semi_infinite_filament.jl") && include("filament/test_semi_infinite_filament.jl")
43-
should_run_test("panel/test_panel.jl") && include("panel/test_panel.jl")
44-
should_run_test("polars/test_polars.jl") && include("polars/test_polars.jl")
45-
should_run_test("ram_geometry/test_kite_geometry.jl") && include("ram_geometry/test_kite_geometry.jl")
46-
should_run_test("settings/test_settings.jl") && include("settings/test_settings.jl")
47-
should_run_test("solver/test_solver.jl") && include("solver/test_solver.jl")
48-
should_run_test("solver/test_unrefined_dist.jl") && include("solver/test_unrefined_dist.jl")
49-
should_run_test("VortexStepMethod/test_VortexStepMethod.jl") && include("VortexStepMethod/test_VortexStepMethod.jl")
50-
should_run_test("wake/test_wake.jl") && include("wake/test_wake.jl")
51-
should_run_test("wing_geometry/test_wing_geometry.jl") && include("wing_geometry/test_wing_geometry.jl")
52-
should_run_test("yaml_geometry/test_yaml_geometry.jl") && include("yaml_geometry/test_yaml_geometry.jl")
53-
should_run_test("Aqua.jl") && include("Aqua.jl")
5464
end
5565

5666
nothing

0 commit comments

Comments
 (0)