Skip to content

Physics

jetfuelburn.utility.physics

_calculate_airspeed_from_mach

_calculate_airspeed_from_mach(mach_number, altitude)

Converts aircraft speed from mach number \(M\) to airspeed \(V\), depending on the flight altitude \(h\).

\[ V = M \sqrt{\gamma R T(h)} \]

where:

Symbol Dimension Value Description
\(V\) [speed] variable aircraft speed
\(M\) [dimensionless] variable Mach number
\(\gamma\) [dimensionless] 1.4 ratio of specific heat (air)
\(R\) (complicated) 287 J/(kg*K) specific gas constant for air

Parameters:

Name Type Description Default
mach_number float[dimensionless]

Mach number

required
altitude float[length]

Flight altitude above sea level

required

Returns:

Type Description
Quantity(float)[speed]

Aircraft velocity (km/h).

See Also

Mach Number entry on Wikipedia

References

Eqn.(1.33)-(1.34) Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . CRC Press. doi:10.1201/9781003279068

Returns:

Type Description
Quantity(float)[speed]

Aircraft velocity in kilometers per hour.

Example

Editor (session: default)Run
import jetfuelburn
from jetfuelburn import ureg
from jetfuelburn.utility.physics import _calculate_airspeed_from_mach
_calculate_airspeed_from_mach(
    mach_number=0.8,
    altitude=10000*ureg.m
)
OutputClear

Source code in jetfuelburn/utility/physics.py
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
@ureg.check(
    "[]",
    "[length]",
)
def _calculate_airspeed_from_mach(
    mach_number: float,
    altitude: float,
) -> pint.Quantity:
    r"""
    Converts aircraft speed from mach number $M$ to airspeed $V$,
    depending on the flight altitude $h$.

    $$
        V = M \sqrt{\gamma R T(h)}
    $$

    where:

    | Symbol   | Dimension       | Value           | Description                   |
    |----------|-----------------|-----------------|-------------------------------|
    | $V$      | [speed]         | variable        | aircraft speed                |
    | $M$      | [dimensionless] | variable        | Mach number                   |
    | $\gamma$ | [dimensionless] | 1.4             | ratio of specific heat (air)  |
    | $R$      | (complicated)   | 287 J/(kg*K)    | specific gas constant for air |

    Parameters
    ----------
    mach_number : float [dimensionless]
        Mach number
    altitude : float [length]
        Flight altitude above sea level

    Returns
    -------
    ureg.Quantity (float) [speed]
        Aircraft velocity (km/h).

    See Also
    --------
    [Mach Number entry on Wikipedia](https://en.wikipedia.org/wiki/Mach_number#Calculation)

    References
    ----------
    Eqn.(1.33)-(1.34) Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . _CRC Press_. doi:[10.1201/9781003279068](https://doi.org/10.1201/9781003279068)

    Returns
    -------
    ureg.Quantity (float) [speed]
        Aircraft velocity in kilometers per hour.

    Example
    -------
    ```pyodide install='jetfuelburn'
    import jetfuelburn
    from jetfuelburn import ureg
    from jetfuelburn.utility.physics import _calculate_airspeed_from_mach
    _calculate_airspeed_from_mach(
        mach_number=0.8,
        altitude=10000*ureg.m
    )
    ```
    """
    temperature = _calculate_atmospheric_temperature(altitude)

    R = 287.052874 * (ureg.J / (ureg.kg * ureg.K))  # specific gas constant for air
    gamma = 1.4 * ureg.dimensionless  # ratio of specific heat for air
    velocity = mach_number * (gamma * R * temperature.to(ureg.K)) ** 0.5

    return velocity.to(ureg.kph)

_calculate_atmospheric_density

_calculate_atmospheric_density(altitude)

Computes the air density as a function of altitude up to 20,000 meters based on the International Standard Atmosphere (ISA):

Density in the Troposphere (<= 11,000 m) is calculated according to

\[ \rho = \rho_0 \left( \frac{T}{T_0} \right)^{\frac{-g}{L R} - 1} \]

Temperature in the lower Stratosphere (> 11,000 m) is calculated according to

