parse_traceur_file.F90
路径
LMDZ.MARS\libf\phymars\parse_traceur_file.F90
所属目录/模块
libf/phymars
文件定位
parse_traceur_file.F90 是旧格式 traceur.def 的解析接口模块。它不依赖外部 tracer 解析库,只按文件字面读取 tracer 数量、名称和父子关系,再把结果广播给所有 MPI 进程。它只在 tracer_mod 的 ini_tracer_mod 初始化阶段被调用。
同目录的 parse_tracer_file 处理新格式 tracer.def。tracer_mod 会先查找 traceur.def;只有旧格式文件不存在时才改用 tracer.def,因此两个文件同时存在时旧格式会优先生效。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
parse_traceur_file_mod |
module |
1 |
包裹旧格式 traceur.def 读取子程序的模块 |
get_nq_from_traceur_file |
subroutine |
7 |
从 traceur.def 第一行读取 tracer 总数 nq |
get_names_from_traceur_file |
subroutine |
29 |
读取 tracer 名称、父 tracer 名和每个 tracer 的子 tracer 数量 |
依赖的模块
| use 模块 |
only 列表 |
用途 |
待确认 |
mod_phys_lmdz_para |
is_master, bcast |
并行控制:只让 master 进程读文件,再广播 nq、noms、nqparents、nqchildren |
|
调用的关键例程
| 被调用例程 |
所在模块/文件 |
调用位置 |
作用 |
bcast |
mod_phys_lmdz_para |
行 23, 78-81 |
把 master 进程读到的 tracer 数量、名称和父子计数广播到所有进程 |
输入
get_nq_from_traceur_file
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
traceur.def |
运行目录文件 |
文本文件 |
— |
第一行必须是 tracer 总数 |
get_names_from_traceur_file
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
nq |
调用方,来自 get_nq_from_traceur_file |
integer |
— |
tracer 数量,也决定后续读取的行数 |
traceur.def |
运行目录文件 |
文本文件 |
— |
第一行后每行以 tracer 名开头,可选跟一个父 tracer 名 |
输出
get_nq_from_traceur_file
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
nq |
tracer_mod::ini_tracer_mod |
integer |
— |
tracer 总数 |
get_names_from_traceur_file
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
noms |
tracer_mod::ini_tracer_mod |
character(len=*)(nq) |
— |
tracer 名称数组 |
nqparents |
tracer_mod::ini_tracer_mod |
integer |
— |
没有父 tracer 字段的顶层 tracer 数量 |
nqchildren |
tracer_mod::ini_tracer_mod |
integer(nq) |
— |
每个 tracer 被其他行声明为 parent 的次数 |
共享状态与副作用
- 读运行目录中的
traceur.def,使用硬编码 Fortran unit 42。
- 只有
is_master 进程打开和解析文件;非 master 进程依赖后续 bcast 获取结果。
- 本模块不保存 module 变量,所有结果都通过参数返回。
- 源码未在
open/read 上使用 status='old'、iostat 或显式错误处理;文件是否存在由上游 tracer_mod::ini_tracer_mod 的 inquire 判断。
核心逻辑
get_nq_from_traceur_file(行 7-25)
- master 进程打开
traceur.def。
- 读取第一行到
nq。
- 关闭文件。
- 调用
bcast(nq),让所有进程拿到同一个 tracer 数量。
get_names_from_traceur_file(行 29-83)
- master 进程重新打开
traceur.def,先读掉第一行 tracer 总数。
- 初始化
nqparents=0 和本地 parent(:)=""。
- 循环读取后续
nq 行:
- 用
index(line," ") 找第一个空格;
- 第一个空格前的字段读入
noms(i);
- 如果整行去尾空格后长度等于名称长度,认为该 tracer 是 parent;
- 否则把第一个空格后的字符串作为
parent(i)。
- 双重循环统计每个
noms(i) 被多少个 parent(j) 引用,写入 nqchildren(i)。
- 逐个广播
noms(i),再广播 nqparents 和整个 nqchildren 数组。
伪代码
get_nq_from_traceur_file:
if master:
open traceur.def on unit 42
read first record as nq
close unit 42
bcast(nq)
get_names_from_traceur_file:
if master:
open traceur.def on unit 42
skip first record
nqparents = 0
parent[:] = ""
for i in 1..nq:
read full line
first_blank = first index of " "
noms[i] = text before first_blank
if trimmed line contains only noms[i]:
nqparents += 1
else:
parent[i] = text after first_blank
for i in 1..nq:
nqchildren[i] = count(parent[j] == noms[i] for j in 1..nq)
for i in 1..nq: bcast(noms[i])
bcast(nqparents)
bcast(nqchildren)
参与的主题流程
| 主题 |
参与方式 |
| tracer 配置体系 |
旧格式 traceur.def 的解析入口,为 tracer_mod 提供 tracer 数量、名称和父子关系 |
| 水循环配置 |
间接:旧格式 tracer 名称决定 h2o_vap、h2o_ice 等水相关 tracer 的索引 |
| CO2 循环配置 |
间接:旧格式 tracer 名称决定 co2、co2_ice 和 CO2 云相关 tracer 的索引 |
写法特点
- 旧格式优先:调用方先查
traceur.def,存在时不会再解析 tracer.def。
- 轻量解析:直接用 Fortran 内建
read 和字符串切片处理,不调用 readtracfiles_mod。
- master-only I/O:文件 I/O 集中在 master 进程,所有并行进程只接收广播结果。
- 空格分隔假设:源码用第一个普通空格拆分名称和 parent 字段,不按任意空白字符做健壮 tokenization。
复现要点
- 运行目录存在
traceur.def 时,tracer_mod 会使用本模块,而不是 parse_tracer_file。
- 第一行必须能读成整数
nq,后面必须至少有 nq 行 tracer 定义。
- 只有名称字段的行被计为 parent tracer;形如
child parent 的行会把 child 记为 tracer 名,把 parent 记为它的父 tracer。
- 所有进程最终依赖 master 广播结果;如果 master 读错或文件格式错,错误会传播到整个并行作业。
待确认
- 源码没有检查
open/read 返回状态;格式错误、行数不足或权限问题会以 Fortran 运行时错误还是静默错误出现,取决于编译器和运行环境。
index(line," ") 只找普通空格。制表符分隔、空行或前导空格在当前解析器中没有专门保护,复现时应按源码字面准备 traceur.def。
parent(i) 使用 character(len=50),而 noms(i) 的长度由调用方决定;极长 tracer 名或 parent 名是否会被截断需要结合实际配置文件确认。
相关页面