☰
WRF前处理实战:从ERA5数据下载到WPS三步走,避开新手常见坑
2026/10/4 4:13:43 网站建设 项目流程

写这篇日记的时候,我刚好把一套WRF实例从数据下载跑到了WPS前处理结束,整个过程可以用“渐入佳境”来形容。软件装好的兴奋劲过去之后,真正让人头大的其实是数据,很多朋友私信问我,WRF装完了下一步到底干什么,为什么照着教程下载数据总是各种报错。说实话,我上周也卡在最基础的下载和格式转换上,折腾了两天才迈过这个坎。这篇日记就把我这次完整撸过一遍的“数据下载 + WPS前处理”流程整理出来,每一步都写清楚为什么这么做,踩过的坑也原样记录,给准备亲自上手跑WRF的人当一份路线图。

WRF要跑起来,本质是一个“食材加工”的过程。模型本身只是灶台和锅,你手里得有处理好的食材——气象驱动数据,还得把灶台的火候(参数化方案)和锅的尺寸(模拟区域)都定好,才能开始炒菜。WPS(Weather Preprocessing System)就是那个洗菜、切菜、配菜的厨师,负责把下载回来的原始气象数据,加工成WRF能直接下锅的格式。这一环如果处理不好,后面real.exe和wrf.exe跑得再顺,结果也是错的。所以我强烈建议每一位新手把WPS这一步当回事,耐心走完。

1. 这次要解决什么:从“装好WRF”到“喂饱WRF”

1.1 很多人卡住不是因为模型,而是因为数据

我翻了不少自学群里的提问,发现一个规律:大家问得最多的不是物理参数化方案怎么选,而是“GRIB文件从哪下”“ERA5下载完是netcdf格式怎么处理”“geogrid一直报错找不到数据”。这些问题看起来散,其实都指向同一个环节——前处理。

首先是数据源选错。有人拿ERA5下载出来的NetCDF文件直接丢给ungrib,结果报错信息根本读不懂,以为是自己WRF装坏了。还有人下数据的时候把全球范围都勾上了,一个时次就几十个GB,硬盘直接告急。这些都是典型的新手坑,我在1.2节把WRF的完整运行链路先捋清楚,后面就不容易跑偏。

1.2 WRF跑通的完整链路:从原始数据到模式积分

WRF的完整流程是这样的:

  1. 下载原始气象资料(再分析资料或预报资料),比如GFS、FNL、ERA5;
  2. 准备静态地理数据(地形、土地利用、植被覆盖等),这是geogrid要用的;
  3. 跑WPS的geogrid.exe,把模拟区域网格化,并插值地形和土地利用数据;
  4. 跑WPS的ungrib.exe,把GRIB格式的气象资料解压成中间格式;
  5. 跑WPS的metgrid.exe,把气象场水平插值到geogrid生成的网格上;
  6. 跑real.exe,生成初始条件和边界条件;
  7. 跑wrf.exe,开始数值积分。

很多人以为数据下载完就能直接real.exe,完全忽略了中间还有个WPS。WPS的作用就是把“别人的网格数据”变成“你的网格数据”,同时把格式统一成WRF能识别的中间格式。

用做饭来打比方,geogrid相当于确定你家炒锅的形状和大小,ungrib相当于把冷冻食材解冻,metgrid相当于把食材切成符合锅型的大小。三步缺一不可。

我这次用的数据是ERA5再分析资料,区域选的是某个局地范围,嵌套层数用了两层。接下来就按“数据下载 → geogrid → ungrib → metgrid”的顺序,把每个环节的实操过程都摆出来。

2. 数据下载:选对数据源,等于成功一半

2.1 再分析资料怎么选:GFS、FNL、ERA5到底有什么区别

先说结论:如果你是新手,想尽快跑通流程,建议用NCEP FNL再分析资料;如果你做科研、需要更高分辨率,再考虑ERA5。两者下载方式和支持程度差别很大,但FNL数据对WPS极其友好。

我在表里整理了一份对比,这是我自己选数据源时候的判断依据:

