XIOS domain/axis/field setup flow
输入范围:
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\misc\wxios.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\xios_writefield.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\regular_lonlat_mod.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\geometry_mod.F90
LMDZ.MARS\libf\phymars\xios_output_mod.F90
LMDZ.MARS\libf\phymars\physiq_mod.F
Mars 运行参与度:条件经过。只有 CPP_XIOS 编译并启用 Mars physics XIOS 输出或临时 COMMON XIOS dump helper 时经过。Mars 标准 physics field 列表由 Mars XML 和 xios_output_mod 控制;COMMON 提供 context/domain helper、物理网格状态和临时 field dump 封装。
读法边界
本页回答“XIOS 的 domain、axis、field 是怎样建立并发送的”。不要把它和以下页面混淆:
- history-xios-getin-boundary:区分 history、diagfi、XIOS 和 getin 配置职责。
- wxios:逐例程说明 COMMON XIOS wrapper。
- xios_writefield:逐例程说明临时 field dump helper。
本页是流程页,重点是把 Mars XIOS 主链和 COMMON helper 放在同一时间顺序里。
总流程
CPP_XIOS build
-> COMMON gcm/mod_const_mpi 调 wxios_init("LMDZ")
-> Mars physiq_mod 首次 physics 初始化调 wxios_context_init()
-> Mars physiq_mod 把 presnivs/pseudoalt/mlayer 传给 initialize_xios_output
-> Mars xios_output_mod 设置 vertical/soil/subslope axes
-> 根据 mod_grid_phy_lmdz:grid_type 选择 wxios domain helper
-> regular_lonlat: wxios_domain_param("dom_glo")
-> unstructured: wxios_domain_param_unstructured("dom_glo")
-> Mars xios_output_mod 定义 Mars calendar/time origin/start date
-> wxios_closedef()
-> 每个 physics 输出步
-> update_xios_timestep()
-> send_xios_field generic
-> histwrite0d/1d/2d/3d_xios
-> xios_send_field(...)
可选临时 dump:
-> xios_writefield(field, name)
-> 为 name 创建 context_lmdz_<name>
-> 调 wxios_domain_param 或 wxios_domain_param_unstructured
-> xios_send_field(name, ...)
-> wxios_set_context() 恢复默认 LMDZ context
初始化入口
| 阶段 | 调用点 | 作用 |
|---|---|---|
| XIOS library init | COMMON dyn3d/gcm.F90, dyn3dpar/mod_const_mpi.F90 |
wxios_init("LMDZ") 调 xios_initialize,保存默认 context name 和 communicator。 |
| Physics context init | Mars physiq_mod.F |
wxios_context_init() 在 COMM_LMDZ_PHY 上初始化 "LMDZ" context,设为 current context,并 xios_solve_inheritance()。 |
| Mars output init | Mars xios_output_mod:initialize_xios_output |
设置 axis、domain、calendar,最后 wxios_closedef()。 |
wxios_init 本身不会定义 domain 或 field;它只是让 XIOS library 和 communicator 准备好。实际 "LMDZ" context 在 wxios_context_init 里创建。
Mars axis 定义
Mars xios_output_mod:initialize_xios_output 在 OMP MASTER 区内直接用 XIOS API 设置 axis:
| Axis id | 来源 | 单位/方向 | 用途 |
|---|---|---|---|
presnivs |
vertical_layers_mod:presnivs 经 physiq_mod 传入 |
Pa, positive down | pressure-level physics output。 |
altitude |
vertical_layers_mod:pseudoalt 经 physiq_mod 传入 |
km, positive up | altitude axis。 |
interlayer |
size(pseudoalt)+1 |
km, positive up | layer interface axis;源码未传 value。 |
soil_layers |
mlayer |
m, positive down | soil layer output。 |
subslope |
comslope_mod:def_slope_mean, nslope |
degree, positive up | subslope output。 |
grid-coordinate-state 说明 presnivs/pseudoalt 的物理侧状态来源。Mars axis 名和实际 field 使用关系由 Mars XML 与 xios_output_mod 决定。
Horizontal domain 分支
Mars xios_output_mod 用 mod_grid_phy_lmdz:grid_type 决定 domain helper:
IF (grid_type==unstructured) THEN
CALL wxios_domain_param_unstructured("dom_glo")
ELSE
CALL wxios_domain_param("dom_glo")
ENDIF
regular lon-lat domain
wxios_domain_param("dom_glo") 不直接读取 regular_lonlat_mod:lon_reg/lat_reg,而是从 geometry_mod 的当前物理列局部角度制坐标 gather:
latitude_deg / longitude_deg
-> gather 到 rlat_glo / rlon_glo
-> bcast 给 ranks
-> 构造 io_lat(nbp_lat), io_lon(nbp_lon)
-> xios_set_domain_attr_hdl(dom,
ni_glo=nbp_lon, nj_glo=nbp_lat,
ibegin=0, jbegin=jj_begin-1,
ni=nbp_lon, nj=jj_nb,
type="rectilinear",
lonvalue_1d=io_lon,
latvalue_1d=io_lat(jj_begin:jj_end))
并行时还构造 mask(nbp_lon,jj_nb),屏蔽 MPI overlap;南极特殊 rank 可重新打开最后一行。
unstructured domain
wxios_domain_param_unstructured("dom_glo") 从 geometry_mod 的弧度坐标和 cell bounds 构造 unstructured XIOS domain:
longitude/latitude/boundslon/boundslat
-> * 180/PI
-> gather_omp 到 MPI-local arrays
ind_cell_glo
-> gather_omp
-> i_index = ind_cell_glo_mpi - 1
xios_set_attr(dom,
ni_glo=klon_glo,
ibegin=ij_begin-1,
ni=ij_nb,
type="unstructured",
nvertex=nvertex,
lonvalue_1d=lon_mpi,
latvalue_1d=lat_mpi,
bounds_lon_1d=transpose(boundslon_mpi),
bounds_lat_1d=transpose(boundslat_mpi),
i_index=ind_cell_glo_mpi-1)
这里的 0-based i_index 是 XIOS 约定;COMMON ind_cell_glo 是 Fortran 1-based。
Calendar 和 context close
Mars xios_output_mod 不调用 wxios_set_cal。它直接定义 Mars physics 的 user-defined calendar:
timestep%second=1。day_length=nint(daysec/dtphys)。month_lengths=[61,66,66,65,60,54,50,46,47,47,51,56]。time_origin=xios_date(1,1,1,0,0,0)。start_date=time_origin。
随后 wxios_closedef() 调用 xios_close_context_definition(),表示 context 定义阶段结束,后续进入发送阶段。
Mars field 发送
Mars xios_output_mod 提供 send_xios_field generic:
| 入口 | 输入 | 发送方式 |
|---|---|---|
histwrite0d_xios |
scalar | OMP MASTER 直接 xios_send_field(field_name, field)。 |
histwrite1d_xios |
field(:) |
OMP MASTER 直接发送 1D array。 |
histwrite2d_xios |
field(klon) |
校验 SIZE(field)==dimphy:klon,Gather_omp 到 klon_mpi,grid1Dto2D_mpi 到 nbp_lon,jj_nb 后发送。 |
histwrite3d_xios |
field(klon,nz) |
校验第一维 dimphy:klon,Gather_omp 到 klon_mpi,nz,grid1Dto2D_mpi 到 nbp_lon,jj_nb,nz 后发送。 |
发送前 update_xios_timestep 会:
set_xios_context()
OMP MASTER:
time_it = time_it + 1
xios_update_calendar(time_it)
xios_is_active_field(field_id) 在 master 线程查询 xios_field_is_active,再用 bcast_omp 给其它线程。字段是否 active 取决于 XIOS XML/output 配置。
临时 xios_writefield 分支
xios_writefield.F90 是 COMMON 提供的临时 field dump helper,不是 Mars 标准 physics 输出主线。它的流程和 Mars xios_output_mod 不同:
| 项目 | Mars xios_output_mod |
COMMON xios_writefield |
|---|---|---|
| Context | 默认 "LMDZ" |
每个字段名创建 context_lmdz_<name>。 |
| Domain id | "dom_glo" |
regular "domain",unstructured "domaingroup",可额外 regular_domain。 |
| Axis | Mars 明确定义 presnivs/altitude/soil_layers/... |
3D 临时 axis id 为 "axis",value 为 1..nz。 |
| Field 来源 | Mars XML 和 send_xios_field 调用 |
调用方传入 name_in 和 field array。 |
| 时间 | time_it 统一计数 |
每个字段 FieldIt(id) 独立计数。 |
如果 unstructured grid 设置了非零 xios_writefield_nlon/nlat,xios_writefield 会创建 regular_domain,让 XIOS 对 native unstructured field 做 rectilinear 插值输出。
regular_lonlat_mod 的角色
regular_lonlat_mod 保存全局 regular lon-lat 坐标轴:
lon_reg(nbp_lon)、lat_reg(nbp_lat)。boundslon_reg(nbp_lon,2)、boundslat_reg(nbp_lat,2)。
Mars iniwrite/iniwritesoil 使用这些数组写 diagfi/soil 输出坐标轴。XIOS regular domain 当前主要通过 wxios_domain_param 从 geometry_mod 的局部物理列坐标重构 io_lon/io_lat,而不是直接读取 lon_reg/lat_reg。因此:
regular_lonlat_mod是 Mars non-XIOS/legacy 输出坐标轴和全局 regular state。geometry_mod是 XIOS domain helper 实际使用的局部 geometry state。- 两者都由
inigeomphy_mod初始化,必须保持一致。
复现和排查顺序
- 确认构建有
CPP_XIOS,且不是XIOS1。 - 确认
wxios_init("LMDZ")在 GCM 初始化阶段被调用。 - 确认 Mars
physiq_mod首次 physics 初始化调用wxios_context_init。 - 确认
initialize_xios_output得到presnivs/pseudoalt/mlayer并设置 axes。 - 根据
grid_type判断dom_glo应走 regular 还是 unstructured helper。 - 若 regular 输出错位,检查
geometry_mod:latitude_deg/longitude_deg、jj_begin/jj_nb和 MPI mask。 - 若 unstructured 输出错位,检查
ind_cell_glo是否正确减 1 给 XIOSi_index,以及boundslon/boundslat维度与nvertex。 - 若字段没有输出,先查 XML/
xios_is_active_field,再查send_xios_field是否被调用。 - 若使用
xios_writefield临时 dump,确认 field 第一维是klon_omp,并确认是否设置了xios_writefield_nlon/nlat。
待确认
- 本地没有运行
CPP_XIOS案例,domain mask、unstructuredi_index和 XIOS interpolation 行为仍需运行验证。 wxios中THREADPRIVATE(g_comm,g_cts_name,g_ctx)的g_cts_name拼写风险可能影响多线程 context name 行为。- Mars XML 中每个 field 对
dom_glo、axis 和 active 状态的最终配置不属于 COMMON 源码,需结合 Marsdeftank/xios/*.xml或运行配置确认。