diff --git a/src/netcdf_io/netcdf_io_implementations.f90 b/src/netcdf_io/netcdf_io_implementations.f90 index 17f957a98..f917058f1 100644 --- a/src/netcdf_io/netcdf_io_implementations.f90 +++ b/src/netcdf_io/netcdf_io_implementations.f90 @@ -15,7 +15,6 @@ module subroutine netcdf_io_check(status, call_identifier) !! author: Carlisle A. Wishard, Dana Singh, and David A. Minton !! !! Checks the status of all NetCDF operations to catch errors - use netcdf implicit none ! Arguments integer, intent (in) :: status !! The status code returned by a NetCDF function @@ -35,7 +34,6 @@ module subroutine netcdf_io_close(self) !! author: Carlisle A. Wishard, Dana Singh, and David A. Minton !! !! Closes a NetCDF file - use netcdf implicit none ! Arguments class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset @@ -49,12 +47,44 @@ module subroutine netcdf_io_close(self) end subroutine netcdf_io_close + + module subroutine netcdf_io_find_tslot(self, t) + !! author: David A. Minton + !! + !! Given an open NetCDF file and a value of time t, finds the index of the time value (aka the time slot) to place a new set of data. + !! The returned value of tslot will correspond to the first index value where the value of t is greater than or equal to the saved time value. + implicit none + ! Arguments + class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset + real(DP), intent(in) :: t !! The value of time to search for + ! Internals + real(DP), dimension(:), allocatable :: tvals + + self%tslot = 0 + + if (.not.self%lfile_is_open) return + + call netcdf_io_check( nf90_inquire_dimension(self%id, self%time_dimid, self%time_dimname, len=self%max_tslot), "netcdf_io_find_tslot nf90_inquire_dimension max_tslot" ) + if (self%max_tslot > 0) then + allocate(tvals(self%max_tslot)) + call netcdf_io_check( nf90_get_var(self%id, self%time_varid, tvals(:), start=[1]), "netcdf_io_find_tslot get_var" ) + else + allocate(tvals(1)) + tvals(1) = -huge(1.0_DP) + end if + + self%tslot = findloc(tvals, t, dim=1) + if (self%tslot == 0) self%tslot = self%max_tslot + 1 + self%max_tslot = max(self%max_tslot, self%tslot) + + return + end subroutine netcdf_io_find_tslot + module subroutine netcdf_io_sync(self) !! author: David A. Minton !! !! Syncrhonize the disk and memory buffer of the NetCDF file (e.g. commit the frame files stored in memory to disk) !! - use netcdf implicit none ! Arguments class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset diff --git a/src/netcdf_io/netcdf_io_module.f90 b/src/netcdf_io/netcdf_io_module.f90 index 3adb7b1a5..74325f809 100644 --- a/src/netcdf_io/netcdf_io_module.f90 +++ b/src/netcdf_io/netcdf_io_module.f90 @@ -138,8 +138,9 @@ module netcdf_io integer(I4B) :: discard_body_id_varid !! ID for the id of the other body involved in the discard logical :: lpseudo_vel_exists = .false. !! Logical flag to indicate whether or not the pseudovelocity vectors were present in an old file. contains - procedure :: close => netcdf_io_close !! Closes an open NetCDF file - procedure :: sync => netcdf_io_sync !! Syncrhonize the disk and memory buffer of the NetCDF file (e.g. commit the frame files stored in memory to disk) + procedure :: close => netcdf_io_close !! Closes an open NetCDF file + procedure :: find_tslot => netcdf_io_find_tslot !! Finds the time dimension index for a given value of t + procedure :: sync => netcdf_io_sync !! Syncrhonize the disk and memory buffer of the NetCDF file (e.g. commit the frame files stored in memory to disk) end type netcdf_parameters interface @@ -153,6 +154,12 @@ module subroutine netcdf_io_close(self) implicit none class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset end subroutine netcdf_io_close + + module subroutine netcdf_io_find_tslot(self, t) + implicit none + class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset + real(DP), intent(in) :: t !! The value of time to search for + end subroutine netcdf_io_find_tslot module subroutine netcdf_io_sync(self) implicit none diff --git a/src/swiftest/swiftest_driver.f90 b/src/swiftest/swiftest_driver.f90 index 1a74a9573..d4ed0cc9a 100644 --- a/src/swiftest/swiftest_driver.f90 +++ b/src/swiftest/swiftest_driver.f90 @@ -63,6 +63,8 @@ program swiftest_driver nloops = ceiling((tstop - t0) / dt, kind=I8B) istart = ceiling((tstart - t0) / dt + 1.0_DP, kind=I8B) iloop = istart - 1 + iout = 0 + idump = 0 ! Set up nbody_system storage for intermittent file dumps if (dump_cadence == 0) dump_cadence = ceiling(nloops / (1.0_DP * istep_out), kind=I8B) @@ -104,9 +106,7 @@ program swiftest_driver call nbody_system%compact_output(param,integration_timer) end if - iout = 0 - idump = 0 - nbody_system%t = tstart + do iloop = istart, nloops !> Step the nbody_system forward in time call integration_timer%start() diff --git a/src/swiftest/swiftest_io.f90 b/src/swiftest/swiftest_io.f90 index 4587e8552..a9a9a873d 100644 --- a/src/swiftest/swiftest_io.f90 +++ b/src/swiftest/swiftest_io.f90 @@ -278,27 +278,16 @@ module subroutine swiftest_io_dump_storage(self, param) class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i - real(DP), dimension(:), allocatable :: tvals if (self%iframe == 0) return call self%make_index_map() associate(nc => param%system_history%nc) call nc%open(param) - ! Get the current time values in the file if this is an old file - if (nc%max_tslot > 0) then - allocate(tvals(nc%max_tslot)) - call netcdf_io_check( nf90_get_var(nc%id, nc%time_varid, tvals(:), start=[1]), "swiftest_io_dump_storage time_varid" ) - else - allocate(tvals(1)) - tvals(1) = -huge(1.0_DP) - end if + do i = 1, self%iframe if (allocated(self%frame(i)%item)) then select type(nbody_system => self%frame(i)%item) class is (swiftest_nbody_system) - nc%tslot = findloc(tvals, nbody_system%t, dim=1) - if (nc%tslot == 0) nc%tslot = nc%max_tslot + 1 - nc%max_tslot = max(nc%max_tslot, nc%tslot) call nbody_system%write_frame(param) end select deallocate(self%frame(i)%item) @@ -907,6 +896,7 @@ module function swiftest_io_netcdf_read_frame_system(self, nc, param) result(ier call nc%open(param, readonly=.true.) + call nc%find_tslot(self%t) call self%read_hdr(nc, param) associate(cb => self%cb, pl => self%pl, tp => self%tp, npl => self%pl%nbody, ntp => self%tp%nbody, tslot => nc%tslot) @@ -1585,10 +1575,11 @@ module subroutine swiftest_io_netcdf_write_frame_system(self, nc, param) !! Write a frame (header plus records for each massive body and active test particle) to a output binary file implicit none ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody_system object + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody_system object class(swiftest_netcdf_parameters), intent(inout) :: nc !! Parameters used to for writing a NetCDF dataset to file - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + call nc%find_tslot(self%t) call self%write_hdr(nc, param) call self%cb%write_frame(nc, param) call self%pl%write_frame(nc, param) diff --git a/src/swiftest/swiftest_util.f90 b/src/swiftest/swiftest_util.f90 index da750e956..ebe9e8c87 100644 --- a/src/swiftest/swiftest_util.f90 +++ b/src/swiftest/swiftest_util.f90 @@ -2645,6 +2645,8 @@ module subroutine swiftest_util_setup_construct_system(nbody_system, param) end select call nbody_system%collider%setup(nbody_system) + nbody_system%t = param%tstart + return end subroutine swiftest_util_setup_construct_system