PP#14~Fortran Tips#9
ちょっと間が空きましたが、グリッドデータの出力表示の続きです。今回は実数(倍精度)データを扱います。
入力データの大きさに合わせて、任意にF、E、及びG書式を選択できるようにしています。
出力のイメージはこんな感じで、
”PrintDblArray”がグリッドデータを綺麗に出力するメインのサブルーチンです。Straightforwardなのでコードを追っていただければ自ずと分かって頂けるでしょう。
subroutine PrintDblArray(Output, DblValue, Space, Expo, NX, NY, NZ, NMAX) !********************************************************************************* !* * !* Produce the Neat Formatted Output for an Double Array * !* * !********************************************************************************* implicit none integer,intent(in):: Output, Space, Expo, NX, NY, NZ, NMAX real(8),intent(in):: DblValue( NMAX ) integer,parameter:: NxPrintDefault = 15 integer:: decimal, NXY, x, y, z, yz, & x1m, x2m, ipr, npr, ig, ib real(8):: factor, gmax, value, dummy character(6):: outbuf, scale character(12):: field logical:: qbreak !================================================================================= ! Output : Output stream ! DblValue: Array to be printed (stored in natural order) ! Space : Field indicator (0=8 characters, 1=6 characters) ! Expo : Format type: 0=F, 1=E, 2=G !================================================================================= npr = NX / NxPrintDefault + 1 !NxPrintDefault grids for X axis NXY = NX * NY !--------------------------------------------------------------------------------- ! Figure out scaling factor !--------------------------------------------------------------------------------- scale = " " if (Expo == 0) then !Find out maximum value to be printed gmax = 0.0 do z=1,NZ do y=1,NY yz = (z-1) * NXY + (y-1) * NX do x=1,NX ig = yz + x dummy = abs(DblValue(ig)) if (dummy < 1.0e+15) gmax = max(gmax,dummy) enddo enddo enddo !Set up scaling factor call ScaleFactor(gmax, factor, scale, decimal, Space, Expo) endif !--------------------------------------------------------------------------------- ! Write heading on new page !--------------------------------------------------------------------------------- write(Output, '(/" **********************************************************************")') write(Output, '( " * Print out Double Array *")') write(Output, '(1x,a6,1x\"**********************************************************************")') scale !--------------------------------------------------------------------------------- do ipr=0,npr-1 x1m = NxPrintDefault * ipr + 1 x2m = min( NX, x1m + NxPrintDefault - 1) do z=1,NZ qbreak = (z == 1) .or. (NY > 10) if (qbreak) then write(Output, '(/"(i, j, k) = ",i3,\)') x1m do x=x1m+1,x2m write(Output, '(i8,\)') x enddo write(Output, '()') !Break at line (i,j,k) endif if (qbreak .or. NY > 1) write(Output, '()') !Except for radidal coordinate do y=1,NY yz = (z-1) * NXY + (y-1) * NX write(Output, '("(*,",i3,",",i3,") ",\)') y,z do x=x1m,x2m ig = yz + x value = DblValue(ig) if (abs(value) >= 1.0e+15) then write(Output, '(" ----- ",\)') else if (Expo == 0) then !F format ! 12345678901 field = '(0p,f8.--,\)' write(outbuf, '(i2)' ) decimal field(8:9) = outbuf write(Output,field) value * factor else if (Expo == 1) then !E Format ! 12345678901 field = '(1p,e8.01,\)' write(Output,field) value else if (Expo == 2) then !G format call ScaleFactor(value, factor, field, decimal, 8, Expo) write(Output,field) value endif endif enddo write(Output, '()') enddo enddo enddo !================================================================================= end subroutine
呼び出しプログラムは整数の出力時に用いた”call_PrintArray”を少し変形させたものです。
program call_PrintArray !******************************************************************************** !* call_printArray * !******************************************************************************** implicit none integer,parameter:: output = 6 integer,parameter:: NMAX = 100 integer:: NX, NY, NZ, NXY, x, y, z, ig integer:: Space = 8 integer:: Expo = 0 integer:: IntValue(NMAX) real(8):: DblValue(NMAX) character(1):: key !================================================================================ ! Space: Field indicator (0=8 characters, 1=6 characters) ! Expo : 1=Exponential format, 2=G format !================================================================================ do print '(/" Input NX, NY, NZ = ",$)' ; read (*,*) NX, NY, NZ if (NX*NY*NZ > NMAX) then print '(" NX*NY*NZ is greater than NMAX. Input again!")' else exit endif enddo 100 continue NXY = NX * NY do z=1,NZ do y=1,NY do x=1,NX ig = NXY * (z-1) + NX * (y-1) + x ! write(*, '(" Input integer value at (",i4,",",i4,",",i4,") = "\)') x,y,z ; read(*,*) IntValue(ig) write(*, '(" Input double value at (",i4,",",i4,",",i4,") = "\)') x,y,z ; read(*,*) DblValue(ig) enddo enddo enddo print '(/" Input Format type (F=0, E=1, G=2) ",$)' ; read (*,*) Expo ! call printIntArray(Output, IntValue, NX, NY, NZ, NMAX) call printDblArray(Output, DblValue, Space, Expo, NX, NY, NZ, NMAX) print '()' print '(/" Re-input value? (y/n) = ",$)' ; read (*,*) key if (key == "y" .or. key == "Y") then goto 100 else print '("Reached end of program")' endif !================================================================================ stop end program
”PrintDblArray”で呼び出しているサブルーチン”ScaleFactor”はグリッドデータの大きさをチェックし、スケールファクターを算定しています。次回公開予定ですが、それまで宿題にしておきます。
つづく