guide 压力层插值和 nudging 系数
源码范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3d\guide_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\guide_p_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\misc\pres2lev_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\misc\q_sat.F
Mars 运行参与度:接口兼容 + 条件边界。只有进入 guide_main 时才会经过本页逻辑;串行/并行 leapfrog* 中的 guide_main 调用受 CPP_IOIPSL + planet_type=="earth" 条件包围。Mars/generic ok_guide 初始化路径调用 relaxetat0("relax.nc"),不经过本页插值链。
调用时机
guide_main 首次进入时调用 guide_init,随后计算各变量的 nudging 系数:
factt = dtvr * iperiod / daysec
tau2alpha(v/u/T/P/Q, factt, tau_min_X, tau_max_X, alpha_X)
若 ini_anal=.TRUE.,首次调用会立刻 guide_interp(ps,teta),然后把 guide 目标场写回初始动力状态。常规运行中,只有 MOD(itau,iguide_int)==0 时才重新执行 guide_interp;两帧 guide 输入之间再用 tau=reste 做时间线性插值,后续叠加见 guide forcing 叠加到动力状态。
guide_interp 总流程
guide_interp(psi,teta) 把读入的 guide 自然变量和压力层转换到 LMDZ 动力层目标场:
输入 ps/teta
-> 构造 guide 输入压力层 plnc1/plnc2
-> 计算模型层压力 pls,以及 U/V staggered 压力 plunc/plvnc
-> 对 T/Q/u/v 调 pres2lev
-> 把自然风转成 covariant 风,把温度转为位温
-> 可选把相对湿度转为比湿
串行版全局处理 (iip1,jjp1) 或 (iip1,jjm);并行版只处理当前本地 jjb_u:jje_u 和 jjb_v:jje_v,并在需要跨纬向边界的压力平均前用 Register_SwapFieldHallo/SendRequest/WaitRequest 补 halo。
压力坐标构造
串行 guide_mod 用 guide_modele 二选一:
| 分支 | guide 输入压力 plnc |
|---|---|
guide_modele=.TRUE. |
apnc(l)+bpnc(l)*psnat(i,j) |
guide_modele=.FALSE. |
apnc(l) |
并行 guide_p_mod 用 guide_plevs 三选一:
guide_plevs |
含义 | guide 输入压力 |
|---|---|---|
| 0 | 纯气压层 | apnc(l) |
| 1 | 混合层 | apnc(l)+bpnc(l)*psnat(i,j) |
| 2 | 逐格点气压 | pnat(i,j,l) |
模型层压力先由当前 ps/teta 推导。串行版调用 pression 和 exner_hyb/exner_milieu,由 Exner 函数反推出层中心压力 pls=preff*(pk/cpp)**(1/kappa);并行版 guide_plevs=1 直接使用 (ap(l)+ap(l+1))/2 + ps*(bp(l)+bp(l+1))/2,其他分支调用 pression_p 与 exner_hyb_p/exner_milieu_p。
U/V staggered 压力来自质量平均:
- 标量网格压力
pls乘面积得pext。 - 串行版直接
massbar(pext,pbarx,pbary)。 - 并行版先对
pext做 swap/halo,再massbar_p(pext,pbarx,pbary)。 plunc=pbarx/aireu,plvnc=pbary/airev。
pres2lev 插值
pres2lev(varo,varn,lmo,lmn,po,pn,ni,nj,ok_invertp) 是 COMMON misc/pres2lev_mod.F90 中的线性垂直插值:
- 若
ok_invertp为真,先把旧层压力和变量顺序倒置。 - 对每个新层压力
pn(k,ln)找到旧层压力区间。 - 若新层在旧层范围之外,取最顶或最低旧层值。
- 否则按压力线性系数插值。
guide_interp 对各变量使用不同目标压力:
| 变量 | 输入变量 | 目标压力 | 输出 |
|---|---|---|---|
| U | unat1/2 |
plunc |
ugui1/2 = interpolated * cu |
| V | vnat1/2 |
plvnc |
vgui1/2 = interpolated * cv |
| T | tnat1/2 |
plsnc |
tgui1/2 = T*cpp/pk,若 guide_teta 则直接用输入 |
| Q | qnat1/2 |
plsnc |
qgui1/2,若 guide_hr 再乘饱和比湿和 0.01 |
U 和标量场在经向周期端复制第一个经度;U 的南北极行强制为 0。T/Q 标量场的极点值复制自相邻有效行。V 使用 jjm 纬向网格,不含标量网格的双极点行。
湿度限制
若 guide_hr=.TRUE.,guide 输入 Q 被解释为相对湿度百分比。guide_interp 调:
q_sat(np, temp, pres, qsat)
qgui = qgui * qsat * 0.01
其中 temp=teta*pk/cpp,pres=plsnc。q_sat.F 使用水/冰两套常数,以 temp <= 273.16 切换,先计算中间 zqsat,把它限制到 0.5,再用 zqsat/(1-retv*zqsat) 得到 kg/kg 的饱和比湿。
待确认:q_sat.F 注释写压力单位为 mb,但公式常数 611.14 和 guide 传入的 plsnc 都按 Pa 路径使用。当前页面按调用源码记录,不推断历史注释意图。
tau2alpha
tau2alpha(typ,pim,pjm,factt,taumin,taumax,alpha) 把天数单位的松弛时间转换成每步 nudging 系数:
alphamin = factt / taumax
alphamax = factt / taumin
有两类分支:
| 分支 | 行为 |
|---|---|
guide_reg 或 guide_add |
先设为 alphamax;若 guide_reg,再用纬度/经度窗口的四个 tanh 因子平滑出区域权重。 |
| 默认 | 按 zoom 网格大小在 alphamin 和 alphamax 之间插值;regular grid 或弱 zoom 时取 alphamin。 |
默认分支先估算标量格点尺度 dxdys,再按 typ 得到 U 或 V staggered 尺度 dxdyu/dxdyv。首次调用用 zoom 中心 coordij(clon,clat,ilon,ilat) 得到 dxdy_min,扫描得到 dxdy_max,再计算 gamma。若不是 guide_add,最终把线性系数转为指数松弛:
alpha = 1. - exp(-alpha)
guide_add 保留 factt/tau 形式,因为后续叠加的是外部 forcing-like 场;普通 nudging 使用指数形式更接近“向目标场松弛”的权重。
串并行差异
| 环节 | 串行 guide_mod |
并行 guide_p_mod |
|---|---|---|
| 输入压力坐标 | guide_modele 布尔 |
guide_plevs=0/1/2 |
| 工作范围 | 全局数组 | jjb_u:jje_u、jjb_v:jje_v 本地段 |
| 模型压力 | pression + exner_* |
guide_plevs=1 直接混合层压力;其他分支 pression_p + exner_*_p |
| U/V staggered 压力 | 直接 massbar |
pext halo 后 massbar_p |
| 逐格点输入压力 | 无 | guide_plevs=2 使用 pnat1/2,V 网格前还需 halo |
| 湿度转换 | 全局 q_sat(iip1*jjp1*llm,...) |
本地 q_sat(iip1*jjn_u*llm,...) |
correctbid
correctbid(iim,nl,x) 在串行和并行 guide 模块尾部都存在:如果 abs(x(i,l))>1.e10,用左右相邻点均值替换并打印 correction。源码搜索未找到活动调用,因此它是保留的局部修补 helper,不应写成 guide 主路径的一部分。
复现要点
- 先确认
guide_2D/guide_plevs/guide_modele/guide_hr/guide_teta,这些开关决定输入场解释。 - 对插值错误,先检查
invert_p和 guide 输入压力层顺序,再查pres2lev的范围外取边界值逻辑。 - 对并行 U/V 差异,检查
pext/psnat/pnathalo 是否覆盖了本地 V 网格需要的相邻纬向行。 - 对 nudging 太强或太弱,先算
factt=dtvr*iperiod/daysec,再看tau_min/max和guide_reg/guide_add分支。 - 对湿度场,区分 guide 输入是相对湿度百分比还是比湿;
guide_hr会把百分比乘以q_sat*0.01。