前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大气视热源的python计算尝试

大气视热源的python计算尝试

作者头像
用户11172986
发布2024-06-20 16:53:55
1020
发布2024-06-20 16:53:55
举报
文章被收录于专栏:气python风雨气python风雨

前言

大气视热源是常用于表征大气热力作用的概念,本项目会尝试使用metpy库计算大气视热源并可视化,希望能给你们一些微小的帮助。

导入并读取数据

代码语言:javascript
复制
代码语言:javascript
复制
from wrf import uvmet, to_np, getvar, interplevel, smooth2d, get_cartopy, cartopy_xlim, cartopy_ylim, latlon_coords,ALL_TIMES
import numpy as np
from netCDF4 import Dataset
import xarray as xr
from metpy.units import units
import matplotlib.pyplot as plt
from matplotlib.cm import get_cmap
from matplotlib.colors import from_levels_and_colors
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader
from cartopy.feature import NaturalEarthFeature
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from cartopy.mpl.gridliner import LATITUDE_FORMATTER, LONGITUDE_FORMATTER
import cmaps
from glob import glob
import metpy.calc as mpcalc
import metpy.constants as constants
import os
代码语言:javascript
复制
代码语言:javascript
复制
Warning: ecCodes 2.21.0 or higher is recommended. You are running version 2.14.1

提取变量与插值

In [2]:

代码语言:javascript
复制
代码语言:javascript
复制
# 定义 WRF 文件夹路径和文件名前缀
wrfout_path = "/home/mw/input/wrfout3385/"
filename_prefix = "wrfout_d02_"

wrf_files = sorted([os.path.join(wrfout_path, f) for f in os.listdir(wrfout_path) if f.startswith(filename_prefix)])
wrf_list = [Dataset(f) for f in wrf_files]
# 提取要素
lon = getvar(wrf_list, 'lon', timeidx=ALL_TIMES, method='cat')
lat = getvar(wrf_list, 'lat', timeidx=ALL_TIMES, method='cat')
u = getvar(wrf_list, 'ua', timeidx=ALL_TIMES, method='cat')
v = getvar(wrf_list, 'va', timeidx=ALL_TIMES, method='cat')
w = getvar(wrf_list, 'omg', timeidx=ALL_TIMES, method='cat')
t = getvar(wrf_list, 'tk', timeidx=ALL_TIMES, method='cat')
theta = getvar(wrf_list, 'theta', timeidx=ALL_TIMES, method='cat')
#q = getvar(wrf_file, 'QVAPOR', timeidx=0)*1000
# 提取WRF模拟的经纬度数组
lats, lons = latlon_coords(u)

# 提取WRF模拟的地图投影
wrf_proj = get_cartopy(u)
levels = [1000,925,850,700,600,500,400,300,200,100]
p = getvar(wrf_list, 'pressure', timeidx=ALL_TIMES, method='cat')
u_in = interplevel(u, p, levels)
v_in = interplevel(v, p, levels)
w_in = interplevel(w, p, levels)
theta_in = interplevel(theta, p, levels)
t_in = interplevel(t, p, levels) 
#z = getvar(wrf_list, 'z', timeidx=ALL_TIMES, method='cat')
#z_in = interplevel(z, p, levels)
dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat)
p_in =interplevel(p, p, levels)
代码语言:javascript
复制
In [3]:
代码语言:javascript
复制
代码语言:javascript
复制
p_in.units,theta_in.units,t_in.units,u_in.units,v_in.units,w_in.units
代码语言:javascript
复制
代码语言:javascript
复制
('hPa', 'K', 'K', 'm s-1', 'm s-1', 'Pa s-1')

计算部分

In [4]:

