guide_mod.F90
源码路径:LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\guide_mod.F90。
Mars 运行参与度:接口兼容 + 条件边界。当前源码中 leapfrog.F 对 guide_mod:guide_main 的活动调用位于 #ifdef CPP_IOIPSL 且 planet_type=="earth" 的分支内;Mars/generic 初始化阶段的 ok_guide 读取 relax.nc 并调用 relaxetat0,不经过本模块。因此本页把 guide_mod 作为 COMMON 串行 nudging 实现和 Mars 配置边界来记录,不写成 Mars 标准 3D 主线必经路径。
文件定位
guide_mod 是串行 nudging/guide 模块。它只有一个外部入口 guide_main(itau,ucov,vcov,teta,q,masse,ps),其余配置读取、NetCDF 输入、垂直插值、松弛系数构造、状态叠加和诊断输出都封装在模块内部。
并行对应实现是 dyn3dpar/guide_p_mod.F90。两者数值职责相同,但并行版额外处理局部分布、halo、guide_plevs 和 root-only 输出,见 guide 串并行差异。
公开入口
| 符号 | 类型 | 调用方 | 职责 |
|---|---|---|---|
guide_main |
subroutine | leapfrog.F 的 Earth/IOIPSL ok_guide 分支 |
首次初始化 guide 系统,按时间读取/插值输入场,把 guide forcing 叠加到 U/V/T/P/Q 动力状态。 |
模块内主要私有例程:
| 例程 | 职责 |
|---|---|
guide_init |
读取 nudging_parameters_out.txt 参数,探测 NetCDF 垂直层数,分配 Xnat/Xgui/alpha 数组,并读第一个时间片。 |
guide_read |
从 3D NetCDF 文件读取 U/V/T/Q/Ps 和 AP/BP。 |
guide_read2D |
从经度-气压二维切片读取场,并沿经度广播。 |
guide_interp |
把自然变量从 guide 压力层插值到 LMDZ 动力层,并转换为 covariant wind、位温和比湿。 |
tau2alpha |
把 tau_min/tau_max 天数常数转换为逐格点 nudging 系数。 |
guide_addfield |
对 forcing 乘 alpha*alpha_pcor。 |
guide_zonave |
可选把 forcing 做纬向平均。 |
guide_out |
可选写 guide_ins.nc 诊断文件。 |
correctbid |
保留的坏值修补 helper;源码中未发现活动调用。 |
共享状态
guide_mod 用 PRIVATE, SAVE 模块状态持有完整 guide 会话:
| 状态组 | 变量 | 含义 |
|---|---|---|
| 频率 | iguide_read, iguide_int, iguide_sav |
输入读取、垂直插值和诊断输出频率。 |
| 变量开关 | guide_u, guide_v, guide_T, guide_Q, guide_P |
控制各物理量是否参与 nudging。 |
| 输入解释 | guide_hr, guide_teta, guide_modele, guide_2D, invert_p, invert_y |
湿度、温度、压力坐标、2D 文件和层序/南北反转。 |
| forcing 语义 | guide_add, guide_zon, guide_reg, guide_BL, ini_anal |
外部增量/目标状态、纬向平均、区域权重、边界层修正和初态分析场。 |
| 原始场 | unat/vnat/tnat/qnat/psnat, apnc/bpnc |
两个 guide 时间片的输入场和输入压力坐标。 |
| 模型层目标场 | ugui/vgui/tgui/qgui/psgui |
插值到 LMDZ 动力层后的目标或增量场。 |
| 权重 | alpha_u/alpha_v/alpha_T/alpha_Q/alpha_P/alpha_pcor |
水平与垂直 nudging 权重。 |
所有数组按串行全局维度分配;本模块没有 MPI 局部切片。
调用流程
guide_main(itau, ucov, vcov, teta, q, masse, ps)
first call:
guide_init()
factt = dtvr * iperiod / daysec
tau2alpha(...) for U/V/T/P/Q
build alpha_pcor
optional ini_anal direct state replacement
each call:
if iguide_read says new input time:
Xnat1 = Xnat2
guide_read or guide_read2D
if MOD(itau,iguide_int)==0:
guide_interp(ps,teta)
tau = interpolation weight between Xgui1 and Xgui2
for U, T, P, Q, V:
build f_add
optional guide_zonave
guide_addfield
optional guide_out
write back to state
guide_main 修改传入的动力状态数组,不返回单独 tendency。guide_add=.FALSE. 时 forcing 是目标场减当前状态;guide_add=.TRUE. 时输入被解释为外部增量。
配置和输入文件
guide_init 通过 getparam 读取 guide 参数。参数组和输入场细节见 guide 配置与初始化约定 与 guide 输入场读取。核心文件名如下:
| 物理量 | 文件 | 变量 |
|---|---|---|
| U | u.nc |
UWND |
| V | v.nc |
VWND |
| T | T.nc |
AIR |
| Q/RH | hur.nc |
RH |
| Ps | ps.nc |
SP |
| AP/BP | apbp.nc |
AP, BP |
串行版只支持两类输入压力坐标:guide_modele=.FALSE. 时用纯压力层 apnc,guide_modele=.TRUE. 时用 apnc + bpnc * psnat。并行版的 guide_plevs=2 逐格点 P.nc 路径不在本文件中。
插值和状态叠加
guide_interp 的职责是把输入压力层上的自然变量转换成 LMDZ 动力层变量:
- 调
pression和exner_hyb或exner_milieu得到模型层压力。 - 用
massbar得到 U/V staggered 网格压力。 - 对 U/V/T/Q 分别调用
pres2lev。 - U/V 乘
cu/cv转为 covariant wind。 - T 若不是
guide_teta,用cpp/pk转为位温。 - Q 若
guide_hr=.TRUE.,调用q_sat把相对湿度百分比转为比湿。
guide_main 的状态叠加顺序固定为 U、T、P、Q、V。P 分支是唯一会立即重算 pression 和 massdair 的分支,因为它改变了 ps 和 masse。
输出诊断
guide_sav=.TRUE. 且 MOD(itau,iguide_sav)==0 时,guide_out 写 guide_ins.nc。串行版直接写完整全局场:
SP写当前表面压力ps。- U/V 当前场会除以
cu/cv转回自然风。 ucov/teta/ps/q/vcov等 forcing 诊断在调用点已用f_add/factt归一化。guide_out自身不接收factt;缩放完全发生在调用点。
输出使用旧 NetCDF C 接口和 netcdf95 的 nf95_def_var/nf95_put_var 混合写法。该路径是 guide 调试诊断,不是 Mars physics 的正式 diagfi/stats/XIOS 输出。
Mars 边界
需要区分三条路径:
| 路径 | 当前源码行为 | 是否经过本模块 |
|---|---|---|
Earth + IOIPSL + ok_guide |
leapfrog.F 调 guide_main |
是 |
Mars planet_type=="mars" |
leapfrog.F 不调 guide_main |
否 |
Generic + ok_guide |
gcm.F90 读 relax.nc 并调 relaxetat0 |
否 |
因此 Mars 运行排错时,看到 ok_guide 不应直接跳到 guide_mod。先确认 planet_type、编译宏和入口调用点,再判断是 COMMON guide 还是 relax.nc 简单松弛边界。
风险和待确认
ini_anal分支中 V 风写vcov=ugui2,不是vgui2;这是 当前源码事实,设计意图待确认。correctbid保留但无活动调用,不应作为主流程依赖。guide_mod的主入口在 串行leapfrog中受 Earth/IOIPSL 条件包围;Mars 是否有旧版或本地补丁直接调用该模块,需要运行分支另行确认。