wxios.F90
源码路径:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\misc\wxios.F90
Mars 运行参与度:条件经过。CPP_XIOS 构建中,COMMON gcm/并行初始化会调用 wxios_init,Mars physiq_mod 会调用 wxios_context_init,Mars xios_output_mod 通过 wxios_domain_param 或 wxios_domain_param_unstructured 初始化 horizontal domain,并用 wxios_closedef 关闭 context definition。未启用 CPP_XIOS 时,本文件主体不提供 wxios 模块能力。
文件职责
wxios 是 COMMON 对 XIOS v2 的薄封装,负责:
- 初始化 XIOS 并保存默认 context 名和 communicator。
- 创建或恢复当前 XIOS context。
- 设置 calendar、time origin、start date 和 timestep。
- 根据 COMMON 物理网格状态填充 regular lon-lat 或 unstructured XIOS domain。
- 动态添加 vertical axis、file、field、field-to-file 关系。
- 在 abort 或结束阶段关闭 XIOS context/finalize。
它不定义 Mars physics 变量清单。Mars 变量、axis 语义和实际发送由 Mars xios_output_mod.F90 与 XML 文件控制;wxios 只提供 context/domain/file/field 操作工具。
编译边界和版本约束
整个文件位于:
#ifdef CPP_XIOS
MODULE wxios
...
END MODULE wxios
#endif文件还显式拒绝 XIOS v1:
#ifdef XIOS1
#error "XIOS v1 no longer supported, use XIOS v2."
#endif因此依赖本模块的调用点必须处在 XIOS 构建条件中,或由构建系统保证 CPP_XIOS 已启用。
模块状态
| 状态 | 类型 | 并行属性 | 含义 |
|---|---|---|---|
g_comm |
integer save | THREADPRIVATE 指令中列出 |
xios_initialize 返回的 communicator。 |
g_ctx_name |
character save, default "LMDZ" |
见待确认 | 默认 context name,wxios_init 写入,wxios_context_init/wxios_set_context 读取。 |
g_ctx |
xios_context save |
THREADPRIVATE 指令中列出 |
保存 xios_get_handle(g_ctx_name,...) 得到的 context handle。 |
g_flag_xml |
logical save | THREADPRIVATE |
最近一次 field 是否由 XML 预定义。 |
g_field_name |
character, default "nofield" |
THREADPRIVATE |
最近一次处理的 field 名,避免重复创建。 |
missing_val_omp, missing_val |
real | missing_val 为 THREADPRIVATE |
当前文件内未见实质使用。 |
源码 OpenMP 指令写为 THREADPRIVATE(g_comm,g_cts_name,g_ctx),其中 g_cts_name 与声明的 g_ctx_name 不一致。页面按源码事实记录:g_ctx_name 是否真正 threadprivate 需要编译器/OpenMP 诊断或运行验证确认。
例程清单
| 例程 | 行为 |
|---|---|
reformadate(odate, ndate) |
把 36day、1hr、1mth 这类 IOIPSL 风格片段写入 xios_duration 的 day/hour/month。 |
reformaop(op) |
把 inst(X)、once、t_max(X)、t_min(X) 映射到 XIOS instant/once/maximum/minimum;其他默认 average。 |
wxios_init(xios_ctx_name, locom, outcom, type_ocean) |
调用 xios_initialize,可传 local communicator,可返回 XIOS communicator,并保存 g_comm/g_ctx_name。 |
wxios_context_init() |
在 COMM_LMDZ_PHY 上初始化 g_ctx_name context,设为 current context,并调用 xios_solve_inheritance。 |
wxios_set_context() |
重新获取并激活 g_ctx_name context。 |
wxios_set_cal(...) |
根据 earth_360d/earth_365d/gregorian 设置 calendar、origin/start date 和 timestep;其他 calendar abort。 |
wxios_set_timestep(ts) |
以 mdtime%timestep=ts 形式设置 XIOS timestep。 |
wxios_domain_param(dom_id, flip_coordinates) |
为 regular lon-lat domain 写入 ni_glo/nj_glo、local j-slice、lon/lat 1D 值和 MPI overlap mask。 |
wxios_domain_param_unstructured(dom_id, flip_coordinates) |
为 unstructured domaingroup 写入 lon/lat、cell bounds、i_index 和 nvertex。 |
wxios_add_vaxis(axis_id, axis_size, axis_value) |
设置 XIOS axis n_glo/value,并检查 axis 是否有效。 |
wxios_add_file(fname, ffreq, flvl) |
如果 XML 中没有该 file,则在 defile 下添加 file fname,输出名为 "X"//fname,并设置频率和 level;若 XML 已定义则只启用。 |
wxios_add_field(fieldname, fieldgroup, fieldlongname, fieldunit) |
向 field group 添加 field,设置 standard name、unit 和 default fill value。 |
wxios_add_field_to_file(...) |
按 2D/3D 选择 field group,创建或启用 field,把 field 加到 file,并设置 operation、freq_op、level、axis。 |
wxios_closedef() |
调用 xios_close_context_definition()。 |
wxios_close() |
依次调用 xios_context_finalize() 和 xios_finalize()。 |
初始化和关闭链
COMMON GCM/XIOS 初始化
dyn3d/gcm.F90
-> wxios_init("LMDZ")
dyn3dpar/mod_const_mpi.F90
-> wxios_init("LMDZ", outcom=COMM_LMDZ, type_ocean=...)
-> wxios_init("LMDZ", outcom=COMM_LMDZ)
-> wxios_init("LMDZ")
wxios_init 只调用 xios_initialize 并保存 context name/communicator;源码中 wxios_context_init 的调用被注释掉,context 初始化由后续 physics/Mars 路径触发。
Mars physics context 和 domain
Mars physiq_mod
-> wxios_context_init
Mars xios_output_mod:initialize_xios_output
-> xios_set_axis_attr("presnivs"/"altitude"/"interlayer"/"soil_layers"/"subslope")
-> if grid_type==unstructured:
wxios_domain_param_unstructured("dom_glo")
else:
wxios_domain_param("dom_glo")
-> xios_define_calendar(...)
-> xios_set_time_origin(...)
-> xios_set_start_date(...)
-> wxios_closedef()
Mars xios_output_mod 直接定义垂直 axis 和 Mars calendar;wxios 在这条链中主要负责 horizontal domain 与 context definition close。
关闭路径
dyn3d/abort_gcm.F
-> wxios_close()
dyn3dpar/parallel_lmdz.F90
-> wxios_close()
Mars xios_output_mod:finalize_xios_output 也会调用 XIOS context finalize,但不经 wxios_close。
regular lon-lat domain
wxios_domain_param(dom_id, flip_coordinates) 从 geometry_mod 收集当前 physics grid 的角度制经纬度:
- 可选
flip_coordinates时对latitude_deg/longitude_deg取负。 - 调用物理 transfer
gather到rlat_glo/rlon_glo,再bcast给所有 rank。 OMP MASTER从全局物理列数组构造 regular 轴:io_lat(1)=rlat_glo(1)。io_lat(nbp_lat)=rlat_glo(klon_glo)。- 中间纬度取
rlat_glo(2+(i-2)*nbp_lon)。 - 若
klon_glo==1,io_lon(1)=rlon_glo(1);否则io_lon(1:nbp_lon)=rlon_glo(2:nbp_lon+1)。
- 设置 XIOS domain:
ni_glo=nbp_lon,ibegin=0,ni=nbp_lon,type="rectilinear"。nj_glo=nbp_lat,jbegin=jj_begin-1,nj=jj_nb,data_dim=2。lonvalue_1d=io_lon,latvalue_1d=io_lat(jj_begin:jj_end)。
- 非 sequential 模式下构造
mask(nbp_lon,jj_nb),屏蔽 MPI overlap,南极特殊 rank 可重新打开最后一行。
这个 domain 是当前 MPI rank 的纬向块,和 mod_grid_phy_lmdz 的 nbp_lon/nbp_lat/klon_glo 约定一致。
unstructured domain
wxios_domain_param_unstructured(dom_id, flip_coordinates) 直接使用 geometry_mod 的局部几何状态:
| 输入状态 | 转换 | 用途 |
|---|---|---|
longitude, latitude |
*180/PI,可选取负 |
cell center lon/lat。 |
boundslon, boundslat |
*180/PI,可选取负,传入前 TRANSPOSE |
cell vertex bounds。 |
ind_cell_glo |
gather_omp 后减 1 |
XIOS i_index,Fortran 1-based 转 XIOS 0-based。 |
nvertex, klon_glo |
直接使用 | XIOS nvertex 和 global cell count。 |
ij_begin, ij_nb, klon_mpi |
物理并行状态 | 当前 rank unstructured slice。 |
该例程设置 domaingroup 属性:ni_glo=klon_glo、ibegin=ij_begin-1、ni=ij_nb、type="unstructured",并写入 bounds 与 cell index。
file/field 动态定义
wxios_add_file 和 wxios_add_field_to_file 是旧 IOIPSL/XIOS 桥接风格的动态定义 helper:
wxios_add_file(fname, ffreq, flvl):- 如果
xios_is_valid_file(fname)为假,则在 file groupdefile下添加fname,输出文件名设为"X"//fname。 ffreq经reformadate转成xios_duration。- 如果 XML 已定义
fname,则只xios_set_file_attr(fname, enabled=.TRUE.)。
- 如果
wxios_add_field_to_file(...):fdim==2使用fields_2D,否则使用fields_3D。- 若 field 已由 XML 定义并且不是上一字段,则设置
g_flag_xml=.TRUE.,后续只启用该 field。 - 若 field 未定义,则调用
wxios_add_field动态创建,再把 field 加到 file。 op经reformaop转为average/instant/once/maximum/minimum。- 3D 字段默认 axis:
fid<=6用presnivs,否则用plev;可用nam_axvert覆盖。
Mars 当前 xios_output_mod 主要使用 XML 和 xios_set_axis_attr/xios_send_field 路径;这些动态 file/field helper 是 COMMON 通用 XIOS 桥接能力。
与 xios_writefield 的关系
xios_writefield 使用本模块的三个例程:
| xios_writefield 调用 | wxios 提供的能力 |
|---|---|
wxios_domain_param("domain") |
regular lon-lat domain 属性。 |
wxios_domain_param_unstructured("domaingroup") |
unstructured domaingroup 属性。 |
wxios_set_context() |
临时 context_lmdz_<field> 发送结束后恢复默认 LMDZ context。 |
二者分工不同:xios_writefield 是按字段名创建临时 context/file/field 的 dump helper;wxios 是更底层的 context、domain、axis、file 和 field 操作封装。
复现要点
- 必须启用
CPP_XIOS,且不能使用XIOS1。 wxios_init之后还需要wxios_context_init才会在COMM_LMDZ_PHY上创建并激活 context。- Mars physics 输出 domain id 是
"dom_glo";临时xios_writefield使用"domain"或"domaingroup"。 - regular domain 的 lon/lat 来自
geometry_mod的角度制局部数组 gather 后重构,不直接读取regular_lonlat_mod:lon_reg/lat_reg。 - unstructured domain 的 bounds 使用弧度几何状态乘
180/PI,并把ind_cell_glo转成 0-basedi_index。 wxios_set_cal只接受earth_360d、earth_365d和gregorian;Marsxios_output_mod自己定义 user-defined calendar。- 动态 file 输出名会加
X前缀,即fname对应"X"//fname。
待确认
THREADPRIVATE(g_comm,g_cts_name,g_ctx)中g_cts_name疑似为g_ctx_name拼写错误;实际线程私有行为需编译器诊断或 OpenMP 运行验证。missing_val_omp/missing_val在本文件内未见使用方,是否为旧接口遗留需更大范围确认。wxios_add_field_to_file中axis_id固定长度 20,源码注释标注 dangerous;长 axis 名是否会截断需调用方约束。