bz_draw.py 技術ドキュメント

プログラムの動作

bz_draw.py は、結晶学における第一ブリルアンゾーン (First Brillouin Zone, BZ) または実空間のウィグナー=ザイツセル (Wigner-Seitz cell) を3Dで可視化するためのPythonプログラムです。

主な機能:

  • 単位格子からのセル構築: ユーザーが指定する単位格子パラメータ(\(a, b, c, \alpha, \beta, \gamma\))と格子タイプ(P, I, Fなどの慣用格子)から、対応する原始格子ベクトルを計算し、ヴォロノイ分割を用いて第一BZまたはウィグナー=ザイツセルを構築します。

  • 高対称点とk-pathの描画 (逆空間のみ): 逆格子空間の第一BZの場合、seekpathライブラリを利用して、その格子に対応する高対称点とそれらを結ぶk-pathを自動的に計算し、描画します。

  • 周期タイルの描画: 中心となるセルだけでなく、周囲の周期的なタイルセルも描画できます。タイルの表示数、最大半径、色付けモード(チェッカー、距離によるグラデーション、ハッシュ)および距離に応じた透明度フェードを細かく制御可能です。

  • インタラクティブなパラメータ調整: オプションで、インタラクティブなスライダーと「Apply」ボタンを備えたGUIを提供します。これにより、格子定数を変更し、その場ですぐに再描画することで、パラメータの変化がセルの形状に与える影響を動的に視覚的に探索できます。

  • 表示オプション: ヴォロノイ計算の基になる格子点/逆格子点、セル面を定義する点、原点からそれらの点へのコネクタラインなどの表示/非表示を切り替えることができます。

解決する課題: このプログラムは、結晶の電子構造計算や格子力学の理解において不可欠な第一BZやウィグナー=ザイツセルの形状を、直感的かつ詳細に視覚化します。特に、インタラクティブモードは、様々な結晶構造や格子定数におけるセルの変化を容易に探索できるため、固体物理学、材料科学、結晶学分野の研究や教育において、重要な概念の理解を深めるのに役立ちます。

原理

bz_draw.py は、以下の主要な数式、物理式、およびアルゴリズムに基づいて動作します。

1. 単位格子から原始格子への変換

  • 慣用格子ベクトルの構築: build_conventional_basis 関数は、入力された単位格子パラメータ \(a, b, c, \alpha, \beta, \gamma\) からデカルト座標系における慣用格子ベクトルを構築します。

    • \(a_{vec} = (a, 0, 0)\)

    • \(b_{vec} = (b \cos\gamma, b \sin\gamma, 0)\)

    • \(c_{vec}\) の成分は、直交基底における投影と長さの条件から計算されます。

      • \(c_x = c \cos\beta\)

      • \(c_y = c(\cos\alpha - \cos\beta \cos\gamma) / \sin\gamma\)

      • \(c_z = \sqrt{c^2 - c_x^2 - c_y^2}\) これらのベクトルを列として持つ行列 \(A_{conv}\) を生成します。

  • 原始格子ベクトルの導出: primitive_from_centering 関数は、慣用格子ベクトル行列 \(A_{conv}\) と格子タイプ(例: I, F)に基づいて、対応する原始格子ベクトル行列 \(A_{prim}\) を計算します。これは、変換行列 \(P\) を用いて \(A_{prim} = A_{conv} P\) として行われます。 例えば、体心立方 (BCC/I) の場合、変換行列 \(P\) は以下のようになります。 $\( P_I = \begin{pmatrix} -0.5 & 0.5 & 0.5 \\ 0.5 & -0.5 & 0.5 \\ 0.5 & 0.5 & -0.5 \end{pmatrix} \)\( 面心立方 (FCC/F) の場合、変換行列 \)P\( は以下のようになります。 \)\( P_F = \begin{pmatrix} 0.0 & 0.5 & 0.5 \\ 0.5 & 0.0 & 0.5 \\ 0.5 & 0.5 & 0.0 \end{pmatrix} \)$

