|
| 1 | +# using VortexStepMethod: Wing, WingAerodynamics, BoundFilament, SemiInfiniteFilament, add_section!, set_va!, solve, calculate_cl |
| 2 | +using VortexStepMethod |
| 3 | +using VortexStepMethod: calculate_cl, calculate_cd_cm, calculate_projected_area |
| 4 | +using LinearAlgebra |
| 5 | +using Test |
| 6 | +using Logging |
| 7 | + |
| 8 | +include("utils.jl") |
| 9 | + |
| 10 | +@testset "Calculate results against output results" begin |
| 11 | + # Setup |
| 12 | + density = 1.225 |
| 13 | + N = 40 |
| 14 | + max_chord = 1.0 |
| 15 | + span = 15.709 # AR = 20 |
| 16 | + Umag = 20.0 |
| 17 | + AR = span^2 / (π * span * max_chord / 4) |
| 18 | + aoa = deg2rad(5) |
| 19 | + Uinf = [cos(aoa), 0.0, sin(aoa)] .* Umag |
| 20 | + model = "VSM" |
| 21 | + |
| 22 | + # Setup wing geometry |
| 23 | + dist = "cos" |
| 24 | + core_radius_fraction = 1e-20 |
| 25 | + coord = generate_coordinates_el_wing(max_chord, span, N, dist) |
| 26 | + coord_left_to_right = flip_created_coord_in_pairs(deepcopy(coord)) |
| 27 | + wing = Wing(N; spanwise_panel_distribution="unchanged") |
| 28 | + for idx in 1:2:length(coord_left_to_right[:, 1]) |
| 29 | + @debug "coord_left_to_right[$idx] = $(coord_left_to_right[idx,:])" |
| 30 | + add_section!( |
| 31 | + wing, |
| 32 | + coord_left_to_right[idx,:], |
| 33 | + coord_left_to_right[idx+1,:], |
| 34 | + "inviscid" |
| 35 | + ) |
| 36 | + end |
| 37 | + |
| 38 | + wing_aero = WingAerodynamics([wing]) |
| 39 | + set_va!(wing_aero, (Uinf, 0.0)) |
| 40 | + |
| 41 | + # Run analysis |
| 42 | + solver_object = Solver( |
| 43 | + aerodynamic_model_type=model, |
| 44 | + core_radius_fraction=core_radius_fraction |
| 45 | + ) |
| 46 | + results_NEW = solve(solver_object, wing_aero) |
| 47 | + |
| 48 | + @test results_NEW isa Dict |
| 49 | + |
| 50 | + # Calculate forces using uncorrected alpha |
| 51 | + alpha = results_NEW["alpha_uncorrected"] |
| 52 | + dyn_visc = 0.5 * density * norm(Uinf)^2 |
| 53 | + n_panels = length(wing_aero.panels) |
| 54 | + lift = zeros(n_panels) |
| 55 | + drag = zeros(n_panels) |
| 56 | + moment = zeros(n_panels) |
| 57 | + |
| 58 | + for (i, panel) in enumerate(wing_aero.panels) |
| 59 | + lift[i] = dyn_visc * calculate_cl(panel, alpha[i]) * panel.chord |
| 60 | + cd_cm = calculate_cd_cm(panel, alpha[i]) |
| 61 | + drag[i] = dyn_visc * cd_cm[1] * panel.chord |
| 62 | + moment[i] = dyn_visc * cd_cm[2] * panel.chord^2 |
| 63 | + @info "lift: $lift, drag: $drag, moment: $moment" |
| 64 | + end |
| 65 | + Fmag = hcat(lift, drag, moment) |
| 66 | + |
| 67 | + # Calculate coefficients using corrected alpha |
| 68 | + alpha = results_NEW["alpha_at_ac"] |
| 69 | + aero_coeffs = hcat( |
| 70 | + [alpha[i] for (i, panel) in enumerate(wing_aero.panels)], |
| 71 | + [calculate_cl(panel, alpha[i]) for (i, panel) in enumerate(wing_aero.panels)], |
| 72 | + [calculate_cd_cm(panel, alpha[i])[1] for (i, panel) in enumerate(wing_aero.panels)], |
| 73 | + [calculate_cd_cm(panel, alpha[i])[2] for (i, panel) in enumerate(wing_aero.panels)] |
| 74 | + ) |
| 75 | + |
| 76 | + ringvec = [Dict("r0" => panel.width * panel.z_airf) for panel in wing_aero.panels] |
| 77 | + controlpoints = [Dict("tangential" => panel.y_airf, "normal" => panel.x_airf) |
| 78 | + for panel in wing_aero.panels] |
| 79 | + Atot = calculate_projected_area(wing) |
| 80 | + |
| 81 | + F_rel_ref, F_gl_ref, Ltot_ref, Dtot_ref, CL_ref, CD_ref, CS_ref = |
| 82 | + output_results(Fmag, aero_coeffs, ringvec, Uinf, controlpoints, Atot) |
| 83 | + |
| 84 | + # Compare results |
| 85 | + @info "Comparing results" |
| 86 | + @info "cl_calculated: $(results_NEW["cl"]), CL_ref: $CL_ref" |
| 87 | + @info "cd_calculated: $(results_NEW["cd"]), CD_ref: $CD_ref" |
| 88 | + @info "cs_calculated: $(results_NEW["cs"]), CS_ref: $CS_ref" |
| 89 | + @info "L_calculated: $(results_NEW["lift"]), Ltot_ref: $Ltot_ref" |
| 90 | + @info "D_calculated: $(results_NEW["drag"]), Dtot_ref: $Dtot_ref" |
| 91 | + |
| 92 | + # Assert results |
| 93 | + @test isapprox(results_NEW["cl"], CL_ref, rtol=1e-4) |
| 94 | + @test isapprox(results_NEW["cd"], CD_ref, rtol=1e-4) |
| 95 | + @test isapprox(results_NEW["cs"], CS_ref, rtol=1e-4) |
| 96 | + @test isapprox(results_NEW["lift"], Ltot_ref, rtol=1e-4) |
| 97 | + @test isapprox(results_NEW["drag"], Dtot_ref, rtol=1e-4) |
| 98 | + |
| 99 | + # Check array shapes |
| 100 | + @test length(results_NEW["cl_distribution"]) == length(wing_aero.panels) |
| 101 | + @test length(results_NEW["cd_distribution"]) == length(wing_aero.panels) |
| 102 | +end |
0 commit comments