# GURU — руководство по `guru-hugoniot` (RU, с учетом фаз)

**Назначение.** Решает условие Ранкина—Хюгонио вдоль **изотерм** и/или **изохор**, используя термоданные из `guru-thermo` и начальное состояние от `guru-iso-fit` (предпочтительно) или `guru-thermo`. Если присутствует столбец `phase` (например, из `guru-thermo-phase`), каждая сгруппированная кривая **разбивается по фазам** и обрабатывается отдельно, с явным приоритетом **неэкстраполированных** решений.

---

## Уравнение Хюгонио

Энергетическая форма соотношения Ранкина—Хюгонио:

$$
(E - E_0) + \frac{1}{2} \bigl(V - V_0\bigr) \bigl(P + P_0\bigr) = 0
$$

Единицы, ожидаемые инструментами GURU:

* $E, E_0$ — **эВ/атом** (внутри конвертируется в Дж/атом),
* $P, P_0$ — **кбар** (переводится в Па),
* $V, V_0$ — **см³/г** (пересчитывается в м³/атом с использованием молярной массы $M_a$).

Все преобразования используют константы SciPy/CODATA.

---

## Синтаксис

```bash
guru-hugoniot --Ma MOLAR_MASS \
  [--initial init.tsv | (--grid-eos EOS.tsv [--grid-init-T T0 --grid-init-rho R0])] \
  [-i data1.tsv ...] [--rho0 R0] \
  [--curves both|iso|rho] [--group-dT 20] [--group-drho 0.01] \
  [--interp pchip|linear] \
  [--grid-step-T 50 --grid-step-rho 0.05 \
   --grid-T-min Tmin --grid-T-max Tmax \
   --grid-rho-min Rmin --grid-rho-max Rmax \
   --extrap-frac 0.10 --combine concat|avg] \
  [-o hugoniot_full.tsv \
   --out-compact hugoniot_compact.tsv [--compact-with-velocity] [--compact-extra-units]] \
  [--plot [--plot-prefix PREFIX]] [--progress|--no-progress] \
  [--u0 U0_KMS] [--P0 P0_KBAR] [--E0 E0_EV]
```

**Обязательные параметры**

* `--initial` — эталонное состояние (TSV), допустимые форматы:

  * из **изотермы `guru-iso-fit`**: заголовок `T  P  E  V  rho ...`,
  * из **изохоры `guru-iso-fit`** : заголовок `rho  P  E  T ...`,
  * из **`guru-thermo --out`**    : использует поля `*_mean` (если есть `density_g_cm3`),
  * **компактный `T P E`**        : допустим; тогда передайте `--rho0`.
* `--Ma` — молярная масса (г/моль) для преобразования $V$ в м³/атом.

**Термоданные (режим выборок)**

* `-i` — один или несколько TSV (компактный формат `T P E` или расширенный `--out`). Если есть столбец **`phase`**, включается фазовая логика.

**Режим сетки EOS (интерполяция по прямоугольной сетке)**

* `--grid-eos` — прямоугольная сетка EOS в TSV со столбцами `T`, `rho`, `P`, `E` (или `E_atom`).
* Необязательная ручная стартовая точка из сетки:
  * `--grid-init-T`, `--grid-init-rho` — задать T0, ρ0; `P0` и `E0` берутся интерполяцией из сетки; `V0=1/ρ0`.
* Управление сканированием:
  * `--grid-step-T` (K), `--grid-step-rho` (г/см³) — шаги по изотермам/изохорам.
  * `--grid-T-min/max`, `--grid-rho-min/max` — явные границы; по умолчанию берутся из сетки и расширяются на `± --extrap-frac * span`.
  * `--extrap-frac` — допускаемая доля экстраполяции за края сетки (по умолчанию 10%).
* Объединение семейств, когда `--curves both`:
  * `--combine concat` — объединить списки решений;
  * `--combine avg` — сопоставить ближайшие по давлению пары «изотерма/изохора» и вывести их средние P,T,ρ.

**Прогресс и графики**

* `--progress` / `--no-progress` — вкл/выкл отображение прогресса (stderr). В режиме сетки показываются этапы “hugoniot iso/rho”.
* `--plot` — сохранить PNG-графики (см. ниже). `--plot-prefix` — префикс для имён файлов (по умолчанию на основе `--out`).
* Повторный удар (double shock): `--u0` — начальная скорость вещества (км/с). Если задано (не 0), выводим
  скоростью частицы $U^* = u_0 - U$, так как вещество уже движется до скачка.
* Переопределения начального состояния: `--P0` (кбар) и/или `--E0` (эВ/атом) задают значения, имеющие приоритет над данными из initial TSV или сетки.

---

## Интерполяция и поиск корня

Для каждой кандидатной кривой (кривая × фаза):

* Строятся два интерполянта:
  * **Изотерма**: $E(V)$ и $P(V)$ по $V=1/\rho$,
  * **Изохора**: $E(T)$ и $P(T)$ по $T$.
