read_dust_scenario_mod.F90

快速理解

它做什么: 从 datadir 读 dust_*.nc NetCDF 场景文件,插值到 GCM 网格返回参考气压处可见光尘埃柱厚度。

基本过程: 首次打开文件缓存经纬/时间/tau → 按 zday 时间插值 + 经纬双线性插值 → 输出 tau_pref_scenario。

关键结果: tau_pref_scenario(ngrid),供 compute_dtau 生成注入目标和 dust_rad_adjust 生成辐射缩放目标。

路径

LMDZ.MARS\libf\phymars\read_dust_scenario_mod.F90

所属目录/模块

libf\phymars

文件定位

read_dust_scenario_mod.F90 定义尘埃场景读取模块 read_dust_scenario_mod(第 1 行)和例程 read_dust_scenario(第 7 行)。它在第一次调用时从 datadir 下打开由 iaervar 选择的 dust_*.nc NetCDF 场景文件,缓存经纬度、时间轴和三维柱光学厚度场;之后每次调用按当前 GCM 网格经纬度和 zday 做时间线性插值、经纬双线性插值,返回参考气压 odpref 处的可见光尘埃柱厚度 tau_pref_scenario(ngrid)。

该例程是尘埃观测场景约束的底层读表器:compute_dtau_mod 用它生成地表注入目标厚度,dust_rad_adjust_mod 用它生成仅辐射缩放目标厚度。它本身不修改 tracer 或辐射场,只把外部尘埃场景文件转换为当前物理网格上的可见光柱厚度。

定义的符号

符号 类型 行号 作用
read_dust_scenario_mod module 1 封装尘埃场景 NetCDF 读取与插值例程
read_dust_scenario subroutine 7 读取/缓存尘埃场景,按时间、经纬度插值输出 tau_pref_scenario
firstcall saved local logical 52 每线程首次调用时读取文件、分配并缓存场景数组
lat/lon/time saved allocatable arrays 49 场景文件中的纬度、经度和时间坐标
tautes saved allocatable array 50 场景文件中的三维尘埃柱光学厚度,维度为 (lonlen,latlen,timelen)
filename saved character 52 由 iaervar 派生的尘埃场景文件名
IRscenario saved logical 53 标记输入场景是否为红外吸收厚度,需要用 IRtoVIScoef 转可见光消光厚度

依赖的模块

use 模块 only 列表 用途 待确认
netcdf - nf90_open/inq_dimid/inquire_dimension/inq_varid/get_var/close/strerror 读取 NetCDF 场景文件 否
geometry_mod latitude, longitude 读取 GCM 物理网格经纬度,源码注释标明为弧度 否
datafile_mod datadir 拼出 trim(datadir)//"/"//trim(filename) 场景文件路径 否
dust_param_mod odpref, dustscaling_mode TES 历史文件参考气压修正;dustscaling_mode==2 时改写时间轴为逐 sol 整数 否
planete_h year_day dustinjection>0 或 dustscaling_mode==2 时校验场景时间长度等于火星年 sol 数 否
mod_phys_lmdz_transfert_para bcast 非 MESOSCALE 路径下把 master 读取的维度、数组和 IRscenario 广播给其他进程 否
callkeys_mod iaervar, dustinjection, swrtype 选择场景文件、决定是否重写时间轴、应用 Fouquart 旧短波方案修正 否

调用的关键例程

被调用例程 所在模块/文件 调用位置 作用
nf90_open / nf90_close NetCDF 第 100、216 行 打开并关闭尘埃场景 NetCDF 文件
nf90_inq_dimid / nf90_inquire_dimension NetCDF 第 112-124 行 定位 Time/time、latitude、longitude 维度并读取长度
nf90_inq_varid / nf90_get_var NetCDF 第 142-213 行 读取 dustop、cdod 或 cdodext,以及 Time、latitude、longitude
bcast mod_phys_lmdz_transfert_para 第 129-131、221-225 行 并行路径下广播维度、场景数组、坐标轴和 IR/VIS 标志
abort_physic 全局物理错误处理例程 第 109、149、160、168、181、191、205、213、246、299、372、382 行 文件、变量、时间长度、坐标或插值结果非法时终止运行

输入

