
LAMMPSの外部で初期値を作る
はじめに
これまでの講座でいくつかのMDの例を学んできた。それらの例では、動的な計算を始める前にまず初期値を作ったことを思いだして欲しい。そのような初期状態はLAMMPSのスクリプト実行中にcreate_atomsコマンドなどを用いて作られた。しかし別の方法もある。それを紹介するのが今回の講座である。
LAMMPSのスクリプトは一般のプログラミング言語に比べて必ずしも使いやすいとは言えない。よって自分が望むような初期値が容易に作れない場合があるかもしれない。こういった問題が生じた場合は、自分の好きなプログラミング言語であらかじめ初期値を作っておき、それをスクリプト内で読み込ませることによって解決できる。
また、同じ初期値を何度も使って別の条件でMDを繰り返し行う場合は、LAMMPSに同じ初期値を何度も作らせるのは非効率的である。よってあらかじめ作っておいた初期値を読み込ませれば計算リソースの節約になる。
さて、以下では実際の例に従ってその方法を学ぶことにする。
外部で作る初期値の例
まず、LAMMPSに原子の状態をファイルから読み込ませるには、そのファイルは適切なフォーマットを有してなければならない。例として、file.inという名前で下のようなフォーマットで書かれたテキストファイルをscriptディレクトリに作っておいた。
# bcc Fe lattice points
31250 atoms
1 atom types
0.000000 71.382500 xlo xhi
0.000000 71.382500 ylo yhi
0.000000 71.382500 zlo zhi
Atoms
1 1 0.000000000000 0.000000000000 0.000000000000
2 1 1.427650000000 1.427650000000 1.427650000000
3 1 0.000000000000 0.000000000000 2.855300000000
4 1 1.427650000000 1.427650000000 4.282950000000
5 1 0.000000000000 0.000000000000 5.710600000000
...........
これまでスクリプトを説明してきたように、上の内容をステップバイステップで見て行こう。まず"#"で始まる行や空の行はLAMMPSのスクリプトと同様に無視される。よって実質的には3行目から意味のある内容が始まっている。
まず最初に、原子の総数を示している。ここでは31250個の原子で構成される初期値を作ることになる。
次が、原子種の数、ここでは1種類とする。ただし、この数はスクリプト内の記述、例えば用いる原子間ポテンシャルと矛盾しないようにしなくてはならない。
次の3行はボックスの定義だ。71.3825 Angstromの立方体の中でシミュレーションが開始されることになる。
次のAtomsは以下の行から原子のデータが始まることを示している。
各原子データは原子の通し番号(この場合は1から総原子数31250までの数)、原子種、原子のx、y、z座標で構成されている。原子の通し番号は同じものや抜けがあってはならない。原子種はこの場合は全て1、すべての原子座標は0と71.3825の間の値でなくてはならない。
非常に単純な構造をしているので受講者が知っている言語(例えばC言語やPythonなど)で初期値を作るためのプログラムを容易に作ることができるはずだ。複雑な初期状態を作成するにはスクリプトの高度なスキルが必要な場合が多く、LAMMPS初心者にとっては少し敷居が高いが、外部で初期状態を作る方法はそれを回避できる。
外部初期値の読み込み方
さて、今度は上で作ったファイルを実際に読み込む作業をしてみよう。上記のfile.inを読み込んで構造緩和させるだけのスクリプトがscriptディレクトリの中のbccFe_read_data.lcmである。その中身のすべてを以下で一気に表示する。
units metal
boundary p p p
atom_style atomic
read_data file.in
pair_style eam/fs
pair_coeff * * ./potentials/Fe_mm.eam.fs Fe
dump 1 all custom 100 bccFe_read_data.out id type xs ys zs
neigh_modify every 1 check yes
fix 1 all box/relax iso 0.0 vmax 0.001
min_style cg
minimize 1.0e-12 1.0e-12 1000 10000
1行目から3行目まではこれまでの講座で何度も出てきたので説明は不要だろう。
4行目で、上のように作成した初期値データfile.inをread_dataコマンドで読み込む。使い方は至ってシンプルである。
その後は構造緩和を行うの講座で説明したように、構造緩和を行っている。ここで改めて説明する必要はないだろう。
この方法を使った場合、これまで初期値を作るのに使ってきたlatticeコマンド、create_boxコマンドおよびcreate_atomsコマンドは不要となる。
スクリプトの実行
上のスクリプトを以下の要領で実行する。
$work> lmp_serial -in script/read_data.lcm
計算が終了したら、標準出力で構造緩和がうまくいったことを確認し、workディレクトリの中にできたbccFe_read_data.outをOVITOで読み込み、画像を確認しよう。
ディスカッション
この例だけを見ると、外部初期値の方が短い行数で実現できるためスクリプト内で初期値を作るよりも優れているような気がする。しかし、必ずしもそうではなくディメリットもある。それは、どういう計算をさせたかという記録を保存する時に、スクリプトだけでなく初期値も一緒に保存させておく必要があることだ。非常に多くのケースを扱う場合には2つのファイルをペアでとっておくというのはひと手間多く、ちょっとした混乱に原因になりうる。つまり、1つのスクリプトファイルの中にMDの全ての情報を含ませておいた方が計算結果を整理しやすい。というわけで、メリットとデメリットを理解した上でこの方法を採用するのが良い。
また、MDを利用する場面でよく遭遇するのが、すでに行ったMDの途中結果や最終結果を初期値としたい場合である。これらの結果は上で出てきたようにdumpコマンドによって出力されるが、その出力ファイルをそのまま初期値として読み込んでもフォーマットが異なるのでうまくいかない。この場合はフォーマットを変換するプログラムが必要になる。これまでdumpコマンドの利用例を学んできたが、いずれも特定のdump ... custom形式の出力ファイルだった。これはOVITOで結果を解析するために選択したフォーマットである。それを初期値のフォーマットに変換するにはプログラムを自作すると良い。ファイルを読み込んで別のフォーマットで保存するだけなので、どんなプログラム言語でも簡単なプログラミングで済む。
また、write_dataコマンド使う方法もある。このコマンドは現状態を上記のread_dataで読めるような形式でセーブするコマンドだ。一度限りならこちらの方が手間は少ないが、すべてのMDでdumpコマンドによる出力は必ず行うので、個人的には変換プログラムを使うことを選択している。
目次へ 前は照射損傷をモデル化する 次は刃状転位を挿入する