Bluepostech

プログラムとかはこっち

【fortran】設定値を別ファイルで与える(namelist)

大規模計算プログラムには大量の設定すべきパラメータがある。物理定数のように内部で与えておけばよいものもあるが、頻繁に変えて実行するものもあり、内部で与えるとその都度コンパイルしなければならず効率が悪い。

簡単に思いつくのは、「平文のまま設定値を順番に書き下してread文で読ませる」という方法だ。しかしこれだと設定ファイルが数値(時々文字列や論理値)の羅列になってしまい、可読性に欠ける。

そこで、fortranにはnamelistという機能がある。これはソースファイルとは別の設定ファイルに決まった書き方で書いた設定値を読み書きできる機能で、これを使えば比較的わかりやすい書き方で設定値を与えることができる。

使うには、まずは実行コード側でnamelistを定義する必要がある。これにはnamelist文を使って次のようにする。

 namelist/hoge/ xx,yy,zz

ただしこの文の前で変数xx、yy、zzがそれぞれ定義されている必要がある。*1設定ファイルとはいえ別ファイルなのでopenで開いてreadで読む必要があり、writeで書き出すこともできる。そのためread、writeにはnmlというパラメータが準備されている。

一方で、設定ファイルのほうは次のように記述する。

&hoge
xx=1d0,
yy=2,
zz='hoge',
/
!

注意しなければならないのは、「最後のスラッシュのあとに改行が必要」ということである。どういうわけかgfortranではこれがないと「End of file」というエラーが出るようだ。

ここではhogeというリストひとつしか記述していないが、ひとつの設定ファイルに複数個のリストを書くこともできる。この場合リスト単位で読み書きができる。

まとめて、上記の設定ファイルを「params.in」としてそれを読みとって「out.in」という名前で保存するプログラムを書くと、次のようになる。

program main
  implicit none
  double precision :: xx
  integer :: yy
  character :: zz
  namelist/hoge/xx, yy, zz

  open(10,file='params.in')
  read(10,nml=hoge)

  open(11,file='out.in')
  write(11,nml=hoge)

  close(10)
  close(11)
end program main

 

*1:implicit noneが適用されている場合。fortranプログラミングでは変数の書き間違いによるバグを防ぐためにimplicit noneは強く推奨される。