やさしい(?)バンド計算プログラムの作り方 [Top]

目次
準備(バンド計算プログラムを作成するのに必要な予備知識、道具)
バンド計算プログラム作成前に注意しておくべきこと
実際のコーディング
プログラム全体の構成
プログラムのメイン部分
メインルーチンの内容(各論)

【注意】:今は、”作る”より”使う”[時代 ](11/26、2002)
本当は、バンド計算(第一原理電子状態計算)プログラムを1つでも作るこ とは、大変な時間と労力と知識を必要とし、決してやさしいものではありませ ん。

ただそれを言ってしまっただけで話しを完結させてしまうと身もふたもない ので、可能な限りわかりやすく説明を行ないたいと思います。
このようなものを書く理由の一つに、自分の持っているプログラムの整備を 行ないたいという意味も込められています。ご存知のように擬ポテンシャルデー タベースNCPS95を構築中(現在、NCPS2Kを[配布中]:11/26、2002)ですが、こ れはこのポテンシャルデータを利用できるプログラムがないことには、このデー タベースは何の役にも立たないことになります。

こういう意味では、自分のプログラムも一緒に公開すれば良いのですが、な かなかそうは行かないわけです。その理由として、

(1)プログラムに汎用性が(全く)ない。
(2)プログラムの可読性が非常に悪い。
(3)プログラム内に他の共同研究者との共作の部分があり、著作権の問題が絡 んでくる。
(いろいろと公開するための事前の手続きが面倒)

特に、(1)、(2)の問題が深刻で、公開することを想定していないでバ ンド計算プログラム(第一原理分子動力学法)を作ったので、非常に難解で、 動かしにくいものになっています。またプログラムに関してのドキュメント、 マニュアル等が全くないことも、公開を妨げる原因の一つになっています。

そこで、公開することを想定(最近一部公開 しました、3/18)して、プログラムに関してのドキュメントを充実さ せるために、このような企画を立てました。これによって、自分のプログラム 作成に関するノウハウを公開し、かつこれによってドキュメントも充実させる ことができます。

準備

バンド計算プログラムを作成するのに必要な予備知識、道具

まず最低線、量子力学の知識が必要です。成積はどうでもよい(というわけ でもないが)ですが、どのような参考書や、どの本のどこらへんの部分を調べ れば良いか位はわかる程度の知識は必要です。特に縮退とか固有値問題、固有 ベクトル(線形代数の知識でもある)、バンド理論(物性論の知識でもある)、 変分原理、ハートリー・フォック近似(平均場近似)、摂動等の用語を知って いるか、すぐに調べられる(そして理解できる)程度でなければなりません。

量子力学以外にも、固体物理の知識も必要です。ブロッホの定理やバンド理 論、逆格子空間の概念、ブリュアンゾーン、結晶対称性や群論など結晶学的な 知識などを理解しておく必要があります。(群論などは絶対必須というわけで はありませんが、知らないと後々苦労することがあります。)

バンド計算と言うからには計算機や計算機言語に対しても深い知識が必要で す。普通、第一原理電子状態計算のプログラムのソースコードは、全部で1万 行(コメント等を含めて)以上にもなります。人によってこれが大きいか、小 さいかは異なると思いますが、普通の計算物理未経験の研究者にとってみれば これは非常に巨大な部類に入ります。できれば千行以上のソースコード(用途 は問わない)を作成、運用、保守の経験があるのが望ましいと思います。

使用言語としては、大抵のバンド計算プログラムはFORTRAN(それも 77)で書いてあります。古いものではFORTRAN66以前の形式で書か れているものもあります。最近、FORTRAN90も大部普及してきました。 もし、全くゼロの状態から作り始めるのなら、FORTRAN90の仕様でプ ログラムをコードした方が良いかもしれません。(少なくとも、77仕様でも すぐにかつ楽にFORTRAN90に 移行できるようにしておくと良いと思います。)

最近、CやC++でバンド計算プログラムを書いたり、FORTRANから 移植する例もあります。私個人としてはC、C++が必ずしも向いているとは 思いませんが、どのような言語で書くかは当事者の自由です。(JAVAで書 こうとする者も出てくるかもしれません。)

バンド計算プログラム作成前に注意しておくべきこと