\[ \rho = \rho_1 e^{\frac{-g M (h - h_1)}{R T_s}} \]

where:

Symbol Dimension Description Value
\(\rho\) [mass/volume] air density at altitude \(h\) N/A
\(\rho_0\) [mass/volume] air density at sea level 1.225 kg/m³
\(\rho_1\) [mass/volume] air density at tropopause (11,000 m) 0.36391 kg/m³
\(T\) [temperature] temperature at altitude \(h\) N/A
\(T_0\) [temperature] temperature at sea level 288.15 K
\(T_s\) [temperature] constant temperature in lower Stratosphere 216.65 K
\(h\) [length] altitude above sea level variable
\(h_1\) [length] altitude at tropopause 11,000 m
\(g\) [length/time²] acceleration due to gravity 9.80665 m/s²
\(L\) [temperature/length] temperature lapse rate (Troposphere) 0.0065 K/m
\(R\) [energy/(mass*temperature)] specific gas constant for air 287.052874 J/(kg·K)
\(M\) [mass/mole] molar mass of dry air 0.0289644 kg/mol
References
  • Troposphere: Eqn. (4.14) in Young, T. M. (2018). Performance of the Jet Transport Airplane. John Wiley & Sons. doi:10.1002/9781118534786
  • Stratosphere: Eqn. (4.16) in Young, T. M. (2018). Performance of the Jet Transport Airplane. John Wiley & Sons. doi:10.1002/9781118534786

Parameters:

Name Type Description Default
altitude Quantity[length]

Altitude above sea level (0 to 20,000 meters).

required

Returns:

Type Description
Quantity(float)[mass / volume]

Air density (kg/m³).

Raises:

Type Description
ValueError

If altitude is less than 0 m or greater than 20,000 m.

Example

Editor (session: default)Run
import jetfuelburn
from jetfuelburn import ureg
from jetfuelburn.utility.physics import _calculate_atmospheric_density
_calculate_atmospheric_density(altitude=10000*ureg.m)
OutputClear

