--- ## TLUSTY208.F 拆分工作 (2026-03-18) ### 任务:将单文件拆分为多个独立模块 **执行流程:** ```bash cd /home/fmq/program/tlusty/tl208-s54/rust python3 extract_fortran.py tlusty/tlusty208.f tlusty/extracted/ cp tlusty/*.FOR tlusty/extracted/ ``` ### 提取结果 | 项目 | 数量 | |------|------| | 程序单元 | **304** | | 子程序 (SUBROUTINE) | 269 | | 函数 (FUNCTION) | 32 | | 主程序 (PROGRAM) | 1 | | BLOCK DATA | **2** (含1个无名) | | 无 COMMON 依赖的纯函数 | 195 | > 注意: 2026-03-19 修复了无名 BLOCK DATA 提取问题,单元数从 303 增加到 304 ### Include 文件 ``` tlusty/extracted/*.FOR ├── IMPLIC.FOR # 隐式类型声明 ├── BASICS.FOR # 基本参数和物理常数 ├── ITERAT.FOR # 迭代控制参数 ├── ALIPAR.FOR # ALI 参数 ├── ATOMIC.FOR # 原子数据 ├── MODELQ.FOR # 模型物理量 ├── ODFPAR.FOR # ODF 参数 └── ARRAY1.FOR # 主工作数组 ``` ### 编译配置 **关键编译选项**: ```makefile FFLAGS = -O3 -fno-automatic -mcmodel=large ``` - `-mcmodel=large`: 支持 >2GB 地址空间 - `-fno-automatic`: 所有变量默认为静态存储(兼容旧Fortran代码) - **不要使用** `-ffixed-line-length-none`: 会将第73-80列的注释区当作代码解析 ### 编译验证 ```bash cd tlusty/extracted && make clean && make # 生成: tlusty_extracted (1,940,488 bytes) # 直接编译 gfortran -fno-automatic -mcmodel=large -O3 -o tlusty.exe tlusty208.f # 生成: tlusty.exe (1,997,416 bytes) ``` **结论**: 功能等价,拆分编译文件更小 (-2.9%) ### 拆分编译 vs 直接编译对比 | 方面 | 直接编译 | 拆分编译 | |------|---------|---------| | 文件大小 | 1,997,416 B | 1,940,488 B | | 功能 | 相同 | 相同 | | 增量编译 | ❌ | ✅ | | 代码定位 | 困难 | 简单 | ### 无 COMMON 依赖的纯函数 (198个) 可独立测试和重构的单元: ``` ACCEL2, ALIFR1, ALIFR3, ALIFR6, ALIFRK, ALISK1, ALISK2, ALIST1, ALIST2, ANGSET, BETAH, BHE, BKHSGO, BPOP, BPOPE, BPOPF, BPOPT, BRE, BREZ, BRTE, BRTEZ, BUTLER, CARBON, CEH12, CHANGE, CHCKSE, CHEAV, CHEAVJ, CIA_H2H, CIA_H2H2, CIA_H2HE, CIA_HHE, CION, CKOEST, COLH, COLHE, COLLHE, CONCOR, CORRWM, CROSS, CROSSD, CSPEC, DIELRC, DIETOT, DIVSTR, DMEVAL, DOPGAM, DWNFR, DWNFR0, DWNFR1, EINT, EMAT, ENTENE, ERFCIN, ERFCX, EXPINT, EXPINX, EXPO, FFCROS, GAMI, GAMSP, GAULEG, GAUNT, GETWRD, GFREE0, GFREE1, GFREED, GNTK, GRCOR, GREYD, GRIDP, H2MINUS, HEPHOT, HIDALG, IJALI2, IJALIS, INCLDY, INDEXX, INIFRS, INILAM, INTERP, INTHYD, INTLEM, INTXEN, IRC, LAGRAN, LAGUER, LEMINI, LEVGRP, LEVSET, LEVSOL, LINEQS, LINSEL, LINSET, LINSPL, LOCATE, LTEGR, LUCY, LYMLIN, MATGEN, MATINV, MEANOP, MEANOPT, MINV3, NEWPOP, NSTOUT, ODF1, ODFFR, ODFHST, ODFHYD, ODFHYS, ODFMER, OPACFL, OPADD0, OPAHST, OPAINI, OPCTAB, OSCCOR, OUTPUT, PFCNO, PFFE, PFHEAV, PFNI, PFSPEC, PRCHAN, PRD, PRDINI, PRINC, PRNT, PROFSP, PSOLVE, PZERT, QUARTC, QUIT, RADPRE, RAPH, RATES1, RATMAL, RATMAT, RATSP1, RAYINI, RAYSET, RDATAX, READBF, RECHCK, REFLEV, REIMAN, RHOEOS, RHONEN, ROSSOP, ROSSTD, RTEDF2, RTEFE2, RTESOL, RTE_SC, SABOLF, SBFCH, SBFHE1, SBFHMI, SBFHMI_OLD, SBFOH, SFFHMI, SFFHMI_ADD, SGHE12, SGMER0, SGMER1, SGMERD, SIGAVE, SIGK, SIGMAR, SPSIGK, SRTFRQ, STARK0, STARKA, SWITCH, SZIRC, TDPINI, TIMING, TIOPF, TLUSTY, TRAINI, TRIDAG, UBETA, VERN16, VERN18, VERN20, VERN26, VERNER, VISINI, VOIGT, VOIGTE, WN, WNSTOR, XENINI, XK2DOP, YINT, YLINTP, ZMRHO ``` --- ## SYNSPEC54.F 拆分工作 (2026-03-18) ### 任务:将单文件拆分为多个独立模块 **执行流程:** #### 1. 创建提取脚本 `extract_fortran.py` ```python # 核心功能: # - 正则匹配 SUBROUTINE/FUNCTION/PROGRAM/BLOCK DATA # - 查找对应的 END 语句确定边界 # - 提取到独立 .f 文件 # - 分析 COMMON 块依赖 # - 生成 Makefile ``` #### 2. 运行提取 ```bash cd /home/fmq/program/tlusty/tl208-s54/rust python3 extract_fortran.py synspec/synspec54.f synspec/extracted/ cp synspec/*.FOR synspec/extracted/ ``` #### 3. 提取结果 | 项目 | 数量 | |------|------| | 程序单元 | 168 | | 子程序 (SUBROUTINE) | 134 | | 函数 (FUNCTION) | 33 | | 主程序 (PROGRAM) | 1 | | 总代码行数 | 23,050 | | 无 COMMON 依赖的纯函数 | 93 | #### 4. 编译配置 **关键编译选项** (解决大型 COMMON 数组链接问题): ```makefile FFLAGS = -O3 -fno-automatic -mcmodel=large ``` - `-mcmodel=large`: 支持 >2GB 地址空间 - `-fno-automatic`: 所有变量默认为静态存储(兼容旧Fortran代码) - **不要使用** `-ffixed-line-length-none`: 会将第73-80列的注释区当作代码解析 #### 5. 编译验证 ```bash cd synspec/extracted && make clean && make # 生成: synspec_extracted (1,000,408 bytes) ``` **对比原始编译:** ```bash gfortran -O3 -fno-automatic -mcmodel=large -o synspec_direct.exe synspec54.f # 生成: synspec_direct.exe (1,044,928 bytes) ``` **结论**: 功能完全等价,拆分编译更小 (-4.3%) ### 生成的文件结构 ``` synspec/extracted/ ├── synspec.f # 主程序 (174行) ├── start.f # 子程序 (107行) ├── sbfhmi.f # H⁻ 光电离截面函数 (42行) ├── expint.f # 指数积分函数 (18行) ├── ... # 共168个 .f 文件 ├── PARAMS.FOR # 参数定义 (include) ├── MODELP.FOR # 模型参数 (include) ├── LINDAT.FOR # 谱线数据 (include) ├── SYNTHP.FOR # 合成谱参数 (include) ├── WINCOM.FOR # 窗口通信 (include) ├── Makefile # 自动构建 ├── _SUMMARY.txt # 提取摘要 ├── _COMMON_ANALYSIS.txt # COMMON 依赖分析 └── _PURE_UNITS.txt # 纯函数列表 ``` ### COMMON 块分析结果 **有 COMMON 依赖的单元**: 75 个 **唯一 COMMON 块**: 68 个 主要 COMMON 块: - `BLAPAR`, `LIMPAR` - 谱线参数 - `EMFLUX` - 辐射流 - `RTEOPA` - 辐射转移不透明度 - `NLTPOP` - 非LTE布居数 - `lasers` - 激光数据处理 ### 拆分编译 vs 直接编译对比 | 方面 | 直接编译 | 拆分编译 | |------|---------|---------| | 文件大小 | 1,044,928 B | 1,000,408 B | | 功能 | 相同 | 相同 | | 增量编译 | ❌ | ✅ | | 代码定位 | 困难 | 简单 | | 模块化重构 | 困难 | 容易 | ### 提取脚本位置 ``` extract_fortran.py ``` ### 推荐用法 ```bash # 开发/调试/重构 cd synspec/extracted && make # 生产环境/快速编译 cd synspec && gfortran -O3 -fno-automatic -mcmodel=large -o synspec.exe synspec54.f ``` ### 无 COMMON 依赖的纯函数 (93个) 可独立测试和重构的函数: ``` CARBON, CHANGE, CHCKAB, CIA_H2H, CIA_H2H2, CIA_H2HE, CIA_HHE, COUNT_WORDS, DENSIT, DIVHE2, DIVSTR, DWNFR0, DWNFR1, EPS, EXOPF, EXPINT, EXTPRF, FEAUTR, GAMHE, GAUNT, GETWRD, GFREE, GNTK, GRIEM, H2MINUS, H2OPF, HE2SET, HE2SEW, HEPHOT, HESET, HIDALG, HYDINI, HYDTAB, HYLSET, HYLSEW, INIBLM, INKUR, INPBF, INTERP, INTHYD, INTRP, INTXEN, IRWPF, ISPEC, LEVSOL, LINEQS, LOCATE, LYMLIN, MATINV, MOLOP, MPARTF, OPADD, PARTDV, PARTF, PFFE, PFHEAV, PFNI, PFSPEC, PHTX, QUIT, RATMAT, READBF, REIMAN, SABOLF, SBFCH, SBFHE1, SBFHMI, SBFHMI_OLD, SBFOH, SETRAY, SFFHMI, SFFHMI_OLD, SGHE12, SGMERG, SPSIGK, STARK0, STARKA, STARKIR, STATE0, SYNSPEC, TINT, TRIDAG, VELSET, VOIGTE, VOPF, WGTJH1, WN, WNSTOR, WTOT, XENINI, XK2DOP, YINT, YLINTP ``` --- ## 功能验证测试 (2026-03-19) ### 测试环境变量 ```bash export TL208=/home/fmq/program/tlusty export TLUSTY=$TL208/tl208-s54 export LINELIST=$TL208/linelist export IRON=$TL208/irondata export OPTABLES=$TL208/optables ``` ### 测试目录 ``` tests/tlusty/hhe/ # H-He 模型测试用例 ├── hhe35lt.5 # LTE 模型输入 ├── hhe35nc.5 # NLTE continua 模型输入 ├── hhe35nl.5 # NLTE with lines 模型输入 └── hhe35*.7,9,14 # 预期输出文件 ``` ### 测试流程 ```bash cd /home/fmq/program/tlusty/tl208-s54/rust/tests/tlusty # 创建测试目录 mkdir -p test_extracted cd test_extracted cp ../hhe/*.5 . ln -sf $TLUSTY/data data # 设置环境变量 export TL208=/home/fmq/program/tlusty export TLUSTY=$TL208/tl208-s54 export LINELIST=$TL208/linelist export IRON=$TL208/irondata export OPTABLES=$TL208/optables # 可执行文件路径 EXE=../../tlusty/extracted/build/tlusty_extracted # 测试1: LTE 模型 (从零开始) $EXE < hhe35lt.5 > hhe35lt.6 cp fort.7 hhe35lt.7; cp fort.9 hhe35lt.9; cp fort.14 hhe35lt.14 # 测试2: NLTE continua (使用 LTE 作为初始模型) cp hhe35lt.7 fort.8 $EXE < hhe35nc.5 > hhe35nc.6 cp fort.7 hhe35nc.7; cp fort.9 hhe35nc.9; cp fort.14 hhe35nc.14 # 测试3: NLTE with lines (使用 NC 作为初始模型) cp hhe35nc.7 fort.8 $EXE < hhe35nl.5 > hhe35nl.6 cp fort.7 hhe35nl.7; cp fort.9 hhe35nl.9; cp fort.14 hhe35nl.14 # 验证: 与原始结果比较 diff hhe35lt.7 ../hhe/hhe35lt.7 diff hhe35nc.7 ../hhe/hhe35nc.7 diff hhe35nl.7 ../hhe/hhe35nl.7 ``` ### 测试结果 | 测试用例 | 拆分编译 | 直接编译 | 原始结果 | |----------|----------|----------|----------| | hhe35lt (LTE) | ✓ 通过 | ✓ 通过 | ✓ 相同 | | hhe35nc (NLTE continua) | ✓ 通过 | ✓ 通过 | ✓ 相同 | | hhe35nl (NLTE lines) | ✓ 通过 | ✓ 通过 | ✓ 相同 | **MD5 校验和 (hhe35nl.7)**: ``` 01f3169947ca24bf1c989619b83ae8f2 ``` **结论**: 拆分编译与直接编译输出完全相同,功能验证通过 --- ## SYNSPEC54 功能验证测试 (2026-03-19) ### 测试目录 ``` tests/synspec/hhe/ ├── hhe35nl.5 # 输入文件 ├── hhe35nl.7 # 模型大气 (来自 TLUSTY 测试) ├── fort.55.con # 附加输入文件 ├── data # 数据目录路径文件 (内容: $TLUSTY/data) └── results/ # 预期输出 ├── hhe35nl.spec # 合成光谱 ├── hhe35nl.cont # 连续谱 └── hhe35nl.iden # 谱线标识 ``` ### 测试流程 ```bash cd /home/fmq/program/tlusty/tl208-s54/rust/tests/synspec/hhe # 设置环境变量 export TL208=/home/fmq/program/tlusty export TLUSTY=$TL208/tl208-s54 export LINELIST=$TL208/linelist export IRON=$TL208/irondata export OPTABLES=$TL208/optables # 准备输入文件 cp hhe35nl.7 fort.8 ln -sf fort.55.con fort.55 ln -sf $TLUSTY/data/gfATO.dat fort.19 # 关键: data 必须是符号链接指向数据目录 rm -f data ln -sf $TLUSTY/data data # 可执行文件路径 EXE_ORIG=$TLUSTY/synspec/synspec.exe EXE_DIRECT=../../synspec/synspec_direct.exe EXE_EXTRACTED=../../synspec/extracted/build/synspec_extracted # 测试原始版本 $EXE_ORIG < hhe35nl.5 > hhe35nl_orig.log cp fort.7 hhe35nl_orig.spec; cp fort.17 hhe35nl_orig.cont # 测试直接编译版本 rm -f fort.7 fort.17 fort.12 $EXE_DIRECT < hhe35nl.5 > hhe35nl_direct.log cp fort.7 hhe35nl_direct.spec; cp fort.17 hhe35nl_direct.cont # 测试拆分编译版本 rm -f fort.7 fort.17 fort.12 $EXE_EXTRACTED < hhe35nl.5 > hhe35nl_extracted.log cp fort.7 hhe35nl_extracted.spec; cp fort.17 hhe35nl_extracted.cont # 验证 diff hhe35nl_orig.spec hhe35nl_direct.spec diff hhe35nl_orig.spec hhe35nl_extracted.spec # 恢复 data 文件 rm -f data echo "/home/fmq/program/tlusty/tl208-s54/data" > data ``` ### 测试结果 | 测试用例 | 原始程序 | 直接编译 | 拆分编译 | |----------|----------|----------|----------| | hhe35nl (NLTE lines) | ✓ 通过 | ✓ 通过 | ✓ 相同 | **MD5 校验和 (hhe35nl.spec)**: ``` 7925533b21b16d6bcdfff40e626cab83 ``` **注意事项**: - `data` 文件/符号链接必须正确设置,否则报错 `Cannot open file './data/h1.dat': Not a directory` - 拆分编译程序与原始程序输出完全相同,功能验证通过