Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions examples/ram_air_kite.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ body_aero = BodyAerodynamics([wing];)

if DEFORM
alpha = [deg2rad(10), 0]
beta = [deg2rad(10), 0]
@time VortexStepMethod.deform!(wing, alpha, beta; width=1.0)
delta = [deg2rad(10), 0]
@time VortexStepMethod.deform!(wing, alpha, delta; width=1.0)
@time VortexStepMethod.init!(body_aero)
end

Expand Down Expand Up @@ -62,7 +62,7 @@ PLOT && plot_distribution(
[body_y_coordinates],
[results],
["VSM"];
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))",
title="CAD_spanwise_distributions_alpha_$(round(aoa, digits=1))_delta_$(round(side_slip, digits=1))_yaw_$(round(yaw_rate, digits=1))_v_a_$(round(v_a, digits=1))",
data_type=".pdf",
is_save=false,
is_show=true,
Expand Down
2 changes: 1 addition & 1 deletion examples/stall_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ PLOT && plot_distribution(
[CAD_y_coordinates, CAD_y_coordinates],
[results, results_with_stall],
["VSM", "VSM with stall correction"];
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))",
title="CAD_spanwise_distributions_alpha_$(round(aoa, digits=1))_delta_$(round(side_slip, digits=1))_yaw_$(round(yaw_rate, digits=1))_v_a_$(round(v_a, digits=1))",
data_type=".pdf",
save_path=joinpath(save_folder, "spanwise_distributions"),
is_save=false,
Expand Down
8 changes: 4 additions & 4 deletions src/VortexStepMethod.jl
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ Enumeration of the implemented aerodynamic models. See also: [AeroData](@ref)
# Elements
- `LEI_AIRFOIL_BREUKELS`: Polynom approximation for leading edge inflatable kites
- `POLAR_VECTORS`: Polar vectors as function of alpha (lookup tables with interpolation)
- `POLAR_MATRICES`: Polar matrices as function of alpha and beta (lookup tables with interpolation)
- `POLAR_MATRICES`: Polar matrices as function of alpha and delta (lookup tables with interpolation)
- INVISCID

where `alpha` is the angle of attack, `beta` is trailing edge angle.
where `alpha` is the angle of attack, `delta` is trailing edge angle.
"""
@enum AeroModel begin
LEI_AIRFOIL_BREUKELS
Expand Down Expand Up @@ -153,9 +153,9 @@ Union of different definitions of the aerodynamic properties of a wing section.
- nothing for INVISCID
- (`tube_diameter`, camber) for `LEI_AIRFOIL_BREUKELS`
- (`alpha_range`, `cl_vector`, `cd_vector`, `cm_vector`) for `POLAR_VECTORS`
- (`alpha_range`, `beta_range`, `cl_matrix`, `cd_matrix`, `cm_matrix`) for `POLAR_MATRICES`
- (`alpha_range`, `delta_range`, `cl_matrix`, `cd_matrix`, `cm_matrix`) for `POLAR_MATRICES`

where `alpha` is the angle of attack [rad], `beta` is trailing edge angle [rad], `cl` the lift coefficient,
where `alpha` is the angle of attack [rad], `delta` is trailing edge angle [rad], `cl` the lift coefficient,
`cd` the drag coefficient and `cm` the pitching moment coefficient. The camber of a kite refers to
the curvature of its airfoil shape. The camber is typically measured as the maximum distance
between the mean camber line (the line equidistant from the upper and lower surfaces)
Expand Down
6 changes: 3 additions & 3 deletions src/body_aerodynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ function init!(body_aero::BodyAerodynamics;
# Create panels
for i in 1:wing.n_panels
if wing isa RamAirWing
beta = wing.beta_dist[i]
delta = wing.delta_dist[i]
else
beta = 0.0
delta = 0.0
end
init!(
body_aero.panels[idx],
Expand All @@ -128,7 +128,7 @@ function init!(body_aero::BodyAerodynamics;
panel_props.x_airf[i],
panel_props.y_airf[i],
panel_props.z_airf[i],
beta;
delta;
remove_nan=wing.remove_nan
)
idx += 1
Expand Down
22 changes: 11 additions & 11 deletions src/kite_geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@
te_interp::NTuple{3, Extrapolation}
area_interp::Extrapolation
alpha_dist::Vector{Float64}
beta_dist::Vector{Float64}
delta_dist::Vector{Float64}
end

"""
Expand Down Expand Up @@ -401,7 +401,7 @@
end

