Metadata-Version: 2.5
Name: flash-sim
Version: 0.2.1
Summary: FLASH plasma simulation Python interface - third-party wrapper and workflow toolkit for FLASH 4.8 radiation-hydrodynamics code. NOT affiliated with the Flash Center for Computational Science. FLASH must be obtained separately from flash.rochester.edu.
Project-URL: Homepage, https://gitee.com/physimx/flash
Project-URL: Repository, https://gitee.com/physimx/flash
Project-URL: Issues, https://gitee.com/physimx/flash/issues
Project-URL: GitHub, https://github.com/QuincyHoward/flash
Project-URL: GitHub-Issues, https://github.com/QuincyHoward/flash/issues
Project-URL: Changelog, https://github.com/QuincyHoward/flash/releases
Author: PhySimX Contributors
Author-email: Quincy Howard <quincy.hd@foxmail.com>
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: flash,high-energy-density,physics,plasma,simulation
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Fortran
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Requires-Dist: cryptography>=41.0
Requires-Dist: numpy>=1.24
Provides-Extra: dev
Requires-Dist: black>=23.0; extra == 'dev'
Requires-Dist: build>=1.0; extra == 'dev'
Requires-Dist: pandas>=2.0; extra == 'dev'
Requires-Dist: pytest-cov>=4.0; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: ruff>=0.1.0; extra == 'dev'
Requires-Dist: scipy>=1.10; extra == 'dev'
Requires-Dist: twine>=5.0; extra == 'dev'
Provides-Extra: full
Requires-Dist: h5py>=3.8; extra == 'full'
Requires-Dist: matplotlib>=3.7; extra == 'full'
Requires-Dist: pandas>=2.0; extra == 'full'
Requires-Dist: yt>=4.1; extra == 'full'
Provides-Extra: plasmapy-dev
Requires-Dist: codespell>=2.3; extra == 'plasmapy-dev'
Requires-Dist: pytest-cov>=7.0; extra == 'plasmapy-dev'
Requires-Dist: pytest-xdist>=3.8; extra == 'plasmapy-dev'
Requires-Dist: pytest>=9.0; extra == 'plasmapy-dev'
Description-Content-Type: text/markdown

# flash-sim — FLASH 等离子体辐射流体力学仿真 Python 接口

