diff --git a/examples/Basic_Simulation/initial_conditions.ipynb b/examples/Basic_Simulation/initial_conditions.ipynb index 2bcd9cfe7..2014b6e06 100644 --- a/examples/Basic_Simulation/initial_conditions.ipynb +++ b/examples/Basic_Simulation/initial_conditions.ipynb @@ -2,10 +2,18 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "id": "2c4f59ea-1251-49f6-af1e-5695d7e25500", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "env: OMP_NUM_THREADS=4\n" + ] + } + ], "source": [ "import swiftest\n", "import numpy as np\n", @@ -15,7 +23,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "id": "6054c7ab-c748-4b39-9fee-d8b27326f497", "metadata": {}, "outputs": [], @@ -26,10 +34,459 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "1c122676-bacb-447c-bc37-5ef8019be0d0", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Creating the Sun as a central body\n", + "Fetching ephemerides data for Mercury from JPL/Horizons\n", + "Fetching ephemerides data for Venus from JPL/Horizons\n", + "Fetching ephemerides data for Earth from JPL/Horizons\n", + "Fetching ephemerides data for Mars from JPL/Horizons\n", + "Fetching ephemerides data for Jupiter from JPL/Horizons\n", + "Fetching ephemerides data for Saturn from JPL/Horizons\n", + "Fetching ephemerides data for Uranus from JPL/Horizons\n", + "Fetching ephemerides data for Neptune from JPL/Horizons\n", + "Fetching ephemerides data for Pluto from JPL/Horizons\n", + "Writing initial conditions to file /home/daminton/git_debug/swiftest/examples/Basic_Simulation/.swiftest/init_cond.nc\n", + "Writing parameter inputs to file /home/daminton/git_debug/swiftest/examples/Basic_Simulation/.swiftest/param.in\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:        (name: 10, time: 1)\n",
+       "Coordinates:\n",
+       "  * name           (name) <U32 'Sun' 'Mercury' 'Venus' ... 'Neptune' 'Pluto'\n",
+       "  * time           (time) float64 0.0\n",
+       "Data variables: (12/20)\n",
+       "    particle_type  (name) <U32 'Central Body' 'Massive Body' ... 'Massive Body'\n",
+       "    id             (name) int64 0 1 2 3 4 5 6 7 8 9\n",
+       "    a              (time, name) float64 nan 0.3871 0.7233 ... 19.24 30.04 39.37\n",
+       "    e              (time, name) float64 nan 0.2056 0.006718 ... 0.008956 0.2487\n",
+       "    inc            (time, name) float64 nan 7.003 3.394 ... 0.773 1.771 17.17\n",
+       "    capom          (time, name) float64 nan 48.3 76.6 ... 74.01 131.8 110.3\n",
+       "    ...             ...\n",
+       "    roty           (time, name) float64 -38.76 -18.38 ... -2.177e+03 261.3\n",
+       "    rotz           (time, name) float64 82.25 34.36 8.703 ... 2.33e+03 -38.57\n",
+       "    j2rp2          (time, name) float64 4.754e-12 nan nan nan ... nan nan nan\n",
+       "    j4rp4          (time, name) float64 -2.247e-18 nan nan nan ... nan nan nan\n",
+       "    ntp            (time) int64 0\n",
+       "    npl            (time) int64 9
" + ], + "text/plain": [ + "\n", + "Dimensions: (name: 10, time: 1)\n", + "Coordinates:\n", + " * name (name) \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:        (name: 5, time: 1)\n",
+       "Coordinates:\n",
+       "  * name           (name) <U14 'MassiveBody_01' ... 'MassiveBody_05'\n",
+       "  * time           (time) float64 0.0\n",
+       "Data variables: (12/18)\n",
+       "    particle_type  (name) <U14 'Massive Body' 'Massive Body' ... 'Massive Body'\n",
+       "    id             (name) int64 10 11 12 13 14\n",
+       "    a              (time, name) float64 0.833 0.5434 0.799 0.3786 1.063\n",
+       "    e              (time, name) float64 0.2656 0.1473 0.178 0.1331 0.2989\n",
+       "    inc            (time, name) float64 82.77 64.86 84.68 52.85 16.77\n",
+       "    capom          (time, name) float64 230.6 328.9 222.6 269.3 218.2\n",
+       "    ...             ...\n",
+       "    Ip3            (time, name) float64 0.4 0.4 0.4 0.4 0.4\n",
+       "    rotx           (time, name) float64 0.0 0.0 0.0 0.0 0.0\n",
+       "    roty           (time, name) float64 0.0 0.0 0.0 0.0 0.0\n",
+       "    rotz           (time, name) float64 0.0 0.0 0.0 0.0 0.0\n",
+       "    ntp            (time) int64 0\n",
+       "    npl            (time) int64 4
" + ], + "text/plain": [ + "\n", + "Dimensions: (name: 5, time: 1)\n", + "Coordinates:\n", + " * name (name) \n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "\n", + "
<xarray.Dataset>\n",
+       "Dimensions:        (name: 10, time: 1)\n",
+       "Coordinates:\n",
+       "  * name           (name) <U15 'TestParticle_01' ... 'TestParticle_10'\n",
+       "  * time           (time) float64 0.0\n",
+       "Data variables:\n",
+       "    particle_type  (name) <U15 'Test Particle' ... 'Test Particle'\n",
+       "    id             (name) int64 15 16 17 18 19 20 21 22 23 24\n",
+       "    a              (time, name) float64 1.23 0.4818 0.8926 ... 0.8866 0.9032\n",
+       "    e              (time, name) float64 0.2545 0.02039 0.107 ... 0.1635 0.1588\n",
+       "    inc            (time, name) float64 74.72 69.71 6.346 ... 14.14 65.34 44.03\n",
+       "    capom          (time, name) float64 128.9 142.6 267.7 ... 311.2 62.34 253.7\n",
+       "    omega          (time, name) float64 95.45 208.0 74.89 ... 146.6 136.8 181.0\n",
+       "    capm           (time, name) float64 100.1 189.3 202.6 ... 327.8 270.4 188.0\n",
+       "    ntp            int64 10\n",
+       "    npl            int64 0
" + ], + "text/plain": [ + "\n", + "Dimensions: (name: 10, time: 1)\n", + "Coordinates:\n", + " * name (name) \u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0msim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", + "\u001b[0;32m~/git_debug/swiftest/python/swiftest/swiftest/simulation_class.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 404\u001b[0m \u001b[0menv\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0menv\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 405\u001b[0m universal_newlines=True) as p:\n\u001b[0;32m--> 406\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mline\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstdout\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 407\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0;34m'['\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mline\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 408\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'\\n'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m'\\r'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mend\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], "source": [ - "sim.run(tstop=10.0)" + "sim.run()" ] }, { diff --git a/examples/Basic_Simulation/simdata/param.in b/examples/Basic_Simulation/simdata/param.in new file mode 100644 index 000000000..3246644ce --- /dev/null +++ b/examples/Basic_Simulation/simdata/param.in @@ -0,0 +1,37 @@ +! 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 diff --git a/examples/helio_gr_test/grsim/param.gr.in b/examples/helio_gr_test/grsim/param.gr.in new file mode 100644 index 000000000..0616db203 --- /dev/null +++ b/examples/helio_gr_test/grsim/param.gr.in @@ -0,0 +1,35 @@ +! VERSION Swiftest input file +T0 0.0 +TSTART 0.0 +TSTOP 1000.0 +DT 0.005 +ISTEP_OUT 2000 +ISTEP_DUMP 2000 +NC_IN init_cond.nc +IN_TYPE NETCDF_DOUBLE +IN_FORM EL +BIN_OUT bin.gr.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 +FRAGMENTATION NO +RESTART NO +CHK_CLOSE YES +GR YES +ROTATION NO +ENERGY NO +EXTRA_FORCE NO +BIG_DISCARD NO +RHILL_PRESENT NO +INTERACTION_LOOPS TRIANGULAR +ENCOUNTER_CHECK TRIANGULAR +TIDES NO diff --git a/examples/helio_gr_test/nogrsim/param.nogr.in b/examples/helio_gr_test/nogrsim/param.nogr.in new file mode 100644 index 000000000..9e2ab0b22 --- /dev/null +++ b/examples/helio_gr_test/nogrsim/param.nogr.in @@ -0,0 +1,35 @@ +! VERSION Swiftest input file +T0 0.0 +TSTART 0.0 +TSTOP 1000.0 +DT 0.005 +ISTEP_OUT 2000 +ISTEP_DUMP 2000 +NC_IN init_cond.nc +IN_TYPE NETCDF_DOUBLE +IN_FORM EL +BIN_OUT bin.nogr.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 +FRAGMENTATION NO +RESTART NO +CHK_CLOSE YES +GR NO +ROTATION NO +ENERGY NO +EXTRA_FORCE NO +BIG_DISCARD NO +RHILL_PRESENT NO +INTERACTION_LOOPS TRIANGULAR +ENCOUNTER_CHECK TRIANGULAR +TIDES NO diff --git a/examples/helio_gr_test/swiftest_relativity.ipynb b/examples/helio_gr_test/swiftest_relativity.ipynb index 6946ef658..4b6d13106 100644 --- a/examples/helio_gr_test/swiftest_relativity.ipynb +++ b/examples/helio_gr_test/swiftest_relativity.ipynb @@ -19,7 +19,7 @@ "metadata": {}, "outputs": [], "source": [ - "sim_gr = swiftest.Simulation(param_file=\"param.gr.in\", output_file_name=\"bin.gr.nc\")\n", + "sim_gr = swiftest.Simulation(param_file=\"grsim/param.gr.in\", output_file_name=\"bin.gr.nc\")\n", "sim_gr.add_solar_system_body([\"Sun\",\"Mercury\",\"Venus\",\"Earth\",\"Mars\",\"Jupiter\",\"Saturn\",\"Uranus\",\"Neptune\"])" ] }, @@ -29,7 +29,7 @@ "metadata": {}, "outputs": [], "source": [ - "sim_nogr = swiftest.Simulation(param_file=\"param.nogr.in\", output_file_name=\"bin.nogr.nc\")\n", + "sim_nogr = swiftest.Simulation(param_file=\"nogrsim/param.nogr.in\", output_file_name=\"bin.nogr.nc\")\n", "sim_nogr.add_solar_system_body([\"Sun\",\"Mercury\",\"Venus\",\"Earth\",\"Mars\",\"Jupiter\",\"Saturn\",\"Uranus\",\"Neptune\"])" ] }, @@ -39,7 +39,6 @@ "metadata": {}, "outputs": [], "source": [ - "%%capture\n", "tstep_out = 10.0\n", "sim_gr.run(tstop=1000.0, dt=0.005, tstep_out=tstep_out, integrator=\"helio\",general_relativity=True)" ] @@ -50,7 +49,6 @@ "metadata": {}, "outputs": [], "source": [ - "%%capture\n", "sim_nogr.run(tstop=1000.0, dt=0.005, tstep_out=tstep_out, integrator=\"helio\",general_relativity=False)" ] }, @@ -138,13 +136,6 @@ "print(f'Obs - Swiftest No GR : {np.mean(dvarpi_obs - dvarpi_nogr)}')" ] }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - }, { "cell_type": "code", "execution_count": null, diff --git a/python/swiftest/swiftest/constants.py b/python/swiftest/swiftest/constants.py index fe3253c86..2d3f89f7c 100644 --- a/python/swiftest/swiftest/constants.py +++ b/python/swiftest/swiftest/constants.py @@ -13,7 +13,7 @@ import astropy.constants as const # Constants in SI units -GC = const.G.value +GC = const.G.value[()] AU2M = const.au.value GMSun = const.GM_sun.value MSun = const.M_sun.value diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py index 4fd797b76..672d762a3 100644 --- a/python/swiftest/swiftest/io.py +++ b/python/swiftest/swiftest/io.py @@ -181,6 +181,7 @@ def read_swiftest_param(param_file_name, param, verbose=True): for f in float_param: if f in param and type(f) is str: param[f] = real2float(param[f]) + for b in bool_param: if b in param: param[b] = str2bool(param[b]) @@ -427,7 +428,7 @@ def write_labeled_param(param, param_file_name): 'TU2S', 'DU2M', 'GMTINY', - 'FRAGMENTATION' + 'FRAGMENTATION', 'MIN_GMFRAG', 'RESTART'] ptmp = param.copy() diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index 9cb330862..c15da7ba9 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 @@ -57,7 +58,7 @@ def __init__(self,read_param: bool = True, **kwargs: Any): 1. Arguments to Simulation() 2. The parameter input file given by `param_file` under the following conditions: - `read_param` is set to True (default behavior). - - The file given by `param_file` exists. The default file is `param.in` located in the `.swiftest` directory + - The file given by `param_file` exists. The default file is `param.in` located in the `simdata` directory inside the current working directory, which can be changed by passing `param_file` as an argument. - The argument has an equivalent parameter or set of parameters in the parameter input file. 3. Default values (see below) @@ -314,7 +315,6 @@ def __init__(self,read_param: bool = True, **kwargs: Any): # Set the location of the parameter input file param_file = kwargs.pop("param_file",self.param_file) - read_param = kwargs.pop("read_param",False) self.set_parameter(verbose=False,param_file=param_file) #----------------------------------------------------------------- @@ -329,6 +329,7 @@ def __init__(self,read_param: bool = True, **kwargs: Any): # We will add the parameter file to the kwarg list. This will keep the set_parameter method from # overriding everything with defaults when there are no arguments passed to Simulation() kwargs['param_file'] = self.param_file + param_file_found = True else: param_file_found = False @@ -393,25 +394,30 @@ def run(self,**kwargs): f.write(f"#{self._shell_full} -l {os.linesep}") f.write(f"source ~/.{self._shell}rc {os.linesep}") f.write(f"cd {self.sim_dir} {os.linesep}") - f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)}") - - 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: - print(line.replace(']\n',']\r').replace("Normal termination","\n\nNormal termination"), end='') - res = p.communicate() - if p.returncode != 0: - for line in res[1]: - print(line, end='') + f.write(f"{str(self.driver_executable)} {self.integrator} {str(self.param_file)} {os.linesep}") + + 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"),end='') + else: + print(line, end='') + 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 + #except: + # warnings.warn(f"Error executing main swiftest_driver program",stacklevel=2) + # return # Read in new data self.bin2xr() @@ -665,7 +671,7 @@ def set_parameter(self, verbose: bool = True, **kwargs): default_arguments = { "codename" : "Swiftest", "integrator": "symba", - "param_file": Path.cwd() / ".swiftest" / "param.in", + "param_file": Path.cwd() / "simdata" / "param.in", "t0": 0.0, "tstart": 0.0, "tstop": None, @@ -2412,7 +2418,7 @@ def read_param(self, if param_file is None: param_file = self.param_file - if coename is None: + if codename is None: codename = self.codename if verbose is None: @@ -2422,7 +2428,7 @@ def read_param(self, return False if codename == "Swiftest": - self.param = io.read_swiftest_param(param_file, param, verbose=verbose) + self.param = io.read_swiftest_param(param_file, self.param, verbose=verbose) elif codename == "Swifter": self.param = io.read_swifter_param(param_file, verbose=verbose) elif codename == "Swift": diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d467332f8..fd0bf10c3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,7 @@ SET(FAST_MATH_FILES ${SRC}/helio/helio_step.f90 ${SRC}/helio/helio_util.f90 ${SRC}/io/io.f90 + ${SRC}/io/io_progress_bar.f90 ${SRC}/netcdf/netcdf.f90 ${SRC}/obl/obl.f90 ${SRC}/operators/operator_cross.f90 diff --git a/src/io/io.f90 b/src/io/io.f90 index 08ab7f868..2c74a42ee 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -12,77 +12,6 @@ contains - module subroutine io_pbar_reset(self, nloops) - !! 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 - ! Internals - character(len=2) :: numchar - character(len=5) :: barfmt - - if (.not.allocated(self%barstr)) then - allocate(character(self%PBARSIZE+4) :: self%barstr) - end if - write(numchar,'(I2)') self%PBARSIZE - self%fmt = '(A1,"[",A' // numchar // ',"]",$)' - barfmt = '(A' // numchar // ')' - write(self%barstr,barfmt) " " - self%nloops = nloops - self%spinner = 0 - - call self%update(0) - - return - end subroutine io_pbar_reset - - module subroutine io_pbar_update(self,i) - !! author: David A. Minton - !! - !! Updates the progress bar with new values and causes the "spinner" to flip. - implicit none - ! Arguments - class(progress_bar), intent(inout) :: self - integer(I8B), intent(in) :: i - ! Internals - integer(I4B) :: k - real(DP) :: frac - integer(I4B) :: pos !! The current integer position of the progress bar - - ! Compute the current position - frac = real(i,kind=DP) / real(self%nloops,kind=DP) - pos = 1 + min(int(ceiling(frac * self%PBARSIZE),kind=I4B),self%PBARSIZE) - - ! Fill in the bar character up to the current position - do k = 1, pos - self%barstr(k:k) = self%barchar - end do - - self%spinner = self%spinner + 1 - if (self%spinner > 4) self%spinner = 1 - select case(self%spinner) - case(1) - self%barstr(pos:pos) = "/" - case(2) - self%barstr(pos:pos) = "-" - case(3) - self%barstr(pos:pos) = "\" - case(4) - self%barstr(pos:pos) = "|" - end select - - write(*,fmt=self%fmt) char(13),self%barstr - - - return - end subroutine io_pbar_update - - - - module subroutine io_conservation_report(self, param, lterminal) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! diff --git a/src/io/io_progress_bar.f90 b/src/io/io_progress_bar.f90 new file mode 100644 index 000000000..9a49ff935 --- /dev/null +++ b/src/io/io_progress_bar.f90 @@ -0,0 +1,98 @@ +module io_progress_bar + !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott + !! + !! Definition of classes and methods used to determine close encounters + use swiftest_globals + use swiftest_classes + implicit none + public + + 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) :: loop_length !! The total number of loops that the progrees bar is executing + character(len=:), allocatable :: barstr !! The string that prints out as the progress bar + integer(I4B) :: bar_pos !! The current position of the progress bar + character(len=32) :: fmt !! The format string that is used to define the progress bar itself + 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 + end type progress_bar + +contains + + subroutine io_pbar_reset(self, loop_length) + !! author: David A. Minton + !! + !! Resets the progress bar to the beginning + implicit none + ! Arguments + 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 + ! Internals + character(len=2) :: numchar + integer(I4B) :: k + + if (.not.allocated(self%barstr)) then + allocate(character(self%PBARSIZE) :: self%barstr) + end if + do k = 1, self%PBARSIZE + self%barstr(k:k) = " " + end do + write(numchar,'(I2)') self%PBARSIZE + self%fmt = '(A1,"[",A' // numchar // ',"] ",A,$)' + self%loop_length = loop_length + self%bar_pos = 0 + self%message = "" + + write(*,fmt=self%fmt) char(13),self%barstr,trim(adjustl(self%message)) + + return + end subroutine io_pbar_reset + + + subroutine io_pbar_update(self,i,message) + !! author: David A. Minton + !! + !! Updates the progress bar with new values + implicit none + ! Arguments + class(progress_bar), intent(inout) :: self !! Progres bar object + integer(I8B), intent(in) :: i !! The current loop index of the progress loop + character(len=*), intent(in), optional :: message !! An optional message to display to the right of the progress bar + ! Internals + real(DP) :: frac + integer(I4B) :: bar_pos !! The current integer position of the progress bar + logical :: update = .false. + + ! Compute the current position + frac = real(i,kind=DP) / real(self%loop_length,kind=DP) + bar_pos = min(int(ceiling(frac * self%PBARSIZE),kind=I4B),self%PBARSIZE) + + if (bar_pos /= self%bar_pos) then + ! Fill in the bar character up to the current position + self%barstr(bar_pos:bar_pos) = barchar + update = .true. + self%bar_pos = bar_pos + end if + + if (present(message)) then + if (message /= self%message) then + update = .true. + self%message = message + end if + end if + + if (update) write(*,fmt=self%fmt) char(13),self%barstr,trim(adjustl(self%message)) + + + return + end subroutine io_pbar_update + + +end module io_progress_bar diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index 0eca02509..7b97eea43 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,9 +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) + 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() @@ -100,9 +104,9 @@ 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 - call pbar%update(iloop) if (istep_out > 0) then iout = iout - 1 if (iout == 0) then @@ -122,6 +126,8 @@ program swiftest_driver !call integration_timer%reset() iout = istep_out + write(pbarmessage,fmt=pbarfmt) t, tstop + call pbar%update(1,message=pbarmessage) end if end if diff --git a/src/modules/swiftest.f90 b/src/modules/swiftest.f90 index 6f84c66b9..edc41f134 100644 --- a/src/modules/swiftest.f90 +++ b/src/modules/swiftest.f90 @@ -23,6 +23,7 @@ module swiftest use lambda_function use walltime_classes use encounter_classes + use io_progress_bar !use advisor_annotate !$ use omp_lib implicit none diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 49735a424..6bbcb537b 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -414,20 +414,6 @@ module swiftest_classes generic :: read_particle_info => read_particle_info_bin, read_particle_info_netcdf !! Genereric method call for reading in the particle information metadata end type swiftest_nbody_system - 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 - 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 - character(len=32) :: fmt !! The format string that is used to define the progress bar itself - 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. - end type progress_bar abstract interface @@ -597,18 +583,6 @@ pure module subroutine gr_vh2pv_body(self, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine gr_vh2pv_body - module subroutine io_pbar_reset(self, nloops) - implicit none - class(progress_bar),intent(inout) :: self - integer(I8B), intent(in) :: nloops - end subroutine io_pbar_reset - - module subroutine io_pbar_update(self,i) - implicit none - class(progress_bar), intent(inout) :: self - integer(I8B), intent(in) :: i - end subroutine io_pbar_update - module subroutine io_conservation_report(self, param, lterminal) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object