Skip to main content
Version: Next

NacaDiscipline

from philote_examples import NacaDiscipline

Philote discipline that generates NACA 4-digit airfoil coordinates.

Produces airfoil coordinates in XFOIL Selig format (TE -> upper -> LE -> lower -> TE), compatible with the XfoilDiscipline inputs.

Inherits from: philote_mdo.general.ExplicitDiscipline

Constructor

NacaDiscipline(n_points: int)

Parameters

NameTypeDescription
n_pointsintTotal number of coordinate points in the output contour

Properties set by constructor

PropertyValueDescription
_is_continuousTrueDiscipline outputs are continuous
_is_differentiableTrueDiscipline outputs are differentiable
_provides_gradientsTrueDiscipline provides analytical gradients

Methods

setup()

Defines inputs and outputs for the NACA discipline.

Inputs:

NameShapeUnitsDescription
camber(1,)--Maximum camber (1st NACA digit)
camber_loc(1,)--Location of maximum camber (2nd NACA digit)
thickness(1,)--Maximum thickness (3rd-4th NACA digits)

Outputs:

NameShapeUnitsDescription
airfoil_x(n_points,)--Airfoil x-coordinates in Selig format
airfoil_y(n_points,)--Airfoil y-coordinates in Selig format

setup_partials()

Declares all partial derivatives. Declares partials of both outputs (airfoil_x, airfoil_y) with respect to all three inputs (camber, camber_loc, thickness).

compute(inputs, outputs)

Generates NACA 4-digit airfoil coordinates.

The input values are internally rescaled:

  • camber is divided by 100 (e.g., 2 becomes 0.02)
  • camber_loc is divided by 10 (e.g., 4 becomes 0.4)
  • thickness is divided by 100 (e.g., 12 becomes 0.12)

Coordinates are computed using cosine-spaced x-stations and output in Selig format (upper surface reversed, concatenated with lower surface).

compute_partials(inputs, partials)

Computes analytical partial derivatives via chain rule through the NACA 4-digit thickness distribution and mean camber line formulas.

The Jacobian includes scaling factors for the input transformations:

  • /camber\partial / \partial\text{camber}: scaled by 0.01
  • /camber_loc\partial / \partial\text{camber\_loc}: scaled by 0.1
  • /thickness\partial / \partial\text{thickness}: scaled by 0.01

Module-Level Functions

The following functions in philote_examples.naca support the discipline:

_thickness_poly(x)

NACA 4-digit thickness polynomial (without the 5t5t scaling factor).

poly(x)=0.2969x0.1260x0.3516x2+0.2843x30.1015x4\text{poly}(x) = 0.2969\sqrt{x} - 0.1260\,x - 0.3516\,x^2 + 0.2843\,x^3 - 0.1015\,x^4

_thickness(x, t)

Full NACA 4-digit thickness distribution: yt=5tpoly(x)y_t = 5t \cdot \text{poly}(x).

_camber(x, m, p)

Mean camber line ycy_c and its slope dyc/dxdy_c/dx for given max camber mm and position pp.

_camber_partials(x, m, p)

Partial derivatives of the camber line and slope with respect to mm and pp:

  • dyc_dm, dyc_dp -- partials of ycy_c
  • ddyc_dm, ddyc_dp -- partials of dyc/dxdy_c/dx

_selig(upper, lower)

Combines upper and lower surface arrays in Selig order: upper reversed, concatenated with lower (excluding the shared leading-edge point).

Example

from philote_examples import NacaDiscipline
from philote_mdo.general import run_server

# Create discipline with 100 contour points
discipline = NacaDiscipline(n_points=100)

# Serve over gRPC
run_server(discipline, port=50051)