代码语言:javascript
复制
代码语言:javascript
复制
from metpy.calc import advection
cp = 1004 #j/(kg*k)
R = 287 #j/(kg*k)
p0 = 1000 # hpa
kappa = R/cp
w_in = w_in/100
lev = u_in.level
time = u_in.Time
# 计算 d theta/ dp
dthetadp = mpcalc.first_derivative(theta_in, axis=1, x=lev) 
##时间处理注意单位
time_sec = (time - np.datetime64('2022-07-14T06:00:00.000000000')) / np.timedelta64(1, 's')
# dT/dt
delta_t = time_sec[-1] - time_sec[0]

dT = mpcalc.first_derivative(t_in, axis=0,x=time_sec)
delta_t_bcast = delta_t.broadcast_like(t_in)
dTdt = dT/delta_t_bcast /units.sec
# 温度平流
adv_T = np.zeros((time.shape[0],lev.shape[0],lon.shape[1],lat.shape[2]))

for j in range(time.shape[0]):
    for i in range(lev.shape[0]):
        adv_T[j,i] = advection(to_np(t_in[j,i]),u=to_np(u_in[j,i]), v=to_np(v_in[j,i]), dx=dx[j], dy=dy[j])
adv_T=adv_T * units.K/ units.s
# Q1
vert_adv_theta = w_in * dthetadp * (p0/p_in)**kappa   / units.s
Q1 = cp * (dTdt + adv_T+ vert_adv_theta)
Q1 = np.nan_to_num(Q1, nan=0)
# 积分,nan值需要去除才能积分
g=9.8 # m*s^-2
q1_int = np.trapz(Q1,lev,axis=1)/g
代码语言:javascript
复制

绘图部分

代码语言:javascript
复制
代码语言:javascript
复制
# 创建画布
fig = plt.figure(figsize=(10, 8))
# 设置地图投影
ax = plt.axes(projection=wrf_proj)
# 设置地图范围
ax.set_xlim(cartopy_xlim(u))
ax.set_ylim(cartopy_ylim(u))

# 读取国界线和九段线
province = shpreader.Reader(
    '/home/mw/input/data5246/中国地图/China_provinces/China_provinces.shp')
nineline = shpreader.Reader(
    '/home/mw/input/data5246/中国地图/China_10-dash_line/China_10-dash_line.shp')
# 绘制国界线和九段线
ax.add_geometries(province.geometries(),
                  crs=ccrs.PlateCarree(),
                  linewidth=0.5,
                  edgecolor='k',
                  facecolor='none',
                  zorder=2)
ax.add_geometries(nineline.geometries(),
                  crs=ccrs.PlateCarree(),
                  linewidth=0.5,
                  color='k',
                  zorder=2)


# 用contourf方法实现等值线填充
plt.contourf(to_np(lons),
             to_np(lats),
             to_np(q1_int[2]),
             
             extend='both',
             transform=ccrs.PlateCarree(),
             cmap=cmaps.MPL_BuPu_r)
# 添加colorbar
cbar = plt.colorbar(ax=ax, extend='both', shrink=1)
cbar.set_label('atmospheric apparent heat source', fontdict={'size': 20})
cbar.ax.tick_params(labelsize=20)

# 设置刻度标签的字体大小
plt.tick_params(labelsize=15)
# 添加标题
plt.title((str(u.Time.values)[0:16]+'(UTC)'), loc='left', fontsize=20)
plt.show()
代码语言:javascript
复制

小结

  1. 用metpy需要非常注意单位
  2. 参考的公式与yanai的文献略有不同,感兴趣的同学可以去算算,文献是Seasonal Heating of the Tibetan Plateau and Its Effects on the Evolution of the Asian Summer Monsoon

3. 因为用的是wrfout文件,计算过程也磕磕绊绊,对公式的理解不到位。如有错误还请见谅。希望有同学用再分析数据去验证一下是否正确。 4. 通常计算用的资料为再分析日资料,好孩子不要学,偷懒用wrfout。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 气python风雨 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 导入并读取数据
  • 提取变量与插值
  • 计算部分
  • 绘图部分
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档