GCM 运行脚本链

路径

脚本组分布在 LMDZ.MARS\deftank/ 及其 6 个 HPC 子目录:

文件/目录 行数 作用
deftank/run0 110 原子级单段运行链——执行一次 GCM 并把 restart 推进到下一段
deftank/run_mcd 78 MCD 生产模式的 12 个月串行编排——按火星月长度依次调 run0
deftank/ciclad/run_month1 80 PBS 调度包装(法国 ciclad 集群)
deftank/occigen/run_month1 87 SLURM 调度包装(法国 occigen 集群)
deftank/irene/run_month1 85 另一集群包装(行数类似)
deftank/adastra/run_month1, run_year1 年度包装(run_year1 特有)
deftank/spirit/run_month1 类似结构
deftank/mesu/run_month1 类似结构

源码依据:deftank/README:35-38 明确说明 "run0" 用于单次或链式模拟;"run_mcd" 用 run0 并按火星月变化驱动链式模拟。

类型

脚本输入(shell 链 + 调度器模板)——用于驱动 LMDZ.MARS 物理 GCM 进行多段串联模拟。

作用

LMDZ.MARS GCM 的 3D 模拟需要长时间积分(数年 = 数千 sol),但 HPC 批处理系统对单作业墙钟时间有限制(典型 12-24 小时)。此脚本链解决:

  1. 段间状态流转run0 解决):一次运行的 restart.nc / restartfi.nc 自动重命名为下一次运行的 startN.nc / startfiN.nc
  2. 按月调度run_mcd / run_monthN 解决):火星 12 个太阳月长度不等(61/66/66/65/60/54/50/46/47/47/51/56 sol,共 669 sol),通过 sed s/9999/<NDAY>/ run.def.ref > run.defnday 占位符逐月替换写入 run.def
  3. 批处理包装(HPC 子目录):#PBS#SBATCH 头指定节点/时间/MPI 配置,末尾通过 qsub / sbatch 提交下一个月的脚本(链式 job)。
  4. 崩溃自愈run0):崩溃时写 num_run = 99999 并保留 num_run.crash,下一段会报错拒绝继续,由外部脚本根据 num_run.crash 恢复。

关键脚本

run0 —— 原子级单段运行链

源码依据:deftank/run0:1-110

流程:
1. 检查 gcm 可执行文件存在(第 22-25 行)
2. 读 num_run 文件(不存在则置 0) → numold (第 30-36 行)
3. numnew = numold + 1 (第 39 行)
4. 若 numold == 99999 → 上一段崩溃,直接 exit 1 (第 47-49 行)
5. 把 start${numold}.nc / startfi${numold}.nc 复制为 start.nc / startfi.nc (第 43-45 行)
6. 调用 ./$gcm > lrun${numnew} (第 58 行)
7. 若生成 restart*.nc → 重命名为 start${numnew}.nc 并把 numnew 写回 num_run (第 62-102 行)
8. 否则 → 把 num_run 备份为 num_run.crash,写 99999 到 num_run,发崩溃邮件(第 66-83 行)
9. 移动 diagfi/diagsoil/stats/profiles* 为带 ${numnew} 编号的版本(第 86-98 行)
10. 若 numnew+1 > nummax 则退出;否则递归 ./exe_mars(run0 副本)继续(第 104-110 行)
关键变量 默认值 含义
nummax 1 本脚本单次执行的最大链长(用户须改)(第 6 行)
gcm gcm.e GCM 可执行文件名(用户须改)(第 9 行)
numold / numnew 自动计算 段序号

文件读写deftank/run0):

文件 读/写 说明
num_run 读+写 段序号状态;崩溃时改为 99999(第 30-40、75、102 行)
num_run.crash 崩溃时保留旧序号(第 69、73 行)
start${old}.nc / startfi${old}.nc 输入初始场(第 43-45 行)
restart.nc / restartfi.nc 读+删/重命名 输出重启场(第 62-65 行)
diagfi.nc / diagsoil.nc / stats.nc / profiles.* 读+重命名 输出诊断(第 86-98 行)
lrun${new} GCM 标准输出日志(第 58 行)

run_mcd —— 串行月级运行链(非 HPC 用)

源码依据:deftank/run_mcd:1-78

流程:
1. 清理旧 error 文件(第 25 行)
2. 按火星月表逐月用 sed 把 run.def.ref 中的 9999 替换为当月 sol 数 → 写入 run.def
3. 调用 ./run0 >> error(第 28-39 行:12 月,对应 61/66/66/65/60/54/50/46/47/47/51/56)
4. 重复 2 次可选(第 42-67 行:用于第 2、3 火星年的注释模板)
5. 末尾:若 num_run == 99999 → 用 num_run.crash 恢复 num_run 并打印中止信息(第 72-78 行)

12 火星月 sol 数(源码依据:deftank/run_mcd:28-39):

sol 数 sol 数
1 61 7 50
2 66 8 46
3 66 9 47
4 65 10 47
5 60 11 51
6 54 12 56
合计 669 sol(= 1 火星年)

源码依据:deftank/run_mcd:27 注释明确 "12 martian months (=30 ° Ls) of unequal length (excentric orbit)"。

