| name | mt-modeling |
| description | 構造モデリングを扱うスキルです。表面(slab)切り出し、分子生成、原子置換、複雑系構造の構築を包括します。 generate_all_slabs, pymatgen, get_orthogonal_c_slab, miller_index, fcc111, slab, SMILES, RDKit, Chem.MolFromSmiles, EmbedMolecule, 分子生成, 原子置換, ドーピング, substitute, LiquidGenerator, EMC, ポリマー, 液体, アモルファス, HEA, 高エントロピー合金, PartialOccupancy, wrap_molecule, get_mol_list, CollisionDetector, 衝突検出, FixAtoms, 拘束条件, 表面モデル, 真空層 に関するコード生成時に使用してください。
|
構造モデリング
概要
シミュレーションの目的に合わせた原子構造モデルを構築するためのガイドです。バルク結晶からの表面 (slab) 切り出し、SMILES 文字列からの分子生成、原子置換 (ドーピング)、液体・アモルファス・高エントロピー合金 (HEA) などの複雑系構造の作成、衝突検出、部分占有サイトの処理、外部データベースからの構造取得までを包括的に扱います。
モデリング品質がシミュレーション結果の信頼性を決定します。生成直後の構造は平衡状態にないため、物性値計算の前に必ず構造最適化を行ってください。
ワークフロー
1. Select - 目的に応じた構造構築ツールを選択
2. Generate - 初期構造を生成(表面切り出し、分子生成、液体充填など)
3. Modify - 構造を修正(原子置換、拘束設定、真空層追加など)
4. Validate - 衝突検出、可視化による確認
5. Save - 構造ファイルとして保存
ツール選択ガイド
| 対象系 | 推奨ツール | 備考 |
|---|
| バルク結晶・単純分子 | ase.build.bulk, ase.build.molecule | 基本の builder |
| 表面 (slab) | ase.build.fcc111 等の slab builder、pymatgen generate_all_slabs | 簡易 or 高度な切り出し |
| 低分子・短鎖の液体 | LiquidGenerator (pfcc_extras) | 凝集構造の自動生成 |
| 長鎖ポリマー | EMC | 長鎖用の専用ツール |
| 高エントロピー合金 (HEA) | 手組み HEA / special builder | ランダム配置 |
| アモルファス | Melt-Quench MD | MD による急冷 |
| クラスター | 手動配置 or Wulff construction | 表面エネルギーベース |
実装パターン
パターン A: 表面 (Slab) の簡易生成 (ASE builder)
ASE 組み込みの slab builder で素早く表面モデルを作成します。
from ase.build import fcc111
atoms = fcc111("Pt", size=(2, 2, 4), vacuum=10.0)
print(f"Atoms: {len(atoms)}")
print(f"Cell: {atoms.cell.lengths()}")
size=(nx, ny, nz) は面内繰り返し (nx, ny) と層数 (nz) を指定します。vacuum は表面上下の真空層の厚さ (A) です。
パターン B: 表面 (Slab) の高度な生成 (pymatgen)
任意のミラー指数に対応し、直交化とスーパーセル化を自動で行う堅牢な実装です。
from pymatgen.core import Structure
from pymatgen.core.surface import generate_all_slabs
from ase import Atoms
import numpy as np
def create_slabs(
bulk_atoms: Atoms,
miller_index: tuple,
min_slab_thick: float = 10.0,
min_vacuum: float = 15.0,
min_ab_size: float = 10.0
) -> list[Atoms]:
"""
指定されたミラー指数のスラブ構造を作成する。
Args:
bulk_atoms: バルク結晶の Atoms オブジェクト
miller_index: 切り出す面 (h, k, l) 例: (1, 1, 1)
min_slab_thick: スラブ部分の最小厚さ (A)
min_vacuum: 真空層の最小厚さ (A)
min_ab_size: 表面 (ab 面) の最小サイズ (A)
"""
structure = Structure.from_ase_atoms(bulk_atoms)
slabs_gen = generate_all_slabs(
structure,
max_index=max(miller_index),
min_slab_size=min_slab_thick,
min_vac_size=min_vacuum
)
target_slabs = [s for s in slabs_gen if s.miller_index == miller_index]
refined_slabs = []
for slab in target_slabs:
slab = slab.get_orthogonal_c_slab()
atoms = slab.to_ase_atoms()
cell = atoms.get_cell()
a_len = np.linalg.norm(cell[0])
b_len = np.linalg.norm(cell[1])
repeat_a = int(np.ceil(min_ab_size / a_len))
repeat_b = int(np.ceil(min_ab_size / b_len))
if repeat_a > 1 or repeat_b > 1:
atoms *= (repeat_a, repeat_b, 1)
atoms.center(axis=2)
refined_slabs.append(atoms)
return refined_slabs
パターン C: SMILES からの分子生成
RDKit を使用して SMILES 文字列から 3 次元分子構造を生成します。
from rdkit import Chem
from rdkit.Chem import AllChem
from ase import Atoms
def smiles_to_atoms_rdkit(smiles: str, vacuum: float = 10.0) -> Atoms:
"""SMILES 文字列から 3 次元分子構造 (Atoms) を生成する。"""
mol = Chem.MolFromSmiles(smiles)
if mol is None:
raise ValueError(f"Invalid SMILES string: {smiles}")
mol = AllChem.AddHs(mol)
res = AllChem.EmbedMolecule(mol)
if res == -1:
res = AllChem.EmbedMolecule(mol, useRandomCoords=True)
conf = mol.GetConformer()
positions = conf.GetPositions()
symbols = [atom.GetSymbol() for atom in mol.GetAtoms()]
atoms = Atoms(symbols=symbols, positions=positions)
atoms.center(vacuum=vacuum)
return atoms
使用例:
ethanol = smiles_to_atoms_rdkit("CCO")
benzene = smiles_to_atoms_rdkit("c1ccccc1")
パターン D: 原子置換 (ドーピング)
結晶内の特定原子を別の元素に置換します。
from ase import Atoms
def substitute_atom(atoms: Atoms, index: int, new_symbol: str) -> Atoms:
"""指定インデックスの原子を別の元素に置換する。"""
new_atoms = atoms.copy()
symbols = new_atoms.get_chemical_symbols()
symbols[index] = new_symbol
new_atoms.set_chemical_symbols(symbols)
return new_atoms
def substitute_atom_by_number(atoms: Atoms, index: int, new_atomic_number: int) -> Atoms:
"""指定インデックスの原子を原子番号で置換する。"""
new_atoms = atoms.copy()
new_atoms.numbers[index] = new_atomic_number
return new_atoms
置換位置が複数考えられる場合(サイト依存性)、すべての候補について構造を作成しエネルギー比較を行う必要があります。
パターン E: 固定層の設定 (FixAtoms)
スラブモデルの下層を固定して上層のみ緩和する場合に使用します。
import numpy as np
from ase.constraints import FixAtoms
z_threshold = atoms.positions[:, 2].min() + 3.0
indices_fix = np.where(atoms.positions[:, 2] < z_threshold)[0]
constraint = FixAtoms(indices=indices_fix)
atoms.set_constraint(constraint)
mask_fix = atoms.positions[:, 2] < z_threshold
print(np.where(mask_fix)[0])
constraint = FixAtoms(mask=mask_fix)
atoms.set_constraint(constraint)
パターン F: 液体構造の生成 (LiquidGenerator)
低分子や短鎖の凝集構造を自動生成します。
from pfcc_extras.liquidgenerator.liquid_generator import LiquidGenerator
from ase.build import molecule
atoms_mol = molecule("H2O")
generator = LiquidGenerator(
"packmol",
cell={"lx": 30, "ly": 30, "lz": 30},
composition=[
{"name": "water", "structure": atoms_mol, "number": 15}
]
)
atoms_liquid = generator.run()
generator = LiquidGenerator(
"torch",
cell=[[30, 0, 0], [0, 30, 0], [0, 0, 30]],
composition=[atoms_mol] * 15
)
atoms_liquid = generator.run()
パターン G: 液体・アモルファスの Seed 構造
結晶構造を繰り返して高温 MD の出発点とする方法です。
from ase.build import bulk
atoms = bulk("Al", "fcc", a=4.05).repeat((3, 3, 3))
乱数で初期配置を作って Seed とする方法もあります。
import numpy as np
from ase import Atoms
seed = 42
rng = np.random.default_rng(seed)
cell = np.diag([30.0, 30.0, 30.0])
positions = rng.random((64, 3)) @ cell
atoms = Atoms(symbols=["Si"] * 64, positions=positions, cell=cell, pbc=True)
パターン H: 衝突検出
モデリング操作後に原子の異常な接近がないか検証します。
from pfcc_extras.structure.connectivity import (
exists_colliding_atom,
generate_colliding_info_dataframe,
CollisionDetector,
)
has_collision = exists_colliding_atom(atoms)
if has_collision:
df = generate_colliding_info_dataframe(atoms)
print(df)
detector = CollisionDetector(atoms)
colliding_indices = detector.get_colliding_indices()
colliding_atoms = detector.extract_colliding_atoms()
パターン I: 部分占有サイトの処理
部分占有 (partial occupancy) を含む結晶構造を実体化します。
from pfcc_extras.structure.partial_occupancy import PartialOccupancy
po = PartialOccupancy(atoms)
realized_atoms = po.assign_atom_positions()
電荷中性を維持するために charge_values を指定して検証し、組成比がずれる場合は cell_repeat を増やして整数比近似を改善します。
パターン J: 分子単位の PBC 整形
複数分子をセル内に配置した系で、分子が周期境界で分断されないようにします。
from pfcc_extras.structure.molecule_wrap import wrap_molecule, get_mol_list
mol_list = get_mol_list(atoms)
wrapped_atoms = wrap_molecule(atoms)
原子単位ではなく分子単位で PBC 整形することで、分子断裂を防ぎます。
ベストプラクティス
-
pfcc-extras を優先する: 構造モデリングにおいて ASE と pfcc-extras の両方で実現できる操作は、pfcc-extras を優先してください。特に衝突検出(CollisionDetector)、PBC ラッピング(wrap_molecule)、部分占有処理(PartialOccupancy)、近傍解析(get_neighbors)、SMILES からの分子生成(pfcc_extras.smiles_to_atoms)は pfcc-extras の専用 API がより安全・簡潔です。
-
構造緩和は必須: 生成直後の構造(特に Slab 切り出しや SMILES 生成後)は平衡状態にありません。物性値計算の前に必ず構造最適化を行ってください。
-
真空層の厚さ: 表面モデルや孤立分子では、周期イメージとの相互作用を防ぐため、最低 10A 以上、推奨 15-20A の真空層を確保してください。
-
スラブの対称性: 表面エネルギーを計算する場合、スラブの上下が同じ終端面である(対称性がある)ことが望ましいです。非対称な場合は双極子補正が必要になることがあります。
-
衝突チェック: モデリング操作後は必ず衝突検出を行ってください。見た目で妥当に見える構造でも接触原子が残ることがあり、計算時に Too many neighbors エラーの原因になります。
-
可視化による確認: 構造を生成・編集したら必ず可視化して確認してください。周期境界の不整合、意図しない原子配置、分子の断裂などを早期に発見できます。
-
ドーピング位置の比較: 置換位置が複数ある場合は、すべての候補構造を作成してエネルギー比較を行ってください。
-
PBC の設定: 結晶・スラブ系では pbc=True を忘れないでください。分子系では pbc=False が適切です。
-
内包表記より NumPy ベクトル化を優先: 数値配列(座標、距離、マスク、インデックス抽出など)に対する処理は、リスト内包表記より NumPy のベクトル演算(例: np.where, ブロードキャスト, boolean mask)を優先してください。可読性と性能の両面で有利です。
外部データベース
モデリングの出発点となる構造データは以下のデータベースから取得できます。
| データベース | 対象 | 形式 |
|---|
| Materials Project | 無機結晶全般 | .cif, .vasp |
| AFLOW | 合金・無機結晶系 | 各種 |
| PubChem | 有機分子 | .sdf, .mol |
| COD (Crystallography Open Database) | 結晶構造 | .cif |
よくあるエラーと対処
| エラー・問題 | 原因 | 対処 |
|---|
Too many neighbors | 原子間距離が近すぎる(重なり) | 衝突検出で問題箇所を特定し、座標を修正してください |
| SMILES から 3D 座標生成失敗 | 複雑な分子構造 | useRandomCoords=True で再試行してください |
| スラブの終端面が意図と異なる | generate_all_slabs の結果から適切な候補を選択していない | miller_index でフィルタリングし、各候補を可視化して確認してください |
| 部分占有で組成がずれる | 部分占有の丸め誤差 | cell_repeat を増やして整数比近似を改善してください |
| 分子が PBC で分断される | 原子単位でラッピングしている | wrap_molecule で分子単位のラッピングを使用してください |
Cell is too small | モデルのセルサイズが PFP のカットオフ半径に対して不足 | スーパーセル化してください |
| 表面モデルで上下の相互作用 | 真空層が不足 | vacuum を 15A 以上に設定してください |
関連ガイド
- Calculator 初期化 (setup/SKILL.md): Calculator 初期化
- ASE 基礎操作 (ase-basics/SKILL.md): Atoms 生成・ファイル I/O
- 構造最適化 (optimization/SKILL.md): モデリング後の必須工程
- 分子動力学 (dynamics/SKILL.md): アモルファス作成の Melt-Quench 等