writediagsoil.F90
路径
LMDZ.MARS\libf\phymars\writediagsoil.F90
所属目录/模块
libf/phymars
文件定位
writediagsoil.F90 是传统 NetCDF 土壤诊断文件 diagsoil.nc 的追加写入后端。conf_phys 读取 diagsoil 开关并写入本模块的全局变量;write_output_mod 遇到第二维等于 nsoilmx 的地下剖面字段时调用 writediagsoil,普通大气三维场则继续走 writediagfi/XIOS 路径。
本文件在第一次有效调用时创建 diagsoil.nc,整理土壤热惯量和网格面积,并调用 iniwritesoil 写入经纬度、深度、时间维和固定字段。后续每到采样步时,它按变量名懒定义新 NetCDF 变量,并把 3D 地下剖面、2D 地表场或 0D 标量追加到当前时间记录。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
writediagsoil_mod |
module |
1 |
封装 diagsoil 开关和 writediagsoil 子程序 |
diagsoil |
module variable |
5 |
全局输出开关;.true. 时才生成/写入 diagsoil.nc,由 conf_phys 初始化 |
writediagsoil |
subroutine |
10 |
将土壤诊断变量写入 diagsoil.nc,必要时先初始化文件和变量定义 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
comsoil_h |
mlayer, nsoilmx, inertiedat |
土壤层数、层中深度和热惯量固定字段 |
|
geometry_mod |
cell_area |
初始化 diagsoil.nc 时写入网格面积 |
|
time_phylmdz_mod |
steps_per_sol, outputs_per_sol |
计算输出采样间隔和 time 变量的 sol 单位值 |
|
mod_phys_lmdz_para |
is_mpi_root, is_master, gather |
并行模式下聚合物理网格字段,并限制主进程写文件 |
|
mod_grid_phy_lmdz |
klon_glo, Grid1Dto2D_glo, nbp_lon, nbp_lat |
物理一维数组到全局经纬网格的转换和维度大小 |
|
mod_grid_phy_lmdz |
grid_type, unstructured |
检查非结构网格并提前中止 |
|
iniwritesoil_mod |
iniwritesoil |
初始化 diagsoil.nc 的维度、坐标和固定变量 |
|
netcdf.inc(include) |
— |
NetCDF F77 接口常量与例程 |
|
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
iniwritesoil |
iniwritesoil_mod / iniwritesoil.F90 |
行 157、159 |
首次调用时初始化 diagsoil.nc 的坐标、时间维、area 和 th_inertia |
Gather |
mod_phys_lmdz_para |
行 125、127、209、296 |
并行模式下把局地物理网格数组聚合到全局数组 |
Grid1Dto2D_glo |
mod_grid_phy_lmdz |
行 212、299 |
将全局一维物理网格重排为经纬二维数组 |
NF_CREATE / NF_OPEN / NF_CLOSE |
NetCDF |
行 116、182、162、414 |
创建、打开和关闭 diagsoil.nc |
NF_INQ_VARID / NF_INQ_DIMID |
NetCDF |
行 189、243、248-251、328、333-335、381、386 |
查询时间、变量和维度 ID;变量不存在时进入懒定义路径 |
def_var |
def_var.F90 |
行 255、339、390 |
为新诊断变量写入 NetCDF 变量定义和属性 |
NF_PUT_VARA_REAL |
NetCDF |
行 194、278、280、360、362、402 |
追加写入时间值和变量数据;本文件强制用 real*4 输出 |
abort_physic |
外部错误处理 |
行 93、107、119、198、374 |
对非结构网格、文件创建失败、时间写入失败等不可继续条件中止 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
ngrid |
调用方 |
integer |
— |
物理水平网格点数 |
name |
调用方 |
character |
— |
NetCDF 变量名;第一次出现的 name 被记作时间循环首变量 |
title |
调用方 |
character |
— |
写入变量的 long_name 属性 |
units |
调用方 |
character |
— |
写入变量的 units 属性 |
dimpx |
调用方 |
integer |
— |
变量维度标志:3 为 (longitude, latitude, depth, time),2 为 (longitude, latitude, time),0 为 (time) |
px |
调用方 |
real(ngrid,nsoilmx) |
随变量 |
待输出字段;2D 和 0D 分支只使用第一土壤层位置 |
diagsoil |
conf_phys / 本模块 |
logical |
— |
.false. 时本例程立即返回,不创建文件 |
inertiedat, cell_area, mlayer |
comsoil_h, geometry_mod |
real arrays |
见源变量 |
首次初始化文件时写入的固定土壤和网格信息 |
steps_per_sol, outputs_per_sol |
time_phylmdz_mod |
integer |
— |
决定采样间隔 isample=steps_per_sol/outputs_per_sol |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
diagsoil.nc |
当前运行目录 |
NetCDF 文件 |
— |
土壤诊断时间序列文件 |
time |
diagsoil.nc |
real(time) |
sol |
每个输出记录的模型时间,date=(zitau+1)/steps_per_sol |
name 对应变量 |
diagsoil.nc |
dimpx 决定 |
units 参数 |
追加的土壤诊断变量 |
典型维度:
dimpx |
NetCDF 维度 |
数据来源 |
3 |
(longitude, latitude, depth, time) |
px(:,1:nsoilmx),用于土壤剖面变量 |
2 |
(longitude, latitude, time) |
px(:,1),用于地表或柱积分场 |
0 |
(time) |
px(1,1),用于标量;并行模式未实现 |
共享状态与副作用
- 模块开关:
diagsoil 是 save 变量,由 conf_phys.F:191-194 读取配置键 diagsoil 后设置,默认 .false.。
- 时间循环状态:
date、isample、ntime、firstname、zitau 都是 save 变量,并通过 !$OMP THREADPRIVATE 设为线程私有状态。
- 首变量约定:第一次传入的
name 被保存为 firstname;之后每次再次遇到这个名字,就把 zitau 加一并视作新的时间步。
- 文件副作用:主进程创建、打开、写入并关闭硬编码文件名
diagsoil.nc。
- 并行副作用:
CPP_PARA 下字段先 Gather 到全局物理网格,再由 MPI root / master 转为经纬二维数组;0D 分支在并行模式下直接 abort。
- 错误处理差异:文件创建、非结构网格、时间写入失败会
abort_physic;变量数据写入失败只打印错误消息,不中止。
核心逻辑
- 检查开关与网格:若
diagsoil=.false. 立即返回;若 grid_type==unstructured,报错并中止,因为 diagsoil.nc 只支持 lon-lat 或 1D。
- 首次初始化:当
firstname=="1234567890" 时,保存首个变量名、设置采样间隔、创建 diagsoil.nc,并整理 inertiedat 与 cell_area。
- 写固定框架:3D lon-lat 情况把极点、内点和冗余经度点填入
inertia / area;1D 情况传入单点数组;随后调用 iniwritesoil 并关闭文件。
- 推进本地时间:每次
name==firstname 时令 zitau=zitau+1。只有 mod(zitau+1,isample)==0 时才进入写数据分支。
- 写时间轴:采样步上,主进程打开
diagsoil.nc;若当前变量就是 firstname,则 ntime=ntime+1 并把 date 写入 time(ntime)。
- 写 3D 剖面变量:把
px(ngrid,nsoilmx) 重排为 (nbp_lon+1,nbp_lat,nsoilmx) 或 1D profile;变量不存在时用 def_var 定义 (longitude,latitude,depth,time);再写当前时间片。
- 写 2D 变量:取
px(:,1),重排为 (nbp_lon+1,nbp_lat) 或 1D surface value;变量不存在时定义 (longitude,latitude,time);再写当前时间片。
- 写 0D 变量:串行模式下取
px(1,1),变量不存在时定义 (time),再写当前时间点。
- 关闭文件:采样步末尾主进程关闭
diagsoil.nc,等待下一变量或下一输出时间。
伪代码
if not diagsoil:
return
if grid_type is unstructured:
abort
if first call:
firstname = name
isample = steps_per_sol / outputs_per_sol
create diagsoil.nc
gather or copy inertiedat and cell_area
map them to lon-lat grid, with redundant longitude point if 3D
iniwritesoil(..., inertia, area, mlayer)
close diagsoil.nc
zitau = -1
if name == firstname:
zitau += 1
if this step is not a sampling step:
return
open diagsoil.nc
if name == firstname:
ntime += 1
time[ntime] = (zitau + 1) / steps_per_sol
if dimpx == 3:
map px(:,1:nsoilmx) to lon-lat-depth or 1D profile
define variable if missing
write one time slab
else if dimpx == 2:
map px(:,1) to lon-lat or 1D surface value
define variable if missing
write one time slab
else if dimpx == 0:
if CPP_PARA: abort
define scalar time variable if missing
write px(1,1)
close diagsoil.nc
参与的主题流程
| 主题 |
参与方式 |
| 土壤诊断输出 |
生成并追加写入 diagsoil.nc,是 iniwritesoil 之后的逐时步写入阶段 |
| 水循环 / 地下水 |
soilwater 的地下水、冰饱和度和 regolith 通量诊断可通过 write_output 进入本例程 |
| 土壤热扩散 |
soil 产生的 tsoil / soiltemp 等地下温度剖面可按 nsoilmx 维度写入 |
| XIOS 与传统输出 |
write_output_mod 同时负责 XIOS 发送和传统文件;writediagsoil 是传统 diagsoil.nc 路径,不受 XIOS file_def 是否引用字段控制 |
写法特点
- 硬编码文件名:输出文件固定为
diagsoil.nc,没有从参数传入文件名。
- 首变量驱动时间轴:时间记录由
firstname 决定,复现时要保持每个输出周期的变量调用顺序稳定。
- real*4 输出:源码注释说明 2010 年修改为强制 real*4 输出;实际写入使用
NF_PUT_VARA_REAL。
- 经度闭合点:3D lon-lat 输出使用
nbp_lon+1,最后一列复制第一列,和 iniwritesoil 写出的经度维度保持一致。
- 旧式 NetCDF 接口:使用
include "netcdf.inc" 和 NF_* 例程,变量不存在时通过查询失败触发 def_var。
- 并行/线程混合:并行数据转换用
Gather、Grid1Dto2D_glo、is_mpi_root、is_master 和 OpenMP barrier;时间计数状态是 THREADPRIVATE。
复现要点
diagsoil 默认关闭;没有配置 diagsoil=true 时,write_output 即使调用到本例程也不会产生文件。
diagsoil.nc 不支持 grid_type==unstructured;非结构网格运行会在本例程开头中止。
write_output_mod 只把第二维等于 nsoilmx 的 2D 数组转给 writediagsoil;普通大气三维变量仍走 writediagfi 或 XIOS。
- 采样间隔是
steps_per_sol/outputs_per_sol 的整数结果;复现输出频率时需要同时核对这两个时间模块变量。
- 1D 模型以
klon_glo==1 判断,写入维度为 1×1×nsoilmx,不写冗余经度点。
- 并行模式下 0D 标量分支未实现;直接调用
writediagsoil(...,dimpx=0,...) 的代码在 CPP_PARA 下会 abort。
- 变量数据写入失败只打印错误而不中止;检查输出完整性时不能只依赖运行是否正常结束。
待确认
write_output_mod 当前未把普通 0D 标量路由到 writediagsoil;0D 分支是否仍有外部直接调用者,需全项目进一步确认。
firstname 长度固定为 20,超过 20 字符的首变量名会触发 abort;当前土壤诊断字段是否都满足这一限制,应结合具体输出清单核验。
isample=steps_per_sol/outputs_per_sol 未在本文件中防护除零或不能整除的情形;配置层是否已保证合法,需从时间配置入口另行确认。
相关页面