ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

CLM独立运行完整实战:从环境配置到结果可视化指南

2026/9/24 20:57:32 拓冰建站 浏览量
CLM独立运行完整实战:从环境配置到结果可视化指南 1. 先说清楚CLM独立运行到底解决什么问题以及你学它值不值先说个我在超级计算机上花了整整一个学期才想明白的道理CESM全耦合模式不适合用来学陆面过程CLM独立运行才是入门和科研的正确姿势。CESMCommunity Earth System Model的完整版把大气、海洋、陆面、海冰四个模块通过耦合器拼在一起跑一次全球十年模拟动辄要几千核并行、算个几天几夜。更麻烦的是四个模块互相牵制只要你改了一个参数整个系统就要重新磨合平衡。做陆面过程研究的人——比如我当年研究土壤湿度对降水的影响实际关心的只是CLMCommunity Land Model这一个模块却要为大气模式的动力核心、海洋模式的网格分辨率买单纯属浪费计算资源和时间。CLM独立运行也叫CLM off-line mode的思路很简单把陆面模块从CESM里单独拆出来给它提供一个已经算好的大气强迫场通常来自观测数据或再分析资料让它自己闭门修炼。这时候你的输入是气温、降水、辐射、风速这些气象要素输出是土壤温湿度、径流、蒸散发、碳通量、植被状态完全由陆面过程本身决定。这不只省了计算开销更重要的是把问题简化到了纯粹可控的陆面过程模拟层面。我梳理了一下下面这几类人最应该提前掌握这套独立运行的完整技能研究陆面过程机理本身的土壤水热、蒸散发、碳循环、冻土演变给某个流域、某块农田做水循环或能量平衡模拟的需要为其他模型提供陆面下边界条件的想在CLM里加入新的植被参数化方案、陆面模块二次开发的以及像我当年一样毕业论文只需要陆面结果但不想把时间耗在跑通整个CESM上的人这篇文章要讲的就是一套完整的、可以直接复现的CLM独立运行流程从环境配置、文件下载、编译一路走到结果处理和可视化出图。硬核但不玄乎你在自己机器上就能跟着一步步做下去。2. 环境准备与编译配置文件锁死版本省掉99%的无头绪报错CLM2CESM这套系统最折磨人的不是代码本身而是版本的互相兼容问题。我见过太多新手一上来就在官网把最新的CESM3代码拖下来然后被一堆接口报错碾碎信心。这里我给出一套经过了大量实践验证、稳定可用的版本组合和配套环境按这个来踩坑最少。2.1 推荐版本组合与硬件要求根据实际经验我推荐使用下面这套组合组件推荐版本说明CESM代码包cesm2_1_1 或2.1.3这两个版本对CLM5.0支持完善社区资料多报错好查netCDF库netcdf-c 4.7.4 netcdf-fortran 4.5.3前后端分离编译器要求清晰MPI库mpich 3.3.2串行可不装跑大区域或全球网格时强烈建议并行Fortran编译器gfortran 9.x 或 Intel ifort 19多数Linux发行版自带gfortran最省事Python3.8以上后面做可视化用先配好环境为什么强调这个版本组合因为这些版本之间的接口约定是匹配好的CLM5.0的代码里硬编码了很多对netCDF库接口的期望比如老版本netcdf-c在处理时间单位字符串时会跟新版本有细微差异直接导致读取数据边界错位。我在实验室的一台CentOS 7服务器上一开始装的是netcdf-c 4.9.2CLM编译倒是能过但运行时读初始条件文件一直报内存越界后来退回到4.7.4才正常。这个坑值得你留意。操作系统的要求其实很宽松Ubuntu 20.04/22.04、CentOS 7/8、openSUSE都行macOS也能跑但需要brew装gcc和netcdfWindows用户建议直接上WSL2或装虚拟机。2.2 环境变量与依赖库编译以Ubuntu系统为例先把基础依赖装齐sudo apt update sudo apt install -y build-essential gfortran m4 perl \ libxml2-dev libcurl4-openssl-dev \ libhdf5-dev libopenmpi-dev openmpi-bin然后编译安装netCDF。这里有个关键点必须先编译netcdf-c再编译netcdf-fortran前者是后者的基础顺序反了必然失败。# 编译 netcdf-c wget https://github.com/Unidata/netcdf-c/archive/refs/tags/v4.7.4.tar.gz tar -xzf v4.7.4.tar.gz cd netcdf-c-4.7.4 ./configure --prefix/usr/local/netcdf --disable-dap make -j4 sudo make install # 编译 netcdf-fortran wget https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v4.5.3.tar.gz tar -xzf v4.5.3.tar.gz cd netcdf-fortran-4.5.3 export LD_LIBRARY_PATH/usr/local/netcdf/lib:$LD_LIBRARY_PATH export CPPFLAGS-I/usr/local/netcdf/include export LDFLAGS-L/usr/local/netcdf/lib ./configure --prefix/usr/local/netcdf make -j4 sudo make install最后把环境变量写进~/.bashrc确保每次登录自动生效export NETCDF/usr/local/netcdf export PATH$NETCDF/bin:$PATH export LD_LIBRARY_PATH$NETCDF/lib:$LD_LIBRARY_PATH export LIBRARY_PATH$NETCDF/lib:$LIBRARY_PATH export CPATH$NETCDF/include:$CPATH注意串行和并行的netCDF建议分开安装。如果你要用MPI并行跑CLM配套的netcdf也要用--enable-parallel重新编译一份否则并行I/O会挂。我第一次没注意这个一跑mpirun -np 8就报NetCDF: Unknown file format排查了半天才发现是串行版库文件顶替了并行版。2.3 下载CESM源代码与CLM部分代码获取最稳妥的方式是通过Git和SVN组合拉取# 创建代码目录 mkdir -p ~/cesm_code cd ~/cesm_code # 用git克隆管理脚本 git clone https://github.com/ESCOMP/cesm.git cesm2_1_1 cd cesm2_1_1 git checkout cesm2_1_1第一次checkout之后代码会指引你运行脚本来拉取所有子模块。这一步对网络要求比较苛刻因为要同时从GitHub和SVN服务器上拉一堆组件经常断线。建议用脚本里的重试机制多跑几次./manage_externals/checkout_externals如果网络不稳定也可以单独把CLM部分拉下来cd components # 如果clm目录为空直接从svn拉取 svn export https://svn-ccsm-models.cgd.ucar.edu/clm2/trunk/ ./clmCLM的源代码体积不小下载完成后确认目录大小在2GB以上才算正常。跑一次du -sh确认一下小于这个数基本说明有子模块没拉全。2.4 创建Machine文件与配置编译这是CLM独立运行里最容易被人忽略的一步。create_newcase脚本在创建Case时需要知道当前机器上的编译器、MPI命令、作业调度系统是什么这些信息都写在config/cesm/machines/config_machines.xml里。如果你的机器不在默认列表中脚本会直接报错说找不到匹配项。解决办法是自己定义一个machine。在config_machines.xml里追加一段machine MACHmyworkstation DESCLocal workstation/DESC OSLINUX/OS COMPILERSgnu/COMPILERS MPILIBSmpich/MPILIBS PROJECTnone/PROJECT SAVE_TIMINGFALSE/SAVE_TIMING CIME_OUTPUT_ROOT/home/yourname/cesm_runs/CIME_OUTPUT_ROOT DIN_LOC_ROOT/home/yourname/cesm_inputdata/DIN_LOC_ROOT DIN_LOC_ROOT_CLMFORC/home/yourname/cesm_inputdata/atm_forcing.datm7/DIN_LOC_ROOT_CLMFORC RUNDIR/home/yourname/cesm_runs/run/RUNDIR EXEROOT/home/yourname/cesm_runs/bld/EXEROOT /machine里面的路径按你自己的目录结构改就行。DIN_LOC_ROOT是输入数据根目录DIN_LOC_ROOT_CLMFORC专门指大气强迫数据目录这两个路径后面下载数据时要用到。接下来是编译。以CLM5.0独立运行的典型配置为例cd ~/cesm_code/cesm2_1_1/cime/scripts ./create_newcase --case /home/yourname/cesm_runs/clm_single_site \ --compset I2000Clm50SpGs \ --res 1x1_brazil --machine myworkstation --run-unsupported参数解释一下I2000Clm50SpGs表示2000年初始条件CLM5.0Sp是卫星植被数据驱动Gs是地表数据使用网格尺度。这是陆面独立模拟最常用的compset。res 1x1_brazil单点网格巴西某个点。如果你要跑某个站点比如通量观测站CESM里预置了一批1x1_xxx的单点grid你可以用query_defaults查看可用选项。--run-unsupported因为我们是自定义的workstation机器必须加上这个参数否则脚本直接拒绝执行。创建完成后进入Case目录开始配置编译cd /home/yourname/cesm_runs/clm_single_site ./xmlchange STOP_N5,STOP_OPTIONnyears # 模拟5年 ./xmlchange RUN_STARTDATE2000-01-01 ./xmlchange DATM_CLMNCEP_YR_ALIGN2000 # 强迫数据与模拟年份对齐 ./xmlchange DATM_CLMNCEP_YR_START2000 ./xmlchange DATM_CLMNCEP_YR_END2004 ./case.setup ./case.build编译时间取决于机器配置一般20到60分钟。看到case.build毫无报错地跑完你的环境配置这一大关就算过了。3. 独立运行的三块硬骨头domain文件、大气强迫数据、namelist参数环境编译过了你只是有了一个能跑的空壳。CLM能不能真正转起来并输出有意义的结果取决于三样东西domain文件模拟区域定义、大气强迫数据外源气象驱动、以及运行控制参数namelist。这三块的坑我挨个说说。3.1 domain文件定义你要模拟的地球表面domain文件说白了就是告诉CLM你的模拟区域有多少个网格点每个网格点的经度纬度是多少哪些网格点是陆地、哪些是海洋/湖泊陆地占每个网格的面积比例是多少对新手而言最稳的路径是利用CESM自带的工具从地表数据生成domain文件而不是自己去构造。在components/clm/tools/mkmapdata/下有个mkmapdata.sh脚本它会读取CLM的地表数据集并生成对应分辨率的domain文件。但单点模拟时还有一个更省事的做法CESM在输入数据仓库里直接预置了和各个站点网格对应的domain和surfdata文件。比如运行结果里会提示你下载# 查看case里设置的输入数据路径 ./xmlquery DIN_LOC_ROOT # 在该目录下按如下结构放置文件 # 以单点为例比如1x1_brazil # ${DIN_LOC_ROOT}/share/domains/domain.lnd.1x1_brazil_navy.090715.nc # ${DIN_LOC_ROOT}/lnd/clm2/surfdata_map/surfdata_1x1_brazil_hist_16pfts_Irrig_CMIP6_simyr2000_c190214.nc这些文件的下载地址在${DIN_LOC_ROOT}/lnd/clm2/surfdata_map/下面有个README文件里有完整链接列表。用wget批量拉下来就行。一个重要的提醒domain文件里的网格坐标必须和surfdata以及大气强迫数据完全对齐。很多时候模拟出来的结果出现奇怪的斑块状异常就是因为domain文件里陆地mask和强迫数据的格点错位了半度。我会在第四部分再详细教你验证这个对齐关系。3.2 大气强迫数据CLM模拟的外部燃料独立运行的CLM自己不会算大气它需要外部输入的辐射、降水、气温、风速、气压、比湿。CESM官方推荐使用GSWP3或CRUNCEP这两套再分析数据集。下载强迫数据的时候系统一般会自动通过DATM_CLMNCEP相关XML变量定位到输入数据服务器。手动下载也行但文件体积很大——全球范围逐小时的气象数据动辄几个GB建议只下你模拟区域所在的那部分数据。站点模拟通常用.nc的单点多文件也可以在inputdata/atm_forcing.datm7/下看到按数据集和年份组织好的目录。强迫数据的时间覆盖很关键。你在DATM_CLMNCEP_YR_START和DATM_CLMNCEP_YR_END里指定的年份必须严格落在你下载的forcing文件覆盖范围内。比如你想跑2000到2004年那么至少要有2000到2004年的逐小时forcing文件。我遇到过缺2001年4月数据的情况CLM直接在某一个时间步上算出NaN接着整个碳循环模块就崩了。3.3 namelist参数控制模拟走向的旋钮在Case目录跑过一次./case.setup之后会生成namelist相关的模板文件。CLM的关键运行参数在user_nl_clm里维护这是你需要手动编辑的最核心文件。一份典型的user_nl_clm长这样! 输出控制设置历史文件输出频率 hist_fincl1 FSDS,FSR,FSA,FIRA,FIRE,FCTR,FCEV,FCS,FGEV,FGR,FGR12,FGR34,FHD,FG hist_nhtfrq -24 hist_mfilt 30 ! 初始条件 finidat ! 输出网格单点模拟时通常省略使用默认网格 ! hist_doy2date .true. ! 时间步长秒 dtime 1800 ! 土壤层设置默认10层可修改 ! nlevgrnd 10我重点解释几个参数的作用hist_fincl1你要输出哪些变量的列表。CLM的变量名和ECMWF、NCEP那套不太一样比如向下短波辐射是FSDS感热通量是FSH潜热通量是FCEVFCTR。选变量时建议先在CLM的文档里查一下变量的含义不要凭缩写猜我做第一个实验时把FGR土壤热通量当成地表径流白白浪费了很多分析时间。hist_nhtfrq输出频率单位是小时负数表示小时数正数表示时间步数。-24就是每天输出一次要做日尺度的蒸散发分析这个设置就够用了。finidat热启动初始文件空字符串表示从冷启动开始。后续做续跑时这个参数非常重要要填上之前的restart文件路径。dtime积分步长单点模拟1800秒30分钟完全够如果跑全球0.9°分辨率建议用900秒以防数值不稳定。配置完成后提交运行命令cd /home/yourname/cesm_runs/clm_single_site nohup ./case.submit run.log 21 单点5年模拟在现代工作站上通常几十分钟就能跑完多核并行更快。4. 从提交到产出实测运行流程和三个最容易翻车的运行细节编译过了、文件配齐了很多人觉得万事大吉结果一跑起来全是幺蛾子。这一节我把实际运行中容易翻车的细节摊开来讲清楚。4.1 冷启动预热期前几个月的结果不可直接使用CLM冷启动时土壤湿度、土壤温度的初始值仓促给出和实际气候状态差距巨大模型需要一个spin-up阶段来自己调整植被、土壤水、碳库到平衡态。我在跑一个亚马逊单点站点时前6个月的模拟结果里土壤含水量一直在剧烈波动直接看蒸散发数值会发现它比观测值低了很多。这不是模型bug而是土壤水库还在蓄水阶段。所以分析结果时必须舍弃前期的预热期。一般建议冷启动后至少舍弃1到2年再做研究分析如果你关心的是碳循环那需要的时间更长甚至要用finidat做多次循环加速平衡。怎么判断spin-up是否完成CLM在运行时会在run/目录下生成.log文件里面每步都会打印土壤水和碳库的统计。你找到水循环或碳循环相关的诊断量看它逐年变化是否趋于稳定如果连续几年波动小于1%基本可以认为进入平衡态了。4.2 单点网格的边界效应坑了我一周的怪相单点模拟运行时CLM只计算那一个格点看起来简单但实际有隐藏问题单点格点在半球日射计算里没有邻域信息处理长波辐射时的天空视角因子会和真实环境有偏差。更常见的是一些站点位于海岸线附近1x1_xxx网格里同时包含了一定的海洋面积比例导致CLM打出奇怪的低植被覆盖度。我的处理办法是模拟之前用ncdump -h查看land fraction变量确定你关心的坐标点上landfrac的数值是否接近1。如果不接近换一个内陆的单点grid或者改用区域网格别在海岸边缘硬跑否则分析结果总差一口气。4.3 缺少独立的实时观测验证数据的必须有观有测CLM独立运行的本质是强迫-响应实验所以它特别依赖高质量的强迫数据这一点常常被忽略。GSWP3数据集在2003年之前和之后的连续性有跳变CNRDAP在某些高海拔区域也存在系统性偏差。如果你观测站点附近的气象站数据是能和GSWP3对比的我强烈建议你做一个简单的一致性检验ncdump -v FSDS path/to/forcing/file.nc | head -100检查辐射通量的日变化曲线是否符合常识白天高、夜间为0最大值不超过太阳常数1361 W/m²。如果连这个基本物理界限都超了你的模拟结果再漂亮也没用问题根源在forcing上。另外一个很实际的小技巧跑完以后立刻去看run/目录下的.lnd.log.*文件搜ERROR和WARNING。有些警告可以忽略比如某个格点短暂出现负降水被代码钳制为0但只要是ERROR你就要老老实实回溯数据来源。这个习惯能帮你省下一整周排查问题的时间。5. 结果处理的三个常用操作finidat续跑、变量筛选、时间尺度聚合CLM跑完后原来的run/目录下会生成一大票历史文件比如*.h0.*.nc月平均、*.h1.*.nc高频输出。直接在原始文件上做分析会非常吃力尤其是跨几十年的模拟文件数量大到不聚合没法用。所以结果处理这一步值得专门讲。5.1 用finidat实现平滑续跑续跑的正确姿势不是重新从冷启动跑一遍而是利用CLM的restart机制。在Case目录下执行./xmlchange RUN_TYPEbranch ./xmlchange RUN_REFCASEclm_single_site ./xmlchange RUN_REFDATE2004-01-01这样CLM会读取2004年1月1日的状态文件.r*.nc从这个时间点接着往下跑。这套机制做两件事一是可以无缝延长模拟年限二是可以用来做敏感性实验——比如你在某个时间点改变了某个参数从该时间点的状态文件做branch run结果的变化就纯粹来自参数改动。如果你是要做超长spin-up比如500年以上碳循环平衡可以循环提交多次案例每次用上一次的restart文件作为本次的finidat输入finidat /path/to/run/clm_single_site.clm2.r.2009-01-01-00000.nc我可以告诉你一个我测试过的平衡收敛指标对碳库量比如TOTVEGC总植被碳连续跑两段各50年末态差异小于0.5%基本可以视为进入准平衡。5.2 基于xarray的变量筛选与时空裁剪CLM输出文件是老牌netCDF格式推荐用xarray来处理代码简洁、内存管理也灵活import xarray as xr ds xr.open_dataset(clm_single_site.clm2.h0.2000-01.nc) # 查看所有变量 print(ds.data_vars) # 选取温度和降水相关变量 sub ds[[TSA, RAIN, SNOW, FSDS]] # 裁剪到感兴趣的时间段 sub sub.sel(timeslice(2000-02-01, 2000-08-01))这里有个小坑CLM的time维度经常带着time_bounds如果后续要用resample做时间聚合先检查时间索引是否连续。某些版本的输出时间轴存在重复或缺失例如闰年处理不当导致2月29日前后时间坐标对齐错乱。5.3 把逐小时数据聚合到月/季尺度CLM最高频输出可以到逐半小时但大多数分析根本不需要这么高的时间分辨率。建议在数据产出的第一时间就做聚合减少后续处理的负担。用xarray可以一行搞定# 月均 monthly sub.resample(time1MS).mean() # 季节均DJF、MAM、JJA、SON seasonal sub.resample(timeQS-DEC).mean() # 多年年均 annual sub.resample(time1AS).mean()如果你的time坐标不稳定比如不是标准日历可以用groupby配合time.dt.month做多年同月合成clim_month sub.groupby(time.month).mean(time)这是研究气候态最常用的一招多年逐月平均之后的曲线会比原始逐日数据平滑得多也更容易在图上看出气候信号。6. 用Python把CLM结果画出专业级图件空间图、时间序列、过程归因数据处理的终点是理解和呈现。CLM模拟的结果怎么画出来这里我不推荐去看那些大而全的可视化平台软件单发一个图很多时候用不上那些重型工具。我自己最常用的组合是Python xarray matplotlib cartopy画出来的图从投稿标准到日常探索都能覆盖。6.1 空间分布图一张图看区域差异以模拟的蒸散发为例如果跑的是区域网格先做多年月均再画空间填色图import xarray as xr import matplotlib.pyplot as plt import cartopy.crs as ccrs import cartopy.feature as cfeature ds xr.open_dataset(clm_regional.clm2.h0.2000-2010.nc) et ds[FCEV] ds[FCTR] # 总蒸散发 W/m2 et_annual et.mean(time) # 多年年均 fig plt.figure(figsize(12, 6)) ax plt.axes(projectionccrs.PlateCarree()) im ax.pcolormesh(et_annual.lon, et_annual.lat, et_annual, cmapYlGnBu, shadingauto) ax.coastlines() ax.add_feature(cfeature.BORDERS, linestyle:) plt.colorbar(im, axax, labelET (W/m²), shrink0.8) ax.set_title(Annual Mean Evapotranspiration (2000-2010)) plt.savefig(et_spatial.png, dpi300, bbox_inchestight)注意事项CLM的网格通常是不规则网格比如FV网格是经纬度规则网格但SE网格就不规则这种网格画图时要避免直接用pcolormesh而要先用xr.interp把数据插值到规则的经纬度网格上再画。别小看这一步不正规则网格直接画出来的图会有明显的网格边界锯齿编辑看到直接打回。插值的做法et_regrid et_annual.interp(latnp.linspace(-60, 80, 280), lonnp.linspace(-180, 180, 720))6.2 时间序列图站点模拟的标配单点模拟最常用的是时间序列。画多年逐月蒸散发曲线时加一个阴影包络标准差范围会更直观import numpy as np et (ds[FCEV] ds[FCTR]).squeeze() et_monthly et.resample(time1MS).mean() # 多年逐月统计 clim et_monthly.groupby(time.month).mean(time) std et_monthly.groupby(time.month).std(time) fig, ax plt.subplots(figsize(10, 5)) months np.arange(1, 13) ax.plot(months, clim, o-, color#1a9850, lw2) ax.fill_between(months, clim - std, clim std, color#1a9850, alpha0.3) ax.set_xlabel(Month) ax.set_ylabel(ET (W/m²)) ax.set_xticks(months) ax.set_xticklabels([Jan,Feb,Mar,Apr,May,Jun, Jul,Aug,Sep,Oct,Nov,Dec])这里fill_between的包络带能让你一眼看出季节性波动的幅度比如季风区的ET是单峰还是双峰。6.3 过程归因把土壤湿度-蒸散发耦合画成散点密度图我做的研究里最能体现CLM价值的一步是把模拟输出的土壤湿度与蒸散发关系画出来用来诊断陆气耦合强度soil ds[H2OSOI].isel(levgrnd0, timeslice(None, None, 3)) # 表层土壤湿度 et (ds[FCEV] ds[FCTR]).isel(timeslice(None, None, 3)) fig, ax plt.subplots(figsize(6, 6)) hb ax.hexbin(soil.values.flatten(), et.values.flatten(), gridsize50, cmapviridis, mincnt1) plt.colorbar(hb, axax, labelCount) ax.set_xlabel(Surface Soil Moisture (m³/m³)) ax.set_ylabel(ET (W/m²))用hexbin而不是普通的scatter是因为几万个点叠在一起会互相遮挡根本看不出密度分布。hexbin可以把点密度用颜色显示出来非常适合这类变量间关系的分析画图。6.4 快速探索工具推荐别什么图都从头写代码在做正式图件之前建议先用一些轻量工具快速浏览数据形态比如直接用ncviewncview clm_single_site.clm2.h0.2000-01.nc这个工具可以在终端里快速翻页查看所有变量的空间分布对排查异常值特别有用。我通常先用ncview浏览一遍全部变量找到感兴趣的变量之后再写Python脚本做深度分析。如果数据量很大还可以考虑用holoviews或hvplot做交互式探索但正式出图还是matplotlib和cartopy最稳。6.5 出图前一定要检查的三个细节出图工作中有几个细节直接影响图片是否被期刊接收第一是色板选择。CLM输出的变量种类繁多辐射通量和降水用YlGnBu这类渐变色比较合适而温度场用RdBu_r更能体现冷暖对比。不要在一篇论文里把十张图的色板风格搞得完全不统一视觉上像拼凑出来的。第二是单位标注。CLM输出的通量单位多为W/m²储量单位多为gC/m²或kg/m²变量名的缩写又不直观画图时必须明确标注。我审稿时经常看到变量符号对但单位错的论文这种硬伤很影响可信度。第三是坐标轴范围和刻度。如果你对比多个实验组一定要统一coord范围否则图之间的视觉差异会被夸大或缩小。这算是科研绘图的基本伦理问题我这里提一句。7. 根据我个人跑CLM的体会最后给你几条实在的建议跑了快三年CLM之后回头看自己掉进去又爬出来的那些坑有几条经验值得特别拎出来说。别一上来就追求全球高分辨率。先把单点跑到通把强迫数据、domain、namelist这套逻辑吃透了再扩展到区域或全球。全球0.25°模拟一跑就是一周起步光调试就够折腾的你怀疑人生。每次改动前先保存一份原来的配置和输出。CLM对参数变化极其敏感有时候只是改了地表反照率方案蒸散发结果会变20%以上。没有对照实验你根本讲不清楚结果变化是物理改进还是数值噪音。养成盯log文件的好习惯。CLM运行中的很多问题在log里其实已经给了明确提示只是被埋在大量输出里。我每次跑完必做的第一件事是grep -i error\|warning *.log*根据这两个词筛出需要关注的内容能过滤掉90%的无效信息。可视化工具不在多顺手最好。我分析时xarraymatplotlib足够应付95%的需求剩下的5%用ncview浏览异常值。不需要为了好看把环境里装上一堆大屏可视化平台那些东西在科研出图上用武之地有限。CESM和CLM的学习曲线确实陡但只要你把独立运行的这条链路完整走通一次——环境配置、数据准备、运行、结果处理、出图——后面的研究就只是在换变量、换区域、换场景了。希望这篇东西能帮你少走我当初走过的那些弯路。