当前位置:首页>python>Python | Rossby波源

Python | Rossby波源

  • 2026-10-21 13:28:53
Python | Rossby波源
罗斯贝波(Rossby wave)是大气和海洋中一种由于地转偏向力随纬度变化(β效应)而产生的大尺度波动,其通过频散效应调节角动量与能量的经向输送,从而主导中高纬度天气系统的演变与维持全球气候系统的平衡。
罗斯贝波波源(Rossby wave source,RWS)是辐散风对绝对涡度的平流与散度对绝对涡度的拉伸共同构成的势函数源项,其空间分布决定了行星尺度罗斯贝波的激发位置与传播路径。
  • 简单推导
主要参考:(Sardeshmukh and Hoskins, 1988)
水平涡度方程写为:
  1. 200 hPa 垂直速度 ω 很小 → 扭转 + 垂直平流 ≈ 0;

  2. 行星尺度上摩擦 F ≈ 0。

于是:

此外,任何水平风都能分解为旋转风与辐散风:
代入得:
只关注旋转风的变化,因此把带 vχ 的项全部移到右端,作为强迫项,于是有:
  1. 第一项:辐散风对涡度的平流;

  2. 第二项:散度对绝对涡度的拉伸;

  3. 第三项:辐散风对行星涡度的平流(β项)

实际上第一和第三项合为一项,即辐散风对绝对涡度的平流。因此,罗斯贝波波源为:

  • 代码实现