数据源水平分辨率时间范围下载渠道对WPS的友好程度适用场景
GFS预报场约0.25度实时滚动NOMADS等高(Vtable.GFS直接支持)业务预报、个例实时模拟
NCEP FNL再分析1度/0.25度1999年至今NCAR RDA等高(Vtable.GFS直接支持)科研个例模拟、模式验证
ERA5再分析0.25度(约31km)1950年至今CDS(Climate Data Store)中(下载GRIB格式可直接用)高分辨率长时间模拟
ERA5-Land0.1度(约9km)1950年至今CDS低(陆面变量,通常做离线驱动)陆面过程、水文模拟

选型逻辑很简单:文件格式越接近“WPS能直接吃”的状态,越适合入门。FNL数据直接就是GRIB2格式,配合Vtable.GFS就能跑,几乎没有坑。ERA5的下载方式更现代,但很多人习惯性选NetCDF格式,结果ungrib根本不认识,这个我在下一节细讲。

2.2 ERA5数据下载实操:CDS API脚本与关键参数

如果你已经决定用ERA5,那下载这一步建议直接用CDS API的Python脚本。我第一次用网页端勾选下载,手动点几十个时次的文件,点得手都酸了,而且网页端断线之后只能重来。换成脚本之后才算是进入正轨。

先安装CDS API库:

pip install cdsapi

然后在CDS官网注册账号,拿到个人API Key,写到配置文件里。之后写一个下载脚本,核心思路是:指定变量、区域、时间、格式,一次性提交下载请求。

下面是我这次用的下载脚本节选,区域和时间范围可以根据你自己的模拟区域改:

import cdsapi c = cdsapi.Client() c.retrieve( 'reanalysis-era5-single-levels', { 'product_type': 'reanalysis', 'variable': [ '10m_u_component_of_wind', '10m_v_component_of_wind', '2m_dewpoint_temperature', '2m_temperature', 'mean_sea_level_pressure', 'surface_pressure', 'sea_surface_temperature', ], 'year': '2020', 'month': '07', 'day': [ '01', '02', '03', '04', '05', '06', '07', '08', '09', '10' ], 'time': [ '00:00', '06:00', '12:00', '18:00' ], 'area': [ 40, 115, 30, 125, ], 'format': 'grib', }, 'era5_single_level_202007.grib')

压力层数据也要单独下一份,因为WRF跑三维模拟需要多层的气压、温度、湿度、风场。通常我会再建一个reanalysis-era5-pressure-levels的请求,变量选geopotential、relative_humidity、temperature、u_component_of_wind、v_component_of_wind,层级从1000 hPa到100 hPa,按自己的模拟顶高设定。

有几个细节必须注意:

  • area参数的顺序是北、西、南、东,写反了会下载到奇怪的位置;我犯过这个错,第一次下出来的区域跑到了海里,浪费了一晚上。
  • 时间段要包含模拟开始前的一段spin-up时间,以及模拟结束后的边界数据。“只下模拟时段”是新手常犯的错误,后面real和wrf会缺边界值报错。
  • format字段下载时务必要选grib,不要选netcdf。新版WPS虽然也支持NetCDF输入,但配置起来复杂,新手阶段直接用GRIB格式最稳妥。

2.3 ERA5-Land的蒸发通量符号:一个小坑

这段时间我在尝试把陆面过程也跑起来,所以顺手关注到ERA5-Land的下载和使用。ERA5-Land的分辨率更高(约9km),主要提供陆面变量,比如土壤湿度、土壤温度、蒸发量、径流等。

很多人下载完ERA5-Land的蒸发数据,发现数值是负的,第一反应是数据出错了。其实不是错,是ECMWF的通量变量有符号约定:向下为正,蒸发意味着水分从地表向大气输送,所以是负值。类似的情况在感热通量、潜热通量里也存在,处理之前先看官方文档的变量说明,不要想当然地取绝对值。

