SpectraRust/docs/sp_fortran.md
2026-03-19 22:16:23 +08:00

404 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
## 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`
- 拆分编译程序与原始程序输出完全相同,功能验证通过