run_monthN (HPC 子目录) —— 批处理调度包装

源码依据:deftank/ciclad/run_month1deftank/occigen/run_month1 等。

通用结构(以 ciclad/run_month1 为例,第 1-80 行):

#!/bin/bash
#PBS -S /bin/bash
#PBS -N run_month1
#PBS -q day
#PBS -l nodes=1:ppn=24
#PBS -l walltime=20:00:00
...
cd $PBS_O_WORKDIR
source ../trunk/LMDZ.COMMON/arch.env
set -exv

num_now=1              # 当前月序号(用户改)
num_end=12             # 终止月序号(用户改)
num_previous=$((num_now-1))
echo "$num_previous" > num_run
num_next=$((num_now+1))
true_num=$((num_now % 12))

# 前置检查 run.def.ref、run0、run_month${num_now} 存在
...
# 根据 true_num 查火星月长度,调 run0
case $true_num in
  1 ) sed s/9999/61/ run.def.ref > run.def ; ./run0 >> error ;;
  2 ) sed s/9999/66/ run.def.ref > run.def ; ./run0 >> error ;;
  ...
  0 ) sed s/9999/56/ run.def.ref > run.def ; ./run0 >> error ;;
  * ) exit 1 ;;
esac

# 若未到终月:复制当前脚本为 run_month${num_next},sed 修改月号,提交
if (( num_next <= num_end )) ; then
  cp -f run_month$num_now tmp
  sed -e "s@run_month${num_now}@run_month${num_next}@" \
      -e "s@num_now=${num_now}@num_now=${num_next}@" tmp > run_month$num_next
  rm tmp
  qsub run_month$num_next   # slurm 版本此处为 sbatch
fi

调度器区分(源码依据:各 run_month1 首行注释):

集群 调度器 提交命令 头标志
ciclad PBS/Torque qsub #PBS
irene PBS/Torque qsub #PBS
occigen SLURM sbatch #SBATCH
adastra / mesu / spirit 各自(SLURM 为主) sbatch #SBATCH

occigen 特有环境变量(源码依据:deftank/occigen/run_month1:20-28):

export I_MPI_DOMAIN=auto
export I_MPI_PIN_RESPECT_CPUSET=0
export KMP_HW_SUBSET=1T
export OMP_NUM_THREADS=$SLURM_CPUS_PER_TASK
export OMP_STACKSIZE=400M
export KMP_AFFINITY=granularity=fine,compact,1,0,verbose

用于 hybrid MPI+OpenMP 模式,与 #SBATCH --nodes=6 --ntasks-per-node=4 --cpus-per-task=5 配合。

关键字段

字段/文件 作用 影响脚本
run0.nummax 单次 run0 执行的最大链长 run0:6, 105
run0.gcm GCM 可执行文件名 run0:9, 22, 58
num_run 段序号(纯数字 ASCII 文件) run0run_mcdrun_monthN
num_run = 99999 崩溃哨兵值 run0:47-49, 75run_mcd:72-73
run.def.ref nday = 9999 占位符的 run.def 模板 run_mcd:28-39run_monthN
9999 nday 占位符,sed 替换为当月 sol 数 run_mcd:28-39run_monthN
#PBS / #SBATCH walltime/nodes/ppn 等资源请求 run_month1 第 1-10 行
num_now / num_end 起止月序号(用户改) run_monthN:28-29, 35-36

被读取的位置

调用者 场景 说明
用户(shell) 启动模拟 直接 ./run_mcdqsub run_month1
run0 自身 链式递归 cp -f run0 exe_mars; ./exe_mars(第 108-109 行)实现链长 nummax
run_monthN 自我复制 cp + sed 生成下一月脚本,交调度器排队
GCM (gcm.e) 段内运行时 run.def(已被 sed 生成)、traceur.defz2sig.defcallphys.def、start*.nc

影响的计算流程

主题 影响
火星年生产模拟 run_mcd 是 MCD 数据库(Mars Climate Database)生产脚本链的基础
长程气候自旋 run0nummax 允许单脚本驱动数百段链
多火星年模拟 run_mcd 内注释的第 2-3 火星年模板(第 42-67 行)启用后可持续到 36 月
高分辨率 HPC 模拟 run_monthN 与 SLURM/PBS 配合实现跨集群链式月度模拟
重启文件管理 startN.nc / startfiN.nc 的 N 编号由脚本链自动维护,复现时不可手动改
崩溃恢复 num_run = 99999 强制停止后续段以避免脏链;num_run.crash 用于人工恢复

脚本调用链总览

用户
 ├── ./run_mcd                          [串行模式]
 │    ├── sed run.def.ref → run.def
 │    ├── ./run0 → gcm.e
 │    ├── sed run.def.ref → run.def
 │    ├── ./run0 → gcm.e
 │    └── ... (12 月)
 └── qsub ./run_month1                  [HPC 模式]
      ├── qsub 提交自身
      ├── source arch.env
      ├── sed run.def.ref → run.def + ./run0 → gcm.e
      ├── cp+sed → run_month2
      └── qsub ./run_month2
           └── ... (至 run_month${num_end})

复现要求

已核验脚本边界