diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b912c46fe1..ee5f882b7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,14 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include) +#=============================================================================== +# Architecture specific definitions +#=============================================================================== + +if (${UNIX}) + add_definitions(-DUNIX) +endif() + #=============================================================================== # Command line options #=============================================================================== diff --git a/src/plot.F90 b/src/plot.F90 index cedba281c7..9e8348db7f 100644 --- a/src/plot.F90 +++ b/src/plot.F90 @@ -10,6 +10,7 @@ module plot use plot_header use ppmlib, only: Image, init_image, allocate_image, & deallocate_image, set_pixel + use progress_header, only: ProgressBar use string, only: to_str implicit none @@ -109,8 +110,9 @@ contains real(8) :: in_pixel real(8) :: out_pixel real(8) :: xyz(3) - type(Image) :: img - type(Particle) :: p + type(Image) :: img + type(Particle) :: p + type(ProgressBar) :: progress ! Initialize and allocate space for image call init_image(img) @@ -149,6 +151,7 @@ contains p % coord % universe = BASE_UNIVERSE do y = 1, img % height + call progress % set_value(dble(y)/dble(img % height)*100.) do x = 1, img % width ! get pixel color @@ -228,7 +231,8 @@ contains integer :: id ! id of cell or material real(8) :: vox(3) ! x, y, and z voxel widths real(8) :: ll(3) ! lower left starting point for each sweep direction - type(Particle) :: p + type(Particle) :: p + type(ProgressBar) :: progress ! compute voxel widths in each direction vox = pl % width/dble(pl % pixels) @@ -253,6 +257,7 @@ contains ll = ll + vox / 2.0 do x = 1, pl % pixels(1) + call progress % set_value(dble(x)/dble(pl % pixels(1))*100.) do y = 1, pl % pixels(2) do z = 1, pl % pixels(3) diff --git a/src/progress_header.F90 b/src/progress_header.F90 new file mode 100644 index 0000000000..d0ee7563a5 --- /dev/null +++ b/src/progress_header.F90 @@ -0,0 +1,102 @@ +module progress_header + + use, intrinsic :: ISO_FORTRAN_ENV, only: OUTPUT_UNIT + + implicit none + +#ifdef UNIX + interface + function check_isatty(fd) bind(C, name = 'isatty') + use, intrinsic :: ISO_C_BINDING, only: c_int + integer(c_int) :: check_isatty + integer(c_int), value :: fd + end function check_isatty + end interface +#endif + +!=============================================================================== +! PROGRESSBAR +!=============================================================================== + + type ProgressBar + private + character(len=72) :: bar="???% | " // & + " |" + contains + procedure :: set_value => bar_set_value + end type ProgressBar + +contains + +!=============================================================================== +! IS_TERMINAL checks if output is currently being output to a terminal. Relies +! on a POSIX implementation of isatty, and defaults to false if that is not +! available +!=============================================================================== + + function is_terminal() result(istty) + logical :: istty + + istty = .true. + +#ifdef UNIX + if (check_isatty(1) == 0) istty = .false. +#else + istty = .false. +#endif + + end function is_terminal + +!=============================================================================== +! BAR_SET_VALUE prints the progress bar without advancing. The value is +! specified as percent completion, from 0 to 100. If the value is ever set to +! 100 or above, the bar is set to 100 and a newline is written. +!=============================================================================== + + subroutine bar_set_value(self, val) + + class(ProgressBar), intent(inout) :: self + real(8), intent(in) :: val + + integer :: i + + if (.not. is_terminal()) return + + ! set the percentage + if (val >= 100.) then + write(self % bar(1:3), "(I3)") 100 + else if (val <= 0.) then + write(self % bar(1:3), "(I3)") 0 + else + write(self % bar(1:3), "(I3)") int(val) + end if + + ! set the bar width + if (val >= 100.) then + do i=1,65 + write(self % bar(i+6:i+6), '(A)') '=' + end do + else + do i=1,int(dble(65)*val/100.) + write(self % bar(i+6:i+6), '(A)') '=' + end do + end if + + write(OUTPUT_UNIT, '(A1,A1,A72)', ADVANCE='no') '+', char(13), self % bar + flush(OUTPUT_UNIT) + + if (val >= 100.) then + + ! make new line + write(OUTPUT_UNIT, "(A)") "" + flush(OUTPUT_UNIT) + + ! reset the bar in case we want to use this instance again + self % bar = "???% | " // & + " |" + + end if + + end subroutine bar_set_value + +end module progress_header