aeropt_mod.F90
路径
LMDZ.MARS\util\aeropt_mod.F90
所属目录/模块
util
文件定位
aeropt_mod.F90 是 util/aeroptical.F90 使用的气溶胶光学性质表模块。它不直接读写 GCM NetCDF 诊断场,而是读取外部 ASCII 光学性质表,把波长轴、粒径轴、消光效率 Qext 和单次散射反照率 omeg 缓存在模块变量中,并为 aeroptical 提供按目标波长和有效半径插值的接口。
该模块是离线气溶胶光学厚度计算链的支撑层:aeroptical 负责读取 GCM 变量和写 NetCDF 输出,aeropt_mod 负责光学表读取、查表插值、日志文件和缓存释放。
定义的符号
| 符号 |
类型 |
行号 |
作用 |
aeropt_mod |
module |
4 |
保存光学性质表状态并提供读取、插值、日志和释放例程。 |
nwvl |
saved module variable |
8 |
光学性质表中的波长数量。 |
nsize |
saved module variable |
9 |
光学性质表中的粒径数量。 |
wvl |
allocatable saved array |
10 |
波长轴,单位 m。 |
radiusdyn |
allocatable saved array |
11 |
有效半径/粒径轴,单位 m。 |
Qext |
allocatable saved array |
12 |
消光效率二维表,维度 (nwvl,nsize)。 |
omeg |
allocatable saved array |
13 |
单次散射反照率二维表,维度 (nwvl,nsize)。 |
aeroptlogfileID |
saved module variable |
15 |
越界有效半径等日志信息写入的 Fortran unit,默认 100。 |
read_optpropfile |
subroutine |
20 |
读取 ASCII 光学性质文件并填充模块数组。 |
interp_wvl_reff |
subroutine |
206 |
对 Qext/omeg 先按有效半径、再按波长做线性插值。 |
end_aeropt_mod |
subroutine |
345 |
释放已分配的光学性质数组。 |
create_logfile |
subroutine |
367 |
创建或覆盖 aeroptical 运行日志文件。 |
依赖
| 依赖 |
用途 |
use netcdf |
出现在 read_optpropfile 和 interp_wvl_reff 中;本文件当前未调用 NetCDF API,推测为与调用程序或历史版本保持一致。 |
| Fortran formatted I/O |
INQUIRE、OPEN、READ、BACKSPACE、CLOSE 读取 ASCII 光学表,OPEN(...STATUS='replace') 创建日志。 |
调用方
| 调用方 |
调用点 |
作用 |
aeroptical.F90 |
use aeropt_mod |
主程序依赖本模块全部接口和模块变量。 |
aeroptical.F90 |
CALL create_logfile(aeroptlogfile) |
为每种 aerosol 创建 aeropt_log_<name>.txt。 |
aeroptical.F90 |
CALL read_optpropfile(datadir,optpropfile_aer(iaer)) |
读取对应 aerosol 的 ASCII 光学性质表。 |
aeroptical.F90 |
CALL interp_wvl_reff(...) |
对每个格点/层/时间的有效半径插值得到 Qext/omeg。 |
aeroptical.F90 |
CALL end_aeropt_mod |
每个 aerosol 处理结束后释放表缓存。 |
输入
| 输入 |
来源 |
类型/维度 |
单位 |
含义 |
datadir |
read_optpropfile 参数 |
字符串 |
- |
光学性质 ASCII 文件所在目录。 |
optpropfile |
read_optpropfile 参数 |
字符串 |
- |
ASCII 光学性质文件名。 |
| 光学性质 ASCII 文件 |
datadir/optpropfile |
文本 |
- |
非注释行依次包含 nwvl、nsize、wvl、radiusdyn、每个粒径一行的 Qext、每个粒径一行的 omeg。 |
wvl_val |
interp_wvl_reff 参数 |
标量 |
m |
要插值的参考波长。 |
reff_val |
interp_wvl_reff 参数 |
标量 |
m |
要插值的有效半径。 |
missval |
interp_wvl_reff 参数 |
标量 |
调用方约定 |
输入半径缺测或越界时输出的缺测值。 |
filename |
create_logfile 参数 |
字符串 |
- |
要创建的日志文件名。 |
输出
| 输出 |
去向 |
类型/维度 |
单位 |
含义 |
wvl |
模块数组 |
(nwvl) |
m |
光学表波长轴。 |
radiusdyn |
模块数组 |
(nsize) |
m |
光学表有效半径轴。 |
Qext |
模块数组 |
(nwvl,nsize) |
无量纲 |
消光效率查找表。 |
omeg |
模块数组 |
(nwvl,nsize) |
无量纲 |
单次散射反照率查找表。 |
Qext_val |
interp_wvl_reff 输出 |
标量 |
无量纲或 missval |
插值后的消光效率。 |
omeg_val |
interp_wvl_reff 输出 |
标量 |
无量纲或 missval |
插值后的单次散射反照率。 |
| 日志文件 |
磁盘 ASCII |
文本 |
- |
记录有效半径越界等 warning。 |
副作用
read_optpropfile 会分配并覆盖模块级缓存 wvl/radiusdyn/Qext/omeg;调用前若已有分配,本例程没有先释放。
- 光学表文件不存在、维度行或数据行读取失败、参考波长越界时直接
stop。
- 有效半径越界不会停止,而是向
aeroptlogfileID 对应日志写 warning,并把 Qext_val/omeg_val 设为 missval。
create_logfile 使用 STATUS='replace',同名日志会被覆盖。
核心逻辑
读取光学性质表
- 用
INQUIRE(FILE=datadir//'/'//optpropfile) 检查文件是否存在。
- 打开 formatted ASCII 文件。
- 第一轮扫描跳过以
# 或空格开头的行,读取两个非注释数据项:
- 分配
wvl(nwvl)、radiusdyn(nsize)、Qext(nwvl,nsize)、omeg(nwvl,nsize)。
- 第二轮继续跳过注释/空行,依次读取:
wvl(:);
radiusdyn(:);
nsize 行 Qext(:,isize);
nsize 行 omeg(:,isize)。
- 关闭文件并打印波长、半径范围。
插值
- 在
wvl 中找到包围 wvl_val 的 iwvl1/iwvl2。若 wvl_val 超出表范围,打印错误并 stop。
- 在
radiusdyn 中找到包围 reff_val 的 isize1/isize2。
- 若
reff_val==missval,直接输出缺测。
- 若
reff_val 超出半径表范围,写日志 warning,输出缺测。
- 否则对
Qext 和 omeg 分别做两步线性插值:
- 先在固定
iwvl1 和 iwvl2 上沿有效半径插值;
- 再沿波长插值到
wvl_val。
伪代码
read_optpropfile(datadir, optpropfile):
require datadir/optpropfile exists
open formatted file
skip comments/blank-leading lines
read nwvl, nsize
allocate wvl, radiusdyn, Qext, omeg
skip comments/blank-leading lines
read wvl(:)
read radiusdyn(:)
for each size: read Qext(:, size)
for each size: read omeg(:, size)
close file
interp_wvl_reff(wvl_val, reff_val, missval):
find bracketing wavelength indices, stop if wavelength out of range
if reff_val is missing: return missval
find bracketing radius indices
if radius out of range: log warning and return missval
interpolate Qext and omeg in radius, then wavelength
参与的主题流程
| 主题 |
参与方式 |
| util 气溶胶诊断链 |
为 aeroptical.F90 提供光学表读取和查表插值。 |
| 辐射/气溶胶后处理 |
将外部光学性质表转成每个格点有效半径对应的 Qext/omeg,供离线不透明度计算。 |
复现要点
- ASCII 光学表必须按源码读取顺序组织;注释行只能用
# 开头,源码也跳过首字符为空格的行。
wvl 与 radiusdyn 必须按升序排列;插值查找逻辑假定数组递增。
wvl_val 必须在表范围内,否则程序停止;reff_val 越界只写日志并输出缺测。
- 调用
interp_wvl_reff 前必须已经调用 read_optpropfile,否则模块数组未分配。
- 处理多个 aerosol 时应在切换表前调用
end_aeropt_mod 或确保上一表缓存已释放。
待确认
read_optpropfile 内声明 iwvl 但未使用,属于无害冗余还是历史残留需确认。
use netcdf 在本文件中未见 NetCDF API 调用,是否仍需要该依赖需确认。
- 注释称
create_logfile 的 Purpose 为 “Deallocate module variables”,与实际创建日志不一致。
- 如果重复调用
read_optpropfile 而未先释放已分配数组,Fortran 对已分配 allocatable 再 ALLOCATE 的行为会导致运行时错误;调用方当前在 aerosol 循环末尾调用 end_aeropt_mod,但异常路径不会释放。
复现风险
- 光学表格式稍有变化会导致读取错误或数据错位。
- 半径越界不会中止,只会把该点光学性质设为缺测;后续 NetCDF 输出中可能出现空间缺口。
- 日志文件使用固定 unit 范围,由调用方设置
aeroptlogfileID=100+iaer,多处并行或嵌套调用需避免 unit 冲突。
相关页面