1. 数据准备:从GSWP3到CMFD的格式转换实战
做CLM区域模拟的朋友们都知道,大气强迫数据的选择直接影响模拟结果的可靠性。GSWP3作为全球数据在中国区域表现一般,而CMFD的高分辨率数据更适合中国区域研究。但在替换过程中,数据格式转换是第一个拦路虎。
先说说降水数据(Precip)的处理细节。用ncdump查看GSWP3的nc文件结构时,你会发现它采用720×360的全球网格,时间维度以"days since"为基准,使用noleap日历(无闰年)。而CMFD数据默认采用中国区域0.1°网格,时间戳格式也不同。这里有个坑我踩过三次:CMFD的闰年2月有29天,而GSWP3用noleap日历固定28天。如果不处理这个差异,后续时间对齐必然报错。
具体操作建议用Python的xarray库处理(比Matlab更易维护):
import xarray as xr # 读取CMFD原始数据 cmfd = xr.open_dataset('CMFD_Prec_2001.nc') # 统一变量名和单位 cmfd = cmfd.rename({'precipitation':'PRECTmms'}) cmfd['PRECTmms'].attrs['units'] = 'mm H2O / sec' # 处理闰年:将2月29日数据合并到28日 if len(cmfd.time.dt.month==2) == 29: feb28 = cmfd.sel(time=cmfd.time.dt.month==2).isel(time=27) feb29 = cmfd.sel(time=cmfd.time.dt.month==2).isel(time=28) feb28['PRECTmms'] = (feb28['PRECTmms'] + feb29['PRECTmms'])/2 cmfd = xr.concat([cmfd.sel(time=cmfd.time.dt.month!=2), feb28], dim='time')处理完时间维度后,还要检查三个关键点:
- 空值处理:GSWP3用1.e+36表示缺失值,CMFD如果使用NaN需要替换
- 负值过滤:降水数据出现负值会导致CLM崩溃
- 单位统一:CMFD原始单位可能是mm/day,要转换为mm/sec
2. 空间域文件配置的隐藏陷阱
空间域文件(domain file)的配置是替换数据时最容易出错的部分。这里要区分两个概念:
- 大气强迫数据的domain:对应CMFD数据覆盖的中国区域范围
- 研究区域的domain:你实际模拟的目标区域(如华北平原)
制作domain文件时,用ncl脚本处理更高效:
ncl 'script="gen_domain.ncl"' 'infile="CMFD_geo.nc"' 'outfile="domain_CMFD.nc"' \ 'ix=720' 'jx=360' 'dx=0.1' 'dy=0.1'特别注意四个边界参数(EDGEN/EDGES/EDGEE/EDGEW)的设置:
- 中国区域建议范围:经度70°E-140°E,纬度15°N-55°N
- 边界值必须与CMFD数据严格匹配,误差超过0.1度就会导致插值失败
我在青藏高原项目中就遇到过因边界设置偏差导致的"幽灵降水"问题——模型边缘出现异常高值。后来发现是EDGEN设置比实际数据范围多出了0.05度。
3. 时间维度对齐的进阶技巧
时间戳处理看似简单,实则暗藏杀机。GSWP3使用"days since 2001-01-01"的时间坐标,而CMFD可能用"hours since"或其他基准日期。这里推荐用cdo工具批量处理:
# 转换时间基准 cdo settunits,"days since 2001-01-01" CMFD_input.nc CMFD_timefix.nc # 统一日历类型 cdo setcalendar,noleap CMFD_timefix.nc CMFD_final.nc对于长时间序列数据,建议分年份处理后再合并。我曾一次性处理10年数据导致内存溢出,后来改成逐年处理就稳定多了:
for year in range(2001,2011): ds = process_single_year(year) ds.to_netcdf(f'CMFD_{year}.nc')4. 流文件配置与案例调试
完成数据预处理后,关键的实战环节是修改datm.streams.txt文件。这里分享一个避坑检查清单:
路径深度限制:
- CESM对路径长度敏感,建议将数据放在不超过3层目录
- 错误示例:
/home/user/projects/CMFD/data/2001/Precip/(太深) - 正确示例:
~/CMFD/Precip_2001/
变量映射关系:
Solar辐射数据需要映射三个变量: FSDS → 短波辐射 FLDS → 长波辐射 PSRF → 表面气压时间覆盖检查: 在user_nl_datm中务必确认:
streams = "datm.streams.txt.CLMGSWP3v1.Solar 2001 2001 2001", "datm.streams.txt.CLMGSWP3v1.Precip 2001 2001 2001"第三个日期必须≥前两个日期,否则会静默失败
调试阶段建议先用单月数据测试。我发现一个快速验证的方法:在case.submit前运行./preview_namelists,检查生成的datm_in文件是否包含正确的CMFD路径。如果这里显示的还是GSWP3路径,说明流文件修改不彻底。
最后提醒:CLM5+版本对TPHWL数据(温度/气压/湿度/风速)有更严格的维度检查。如果遇到"变量维度不匹配"错误,先用ncks检查数据维度顺序是否符合(time, lat, lon)的约定。