PP#14~Fortran Tips#9

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

つづく

Comments are closed.