Skip to content

Commit

Permalink
improve POD // allow custom separators when reading from ascii file /…
Browse files Browse the repository at this point in the history
…/ add force computation from HDF5 files
  • Loading branch information
tommy-engels committed Jan 11, 2019
1 parent 5c910fc commit b3b39b9
Show file tree
Hide file tree
Showing 5 changed files with 524 additions and 279 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ FFILES = rhs.f90 vis.f90 fluid_time_step.f90 init_fields.f90 \
sponge.f90 fft_unit_test.f90 draw_plate.f90 draw_sphere.f90 \
rotation_matrices.f90 add_channel.f90 add_cavity.f90 init_scalar.f90 dry_run.f90 \
noncircular_cylinder.f90 draw_flexible_plate.f90 \
runtime_backuping.f90 io_test.f90 POD.f90
runtime_backuping.f90 io_test.f90 POD.f90 post_force.f90

ifndef NOHDF5
# Case WITH HDF5 (all machines except earth simulator)
Expand Down
220 changes: 136 additions & 84 deletions src/ini_files_parser.f90
Original file line number Diff line number Diff line change
Expand Up @@ -59,110 +59,162 @@ module module_ini_files_parser
! note: array is assumed-shape and its size defines what we try to read
! --> MPI wrapper in the MPI parser module
!-----------------------------------------------------------------------------
subroutine read_array_from_ascii_file(file, array, n_header)
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: n_header
real(kind=pr), intent(inout) :: array (1:,1:)
integer :: nlines, ncols, i, io_error
character(len=maxcolumns) :: dummy
character(len=16) :: fmt
character(len=3) :: ncols_str

! check if the specified file exists
call check_file_exists( file )

nlines = size(array,1)
ncols = size(array,2)

write(*,'(80("-"))')
write(*,'("INFO: reading ",i8," lines with ",i8," colums from ",A)') nlines, ncols, file

! set up format string
write(ncols_str,'(i3.3)') ncols
fmt = '('//ncols_str//'(es12.4,1x))'

io_error = 0
i = 0

