pycontrails 0.54.2__cp310-cp310-macosx_11_0_arm64.whl → 0.54.4__cp310-cp310-macosx_11_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pycontrails might be problematic. Click here for more details.
- pycontrails/__init__.py +2 -2
- pycontrails/_version.py +2 -2
- pycontrails/core/__init__.py +1 -1
- pycontrails/core/aircraft_performance.py +75 -61
- pycontrails/core/cache.py +7 -7
- pycontrails/core/fleet.py +25 -21
- pycontrails/core/flight.py +215 -301
- pycontrails/core/interpolation.py +56 -56
- pycontrails/core/met.py +48 -39
- pycontrails/core/models.py +25 -11
- pycontrails/core/polygon.py +15 -15
- pycontrails/core/rgi_cython.cpython-310-darwin.so +0 -0
- pycontrails/core/vector.py +22 -22
- pycontrails/datalib/_met_utils/metsource.py +8 -5
- pycontrails/datalib/ecmwf/__init__.py +14 -14
- pycontrails/datalib/ecmwf/common.py +1 -1
- pycontrails/datalib/ecmwf/era5.py +7 -7
- pycontrails/datalib/ecmwf/hres.py +3 -3
- pycontrails/datalib/ecmwf/ifs.py +1 -1
- pycontrails/datalib/ecmwf/variables.py +1 -0
- pycontrails/datalib/gfs/__init__.py +6 -6
- pycontrails/datalib/gfs/gfs.py +2 -2
- pycontrails/datalib/goes.py +5 -5
- pycontrails/datalib/landsat.py +5 -8
- pycontrails/datalib/sentinel.py +7 -11
- pycontrails/ext/bada.py +3 -2
- pycontrails/ext/empirical_grid.py +1 -1
- pycontrails/ext/synthetic_flight.py +3 -2
- pycontrails/models/accf.py +40 -19
- pycontrails/models/apcemm/apcemm.py +5 -4
- pycontrails/models/cocip/__init__.py +2 -2
- pycontrails/models/cocip/cocip.py +16 -17
- pycontrails/models/cocip/cocip_params.py +2 -11
- pycontrails/models/cocip/cocip_uncertainty.py +24 -18
- pycontrails/models/cocip/contrail_properties.py +331 -316
- pycontrails/models/cocip/output_formats.py +53 -53
- pycontrails/models/cocip/radiative_forcing.py +135 -131
- pycontrails/models/cocip/radiative_heating.py +135 -135
- pycontrails/models/cocip/unterstrasser_wake_vortex.py +90 -87
- pycontrails/models/cocip/wake_vortex.py +92 -92
- pycontrails/models/cocip/wind_shear.py +8 -8
- pycontrails/models/cocipgrid/cocip_grid.py +118 -107
- pycontrails/models/dry_advection.py +59 -58
- pycontrails/models/emissions/__init__.py +2 -2
- pycontrails/models/emissions/black_carbon.py +108 -108
- pycontrails/models/emissions/emissions.py +85 -85
- pycontrails/models/emissions/ffm2.py +35 -35
- pycontrails/models/humidity_scaling/humidity_scaling.py +23 -23
- pycontrails/models/ps_model/__init__.py +3 -2
- pycontrails/models/ps_model/ps_aircraft_params.py +11 -6
- pycontrails/models/ps_model/ps_grid.py +256 -60
- pycontrails/models/ps_model/ps_model.py +18 -21
- pycontrails/models/ps_model/ps_operational_limits.py +58 -69
- pycontrails/models/tau_cirrus.py +8 -1
- pycontrails/physics/geo.py +216 -67
- pycontrails/physics/jet.py +220 -90
- pycontrails/physics/static/iata-cargo-load-factors-20241115.csv +71 -0
- pycontrails/physics/static/iata-passenger-load-factors-20241115.csv +71 -0
- pycontrails/physics/units.py +14 -14
- pycontrails/utils/json.py +1 -2
- pycontrails/utils/types.py +12 -7
- {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/METADATA +10 -10
- {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/NOTICE +1 -1
- pycontrails-0.54.4.dist-info/RECORD +111 -0
- {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/WHEEL +1 -1
- pycontrails-0.54.2.dist-info/RECORD +0 -109
- {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/LICENSE +0 -0
- {pycontrails-0.54.2.dist-info → pycontrails-0.54.4.dist-info}/top_level.txt +0 -0
|
@@ -155,34 +155,34 @@ def max_available_thrust_coefficient(
|
|
|
155
155
|
|
|
156
156
|
|
|
157
157
|
def get_excess_thrust_available(
|
|
158
|
-
mach_number:
|
|
159
|
-
air_temperature:
|
|
160
|
-
air_pressure:
|
|
161
|
-
aircraft_mass:
|
|
162
|
-
theta:
|
|
158
|
+
mach_number: ArrayOrFloat,
|
|
159
|
+
air_temperature: ArrayOrFloat,
|
|
160
|
+
air_pressure: ArrayOrFloat,
|
|
161
|
+
aircraft_mass: ArrayOrFloat,
|
|
162
|
+
theta: ArrayOrFloat,
|
|
163
163
|
atyp_param: PSAircraftEngineParams,
|
|
164
|
-
) ->
|
|
164
|
+
) -> ArrayOrFloat:
|
|
165
165
|
r"""
|
|
166
166
|
Calculate the excess thrust coefficient available at specified operation condition.
|
|
167
167
|
|
|
168
168
|
Parameters
|
|
169
169
|
----------
|
|
170
|
-
mach_number :
|
|
170
|
+
mach_number : ArrayOrFloat
|
|
171
171
|
Mach number at each waypoint
|
|
172
|
-
air_temperature :
|
|
172
|
+
air_temperature : ArrayOrFloat
|
|
173
173
|
Ambient temperature at each waypoint, [:math:`K`]
|
|
174
|
-
air_pressure :
|
|
174
|
+
air_pressure : ArrayOrFloat
|
|
175
175
|
Ambient pressure, [:math:`Pa`]
|
|
176
|
-
aircraft_mass :
|
|
176
|
+
aircraft_mass : ArrayOrFloat
|
|
177
177
|
Aircraft mass at each waypoint, [:math:`kg`]
|
|
178
|
-
theta :
|
|
178
|
+
theta : ArrayOrFloat
|
|
179
179
|
Climb (positive value) or descent (negative value) angle, [:math:`\deg`]
|
|
180
180
|
atyp_param : PSAircraftEngineParams
|
|
181
181
|
Extracted aircraft and engine parameters.
|
|
182
182
|
|
|
183
183
|
Returns
|
|
184
184
|
-------
|
|
185
|
-
|
|
185
|
+
ArrayOrFloat
|
|
186
186
|
The difference between the maximum rated thrust coefficient and the thrust coefficient
|
|
187
187
|
required to maintain the current mach_number.
|
|
188
188
|
"""
|
|
@@ -217,7 +217,7 @@ def get_excess_thrust_available(
|
|
|
217
217
|
)
|
|
218
218
|
|
|
219
219
|
tas = units.mach_number_to_tas(mach_number, air_temperature)
|
|
220
|
-
req_thrust_coeff = required_thrust_coefficient(c_lift, c_drag, tas)
|
|
220
|
+
req_thrust_coeff = required_thrust_coefficient(c_lift, c_drag, tas) # type: ignore[type-var]
|
|
221
221
|
|
|
222
222
|
c_t_eta_b = thrust_coefficient_at_max_efficiency(
|
|
223
223
|
mach_number, atyp_param.m_des, atyp_param.c_t_des
|
|
@@ -226,7 +226,7 @@ def get_excess_thrust_available(
|
|
|
226
226
|
air_temperature, mach_number, c_t_eta_b, atyp_param
|
|
227
227
|
)
|
|
228
228
|
|
|
229
|
-
return max_thrust_coeff - req_thrust_coeff
|
|
229
|
+
return max_thrust_coeff - req_thrust_coeff # type: ignore[return-value]
|
|
230
230
|
|
|
231
231
|
|
|
232
232
|
def _normalised_max_throttle_parameter(
|
|
@@ -350,49 +350,47 @@ def max_usable_lift_coefficient(
|
|
|
350
350
|
|
|
351
351
|
|
|
352
352
|
def minimum_mach_num(
|
|
353
|
-
air_pressure:
|
|
354
|
-
aircraft_mass:
|
|
353
|
+
air_pressure: ArrayOrFloat,
|
|
354
|
+
aircraft_mass: ArrayOrFloat,
|
|
355
355
|
atyp_param: PSAircraftEngineParams,
|
|
356
|
-
) ->
|
|
356
|
+
) -> ArrayOrFloat:
|
|
357
357
|
"""
|
|
358
358
|
Calculate minimum mach number to avoid stall.
|
|
359
359
|
|
|
360
360
|
Parameters
|
|
361
361
|
----------
|
|
362
|
-
air_pressure :
|
|
362
|
+
air_pressure : ArrayOrFloat
|
|
363
363
|
Ambient pressure, [:math:`Pa`]
|
|
364
|
-
aircraft_mass :
|
|
364
|
+
aircraft_mass : ArrayOrFloat
|
|
365
365
|
Aircraft mass at each waypoint, [:math:`kg`]
|
|
366
366
|
atyp_param : PSAircraftEngineParams
|
|
367
367
|
Extracted aircraft and engine parameters.
|
|
368
368
|
|
|
369
369
|
Returns
|
|
370
370
|
-------
|
|
371
|
-
|
|
372
|
-
|
|
371
|
+
ArrayOrFloat
|
|
372
|
+
Minimum mach number to avoid stall.
|
|
373
373
|
"""
|
|
374
374
|
|
|
375
375
|
def excess_mass(
|
|
376
|
-
mach_number:
|
|
377
|
-
air_pressure:
|
|
378
|
-
aircraft_mass:
|
|
376
|
+
mach_number: ArrayOrFloat,
|
|
377
|
+
air_pressure: ArrayOrFloat,
|
|
378
|
+
aircraft_mass: ArrayOrFloat,
|
|
379
379
|
mach_num_des: float,
|
|
380
380
|
c_l_do: float,
|
|
381
381
|
wing_surface_area: float,
|
|
382
|
-
) ->
|
|
382
|
+
) -> ArrayOrFloat:
|
|
383
383
|
amass_max = max_allowable_aircraft_mass(
|
|
384
384
|
air_pressure,
|
|
385
385
|
mach_number,
|
|
386
386
|
mach_num_des,
|
|
387
387
|
c_l_do,
|
|
388
388
|
wing_surface_area,
|
|
389
|
-
1e10,
|
|
389
|
+
1e10, # clipped to this value which we want to ignore
|
|
390
390
|
)
|
|
391
|
-
if amass_max < 0:
|
|
392
|
-
return np.nan
|
|
393
391
|
return amass_max - aircraft_mass
|
|
394
392
|
|
|
395
|
-
m = scipy.optimize.
|
|
393
|
+
m = scipy.optimize.newton(
|
|
396
394
|
excess_mass,
|
|
397
395
|
args=(
|
|
398
396
|
air_pressure,
|
|
@@ -401,21 +399,22 @@ def minimum_mach_num(
|
|
|
401
399
|
atyp_param.c_l_do,
|
|
402
400
|
atyp_param.wing_surface_area,
|
|
403
401
|
),
|
|
404
|
-
x0=0.
|
|
405
|
-
x1=0.
|
|
406
|
-
|
|
402
|
+
x0=np.full_like(air_pressure, 0.4),
|
|
403
|
+
x1=np.full_like(air_pressure, 0.5),
|
|
404
|
+
tol=1e-4,
|
|
405
|
+
)
|
|
407
406
|
|
|
408
407
|
return m
|
|
409
408
|
|
|
410
409
|
|
|
411
410
|
def maximum_mach_num(
|
|
412
|
-
altitude_ft:
|
|
413
|
-
air_pressure:
|
|
414
|
-
aircraft_mass:
|
|
415
|
-
air_temperature:
|
|
416
|
-
theta:
|
|
411
|
+
altitude_ft: ArrayOrFloat,
|
|
412
|
+
air_pressure: ArrayOrFloat,
|
|
413
|
+
aircraft_mass: ArrayOrFloat,
|
|
414
|
+
air_temperature: ArrayOrFloat,
|
|
415
|
+
theta: ArrayOrFloat,
|
|
417
416
|
atyp_param: PSAircraftEngineParams,
|
|
418
|
-
) ->
|
|
417
|
+
) -> ArrayOrFloat:
|
|
419
418
|
r"""
|
|
420
419
|
Return the maximum mach number at the current operating conditions.
|
|
421
420
|
|
|
@@ -424,23 +423,23 @@ def maximum_mach_num(
|
|
|
424
423
|
|
|
425
424
|
Parameters
|
|
426
425
|
----------
|
|
427
|
-
altitude_ft :
|
|
426
|
+
altitude_ft : ArrayOrFloat
|
|
428
427
|
Altitude, [:math:`ft`]
|
|
429
|
-
air_pressure :
|
|
428
|
+
air_pressure : ArrayOrFloat
|
|
430
429
|
Ambient pressure, [:math:`Pa`]
|
|
431
|
-
aircraft_mass :
|
|
430
|
+
aircraft_mass : ArrayOrFloat
|
|
432
431
|
Aircraft mass at each waypoint, [:math:`kg`]
|
|
433
|
-
air_temperature :
|
|
432
|
+
air_temperature : ArrayOrFloat
|
|
434
433
|
Array of ambient temperature, [:math: `K`]
|
|
435
|
-
theta :
|
|
434
|
+
theta : ArrayOrFloat
|
|
436
435
|
Climb (positive value) or descent (negative value) angle, [:math:`\deg`]
|
|
437
436
|
atyp_param : PSAircraftEngineParams
|
|
438
437
|
Extracted aircraft and engine parameters.
|
|
439
438
|
|
|
440
439
|
Returns
|
|
441
440
|
-------
|
|
442
|
-
|
|
443
|
-
Maximum
|
|
441
|
+
ArrayOrFloat
|
|
442
|
+
Maximum mach number given thrust limiations.
|
|
444
443
|
"""
|
|
445
444
|
# Max speed ignoring thrust limits
|
|
446
445
|
mach_num_op_lim = max_mach_number_by_altitude(
|
|
@@ -451,27 +450,15 @@ def maximum_mach_num(
|
|
|
451
450
|
atyp_param.p_inf_co,
|
|
452
451
|
)
|
|
453
452
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
)
|
|
461
|
-
return mach_num_op_lim
|
|
462
|
-
|
|
463
|
-
# Numerically solve for the speed where drag == max thrust
|
|
464
|
-
try:
|
|
465
|
-
m_max = scipy.optimize.root_scalar(
|
|
466
|
-
get_excess_thrust_available,
|
|
467
|
-
args=(air_temperature, air_pressure, aircraft_mass, theta, atyp_param),
|
|
468
|
-
x0=mach_num_op_lim,
|
|
469
|
-
x1=mach_num_op_lim - 0.05,
|
|
470
|
-
).root
|
|
471
|
-
except ValueError:
|
|
472
|
-
return np.nan
|
|
453
|
+
max_mach = scipy.optimize.newton(
|
|
454
|
+
func=get_excess_thrust_available,
|
|
455
|
+
args=(air_temperature, air_pressure, aircraft_mass, theta, atyp_param),
|
|
456
|
+
x0=mach_num_op_lim,
|
|
457
|
+
x1=mach_num_op_lim - 0.01,
|
|
458
|
+
tol=1e-4,
|
|
459
|
+
).clip(max=mach_num_op_lim)
|
|
473
460
|
|
|
474
|
-
return
|
|
461
|
+
return max_mach
|
|
475
462
|
|
|
476
463
|
|
|
477
464
|
# ----------------
|
|
@@ -479,7 +466,9 @@ def maximum_mach_num(
|
|
|
479
466
|
# ----------------
|
|
480
467
|
|
|
481
468
|
|
|
482
|
-
def fuel_flow_idle(
|
|
469
|
+
def fuel_flow_idle(
|
|
470
|
+
fuel_flow_idle_sls: float, altitude_ft: ArrayOrFloat
|
|
471
|
+
) -> npt.NDArray[np.floating]:
|
|
483
472
|
r"""Calculate minimum fuel mass flow rate at flight idle conditions.
|
|
484
473
|
|
|
485
474
|
Parameters
|
|
@@ -491,7 +480,7 @@ def fuel_flow_idle(fuel_flow_idle_sls: float, altitude_ft: ArrayOrFloat) -> npt.
|
|
|
491
480
|
|
|
492
481
|
Returns
|
|
493
482
|
-------
|
|
494
|
-
npt.NDArray[np.
|
|
483
|
+
npt.NDArray[np.floating]
|
|
495
484
|
Fuel mass flow rate at flight idle conditions, [:math:`kg \ s^{-1}`]
|
|
496
485
|
"""
|
|
497
486
|
x = altitude_ft / 10000.0
|
|
@@ -504,7 +493,7 @@ def max_fuel_flow(
|
|
|
504
493
|
mach_number: ArrayOrFloat,
|
|
505
494
|
fuel_flow_max_sls: float,
|
|
506
495
|
flight_phase: npt.NDArray[np.uint8] | flight.FlightPhase,
|
|
507
|
-
) -> npt.NDArray[np.
|
|
496
|
+
) -> npt.NDArray[np.floating]:
|
|
508
497
|
r"""Correct maximum fuel mass flow rate that can be supplied by the engine.
|
|
509
498
|
|
|
510
499
|
Parameters
|
|
@@ -522,7 +511,7 @@ def max_fuel_flow(
|
|
|
522
511
|
|
|
523
512
|
Returns
|
|
524
513
|
-------
|
|
525
|
-
npt.NDArray[np.
|
|
514
|
+
npt.NDArray[np.floating]
|
|
526
515
|
Maximum allowable fuel mass flow rate, [:math:`kg \ s^{-1}`]
|
|
527
516
|
"""
|
|
528
517
|
ff_max = jet.equivalent_fuel_flow_rate_at_cruise(
|
pycontrails/models/tau_cirrus.py
CHANGED
|
@@ -80,7 +80,14 @@ def tau_cirrus(met: MetDataset) -> xr.DataArray:
|
|
|
80
80
|
met.data["air_pressure"],
|
|
81
81
|
)
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
# dask.array.gradient expects at least 2 elements in each chunk
|
|
84
|
+
level_axis = geopotential_height.get_axis_num("level")
|
|
85
|
+
if geopotential_height.chunks:
|
|
86
|
+
level_chunks = geopotential_height.chunks[level_axis] # type: ignore[call-overload, index]
|
|
87
|
+
if any(chunk < 2 for chunk in level_chunks):
|
|
88
|
+
geopotential_height = geopotential_height.chunk(level=-1)
|
|
89
|
+
|
|
90
|
+
dz = -dask.array.gradient(geopotential_height, axis=level_axis)
|
|
84
91
|
dz = xr.DataArray(dz, dims=geopotential_height.dims)
|
|
85
92
|
|
|
86
93
|
da = beta_e * dz
|