WRF真实案例跑通:WPS前处理全流程实操与避坑指南
发布时间:2026/10/4 2:06:26 锦皓数字建站

真到了第三篇总算配得上“渐入佳境”这四个字。前两篇我还被困在编译环境里一个库一个库地给WRF“治病”这篇终于开始做正事——跑一个真正的WRF实例。所谓实例说白了就是一句话给WRF一套真实的天气资料让它在你的模拟区域里跑出未来几十小时的气象场。这套流程的第一步也是最磨人的一步就是从数据下载开始经过WPSWeather Preprocessing System气象预处理系统处理把原始GRIB格式的全球资料变成WRF可以读懂的区域网格场。整个过程我没有少踩坑漏时次、时区写错、Vtable没链接、静态地理数据没下全……每一个错误都能让人原地怀疑人生。这篇文章把我跑通的完整路径记录下来从数据下载到WPS三个核心程序全部跑完拿到met_em中间文件为止。目标读者就是刚装好WRF、准备跑第一个真实案例的人如果你也卡在这一步这篇应该能帮你省下至少一个星期的弯路。先插一句题外话气象圈说的WPS是WRF Preprocessing System跟那个办公软件没关系它是完全开源的程序套件不需要任何破解激活之类操作。接下来所有内容都围绕这个真正的前处理系统展开。1. 数据源怎么选FNL稳、ERA5强我建议新手先用FNL开刀1.1 两种驱动数据到底差在哪WRF是区域模式它跑不了全球只能在模拟区域四周和初始时刻获得“外力”——这些外力就来自全球模式或再分析资料。模拟结果真不真一半取决于驱动数据好不好。目前主流的免费数据源基本就是两个NCEP的FNL以及ECMWF的ERA5。FNL是NCEP提供的全球分析资料经过资料同化把观测信息融进模式初始场产品稳定历史上一直在用。RDA数据中心里面有两类常用集合ds083.2是1度分辨率的FNLds083.3是0.25度分辨率的FNL/GDAS分析场文件都是现成的GRIB2格式每6小时一个时次拿回来就能喂给WPS。ERA5是ECMWF第五代全球再分析0.25度分辨率时间上能做到小时级学术论文里用得非常多。它的优点是精度高、变量全、历史跨度长缺点是下载流程比FNL麻烦需要在CDS数据平台勾变量、排队、等任务完成而且要让WRF跑起来必须同时下载气压层和地面变量漏一个后面都会出问题。我给一个实际对比表格方便你决定对比项FNLds083.2/ds083.3ERA5机构NCEPECMWF水平分辨率1度 / 0.25度0.25度约31公里时间分辨率6小时1小时下载门槛低RDA页面按日期选即可中需要CDS账户并配置变量文件格式直接是GRIB2可下载GRIB或netCDF三层变量GRIB文件里已包含不用操心必须分别下载pressure levels和single levels新手友好度高中适合场景初学练手、快速跑通流程、粗网格模拟研究级模拟、高精度案例分析如果你是第一次跑WRF实例我强烈建议先用FNL开刀。不是因为ERA5不好而是因为你现在的任务是把流程跑通FNL的“省心”是最大优势一个grib2文件里该有的东西全有。1.2 FNL下载的完整链路附wget要点FNL从RDA下载具体说就是NCAR的研究数据档案库rda.ucar.edu。第一次用需要注册账号然后在数据集页面接受数据使用协议之后才能进到文件列表。下载的操作路径大致是进入RDA找到ds083.2这个数据集在Data Access区域选择Web File Listing按年/月目录浏览文件把模拟时段需要的时次勾选加入下载列表页面会生成一个带认证信息的wget脚本保存到本地执行。这里有个关键点RDA的下载链接带有cookie认证不能用浏览器随便复制个URL交给wget硬下那样大概率会403。正确做法是保存站点生成的下载脚本或者用--load-cookies参数带着cookie文件下载。我自己实际用到的命令简化下来长这样# 假设你已经在RDA页面拿到了下载列表download_list.txt # -c 支持断点续传这个参数在校园网环境下太重要了 wget -c -i download_list.txt下载完成后别急着进行下一步先做一次完整性体检ls -lh fnl_20230601_*.grib21度分辨率的FNL每个时次大约几十MB0.25度的大约两三百MB。如果哪个时次文件大小明显异常或者干脆是0KB马上补下不然等到metgrid阶段你会发现数据缺时次又得回头重新折腾。1.3 ERA5能带来什么又要付出什么如果你执意要用ERA5或者你的研究场景需要更高精度驱动那下载阶段要比FNL多花不少功夫。在CDS平台下载ERA5至少要注意三件事第一必须下载气压层数据。站在CDS页面要找到“Reanalysis - ERA5, pressure levels”这个数据集勾选温度、风场、相对湿度、位势高度等三维变量再选覆盖你模拟区域的气压层。常见选择是1000、975、950、925、900、850、800、700、600、500、400、300、200、150、100 hPa这些层基本能满足绝大多数中尺度模拟。第二必须配合下载地面单层变量。WPS的ungrib阶段不仅需要三维气压层数据还需要2米温度、2米露点温度、10米风场、海平面气压、地表气压。这些变量在另一个数据集“Reanalysis - ERA5, single levels”里。第三格式尽量选GRIB。CDS允许选netCDF或GRIB虽然最终都能用但GRIB可以直接被link_grib.csh脚本处理netCDF还得额外转格式属于自己给自己加难度。一个常见误区是新手只下载了single levels就把数据交给WPS结果ungrib倒是跑完了到real阶段直接崩溃报错提示缺三维场。我见过不止一次这种问题。所以如果你想确认WPS自带的Vtable能不能正确处理ERA5文件先进WPS/ungrib/Variable_Tables/看一下有没有Vtable.ERA5这个文件WPS 4.x版本一般自带老版本没有的话就直接对照Vtable.GFS改一版关键的变量名映射。2. 别急着敲命令先搞懂WPS三个程序各管哪一段很多新手拿到WPS第一反应就是执行./geogrid.exe、./ungrib.exe、./metgrid.exe按顺序跑完就完事。结果一旦报错完全不知道问题出在哪个环节更不知道怎么排查。我建议你在敲第一条命令之前先花十分钟理解这三个程序的职责边界。它们本质上是一条流水线缺一环或者顺序错了后面都白搭。2.1 geogrid给模拟区域“画底图”geogrid负责定义模拟区域和把静态地理数据插值到网格上。静态地理数据是什么就是地形高度、土地利用类型、土壤类型、植被覆盖这些不随时间变化的地理信息。WRF要跑在一个真实的区域上必须知道你这个区域哪里有山、哪里有水、城市和农田边界在哪。这些信息以原始栅格数据的形式存在WPS_GEOG目录里geogrid会把你设定的网格区域和这些静态数据叠在一起插值输出到一个geo_em.d01.nc文件。可以把它理解成“画户型图”。你告诉它房间多大、墙在哪里、窗户朝哪它给你一张标准底图。后面所有的家具气象数据都要按这张底图来摆放。2.2 ungrib把GRIB“翻译”成中间格式ungrib的任务是把下载回来的GRIB格式气象数据解压并提取成WPS内部使用的“中间格式”。为什么需要这一步因为GRIB是气象领域专用的二进制编码格式虽然信息密度高但WRF的可执行程序不能直接读尤其不同来源的GRIB文件里变量编号和单位还不太一样直接喂进去很容易解释错。ungrib怎么知道某个变量该提取、提取后叫什么名字、用什么单位靠的是Vtable。Vtable本质上是一份“字典”把GRIB里的变量编码对应到WPS中间格式的标准名。比如GRIB里的某个参数编号代表温度Vtable就告诉ungrib“把这个变量提出来命名为TT单位用开尔文”。ungrib的产出是一串FILE:YYYY-MM-DD_HH格式的中间文件每个时次一个。这些文件已经和WRF“说同一种语言”了但还没有落到你定义的网格上。2.3 metgrid把气象场“摆放”到模型网格metgrid干的是最后一步空间匹配。ungrib提取出来的气象数据是原始全球模式的水平网格比如FNL的1度网格经纬度都是规则的。但你模拟区域用的是Lambert投影下的区域网格格点和全球网格并不是对齐的。metgrid做的工作就是水平插值把全球网格上的气压、温度、风、湿度等物理量插到geogrid生成的那个geo_em.d01.nc网格上。它的输出是met_em.d01.日期_时间.nc文件命名里带网格编号d01。到这一步为止WPS的使命就完成了——原始GRIB数据变成了WRF的real.exe可以直接读取的区域网格驱动文件。理解这三个阶段的逻辑之后你再看后面每一步操作就会很清楚自己正在处理的是哪个环节报错信息也能更快定位。3. namelist.wps逐项拆解一份可以直接抄的实例配置配置是WPS的灵魂。下面我给出一个完整可用的namelist.wps实例模拟时段选的是2023年6月1日00时世界时UTC到当天18时一共4个FNL时次区域中心放在34°N114°E附近单层模拟域水平格距30公里网格规模120×100。share wrf_core ARW, max_dom 1, start_date 2023-06-01_00:00:00, end_date 2023-06-01_18:00:00, interval_seconds 21600, io_form_geogrid 2, / geogrid parent_id 1, parent_grid_ratio 1, i_parent_start 1, j_parent_start 1, e_we 120, e_sn 100, geog_data_res default, dx 30000, dy 30000, map_proj lambert, ref_lat 34.0, ref_lon 114.0, truelat1 30.0, truelat2 60.0, stand_lon 114.0, geog_data_path /home/smallzeng/WPS_GEOG / ungrib out_format WPS, prefix FILE, / metgrid fg_name FILE io_form_metgrid 2, /这份配置每行都有意义下面逐项拆解。3.1 时间参数整条链路的第一步错一个全白跑share里的start_date和end_date是整条WPS流程的时间锚点。注意它们必须是世界时UTC不是本地时间。如果你模拟的是中国区域本地时间比UTC快8小时如果把2023-06-01_00:00:00当成北京时间去填实际对应的是UTC的6月1日16时但FNL文件名里用的是UTC下载数据时你一定会发现时间对不上。interval_seconds是相邻时次之间的秒数间隔。FNL数据每6小时一次对应21600秒。这个参数会告诉ungrib和metgrid在start_date到end_date之间应该期望多少个中间文件。如果你下载的数据间隔不是6小时比如用了3小时间隔的GFS就要改成10800。还有一个容易忽略的点模拟时段必须被数据完整覆盖。如果你打算从6月1日00时开始跑哪怕只跑到当天18时那你的数据至少要从6月1日00时覆盖到6月1日18时。假如你计划加一段spin-up时间让模式先“热起来”比如提前6小时开始积分那数据下载范围就要从5月31日18时算起。3.2 模拟区域与投影网格数量、格距和Lambert的秘密geogrid里的参数决定了你的“户型图”。e_we和e_sn是东西、南北方向的网格点数量dx和dy是格距单位米。拿这个实例来说120个网格点乘30公里东西跨度约3600公里100个网格点乘30公里南北跨度约3000公里。30公里格距是一个很好的入门选择算得快、对驱动数据分辨率要求不高也能看出天气系统的大结构。map_proj选了lambert这是中纬度区域模拟最常用的投影因为它在双标准纬线附近变形小。ref_lat和ref_lon是模拟区域中心点坐标truelat1和truelat2是两条真纬线WRF的Lambert投影通过它们控制变形分布stand_lon是投影中心经线在中纬度区域通常直接设为ref_lon。你可能好奇为什么要关注投影。原因是WRF的网格不是经纬度规则网格而是投影平面上的直角网格。如果两个真纬线设得太离谱模拟区域的形状会发生明显畸变直接影响后面的metgrid插值质量。常规经验中纬度案例用lambert低纬度热带气旋或赤道研究用mercator极地研究用polar_stereographic。3.3 静态地理数据路径最容易忽略的硬依赖geog_data_path指向静态地理数据所在目录也就是WPS_GEOG解压后的目录。这个路径必须存在而且建议用绝对路径不要用相对路径或者~符号因为geogrid在不同运行目录下对相对路径的解释可能不一致到时候报错又得排查半天。WPS_GEOG数据包需要另外下载不包含在WPS源码里。WPS官方页面提供了完整包和分项数据包新手直接下载完整包最省事解压后大概二三十GB。如果你只做粗分辨率模拟理论上有些数据可以只要默认分辨率版本但为了一次跑通我还是建议下载完整包。最常见的一个错误就是没下载静态地理数据就运行geogrid程序跑几秒就报错退出。记住geogrid必须依赖WPS_GEOG目录下的地理数据才能生成geo_em.d01.nc。3.4 别忘了和namelist.input保持默契namelist.wps处理完只是半程后面real.exe和wrf.exe读的是namelist.input那里面的max_dom、start_date、end_date、e_we、e_sn、dx、dy等参数必须和namelist.wps保持基本一致。如果WPS按120×100的网格生成了met_em文件real却按100×120去读结果就是数组不匹配或者直接报错。另一个隐性契约是interval_seconds。WPS生成的met_em文件是每隔6小时一个但real运行时的输入间隔也受namelist.input中interval_seconds的影响。很多人在WPS阶段跑通了到real阶段又开始崩溃回头一查两个namelist的间隔参数不一致。4. WPS三步走实操从裸数据跑到met_em文件配置没问题数据下载完整接下来就是老老实实按顺序跑三个程序。每一步都有对应产物跑完一步检查一步不要一口气把所有命令都敲了出了错很难定位。4.1 跑geogrid耐心等一次“画图”确保已经在WPS根目录输入./geogrid.exegeogrid的运行时间取决于区域大小和静态数据分辨率一般从几十秒到几分钟不等。程序运行期间没有明显的进度条看起来像“卡住”了其实是它在默默读地形、土地利用数据并插值。运行结束后检查日志尾部和产物tail -5 geogrid.log ls -lh geo_em.d01.nc正常的日志末尾会显示类似“Successful completion of geogrid”的提示geo_em.d01.nc文件生成且大小正常通常在几十MB级别。如果日志里出现了ERROR: Could not open geogrid file基本可以断定geog_data_path路径写错或静态数据缺失。4.2 链接GRIB文件配置Vtable跑ungribungrib之前有两件事必须做少一件都会白跑。第一把下载的GRIB文件链接成ungrib认识的序列文件。WPS提供了现成脚本./link_grib.csh /home/smallzeng/data/fnl/fnl_20230601_*.grib2 ls -l GRIBFILE.*正常会生成GRIBFILE.AAA、GRIBFILE.AAB这样的软链接指向你每个grib2文件。如果GRIBFILE.*一个都没有说明link脚本没找对文件路径或者通配符没匹配到任何文件。第二把对应的Vtable软链接到当前目录并命名为Vtableln -sf /home/smallzeng/WPS/ungrib/Variable_Tables/Vtable.GFS ./Vtable这里用ln -sf是为了幂等即使之前已经链接过也不会报错。FNL的GRIB2文件直接用Vtable.GFS就行别的表不用考虑。然后运行ungrib./ungrib.exe运行成功后当前目录会出现FILE:2023-06-01_00这样的中间文件。查看时注意冒号在shell里是特殊字符要加引号ls -lh FILE:2023-06-01_00 FILE:2023-06-01_06 FILE:2023-06-01_12 FILE:2023-06-01_18正常的中间文件大小从几十MB到一两百MB不等。如果ungrib日志里有ERROR: Bad grib2 file或者提示找不到Vtable自己检查GRIB文件和Vtable链接。4.3 跑metgrid与解读三个日志最后一步运行metgrid./metgrid.exe它会读取所有FILE:*中间文件把它们插值到geo_em.d01.nc的网格上。跑完后检查ls -lh met_em.d01.*正常情况下应该生成与模拟时段对应的4个文件命名类似met_em.d01.2023-06-01_00:00:00.nc一直到2023-06-01_18:00:00.nc。数量不对就说明某个时次的数据缺失或中间文件时间不匹配。我把三个程序的日志检查点整理成一张表方便排错程序成功标志常见错误关键信息geogrid.exe日志尾部出现Successful completionCould not open geogrid file / ERROR: Grib dataungrib.exe每个时次都打印Processing消息Bad grib2 file / Cannot find Vtablemetgrid.exe日志尾部出现Successful completionCould not find matching time / Missing intermediate files无论哪个程序报错第一反应都应该是回去看日志文件的最后二三十行而不是重新改配置闷头再跑。日志里通常已经把问题类型写得很清楚了。4.4 三个日志文件的读法日志文件是排错的第一现场但很多新手拿到日志不知道看哪儿。我的习惯是三步走tail -20 geogrid.log tail -20 ungrib.log tail -20 metgrid.log重点看最后几行的ERROR、FATAL、WARNING。WARNING可以酌情忽略ERROR和FATAL几乎都是硬错误。如果日志结尾明确出现了Successful completion哪怕中间有零星WARNING也可以放心往下走。还有一个实用小技巧如果某个程序运行很久没有结束比如metgrid卡在某个时次可以用ps -ef | grep metgrid看看进程是不是还活着再用ls -lh met_em.d01.*看看输出文件有没有在增长。如果进程死了但日志没有明确报错多半是磁盘满了或者文件权限问题。5. 新手踩坑实录我卡住的每一个地方希望你一次跳过写完标准流程再讲讲我在实际跑WPS时踩过的一系列坑。这些坑分布在时间处理、数据完整性、配置细节三个阶段每一个都让我多花了几小时甚至一整天。列出来给你当反面教材能跳过就跳过。5.1 时区与UTC差8小时模拟结果全偏移我一开始没把UTC当回事觉得反正都是“6月1日零点”写进namelist就行。结果第一次跑出来的天气系统位置、时间全部对不上看met_em文件里写入的时间戳才发现我全程用的是北京时间。问题出在FNL文件名上fnl_20230601_00_00.grib2里的时间是世界时UTC。北京时间6月1日08时对UTC来说还是5月31日24时也就是6月1日00时。如果namelist.wps里写的是本地时间ungrib提取出的中间文件时间戳必然错位metgrid也没法正确匹配数据。模拟结果里面的降水、温度场自然全乱套。解决办法只有一个所有配置、文件名、时间戳都统一用UTC。你在心里可以想着北京时间的天气过程但落到配置上必须是UTC。等结果出来想画图再在脚本里对时间做8小时转换。5.2 漏时次和数据残缺下载列表里的数字陷阱第二次踩坑是漏时次。当时我以为下载了4个时次就够了结果metgrid跑到第三个时次直接报错提示找不到匹配的中间文件。回头检查链接文件发现只有3个GRIBFILE软链接第4个时次的grib2文件根本没下载成功——下载列表里那个URL太大校园网中途断了wget没加-c参数直接退出文件留在服务器上我还没发现。后来我养成一个习惯下载完数据、链接完GRIBFILE之后强制清点一遍ls -lh GRIBFILE.*软链接数量必须跟模拟时次数完全一致。少一个就是数据下载环节有问题先别碰namelist。如果确认文件在但下载不完整用wget -c重新续传然后再跑link_grib.csh。5.3 Vtable没链接、GRIB文件后缀没配对诡异但常见的报错有一次ungrib直接报“Cannot find Vtable”我盯着当前目录看了半天Vtable文件明明存在。后来发现我只把Vtable.GFS复制过来了文件名却还叫Vtable.GFS而ungrib要读的是叫Vtable的文件。复制、改名、软链接名字必须精确匹配。还有一次是GRIB1和GRIB2的坑。老资料里有些FNL文件可能是GRIB1编码对应要用Vtable.GFS.G1之类的表Vtable.GFS是按GRIB2变量编码设计的。当时我拿着老数据的GRIB1文件配Vtable.GFSungrib能跑但提取出的变量乱码到metgrid阶段才反应过来。现在FNL基本都是GRIB2这个坑碰到概率低但如果你用的是历史久远的数据还是要留意编码格式。5.4 怎么确认WPS真的跑成功了确认WPS是否成功的标准不是“命令都执行完了没报错”而是met_em文件完整且内容正确。在进入real阶段之前强烈建议用ncdump做一次“体检”ncdump -h met_em.d01.2023-06-01_00:00:00.nc | head -50重点看几个维度是否存在且数值合理west_east、south_north对应你设置的120和100num_metgrid_levels显示三维气压层数量时间变量的单位是秒起始参考时间和文件命名时间一致。再抽一个变量看看范围比如TT温度在300K附近PSFC地面气压在1000hPa附近基本就可以放心了。还有一个笨但有效的办法ls met_em.d01.*的输出数量乘以时间间隔必须完整覆盖start_date到end_date的整个跨度。时间窗覆盖不完整real阶段一定会报错到时候再回来看WPS浪费的时间更不值。走到这一步其实你已经完成了WRF前处理中最磨人的一环。我自己的体验是第一次看到met_em.d01文件一个不落地生成时才真正有种“我在做数值天气预报”的感觉。后面的real.exe和wrf.exe虽然也有各自的报错风格但一旦数据链是通的很多问题都只是配置文件里打错字。建议你用ncdump之类工具把met_em文件打开亲眼确认气压层和变量都在这种“眼见为实”的踏实感比任何教程都管用。接下来你可以顺手检查一下namelist.input和namelist.wps的一致性再放心进入下一步。祝你一次跑通少踩几个我当时踩过的坑。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。