writediagfi.F

路径

LMDZ.MARS\libf\phymars\writediagfi.F

所属目录 / 模块

libf/phymars

文件定位

writediagfi.F 定义传统物理诊断文件 diagfi.nc 的逐字段写入后端。它可以被物理包任意例程多次调用;第一次通过 diagfi.def 可选筛选变量,第一次有效变量调用时创建 diagfi.nc、定义 Time 并调用 iniwrite 写经纬度、垂直层、地表位势、网格面积等固定头信息。后续调用按 steps_per_sol/outputs_per_sol 派生的采样间隔追加时间和变量。

本例程处理四类维度码:dim=3 写经纬度-高度-时间场,dim=2 写地表经纬度-时间场,dim=1 写 1D column 的高度-时间剖面,dim=0 写时间标量。并行 GCM 路径先 gather 到全局物理网格并用 Grid1Dto2D_glo 重排,串行路径手工把物理网格复制到带冗余经度点的 (nbp_lon+1,nbp_lat) 网格。

定义的符号

符号 类型 行号 作用
writediagfi subroutine 1 diagfi.nc 创建并追加写入诊断变量。
firstcall saved logical 105 首次进入时读取 diagfi.def 并计算采样控制;其 THREADPRIVATE 声明在第 106 行。
firstnom/prevnom/lastnom saved character 83-85 识别每个物理时刻的第一个和最后一个诊断变量名;对应 THREADPRIVATE 声明在第 86 行。
zitau/ntime/nid/date saved state 79-101 管理输出步计数、NetCDF 时间索引、文件 id 和输出日期。

依赖的模块

use 模块 only 列表 用途 待确认
surfdat_h phisfi 初始化文件头时写地表位势。 -
geometry_mod cell_area 初始化文件头时写网格面积。 -
time_phylmdz_mod steps_per_sol, outputs_per_sol, day_end, day_ini, slow_diagfi 计算采样间隔、最后输出步和 1D 文件打开/关闭策略。 -
mod_phys_lmdz_para is_parallel, is_mpi_root, is_master, gather 并行收集和只允许 master/root 写 NetCDF。 -
mod_grid_phy_lmdz klon_glo, Grid1Dto2D_glo, nbp_lon, nbp_lat, nbp_lev, grid_type, unstructured 网格维度、物理到经纬网格重排和 unstructured 网格早退。 -

调用的关键例程

被调用例程 所在模块 / 文件 调用位置 作用
iniwrite iniwrite.F 首次有效变量调用 diagfi.nc 固定头信息和坐标。
def_var def_var.F90 新变量首次写入 在 NetCDF define mode 中创建变量并写 title/units 属性。
abort_physic 外部错误处理 多处错误分支 变量名过长、diagfi.def 超限、变量重复、写入失败或并行 dim=1 时中止。
NetCDF NF_* NetCDF F77 接口 多处 创建/打开/关闭文件,定义维度变量,追加时间和写变量。
gather, Grid1Dto2D_glo 并行/网格模块 并行 dim=2/3 路径 收集物理网格并重排到全局经纬网格。

输入

输入 来源 类型 / 维度 单位 含义
ngrid 调用方 integer - 当前物理网格点数。
nom, titre, unite 调用方 character - 变量名、说明和单位属性。
dim 调用方 integer 0/1/2/3 - 变量维度码。
px(ngrid,nbp_lev) 调用方 real array variable-dependent 待写诊断场;低维变量也通过该二维实参承载。
diagfi.def 运行目录可选文件 text file - 若存在,仅输出列在其中的变量名。

输出

输出 去向 类型 / 维度 单位 含义
diagfi.nc 当前运行目录 NetCDF file - 传统物理诊断文件。
Time diagfi.nc unlimited coordinate days zitausteps_per_sol 派生的输出时间。
nom 变量 diagfi.nc 0D/1D/2D/3D unite 由调用方指定的诊断变量。

共享状态与副作用

核心逻辑

  1. 首次调用读取 diagfi.def,并计算 isample=steps_per_sol/outputs_per_sollastzitau=(day_end-day_ini)*steps_per_sol-1
  2. 若启用 diagfi.def 且当前变量名不在列表中,立即返回。
  3. 第一次有效变量调用时创建 diagfi.nc,定义 unlimited Time,收集 phisfi/cell_area,调用 iniwrite 写文件头。
  4. firstnom 判断是否进入新的物理时刻;若当前变量名等于 firstnom,递增 zitau
  5. 仅当 MOD(zitau+1,isample)==0 时写出:master 打开文件,首变量追加 Time
  6. 根据 dim 创建变量(若尚不存在)并写入 dx3/dx2/dx1/dx0
  7. 根据 1D/3D 和 slow_diagfi 策略关闭文件。

伪代码

writediagfi(ngrid, nom, titre, unite, dim, px):
  if unstructured grid: return
  on first call:
    read optional diagfi.def
    compute isample and lastzitau
  if diagfi.def exists and nom not listed: return
  on first valid variable:
    create diagfi.nc
    define Time
    write fixed header with iniwrite
  if nom == firstnom:
    zitau += 1
  if output step:
    open diagfi.nc
    if nom == firstnom:
      ntime += 1
      write Time
    recast/gather px according to dim
    create variable with def_var if needed
    write variable at ntime
    close file according to slow_diagfi and 1D/3D mode

参与的主题流程

主题 参与方式
传统诊断输出 write_output_mod 或物理例程直接调用本例程写 diagfi.nc
文件初始化 首次有效变量调用时调用 iniwrite 写固定坐标和控制字段。
并行输出 并行构建中通过 gatherGrid1Dto2D_glo 先集中到 root/master 再写 NetCDF。

写法特点

复现要点

待确认

相关页面