Wing Geometry Schema

This document describes the user-facing schema for defining a wing using standard preliminary-design parameters while internally constructing NURBS patches with explicit C0/G1 join control.


Runtime Support Summary

As of 2026-03-25, WingCanonical.from_spec(...) resolves wing section airfoils through AirfoilFactory.from_spec(...). That currently supports runtime section sampling for these airfoil types:

  • naca4

  • naca4_modified

  • naca5

  • naca5_modified

Other airfoil families documented in the airfoil schema are valid schema targets but are not yet constructable through the current runtime factory.


1. Top-Level Structure

Required Keys

  • schema_version (int): schema version.

  • units (object): unit declarations (used for validation and display).

  • wing (object): the wing definition.

  • airfoils (object): named airfoil definitions referenced by panels.

Example Skeleton

schema_version: 2
units: {length: m, angle: deg}

wing: {}
airfoils: {}

2. Units

units:
  length: m        # or ft (if you support it)
  angle: deg       # or rad
  • Recommend storing angles in degrees for user convenience; convert to radians internally.


3. wing

3.1 Required Fields

  • symmetry (enum): "mirror_y" or "none"

  • half_span (float): half-span (length units)

  • reference_axis (enum): "leading_edge" | "quarter_chord" | "elastic_axis"

  • twist_axis (enum): "leading_edge" | "quarter_chord" | "elastic_axis"

  • panels (list[panel])


4. panel

4.1 Required Fields

  • id (str): unique panel identifier.

  • eta_range (2-tuple float): [eta0, eta1] with 0 eta0 < eta1 1.

  • ref_line (object): defines x_ref(eta) and z_ref(eta).

  • chord (distribution): defines c(eta).

  • twist (distribution): defines theta(eta) in units.angle.

  • airfoil (airfoil_spec)

4.2 Optional Fields

  • nurbs (object): internal construction knobs (safe to omit; defaults apply)

  • mesh (object): sampling preferences for exports (VLM/CFD)


5. Distribution

A distribution defines a scalar function of eta.

5.2 Validation Rules

  • eta values must be increasing.

  • Values are in the implied units for the field (meters for chord, degrees for twist, meters for x_ref/z_ref).

5.3 Future Extensions

You can later add:

  • type: spline

  • type: polynomial

  • type: constant


6. Reference Line

ref_line:
  x_ref: {type: piecewise_linear, data: [[0.0, 0.0], [1.0, 1.8]]}
  z_ref: {type: piecewise_linear, data: [[0.0, 0.0], [1.0, 0.8]]}

6.1 Interpretation

  • x_ref(eta) encodes sweep as the x-position of the selected reference axis.

  • z_ref(eta) encodes dihedral as the z-position of the selected reference axis.


7. Airfoil Specification

7.1 Single Airfoil

airfoil:
  type: single
  name: naca0012

Fields

  • type: "single"

  • name: key in the top-level airfoils map

7.2 Spanwise Blended Airfoil

airfoil:
  type: blend
  method: cst                 # "pointwise" | "cst" | "camber_thickness"
  stations: [[0.0, naca2412], [0.6, naca0012]]

Fields

  • type: "blend"

  • method: blending method

  • stations: list of [eta, airfoil_name] pairs defining blend control stations

Validation Rules

  • eta in stations must be increasing and cover the panel’s eta_range (recommended).

  • Implementer note: if stations don’t align with panel ends, decide whether to extrapolate or error.


8. airfoils (Top Level)

Named airfoil definitions referenced by wing panels.

This mapping is part of the wing document, so a wing YAML file is self-contained. Each value in the mapping must conform to the airfoil definition schema documented in the Airfoil Geometry Schema.

Example:

airfoils:
  root: {type: naca4, designation: "2412"}
  mid:  {type: naca4_modified, designation: "2412-46"}
  tip:  {type: dat, path: "airfoils/tip.dat"}

Wing canonical currently supports naca4, naca4_modified, naca5, and naca5_modified definitions for section sampling.


9. NURBS (Panel-Local)

These parameters affect internal NURBS construction. Users can omit them and accept defaults.

nurbs:
  degrees: {u: 4, v: 3}
  ctrlpts: {u: 16, v: 10}
  fit:
    method: skin              # "skin" | "least_squares"

9.1 Validation Recommendations

  • degrees.u >= 2, degrees.v >= 2

  • ctrlpts.u > degrees.u, ctrlpts.v > degrees.v


10. joins

Users explicitly specify continuity at each patch interface.

joins:
  - id: "J0"
    left:  {panel: "P0_inboard", side: "v_max"}
    right: {panel: "P1_outboard", side: "v_min"}
    continuity: "G1"          # "C0" | "G1"
    weight: 5.0               # optional; solver weighting
    tangent_scale: "auto"     # "auto" or numeric lambda

10.1 Required Fields

  • id (str)

  • left.panel (str): existing panel id

  • left.side (enum): u_min|u_max|v_min|v_max

  • right.panel (str)

  • right.side (enum)

  • continuity (enum): C0|G1

10.2 Optional Fields

  • weight (float): relative strength of the join constraint (for constrained solve).

  • tangent_scale (float or “auto”): sets λ in the G1 condition.


11. Export Sampling Controls (Optional)

You can attach export sampling controls at the panel level or globally.

Example:

mesh:
  vlm: {n_span: 24, n_chord: 12, span_spacing: cosine, chord_spacing: cosine}
  cfd: {n_span: 80, n_airfoil: 240}

11.1 Validation Rules (Suggested)

  • positive integer counts

  • allow uniform|cosine


12. Minimal Complete Example

schema_version: 2
units: {length: m, angle: deg}

wing:
  name: demo
  symmetry: mirror_y
  half_span: 5.0
  reference_axis: quarter_chord
  twist_axis: quarter_chord

  panels:
    - id: P0
      eta_range: [0.0, 1.0]
      ref_line:
        x_ref: {type: piecewise_linear, data: [[0.0, 0.0], [1.0, 1.0]]}
        z_ref: {type: piecewise_linear, data: [[0.0, 0.0], [1.0, 0.5]]}
      chord: {type: piecewise_linear, data: [[0.0, 2.0], [1.0, 1.0]]}
      twist: {type: piecewise_linear, data: [[0.0, 2.0], [1.0, -2.0]]}
      airfoil: {type: single, name: naca0012}

airfoils:
  naca0012: {type: naca4, designation: "0012"}