Files
DCTS/.agents/skills/tlusty-synspec-test/references/directory-convention.md
T
fmq b058e66722 feat(all): NaN 伪收敛否决与 nl_tight 能量回退、emflux 检验 4π 修正、nst 行宽与种子边界修复、gfATO 谱线表接通与网格加密 9216 点、阶段分项统计与跳板机部署
物理修复(400 失败点归因,见 docs/failed400_nan_pseudo_convergence_2026_08_17.md):
- runner: 阶段 converged 后复查 fort.7,含 NaN/Inf 即否决(fort.9 全零伪收敛,
  曾致 261 点误跳过 nl_direct 回退);否决阶段不产出种子,阻断污染传播
- runner: nl_tight 回退——仅能量边际失败时以 CHMAX 收紧 10× 从自身模型续迭代,
  残差降幅 ~10×;execute_tlusty_stage 抽取供主链与回退共用
- conv_check: fort.14 为 Eddington 通量 Hλ,积分需乘 4π 再比 σTeff⁴
  (旧版 ratio 稳定 0.0796=1/4π,全点系统性假阳性)+ 回归测试
- nst_writer: 单行超 80 字符被 TLUSTY 静默截断,IFALI/JALI/TRAD 等从未生效;
  按 75 字符自动换行
- seed_finder: Teff 容忍度改含边界 <=,相邻 5000K 档恢复互为种子 + 回归测试

谱线表与网格:
- 默认线表 gfVIS99 → gfATO(全波段 18-23000Å),TaskSpec.linelist 支持工作流
  级覆盖,节点按需下载(进程互斥锁防并发重复下载 238MB)
- sdB_cno Teff 加密至 5000K 步长,432 → 9216 点;tlusty/synspec 静态二进制更新

统计与部署:
- grid 汇总改按 tlusty_status/synspec_status 分项计数,新增 tlusty_failed/
  synspec_failed/synspec_pending,前端详情页双视图适配
- deploy/fetch_results 支持跳板机 ProxyJump 与 SSH 主连接复用,fetch 新增 --force;
- Docker 构建支持 CARGO_MIRROR/USE_MIRRORS 国内镜像参数;移除 tools/ 拷贝
- 新增 tlusty-synspec-test skill 与 6 篇根因分析/验证文档
2026-08-17 23:55:26 +08:00