* В режиме выборок: `pchip` (по умолчанию, форма‑сохраняющий) или `linear`.
* Ищется смена знака остатка Хюгонио между соседними опорными точками, затем корень уточняется **бисекцией**.
* Если знака нет, пробуется **симметричная экстраполяция** на одну «ширину» за предел данных; такое решение помечается как экстраполированное.

### Интерполяция в режиме сетки (прямоугольная EOS)

Используется раздельная PCHIP‑интерполяция по осям (“PCHIP2D”), сохраняющая монотонность и избегающая осцилляций:

- Для каждого столбца по ρ строится 1D PCHIP по T.
- В нужной T вычисляются значения по всем ρ, затем PCHIP по ρ (аналогично для E).
- Экстраполяция управляется `--extrap-frac` через расширение области сканирования.

### Режим сетки: поиск «скобки» и решатель

- Остаток Хюгонио считается в согласованных **СИ‑единицах** на атом (как и в режиме выборок).
- «Скобка» для корня сначала ищется на узлах исходной сетки (`Tvec`, `Rvec`), затем корень уточняется при помощи **`brentq`** (быстрее и столь же надёжно, как бисекция).
- При отсутствии скобки по узлам выполняется краткий грубый просмотр равномерной сеткой только локально.
- Практические оговорки: при задании `--grid-init-T` скан по изотермам стартует от этой температуры; если базовая сетка неотрицательна по T или ρ, нижние границы принудительно ≥ 0, а ρ=0 избегается в операциях с обратной величиной.

---

## Вывод

Основной TSV содержит колонки:

```
curve_type  label  P[kbar]  T[K]  rho[g/cm^3]  is_extrapolated  phase  rho/rho0  D[km/s]  U[km/s]
```

* `curve_type` — `isotherm` или `isochor`.
* `label` — например, `T=300.0K` или `rho=8.9000g/cm^3`.
* `P[kbar]`, `T[K]`, `rho[g/cm^3]` — найденная точка Хюгонио.
* `is_extrapolated` — `0` (внутри интервала) или `1` (экстраполяция).
* `phase` — фазовая метка (целое), если была в исходных данных.
* `rho/rho0` — степень сжатия $r = \rho/\rho_0$.
* `D[km/s]` — скорость ударной волны: \( D = \tfrac{1}{10^3} \sqrt{ \tfrac{ P\cdot10^8\, \rho }{ \rho_0\cdot10^3\, (\rho-\rho_0) } } \).
* `U[km/s]` — массовая скорость частиц: \( U = D\,(1 - 1/r) \).

### Компактный вывод (опционально)

Передайте `--out-compact compact.tsv`, чтобы записать урезанную таблицу:

```
P[kbar]  T[K]  rho[g/cm^3]
```

Опции:

- `--compact-with-velocity` — добавить `D[km/s]`, `U[km/s]`.
- `--compact-extra-units` — добавить `P[GPa]` и `T[kK]`.

### Графики (опционально)

`--plot` сохраняет PNG‑графики: P–rho, P–T, T–rho, D–U, P–u. В режиме сетки рисуются **линии**, в режиме выборок — **точки**. Префикс задаётся `--plot-prefix` (по умолчанию из `--out`).

---

## Группировка и учет фаз

### Группировка кривых

* **Изотермы**: группировка по $T$ с шагом `--group-dT` (по умолчанию 20 K). Сортировка по **убыванию плотности** (возрастающему $V = 1/\rho$).
* **Изохоры**: группировка по $\rho$ с шагом `--group-drho` (по умолчанию 0.01 г/см³). Сортировка по **возрастанию $T$**.
* Для построения интерполянтов требуется **не менее 2 точек** на кривую.

### Разделение по фазам и приоритеты

Если присутствует столбец `phase`:

1. Разбить кривую по различным целочисленным значениям `phase`.
2. **Пробовать решения в пределах интервала (без экстраполяции)** для каждой фазы. Если хоть одно успешно, **выбрать вариант с наибольшей поддержкой данными** (больше точек) и **пропустить** остальные фазы для этой кривой.
3. Если решений в пределах интервала нет, **разрешить экстраполяцию**; среди экстраполированных кандидатов выбрать тот, у которого **минимальное нормированное расстояние** за пределами диапазона данных.

Без столбца `phase` вся кривая рассматривается как единый набор.

---

## Интерполяция и поиск корня

Для каждого кандидата (кривая × фаза):

* Построить две интерполяции:

  * **Изотерма**: $E(V)$ и $P(V)$ как функции $V = 1/\rho$,
  * **Изохора** : $E(T)$ и $P(T)$ как функции $T$.
* Для режима выборок: `pchip` (формосохраняющий; по умолчанию) или `linear`.
* Найти смену знака невязки Хюгонио между соседними точками и определить корень методом **дихотомии**.
* Если смены знака нет, попробовать **одну симметричную экстраполированную скобку** (на один шаг шире данных); пометить решение как экстраполированное.

### Интерполяция в режиме сетки (прямоугольная EOS)