@info "Loading polars and kite info from $polar_path and $info_path"
(alpha_range, beta_range, cl_matrix::Matrix, cd_matrix::Matrix, cm_matrix::Matrix) = deserialize(polar_path)
(alpha_range, delta_range, cl_matrix::Matrix, cd_matrix::Matrix, cm_matrix::Matrix) = deserialize(polar_path)
if remove_nan
interpolate_matrix_nans!(cl_matrix)
interpolate_matrix_nans!(cd_matrix)
Expand All @@ -414,7 +414,7 @@
# Create sections
sections = Section[]
for gamma in range(-gamma_tip, gamma_tip, n_sections)
aero_data = (collect(alpha_range), collect(beta_range), cl_matrix, cd_matrix, cm_matrix)
aero_data = (collect(alpha_range), collect(delta_range), cl_matrix, cd_matrix, cm_matrix)
LE_point = [le_interp[i](gamma) for i in 1:3]
TE_point = [te_interp[i](gamma) for i in 1:3]
push!(sections, Section(LE_point, TE_point, POLAR_MATRICES, aero_data))
Expand All @@ -426,20 +426,20 @@
end

"""
deform!(wing::RamAirWing, alphas::AbstractVector, betas::AbstractVector; width)
deform!(wing::RamAirWing, alphas::AbstractVector, deltas::AbstractVector; width)

Deform wing by applying left and right alpha and beta.
Deform wing by applying left and right alpha and delta.

# Arguments
- `wing`: RamAirWing to deform
- `alphas`: [left, right] the angle between of the kite and the body x-axis in radians
- `betas`: [left, right] the deformation of the trailing edges
- `deltas`: [left, right] the deformation of the trailing edges
- `width`: Transition width in meters to smoothe out the transition from left to right deformation

# Effects
Updates wing.sections with deformed geometry
"""
function deform!(wing::RamAirWing, alphas::AbstractVector, betas::AbstractVector; width)
function deform!(wing::RamAirWing, alphas::AbstractVector, deltas::AbstractVector; width)

Check warning on line 442 in src/kite_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/kite_geometry.jl#L442

Added line #L442 was not covered by tests
local_y = zeros(MVec3)
chord = zeros(MVec3)

Expand All @@ -452,12 +452,12 @@
else
alphas[1] * (1.0 - normalized_gamma) + alphas[2] * normalized_gamma
end
wing.beta_dist[i] = if normalized_gamma <= 0.0
betas[1]
wing.delta_dist[i] = if normalized_gamma <= 0.0
deltas[1]

Check warning on line 456 in src/kite_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/kite_geometry.jl#L455-L456

Added lines #L455 - L456 were not covered by tests
elseif normalized_gamma >= 1.0
betas[2]
deltas[2]

Check warning on line 458 in src/kite_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/kite_geometry.jl#L458

Added line #L458 was not covered by tests
else
betas[1] * (1.0 - normalized_gamma) + betas[2] * normalized_gamma
deltas[1] * (1.0 - normalized_gamma) + deltas[2] * normalized_gamma

Check warning on line 460 in src/kite_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/kite_geometry.jl#L460

Added line #L460 was not covered by tests
end

section1 = wing.non_deformed_sections[i]
Expand Down
26 changes: 13 additions & 13 deletions src/panel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
SemiInfiniteFilament(),
SemiInfiniteFilament()
)
beta::Float64 = 0.0
delta::Float64 = 0.0
end

function init_pos!(
Expand All @@ -84,7 +84,7 @@
x_airf::PosVector,
y_airf::PosVector,
z_airf::PosVector,
beta
delta
)
# Initialize basic geometry
panel.TE_point_1 .= section_1.TE_point
Expand All @@ -108,7 +108,7 @@
panel.x_airf .= x_airf
panel.y_airf .= y_airf
panel.z_airf .= z_airf
panel.beta = Float64(beta)
panel.delta = Float64(delta)
return nothing
end