165 lines
7.5 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.
# 测试目录结构、命名与文档模板
参考:`docs/testing_workflow_2026_08_11.md`、现有测试 `dcts/test/20260811_tlusty_divergence/``dcts/test/20260812_synspec_fullband/`
## 四级目录结构
每次测试在 `dcts/test/` 下建独立子目录,禁止在 test 根或共享目录直接执行。
```
dcts/test/
├── {test_id}/ # 1层:本次测试唯一目录({日期}_{目的})
│ └── {type}/ # 2层:测试类型
│ └── {grid}/ # 3层:网格/参数区
│ └── {content}/ # 4层:测试内容(测试变量)
│ ├── inputs/ # 输入文件(执行前生成并检查)
│ ├── scripts/ # run.sh(必有)
│ ├── run/ # 执行工作目录(fort.* 在此生成)
│ └── outputs/ # 阶段产物(按阶段重命名)+ RESULT.md
```
`new_test.sh` 会自动建这四级并把对应模板拷成 `scripts/run.sh`
## 命名规范
| 层 | 规则 | 示例 |
| ----------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------- |
| `test_id` | `{日期}_{目的}` | `20260813_tlusty_divergence` |
| `type` | `convergence`(收敛) / `physics`(物理解) / `synspec`(光谱) / `validation`(校验复现) | `convergence` |
| `grid` | `t{teff}_g{logg}_he{loghe}` + 链后缀;可追加 CNO | `t60000_g5.0_he-2_cold``t55000_g5.0_he-4_seed``t50000_g5.0_cno` |
| `content` | 描述测试变量 | `baseline``itek0_iacc0_dpsilg15``niter50``nd70``gfato_100_20000` |
- **链后缀**:冷启动链 `_cold`,种子链 `_seed`
- 脚本统一 `run.sh`;输入文件按链类型命名(见 `references/tlusty-stages.md`)。
## 阶段文件重命名规范(关键)
TLUSTY 每阶段都写同名 `fort.*`,**必须每阶段执行后立即重命名**,否则被下阶段覆盖。
| 阶段产物 | 重命名 | 说明 |
| ------------------------- | -------------- | ----------------------------------------- |
| `fort.6` (stdout) | `{stage}.6` | `lte.6`/`nc.6`/`nl.6`/`seed_nc.6` |
| `fort.7` (模型) | `{stage}.7` | 事后温度结构审查的输入 |
| `fort.9` (迭代收敛记录) | `{stage}.9` | 事后收敛轨迹审查的输入 |
| `fort.14` (stderr) | `{stage}.14` | — |
**种子传递**:下一阶段 `fort.8` = 上一阶段 `fort.7` 的复制(冷启动 lte 阶段删 `fort.8`)。
### 执行后 run/ 目录状态(冷启动链)
```
run/
├── fort.6 fort.7 fort.9 fort.14 # 末阶段(nl)产物
├── lte.6 lte.7 lte.9 lte.14 # lte 阶段(已重命名)
├── nc.6 nc.7 nc.9 nc.14 # nc 阶段
├── nl.6 nl.7 nl.9 nl.14 # nl 阶段
├── data -> assets/data/ # 原子数据软链
└── fort.8 # 种子(若在种子链)
```
## 执行前检查清单(TLUSTY 冷启动链)
执行前对 `inputs/` 逐项确认(`check_inputs.py` 自动做):
- [ ] `lte.5` 第2行 `T T``nc.5`/`nl.5` 第2行 `F F`
- [ ] `.5` 第3行 `'nst'` 与实际 nst 文件名一致(生产默认 `nst`
- [ ] ions 行 `ilvlin`:nc 阶段=0nl 阶段非裸核=100,裸核(nlevs=1)=0
- [ ] nst 第1行含 `NITER=`;第2行 `ORELAX/IACC/ICHANG/IELCOR` 正确;DPSILG 注入值(若有)
- [ ] `data/` 软链指向 `assets/data/`
- [ ] **冷启动链确认无 fort.8**;种子链确认 `fort.8` 存在且无 NaN
建议再加一次冒烟(`timeout 30` 跑 lte),确认 fort.6 回显的 NITER/ITEK/DPSILG 与输入一致。
## 超时与并行
- 不需要超时限制
- 每个 tlusty 进程 ~260MB,按可用内存控制并行度
- 多测试并行时各日志独立(`scripts/run.log` 或外部日志)
## RESULT.md 模板
每个 `{content}/outputs/``RESULT.md`(模板见 `assets/result_template.md`)。核心是**诚实区分数值收敛与物理收敛**:
```markdown
# {test_id} / {type} / {grid} / {content}
## 目的
一句话说清这次测试想验证什么。
## 配置
- 二进制: dcts/assets/tlusty_static(或 synspec_static
- 网格: t{teff}_g{logg}_he{loghe}[_cno]
- 链: 冷启动 lte→nc→nl / 种子 seed_nc→nl / SYNSPEC
- 变体: {ITEK}/{IACC}/{DPSILG}/{ORELAX}/{NITER}(与 baseline 不同的关键参数)
## 输入
- inputs/ 生成方式: 代码生成 / 模板修改(留 diff)
- 关键参数: ...
## 执行
- 命令: bash scripts/run.sh
- 各阶段: lte(rc=0) → nc(rc=0) → nl(rc=?)
- 耗时: ...
## 结果(TLUSTY
| 阶段 | 迭代 | 末 max_relc | STOP | NaN | 温度结构 |
|---|---|---|---|---|---|
| lte | 0 | — | — | 0 | — |
| nc | 10 | 1.4e0 | 无 | 0 | 物理 |
| nl | 19 | 1.2e16 | STOP iter19 | 0 | 物理(停止时) |
## 结果(SYNSPEC,若适用)
| 指标 | 值 |
|---|---|
| 采样点数 | N |
| 波长范围 | ALAM0 ALAST Å |
| NaN/Inf/坏行 | 0 |
| 分段 NaN | EUV/UV/可见/NIR 各段计数 |
## 审查结论
- 数值: ❌/✅(max_relc 是否达标;有无 STOP/雪崩)
- 物理: ❌/✅(温度结构三项:表层<3×Teff、各深度∈[10,1e8]、无 NaN
- 结论: 一句话。区分"数值收敛"与"物理收敛"——只有后者才是真正成功。
## 复现
cd dcts/test/{test_id}/{type}/{grid}/{content}
bash scripts/run.sh
```
## 完整示例(参考现有测试)
```
dcts/test/20260811_tlusty_divergence/
└── convergence/
├── t60000_g5.0_he-2_cold/
│ ├── baseline/ # 生产配置复现
│ │ ├── inputs/ (lte.5 nc.5 nl.5 lte.nst nc.nst nl.nst)
│ │ ├── scripts/ (run.sh)
│ │ ├── run/
│ │ ├── outputs/
│ │ └── README.md
│ └── itek0_iacc0_dpsilg15/ # 修复变体
│ └── ...
├── t60000_g5.0_he-2_seed/
│ └── doubleoff_dpsilg15/ # 种子链变体
│ └── ... (inputs 含 fort.8)
└── t55000_g5.0_he-4_cold/
└── itek0_iacc0_dpsilg15/ # 另一网格点
└── ...
dcts/test/20260812_synspec_fullband/
└── synspec/
└── t50000_g5.0_cno/
└── gfato_100_20000/ # 全波段 SYNSPEC
├── inputs/ (fort.5 fort.55 fort.8 + fort.19/data 软链)
├── scripts/ (run.sh)
├── run/
└── outputs/ (fullband.spec/.cont/.iden + RESULT.md)
```
A/B 测试(baseline vs 变体)放同一 `{grid}` 下两个 `{content}` 目录,便于对照。生成完输入后用 `scripts/diff_configs.py` 确认各组**只有刻意改的参数不同**(带 `*` 的行应只有 ITEK/ORELAX/NITER 等),否则对照无效:
```bash
python3 .agents/skills/tlusty-synspec-test/scripts/diff_configs.py dirA/inputs dirB/inputs dirC/inputs --teff 60000
```