如果你只用它做离线驱动或者水电模拟,负号本身不影响趋势判断,但如果你要计算水量平衡,就必须搞清楚单位换算。ERA5-Land里很多通量单位是kg m-2 s-1,累积量需要乘时间步长,我建议写一个独立的处理脚本专门做单位换算和符号判断,免得后面分析时被坑。

2.4 下载避坑:连接中断、硬盘爆满、命名混乱

数据下载的坑主要在三点。

第一,连接中断。ERA5批量下载数据量很大,动辄几十GB,网络稍微不稳就中断。我的经验是不要一次性提交一个超大的下载任务,按月份拆分成多个小任务,中断之后重试的成本低。另外下载脚本加一个循环重试逻辑,遇到报错就等待几秒继续请求。

第二,硬盘空间。下载前先确认本地剩余空间,至少保留模拟所需数据体积的3倍余量。我这次下载单层+压力层加起来约15GB,解压和中间格式转换膨胀到30GB以上,硬盘差点没扛住。规划要趁早。

第三,文件命名混乱。下载下来的GRIB文件名往往不直观,我习惯按“变量_区域_时间段”的方式重命名,比如era5_pl_d02_2020070100.grib。后面WPS链接文件的时候一目了然,省去反复确认的时间。

3. WPS前处理:三步走全拆解

3.1 动手之前先把namelist.wps填明白

WPS三个可执行程序geogrid.exe、ungrib.exe、metgrid.exe共用同一个配置文件namelist.wps。所以先把配置填对,后面三个步骤基本不会出错。

这是我这次跑两重嵌套用的模板,里面的关键项我逐个解释:

&share wrf_core = 'ARW', max_dom = 2, start_date = '2020-07-01_00:00:00', end_date = '2020-07-10_00:00:00', interval_seconds = 21600 / &geogrid parent_grid_ratio = 1, 3, i_parent_start = 1, 60, j_parent_start = 1, 40, e_we = 120, 151, e_sn = 100, 151, geog_data_res = 'default', 'default', dx = 9000, dy = 9000, map_proj = 'lambert', ref_lat = 35.0, ref_lon = 120.0, truelat1 = 30.0, truelat2 = 60.0, stand_lon = 120.0, / &ungrib out_format = 'WPS', prefix = 'ERA5' / &metgrid fg_name = 'ERA5' /

几个容易理解错的地方:

  • interval_seconds是驱动数据的时间间隔,我下载数据是6小时间隔,所以填21600秒。这个必须和GRIB文件的实际间隔一致,否则metgrid会找不到对应时间的文件。
  • e_we和e_sn是网格点数,而不是区域经纬度范围。网格点数乘分辨率才是模拟范围。新手想把范围设置成“东经115到125度”时,会误把度数填进去,这是典型错误。
  • i_parent_start和j_parent_start是从父域左下角开始的起始网格序号。如果嵌套层数大于1,第二层起始位置必须落在父域范围内,并且要保证嵌套层分辨率是父域的整数倍。
  • geog_data_res一般填default,WPS会自己在静态数据里查找可用的最高分辨率数据。如果手动指定modis_lc之类的方案,必须确认对应数据在geo_em目录里真的存在。

3.2 geogrid:静态地理数据与地形插值

geogrid的职责是在你设定的模式网格上,插值地形高度、土地利用、土壤类型、植被覆盖等静态地理数据。这些数据几乎不随时间变化,所以只需要处理一次。

运行前需要准备静态地理数据。官方数据包geog_complete.tar.gz体积不小,我建议下载后解压到WPS/geog目录下,然后在namelist.wps里用geog_data_path指定路径。如果是初学者,可以直接把路径写进&geogrid:

&geogrid geog_data_path = '/home/xiaozeng/WPS/geog/' /

准备好之后运行:

./geogrid.exe

正常情况下会生成geo_em.d01.nc、geo_em.d02.nc等文件。如果没有生成,常见的原因有两个:

  • geogrid.exe找不到GEOGRID.TBL文件,需要把它从geogrid/GEOGRID.TBL复制到当前目录,或者设置环境变量GEOGRID_TBL_PATH;
  • 静态地理数据路径设置错了,geogrid会报Geog data not found,这时候去检查geog_data_path下面是否真的有对应变量目录。

