Skip to content

Commit 0c94c6d

Browse files
authored
Merge pull request #340 from OpenSourceAWE/agent/153-remove-the-parameter-body-aero-from-the-
Build a Solver from VSMSettings or from panel and section counts, deprecate the body_aero constructors, and check the sizes in solve!
2 parents 7724c0d + 4cd7a7e commit 0c94c6d

31 files changed

Lines changed: 254 additions & 142 deletions

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
### Added
66

7+
- `Solver(settings)` and `Solver(n_panels, n_unrefined_sections)` build a solver without
8+
a `BodyAerodynamics`; keyword arguments override the settings.
79
- `set_va!(body_aero, va_vec, omega; reference_point)` turns the body about
810
`reference_point` [m] instead of the origin. The point is stored on
911
`BodyAerodynamics`, starts at the origin, and is kept by later `set_va!`, `reinit!`
@@ -24,9 +26,15 @@
2426
- The Makie `plot!` methods for a `Panel` or a `BodyAerodynamics` return a
2527
`Vector{Makie.AbstractPlot}` instead of a `Vector{Any}`; for a `BodyAerodynamics`
2628
drawn as flat panels it is one flat list rather than a list per panel.
29+
- `Solver(body_aero; kwargs...)` and `Solver(body_aero, settings)` are deprecated and warn
30+
on use; build the solver with `Solver(settings)` or
31+
`Solver(n_panels, n_unrefined_sections)` instead.
2732

2833
### Fixed
2934

35+
- `solve!` and `solve` throw a `DimensionMismatch` naming both sizes for a `body_aero` whose
36+
panel or unrefined-section count differs from the solver's, where they failed on a
37+
broadcast partway through or silently left section results at zero.
3038
- `set_va!(body_aero, settings)` applies `condition.yaw_rate` as a turn rate about the
3139
body z axis; it was read from the settings file and ignored.
3240
- The `VSMSolution` docstring gives `lift_dist`, `drag_dist` and `panel_moment_dist` in

data/TUDELFT_V3_KITE/vsm_settings_coarse.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ condition:
4444
# Define wing geometry files and discretization parameters
4545
wings:
4646
- name: V3_Kite # Wing identifier for output labeling
47-
geometry_file: data/TUDELFT_V3_KITE/aero_geometry.yaml
47+
geometry_file: data/TUDELFT_V3_KITE/aero_geometry_coarse_discretisation.yaml
4848
n_panels: 54 # Total number of panels along wingspan
4949
spanwise_panel_distribution: SPLIT_PROVIDED # Panel spacing algorithm
5050
spanwise_direction: [0.0, 1.0, 0.0] # Unit vector defining wingspan direction

docs/src/examples.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ julia> set_va!(body_aero, va_vec, [0, 0, 0.1])
8484
#### Step 5: Initialize solvers for both LLT and VSM methods
8585

8686
```julia
87-
julia> llt_solver = Solver(body_aero; aerodynamic_model_type=LLT)
88-
julia> vsm_solver = Solver(body_aero; aerodynamic_model_type=VSM)
87+
julia> llt_solver = Solver(wing.n_panels, wing.n_unrefined_sections; aerodynamic_model_type=LLT)
88+
julia> vsm_solver = Solver(wing.n_panels, wing.n_unrefined_sections; aerodynamic_model_type=VSM)
8989
```
9090

9191
#### Step 6: Solve using both methods

docs/src/private_functions.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ settings_range
1212

1313
### Solver, forces and circulation
1414
```@docs
15+
n_unrefined_sections
16+
solver_kwargs
17+
check_dimensions
1518
calculate_AIC_matrices!
1619
gamma_loop!
1720
build_spanwise_laplacian!

docs/src/settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ settings = VSMSettings("my/vsm_settings.yaml"; data_prefix=false) # as written
1111

1212
wing = Wing(settings)
1313
body_aero = BodyAerodynamics([wing])
14-
solver = Solver(body_aero, settings)
14+
solver = Solver(settings)
1515
set_va!(body_aero, settings)
1616
```
1717

