write_archive.F
路径
LMDZ.MARS\libf\dynphy_lonlat\phymars\write_archive.F
所属目录/模块
libf/dynphy_lonlat/phymars
文件定位
write_archive.F 定义 write_archive,是在已由 ini_archive 建好头的 start_archive.nc 中创建并追加变量数据的通用写入器。调用方传入 NetCDF 文件句柄、时间记录号、变量名/标题/单位、维度标记 dim 和数据缓冲区 px;本例程按 dim 与变量名选择 NetCDF 维度组合,必要时调用 def_var 先定义变量,然后用 NF_PUT_VARA_* 在指定 Time=ntime 位置写入数据。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
write_archive |
subroutine |
2 |
为 start_archive.nc 创建缺失变量并在指定时间记录写入 3D/2D/0D/土壤变量。 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
comsoil_h |
nsoilmx |
dim=-3 时确定 subsurface_layers 写入长度。 |
无。 |
comslope_mod |
nslope |
dim=2 的坡面变量和 dim=-3 的 tsoil/inertiesoil 写入坡面维长度。 |
无。 |
include 依赖
| include |
用途 |
dimensions.h |
提供 iim/jjm/llm。 |
paramet.h |
提供 iip1/jjp1 等 archive 网格维度。 |
comgeom.h |
当前例程未直接引用其中变量;可能为历史保留。 |
netcdf.inc |
提供 NetCDF API 常量和例程。 |
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
NF_INQ_VARID |
NetCDF API |
多处分支入口 |
检查变量是否已存在。 |
NF_INQ_DIMID |
NetCDF API |
多处 |
获取 longitude/latitude/altitude/subsurface_layers/nslope/Time 维度 ID。 |
def_var |
def_var |
多处 |
变量不存在时按维度 ID 列表创建变量并写属性。 |
NF_PUT_VARA_DOUBLE / NF_PUT_VARA_REAL |
NetCDF API |
多处 |
根据 NC_DOUBLE 写入当前时间记录的数据块。 |
abort |
外部例程 |
错误分支 |
变量写入失败、必需维度缺失或未知 dim 时终止。 |
调用方
| 调用方 |
调用位置 |
作用 |
start2archive |
start2archive.F:461-543 |
依次写入水冰、CO2 冰、尘/云、发射率、反照率、地表压、温度、风、q2、可选 SSO、tracer、地表 tracer、土壤温度和土壤热惯量。 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
nid |
调用方 |
INTEGER |
- |
已打开的 start_archive.nc NetCDF 文件 ID。 |
ntime |
调用方 |
INTEGER |
record index |
要写入的 Time 记录号。 |
nom |
调用方 |
CHARACTER*(*) |
- |
NetCDF 变量名。 |
titre |
调用方 |
CHARACTER*(*) |
- |
变量 title 属性。 |
unite |
调用方 |
CHARACTER*(*) |
- |
变量 units 属性。 |
dim |
调用方 |
INTEGER |
- |
维度标记:3、2、0 或 -3。 |
px |
调用方 |
REAL(iip1,jjp1,llm) 声明 |
按变量而定 |
数据缓冲区;源码通过 Fortran 实参序列关联传入不同形状数组。 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
NetCDF 变量 nom |
start_archive.nc |
依 dim/nom 决定 |
unite |
若变量不存在则创建,随后在 ntime 位置写入 px。 |
维度分支
dim |
变量类别 |
NetCDF 维度 |
写入尺寸 edges |
代表调用 |
3 |
大气三维变量 |
longitude,latitude,altitude,Time |
iip1,jjp1,llm,1 |
temp,u,v,q2atm,tracer |
2 且变量在特殊名单中 |
无坡面二维变量 |
longitude,latitude,Time |
iip1,jjp1,1 |
ps,q2surf,tauscaling,totcloudfrac,ZMEA,z0,watercaptag |
2 其他变量 |
带坡面二维变量 |
longitude,latitude,nslope,Time |
iip1,jjp1,nslope,1 |
watercap,perennial_co2ice,emis,albedo,qsurf |
-3 且 nom 为 tsoil 或 inertiesoil |
土壤层 + 坡面变量 |
longitude,latitude,subsurface_layers,nslope,Time |
iip1,jjp1,nsoilmx,nslope,1 |
tsoil,inertiesoil |
-3 其他变量 |
土壤层变量 |
longitude,latitude,subsurface_layers,Time |
iip1,jjp1,nsoilmx,1 |
inertiedat |
0 |
时间标量 |
Time |
1 |
源码支持,但 start2archive 当前未启用 volcapa 写入。 |
共享状态与副作用
- 修改已打开 NetCDF 文件;变量不存在时会进入 define mode 创建变量。
- 读取
nsoilmx 和 nslope 来确定写入尺寸。
- 出错时打印变量名和
NF_STRERROR(ierr),然后 abort。
px 声明为三维数组,但调用方传入二维、三维、土壤四维/五维逻辑布局时依赖 Fortran 存储连续性和 edges 控制实际写入长度。
核心逻辑
- 根据
dim 进入分支。
- 每个分支先
NF_INQ_VARID(nid,nom,varid);若变量不存在,查询对应坐标维度 ID 并调用 def_var 创建变量。
- 设置
corner,通常空间维为 1,时间维为 ntime。
- 设置
edges,空间长度来自 iip1/jjp1/llm/nsoilmx/nslope,时间长度为 1。
- 根据
NC_DOUBLE 选择 NF_PUT_VARA_DOUBLE 或 NF_PUT_VARA_REAL 写 px。
- 写入失败时打印错误并终止;未知
dim 也终止。
伪代码
if dim == 3:
ensure variable(nom) has longitude, latitude, altitude, Time
write px(1:iip1,1:jjp1,1:llm) at Time=ntime
else if dim == -3:
if nom is tsoil or inertiesoil:
ensure longitude, latitude, subsurface_layers, nslope, Time
write iip1*jjp1*nsoilmx*nslope
else:
ensure longitude, latitude, subsurface_layers, Time
write iip1*jjp1*nsoilmx
else if dim == 2:
if nom is in the no-slope whitelist:
ensure longitude, latitude, Time
write iip1*jjp1
else:
ensure longitude, latitude, nslope, Time
write iip1*jjp1*nslope
else if dim == 0:
ensure Time variable shape
write one scalar at ntime
else:
abort
参与的主题流程
写法特点
- 固定格式 Fortran,无
INTENT 标注。
- 用
dim 的数值约定而不是类型安全接口区分数据形状。
dim=2 的是否带 nslope 由变量名白名单决定。
dim=-3 的是否带 nslope 只对 tsoil 和 inertiesoil 特判。
NC_DOUBLE 只影响数据写入 API;变量定义仍由 def_var 处理。
复现要点
- 调用前必须已经打开
start_archive.nc,且 ini_archive 已创建必要维度。
ntime 应是 Time 维中的有效追加记录位置。
- 调用方传入的数组内存布局必须和本例程选择的
edges 一致。
- 新增变量若应含坡面维,不能把名字放进无坡面二维白名单。
待确认
px 的固定三维声明与 tsoil/inertiesoil/qsurf 等多形状实参之间依赖旧式 Fortran 序列关联;需结合编译器选项确认无接口检查问题。
def_var 当前是否按 NC_DOUBLE 创建 double 变量需看其实现;本例程只在写入时分派 double/real。
dim=0 当前在 start2archive 中没有实际启用调用。
相关页面