我这次跑的时候还遇到了一个隐蔽的问题:嵌套层静态数据里某些变量(比如土地利用)只下载了粗分辨率的版本,geogrid虽然没报错,但生成的geo_em.d02.nc里土地利用数据非常模糊。后来我在namelist.wps里把第二层的geog_data_res改成'modis_lc',重新跑了一遍geogrid,效果才正常。

3.3 ungrib:从GRIB到中间格式

ungrib是WPS里最容易被忽略、也最让人困惑的一步。它的作用是把GRIB编码的气象数据解码成一种简单的中间格式,让metgrid能统一读取。

执行前先确认两件事:

第一,Vtable要链接正确。Vtable本质是一张“字段映射表”,告诉ungrib某个GRIB变量对应到WRF中间格式里的哪个字段。GFS和FNL数据用Vtable.GFS,ERA5数据一般也用Vtable.GFS(因为ERA5的变量命名和GFS类似)。链接方式:

ln -sf ungrib/Variable_Tables/Vtable.GFS Vtable

第二,GRIB文件要链接到当前目录。WPS提供了一键链接脚本:

./link_grib.csh /path/to/your/data/era5_*.grib

链接之后,当前目录会生成一堆GRIBFILE.AAA、GRIBFILE.AAB这样的符号链接文件。注意link_grib.csh是按文件名顺序链接的,如果时间顺序不对,后面metgrid出来的数据顺序也会乱。我建议下载数据时就统一文件名格式,确保年份、月、日、时在文件名中的顺序符合字典序。

然后运行:

./ungrib.exe

如果namelist.wps里prefix = 'ERA5',输出文件会命名为ERA5:2020-07-01_00这样的中间格式文件。

ungrib最常见的报错是:

ERROR: Error opening GRIB file

排查思路有两个:一是GRIB文件本身损坏,重新下载该时次;二是文件不是GRIB格式,比如有人把NetCDF硬改后缀成.grib,ungrib当然不认。还有更隐蔽的情况是GRIB2文件缺少索引信息,ungrib会尝试读取但最终超时,这种建议先检查文件是否完整。

3.4 metgrid:把气象场插值到模式网格

ungrib输出的中间格式仍然是原始数据自带的水平网格,和WRF网格不一定重合。metgrid的作用就是把气象场水平插值到geogrid生成的模式网格上。

运行前确认namelist.wps里fg_name值要和ungrib的prefix一致。比如我的ungrib输出前缀是ERA5,那metgrid部分就要写:

&metgrid fg_name = 'ERA5' /

然后直接运行:

./metgrid.exe

成功后会生成met_em.d01.2020-07-01_00:00:00.nc、met_em.d01.2020-07-01_06:00:00.nc等文件。

metgrid报错最典型的一类和时间有关,例如:

ERROR: Failed to find input data for time 2020-07-05_00

这是GRIB数据里缺了那个时次,或者下载时少选了某个时间步。遇到这个报错,先回去查原始数据时间范围,不要急着改namelist。

另外有一个细节:metgrid输出的NetCDF文件里,纬度坐标叫XLAT_M,经度坐标叫XLONG_M,初次接触的人容易和XLAT_U、XLONG_V搞混。前者是质量点(格点中心)坐标,后者是风场交错的U/V点坐标,后面做后处理时用哪个取决于你读取的变量在哪个网格上。

4. 运行中常见的坑与排错实录

4.1 WPS运行报错速查表

我把这周踩过的坑整理成一张速查表,遇到类似报错可以直接对照排查。

