From a83690cd75a73f2e689a5937eb94ab171860b30f Mon Sep 17 00:00:00 2001 From: David A Minton Date: Sat, 10 Dec 2022 21:08:06 -0500 Subject: [PATCH] Started working on a more efficient way to store ids --- src/CMakeLists.txt | 1 + src/encounter/encounter_io.f90 | 2 +- src/encounter/encounter_util.f90 | 32 ++++++++++++++++++++++++- src/modules/swiftest_classes.f90 | 7 ++++++ src/symba/symba_util.f90 | 2 ++ src/util/util_reset.f90 | 2 ++ src/util/util_unique.f90 | 41 ++++++++++++++++++++++++++++++++ 7 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 src/util/util_unique.f90 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 344a2e7d8..6f382cd8e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -88,6 +88,7 @@ SET(FAST_MATH_FILES ${SRC}/util/util_solve.f90 ${SRC}/util/util_sort.f90 ${SRC}/util/util_spill.f90 + ${SRC}/util/util_unique.f90 ${SRC}/util/util_valid.f90 ${SRC}/util/util_version.f90 ${SRC}/walltime/walltime.f90 diff --git a/src/encounter/encounter_io.f90 b/src/encounter/encounter_io.f90 index 414c3854a..c5e458e57 100644 --- a/src/encounter/encounter_io.f90 +++ b/src/encounter/encounter_io.f90 @@ -50,6 +50,7 @@ module subroutine encounter_io_dump_storage(self, param) ! Internals integer(I4B) :: i + call self%mapid() do i = 1, self%nframes if (allocated(self%frame(i)%item)) then select type(snapshot => self%frame(i)%item) @@ -62,7 +63,6 @@ module subroutine encounter_io_dump_storage(self, param) end if end do - return end subroutine encounter_io_dump_storage diff --git a/src/encounter/encounter_util.f90 b/src/encounter/encounter_util.f90 index 7d5094ede..9385ad2c0 100644 --- a/src/encounter/encounter_util.f90 +++ b/src/encounter/encounter_util.f90 @@ -183,11 +183,41 @@ end subroutine encounter_util_final_storage module subroutine encounter_util_index_map_storage(self) !! author: David A. Minton !! - !! Maps body id values to storage index values so we don't have to use unlimited dimensions for id + !! Maps body id values to storage index values so we don't have to use unlimited dimensions for id. + !! Basically this will make a unique list of ids that exist in all of the saved snapshots implicit none ! Arguments class(encounter_storage(*)), intent(inout) :: self !! Swiftest storage object ! Internals + integer(I4B) :: i, n, nold + integer(I4B), dimension(:), allocatable :: idlist + + if (self%nid == 0) return + allocate(idlist(self%nid)) + + n = 0 + nold = 1 + do i = 1, self%nframes + if (allocated(self%frame(i)%item)) then + select type(snapshot => self%frame(i)%item) + class is (encounter_snapshot) + if (allocated(snapshot%pl)) then + n = n + snapshot%pl%nbody + idlist(nold:n) = snapshot%pl%id(:) + nold = n+1 + end if + if (allocated(snapshot%tp)) then + n = n + snapshot%tp%nbody + idlist(nold:n) = snapshot%tp%id(:) + nold = n+1 + end if + end select + else + exit + end if + end do + + call util_unique(idlist,self%idmap) return end subroutine encounter_util_index_map_storage diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 8624f8ece..6fb35383e 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -159,6 +159,7 @@ module swiftest_classes integer(I4B), dimension(nframes) :: tslot !! The value of the time dimension index associated with each frame real(DP), dimension(nframes) :: tvals !! Stored time values for snapshots integer(I4B), dimension(:), allocatable :: idmap !! The id value -> index map + integer(I4B) :: nid !! Number of unique id values in all saved snapshots contains procedure :: dump => io_dump_storage !! Dumps storage object contents to file procedure :: mapid => util_index_map_storage !! Maps body id values to storage index values so we don't have to use unlimited dimensions for id @@ -1956,6 +1957,12 @@ module subroutine util_spill_tp(self, discards, lspill_list, ldestructive) logical, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not end subroutine util_spill_tp + module subroutine util_unique(input_array, output_array) + implicit none + integer(I4B), dimension(:), intent(in) :: input_array + integer(I4B), dimension(:), allocatable, intent(out) :: output_array + end subroutine util_unique + module subroutine util_valid_id_system(self, param) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nbody system object diff --git a/src/symba/symba_util.f90 b/src/symba/symba_util.f90 index 60c3311c4..f7711e6bf 100644 --- a/src/symba/symba_util.f90 +++ b/src/symba/symba_util.f90 @@ -1380,6 +1380,7 @@ module subroutine symba_util_take_collision_snapshot(self, param, t, stage) return end subroutine symba_util_take_collision_snapshot + module subroutine symba_util_take_encounter_snapshot(self, param, t) !! author: David A. Minton !! @@ -1477,6 +1478,7 @@ module subroutine symba_util_take_encounter_snapshot(self, param, t) end select ! Save the snapshot + self%encounter_history%nid = self%encounter_history%nid + ntp_snap + npl_snap call symba_util_save_encounter(self,snapshot,t) end select end select diff --git a/src/util/util_reset.f90 b/src/util/util_reset.f90 index 7bb8d5ee3..a588c65fe 100644 --- a/src/util/util_reset.f90 +++ b/src/util/util_reset.f90 @@ -27,6 +27,8 @@ module subroutine util_reset_storage(self) self%tslot(:) = 0 self%tvals(:) = huge(1.0_DP) self%iframe = 0 + if (allocated(self%idmap)) deallocate(self%idmap) + self%nid = 0 return end subroutine util_reset_storage diff --git a/src/util/util_unique.f90 b/src/util/util_unique.f90 new file mode 100644 index 000000000..9cf77536c --- /dev/null +++ b/src/util/util_unique.f90 @@ -0,0 +1,41 @@ +!! Copyright 2022 - David Minton, Carlisle Wishard, Jennifer Pouplin, Jake Elliott, & Dana Singh +!! This file is part of Swiftest. +!! Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License +!! as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. +!! Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty +!! of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. +!! You should have received a copy of the GNU General Public License along with Swiftest. +!! If not, see: https://www.gnu.org/licenses. + +submodule (swiftest_classes) s_util_unique + use swiftest +contains + + module subroutine util_unique(input_array, output_array) + !! author: David A. Minton + !! + !! Takes an input unsorted integer array and returns a new array of sorted, unique values + implicit none + ! Arguments + integer(I4B), dimension(:), intent(in) :: input_array + integer(I4B), dimension(:), allocatable, intent(out) :: output_array + ! Internals + integer(I4B), dimension(:), allocatable :: unique_array + integer(I4B) :: n, lo, hi + + allocate(unique_array, mold=input_array) + lo = minval(input_array) - 1 + hi = maxval(input_array) + + n = 0 + do while (lo < hi) + n = n + 1 + lo = minval(input_array, mask=input_array > lo) + unique_array(n) = lo + enddo + allocate(output_array(n), source=unique_array(1:n)) + + return + end subroutine util_unique + +end submodule s_util_unique \ No newline at end of file