Source code in jetfuelburn/utility/physics.py
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
@ureg.check("[length]")
def _calculate_atmospheric_density(
    altitude,
) -> pint.Quantity:
    r"""
    Computes the air density as a function of altitude up to 20,000 meters
    based on the International Standard Atmosphere (ISA):

    <img src="https://upload.wikimedia.org/wikipedia/commons/a/a8/International_Standard_Atmosphere.svg" width="250" />

    Density in the Troposphere (<= 11,000 m) is calculated according to

    $$
    \rho = \rho_0 \left( \frac{T}{T_0} \right)^{\frac{-g}{L R} - 1}
    $$

    Temperature in the lower Stratosphere (> 11,000 m) is calculated according to

    $$
    \rho = \rho_1 e^{\frac{-g M (h - h_1)}{R T_s}}
    $$

    where:

    | Symbol  | Dimension                   | Description                                | Value                |
    |---------|-----------------------------|--------------------------------------------|----------------------|
    | $\rho$  | [mass/volume]               | air density at altitude $h$                | N/A                  |
    | $\rho_0$| [mass/volume]               | air density at sea level                   | 1.225 kg/m³          |
    | $\rho_1$| [mass/volume]               | air density at tropopause (11,000 m)       | 0.36391 kg/m³        |
    | $T$     | [temperature]               | temperature at altitude $h$                | N/A                  |
    | $T_0$   | [temperature]               | temperature at sea level                   | 288.15 K             |
    | $T_s$   | [temperature]               | constant temperature in lower Stratosphere | 216.65 K             |
    | $h$     | [length]                    | altitude above sea level                   | variable             |
    | $h_1$   | [length]                    | altitude at tropopause                     | 11,000 m             |
    | $g$     | [length/time²]              | acceleration due to gravity                | 9.80665 m/s²         |
    | $L$     | [temperature/length]        | temperature lapse rate (Troposphere)       | 0.0065 K/m           |
    | $R$     | [energy/(mass*temperature)] | specific gas constant for air              | 287.052874 J/(kg·K)  |
    | $M$     | [mass/mole]                 | molar mass of dry air                      | 0.0289644 kg/mol     |

    References
    ----------
    - Troposphere: Eqn. (4.14) in Young, T. M. (2018). Performance of the Jet Transport Airplane. _John Wiley & Sons_. doi:[10.1002/9781118534786](https://doi.org/10.1002/9781118534786)
    - Stratosphere: Eqn. (4.16) in Young, T. M. (2018). Performance of the Jet Transport Airplane. _John Wiley & Sons_. doi:[10.1002/9781118534786](https://doi.org/10.1002/9781118534786)

    Parameters
    ----------
    altitude : Quantity [length]
        Altitude above sea level (0 to 20,000 meters).

    Returns
    -------
    ureg.Quantity (float) [mass/volume]
        Air density (kg/m³).

    Raises
    ------
    ValueError
        If altitude is less than 0 m or greater than 20,000 m.

    Example
    -------
    ```pyodide install='jetfuelburn'
    import jetfuelburn
    from jetfuelburn import ureg
    from jetfuelburn.utility.physics import _calculate_atmospheric_density
    _calculate_atmospheric_density(altitude=10000*ureg.m)
    ```
    """
    if altitude < 0 * ureg.m:
        raise ValueError("Altitude must not be < 0.")
    elif altitude > 20000 * ureg.m:
        raise ValueError("Altitude must not be > 20000 m.")

    rho_0 = 1.225 * (ureg.kg / ureg.m**3)  # Sea-level density
    rho_1 = 0.36391 * (ureg.kg / ureg.m**3)  # Density at 11,000 m (Tropopause)
    g = 9.80665 * (ureg.m / ureg.s**2)  # Gravity
    R = 8.3144598 * ((ureg.N * ureg.m) / (ureg.mol * ureg.K))  # Universal gas constant
    M = 0.0289644 * (ureg.kg / ureg.mol)  # Molar mass of dry air
    temperature_0 = 288.15 * ureg.K  # Sea-level standard temperature
    lapse_rate = 0.0065 * (ureg.K / ureg.m)  # Temperature lapse rate
    temperature_stratosphere = (
        216.65 * ureg.K
    )  # Constant temperature in the lower Stratosphere

    if altitude <= 11000 * ureg.m:
        current_temp = _calculate_atmospheric_temperature(altitude).to(ureg.K)
        exponent = (g * M / (R * lapse_rate)) - 1
        rho = rho_0 * (current_temp / temperature_0) ** exponent
    else:
        # This part was already correct
        rho = rho_1 * math.exp(
            -g * M * (altitude - 11000 * ureg.m) / (R * temperature_stratosphere)
        )

    return rho.to(ureg.kg / ureg.m**3)

_calculate_atmospheric_temperature

_calculate_atmospheric_temperature(altitude)

Computes the air temperature as a function of altitude up to 20,000 meters based on the International Standard Atmosphere (ISA):

Temperature in the Troposphere (<= 11,000 m) is calculated according to

\[ T = T_0 - L \cdot h \]

where:

Symbol Dimension Description Value
\(T\) [temperature] temperature at altitude \(h\) N/A
\(T_0\) [temperature] temperature at sea level 288.15 K
\(L\) [temperature/length] temperature lapse rate (Troposphere) 0.0065 K/m

Temperature in the lower Stratosphere (> 11,000 m) is assumed constant at -56.5°C (216.65 K).

References

Eqn.(1.6) in Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . CRC Press. doi:10.1201/9781003279068

Parameters:

Name Type Description Default
altitude Quantity[length]

Altitude above sea level (0 to 20,000 meters).

required

Returns:

Type Description
Quantity(float)[temperature]

Air temperature (°C).

Raises:

Type Description
ValueError

If altitude is less than 0 m or greater than 20,000 m.

Example

Editor (session: default)Run
import jetfuelburn
from jetfuelburn import ureg
from jetfuelburn.utility.physics import _calculate_atmospheric_temperature
_calculate_atmospheric_temperature(altitude=10000*ureg.m)
OutputClear

