leapfrog_p 并行动力-物理耦合
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\leapfrog_p.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dynphy_lonlat\calfis_p.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\addfi_p.F
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\top_bound_p.F
Mars 运行参与度:条件经过。Mars 并行 GCM 在 apphys=.TRUE. 且 physics 未被 iflag_phys==0/2 关闭时经过 leapfrog_p -> calfis_p -> addfi_p;串行 Mars GCM 走 leapfrog/calfis/addfi,MARS phymars/nogcm.F90 只作边界背景。
职责边界
本页只说明并行 leapfrog_p 中的 physics 调用链:
apphys
-> physics 前刷新 p/pk/phi/date
-> 分布切到 jj_Nb_physic
-> calfis_p(lafin,jD_cur,jH_cur,...)
-> tendency halo + _tmp 回填
-> addfi_p(dtphys,...)
-> 刷新 p/masse/pk
-> 可选 top_bound_p(dtphys)
-> 分布切回 jj_Nb_caldyn
calfis_p 负责把动力状态映射到物理列、调用 call_physiq 并把 physics tendency 放回动力网格;addfi_p 才把这些 tendency 乘以 dtphys 加到 prognostic state。分布切换和 halo/swap request 的细节见 leapfrog_p 分布和 halo 调度。
进入 physics 的门控
leapfrog_p 先在 851-855 行设置 lafin:
| 分支 | lafin 条件 |
|---|---|
purmats |
itau==itaufin .AND. .NOT.forward |
非 purmats |
itau+1 == itaufin |
随后 861 行只有 apphys 为真才进入 physics 段。apphys 的时间步规则由 leapfrog_p 时间步调度 覆盖;本页只沿着已经进入 physics 的路径展开。
physics 前状态刷新
进入 physics 后,leapfrog_p 先刷新物理需要的诊断状态:
- 877 行
pression_p(ap,bp,ps,p)重算层界 pressure。 - 880-884 行按
pressure_exner选择exner_hyb_p或exner_milieu_p,刷新pks/pk/pkf。 - 890-900 行先由
tpot2t_glo_p得到temp,再计算tsurpk=cpp*temp/pk,最后用geopot_p(...,tsurpk,pk,pks,phis,phi)重算位势。 - 905-927 行刷新 physics 日期:
- 默认
jD_cur = jD_ref + day_ini - day_ref + (itau+1)/day_step。 - Mars/generic 覆盖为
int(day_ini + itau/day_step)。 - Mars
jH_cur = jH_ref + hour_ini + mod(itau,day_step)/day_step。 - generic 用
start_time + mod(itau,day_step)/day_step。 - 其他行星用
start_time + mod(itau+1,day_step)/day_step。 - 若
jH_cur>1,日期进一日并把小时减 1。
- 默认
- 若
ip_ebil_dyn>=1且planet_type=="earth",才调用diagedyn;Mars 不走这个 Earth-specific 诊断。
这个日期逻辑不同于 leapfrog 阶段日期刷新:Mars physics 使用当前 itau,不是 itau+1。
调用 calfis_p
948-1002 行先把字段切到 jj_Nb_physic。随后 1017-1021 行调用:
calfis_p(lafin,jD_cur,jH_cur,
ucov,vcov,teta,q,masse,ps,p,pk,phis,phi,
du,dv,dteta,dq,flxw,
dufi,dvfi,dtetafi,dqfi,dpfi)
关键约定:
| 参数组 | 含义 |
|---|---|
ucov/vcov/teta/q/masse/ps/p/pk/phis/phi |
physics 输入状态。 |
du/dv/dteta/dq |
动力 tendency,传给 calfis_p;当前 calfis_p 页面标注部分输入在实际路径中有限使用。 |
flxw |
垂直质量通量,转到 physics 列。 |
dufi/dvfi/dtetafi/dqfi/dpfi |
physics 输出 tendency,单位是每秒。 |
calfis_p 内部再按 nsplit_phys 调用 call_physiq。每个 split 使用 dtphys/nsplit_phys,jH_cur_split = jH_cur + (isplit-1)*dtvr/(daysec*nsplit_phys);只有最后一个 split 才收到 lafin_split=.TRUE.。
tendency halo 和回填
calfis_p 返回后,leapfrog_p 不能立刻 addfi_p。它先处理 physics band 边界:
- 1023-1038 行在非北极 rank 保存本 rank 起始纬圈的
dufi/dvfi/dtetafi/dqfi/dpfi到_tmp数组。 - 1042 行切到
jj_nb_Physic_bis。 - 1048-1064 行对
dufi/dvfi/dtetafi/dpfi/dqfi注册Register_Hallo(...,1,0,0,1,Request_physic)。 - 1067-1069 行
SendRequest/WaitRequest完成 tendency halo。 - 1075 行切回
jj_nb_Physic。 - 1081-1094 行把
_tmp加回当前起始纬圈。
因此 dufi/dvfi/dtetafi/dqfi/dpfi 是经过 calfis_p 回填、跨 band halo 合并和 _tmp 补偿后的 physics tendency。排查并行 physics 差异时,要把 calfis_p 自身回填和 leapfrog_p 的后处理分开看。
addfi_p 写回状态
1106-1108 行调用:
addfi_p(dtphys,leapf,forward,
ucov,vcov,teta,q,ps,
dufi,dvfi,dtetafi,dqfi,dpfi)
addfi_p 中 leapf/forward 声明为 not used。实际写回规则:
| 状态 | 写回方式 |
|---|---|
teta |
teta += dtetafi*dtphys,随后按极点面积平均统一极点值。 |
teta pressure correction |
teta *= (1 + dpfi*dtphys/ps)**kappa。 |
ucov/vcov |
分别加 dufi*dtphys、dvfi*dtphys;U 风极点范围会避开对应极点行。 |
ps |
master 段执行 ps += dpfi*dtphys,随后极点面积平均。 |
q |
q += dqfi*dtphys,并做下限保护;Mars 走 general case,下限为 qtestt=1e-40。Earth 对前两个 tracer 用水汽下限,Titan 用 1D-200。 |
addfi_p 改了 ps,所以 leapfrog_p 立即在 1110-1118 行重算:
pression_pmassdair_pexner_hyb_p或exner_milieu_p
这个刷新是 physics 写回后保持 ps/p/masse/pk 一致的关键步骤。
top_bound_p 在 physics 段内的作用
1123-1133 行若 iflag_top_bound>0,leapfrog_p 调用:
top_bound_p(vcov,ucov,teta,masse,dtphys,dutop)
top_bound_p 的源码约定:
iflag_top_bound==1:顶部 4 层 sponge。iflag_top_bound==2:从顶部向下到约顶部层压力 100 倍的位置。mode_top_bound==1:U/V 向 0 松弛。mode_top_bound==2:U/V 向纬向平均松弛。mode_top_bound==3:U/V 和位温向纬向平均松弛。rdamp=1-exp(-lambda*dt),dt这里是dtphys。
需要注意:top_bound_p 直接修改 ucov/vcov/teta,并把 U 风增量写到 dutop。leapfrog_p 随后把 dutop 除以 dtphys,转换成 (m/s)/s tendency 形式,供后续诊断或输出使用;但状态修正已经在 top_bound_p 内完成。
与 iflag_phys==2 分支的区别
本页主线是 apphys 物理耦合段。iflag_phys==2 会在 physics 关闭的情况下走另一段 academic/Newtonian/friction/top-bound 逻辑:
addfi_p不参与该分支。friction_p(ucov,vcov,dtvr)使用dtvr。top_bound_p(...,dtvr,dutop)使用动力时间步dtvr,不是dtphys。
因此不要把 apphys 段中的 top_bound_p(dtphys) 与 iflag_phys==2 分支中的 top_bound_p(dtvr) 混为一条路径。
复现检查表
- 确认
apphys为真,且iflag_phys没有关掉 physics。 - 记录
planet_type、itau/day_step/hour_ini/start_time,Mars physics 日期按itau而不是itau+1。 - 检查
calfis_p前p/pk/phi是否已刷新。 - 对 physics tendency 差异,先查
calfis_p输出,再查jj_nb_Physic_bishalo 和_tmp加回。 - 对状态差异,检查
addfi_p的dtphys乘法、dpfipressure correction 和 tracer 下限。 - 对
ps/p/masse/pk不一致,检查addfi_p后的pression_p/massdair_p/exner_*_p是否执行。 - 对高层风温差异,检查
iflag_top_bound/mode_top_bound/tau_top_bound,并区分 physics 段dtphys与iflag_phys==2分支dtvr。
待确认
calfis_p接收du/dv/dteta/dq动力 tendency,但当前 Mars physics 实际使用程度需在callphysiq_mod和 Mars physics 侧继续确认。- Mars tracers 在
addfi_pgeneral case 中统一使用qtestt=1e-40下限;是否所有 Mars tracer 都应使用同一阈值需由 Mars physics 配置确认。 top_bound_p直接改状态而dutop只记录 U 风增量,V 风和位温的 top-bound 诊断输出边界需结合后续输出页确认。