Skip to content

Commit 7724c0d

Browse files
authored
Merge pull request #353 from OpenSourceAWE/agent/329-set-va-rotates-the-body-about-the-origin
set_va! turns the body about a stored reference_point, and set_va!(body_aero, settings) applies yaw_rate
2 parents 2665240 + a035f39 commit 7724c0d

7 files changed

Lines changed: 81 additions & 37 deletions

File tree

CHANGELOG.md

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

55
### Added
66

7+
- `set_va!(body_aero, va_vec, omega; reference_point)` turns the body about
8+
`reference_point` [m] instead of the origin. The point is stored on
9+
`BodyAerodynamics`, starts at the origin, and is kept by later `set_va!`, `reinit!`
10+
and `linearize` calls until it is given again.
711
- Spanwise-flow viscous drag correction (Gaunaa et al. 2024,
812
doi:10.1088/1742-6596/2767/2/022068): each section gets a drag increment and a force
913
along its span from the flow across it, in `solve!`, `solve` and `linearize`. Opt-in
@@ -23,6 +27,8 @@
2327

2428
### Fixed
2529

30+
- `set_va!(body_aero, settings)` applies `condition.yaw_rate` as a turn rate about the
31+
body z axis; it was read from the settings file and ignored.
2632
- The `VSMSolution` docstring gives `lift_dist`, `drag_dist` and `panel_moment_dist` in
2733
the per-unit-span units they hold, [N/m] and [Nm/m], instead of [N] and [Nm].
2834
- Inside its vortex core, `velocity_3D_trailing_vortex!` induces an azimuthal velocity

docs/src/settings.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ condition:
3232
wind_speed: 10.0 # free-stream velocity magnitude [m/s]
3333
alpha: 5.0 # angle of attack [°]
3434
beta: 0.0 # sideslip angle [°]
35-
yaw_rate: 0.0 # yaw rate [°/s]
35+
yaw_rate: 0.0 # turn rate about the body z axis [°/s]
3636

3737
wings:
3838
- name: main_wing # label the wing carries into plots and output

src/body_aerodynamics.jl

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Main structure for calculating aerodynamic properties of bodies. Use the constru
88
- wings::Vector{W}: A vector of wings of type `W <: AbstractWing`; a body can have multiple wings
99
- `va::MVec3` = zeros(MVec3): A vector of the apparent wind speed, see: [`MVec3`](@ref)
1010
- `omega`::MVec3 = zeros(MVec3): A vector of the turn rates around the kite body axes
11+
- `reference_point`::MVec3 = zeros(MVec3): The point `omega` turns the body about [m]
1112
- `gamma_distribution`=zeros(Float64, P): A vector of the circulation
1213
of the velocity field; Length: Number of segments. [m²/s]
1314
- `alpha_uncorrected`=zeros(Float64, P): angles of attack per panel
@@ -35,6 +36,7 @@ Main structure for calculating aerodynamic properties of bodies. Use the constru
3536
_va::MVector{3, T} = zeros(MVector{3, T})
3637
has_distributed_va::Bool = false
3738
omega::MVector{3, T} = zeros(MVector{3, T})
39+
reference_point::MVector{3, T} = zeros(MVector{3, T})
3840
gamma_distribution::MVector{P, T} = zeros(MVector{P, T})
3941
alpha_uncorrected::MVector{P, T} = zeros(MVector{P, T})
4042
alpha_corrected::MVector{P, T} = zeros(MVector{P, T})
@@ -155,6 +157,8 @@ function Base.setproperty!(obj::BodyAerodynamics, sym::Symbol, val)
155157
set_va!(obj, val)
156158
elseif sym === :omega
157159
set_va!(obj, obj._va, val)
160+
elseif sym === :reference_point
161+
set_va!(obj, obj._va, obj.omega; reference_point=val)
158162
else
159163
setfield!(obj, sym, val)
160164
end
@@ -1083,44 +1087,32 @@ end
10831087

10841088

10851089
"""
1086-
set_va!(body_aero::BodyAerodynamics, va_vec::VelVector, omega=zeros(MVec3))
1090+
set_va!(body_aero::BodyAerodynamics, va_vec::VelVector, omega=zeros(MVec3);
1091+
reference_point=body_aero.reference_point)
10871092
1088-
Set velocity array and update wake filaments.
1093+
Set a uniform apparent wind and a body turn rate, and update the wake filaments. Each
1094+
panel sees `va_vec - omega × (control_point - reference_point)`.
10891095
10901096
# Arguments
10911097
- body_aero::BodyAerodynamics: The [`BodyAerodynamics`](@ref) struct to modify
10921098
- `va_vec::VelVector`: Velocity vector of the apparent wind speed [m/s]
10931099
- `omega::VelVector`: Turn rate vector around x y and z axis [rad/s]
1100+
- `reference_point`: Point the body turns about, stored on `body_aero` [m]
10941101
10951102
`omega` is also projected onto each panel's spanwise axis into
10961103
`pitch_rate_dist`, which the solver reads when `flow_curvature` is enabled.
10971104
"""
10981105
function set_va!(body_aero::BodyAerodynamics{P, W, T}, va_vec::AbstractVector,
1099-
omega=zeros(MVector{3, T})) where {P, W, T}
1100-
n_panels = length(body_aero.panels)
1101-
va_vec_dist = zeros(T, n_panels, 3)
1106+
omega=zeros(MVector{3, T});
1107+
reference_point=body_aero.reference_point) where {P, W, T}
11021108
body_aero.omega .= omega
1109+
body_aero.reference_point .= reference_point
11031110
set_pitch_rate_dist!(body_aero, omega)
11041111

