チュートリアル

en ja

単原子 template から構造を作る

Fe–Si–B のように、各元素を独立した単原子 template として配置する例です。

template を作る

from packmol_util.model import write_single_atom_xyz

write_single_atom_xyz("Fe.xyz", "Fe")
write_single_atom_xyz("Si.xyz", "Si")
write_single_atom_xyz("B.xyz", "B")

それぞれ 1 原子だけを含む XYZ template が生成されます。

Builder を作る

from packmol_util.builder import AmorphousBuilder

builder = AmorphousBuilder(
    symbols=["Fe", "Si", "B"],
    ratios=[80, 9, 11],
    total_atom_count=1000,
    minimum_separation=2.0,
    mass_density=7.0,
)

組成比の和は 100 なので、この場合の組成単位の倍率は、

builder.multiplier

から取得できます。

template を登録する

builder.add_template(
    "Fe.xyz",
    80 * builder.multiplier,
)

builder.add_template(
    "Si.xyz",
    9 * builder.multiplier,
)

builder.add_template(
    "B.xyz",
    11 * builder.multiplier,
)

構造を生成する

builder.build("FeSiB")

build() により Packmol 入力生成、Packmol 実行、出力構造の変換が行われます。

数密度を指定する

質量密度の代わりに数密度を指定できます。

builder = AmorphousBuilder(
    symbols=["Fe", "Si", "B"],
    ratios=[80, 9, 11],
    total_atom_count=1000,
    minimum_separation=2.0,
    number_density=0.08,
)

計算されたセル一辺長は、

print(builder.box_length)

で確認できます。

分子ユニットを配置する

Li3PO4 のように PO4 を 1 個の構造ユニットとして配置する場合は、PO4 の XYZ template を作ります。

Li template

from packmol_util.model import write_single_atom_xyz

write_single_atom_xyz("Li.xyz", "Li")

PO4 template

from packmol_util.model import write_tetrahedral_unit_xyz

write_tetrahedral_unit_xyz(
    filename="PO4.xyz",
    center_element="P",
    vertex_element="O",
    center_vertex_distance=1.54,
    vertex_vertex_distance=2.51,
)

ここで指定している距離は PO4 内部の幾何です。

Builder

from packmol_util.builder import AmorphousBuilder

builder = AmorphousBuilder(
    symbols=["Li", "P", "O"],
    ratios=[3, 1, 4],
    total_atom_count=512,
    minimum_separation=1.5,
    number_density=0.09119,
)

Li3PO4 は 1 組成単位あたり 8 原子なので、512 原子では 64 組成単位です。

template を登録する

builder.add_template(
    xyz_file="Li.xyz",
    number=3 * builder.multiplier,
)

builder.add_template(
    xyz_file="PO4.xyz",
    number=builder.multiplier,
    packing_radii={
        "P": 0.25,
        "O": 1.05,
    },
)

packing_radii は PO4 内部の結合距離ではなく、Packmol が template を配置するときの排除距離に使われます。

構造を生成する

builder.build("Li3PO4")

低レベル API

高レベルの AmorphousBuilder を使わず、下位 API を個別に利用することもできます。

たとえば Packmol 入力だけを組み立てたい場合は PackmolInp、密度やセルサイズの計算、Packmol 実行、XYZ → POSCAR 変換などを個別に扱いたい場合は Packmol を利用します。

各クラスとメソッドの最新のシグネチャは packmol_util を参照してください。

Packmol のインストール

packmol_util は Packmol 実行ファイルを同梱しません。Packmol を別途インストールし、packmol コマンドを実行できる状態にします。実行ファイルを別の場所に置く場合は AmorphousBuilder(packmol_bin="...") にパスを指定します。

Linux でソースからビルドする例:

wget https://m3g.iqm.unicamp.br/packmol/packmol.tar.gz
tar xzf packmol.tar.gz
cd packmol
make

macOS で GNU Fortran を使用する例:

brew install gcc
tar xzf packmol.tar.gz
cd packmol
FC=gfortran-14 F77=gfortran-14 ./configure
make

gfortran-14 はインストール済みのコンパイラ名に合わせて変更します。ビルド手順は Packmol のバージョンにより異なるため、配布元の手順も確認してください。実行ファイルの場所を PATH に追加するか、packmol_bin で指定します。

Packmol 入力ファイルと低レベル API

