# SALC / k-混成判定ツール マニュアル（tkpg + salc_run.py）

## 1. プログラムの目的

結晶中に周期的に埋め込まれた「錯体クラスター（中心金属＋リガンド）」について、**中心波動関数（例：金属 d 軌道）が、リガンド側の状態と混成（結合）できるか**を、**点群対称性**と**Bloch 位相（k点）**を用いて判定する。

本ツールが提供する主な機能は次の通り。

- リガンド配置から **点群（例：Oh, Td, C4v, C4…）を自動判定**
- 指定したリガンド基底（`mode`）で **リガンドの既約表現分解（reducible → irreps）**
- 各既約表現ごとに **SALC（Symmetry Adapted Linear Combination）** を構成
- 指定した k点集合に対し、**周期同値サイトの Bloch 位相整合（k-compatibility）**を満たす SALC のみ抽出
- `raw / phase / eff` を表示し、位相の役割を可視化

最終的な目的は、結晶の Γ点や任意の k点で

- 中心波動関数の既約表現と一致するか（対称性条件）
- さらに「周期同値のリガンド」に対して Bloch 位相整合した SALC が存在するか（k条件）

を満たすかどうかを判定し、**結合／非結合**を決めることである。

---

## 2. 動作原理

### 2.1 点群判定（プラグイン選択）

`tkpg` には複数の点群プラグイン（`tkpg/Oh.py`, `tkpg/C4v.py` など）が存在する。  
各プラグインは

- `align_guess(ligands_pos)`：入力構造を「点群の標準軸系」に近づける回転（整列）を推定
- `build_group()`：その点群の群要素（3×3行列）を生成

を持つ。整列後の座標に対して群要素を適用し、

- リガンド集合が自分自身に写る割合（hit rate）

を計算し、最も hit rate が高いプラグインを採用する。

### 2.2 リガンド基底（mode）

リガンド上の基底関数は以下から選ぶ。

- `mode="s"`  
  各リガンドに s 軌道 1つ（スカラー）
- `mode="p"`  
  各リガンドに `px, py, pz`（グローバル座標の直交基底）
- `mode="sigma"`  
  各リガンドに `p_sigma` のみ（局所軸 `ez`、金属→リガンド方向）
- `mode="full"`  
  各リガンドに `p_sigma + p_pi1 + p_pi2`（局所軸 `ez/ex/ey`）

### 2.3 既約表現分解（reducible → irreps）

各群要素 g に対して、リガンド基底上の表現行列 D(g) を構成し、文字 χΓ(g)=Tr D(g) を得る。  
これを既約表現 χ_irrep(g) と内積して、多重度を求める。

$$
n_{\alpha} = \frac{1}{|G|}\sum_{g\in G} \chi_{\Gamma}(g)\,\chi_{\alpha}(g)
$$

ここで |G| は群の位数、α は既約表現。

### 2.4 SALC 抽出（射影演算子）

既約表現 α に対して射影演算子 Pα を作り、固有値 1 成分から SALC を抽出する。

$$
P_{\alpha} = \frac{l_{\alpha}}{|G|}\sum_{g\in G}\chi_{\alpha}(g)\,D(g)
$$

- lα：既約表現の次元
- D(g)：基底上の表現行列

Pα を対角化し、固有値が閾値以上の固有ベクトルを SALC として採用する。

### 2.5 Bloch 位相と k-compatibility（周期同値の整合条件）

結晶中では、セル並進 T（整数ベクトル）に対して Bloch 位相がかかる。

$$
\phi(\mathbf{r}+\mathbf{T}) = e^{i2\pi \mathbf{k}\cdot\mathbf{T}} \phi(\mathbf{r})
$$

本ツールでは、同一の物理的リガンド（同じ site_id）に属し、セルだけが異なる基底関数について、

- SALC の係数 raw
- Bloch 位相 phase = exp(i2π k·T)
- 位相込み実効係数 eff = raw × phase

を定義し、**同一 site_id の中で eff が一致する**（位相整合する）SALC のみを「k-compatibility を満たす SALC」として採用する。

出力では以下を並べて表示する。

- raw：SALC 固有ベクトルの係数（基底の取り方で変わり得る）
- phase：Bloch 位相
- eff：raw×phase（周期同値の整合を見るべき量）

---

## 3. 必要な非標準ライブラリ

- なし（標準ライブラリ＋NumPyのみ）

必要な Python パッケージ：
- `numpy`

標準ライブラリ使用：
- `json`
- `argparse`
- `math`

---

## 4. 入力ファイル（structure.json）の書式

`salc_run.py` は `--infile` で JSON を読み込む。デフォルトは `structure.json`。

### 4.1 最小例（分子クラスターのみ）

- `ligands_pos`：金属中心から見たリガンドの直交座標（任意単位）

例：
- 5配位（square pyramidal）なども可

### 4.2 結晶周期を含めた推奨形式（k判定を行う場合）

k依存の混成判定を目的とする場合、**リガンドを格子周期に対応するように入力**するのが原則である。  
推奨キー：

- `lattice`：3×3 の格子ベクトル（直交・非直交いずれも可）
- `ligands_frac`：リガンド位置（分率座標）
- `center_ligands`：true の場合、重心を引いて中心化（既定の挙動は実装に依存）
- `kpoints_frac`：判定したい k 点（分率座標）

例：
- +x 側のリガンドと -x 側のリガンドが周期同値となるように、`T` が付く形で登録される

### 4.3 代表的な JSON（例）

- 単純立方格子
- リガンドは格子周期に沿って入力
- k点は Γ と (1/2,1/2,0)

