Last updated on Nov 5, 2023
Demo script for the analyses done in Nakamura and Huang (2018, Science)
This is a complimentary demo script that can be used to implement the local wave activity, fluxes and flux convergence/divergence computation required in the analyses presented in Nakamura and Huang, Atmospheric Blocking as a Traffic Jam in the Jet Stream. Science. (2018)
This notebook demonstrate how to compute local wave activity and all the flux terms in equations (2) and (3) in NH2018 with the updated functionality in the python package falwa
. To run the script, please install the package falwa
using
python setup.py develop
after cloning the GitHub repo.
Please raise an issue in the GitHub repo or contact Clare S. Y. Huang (csyhuang@uchicago.edu) if you have any questions or suggestions regarding the package.
[1]:
import datetime as dt
from math import pi
import numpy as np
from numpy import dtype
import xarray as xr
import matplotlib.pyplot as plt
%matplotlib inline
from falwa.oopinterface import QGFieldNH18
import falwa.utilities as utilities
Load ERA-Interim reanalysis data retrieved from ECMWF server
The sample script in this directory download_example.py
include the code to retrieve zonal wind field U, meridional wind field V and temperature field T at various pressure levels. Given that you have an account on ECMWF server and have the ecmwfapi
package installed, you can run the scripts to download data from there:
python download_example.py
[2]:
u_file = xr.open_dataset('2005-01-23_to_2005-01-30_u.nc')
v_file = xr.open_dataset('2005-01-23_to_2005-01-30_v.nc')
t_file = xr.open_dataset('2005-01-23_to_2005-01-30_t.nc')
ntimes = u_file.time.size
time_array = u_file.time
[3]:
u_file
[3]:
<xarray.Dataset> Dimensions: (longitude: 240, latitude: 121, level: 37, time: 32) Coordinates: * longitude (longitude) float32 0.0 1.5 3.0 4.5 ... 354.0 355.5 357.0 358.5 * latitude (latitude) float32 90.0 88.5 87.0 85.5 ... -87.0 -88.5 -90.0 * level (level) int32 1 2 3 5 7 10 20 30 ... 850 875 900 925 950 975 1000 * time (time) datetime64[ns] 2005-01-23 ... 2005-01-30T18:00:00 Data variables: u (time, level, latitude, longitude) float32 ... Attributes: Conventions: CF-1.6 history: 2018-07-17 16:50:39 GMT by grib_to_netcdf-2.8.0: grib_to_ne...
Load the dimension arrays
In this version, the QGField
object takes only: - latitude array in degree ascending order, and - pressure level in hPa in decending order (from ground to aloft).
[4]:
xlon = u_file.longitude.values
# latitude has to be in ascending order
ylat = u_file.latitude.values
if np.diff(ylat)[0]<0:
print('Flip ylat.')
ylat = ylat[::-1]
# pressure level has to be in descending order (ascending height)
plev = u_file.level.values
if np.diff(plev)[0]>0:
print('Flip plev.')
plev = plev[::-1]
nlon = xlon.size
nlat = ylat.size
nlev = plev.size
Flip ylat.
Flip plev.
[5]:
clat = np.cos(np.deg2rad(ylat)) # cosine latitude
p0 = 1000. # surface pressure [hPa]
kmax = 49 # number of grid points for vertical extrapolation (dimension of height)
dz = 1000. # differential height element
height = np.arange(0,kmax)*dz # pseudoheight [m]
dphi = np.diff(ylat)[0]*pi/180. # differential latitudinal element
dlambda = np.diff(xlon)[0]*pi/180. # differential latitudinal element
hh = 7000. # scale height
cp = 1004. # heat capacity of dry air
rr = 287. # gas constant
omega = 7.29e-5 # rotation rate of the earth
aa = 6.378e+6 # earth radius
prefactor = np.array([np.exp(-z/hh) for z in height[1:]]).sum() # integrated sum of density from the level
#just above the ground (z=1km) to aloft
npart = nlat # number of partitions to construct the equivalent latitude grids
maxits = 100000 # maximum number of iteration in the SOR solver to solve for reference state
tol = 1.e-5 # tolerance that define convergence of solution
rjac = 0.95 # spectral radius of the Jacobi iteration in the SOR solver.
jd = nlat//2+1 # (one plus) index of latitude grid point with value 0 deg
# This is to be input to fortran code. The index convention is different.
Set the level of pressure and the timestamp to display below
[6]:
tstamp = [dt.datetime(2005,1,23,0,0) + dt.timedelta(seconds=6*3600) * tt for tt in range(ntimes)]
plev_selected = 10 # selected pressure level to display
tstep_selected = 0
Loop through the input file and plot computed quantities
[7]:
for tstep in range(32): # or ntimes
uu = u_file.u.isel(time=tstep).values[::-1, ::-1, :]
vv = v_file.v.isel(time=tstep).values[::-1, ::-1, :]
tt = t_file.t.isel(time=tstep).values[::-1, ::-1, :]
qgfield_object = QGFieldNH18(xlon, ylat, plev, uu, vv, tt, northern_hemisphere_results_only=False)
qgfield_object.interpolate_fields(return_named_tuple=False)
qgfield_object.compute_reference_states(return_named_tuple=False)
qgfield_object.compute_lwa_and_barotropic_fluxes(return_named_tuple=False)
if tstep == tstep_selected:
# === Below demonstrate another way to access the computed variables ===
# 3D Variables that I would choose one pressure level to display
variables_3d = [
(qgfield_object.qgpv, 'Quasigeostrophic potential vorticity (QGPV)'),
(qgfield_object.lwa, 'Local wave activity (LWA)'),
(qgfield_object.interpolated_u, 'Interpolated zonal wind (u)'),
(qgfield_object.interpolated_v, 'Interpolated meridional wind (v)')]
# Reference states to be displayed on y-z plane
variables_yz = [
(qgfield_object.qref, 'Qref'),
(qgfield_object.uref, 'Uref'),
(qgfield_object.ptref, 'PTref')]
# Vertically averaged variables to be displayed on x-y plane
variables_xy = [
(qgfield_object.adv_flux_f1, 'Advective flux F1'),
(qgfield_object.adv_flux_f2, 'Advective flux F2'),
(qgfield_object.adv_flux_f3, 'Advective flux F3'),
(qgfield_object.convergence_zonal_advective_flux, 'Advective flux convergence -Div(F1+F2+F3)'),
(qgfield_object.divergence_eddy_momentum_flux, 'divergence_eddy_momentum_flux'),
(qgfield_object.meridional_heat_flux, 'meridional_heat_flux')
]
# Plot 240 hPa of 3D-variables
for variable, name in variables_3d:
plt.figure(figsize=(12,6))
plt.contourf(xlon, ylat[1:-1], variable[plev_selected, 1:-1, :], 50, cmap='jet')
if name=='Local wave activity (LWA)':
plt.axhline(y=0, c='w', lw=30)
plt.colorbar()
plt.ylabel('Latitude (deg)')
plt.xlabel('Longitude (deg)')
plt.title(name + ' at 240hPa | ' + str(tstamp[tstep]))
plt.show()
# Plot reference states
for variable, name in variables_yz:
plt.figure(figsize=(6,4))
plt.contourf(ylat[1:-1], height, variable[:, 1:-1], 50, cmap='jet')
plt.axvline(x=0, c='w', lw=2)
plt.xlabel('Latitude (deg)')
plt.ylabel('Pseudoheight (m)')
plt.colorbar()
plt.title(name + ' | ' + str(tstamp[tstep]))
plt.show()
# Plot barotropic (2D-)variables
for variable, name in variables_xy:
plt.figure(figsize=(12,6))
plt.contourf(xlon, ylat[1:-1], variable[1:-1, :], 50, cmap='jet')
plt.axhline(y=0, c='w', lw=30)
plt.ylabel('Latitude (deg)')
plt.xlabel('Longitude (deg)')
plt.colorbar()
plt.title(name + ' | ' + str(tstamp[tstep]))
plt.show()
print('tstep = {}/{}\n'.format(tstep, ntimes))
1128425192 32684 1132480416 converged at n = 950
1128425192 32684 1132480416 converged at n = 721
tstep = 0/32
1128425192 32684 1132480416 converged at n = 953
1128425192 32684 1132480416 converged at n = 721
tstep = 1/32
1128425192 32684 1132480416 converged at n = 949
1128425192 32684 1132480416 converged at n = 703
tstep = 2/32
853002984 32684 1132480416 converged at n = 948
853002984 32684 1132480416 converged at n = 711
tstep = 3/32
1120484072 32684 1132480416 converged at n = 949
1120484072 32684 1132480416 converged at n = 718
tstep = 4/32
1120484072 32684 1132480416 converged at n = 948
1120484072 32684 1132480416 converged at n = 721
tstep = 5/32
67727080 32684 1132480416 converged at n = 946
67727080 32684 1132480416 converged at n = 706
tstep = 6/32
67727080 32684 1132480416 converged at n = 944
67727080 32684 1132480416 converged at n = 718
tstep = 7/32
67727080 32684 1132480416 converged at n = 947
67727080 32684 1132480416 converged at n = 709
tstep = 8/32
1128425192 32684 1132480416 converged at n = 946
1128425192 32684 1132480416 converged at n = 716
tstep = 9/32
853002984 32684 1132480416 converged at n = 942
853002984 32684 1132480416 converged at n = 714
tstep = 10/32
67754216 32684 1132480416 converged at n = 943
67754216 32684 1132480416 converged at n = 719
tstep = 11/32
67727080 32684 1132480416 converged at n = 941
67727080 32684 1132480416 converged at n = 716
tstep = 12/32
67754216 32684 1132480416 converged at n = 942
67754216 32684 1132480416 converged at n = 725
tstep = 13/32
67727080 32684 1132480416 converged at n = 945
67727080 32684 1132480416 converged at n = 722
tstep = 14/32
1128425192 32684 1132480416 converged at n = 943
1128425192 32684 1132480416 converged at n = 734
tstep = 15/32
588451048 32684 1132480416 converged at n = 946
588451048 32684 1132480416 converged at n = 735
tstep = 16/32
67754216 32684 1132480416 converged at n = 944
67754216 32684 1132480416 converged at n = 742
tstep = 17/32
1128425192 32684 1132480416 converged at n = 945
1128425192 32684 1132480416 converged at n = 735
tstep = 18/32
581618920 32684 1132480416 converged at n = 946
581618920 32684 1132480416 converged at n = 749
tstep = 19/32
581618920 32684 1132480416 converged at n = 943
581618920 32684 1132480416 converged at n = 749
tstep = 20/32
67727080 32684 1132480416 converged at n = 945
67727080 32684 1132480416 converged at n = 750
tstep = 21/32
1120484072 32684 1132480416 converged at n = 943
1120484072 32684 1132480416 converged at n = 742
tstep = 22/32
588451048 32684 1132480416 converged at n = 940
588451048 32684 1132480416 converged at n = 752
tstep = 23/32
1120484072 32684 1132480416 converged at n = 941
1120484072 32684 1132480416 converged at n = 749
tstep = 24/32
1128425192 32684 1132480416 converged at n = 940
1128425192 32684 1132480416 converged at n = 747
tstep = 25/32
588451048 32684 1132480416 converged at n = 943
588451048 32684 1132480416 converged at n = 736
tstep = 26/32
1128425192 32684 1132480416 converged at n = 944
1128425192 32684 1132480416 converged at n = 738
tstep = 27/32
1120484072 32684 1132480416 converged at n = 945
1120484072 32684 1132480416 converged at n = 736
tstep = 28/32
1128425192 32684 1132480416 converged at n = 945
1128425192 32684 1132480416 converged at n = 733
tstep = 29/32
67727080 32684 1132480416 converged at n = 943
67727080 32684 1132480416 converged at n = 731
tstep = 30/32
853002984 32684 1132480416 converged at n = 944
853002984 32684 1132480416 converged at n = 736
tstep = 31/32