Packmol は XYZ テンプレート、配置個数、配置領域を入力ファイルで指定します。以下は Fe、Si、B の単原子テンプレートを配置する入力例です。

tolerance 2.0
pbc 20.0 20.0 20.0
filetype xyz
output FeSiB_packmol.xyz

structure Fe.xyz
  number 80
  inside box 0.0 0.0 0.0 20.0 20.0 20.0
end structure

structure Si.xyz
  number 9
  inside box 0.0 0.0 0.0 20.0 20.0 20.0
end structure

structure B.xyz
  number 11
  inside box 0.0 0.0 0.0 20.0 20.0 20.0
end structure

PackmolInp を使うと同じ構造を Python から記述できます。ここではセル長を例示値の 20 Å とし、密度から計算しません。

from packmol_util.model import write_single_atom_xyz
from packmol_util.packmol_inp import PackmolInp
from packmol_util.packmol import Packmol

for symbol in ("Fe", "Si", "B"):
    write_single_atom_xyz(f"{symbol}.xyz", symbol)

inp = PackmolInp(
    minimum_separation_distance=2.0,
    output_xyz="FeSiB_packmol.xyz",
    box_length=20.0,
    use_pbc=True,
)
for symbol, count in (("Fe", 80), ("Si", 9), ("B", 11)):
    inp.add_structure(f"{symbol}.xyz", count)
inp.write("FeSiB_packmol.inp")

runner = Packmol()
runner.run_packmol("FeSiB_packmol.inp", "FeSiB_packmol.log")
index_map = runner.xyz_to_poscar(
    xyz_file="FeSiB_packmol.xyz",
    poscar_file="POSCAR",
    packmol_inp="FeSiB_packmol.inp",
    elements=["Fe", "Si", "B"],
)

run_packmol() は入力ファイルを Packmol の標準入力に渡し、標準出力と標準エラーをログに保存します。xyz_to_poscar() は inside box からセル長を読み取り、Cartesian 座標を Direct 座標へ変換し、元素ごとに並べ替えます。戻り値 index_map は Packmol XYZ の 1 始まり原子番号から POSCAR の 1 始まり原子番号への辞書です。

密度、組成比、総原子数

AmorphousBuilder は数密度を直接指定するか、質量密度と組成比から数密度を求めます。数密度を (n) [Å(^{-3})]、総原子数を (N) とすると、立方セルの一辺は (L=(N/n)^{1/3}) [Å] です。質量密度 (\rho) [g cm(^{-3})]、平均原子量 (\bar M) [g mol(^{-1})] の場合、(n=\rho N_A 10^{-24}/\bar M) です。

from packmol_util.packmol import Packmol
pm = Packmol()
counts = pm.compute_element_counts(["Fe", "Si", "B"], [80, 9, 11], 503)
number_density = pm.number_density_from_mass_density(
    ["Fe", "Si", "B"], [80, 9, 11], 7.35
)
length = pm.cell_length_from_number_density(500, number_density)
print(counts, length)

Packmol.compute_element_counts() は総原子数を固定し、端数の大きい元素に残余を配分するため、厳密な組成比にならない場合があります。一方 AmorphousBuilder は total_atom_count を sum(ratios) の最も近い整数倍に補正し、組成比を維持します。補正後の原子数は builder.total_atom_count、倍率は builder.multiplier で確認します。model.make_atomic_mixture_recipe() は整数倍でない原子数を受け付けず ValueError を送出します。これらの動作は異なります。

構造レシピとテンプレート

model は XYZ テンプレートの作成と、配置数をまとめるデータ構造を提供します。StructureSpec はテンプレートファイル、配置数、元素別 packing 半径を保持します。make_material_recipe() は各 XYZ の先頭行からテンプレート内原子数を読み、number × テンプレート原子数 の合計を MaterialRecipe.total_atom_count に設定します。make_atomic_mixture_recipe() は単原子 XYZ の生成とレシピ作成を同時に行います。

from packmol_util.model import make_atomic_mixture_recipe
recipe = make_atomic_mixture_recipe(
    symbols=["Fe", "Si", "B"],
    ratios=[80, 9, 11],
    total_atom_count=500,
)
assert recipe.total_atom_count == 500

StructureSpec や MaterialRecipe を作成するだけでは Packmol は実行されません。AmorphousBuilder に渡す場合は recipe.structures を順に builder.add_template() へ登録します。

