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 先刷新物理需要的诊断状态:

  1. 877 行 pression_p(ap,bp,ps,p) 重算层界 pressure。
  2. 880-884 行按 pressure_exner 选择 exner_hyb_pexner_milieu_p,刷新 pks/pk/pkf
  3. 890-900 行先由 tpot2t_glo_p 得到 temp,再计算 tsurpk=cpp*temp/pk,最后用 geopot_p(...,tsurpk,pk,pks,phis,phi) 重算位势。
  4. 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。
  5. ip_ebil_dyn>=1planet_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_physjH_cur_split = jH_cur + (isplit-1)*dtvr/(daysec*nsplit_phys);只有最后一个 split 才收到 lafin_split=.TRUE.

tendency halo 和回填

calfis_p 返回后,leapfrog_p 不能立刻 addfi_p。它先处理 physics band 边界:

  1. 1023-1038 行在非北极 rank 保存本 rank 起始纬圈的 dufi/dvfi/dtetafi/dqfi/dpfi_tmp 数组。
  2. 1042 行切到 jj_nb_Physic_bis
  3. 1048-1064 行对 dufi/dvfi/dtetafi/dpfi/dqfi 注册 Register_Hallo(...,1,0,0,1,Request_physic)
  4. 1067-1069 行 SendRequest/WaitRequest 完成 tendency halo。
  5. 1075 行切回 jj_nb_Physic
  6. 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_pleapf/forward 声明为 not used。实际写回规则:

状态 写回方式
teta teta += dtetafi*dtphys,随后按极点面积平均统一极点值。
teta pressure correction teta *= (1 + dpfi*dtphys/ps)**kappa
ucov/vcov 分别加 dufi*dtphysdvfi*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 行重算:

这个刷新是 physics 写回后保持 ps/p/masse/pk 一致的关键步骤。

top_bound_p 在 physics 段内的作用

1123-1133 行若 iflag_top_bound>0leapfrog_p 调用:

top_bound_p(vcov,ucov,teta,masse,dtphys,dutop)

top_bound_p 的源码约定:

需要注意:top_bound_p 直接修改 ucov/vcov/teta,并把 U 风增量写到 dutopleapfrog_p 随后把 dutop 除以 dtphys,转换成 (m/s)/s tendency 形式,供后续诊断或输出使用;但状态修正已经在 top_bound_p 内完成。

与 iflag_phys==2 分支的区别

本页主线是 apphys 物理耦合段。iflag_phys==2 会在 physics 关闭的情况下走另一段 academic/Newtonian/friction/top-bound 逻辑:

因此不要把 apphys 段中的 top_bound_p(dtphys)iflag_phys==2 分支中的 top_bound_p(dtvr) 混为一条路径。

复现检查表

  1. 确认 apphys 为真,且 iflag_phys 没有关掉 physics。
  2. 记录 planet_typeitau/day_step/hour_ini/start_time,Mars physics 日期按 itau 而不是 itau+1
  3. 检查 calfis_pp/pk/phi 是否已刷新。
  4. 对 physics tendency 差异,先查 calfis_p 输出,再查 jj_nb_Physic_bis halo 和 _tmp 加回。
  5. 对状态差异,检查 addfi_pdtphys 乘法、dpfi pressure correction 和 tracer 下限。
  6. ps/p/masse/pk 不一致,检查 addfi_p 后的 pression_p/massdair_p/exner_*_p 是否执行。
  7. 对高层风温差异,检查 iflag_top_bound/mode_top_bound/tau_top_bound,并区分 physics 段 dtphysiflag_phys==2 分支 dtvr

待确认

相关页面