Home
3647 words
18 minutes
【計算化学】自作pythonライブラリで遷移状態構造を求めてみる(BH9データセット, 3. Halogen atom transferのNo. 1の素過程, NNP使用)

最終更新:2025-10-04

概要#

本記事では、自作ライブラリ(MultiOptPy)で、BH9データセット 3. Halogen atom transferのNo. 1の素過程の遷移状態構造を算出してみる。計算レベルは、Meta社のFAIR Chemistryが開発したニューラルネットワークポテンシャル(NNP)であるUMA(Meta’s Universal Model for Atoms)とした。

MultiOptPyは電子状態計算ソフトウェアを用いた分子構造最適化手法の勉強を目的として作成したpythonライブラリである。

MultiOptPyのレポジトリ:https://github.com/ss0832/MultiOptPy

BH9のデータセットについて:

この文献のSupporting Informationから、データセットの詳細を確認できる。

今回使用したニューラルネットワークポテンシャルについて:

使用した自作ライブラリMultiOptPyのバージョン#

v1.18b

環境#

Windows 11

※Windows 11環境下でAnaconda PowerShell Promptを使用した。

Source codeのダウンロード(Unixコマンド)#

wget https://github.com/ss0832/MultiOptPy/archive/refs/tags/v1.18b.zip
unzip v1.18b.zip
cd MultiOptPy-v1.18b

https://github.com/ss0832/MultiOptPy/releases/tag/v1.18b にアクセスしてzipファイルをダウンロードする。Unixコマンドの場合とはディレクトリ名が異なるので都度読み替えていただけると良い。

環境構築手順#

今回は、Windows 11のPower Shellを使用した。初めに、NNPを使用できる環境が整ったAnaconda PowerShell Promptを用意する手順を説明する。

1, https://repo.anaconda.com/archive/ より、Anaconda3-2025.06-1-Windows-x86_64.exeでAnacondaをインストールする。

2, 検索機能を使い、スタートからAnaconda PowerShell Promptを開く。

3, 以下のコマンドを実行し、仮想環境を作成する。

conda create -n (任意の仮想環境名) python=3.12.7

4, 先ほど作成した仮想環境をconda activate (仮想環境名)で起動させる。

5, 以下のコマンドを実行し、必要なライブラリを導入する。

pip install ase==3.26.0 fairchem-core==2.7.1 torch==2.6.0
  • fairchem-coreは、FAIR Chemistryが管理しているNNPを動作させるために必要なライブラリである。
  • aseはNNPに電子エネルギーを算出したい分子構造を渡すために必要なインターフェイスの役割を果たすために必要なライブラリである。
  • torchはPyTorchライブラリを指す。これはニューラルネットワークなどの機械学習を行ったり、学習結果を扱ったりするために必須なライブラリである。

これで、Anaconda PowerShell Promptから仮想環境を立ち上げることで、NNPを使用する準備が整えることが出来る。

次に、NNPを使用するために必要なModelの情報が保存されている.ptファイルのダウンロードおよびNNPの自作ライブラリへの導入方法について説明する。

1, 以下のサイトにアクセスして、uma-s-1p1.ptをダウンロードする。(使用許諾が下りていれば可能である。)

https://huggingface.co/facebook/UMA

2, ダウンロード後、MultiOptPy-v1.18bディレクトリ内に存在するsoftware_path.confに対して、uma-s-1p1.ptの絶対パスを用いて以下を追記する。

uma-s-1p1::(uma-s-1p1.ptの絶対パス)

これで、MultiOptPy-v1.18bがNNPuma-s-1p1を使用できるようになる。

使用するNNPに関する具体的な説明#

今回使用するNNPについて具体的に説明する。

  • UMAのModel Checkpointはuma-s-1p1を使用した。
  • 小分子系のトレーニングセットであるOmol25(omol)を使用して学習したニューラルネットワークポテンシャルを使用する。

※自作ライブラリでの具体的な使用の仕方に関しては、ase_calculation_tools.py を参照

手順#

