iostart.F90
路径
LMDZ.MARS\libf\phymars\iostart.F90
所属目录 / 模块
libf\phymars
文件定位
iostart.F90 定义 iostart 模块,是 LMDZ.MARS 物理重启文件(startfi.nc 和 restartfi.nc)的 NetCDF I/O 核心模块。它提供读取初始场(get_field/get_var)和写入重启场(put_field/put_var)的统一接口,支持 1D/2D/3D/4D 数组的读写,并处理并行环境下的数据分发和重排。
本模块是物理初始化(phyetat0)和重启输出(phyredem)的核心依赖,被 soil_settings.F、phyetat0_mod.F90、phyredem.F90 等文件调用。
定义的符号
| 符号 | 类型 | 行号 | 作用 |
|---|---|---|---|
iostart |
module | 1 | 封装物理重启文件 NetCDF I/O 接口 |
open_startphy |
subroutine | 53 | 打开 startfi.nc 初始场文件 |
close_startphy |
subroutine | 73 | 关闭 startfi.nc 文件 |
inquire_field |
function | 86 | 检查字段是否存在于 startfi.nc |
inquire_field_ndims |
function | 110 | 查询字段的维度数 |
inquire_dimension |
function | 138 | 检查维度是否存在于 startfi.nc |
inquire_dimension_length |
function | 161 | 查询维度的长度 |
get_field |
interface | 29 | 从 startfi.nc 读取字段(1D/2D/3D) |
get_field_r1 |
subroutine | 188 | 读取 1D 表面场 |
get_field_r2 |
subroutine | 214 | 读取 2D 水平-垂直场 |
get_field_r3 |
subroutine | 244 | 读取 3D 场 |
get_field_rgen |
subroutine | 274 | 通用字段读取(含并行分发) |
get_var |
interface | 33 | 从 startfi.nc 读取变量(标量/1D/2D/3D) |
get_var_r0 |
subroutine | 351 | 读取标量 |
get_var_r1 |
subroutine | 369 | 读取 1D 向量 |
get_var_r2 |
subroutine | 384 | 读取 2D 场 |
get_var_r3 |
subroutine | 399 | 读取 3D 场 |
get_var_rgen |
subroutine | 414 | 通用变量读取 |
open_restartphy |
subroutine | 462 | 创建或打开 restartfi.nc 重启文件 |
close_restartphy |
subroutine | 614 | 关闭 restartfi.nc 文件 |
put_field |
interface | 37 | 向 restartfi.nc 写入字段(1D/2D/3D) |
put_field_r1 |
subroutine | 626 | 写入 1D 表面场 |
put_field_r2 |
subroutine | 643 | 写入 2D 水平-垂直场 |
put_field_r3 |
subroutine | 660 | 写入 3D 场 |
put_field_rgen |
subroutine | 678 | 通用字段写入(含并行收集和重排) |
put_var |
interface | 41 | 向 restartfi.nc 写入变量(标量/1D/2D/3D/字符) |
put_var_r0 |
subroutine | 972 | 写入标量 |
put_var_r1 |
subroutine | 986 | 写入 1D 向量 |
put_var_r2 |
subroutine | 997 | 写入 2D 场 |
put_var_r3 |
subroutine | 1008 | 写入 3D 场 |
put_var_rgen |
subroutine | 1019 | 通用变量写入 |
put_var_c1 |
subroutine | 1114 | 写入字符向量 |
依赖的模块
| use 模块 | only 列表 | 用途 | 待确认 |
|---|---|---|---|
netcdf |
NF90_OPEN, NF90_CREATE, NF90_GET_VAR, NF90_PUT_VAR, 等 |
NetCDF 库函数 | - |
mod_phys_lmdz_para |
is_master, bcast, scatter, gather |
并行环境下的主进程判断和数据分发 | - |
mod_grid_phy_lmdz |
klon_glo |
全局网格列数 | - |
dimphy |
klon, klev, klevp1 |
本地物理网格维度 | - |
geometry_mod |
ind_cell_glo |
全局单元索引(用于重排) | - |
tracer_mod |
nqmx |
tracer 数量 | - |
comsoil_h |
nsoilmx |
土壤层数 | - |
comslope_mod |
nslope |
坡面数 | - |
调用的关键例程
| 被调用例程 | 所在模块 / 文件 | 调用位置 | 作用 |
|---|---|---|---|
abort_physic |
abort |
多处 | 错误中止 |
NF90_* |
netcdf |
多处 | NetCDF 库函数 |
输入
| 输入 | 来源 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
filename |
调用方 | character | - | NetCDF 文件名 |
field_name |
调用方 | character | - | 字段名称 |
var_name |
调用方 | character | - | 变量名称 |
field |
调用方 | real (1D/2D/3D) | - | 待写入的字段数据 |
var |
调用方 | real/character | - | 待写入的变量数据 |
title |
调用方 | character | - | 变量标题属性 |
输出
| 输出 | 去向 | 类型/维度 | 单位 | 含义 |
|---|---|---|---|---|
field |
调用方 | real (1D/2D/3D) | - | 读取的字段数据 |
var |
调用方 | real/character | - | 读取的变量数据 |
found |
调用方 | logical | - | 字段/变量是否存在 |
共享状态与副作用
- 模块级
SAVE变量:nid_start:startfi.nc文件标识符nid_restart:restartfi.nc文件标识符idim0~idim11:restartfi.nc维度标识符timeindex:当前时间索引first_time1d:1D 模式首次调用标记
- 这些变量由主进程维护,通过
bcast广播到所有进程。 open_restartphy会创建或打开restartfi.nc文件,并定义维度。put_field_rgen和put_var_rgen会修改restartfi.nc文件内容。
核心逻辑
文件打开:
open_startphy:主进程打开startfi.nc,广播文件标识符open_restartphy:首次调用时创建restartfi.nc并定义维度,后续调用直接打开
字段读取 (
get_field):- 主进程从
startfi.nc读取全局数据 - 按
ind_cell_glo重排列顺序 - 通过
scatter分发到各进程
- 主进程从
字段写入 (
put_field):- 各进程通过
gather收集数据到主进程 - 主进程按
ind_cell_glo重排列顺序 - 根据字段维度(1D/2D/3D)和时间依赖性选择 NetCDF 维度组合
- 写入
restartfi.nc
- 各进程通过
变量读取 (
get_var):- 主进程从
startfi.nc读取变量 - 通过
bcast广播到所有进程
- 主进程从
变量写入 (
put_var):- 主进程将变量写入
restartfi.nc - 特殊处理
Time变量(追加模式)
- 主进程将变量写入
伪代码
iostart:
nid_start, nid_restart: NetCDF file IDs
idim0..idim11: dimension IDs for restartfi.nc
timeindex: current time index
open_startphy(filename):
if is_master:
NF90_OPEN(filename, nid_start)
bcast(nid_start)
get_field(field_name, field):
if is_master:
NF90_GET_VAR(nid_start, field_name, field_glo)
reorder field_glo by ind_cell_glo
scatter(field_glo, field)
open_restartphy(filename):
if is_master:
if first_time:
NF90_CREATE(filename, nid_restart)
define dimensions (scalar, index, physical_points, ...)
else:
NF90_OPEN(filename, nid_restart)
put_field(field_name, field):
gather(field, field_glo)
if is_master:
reorder field_glo by ind_cell_glo
NF90_REDEF(nid_restart)
NF90_DEF_VAR(field_name, dimensions)
NF90_PUT_VAR(field_glo)
close_startphy():
if is_master:
NF90_CLOSE(nid_start)
close_restartphy():
if is_master:
NF90_CLOSE(nid_restart)
参与的主题流程
| 主题 | 参与方式 |
|---|---|
| 物理初始化 | phyetat0 调用 open_startphy 和 get_field/get_var 读取初始场 |
| 物理重启输出 | phyredem 调用 open_restartphy 和 put_field/put_var 写入重启场 |
| 土壤初始化 | soil_settings 调用 get_field 读取土壤参数 |
| 并行计算 | 所有 I/O 操作由主进程执行,通过 bcast/scatter/gather 分发数据 |
写法特点
.F90自由格式模块,使用 Fortran 90 的INTERFACE和MODULE PROCEDURE实现泛型接口。- 使用
PRIVATE/PUBLIC控制可见性,模块级变量默认私有。 - 使用
SAVE属性保存文件标识符和维度 ID。 - 使用
#ifdef NC_DOUBLE预处理指令选择 NetCDF 数据类型(NF90_FLOAT或NF90_DOUBLE)。 - 特殊处理 1D 模式(
klon_glo==1)的restartfi.nc创建。 - 特殊处理
tsoil/inertiesoil字段的 4D 写入(含坡面维度)。 timeindex由put_var_rgen中的Time变量写入时自动更新。
复现要点
- 必须确保
startfi.nc文件存在且包含所需字段。 - 并行环境下,所有 I/O 由主进程执行,数据通过 MPI 通信分发。
ind_cell_glo必须正确初始化,用于重排列顺序。restartfi.nc的维度定义必须与写入的数据匹配。timeindex在每次写入Time变量时自动递增。
待确认
first_time1d的特殊处理逻辑(行 480-484)是否正确处理了 1D 模式的重启。put_field_rgen中tsoil/inertiesoil的 4D 写入(行 900-905)是否正确处理了坡面维度。#ifdef NC_DOUBLE的默认行为(NF90_FLOAT)是否适用于所有编译环境。
相关页面
- phyetat0_mod:物理初始化,调用本模块读取
startfi.nc初始场。 - phyredem:物理重启输出,调用本模块写入
startfi.nc/restartfi.nc。 - soil_settings:土壤初始化设置,调用本模块读取土壤参数。
- config-system:配置系统,记录文件路径和参数。