プログラム作成一般に言えることと思いますが、以下のようなものが挙げら れます。

  1. プログラムに汎用性があること
  2. 可読性が良いこと
  3. いろいろな機種、OSで動くこと(を想定して作る→汎用性)
  4. 計算対象マシンがベクトル計算機ならベクトル化について留意する
  5. 著作権等の留意(特に複数のユーザーで作る時や、公開版として作る場合)
  6. 改造、拡張、他機種への移植が容易なこと(汎用性、可読性)
  7. 以上を実現するために、プログラムコーディング前に十分計画を練る
最初の段階で、コーディングの方針と作業計画を十分練る必要があります。 まず全て全くゼロから作るのか、誰かのプログラムを拡張させるのかで、大分 方針が異なってきます。特に元になるプログラムがある場合、その元プログラ ムの汎用性や可読性が、新たに作っていくプログラムの運命を決定付けてしま います。

また元プログラムが存在する場合、その設計方針(使用言語、稼働対象マシ ン、OS、プログラム仕様等)に従わなければなりません。もし従わないと、 結局ゼロから始めた方がマシになります。

言語をFORTRAN77にするか90にするかは、大変重要な問題です。 HPF(High performance FORTRAN)という選択もありますが、これはFOR TRAN90程(日本では90でさえまだ普及しているとは言えない)には普 及していません。

FORTRAN90は(1)動的な メモリの使用が可能、(2)モジュール文の存在(77でのコモン文はいらな くなる)、(3)構造体の存在、(4)強力な行列演算機能、(5)行列表現 の簡略化、(6)1行に複数の命令が可能、(6)再帰呼び出し可能、(7) SELECT---CASE文、DO---WHILE文、DO---END DO文等新しい命令の存在、(8) ポインターの概念の存在などなどが挙げられます。

特に、(1)の機能は大変魅力あるもので、これは実行中に必要な配列サイ ズを、事前に考慮しなくても計算を遂行できるようにすることが可能で(機種 とOS、計算機運用環境に依存し、バッチで処理して複数のユーザーが使用す るシステムでは動的メモリ割付けは実際上不可能)、非常に柔軟な計算が可能 になります。例えば、系のサイズの変化や、計算条件の変更で、いちいち配列 のサイズ変更による再コンパイルを繰り返す必要がなくなります。

