guide forcing 叠加到动力状态
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\guide_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\guide_p_mod.F90
Mars 运行参与度:接口兼容 + 条件边界。只有由 leapfrog/leapfrog_p 调用 guide_main 时经过;当前源码中该调用受 CPP_IOIPSL + planet_type=="earth" 条件包围。Mars/generic ok_guide 初始化路径调用 relaxetat0("relax.nc"),不经过本页状态叠加链。
guide_main 职责
guide_main(itau,ucov,vcov,teta,q,masse,ps) 直接修改动力预报变量。它不是返回一个独立 tendency,而是把 guide 目标场与当前状态的差值经 guide_addfield 加权后写回:
target = (1-tau) * Xgui1 + tau * Xgui2
if guide_add:
f_add = target
else:
f_add = target - current_state
optional guide_zonave(f_add)
guide_addfield(f_add, alpha_X)
current_state = current_state + f_add
tau 是两个 guide 输入时间片之间的线性权重;若 iguide_read=0,则固定 tau=1。factt=dtvr*iperiod/daysec 在首次进入时计算,用于 tau2alpha 和 guide 输出诊断。
变量叠加顺序
guide_main 的状态更新顺序固定为 U、T、P、Q、V:
| 开关 | 目标场 | 差值/forcing | 权重 | 写回 |
|---|---|---|---|---|
guide_u |
ugui1/ugui2 |
f_add 或 target-ucov |
alpha_u |
ucov += f_add |
guide_T |
tgui1/tgui2 |
f_add 或 target-teta |
alpha_T |
teta += f_add |
guide_P |
psgui1/psgui2 |
f_add(:,1) 或 target-ps |
alpha_P |
ps += f_add(:,1) 后重算 masse |
guide_Q |
qgui1/qgui2 |
f_add 或 target-q |
alpha_Q |
q += f_add |
guide_v |
vgui1/vgui2 |
f_add(1:ip1jm,:) 或 target-vcov |
alpha_v |
vcov += f_add(1:ip1jm,:) |
guide_add=.TRUE. 时,target 被解释为外部 forcing-like 增量;普通 nudging 则使用目标场减当前状态的差值。guide_zon=.TRUE. 时,会先把 f_add 做 zonal average,再乘权重并写回。
guide_addfield
串行版 guide_addfield(hsize,vsize,field,alpha) 对所有水平点和垂直层执行:
field(:,l) = alpha * field(:,l) * alpha_pcor(l)
并行版按 hsize 判断 U/scalar 网格和 V 网格:
hsize==ip1jm:只处理ijb_v:ije_v。- 其他情况:只处理
ijb_u:ije_u。
alpha_pcor(l) 是边界层修正。若 guide_BL=.TRUE.,所有层为 1;否则按
(1 + tanh((0.85 - presnivs(l)/preff)/0.05)) / 2
衰减靠近边界层的 nudging。presnivs/preff 越接近低层,系数越容易被压低。
guide_zonave
guide_zonave(typ,hsize,vsize,field) 可把 forcing 变成纬向平均场。首次调用时根据 guide_reg 和 lon_min_g/lon_max_g 计算平均经度范围:
typ=1使用rlonu,用于 U 网格。typ=2使用rlonv,用于标量、P、Q、T 和 V 调用。
随后对每个纬向行和垂直层,在 imin(typ):imax(typ) 经度范围内求平均,并把该平均值复制到整圈经度。若 guide_reg=.FALSE.,默认使用全经度范围。
并行版只在本地纬向范围内做相同操作:V 网格用 jjb_v:jje_v,其他网格最终写 jjb_u:jje_u。源码中非 V 分支计算平均时也用 jjb_v:jje_v 扫描,再填回 U/scalar 本地行;这对南极缩减分布可能使极行行为不同,属于运行验证点。
guide 输出诊断
若 guide_sav=.TRUE. 且 MOD(itau,iguide_sav)==0,f_out 为真:
- 串行版先写
SP,再在各变量段写当前场、目标场或f_add/factt。 - 并行版在写
SP前重算层中心压力并传给guide_out("SP",...,factt=1.);各变量调用guide_out(..., factt),由 guide 输出例程处理并行 gather/root 写。
诊断中的 f_add/factt 表示把当前步增量换算为每“动力步天分数”的 forcing 量,不等同于物理包 tendency 单位。
ini_anal 分支
首次进入 guide_main 时若 ini_anal=.TRUE.,源码直接把初始状态设为 guide 当前目标场并返回,不走常规 guide_addfield:
- U、T、Q、P 分别写
ugui2/tgui2/qgui2/psgui2。 - P 分支写
ps后立即调用pression/massdair或_p版本刷新masse。 - V 分支源码写的是
vcov=ugui2(并行版为vcov(ijb_v:ije_v,:)=ugui2(...)),不是vgui2;本页按 当前源码记录,设计意图待确认。
串并行差异
| 环节 | 串行 guide_mod |
并行 guide_p_mod |
|---|---|---|
| 写回范围 | 全局数组 | ijb_u:ije_u 或 ijb_v:ije_v 本地段 |
guide_addfield |
全水平域乘 alpha*alpha_pcor |
按 U/scalar 或 V 本地段乘权重 |
guide_zonave |
全纬向行和全经度可见 | 本地纬向行可见;V 分支按 jjb_v:jje_v |
guide_P 后刷新 |
pression + massdair |
pression_p + massdair_p |
| 输出 | guide_out 直接写 |
guide_out 需并行 gather/root 语义 |
并行版没有在 guide_main 入口执行注释掉的 AllGather_Field,所以正常路径依赖 guide_read 读全场、guide_interp 局部切片和本地写回。
复现要点
- 先确认
guide_add:它决定 guide 场是外部增量还是目标状态。 guide_zon会在加权前把 forcing 做纬向平均,影响所有变量。guide_P是唯一会立刻重算masse的分支;U/T/Q/V 只直接写对应状态。- 若低层 nudging 弱,检查
guide_BL和alpha_pcor(l)。 - 并行调试时,按
ijb_u/ije_u与ijb_v/ije_v分开看写回范围。
待确认
ini_anal下 V 风写ugui2而非vgui2是否是历史 bug。- 并行
guide_zonave的非 V 分支用jjb_v:jje_v做平均是否会影响极行或仅是可接受的本地行选择。