Source code in jetfuelburn/utility/physics.py
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@ureg.check("[length]")
def _calculate_atmospheric_temperature(
    altitude,
) -> pint.Quantity:
    r"""
    Computes the air temperature as a function of altitude up to 20,000 meters
    based on the International Standard Atmosphere (ISA):

    <img src="https://upload.wikimedia.org/wikipedia/commons/a/a8/International_Standard_Atmosphere.svg" width="250" />

    Temperature in the Troposphere (<= 11,000 m) is calculated according to

    $$
    T = T_0 - L \cdot h
    $$

    where:

    | Symbol | Dimension             | Description                         | Value        |
    |--------|-----------------------|-------------------------------------|--------------|
    | $T$    | [temperature]         | temperature at altitude $h$         | N/A          |
    | $T_0$  | [temperature]         | temperature at sea level            | 288.15 K     |
    | $L$    | [temperature/length]  | temperature lapse rate (Troposphere)| 0.0065 K/m   |

    Temperature in the lower Stratosphere (> 11,000 m) is assumed constant at -56.5°C (216.65 K).

    References
    ----------
    Eqn.(1.6) in Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . _CRC Press_. doi:[10.1201/9781003279068](https://doi.org/10.1201/9781003279068)

    Parameters
    ----------
    altitude : Quantity [length]
        Altitude above sea level (0 to 20,000 meters).

    Returns
    -------
    ureg.Quantity (float) [temperature]
        Air temperature (°C).

    Raises
    ------
    ValueError
        If altitude is less than 0 m or greater than 20,000 m.

    Example
    -------
    ```pyodide install='jetfuelburn'
    import jetfuelburn
    from jetfuelburn import ureg
    from jetfuelburn.utility.physics import _calculate_atmospheric_temperature
    _calculate_atmospheric_temperature(altitude=10000*ureg.m)
    ```
    """
    if altitude < 0 * ureg.m:
        raise ValueError("Altitude must not be < 0.")
    elif altitude > 20000 * ureg.m:
        raise ValueError("Altitude must not be > 20000 m.")

    temperature_0 = 288.15 * ureg.K  # Sea-level standard temperature
    lapse_rate = 0.0065 * (ureg.K / ureg.m)  # Temperature lapse rate
    temperature_stratosphere = 216.65 * ureg.K  # Constant temp in lower stratosphere

    if altitude <= 11000 * ureg.m:
        temperature = temperature_0 - lapse_rate * altitude
    else:
        temperature = temperature_stratosphere

    return temperature.to(ureg.celsius)

_calculate_dynamic_pressure

_calculate_dynamic_pressure(speed, altitude)

Computes the dynamic pressure \(q\) at a given speed and altitude.

\[ q = \frac{1}{2} \rho V^2 \]

where:

Symbol Dimension Description
\(q\) [pressure] dynamic pressure
\(\rho\) [mass/volume] air density
\(V\) [speed] aircraft speed
See Also

Dynamic Pressure entry on Wikipedia

References

Eqn. (2.63) in in Young, T. M. (2018). Performance of the Jet Transport Airplane. John Wiley & Sons. doi:10.1002/9781118534786

Parameters:

Name Type Description Default
speed float

Aircraft speed [speed]

required
altitude float

Aircraft altitude above sea level [distance]

required

Returns:

Type Description
Quantity(float)[pressure]

Dynamic pressure (Pascals).

Example

Editor (session: default)Run
import jetfuelburn
from jetfuelburn import ureg
from jetfuelburn.utility.physics import _calculate_dynamic_pressure
_calculate_dynamic_pressure(
    speed=833*ureg.kph,
    altitude=10000*ureg.m
)
OutputClear

