simu_MCS.F90

路径

LMDZ.MARS\util\simu_MCS.F90

所属目录/模块

util

文件定位

MRO/MCS 观测模拟器(observer simulator)离线后处理工具。把 GCM 输出(diagfi.nc/concat.ncstats.nc)按 MRO/MCS 观测数据(Luca Montabone 分箱版)的时空采样和分箱方式重采样,生成一个与 MCS 文件同格式、同维度声明顺序的 netcdf 文件,用于 GCM 与 MCS 观测的逐 bin 对比。

核心思路:MCS 数据按 Ls 区间分箱。程序把每个 Ls 区间换算为 GCM 的 sol 区间,在该区间内对每个 MCS 空间 bin(经/纬/高)的若干 sol×当地时(LT)采样点做 GCM 场的四维线性插值,再平均成一个输出 bin 值。昼/夜(dayside/nightside)分两遍处理。还能计算柱积分尘埃光学厚度比 tau_ratio = tau_GCM/tau_MCS,用于归一化对比。

作者 Antoine Bierjon(2019-2020)。本文件是一个独立的 program(非 GCM 运行时模块),编译为命令行工具,通过 stdin 交互式读入文件名和变量列表。

定义的符号

符号 类型 行号 作用
simu_MCS program 1 MCS 观测模拟器主程序
extraction subroutine 1778 在 GCM 4D 场上对给定 (lon,lat,alt,sol) 做四维线性插值
inidim subroutine 2072 按 MCS 文件维度顺序初始化输出 netcdf 文件的维度
ls2sol subroutine 2290 太阳经度 Ls → sol 日期(开普勒方程反解)
gen_sol_list subroutine 2337 生成 sol×LT 采样点列表(围绕 LTave 均匀分布)
status_check subroutine 2426 netcdf 返回码检查,出错打印并 stop
LTmod function 2446 夜间 LT 从 [0,24) 映射到 [-12,12) 以保证午夜连续

依赖的模块

