write_output_mod.F90
路径
LMDZ.MARS\libf\phymars\write_output_mod.F90
所属目录 / 模块
libf/phymars
文件定位
write_output_mod.F90 提供 write_output 泛型接口,是物理代码向传统 diagfi.nc、土壤诊断和可选 XIOS 输出发送字段的薄封装层。调用方只传 field_name/title/units/field,本模块按字段类型和维度分派到 9 个具体过程:real、integer、logical 各支持 0D scalar、1D surface field 和 2D horizontal-vertical field。
传统输出由全局开关 output_diagfi 控制;二维字段若第二维等于 comsoil_h:nsoilmx,则改走 writediagsoil,不受 output_diagfi 控制。启用 CPP_XIOS 时,每个具体过程还会调用 send_xios_field。源码中 xios_is_active_field(field_name) 检查被注释掉,实际 is_active=.true.,因此 XIOS 编译路径会无条件向 XIOS 发送本次调用的字段。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
write_output_mod |
module |
1 |
封装传统诊断和 XIOS 输出的统一写字段接口。 |
write_output |
generic interface |
7 |
对外公开的泛型接口,按实参类型/维度分派到 9 个具体过程。 |
output_diagfi |
logical public saved variable |
15 |
控制是否写传统 diagfi.nc,源码注释说明由 conf_phys() 初始化。 |
write_output_d0/d1/d2 |
subroutines |
24/56/88 |
写 real scalar、surface field、2D field。 |
write_output_i0/i1/i2 |
subroutines |
128/161/194 |
写 integer scalar、surface field、2D field,传统和 XIOS 路径均转换为 real。 |
write_output_l0/l1/l2 |
subroutines |
233/269/307 |
写 logical scalar、surface field、2D field,先转换为 0/1 real。 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
xios_output_mod |
xios_is_active_field, send_xios_field |
仅在 CPP_XIOS 下导入;实际活跃性检查被注释,发送由 send_xios_field 完成。 |
xios_is_active_field 当前未使用。 |
comsoil_h |
nsoilmx |
d2/i2/l2 判断二维字段是否为土壤剖面字段。 |
- |
writediagsoil_mod |
writediagsoil |
d2/i2/l2 的土壤字段传统输出。 |
- |
调用的关键例程
| 被调用例程 |
所在模块 / 文件 |
调用位置 |
作用 |
writediagfi |
writediagfi.F |
各具体过程 |
写传统 diagfi.nc 字段;维度码为 0、2、3。 |
writediagsoil |
writediagsoil_mod / writediagsoil.F90 |
d2/i2/l2 |
当 size(field,2)==nsoilmx 时写土壤诊断。 |
send_xios_field |
xios_output_mod.F90 |
CPP_XIOS 分支 |
向 XIOS 发送 scalar、1D 或 2D 字段。 |
输入
| 输入 |
来源 |
类型 / 维度 |
单位 |
含义 |
field_name |
调用方 |
character |
- |
输出变量名,同时用于传统 NetCDF 和 XIOS field 名。 |
title |
调用方 |
character |
- |
传统 diagfi/writediagsoil 变量说明。 |
units |
调用方 |
character |
- |
传统输出变量单位属性。 |
field |
调用方 |
real/integer/logical scalar、1D 或 2D |
variable-dependent |
待写出的诊断字段。 |
output_diagfi |
conf_phys 初始化 |
logical module variable |
- |
是否写传统 diagfi.nc。 |
输出
| 输出 |
去向 |
类型 / 维度 |
单位 |
含义 |
diagfi.nc 字段 |
writediagfi |
scalar/surface/3D-like |
variable-dependent |
非土壤传统诊断输出,受 output_diagfi 控制。 |
| 土壤诊断字段 |
writediagsoil |
2D soil profile |
variable-dependent |
当二维字段第二维等于 nsoilmx 时写出。 |
| XIOS field |
send_xios_field |
scalar/1D/2D |
variable-dependent |
CPP_XIOS 编译路径下发送给 XIOS。 |
共享状态与副作用
output_diagfi 是 public, save 且 THREADPRIVATE,控制传统 diagfi 输出是否发生。
- 每个具体过程都包含
dimensions.h,并用 ngrid = 2 + (jjm - 1)*iim - 1/jjm 计算传统输出网格点数。
- integer 和 logical 字段在写出前转换为 real;logical 使用 0/1 编码。
write_output_l1 分配 field_real(size(field,1)) 后未显式 deallocate;过程退出时 Fortran allocatable 局部变量会自动释放。
d2/i2/l2 的土壤字段路径不检查 output_diagfi,只由 size(field,2)==nsoilmx 触发。
核心逻辑
- 泛型
write_output 根据 field 的类型和秩选择 d/i/l 与 0/1/2 具体过程。
- scalar real 传统输出以
(/field/) 包装为长度 1 数组,维度码用 0。
- 1D surface field 传统输出维度码用 2。
- 2D field 若第二维等于
nsoilmx,调用 writediagsoil(...,3,field);否则在 output_diagfi 为真时调用 writediagfi(...,3,field)。
- integer 和 logical 在进入传统或 XIOS 输出前转为 real;logical
.true. 写作 1,.false. 写作 0。
CPP_XIOS 下把 is_active 强制设为 .true.,然后调用 send_xios_field(field_name, converted_field)。
伪代码
write_output(field_name, title, units, field):
dispatch by type and rank
if rank == 2 and size(field,2) == nsoilmx:
writediagsoil(ngrid, field_name, title, units, 3, real_field)
else if output_diagfi:
writediagfi(ngrid, field_name, title, units, dimension_code, real_field)
if CPP_XIOS:
is_active = true
if is_active:
send_xios_field(field_name, real_field)
参与的主题流程
| 主题 |
参与方式 |
| 传统诊断输出 |
为物理过程提供统一入口,最终写入 diagfi.nc。 |
| 土壤诊断输出 |
根据二维字段第二维是否等于 nsoilmx 自动改走 writediagsoil。 |
| XIOS 输出 |
CPP_XIOS 下把字段发送给 xios_output_mod,由 XIOS 配置决定文件输出。 |
写法特点
- 使用 Fortran 泛型接口隐藏具体类型/维度分派,调用方只需调用
write_output(...)。
- 传统
writediagfi 的维度码在本模块硬编码为 0、2、3。
- XIOS 活跃字段检查目前被注释,
is_active=.true. 是源码实际行为。
- 2D 土壤字段用维度长度识别,而不是用变量名识别。
复现要点
- 复现传统输出时必须先确认
output_diagfi 的线程副本已由 conf_phys 正确初始化。
- 若二维非土壤字段刚好第二维等于
nsoilmx,本模块会把它送入 writediagsoil;字段维度设计应避免误判。
- XIOS 路径当前不会过滤未激活字段;若重启
xios_is_active_field 检查,输出行为会改变。
- logical 输出不是 NetCDF logical 类型,而是 real 0/1。
待确认
write_output_l1 未显式释放 field_real,按 Fortran allocatable 局部变量退出自动释放解释;若目标编译器或编译选项有差异,需要确认运行时行为。
output_diagfi 的初始化调用点和 OpenMP THREADPRIVATE 副本同步需结合 conf_phys.F 与物理并行初始化流程继续核对。
相关页面