Density Altitude (cross-cutting/units-atmos/density-altitude)
Use when the task is the density altitude on a non-standard day:
the pressure altitude and the outside air temperature (OAT) collapse
to the altitude the air would occupy on an ISA day, which gates
takeoff distance, climb rate and performance reduction. This leaf
owns the inverse-density step: the ISA deviation, the density ratio
sigma = delta(hp) * T0 / T_oat, and the density altitude from the
troposphere closed-form inverse with the stratosphere branch, in
pure Python stdlib only. It pairs with cross-cutting/units-atmos/
isa-atmosphere, the forward ISA model this leaf inverts, and serves
the domain consumers that previously duplicated this function.
Domain quick reference
- Constants: T0 = 288.15 K, L = 0.0065 K/m, g = 9.80665 m/s2,
R = 287.0 J/(kg K), p0 = 101325 Pa, tropopause 11000 m, isothermal
stratosphere 216.65 K.
- ISA temperature at pressure altitude hp: T0 - L * hp in the
troposphere, 216.65 K above it (isa_temperature_k).
- ISA pressure ratio: delta(hp) = (1 - L hp / T0)^(g/(R L)) in the
troposphere, exponential decay from the tropopause state above
(isa_pressure_ratio).
- ISA deviation: DeltaT = OAT - T_ISA(hp) (isa_deviation_k).
- Density ratio: sigma = delta(hp) * T0 / T_oat. At fixed pressure
altitude a warm day gives sigma below the ISA value and raises the
density altitude; a cold day lowers it.
- Troposphere density altitude, closed form:
h_rho = (T0 / L) * (1 - sigma^e) with e = 1 / (g/(R L) - 1),
the exact inverse of the density power law (about 0.2349). Note:
the exponent e equals R L / (g - R L) with the module constants;
the classical R L / g inverts the pressure law, not the density
law, and would break the ISA identity, so the exact density
inverse is used here.
- Stratosphere branch (sigma below the tropopause density ratio):
h_rho = 11000 - (R * 216.65 / g) * ln(sigma / sigma_trop). The two
branches meet exactly at the tropopause.
- Units: hp and altitude in meters (ft wrapper accepts feet), OAT in
kelvin for the meter forms and degrees C for the ft wrapper.
Workflow
- Fix the pressure altitude and the OAT at the test point.
- Read the ISA temperature there with isa_temperature_k.
- Get the day's non-standard character with isa_deviation_k.
- Read the ISA pressure ratio with isa_pressure_ratio, then the
density ratio sigma with density_ratio_from_pressure_temperature
or the direct product delta * T0 / oat_k.
- Compute the density altitude with density_altitude_m (meters,
kelvin) or density_altitude_ft (feet, degrees C).
- Collect the full set with density_altitude_summary.
- Confirm the deterministic checks with the contract test.
Worked example
Module outputs on the spec anchors (real values, R = 287.0):
- ISA identity: density_altitude_m(0, 288.15) = 0.00 m and
density_altitude_m(3048, isa_temperature_k(3048)) = 3048.00 m
(h_rho = h_p on the standard day, exact at 10000 ft); the identity
also holds at the tropopause and in the stratosphere branch.
- Hot day, sea level: OAT 30 C, 15 K above the standard day:
density_altitude_m(0, 303.15) = 525.34 m,
density_altitude_ft(0, 30) = 1723.55 ft (about 525.46 m =
1723.94 ft by the independent check).
- Warm day at 10000 ft pressure altitude, OAT = ISA + 10 K (5.19 C):
density_altitude_ft(10000, 5.188) = 11159.18 ft, above the
pressure altitude (about 11159.44 ft by the independent check).
- Cold day at 10000 ft, OAT = ISA - 10 K (-14.81 C):
density_altitude_ft(10000, -14.812) = 8786.21 ft, below the
pressure altitude (about 8785.93 ft by the independent check).
- Domain cross-check: density_altitude_ft(10000, 15) = 12247.62 ft,
reproducing the climb-performance-flight-test bisection result of
12248.13 ft at OAT 15 C absolute on a 10000 ft pressure altitude.
Pitfalls
- Feeding OAT in degrees C to the meter form (or kelvin to the ft
wrapper): density_altitude_m takes kelvin and density_altitude_ft
takes degrees C; mixing the scales shifts the result by 273.15 K.
- Confusing density altitude with pressure altitude: the two are equal
only on the standard day; an OAT deviation moves them apart (ISA +10 K
at 10000 ft reads about 11159 ft, ISA -10 K about 8786 ft).
- Using the ISA temperature instead of the day's measured OAT at the
test point: the whole quantity exists to capture the non-standard
deviation, so the standard-day temperature gives back the pressure
altitude by construction.
- Passing OAT at or below 0 K or a pressure altitude below -1000 m: the
module raises ValueError rather than extrapolating, though small
negative geopotential altitudes are allowed down to -1000 m.
- Expecting one lapse behavior across the whole atmosphere: the ISA
temperature and pressure ratio branches switch at the tropopause, and
the closed-form inversion matches the bisection only within the
correct branch.
Verification
- ISA identity: density altitude equals pressure altitude at 0 m,
3048 m and the tropopause on the standard day, to 0.2 m.
- Worked magnitudes: sea level OAT 30 C about 525.4 m / 1723.6 ft;
10000 ft ISA +10 K about 11159 ft; ISA -10 K about 8786 ft.
- Monotonicity: at fixed pressure altitude a warmer OAT raises the
density altitude and a colder one lowers it; at fixed OAT a higher
pressure altitude raises it.
- Closed form versus 200-iteration bisection of the forward ISA
density law agrees to 1e-6 on both the troposphere and the
stratosphere branches; the branch switch is continuous.
- Determinism: identical outputs run to run, no RNG, offline.
- ValueError rejection: pressure altitude below -1000 m (small
negative geopotential is allowed) and OAT at or below 0 K.
- Run the contract test offline: python3
scripts/test_density_altitude.py (35 tests, deterministic).
Related leaves
- cross-cutting/units-atmos/isa-atmosphere: the forward ISA state
model this leaf inverts.
- cross-cutting/units-atmos/airspeed-conversion: takes pressure
altitude as input and pairs with the density altitude for air-data
reduction.
- flight-test-operations/performance/climb-performance-flight-test:
the domain consumer that previously duplicated this function.
Behavior contract (gate 3)
Run the deterministic contract test (stdlib unittest, offline):
python3 scripts/test_density_altitude.py
The test covers the module constants and sea-level anchors, the ISA
temperature and pressure ratio branches, the ISA deviation, the
density ratio from pressure and temperature, the ISA identity at
0 m, 3048 m, the tropopause and in the stratosphere, the worked
magnitude anchors (sea level OAT 30 C, 10000 ft ISA +10 K and
ISA -10 K), the domain-precedent cross-check at 10000 ft OAT 15 C,
monotonicity in temperature and pressure altitude, closed-form
agreement with an independent 200-iteration bisection on both
branches, continuity across the tropopause branch switch, ValueError
rejection of non-physical inputs including the -1000 m boundary,
the ft wrapper against the meter form, the exact summary dict key
set and its consistency with the functions, and run-to-run
determinism.
Compliance
- Standards referenced, not reproduced: ECSS frames the atmosphere
reference context; the ISA model is common reference data and the
relations above are standard engineering methodology, summary-only
per standards-map.yaml.
- compliance: STANDARDS-REF, gated: false.
1---2name: density-altitude3description: Use when you must compute the density altitude from the pressure altitude and the outside temperature: the ISA deviation, the density ratio sigma from the ISA pressure ratio and the temperature ratio, and the density altitude via the troposphere closed-form inverse with the stratosphere branch. Produces the density altitude in meters and feet for hot-day and cold-day takeoff and performance checks. Trigger: density altitude, pressure altitude, outside air temperature, non-standard day, ISA deviation, density ratio, hot day, cold day, takeoff performance, performance reduction.4license: Apache-2.05---67# Density Altitude (cross-cutting/units-atmos/density-altitude)89Use when the task is the density altitude on a non-standard day:10the pressure altitude and the outside air temperature (OAT) collapse11to the altitude the air would occupy on an ISA day, which gates12takeoff distance, climb rate and performance reduction. This leaf13owns the inverse-density step: the ISA deviation, the density ratio14sigma = delta(hp) * T0 / T_oat, and the density altitude from the15troposphere closed-form inverse with the stratosphere branch, in16pure Python stdlib only. It pairs with cross-cutting/units-atmos/17isa-atmosphere, the forward ISA model this leaf inverts, and serves18the domain consumers that previously duplicated this function.1920## Domain quick reference2122- Constants: T0 = 288.15 K, L = 0.0065 K/m, g = 9.80665 m/s2,23 R = 287.0 J/(kg K), p0 = 101325 Pa, tropopause 11000 m, isothermal24 stratosphere 216.65 K.25- ISA temperature at pressure altitude hp: T0 - L * hp in the26 troposphere, 216.65 K above it (isa_temperature_k).27- ISA pressure ratio: delta(hp) = (1 - L hp / T0)^(g/(R L)) in the28 troposphere, exponential decay from the tropopause state above29 (isa_pressure_ratio).30- ISA deviation: DeltaT = OAT - T_ISA(hp) (isa_deviation_k).31- Density ratio: sigma = delta(hp) * T0 / T_oat. At fixed pressure32 altitude a warm day gives sigma below the ISA value and raises the33 density altitude; a cold day lowers it.34- Troposphere density altitude, closed form:35 h_rho = (T0 / L) * (1 - sigma^e) with e = 1 / (g/(R L) - 1),36 the exact inverse of the density power law (about 0.2349). Note:37 the exponent e equals R L / (g - R L) with the module constants;38 the classical R L / g inverts the pressure law, not the density39 law, and would break the ISA identity, so the exact density40 inverse is used here.41- Stratosphere branch (sigma below the tropopause density ratio):42 h_rho = 11000 - (R * 216.65 / g) * ln(sigma / sigma_trop). The two43 branches meet exactly at the tropopause.44- Units: hp and altitude in meters (ft wrapper accepts feet), OAT in45 kelvin for the meter forms and degrees C for the ft wrapper.4647## Workflow48491. Fix the pressure altitude and the OAT at the test point.502. Read the ISA temperature there with isa_temperature_k.513. Get the day's non-standard character with isa_deviation_k.524. Read the ISA pressure ratio with isa_pressure_ratio, then the53 density ratio sigma with density_ratio_from_pressure_temperature54 or the direct product delta * T0 / oat_k.555. Compute the density altitude with density_altitude_m (meters,56 kelvin) or density_altitude_ft (feet, degrees C).576. Collect the full set with density_altitude_summary.587. Confirm the deterministic checks with the contract test.5960## Worked example6162Module outputs on the spec anchors (real values, R = 287.0):6364- ISA identity: density_altitude_m(0, 288.15) = 0.00 m and65 density_altitude_m(3048, isa_temperature_k(3048)) = 3048.00 m66 (h_rho = h_p on the standard day, exact at 10000 ft); the identity67 also holds at the tropopause and in the stratosphere branch.68- Hot day, sea level: OAT 30 C, 15 K above the standard day:69 density_altitude_m(0, 303.15) = 525.34 m,70 density_altitude_ft(0, 30) = 1723.55 ft (about 525.46 m =71 1723.94 ft by the independent check).72- Warm day at 10000 ft pressure altitude, OAT = ISA + 10 K (5.19 C):73 density_altitude_ft(10000, 5.188) = 11159.18 ft, above the74 pressure altitude (about 11159.44 ft by the independent check).75- Cold day at 10000 ft, OAT = ISA - 10 K (-14.81 C):76 density_altitude_ft(10000, -14.812) = 8786.21 ft, below the77 pressure altitude (about 8785.93 ft by the independent check).78- Domain cross-check: density_altitude_ft(10000, 15) = 12247.62 ft,79 reproducing the climb-performance-flight-test bisection result of80 12248.13 ft at OAT 15 C absolute on a 10000 ft pressure altitude.8182## Pitfalls8384- Feeding OAT in degrees C to the meter form (or kelvin to the ft85 wrapper): density_altitude_m takes kelvin and density_altitude_ft86 takes degrees C; mixing the scales shifts the result by 273.15 K.87- Confusing density altitude with pressure altitude: the two are equal88 only on the standard day; an OAT deviation moves them apart (ISA +10 K89 at 10000 ft reads about 11159 ft, ISA -10 K about 8786 ft).90- Using the ISA temperature instead of the day's measured OAT at the91 test point: the whole quantity exists to capture the non-standard92 deviation, so the standard-day temperature gives back the pressure93 altitude by construction.94- Passing OAT at or below 0 K or a pressure altitude below -1000 m: the95 module raises ValueError rather than extrapolating, though small96 negative geopotential altitudes are allowed down to -1000 m.97- Expecting one lapse behavior across the whole atmosphere: the ISA98 temperature and pressure ratio branches switch at the tropopause, and99 the closed-form inversion matches the bisection only within the100 correct branch.101102## Verification103104- ISA identity: density altitude equals pressure altitude at 0 m,105 3048 m and the tropopause on the standard day, to 0.2 m.106- Worked magnitudes: sea level OAT 30 C about 525.4 m / 1723.6 ft;107 10000 ft ISA +10 K about 11159 ft; ISA -10 K about 8786 ft.108- Monotonicity: at fixed pressure altitude a warmer OAT raises the109 density altitude and a colder one lowers it; at fixed OAT a higher110 pressure altitude raises it.111- Closed form versus 200-iteration bisection of the forward ISA112 density law agrees to 1e-6 on both the troposphere and the113 stratosphere branches; the branch switch is continuous.114- Determinism: identical outputs run to run, no RNG, offline.115- ValueError rejection: pressure altitude below -1000 m (small116 negative geopotential is allowed) and OAT at or below 0 K.117- Run the contract test offline: python3118 scripts/test_density_altitude.py (35 tests, deterministic).119120## Related leaves121122- cross-cutting/units-atmos/isa-atmosphere: the forward ISA state123 model this leaf inverts.124- cross-cutting/units-atmos/airspeed-conversion: takes pressure125 altitude as input and pairs with the density altitude for air-data126 reduction.127- flight-test-operations/performance/climb-performance-flight-test:128 the domain consumer that previously duplicated this function.129130## Behavior contract (gate 3)131132Run the deterministic contract test (stdlib unittest, offline):133134 python3 scripts/test_density_altitude.py135136The test covers the module constants and sea-level anchors, the ISA137temperature and pressure ratio branches, the ISA deviation, the138density ratio from pressure and temperature, the ISA identity at1390 m, 3048 m, the tropopause and in the stratosphere, the worked140magnitude anchors (sea level OAT 30 C, 10000 ft ISA +10 K and141ISA -10 K), the domain-precedent cross-check at 10000 ft OAT 15 C,142monotonicity in temperature and pressure altitude, closed-form143agreement with an independent 200-iteration bisection on both144branches, continuity across the tropopause branch switch, ValueError145rejection of non-physical inputs including the -1000 m boundary,146the ft wrapper against the meter form, the exact summary dict key147set and its consistency with the functions, and run-to-run148determinism.149150## Compliance151152- Standards referenced, not reproduced: ECSS frames the atmosphere153 reference context; the ISA model is common reference data and the154 relations above are standard engineering methodology, summary-only155 per standards-map.yaml.156- compliance: STANDARDS-REF, gated: false.