|
| 1 | +using Pkg |
| 2 | +if !("ControlPlots" ∈ keys(Pkg.project().dependencies)) |
| 3 | + Pkg.activate(@__DIR__) |
| 4 | +end |
| 5 | + |
| 6 | +using LinearAlgebra |
| 7 | +using VortexStepMethod |
| 8 | +using ControlPlots |
| 9 | + |
| 10 | +PLOT = true |
| 11 | +USE_TEX = false |
| 12 | +DEFORM = false |
| 13 | + |
| 14 | +project_dir = dirname(@__DIR__) |
| 15 | +literature_paths = [ |
| 16 | + joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "CFD_RANS_Rey_5e5_Poland2025_alpha_sweep_beta_0_NoStruts.csv"), |
| 17 | + joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "CFD_RANS_Rey_10e5_Poland2025_alpha_sweep_beta_0.csv"), |
| 18 | + joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "python_alpha_sweep.csv"), |
| 19 | + joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "windtunnel_alpha_sweep_beta_00_0_Poland_2025_Rey_5e5.csv"), |
| 20 | +] |
| 21 | +labels = [ |
| 22 | + "VSM Julia Re=5e5", |
| 23 | + "CFD Re=5e5", |
| 24 | + "CFD Re=10e5", #with struts |
| 25 | + "VSM Python Re=5e5", |
| 26 | + "WindTunnel Re=5e5" #with struts |
| 27 | +] |
| 28 | +beta_literature_paths = [ |
| 29 | + joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "windtunnel_beta_sweep_alpha_07_4_Poland_2025_Rey_5e5.csv"), |
| 30 | + # joinpath(project_dir, "data", "TUDELFT_V3_KITE", "literature_results", "windtunnel_beta_sweep_alpha_12_5_Poland_2025_Rey_5e5.csv"), |
| 31 | +] |
| 32 | +beta_labels = [ |
| 33 | + labels[1], |
| 34 | + "Wind Tunnel Re=5e5 beta sweep alpha=7.4", |
| 35 | + # "Wind Tunnel Re=5e5 beta sweep alpha=12.5", |
| 36 | +] |
| 37 | + |
| 38 | +# Load YAML settings directly (avoids VSMSettings(filename) conversion issues in live sessions) |
| 39 | +settings_path = joinpath(project_dir, "data", "TUDELFT_V3_KITE", "vsm_settings.yaml") |
| 40 | +settings_data = VortexStepMethod.YAML.load_file(settings_path) |
| 41 | +condition_cfg = settings_data["condition"] |
| 42 | +wing_cfg = settings_data["wings"][1] |
| 43 | +solver_cfg = settings_data["solver_settings"] |
| 44 | + |
| 45 | +# Create wing, body_aero, and solver objects using settings |
| 46 | + |
| 47 | +wing = Wing( |
| 48 | + joinpath(project_dir, wing_cfg["geometry_file"]); |
| 49 | + n_panels=wing_cfg["n_panels"], |
| 50 | + spanwise_distribution=getproperty(VortexStepMethod, Symbol(wing_cfg["spanwise_panel_distribution"])), |
| 51 | + spanwise_direction=Float64.(wing_cfg["spanwise_direction"]), |
| 52 | + remove_nan=wing_cfg["remove_nan"], |
| 53 | +) |
| 54 | +refine!(wing) |
| 55 | +body_aero = BodyAerodynamics([wing]) |
| 56 | +VortexStepMethod.reinit!(body_aero) |
| 57 | + |
| 58 | +if DEFORM |
| 59 | + VortexStepMethod.unrefined_deform!( |
| 60 | + wing, |
| 61 | + deg2rad.(range(-10, 10, length=wing.n_unrefined_sections)), |
| 62 | + deg2rad.(range(0, 0, length=wing.n_unrefined_sections)); |
| 63 | + smooth=true |
| 64 | + ) |
| 65 | + VortexStepMethod.reinit!(body_aero; init_aero=false) |
| 66 | +end |
| 67 | + |
| 68 | + |
| 69 | +# Construct Solver using keyword arguments from solver settings |
| 70 | +solver = Solver(body_aero; |
| 71 | + solver_type=(solver_cfg["solver_type"] == "NONLIN" ? NONLIN : LOOP), |
| 72 | + aerodynamic_model_type=getproperty(VortexStepMethod, Symbol(solver_cfg["aerodynamic_model_type"])), |
| 73 | + density=solver_cfg["density"], |
| 74 | + max_iterations=solver_cfg["max_iterations"], |
| 75 | + rtol=solver_cfg["rtol"], |
| 76 | + tol_reference_error=solver_cfg["tol_reference_error"], |
| 77 | + relaxation_factor=solver_cfg["relaxation_factor"], |
| 78 | + is_with_artificial_damping=solver_cfg["artificial_damping"], |
| 79 | + artificial_damping=(k2=solver_cfg["k2"], k4=solver_cfg["k4"]), |
| 80 | + type_initial_gamma_distribution=getproperty(VortexStepMethod, Symbol(solver_cfg["type_initial_gamma_distribution"])), |
| 81 | + use_gamma_prev=get(solver_cfg, "use_gamma_prev", get(solver_cfg, "use_gamme_prev", true)), |
| 82 | + core_radius_fraction=solver_cfg["core_radius_fraction"], |
| 83 | + mu=solver_cfg["mu"], |
| 84 | + is_only_f_and_gamma_output=get(solver_cfg, "calc_only_f_and_gamma", false), |
| 85 | + correct_aoa=get(solver_cfg, "correct_aoa", false), |
| 86 | + reference_point=get(solver_cfg, "reference_point", [0.422646, 0.0, 9.3667]), #ref-point from WT exp. |
| 87 | +) |
| 88 | + |
| 89 | +# Extract values for plotting (optional - for reference) |
| 90 | +wind_speed = condition_cfg["wind_speed"] |
| 91 | +angle_of_attack_deg = condition_cfg["alpha"] |
| 92 | +sideslip_deg = condition_cfg["beta"] |
| 93 | +yaw_rate = condition_cfg["yaw_rate"] |
| 94 | + |
| 95 | +# Set flight conditions from settings |
| 96 | +α0 = deg2rad(angle_of_attack_deg) |
| 97 | +β0 = deg2rad(sideslip_deg) |
| 98 | +set_va!(body_aero, wind_speed .* [cos(α0) * cos(β0), sin(β0), sin(α0) * cos(β0)]) |
| 99 | + |
| 100 | +# Solve and plot combined analysis |
| 101 | +results = VortexStepMethod.solve(solver, body_aero; log=true) |
| 102 | +# Plotting polars |
| 103 | +PLOT && plot_polars( |
| 104 | + [solver], |
| 105 | + [body_aero], |
| 106 | + labels, |
| 107 | + literature_path_list=literature_paths, |
| 108 | + angle_range=range(-5, 25, length=31), |
| 109 | + angle_type="angle_of_attack", |
| 110 | + angle_of_attack=angle_of_attack_deg, |
| 111 | + side_slip=sideslip_deg, |
| 112 | + v_a=wind_speed, |
| 113 | + title="$(wing.n_panels)_panels_$(wing.spanwise_distribution)_from_yaml_settings", |
| 114 | + data_type=".pdf", |
| 115 | + is_save=false, |
| 116 | + is_show=true, |
| 117 | + use_tex=USE_TEX |
| 118 | +) |
| 119 | + |
| 120 | + |
| 121 | +# Plotting geometry |
| 122 | +results = VortexStepMethod.solve(solver, body_aero; log=true) |
| 123 | +PLOT && plot_geometry( |
| 124 | + body_aero, |
| 125 | + ""; |
| 126 | + data_type=".svg", |
| 127 | + save_path="", |
| 128 | + is_save=false, |
| 129 | + is_show=true, |
| 130 | + view_elevation=15, |
| 131 | + view_azimuth=-120, |
| 132 | + use_tex=USE_TEX |
| 133 | +) |
| 134 | + |
| 135 | + |
| 136 | +# Plotting spanwise distributions |
| 137 | +body_y_coordinates = [panel.aero_center[2] for panel in body_aero.panels] |
| 138 | + |
| 139 | +PLOT && plot_distribution( |
| 140 | + [body_y_coordinates], |
| 141 | + [results], |
| 142 | + ["VSM"]; |
| 143 | + title="CAD_spanwise_distributions_alpha_$(round(angle_of_attack_deg, digits=1))_delta_$(round(sideslip_deg, digits=1))_yaw_$(round(yaw_rate, digits=1))_v_a_$(round(wind_speed, digits=1))", |
| 144 | + data_type=".pdf", |
| 145 | + is_save=false, |
| 146 | + is_show=true, |
| 147 | + use_tex=USE_TEX |
| 148 | +) |
| 149 | + |
| 150 | + |
| 151 | +nothing |
0 commit comments