その他に、構造体の概念や行列演算部分の簡略表示などは、うまく利用すれ ば、プログラムを非常に使い易いものにし、汎用性や可読性をも向上させるこ とができます。一方、バンド計算は基本的に、たして、ひいて、かけて、わっ て、だけで計算できてしまうもので、このようなものにポインターのような概 念が本当に(バンド計算エンドユーザーにとって)必要かどうか甚だ疑問では あります。(少なくとも必須のものではないし、これまで、ポインターの概念 がなくてもバンド計算プログラムはきちんと動いてきました。(当然、非常に 計算に達者な者はこの限りではありません。)

もし既存のプログラム(FORTRAN77仕様)を改良、拡張するなら、 無理をしないで、FORTRAN77でプログラムをコーディングしていった らいいと思います。ただ近い将来FORTRAN90に移行することを考えて コーディングしておいた方が良いと思います。(なるべくコモン文は使用しな い、DO文はEND DOで終るようにする、ちゃんと汎用性、可読性を考慮 してプログラムを書けば、90への移行はそう困難なことではないと思います。)

既存のコードを流用する場合、元のプログラムが非常に、汎用性や可読性に 欠ける場合はどうすればよいでしょうか?
結論としてはどうしようもないと思います。自分で、修正するか、汎用性や 可読性のなさに目をつむってそのまま拡張、改良していくしかないと思います。 なるべく元になるコードも、汎用性、可読性の良いプログラムを使用すること を勧めます。(ただ最初に見ただけでは、なかなかそれがわからないとは思い ます。)

実際のコーディング

では次に、実際のコーディングについて説明を行ないたいと思います。

自分の所有するプログラムは第一原理分子動力学手法を使って、系の安定構 造とその電子状態を計算するもので、これは自分が東大物性研の寺倉研にいた 時代に作成を開始しました。(寺倉先生は現在工業技術院産業技術融合領域研 究所に所属しています。)

これには元になるプログラムがあり、これは当時寺倉研の助手であった石田さ ん(石田先生は現在、日大文理に所属しています。)が作ったものでした。この 段階で、BHSの論文(G. B. Bachlet, D. R. Hamann and M .Schluter, Phys. Rev. B26, 4199(1982))の表のパラメーターをもとに平面波基底を用いたバンド 計算が可能でした。これに力の計算部分を加え、Kleinman-Bylanderの分離形( L. Kleinman and D. M. Bylander, Phys. Rev. Lett., 48, 1425(1982))を導入 し、1990年春にはカー・パリネロ計算(第一原理分子動力学計算)が可能と なりました。

この1990年春の段階では、プログラムとしては、最急降下法による対角 化を用いない電子状態の計算と、ユニットセル内の力の計算ができ、それをも とにした初歩的な分子動力学計算ができるだけでした。

ここで、現在のプログラムの先頭部分 を示したいと思います。
これはプログラムの最初の注釈行です。御覧のように1989年5月4日か ら本格的なカー・パリネロプログラムの作成を開始し、いろいろな改良(部分 内殻補正や対称性の部分は現在産業技術融合領域研究所の森川先生が作成した。)、 拡張を行ない現在に至っています。現段階で、このプログラムは以下の計算が 可能です。

  1. BCC、FCC、HCP、SC、正方晶、斜方晶等の結晶対称性を考慮した 計算が可能
  2. s、p、d、(f)を非局所ポテンシャルとした計算が可能
  3. 磁性を考慮した計算が可能(ここで示しているプログラムのバージョンでは 不可)
  4. ユニットセル内の原子に働く力以外に、系そのものに懸かるストレス(圧力)の計算が可能
  5. 完全ではないが、上記ストレスを使用して、定圧条件での構造最適化が可能
  6. 部分内殻補正を考慮した計算が可能(力、ストレスに対する補正も考慮)
  7. 富士通のベクトル並列計算機VPPシリーズでの並列計算が可能
  8. 直接プログラム内容とは関わりないが、NCPS95を使って、非常に広範な範 囲の電子状態計算が可能
逆に、現在できない機能として以下ののものが挙げられます。
  1. LDAを越えた計算はできない。(GGA、SICなどはできない。
    但し、現在SIC擬ポテンシャル を検討中、3/18、1997)
  2. スピン軌道相互作用は考慮されていない。
  3. 電子状態計算部分は基本的に絶対零度の計算(有限温度の計算は不可)
  4. 非常に複雑な対称性を持つ系に対しては、対称性なしで計算するしかない。
  5. VPP以外での並列計算(PVM、 MPI等)には対応していない。

プログラム全体の構成

では次に、プログラム全体の構成について話したいと思います。
まずプログラムのサブルーチン構造ツリーを示します

次に、プログラムのおおまかな流れ(ループ)を示します
LOOP0は、最も外側のループで、一定圧力下での構造最適化を行なう場合の ものです。この場合、ユニットセルを規定する格子パラメーターそのものが最 適化されるので、ループの範囲はこのようになります。

LOOP1は、通常のカー・パリネロ法による、系の内部構造とその電子状態を 最適化するループです。
LOOP2は、電子状態部分のみ計算する場合のループで、サブルーチンMDは 計算されません。

更に、各サブルーチンのおおまかな説明を示します

次に、このプログラムで使用しているインクルードファイルと入力データを 示します。
インクルードファイル”PACVPP”
インクルードファイル”REINIT”
入力データ”I.DAT”
入力データ”CONTL.DAT”

他にも、擬ポテンシャルデータ入力ファイルがありますが、これは擬ポテン シャルの説明の記事で言及されているので略します。

インクルードファイル”PACVPP”は、主に変数(含む配列変数)の定義され た部分です。これをプログラム本体(revpe_d.f)中のinclude文で読み込みま す(REINITも同じ)。PACVPPではパラメーターの設定、主にコモン文による配 列変数の定義が行なわれています。最後の方にある、注釈行!XOCLで始まる部 分は富士通のベクトル並列スーパーコンピューターVPP500用の並列化制 御のための指示命令行です。

これを見てわかるように、コモン(大域定義)文によって定義された変数や 配列変数が多数あります。前述のように、可読性や汎用性、移植性を考えると、 このような変数定義の仕方はお勧めすることができません。あまり良くない例 と思って見てやってください。

インクルードファイル”REINIT”は、ファイル入出力のためのOPEN文に始ま り、計算制御用入力データCONTL.DAT入力部分(READ文使用)とからなります。

入力データ"I.DAT"は、この場合ヨウ素(I)の入力データを意味していま す。データの内容は主にユニットセルの格子パラメーターと、内部原子座標に 関するものです。但し、一部計算制御用のパラメーターが混じっています。ま た最後の行に局所擬ポテンシャル計算で使われるVcore用のパラメーターがあ ります。

入力データ”CONTL.DAT”は、計算制御用のパラメーターが入っています。 外部から懸かる圧力、結晶構造の種類、PCCを考慮するかしないか、イタレー ションの数などが主なパラメーターです。

ここでの重要な問題は、二つの入力用データが用途として完全に独立してい ないことです。座標定義用のI.DATに制御用のパラメーターが混じっています。 これはデーター内容の理解や、プログラム運用を甚だ面倒なものにします。

新たに、バンド計算プログラムを作ろうという方は、入力データの設計には 十分な配慮(データの割り振りと定義をきちんとする)が必要と思います。行 き当たりばったり的な入力データの構築をすると、後で後悔することになりま す。

プログラムのメイン部分

では次に、プログラムの メイン部分を示したいと思います。

メインルーチンだけでも400行もあります。ここでは第一原理分子動力学 計算の制御と、サブルーチンの呼び出しが行なわれているだけです。
このルーチンの問題点は、第一原理分子動力学計算の制御にあります。この 計算は3つに場合分けされています。

(1)第一原理電子状態計算のみ
(2)第一原理電子状態計算+ユニットセル内原子の構造最適化
(3)(2)+ストレスを使った系のユニットセルの最適化(定圧問題用)

最初は(1)と(2)の場合のみの計算に対応していました。この段階でも、 (1)のみの計算と(2)の計算を、最初の設定条件(CONTL.DATで設定)によ って計算を切替えるようになっていて、メインルーチンのプログラムの流れを 大変分り難いものにしていました。その後、ストレスの計算を導入し、系のユ ニットセルそのものを最適化できるようにするため、(1)、(2)、(3) の各計算を切替えて計算できるようにプログラムを書き替えたのですが、(3) の付加は、ほとんど場当たり的に、無理に付け足したものとなり、メインルー チンの構造は、複雑怪奇なものになってしまいました。

プログラム作成においてメインルーチンは、そのプログラムの顔とも言える 部分であり、ここが分りやすくすっきりしているか、そうでないかで、プログ ラムの見ためや、可読性を大きく左右します。教訓としては、先の入力データ 等のところでも述べたように、事前の設計や計算方針の決定は十分に時間をか けて、練りに練った上で、コーディングを開始すべきだと思います。

尚、メイン文がどのようなサブルーチンを呼び出しているかは、前述のサブ ルーチンツリーを参照して下さい。第一段目にコール(呼び出し)されている ものがメインルーチンで呼び出されているサブルーチンです。

では具体的に良いメインルーチンの書き方を考えて見ましょう。まず、

(1)どのようなバンド計算をするか、方針をきちんと決める。
(2)どのようにコードするかじっくり考える。
(3)計画、方針に則って、メインルーチンを書く。
(4)メインルーチンでは、具体的な計算を行なわない。
(5)基本的には、サブルーチンコールだけにする。
(6)呼び出すサブルーチン毎に何をするサブルーチンか注釈をつける。
(7)各サブルーチン毎に、時間を計れるようにしておくと、実行時での各サ ブルーチンの処要時間を割出すことができる。
(8)サブルーチン名も、なるべく誰が(少なくとも他のバンド屋が)みても わかるようなものにしておく。(例、DIAGON、EIGEN、FERMI、VELRET、SD等)
(9)計算が電子状態だけか、構造最適化も行なうかなどの場合分けは、すっ きり、分り易くする。(なるべく最初の段階で、方針を決めたら、後で安易に 変更しない。)

などが考えられます。

先ほど言及しましたが、このバンド計算プログラムでは、2つのインクルー ドファイルを読み込んでいます。[PACVPP][REINIT]

PACVPPは主に、変数(配列変数)等の定義、REINITはオープン文によるファ イルのI/O定義を行なっています。PACVPPは、メインルーチンを含めのほと んど全てのサブルーチンでも取り込む(インクルードする)ようになっていま す。REINITはメインルーチンで1回だけ取り込みます。

OPEN文に関しては、I/O用のファイル名を変更する毎に、プログラムをコン パイルし直さなければならないので、少々不便です。OSやベンダーに依存し ますが、OS上の環境設定段階で、ファイル入出力を制御することも可能です。 例えば、昔のメインフレーム大型コンピューターでは、JCLを使ってOPEN文 を使わないで、ファイル入出力が制御でき、この場合、プログラムの再コンパ イルをする必要はありません。UNIX環境でも、これに似たことをすることが可 能です(確か。setenvを使う)が、ここではこれ以上の説明はしません。各自 で、自分の環境に対応した方法を探してください。

メインルーチンの内容(各論)

ここで、メインルーチンにおける、計算の大まかな流れを説明したいと思い ます。
(1)まず最初に行なうのが初期設定部分で、計算するべき系の格子パラメー ターや、擬ポテンシャルデータ、計算制御パラメーターの入力。これらの入力 データをもとにした、逆格子空間座標の計算。必要(計算制御パラメータで指 示してあれば)ならば、空間群による対称性の計算。初期電荷密度の計算(ガ ウス関数を用いた初期電荷密度を使用)。エバルト和の計算(いわゆるマーデ ルングエネルギーの計算)。フォームファクターの計算。などが挙げられます。

(2)次に、読み込んだ擬ポテンシャル (局所、非局所)のフーリエ変換を行ないます。以下に、局所ポテンシャルの 座標変換の式を示します。

V_loc(G)=int{j_0(G*r)*V_loc(r)*exp(-i*G*r)}/Ω

ここで、Ωは体積、V_loc(G)は逆格子空間での局所擬ポテンシャル、 V_loc(r)は実空間(動径方向)の局所擬ポテンシャル、j_0(r)は0次球ベッセ ル関数、intは積分の意、G、rはそれぞれ逆格子空間座標、実空間(動径)座 標です。

非局所擬ポテンシャルは、局所の場合より複雑になります。(従って、表式 による説明は行ないません。)特に、このプログラムではKB近似による分離 形を使っているので、計算手順がいろいろと複雑になっています。これは後の プログラムの説明を見ていくと次第に明らかになっていくものと思います。

さて、久しぶりに続きを書いていきたいと思います。(11月7日、199 6年)

(3)次に、交換相関エネルギーまたは交換 相関ポテンシャルの計算を行なっています。どちらの計算をするかは、状 況によって異なりますが、メインルーチン上では、交換相関ポテンシャルの計 算を行なっています。(どちらを計算するかわ、サブルーチンの引数によって 選択できるようになっています。)
これは後で、電子状態計算のための行列要素の計算を行なう時に使います。

(4)一回目のイタレーションでは、行列の対角化を使って電子状態を解きま す。これは初期固有エネルギーと初期固有ベクトル(つまり波動関数)を用意 するためです。これら固有エネルギーと固有ベクトルを使って、次のイタレー ションからカー・パリネロ的な逐次的な実行により波動関数を求めていきます。

対角化の際、解くべき行列の要素数は、実際の平面波の数より少なめにとり ます。本計算では普通、GMAX/2(つまり通常の平面波の1/8の空間) に対応する行列の対角化を行なっています。これだけでも、初期の固有ベクト ル(波動関数)としては十分です。非常に大きな系を扱う場合は、更に、初期 の行列要素数を少なくしますが、その分、電子状態計算の収束が遅くなります。 (当然、極端に少な過ぎると、計算が収束せずに、破綻する可能性があります。)

2回目以降のイタレーションでは、カー・パリネロ的な手法(実際は時間の 1次微分方程式として扱う、最急降下法〔SD法〕)を用いて、電子状態を解 いていきます(固有値、固有ベクトルを求める)。解き方の内容の詳細は、私 の書いたD論(東京大学、1990年度)に書いてあります。現在も方法論的 にはほとんど進歩していません。カー・パリネロ法に関しては、カー・パリネ ロの最初の論文(R. Car and M. Parrinello, Phys. Rev. Lett., 55, 2741(1985))をはじめ、多数の論文や詳しい解説 (日本語によるものもある)が出ていて、探せば容易に入手することができま す。

メインルーチンでは、一回目と二回目以降で、対角化とSD法による場合分 けを行なっています。以下参照。

      IF (ITER.EQ.1) THEN                                               
          CALL TIME(ITIME1,'      ',1)                                  
          CALL KBMAT 
          CALL DIAGON(IREC8)                                            
          CALL KBINT 
          CALL TIME(ITIME1,'KBMSD ',2)                                  
        ELSE                                                            
          CALL TIME(ITIME1,'      ',1)                                  
          CALL MSD(IREC8,IREC9,IMD,ICAR,ISTR) 
          CALL TIME(ITIME1,'MSD   ',2)                                  
      END IF                                  
これは、比較的単純なIF文による場合分けです。メインルーチンにはもっと 複雑怪奇な場合分けをしている部分もあります。当然、条件判定を変更して、 最初から最後まで、行列の対角化のみで、電子状態の計算を遂行していくこと も可能です。但し、最初から(対角化による初期固有ベクトルなしに)SD法 で始められるようにはなっていません。

バンド計算グループによっては、初期固有ベクトルを乱数を使って、求めて おくという手法を用いているところもあります。この方法では対角化という比 較的面倒な手法を用いないので、労力や計算時間が稼げますが、その分、電子 状態の収束のスピードが遅くなります。(曲がりなりにも、対角化で求めた固 有ベクトル(波動関数)の方が真の解により近いため。)

(5)次に、電子状態(固有値、固有ベクトル)からフェルミエネルギーを求 めます。フェルミエネルギーは、実際は固有値(固有エネルギー)つまり、バ ンドの底から、扱っているユニットセル内の総電子数分を数えていき、1つの バンドに2個(up-spinとdown-spinで2個分)電子が詰まるとして、その詰ま り切ったところ(位置)を、フェルミエネルギーとしています。
詰めていく場合、各バンドとk点について足していきます。
Σ_i,k[ε(i,k)]=N

ε(E,k)が固有値で、これをi(バンド数)とk(k点)で足していき、足し た数Nが、ユニットセル内の総電子数と一致した場合のε(i,k)の値がフェルミ エネルギーとなります。但し、バンドとk点はとびとびの値で、固有値自身も 連続ではないので、金属的なバンドで、フェルミエネルギーを決める場合は、 なんらかの内挿を行なうか(例えばテトラヘドロン法〔四面体法ともいう〕な ど)、バンドに適当な幅を与える(大抵は、フェルミ分布関数か、ガウス関数 によってバンドにエネルギー方向に関しての広がり〔ブロードニング〕を与え る)などの方法をとります。これは一種の温度の概念を導入することでありま すが、本当の意味で密度汎関数計算で温度の計算が可能になったわけではあり ません。我々の計算でも後者の。バンドに広がりを与える方法を使いますが、 方法はもっと簡単で、放物線関数を使った非常に簡単な関数を使って、バンド の広がりに関しての積分を解析的に行なってしまいます。(詳しくは私のD論 参照)

(6)フェルミエネルギーが求まると、これによって力や電荷密度、全エネル ギー、ストレスなどの計算が可能となります。これは、これらの物理量がバン ドとk点に関しての足し上げによって求まり、その足し上げがフェルミエネル ギーのところまでだからです。つまり(5)でフェルミエネルギーが求まって いなければ、力、電荷密度、全エネルギー、ストレス等は求めることができま せん。フェルミエネルギーを求めるサブルーチン、FERMIを実行した後は、ま ず力の計算が行なわれています。但し、第一原理分子動力学計算では、最初電 子状態のみを断熱ポテンシャル面に落すため、ユニットセル内の原子に働く力 の計算を行なう必要がなく、電子状態の計算のみが必要となります。また、分 子動力学計算を行なっている時も、毎回(毎イタレーション)力の計算を行な わず、数イタレーションに一回力の計算を行ない、原子をその時だけ動かすと した方が、計算全体としての収束が速い場合があります(と言うより、ほとん どの場合で収束は速くなります)。このプログラムでは、力の計算を行なうサ ブルーチンで、非局所擬ポテンシャル用の行列要素の計算で必要な部分の計算 も一緒にやらせており、力の計算を必要としない場合は、この行列要素のため の計算のみを行なうサブルーチンが用意されています。そして必要に応じて切 替えてサブルーチンが呼び出されるようになっています。以下に、そのプログ ラム部分を示します。

      IF (MOD(ITER,IMDI).EQ.IRES) THEN
        IF (ITER.EQ.1 .OR. ITER.GT.IMD) THEN                            
          WRITE (6,*) 'CALL FORCE'
          CALL FORCE(IREC8) 
        ELSE
          CALL FORZFB 
        END IF
      ELSE
        WRITE (6,*) 'CALL FORZFB'
        CALL FORZFB 
      END IF
    
先の、DIAGON、MSD と比べて、場合分けがかなり複雑になっています。まず最初のIF文では、何 回かに1回の割で、力の計算を行なうように設定しています。内側にあるIF 文では、外側のIF文の条件を満たし、かつ第一回目のイタレーションか、ま たはIMD回より多くイタレーションが進んでいる場合に力の計算が行なわれ ます。そうでない時は力を除いた部分のみの計算(CALL FORZFB) が行なわれます。制御構造が大分複雑になり、プログラム作者でさえ、ちょっ と考えないとわからないくらいになっています。

(7)次に、電荷密度の計算を行なっています。これはサブルーチンMSDで 計算される波動関数(固有ベクトル)を使って求められます。この時、波動関 数同士のかけ算が、畳み込みの形になっているので、FFT(高速フーリエ変換)を使って、計 算量をNの自乗のオーダーをNlogNのオーダーまで少なくすることができ ます。

(8)その後、必要ならばストレスの計算 を行ないます。一応、一定圧力の条件でのユニットセルの形そのものの構 造最適化も可能です。サブルーチンを呼び出している部分を以下に示します。


          IF (ISTR.EQ.1) THEN
              CALL TIME(ITIME1,'      ',1)                              
              CALL STRESS(IPCC,SCHGPC
     &       ,ETOT1,TOTCH,EPC,PCM,KOPR,KBZTYP) 
              CALL TIME(ITIME1,'STRESS',2)                              
          END IF                                 
   
ここで、制御用の変数ISTRがクセ者で、一応ISTRの値が1の場合に、 ストレスの計算を行なうようにさせていますが、この場合、ユニットセルの形 が変わることを想定したプログラム制御を行なう必要があり、そのための制御 をするための部分を、後から(場当たり的に)付け足したため、メインルーチ ンの構造が複雑怪奇なものになってしまいました。

(9)次に、非局所部分以外の力の寄与の部分の計算と、場合によっては対称 性を考慮するための計算を行ない全ての力を足し上げます。その後、この力を 使って分子動力学計算(ユニットセル内の原子の最適化、及び、必要ならスト レスを使って、ユニットセル自身の構造最適化)を行ないます。分子動力学そ のものは、単純なベレのアルゴリズムを使った方法を用いています。
第一原理分子動力学計算では、この分子動力学計算部分は計算全体の1%に も満たないので、あまりプログラムに関してテクニカルな方法は用いていませ ん。

(10)そして、最終的に系の全エネルギーを求めます。ここでは交換相関エ ネルギーが必要なので、全エネルギー計算のためのサブルーチンで、交換相関 ポテンシャル、エネルギーを計算するためのサブルーチンを呼び出しています。

(11)最後に、全エネルギーに関しての収束判定と、 収束していない場合、次のイタレーションに進むために新しい(更新された) 電荷密度と、古い電荷密度の混合を行ないます。本当は、MSDでの波動関数 の更新処理の段階で、電荷密度の混合と類似(厳密には等価ではない)な処理 を施しているのですが、実際の計算では、ここ(収束判定のところ)でも新し い電荷と古い電荷の混合を行なっています。混合の仕方は単純混合です。この 方法を用いた方が、時間の刻み幅を小さくするより、経験的に収束がずっと速 いことがわかっています。
(注意)”電荷密度の混合と類似”:これは波動関数の混合操作を意味しませ ん。また、電荷密度の混合は各イタレーション毎の最後(収束判定)のところ で一度だけ行ないます。

単純な混合より、ブロイデンの方法な ど、より収束を速める混合手法がありますが、現在このプログラムでは使用し ていないので、これ以上の説明は行ないません。

12月16日(1996年頃?)、久々に話しを進めて行きたいと思います。 一応、以上の説明でメインプログラム部分の説明はおしまいです。これでプロ グラム全体の概要がある程度説明できたと思います。次の[各論編]へ進む。

(寄り道)
不肖この私目も物性研や原研のVPPを利用して、プログラムの並列化、及 びその実行を行なっています(既に、過去の話:11/26、2002)。こ の並列化作業の内容についての話は、[並列化 (VPP)]を参照。

[先頭][総目次 ][最初に戻る][各論編][デバッグ編 ]