pycontrails 0.58.0__cp314-cp314-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 +70 -0
- pycontrails/_version.py +34 -0
- pycontrails/core/__init__.py +30 -0
- pycontrails/core/aircraft_performance.py +679 -0
- pycontrails/core/airports.py +228 -0
- pycontrails/core/cache.py +889 -0
- pycontrails/core/coordinates.py +174 -0
- pycontrails/core/fleet.py +483 -0
- pycontrails/core/flight.py +2185 -0
- pycontrails/core/flightplan.py +228 -0
- pycontrails/core/fuel.py +140 -0
- pycontrails/core/interpolation.py +702 -0
- pycontrails/core/met.py +2931 -0
- pycontrails/core/met_var.py +387 -0
- pycontrails/core/models.py +1321 -0
- pycontrails/core/polygon.py +549 -0
- pycontrails/core/rgi_cython.cpython-314-darwin.so +0 -0
- pycontrails/core/vector.py +2249 -0
- pycontrails/datalib/__init__.py +12 -0
- pycontrails/datalib/_met_utils/metsource.py +746 -0
- pycontrails/datalib/ecmwf/__init__.py +73 -0
- pycontrails/datalib/ecmwf/arco_era5.py +345 -0
- pycontrails/datalib/ecmwf/common.py +114 -0
- pycontrails/datalib/ecmwf/era5.py +554 -0
- pycontrails/datalib/ecmwf/era5_model_level.py +490 -0
- pycontrails/datalib/ecmwf/hres.py +804 -0
- pycontrails/datalib/ecmwf/hres_model_level.py +466 -0
- pycontrails/datalib/ecmwf/ifs.py +287 -0
- pycontrails/datalib/ecmwf/model_levels.py +435 -0
- pycontrails/datalib/ecmwf/static/model_level_dataframe_v20240418.csv +139 -0
- pycontrails/datalib/ecmwf/variables.py +268 -0
- pycontrails/datalib/geo_utils.py +261 -0
- pycontrails/datalib/gfs/__init__.py +28 -0
- pycontrails/datalib/gfs/gfs.py +656 -0
- pycontrails/datalib/gfs/variables.py +104 -0
- pycontrails/datalib/goes.py +757 -0
- pycontrails/datalib/himawari/__init__.py +27 -0
- pycontrails/datalib/himawari/header_struct.py +266 -0
- pycontrails/datalib/himawari/himawari.py +667 -0
- pycontrails/datalib/landsat.py +589 -0
- pycontrails/datalib/leo_utils/__init__.py +5 -0
- pycontrails/datalib/leo_utils/correction.py +266 -0
- pycontrails/datalib/leo_utils/landsat_metadata.py +300 -0
- pycontrails/datalib/leo_utils/search.py +250 -0
- pycontrails/datalib/leo_utils/sentinel_metadata.py +748 -0
- pycontrails/datalib/leo_utils/static/bq_roi_query.sql +6 -0
- pycontrails/datalib/leo_utils/vis.py +59 -0
- pycontrails/datalib/sentinel.py +650 -0
- pycontrails/datalib/spire/__init__.py +5 -0
- pycontrails/datalib/spire/exceptions.py +62 -0
- pycontrails/datalib/spire/spire.py +604 -0
- pycontrails/ext/bada.py +42 -0
- pycontrails/ext/cirium.py +14 -0
- pycontrails/ext/empirical_grid.py +140 -0
- pycontrails/ext/synthetic_flight.py +431 -0
- pycontrails/models/__init__.py +1 -0
- pycontrails/models/accf.py +425 -0
- pycontrails/models/apcemm/__init__.py +8 -0
- pycontrails/models/apcemm/apcemm.py +983 -0
- pycontrails/models/apcemm/inputs.py +226 -0
- pycontrails/models/apcemm/static/apcemm_yaml_template.yaml +183 -0
- pycontrails/models/apcemm/utils.py +437 -0
- pycontrails/models/cocip/__init__.py +29 -0
- pycontrails/models/cocip/cocip.py +2742 -0
- pycontrails/models/cocip/cocip_params.py +305 -0
- pycontrails/models/cocip/cocip_uncertainty.py +291 -0
- pycontrails/models/cocip/contrail_properties.py +1530 -0
- pycontrails/models/cocip/output_formats.py +2270 -0
- pycontrails/models/cocip/radiative_forcing.py +1260 -0
- pycontrails/models/cocip/radiative_heating.py +520 -0
- pycontrails/models/cocip/unterstrasser_wake_vortex.py +508 -0
- pycontrails/models/cocip/wake_vortex.py +396 -0
- pycontrails/models/cocip/wind_shear.py +120 -0
- pycontrails/models/cocipgrid/__init__.py +9 -0
- pycontrails/models/cocipgrid/cocip_grid.py +2552 -0
- pycontrails/models/cocipgrid/cocip_grid_params.py +138 -0
- pycontrails/models/dry_advection.py +602 -0
- pycontrails/models/emissions/__init__.py +21 -0
- pycontrails/models/emissions/black_carbon.py +599 -0
- pycontrails/models/emissions/emissions.py +1353 -0
- pycontrails/models/emissions/ffm2.py +336 -0
- pycontrails/models/emissions/static/default-engine-uids.csv +239 -0
- pycontrails/models/emissions/static/edb-gaseous-v29b-engines.csv +596 -0
- pycontrails/models/emissions/static/edb-nvpm-v29b-engines.csv +215 -0
- pycontrails/models/extended_k15.py +1327 -0
- pycontrails/models/humidity_scaling/__init__.py +37 -0
- pycontrails/models/humidity_scaling/humidity_scaling.py +1075 -0
- pycontrails/models/humidity_scaling/quantiles/era5-model-level-quantiles.pq +0 -0
- pycontrails/models/humidity_scaling/quantiles/era5-pressure-level-quantiles.pq +0 -0
- pycontrails/models/issr.py +210 -0
- pycontrails/models/pcc.py +326 -0
- pycontrails/models/pcr.py +154 -0
- pycontrails/models/ps_model/__init__.py +18 -0
- pycontrails/models/ps_model/ps_aircraft_params.py +381 -0
- pycontrails/models/ps_model/ps_grid.py +701 -0
- pycontrails/models/ps_model/ps_model.py +1000 -0
- pycontrails/models/ps_model/ps_operational_limits.py +525 -0
- pycontrails/models/ps_model/static/ps-aircraft-params-20250328.csv +69 -0
- pycontrails/models/ps_model/static/ps-synonym-list-20250328.csv +104 -0
- pycontrails/models/sac.py +442 -0
- pycontrails/models/tau_cirrus.py +183 -0
- pycontrails/physics/__init__.py +1 -0
- pycontrails/physics/constants.py +117 -0
- pycontrails/physics/geo.py +1138 -0
- pycontrails/physics/jet.py +968 -0
- pycontrails/physics/static/iata-cargo-load-factors-20250221.csv +74 -0
- pycontrails/physics/static/iata-passenger-load-factors-20250221.csv +74 -0
- pycontrails/physics/thermo.py +551 -0
- pycontrails/physics/units.py +472 -0
- pycontrails/py.typed +0 -0
- pycontrails/utils/__init__.py +1 -0
- pycontrails/utils/dependencies.py +66 -0
- pycontrails/utils/iteration.py +13 -0
- pycontrails/utils/json.py +187 -0
- pycontrails/utils/temp.py +50 -0
- pycontrails/utils/types.py +163 -0
- pycontrails-0.58.0.dist-info/METADATA +180 -0
- pycontrails-0.58.0.dist-info/RECORD +122 -0
- pycontrails-0.58.0.dist-info/WHEEL +6 -0
- pycontrails-0.58.0.dist-info/licenses/LICENSE +178 -0
- pycontrails-0.58.0.dist-info/licenses/NOTICE +43 -0
- pycontrails-0.58.0.dist-info/top_level.txt +3 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Date,Global,Africa,Asia Pacific,Europe,Latin America,Middle East,North America
|
|
2
|
+
15/12/2018,0.488,0.381,0.54,0.567,0.291,0.488,0.414
|
|
3
|
+
15/1/2019,0.451,0.354,0.501,0.501,0.299,0.421,0.4
|
|
4
|
+
15/2/2019,0.447,0.363,0.473,0.53,0.297,0.466,0.379
|
|
5
|
+
15/3/2019,0.495,0.384,0.556,0.56,0.323,0.488,0.416
|
|
6
|
+
15/4/2019,0.463,0.374,0.518,0.496,0.325,0.458,0.405
|
|
7
|
+
15/5/2019,0.468,0.386,0.52,0.513,0.353,0.469,0.398
|
|
8
|
+
15/6/2019,0.454,0.324,0.522,0.498,0.337,0.44,0.382
|
|
9
|
+
15/7/2019,0.45,0.323,0.519,0.485,0.354,0.453,0.373
|
|
10
|
+
15/8/2019,0.446,0.302,0.516,0.477,0.372,0.435,0.377
|
|
11
|
+
15/9/2019,0.464,0.329,0.539,0.501,0.379,0.459,0.381
|
|
12
|
+
15/10/2019,0.477,0.361,0.539,0.533,0.364,0.477,0.394
|
|
13
|
+
15/11/2019,0.496,0.404,0.538,0.569,0.403,0.497,0.413
|
|
14
|
+
15/12/2019,0.467,0.368,0.519,0.53,0.3,0.47,0.395
|
|
15
|
+
15/1/2020,0.45,0.356,0.474,0.501,0.311,0.426,0.424
|
|
16
|
+
15/2/2020,0.464,0.368,0.543,0.531,0.342,0.461,0.372
|
|
17
|
+
15/3/2020,0.545,0.425,0.656,0.63,0.411,0.532,0.429
|
|
18
|
+
15/4/2020,0.58,0.486,0.691,0.648,0.554,0.525,0.487
|
|
19
|
+
15/5/2020,0.576,0.612,0.643,0.625,0.561,0.483,0.526
|
|
20
|
+
15/6/2020,0.573,0.547,0.645,0.62,0.512,0.494,0.521
|
|
21
|
+
15/7/2020,0.564,0.489,0.639,0.594,0.464,0.53,0.506
|
|
22
|
+
15/8/2020,0.548,0.502,0.616,0.568,0.478,0.535,0.489
|
|
23
|
+
15/9/2020,0.569,0.507,0.642,0.62,0.456,0.579,0.484
|
|
24
|
+
15/10/2020,0.576,0.502,0.617,0.651,0.443,0.606,0.496
|
|
25
|
+
15/11/2020,0.582,0.496,0.631,0.655,0.436,0.6,0.5
|
|
26
|
+
15/12/2020,0.573,0.51,0.639,0.653,0.367,0.597,0.482
|
|
27
|
+
15/1/2021,0.589,0.48,0.665,0.627,0.39,0.569,0.532
|
|
28
|
+
15/2/2021,0.575,0.476,0.692,0.641,0.429,0.598,0.453
|
|
29
|
+
15/3/2021,0.588,0.499,0.661,0.685,0.453,0.613,0.472
|
|
30
|
+
15/4/2021,0.578,0.504,0.633,0.681,0.457,0.598,0.473
|
|
31
|
+
15/5/2021,0.572,0.502,0.646,0.656,0.423,0.589,0.469
|
|
32
|
+
15/6/2021,0.565,0.48,0.676,0.626,0.381,0.581,0.458
|
|
33
|
+
15/7/2021,0.544,0.455,0.654,0.598,0.387,0.536,0.443
|
|
34
|
+
15/8/2021,0.542,0.43,0.698,0.575,0.404,0.529,0.437
|
|
35
|
+
15/9/2021,0.553,0.428,0.68,0.604,0.37,0.558,0.447
|
|
36
|
+
15/10/2021,0.561,0.45,0.661,0.626,0.421,0.572,0.449
|
|
37
|
+
15/11/2021,0.559,0.434,0.654,0.631,0.446,0.572,0.444
|
|
38
|
+
15/12/2021,0.542,0.502,0.634,0.623,0.413,0.556,0.43
|
|
39
|
+
15/1/2022,0.541,0.492,0.609,0.584,0.417,0.513,0.474
|
|
40
|
+
15/2/2022,0.532,0.502,0.592,0.636,0.476,0.529,0.429
|
|
41
|
+
15/3/2022,0.549,0.494,0.638,0.671,0.448,0.526,0.442
|
|
42
|
+
15/4/2022,0.516,0.49,0.631,0.578,0.419,0.504,0.419
|
|
43
|
+
15/5/2022,0.505,0.495,0.627,0.548,0.387,0.487,0.411
|
|
44
|
+
15/6/2022,0.492,0.447,0.608,0.507,0.383,0.488,0.404
|
|
45
|
+
15/7/2022,0.472,0.452,0.563,0.493,0.374,0.469,0.398
|
|
46
|
+
15/8/2022,0.467,0.418,0.547,0.502,0.374,0.466,0.393
|
|
47
|
+
15/9/2022,0.481,0.451,0.572,0.528,0.381,0.478,0.396
|
|
48
|
+
15/10/2022,0.487,0.437,0.561,0.558,0.384,0.48,0.401
|
|
49
|
+
15/11/2022,0.491,0.458,0.545,0.569,0.382,0.475,0.419
|
|
50
|
+
15/12/2022,0.472,0.432,0.528,0.559,0.322,0.454,0.406
|
|
51
|
+
15/1/2023,0.448,0.439,0.452,0.541,0.325,0.411,0.423
|
|
52
|
+
15/2/2023,0.456,0.468,0.464,0.574,0.361,0.445,0.4
|
|
53
|
+
15/3/2023,0.462,0.489,0.485,0.57,0.366,0.456,0.393
|
|
54
|
+
15/4/2023,0.427,0.482,0.442,0.497,0.364,0.431,0.373
|
|
55
|
+
15/5/2023,0.415,0.448,0.422,0.489,0.333,0.41,0.373
|
|
56
|
+
15/6/2023,0.432,0.446,0.468,0.476,0.337,0.446,0.374
|
|
57
|
+
15/7/2023,0.421,0.417,0.457,0.472,0.322,0.411,0.37
|
|
58
|
+
15/8/2023,0.42,0.388,0.443,0.484,0.326,0.407,0.377
|
|
59
|
+
15/9/2023,0.438,0.436,0.466,0.5,0.319,0.424,0.392
|
|
60
|
+
15/10/2023,0.452,0.416,0.472,0.53,0.354,0.46,0.392
|
|
61
|
+
15/11/2023,0.467,0.421,0.479,0.57,0.363,0.469,0.408
|
|
62
|
+
15/12/2023,0.459,0.41,0.479,0.562,0.316,0.455,0.403
|
|
63
|
+
15/1/2024,0.457,0.431,0.446,0.555,0.344,0.439,0.435
|
|
64
|
+
15/2/2024,0.451,0.451,0.432,0.584,0.376,0.463,0.396
|
|
65
|
+
15/3/2024,0.473,0.473,0.475,0.581,0.402,0.496,0.404
|
|
66
|
+
15/4/2024,0.439,0.429,0.445,0.515,0.387,0.447,0.387
|
|
67
|
+
15/5/2024,0.446,0.438,0.453,0.518,0.362,0.461,0.397
|
|
68
|
+
15/6/2024,0.458,0.385,0.496,0.507,0.336,0.473,0.388
|
|
69
|
+
15/7/2024,0.444,0.4,0.48,0.496,0.338,0.458,0.382
|
|
70
|
+
15/8/2024,0.44,0.378,0.466,0.501,0.359,0.445,0.387
|
|
71
|
+
15/9/2024,0.456,0.392,0.485,0.525,0.368,0.474,0.389
|
|
72
|
+
15/10/2024,0.473,0.401,0.493,0.555,0.411,0.48,0.411
|
|
73
|
+
15/11/2024,0.49,0.425,0.5,0.576,0.396,0.494,0.438
|
|
74
|
+
15/12/2024,0.473,0.415,0.491,0.567,0.335,0.473,0.421
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
Date,Global,Africa,Asia Pacific,Europe,Latin America,Middle East,North America
|
|
2
|
+
15/12/2018,0.804,0.724,0.81,0.81,0.818,0.736,0.825
|
|
3
|
+
15/1/2019,0.796,0.709,0.81,0.796,0.825,0.76,0.795
|
|
4
|
+
15/2/2019,0.806,0.704,0.826,0.815,0.813,0.726,0.808
|
|
5
|
+
15/3/2019,0.817,0.72,0.812,0.837,0.815,0.739,0.85
|
|
6
|
+
15/4/2019,0.828,0.733,0.817,0.851,0.822,0.803,0.839
|
|
7
|
+
15/5/2019,0.815,0.676,0.802,0.837,0.832,0.732,0.851
|
|
8
|
+
15/6/2019,0.844,0.706,0.821,0.875,0.832,0.767,0.887
|
|
9
|
+
15/7/2019,0.857,0.735,0.831,0.89,0.853,0.812,0.888
|
|
10
|
+
15/8/2019,0.857,0.755,0.839,0.889,0.833,0.821,0.875
|
|
11
|
+
15/9/2019,0.819,0.721,0.801,0.866,0.819,0.75,0.828
|
|
12
|
+
15/10/2019,0.82,0.697,0.815,0.855,0.819,0.734,0.841
|
|
13
|
+
15/11/2019,0.818,0.708,0.813,0.833,0.822,0.732,0.828
|
|
14
|
+
15/12/2019,0.823,0.724,0.816,0.828,0.825,0.78,0.859
|
|
15
|
+
15/1/2020,0.803,0.702,0.799,0.816,0.826,0.785,0.812
|
|
16
|
+
15/2/2020,0.759,0.668,0.678,0.813,0.812,0.725,0.811
|
|
17
|
+
15/3/2020,0.606,0.609,0.589,0.67,0.681,0.599,0.557
|
|
18
|
+
15/4/2020,0.366,0.111,0.538,0.32,0.55,0.284,0.15
|
|
19
|
+
15/5/2020,0.507,0.071,0.62,0.427,0.623,0.255,0.381
|
|
20
|
+
15/6/2020,0.576,0.162,0.638,0.555,0.666,0.357,0.524
|
|
21
|
+
15/7/2020,0.579,0.296,0.657,0.609,0.631,0.396,0.476
|
|
22
|
+
15/8/2020,0.585,0.39,0.65,0.635,0.639,0.372,0.477
|
|
23
|
+
15/9/2020,0.601,0.378,0.692,0.586,0.706,0.365,0.525
|
|
24
|
+
15/10/2020,0.602,0.482,0.687,0.552,0.721,0.387,0.558
|
|
25
|
+
15/11/2020,0.58,0.474,0.664,0.523,0.74,0.372,0.518
|
|
26
|
+
15/12/2020,0.575,0.549,0.616,0.578,0.73,0.44,0.516
|
|
27
|
+
15/1/2021,0.541,0.544,0.566,0.576,0.685,0.422,0.484
|
|
28
|
+
15/2/2021,0.554,0.516,0.591,0.563,0.683,0.398,0.527
|
|
29
|
+
15/3/2021,0.623,0.53,0.669,0.593,0.708,0.422,0.624
|
|
30
|
+
15/4/2021,0.633,0.476,0.678,0.563,0.723,0.404,0.668
|
|
31
|
+
15/5/2021,0.658,0.53,0.678,0.593,0.768,0.389,0.728
|
|
32
|
+
15/6/2021,0.696,0.587,0.657,0.658,0.784,0.459,0.806
|
|
33
|
+
15/7/2021,0.731,0.614,0.675,0.725,0.793,0.513,0.841
|
|
34
|
+
15/8/2021,0.7,0.64,0.545,0.746,0.774,0.56,0.786
|
|
35
|
+
15/9/2021,0.676,0.56,0.605,0.719,0.773,0.524,0.727
|
|
36
|
+
15/10/2021,0.706,0.558,0.629,0.741,0.809,0.577,0.769
|
|
37
|
+
15/11/2021,0.713,0.616,0.597,0.752,0.822,0.616,0.786
|
|
38
|
+
15/12/2021,0.723,0.647,0.625,0.745,0.816,0.663,0.793
|
|
39
|
+
15/1/2022,0.645,0.623,0.576,0.682,0.782,0.591,0.663
|
|
40
|
+
15/2/2022,0.698,0.648,0.629,0.721,0.795,0.648,0.745
|
|
41
|
+
15/3/2022,0.747,0.657,0.642,0.739,0.808,0.718,0.839
|
|
42
|
+
15/4/2022,0.778,0.68,0.67,0.795,0.809,0.713,0.858
|
|
43
|
+
15/5/2022,0.794,0.696,0.696,0.807,0.807,0.762,0.86
|
|
44
|
+
15/6/2022,0.824,0.743,0.729,0.86,0.817,0.772,0.891
|
|
45
|
+
15/7/2022,0.835,0.753,0.764,0.87,0.831,0.812,0.882
|
|
46
|
+
15/8/2022,0.818,0.757,0.74,0.862,0.824,0.796,0.856
|
|
47
|
+
15/9/2022,0.816,0.743,0.747,0.847,0.823,0.795,0.855
|
|
48
|
+
15/10/2022,0.82,0.726,0.755,0.848,0.833,0.791,0.864
|
|
49
|
+
15/11/2022,0.808,0.748,0.77,0.838,0.82,0.775,0.832
|
|
50
|
+
15/12/2022,0.811,0.769,0.772,0.836,0.785,0.8,0.842
|
|
51
|
+
15/1/2023,0.777,0.742,0.774,0.762,0.813,0.791,0.784
|
|
52
|
+
15/2/2023,0.778,0.756,0.792,0.752,0.811,0.798,0.771
|
|
53
|
+
15/3/2023,0.807,0.739,0.792,0.805,0.812,0.794,0.837
|
|
54
|
+
15/4/2023,0.813,0.708,0.784,0.838,0.814,0.76,0.856
|
|
55
|
+
15/5/2023,0.818,0.699,0.773,0.848,0.811,0.799,0.863
|
|
56
|
+
15/6/2023,0.842,0.689,0.804,0.877,0.825,0.794,0.887
|
|
57
|
+
15/7/2023,0.852,0.746,0.816,0.877,0.867,0.821,0.897
|
|
58
|
+
15/8/2023,0.846,0.764,0.822,0.876,0.851,0.83,0.858
|
|
59
|
+
15/9/2023,0.826,0.731,0.8,0.86,0.839,0.816,0.83
|
|
60
|
+
15/10/2023,0.831,0.707,0.821,0.856,0.848,0.806,0.836
|
|
61
|
+
15/11/2023,0.818,0.704,0.814,0.837,0.844,0.777,0.827
|
|
62
|
+
15/12/2023,0.821,0.732,0.812,0.851,0.827,0.782,0.829
|
|
63
|
+
15/1/2024,0.799,0.731,0.808,0.782,0.85,0.799,0.799
|
|
64
|
+
15/2/2024,0.806,0.744,0.844,0.761,0.827,0.808,0.795
|
|
65
|
+
15/3/2024,0.82,0.721,0.835,0.809,0.831,0.775,0.837
|
|
66
|
+
15/4/2024,0.824,0.734,0.824,0.838,0.822,0.792,0.83
|
|
67
|
+
15/5/2024,0.834,0.729,0.818,0.852,0.834,0.808,0.858
|
|
68
|
+
15/6/2024,0.85,0.771,0.829,0.877,0.842,0.795,0.876
|
|
69
|
+
15/7/2024,0.86,0.75,0.834,0.882,0.862,0.84,0.889
|
|
70
|
+
15/8/2024,0.862,0.779,0.86,0.879,0.84,0.823,0.871
|
|
71
|
+
15/9/2024,0.836,0.765,0.831,0.865,0.834,0.814,0.824
|
|
72
|
+
15/10/2024,0.839,0.738,0.841,0.862,0.845,0.803,0.832
|
|
73
|
+
15/11/2024,0.834,0.733,0.849,0.853,0.845,0.812,0.81
|
|
74
|
+
15/12/2024,0.84,0.76,0.833,0.865,0.83,0.805,0.85
|
|
@@ -0,0 +1,551 @@
|
|
|
1
|
+
"""Thermodynamic relationships."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from pycontrails.physics import constants
|
|
8
|
+
from pycontrails.utils.types import ArrayScalarLike, support_arraylike
|
|
9
|
+
|
|
10
|
+
# -------------------
|
|
11
|
+
# Material Properties
|
|
12
|
+
# -------------------
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def rho_d(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
16
|
+
r"""Calculate air density for (T, p) assuming dry air.
|
|
17
|
+
|
|
18
|
+
Parameters
|
|
19
|
+
----------
|
|
20
|
+
T : ArrayScalarLike
|
|
21
|
+
Temperature, [:math:`K`]
|
|
22
|
+
p : ArrayScalarLike
|
|
23
|
+
Pressure, [:math:`Pa`]
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
ArrayScalarLike
|
|
28
|
+
Air density of dry air, [:math:`kg \ m^{-3}`]
|
|
29
|
+
"""
|
|
30
|
+
return p / (constants.R_d * T)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def rho_v(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
34
|
+
r"""Calculate the air density for (T, p) assuming all water vapor.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
T : ArrayScalarLike
|
|
39
|
+
Temperature, [:math:`K`]
|
|
40
|
+
p : ArrayScalarLike
|
|
41
|
+
Pressure, [:math:`Pa`]
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
ArrayScalarLike
|
|
46
|
+
Air density of water vapor, [:math:`kg \ m^{-3}`]
|
|
47
|
+
"""
|
|
48
|
+
return p / (constants.R_v * T)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def c_pm(q: ArrayScalarLike) -> ArrayScalarLike:
|
|
52
|
+
r"""Calculate isobaric heat capacity of moist air.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
q : ArrayScalarLike
|
|
57
|
+
Specific humidity, [:math:`kg \ kg^{-1}`]
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
ArrayScalarLike
|
|
62
|
+
Isobaric heat capacity of moist air, [:math:`J \ kg^{-1} \ K^{-1}`]
|
|
63
|
+
|
|
64
|
+
Notes
|
|
65
|
+
-----
|
|
66
|
+
Some models (including CoCiP) use a constant value here (1004 :math:`J \ kg^{-1} \ K^{-1}`)
|
|
67
|
+
|
|
68
|
+
"""
|
|
69
|
+
return constants.c_pd * (1.0 - q) + constants.c_pv * q
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def p_vapor(q: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
73
|
+
r"""Calculate the vapor pressure.
|
|
74
|
+
|
|
75
|
+
Parameters
|
|
76
|
+
----------
|
|
77
|
+
q : ArrayScalarTypeVar
|
|
78
|
+
Specific humidity, [:math:`kg \ kg^{-1}`]
|
|
79
|
+
p : ArrayScalarTypeVar
|
|
80
|
+
Pressure, [:math:`Pa`]
|
|
81
|
+
|
|
82
|
+
Returns
|
|
83
|
+
-------
|
|
84
|
+
ArrayScalarTypeVar
|
|
85
|
+
Vapor pressure, [:math:`Pa`]
|
|
86
|
+
"""
|
|
87
|
+
return q * p * (constants.R_v / constants.R_d)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def water_vapor_partial_pressure_along_mixing_line(
|
|
91
|
+
specific_humidity: ArrayScalarLike,
|
|
92
|
+
air_pressure: ArrayScalarLike,
|
|
93
|
+
T_plume: ArrayScalarLike,
|
|
94
|
+
T_ambient: ArrayScalarLike,
|
|
95
|
+
G: ArrayScalarLike,
|
|
96
|
+
) -> ArrayScalarLike:
|
|
97
|
+
"""
|
|
98
|
+
Calculate water vapor partial pressure along mixing line.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
specific_humidity : ArrayScalarLike
|
|
103
|
+
Specific humidity at each waypoint, [:math:`kg_{H_{2}O} / kg_{air}`]
|
|
104
|
+
air_pressure : ArrayScalarLike
|
|
105
|
+
Pressure altitude at each waypoint, [:math:`Pa`]
|
|
106
|
+
T_plume : ArrayScalarLike
|
|
107
|
+
Plume temperature evolution along mixing line, [:math:`K`]
|
|
108
|
+
T_ambient : ArrayScalarLike
|
|
109
|
+
Ambient temperature for each waypoint, [:math:`K`]
|
|
110
|
+
G : ArrayScalarLike
|
|
111
|
+
Slope of the mixing line in a temperature-humidity diagram.
|
|
112
|
+
|
|
113
|
+
Returns
|
|
114
|
+
-------
|
|
115
|
+
ArrayScalarLike
|
|
116
|
+
Water vapor partial pressure along mixing line (p_mw), [:math:`Pa`]
|
|
117
|
+
|
|
118
|
+
References
|
|
119
|
+
----------
|
|
120
|
+
Eq. (2) of Karcher et al. (2015).
|
|
121
|
+
"""
|
|
122
|
+
p_wa = p_vapor(specific_humidity, air_pressure)
|
|
123
|
+
return p_wa + G * (T_plume - T_ambient)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# -------------------
|
|
127
|
+
# Saturation Pressure
|
|
128
|
+
# -------------------
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def e_sat_ice(T: ArrayScalarLike) -> ArrayScalarLike:
|
|
132
|
+
r"""Calculate saturation pressure of water vapor over ice.
|
|
133
|
+
|
|
134
|
+
Parameters
|
|
135
|
+
----------
|
|
136
|
+
T : ArrayScalarLike
|
|
137
|
+
Temperature, [:math:`K`]
|
|
138
|
+
|
|
139
|
+
Returns
|
|
140
|
+
-------
|
|
141
|
+
ArrayScalarLike
|
|
142
|
+
Saturation pressure of water vapor over ice, [:math:`Pa`]
|
|
143
|
+
|
|
144
|
+
References
|
|
145
|
+
----------
|
|
146
|
+
- :cite:`sonntag1994`
|
|
147
|
+
|
|
148
|
+
"""
|
|
149
|
+
# Goff Gratch equation (Smithsonian Tables, 1984)
|
|
150
|
+
# return np.log10(-9.09718 * (273.16/T - 1) - 3.56654 * np.log10(273.16/T) + \
|
|
151
|
+
# 0.87679 * (1 - T/273.16) + np.log10(6.1071))
|
|
152
|
+
|
|
153
|
+
# Magnus Teten (Murray, 1967)
|
|
154
|
+
# return 6.1078 * np.exp(21.8745 * (T - 273.16) / (T - 7.66))
|
|
155
|
+
|
|
156
|
+
# Zhang 2017 - incorrect implementation of Magnus Teten
|
|
157
|
+
# return 6.1808 * np.exp(21.875 * (T - 276.16) / (T - 7.66))
|
|
158
|
+
|
|
159
|
+
# Guide to Meteorological Instruments and Methods of Observation (CIMO Guide) (WMO, 2008)
|
|
160
|
+
# return 6.112 * np.exp(22.46 * (T - 273.16) / (272.62 + T - 273.16))
|
|
161
|
+
|
|
162
|
+
# Sonntag (1994) is used in CoCiP
|
|
163
|
+
|
|
164
|
+
# FIXME: Presently, mypy is not aware that numpy ufuncs will return `xr.DataArray``
|
|
165
|
+
# when xr.DataArray is passed in. This will get fixed at some point in the future
|
|
166
|
+
# as `numpy` their typing patterns, after which the "type: ignore" comment can
|
|
167
|
+
# get ripped out.
|
|
168
|
+
# We could explicitly check for `xr.DataArray` then use `xr.apply_ufunc`, but
|
|
169
|
+
# this only renders our code more boilerplate and less performant.
|
|
170
|
+
# This comment is pasted several places in `pycontrails` -- they should all be
|
|
171
|
+
# addressed at the same time.
|
|
172
|
+
return 100.0 * np.exp( # type: ignore[return-value]
|
|
173
|
+
(-6024.5282 / T)
|
|
174
|
+
+ 24.7219
|
|
175
|
+
+ (0.010613868 * T)
|
|
176
|
+
- (1.3198825e-5 * (T**2))
|
|
177
|
+
- 0.49382577 * np.log(T)
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def sonntag_e_sat_liquid(T: ArrayScalarLike) -> ArrayScalarLike:
|
|
182
|
+
"""Calculate saturation pressure of water vapor over liquid water using Sonntag (1994).
|
|
183
|
+
|
|
184
|
+
Parameters
|
|
185
|
+
----------
|
|
186
|
+
T : ArrayScalarLike
|
|
187
|
+
Temperature, [:math:`K`]
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
ArrayScalarLike
|
|
192
|
+
Saturation pressure of water vapor over liquid water, [:math:`Pa`]
|
|
193
|
+
"""
|
|
194
|
+
return 100.0 * np.exp( # type: ignore[return-value]
|
|
195
|
+
-6096.9385 / T + 16.635794 - 0.02711193 * T + 1.673952 * 1e-5 * T**2 + 2.433502 * np.log(T)
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
def mk05_e_sat_liquid(T: ArrayScalarLike) -> ArrayScalarLike:
|
|
200
|
+
"""Calculate saturation pressure of water vapor over liquid water using Murphy and Koop (2005).
|
|
201
|
+
|
|
202
|
+
Parameters
|
|
203
|
+
----------
|
|
204
|
+
T : ArrayScalarLike
|
|
205
|
+
Temperature, [:math:`K`]
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
ArrayScalarLike
|
|
210
|
+
Saturation pressure of water vapor over liquid water, [:math:`Pa`]
|
|
211
|
+
|
|
212
|
+
Notes
|
|
213
|
+
-----
|
|
214
|
+
Several formulations exist for the saturation vapor pressure over liquid water.
|
|
215
|
+
|
|
216
|
+
Buck (Buck Research Manual 1996)..
|
|
217
|
+
|
|
218
|
+
6.1121 * np.exp((18.678 * (T - 273.15) / 234.5) * (T - 273.15) / (257.14 + (T - 273.15)))
|
|
219
|
+
|
|
220
|
+
Magnus Tetens (Murray, 1967)..
|
|
221
|
+
|
|
222
|
+
6.1078 * np.exp(17.269388 * (T - 273.16) / (T - 35.86))
|
|
223
|
+
|
|
224
|
+
Guide to Meteorological Instruments and Methods of Observation (CIMO Guide) (WMO, 2008)..
|
|
225
|
+
|
|
226
|
+
6.112 * np.exp(17.62 * (T - 273.15) / (243.12 + T - 273.15))
|
|
227
|
+
|
|
228
|
+
Sonntag (1994) (see :func:`sonntag_e_sat_liquid`) is used in older versions of CoCiP.
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
return np.exp( # type: ignore[return-value]
|
|
232
|
+
54.842763
|
|
233
|
+
- 6763.22 / T
|
|
234
|
+
- 4.21 * np.log(T)
|
|
235
|
+
+ 0.000367 * T
|
|
236
|
+
+ np.tanh(0.0415 * (T - 218.8))
|
|
237
|
+
* (53.878 - 1331.22 / T - 9.44523 * np.log(T) + 0.014025 * T)
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
241
|
+
def sonntag_e_sat_liquid_prime(T: ArrayScalarLike) -> ArrayScalarLike:
|
|
242
|
+
"""Calculate the derivative of :func:`sonntag_e_sat_liquid`.
|
|
243
|
+
|
|
244
|
+
Parameters
|
|
245
|
+
----------
|
|
246
|
+
T : ArrayScalarLike
|
|
247
|
+
Temperature, [:math:`K`].
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
ArrayScalarLike
|
|
252
|
+
Derivative of :func:`sonntag_e_sat_liquid`
|
|
253
|
+
"""
|
|
254
|
+
d_inside = 6096.9385 / (T**2) - 0.02711193 + 1.673952 * 1e-5 * 2 * T + 2.433502 / T
|
|
255
|
+
return sonntag_e_sat_liquid(T) * d_inside
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def mk05_e_sat_liquid_prime(T: ArrayScalarLike) -> ArrayScalarLike:
|
|
259
|
+
"""Calculate the derivative of :func:`mk05_e_sat_liquid`.
|
|
260
|
+
|
|
261
|
+
Parameters
|
|
262
|
+
----------
|
|
263
|
+
T : ArrayScalarLike
|
|
264
|
+
Temperature, [:math:`K`].
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
ArrayScalarLike
|
|
269
|
+
Derivative of :func:`mk05_e_sat_liquid`
|
|
270
|
+
"""
|
|
271
|
+
tanh_term = np.tanh(0.0415 * (T - 218.8))
|
|
272
|
+
return mk05_e_sat_liquid(T) * (
|
|
273
|
+
6763.22 / T**2
|
|
274
|
+
- 4.21 / T
|
|
275
|
+
+ 0.000367
|
|
276
|
+
+ 0.0415 * (1 - tanh_term**2) * (53.878 - 1331.22 / T - 9.44523 * np.log(T) + 0.014025 * T)
|
|
277
|
+
+ tanh_term * (1331.22 / T**2 - 9.44523 / T + 0.014025)
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
# Set aliases. These could be swapped out or made configurable.
|
|
282
|
+
e_sat_liquid = mk05_e_sat_liquid
|
|
283
|
+
e_sat_liquid_prime = mk05_e_sat_liquid_prime
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
@support_arraylike
|
|
287
|
+
def _e_sat_piecewise(T: np.ndarray) -> np.ndarray:
|
|
288
|
+
"""Calculate `e_sat_liquid` when T is above freezing otherwise `e_sat_ice`.
|
|
289
|
+
|
|
290
|
+
Parameters
|
|
291
|
+
----------
|
|
292
|
+
T : np.ndarray
|
|
293
|
+
Temperature, [:math:`K`]
|
|
294
|
+
|
|
295
|
+
Returns
|
|
296
|
+
-------
|
|
297
|
+
np.ndarray
|
|
298
|
+
Piecewise array of e_sat_liquid and e_sat_ice values.
|
|
299
|
+
"""
|
|
300
|
+
condlist = [T >= -constants.absolute_zero, T < constants.absolute_zero] # noqa: SIM300
|
|
301
|
+
funclist = [e_sat_liquid, e_sat_ice, np.nan] # nan passed through
|
|
302
|
+
return np.piecewise(T, condlist, funclist)
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
# ----------------------------
|
|
306
|
+
# Saturation Specific Humidity
|
|
307
|
+
# ----------------------------
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
def q_sat(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
311
|
+
r"""Calculate saturation specific humidity over liquid or ice.
|
|
312
|
+
|
|
313
|
+
When T is above 0 C, liquid saturation is computed. Otherwise, ice saturation
|
|
314
|
+
is computed.
|
|
315
|
+
|
|
316
|
+
Parameters
|
|
317
|
+
----------
|
|
318
|
+
T : ArrayScalarLike
|
|
319
|
+
Temperature, [:math:`K`]
|
|
320
|
+
p : ArrayScalarLike
|
|
321
|
+
Pressure, [:math:`Pa`]
|
|
322
|
+
|
|
323
|
+
Returns
|
|
324
|
+
-------
|
|
325
|
+
ArrayScalarLike
|
|
326
|
+
Saturation specific humidity, [:math:`kg \ kg^{-1}`]
|
|
327
|
+
|
|
328
|
+
Notes
|
|
329
|
+
-----
|
|
330
|
+
Smith et al. (1999)
|
|
331
|
+
"""
|
|
332
|
+
e_sat = _e_sat_piecewise(T)
|
|
333
|
+
return constants.epsilon * e_sat / p
|
|
334
|
+
|
|
335
|
+
|
|
336
|
+
def q_sat_ice(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
337
|
+
r"""Calculate saturation specific humidity over ice.
|
|
338
|
+
|
|
339
|
+
Parameters
|
|
340
|
+
----------
|
|
341
|
+
T : ArrayScalarLike
|
|
342
|
+
Temperature, [:math:`K`]
|
|
343
|
+
p : ArrayScalarLike
|
|
344
|
+
Pressure, [:math:`Pa`]
|
|
345
|
+
|
|
346
|
+
Returns
|
|
347
|
+
-------
|
|
348
|
+
ArrayScalarLike
|
|
349
|
+
Saturation specific humidity, [:math:`kg \ kg^{-1}`]
|
|
350
|
+
|
|
351
|
+
Notes
|
|
352
|
+
-----
|
|
353
|
+
Smith et al. (1999)
|
|
354
|
+
"""
|
|
355
|
+
return constants.epsilon * e_sat_ice(T) / p
|
|
356
|
+
|
|
357
|
+
|
|
358
|
+
def q_sat_liquid(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
359
|
+
r"""Calculate saturation specific humidity over liquid.
|
|
360
|
+
|
|
361
|
+
Parameters
|
|
362
|
+
----------
|
|
363
|
+
T : ArrayScalarLike
|
|
364
|
+
Temperature, [:math:`K`]
|
|
365
|
+
p : ArrayScalarLike
|
|
366
|
+
Pressure, [:math:`Pa`]
|
|
367
|
+
|
|
368
|
+
Returns
|
|
369
|
+
-------
|
|
370
|
+
ArrayScalarLike
|
|
371
|
+
Saturation specific humidity, [:math:`kg \ kg^{-1}`]
|
|
372
|
+
|
|
373
|
+
Notes
|
|
374
|
+
-----
|
|
375
|
+
Smith et al. (1999)
|
|
376
|
+
"""
|
|
377
|
+
return constants.epsilon * e_sat_liquid(T) / p
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
# -----------------
|
|
381
|
+
# Relative Humidity
|
|
382
|
+
# -----------------
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def rh(q: ArrayScalarLike, T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
386
|
+
r"""Calculate the relative humidity with respect to to liquid water.
|
|
387
|
+
|
|
388
|
+
Parameters
|
|
389
|
+
----------
|
|
390
|
+
q : ArrayScalarLike
|
|
391
|
+
Specific humidity, [:math:`kg \ kg^{-1}`]
|
|
392
|
+
T : ArrayScalarLike
|
|
393
|
+
Temperature, [:math:`K`]
|
|
394
|
+
p : ArrayScalarLike
|
|
395
|
+
Pressure, [:math:`Pa`]
|
|
396
|
+
|
|
397
|
+
Returns
|
|
398
|
+
-------
|
|
399
|
+
ArrayScalarLike
|
|
400
|
+
Relative Humidity, :math:`[0 - 1]`
|
|
401
|
+
"""
|
|
402
|
+
return (q * p * (constants.R_v / constants.R_d)) / e_sat_liquid(T)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
def rhi(q: ArrayScalarLike, T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
406
|
+
r"""Calculate the relative humidity with respect to ice (RHi).
|
|
407
|
+
|
|
408
|
+
Parameters
|
|
409
|
+
----------
|
|
410
|
+
q : ArrayScalarLike
|
|
411
|
+
Specific humidity, [:math:`kg \ kg^{-1}`]
|
|
412
|
+
T : ArrayScalarLike
|
|
413
|
+
Temperature, [:math:`K`]
|
|
414
|
+
p : ArrayScalarLike
|
|
415
|
+
Pressure, [:math:`Pa`]
|
|
416
|
+
|
|
417
|
+
Returns
|
|
418
|
+
-------
|
|
419
|
+
ArrayScalarLike
|
|
420
|
+
Relative Humidity over ice, :math:`[0 - 1]`
|
|
421
|
+
"""
|
|
422
|
+
return (q * p * (constants.R_v / constants.R_d)) / e_sat_ice(T)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
# --------------
|
|
426
|
+
# Met Properties
|
|
427
|
+
# --------------
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def pressure_dz(T: ArrayScalarLike, p: ArrayScalarLike, dz: float) -> ArrayScalarLike:
|
|
431
|
+
r"""Calculate the pressure altitude ``dz`` meters below input pressure.
|
|
432
|
+
|
|
433
|
+
Returns surface pressure if the calculated pressure altitude is greater
|
|
434
|
+
than :const:`constants.p_surface`.
|
|
435
|
+
|
|
436
|
+
Parameters
|
|
437
|
+
----------
|
|
438
|
+
T : ArrayScalarLike
|
|
439
|
+
Temperature, [:math:`K`]
|
|
440
|
+
p : ArrayScalarLike
|
|
441
|
+
Pressure, [:math:`Pa`]
|
|
442
|
+
dz : float
|
|
443
|
+
Difference in altitude between measurements, [:math:`m`]
|
|
444
|
+
|
|
445
|
+
Returns
|
|
446
|
+
-------
|
|
447
|
+
ArrayScalarLike
|
|
448
|
+
Pressure at altitude, [:math:`Pa`]
|
|
449
|
+
|
|
450
|
+
Notes
|
|
451
|
+
-----
|
|
452
|
+
This is used to calculate the temperature gradient and wind shear.
|
|
453
|
+
"""
|
|
454
|
+
dp = rho_d(T, p) * constants.g * dz
|
|
455
|
+
|
|
456
|
+
# FIXME: Presently, mypy is not aware that numpy ufuncs will return `xr.DataArray``
|
|
457
|
+
# when xr.DataArray is passed in. This will get fixed at some point in the future
|
|
458
|
+
# as `numpy` their typing patterns, after which the "type: ignore" comment can
|
|
459
|
+
# get ripped out.
|
|
460
|
+
# We could explicitly check for `xr.DataArray` then use `xr.apply_ufunc`, but
|
|
461
|
+
# this only renders our code more boilerplate and less performant.
|
|
462
|
+
# This comment is pasted several places in `pycontrails` -- they should all be
|
|
463
|
+
# addressed at the same time.
|
|
464
|
+
return np.minimum(p + dp, constants.p_surface) # type: ignore[return-value]
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
def T_potential_gradient(
|
|
468
|
+
T_top: ArrayScalarLike,
|
|
469
|
+
p_top: ArrayScalarLike,
|
|
470
|
+
T_btm: ArrayScalarLike,
|
|
471
|
+
p_btm: ArrayScalarLike,
|
|
472
|
+
dz: float,
|
|
473
|
+
) -> ArrayScalarLike:
|
|
474
|
+
r"""Calculate the potential temperature gradient between two altitudes.
|
|
475
|
+
|
|
476
|
+
Parameters
|
|
477
|
+
----------
|
|
478
|
+
T_top : ArrayScalarLike
|
|
479
|
+
Temperature at original altitude, [:math:`K`]
|
|
480
|
+
p_top : ArrayScalarLike
|
|
481
|
+
Pressure at original altitude, [:math:`Pa`]
|
|
482
|
+
T_btm : ArrayScalarLike
|
|
483
|
+
Temperature at lower altitude, [:math:`K`]
|
|
484
|
+
p_btm : ArrayScalarLike
|
|
485
|
+
Pressure at lower altitude, [:math:`Pa`]
|
|
486
|
+
dz : float
|
|
487
|
+
Difference in altitude between measurements, [:math:`m`]
|
|
488
|
+
|
|
489
|
+
Returns
|
|
490
|
+
-------
|
|
491
|
+
ArrayScalarLike
|
|
492
|
+
Potential Temperature gradient, [:math:`K \ m^{-1}`]
|
|
493
|
+
"""
|
|
494
|
+
T_potential_top = T_potential(T_top, p_top)
|
|
495
|
+
T_potential_btm = T_potential(T_btm, p_btm)
|
|
496
|
+
return (T_potential_top - T_potential_btm) / dz
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
def T_potential(T: ArrayScalarLike, p: ArrayScalarLike) -> ArrayScalarLike:
|
|
500
|
+
r"""Calculate potential temperature.
|
|
501
|
+
|
|
502
|
+
The potential temperature is the temperature that
|
|
503
|
+
an air parcel would attain if adiabatically
|
|
504
|
+
brought to a standard reference pressure, :const:`constants.p_surface`.
|
|
505
|
+
|
|
506
|
+
Parameters
|
|
507
|
+
----------
|
|
508
|
+
T : ArrayScalarLike
|
|
509
|
+
Temperature , [:math:`K`]
|
|
510
|
+
p : ArrayScalarLike
|
|
511
|
+
Pressure, [:math:`Pa`]
|
|
512
|
+
|
|
513
|
+
Returns
|
|
514
|
+
-------
|
|
515
|
+
ArrayScalarLike
|
|
516
|
+
Potential Temperature, [:math:`K`]
|
|
517
|
+
|
|
518
|
+
References
|
|
519
|
+
----------
|
|
520
|
+
- https://en.wikipedia.org/wiki/Potential_temperature
|
|
521
|
+
"""
|
|
522
|
+
return T * (constants.p_surface / p) ** (constants.R_d / constants.c_pd)
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
def brunt_vaisala_frequency(p: np.ndarray, T: np.ndarray, T_grad: np.ndarray) -> np.ndarray:
|
|
526
|
+
r"""Calculate the Brunt-Vaisaila frequency.
|
|
527
|
+
|
|
528
|
+
The Brunt-Vaisaila frequency is the frequency at which a vertically
|
|
529
|
+
displaced parcel will oscillate within a statically stable environment.
|
|
530
|
+
|
|
531
|
+
Parameters
|
|
532
|
+
----------
|
|
533
|
+
p : np.ndarray
|
|
534
|
+
Pressure, [:math:`Pa`]
|
|
535
|
+
T : np.ndarray
|
|
536
|
+
Temperature , [:math:`K`]
|
|
537
|
+
T_grad : np.ndarray
|
|
538
|
+
Potential Temperature gradient (see :func:`T_potential_gradient`), [:math:`K \ m^{-1}`]
|
|
539
|
+
|
|
540
|
+
Returns
|
|
541
|
+
-------
|
|
542
|
+
np.ndarray
|
|
543
|
+
Brunt-Vaisaila frequency, [:math:`s^{-1}`]
|
|
544
|
+
|
|
545
|
+
References
|
|
546
|
+
----------
|
|
547
|
+
- https://en.wikipedia.org/wiki/Brunt%E2%80%93V%C3%A4is%C3%A4l%C3%A4_frequency
|
|
548
|
+
"""
|
|
549
|
+
theta = T_potential(T, p)
|
|
550
|
+
T_grad.clip(min=1e-6, out=T_grad)
|
|
551
|
+
return (T_grad * constants.g / theta) ** 0.5
|