iniwritesoil.F90
路径
LMDZ.MARS\libf\phymars\iniwritesoil.F90
所属目录/模块
libf/phymars
文件定位
iniwritesoil.F90 是土壤诊断 NetCDF 输出的初始化例程。它只在 writediagsoil 首次被调用时执行一次,负责在 diagsoil.nc 文件中创建经纬度、深度、时间四个维度及其坐标变量,并写入与时间无关的固定字段(网格面积 area、热惯量 th_inertia)。后续逐时步的土壤诊断数据由 writediagsoil 追加写入,不再经过本文件。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
iniwritesoil_mod |
module |
1 |
包裹 iniwritesoil 子程序的模块 |
iniwritesoil |
subroutine |
7 |
初始化土壤诊断 NetCDF 文件的维度与固定变量 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
comcstfi_h |
pi |
弧度→度转换因子 180./pi |
|
regular_lonlat_mod |
lon_reg, lat_reg |
规则经纬度网格坐标(弧度),写入 NetCDF 前转为度 |
|
mod_grid_phy_lmdz |
nbp_lon, nbp_lat |
物理网格经/纬点数,决定维度大小 |
|
netcdf.inc(include) |
— |
NetCDF C 接口头文件,提供 NF_* 函数与常量 |
|
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
NF_REDEF / NF_ENDDEF |
netcdf 库 |
多处 |
进入/退出 NetCDF 定义模式 |
NF_DEF_DIM |
netcdf 库 |
行 60–78 |
定义 longitude/latitude/depth/time 维度 |
NF_DEF_VAR |
netcdf 库 |
行 89–254 |
定义坐标变量与数据变量 |
NF_PUT_ATT_TEXT |
netcdf 库 |
行 99–203 |
写入变量属性(long_name、units、positive) |
NF_PUT_VAR_DOUBLE / NF_PUT_VAR_REAL |
netcdf 库 |
行 113–272 |
写入变量数据(受 NC_DOUBLE 宏控制精度) |
本文件不调用其他 LMDZ 子程序。
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
nid |
调用方 writediagsoil |
integer |
— |
已打开的 NetCDF 文件 ID |
ngrid |
调用方 |
integer |
— |
水平网格点数(本文件未直接使用,保留接口一致性) |
inertia |
调用方(来自 comsoil_h) |
real(nbplon, nbplat, nsoilmx) |
J·s⁻¹/²·m⁻²·K⁻¹ |
各层热惯量三维数组 |
area |
调用方(来自 geometry_mod) |
real(nbplon, nbp_lat) |
m² |
水平网格面积 |
nbplon, nbplat |
调用方 |
integer |
— |
经/纬方向点数(3D 时为 nbp_lon+1, nbp_lat;1D 时为 1, 1) |
nsoilmx |
调用方(来自 comsoil_h) |
integer |
— |
土壤层数 |
mlayer |
调用方(来自 comsoil_h) |
real(nsoilmx) |
m |
各土壤层中间深度 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
NetCDF 文件 nid |
磁盘 diagsoil.nc |
— |
— |
写入维度定义、坐标变量和固定字段 |
写入的 NetCDF 变量:
| 变量名 |
维度 |
单位 |
说明 |
longitude |
(longitude) |
degrees_east |
经度坐标,含冗余 180° 点(3D) |
latitude |
(latitude) |
degrees_north |
纬度坐标 |
depth |
(depth) |
m(positive: down) |
土壤层中间深度 |
time |
(time) |
days since 0000-00-00 00:00:00 |
仅定义,不写数据(由 writediagsoil 追加) |
area |
(longitude, latitude) |
m² |
网格面积 |
th_inertia |
(longitude, latitude, depth) |
J·s⁻¹/²·m⁻²·K⁻¹ |
热惯量 |
共享状态与副作用
- 写入 NetCDF 文件:通过
nid 文件 ID 写入 diagsoil.nc,这是唯一副作用。
- 无 module 变量修改:不修改任何 module 级变量。
- 1D vs 3D 分支:
nbp_lon*nbp_lat==1 时走 1D 模型路径(维度大小为 1,无冗余经度点),否则走 3D 路径(经度维度为 nbp_lon+1,含冗余闭合点)。
NC_DOUBLE 宏:编译时若定义 NC_DOUBLE,所有变量以 NF_DOUBLE(real8)写入;否则以 NF_FLOAT(real4)写入。
核心逻辑
- 分配扩展经度数组(行 46–52):1D 时长度为 1,3D 时长度为
nbp_lon+1。
- 定义 4 个维度(行 56–78):
longitude(1D 时为 1,3D 时为 nbp_lon+1)、latitude(nbp_lat)、depth(nsoilmx)、time(NF_UNLIMITED)。
- 写经度坐标变量(行 84–120):定义变量 → 写属性 → 从
lon_reg 复制到 lon_reg_ext,3D 时追加冗余点 lon_reg_ext(nbp_lon+1) = -lon_reg_ext(1)(即 180°)→ 弧度转度 → 写入。
- 写纬度坐标变量(行 122–151):定义变量 → 写属性 →
lat_reg 弧度转度 → 写入。
- 写深度坐标变量(行 153–184):定义变量 → 写属性 → 直接写入
mlayer(已是米)。
- 定义时间变量(行 186–206):定义变量 → 写属性 → 不写数据(注释说明由
writediagsoil 追加)。
- 写网格面积(行 210–241):定义 2D 变量
(longitude, latitude) → 写属性 → 写入 area。
- 写热惯量(行 243–275):定义 3D 变量
(longitude, latitude, depth) → 写属性 → 写入 inertia。
伪代码
allocate lon_reg_ext (1D: 长度1, 3D: 长度nbp_lon+1)
! 定义维度
NF_REDEF
定义 longitude (1D→1, 3D→nbp_lon+1)
定义 latitude (nbp_lat)
定义 depth (nsoilmx)
定义 time (unlimited)
NF_ENDDEF
! 写经度坐标
NF_REDEF → NF_DEF_VAR("longitude")
lon_reg_ext[1:nbp_lon] = lon_reg[1:nbp_lon]
if 3D: lon_reg_ext[nbp_lon+1] = -lon_reg_ext[1] ! 冗余180°点
NF_ENDDEF → NF_PUT_VAR (弧度→度)
! 写纬度坐标
NF_REDEF → NF_DEF_VAR("latitude")
NF_ENDDEF → NF_PUT_VAR (弧度→度)
! 写深度坐标
NF_REDEF → NF_DEF_VAR("depth")
NF_ENDDEF → NF_PUT_VAR (已是米)
! 定义时间变量(不写数据)
NF_REDEF → NF_DEF_VAR("time")
NF_ENDDEF
! 写固定字段
NF_REDEF → NF_DEF_VAR("area", 2D)
NF_ENDDEF → NF_PUT_VAR(area)
NF_REDEF → NF_DEF_VAR("th_inertia", 3D)
NF_ENDDEF → NF_PUT_VAR(inertia)
参与的主题流程
| 主题 |
参与方式 |
| 土壤诊断输出 |
为 diagsoil.nc 建立维度和固定字段框架,是土壤诊断时间序列输出的第一步 |
写法特点
- 固定格式 Fortran:虽使用
.F90 扩展名,但代码风格偏旧式(implicit none 重复声明、无模块化接口块)。
#ifdef NC_DOUBLE 条件编译:控制 NetCDF 变量精度,默认 NF_FLOAT(real4),定义 NC_DOUBLE 后为 NF_FLOAT→NF_DOUBLE(real8)。
- 冗余经度点:3D 模式下经度维度为
nbp_lon+1,最后一点为 -lon_reg(1)(即 180°),用于闭合经度环。
- 错误处理:每个 NetCDF 调用后检查
ierr.ne.NF_NOERR,但仅 write(*,*) 打印错误,不中止执行。
- 行 150 错误信息误写:写纬度变量失败时,错误信息写成
"could not write longitude variable"(应为 latitude),是复制粘贴遗留。
复现要点
- 本例程只在
writediagsoil 首次调用时执行一次;后续调用由 writediagsoil 内部的 firstcall 逻辑跳过。
diagsoil 全局开关(writediagsoil_mod 中的 logical,save :: diagsoil)在 conf_phys() 中初始化,控制是否生成 diagsoil.nc。
- 1D 模型(
nbp_lon*nbp_lat==1)走不同分支:经度维度为 1、无冗余点、area 和 inertia 为单点标量。
待确认
- 行 150 错误信息
"could not write longitude variable" 应为 "could not write latitude variable",推断为复制粘贴错误(待确认:不影响功能,仅为日志可读性问题)。
ngrid 参数在本子程序中未使用,仅作为接口一致性保留(待确认:是否为历史遗留参数)。
相关页面