Skip to content
This repository was archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Fixed problems identifiying the correct idslot to store bodies in the…
Browse files Browse the repository at this point in the history
… various NetCDF files.
  • Loading branch information
daminton committed Jan 16, 2023
1 parent c989d03 commit 3508e3a
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 60 deletions.
6 changes: 3 additions & 3 deletions examples/Fragmentation/Fragmentation_Movie.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,8 @@ def encounter_combiner(sim):
ds = xr.combine_nested([data,enc],concat_dim='time').sortby("time").interpolate_na(dim="time")

# Interpolate in time to make a smooth, constant time step dataset
smooth_time = np.linspace(start=tgood.isel(time=0), stop=ds.time[-1], num=num_movie_frames)
# Add a bit of padding to the time, otherwise there are some issues with the interpolation in the last few frames.
smooth_time = np.linspace(start=tgood.isel(time=0), stop=ds.time[-1], num=int(1.2*num_movie_frames))
ds = ds.interp(time=smooth_time)

return ds
Expand All @@ -154,7 +155,6 @@ class AnimatedScatter(object):
def __init__(self, sim, animfile, title, style, nskip=1):

self.ds = encounter_combiner(sim)
nframes = int(self.ds['time'].size)
self.sim = sim
self.title = title
self.body_color_list = {'Initial conditions': 'xkcd:windows blue',
Expand All @@ -168,7 +168,7 @@ def __init__(self, sim, animfile, title, style, nskip=1):
self.fig, self.ax = self.setup_plot()

# Then setup FuncAnimation.
self.ani = animation.FuncAnimation(self.fig, self.update_plot, interval=1, frames=range(0,nframes,nskip), blit=True)
self.ani = animation.FuncAnimation(self.fig, self.update_plot, interval=1, frames=range(0,num_movie_frames,nskip), blit=True)
self.ani.save(animfile, fps=60, dpi=300, extra_args=['-vcodec', 'libx264'])
print(f"Finished writing {animfile}")

Expand Down
5 changes: 4 additions & 1 deletion src/collision/collision_io.f90
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,11 @@ module subroutine collision_io_netcdf_write_frame_snapshot(self, history, param)
allocate(pl, source=after%pl)
end select
npl = pl%nbody

! This ensures that there first idslot will have the first body in it, not id 0 which is the default for a new idvals array
if (.not.allocated(nc%idvals)) allocate(nc%idvals, source=pl%id)
do i = 1, npl
idslot = findloc(history%idvals,pl%id(i),dim=1)
call nc%find_idslot(pl%id(i), idslot)
call netcdf_io_check( nf90_put_var(nc%id, nc%id_varid, pl%id(i), start=[ idslot ]), "collision_io_netcdf_write_frame_snapshot nf90_put_var id_varid" )
charstring = trim(adjustl(pl%info(i)%name))
call netcdf_io_check( nf90_put_var(nc%id, nc%name_varid, charstring, start=[1, idslot ], count=[NAMELEN, 1]), "collision_io_netcdf_write_frame_snapshot nf90_put_var name_varid" )
Expand Down
7 changes: 5 additions & 2 deletions src/encounter/encounter_io.f90
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,10 @@ module subroutine encounter_io_netcdf_write_frame_snapshot(self, history, param)
call netcdf_io_check( nf90_put_var(nc%id, nc%time_varid, self%t, start=[tslot]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var time_varid" )

npl = pl%nbody
! This ensures that there first idslot will have the first body in it, not id 0 which is the default for a new idvals array
if (.not.allocated(nc%idvals)) allocate(nc%idvals, source=pl%id)
do i = 1, npl
idslot = findloc(history%idvals,pl%id(i),dim=1)
call nc%find_idslot(pl%id(i), idslot)
call netcdf_io_check( nf90_put_var(nc%id, nc%id_varid, pl%id(i), start=[idslot]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var pl id_varid" )
call netcdf_io_check( nf90_put_var(nc%id, nc%rh_varid, pl%rh(:,i), start=[1,idslot,tslot], count=[NDIM,1,1]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var pl rh_varid" )
call netcdf_io_check( nf90_put_var(nc%id, nc%vh_varid, pl%vh(:,i), start=[1,idslot,tslot], count=[NDIM,1,1]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var pl vh_varid" )
Expand All @@ -269,8 +271,9 @@ module subroutine encounter_io_netcdf_write_frame_snapshot(self, history, param)
end do

ntp = tp%nbody
if (.not.allocated(nc%idvals)) allocate(nc%idvals, source=tp%id)
do i = 1, ntp
idslot = findloc(history%idvals,tp%id(i),dim=1)
call nc%find_idslot(tp%id(i), idslot)
call netcdf_io_check( nf90_put_var(nc%id, nc%id_varid, tp%id(i), start=[idslot]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var tp id_varid" )
call netcdf_io_check( nf90_put_var(nc%id, nc%rh_varid, tp%rh(:,i), start=[1,idslot,tslot], count=[NDIM,1,1]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var tp rh_varid" )
call netcdf_io_check( nf90_put_var(nc%id, nc%vh_varid, tp%vh(:,i), start=[1,idslot,tslot], count=[NDIM,1,1]), "encounter_io_netcdf_write_frame_snapshot nf90_put_var tp vh_varid" )
Expand Down
2 changes: 1 addition & 1 deletion src/encounter/encounter_util.f90
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ module subroutine encounter_util_get_vals_storage(self, idvals, tvals)

allocate(idvals(ntotal))
nlo = 1
! Second pass to store all ids get all of the ids stored
! Second pass to get all of the ids stored
do i = 1, nsnaps
if (allocated(self%frame(i)%item)) then
select type(snapshot => self%frame(i)%item)
Expand Down
52 changes: 44 additions & 8 deletions src/netcdf_io/netcdf_io_implementations.f90
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module subroutine netcdf_io_close(self)
end subroutine netcdf_io_close


module subroutine netcdf_io_find_tslot(self, t)
module subroutine netcdf_io_find_tslot(self, t, tslot)
!! 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.
Expand All @@ -56,12 +56,13 @@ module subroutine netcdf_io_find_tslot(self, t)
! 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
integer(I4B), intent(out) :: tslot !! The index of the time slot where this data belongs
! Internals
real(DP), dimension(:), allocatable :: tvals

self%tslot = 0

if (.not.self%lfile_is_open) return
tslot = 0

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
Expand All @@ -72,19 +73,54 @@ module subroutine netcdf_io_find_tslot(self, t)
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)
tslot = findloc(tvals, t, dim=1)
if (tslot == 0) tslot = self%max_tslot + 1
self%max_tslot = max(self%max_tslot, tslot)
self%tslot = tslot

return
end subroutine netcdf_io_find_tslot


module subroutine netcdf_io_get_idvals(self)
module subroutine netcdf_io_find_idslot(self, id, idslot)
!! author: David A. Minton
!!
!! Given an open NetCDF file and a value of id, finds the index of the id value (aka the id slot) to place a new set of data.
!! The returned value of idslot will correspond to the first index value where the value of id is equal to a saved id value. If none are found, it is the next available index.
!! The returned value of idslot will correspond to the first index value where the value of id is greater than or equal to the saved id value.
implicit none
! Arguments
class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset
integer(I4B), intent(in) :: id !! The value of id to search for
integer(I4B), intent(out) :: idslot !! The index of the id slot where this data belongs
! Internals
integer(I4B), dimension(:), allocatable :: idvals

if (.not.self%lfile_is_open) return

if (.not.allocated(self%idvals)) call self%get_idvals()
self%max_idslot = size(self%idvals)
idslot = findloc(self%idvals, id, dim=1)
if (idslot == 0) then
self%max_idslot = self%max_idslot + 1
idslot = self%max_idslot

! Update the idvals array
allocate(idvals(idslot))
idvals(1:idslot-1) = self%idvals(1:idslot-1)
idvals(idslot) = id
call move_alloc(idvals, self%idvals)
end if

self%idslot = idslot

return
end subroutine netcdf_io_find_idslot


module subroutine netcdf_io_get_idvals(self)
!! author: David A. Minton
!!
!! Gets a full list of id values
implicit none
! Arguments
class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset
Expand All @@ -99,7 +135,7 @@ module subroutine netcdf_io_get_idvals(self)
call netcdf_io_check( nf90_get_var(self%id, self%id_varid, self%idvals(:), start=[1]), "netcdf_io_find_idslot get_var" )
else
allocate(self%idvals(1))
self%idvals(1) = -huge(1)
self%idvals(1) = 0
end if

return
Expand Down
20 changes: 15 additions & 5 deletions src/netcdf_io/netcdf_io_module.f90
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ module netcdf_io
integer(I4B) :: tslot = 1 !! The current time slot that gets passed to the NetCDF reader/writer
integer(I4B) :: max_tslot = 0 !! Records the last index value of time in the NetCDF file
integer(I4B), dimension(:), allocatable :: idvals !! Array of id values in this NetCDF file
integer(I4B) :: idslot = 1 !! The current id slot that gets passed to the NetCDF reader/writer
integer(I4B) :: max_idslot = 0 !! Records the last index value of id in the NetCDF file

! Dimension ids and variable names
Expand Down Expand Up @@ -142,10 +143,11 @@ 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 :: find_tslot => netcdf_io_find_tslot !! Finds the time dimension index for a given value of t
procedure :: get_idvals => netcdf_io_get_idvals !! Gets the valid id numbers currently stored in this dataset
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 :: find_idslot => netcdf_io_find_idslot !! Finds the id dimension index for a given value of id
procedure :: get_idvals => netcdf_io_get_idvals !! Gets the valid id numbers currently stored in this dataset
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
Expand All @@ -165,11 +167,19 @@ module subroutine netcdf_io_get_idvals(self)
class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset
end subroutine netcdf_io_get_idvals

module subroutine netcdf_io_find_tslot(self, t)
module subroutine netcdf_io_find_tslot(self, t, tslot)
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
integer(I4B), intent(out) :: tslot !! The index of the time slot where this data belongs
end subroutine netcdf_io_find_tslot

module subroutine netcdf_io_find_idslot(self, id, idslot)
implicit none
class(netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset
integer(I4B), intent(in) :: id !! The value of id to search for
integer(I4B), intent(out) :: idslot !! The index of the id slot where this data belongs
end subroutine netcdf_io_find_idslot

module subroutine netcdf_io_sync(self)
implicit none
Expand Down
Loading

0 comments on commit 3508e3a

Please sign in to comment.