观潮 · 模式预报与气象 AI 观察
WPS 4.7.0 发布:GWDO 地形形阻场计算脚本、CMA-GFS GRIB2 直接可读、全球 1km 城市参数更新到 2020 年
WPS 在 2026 年 7 月 6 日发布了 4.7.0。这一版里有三条对实际业务影响比较直接的变化:GWDO 方案需要的次网格地形场现在可以在 WRF 网格上直接算出来、CMA-GFS 的 GRIB2 数据可以直接读、全球 1km 城市参数数据集更新到了 2020 年条件。
另外有两个 bug 修复的表现形式很隐蔽——一个会让 metgrid 输出文件里一个变量都没有,另一个会让土壤层字段被静默丢掉。
先说两个隐蔽的 bug
metgrid 输出里没有任何变量。 init_output_fields 例程里使用了一个未初始化的变量 is_subgrid_var,在特定条件下(比如 GNU 编译器版本 >= 14.2.0)会导致 metgrid 输出文件里没有定义任何输出变量(PR #291)。这类问题的麻烦在于 metgrid 不会报错退出——它照常运行、照常生成文件,只是文件是空的或缺字段,要到后面读数据时才发现。
土壤层字段被静默丢弃。 rd_grib2 里对 glevel1 和 glevel2 做了浮点比较。在某些编译环境下,算出来的土壤层与请求的整数层不能精确相等,结果就是中间的土壤字段被省略(PR #292)。原文的措辞是"计算得到的土壤层与请求的整数层不完全相等,导致土壤字段被省略",也就是"比较不相等 → 字段被丢掉",而不是"比较失败 → 报错"。
这一条的触发条件写得很具体:某些编译环境。也就是说它不是必现bug,而是在特定编译器/优化设置下才出现。这也是它容易被漏掉的原因——换一台机器编译,同样的 namelist 就正常了。
新增 compute_gwdo.py:GWDO 方案的地形场
新工具 compute_gwdo.py 用来计算 GWDO 方案用的次网格尺度地形场,可以直接在 WRF 网格上从全球高分辨率地形数据(典型是 GMTED2010 30 角秒)算出来(PR #281)。
背景是 WRF 4.8.0 里更新了 orographic gravity drag 选项 gwd_opt = 1,新增了 gwd_dx_factor 和 gwd_if_nonhyd 等参数。但 4.8.0 的 release notes 里明确写了这些新增选项需要配合特定配置使用,却没有说是哪个配置——WPS 4.7.0 补上的 compute_gwdo.py 就是那个缺失的环节:这个方案需要一组次网格尺度的地形字段作为输入,而以前没有现成工具生成,只能自己写。
所以如果你要用 gwd_opt = 1 的新能力,WRF 4.8.0 + WPS 4.7.0 是一对,不是可以拆开单独升级 WRF 的。
新增 plot_domains.py:替代 NCL 的 plotgrids_new.ncl
新 Python 脚本 plot_domains.py 是嵌套网格的可视化工具,release notes 说它"offers improved functionality over the NCL plotgrids_new.ncl script"(PR #277)。
对还在用 NCL 版本的人来说,这个改动意味着以后画网格域图不必再依赖 NCL 环境——纯 Python 装个 matplotlib 就行。如果你的工作流里依赖 plotgrids_new.ncl 输出固定样式的图做归档,换之前建议先比对一下样式差异。
CMA-GFS GRIB2 数据直接支持
现在 WPS 支持 CMA-GFS GRIB2 数据,包含一个新的 Vtable.CMA_GFS(Vtable 是告诉 WPS 该读哪些变量、如何映射到 WRF 变量名的文本表)。
ungrib 源码也做了修改,因为 CMA_GFS 的模式层在广义垂直高度坐标(generalized vertical height coordinates)上——这一点和常见的等压面模式不同,是需要专门处理的地方(PR #236)。另外 rd_grib2 例程被更新为把 CMA 识别为有效中心(icenter == 38)(PR #285)。
广义垂直高度坐标为什么需要特殊处理,值得说清楚。 常见的 GFS/ECMWF 类资料用的是等压面(pressure level)——每一层的气压值是固定已知的,读到某一层就等于知道它在哪。但 CMA-GFS 用的是广义垂直高度坐标:每个模式层只存一个"层顶/层底的高度系数",实际气压要靠这组系数逐层累加算出来。
这带来两个实际差异:
一是层数信息不直接给。用等压面资料时,你可以从 GRIB 里直接看到有哪些气压层;用广义高度坐标时,看到的是一组系数,得先在脑子里(或者代码里)把它们转成实际气压,才能判断模式层在哪。
二是插值到等压面的位置不同。WPS 的 ungrib 最终要把模式层整理成 WRF 能用的层次结构,这个转换过程对两种坐标的处理方式不一样。PR #236 改的就是 ungrib 源码里这部分。
这也是为什么这一条不能只靠 Vtable 解决——Vtable.CMA_GFS 解决的是"读哪些变量、映射成什么名字",而垂直坐标的转换必须改源码。两条一起才是完整的支持。
另外 rd_grib2 把 CMA 识别为有效中心(icenter == 38)这条是前置条件:GRIB2 头里有个"生成中心"字段,WPS 靠它判断数据来源。原来的代码不认识 CMA,遇到它的数据会当成无效文件处理。
这两条一起看:CMA-GFS 是中国气象局自己的全球预报模式,现在在 WPS 里是一等公民,不需要再手工拆 Vtable。这对做国产模式资料对比、或者想用 CMA-GFS 驱动 WRF 的人是直接的生产力提升。
全球 1km 城市参数更新到 2020 年条件
geogrid 新增了全球 1km 城市参数(URB_PARAM)的数据集支持,基于:
- GloUCP 数据,2020 年条件(Liao et al. 2025)
- Global Artificial Impervious Area(GAIA) 数据集,2020 年条件,用于全球 1km 城市/不透水面比例(
FRC_URB2D和IMPERV)(Gong et al.)
注意两个时间戳都写明了 year 2020 conditions。如果你之前用的是旧版本数据集,切换后城市建筑密度和不透水面比例都会变,做城市 UCM 敏感性试验时这属于输入数据变更,不是代码变更——两组结果不能直接对比。
具体变了哪些字段。 三个 WPS 变量受影响:
变量 · 含义 · 新数据源
`URB_PARAM` · 城市参数(建筑高度、密度等) · GloUCP,2020 年条件
`FRC_URB2D` · 城市占比 · GAIA,2020 年条件
`IMPERV` · 不透水面比例 · GAIA,2020 年条件
引用上要注意两点:GloUCP 那篇的数据说明是 Liao et al. 2025(数据集是 2020 年条件,但论文发表在 2025 年);GAIA 那篇是 Gong et al. 2020——正好是数据基准年,两篇的年份含义不一样,别混。
为什么这两套数据是配套的。 FRC_URB2D 和 IMPERV 描述的是"这个格子 urban 与不透水面各占多少比例",URB_PARAM 描述的是"城市建筑本身的高度和密度"。前两个来自 GAIA(人工不透水面产品),第三个来自 GloUCP(全球城市气候区划参数)。WPS 这次把两套 2020 年条件的数据一并接进来,意味着三个字段来自同一基准年,几何上也能对齐——如果只更新其中一个,另外两个还是旧基准年,比例关系就会错位。
这一点对做城市冠层模拟的人有实际意义:混用不同基准年的城市参数会让建筑密度和不透水面比例互相矛盾,模拟出的热岛强度会偏。所以升级后要么全用新的、要么全用旧的,不要只换一部分。
构建方面的变化
GNU Make 支持链接共享 libnetcdff 库(PR #203)。以前用共享库链接 netcdf-fortran 会有问题,这条修掉之后,共享库部署(多环境共存、避免重复编译 netcdf)更可行。
CMake 构建修了一堆问题:
修复项 · 说明
ungrib 日志文件名 · PR #274
MPI 支持 · PR #270、#271
若干构建选项补默认值 · PR #276
GRIB2 编译问题 · PR #280
CMake 路线的使用者之前如果在 MPI 或 GRIB2 上踩过坑,这版应该能过。
验收时怎么确认升级真的生效
这一版的两个 bug 修复都有一个共同特点:都不报错,只在数据层面出问题。所以验收不应该只看"编译通过、作业跑完",而要具体检查:
- metgrid 输出的 netCDF 里变量数量与 namelist 声明的一致(对应 #291)。
- 中间文件里要求的土壤层字段都在,层数与请求一致(对应浮点比较修复)。
- 如果用
gwd_opt = 1,确认compute_gwdo.py产出的次网格地形场确实被 WRF 读进去了。
全部 PR 清单:改了什么、对应哪个 PR
release notes 里每条改动都挂了 PR 号,整理成表可以直接当升级对照单用:
PR · 类别 · 内容
#281 · 新增 · `compute_gwdo.py`,在 WRF 网格上算 GWDO 用的次网格地形场
#277 · 新增 · `plot_domains.py`,替代 NCL 的 `plotgrids_new.ncl`
#278 · 新增 · 全球 1km 城市参数新数据集(GloUCP + GAIA,均为 2020 年条件)
#236 · 新增 · CMA-GFS GRIB2 支持,含新 `Vtable.CMA_GFS` 与 ungrib 源码改动
#285 · 修复 · `rd_grib2` 把 CMA 识别为有效中心(`icenter == 38`)
#292 · 修复 · `rd_grib2` 里 `glevel1`/`glevel2` 的浮点比较问题
#291 · 修复 · `init_output_fields` 里 `is_subgrid_var` 未初始化
#203 · 构建 · GNU Make 支持链接共享 `libnetcdff` 库
#274 · 构建 · CMake:ungrib 日志文件名
#270 · 构建 · CMake:MPI 支持
#271 · 构建 · CMake:MPI 支持
#276 · 构建 · CMake:若干构建选项补默认值
#280 · 构建 · CMake:GRIB2 编译问题
统计下来是 4 条新增、3 条修复、6 条构建相关,构建相关占了将近一半——这个版本的改动重心明显在工程侧而不是新增功能侧。
这一版的致谢名单
release notes 末尾单独列了四位贡献者:Umur Dinç(@bakamotokatas)、Cenlin He(@cenlinhe)、Andrew Song(@andrewsoong)、以及 @Geek-007。
这条信息有实际用处:如果升级后遇到问题,这四位是这一版具体改动的直接负责人,提问时带上 PR 号比泛泛地问"新版能不能用"更容易得到有效回答。
作者承认的限制
release notes 里对新增数据集的时间范围给了明确限定:GloUCP 和 GAIA 都是 2020 年条件。这不是"最近年份",是固定的 2020 年。做长期城市气候趋势分析时要记住这个基准年。
CMake 那几条修复没有说明覆盖范围,只列了 PR 号,没写具体哪些编译器/平台组合被验证过。
is_subgrid_var 那条修复有明确的触发条件写的是「特定条件下(例如 GNU 编译器版本 >= 14.2.0)」,但没说在这个条件之外是否绝对安全。 如果你的编译器版本低于 14.2.0 又遇到了同类症状,不能因为版本号对不上就排除这条。
两个 bug 修复都只说了「修复了什么」,没有说明「怎么验证修好了」。 release notes 里没有给出对应的测试用例或复现脚本,这意味着升级后是否真的修好,需要你自己按上面那三条验收清单去确认。
新数据集没有给出与旧版本数据集的差异量化。 只写了新的基准年是 2020 年,没写城市建筑密度、不透水面比例相对旧数据变了多少。做趋势对比时无法判断差异有多少来自数据更新、多少来自模式变更。
一句话判断
如果你在用 CMA-GFS 资料驱动 WRF,或者要做 1km 城市冠层模拟,这一版是明确的升级理由——前者省掉手工 Vtable,后者给你一套更新到 2020 年的官方全球 1km 参数。但要注意那两个 bug 修复都是"静默出错"类型,升级后请按上面三条具体验收,不要只看作业有没有正常跑完。