abort_physic.F90
源码路径:LMDZ.COMMON-6.3\LMDZ.COMMON\libf\phy_common\abort_physic.F90 Mars 运行参与度:条件经过。COMMON 本体、Mars phymars 和 Mars aeronomars 都把运行时致命错误汇入本例程。
文件职责
abort_physic(modname,message,ierr) 是物理侧统一终止入口。它负责把调用方名称、错误原因和严重级别写到 print_control_mod:lunout,在 IOIPSL 构建下关闭 history/restart 输出并 dump getin 配置,然后在非零 ierr 时终止当前物理 communicator。
源码注释写成 "Stops the simulation cleanly",但实际分支更窄:只有 ierr /= 0 才进入 MPI_ABORT 或 stop 1;ierr == 0 只打印 Everything is cool! 后返回。
例程清单
| 例程 | 输入 | 输出/副作用 |
|---|---|---|
abort_physic(modname,message,ierr) |
modname 调用方名称;message 诊断文本;ierr 严重级别,源码注释称 0 为 normal |
写 lunout;IOIPSL 构建下关闭 hist/restart、rank 0 dump getin;非零 ierr 时 MPI abort 或 stop 1。 |
本文件没有模块级状态、SAVE 变量、allocatable 数组或显式 THREADPRIVATE 数据。
依赖
| 依赖 | 条件 | 用途 |
|---|---|---|
IOIPSL |
CPP_IOIPSL |
提供 histclo、restclo 和 getin_dump。 |
ioipsl_getincom |
非 CPP_IOIPSL |
本地 fallback 只保证 getin_dump 符号可见;调用 getin_dump 的代码块仍在 CPP_IOIPSL 内。 |
mod_phys_lmdz_para |
总是 USE |
提供 mpi_rank 和 COMM_LMDZ_PHY。 |
print_control_mod, ONLY: lunout |
总是 USE |
决定诊断输出 unit。 |
MPI_ABORT |
CPP_MPI 且 ierr /= 0 |
在 COMM_LMDZ_PHY 上用错误码 1 终止并行物理侧。 |
控制流程
write(lunout,*) "in abort_physic"
if CPP_IOIPSL:
!$OMP MASTER
call histclo
call restclo
if mpi_rank == 0:
call getin_dump
!$OMP END MASTER
write stopping module and reason
if ierr == 0:
write "Everything is cool!"
return
else:
write "Houston, we have a problem, ierr =", ierr
if CPP_MPI:
!$OMP CRITICAL (MPI_ABORT_PHYSIC)
call MPI_ABORT(COMM_LMDZ_PHY, 1, ierror_mpi)
!$OMP END CRITICAL (MPI_ABORT_PHYSIC)
else:
stop 1
两个预处理边界要分清:
histclo/restclo/getin_dump只在CPP_IOIPSL构建中执行;非 IOIPSL fallback 虽然USE ioipsl_getincom,但不会进入 dump 调用块。MPI_ABORT只在CPP_MPI构建中执行;否则非零ierr走 Fortranstop 1。
并行和 OpenMP 语义
- IOIPSL 关闭和
getin_dump被包在!$OMP MASTER内,避免所有 OpenMP 线程重复关闭和 dump。 getin_dump还要求mpi_rank == 0,因此并行运行中只有物理侧 rank 0 写配置 dump。- MPI abort 被
!$OMP CRITICAL (MPI_ABORT_PHYSIC)包住,避免同一进程多个线程同时调用MPI_ABORT。 !$OMP MASTER后没有显式 barrier;非 master 线程可以继续执行后续打印/abort 分支。实际终止时机取决于调用点是否本来位于串行区、OpenMP 并行区或只有 master 调用。
COMMON 调用点
| 文件 | 条件 | 传入参数 |
|---|---|---|
phy_common/mod_phys_lmdz_omp_data.F90 |
OpenMP 初始化中发现 OMP_MASTER 线程号不是 0 |
abort_physic(modname,'ANORMAL : OMP_MASTER /= 0',1) |
misc/wxios.F90 |
wxios_set_cal 遇到未知 calendrier |
abort_physic('Gcm:Xios','wxios_set_cal: Mauvais choix de calendrier',1) |
misc/handle_err_m.F90 |
NetCDF95 fatal error;若传入 ncid,先尝试 nf90_close(ncid) |
abort_physic('NetCDF95 handle_err','',1) |
这些 COMMON 调用点都传 ierr=1,即进入终止分支。
Mars 调用模式
Mars physics 和 aeronomy 侧把很多运行时一致性检查汇入本例程。代表性类别如下:
| Mars 范围 | 典型文件/条件 | 说明 |
|---|---|---|
| 主 physics 同步 | phymars/physiq_mod.F |
pday 与 day_ini 不一致、callslope=true 但 nslope.ne.1、turb_resolved 和 calldifv 组合不合法。 |
| aerosol/dust 数据 | phymars/aeropacity_mod.F, read_dust_scenario_mod.F90, suaer.F90 |
iaervar 非法、dust opacity 需要但没有 rescaling、dust/aerosol 输入文件或坐标变量异常。 |
| physics restart/startfi | phymars/iostart.F90, phyetat0_mod.F90, surfini_mod.F90 |
NetCDF 定义、读写、字段维度、surface/startfi 缺失或变量不可读。 |
| tracer/微物理 | phymars/tracer_mod.F90, callsedim_mod.F, co2cloud_mod.F90, watercloud_mod.F |
必需 tracer 缺失、同位素配置非法、云/沉降数组条件异常。 |
| 诊断输出 | writediagfi.F, writediagmicrofi.F, writediagsoil.F90, wstats_mod.F90, xios_output_mod.F90 |
诊断文件创建、变量定义、写入或维度检查失败。 |
| aeronomy/chemistry | aeronomars/calchim_mod.F90, photochemistry_mod.F90, chemistrydata.F90, chemthermos_readini.F |
chemistry tracer 缺失、photolysis table 缺失、LAPACK/数组维度错误、chemthermos_reactionrates.def 缺失。 |
源码检索到的活动调用主要传 ierr=1;未发现直接传入字面量 0 的 COMMON/MARS 调用点。
复现和排障要点
- 先确认
lunout。诊断输出不会固定写到 stdout,而是跟随print_control_mod:lunout,其初始化由 print-control-abort 说明。 - 若要验证 IOIPSL 收尾,必须使用
CPP_IOIPSL构建;否则不会执行histclo/restclo/getin_dump。 - 若要验证 MPI 终止,必须使用
CPP_MPI构建,并确认COMM_LMDZ_PHY已由 mod_phys_lmdz_para 初始化。 - 在并行日志中只期待 rank 0 的
getin_dump,但不要假设只有一个线程会打印错误文本;这取决于调用点的 OpenMP 上下文。 ierr=0是正常信息路径,不会终止。用它做“clean stop”测试会得到返回调用方的行为。
待确认
histclo/restclo的具体关闭顺序和失败处理属于 IOIPSL 外部库行为,本页只记录本文件发出的调用。- 源码检索未发现字面量
ierr=0调用;若某些间接封装以变量传入 0,需要在对应调用方页继续确认。