Чтобы корректно описывать резкие особенности (например, фазовые переходы) **без лишних осцилляций**, в режиме сетки используется разделённая формосохраняющая схема («PCHIP2D»):

- Для каждого столбца по ρ строится 1D‑PCHIP по T.
- При заданном T вычисляются значения в столбцах P(T,ρ_j) (и E аналогично), после чего выполняется PCHIP по ρ.
- Экстраполяция использует крайние угловые коэффициенты PCHIP и ограничивается границами сканирования `--extrap-frac`.

---

## Выходные данные

Столбцы (TSV):

```
curve_type  label P[kbar] T[K]  rho[g/cm^3] is_extrapolated phase rho/rho0  D[km/s] U[km/s]
```

* `curve_type` — `isotherm` или `isochor`.
* `label` — например, `T=300.0K` или `rho=8.9000g/cm^3`.
* `P[kbar]`, `T[K]`, `rho[g/cm^3]` — точка Хюгонио.
* `is_extrapolated` — `0` (внутри диапазона) или `1` (экстраполяция).
* `phase` — целочисленный фазовый ярлык, если он был в исходных данных.
* `rho/rho0` — степень сжатия; \( r = \rho / \rho_0 \).
* `D[km/s]` — скорость ударной волны;
  \[ D = 10^{-3}\,\sqrt{ \dfrac{ (P - P_0)\,[\mathrm{Па}]\; \rho\,[\mathrm{кг/м^3}] }{ \rho_0\,[\mathrm{кг/м^3}]\; (\rho - \rho_0)\,[\mathrm{кг/м^3}] } } \],
  эквивалентно из уравнений импульса и непрерывности.
* `U[km/s]` — скорость частицы;
  \[ U = 10^{-3}\,\sqrt{ \dfrac{ (P - P_0)\,[\mathrm{Па}]\; (\rho - \rho_0)\,[\mathrm{кг/м^3}] }{ \rho\,[\mathrm{кг/м^3}]\; \rho_0\,[\mathrm{кг/м^3}] } } \]
  (эквивалентно $U = D\,(1 - \rho_0/\rho)$).
  При `--u0` в таблицу выводится $U^* = u_0 - U$.

---

## Примеры

```bash
# Обе семьи, интерполяция PCHIP
guru-hugoniot --initial init_T300.tsv --Ma 27.0 \
  -i isotherms/T300/*.tsv --curves both --interp pchip -o hugo_T300.tsv
```

```bash
# Учет фаз: термоданные со столбцом `phase`
guru-hugoniot --initial ep0.tsv --Ma 63.5 \
  -i thermo_with_phase_T300.tsv thermo_with_phase_T500.tsv \
  --curves both -o hugo_phase.tsv
```

```bash
# Компактные термоданные (в исходном нет плотности), передайте rho0 явно
guru-hugoniot --initial init_compact.tsv --rho0 8.90 --Ma 26.98 \
  -i compact_*.tsv -o hugo.tsv
```

```bash
# Сетка EOS: изотермы со стартовой точкой по сетке + компактный вывод и графики
guru-hugoniot --Ma 20.18 \
  --grid-eos EOS_grid.tsv --grid-init-T 19000 --grid-init-rho 0.96 \
  --curves iso --grid-step-T 100 --extrap-frac 0.1 \
  -o hug_grid_iso.tsv --out-compact hug_grid_iso_compact.tsv \
  --compact-with-velocity --compact-extra-units --plot --plot-prefix hug_grid
```

```bash
# Сетка EOS: обе семьи и усреднение
guru-hugoniot --Ma 20.18 --grid-eos EOS_grid.tsv \
  --curves both --combine avg --grid-step-T 100 --grid-step-rho 0.05 \
  -o hug_grid_avg.tsv
```

---

## Диагностика

* **«Initial state lacks density; supply --rho0.»** Укажите `--rho0` (г/см³), если в исходном TSV нет плотности.
* **«No thermo rows in input files.»** Проверьте заголовки; предпочтительнее вывод `guru-thermo --out` или `--dump-log`.
* **Только экстраполированные решения.** Расширьте диапазон выборки или уточните `--group-dT`/`--group-drho`, чтобы не смешивать разные кривые.
* **Неожиданное смешение фаз.** Постройте `phase` с помощью `guru-thermo-phase` и убедитесь, что подмножество точек по каждой кривой фазово однородно.
* **Предупреждения о делении на ноль/переполнении.** В режимe сетки плотности ρ≈0 автоматически избегаются; при необходимости задайте более высокий `--grid-rho-min`.

---

## Рекомендации

* Формируйте начальное состояние с помощью **`guru-iso-fit`** в той же семье (изотерма/изохора), которую планируете использовать.
* Держите допуски группировки достаточно малыми, чтобы не смешивать кривые, но не настолько, чтобы на кривой было < 2 точек.
* Предпочитайте **PCHIP** линейной интерполяции — она лучше сохраняет форму и монотонность.
* В режиме сетки задание `--grid-init-T` и `--grid-init-rho` гарантирует, что эталон будет взят из сетки, а скан по T стартует именно от заданной температуры.