1105-
if all(iszero, omega)
1106-
va_vec_dist .= reshape(va_vec, 1, 3)
1107-
else
1108-
idx = 1
1109-
for wing in body_aero.wings
1110-
panel_end = idx + wing.n_panels - 1
1111-
1112-
# Calculate velocities for each panel in this wing slice
1113-
for j in idx:panel_end
1114-
omega_va_vec = -omega × body_aero.panels[j].control_point
1115-
va_vec_dist[j, :] .= omega_va_vec .+ va_vec
1116-
end
1117-
idx = panel_end + 1
1118-
end
1119-
end
1120-
1121-
# Update panel velocities
1112+
va_vec_dist = zeros(T, P, 3)
11221113
for (i, panel) in enumerate(body_aero.panels)
1123-
panel.va .= va_vec_dist[i,:]
1114+
panel.va .= va_vec .- omega × (panel.control_point .- body_aero.reference_point)
1115+
va_vec_dist[i, :] .= panel.va
11241116
end
11251117

11261118
# Update wake elements
@@ -1175,6 +1167,8 @@ constructs the velocity vector in the body reference frame based on:
11751167
- Wind speed from settings.condition.wind_speed
11761168
- Angle of attack from settings.condition.alpha (converted from degrees)
11771169
- Sideslip angle from settings.condition.beta (converted from degrees)
1170+
- Yaw rate from settings.condition.yaw_rate (converted from °/s), applied as `omega`
1171+
about Z_b and turning the body about `body_aero.reference_point`
11781172
11791173
The velocity vector is constructed as:
11801174
- X_b (forward): wind_speed * cos(α) * cos(β)
@@ -1202,6 +1196,7 @@ function set_va!(body_aero::BodyAerodynamics, settings::VSMSettings)
12021196
sin(β), # Y_b (right)
12031197
sin(α)*cos(β) # Z_b (down)
12041198
]
1205-
1206-
set_va!(body_aero, va_vec)
1199+
omega = [0.0, 0.0, deg2rad(settings.condition.yaw_rate)]
1200+
1201+
set_va!(body_aero, va_vec, omega)
12071202
end

src/solver.jl

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1215,10 +1215,9 @@ function make_dual_shadow(solver::Solver{P, U, Float64},
12151215
body_aero::BodyAerodynamics{P, W, Float64},
12161216
::Type{TD}) where {P, U, W, TD}
12171217
wings_d = [_wing_with_eltype(wing, TD) for wing in body_aero.wings]
1218-
body_aero_d = BodyAerodynamics(wings_d;
1219-
va = MVector{3, TD}(body_aero._va),
1220-
omega = MVector{3, TD}(body_aero.omega),
1221-
)
1218+
body_aero_d = BodyAerodynamics(wings_d)
1219+
set_va!(body_aero_d, MVector{3, TD}(body_aero._va), MVector{3, TD}(body_aero.omega);
1220+
reference_point=body_aero.reference_point)
12221221
solver_d = Solver(body_aero_d;
12231222
solver_type = solver.solver_type,
12241223
aerodynamic_model_type = solver.aerodynamic_model_type,

test/body_aerodynamics/test_body_aerodynamics.jl

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,10 @@ end
431431
@test length(results_NEW["cd_distribution"]) == length(body_aero.panels)
432432
end
433433

434-
@testset "set_va! with VSMSettings" begin
434+
@testset "set_va! with VSMSettings applies the yaw rate about body z" begin
435435
settings_file = create_temp_wing_settings("body_aerodynamics", "test_wing.yaml";
436-
alpha=10.0, beta=5.0, wind_speed=15.0)
436+
alpha=10.0, beta=5.0, wind_speed=15.0,
437+
yaw_rate=30.0)
437438
try
438439
settings = VSMSettings(settings_file)
439440
wing = Wing(settings)
@@ -444,11 +445,13 @@ end
444445

445446
α, β, wind_speed = deg2rad(10.0), deg2rad(5.0), 15.0
446447
expected_va_vec = wind_speed .* [cos(α)*cos(β), sin(β), sin(α)*cos(β)]
448+
omega = [0.0, 0.0, deg2rad(30.0)]
447449