Expand Down Expand Up @@ -157,19 +157,19 @@

elseif panel.aero_model == POLAR_MATRICES
!all(isapprox.(aero_1[1], aero_2[1])) && @error "Make sure you use the same alpha range for all your interpolations."
!all(isapprox.(aero_1[2], aero_2[2])) && @error "Make sure you use the same beta range for all your interpolations."
!all(isapprox.(aero_1[2], aero_2[2])) && @error "Make sure you use the same delta range for all your interpolations."

polar_data = (
Matrix{Float64}((aero_1[3] + aero_2[3]) / 2),
Matrix{Float64}((aero_1[4] + aero_2[4]) / 2),
Matrix{Float64}((aero_1[5] + aero_2[5]) / 2)
)
alphas = Vector{Float64}(aero_1[1])
betas = Vector{Float64}(aero_1[2])
deltas = Vector{Float64}(aero_1[2])

panel.cl_interp = linear_interpolation((alphas, betas), polar_data[1]; extrapolation_bc)
panel.cd_interp = linear_interpolation((alphas, betas), polar_data[2]; extrapolation_bc)
panel.cm_interp = linear_interpolation((alphas, betas), polar_data[3]; extrapolation_bc)
panel.cl_interp = linear_interpolation((alphas, deltas), polar_data[1]; extrapolation_bc)
panel.cd_interp = linear_interpolation((alphas, deltas), polar_data[2]; extrapolation_bc)
panel.cm_interp = linear_interpolation((alphas, deltas), polar_data[3]; extrapolation_bc)
else
throw(ArgumentError("Polar data in wrong format: $aero_1"))
end
Expand All @@ -190,12 +190,12 @@
x_airf::PosVector,
y_airf::PosVector,
z_airf::PosVector,
beta;
delta;
init_aero = true,
remove_nan = true
)
init_pos!(panel, section_1, section_2, aero_center, control_point, bound_point_1, bound_point_2,
x_airf, y_airf, z_airf, beta)
x_airf, y_airf, z_airf, delta)
init_aero && init_aero!(panel, section_1, section_2; remove_nan)
return nothing
end
Expand Down Expand Up @@ -331,7 +331,7 @@
elseif panel.aero_model == POLAR_VECTORS
cl = panel.cl_interp(alpha)::Float64
elseif panel.aero_model == POLAR_MATRICES
cl = panel.cl_interp(alpha, panel.beta)::Float64
cl = panel.cl_interp(alpha, panel.delta)::Float64
else
throw(ArgumentError("Unsupported aero model: $(panel.aero_model)"))
end
Expand All @@ -356,8 +356,8 @@
cd = panel.cd_interp(alpha)::Float64
cm = panel.cm_interp(alpha)::Float64
elseif panel.aero_model == POLAR_MATRICES
cd = panel.cd_interp(alpha, panel.beta)::Float64
cm = panel.cm_interp(alpha, panel.beta)::Float64
cd = panel.cd_interp(alpha, panel.delta)::Float64
cm = panel.cm_interp(alpha, panel.delta)::Float64

Check warning on line 360 in src/panel.jl

View check run for this annotation

Codecov / codecov/patch

src/panel.jl#L359-L360