Source code in jetfuelburn/utility/physics.py
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
@ureg.check(
    "[speed]",
    "[length]",
)
def _calculate_dynamic_pressure(
    speed: float,
    altitude: float,
) -> pint.Quantity:
    r"""
    Computes the dynamic pressure $q$ at a given speed and altitude.

    $$
    q = \frac{1}{2} \rho V^2
    $$

    where:

    | Symbol | Dimension       | Description         |
    |--------|-----------------|---------------------|
    | $q$    | [pressure]      | dynamic pressure    |
    | $\rho$ | [mass/volume]   | air density         |
    | $V$    | [speed]         | aircraft speed      |


    See Also
    --------
    [Dynamic Pressure entry on Wikipedia](https://en.wikipedia.org/wiki/Dynamic_pressure)

    References
    --------
    Eqn. (2.63) in in Young, T. M. (2018). Performance of the Jet Transport Airplane. _John Wiley & Sons_. doi:[10.1002/9781118534786](https://doi.org/10.1002/9781118534786)

    Parameters
    ----------
    speed : float
        Aircraft speed [speed]
    altitude : float
        Aircraft altitude above sea level [distance]

    Returns
    -------
    ureg.Quantity (float) [pressure]
        Dynamic pressure (Pascals).

    Example
    -------
    ```pyodide install='jetfuelburn'
    import jetfuelburn
    from jetfuelburn import ureg
    from jetfuelburn.utility.physics import _calculate_dynamic_pressure
    _calculate_dynamic_pressure(
        speed=833*ureg.kph,
        altitude=10000*ureg.m
    )
    ```
    """
    air_density = _calculate_atmospheric_density(altitude)
    dynamic_pressure = 0.5 * air_density * speed**2
    return dynamic_pressure.to(ureg.Pa)

_calculate_mach_from_airspeed

_calculate_mach_from_airspeed(airspeed, altitude)

Converts aircraft airspeed \(V\) to Mach number \(M\), depending on the flight altitude \(h\).

\[ M = \frac{V}{\sqrt{\gamma R T(h)}} \]

where:

Symbol Dimension Value Description
\(M\) [dimensionless] variable Mach number
\(V\) [speed] variable aircraft speed
\(\gamma\) [dimensionless] 1.4 ratio of specific heat (air)
\(R\) (complicated) 287 J/(kg*K) specific gas constant for air

Parameters:

Name Type Description Default
airspeed float[speed]

Aircraft true airspeed (TAS).

required
altitude float[length]

Flight altitude above sea level.

required

Returns:

Type Description
Quantity(float)[dimensionless]

Mach number.

See Also

Mach Number entry on Wikipedia

References

Eqn.(1.33)-(1.34) Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . CRC Press. doi:10.1201/9781003279068

Example

Editor (session: default)Run
import jetfuelburn
from jetfuelburn import ureg
from jetfuelburn.utility.physics import _calculate_mach_from_airspeed
_calculate_mach_from_airspeed(
    airspeed=850*ureg.kph,
    altitude=10000*ureg.m
)
OutputClear

Source code in jetfuelburn/utility/physics.py
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
@ureg.check(
    "[speed]",
    "[length]",
)
def _calculate_mach_from_airspeed(
    airspeed: float,
    altitude: float,
) -> float:
    r"""
    Converts aircraft airspeed $V$ to Mach number $M$,
    depending on the flight altitude $h$.

    $$
        M = \frac{V}{\sqrt{\gamma R T(h)}}
    $$

    where:

    | Symbol   | Dimension       | Value           | Description                   |
    |----------|-----------------|-----------------|-------------------------------|
    | $M$      | [dimensionless] | variable        | Mach number                   |
    | $V$      | [speed]         | variable        | aircraft speed                |
    | $\gamma$ | [dimensionless] | 1.4             | ratio of specific heat (air)  |
    | $R$      | (complicated)   | 287 J/(kg*K)    | specific gas constant for air |

    Parameters
    ----------
    airspeed : float [speed]
        Aircraft true airspeed (TAS).
    altitude : float [length]
        Flight altitude above sea level.

    Returns
    -------
    ureg.Quantity (float) [dimensionless]
        Mach number.

    See Also
    --------
    [Mach Number entry on Wikipedia](https://en.wikipedia.org/wiki/Mach_number#Calculation)

    References
    ----------
    Eqn.(1.33)-(1.34) Sadraey, M. H. (2017). Aircraft Performance: An Engineering Approach . _CRC Press_. doi:[10.1201/9781003279068](https://doi.org/10.1201/9781003279068)

    Example
    -------
    ```pyodide install='jetfuelburn'
    import jetfuelburn
    from jetfuelburn import ureg
    from jetfuelburn.utility.physics import _calculate_mach_from_airspeed
    _calculate_mach_from_airspeed(
        airspeed=850*ureg.kph,
        altitude=10000*ureg.m
    )
    ```
    """
    temperature = _calculate_atmospheric_temperature(altitude)

    R = 287.052874 * (ureg.J / (ureg.kg * ureg.K))  # specific gas constant for air
    gamma = 1.4 * ureg.dimensionless  # ratio of specific heat for air

    # Calculate the speed of sound at the given altitude
    speed_of_sound = (gamma * R * temperature.to(ureg.K)) ** 0.5

    mach_number = airspeed / speed_of_sound

    return mach_number.to(ureg.dimensionless)

