From 5afb1ea51520df38c5fc848aa405e92ef9c1f3a9 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 12:13:53 -0500 Subject: [PATCH 1/9] Created new compact formatted output that can be post-processed by Python --- src/io/io.f90 | 105 +++++++++++++++++++++++++------ src/main/swiftest_driver.f90 | 12 ++-- src/modules/swiftest_classes.f90 | 10 +-- src/modules/swiftest_globals.f90 | 18 +++--- src/modules/symba_classes.f90 | 2 +- src/symba/symba_io.f90 | 2 +- 6 files changed, 109 insertions(+), 40 deletions(-) diff --git a/src/io/io.f90 b/src/io/io.f90 index 974c6aae0..6b6654998 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -18,35 +18,100 @@ module subroutine io_compact_output(self, param, timer) !! Generates the terminal output displayed when display_style is set to COMPACT. This is used by the Python driver to !! make nice-looking progress reports. implicit none + + interface fmt + !! author: David Minton + !! + !! Formats a pair of variables and corresponding values for the compact display output. Generic interface for different variable types to format. + procedure :: fmt_I4B, fmt_I8B, fmt_DP + end interface + ! Arguments class(swiftest_nbody_system), intent(in) :: self !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Input colleciton of user-defined parameters class(*), intent(in) :: timer !! Object used for computing elapsed wall time (must be unlimited polymorphic because the walltimer module requires swiftest_classes) ! Internals - character(*), parameter :: COMPACTFMT = '("ILOOP",I,";T",ES23.16,";WT",ES23.16,";IWT",ES23.16,";WTPS",ES23.16,";NPL",I,";NTP",I,";"$)' - character(*), parameter :: SYMBAFMT = '(";NPLM",I,$)' - character(*), parameter :: EGYFMT = '("LTOTERR",ES24.16,";ETOTERR",ES24.16,";MTOTERR",ES24.16,";KEOERR",ES24.16,";KESERR",ES24.16,";PEERR",ES24.16' & - // '";EORBERR",ES24.16,";ECOLERR",ES24.16,";EUNTRERR",ES24.16,";LSPINERR",ES24.16,";LESCERR",ES24.16' & - // '";MESCERR",ES24.16,$)' + !character(*), parameter :: COMPACTFMT = '("ILOOP",I,";T",ES23.16,";WT",ES23.16,";IWT",ES23.16,";WTPS",ES23.16,";NPL",I,";NTP",I,";"$)' + !character(*), parameter :: SYMBAFMT = '(";NPLM",I,$)' + !character(*), parameter :: EGYFMT = '("LTOTERR",ES24.16,";ETOTERR",ES24.16,";MTOTERR",ES24.16,";KEOERR",ES24.16,";KESERR",ES24.16,";PEERR",ES24.16' & + ! // '";EORBERR",ES24.16,";ECOLERR",ES24.16,";EUNTRERR",ES24.16,";LSPINERR",ES24.16,";LESCERR",ES24.16' & + ! // '";MESCERR",ES24.16,$)' + character(len=:), allocatable :: formatted_output + select type(timer) class is (walltimer) - if (.not. timer%main_is_started) then ! This is the start of a new run - write(*,*) "START" - write(*,COMPACTFMT) 0,param%t,0.0,0.0,0.0,self%pl%nbody, self%tp%nbody - else - write(*,COMPACTFMT) param%iloop,param%t, timer%wall_main, timer%wall_step, timer%wall_per_substep,self%pl%nbody, self%tp%nbody - end if + formatted_output = fmt("ILOOP",param%iloop) // fmt("T",param%t) // fmt("NPL",self%pl%nbody) // fmt("NTP",self%tp%nbody) select type(pl => self%pl) class is (symba_pl) - write(*,SYMBAFMT) pl%nplm + formatted_output = formatted_output // fmt("NPLM",pl%nplm) end select if (param%lenergy) then - write(*,EGYFMT) self%Ltot_error, self%Etot_error, self%Mtot_error, self%ke_orbit_error, self%ke_spin_error, self%pe_error, & - self%Eorbit_error, self%Ecoll_error, self%Euntracked_error, self%Lspin_error, self%Lescape_error, self%Mescape_error + formatted_output = formatted_output // fmt("LTOTERR",self%Ltot_error) // fmt("ETOTERR",self%Mtot_error) // fmt("MTOTERR",self%Mtot_error) & + // fmt("KEOERR",self%ke_orbit_error) // fmt("PEERR",self%pe_error) // fmt("EORBERR",self%Eorbit_error) & + // fmt("EUNTRERR",self%Euntracked_error) // fmt("LESCERR",self%Lescape_error) // fmt("MESCERR",self%Mescape_error) + if (param%lclose) formatted_output = formatted_output // fmt("ECOLLERR",self%Ecoll_error) + if (param%lrotation) formatted_output = formatted_output // fmt("KESPINERR",self%ke_spin_error) // fmt("LSPINERR",self%Lspin_error) + end if + + if (.not. timer%main_is_started) then ! This is the start of a new run + formatted_output = formatted_output // fmt("WT",0.0_DP) // fmt("IWT",0.0_DP) // fmt("WTPS",0.0_DP) + else + formatted_output = formatted_output // fmt("WT",timer%wall_main) // fmt("IWT",timer%wall_step) // fmt("WTPS",timer%wall_per_substep) end if - write(*,*) + write(*,*) formatted_output end select return + + contains + + function fmt_I4B(varname,val) result(pair_string) + implicit none + ! Arguments + character(*), intent(in) :: varname !! The variable name of the pair + integer(I4B), intent(in) :: val !! A 4-byte integer value + ! Result + character(len=:), allocatable :: pair_string + ! Internals + character(len=24) :: str_value + + write(str_value,*) val + pair_string = trim(adjustl(varname)) // " " // trim(adjustl(str_value)) // ";" + + return + end function fmt_I4B + + function fmt_I8B(varname, val) result(pair_string) + implicit none + ! Arguments + character(*), intent(in) :: varname !! The variable name of the pair + integer(I8B), intent(in) :: val !! An 8-byte integer value + ! Result + character(len=:), allocatable :: pair_string + ! Internals + character(len=24) :: str_value + + write(str_value,*) val + pair_string = trim(adjustl(varname)) // " " // trim(adjustl(str_value)) // ";" + + return + end function fmt_I8B + + function fmt_DP(varname, val) result(pair_string) + implicit none + ! Arguments + character(*), intent(in) :: varname !! The variable name of the pair + real(DP), intent(in) :: val !! A double precision floating point value + ! Result + character(len=:), allocatable :: pair_string + ! Internals + character(len=24) :: str_value + + write(str_value,'(ES24.16)') val + pair_string = trim(adjustl(varname)) // " " // trim(adjustl(str_value)) // ";" + + return + end function fmt_DP + end subroutine io_compact_output @@ -115,7 +180,7 @@ module subroutine io_conservation_report(self, param, lterminal) system%Mescape_error = system%GMescape / system%GMtot_orig system%Mtot_error = (GMtot_now - system%GMtot_orig) / system%GMtot_orig if (lterminal) write(display_unit, EGYTERMFMT) system%Ltot_error, system%Ecoll_error, system%Etot_error,system%Mtot_error - if (abs(Merror) > 100 * epsilon(Merror)) then + if (abs(system%Mtot_error) > 100 * epsilon(system%Mtot_error)) then write(*,*) "Severe error! Mass not conserved! Halting!" ! Save the frame of data to the bin file in the slot just after the present one for diagnostics param%ioutput = param%ioutput + 1_I8B @@ -379,9 +444,9 @@ module subroutine io_get_args(integrator, param_file_name, display_style) !! Reads in the name of the parameter file from command line arguments. implicit none ! Arguments - integer(I4B) :: integrator !! Symbolic code of the requested integrator - character(len=:), allocatable :: param_file_name !! Name of the input parameters file - character(len=:), allocatable :: display_style !! Style of the output display {"STANDARD", "COMPACT", "PROGRESS"}). Default is "STANDARD" + character(len=:), intent(inout), allocatable :: integrator !! Symbolic code of the requested integrator + character(len=:), intent(inout), allocatable :: param_file_name !! Name of the input parameters file + character(len=:), intent(inout), allocatable :: display_style !! Style of the output display {"STANDARD", "COMPACT", "PROGRESS"}). Default is "STANDARD" ! Internals character(len=STRMAX), dimension(:), allocatable :: arg integer(I4B), dimension(:), allocatable :: ierr @@ -599,7 +664,7 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + character(len=*), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader integer, intent(out) :: iostat !! IO status code character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 ! Internals diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index e557cbdfa..c25566fe0 100644 --- a/src/main/swiftest_driver.f90 +++ b/src/main/swiftest_driver.f90 @@ -20,7 +20,7 @@ program swiftest_driver class(swiftest_nbody_system), allocatable :: nbody_system !! Polymorphic object containing the nbody system to be integrated class(swiftest_parameters), allocatable :: param !! Run configuration parameters - integer(I4B) :: integrator !! Integrator type code (see swiftest_globals for symbolic names) + character(len=:), allocatable :: integrator !! Integrator type code (see swiftest_globals for symbolic names) character(len=:),allocatable :: param_file_name !! Name of the file containing user-defined parameters character(len=:), allocatable :: display_style !! Style of the output display {"STANDARD", "COMPACT", "PROGRESS"}). Default is "STANDARD" integer(I4B) :: ierr !! I/O error code @@ -102,6 +102,7 @@ program swiftest_driver write(pbarmessage,fmt=pbarfmt) t0, tstop call pbar%update(1,message=pbarmessage) else if (display_style == "COMPACT") then + write(*,*) "SWIFTEST START " // trim(adjustl(param%integrator)) call nbody_system%compact_output(param,integration_timer) end if do iloop = 1, nloops @@ -121,7 +122,7 @@ program swiftest_driver iout = iout - 1 if (iout == 0) then ioutput = ioutput_t0 + iloop / istep_out - if (t > old_t_final) call nbody_system%write_frame(param) + call nbody_system%write_frame(param) tfrac = (param%t - param%t0) / (param%tstop - param%t0) @@ -133,15 +134,17 @@ program swiftest_driver end select if (param%lenergy) call nbody_system%conservation_report(param, lterminal=.true.) call integration_timer%report(message="Integration steps:", unit=display_unit, nsubsteps=istep_out) - call integration_timer%reset() - iout = istep_out if (display_style == "PROGRESS") then write(pbarmessage,fmt=pbarfmt) t, tstop call pbar%update(1,message=pbarmessage) else if (display_style == "COMPACT") then call nbody_system%compact_output(param,integration_timer) end if + + call integration_timer%reset() + + iout = istep_out end if end if @@ -154,6 +157,7 @@ program swiftest_driver end if end if end do + if (display_style == "COMPACT") write(*,*) "SWIFTEST STOP" // trim(adjustl(param%integrator)) end associate call nbody_system%dealloc() diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 26686c1d6..00cf6583f 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -32,7 +32,7 @@ module swiftest_classes !> User defined parameters that are read in from the parameters input file. !> Each paramter is initialized to a default values. type :: swiftest_parameters - integer(I4B) :: integrator = UNKNOWN_INTEGRATOR !! Symbolic name of the nbody integrator used + character(STRMAX) :: integrator = UNKNOWN_INTEGRATOR !! Symbolic name of the nbody integrator used character(STRMAX) :: param_file_name = "param.in" !! The default name of the parameter input file integer(I4B) :: maxid = -1 !! The current maximum particle id number integer(I4B) :: maxid_collision = 0 !! The current maximum collision id number @@ -657,9 +657,9 @@ end subroutine io_dump_system module subroutine io_get_args(integrator, param_file_name, display_style) implicit none - integer(I4B) :: integrator !! Symbolic code of the requested integrator - character(len=:), allocatable :: param_file_name !! Name of the input parameters file - character(len=:), allocatable :: display_style !! Style of the output display {"STANDARD", "COMPACT"}). Default is "STANDARD" + character(len=:), allocatable, intent(inout) :: integrator !! Symbolic code of the requested integrator + character(len=:), allocatable, intent(inout) :: param_file_name !! Name of the input parameters file + character(len=:), allocatable, intent(inout) :: display_style !! Style of the output display {"STANDARD", "COMPACT"}). Default is "STANDARD" end subroutine io_get_args module function io_get_old_t_final_system(self, param) result(old_t_final) @@ -697,7 +697,7 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) integer(I4B), intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer(I4B), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + character(len=*), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader integer(I4B), intent(out) :: iostat !! IO status code character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 end subroutine io_param_reader diff --git a/src/modules/swiftest_globals.f90 b/src/modules/swiftest_globals.f90 index dff9cad56..97c68b85e 100644 --- a/src/modules/swiftest_globals.f90 +++ b/src/modules/swiftest_globals.f90 @@ -44,15 +44,15 @@ module swiftest_globals real(SP), parameter :: VERSION_NUMBER = 1.0_SP !! swiftest version !> Symbolic name for integrator types - integer(I4B), parameter :: UNKNOWN_INTEGRATOR = 1 - integer(I4B), parameter :: BS = 2 - integer(I4B), parameter :: HELIO = 3 - integer(I4B), parameter :: RA15 = 4 - integer(I4B), parameter :: TU4 = 5 - integer(I4B), parameter :: WHM = 6 - integer(I4B), parameter :: RMVS = 7 - integer(I4B), parameter :: SYMBA = 8 - integer(I4B), parameter :: RINGMOONS = 9 + character(*), parameter :: UNKNOWN_INTEGRATOR = "UKNOWN INTEGRATOR" + character(*), parameter :: BS = "Bulirsch-Stoer" + character(*), parameter :: HELIO = "Democratic Heliocentric" + character(*), parameter :: RA15 = "Radau 15th order" + character(*), parameter :: TU4 = "T+U 4th order" + character(*), parameter :: WHM = "Wisdom-Holman Method" + character(*), parameter :: RMVS = "Regularized Mixed Variable Symplectic" + character(*), parameter :: SYMBA = "SyMBA" + character(*), parameter :: RINGMOONS = "SyMBA-RINGMOONS" integer(I4B), parameter :: STRMAX = 512 !! Maximum size of character strings integer(I4B), parameter :: NAMELEN = 32 !! Maximum size of name strings diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index cacad4b4d..e016a36b9 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -375,7 +375,7 @@ module subroutine symba_io_param_reader(self, unit, iotype, v_list, iostat, ioms integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + character(len=*), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader integer, intent(out) :: iostat !! IO status code character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 end subroutine symba_io_param_reader diff --git a/src/symba/symba_io.f90 b/src/symba/symba_io.f90 index 7f2792309..d9a48b52a 100644 --- a/src/symba/symba_io.f90 +++ b/src/symba/symba_io.f90 @@ -24,7 +24,7 @@ module subroutine symba_io_param_reader(self, unit, iotype, v_list, iostat, ioms integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + character(len=*), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader integer, intent(out) :: iostat !! IO status code character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 ! internals From 3fb5fff6d3fe7de40bcb9185baa50da2739a60ae Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:03:32 -0500 Subject: [PATCH 2/9] Finished making compact output that can easily be turned into a Python dictionary --- python/swiftest/swiftest/simulation_class.py | 19 ++++++++++++------- src/io/io.f90 | 5 ----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 834f6e40a..9f1555411 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -365,7 +365,7 @@ def _run_swiftest_driver(self): f.write(f"#{self._shell_full} -l\n") f.write(f"source ~/.{self._shell}rc\n") f.write(f"cd {self.sim_dir}\n") - f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} progress\n") + f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} compact\n") cmd = f"{env['SHELL']} -l {driver_script}" @@ -375,13 +375,18 @@ def _run_swiftest_driver(self): stderr=subprocess.PIPE, env=env, universal_newlines=True) as p: + process_output = False 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"), end='') - else: - print(line, end='') + if "SWIFTEST STOP" in line: + process_output = False + + if process_output: + kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, + output_data = {kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]} + + if "SWIFTEST START" in line: + process_output = True + res = p.communicate() if p.returncode != 0: for line in res[1]: diff --git a/src/io/io.f90 b/src/io/io.f90 index 6b6654998..c5af067f5 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -31,11 +31,6 @@ module subroutine io_compact_output(self, param, timer) class(swiftest_parameters), intent(in) :: param !! Input colleciton of user-defined parameters class(*), intent(in) :: timer !! Object used for computing elapsed wall time (must be unlimited polymorphic because the walltimer module requires swiftest_classes) ! Internals - !character(*), parameter :: COMPACTFMT = '("ILOOP",I,";T",ES23.16,";WT",ES23.16,";IWT",ES23.16,";WTPS",ES23.16,";NPL",I,";NTP",I,";"$)' - !character(*), parameter :: SYMBAFMT = '(";NPLM",I,$)' - !character(*), parameter :: EGYFMT = '("LTOTERR",ES24.16,";ETOTERR",ES24.16,";MTOTERR",ES24.16,";KEOERR",ES24.16,";KESERR",ES24.16,";PEERR",ES24.16' & - ! // '";EORBERR",ES24.16,";ECOLERR",ES24.16,";EUNTRERR",ES24.16,";LSPINERR",ES24.16,";LESCERR",ES24.16' & - ! // '";MESCERR",ES24.16,$)' character(len=:), allocatable :: formatted_output select type(timer) From 63617b1581910d07165da4b476fae846618d2f2f Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:04:05 -0500 Subject: [PATCH 3/9] Changed cmake so that mod files get put in the includes directory instead of lib --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 96ce5efa9..828a37bb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,9 +59,10 @@ SET(SWIFTEST_DRIVER swiftest_driver) SET(SRC ${CMAKE_SOURCE_DIR}/src) SET(LIB ${CMAKE_SOURCE_DIR}/lib) SET(BIN ${CMAKE_SOURCE_DIR}/bin) +SET(MOD ${CMAKE_SOURCE_DIR}/include) # Have the .mod files placed in the lib folder -SET(CMAKE_Fortran_MODULE_DIRECTORY ${LIB}) +SET(CMAKE_Fortran_MODULE_DIRECTORY ${MOD}) # The source for the SWIFTEST binary and have it placed in the bin folder ADD_SUBDIRECTORY(${SRC} ${BIN}) From b037272b31b65aa68e4b44ba4b7e90b7b6b5ebbd Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:06:27 -0500 Subject: [PATCH 4/9] Updated the ignore file to try to remove the simdata directory --- examples/.gitignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/.gitignore b/examples/.gitignore index df5a1c5d1..4aceee79f 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -1,2 +1,4 @@ */param.* -*/.swiftest* +*/simdata/* +*/*/simdata/* + From 35d1cf079127f3ed735c9112ca86ea8f0137a1bf Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:07:46 -0500 Subject: [PATCH 5/9] Removed param file from repo --- examples/Basic_Simulation/simdata/param.in | 37 ---------------------- 1 file changed, 37 deletions(-) delete mode 100644 examples/Basic_Simulation/simdata/param.in diff --git a/examples/Basic_Simulation/simdata/param.in b/examples/Basic_Simulation/simdata/param.in deleted file mode 100644 index 3246644ce..000000000 --- a/examples/Basic_Simulation/simdata/param.in +++ /dev/null @@ -1,37 +0,0 @@ -! VERSION Swiftest input file -T0 0.0 -TSTART 0.0 -TSTOP 1000.0 -DT 0.005 -ISTEP_OUT 200 -ISTEP_DUMP 200 -NC_IN init_cond.nc -IN_TYPE NETCDF_DOUBLE -IN_FORM EL -BIN_OUT bin.nc -OUT_FORM XVEL -OUT_TYPE NETCDF_DOUBLE -OUT_STAT REPLACE -CHK_QMIN 0.004650467260962157 -CHK_RMIN 0.004650467260962157 -CHK_RMAX 10000.0 -CHK_EJECT 10000.0 -CHK_QMIN_COORD HELIO -CHK_QMIN_RANGE 0.004650467260962157 10000.0 -MU2KG 1.988409870698051e+30 -TU2S 31557600.0 -DU2M 149597870700.0 -GMTINY 9.869231602224408e-07 -FRAGMENTATION YES -MIN_GMFRAG 9.869231602224408e-10 -RESTART NO -CHK_CLOSE YES -GR YES -ROTATION YES -ENERGY NO -EXTRA_FORCE NO -BIG_DISCARD NO -RHILL_PRESENT NO -INTERACTION_LOOPS TRIANGULAR -ENCOUNTER_CHECK TRIANGULAR -TIDES NO From 9f429d11c0f6aaabd56b0417b87e93d367dcffa3 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:19:07 -0500 Subject: [PATCH 6/9] Added tqdm progress bar --- python/swiftest/swiftest/simulation_class.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 9f1555411..436cfb605 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -26,6 +26,7 @@ import subprocess import shlex import warnings +from tqdm import tqdm from typing import ( Literal, Dict, @@ -376,7 +377,8 @@ def _run_swiftest_driver(self): env=env, universal_newlines=True) as p: process_output = False - for line in p.stdout: + noutput = int((self.param['TSTOP'] - self.param['T0']) / (self.param['DT'] * self.param['ISTEP_OUT'])) + for line in tqdm(p.stdout,total=noutput): if "SWIFTEST STOP" in line: process_output = False From e6de73a70a2c34e6d2188a8c697b4a4f397fb2d5 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 17:30:13 -0500 Subject: [PATCH 7/9] Set the progress bar in tqdm so that it manually updates --- python/swiftest/swiftest/simulation_class.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 436cfb605..3ccea2d6a 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -377,14 +377,16 @@ def _run_swiftest_driver(self): env=env, universal_newlines=True) as p: process_output = False - noutput = int((self.param['TSTOP'] - self.param['T0']) / (self.param['DT'] * self.param['ISTEP_OUT'])) - for line in tqdm(p.stdout,total=noutput): + noutput = int((self.param['TSTOP'] - self.param['T0']) / self.param['DT']) + pbar = tqdm(total=noutput) + for line in p.stdout: if "SWIFTEST STOP" in line: process_output = False if process_output: kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, output_data = {kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]} + pbar.update(self.param['ISTEP_OUT']) if "SWIFTEST START" in line: process_output = True @@ -397,6 +399,7 @@ def _run_swiftest_driver(self): except: warnings.warn(f"Error executing main swiftest_driver program", stacklevel=2) + pbar.close() return def run(self,**kwargs): From d1599f3adbd36856638099d04a724c658a444a74 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 22 Nov 2022 19:43:04 -0500 Subject: [PATCH 8/9] Added time values to progress bar --- python/swiftest/swiftest/simulation_class.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 3ccea2d6a..21b0e8e95 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -370,6 +370,15 @@ def _run_swiftest_driver(self): cmd = f"{env['SHELL']} -l {driver_script}" + def _type_scrub(output_data): + int_vars = ["ILOOP","NPL","NTP","NPLM"] + for k,v in output_data.items(): + if k in int_vars: + output_data[k] = int(v) + else: + output_data[k] = float(v) + return output_data + try: with subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, @@ -378,6 +387,7 @@ def _run_swiftest_driver(self): universal_newlines=True) as p: process_output = False noutput = int((self.param['TSTOP'] - self.param['T0']) / self.param['DT']) + iloop = int((self.param['TSTART'] - self.param['T0']) / self.param['DT']) pbar = tqdm(total=noutput) for line in p.stdout: if "SWIFTEST STOP" in line: @@ -385,8 +395,13 @@ def _run_swiftest_driver(self): if process_output: kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, - output_data = {kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]} - pbar.update(self.param['ISTEP_OUT']) + output_data = _type_scrub({kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]}) + message = f"Time: {output_data['T']} {self.TU_name}/{self.param['TSTOP']} {self.TU_name}" + pbar.set_description_str(message) + interval = output_data['ILOOP'] - iloop + if interval > 0: + pbar.update(interval) + iloop = output_data['ILOOP'] if "SWIFTEST START" in line: process_output = True From 92702fc5978da97c36af765d44eed6740fb52757 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Wed, 23 Nov 2022 10:03:46 -0500 Subject: [PATCH 9/9] Added more data to the progress bar --- python/swiftest/swiftest/simulation_class.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 21b0e8e95..d0a3f2829 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -26,7 +26,7 @@ import subprocess import shlex import warnings -from tqdm import tqdm +from tqdm.auto import tqdm from typing import ( Literal, Dict, @@ -396,8 +396,12 @@ def _type_scrub(output_data): if process_output: kvstream=line.replace('\n','').strip().split(';') # Removes the newline character, output_data = _type_scrub({kv.split()[0]: kv.split()[1] for kv in kvstream[:-1]}) - message = f"Time: {output_data['T']} {self.TU_name}/{self.param['TSTOP']} {self.TU_name}" - pbar.set_description_str(message) + pre_message = f"Time: {output_data['T']} / {self.param['TSTOP']} {self.TU_name}" + post_message = f"npl: {output_data['NPL']} ntp: {output_data['NTP']}" + if "NPLM" in output_data: + post_message = post_message + f" nplm: {output_data['NPLM']}" + pbar.set_description_str(pre_message) + pbar.set_postfix_str(post_message) interval = output_data['ILOOP'] - iloop if interval > 0: pbar.update(interval)