pycontrails 0.54.2__cp313-cp313-macosx_11_0_arm64.whl → 0.54.4__cp313-cp313-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-313-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
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import logging
|
|
6
|
-
from typing import Any,
|
|
6
|
+
from typing import Any, overload
|
|
7
7
|
|
|
8
8
|
import numpy as np
|
|
9
9
|
import numpy.typing as npt
|
|
@@ -19,14 +19,14 @@ logger = logging.getLogger(__name__)
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def initial_iwc(
|
|
22
|
-
air_temperature: npt.NDArray[np.
|
|
23
|
-
specific_humidity: npt.NDArray[np.
|
|
24
|
-
air_pressure: npt.NDArray[np.
|
|
25
|
-
fuel_dist: npt.NDArray[np.
|
|
26
|
-
width: npt.NDArray[np.
|
|
27
|
-
depth: npt.NDArray[np.
|
|
22
|
+
air_temperature: npt.NDArray[np.floating],
|
|
23
|
+
specific_humidity: npt.NDArray[np.floating],
|
|
24
|
+
air_pressure: npt.NDArray[np.floating],
|
|
25
|
+
fuel_dist: npt.NDArray[np.floating],
|
|
26
|
+
width: npt.NDArray[np.floating],
|
|
27
|
+
depth: npt.NDArray[np.floating],
|
|
28
28
|
ei_h2o: float,
|
|
29
|
-
) -> npt.NDArray[np.
|
|
29
|
+
) -> npt.NDArray[np.floating]:
|
|
30
30
|
r"""
|
|
31
31
|
Estimate the initial contrail ice water content (iwc) before the wake vortex phase.
|
|
32
32
|
|
|
@@ -35,24 +35,24 @@ def initial_iwc(
|
|
|
35
35
|
|
|
36
36
|
Parameters
|
|
37
37
|
----------
|
|
38
|
-
air_temperature : npt.NDArray[np.
|
|
38
|
+
air_temperature : npt.NDArray[np.floating]
|
|
39
39
|
ambient temperature for each waypoint, [:math:`K`]
|
|
40
|
-
specific_humidity : npt.NDArray[np.
|
|
40
|
+
specific_humidity : npt.NDArray[np.floating]
|
|
41
41
|
ambient specific humidity for each waypoint, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
42
|
-
air_pressure : npt.NDArray[np.
|
|
42
|
+
air_pressure : npt.NDArray[np.floating]
|
|
43
43
|
initial pressure altitude at each waypoint, before the wake vortex phase, [:math:`Pa`]
|
|
44
|
-
fuel_dist : npt.NDArray[np.
|
|
44
|
+
fuel_dist : npt.NDArray[np.floating]
|
|
45
45
|
fuel consumption of the flight segment per distance traveled, [:math:`kg m^{-1}`]
|
|
46
|
-
width : npt.NDArray[np.
|
|
46
|
+
width : npt.NDArray[np.floating]
|
|
47
47
|
initial contrail width, [:math:`m`]
|
|
48
|
-
depth : npt.NDArray[np.
|
|
48
|
+
depth : npt.NDArray[np.floating]
|
|
49
49
|
initial contrail depth, [:math:`m`]
|
|
50
50
|
ei_h2o : float
|
|
51
51
|
water vapor emissions index of fuel, [:math:`kg_{H_{2}O} \ kg_{fuel}^{-1}`]
|
|
52
52
|
|
|
53
53
|
Returns
|
|
54
54
|
-------
|
|
55
|
-
npt.NDArray[np.
|
|
55
|
+
npt.NDArray[np.floating]
|
|
56
56
|
Initial contrail ice water content (iwc) at the original waypoint
|
|
57
57
|
before the wake vortex phase, [:math:`kg_{H_{2}O}/kg_{air}`].
|
|
58
58
|
Returns zero if iwc is is negative (dry air).
|
|
@@ -63,34 +63,34 @@ def initial_iwc(
|
|
|
63
63
|
|
|
64
64
|
|
|
65
65
|
def q_exhaust(
|
|
66
|
-
air_temperature: npt.NDArray[np.
|
|
67
|
-
air_pressure: npt.NDArray[np.
|
|
68
|
-
fuel_dist: npt.NDArray[np.
|
|
69
|
-
width: npt.NDArray[np.
|
|
70
|
-
depth: npt.NDArray[np.
|
|
66
|
+
air_temperature: npt.NDArray[np.floating],
|
|
67
|
+
air_pressure: npt.NDArray[np.floating],
|
|
68
|
+
fuel_dist: npt.NDArray[np.floating],
|
|
69
|
+
width: npt.NDArray[np.floating],
|
|
70
|
+
depth: npt.NDArray[np.floating],
|
|
71
71
|
ei_h2o: float,
|
|
72
|
-
) -> npt.NDArray[np.
|
|
72
|
+
) -> npt.NDArray[np.floating]:
|
|
73
73
|
r"""
|
|
74
74
|
Calculate the specific humidity released by water vapor from aircraft emissions.
|
|
75
75
|
|
|
76
76
|
Parameters
|
|
77
77
|
----------
|
|
78
|
-
air_temperature : npt.NDArray[np.
|
|
78
|
+
air_temperature : npt.NDArray[np.floating]
|
|
79
79
|
ambient temperature for each waypoint, [:math:`K`]
|
|
80
|
-
air_pressure : npt.NDArray[np.
|
|
80
|
+
air_pressure : npt.NDArray[np.floating]
|
|
81
81
|
initial pressure altitude at each waypoint, before the wake vortex phase, [:math:`Pa`]
|
|
82
|
-
fuel_dist : npt.NDArray[np.
|
|
82
|
+
fuel_dist : npt.NDArray[np.floating]
|
|
83
83
|
fuel consumption of the flight segment per distance travelled, [:math:`kg m^{-1}`]
|
|
84
|
-
width : npt.NDArray[np.
|
|
84
|
+
width : npt.NDArray[np.floating]
|
|
85
85
|
initial contrail width, [:math:`m`]
|
|
86
|
-
depth : npt.NDArray[np.
|
|
86
|
+
depth : npt.NDArray[np.floating]
|
|
87
87
|
initial contrail depth, [:math:`m`]
|
|
88
88
|
ei_h2o : float
|
|
89
89
|
water vapor emissions index of fuel, [:math:`kg_{H_{2}O} \ kg_{fuel}^{-1}`]
|
|
90
90
|
|
|
91
91
|
Returns
|
|
92
92
|
-------
|
|
93
|
-
npt.NDArray[np.
|
|
93
|
+
npt.NDArray[np.floating]
|
|
94
94
|
Humidity released by water vapour from aircraft emissions, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
95
95
|
"""
|
|
96
96
|
rho_air = thermo.rho_d(air_temperature, air_pressure)
|
|
@@ -98,25 +98,25 @@ def q_exhaust(
|
|
|
98
98
|
|
|
99
99
|
|
|
100
100
|
def iwc_adiabatic_heating(
|
|
101
|
-
air_temperature: npt.NDArray[np.
|
|
102
|
-
air_pressure: npt.NDArray[np.
|
|
103
|
-
air_pressure_1: npt.NDArray[np.
|
|
104
|
-
) -> npt.NDArray[np.
|
|
101
|
+
air_temperature: npt.NDArray[np.floating],
|
|
102
|
+
air_pressure: npt.NDArray[np.floating],
|
|
103
|
+
air_pressure_1: npt.NDArray[np.floating],
|
|
104
|
+
) -> npt.NDArray[np.floating]:
|
|
105
105
|
"""
|
|
106
106
|
Calculate the change in ice water content due to adiabatic heating from the wake vortex phase.
|
|
107
107
|
|
|
108
108
|
Parameters
|
|
109
109
|
----------
|
|
110
|
-
air_temperature : npt.NDArray[np.
|
|
110
|
+
air_temperature : npt.NDArray[np.floating]
|
|
111
111
|
ambient temperature for each waypoint, [:math:`K`]
|
|
112
|
-
air_pressure : npt.NDArray[np.
|
|
112
|
+
air_pressure : npt.NDArray[np.floating]
|
|
113
113
|
initial pressure altitude at each waypoint, before the wake vortex phase, [:math:`Pa`]
|
|
114
|
-
air_pressure_1 : npt.NDArray[np.
|
|
114
|
+
air_pressure_1 : npt.NDArray[np.floating]
|
|
115
115
|
pressure altitude at each waypoint, after the wake vortex phase, [:math:`Pa`]
|
|
116
116
|
|
|
117
117
|
Returns
|
|
118
118
|
-------
|
|
119
|
-
npt.NDArray[np.
|
|
119
|
+
npt.NDArray[np.floating]
|
|
120
120
|
Change in ice water content due to adiabatic heating from the wake
|
|
121
121
|
vortex phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
122
122
|
"""
|
|
@@ -130,26 +130,26 @@ def iwc_adiabatic_heating(
|
|
|
130
130
|
|
|
131
131
|
|
|
132
132
|
def temperature_adiabatic_heating(
|
|
133
|
-
air_temperature: npt.NDArray[np.
|
|
134
|
-
air_pressure: npt.NDArray[np.
|
|
135
|
-
air_pressure_1: npt.NDArray[np.
|
|
136
|
-
) -> npt.NDArray[np.
|
|
133
|
+
air_temperature: npt.NDArray[np.floating],
|
|
134
|
+
air_pressure: npt.NDArray[np.floating],
|
|
135
|
+
air_pressure_1: npt.NDArray[np.floating],
|
|
136
|
+
) -> npt.NDArray[np.floating]:
|
|
137
137
|
"""Calculate the ambient air temperature for each waypoint after the wake vortex phase.
|
|
138
138
|
|
|
139
139
|
This calculation accounts for adiabatic heating.
|
|
140
140
|
|
|
141
141
|
Parameters
|
|
142
142
|
----------
|
|
143
|
-
air_temperature : npt.NDArray[np.
|
|
143
|
+
air_temperature : npt.NDArray[np.floating]
|
|
144
144
|
ambient temperature for each waypoint, [:math:`K`]
|
|
145
|
-
air_pressure : npt.NDArray[np.
|
|
145
|
+
air_pressure : npt.NDArray[np.floating]
|
|
146
146
|
initial pressure altitude at each waypoint, before the wake vortex phase, [:math:`Pa`]
|
|
147
|
-
air_pressure_1 : npt.NDArray[np.
|
|
147
|
+
air_pressure_1 : npt.NDArray[np.floating]
|
|
148
148
|
pressure altitude at each waypoint, after the wake vortex phase, [:math:`Pa`]
|
|
149
149
|
|
|
150
150
|
Returns
|
|
151
151
|
-------
|
|
152
|
-
npt.NDArray[np.
|
|
152
|
+
npt.NDArray[np.floating]
|
|
153
153
|
ambient air temperature after the wake vortex phase, [:math:`K`]
|
|
154
154
|
|
|
155
155
|
Notes
|
|
@@ -165,8 +165,8 @@ def temperature_adiabatic_heating(
|
|
|
165
165
|
|
|
166
166
|
|
|
167
167
|
def iwc_post_wake_vortex(
|
|
168
|
-
iwc: npt.NDArray[np.
|
|
169
|
-
) -> npt.NDArray[np.
|
|
168
|
+
iwc: npt.NDArray[np.floating], iwc_ad: npt.NDArray[np.floating]
|
|
169
|
+
) -> npt.NDArray[np.floating]:
|
|
170
170
|
"""
|
|
171
171
|
Calculate the ice water content after the wake vortex phase (``iwc_1``).
|
|
172
172
|
|
|
@@ -178,16 +178,16 @@ def iwc_post_wake_vortex(
|
|
|
178
178
|
|
|
179
179
|
Parameters
|
|
180
180
|
----------
|
|
181
|
-
iwc : npt.NDArray[np.
|
|
181
|
+
iwc : npt.NDArray[np.floating]
|
|
182
182
|
initial ice water content at each waypoint before the wake vortex
|
|
183
183
|
phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
184
|
-
iwc_ad : npt.NDArray[np.
|
|
184
|
+
iwc_ad : npt.NDArray[np.floating]
|
|
185
185
|
change in iwc from adiabatic heating during the wake vortex
|
|
186
186
|
phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
187
187
|
|
|
188
188
|
Returns
|
|
189
189
|
-------
|
|
190
|
-
npt.NDArray[np.
|
|
190
|
+
npt.NDArray[np.floating]
|
|
191
191
|
ice water content after the wake vortex phase, ``iwc_1``, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
192
192
|
|
|
193
193
|
Notes
|
|
@@ -202,13 +202,13 @@ def iwc_post_wake_vortex(
|
|
|
202
202
|
|
|
203
203
|
|
|
204
204
|
def ice_particle_number(
|
|
205
|
-
nvpm_ei_n: npt.NDArray[np.
|
|
206
|
-
fuel_dist: npt.NDArray[np.
|
|
207
|
-
f_surv: npt.NDArray[np.
|
|
208
|
-
air_temperature: npt.NDArray[np.
|
|
209
|
-
T_crit_sac: npt.NDArray[np.
|
|
205
|
+
nvpm_ei_n: npt.NDArray[np.floating],
|
|
206
|
+
fuel_dist: npt.NDArray[np.floating],
|
|
207
|
+
f_surv: npt.NDArray[np.floating],
|
|
208
|
+
air_temperature: npt.NDArray[np.floating],
|
|
209
|
+
T_crit_sac: npt.NDArray[np.floating],
|
|
210
210
|
min_ice_particle_number_nvpm_ei_n: float,
|
|
211
|
-
) -> npt.NDArray[np.
|
|
211
|
+
) -> npt.NDArray[np.floating]:
|
|
212
212
|
"""Calculate the initial number of ice particles per distance after the wake vortex phase.
|
|
213
213
|
|
|
214
214
|
The initial number of ice particle per distance is calculated from the black
|
|
@@ -218,15 +218,15 @@ def ice_particle_number(
|
|
|
218
218
|
|
|
219
219
|
Parameters
|
|
220
220
|
----------
|
|
221
|
-
nvpm_ei_n : npt.NDArray[np.
|
|
221
|
+
nvpm_ei_n : npt.NDArray[np.floating]
|
|
222
222
|
black carbon number emissions index, [:math:`kg^{-1}`]
|
|
223
|
-
fuel_dist : npt.NDArray[np.
|
|
223
|
+
fuel_dist : npt.NDArray[np.floating]
|
|
224
224
|
fuel consumption of the flight segment per distance traveled, [:math:`kg m^{-1}`]
|
|
225
|
-
f_surv : npt.NDArray[np.
|
|
225
|
+
f_surv : npt.NDArray[np.floating]
|
|
226
226
|
Fraction of contrail ice particle number that survive the wake vortex phase.
|
|
227
|
-
air_temperature : npt.NDArray[np.
|
|
227
|
+
air_temperature : npt.NDArray[np.floating]
|
|
228
228
|
ambient temperature for each waypoint, [:math:`K`]
|
|
229
|
-
T_crit_sac : npt.NDArray[np.
|
|
229
|
+
T_crit_sac : npt.NDArray[np.floating]
|
|
230
230
|
estimated Schmidt-Appleman temperature threshold for contrail formation, [:math:`K`]
|
|
231
231
|
min_ice_particle_number_nvpm_ei_n : float
|
|
232
232
|
lower bound for nvpm_ei_n to account for ambient aerosol particles for
|
|
@@ -234,7 +234,7 @@ def ice_particle_number(
|
|
|
234
234
|
|
|
235
235
|
Returns
|
|
236
236
|
-------
|
|
237
|
-
npt.NDArray[np.
|
|
237
|
+
npt.NDArray[np.floating]
|
|
238
238
|
initial number of ice particles per distance after the wake vortex phase, [:math:`# m^{-1}`]
|
|
239
239
|
"""
|
|
240
240
|
f_activation = ice_particle_activation_rate(air_temperature, T_crit_sac)
|
|
@@ -243,8 +243,8 @@ def ice_particle_number(
|
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
def ice_particle_activation_rate(
|
|
246
|
-
air_temperature: npt.NDArray[np.
|
|
247
|
-
) -> npt.NDArray[np.
|
|
246
|
+
air_temperature: npt.NDArray[np.floating], T_crit_sac: npt.NDArray[np.floating]
|
|
247
|
+
) -> npt.NDArray[np.floating]:
|
|
248
248
|
"""
|
|
249
249
|
Calculate the activation rate of black carbon particles to contrail ice crystals.
|
|
250
250
|
|
|
@@ -253,14 +253,14 @@ def ice_particle_activation_rate(
|
|
|
253
253
|
|
|
254
254
|
Parameters
|
|
255
255
|
----------
|
|
256
|
-
air_temperature : npt.NDArray[np.
|
|
256
|
+
air_temperature : npt.NDArray[np.floating]
|
|
257
257
|
ambient temperature at each waypoint before wake_wortex, [:math:`K`]
|
|
258
|
-
T_crit_sac : npt.NDArray[np.
|
|
258
|
+
T_crit_sac : npt.NDArray[np.floating]
|
|
259
259
|
estimated Schmidt-Appleman temperature threshold for contrail formation, [:math:`K`]
|
|
260
260
|
|
|
261
261
|
Returns
|
|
262
262
|
-------
|
|
263
|
-
npt.NDArray[np.
|
|
263
|
+
npt.NDArray[np.floating]
|
|
264
264
|
Proportion of black carbon particles that activates to contrail ice parties.
|
|
265
265
|
|
|
266
266
|
Notes
|
|
@@ -285,8 +285,8 @@ def ice_particle_activation_rate(
|
|
|
285
285
|
|
|
286
286
|
|
|
287
287
|
def ice_particle_survival_fraction(
|
|
288
|
-
iwc: npt.NDArray[np.
|
|
289
|
-
) -> npt.NDArray[np.
|
|
288
|
+
iwc: npt.NDArray[np.floating], iwc_1: npt.NDArray[np.floating]
|
|
289
|
+
) -> npt.NDArray[np.floating]:
|
|
290
290
|
"""
|
|
291
291
|
Estimate the fraction of contrail ice particle number that survive the wake vortex phase.
|
|
292
292
|
|
|
@@ -295,15 +295,15 @@ def ice_particle_survival_fraction(
|
|
|
295
295
|
|
|
296
296
|
Parameters
|
|
297
297
|
----------
|
|
298
|
-
iwc : npt.NDArray[np.
|
|
298
|
+
iwc : npt.NDArray[np.floating]
|
|
299
299
|
initial ice water content at each waypoint before the wake vortex
|
|
300
300
|
phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
301
|
-
iwc_1 : npt.NDArray[np.
|
|
301
|
+
iwc_1 : npt.NDArray[np.floating]
|
|
302
302
|
ice water content after the wake vortex phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
303
303
|
|
|
304
304
|
Returns
|
|
305
305
|
-------
|
|
306
|
-
npt.NDArray[np.
|
|
306
|
+
npt.NDArray[np.floating]
|
|
307
307
|
Fraction of contrail ice particle number that survive the wake vortex phase.
|
|
308
308
|
"""
|
|
309
309
|
f_surv = np.empty_like(iwc)
|
|
@@ -319,8 +319,8 @@ def ice_particle_survival_fraction(
|
|
|
319
319
|
|
|
320
320
|
|
|
321
321
|
def initial_persistent(
|
|
322
|
-
iwc_1: npt.NDArray[np.
|
|
323
|
-
) -> npt.NDArray[np.
|
|
322
|
+
iwc_1: npt.NDArray[np.floating], rhi_1: npt.NDArray[np.floating]
|
|
323
|
+
) -> npt.NDArray[np.floating]:
|
|
324
324
|
"""
|
|
325
325
|
Determine if waypoints have persistent contrails.
|
|
326
326
|
|
|
@@ -335,14 +335,14 @@ def initial_persistent(
|
|
|
335
335
|
|
|
336
336
|
Parameters
|
|
337
337
|
----------
|
|
338
|
-
iwc_1 : npt.NDArray[np.
|
|
338
|
+
iwc_1 : npt.NDArray[np.floating]
|
|
339
339
|
ice water content after the wake vortex phase, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
340
|
-
rhi_1 : npt.NDArray[np.
|
|
340
|
+
rhi_1 : npt.NDArray[np.floating]
|
|
341
341
|
relative humidity with respect to ice after the wake vortex phase
|
|
342
342
|
|
|
343
343
|
Returns
|
|
344
344
|
-------
|
|
345
|
-
npt.NDArray[np.
|
|
345
|
+
npt.NDArray[np.floating]
|
|
346
346
|
Mask of waypoints with persistent contrails. Waypoints with persistent contrails
|
|
347
347
|
will have value 1.
|
|
348
348
|
|
|
@@ -358,12 +358,12 @@ def initial_persistent(
|
|
|
358
358
|
|
|
359
359
|
|
|
360
360
|
def contrail_persistent(
|
|
361
|
-
latitude: npt.NDArray[np.
|
|
362
|
-
altitude: npt.NDArray[np.
|
|
363
|
-
segment_length: npt.NDArray[np.
|
|
361
|
+
latitude: npt.NDArray[np.floating],
|
|
362
|
+
altitude: npt.NDArray[np.floating],
|
|
363
|
+
segment_length: npt.NDArray[np.floating],
|
|
364
364
|
age: npt.NDArray[np.timedelta64],
|
|
365
|
-
tau_contrail: npt.NDArray[np.
|
|
366
|
-
n_ice_per_m3: npt.NDArray[np.
|
|
365
|
+
tau_contrail: npt.NDArray[np.floating],
|
|
366
|
+
n_ice_per_m3: npt.NDArray[np.floating],
|
|
367
367
|
params: dict[str, Any],
|
|
368
368
|
) -> npt.NDArray[np.bool_]:
|
|
369
369
|
r"""
|
|
@@ -391,17 +391,17 @@ def contrail_persistent(
|
|
|
391
391
|
|
|
392
392
|
Parameters
|
|
393
393
|
----------
|
|
394
|
-
latitude : npt.NDArray[np.
|
|
394
|
+
latitude : npt.NDArray[np.floating]
|
|
395
395
|
Contrail latitude, [:math:`\deg`]
|
|
396
|
-
altitude : npt.NDArray[np.
|
|
396
|
+
altitude : npt.NDArray[np.floating]
|
|
397
397
|
Contrail altitude, [:math:`m`]
|
|
398
|
-
segment_length : npt.NDArray[np.
|
|
398
|
+
segment_length : npt.NDArray[np.floating]
|
|
399
399
|
Contrail segment length, [:math:`m`]
|
|
400
400
|
age : npt.NDArray[np.timedelta64]
|
|
401
401
|
Contrail age
|
|
402
|
-
tau_contrail : npt.NDArray[np.
|
|
402
|
+
tau_contrail : npt.NDArray[np.floating]
|
|
403
403
|
Contrail optical depth
|
|
404
|
-
n_ice_per_m3 : npt.NDArray[np.
|
|
404
|
+
n_ice_per_m3 : npt.NDArray[np.floating]
|
|
405
405
|
Contrail ice particle number per volume of air, [:math:`# m^{-3}`]
|
|
406
406
|
params : dict[str, Any]
|
|
407
407
|
Dictionary of :class:`CocipParams` parameters determining the
|
|
@@ -420,7 +420,7 @@ def contrail_persistent(
|
|
|
420
420
|
)
|
|
421
421
|
status_4 = _within_range(altitude, max=params["max_altitude_m"], min=params["min_altitude_m"])
|
|
422
422
|
status_5 = _within_range(segment_length, max=params["max_seg_length_m"])
|
|
423
|
-
status_6 = _within_range(latitude, max=89.0, min=-89.0)
|
|
423
|
+
status_6 = _within_range(latitude, max=89.0, min=-89.0)
|
|
424
424
|
|
|
425
425
|
logger.debug(
|
|
426
426
|
"Survival stats. age: %s, tau: %s, ice: %s, altitude: %s, segment: %s, latitude: %s",
|
|
@@ -434,13 +434,26 @@ def contrail_persistent(
|
|
|
434
434
|
return status_1 & status_2 & status_3 & status_4 & status_5 & status_6
|
|
435
435
|
|
|
436
436
|
|
|
437
|
-
|
|
437
|
+
@overload
|
|
438
|
+
def _within_range(
|
|
439
|
+
val: npt.NDArray[np.floating],
|
|
440
|
+
max: float | None = None,
|
|
441
|
+
min: float | None = None,
|
|
442
|
+
) -> npt.NDArray[np.bool_]: ...
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
@overload
|
|
446
|
+
def _within_range(
|
|
447
|
+
val: npt.NDArray[np.timedelta64],
|
|
448
|
+
max: np.timedelta64 | None = None,
|
|
449
|
+
min: np.timedelta64 | None = None,
|
|
450
|
+
) -> npt.NDArray[np.bool_]: ...
|
|
438
451
|
|
|
439
452
|
|
|
440
453
|
def _within_range(
|
|
441
|
-
val:
|
|
442
|
-
max:
|
|
443
|
-
min:
|
|
454
|
+
val: np.ndarray,
|
|
455
|
+
max: float | np.timedelta64 | None = None,
|
|
456
|
+
min: float | np.timedelta64 | None = None,
|
|
444
457
|
) -> npt.NDArray[np.bool_]:
|
|
445
458
|
"""
|
|
446
459
|
Check if the input values (val) are each within the specified range.
|
|
@@ -475,16 +488,16 @@ def _within_range(
|
|
|
475
488
|
|
|
476
489
|
|
|
477
490
|
def contrail_edges(
|
|
478
|
-
lon: npt.NDArray[np.
|
|
479
|
-
lat: npt.NDArray[np.
|
|
480
|
-
sin_a: npt.NDArray[np.
|
|
481
|
-
cos_a: npt.NDArray[np.
|
|
482
|
-
width: npt.NDArray[np.
|
|
491
|
+
lon: npt.NDArray[np.floating],
|
|
492
|
+
lat: npt.NDArray[np.floating],
|
|
493
|
+
sin_a: npt.NDArray[np.floating],
|
|
494
|
+
cos_a: npt.NDArray[np.floating],
|
|
495
|
+
width: npt.NDArray[np.floating],
|
|
483
496
|
) -> tuple[
|
|
484
|
-
npt.NDArray[np.
|
|
485
|
-
npt.NDArray[np.
|
|
486
|
-
npt.NDArray[np.
|
|
487
|
-
npt.NDArray[np.
|
|
497
|
+
npt.NDArray[np.floating],
|
|
498
|
+
npt.NDArray[np.floating],
|
|
499
|
+
npt.NDArray[np.floating],
|
|
500
|
+
npt.NDArray[np.floating],
|
|
488
501
|
]:
|
|
489
502
|
"""
|
|
490
503
|
Calculate the longitude and latitude of the contrail edges to account for contrail spreading.
|
|
@@ -498,20 +511,20 @@ def contrail_edges(
|
|
|
498
511
|
|
|
499
512
|
Parameters
|
|
500
513
|
----------
|
|
501
|
-
lon : npt.NDArray[np.
|
|
514
|
+
lon : npt.NDArray[np.floating]
|
|
502
515
|
longitude of contrail waypoint, degrees
|
|
503
|
-
lat : npt.NDArray[np.
|
|
516
|
+
lat : npt.NDArray[np.floating]
|
|
504
517
|
latitude of contrail waypoint, degrees
|
|
505
|
-
sin_a : npt.NDArray[np.
|
|
518
|
+
sin_a : npt.NDArray[np.floating]
|
|
506
519
|
sin(a), where a is the angle between the plume and the longitudinal axis
|
|
507
|
-
cos_a : npt.NDArray[np.
|
|
520
|
+
cos_a : npt.NDArray[np.floating]
|
|
508
521
|
cos(a), where a is the angle between the plume and the longitudinal axis
|
|
509
|
-
width : npt.NDArray[np.
|
|
522
|
+
width : npt.NDArray[np.floating]
|
|
510
523
|
contrail width at each waypoint, [:math:`m`]
|
|
511
524
|
|
|
512
525
|
Returns
|
|
513
526
|
-------
|
|
514
|
-
tuple[npt.NDArray[np.
|
|
527
|
+
tuple[npt.NDArray[np.floating], npt.NDArray[np.floating], npt.NDArray[np.floating], npt.NDArray[np.floating]]
|
|
515
528
|
(lon_edge_l, lat_edge_l, lon_edge_r, lat_edge_r), longitudes and latitudes
|
|
516
529
|
at the left and right edges of the contrail, degrees
|
|
517
530
|
""" # noqa: E501
|
|
@@ -527,21 +540,21 @@ def contrail_edges(
|
|
|
527
540
|
|
|
528
541
|
|
|
529
542
|
def contrail_vertices(
|
|
530
|
-
lon: npt.NDArray[np.
|
|
531
|
-
lat: npt.NDArray[np.
|
|
532
|
-
sin_a: npt.NDArray[np.
|
|
533
|
-
cos_a: npt.NDArray[np.
|
|
534
|
-
width: npt.NDArray[np.
|
|
535
|
-
segment_length: npt.NDArray[np.
|
|
543
|
+
lon: npt.NDArray[np.floating],
|
|
544
|
+
lat: npt.NDArray[np.floating],
|
|
545
|
+
sin_a: npt.NDArray[np.floating],
|
|
546
|
+
cos_a: npt.NDArray[np.floating],
|
|
547
|
+
width: npt.NDArray[np.floating],
|
|
548
|
+
segment_length: npt.NDArray[np.floating],
|
|
536
549
|
) -> tuple[
|
|
537
|
-
npt.NDArray[np.
|
|
538
|
-
npt.NDArray[np.
|
|
539
|
-
npt.NDArray[np.
|
|
540
|
-
npt.NDArray[np.
|
|
541
|
-
npt.NDArray[np.
|
|
542
|
-
npt.NDArray[np.
|
|
543
|
-
npt.NDArray[np.
|
|
544
|
-
npt.NDArray[np.
|
|
550
|
+
npt.NDArray[np.floating],
|
|
551
|
+
npt.NDArray[np.floating],
|
|
552
|
+
npt.NDArray[np.floating],
|
|
553
|
+
npt.NDArray[np.floating],
|
|
554
|
+
npt.NDArray[np.floating],
|
|
555
|
+
npt.NDArray[np.floating],
|
|
556
|
+
npt.NDArray[np.floating],
|
|
557
|
+
npt.NDArray[np.floating],
|
|
545
558
|
]:
|
|
546
559
|
"""
|
|
547
560
|
Calculate the longitude and latitude of the contrail vertices.
|
|
@@ -559,22 +572,22 @@ def contrail_vertices(
|
|
|
559
572
|
|
|
560
573
|
Parameters
|
|
561
574
|
----------
|
|
562
|
-
lon : npt.NDArray[np.
|
|
575
|
+
lon : npt.NDArray[np.floating]
|
|
563
576
|
longitude of contrail waypoint, degrees
|
|
564
|
-
lat : npt.NDArray[np.
|
|
577
|
+
lat : npt.NDArray[np.floating]
|
|
565
578
|
latitude of contrail waypoint, degrees
|
|
566
|
-
sin_a : npt.NDArray[np.
|
|
579
|
+
sin_a : npt.NDArray[np.floating]
|
|
567
580
|
sin(a), where a is the angle between the plume and the longitudinal axis
|
|
568
|
-
cos_a : npt.NDArray[np.
|
|
581
|
+
cos_a : npt.NDArray[np.floating]
|
|
569
582
|
cos(a), where a is the angle between the plume and the longitudinal axis
|
|
570
|
-
width : npt.NDArray[np.
|
|
583
|
+
width : npt.NDArray[np.floating]
|
|
571
584
|
contrail width at each waypoint, [:math:`m`]
|
|
572
|
-
segment_length : npt.NDArray[np.
|
|
585
|
+
segment_length : npt.NDArray[np.floating]
|
|
573
586
|
contrail length at each waypoint, [:math:`m`]
|
|
574
587
|
|
|
575
588
|
Returns
|
|
576
589
|
-------
|
|
577
|
-
tuple[npt.NDArray[np.
|
|
590
|
+
tuple[npt.NDArray[np.floating], npt.NDArray[np.floating], npt.NDArray[np.floating], npt.NDArray[np.floating]]
|
|
578
591
|
(lon_1, lat_1, lon_2, lat_2, lon_3, lat_3, lon_4, lat_4) degrees
|
|
579
592
|
""" # noqa: E501
|
|
580
593
|
dlon_width = units.m_to_longitude_distance(width * sin_a * 0.5, lat)
|
|
@@ -598,10 +611,10 @@ def contrail_vertices(
|
|
|
598
611
|
|
|
599
612
|
|
|
600
613
|
def plume_effective_cross_sectional_area(
|
|
601
|
-
width: npt.NDArray[np.
|
|
602
|
-
depth: npt.NDArray[np.
|
|
603
|
-
sigma_yz: npt.NDArray[np.
|
|
604
|
-
) -> npt.NDArray[np.
|
|
614
|
+
width: npt.NDArray[np.floating],
|
|
615
|
+
depth: npt.NDArray[np.floating],
|
|
616
|
+
sigma_yz: npt.NDArray[np.floating] | float,
|
|
617
|
+
) -> npt.NDArray[np.floating]:
|
|
605
618
|
"""
|
|
606
619
|
Calculate the effective cross-sectional area of the contrail plume (``area_eff``).
|
|
607
620
|
|
|
@@ -610,16 +623,16 @@ def plume_effective_cross_sectional_area(
|
|
|
610
623
|
|
|
611
624
|
Parameters
|
|
612
625
|
----------
|
|
613
|
-
width : npt.NDArray[np.
|
|
626
|
+
width : npt.NDArray[np.floating]
|
|
614
627
|
contrail width at each waypoint, [:math:`m`]
|
|
615
|
-
depth : npt.NDArray[np.
|
|
628
|
+
depth : npt.NDArray[np.floating]
|
|
616
629
|
contrail depth at each waypoint, [:math:`m`]
|
|
617
|
-
sigma_yz : npt.NDArray[np.
|
|
630
|
+
sigma_yz : npt.NDArray[np.floating] | float
|
|
618
631
|
temporal evolution of the contrail plume parameters
|
|
619
632
|
|
|
620
633
|
Returns
|
|
621
634
|
-------
|
|
622
|
-
npt.NDArray[np.
|
|
635
|
+
npt.NDArray[np.floating]
|
|
623
636
|
effective cross-sectional area of the contrail plume, [:math:`m^{2}`]
|
|
624
637
|
"""
|
|
625
638
|
sigma_yy = 0.125 * (width**2)
|
|
@@ -628,8 +641,8 @@ def plume_effective_cross_sectional_area(
|
|
|
628
641
|
|
|
629
642
|
|
|
630
643
|
def plume_effective_depth(
|
|
631
|
-
width: npt.NDArray[np.
|
|
632
|
-
) -> npt.NDArray[np.
|
|
644
|
+
width: npt.NDArray[np.floating], area_eff: npt.NDArray[np.floating]
|
|
645
|
+
) -> npt.NDArray[np.floating]:
|
|
633
646
|
"""
|
|
634
647
|
Calculate the effective depth of the contrail plume (``depth_eff``).
|
|
635
648
|
|
|
@@ -638,100 +651,100 @@ def plume_effective_depth(
|
|
|
638
651
|
|
|
639
652
|
Parameters
|
|
640
653
|
----------
|
|
641
|
-
width : npt.NDArray[np.
|
|
654
|
+
width : npt.NDArray[np.floating]
|
|
642
655
|
contrail width at each waypoint, [:math:`m`]
|
|
643
|
-
area_eff : npt.NDArray[np.
|
|
656
|
+
area_eff : npt.NDArray[np.floating]
|
|
644
657
|
effective cross-sectional area of the contrail plume, [:math:`m^{2}`]
|
|
645
658
|
|
|
646
659
|
Returns
|
|
647
660
|
-------
|
|
648
|
-
npt.NDArray[np.
|
|
661
|
+
npt.NDArray[np.floating]
|
|
649
662
|
effective depth of the contrail plume, [:math:`m`]
|
|
650
663
|
"""
|
|
651
664
|
return area_eff / width
|
|
652
665
|
|
|
653
666
|
|
|
654
667
|
def plume_mass_per_distance(
|
|
655
|
-
area_eff: npt.NDArray[np.
|
|
656
|
-
) -> npt.NDArray[np.
|
|
668
|
+
area_eff: npt.NDArray[np.floating], rho_air: npt.NDArray[np.floating]
|
|
669
|
+
) -> npt.NDArray[np.floating]:
|
|
657
670
|
"""
|
|
658
671
|
Calculate the contrail plume mass per unit length.
|
|
659
672
|
|
|
660
673
|
Parameters
|
|
661
674
|
----------
|
|
662
|
-
area_eff : npt.NDArray[np.
|
|
675
|
+
area_eff : npt.NDArray[np.floating]
|
|
663
676
|
effective cross-sectional area of the contrail plume, [:math:`m^{2}`]
|
|
664
|
-
rho_air : npt.NDArray[np.
|
|
677
|
+
rho_air : npt.NDArray[np.floating]
|
|
665
678
|
density of air for each waypoint, [:math:`kg m^{-3}`]
|
|
666
679
|
|
|
667
680
|
Returns
|
|
668
681
|
-------
|
|
669
|
-
npt.NDArray[np.
|
|
682
|
+
npt.NDArray[np.floating]
|
|
670
683
|
contrail plume mass per unit length, [:math:`kg m^{-1}`]
|
|
671
684
|
"""
|
|
672
685
|
return area_eff * rho_air
|
|
673
686
|
|
|
674
687
|
|
|
675
688
|
def ice_particle_number_per_volume_of_plume(
|
|
676
|
-
n_ice_per_m: npt.NDArray[np.
|
|
677
|
-
) -> npt.NDArray[np.
|
|
689
|
+
n_ice_per_m: npt.NDArray[np.floating], area_eff: npt.NDArray[np.floating]
|
|
690
|
+
) -> npt.NDArray[np.floating]:
|
|
678
691
|
"""
|
|
679
692
|
Calculate the number of contrail ice particles per volume of plume (``n_ice_per_vol``).
|
|
680
693
|
|
|
681
694
|
Parameters
|
|
682
695
|
----------
|
|
683
|
-
n_ice_per_m : npt.NDArray[np.
|
|
696
|
+
n_ice_per_m : npt.NDArray[np.floating]
|
|
684
697
|
number of ice particles per distance at time t, [:math:`m^{-1}`]
|
|
685
|
-
area_eff : npt.NDArray[np.
|
|
698
|
+
area_eff : npt.NDArray[np.floating]
|
|
686
699
|
effective cross-sectional area of the contrail plume, [:math:`m^{2}`]
|
|
687
700
|
|
|
688
701
|
Returns
|
|
689
702
|
-------
|
|
690
|
-
npt.NDArray[np.
|
|
703
|
+
npt.NDArray[np.floating]
|
|
691
704
|
number of ice particles per volume of contrail plume at time t, [:math:`# m^{-3}`]
|
|
692
705
|
"""
|
|
693
706
|
return n_ice_per_m / area_eff
|
|
694
707
|
|
|
695
708
|
|
|
696
709
|
def ice_particle_number_per_mass_of_air(
|
|
697
|
-
n_ice_per_vol: npt.NDArray[np.
|
|
698
|
-
) -> npt.NDArray[np.
|
|
710
|
+
n_ice_per_vol: npt.NDArray[np.floating], rho_air: npt.NDArray[np.floating]
|
|
711
|
+
) -> npt.NDArray[np.floating]:
|
|
699
712
|
"""
|
|
700
713
|
Calculate the number of contrail ice particles per mass of air.
|
|
701
714
|
|
|
702
715
|
Parameters
|
|
703
716
|
----------
|
|
704
|
-
n_ice_per_vol : npt.NDArray[np.
|
|
717
|
+
n_ice_per_vol : npt.NDArray[np.floating]
|
|
705
718
|
number of ice particles per volume of contrail plume at time t, [:math:`# m^{-3}`]
|
|
706
|
-
rho_air : npt.NDArray[np.
|
|
719
|
+
rho_air : npt.NDArray[np.floating]
|
|
707
720
|
density of air for each waypoint, [:math:`kg m^{-3}`]
|
|
708
721
|
|
|
709
722
|
Returns
|
|
710
723
|
-------
|
|
711
|
-
npt.NDArray[np.
|
|
724
|
+
npt.NDArray[np.floating]
|
|
712
725
|
number of ice particles per mass of air at time t, [:math:`# kg^{-1}`]
|
|
713
726
|
"""
|
|
714
727
|
return n_ice_per_vol / rho_air
|
|
715
728
|
|
|
716
729
|
|
|
717
730
|
def ice_particle_volume_mean_radius(
|
|
718
|
-
iwc: npt.NDArray[np.
|
|
719
|
-
) -> npt.NDArray[np.
|
|
731
|
+
iwc: npt.NDArray[np.floating], n_ice_per_kg_air: npt.NDArray[np.floating]
|
|
732
|
+
) -> npt.NDArray[np.floating]:
|
|
720
733
|
"""
|
|
721
734
|
Calculate the ice particle volume mean radius.
|
|
722
735
|
|
|
723
736
|
Parameters
|
|
724
737
|
----------
|
|
725
|
-
iwc : npt.NDArray[np.
|
|
738
|
+
iwc : npt.NDArray[np.floating]
|
|
726
739
|
contrail ice water content, i.e., contrail ice mass per
|
|
727
740
|
kg of air, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
728
741
|
|
|
729
|
-
n_ice_per_kg_air : npt.NDArray[np.
|
|
742
|
+
n_ice_per_kg_air : npt.NDArray[np.floating]
|
|
730
743
|
number of ice particles per mass of air, [:math:`# kg^{-1}`]
|
|
731
744
|
|
|
732
745
|
Returns
|
|
733
746
|
-------
|
|
734
|
-
npt.NDArray[np.
|
|
747
|
+
npt.NDArray[np.floating]
|
|
735
748
|
ice particle volume mean radius, [:math:`m`]
|
|
736
749
|
|
|
737
750
|
Notes
|
|
@@ -752,10 +765,10 @@ def ice_particle_volume_mean_radius(
|
|
|
752
765
|
|
|
753
766
|
|
|
754
767
|
def ice_particle_terminal_fall_speed(
|
|
755
|
-
air_pressure: npt.NDArray[np.
|
|
756
|
-
air_temperature: npt.NDArray[np.
|
|
757
|
-
r_ice_vol: npt.NDArray[np.
|
|
758
|
-
) -> npt.NDArray[np.
|
|
768
|
+
air_pressure: npt.NDArray[np.floating],
|
|
769
|
+
air_temperature: npt.NDArray[np.floating],
|
|
770
|
+
r_ice_vol: npt.NDArray[np.floating],
|
|
771
|
+
) -> npt.NDArray[np.floating]:
|
|
759
772
|
"""
|
|
760
773
|
Calculate the terminal fall speed of contrail ice particles.
|
|
761
774
|
|
|
@@ -766,16 +779,16 @@ def ice_particle_terminal_fall_speed(
|
|
|
766
779
|
|
|
767
780
|
Parameters
|
|
768
781
|
----------
|
|
769
|
-
air_pressure : npt.NDArray[np.
|
|
782
|
+
air_pressure : npt.NDArray[np.floating]
|
|
770
783
|
Pressure altitude at each waypoint, [:math:`Pa`]
|
|
771
|
-
air_temperature : npt.NDArray[np.
|
|
784
|
+
air_temperature : npt.NDArray[np.floating]
|
|
772
785
|
Ambient temperature for each waypoint, [:math:`K`]
|
|
773
|
-
r_ice_vol : npt.NDArray[np.
|
|
786
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
774
787
|
Ice particle volume mean radius, [:math:`m`]
|
|
775
788
|
|
|
776
789
|
Returns
|
|
777
790
|
-------
|
|
778
|
-
npt.NDArray[np.
|
|
791
|
+
npt.NDArray[np.floating]
|
|
779
792
|
Terminal fall speed of contrail ice particles, [:math:`m s^{-1}`]
|
|
780
793
|
|
|
781
794
|
References
|
|
@@ -805,7 +818,7 @@ def ice_particle_terminal_fall_speed(
|
|
|
805
818
|
return alpha * (30000.0 / air_pressure) ** 0.178 * (233.0 / air_temperature) ** 0.394
|
|
806
819
|
|
|
807
820
|
|
|
808
|
-
def ice_particle_mass(r_ice_vol: npt.NDArray[np.
|
|
821
|
+
def ice_particle_mass(r_ice_vol: npt.NDArray[np.floating]) -> npt.NDArray[np.floating]:
|
|
809
822
|
"""
|
|
810
823
|
Calculate the contrail ice particle mass.
|
|
811
824
|
|
|
@@ -813,34 +826,34 @@ def ice_particle_mass(r_ice_vol: npt.NDArray[np.float64]) -> npt.NDArray[np.floa
|
|
|
813
826
|
|
|
814
827
|
Parameters
|
|
815
828
|
----------
|
|
816
|
-
r_ice_vol : npt.NDArray[np.
|
|
829
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
817
830
|
Ice particle volume mean radius, [:math:`m`]
|
|
818
831
|
|
|
819
832
|
Returns
|
|
820
833
|
-------
|
|
821
|
-
npt.NDArray[np.
|
|
834
|
+
npt.NDArray[np.floating]
|
|
822
835
|
Mean contrail ice particle mass, [:math:`kg`]
|
|
823
836
|
"""
|
|
824
837
|
return ((4 / 3) * np.pi * r_ice_vol**3) * constants.rho_ice
|
|
825
838
|
|
|
826
839
|
|
|
827
840
|
def horizontal_diffusivity(
|
|
828
|
-
ds_dz: npt.NDArray[np.
|
|
829
|
-
) -> npt.NDArray[np.
|
|
841
|
+
ds_dz: npt.NDArray[np.floating], depth: npt.NDArray[np.floating]
|
|
842
|
+
) -> npt.NDArray[np.floating]:
|
|
830
843
|
"""
|
|
831
844
|
Calculate contrail horizontal diffusivity.
|
|
832
845
|
|
|
833
846
|
Parameters
|
|
834
847
|
----------
|
|
835
|
-
ds_dz : npt.NDArray[np.
|
|
848
|
+
ds_dz : npt.NDArray[np.floating]
|
|
836
849
|
Total wind shear (eastward and northward winds) with respect
|
|
837
850
|
to altitude (``dz``), [:math:`m s^{-1} / Pa`]
|
|
838
|
-
depth : npt.NDArray[np.
|
|
851
|
+
depth : npt.NDArray[np.floating]
|
|
839
852
|
Contrail depth at each waypoint, [:math:`m`]
|
|
840
853
|
|
|
841
854
|
Returns
|
|
842
855
|
-------
|
|
843
|
-
npt.NDArray[np.
|
|
856
|
+
npt.NDArray[np.floating]
|
|
844
857
|
horizontal diffusivity, [:math:`m^{2} s^{-1}`]
|
|
845
858
|
|
|
846
859
|
References
|
|
@@ -856,39 +869,39 @@ def horizontal_diffusivity(
|
|
|
856
869
|
|
|
857
870
|
|
|
858
871
|
def vertical_diffusivity(
|
|
859
|
-
air_pressure: npt.NDArray[np.
|
|
860
|
-
air_temperature: npt.NDArray[np.
|
|
861
|
-
dT_dz: npt.NDArray[np.
|
|
862
|
-
depth_eff: npt.NDArray[np.
|
|
863
|
-
terminal_fall_speed: npt.NDArray[np.
|
|
864
|
-
sedimentation_impact_factor: npt.NDArray[np.
|
|
865
|
-
eff_heat_rate: npt.NDArray[np.
|
|
866
|
-
) -> npt.NDArray[np.
|
|
872
|
+
air_pressure: npt.NDArray[np.floating],
|
|
873
|
+
air_temperature: npt.NDArray[np.floating],
|
|
874
|
+
dT_dz: npt.NDArray[np.floating],
|
|
875
|
+
depth_eff: npt.NDArray[np.floating],
|
|
876
|
+
terminal_fall_speed: npt.NDArray[np.floating] | float,
|
|
877
|
+
sedimentation_impact_factor: npt.NDArray[np.floating] | float,
|
|
878
|
+
eff_heat_rate: npt.NDArray[np.floating] | None,
|
|
879
|
+
) -> npt.NDArray[np.floating]:
|
|
867
880
|
"""
|
|
868
881
|
Calculate contrail vertical diffusivity.
|
|
869
882
|
|
|
870
883
|
Parameters
|
|
871
884
|
----------
|
|
872
|
-
air_pressure : npt.NDArray[np.
|
|
885
|
+
air_pressure : npt.NDArray[np.floating]
|
|
873
886
|
Pressure altitude at each waypoint, [:math:`Pa`]
|
|
874
|
-
air_temperature : npt.NDArray[np.
|
|
887
|
+
air_temperature : npt.NDArray[np.floating]
|
|
875
888
|
Ambient temperature for each waypoint, [:math:`K`]
|
|
876
|
-
dT_dz : npt.NDArray[np.
|
|
889
|
+
dT_dz : npt.NDArray[np.floating]
|
|
877
890
|
Temperature gradient with respect to altitude (dz), [:math:`K m^{-1}`]
|
|
878
|
-
depth_eff : npt.NDArray[np.
|
|
891
|
+
depth_eff : npt.NDArray[np.floating]
|
|
879
892
|
Effective depth of the contrail plume, [:math:`m`]
|
|
880
|
-
terminal_fall_speed : npt.NDArray[np.
|
|
893
|
+
terminal_fall_speed : npt.NDArray[np.floating]
|
|
881
894
|
Terminal fall speed of contrail ice particles, [:math:`m s^{-1}`]
|
|
882
895
|
sedimentation_impact_factor : float
|
|
883
896
|
Enhancement parameter denoted by `f_T` in eq. (35) Schumann (2012).
|
|
884
|
-
eff_heat_rate: npt.NDArray[np.
|
|
897
|
+
eff_heat_rate: npt.NDArray[np.floating] | None
|
|
885
898
|
Effective heating rate, i.e., rate of which the contrail plume
|
|
886
899
|
is heated, [:math:`K s^{-1}`]. If None is passed, the radiative
|
|
887
900
|
heating effects on contrail cirrus properties are not included.
|
|
888
901
|
|
|
889
902
|
Returns
|
|
890
903
|
-------
|
|
891
|
-
npt.NDArray[np.
|
|
904
|
+
npt.NDArray[np.floating]
|
|
892
905
|
vertical diffusivity, [:math:`m^{2} s^{-1}`]
|
|
893
906
|
|
|
894
907
|
References
|
|
@@ -913,7 +926,7 @@ def vertical_diffusivity(
|
|
|
913
926
|
n_bv = thermo.brunt_vaisala_frequency(air_pressure, air_temperature, dT_dz)
|
|
914
927
|
n_bv.clip(min=0.001, out=n_bv)
|
|
915
928
|
|
|
916
|
-
cvs: npt.NDArray[np.
|
|
929
|
+
cvs: npt.NDArray[np.floating] | float
|
|
917
930
|
if eff_heat_rate is not None:
|
|
918
931
|
cvs = radiative_heating.convective_velocity_scale(depth_eff, eff_heat_rate, air_temperature)
|
|
919
932
|
cvs.clip(min=0.01, out=cvs)
|
|
@@ -929,28 +942,28 @@ def vertical_diffusivity(
|
|
|
929
942
|
|
|
930
943
|
|
|
931
944
|
def particle_losses_aggregation(
|
|
932
|
-
r_ice_vol: npt.NDArray[np.
|
|
933
|
-
terminal_fall_speed: npt.NDArray[np.
|
|
934
|
-
area_eff: npt.NDArray[np.
|
|
945
|
+
r_ice_vol: npt.NDArray[np.floating],
|
|
946
|
+
terminal_fall_speed: npt.NDArray[np.floating],
|
|
947
|
+
area_eff: npt.NDArray[np.floating],
|
|
935
948
|
agg_efficiency: float = 1.0,
|
|
936
|
-
) -> npt.NDArray[np.
|
|
949
|
+
) -> npt.NDArray[np.floating]:
|
|
937
950
|
"""
|
|
938
951
|
Calculate the rate of contrail ice particle losses due to sedimentation-induced aggregation.
|
|
939
952
|
|
|
940
953
|
Parameters
|
|
941
954
|
----------
|
|
942
|
-
r_ice_vol : npt.NDArray[np.
|
|
955
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
943
956
|
Ice particle volume mean radius, [:math:`m`]
|
|
944
|
-
terminal_fall_speed : npt.NDArray[np.
|
|
957
|
+
terminal_fall_speed : npt.NDArray[np.floating]
|
|
945
958
|
Terminal fall speed of contrail ice particles, [:math:`m s^{-1}`]
|
|
946
|
-
area_eff : npt.NDArray[np.
|
|
959
|
+
area_eff : npt.NDArray[np.floating]
|
|
947
960
|
Effective cross-sectional area of the contrail plume, [:math:`m^{2}`]
|
|
948
961
|
agg_efficiency : float, optional
|
|
949
962
|
Aggregation efficiency
|
|
950
963
|
|
|
951
964
|
Returns
|
|
952
965
|
-------
|
|
953
|
-
npt.NDArray[np.
|
|
966
|
+
npt.NDArray[np.floating]
|
|
954
967
|
Rate of contrail ice particle losses due to sedimentation-induced
|
|
955
968
|
aggregation, [:math:`# s^{-1}`]
|
|
956
969
|
|
|
@@ -968,34 +981,34 @@ def particle_losses_aggregation(
|
|
|
968
981
|
|
|
969
982
|
|
|
970
983
|
def particle_losses_turbulence(
|
|
971
|
-
width: npt.NDArray[np.
|
|
972
|
-
depth: npt.NDArray[np.
|
|
973
|
-
depth_eff: npt.NDArray[np.
|
|
974
|
-
diffuse_h: npt.NDArray[np.
|
|
975
|
-
diffuse_v: npt.NDArray[np.
|
|
984
|
+
width: npt.NDArray[np.floating],
|
|
985
|
+
depth: npt.NDArray[np.floating],
|
|
986
|
+
depth_eff: npt.NDArray[np.floating],
|
|
987
|
+
diffuse_h: npt.NDArray[np.floating],
|
|
988
|
+
diffuse_v: npt.NDArray[np.floating],
|
|
976
989
|
turb_efficiency: float = 0.1,
|
|
977
|
-
) -> npt.NDArray[np.
|
|
990
|
+
) -> npt.NDArray[np.floating]:
|
|
978
991
|
"""
|
|
979
992
|
Calculate the rate of contrail ice particle losses due to plume-internal turbulence.
|
|
980
993
|
|
|
981
994
|
Parameters
|
|
982
995
|
----------
|
|
983
|
-
width : npt.NDArray[np.
|
|
996
|
+
width : npt.NDArray[np.floating]
|
|
984
997
|
Contrail width at each waypoint, [:math:`m`]
|
|
985
|
-
depth : npt.NDArray[np.
|
|
998
|
+
depth : npt.NDArray[np.floating]
|
|
986
999
|
Contrail depth at each waypoint, [:math:`m`]
|
|
987
|
-
depth_eff : npt.NDArray[np.
|
|
1000
|
+
depth_eff : npt.NDArray[np.floating]
|
|
988
1001
|
Effective depth of the contrail plume, [:math:`m`]
|
|
989
|
-
diffuse_h : npt.NDArray[np.
|
|
1002
|
+
diffuse_h : npt.NDArray[np.floating]
|
|
990
1003
|
Horizontal diffusivity, [:math:`m^{2} s^{-1}`]
|
|
991
|
-
diffuse_v : npt.NDArray[np.
|
|
1004
|
+
diffuse_v : npt.NDArray[np.floating]
|
|
992
1005
|
Vertical diffusivity, [:math:`m^{2} s^{-1}`]
|
|
993
1006
|
turb_efficiency : float, optional
|
|
994
1007
|
Turbulence sublimation efficiency
|
|
995
1008
|
|
|
996
1009
|
Returns
|
|
997
1010
|
-------
|
|
998
|
-
npt.NDArray[np.
|
|
1011
|
+
npt.NDArray[np.floating]
|
|
999
1012
|
Rate of contrail ice particle losses due to plume-internal turbulence, [:math:`# s^{-1}`]
|
|
1000
1013
|
|
|
1001
1014
|
Notes
|
|
@@ -1018,25 +1031,25 @@ def particle_losses_turbulence(
|
|
|
1018
1031
|
|
|
1019
1032
|
|
|
1020
1033
|
def contrail_optical_depth(
|
|
1021
|
-
r_ice_vol: npt.NDArray[np.
|
|
1022
|
-
n_ice_per_m: npt.NDArray[np.
|
|
1023
|
-
width: npt.NDArray[np.
|
|
1024
|
-
) -> npt.NDArray[np.
|
|
1034
|
+
r_ice_vol: npt.NDArray[np.floating],
|
|
1035
|
+
n_ice_per_m: npt.NDArray[np.floating],
|
|
1036
|
+
width: npt.NDArray[np.floating],
|
|
1037
|
+
) -> npt.NDArray[np.floating]:
|
|
1025
1038
|
"""
|
|
1026
1039
|
Calculate the contrail optical depth for each waypoint.
|
|
1027
1040
|
|
|
1028
1041
|
Parameters
|
|
1029
1042
|
----------
|
|
1030
|
-
r_ice_vol : npt.NDArray[np.
|
|
1043
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
1031
1044
|
ice particle volume mean radius, [:math:`m`]
|
|
1032
|
-
n_ice_per_m : npt.NDArray[np.
|
|
1045
|
+
n_ice_per_m : npt.NDArray[np.floating]
|
|
1033
1046
|
Number of contrail ice particles per distance, [:math:`m^{-1}`]
|
|
1034
|
-
width : npt.NDArray[np.
|
|
1047
|
+
width : npt.NDArray[np.floating]
|
|
1035
1048
|
Contrail width, [:math:`m`]
|
|
1036
1049
|
|
|
1037
1050
|
Returns
|
|
1038
1051
|
-------
|
|
1039
|
-
npt.NDArray[np.
|
|
1052
|
+
npt.NDArray[np.floating]
|
|
1040
1053
|
Contrail optical depth
|
|
1041
1054
|
"""
|
|
1042
1055
|
q_ext = scattering_extinction_efficiency(r_ice_vol)
|
|
@@ -1048,18 +1061,20 @@ def contrail_optical_depth(
|
|
|
1048
1061
|
return tau_contrail
|
|
1049
1062
|
|
|
1050
1063
|
|
|
1051
|
-
def scattering_extinction_efficiency(
|
|
1064
|
+
def scattering_extinction_efficiency(
|
|
1065
|
+
r_ice_vol: npt.NDArray[np.floating],
|
|
1066
|
+
) -> npt.NDArray[np.floating]:
|
|
1052
1067
|
"""
|
|
1053
1068
|
Calculate the scattering extinction efficiency (``q_ext``) based on Mie-theory.
|
|
1054
1069
|
|
|
1055
1070
|
Parameters
|
|
1056
1071
|
----------
|
|
1057
|
-
r_ice_vol : npt.NDArray[np.
|
|
1072
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
1058
1073
|
ice particle volume mean radius, [:math:`m`]
|
|
1059
1074
|
|
|
1060
1075
|
Returns
|
|
1061
1076
|
-------
|
|
1062
|
-
npt.NDArray[np.
|
|
1077
|
+
npt.NDArray[np.floating]
|
|
1063
1078
|
scattering extinction efficiency
|
|
1064
1079
|
|
|
1065
1080
|
References
|
|
@@ -1072,18 +1087,18 @@ def scattering_extinction_efficiency(r_ice_vol: npt.NDArray[np.float64]) -> npt.
|
|
|
1072
1087
|
)
|
|
1073
1088
|
|
|
1074
1089
|
|
|
1075
|
-
def light_wave_phase_delay(r_ice_vol: npt.NDArray[np.
|
|
1090
|
+
def light_wave_phase_delay(r_ice_vol: npt.NDArray[np.floating]) -> npt.NDArray[np.floating]:
|
|
1076
1091
|
"""
|
|
1077
1092
|
Calculate the phase delay of the light wave passing through the contrail ice particle.
|
|
1078
1093
|
|
|
1079
1094
|
Parameters
|
|
1080
1095
|
----------
|
|
1081
|
-
r_ice_vol : npt.NDArray[np.
|
|
1096
|
+
r_ice_vol : npt.NDArray[np.floating]
|
|
1082
1097
|
ice particle volume mean radius, [:math:`m`]
|
|
1083
1098
|
|
|
1084
1099
|
Returns
|
|
1085
1100
|
-------
|
|
1086
|
-
npt.NDArray[np.
|
|
1101
|
+
npt.NDArray[np.floating]
|
|
1087
1102
|
phase delay of the light wave passing through the contrail ice particle
|
|
1088
1103
|
|
|
1089
1104
|
References
|
|
@@ -1103,21 +1118,21 @@ def light_wave_phase_delay(r_ice_vol: npt.NDArray[np.float64]) -> npt.NDArray[np
|
|
|
1103
1118
|
|
|
1104
1119
|
|
|
1105
1120
|
def segment_length_ratio(
|
|
1106
|
-
seg_length_t1: npt.NDArray[np.
|
|
1107
|
-
seg_length_t2: npt.NDArray[np.
|
|
1108
|
-
) -> npt.NDArray[np.
|
|
1121
|
+
seg_length_t1: npt.NDArray[np.floating],
|
|
1122
|
+
seg_length_t2: npt.NDArray[np.floating],
|
|
1123
|
+
) -> npt.NDArray[np.floating]:
|
|
1109
1124
|
"""Calculate the ratio of contrail segment length pre-advection to post-advection.
|
|
1110
1125
|
|
|
1111
1126
|
Parameters
|
|
1112
1127
|
----------
|
|
1113
|
-
seg_length_t1 : npt.NDArray[np.
|
|
1128
|
+
seg_length_t1 : npt.NDArray[np.floating]
|
|
1114
1129
|
Segment length of contrail waypoint at the start of the time step, [:math:`m`]
|
|
1115
|
-
seg_length_t2 : npt.NDArray[np.
|
|
1130
|
+
seg_length_t2 : npt.NDArray[np.floating]
|
|
1116
1131
|
Segment length of contrail waypoint after time step and advection, [:math:`m`]
|
|
1117
1132
|
|
|
1118
1133
|
Returns
|
|
1119
1134
|
-------
|
|
1120
|
-
npt.NDArray[np.
|
|
1135
|
+
npt.NDArray[np.floating]
|
|
1121
1136
|
Ratio of segment length before advection to segment length after advection.
|
|
1122
1137
|
|
|
1123
1138
|
Notes
|
|
@@ -1146,16 +1161,16 @@ def segment_length_ratio(
|
|
|
1146
1161
|
|
|
1147
1162
|
|
|
1148
1163
|
def plume_temporal_evolution(
|
|
1149
|
-
width_t1: npt.NDArray[np.
|
|
1150
|
-
depth_t1: npt.NDArray[np.
|
|
1151
|
-
sigma_yz_t1: npt.NDArray[np.
|
|
1152
|
-
dsn_dz_t1: npt.NDArray[np.
|
|
1153
|
-
diffuse_h_t1: npt.NDArray[np.
|
|
1154
|
-
diffuse_v_t1: npt.NDArray[np.
|
|
1155
|
-
seg_ratio: npt.NDArray[np.
|
|
1164
|
+
width_t1: npt.NDArray[np.floating],
|
|
1165
|
+
depth_t1: npt.NDArray[np.floating],
|
|
1166
|
+
sigma_yz_t1: npt.NDArray[np.floating],
|
|
1167
|
+
dsn_dz_t1: npt.NDArray[np.floating],
|
|
1168
|
+
diffuse_h_t1: npt.NDArray[np.floating],
|
|
1169
|
+
diffuse_v_t1: npt.NDArray[np.floating],
|
|
1170
|
+
seg_ratio: npt.NDArray[np.floating] | float,
|
|
1156
1171
|
dt: npt.NDArray[np.timedelta64] | np.timedelta64,
|
|
1157
1172
|
max_depth: float | None,
|
|
1158
|
-
) -> tuple[npt.NDArray[np.
|
|
1173
|
+
) -> tuple[npt.NDArray[np.floating], npt.NDArray[np.floating], npt.NDArray[np.floating]]:
|
|
1159
1174
|
"""
|
|
1160
1175
|
Calculate the temporal evolution of the contrail plume parameters.
|
|
1161
1176
|
|
|
@@ -1163,13 +1178,13 @@ def plume_temporal_evolution(
|
|
|
1163
1178
|
|
|
1164
1179
|
Parameters
|
|
1165
1180
|
----------
|
|
1166
|
-
width_t1 : npt.NDArray[np.
|
|
1181
|
+
width_t1 : npt.NDArray[np.floating]
|
|
1167
1182
|
contrail width at the start of the time step, [:math:`m`]
|
|
1168
|
-
depth_t1 : npt.NDArray[np.
|
|
1183
|
+
depth_t1 : npt.NDArray[np.floating]
|
|
1169
1184
|
contrail depth at the start of the time step, [:math:`m`]
|
|
1170
|
-
sigma_yz_t1 : npt.NDArray[np.
|
|
1185
|
+
sigma_yz_t1 : npt.NDArray[np.floating]
|
|
1171
1186
|
sigma_yz governs the contrail plume's temporal evolution at the start of the time step
|
|
1172
|
-
dsn_dz_t1 : npt.NDArray[np.
|
|
1187
|
+
dsn_dz_t1 : npt.NDArray[np.floating]
|
|
1173
1188
|
vertical gradient of the horizontal velocity (wind shear) normal to the contrail axis
|
|
1174
1189
|
at the start of the time step, [:math:`m s^{-1} / Pa`]::
|
|
1175
1190
|
|
|
@@ -1178,11 +1193,11 @@ def plume_temporal_evolution(
|
|
|
1178
1193
|
| (dsn_dz) | <-- (dsn_dz)
|
|
1179
1194
|
| |
|
|
1180
1195
|
X
|
|
1181
|
-
diffuse_h_t1 : npt.NDArray[np.
|
|
1196
|
+
diffuse_h_t1 : npt.NDArray[np.floating]
|
|
1182
1197
|
horizontal diffusivity at the start of the time step, [:math:`m^{2} s^{-1}`]
|
|
1183
|
-
diffuse_v_t1 : npt.NDArray[np.
|
|
1198
|
+
diffuse_v_t1 : npt.NDArray[np.floating]
|
|
1184
1199
|
vertical diffusivity at the start of the time step, [:math:`m^{2} s^{-1}`]
|
|
1185
|
-
seg_ratio : npt.NDArray[np.
|
|
1200
|
+
seg_ratio : npt.NDArray[np.floating] | float
|
|
1186
1201
|
Segment length ratio before and after it is advected to the new location.
|
|
1187
1202
|
See :func:`segment_length_ratio`.
|
|
1188
1203
|
dt : npt.NDArray[np.timedelta64] | np.timedelta64
|
|
@@ -1193,11 +1208,11 @@ def plume_temporal_evolution(
|
|
|
1193
1208
|
|
|
1194
1209
|
Returns
|
|
1195
1210
|
-------
|
|
1196
|
-
sigma_yy_t2 : npt.NDArray[np.
|
|
1211
|
+
sigma_yy_t2 : npt.NDArray[np.floating]
|
|
1197
1212
|
The ``yy`` component of convariance matrix, [:math:`m^{2}`]
|
|
1198
|
-
sigma_zz_t2 : npt.NDArray[np.
|
|
1213
|
+
sigma_zz_t2 : npt.NDArray[np.floating]
|
|
1199
1214
|
The ``zz`` component of convariance matrix, [:math:`m^{2}`]
|
|
1200
|
-
sigma_yz_t2 : npt.NDArray[np.
|
|
1215
|
+
sigma_yz_t2 : npt.NDArray[np.floating]
|
|
1201
1216
|
The ``yz`` component of convariance matrix, [:math:`m^{2}`]
|
|
1202
1217
|
"""
|
|
1203
1218
|
# Convert dt to seconds value and use dtype of other variables
|
|
@@ -1242,26 +1257,26 @@ def plume_temporal_evolution(
|
|
|
1242
1257
|
|
|
1243
1258
|
|
|
1244
1259
|
def new_contrail_dimensions(
|
|
1245
|
-
sigma_yy_t2: npt.NDArray[np.
|
|
1246
|
-
sigma_zz_t2: npt.NDArray[np.
|
|
1247
|
-
) -> tuple[npt.NDArray[np.
|
|
1260
|
+
sigma_yy_t2: npt.NDArray[np.floating],
|
|
1261
|
+
sigma_zz_t2: npt.NDArray[np.floating],
|
|
1262
|
+
) -> tuple[npt.NDArray[np.floating], npt.NDArray[np.floating]]:
|
|
1248
1263
|
"""
|
|
1249
1264
|
Calculate the new contrail width and depth.
|
|
1250
1265
|
|
|
1251
1266
|
Parameters
|
|
1252
1267
|
----------
|
|
1253
|
-
sigma_yy_t2 : npt.NDArray[np.
|
|
1268
|
+
sigma_yy_t2 : npt.NDArray[np.floating]
|
|
1254
1269
|
element yy, covariance matrix of the Gaussian concentration
|
|
1255
1270
|
field, Eq. (6) of Schumann (2012)
|
|
1256
|
-
sigma_zz_t2 : npt.NDArray[np.
|
|
1271
|
+
sigma_zz_t2 : npt.NDArray[np.floating]
|
|
1257
1272
|
element zz, covariance matrix of the Gaussian concentration
|
|
1258
1273
|
field, Eq. (6) of Schumann (2012)
|
|
1259
1274
|
|
|
1260
1275
|
Returns
|
|
1261
1276
|
-------
|
|
1262
|
-
width_t2 : npt.NDArray[np.
|
|
1277
|
+
width_t2 : npt.NDArray[np.floating]
|
|
1263
1278
|
Contrail width at the end of the time step, [:math:`m`]
|
|
1264
|
-
depth_t2 : npt.NDArray[np.
|
|
1279
|
+
depth_t2 : npt.NDArray[np.floating]
|
|
1265
1280
|
Contrail depth at the end of the time step, [:math:`m`]
|
|
1266
1281
|
"""
|
|
1267
1282
|
width_t2 = (8 * sigma_yy_t2) ** 0.5
|
|
@@ -1270,10 +1285,10 @@ def new_contrail_dimensions(
|
|
|
1270
1285
|
|
|
1271
1286
|
|
|
1272
1287
|
def new_effective_area_from_sigma(
|
|
1273
|
-
sigma_yy: npt.NDArray[np.
|
|
1274
|
-
sigma_zz: npt.NDArray[np.
|
|
1275
|
-
sigma_yz: npt.NDArray[np.
|
|
1276
|
-
) -> npt.NDArray[np.
|
|
1288
|
+
sigma_yy: npt.NDArray[np.floating],
|
|
1289
|
+
sigma_zz: npt.NDArray[np.floating],
|
|
1290
|
+
sigma_yz: npt.NDArray[np.floating] | float,
|
|
1291
|
+
) -> npt.NDArray[np.floating]:
|
|
1277
1292
|
"""
|
|
1278
1293
|
Calculate effective cross-sectional area of contrail plume (``area_eff``) from sigma parameters.
|
|
1279
1294
|
|
|
@@ -1282,19 +1297,19 @@ def new_effective_area_from_sigma(
|
|
|
1282
1297
|
|
|
1283
1298
|
Parameters
|
|
1284
1299
|
----------
|
|
1285
|
-
sigma_yy : npt.NDArray[np.
|
|
1300
|
+
sigma_yy : npt.NDArray[np.floating]
|
|
1286
1301
|
element yy, covariance matrix of the Gaussian concentration
|
|
1287
1302
|
field, Eq. (6) of Schumann (2012)
|
|
1288
|
-
sigma_zz : npt.NDArray[np.
|
|
1303
|
+
sigma_zz : npt.NDArray[np.floating]
|
|
1289
1304
|
element zz, covariance matrix of the Gaussian concentration
|
|
1290
1305
|
field, Eq. (6) of Schumann (2012)
|
|
1291
|
-
sigma_yz : npt.NDArray[np.
|
|
1306
|
+
sigma_yz : npt.NDArray[np.floating] | float
|
|
1292
1307
|
element yz, covariance matrix of the Gaussian concentration
|
|
1293
1308
|
field, Eq. (6) of Schumann (2012)
|
|
1294
1309
|
|
|
1295
1310
|
Returns
|
|
1296
1311
|
-------
|
|
1297
|
-
npt.NDArray[np.
|
|
1312
|
+
npt.NDArray[np.floating]
|
|
1298
1313
|
Effective cross-sectional area of the contrail plume (area_eff)
|
|
1299
1314
|
"""
|
|
1300
1315
|
det_sigma = sigma_yy * sigma_zz - sigma_yz**2
|
|
@@ -1302,44 +1317,44 @@ def new_effective_area_from_sigma(
|
|
|
1302
1317
|
|
|
1303
1318
|
|
|
1304
1319
|
def new_ice_water_content(
|
|
1305
|
-
iwc_t1: npt.NDArray[np.
|
|
1306
|
-
q_t1: npt.NDArray[np.
|
|
1307
|
-
q_t2: npt.NDArray[np.
|
|
1308
|
-
q_sat_t1: npt.NDArray[np.
|
|
1309
|
-
q_sat_t2: npt.NDArray[np.
|
|
1310
|
-
mass_plume_t1: npt.NDArray[np.
|
|
1311
|
-
mass_plume_t2: npt.NDArray[np.
|
|
1312
|
-
) -> npt.NDArray[np.
|
|
1320
|
+
iwc_t1: npt.NDArray[np.floating],
|
|
1321
|
+
q_t1: npt.NDArray[np.floating],
|
|
1322
|
+
q_t2: npt.NDArray[np.floating],
|
|
1323
|
+
q_sat_t1: npt.NDArray[np.floating],
|
|
1324
|
+
q_sat_t2: npt.NDArray[np.floating],
|
|
1325
|
+
mass_plume_t1: npt.NDArray[np.floating],
|
|
1326
|
+
mass_plume_t2: npt.NDArray[np.floating],
|
|
1327
|
+
) -> npt.NDArray[np.floating]:
|
|
1313
1328
|
"""
|
|
1314
1329
|
Calculate the new contrail ice water content after the time integration step (``iwc_t2``).
|
|
1315
1330
|
|
|
1316
1331
|
Parameters
|
|
1317
1332
|
----------
|
|
1318
|
-
iwc_t1 : npt.NDArray[np.
|
|
1333
|
+
iwc_t1 : npt.NDArray[np.floating]
|
|
1319
1334
|
contrail ice water content, i.e., contrail ice mass per kg of air,
|
|
1320
1335
|
at the start of the time step, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
1321
|
-
q_t1 : npt.NDArray[np.
|
|
1336
|
+
q_t1 : npt.NDArray[np.floating]
|
|
1322
1337
|
specific humidity for each waypoint at the start of the
|
|
1323
1338
|
time step, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
1324
|
-
q_t2 : npt.NDArray[np.
|
|
1339
|
+
q_t2 : npt.NDArray[np.floating]
|
|
1325
1340
|
specific humidity for each waypoint at the end of the
|
|
1326
1341
|
time step, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
1327
|
-
q_sat_t1 : npt.NDArray[np.
|
|
1342
|
+
q_sat_t1 : npt.NDArray[np.floating]
|
|
1328
1343
|
saturation humidity for each waypoint at the start of the
|
|
1329
1344
|
time step, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
1330
|
-
q_sat_t2 : npt.NDArray[np.
|
|
1345
|
+
q_sat_t2 : npt.NDArray[np.floating]
|
|
1331
1346
|
saturation humidity for each waypoint at the end of the
|
|
1332
1347
|
time step, [:math:`kg_{H_{2}O}/kg_{air}`]
|
|
1333
|
-
mass_plume_t1 : npt.NDArray[np.
|
|
1348
|
+
mass_plume_t1 : npt.NDArray[np.floating]
|
|
1334
1349
|
contrail plume mass per unit length at the start of the
|
|
1335
1350
|
time step, [:math:`kg_{air} m^{-1}`]
|
|
1336
|
-
mass_plume_t2 : npt.NDArray[np.
|
|
1351
|
+
mass_plume_t2 : npt.NDArray[np.floating]
|
|
1337
1352
|
contrail plume mass per unit length at the end of the
|
|
1338
1353
|
time step, [:math:`kg_{air} m^{-1}`]
|
|
1339
1354
|
|
|
1340
1355
|
Returns
|
|
1341
1356
|
-------
|
|
1342
|
-
npt.NDArray[np.
|
|
1357
|
+
npt.NDArray[np.floating]
|
|
1343
1358
|
Contrail ice water content at the end of the time step, [:math:`kg_{ice} kg_{air}^{-1}`]
|
|
1344
1359
|
|
|
1345
1360
|
Notes
|
|
@@ -1363,31 +1378,31 @@ def new_ice_water_content(
|
|
|
1363
1378
|
|
|
1364
1379
|
|
|
1365
1380
|
def new_ice_particle_number(
|
|
1366
|
-
n_ice_per_m_t1: npt.NDArray[np.
|
|
1367
|
-
dn_dt_agg: npt.NDArray[np.
|
|
1368
|
-
dn_dt_turb: npt.NDArray[np.
|
|
1369
|
-
seg_ratio: npt.NDArray[np.
|
|
1381
|
+
n_ice_per_m_t1: npt.NDArray[np.floating],
|
|
1382
|
+
dn_dt_agg: npt.NDArray[np.floating],
|
|
1383
|
+
dn_dt_turb: npt.NDArray[np.floating],
|
|
1384
|
+
seg_ratio: npt.NDArray[np.floating] | float,
|
|
1370
1385
|
dt: npt.NDArray[np.timedelta64] | np.timedelta64,
|
|
1371
|
-
) -> npt.NDArray[np.
|
|
1386
|
+
) -> npt.NDArray[np.floating]:
|
|
1372
1387
|
"""Calculate the number of ice particles per distance at the end of the time step.
|
|
1373
1388
|
|
|
1374
1389
|
Parameters
|
|
1375
1390
|
----------
|
|
1376
|
-
n_ice_per_m_t1 : npt.NDArray[np.
|
|
1391
|
+
n_ice_per_m_t1 : npt.NDArray[np.floating]
|
|
1377
1392
|
number of contrail ice particles per distance at the start of
|
|
1378
1393
|
the time step, [:math:`m^{-1}`]
|
|
1379
|
-
dn_dt_agg : npt.NDArray[np.
|
|
1394
|
+
dn_dt_agg : npt.NDArray[np.floating]
|
|
1380
1395
|
rate of ice particle losses due to sedimentation-induced aggregation, [:math:`# s^{-1}`]
|
|
1381
|
-
dn_dt_turb : npt.NDArray[np.
|
|
1396
|
+
dn_dt_turb : npt.NDArray[np.floating]
|
|
1382
1397
|
rate of contrail ice particle losses due to plume-internal turbulence, [:math:`# s^{-1}`]
|
|
1383
|
-
seg_ratio : npt.NDArray[np.
|
|
1398
|
+
seg_ratio : npt.NDArray[np.floating] | float
|
|
1384
1399
|
Segment length ratio before and after it is advected to the new location.
|
|
1385
1400
|
dt : npt.NDArray[np.timedelta64] | np.timedelta64
|
|
1386
1401
|
integrate contrails with time steps of dt, [:math:`s`]
|
|
1387
1402
|
|
|
1388
1403
|
Returns
|
|
1389
1404
|
-------
|
|
1390
|
-
npt.NDArray[np.
|
|
1405
|
+
npt.NDArray[np.floating]
|
|
1391
1406
|
number of ice particles per distance at the end of the time step, [:math:`m^{-1}`]
|
|
1392
1407
|
"""
|
|
1393
1408
|
# Convert dt to seconds value and use dtype of other variables
|
|
@@ -1416,13 +1431,13 @@ def new_ice_particle_number(
|
|
|
1416
1431
|
|
|
1417
1432
|
|
|
1418
1433
|
def energy_forcing(
|
|
1419
|
-
rf_net_t1: npt.NDArray[np.
|
|
1420
|
-
rf_net_t2: npt.NDArray[np.
|
|
1421
|
-
width_t1: npt.NDArray[np.
|
|
1422
|
-
width_t2: npt.NDArray[np.
|
|
1423
|
-
seg_length_t2: npt.NDArray[np.
|
|
1434
|
+
rf_net_t1: npt.NDArray[np.floating],
|
|
1435
|
+
rf_net_t2: npt.NDArray[np.floating],
|
|
1436
|
+
width_t1: npt.NDArray[np.floating],
|
|
1437
|
+
width_t2: npt.NDArray[np.floating],
|
|
1438
|
+
seg_length_t2: npt.NDArray[np.floating] | float,
|
|
1424
1439
|
dt: npt.NDArray[np.timedelta64] | np.timedelta64,
|
|
1425
|
-
) -> npt.NDArray[np.
|
|
1440
|
+
) -> npt.NDArray[np.floating]:
|
|
1426
1441
|
"""Calculate the contrail energy forcing over time step.
|
|
1427
1442
|
|
|
1428
1443
|
The contrail energy forcing is calculated as the local contrail net
|
|
@@ -1431,22 +1446,22 @@ def energy_forcing(
|
|
|
1431
1446
|
|
|
1432
1447
|
Parameters
|
|
1433
1448
|
----------
|
|
1434
|
-
rf_net_t1 : npt.NDArray[np.
|
|
1449
|
+
rf_net_t1 : npt.NDArray[np.floating]
|
|
1435
1450
|
local contrail net radiative forcing at the start of the time step, [:math:`W m^{-2}`]
|
|
1436
|
-
rf_net_t2 : npt.NDArray[np.
|
|
1451
|
+
rf_net_t2 : npt.NDArray[np.floating]
|
|
1437
1452
|
local contrail net radiative forcing at the end of the time step, [:math:`W m^{-2}`]
|
|
1438
|
-
width_t1 : npt.NDArray[np.
|
|
1453
|
+
width_t1 : npt.NDArray[np.floating]
|
|
1439
1454
|
contrail width at the start of the time step, [:math:`m`]
|
|
1440
|
-
width_t2 : npt.NDArray[np.
|
|
1455
|
+
width_t2 : npt.NDArray[np.floating]
|
|
1441
1456
|
contrail width at the end of the time step, [:math:`m`]
|
|
1442
|
-
seg_length_t2 : npt.NDArray[np.
|
|
1457
|
+
seg_length_t2 : npt.NDArray[np.floating] | float
|
|
1443
1458
|
Segment length of contrail waypoint at the end of the time step, [:math:`m`]
|
|
1444
1459
|
dt : npt.NDArray[np.timedelta64] | np.timedelta64
|
|
1445
1460
|
integrate contrails with time steps of dt, [:math:`s`]
|
|
1446
1461
|
|
|
1447
1462
|
Returns
|
|
1448
1463
|
-------
|
|
1449
|
-
npt.NDArray[np.
|
|
1464
|
+
npt.NDArray[np.floating]
|
|
1450
1465
|
Contrail energy forcing over time step dt, [:math:`J`].
|
|
1451
1466
|
"""
|
|
1452
1467
|
rad_flux_per_m = mean_radiative_flux_per_m(rf_net_t1, rf_net_t2, width_t1, width_t2)
|
|
@@ -1455,27 +1470,27 @@ def energy_forcing(
|
|
|
1455
1470
|
|
|
1456
1471
|
|
|
1457
1472
|
def mean_radiative_flux_per_m(
|
|
1458
|
-
rf_net_t1: npt.NDArray[np.
|
|
1459
|
-
rf_net_t2: npt.NDArray[np.
|
|
1460
|
-
width_t1: npt.NDArray[np.
|
|
1461
|
-
width_t2: npt.NDArray[np.
|
|
1462
|
-
) -> npt.NDArray[np.
|
|
1473
|
+
rf_net_t1: npt.NDArray[np.floating],
|
|
1474
|
+
rf_net_t2: npt.NDArray[np.floating],
|
|
1475
|
+
width_t1: npt.NDArray[np.floating],
|
|
1476
|
+
width_t2: npt.NDArray[np.floating],
|
|
1477
|
+
) -> npt.NDArray[np.floating]:
|
|
1463
1478
|
"""Calculate the mean radiative flux per length of contrail between two time steps.
|
|
1464
1479
|
|
|
1465
1480
|
Parameters
|
|
1466
1481
|
----------
|
|
1467
|
-
rf_net_t1 : npt.NDArray[np.
|
|
1482
|
+
rf_net_t1 : npt.NDArray[np.floating]
|
|
1468
1483
|
local contrail net radiative forcing at the start of the time step, [:math:`W m^{-2}`]
|
|
1469
|
-
rf_net_t2 : npt.NDArray[np.
|
|
1484
|
+
rf_net_t2 : npt.NDArray[np.floating]
|
|
1470
1485
|
local contrail net radiative forcing at the end of the time step, [:math:`W m^{-2}`]
|
|
1471
|
-
width_t1 : npt.NDArray[np.
|
|
1486
|
+
width_t1 : npt.NDArray[np.floating]
|
|
1472
1487
|
contrail width at the start of the time step, [:math:`m`]
|
|
1473
|
-
width_t2 : npt.NDArray[np.
|
|
1488
|
+
width_t2 : npt.NDArray[np.floating]
|
|
1474
1489
|
contrail width at the end of the time step, [:math:`m`]
|
|
1475
1490
|
|
|
1476
1491
|
Returns
|
|
1477
1492
|
-------
|
|
1478
|
-
npt.NDArray[np.
|
|
1493
|
+
npt.NDArray[np.floating]
|
|
1479
1494
|
Mean radiative flux between time steps, [:math:`W m^{-1}`]
|
|
1480
1495
|
"""
|
|
1481
1496
|
rad_flux_per_m_t1 = width_t1 * rf_net_t1
|
|
@@ -1484,13 +1499,13 @@ def mean_radiative_flux_per_m(
|
|
|
1484
1499
|
|
|
1485
1500
|
|
|
1486
1501
|
def mean_energy_flux_per_m(
|
|
1487
|
-
rad_flux_per_m: npt.NDArray[np.
|
|
1488
|
-
) -> npt.NDArray[np.
|
|
1502
|
+
rad_flux_per_m: npt.NDArray[np.floating], dt: npt.NDArray[np.timedelta64] | np.timedelta64
|
|
1503
|
+
) -> npt.NDArray[np.floating]:
|
|
1489
1504
|
"""Calculate the mean energy flux per length of contrail on segment following waypoint.
|
|
1490
1505
|
|
|
1491
1506
|
Parameters
|
|
1492
1507
|
----------
|
|
1493
|
-
rad_flux_per_m : npt.NDArray[np.
|
|
1508
|
+
rad_flux_per_m : npt.NDArray[np.floating]
|
|
1494
1509
|
Mean radiative flux between time steps for waypoint, [:math:`W m^{-1}`].
|
|
1495
1510
|
See :func:`mean_radiative_flux_per_m`.
|
|
1496
1511
|
dt : npt.NDArray[np.timedelta64]
|
|
@@ -1498,7 +1513,7 @@ def mean_energy_flux_per_m(
|
|
|
1498
1513
|
|
|
1499
1514
|
Returns
|
|
1500
1515
|
-------
|
|
1501
|
-
npt.NDArray[np.
|
|
1516
|
+
npt.NDArray[np.floating]
|
|
1502
1517
|
Mean energy flux per length of contrail after waypoint, [:math:`J m^{-1}`]
|
|
1503
1518
|
|
|
1504
1519
|
Notes
|