_calculate_speed_of_sound

_calculate_speed_of_sound(temperature)

Computes the speed of sound in air as a function of temperature uses the relationship for an ideal gas:

\[ a = a_0 \sqrt{\frac{T}{T_0}} \]

Or equivalently:

\[ a = \sqrt{\gamma R T} \]

where:

Symbol Dimension Description Value
\(a\) [velocity] speed of sound N/A
\(a_0\) [velocity] speed of sound at sea level 340.29 m/s
\(T\) [temperature] local air temperature N/A
\(T_0\) [temperature] standard sea level temp 288.15 K
\(\gamma\) [dimensionless] ratio of specific heats 1.40
\(R\) [energy/(mass*temp)] gas constant 287.05 m²/(s²K)
See Also

jetfuelburn.utility.physics._calculate_atmospheric_temperature

References

Eqn. (2.77) in Young, T. M. (2018). Performance of the Jet Transport Airplane. John Wiley & Sons. doi:10.1002/9781118534786

Parameters:

Name Type Description Default
temperature Quantity[temperature]

The local air temperature.

required

Returns:

Type Description
Quantity(float)[velocity]

Speed of sound (km/h).

Raises:

Type Description
ValueError

If temperature is below absolute zero.

Source code in jetfuelburn/utility/physics.py
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
@ureg.check("[temperature]")
def _calculate_speed_of_sound(
    temperature,
):
    r"""
    Computes the speed of sound in air as a function of temperature uses the relationship for an ideal gas:

    $$
    a = a_0 \sqrt{\frac{T}{T_0}}
    $$

    Or equivalently:

    $$
    a = \sqrt{\gamma R T}
    $$

    where:

    | Symbol   | Dimension                | Description                     | Value             |
    |----------|--------------------------|---------------------------------|-------------------|
    | $a$      | [velocity]               | speed of sound                  | N/A               |
    | $a_0$    | [velocity]               | speed of sound at sea level     | 340.29 m/s        |
    | $T$      | [temperature]            | local air temperature           | N/A               |
    | $T_0$    | [temperature]            | standard sea level temp         | 288.15 K          |
    | $\gamma$ | [dimensionless]          | ratio of specific heats         | 1.40              |
    | $R$      | [energy/(mass*temp)]     | gas constant                    | 287.05 m²/(s²K)   |

    See Also
    --------
    [`jetfuelburn.utility.physics._calculate_atmospheric_temperature`][]

    References
    ----------
    Eqn. (2.77) in Young, T. M. (2018). Performance of the Jet Transport Airplane. _John Wiley & Sons_. doi:[10.1002/9781118534786](https://doi.org/10.1002/9781118534786)

    Parameters
    ----------
    temperature : Quantity [temperature]
        The local air temperature.

    Returns
    -------
    ureg.Quantity (float) [velocity]
        Speed of sound (km/h).

    Raises
    ------
    ValueError
        If temperature is below absolute zero.
    """
    T_val = temperature.to(ureg.kelvin)
    if T_val.magnitude < 0:
        raise ValueError(
            "Temperature must be above absolute zero. If you really did manage to measure a temperature below absolute zero, please contact the JetFuelBurn developers."
        )

    a0 = 661.479 * ureg.knot  # Standard speed of sound at sea level
    T0 = 288.15 * ureg.kelvin  # Standard sea level temperature

    speed_of_sound = a0 * math.sqrt((T_val / T0).magnitude)

    return speed_of_sound.to(ureg.kph)