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 是怎样建立并发送的”。不要把它和以下页面混淆:

本页是流程页,重点是把 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_outputOMP MASTER 区内直接用 XIOS API 设置 axis:

Axis id 来源 单位/方向 用途
presnivs vertical_layers_mod:presnivsphysiq_mod 传入 Pa, positive down pressure-level physics output。
altitude vertical_layers_mod:pseudoaltphysiq_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_modmod_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:

随后 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:klonGather_ompklon_mpigrid1Dto2D_mpinbp_lon,jj_nb 后发送。
histwrite3d_xios field(klon,nz) 校验第一维 dimphy:klonGather_ompklon_mpi,nzgrid1Dto2D_mpinbp_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/nlatxios_writefield 会创建 regular_domain,让 XIOS 对 native unstructured field 做 rectilinear 插值输出。

regular_lonlat_mod 的角色

regular_lonlat_mod 保存全局 regular lon-lat 坐标轴:

Mars iniwrite/iniwritesoil 使用这些数组写 diagfi/soil 输出坐标轴。XIOS regular domain 当前主要通过 wxios_domain_paramgeometry_mod 的局部物理列坐标重构 io_lon/io_lat,而不是直接读取 lon_reg/lat_reg。因此:

复现和排查顺序

  1. 确认构建有 CPP_XIOS,且不是 XIOS1
  2. 确认 wxios_init("LMDZ") 在 GCM 初始化阶段被调用。
  3. 确认 Mars physiq_mod 首次 physics 初始化调用 wxios_context_init
  4. 确认 initialize_xios_output 得到 presnivs/pseudoalt/mlayer 并设置 axes。
  5. 根据 grid_type 判断 dom_glo 应走 regular 还是 unstructured helper。
  6. 若 regular 输出错位,检查 geometry_mod:latitude_deg/longitude_degjj_begin/jj_nb 和 MPI mask。
  7. 若 unstructured 输出错位,检查 ind_cell_glo 是否正确减 1 给 XIOS i_index,以及 boundslon/boundslat 维度与 nvertex
  8. 若字段没有输出,先查 XML/xios_is_active_field,再查 send_xios_field 是否被调用。
  9. 若使用 xios_writefield 临时 dump,确认 field 第一维是 klon_omp,并确认是否设置了 xios_writefield_nlon/nlat

待确认

相关页面