动力-物理接口
源码范围:LMDZ.COMMON-6.3/LMDZ.COMMON/libf/dynphy_lonlat、libf/phy_common,并串联 dyn3d/leapfrog.F、dyn3dpar/leapfrog_p.F、dyn3d/addfi.F、dyn3dpar/addfi_p.F 的调用边界。 Mars 运行参与度:条件经过。Mars 3D GCM 启用物理时经过本主题覆盖的初始化和 calfis/calfis_p -> call_physiq -> addfi/addfi_p 接口;Mars 1D/testphys 路径只使用其中的接口兼容层和物理侧网格/垂直层初始化。
主题定位
本页回答一个问题:动力网格上的 ps/p/pk/teta/q/u/v/phi/flxw 如何进入 Mars physics,又如何以 tendency 形式回到动力状态。
接口拆成三层:
| 层 | 责任 | 主要页面 |
|---|---|---|
| 初始化层 | 建立物理列分布、几何、垂直层和动力-物理索引。 | inigeomphy_mod, parallel-physics-grid-distribution, mod_interface_dyn_phys |
| 每步调用层 | 把动力状态转为物理列,调用 call_physiq,把 tendency 放回动力网格。 |
calfis, calfis_p, dyn-phys-grid-transforms |
| 写回状态层 | addfi/addfi_p 将 tendency 乘以 dtphys 加到 prognostic state,并刷新 pressure/mass/Exner。 |
leapfrog-physics-coupling, leapfrog-p-physics-coupling, addfi-serial-parallel |
总体调用链
串行 GCM physics 步:
gcm/conf_gcm/iniconst/inigeom/iniphysiq
-> COMMON inigeomphy
-> init_physics_distribution
-> init_interface_dyn_phys
-> init_regular_lonlat / init_geometry / init_vertical_layers
leapfrog
-> apphys gate
-> pression / exner_* / geopot
-> calfis(lafin,jD_cur,jH_cur,...)
-> gr_dyn_fi and manual wind/tracer mapping
-> call_physiq, optionally split by nsplit_phys
-> gr_fi_dyn and manual tendency writeback
-> addfi(dtphys,...)
-> pression / massdair / exner_*
并行 GCM physics 步:
gcm_p/init_parallel/set_bands
-> iniphysiq
-> inigeomphy
-> init_physics_distribution
-> init_grid_phy_lmdz
-> Init_phys_lmdz_para
-> init_phys_lmdz_mpi_data
-> init_phys_lmdz_omp_data
-> dimphy:Init_dimphy(klon_omp, nbp_lev)
-> init_interface_dyn_phys(index_i/index_j)
-> init_geometry(klon_omp, ...)
-> init_vertical_layers(...)
leapfrog_p
-> apphys gate
-> pression_p / exner_*_p / geopot_p
-> SetDistrib(jj_Nb_Physic)
-> calfis_p(lafin,jD_cur,jH_cur,...)
-> rank-level动力格点到klon_mpi物理列
-> OpenMP切片到klon_omp
-> call_physiq, optionally split by nsplit_phys
-> OpenMP gather回klon_mpi
-> MPI wind tendency boundary exchange
-> tendency写回动力网格
-> SetDistrib(jj_Nb_Physic_bis)
-> tendency halo and tmp add-back
-> addfi_p(dtphys,...)
-> pression_p / massdair_p / exner_*_p
-> SetDistrib(jj_Nb_Caldyn)
calfis/calfis_p 只产生每秒 tendency;真正修改 ucov/vcov/teta/q/ps 的位置是 addfi/addfi_p。addfi* 之后必须刷新 p/masse/pk,否则后续动力、输出或 restart 会看到与新 ps 不一致的派生状态。
初始化约定
Mars physics 初始化先进入 MARS 侧 iniphysiq,再调用 COMMON 的 inigeomphy。inigeomphy 的输出不是单个返回值,而是写入一组物理侧公共模块:
| 状态 | 写入者 | 使用位置 | 关键边界 |
|---|---|---|---|
klon_glo, nbp_lon/lat/lev |
init_grid_phy_lmdz |
全局物理网格转换、XIOS、debug 写场 | klon_glo 是全局物理列数,两极各压缩成单列。 |
klon_mpi 和 rank 分布表 |
init_phys_lmdz_mpi_data |
MPI transfer、calfis_p、XIOS/write_field |
当前 MPI rank 的物理列数,不等于全局列数。 |
klon_omp 和 thread 切片 |
init_phys_lmdz_omp_data |
Mars physics、OMP transfer、calfis_p |
当前 OpenMP 线程的物理列数。 |
dimphy:klon/klev |
Init_dimphy |
Mars physics 例程 | dimphy:klon 等于 klon_omp,不是 klon_glo 或 klon_mpi。 |
index_i/index_j |
Init_interface_dyn_phys |
calfis_p, gr_dyn_fi_p, gr_fi_dyn_p |
长度为 klon_mpi,把 rank 级物理列映射到动力 (i,j)。 |
longitude/latitude/cell_area |
init_geometry |
physics、diagfi、XIOS、archive 工具链 | 每个 OMP 线程只持有自己的 klon_omp 几何切片。 |
ap/bp/aps/bps/presnivs/pseudoalt |
init_vertical_layers |
physics、输出轴、Mars utility | 从动力侧 comvert_mod 显式复制到物理侧 vertical_layers_mod。 |
这条链只建立分布和静态几何。每个 physics 步的 ps/teta/q/u/v/phi/flxw 仍由 calfis/calfis_p 从动力状态重新映射。
串行接口
串行 calfis 使用全局 lon-lat 规则把动力网格压缩成物理列:
- 北极和南极各为一个物理列。
- 中间纬圈按非重复经度展开。
gr_dyn_fi转换标量场,风场用cu/cv和极点cos/sin投影转换为自然风。tpot2t把位温转为 physics 温度。- 按
nsplit_phys分段调用call_physiq,每段使用dtphys/nsplit_phys。 - 物理返回的温度、风、tracer、surface pressure tendency 被累计、平均,再用
gr_fi_dyn或显式循环写回动力 tendency 数组。
串行 tracer 写回使用 niadv(iq) 连接 physics tracer 和动力 tracer 序号。排查 tracer 顺序差异时,串行路径要同时看 infotrac 的 nqtot/tname/niadv。
并行接口
并行 calfis_p 的职责比串行多三件事:rank 分布、OpenMP 切片和跨 rank tendency 边界。
动力格点到物理列
calfis_p 先以 klon=klon_mpi 工作。普通列通过 index_i/index_j 读取动力格点:
zpsrf(ig) = ps(index_i(ig), index_j(ig))
zpk(ig,l) = pk(index_i(ig), index_j(ig), l)
zqfi(ig,l,iq) = q(index_i(ig), index_j(ig), l, iq)
gr_dyn_fi_p 和 gr_fi_dyn_p 也使用同一映射。极点列仍是单列,写回动力网格时要扩展成整条极点行。
OpenMP 物理调用
rank 级 z*(klon_mpi,...) 数组准备好后,源码按 klon_omp_begin/end 手写循环复制到当前线程的 *_omp(klon_omp,...)。随后局部 klon 改为 klon_omp,call_physiq(klon,...) 看到的是当前线程的物理列数。
这一段不调用 mod_phys_lmdz_transfert_para 的 scatter/gather 泛型。原因是 calfis_p 的映射源是动力二维网格 (iip1,jjp1),目标是 rank 内物理列;phy_common 通用 transfer 的映射对象是 klon_glo -> klon_mpi -> klon_omp 的物理列数组,两者不是同一类搬运。
tendency 边界和 addfi_p 前处理
calfis_p 返回前已经把 tendency 写回动力网格,但并行 leapfrog_p 还要做一次 physics band 后处理:
- 保存非北极 rank 起始纬圈的
dufi/dvfi/dtetafi/dqfi/dpfi到_tmp。 - 切换到
jj_nb_Physic_bis。 - 对 physics tendency 注册 halo request 并等待完成。
- 切回
jj_nb_Physic。 - 把
_tmp加回起始纬圈。
只有完成这一步后,addfi_p 才把 tendency 加到状态。因此并行差异要分成三段定位:calfis_p 列映射和 call_physiq 输出、leapfrog_p tendency halo、addfi_p 状态写回。
call_physiq 约定
COMMON 侧不实现 Mars physics 过程本体,但它负责提供一致的入口实参:
| 实参组 | 来源 | 说明 |
|---|---|---|
klon,llm,nqtot,tname |
物理分布、动力垂直层、tracer 初始化 | klon 在并行 OMP 内为 klon_omp。 |
jD_cur,jH_cur |
leapfrog* 日期逻辑 |
并行 Mars physics 日期在 leapfrog_p 中按当前 itau 计算。 |
zplev,zplay,zpk |
pression*、Exner、preff*(ppk/cpp)**(1/kappa) |
pressure 层和 Exner/温度转换输入。 |
ztfi,zqfi,zufi,zvfi,zrfi |
calfis* 转换 |
physics 使用的温度、tracer、自然风和涡度。 |
zphi,zphis,flxwfi |
geopot* 和 grid transform |
位势、地表位势和垂直质量通量。 |
zdufi/zdvfi/zdtfi/zdqfi/zdpsrf |
call_physiq 输出 |
每秒 tendency,之后由 calfis* 和 addfi* 分别映射/加回。 |
nsplit_phys 分段时,COMMON 侧在每个 split 后先用 tendency 更新 physics 输入列,再累计平均 tendency。最后一个 split 才接收 lafin_split=.TRUE.。
transfer 边界
物理侧通用 transfer 已由 mod_phys_lmdz_mpi_transfert、mod_phys_lmdz_omp_transfert 和 mod_phys_lmdz_transfert_para 覆盖。它们服务于物理侧数组在全局、rank 和 thread 之间的 scatter/gather/bcast/reduce。
本主题需要区分三类通信:
| 通信/搬运 | 实现位置 | 是否是 calfis_p 主搬运 |
|---|---|---|
物理侧通用 bcast/scatter/gather/reduce_sum |
phy_common/mod_phys_lmdz_*_transfert.F90 |
否。供 physics 公共层和输出/helper 使用。 |
| 动力网格到物理列映射 | calfis_p, gr_dyn_fi_p, gr_fi_dyn_p |
是。由 index_i/index_j 和手写 OMP 循环驱动。 |
| wind tendency 跨 rank 交换 | calfis_p 内 MPI_ISSEND/IRECV/WAITALL |
是。只服务于 pdvfi 等跨纬带回填 stencil。 |
不要把 calfis_p 的手写 scatter/gather 描述成直接调用 mod_phys_lmdz_transfert_para。两者共享 klon_mpi/klon_omp 维度概念,但调用路径和映射关系不同。
与物理几何和垂直层的关系
inigeomphy 同时初始化水平几何和垂直层副本:
- regular lon-lat 的全局经纬轴写入
regular_lonlat_mod。 - 当前线程局部物理列的经纬度、边界、面积、输出面积写入
geometry_mod。 - 动力侧
comvert_mod中的ap/bp/aps/bps/presnivs/pseudoalt复制到vertical_layers_mod。
Mars physics、diagfi/stats、XIOS 输出和 archive utility 可能使用这些物理侧状态。若出现输出坐标、面积或压力轴问题,先确认 iniconst/disvert/inigeom/iniphysiq -> inigeomphy 顺序,而不是直接查每步 calfis_p。
串并行差异表
| 方面 | 串行 | 并行 |
|---|---|---|
| 调度入口 | leapfrog -> calfis -> addfi |
leapfrog_p -> SetDistrib(jj_Nb_Physic) -> calfis_p -> halo -> addfi_p |
| 物理列规模 | 全局 ngridmx |
rank 级 klon_mpi,线程级 klon_omp |
| 列映射 | 固定 lon-lat 展开 | index_i/index_j |
| OMP | 无 | rank 级共享数组 + threadprivate *_omp 工作区 |
| MPI | 无 | physics tendency halo + calfis_p wind exchange |
| tracer 写回 | 使用 niadv(iq) |
当前 calfis_p 按 iq=1,nqtot 直接写回 |
| 状态写回 | addfi 后刷新 p/masse/pk |
addfi_p 后刷新 p/masse/pk,并受 band/halo 影响 |
复现检查表
- 确认
conf_gcm已设置iphysiq/iflag_phys/nsplit_phys,并且当前时间步apphys=.TRUE.。 - 确认 physics 前已刷新
p/pk/phi,并记录jD_cur/jH_cur。 - 串行路径检查
gr_dyn_fi/gr_fi_dyn的极点和周期端点规则。 - 并行路径检查
SetDistrib(jj_Nb_Physic)、index_i/index_j、klon_mpi/klon_omp和dimphy:klon是否一致。 - 对 physics 内部差异,先确认
call_physiq入口看到的是温度ztfi而不是动力位温teta。 - 对 tendency 差异,区分
calfis*输出、并行 halo 合并、addfi*加回三步。 - 对 pressure/mass 不一致,检查
addfi*后pression*/massdair*/exner_*是否执行。 - 对输出几何或垂直坐标,检查
inigeomphy -> init_geometry/init_vertical_layers,不要只看每步calfis*。
易混点
calfis_p使用klon_mpi/klon_omp,但不直接调用mod_phys_lmdz_transfert_para的scatter/gather泛型。dimphy:klon在并行 physics 内等于当前线程的klon_omp。calfis/calfis_p输出是每秒 tendency,不是已经加到状态里的增量。addfi/addfi_p改ps后必须刷新压力、质量和 Exner。inigeomphy初始化的是物理侧几何和垂直层状态;每步动力状态仍需由calfis*映射。- 串行
calfis和并行calfis_p对 tracer index 的处理不同,不能直接套用同一niadv推理。 - Mars 1D/testphys 通过接口兼容层使用 COMMON 状态,但不等同于 3D 并行动力的
calfis_p主链。
待确认
COMM_LMDZ与COMM_LMDZ_PHY在所有 Mars 并行配置中是否完全一致,需要运行配置或 MPI 初始化实测确认。calfis_p传入call_physiq的动力 tendency 参数在 Mars physics 侧实际使用程度,需要结合LMDZ.MARS/libf/phymars/callphysiq_mod.F90和具体物理过程继续确认。- 并行
calfis_p未使用niadv是否依赖 当前 tracer 顺序保证,仍需结合真实traceur.def配置验证。
相关页面
- dynamics-time-integration
- serial-parallel-dynamics
- dynphy_lonlat 总览
- calfis
- calfis_p
- mod_interface_dyn_phys
- inigeomphy_mod
- dyn-phys-grid-transforms
- calfis-p-grid-mapping
- calfis-p-physiq-contract
- calfis-p-parallel-transfer
- calfis-p-date-planet-branches
- parallel-physics-grid-distribution
- vertical-coordinate-mars-contract
- leapfrog-physics-coupling
- leapfrog-p-physics-coupling
- phys-transfer-para-wrapper