输入 来源 类型/维度 单位 含义
ngrid 调用方 integer scalar - 当前物理网格点数
nlayer 调用方 integer scalar - 垂直层数;本例程只用来声明 pplev 维度
zday 调用方 real scalar sol 当前火星日;内部用 mod(zday,669.) 得到年内日
pplev(ngrid,nlayer+1) 调用方 real array Pa 层界面气压;当前源码中仅作为接口参数,未直接参与插值
IRtoVIScoef(ngrid) aeropacity/调用链 real array - 红外吸收柱厚度到可见光消光柱厚度的格点换算系数
iaervar callkeys_mod integer - 场景文件选择键:如 4/6/7/8/24-37/124-126
dustinjection callkeys_mod integer/logical-style - 大于 0 时要求场景每天一张图并把时间轴重写为整数 sol
dustscaling_mode dust_param_mod integer - 等于 2 时同样要求逐 sol 场景时间轴
swrtype callkeys_mod integer - 等于 1 时应用旧 Fouquart 短波方案补偿因子

输出

输出 去向 类型/维度 单位 含义
tau_pref_scenario(ngrid) 调用方 real array 无量纲 当前 GCM 网格上、参考气压 odpref 处的可见光尘埃柱光学厚度

共享状态与副作用

核心逻辑

  1. 首次调用选择并读取场景文件:按 iaervar 映射 dust_tes.nc、dust_cold.nc、dust_warm.nc、dust_clim.nc、dust_MYxx.nc 或 dust_tes_MYxx.nc(第 70-94 行),再从 datadir 打开文件。
  2. 读取维度和坐标:识别 Time 或 time 维度,读取 latitude、longitude 和时间轴长度;非 MESOSCALE 路径广播维度后分配缓存数组。
  3. 读取尘埃柱厚度变量:优先读 dustop 并标记为可见光场景;若没有 dustop,依次读 cdod 或 cdodext 并标记为红外场景。cdodext 会先除以 1.3 转为红外吸收厚度。
  4. 按需要重写时间轴:当 dustinjection>0 或 dustscaling_mode==2 时,要求 timelen==year_day,然后把 time(iloop) 写成 0..timelen-1,保证每日一张图的场景按整数 sol 索引。
  5. 逐 GCM 格点找四邻点:把 geometry_mod 的弧度经纬度转为度,纬度改成余纬;对略小于 -180 的经度做容差修正;定位上下纬度和左右经度,跨 180 经线时用 xsup=1/xinf=lonlen。
  6. 先时间插值、再水平双线性插值:对四个邻点分别在 tinf/tsup 两个时间层间线性插值,跨年时把分母写成 time(tsup)+(669-time(tinf));随后用 dlat/dlon 做双线性插值生成 tau。
  7. 单位/历史方案修正:若 IRscenario 为真,将 tau 乘 IRtoVIScoef(ig) 转为可见光厚度;旧 TES 文件再乘 1.3*(odpref/700.),swrtype==1 时再乘 0.825/1.3。

伪代码

realday = mod(zday, 669)

if firstcall:
    filename = select_by_iaervar(iaervar)
    open datadir/filename
    read lon/lat/time dimensions
    allocate tautes(lonlen,latlen,timelen), lon, lat, time

    if variable dustop exists:
        read tautes
        IRscenario = false
    else if variable cdod exists:
        read tautes
        IRscenario = true
    else:
        read cdodext into tautes
        tautes = tautes / 1.3
        IRscenario = true

    read Time, latitude, longitude
    if dustinjection>0 or dustscaling_mode==2:
        require timelen == year_day
        time = [0, 1, ..., timelen-1]
    broadcast cached fields on non-MESOSCALE builds

for each GCM grid point ig:
    convert latitude/longitude from radians to degrees
    find enclosing scenario latitudes and longitudes
    find enclosing scenario times, with wraparound across sol 669
    interpolate tau at four horizontal neighbours in time
    bilinear-interpolate the four tau values in latitude/longitude
    if IRscenario:
        tau_pref_scenario(ig) = tau * IRtoVIScoef(ig)
    else:
        tau_pref_scenario(ig) = tau

if filename begins with "dust_tes":
    tau_pref_scenario *= 1.3 * (odpref / 700)
if swrtype == 1:
    tau_pref_scenario *= 0.825 / 1.3

参与的主题流程

主题 参与方式
尘埃循环 为 prescribed dust scenario、dust injection 和 GCM v6 dust radiative adjustment 提供按格点插值后的目标柱厚度
辐射/气溶胶 输出可见光尘埃柱厚度,后续用于尘埃辐射缩放或目标约束;红外场景需通过 IRtoVIScoef 转换

写法特点

复现要点

待确认

相关页面