1. 先搞懂整体逻辑chem_opt和emiss_opt到底在管什么很多新手第一次跑WRF-Chem最容易卡住的地方不是编译也不是下载数据而是namelist.input里那一排看着像密码一样的化学选项。尤其是chem_opt和emiss_opt这对组合手册上写得极其简约——给个数字告诉你选哪个是哪个机制然后就没了。但实际操作里这两个参数决定的不只是“用哪种化学机制”还直接关系到你的排放清单怎么准备、初始场从哪里来、跑出来的结果能不能解释得通。先说结论chem_opt是化学机理的开关决定大气中发生哪些化学反应emiss_opt是排放源的处理方式决定污染物以什么形式、什么物种、什么时空分布进入模式。两者必须配套使用而且配套关系不是一一对应的一个chem_opt可以对应多个emiss_opt选错了要么直接报错要么跑出来浓度离谱到没法用。打个比方chem_opt相当于厨房里的菜谱emiss_opt相当于买菜和切菜的方式。菜谱是川菜你却用粤菜的白灼方式处理食材端出来那肯定不是那个味儿。WRF-Chem里化学机制定义了物种之间的反应排放方案得按这个机制要求的物种列表来提供污染物否则模式根本不知道你给的那些排放量该放进哪个物种里。具体到软件层面chem_opt和emiss_opt都写在namelist.input的chem这个段落里。WRF-Chem在初始化时会根据这两个选项去生成对应的化学变量列表、化学反应配置、排放模块接口。我见过不少新手chem_opt选了个202MOZART-MOSAIC气溶胶机制emiss_opt却还留着默认的1结果wrf.exe跑了两步就崩报错信息又不友好最后查了一整天发现就是排放方案不匹配。所以我建议所有新手在动namelist之前先把这两个参数的逻辑关系用一张纸画出来你研究什么区域关注什么污染物手里有什么排放清单这三个问题的答案直接框定了chem_opt和emiss_opt的合理选择范围。不要一上来就盯着最新版的机制选数值最大的不一定适合你。1.1 chem_opt化学反应引擎的工作模式chem_opt这个参数本质上是告诉WRF-Chem“你要模拟哪种化学体系”从最简单的无化学chem_opt0等价于普通WRF到气相机制再到气相加气溶胶的复杂配置数字越大一般代表机制越复杂。这里有个新手特别容易误解的地方chem_opt0并不代表“不跑化学”它代表的是跑纯气象模式——也就是说你的WRF-Chem就当WRF用了不计算任何化学过程。很多人想在正式跑化学之前先用纯气象模式测试一下流程这个做法完全可行只要把chem_opt和emiss_opt都设成0就行。但一旦你设了chem_opt大于0模式就会自动启用化学的一系列模块包括化学传输、化学反应、干湿沉降、光解率计算等等这时候你的输入文件里就必须有对应的化学场和排放场。从我自己的使用经验来看化学机制的选择要综合考虑三个因素一是模拟区域的特征城市污染主导还是区域传输主导二是计算资源复杂机制慢得可不是一星半点三是可用的排放清单和初始场数据你选的机制如果找不到对应的全球化学模式数据初始场只能自己凭空捏造那就没法玩。1.2 为什么说emiss_opt是“最容易翻车的环节”emiss_opt的设置之所以难是因为它不像chem_opt那样只要理解了机制差异就能选对它涉及的是一个冷门的领域——排放清单的格式处理。WRF-Chem本身不自带排放数据你需要自己下载或准备排放清单文件然后用prep_chem_sources或者convert_emiss工具把它们转成模式能读的格式这个过程里任何一环出了错最后都会反映到emiss_opt和对应文件不匹配上。我自己见过一个特别坑的案例有个朋友跑长三角区域的臭氧模拟用的是RADM2机制排放清单来自某机构提供的清单产品。他下载的数据明明标注是“适用于RADM2”但实际跑的时候wrf.exe总是报“error opening/wrong shape of emiss file”。后来排查发现他的排放文件里物种名带了个后缀和WRF-Chem默认的读取接口对应不上前处理时候少了一个映射步骤。这种问题手册里根本不会写只有真正动手跑过的人才知道。2. 常见chem_opt机制速览别只盯着数字选WRF-Chem发展了这么多年chem_opt的选项从个位数扩展到了四位数不同版本之间数值含义还会变这对新手来说是巨大的坑。我这里基于WRF-Chem 4.x版本把最常用的一组机制整理出来帮大家建立一个基本认知框架。chem_opt值机制名称类型适用场景0无化学纯气象测试流程、跑气象场1T1气相简单气溶胶教学、快速测试2T2气相简单气溶胶教学、快速测试5RADM2气相传统臭氧模拟7RADM2MADE/SORGAM气相气溶胶颗粒物与臭氧协同模拟8RADM2MADE/SORGAMAQ气相气溶胶液相酸沉降、湿清除相关9CBMZ气相城市光化学烟雾202MOZART-MOSAIC气相气溶胶区域/全球尺度耦合模拟301CBMZ-MOSAIC气相气溶胶考虑气溶胶粒径分布的研究注意上面这个表只是冰山一角WRF-Chem 4.x里chem_opt值有几十个每个背后还有一堆子选项。我见过有人用chem_opt202跑然后给MOZART机制配置了CBMZ的排放物种结果NOx的排放量一直被模式错误地分配到别的物种里模拟的臭氧浓度偏低得离谱。2.1 从简单到复杂新手怎么选第一套机制如果你只是想跑通流程、验证安装、熟悉数据预处理流程我的建议是先用chem_opt2T2机制。原因有三个第一它计算量小跑一天的区域模拟只要几十分钟第二它对排放清单格式要求低很多通用清单工具默认支持第三它的结果虽然比较粗糙但足以让你检查出代码层面有没有bug。跑通了T2再根据自己的研究方向逐步升级。比如做臭氧研究可以试RADM2或CBMZ做PM2.5研究就要盯住带气溶胶模块的机制比如RADM2MADE/SORGAMchem_opt7或者MOSAIC系列。不要想着一步到位直接用最复杂的MOZART-MOSAIC那样你会被一堆气溶胶参数搞到崩溃。我记得有一次帮人排查问题他用chem_opt202跑中国全域结果初始场数据里的气溶胶物种和模式要求对不上折腾了整整一周才搞清楚。2.2 chem_opt背后的气相机制差异为什么要分这么多机制本质上是化学反应网络的简化程度不一样。像RADM2它把VOCs归并为十几个物种氧化机理也比较简洁跑起来快但对复杂的臭氧生成过程刻画得不够精细。CBMZ用的是碳键方法把碳链结构作为分类依据对芳香烃的处理比RADM2好一些。MOZART则是大规模机制物种数量多化学反应方程式上千条理论上最能还原真实大气化学过程但计算量大得惊人而且它本身也需要更多的输入参数。选机制时还有一个容易忽视的点气象过程和化学过程的时间步长耦合。WRF-Chem里化学机制的求解时间步长可以单独设置但不同机制对数值稳定性要求不同复杂机制在强对流天气下容易出现浓度振荡甚至数值爆炸。我自己在跑夏季雷暴天气下的臭氧模拟时用过RADM2没事换到MOZART就频繁出现“NaN in mixing ratio”的报错最后只能把化学时间步长调小才稳住。这部分经验就是踩坑踩出来的。3. emiss_opt排放参数一套排放数据对应一套玩法说完chem_opt再看emiss_opt。WRF-Chem的排放模块设计思路是用emiss_opt告诉模式“我要用什么方式读排放文件、文件里的物种怎么映射到化学机制里去”。所以emiss_opt的数值选择一半取决于你排放文件是怎么生成的一半取决于chem_opt要什么物种。我自己遇到过好几种情况用prep_chem_sources工具处理标准清单时emiss_opt通常选1它会按工具生成的物种映射表来读取。用convert_emiss处理一些区域高分辨率清单比如某些城市级清单时emiss_opt选17或对应值因为那些清单已经按照MOZART-MOSAIC机制做过物种映射。想用生物源排放MEGAN那就是bio_emiss_opt的事单独一套参数不要和emiss_opt混淆。这里值得多说一句emiss_opt还跟时间变化有关。很多排放清单给出的是一天、一个月或者一年的总排放量WRF-Chem需要根据emiss_opt所指定的方案把这些总量分配到每个时间步上。有的方案是恒定排放有的是按日变化系数插值。如果你模拟的是臭氧日变化特征但排放源用的是恒定速率那结果基本没法看。3.1 人为源、生物源和火灾源三套排放别搞混WRF-Chem的排放体系其实分三大块人为源anthropogenic、生物源biogenic、火灾源biomass burning。它们对应不同的输入文件和不同的开关参数。人为源就是工厂、机动车这些用emiss_opt控制生物源是植被释放的VOCs由bio_emiss_opt控制火灾源是森林大火、秸秆燃烧这些用另一个参数控制。新手最容易犯的错是把生物源排放直接设为0然后模拟出的VOCs浓度低到离谱。要知道在很多区域异戊二烯和单萜烯这类生物源VOCs在夏季对臭氧生成的贡献极大你要是把生物源关了臭氧浓度拟合度会惨不忍睹。反过来如果你不关心臭氧和二次有机气溶胶只关注一次排放的颗粒物那生物源影响相对小一些可以简化处理。生物源排放的计算WRF-Chem默认有一套MEGAN模型它需要输入地表植被类型数据同时根据气象场温度、辐射实时计算VOCs排放。这个过程的计算量不小但对结果的改善很明显。我第一次跑夏季华北区域模拟时生物源排放开和关臭氧模拟浓度能差到30%以上所以千万别省这一步。3.2 排放文件的时间轴最容易出现的“隐形错误”排放文件的时间覆盖范围必须覆盖你的模拟时间段这个道理说出来大家都懂但操作时经常出问题。我见过一个案例模拟时段是7月15日到7月20日但排放文件只处理了7月15日到7月19日结果最后一天wrf.exe直接报“cant find valid time”错误。这种问题说起来很弱智但确实就是很弱智地浪费了我两个小时。还有一个更隐蔽的问题排放文件的时间频率。WRF-Chem的排放输入文件通常是逐小时的但有些工具生成的可能是逐3小时或者逐6小时。模式在读的时候虽然会做时间插值但如果你在namelist里没写对时间步长的匹配逻辑可能就会出现排放量突变的情况。我建议所有新手拿到排放文件之后第一步用ncdump查看一下时间维度确认时间步长和覆盖范围都正确再开始跑。4. 实战配置一套完整的chem_optemiss_opt实战参数表说了这么多原理上点实际能抄的作业。下面这套配置是我自己常用的初始配置适用于跑一个区域尺度的臭氧和PM2.5协同模拟区域范围大概相当于一个省或省份群水平分辨率9km到12kmchem_opt用RADM2MADE/SORGAM机制chem_opt7配套emiss_opt3的人为源排放方案。chem chem_opt 7, 7, 7, emiss_opt 3, 3, 3, bio_emiss_opt 3, 3, 3, phot_opt 1, 1, 1, gas_drydep_opt 1, 1, 1, aer_drydep_opt 1, 1, 1, aerchem_onoff 1, 1, 1, chem_inv_opt 0, 0, 0, kemit 1, 1, 1, /先解释几个关键项chem_opt 7RADM2气相机制加MADE/SORGAM气溶胶模块这个机制对臭氧和PM2.5都能给出比较合理的模拟计算量在可接受范围内。emiss_opt 3这里选了3意味着找人源排放文件时会使用chem_opt7对应的物种映射表把排放清单里的NOx、SO2、VOCs等物种映射到RADM2机制的变量体系里。bio_emiss_opt 3开启MEGAN生物源排放计算需要提前准备植被类型输入文件。phot_opt 1开启光解率计算化学机制中光解反应必不可少。这个参数也是个容易踩的坑光解率方案不同结果差异很大新手先用默认的1就好。aerchem_onoff 1开启气溶胶化学这个是配合气溶胶模块用的只有chem_opt里包含气溶胶这个参数设成1才有意义。chem_inv_opt 0化学初始场选项0表示不添加额外化学初始场直接由wrfinput文件里的化学浓度开始积分。这里要特别提醒如果你用的是全球模式数据比如WACCM或者MOZART-4输出做化学边界场chem_inv_opt就不是0了要选成对应的方案。这三层嵌套域都设成一样的化学配置看起来是理所应当的但实际里面有个坑如果嵌套域里某一层用不同的chem_opt那么两层之间的化学物种交互就会出问题。我建议新手在跑嵌套模拟时所有层的化学选项保持一致省去一大堆莫名其妙的错误。4.1 配套文件准备wrfinput和wrfbdy里必须有化学场chem_opt大于0之后你的wrfinput文件里就要包含化学场的初始浓度wrfbdy里要包含化学场的边界浓度。这一步新手特别容易忽略或者说不清楚从哪来。我的做法是用全球化学模式输出产品通过工具把全球数据插值到自己的模拟区域生成包含化学物种初始浓度和边界浓度的输入文件。具体工具包括mozbc、wrfchembc等。以mozbc为例你需要在运行时指定全球数据文件名、模拟时间段、要映射的化学机制工具会自动把全球模式的物种浓度插值到你的网格上生成对应的wrfinput和wrfbdy变量。这个环节的重要性我在自己第一次跑WRF-Chem时体会极深当时我图省事直接用纯气象的wrfinput去跑化学模式结果前36个小时的化学浓度全靠模式内部从零开始“造”模拟出的臭氧浓度明显偏低而要等spin-up跑完、化学场稳定下来至少得两三天。对于很多短期个例模拟来说前两天的数据基本就是废的。所以化学初始场一定要配好别在这上面省事。还有一种操作是给模式较长的spin-up时间比如先跑5天取后3天的结果做分析。这个方法比直接改初始场来说更省事但代价是计算量上去了而且你依然需要一个能用的ndown或restart流程。两种方法我都试过如果要做一个高质量个例分析我强烈建议用全球化学模式数据生成初始场这样你的化学模式从第一个时间步起就是“有记忆”的而不是从一张白纸开始。4.2 排放文件与emiss_opt的匹配检查清单准备排放文件时我总结了一个自检清单每次做新案例都按这个过一遍大大降低翻车概率确认排放文件的时间范围覆盖整个模拟时段宁多勿少。用ncdump -h查看排放文件里的变量名确认物种名和emiss_opt对应的映射表匹配。确认排放文件的投影信息、网格维度嵌套层次与wrfinput一致。网格不一致的排放文件模式读进去会有偏移结果完全不可用。检查排放量单位。不同清单的单位差异巨大有的用mol/km2/hr有的用µg/m2/s前处理工具里单位换算错了结果浓度会差好几个量级。单位这个坑我栽过不止一次。有一次跑一个国外团队提供的清单单位是molecules/cm2/s没做换算直接塞给模式结果NO2浓度模拟值比观测高了将近100倍一开始我还以为是化学机制的问题排查了三天才意识到是排放单位错了。这个惨痛经历告诉我拿到任何排放清单第一件事就是查文档确认单位而且要在前处理脚本里显式写好单位换算关系。5. 编译选项与版本差异chem_opt值在不同版本间可能变脸WRF-Chem的一个麻烦之处是它的参数数值在不同版本之间并不完全兼容。我最早用的是3.6.1版本后来换成4.1.3再到4.4版本chem_opt的数值含义就有过调整。有些在老版本里是7的机制在新版本里可能变成了别的值或者功能发生了调整。所以当你从网上下载一个namelist模板时先确认模板对应的WRF-Chem版本再对照你本地的Registry文件查一下实际数值定义不要想当然。Registry文件路径通常在Registry/目录下搜一下chem_opt就能看到各个数值对应的机制说明。编译时的另一个坑是KPP化学求解器的开启。WRF-Chem里复杂机制通常会用KPP来生成化学求解代码编译前你需要选择是否启用KPP。如果编译时没开KPP但namelist里选了依赖KPP的机制比如某些MOZART选项wrf.exe运行时会直接报错“KPP not compiled”。这类错误在论坛上隔三差五就有新人问但本质上就是你编译配置和运行时配置不匹配。建议新手在编译前先把WRF-Chem自带的README和编译指导仔细读一遍特别是关于chem_opt和KPP的描述。虽然文档写得不够细但至少能帮你避免“机制和编译配置不匹配”这种低级问题。5.1 wrf.exe崩溃的常见信号wrf.exe运行中途崩溃算是每个WRF-Chem新手的“成人礼”。崩溃的原因五花八门但和chem_opt/emiss_opt相关的崩溃有几种典型信号“ERROR: emission file not found”说明emiss_opt指定的文件路径下找不到排放文件或者文件名和模式期望的不一致。WRF-Chem对排放文件的命名有严格要求比如wrfchemi_00z_d01这个00z指的是排放文件的小时标记你必须保证文件名里的时间和模拟起始时间一致。“NaN in mixing ratio”化学浓度出现非数值常见原因是排放量过大导致数值不稳定性或者某个物种的初始浓度为负值。排查方法先检查排放单位再看初始场。“ERROR: mismatch in dimension”排放文件网格和wrfinput网格不一致或者嵌套层数不匹配。这种错误通常在模式刚开始读排放文件时就出现但报错信息不一定指向排放文件有时候会让你云里雾里。我建议新手在跑完整模拟之前先做一个12小时或者24小时的短测试把chem里的诊断开关打开比如io_form_chem2输出netCDF格式化学诊断文件如果短测试能稳定跑完再上长模拟。不要一上来就跑一个月出了问题排查看日志看到怀疑人生。5.2 chem_opt和emiss_opt的常见错误搭配部分错误搭配我整理成了表格方便大家对照检查现象可能原因排查步骤跑了几步就崩报emission文件找不到emiss_opt值和排放文件格式不匹配查看rsl.error.0000文件确认报错行检查emiss_opt是否正确跑完但臭氧浓度异常偏低chem_opt对应的VOCs物种和排放文件不匹配使用ncdump检查排放文件物种比对化学机制物种列表PM2.5浓度全是0或极小chem_opt不含气溶胶模块或aerchem_onoff0确认chem_opt带气溶胶检查aerchem_onoff设置某一层跑得好其他层浓度爆炸嵌套层化学选项不一致或排放文件层数不足统一各层chem_opt/emiss_opt检查排放文件是否包含所有嵌套层模拟前几天化学浓度漂移严重缺化学初始场用mozbc等工具准备化学初始场和边界场5.3 排放文件时间命名一个非常低级但常见的问题排放文件的命名规则我单独拿出来说一次因为这个问题几乎每隔一段时间就会在用户群里被问一次。WRF-Chem读排放文件时文件名里的时间是按世界时UTC标记的。假设你的模拟从2024年7月15日00时UTC开始那么排放文件名就应该是wrfchemi_00z_d01这里的00z代表UTC时间0点。如果你用的是北京时间那就要把时区差考虑进去模拟从北京时间8点开始UTC时间就是0点文件名还是00z。另外一个模拟时段通常需要多个小时的排放文件比如跑一天你可能需要24个逐小时排放文件或者一个包含24个时次的多时次排放文件。用prep_chem_sources生成的通常是后者但用其他工具处理时可能生成前者。这两种格式WRF-Chem都支持但对应的emiss_opt读取方式可能不同——这正是emiss_opt数值设计如此分裂的原因之一。所以拿到排放数据时先搞清楚它的时间组织方式再决定emiss_opt选什么。6. 进阶技巧手动修改chem_opt对应排放物种的映射表前面聊的都是参数本身这里再分享一个手册里没写但很实用的技巧自定义排放物种映射。WRF-Chem排放文件的物种映射表在两个关键的地方定义一是前处理工具比如convert_emiss里有一个物种映射表文件二是模式运行时根据emiss_opt去匹配排放文件里的变量名。如果你的排放清单物种和chem_opt机制要求的物种不完全一致你不需要重新生成排放文件只需要修改映射表文件把清单里的物种映射到机制物种上。具体做法是打开映射文件通常在chem/或者run/目录下文件名类似Chem_opt_xxx_emiss_xxx.txt找到对应的物种对应关系手动增加一行映射。比如清单里有“NMHC”非甲烷总烃但你的机制需要“ETH”乙烯、“TOL”甲苯等具体物种你就可以按经验把NMHC按比例拆到这些具体物种上。这个操作需要一定的大气化学知识才能做出合理拆分但对很多区域清单来说不做拆分就没法跑模型。我自己的做法是先看清单文档里对物种的定义再查一下这个地区排放源的构成机动车多还是工业源多用排放源谱把总量拆到具体物种。这步虽然费时间但比硬跑后结果对不上要好得多。6.1 用python快速检查排放文件和wrfinput的匹配性最后分享一个我日常用的python小脚本专门用来检查排放文件和wrfinput的匹配性。这个脚本很短但能帮我快速发现90%的低级错误。import netCDF4 as nc def check_emiss_match(emiss_path, wrfinput_path): # 读取排放文件和wrfinput文件 emiss nc.Dataset(emiss_path) wrfin nc.Dataset(wrfinput_path) # 检查网格维度 e_lat, e_lon emiss[XLAT][0], emiss[XLONG][0] w_lat, w_lon wrfin[XLAT][0], wrfin[XLONG][0] print(网格维度检查:) print(f 排放文件: {e_lat.shape}, 最大经度差: {abs(e_lon.max()-e_lon.min()):.2f}) print(f wrfinput: {w_lat.shape}, 最大经度差: {abs(w_lon.max()-w_lon.min()):.2f}) # 打印排放文件里的物种列表 chem_vars [v for v in emiss.variables if e_ in v or E_ in v] print(f\n排放物种清单共{len(chem_vars)}个:) print(chem_vars[:20]) # 检查经纬度是否对齐粗略检查 close (abs(e_lat - w_lat).max() 0.1) and (abs(e_lon - w_lon).max() 0.1) print(f\n网格对齐检查: {通过 if close else 不通过经纬度可能偏移}) emiss.close() wrfin.close() if __name__ __main__: check_emiss_match(wrfchemi_00z_d01, wrfinput_d01)运行这个脚本你大概就能确认排放文件和wrfinput之间最基础的匹配性。再结合ncdump查看物种名是否有拼写问题用ncview看排放量空间分布是否合理比如城市区域是否有高值基本就能把排放文件的坑踩平大半。我一直觉得WRF-Chem入门最大的障碍不是编程也不是大气化学知识而是这种“手册没写但你不知道就寸步难行”的暗坑。chem_opt和emiss_opt这对参数说透了其实就一句话它们是一对必须互相理解、互相匹配的搭档。搞明白这个核心再配合上面这些排查思路你就能少走很多弯路。根据我个人的使用经验新手最容易陷入的误区是把时间花在纠结“选哪个机制更高级”上而忽略了排放文件和机制之间的配套问题。实际上对大多数应用场景来说稳定跑通、结果合理比机制华不华丽重要得多。先把一个简单机制调到结果能看、能和观测对比再考虑升级复杂机制是更靠谱的学习路径。
阅读完成 · 觉得有帮助?