pub fn resolve_atmosphere_for_density_altitude(
density_altitude_m: f64,
explicit_temperature_c: Option<f64>,
) -> (f64, f64, f64)Expand description
Back-solve an ISA-equivalent station altitude/temperature/pressure from a directly-declared density altitude (MBA-1366) — the single-value atmosphere entry mode Shooter, Nosler, AB Analytics, Ballistic AE, and TRASOL all support as an alternative to altitude + pressure + temperature.
This is the exact algebraic inverse of the FAA-rule density-altitude model this engine
already uses to REPORT density altitude (faa_rule_density_altitude_ft, which
pdf_dope_card::calculate_density_altitude delegates to):
pressure_alt_ft = 145366.45 * (1 - (station_hpa / 1013.25)^0.190284)
isa_temp_f = 59.0 - pressure_alt_ft / 1000.0 * 3.57
density_alt_ft = pressure_alt_ft + (120*5/9) * (station_temp_f - isa_temp_f)Solved for station_hpa given a target density_alt_ft and a station temperature `K = 120
- 5/9` is the “120 ft per °C” density-altitude correction rule, expressed in ft per °F):
pressure_alt_ft = (density_alt_ft - K*(station_temp_f - 59.0)) / (1 + K*3.57/1000.0)
station_hpa = 1013.25 * (1 - pressure_alt_ft/145366.45)^(1/0.190284)§Temperature precedence (MBA-1366)
explicit_temperature_c == None: ISA-at-density-altitude is the default. Algebraically this collapsespressure_alt_ftto EXACTLYdensity_alt_ft: the correction term above is zero by construction whenever the station temperature equals the ISA temperature at that pressure altitude, which is self-consistently true when temperature is left at ISA — i.e. omitting an explicit temperature is equivalent to typing--altitude <density_altitude>with no--temperature/--pressureoverride.explicit_temperature_c == Some(t):twins outright (returned unchanged astemperature_c, never re-derived) and the station pressure is re-solved so the resulting density altitude still reproduces the input exactly. The FAA-rule density altitude is honored either way, but the DENSITY is not: the rule is a straight-line approximation, not a curve of equal density, so the ISA-default case rebuilds different air — at 30 °C and 1013.25 hPa, a rebuilt 11.4 °C / 949 hPa, 0.3% denser, with a speed of sound 3% lower. Only the real temperature reproduces the real air.
§Height convention
The FAA-rule formula being inverted (faa_rule_density_altitude_ft) performs no
geopotential correction — it treats its altitude as a plain height (the DOPE card, which
delegates to it, leaves its own _altitude_ft parameter unused for that reason). Consistent with that, the altitude_m this returns is GEOMETRIC altitude
— the same convention every other engine altitude input uses (--altitude,
AtmosphericConditions::altitude) —
rather than being run through geometric_to_geopotential_height_m a second time here; that
conversion is calculate_icao_standard_atmosphere’s job (both private to this crate — see
their doc comments elsewhere in this file), applied once this altitude re-enters the normal
altitude-lapse pipeline (this is what “back-solve an ISA-equivalent atmosphere” means —
unlike get_direct_atmosphere, which would freeze speed of sound and bypass that pipeline
entirely).
§Interaction with PressureReferenceMode (QNH)
Density altitude supersedes pressure outright — callers must not also run a declared
--pressure/QNH value through resolve_station_pressure_with_mode when a density
altitude is present; see the CLI/WASM call sites, which emit a note to that effect.
§Returns
(altitude_m, temperature_c, pressure_hpa), meant to be written directly into
crate::cli_api::AtmosphericConditions (and the paired BallisticInputs environment
fields, so powder-temperature sensitivity and the moist speed of sound both see the real
resolved temperature) via the Authoritative
(TrajectorySolver::new_with_resolved_station_atmosphere) constructor.