solzenangle.F90

路径

LMDZ.MARS\util\solzenangle.F90

所属目录/模块

util

文件定位

solzenangle.F90 是一个离线 NetCDF 后处理程序,用于把 diagfi.ncconcat.ncstats.nc 类输出中的 3D/4D 变量插值到指定太阳天顶角对应的本地真太阳时。它常用于抽取晨侧或昏侧的掩星/晨昏线条件,例如 sza=90 度时的地表终止线。

程序不改变经纬度网格或垂直坐标。核心流程是先按日期、经度、纬度和目标太阳天顶角反解本地时 LTsolzenangle(lon,lat,Time),再沿输入文件的时间维对用户选择的变量做一维线性插值,输出 *_MO.nc*_EV.nc

定义的符号

符号 类型 行号 作用
solzenangle program 1 主程序:读取输入文件、变量列表、晨/昏侧和目标 SZA,创建输出 NetCDF 并插值变量。
initiate internal subroutine 861 创建输出 NetCDF 文件,定义坐标、TimeGCM_layers 和可选 controle
init2 internal subroutine 1076 从输入复制可选 aps/bps hybrid 坐标和 phisinit
def_var internal subroutine 1252 定义输出变量并写入 long_nameunits 属性。
missing_value internal subroutine 1302 valid_rangemissing_value 属性写到输出变量。
interpolf internal subroutine 1381 一维线性插值;目标点不在坐标范围内或邻点缺测时返回 missing。
LTsolzenangle internal subroutine 1428 由纬度、Ls、晨/昏侧和目标 SZA 反解本地真太阳时。
sol2ls internal subroutine 1483 把 sol 日期转换为太阳经度 Ls,单位为度。

依赖

依赖 用途
include "netcdf.inc" 使用旧式 NetCDF Fortran NF_* 接口读写输入和输出。

调用的关键例程

被调用例程 所在位置 作用
NF_OPEN / NF_CLOSE NetCDF 库 打开输入文件,关闭输入和输出文件。
NF_INQ_NVARS / NF_INQ_VARNAME / NF_INQ_VARNDIMS NetCDF 库 枚举变量、排除坐标/静态字段、确认 3D/4D 变量。
NF_INQ_DIMID / NF_INQ_VARID / NF_INQ_DIMLEN NetCDF 库 读取 latitude/longitude/altitude/Time/index/GCM_layers 维度和变量。
NF_GET_VAR_REAL / NF_PUT_VARA_REAL NetCDF 库 读取坐标、控制数组、输入变量,并写出插值后的变量。
NF_GET_ATT_TEXT / NF_GET_ATT_REAL / NF_PUT_ATT_* NetCDF 库 读取和写入 long_name/titleunitsmissing_valuevalid_range 等属性。
LTsolzenangle 本文件 反解目标 SZA 对应的本地真太阳时。
sol2ls 本文件 stats 输入时把 sol 日期换算到 Ls,供太阳赤纬计算使用。
interpolf 本文件 沿每个格点的时间序列做线性插值。

输入

输入 来源 类型/维度 单位 含义
输入文件名 stdin / solzenangle.def NetCDF 文件名 - diagfi.ncconcat.ncstats.nc 等。
变量列表 stdin / solzenangle.def all 或逐行变量名,空行结束 - 要插值到目标 SZA 本地时的变量;源码只处理 3D 或 4D 变量。
planetside stdin / solzenangle.def morningevening - 选择目标 SZA 位于当地正午之前还是之后。
sza stdin / solzenangle.def real scalar degree 目标太阳天顶角,源码要求 0 <= sza < 180
参考时间 stdin / solzenangle.def n、sol 值或 stats 平均 Ls sol 或 degree stats 文件可保留/覆盖起始 sol;stats 文件读取平均 Ls
latitude / longitude / altitude 输入 NetCDF 1D degrees / 输入属性 空间坐标;altitude 属性会复制到输出。
Time 输入 NetCDF 1D sol 或 stats 小时 输入时间轴;若属性为 Solar longitude,程序停止。
controle 输入 NetCDF 1D,可选 - 用于推导 startsol,存在时也复制到输出并可能更新 ctl(4)
GCM_layers 输入 NetCDF 维度,可选 - aps/bps 长度使用;不存在时取 altlen
aps/bps / phisinit 输入 NetCDF 可选 - init2 尝试复制到输出。

solzenangle.def 示例依次给出 diagfi.nctsurf/ps/temp、空行、morning900。其中注释说明 90 度代表地表终止线,>90 度可代表高空终止线条件。

输出

输出 去向 类型/维度 单位 含义
*_MO.nc 磁盘 NetCDF 文件 - morning 分支输出,输入文件去掉 .nc 后追加 _MO.nc
*_EV.nc 磁盘 NetCDF 文件 - evening 分支输出,输入文件去掉 .nc 后追加 _EV.nc
latitude / longitude / altitude 输出 NetCDF 1D 输入或固定属性 原坐标复制。
Time 输出 NetCDF unlimited 源码属性写成 calendar-like 字符串 stats 分支写整数 sol;stats 分支写 intsol*24
GCM_layers / aps / bps / phisinit 输出 NetCDF 可选 - 从输入复制的辅助坐标和地形字段。
用户选择变量 输出 NetCDF 3D (lon,lat,Time) 或 4D (lon,lat,alt,Time) 输入 units 插值到目标 SZA 对应本地时后的变量。
LTsolzenangle 输出 NetCDF (lon,lat,Time) hours 每个经纬度、sol 上目标 SZA 对应的本地真太阳时;无解时为 1E+20