2. ヴォロノイ分割による第一BZ/ウィグナー=ザイツセルの構築

  • 格子点/逆格子点の生成:

    • --space real の場合、原始格子ベクトル \(A_{prim}\) を基に、実空間の格子点 \(R_{ijk} = i a_1 + j a_2 + k a_3\) を生成します。

    • --space reciprocal の場合、原始格子ベクトル \(A_{prim}\) から逆格子ベクトル \(B_{std}\) を導出し、逆格子点 \(G_{ijk} = i b_1 + j b_2 + k b_3\) を生成します。ここで \(b_1, b_2, b_3\)\(2\pi\) を含む原始逆格子ベクトルです。 これらの点は、-n-shell 引数で指定されたシェル範囲 (\(i,j,k \in [-n, n]\)) 内で生成されます。

  • ヴォロノイ分割: 生成された点群に対して scipy.spatial.Voronoi を使用し、ヴォロノイ分割を計算します。 ヴォロノイセルは、ある点に最も近い空間領域として定義されます。第一ブリルアンゾーン(逆格子空間)およびウィグナー=ザイツセル(実空間)は、原点を含むヴォロノイセルとして構築されます。

  • セル面の抽出: get_cell_faces_and_neighbors および cell_polygons 関数は、原点を含むヴォロノイセル(第一BZまたはウィグナー=ザイツセル)の面を構成する頂点とその隣接点(面を定義する点)を抽出します。

  • ポリゴンの頂点順序付け: ヴォロノイセルの面は3次元空間内の平面ポリゴンですが、scipy.spatial.Voronoi が返す頂点は順序付けられていません。order_polygon_vertices_on_plane 関数は、特異値分解 (SVD) を用いてポリゴンが乗る平面の法線ベクトルを特定し、その平面上で各頂点の角度を計算することで、頂点を時計回りまたは反時計回りに順序付けします。これにより、matplotlib.pyplot.Poly3DCollection を用いたポリゴンの正しい描画が可能になります。

3. seekpath ライブラリの利用 (逆空間のみ)

bz_and_kpath_from_seekpath_cached 関数は、原始格子ベクトル \(A_{prim}\) を入力として seekpath ライブラリを呼び出し、その格子に対応する原始逆格子ベクトル、標準化された高対称点の絶対座標 (例: \(\Gamma, H, N, P\))、およびそれらを結ぶk-pathのセグメント情報を取得します。 この関数は、functools.lru_cache デコレータを用いてキャッシュされており、同じ格子パラメータが再入力された場合には計算をスキップし、高速な再描画を可能にします。

4. 周期タイリングと視覚効果

  • タイリング: tile_nx, tile_ny, tile_nz 引数で指定された範囲で、原始格子ベクトル(または原始逆格子ベクトル)の整数倍 \((i a_1 + j a_2 + k a_3)\) の並進ベクトル \(t\) を計算し、中心のヴォロノイセルを平行移動して描画します。

  • 色付けと透明度: タイルセルは、--tile-color-mode オプションに応じて、チェッカーパターン、ハッシュ値に基づく色、または中心からの距離に応じたグラデーションで色付けされます。 また、alpha_fade 関数により、中心からの距離 \(r\) が大きいほど透明度を増すように調整され、--fade-power 引数でフェードの非線形性を制御できます。

必要な非標準ライブラリとインストール方法

このプログラムの実行には、以下のPython非標準ライブラリが必要です。

  • numpy: 高性能な数値計算のため

  • matplotlib: 2D/3Dプロットの描画のため

  • scipy: ヴォロノイ分割の計算のため

  • seekpath: 逆格子空間の高対称点とk-pathの計算のため

  • spglib: seekpath の依存ライブラリであり、結晶の空間群情報を扱うため

これらのライブラリは、Pythonのパッケージマネージャ pip を使ってインストールできます。

pip install numpy matplotlib scipy seekpath spglib

必要な入力ファイル

bz_draw.py は、すべての設定パラメータをコマンドライン引数として受け取ります。そのため、特定の入力ファイルを必要としません

生成される出力ファイル

  • グラフィカルウィンドウ: デフォルトでは、matplotlib のグラフィカルユーザーインターフェース (GUI) ウィンドウが開き、3Dプロットがインタラクティブに表示されます。ユーザーはこのウィンドウを操作して、視点を変更したり、画像を保存したりできます。

  • 画像ファイル: --save オプションがコマンドラインで指定された場合、描画された図は指定されたパスに画像ファイルとして保存されます。matplotlib がサポートする様々な画像フォーマット(例: .png, .jpg, .pdf, .svg)に対応しています。

コマンドラインでの使用例 (Usage)