open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
! read a line from file
read (14,'(A)',iostat=io_error) dummy
i = i + 1
! if we're past the header AND the read worked (i.e. not end of file)
if (i > n_header .and. io_error==0) then
read(dummy,*) array(i-n_header,:)
subroutine read_array_from_ascii_file(file, array, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: n_header
real(kind=pr), intent(inout) :: array (1:,1:)
character(len=1), optional, intent(in) :: user_separator
integer :: nlines, ncols, i, io_error, k
character(len=maxcolumns) :: dummy
character(len=16) :: fmt
character(len=3) :: ncols_str
character(len=1) :: sep

! check if the specified file exists
call check_file_exists( file )

nlines = size(array,1)
ncols = size(array,2)

if (present(user_separator)) then
sep = user_separator
else
sep = " "
endif
enddo
close (14)

write(*,'("Done reading.")')
write(*,'(80("-"))')
write(*,'(80("-"))')
write(*,'("INFO: reading ",i8," lines with ",i8," colums from ",A)') nlines, ncols, file
write(*,'("INFO: separator is -->",A1,"<--")') sep

! set up format string
write(ncols_str,'(i3.3)') ncols
fmt = '('//ncols_str//'(es12.4,1x))'

io_error = 0
i = 0

open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
! read a line from file
read (14,'(A)',iostat=io_error) dummy
i = i + 1

! if we're past the header AND the read worked (i.e. not end of file)
if (i > n_header .and. io_error==0) then

k = count_seperators_in_line(dummy, sep)
if (k == ncols) then
dummy = adjustl(dummy)
read(dummy,*) array(i-n_header,:)
else
write(*,*) "ERROR in file ",trim(adjustl(file))," line ", i, "has wrong number of columns, skip"
! this module is not MPI aware so abort is not available
stop
endif
endif
enddo
close (14)

write(*,'("Done reading.")')
write(*,'(80("-"))')
end subroutine read_array_from_ascii_file


!-----------------------------------------------------------------------------
! count the number of lines in an ascii file, skip n_header lines
! --> MPI wrapper in the MPI parser module
!-----------------------------------------------------------------------------
subroutine count_lines_in_ascii_file(file, num_lines, n_header)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_lines
integer, intent(in) :: n_header
integer :: io_error, i
character(len=maxcolumns) :: dummy

! check if the specified file exists
call check_file_exists( file )
subroutine count_lines_in_ascii_file(file, num_lines, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_lines
integer, intent(in) :: n_header
character(len=1), optional, intent(in) :: user_separator
integer :: io_error, i
character(len=maxcolumns) :: dummy
character(len=1) :: sep

! check if the specified file exists
call check_file_exists( file )

if (present(user_separator)) then
sep = user_separator
else
sep = " "
endif

! count the lines
io_error = 0
i = 0
open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
read (14,'(A)',iostat=io_error) dummy
if (io_error==0) i = i+1
enddo
close (14)
num_lines = i - n_header
! count the lines
io_error = 0
i = 0
open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
read (14,'(A)',iostat=io_error) dummy
if (io_error==0) i = i+1
enddo
close (14)
num_lines = i - n_header
end subroutine count_lines_in_ascii_file


subroutine count_cols_in_ascii_file(file, num_cols, n_header)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_cols
integer, intent(in) :: n_header
integer :: io_error, i
character(len=maxcolumns) :: dummy
subroutine count_cols_in_ascii_file(file, num_cols, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_cols
integer, intent(in) :: n_header
character(len=1), optional, intent(in) :: user_separator
integer :: io_error, i
character(len=maxcolumns) :: dummy
character(len=1) :: sep

! check if the specified file exists
call check_file_exists( file )
! check if the specified file exists
call check_file_exists( file )

! count the lines
io_error = 0
i = 0
if (present(user_separator)) then
sep = user_separator
else
sep = " "
endif

open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
read (14,'(A)',iostat=io_error) dummy
if (io_error==0 .and. i>n_header) exit
i=i+1
enddo
close (14)
! count the lines
io_error = 0
i = 1

num_cols = 1
do i = 1, len_trim(adjustl(dummy))
! count elements in the line by counting the separating spaces
if ( dummy(i:i) == " " ) then
num_cols = num_cols + 1
end if
enddo
! just read first line....after the header
open(unit=14,file=trim(adjustl(file)),action='read',status='old')
do while (io_error==0)
read (14,'(A)',iostat=io_error) dummy
if (io_error==0 .and. i>n_header) exit
i = i+1
enddo
close (14)

num_cols = count_seperators_in_line(dummy, sep)
end subroutine count_cols_in_ascii_file



integer function count_seperators_in_line( line, sep )
implicit none
CHARACTER(len=*), intent(in) :: line, sep
character(len=maxcolumns) :: dummy
integer :: num_cols, i

num_cols = 1
! remove leading spaces
dummy = adjustl(line)

do i = 1, len_trim(dummy)
! count elements in the dummy by counting the separators
if ( dummy(i:i) == sep(1:1) ) then
num_cols = num_cols + 1
end if
enddo

count_seperators_in_line = num_cols
end function


!-------------------------------------------------------------------------------
! clean a previously read ini file, deallocate its string array, and reset
! verbosity to .true. (as a matter of precaution)
Expand Down
31 changes: 25 additions & 6 deletions src/ini_files_parser_mpi.f90
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ module module_ini_files_parser_mpi
! read an array from an ascii file (SERIAL version, to be executed only on root)
! note: array is assumed-shape and its size defines what we try to read
!-----------------------------------------------------------------------------
subroutine read_array_from_ascii_file_mpi(file, array, n_header)
subroutine read_array_from_ascii_file_mpi(file, array, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(in) :: n_header
real(kind=pr), intent(inout) :: array (1:,1:)
character(len=1), optional, intent(in) :: user_separator
integer :: nlines, ncols, mpicode, mpirank

! fetch my process id
Expand All @@ -41,7 +42,12 @@ subroutine read_array_from_ascii_file_mpi(file, array, n_header)
ncols = size(array,2)

! only root reads from file...
if (mpirank==0) call read_array_from_ascii_file(file, array, n_header)
if (present(user_separator)) then
if (mpirank==0) call read_array_from_ascii_file(file, array, n_header, user_separator)
else
if (mpirank==0) call read_array_from_ascii_file(file, array, n_header)
endif

! ... then broadcast
call MPI_BCAST(array,nlines*ncols,MPI_DOUBLE_PRECISION,0,MPI_COMM_WORLD,mpicode)
end subroutine read_array_from_ascii_file_mpi
Expand All @@ -50,35 +56,48 @@ end subroutine read_array_from_ascii_file_mpi
!-----------------------------------------------------------------------------
! count the number of lines in an ascii file, skip n_header lines
!-----------------------------------------------------------------------------
subroutine count_lines_in_ascii_file_mpi(file, num_lines, n_header)
subroutine count_lines_in_ascii_file_mpi(file, num_lines, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_lines
integer, intent(in) :: n_header
character(len=1), optional, intent(in) :: user_separator
integer :: mpicode, mpirank

! fetch my process id
call MPI_Comm_rank(MPI_COMM_WORLD, mpirank, mpicode)

! only root reads from file...
if (mpirank==0) call count_lines_in_ascii_file(file, num_lines, n_header)
if (present(user_separator)) then
if (mpirank==0) call count_lines_in_ascii_file(file, num_lines, n_header, user_separator)
else
if (mpirank==0) call count_lines_in_ascii_file(file, num_lines, n_header)
endif

! ... then broadcast
call MPI_BCAST(num_lines,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpicode)
end subroutine count_lines_in_ascii_file_mpi


subroutine count_cols_in_ascii_file_mpi(file, num_cols, n_header)
subroutine count_cols_in_ascii_file_mpi(file, num_cols, n_header, user_separator)
implicit none
character(len=*), intent(in) :: file
integer, intent(out) :: num_cols
integer, intent(in) :: n_header
character(len=1), optional, intent(in) :: user_separator
integer :: mpicode, mpirank

! fetch my process id
call MPI_Comm_rank(MPI_COMM_WORLD, mpirank, mpicode)

! only root reads from file...
if (mpirank==0) call count_cols_in_ascii_file(file, num_cols, n_header)
if (present(user_separator)) then
if (mpirank==0) call count_cols_in_ascii_file(file, num_cols, n_header, user_separator)
else
if (mpirank==0) call count_cols_in_ascii_file(file, num_cols, n_header)
endif


! ... then broadcast
call MPI_BCAST(num_cols,1,MPI_INTEGER,0,MPI_COMM_WORLD,mpicode)
end subroutine count_cols_in_ascii_file_mpi
Expand Down
Loading

2 comments on commit b3b39b9

@Truong-Hung
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to me that you forgot to submit the post_force.f90 file?

@tommy-engels
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry! added the file now.
thanks for noticing!

Please sign in to comment.