如果你刚开始接触大气污染数值模式,最容易被一堆缩写砸晕:WRF、WRF-Chem、SMOKE、CAMx、CMAQ、WPS、排放清单、化学机理……每个词单独看都认识,凑在一起就像天书。我当年入坑的时候,光搞清楚这些模式之间的关系就花了两周,更别提后面还有装环境、编译、跑通流程这些坎。这篇东西就是写给零基础朋友的,用我能想到的最直白的语言,把这套大气污染模式体系的来龙去脉、安装步骤、实操细节和常见坑全部捋一遍。目标是让一个完全没碰过模式的人,能照着这篇文章一步步把WRF-Chem或者CAMx跑起来,知道每一步在干什么、为什么这么干、出了问题去哪里查。
这套东西能解决的问题很实在:模拟污染物浓度时空分布、分析重污染过程的成因、评估减排方案的效果、做空气质量预报。搞环境管理、做科研、写毕业论文、进环保公司做咨询的人都会用到。内容量很大,我尽量按“先建骨架、再填细节”的方式来写,你看完哪怕暂时不动手,脑子里的地图也会清晰很多。
1. 先搞明白:这几个模式到底在干什么
1.1 一张关系图看懂模式分工(靠文字描述理清)
先说结论:WRF是气象模式,只算温度、风、湿度、气压这些大气物理量;WRF-Chem是在WRF的框架里加了化学模块,让气象场和污染物浓度能在线耦合着算;CAMx是一个独立的三维空气质量模式,它自己不算气象,而是把WRF算好的气象场拿过来用,专业术语叫“离线耦合”;SMOKE是一个排放清单处理工具,不管你用WRF-Chem还是CAMx,都得先把原始排放数据变成模式能读的格式,SMOKE干的就是这个活。
这四者的关系可以这么理解:WRF-Chem是“气象+化学全家桶”,一次编译全搞定,但排放处理比较粗放;CAMx是“只算污染的专用计算器”,气象场由WRF喂给它,排放处理用SMOKE,三条线配合起来各管一段。科研圈里两条路线都有人用,大气化学机理研究多用WRF-Chem,法规类的空气质量评估、减排情景分析则更常见CAMx/CMAQ。
1.2 零基础从哪里开始学
我的建议非常朴素:先别碰WRF-Chem,先把纯气象版WRF跑通。理由很简单,WRF-Chem等于在WRF基础上增改了很多代码,排放部分还牵扯化学机理,如果连WRF都跑不顺,叠加了化学模块之后报错你根本分不清是气象的问题还是化学的问题。当年我跳过这步,直接在WRF-Chem上折腾,一个星期都在跟各种段错误搏斗,最后老老实实回去跑WRF案例,两三天就把整个流程顺下来了。
学习路径大概是:Linux基础命令 → WRF模式原理与文件结构 → WPS前处理(geogrid/ungrib/metgrid)→ WRF核心运行 → 气象场结果可视化 → 再进WRF-Chem或CAMx路线。每一步都需要动手敲命令,光看不练是不行的。
1.3 版本选择也是个讲究事
WRF目前主流版本是4.x,常见的有4.3、4.4、4.5、4.6,不同版本对编译器、依赖库版本的要求有细微差别。经验是:如果是新手,选一个和身边人一致的版本,或者按官方Release Notes里“经过测试的组合”去选。别盲目追新,也别用太老的版本。4.6出来之后我跑过一阵子,稳定性好很多,但有些老脚本参数名变了,得改。这里没有绝对标准,关键是“版本之间保持兼容”——编译器、MPI、NetCDF、HDF5这些库的版本要和WRF要求的对得上。
2. 环境准备:把Linux环境配到“能跑模式”的状态
2.1 为什么必须用Linux(Windows没法省事)
WRF全家桶原生支持Linux/Unix,虽然Windows下用Cygwin或者WSL也能折腾,但性能和兼容性问题非常多,尤其涉及MPI并行、NetCDF库时,Windows下各种路径问题能把人逼疯。直接上Ubuntu 18.04/20.04/22.04都是网络上验证过的版本,装个双系统或者用服务器都行。我自己最推荐的是Ubuntu 20.04,资料多、遇到报错到处能搜到答案。
新手装环境,务必学会一个习惯:全程用普通用户操作,不要用root。很多人在root下编译没问题,一换普通用户就各种权限报错。另外,模式运算需要大量磁盘空间(气象数据+输出文件动不动几十个G),装之前看清楚磁盘配额。
2.2 编译器、MPI、NetCDF等依赖库选型
WRF编译需要几个核心武器:Fortran/C编译器(gfortran/gcc)、MPI并行库(mpich或openmpi)、NetCDF(处理气象数据的核心I/O库)、HDF5(NetCDF4的底层依赖)、还有zlib、libpng、jasper(用于处理GRIB格式数据)。新手期最容易翻车的就是库之间的版本兼容。
我的建议是:整套环境自己手动编译安装,不要一股脑用apt装。用apt装NetCDF虽然快,但版本和路径经常跟WRF编译器配置对不上,后面报错会让你怀疑人生。我踩过的坑就是apt装的netcdf,WRF编译时提示版本过旧,最后全部重来。手动编译虽然麻烦一点,但每一步都在自己掌控之下,出了问题也知道该查哪里。
注意:NetCDF的安装路径要记好,后面配置环境变量时要用。很多新手unset掉环境变量后重新打开终端,发现编译好的WRF又挂了,就是因为没写进~/.bashrc。
2.3 WPS下载与编译完整实录(wrf前处理wps下载的关键细节)
WPS是WRF前处理系统的总称,包含三个工具:geogrid(定义模拟区域和地形数据)、ungrib(把气象再分析资料转成中间格式)、metgrid(将气象数据水平插值到模拟网格上)。很多新手问“wrf前处理wps下载”,其实就是从WRF官网下载WPS源码包,版本要和WRF匹配。比如WRF 4.5对应WPS 4.5,不要混搭。
下载解压后,需要进行环境变量配置,我习惯在~/.bashrc里加上这样一段(路径以你的实际安装目录为准):
export DIR=/home/yourname/models export PATH=$DIR/netcdf/bin:$PATH export NETCDF=$DIR/netcdf export JASPERLIB=$DIR/grib2/lib export JASPERINC=$DIR/grib2/include export WRF_DIR=/home/yourname/models/WRF-4.5 export PATH=$DIR/mpich/bin:$PATH配完执行source ~/.bashrc,然后进入WPS目录运行./configure,界面会出现一串选项。对新手,选Linux gfortran serial,也就是不带并行(如果是练习跑通流程,serial就够了;要跑真实案例就选dmpar)。然后./compile,等待输出一堆exe。编译完成后,用ls -l检查是否有geogrid.exe、ungrib.exe、metgrid.exe三个可执行文件,缺哪个说明编译有问题。
这里有一条经验:WPS编译报错八成是环境变量没设对,尤其是JASPERLIB和JASPERINC,如果路径和实际安装位置不一致,ungrib.exe就编不出来。很多新手卡在“WPS编译报错libjasper.a找不到”,就是这个原因。
3. WRF核心:从WPS前处理到wrf.exe跑通全流程
3.1 WPS的三大步骤分别干什么
WPS全称WRF Preprocessing System,一共三步,每步对应一个可执行文件:
geogrid.exe:定义模拟区域,生成geo_em.d01.nc文件。它读的是地形、土地利用、土壤类型等静态地理数据,这些数据在WPS自带的geogrid文件夹里部分有,部分要单独下载,新版WPS要求下载完整的geog_complete.tar.gz解压到一个大硬盘目录,然后在namelist.wps里指定geog_data_path路径,这个坑很常见——如果你geogrid报错找不到geo_data,多半是路径没写对。
ungrib.exe:把GRIB格式的气象再分析资料(FNL、GDAS、ERA5等)解压并转换成中间格式。使用之前要先链接Vtable,比如./link_grib.csh /path/to/fnl_xxx,然后ln -sf ungrib/Variable_Tables/Vtable.GFS Vtable,不同气象数据源对应不同Vtable,选错了后面metgrid就会报错。
metgrid.exe:将ungrib处理出的中间气象场水平插值到geogrid定义的网格点上,输出met_em.d01.*.nc文件。这步完成后,前处理就结束了,接下来进入WRF主体。
3.2 namelist.wps关键参数怎么填
namelist.wps是整个前处理的控制中心,核心内容是两个时间设置和区域设置:
&share wrf_core = 'ARW', max_dom = 1, start_date = '2021-01-01_00:00:00', end_date = '2021-01-03_00:00:00', interval_seconds = 21600, / &geogrid parent_grid_ratio = 1, i_parent_start = 1, j_parent_start = 1, e_we = 120, e_sn = 120, geog_data_res = 'default', dx = 27000, dy = 27000, map_proj = 'lambert', ref_lat = 34.0, ref_lon = 108.0, stand_lon = 108.0, geog_data_path = '/home/yourname/WPS_GEOG', / &ungrib out_format = 'WPS', prefix = 'FNL', /区域大小(e_we、e_sn)和格距(dx、dy)是核心。新手学跑通流程,dx=27000就是27km的粗网格,区域范围国内大约相当于覆盖一个大省,跑3天模拟也就几十GB。核心经验是:dx增大一倍,计算量减小四倍(面积比例),跑测试别一上来就设1km的精细网格,慢慢来。
3.3 wrf.exe运行与输出检查
前处理生成met_em文件后,进入WRF目录,先链接气象输入:
ln -sf /home/yourname/WPS/met_em.* .然后修改namelist.input。这个文件和namelist.wps的日期、区域要完全一致,否则会报错。关键参数包括:
&time_control start_year = 2021, start_month = 01, start_day = 01, start_hour = 00, end_year = 2021, end_month = 01, end_day = 03, end_hour = 00, interval_seconds = 21600, / &domains e_we = 120, e_sn = 120, dx = 27000, dy = 27000, / &physics ra_lw_physics = 1, ra_sw_physics = 1, sf_sfclay_physics = 1, sf_surface_physics = 2, bl_pbl_physics = 1, cu_physics = 3, /选定后运行./compile em_real,编译出wrf.exe、real.exe。然后先运行real.exe生成wrfinput_d01和wrfbdy_d01,再运行mpirun -np 4 ./wrf.exe执行主程序。跑完后用ncdump或者Python的xarray打开wrfout_d01_2021-01-01_00:00:00文件,看看变量有没有数据,画个温度场、风场,就知道模式跑没跑对了。
4. WRF-Chem:让气象模式“会算污染”
4.1 从WRF到WRF-Chem需要多做什么
WRF-Chem不是单独下载的另一个包,而是用WRF源码里的chem子目录编译出来的一个选项。在configure阶段,选择带有CHEM的选项(比如Linux x86_64, gfortran, dmpar, ARW, Chem)。编译命令依然是./compile em_real,但系统会连带编译chem模块下的代码。装WRF-Chem前,强烈建议你再用WRF-Chem官网提供的一个练习案例(比如RADM2/MADE-SORGAM那个测试算例)跑一遍,确保化学模块本身没问题,再做自己的真实案例。
额外需要准备的东西是化学机理文件、光解数据、排放清单。化学机理一般在WRF-Chem源码里带了一部分,光解数据需要单独下载(如photolysis data),排放清单就更复杂,见下文。
4.2 排放清单接入方式
这是WRF-Chem新手最容易崩溃的环节。WRF-Chem读取排放有两种方式:一种是直接把排放源数据写在wrfinput里(prep_chem_sources工具干的事),另一种是跑在线排放模型。常见工具是prep_chem_sources,它读原始排放清单(MEIC、EDGAR、MIX等),生成wrfchemi_d01_YYYY-MM-DD_HH.nc文件。
国内做空气质量模拟,MEIC清单用得很广泛,结合自己的网格设置做空间分配和时间分配。关键步骤是先把MEIC的经纬度网格数据重映射到你的WRF网格上来,这通常需要用到Python的xesmf或者cdo工具,然后再跑prep_chem_sources。新手别想一步到位,先下载业务部门公开的现成处理脚本,搞清楚每个参数含义再改。
4.3 SMOKE在WRF-Chem路线里的定位
实际上,原生的WRF-Chem不强制用SMOKE,SMOKE更多用于CMAQ/CAMx这条线。但如果你手里的排放清单是SMOKE处理过的(很多环境规划项目都有),也可以把它的输出转成WRF-Chem格式。这里核心是理解格式差异:SMOKE输出的nc文件时间维度是hourly,化学成分按CB05或SAPRC机理命名,跟WRF-Chem的RADM2/MADE-SORGAM命名不一样,需要写映射脚本转换。
除非你在做非常规范的大规模研究,否则新手别一上来就整SMOKE+WRF-Chem的串联,工作量很大。建议第一步直接用prep_chem_sources吃MEIC数据,跑通之后再考虑SMOKE的精细处理。
5. CAMx与SMOKE:另一条主流路线怎么入门
5.1 CAMx是什么,和WRF-Chem有什么不同
CAMx(Comprehensive Air quality Model with eXtensions)是由Ramboll公司开发的三维欧拉空气质量模式,目前版本到7.x/8.x。它与WRF-Chem的核心区别:
- CAMx不参与气象计算,气象场完全依赖WRF输出(离线耦合),好处是气象场可以反复使用、调试方便;坏处是没办法考虑气溶胶辐射反馈这些气象-污染双向作用。
- CAMx的化学机理选项丰富,支持CB6、SAPRC07、SAPRC11等,对付臭氧和二次气溶胶问题很顺手。
- CAMx有臭氧源解析工具OSAT、颗粒物源解析工具PSAT,这是它的杀手锏,做污染物来源追踪非常方便。
很多环保规划项目用CAMx做PM2.5来源解析、减排情景评估,因为这个模式的历史资料多、工具链完整、后处理生态成熟。
5.2 CAMx跑通需要哪几类输入
CAMx的运行需要四大类输入:
- wrfout气象场:先用WRF跑出wrfout文件,再用CAMx自带的工具(wrf2camx)转换成CAMx格式。
- 排放清单:SMOKE处理后输出camx格式的排放文件,或者用工具把MEIC直接转换。
- 初始条件和边界条件:可以用CAMx自带的profile文件,也可以用全球模式(如GEOS-Chem、MOZART)的模拟结果来提供侧边界。
- 光解速率:用CAMx的TUV模块计算,或者用在线方案直接调用。
新手跑CAMx,最重要的是把CAMx的control文件搞清楚。这个文件类似namelist,指定了各种输入文件路径、起止时间、输出频次、化学机理名称等。每一样都要和你的输入文件一一对应,报错通常也是从这里开始。
5.3 SMOKE处理排放的核心流程
SMOKE(Sparse Matrix Operator Kernel Emissions)是一个很庞大的工具套件,核心逻辑是“把原始排放清单磨成模式能用的shape”。流程大致为:清单数据标准化 → 时空分配(把年排放量分配到月/时,把行政区划排放量分配到网格)→ 物种映射(把清单里的污染物种类映射成模式机理的物种)→ 点源处理(处理烟囱高度、烟气流量等参数)→ 输出netCDF格式排放文件。
SMOKE的编译非常考验耐心,它需要许多Perl模块和库的支持,官方文档也不太好读。我是建议新手先别自己从零编译SMOKE,可以基于项目已有的处理成果来学,或者先用WRF-Chem线上排放模块顶上,等基本概念都熟了再回头啃SMOKE。
6. 常见问题与排查技巧实录
6.1 编译阶段最容易翻车的三个地方
- NetCDF路径不对:configure阶段提示找不到netcdf,十有八九是NETCDF环境变量没导出。检查echo $NETCDF是否有值。
- Fortran编译器版本不匹配:gfortran太新或太旧都容易出问题,尤其是gfortran 10以上的版本经常在WRF 4.3以下版本编译时报错,要么换旧版WRF,要么加编译参数。
- 内存爆掉:编译WRF-Chem时非常占内存,如果服务器只有2G内存,make -j4必挂,用make -j1甚至直接make,慢慢编。
6.2 运行阶段典型报错速查表
| 报错现象 | 可能原因 | 解决办法 |
|---|---|---|
| real.exe运行后没生成wrfinput | namelist.wps和namelist.input的起止时间/区域设置不一致 | 逐项对比两个文件的时间、e_we、e_sn、dx、dy |
| wrf.exe运行瞬间退出,rsl.error.0000报错 | met_em文件缺失或链接错误;物理方案选错;输入数据不完整 | 确认met_em文件存在且日期匹配 |
| CFL崩溃(cfl错) | 气象场出现极端值,多为地形或嵌套边界处理不当 | 检查地形数据、降低时间步长、检查嵌套区域设置 |
| 化学浓度全是0或者NaN | 排放清单没读进去 | 检查wrfchemi文件命名,检查化学机理开关,看rsl.out里的化学模块初始化日志 |
6.3 排放数据相关的坑
MEIC清单下载后往往是二维栅格(如0.25度),必须先做重映射再插值到模式网格。这里常见的坑是经纬度方向搞反导致整个浓度场偏移,我碰到过很多次,解决办法是画一张先验对比图,把排放源的位置和城市分布叠在一张图上人工检查。另一个坑是时间维度:MEIC给的是月排放量,你要先按照小时系数分配到小时,WRF-Chem的小时排放文件每小时一个记录,24小时一个周期循环,如果没处理好,模拟出来会看出很奇怪的日变化。
6.4 给零基础朋友的一条规划建议
你最需要的是“先跑通一个简单案例,再逐步加深”。别贪多,别一开始就追求“高精度嵌套”“完整排放清单”“气溶胶反馈”这些进阶玩法。先把WRF练习案例跑通,再跑WRF-Chem自带的chem案例,最后换自己的模拟区域和清单数据。整个过程心态要稳,因为数值模式的编译和运行报错实在太多了,排查一个问题可能要几天时间,这是正常节奏。我当年有一次为了找模数据异常的原因,连续两周晚上都在看rsl.error文件,最后发现是namelist里时间步长太大导致CFL崩溃,改小就过了。这类经验只有自己踩过才有感觉。
如果后续要继续扩展,建议掌握Python的可视化和数据处理技能,尤其要用好xarray、matplotlib、cartopy这三个库,做模式场和观测站点的对比验证几乎天天用得到。还可以把CMAQ、GEOS-Chem也了解起来,它们和WRF-Chem、CAMx的原理相通,学会了其中一个,其他的都只是参数和接口的问题了。