はじめに
同位体効果は、材料科学や触媒化学、生化学など多くの分野で観測される現象です。また、水素原子を含むMDシミュレーションの計算コストを低減する方法としても使われます。本記事ではシミュレーションにおいて同位体置換する際の注意点と、ASEでのシミュレーションにおいて同位体置換する方法について説明します。
適用範囲と注意点
手法:
対象とする原子の質量を置き換えて同位体を表現します。例えば、水素原子(¹H, 質量約 1 Da)を三重水素(³H, 質量約 3 Da)として扱う場合、水素原子の質量を約3 Daに変更します。
適用範囲:
原子の質量が直接的に関与する物理現象が適用範囲です。例えば原子・分子の拡散、格子振動や分子内振動、および質量に依存する速度論的プロセスなどです。これらの現象では、原子核の質量が運動エネルギーや慣性に直接影響を与えるため、質量の変更によって同位体効果を近似的に再現することが期待できます。
以下は、水の水素原子の一つを三重水素に変えて300 KでMDシミュレーションを実施した際の、酸素と水素間の結合の振動をプロットした図です。表示した100 fsの間に水素は約11.5回、三重水素は約7回振動しており、三重水素の方が振動の周期が長くなっており同位体効果が現れていることがわかります。
図. 300 Kにおける水の酸素-水素間結合の振動の様子
注意点:
原子核質量の変化が化学反応性などにわずかに影響を与える場合があります(例:微細な結合解離エネルギーの変化、超微細構造の変化など)。このような量子論的効果に起因する同位体効果を精密に再現することは、本手法の適用範囲外となります。
MDシミュレーションでの応用:
水素原子は質量が軽く高速で移動するため、MDシミュレーションを実施する際には小さな時間刻み(time step)でシミュレーションをしなければ計算が破綻することがあります。このため水素原子を重水素などで置換し、計算の安定性を高める応用法があります。例えば水素原子では1 fsのtime stepで破綻することがありますが、重水素に置換すると破綻しにくくなります。
なおこの手法は水素の拡散性など、同位体効果が効く現象をシミュレーションする際には利用できませんのでご注意ください。
実装
ASE環境において Atoms オブジェクトは各原子の質量情報を保持しており、これをプログラム的に変更することが可能です。以下に、特定の元素(例:水素 'H')の質量を選択的に変更するためのPythonコードを示します。
# --- 前提 ---
# ASE の Atoms オブジェクトが変数 'atoms' に格納されていることが必要です。
# 例1:
# from ase.build import molecule
# atoms = molecule('H2O')
# 例2:
# from ase.io import read
# atoms = read('FILE_YOU_WANT_TO_READ.xyz')
# --- 原子質量変更の実装 ---
# 1. 質量を変更する原子の元素記号を定義
target_symbol = 'H'
# 2. 目的の同位体の原子質量を定義 (単位: Da)
# 三重水素(Tritium, T) の場合: 約 3.0
# 重水素(Deuterium, D) の場合: 約 2.0
# ここでは三重水素の質量を使用
isotope_mass = 3.0
# 3. 対象元素のインデックスリストを生成
# get_chemical_symbols() で元素記号リストを取得し、元素記号がtarget_symbolと一致するもののインデックスを取得
target_indices = [index for index, symbol in enumerate(atoms.get_chemical_symbols()) if symbol == target_symbol]
# --- (オプション) 特定の原子インデックスのみを指定する場合 ---
# target_indices = [0, 2] # 例えば0番目と2番目の原子のみ対象
# 4. 現在の質量リストを取得
original_masses = atoms.get_masses()
# 5. 対象インデックスに対応する質量を同位体の質量に更新
modified_masses = original_masses.copy() # 元のリストをコピーして変更
for index in target_indices:
if index < len(modified_masses):
modified_masses[index] = isotope_mass
else:
print(f"Warning: Index {index} is out of range.")
# 6. 更新された質量リストを Atoms オブジェクトに設定
atoms.set_masses(modified_masses)
# --- 変更後の質量を確認 ---
# print("Updated atomic masses:")
# print(atoms.get_masses())