正四面体テンプレートと RMC_POT FNC

PO4 の場合、テンプレートの局所原子番号は P=1、O=2–5 です。FNC の原子ペアは局所番号で登録し、Packmol 実行後に POSCAR の原子番号へ変換されます。make_tetrahedral_unit_fnc_pairs() は P–O の 4 ペア(type 1)と O–O の 6 ペア(type 2)を返します。

from packmol_util.builder import AmorphousBuilder
from packmol_util.model import (
    write_single_atom_xyz,
    write_tetrahedral_unit_xyz,
    make_tetrahedral_unit_fnc_pairs,
)

write_single_atom_xyz("Li.xyz", "Li")
write_tetrahedral_unit_xyz(
    filename="PO4.xyz",
    center_element="P",
    vertex_element="O",
    center_vertex_distance=1.54,
    vertex_vertex_distance=2.515,
)

builder = AmorphousBuilder(
    symbols=["Li", "P", "O"],
    ratios=[3, 1, 4],
    total_atom_count=512,
    minimum_separation=1.5,
    number_density=0.09119,
)
builder.add_template("Li.xyz", 3 * builder.multiplier)
builder.add_template(
    "PO4.xyz",
    builder.multiplier,
    packing_radii={"P": 0.25, "O": 1.05},
    fnc_pairs_in_template=make_tetrahedral_unit_fnc_pairs(),
    fnc_distance_ranges={1: (1.45, 1.65), 2: (2.40, 2.65)},
    fnc_output_constraint_types=[1, 2],
)
builder.build("Li3PO4")

fnc_output_constraint_types=None は全 type を出力します。[1] は type 1 のみを出力します。FNC の選択は Packmol に渡す XYZ の形状や配置条件には影響しません。Packmol.write_fnc_file() は FNC type が 1 から始まる連続整数であることを要求するため、type 2 のみを指定する [2] は現行実装ではエラーになります。

make_tetrahedral_unit_fnc_spec_from_ranges() は FNC の距離範囲から各中央値を計算し、正四面体としての整合性を検査してテンプレート用代表距離と FNC ペアを返します。中心–頂点距離 (d) と頂点–頂点距離 (a) は (a=d\sqrt{8/3}) を満たす必要があります。geometry_distance_tolerance は幾何検査の許容差であり、FNC 距離範囲の幅ではありません。

solve_packing_radii_from_pair_distances() は元素ペアの希望最小距離を半径和で近似します。全元素の自己ペアと異種ペアの距離が必要です。pair_distance_tolerance は距離表の近似誤差の許容値であり、Packmol の tolerance とは異なります。探索は離散的であり、任意の距離表に対する解の存在を保証しません。

出力ファイルと実装上の条件

builder.build("FeSiB") の出力は FeSiB_packmol.inp、FeSiB_packmol.xyz、FeSiB_packmol.log、POSCAR、POSCAR.vasp です。FNC ペアが登録されている場合に限り、既定で FeSiB.fnc が出力されます。FNC 出力先は build(output_prefix, fnc_file=...) で変更できます。POSCAR と POSCAR.vasp は接頭辞にかかわらず固定名のため、同じ作業ディレクトリで複数回実行すると上書きされます。

add_template(number=...) の配置数と各テンプレート内の原子数の積の合計は、補正後の builder.total_atom_count に一致させてください。現行 AmorphousBuilder はこの一致を build() の開始時に検査しません。FNC は Packmol XYZ のテンプレート配置順と POSCAR の元素別並べ替えに依存します。FNC 原子番号は 1 始まりです。

付属スクリプト・サンプルのインストール

pip install packmol-util 後、任意の作業ディレクトリで次のコマンドを実行できます。

packmol_util install scripts
packmol_util install example

前者はリポジトリの scripts/ 以下、後者は example/ 以下のファイルを現在の作業ディレクトリにコピーします。下位ディレクトリ構成も保持します。たとえば example/Li3PO4/non_builder/make_Li3PO4.py は ./Li3PO4/non_builder/make_Li3PO4.py に配置されます。

既存の同名ファイルは既定で上書きせず、スキップします。上書きする場合のみ --force を指定してください。

packmol_util install scripts --force
packmol_util install example --force

コピー先はコマンド実行時のカレントディレクトリです。既存の無関係なファイルは削除しません。Packmol 本体のインストールとは別の機能です。