Skip to content

Commit 08c47f3

Browse files
committed
more efficient polars
1 parent b9868eb commit 08c47f3

File tree

7 files changed

+81
-100
lines changed

7 files changed

+81
-100
lines changed

examples/ram_air_kite.jl

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,48 +35,48 @@ vel_app = [
3535
] * v_a
3636
body_aero.va = vel_app
3737

38-
# Plotting geometry
39-
plot_geometry(
40-
body_aero,
41-
"";
42-
data_type=".svg",
43-
save_path="",
44-
is_save=false,
45-
is_show=true,
46-
view_elevation=15,
47-
view_azimuth=-120
48-
)
38+
# # Plotting geometry
39+
# plot_geometry(
40+
# body_aero,
41+
# "";
42+
# data_type=".svg",
43+
# save_path="",
44+
# is_save=false,
45+
# is_show=true,
46+
# view_elevation=15,
47+
# view_azimuth=-120
48+
# )
4949

5050
# Solving and plotting distributions
5151
@time results = solve(VSM, body_aero)
5252
@time results = solve(VSM, body_aero)
5353

5454
CAD_y_coordinates = [panel.aerodynamic_center[2] for panel in body_aero.panels]
5555

56-
plot_distribution(
57-
[CAD_y_coordinates],
58-
[results],
59-
["VSM"];
60-
title="CAD_spanwise_distributions_alpha_$(round(aoa, digits=1))_beta_$(round(side_slip, digits=1))_yaw_$(round(yaw_rate, digits=1))_v_a_$(round(v_a, digits=1))",
61-
data_type=".pdf",
62-
is_save=false,
63-
is_show=true
64-
)
56+
# plot_distribution(
57+
# [CAD_y_coordinates],
58+
# [results],
59+
# ["VSM"];
60+
# title="CAD_spanwise_distributions_alpha_$(round(aoa, digits=1))_beta_$(round(side_slip, digits=1))_yaw_$(round(yaw_rate, digits=1))_v_a_$(round(v_a, digits=1))",
61+
# data_type=".pdf",
62+
# is_save=false,
63+
# is_show=true
64+
# )
6565

66-
plot_polars(
67-
[VSM],
68-
[body_aero],
69-
[
70-
"VSM from Ram Air Kite OBJ and DAT file",
71-
];
72-
angle_range=range(0, 20, length=20),
73-
angle_type="angle_of_attack",
74-
angle_of_attack=0,
75-
side_slip=0,
76-
v_a=10,
77-
title="ram_kite_panels_$(wing.n_panels)_distribution_$(wing.spanwise_panel_distribution)",
78-
data_type=".pdf",
79-
is_save=false,
80-
is_show=true
81-
)
66+
# plot_polars(
67+
# [VSM],
68+
# [body_aero],
69+
# [
70+
# "VSM from Ram Air Kite OBJ and DAT file",
71+
# ];
72+
# angle_range=range(0, 20, length=20),
73+
# angle_type="angle_of_attack",
74+
# angle_of_attack=0,
75+
# side_slip=0,
76+
# v_a=10,
77+
# title="ram_kite_panels_$(wing.n_panels)_distribution_$(wing.spanwise_panel_distribution)",
78+
# data_type=".pdf",
79+
# is_save=false,
80+
# is_show=true
81+
# )
8282
nothing