报错信息可能原因解决办法
Geog data not foundgeog_data_path路径错误,或者静态数据未解压完整检查路径下是否有HGT、LANDUSE等目录
Could not open GEOGRID.TBL找不到GEOGRID.TBL文件将geogrid/GEOGRID.TBL复制到运行目录,或设置环境变量
Error opening GRIB file文件损坏、不是GRIB格式重新下载,确认后缀名与真实格式一致
Failed to find input data for time下载数据缺了对应时间步检查原始GRIB文件覆盖范围,补下缺失时次
metgrid: Symbolic links faillink_grib.csh没有正确执行确认执行了脚本,且链接文件指向真实存在的GRIB文件
ungrib: Bad vtableVtable链接错误或版本不匹配重新链接对应数据源的Vtable
生成的geo_em.nc里地形和实际差很多静态数据路径下分辨率不足,或被默认值覆盖将geog_data_res指定为更高分辨率数据集名

表格里的问题,我基本都遇到过一遍,尤其是前两项,几乎每次换机器、换环境都会踩一次。关键是一旦理解了每个程序需要什么输入、输出到哪,排错很快。

4.2 环境与版本带来的隐蔽问题

WPS对编译环境非常敏感,不同编译器、不同NETCDF版本,跑出来的结果可能完全不一样。有一次我换了集群,netcdf库是新的,但环境变量没有指向新路径,结果geogrid能跑,metgrid却一直段错误。

所以我的建议是:跑之前先执行:

which netcdf nc-config --version

确保每个可执行程序编译时的库和运行时用的库是同一个。如果你用的是一键安装脚本(比如WPS 4.x的编译脚本),更要留意输出日志里有没有警告。

另一个隐蔽问题是库文件冲突。机器上可能同时装了Intel编译器版本的netcdf和GNU编译器版本的netcdf,如果混用,轻则报错,重则数据静默出错。我通常习惯在.bashrc里写死一套环境:

export NETCDF=/home/xiaozeng/libs/netcdf export PATH=$NETCDF/bin:$PATH export LD_LIBRARY_PATH=$NETCDF/lib:$LD_LIBRARY_PATH

4.3 验证前处理结果:别急着跑real.exe

很多人跑完metgrid,看到生成了met_em文件就急着进real.exe。我建议先花五分钟检查一下数据质量。

用ncdump -h查看met_em文件头,确认变量完整:

ncdump -h met_em.d01.2020-07-01_00:00:00.nc | less

重点看有没有PRES(气压)、GHT(位势高度)、TT(温度)、RH(相对湿度)、U(纬向风)、V(经向风)。如果某一层气压变量值全是0,说明ungrib阶段对应变量解码失败,需要回炉重跑,不要带着错误数据往下走。

再检查空间范围。把XLAT_M和XLONG_M的最小最大值打印出来,和你的模拟区域设定对比。如果区域偏了,可能是area或ref_lat/ref_lon写错。

还有一个我特别想说的小技巧:用Python的netCDF4库读一下温度变量:

import netCDF4 as nc f = nc.Dataset('met_em.d01.2020-07-01_00:00:00.nc') tt = f.variables['TT'][0, 0, :, :] print(tt.min(), tt.max())

温度单位是开尔文,夏季7月中午的近地面温度应该在290K左右。如果读出来是几千K或者负值,基本可以断定数据解码有问题,不用纠结结果对不对了。

5. 我这阶段最想分享的三句话

第一句话是:跑通WRF流程,真正的瓶颈不是模型物理,而是前处理。很多教程把重点放在参数化方案的选择上,对新手来说意义不大,先把数据链路跑通,你才有资格谈物理过程。

第二句话是:数据下载和文件名管理要当成正式工程来做。我吃过亏之后,现在所有下载脚本都会输出一个download_log.txt,记录时间范围、变量列表、区域框,后面出问题能快速回溯。

第三句话是:前处理结果一定要可视化验证一次。哪怕就是简单画出地形高度图、温度分布图,都比闷头跑wrf.exe靠谱得多。我每次metgrid完都会快速出一个图,确认模拟区域没有落到海上、地形没有异常,这一步几乎帮我挡住了80%的“模型跑飞”问题。

这周的进度就到这,WPS前处理走通之后,我准备进入real.exe和wrf.exe的实际积分环节,跑完一轮完整模拟再回来更新下一篇日记。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询