windspharm(https://ajdawson.github.io/windspharm/)实现

import warningswarnings.filterwarnings("ignore")import xarray as xrimport numpy as npnp.int = intimport matplotlib.pyplot as pltimport cartopy.crs as ccrsfrom windspharm.xarray import VectorWindimport cmapsfrom cartopy.util import add_cyclic_pointimport matplotlib.ticker as mtickerfrom cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatterfrom mpl_toolkits.axes_grid1.inset_locator import inset_axesfrom tqdm import tqdm# ------------------------------------------------------------------# 1. 读数据# ------------------------------------------------------------------u_file = 'uwnd.mon.mean.2.5.nc'v_file = 'vwnd.mon.mean.2.5.nc'ds_u = xr.open_dataset(u_file, chunks={'time': 12})ds_v = xr.open_dataset(v_file, chunks={'time': 12})level_sel = 200          # hPau_all = ds_u['u'].sel(level=level_sel, expver=1)v_all = ds_v['v'].sel(level=level_sel, expver=1)time_slice = slice('1979-01', '2022-12')u_all = u_all.sel(time=time_slice)v_all = v_all.sel(time=time_slice)# ------------------------------------------------------------------# 2. 计算 RWS# ------------------------------------------------------------------Omega = 7.2921150e-5f = 2 * Omega * np.sin(np.deg2rad(u_all.latitude))f2d = f.broadcast_like(u_all.isel(time=0))   # (lat,lon)rws_list = []for t in tqdm(u_all.time, desc='Computing RWS'):    u = u_all.sel(time=t).fillna(0)    v = v_all.sel(time=t).fillna(0)    vw = VectorWind(u, v)    zeta = vw.vorticity()    div  = vw.divergence()    u_chi, v_chi = vw.irrotationalcomponent()    vw_chi = VectorWind(u_chi, v_chi)    div_vchi = vw_chi.divergence()    try:        eta = vw.absolutevorticity()    except Exception:        eta = zeta + f2d    grad_x, grad_y = vw.gradient(eta)    rws = - (u_chi * grad_x + v_chi * grad_y) - eta * div_vchi    rws_list.append(rws.assign_coords(time=t))# 合并成一个 DataArrayRWS_all = xr.concat(rws_list, dim='time')# coslat = np.cos(np.deg2rad(RWS_all.latitude))   # 1D# RWS_weighted = RWS_all * coslat# ------------------------------------------------------------------# 3. 夏季 (6-7-8) RWS# ------------------------------------------------------------------jja = RWS_all.sel(time=RWS_all.time.dt.month.isin([6, 7, 8]))RWS_jja_clim = jja.mean('time')# ------------------------------------------------------------------# 4. 夏季平均的不可旋转风 (u_chi, v_chi) 矢量# ------------------------------------------------------------------u_chi_clim = []v_chi_clim = []for t in u_all.time:    if t.dt.month.item() in (6, 7, 8):        u = u_all.sel(time=t).fillna(0)        v = v_all.sel(time=t).fillna(0)        vw = VectorWind(u, v)        u_chi, v_chi = vw.irrotationalcomponent()        u_chi_clim.append(u_chi.assign_coords(time=t))        v_chi_clim.append(v_chi.assign_coords(time=t))u_chi_clim = xr.concat(u_chi_clim, dim='time').mean('time')v_chi_clim = xr.concat(v_chi_clim, dim='time').mean('time')# ------------------------------------------------------------------# 5. 绘图# ------------------------------------------------------------------# 处理0经度处断点问题def add_cyclic_da(da):    vals, lon = add_cyclic_point(da.values, coord=da.longitude)    return xr.DataArray(vals,                        coords={'longitude': lon, 'latitude': da.latitude},                        dims=da.dims)RWS_plot = add_cyclic_da(RWS_jja_clim)u_chi_plot = add_cyclic_da(u_chi_clim)v_chi_plot = add_cyclic_da(v_chi_clim)# ------------------------------------------------------------------fig = plt.figure(figsize=(12, 6))ax = plt.axes(projection=ccrs.Robinson())ax.set_global()im = ax.contourf(RWS_plot.longitude, RWS_plot.latitude, RWS_plot*1e11,                 transform=ccrs.PlateCarree(),                 cmap=cmaps.MPL_PuOr_r,                 levels=np.arange(-20, 22, 2), extend='both')# 辐散风step = max(1, int(u_chi_plot.sizes['longitude']//40))lon = RWS_plot.longitude.valueslat = RWS_plot.latitude.valueslon2d, lat2d = np.meshgrid(lon, lat)uv = ax.quiver(lon2d[::step, ::step], lat2d[::step, ::step],               u_chi_plot.values[::step, ::step],               v_chi_plot.values[::step, ::step],               transform=ccrs.PlateCarree(), scale=100, width=0.002)ax.quiverkey(uv, X=0.82, Y=-0.09, U=5, angle=0,             label='5 m/s', labelpos='E', color='k', labelcolor='k')ax.coastlines(linewidth=1.5, color='grey')gl = ax.gridlines(draw_labels=True, linewidth=0.5, color='gray',                  alpha=0.8, linestyle='--')# gl.top_labels   = False# gl.right_labels = Falsegl.xlocator = mticker.FixedLocator(np.arange(-180, 181, 60))gl.ylocator = mticker.FixedLocator(np.arange(-90, 91, 30))gl.xformatter = LongitudeFormatter()gl.yformatter = LatitudeFormatter()gl.xlabel_style = {'size': 14}gl.ylabel_style = {'size': 14}# colorbarcax = inset_axes(ax, width='50%', height='3%', loc='lower center',                 bbox_to_anchor=(0, -0.12, 1, 1), bbox_transform=ax.transAxes)cbar = plt.colorbar(im, cax=cax, orientation='horizontal')cbar.set_label('10$^{-11}$s$^{-2}$')ax.set_title('RWS Clim. JJA (1979-2022)',             fontdict={'family': 'sans-serif', 'size': 18}, fontweight='bold')plt.savefig('RWS_JJA_clim.png', dpi=600, bbox_inches='tight')plt.show()
  • 结果分析

  1. 北半球热力场:夏季风的降水在东南亚产生了很强的潜热释放,加上青藏高原的热力作用和热带西太平洋上的积云对流加热,在东南亚和热带西太平洋形成了强大的热源区;而由于地中海周围的沙漠地带为净辐射的汇,其大气柱会不断的冷却,所以为强的冷源区。
  2. 辐散场分布:冷热源分布形成了热带西太平洋和东南亚上空的强大辐散场,地中海上空很强的辐合场。
  3. 罗斯贝波源(涡源)分布:形成了东亚及西北太平洋上空的负涡源,地中海附近上空的正涡源和中纬度东太平洋、东大西洋上空的正涡源。

最新文章

随机文章