この文書の現在のバージョンと選択したバージョンの差分を表示します。
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
fortran [2009/06/24 17:27] saito |
fortran [2009/12/01 13:59] (現在) saito |
||
|---|---|---|---|
| ライン 1: | ライン 1: | ||
| ====== Fortranのtips ====== | ====== Fortranのtips ====== | ||
| + | * intelのコンパイラは[[ifort]]参照のこと. | ||
| + | ===== コンパイラオプション ===== | ||
| + | |||
| + | * プログラム作成段階においては,配列外参照,暗黙の型宣言,浮動小数点演算例外の検出はつけてコンパイルした方が良い. | ||
| + | * プログラムが完成して,エラーがない場合には以下のコンパイルオプションはない方が良い.ない方が早く計算できる. | ||
| ^ compiler ^ gfortran ^ ifort ^ frt ^ | ^ compiler ^ gfortran ^ ifort ^ frt ^ | ||
| ライン 7: | ライン 12: | ||
| |暗黙の型宣言|-fimplicit-none|-warn declarations| | | |暗黙の型宣言|-fimplicit-none|-warn declarations| | | ||
| |浮動小数点演算例外の検出|-ffpe-trap=zero|-fpe0| | | |浮動小数点演算例外の検出|-ffpe-trap=zero|-fpe0| | | ||
| - | |標準外機能の警告|?|-std| | | + | |標準外機能の警告|-std=f95|-std| | |
| ===== 連番のファイル名をつける。 ===== | ===== 連番のファイル名をつける。 ===== | ||
| ライン 26: | ライン 31: | ||
| </code> | </code> | ||
| - | このファイルをperlに食わせて処理すると便利かも. | + | 処理は[[movie]]参照のこと. |
| - | 以下,サンプル. | + | |
| - | <code perl> | + | |
| - | #!/usr/bin/perl | + | |
| - | $gpfile .= sprintf("%s\n","set terminal gif"); | + | |
| - | $gpfile .= sprintf("%s\n","set pm3d map"); | + | ===== makefileでコンパイル ===== |
| - | for($i=1;$i < 30;$i++){ | + | |
| - | $file = sprintf("hoge%04d",$i*10); | + | 複数のファイル(サブルーチンetc.)で構成されるプログラムを動かすのに便利. |
| - | $gpfile .= sprintf("%s\n","set output \"$file.gif\""); | + | 以下の文を「makefile」という名前で作り,コンパイルしたいファイルと同じディレクトリに置く. |
| - | $gpfile .= sprintf("%s\n","splot \"$file.dat\" using 1:2:5"); | + | (以下,main.f90, modules.f90[モジュールファイル], sub1.f90, sub2.f90をコンパイルする場合) |
| - | }; | + | <code> |
| - | open (GP, "| gnuplot" ) or die "no gnuplot"; | + | TARGET = a.out |
| - | print GP "$gpfile"; | + | OBJECTS = modules.o main.o sub1.o sub2.o |
| - | close GP; | + | F90 = ifort |
| - | system("gifsicle --delay 50 hoge*gif > anime.gif"); | + | FLAGS = -check all -warn declarations -CB -fpe0 -traceback |
| + | COMMON_MOD = modules.f90 | ||
| + | |||
| + | .SUFFIXES : | ||
| + | .SUFFIXES : .o .f90 | ||
| + | .f90.o: | ||
| + | ${F90} -c $< ${FFLAGS} | ||
| + | |||
| + | ${TARGET} : ${OBJECTS} | ||
| + | ${F90} -o $@ ${OBJECTS} | ||
| + | clean : | ||
| + | rm *.o ${TARGET} *.mod | ||
| + | |||
| + | |||
| + | ${OBJECTS} : ${COMMON_MOD} | ||
| + | </code> | ||
| + | あとは,makeコマンドを打てばコンパイル完了.そして実行(上の例では./a.outを打てば良い). | ||
| + | <code> | ||
| + | $ make | ||
| + | $./a.out | ||
| + | </code> | ||
| + | また,以下の様にmake cleanで実行ファイル(a.out)及びオブジェクトファイル(*.o)を消去できる. | ||
| + | <code> | ||
| + | $ make clean | ||
| + | </code> | ||
| + | 以下,makefileの変数について簡単に説明する. | ||
| + | <code> | ||
| + | TARGET = 実行ファイル名 | ||
| + | OBJECTS = モジュールファイル プログラムファイル (すべて拡張子は.oとする.) | ||
| + | F90 = コンパイラコマンド (gfortranを使うなら「gfortran」) | ||
| + | FLAGS = コンパイラオプション | ||
| + | COMMON_MOD = モジュールファイル (拡張子は.f90) | ||
| </code> | </code> | ||
| - | gifsicle はgifアニメを作成するツール.アニメを見るにはgifview. | + | ===== データファイルの読み込み ===== |
| + | |||
| + | データファイルの中に何行あるか分からないときにはiostatかendを使う. | ||
| + | iostatの方がスマートなやり方かも. | ||
| + | |||
| + | ==== やり方その1 ==== | ||
| + | read文にiostatのオプションを付ける. | ||
| + | iostatが正の数を返す場合はエラー,負の値を返す場合は行の終わりを意味するらしい. | ||
| + | <code fortran> | ||
| + | program hoge | ||
| + | implicit none | ||
| + | real a,b | ||
| + | integer i,inputstatus | ||
| + | do i=1,10 | ||
| + | read(*,*,iostat=inputstatus) a,b | ||
| + | if(inputstatus>0) stop "error" | ||
| + | if(inputstatus<0) exit | ||
| + | write(*,*) a,b,a**2-b | ||
| + | end do | ||
| + | end program hoge | ||
| + | </code> | ||
| + | ==== やり方その2 ==== | ||
| + | |||
| + | endを使う. | ||
| + | |||
| + | 以下サンプル.プログラムの中では10回ループを回すが,読み込むのは5行分だけ. | ||
| <code bash> | <code bash> | ||
| - | gifview -a anim.gif | + | gfortran hoge.f90 |
| + | ./a.out < hoge.dat | ||
| </code> | </code> | ||
| + | hoge.f90 | ||
| + | <code fortran> | ||
| + | program hoge | ||
| + | do i=1,10 | ||
| + | read(*,*,end=999) a,b | ||
| + | write(*,*) a**2-b | ||
| + | end do | ||
| + | 999 continue | ||
| + | end program hoge | ||
| + | </code> | ||
| - | ===== ifortで改行を抑制する ===== | + | hoge.dat |
| + | <code> | ||
| + | 1. 1. | ||
| + | 2. 4. | ||
| + | 3. 9. | ||
| + | 4. 16. | ||
| + | 5. 25. | ||
| + | </code> | ||
| - | ifortでは出力時に勝手に改行する仕様になっている。改行を抑制するためには、Format文を使用すればよい。 | + | ===== NaNの検出 ===== |
| + | |||
| + | |||
| + | 浮動小数点演算例外を検出するコンパイラオプションがあるので、それを使用する。 | ||
| + | |||
| + | ===== Makefile ===== | ||
| + | 保存するためのmakefile | ||
| + | <code bash> | ||
| + | DATE= `date +%y%m%d%H%M` | ||
| + | TAR = backup/backup${DATE}.tgz | ||
| + | backup : | ||
| + | tar czvf ${TAR} Makefile *.f90 | ||
| + | </code> | ||
| + | |||
| + | |||
| + | ===== implicit none ===== | ||
| + | 宣言文で宣言した変数以外を利用しないようにする。 | ||
| + | 長いプログラムを書く場合はミスを避けるためにも使用するべき。 | ||
| + | 自由形式の場合はuse文の後に使用。 | ||
| <code fortran> | <code fortran> | ||
| - | integer n | + | program hoge |
| - | real(8),allocatable::a(:) | + | use hoge_lib |
| - | n=9 | + | implicit none |
| - | allocate(a(9)) | + | real(8) a,b,c, |
| - | do i=1,n | + | ... |
| - | a(i)=i | + | </code> |
| + | ===== 装置番号 ===== | ||
| + | write(?,*)やread(?,*)の?に入る番号。 | ||
| + | 通常、5が標準入力(キーボード)、6が標準出力(ディスプレイ上の端末)に使用されるので、 | ||
| + | 5と6を使ってopenするのは避けるべき。 | ||
| + | slatecのI1MACHを使えば、標準入力、標準出力の番号が調べられる。 | ||
| + | 装置番号にはcharacterも入る。 | ||
| + | |||
| + | |||
| + | |||
| + | ===== 連番のファイル名をつける。 ===== | ||
| + | ファイル名をcharacter変数に代入して使う。ファイル名の変更にはwrite文を使う。 | ||
| + | 逐次計算に使える。 | ||
| + | <code fortran> | ||
| + | character(len=12) filename | ||
| + | ... | ||
| + | do i=1,100 | ||
| + | write(filename,'(a,i4.4,a)') 'hoge',i,'.dat' | ||
| + | open(10,file=filename) | ||
| + | ... | ||
| + | write(10,*) ... | ||
| + | ... | ||
| + | close(10) | ||
| end do | end do | ||
| - | write(*,'(<n>f)') a | ||
| - | end program | ||
| </code> | </code> | ||
| + | |||
| + | |||
| + | |||
| + | ===== 簡単なシェルスクリプト ===== | ||
| + | 連続してプログラムを実行したいとき、shファイルが便利。 | ||
| + | 端末で入力する内容をあらかじめファイルに書いておき、それを実行すれば、上から順に実行してくれる。 | ||
| + | windowsで言うバッチファイル。 | ||
| + | |||
| + | <code bash> | ||
| + | gfortran hoge.f90 | ||
| + | cd case10 | ||
| + | ../a.out | ||
| + | cd ../case20 | ||
| + | ../a.out | ||
| + | cd ../case30 | ||
| + | ../a.out | ||
| + | </code> | ||
| + | <code> | ||
| + | $ sh hoge.sh | ||
| + | </code> | ||
| + | |||
| + | |||
| + | |||