MetPy计算水汽通量散度的原理及与手动计算差异的问询
我正在用Python的MetPy模块计算水汽通量散度,代码如下:
import xarray as xr import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as mticker import pandas as pd import metpy.calc as mpcalc import matplotlib.patches as mpatches file1 = xr.open_mfdataset('/2018,19_1000to500/*.nc') file = file1.sel(longitude=slice(75.75, 77.25), latitude=slice(10.5, 9.5)) q1 = (file.q) * 1000 u1 = file.u v1 = file.v lat = file.latitude lon = file.longitude for k in range(1): level = ['1000'] # 可扩展为其他层级如'925','850'等 q1d = q1.resample(time='1D').mean().sel(level=int(level[k])) u1d = u1.resample(time='1D').mean().sel(level=int(level[k])) v1d = v1.resample(time='1D').mean().sel(level=int(level[k])) sdate = ['2018-08-08','2018-10-06','2018-11-10','2019-06-06','2019-08-06','2019-10-24'] edate = ['2018-08-17','2018-10-15','2018-11-19','2019-06-13','2019-08-14','2019-10-27'] for i in range(6): q1dm = q1d.sel(time=slice(sdate[i], edate[i])).mean('time') u1dm = u1d.sel(time=slice(sdate[i], edate[i])).mean('time') v1dm = v1d.sel(time=slice(sdate[i], edate[i])).mean('time') qu = q1dm * u1dm qv = q1dm * v1dm dx, dy = mpcalc.lat_lon_grid_deltas(lon, lat) HMD = np.array(mpcalc.divergence(qu, qv, dx=dx, dy=dy)) print(HMD)
已知MetPy计算散度的方式为$\frac{\partial u}{\partial x} + \frac{\partial v}{\partial y}$,我想确认:当传入qu(水汽通量的纬向分量)、qv(水汽通量的经向分量)而非u、v时,MetPy是否按$\frac{\partial (qu)}{\partial x} + \frac{\partial (qv)}{\partial y}$计算水汽通量散度?我手动计算该求和值后,与MetPy的结果存在微小差异(差异出现在第3或第4位小数),由于MetPy水汽通量散度的相关文档缺失,需要明确其计算所用的精确公式。
MetPy的
mpcalc.divergence()函数仅遵循散度的数学定义计算,不关心输入变量的物理意义:对于传入的水平分量参数(这里是qu和qv),计算逻辑就是$\frac{\partial \text{输入u分量}}{\partial x} + \frac{\partial \text{输入v分量}}{\partial y}$,对应你的场景就是$\frac{\partial (qu)}{\partial x} + \frac{\partial (qv)}{\partial y}$,这正是水汽通量散度的标准表达式。手动计算与MetPy结果的微小差异,主要来自两个方面:
- 差分格式不同:MetPy内部默认使用二阶中心差分计算偏导数,边界点会自动切换为一阶差分;你手动计算时可能使用了一阶差分或其他格式,导致结果偏差。
- 浮点数精度误差:不同计算顺序、数据类型(如numpy的float32与float64)会引发小数位的细微差异,这类误差属于数值计算的正常现象。
若要进一步验证,可查看MetPy的
divergence函数源码:其核心是调用mpcalc.first_derivative分别计算x、y方向的偏导数后求和,而first_derivative的默认差分方式就是二阶中心差分。
内容的提问来源于stack exchange,提问作者Sreeshma

