| Class | file_operate |
| In: |
file_operate.f90
|
CReSS の計算結果出力ファイルデータの操作用モジュール
| Subroutine : | |||
| file_name : | character(*), intent(in)
| ||
| d2n : | integer, intent(in)
| ||
| d3n : | integer, intent(in)
| ||
| d2val : | character(*), intent(in)
| ||
| d3val : | character(*), intent(in)
| ||
| ad2val : | character(*), intent(in)
| ||
| ad3val : | character(*), intent(in)
| ||
| nx : | integer, intent(in)
| ||
| ny : | integer, intent(in)
| ||
| nz : | integer, intent(in)
| ||
| d2var : | real, dimension(nx,ny,d2n), intent(inout)
| ||
| d3var : | real, dimension(nx,ny,nz,d3n), intent(inout)
|
読み込む変数の個数を指定することで, 不要な変数データはメモリに読み込まない ルーチン. (For CReSS) このルーチンを呼び出す前に必ず, val_counter で用意する変数の総数を求めておく.
subroutine auto_read_file( file_name, d2n, d3n, d2val, d3val, ad2val, ad3val, nx, ny, nz, d2var, d3var )
! 読み込む変数の個数を指定することで, 不要な変数データはメモリに読み込まない
! ルーチン. (For CReSS)
! このルーチンを呼び出す前に必ず, val_counter で用意する変数の総数を求めておく.
implicit none
character(*), intent(in) :: file_name ! 読み出すファイル名
integer, intent(in) :: d2n ! d2 変数用に用意すべき配列総数 (変数の種類数)
integer, intent(in) :: d3n ! d3 変数用に用意すべき配列総数 (変数の種類数)
character(*), intent(in) :: d2val ! CReSS のダンプファイルの最初の d2 データ
character(*), intent(in) :: d3val ! CReSS のダンプファイルの最初の d3 データ
character(*), intent(in) :: ad2val ! CReSS のダンプファイルの後の d2 データ
character(*), intent(in) :: ad3val ! CReSS のダンプファイルの後の d3 データ
integer, intent(in) :: nx ! x 方向の要素数
integer, intent(in) :: ny ! y 方向の要素数
integer, intent(in) :: nz ! z 方向の要素数
real, dimension(nx,ny,d2n), intent(inout) :: d2var ! d2 変数用配列
real, dimension(nx,ny,nz,d3n), intent(inout) :: d3var ! d3 変数用配列
integer :: d2m, d3m, d2am, d3am, i, j, k, all_count, d2_count, d3_count
d2m=len_trim(d2val)
d3m=len_trim(d3val)
d2am=len_trim(ad2val)
d3am=len_trim(ad3val)
write(*,*) "len=", d2m, d3m, d2am, d3am
all_count=0
!-- ファイルの 1 レコード目から順に読むかどうかの判断を行って読む ---
!-- まず, 最初の d2 データについて
j=0
if(d2m>=1)then
do i=1,d2m
if(d2val(i:i)=='1')then
j=j+1
if(d2n<j)then
write(*,*) "*** ERROR ***"
write(*,*) "read array exceeds d2n. STOP."
stop
else
call read_file( file_name, nx, ny, i, d2var(:,:,j))
end if
end if
end do
end if
d2_count=j ! 最初の d2 データでいくら入ったか (読み飛ばしを入れない)
all_count=all_count+d2m ! 読み飛ばした分も含めて何レコード分読んだかのカウント
!-- 次, 最初の d3 データについて
j=0
if(d3m>=1)then
do i=1,d3m
if(d3val(i:i)=='1')then
j=j+1
if(d3n<j)then
write(*,*) "*** ERROR ***"
write(*,*) "read array exceeds d3n. STOP."
stop
else
do k=1,nz
call read_file( file_name, nx, ny, all_count+k, d3var(:,:,k,j))
end do
end if
end if
all_count=all_count+nz ! if 文で読んでいなくても nz 行分カウント
end do
end if
d3_count=j ! 最初の d3 データでいくら入ったか (読み飛ばしを入れない)
!-- 続いて, 後の d2 データについて
j=d2_count
if(d2am>=1)then
do i=1,d2am
if(ad2val(i:i)=='1')then
j=j+1
if(d2n<j)then
write(*,*) "*** ERROR ***"
write(*,*) "read array exceeds d2n. STOP."
stop
else
call read_file( file_name, nx, ny, all_count+i, d2var(:,:,j))
end if
end if
end do
end if
all_count=all_count+d2am ! 読み飛ばした分も含めて何レコード分読んだかのカウント
!-- 最後に, 後の d3 データについて
j=d3_count
if(d3am>=1)then
do i=1,d3am
if(ad3val(i:i)=='1')then
j=j+1
if(d3n<j)then
write(*,*) "*** ERROR ***"
write(*,*) "read array exceeds d3n. STOP."
stop
else
do k=1,nz
call read_file( file_name, nx, ny, all_count+k, d3var(:,:,k,j))
end do
end if
end if
all_count=all_count+nz ! if 文で読んでいなくても nz 行分カウント
end do
end if
end subroutine
| Function : | |||
| line_number_counter : | integer | ||
| fname : | character(*), intent(in)
|
テキストデータの行数を計算する関数
integer function line_number_counter( fname )
! テキストデータの行数を計算する関数
implicit none
character(*), intent(in) :: fname ! 読み取るテキストファイル
! integer, intent(inout) :: res
integer :: i, err
character(1) :: dummy
i=0
open(unit=10,file=trim(fname),iostat=err,status='old')
do while(err==0)
read(10,*,iostat=err) dummy
i=i+1
end do
close(unit=10,status='keep')
line_number_counter=i-1
return
end function
| Subroutine : | |||
| file_name : | character(*), intent(in)
| ||
| nx : | integer, intent(in)
| ||
| ny : | integer, intent(in)
| ||
| rec_num : | integer, intent(in)
| ||
| var(nx,ny) : | real, intent(inout)
|
出力結果読み取りルーチン 本ルーチンでは, ダイレクトアクセスを読み出す際, 1 変数のバイト数を 4 バイト と仮定して読み出すので, 4 バイト以外のファイルを読み出すときは, やはりソースファイルの書き換えが必要となる(要修正)
subroutine read_file( file_name, nx, ny, rec_num, var ) ! 出力結果読み取りルーチン
! 本ルーチンでは, ダイレクトアクセスを読み出す際, 1 変数のバイト数を 4 バイト
! と仮定して読み出すので, 4 バイト以外のファイルを読み出すときは,
! やはりソースファイルの書き換えが必要となる(要修正)
implicit none
integer, intent(in) :: nx ! データの x 方向の個数
integer, intent(in) :: ny ! データの y 方向の個数
integer, intent(in) :: rec_num ! 読み出すデータのレコード番号
character(*), intent(in) :: file_name ! 読み出すデータファイル名
real, intent(inout) :: var(nx,ny) ! 読み出すデータ
integer :: i, j, er, k ! 作業用配列
open(unit=11, file=file_name, access='direct', recl=4*nx*ny, status='old')
read(11,rec=rec_num) ((var(i,j),i=1,nx),j=1,ny)
close(unit=11, status='keep')
end subroutine read_file
| Subroutine : | |||
| fname : | character(*), intent(in)
| ||
| nx : | integer, intent(in)
| ||
| ny : | integer, intent(in)
| ||
| val(nx,ny) : | character(*), intent(inout)
| ||
| skip : | integer, intent(in), optional
| ||
| forma : | character(*), intent(in), optional
|
テキスト形式のデータを読み込むルーチン forma と nx, ny の関係は 4x3 の i3 (空白込み) の行列データの場合, forma = ’(3a3)’ という form で読み込むなら, nx = 3, ny = 4 forma = ’(a)’ という form で読み込むなら, nx = 1, ny = 4 となる.
subroutine read_file_text( fname, nx, ny, val, skip, forma )
! テキスト形式のデータを読み込むルーチン
! forma と nx, ny の関係は 4x3 の i3 (空白込み) の行列データの場合,
! forma = '(3a3)' という form で読み込むなら, nx = 3, ny = 4
! forma = '(a)' という form で読み込むなら, nx = 1, ny = 4 となる.
implicit none
character(*), intent(in) :: fname ! 読み込むテキストファイル
integer, intent(in) :: nx ! 読み込むファイルの列数
integer, intent(in) :: ny ! 読み込むファイルの行数
character(*), intent(inout) :: val(nx,ny) ! 文字列データにも対応するため, 文字列で結果を返す.
integer, intent(in), optional :: skip ! 行頭何行を読み飛ばすか. default は 0.
character(*), intent(in), optional :: forma ! read のフォーマット '(f4.1)' など. デフォルトでは read のデフォルトフォーマット使用.
integer :: i, j
character(1) :: dummy
open(unit=10, file=trim(fname), status='old')
if(present(skip))then
do i=1,skip
read(10,*) dummy
end do
end if
if(present(forma))then
do j=1,ny
read(10,forma) (val(i,j),i=1,nx)
end do
else
do j=1,ny
read(10,*) (val(i,j),i=1,nx)
end do
end if
close(unit=10,status='keep')
end subroutine
| Subroutine : | |||
| file_name : | character(*), intent(in)
| ||
| nx : | integer, intent(in)
| ||
| ny : | integer, intent(in)
| ||
| rec_num : | integer, intent(in)
| ||
| var(nx,ny) : | real, intent(inout)
| ||
| mode : | character(*), optional, intent(in)
|
解析出力ルーチン 本ルーチンでは, ダイレクトアクセスを読み出す際, 1 変数のバイト数を 4 バイト と仮定して読み出すので, 4 バイト以外のファイルを読み出すときは, やはりソースファイルの書き換えが必要となる(要修正)
subroutine write_file( file_name, nx, ny, rec_num, var, mode ) ! 解析出力ルーチン
! 本ルーチンでは, ダイレクトアクセスを読み出す際, 1 変数のバイト数を 4 バイト
! と仮定して読み出すので, 4 バイト以外のファイルを読み出すときは,
! やはりソースファイルの書き換えが必要となる(要修正)
implicit none
integer, intent(in) :: nx ! データの x 方向の個数
integer, intent(in) :: ny ! データの y 方向の個数
integer, intent(in) :: rec_num ! 読み出すデータのレコード番号
character(*), intent(in) :: file_name ! 読み出すデータファイル名
real, intent(inout) :: var(nx,ny) ! 読み出すデータ
character(*), optional, intent(in) :: mode ! ファイルの書き出しオプション
integer :: i, j, er, k ! 作業用配列
character(10) :: cmode
if(present(mode))then
cmode=mode
else
cmode='unknown'
end if
open(unit=11, file=file_name, access='direct', recl=4*nx*ny, status=cmode)
write(11,rec=rec_num) ((var(i,j),i=1,nx),j=1,ny)
close(unit=11, status='keep')
end subroutine write_file