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”はグリッドデータの大きさをチェックし、スケールファクターを算定しています。次回公開予定ですが、それまで宿題にしておきます。
つづく