Added lines #L359 - L360 were not covered by tests
elseif !(panel.aero_model == INVISCID)
throw(ArgumentError("Unsupported aero model: $(panel.aero_model)"))
end
Expand Down
20 changes: 10 additions & 10 deletions src/plotting.jl
Original file line number Diff line number Diff line change
Expand Up @@ -839,23 +839,23 @@ function VortexStepMethod.plot_polars(
end

"""
plot_polar_data(body_aero::BodyAerodynamics; alphas=collect(deg2rad.(-5:0.3:25)), beta_tes=collect(deg2rad.(-5:0.3:25)))
plot_polar_data(body_aero::BodyAerodynamics; alphas=collect(deg2rad.(-5:0.3:25)), delta_tes=collect(deg2rad.(-5:0.3:25)))

Plot polar data (Cl, Cd, Cm) as 3D surfaces against alpha and beta_te angles. Beta_te is the trailing edge deflection angle
Plot polar data (Cl, Cd, Cm) as 3D surfaces against alpha and delta_te angles. delta_te is the trailing edge deflection angle
relative to the 2d airfoil or panel chord line.

# Arguments
- `body_aero`: Wing aerodynamics struct

# Keyword arguments
- `alphas`: Range of angle of attack values in radians (default: -5° to 25° in 0.3° steps)
- `beta_tes`: Range of trailing edge angles in radians (default: -5° to 25° in 0.3° steps)
- `delta_tes`: Range of trailing edge angles in radians (default: -5° to 25° in 0.3° steps)
- `is_show`: Whether to display plots (default: true)
- `use_tex`: if the external `pdflatex` command shall be used
"""
function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics;
alphas=collect(deg2rad.(-5:0.3:25)),
beta_tes = collect(deg2rad.(-5:0.3:25)),
delta_tes = collect(deg2rad.(-5:0.3:25)),
is_show = true,
use_tex = false
)
Expand All @@ -877,10 +877,10 @@ function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics;
ax = fig.add_subplot(1, 3, idx, projection="3d")

# Create interpolation matrix
interp_matrix = zeros(length(alphas), length(beta_tes))
interp_matrix .= [interp(alpha, beta_te) for alpha in alphas, beta_te in beta_tes]
X = collect(beta_tes) .+ zeros(length(alphas))'
Y = collect(alphas)' .+ zeros(length(beta_tes))
interp_matrix = zeros(length(alphas), length(delta_tes))
interp_matrix .= [interp(alpha, delta_te) for alpha in alphas, delta_te in delta_tes]
X = collect(delta_tes) .+ zeros(length(alphas))'
Y = collect(alphas)' .+ zeros(length(delta_tes))

