プログラミングに慣れてくると、サブルーチンをやろう!、サブルーチンしなさい!等、思ったり、言われたりすると思います。
サブルーチン…よく分からない
最初に私が思ったことです。
しかし、今は何とかサブルーチンを使ってプログラムしてます。
(完全に理解してるかどうかは分からない…)
今回はサブルーチンについて書きたいと思います。
サブルーチンは必要?
まず、サブルーチンは覚えなければならない知識なのか?と言われると、別に使わなくてもプログラミングできます。
しかし、使った方が楽になる所があります。(デバック作業とか)
サブルーチンについて
まずサブルーチン構文は
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行になりました。
このような風ににサブルーチンは使われます。
まとめ
サブルーチンについて説明しましたが、別に使わなくてもプログラムはできます。
しかし、プログラムコードが多ければ多いほどサブルーチンの有用性が分かると思います。
関連記事
プログラムコード
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