diff --git a/examples/Basic_Simulation/initial_conditions.ipynb b/examples/Basic_Simulation/initial_conditions.ipynb index 055c16fa3..2014b6e06 100644 --- a/examples/Basic_Simulation/initial_conditions.ipynb +++ b/examples/Basic_Simulation/initial_conditions.ipynb @@ -1512,7 +1512,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "fd30638b-6868-4162-bc05-1011bb255968", "metadata": {}, "outputs": [ @@ -1534,7 +1534,22 @@ "\n", "[====- ] MassiveBody_01 (10) perihelion distance too small at t = 41331.8700000000\n", "\n", - "[==========- ]\r" + "[=====================/ ] Mercury (1) perihelion distance too small at t = 252784.155000000\n", + "\n", + "[==================================- ] MassiveBody_03 (12) perihelion distance too small at t = 417930.725000000\n", + "\n", + "[====================================\\ ] Particle TestParticle_02 (16) too far from the central body at t = 438551.305000000\n", + "\n", + "[================================================================/ ] Particle TestParticle_01 (15) too far from the central body at t = 792096.480000000\n", + "\n", + "[================================================================================]\n", + "\n", + "Normal termination of Swiftest (version 1.0)\n", + "------------------------------------------------\n", + "\n", + "Creating Dataset from NetCDF file\n", + "Successfully converted 1001 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .data\n" ] } ], diff --git a/examples/Basic_Simulation/run_simulation.ipynb b/examples/Basic_Simulation/run_simulation.ipynb index ea78c2690..97b063130 100644 --- a/examples/Basic_Simulation/run_simulation.ipynb +++ b/examples/Basic_Simulation/run_simulation.ipynb @@ -2,10 +2,18 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "86c845ce-1801-46ca-8a8a-1cabb266e6a6", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: OMP_NUM_THREADS=8\n" + ] + } + ], "source": [ "import swiftest\n", "import xarray as xr\n", @@ -16,10 +24,18 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "d716c371-8eb4-4fc1-82af-8b5c444c831e", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file /home/daminton/git_debug/swiftest/examples/Basic_Simulation/simdata/param.in\n" + ] + } + ], "source": [ "sim = swiftest.Simulation()" ] @@ -29,9 +45,33 @@ "execution_count": null, "id": "ec7452d6-4c9b-4df3-acc0-b11c32264b91", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing parameter inputs to file /home/daminton/git_debug/swiftest/examples/Basic_Simulation/simdata/param.in\n", + "Running a Swiftest symba run from tstart=0.0 y to tstop=1000.0 y\n", + "\u001b]2;cd /home/daminton/git_debug/swiftest/examples/Basic_Simulation/simdata\u0007\u001b]1;\u0007\u001b]2;/home/daminton/git_debug/swiftest/bin/swiftest_driver symba \u0007\u001b]1;\u0007 Parameter input file is /home/daminton/git_debug/swiftest/examples/Basic_Simulation/simdata/param.in\n", + "\n", + " \n", + "\n", + " OpenMP parameters:\n", + "\n", + " ------------------\n", + "\n", + " Number of threads = 8\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "[===/ ] Time = 3.00000E+01 of 1.00000E+03\r" + ] + } + ], "source": [ - "sim.run(tstop=10.0)" + "sim.run()" ] }, { diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 57fe3956b..39798f62a 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -18,6 +18,7 @@ import json import os from pathlib import Path +import sys import datetime import xarray as xr import numpy as np @@ -395,28 +396,28 @@ def run(self,**kwargs): f.write(f"cd {self.sim_dir} {os.linesep}") f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} {os.linesep}") - try: - cmd = f"{env['SHELL']} -l {driver_script}" - with subprocess.Popen(shlex.split(cmd), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - env=env, - universal_newlines=True) as p: - for line in p.stdout: - if '[' in line: - print(line.replace('\n','\r')) - elif "Normal termination" in line: - print(line.replace("Normal termination","\n\nNormal termination")) - else: - print(line) - res = p.communicate() - if p.returncode != 0: - for line in res[1]: - print(line, end='') - raise Exception ("Failure in swiftest_driver") - except: - warnings.warn(f"Error executing main swiftest_driver program",stacklevel=2) - return + cmd = f"{env['SHELL']} -l {driver_script}" + oldline = None + with subprocess.Popen(shlex.split(cmd), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + universal_newlines=True) as p: + for line in p.stdout: + if '[' in line: + print(line.replace('\n','\r'), end='') + elif "Normal termination" in line: + print(line.replace("Normal termination","\n\nNormal termination")) + else: + print(line) + res = p.communicate() + if p.returncode != 0: + for line in res[1]: + print(line, end='') + raise Exception ("Failure in swiftest_driver") + #except: + # warnings.warn(f"Error executing main swiftest_driver program",stacklevel=2) + # return # Read in new data self.bin2xr() diff --git a/src/io/io_progress_bar.f90 b/src/io/io_progress_bar.f90 index 2f0aaf6f0..37fc819f9 100644 --- a/src/io/io_progress_bar.f90 +++ b/src/io/io_progress_bar.f90 @@ -7,18 +7,22 @@ module io_progress_bar implicit none public + character(len=1), dimension(4), parameter, private :: spinstr = ["/","-","\","|"] !! The progress spinner sequency + character(len=1),parameter, private :: barchar = "=" !! The progress bar character + type :: progress_bar !! author: David A. Minton !! !! Implements a class for a simple progress bar that can print on the screen. integer(I4B) :: PBARSIZE = 80 !! Number of characters acros for a whole progress bar - integer(I8B) :: nloops !! The total number of loops that the progrees bar is executing + integer(I8B) :: loop_length !! The total number of loops that the progrees bar is executing + integer(I8B) :: spinner_cycle_length !! The number of loop iterations it takes to execute a full spinner cycle + integer(I8B) :: spinner_skip !! The number of loop iterations to execute before updating the spinner character(len=:), allocatable :: barstr !! The string that prints out as the progress bar - integer(I4B) :: spinner !! Position of the "spinner" that indicates that progress is being made - character(len=1) :: barchar = "=" !! The progress bar character + integer(I4B) :: bar_pos !! The current position of the progress bar + integer(I4B) :: spin_pos !! Position of the "spinner" that indicates that progress is being made character(len=32) :: fmt !! The format string that is used to define the progress bar itself - integer(I4B) :: pos !! The current position of the progress bar - character(len=32) :: message !! The current message displayed at the end of the progress bar + character(len=64) :: message !! The current message displayed at the end of the progress bar contains procedure :: reset => io_pbar_reset !! Resets the progress bar to the beginning procedure :: update => io_pbar_update !! Updates the progress bar with new values and causes the "spinner" to flip. @@ -26,14 +30,15 @@ module io_progress_bar contains - subroutine io_pbar_reset(self, nloops) + subroutine io_pbar_reset(self, loop_length, spinner_cycle_length) !! author: David A. Minton !! !! Resets the progress bar to the beginning implicit none ! Arguments - class(progress_bar),intent(inout) :: self - integer(I8B), intent(in) :: nloops + class(progress_bar),intent(inout) :: self !! The progress bar object + integer(I8B), intent(in) :: loop_length !! The length of the loop that the progress bar is attached to + integer(I8B), intent(in), optional :: spinner_cycle_length !! The number of iterations between a complete spinner cycle. If not passd, the default is to update the spinner each call ! Internals character(len=2) :: numchar integer(I4B) :: k @@ -45,13 +50,20 @@ subroutine io_pbar_reset(self, nloops) self%barstr(k:k) = " " end do write(numchar,'(I2)') self%PBARSIZE - self%fmt = '(A1,"[",A' // numchar // ',"]",$)' - self%nloops = nloops - self%spinner = 0 - self%pos = 0 + self%fmt = '(A1,"[",A' // numchar // ',"] ",A,$)' + self%loop_length = loop_length + self%bar_pos = 0 self%message = "" + if (present(spinner_cycle_length)) then + self%spinner_cycle_length = spinner_cycle_length + self%spinner_skip = self%spinner_cycle_length / size(spinstr) + else + self%spinner_cycle_length = size(spinstr) + self%spinner_skip = 1 + end if + self%spin_pos = 1 - write(*,fmt=self%fmt) char(13),self%barstr + write(*,fmt=self%fmt) char(13),self%barstr,trim(adjustl(self%message)) return end subroutine io_pbar_reset @@ -68,28 +80,36 @@ subroutine io_pbar_update(self,i,message) character(len=*), intent(in), optional :: message !! An optional message to display to the right of the progress bar ! Internals real(DP) :: frac - integer(I4B) :: pos !! The current integer position of the progress bar - character(len=1), dimension(4), parameter :: spinstr = ["/","-","\","|"] - - + integer(I4B) :: bar_pos, spin_pos !! The current integer position of the progress bar and spinner + logical :: update = .false. ! Compute the current position - frac = real(i,kind=DP) / real(self%nloops,kind=DP) - pos = min(int(ceiling(frac * self%PBARSIZE),kind=I4B),self%PBARSIZE) + frac = real(i,kind=DP) / real(self%loop_length,kind=DP) + bar_pos = min(int(ceiling(frac * self%PBARSIZE),kind=I4B),self%PBARSIZE) - if (pos /= self%pos) then - self%pos = pos + if (bar_pos /= self%bar_pos) then ! Fill in the bar character up to the current position - self%barstr(pos:pos) = self%barchar + self%barstr(bar_pos:bar_pos) = barchar + update = .true. + self%bar_pos = bar_pos end if ! Compute the current value of the spinner and set the spinner character - self%spinner = self%spinner + 1 - if (self%spinner > size(spinstr)) self%spinner = 1 + spin_pos = mod(i / self%spinner_skip, size(spinstr)) + 1 + if (spin_pos /= self%spin_pos) then + self%barstr(bar_pos+1:bar_pos+1) = spinstr(spin_pos) + self%spin_pos = spin_pos + update = .true. + end if - self%barstr(pos+1:pos+1) = spinstr(self%spinner) + if (present(message)) then + if (message /= self%message) then + update = .true. + self%message = message + end if + end if - write(*,fmt=self%fmt) char(13),self%barstr + if (update) write(*,fmt=self%fmt) char(13),self%barstr,trim(adjustl(self%message)) return diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index 1d3535daf..f93f2522a 100644 --- a/src/main/swiftest_driver.f90 +++ b/src/main/swiftest_driver.f90 @@ -36,6 +36,8 @@ program swiftest_driver '"; Number of active pl, tp = ", I5, ", ", I5)' character(*), parameter :: symbastatfmt = '("Time = ", ES12.5, "; fraction done = ", F6.3, ' // & '"; Number of active plm, pl, tp = ", I5, ", ", I5, ", ", I5)' + character(*), parameter :: pbarfmt = '("Time = ", ES12.5," of ",ES12.5)' + character(len=64) :: pbarmessage ierr = io_get_args(integrator, param_file_name) if (ierr /= 0) then @@ -87,10 +89,11 @@ program swiftest_driver !$ write(*,'(a)') ' OpenMP parameters:' !$ write(*,'(a)') ' ------------------' !$ write(*,'(a,i3,/)') ' Number of threads = ', nthreads - write(*, *) " *************** Main Loop *************** " + !write(*, *) " *************** Main Loop *************** " if (param%lrestart .and. param%lenergy) call nbody_system%conservation_report(param, lterminal=.true.) - call pbar%reset(nloops) - call pbar%update(1) + call pbar%reset(nloops, spinner_cycle_length=istep_out) + write(pbarmessage,fmt=pbarfmt) t0, tstop + call pbar%update(1,message=pbarmessage) do iloop = 1, nloops !> Step the system forward in time call integration_timer%start() @@ -101,6 +104,7 @@ program swiftest_driver !> Evaluate any discards or collisional outcomes call nbody_system%discard(param) + call pbar%update(iloop) !> If the loop counter is at the output cadence value, append the data file with a single frame if (istep_out > 0) then @@ -122,7 +126,8 @@ program swiftest_driver !call integration_timer%reset() iout = istep_out - call pbar%update(iloop) + write(pbarmessage,fmt=pbarfmt) t, tstop + call pbar%update(1,message=pbarmessage) end if end if