# Plot surface
ax.plot_wireframe(X, Y, interp_matrix,
Expand All @@ -891,10 +891,10 @@ function VortexStepMethod.plot_polar_data(body_aero::BodyAerodynamics;
alpha=0.6)

# Set labels and title
ax.set_xlabel(L"$\beta$ [rad]")
ax.set_xlabel(L"$\delta$ [rad]")
ax.set_ylabel(L"$\alpha$ [rad]")
ax.set_zlabel(label)
ax.set_title(label * L" vs $\alpha$ and $\beta$")
ax.set_title(label * L" vs $\alpha$ and $\delta$")
ax.grid(true)
end

Expand Down
10 changes: 5 additions & 5 deletions src/wing_geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -310,20 +310,20 @@
return (alpha_left, CL_data, CD_data, CM_data)

elseif model_type == POLAR_MATRICES
alpha_left, beta_left, CL_left, CD_left, CM_left = polar_left
alpha_right, beta_right, CL_right, CD_right, CM_right = polar_right
alpha_left, delta_left, CL_left, CD_left, CM_left = polar_left
alpha_right, delta_right, CL_right, CD_right, CM_right = polar_right

Check warning on line 314 in src/wing_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/wing_geometry.jl#L313-L314

Added lines #L313 - L314 were not covered by tests

# Create common alpha array
!all(isapprox.(alpha_left, alpha_right)) && @error "Make sure you use the same alpha range for all your interpolations."
!all(isapprox.(beta_left, beta_right)) && @error "Make sure you use the same alpha range for all your interpolations."
!isa(CL_right, AbstractMatrix) && @error "Provide polar data in the correct format: (alpha, beta, cl, cd, cm)"
!all(isapprox.(delta_left, delta_right)) && @error "Make sure you use the same alpha range for all your interpolations."
!isa(CL_right, AbstractMatrix) && @error "Provide polar data in the correct format: (alpha, delta, cl, cd, cm)"

Check warning on line 319 in src/wing_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/wing_geometry.jl#L318-L319

Added lines #L318 - L319 were not covered by tests

# Weighted interpolation
CL_data = CL_left .* left_weight .+ CL_right .* right_weight
CD_data = CD_left .* left_weight .+ CD_right .* right_weight
CM_data = CM_left .* left_weight .+ CM_right .* right_weight

return (alpha_left, beta_left, CL_data, CD_data, CM_data)
return (alpha_left, delta_left, CL_data, CD_data, CM_data)

Check warning on line 326 in src/wing_geometry.jl

View check run for this annotation

Codecov / codecov/patch

src/wing_geometry.jl#L326

Added line #L326 was not covered by tests
end

elseif model_type === LEI_AIRFOIL_BREUKELS
Expand Down
4 changes: 2 additions & 2 deletions test/test_body_aerodynamics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -262,12 +262,12 @@ end
v_a = [cos(aoa), 0.0, sin(aoa)] .* v_a

coord = if wing_type === :rectangular
twist = range(-0.5, 0.5, length=N)
theta = range(-0.5, 0.5, length=N)
beta = range(-2, 2, length=N)
generate_coordinates_rect_wing(
fill(max_chord, N),
span,
twist,
theta,
beta,
N,
"lin"
Expand Down
10 changes: 5 additions & 5 deletions test/test_wing_geometry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,17 @@ end

# Create matrix data with NaNs
alpha = collect(range(-10, 10, 21))
beta = collect(range(-5, 5, 11))
cl = [cos(a) * cos(b) for a in alpha, b in beta]
cd = [sin(a) * sin(b) for a in alpha, b in beta]
delta = collect(range(-5, 5, 11))
cl = [cos(a) * cos(b) for a in alpha, b in delta]
cd = [sin(a) * sin(b) for a in alpha, b in delta]
cm = zeros(21, 11)

# Insert NaNs at various positions
cl[5,3] = NaN
cd[10,5] = NaN
cm[15,7] = NaN

aero_data = (alpha, beta, cl, cd, cm)
aero_data = (alpha, delta, cl, cd, cm)
add_section!(wing, [0.0, 0.0, 0.0], [1.0, 0.0, 0.0], POLAR_MATRICES, aero_data)

# Check if NaNs were removed consistently
Expand All @@ -89,7 +89,7 @@ end
@test !any(isnan, cleaned_data[4]) # cd
@test !any(isnan, cleaned_data[5]) # cm
@test all(diff(cleaned_data[1]) .> 0) # alpha still monotonic
@test all(diff(cleaned_data[2]) .> 0) # beta still monotonic
@test all(diff(cleaned_data[2]) .> 0) # delta still monotonic
end

@testset "Robustness left to right" begin
Expand Down
12 changes: 6 additions & 6 deletions test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ Generate 3D coordinates of a rectangular wing with twist and dihedral.
# Arguments
- `chord::Vector{Float64}`: Chord lengths of wing panels
- `span::Float64`: Total wing span
- `twist::Vector{Float64}`: Twist angles in radians
- `theta::Vector{Float64}`: Twist angles in radians
- `beta::Vector{Float64}`: Dihedral angles in radians
- `N::Int`: Number of spanwise panels
- `dist::String`: Distribution type ("cos" or "lin")

# Returns
- `coord::Matrix{Float64}`: 2N×3 matrix of coordinates
"""
function generate_coordinates_rect_wing(chord, span, twist, beta, N, dist)
function generate_coordinates_rect_wing(chord, span, theta, beta, N, dist)
coord = zeros(2 * N, 3)
span_points = if dist == "cos"
cosspace(-span/2, span/2, N)
Expand All @@ -40,14 +40,14 @@ function generate_coordinates_rect_wing(chord, span, twist, beta, N, dist)

for i in 1:N
coord[2i-1, :] = [
-0 * chord[i] * cos(twist[i]),
-0 * chord[i] * cos(theta[i]),
span_points[i],
0 * chord[i] * sin(twist[i]) - abs(span_points[i] * sin(beta[i]))
0 * chord[i] * sin(theta[i]) - abs(span_points[i] * sin(beta[i]))
]
coord[2i, :] = [
1 * chord[i] * cos(twist[i]),
1 * chord[i] * cos(theta[i]),
span_points[i],
-1 * chord[i] * sin(twist[i]) - abs(span_points[i] * sin(beta[i]))
-1 * chord[i] * sin(theta[i]) - abs(span_points[i] * sin(beta[i]))
]
end
return coord
Expand Down
Loading