src/body_aerodynamics.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function calculate_panel_properties(section_list::Vector{Section}, n_panels::Int
226226
end
227227

228228
"""
229-
calculate_AIC_matrices(body_aero::BodyAerodynamics, model::String,
229+
calculate_AIC_matrices!(body_aero::BodyAerodynamics, model::String,
230230
core_radius_fraction::Float64,
231231
va_norm_array::Vector{Float64},
232232
va_unit_array::Matrix{Float64})
@@ -236,7 +236,7 @@ Calculate Aerodynamic Influence Coefficient matrices.
236236
Returns:
237237
Tuple of (AIC_x, AIC_y, AIC_z) matrices
238238
"""
239-
function calculate_AIC_matrices(body_aero::BodyAerodynamics, model::String,
239+
function calculate_AIC_matrices!(body_aero::BodyAerodynamics, model::String,
240240
core_radius_fraction::Float64,
241241
va_norm_array::Vector{Float64},
242242
va_unit_array::Matrix{Float64})
@@ -249,9 +249,9 @@ function calculate_AIC_matrices(body_aero::BodyAerodynamics, model::String,
249249
velocity_induced, tempvel, va_unit, U_2D = zeros(MVec3), zeros(MVec3), zeros(MVec3), zeros(MVec3)
250250

251251
# Calculate influence coefficients
252-
for icp in 1:length(body_aero.panels)
252+
for icp in eachindex(body_aero.panels)
253253
ep = getproperty(body_aero.panels[icp], evaluation_point)
254-
for jring in 1:body_aero.n_panels
254+
for jring in eachindex(body_aero.panels)
255255
va_unit .= @views va_unit_array[jring, :]
256256
filaments = body_aero.panels[jring].filaments
257257
va_norm = va_norm_array[jring]

src/panel.jl

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ mutable struct Panel
3636
cl_coefficients::Union{Nothing,Vector{Float64}}
3737
cd_coefficients::Union{Nothing,Vector{Float64}}
3838
cm_coefficients::Union{Nothing,Vector{Float64}}
39-
polar_data::Union{Nothing, Tuple{Extrapolation}}
39+
cl_interp::Function
40+
cd_interp::Function
41+
cm_interp::Function
4042
aerodynamic_center::MVec3
4143
control_point::MVec3
4244
bound_point_1::MVec3
@@ -78,10 +80,8 @@ mutable struct Panel
7880
aero_model = isa(section_1.aero_input, String) ? section_1.aero_input : section_1.aero_input[1]
7981

8082
# Initialize aerodynamic properties
81-
cl_coeffs = nothing
82-
cd_coeffs = nothing
83-
cm_coeffs = nothing
84-
polar_data = nothing
83+
cl_coeffs, cd_coeffs, cm_coeffs = nothing, nothing, nothing
84+
cl_interp, cd_interp, cm_interp = ()->nothing, ()->nothing, ()->nothing
8585

8686
if aero_model == "lei_airfoil_breukels"
8787
cl_coeffs, cd_coeffs, cm_coeffs = compute_lei_coefficients(section_1, section_2)
@@ -92,29 +92,21 @@ mutable struct Panel
9292
throw(ArgumentError("Polar data must have same shape"))
9393
end
9494
polar_data = (aero_1 + aero_2) / 2
95-
cl_interp = linear_interpolation(
96-
polar_data[:,1],
97-
polar_data[:,2];
98-
extrapolation_bc=NaN
99-
)
100-
cd_interp = linear_interpolation(
101-
polar_data[:,1],
102-
polar_data[:,3];
103-
extrapolation_bc=NaN
104-
)
105-
cm_interp = linear_interpolation(
106-
polar_data[:,1],
107-
polar_data[:,4];
108-
extrapolation_bc=NaN
109-
)
110-
polar_data = (cl_interp, cd_interp, cm_interp)
95+
cl_interp_ = linear_interpolation(polar_data[:,1], polar_data[:,2]; extrapolation_bc=NaN)
96+
cd_interp_ = linear_interpolation(polar_data[:,1], polar_data[:,3]; extrapolation_bc=NaN)
97+
cm_interp_ = linear_interpolation(polar_data[:,1], polar_data[:,4]; extrapolation_bc=NaN)
98+
cl_interp = (α) -> cl_interp_(α)
99+
cd_interp = (α) -> cd_interp_(α)
100+
cm_interp = (α) -> cm_interp_(α)
111101
elseif aero_model == "interpolations"
112102
cl_left, cd_left, cm_left = section_1.aero_input[2]
113103
cl_right, cd_right, cm_right = section_2.aero_input[2]
114-
cl_interp = (α, β) -> 0.5cl_left(α, β) + 0.5cl_right(α, β)
115-
cd_interp = (α, β) -> 0.5cd_left(α, β) + 0.5cd_right(α, β)
116-
cm_interp = (α, β) -> 0.5cm_left(α, β) + 0.5cm_right(α, β)
117-
polar_data = (cl_interp, cd_interp, cm_interp)
104+
cl_interp = cl_left === cl_right ? cl_left :
105+
(α, β) -> 0.5cl_left(α, β) + 0.5cl_right(α, β)
106+
cd_interp = cd_left === cd_right ? cd_left :
107+
(α, β) -> 0.5cd_left(α, β) + 0.5cd_right(α, β)
108+
cm_interp = cm_left === cm_right ? cm_left :
109+
(α, β) -> 0.5cm_left(α, β) + 0.5cm_right(α, β)
118110
elseif aero_model != "inviscid"
119111
throw(ArgumentError("Unsupported aero model: $aero_model"))
120112
end
@@ -132,7 +124,8 @@ mutable struct Panel
132124
new(
133125
TE_point_1, LE_point_1, TE_point_2, LE_point_2,
134126
chord, nothing, corner_points, aero_model,
135-
cl_coeffs, cd_coeffs, cm_coeffs, polar_data,
127+
cl_coeffs, cd_coeffs, cm_coeffs,
128+
cl_interp, cd_interp, cm_interp,
136129
aerodynamic_center, control_point,
137130
bound_point_1, bound_point_2,
138131
x_airf, y_airf, z_airf,
@@ -269,9 +262,9 @@ function calculate_cl(panel::Panel, alpha::Float64)
269262
elseif panel.aero_model == "inviscid"
270263
return 2π * alpha
271264
elseif panel.aero_model == "polar_data"
272-
return panel.polar_data[1](alpha)
265+
return panel.cl_interp(alpha)
273266
elseif panel.aero_model == "interpolations"
274-
return panel.polar_data[1](alpha, 0.0)
267+
return panel.cl_interp(alpha, 0.0)
275268
else
276269
throw(ArgumentError("Unsupported aero model: $(panel.aero_model)"))
277270
end
@@ -281,6 +274,14 @@ function calculate_cl(polar_data::Nothing, model_type::String, alpha::Float64)
281274
return 2π * alpha
282275
end
283276

277+
function calculate_cl(polar_data::Tuple{Function, Function, Function}, model_type::String, alpha::Float64)
278+
if model_type == "polar_data"
279+
return polar_data[1](alpha)
280+
elseif model_type == "interpolations"
281+
return polar_data[1](alpha, 0.0)
282+
end
283+
end
284+
284285
"""
285286
calculate_cd_cm(panel::Panel, alpha::Float64)
286287
@@ -297,12 +298,12 @@ function calculate_cd_cm(panel::Panel, alpha::Float64)
297298
elseif panel.aero_model == "inviscid"
298299
return 0.0, 0.0
299300
elseif panel.aero_model == "polar_data"
300-
cd = panel.polar_data[2](alpha)
301-
cm = panel.polar_data[3](alpha)
301+
cd = panel.cd_interp(alpha)
302+
cm = panel.cm_interp(alpha)
302303
return cd, cm
303304
elseif panel.aero_model == "interpolations"
304-
cd = panel.polar_data[2](alpha, 0.0)
305-
cm = panel.polar_data[3](alpha, 0.0)
305+
cd = panel.cd_interp(alpha, 0.0)
306+
cm = panel.cm_interp(alpha, 0.0)
306307
return cd, cm
307308
else
308309
throw(ArgumentError("Unsupported aero model: $(panel.aero_model)"))

src/solver.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ function gamma_loop(
188188
relaxation_factor::Float64
189189
)
190190
converged = false
191-
n_panels = body_aero.n_panels
191+
n_panels = length(body_aero.panels)
192192
alpha_array = body_aero.alpha_array
193193
v_a_array = body_aero.v_a_array
194194
Umagw_array = similar(v_a_array)
@@ -244,7 +244,7 @@ function gamma_loop(
244244
end
245245

246246
for (i, (panel, alpha)) in enumerate(zip(panels, alpha_array))
247-
cl_array[i] = calculate_cl(panel.polar_data, panel.aero_model, alpha)
247+
cl_array[i] = calculate_cl(panel, alpha)
248248
end
249249
gamma_new .= 0.5 .* v_a_array.^2 ./ Umagw_array .* cl_array .* chord_array
250250

src/wing_geometry.jl

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -239,23 +239,14 @@ function calculate_new_aero_input(aero_input,
239239
cl_left, cd_left, cm_left = aero_input[section_index][2]
240240
cl_right, cd_right, cm_right = aero_input[section_index + 1][2]
241241

242-
@info "Interpolation object comparison" begin
243-
objects_equal = (
244-
cl_left === cl_right,
245-
cd_left === cd_right,
246-
cm_left === cm_right
247-
)
248-
(; objects_equal)
249-
end
250-
251-
CL_interp = cl_left === cl_right ? cl_left :
242+
cl_interp = cl_left === cl_right ? (α, β) -> cl_left[α, β] :
252243
(α, β) -> left_weight * cl_left[α, β] + right_weight * cl_right[α, β]
253-
CD_interp = cd_left === cd_right ? cd_left :
244+
cd_interp = cd_left === cd_right ? (α, β) -> cd_left[α, β] :
254245
(α, β) -> left_weight * cd_left[α, β] + right_weight * cd_right[α, β]
255-
CM_interp = cm_left === cm_right ? cm_left :
246+
cm_interp = cm_left === cm_right ? (α, β) -> cm_left[α, β] :
256247
(α, β) -> left_weight * cm_left[α, β] + right_weight * cm_right[α, β]
257248

258-
return ("interpolations", (CL_interp, CD_interp, CM_interp))
249+
return ("interpolations", (cl_interp, cd_interp, cm_interp))
259250

260251
elseif model_type == "lei_airfoil_breukels"
261252
tube_diameter_left = aero_input[section_index][2][1]

test/test_body_aerodynamics.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,13 +195,13 @@ end
195195
va_norm_array = fill(norm(Uinf), length(coord))
196196
va_unit_array = repeat(reshape(Uinf ./ norm(Uinf), 1, 3), length(coord))
197197
calculate_AIC_matrices!(
198-
wing_aero,
198+
body_aero,
199199
"VSM",
200200
core_radius_fraction,
201201
va_norm_array,
202202
va_unit_array
203203
)
204-
AIC_x, AIC_y, AIC_z = wing_aero.AIC[1, :, :], wing_aero.AIC[2, :, :], wing_aero.AIC[3, :, :]
204+
AIC_x, AIC_y, AIC_z = body_aero.AIC[1, :, :], body_aero.AIC[2, :, :], body_aero.AIC[3, :, :]
205205

206206
# Compare matrices with higher precision for VSM
207207
@test isapprox(MatrixU, AIC_x, atol=1e-8)

test/test_panel.jl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,17 +134,6 @@ end
134134
# Create panel
135135
panel = create_panel(section1, section2)
136136

137-
@testset "Panel Polar Data Initialization" begin
138-
# Test if panel has polar data
139-
@test hasproperty(panel, :polar_data)
140-
@test !isnothing(panel.polar_data)
141-
@test size(panel.polar_data) == size(polar_data)
142-
143-
# Test if panel polar data is correctly averaged
144-
expected_data = (polar_data + big_polar_data) / 2
145-
@test isapprox(panel.polar_data, expected_data, rtol=1e-5)
146-
end
147-
148137
@testset "Coefficient Interpolation" begin
149138
test_alphas = deg2rad.([-5.0, 0.0, 5.0, 10.0])
150139
for alpha in test_alphas

0 commit comments

Comments
 (0)