1. 初期構造の準備#

モデル反応系として、以下の構造を用意した。今回はファイルの名前をbh9_3_1.xyzとした。 初期構造は以下のものを使用した。

7
OptimizedStructure
C     -0.482536678655     -0.257851790863     -0.846861304527
H      0.011615726269     -1.164152842340     -0.503679057748
H     -0.273478875202     -0.076354669414     -1.899000971806
H     -1.555312280743     -0.319172978747     -0.675318969116
F      0.018642809174      0.820275778074     -0.112314672879
S      0.578044636624      0.217773792397      2.251831878932
H      1.703024662534      0.779482710894      1.785343097144
初期パスを求めるための初期構造

2. 遷移状態構造最適化のための初期構造の算出#

a. 初期構造をカレントディレクトリにbh9_3_1.xyzとして保存し、以下を実行する。#

python optmain.py .\bh9_3_1.xyz -ma 1000 5 6 -os uma-s-1p1 -fc 50 -opt rsirfo_block_fsb -spin 2 -elec 0
  • -opt rsirfo_block_fsbは準ニュートン法であるRS-I-RFO法を構造最適化に使用することを示す。初期のへシアンに関しては、特にオプションで指定しない限り、単位行列が使われる。(以前のHessian更新法とは細かな点で異なる方法を使用している。具体的には、複数の座標変位や勾配変位を用いてHessianの更新を行う。)
  • -spinはスピン多重度の指定である。PySCFを使用するときは目的とするスピン多重度に1を引いた値を指定する。(デフォルトでは1が指定される。)今回はUMAモデルのNNPを使用し、ラジカル反応を扱うためスピンだ重度を2とした。
  • -elec Mは形式電荷をMとすることを示す。(デフォルトでは0が指定される。)
  • -ma yyy a bはyyykJ/molの活性化障壁を超えうるペア同士を近づける力を原子のラベル番号aとbのペアに構造最適化時に加えることを示す。
  • -os uma-s-1p1は今回使用するNNPを指定している。これを使用する際にASEライブラリが必要である。
  • -fc XはX回の反復計算ごとに正確なHessianを計算することを指定する。Hessianの計算コストは勾配の場合と比べると大きいが、構造最適化の収束までの時間を短縮できる。

これを実行すると、omolのデータセットを使用したuma-s-1p1モデルのNNPで得たエネルギーに対して、指定した人工力ポテンシャルを加えた上で初期構造を構造最適化することができる。

結果はyyyy_mm_dd(今日の年月日)ディレクトリの中に存在するディレクトリを開いて確認できる。

正常終了していれば、このディレクトリ中に、bh9_3_1_traj.xyzが存在するので、これをコピーして、MultiOptPy-v1.18bディレクトリに置く。

