ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

CESM地球系统模式从入门到实战:架构解析、环境配置与故障排查指南

CESM地球系统模式从入门到实战:架构解析、环境配置与故障排查指南 接手CESM的第一天我盯着屏幕上一串串create_newcase、case.build、xmlchange的命令完全不知道这些像暗号一样的东西会把实验带向哪里。文档是厚厚一摞但真正跑起来之后的心得往往是那些没有写的坑里爬出来的。这篇不是官方手册的复读而是把这套地球系统模式从架构理解、环境搭建、实验配置到故障排查的完整链路按照我实际操作的顺序重新讲一遍。不管你是第一次接触CESM的新手还是准备把实验从大气模式扩展到全耦合的老手这里面的经验都可以直接拿去做参考。1. 地球系统模式CESM的定位从单学科模式到全耦合的跨越1.1 CESM到底是什么和大气环流模式的区别很多刚入门的人会有个误会觉得CESM只是“更大一号的天气模式”。实际上地球系统模式Earth System ModelESM和大气的通用环流模型AGCM之间有本质的区别AGCM只算大气海温、海冰、陆面状态都是“给定边界条件”也就是外强迫数据而CESM是把大气、海洋、陆面、海冰、径流、冰盖这些圈层全部耦合在一起让它们在同一段模拟时间轴里互相交换通量、彼此反馈。简单说大气模式的输出里海洋可能只是一个随季节变化的固定温度场而在CESM里海温是海洋模式自己算出来的然后反哺给大气做感热、潜热交换同时大气给海洋风应力、淡水通量和辐射两边边算边互相影响。这个“动态反馈”是“地球系统”四个字的核心价值所在。CESM的全称是Community Earth System Model由美国国家大气研究中心NCAR主导开发社区属性非常强。从早期的CCSM3/CCSM4一路迭代到现在的CESM2系列每一个组件都有独立的开发社区和维护版本再通过统一的框架集成在一起。所以你下载的CESM不是一个“软”而是一整套组件代码加脚本框架的集合体。1.2 六大组件和各自动力学核心这套模式的组件结构我习惯用一支乐队来打比方每个声部都有自己的乐谱和演奏技法但合奏时必须由指挥统一节奏否则各吹各的整首曲子就垮了。CESM里的“声部”和“指挥”分别是组件全称职责动力学/物理核心CAMCommunity Atmosphere Model大气过程有限体积FV/谱元SE动力核心物理参数化包含云、辐射、对流、边界层CLMCommunity Land Model陆面过程生物地球物理、水文、碳氮循环、植被动态POPParallel Ocean Program海洋过程广义水平坐标海洋环流含涡扩散参数化与海洋生物地球化学可选CICECommunity Ice CodE海冰过程弹性-粘塑性海冰流变学、多类别冰厚分布、卤水-辐射耦合MOSARTModel for Scale Adaptive River Transport径流过程陆面汇流与河道输送把陆地产水送到海洋点CISMCommunity Ice Sheet Model冰盖过程冰盖动力与质量平衡主要用于长期气候模拟这些组件之间的“指挥”是耦合器CPL7。它负责把各组件的网格场插值到其他组件需要的网格上统一交换时间基准并保证能量和淡水通量守恒。后面第4章我会专门展开。如果到这里你还不太理解为什么需要这么复杂的组件拆分可以反过来想如果只算大气那么陆面蒸发怎么来海冰覆盖面积怎么定径流注入海洋的淡水怎么给这些一旦全部外包给“固定强迫数据”模式的内部一致性就没有了你也就无法研究海冰-大气反馈这类核心问题。CESM的价值正是把这个多圈层反馈链在代码层面完整地搭起来。2. 从零搭起一套CESM运行环境安装与配置中的关键抉择2.1 硬件选型先想清楚你要跑多长、跑多细我第一次配机器时犯过一个错误只盯着“核数多不多”忽略了内存、磁盘和I/O结果编译倒是成功了跑起来之后输出文件把家目录整个写爆。CESM的硬件需求取决于你的实验方案但有一组比较稳妥的起步配置CPU至少64物理核。跑f09_g171度大气1度海洋这类常用网格64~128核能把单核负载控制稳定避免每个进程内存超限。内存每核2GB起步。CESM各组件对内存的消耗不均匀。比如CAM6在SE动力核心下谱元网格需要额外的数组空间内存小了容易直接崩。128核的话256GB内存是相对安心的线。磁盘这是最容易被低估的。输入数据一套低分辨率大约几十GB但长期模拟的历史输出会轻松超过输入数据一个量级。建议预留实验输出目录至少2TB并用独立挂载点不要和系统盘抢空间。网络与I/O集群环境下运行目录尽量放在本地高速盘或者并行文件系统不要放在普通NFS网络盘上跑否则历史输出的写入瓶颈会让几百核等你一个磁盘。实测下来f09_g17配置下用240核跑一个百年全耦合实验大约需要几倍的墙钟时间这取决于编译器优化和硬件。计算前先小规模试跑1年用测出来的时间反推总时长比盲目提交百年级任务靠谱得多。2.2 依赖库的版本搭配netcdf/mpi/pio的组合拳CESM的运行依赖一套底层库最核心的三个是NetCDF、MPI和PIOParallel I/O。这三个库的版本关系是新手在安装阶段最容易翻车的地方。NetCDF需要分别安装C接口和Fortran接口而且两者的版本要配套。比如用NetCDF-C 4.9.2Fortran接口最好用4.6.0这一代。版本错位最常见的报错是编译阶段找不到netcdf.mod或者链接阶段报一堆undefined reference to nf_create_。MPI方面OpenMPI 4.x和Intel MPI都有社区实践成功的案例。关键是编译整个CESM时所有组件和依赖库必须用同一个MPI。如果NetCDF是用OpenMPI编出来的后面跑CESM却用Intel MPI运行时就会因为ABI不一致出现莫名其妙的错误。所以我的习惯是先定MPI再编NetCDF最后再编CESM全程记录版本号和安装路径。PIO2虽然由CIME框架自动管理但它依赖NetCDF和MPI本质上是对底层I/O的封装。你不需要手编PIO只要保证前面两个库路径清晰、环境变量干净即可。另外CIME还依赖CMake和Python 3高版本CESM已不再支持Python 2这些基础工具也建议提前装齐。注意不要在同一台机器上同时加载多套MPI环境变量。跑CESM之前先module list看一下当前环境确保编译环境和运行环境完全一致。2.3 输入数据下载与机器端口配置CESM需要一套庞大的输入数据inputdata包括地形、海温、温室气体浓度、太阳常数、陆面植被类型等。在创建case之前就必须先保证输入数据可用。下载方式通常是运行./manage_case --download inputdata或者手动从官方数据服务器同步但无论哪种方式都需要先配置好机器端口machine port。端口配置是CIME框架里一个很关键的步骤你要在config_machines.xml里定义本机的名称、操作系统、编译器、作业提交系统和队列设置。这个文件位于cime/config/cesm/machines/下。如果你是单机可以仿照其中的generic_Linux模板改一个自己的machine条目。我第一次没配置端口就直接create_newcase结果脚本找不到对应的机器配置直接退出。后来才明白CIME的整套逻辑是“先有机器定义后有case实例”——机器端口是CIME和你本机间的翻译层它告诉框架用哪个编译器、怎么提交作业、在哪找数据没有这个定义框架连编译命令都拼不出来。这里我再补充一个经验输入数据尽量不要放在home目录下。很多新手配置路径时会顺手用~/inputdata但模拟一天天跑日志和临时文件会不断增长home的配额很快被耗尽。我一般单独建/data/cesm_inputdata这样的目录并且在配置里用绝对路径写死这样即使跑完一个case下一个case也能复用同一套输入数据避免重复下载几十GB。3. case生命周期CESM实验管理的一整套规则3.1 compset与网格命名规则里藏着实验设计在CESM中一次实验被称为一个case。创建case的命令是./create_newcase但真正考验理解力的是--compset和--res这两个参数。compset是“组件集合”的缩写它决定实验里哪些组件被激活、使用哪种强迫年限配置。以最常见的F2000为例F代表只跑大气CAM陆面CLM有时带海冰数据2000代表温室气体、气溶胶、太阳常数这些外强迫固定在2000年附近。这种AMIP型的配置因为不含海洋和海冰动态计算量小、稳定度高适合跑模式调优、快速验证物理参数化。而B1850里的B代表“fully coupled”即所有主动组件都打开1850表示工业化前期强迫。如果要研究气候变率、海冰反馈、全球变暖响应就需要B类compset。全耦合的计算量比F大很多每个时间步都要等最慢的组件所以不要一上来就跑B类百年实验先把F类流程走通。网格参数--res同样有命名规则。f09_g17表示大气使用1度网格约110km海洋使用名义1度网格g17f19_g17则是大气2度约220km海洋仍是1度。分辨率越高可分辨的天气尺度过程越细但计算量和输出量同步上涨起步阶段建议用低分辨率跑通再用目标分辨率做正式实验。3.2 XML配置系统环境变量、构建选项与运行选项创建case之后目录里会生成一堆env_*.xml文件这是CESM的配置中枢。你不需要直接编辑这些XML而是用./xmlchange命令修改用./xmlquery查询。几个高频修改项运行长度./xmlchange STOP_OPTIONnyears,STOP_N10表示连续运行10年如果只想跑30天就改成STOP_OPTIONndays,STOP_N30。输出频率./xmlchange HIST_OPTIONndays,HIST_N1控制历史文件按天输出。默认是月平均如果你的分析需要日数据再改成按天输出但这会让输出体积膨胀很多建议先确认磁盘够。作业队列./xmlchange JOB_QUEUEregular适配本机集群的队列策略。没有设置好队列提交作业时会被调度系统拒绝。还有一种更隐蔽的配置方式是通过user_nl_cam、user_nl_clm这些“user namelist”文件给组件传入额外的物理参数。比如想修改CAM的辐射步长可以在user_nl_cam里加iradsw 1。这些namelist文件在case运行前必须确认存在并写对否则组件会使用默认值你的实验设计就悄悄失真了。3.3 构建与提交case.build和case.submit之前必须检查的几件事整个case流程通常四步create_newcase-case.setup-case.build-case.submit。很多人以为这只是机械地敲四条命令其实每一步背后都有必须确认的细节。case.setup会生成运行时目录和配置文件。执行之前一定要确认env_mach_specific.xml里的模块加载命令和你的实际环境一致。我经历过一次脚本里加载的是Intel 19.0但机器上module默认是Intel 2021结果case.build编译出一堆internal compiler error查了半天才发现是版本漂移。case.build是编译组件库和生成可执行文件的过程。这一步耗时较长低分辨率全组件编译在普通集群上可能要30分钟到1小时。如果编译中途失败不要慌先看bld/目录下的编译日志最常见的失败是找不到某个依赖库的路径改好环境变量后不用全部重来直接重新执行case.build即可。case.submit提交后实验进入运行阶段。提交前建议随手执行一次./check_input_data这个命令会帮你检查输入数据是否完整能省下运行时因缺数据而崩溃的等待时间。4. 一次完整运行的幕后耦合器CPL7与控制流4.1 耦合器CPL7组件之间到底怎么对话CESM组件之间不是简单地把各自的输出文件拼在一起而是通过CPL7耦合器以设定好的频率进行在线交换。CPL7基于ESMF框架开发它做的事情可以分三层理解。第一层是网格映射。大气和海洋的网格点并不重合大气的一个网格可能覆盖海洋的多个网格。CPL7预先计算好稀疏矩阵插值权重比如双线性映射、保守映射每次耦合时用矩阵乘法完成数据转移。这个映射不是“文学式地近似一下”它有严格的守恒约束尤其是热量和淡水通量必须在映射过程中保持不变否则模拟几十年后全球平均温度会缓慢漂移。第二层是通量计算。有些交换字段如感热、潜热、长波辐射由大气算出来交给海洋而海表温度、海冰覆盖率等则从海洋/海冰传回大气。CPL7还负责部分通量的合成比如把径流、冰盖融水、降水的淡水通量合并后交给海洋。第三层是同步控制。地球系统模式里各组件的时间步长不一样大气可能10分钟一个物理步海洋可能30分钟一个动力步。CPL7在规定的耦合周期通常模拟时长里的若干分钟内等所有组件推进到同一时刻的耦合点再统一交换数据。这样每一轮耦合都严格同步不存在某个组件“跑在前面”或“落后”的情况。理解CPL7的意义在于排查问题。当你看到某个模拟年份后海洋温度异常第一反应不应是“海洋模式有bug”而应该先去查耦合器日志里是否有持续的通量丢失或者映射权重缺失。这类问题往往比组件内部bug更隐蔽。4.2 运行目录会生成什么日志与输出文件的读法运行提交后case目录下的run/会变成最热闹的地方。熟悉这些文件的含义能让你在排错时节省大量时间。每个组件会分别写自己的日志atm.log、lnd.log、ocn.log、ice.log、cpl.log。其中cpl.log是总控日志记录每次耦合的时间推进和通量交换组件日志则记录各自内部的运行状态。我的排错顺序永远是先看cpl.log最后几十行确认模式推进到哪一天崩的再去看那个时间点对应的组件日志。rpointer文件是一组文本指针记录重启文件restart files的位置和名称。续跑时模式根据rpointer.atm等文件找到重启数据。如果这些指针对应的文件被你误删了续跑会直接失败。所以任何时候都不要手动删run/里的文件除非你非常确定它在后续运行中不再需要。历史输出文件通常以h0、h1标识区分h0默认频率的历史文件通常是月平均包含长期分析所需的主要变量。h1更高频率输出如日平均或6小时平均用于分析天气尺度变率。h2等极少用一般对应瞬时快照。文件格式是NetCDF变量名和坐标名遵循各组件约定。分析时我习惯先用ncdump -h快速查看变量列表再用CDO或NCO做变量提取、区域平均和时间拼接。如果你处理的是多年代月平均数据cdo monmean和ncks的组合基本能覆盖大多数需求。4.3 三种启动方式initial、hybrid、branch怎么选一个常被忽视但极其重要的选择出现在env_run.xml的RUN_TYPE变量里。initial从初始条件文件冷启动。所有组件从各自的初值出发通常前期需要一段“spin-up”让模式内部各圈层达到平衡。hybrid从其他case的重启文件启动但允许修改某些配置。比如你想用1850年的海洋重启文件来跑2000年强迫实验或者想换一个参数化方案后继续跑就选hybrid。branch严格接续某个运行状态的“分支”物理过程和重启文件必须完全一致适合做集合实验的不同扰动分支。三种方式的关键区别在于“能否改配置”。branch的约束最强最能保证和母实验的连续性hybrid最灵活但引入的偏差需要自己评估initial适合全新实验。我遇到过同学为了省spin-up时间从一个case的hybrid启动做了完全不同的参数化修改结果前100年模拟出现明显的模式漂移和母实验对不上。这提醒我们hybrid启动后要留出足够的平衡时间不是你想要的物理状态立刻就能得到。5. 我在CESM运行中踩过的坑故障排查实战记录5.1 编译失败netcdf与mpi库不一致这是出现率最高的失败类型。我第一次自己搭环境时按网上教程分别编译了NetCDF-C、NetCDF-Fortran和OpenMPI但教程里的版本号和我机器上的不完全一致。编译CAM时报错信息是一堆undefined reference to nf90_create。我心里明白这不是代码问题而是链接时找不到Fortran接口的符号。查了bld/cmake的日志后发现NetCDF-Fortran是用OpenMPI 3编译的而我给CIME配置的MPI是OpenMPI 4两者运行时库路径冲突Fortran接口没有正确链接。解决方式很直接把NetCDF-C、NetCDF-Fortran全部用同一个OpenMPI版本重新编译一遍再清掉bld目录重新build。此后再也没出现这类链接错误。这个坑给我的教训是环境里的“小版本差异”在平台类代码里根本不小务必逐库统一MPI版本。5.2 运行中期崩溃NaN、SIGSEGV与磁盘空间运行到第17年突然崩溃是比编译失败更吓人的场景。日志最后一行显示NaN detected in atm看起来像大气模式算出了非法浮点数。排查过程是一层层剥的。先看atm.logNaN出现的时间点对应模式中的某次对流调整。再看cpl.log确认该时刻陆地-大气通量交换是否有异常淡水输入因为淡水通量异常可能破坏边界层热力结构进而触发对流参数化里的非法数值。最后定位到陆面模式某个网格的径流变量在连续数天里出现异常峰值根因是那个网格的植被类型在输入数据里被标记为“城市”城市网格的水力传导率设置极端导致数据异常。这种隐藏在输入数据里的脏数据问题比模式本身的bug更难发现。建议大型实验前先做一个“输入数据体检”单独运行模式前两三年按月尺度检查关键变量如降水、海表温度、径流的最大值是否在物理合理范围内。SIGSEGV则通常是内存或栈溢出。遇到过在集群上因为ulimit -s栈大小被系统默认限制为8MB而SE动力核心需要更大的栈空间。在env_mach_specific.xml里加上ulimit -s unlimited之后问题消失。磁盘满这个坑不算技术问题但它最容易埋雷。f09_g17输出在日频率下每年历史文件可能达到几百GB。如果实验计划跑30年磁盘就要先准备至少这个规模的几倍空间。我习惯在每个case里配一个磁盘检测脚本定期检查输出目录占用超过阈值自动告警。5.3 一个隐蔽的坑续跑后模型状态不一致有一次我中断了一个100年实验做了一些代码改进只是修改了输出频率的namelist然后用branch方式续跑。结果续跑后的第一个月某些变量的输出值出现了不连续跳跃。我没急着改物理配置先检查了rpointer里记录的重启时间。发现问题出在中断方式上上一次运行是在模拟年2023年6月30日输出时被作业系统杀掉但部分组件已经写完了下一个小时的状态。重启后模式从6月30日0时开始而输出文件却记录到了7月1日新旧数据出现了重叠。这类时间不连续问题通常肉眼不容易发现但对后期统计有隐性影响。经验是中断实验后不要直接续跑先检查rpointer和各组件日志末尾的时间是否完全一致若有微小不一致把不完整的输出文件先移走再让模式重建该时段确保输出序列是干净的。6. 给新手的三条实战建议第一从最简配置跑通全流程。很多同学第一次就想跑B1850全耦合百年实验结果被计算量、崩溃频率和数据量三重打击。我的建议是先建一个F2000、f19_g17、模拟1年的case从create_newcase到后处理完整走一遍理解每一步的控制文件和后端逻辑再逐步上复杂配置。第二实验记录要“过度”而非“不足”。系统性的实验管理比纠结某个物理参数更影响你的科研效率。我给每个case建一个文本日记记录创建时间、compset、分辨率、改了哪些XML、哪个namelist、跑了多久、崩在哪个文件、后续怎么处理。等到写论文存档或追溯问题时这套日记的价值比任何代码管理工具都大。第三不要用黑客心态硬碰问题。CESM的报错信息大多有明确指向花5分钟读日志最顶部的ERROR行和最尾部的时间信息往往就能定位问题。遇到不确定的报错先./xmlquery确认关键配置是否符合预期别急着重编。依靠“先想后动”比盲目更换库版本更有效率。最后分享一点个人体会地球系统模式规模庞大很多时候我们容易陷进技术细节里不能自拔。但退一步想模式本身是工具真正值得投入的是用工具去逼近“圈层如何协同演变”这个物理问题。CESM的学习曲线确实陡峭但当你第一次看到自己配置的耦合实验跑出完整的大气环流和海洋环流同步演变的漂亮结果时前面那些编译报错、磁盘告警和NaN排查都会变成值得回看的旧事。
返回列表