package numerics import "math" // NasaDensity returns air density in kg/m^3 at the given altitude in metres, // using the NASA piecewise standard-atmosphere model. // See https://www.grc.nasa.gov/WWW/K-12/airplane/atmosmet.html. // // The model is split into three altitude bands (troposphere, lower // stratosphere, upper stratosphere); density is pressure / (0.2869 * T_K). func NasaDensity(alt float64) float64 { var temp, pressure float64 switch { case alt > 25000: temp = -131.21 + 0.00299*alt pressure = 2.488 * math.Pow((temp+273.1)/216.6, -11.388) case alt > 11000: temp = -56.46 pressure = 22.65 * math.Exp(1.73-0.000157*alt) default: temp = 15.04 - 0.00649*alt pressure = 101.29 * math.Pow((temp+273.1)/288.08, 5.256) } return pressure / (0.2869 * (temp + 273.1)) } // DragTerminalVelocity returns the vertical velocity (m/s, negative = downward) // of a parachute descent at the given altitude. seaLevelRate is the descent // speed at sea level (positive m/s); the rate grows with altitude as the // thinner air provides less drag: // // v = -k / sqrt(rho(alt)), k = seaLevelRate * 1.1045 // // Matches Tawhiri's drag_descent. func DragTerminalVelocity(seaLevelRate, alt float64) float64 { k := seaLevelRate * 1.1045 return -k / math.Sqrt(NasaDensity(alt)) }