bh9_3_1_traj.xyzは構造最適化の過程をAvogadro(公式ページ:https://avogadro.cc/ )等で可視化して確認できるようにしている。このbh9_3_1_traj.xyzは次のNEB計算に使用する。

bh9_3_1_traj.xyzをアニメーションとして表示したい場合は、[https://github.com/ss0832/molecule_movie] を使うと良い。

(この人工力ポテンシャルを加えて行った構造最適化の結果はbh9_3_1_optimized.xyzで確認できる。構造を可視化して、生成系になっているか確認する。反応系のままであれば、-maの設定を見直してb.をやり直す。今回の場合以下の構造が得られた。生成系の安定構造に近いものが得られていると判断できるため、次のNEB計算を行うことが可能である。)

b. bh9_3_1_traj.xyzを初期パスとして、NEB法で経路の緩和を行う。#

NEB法を用いることで、先ほど得られたbh9_3_1_traj.xyz全体のエネルギーを下げることができる。これにより、パスのエネルギー極大値を持つ構造を遷移状態構造に近づける。(この時点ではまだ正確な遷移状態構造は求められていない。)

python nebmain.py bh9_3_1_traj.xyz -os uma-s-1p1 -ns 15 -aneb 3 5 -modelhess -spng -ndb 0.75 -ad 9999 -spin 2 -elec 0
  • -ad Xは線形補間で、各ノード間の距離を全て等しくするための処理である。X回の反復計算ごとに本処理を行う。Xを-nsよりも大きな数値を指定することで、初期経路に対してのみ処理を行うことが出来る。
  • -ndb Nはノード間の距離をN Åとして初期経路を作成することを示す。経路作成時に元のノードをベルンシュタイン多項式を用いてがたついた経路を滑らかにする。

→プログラムの仕様上-adの処理を行った後に、-ndbの処理を行うようになっている。

  • -ns nはn回分NEB法による経路の緩和を行うことを示す。
  • -fc MはM回あたりの経路緩和回数に対して1回だけ正確なHessianを計算し、経路緩和に使用する。これを使用すると、Hessianを使用しない場合の経路緩和アルゴリズムとは別のものを使用して、経路緩和を行う。
  • -spngは緩和中のパスのエネルギープロファイルや各ノードの勾配のRMS値をmatplotlibで可視化するオプションである。
  • -os uma-s-1p1は今回使用するNNPを指定している。これを使用する際にASEライブラリが必要である。
  • -aneb A Bこれを指定すると、(B+1)回の緩和ごとに、エネルギー極大値を示すノードと前後のノードの間に線形補間でA個の新規ノードを内挿するようにできる。デフォルトではこのような操作は行われない。このオプションを使用するとノードの数が徐々に増えるため、計算コストが使用しない場合と比べて増加する。一方で、エネルギー極大値を示すノード周辺にノードを増加させるため、緩和している経路中のノードが遷移状態構造付近に存在する可能性が高くすることが出来る。

c. 初期構造の決定及び遷移状態構造の計算#

MultiOptPy-v1.18bと同じディレクトリ内に、NEBという名前を含むディレクトリが生成されている。 そのディレクトリ内のenergy_plot.csvを確認し、緩和後のパスのエネルギー極大値を示す構造を確認する。

パスの緩和後の各ノードのエネルギー一覧(単位) (energy_plot.csvに保存されている。)

NEB計算の結果の可視化
NEB計算の結果の可視化

bias_force_rms.csvにて、各Iterationごとのすべてのノードの勾配のRMS値を確認できる。

経路緩和の結果、経路のエネルギー極大値を示す構造の中から目視で、緩和後に得られた経路の6番(グラフ上では7番)の構造を遷移状態構造を求める初期構造として採用した。

※こちら[https://ss0832.github.io/molecule_viewer/] を使うことでも可視化は可能である。

bh9_3_1_traj_6.xyz

7
0 2
C      -0.559164146794     -0.443292482956     -0.983781307803
H      -0.011930616389     -1.265792676801     -0.554084172098
H      -0.130744548059      0.120211358807     -1.789910963402
H      -1.604935641079     -0.348854812854     -0.765571416453
F      -0.064389054248      0.829027438255      0.408590113408
S       0.589260882879      0.357423070137      2.071065288739
H       1.781903123690      0.751278105411      1.613692457610
NEB法により緩和した経路から得られた遷移状態構造を求めるための初期構造

構造が壊れていないので、これを遷移状態を求めるための初期構造とする。

遷移状態構造を求めるための初期構造を含むxyzファイルをMultiOptPy-v1.18bと同じディレクトリ内にコピーする。

そして、以下を実行する。

python optmain.py .\bh9_3_1_traj_6.xyz -spin 2 -elec 0 -os uma-s-1p1  -tcc -freq -opt rsirfo_block_bofill -order 1 -fc 5 -tr 0.2
  • -opt rsirfo_block_bofillは遷移状態構造の最適化向けのoptimizerを指定することを意味する。準ニュートン法であるRS-I-RFO法を使用する。今回は-fcで正確なHessianを計算するようにしているので、初期Hessianは正確なHessianを使用するようになっている。(Bofill法によるHessianの更新法を細かい点で変更している。具体的には、複数の座標変位や勾配変位を用いてHessianの更新を行う。)
  • -order 1は一次の鞍点を求めることを指定する。(デフォルトだと極小値を求めるようになっている。)
  • -fc 5は5回の反復回数当たり1回正確なHessianを計算することを指定する。
  • -freqは収束条件を満たした後に基準振動解析を行うことを示す。(自前で実装しているため、あくまで目安として使用することを推奨する。各振動モードをvibration_animation内のxyzファイルで可視化できる。)UMAモデルから算出されるHessianは数値微分により求めているため、原子数Zが多いとZの二乗オーダーで計算コストが急増する。
  • -tccは収束条件を厳しくすることを示す。(Gaussianのtightと同等)
  • -tr Dは一回の反復計算ごとの計算されるステップ幅の最大値をDÅ以下にすることを示す。

実行して得られた正確な遷移状態構造と思われる構造を以下に示す。

(実行して得られた正確な遷移状態構造は計算開始時に、yyyy_mm_ddディレクトリ内に生成された新規ディレクトリ内のYYY_optimized.xyzとして保存されている。)

7
OptimizedStructure
C     -0.611950135561     -0.457829725098     -1.062226898988
H     -0.097283418923     -1.399597882893     -0.965264686138
H     -0.195928585698      0.289142113074     -1.718092603490
H     -1.669450297419     -0.429492212932     -0.857221537972
F     -0.024165210331      0.327102281426      0.611978215587
S      0.701293808126      1.101660967700      2.137923487982
H      1.897483839806      0.569014458723      1.852904023019
遷移状態構造

停留点に収束した分子構造が得られた。-freqオプションにより生成されたnormal_modes.txtvibration_animationディレクトリ内の振動モードのアニメーションを確認した。

以下に-freqオプションで生成されたnormal_modes.txtの一部を示す。

Mode                                 0                   1                   2
Freq [cm^-1]                     -785.5586              9.0999             79.0888
Reduced mass [au]                  15.9604              1.0506              6.0578
Force const [Dyne/A]               -5.8030              0.0001              0.0223
Char temp [K]                       0.0000             13.0927            113.7912
Normal mode                   x         y         z            x         y         z            x         y         z     
       C                -0.04397   -0.05758   -0.12084    0.00303   -0.02000    0.00819    0.03737    0.08562   -0.04430
       H                -0.00213   -0.02244   -0.01982    0.28726    0.12173   -0.12415    0.01356    0.06371   -0.13093
       H                -0.00305   -0.00137   -0.02776   -0.29646    0.14469    0.00581    0.09664    0.16273    0.08107
       H                -0.02025   -0.00900   -0.01455    0.02145   -0.33964    0.14769    0.02371    0.07970   -0.11332
       F                 0.06458    0.07798    0.15541   -0.00602    0.03743   -0.01566   -0.05741   -0.14148    0.09765
       S                -0.02179   -0.02437   -0.04637    0.00784    0.00760   -0.00701    0.01732    0.04730   -0.03881
       H                 0.02280    0.02161    0.04251   -0.18369   -0.63545    0.39082   -0.04601   -0.15897    0.08109
       
(...snip...)

その結果、虚振動が1つであることが確認できた。つまりこの構造は遷移状態構造である。

次に、vibration_animation内の虚振動を示す分子振動が示されたxyzファイル(mode_1_XXXi_wave_number.xyz)をAvogadroで確認すると、想定される反応系と生成系をつなぐ方向に振動していることを確認できた。

終わりに#

   自作ライブラリで、UMAモデルのニューラルネットワークポテンシャル(NNP)を用いて、BH9データセット 3. Halogen atom transfer, No. 1の反応のある1つの遷移状態構造を算出する手順を説明した。

参考#

【計算化学】自作pythonライブラリで遷移状態構造を求めてみる(BH9データセット, 3. Halogen atom transferのNo. 1の素過程, NNP使用)
https://ss0832.github.io/posts/20251004_mop_usage_182/
Author
ss0832
Published at
2025-10-04