namelistの使用方法

namelistって何

外部ファイルからのインプットが多少楽になる形式.
read 文を複数行にわたって書かなくて済む.

基本的な使い方

本文

以下のように変数及び namelist の種類を宣言する.

 integer nx,ny,nz
 real*8 dx,dy,dz
 character*128 listname
 character*128 fnamein1 ,fnamein2
 character*128 fnameout1,fnameout2
 
 namelist /dim/nx,ny,nz,dx,dy,dz
 namelist /filenamein /fnamein1 ,fnamein2
 namelist /filenameout/fnameout1,fnameout2

namelist と書いてある文の 2つの "/" の間の文字列は,namelist の名前(種類).理解のしやすさ,利便性に応じてグルーピングする.
2つ目の "/" 以降には,そのグループに含まれる変数名を書く.
読み込む際は read のあとに 'nml=(namelistの名前)' をつける.

 !! namelistが記されたファイルを開く
 open(11,file=listname,status='old',action='read')
 !! 読む
 read(11,nml=dim)
 read(11,nml=filenamein)
 read(11,nml=filenameout)
 !! 閉じる
 close(11)

こうすると,namelist にある変数が1行の read によって読み取られる.

namelistのファイル

各値を設定するファイルには,以下のように記述する.

&dim
nx = 100 !コメントも可
ny = 150
nz = 20
dx = 5.0d0
dy = 5.0d0
dz = 10.0d0
/
&filenamein
fnamein1 = "./input/foobar.dat"
fnamein2 = "./input/hogehoge.in"
/
&filenameout
fnameout1 = "./output/foobar.csv"
fnameout2 = "./output/hogehoge.dat"
/

コメント行も挿入できるし,= の間にスペースがあっても良い.
ファイル名等を指定するcharacter型の場合は,クォーテーションマーク("")をつけた方が無難.""がないと,ドット(.)やスラッシュ(/)がある場合にエラーになったり,途中で読み込みが終了してしまう.


注意!

対応可能なフォーマットがコンパイラによって異なる. 例えば,

& dim

のように & とリスト名の間にスペースが入ることは gfortran では許されないが,ifort では大丈夫だった.また,

ny = 150,

のように行末カンマが必須なこともある.

さらにさらに,gfortran (v12時点)では, namelist のファイル末尾に空行がないとエラーになった.つまり

/

が最終行だとエラーになる.後ろに1行空行を入れるだけでエラー回避できる. ファイル末尾が "/" 前者の場合に下記のようなエラーが出て,原因を長いこと探してハマった.

 At line 47 of file hoge.f90 (unit = 11, file = 'hoge_namelist.nml')
 Fortran runtime error: End of file
 
 Error termination. Backtrace:


文字列を使用するとき

namelistで読んだchatacter変数を使用するときは,

open(12,file=trim(fnamein1),status='old')
open(51,file=trim(fnameout1),status='replace')

のように trim を使う.trim がないと宣言した文字列の幅になるように空白文字列が入ってしまうようだ.

getargを使ってnamelistを読んでみる

namelistのファイル名をnamelist.in,実行ファイル名をfoobar(.exe)として,

./foobar namelist.in

と実行できるようにするには,getarg を使ってコードを下記のように書く.

if(iargc()>0)then
   call getarg(1,listname)
   write(*,*)trim(listname)
   open(11,file=trim(listname),status='old')
   read(11,nml=fname_input)
   read(11,nml=fname_output)
   close(11)
else
   write(*,*) 'No input argument'
   stop
end if

Front page   Edit Diff Attach Copy Rename Reload   New List of pages Search Recent changes   Help   RSS of recent changes
Last-modified: 2020-01-15 (Wed) 04:52:09 (1557d)