[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![FLASH: Separate License](https://img.shields.io/badge/FLASH-Separate_License-orange.svg)](https://flash.rochester.edu)
[![PyPI: flash-sim](https://img.shields.io/badge/PyPI-flash--sim-blue.svg)](https://pypi.org/project/flash-sim/)
[![Gitee](https://img.shields.io/badge/Gitee-physimx%2Fflash-C71D1D.svg)](https://gitee.com/physimx/flash)
[![GitHub](https://img.shields.io/badge/GitHub-QuincyHoward%2Fflash-181717.svg)](https://github.com/QuincyHoward/flash)

> **版本维护策略**: 以 Gitee 分支为开发主仓库 ,
> PyPI 按阶段发布更新。文档中**不标注具体版本号** ,
> 当前版本以 `pyproject.toml` 为准, 历史版本见 `git tag -l` 与 PyPI Releases。

**flash-sim** 是 [FLASH](https://flash.rochester.edu/) 高能量密度物理 (HEDP) 仿真代码的全功能 Python 封装。提供**场景系统**（即插即用仿真入口）、参数文件生成、多环境运行管理、HDF5 输出分析与自适应可视化的一站式工作流。


## 仓库地址 (Repository)

本项目在 Gitee 与 GitHub **双平台同步维护**；国内用户建议使用 Gitee，海外用户可使用 GitHub 镜像。
| 操作 | 命令 |
|------|------|
| **在线浏览（Gitee）** | https://gitee.com/physimx/flash （Code / Issues / Releases 页签） |
| **在线浏览（GitHub）** | https://github.com/QuincyHoward/flash （Code / Issues / Releases 页签） |
| **HTTPS 克隆（Gitee）** | `git clone https://gitee.com/physimx/flash.git`<br>`git clone --depth 1 https://gitee.com/physimx/flash.git` |
| **HTTPS 克隆（GitHub）** | `git clone https://github.com/QuincyHoward/flash.git`<br>`git clone --depth 1 https://github.com/QuincyHoward/flash.git` |
| **PyPI 版本（可能滞后）** | `pip install flash-sim` |
| **版本标签** | 以 `git tag -l` 查看全部（PyPI 按阶段更新，见上方维护策略） |
| **问题反馈** | 通过 Gitee 或 GitHub Issues 提交（登录后新建 Issue） |

**说明**：`--depth 1` 为浅克隆，只拉取最新一次提交，不包含完整历史，可显著减小下载体积与磁盘占用；代价是无法查看、切换历史提交。需要完整历史时，在浅克隆仓库内执行 `git fetch --unshallow` 即可恢复。

> 发布包已通过全局测试 (**436 passed / 2 skipped**: framework 293 / input_gen 86 / output_pro 57) ；
> 版权合规检查详见 [许可](#许可) 与 [NOTICE](NOTICE)；
> 离线部署自检另计 **183 项** (`deploy/test_offline_install.py`)；
> 35 个注册场景已通过本地 WSL 极短端到端验证（`tmax=1e-11`，详见 `test/reports/scene_verify_20261030.md`）。

---

## 目录

- [概述](#概述)
- [核心特性](#核心特性)
- [模块架构](#模块架构)
- [安装](#安装)
- [快速开始](#快速开始)
- [API 速览](#api-速览)
- [典型工作流](#典型工作流)
- [运行环境](#运行环境)
- [开发指南](#开发指南)
- [文档索引](#文档索引)
- [版本更新日志](PhySimX_flash_CHANGELOG.md)
- [重要依赖材料清单](#重要依赖材料清单gitignore-忽略的私有材料)
- [许可](#许可)

---

## 概述


**FLASH** 是芝加哥大学 Flash Center 开发的多物理、多维度自适应网格 (AMR) 流体力学仿真框架，在激光聚变 (ICF)、天体物理及实验室天体物理等领域有着广泛应用。

**flash-sim** 是一款专为 FLASH 设计的 Python 接口与自动化工作流工具，旨在简化仿真配置、任务调度及后处理流程，显著提升科研迭代效率。该工具作为 FLASH 的扩展组件，需配合 FLASH 仿真引擎使用。FLASH 仿真引擎需从 flash.rochester.edu 单独获取并遵循其许可协议。

`flash-sim` 封装了从仿真配置、编译运行到结果分析的完整流程：

```
物理参数设计 → .par 文件生成 → FLASH 编译运行
                                    ↓
                              HDF5 输出处理
                                    ↓
               自适应可视化 (1D/2D/3D) + 物理量分析
```
`flash-sim`使用Agent生成、使用、维护，适用于这种流程辅助，在第一次全流程构造、或使用`output_pro`进行数据分析等专业决策时，请仔细核对。

可作为独立 Python 包使用，便于用户直接调用API。

---

## 核心特性

### 场景系统 (`scenarios/`)

| 模块 | 功能 |
|------|------|
| `scenarios/core/engine/base.py` | `SimulationScenario` 数据类 — 场景声明式配置 |
| `scenarios/core/scene_reg/registry.py` | 场景注册表 — `get_scenario()`（name 优先→别名回退） |
| `scenarios/core/scene_reg/discovery.py` | **约定式场景发现器** — `scene.json` 零注册接入（新增场景 = 建目录 + 落 manifest，不改框架） |
| `scenarios/core/entry/cli.py` | **统一 CLI** — `python -m flash.scenarios list/run/submit`（平台自适应 `--mode auto`，支持 `--tmax` 极短验证） |
| `simulator.py` | `FlashSimulatorEngine` 统一引擎 — 集成 WSL 执行 + chk 收集 + 插值 + 输出 |

**即插即用**:

```python
from flash.scenarios.core.registry import get_scenario
from flash.scenarios.core.simulator import FlashSimulatorEngine

engine = FlashSimulatorEngine(get_scenario("thin_layer_sandwich_si"))
output = engine.run()  # 自动编译→运行→插值→输出
```

**输入文件生成机制（重要）**: 场景的 FLASH 源文件目录 `flash_input/`
（`.par` / `Config` / `Makefile` / `*.F90` / EOS `.cn4`）**不随仓库分发**
（.gitignore 排除，同 output_pro 的 inputfiles/ 模式）。引擎
`FlashSimulatorEngine.run()` 运行前调用场景 `ensure_sim_input()` 自动补齐
（ch_center 由 `gen_flash_inputs.py` 经 input_gen 包生成），干净克隆/发布环境
开箱即用；也可单独运行 `python flash/scenarios/public/center_evolution/ch_center/gen_flash_inputs.py`
（`--check` 仅检查 / `--force` 强制重生成）。

详见 [`scenarios/README.md`](flash/scenarios/README.md)。

**参考场景文档**:

- [`center_evolution/ch_center/`](flash/scenarios/public/center_evolution/ch_center/) — CH 靶中心演化：物理设置、五种执行模式使用指南与参数切换、输入重建（[README](flash/scenarios/public/center_evolution/ch_center/README.md)）
- [`center_evolution/ch_center/modes_test/`](flash/scenarios/public/center_evolution/ch_center/modes_test/) — 多执行模式测试框架：五路径（win-wsl / wsl-wsl / win-hpc / wsl-hpc / hpc-insitu）同算例 dens/nele 对比（[README](flash/scenarios/public/center_evolution/ch_center/modes_test/README.md)）

**公开场景统一入口**（三个场景，缺省 `--mode auto` 平台自适应）：

```bash
python -m flash.scenarios.core.entry.cli list                          # 列出场景与允许模式
python -m flash.scenarios.core.entry.cli run ch_center                # 缺省 auto
python -m flash.scenarios.core.entry.cli run grad_dens_sandwich --tmax 1e-13
python -m flash.scenarios.core.entry.cli run thin_layer_sandwich_si
python flash/scenarios/public/short_validation.py          # 三场景一键极短验证 (tmax=1e-13 s)
```

### 仿真输入生成 (`input_gen/`)

| 模块 | 功能 |
|------|------|
| `gen_par/` | 参数化 `.par` 文件生成，支持多维度(1D/2D/3D)，默认值中心化 (`defaults.py`) |
| `gen_config/` | FLASH `Config` 文件生成，模块依赖自动管理 |
| `gen_makefile/` | `Makefile` 生成，含 MPI/HDF5/HYPRE 路径注入 |
| `gen_sim_data/` | `Simulation_data.F90` — 全局仿真数据声明 |
| `gen_sim_init/` | `Simulation_init.F90` — 运行时参数读取和初始化 |
| `gen_sim_initblock/` | `Simulation_initBlock.F90` — 空间网格和物质分配（1D/2D/3D 对称域） |
| `gen_eos_op/` | IONMIX4 格式 `.cn4` EOS/不透明度表生成与复制 |
| `gen_shell_script/` | 平台感知的运行脚本生成（本地 WSL / 超算 SLURM） |
| `gen_checker/` | 依赖检查 + 脉冲/密度/射线可视化诊断 |
| `gen_Grid_markRefineDerefine/` | FLASH 网格细化/粗化 Fortran 生成器 |

### 运行管理 (`flash_run/`)

| 模块 | 功能 |
|------|------|
| `execution.py` | **唯一执行契约**：四种执行目标（local / wsl / hpc-remote / hpc-insitu）平台自适应判定 + 场景策略校验 |
| `env/` | 多环境管理（本地 WSL / SSH 超算），维度感知资源配置，venv 路径单一事实源 |
| `modes/` | 运行模式执行体（`run_wsl` / `HpcRunner` / `run_insitu`），自 scenarios 迁入的唯一归属（兼容壳现为 `scenarios/core/runner.py`） |
| `remote/` | 远程部署：唯一 SSH（`RemoteSession`）、统一命令面（executors）、SLURM 下沉（slurm_control）、chk-only 回传策略（fetch_policy） |
| `hpc.py` | 超算技能统一 CLI（本地驱动 / 登录节点两侧可调） |

> 模块总览、目标判定表、用户名规范与工程铁律见 [`flash/flash_run/README.md`](flash/flash_run/README.md)（2026-10-24 合并重写，唯一入口文档）。

### 输出处理 (`output_pro/`)

| 模块 | 功能 |
|------|------|
| `hdf5pro/` | 纯 h5py 底层 HDF5 读取，自动检测 1D/2D/3D，AMR 块结构解析；内含 `DataCalculator` 派生变量计算与 `extract_var_yt_style` 坐标重建 |
| `loader/` | `FlashDataLoader` + `FlashDataContainer` 结构化数据加载（自动维度检测、派生变量、全局坐标） |
| `plotter/` | `FlashPlotter` 自适应维度可视化（1D 线图 / 2D 伪彩 / 3D 切片），AMR 网格绘图 |
| `parallel.py` | 多文件 / 多变量 / 多文件夹并行加载与插值加速 |
| `plasmapy_bridge.py` | **[PlasmaPy](https://github.com/PlasmaPy/PlasmaPy) 物理量适配层（2026.10 新增）**：把 FLASH 网格量转 astropy `Quantity`，提供库仑对数 lnΛ、Debye 长度 λ_D、Spitzer/Braginskii 电子热导率 κ_e、电子平均自由程与 Knudsen 数 K_n=λ_mfp/L_Te、量子简并参数 Θ_e、离子耦合参数 Γ、Saha 电离度 Z̄、临界密度面 n_c(0.351μm) 等带单位诊断量；`HAS_PLASMAPY=False` 时优雅降级（其余功能不受影响）。源码以 **vendor 快照**随仓库分发（`output_pro/PlasmaPy/src/PlasmaPy`，BSD-3），editable 安装见 `output_pro/PlasmaPy/install_editable.py`（win/wsl），HPC 走离线 wheel（见 `DEPENDENCIES.md`） |

### 仿真驱动 (`interface.py`)

`FlashSimulator` 类提供统一仿真接口：
- **Mock 模式**：基于 Planck 辐射 / Saha 电离闭合公式的确定性模拟，适合 pipeline 开发和测试
- **Real 模式**：调用本地或远程 FLASH 二进制，解析 HDF5 输出

### 完整 Demo 套件 (`scenarios/flash_demo/`)

- `hello_flash/` — 零依赖快速上手包（一键安装 + 运行 + 分析）
- `LaserSlab1d/` — 1D 激光烧蚀参考仿真文件（含 Config / .par / .cn4）
- `new_struture/` — 自定义对称域 1D 仿真 + CH 靶中心物理量时域分析
- `laserslab1d_local_demo.py` / `laserslab1d_supercomputer_demo.py` — 本地/超算一键运行
- `laserslab1d_hpc_demo_batch.py` — 多功率因子批量仿真工作流

---

## 模块架构

> 本节从**分层架构**、**双模式运行机制**、**端到端数据流**三个角度，说明 `flash` 包如何把"物理参数 → FLASH 运行 → HDF5 输出 → 可视化/分析"串成一条可复用的管线。读完后即可按图索骥定位任一功能的代码位置。

### 分层架构总览

```
┌──────────────────────────────────────────────────────────────────────────┐
│ 接口/适配层   interface.py (FlashSimulator: mock/real) · __init__.py       │
│               └─ 契约来源：内置 _core/（dataclass schema，自包含）         │
├──────────────────────────────────────────────────────────────────────────┤
│ 输入生成层   input_gen/   gen_par · gen_config · gen_makefile ·            │
│               gen_sim_data · gen_sim_init · gen_sim_initblock ·           │
│               gen_eos_op · gen_shell_script · gen_Grid_markRefineDerefine  │
├──────────────────────────────────────────────────────────────────────────┤
│ 仿真执行层   scenarios/ (base · registry · simulator · 物理场景)           │
│               flash_run/ (env 环境管理 · remote 远程部署) · _core/config.py         │
├──────────────────────────────────────────────────────────────────────────┤
│ 输出处理层   output_pro/   hdf5pro → loader → plotter         │
│               (+ parallel 并行加速 + plasmapy_bridge 物理量)  │
├──────────────────────────────────────────────────────────────────────────┤
│ 核心抽象层   _core/   interface/BaseSimulator · schema 数据契约 ·          │
│               registry · credentials(加密凭据)                             │
└──────────────────────────────────────────────────────────────────────────┘
        支撑模块: scenarios/flash_demo/ (示例) · docs/ (文档) · scripts/ (工具) · test/ (测试)
```

各层职责：

| 层 | 关键模块/类 | 职责 |
|----|------------|------|
| 接口/适配 | `interface.py::FlashSimulator`, `flash/__init__.py` | 对外统一入口。`mock` 模式用 Planck/Saha 闭式公式产出确定性假数据；`real` 模式调用 FLASH 二进制 |
| 核心抽象 | `_core/interface.py::BaseSimulator`, `_core/schema.py` | 定义 `capability()` / `simulate()` 契约与 `SimulationRequest` / `SimulationResult` 数据结构；凭据经 `credentials.py` (Fernet) 加密 |
| 输入生成 | `input_gen/*/generator.py` | 把结构化参数翻译成 FLASH 需要的 `.par`、Fortran 源、`Config`、`Makefile`、`.cn4` 表、运行脚本 |
| 仿真执行 | `scenarios/core/engine/simulator.py::FlashSimulatorEngine`, `flash_run/env`, `flash_run/remote` | 编排"编译 → 运行 → 采集 → 插值 → 保存"；管理本地 WSL 与超算 SSH/SLURM 环境 |
| 输出处理 | `output_pro/{hdf5pro,loader,plotter,parallel}` + `plasmapy_bridge` | 纯 h5py 解析 FLASH AMR HDF5，结构化加载，自适应 1D/2D/3D 绘图；PlasmaPy 适配层提供带单位等离子体诊断量（lnΛ/λ_D/κ_e/K_n 等） |

### 自包含运行机制

`flash` 是**完全自包含**的独立包：基础契约（`BaseSimulator`、`SimulationRequest`、
`SimulationResult` 等 schema）全部定义在内置的 `_core/` 子包中，不依赖任何
PhySimX 内部包，所有运行时依赖均可从 PyPI 解析。

```python
# flash/__init__.py 与 interface.py 中
from ._core.interface import BaseSimulator      # dataclass 版契约
from ._core.schema import SimulationRequest     # 无 pydantic 依赖
```

- 安装即用：`pip install -e ".[full,dev]"` 之后 `import flash` 立即可用，无需任何额外私有源。
- `flash.__standalone__` 常量恒为 `True`，保留该常量仅为向后兼容。

### 端到端数据流

`FlashSimulatorEngine.run(params_override)` 是管线的中枢，单条调用串起下述全部步骤（源码见 `scenarios/core/engine/simulator.py`）：

```
参数 override
   │ ① scenario.default_params 合并 override
   ▼
构建运行目录 runs/{id}/
   ├─ sim_input/          ← .F90 / Config / Makefile / .cn4 + {sim_name}.par
   ├─ sim_output/         ← FLASH 原始 chk 文件（keep_flash_raw=True 时保留）
   ├─ database/flash_in/  ← input_params.json + run.log
   └─ database/flash_out/ ← result.h5（最终规整网格插值结果）
   │ ② build_par(params) 生成 .par；复制源文件；生成预诊断图
   ▼
③ 生成 run_flash.sh / submit_flash.sh（WSL / SLURM 双版本，LF 换行）
   │
   ▼
④ WSL:  setup -auto … → make -j → mpirun ./flash4
      （超算:  sbatch submit_flash.sh → srun ./flash4）
   │ 产出 lasslab_hdf5_chk_*（FLASH AMR checkpoint）
   ▼
⑤ 从 WSL /tmp 采集 HDF5 回本地临时目录
   │
   ▼
⑥ scenario.build_grid(params)       构造 (t_grid, x_grid)
   scenario.interpolate(flash_files, t_grid, x_grid, fields)  变分辨率插值
   │
   ▼
⑦ _save_output_hdf5 → database/flash_out/result.h5
   （数据集 t, x, {field:(Nt,Nx)} + 输入参数 attrs，gzip 压缩）
   │
   ▼
⑧ 自动诊断图 → sim_output_plots/（profile / t-x / center_evolution）
```

**输出数据的两种消费方式**：

1. **引擎内置（端到端）**：`result.h5` 是统一规整网格 `(t, x)` 的压缩 HDF5，便于后续优化与跨算例对比。
2. **output_pro 独立消费（原始 AMR 文件）**：直接解析 FLASH 产出的 checkpoint/plot 文件：

```python
from flash.output_pro.loader import FlashDataLoader
from flash.output_pro.plotter import FlashPlotter

loader = FlashDataLoader("lasslab_hdf5_chk_0001")
container = loader.load(compute_derived=True)        # 自动计算派生变量
print(container.ndim, container.nblocks, container.simulation_time)
plotter = FlashPlotter(container)
plotter.plot("dens", save_path="dens.png")
```

   其链路为：`FlashHDF5File`（解析 AMR 块结构 + `extract_var_yt_style` 坐标重建，纯 h5py 无需 yt）→ `FlashDataLoader` / `FlashDataContainer`（结构化容器）→ `FlashPlotter`（自适应 1D 线图 / 2D 伪彩 / 3D 切片）。派生变量（电子密度梯度、压强等）由 `hdf5pro.DataCalculator` 在加载时自动计算。

### 场景驱动机制（即插即用入口）

所有物理问题都封装为 `SimulationScenario` 数据类，引擎只关心它的三个可调用钩子：

| 钩子 | 签名 | 作用 |
|------|------|------|
| `build_par` | `(params) → str` | 生成 FLASH `.par` 内容 |
| `build_grid` | `(params) → (t_grid, x_grid)` | 定义输出规整网格 |
| `interpolate` | `(flash_files, t_grid, x_grid, var_names) → {field: array}` | 把 AMR chk 插值到规整网格 |

新增场景（2026-10-27 去注册化三件套，**零注册代码**）：建场景目录 →
备好 `.F90` / `Config` / `cn4` → 定义 `scenario = SimulationScenario(...)` →
落一份 `scene.json`（name/kind/module/attr/policy 等，模板抄任一现有场景）→
（可选）复制一份通用 `run.py` 到目录内即可 `python run.py --dry-run` 直跑。
`flash.scenarios.core.discovery` 会自动扫描发现，**不改** `registry`/`catalog`/
父包 `__init__`。超算提交需在 `scene.json` 追加 `"hpc": {...}` 节
（见 `flash/scenarios/core/hpc/hpc_job.py` 字段白名单）；核数默认值写 `"nproc_default"`。

### 目录地图（实际结构）

```
flash/
├─ interface.py            # FlashSimulator（旧版 mock/real 统一接口）
├─ _core/                  # 核心抽象：BaseSimulator / schema / registry / config(FlashConfig) / credentials(加密)
├─ scenarios/              # 场景层（只做物理搭建 + 参数覆盖 + 分析回调）
│  ├─ core/                #   框架层 4 子包：scene_reg(发现注册) entry(cli/launcher)
│  │                       #   engine(simulator/base/interpolator) hpc(hpc_job/submit_cli)
│  ├─ core/runner.py       #   兼容壳 → flash_run.modes.runner（125 处引用原地保留）
│  ├─ common/              #   场景共享代码（scene_ref 按名加载 / time_control）
│  ├─ scripts/             #   relocate 工具链 / checks / validation / legacy
│  └─ public/ private/ flash_demo/   # 公开场景 / 私有研究线 / 演示脚本
├─ input_gen/              # 输入生成（按产物分子包，每个含 generator.py）
│  ├─ gen_par/  gen_config/  gen_makefile/  gen_sim_data/  gen_sim_init/
│  ├─ gen_sim_initblock/  gen_eos_op/  gen_shell_script/  gen_Grid_markRefineDerefine/
│  └─ gen_checker/         #   生成质量检查（含 check_scene_sources 去运行化护栏）
├─ flash_run/              # 执行层（唯一知道"怎么跑"的地方）
│  ├─ modes/runner.py      #   四模式执行体 + 目标解析 + HpcRunner + 环境自检
│  ├─ hpc.py               #   超算技能 CLI（status/submit/cancel/wait/download/…）
│  ├─ env/                 #   FlashEnvManager / resource_config / venv_paths(venv 唯一事实源)
│  └─ remote/              #   SSH/SFTP + slurm 控制 + fetch_policy（chk-only 唯一策略）
├─ output_pro/      # 输出处理
│  ├─ hdf5pro/       #   FlashHDF5File / DataCalculator / DATA_CONFIG
│  ├─ loader/              #   FlashDataLoader / FlashDataContainer
│  ├─ plotter/             #   FlashPlotter（自适应维度）
│  └─ parallel.py          #   多文件 / 多变量并行加速
├─ physics/                # 物理专题资料（ele_nonlocal 等）
├─ projects/               # 项目级实验配置
├─ docs/ scripts/ utils/   # 文档 / Git 工具（含 08_docs 文档门禁）/ 辅助脚本
└─ test/                   # 测试套件
```

---

## 安装

### 从源码安装

```bash
# 克隆仓库
git clone <your-repo-url>
cd flash

# 安装核心依赖
pip install -e .

# 安装完整功能（含 h5py / matplotlib / yt）
pip install -e ".[full]"

# 安装开发工具
pip install -e ".[dev]"

# 建议安装好后运行 start_flash.py 进行全局测试 (环境自检自愈)
```

### 最小依赖（独立模式）

```
cryptography>=41.0   # 凭据加密
numpy>=1.24          # 数值计算
pydantic>=2.0        # 数据校验
```

### 可选依赖

| 依赖包 | 用途 | 安装方式 |
|--------|------|----------|
| `h5py>=3.8` | HDF5 文件读取 | `pip install h5py` |
| `matplotlib>=3.7` | 可视化 | `pip install matplotlib` |
| `yt>=4.1` | FLASH HDF5 专业可视化 | `pip install yt` |
| `paramiko` | SSH 远程连接 | `pip install paramiko` |

---

## 快速开始

### 0. 环境准备

```bash
# WSL 上确保 FLASH 4.8 已安装
./setup -auto ...  # (按 FLASH 安装文档)
```

### 0.1 还没装 FLASH？—— `hello_flash` 零基础一键安装包（从零到首图）

[`flash/scenarios/flash_demo/hello_flash/`](flash/scenarios/flash_demo/hello_flash/README.md)
是面向**首次接触 FLASH** 用户的快速上手包：从零安装 FLASH 4.8 → 运行首个 LaserSlab 1D 仿真 → 自动生成密度分析图，开箱即用。详细步骤、脚本清单与踩坑指南见其 [README.md](flash/scenarios/flash_demo/hello_flash/README.md)，此处只列功能概要：

**① 前期准备（3 步，全部就绪后安装约 30–60 分钟）**

| 步骤 | 内容 |
|---|---|
| 安装 WSL + Ubuntu | PowerShell（管理员）：`wsl --install -d Ubuntu` |
| 下载 4 个源码包 → `flash/flash_src/` | **FLASH 4.8** / **HDF5 1.8.12** / **HYPRE 2.9.0b** / **MPICH 3.2**（受 FLASH License §3 约束**不随包分发**，需自行从官网下载，地址表见 hello_flash README） |
| 设置用户名 | `python -m flash._core.credentials user <名字>`（默认 `hello`；FLASH 安装到 `~/<用户名>/FLASH/FLASH4.8/`，所有脚本自动读取，**代码零硬编码**） |

（可选）下载 IONMIX 源码——仅后期用 `gen_eos_op` 生成自定义 EOS/不透明度表时需要。

**② 推荐方式：交给 Agent AI 微调适配执行（不要直接点脚本）**

脚本是给 Agent AI 的"操作蓝图"——Agent 会结合当前装置（Ubuntu 版本、gcc、核数内存、sudo、网络）自动微调编译参数与并行度、读取 credentials 用户名、出错时读日志定位根因重跑。直接执行需自行处理环境差异（如新版 Ubuntu 无 gcc-9）。

**③ 三阶段流程**

| 阶段 | 命令 | 自动完成 | 产物 |
|---|---|---|---|
| 📦 安装 | `python deploy_flash.py`（交互菜单：Local WSL / SSH1 / SSH2） | 系统依赖(gcc-9/gfortran-9/LAPACK) → 源码编译 MPICH/HDF5/HYPRE → 配置 FLASH → 编译 LaserSlab | `flash4` 可执行文件 |
| 🎯 运行 | `bash run_and_collect.sh`（或总入口 `run_hello_flash.sh`） | 运行仿真 → 收集 HDF5 → 调用分析 | 41 个 chk + 80 个 plt（约 3–10 分钟） |
| 📊 分析 | `python3 analyze_density.py`（阶段 2 已自动调用） | HDF5 → 密度分析 | `outputfiles/plots/` 下 3 张图（x-t 密度谱 / 演化曲线 / 快照对比） |

> 环境变量：`FLASH_SIM_USER_DIR`（用户名覆盖）、`FLASH_SOURCE_SUFFIX`（数据来源后缀 `from_ssh1`/`from_ssh2`）。安装脚本会将 MPI/HDF5/HYPRE 路径写入 `~/.bashrc`。
> 常见坑（HYPRE 符号链接、MPICH root 参数、`python` vs `python3`）的解决方案均已在 hello_flash README「已知问题」节收录。

### 0.2 两个常用脚本入口（推荐）

仓库根目录提供两个开箱即用的脚本，覆盖「安装验证」与「场景仿真」两类日常操作。

**① `start_flash.py` — 统一入口：安装验证 / 造离线包 / 导出 U 盘**

所有部署相关操作都从这里发起，**不必记住分散的脚本**（它们仍可独立运行，
`start_flash.py` 只做参数翻译与转发，逻辑不会漂移）。

```bash
# ---- 联网机 ----
python start_flash.py --make-wheelhouse# 造 wheelhouse（等价 build_wheelhouse.py）
python start_flash.py --make-wheelhouse --export-profile lite   # 精简档
python start_flash.py --export-usb D:\usb_pkg                 # 导出到 U 盘（等价 usb_backup.py）

# ---- 离线机（安装 + 测试）----
python start_flash.py --offline --wheelhouse D:\pkg\wheelhouse# 离线安装 + 三套测试
python start_flash.py --offline --check      # 只校验，不安装不改动任何文件
python start_flash.py --offline --no-tests   # 快速安装（跳过三套测试）

# ---- 在线机 ----
python start_flash.py                        # 在线安装 + 三套测试 + 报告
python start_flash.py --no-tests# 只装环境
```

自动完成：检查/创建项目专属虚拟环境（含**环境健康检查**：关键依赖可导入 + pytest 可启动）→ 安装 flash 包及全部依赖 → 运行三套全局测试 → 生成纯文本报告 `test/reports/INSTALL_TEST_REPORT.txt`（含**环境版本快照**；pytest 日志同目录）。

> **三种部署流程**（同一入口）：
> ① 在线机直接装并测试 → `python start_flash.py`
> ② 在线机造包 + 导 U 盘 → 离线机安装 → `--make-wheelhouse` / `--export-usb`，再 `--offline`
> ③ 离线机直接装并测试 → `python start_flash.py --offline --check` 后 `--offline`
>
> **sdist 现已自足（2026-10-24）**：源码包从 37.5 MB 降至 4.6 MB，且包含
> `deploy/_wh_common.py`、`deploy/install_offline.py`，因此「解包 sdist → 离线安装」
> 这条路径可用（此前 `/deploy/**` 被整目录排除，离线预检直接 FATAL）。

| 参数 | 作用 |
|---|---|
| `--make-wheelhouse` | 联网机造 wheelhouse（转发到 `build_wheelhouse.py`） |
| `--export-profile` | 造包档位 `full`/`runtime`/`lite`（默认 `full`） |
| `--export-usb <DEST>` | 导出源码+wheelhouse 到 U 盘（转发到 `usb_backup.py --mode gitee`） |
| `--offline` | 离线安装：pip 走本地 wheelhouse（`--no-index`），物理上无法联网 |
| `--wheelhouse <路径>` | wheelhouse 目录（默认自动探测） |
| `--profile <档位>` | 离线预检档位 |
| `--check` | **只校验**：清单 + 平台 + 依赖覆盖度，不创建/改动 venv，不安装、不测试 |
| `--no-tests` | 装好环境后跳过三套测试（快速安装） |

- **自愈机制（重要）**：venv 环境健康检查不通过（关键依赖缺失 / pytest 无法启动）或三套件全部「0 用例启动失败」时，脚本**自动清零重建并重测**——无需手动设置 `FLASH_FORCE_CLEAN=1`、不依赖重启机器。
- 报告内容：安装验证、环境版本快照（关键依赖真实版本统一记录）、三套件统计（framework / input_gen / output_pro）、失败明细
- 高级变量：`FLASH_VENV_DIR` 指定 venv 路径；`FLASH_FORCE_CLEAN=1` 强制重建；`FLASH_NO_AUTO_REBUILD=1` 禁用自动重建（仅诊断用）；`FLASH_SIM_USER_DIR` 指定 FLASH 安装用户名

> ★ **venv 目录按平台区分**（09-10）：`Windows → .venv-win`、`Linux/WSL → .venv-linux`。
>
> 原因：两平台的 venv **物理上不能共用** —— 解释器一个是 PE（`.venv-win\Scripts\python.exe`）
> 一个是 ELF（`.venv-linux/bin/python`），且 numpy/scipy/h5py 等已编译扩展分别是
> `win_amd64` 与 `manylinux` wheel，同一目录只能装其中一种。
> 分目录后可**在Windows 与 WSL 之间来回切换**，各自环境独立保留、互不覆盖。
>
> 向后兼容：旧的无后缀 `.venv` 若**正好属于本平台**仍会被沿用；
> 若属于另一平台，脚本会改用本平台目录并**保留原目录不删**。
> 显式设`FLASH_VENV_DIR` 时以你的指定为准。

**② `laserslab1d_local_custom.py` — LaserSlab 1D 场景仿真（超算 / 本地 WSL 双模式）**

`flash/scenarios/public/center_evolution/ch_center/` 下的可配置一维对称域 LaserSlab 仿真：CH 靶居中、两侧真空、两束 351nm 激光相向入射。自动完成：生成 FLASH 输入文件 → 运行（超算 SLURM 或本地 WSL）→ HDF5 分析 → 输出 PNG。

```bash
# ★ 推荐入口（2026-10-24）：统一 CLI，--mode 默认 auto（平台自适应）
python -m flash.scenarios.core.entry.cli run ch_center            # auto：Win→wsl / Linux→local / 登录节点→hpc-insitu
python -m flash.scenarios.core.entry.cli run ch_center --mode hpc-insitu   # 已登录超算：就地 sbatch 编排
python -m flash.scenarios.core.entry.cli run ch_center --mode hpc-remote   # 本机驱动：上传 → sbatch → 回收
python -m flash.scenarios.core.entry.cli explain ch_center        # 只打印判定轨迹，不执行
python -m flash.scenarios.core.entry.cli list                     # 列出可执行场景与允许模式

# 直跑场景脚本（等价，保留兼容；★ 该脚本**没有** argparse，
#   模式只能由环境变量指定，传 --mode 会被忽略）
set FLASH_RUN_MODE=hpc-insitu       # Windows CMD
export FLASH_RUN_MODE=hpc-insitu    # bash
.venv-win\Scripts\python.exe flash\scenarios\center_evolution\ch_center\laserslab1d_local_custom.py
```

- 运行模式：**`auto`（默认，平台自适应）** / `local` / `wsl` / `hpc-remote` / `hpc-insitu`；
  优先级 `--mode` > `FLASH_RUN_MODE` > 场景默认。判定依据会打印在日志首行，
  **不做静默兜底**（例：SNB 族只允许超算，若在 Windows 上跑 auto 会明确报错并给出修复建议）。
- **跨平台（09-10 实测）**：Windows 上以 `.venv-win\Scripts\python.exe` 调用，内部经
  `wsl bash -c` 转发；**若已在 WSL 内**（如离线机把仓库放在 `/mnt/e/...` 并用 Linux
  解释器执行），脚本自动改用 `bash -c`，路径转换也幂等，两种方式都可直接跑。
- **FLASH 安装位置解析（09-10）**：依次为
  1. 环境变量 `FLASH_SIM_USER_DIR`（最高优先级）
  2. 加密凭据里的 `default_user_name`（`~/.physimx/flash/credentials.enc`）
  3. 自动扫描 `$HOME/*/FLASH/FLASH4.8`（判据：同时有 `setup` 与
     `source/Simulation/SimulationMain`）
  4. 以上都无 ⇒ 回落到字面量 `hello`（`~/hello/FLASH/FLASH4.8`）

  ★ 干净克隆 / 离线机**没有** `credentials.enc`，第2 步读不到 ⇒ 会误指向
  `~/hello/...` 而报 `FLASH_HOME not found`；第 3 步的自动扫描正是为此准备的。
  需要强制指定时：`export FLASH_SIM_USER_DIR=QC`。
- **必须文件自动生成（自愈）**：仓库不发布 `.par/Makefile/Config/F90/run 脚本/cn4` 等生成文件（`flash_input/` 被 .gitignore 排除，同 output_pro 的 inputfiles/ 模式）。脚本执行时先经 `gen_checker` 检查 7 项 FLASH 仿真必须文件，**缺失则自动调用 input_gen 包生成**，已就绪则直接下一步。也可单独运行 `python flash/scenarios/public/center_evolution/ch_center/gen_flash_inputs.py`（`--check` 仅检查 / `--force` 强制重生成）生成/检查输入文件
- EOS 表：cn4 源文件存放于 `flash/input_gen/gen_eos_op/eos_op_data/Gen_eos_op_data/`（`ch_mix` / `helium_hires` 等自研 ionmix 表随仓库分发），由 `EOSOpacityGenerator` 复制到 `flash_input/`
- 输出：`flash/scenarios/public/center_evolution/ch_center/flash_output/plots/{dens,tele,trad}_hpc.png`（超算）/ `{dens,tele,trad}_wsl.png`（本地 WSL）

### 1. 场景系统 — 即插即用（推荐）

```python
import sys
sys.path.insert(0, "path/to/physimx_sim/src/physimx_sim")

from flash.scenarios.core.registry import get_scenario
from flash.scenarios.core.simulator import FlashSimulatorEngine

# 列出所有可用场景
from flash.scenarios.core.registry import list_scenarios
for name, desc in list_scenarios():
    print(f"{name}: {desc}")

# 运行一个场景 (自动完成: 编译 → 运行 → 插值 → 输出)
engine = FlashSimulatorEngine(get_scenario("thin_layer_sandwich_si"))
output = engine.run()

print(f"✅ 输出 HDF5: {output.result_h5_path}")
print(f"   运行目录:   {output.run_dir}")
print(f"   chk 文件:   {output.n_chk}")
print(f"   输出字段:   {output.fields}")
```

详见 [`scenarios/README.md`](flash/scenarios/README.md)。

### 2. 仿真输入生成

```python
from flash.input_gen.gen_par.generator import ParGeneratorExtended

gen = ParGeneratorExtended()
par_content = gen.generate(
    dimension=1,
    sim_name="LaserSlab1D",
    tmax=1.0e-9,
    nblockx=4,
    lrefine_max=6,
)
with open("laserslab.par", "w") as f:
    f.write(par_content)
```

### 3. HDF5 输出分析

```python
from flash.output_pro.loader import FlashDataLoader
from flash.output_pro.plotter import FlashPlotter

# 加载 checkpoint 文件
loader = FlashDataLoader("laserslab_hdf5_chk_0001")
container = loader.load(compute_derived=True)

print(f"仿真时间: {container.simulation_time:.4e} s")
print(f"维度: {container.ndim}D, 块数: {container.nblocks}")
print(f"变量: {list(container.data.keys())}")

# 自适应维度绘图
plotter = FlashPlotter(container)
plotter.plot("dens", save_path="dens.png",
             title="Density Distribution")
plotter.plot("tele", save_path="tele.png",
             title="Electron Temperature")
```

### 4. 远程超算运行

```python
from flash.flash_run.remote.remote_deploy import FlashRemoteDeploy

with FlashRemoteDeploy(credential_name="flash_ssh") as deploy:
    # 上传参数文件
    deploy.upload("laserslab.par", "~/run/laserslab.par")

    # 提交 SLURM 作业
    job_id = deploy.submit_job(
        par_file="laserslab.par",
        nprocs=4,
        wall_time="01:00:00",
        job_name="LaserSlab1D",
    )
    print(f"Job submitted: {job_id}")

    # 等待完成并下载结果
    deploy.wait_for_job(job_id, timeout=3600)
    deploy.download_results(
        remote_output_dir="~/run",
        local_output_dir="./outputs",
        pattern="*.h5",
    )
```

### 5. 使用 `FlashSimulator` 统一接口

```python
from flash import FlashSimulator
from flash._core.schema import SimulationRequest

sim = FlashSimulator(mock=True)
result = sim.simulate(SimulationRequest(
    request_id="demo-001",
    params={"temperature": 5000.0, "density": 1e-3},
))
print(result.output_data)
```

---

## API 速览

### 核心类

| 类 | 包路径 | 说明 |
|----|--------|------|
| `FlashSimulatorEngine` | `flash.scenarios.core.engine.simulator` | **统一仿真引擎** — 场景驱动, 封装 WSL 执行 + 插值 + 输出管线 |
| `SimulationScenario` | `flash.scenarios.core.engine.base` | 场景声明式配置数据类 |
| `FlashSimulator` | `flash` | 旧版统一仿真接口, 支持 mock/real 双模式 (旧接口) |
| `FlashConfig` | `flash._core.config` | 全局配置管理器 |
| `ParGeneratorExtended` | `flash.input_gen.gen_par.generator` | `.par` 参数文件生成器 |
| `ConfigGenerator` | `flash.input_gen.gen_config.generator` | `Config` 文件生成器 |
| `BlockGenerator` | `flash.input_gen.gen_sim_initblock.generator` | `Simulation_initBlock.F90` 生成器 |
| `FlashHDF5File` | `flash.output_pro.hdf5pro.flash_hdf5` | 底层 HDF5 文件读取器 |
| `FlashDataLoader` | `flash.output_pro.loader.data_loader` | 结构化数据加载器 |
| `FlashDataContainer` | `flash.output_pro.loader.data_loader` | 数据容器（含 data / derived / grid） |
| `FlashPlotter` | `flash.output_pro.plotter.plot_generator` | 自适应维度绘图器 |
| `FlashEnvManager` | `flash.flash_run.env.env_manager` | 多环境管理器 |
| `FlashRemoteDeploy` | `flash.flash_run.remote.remote_deploy` | 远程部署管理器 |

### CLI 命令

```bash
# 凭据管理交互式菜单
flash-cred

# 启动初始化配置
flash-setup
```

---

## 典型工作流

### 0. 功能模块地图（2026-10-24 解耦改造）

三个功能模块**独立分工、显式接口解耦**，依赖方向单调、可机器校验：

```
deploy/          部署层：造包 / 离线安装 / 环境自检 / 超算部署链 / wheel 护栏
                 → 禁止 import flash.scenarios；允许 import flash.flash_run
flash/flash_run/ 执行层：目标解析 / 四模式执行体 / SSH / slurm / 产物回收 / 装置配置
                 → 禁止 import flash.scenarios
flash/scenarios/ 场景层：只做物理搭建 + 参数覆盖 + 分析回调
                 → 禁止内联 ssh/sbatch/paramiko/["wsl"/分区表/装置绝对路径
flash/input_gen/ 输入生成层：无运行细节
```

**执行目标模型（新）**：`EXEC_TARGETS = local | wsl | hpc-remote | hpc-insitu`

| 目标 | 何时命中 | 说明 |
|---|---|---|
| `hpc-insitu` | 本机有 `sbatch`+`sacct`+`sinfo` | 脚本已在超算登录节点，就地 sbatch 编排（不自连 SSH） |
| `local` | 本机为 Linux/WSL 原生 | 直接 `bash run_flash.sh` |
| `wsl` | Windows 且存在 `wsl` 命令 | 经 `wsl.exe` 转发到发行版内执行 |
| `hpc-remote` | 显式指定（Windows/Linux 均可） | 本机驱动 → SSH → 超算 |

`--mode auto`（**默认**）按上表自上而下判定，并打印命中依据；
`--mode <target>` 与 `FLASH_RUN_MODE` 环境变量始终可覆盖。
`RUN_MODES` 旧三元组保持兼容（`hpc` 为 `hpc-remote` 的永久别名）。

常用入口：

```bash
# 安装（联网/离线同一入口；离线需 artifacts/wheelhouse 含 MANIFEST.json）
python start_flash.py [--offline] [--wheelhouse D] [--profile full|runtime|lite]
# 部署目标统一入口（2026-10-24）：本机安装与超算部署链不再需要记两套命令
python start_flash.py --target auto|win|wsl|hpc
python start_flash.py --target hpc -- --only 05b        # `--` 之后透传给 hpc_deploy/run_all.py
# 三平台依赖差异表（根目录唯一事实源 = deploy/env_spec.py）
#   机器可读 lock: deps_lock/requirements-{win,wsl,hpc}.txt
python deps_lock/generate_locks.py --check

# 运行环境自检（可作门禁：存在待修项时 --strict 返回非零）
python -m flash.flash_run.modes.runner --check-env [--strict]

# 场景统一入口（唯一实现；--mode 默认 auto，平台自适应）
python -m flash.scenarios.core.entry.cli list | explain <scene> | run <scene> [--mode ...]

# 超算技能统一 CLI（本地/登录节点两侧可调）
python -m flash.flash_run.hpc status | submit | cancel | wait | download | route-test | nodes

# 分层护栏（8 条规则；基线由 --freeze 生成，只降不升）
python -m flash.input_gen.gen_checker.check_scene_sources [--report-only|--rules-only|--freeze]

# 构建产物统一落 artifacts/（dist、wheelhouse、logs），不污染根目录
python deploy/wheel_leak_audit.py <wheel>   # 造包后必跑的护栏
```

> **虚拟环境路径单一事实源**：`flash/flash_run/env/venv_paths.py`（纯 stdlib）。
> 优先级 `FLASH_VENV_DIR` > `<仓库根>/.venv-<平台>` > 旧 `.venv`。
> 超算侧固定 `<TARGET>/.venv-hpc-nce`。安装/部署/运行时三侧共用，不再各自实现。

### 1. 完整仿真工作流

```
Config 编译配置  →  setup + make →  FLASH 二进制
     ↑                              ↓
  生成 Config                    生成 .par  →  mpirun
  (gen_config/)                              (flash_run/)
                                                 ↓
                                             HDF5 输出
                                                 ↓
                                        output_pro/
                                        自适应绘图 + 分析
```

### 2. 批量参数扫描

```python
# 多功率因子批量仿真
from flash.scenarios.flash_demo.demo_hpc.laserslab1d_hpc_demo_batch import (
    create_power_variants, deploy_to_supercomputer,
    run_flash_remotely, analyze_and_plot,
)

power_factors = [0.5, 1.0, 1.5, 2.0]
variants = create_power_variants(power_factors)
deploy_to_supercomputer(variants)
job_ids = run_flash_remotely(variants)
analyze_and_plot(variants)
```

### 3. 自定义网格细化

`input_gen/gen_Grid_markRefineDerefine/` 提供 FLASH `Grid_markRefineDerefine.F90` 的 Python 生成器，支持密度/温度梯度和多物质界面的自适应加密。

### 4. 多环境管理与切换

```python
from flash.flash_run.env import get_env_manager

mgr = get_env_manager()
print(mgr.summary())
# [local_wsl] LOCAL(WSL) - 当前
# [supercomputer_nc_e] SSH(flash_ssh)
# [supercomputer_bscc_t6] SSH(flash_ssh_2)

mgr.set_active("supercomputer_nc_e")
```

---

## 运行环境

flash-sim 支持三平台部署：

| 平台 | 访问方式 | MPI | HDF5 | HYPRE | 典型核数 |
|------|----------|-----|------|-------|----------|
| 本地 WSL (Ubuntu) | 本地 | 源码编译 → `/usr/local/mpich/` | 源码编译 → `/usr/local/hdf5/` | 源码编译 → `/usr/local/hypre/` | 1 |
| ParaCloud NC-E | SSH port 22 | `module load mpich/3.2-gcc9.3` | `module load hdf5/1.8.18` | 用户空间 `~/hello/FLASH/local/hypre/` | 4 |
| ParaCloud BSCC-T6 | SSH port 8443 | `module load mpich/3.2-gcc9.3` | `module load hdf5/1.8.18` | 用户空间 `~/hello/FLASH/local/hypre/` | 4 |

> **关键提示**: FLASH 的默认安装路径为 `~/hello/FLASH/FLASH4.8`，其中 `hello` 是**回落用的字面量默认值**。实际解析顺序为：
> `FLASH_SIM_USER_DIR` 环境变量 → 加密凭据的 `default_user_name`（`~/.physimx/flash/credentials.enc`，可用 `manage.py` 交互式修改）→ 自动扫描 `$HOME/*/FLASH/FLASH4.8` → 字面量 `hello`。
> ★ 第3 步的自动扫描是为**干净克隆 / 离线机**准备的 —— 这类环境没有 `credentials.enc`，第 2 步会回落 `hello` 而实际 FLASH 可能装在 `~/QC` 等其他用户目录下。
> **HPC 关键提示**: 超算上 HYPRE_PATH 可能因符号链接 `/public1/home → /publicfs01/fs1-e/home` 导致编译失败。必须使用 `readlink -f` 解析真实路径后写入 `Makefile.h`。
---

## 开发指南

### 代码规范

- **行尾**: 所有文件强制 Unix LF（`.gitattributes` 已配置）
- **格式化**: Black (`--line-length=120`), Ruff linting
- **绘图**: 全英文字符，标题≥24pt，标签≥20pt，DPI≥450，即英文文献插图风格，默认字体 Times New Roman
- **Python**: 3.10+，类型注解优先
- **PlasmaPy vendor 边界**: `flash/output_pro/PlasmaPy/` 下的上游源码**不参与**本仓 Black/Ruff 检查（pyproject 已排除），不修改其源文本；对 PlasmaPy 的所有扩展一律经 `output_pro/plasmapy_bridge.py` 适配层实现

### PlasmaPy 开发要求（vendor 快照合规）

flash 包内嵌 PlasmaPy v2026.2.0 源码快照（BSD-3），开发时须遵守以下对齐要求（详见 [docs/PLASMAPY_DEVELOPMENT.md](docs/PLASMAPY_DEVELOPMENT.md)）：

```bash
# ① 开发工具链（对齐 PlasmaPy 上游 dev 依赖: pytest 9 / xdist / codespell）
pip install -e ".[plasmapy-dev]"

# ② PlasmaPy editable 安装进当前环境（source of truth = vendor 目录）
python flash/output_pro/PlasmaPy/install_editable.py

# ③ 开发自测: 桥接层 12 项物理交叉验证 + PlasmaPy 冒烟
pytest flash/output_pro/test/test_plasmapy_bridge.py -v
python flash/output_pro/PlasmaPy/install_editable.py --check

# ④ 升级上游版本: 替换 vendor 目录 → git commit → 重跑 ②③ → 更新 NOTICE/CHANGELOG
```

关键约束：vendor 源码**未修改**（版权合规前提，见 [NOTICE](NOTICE)）；桥接扩展不改 PlasmaPy 源文本；HPC 离线环境走 wheel bundle 路线（`DEPENDENCIES.md`）。

### 运行测试

```bash
# Flash 框架测试（核心）
make test
# 或
pytest test/ -v

# 全局测试（全部模块）
make test-all

# 代码检查
make lint
make format
```

**私有场景测试说明**:
- **全局测试不测私有场景**（`thin_layer_sandwich_si/al`、`grad_dens_sandwich` 为本地私有,
  发布环境未注册时自动跳过; 全局只测公开场景 `ch_center`）。
- 本地手动执行私有场景完整测试（需私有场景代码在仓库中）:
  ```bash
  pytest test/scenarios/test_engine_dryrun.py -v
  pytest test/scenarios/test_scenario_par_build.py -v
  ```

**output_pro 测试数据说明**:
- 测试所需 HDF5 数据（`flash/output_pro/inputfiles/`, .gitignore 排除,
  **不随包/仓库发布**）由 `flash/output_pro/test/gen_test_data.py`
  **并行快速生成 → 测试 → 全部通过即自动删除**;
  测试有失败则**保留数据文件**供调试
  （调试完成后 `python flash/output_pro/test/gen_test_data.py --cleanup` 手动清理）。

### Git 工作流

```bash
# 安装 Git 钩子（pre-commit + pre-push）
bash scripts/03_git_publish/install-git-hooks.sh

# 提交触发 ≈ 代码风格检查
# 推送触发 ≈ 框架测试
# 打标签前运行全局测试:
bash scripts/03_git_publish/git-tag-with-test.sh v<版本号>

# 完整发布流程（格式检查 + 测试 + 构建 + 打标签）
bash scripts/03_git_publish/tag-release.sh v<版本号>
```

### 发布

```bash
# 构建分发包
make build
# 或
python -m build

# 产物在 dist/ (以 pyproject.toml 版本号命名)
# flash-sim-<版本号>.tar.gz, flash_sim-<版本号>-py3-none-any.whl
```

---

## 文档索引

### 根目录文档

| 文件 | 说明 |
|------|------|
| `README.md` | **本文档** — 项目概述与快速入门 |
| `AGENTS.md` | **Agent 入口索引** — 各类 Agent（Codex/Claude Code/OpenCode/WorkBuddy…）的技能索引与分工声明 |
| `CLAUDE.md` | Claude Code 桥接（首行 `@AGENTS.md` 导入） |
| `skills编写计划.md` | Agent skills 仓库化的计划与实施记录（Phase 0–3 已完成） |
| `scenarios/README.md` | **场景系统使用指南** — 即插即用仿真入口 |
| `docs/README.md` | FLASH 仿真使用指南（详细版，含所有子模块 API） |
| `docs/flash_operation_standard.md` | 仿真操作规范（绘图语言/行尾格式/运行流程） |
| `docs/flash_simulation_execution_knowledge.md` | 仿真执行知识库（LaserSlab 变体/SLURM/HDF5 复合类型） |
| `docs/par_format_guide.md` | `.par` 排版规范 |
| `docs/GIT_WORKFLOW.md` | Git 工作流与测试分层策略 |
| `docs/VERSIONING.md` | 版本号命名协议 (SemVer) |
| `docs/skills-map.md` | 技能 ↔ 文档 ↔ Python 模块三向索引 |
| `docs/reference/param_index_flash48.md` | FLASH 4.8 高频参数索引（~150 条，含 setup 相关性） |

### 文档体系索引（2026-11-05 重建，各目录均含「最后核对」元信息）

| 区域 | 入口文档 |
|------|---------|
| 核心层 | `flash/_core/README.md` · `flash/_core/credentials/README.md` |
| 执行层 | `flash/flash_run/README.md`（含工程铁律）· `env/` · `remote/` · `modes/` |
| 输入生成 | `flash/input_gen/README.md` · 各 gen_* 子包 README.md（原 GEN_*_GUIDE，2026-11-06 统一改名）· `gen_eos_op/README.md`（含 eosop_pro/ionmix/src 子体系导航） |
| 输出处理 | `flash/output_pro/README.md` · `hdf5pro/` · `loader/` · `plotter/` · `test/README.md` |
| 场景系统 | `flash/scenarios/README.md` · `core/`（4 子包）· `common/` · `scripts/`（relocate 六件套）· 各场景薄 README |
| 文档工具 | `scripts/08_docs/README.md`（dump_docstrings 摘要 / check_docs 门禁） |
| Agent 技能 | `skills/README.md`（skill 编写规范与 SKILL.md 模板）· 各 `skills/<name>/SKILL.md` |

### 子模块文档

| 文档 | 位置 |
|------|------|
| Output Processors 使用说明 | `output_pro/docs/output_processors_usage.md` |
| Hello FLASH 快速上手 | `scenarios/flash_demo/hello_flash/README.md` |
| 网格细化实施指南 | `input_gen/gen_Grid_markRefineDerefine/README.md` |
| 新参数生成指南 | `input_gen/gen_newpara/README.md` |
| F90 参考文件指南 | `input_gen/gen_otherf90s/README.md` |
| 多区密度剖面参考 | `input_gen/gen_newpara/RP_Reference.md` |

### Skills（Agent 技能库，多 Agent 通用，随 git 分发）

> 2026-11-06 起，Agent skills 沉淀到仓库级 `skills/`（13 个，统一 `flash-` 前缀），
> 是**唯一事实源**。编写规范、SKILL.md 模板见 `skills/README.md`；
> 技能索引与分工声明见根 `AGENTS.md`；skill ↔ docs ↔ 模块三向映射见 `docs/skills-map.md`。

**各 Agent 的加载方式**：

| Agent | 加载路径 |
|---|---|
| Codex / OpenCode / Cursor / Zed / Warp / Amp / Jules / VS Code | 原生读取根级 `AGENTS.md` → 按索引表加载 `skills/<name>/SKILL.md` |
| Claude Code | 根级 `CLAUDE.md`（首行 `@AGENTS.md` 导入） |
| WorkBuddy | 项目级 `.workbuddy/skills/` 自动加载——由 `python scripts/sync_workbuddy_skills.py` 从 `skills/` 单向镜像（`--dry-run` 预览 / `--check` 一致性校验） |
| 其他任意 Agent | 纯 markdown 链路：`AGENTS.md` → `skills/README.md` → 对应 `SKILL.md` |

**技能清单速览**（详细触发场景见 `AGENTS.md`）：

| 类别 | Skill |
|---|---|
| 入口 | `flash-sim-overview`（含「意图→技能→模块」路由矩阵） |
| 操作型 | `flash-scenario-setup`（SNB/FL-SH 场景·dtmax·分享合规）· `flash-scenario-family`（家族派生·cn4 核查·关辐射变体）· `flash-input-gen`（输入文件全流程生成）· `flash-newpara`（新参数/多区密度剖面）· `flash-par-gen`（.par 排版规范）· `flash-grid-refine-constraint`（AMR 细化约束）· `flash-run-deploy`（三模式·超算部署）· `flash-output-analysis`（HDF5·x-t 图纪律）· `flash-eos-op`（IONMIX cn4/cnr）· `flash-flychk-history`（FLASH→FLYCHK）· `flash-hpc-fetch`（超算取数）· `flash-data-extract`（纯 h5py 提取）· `flash-backup-verify`（备份验证）· `flash-readme-sync`（全仓 README 巡检） |
| 知识型 | `flash-knowledge`（FLASH 11 单元源码级知识导航 + src_finding 方程↔源码对照，吸收自上游 FLASH-Expert @ 25013c5）· `flash-pitfalls`（报错→根因→修复速查，38 条）· `flash-param-lookup`（联网查官方 rpDoc 参数定义，4050 参数离线索引） |
| 通用工程 | `flash-code-refactor-safe`（安全重构）· `flash-code-execute-verify`（代码级执行验证）· `flash-token-budget`（token 节约纪律）· `flash-skill-sync`（全体系 skill 巡检维护） |

**用户级 skill 已 deprecated（2026-11-06）**：以下 `~/.workbuddy/skills/` 技能内容已并入仓内
对应 skill（SKILL.md 头部有 DEPRECATED 横幅），请改用仓库级版本：
`snb-flash-scenario-setup` → `flash-scenario-setup`；
`flash-to-flychk-history` → `flash-flychk-history`；
`hpc-sftp-parallel-fetch` → `flash-hpc-fetch`；
`physimx-h5py-yt-extract` / `physimx-h5py-batch-read` / `physimx-float64-cv-fix` → `flash-data-extract`；
`physimx-flash-backup-verify` → `flash-backup-verify`。
外部仓库依赖类技能（flychk 四件套 / spectime 双 skill / knnum-mc-ploter /
eos-table-family-census / literature-citation-graph-harvest 等）保留在用户级，不受影响。

---

## 重要依赖材料清单（.gitignore 忽略的私有材料）

> 以下材料因许可限制（FLASH License / 第三方软件）或体积原因被 `.gitignore` 排除，
> **不随仓库分发**。此处仅列出文件名与所在位置，便于自行准备
> 哪些材料、放置在何处。获取方式见各条目说明。

### 1. FLASH 安装依赖压缩包 — `flash/flash_src/`

FLASH 4.8 引擎源码及其编译依赖（hdf5 / hypre / mpich）压缩包与一键安装脚本：

```
flash/flash_src/
├── FLASH4.8.tar.gz              # FLASH 4.8 官方源码包（许可限制，须自行从 flash.rochester.edu 获取）
├── FLASH4.8/                    # 解压后的源码树（本地生成）
├── hdf5-1.8.12.tar.gz           # HDF5 1.8.12（FLASH 输出格式依赖）
├── hypre-2.9.0b.tar.gz          # Hypre 2.9.0b（扩散求解器依赖）
├── mpich-3.2.tar.gz             # MPICH 3.2（MPI 并行依赖）
└── FLASH_one_click_install.sh   # 一键编译安装脚本（随仓库分发）
```

### 2. IONMIX 相关源码 — `flash/input_gen/gen_eos_op/ionmix/ionmix/src/Ionmix_run/`

IONMIX 物性生成程序源码、示例输入/输出与参考文献（许可限制，不随仓库分发）：

```
.../ionmix/ionmix/src/Ionmix/
├── abjt_03.f                    # IONMIX 主源码（Fortran）
├── abjt_03                      # 编译产物（可执行）
├── CH-QC-1-001.cn4              # CH 材料 EOS/不透明度数据表
├── eos_Gen.cn4                  # EOS 生成用数据表
├── cnrdeos                      # EOS 相关辅助程序
├── ionmxinp / ionmxout / ionmxbug  # 示例输入 / 输出 / 调试文件
├── implot01 ... implot06        # 绘图辅助脚本（implot01–06）
├── macfarlane1989.pdf / .md     # MacFarlane 1989 参考文献及笔记
├── README.txt                   # 本目录原始说明
└── _init_.py                    # Python 包标记
```

> 同级还有 `Ionmix_run/`（运行工作目录），同样被忽略。

### 3. Multi1D++ 软件 — `flash/input_gen/gen_eos_op/src/`

Multi1D++ 便携版（Windows 可执行程序集）及相关文档、源码整理：

```
flash/input_gen/gen_eos_op/src/
├── Multi1D++***.rar    # 原始便携压缩包
├── Multi1D++***/       # 解压后程序集
│   ├── Multi1D++.exe / Multi1D.exe / multi7.exe
│   ├── GUI4Multi1D.exe
│   ├── FEOS.exe / Ioniz.exe / Snop++.exe / snop.exe / ShowEOS.exe / mpqeos.exe
│   ├── MULTIfs.exe
│   ├── FEOS_Material-DB.dat / FEOS_TF-Table_1197.dat   # 材料数据库 / TF 表
│   ├── Flux0.dat / Flux3ns.dat      # 激光通量数据
│   ├── cases_simple / cases_1988CPC / cases_Experiments / cases_HotElectrons
│   ├── cases_M1_78 / cases_RadiativeShock / cases_ZhangLu
│   ├── cases_multi-ife / cases_multifs   # 各算例集
│   ├── doc / templates / tools / matlab / matter++ / tabelle
│   ├── gnuplot.exe / wgnuplot.exe / ZedGraph.dll / gsl.dll / gslcblas.dll
│   └── default.ini / settings.ini / Changes.log
├── multi_docs/                      # 文档
└── multi_src/                       # 源码整理（01_inventory … 09_source_verify 编号目录、MANIFEST.tsv、README.md）
```

### 4. SNB 场景建立相关 F90 源码 — `flash/scenarios/private/SNB/SNB/`

SNB（Scherbet–Nugent–Bulanov 非局域热传导）场景的核心 Fortran 源码与变体
（私有场景，整目录被忽略）：

```
flash/scenarios/private/SNB/SNB/
├── source/snb_package/             # SNB 主包（编译集成用核心 F90）
│   ├── Conductivity.F90            # 电导率/热传导系数
│   ├── diff_advanceTherm.F90       # 热扩散推进（SNB 修改版）
│   ├── Driver_evolveFlash.F90      # 驱动演化（含辐射开关逻辑）
│   ├── Grid_advanceDiffusion.F90   # 网格级扩散求解接口
│   ├── mgd_qesh.F90                # MGD 群能量源项
│   ├── Simulation_data.F90 / Simulation_init.F90 / Simulation_initBlock.F90
│   ├── hy_uhd_dataReconstOneStep.F90
│   ├── hy_uhd_DataReconstructNormalDir_PPM.F90
│   ├── hy_uhd_getRiemannState.F90
│   └── hy_uhd_ragelike.F90
├── source/stock_sh/                # FL-SH（限流 Spitzer–Härm）对照版
│   └── diff_advanceTherm.F90
├── variants/                       # 变体源码
│   ├── diff_advanceTherm_limiterON.F90   # 限流器开启变体
│   └── Driver_evolveFlash_radON.F90      # 辐射开启变体
├── tools_local/make_variants.py    # 变体生成工具
├── scripts/                        # snb_params.py / check_share_safety.py
└── docs/                           # 设置方法 / 端到端流程 / 编译依赖 / 坑位清单等（01–10）
```

---

## 许可

flash-sim 采用**双重许可结构**，并严格遵守 [FLASH License Agreement](docs/license_agreement.txt)（官方协议全文见 `docs/license_agreement.txt`）：

| 组件 | 许可 | 说明 |
|------|------|------|
| **flash-sim Python 代码** | [Apache 2.0](LICENSE) | PhySimX Contributors 原创 wrapper / 工具 / 工作流代码 |
| **FLASH 仿真引擎** | [FLASH License Agreement](https://flash.rochester.edu) | 由 Flash Center for Computational Science 开发维护 |
| **PlasmaPy（vendor 快照）** | [BSD 3-Clause](flash/output_pro/PlasmaPy/src/PlasmaPy/LICENSE.md) | PlasmaPy Developers © 2015–2026；随包分发的**未修改**源码快照 v2026.2.0（`output_pro/PlasmaPy/src/PlasmaPy/`），版权与免责声明见 [NOTICE](NOTICE) |

**重要说明（依据 FLASH License Agreement）：**

- **本包不包含、亦不再分发** FLASH 源代码、二进制、源码包、SimulationMain 示例（含 LaserSlab）、FLASH 分发的 EOS/不透明度表（`*.cn4` 等）、FLASH 用户手册、IONMIX 源码或 MultiEOS 数据（协议 §3 禁止用户再分发 FLASH Code 及其任何组件）。
- 用户必须从 [flash.rochester.edu](https://flash.rochester.edu) **独立获取** FLASH 并接受其许可协议后才能使用本包。
- 包内场景输入中的部分 `.F90` 文件（如 `Simulation_data.F90` 等）是 FLASH 示例问题的**修改版**，已按协议 §4(a) 在文件头与 [NOTICE](NOTICE) 中声明修改、保留 FLASH 头（§4(c)）并显示致谢（§4(b)）。
- FLASH 的商业使用需获得 Flash Center 主任的事先书面批准（FLASH License §5）。
- 使用 FLASH 的所有出版物必须致谢 Flash Center（详见 [NOTICE](NOTICE) 文件）。
- **PlasmaPy 边界声明**：随包 vendor 的 PlasmaPy 源码（BSD-3）是 PlasmaPy Developers 的独立项目，**不受** FLASH License §3 再分发限制约束，也不属于 flash-sim Apache-2.0 覆盖范围；flash 与 PlasmaPy 的集成层 `plasmapy_bridge.py` 为 Apache-2.0。依赖 PlasmaPy 功能的出版物请同时致谢并引用 PlasmaPy（`CITATION.cff`）。

### flash-sim 包附加条款：PhySimX 团队致谢与商用说明

flash-sim（flash 仿真辅助 Python 包）由**绵阳市的 PhySimX 团队**原创开发。除 FLASH Center 的致谢要求外，另有以下附加条款：

**出版物致谢（Publications Acknowledgment）**

使用 flash-sim 产生的任何出版物，请在致谢部分感谢**绵阳市的 PhySimX 团队**开发了该仿真辅助 Python 包。建议致谢文案：

> "We acknowledge the PhySimX team (Mianyang, China) for developing the flash-sim auxiliary Python package used in this work."

**商用说明（Commercial Use）**

flash-sim 的 Python 代码以 Apache 2.0 许可，但其商用须遵守所有适用许可条款，包括 FLASH 仿真引擎的 [FLASH License Agreement](https://flash.rochester.edu) §5（商用须经 Flash Center 主任事先书面批准）。本包由绵阳市的 PhySimX 团队原创开发，商用场景下的授权与责任以届时适用的许可及书面约定为准。

> 注：Apache 2.0 仅覆盖本包的 Python 代码，不授予 FLASH 仿真引擎的任何商用权利；flash-sim 不对任何商用后果作担保。

### 第三方致谢：FLASH-Expert（AI 知识库）

本仓库 `skills/flash-knowledge`（FLASH 源码级知识导航）、`skills/flash-pitfalls`（报错速查库）及
`docs/reference/param_index_flash48.md`（FLASH 4.8 参数索引）的部分内容，整理/转写自
**FLASH-Expert** 项目——由 **xubo（boxu-pku，北京大学）** 开发的 FLASH 4.8 多 harness AI 专家
skill 系统（知识层 11 单元 + 工具层 5 + 操作层 2）。特此致谢！

- 上游仓库：<https://github.com/boxu-pku/FLASH-Expert>
- 本仓吸收基准：上游 commit `25013c5`（2026-11-06 收纳，各产物头部均有「上游：FLASH-Expert @ 25013c5」标注）
- 使用说明：上游原文以浅克隆形式存放于 `temp/FLASH-Expert/`（不入 git），仅作本机更新通道；吸收产物为精华转写并保留源码锚点，未整体再分发原文
- 上游许可：**仅供学术研究使用**；FLASH 4.8 本身遵循 [FLASH Code License](https://flash.uchicago.edu/site/license/)。使用本仓上述 skill 的出版物，建议同时致谢 FLASH-Expert 作者

© 2026 PhySimX Contributors. Apache 2.0 License.

---

> **flash-sim** — Build FLASH simulations smarter, not harder. ⚡


---

# flash-sim — English Overview

> **Sync rule**: the Chinese main body (above) is authoritative — update it first,
> then mirror §Overview / §Architecture / §Directory map / §Quick start here.
> Last synced: 2026-11-05 (module paths updated to `scenarios/core/{scene_reg,entry,engine,hpc}` layout;
> the former config/ package was merged into `flash/_core/config.py`).

**flash-sim** is a full-featured Python interface and automation toolkit for the
[FLASH](https://flash.rochester.edu) high-energy-density physics (HEDP) simulation
code. It provides an end-to-end workflow: physics scenario design → `.par` file
generation → FLASH compile & run → HDF5 output processing → adaptive visualization
(1D/2D/3D) and physical analysis.

> **Status**: the release package passes the global test suite
> (**436 passed / 2 skipped**: framework 293 / input_gen 86 / output_pro 57)
> and the FLASH license-compliance check; all **35 registered scenarios** pass
> local WSL short-run end-to-end verification (`tmax=1e-11`). The
> offline-deployment self-check adds **183 further checks**
> (`deploy/test_offline_install.py`).
> **Scope note**: this package does **not** redistribute any FLASH source,
> binaries, distributed EOS/opacity tables or IONMIX/MultiEOS data (FLASH License §3).

## Repository

Mirrored on **Gitee** (primary development host) and **GitHub**:

```
Gitee  : https://gitee.com/physimx/flash
GitHub : https://github.com/QuincyHoward/flash
```

Clone with HTTPS:

```
git clone https://gitee.com/physimx/flash.git
git clone https://github.com/QuincyHoward/flash.git
```

## Key Features

- **Scenario System** (`scenarios/`): declarative `SimulationScenario` definitions,
  a registry (`get_scenario()` / `list_scenarios()`), and a unified
  `FlashSimulatorEngine` that integrates WSL/remote execution, checkpoint
  collection, interpolation and result output.
  **35 registered scenarios** (public demos + private research families) are
  discoverable via zero-registration `scene.json` manifests and driven through
  one CLI: `python -m flash.scenarios list | run <scene> --mode auto|local|wsl|hpc-remote`
  (platform-adaptive targeting, `--tmax` short-run verification, HPC `submit`).
  Built-in (distributed) scenarios: `ch_center`, `grad_dens_sandwich`,
  `thin_layer_sandwich_si`, `thin_layer_sandwich_al`.
- **Research scenario families** (private, not distributed): the **SNB
  non-local electron-transport line** (`scenarios/private/SNB/`, a shareable
  method/tooling module + `SNBtest/Test/t001…t006`) and the **tracer line**
  (`scenarios/private/tracer/`: `layer_tracer_CH`, `VCH_ml`, `OneCH_ml`,
  `CHTi`, `TiTi`, `OneSi_ml`, `OneC_ml` and their no-radiation `_F` variants,
  plus `tracer/SNB/SNBOneCH{,_ml}` as local-vs-nonlocal counterparts).
- **Generated Scenario Inputs** (no static `flash_input/` in the repo): FLASH
  source files (`.par` / `Config` / `Makefile` / `*.F90` / EOS `.cn4` tables)
  are produced on demand by `gen_flash_inputs.py` (powered by the `input_gen`
  package); the scenario's `ensure_sim_input()` and the engine auto-generate
  them before a run, so clean clones and published wheels work out of the box.
- **Self-Healing One-Command Setup** (`start_flash.py`): creates the project
  venv (`.venv-win` / `.venv-linux` / `.venv-mac`, one per platform),
  health-checks it (key dependencies importable + pytest launchable),
  **automatically rebuilds from scratch when unhealthy**, re-runs the global
  test suites if pytest crashes at startup, and writes an
  `test/reports/INSTALL_TEST_REPORT.txt` including a **dependency version snapshot**.
  It is also the single entry point for air-gapped deployment
  (`--make-wheelhouse` / `--export-usb` / `--offline` / `--check` / `--no-tests`).
  ★ A venv belonging to the *other* platform is detected and **kept, never
  deleted**, so switching between Windows and WSL is safe.
- **Input Generation** (`input_gen/`): a family of generators
  (`gen_par` / `gen_config` / `gen_makefile` / `gen_sim_data` / `gen_sim_init` /
  `gen_sim_initblock` / `gen_shell_script`), EOS & opacity table tooling
  (`gen_eos_op` hosts the self-generated `*.cn4` tables), multi-zone density
  profiles (`gen_newpara`), FLYCHK-history input generation
  (`gen_flychk_his`), and a dependency checker (`gen_checker`).
- **Output Processing** (`output_pro/`): HDF5 loading (1D/2D/3D) that is
  byte-compatible with real FLASH files (incl. WSL `(n,1)` `unknown names`
  layout), derived variables (`nele = ye·dens·N_A`, `nion`, `zbar`, gradient
  scale lengths …), unit conversion, batch/lazy/parallel loading, AMR
  visualization, and **space-time (x-t) maps** (`FlashPlotter.plot_xt_map` /
  `collect_xt` / `time_uniformity`).
  ⚠ x-t maps are rendered with `pcolormesh` using the **true per-frame times**
  — FLASH checkpoints are written every *N steps*, so their Δt is often highly
  non-uniform (measured 52.7× on an AMR run) and `imshow` would distort the
  time axis.
- **PlasmaPy Bridge** (`output_pro/plasmapy_bridge.py`, new in 0.1.15):
  converts FLASH grid quantities into astropy-units-aware `Quantity` arrays and
  exposes unit-safe plasma diagnostics via
  [PlasmaPy](https://github.com/PlasmaPy/PlasmaPy) — Coulomb logarithm lnΛ,
  Debye length λ_D, Spitzer/Braginskii electron thermal conductivity κ_e,
  electron mean free path and Knudsen number K_n = λ_mfp/L_Te, quantum
  degeneracy parameter Θ_e, ion coupling Γ, Saha ionization Z̄, and the
  0.351 μm critical-density surface n_c. Gracefully degrades when PlasmaPy is
  absent (`HAS_PLASMAPY=False`). PlasmaPy 2026.2.0 is **vendored** as a source
  snapshot (`output_pro/PlasmaPy/src/PlasmaPy`, BSD-3); editable install on
  win/wsl via `output_pro/PlasmaPy/install_editable.py`, offline wheel bundle
  on HPC (see `DEPENDENCIES.md`).
- **Share-safety gate** (`scenarios/private/SNB/SNB/scripts/check_share_safety.py`):
  a mandatory pre-publish check with three gates — file type, protected
  directories, and content (source/binary **blacklist** scan over the *staged ∪
  untracked ∪ modified* set; fails closed if git cannot be queried). It keeps
  FLASH source, F90-emitting scripts, algorithm fragments and credentials out
  of any public release.
- **Multi-Environment Execution**: local WSL (Ubuntu) and HPC clusters over SSH
  (ParaCloud), with SLURM/SBATCH support.
- **Credential Management** (`_core/credentials/`): encrypted storage for Gitee
  tokens, SSH accounts and API keys (read-only for agents; user-managed).
- **No-Prompt Gitee Integration**: HTTPS auth through a **git credential helper**
  (`scripts/03_git_publish/_git_auth.py` + `_git_credential_helper.py`) that reads
  the encrypted store at push time and hands the token to git over a **pipe** —
  the token never lands in `.git/config` and never shows up in `argv`
  (invisible to `ps`). All other credential helpers and askpass are cleared, so
  `git push` never pops a dialog.
- **Dual Mode**: standalone Python package (`flash.*`) or PhySimX plugin
  (`physimx_sim.flash.*`).

## Air-Gapped Deployment (offline install)

For sites without internet access, `start_flash.py` is the **single entry
point** for the whole workflow — building the wheelhouse, exporting to USB,
installing and testing. It only *forwards* to the underlying scripts
(`build_wheelhouse.py` / `usb_backup.py`), so the logic never drifts and those
scripts remain independently runnable.

```bash
# --- connected machine ---
python start_flash.py --make-wheelhouse                # build the wheelhouse
python start_flash.py --make-wheelhouse --export-profile lite
python start_flash.py --export-usb /media/usb/pkg     # export sources + wheels

# --- air-gapped machine ---
python start_flash.py --offline --wheelhouse D:\pkg\wheelhouse   # install + test
python start_flash.py --offline --check               # verify only, changes nothing
python start_flash.py --offline --no-tests            # fast install, skip the suites

# --- online machine ---
python start_flash.py                                 # install + test + report
python start_flash.py --no-tests                      # install only
```

**Deployment target (2026-10-24)** — one entry point for both local install and the
HPC chain, so you no longer have to remember two separate command sets:

```bash
python start_flash.py --target auto|win|wsl|hpc
python start_flash.py --target hpc -- --only 05b   # everything after `--` goes to hpc_deploy/run_all.py
```

Four gates run **before** anything is created or modified — any failure aborts
without leaving a half-built venv:

1. **wheelhouse exists** and contains `MANIFEST.json`
2. **manifest verification** — presence + size + **SHA256** of every archive
   (USB transfer is the most likely place for silent corruption)
3. **platform / Python version match** — wheel names carry `cp3XX` ABI tags, so
   a cross-version install is impossible; pip only says *"No matching
   distribution found"* and never mentions the version, so this is checked
   explicitly and reported with an actionable fix
4. **dependency coverage** — `pyproject.toml`'s closure must be ⊆ wheelhouse

`--no-index` is the hard gate: pip physically cannot reach PyPI.

**No `apt` required on Linux/WSL.** Ubuntu ships without `python3.x-venv`, so
`python3 -m venv` normally fails with *ensurepip is not available*. The script
detects this and **bootstraps pip offline** from the `pip-*.whl` already shipped
inside the wheelhouse (`--without-pip` skeleton → install pip from the local
wheel), so an air-gapped machine needs no network and no system packages.

**Platform-isolated venv.** The venv directory carries a platform suffix —
`Windows → .venv-win`, `Linux/WSL → .venv-linux`, `macOS → .venv-mac`. The two
*cannot* share one directory (the interpreter is PE vs ELF, and compiled wheels
are `win_amd64` vs `manylinux`). With separate directories you can **switch
freely between Windows and WSL**: each side keeps its own environment, and the
other platform's venv is **never deleted**.

**Sizes differ by platform — and that is expected.** `full` measures
130 MB / 71 packages on Windows (Python 3.13) but 165 MB / 78 packages on Linux
(Python 3.10). The difference is driven mainly by the **Python version** (3.10
needs `typing-extensions` / `tomli` / `exceptiongroup` shims, and pandas drops
to 2.x), not the OS. **Use the same Python version on both machines.**

## Quick Start

```python
from flash.scenarios.core.registry import get_scenario
from flash.scenarios.core.simulator import FlashSimulatorEngine

scenario = get_scenario("thin_layer_sandwich_si")
engine = FlashSimulatorEngine(scenario, verbose=True)
output = engine.run(run_flash=False)   # dry-run: generate inputs only
```

One-command setup + global test (self-healing):

```bash
python start_flash.py     # venv check → auto-rebuild if broken → 3 test suites → report
python start_flash.py --no-tests   # install the environment only
```

Run the built-in 1D LaserSlab scenario with platform auto-detection:

```bash
# Recommended (2026-10-24): the unified CLI, --mode defaults to auto
python -m flash.scenarios.core.entry.cli run ch_center                # auto: Win→wsl, Linux→local, login node→hpc-insitu
python -m flash.scenarios.core.entry.cli run ch_center --mode hpc-insitu
python -m flash.scenarios.core.entry.cli explain ch_center            # print the decision trace only
python -m flash.scenarios.core.entry.cli list

# Running the scene script directly still works, but it has **no argparse** —
# the mode can only be set via the environment variable (a `--mode` flag is ignored):
export FLASH_RUN_MODE=hpc-insitu      # bash
set FLASH_RUN_MODE=hpc-insitu         # Windows CMD
.venv-win\Scripts\python.exe flash\scenarios\center_evolution\ch_center\laserslab1d_local_custom.py
```

**Execution targets** (`EXEC_TARGETS`, 2026-10-24): `local` | `wsl` | `hpc-remote` | `hpc-insitu`

| Order | Probe | Target |
|---|---|---|
| 1 | `sbatch` + `sacct` + `sinfo` all present | `hpc-insitu` (on login node, no self-SSH) |
| 2 | POSIX native (`os.name != "nt"`) | `local` |
| 3 | Windows with `wsl` on PATH | `wsl` |
| 4 | none of the above | explicit error with the probe trace |

`--mode` and `FLASH_RUN_MODE` always override. The legacy `RUN_MODES` triple is
kept as an alias layer (`hpc` → `hpc-remote`), so existing scripts keep working.
Scenarios may restrict the allowed set (e.g. the SNB family allows only
`hpc-remote`/`hpc-insitu` and refuses to run locally).

The FLASH installation directory is resolved automatically: the
`FLASH_SIM_USER_DIR` environment variable → the encrypted credential store →
a scan of `$HOME/*/FLASH/FLASH4.8` → the literal `hello`. The scan matters
because clean clones and air-gapped machines have no `credentials.enc`.

Virtual-environment lookup lives in **one** place
(`flash/flash_run/env/venv_paths.py`, stdlib-only): `FLASH_VENV_DIR` >
`<repo>/.venv-<platform>` > legacy `.venv`; on the HPC side it is
`<TARGET>/.venv-hpc-nce`. It never falls back to `sys.executable`.

**Documentation entry points (2026-10-24)**:

- [`flash/flash_run/README.md`](flash/flash_run/README.md) — unified
  run-management doc (merged from README + PROCESS): module map,
  execution-target decision table, username rules (never hardcode —
  `FLASH_SIM_USER_DIR` > credential store > default `hello`), and the
  engineering rules learned from real failures;
- [`flash/scenarios/public/center_evolution/ch_center/README.md`](flash/scenarios/public/center_evolution/ch_center/README.md) — reference
  scenario: physics setup, five execution modes with parameter switching,
  input regeneration;
- [`flash/scenarios/public/center_evolution/ch_center/modes_test/`](flash/scenarios/public/center_evolution/ch_center/modes_test/) — same-case
  cross-mode comparison harness (`win-wsl` / `wsl-wsl` / `win-hpc` /
  `wsl-hpc` / `hpc-insitu`) with dens/nele evolution analysis.

Generate scenario input files explicitly (optional; normally auto-generated):

```bash
python flash/scenarios/public/center_evolution/ch_center/gen_flash_inputs.py --check   # 0=ready / 1=missing
python flash/scenarios/public/center_evolution/ch_center/gen_flash_inputs.py --force   # regenerate all
```

Environment self-check (usable as a gate — non-zero exit on findings):

```bash
python -m flash.flash_run.modes.runner --check-env --strict
```

Distribution note (2026-10-24): the sdist shrank from 37.5 MB to **4.6 MB** and now
ships `deploy/_wh_common.py` + `deploy/install_offline.py`, so
"unpack sdist → offline install" works (previously the whole `deploy/` directory
was excluded and the offline preflight aborted).

See [README.md] (Chinese) for the full documentation, the
[changelog](PhySimX_flash_CHANGELOG.md), or run the global test suite:

```bash
python scripts/05_test/run_global_tests.py     # framework + input + output suites
```

## License

flash-sim is dual-licensed: the Python wrapper/tool code is **Apache 2.0**
(© 2026 PhySimX Contributors); the FLASH simulation engine is governed by the
separate [FLASH License Agreement](https://flash.rochester.edu). This package
does **not** redistribute any FLASH source code, binaries, distributed EOS /
opacity tables (`*.cn4` etc.), user manuals, IONMIX sources or MultiEOS data
(per §3 of the FLASH License). Obtain FLASH independently from
[flash.rochester.edu](https://flash.rochester.edu).

**PlasmaPy (vendored snapshot, BSD 3-Clause).** This package redistributes an
**unmodified** source snapshot of PlasmaPy v2026.2.0
(`flash/output_pro/PlasmaPy/src/PlasmaPy/`), Copyright (c) 2015–2026,
PlasmaPy Developers, under the BSD 3-Clause License (full text and disclaimer
in the vendored `LICENSE.md`; attribution in [NOTICE](NOTICE)). PlasmaPy is an
independent project (https://www.plasmapy.org) — it is not a FLASH component
and is not covered by the FLASH License Agreement or by the Apache 2.0 license
of flash-sim. The flash-sim integration layer (`plasmapy_bridge.py`) is
Apache 2.0. Publications relying on PlasmaPy functionality should acknowledge
and cite PlasmaPy (see the vendored `CITATION.cff`).

**flash-sim Package — PhySimX Team Attribution (additional terms)**

*Publications Acknowledgment.* Any publication resulting from the use of
flash-sim (the flash auxiliary Python package) should acknowledge the
**PhySimX team (Mianyang, China)** for developing this auxiliary
Python package. Suggested text: "We acknowledge the PhySimX team
(Mianyang, China) for developing the flash-sim auxiliary Python
package used in this work."

*Commercial Use.* The flash-sim Python code is released under Apache 2.0,
but any commercial use must comply with all applicable licenses, including
Section 5 of the FLASH License Agreement (commercial use of FLASH requires
prior written approval from the Director of the Flash Center). flash-sim was
originally developed by the PhySimX team (Mianyang, China); commercial
licensing and liability are governed by the applicable license and any
written agreement in force at the time. The Apache 2.0 license covers only
the flash-sim Python code and does not grant any commercial rights to the
FLASH simulation engine.

## Contact

- Repository (Gitee): https://gitee.com/physimx/flash
- Repository (GitHub): https://github.com/QuincyHoward/flash
- Issues & feedback: via Gitee Issues or GitHub Issues

*English overview generated for search-engine discoverability. The authoritative
documentation remains the Chinese README above.*