use 模块 only 列表 用途 待确认
netcdf (全部) netcdf 文件读写(主程序、inidimstatus_check 各自 use

无 LMDZ 物理模块依赖——本工具自包含,仅依赖 netcdf 库。

调用的关键例程

被调用例程 所在模块/文件 调用位置 作用
status_check 本文件 贯穿主程序 每个 netcdf 调用后检查返回码
ls2sol 本文件 行 460-461, 1393, 1400 Ls 边界换算为 sol 区间
inidim 本文件 section 1.3 初始化输出文件维度
gen_sol_list 本文件 行 1482 为每个 bin 生成 sol×LT 采样列表
extraction 本文件 行 1494 对每个采样点插值 GCM 场
LTmod 本文件 作为 f_LT 实参传入 gen_sol_list 夜间 LT 连续化

输入

输入 来源 类型/维度 单位 含义
obsfile stdin netcdf 文件 - MRO/MCS 观测数据(分箱),含 dtemp/ntemp、ddust/ndust、dwice/nwice、d/n numbin*、d/n timeave/max/min
gcmfile stdin netcdf 文件 - GCM 输出(diagfi/concat 或 stats),需含 temp、rho(算不透明度时)等 4D 场
变量列表 stdin 字符串 - 要重采样的 GCM 变量名(逐行,空行结束;或 all
outfile stdin 字符串 - 输出文件名

输出

输出 去向 类型/维度 单位 含义
outfile 磁盘 netcdf 文件 - GCM 数据按 MCS 分箱重采样的结果,昼/夜两套变量,格式同 MCS 文件
outvar outfile REAL (lon,lat,alt,Ls) 随变量 每个变量的分箱结果(无值处填 OBSmiss_val
tau_ratio outfile REAL (lon,lat,Ls) - 柱积分尘埃光学厚度比 tau_GCM/tau_MCS(仅压力坐标且有尘埃/温度时)

共享状态与副作用

核心逻辑

  1. 打开文件 + 读维度(section 1.1-1.2):交互读 obsfile/gcmfile;分别读 lon/lat/alt/time 维度。MCS 时间轴是 Ls,GCM 时间轴是 sol。由 altitude 的 units 属性判定坐标类型 'p'(Pa,压力)或 'z'(m,高度),两文件须一致。OBSdeltaLs = OBSLs(2)-OBSLs(1) 为 Ls bin 宽。

  2. 创建输出文件(section 1.3):用 inidim 按 MCS 维度顺序建 outfile 坐标。

  3. 变量管理(section 2):

    • 读 GCM 变量清单,跳过 15 个非处理变量(坐标/混合系数等);用户选变量或 all
    • 检测能否算不透明度:dso→dustok1、dsodust→dustok2、dustq→dustok3、h2o_ice→wiceok;若可,加载 rho(stats 文件只有部分 sol,循环填满所有 sol),并把 dust/wice 追加进待处理变量。
    • 昼/夜大循环开始:dayside 用 d* 变量、nightside 用 n* 变量。从 obsfile 读 LT 的均值/max/min(OBSLT/OBSLTmax/OBSLTmin)和各 bin 样本数 numbin(temp/dust/wice)。
  4. 变量循环(section 2.4-2.6):逐个待处理变量,通用读取 GCM 4D 场(stats 文件同样循环填充);dust/wice 不透明度由 dso/dsodust/dustq(×rho) 和 h2o_ice×rho 算出;读对应 MCS 参考变量与 numbin;在 outfile 定义该变量。

  5. 提取与分箱(section 3,四重坐标循环 Ls→lat→lon→alt):

    • 3.1:把 Ls bin [Ls-δ/2, Ls+δ/2] 经 ls2sol 换算成 sol 区间,定位 GCM 时间索引 m_minsol/m_maxsol(±0.5 sol 余量覆盖全经度);取区间内的整数 sol 列表 int_sol_list(共 solcount 个)。无 GCM 数据则该 Ls 填缺测。
    • lon 规整到 [-180,180];取该 bin 的观测 LT 均值 LT_val;缺测则跳过。
    • 3.2LTcount = floor(numbin) 为该 bin 的样本数;gen_sol_list 生成 solcount*LTcount 个 sol 采样点(每个整数 sol 配 LTcount 个围绕 LT_val 对称分布的 LT,换算到 lon=0° 的 sol:sol = int_sol + (LT - lon/15)/24)。
    • 3.3:对每个采样点调 extraction 插值;非缺测值累加,最后除以有效样本数得 solbinned_value 写入 outvar
    • 3.4:整变量写入 outfile,释放数组。
  6. CDOD ratio(section 4,仅 OBSalttype='p'):在 outfile 找尘埃不透明度(d/ndustd/nopa_dustd/nopadust 依次回退)、obsfile 找温度;用 OBS 温度+压力算 OBS 密度,按层积分得 GCM 与 MCS 柱光学厚度,算比值 tau_ratio 写入 outfile。

  7. 昼夜循环结束 + 关闭文件(section 5-6)。

伪代码

program simu_MCS:
  读 obsfile, gcmfile (stdin); 读 lon/lat/alt/time 维度
  由 altitude units 定 alttype ('p'/'z'); OBSdeltaLs = OBSLs(2)-OBSLs(1)
  inidim(outfile)                          // 按 MCS 维度顺序建输出
  读 GCM 变量清单 (跳过 15 个非处理变量); 用户选变量或 all
  检测 dust/wice 不透明度可行性; 若可: 加载 rho (stats 循环填充)

  for dayornight in [dayside, nightside]:   // 昼/夜大循环
    从 obsfile 读 OBSLT(ave/max/min), numbin(temp/dust/wice)
    for var in 待处理变量:                   // 变量循环
      读 GCM 4D 场 (stats 循环填充); 算 dust/wice 不透明度 (×rho)
      读对应 MCS 参考变量 + numbin; 在 outfile 定义该变量
      for l in Ls:                          // 坐标循环
        [Ls±δ/2] --ls2sol--> sol 区间 -> m_minsol/m_maxsol
        int_sol_list = 区间内整数 sol (solcount 个)
        for j in lat, i in lon:
          lon 规整 [-180,180]; LT_val = OBSLT(i,j,l)
          for k in alt:
            LTcount = floor(numbin); 若 0 -> 填缺测
            sol_list = gen_sol_list(int_sol_list, LTcount, LT_val, ...)  // solcount*LTcount 点
            for sol in sol_list:
              extraction(lon,lat,alt,sol, GCM_var) -> extr_value
              累加非缺测值
            outvar(i,j,k,l) = 累加 / 有效样本数
        outfile <- outvar
      if alttype=='p' 且有尘埃+温度:          // CDOD ratio
        tau_ratio = 柱积分(tau_GCM) / 柱积分(tau_MCS) -> outfile
  关闭文件

subroutine extraction(lon,lat,alt,sol, ..., field, ..., value):
  若坐标变化: 二分查找包围索引 (SAVE 缓存); 越界 -> value=missing 返回
  16 个角点任一为 missing -> 返回
  时间线性插值 -> 垂直插值 (rho/pressure 在 z 坐标下取 log) -> 纬度 -> 经度

参与的主题流程

主题 参与方式
GCM 验证/观测对比 离线工具:把 GCM 输出重采样到 MCS 观测的时空分箱,供逐 bin 对比
util-toolchain 观测比较链中的 MCS 分箱模拟器。

写法特点

复现要点

待确认

复现风险

相关页面