xios_output_mod.F90
路径
LMDZ.MARS\libf\phymars\xios_output_mod.F90
所属目录 / 模块
libf/phymars
文件定位
xios_output_mod.F90 是 LMDZ.MARS 物理包到 XIOS 输出库的 Fortran 封装层。它在 CPP_XIOS 编译期开关下提供 XIOS 上下文初始化、时间步推进、0D/1D/2D/3D 字段发送、字段活跃性查询和上下文 finalize;无 CPP_XIOS 时,源码中实际可见的模块内容只剩 time_it 与 context_id 等静态定义,XIOS 例程不会进入编译。
运行时该模块与 deftank/xios/*.xml 配置配合:context_id="LMDZ" 对应 context_pcm_physics.xml,initialize_xios_output 设置垂直轴、土壤轴、坡面轴、水平 domain、用户自定义日历和起始时间,然后调用 wxios_closedef 关闭定义阶段;后续 update_xios_timestep 每个物理时间步推进 XIOS calendar,send_xios_field 泛型接口把具体字段发送给 XIOS。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
xios_output_mod |
module |
1 |
XIOS 输出封装模块。 |
time_it |
private saved integer |
5 |
记录自启动以来已调用 XIOS 时间推进的次数。 |
context_id |
parameter character |
8 |
XIOS context 名称,固定为 "LMDZ"。 |
send_xios_field |
generic interface |
12 |
分派到 0D/1D/2D/3D 的 histwrite*_xios。 |
initialize_xios_output |
subroutine |
19 |
初始化 XIOS 轴、domain、日历、起始时间并关闭定义阶段。 |
finalize_xios_output |
subroutine |
155 |
调用 xios_context_finalize 关闭上下文。 |
update_xios_timestep |
subroutine |
168 |
设置当前上下文,递增 time_it 并更新 XIOS calendar。 |
set_xios_context |
subroutine |
180 |
获取 context_id 对应句柄并设置为当前上下文。 |
histwrite0d_xios |
subroutine |
193 |
向 XIOS 发送标量 real 字段。 |
histwrite1d_xios |
subroutine |
212 |
向 XIOS 发送一维 real 字段;dimens 参数未在源码中使用。 |
histwrite2d_xios |
subroutine |
231 |
校验物理网格长度,gather 到 MPI 子域二维数组并发送。 |
histwrite3d_xios |
subroutine |
266 |
校验第一维等于 klon,gather 到三维经纬-层数组并发送。 |
xios_is_active_field |
function |
309 |
查询 XIOS 中某 field 是否激活,并通过 OpenMP 广播结果。 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
xios / XIOS |
多个 XIOS API |
设置轴、日历、上下文,发送字段和查询 field 活跃性。 |
- |
wxios |
wxios_domain_param, wxios_domain_param_unstructured, wxios_closedef |
初始化结构化或非结构 domain,并关闭 XIOS 定义阶段。 |
- |
mod_phys_lmdz_para |
jj_nb, jj_begin, jj_end, ii_begin, ii_end, mpi_size, mpi_rank, klon_mpi, is_sequential, is_south_pole_dyn, gather_omp, grid1Dto2D_mpi |
MPI/OMP 子域信息、字段收集和 1D 到 2D/3D 子域重排。 |
初始化中部分变量只出现在注释代码和调试输出中。 |
mod_grid_phy_lmdz |
nbp_lon, nbp_lat, klon_glo, grid_type, unstructured |
全局维度和结构/非结构网格分支。 |
- |
regular_lonlat_mod |
lon_reg, lat_reg |
旧版显式 domain 初始化代码保留在注释中;当前实际调用封装的 wxios_domain_param。 |
是否仍需保留导入待确认。 |
comslope_mod |
nslope, def_slope_mean |
设置 subslope 轴。 |
- |
dimphy |
klon, klev |
2D/3D 发送前校验物理网格维度。 |
klev 在当前 3D 例程中未直接使用。 |
print_control_mod |
lunout, prt_level |
输出 XIOS 调试日志。 |
- |
mod_phys_lmdz_omp_transfert |
bcast_omp |
广播 xios_is_active_field 查询结果。 |
- |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
xios_set_axis_attr |
XIOS |
initialize_xios_output |
设置 presnivs、altitude、interlayer、soil_layers、subslope 轴属性。 |
wxios_domain_param / wxios_domain_param_unstructured |
wxios |
initialize_xios_output |
根据网格类型初始化 dom_glo domain。 |
xios_define_calendar |
XIOS |
initialize_xios_output |
定义 user_defined calendar、时间步、sol 长和 12 个月长度。 |
xios_set_time_origin, xios_set_start_date |
XIOS |
initialize_xios_output |
设置时间原点和本次模拟起始时间。 |
wxios_closedef |
wxios |
initialize_xios_output |
关闭 XIOS 定义阶段,之后可发送字段。 |
xios_update_calendar |
XIOS |
update_xios_timestep |
按 time_it 推进 XIOS 时间。 |
xios_send_field |
XIOS |
histwrite*_xios |
发送 0D/1D/2D/3D 字段。 |
xios_field_is_active |
XIOS |
xios_is_active_field |
查询 field 是否被输出配置激活。 |
abort_physic |
外部错误处理 |
2D/3D 尺寸校验失败 |
输入字段第一维不等于 klon 时中止。 |
输入
| 输入 |
来源 |
类型 / 维度 |
单位 |
含义 |
day |
initialize_xios_output 调用方 |
real |
sol |
从参考 Ls=0 起的已过 sol 数;当前源码未用于 start_date 计算。 |
timeofday |
调用方 |
real |
sol fraction |
UT 日内比例;当前源码未用于 start_date 计算。 |
dtphys |
调用方 |
real |
seconds |
物理时间步;用于 XIOS calendar 的 day_length=nint(daysec/dtphys)。 |
daysec |
调用方 |
real |
seconds |
标准 sol 长度。 |
presnivs(:) |
调用方 |
real array |
Pa |
近似层压,写入 presnivs 轴。 |
pseudoalt(:) |
调用方 |
real array |
km |
近似高度,写入 altitude 和 interlayer 轴长度。 |
mlayer(:) |
调用方 |
real array |
m |
土壤层深度,写入 soil_layers 轴。 |
field_name |
histwrite*_xios 调用方 |
character |
- |
XIOS field id。 |
field |
histwrite*_xios 调用方 |
real scalar/vector/array |
variable-dependent |
待发送到 XIOS 的诊断值。 |
输出
| 输出 |
去向 |
类型 / 维度 |
单位 |
含义 |
XIOS context LMDZ |
XIOS runtime |
context |
- |
物理输出上下文。 |
dom_glo |
XIOS domain |
structured/unstructured domain |
degrees |
物理水平网格 domain。 |
presnivs, altitude, interlayer, soil_layers, subslope |
XIOS axes |
axis metadata |
mixed |
XIOS XML 中 field/grid 使用的轴。 |
field_name 字段 |
XIOS runtime / NetCDF files |
0D/1D/2D/3D |
variable-dependent |
由 XML file_def 决定是否写入具体 NetCDF 文件。 |
共享状态与副作用
time_it 是模块私有 SAVE 状态,由 OpenMP master 在 update_xios_timestep 中递增。
- 多数 XIOS API 调用包在
!$OMP MASTER 中,调用前后常用 !$OMP BARRIER 同步。
initialize_xios_output 会关闭 XIOS 定义阶段;之后再改 XML 定义或动态添加轴/field 不属于该例程覆盖范围。
histwrite2d_xios 和 histwrite3d_xios 会把物理网格字段通过 Gather_omp 与 grid1Dto2D_mpi 转为当前 MPI 子域的二维/三维数组再发送。
xios_is_active_field 的结果由 master 查询后用 bcast_omp 广播;但当前 write_output_mod 中活跃性检查被注释,实际发送路径将 is_active 强制为 .true.。
核心逻辑
CPP_XIOS 编译时定义 send_xios_field 泛型接口,按实参秩分派到 0D/1D/2D/3D 发送例程。
initialize_xios_output 在 master 线程设置所有垂直/土壤/坡面轴属性。
- 根据
grid_type 调用 wxios_domain_param_unstructured("dom_glo") 或 wxios_domain_param("dom_glo") 初始化水平 domain。
- master 定义 user-defined calendar:XIOS 时间步为 1 秒,
day_length=nint(daysec/dtphys),月份长度硬编码为 12 个 Mars 月长度。
- 设置
time_origin=xios_date(1,1,1,0,0,0) 和同样的 start_date,然后 wxios_closedef。
- 每个 XIOS 时间步调用
update_xios_timestep:先 set_xios_context,再递增 time_it 并 xios_update_calendar(time_it)。
- 写字段时,0D/1D 直接
xios_send_field;2D/3D 先校验第一维等于 klon,再 gather/recast 后发送。
- 结束时调用
finalize_xios_output 执行 xios_context_finalize。
伪代码
initialize_xios_output(day, timeofday, dtphys, daysec, presnivs, pseudoalt, mlayer):
master:
set XIOS axes presnivs, altitude, interlayer, soil_layers, subslope
barrier
if grid_type == unstructured:
wxios_domain_param_unstructured("dom_glo")
else:
wxios_domain_param("dom_glo")
master:
define user calendar using day_length = nint(daysec / dtphys)
set time_origin and start_date
wxios_closedef()
barrier
update_xios_timestep():
set_xios_context()
master:
time_it += 1
xios_update_calendar(time_it)
send_xios_field(field_name, field):
if field is 0D or 1D:
master sends directly
if field is 2D or 3D:
require first dimension == klon
Gather_omp(field)
master grid1Dto2D_mpi(...)
master xios_send_field(...)
参与的主题流程
| 主题 |
参与方式 |
| XIOS 输出 |
提供 Fortran 到 XIOS runtime 的初始化、时间推进、字段发送和关闭接口。 |
| 通用输出封装 |
write_output_mod 在 CPP_XIOS 下调用 send_xios_field。 |
| 物理主循环 |
physiq 首次调用时初始化 XIOS,每步更新 calendar,末尾发送控制表和轴相关字段。 |
| 配置系统 |
与 xios-config 中的 XML context、field_def 和 file_def 配套。 |
写法特点
- 所有实际 XIOS 例程都在
#ifdef CPP_XIOS 内;编译配置决定该模块是否提供可调用输出接口。
context_id 硬编码为 "LMDZ",必须与 XML context id 保持一致。
day 和 timeofday 当前没有参与 start_date 计算;源码注释保留了“减去 dtphys”的说明,但实际 start_date=time_origin。
histwrite1d_xios 的 dimens 参数未使用,1D 实参直接发送给 XIOS。
- 2D/3D 字段发送前只检查第一维
klon,不在本例程内验证 XML field 的 grid_ref 是否匹配。
复现要点
- 必须使用
CPP_XIOS 编译,并保证 XIOS XML 中存在 context id LMDZ。
initialize_xios_output 必须在任何 send_xios_field 之前执行,且必须完成 wxios_closedef。
- 每个实际物理输出步需要先调用
update_xios_timestep,否则 XIOS calendar 与字段时间轴会错位。
dtphys 和 daysec 若不是整数,源码只打印 warning;day_length 仍取 nint(daysec/dtphys)。
- 2D/3D 发送字段第一维必须等于
dimphy:klon,否则 abort_physic 中止。
- 非结构网格走
wxios_domain_param_unstructured,与结构化经纬 domain 的 XML/后处理假设不同。
待确认
day、timeofday 在接口中传入但当前未用于 start_date;是否为历史遗留或待恢复逻辑需结合 XIOS 时间轴测试确认。
regular_lonlat_mod、若干 MPI 子域变量在当前实代码中主要出现在注释或调试路径,是否仍需导入待确认。
write_output_mod 当前注释掉 xios_is_active_field 检查并强制发送;若恢复活跃性过滤,XIOS 输出量和性能都会改变。
相关页面