From cd9a02042adaf027a639be5a21b84fd498f50c67 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 5 Jan 2023 15:16:01 -0500 Subject: [PATCH] Consolidated encounters into a single NetCDF file --- python/swiftest/swiftest/simulation_class.py | 19 ++--- src/collision/collision_module.f90 | 4 +- src/encounter/encounter_io.f90 | 76 ++++++++++++++++++-- src/encounter/encounter_module.f90 | 10 ++- src/swiftest/swiftest_util.f90 | 6 +- 5 files changed, 91 insertions(+), 24 deletions(-) diff --git a/python/swiftest/swiftest/simulation_class.py b/python/swiftest/swiftest/simulation_class.py index ad5e8eb0f..6adba385c 100644 --- a/python/swiftest/swiftest/simulation_class.py +++ b/python/swiftest/swiftest/simulation_class.py @@ -2753,22 +2753,13 @@ def read_output_file(self,read_init_cond : bool = True): return def read_encounter(self): - enc_files = glob(f"{self.simdir}{os.path.sep}encounter_*.nc") - if len(enc_files) == 0: - return - - if self.verbose: - print("Reading encounter history file as .encounters") - - enc_files.sort() + enc_file = self.simdir / "encounters.nc" + if not os.path.exists(enc_file): + return - # This is needed in order to pass the param argument down to the io.process_netcdf_input function - def _preprocess(ds, param): - return io.process_netcdf_input(ds,param) - partial_func = partial(_preprocess, param=self.param) + self.collisions = xr.open_dataset(enc_file) + self.collisions = io.process_netcdf_input(self.collisions, self.param) - self.encounters = xr.open_mfdataset(enc_files,parallel=True,combine="nested",concat_dim="time",join="left",preprocess=partial_func,mask_and_scale=True) - self.encounters = io.process_netcdf_input(self.encounters, self.param) # Remove any overlapping time values tgood,tid = np.unique(self.encounters.time,return_index=True) self.encounters = self.encounters.isel(time=tid) diff --git a/src/collision/collision_module.f90 b/src/collision/collision_module.f90 index 73e7b4243..50e2bb75a 100644 --- a/src/collision/collision_module.f90 +++ b/src/collision/collision_module.f90 @@ -18,8 +18,8 @@ module collision implicit none public - character(len=*), parameter :: COLLISION_OUTFILE = 'collision.nc' !! Name of NetCDF output file for collision information - character(len=*), parameter :: COLLISION_LOG_OUT = "collision.log" !! Name of log file for collision diagnostic information + character(len=*), parameter :: COLLISION_OUTFILE = 'collisions.nc' !! Name of NetCDF output file for collision information + character(len=*), parameter :: COLLISION_LOG_OUT = "collisions.log" !! Name of log file for collision diagnostic information !>Symbolic names for collisional outcomes from collresolve_resolve: integer(I4B), parameter :: COLLRESOLVE_REGIME_MERGE = 1 diff --git a/src/encounter/encounter_io.f90 b/src/encounter/encounter_io.f90 index cba31cfb8..45d2d2174 100644 --- a/src/encounter/encounter_io.f90 +++ b/src/encounter/encounter_io.f90 @@ -26,13 +26,8 @@ module subroutine encounter_io_netcdf_dump(self, param) class is (encounter_netcdf_parameters) if (self%iframe > 0) then ! Create and save the output files for this encounter and fragmentation - nc%file_number = nc%file_number + 1 call self%make_index_map() - nc%time_dimsize = self%nt - nc%name_dimsize = self%nid - write(nc%file_name, '("encounter_",I0.6,".nc")') nc%file_number - call nc%initialize(param) - + call nc%open(param) do i = 1, self%iframe if (allocated(self%frame(i)%item)) then select type(snapshot => self%frame(i)%item) @@ -153,6 +148,75 @@ module subroutine encounter_io_netcdf_initialize_output(self, param) end subroutine encounter_io_netcdf_initialize_output + module subroutine encounter_io_netcdf_open(self, param, readonly) + !! author: Carlisle A. Wishard, Dana Singh, and David A. Minton + !! + !! Opens a NetCDF file and does the variable inquiries to activate variable ids + use netcdf + implicit none + ! Arguments + class(encounter_netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset + class(base_parameters), intent(in) :: param !! Current run configuration parameters + logical, optional, intent(in) :: readonly !! Logical flag indicating that this should be open read only + ! Internals + integer(I4B) :: mode + character(len=STRMAX) :: errmsg + logical fileExists + + mode = NF90_WRITE + if (present(readonly)) then + if (readonly) mode = NF90_NOWRITE + end if + + select type(param) + class is (base_parameters) + associate(nc => self) + + inquire(file=nc%file_name, exist=fileExists) + if (.not.fileExists) then + call nc%initialize(param) + return + end if + + write(errmsg,*) "encounter_io_netcdf_opennf90_open ",trim(adjustl(nc%file_name)) + call netcdf_io_check( nf90_open(nc%file_name, mode, nc%id), errmsg) + self%lfile_is_open = .true. + + ! Dimensions + call netcdf_io_check( nf90_inq_dimid(nc%id, nc%time_dimname, nc%time_dimid), "encounter_io_netcdf_opennf90_inq_dimid time_dimid" ) + call netcdf_io_check( nf90_inq_dimid(nc%id, nc%space_dimname, nc%space_dimid), "encounter_io_netcdf_opennf90_inq_dimid space_dimid" ) + call netcdf_io_check( nf90_inq_dimid(nc%id, nc%name_dimname, nc%name_dimid), "encounter_io_netcdf_opennf90_inq_dimid name_dimid" ) + call netcdf_io_check( nf90_inq_dimid(nc%id, nc%str_dimname, nc%str_dimid), "encounter_io_netcdf_opennf90_inq_dimid str_dimid" ) + + ! Dimension coordinates + call netcdf_io_check( nf90_inq_varid(nc%id, nc%time_dimname, nc%time_varid), "encounter_io_netcdf_opennf90_inq_varid time_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%space_dimname, nc%space_varid), "encounter_io_netcdf_opennf90_inq_varid space_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%name_dimname, nc%name_varid), "encounter_io_netcdf_opennf90_inq_varid name_varid" ) + + ! Required Variables + call netcdf_io_check( nf90_inq_varid(nc%id, nc%id_varname, nc%id_varid), "encounter_io_netcdf_opennf90_inq_varid name_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%ptype_varname, nc%ptype_varid), "encounter_io_netcdf_opennf90_inq_varid ptype_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%time_dimname, nc%time_varid), "encounter_io_netcdf_opennf90_inq_varid time_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%rh_varname, nc%rh_varid), "encounter_io_netcdf_opennf90_inq_varid rh_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%vh_varname, nc%vh_varid), "encounter_io_netcdf_opennf90_inq_varid vh_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%Gmass_varname, nc%Gmass_varid), "encounter_io_netcdf_opennf90_inq_varid Gmass_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%loop_varname, nc%loop_varid), "encounter_io_netcdf_opennf90_inq_varid loop_varid" ) + if (param%lclose) then + call netcdf_io_check( nf90_inq_varid(nc%id, nc%radius_varname, nc%radius_varid), "encounter_io_netcdf_opennf90_inq_varid radius_varid" ) + end if + + if (param%lrotation) then + call netcdf_io_check( nf90_inq_varid(nc%id, nc%Ip_varname, nc%Ip_varid), "encounter_io_netcdf_opennf90_inq_varid Ip_varid" ) + call netcdf_io_check( nf90_inq_varid(nc%id, nc%rot_varname, nc%rot_varid), "encounter_io_netcdf_opennf90_inq_varid rot_varid" ) + end if + + end associate + end select + + return + end subroutine encounter_io_netcdf_open + + module subroutine encounter_io_netcdf_write_frame_snapshot(self, history, param) !! author: David A. Minton !! diff --git a/src/encounter/encounter_module.f90 b/src/encounter/encounter_module.f90 index 32ff67d25..a343715f1 100644 --- a/src/encounter/encounter_module.f90 +++ b/src/encounter/encounter_module.f90 @@ -18,6 +18,7 @@ module encounter public integer(I4B), parameter :: SWEEPDIM = 3 + character(len=*), parameter :: ENCOUNTER_OUTFILE = 'encounters.nc' !! Name of NetCDF output file for encounter information type, abstract :: encounter_list integer(I8B) :: nenc = 0 !! Total number of encounters @@ -67,6 +68,7 @@ module encounter integer(I4B) :: file_number = 1 !! The number to append on the output file contains procedure :: initialize => encounter_io_netcdf_initialize_output !! Initialize a set of parameters used to identify a NetCDF output object + procedure :: open => encounter_io_netcdf_open !! Open an encounter NetCDF file final :: encounter_final_netcdf_parameters !! Finalizer will close the NetCDF file end type encounter_netcdf_parameters @@ -229,6 +231,13 @@ module subroutine encounter_io_netcdf_initialize_output(self, param) class(base_parameters), intent(in) :: param end subroutine encounter_io_netcdf_initialize_output + module subroutine encounter_io_netcdf_open(self, param, readonly) + implicit none + class(encounter_netcdf_parameters), intent(inout) :: self !! Parameters used to identify a particular NetCDF dataset + class(base_parameters), intent(in) :: param !! Current run configuration parameters + logical, optional, intent(in) :: readonly !! Logical flag indicating that this should be open read only + end subroutine encounter_io_netcdf_open + module subroutine encounter_io_netcdf_write_frame_snapshot(self, history, param) implicit none class(encounter_snapshot), intent(in) :: self !! Swiftest encounter structure @@ -272,7 +281,6 @@ module subroutine encounter_util_dealloc_list(self) class(encounter_list), intent(inout) :: self !! Swiftest encounter list object end subroutine encounter_util_dealloc_list - module subroutine encounter_util_get_idvalues_snapshot(self, idvals) implicit none class(encounter_snapshot), intent(in) :: self !! Encounter snapshot object diff --git a/src/swiftest/swiftest_util.f90 b/src/swiftest/swiftest_util.f90 index 667ad1627..8b73f05ae 100644 --- a/src/swiftest/swiftest_util.f90 +++ b/src/swiftest/swiftest_util.f90 @@ -2608,7 +2608,11 @@ module subroutine swiftest_util_setup_construct_system(nbody_system, param) call encounter_history%reset() select type(nc => encounter_history%nc) class is (encounter_netcdf_parameters) - nc%file_number = param%iloop / param%dump_cadence + nc%file_name = ENCOUNTER_OUTFILE + if (.not.param%lrestart) then + call nc%initialize(param) + call nc%close() + end if end select allocate(nbody_system%encounter_history, source=encounter_history) end if