examples/V3_kite.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ wing = Wing(settings)
4242
refine!(wing)
4343
body_aero = BodyAerodynamics([wing])
4444
VortexStepMethod.reinit!(body_aero)
45-
solver = Solver(body_aero, settings)
45+
solver = Solver(settings)
4646
solver.reference_point .= REFERENCE_POINT
4747

4848
if DEFORM
@@ -75,7 +75,7 @@ if NEURALFOIL
7575
refine!(wing_nf)
7676
body_nf = BodyAerodynamics([wing_nf])
7777
VortexStepMethod.reinit!(body_nf)
78-
solver_nf = Solver(body_nf, settings_nf)
78+
solver_nf = Solver(settings_nf)
7979
solver_nf.reference_point .= REFERENCE_POINT
8080

8181
# Reading the generated directory instead of the OBJ shows the airfoils the polar

examples/V3_neuralfoil.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,18 @@ wing_cfd = Wing(settings_cfd)
8181
refine!(wing_cfd)
8282
body_cfd = BodyAerodynamics([wing_cfd])
8383
VortexStepMethod.reinit!(body_cfd)
84-
solver_cfd = Solver(body_cfd, settings_cfd)
84+
solver_cfd = Solver(settings_cfd)
8585

8686
println("Creating wing with NeuralFoil polars...")
8787
wing_nf = Wing(nf_yaml; n_panels=50, spanwise_distribution=LINEAR)
8888
refine!(wing_nf)
8989
body_nf = BodyAerodynamics([wing_nf])
9090
VortexStepMethod.reinit!(body_nf)
91-
solver_nf = Solver(body_nf, settings_cfd)
91+
settings_nf = VSMSettings("TUDELFT_V3_KITE/vsm_settings.yaml")
92+
settings_nf.wings[1].geometry_file = nf_yaml
93+
settings_nf.solver_settings.relaxation_factor = RELAXATION
94+
settings_nf.solver_settings.artificial_damping = ARTIFICIAL_DAMPING
95+
solver_nf = Solver(settings_nf)
9296

9397
# Compare CFD-polar and NeuralFoil-polar wings against published references
9498
# (Poland 2025 RANS CFD and wind tunnel). `plot_polars` sweeps each solver over the

examples/bench.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ va_vec = [cos(alpha), 0.0, sin(alpha)] .* va
4141
set_va!(body_aero, va_vec)
4242

4343
# Step 4: Initialize solvers for both LLT and VSM methods
44-
llt_solver = Solver(body_aero; aerodynamic_model_type=LLT)
45-
vsm_solver = Solver(body_aero; aerodynamic_model_type=VSM)
44+
llt_solver = Solver(wing.n_panels, wing.n_unrefined_sections; aerodynamic_model_type=LLT)
45+
vsm_solver = Solver(wing.n_panels, wing.n_unrefined_sections; aerodynamic_model_type=VSM)
4646

4747
# Step 5: Solve using both methods
4848
results_vsm = solve(vsm_solver, body_aero, nothing)
@@ -66,7 +66,7 @@ body_aero = BodyAerodynamics([wing])
6666

6767
# Create solvers
6868
vsm_solver = Solver(
69-
body_aero;
69+
wing.n_panels, wing.n_unrefined_sections;
7070
aerodynamic_model_type=VSM,
7171
is_with_artificial_damping=false,
7272
solver_type=LOOP,

examples/billowing.jl

Lines changed: 10 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,12 @@ literature_paths = [
3030
"windtunnel_alpha_sweep_beta_00_0_Poland_2025_Rey_5e5.csv"),
3131
]
3232

33-
# Load solver settings (coarse: 54 panels, matches 10-section geometry)
34-
settings_data = VortexStepMethod.YAML.load_file(
35-
joinpath(v3_dir, "vsm_settings_coarse.yaml"))
36-
condition_cfg = settings_data["condition"]
37-
solver_cfg = settings_data["solver_settings"]
38-
wing_cfg = settings_data["wings"][1]
39-
n_panels = wing_cfg["n_panels"]
33+
# Coarse settings: 54 panels on the 10-section geometry
34+
settings = VSMSettings(joinpath(v3_dir, "vsm_settings_coarse.yaml"); data_prefix=false)
35+
settings.wings[1].geometry_file = joinpath(project_dir, settings.wings[1].geometry_file)
36+
n_panels = settings.wings[1].n_panels
4037