副作用

核心逻辑

  1. 变量筛选:程序枚举输入文件中的所有变量,排除 Time/controle/rlonu/latitude/longitude/altitude/rlatv/aps/bps/ap/bp/soildepth/cu/cv/aire/phisinit 这 16 个字段;用户输入 all 时取其余变量,否则逐行读取变量名。
  2. 坐标和时间读取:要求存在 latitudelongitudealtitudeTimecontroleGCM_layers 可选。Timelong_nametitle 若等于 Solar longitude,程序停止,因为后续插值需要 sol 类时间轴。
  3. SZA 参数检查planetside 只能是 morningeveningsza 必须在 [0,180) 度。
  4. 确定季节日期
    • controle 时用 int(int(ctl(4))+int(time(1)+ctl(27))) 推导 startsol
    • controle 时用 int(time(1))
    • timelen==12time(1)==2time(last)==24,识别为 stats 文件,把时间小时除以 24,nsol=1,并从 stdin 读取平均 Ls
    • 其他文件按 nsol=int(time(last))-int(time(first)) 生成每个输出 sol。
  5. 反解目标本地时:对每个输出 sol、经度和纬度:
    • 晨侧先用 tmpsol=intsol+(6-lon/15)/24+startsol 估计用于计算 Ls 的日期。
    • 昏侧用 tmpsol=intsol+(18-lon/15)/24+startsol
    • stats 分支调用 sol2ls(tmpsol,tmpLs)
    • 调用 LTsolzenangle(lat,tmpLs,planetside,sza,miss_lt,tmpLT) 得到本地真太阳时小时。
  6. 创建输出和复制辅助字段initiate 写基本维度与坐标;init2 在可用时复制 aps/bps/phisinit
  7. 逐变量时间插值
    • 只处理 ndim>=3 的变量,ndim==3(lon,lat,time)ndim==4(lon,lat,alt,time)
    • 每个经度的输入本地时轴为 lt_gcm=time+lon/360
    • 目标 LTsolzenangle 小时被换成 lt_outc=intsol+LT/24
    • 单 sol 输入会在尾部追加周期点;多 sol 输入若目标点越界则把 lt_outlt_outc 置 missing。
    • interpolf 对每条时间序列线性插值。
  8. 写输出变量和属性:变量保留输入 long_name/titleunits;输入没有 missing_value 属性时,源码把 missing 设为 1E+20 并写回输出。
  9. LTsolzenangle 和全局注释:输出目标 SZA 对应的本地时变量,并在全局 comment 中说明可由 LTsolzenangle、经度和 Time 组合推回经度 0 度的 sol。

太阳天顶角反解公式

LTsolzenangle 使用固定火星倾角 obliquity=25.1919 度,先计算太阳赤纬:

declin = asin(sin(Ls) * sin(obliquity))

然后由源码注释中的太阳天顶角方程反解时角:

cos(sza) = sin(lat)*sin(declin)
         + cos(lat)*cos(declin)*cos(2*pi*(localtime/24 - 0.5))

程序实际计算:

tmpcos = cos(sza)/(cos(lat)*cos(declin)) - tan(lat)*tan(declin)

tmpcos 超出 [-1,1],视为极昼/极夜下无对应本地时,返回 missing。否则晨侧使用:

lt = 24 * (0.5 - acos(tmpcos)/(2*pi))

昏侧使用:

lt = 24 * (0.5 + acos(tmpcos)/(2*pi))

伪代码

read input file
list variables not in the 16-field skip list
read selected variables
read latitude, longitude, altitude, optional controle, and Time
reject Solar longitude time axis
read planetside and sza
derive startsol and detect stats case
for each output sol, longitude, latitude:
  estimate tmpsol at LT=6 or LT=18 for season
  if not stats: tmpLs = sol2ls(tmpsol)
  lt_out = LTsolzenangle(lat, tmpLs, planetside, sza)
create *_MO.nc or *_EV.nc
copy coords, optional controle, aps/bps, phisinit
for each selected 3D/4D variable:
  read full variable
  for each longitude:
    lt_gcm = time + lon/360
    convert lt_out hours to sol decimal lt_outc
    wrap one-sol inputs or mark out-of-range multi-sol targets missing
    interpolate each lat or lat-alt series with interpolf
  write variable and missing/valid_range attributes
write LTsolzenangle(lon,lat,Time)
write global comment and close files

参与的主题流程

主题 参与方式
util 后处理链 常接在 concatnczrecastlocaltime 类工具附近,用于把模型输出抽样到晨/昏侧指定 SZA。
观测/掩星比较链 sza=90 可模拟晨昏线或太阳掩星几何条件,输出的 LTsolzenangle 可检查每个格点实际抽样本地时。
太阳几何 solarlong 的主模式轨道换算不同,本文件内置 sol2ls 参数并直接用 SZA 几何公式反解本地时。

复现要点

待确认

复现风险

相关页面