Fortran サブルーチン

プログラム
Pocket

プログラミングに慣れてくると、サブルーチンをやろう!、サブルーチンしなさい!等、思ったり、言われたりすると思います。

サブルーチン…よく分からない

最初に私が思ったことです。

しかし、今は何とかサブルーチンを使ってプログラムしてます。
(完全に理解してるかどうかは分からない…)

今回はサブルーチンについて書きたいと思います。

サブルーチンは必要?

まず、サブルーチンは覚えなければならない知識なのか?と言われると、別に使わなくてもプログラミングできます。

しかし、使った方が楽になる所があります。(デバック作業とか

サブルーチンについて

まずサブルーチン構文は

CALL 名前   ()

SUBROUTINE  名前()

です。

言葉だけだと説明しずらいので私が作った下記のプログラムコードと連動させて説明します。

下記のプログラムは非定常一次元熱伝導方程式(発熱なし)のコードになります。
まずこのプログラムのmain(メインロード)は
Main Program start ~ Main Program endです。

プログラムは上から順番に読み込んでいきます。

そしてメインロードの CALL MEM_T   (I0,I1,J0,J1,T,T0)に到達すると、Main Program end の下書いてある
SUBROUTINE MEM_T (I0,I1,J0,J1,T,T0)にワープし、RETURN ENDまで計算し、またメインロードにワープして、下に向かって読み込みます。

これがサブルーチンになります。

RPGのダンジョンで例えると、ボス(Main Program end)まで一本道で作られていて、道の途中にワープゾーンとそれに対応するギミック部屋があるみたいな感じですかね。(赤文字がサブルーチンの所)分かりずらいかも(笑)

サブルーチンも色々な書き方がありますが、私の場合、使う文字はすべて— Global Variable —–に書いて、サブルーチンで使う文字をCALL MEM_T   (I0,I1,J0,J1,T,T0)のように()に書いて使ってます。

サブルーチンを使う意味としては色々ありますが

デバック作業が楽になる!という点が大きいと思います。

例えば、プログラムコードが3万行あったとします。
そして3万行のコードの内、一行だけプログラミングミスをしました。
3万行を一行ずつ確認していくのはどうでしょう?
私はやりたくありません(笑)

そこでサブルーチンを使って30個部屋を作って1000行ずつコードを分けます。
そしてCALL 名前のすぐ下に STOP END PROGRAMを書きます。
プログラミングミスがなければその部屋は問題なしエラー出たら、その部屋のどこかにプログラムミスがあります。
どうでしょうか?

3万行の確認が1000行になりました

このような風ににサブルーチンは使われます。

まとめ

サブルーチンについて説明しましたが、別に使わなくてもプログラムはできます。
しかし、プログラムコードが多ければ多いほどサブルーチンの有用性が分かると思います。

関連記事

1からプログラミングを覚えるなら独学じゃない方がいい理由

FORTRAN基本から中級レベルまでの記事を紹介 まとめ

6記事でGoogle AdSense合格しました、その時のブログの状態

プログラムコード

PROGRAM MAIN
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 X_T(ISSS:IEEE)        !— Position X
REAL*4 T(ISSS:IEEE)           !— Thermal
REAL*4 T0 (ISSS:IEEE)    !— Temperature for Meomory
REAL*4 DENS                   !—Solid Density
REAL*4 S_H                    !— Specific heat
REAL*4 T_C                    !—  Thermal Conductivity
REAL*4 TIM(ISSS:IEEE)         !—  TIME
REAL*4 A                      !— Thermal Diffusivity
REAL*4 DEL_TIM                !— TIME STEP

C———————————————————————-

C
INTEGER I0, I1, J0, J1 ,N0 ,N1   !— Mesh Size
INTEGER S0, S1                   !— Mesh Size

C
REAL*4 RES_P                     !— Residual P
REAL*4 RES_PP                    !— Residual PP
REAL*4 RES_PPP                   !— Residual PPP
REAL*4 RES_T                     !— Residual T
REAL*4 RES_E                     !— Residual E
C
REAL*4 DELY_T                     !— deltaY T
C
INTEGER NMAX_P, NMAX_T, NMAX_Y  ,ALL ,NMAX_E

C————————————————- Local Variable —–
REAL*4  DX , DY
INTEGER I,J,S ,BB
INTEGER N
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
110 FORMAT(A)
WRITE(*,110) ‘**************************************************’
WRITE(*,110) ‘************                          ************’
WRITE(*,110) ‘************     Main Program         ************’
WRITE(*,110) ‘************     Start !!!     ************’
WRITE(*,110) ‘************                          ************’
WRITE(*,110) ‘**************************************************’
WRITE(*,110) ‘ ‘
C
111 FORMAT(A,E16.8E3,A)
116 FORMAT(A,I5,10X,I4)
C
WRITE(*,110) ‘———– Reading Parameter of Mesh ————‘
OPEN  (11,FILE=’./para_mesh.txt’,STATUS=’unknown’)
READ(11,*) I0
READ(11,*) I1
READ(11,*) J0
READ(11,*) J1
READ(11,*) S0
READ(11,*) S1
CLOSE (11)
WRITE(*,110) ‘———————————— has done. —‘
WRITE(*,110) ‘ ‘
WRITE(*,110) ‘>>> Grid Parameter — start ——- end ———-‘
WRITE(*,116) ‘    I-Direction :   ‘,I0,I1
WRITE(*,116) ‘    J-Direction :   ‘,J0,J1
WRITE(*,110) ‘                                                 ‘

WRITE(*,110) ‘———– Reading Parameter of Mesh ————‘
OPEN  (11,FILE=’./para_thermal.txt’,STATUS=’unknown’)
READ(11,*) DENS
READ(11,*) S_H
READ(11,*) T_C
READ(11,*) DEL_TIM
CLOSE (11)
WRITE(*,110) ‘———————————— has done. —‘
WRITE(*,110) ‘>>> Physical Parameter —————————‘
WRITE(*,111) ‘ Fluid Density      =’,DENS        ,’ [kg/m3  ] ‘
WRITE(*,111) ‘ specific heat      =’,S_H         ,’ [kj/kg K] ‘
WRITE(*,111) ‘ Thermal Conductivity =’,T_C       ,’ [W/m k] ‘
WRITE(*,111) ‘ specific heat      =’,DEL_TIM     ,’ [s] ‘
WRITE(*,110) ‘                                                 ‘
c      GOTO 999

NMAX_T = 7200
C—————————–Position X——————————-
DO I = I0, I1
X_T(I) = 0.2 / 200 * REAL(I)
END DO

C—————————–initial——————————-
DO I = I0+1, I1-1
T(I) = 0
END DO
C
T(I0) = 1000
T(I1) = 0
A = T_C / (DENS * S_H)

WRITE(*,*) ‘A=’,A
C—– Computation of Thermal Eq. ————————————
DO BB = 1 , NMAX_T
CALL MEM_T   (I0,I1,J0,J1,T,T0)
C
CAll CAL_T   (I0,I1,J0,J1,T,T0,X_T,A,DEL_TIM)
C
CAll BOU_T   (I0,I1,J0,J1,T)
C
CAll CAL_R_T (I0,I1,J0,J1,T,T0,RES_T)

IF(BB == 1200)THEN
CALL OUTPUT_T1 (I0,I1,J0,J1,X_T,T)
END IF

IF(BB == 2400)THEN
CALL OUTPUT_T2 (I0,I1,J0,J1,X_T,T)
END IF

IF(BB == 3600)THEN
CALL OUTPUT_T3 (I0,I1,J0,J1,X_T,T)
END IF

IF(BB == 4800)THEN
CALL OUTPUT_T4 (I0,I1,J0,J1,X_T,T)
END IF

IF(BB == 6000)THEN
CALL OUTPUT_T5 (I0,I1,J0,J1,X_T,T)
END IF

IF(BB == 7200)THEN
CALL OUTPUT_T6 (I0,I1,J0,J1,X_T,T)
END IF
END DO

WRITE(*,110) ‘**************************************************’
WRITE(*,110) ‘************                          ************’
WRITE(*,110) ‘************      Main Program        ************’
WRITE(*,110) ‘************       End !!!      ************’
WRITE(*,110) ‘************                          ************’
WRITE(*,110) ‘**************************************************’
WRITE(*,110) ‘ ‘
C
999 STOP
END PROGRAM
C *********************************************************************
SUBROUTINE MEM_T (I0,I1,J0,J1,T,T0)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 T0 (ISSS:IEEE)            !— Temperature for Meomory
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
DO I=I0,I1
T0(I) = T(I)
END DO
C
999 RETURN
END
C
C
C
C *********************************************************************
SUBROUTINE CAL_T (I0,I1,J0,J1,T,T0,X_T,A,DEL_TIM)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 T0 (ISSS:IEEE)            !— Temperature for Meomory
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
REAL*4 A                         !— Thermal Diffusivity
REAL*4 DEL_TIM                   !— TIME STEP
INTEGER I0, I1, J0, J1           !— Mesh Size

C————————————————- Local Variable —–
INTEGER I,J,S
REAL*4 DX, DY
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
DX = X_T(1) – X_T(0)
C
DO I = I0+1, I1-1
S=I
T(S) = A * DEL_TIM * (T0(I+1) -2*T0(I) +T0(I-1)) / DX**2
&       + T0(I)
END DO

999 RETURN
END
C
C
C
C *********************************************************************
SUBROUTINE BOU_T(I0,I1,J0,J1,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

C
T(I0) = 1000
T(I1) = 0

999 RETURN
END
C
C
C
C *********************************************************************
SUBROUTINE CAL_R_T (I0,I1,J0,J1,T,T0,RES_T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)  !— Temperature
REAL*4 T0 (ISSS:IEEE)  !— Temperature for Meomory
INTEGER I0, I1, J0, J1           !— Mesh Size
REAL*4 RES_T                     !— Residual T
C————————————————- Local Variable —–
INTEGER I , J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
RES_T=-1.0E+10
DO I=I0,I1
RES_T = AMAX1( RES_T , ABS(T(I)-T0(I)) )
END DO
C
999 RETURN
END
C
CC**********************************************************************
SUBROUTINE OUTPUT_T1 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_600.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END
C
C
C
C**********************************************************************
SUBROUTINE OUTPUT_T2 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_1200.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END
C
C
CC**********************************************************************
SUBROUTINE OUTPUT_T3 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_1800.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END
C
C
CC**********************************************************************
SUBROUTINE OUTPUT_T4 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_2400.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END
C
C
CC**********************************************************************
SUBROUTINE OUTPUT_T5 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_3000.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END
C
C
CC**********************************************************************
SUBROUTINE OUTPUT_T6 (I0,I1,J0,J1,X_T,T)
INCLUDE ‘implicit.for’
C———————————————— Global Variable —–
REAL*4 T  (ISSS:IEEE)            !— Temperature
REAL*4 X_T(ISSS:IEEE)            !— Position X-component
INTEGER I0, I1, J0, J1           !— Mesh Size
C————————————————- Local Variable —–
INTEGER I,J
C++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C
112 FORMAT(2(E16.8E3,1X))
113 FORMAT(3(E16.8E3,1X))
114 FORMAT(4(E16.8E3,1X))
C
OPEN (11,FILE=’./data/maeda_3600.dat’,STATUS=’unknown’)
DO I=I0,I1
WRITE(11,112) X_T(I),T(I)
END DO
CLOSE(11)
C
RETURN
END