41-
BILLOWING_PCT = get(wing_cfg, "billowing_percentage", 0.0)
38+
BILLOWING_PCT = settings.wings[1].billowing_percentage
4239

4340
labels = [
4441
"VSM flat",
@@ -49,9 +46,7 @@ labels = [
4946
"WindTunnel Re=5e5",
5047
]
5148

52-
# Load coarse geometry (10 structural rib sections)
53-
geom_data = VortexStepMethod.YAML.load_file(
54-
joinpath(v3_dir, "aero_geometry_coarse_discretisation.yaml"))
49+
geom_data = VortexStepMethod.YAML.load_file(settings.wings[1].geometry_file)
5550
section_headers = geom_data["wing_sections"]["headers"]
5651
section_rows = geom_data["wing_sections"]["data"]
5752

@@ -84,43 +79,13 @@ body_aero_bill = BodyAerodynamics([wing_bill])
8479
VortexStepMethod.reinit!(body_aero_bill)
8580

8681
# --- Build solvers ---
87-
function make_solver(body_aero)
88-
Solver(body_aero;
89-
solver_type=(solver_cfg["solver_type"] == "NONLIN" ?
90-
NONLIN : LOOP),
91-
aerodynamic_model_type=getproperty(
92-
VortexStepMethod,
93-
Symbol(solver_cfg["aerodynamic_model_type"])),
94-
density=solver_cfg["density"],
95-
max_iterations=solver_cfg["max_iterations"],
96-
rtol=solver_cfg["rtol"],
97-
tol_reference_error=solver_cfg["tol_reference_error"],
98-
relaxation_factor=solver_cfg["relaxation_factor"],
99-
is_with_artificial_damping=solver_cfg["artificial_damping"],
100-
artificial_damping=(
101-
k2=solver_cfg["k2"], k4=solver_cfg["k4"]),
102-
type_initial_gamma_distribution=getproperty(
103-
VortexStepMethod,
104-
Symbol(solver_cfg["type_initial_gamma_distribution"])),
105-
use_gamma_prev=get(solver_cfg, "use_gamma_prev",
106-
get(solver_cfg, "use_gamme_prev", true)),
107-
core_radius_fraction=solver_cfg["core_radius_fraction"],
108-
mu=solver_cfg["mu"],
109-
is_only_f_and_gamma_output=get(
110-
solver_cfg, "calc_only_f_and_gamma", false),
111-
correct_aoa=get(solver_cfg, "correct_aoa", false),
112-
reference_point=get(solver_cfg, "reference_point",
113-
[0.422646, 0.0, 9.3667]),
114-
)
115-
end
116-
117-
solver_flat = make_solver(body_aero_flat)
118-
solver_bill = make_solver(body_aero_bill)
82+
solver_flat = Solver(settings; reference_point=[0.422646, 0.0, 9.3667])
83+
solver_bill = Solver(settings; reference_point=[0.422646, 0.0, 9.3667])
11984

12085
# --- Set flight conditions ---
121-
wind_speed = condition_cfg["wind_speed"]
86+
wind_speed = settings.condition.wind_speed
12287
angle_of_attack_deg = 10.0
123-
sideslip_deg = condition_cfg["beta"]
88+
sideslip_deg = settings.condition.beta
12489

12590
α0 = deg2rad(angle_of_attack_deg)
12691
β0 = deg2rad(sideslip_deg)

examples/linearize_check.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ yaml = obj_to_yaml(
2323
wing = Wing(yaml; n_panels=16)
2424
body_aero = BodyAerodynamics([wing])
2525

26-
solver = Solver(body_aero;
26+
solver = Solver(wing.n_panels, wing.n_unrefined_sections;
2727
aerodynamic_model_type=VSM,
2828
is_with_artificial_damping=false,
2929
rtol=1e-7,

0 commit comments

Comments
 (0)