Enumerations
VortexStepMethod.Model — Type
Model VSM LLT
Enumeration of the implemented model types.
Elements
- VSM: Vortex Step Method
- LLT: Lifting Line Theory
VortexStepMethod.WingType — Type
WingType `RECTANGULAR` `CURVED` `ELLIPTICAL`Enumeration of the implemented wing types.
Elements:
- RECTANGULAR
- CURVED
- ELLIPTICAL
VortexStepMethod.AeroModel — Type
AeroModel POLY POLAR_VECTORS POLAR_MATRICES INVISCID
Enumeration of the implemented aerodynamic models. See also: AeroData
Elements
POLY: α-polynomial coefficients for cl/cd/cm (e.g. Breukels LEI coeffs, generated by theAirfoilAeropackage). Core only evaluates the polynomial.POLAR_VECTORS: Polar vectors as function of alpha (lookup tables with interpolation). A panel's table may be rewritten at run time byset_polar!, which is how a live polar source regenerates it from the panel's deformed shape each solve.POLAR_MATRICES: Polar matrices as function of alpha and delta (lookup tables with interpolation)- INVISCID
LEI_AIRFOIL_BREUKELS is a deprecated alias of POLY.
where alpha is the angle of attack, delta is trailing edge angle.
VortexStepMethod.PanelDistribution — Type
PanelDistribution LINEAR COSINE SPLIT_PROVIDED UNCHANGED BILLOWING
Enumeration of the implemented panel distributions.
Elements
- LINEAR # Linear distribution
- COSINE # Cosine distribution
SPLIT_PROVIDED# Split provided sectionsUNCHANGED# 1:1 copy of unrefined to refined sections (no interpolation)BILLOWING# Split provided + sinusoidal TE billowing between ribs
VortexStepMethod.InitialGammaDistribution — Type
InitialGammaDistribution ELLIPTIC ZEROS
Enumeration of the implemented initial gamma distributions.
Elements
- ELLIPTIC
- ZEROS
VortexStepMethod.SolverType — Type
SolverTypeEnumeration specifying the method used to solve for circulation distribution.
Values
LOOP: Converging gamma loop - iterative approach that repeatedly updates circulation values until convergenceNONLIN: Nonlinear solver - uses a numerical solver to solve the circulation equations
VortexStepMethod.SolverStatus — Type
SolverStatus FEASIBLE INFEASIBLE FAILURE
Enumeration to report back the validity of the result of the solve! function. Used in the VSMSolution struct.
Elements
- FEASIBLE: The gamma distribution is physically feasible
- INFEASIBLE: The gamma distribution is physically infeasible
- FAILURE: The result did not converge within the maximal number of iterations
Basic Vectors
VortexStepMethod.MVec3 — Type
const MVec3 = MVector{3, Float64}
Basic 3-dimensional vector, stack allocated, mutable.
VortexStepMethod.PosVector — Type
const PosVector=Union{MVec3, Vector}
Position vector, either a MVec3 or a Vector for use in function signatures.
VortexStepMethod.VelVector — Type
const VelVector=Union{MVec3, Vector}
Velocity vector, either a MVec3 or a Vector for use in function signatures.
Aerodynamic data
VortexStepMethod.AeroData — Type
AeroData= Union{
Nothing,
Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}},
Tuple{Vector{Float64}, Vector{Float64}, Vector{Float64}, Vector{Float64}},
Tuple{Vector{Float64}, Vector{Float64}, Matrix{Float64}, Matrix{Float64}, Matrix{Float64}}
}Union of different definitions of the aerodynamic properties of a wing section. See also: AeroModel
- nothing for INVISCID
- (
cl_coeffs,cd_coeffs,cm_coeffs) α-polynomial coefficients forPOLY - (
alpha_range,cl_vector,cd_vector,cm_vector) forPOLAR_VECTORS - (
alpha_range,delta_range,cl_matrix,cd_matrix,cm_matrix) forPOLAR_MATRICES
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) and the chord line of the airfoil.
Settings
VortexStepMethod.VSMSettings — Type
VSMSettingsTop-level settings container for a VortexStepMethod simulation. Can be constructed from keyword arguments or loaded from a YAML file with VSMSettings(filename).
Fields
condition:ConditionSettings(wind speed, alpha, beta, yaw rate)wings: Vector ofWingSettingssolver_settings:SolverSettings
Example
settings = VSMSettings("vsm_settings.yaml")
wing = Wing(settings)VortexStepMethod.WingSettings — Type
WingSettingsSettings for a single wing, used within VSMSettings.
Fields
name: Wing identifier (default"main_wing")geometry_file: Path to wing geometry YAML fileobj_file: Path to.objgeometry filedat_file: Path to.datairfoil filen_panels: Number of panels (default40)spanwise_panel_distribution: Panel distribution type (defaultLINEAR)spanwise_direction: Spanwise direction vector (default[0, 1, 0])remove_nan: Whether to remove NaN values from polar data (defaulttrue)use_prior_polar: Reuse prior refined/panel polar mapping on reinit/refine updates (defaultfalse)billowing_percentage: TE billow as percentage of arc length (default0.0; only used withBILLOWINGdistribution).crease_frac: Chordwise flap-hinge fraction (0–1) the polars are deflected about and the δ-deflected plate/skin is drawn with (default0.75).mesh:MeshSettings— howobj_fileis sliced into sections.airfoil:AirfoilSettings— the 2D backend and the polars it writes.
VortexStepMethod.MeshSettings — Type
MeshSettingsHow a wing's .obj mesh becomes airfoil slices, used within WingSettings: which mesh, and how to cut it.
obj_file here is the mesh the sections are generated from, an input to the geometry_file a wing then flies. That is not the wing's own obj_file, which is an alternative to geometry_file — a wing built straight from an obj and a dat, with no polar generation in between — and which cannot be given alongside one.
Apart from n_sections, which obj_to_yaml requires, every default here is the one that call and ShrinkWrap already apply, so a wing naming no mesh: block slices as an unconfigured call.
Fields
obj_file: Mesh the sections are sliced from, relative to the data directory (default"", no mesh).n_sections: Sections sliced from the mesh (default45).n_bins: Leading-edge stations marched across the span; more gives a smoother trace (default60).rotation: Rows of the mesh-to-slicer rotation, which brings the mesh into the slicer's convention of x = chord, y = span, z = up (default the identity).wingtip_distance: Spanwise length [m] the outermost sections stop short of each tip (default0.0).clearance: Shrink-wrap offset [chord fraction] the contour holds outside every cloud point, and the radius its convex corners are rounded at (default0.006).min_concave_radius: Shrink-wrap rolling-ball radius [chord fraction], bridging gaps and crevices in the point cloud (default0.02).
VortexStepMethod.AirfoilSettings — Type
AirfoilSettingsThe 2D section backend and the polars it tabulates, used within WingSettings. One block answers for both the tables a mesh is sliced into and the live polars a deformed section is re-solved on, so the two cannot be generated at different transition settings or off different networks.
Fields
solver: Section backend,"neuralfoil"or"xfoil"(default"neuralfoil").model_size: NeuralFoil network size (default"large").n_crit: e^N transition criticality; lower is dirtier, so transition is earlier (default9.0, the standard clean-tunnel value).xtr_upper/xtr_lower: Forced transition as a chord fraction, applied to whichever backendsolvernames (default0.05).alpha_range: Angle-of-attack sweep [deg] as[first, step, last](default[-180, 1, 180]).delta_range: Flap-deflection sweep [deg] as[first, step, last];nothingfor a dataset generated without a flap sweep (defaultnothing).live_offsets: Angles [deg] off the reference angle a live polar is sampled at (default-12:3:12).va: apparent wind speed [m/s] the polars' Reynolds number is taken at (default25.0).chord_ref: Reference (maximum panel) chord [m], which Reynolds is defined against (default1.0).table_format: Per-node table format,:csv(readable) or:arrow(about ten times faster to load; default:arrow). Written in YAML as a plain string, and carried as theSymbolthe generator takes.
VortexStepMethod.SolverSettings — Type
SolverSettingsSolver configuration, used within VSMSettings.
Fields
n_panels: Total number of panels (default40)aerodynamic_model_type:VSMorLLT(defaultVSM)solver_type:"LOOP"or"NONLIN"(default"LOOP")density: Air density (kg/m^3) (default1.225)max_iterations: Maximum solver iterations (default1500)rtol: Relative tolerance on the fixed-point residual (default1e-5)tol_reference_error: Reference error tolerance (default0.001)relaxation_factor: Convergence relaxation factor (default0.03)is_with_artificial_viscosity: Enable Li/Gaunaa post-stall artificial viscosity (defaultfalse)artificial_viscosity_factor: Viscosity scaling coefficient k (default0.035)type_initial_gamma_distribution:ELLIPTICorZEROS(defaultZEROS)use_gamma_prev: Reuse provided previous gamma as initial guess when available (defaulttrue)core_radius_fraction: Bound vortex core cut-off, as a fraction of the filament length, following Damiani et al. (2019) (default0.05)mu: Dynamic viscosity (N*s/m^2) (default1.81e-5)calc_only_f_and_gamma: Only output forces and circulation (defaultfalse)correct_aoa: Perform angle of attack correction (defaultfalse)flow_curvature: Add the thin-airfoil pitch-rate moment increment to each section (defaultfalse)is_with_viscous_drag_correction: Add the spanwise-flow viscous drag and side force to each section (defaultfalse)is_with_attached_trailed_force: Add the force on the chordwise trailed vortex segments bound to each panel (defaultfalse)
Wing Geometry, Panel and Aerodynamics
A body is constructed of one or more abstract wings. All wings are of type Wing. A Wing has one or more sections and can be created from YAML files or OBJ geometry.
VortexStepMethod.Section — Type
mutable struct Section{T}Represents a wing section with leading edge, trailing edge, and aerodynamic properties.
Fields
LE_point::MVector{3, T}: Leading edge point coordinatesTE_point::MVector{3, T}: Trailing edge point coordinatesaero_model::AeroModel:AeroModelaero_data::AeroData: See:AeroDatasection_aero::Union{Nothing, SectionAero}: optional surface aero table, seeSectionAero
VortexStepMethod.Section — Method
Section(LE_point, TE_point, aero_model)Create a new wing section with the specified leading edge point, trailing edge point, and aerodynamic model.
Arguments
LE_point::PosVector: Leading edge point coordinatesTE_point::PosVector: Trailing edge point coordinatesaero_model::AeroModel: Aerodynamic model type (e.g., INVISCID, POLAR_VECTORS)
Returns
Section: A new section with the specified parameters and no aerodynamic data
VortexStepMethod.Wing — Type
WingRepresents a wing composed of multiple sections with aerodynamic properties.
Core Fields (all wings)
n_panels::Int16: Number of panels in aerodynamic meshn_unrefined_sections::Int16: Number of unrefined sections (sections before mesh refinement)spanwise_distribution::PanelDistribution:PanelDistributionspanwise_direction::MVec3: Wing span direction vectorsections::AbstractVector{<:Section}: Vector of wing sections, see:Sectionrefined_sections::AbstractVector{<:Section}: Vector of refined wing sections, see:Sectionremove_nan::Bool: Wether to remove the NaNs from interpolations or notuse_prior_polar::Bool: Keep previously-initialized section/panel polar data when refining geometry updatescrease_frac::Float64: chordwise flap-hinge fraction (0–1) used when plotting the deflected plate
Deformation Fields (optional, for deformable wings)
non_deformed_sections::AbstractVector{<:Section}: Original undeformed sectionstheta_dist::Vector{Float64}: Panel twist angle distributiondelta_dist::Vector{Float64}: Trailing edge deflection distribution
Physical Properties (optional, for OBJ-based wings)
mass::Float64: Total wing mass in kg (0.0 if not applicable)gamma_tip::Float64: Angular extent from center to wing tip (0.0 if not applicable)inertia_tensor::Matrix{Float64}: 3x3 inertia tensor (empty if not applicable)T_cad_body::MVec3: Translation from CAD to body frame (zeros if not applicable)R_cad_body::MMat3: Rotation from CAD to body frame (identity if not applicable)radius::Float64: Wing curvature radius (0.0 if not applicable)le_interp::Union{Nothing, NTuple{3, Extrapolation}}: Leading edge interpolationte_interp::Union{Nothing, NTuple{3, Extrapolation}}: Trailing edge interpolationarea_interp::Union{Nothing, Extrapolation}: Area interpolationcache::Vector{PreallocationTools.LazyBufferCache{typeof(identity), typeof(identity)}}: Preallocated buffers
Deformation Fields (optional, for deformable wings)
non_deformed_sections::Vector{Section}: Original undeformed sectionstheta_dist::Vector{Float64}: Panel twist angle distributiondelta_dist::Vector{Float64}: Trailing edge deflection distribution
Physical Properties (optional, for OBJ-based wings)
mass::Float64: Total wing mass in kg (0.0 if not applicable)gamma_tip::Float64: Angular extent from center to wing tip (0.0 if not applicable)inertia_tensor::Matrix{Float64}: 3x3 inertia tensor (empty if not applicable)T_cad_body::MVec3: Translation from CAD to body frame (zeros if not applicable)R_cad_body::MMat3: Rotation from CAD to body frame (identity if not applicable)radius::Float64: Wing curvature radius (0.0 if not applicable)le_interp::Union{Nothing, NTuple{3, Extrapolation}}: Leading edge interpolationte_interp::Union{Nothing, NTuple{3, Extrapolation}}: Trailing edge interpolationarea_interp::Union{Nothing, Extrapolation}: Area interpolationcache::Vector{PreallocationTools.LazyBufferCache{typeof(identity), typeof(identity)}}: Preallocated buffers
VortexStepMethod.Wing — Method
Wing(n_panels::Int;
n_unrefined_sections=nothing,
spanwise_distribution::PanelDistribution=LINEAR,
spanwise_direction::PosVector=MVec3([0.0, 1.0, 0.0]),
remove_nan::Bool=true,
use_prior_polar::Bool=false,
billowing_percentage::Float64=0.0)Constructor for a Wing struct with default values that initializes the sections and refined sections as empty arrays. Creates a basic wing suitable for YAML-based construction.
Parameters
n_panels::Int: Number of panels in aerodynamic meshn_unrefined_sections::Int: Number of unrefined sections (inferred from added sections for YAML wings)spanwise_distribution::PanelDistribution = LINEAR:PanelDistributionspanwise_direction::MVec3= MVec3([0.0, 1.0, 0.0]): Wing span direction vectorremove_nan::Bool: Whether to remove the NaNs from interpolations or notuse_prior_polar::Bool: Reuse prior refined/panel polar mapping during geometry-only updatesbillowing_percentage::Float64: TE billow as percentage of arc length (0=flat)
VortexStepMethod.ObjWing — Function
ObjWing(obj_path[, dat_path]; n_panels, Re, alpha_range, delta_range,
n_sections, spanwise_direction, aero_solver, remake, output_dir,
crease_frac, verbose) → WingConvenience constructor retained for backward compatibility. Converts an OBJ mesh to a YAML wing geometry via ObjAdapter.obj_to_yaml and returns a Wing.
dat_path is accepted but ignored — airfoil shapes are extracted directly from the OBJ geometry. Use aero_solver=AirfoilAero.XFoilSolver() to reproduce old XFoil-based polars; the default is AirfoilAero.NeuralFoilSolver().
alpha_range and delta_range are in degrees (matching ObjAdapter.obj_to_yaml).
By default (remake=false) an existing geometry.yaml in output_dir is reused, skipping the expensive polar generation. Set remake=true to force regeneration.
VortexStepMethod.BodyAerodynamics — Type
@with_kw mutable struct BodyAerodynamics{P,W<:AbstractWing}Main structure for calculating aerodynamic properties of bodies. Use the constructor to initialize.
Fields
- panels::Vector{<:Panel}: Vector of refined
Panelstructs - wings::Vector{W}: A vector of wings of type
W <: AbstractWing; a body can have multiple wings va_vec::MVec3= zeros(MVec3): apparent wind vector [m/s], see:MVec3omega::MVec3 = zeros(MVec3): A vector of the turn rates around the KA body axesreference_point::MVec3 = zeros(MVec3): The pointomegaturns the body about [m]gamma_distribution=zeros(Float64, P): A vector of the circulation of the velocity field; Length: Number of segments. [m²/s]alpha_uncorrected=zeros(Float64, P): angles of attack per panelalpha_corrected=zeros(Float64, P): corrected angles of attack per panelstall_angle_list=zeros(Float64, P): stall angle per panelalpha_dist::MVector{P, Float64}= zeros(Float64, P)v_rel_dist::MVector{P, Float64}= zeros(Float64, P): norm of the relative velocity crossed with the panel spanwise axis, |vrel × yairf| [m/s]pitch_rate_dist::MVector{P, Float64}= zeros(Float64, P): rotation rate of each panel about its own spanwise axis, positive nose-up [rad/s]; set byset_va!and read when the solver hasflow_curvatureenabledwork_vectors::NTuple{10, MVec3} = ntuple(_ -> zeros(MVec3), 10)AIC::Array{Float64, 3}= zeros(P, P, 3): control-point influence coefficients, the matrix the circulation is solved against; component last so that eachAIC[:, :, k]slice is a contiguous BLAS matrixAIC_aero_center::Array{Float64, 3}= zeros(P, P, 3): aerodynamic-centre (LLT) influence coefficients, used only for the corrected angle of attackprojected_area::Float64= 1.0: The area projected onto the xy-plane of the KA body frame [m²]c_ref::Float64= 1.0: Reference chord length (max panel chord) [m]cache::Vector{PreallocationTools.LazyBufferCache{typeof(identity), typeof(identity)}}= [LazyBufferCache() for _ in 1:12]
The Solver and its results
VortexStepMethod.Solver — Type
SolverMain solver structure for the Vortex Step Method.See also: solve
Attributes
General settings
aerodynamic_model_type::Model = VSM: The model type, see:Model- density::Float64 = 1.225: Air density [kg/m³]
max_iterations::Int64 = 1500rtol::Float64 = 1e-5: Relative tolerance on the fixed-point residualtol_reference_error::Float64 = 0.001relaxation_factor::Float64 = 0.03: Relaxation factor for convergence
Artificial viscosity settings
is_with_artificial_viscosity::Bool = false: Enable the Li/Gaunaa spanwise artificial viscosity (TORQUE 2026) for post-stall stabilization in the LOOP solverartificial_viscosity_factor::Float64 = 0.035: Coefficient k in the viscosity scaling (the conservative envelope from the paper)
Additional settings
type_initial_gamma_distribution::InitialGammaDistribution = ZEROS: see:InitialGammaDistributionuse_gamma_prev::Bool = true: reuse provided previous gamma as initial guess when availablecore_radius_fraction::Float64 = 0.05: Bound vortex core cut-off, as a fraction of the filament length, following Damiani et al. (2019)- mu::Float64 = 1.81e-5: Dynamic viscosity [N·s/m²]
is_only_f_and_gamma_output::Bool = false: Whether to only output f and gammaflow_curvature::Bool = false: Add the thin-airfoil pitch-rate moment increment-(π/4) q̂to each section, see:flow_curvature_cmis_with_viscous_drag_correction::Bool = false: Add the spanwise-flow viscous drag and side force to each section, see:spanwise_flow_dragis_with_attached_trailed_force::Bool = false: Add the force on the chordwise trailed vortex segments bound to each panel, see:attached_trailed_loadsreference_point::MVec3 = [0.0, 0.0, 0.0]: Moment reference point in body frame
Solution
sol::VSMSolution = VSMSolution(): The result of calling solve!
VortexStepMethod.VSMSolution — Type
VSMSolutionStruct for storing the solution of the solve! function. Must contain all info needed by KiteModels.jl.
Naming Convention
- Variables ending in
_dist: Per-panel distributions (length P, one value per panel) - Variables ending in
_unrefined_dist: Per-unrefined-section distributions (length U, averaged values per unrefined section)
Attributes
width_dist::Vector{Float64}: Width of the panels [m]alpha_dist::Vector{Float64}: Angle of attack of each panel relative to the apparent wind [rad]- cl_dist::Vector{Float64}: Lift coefficients of the panels [-]
- cd_dist::Vector{Float64}: Drag coefficients of the panels [-]
- cm_dist::Vector{Float64}: Pitching moment coefficients of the panels [-]
- lift_dist::Vector{Float64}: Lift force per unit span of the panels [N/m]
- drag_dist::Vector{Float64}: Drag force per unit span of the panels [N/m]
- panelmomentdist::Vector{Float64}: Pitching moment per unit span about y_airf [Nm/m]
f_body_3D::Matrix{Float64}: Matrix of the aerodynamic forces (x, y, z vectors) [N]m_body_3D::Matrix{Float64}: Matrix of the aerodynamic moments [Nm]gamma_distribution::Union{Nothing, Vector{Float64}}: Vector containing the panel circulations.- force::MVec3: Aerodynamic force vector in the KA frame [N]
- moment::MVec3: Aerodynamic moments [Mx, My, Mz] around the reference point [Nm]
- force_coeffs::MVec3: Aerodynamic force coefficients [CFx, CFy, CFz] [-]
moment_coeffs::MVec3: Aerodynamic moment coefficients [CMx, CMy, CMz] [-]moment_dist::Vector{Float64}: Pitching moments around the spanwise vector of each panel. [Nm]moment_coeff_dist::Vector{Float64}: Pitching moment coefficient around the spanwise vector of each panel. [-]moment_unrefined_dist::MVector{U, Float64}: Averaged moments for unrefined sections [Nm]cl_unrefined_dist::MVector{U, Float64}: Averaged lift coefficients for unrefined sections [-]cd_unrefined_dist::MVector{U, Float64}: Averaged drag coefficients for unrefined sections [-]cm_unrefined_dist::MVector{U, Float64}: Averaged airfoil moment coefficients for unrefined sections [-]moment_coeff_unrefined_dist::MVector{U, Float64}: Summedmoment_frac-referenced pitching-moment coefficient per unrefined section [-]alpha_unrefined_dist::MVector{U, Float64}: Averaged angles of attack for unrefined sections [rad]solver_status::SolverStatus: enum, seeSolverStatus
VortexStepMethod.SolveFailure — Type
SolveFailure(msg)Thrown by solve!(...; throw_on_fail=true) when the circulation loop missed the solver's tolerances, or when the coefficients it assembled are not finite.