write_field 调试写场接口

源码基线:LMDZ.COMMON-6.3\LMDZ.COMMON。 Mars 运行参与度:条件经过。write_field 是旧式调试 dump 工具,不是 Mars 标准 history/diagfi 主输出;但 Mars/COMMON 动力、guide、并行动力和物理侧调试路径可通过它把中间场写到独立 .nc.field 文件。

源码范围

LMDZ.COMMON-6.3\LMDZ.COMMON\libf\misc\write_field.F90
LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\write_field_phy.F90

关联边界:

LMDZ.COMMON-6.3\LMDZ.COMMON\libf\dyn3dpar\write_field_p.F90

dyn3dpar/write_field_p.F90 不在本页范围内,但它是并行动力场写入 misc/write_field 的直接 wrapper,本页在并行边界中记录其行为。

模块和符号

文件 行数 模块 主要符号 作用
misc/write_field.F90 326 write_field generic WriteField, GetFieldIndex, WriteField_gen, CreateNewField, write_field1D/2D/3D, int2str 旧式字段 dump 底座,支持 NetCDF .nc 和格式化文本 .field 两套路径。
phy_common/write_field_phy.F90 37 write_field_phy WriteField_phy 将物理列局地数组 gather 到全局物理网格,再转成 (nbp_lon, nbp_lat, ll) 并调用 WriteField
dyn3dpar/write_field_p.F90 73 write_field_p generic WriteField_p, write_field1D_p/2D_p/3D_p 并行动力 wrapper:Gather_Field 后只在 MPI_Rank==0WriteField

write_field 模块状态

write_field.F90 维护一个最多 100 个字段的本地表:

状态 类型 含义
MaxWriteField integer parameter = 100 最多登记字段数。
FieldId(MaxWriteField) integer, save 每个字段对应的 NetCDF file id。
FieldVarId(MaxWriteField) integer, save 每个字段对应的 NetCDF var id。
FieldIndex(MaxWriteField) integer, save 当前字段已写出的 iter 下标。
FieldName(MaxWriteField) character(len=255) 字段名表。
NbField integer, save = 0 已登记字段数。

源码没有显式检查 NbField > MaxWriteField,也没有检查 NetCDF status 返回值;调试复现时若文件没生成或字段过多,不能期待它像正式 I/O wrapper 那样报错。

generic WriteField 的 NetCDF 路径

WriteField 是一个 generic interface,按输入数组 rank 分派到:

分派例程 输入 维度传给 WriteField_gen
WriteField3d(name, Field(:,:,:)) 3D real (dimx, dimy, dimz)
WriteField2d(name, Field(:,:)) 2D real (dimx, dimy, 1)
WriteField1d(name, Field(:)) 1D real (dimx, 1, 1)

共同流程:

WriteField(...)
  -> shape(Field)
  -> WriteField_gen(name, Field, dimx, dimy, dimz)
       -> GetFieldIndex(name)
       -> if new name: CreateNewField(name, dimx, dimy, dimz)
       -> else: FieldIndex(index) += 1
       -> NF_PUT_VARA_DOUBLE(file_id, var_id, start=(1,1,1,iter), count=(dimx,dimy,dimz,1), Field)
       -> NF_SYNC(file_id)

首次写某个 name 时,CreateNewField 会创建 name.nc,定义 4 个维度:

维度 长度
X dimx
Y dimy
Z dimz
iter NF_UNLIMITED

变量名使用字段名本身,类型为 NF_DOUBLE,维度顺序为 (X,Y,Z,iter)。后续同名写入不会重新定义文件,而是把 iter 下标加 1 后追加一帧。

格式化 .field 路径

同一模块还定义了带下划线的 write_field1D, write_field2D, write_field3D。这组例程不是 generic WriteField 的分派目标,而是单独公开的格式化文本 dump:

例程 输出文件 格式
write_field1D(name, Field(:)) name.field 每项写 i ---> value,每 4 列换行。
write_field2D(name, Field(:,:)) name.field 每项写 (j,i) ---> value,纬向循环外加分隔线。
write_field3D(name, Field(:,:,:)) name.field 每项写 (k,j,i) ---> value,逐层/逐行分隔。

这组文本输出每次 status='replace' 打开文件,会覆盖旧文件;NetCDF generic WriteField 则按字段名维持 iter 无限维追加。

WriteField_phy 物理列桥接

phy_common/write_field_phy.F90 定义:

SUBROUTINE WriteField_phy(name, Field, ll)
  Field(klon_omp, ll)

流程:

  1. Gather(Field, New_Field) 把本地 OMP/MPI 物理列收集到 New_Field(klon_glo,ll)
  2. 进入 !$OMP MASTER 区。
  3. is_mpi_root,调用 Grid1Dto2D_glo(New_Field, Field_2D),把全局 1D 物理列转成 Field_2d(nbp_lon,nbp_lat,ll)
  4. root 调用 WriteField(name, Field_2d),走 misc/write_field.F90 的 NetCDF dump 路径。

它依赖:

use 模块 符号 作用
mod_phys_lmdz_para klon_omp, is_mpi_root, Gather 物理侧并行列数、root 判定和 gather。
mod_grid_phy_lmdz nbp_lon, nbp_lat, klon_glo, Grid1Dto2D_glo 全局物理网格尺寸和 1D 到 2D 映射。
write_field WriteField 写出最终 NetCDF dump。

WriteField_phy 不做 XIOS context、field 或正式诊断注册;它只是把物理列调试场转成全局 lon-lat 后交给旧式 dump 底座。

并行动力 wrapper 边界

dyn3dpar/write_field_p.F90 定义 generic WriteField_p。1D/2D/3D 版本都遵循:

copy local Field into New_Field
Gather_Field(New_Field, horizontal_size, vertical_size, 0)
if MPI_Rank == 0:
    WriteField(name, New_Field)

这解释了并行动力中 WriteField_p 的行为:它先把分布式动力数组 gather 到 root,再复用串行 WriteField。因此并行 debug dump 的输出文件也只由 rank 0 写,文件名仍是 name.nc

调用关系和 Mars 边界

源码搜索显示几类使用方式:

所以本页是“调试写场”页,不应替代正式输出链:history-xios-getin-boundaryrestart-ioXIOS/write_field 输出封装组页

复现检查表

目标 检查
想得到 name.nc 调用 generic WriteField(name, array)WriteField_p/WriteField_phy;首次调用会创建 name.nc,后续同名追加 iter
想得到可读文本 调用带下划线的 write_field1D/2D/3D;输出 name.field,每次覆盖。
并行动力 dump 缺文件 确认是否在 MPI_Rank==0,以及 Gather_Field 前并行分布是否匹配当前数组。
物理列 dump 形状异常 确认 klon_omp, klon_glo, nbp_lon, nbp_latGrid1Dto2D_glo 已初始化。
NetCDF 文件损坏或无变量 源码不检查 NF_* status,需外部用 NetCDF 工具验证。
字段超过 100 个 MaxWriteField=100,源码未见越界保护。

待确认

相关页面