（実際の値はユーザ環境の JSON に合わせる）

---

## 5. 対称性ライブラリ（tkpg プラグイン）の仕様

本ツールは点群ごとに `tkpg/<Group>.py` をプラグインとして読み込む。  
後日、生成AIに新しい点群プラグインを作ってもらうことを想定し、必要仕様を以下にまとめる。

### 5.1 プラグインが提供すべき辞書インターフェース

`tkpg.load_plugins()` は各点群プラグインから次の情報を収集し、辞書として返す。

- `name`：点群名（例："Oh", "C4v", "Td", "C4"）
- `align_guess(ligands_pos)`：
  - 入力：`(N,3)` の NumPy 配列（中心化済み直交座標）
  - 出力：`(ok, R_align, pos_aligned)`
    - ok：整列推定に成功したか
    - R_align：3×3 回転行列（入力座標→標準軸系）
    - pos_aligned：`(N,3)` 整列後の座標
- `build_group()`：
  - 出力：群要素リスト
  - 群要素は dict とし、少なくとも
    - `name`（表示用）
    - `R`（3×3 の直交行列）
    - `class`（既約表現の文字表で参照するクラス名）
  を持つ
- `irreps()`：既約表現名のリストを返す（例：["A1","A2","B1","B2","E"] など）
- `irrep_dim(irrep)`：既約表現の次元
- `irrep_char(irrep, element)`：群要素 element に対する文字 χ(irrep, g)
- `d_irreps`：中心金属の d 軌道 → 既約表現の辞書
  - 例：C4v なら `d_xy -> B2` など

### 5.2 群要素の行列についての注意

- `R` は「標準軸系」で定義する
- `align_guess` が推定した `pos_aligned` は、その `R` に対して閉じる（自己写像する）必要がある
- 反転を含む群（Oh など）では、必要に応じて `inv` フラグ等を element dict に追加してよい（実装側の `irrep_char` が参照する）

### 5.3 生成AIで新点群プラグインを作るためのプロンプト雛形

以下のテンプレートを使うと、追加点群プラグインの生成がしやすい。

- 依頼文テンプレート（そのまま使える形）：

新しい点群プラグイン `tkpg/<NAME>.py` を作ってください。  
要件：
1. `plugin()` 関数を実装し、以下のキーを持つ dict を返す：
   - name, align_guess, build_group, irreps, irrep_dim, irrep_char, d_irreps
2. 群要素は list[dict] とし、各要素は少なくとも {name, R, class} を持つ。
3. 既約表現の文字表（character table）を内部に持ち、`irrep_char(irrep, element)` で返す。
4. `align_guess(ligands_pos)` は入力座標を標準軸系に近づける回転を推定し、
   (ok, R_align, pos_aligned) を返す。失敗時は ok=False。
5. `core.symmetry_hit_rate(group, pos_aligned, tol_match)` が高くなるように整列を設計する。
6. 中心 d 軌道の既約表現対応 `d_irreps` を実装する（d_z2, d_x2_y2, d_xy, d_xz, d_yz）。
7. NumPy のみで動作し、外部依存を増やさない。

点群：
- NAME = <点群名>
- 主軸の取り方：
  - <ここに軸規約を書く>
- 群要素：
  - <必要ならクラス分けや行列生成法を書く>
- 文字表：
  - <必要なら表を列挙する>

---

## 6. Usage

### 6.1 実行コマンド

- デフォルト入力（structure.json）で実行：

python salc_run.py

- 入力ファイルを指定：

python salc_run.py --infile my_structure.json

### 6.2 出力の読み方（典型）

- 自動判定された点群と候補スコア
- 中心 d 軌道の既約表現
- リガンド側 reducible rep の分解
- k点ごとの k-compatibility 判定
- k-compatibility を満たす SALC の表示（raw/phase/eff）

---

## 7. 実行例

### 7.1 例：C4 系で d_xy (B2) を判定

出力例（要旨）：

[Auto-detected point group]  C4v (hit_rate=1.000)  
[Central metal d orbital] Orbital: d_xy  Irrep: B2

[k-compatibility] irrep=B2  k_frac=(0.000,0.000,0.000) compatible=0/1  
(No k-compatible SALCs…)

[k-compatibility] irrep=B2  k_frac=(0.500,0.500,0.000) compatible=1/1

[SALCs for B2 at k=(0.500,0.500,0.000)] (count=1)  
raw=-0.5000 phase=+1.0000 eff=-0.5000 L0:py (T=[0,0,0])  
raw=+0.5000 phase=-1.0000 eff=-0.5000 L1:py (T=[-1,0,0])  
raw=-0.5000 phase=+1.0000 eff=-0.5000 L2:px (T=[0,0,0])  
raw=+0.5000 phase=-1.0000 eff=-0.5000 L3:px (T=[0,-1,0])

解釈：
- Γ点では B2 の k整合SALCが存在しない → Γ点では d_xy は非結合
- k=(1/2,1/2,0) では B2 の k整合SALCが存在 → このkでは混成可能性あり
- raw は基底の取り方で符号が変わり得るが、eff が周期同値で一致していることが重要

---

## 8. 注意事項とコツ

- 構造が歪んでいる場合は `tolerances` を調整する
  - `tol_match_geom`：点群判定の厳しさ
  - `tol_match_D`：D(g) 構成時の一致判定
- `mode="p"` は「位相整合」の議論をしやすい（係数の意味が明確）
- `mode="full"` はより物理的だが、局所軸定義の影響を受ける
- SALC の固有ベクトルは縮退部分空間内で混ざるため、raw の符号・並びは変わり得る
  - k-compatibility の判定は eff で行う

---
