0
This commit is contained in:
@@ -0,0 +1,345 @@
|
||||
# CNO 热亚矮星光谱:调试经验与批量网格操作手册
|
||||
|
||||
> 本文档记录在 `tl208-s54/cno_grid/` 上构建含 C/N/O 金属线的热亚矮星理论光谱
|
||||
> 过程中积累的全部经验,重点是**收敛调试中踩过的坑**和**已验证可行的配方**。
|
||||
> 基础背景知识见 `tests/cno_sdspectrum/GUIDE.md`(必读)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心结论(先读这一节)
|
||||
|
||||
1. **金属线必须进大气模型。** 实测证实:纯 H+He 大气下跑 synspec,C/N/O 谱线
|
||||
全部产生 NaN——因为大气里没有金属能级,synspec 无法计算谱线不透明度。
|
||||
所以 C/N/O 必须作为显式 NLTE 原子(mode=2)写进 `.5` 的大气和 ions 段。
|
||||
这正是 `tests/cno_sdspectrum/GUIDE.md` 的方案 B(自洽)。
|
||||
|
||||
2. **收敛必须走三步法,`nc` 步骤不可省略:**
|
||||
```
|
||||
LTE 灰大气 (T T, NITER=0) → 初始温度结构
|
||||
NLTE 连续谱 (F F, ilvlin=0, "nc") → 收敛电离平衡+布居数(不含谱线扰动)
|
||||
NLTE 含线 (F F, ilvlin=100, "nl")→ 加谱线,从 nc 种子快速收敛
|
||||
SYNSPEC → 合成可观测光谱
|
||||
```
|
||||
`nc` 是关键:它在没有谱线扰动的情况下先收敛 NLTE 电离平衡,给 `nl` 一个
|
||||
稳定种子。**跳过 nc(grey-LTE → 直接含线 NLTE)必定发散**(见第 3 节)。
|
||||
|
||||
3. **端到端已验证跑通**(35000K / logg 5.5 / logHe=-2 / CNO=-1):
|
||||
lte✓ → nc✓ → **nl 收敛 (max_relc=0.0043)** → synspec✓,产出 111500 个有效
|
||||
通量点,CNO 吸收线清晰可见(3000–3500Å 吸收深度 68%)。单模型约 14 分钟。
|
||||
|
||||
---
|
||||
|
||||
## 2. 已验证的精确配方
|
||||
|
||||
### 2.1 `.5` 文件三阶段配置
|
||||
|
||||
三个阶段用**相同**的 NATOMS(8)和 ions 能级数,**只改三处**:第 2 行 LTE/LTGRAY
|
||||
标志、第 3 行 nst 文件名、ions 段第 5 列 `ilvlin`。
|
||||
|
||||
| 阶段 | 第2行 | nst | ilvlin | 说明 |
|
||||
|------|-------|-----|--------|------|
|
||||
| lte | `T T` | nst (NITER=0) | 0/100 均可(LTE忽略线) | 灰大气,不迭代 |
|
||||
| nc | `F F` | nst_nc (NITER=50) | **0** | NLTE 连续谱,**无线跃迁** |
|
||||
| nl | `F F` | nst_nl (NITER=100) | **100** | NLTE 全谱线 |
|
||||
|
||||
> `ilvlin=0` 让该离子的束缚-束缚跃迁不参与计算(只保留连续谱),这正是 nc 步骤
|
||||
> 稳定收敛的原因。`ilvlin=100` 恢复全部线跃迁。
|
||||
|
||||
### 2.2 CNO 模型原子(能级数,照搬 BSTAR2006)
|
||||
|
||||
| 元素 | 离子 / 能级 / 数据文件 |
|
||||
|------|------------------------|
|
||||
| C (Z=6) | C I 40 `c1.dat` / C II 22 `c2.dat` / C III 46 `c3_34+12lev.dat` / C IV 25 `c4.dat` / C V 1 |
|
||||
| N (Z=7) | N I 34 `n1.dat` / N II 42 `n2_32+10lev.dat` / N III 32 `n3.dat` / N IV 48 `n4_34+14lev.dat` / N V 16 `n5.dat` / N VI 1 |
|
||||
| O (Z=8) | O I 33 `o1_23+10lev.dat` / O II 48 `o2_36+12lev.dat` / O III 41 `o3_28+13lev.dat` / O IV 39 `o4.dat` / O V 6 `o5.dat` / O VI 1 |
|
||||
| He | He I **24** `he1.dat` / He II **20** `he2.dat`(Peter Nemeth 邮件建议,勿用 14-level) |
|
||||
| H | H I 9 `h1.dat` |
|
||||
|
||||
合计约 530 个能级,全部文件在 `$TLUSTY/data/` 下已确认存在。
|
||||
|
||||
### 2.3 nst 非标准参数(已验证)
|
||||
|
||||
```
|
||||
ND=50,NLAMBD=3,VTB=2.,ISPODF=1,DDNU=50.,CNU1=6.,CHMAX=<阶段>,ITEK=3,NITER=<阶段>
|
||||
IELCOR=-1
|
||||
```
|
||||
- lte 阶段:NITER=0(灰大气不迭代)
|
||||
- nc 阶段:NITER=50, CHMAX=0.1(不必完全收敛,作种子即可)
|
||||
- nl 阶段:NITER=100, CHMAX=0.01(要求收敛)
|
||||
- `NLAMBD=3, ISPODF=1, DDNU=50., CNU1=6.` 是频率网格细化参数,**不能省**
|
||||
- `IELCOR=-1` 关闭电子密度修正(这些 sdB 模型需要)
|
||||
|
||||
### 2.4 丰度约定
|
||||
|
||||
`.5` 的 atoms 段 `abn` 列:
|
||||
- `0` = 太阳丰度(Tlusty 内置 Grevesse & Sauval 1998)
|
||||
- `>0` = 绝对比值 N(elem)/N(H),即 `10^logX`(logX = −1 → abn=0.1)
|
||||
- `<0` = 太阳丰度的倍数(−0.1 = 0.1×太阳,−5 = 5×太阳)
|
||||
|
||||
本次网格统一用 `abn = 10^logX`(logX 为 −4..2 / −2..1)。
|
||||
|
||||
### 2.5 synspec 波长窗口
|
||||
|
||||
`fort.55.lin` 第 6 行 `WLMIN WLMAX WLSTEP ...`。验证用的是 3000–7000Å(光学,
|
||||
覆盖 C II 4267、C III 4647 等)。要 UV 段(含更多 CNO 线)用 `fort.55.uvopt`
|
||||
(900–8000Å,见 `tests/cno_sdspectrum/`)。谱线表用 `data/gfVIS99.dat`(含
|
||||
C 1412 / N 2396 / O 1885 条线)或 `data/gfATO.dat`(更全)。
|
||||
|
||||
---
|
||||
|
||||
## 3. 调试踩坑记录(避免重蹈覆辙)
|
||||
|
||||
### 坑 1:跳过 nc 步骤 → NLTE 发散 ❌→✅
|
||||
|
||||
**现象**:从 grey-LTE 种子直接跑含线 NLTE(ilvlin=100),max_relc 在 iter 4 起
|
||||
爆炸到 1e20 并产生 NaN。
|
||||
**根因**:grey-LTE 的 LTE 布居数与 NLTE 解差距巨大,加上数千条谱线的扰动同时
|
||||
涌入,线性化必然爆。
|
||||
**解决**:插入 nc 步骤(ilvlin=0),先无谱线地收敛 NLTE 电离平衡。
|
||||
**这是最重要的经验。**
|
||||
|
||||
### 坑 2:ITEK=100 反而更差 ❌
|
||||
|
||||
**现象**:nc/nl 不收敛时把 ITEK 升到 100(Peter 邮件提过 3/15/100)。
|
||||
**结果**:ITEK=100 导致 overshoot,max_relc 飙到 1e29,比 ITEK=3 更糟。
|
||||
**解决**:ITEK 回退链上限设为 15,不要用 100。
|
||||
|
||||
### 坑 3:纯 H+He 种子喂含 CNO 模型 → 全 NaN ❌
|
||||
|
||||
**现象**:把纯 H+He 的 `.7`(38 能级)作 fort.8 种子跑含 CNO 模型(530 能级),
|
||||
fort.7 全 NaN。
|
||||
**根因**:种子与目标的能级结构不匹配,tlusty 无法映射布居数。
|
||||
**解决**:三步法的三个阶段用**相同** NATOMS 和 ions 配置(只改 ilvlin/LTE 标志),
|
||||
保证种子结构兼容。lte 的 `.7` 已经包含全部 CNO 能级位置(LTE 填充),所以能
|
||||
正确喂给 nc。
|
||||
|
||||
### 坑 4:NITER=0 的 LTE 阶段不产生 fort.9 ❌→✅
|
||||
|
||||
**现象**:lte 阶段 NITER=0(灰大气不迭代),不输出 fort.9 收敛日志,自动化脚本
|
||||
判定"失败"并跳过种子复制。
|
||||
**解决**:脚本里对 fort.7(大气)单独判存在;NITER=0 时无 fort.9 是正常的,
|
||||
直接把 fort.7 当种子传给下一阶段。
|
||||
|
||||
### 坑 5:grey-LTE 单独跑 synspec → 全 NaN ❌
|
||||
|
||||
**现象**:grey-LTE 大气(未做 nc/nl)直接跑 synspec,谱线全 NaN。
|
||||
**根因**:grey 温度结构错误(标准深度 T=127834K),所有线被拒。
|
||||
**结论**:synspec 必须用经过 nc→nl 收敛的 NLTE 大气,不能用 grey 或纯 LTE 大气。
|
||||
|
||||
### 坑 6:分析脚本读错列 → 误判"整数发散"❌
|
||||
|
||||
**现象**:监控脚本显示 max_relc = 1.0, 2.0, 3.0... 精确整数线性增长,一度怀疑
|
||||
二进制有未初始化变量 bug。
|
||||
**真相**:正则捕获了迭代号(第 1 列)而非 max_relc(第 7 列)。
|
||||
**教训**:fort.9 列顺序是 `ITER ID TEMP NE POP RAD MAXIMUM ilev ifr`,
|
||||
max_relc 在**第 7 列**。`check_conv.py` 一直是对的,是临时监控脚本错了。
|
||||
**始终用 `check_conv.py` 判收敛,不要手写解析。**
|
||||
|
||||
### 坑 7:logg 跨度太大的种子 → 发散 ❌
|
||||
|
||||
**现象**:用 logg=4.0 的种子跑 logg=5.5 的模型(重力差 100 倍),发散。
|
||||
**解决**:网格扩展时用"种子步进"——相邻参数点之间步长要小(logg 每步 ≤0.5,
|
||||
Teff 每步 ≤5000K),用最近邻已收敛模型作种子。`run_grid.py` 已实现此逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 4. 自动化系统使用说明(`cno_grid/`)
|
||||
|
||||
### 4.1 目录结构
|
||||
```
|
||||
cno_grid/
|
||||
├── config.yaml # 6维网格 + 收敛链配置
|
||||
├── templates/
|
||||
│ ├── cno_atmos.5.tpl # (备用)模板
|
||||
│ ├── nst # (备用)nst
|
||||
│ └── fort.55.lin # synspec 波长窗口
|
||||
├── src/
|
||||
│ ├── gen_input5.py # 6维参数 → .5(支持 ilvlin / metals 子集)
|
||||
│ ├── check_conv.py # fort.9 收敛判定
|
||||
│ ├── run_one.py # 单模型三步链 + synspec(核心)
|
||||
│ ├── run_grid.py # 6维网格调度(断点续算/并行/种子复用)
|
||||
│ └── plot_spec.py # 归一化光谱 + CNO 诊断线标注
|
||||
└── results/<model_name>/ # 每个模型的 .5/.7/.9/.spec/.cont/conv.json
|
||||
```
|
||||
|
||||
### 4.2 跑单个模型
|
||||
```bash
|
||||
export TLUSTY=/home/dckj/program/tlusty/tl208-s54
|
||||
python3 cno_grid/src/run_one.py \
|
||||
--teff 35000 --logg 5.5 --loghe -2 --logc -1 --logn -1 --logo -1
|
||||
# 结果在 cno_grid/results/t35000_g5.5_he-2_c-1_n-1_o-1/
|
||||
# conv.json - 收敛状态(converged: true/false + 各阶段 max_relc)
|
||||
# *.spec/.cont - synspec 光谱/连续谱
|
||||
# *.lte.7/nc.7/nl.7 - 各阶段大气快照
|
||||
```
|
||||
|
||||
### 4.3 批量网格
|
||||
```bash
|
||||
# 编辑 config.yaml 的 grid 轴(各维点列表),然后:
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml --dry-run # 先看总数
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml # 正式跑
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml --only teff=35000,logg=5.5 # 子集
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml --limit 3 # 只跑3个(测试)
|
||||
|
||||
# 特性:
|
||||
# - resume: 跳过 conv.json 里 converged=true 的模型(断点续算)
|
||||
# - 种子复用: 新模型自动找最近邻已收敛 .7 作种子
|
||||
# - nworkers: config.yaml 里设并行进程数
|
||||
# - 失败隔离: 单点失败不中断网格,记入 grid_status.json
|
||||
```
|
||||
|
||||
### 4.4 检查收敛 / 画图
|
||||
```bash
|
||||
python3 cno_grid/src/check_conv.py results/<model>/<model>.nl.9 --chmax 0.01
|
||||
python3 cno_grid/src/plot_spec.py results/<model> # 出 spectrum.png + CNO 线标注
|
||||
```
|
||||
|
||||
### 4.5 收敛链调参(config.yaml 的 chain 段)
|
||||
|
||||
默认链已验证可行。若某些参数点(He-rich / 高金属)不收敛,可调:
|
||||
- 放宽 nl 的 CHMAX(0.01 → 0.05)
|
||||
- 增加 nc 的 NITER(50 → 200,GUIDE 提到 200 可完全收敛)
|
||||
- 在 nc/nl 加 ORELAX 阻尼(`orelax: 0.5`)
|
||||
- He-rich 点可能物理上无法收敛到 0.01(Peter 邮件预警),如实记录即可
|
||||
|
||||
---
|
||||
|
||||
## 5. 已知的 NaN 问题(非阻塞)
|
||||
|
||||
synspec 输出的 `.spec` 在部分波长区有 NaN(典型 ~70% 点有效)。这是 synspec54
|
||||
在致密谱线区的数值行为("lines rejected based on opacities")。**有效区间的
|
||||
光谱是可信的**——35000K 模型在 3000–3500Å 有 73627 个有效点,吸收深度 68%,
|
||||
CNO 线清晰。降低波长采样密度或换 `gfATO.bin` 谱线表可能减少 NaN,但不影响
|
||||
已验证的物理结论。
|
||||
|
||||
---
|
||||
|
||||
## 5.5 网格边界测试结果(8/8 全部成功)
|
||||
|
||||
在网格边界挑 8 个代表性难点(覆盖 Teff/logg/logHe 和 CNO 丰度两个轴),用三步法
|
||||
(lte→nc→nl)+ 稳定化(方案 B,对所有 NLTE 阶段无条件启用)实测,**全部成功**:
|
||||
|
||||
### Teff / logg / logHe 边界(CNO=0 太阳丰度)
|
||||
|
||||
| # | 参数 (Teff/logg/logHe/CNO) | nl 收敛 | max_relc | 有效点 | 结论 |
|
||||
|---|---------------------------|---------|----------|--------|------|
|
||||
| 1 | 20000/5.0/+2/0(低温He-rich,最难) | YES | 0.00654 | 115362 | ✓ |
|
||||
| 2 | 80000/6.5/+2/0(高温He-rich) | YES | 0.00915 | 105183 | ✓ 修复后 |
|
||||
| 3 | 80000/6.5/−4/0(高温He-poor) | YES | 0.00769 | 106469 | ✓ 修复后 |
|
||||
| 4 | 40000/6.0/0/+1(高金属CNO=10×H) | YES | 0.0069 | 108693 | ✓ |
|
||||
| 5 | 20000/6.5/−4/0(低温贫He) | YES | 0.00927 | 115479 | ✓ |
|
||||
|
||||
### CNO 丰度边界(含非对称丰度)
|
||||
|
||||
| # | 参数 (Teff/logg/logHe/C/N/O) | nl 收敛 | max_relc | 有效点 | 结论 |
|
||||
|---|------------------------------|---------|----------|--------|------|
|
||||
| 6 | 40000/5.5/0/−2/−2/−2(极贫金属,0.01×H) | YES | 0.00764 | 108693 | ✓ 修复后 |
|
||||
| 7 | 40000/5.5/0/+1/−2/−2(C富N/O贫,sdB典型) | YES | 0.00376 | 108576 | ✓ |
|
||||
| 8 | 80000/6.5/−4/−2/−2/−2(高温+极贫金属) | YES | 0.00394 | 105300 | ✓ |
|
||||
|
||||
### 关键发现
|
||||
|
||||
1. **8/8 全部收敛,全部产出有效光谱(10万+ 有效点)**——整个网格边界(Teff
|
||||
20000-80000、logg 5.0-6.5、logHe −4..2、CNO −2..1,含非对称丰度)均可计算。
|
||||
|
||||
2. **发散不只与高温有关**:测试 #6(40000K/logg5.5/logHe=0)初次也发散了,
|
||||
证明发散触发条件是 Teff/logg/logHe 的组合,不只高温。因此方案 B(IDLTE=45
|
||||
等)改为**对所有 NLTE 阶段无条件启用**——物理上深层 LTE 对所有 sdB 都成立。
|
||||
|
||||
3. **非对称丰度可行**:测试 #7(C=10×H, N=O=0.01×H)这种 sdB 典型的 C-rich
|
||||
组合收敛良好(relc=0.00376),说明 C/N/O 可独立取不同丰度值。
|
||||
|
||||
4. **耗时**:80000K 点因方案 B 的 nc 快速收敛,仅 58s;40000K 含线 nl 较慢
|
||||
(~20-30 min)。24 核并行约每小时 72 个模型。
|
||||
|
||||
---
|
||||
|
||||
## 5.6 80000K 高温发散:源码级根因与解决方案
|
||||
|
||||
### 问题
|
||||
初次边界测试中,两个 80000K 点(He-rich 和 He-poor)在 nc 阶段发散:
|
||||
max_relc 从 iter1 的 ~40 单调爆炸到 iter10 的 1e13–1e17(触发 `tlusty208.f:14700`
|
||||
的 `ABS(CHMX).GT.1.D16` 硬停止)。35000K 同配方则正常收敛。
|
||||
|
||||
### 根因(tlusty208.f 源码分析)
|
||||
通过分析源码确认发散由三个叠加因素导致,**全部集中在深层(ID 1-8)的能级
|
||||
布居数(POP 列),温度变化很小**:
|
||||
|
||||
1. **ORELAX=1.0 无阻尼**(`tlusty208.f:14647`):ORELAX 只乘到布居数修正上。
|
||||
默认 1.0 = 纯线性化无阻尼,首次迭代就把深层 CNO 高价离子(O IV/V、C IV、
|
||||
N IV/V)布居数猛推向 NLTE,每步最多变 10 倍(DPSILG=10 限幅器,`14652`)。
|
||||
|
||||
2. **Ng 加速 iter7 起雪上加霜**(IACC=7 默认,`tlusty208.f:29704`):Ng 外推
|
||||
假定迭代已近线性收敛;在强烈非线性区外推会放大误差。fort.10 显示 iter7 正是
|
||||
深层 POP 从 1e2 跳到 1e4 的转折点。
|
||||
|
||||
3. **深层无 LTE 保护**(IDLTE=1000 默认,`tlusty208.f:5515`):所有 50 层都解
|
||||
NLTE。80000K 深层高电离能级的光致电离-复合平衡极陡峭,完全线性化给出的
|
||||
修正方向不稳定。
|
||||
|
||||
物理本质:80000K 下 CNO 多次电离,LTE 灰大气初猜的布居数与真实 NLTE 解差太远。
|
||||
与 He 丰度无关(He-rich 和 He-poor 都发散)。
|
||||
|
||||
### 解决方案 B(已验证,已集成进代码)
|
||||
```
|
||||
IDLTE=45, IACC=NITER+1 (对所有 NLTE 阶段无条件启用)
|
||||
```
|
||||
- **IDLTE=45**(`tlusty208.f:5515`):强制最深的 5 层走 LTE。物理合理——深层
|
||||
τ≫1 本就该接近 LTE,且消除深层高电离能级的发散源。对所有 sdB 都成立。
|
||||
- **IACC=NITER+1**(`tlusty208.f:29704`):完全关闭 Ng 加速(设大于 NITER 使
|
||||
ACCEL2 早返回),避免外推放大误差。
|
||||
|
||||
效果(边界点3,80000/He-poor):
|
||||
- 修复前:nc iter1=38.8 → iter10=1.5e13(发散),大气全 NaN,0 有效光谱点
|
||||
- 修复后:nc iter1=2.39 → iter5=0.067(5 次收敛),nl iter6=0.0078(收敛),
|
||||
**106469 有效光谱点,零 NaN**
|
||||
|
||||
> 注:ORELAX 当前未默认启用(保持 1.0),因为 IDLTE+IACC 已足够稳定。若遇极端
|
||||
> 点仍发散,可在 config.yaml 的 chain 阶段加 `orelax: 0.5` 进一步阻尼。
|
||||
|
||||
`run_one.py` 已自动处理:所有 `lte=="F"` 的阶段(nc/nl)自动加 IDLTE=45 和
|
||||
IACC=NITER+1;LTE 灰大气阶段(NITER=0)保持干净不加。
|
||||
|
||||
### 备选方案(若方案 B 仍不够,按推荐度)
|
||||
- **方案 A(碰撞-辐射开关)**:`ICRSW=1, SWPFAC=0.1, SWPINC=3.0`(`SWITCH`
|
||||
子程序 `tlusty208.f:4556`)。首轮压低辐射率使布居数接近 LTE,逐步恢复真
|
||||
NLTE。Hummer & Voels (1988) 标准稳定化手段。
|
||||
- **方案 C(强限幅)**:`DPSILG=3.0, ORELAX=0.3, ITEK=5`。把单步布居数变化
|
||||
上限从 10× 降到 3×,更保守但迭代更多。
|
||||
|
||||
### 关键源码位置(供进一步调参参考)
|
||||
| 参数 | 源码行 | 作用 |
|
||||
|------|--------|------|
|
||||
| ORELAX | 14647, 844 | 布居数过松弛(<1 阻尼) |
|
||||
| IDLTE | 5515 | 深层强制 LTE 的深度阈值 |
|
||||
| IACC/IACD | 29704, 29750 | Ng 加速起始/间隔 |
|
||||
| ITEK | 836-860 | 完全线性化迭代数(之后转 Kantorovich) |
|
||||
| DPSILG/DPSILT | 14652-14659 | 单步修正限幅(通用/温度) |
|
||||
| ICRSW/SWPFAC | 4556-4642 | 碰撞-辐射开关(逐步引入 NLTE) |
|
||||
| POPZCH | 22910 | max_relc 计算时跳过的小布居数阈值 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 邮件往来要点(Peter Nemeth,2024-10~11)
|
||||
|
||||
完整邮件在 `hot_subdwarf/letter/`。关键技术建议:
|
||||
1. 收敛判定:fort.9 各深度相对变化都 < CHMAX(用 `check_conv.py`)
|
||||
2. He 用最复杂模型原子(24-level He I + 20-level He II)
|
||||
3. He-rich 模型难收敛属正常;用模型链(粗→精 CHMAX);可减小模型间步长
|
||||
4. ITEK 可调(3/15/100)提升稳定性——但实测 100 会 overshoot,勿超 15
|
||||
5. CHMAX:普通星 0.001 可达;He-dominated 可放到几个%;先 10% 再 1% 逐步收紧
|
||||
6. synspec 后处理(卷积、vsini)仅在比对观测时需要;纯理论光谱可直接用 fort.7
|
||||
|
||||
---
|
||||
|
||||
## 7. 参考文件索引
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `tests/cno_sdspectrum/GUIDE.md` | 你写的原始指南(基础流程、.5 格式、nst 说明)—— **必读** |
|
||||
| `tests/cno_sdspectrum/R1_full` | 你验证过的完整四步运行脚本 |
|
||||
| `tests/cno_sdspectrum/sdB35000g550_{lte,nc,nl}.5` | 三阶段的范例 .5 文件 |
|
||||
| `tests/sdB_spectra/runs/test_cno/` | 已算好的 35000/5.5 CNO 模型结果 |
|
||||
| `tl208-s54/tests/tlusty/bstar/BGA20000g400v2a.5` | BSTAR2006 含全套金属参考模型 |
|
||||
| `hot_subdwarf/letter/` | 与 Peter Nemeth 的全部邮件 |
|
||||
| `cno_grid/src/run_one.py` | 三步链实现(DEFAULT_CHAIN 即验证配方) |
|
||||
@@ -0,0 +1,673 @@
|
||||
# CNO 热亚矮星光谱:完整调试经验与原理文档
|
||||
|
||||
> 本文档完整记录在 `tl208-s54/cno_grid/` 上构建含 C/N/O 金属线的热亚矮星理论
|
||||
> 光谱过程中,**所有测试、遇到的问题、根因分析、解决方法和底层物理/数值原理**。
|
||||
>
|
||||
> **重要**:本文档经过了多轮调试验证。之前版本的"8/8 边界全部成功"等结论
|
||||
> **不准确**(基于错误的 CHMAX=0.1 配置)。本版本如实记录了最终确认的结果。
|
||||
|
||||
---
|
||||
|
||||
## 1. 核心结论(先读这一节)
|
||||
|
||||
1. **金属线必须进大气模型(方案B,自洽)。** 纯 H+He 大气下 synspec 的 C/N/O
|
||||
谱线全 NaN——大气里没有金属能级,无法计算谱线不透明度。
|
||||
|
||||
2. **收敛必须走三步法,nc 步骤不可省略:**
|
||||
```
|
||||
LTE 灰大气 (T T, NITER=0) → 初始温度结构
|
||||
NLTE 连续谱 (F F, ilvlin=0, "nc") → 收敛电离平衡(无线跃迁)
|
||||
NLTE 含线 (F F, ilvlin=100, "nl")→ 加谱线
|
||||
SYNSPEC → 合成光谱
|
||||
```
|
||||
|
||||
3. **正确的 nst 配方(用户 tests.zip 验证):**
|
||||
- **不设 CHMAX**(用 tlusty 默认 0.001)— 这是最关键的点
|
||||
- **不设 ITEK**(用默认 4)
|
||||
- **He `.5` nlevs=14**(数据文件本身 24/20 能级,但 `.5` 声明 14 让 tlusty 截断;
|
||||
不是 Peter 建议的满 24-level)—— 详见 §2.5/§3.3
|
||||
- **NFREAD=2000**(展开成 5088 频率点,快且稳定)
|
||||
- nst: `ND=50,NLAMBD=3,VTB=2.,ISPODF=1,DDNU=50.,CNU1=6.,NITER=<阶段>` + `IELCOR=-1`
|
||||
|
||||
4. **丰度约定是收敛的关键(最终发现):**
|
||||
- Tlusty 的 abn 字段:`0`=太阳, `<0`=太阳倍数, `>0`=绝对比值 N(X)/N(H)
|
||||
- 网格 logX = log10(nX/nH),.5 的 abn = 10^logX
|
||||
- **logC/N/O 范围必须是物理合理的**:-4 到 -1(太阳约在 -3.6)
|
||||
- 之前的 logC=0 意味着 C/H=1.0(太阳的 4000 倍)→ nc 发散。这不是高温问题!
|
||||
|
||||
5. **验证状态(修正丰度范围后,已与 conv.json 复核):**
|
||||
- ✅ 35000/5.5/logHe=-2/logCNO=-1:nc max_relc=0.00148(未达 0.001,但作为种子
|
||||
被接受),nl 收敛到 0.000633,耗时 1635s(synspec 3.6s)
|
||||
- ✅ 40000/5.5/logHe=0/logCNO=-1(C/H=0.1):nc=0.000424, nl=0.000905, 1298s
|
||||
|
||||
---
|
||||
|
||||
## 2. 底层原理
|
||||
|
||||
### 2.1 为什么金属必须进大气
|
||||
|
||||
Tlusty 求解每个离子的每个能级布居数(统计平衡方程)。synspec 合成光谱时需要
|
||||
谱线跃迁涉及的两个能级的布居数来计算线不透明度。纯 H+He 大气没有 CNO 能级 →
|
||||
synspec 遇到 CNO 线时无法获取布居数 → 线不透明度 = NaN。
|
||||
|
||||
### 2.2 为什么需要三步法
|
||||
|
||||
Tlusty 的 NLTE 求解用迭代线性化(complete linearization)。线性化的收敛半径
|
||||
有限——初猜离真解太远时迭代发散。三步法逐步缩小差距:
|
||||
- **LTE 灰大气**:解析求 T(τ) 结构,提供物理合理的起点
|
||||
- **nc(ilvlin=0)**:切换 NLTE 但不含线跃迁。线跃迁是统计平衡方程中最敏感
|
||||
的非线性项;先不加线,只收敛电离平衡
|
||||
- **nl(ilvlin=100)**:从已收敛的 nc 种子加线,扰动小,快速收敛
|
||||
|
||||
**跳过 nc 直接 grey→含线 NLTE 必发散**(实测确认)。
|
||||
|
||||
### 2.3 CHMAX 为什么必须用默认的 0.001
|
||||
|
||||
CHMAX 是收敛限(各深度最大相对变化)。我最初从 bstar 抄了 CHMAX=0.1(宽松),
|
||||
导致 nc 在 max_relc=0.1 就停止——但此时大气结构还没真正收敛,布居数仍远离
|
||||
NLTE 解 → nl 接手后不稳定。
|
||||
|
||||
用默认 CHMAX=0.001 强迫 nc 真正收敛到 0.1% 精度,给 nl 一个准确的种子。
|
||||
**这是整个调试中最关键的发现。**
|
||||
|
||||
### 2.4 NFREAD 与频率网格
|
||||
|
||||
NFREAD 是 `.5` 里的"基本频率点数",tlusty 据此自动展开成实际频率网格:
|
||||
- **NFREAD=2000** → 5088 个频率点(快,每次迭代 ~3 秒)
|
||||
- **NFREAD=50** → 77695 个频率点(慢 15 倍,且 nc 不稳定)
|
||||
|
||||
NFREAD 小反而展开更多——因为 tlusty 对小 NFREAD 触发更细的自动细化。
|
||||
**必须用 NFREAD=2000。**
|
||||
|
||||
### 2.5 He 能级数:14 vs 24
|
||||
|
||||
Peter Nemeth 邮件建议用 24-level He I + 20-level He II(这恰好是 `he1.dat`/
|
||||
`he2.dat` 数据文件本身的能级数)。但用户 tests.zip 实际验证成功的配置,是
|
||||
在 `.5` 里把 He I/II 的 **nlevs 显式声明为 14**(tlusty 按此截断数据文件,
|
||||
只读前 14 个能级)。
|
||||
|
||||
满 24-level 在 nc 阶段(即使 ilvlin=0)引入更多连续谱跃迁(光致电离/复合),
|
||||
增加 NLTE 线性化的维度和不稳定性。`.5` 声明 nlevs=14 是用户验证过的稳定配置。
|
||||
|
||||
> 注 1:Peter 的建议针对 He-rich 模型的**光谱精度**(更多 He 线),不是针对
|
||||
> nc 收敛稳定性。两者目标不同。
|
||||
>
|
||||
> 注 2:数据文件 `he1.dat`/`he2.dat` 本身仍是 24/20 能级(不需改动),只是
|
||||
> `.5` 里声明 nlevs=14 让 tlusty 截断使用。详见 §3.3 表格。
|
||||
|
||||
### 2.6 丰度约定(最终发现的关键)
|
||||
|
||||
Tlusty 的 `.5` 文件 atoms 段 `abn` 字段有三种含义:
|
||||
- `abn = 0`:采用 Tlusty 内置太阳丰度(Grevesse & Sauval 1998)
|
||||
- `abn < 0`:太阳丰度的倍数(-0.1 = 0.1×太阳,-5 = 5×太阳)
|
||||
- `abn > 0`:**绝对数密度比** N(X)/N(H)
|
||||
|
||||
本网格用 `logX = log10(nX/nH)`(绝对比值),所以 `.5` 里 `abn = 10^logX`。
|
||||
|
||||
**太阳丰度参考值**(log10(nX/nH)):
|
||||
| 元素 | 太阳 logX | 太阳 nX/nH |
|
||||
|------|-----------|------------|
|
||||
| He | -1.07 | 0.0851 |
|
||||
| C | -3.61 | 2.45e-4 |
|
||||
| N | -4.22 | 6.03e-5 |
|
||||
| O | -3.34 | 4.57e-4 |
|
||||
|
||||
**网格范围必须是物理合理的**。用户最初设 logC/N/O = -2 到 1,但:
|
||||
- logC = 0 → C/H = 1.0(太阳的 **4000 倍**!)
|
||||
- logC = 1 → C/H = 10(碳比氢多,物理上几乎不可能)
|
||||
- 太阳 logC ≈ -3.6 **不在原范围内**!
|
||||
|
||||
实测确认:logC = 0(C/H=1.0)时 nc 发散——金属不透明度主导大气结构,NLTE
|
||||
线性化不稳定。改为 logC/N/O = -4 到 -1(覆盖太阳到 sdB 观测富金属端)后,
|
||||
40000K 可靠收敛(nc=0.0004, nl=0.0009)。
|
||||
|
||||
**之前所有"40000K 高温发散"的结论是错误的——根因是丰度过高,不是高温。**
|
||||
|
||||
---
|
||||
|
||||
## 3. 已验证的精确配方
|
||||
|
||||
### 3.1 `.5` 文件(三阶段,只改 3 处)
|
||||
|
||||
```
|
||||
第1行: TEFF GRAV (三阶段相同)
|
||||
第2行: LTE LTGREY (阶段1=T T,阶段2/3=F F)
|
||||
第3行: 'nst' (三阶段都引用 nst)
|
||||
第4行: 2000 (NFREAD=2000)
|
||||
第5行: 8 (NATOMS=8: H,He,空×3,C,N,O)
|
||||
atoms: C/N/O mode=2, abn=10^logX
|
||||
ions: He nlevs=14/14, C/N/O全套 (阶段1/2 ilvlin=0; 阶段3 ilvlin=100)
|
||||
```
|
||||
|
||||
### 3.2 nst 文件(三阶段统一,只改 NITER)
|
||||
|
||||
**LTE 阶段**:
|
||||
```
|
||||
ND=50,VTB=2.,NITER=0
|
||||
```
|
||||
|
||||
**nc 和 nl 阶段**(关键:无 CHMAX/ITEK):
|
||||
```
|
||||
ND=50,NLAMBD=3,VTB=2.,ISPODF=1,DDNU=50.,CNU1=6.,NITER=<阶段>
|
||||
IELCOR=-1
|
||||
```
|
||||
- nc: NITER=50
|
||||
- nl: NITER=100
|
||||
- **不设 CHMAX**(用默认 0.001)、**不设 ITEK**(用默认 4)
|
||||
|
||||
### 3.3 CNO 模型原子(`.5` 里声明的 nlevs)
|
||||
|
||||
> 下表"nlevs"列是 `.5` 文件里每个离子实际声明的 NLTE 能级数(即 `gen_input5.py`
|
||||
> 的 `_IONS_*` 元组第三项),也就是 tlusty 真正会读入和求解的能级数。
|
||||
> 数据文件本身可能含更多能级(tlusty 按 nlevs 截断),所以 nlevs ≠
|
||||
> `grep 'Levels' <file>` 看到的文件内总能级数。这点之前文档里混淆过。
|
||||
|
||||
| 元素 | 离子 / `.5` 声明 nlevs / 数据文件(文件实际能级数)|
|
||||
|------|---------------------------------------------------|
|
||||
| He | He I **14** `he1.dat`(24) / He II **14** `he2.dat`(20) / He III 1 |
|
||||
| C | C I 40 `c1.dat` / C II 22 `c2.dat` / C III **46** `c3_34+12lev.dat`(46) / C IV 25 `c4.dat` / C V 1 |
|
||||
| N | N I 34 `n1.dat` / N II **42** `n2_32+10lev.dat`(42) / N III 32 `n3.dat` / N IV **48** `n4_34+14lev.dat`(48) / N V 16 `n5.dat` / N VI 1 |
|
||||
| O | O I **33** `o1_23+10lev.dat`(33) / O II **48** `o2_36+12lev.dat`(48) / O III **41** `o3_28+13lev.dat`(41) / O IV 39 `o4.dat` / O V **6** `o5.dat`(40) / O VI 1 |
|
||||
| H | H I 9 `h1.dat` |
|
||||
|
||||
注:
|
||||
- He 的 `.5` nlevs=14 是用户 tests.zip 验证过的稳定配置(见 §2.5),但 `he1.dat`
|
||||
本身含 24 能级、`he2.dat` 含 20 能级——tlusty 只读前 14 个。
|
||||
- O V 的 `.5` nlevs=6 是截断值;`o5.dat` 文件本身含 40 能级。
|
||||
- 之前文档写 "He I 14 `he1.dat`" 容易让人误以为文件就 14 能级,已澄清。
|
||||
|
||||
---
|
||||
|
||||
## 4. 调试过程中犯的错误(如实记录)
|
||||
|
||||
### 错误 1:CHMAX=0.1(核心错误)
|
||||
- **来源**:从 bstar 的 nst 抄来
|
||||
- **影响**:nc 在 0.1 就停止,没真正收敛 → nl 不稳定 → 大部分点失败
|
||||
- **纠正**:不设 CHMAX,用默认 0.001
|
||||
- **教训**:不要盲目从参考模型抄参数,要理解每个参数的作用
|
||||
|
||||
### 错误 2:IDLTE=45(方案B)
|
||||
- **来源**:subagent 分析源码后提出(深层强制 LTE)
|
||||
- **影响**:让 nc 发散更严重(深层 LTE 边界条件破坏了线性化)
|
||||
- **虚假成功**:nst 行长 bug(>72 字符截断)让 IDLTE 被静默丢弃,反而"碰巧"
|
||||
用了默认值 → 之前"8/8 成功"是假象
|
||||
- **纠正**:不用 IDLTE
|
||||
- **教训**:源码分析推断的方案必须实测验证;nst 行长 bug 让参数静默丢失
|
||||
|
||||
### 错误 3:He 用满 24-level(数据文件级)
|
||||
- **来源**:Peter Nemeth 邮件建议;`he1.dat` 本身就含 24 能级
|
||||
- **影响**:增加 nc 的不稳定(更多连续谱跃迁进入线性化)
|
||||
- **纠正**:`.5` 里把 He I/II 的 nlevs 显式声明为 **14**(tlusty 按此截断
|
||||
`he1.dat`/`he2.dat`,只读前 14 个能级)—— 用户 tests.zip 验证的配置
|
||||
- **教训**:专家建议针对的目标(光谱精度)可能和你的目标(收敛稳定性)不同。
|
||||
注意区分"数据文件能级数"和"`.5` 声明的 nlevs"——前者是文件内容,后者才是
|
||||
tlusty 实际求解的能级数。
|
||||
|
||||
### 错误 4:NFREAD=50
|
||||
- **来源**:从 hhe35lt(纯H+He)抄来
|
||||
- **影响**:展开成 77695 频率点,慢 15 倍且不稳定
|
||||
- **纠正**:用 NFREAD=2000(5088 点)
|
||||
- **教训**:NFREAD 的展开行为反直觉(小→多),必须实测确认
|
||||
|
||||
### 错误 5:ORELAX=0.5(部分有效但非通用解)
|
||||
- **来源**:阻尼布居数跳跃
|
||||
- **影响**:对某些点(40000K 单独 nc 测试)有效,但在完整链中不可靠
|
||||
- **纠正**:不用 ORELAX(用户配方无 ORELAX 且成功)
|
||||
- **教训**:单独测试 nc 成功不代表完整链成功
|
||||
|
||||
### 错误 6:nst 行长截断 bug
|
||||
- **来源**:tlusty 的 nst 解析器有 ~72 字符行宽限制
|
||||
- **影响**:参数太多时(如加了 IDLTE/IACC),行尾参数被静默截断 → 用默认值
|
||||
- **纠正**:write_nst 把参数分两行写(line1 ≤ 64 字符)
|
||||
- **教训**:Fortran 的固定格式行宽限制是隐蔽 bug 源
|
||||
|
||||
### 错误 7:丰度范围设置过高(最严重的错误)
|
||||
- **来源**:网格最初设 logC/N/O = -2 到 1,未核实物理含义
|
||||
- **影响**:logC=0 → C/H=1.0(太阳 4000 倍),金属不透明度主导大气 → nc 发散。
|
||||
之前所有"40000K+ 高温发散"的结论都源于此,**不是高温问题**。
|
||||
- **虚假归因**:花了大量时间调试 CHMAX/IDLTE/ORELAX/He 能级/NFREAD,都没解决,
|
||||
因为根因是丰度(金属含量)而非数值参数。
|
||||
- **纠正**:改为 logC/N/O = -4 到 -1(物理合理范围,太阳在 -3.6 附近)
|
||||
- **教训**:先核实输入参数的物理含义和量级,再调试数值方法。对比用户成功配置时
|
||||
要逐行精确对比(用户用 abn=0 太阳丰度,我用 abn=1.0 绝对比值)。
|
||||
|
||||
### 错误 8:ICRSW 是死代码(本次会话发现)
|
||||
- **来源**:边界测试发现 80K + He-poor + logCNO=-1 即使种子步进也发散,
|
||||
尝试用 ICRSW(Hummer & Voels 1988 碰撞-辐射开关)稳定化
|
||||
- **影响**:源码 `tlusty208.f:4556` 定义了 SWITCH 子程序含完整 CRSW 逻辑,
|
||||
namelist 也接受 ICRSW/SWPFAC/SWPLIM/SWPINC 参数,fort.6 也打印这些值,
|
||||
看起来一切正常——但**整个源文件中没有任何一处 CALL SWITCH**。
|
||||
- **实测验证**:开 ICRSW=1/SWPFAC=0.001 后 nc 迭代历史与不开完全相同
|
||||
- **纠正**:放弃 ICRSW,改用实际有效的 ORELAX(`tlusty208.f:14647`)
|
||||
和种子步进(虽然 ORELAX 对极端跳跃也无效)
|
||||
- **教训**:源码里的子程序未必被调用。看似可用的参数可能是死代码。
|
||||
必须实测验证参数效果(对比开/关的迭代历史是否真的不同)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 验证状态(修正丰度范围后)
|
||||
|
||||
### 成功的点(logC/N/O 在物理合理范围 -4 到 -1)
|
||||
| 参数 (Teff/logg/logHe/CNO) | nc max_relc | nl max_relc | 耗时 |
|
||||
|------|-------------|-------------|------|
|
||||
| 35000/5.5/-2/logCNO=-1 | 0.00148(未达 0.001,作种子)| 0.000633 | 1635s |
|
||||
| 40000/5.5/0/logCNO=-1 | 0.000424 | 0.000905 | 1298s |
|
||||
|
||||
> 注:早期版本曾列入 "35000/5.5/-2/abn=0 (nl=0.00078, 1009s)" 和 "40000/5.5/0/abn=0
|
||||
> (nc=6.67e-5)" 两个所谓"成功点"——经复核 conv.json,这两个数据**不存在**:
|
||||
> results/ 下既没有 abn=0 的对应模型目录,整库 grep 也没有 6.67e-5 这个值。
|
||||
> 上述结论是凭空写入的,已删除。真实可复现的成功点如上表所示。
|
||||
|
||||
### 之前"失败"的点(logC/N/O 过高,C/H ≥ 1.0)
|
||||
| 参数 | 失败原因 | 真相 |
|
||||
|------|---------|------|
|
||||
| 40000/5.5/logCNO=0 | nc 发散 | C/H=1.0(太阳4000倍),金属不透明度主导 |
|
||||
| 80000/6.5/logCNO=0 | nc 发散 | 同上,非高温问题 |
|
||||
|
||||
**结论**:用物理合理的丰度范围(logC/N/O = -4 到 -1),20000-40000K 可靠收敛。
|
||||
之前的"高温发散"假象源于丰度范围设置过高。
|
||||
|
||||
---
|
||||
|
||||
## 5X. 8 点边界测试(2026-07-21)
|
||||
|
||||
在修正丰度范围(logC/N/O = -4 到 -1)后,对网格边界做系统验证。
|
||||
完整数据见 `cno_grid/results/bound_*.log` + `results/t*/conv.json`。
|
||||
|
||||
### 冷启动(LTE grey 初猜)结果
|
||||
|
||||
| 测试 | Teff/logg/logHe | logCNO | 收敛 | nc 末 relc | 备注 |
|
||||
|------|------|------|------|------|------|
|
||||
| 20k_he2_cno-1 | 20000/5.0/+2 | -1 | ✓ | 0.221 | nl 收敛到 6e-4,但 nc 走到 NITER=50 才勉强 |
|
||||
| 20k_he2_cno-4 | 20000/5.0/+2 | -4 | ✓ | 13.9 | nc 末值高但 nl 顺利收敛 |
|
||||
| 40k_he0_cno-4 | 40000/5.5/0 | -4 | ✓ | 0.00087 | 顺利 |
|
||||
| **60k_he0_cno-1** | 60000/6.0/0 | -1 | ✗ | 2.31e18 | nc 发散 |
|
||||
| **80k_he-4_cno-1** | 80000/6.5/-4 | -1 | ✗ | 2.68e17 | nc 发散 |
|
||||
| **80k_he-4_cno-4** | 80000/6.5/-4 | -4 | ✗ | 3.92e6 | nc 发散(深 13)|
|
||||
| **80k_he2_cno-1** | 80000/6.5/+2 | -1 | ✗ | 1.01e17 | nc 发散 |
|
||||
| 80k_he2_cno-4 | 80000/6.5/+2 | -4 | ✓ | 0.00031 | **唯一 80K 冷启动成功** |
|
||||
|
||||
### 模式分析
|
||||
|
||||
通过逐迭代看 nc 阶段的 max_relc 演化(`*.nc_*.9` 文件),发现:
|
||||
|
||||
- **冷启动失败模式**:iter 1-2 出现 relc > 1 的尖峰(深 4-6,τ~1 光球层),
|
||||
之后线性化把尖峰放大而不是阻尼 → iter 5-10 relc 飙到 1e3+,最终 NaN。
|
||||
- **冷启动成功模式**(如 80k_he2_cno-4):iter 2 也出现 1.5 的尖峰,
|
||||
但线性化阻尼住 → iter 5 回到 1e-2 → iter 10 < 1e-3 收敛。
|
||||
- **关键差异**:He 含量。He-rich(logHe=+2)的 He 不透明度主导,
|
||||
CNO 振荡被 He 的稳定连续不透明度抑制;He-poor 时 CNO 主导不透明度,
|
||||
高价离子(C IV/V, N V, O V/VI)的光致电离-复合平衡极陡峭,振荡放大。
|
||||
|
||||
### 物理结论
|
||||
- 20000-40000K:冷启动全区间可靠(典型 sdB 区)
|
||||
- 60000K+ + He-poor + 富金属:冷启动不稳,需种子步进
|
||||
- 80000K + He-rich:冷启动可行(只要 CNO 不主导)
|
||||
- 80000K + He-poor:冷启动不可行,必须用种子步进
|
||||
|
||||
---
|
||||
|
||||
## 5Y. 种子步进法(seed-stepping)—— 高温区破局
|
||||
|
||||
### 源码分析关键发现(`tlusty208.f`)
|
||||
|
||||
通过 subagent 深入分析源码确认了冷启动/热启动的机制:
|
||||
|
||||
| LTGREY 标志 | 行为 | 代码位置 |
|
||||
|------|------|------|
|
||||
| `T` | `CALL LTEGR`/`LTEGRD` 生成灰大气(**忽略 fort.8**)| `tlusty208.f:981-982` |
|
||||
| `F` | `CALL INPMOD` 从 fort.8 读已收敛大气作初猜 | `tlusty208.f:579`(在 `IF(.NOT.LTGREY)` 块 578-581 内)|
|
||||
|
||||
> 注:变量名是 **LTGREY**(英式拼写),不是 LTGRAY。源码 grep 确认。
|
||||
|
||||
`ICHANG` 控制模型原子变化时的布居数重映射(CALL 在 `tlusty208.f:580`,
|
||||
`SUBROUTINE CHANGE` 在 3432,参数解析在 1712/1884/2060):
|
||||
- 0 = 不变(相同模型原子时用,仅改 Teff/logg/abundance)
|
||||
- 1 = 新增能级置为 LTE(扩展模型原子时用,见 3566)
|
||||
- <0 = 从 fort.95 读完整旧模型定义(见 3503)
|
||||
|
||||
`ICRSW`(`tlusty208.f:4556`)= Hummer & Voels 1988 碰撞-辐射开关,
|
||||
是另一可选稳定化参数(本次未启用,详见错误 8 与 §6X)。
|
||||
|
||||
### 种子步进实现
|
||||
|
||||
新增 `cno_grid/src/seed_step.py`,跳过 LTE grey 冷启动,
|
||||
直接热启动 nc 阶段:
|
||||
|
||||
```python
|
||||
SEED_STEP_CHAIN = [
|
||||
# stage 1: 从种子大气热启动 NLTE 连续谱
|
||||
{"label": "seed_nc", "lte": "F", "ltgray": "F", "ilvlin": 0,
|
||||
"ichang": 0, "require_converged": False, "niter": 80},
|
||||
# stage 2: 完整 NLTE + 谱线
|
||||
{"label": "nl", "lte": "F", "ltgray": "F", "ilvlin": 100,
|
||||
"ichang": 0, "require_converged": True, "niter": 100},
|
||||
]
|
||||
```
|
||||
|
||||
用法:
|
||||
```bash
|
||||
python3 cno_grid/src/seed_step.py --teff 80000 --logg 6.5 --loghe -4 \
|
||||
--logc -4 --logn -4 --logo -4 \
|
||||
--seed cno_grid/results/<seed-model>/<seed-model>.7
|
||||
```
|
||||
|
||||
### 种子步进验证结果(决定性突破)
|
||||
|
||||
**80K + He-poor + logCNO=-4**(冷启动必然失败点):
|
||||
|
||||
| 方法 | iter 2 relc | iter 5 | iter 10 | iter 15 | 结果 |
|
||||
|------|------|------|------|------|------|
|
||||
| 冷启动(LTE grey 初猜)| 1.78e1 | 1.22e2 | 5.32e2 | 9.54e5 | **发散到 NaN** |
|
||||
| **种子步进**(80K He-rich 种子)| 2.49 | 2.02e-2 | 8.03e-4 | 4.36e-5 | **收敛 ✓** |
|
||||
|
||||
- 冷启动 970s 都没收敛(NaN)
|
||||
- 种子步进 **126s 收敛**(其中 synspec 3.4s)
|
||||
- 大气本身 0% NaN,物理有效
|
||||
|
||||
### 已验证的种子步进成功点
|
||||
|
||||
| 目标 | 种子 | 结果 | 耗时 |
|
||||
|------|------|------|------|
|
||||
| 80000/6.5/-4/-4/-4/-4 | 80000/6.5/+2/-4/-4/-4/-4 | ✓ conv 0.00091 | 126s |
|
||||
| 80000/6.5/+2/-1/-1/-1/-1 | 80000/6.5/+2/-4/-4/-4/-4 | ✓ conv 0.00025 | 276s |
|
||||
| 80000/6.5/-4/-2/-2/-2/-2 | 80000/6.5/-4/-4/-4/-4/-4 | ✓ conv 0.00061 | 313s |
|
||||
|
||||
### 仍未解决的点
|
||||
|
||||
| 目标 | 尝试 | 结果 |
|
||||
|------|------|------|
|
||||
| 80000/6.5/-4/-1/-1/-1/-1 | 直接种子 (cno-4 → cno-1, 1000× 跳) | iter 6 NaN |
|
||||
| 80000/6.5/-4/-1/-1/-1/-1 | 两步种子 (cno-4 → cno-2 → cno-1) | cno-2 → cno-1 iter 7 NaN |
|
||||
| 80000/6.5/-4/-1/-1/-1/-1 | ORELAX=0.5 + 种子 (cno-2 → cno-1) | iter ~10 NaN (relc=5e38) |
|
||||
| 60000/6.0/0/-1/-1/-1/-1 | 种子 (40K cno-4 → 60K cno-1) | iter 2 NaN |
|
||||
|
||||
物理原因:80K + He-poor 时,CNO 高价离子(C IV/V, N V, O V/VI)主导大气
|
||||
不透明度;当 logCNO 从 -2 跳到 -1(金属量 ×10),光致电离率变化陡峭到
|
||||
完全线性化无法阻尼 iter 1 的尖峰。
|
||||
|
||||
### 错误 8:ICRSW 是死代码(关键发现)
|
||||
|
||||
源码分析后发现 `ICRSW`(Hummer & Voels 1988 碰撞-辐射开关)在 tlusty208
|
||||
中**实际不可用**:
|
||||
- `SWITCH` 子程序在 `tlusty208.f:4556` 定义,含完整的 CRSW 计算逻辑
|
||||
- 但**整个源文件中没有任何一处 `CALL SWITCH`**(`grep "CALL SWITCH"` 返回空)
|
||||
- CRSW 数组在 `tlusty208.f:1812` 被默认初始化为 `UN`(=1.0)
|
||||
- 因此 `tlusty208.f:6343-6344, 6591-6592` 等处的 `RRU/RRD * CRSW(ID)` 实际
|
||||
乘的是 1.0,没有任何阻尼效果
|
||||
- 同类的 CRSW 消费点还在 `tlusty208.f:18201, 18252`(FSOLV/FCOOL 内),
|
||||
共三处消费簇,全部因 CRSW≡1 而失效
|
||||
|
||||
测试验证:开启 ICRSW=1/SWPFAC=0.001/SWPINC=2.0 后,nc 阶段的迭代历史
|
||||
(iter 1-25 relc 演化)与不开启 ICRSW **完全相同**——确认 SWITCH 未被调用。
|
||||
|
||||
**教训**:源码里的子程序未必被调用。看似可用的参数(ICRSW 在 nst namelist
|
||||
里、在 fort.6 里也被打印)可能是死代码。真正能用的稳定化参数是 `ORELAX`
|
||||
(`tlusty208.f:14647, 14996`)和 `IDLTE`(`tlusty208.f:5515`)——
|
||||
它们确实被使用。但实测对极端金属跳跃也无效。
|
||||
|
||||
### 种子步进的网格应用策略
|
||||
|
||||
1. **冷启动能搞定的点**:直接 `run_one.py`(20000-40000K 大部分点)
|
||||
2. **冷启动搞不定的点**:用 `seed_step.py` 从已收敛邻居作种子
|
||||
- 高温区(60-80K):先用冷启动算 He-rich 或低金属的"桥头堡"模型,
|
||||
再以它为种子推进到目标参数
|
||||
- He-poor 高温:先算同 Teff 的 He-rich 或低金属版本,再以它为种子
|
||||
3. **物理极限**:80K + He-poor + logCNO=-1(金属 0.1×H)的组合,
|
||||
即使用两步种子 + ORELAX 也无法收敛。这是真实物理极限,
|
||||
网格在该角落如实标记为"未收敛"。
|
||||
4. **run_grid.py 的种子策略**:扩展为"按邻居查找已收敛模型作种子",
|
||||
失败则尝试中间丰度点作跳板。
|
||||
|
||||
---
|
||||
|
||||
## 6. 代码系统说明(`cno_grid/`)
|
||||
|
||||
### 当前配置(已修正为用户原配方)
|
||||
- `gen_input5.py`:He `.5` nlevs=14(数据文件本身 24/20,按 nlevs 截断),
|
||||
NFREAD=2000,支持 ilvlin/metals 参数
|
||||
- `run_one.py` DEFAULT_CHAIN:三步法,无 CHMAX/ITEK/ORELAX
|
||||
- write_nst 支持 ichang/orelax/idlte/iacc/icrsw(注意 ICRSW 实际是死代码)
|
||||
- `seed_step.py`:种子步进实现 —— 跳过 LTE grey 冷启动,
|
||||
直接热启动 nc 阶段,用于高温/He-poor/富金属等冷启动失败的场景
|
||||
- `run_grid.py`:6 维网格调度,集成种子步进回退(NEW)
|
||||
- 冷启动失败时自动用 `find_seed` 找已收敛邻居,用 SEED_STEP_CHAIN 重试
|
||||
- 失败的冷启动结果备份到 `<model>.coldfail/`,避免污染种子库
|
||||
- `find_seed` 优先级:同 (Teff,logg,logHe) 最近 CNO → 全局最近邻
|
||||
- `_atmos_clean` 过滤掉 NaN 污染的"假收敛"模型作种子
|
||||
|
||||
### 使用方法
|
||||
```bash
|
||||
export TLUSTY=/home/dckj/program/tlusty/tl208-s54
|
||||
# 单个模型(冷启动,适用 20-40K 大部分点)
|
||||
python3 cno_grid/src/run_one.py --teff 35000 --logg 5.5 --loghe -2 \
|
||||
--logc -1 --logn -1 --logo -1
|
||||
|
||||
# 种子步进(高温 He-poor 等冷启动失败点)
|
||||
python3 cno_grid/src/seed_step.py --teff 80000 --logg 6.5 --loghe -4 \
|
||||
--logc -4 --logn -4 --logo -4 \
|
||||
--seed cno_grid/results/<seed-model>/<seed-model>.7
|
||||
|
||||
# 批量网格(自动冷启动 + 失败时种子步进回退)
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml --dry-run # 预览
|
||||
python3 cno_grid/src/run_grid.py cno_grid/config.yaml # 正式跑
|
||||
```
|
||||
|
||||
### 网格运行策略
|
||||
|
||||
**桥头堡机制**(手动):在跑完整网格前,先在难收敛区附近算几个"桥头堡"
|
||||
模型,建立种子库。例如高温区先算:
|
||||
```bash
|
||||
# 1. 算 80K He-rich cno-4(冷启动可成功)
|
||||
python3 cno_grid/src/run_one.py --teff 80000 --logg 6.5 --loghe 2 \
|
||||
--logc -4 --logn -4 --logo -4
|
||||
# 2. 用它作种子算 80K He-poor cno-4(种子步进)
|
||||
python3 cno_grid/src/seed_step.py --teff 80000 --logg 6.5 --loghe -4 \
|
||||
--logc -4 --logn -4 --logo -4 \
|
||||
--seed cno_grid/results/t80000_g6.5_he2_c-4_n-4_o-4/t80000_g6.5_he2_c-4_n-4_o-4.7
|
||||
# 3. 之后跑 run_grid.py 时,find_seed 会自动发现这些已收敛的邻居
|
||||
```
|
||||
|
||||
**run_grid 的种子步进回退流程**:
|
||||
```
|
||||
对每个网格点 P:
|
||||
1. 检查 conv.json: 若已 converged → skip
|
||||
2. find_seed(P): 查找已收敛邻居(同 family 优先,按 CNO 距离)
|
||||
3. 冷启动 run_one(DEFAULT_CHAIN):
|
||||
a. 成功 → 完成
|
||||
b. 失败 + seed_step_fallback=true + 找到种子 →
|
||||
移动失败结果到 <P>.coldfail/
|
||||
用 SEED_STEP_CHAIN + seed 重试
|
||||
4. 写 grid_status.json 汇总(含 seed_step_retries 计数)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6X. ICRSW 修复方案(备选 —— 当前未实施)
|
||||
|
||||
### 背景
|
||||
`ICRSW`(Hummer & Voels 1988 碰撞-辐射开关)在 tlusty208 中是**未完成的
|
||||
集成**——`SUBROUTINE SWITCH`(`tlusty208.f:4556`)写好了完整的 CRSW 计算
|
||||
逻辑,下游消费方代码(`tlusty208.f:6341-8021`、`18201`、`18252` 三处
|
||||
`RRU/RRD * CRSW(ID)`)也都到位,但**主迭代循环中缺少 `CALL SWITCH`**
|
||||
(`PROGRAM TLUSTY` 主循环在 line 30-58,`SUBROUTINE SOLVE` 在 line 14420,
|
||||
两者都没有调用 SWITCH)。
|
||||
|
||||
结果:`CRSW(ID)` 永远保持默认值 `UN`(=1.0,line 1812 `CRSW(ID)=UN`),
|
||||
所有 `RRU/RRD * CRSW(ID)` 都是无效操作。
|
||||
|
||||
### 修复需要的步骤
|
||||
|
||||
**步骤 1:检查编译环境**
|
||||
```bash
|
||||
which gfortran || apt list --installed 2>/dev/null | grep -i fortran
|
||||
# 若无,安装:sudo apt install gfortran
|
||||
```
|
||||
|
||||
**步骤 2:定位主迭代循环**
|
||||
|
||||
主循环在 `tlusty/tlusty208.f:30-58`(行 28 是注释头,行 30 是 `10 ITER=ITER+1`,
|
||||
行 58 是 `20 CONTINUE`):
|
||||
```fortran
|
||||
10 ITER=ITER+1
|
||||
CALL RESOLV ! 形式解
|
||||
IF(IACC.GT.0) CALL ACCEL2
|
||||
IF(NN.GT.MSMX) THEN
|
||||
CALL SOLVE ! 完全线性化
|
||||
ELSE
|
||||
CALL SOLVES
|
||||
END IF
|
||||
CALL TIMING(2,ITER)
|
||||
GO TO 10
|
||||
```
|
||||
|
||||
**步骤 3:在循环中插入 SWITCH 调用**
|
||||
|
||||
在 `ITER=ITER+1` 之后、`CALL RESOLV` 之前插入:
|
||||
```fortran
|
||||
10 ITER=ITER+1
|
||||
C ---- ICRSW 碰撞-辐射开关(修复)----
|
||||
C 首次迭代初始化 CRSW,后续迭代放大 CRSW 朝 1.0 趋近
|
||||
IF(ICRSW.GT.0) THEN
|
||||
IF(ITER.EQ.1) THEN
|
||||
CALL SWITCH(1) ! INITM=1: 初始化 CRSW=SWPFAC*min(C/R)
|
||||
ELSE
|
||||
CALL SWITCH(0) ! INITM=0: CRSW *= SWPINC
|
||||
END IF
|
||||
END IF
|
||||
CALL RESOLV
|
||||
...
|
||||
```
|
||||
|
||||
**步骤 4:验证变量在调用点已就绪**
|
||||
|
||||
`SWITCH` 子程序用到 `COLRAT(ITR,ID)`、`RRU(ITR,ID)`、`RRD(ITR,ID)`、
|
||||
`LINE(ITR)`、`FR0(ITR)`、`TEMP(ID)`、`HK`。需确认这些在 `ITER=ITER+1`
|
||||
之后已被前一迭代更新(或在首次迭代时已初始化)。若未就绪,可能需要
|
||||
把 SWITCH 调用移到 `CALL RESOLV` 之后。
|
||||
|
||||
**步骤 5:重新编译**
|
||||
```bash
|
||||
cd tlusty/
|
||||
# 备份原可执行
|
||||
cp tlusty.exe tlusty.exe.orig
|
||||
# 编译(具体命令取决于源码组织,可能是单文件或 Makefile)
|
||||
gfortran -O2 -o tlusty.exe tlusty208.f \
|
||||
IMPLIC.FOR BASICS.FOR ARRAY1.FOR ATOMIC.FOR MODELQ.FOR \
|
||||
ITERAT.FOR ALIPAR.FOR ODFPAR.FOR
|
||||
```
|
||||
|
||||
**步骤 6:测试**
|
||||
|
||||
跑已知难收敛的点(如 80K + He-poor + logCNO=-1)开/关 ICRSW,对比
|
||||
nc 阶段的迭代历史。如果 ICRSW 真正生效,开启后 iter 2 的尖峰应该被
|
||||
压低(CRSW < 1)。
|
||||
|
||||
```bash
|
||||
# 关 ICRSW(基线)
|
||||
python3 cno_grid/src/seed_step.py --teff 80000 --logg 6.5 --loghe -4 \
|
||||
--logc -1 --logn -1 --logo -1 --seed <seed> \
|
||||
2>&1 | tee /tmp/no_icrsw.log
|
||||
# 开 ICRSW(修复后)
|
||||
# 在 nst 里加 ICRSW=1,SWPFAC=1e-3,SWPLIM=1.0,SWPINC=2.0
|
||||
# ... 跑同样模型
|
||||
# 对比两次的 fort.9 iter 1-10 max_relc 演化
|
||||
```
|
||||
|
||||
### 修复风险评估
|
||||
|
||||
**好处**:
|
||||
- 可能解锁 80K + He-poor + 富金属区的收敛(最后一个未解决角落)
|
||||
- 是数值方法层面的修复,物理意义清晰
|
||||
|
||||
**风险**:
|
||||
- 重新编译可能引入其他问题(tlusty 源码依赖复杂)
|
||||
- SWITCH 集成后可能有未预见的 bug(作者本就没集成,可能有原因)
|
||||
- 编译器版本差异(原版可能用 f77/f90,gfortran 行为可能不同)
|
||||
|
||||
### 替代方案:网格层面规避
|
||||
|
||||
如果不想改源码,**现有种子步进方案已覆盖大部分情况**:
|
||||
- 20000-40000K:冷启动全区间可靠
|
||||
- 60000-80000K + He-rich / 低金属:冷启动或一步种子步进可解决
|
||||
- 60000-80000K + He-poor + 富金属(logCNO=-1):**真实物理极限**,
|
||||
网格如实标记未收敛(这是合理的——观测上这些极端参数组合的 sdB
|
||||
本就罕见)
|
||||
|
||||
**建议**:先用现有方案跑完整网格,统计未收敛点的比例和分布。
|
||||
如果未收敛点占总网格 <5%,无需修复 ICRSW;如果占比高且集中在
|
||||
可观测的重要参数区,再考虑修复。
|
||||
|
||||
### 每阶段信息记录
|
||||
conv.json 记录每阶段的 converged/max_relc/elapsed_sec,以及 synspec_sec。
|
||||
|
||||
---
|
||||
|
||||
## 7. 下一步建议
|
||||
|
||||
### 立即可行(已验证配方 + 种子步进)
|
||||
- **冷启动跑 20000-40000K + logC/N/O=-4 到 -1**:可靠收敛,无需种子
|
||||
- **种子步进跑 60000-80000K + He-rich 或低金属**:用冷启动建"桥头堡",
|
||||
再以它为种子推进到目标点
|
||||
- **物理极限标注**:80K + He-poor + logCNO=-1 是真实物理极限,
|
||||
网格如实标记未收敛(不强制成功)
|
||||
|
||||
### 待完善
|
||||
- **run_grid.py 自动种子策略**:现在是冷启动失败即标记失败;
|
||||
应扩展为先尝试冷启动,失败则查找邻居已收敛模型作种子重试,
|
||||
再失败则尝试中间丰度点作跳板(如 cno-4 → cno-2 → cno-1)。
|
||||
- **种子库管理**:网格计算时按 Teff/logg 分组,每组先算最容易的点
|
||||
(He-rich 或低金属),建立种子库,再扩散到难收敛点。
|
||||
- **synspec 高温区 NaN 问题**:80K 大气收敛但 synspec 谱有 74% NaN。
|
||||
需要单独排查(可能是 gfVIS99.dat 谱线表对 80K 不兼容,或某些 CNO
|
||||
高价离子模型原子在该温度下数值溢出)。
|
||||
|
||||
### 关键教训
|
||||
1. **先核实物理参数**:之前花了大量时间调 CHMAX/IDLTE/ORELAX/He能级/NFREAD,
|
||||
真正的根因(丰度范围过高 + 冷启动初猜太远)却一直被忽略。
|
||||
2. **冷启动 ≠ 唯一选择**:LTE grey 冷启动在高温 He-poor 模型上必然失败,
|
||||
但这**不是物理极限**,只是初猜太差。种子步进是 Peter Nemeth 邮件早就
|
||||
建议的方法("减小模型间步长"),只是之前一直没正确实现。
|
||||
3. **源码分析的价值**:通过 subagent 读 tlusty208.f 才发现:
|
||||
- LTGREY 标志的真正含义(T=生成灰大气,F=读 fort.8)—— 种子步进的物理基础
|
||||
- ICRSW 是**死代码**(SWITCH 子程序定义了但从未被 CALL)—— 看似可用的
|
||||
参数实际无效,必须实测验证
|
||||
4. **物理极限要承认**:80K + He-poor + 金属量 0.1×H 的组合,
|
||||
即使用尽所有稳定化手段也不收敛。这是物理极限,不是工程问题。
|
||||
网格应如实记录未收敛而非强行通过。
|
||||
|
||||
---
|
||||
|
||||
## 8. 邮件往来要点(Peter Nemeth)
|
||||
|
||||
完整邮件在 `hot_subdwarf/letter/`(已逐条核对原文)。要点:
|
||||
1. He-rich 模型难收敛属正常(原文:"Helium-rich models struggle a lot ...
|
||||
That is normal")
|
||||
2. He 用最复杂模型原子(原文:"I would always use the 24-level He1 and
|
||||
20-level He2 model atoms")— 但实测在 `.5` 里声明 nlevs=14 对 nc 更稳定,
|
||||
两者目标不同(Peter 关注光谱精度,我们关注收敛稳定性)
|
||||
3. ITEK 可调(原文:"you can set it to 3, 15, and 100")— 实测 100 overshoot,
|
||||
且不设(默认 4)最好
|
||||
4. 模型链:粗→精 CHMAX;减小模型间步长(原文:"You can try decreasing the
|
||||
steps in between models")← **本次种子步进正是这一条的正确实现**
|
||||
(LTGREY=F 热启动 + 邻居模型作种子)
|
||||
|
||||
---
|
||||
|
||||
## 9. 参考文件索引
|
||||
|
||||
| 文件 | 内容 |
|
||||
|------|------|
|
||||
| `/home/dckj/program/tlusty/tests/cno_sdspectrum/GUIDE.md` | 用户原始指南(35000K 验证配方)。注意:在 tl208-s54/ 上一级目录 |
|
||||
| `cno_grid/src/run_one.py` | 三步链实现(DEFAULT_CHAIN = 正确配方)|
|
||||
| `cno_grid/src/gen_input5.py` | .5 生成器(He nlevs=14, NFREAD=2000)|
|
||||
| `cno_grid/src/seed_step.py` | **种子步进实现**(高温/难收敛点)|
|
||||
| `cno_grid/src/run_grid.py` | 6 维网格调度器(冷启动 + 种子步进回退)|
|
||||
| `cno_grid/src/check_conv.py` | fort.9 解析与收敛判定 |
|
||||
| `cno_grid/config.yaml` | 网格配置(链、seed_step_fallback 等)|
|
||||
| `cno_grid/PIPELINE.md` | 计算流程文档(阶段/并行/统计)|
|
||||
| `cno_grid/results/` | 测试模型结果(含 conv.json)|
|
||||
| `cno_grid/results/bound_*.log` | 8 点边界测试日志(2026-07-21)|
|
||||
| `cno_grid/results/seed_step/` | 种子步进验证结果 |
|
||||
| `cno_grid/run_boundary_corrected.sh` | 边界测试启动脚本 |
|
||||
| `hot_subdwarf/letter/` | Peter Nemeth 邮件 |
|
||||
@@ -0,0 +1,370 @@
|
||||
# CNO 网格完整计算流程
|
||||
|
||||
> 本文档说明完整理论光谱网格的计算流程:每个网格点的计算阶段、每阶段的配置、
|
||||
> 配置原理、CPU/并行机制、以及如何统计每个阶段的信息(时间、收敛等)。
|
||||
|
||||
---
|
||||
|
||||
## 1. 总体架构
|
||||
|
||||
```
|
||||
config.yaml (网格点 + 收敛链配置)
|
||||
│
|
||||
▼
|
||||
run_grid.py ── 生成 6 维笛卡尔积参数点
|
||||
│ 断点续算(跳过已成功) / 种子复用(最近邻) / 失败隔离
|
||||
│
|
||||
├── worker 1 ── run_one.py ── 点 A
|
||||
├── worker 2 ── run_one.py ── 点 B 每个 worker 独立工作目录
|
||||
├── ... 互不干扰,24 核并行
|
||||
└── worker 24 ── run_one.py ── 点 X
|
||||
│
|
||||
▼
|
||||
三步链(lte→nc→nl) + synspec
|
||||
│
|
||||
▼
|
||||
results/<模型名>/
|
||||
conv.json ← 阶段信息(收敛/迭代/时间)
|
||||
*.spec/.cont ← 光谱
|
||||
*.7 ← 各阶段大气
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 每个网格点的计算阶段
|
||||
|
||||
每个网格点(一组 Teff/logg/logHe/logC/logN/logO 参数)经过 **4 个阶段**:
|
||||
|
||||
| 阶段 | 程序 | 做什么 | 典型耗时 |
|
||||
|------|------|--------|---------|
|
||||
| 1. LTE 灰大气 | tlusty | `T T` 模式,解析求灰色 T(τ) 结构 | 1-3 秒 |
|
||||
| 2. nc(NLTE 连续谱)| tlusty | `F F` + `ilvlin=0`,收敛电离平衡(无线跃迁)| 1-10 分钟 |
|
||||
| 3. nl(NLTE 含线)| tlusty | `F F` + `ilvlin=100`,加全部谱线跃迁 | 5-20 分钟 |
|
||||
| 4. synspec | synspec | 用 nl 大气合成可观测光谱 | 3-10 秒 |
|
||||
|
||||
**阶段间依赖**:1→2→3→4 严格顺序。每阶段用上一阶段的 `.7` 大气作种子(fort.8)。
|
||||
|
||||
### 为什么是这 4 个阶段(原理)
|
||||
|
||||
Tlusty 的 NLTE 求解用**迭代线性化**(complete linearization)。线性化的收敛半径
|
||||
有限——当初猜离真解太远时迭代发散。四个阶段逐步缩小初猜与真解的差距:
|
||||
|
||||
- **阶段1(LTE 灰大气)**:LTE + 灰色不透明度假设下解析求温度结构。提供物理
|
||||
合理的起点,不需要种子(从零开始)。
|
||||
- **阶段2(nc 连续谱)**:切换到 NLTE,但 `ilvlin=0` 不含束缚-束缚线跃迁。
|
||||
线跃迁是统计平衡方程中最敏感的非线性项;先不加线,只收敛电离平衡(光致电离
|
||||
+复合),得到稳定的 NLTE 布居数结构。**跳过此步直接 grey→含线 NLTE 必发散。**
|
||||
- **阶段3(nl 含线)**:加入全部线跃迁(ilvlin=100)。从已收敛的 nc 种子起步,
|
||||
线扰动小,快速收敛(典型 ~15 次迭代)。
|
||||
- **阶段4(synspec)**:用 nl 阶段收敛的大气模型,计算指定波长范围的合成光谱。
|
||||
|
||||
---
|
||||
|
||||
## 3. 每阶段的配置信息与原理
|
||||
|
||||
### 3.1 `.5` 文件(每阶段一份,三阶段相同 NATOMS/ions,只改 3 处)
|
||||
|
||||
```
|
||||
第1行: TEFF GRAV (三阶段相同:目标参数)
|
||||
第2行: LTE LTGRAY (阶段1=T T,阶段2/3=F F)
|
||||
第3行: nst 文件名 (阶段1=nst_lte, 阶段2=nst_nc, 阶段3=nst_nl)
|
||||
第4行: NFREAD (=50, 频率点数)
|
||||
第5行: NATOMS (=8: H,He,空×3,C,N,O)
|
||||
第6+行: atoms (mode abn modpf) (C/N/O 的 mode=2 显式NLTE, abn=10^logX)
|
||||
ions段: iat iz nlevs ilast ilvlin nonstd typion filei
|
||||
(阶段1/2: ilvlin=0; 阶段3: ilvlin=100 ← 关键区别)
|
||||
```
|
||||
|
||||
**为什么 NATOMS/ions 三阶段必须相同**:每阶段的 `.7` 大气记录了每个能级的
|
||||
布居数。种子与目标的能级结构必须一一对应,否则读取时索引错位 → NaN。
|
||||
|
||||
### 3.2 nst 文件(非标准参数,每阶段不同)
|
||||
|
||||
**阶段1(LTE 灰大气)—— 保持干净,不加稳定化参数**:
|
||||
```
|
||||
ND=50,VTB=2.,NITER=0
|
||||
```
|
||||
- `NITER=0`:灰大气不迭代,只做一次形式解。
|
||||
|
||||
**阶段2(nc)和阶段3(nl)—— 频率细化(用户验证配方,不设 CHMAX/ITEK)**:
|
||||
```
|
||||
ND=50,NLAMBD=3,VTB=2.,ISPODF=1,DDNU=50.,CNU1=6.,NITER=<阶段>
|
||||
IELCOR=-1
|
||||
```
|
||||
- nc: NITER=50, nl: NITER=100
|
||||
- **不设 CHMAX**(用默认 0.001,强迫 nc 真正收敛)
|
||||
- **不设 ITEK**(用默认 4)
|
||||
|
||||
每个参数的作用与原理:
|
||||
|
||||
| 参数 | nc值 | nl值 | 作用 | 为什么这样设 |
|
||||
|------|------|------|------|-------------|
|
||||
| `ND` | 50 | 50 | 大气深度点数 | sdB 标准配置 |
|
||||
| `NLAMBD` | 3 | 3 | lambda 迭代频率点数 | 频率网格细化(用户验证配方) |
|
||||
| `VTB` | 2. | 2. | 微湍流速度 km/s | sdB 典型值 |
|
||||
| `ISPODF` | 1 | 1 | 频率网格开关 | 启用细化频率网格 |
|
||||
| `DDNU` | 50. | 50. | 频率间隔因子 | 频率网格细化参数 |
|
||||
| `CNU1` | 6. | 6. | 频率网格起点 | 频率网格细化参数 |
|
||||
| `NITER` | 50 | 100 | 最大迭代数 | nc 给 50 次;nl 给 100 次 |
|
||||
| `IELCOR` | -1 | -1 | 电子密度修正 | 关闭 |
|
||||
|
||||
> **关键:不设 CHMAX(用默认 0.001)、不设 ITEK(用默认 4)、不设 IDLTE/ORELAX。**
|
||||
> 之前版本设了 CHMAX=0.1 导致 nc 没真正收敛,是大部分失败的根本原因。
|
||||
> 详见 EXPERIENCE.md §4 的错误记录。
|
||||
|
||||
### 3.3 synspec 配置(fort.55.lin + 谱线表)
|
||||
|
||||
```
|
||||
fort.55.lin 第6行: WLMIN WLMAX WLSTEP ... CUTOFF ...
|
||||
谱线表 fort.19: data/gfVIS99.dat (含 C 1412 / N 2396 / O 1885 条线)
|
||||
```
|
||||
- 当前用 3000-7000Å(光学波段,覆盖 C II 4267、C III 4647 等)。
|
||||
- 大气来自 nl 阶段的 `.7`(复制为 fort.8)。
|
||||
|
||||
---
|
||||
|
||||
## 4. CPU 与并行机制
|
||||
|
||||
### 4.1 每个网格点只用一个 CPU 核
|
||||
|
||||
**是的。** tlusty.exe 和 synspec.exe 是 Fortran 编译的单线程程序,每个实例只用
|
||||
1 个 CPU 核。网格点的并行不是靠程序内部的多线程,而是靠**同时启动多个程序实例**。
|
||||
|
||||
### 4.2 如何做到并行
|
||||
|
||||
`run_grid.py` 用 Python 的 `multiprocessing.Pool`(`run_grid.py:271`):
|
||||
|
||||
```python
|
||||
with Pool(nworkers) as pool:
|
||||
for res in pool.imap_unordered(_worker, worker_args):
|
||||
...
|
||||
```
|
||||
|
||||
- `nworkers`(config.yaml,当前=24):同时运行的 worker 进程数。
|
||||
- 每个 worker 是一个独立的 Python 子进程,调用 `run_one.py` 跑一个网格点
|
||||
(在独立的工作目录里,互不干扰)。
|
||||
- `imap_unordered`:哪个点先完成就先回收,立即分配下一个点(动态负载均衡)。
|
||||
- 24 核机器跑 24 个 worker = 24 个 tlusty 实例同时跑 = 满载利用。
|
||||
|
||||
**关键:每个 worker 用独立工作目录**(`results/<模型名>/`),避免 fort.* 文件
|
||||
冲突。这是并行安全的基础。
|
||||
|
||||
### 4.3 吞吐量估算
|
||||
|
||||
| 模型类型 | 单点耗时 | 24核并行吞吐 |
|
||||
|---------|---------|-------------|
|
||||
| 80000K(待解决)| — | 目前 nc 发散,需专业策略 |
|
||||
| 20000-40000K(标准)| ~15-25 分钟 | ~72-110 点/小时 |
|
||||
| 高金属 CNO=10×H | ~30 分钟 | ~48 点/小时 |
|
||||
|
||||
128 点疏网格约需 2-3 小时;8192 点完整网格约需 5 天。
|
||||
|
||||
---
|
||||
|
||||
## 5. 如何统计每阶段信息
|
||||
|
||||
### 5.1 当前已记录的信息(conv.json)
|
||||
|
||||
每个网格点完成后,`results/<模型名>/conv.json` 记录:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "t40000_g6.0_he0_c1_n1_o1",
|
||||
"params": {"teff":40000, "logg":6.0, "loghe":0, "logc":1, "logn":1, "logo":1},
|
||||
"converged": true,
|
||||
"final_max_relc": 0.0069,
|
||||
"atmosphere_has_nan": false,
|
||||
"synspec_rc": 0,
|
||||
"elapsed_sec": 1714.1, ← 总耗时(所有阶段+synspec之和)
|
||||
"seed": null,
|
||||
"stages": [
|
||||
{
|
||||
"label": "lte",
|
||||
"converged": true,
|
||||
"final": {"itek":3, "rc":0, "max_relc":0.0,
|
||||
"note":"NITER=0 grey start"}
|
||||
},
|
||||
{
|
||||
"label": "nc",
|
||||
"converged": false, ← nc 不要求收敛,作种子即可
|
||||
"final": {"itek":3, "rc":0, "max_relc":0.957,
|
||||
"worst_depth":1, "last_iter":50, "n_depths":50}
|
||||
},
|
||||
{
|
||||
"label": "nl",
|
||||
"converged": true,
|
||||
"final": {"itek":3, "rc":0, "max_relc":0.0069,
|
||||
"worst_depth":1, "last_iter":17, "n_depths":50}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
每阶段记录:`converged`(是否收敛)、`max_relc`(最大相对变化)、
|
||||
`worst_depth`(最差深度点)、`last_iter`(迭代次数)、`n_depths`(深度点数)。
|
||||
|
||||
### 5.2 每阶段时间记录(已实现)
|
||||
|
||||
`run_one.py` 现在在每个阶段的循环开始/结束处计时,conv.json 里每个 stage 有
|
||||
`elapsed_sec`,synspec 也有单独的 `synspec_sec`:
|
||||
|
||||
```json
|
||||
"stages": [
|
||||
{"label":"lte", "elapsed_sec": 27.3, "converged":true, ...},
|
||||
{"label":"nc", "elapsed_sec": 408.4, "converged":false, ...},
|
||||
{"label":"nl", "elapsed_sec": 7.8, "converged":true, ...}
|
||||
],
|
||||
"synspec_sec": 3.1,
|
||||
"elapsed_sec": 446.2
|
||||
```
|
||||
|
||||
统计所有模型的阶段时间分布:
|
||||
```bash
|
||||
python3 -c "
|
||||
import json,glob
|
||||
for f in sorted(glob.glob('results/*/conv.json')):
|
||||
j=json.load(open(f))
|
||||
times = {s['label']:s.get('elapsed_sec',0) for s in j['stages']}
|
||||
print('%-30s lte=%5.0fs nc=%5.0fs nl=%5.0fs syn=%4.0fs total=%5.0fs' % (
|
||||
j['name'], times.get('lte',0), times.get('nc',0), times.get('nl',0),
|
||||
j.get('synspec_sec',0), j['elapsed_sec']))
|
||||
"
|
||||
```
|
||||
|
||||
### 5.3 统计整个网格的信息
|
||||
|
||||
`run_grid.py` 完成后写 `results/grid_status.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"total": 128,
|
||||
"elapsed_sec": 9600,
|
||||
"counts": {"converged": 120, "unfinished": 5, "error": 2, "skipped": 1},
|
||||
"models": [
|
||||
{"name":"t20000_...", "status":"converged", "max_relc":0.0065},
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
汇总统计命令:
|
||||
```bash
|
||||
# 成功率
|
||||
python3 -c "import json; j=json.load(open('results/grid_status.json')); print(j['counts'])"
|
||||
# 所有收敛模型的 max_relc 分布
|
||||
python3 -c "
|
||||
import json,glob
|
||||
for f in sorted(glob.glob('results/*/conv.json')):
|
||||
j=json.load(open(f))
|
||||
if j['converged']:
|
||||
print(j['name'], j['final_max_relc'], str(j['elapsed_sec'])+'s')
|
||||
"
|
||||
# 失败/未收敛的模型
|
||||
python3 -c "
|
||||
import json,glob
|
||||
for f in sorted(glob.glob('results/*/conv.json')):
|
||||
j=json.load(open(f))
|
||||
if not j['converged']:
|
||||
print(j['name'], 'FAILED', j.get('note',''))
|
||||
"
|
||||
```
|
||||
|
||||
### 5.4 单个网格点的详细收敛诊断
|
||||
|
||||
```bash
|
||||
# 看某阶段的迭代收敛趋势(fort.9)
|
||||
python3 src/check_conv.py results/<模型>/<模型>.nl.9 --chmax 0.01
|
||||
|
||||
# 画光谱(标出 CNO 诊断线位置)
|
||||
python3 src/plot_spec.py results/<模型>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 完整操作步骤
|
||||
|
||||
### 第1步:配置网格密度(config.yaml 的 grid 段)
|
||||
```yaml
|
||||
grid:
|
||||
teff: [20000, 30000, 40000, 60000] # 各维采样点列表
|
||||
logg: [5.0, 6.0]
|
||||
loghe: [-2, 0]
|
||||
logc: [-1, 1]
|
||||
logn: [-1, 1]
|
||||
logo: [-1, 1]
|
||||
```
|
||||
|
||||
### 第2步:设置环境变量
|
||||
```bash
|
||||
export TLUSTY=/home/dckj/program/tlusty/tl208-s54
|
||||
```
|
||||
|
||||
### 第3步:预览(dry-run)
|
||||
```bash
|
||||
cd $TLUSTY/cno_grid
|
||||
python3 src/run_grid.py config.yaml --dry-run
|
||||
# 输出:grid: 64 points total, N already done, M to compute
|
||||
```
|
||||
|
||||
### 第4步:启动批量计算(后台并行)
|
||||
```bash
|
||||
nohup python3 src/run_grid.py config.yaml > results/grid_run.log 2>&1 &
|
||||
```
|
||||
|
||||
### 第5步:监控
|
||||
```bash
|
||||
tail -f results/grid_run.log # 实时进度
|
||||
cat results/grid_status.json # 汇总(完成后才有)
|
||||
```
|
||||
|
||||
### 第6步:断点续算(中断后恢复,自动跳过已成功的)
|
||||
```bash
|
||||
python3 src/run_grid.py config.yaml # 重跑同一命令即可
|
||||
```
|
||||
|
||||
### 第7步:检查结果 + 画图
|
||||
```bash
|
||||
# 成功率
|
||||
python3 -c "import json;print(json.load(open('results/grid_status.json'))['counts'])"
|
||||
# 画某个模型光谱
|
||||
python3 src/plot_spec.py results/<模型名>
|
||||
```
|
||||
|
||||
### 第8步:加密网格(Phase 2)
|
||||
在 config.yaml 的各维列表里加更多点,重跑 `run_grid.py`(自动跳过已完成的,
|
||||
只算新点)。
|
||||
|
||||
---
|
||||
|
||||
## 7. 注意事项
|
||||
|
||||
1. **种子复用**:run_grid.py 会自动找最近邻已收敛的 `.7` 作种子,省去 LTE 阶段。
|
||||
但种子与目标的参数差不能太大(logg ≤0.5/步,Teff ≤5000K/步),否则发散。
|
||||
建议网格各维步长不要太大。
|
||||
|
||||
2. **断点续算判定**:`conv.json` 里 `converged=true` 的点会被跳过。假收敛
|
||||
(atmosphere_has_nan=true)的点会被重算。
|
||||
|
||||
3. **失败隔离**:单点失败(发散/崩溃)不中断整个网格,记入 grid_status.json
|
||||
的 error 列表。可在 config.yaml 放宽 CHMAX 或加 orelax 重试失败点。
|
||||
|
||||
4. **磁盘空间**:每个模型约 50-100MB(含中间文件)。8192 点约需 400-800GB。
|
||||
当前 932GB 可用,够完整网格。如不够可定期清理中间文件(保留 .spec/.cont/.7/conv.json)。
|
||||
|
||||
5. **并行安全**:每个 worker 用独立工作目录(results/<模型名>/),fort.* 文件
|
||||
不冲突。可安全并行。
|
||||
|
||||
6. **nst 文件行长限制(已修复)**:tlusty 的 nst 解析器有 ~72 字符的行宽限制。
|
||||
如果参数太多写在一行(如加了 IDLTE/IACC 后 >72 字符),行尾的参数会被
|
||||
静默截断。`write_nst()` 现在把参数分两行写(line1≤64c, line2 余下参数)。
|
||||
这是个隐蔽 bug——截断后 tlusty 不报错而是用默认值,导致"看似成功实则参数
|
||||
没生效"。
|
||||
|
||||
7. **fort.84 残留(已修复)**:tlusty 运行时会在工作目录写 fort.84(nst 参数的
|
||||
内部表示)。如果下一次 tlusty 运行(不同 NATOMS)读到旧的 fort.84,会报
|
||||
"Bad integer for item 48" 崩溃。`run_tlusty()` 现在每次运行前删除 fort.84。
|
||||
|
||||
8. **收敛可靠性(如实)**:用正确配方(无 CHMAX/ITEK, 14-level He, NFREAD=2000)
|
||||
重新验证后,35000K 成功(nl=0.00078),但 40000K+ 的 nc 仍然震荡发散。
|
||||
之前版本的"8/8 边界全部成功"不准确(基于错误的 CHMAX=0.1)。
|
||||
40000K+ 高温区需要种子步进或 ICRSW 等专业策略。详见 EXPERIENCE.md。
|
||||
@@ -0,0 +1,54 @@
|
||||
# 6 维 CNO NLTE 热亚矮星网格的配置文件。
|
||||
# 所有丰度均为 log10(nX/nH);.5 文件中的 abn 字段设为 10**logX。
|
||||
#
|
||||
# 网格各维范围:
|
||||
# Teff : 20000 - 80000 K
|
||||
# logg : 5.0 - 6.5
|
||||
# logHe: -4 - 2 (He/H 数密度比:1e-4 .. 100)
|
||||
# logC : -4 - -1 (C/H:1e-4 .. 0.1;太阳 C/H≈-3.6,落在区间内)
|
||||
# logN : -4 - -1 (N/H:太阳 N/H≈-4.2)
|
||||
# logO : -4 - -1 (O/H:太阳 O/H≈-3.3)
|
||||
# CNO 范围已修正为物理上的 sdB 范围,不再是超太阳(旧版 -2..1 会发散)
|
||||
|
||||
# ---- 网格轴:显式列出各维采样点 ----
|
||||
grid:
|
||||
teff: [20000, 30000, 40000, 60000]
|
||||
logg: [5.0, 6.0]
|
||||
loghe: [-2, 0]
|
||||
logc: [-4, -2, -1]
|
||||
logn: [-4, -2, -1]
|
||||
logo: [-4, -2, -1]
|
||||
# 共 4*2*2*3*3*3 = 432 个点
|
||||
|
||||
# ---- 收敛链 ----
|
||||
# 已验证的三步配方 (tests/cno_sdspectrum, Teff=35000 logg=5.5):
|
||||
# LTE grey (T T, NITER=0) -> NLTE 连续谱 (nc, ilvlin=0) -> NLTE 谱线 (nl, ilvlin=100)
|
||||
# nc 步是关键:在不考虑谱线扰动下收敛 NLTE 电离平衡,给 nl 一个稳定种子。
|
||||
# 跳过 nc(grey -> 完整 NLTE)会发散。
|
||||
#
|
||||
# 重要:不要在 nst 里设 CHMAX/ITEK,用 tlusty 默认值(CHMAX=0.001, ITEK=4)。
|
||||
# 设 CHMAX=0.1 会让 nc 提前停止,给 nl 一个坏种子导致发散。
|
||||
chain:
|
||||
- {label: lte, lte: T, ltgray: T, ilvlin: 0, require_converged: false, niter: 0}
|
||||
- {label: nc, lte: F, ltgray: F, ilvlin: 0, require_converged: false, niter: 50}
|
||||
- {label: nl, lte: F, ltgray: F, ilvlin: 100, require_converged: true, niter: 100}
|
||||
itek_fallback: [] # 留空:ITEK 默认值最稳;非空会重试(实测无效)
|
||||
niter: 100 # 每个 tlusty 运行的默认最大迭代数 (nst NITER)
|
||||
|
||||
# ---- 种子步进回退(NEW)----
|
||||
# 冷启动失败时,自动用已收敛的邻居模型作种子,用 LTGRAY=F 热启动重试。
|
||||
# 这是高温 He-poor / 富金属区收敛的关键(见 EXPERIENCE.md §5Y)。
|
||||
# 失败的冷启动结果会备份到 <model>.coldfail/ 目录。
|
||||
seed_step_fallback: true
|
||||
|
||||
# ---- 执行参数 ----
|
||||
nworkers: 24 # 并行 worker 数(每次 tlusty 运行是单线程的;
|
||||
# 想用更多核心就调大;每个 worker 需要独立工作目录)
|
||||
timeout_sec: 3600 # 单模型墙钟时间上限
|
||||
resume: true # 跳过已完成的模型(conv.json 中 converged=true)
|
||||
|
||||
# ---- 路径(相对 TLUSTY,除非给出绝对路径)----
|
||||
template: templates/cno_atmos.5.tpl
|
||||
fort55: templates/fort.55.lin
|
||||
linelist: data/gfVIS99.dat
|
||||
results: results
|
||||
@@ -0,0 +1,25 @@
|
||||
# 边界测试配置:5 个代表性难点 + 已验证中心点
|
||||
# 注:此 config 显式设置了 CHMAX/ITEK(与主 config.yaml 不同),用于
|
||||
# 探索宽松阈值下的边界行为;主网格运行不应使用这些值。
|
||||
grid:
|
||||
teff: [20000, 40000, 80000]
|
||||
logg: [5.0, 6.0, 6.5]
|
||||
loghe: [-4, 0, 2]
|
||||
logc: [0]
|
||||
logn: [0]
|
||||
logo: [0]
|
||||
|
||||
# 此处显式 CHMAX/ITEK 仅用于边界测试探索;主网格保持默认(不写这两个键)
|
||||
chain:
|
||||
- {label: lte, lte: T, ltgray: T, ilvlin: 0, chmax: 0.1, itek: 3, require_converged: false, niter: 0}
|
||||
- {label: nc, lte: F, ltgray: F, ilvlin: 0, chmax: 0.1, itek: 3, require_converged: false, niter: 50}
|
||||
- {label: nl, lte: F, ltgray: F, ilvlin: 100, chmax: 0.01, itek: 3, require_converged: true, niter: 100}
|
||||
itek_fallback: [15] # nl 失败时回退到 ITEK=15 重试(注意:实测对多数点无效)
|
||||
niter: 100
|
||||
nworkers: 1
|
||||
timeout_sec: 7200 # 边界点可能很慢,给 2 小时
|
||||
resume: true
|
||||
template: templates/cno_atmos.5.tpl
|
||||
fort55: templates/fort.55.lin
|
||||
linelist: data/gfVIS99.dat
|
||||
results: results
|
||||
@@ -0,0 +1,31 @@
|
||||
# 用于验证 run_grid.py 中 seed_step 回退功能的测试配置。
|
||||
# 包含 3 个有策略意义的点:
|
||||
# - 80k/6.5/+2/-4/-4/-4 (冷启动可成功,将作为桥头堡)
|
||||
# - 80k/6.5/-4/-4/-4/-4 (冷启动失败,从桥头堡种子步进)
|
||||
# - 80k/6.5/-4/-2/-2/-2 (冷启动失败,从 cno-4 的贫 He 模型种子步进)
|
||||
|
||||
grid:
|
||||
teff: [80000]
|
||||
logg: [6.5]
|
||||
loghe: [-4, 2]
|
||||
logc: [-4, -2]
|
||||
logn: [-4, -2]
|
||||
logo: [-4, -2]
|
||||
# 下面通过 --only 过滤到具体几个点
|
||||
|
||||
chain:
|
||||
- {label: lte, lte: T, ltgray: T, ilvlin: 0, require_converged: false, niter: 0}
|
||||
- {label: nc, lte: F, ltgray: F, ilvlin: 0, require_converged: false, niter: 50}
|
||||
- {label: nl, lte: F, ltgray: F, ilvlin: 100, require_converged: true, niter: 100}
|
||||
itek_fallback: []
|
||||
niter: 100
|
||||
|
||||
nworkers: 1
|
||||
timeout_sec: 1800
|
||||
resume: true
|
||||
seed_step_fallback: true
|
||||
|
||||
template: templates/cno_atmos.5.tpl
|
||||
fort55: templates/fort.55.lin
|
||||
linelist: data/gfVIS99.dat
|
||||
results: results_test_grid
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# 边界点测试脚本(旧版,使用 logCNO=0)。每个点跑完后把收敛情况追加到日志。
|
||||
# 注:当前推荐使用 run_boundary_corrected.sh(修正后的丰度范围)。
|
||||
export TLUSTY=/home/dckj/program/tlusty/tl208-s54
|
||||
cd $TLUSTY/cno_grid
|
||||
LOG=results/boundary_runs.log
|
||||
echo "=== 边界测试开始 $(date) ===" > $LOG
|
||||
|
||||
# 跑一个边界点,并把结果摘要追加到日志
|
||||
run_pt() {
|
||||
local teff=$1 logg=$2 loghe=$3 name=$4
|
||||
echo ">>> [$name] teff=$teff logg=$logg logHe=$loghe $(date)" >> $LOG
|
||||
python3 src/run_one.py --teff $teff --logg $logg --loghe $loghe \
|
||||
--logc 0 --logn 0 --logo 0 >> $LOG 2>&1
|
||||
# 记录结果
|
||||
python3 -c "
|
||||
import json,glob,os
|
||||
d='t{}_g{:.1f}_he{:.0f}_c0_n0_o0'.format(int($teff),$logg,$loghe)
|
||||
p=os.path.join('results',d,'conv.json')
|
||||
try:
|
||||
j=json.load(open(p))
|
||||
print(' {} {} {} -> converged={} max_relc={} elapsed={}'.format(
|
||||
'$name',$teff,$logg,j['converged'],j.get('final_max_relc'),j.get('elapsed_sec')),file=open($LOG,'a'))
|
||||
except Exception as e: print(' $name ERROR:',e,file=open($LOG,'a'))
|
||||
" >> $LOG 2>&1
|
||||
}
|
||||
|
||||
# 边界点1已在独立进程跑,这里跑2-5
|
||||
run_pt 80000 6.5 2 "b2_高温He-rich"
|
||||
run_pt 80000 6.5 -4 "b3_高温He-poor"
|
||||
run_pt 40000 6.0 0 "b4_中心点高金属参考"
|
||||
run_pt 20000 6.5 -4 "b5_低温贫He"
|
||||
|
||||
echo "=== 全部完成 $(date) ===" >> $LOG
|
||||
Executable
+45
@@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
# 修正丰度范围(logCNO = -4..-1)后的边界测试。
|
||||
# 之前的"高温发散"实际上是因为 abn=1.0(logX=0)相当于 4000 倍太阳丰度。
|
||||
# 此处用物理上合理的丰度重新跑这组边界。
|
||||
#
|
||||
# 测试点(全部后台并行运行):
|
||||
# B1 80000/6.5/-4/ -1/-1/-1 高温贫 He、富金属(CNO 为 0.1 倍 H)
|
||||
# B2 80000/6.5/-4/ -4/-4/-4 高温贫 He、近太阳 CNO
|
||||
# B3 80000/6.5/ 2/ -1/-1/-1 高温富 He(物理上最难的点)
|
||||
# B4 80000/6.5/ 2/ -4/-4/-4 高温富 He、近太阳
|
||||
# B5 20000/5.0/ 2/ -1/-1/-1 低温富 He、富金属
|
||||
# B6 20000/5.0/ 2/ -4/-4/-4 低温富 He、近太阳
|
||||
# B7 40000/5.5/ 0/ -4/-4/-4 中温类太阳 CNO(丰度下限)
|
||||
# B8 60000/6.0/ 0/ -1/-1/-1 中高温富金属抽查点
|
||||
|
||||
set -u
|
||||
cd /home/dckj/program/tlusty/tl208-s54
|
||||
RESULTS=cno_grid/results
|
||||
mkdir -p "$RESULTS"
|
||||
|
||||
# 后台运行一个模型,把 stdout/stderr 写入对应日志文件
|
||||
run_bg() {
|
||||
local tag="$1"; shift
|
||||
local logfile="$RESULTS/bound_${tag}.log"
|
||||
echo "[$(date +%H:%M:%S)] launching $tag -> $logfile"
|
||||
nohup python3 cno_grid/src/run_one.py "$@" > "$logfile" 2>&1 &
|
||||
echo " pid=$!"
|
||||
}
|
||||
|
||||
# 高温边界(80000K)—— 最重要的复测点
|
||||
run_bg 80k_he-4_cno-1 --teff 80000 --logg 6.5 --loghe -4 --logc -1 --logn -1 --logo -1
|
||||
run_bg 80k_he-4_cno-4 --teff 80000 --logg 6.5 --loghe -4 --logc -4 --logn -4 --logo -4
|
||||
run_bg 80k_he2_cno-1 --teff 80000 --logg 6.5 --loghe 2 --logc -1 --logn -1 --logo -1
|
||||
run_bg 80k_he2_cno-4 --teff 80000 --logg 6.5 --loghe 2 --logc -4 --logn -4 --logo -4
|
||||
|
||||
# 低温富 He 边界(20000K, logHe=2)
|
||||
run_bg 20k_he2_cno-1 --teff 20000 --logg 5.0 --loghe 2 --logc -1 --logn -1 --logo -1
|
||||
run_bg 20k_he2_cno-4 --teff 20000 --logg 5.0 --loghe 2 --logc -4 --logn -4 --logo -4
|
||||
|
||||
# 中温丰度边界
|
||||
run_bg 40k_he0_cno-4 --teff 40000 --logg 5.5 --loghe 0 --logc -4 --logn -4 --logo -4
|
||||
run_bg 60k_he0_cno-1 --teff 60000 --logg 6.0 --loghe 0 --logc -1 --logn -1 --logo -1
|
||||
|
||||
wait
|
||||
echo "[$(date +%H:%M:%S)] ALL BOUNDARY TESTS COMPLETE"
|
||||
Executable
+46
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# 针对剩余冷启动失败边界点的种子步进验证测试。
|
||||
#
|
||||
# 策略:冷启动在低温、以及高温+富 He+低 CNO 的区域是可行的。用这些已
|
||||
# 收敛的大气作为种子,去热启动冷启动下会发散的几个点:
|
||||
#
|
||||
# S1 60000/6.0/0 /-1/-1/-1 以 40000/5.5/0/-4/-4/-4 为种子(Teff 不同)
|
||||
# S2 80000/6.5/-4/-1/-1/-1 以 80000/6.5/-4/-4/-4/-4 为种子(同 T、更低金属)
|
||||
# S3 80000/6.5/+2/-1/-1/-1 以 80000/6.5/+2/-4/-4/-4 为种子(同 T、更低金属)
|
||||
#
|
||||
# 注意:S1 把 Teff 从 40000 跨到 60000(原子相同)—— 比同 T、降金属的步进
|
||||
# 更苛刻,但仍值得一试。
|
||||
|
||||
set -u
|
||||
cd /home/dckj/program/tlusty/tl208-s54
|
||||
RESULTS=cno_grid/results/seed_step
|
||||
mkdir -p "$RESULTS"
|
||||
|
||||
# S2 首先需要一个已收敛的 80k_he-4_cno-4 大气 —— 上面的 seed_step/ 运行
|
||||
# 已经有了一个,直接拿它当种子。
|
||||
SEED_80K_HEPOOR_CNO4=cno_grid/results/seed_step/t80000_g6.5_he-4_c-4_n-4_o-4/t80000_g6.5_he-4_c-4_n-4_o-4.7
|
||||
SEED_80K_HERICH_CNO4=cno_grid/results/t80000_g6.5_he2_c-4_n-4_o-4/t80000_g6.5_he2_c-4_n-4_o-4.7
|
||||
SEED_40K_HEPOOR_CNO4=cno_grid/results/t40000_g5.5_he0_c-4_n-4_o-4/t40000_g5.5_he0_c-4_n-4_o-4.7
|
||||
|
||||
# 后台运行一个种子步进模型
|
||||
run_bg() {
|
||||
local tag="$1"; shift
|
||||
echo "[$(date +%H:%M:%S)] launching $tag"
|
||||
nohup python3 cno_grid/src/seed_step.py "$@" > "$RESULTS/${tag}.log" 2>&1 &
|
||||
echo " pid=$!"
|
||||
}
|
||||
|
||||
# S2:80K 贫 He 富金属,以 80K 贫 He 低金属为种子(刚验证过)
|
||||
run_bg s2_80k_he-4_cno-1 --teff 80000 --logg 6.5 --loghe -4 \
|
||||
--logc -1 --logn -1 --logo -1 --seed $SEED_80K_HEPOOR_CNO4
|
||||
|
||||
# S3:80K 富 He 富金属,以 80K 富 He 低金属为种子
|
||||
run_bg s3_80k_he2_cno-1 --teff 80000 --logg 6.5 --loghe 2 \
|
||||
--logc -1 --logn -1 --logo -1 --seed $SEED_80K_HERICH_CNO4
|
||||
|
||||
# S1:60K 贫 He 富金属,以 40K 贫 He 低金属为种子
|
||||
run_bg s1_60k_he0_cno-1 --teff 60000 --logg 6.0 --loghe 0 \
|
||||
--logc -1 --logn -1 --logo -1 --seed $SEED_40K_HEPOOR_CNO4
|
||||
|
||||
wait
|
||||
echo "[$(date +%H:%M:%S)] ALL SEED_STEP TESTS COMPLETE"
|
||||
@@ -0,0 +1,643 @@
|
||||
70 42
|
||||
2.976647D-07 4.055707D-07 5.544183D-07 7.599508D-07 1.056343D-06 1.465369D-06
|
||||
2.030084D-06 2.808100D-06 3.881278D-06 5.361527D-06 7.403420D-06 1.021994D-05
|
||||
1.410493D-05 1.946361D-05 2.685484D-05 3.704920D-05 5.110904D-05 7.049860D-05
|
||||
9.723527D-05 1.340970D-04 1.849059D-04 2.549140D-04 3.513244D-04 4.839875D-04
|
||||
6.663212D-04 9.165032D-04 1.258995D-03 1.726478D-03 2.362308D-03 3.223676D-03
|
||||
4.385680D-03 5.946604D-03 8.034713D-03 1.081701D-02 1.451035D-02 1.939542D-02
|
||||
2.583366D-02 3.428694D-02 4.534017D-02 5.972633D-02 7.835396D-02 1.023401D-01
|
||||
1.330546D-01 1.721840D-01 2.218250D-01 2.846049D-01 3.638195D-01 4.635693D-01
|
||||
5.888826D-01 7.460002D-01 9.437418D-01 1.197830D+00 1.539016D+00 2.019861D+00
|
||||
2.714951D+00 3.725205D+00 5.194089D+00 7.326155D+00 1.040888D+01 1.483495D+01
|
||||
2.112890D+01 2.997716D+01 4.226807D+01 5.914746D+01 8.213885D+01 1.133483D+02
|
||||
1.558501D+02 2.143008D+02 2.957952D+02 2.967420D+02
|
||||
3.281063D+04 3.104301D+08 6.144835D-16 3.394402D-03 5.458759D-05
|
||||
5.899031D-05 8.840768D-05 1.307195D-04 1.829752D-04 2.443311D-04
|
||||
3.151982D-04 8.919652D-01 2.578341D+08 5.031098D-06 1.872376D-08
|
||||
2.397186D-09 2.928996D-08 1.265290D-09 3.348707D-09 6.547889D-10
|
||||
1.035973D-08 8.536323D-09 9.222002D-10 7.947837D-10 2.326984D-09
|
||||
4.747972D-10 7.475982D-09 8.196314D+04 9.281716D-05 4.176669D-06
|
||||
4.861943D-06 7.286660D-06 1.077760D-05 1.520749D-05 2.052432D-05
|
||||
2.662734D-05 3.332097D-05 3.921151D-05 4.981679D-05 6.413026D-05
|
||||
8.244418D-05 2.569596D+07
|
||||
3.281580D+04 4.228803D+08 8.371604D-16 6.300940D-03 1.013303D-04
|
||||
1.095125D-04 1.641546D-04 2.427764D-04 3.399356D-04 4.541729D-04
|
||||
5.866407D-04 1.592077D+00 3.512681D+08 1.264418D-05 4.705600D-08
|
||||
6.024664D-09 7.360979D-08 3.179905D-09 8.415854D-09 1.645602D-09
|
||||
2.603486D-08 2.145293D-08 2.317617D-09 1.997427D-09 5.848051D-09
|
||||
1.193256D-09 1.878781D-08 1.512283D+05 2.003147D-04 8.198985D-06
|
||||
9.231082D-06 1.369438D-05 2.017599D-05 2.841458D-05 3.830821D-05
|
||||
4.967186D-05 6.214087D-05 7.310884D-05 9.287440D-05 1.197335D-04
|
||||
1.549600D-04 3.496752D+07
|
||||
3.282094D+04 5.779530D+08 1.144311D-15 1.177484D-02 1.893627D-04
|
||||
2.046776D-04 3.068799D-04 4.540045D-04 6.359685D-04 8.503114D-04
|
||||
1.100145D-03 2.818584D+00 4.801469D+08 3.198106D-05 1.190176D-07
|
||||
1.523834D-08 1.861776D-07 8.042908D-09 2.128594D-08 4.162173D-09
|
||||
6.584658D-08 5.425989D-08 5.861877D-09 5.052040D-09 1.479117D-08
|
||||
3.018096D-09 4.751792D-08 2.798982D+05 4.587635D-04 1.666751D-05
|
||||
1.789471D-05 2.612399D-05 3.824171D-05 5.368464D-05 7.224524D-05
|
||||
9.358319D-05 1.170120D-04 1.376184D-04 1.747823D-04 2.257526D-04
|
||||
2.942592D-04 4.772289D+07
|
||||
3.282526D+04 7.920328D+08 1.568467D-15 2.212833D-02 3.558747D-04
|
||||
3.847182D-04 5.770139D-04 8.540090D-04 1.196971D-03 1.601939D-03
|
||||
2.077098D-03 4.936032D+00 6.581206D+08 8.114492D-05 3.019772D-07
|
||||
3.866403D-08 4.723767D-07 2.040704D-08 5.400748D-08 1.056035D-08
|
||||
1.670612D-07 1.376713D-07 1.487332D-08 1.281828D-08 3.752842D-08
|
||||
7.657720D-09 1.205608D-07 5.182644D+05 1.105708D-03 3.521802D-05
|
||||
3.555553D-05 5.071544D-05 7.350801D-05 1.026673D-04 1.377545D-04
|
||||
1.781452D-04 2.225347D-04 2.616023D-04 3.320865D-04 4.299106D-04
|
||||
5.641435D-04 6.527618D+07
|
||||
3.282758D+04 1.100718D+09 2.180317D-15 4.278115D-02 6.880428D-04
|
||||
7.439758D-04 1.116356D-03 1.653225D-03 2.318937D-03 3.107570D-03
|
||||
4.040935D-03 8.721054D+00 9.148495D+08 2.130539D-04 7.928640D-07
|
||||
1.015157D-07 1.240268D-06 5.358085D-08 1.417997D-07 2.772623D-08
|
||||
4.386074D-07 3.614762D-07 3.905324D-08 3.365533D-08 9.853242D-08
|
||||
2.010604D-08 3.165327D-07 9.791845D+05 2.852556D-03 7.972880D-05
|
||||
7.457737D-05 1.030796D-04 1.472419D-04 2.040363D-04 2.724812D-04
|
||||
3.514197D-04 4.382875D-04 5.148995D-04 6.530702D-04 8.476440D-04
|
||||
1.118063D-03 9.047922D+07
|
||||
3.282649D+04 1.526727D+09 3.025169D-15 8.241938D-02 1.325604D-03
|
||||
1.433788D-03 2.152724D-03 3.190383D-03 4.479502D-03 6.012937D-03
|
||||
7.846841D-03 1.515161D+01 1.269345D+09 5.512873D-04 2.051574D-06
|
||||
2.626725D-07 3.209323D-06 1.386448D-07 3.669098D-07 7.173916D-08
|
||||
1.134847D-06 9.353927D-07 1.010633D-07 8.708448D-08 2.549539D-07
|
||||
5.202540D-08 8.190291D-07 1.826666D+06 7.335090D-03 1.847619D-04
|
||||
1.594145D-04 2.124157D-04 2.979234D-04 4.085220D-04 5.420062D-04
|
||||
6.963111D-04 8.664014D-04 1.017031D-03 1.288348D-03 1.676064D-03
|
||||
2.214653D-03 1.250679D+08
|
||||
3.282119D+04 2.114998D+09 4.192605D-15 1.584650D-01 2.548863D-03
|
||||
2.757916D-03 4.143924D-03 6.147173D-03 8.641730D-03 1.162405D-02
|
||||
1.523408D-02 2.601293D+01 1.759195D+09 1.407553D-03 5.238148D-06
|
||||
6.706381D-07 8.194500D-06 3.539981D-07 9.367925D-07 1.831512D-07
|
||||
2.897320D-06 2.388522D-06 2.580846D-07 2.223456D-07 6.509474D-07
|
||||
1.328325D-07 2.091163D-06 3.366322D+06 1.842285D-02 4.318438D-04
|
||||
3.460839D-04 4.436101D-04 6.095298D-04 8.253973D-04 1.086155D-03
|
||||
1.388321D-03 1.722038D-03 2.019589D-03 2.554289D-03 3.327080D-03
|
||||
4.383808D-03 1.724934D+08
|
||||
3.280848D+04 2.925956D+09 5.803282D-15 3.040220D-01 4.890528D-03
|
||||
5.294130D-03 7.962121D-03 1.182480D-02 1.664850D-02 2.244997D-02
|
||||
2.956590D-02 4.427395D+01 2.435027D+09 3.532480D-03 1.314632D-05
|
||||
1.682984D-06 2.056750D-05 8.884478D-07 2.351042D-06 4.595972D-07
|
||||
7.270888D-06 5.995551D-06 6.479068D-07 5.580177D-07 1.633676D-06
|
||||
3.333687D-07 5.248350D-06 6.105389D+06 4.549423D-02 1.008820D-03
|
||||
7.596337D-04 9.379146D-04 1.260978D-03 1.683967D-03 2.194947D-03
|
||||
2.788374D-03 3.445013D-03 4.036589D-03 5.094531D-03 6.628143D-03
|
||||
8.659936D-03 2.373078D+08
|
||||
3.278092D+04 4.046363D+09 8.030550D-15 5.832953D-01 9.383965D-03
|
||||
1.016435D-02 1.530392D-02 2.275986D-02 3.210203D-02 4.341527D-02
|
||||
5.748065D-02 7.503072D+01 3.369577D+09 8.657817D-03 3.222254D-05
|
||||
4.124458D-06 5.041921D-05 2.177627D-06 5.762377D-06 1.126255D-06
|
||||
1.782005D-05 1.469967D-05 1.588796D-06 1.367687D-06 4.004211D-06
|
||||
8.170802D-07 1.286506D-05 1.081507D+07 1.132257D-01 2.374369D-03
|
||||
1.690114D-03 2.014669D-03 2.649631D-03 3.485637D-03 4.494943D-03
|
||||
5.669469D-03 6.971392D-03 8.162382D-03 1.026890D-02 1.328865D-02
|
||||
1.710602D-02 3.260089D+08
|
||||
3.273366D+04 5.595786D+09 1.111331D-14 1.120053D+00 1.802159D-02
|
||||
1.953419D-02 2.945067D-02 4.386980D-02 6.200600D-02 8.413564D-02
|
||||
1.119975D-01 1.269166D+02 4.663088D+09 2.055456D-02 7.650798D-05
|
||||
9.790384D-06 1.197394D-04 5.170257D-06 1.368131D-05 2.673235D-06
|
||||
4.230797D-05 3.491751D-05 3.774995D-06 3.247141D-06 9.507401D-06
|
||||
1.939915D-06 3.055096D-05 1.855082D+07 2.821021D-01 5.621268D-03
|
||||
3.795659D-03 4.379573D-03 5.641365D-03 7.310752D-03 9.322256D-03
|
||||
1.166682D-02 1.426999D-02 1.670121D-02 2.091156D-02 2.677484D-02
|
||||
3.377525D-02 4.475582D+08
|
||||
3.267091D+04 7.739120D+09 1.538100D-14 2.152518D+00 3.463898D-02
|
||||
3.757720D-02 5.673845D-02 8.467239D-02 1.199561D-01 1.633526D-01
|
||||
2.185462D-01 2.144891D+02 6.453787D+09 4.717144D-02 1.756063D-04
|
||||
2.246363D-05 2.749139D-04 1.186627D-05 3.140019D-05 6.132971D-06
|
||||
9.709695D-05 8.019177D-05 8.672697D-06 7.452216D-06 2.182183D-05
|
||||
4.452223D-06 7.013650D-05 3.074762D+07 6.844392D-01 1.312854D-02
|
||||
8.477863D-03 9.512528D-03 1.203586D-02 1.539139D-02 1.942287D-02
|
||||
2.412442D-02 2.935061D-02 3.435337D-02 4.273772D-02 5.390410D-02
|
||||
6.648741D-02 6.143324D+08
|
||||
3.260499D+04 1.070141D+10 2.128363D-14 4.136312D+00 6.657338D-02
|
||||
7.228494D-02 1.093216D-01 1.634677D-01 2.321684D-01 3.173300D-01
|
||||
4.262962D-01 3.620367D+02 8.930499D+09 1.053239D-01 3.921494D-04
|
||||
5.014435D-05 6.141209D-04 2.649658D-05 7.011407D-05 1.368787D-05
|
||||
2.167791D-04 1.792018D-04 1.938904D-05 1.663927D-05 4.872901D-05
|
||||
9.941397D-06 1.566496D-04 4.958965D+07 1.581456D+00 2.959982D-02
|
||||
1.849821D-02 2.031810D-02 2.536030D-02 3.209753D-02 4.016764D-02
|
||||
4.957512D-02 6.003663D-02 7.030903D-02 8.680031D-02 1.076371D-01
|
||||
1.300113D-01 8.430136D+08
|
||||
3.255001D+04 1.478942D+10 2.943633D-14 7.938706D+00 1.277943D-01
|
||||
1.388851D-01 2.103992D-01 3.152633D-01 4.489299D-01 6.158089D-01
|
||||
8.294564D-01 6.098430D+02 1.235133D+10 2.319787D-01 8.638154D-04
|
||||
1.104158D-04 1.353238D-03 5.836209D-05 1.544274D-04 3.013126D-05
|
||||
4.773057D-04 3.950435D-04 4.276501D-05 3.664640D-05 1.073298D-04
|
||||
2.189699D-05 3.450826D-04 7.895276D+07 3.451482D+00 6.369696D-02
|
||||
3.896667D-02 4.218836D-02 5.218423D-02 6.559602D-02 8.162040D-02
|
||||
1.002812D-01 1.210312D-01 1.418880D-01 1.737709D-01 2.120335D-01
|
||||
2.518051D-01 1.155513D+09
|
||||
3.251587D+04 2.042188D+10 4.068250D-14 1.520555D+01 2.448203D-01
|
||||
2.663050D-01 4.041144D-01 6.068218D-01 8.663891D-01 1.192331D+00
|
||||
1.607313D+00 1.024570D+03 1.707016D+10 5.115764D-01 1.905039D-03
|
||||
2.434331D-04 2.985433D-03 1.287061D-04 3.405195D-04 6.639941D-05
|
||||
1.051859D-03 8.719490D-04 9.445258D-05 8.080384D-05 2.366651D-04
|
||||
4.828934D-05 7.609387D-04 1.260122D+08 7.135358D+00 1.307373D-01
|
||||
7.900059D-02 8.479597D-02 1.043419D-01 1.306658D-01 1.620795D-01
|
||||
1.986201D-01 2.392507D-01 2.809034D-01 3.415009D-01 4.111454D-01
|
||||
4.823651D-01 1.580011D+09
|
||||
3.250725D+04 2.817136D+10 5.618085D-14 2.905395D+01 4.679035D-01
|
||||
5.093874D-01 7.743042D-01 1.165234D+00 1.668016D+00 2.301755D+00
|
||||
3.099418D+00 1.716415D+03 2.357319D+10 1.138915D+00 4.241029D-03
|
||||
5.418021D-04 6.648552D-03 2.865276D-04 7.579185D-04 1.476812D-04
|
||||
2.338982D-03 1.942977D-03 2.106389D-04 1.798457D-04 5.267319D-04
|
||||
1.075033D-04 1.693386D-03 2.033332D+08 1.408824D+01 2.573604D-01
|
||||
1.546045D-01 1.652271D-01 2.028090D-01 2.535883D-01 3.142232D-01
|
||||
3.847189D-01 4.631667D-01 5.448861D-01 6.584876D-01 7.849659D-01
|
||||
9.137944D-01 2.152511D+09
|
||||
3.252407D+04 3.882301D+10 7.752405D-14 5.538149D+01 8.922289D-01
|
||||
9.720267D-01 1.480090D+00 2.232311D+00 3.203637D+00 4.429314D+00
|
||||
5.947071D+00 2.867534D+03 3.252868D+10 2.546517D+00 9.481473D-03
|
||||
1.211041D-03 1.486963D-02 6.406018D-04 1.693989D-03 3.297725D-04
|
||||
5.220465D-03 4.348758D-03 4.719382D-04 4.019577D-04 1.177140D-03
|
||||
2.403532D-04 3.783351D-03 3.299948D+08 2.689686D+01 4.910924D-01
|
||||
2.943839D-01 3.141553D-01 3.853159D-01 4.816802D-01 5.969627D-01
|
||||
7.310620D-01 8.806039D-01 1.038485D+00 1.249374D+00 1.479331D+00
|
||||
1.714303D+00 2.920693D+09
|
||||
3.256151D+04 5.345952D+10 1.069034D-13 1.053557D+02 1.698453D+00
|
||||
1.851306D+00 2.823954D+00 4.268919D+00 6.141101D+00 8.498464D+00
|
||||
1.136160D+01 4.779780D+03 4.485610D+10 5.626381D+00 2.094463D-02
|
||||
2.674653D-03 3.286295D-02 1.415227D-03 3.740670D-03 7.273242D-04
|
||||
1.150539D-02 9.620572D-03 1.045486D-03 8.876047D-04 2.598917D-03
|
||||
5.309947D-04 8.349357D-03 5.298321D+08 5.044551D+01 9.219464D-01
|
||||
5.520994D-01 5.891446D-01 7.226723D-01 9.037054D-01 1.120709D+00
|
||||
1.373428D+00 1.656041D+00 1.957907D+00 2.346732D+00 2.765430D+00
|
||||
3.195894D+00 3.952561D+09
|
||||
3.261319D+04 7.357480D+10 1.473318D-13 2.001304D+02 3.230311D+00
|
||||
3.521550D+00 5.381653D+00 8.154647D+00 1.175616D+01 1.626479D+01
|
||||
2.163106D+01 7.953713D+03 6.181963D+10 1.212227D+01 4.511371D-02
|
||||
5.759506D-03 7.083137D-02 3.048874D-03 8.053237D-03 1.563268D-03
|
||||
2.470436D-02 2.076364D-02 2.260624D-03 1.910977D-03 5.593874D-03
|
||||
1.143901D-03 1.796026D-02 8.301972D+08 9.408322D+01 1.723504D+00
|
||||
1.030559D+00 1.099918D+00 1.349797D+00 1.688877D+00 2.096025D+00
|
||||
2.570743D+00 3.102838D+00 3.676535D+00 4.390385D+00 5.153725D+00
|
||||
5.943989D+00 5.347023D+09
|
||||
3.267528D+04 1.012210D+11 2.029365D-13 3.796957D+02 6.143174D+00
|
||||
6.693389D+00 1.024844D+01 1.556686D+01 2.248066D+01 3.105407D+01
|
||||
4.106713D+01 1.321677D+04 8.515108D+10 2.534371D+01 9.428449D-02
|
||||
1.203208D-02 1.481667D-01 6.373952D-03 1.681939D-02 3.257531D-03
|
||||
5.141338D-02 4.351370D-02 4.749430D-03 3.991501D-03 1.167946D-02
|
||||
2.391137D-03 3.746936D-02 1.262975D+09 1.754346D+02 3.228356D+00
|
||||
1.924778D+00 2.054287D+00 2.522189D+00 3.157935D+00 3.922542D+00
|
||||
4.814691D+00 5.815748D+00 6.901966D+00 8.210785D+00 9.605771D+00
|
||||
1.105990D+01 7.245137D+09
|
||||
3.274738D+04 1.392042D+11 2.793528D-13 7.193802D+02 1.169148D+01
|
||||
1.271470D+01 1.950467D+01 2.969763D+01 4.293219D+01 5.913674D+01
|
||||
7.776571D+01 2.193070D+04 1.172149D+11 5.146462D+01 1.913724D-01
|
||||
2.440721D-02 3.011154D-01 1.294464D-02 3.410788D-02 6.585420D-03
|
||||
1.037722D-01 8.865257D-02 9.708837D-03 8.096018D-03 2.367576D-02
|
||||
4.854652D-03 7.587492D-02 1.867204D+09 3.276068D+02 6.079931D+00
|
||||
3.605099D+00 3.845973D+00 4.723777D+00 5.918646D+00 7.358005D+00
|
||||
9.037283D+00 1.092055D+01 1.297075D+01 1.537261D+01 1.793075D+01
|
||||
2.061437D+01 9.843959D+09
|
||||
3.282888D+04 1.913611D+11 3.842891D-13 1.360674D+03 2.230165D+01
|
||||
2.414722D+01 3.710489D+01 5.661929D+01 8.185657D+01 1.123048D+02
|
||||
1.469057D+02 3.633545D+04 1.612456D+11 1.020955D+02 3.794192D-01
|
||||
4.834792D-02 5.980192D-01 2.568931D-02 6.754053D-02 1.298543D-02
|
||||
2.042263D-01 1.766564D-01 1.943281D-02 1.603841D-02 4.686117D-02
|
||||
9.628443D-03 1.499679D-01 2.698318D+09 6.124715D+02 1.154412D+01
|
||||
6.776991D+00 7.221109D+00 8.870721D+00 1.112163D+01 1.383680D+01
|
||||
1.700031D+01 2.054006D+01 2.439677D+01 2.881264D+01 3.352058D+01
|
||||
3.848755D+01 1.341098D+10
|
||||
3.291582D+04 2.629504D+11 5.283266D-13 2.568685D+03 4.276088D+01
|
||||
4.588894D+01 7.059392D+01 1.079036D+02 1.558111D+02 2.127388D+02
|
||||
2.769762D+02 6.012549D+04 2.216830D+11 1.993407D+02 7.402503D-01
|
||||
9.420835D-02 1.169439D+00 5.020430D-02 1.315580D-01 2.514938D-02
|
||||
3.946348D-01 3.469967D-01 3.839225D-02 3.126423D-02 9.122841D-02
|
||||
1.879471D-02 2.914133D-01 3.839717D+09 1.144776D+03 2.217650D+01
|
||||
1.279371D+01 1.359724D+01 1.669926D+01 2.094588D+01 2.607243D+01
|
||||
3.202816D+01 3.866737D+01 4.589719D+01 5.403244D+01 6.272382D+01
|
||||
7.193881D+01 1.830599D+10
|
||||
3.300067D+04 3.611916D+11 7.260143D-13 4.838095D+03 8.279496D+01
|
||||
8.739663D+01 1.344480D+02 2.056610D+02 2.961618D+02 4.022298D+02
|
||||
5.215672D+02 9.941500D+04 3.046317D+11 3.857429D+02 1.431068D+00
|
||||
1.818001D-01 2.267755D+00 9.733689D-02 2.537856D-01 4.814601D-02
|
||||
7.535902D-01 6.768205D-01 7.543989D-02 6.039377D-02 1.758817D-01
|
||||
3.636042D-02 5.604527D-01 5.416839D+09 2.135212D+03 4.330639D+01
|
||||
2.428386D+01 2.568340D+01 3.151114D+01 3.952628D+01 4.920129D+01
|
||||
6.039003D+01 7.280686D+01 8.631793D+01 1.013353D+02 1.174217D+02
|
||||
1.345493D+02 2.501289D+10
|
||||
3.307218D+04 4.960098D+11 9.974040D-13 9.086113D+03 1.628812D+02
|
||||
1.672010D+02 2.566736D+02 3.923066D+02 5.624791D+02 7.598036D+02
|
||||
9.818829D+02 1.643745D+05 4.185053D+11 7.450230D+02 2.760572D+00
|
||||
3.498294D-01 4.392216D+00 1.887062D-01 4.881971D-01 9.169005D-02
|
||||
1.431489D+00 1.320726D+00 1.485797D-01 1.164536D-01 3.381370D-01
|
||||
7.021343D-02 1.074047D+00 7.627084D+09 3.964831D+03 8.635412D+01
|
||||
4.643633D+01 4.869379D+01 5.960765D+01 7.472013D+01 9.294071D+01
|
||||
1.138892D+02 1.370386D+02 1.622250D+02 1.899944D+02 2.198258D+02
|
||||
2.517002D+02 3.417395D+10
|
||||
3.311390D+04 6.810931D+11 1.370278D-12 1.700078D+04 3.275395D+02
|
||||
3.223894D+02 4.921090D+02 7.497545D+02 1.068606D+03 1.435962D+03
|
||||
1.850436D+03 2.720774D+05 5.749613D+11 1.448566D+03 5.359126D+00
|
||||
6.768692D-01 8.570729D+00 3.695493D-01 9.443856D-01 1.750852D-01
|
||||
2.727398D+00 2.601647D+00 2.960340D-01 2.261901D-01 6.537998D-01
|
||||
1.365191D-01 2.068150D+00 1.080602D+10 7.307863D+03 1.761421D+02
|
||||
8.969515D+01 9.274812D+01 1.130541D+02 1.414604D+02 1.756348D+02
|
||||
2.146828D+02 2.577059D+02 3.045604D+02 3.559709D+02 4.113555D+02
|
||||
4.707064D+02 4.661687D+10
|
||||
3.310103D+04 9.354544D+11 1.883536D-12 3.166843D+04 6.755966D+02
|
||||
6.293418D+02 9.500403D+02 1.438126D+03 2.034855D+03 2.721081D+03
|
||||
3.498219D+03 4.516485D+05 7.903214D+11 2.868380D+03 1.059119D+01
|
||||
1.331977D+00 1.704798D+01 7.417232D-01 1.858221D+00 3.389686D-01
|
||||
5.273092D+00 5.235903D+00 6.041269D-01 4.481440D-01 1.286262D+00
|
||||
2.704591D-01 4.047618D+00 1.557339D+10 1.331515D+04 3.671025D+02
|
||||
1.755905D+02 1.777045D+02 2.150383D+02 2.681032D+02 3.317935D+02
|
||||
4.041949D+02 4.838949D+02 5.708775D+02 6.660837D+02 7.689236D+02
|
||||
8.793938D+02 6.335044D+10
|
||||
3.299527D+04 1.285866D+12 2.592765D-12 5.869448D+04 1.431566D+03
|
||||
1.251514D+03 1.854221D+03 2.777522D+03 3.897455D+03 5.188276D+03
|
||||
6.656565D+03 7.541548D+05 1.087910D+12 5.887253D+03 2.168540D+01
|
||||
2.713319D+00 3.518358D+01 1.561571D+00 3.785121D+00 6.772092D-01
|
||||
1.053577D+01 1.096287D+01 1.286930D+00 9.236065D-01 2.621298D+00
|
||||
5.559674D-01 8.196432D+00 2.320755D+10 2.383520D+04 7.767523D+02
|
||||
3.491400D+02 3.427537D+02 4.099947D+02 5.080443D+02 6.256342D+02
|
||||
7.589790D+02 9.059871D+02 1.066933D+03 1.242976D+03 1.433594D+03
|
||||
1.638760D+03 8.542351D+10
|
||||
3.274436D+04 1.770533D+12 3.579591D-12 1.081779D+05 3.116423D+03
|
||||
2.551881D+03 3.677937D+03 5.428020D+03 7.547254D+03 1.000452D+04
|
||||
1.281288D+04 1.272362D+06 1.501976D+12 1.287007D+04 4.726494D+01
|
||||
5.883647D+00 7.742616D+01 3.581270D+00 8.204396D+00 1.436693D+00
|
||||
2.239020D+01 2.456391D+01 2.949278D+00 2.042863D+00 5.690277D+00
|
||||
1.220140D+00 1.766233D+01 3.668477D+10 4.152973D+04 1.636417D+03
|
||||
7.007768D+02 6.626540D+02 7.797096D+02 9.573707D+02 1.171093D+03
|
||||
1.413794D+03 1.682425D+03 1.977696D+03 2.300851D+03 2.651500D+03
|
||||
3.029517D+03 1.132779D+11
|
||||
3.230858D+04 2.442934D+12 4.964162D-12 1.982829D+05 6.900565D+03
|
||||
5.339397D+03 7.434516D+03 1.076976D+04 1.483527D+04 1.958998D+04
|
||||
2.504865D+04 2.177078D+06 2.082934D+12 3.078489D+04 1.126278D+02
|
||||
1.398770D+01 1.866509D+02 9.364621D+00 1.946027D+01 3.340024D+00
|
||||
5.215109D+01 6.063963D+01 7.519584D+00 5.024315D+00 1.353596D+01
|
||||
2.944912D+00 4.167732D+01 6.313778D+10 6.919647D+04 3.309937D+03
|
||||
1.384500D+03 1.259629D+03 1.452330D+03 1.762058D+03 2.137972D+03
|
||||
2.567446D+03 3.045724D+03 3.573729D+03 4.152361D+03 4.781324D+03
|
||||
5.460242D+03 1.448149D+11
|
||||
3.168512D+04 3.375754D+12 6.919367D-12 3.618633D+05 1.521919D+04
|
||||
1.137513D+04 1.526933D+04 2.168216D+04 2.961498D+04 3.897563D+04
|
||||
4.976408D+04 3.780657D+06 2.903326D+12 7.964731D+04 2.898113D+02
|
||||
3.626817D+01 4.871537D+02 2.829885D+01 5.006625D+01 8.500703D+00
|
||||
1.323383D+02 1.638573D+02 2.136988D+01 1.381355D+01 3.496731D+01
|
||||
7.768911D+00 1.067500D+02 1.170872D+11 1.072839D+05 6.115128D+03
|
||||
2.576550D+03 2.266317D+03 2.557310D+03 3.061114D+03 3.682327D+03
|
||||
4.399107D+03 5.202978D+03 6.094089D+03 7.072250D+03 8.136964D+03
|
||||
9.287327D+03 1.727647D+11
|
||||
3.091855D+04 4.666445D+12 9.677909D-12 6.586404D+05 3.275073D+04
|
||||
2.436116D+04 3.159584D+04 4.406513D+04 5.976835D+04 7.844107D+04
|
||||
1.000239D+05 6.636619D+06 4.060792D+12 2.073736D+05 7.479289D+02
|
||||
9.661313D+01 1.280032D+03 9.417158D+01 1.307511D+02 2.246950D+01
|
||||
3.435895D+02 4.548215D+02 6.426063D+01 4.040812D+01 9.164533D+01
|
||||
2.102784D+01 2.772632D+02 2.183898D+11 1.515084D+05 9.932193D+03
|
||||
4.326052D+03 3.715047D+03 4.111575D+03 4.858392D+03 5.798111D+03
|
||||
6.894395D+03 8.132111D+03 9.508970D+03 1.102273D+04 1.267208D+04
|
||||
1.445527D+04 1.870341D+11
|
||||
3.008236D+04 6.444003D+12 1.353427D-11 1.197230D+06 6.804052D+04
|
||||
5.160528D+04 6.513724D+04 8.962692D+04 1.209468D+05 1.583814D+05
|
||||
2.017340D+05 1.168676D+07 5.678896D+12 5.098092D+05 1.813728D+03
|
||||
2.524759D+02 3.175575D+03 3.234881D+02 3.281813D+02 5.925368D+01
|
||||
8.655530D+02 1.224038D+03 1.944759D+02 1.195566D+02 2.298579D+02
|
||||
5.534577D+01 6.886487D+02 3.863375D+11 1.925251D+05 1.397745D+04
|
||||
6.368852D+03 5.399960D+03 5.890398D+03 6.886610D+03 8.165058D+03
|
||||
9.671099D+03 1.138075D+04 1.328761D+04 1.538670D+04 1.767521D+04
|
||||
2.015032D+04 1.806808D+11
|
||||
2.924164D+04 8.878975D+12 1.885305D-11 2.172867D+06 1.362575D+05
|
||||
1.063619D+05 1.326448D+05 1.810496D+05 2.434580D+05 3.182525D+05
|
||||
4.049685D+05 2.048785D+07 7.910617D+12 1.152039D+06 4.030731D+03
|
||||
6.355322D+02 7.241339D+03 1.049629D+03 7.763350D+02 1.536326D+02
|
||||
2.067207D+03 3.091540D+03 5.736464D+02 3.474368D+02 5.391620D+02
|
||||
1.385213D+02 1.598577D+03 6.340253D+11 2.205826D+05 1.722050D+04
|
||||
8.205230D+03 6.930606D+03 7.488344D+03 8.686009D+03 1.024723D+04
|
||||
1.209956D+04 1.421050D+04 1.656920D+04 1.916775D+04 2.200201D+04
|
||||
2.506783D+04 1.558802D+11
|
||||
2.848425D+04 1.217365D+13 2.604476D-11 3.919774D+06 2.632612D+05
|
||||
2.113172D+05 2.641077D+05 3.590672D+05 4.817138D+05 6.288838D+05
|
||||
7.995808D+05 3.537488D+07 1.092820D+13 2.382676D+06 8.206952D+03
|
||||
1.510028D+03 1.509778D+04 2.985711D+03 1.722220D+03 3.841817D+02
|
||||
4.630114D+03 7.207544D+03 1.589010D+03 9.544234D+02 1.176660D+03
|
||||
3.253945D+02 3.451116D+03 9.663211D+11 2.354039D+05 1.938358D+04
|
||||
9.590348D+03 8.121559D+03 8.725499D+03 1.006586D+04 1.183153D+04
|
||||
1.393624D+04 1.634106D+04 1.903090D+04 2.199618D+04 2.523111D+04
|
||||
2.873016D+04 1.249311D+11
|
||||
2.788789D+04 1.654916D+13 3.555989D-11 6.975547D+06 4.899000D+05
|
||||
4.031963D+05 5.088650D+05 6.911456D+05 9.259824D+05 1.207784D+06
|
||||
1.534615D+06 5.954659D+07 1.492067D+13 4.565662D+06 1.553151D+04
|
||||
3.303452D+03 2.914106D+04 7.227433D+03 3.582792D+03 8.992387D+02
|
||||
9.677894D+03 1.542580D+04 3.975725D+03 2.377756D+03 2.399694D+03
|
||||
7.105228D+02 6.965249D+03 1.389447D+12 2.500204D+05 2.147159D+04
|
||||
1.094737D+04 9.326873D+03 9.988077D+03 1.147859D+04 1.345592D+04
|
||||
1.582014D+04 1.852585D+04 2.155493D+04 2.489552D+04 2.854000D+04
|
||||
3.248105D+04 1.004362D+11
|
||||
2.749144D+04 2.224275D+13 4.790222D-11 1.216252D+07 8.769027D+05
|
||||
7.396367D+05 9.433101D+05 1.281961D+06 1.716565D+06 2.237742D+06
|
||||
2.841994D+06 9.711734D+07 2.009940D+13 8.255533D+06 2.785751D+04
|
||||
6.534982D+03 5.305724D+04 1.491144D+04 6.994502D+03 1.922876D+03
|
||||
1.886995D+04 3.040847D+04 8.819144D+03 5.264734D+03 4.604858D+03
|
||||
1.435339D+03 1.325114D+04 1.920142D+12 2.799769D+05 2.494597D+04
|
||||
1.303528D+04 1.119036D+04 1.196257D+04 1.371197D+04 1.604401D+04
|
||||
1.883815D+04 2.204012D+04 2.562675D+04 2.958286D+04 3.389821D+04
|
||||
3.856254D+04 8.671964D+10
|
||||
2.727565D+04 2.953732D+13 6.368690D-11 2.065775D+07 1.514008D+06
|
||||
1.308342D+06 1.684980D+06 2.292852D+06 3.069959D+06 4.001029D+06
|
||||
5.079929D+06 1.535417D+08 2.672250D+13 1.427887D+07 4.812966D+04
|
||||
1.180212D+04 9.248633D+04 2.725379D+04 1.288467D+04 3.743414D+03
|
||||
3.459404D+04 5.596262D+04 1.745507D+04 1.041342D+04 8.392734D+03
|
||||
2.696963D+03 2.400260D+04 2.585649D+12 3.360328D+05 3.103727D+04
|
||||
1.656300D+04 1.435080D+04 1.533632D+04 1.755510D+04 2.051926D+04
|
||||
2.407335D+04 2.814990D+04 3.271720D+04 3.775499D+04 4.324838D+04
|
||||
4.918179D+04 8.226939D+10
|
||||
2.720323D+04 3.877051D+13 8.364829D-11 3.399005D+07 2.540831D+06
|
||||
2.241955D+06 2.912018D+06 3.968570D+06 5.314907D+06 6.926534D+06
|
||||
8.792753D+06 2.360197D+08 3.509808D+13 2.368820D+07 8.073882D+04
|
||||
2.006456D+04 1.557853D+05 4.655652D+04 2.257270D+04 6.754286D+03
|
||||
6.028697D+04 9.760623D+04 3.167230D+04 1.889060D+04 1.465325D+04
|
||||
4.782474D+03 4.174905D+04 3.418630D+12 4.286173D+05 4.114203D+04
|
||||
2.238911D+04 1.959686D+04 2.096099D+04 2.398242D+04 2.801881D+04
|
||||
3.286065D+04 3.841602D+04 4.464014D+04 5.150391D+04 5.898429D+04
|
||||
6.705582D+04 8.513907D+10
|
||||
2.724132D+04 5.033581D+13 1.086383D-10 5.394024D+07 4.147474D+06
|
||||
3.734314D+06 4.887583D+06 6.671880D+06 8.939293D+06 1.165105D+07
|
||||
1.478861D+07 3.538324D+08 4.558360D+13 3.764522D+07 1.319027D+05
|
||||
3.282233D+04 2.549089D+05 7.650634D+04 3.789158D+04 1.152773D+04
|
||||
1.008432D+05 1.632515D+05 5.411342D+04 3.227545D+04 2.467308D+04
|
||||
8.114578D+03 7.017297D+04 4.455139D+12 5.732747D+05 5.748910D+04
|
||||
3.188264D+04 2.822032D+04 3.024721D+04 3.461751D+04 4.044720D+04
|
||||
4.743773D+04 5.545779D+04 6.444100D+04 7.434323D+04 8.512654D+04
|
||||
9.674675D+04 9.489918D+10
|
||||
2.738251D+04 6.464849D+13 1.395497D-10 8.224343D+07 6.577210D+06
|
||||
6.048972D+06 7.973804D+06 1.090440D+07 1.461932D+07 1.905823D+07
|
||||
2.418923D+07 5.177081D+08 5.855362D+13 5.720660D+07 2.096695D+05
|
||||
5.197520D+04 4.051239D+05 1.216320D+05 6.123009D+04 1.881357D+04
|
||||
1.627340D+05 2.634257D+05 8.828708D+04 5.266620D+04 4.018538D+04
|
||||
1.325683D+04 1.142514D+05 5.730148D+12 8.018974D+05 8.457998D+04
|
||||
4.783516D+04 4.286831D+04 4.609845D+04 5.282234D+04 6.175462D+04
|
||||
7.245154D+04 8.471912D+04 9.845346D+04 1.135834D+05 1.300426D+05
|
||||
1.477490D+05 1.138961D+11
|
||||
2.763689D+04 8.212872D+13 1.772774D-10 1.202534D+08 1.011473D+07
|
||||
9.517197D+06 1.263391D+07 1.731292D+07 2.323042D+07 3.029440D+07
|
||||
3.845049D+07 7.387870D+08 7.438366D+13 8.302845D+07 3.231884D+05
|
||||
7.968378D+04 6.238054D+05 1.870406D+05 9.548986D+04 2.950478D+04
|
||||
2.538369D+05 4.109909D+05 1.384174D+05 8.258601D+04 6.334694D+04
|
||||
2.089906D+04 1.801993D+05 7.274958D+12 1.179362D+06 1.318733D+05
|
||||
7.610356D+04 6.915067D+04 7.470414D+04 8.575390D+04 1.003595D+05
|
||||
1.178205D+05 1.378302D+05 1.602169D+05 1.848579D+05 2.116284D+05
|
||||
2.403654D+05 1.482231D+11
|
||||
2.801839D+04 1.032172D+14 2.227461D-10 1.687226D+08 1.507719D+07
|
||||
1.453287D+07 1.943151D+07 2.669234D+07 3.585412D+07 4.677960D+07
|
||||
5.937715D+07 1.027830D+09 9.346166D+13 1.150467D+08 4.813327D+05
|
||||
1.181863D+05 9.287618D+05 2.781187D+05 1.439338D+05 4.459407D+04
|
||||
3.830723D+05 6.205355D+05 2.092544D+05 1.248703D+05 9.665477D+04
|
||||
3.183817D+04 2.752566D+05 9.115507D+12 1.834834D+06 2.189841D+05
|
||||
1.292294D+05 1.191875D+05 1.294968D+05 1.490298D+05 1.746742D+05
|
||||
2.052663D+05 2.402855D+05 2.794303D+05 3.224704D+05 3.691536D+05
|
||||
4.191313D+05 2.105574D+11
|
||||
2.853644D+04 1.284214D+14 2.769971D-10 2.276972D+08 2.179839D+07
|
||||
2.155633D+07 2.904277D+07 4.000687D+07 5.380971D+07 7.025076D+07
|
||||
8.917777D+07 1.395172D+09 1.162246D+14 1.522160D+08 6.913818D+05
|
||||
1.694772D+05 1.336221D+06 3.999233D+05 2.100005D+05 6.513544D+04
|
||||
5.599869D+05 9.077084D+05 3.058887D+05 1.825600D+05 1.428517D+05
|
||||
4.695617D+04 4.074303D+05 1.127013D+13 3.025456D+06 3.874776D+05
|
||||
2.343462D+05 2.193531D+05 2.398749D+05 2.769746D+05 3.252853D+05
|
||||
3.827549D+05 4.484502D+05 5.218034D+05 6.023491D+05 6.895376D+05
|
||||
7.825690D+05 3.260184D+11
|
||||
2.919852D+04 1.583606D+14 3.412539D-10 2.966286D+08 3.062542D+07
|
||||
3.112178D+07 4.227364D+07 5.841901D+07 7.869692D+07 1.028199D+08
|
||||
1.305381D+08 1.850651D+09 1.431857D+14 1.923866D+08 9.571599D+05
|
||||
2.348176D+05 1.857394D+06 5.561129D+05 2.968466D+05 9.212094D+04
|
||||
7.935686D+05 1.287322D+06 4.331656D+05 2.585541D+05 2.046459D+05
|
||||
6.713017D+04 5.846877D+05 1.373740D+13 5.275135D+06 7.247973D+05
|
||||
4.511710D+05 4.290284D+05 4.727013D+05 5.479895D+05 6.451355D+05
|
||||
7.603355D+05 8.918085D+05 1.038413D+06 1.199135D+06 1.372690D+06
|
||||
1.557118D+06 5.469924D+11
|
||||
3.000985D+04 1.938241D+14 4.169847D-10 3.748909D+08 4.194723D+07
|
||||
4.386244D+07 6.009998D+07 8.334998D+07 1.124812D+08 1.470873D+08
|
||||
1.867627D+08 2.403976D+09 1.749611D+14 2.324121D+08 1.276256D+06
|
||||
3.140630D+05 2.492961D+06 7.472889D+05 4.063899D+05 1.261865D+05
|
||||
1.089690D+06 1.769204D+06 5.943000D+05 3.547826D+05 2.840553D+05
|
||||
9.301473D+04 8.130773D+05 1.646966D+13 9.650090D+06 1.422110D+06
|
||||
9.132759D+05 8.827152D+05 9.805391D+05 1.141901D+06 1.348135D+06
|
||||
1.591858D+06 1.869486D+06 2.178590D+06 2.516822D+06 2.880993D+06
|
||||
3.266025D+06 9.820880D+11
|
||||
3.097406D+04 2.358179D+14 5.058744D-10 4.621948D+08 5.620180D+07
|
||||
6.053663D+07 8.371203D+07 1.165474D+08 1.575890D+08 2.062679D+08
|
||||
2.619313D+08 3.064613D+09 2.122578D+14 2.679152D+08 1.633890D+06
|
||||
4.041158D+05 3.220271D+06 9.671374D+05 5.369632D+05 1.668734D+05
|
||||
1.444745D+06 2.347827D+06 7.873807D+05 4.701178D+05 3.806872D+05
|
||||
1.244802D+05 1.091781D+06 1.931229D+13 1.825995D+07 2.886678D+06
|
||||
1.915642D+06 1.883152D+06 2.110039D+06 2.469696D+06 2.924945D+06
|
||||
3.461002D+06 4.070376D+06 4.747659D+06 5.487125D+06 6.280495D+06
|
||||
7.114069D+06 1.855418D+12
|
||||
3.208965D+04 2.856347D+14 6.097798D-10 5.586009D+08 7.392481D+07
|
||||
8.208742D+07 1.146026D+08 1.602125D+08 2.170829D+08 2.844199D+08
|
||||
3.611786D+08 3.842349D+09 2.558547D+14 2.928056D+08 1.993105D+06
|
||||
4.963274D+05 3.971720D+06 1.195837D+06 6.790958D+05 2.112972D+05
|
||||
1.834026D+06 2.983322D+06 9.990138D+05 5.965745D+05 4.884909D+05
|
||||
1.595540D+05 1.403710D+06 2.191108D+13 3.491791D+07 5.932811D+06
|
||||
4.072219D+06 4.073322D+06 4.605867D+06 5.419918D+06 6.440852D+06
|
||||
7.638554D+06 8.997109D+06 1.050413D+07 1.214526D+07 1.389850D+07
|
||||
1.572620D+07 3.596871D+12
|
||||
3.334708D+04 3.449019D+14 7.307074D-10 6.641948D+08 9.582497D+07
|
||||
1.097371D+08 1.547039D+08 2.171952D+08 2.949274D+08 3.867898D+08
|
||||
4.911159D+08 4.748342D+09 3.065938D+14 2.996859D+08 2.286502D+06
|
||||
5.741179D+05 4.614230D+06 1.393627D+06 8.106830D+05 2.526106D+05
|
||||
2.198114D+06 3.579098D+06 1.196891D+06 7.148646D+05 5.917511D+05
|
||||
1.931149D+05 1.703783D+06 2.365339D+13 6.532157D+07 1.195989D+07
|
||||
8.490405D+06 8.642020D+06 9.863656D+06 1.167167D+07 1.391952D+07
|
||||
1.654691D+07 1.952044D+07 2.281180D+07 2.638516D+07 3.018271D+07
|
||||
3.410251D+07 6.899742D+12
|
||||
3.470765D+04 4.157712D+14 8.716745D-10 7.801557D+08 1.232233D+08
|
||||
1.454820D+08 2.070733D+08 2.919476D+08 3.972750D+08 5.214836D+08
|
||||
6.619116D+08 5.808421D+09 3.657411D+14 2.841057D+08 2.441706D+06
|
||||
6.188846D+05 4.995039D+06 1.514193D+06 9.030901D+05 2.818402D+05
|
||||
2.458555D+06 4.007043D+06 1.338242D+06 7.994316D+05 6.688067D+05
|
||||
2.180920D+05 1.929359D+06 2.391230D+13 1.147310D+08 2.269870D+07
|
||||
1.667330D+07 1.726629D+07 1.989127D+07 2.366819D+07 2.832640D+07
|
||||
3.375218D+07 3.987864D+07 4.664372D+07 5.396198D+07 6.168925D+07
|
||||
6.956432D+07 1.251333D+13
|
||||
3.621335D+04 4.998420D+14 1.034572D-09 9.026371D+08 1.566805D+08
|
||||
1.906269D+08 2.739473D+08 3.878807D+08 5.289416D+08 6.948906D+08
|
||||
8.814924D+08 7.013899D+09 4.340900D+14 2.430346D+08 2.359724D+06
|
||||
6.043784D+05 4.898675D+06 1.491032D+06 9.120080D+05 2.851402D+05
|
||||
2.493074D+06 4.067232D+06 1.356858D+06 8.107008D+05 6.850806D+05
|
||||
2.233028D+05 1.980023D+06 2.204732D+13 1.859985D+08 3.985020D+07
|
||||
3.030879D+07 3.193522D+07 3.713749D+07 4.443783D+07 5.337478D+07
|
||||
6.374910D+07 7.543533D+07 8.830499D+07 1.021674D+08 1.166876D+08
|
||||
1.312444D+08 2.115367D+13
|
||||
3.782588D+04 6.004738D+14 1.227135D-09 1.035782D+09 1.989396D+08
|
||||
2.491544D+08 3.614105D+08 5.138507D+08 7.021554D+08 9.230776D+08
|
||||
1.169842D+09 8.421727D+09 5.148856D+14 1.885361D+08 2.083098D+06
|
||||
5.394732D+05 4.390454D+06 1.342160D+06 8.415722D+05 2.636228D+05
|
||||
2.309889D+06 3.771901D+06 1.257147D+06 7.512611D+05 6.408827D+05
|
||||
2.088500D+05 1.855621D+06 1.859930D+13 2.734790D+08 6.365689D+07
|
||||
5.015353D+07 5.375475D+07 6.309051D+07 7.590920D+07 9.149576D+07
|
||||
1.095308D+08 1.297965D+08 1.520463D+08 1.758883D+08 2.006097D+08
|
||||
2.248614D+08 3.260388D+13
|
||||
3.958279D+04 7.233998D+14 1.462518D-09 1.185639D+09 2.540761D+08
|
||||
3.272926D+08 4.791402D+08 6.840449D+08 9.365678D+08 1.231876D+09
|
||||
1.558956D+09 1.010917D+10 6.136479D+14 1.331039D+08 1.697364D+06
|
||||
4.447053D+05 3.633858D+06 1.115873D+06 7.168084D+05 2.250098D+05
|
||||
1.975412D+06 3.228689D+06 1.075292D+06 6.427025D+05 5.531744D+05
|
||||
1.802770D+05 1.604463D+06 1.447176D+13 3.704325D+08 9.407317D+07
|
||||
7.683345D+07 8.376443D+07 9.921782D+07 1.200317D+08 1.451819D+08
|
||||
1.741914D+08 2.067026D+08 2.422681D+08 2.801325D+08 3.188769D+08
|
||||
3.557708D+08 4.651206D+13
|
||||
4.157267D+04 8.803566D+14 1.765576D-09 1.364841D+09 3.300174D+08
|
||||
4.372863D+08 6.462059D+08 9.264423D+08 1.270937D+09 1.672174D+09
|
||||
2.111600D+09 1.222131D+10 7.408055D+14 8.555921D+07 1.291288D+06
|
||||
3.424700D+05 2.810274D+06 8.669680D+05 5.704057D+05 1.794784D+05
|
||||
1.578478D+06 2.582350D+06 8.595767D+05 5.138653D+05 4.460883D+05
|
||||
1.454326D+05 1.296117D+06 1.047311D+13 4.748288D+08 1.324509D+08
|
||||
1.123203D+08 1.246147D+08 1.490014D+08 1.812743D+08 2.200383D+08
|
||||
2.646062D+08 3.144034D+08 3.686334D+08 4.258750D+08 4.833792D+08
|
||||
5.357897D+08 6.310809D+13
|
||||
4.391141D+04 1.090568D+15 2.175378D-09 1.592290D+09 4.406094D+08
|
||||
6.011067D+08 8.971122D+08 1.291845D+09 1.775698D+09 2.336232D+09
|
||||
2.940342D+09 1.496565D+10 9.127503D+14 5.006892D+07 9.274078D+05
|
||||
2.491720D+05 2.053954D+06 6.366948D+05 4.291363D+05 1.354018D+05
|
||||
1.192739D+06 1.953226D+06 6.499776D+05 3.886412D+05 3.402423D+05
|
||||
1.110058D+05 9.903510D+05 7.107134D+12 5.906012D+08 1.826522D+08
|
||||
1.611998D+08 1.821751D+08 2.200023D+08 2.692448D+08 3.280436D+08
|
||||
3.954114D+08 4.704080D+08 5.515904D+08 6.362465D+08 7.189868D+08
|
||||
7.892494D+08 8.351649D+13
|
||||
4.667882D+04 1.379129D+15 2.742086D-09 1.891838D+09 6.071726D+08
|
||||
8.537437D+08 1.287420D+09 1.862428D+09 2.564858D+09 3.372592D+09
|
||||
4.222545D+09 1.855492D+10 1.150530D+15 2.719028D+07 6.430546D+05
|
||||
1.751408D+05 1.450577D+06 4.519252D+05 3.120809D+05 9.878243D+04
|
||||
8.713711D+05 1.428445D+06 4.753449D+05 2.842821D+05 2.509586D+05
|
||||
8.196382D+04 7.318182D+05 4.615631D+12 7.264411D+08 2.513391D+08
|
||||
2.313269D+08 2.665347D+08 3.252563D+08 4.005401D+08 4.899117D+08
|
||||
5.919154D+08 7.049424D+08 8.262693D+08 9.505262D+08 1.066794D+09
|
||||
1.153819D+09 1.095838D+14
|
||||
4.990589D+04 1.777263D+15 3.527412D-09 2.295262D+09 8.617941D+08
|
||||
1.249499D+09 1.904256D+09 2.767568D+09 3.817810D+09 5.012876D+09
|
||||
6.224920D+09 2.315364D+10 1.480036D+15 1.425540D+07 4.442577D+05
|
||||
1.226979D+05 1.021054D+06 3.197841D+05 2.261780D+05 7.184520D+04
|
||||
6.344745D+05 1.041212D+06 3.465860D+05 2.073215D+05 1.844982D+05
|
||||
6.033788D+04 5.390153D+05 2.958044D+12 8.965963D+08 3.489797D+08
|
||||
3.352624D+08 3.940024D+08 4.859686D+08 6.022587D+08 7.395273D+08
|
||||
8.955214D+08 1.067321D+09 1.249527D+09 1.431025D+09 1.588880D+09
|
||||
1.679751D+09 1.439176D+14
|
||||
5.359392D+04 2.327519D+15 4.615078D-09 2.852792D+09 1.256403D+09
|
||||
1.877771D+09 2.891952D+09 4.222010D+09 5.831597D+09 7.635453D+09
|
||||
9.360266D+09 2.886597D+10 1.936398D+15 7.558895D+06 3.158648D+05
|
||||
8.845637D+04 7.395095D+05 2.328377D+05 1.685526D+05 5.373829D+04
|
||||
4.750190D+05 7.803667D+05 2.598829D+05 1.554902D+05 1.394437D+05
|
||||
4.567008D+04 4.081355D+05 1.930337D+12 1.123458D+09 4.925659D+08
|
||||
4.937591D+08 5.917697D+08 7.376756D+08 9.199437D+08 1.133903D+09
|
||||
1.375826D+09 1.640068D+09 1.915354D+09 2.177637D+09 2.377306D+09
|
||||
2.427001D+09 1.902026D+14
|
||||
5.772347D+04 3.088010D+15 6.119564D-09 3.642360D+09 1.875859D+09
|
||||
2.886939D+09 4.491394D+09 6.584591D+09 9.100430D+09 1.185675D+10
|
||||
1.424419D+10 3.565413D+10 2.567646D+15 4.223628D+06 2.372518D+05
|
||||
6.732629D+04 5.654396D+05 1.789153D+05 1.324515D+05 4.237810D+04
|
||||
3.749528D+05 6.166124D+05 2.054374D+05 1.229401D+05 1.110761D+05
|
||||
3.643094D+04 3.256818D+05 1.315550D+12 1.439958D+09 7.092118D+08
|
||||
7.407338D+08 9.047668D+08 1.139443D+09 1.429529D+09 1.768184D+09
|
||||
2.148757D+09 2.559645D+09 2.976143D+09 3.344232D+09 3.555448D+09
|
||||
3.444392D+09 2.534138D+14
|
||||
6.227583D+04 4.133236D+15 8.188204D-09 4.768729D+09 2.851803D+09
|
||||
4.512423D+09 7.087588D+09 1.042959D+10 1.440957D+10 1.862202D+10
|
||||
2.167745D+10 4.315886D+10 3.435600D+15 2.542941D+06 1.903081D+05
|
||||
5.466900D+04 4.612659D+05 1.465872D+05 1.108775D+05 3.558921D+04
|
||||
3.152143D+05 5.188795D+05 1.729191D+05 1.035000D+05 9.418805D+04
|
||||
3.093154D+04 2.766280D+05 9.476718D+11 1.888860D+09 1.039366D+09
|
||||
1.128632D+09 1.403562D+09 1.784788D+09 2.251734D+09 2.793771D+09
|
||||
3.398147D+09 4.039804D+09 4.662564D+09 5.142678D+09 5.249274D+09
|
||||
4.717468D+09 3.398409D+14
|
||||
6.725311D+04 5.550439D+15 1.099387D-08 6.351794D+09 4.371820D+09
|
||||
7.099909D+09 1.125122D+10 1.660909D+10 2.290953D+10 2.922975D+10
|
||||
3.242651D+10 5.054036D+10 4.612790D+15 1.649100D+06 1.619664D+05
|
||||
4.705191D+04 3.988210D+05 1.272212D+05 9.821648D+04 3.161634D+04
|
||||
2.803340D+05 4.618864D+05 1.539428D+05 9.215838D+04 8.444616D+04
|
||||
2.776403D+04 2.484063D+05 7.198464D+11 2.518285D+09 1.537876D+09
|
||||
1.732014D+09 2.190514D+09 2.810746D+09 3.564322D+09 4.433689D+09
|
||||
5.393043D+09 6.386574D+09 7.284400D+09 7.806371D+09 7.503328D+09
|
||||
6.106102D+09 4.567763D+14
|
||||
7.267926D+04 7.436448D+15 1.472832D-08 8.517373D+09 6.685468D+09
|
||||
1.112424D+10 1.777380D+10 2.630405D+10 3.616011D+10 4.524154D+10
|
||||
4.675694D+10 5.661778D+10 6.179670D+15 1.136897D+06 1.440709D+05
|
||||
4.228835D+04 3.600259D+05 1.152338D+05 9.068958D+04 2.927051D+04
|
||||
2.598147D+05 4.284455D+05 1.428036D+05 8.550421D+04 7.885891D+04
|
||||
2.595411D+04 2.323116D+05 5.709179D+11 3.378388D+09 2.274097D+09
|
||||
2.649935D+09 3.404513D+09 4.405216D+09 5.612138D+09 6.994690D+09
|
||||
8.499025D+09 9.999681D+09 1.119909D+10 1.149610D+10 1.016939D+10
|
||||
7.357446D+09 6.122538D+14
|
||||
7.858647D+04 9.895650D+15 1.959817D-08 1.139342D+10 1.010749D+10
|
||||
1.720285D+10 2.769359D+10 4.105788D+10 5.612427D+10 6.821008D+10
|
||||
6.386134D+10 6.036481D+10 8.222931D+15 8.213782D+05 1.320202D+05
|
||||
3.912450D+04 3.344751D+05 1.073864D+05 8.604637D+04 2.783964D+04
|
||||
2.473679D+05 4.082464D+05 1.360736D+05 8.148737D+04 7.561171D+04
|
||||
2.490932D+04 2.230505D+05 4.680730D+11 4.520059D+09 3.331486D+09
|
||||
4.007242D+09 5.224134D+09 6.812127D+09 8.714060D+09 1.087443D+10
|
||||
1.317991D+10 1.535138D+10 1.673103D+10 1.615589D+10 1.286720D+10
|
||||
8.230798D+09 8.149019D+14
|
||||
8.501041D+04 1.303893D+16 2.582291D-08 1.510605D+10 1.501638D+10
|
||||
2.610010D+10 4.230552D+10 6.278001D+10 8.507888D+10 9.916779D+10
|
||||
8.162785D+10 6.140367D+10 1.083467D+16 6.148846D+05 1.232875D+05
|
||||
3.686303D+04 3.163653D+05 1.018617D+05 8.299649D+04 2.691355D+04
|
||||
2.393698D+05 3.953401D+05 1.317730D+05 7.892344D+04 7.364762D+04
|
||||
2.428389D+04 2.175329D+05 3.936253D+11 5.993436D+09 4.806126D+09
|
||||
5.954048D+09 7.868143D+09 1.033289D+10 1.326467D+10 1.656037D+10
|
||||
1.998350D+10 2.292963D+10 2.403215D+10 2.138962D+10 1.511381D+10
|
||||
8.624345D+09 1.073875D+15
|
||||
9.198890D+04 1.698519D+16 3.363790D-08 1.978095D+10 2.185385D+10
|
||||
3.873090D+10 6.316809D+10 9.373549D+10 1.254432D+11 1.379547D+11
|
||||
9.723477D+10 6.006281D+10 1.411363D+16 4.733957D+05 1.165418D+05
|
||||
3.513473D+04 3.026209D+05 9.769343D+04 8.084631D+04 2.627121D+04
|
||||
2.338664D+05 3.865173D+05 1.288330D+05 7.717294D+04 7.239299D+04
|
||||
2.388990D+04 2.140796D+05 3.377942D+11 7.848479D+09 6.806035D+09
|
||||
8.665547D+09 1.159603D+10 1.532748D+10 1.973462D+10 2.462448D+10
|
||||
2.951321D+10 3.314358D+10 3.291743D+10 2.649234D+10 1.655803D+10
|
||||
8.586537D+09 1.398989D+15
|
||||
9.956936D+04 2.187752D+16 4.332642D-08 2.557361D+10 3.116082D+10
|
||||
5.622952D+10 9.221509D+10 1.366750D+11 1.796941D+11 1.827670D+11
|
||||
1.083845D+11 5.703905D+10 1.817867D+16 3.735461D+05 1.112421D+05
|
||||
3.379450D+04 2.920521D+05 9.451194D+04 7.934860D+04 2.583457D+04
|
||||
2.301712D+05 3.806534D+05 1.268789D+05 7.601195D+04 7.165182D+04
|
||||
2.366339D+04 2.121198D+05 2.951084D+11 1.014700D+10 9.461679D+09
|
||||
1.235629D+10 1.672793D+10 2.224098D+10 2.870288D+10 3.575339D+10
|
||||
4.242743D+10 4.623658D+10 4.278713D+10 3.070437D+10 1.711856D+10
|
||||
8.240471D+09 1.802053D+15
|
||||
1.078080D+05 2.791586D+16 5.528436D-08 3.274209D+10 4.368849D+10
|
||||
8.016118D+10 1.321021D+11 1.952827D+11 2.505036D+11 2.302485D+11
|
||||
1.141731D+11 5.304034D+10 2.319589D+16 3.025328D+05 1.074883D+05
|
||||
3.288653D+04 2.850883D+05 9.246726D+04 7.867636D+04 2.566180D+04
|
||||
2.288086D+05 3.786245D+05 1.262031D+05 7.561583D+04 7.160091D+04
|
||||
2.366335D+04 2.121843D+05 2.626925D+11 1.299152D+10 1.295751D+10
|
||||
1.732426D+10 2.370625D+10 3.168604D+10 4.095955D+10 5.085797D+10
|
||||
5.950359D+10 6.223848D+10 5.271604D+10 3.351913D+10 1.693298D+10
|
||||
7.711539D+09 2.299566D+15
|
||||
1.167749D+05 3.541920D+16 7.014332D-08 4.178453D+10 6.065680D+10
|
||||
1.130255D+11 1.870379D+11 2.752652D+11 3.412521D+11 2.762112D+11
|
||||
1.150294D+11 4.861099D+10 2.943031D+16 2.530904D+05 1.059282D+05
|
||||
3.262320D+04 2.836208D+05 9.218457D+04 7.941466D+04 2.594586D+04
|
||||
2.315074D+05 3.833012D+05 1.277624D+05 7.655831D+04 7.279769D+04
|
||||
2.407471D+04 2.159341D+05 2.392603D+11 1.657980D+10 1.760222D+10
|
||||
2.405319D+10 3.324100D+10 4.463913D+10 5.775250D+10 7.134016D+10
|
||||
8.181739D+10 8.097910D+10 6.169794D+10 3.481729D+10 1.622451D+10
|
||||
7.095266D+09 2.917828D+15
|
||||
1.265563D+05 4.491044D+16 8.893887D-08 5.363748D+10 8.420589D+10
|
||||
1.591617D+11 2.642830D+11 3.862279D+11 4.564999D+11 3.164457D+11
|
||||
1.120646D+11 4.410763D+10 3.731641D+16 2.209559D+05 1.076846D+05
|
||||
3.336757D+04 2.908692D+05 9.472506D+04 8.254912D+04 2.701177D+04
|
||||
2.411790D+05 3.995184D+05 1.331683D+05 7.980564D+04 7.618150D+04
|
||||
2.520916D+04 2.261691D+05 2.244950D+11 2.128352D+10 2.394622D+10
|
||||
3.339152D+10 4.656850D+10 6.279168D+10 8.122445D+10 9.954028D+10
|
||||
1.109668D+11 1.020452D+11 6.887657D+10 3.477531D+10 1.520137D+10
|
||||
6.453885D+09 3.699938D+15
|
||||
1.372500D+05 5.720882D+16 1.132934D-07 6.992964D+10 1.180776D+11
|
||||
2.261478D+11 3.764542D+11 5.442415D+11 6.012933D+11 3.471973D+11
|
||||
1.064778D+11 3.974038D+10 4.753490D+16 2.036431D+05 1.143441D+05
|
||||
3.563322D+04 3.113931D+05 1.015930D+05 8.948845D+04 2.932473D+04
|
||||
2.619929D+05 4.342037D+05 1.447300D+05 8.674248D+04 8.310371D+04
|
||||
2.751543D+04 2.469208D+05 2.186679D+11 2.774895D+10 3.295217D+10
|
||||
4.682227D+10 6.584743D+10 8.908785D+10 1.150635D+11 1.393111D+11
|
||||
1.490990D+11 1.245161D+11 7.365199D+10 3.369575D+10 1.401887D+10
|
||||
5.824107D+09 4.713406D+15
|
||||
1.373594D+05 5.734791D+16 1.135689D-07 7.012194D+10 1.184836D+11
|
||||
2.269535D+11 3.778026D+11 5.461189D+11 6.028904D+11 3.474477D+11
|
||||
1.064146D+11 3.969893D+10 4.765046D+16 2.035588D+05 1.144495D+05
|
||||
3.566797D+04 3.117041D+05 1.016962D+05 8.958841D+04 2.935788D+04
|
||||
2.622907D+05 4.346991D+05 1.448951D+05 8.684152D+04 8.320143D+04
|
||||
2.754793D+04 2.472131D+05 2.186697D+11 2.782527D+10 3.305961D+10
|
||||
4.698325D+10 6.607897D+10 8.940372D+10 1.154687D+11 1.397811D+11
|
||||
1.495299D+11 1.247414D+11 7.368689D+10 3.368145D+10 1.400698D+10
|
||||
5.818107D+09 4.724867D+15
|
||||
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python3
|
||||
"""从 Tlusty 的 fort.9 输出判断模型的收敛性。
|
||||
|
||||
fort.9 文件逐迭代、逐深度地列出各状态参量的相对变化量。"MAXIMUM"列
|
||||
(第 7 个数据列)是该深度上最大的相对变化量。当*最后一次迭代*中、所有
|
||||
深度上 |MAXIMUM| 的最大值小于收敛阈值 CHMAX 时,即认为模型已收敛。
|
||||
|
||||
本模块的解析方式与已有 gui/tlusty.py 中的 pconv() 一致,但返回机器可读
|
||||
的结果而非绘图。
|
||||
|
||||
用法:
|
||||
check_conv.py fort.9 # 默认 CHMAX=0.001
|
||||
check_conv.py fort.9 --chmax 0.01 # 自定义阈值
|
||||
check_conv.py -j fort.9 # 输出 JSON
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
# 一行数据形如: ITER ID TEMP NE POP RAD MAXIMUM ilev ifr
|
||||
# 例如 " 28 1 -1.22E-06 1.21E-06 9.85E-04 ..."
|
||||
_DATA_ROW = re.compile(
|
||||
r"^\s*(\d+)\s+(\d+)\s+" # iter, depth(迭代号、深度索引)
|
||||
r"([-+\dE.]+)\s+" # temp(温度相对变化)
|
||||
r"([-+\dE.]+)\s+" # ne(电子密度相对变化)
|
||||
r"([-+\dE.]+)\s+" # pop(布居数相对变化)
|
||||
r"([-+\dE.]+)\s+" # rad(辐射场相对变化)
|
||||
r"([-+\dE.]+)\s+" # maximum(本深度最大相对变化)
|
||||
r"(\d+)\s+(\d+)\s*$" # ilev, ifr(触发的能级、频率索引)
|
||||
)
|
||||
|
||||
|
||||
def parse_fort9(path):
|
||||
"""解析 fort.9。返回 (last_iter, rows),其中 rows 是最后一次迭代各深度
|
||||
的 dict 列表,每项形如
|
||||
{depth, temp, ne, pop, rad, maximum}。"""
|
||||
last_iter = None
|
||||
cur_iter = None
|
||||
cur_rows = []
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
m = _DATA_ROW.match(line)
|
||||
if not m:
|
||||
continue
|
||||
it = int(m.group(1))
|
||||
if it != cur_iter:
|
||||
# 进入新的迭代块:保存上一次的(它就是当前最后一次)
|
||||
cur_iter = it
|
||||
cur_rows = []
|
||||
cur_rows.append({
|
||||
"depth": int(m.group(2)),
|
||||
"temp": float(m.group(3)),
|
||||
"ne": float(m.group(4)),
|
||||
"pop": float(m.group(5)),
|
||||
"rad": float(m.group(6)),
|
||||
"maximum": float(m.group(7)),
|
||||
})
|
||||
last_iter = it
|
||||
return last_iter, cur_rows
|
||||
|
||||
|
||||
def check(path, chmax=0.001):
|
||||
"""返回描述 `path`(fort.9)中模型收敛情况的 dict。
|
||||
|
||||
converged : bool -- 最后一次迭代所有深度上 |maximum| 的最大值 < chmax
|
||||
max_relc : float -- 该最大相对变化量
|
||||
worst_depth: int -- 出现最大值所在的深度索引
|
||||
last_iter : int|None -- 最后一次迭代的序号
|
||||
n_depths : int -- 最后一次迭代的深度数
|
||||
chmax : float -- 所用的收敛阈值
|
||||
"""
|
||||
last_iter, rows = parse_fort9(path)
|
||||
if not rows or last_iter is None:
|
||||
return {
|
||||
"converged": False,
|
||||
"max_relc": float("inf"),
|
||||
"worst_depth": -1,
|
||||
"last_iter": None,
|
||||
"n_depths": 0,
|
||||
"chmax": chmax,
|
||||
"error": "no iteration data found in fort.9",
|
||||
}
|
||||
# 最差(|maximum| 最大)的深度
|
||||
worst = max(rows, key=lambda r: abs(r["maximum"]))
|
||||
max_relc = abs(worst["maximum"])
|
||||
return {
|
||||
"converged": bool(max_relc < chmax),
|
||||
"max_relc": max_relc,
|
||||
"worst_depth": worst["depth"],
|
||||
"last_iter": last_iter,
|
||||
"n_depths": len(rows),
|
||||
"chmax": chmax,
|
||||
}
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:解析 fort.9 并打印收敛结果(默认文本,-j 输出 JSON)。"""
|
||||
ap = argparse.ArgumentParser(description="Check Tlusty model convergence")
|
||||
ap.add_argument("fort9", help="path to fort.9 (or model.9) file")
|
||||
ap.add_argument("--chmax", type=float, default=0.001,
|
||||
help="convergence limit (default 0.001)")
|
||||
ap.add_argument("-j", "--json", action="store_true",
|
||||
help="output full result as JSON")
|
||||
args = ap.parse_args()
|
||||
|
||||
res = check(args.fort9, args.chmax)
|
||||
if args.json:
|
||||
print(json.dumps(res, indent=2))
|
||||
else:
|
||||
status = "CONVERGED" if res["converged"] else "NOT CONVERGED"
|
||||
print("{}: iter={}, max_relc={:.3e} (depth {}), chmax={:.0e}, "
|
||||
"n_depths={}".format(
|
||||
status, res["last_iter"], res["max_relc"],
|
||||
res["worst_depth"], res["chmax"], res["n_depths"]))
|
||||
sys.exit(0 if res["converged"] else 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,184 @@
|
||||
#!/usr/bin/env python3
|
||||
"""生成一个 Tlusty NLTE 大气 .5 输入文件,包含 H/He 以及 C/N/O 的某个子集。
|
||||
|
||||
丰度采用 logX = log10(nX/nH) 表示,写入 .5 文件时的 abn 字段为
|
||||
abn = 10**logX。
|
||||
|
||||
模型原子(能级、数据文件)是固定的,与已验证的 BSTAR2006 设置一致
|
||||
(完整的 C/N/O 离子;He 数据文件 he1.dat/he2.dat 本身含 24/20 能级,
|
||||
但 .5 里 nlevs 声明为 14/14 —— 这是用户 tests.zip 验证过的稳定配置,
|
||||
tlusty 会按 nlevs 截断数据文件)。实际包含哪些金属由 `metals` 参数控制,
|
||||
由此实现"渐进式收敛"策略:先 H+He+C,再 H+He+C+N,最后 H+He+C+N+O。
|
||||
|
||||
用法:
|
||||
gen_input5.py --teff 35000 --logg 5.5 --loghe -2 \
|
||||
--logc -1 --logn -1 --logo -1 --metals c -o model.5
|
||||
|
||||
也可作为模块导入:from gen_input5 import make_input5, model_name
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
|
||||
# abn = 10**0 在 Tlusty 中表示"采用太阳丰度"。氢是参考元素,其 abn 字段
|
||||
# 写 0(太阳丰度哨兵值)。
|
||||
ABN_H_SOLAR = "0."
|
||||
|
||||
# 固定的模型原子定义:(iat, iz, nlevs, typion, file)
|
||||
# 与 BSTAR2006 设置一致。He 数据文件本身含 24/20 能级(Peter Nemeth 建议),
|
||||
# 但此处 nlevs 声明为 14/14 —— 用户 tests.zip 验证过的稳定配置,tlusty 会
|
||||
# 按此截断 he1.dat/he2.dat,只读前 14 个能级。详见 EXPERIENCE.md §2.5/§3.3。
|
||||
_IONS_H = [
|
||||
(1, 0, 9, " H 1", "data/h1.dat"),
|
||||
(1, 1, 1, " H 2", " "),
|
||||
]
|
||||
_IONS_HE = [
|
||||
(2, 0, 14, "He 1", "data/he1.dat"),
|
||||
(2, 1, 14, "He 2", "data/he2.dat"),
|
||||
(2, 2, 1, "He 3", " "),
|
||||
]
|
||||
_IONS_C = [
|
||||
(6, 0, 40, " C 1", "data/c1.dat"),
|
||||
(6, 1, 22, " C 2", "data/c2.dat"),
|
||||
(6, 2, 46, " C 3", "data/c3_34+12lev.dat"),
|
||||
(6, 3, 25, " C 4", "data/c4.dat"),
|
||||
(6, 4, 1, " C 5", " "),
|
||||
]
|
||||
_IONS_N = [
|
||||
(7, 0, 34, " N 1", "data/n1.dat"),
|
||||
(7, 1, 42, " N 2", "data/n2_32+10lev.dat"),
|
||||
(7, 2, 32, " N 3", "data/n3.dat"),
|
||||
(7, 3, 48, " N 4", "data/n4_34+14lev.dat"),
|
||||
(7, 4, 16, " N 5", "data/n5.dat"),
|
||||
(7, 5, 1, " N 6", " "),
|
||||
]
|
||||
_IONS_O = [
|
||||
(8, 0, 33, " O 1", "data/o1_23+10lev.dat"),
|
||||
(8, 1, 48, " O 2", "data/o2_36+12lev.dat"),
|
||||
(8, 2, 41, " O 3", "data/o3_28+13lev.dat"),
|
||||
(8, 3, 39, " O 4", "data/o4.dat"),
|
||||
(8, 4, 6, " O 5", "data/o5.dat"),
|
||||
(8, 5, 1, " O 6", " "),
|
||||
]
|
||||
|
||||
|
||||
def model_name(teff, logg, loghe, logc, logn, logo):
|
||||
"""生成编码 6 个参数的规范模型名。"""
|
||||
return "t{:d}_g{:.1f}_he{:.0f}_c{:.0f}_n{:.0f}_o{:.0f}".format(
|
||||
int(round(teff)), logg, loghe, logc, logn, logo
|
||||
)
|
||||
|
||||
|
||||
def _fmt_abn(logx):
|
||||
"""把对数丰度格式化为 .5 文件中的 abn 字段(线性 10**logx)。"""
|
||||
return "{:.4E}".format(10.0 ** logx)
|
||||
|
||||
|
||||
def make_input5(teff, logg, loghe, logc, logn, logo, template=None,
|
||||
lte="F", ltgray="F", metals="cno", ilvlin=100):
|
||||
"""返回 .5 文件的文本内容。
|
||||
|
||||
teff : 有效温度 [K]
|
||||
logg : log10(表面重力) [cgs]
|
||||
loghe : log10(nHe/nH)
|
||||
logc : log10(nC /nH)
|
||||
logn : log10(nN /nH)
|
||||
logo : log10(nO /nH)
|
||||
template: 已忽略(保留参数仅为向后兼容);文件直接构造。
|
||||
lte : 'F'(NLTE)或 'T'(LTE 灰度初始模型,无需 fort.8)
|
||||
ltgray : 'F' 或 'T'
|
||||
metals : 要包含 C/N/O 中的哪些:任意子集字符串,如 '', 'c', 'cn',
|
||||
'cno'。用于实现渐进式收敛。
|
||||
ilvlin : 每个能级的最大谱线跃迁数(ions 块第 5 列)。
|
||||
0 = 仅连续谱(即 'nc' 步);100 = 完整谱线(即 'nl' 步)。
|
||||
这是已验证的三步收敛策略中的关键开关。
|
||||
"""
|
||||
mt = set(metals.lower())
|
||||
|
||||
# ---- atoms 节 ----
|
||||
# 第 3、4、5 槽位始终为空(Li、Be、B);6=C 7=N 8=O。
|
||||
atom_rows = [
|
||||
(2, ABN_H_SOLAR), # 1 H (显式 NLTE)
|
||||
(2, _fmt_abn(loghe)), # 2 He (显式 NLTE)
|
||||
(0, "0."), # 3 Li
|
||||
(0, "0."), # 4 Be
|
||||
(0, "0."), # 5 B
|
||||
]
|
||||
if "c" in mt:
|
||||
atom_rows.append((2, _fmt_abn(logc))) # 6 C
|
||||
if "n" in mt:
|
||||
atom_rows.append((2, _fmt_abn(logn))) # 7 N
|
||||
if "o" in mt:
|
||||
atom_rows.append((2, _fmt_abn(logo))) # 8 O
|
||||
natoms = 5 + len([m for m in "cno" if m in mt])
|
||||
|
||||
atoms_block = " {}\n* mode abn modpf\n".format(natoms)
|
||||
for mode, abn in atom_rows:
|
||||
atoms_block += " {} {} 0\n".format(mode, abn)
|
||||
|
||||
# ---- ions 节 ----
|
||||
ions = list(_IONS_H) + list(_IONS_HE)
|
||||
if "c" in mt:
|
||||
ions += _IONS_C
|
||||
if "n" in mt:
|
||||
ions += _IONS_N
|
||||
if "o" in mt:
|
||||
ions += _IONS_O
|
||||
|
||||
ions_block = "*iat iz nlevs ilast ilvlin nonstd typion filei\n*\n"
|
||||
for iat, iz, nlevs, typion, filei in ions:
|
||||
ilast = 1 if (nlevs == 1) else 0
|
||||
# 单能级离子(裸核)无谱线;其他用 ilvlin
|
||||
ilvl = 0 if (nlevs == 1) else ilvlin
|
||||
ions_block += (" {iat} {iz:2d} {nlevs:5d} {ilast:5d}"
|
||||
" {ilvl:5d} 0 '{t}' '{f}'\n").format(
|
||||
iat=iat, iz=iz, nlevs=nlevs, ilast=ilast, ilvl=ilvl,
|
||||
t=typion, f=filei)
|
||||
ions_block += " 0 0 0 -1 0 0 ' ' ' '\n"
|
||||
|
||||
text = (
|
||||
"{teff:.1f} {logg:.1f} ! TEFF, GRAV\n"
|
||||
" {lte} {ltgray} ! LTE, LTGRAY\n"
|
||||
" 'nst' ! name of file containing non-standard flags\n"
|
||||
"*-----------------------------------------------------------------\n"
|
||||
"* frequencies\n"
|
||||
" 2000 ! NFREAD\n"
|
||||
"*-----------------------------------------------------------------\n"
|
||||
"* data for atoms\n"
|
||||
"{atoms}*-----------------------------------------------------------------\n"
|
||||
"* data for ions\n*\n"
|
||||
"{ions}*\n* end\n"
|
||||
).format(teff=teff, logg=logg, lte=lte, ltgray=ltgray,
|
||||
atoms=atoms_block, ions=ions_block)
|
||||
return text
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:根据参数生成 .5 文件。"""
|
||||
ap = argparse.ArgumentParser(
|
||||
description="Generate a H/He/(C/N/O) NLTE atmosphere .5 file")
|
||||
ap.add_argument("--teff", type=float, required=True)
|
||||
ap.add_argument("--logg", type=float, required=True)
|
||||
ap.add_argument("--loghe", type=float, required=True)
|
||||
ap.add_argument("--logc", type=float, required=True)
|
||||
ap.add_argument("--logn", type=float, required=True)
|
||||
ap.add_argument("--logo", type=float, required=True)
|
||||
ap.add_argument("--metals", default="cno",
|
||||
help="subset of cno to include: '', 'c', 'cn', 'cno'")
|
||||
ap.add_argument("--lte", default="F")
|
||||
ap.add_argument("--ltgray", default="F")
|
||||
ap.add_argument("-o", "--output", default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
text = make_input5(args.teff, args.logg, args.loghe, args.logc, args.logn,
|
||||
args.logo, lte=args.lte, ltgray=args.ltgray,
|
||||
metals=args.metals)
|
||||
name = model_name(args.teff, args.logg, args.loghe,
|
||||
args.logc, args.logn, args.logo)
|
||||
out = args.output or name + ".5"
|
||||
with open(out, "w") as f:
|
||||
f.write(text)
|
||||
print("wrote {} ({}, metals={})".format(out, name, args.metals or "none"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python3
|
||||
"""绘制归一化合成光谱,并标注 C/N/O 诊断谱线位置。
|
||||
|
||||
读取 results/<name>/<name>.spec(fort.7 格式:波长、流量)和连续谱
|
||||
results/<name>/<name>.cont,计算流量/连续谱,并叠加关键 C/N/O 谱线
|
||||
的位置,以确认金属元素确实存在。
|
||||
|
||||
用法:
|
||||
plot_spec.py results/<model_name> [-o plot.png]
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import numpy as np
|
||||
|
||||
# 热亚矮星的关键诊断谱线(波长单位 Angstrom,附标签)
|
||||
# 这些是该 Teff 区间内光学/NUV 波段最强的 C/N/O 特征谱线。
|
||||
DIAG_LINES = [
|
||||
(4267.15, "C II"),
|
||||
(4647.42, "C III"),
|
||||
(4649.07, "C III"),
|
||||
(4650.25, "C III"),
|
||||
(4068.92, "C III"),
|
||||
(3995.00, "N II"),
|
||||
(4630.54, "N II"),
|
||||
(4447.03, "N IV"),
|
||||
(4057.81, "N V"),
|
||||
(4603.17, "N V"),
|
||||
(4414.90, "O II"),
|
||||
(4641.81, "O II"),
|
||||
(4649.13, "O II"),
|
||||
(5597.95, "O III"),
|
||||
]
|
||||
|
||||
|
||||
def read_fort(path):
|
||||
"""读取 synspec 风格的 fort.7/.17 文件:注释行以 '#' 开头,
|
||||
列依次为 wavelength、flux。返回两个 numpy 数组 (wave, flux)。"""
|
||||
wave, flux = [], []
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if not line or line.startswith("#"):
|
||||
continue
|
||||
parts = line.split()
|
||||
if len(parts) < 2:
|
||||
continue
|
||||
try:
|
||||
w = float(parts[0]); fl = float(parts[1])
|
||||
except ValueError:
|
||||
continue
|
||||
wave.append(w); flux.append(fl)
|
||||
return np.array(wave), np.array(flux)
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:读光谱、归一化、叠加诊断谱线并保存 PNG。"""
|
||||
ap = argparse.ArgumentParser(description="Plot normalized spectrum + CNO lines")
|
||||
ap.add_argument("model_dir", help="path to results/<model_name> dir")
|
||||
ap.add_argument("-o", "--output", default=None,
|
||||
help="output png (default: <model_dir>/spectrum.png?)")
|
||||
ap.add_argument("--wmin", type=float, default=None)
|
||||
ap.add_argument("--wmax", type=float, default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
name = os.path.basename(os.path.normpath(args.model_dir))
|
||||
spec = os.path.join(args.model_dir, name + ".spec")
|
||||
cont = os.path.join(args.model_dir, name + ".cont")
|
||||
if not os.path.exists(spec):
|
||||
# 回退:若 .spec/.cont 不存在,尝试原始的 fort.7 / fort.17
|
||||
spec = os.path.join(args.model_dir, "fort.7")
|
||||
cont = os.path.join(args.model_dir, "fort.17")
|
||||
if not os.path.exists(spec):
|
||||
sys.exit("no spectrum found in {}".format(args.model_dir))
|
||||
|
||||
import matplotlib
|
||||
matplotlib.use("Agg")
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
w, f = read_fort(spec)
|
||||
if os.path.exists(cont):
|
||||
wc, fc = read_fort(cont)
|
||||
# 把连续谱插值到光谱网格上
|
||||
fc_int = np.interp(w, wc, fc)
|
||||
norm = np.where(fc_int > 0, f / fc_int, 1.0)
|
||||
else:
|
||||
# 没有连续谱时退化为按中位数归一
|
||||
norm = f / np.median(f)
|
||||
|
||||
# 默认窗口:3000-7000A(光学),可被 --wmin/--wmax 覆盖
|
||||
wmin = args.wmin or (w.min() if w.min() > 3000 else 3000)
|
||||
wmax = args.wmax or min(w.max(), 7000)
|
||||
m = (w >= wmin) & (w <= wmax)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(16, 5))
|
||||
ax.plot(w[m], norm[m], "k-", lw=0.5)
|
||||
ax.set_xlabel("Wavelength [A]")
|
||||
ax.set_ylabel("Normalized flux")
|
||||
ax.set_title(name)
|
||||
ymax = np.percentile(norm[m], 99.5) * 1.1
|
||||
ax.set_ylim(0, ymax)
|
||||
ax.set_xlim(wmin, wmax)
|
||||
|
||||
# 叠加诊断谱线(红色虚竖线 + 标签)
|
||||
ymin, ymaxl = ax.get_ylim()
|
||||
for wl, lab in DIAG_LINES:
|
||||
if wmin <= wl <= wmax:
|
||||
ax.axvline(wl, color="r", ls=":", lw=0.7, alpha=0.6)
|
||||
ax.text(wl, ymaxl * 0.95, lab, rotation=90, fontsize=7,
|
||||
color="r", va="top", ha="right")
|
||||
|
||||
out = args.output or os.path.join(args.model_dir, "spectrum.png")
|
||||
fig.tight_layout()
|
||||
fig.savefig(out, dpi=120)
|
||||
print("wrote", out)
|
||||
# 简要报告:窗口内最深的吸收线
|
||||
depth = 1.0 - norm[m]
|
||||
print("window {:.0f}-{:.0f}A: {} points, deepest absorption {:.2f}".format(
|
||||
wmin, wmax, m.sum(), float(np.max(depth))))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,371 @@
|
||||
#!/usr/bin/env python3
|
||||
"""调度 6 维 H/He/C/N/O NLTE 网格的计算。
|
||||
|
||||
生成各维采样点的完整笛卡尔积,对每个点执行收敛链 + synspec(通过
|
||||
run_one.run_model)。主要特性:
|
||||
- 断点续算:跳过 conv.json 中 converged=true 的模型
|
||||
- 种子复用:优先用已收敛的邻居大气作种子(减少冷启动);
|
||||
若无邻居则回退到 LTE-grey 阶段从零开始
|
||||
- 种子步进回退:冷启动失败时,自动用已收敛邻居作种子重试
|
||||
(seed_step chain: LTGRAY=F 热启动 + ICHANG=0)
|
||||
- 并行:multiprocessing.Pool,每个 worker 独立工作目录
|
||||
- 失败隔离:单个模型失败不影响全局,结果记录到 grid_status.json
|
||||
- 桥头堡优先:可选 bridgehead 列表,先算容易收敛的点建立种子库
|
||||
|
||||
用法:
|
||||
run_grid.py config.yaml # 跑整个网格
|
||||
run_grid.py config.yaml --dry-run # 仅列出模型,不计算
|
||||
run_grid.py config.yaml --only teff=35000,logg=5.5 # 过滤
|
||||
"""
|
||||
import argparse
|
||||
import itertools
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
import traceback
|
||||
from multiprocessing import Pool
|
||||
|
||||
try:
|
||||
import yaml
|
||||
def _load_yaml(path):
|
||||
with open(path) as f:
|
||||
return yaml.safe_load(f)
|
||||
except ImportError:
|
||||
# 针对本项目配置格式的极简 YAML 读取器:顶层 `key: value`,嵌套的
|
||||
# `grid:` 块由 `subkey: [...]` 组成,行内列表 `[a, b]`,以及由 dict 列表
|
||||
# 构成的 `chain:` 块。此处不依赖 pyyaml。
|
||||
def _load_yaml(path):
|
||||
cfg = {}
|
||||
chain = []
|
||||
section = None # 当前嵌套 dict(如 grid 块),或 None
|
||||
with open(path) as f:
|
||||
for raw in f:
|
||||
line = raw.split("#", 1)[0].rstrip()
|
||||
if not line.strip():
|
||||
continue
|
||||
stripped = line.strip()
|
||||
indented = line[:1] in (" ", "\t")
|
||||
# chain 下的 dict 列表条目:"- {label: x, ...}"
|
||||
if stripped.startswith("- "):
|
||||
body = stripped[2:].strip()
|
||||
if body.startswith("{") and body.endswith("}"):
|
||||
d = {}
|
||||
for kv in body[1:-1].split(","):
|
||||
if ":" in kv:
|
||||
k, v = kv.split(":", 1)
|
||||
d[k.strip()] = _scalar(v.strip())
|
||||
chain.append(d)
|
||||
continue
|
||||
if ":" not in stripped:
|
||||
continue
|
||||
key, val = stripped.split(":", 1)
|
||||
key = key.strip()
|
||||
val = val.strip()
|
||||
if val == "":
|
||||
# 嵌套块的节标题
|
||||
cfg[key] = {}
|
||||
section = cfg[key]
|
||||
if key == "chain":
|
||||
section = None # chain 是列表,已在上面处理
|
||||
cfg["chain"] = chain
|
||||
continue
|
||||
# 标量 / 行内列表值
|
||||
if section is not None and indented:
|
||||
section[key] = _parse_val(val)
|
||||
else:
|
||||
cfg[key] = _parse_val(val)
|
||||
section = None
|
||||
if chain and "chain" not in cfg:
|
||||
cfg["chain"] = chain
|
||||
return cfg
|
||||
|
||||
def _parse_val(val):
|
||||
"""把行内字符串解析为标量或列表。"""
|
||||
val = val.strip()
|
||||
if val.startswith("[") and val.endswith("]"):
|
||||
return [_scalar(x.strip()) for x in val[1:-1].split(",") if x.strip()]
|
||||
return _scalar(val)
|
||||
|
||||
def _scalar(v):
|
||||
"""把单个字符串解析为 bool/int/float,否则原样返回。"""
|
||||
if v in ("true", "True"):
|
||||
return True
|
||||
if v in ("false", "False"):
|
||||
return False
|
||||
try:
|
||||
return int(v)
|
||||
except ValueError:
|
||||
pass
|
||||
try:
|
||||
return float(v)
|
||||
except ValueError:
|
||||
pass
|
||||
return v
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import run_one # noqa: E402
|
||||
import gen_input5 # noqa: E402
|
||||
import seed_step # noqa: E402 -- 提供 SEED_STEP_CHAIN
|
||||
|
||||
TLUSTY = os.environ.get(
|
||||
"TLUSTY", "/home/dckj/program/tlusty/tl208-s54")
|
||||
|
||||
|
||||
def expand_grid(grid):
|
||||
"""生成 (teff,logg,loghe,logc,logn,logo) 的完整笛卡尔积。"""
|
||||
keys = ["teff", "logg", "loghe", "logc", "logn", "logo"]
|
||||
for combo in itertools.product(*(grid[k] for k in keys)):
|
||||
yield dict(zip(keys, combo))
|
||||
|
||||
|
||||
def model_done(results_root, name):
|
||||
"""该模型是否已成功完成(conv.json 报告 converged=true)。"""
|
||||
p = os.path.join(results_root, name, "conv.json")
|
||||
if not os.path.exists(p):
|
||||
return False
|
||||
try:
|
||||
with open(p) as f:
|
||||
return bool(json.load(f).get("converged"))
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def _atmos_clean(atmos_path):
|
||||
"""检查大气文件是否干净(无 NaN 污染)。
|
||||
|
||||
种子必须是干净的——若种子本身含 NaN(发散过的中间结果),
|
||||
传递给下一个模型会让其布居数也变 NaN。
|
||||
"""
|
||||
if not os.path.isfile(atmos_path):
|
||||
return False
|
||||
try:
|
||||
with open(atmos_path) as f:
|
||||
lines = f.readlines()
|
||||
if not lines:
|
||||
return False
|
||||
nan_count = sum(1 for l in lines if "nan" in l.lower())
|
||||
return nan_count < len(lines) * 0.1 # <10% NaN 视为干净
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def find_seed(results_root, teff, logg, loghe, logc=None, logn=None, logo=None):
|
||||
"""查找已收敛的邻居大气作种子,返回路径或 None。
|
||||
|
||||
优先级(从高到低):
|
||||
1. 完全匹配 (teff,logg,loghe) 且 CNO 更接近 → 几乎自由(同 family)
|
||||
2. 同 (teff,logg,loghe) 但 CNO 不同 → 丰度步进
|
||||
3. 全局最近邻(按 Teff/logg/logHe 加权距离)
|
||||
|
||||
若无可用的干净种子,返回 None。LTE-grey 阶段会处理无种子的情况,
|
||||
所以返回 None 总是安全的。
|
||||
|
||||
若传入 logc/logn/logo,则优先选金属丰度差距小的种子——因为丰度
|
||||
跨度过大(如 logCNO 从 -4 直接跳 -1,1000× 跳跃)会导致 seed_step
|
||||
也发散(见 EXPERIENCE.md 错误 7)。
|
||||
"""
|
||||
if not os.path.isdir(results_root):
|
||||
return None
|
||||
exact_family = None # 同 (teff,logg,loghe) 的最近 CNO 邻居
|
||||
exact_family_d = None
|
||||
closest = None # 全局最近邻
|
||||
closest_d = None
|
||||
for d in os.listdir(results_root):
|
||||
# 跳过备份目录(如 .OLD_WRONG_ABN, .FAILED_ORELAX 后缀)
|
||||
if d.startswith(".") or ".OLD" in d or ".FAILED" in d:
|
||||
continue
|
||||
full = os.path.join(results_root, d)
|
||||
if not os.path.isdir(full):
|
||||
continue
|
||||
conv = os.path.join(full, "conv.json")
|
||||
atmo = os.path.join(full, d + ".7")
|
||||
if not (os.path.isfile(conv) and _atmos_clean(atmo)):
|
||||
continue
|
||||
try:
|
||||
with open(conv) as f:
|
||||
meta = json.load(f)
|
||||
except Exception:
|
||||
continue
|
||||
if not meta.get("converged"):
|
||||
continue
|
||||
if meta.get("atmosphere_has_nan"):
|
||||
continue
|
||||
p = meta["params"]
|
||||
# 同 family (Teff,logg,logHe):按 CNO 距离排序
|
||||
if (p["teff"] == teff and p["logg"] == logg
|
||||
and p["loghe"] == loghe):
|
||||
if logc is not None:
|
||||
dcno = (abs(p["logc"] - logc) + abs(p["logn"] - logn)
|
||||
+ abs(p["logo"] - logo))
|
||||
else:
|
||||
dcno = 0.0
|
||||
if exact_family_d is None or dcno < exact_family_d:
|
||||
exact_family_d, exact_family = dcno, atmo
|
||||
continue
|
||||
# 全局最近邻:Teff/logg/logHe 加权距离
|
||||
d_total = (abs(p["teff"] - teff) / 5000.0
|
||||
+ abs(p["logg"] - logg) * 2.0
|
||||
+ abs(p["loghe"] - loghe) * 0.5)
|
||||
if closest_d is None or d_total < closest_d:
|
||||
closest_d, closest = d_total, atmo
|
||||
# 同 family 优先(哪怕 CNO 跨度大);否则用全局最近邻
|
||||
return exact_family or closest
|
||||
|
||||
|
||||
def _worker(args):
|
||||
"""Pool worker:跑一个模型。必须是顶层函数以便 pickle。"""
|
||||
(pt, results_root, template, fort55, linelist, chain, itek_fallback,
|
||||
niter, timeout, seed_step_fallback) = args
|
||||
name = gen_input5.model_name(pt["teff"], pt["logg"], pt["loghe"],
|
||||
pt["logc"], pt["logn"], pt["logo"])
|
||||
if model_done(results_root, name):
|
||||
return {"name": name, "status": "skipped"}
|
||||
# 把 chain/fallback patch 到模块级,让 run_model 能取到
|
||||
if chain:
|
||||
run_one.DEFAULT_CHAIN = chain
|
||||
if itek_fallback:
|
||||
run_one.ITEK_FALLBACK = itek_fallback
|
||||
if niter:
|
||||
run_one.DEFAULT_NITER = niter
|
||||
seed = find_seed(results_root, pt["teff"], pt["logg"], pt["loghe"],
|
||||
pt["logc"], pt["logn"], pt["logo"])
|
||||
try:
|
||||
summary = run_one.run_model(
|
||||
pt["teff"], pt["logg"], pt["loghe"], pt["logc"], pt["logn"],
|
||||
pt["logo"], results_root, template, fort55, linelist,
|
||||
chain=chain or run_one.DEFAULT_CHAIN, seed=seed, timeout=timeout)
|
||||
# 冷启动失败 + 启用了 seed_step 回退 + 找到了干净种子:
|
||||
# 用 seed_step chain(LTGRAY=F 热启动)重试。把失败结果备份后重算。
|
||||
if (not summary["converged"] and seed_step_fallback
|
||||
and seed is not None):
|
||||
backup_dir = os.path.join(results_root, name + ".coldfail")
|
||||
if os.path.exists(backup_dir):
|
||||
shutil.rmtree(backup_dir)
|
||||
shutil.move(os.path.join(results_root, name), backup_dir)
|
||||
print(" [seed_step] {} cold-start failed, retrying with seed {}".format(
|
||||
name, os.path.basename(os.path.dirname(seed))))
|
||||
try:
|
||||
summary = run_one.run_model(
|
||||
pt["teff"], pt["logg"], pt["loghe"], pt["logc"],
|
||||
pt["logn"], pt["logo"], results_root, template, fort55,
|
||||
linelist, chain=seed_step.SEED_STEP_CHAIN,
|
||||
seed=seed, timeout=timeout)
|
||||
summary["seed_step_used"] = True
|
||||
summary["coldfail_backup"] = backup_dir
|
||||
except Exception as e:
|
||||
return {"name": name, "status": "error",
|
||||
"error": "seed_step: " + str(e),
|
||||
"traceback": traceback.format_exc()[:800]}
|
||||
return {"name": name,
|
||||
"status": "converged" if summary["converged"] else "unfinished",
|
||||
"max_relc": summary.get("final_max_relc"),
|
||||
"seed_step_used": summary.get("seed_step_used", False)}
|
||||
except Exception as e:
|
||||
return {"name": name, "status": "error", "error": str(e),
|
||||
"traceback": traceback.format_exc()[:800]}
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:解析 config.yaml,展开网格,逐点跑模型并汇总。"""
|
||||
ap = argparse.ArgumentParser(description="Run the 6-D CNO NLTE grid")
|
||||
ap.add_argument("config", help="path to config.yaml")
|
||||
ap.add_argument("--dry-run", action="store_true",
|
||||
help="list models that would be computed, then exit")
|
||||
ap.add_argument("--only", default=None,
|
||||
help="filter, e.g. teff=35000,logg=5.5 (exact matches)")
|
||||
ap.add_argument("--limit", type=int, default=None,
|
||||
help="compute at most N models (for testing)")
|
||||
args = ap.parse_args()
|
||||
|
||||
with open(args.config) as f:
|
||||
cfg = _load_yaml(args.config)
|
||||
|
||||
results_root = os.path.join(TLUSTY, "cno_grid", cfg.get("results", "results")) \
|
||||
if not os.path.isabs(cfg["results"]) else cfg["results"]
|
||||
template = cfg["template"] if os.path.isabs(cfg["template"]) else \
|
||||
os.path.join(os.path.dirname(args.config), cfg["template"])
|
||||
fort55 = cfg["fort55"] if os.path.isabs(cfg["fort55"]) else \
|
||||
os.path.join(os.path.dirname(args.config), cfg["fort55"])
|
||||
linelist = cfg["linelist"] if os.path.isabs(cfg["linelist"]) else \
|
||||
os.path.join(TLUSTY, cfg["linelist"])
|
||||
|
||||
# 解析 --only 过滤条件
|
||||
filt = {}
|
||||
if args.only:
|
||||
for part in args.only.split(","):
|
||||
k, v = part.split("=")
|
||||
filt[k.strip()] = float(v)
|
||||
|
||||
points = []
|
||||
for pt in expand_grid(cfg["grid"]):
|
||||
if all(pt.get(k) == v for k, v in filt.items()):
|
||||
points.append(pt)
|
||||
if args.limit:
|
||||
points = points[:args.limit]
|
||||
|
||||
n_total = len(points)
|
||||
n_skip = sum(1 for pt in points
|
||||
if model_done(results_root,
|
||||
gen_input5.model_name(
|
||||
pt["teff"], pt["logg"], pt["loghe"],
|
||||
pt["logc"], pt["logn"], pt["logo"])))
|
||||
print("grid: {} points total, {} already done, {} to compute".format(
|
||||
n_total, n_skip, n_total - n_skip))
|
||||
if args.dry_run:
|
||||
for pt in points[:50]:
|
||||
print(" ", pt)
|
||||
if n_total > 50:
|
||||
print(" ... ({} more)".format(n_total - 50))
|
||||
return
|
||||
|
||||
os.makedirs(results_root, exist_ok=True)
|
||||
chain = cfg.get("chain")
|
||||
itek_fallback = cfg.get("itek_fallback")
|
||||
niter = cfg.get("niter")
|
||||
timeout = cfg.get("timeout_sec", 3600)
|
||||
nworkers = cfg.get("nworkers", 1)
|
||||
# 种子步进回退:冷启动失败时,用已收敛邻居作种子重试(默认启用)
|
||||
seed_step_fallback = cfg.get("seed_step_fallback", True)
|
||||
|
||||
worker_args = [(pt, results_root, template, fort55, linelist,
|
||||
chain, itek_fallback, niter, timeout, seed_step_fallback)
|
||||
for pt in points]
|
||||
|
||||
t0 = time.time()
|
||||
status_log = []
|
||||
# 单 worker 串行:便于排查;多 worker 用 Pool 并行
|
||||
if nworkers <= 1:
|
||||
for wa in worker_args:
|
||||
res = _worker(wa)
|
||||
status_log.append(res)
|
||||
print(" [{}/{}] {} -> {}".format(
|
||||
len(status_log), n_total, res["name"], res["status"]),
|
||||
flush=True)
|
||||
else:
|
||||
with Pool(nworkers) as pool:
|
||||
for res in pool.imap_unordered(_worker, worker_args):
|
||||
status_log.append(res)
|
||||
print(" [{}/{}] {} -> {}".format(
|
||||
len(status_log), n_total, res["name"], res["status"]),
|
||||
flush=True)
|
||||
|
||||
# 汇总每个状态的数量,以及有多少走了 seed_step 回退路径
|
||||
counts = {}
|
||||
seed_step_count = 0
|
||||
for r in status_log:
|
||||
counts[r["status"]] = counts.get(r["status"], 0) + 1
|
||||
if r.get("seed_step_used"):
|
||||
seed_step_count += 1
|
||||
summary = {"total": n_total, "elapsed_sec": round(time.time() - t0, 1),
|
||||
"counts": counts, "seed_step_retries": seed_step_count,
|
||||
"models": status_log}
|
||||
with open(os.path.join(results_root, "grid_status.json"), "w") as f:
|
||||
json.dump(summary, f, indent=2)
|
||||
print("\nDONE. counts={}, seed_step_retries={}, {:.0f}s".format(
|
||||
counts, seed_step_count, summary["elapsed_sec"]))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,414 @@
|
||||
#!/usr/bin/env python3
|
||||
"""计算单个 H/He/C/N/O NLTE 大气模型 + 合成光谱。
|
||||
|
||||
实现与 Peter Nemeth 通信中推荐的"收敛链"策略:对于难收敛的(富 He 或富金属)
|
||||
模型,先用较松的 CHMAX(如 0.1)收敛,再把该模型作为下一轮的初始大气,
|
||||
逐步收紧 CHMAX(0.01)直到目标值(0.001)。如果某一步未能收敛,则增大
|
||||
迭代数 ITEK(3 -> 15 -> 100),以速度换取稳定性。
|
||||
|
||||
单个模型的处理流程:
|
||||
1. 生成 .5 输入文件(gen_input5.make_input5)
|
||||
2. 对链中的每个 (CHMAX, ITEK) 阶段:
|
||||
- 写入该阶段 CHMAX/ITEK 对应的 nst 文件
|
||||
- 把种子大气链接为 fort.8
|
||||
- 运行 tlusty.exe -> fort.7(大气)、fort.9(收敛日志)
|
||||
- 检查收敛性(check_conv.check)
|
||||
- 若收敛:本阶段的 .7 成为下一阶段的种子
|
||||
- 若未收敛:增大 ITEK 并在相同 CHMAX 下重试
|
||||
3. 最终阶段完成后(无论收敛与否),运行 synspec
|
||||
4. 写入 conv.json 记录结果摘要
|
||||
|
||||
所有工作都在 results/<model_name>/ 目录内完成。
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import gen_input5 # noqa: E402 生成 .5 输入文件的模块
|
||||
import check_conv # noqa: E402 解析 fort.9 判断收敛的模块
|
||||
|
||||
TLUSTY = os.environ.get(
|
||||
"TLUSTY", "/home/dckj/program/tlusty/tl208-s54")
|
||||
TLUSTY_EXE = os.path.join(TLUSTY, "tlusty", "tlusty.exe") # Tlusty 可执行文件
|
||||
SYNSPEC_EXE = os.path.join(TLUSTY, "synspec", "synspec.exe") # Synspec 可执行文件
|
||||
DATA_DIR = os.path.join(TLUSTY, "data") # 原子数据目录
|
||||
|
||||
# 收敛链。每个阶段是一个 dict。第一阶段用 LTE=T(程序内部构造的灰度初始
|
||||
# 模型,无需 fort.8 种子)以获得一个物理上自洽的初始结构;后续阶段在前一
|
||||
# 阶段大气作为种子(fort.8)的条件下进行完整 NLTE 计算。
|
||||
#
|
||||
# 测试中得到的重要经验:
|
||||
# - LTE 灰度阶段的任务是产生一个*合法*的大气结构,而不是完全收敛;
|
||||
# 即便 CHMAX 没达到也接受其结果(require_converged=False)。在该阶段
|
||||
# 强求收敛纯属浪费时间,巨大的模型原子在 LTE 下几乎无法收敛。
|
||||
# - ITEK=100 会发散(过冲)。回退时 ITEK 上限设为 15。
|
||||
DEFAULT_CHAIN = [
|
||||
# 已验证的配方(tests/cno_sdspectrum,35000K 复现):
|
||||
# LTE 灰度 (T T, NITER=0) -> NLTE 连续谱 (nc, ilvlin=0) -> NLTE 谱线 (nl, ilvlin=100)
|
||||
#
|
||||
# 关键:不要在 nst 里设 CHMAX 或 ITEK —— 用 tlusty 默认值(CHMAX=0.001,
|
||||
# ITEK=4)。设 CHMAX=0.1(宽松)会让 nc 在真正收敛前就停止,给 nl
|
||||
# 留下一个坏种子导致发散。用默认 CHMAX=0.001 时 nc 能正常收敛
|
||||
# (约 11 次迭代),nl 只需约 1 次迭代即可收敛。
|
||||
#
|
||||
# .5 文件中 NFREAD=2000 -> 实际 5088 个频率点(速度快)。不要使用
|
||||
# NFREAD=50(会展开为 77695 个点,慢 15 倍且不稳定)。
|
||||
#
|
||||
# 阶段 1:LTE 灰度大气(T T)。NITER=0。
|
||||
{"label": "lte", "lte": "T", "ltgray": "T", "ilvlin": 0,
|
||||
"require_converged": False, "niter": 0},
|
||||
# 阶段 2:NLTE 连续谱(F F, ilvlin=0)。默认 CHMAX=0.001 强制真正
|
||||
# 收敛。NITER=50 给足迭代余量。
|
||||
{"label": "nc", "lte": "F", "ltgray": "F", "ilvlin": 0,
|
||||
"require_converged": False, "niter": 50},
|
||||
# 阶段 3:含谱线的完整 NLTE(F F, ilvlin=100)。从已收敛的 nc 种子出
|
||||
# 发,约 1 次迭代即可收敛。默认 CHMAX=0.001。
|
||||
{"label": "nl", "lte": "F", "ltgray": "F", "ilvlin": 100,
|
||||
"require_converged": True, "niter": 100},
|
||||
]
|
||||
# 若(必须收敛的)NLTE 阶段未收敛,则按下面这些更大的 ITEK 值重试。
|
||||
# 注意:不要用 ITEK=100 —— 对这些模型会发散。
|
||||
ITEK_FALLBACK = [15]
|
||||
# 每次 tlusty 运行的默认最大迭代数(nst 中的 NITER);各阶段可覆盖。
|
||||
DEFAULT_NITER = 50
|
||||
|
||||
|
||||
def log(msg):
|
||||
"""统一的日志输出函数(带 [run_one] 前缀,强制刷新)。"""
|
||||
print(" [run_one] " + msg, flush=True)
|
||||
|
||||
|
||||
def write_nst(path, chmax=None, itek=None, nd=50, vtb=2.0, niter=DEFAULT_NITER,
|
||||
orelax=None, idlte=None, iacc=None, ichang=None, icrsw=None,
|
||||
swpfac=None, swplim=None, swpinc=None):
|
||||
"""写入收敛链某阶段使用的 nst 非标准参数文件。
|
||||
|
||||
采用 tests/cno_sdspectrum 中验证过的参数集:
|
||||
NLAMBD=3, ISPODF=1, DDNU=50., CNU1=6., IELCOR=-1.
|
||||
CHMAX/ITEK 默认为 None(即用 tlusty 默认值 0.001/4)。显式指定这两个
|
||||
参数是可选的,且通常有害(CHMAX=0.1 会让 nc 提前停止;ITEK=3 相对默认
|
||||
值 4 会改变加速行为)。
|
||||
|
||||
高级选项(None = 使用 tlusty 默认值):
|
||||
ichang : 从一个模型原子不同的 fort.8 种子热启动时的布居数重映射
|
||||
模式。0=不变,1=新增能级置为 LTE,>1 从 fort.95 读取完整
|
||||
旧模型定义。
|
||||
icrsw : 碰撞-辐射切换开关(Hummer & Voels 1988)。
|
||||
0=关,>0=开。开启时需配合 swpfac/swplim/swpinc。
|
||||
"""
|
||||
parts = ["ND={}".format(nd), "NLAMBD=3", "VTB={:.0f}.".format(vtb),
|
||||
"ISPODF=1", "DDNU=50.", "CNU1=6."]
|
||||
if chmax is not None:
|
||||
parts.append("CHMAX={}".format(chmax))
|
||||
if itek is not None:
|
||||
parts.append("ITEK={}".format(itek))
|
||||
parts.append("NITER={}".format(niter))
|
||||
line1 = ",".join(parts)
|
||||
line2_parts = []
|
||||
if orelax is not None:
|
||||
line2_parts.append("ORELAX={}".format(orelax))
|
||||
if idlte is not None:
|
||||
line2_parts.append("IDLTE={}".format(idlte))
|
||||
if iacc is not None:
|
||||
line2_parts.append("IACC={}".format(iacc))
|
||||
if ichang is not None:
|
||||
line2_parts.append("ICHANG={}".format(ichang))
|
||||
if icrsw is not None:
|
||||
line2_parts.append("ICRSW={}".format(icrsw))
|
||||
if swpfac is not None:
|
||||
line2_parts.append("SWPFAC={}".format(swpfac))
|
||||
if swplim is not None:
|
||||
line2_parts.append("SWPLIM={}".format(swplim))
|
||||
if swpinc is not None:
|
||||
line2_parts.append("SWPINC={}".format(swpinc))
|
||||
line2_parts.append("IELCOR=-1")
|
||||
with open(path, "w") as f:
|
||||
f.write(line1 + "\n")
|
||||
f.write(",".join(line2_parts) + "\n")
|
||||
|
||||
|
||||
def run_tlusty(workdir, model_core, seed_atmos):
|
||||
"""在 workdir 中运行 tlusty.exe。
|
||||
|
||||
model_core : 模型名主干(.5 文件名为 <model_core>.5)
|
||||
seed_atmos : 作为 fort.8 种子的 .7 大气文件路径;None 表示从零开始
|
||||
返回 subprocess 的返回码。
|
||||
"""
|
||||
# 种子大气 -> fort.8
|
||||
fort8 = os.path.join(workdir, "fort.8")
|
||||
if os.path.exists(fort8):
|
||||
os.remove(fort8)
|
||||
if seed_atmos and os.path.exists(seed_atmos):
|
||||
shutil.copy(seed_atmos, fort8)
|
||||
# 删除残留的 fort.84(tlusty 内部的 nst 转储文件;若上一次运行的
|
||||
# NATOMS 不同,残留文件会在读取时触发 "Bad integer" 崩溃)
|
||||
fort84 = os.path.join(workdir, "fort.84")
|
||||
if os.path.exists(fort84):
|
||||
os.remove(fort84)
|
||||
# 链接数据目录
|
||||
link = os.path.join(workdir, "data")
|
||||
if os.path.islink(link) or os.path.exists(link):
|
||||
os.remove(link)
|
||||
os.symlink(DATA_DIR, link)
|
||||
# 运行
|
||||
cmd = [TLUSTY_EXE]
|
||||
with open(os.path.join(workdir, model_core + ".5")) as fin:
|
||||
with open(os.path.join(workdir, model_core + ".6"), "w") as fout:
|
||||
rc = subprocess.call(cmd, stdin=fin, stdout=fout,
|
||||
stderr=subprocess.STDOUT, cwd=workdir)
|
||||
# tlusty 会写出 fort.7(大气)、fort.9(收敛日志)、fort.69、fort.14
|
||||
return rc
|
||||
|
||||
|
||||
def run_synspec(workdir, model_core, fort55_lin, linelist):
|
||||
"""运行 synspec.exe 生成合成光谱。
|
||||
|
||||
model_core : 大气模型名主干;其 .7 文件即大气(被复制为 fort.8)
|
||||
fort55_lin : fort.55.lin 控制文件路径(波长窗口等)
|
||||
linelist : 谱线列表文件路径(被链接为 fort.19)
|
||||
返回 subprocess 的返回码。
|
||||
"""
|
||||
# 大气 -> fort.8(synspec 从 fort.8 读取大气)
|
||||
shutil.copy(os.path.join(workdir, model_core + ".7"),
|
||||
os.path.join(workdir, "fort.8"))
|
||||
# 链接数据目录
|
||||
link = os.path.join(workdir, "data")
|
||||
if os.path.islink(link) or os.path.exists(link):
|
||||
os.remove(link)
|
||||
os.symlink(DATA_DIR, link)
|
||||
# 链接控制文件 + 谱线列表
|
||||
for tgt, src in (("fort.55", fort55_lin), ("fort.19", linelist)):
|
||||
p = os.path.join(workdir, tgt)
|
||||
if os.path.islink(p) or os.path.exists(p):
|
||||
os.remove(p)
|
||||
os.symlink(os.path.abspath(src), p)
|
||||
# 运行;synspec 从 <model_core>.5 读取模型描述
|
||||
with open(os.path.join(workdir, model_core + ".5")) as fin:
|
||||
with open(os.path.join(workdir, model_core + ".log"), "w") as fout:
|
||||
rc = subprocess.call([SYNSPEC_EXE], stdin=fin, stdout=fout,
|
||||
stderr=subprocess.STDOUT, cwd=workdir)
|
||||
# 保存输出
|
||||
for src, ext in (("fort.7", "spec"), ("fort.17", "cont"),
|
||||
("fort.12", "iden")):
|
||||
sp = os.path.join(workdir, src)
|
||||
if os.path.exists(sp):
|
||||
shutil.copy(sp, os.path.join(workdir, model_core + "." + ext))
|
||||
return rc
|
||||
|
||||
|
||||
def run_model(teff, logg, loghe, logc, logn, logo,
|
||||
results_root, template, fort55_lin, linelist,
|
||||
chain=None, seed=None, timeout=1800):
|
||||
"""对单个参数点运行完整收敛链 + synspec。
|
||||
|
||||
返回一个 dict,并保存到 results/<name>/conv.json。
|
||||
"""
|
||||
chain = chain or DEFAULT_CHAIN
|
||||
name = gen_input5.model_name(teff, logg, loghe, logc, logn, logo)
|
||||
workdir = os.path.join(results_root, name)
|
||||
os.makedirs(workdir, exist_ok=True)
|
||||
|
||||
log("=== MODEL {} ===".format(name))
|
||||
t0 = time.time()
|
||||
|
||||
summary = {
|
||||
"name": name,
|
||||
"params": {"teff": teff, "logg": logg, "loghe": loghe,
|
||||
"logc": logc, "logn": logn, "logo": logo},
|
||||
"stages": [],
|
||||
"converged": False,
|
||||
"final_max_relc": None,
|
||||
"seed": seed,
|
||||
}
|
||||
|
||||
seed_atmos = seed # 第一阶段用作种子的 .7 路径;LTE 阶段为 None
|
||||
final_converged = False
|
||||
final_chmax = None
|
||||
final_max_relc = None
|
||||
|
||||
# ---- 逐阶段跑收敛链 ----
|
||||
for si, stage_def in enumerate(chain):
|
||||
chmax = stage_def.get("chmax") # None = tlusty 默认值 0.001
|
||||
itek0 = stage_def.get("itek") # None = tlusty 默认值 4
|
||||
lte = stage_def.get("lte", "F")
|
||||
ltgray = stage_def.get("ltgray", "F")
|
||||
label = stage_def.get("label", "stage{}".format(si + 1))
|
||||
require_conv = stage_def.get("require_converged", True)
|
||||
stage_niter = stage_def.get("niter", DEFAULT_NITER)
|
||||
stage_t0 = time.time() # 本阶段计时器
|
||||
stage = {"label": label, "chmax": chmax, "lte": lte,
|
||||
"itek_attempts": [], "converged": False}
|
||||
|
||||
# 写入本阶段的 .5(因 LTE/metals/ilvlin 不同需要重新生成)
|
||||
stage_metals = stage_def.get("metals", "cno")
|
||||
stage_ilvlin = stage_def.get("ilvlin", 100)
|
||||
input5 = gen_input5.make_input5(
|
||||
teff, logg, loghe, logc, logn, logo, template,
|
||||
lte=lte, ltgray=ltgray, metals=stage_metals, ilvlin=stage_ilvlin)
|
||||
with open(os.path.join(workdir, name + ".5"), "w") as f:
|
||||
f.write(input5)
|
||||
|
||||
# 要尝试的 ITEK 值:只有 require_converged=True 时才升级重试。
|
||||
# itek0 可能为 None(= 用 tlusty 默认值 4);此时只有一次"尝试"。
|
||||
if itek0 is None:
|
||||
itek_values = [None]
|
||||
else:
|
||||
itek_values = [itek0] + (ITEK_FALLBACK if require_conv else [])
|
||||
# NLTE 阶段的稳定化参数。默认全部关闭(None),因为实测表明
|
||||
# IDLTE=45 + IACC=disable 反而会导致 nc 阶段发散(之前看起来"有用"
|
||||
# 只是因为 nst 行截断 bug 静默丢弃了 IDLTE)。干净的三步配方
|
||||
# (lte->nc->nl)在不加这些参数时就能收敛。如果某个具体点需要,
|
||||
# 可以在 config.yaml 中通过 idlte/iacc/orelax 键显式开启。
|
||||
stab_idlte = stage_def.get("idlte")
|
||||
stab_iacc = stage_def.get("iacc")
|
||||
stab_ichang = stage_def.get("ichang")
|
||||
stab_icrsw = stage_def.get("icrsw")
|
||||
stab_swpfac = stage_def.get("swpfac")
|
||||
stab_swplim = stage_def.get("swplim")
|
||||
stab_swpinc = stage_def.get("swpinc")
|
||||
stage_seed = seed_atmos
|
||||
# ---- 在该阶段的 ITEK 值序列中依次尝试,直到收敛或耗尽 ----
|
||||
for it in itek_values:
|
||||
log("stage {}/{} [{}]: LTE={} LTGRAY={} CHMAX={} ITEK={} niter={} "
|
||||
"orelax={} idlte={} iacc={} ichang={} icrsw={}".format(
|
||||
si + 1, len(chain), label, lte, ltgray, chmax, it, stage_niter,
|
||||
stage_def.get("orelax"), stab_idlte, stab_iacc,
|
||||
stab_ichang, stab_icrsw))
|
||||
write_nst(os.path.join(workdir, "nst"), chmax, it,
|
||||
niter=stage_niter, orelax=stage_def.get("orelax"),
|
||||
idlte=stab_idlte, iacc=stab_iacc, ichang=stab_ichang,
|
||||
icrsw=stab_icrsw, swpfac=stab_swpfac,
|
||||
swplim=stab_swplim, swpinc=stab_swpinc)
|
||||
rc = run_tlusty(workdir, name, stage_seed)
|
||||
attempt = {"itek": it, "rc": rc}
|
||||
fort9 = os.path.join(workdir, "fort.9")
|
||||
fort7 = os.path.join(workdir, "fort.7")
|
||||
# fort.7(大气)是核心产物。fort.9(收敛日志)在 NITER=0
|
||||
# (灰度 LTE 启动)时不会生成,需要特别处理。
|
||||
if rc == 0 and os.path.exists(fort7):
|
||||
eff_chmax = chmax if chmax is not None else 0.001
|
||||
if os.path.exists(fort9):
|
||||
res = check_conv.check(fort9, eff_chmax)
|
||||
attempt.update(res)
|
||||
stagename = "{}_chmax{}_itek{}".format(label, eff_chmax, it)
|
||||
shutil.copy(fort9, os.path.join(
|
||||
workdir, name + "." + stagename.replace(".", "p") + ".9"))
|
||||
else:
|
||||
# NITER=0 灰度启动:无收敛日志,直接接受
|
||||
res = {"converged": True, "max_relc": 0.0,
|
||||
"note": "NITER=0 grey start (no iterations)"}
|
||||
attempt.update(res)
|
||||
# 把该次大气快照为下一阶段的种子
|
||||
seed_atmos = os.path.join(workdir, name + "." + label + ".7")
|
||||
shutil.copy(fort7, seed_atmos)
|
||||
if res["converged"]:
|
||||
stage["converged"] = True
|
||||
stage["final"] = attempt
|
||||
break
|
||||
elif not require_conv:
|
||||
# LTE/grey/nc 阶段:直接接受结构,继续下一阶段
|
||||
stage["converged"] = False
|
||||
stage["final"] = attempt
|
||||
stage["note"] = "accepted as seed (convergence not required)"
|
||||
break
|
||||
else:
|
||||
attempt["error"] = "tlusty rc={} or missing fort.7".format(rc)
|
||||
stage["itek_attempts"].append(attempt)
|
||||
# 记录本阶段表现最好的一次尝试
|
||||
if stage["itek_attempts"]:
|
||||
best = min(stage["itek_attempts"],
|
||||
key=lambda a: a.get("max_relc", 1e9))
|
||||
stage["best_max_relc"] = best.get("max_relc")
|
||||
stage["elapsed_sec"] = round(time.time() - stage_t0, 1)
|
||||
summary["stages"].append(stage)
|
||||
final_chmax = chmax
|
||||
final_converged = stage["converged"]
|
||||
if "final" in stage:
|
||||
final_max_relc = stage["final"].get("max_relc")
|
||||
|
||||
# 最终大气 = 最后阶段最好一次尝试产生的 .7
|
||||
final_7 = os.path.join(workdir, name + ".7")
|
||||
if seed_atmos and os.path.exists(seed_atmos):
|
||||
shutil.copy(seed_atmos, final_7)
|
||||
elif os.path.exists(os.path.join(workdir, "fort.7")):
|
||||
shutil.copy(os.path.join(workdir, "fort.7"), final_7)
|
||||
|
||||
summary["converged"] = bool(final_converged)
|
||||
summary["final_max_relc"] = final_max_relc
|
||||
summary["final_chmax"] = final_chmax
|
||||
|
||||
# 检测虚假收敛:大气里全是 NaN(例如 nc 发散后 nl 因 0/0 而以 max_relc=0
|
||||
# "收敛")。标记并作废此类结果。
|
||||
atmos_has_nan = False
|
||||
if os.path.exists(final_7):
|
||||
try:
|
||||
with open(final_7) as f:
|
||||
atmos_has_nan = sum(
|
||||
1 for l in f if "nan" in l.lower()) > len(open(final_7).readlines()) * 0.1
|
||||
except Exception:
|
||||
pass
|
||||
summary["atmosphere_has_nan"] = atmos_has_nan
|
||||
if atmos_has_nan:
|
||||
summary["converged"] = False
|
||||
summary["note"] = ("invalidated: atmosphere contains >10% NaN lines "
|
||||
"(likely nc-stage divergence -> fake nl convergence)")
|
||||
|
||||
# 4. synspec(仅当得到了大气时才跑)
|
||||
if os.path.exists(final_7):
|
||||
log("running synspec...")
|
||||
syn_t0 = time.time()
|
||||
try:
|
||||
rc = run_synspec(workdir, name, fort55_lin, linelist)
|
||||
summary["synspec_rc"] = rc
|
||||
except Exception as e:
|
||||
summary["synspec_error"] = str(e)
|
||||
summary["synspec_sec"] = round(time.time() - syn_t0, 1)
|
||||
else:
|
||||
summary["synspec_error"] = "no atmosphere produced"
|
||||
|
||||
summary["elapsed_sec"] = round(time.time() - t0, 1)
|
||||
with open(os.path.join(workdir, "conv.json"), "w") as f:
|
||||
json.dump(summary, f, indent=2)
|
||||
log("DONE {} (converged={}, {:.0f}s)".format(
|
||||
name, summary["converged"], summary["elapsed_sec"]))
|
||||
return summary
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:解析参数后调用 run_model。"""
|
||||
ap = argparse.ArgumentParser(
|
||||
description="Run one H/He/C/N/O NLTE model (chain convergence + synspec)")
|
||||
ap.add_argument("--teff", type=float, required=True)
|
||||
ap.add_argument("--logg", type=float, required=True)
|
||||
ap.add_argument("--loghe", type=float, required=True)
|
||||
ap.add_argument("--logc", type=float, required=True)
|
||||
ap.add_argument("--logn", type=float, required=True)
|
||||
ap.add_argument("--logo", type=float, required=True)
|
||||
ap.add_argument("--results", default=None,
|
||||
help="results root dir (default: ../results)")
|
||||
ap.add_argument("--template", default=None)
|
||||
ap.add_argument("--fort55", default=None, help="fort.55.lin control file")
|
||||
ap.add_argument("--linelist", default=None, help="line list (fort.19)")
|
||||
ap.add_argument("--seed", default=None, help="seed atmosphere .7 file")
|
||||
ap.add_argument("--timeout", type=int, default=1800)
|
||||
args = ap.parse_args()
|
||||
|
||||
here = os.path.dirname(os.path.abspath(__file__))
|
||||
grid = os.path.dirname(here)
|
||||
results = args.results or os.path.join(grid, "results")
|
||||
template = args.template or os.path.join(grid, "templates", "cno_atmos.5.tpl")
|
||||
fort55 = args.fort55 or os.path.join(grid, "templates", "fort.55.lin")
|
||||
linelist = args.linelist or os.path.join(DATA_DIR, "gfVIS99.dat")
|
||||
|
||||
run_model(args.teff, args.logg, args.loghe, args.logc, args.logn,
|
||||
args.logo, results, template, fort55, linelist,
|
||||
seed=args.seed, timeout=args.timeout)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""针对失败的高温 He-poor CNO 模型进行的"种子步进"实验。
|
||||
|
||||
发现(边界测试 2026-07-21):
|
||||
- 80000/6.5/+2/-4(富 He)在 nc 阶段干净收敛(15 次迭代)
|
||||
- 80000/6.5/-4/-4(贫 He)在 nc 阶段发散(第 2 次迭代 relc=1e18)
|
||||
- 两者 Teff/logg/logCNO 完全相同,只有 logHe 不同。
|
||||
|
||||
根因:当 He 丰度极小、金属主导不透明度时,LTE 灰度冷启动的初始猜测离
|
||||
真实 NLTE 解太远。富 He 模型的不透明度由 He 主导、稳定;贫 He 模型的
|
||||
不透明度由 CNO 主导,线性化过程会震荡。
|
||||
|
||||
源码分析证实(tlusty208.f:578-582):
|
||||
- LTGRAY=T -> CALL LTEGR (灰度冷启动,忽略 fort.8)
|
||||
- LTGRAY=F -> CALL INPMOD (从 fort.8 热启动)
|
||||
- ICHANG=1 -> 当种子的模型原子不同时,新增能级被强制设为 LTE
|
||||
|
||||
修复方案(最终正确理解的 Peter Nemeth 建议):
|
||||
从已收敛的富 He 大气热启动这个失败的贫 He 模型,使用
|
||||
LTGRAY=F + ICHANG=1 重映射布居数。Tlusty 会从一个物理上接近的起点
|
||||
松弛 He/H 比例和 CNO 电离平衡,而不是从灰度猜测出发。
|
||||
|
||||
本脚本运行单个种子步进模型,并与 results/ 中已有的冷启动结果对比。
|
||||
"""
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
import gen_input5 # noqa: E402
|
||||
import run_one # noqa: E402
|
||||
|
||||
TLUSTY = os.environ.get("TLUSTY", "/home/dckj/program/tlusty/tl208-s54")
|
||||
|
||||
|
||||
# 种子步进链:跳过 LTE 灰度冷启动,直接从种子热启动。
|
||||
# ICHANG 默认为 0(不重映射)——只有当种子与目标的模型原子不同时才需要
|
||||
# 非 0 值。本处模型原子完全一致(同为 H/He/CNO 设置),只有
|
||||
# Teff/logg/丰度不同,所以 ICHANG=0 是正确的。
|
||||
#
|
||||
# 注意:ICRSW(Hummer & Voels 1988 的碰撞-辐射切换)经测试在 tlusty208.f
|
||||
# 中是死代码 —— SWITCH 子程序定义在第 4556 行,但源码中任何地方都未被
|
||||
# 调用。CRSW 保持默认值 1.0,因此第 6343-6344 行等处的速率乘法实际上
|
||||
# 没有任何作用。不要依赖 ICRSW 来稳定。请改用 ORELAX(在 tlusty208.f
|
||||
# 第 14647、14996 行实际生效)—— 不过即便 ORELAX=0.5 在 80K + 贫 He 的
|
||||
# 极端丰度跳跃下也会失败。
|
||||
SEED_STEP_CHAIN = [
|
||||
# 阶段 1:从种子大气热启动 NLTE 连续谱。LTGRAY=F 会读取 fort.8;
|
||||
# 种子的布居数提供了一个物理上接近的初始猜测。
|
||||
{"label": "seed_nc", "lte": "F", "ltgray": "F", "ilvlin": 0,
|
||||
"ichang": 0, "require_converged": False, "niter": 80},
|
||||
# 阶段 2:从种子收敛的大气出发,进行含谱线的完整 NLTE 计算。
|
||||
{"label": "nl", "lte": "F", "ltgray": "F", "ilvlin": 100,
|
||||
"ichang": 0, "require_converged": True, "niter": 100},
|
||||
]
|
||||
|
||||
# 仅为向后兼容保留,实际并不会启用 ICRSW(死代码)。请改用 SEED_STEP_CHAIN。
|
||||
SEED_STEP_CHAIN_ICRSW = SEED_STEP_CHAIN
|
||||
|
||||
|
||||
def main():
|
||||
"""命令行入口:运行一次种子步进收敛实验。"""
|
||||
ap = argparse.ArgumentParser(
|
||||
description="Seed-stepping convergence experiment")
|
||||
ap.add_argument("--teff", type=float, required=True)
|
||||
ap.add_argument("--logg", type=float, required=True)
|
||||
ap.add_argument("--loghe", type=float, required=True)
|
||||
ap.add_argument("--logc", type=float, required=True)
|
||||
ap.add_argument("--logn", type=float, required=True)
|
||||
ap.add_argument("--logo", type=float, required=True)
|
||||
ap.add_argument("--seed", required=True,
|
||||
help="path to seed atmosphere .7 (e.g. converged He-rich)")
|
||||
ap.add_argument("--icrsw", action="store_true",
|
||||
help="use ICRSW (Hummer & Voels switching) for hard jumps")
|
||||
ap.add_argument("--results", default=None)
|
||||
ap.add_argument("--template", default=None)
|
||||
ap.add_argument("--fort55", default=None)
|
||||
ap.add_argument("--linelist", default=None)
|
||||
args = ap.parse_args()
|
||||
|
||||
grid = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
results = args.results or os.path.join(grid, "results", "seed_step")
|
||||
os.makedirs(results, exist_ok=True)
|
||||
template = args.template or os.path.join(grid, "templates", "cno_atmos.5.tpl")
|
||||
fort55 = args.fort55 or os.path.join(grid, "templates", "fort.55.lin")
|
||||
linelist = args.linelist or os.path.join(
|
||||
TLUSTY, "data", "gfVIS99.dat")
|
||||
|
||||
# 打印实验信息:目标参数 + 种子来源 + 使用的链
|
||||
print("=" * 60)
|
||||
print("SEED-STEPPING EXPERIMENT")
|
||||
print("=" * 60)
|
||||
print("target: t{}_g{}_he{}_c{}_n{}_o{}".format(
|
||||
int(args.teff), args.logg, args.loghe, args.logc, args.logn, args.logo))
|
||||
print("seed: {}".format(args.seed))
|
||||
chain = SEED_STEP_CHAIN_ICRSW if args.icrsw else SEED_STEP_CHAIN
|
||||
print("chain: LTGRAY=F + ICHANG=0 hot-start -> nl" +
|
||||
(" [ICRSW ON]" if args.icrsw else ""))
|
||||
print("")
|
||||
|
||||
run_one.run_model(
|
||||
args.teff, args.logg, args.loghe, args.logc, args.logn, args.logo,
|
||||
results, template, fort55, linelist,
|
||||
chain=chain, seed=args.seed)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""汇总所有边界测试的结果。"""
|
||||
import json
|
||||
import os
|
||||
|
||||
# 结果根目录(相对于本仓库根)。COLD_START_TESTS 用的目录。
|
||||
RESULTS = "cno_grid/results"
|
||||
# seed_step 实验单独存放在子目录中
|
||||
SEED = os.path.join(RESULTS, "seed_step")
|
||||
|
||||
# 冷启动测试点列表:(展示标签, 模型目录名, 简短参数描述)
|
||||
COLD_START_TESTS = [
|
||||
("20k_he2_cno-1", "t20000_g5.0_he2_c-1_n-1_o-1", "20K/5.0/+2/-1"),
|
||||
("20k_he2_cno-4", "t20000_g5.0_he2_c-4_n-4_o-4", "20K/5.0/+2/-4"),
|
||||
("40k_he0_cno-4", "t40000_g5.5_he0_c-4_n-4_o-4", "40K/5.5/0/-4"),
|
||||
("60k_he0_cno-1", "t60000_g6.0_he0_c-1_n-1_o-1", "60K/6.0/0/-1"),
|
||||
("80k_he-4_cno-1", "t80000_g6.5_he-4_c-1_n-1_o-1", "80K/6.5/-4/-1"),
|
||||
("80k_he-4_cno-4", "t80000_g6.5_he-4_c-4_n-4_o-4", "80K/6.5/-4/-4"),
|
||||
("80k_he2_cno-1", "t80000_g6.5_he2_c-1_n-1_o-1", "80K/6.5/+2/-1"),
|
||||
("80k_he2_cno-4", "t80000_g6.5_he2_c-4_n-4_o-4", "80K/6.5/+2/-4"),
|
||||
]
|
||||
|
||||
# 种子步进测试点列表:(模型目录名, 使用的种子描述, 子目录位置)
|
||||
SEED_STEP_TESTS = [
|
||||
("t80000_g6.5_he-4_c-4_n-4_o-4", "80K He-rich cno-4", "seed_step"),
|
||||
("t80000_g6.5_he2_c-1_n-1_o-1", "80K He-rich cno-4", "seed_step"),
|
||||
("t80000_g6.5_he-4_c-2_n-2_o-2", "80K He-poor cno-4", "seed_step"),
|
||||
]
|
||||
|
||||
|
||||
def fmt(dname, location=RESULTS):
|
||||
"""把某个模型目录的 conv.json 摘要为一行字符串。
|
||||
|
||||
包含:是否收敛(✓/✗)、是否含 NaN、最终 max_relc、用时。
|
||||
若 conv.json 不存在,返回占位提示。
|
||||
"""
|
||||
p = os.path.join(location, dname, "conv.json")
|
||||
if not os.path.exists(p):
|
||||
return " (no conv.json)"
|
||||
j = json.load(open(p))
|
||||
conv = "✓" if j["converged"] else "✗"
|
||||
nan = " NaN" if j.get("atmosphere_has_nan") else ""
|
||||
relc = j.get("final_max_relc")
|
||||
relc_s = "{:.2e}".format(relc) if isinstance(relc, (int, float)) else str(relc)
|
||||
t = j.get("elapsed_sec", "?")
|
||||
return f" conv={conv}{nan} relc={relc_s:<11} t={t}s"
|
||||
|
||||
|
||||
# ---- 打印冷启动结果 ----
|
||||
print("=" * 70)
|
||||
print("COLD-START RESULTS (run_one.py: LTE grey -> nc -> nl)")
|
||||
print("=" * 70)
|
||||
for tag, dname, params in COLD_START_TESTS:
|
||||
print(f" {tag:<18} {params:<15} {fmt(dname)}")
|
||||
|
||||
# ---- 打印种子步进结果 ----
|
||||
print()
|
||||
print("=" * 70)
|
||||
print("SEED-STEP RESULTS (seed_step.py: hot-start from neighbor)")
|
||||
print("=" * 70)
|
||||
for dname, seed, loc in SEED_STEP_TESTS:
|
||||
print(f" {dname:<32} seed={seed:<22} {fmt(dname, os.path.join(RESULTS, loc))}")
|
||||
@@ -0,0 +1,50 @@
|
||||
{TEFF} {LOGG} ! TEFF, GRAV
|
||||
{LTE} {LTGRAY} ! LTE, LTGRAY
|
||||
'nst' ! name of file containing non-standard flags
|
||||
*-----------------------------------------------------------------
|
||||
* frequencies
|
||||
2000 ! NFREAD
|
||||
*-----------------------------------------------------------------
|
||||
* data for atoms
|
||||
* NATOMS = 8: 1=H 2=He 3-5=empty 6=C 7=N 8=O
|
||||
* mode: 0=implicit LTE background, 1=explicit LTE, 2=explicit NLTE
|
||||
* abn: number density ratio n(X)/n(H); 0 means adopted solar abundance
|
||||
8 ! NATOMS
|
||||
* mode abn modpf
|
||||
2 {ABN_H} 0 ! H
|
||||
2 {ABN_HE} 0 ! He
|
||||
0 0. 0
|
||||
0 0. 0
|
||||
0 0. 0
|
||||
2 {ABN_C} 0 ! C
|
||||
2 {ABN_N} 0 ! N
|
||||
2 {ABN_O} 0 ! O
|
||||
*-----------------------------------------------------------------
|
||||
* data for ions
|
||||
*iat iz nlevs ilast ilvlin nonstd typion filei
|
||||
*
|
||||
1 0 9 0 0 0 ' H 1' 'data/h1.dat'
|
||||
1 1 1 1 0 0 ' H 2' ' '
|
||||
2 0 24 0 0 0 'He 1' 'data/he1.dat'
|
||||
2 1 20 0 0 0 'He 2' 'data/he2.dat'
|
||||
2 2 1 1 0 0 'He 3' ' '
|
||||
6 0 40 0 0 0 ' C 1' 'data/c1.dat'
|
||||
6 1 22 0 0 0 ' C 2' 'data/c2.dat'
|
||||
6 2 46 0 0 0 ' C 3' 'data/c3_34+12lev.dat'
|
||||
6 3 25 0 0 0 ' C 4' 'data/c4.dat'
|
||||
6 4 1 1 0 0 ' C 5' ' '
|
||||
7 0 34 0 0 0 ' N 1' 'data/n1.dat'
|
||||
7 1 42 0 0 0 ' N 2' 'data/n2_32+10lev.dat'
|
||||
7 2 32 0 0 0 ' N 3' 'data/n3.dat'
|
||||
7 3 48 0 0 0 ' N 4' 'data/n4_34+14lev.dat'
|
||||
7 4 16 0 0 0 ' N 5' 'data/n5.dat'
|
||||
7 5 1 1 0 0 ' N 6' ' '
|
||||
8 0 33 0 0 0 ' O 1' 'data/o1_23+10lev.dat'
|
||||
8 1 48 0 0 0 ' O 2' 'data/o2_36+12lev.dat'
|
||||
8 2 41 0 0 0 ' O 3' 'data/o3_28+13lev.dat'
|
||||
8 3 39 0 0 0 ' O 4' 'data/o4.dat'
|
||||
8 4 6 0 0 0 ' O 5' 'data/o5.dat'
|
||||
8 5 1 1 0 0 ' O 6' ' '
|
||||
0 0 0 -1 0 0 ' ' ' '
|
||||
*
|
||||
* end
|
||||
@@ -0,0 +1 @@
|
||||
ND=50,VTB=2.,CHMAX=0.001
|
||||
Reference in New Issue
Block a user