448450
for p in body_aero.panels
449-
@test p.va expected_va_vec atol=1e-10
451+
@test p.va expected_va_vec .- omega × p.control_point atol=1e-10
450452
end
451453
@test body_aero._va expected_va_vec atol=1e-10
454+
@test body_aero.omega omega
452455
finally
453456
isfile(settings_file) && rm(settings_file; force=true)
454457
end
@@ -504,6 +507,40 @@ end
504507
@test body_aero.omega new_omega
505508
end
506509

510+
"""
511+
test_rigid_body_inflow(body_aero, va_vec, omega, reference_point)
512+
513+
Test that every panel sees `va_vec` plus the inflow of a body turning at `omega` about
514+
`reference_point`.
515+
"""
516+
function test_rigid_body_inflow(body_aero, va_vec, omega, reference_point)
517+
for panel in body_aero.panels
518+
expected_va_vec = va_vec .- omega × (panel.control_point .- reference_point)
519+
@test panel.va expected_va_vec atol=1e-12
520+
end
521+
end
522+
523+
@testset "set_va! rotates the body about reference_point" begin
524+
body_aero = BodyAerodynamics([inviscid_wing([0.0, 1.0, 2.0]),
525+
inviscid_wing([10.0, 11.0, 12.0])])
526+
va_vec = [10.0, 0.0, 1.0]
527+
omega = [0.1, 0.2, 1.0]
528+
reference_point = [0.25, 6.0, -0.5]
529+
530+
set_va!(body_aero, va_vec, omega; reference_point)
531+
@test body_aero.reference_point reference_point
532+
test_rigid_body_inflow(body_aero, va_vec, omega, reference_point)
533+
534+
body_aero.omega = 2 .* omega
535+
test_rigid_body_inflow(body_aero, va_vec, 2 .* omega, reference_point)
536+
537+
reinit!(body_aero; va=va_vec, omega)
538+
test_rigid_body_inflow(body_aero, va_vec, omega, reference_point)
539+
540+
body_aero.reference_point = zeros(3)
541+
test_rigid_body_inflow(body_aero, va_vec, omega, zeros(3))
542+
end
543+
507544
"""
508545
solve_wings(wings)
509546

test/solver/test_forwarddiff.jl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,24 @@ relative_error(jac, reference) = maximum(abs.(jac .- reference)) / maximum(abs,
2121
omega = [0.0, 0.0, 0.0]
2222
y0 = [va_vec; omega]
2323

24-
@testset "AutoForwardDiff matches AutoFiniteDiff (LOOP, INVISCID)" begin
25-
solver = Solver(body_aero;
24+
turns = ((omega, zeros(3)), ([0.0, 0.0, 0.2], [0.5, 4.0, 0.0]))
25+
@testset "ForwardDiff matches FiniteDiff about $reference_point (LOOP, INVISCID)" for
26+
(omega_op, reference_point) in turns
27+
pivot_body = BodyAerodynamics([wing])
28+
set_va!(pivot_body, va_vec, omega_op; reference_point)
29+
y_op = [va_vec; omega_op]
30+
solver = Solver(pivot_body;
2631
use_gamma_prev=false,
2732
type_initial_gamma_distribution=ELLIPTIC)
2833

2934
jac_fwd, _, fwd_converged = VortexStepMethod.linearize(
30-
solver, body_aero, y0;
35+
solver, pivot_body, y_op;
3136
theta_idxs=nothing, va_idxs=1:3, omega_idxs=4:6,
3237
aero_coeffs=true, backend=AutoForwardDiff())
3338
@test fwd_converged
3439

3540
jac_fd, _, fd_converged = VortexStepMethod.linearize(
36-
solver, body_aero, y0;
41+
solver, pivot_body, y_op;
3742
theta_idxs=nothing, va_idxs=1:3, omega_idxs=4:6,
3843
aero_coeffs=true,
3944
backend=AutoFiniteDiff(absstep=1e-5, relstep=1e-5))

test/test_data_utils.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ function create_temp_wing_settings(module_name, wing_file;
135135
alpha=10.0,
136136
beta=5.0,
137137
wind_speed=15.0,
138+
yaw_rate=0.0,
138139
)
139140
wing_file_path = isabspath(wing_file) ? wing_file : test_data_path(module_name, wing_file)
140141
wing_file_path = replace(normpath(wing_file_path), '\\' => '/')
@@ -158,6 +159,7 @@ function create_temp_wing_settings(module_name, wing_file;
158159
"alpha" => alpha,
159160
"beta" => beta,
160161
"wind_speed" => wind_speed,
162+
"yaw_rate" => yaw_rate,
161163
),
162164
)
163165

0 commit comments

Comments
 (0)