python bz_draw.py [--space {reciprocal,real}] [--lattice LATTICE] [--a A] [--b B] [--c C] [--alpha ALPHA] [--beta BETA] [--gamma GAMMA] [--n-shell N_SHELL] [--tile-nx TILE_NX] [--tile-ny TILE_NY] [--tile-nz TILE_NZ] [--tile-rmax TILE_RMAX] [--plot-limit PLOT_LIMIT] [--tile-color-mode {checker,byindex,distance}] [--fade-power FADE_POWER] [--no-outside-points] [--no-highlight-face-points] [--no-connectors] [--no-kpath] [--label-fontsize LABEL_FONTSIZE] [--interactive-apply] [--save SAVE]
  • --space {reciprocal,real}: 描画する空間を指定します。reciprocal は第一ブリルアンゾーン、real はウィグナー=ザイツセルです。(デフォルト: reciprocal)

  • --lattice LATTICE: 格子タイプを指定します。P|SC, I|BCC, F|FCC, A, B, C のいずれか。(デフォルト: P)

  • --a A, --b B, --c C: 単位格子の格子定数を指定します (Å)。(デフォルト: 1.0)

  • --alpha ALPHA, --beta BETA, --gamma GAMMA: 単位格子の角度を指定します (度)。(デフォルト: 90.0)

  • --n-shell N_SHELL: ヴォロノイ計算に使用する格子点/逆格子点の範囲。中心から \(n\) 単位セル分広がる空間を考慮します。(デフォルト: 3)

  • --tile-nx TILE_NX, --tile-ny TILE_NY, --tile-nz TILE_NZ: 各方向の周期タイルの数。0を指定するとその方向にはタイルしません。(デフォルト: 0)

  • --tile-rmax TILE_RMAX: タイル描画の半径上限。中心から距離 \(r \le r_{max}\) のセルのみ描画します。

  • --plot-limit PLOT_LIMIT: 軸の表示範囲を強制的に \([-L, L]\) に制限します。

  • --tile-color-mode {checker,byindex,distance}: タイルの色付けモードを指定します。checker (チェッカーパターン), byindex (ハッシュによる色), distance (距離グラデーション) のいずれか。(デフォルト: checker)

  • --fade-power FADE_POWER: 距離による透明度フェードの指数を指定します。(デフォルト: 1.0)

  • --no-outside-points: 面を定義する格子点/逆格子点を表示しません。

  • --no-highlight-face-points: 面を定義する点を強調表示しません。

  • --no-connectors: 原点と面を定義する点を結ぶ点線を表示しません。

  • --no-kpath: 第一BZの高対称点とk-pathを表示しません(--space reciprocal の場合のみ有効)。

  • --label-fontsize LABEL_FONTSIZE: 高対称点ラベルのフォントサイズを指定します。(デフォルト: 10)

  • --interactive-apply: インタラクティブなスライダーと「Apply」ボタンで格子定数を変更し、再描画するモードを有効にします。

  • --save SAVE: 描画結果を画像ファイルとして保存するパスを指定します。

コマンドラインでの具体的な使用例

  1. 体心立方 (BCC) 格子の第一ブリルアンゾーンをタイル表示し、高対称点とk-pathを表示

    python bz_draw.py --lattice BCC --tile-nx 1 --tile-ny 1 --tile-nz 1 --tile-color-mode distance --fade-power 2.0
    

    実行結果の説明: このコマンドは、体心立方 (BCC) 格子の第一ブリルアンゾーンを中心に描画します。その周囲には、各方向に一周期分(1セル分)のタイルセルが表示されます。--tile-color-mode distance により、タイルセルは中心からの距離に応じてグラデーションカラーで色付けされ、--fade-power 2.0 により、距離の二乗に比例して透明度がフェードアウトします。seekpathで計算された高対称点(Γ, H, N, Pなど)とそれらを結ぶk-pathも表示され、結晶の逆格子空間を包括的に視覚化します。

  2. 面心立方 (FCC) 格子のウィグナー=ザイツセルを実空間で表示し、外側の点を非表示

    python bz_draw.py --space real --lattice FCC --no-outside-points --tile-nx 1 --tile-ny 1 --tile-nz 0 --tile-rmax 1.5
    

    実行結果の説明: このコマンドは、面心立方 (FCC) 格子の実空間ウィグナー=ザイツセルを描画します。--space real オプションにより実空間のセルが表示されます。中心セルに加え、x方向とy方向に一周期分のタイルセルが表示されますが、z方向にはタイルされません (--tile-nz 0)。--no-outside-points オプションにより、中心セルを定義する実格子点やタイリングに使われる格子点は表示されません。また、--tile-rmax 1.5 により、中心から距離1.5を超える位置にあるタイルセルは表示されず、表示範囲が制限されます。

  3. インタラクティブモードで単純立方 (SC) 格子の第一ブリルアンゾーンを操作

    python bz_draw.py --lattice SC --interactive-apply
    

    実行結果の説明: このコマンドを実行すると、単純立方 (SC) 格子の第一ブリルアンゾーンが初期値 (a=b=c=1.0) で描画されます。図の下部には、a, b, c の格子定数を変更できるスライダーと「Apply」ボタンが表示されます。スライダーを動かしても描画は更新されず、「Apply」ボタンをクリックすることで、変更された格子定数に基づき新しい第一ブリルアンゾーンが再計算・再描画されます。これにより、格子定数の変化が第一BZの形状に与える影響を動的に、かつユーザーの操作で確認することができます。例えば、aの値を大きくすると、逆格子空間ではk_x方向が狭くなり(BZがその方向につぶれる)、六面体の形状が歪む様子が視覚的に理解できます。