guide 输入场读取

guide_readguide_read2D 负责从 NetCDF 文件读取 nudging 输入场。两者共享相同的文件打开和初始化逻辑,区别在于空间维度:guide_read 读取完整三维场 (iip1, jjp1, nlevnc)guide_read2D 读取经度-气压二维切片 (jjp1, nlevnc) 后沿 iip1 广播。串行版 guide_mod 和并行版 guide_p_mod 在读取逻辑上几乎相同,但并行版额外支持 guide_plevs=2 逐格点气压场读取。

调用链

guide_main 在每个读取步调用 guide_read(step_rea)guide_read2D(step_rea),由 guide_2D 开关选择。guide_init 首次执行时通过 guide_read(1)guide_read2D(1) 加载第一个时间片,随后将 Xnat2 复制到 Xnat1 作为初始对。guide_main 中每次读取前先执行 Xnat1 = Xnat2(仅局部 jjb:jje 对并行版),然后读入新的 Xnat2

文件结构与 NetCDF 变量映射

物理量 文件名 NetCDF 变量 水平维度 垂直维度
u u.nc UWND (iip1, jjp1) nlevnc
v v.nc VWND (iip1, jjm) nlevnc
T T.nc AIR (iip1, jjp1) nlevnc
Q/hur hur.nc RH (iip1, jjp1) nlevnc
Ps ps.nc SP (iip1, jjp1) 1(第 3 维 = time)
AP/BP apbp.nc AP, BP 1D (nlevnc)
P P.nc PRES (iip1, jjp1) nlevnc

Ps 的 start/count 特殊处理:start(3)=timestep, start(4)=0, count(2)=jjp1, count(3)=1, count(4)=0,即从第 3 维读取单个时间步。其余三维场使用 start(4)=timestep, count(4)=1

首次调用初始化

两个 read 子例程都用 first SAVE flag 控制首次调用。首次调用完成所有文件打开、变量 ID 查询和垂直坐标系数读取。文件打开顺序有依赖:需要先确定 ncidpl(用于读取 LEVEL/PRESSURE 或 AP/BP 的文件 ID),按 guide_plevs 值或变量优先级依次尝试 apbp.ncP.ncu.ncv.ncT.nchur.nc,取第一个成功打开的作为 ncidpl

垂直坐标系数

guide_plevs=0(纯气压层):从 NetCDF 的 LEVELPRESSURE 维变量读取 apnc,乘以 100 转 Pa,bpnc 全部置零。guide_plevs=1(混合层):从 apbp.nc 读取 APBP 变量到 apncbpncguide_plevs=2(逐格点气压):不在此处读取系数,气压由 P.ncpnat 三维场直接提供。

NC_DOUBLE 精度守卫

所有 NF_GET_VARA_* 调用用 #ifdef NC_DOUBLE 条件编译选择 NF_GET_VARA_DOUBLENF_GET_VARA_REAL。这是 LMDZ 全局精度抽象:编译时 CPP_REAL8 宏定义 NC_DOUBLE,使所有 I/O 使用双精度。guide 模块不检查返回值 status,依赖 NetCDF 运行时错误处理。

guide_read 3D 模式

串行版对每个启用的变量读取完整 (iip1, jjp1, nlevnc)(iip1, jjm, nlevnc)(v)数组。读取后若 invert_y=.TRUE. 则调用 invert_lat 翻转南北方向。invert_latdyn3d_common/invert_lat.F90 中的独立子例程,用临时数组 f_auxfield(:,j,:) 映射到 field(:,ysize+1-j,:)

并行版读取逻辑与串行版完全相同——并行版在 I/O 阶段不做域分解,每个进程读取完整场(所有进程都执行 NF_GET_VARA_*)。域分解发生在后续 guide_interpguide_main 中通过 jjb_u:jje_u / jjb_v:jje_v 切片访问。

并行版额外:guide_plevs=2

并行版 guide_readguide_plevs=2 时额外读取 P.ncPRES 变量到 pnat2(iip1,jjp1,nlevnc)。串行版无此路径。

guide_read2D 2D 模式

guide_2D=.TRUE. 时使用。读取经度-气压二维切片 (jjp1, nlevnc)(jjm, nlevnc)(v),然后通过 DO i=1,iip1; Xnat2(i,:,:)=zu(:,:) 广播到所有经度。Ps 读取为 1D (jjp1) 后广播到 (iip1, jjp1)

并行版在 guide_plevs=2 时也支持 2D 模式读取 P.ncPRES 变量为 (jjp1, nlevnc) 后广播到三维 pnat2

时间步管理

guide_mainiguide_read 控制读取时机:

tau 的整数部分判断是否到达新时间片(reste = tau - AINT(tau),若 reste==0 则读取),小数部分作为两帧间的线性插值权重。itau_test 防止同一 itau 重复读取(double-pass 检测,若检测到则 stop)。

错误处理

文件打开和变量查询失败时调用 abort_gcm(modname, abort_message, 1) 终止。错误信息用法语(如 'Guide: probleme -> pas de fichier u.nc')。不检查 NF_GET_VARA_* 的返回 status,依赖 NetCDF 运行时错误。

串并行差异

特性 串行 guide_read/2D 并行 guide_read/2D
I/O 分布 单进程读取全部 所有进程读取全部(无域分解 I/O)
guide_plevs=2 不支持 支持 P.nc 逐格点气压
文件打开条件 guide_modele 布尔 guide_plevs 整数 0/1/2
ncidpl 探测 按变量优先级 增加 P.nc 路径
psnat 条件 guide_P .OR. guide_modele guide_P .OR. guide_plevs==1
pnat 不存在 guide_plevs=2
invert_lat 全局 全局(同串行,I/O 不分解)

NetCDF95 在 guide 中的角色

netcdf95 模块(libf/misc/netcdf95.F90)仅在 guide_out 中使用 nf95_def_varnf95_put_var 写 alpha_T/alpha_Q 诊断变量。guide_read / guide_read2D 不使用 netcdf95,直接调用 NetCDF-3 C 接口 NF_GET_VARA_DOUBLE/REALhandle_err_mlibf/misc/handle_err_m.F90)是 netcdf95 内部错误处理模块,将 NetCDF 错误码转为 nf90_strerror 消息后调用 abort_physic,guide 读取路径不经过它。

Mars 运行参与度

Mars 运行对本页是接口兼容和条件边界。guide_read/guide_read2D 的活动调用来自 guide_main,而 guide_main 在串行/并行 leapfrog* 中受 CPP_IOIPSL + planet_type=="earth" 条件包围。Mars/generic 初始化中的 relaxetat0("relax.nc") 是独立路径,不经过 guide_read。guide 读取纯用 NetCDF 接口,不依赖 IOIPSL 历史/重启框架,但调用点本身在 当前源码中受 IOIPSL 宏保护。

依赖表

模块/文件 用途
netcdf (Fortran) nf90_nowrite, nf90_open, nf90_inq_varid, nf90_close
netcdf.inc (C 接口) NF_GET_VARA_DOUBLE/REAL, NF_INQ_DIMID/LEN, NF_NOERR
netcdf95 guide_out 使用 nf95_def_var, nf95_put_var
invert_lat.F90 南北方向翻转
getparam ini_getparam/getpar/fin_getparam 参数读取
dimensions.h / paramet.h iip1, jjp1, jjm, ip1jmp1, ip1jm, llm
control_mod day_step(频率编码)
parallel_lmdz(仅并行版) ij_begin/end, jj_begin/end(后处理切片用,I/O 不用)

相关页面