From 5a9a0782dcc71e4107323db1630bdeb810e2432b Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 13 Jul 2021 23:16:03 -0400 Subject: [PATCH 01/33] Started putting in symba step interpolator --- src/symba/symba_step.f90 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index b04caa74e..14a82cc4e 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -37,11 +37,35 @@ end subroutine symba_step_system module subroutine symba_step_interp_system(self, param, t, dt) implicit none + ! Arguments class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP) :: dth + dth = 0.5_DP * dt + select type(pl => self%pl) + class is (symba_pl) + select type(tp => self%tp) + class is (symba_tp) + call pl%vh2vb(cb) + call pl%lindrift(cb, dth, lbeg=.true.) + if (tp%nbody > 0) then + call tp%vh2vb(vbcb = -cb%ptbeg) + call tp%lindrift(cb, dth, lbeg=.true.) + call pl%set_beg_end(xbeg = pl%xh) + end if + call pl%accel(system, param, t) + call tp%accel(system, param, t, lbeg=.true.) + call pl%kick(dth) + call tp%kick(dth) + call pl%drift(system, param, dt) + call tp%drift(system, param, dt + + end select + end select return end subroutine symba_step_interp_system end submodule s_symba_step From c49e3180d5299a496b9144ef7543ceb50e9263f3 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Wed, 14 Jul 2021 22:03:18 -0400 Subject: [PATCH 02/33] Added io routine from other branch so I can develop here and it won't break running scripts --- python/swiftest/swiftest/io.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py index ceab9a74f..caf1c0e39 100644 --- a/python/swiftest/swiftest/io.py +++ b/python/swiftest/swiftest/io.py @@ -466,7 +466,8 @@ def swiftest_stream(f, param): npl = f.read_ints() ntp = f.read_ints() iout_form = f.read_reals('c') - cbid = f.read_ints() + #cbid = f.read_ints() + cbid = np.array([0]) Mcb = f.read_reals(np.float64) Rcb = f.read_reals(np.float64) J2cb = f.read_reals(np.float64) From ae0a82e902f7c118d39e874bbc60da98bc30a43f Mon Sep 17 00:00:00 2001 From: David A Minton Date: Wed, 14 Jul 2021 22:57:01 -0400 Subject: [PATCH 03/33] Fleshed out symba_step_interp and started adding symba_step_recur --- src/modules/symba_classes.f90 | 28 ++++++++---- src/symba/symba_step.f90 | 85 +++++++++++++++++++++++++++-------- 2 files changed, 85 insertions(+), 28 deletions(-) diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 5b712c9de..fd477da40 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -140,9 +140,11 @@ module symba_classes class(symba_pl), allocatable :: pl_discards !! Discarded test particle data structure contains private - procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps - procedure, public :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step - procedure, public :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system + procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps + procedure, public :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step + procedure, public :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system + procedure, public :: recursive_step => symba_step_recur_system !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current + !! recursion level, if applicable, and descend to the next deeper level if necessarye end type symba_nbody_system interface @@ -246,6 +248,12 @@ module subroutine symba_setup_system(self, param) class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine symba_setup_system + module subroutine symba_setup_tp(self,n) + implicit none + class(symba_tp), intent(inout) :: self !! SyMBA test particle object + integer(I4B), intent(in) :: n !! Number of test particles to allocate + end subroutine symba_setup_tp + module subroutine symba_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none @@ -255,12 +263,6 @@ module subroutine symba_step_system(self, param, t, dt) real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_system - module subroutine symba_setup_tp(self,n) - implicit none - class(symba_tp), intent(inout) :: self !! SyMBA test particle object - integer(I4B), intent(in) :: n !! Number of test particles to allocate - end subroutine symba_setup_tp - module subroutine symba_step_interp_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none @@ -269,5 +271,13 @@ module subroutine symba_step_interp_system(self, param, t, dt) real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_interp_system + + module recursive subroutine symba_step_recur_system(self, param, t, dt) + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + end subroutine symba_step_recur_system end interface end module symba_classes \ No newline at end of file diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index 14a82cc4e..e0709a7f8 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -36,36 +36,83 @@ module subroutine symba_step_system(self, param, t, dt) end subroutine symba_step_system module subroutine symba_step_interp_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step planets and active test particles ahead in democratic heliocentric coordinates, calling the recursive + !! subroutine to descend to the appropriate level to handle close encounters + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step_interp.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_interp.f implicit none ! Arguments - class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth + integer(I4B) :: irec dth = 0.5_DP * dt - select type(pl => self%pl) - class is (symba_pl) - select type(tp => self%tp) - class is (symba_tp) - call pl%vh2vb(cb) - call pl%lindrift(cb, dth, lbeg=.true.) - if (tp%nbody > 0) then - call tp%vh2vb(vbcb = -cb%ptbeg) - call tp%lindrift(cb, dth, lbeg=.true.) - call pl%set_beg_end(xbeg = pl%xh) - end if - call pl%accel(system, param, t) - call tp%accel(system, param, t, lbeg=.true.) - call pl%kick(dth) - call tp%kick(dth) - call pl%drift(system, param, dt) - call tp%drift(system, param, dt + associate(system => self) + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + select type(cb => system%cb) + class is (symba_cb) + call pl%vh2vb(cb) + call pl%lindrift(cb, dth, lbeg=.true.) + call tp%vh2vb(vbcb = -cb%ptbeg) + call tp%lindrift(cb, dth, lbeg=.true.) + + call pl%set_beg_end(xbeg = pl%xh) + call pl%accel(system, param, t) + call tp%accel(system, param, t, lbeg=.true.) + + call pl%kick(dth) + call tp%kick(dth) + + irec = -1 + call pl%drift(system, param, dt) + call tp%drift(system, param, dt) + irec = 0 + call system%recursive_step(param, t, dt) + + call pl%set_beg_end(xend = pl%xh) + call pl%accel(system, param, t + dt) + call tp%accel(system, param, t + dt, lbeg=.false.) + + call pl%kick(dth) + call tp%kick(dth) + + call pl%vh2vb(cb) + call pl%lindrift(cb, dth, lbeg=.false.) + call tp%vh2vb(vbcb = -cb%ptend) + call tp%lindrift(cb, dth, lbeg=.false.) + end select + end select end select - end select + end associate return end subroutine symba_step_interp_system + + module recursive subroutine symba_step_recur_system(self, param, t, dt) + !! author: David A. Minton + !! + !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current + !! recursion level, if applicable, and descend to the next deeper level if necessarys + !! + !! Adapted from David E. Kaufmann's Swifter routine: symba_step_recur.f90 + !! Adapted from Hal Levison's Swift routine symba5_step_recur.f + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + end subroutine symba_step_recur_system + end submodule s_symba_step From f2eea054395fa9b9c18e9a839cc47d7cbacafc02 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Wed, 14 Jul 2021 22:59:05 -0400 Subject: [PATCH 04/33] Moved irec to be internal component of the system object --- src/modules/symba_classes.f90 | 1 + src/symba/symba_step.f90 | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index fd477da40..306153379 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -138,6 +138,7 @@ module symba_classes class(symba_pltpenc), allocatable :: pltpenc_list !! List of massive body-test particle encounters in a single step class(symba_plplenc), allocatable :: plplenc_list !! List of massive body-massive body encounters in a single step class(symba_pl), allocatable :: pl_discards !! Discarded test particle data structure + integer(I4B) :: irec !! Recursion level contains private procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index e0709a7f8..3e14686ac 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -51,7 +51,6 @@ module subroutine symba_step_interp_system(self, param, t, dt) real(DP), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth - integer(I4B) :: irec dth = 0.5_DP * dt associate(system => self) @@ -73,10 +72,10 @@ module subroutine symba_step_interp_system(self, param, t, dt) call pl%kick(dth) call tp%kick(dth) - irec = -1 + system%irec = -1 call pl%drift(system, param, dt) call tp%drift(system, param, dt) - irec = 0 + system%irec = 0 call system%recursive_step(param, t, dt) From 84d22ea39c9b4abf7a8a94587ed8c612fd2e037e Mon Sep 17 00:00:00 2001 From: David Minton Date: Wed, 21 Jul 2021 15:30:26 -0400 Subject: [PATCH 05/33] Grabbed the bug fix to the parameter file dump method from the OOPrestructure branch --- src/io/io.f90 | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/io/io.f90 b/src/io/io.f90 index 2bb46ae0e..e74255466 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -429,14 +429,14 @@ module subroutine io_dump_system(self, param, msg) !! so that if a dump file gets corrupted during writing, the user can restart from the older one. implicit none ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - character(*), optional, intent(in) :: msg !! Message to display with dump operation + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + character(*), optional, intent(in) :: msg !! Message to display with dump operation ! Internals - class(swiftest_parameters), allocatable :: dump_param !! Local parameters variable used to parameters change input file names - !! to dump file-specific values without changing the user-defined values - integer(I4B), save :: idx = 1 !! Index of current dump file. Output flips between 2 files for extra security - !! in case the program halts during writing + class(swiftest_parameters), allocatable :: dump_param !! Local parameters variable used to parameters change input file names + !! to dump file-specific values without changing the user-defined values + integer(I4B), save :: idx = 1 !! Index of current dump file. Output flips between 2 files for extra security + !! in case the program halts during writing character(len=:), allocatable :: param_file_name real(DP) :: tfrac @@ -447,6 +447,7 @@ module subroutine io_dump_system(self, param, msg) dump_param%intpfile = trim(adjustl(DUMP_TP_FILE(idx))) dump_param%out_form = XV dump_param%out_stat = 'APPEND' + dump_param%T0 = param%t call dump_param%dump(param_file_name) call self%cb%dump(dump_param) From 9ace669f465e235b9d89829fea6eceec632e9930 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 10:40:32 -0400 Subject: [PATCH 06/33] Setting up rhill approximate and started putting interfaces back onto the operator implementations --- src/operators/operator_cross.f90 | 8 ++++++-- src/util/util_set.f90 | 25 +++++++++++++++++++++++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/operators/operator_cross.f90 b/src/operators/operator_cross.f90 index d6fd82944..235294a3e 100644 --- a/src/operators/operator_cross.f90 +++ b/src/operators/operator_cross.f90 @@ -120,8 +120,12 @@ return end procedure operator_cross_el_i4b - module procedure operator_cross_el_i8b + module pure function operator_cross_el_i8b(A, B) result(C) implicit none + ! Arguments + integer(I8B), dimension(:,:), intent(in) :: A, B + integer(I8B), dimension(:,:), allocatable :: C + ! Internals integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -131,6 +135,6 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_i8b + end function operator_cross_el_i8b end submodule operator_cross_implementation \ No newline at end of file diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 index b690f37b2..edc6a1bb5 100644 --- a/src/util/util_set.f90 +++ b/src/util/util_set.f90 @@ -72,8 +72,9 @@ module subroutine util_set_rhill(self,cb) !! !! Sets the value of the Hill's radius implicit none - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object - class(swiftest_cb), intent(inout) :: cb !! Swiftest massive body object + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object if (self%nbody > 0) then call self%xv2el(cb) @@ -83,6 +84,26 @@ module subroutine util_set_rhill(self,cb) return end subroutine util_set_rhill + + module subroutine util_set_approximate_rhill(self,cb) + !! author: David A. Minton + !! + !! Sets the approximate value of the Hill's radius using the heliocentric radius instead of computing the semimajor axis + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals + real(DP) :: rh + + if (self%nbody > 0) then + call self%xv2el(cb) + self%rhill(:) = self%a(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD + end if + + return + end subroutine util_set_approximate_rhill + module subroutine util_set_ir3h(self) !! author: David A. Minton !! From 23239eead8fddb5f2f0c2806d9e92dbc86ca2236 Mon Sep 17 00:00:00 2001 From: David Minton Date: Thu, 22 Jul 2021 11:17:25 -0400 Subject: [PATCH 07/33] Added explicit interfaces to cross product operators and defined the approximate rhill procedure --- src/modules/swiftest_classes.f90 | 10 ++++- src/operators/operator_cross.f90 | 74 ++++++++++++++++++++------------ src/util/util_set.f90 | 56 +++++++++++++----------- 3 files changed, 85 insertions(+), 55 deletions(-) diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 13ee255cc..db9e72b0d 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -21,7 +21,7 @@ module swiftest_classes public :: user_getacch_body public :: util_coord_b2h_pl, util_coord_b2h_tp, util_coord_h2b_pl, util_coord_h2b_tp, util_exit, util_fill_body, util_fill_pl, util_fill_tp, & util_index, util_peri_tp, util_reverse_status, util_set_beg_end_pl, util_set_ir3h, util_set_msys, util_set_mu_pl, & - util_set_mu_tp, util_set_rhill, util_sort, util_spill_body, util_spill_pl, util_spill_tp, util_valid, util_version + util_set_mu_tp, util_set_rhill, util_set_rhill_approximate, util_sort, util_spill_body, util_spill_pl, util_spill_tp, util_valid, util_version !******************************************************************************************************************************** ! swiftest_parameters class definitions @@ -806,8 +806,14 @@ end subroutine util_set_mu_tp module subroutine util_set_rhill(self,cb) implicit none class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object - class(swiftest_cb), intent(inout) :: cb !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object end subroutine util_set_rhill + + module subroutine util_set_rhill_approximate(self,cb) + implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine util_set_rhill_approximate end interface interface util_sort diff --git a/src/operators/operator_cross.f90 b/src/operators/operator_cross.f90 index 235294a3e..1efce2359 100644 --- a/src/operators/operator_cross.f90 +++ b/src/operators/operator_cross.f90 @@ -1,4 +1,4 @@ -submodule(swiftest_operators) operator_cross_implementation +submodule(swiftest_operators) s_operator_cross use swiftest !! author: David A. Minton !! @@ -7,56 +7,70 @@ !! Vector list implementations: C(1:3, :) = A(1:3, :) .cross. B(1:3, :) contains - module procedure operator_cross_sp + module pure function operator_cross_sp(A, B) result(C) implicit none + real(SP), dimension(:), intent(in) :: A, B + real(SP), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_sp + end function operator_cross_sp - module procedure operator_cross_dp + module pure function operator_cross_dp(A, B) result(C) implicit none + real(DP), dimension(:), intent(in) :: A, B + real(DP), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_dp + end function operator_cross_dp - module procedure operator_cross_i1b + module pure function operator_cross_i1b(A, B) result(C) implicit none + integer(I1B), dimension(:), intent(in) :: A, B + integer(I1B), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_i1b + end function operator_cross_i1b - module procedure operator_cross_i2b + module pure function operator_cross_i2b(A, B) result(C) implicit none + integer(I2B), dimension(:), intent(in) :: A, B + integer(I2B), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_i2b + end function operator_cross_i2b - module procedure operator_cross_i4b + module pure function operator_cross_i4b(A, B) result(C) implicit none + integer(I4B), dimension(:), intent(in) :: A, B + integer(I4B), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_i4b + end function operator_cross_i4b - module procedure operator_cross_i8b + module pure function operator_cross_i8b(A, B) result(C) implicit none + integer(I8B), dimension(:), intent(in) :: A, B + integer(I8B), dimension(3) :: C C(1) = A(2) * B(3) - A(3) * B(2) C(2) = A(3) * B(1) - A(1) * B(3) C(3) = A(1) * B(2) - A(2) * B(1) return - end procedure operator_cross_i8b + end function operator_cross_i8b - module procedure operator_cross_el_sp + module pure function operator_cross_el_sp(A, B) result(C) implicit none + real(SP), dimension(:,:), intent(in) :: A, B + real(SP), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -66,10 +80,12 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_sp + end function operator_cross_el_sp - module procedure operator_cross_el_dp + module pure function operator_cross_el_dp(A, B) result(C) implicit none + real(DP), dimension(:,:), intent(in) :: A, B + real(DP), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -79,10 +95,12 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_dp + end function operator_cross_el_dp - module procedure operator_cross_el_i1b - implicit none + module pure function operator_cross_el_i1b(A, B) result(C) + implicit none + integer(I1B), dimension(:,:), intent(in) :: A, B + integer(I1B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -92,10 +110,12 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_i1b + end function operator_cross_el_i1b - module procedure operator_cross_el_i2b + module pure function operator_cross_el_i2b(A, B) result(C) implicit none + integer(I2B), dimension(:,:), intent(in) :: A, B + integer(I2B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -105,10 +125,12 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_i2b + end function operator_cross_el_i2b - module procedure operator_cross_el_i4b + module pure function operator_cross_el_i4b(A, B) result(C) implicit none + integer(I4B), dimension(:,:), intent(in) :: A, B + integer(I4B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -118,14 +140,12 @@ C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) end do return - end procedure operator_cross_el_i4b + end function operator_cross_el_i4b module pure function operator_cross_el_i8b(A, B) result(C) implicit none - ! Arguments integer(I8B), dimension(:,:), intent(in) :: A, B integer(I8B), dimension(:,:), allocatable :: C - ! Internals integer(I4B) :: i, n n = size(A, 2) allocate(C, mold = A) @@ -137,4 +157,4 @@ module pure function operator_cross_el_i8b(A, B) result(C) return end function operator_cross_el_i8b -end submodule operator_cross_implementation \ No newline at end of file +end submodule s_operator_cross \ No newline at end of file diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 index edc6a1bb5..dbaae3ea3 100644 --- a/src/util/util_set.f90 +++ b/src/util/util_set.f90 @@ -30,12 +30,37 @@ module subroutine util_set_beg_end_pl(self, xbeg, xend, vbeg) end subroutine util_set_beg_end_pl + module subroutine util_set_ir3h(self) + !! author: David A. Minton + !! + !! Sets the inverse heliocentric radius term (1/rh**3) for all bodies in a structure + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + ! Internals + integer(I4B) :: i + real(DP) :: r2, irh + + if (self%nbody > 0) then + + do i = 1, self%nbody + r2 = dot_product(self%xh(:, i), self%xh(:, i)) + irh = 1.0_DP / sqrt(r2) + self%ir3h(i) = irh / r2 + end do + end if + + return + end subroutine util_set_ir3h + module subroutine util_set_msys(self) !! author: David A. Minton !! !! Sets the value of msys and the vector mass quantities based on the total mass of the system implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system objec + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest nobdy system object + self%msys = self%cb%mass + sum(self%pl%mass(1:self%pl%nbody)) return @@ -46,11 +71,11 @@ module subroutine util_set_mu_pl(self, cb) !! !! Computes G * (M + m) for each massive body implicit none + ! Arguments class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object if (self%nbody > 0) self%mu(:) = cb%Gmass + self%Gmass(:) - return end subroutine util_set_mu_pl @@ -59,6 +84,7 @@ module subroutine util_set_mu_tp(self, cb) !! !! Converts certain scalar values to arrays so that they can be used in elemental functions implicit none + ! Arguments class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object @@ -84,8 +110,7 @@ module subroutine util_set_rhill(self,cb) return end subroutine util_set_rhill - - module subroutine util_set_approximate_rhill(self,cb) + module subroutine util_set_rhill_approximate(self,cb) !! author: David A. Minton !! !! Sets the approximate value of the Hill's radius using the heliocentric radius instead of computing the semimajor axis @@ -102,27 +127,6 @@ module subroutine util_set_approximate_rhill(self,cb) end if return - end subroutine util_set_approximate_rhill + end subroutine util_set_rhill_approximate - module subroutine util_set_ir3h(self) - !! author: David A. Minton - !! - !! Sets the inverse heliocentric radius term (1/rh**3) for all bodies in a structure - implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest generic body object - - integer(I4B) :: i - real(DP) :: r2, irh - - if (self%nbody > 0) then - - do i = 1, self%nbody - r2 = dot_product(self%xh(:, i), self%xh(:, i)) - irh = 1.0_DP / sqrt(r2) - self%ir3h(i) = irh / r2 - end do - end if - - return - end subroutine util_set_ir3h end submodule s_util_set \ No newline at end of file From 3a5d874b61b2e18c97a23f4f6a7e7f0e3ceb6019 Mon Sep 17 00:00:00 2001 From: David Minton Date: Thu, 22 Jul 2021 11:38:49 -0400 Subject: [PATCH 08/33] Added mag operator --- src/modules/swiftest_operators.f90 | 54 ++++++++++++++++++++++++ src/operators/operator_cross.f90 | 32 ++++++++++++++ src/operators/operator_mag.f90 | 68 ++++++++++++++++++++++++++++++ src/util/util_set.f90 | 5 ++- 4 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 src/operators/operator_mag.f90 diff --git a/src/modules/swiftest_operators.f90 b/src/modules/swiftest_operators.f90 index b5b4ce078..2c982f09c 100644 --- a/src/modules/swiftest_operators.f90 +++ b/src/modules/swiftest_operators.f90 @@ -26,6 +26,12 @@ module pure function operator_cross_dp(A, B) result(C) real(DP), dimension(3) :: C end function operator_cross_dp + module pure function operator_cross_qp(A, B) result(C) + implicit none + real(QP), dimension(:), intent(in) :: A, B + real(QP), dimension(3) :: C + end function operator_cross_qp + module pure function operator_cross_i1b(A, B) result(C) implicit none integer(I1B), dimension(:), intent(in) :: A, B @@ -62,6 +68,12 @@ module pure function operator_cross_el_dp(A, B) result(C) real(DP), dimension(:,:), allocatable :: C end function operator_cross_el_dp + module pure function operator_cross_el_qp(A, B) result(C) + implicit none + real(QP), dimension(:,:), intent(in) :: A, B + real(QP), dimension(:,:), allocatable :: C + end function operator_cross_el_qp + module pure function operator_cross_el_i1b(A, B) result(C) implicit none integer(I1B), dimension(:,:), intent(in) :: A, B @@ -87,4 +99,46 @@ module pure function operator_cross_el_i8b(A, B) result(C) end function operator_cross_el_i8b end interface + !******************************************************************************************************************************** + ! Interfaces for .mag. operator + !******************************************************************************************************************************** + + interface operator(.mag.) + module pure function operator_mag_sp(A) result(B) + implicit none + real(SP), dimension(:), intent(in) :: A + real(SP) :: B + end function operator_mag_sp + + module pure function operator_mag_dp(A) result(B) + implicit none + real(DP), dimension(:), intent(in) :: A + real(DP) :: B + end function operator_mag_dp + + module pure function operator_mag_qp(A) result(B) + implicit none + real(QP), dimension(:), intent(in) :: A + real(QP) :: B + end function operator_mag_qp + + module pure function operator_mag_el_sp(A) result(B) + implicit none + real(SP), dimension(:,:), intent(in) :: A + real(SP), dimension(:), allocatable :: B + end function operator_mag_el_sp + + module pure function operator_mag_el_dp(A) result(B) + implicit none + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), allocatable :: B + end function operator_mag_el_dp + + module pure function operator_mag_el_qp(A) result(B) + implicit none + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), allocatable :: B + end function operator_mag_el_qp + end interface + end module swiftest_operators diff --git a/src/operators/operator_cross.f90 b/src/operators/operator_cross.f90 index 1efce2359..736dc2696 100644 --- a/src/operators/operator_cross.f90 +++ b/src/operators/operator_cross.f90 @@ -27,6 +27,16 @@ module pure function operator_cross_dp(A, B) result(C) return end function operator_cross_dp + module pure function operator_cross_qp(A, B) result(C) + implicit none + real(QP), dimension(:), intent(in) :: A, B + real(QP), dimension(3) :: C + C(1) = A(2) * B(3) - A(3) * B(2) + C(2) = A(3) * B(1) - A(1) * B(3) + C(3) = A(1) * B(2) - A(2) * B(1) + return + end function operator_cross_qp + module pure function operator_cross_i1b(A, B) result(C) implicit none integer(I1B), dimension(:), intent(in) :: A, B @@ -73,6 +83,7 @@ module pure function operator_cross_el_sp(A, B) result(C) real(SP), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) @@ -88,6 +99,7 @@ module pure function operator_cross_el_dp(A, B) result(C) real(DP), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) @@ -97,12 +109,29 @@ module pure function operator_cross_el_dp(A, B) result(C) return end function operator_cross_el_dp + module pure function operator_cross_el_qp(A, B) result(C) + implicit none + real(QP), dimension(:,:), intent(in) :: A, B + real(QP), dimension(:,:), allocatable :: C + integer(I4B) :: i, n + n = size(A, 2) + if (allocated(C)) deallocate(C) + allocate(C, mold = A) + do concurrent (i = 1:n) + C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) + C(2, i) = A(3, i) * B(1, i) - A(1, i) * B(3, i) + C(3, i) = A(1, i) * B(2, i) - A(2, i) * B(1, i) + end do + return + end function operator_cross_el_qp + module pure function operator_cross_el_i1b(A, B) result(C) implicit none integer(I1B), dimension(:,:), intent(in) :: A, B integer(I1B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) @@ -118,6 +147,7 @@ module pure function operator_cross_el_i2b(A, B) result(C) integer(I2B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) @@ -133,6 +163,7 @@ module pure function operator_cross_el_i4b(A, B) result(C) integer(I4B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) @@ -148,6 +179,7 @@ module pure function operator_cross_el_i8b(A, B) result(C) integer(I8B), dimension(:,:), allocatable :: C integer(I4B) :: i, n n = size(A, 2) + if (allocated(C)) deallocate(C) allocate(C, mold = A) do concurrent (i = 1:n) C(1, i) = A(2, i) * B(3, i) - A(3, i) * B(2, i) diff --git a/src/operators/operator_mag.f90 b/src/operators/operator_mag.f90 new file mode 100644 index 000000000..5a054d5ce --- /dev/null +++ b/src/operators/operator_mag.f90 @@ -0,0 +1,68 @@ +submodule(swiftest_operators) s_operator_mag + !! author: David A. Minton + !! + !! Contains implementations for the .mag. operator for all defined real types + !! Single vector implementations: B = .mag. A(1:3) + !! Vector list implementations: B(:) = .mag. A(1:3, :) + contains + + module pure function operator_mag_sp(A) result(B) + implicit none + real(SP), dimension(:), intent(in) :: A + real(SP) :: B + B = norm2(A(:)) + return + end function operator_mag_sp + + module pure function operator_mag_dp(A) result(B) + implicit none + real(DP), dimension(:), intent(in) :: A + real(DP) :: B + B = norm2(A(:)) + return + end function operator_mag_dp + + module pure function operator_mag_el_sp(A) result(B) + implicit none + real(SP), dimension(:,:), intent(in) :: A + real(SP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_sp + + module pure function operator_mag_el_dp(A) result(B) + implicit none + real(DP), dimension(:,:), intent(in) :: A + real(DP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_dp + + module pure function operator_mag_el_qp(A) result(B) + implicit none + real(QP), dimension(:,:), intent(in) :: A + real(QP), dimension(:), allocatable :: B + integer(I4B) :: i,n + n = size(A, 2) + if (allocated(B)) deallocate(B) + allocate(B(n)) + do concurrent (i=1:n) + B(i) = norm2(A(:, i)) + end do + return + end function operator_mag_el_qp + +end submodule s_operator_mag + diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 index dbaae3ea3..7442d1517 100644 --- a/src/util/util_set.f90 +++ b/src/util/util_set.f90 @@ -119,10 +119,11 @@ module subroutine util_set_rhill_approximate(self,cb) class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object ! Internals - real(DP) :: rh + real(DP), dimension(:), allocatable :: rh if (self%nbody > 0) then - call self%xv2el(cb) + allocate(rh, mold=self%rhill) + self%rhill(:) = self%a(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD end if From 4ea98628b70ab454302e48e9b3141f8d838484f1 Mon Sep 17 00:00:00 2001 From: David Minton Date: Thu, 22 Jul 2021 11:40:23 -0400 Subject: [PATCH 09/33] Use the mag operator for the approximate rhill calculation --- src/util/util_set.f90 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 index 7442d1517..7a082648a 100644 --- a/src/util/util_set.f90 +++ b/src/util/util_set.f90 @@ -122,9 +122,8 @@ module subroutine util_set_rhill_approximate(self,cb) real(DP), dimension(:), allocatable :: rh if (self%nbody > 0) then - allocate(rh, mold=self%rhill) - - self%rhill(:) = self%a(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD + rh(:) = .mag. self%xh(:,:) + self%rhill(:) = rh():) * (self%Gmass(:) / cb%Gmass / 3)**THIRD end if return From ba010184dbeac865ec1da9920c20fa94f43ec5c5 Mon Sep 17 00:00:00 2001 From: David Minton Date: Thu, 22 Jul 2021 11:40:46 -0400 Subject: [PATCH 10/33] Fixed typo --- src/util/util_set.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/util_set.f90 b/src/util/util_set.f90 index 7a082648a..2c52c86df 100644 --- a/src/util/util_set.f90 +++ b/src/util/util_set.f90 @@ -123,7 +123,7 @@ module subroutine util_set_rhill_approximate(self,cb) if (self%nbody > 0) then rh(:) = .mag. self%xh(:,:) - self%rhill(:) = rh():) * (self%Gmass(:) / cb%Gmass / 3)**THIRD + self%rhill(:) = rh(:) * (self%Gmass(:) / cb%Gmass / 3)**THIRD end if return From 72c31ff999144f2f9f866b5e2abb3e54d6e95a4f Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 13:53:14 -0400 Subject: [PATCH 11/33] Updated formatting and changed the definition of VSMALL to use pre-defined epsilon --- src/modules/swiftest_globals.f90 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/modules/swiftest_globals.f90 b/src/modules/swiftest_globals.f90 index 256c4124b..a1f0d7511 100644 --- a/src/modules/swiftest_globals.f90 +++ b/src/modules/swiftest_globals.f90 @@ -100,10 +100,10 @@ module swiftest_globals !> Standard file names integer(I4B), parameter :: NDUMPFILES = 2 - character(*), dimension(2), parameter :: DUMP_CB_FILE = (/ 'dump_cb1.bin', 'dump_cb2.bin' /) - character(*), dimension(2), parameter :: DUMP_PL_FILE = (/ 'dump_pl1.bin', 'dump_pl2.bin' /) - character(*), dimension(2), parameter :: DUMP_TP_FILE = (/ 'dump_tp1.bin', 'dump_tp2.bin' /) - character(*), dimension(2), parameter :: DUMP_PARAM_FILE = (/ 'dump_param1.dat', 'dump_param2.dat' /) + character(*), dimension(2), parameter :: DUMP_CB_FILE = ['dump_cb1.bin', 'dump_cb2.bin' ] + character(*), dimension(2), parameter :: DUMP_PL_FILE = ['dump_pl1.bin', 'dump_pl2.bin' ] + character(*), dimension(2), parameter :: DUMP_TP_FILE = ['dump_tp1.bin', 'dump_tp2.bin' ] + character(*), dimension(2), parameter :: DUMP_PARAM_FILE = ['dump_param1.dat', 'dump_param2.dat'] !> Default file names that can be changed by the user in the parameters file character(*), parameter :: ENC_OUTFILE = 'encounter.out' @@ -116,11 +116,11 @@ module swiftest_globals integer(I4B), parameter :: BINUNIT = 20 !! File unit number for the binary output file !> Miscellaneous constants: - integer(I4B), parameter :: NDIM = 3 !! Number of dimensions in our reality - integer(I4B), parameter :: NDIM2 = 2 * NDIM !! 2x the number of dimensions - real(DP), parameter :: VSMALL = 4.0E-15_DP + integer(I4B), parameter :: NDIM = 3 !! Number of dimensions in our reality + integer(I4B), parameter :: NDIM2 = 2 * NDIM !! 2x the number of dimensions + real(DP), parameter :: VSMALL = 2 * epsilon(1._DP) !! Very small number used to prevent floating underflow - real(DP), parameter :: GC = 6.6743E-11_DP !! Universal gravitational constant in SI units + real(DP), parameter :: GC = 6.6743E-11_DP !! Universal gravitational constant in SI units real(DP), parameter :: einsteinC = 299792458.0_DP !! Speed of light in SI units end module swiftest_globals From b91f7ea0b1bbce268c292574804fe61a1e0659f7 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 14:21:05 -0400 Subject: [PATCH 12/33] Moved drift routine to be a Swiftest body method that WHM overrides. Fixed up some formatting and comments --- src/drift/drift.f90 | 52 ++++++++++++++++++++++++++++++++ src/modules/swiftest_classes.f90 | 37 ++++++++++++++--------- src/modules/whm_classes.f90 | 26 +++++----------- src/whm/whm_drift.f90 | 52 +------------------------------- 4 files changed, 84 insertions(+), 83 deletions(-) diff --git a/src/drift/drift.f90 b/src/drift/drift.f90 index 8bba1a273..2ddb03500 100644 --- a/src/drift/drift.f90 +++ b/src/drift/drift.f90 @@ -9,6 +9,57 @@ integer(I2B), parameter :: NLAG2 = 40 contains + + module subroutine drift_body(self, system, param, dt) + !! author: David A. Minton + !! + !! Loop bodies and call Danby drift routine on the heliocentric position and velocities. + !! + !! Adapted from Hal Levison's Swift routine drift_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_drift_tp.f90 + implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + ! Internals + integer(I4B) :: i + real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation + integer(I4B), dimension(:), allocatable :: iflag + real(DP), dimension(:), allocatable :: dtp + + associate(n => self%nbody) + if (n == 0) return + allocate(iflag(n)) + iflag(:) = 0 + allocate(dtp(n)) + if (param%lgr) then + do i = 1, n + rmag = norm2(self%xh(:, i)) + vmag2 = dot_product(self%vh(:, i), self%vh(:, i)) + energy = 0.5_DP * vmag2 - self%mu(i) / rmag + dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) + end do + else + dtp(:) = dt + end if + do concurrent(i = 1:n, self%status(i) == ACTIVE) + call drift_one(self%mu(i), self%xh(1,i), self%xh(2,i), self%xh(3,i), & + self%vh(1,i), self%vh(2,i), self%vh(3,i), & + dtp(i), iflag(i)) + end do + if (any(iflag(1:n) /= 0)) then + where(iflag(1:n) /= 0) self%status(1:n) = DISCARDED_DRIFTERR + do i = 1, n + if (iflag(i) /= 0) write(*, *) "Particle ", self%id(i), " lost due to error in Danby drift" + end do + end if + end associate + + return + end subroutine drift_body + module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! @@ -406,4 +457,5 @@ pure subroutine drift_kepu_stumpff(x, c0, c1, c2, c3) return end subroutine drift_kepu_stumpff + end submodule drift_implementation diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index db9e72b0d..e924d2546 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -7,7 +7,7 @@ module swiftest_classes implicit none private public :: discard_pl, discard_system, discard_tp - public :: drift_one + public :: drift_body, drift_one public :: eucl_dist_index_plpl, eucl_dist_index_pltp, eucl_irij3_plpl public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & @@ -173,6 +173,7 @@ module swiftest_classes procedure(abstract_step_body), public, deferred :: step procedure(abstract_accel), public, deferred :: accel ! These are concrete because the implementation is the same for all types of particles + procedure, public :: drift => drift_body !! Loop through bodies and call Danby drift routine on heliocentric variables procedure, public :: v2pv => gr_vh2pv_body !! Converts from velocity to psudeovelocity for GR calculations using symplectic integrators procedure, public :: pv2v => gr_pv2vh_body !! Converts from psudeovelocity to velocity for GR calculations using symplectic integrators procedure, public :: initialize => io_read_body_in !! Read in body initial conditions from a file @@ -247,16 +248,16 @@ module swiftest_classes private ! Test particle-specific concrete methods ! These are concrete because they are the same implemenation for all integrators - procedure, public :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies - procedure, public :: eucl_index => eucl_dist_index_pltp !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix - procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body - procedure, public :: setup => setup_tp !! A base constructor that sets the number of bodies and - procedure, public :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass - procedure, public :: h2b => util_coord_h2b_tp !! Convert test particles from heliocentric to barycentric coordinates (position and velocity) - procedure, public :: b2h => util_coord_b2h_tp !! Convert test particles from barycentric to heliocentric coordinates (position and velocity) - procedure, public :: fill => util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) - procedure, public :: get_peri => util_peri_tp !! Determine system pericenter passages for test particles - procedure, public :: spill => util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure, public :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies + procedure, public :: eucl_index => eucl_dist_index_pltp !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix + procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body + procedure, public :: setup => setup_tp !! A base constructor that sets the number of bodies and + procedure, public :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass + procedure, public :: h2b => util_coord_h2b_tp !! Convert test particles from heliocentric to barycentric coordinates (position and velocity) + procedure, public :: b2h => util_coord_b2h_tp !! Convert test particles from barycentric to heliocentric coordinates (position and velocity) + procedure, public :: fill => util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) + procedure, public :: get_peri => util_peri_tp !! Determine system pericenter passages for test particles + procedure, public :: spill => util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) end type swiftest_tp !******************************************************************************************************************************** @@ -309,7 +310,7 @@ subroutine abstract_accel(self, system, param, t, lbeg) import swiftest_body, swiftest_nbody_system, swiftest_parameters, DP class(swiftest_body), intent(inout) :: self !! Swiftest body data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step end subroutine abstract_accel @@ -383,6 +384,14 @@ module subroutine discard_tp(self, system, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_tp + module subroutine drift_body(self, system, param, dt) + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + end subroutine drift_body + module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) implicit none real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body to drift @@ -434,7 +443,7 @@ end subroutine gr_pseudovel2vel module pure subroutine gr_pv2vh_body(self, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine gr_pv2vh_body module pure subroutine gr_vel2pseudovel(param, mu, xh, vh, pv) @@ -449,7 +458,7 @@ end subroutine gr_vel2pseudovel module pure subroutine gr_vh2pv_body(self, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine gr_vh2pv_body module subroutine io_dump_param(self, param_file_name) diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index 6107a719d..21811cf38 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -33,7 +33,7 @@ module whm_classes procedure, public :: h2j => whm_coord_h2j_pl !! Convert position and velcoity vectors from heliocentric to Jacobi coordinates procedure, public :: j2h => whm_coord_j2h_pl !! Convert position and velcoity vectors from Jacobi to helliocentric coordinates procedure, public :: vh2vj => whm_coord_vh2vj_pl !! Convert velocity vectors from heliocentric to Jacobi coordinates - procedure, public :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine + procedure, public :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine to jacobi coordinates procedure, public :: fill => whm_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: accel => whm_getacch_pl !! Compute heliocentric accelerations of massive bodies procedure, public :: accel_gr => whm_gr_getacch_pl !! Acceleration term arising from the post-Newtonian correction @@ -55,7 +55,6 @@ module whm_classes !! component list, such as whm_setup_tp and whm_spill_tp contains private - procedure, public :: drift => whm_drift_tp !! Loop through test particles and call Danby drift routine procedure, public :: accel => whm_getacch_tp !! Compute heliocentric accelerations of test particles procedure, public :: accel_gr => whm_gr_getacch_tp !! Acceleration term arising from the post-Newtonian correction procedure, public :: gr_pos_kick => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction @@ -102,19 +101,10 @@ module subroutine whm_drift_pl(self, system, param, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine whm_drift_pl - module subroutine whm_drift_tp(self, system, param, dt) - use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters - implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize - end subroutine whm_drift_tp - module subroutine whm_fill_pl(self, inserts, lfill_list) use swiftest_classes, only : swiftest_body implicit none @@ -129,7 +119,7 @@ module subroutine whm_getacch_pl(self, system, param, t, lbeg) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step end subroutine whm_getacch_pl @@ -140,7 +130,7 @@ module subroutine whm_getacch_tp(self, system, param, t, lbeg) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step end subroutine whm_getacch_tp @@ -149,7 +139,7 @@ module subroutine whm_gr_getacch_pl(self, param) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine whm_gr_getacch_pl module subroutine whm_gr_getacch_tp(self, param) @@ -163,7 +153,7 @@ module pure subroutine whm_gr_p4_pl(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl @@ -171,7 +161,7 @@ module pure subroutine whm_gr_p4_tp(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! WHM test particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp @@ -198,7 +188,7 @@ module subroutine whm_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine whm_setup_system !> Reads WHM test particle object in from file diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index a27897cfa..ed72cd7f3 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -12,7 +12,7 @@ module subroutine whm_drift_pl(self, system, param, dt) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize ! Internals integer(I4B) :: i @@ -59,54 +59,4 @@ module subroutine whm_drift_pl(self, system, param, dt) end subroutine whm_drift_pl - module subroutine whm_drift_tp(self, system, param, dt) - !! author: David A. Minton - !! - !! Loop through test particles and call Danby drift routine - !! - !! Adapted from Hal Levison's Swift routine drift_tp.f - !! Includes - !! Adapted from David E. Kaufmann's Swifter routine whm_drift_tp.f90 - implicit none - ! Arguments - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize - ! Internals - integer(I4B) :: i - real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation - integer(I4B), dimension(:), allocatable :: iflag - real(DP), dimension(:), allocatable :: dtp - - associate(tp => self, ntp => self%nbody) - if (ntp == 0) return - allocate(iflag(ntp)) - iflag(:) = 0 - allocate(dtp(ntp)) - if (param%lgr) then - do i = 1, ntp - rmag = norm2(tp%xh(:, i)) - vmag2 = dot_product(tp%vh(:, i), tp%vh(:, i)) - energy = 0.5_DP * vmag2 - tp%mu(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - dtp(:) = dt - end if - do concurrent(i = 1:ntp, tp%status(i) == ACTIVE) - call drift_one(tp%mu(i), tp%xh(1,i), tp%xh(2,i), tp%xh(3,i), & - tp%vh(1,i), tp%vh(2,i), tp%vh(3,i), & - dtp(i), iflag(i)) - end do - if (any(iflag(1:ntp) /= 0)) then - where(iflag(1:ntp) /= 0) tp%status(1:ntp) = DISCARDED_DRIFTERR - do i = 1, ntp - if (iflag(i) /= 0) write(*, *) "Particle ", self%id(i), " lost due to error in Danby drift" - end do - end if - end associate - - return - end subroutine whm_drift_tp end submodule whm_drift From 645df4c2a9e0580f2493e3c4d3dab1fd1d96ba6d Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 14:21:17 -0400 Subject: [PATCH 13/33] Fixed up formatting and some comments --- src/gr/gr.f90 | 4 ++-- src/helio/helio_drift.f90 | 4 ++-- src/helio/helio_getacch.f90 | 6 +++--- src/modules/helio_classes.f90 | 6 +++--- src/symba/symba_step.f90 | 1 + src/user/user_getacch.f90 | 2 +- src/whm/whm_getacch.f90 | 4 ++-- src/whm/whm_gr.f90 | 6 +++--- src/whm/whm_setup.f90 | 2 +- src/whm/whm_step.f90 | 2 +- 10 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/gr/gr.f90 b/src/gr/gr.f90 index 8831a93d5..7d794bf2b 100644 --- a/src/gr/gr.f90 +++ b/src/gr/gr.f90 @@ -108,7 +108,7 @@ module pure subroutine gr_pv2vh_body(self, param) implicit none ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion @@ -207,7 +207,7 @@ module pure subroutine gr_vh2pv_body(self, param) implicit none ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 40da379ee..3f64905b0 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -14,7 +14,7 @@ module subroutine helio_drift_pl(self, system, param, dt) ! Arguments class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize) ! Internals integer(I4B) :: i !! Loop counter @@ -104,7 +104,7 @@ module subroutine helio_drift_tp(self, system, param, dt) ! Arguments class(helio_tp), intent(inout) :: self !! Helio test particle object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize ! Internals integer(I4B) :: i !! Loop counter diff --git a/src/helio/helio_getacch.f90 b/src/helio/helio_getacch.f90 index ca6f09fc1..e7a84108e 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -12,7 +12,7 @@ module subroutine helio_getacch_pl(self, system, param, t, lbeg) ! Arguments class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step @@ -46,7 +46,7 @@ module subroutine helio_getacch_tp(self, system, param, t, lbeg) ! Arguments class(helio_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step ! Internals @@ -110,7 +110,7 @@ subroutine helio_getacch_int_tp(tp, system, param, t) ! Arguments class(helio_tp), intent(inout) :: tp !! Helio test particle object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current times ! Internals integer(I4B) :: i, j diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 190c354b7..8d23d2f8c 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -91,7 +91,7 @@ module subroutine helio_drift_pl(self, system, param, dt) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_pl @@ -100,7 +100,7 @@ module subroutine helio_drift_tp(self, system, param, dt) implicit none class(helio_tp), intent(inout) :: self !! Helio test particle object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_tp @@ -125,7 +125,7 @@ module subroutine helio_getacch_pl(self, system, param, t, lbeg) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step end subroutine helio_getacch_pl diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index 3e14686ac..bfd36b7f5 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -112,6 +112,7 @@ module recursive subroutine symba_step_recur_system(self, param, t, dt) real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize ! Internals + !associate() end subroutine symba_step_recur_system end submodule s_symba_step diff --git a/src/user/user_getacch.f90 b/src/user/user_getacch.f90 index c54c21693..16a2f0916 100644 --- a/src/user/user_getacch.f90 +++ b/src/user/user_getacch.f90 @@ -11,7 +11,7 @@ module subroutine user_getacch_body(self, system, param, t, lbeg) ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody_system_object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of user parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters user parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the ste diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 4d761fc02..f393bd60e 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -12,7 +12,7 @@ module subroutine whm_getacch_pl(self, system, param, t, lbeg) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step ! Internals @@ -61,7 +61,7 @@ module subroutine whm_getacch_tp(self, system, param, t, lbeg) ! Arguments class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step ! Internals diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 index 3cf159504..62c7fb2b5 100644 --- a/src/whm/whm_gr.f90 +++ b/src/whm/whm_gr.f90 @@ -10,7 +10,7 @@ module subroutine whm_gr_getacch_pl(self, param) !! author: David A. Minton implicit none ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: suma @@ -71,7 +71,7 @@ module pure subroutine whm_gr_p4_pl(self, param, dt) implicit none ! Arguments class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size ! Internals integer(I4B) :: i @@ -96,7 +96,7 @@ module pure subroutine whm_gr_p4_tp(self, param, dt) implicit none ! Arguments class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size ! Internals integer(I4B) :: i diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 index 9f0f9b1b7..50f0618bb 100644 --- a/src/whm/whm_setup.f90 +++ b/src/whm/whm_setup.f90 @@ -79,7 +79,7 @@ module subroutine whm_setup_system(self, param) implicit none ! Arguments class(whm_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters call io_read_initialize_system(self, param) ! Make sure that the discard list gets allocated initially diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index 22dd16387..9296a179c 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -12,7 +12,7 @@ module subroutine whm_step_system(self, param, t, dt) implicit none ! Arguments class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Current stepsize From 1af1dfb48679e113aea6abcfb5d2a6bebbf77e02 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 14:49:48 -0400 Subject: [PATCH 14/33] Updated drift routines to use mask --- .../swiftest_vs_swifter.ipynb | 54 +++++------ python/swiftest/swiftest/io.py | 3 +- src/drift/drift.f90 | 9 +- src/helio/helio_drift.f90 | 92 +++++-------------- src/helio/helio_step.f90 | 4 +- src/modules/helio_classes.f90 | 13 +-- src/modules/swiftest_classes.f90 | 3 +- src/modules/whm_classes.f90 | 3 +- src/symba/symba_step.f90 | 4 +- src/whm/whm_drift.f90 | 16 ++-- src/whm/whm_step.f90 | 4 +- 11 files changed, 72 insertions(+), 133 deletions(-) diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb index 52568fd84..4c9361b73 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb @@ -42,11 +42,23 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reading Swiftest file param.swiftest.in\n", - "Reading in time 1.506e-01\n", - "Creating Dataset\n", - "Successfully converted 221 output frames.\n", - "Swiftest simulation data stored as xarray DataSet .ds\n" + "Reading Swiftest file param.swiftest.in\n" + ] + }, + { + "ename": "ValueError", + "evalue": "Size obtained (4) is not a multiple of the dtypes given (8).", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mswiftestsim\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mswiftest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSimulation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam_file\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"param.swiftest.in\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mswiftestsim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbin2xr\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/swiftest/python/swiftest/swiftest/simulation_class.py\u001b[0m in \u001b[0;36mbin2xr\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mbin2xr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[1;32m 135\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcodename\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"Swiftest\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 136\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mswiftest2xr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparam\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 137\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Swiftest simulation data stored as xarray DataSet .ds'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 138\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcodename\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"Swifter\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/git/swiftest/python/swiftest/swiftest/io.py\u001b[0m in \u001b[0;36mswiftest2xr\u001b[0;34m(param)\u001b[0m\n\u001b[1;32m 600\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcbid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclab\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 601\u001b[0m \u001b[0mnpl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplab\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 602\u001b[0;31m \u001b[0mntp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtpid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtlab\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mswiftest_stream\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparam\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[1;32m 603\u001b[0m \u001b[0;31m# Prepare frames by adding an extra axis for the time coordinate\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 604\u001b[0m \u001b[0mcbframe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_dims\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/git/swiftest/python/swiftest/swiftest/io.py\u001b[0m in \u001b[0;36mswiftest_stream\u001b[0;34m(f, param)\u001b[0m\n\u001b[1;32m 469\u001b[0m \u001b[0;31m#cbid = f.read_ints()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 470\u001b[0m \u001b[0mcbid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\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;32m--> 471\u001b[0;31m \u001b[0mMcb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\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 472\u001b[0m \u001b[0mRcb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 473\u001b[0m \u001b[0mJ2cb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;32m~/.conda/envs/cent7/2020.02-py37/swiftestOOF/lib/python3.7/site-packages/scipy/io/_fortran.py\u001b[0m in \u001b[0;36mread_reals\u001b[0;34m(self, dtype)\u001b[0m\n\u001b[1;32m 336\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 337\u001b[0m \"\"\"\n\u001b[0;32m--> 338\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_record\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtype\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 339\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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;32m~/.conda/envs/cent7/2020.02-py37/swiftestOOF/lib/python3.7/site-packages/scipy/io/_fortran.py\u001b[0m in \u001b[0;36mread_record\u001b[0;34m(self, *dtypes, **kwargs)\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mremainder\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 259\u001b[0m raise ValueError('Size obtained ({0}) is not a multiple of the '\n\u001b[0;32m--> 260\u001b[0;31m 'dtypes given ({1}).'.format(first_size, block_size))\n\u001b[0m\u001b[1;32m 261\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 262\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtypes\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mfirst_size\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mblock_size\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: Size obtained (4) is not a multiple of the dtypes given (8)." ] } ], @@ -57,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -66,7 +78,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -75,33 +87,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[,\n", - " ]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "swiftdiff['px'].plot.line(x=\"time (y)\")" ] diff --git a/python/swiftest/swiftest/io.py b/python/swiftest/swiftest/io.py index caf1c0e39..ceab9a74f 100644 --- a/python/swiftest/swiftest/io.py +++ b/python/swiftest/swiftest/io.py @@ -466,8 +466,7 @@ def swiftest_stream(f, param): npl = f.read_ints() ntp = f.read_ints() iout_form = f.read_reals('c') - #cbid = f.read_ints() - cbid = np.array([0]) + cbid = f.read_ints() Mcb = f.read_reals(np.float64) Rcb = f.read_reals(np.float64) J2cb = f.read_reals(np.float64) diff --git a/src/drift/drift.f90 b/src/drift/drift.f90 index 2ddb03500..ce9f66761 100644 --- a/src/drift/drift.f90 +++ b/src/drift/drift.f90 @@ -10,7 +10,7 @@ contains - module subroutine drift_body(self, system, param, dt) + module subroutine drift_body(self, system, param, dt, mask) !! author: David A. Minton !! !! Loop bodies and call Danby drift routine on the heliocentric position and velocities. @@ -23,6 +23,7 @@ module subroutine drift_body(self, system, param, dt) class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. ! Internals integer(I4B) :: i real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation @@ -35,16 +36,16 @@ module subroutine drift_body(self, system, param, dt) iflag(:) = 0 allocate(dtp(n)) if (param%lgr) then - do i = 1, n + do concurrent(i = 1:n, mask(i)) rmag = norm2(self%xh(:, i)) vmag2 = dot_product(self%vh(:, i), self%vh(:, i)) energy = 0.5_DP * vmag2 - self%mu(i) / rmag dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) end do else - dtp(:) = dt + where(mask(1:n)) dtp(1:n) = dt end if - do concurrent(i = 1:n, self%status(i) == ACTIVE) + do concurrent(i = 1:n, mask(i)) call drift_one(self%mu(i), self%xh(1,i), self%xh(2,i), self%xh(3,i), & self%vh(1,i), self%vh(2,i), self%vh(3,i), & dtp(i), iflag(i)) diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 3f64905b0..7ae65feab 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -1,7 +1,7 @@ submodule (helio_classes) s_helio_drift use swiftest contains - module subroutine helio_drift_pl(self, system, param, dt) + module subroutine helio_drift_pl(self, system, param, dt, mask) !! author: David A. Minton !! @@ -13,9 +13,10 @@ module subroutine helio_drift_pl(self, system, param, dt) implicit none ! Arguments class(helio_pl), intent(inout) :: self !! Helio massive body object - class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: dt !! Stepsize) + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. ! Internals integer(I4B) :: i !! Loop counter real(DP) :: rmag, vmag2, energy @@ -29,33 +30,39 @@ module subroutine helio_drift_pl(self, system, param, dt) iflag(:) = 0 allocate(dtp(npl)) allocate(mu(npl)) - mu = cb%Gmass + mu(:) = cb%Gmass if (param%lgr) then - do i = 1,npl - rmag = norm2(pl%xh(:, i)) - vmag2 = dot_product(pl%vb(:, i), pl%vb(:, i)) - energy = 0.5_DP * vmag2 - pl%mu(i) / rmag + do concurrent(i = 1:npl, mask(i)) + rmag = norm2(pl%xb(:, i)) + vmag2 = dot_product(pl%vb(:, i), pl%vb(:, i)) + energy = 0.5_DP * vmag2 - mu(i) / rmag dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) end do else - dtp(:) = dt + where(mask(1:npl)) dtp(1:npl) = dt end if - call drift_one(mu(1:npl), pl%xh(1,1:npl), pl%xh(2,1:npl), pl%xh(3,1:npl), & - pl%vb(1,1:npl), pl%vb(2,1:npl), pl%vb(3,1:npl), & - dtp(1:npl), iflag(1:npl)) + do concurrent(i = 1:npl, mask(i)) + call drift_one(mu(i), pl%xb(1,i), pl%xb(2,i), pl%xb(3,i), & + pl%vb(1,i), pl%vb(2,i), pl%vb(3,i), & + dtp(i), iflag(i)) + end do if (any(iflag(1:npl) /= 0)) then do i = 1, npl - write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!" - write(*, *) pl%xh(:,i) - write(*, *) pl%vb(:,i) - write(*, *) " stopping " - call util_exit(FAILURE) + if (iflag(i) /= 0) then + write(*, *) " Planet ", self%id(i), " is lost!!!!!!!!!!" + write(*, *) pl%xb(:,i) + write(*, *) pl%vb(:,i) + write(*, *) " stopping " + call util_exit(FAILURE) + end if end do end if end associate + return + end subroutine helio_drift_pl module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) @@ -93,57 +100,6 @@ module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) return end subroutine helio_drift_linear_pl - module subroutine helio_drift_tp(self, system, param, dt) - !! author: David A. Minton - !! - !! Loop through test particles and call Danby drift routine - !! - !! Adapted from David E. Kaufmann's Swifter routine helio_drift_tp.f90 - !! Adapted from Hal Levison's Swift routine drift_tp.f - implicit none - ! Arguments - class(helio_tp), intent(inout) :: self !! Helio test particle object - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: dt !! Stepsize - ! Internals - integer(I4B) :: i !! Loop counter - real(DP) :: rmag, vmag2, energy - real(DP), dimension(:), allocatable :: dtp, mu - integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag - - associate(tp => self, ntp => self%nbody, cb => system%cb) - if (ntp == 0) return - allocate(iflag(ntp)) - allocate(dtp(ntp)) - iflag(:) = 0 - allocate(mu(ntp)) - mu = cb%Gmass - - if (param%lgr) then - do i = 1,ntp - rmag = norm2(tp%xh(:, i)) - vmag2 = dot_product(tp%vh(:, i), tp%vh(:, i)) - energy = 0.5_DP * vmag2 - tp%mu(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - dtp(:) = dt - end if - call drift_one(mu(1:ntp), tp%xh(1,1:ntp), tp%xh(2,1:ntp), tp%xh(3,1:ntp), & - tp%vb(1,1:ntp), tp%vb(2,1:ntp), tp%vb(3,1:ntp), & - dtp(1:ntp), iflag(1:ntp)) - if (any(iflag(1:ntp) /= 0)) then - tp%status = DISCARDED_DRIFTERR - do i = 1, ntp - if (iflag(i) /= 0) write(*, *) "Particle ", tp%id(i), " lost due to error in Danby drift" - end do - end if - end associate - - return - end subroutine helio_drift_tp - module subroutine helio_drift_linear_tp(self, cb, dt, lbeg) !! author: David A. Minton !! diff --git a/src/helio/helio_step.f90 b/src/helio/helio_step.f90 index d37b21bbb..511ffacb6 100644 --- a/src/helio/helio_step.f90 +++ b/src/helio/helio_step.f90 @@ -53,7 +53,7 @@ module subroutine helio_step_pl(self, system, param, t, dt) call pl%accel(system, param, t) call pl%kick(dth) call pl%set_beg_end(xbeg = pl%xh) - call pl%drift(system, param, dt) + call pl%drift(system, param, dt, pl%status(:) == ACTIVE) call pl%set_beg_end(xend = pl%xh) call pl%accel(system, param, t + dt) call pl%kick(dth) @@ -97,7 +97,7 @@ module subroutine helio_step_tp(self, system, param, t, dt) call tp%lindrift(cb, dth, lbeg=.true.) call tp%accel(system, param, t, lbeg=.true.) call tp%kick(dth) - call tp%drift(system, param, dt) + call tp%drift(system, param, dt, tp%status(:) == ACTIVE) call tp%accel(system, param, t + dt, lbeg=.false.) call tp%kick(dth) call tp%lindrift(cb, dth, lbeg=.false.) diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 8d23d2f8c..ae0de83a7 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -52,7 +52,6 @@ module helio_classes contains procedure, public :: vh2vb => helio_coord_vh2vb_tp !! Convert test particles from heliocentric to barycentric coordinates (velocity only) procedure, public :: vb2vh => helio_coord_vb2vh_tp !! Convert test particles from barycentric to heliocentric coordinates (velocity only) - procedure, public :: drift => helio_drift_tp !! Method for Danby drift in Democratic Heliocentric coordinates procedure, public :: lindrift => helio_drift_linear_tp !! Method for linear drift of massive bodies due to barycentric momentum of Sun procedure, public :: accel => helio_getacch_tp !! Compute heliocentric accelerations of massive bodies procedure, public :: kick => helio_kickvb_tp !! Kicks the barycentric velocities @@ -86,24 +85,16 @@ module subroutine helio_coord_vh2vb_tp(self, vbcb) real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body end subroutine helio_coord_vh2vb_tp - module subroutine helio_drift_pl(self, system, param, dt) + module subroutine helio_drift_pl(self, system, param, dt, mask) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift end subroutine helio_drift_pl - module subroutine helio_drift_tp(self, system, param, dt) - use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters - implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle object - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: dt !! Stepsize - end subroutine helio_drift_tp - module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index e924d2546..d07f39f5a 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -384,12 +384,13 @@ module subroutine discard_tp(self, system, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_tp - module subroutine drift_body(self, system, param, dt) + module subroutine drift_body(self, system, param, dt, mask) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift end subroutine drift_body module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index 21811cf38..a1f501a10 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -96,13 +96,14 @@ module subroutine whm_coord_vh2vj_pl(self, cb) class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree end subroutine whm_coord_vh2vj_pl - module subroutine whm_drift_pl(self, system, param, dt) + module subroutine whm_drift_pl(self, system, param, dt, mask) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift end subroutine whm_drift_pl module subroutine whm_fill_pl(self, inserts, lfill_list) diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index bfd36b7f5..43d11125c 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -73,8 +73,8 @@ module subroutine symba_step_interp_system(self, param, t, dt) call tp%kick(dth) system%irec = -1 - call pl%drift(system, param, dt) - call tp%drift(system, param, dt) + call pl%drift(system, param, dt, pl%status(:) == ACTIVE) + call tp%drift(system, param, dt, tp%status(:) == ACTIVE) system%irec = 0 call system%recursive_step(param, t, dt) diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index ed72cd7f3..12d8494a8 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -1,7 +1,7 @@ submodule(whm_classes) whm_drift use swiftest contains - module subroutine whm_drift_pl(self, system, param, dt) + module subroutine whm_drift_pl(self, system, param, dt, mask) !! author: David A. Minton !! !! Loop through planets and call Danby drift routine @@ -14,6 +14,7 @@ module subroutine whm_drift_pl(self, system, param, dt) class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift ! Internals integer(I4B) :: i real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation @@ -21,7 +22,6 @@ module subroutine whm_drift_pl(self, system, param, dt) real(DP), dimension(:), allocatable :: dtp associate(pl => self, npl => self%nbody) - if (npl == 0) return allocate(iflag(npl)) @@ -29,19 +29,21 @@ module subroutine whm_drift_pl(self, system, param, dt) allocate(dtp(npl)) if (param%lgr) then - do i = 1,npl + do concurrent(i = 1:npl, mask(i)) rmag = norm2(pl%xj(:, i)) vmag2 = dot_product(pl%vj(:, i), pl%vj(:, i)) energy = 0.5_DP * vmag2 - pl%muj(i) / rmag dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) end do else - dtp(:) = dt + where(mask(1:npl)) dtp(1:npl) = dt end if - call drift_one(pl%muj(1:npl), pl%xj(1,1:npl), pl%xj(2,1:npl), pl%xj(3,1:npl), & - pl%vj(1,1:npl), pl%vj(2,1:npl), pl%vj(3,1:npl), & - dtp(1:npl), iflag(1:npl)) + do concurrent(i = 1:npl, mask(i)) + call drift_one(pl%muj(i), pl%xj(1,i), pl%xj(2,i), pl%xj(3,i), & + pl%vj(1,i), pl%vj(2,i), pl%vj(3,i), & + dtp(i), iflag(i)) + end do if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index 9296a179c..64415f15d 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -56,7 +56,7 @@ module subroutine whm_step_pl(self, system, param, t, dt) call pl%kick(dth) call pl%vh2vj(cb) if (param%lgr) call pl%gr_pos_kick(param, dth) - call pl%drift(system, param, dt) + call pl%drift(system, param, dt, pl%status(:) == ACTIVE) if (param%lgr) call pl%gr_pos_kick(param, dth) call pl%j2h(cb) call pl%accel(system, param, t + dt) @@ -95,7 +95,7 @@ module subroutine whm_step_tp(self, system, param, t, dt) end if call tp%kick(dth) if (param%lgr) call tp%gr_pos_kick(param, dth) - call tp%drift(system, param, dt) + call tp%drift(system, param, dt, tp%status(:) == ACTIVE) if (param%lgr) call tp%gr_pos_kick(param, dth) call tp%accel(system, param, t + dt, lbeg=.false.) call tp%kick(dth) From e7ecc65a470d0d01401ff99dadb39e2aeaba00c3 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 15:23:47 -0400 Subject: [PATCH 15/33] Updated examples --- .../swiftest_vs_swifter.ipynb | 54 +++++++++++-------- examples/whm_gr_test/init_cond.py | 2 +- examples/whm_gr_test/param.swifter.in | 2 +- examples/whm_gr_test/param.swiftest.in | 2 +- examples/whm_gr_test/pl.swifter.in | 48 ++++++++--------- examples/whm_gr_test/pl.swiftest.in | 32 +++++------ .../whm_gr_test/swiftest_relativity.ipynb | 39 ++++++++------ 7 files changed, 99 insertions(+), 80 deletions(-) diff --git a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb index 4c9361b73..98b32fc30 100644 --- a/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb +++ b/examples/rmvs_swifter_comparison/1pl_1tp_encounter/swiftest_vs_swifter.ipynb @@ -42,23 +42,11 @@ "name": "stdout", "output_type": "stream", "text": [ - "Reading Swiftest file param.swiftest.in\n" - ] - }, - { - "ename": "ValueError", - "evalue": "Size obtained (4) is not a multiple of the dtypes given (8).", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", - "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mswiftestsim\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mswiftest\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mSimulation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mparam_file\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m\"param.swiftest.in\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 2\u001b[0;31m \u001b[0mswiftestsim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbin2xr\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/swiftest/python/swiftest/swiftest/simulation_class.py\u001b[0m in \u001b[0;36mbin2xr\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 134\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mbin2xr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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[1;32m 135\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcodename\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"Swiftest\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 136\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mds\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mio\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mswiftest2xr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparam\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 137\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'Swiftest simulation data stored as xarray DataSet .ds'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 138\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcodename\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m\"Swifter\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/git/swiftest/python/swiftest/swiftest/io.py\u001b[0m in \u001b[0;36mswiftest2xr\u001b[0;34m(param)\u001b[0m\n\u001b[1;32m 600\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcbid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mclab\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 601\u001b[0m \u001b[0mnpl\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mplab\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 602\u001b[0;31m \u001b[0mntp\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtpid\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtlab\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mswiftest_stream\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparam\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[1;32m 603\u001b[0m \u001b[0;31m# Prepare frames by adding an extra axis for the time coordinate\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 604\u001b[0m \u001b[0mcbframe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mexpand_dims\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcvec\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0maxis\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/git/swiftest/python/swiftest/swiftest/io.py\u001b[0m in \u001b[0;36mswiftest_stream\u001b[0;34m(f, param)\u001b[0m\n\u001b[1;32m 469\u001b[0m \u001b[0;31m#cbid = f.read_ints()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 470\u001b[0m \u001b[0mcbid\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\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;32m--> 471\u001b[0;31m \u001b[0mMcb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\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 472\u001b[0m \u001b[0mRcb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 473\u001b[0m \u001b[0mJ2cb\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_reals\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat64\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;32m~/.conda/envs/cent7/2020.02-py37/swiftestOOF/lib/python3.7/site-packages/scipy/io/_fortran.py\u001b[0m in \u001b[0;36mread_reals\u001b[0;34m(self, dtype)\u001b[0m\n\u001b[1;32m 336\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 337\u001b[0m \"\"\"\n\u001b[0;32m--> 338\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mread_record\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtype\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 339\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 340\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mclose\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\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;32m~/.conda/envs/cent7/2020.02-py37/swiftestOOF/lib/python3.7/site-packages/scipy/io/_fortran.py\u001b[0m in \u001b[0;36mread_record\u001b[0;34m(self, *dtypes, **kwargs)\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mremainder\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 259\u001b[0m raise ValueError('Size obtained ({0}) is not a multiple of the '\n\u001b[0;32m--> 260\u001b[0;31m 'dtypes given ({1}).'.format(first_size, block_size))\n\u001b[0m\u001b[1;32m 261\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 262\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdtypes\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mfirst_size\u001b[0m \u001b[0;34m!=\u001b[0m \u001b[0mblock_size\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", - "\u001b[0;31mValueError\u001b[0m: Size obtained (4) is not a multiple of the dtypes given (8)." + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.506e-01\n", + "Creating Dataset\n", + "Successfully converted 221 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" ] } ], @@ -69,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -78,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -87,9 +75,33 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[,\n", + " ]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAEGCAYAAABGnrPVAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAWKklEQVR4nO3dfbBV9X3v8fe3gFIrPosePFhoQAuoMeRcJA9jGgkdJCkksU0lacTE1DHGJK3Xm0tvpjftH02YSXOvSaVxUONgmlsm1yQ+ZFBL1Ew6phhRo4iEQH3i4KkSEo1er4/53j/2lrs5bGBz9m/vtZH3a2YPe631/a31PZuzzuestfZZOzITSZJK+a2qG5AkvbEYLJKkogwWSVJRBoskqSiDRZJU1OiqG+imY445JidNmlR1G5K0X7n33nt/kZnHtlp/QAXLpEmTWLt2bdVtSNJ+JSIe35d6T4VJkooyWCRJRRkskqSiDqhrLJK0J6+88gqDg4O8+OKLVbdSibFjx9Lf38+YMWPaWo/BIkl1g4ODjBs3jkmTJhERVbfTVZnJ9u3bGRwcZPLkyW2ty1NhklT34osvcvTRRx9woQIQERx99NFFjtYMFklqcCCGyutKfe0GiySpKINFkir09re/ven8888/n+uvv77L3ZRhsEhShX784x9X3UJxvitMkip06KGH8vzzz5OZfPrTn+aOO+5g8uTJ7M+f7usRiyT1gO9973ts3LiRdevWcdVVV+3XRzIGiyT1gB/96EcsWrSIUaNGMWHCBM4666yqWxoxg0WSesQb5a3OBosk9YAzzzyTlStX8tprrzE0NMSdd95ZdUsj5sV7SeoBH/jAB7jjjjs49dRTOemkk3jXu95VdUsjZrBIUoWef/55oHYa7Iorrqi4mzI8FSZJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiyT1kC1btvDud7+badOmMWPGDL761a/uUpOZfOYzn2HKlCmcdtpp3HfffRV0unv+HYsk9ZDRo0fzla98hZkzZ/Lcc8/x1re+lblz5zJ9+vQdNbfccgubNm1i06ZN3H333Xzyk5/k7rvvrrDrnVV6xBIR8yJiY0RsjoglTZZHRHytvvzBiJg5bPmoiLg/Ir7fva4lqXP6+vqYObP2o27cuHFMmzaNrVu37lRz4403ct555xERzJ49m2eeeYahoaEq2m2qsiOWiBgFLAPmAoPAPRFxU2Y+3FB2NjC1/jgD+Hr939d9FtgAHNaVpiUdMP725vU8/OSvi65z+oTD+MIfzWi5/rHHHuP+++/njDPO2Gn+1q1bmThx4o7p/v5+tm7dSl9fX7Fe21HlEcssYHNmPpKZLwMrgYXDahYC12XNGuCIiOgDiIh+4L3A1d1sWpK64fnnn+ecc87h8ssv57DDdv7dudmHgPXSnZGrvMZyArClYXqQnY9GdldzAjAEXA58Dhi3p41ExIXAhQAnnnhiWw1LOnDsy5FFaa+88grnnHMOH/nIR/jgBz+4y/L+/n62bPn/PxoHBweZMGFCN1vcoyqPWJrF6/AYbloTEe8Dns7Me/e2kcxcnpkDmTlw7LHHjqRPSeqazOSCCy5g2rRpXHrppU1rFixYwHXXXUdmsmbNGg4//PCeOQ0G1R6xDAITG6b7gSdbrPljYEFEzAfGAodFxD9l5p91sF9J6ri77rqLb37zm5x66qmcfvrpAHzxi1/kiSeeAOCiiy5i/vz5rFq1iilTpnDIIYdw7bXXVtjxrqoMlnuAqRExGdgKnAt8eFjNTcAlEbGS2mmyZzNzCPir+oOI+APgMkNF0hvBO9/5zqbXUBpFBMuWLetSR/uusmDJzFcj4hLgNmAU8I3MXB8RF9WXXwmsAuYDm4EXgI9V1a8kqTWV/oFkZq6iFh6N865seJ7Ap/ayjh8CP+xAe5KkEfCWLpKkogwWSVJRBoskqSiDRZJUlMEiST3k4x//OOPHj+eUU07ZMe+Xv/wlc+fOZerUqcydO5df/epXO5Z96UtfYsqUKZx88sncdtttTde5p/GdYLBIUg85//zzufXWW3eat3TpUubMmcOmTZuYM2cOS5cuBeDhhx9m5cqVrF+/nltvvZWLL76Y1157bZd17m58pxgsktRDzjzzTI466qid5t14440sXrwYgMWLF3PDDTfsmH/uuedy8MEHM3nyZKZMmcJPfvKTXda5u/Gd4gd9SVIztyyB/1hXdp3Hnwpn7/vRwlNPPbXjXmB9fX08/fTTQO32+bNnz95R9/rt81sd3ykesUjSfqpXb5/vEYskNTOCI4tOOe644xgaGqKvr4+hoSHGjx8PtH77/N2N7xSPWCSpxy1YsIAVK1YAsGLFChYuXLhj/sqVK3nppZd49NFH2bRpE7NmzWp5fKcYLJLUQxYtWsTb3vY2Nm7cSH9/P9dccw1Llixh9erVTJ06ldWrV7NkyRIAZsyYwYc+9CGmT5/OvHnzWLZsGaNGjQLgE5/4BGvXrgXY7fhOib3dnvmNZGBgIF9/oSVpuA0bNjBt2rSq26hUs9cgIu7NzIFW1+ERiySpKINFklSUwSJJDQ6kywPDlfraDRZJqhs7dizbt28/IMMlM9m+fTtjx45te13+HYsk1fX39zM4OMi2bduqbqUSY8eOpb+/v+31GCySVDdmzBgmT55cdRv7PU+FSZKKMlgkSUUZLJKkogwWSVJRBoskqSiDRZJUlMEiSSrKYJEkFWWwSJKKMlgkSUUZLJKkoioNloiYFxEbI2JzROzyWZlR87X68gcjYmZ9/sSIuDMiNkTE+oj4bPe7lyQ1U1mwRMQoYBlwNjAdWBQR04eVnQ1MrT8uBL5en/8q8J8zcxowG/hUk7GSpApUecQyC9icmY9k5svASmDhsJqFwHVZswY4IiL6MnMoM+8DyMzngA3ACd1sXpLUXJXBcgKwpWF6kF3DYa81ETEJeAtwd/kWJUn7qspgiSbzhn9s2x5rIuJQ4DvAX2Tmr5tuJOLCiFgbEWsP1A/vkaRuqjJYBoGJDdP9wJOt1kTEGGqh8q3M/O7uNpKZyzNzIDMHjj322CKNS5J2r8pguQeYGhGTI+Ig4FzgpmE1NwHn1d8dNht4NjOHIiKAa4ANmfk/utu2JGlPKvto4sx8NSIuAW4DRgHfyMz1EXFRffmVwCpgPrAZeAH4WH34O4CPAusi4qf1ef8tM1d18UuQJDURmcMva7xxDQwM5Nq1a6tuQ5L2KxFxb2YOtFrvX95LkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKqqlYImIC4ZNj4qIL7S78YiYFxEbI2JzRCxpsjwi4mv15Q9GxMxWx0qSqtHqEcuciFgVEX0RcQqwBhjXzoYjYhSwDDgbmA4siojpw8rOBqbWHxcCX9+HsZKkCoxupSgzPxwRfwqsA14AFmXmXW1uexawOTMfAYiIlcBC4OGGmoXAdZmZwJqIOCIi+oBJLYwtZs0//jnjntnQiVVLUkc9PvpNrDj8IqZPOIwv/NGMrmyz1VNhU4HPAt8BHgM+GhGHtLntE4AtDdOD9Xmt1LQyFoCIuDAi1kbE2m3btrXZsiRpb1o6YgFuBj6VmbdHRAB/CdwDtBN/0WRetljTytjazMzlwHKAgYGBpjV7M/viq0YyTJIqNwOY3+VttnqNZRbw5oj4LnA9tR/i57a57UFgYsN0P/BkizWtjJUkVaDVYLmaWvD9A3AFMA346za3fQ8wNSImR8RB1ILqpmE1NwHn1d8dNht4NjOHWhwrSapAq6fCTs7MNzdM3xkRD7Sz4cx8NSIuAW4DRgHfyMz1EXFRffmVwCpqR3Gbqb1p4GN7GttOP5KkMloNlvsjYnZmrgGIiDOAdt8VRmauohYejfOubHiewKdaHStJql6rwXIGtVNST9SnTwQ2RMQ6aj//T+tId5Kk/U6rwTKvo11Ikt4wWv0Dycc73Ygk6Y3Bm1BKkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiDBZJUlEGiySpKINFklSUwSJJKspgkSQVZbBIkooyWCRJRRkskqSiKgmWiDgqIlZHxKb6v0fupm5eRGyMiM0RsaRh/pcj4mcR8WBEfC8ijuha85KkParqiGUJcHtmTgVur0/vJCJGAcuAs4HpwKKImF5fvBo4JTNPA34O/FVXupYk7VVVwbIQWFF/vgJ4f5OaWcDmzHwkM18GVtbHkZn/kpmv1uvWAP2dbVeS1KqqguW4zBwCqP87vknNCcCWhunB+rzhPg7cUrxDSdKIjO7UiiPiB8DxTRZ9vtVVNJmXw7bxeeBV4Ft76ONC4EKAE088scVNS5JGqmPBkpnv2d2yiHgqIvoycygi+oCnm5QNAhMbpvuBJxvWsRh4HzAnM5PdyMzlwHKAgYGB3dZJksqo6lTYTcDi+vPFwI1Nau4BpkbE5Ig4CDi3Po6ImAf8V2BBZr7QhX4lSS2qKliWAnMjYhMwtz5NREyIiFUA9YvzlwC3ARuAb2fm+vr4K4BxwOqI+GlEXNntL0CS1FzHToXtSWZuB+Y0mf8kML9hehWwqkndlI42KEkaMf/yXpJUlMEiSSrKYJEkFWWwSJKKMlgkSUUZLJKkogwWSVJRBoskqSiDRZJUlMEiSSrKYJEkFWWwSJKKMlgkSUUZLJKkogwWSVJRBoskqSiDRZJUlMEiSSrKYJEkFWWwSJKKMlgkSUUZLJKkogwWSVJRBoskqSiDRZJUlMEiSSrKYJEkFWWwSJKKMlgkSUUZLJKkogwWSVJRlQRLRBwVEasjYlP93yN3UzcvIjZGxOaIWNJk+WURkRFxTOe7liS1oqojliXA7Zk5Fbi9Pr2TiBgFLAPOBqYDiyJiesPyicBc4ImudCxJaklVwbIQWFF/vgJ4f5OaWcDmzHwkM18GVtbHve5/Ap8DsoN9SpL2UVXBclxmDgHU/x3fpOYEYEvD9GB9HhGxANiamQ/sbUMRcWFErI2Itdu2bWu/c0nSHo3u1Ioj4gfA8U0Wfb7VVTSZlxFxSH0df9jKSjJzObAcYGBgwKMbSeqwjgVLZr5nd8si4qmI6MvMoYjoA55uUjYITGyY7geeBN4ETAYeiIjX598XEbMy8z+KfQGSpBGp6lTYTcDi+vPFwI1Nau4BpkbE5Ig4CDgXuCkz12Xm+MyclJmTqAXQTENFknpDVcGyFJgbEZuovbNrKUBETIiIVQCZ+SpwCXAbsAH4dmaur6hfSVKLOnYqbE8yczswp8n8J4H5DdOrgFV7Wdek0v1JkkbOv7yXJBVlsEiSijJYJElFGSySpKIMFklSUQaLJKkog0WSVJTBIkkqymCRJBVlsEiSijJYJElFGSySpKIMFklSUQaLJKkog0WSVJTBIkkqymCRJBVlsEiSijJYJElFGSySpKIMFklSUQaLJKkog0WSVJTBIkkqKjKz6h66JiK2AY+PcPgxwC8KttMN9twd9twd9twdzXr+3cw8ttUVHFDB0o6IWJuZA1X3sS/suTvsuTvsuTtK9OypMElSUQaLJKkog6V1y6tuYATsuTvsuTvsuTva7tlrLJKkojxikSQVZbBIkooyWICImBcRGyNic0QsabI8IuJr9eUPRsTMVsf2Ws8RMTEi7oyIDRGxPiI+28v9NiwfFRH3R8T3u9Fvuz1HxBERcX1E/Kz+Wr9tP+j5L+vfEw9FxD9HxNge6fn3I+LfIuKliLhsX8b2Ws9V7X/t9NywvPV9MDMP6AcwCvh34PeAg4AHgOnDauYDtwABzAbubnVsD/bcB8ysPx8H/LzTPbfTb8PyS4H/BXy/178v6stWAJ+oPz8IOKKXewZOAB4Ffrs+/W3g/B7peTzwn4C/Ay7bl7E92HPX9792e25Y3vI+6BELzAI2Z+YjmfkysBJYOKxmIXBd1qwBjoiIvhbH9lTPmTmUmfcBZOZzwAZqP1R6sl+AiOgH3gtc3eE+i/QcEYcBZwLXAGTmy5n5TC/3XF82GvjtiBgNHAI82Qs9Z+bTmXkP8Mq+ju21niva/9rqGfZ9HzRYav+pWxqmB9n1P3p3Na2M7YR2et4hIiYBbwHuLt/ivvWyl5rLgc8Bv+lQf8200/PvAduAa+unDq6OiN/pZLN76WevNZm5Ffh74AlgCHg2M/+lg73usZ8ujG1Hke12cf+D9nu+nH3YBw2W2imB4Ya/B3t3Na2M7YR2eq4tjDgU+A7wF5n564K9NTPifiPifcDTmXlv+bb2qJ3XeDQwE/h6Zr4F+D9AN87/t/M6H0ntN9jJwATgdyLizwr310w7+1Av7397XkF39z9oo+eR7IMGSy25JzZM97PrKYDd1bQythPa6ZmIGEPtm/pbmfndDva5115aqHkHsCAiHqN2+H5WRPxT51rdaz+t1AwCg5n5+m+i11MLmk5rp+f3AI9m5rbMfAX4LvD2Dva6t346PbYdbW23gv0P2ut53/fBTl806vUHtd8uH6H2m9rrF7VmDKt5Lztf8PxJq2N7sOcArgMu3x9e42E1f0D3Lt631TPwr8DJ9ed/A3y5l3sGzgDWU7u2EtTefPDpXui5ofZv2PlCeM/uf3vouev7X7s9D1vW0j7YtS+slx/U3inzc2rvmvh8fd5FwEUN3wzL6svXAQN7GtvLPQPvpHYI/CDw0/pjfq/2O2wdLX1T90LPwOnA2vrrfANw5H7Q898CPwMeAr4JHNwjPR9P7TfuXwPP1J8ftruxvdxzVftfu69zwzpa2ge9pYskqSivsUiSijJYJElFGSySpKIMFklSUQaLJKkog0UaofodjC9umJ4QEdd3aFvvj4j/vpeav4+IszqxfWlf+HZjaYTq93r6fmae0oVt/RhYkJm/2EPN7wJXZeYfdrofaU88YpFGbinwpoj4aUR8OSImRcRDABFxfkTcEBE3R8SjEXFJRFxavynlmog4ql73poi4NSLujYh/jYjfH76RiDgJeCkzfxER4+rrG1NfdlhEPBYRYzLzceDoiDi+i6+BtAuDRRq5JcC/Z+bpmflfmiw/BfgwtVuW/x3wQtZuSvlvwHn1muXUbp3yVuAy4B+brOcdQOOt1n9I7dYsAOcC38na/b2o172jza9LasvoqhuQ3sDurAfBcxHxLHBzff464LT6HW7fDvzviB03nz24yXr6qN2G/3VXU7uF+Q3Ax4A/b1j2NLW7E0uVMVikznmp4flvGqZ/Q23f+y3gmcw8fS/r+b/A4a9PZOZd9dNu7wJGZeZDDbVj6/VSZTwVJo3cc9Q+XnZEsvY5HI9GxJ/Ajs+jf3OT0g3AlGHzrgP+Gbh22PyTqN1EUqqMwSKNUGZuB+6KiIci4ssjXM1HgAsi4gFqt61v9tG6PwLeEg3ny4BvAUdSCxdgx+d8TKF2V2WpMr7dWNoPRMRXgZsz8wf16T8GFmbmRxtqPgDMzMy/rqhNCfAai7S/+CK1D+MiIv4BOJva52s0Gg18pct9SbvwiEWSVJTXWCRJRRkskqSiDBZJUlEGiySpKINFklTU/wPoW2iXk/7T8QAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "swiftdiff['px'].plot.line(x=\"time (y)\")" ] diff --git a/examples/whm_gr_test/init_cond.py b/examples/whm_gr_test/init_cond.py index 57b0fb534..8d197c6f4 100755 --- a/examples/whm_gr_test/init_cond.py +++ b/examples/whm_gr_test/init_cond.py @@ -13,7 +13,7 @@ sim.param['DU2M'] = swiftest.AU2M sim.param['T0'] = 0.0 sim.param['DT'] = 0.25 * swiftest.JD2S / swiftest.YR2S -sim.param['TSTOP'] = 100.0 +sim.param['TSTOP'] = 1000.0 sim.param['ISTEP_OUT'] = 1461 sim.param['ISTEP_DUMP'] = 1461 sim.param['CHK_QMIN_COORD'] = "HELIO" diff --git a/examples/whm_gr_test/param.swifter.in b/examples/whm_gr_test/param.swifter.in index 6addd694c..789250f41 100644 --- a/examples/whm_gr_test/param.swifter.in +++ b/examples/whm_gr_test/param.swifter.in @@ -1,6 +1,6 @@ ! VERSION Swifter parameter file converted from Swiftest T0 0.0 -TSTOP 100.0 +TSTOP 1000.0 DT 0.0006844626967830253 ISTEP_OUT 1461 ISTEP_DUMP 1461 diff --git a/examples/whm_gr_test/param.swiftest.in b/examples/whm_gr_test/param.swiftest.in index c9b7462f0..ace6f3cad 100644 --- a/examples/whm_gr_test/param.swiftest.in +++ b/examples/whm_gr_test/param.swiftest.in @@ -1,6 +1,6 @@ ! VERSION Swiftest parameter input T0 0.0 -TSTOP 100.0 +TSTOP 1000.0 DT 0.0006844626967830253 ISTEP_OUT 1461 ISTEP_DUMP 1461 diff --git a/examples/whm_gr_test/pl.swifter.in b/examples/whm_gr_test/pl.swifter.in index e0ef4e881..782e57140 100644 --- a/examples/whm_gr_test/pl.swifter.in +++ b/examples/whm_gr_test/pl.swifter.in @@ -2,35 +2,35 @@ 0 39.476926408897625196 0.0 0.0 0.0 0.0 0.0 0.0 -1 6.5537098095653139645e-06 0.0014751243077781048702 +1 6.5537098095653139645e-06 0.0014751234419554511911 1.6306381826061645943e-05 -0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 --4.2340114788918336805 10.486553514018327622 1.2453138107251555947 -2 9.663313399581537916e-05 0.006759104275397271956 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 +2 9.663313399581537916e-05 0.00675908960945781479 4.0453784346544178454e-05 --0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 -0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 -3 0.000120026935827952453094 0.010044787321379672528 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 +3 0.000120026935827952453094 0.010044837538502923644 4.25875607065040958e-05 -0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 -5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 -4 1.2739802010675941456e-05 0.007246743835971885302 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 +4 1.2739802010675941456e-05 0.0072467236860282326973 2.265740805092889601e-05 --1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 --1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 -5 0.037692251088985676735 0.35527126534549128905 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 +5 0.037692251088985676735 0.35527094075555771578 0.00046732617030490929307 -4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 -1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 -6 0.011285899820091272997 0.4376527512949726007 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 +6 0.011285899820091272997 0.43765464106459166412 0.00038925687730393611812 -6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 -1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 -7 0.0017236589478267730203 0.4695362423191493196 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 +7 0.0017236589478267730203 0.46956055286931676728 0.00016953449859497231466 -14.856082147529010129 13.007589275314199284 -0.14417795763685259391 --0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 -8 0.0020336100526728302319 0.7812870996943599397 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 +8 0.0020336100526728302319 0.7813163071687303693 0.000164587904124493665 -29.55744967800954015 -4.629377558152945049 -0.58590957207831262377 -0.17162147939801157335 1.1422848961108499101 -0.027445465472921385952 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/whm_gr_test/pl.swiftest.in b/examples/whm_gr_test/pl.swiftest.in index 9d49cc3da..10d425453 100644 --- a/examples/whm_gr_test/pl.swiftest.in +++ b/examples/whm_gr_test/pl.swiftest.in @@ -1,33 +1,33 @@ 8 1 6.5537098095653139645e-06 1.6306381826061645943e-05 -0.33206272695596028566 0.07436707001147663254 -0.02438290851908785084 --4.2340114788918336805 10.486553514018327622 1.2453138107251555947 +0.13267502226188271353 0.2786606257975073886 0.010601098875389479426 +-11.331978934667442676 4.8184460126705647045 1.4332264599878684131 2 9.663313399581537916e-05 4.0453784346544178454e-05 --0.7188115337296047125 -0.0118554711069603201795 0.041316403191083782287 -0.07826338813583945357 -7.419533988988633545 -0.10634201014368884618 +-0.69398700025820403425 -0.19235393648106968723 0.03740673057980103272 +1.9245789988923785786 -7.1528261190002948057 -0.20922405362759749996 3 0.000120026935827952453094 4.25875607065040958e-05 -0.35677088372527121507 -0.95189300879814897627 4.4027442504036787155e-05 -5.7819217550992820422 2.18192814489641851 -0.00012230072278352209966 +0.49463573470256239073 -0.8874896493821613497 4.051630875713834232e-05 +5.386704768180099809 3.0357508899436080915 -0.00016218409216515533796 4 1.2739802010675941456e-05 2.265740805092889601e-05 --1.5233712071242269115 0.6723825347339112968 0.051459143378398922164 --1.8728417739956807141 -4.239719661832373223 -0.042909557750301418264 +-1.5655322071100350456 0.56626121192188216824 0.050269397991054412533 +-1.5477080637857006753 -4.370087697214287981 -0.05361768768801557225 5 0.037692251088985676735 0.00046732617030490929307 -4.049944927347420176 -2.9910878677758190314 -0.078187280837353656526 -1.6060801375519682711 2.349356876761497338 -0.045690062807172619064 +4.0891378954287338487 -2.9329188614380639066 -0.07930573161132697946 +1.575024788882753283 2.3719591091996699917 -0.045089307261129988257 6 0.011285899820091272997 0.00038925687730393611812 -6.298929503477405767 -7.706413024510769816 -0.11669919842191249504 -1.4661378456572359413 1.2872251175075805794 -0.08070991686100478242 +6.3349788609660162564 -7.674600716671800882 -0.11868650931385750502 +1.4598618704191345578 1.2948691245181617393 -0.080593167691228835176 7 0.0017236589478267730203 0.00016953449859497231466 -14.856082147529010129 13.007589275314199284 -0.14417795763685259391 --0.9554310497290159123 1.0161753499437922057 0.016099529164307530124 +14.832516206189200858 13.032608531076540714 -0.14378102535616668622 +-0.9573374666934839659 1.014553546383260322 0.016118112341773867214 8 0.0020336100526728302319 0.000164587904124493665 -29.55744967800954015 -4.629377558152945049 -0.58590957207831262377 -0.17162147939801157335 1.1422848961108499101 -0.027445465472921385952 +29.561664938083289655 -4.6012285192418387325 -0.586585578731106283 +0.17051705220469790965 1.1424784769020628332 -0.027423757798549895085 diff --git a/examples/whm_gr_test/swiftest_relativity.ipynb b/examples/whm_gr_test/swiftest_relativity.ipynb index 0d8111fea..53c4e5453 100644 --- a/examples/whm_gr_test/swiftest_relativity.ipynb +++ b/examples/whm_gr_test/swiftest_relativity.ipynb @@ -22,9 +22,9 @@ "output_type": "stream", "text": [ "Reading Swifter file param.swifter.in\n", - "Reading in time 1.000e+02\n", + "Reading in time 1.000e+03\n", "Creating Dataset\n", - "Successfully converted 101 output frames.\n", + "Successfully converted 1001 output frames.\n", "Swifter simulation data stored as xarray DataSet .ds\n" ] } @@ -45,9 +45,9 @@ "output_type": "stream", "text": [ "Reading Swiftest file param.swiftest.in\n", - "Reading in time 1.000e+02\n", + "Reading in time 1.000e+03\n", "Creating Dataset\n", - "Successfully converted 101 output frames.\n", + "Successfully converted 1001 output frames.\n", "Swiftest simulation data stored as xarray DataSet .ds\n" ] } @@ -70,12 +70,12 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "obj = Horizons(id='1', id_type='majorbody',location='@sun',\n", - " epochs={'start':'2021-01-28', 'stop':'2121-02-05',\n", + " epochs={'start':'2021-01-28', 'stop':'3021-02-05',\n", " 'step':'1y'})\n", "el = obj.elements()\n", "t = (el['datetime_jd']-el['datetime_jd'][0]) / 365.25\n", @@ -84,7 +84,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "metadata": {}, "outputs": [], "source": [ @@ -95,7 +95,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "metadata": {}, "outputs": [], "source": [ @@ -106,7 +106,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "metadata": {}, "outputs": [ { @@ -114,17 +114,17 @@ "output_type": "stream", "text": [ "Mean precession rate for Mercury long. peri. (arcsec/100 y)\n", - "JPL Horizons : 573.8351991142854\n", - "Swifter GR : 579.5897815748845\n", - "Swiftest GR : 579.5897815748845\n", - "Obs - Swifter : -5.754582460598964\n", - "Obs - Swiftest : -5.754582460598964\n", - "Swiftest - Swifter: 0.0\n" + "JPL Horizons : 571.3210506300043\n", + "Swifter GR : 571.6183105524942\n", + "Swiftest GR : 571.6183105392645\n", + "Obs - Swifter : -0.2972599224899675\n", + "Obs - Swiftest : -0.29725990926022927\n", + "Swiftest - Swifter: -1.3229737305664457e-08\n" ] }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -153,6 +153,13 @@ "print(f'Swiftest - Swifter: {np.mean(dvarpi_swiftest - dvarpi_swifter)}')" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, { "cell_type": "code", "execution_count": null, From b22433539be49c418cbb9d7202aa1b24605cacf6 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 17:07:33 -0400 Subject: [PATCH 16/33] Added new setup classes for SyMBA data structures --- src/modules/helio_classes.f90 | 8 +-- src/modules/symba_classes.f90 | 24 +++++++- src/symba/symba_setup.f90 | 105 ++++++++++++++++++++++++++++------ src/symba/symba_step.f90 | 49 ++++++++++++++++ 4 files changed, 163 insertions(+), 23 deletions(-) diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index ae0de83a7..ae2693167 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -156,10 +156,10 @@ end subroutine helio_step_pl module subroutine helio_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Simulation time - real(DP), intent(in) :: dt !! Current stepsize + class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine helio_step_system module subroutine helio_step_tp(self, system, param, t, dt) diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 306153379..8b33960cb 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -116,6 +116,8 @@ module symba_classes integer(I4B), dimension(:), allocatable :: level !! encounter recursion level integer(I4B), dimension(:), allocatable :: index1 !! position of the planet in encounter integer(I4B), dimension(:), allocatable :: index2 !! position of the test particle in encounter + contains + procedure, public :: setup => symba_setup_pltpenc !! A constructor that sets the number of encounters and allocates and initializes all arrays end type symba_pltpenc !******************************************************************************************************************************** @@ -127,6 +129,8 @@ module symba_classes real(DP), dimension(:,:), allocatable :: xh2 !! the heliocentric position of parent 2 in encounter real(DP), dimension(:,:), allocatable :: vb1 !! the barycentric velocity of parent 1 in encounter real(DP), dimension(:,:), allocatable :: vb2 !! the barycentric velocity of parent 2 in encounter + contains + procedure, public :: setup => symba_setup_plplenc !! A constructor that sets the number of encounters and allocates and initializes all arrays end type symba_plplenc !******************************************************************************************************************************** @@ -145,7 +149,8 @@ module symba_classes procedure, public :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step procedure, public :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system procedure, public :: recursive_step => symba_step_recur_system !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current - !! recursion level, if applicable, and descend to the next deeper level if necessarye + !! recursion level, if applicable, and descend to the next deeper level if necessary + procedure, public :: reset => symba_step_reset_system !! Resets pl, tp,and encounter structures at the start of a new step end type symba_nbody_system interface @@ -242,6 +247,18 @@ module subroutine symba_setup_pl(self,n) integer(I4B), intent(in) :: n !! Number of massive bodies to allocate end subroutine symba_setup_pl + module subroutine symba_setup_pltpenc(self,n) + implicit none + class(symba_pltpenc), intent(inout) :: self !! Symba pl-tp encounter structure + integer, intent(in) :: n !! Number of encounters to allocate space for + end subroutine symba_setup_pltpenc + + module subroutine symba_setup_plplenc(self,n) + implicit none + class(symba_plplenc), intent(inout) :: self !! Symba pl-tp encounter structure + integer, intent(in) :: n !! Number of encounters to allocate space for + end subroutine symba_setup_plplenc + module subroutine symba_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none @@ -280,5 +297,10 @@ module recursive subroutine symba_step_recur_system(self, param, t, dt) real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_recur_system + + module subroutine symba_step_reset_system(self) + implicit none + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + end subroutine symba_step_reset_system end interface end module symba_classes \ No newline at end of file diff --git a/src/symba/symba_setup.f90 b/src/symba/symba_setup.f90 index 6449013dd..5a56e1b79 100644 --- a/src/symba/symba_setup.f90 +++ b/src/symba/symba_setup.f90 @@ -12,14 +12,84 @@ module subroutine symba_setup_pl(self,n) class(symba_pl), intent(inout) :: self !! SyMBA test particle object integer(I4B), intent(in) :: n !! Number of massive bodies to allocate ! Internals - integer(I4B) :: i,j + integer(I4B) :: i !> Call allocation method for parent class - !call helio_setup_pl(self, n) call setup_pl(self, n) if (n <= 0) return + allocate(self%lcollision(n)) + allocate(self%lencounter(n)) + allocate(self%nplenc(n)) + allocate(self%ntpenc(n)) + allocate(self%levelg(n)) + allocate(self%levelm(n)) + allocate(self%isperi(n)) + allocate(self%peri(n)) + allocate(self%atp(n)) + allocate(self%kin(n)) + allocate(self%info(n)) + + self%lcollision(:) = .false. + self%lencounter(:) = .false. + self%nplenc(:) = 0 + self%ntpenc(:) = 0 + self%levelg(:) = -1 + self%levelm(:) = -1 + self%isperi(:) = 0 + self%peri(:) = 0.0_DP + self%atp(:) = 0.0_DP + self%kin(:)%nchild = 0 + self%kin(:)%parent = [(i, i=1, n)] + return + end subroutine symba_setup_pl + + module subroutine symba_setup_pltpenc(self,n) + !! author: David A. Minton + !! + !! A constructor that sets the number of encounters and allocates and initializes all arrays + !! + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! Symba pl-tp encounter structure + integer, intent(in) :: n !! Number of encounters to allocate space for + + self%nenc = n + if (n == 0) return + allocate(self%lvdotr(n)) + allocate(self%status(n)) + allocate(self%level(n)) + allocate(self%index1(n)) + allocate(self%index2(n)) + self%lvdotr(:) = .false. + self%status(:) = INACTIVE + self%level(:) = -1 + self%index1(:) = 0 + self%index2(:) = 0 + return + end subroutine symba_setup_pltpenc + + module subroutine symba_setup_plplenc(self,n) + !! author: David A. Minton + !! + !! A constructor that sets the number of encounters and allocates and initializes all arrays + ! + implicit none + ! Arguments + class(symba_plplenc), intent(inout) :: self !! Symba pl-tp encounter structure + integer, intent(in) :: n !! Number of encounters to allocate space for + + call symba_setup_pltpenc(self, n) + if (n == 0) return + allocate(self%xh1(NDIM,n)) + allocate(self%xh2(NDIM,n)) + allocate(self%vb1(NDIM,n)) + allocate(self%vb2(NDIM,n)) + self%xh1(:,:) = 0.0_DP + self%xh2(:,:) = 0.0_DP + self%vb1(:,:) = 0.0_DP + self%vb2(:,:) = 0.0_DP return - end subroutine symba_setup_pl + end subroutine symba_setup_plplenc module subroutine symba_setup_system(self, param) !! author: David A. Minton @@ -34,20 +104,14 @@ module subroutine symba_setup_system(self, param) integer(I4B) :: i, j ! Call parent method - call whm_setup_system(self, param) - - select type(pl => self%pl) - class is(symba_pl) - select type(cb => self%cb) - class is (symba_cb) - select type (tp => self%tp) - class is (symba_tp) - - - end select - end select - end select - + associate(system => self) + call whm_setup_system(system, param) + call system%mergeadd_list%setup(1) + call system%mergesub_list%setup(1) + call system%pltpenc_list%setup(1) + call system%plplenc_list%setup(1) + end associate + return end subroutine symba_setup_system module subroutine symba_setup_tp(self,n) @@ -62,9 +126,14 @@ module subroutine symba_setup_tp(self,n) integer, intent(in) :: n !! Number of test particles to allocate !> Call allocation method for parent class - !call helio_setup_tp(self, n) call setup_tp(self, n) if (n <= 0) return + allocate(self%nplenc(n)) + allocate(self%levelg(n)) + allocate(self%levelm(n)) + self%nplenc(:) = 0 + self%levelg(:) = -1 + self%levelm(:) = -1 return end subroutine symba_setup_tp diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index 43d11125c..3ddde3377 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -54,6 +54,7 @@ module subroutine symba_step_interp_system(self, param, t, dt) dth = 0.5_DP * dt associate(system => self) + call system%reset() select type(pl => system%pl) class is (symba_pl) select type(tp => system%tp) @@ -115,4 +116,52 @@ module recursive subroutine symba_step_recur_system(self, param, t, dt) !associate() end subroutine symba_step_recur_system + module subroutine symba_step_reset_system(self) + !! author: David A. Minton + !! + !! Resets pl, tp,and encounter structures at the start of a new step + !! + implicit none + ! Arguments + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + ! Internals + integer(I4B) :: i + + associate(system => self, pltpenc_list => self%pltpenc_list, plplenc_list => self%plplenc_list, mergeadd_list => self%mergeadd_list, mergesub_list => self%mergesub_list) + select type(pl => system%pl) + class is (symba_pl) + select type(tp => system%tp) + class is (symba_tp) + system%irec = -1 + pl%lcollision(:) = .false. + pl%kin(:)%parent = [(i, i=1, pl%nbody)] + pl%kin(:)%nchild = 0 + do i = 1, pl%nbody + if (allocated(pl%kin(i)%child)) deallocate(pl%kin(i)%child) + end do + pl%nplenc(:) = 0 + pl%ntpenc(:) = 0 + pl%levelg(:) = 0 + pl%levelm(:) = 0 + pl%lencounter = .false. + pl%lcollision = .false. + + tp%nplenc(:) = 0 + tp%levelg(:) = 0 + tp%levelm(:) = 0 + + plplenc_list%nenc = 0 + pltpenc_list%nenc = 0 + + mergeadd_list%nbody = 0 + mergesub_list%nbody = 0 + end select + end select + end associate + + + end subroutine symba_step_reset_system + + + end submodule s_symba_step From 1ae0953bff97515ac98774fac7c5748768bc5e0c Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 17:48:11 -0400 Subject: [PATCH 17/33] Began developing encounter checks for SyMBA --- src/modules/rmvs_classes.f90 | 6 +++++ src/modules/symba_classes.f90 | 11 ++++---- src/rmvs/rmvs_encounter_check.f90 | 2 +- src/symba/symba_step.f90 | 45 +++++++++++++++++++++---------- 4 files changed, 44 insertions(+), 20 deletions(-) diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index a523e8643..bf2a0cebd 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -98,6 +98,12 @@ module rmvs_classes end type rmvs_pl interface + module elemental function rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) result(lflag) + implicit none + real(DP), intent(in) :: r2, v2, vdotr, dt, r2crit + logical :: lflag + end function rmvs_chk_ind + module subroutine rmvs_discard_tp(self, system, param) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 8b33960cb..9e3ae30e4 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -6,12 +6,13 @@ module symba_classes use swiftest_globals use swiftest_classes, only : swiftest_parameters, swiftest_base use helio_classes, only : helio_cb, helio_pl, helio_tp, helio_nbody_system + use rmvs_classes, only : rmvs_chk_ind implicit none !integer(I4B), parameter :: NENMAX = 32767 - !integer(I4B), parameter :: NTENC = 3 - !real(DP), parameter :: RHSCALE = 6.5_DP - !real(DP), parameter :: RSHELL = 0.48075_DP + integer(I4B), private, parameter :: NTENC = 3 + real(DP), private, parameter :: RHSCALE = 6.5_DP + real(DP), private, parameter :: RSHELL = 0.48075_DP character(*), parameter :: PARTICLE_OUTFILE = 'particle.dat' integer(I4B), parameter :: PARTICLEUNIT = 44 !! File unit number for the binary particle info output file @@ -142,7 +143,6 @@ module symba_classes class(symba_pltpenc), allocatable :: pltpenc_list !! List of massive body-test particle encounters in a single step class(symba_plplenc), allocatable :: plplenc_list !! List of massive body-massive body encounters in a single step class(symba_pl), allocatable :: pl_discards !! Discarded test particle data structure - integer(I4B) :: irec !! Recursion level contains private procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps @@ -290,12 +290,13 @@ module subroutine symba_step_interp_system(self, param, t, dt) real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_interp_system - module recursive subroutine symba_step_recur_system(self, param, t, dt) + module recursive subroutine symba_step_recur_system(self, param, t, dt, ireci) implicit none class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize + integer(I4B), value, intent(in) :: ireci !! input recursion level end subroutine symba_step_recur_system module subroutine symba_step_reset_system(self) diff --git a/src/rmvs/rmvs_encounter_check.f90 b/src/rmvs/rmvs_encounter_check.f90 index bead4c21b..64b5b59d9 100644 --- a/src/rmvs/rmvs_encounter_check.f90 +++ b/src/rmvs/rmvs_encounter_check.f90 @@ -46,7 +46,7 @@ module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) return end function rmvs_encounter_check_tp - elemental function rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) result(lflag) + module elemental function rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) result(lflag) !! author: David A. Minton !! !! Determine whether a test particle and planet are having or will have an encounter within the next time step diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index 3ddde3377..9830e3704 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -18,6 +18,7 @@ module subroutine symba_step_system(self, param, t, dt) ! Internals logical :: lencounter_pl, lencounter_tp, lencounter + call self%reset() select type(pl => self%pl) class is (symba_pl) select type(tp => self%tp) @@ -45,16 +46,16 @@ module subroutine symba_step_interp_system(self, param, t, dt) !! Adapted from Hal Levison's Swift routine symba5_step_interp.f implicit none ! Arguments - class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Simulation time - real(DP), intent(in) :: dt !! Current stepsize - ! Internals - real(DP) :: dth + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize + ! Internals + real(DP) :: dth !! Half step size + integer(I4B) :: irec !! Recursion level dth = 0.5_DP * dt associate(system => self) - call system%reset() select type(pl => system%pl) class is (symba_pl) select type(tp => system%tp) @@ -73,12 +74,10 @@ module subroutine symba_step_interp_system(self, param, t, dt) call pl%kick(dth) call tp%kick(dth) - system%irec = -1 call pl%drift(system, param, dt, pl%status(:) == ACTIVE) call tp%drift(system, param, dt, tp%status(:) == ACTIVE) - system%irec = 0 - - call system%recursive_step(param, t, dt) + irec = 0 + call system%recursive_step(param, t, dt, irec) call pl%set_beg_end(xend = pl%xh) call pl%accel(system, param, t + dt) @@ -98,7 +97,7 @@ module subroutine symba_step_interp_system(self, param, t, dt) return end subroutine symba_step_interp_system - module recursive subroutine symba_step_recur_system(self, param, t, dt) + module recursive subroutine symba_step_recur_system(self, param, t, dt, ireci) !! author: David A. Minton !! !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current @@ -112,8 +111,27 @@ module recursive subroutine symba_step_recur_system(self, param, t, dt) class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Simulation time real(DP), intent(in) :: dt !! Current stepsize + integer(I4B), value, intent(in) :: ireci !! input recursion level ! Internals - !associate() + integer(I4B) :: i, j, irecp, icflg, index_i, index_j, index_pl, index_tp + real(DP) :: dtl, dth,sgn + + associate(plplenc_list => self%plplenc_list, pltpenc_list => self%pltpenc_list) + dtl = param%dt / (NTENC**ireci) + dth = 0.5_DP * dtl + IF (dtl / param%dt < VSMALL) THEN + WRITE(*, *) "SWIFTEST Warning:" + WRITE(*, *) " In symba_step_recur_system, local time step is too small" + WRITE(*, *) " Roundoff error will be important!" + call util_exit(FAILURE) + END IF + irecp = ireci + 1 + if (ireci == 0) then + icflg = 0 + + end if + end associate + end subroutine symba_step_recur_system module subroutine symba_step_reset_system(self) @@ -132,7 +150,6 @@ module subroutine symba_step_reset_system(self) class is (symba_pl) select type(tp => system%tp) class is (symba_tp) - system%irec = -1 pl%lcollision(:) = .false. pl%kin(:)%parent = [(i, i=1, pl%nbody)] pl%kin(:)%nchild = 0 From 4c0dd0c7ec124a03b05db78fa5a2d5ddbe82a74c Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 18:27:42 -0400 Subject: [PATCH 18/33] More work on encounters --- src/eucl/eucl.f90 | 20 ++++++++++---------- src/modules/symba_classes.f90 | 5 ++++- src/symba/symba_encounter_check.f90 | 25 +++++++++++++++++++++++-- src/symba/symba_setup.f90 | 8 ++++++++ src/symba/symba_step.f90 | 2 +- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 index 519a38d76..e17aadd4d 100644 --- a/src/eucl/eucl.f90 +++ b/src/eucl/eucl.f90 @@ -14,22 +14,22 @@ module subroutine eucl_dist_index_plpl(self) ! Arguments class(swiftest_pl), intent(inout) :: self !! Swiftest massive body objec ! Internals - integer(I4B) :: i, j, k, kp, p + integer(I8B) :: i, j, counter, npl - associate(npl => self%nbody, num_comparisons => self%num_comparisons, k_eucl => self%k_eucl) + npl = int(self%nbody, kind=I8B) + associate(num_comparisons => self%num_comparisons, k_eucl => self%k_eucl) num_comparisons = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column if (allocated(self%k_eucl)) deallocate(self%k_eucl) ! Reset the index array if it's been set previously if (allocated(self%irij3)) deallocate(self%irij3) allocate(self%k_eucl(2, num_comparisons)) allocate(self%irij3(num_comparisons)) - !do concurrent(k = 1:num_comparisons) !shared(num_comparisons, k_eucl, npl) local(kp, i, j, p) - do k = 1, num_comparisons - kp = npl * (npl - 1) / 2 - k - p = floor((sqrt(1._DP + 8 * kp) - 1._DP) / 2._DP) - i = k - (npl - 1) * (npl - 2) / 2 + p * (p + 1) / 2 + 1 - j = npl - 1 - p - k_eucl(1, k) = i - k_eucl(2, k) = j + do i = 1, npl + counter = (i - 1_I8B) * npl - i * (i - 1_I8B) / 2_I8B + 1_I8B + do j = i + 1_I8B, npl + self%k_eucl(1, counter) = i + self%k_eucl(2, counter) = j + counter = counter + 1_I8B + end do end do end associate return diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 9e3ae30e4..471019127 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -75,6 +75,8 @@ module symba_classes type, public, extends(helio_pl) :: symba_pl logical, dimension(:), allocatable :: lcollision !! flag indicating whether body has merged with another this time step logical, dimension(:), allocatable :: lencounter !! flag indicating whether body is part of an encounter this time step + logical, dimension(:), allocatable :: lmtiny !! flag indicating whether this body is below the MTINY cutoff value + integer(I4B) :: nplm !! number of bodies above the MTINY limit integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with other planets this time step integer(I4B), dimension(:), allocatable :: ntpenc !! number of encounters with test particles this time step integer(I4B), dimension(:), allocatable :: levelg !! level at which this body should be moved @@ -170,12 +172,13 @@ module subroutine symba_discard_tp(self, system, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine symba_discard_tp - module function symba_encounter_check_pl(self, system, dt) result(lencounter) + module function symba_encounter_check_pl(self, system, dt, irec) result(lencounter) implicit none class(symba_pl), intent(inout) :: self !! SyMBA test particle object class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object real(DP), intent(in) :: dt !! step size logical :: lencounter !! Returns true if there is at least one close encounter + integer(I4B), intent(in) :: irec !! Current recursion level end function symba_encounter_check_pl module function symba_encounter_check_tp(self, system, dt) result(lencounter) diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 index ce4b53dff..c6151e788 100644 --- a/src/symba/symba_encounter_check.f90 +++ b/src/symba/symba_encounter_check.f90 @@ -1,16 +1,37 @@ submodule (symba_classes) s_symba_encounter_check use swiftest contains - module function symba_encounter_check_pl(self, system, dt) result(lencounter) + module function symba_encounter_check_pl(self, system, dt, irec) result(lencounter) implicit none ! Arguments class(symba_pl), intent(inout) :: self !! SyMBA test particle object class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level ! Result logical :: lencounter !! Returns true if there is at least one close encounter + ! Internals + integer(I4B) :: i, j + real(DP) :: r2, v2, vdotr + real(DP), dimension(NDIM) :: xr, vr + real(DP) :: rcrit, r2crit + logical :: lflag - lencounter = .false. + associate(pl => self, npl => self%nbody) + lencounter = .false. + do concurrent(j = 1:npl, pl%lminty(j)) + do i = 1, npl + rcrit = (pl%rhill(i) + pl%rhill(j)) * RHSCALE * (RSHELL**(irec)) + r2crit = r2crit**2 + xr(:) = pl%xh(:, j) - pl%xh(:, i) + vr(:) = pl%vh(:, j) - pl%vh(:, i) + v2 = dot_product(vr(:), vr(:)) + vdotr = dot_product(vr(:), xr(:)) + lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) + if (lflag) lencounter = .true. + end do + end do + end associate return end function symba_encounter_check_pl diff --git a/src/symba/symba_setup.f90 b/src/symba/symba_setup.f90 index 5a56e1b79..94921f767 100644 --- a/src/symba/symba_setup.f90 +++ b/src/symba/symba_setup.f90 @@ -110,6 +110,14 @@ module subroutine symba_setup_system(self, param) call system%mergesub_list%setup(1) call system%pltpenc_list%setup(1) call system%plplenc_list%setup(1) + select type(pl => system%pl) + class is (symba_pl) + select type(param) + class is (symba_parameters) + pl%lmtiny(:) = pl%Gmass(:) > param%MTINY + pl%nplm = count(pl%lmtiny(:)) + end select + end select end associate return end subroutine symba_setup_system diff --git a/src/symba/symba_step.f90 b/src/symba/symba_step.f90 index 9830e3704..631c8c087 100644 --- a/src/symba/symba_step.f90 +++ b/src/symba/symba_step.f90 @@ -23,7 +23,7 @@ module subroutine symba_step_system(self, param, t, dt) class is (symba_pl) select type(tp => self%tp) class is (symba_tp) - lencounter = pl%encounter_check(self, dt) .or. tp%encounter_check(self, dt) + lencounter = pl%encounter_check(self, dt, 0) .or. tp%encounter_check(self, dt) if (lencounter) then call self%interp(param, t, dt) else From 2a2700f7c08222fa5463f1b9665052710f87ca09 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 20:43:51 -0400 Subject: [PATCH 19/33] Fixed typo --- src/symba/symba_encounter_check.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 index c6151e788..fc38cce69 100644 --- a/src/symba/symba_encounter_check.f90 +++ b/src/symba/symba_encounter_check.f90 @@ -19,7 +19,7 @@ module function symba_encounter_check_pl(self, system, dt, irec) result(lencount associate(pl => self, npl => self%nbody) lencounter = .false. - do concurrent(j = 1:npl, pl%lminty(j)) + do concurrent(j = 1:npl, pl%lmtiny(j)) do i = 1, npl rcrit = (pl%rhill(i) + pl%rhill(j)) * RHSCALE * (RSHELL**(irec)) r2crit = r2crit**2 From 2107b343783edd2aaa68c7dc6a19a8b45b8f073c Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 20:44:43 -0400 Subject: [PATCH 20/33] Flipped boolean to correct condition --- src/symba/symba_encounter_check.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 index fc38cce69..4e71bf648 100644 --- a/src/symba/symba_encounter_check.f90 +++ b/src/symba/symba_encounter_check.f90 @@ -19,7 +19,7 @@ module function symba_encounter_check_pl(self, system, dt, irec) result(lencount associate(pl => self, npl => self%nbody) lencounter = .false. - do concurrent(j = 1:npl, pl%lmtiny(j)) + do concurrent(j = 1:npl, .not.pl%lmtiny(j)) do i = 1, npl rcrit = (pl%rhill(i) + pl%rhill(j)) * RHSCALE * (RSHELL**(irec)) r2crit = r2crit**2 From 95af4879534d78b60ffc94639b9a745737b114c8 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 23:18:40 -0400 Subject: [PATCH 21/33] Moved initialize_system from io to setup where it belongs --- src/io/io.f90 | 20 ------------------ src/modules/swiftest_classes.f90 | 32 ++++++++++++++--------------- src/setup/setup.f90 | 23 ++++++++++++++++++++- src/symba/symba_encounter_check.f90 | 8 ++++---- src/whm/whm_setup.f90 | 2 +- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/io/io.f90 b/src/io/io.f90 index e74255466..cf4772a8f 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -976,26 +976,6 @@ function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) return end function io_read_hdr - module subroutine io_read_initialize_system(self, param) - !! author: David A. Minton - !! - !! Wrapper method to initialize a basic Swiftest nbody system from files - !! - implicit none - ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - - call self%cb%initialize(param) - call self%pl%initialize(param) - if (.not.param%lrhill_present) call self%pl%set_rhill(self%cb) - call self%tp%initialize(param) - call self%set_msys() - call self%pl%set_mu(self%cb) - call self%tp%set_mu(self%cb) - - end subroutine io_read_initialize_system - module subroutine io_toupper(string) !! author: David A. Minton !! diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index d07f39f5a..85986fec4 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -11,12 +11,12 @@ module swiftest_classes public :: eucl_dist_index_plpl, eucl_dist_index_pltp, eucl_irij3_plpl public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & - io_read_cb_in, io_read_param_in, io_read_frame_body, io_read_frame_cb, io_read_frame_system, io_read_initialize_system, & + io_read_cb_in, io_read_param_in, io_read_frame_body, io_read_frame_cb, io_read_frame_system, & io_toupper, io_write_discard, io_write_encounter, io_write_frame_body, io_write_frame_cb, io_write_frame_system public :: kickvh_body public :: obl_acc_body, obl_acc_pl, obl_acc_tp public :: orbel_el2xv_vec, orbel_xv2el_vec, orbel_scget, orbel_xv2aeq, orbel_xv2aqt - public :: setup_body, setup_construct_system, setup_pl, setup_tp + public :: setup_body, setup_construct_system, setup_initialize_system, setup_pl, setup_tp public :: tides_getacch_pl, tides_step_spin_system public :: user_getacch_body public :: util_coord_b2h_pl, util_coord_b2h_tp, util_coord_h2b_pl, util_coord_h2b_tp, util_exit, util_fill_body, util_fill_pl, util_fill_tp, & @@ -288,14 +288,14 @@ module swiftest_classes procedure(abstract_step_system), public, deferred :: step ! Concrete classes that are common to the basic integrator (only test particles considered for discard) - procedure, public :: discard => discard_system !! Perform a discard step on the system - procedure, public :: dump => io_dump_system !! Dump the state of the system to a file - procedure, public :: initialize => io_read_initialize_system !! Initialize the system from an input file - procedure, public :: read_frame => io_read_frame_system !! Append a frame of output data to file - procedure, public :: write_discard => io_write_discard !! Append a frame of output data to file - procedure, public :: write_frame => io_write_frame_system !! Append a frame of output data to file - procedure, public :: step_spin => tides_step_spin_system !! Steps the spins of the massive & central bodies due to tides. - procedure, public :: set_msys => util_set_msys !! Sets the value of msys from the masses of system bodies. + procedure, public :: discard => discard_system !! Perform a discard step on the system + procedure, public :: dump => io_dump_system !! Dump the state of the system to a file + procedure, public :: initialize => setup_initialize_system !! Initialize the system from input files + procedure, public :: read_frame => io_read_frame_system !! Append a frame of output data to file + procedure, public :: write_discard => io_write_discard !! Append a frame of output data to file + procedure, public :: write_frame => io_write_frame_system !! Append a frame of output data to file + procedure, public :: step_spin => tides_step_spin_system !! Steps the spins of the massive & central bodies due to tides. + procedure, public :: set_msys => util_set_msys !! Sets the value of msys from the masses of system bodies. end type swiftest_nbody_system abstract interface @@ -565,12 +565,6 @@ module subroutine io_read_frame_system(self, iu, param, form, ierr) integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_system - module subroutine io_read_initialize_system(self, param) - implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - end subroutine io_read_initialize_system - module subroutine io_write_discard(self, param) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object @@ -680,6 +674,12 @@ module subroutine setup_construct_system(system, param) type(swiftest_parameters), intent(in) :: param !! Swiftest parameters end subroutine setup_construct_system + module subroutine setup_initialize_system(self, param) + implicit none + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + end subroutine setup_initialize_system + module subroutine setup_pl(self,n) implicit none class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index dab78a875..0c89d613b 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -69,6 +69,28 @@ module subroutine setup_construct_system(system, param) return end subroutine setup_construct_system + + module subroutine setup_initialize_system(self, param) + !! author: David A. Minton + !! + !! Wrapper method to initialize a basic Swiftest nbody system from files + !! + implicit none + ! Arguments + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + + call self%cb%initialize(param) + call self%pl%initialize(param) + if (.not.param%lrhill_present) call self%pl%set_rhill(self%cb) + call self%tp%initialize(param) + call self%set_msys() + call self%pl%set_mu(self%cb) + call self%tp%set_mu(self%cb) + call self%pl%eucl_index() + return + end subroutine setup_initialize_system + module subroutine setup_body(self,n) !! author: David A. Minton !! @@ -83,7 +105,6 @@ module subroutine setup_body(self,n) if (n <= 0) return self%lfirst = .true. - !write(*,*) 'Allocating the basic Swiftest particle' allocate(self%id(n)) allocate(self%name(n)) allocate(self%status(n)) diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 index 4e71bf648..633973dba 100644 --- a/src/symba/symba_encounter_check.f90 +++ b/src/symba/symba_encounter_check.f90 @@ -19,8 +19,8 @@ module function symba_encounter_check_pl(self, system, dt, irec) result(lencount associate(pl => self, npl => self%nbody) lencounter = .false. - do concurrent(j = 1:npl, .not.pl%lmtiny(j)) - do i = 1, npl + !do concurrent(j = 1:npl, .not.pl%lmtiny(j)) + ! do i = 1, npl rcrit = (pl%rhill(i) + pl%rhill(j)) * RHSCALE * (RSHELL**(irec)) r2crit = r2crit**2 xr(:) = pl%xh(:, j) - pl%xh(:, i) @@ -29,8 +29,8 @@ module function symba_encounter_check_pl(self, system, dt, irec) result(lencount vdotr = dot_product(vr(:), xr(:)) lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) if (lflag) lencounter = .true. - end do - end do + ! end do + !end do end associate return end function symba_encounter_check_pl diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 index 50f0618bb..1f098df26 100644 --- a/src/whm/whm_setup.f90 +++ b/src/whm/whm_setup.f90 @@ -81,7 +81,7 @@ module subroutine whm_setup_system(self, param) class(whm_nbody_system), intent(inout) :: self !! Swiftest system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - call io_read_initialize_system(self, param) + call setup_initialize_system(self, param) ! Make sure that the discard list gets allocated initially call self%tp_discards%setup(self%tp%nbody) call self%pl%set_mu(self%cb) From 05570b95619dd67e51ff33b433997c9b4af8af47 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Thu, 22 Jul 2021 23:23:45 -0400 Subject: [PATCH 22/33] Small changes to the plpl flattener --- src/eucl/eucl.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 index e17aadd4d..306110635 100644 --- a/src/eucl/eucl.f90 +++ b/src/eucl/eucl.f90 @@ -17,7 +17,7 @@ module subroutine eucl_dist_index_plpl(self) integer(I8B) :: i, j, counter, npl npl = int(self%nbody, kind=I8B) - associate(num_comparisons => self%num_comparisons, k_eucl => self%k_eucl) + associate(num_comparisons => self%num_comparisons) num_comparisons = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column if (allocated(self%k_eucl)) deallocate(self%k_eucl) ! Reset the index array if it's been set previously if (allocated(self%irij3)) deallocate(self%irij3) From 4836fcbb45602611036a812c2480f07b3c9dd112 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 10:10:00 -0400 Subject: [PATCH 23/33] Refactored num_comparisons to more compact nplpl, and added nplplm for the SyMBA case with MTINY bodies --- src/eucl/eucl.f90 | 10 +++++----- src/modules/swiftest_classes.f90 | 2 +- src/modules/symba_classes.f90 | 1 + src/setup/setup.f90 | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 index 306110635..09ff2eb63 100644 --- a/src/eucl/eucl.f90 +++ b/src/eucl/eucl.f90 @@ -17,12 +17,12 @@ module subroutine eucl_dist_index_plpl(self) integer(I8B) :: i, j, counter, npl npl = int(self%nbody, kind=I8B) - associate(num_comparisons => self%num_comparisons) - num_comparisons = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column + associate(nplpl => self%nplpl) + nplpl = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column if (allocated(self%k_eucl)) deallocate(self%k_eucl) ! Reset the index array if it's been set previously if (allocated(self%irij3)) deallocate(self%irij3) - allocate(self%k_eucl(2, num_comparisons)) - allocate(self%irij3(num_comparisons)) + allocate(self%k_eucl(2, nplpl)) + allocate(self%irij3(nplpl)) do i = 1, npl counter = (i - 1_I8B) * npl - i * (i - 1_I8B) / 2_I8B + 1_I8B do j = i + 1_I8B, npl @@ -61,7 +61,7 @@ module subroutine eucl_irij3_plpl(self) real(DP), dimension(NDIM) :: dx real(DP) :: rji2 - associate(k_eucl => self%k_eucl, xh => self%xh, irij3 => self%irij3, nk => self%num_comparisons) + associate(k_eucl => self%k_eucl, xh => self%xh, irij3 => self%irij3, nk => self%nplpl) do k = 1, nk i = k_eucl(1, k) j = k_eucl(2, k) diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 85986fec4..c70d3159a 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -163,7 +163,7 @@ module swiftest_classes real(DP), dimension(:), allocatable :: capm !! Mean anomaly real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) integer(I4B), dimension(:,:), allocatable :: k_eucl !! Index array used to convert flattened the body-body comparison upper triangular matrix - integer(I8B) :: num_comparisons !! Number of body-body comparisons in the flattened upper triangular matrix + integer(I8B) :: nplpl !! Number of body-body comparisons in the flattened upper triangular matrix !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the !! component list, such as setup_body and util_spill contains diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 471019127..d8fc75707 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -77,6 +77,7 @@ module symba_classes logical, dimension(:), allocatable :: lencounter !! flag indicating whether body is part of an encounter this time step logical, dimension(:), allocatable :: lmtiny !! flag indicating whether this body is below the MTINY cutoff value integer(I4B) :: nplm !! number of bodies above the MTINY limit + integer(I8B) :: nplplm !! Number of body (all massive)-body (only those above MTINY) comparisons in the flattened upper triangular matrix integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with other planets this time step integer(I4B), dimension(:), allocatable :: ntpenc !! number of encounters with test particles this time step integer(I4B), dimension(:), allocatable :: levelg !! level at which this body should be moved diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index 0c89d613b..e85f9754a 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -183,7 +183,7 @@ module subroutine setup_pl(self,n) self%k2(:) = 0.0_DP self%Q(:) = 0.0_DP self%tlag(:) = 0.0_DP - self%num_comparisons = 0 + self%nplpl = 0 return end subroutine setup_pl From 7566551b62073b901d5b113fd231a1768f188579 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 10:12:35 -0400 Subject: [PATCH 24/33] Tidying up the formatting a bit --- src/modules/symba_classes.f90 | 83 +++++++++++++++++------------------ 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index d8fc75707..1388cfbf4 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -9,18 +9,18 @@ module symba_classes use rmvs_classes, only : rmvs_chk_ind implicit none - !integer(I4B), parameter :: NENMAX = 32767 - integer(I4B), private, parameter :: NTENC = 3 - real(DP), private, parameter :: RHSCALE = 6.5_DP - real(DP), private, parameter :: RSHELL = 0.48075_DP - character(*), parameter :: PARTICLE_OUTFILE = 'particle.dat' - integer(I4B), parameter :: PARTICLEUNIT = 44 !! File unit number for the binary particle info output file + integer(I4B), private, parameter :: NENMAX = 32767 + integer(I4B), private, parameter :: NTENC = 3 + real(DP), private, parameter :: RHSCALE = 6.5_DP + real(DP), private, parameter :: RSHELL = 0.48075_DP + character(*), parameter :: PARTICLE_OUTFILE = 'particle.dat' + integer(I4B), parameter :: PARTICLEUNIT = 44 !! File unit number for the binary particle info output file type, public, extends(swiftest_parameters) :: symba_parameters - character(STRMAX) :: particle_file = PARTICLE_OUTFILE !! Name of output particle information file - real(DP) :: MTINY = -1.0_DP !! Smallest mass that is fully gravitating - integer(I4B), dimension(:), allocatable :: seed !! Random seeds - logical :: lfragmentation = .false. !! Do fragmentation modeling instead of simple merger. + character(STRMAX) :: particle_file = PARTICLE_OUTFILE !! Name of output particle information file + real(DP) :: MTINY = -1.0_DP !! Smallest mass that is fully gravitating + integer(I4B), dimension(:), allocatable :: seed !! Random seeds + logical :: lfragmentation = .false. !! Do fragmentation modeling instead of simple merger. contains private procedure, public :: reader => symba_io_param_reader @@ -32,10 +32,10 @@ module symba_classes !******************************************************************************************************************************* !> SyMBA central body particle class type, public, extends(helio_cb) :: symba_cb - real(DP) :: M0 = 0.0_DP !! Initial mass of the central body - real(DP) :: dM = 0.0_DP !! Change in mass of the central body - real(DP) :: R0 = 0.0_DP !! Initial radius of the central body - real(DP) :: dR = 0.0_DP !! Change in the radius of the central body + real(DP) :: M0 = 0.0_DP !! Initial mass of the central body + real(DP) :: dM = 0.0_DP !! Change in mass of the central body + real(DP) :: R0 = 0.0_DP !! Initial radius of the central body + real(DP) :: dR = 0.0_DP !! Change in the radius of the central body contains private end type symba_cb @@ -73,20 +73,20 @@ module symba_classes !******************************************************************************************************************************* !> SyMBA massive body class type, public, extends(helio_pl) :: symba_pl - logical, dimension(:), allocatable :: lcollision !! flag indicating whether body has merged with another this time step - logical, dimension(:), allocatable :: lencounter !! flag indicating whether body is part of an encounter this time step - logical, dimension(:), allocatable :: lmtiny !! flag indicating whether this body is below the MTINY cutoff value - integer(I4B) :: nplm !! number of bodies above the MTINY limit - integer(I8B) :: nplplm !! Number of body (all massive)-body (only those above MTINY) comparisons in the flattened upper triangular matrix - integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with other planets this time step - integer(I4B), dimension(:), allocatable :: ntpenc !! number of encounters with test particles this time step - integer(I4B), dimension(:), allocatable :: levelg !! level at which this body should be moved - integer(I4B), dimension(:), allocatable :: levelm !! deepest encounter level achieved this time step - integer(I4B), dimension(:), allocatable :: isperi !! perihelion passage flag - real(DP), dimension(:), allocatable :: peri !! perihelion distance - real(DP), dimension(:), allocatable :: atp !! semimajor axis following perihelion passage - type(symba_kinship), dimension(:), allocatable :: kin !! Array of merger relationship structures that can account for multiple pairwise mergers in a single step - type(symba_particle_info), dimension(:), allocatable :: info + logical, dimension(:), allocatable :: lcollision !! flag indicating whether body has merged with another this time step + logical, dimension(:), allocatable :: lencounter !! flag indicating whether body is part of an encounter this time step + logical, dimension(:), allocatable :: lmtiny !! flag indicating whether this body is below the MTINY cutoff value + integer(I4B) :: nplm !! number of bodies above the MTINY limit + integer(I8B) :: nplplm !! Number of body (all massive)-body (only those above MTINY) comparisons in the flattened upper triangular matrix + integer(I4B), dimension(:), allocatable :: nplenc !! number of encounters with other planets this time step + integer(I4B), dimension(:), allocatable :: ntpenc !! number of encounters with test particles this time step + integer(I4B), dimension(:), allocatable :: levelg !! level at which this body should be moved + integer(I4B), dimension(:), allocatable :: levelm !! deepest encounter level achieved this time step + integer(I4B), dimension(:), allocatable :: isperi !! perihelion passage flag + real(DP), dimension(:), allocatable :: peri !! perihelion distance + real(DP), dimension(:), allocatable :: atp !! semimajor axis following perihelion passage + type(symba_kinship), dimension(:), allocatable :: kin !! Array of merger relationship structures that can account for multiple pairwise mergers in a single step + type(symba_particle_info), dimension(:), allocatable :: info contains private procedure, public :: discard => symba_discard_pl !! Process massive body discards @@ -151,8 +151,7 @@ module symba_classes procedure, public :: initialize => symba_setup_system !! Performs SyMBA-specific initilization steps procedure, public :: step => symba_step_system !! Advance the SyMBA nbody system forward in time by one step procedure, public :: interp => symba_step_interp_system !! Perform an interpolation step on the SymBA nbody system - procedure, public :: recursive_step => symba_step_recur_system !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current - !! recursion level, if applicable, and descend to the next deeper level if necessary + procedure, public :: recursive_step => symba_step_recur_system !! Step interacting planets and active test particles ahead in democratic heliocentric coordinates at the current recursion level, if applicable, and descend to the next deeper level if necessary procedure, public :: reset => symba_step_reset_system !! Resets pl, tp,and encounter structures at the start of a new step end type symba_nbody_system @@ -241,8 +240,8 @@ module subroutine symba_io_write_frame_info(self, iu, param) use swiftest_classes, only : swiftest_parameters implicit none class(symba_particle_info), intent(in) :: self !! SyMBA particle info object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine symba_io_write_frame_info module subroutine symba_setup_pl(self,n) @@ -266,8 +265,8 @@ end subroutine symba_setup_plplenc module subroutine symba_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(symba_nbody_system), intent(inout) :: self !! SyMBA system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + class(symba_nbody_system), intent(inout) :: self !! SyMBA system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine symba_setup_system module subroutine symba_setup_tp(self,n) @@ -279,19 +278,19 @@ end subroutine symba_setup_tp module subroutine symba_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Simulation time - real(DP), intent(in) :: dt !! Current stepsize + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_system module subroutine symba_step_interp_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Simulation time - real(DP), intent(in) :: dt !! Current stepsize + class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine symba_step_interp_system module recursive subroutine symba_step_recur_system(self, param, t, dt, ireci) From 5cb07aa57e5a37ab87132a84694b919c75ab415e Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 10:13:07 -0400 Subject: [PATCH 25/33] Tidying up the formatting a bit --- src/modules/symba_classes.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index 1388cfbf4..a25304a26 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -63,9 +63,9 @@ module symba_classes !******************************************************************************************************************************* !> Class definition for the kinship relationships used in bookkeeping multiple collisions bodies in a single time step. type symba_kinship - integer(I4B) :: parent ! Index of parent particle - integer(I4B) :: nchild ! number of children in merger list - integer(I4B), dimension(:), allocatable :: child ! Index of children particles + integer(I4B) :: parent !! Index of parent particle + integer(I4B) :: nchild !! number of children in merger list + integer(I4B), dimension(:), allocatable :: child !! Index of children particles end type symba_kinship !******************************************************************************************************************************** From e47a6f1566bdec10d51b6bebaebd2f00d972fdb9 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 10:34:20 -0400 Subject: [PATCH 26/33] Converted the cross term in the WHM accelration to use the flattened array. Tests pass --- src/whm/whm_getacch.f90 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index f393bd60e..0aa438a5e 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -187,17 +187,16 @@ pure subroutine whm_getacch_ah3(pl) implicit none class(whm_pl), intent(inout) :: pl - integer(I4B) :: i, j + integer(I4B) :: k real(DP) :: rji2, irij3, faci, facj real(DP), dimension(NDIM) :: dx real(DP), dimension(:,:), allocatable :: ah3 - associate(npl => pl%nbody) + associate(npl => pl%nbody, nplpl => pl%nplpl) allocate(ah3, mold=pl%ah) ah3(:, :) = 0.0_DP - - do i = 1, npl - 1 - do j = i + 1, npl + do k = 1, nplpl + associate(i => pl%k_eucl(1, k), j => pl%k_eucl(2, k)) dx(:) = pl%xh(:, j) - pl%xh(:, i) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) @@ -205,10 +204,10 @@ pure subroutine whm_getacch_ah3(pl) facj = pl%Gmass(j) * irij3 ah3(:, i) = ah3(:, i) + facj * dx(:) ah3(:, j) = ah3(:, j) - faci * dx(:) - end do + end associate end do - do i = 1, NDIM - pl%ah(i, 1:npl) = pl%ah(i, 1:npl) + ah3(i, 1:npl) + do concurrent (k = 1:npl) + pl%ah(:, k) = pl%ah(:, k) + ah3(:, k) end do deallocate(ah3) end associate From 8070dc52710e8426d55ee40339c719e8f6502179 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 11:18:54 -0400 Subject: [PATCH 27/33] Rearranging loops for efficiency --- src/obl/obl.f90 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/obl/obl.f90 b/src/obl/obl.f90 index 8792f2399..f027908f9 100644 --- a/src/obl/obl.f90 +++ b/src/obl/obl.f90 @@ -57,8 +57,8 @@ module subroutine obl_acc_pl(self, system) cb%aobl(i) = -sum(pl%Gmass(1:npl) * pl%aobl(i, 1:npl)) / cb%Gmass end do - do i = 1, NDIM - pl%ah(i, 1:npl) = pl%ah(i, 1:npl) + pl%aobl(i, 1:npl) - cb%aobl(i) + do i = 1, npl + pl%ah(:, i) = pl%ah(:, i) + pl%aobl(:, i) - cb%aobl(:) end do end associate @@ -89,8 +89,8 @@ module subroutine obl_acc_tp(self, system) aoblcb = cb%aoblend end if - do i = 1, NDIM - tp%ah(i, 1:ntp) = tp%ah(i, 1:ntp) + tp%aobl(i, 1:ntp) - aoblcb(i) + do i = 1, ntp + tp%ah(:, i) = tp%ah(:, i) + tp%aobl(:, i) - aoblcb(:) end do end associate From 4efd05b8a06f23ac9217c27f0473419845b6961a Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 16:16:55 -0400 Subject: [PATCH 28/33] Moved interaction acceleration to the main kick submodule, as the algorithm is shared by multiple integrators --- .../swiftest_vs_swifter.ipynb | 4 +- src/eucl/eucl.f90 | 27 ------ src/helio/helio_getacch.f90 | 91 ++----------------- src/kick/kick.f90 | 72 ++++++++++++++- src/modules/swiftest_classes.f90 | 35 ++++--- src/whm/whm_getacch.f90 | 90 +++--------------- 6 files changed, 112 insertions(+), 207 deletions(-) diff --git a/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb b/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb index 82bd3d63f..7740f02c8 100644 --- a/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb +++ b/examples/whm_swifter_comparison/swiftest_vs_swifter.ipynb @@ -107,7 +107,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -167,7 +167,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 index 09ff2eb63..fb8afa131 100644 --- a/src/eucl/eucl.f90 +++ b/src/eucl/eucl.f90 @@ -20,9 +20,7 @@ module subroutine eucl_dist_index_plpl(self) associate(nplpl => self%nplpl) nplpl = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column if (allocated(self%k_eucl)) deallocate(self%k_eucl) ! Reset the index array if it's been set previously - if (allocated(self%irij3)) deallocate(self%irij3) allocate(self%k_eucl(2, nplpl)) - allocate(self%irij3(nplpl)) do i = 1, npl counter = (i - 1_I8B) * npl - i * (i - 1_I8B) / 2_I8B + 1_I8B do j = i + 1_I8B, npl @@ -49,29 +47,4 @@ module subroutine eucl_dist_index_pltp(self, pl) class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object end subroutine eucl_dist_index_pltp - module subroutine eucl_irij3_plpl(self) - !! author: Jacob R. Elliott and David A. Minton - !! - !! Efficient parallel loop-blocking algrorithm for evaluating the Euclidean distance matrix for planet-planet - implicit none - ! Arguments - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object - ! Internals - integer(I4B) :: k, i, j - real(DP), dimension(NDIM) :: dx - real(DP) :: rji2 - - associate(k_eucl => self%k_eucl, xh => self%xh, irij3 => self%irij3, nk => self%nplpl) - do k = 1, nk - i = k_eucl(1, k) - j = k_eucl(2, k) - dx(:) = xh(:, j) - xh(:, i) - rji2 = dot_product(dx(:), dx(:)) - irij3(k) = 1.0_DP / (rji2 * sqrt(rji2)) - end do - end associate - - return - end subroutine eucl_irij3_plpl - end submodule s_eucl diff --git a/src/helio/helio_getacch.f90 b/src/helio/helio_getacch.f90 index e7a84108e..9b00b698b 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -17,7 +17,8 @@ module subroutine helio_getacch_pl(self, system, param, t, lbeg) logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step associate(cb => system%cb, pl => self, npl => self%nbody) - call helio_getacch_int_pl(pl, t) + pl%ah(:,:) = 0.0_DP + call pl%accel_int() if (param%loblatecb) then cb%aoblbeg = cb%aobl call pl%accel_obl(system) @@ -49,15 +50,14 @@ module subroutine helio_getacch_tp(self, system, param, t, lbeg) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step - ! Internals - logical, save :: lmalloc = .true. - integer(I4B) :: i - real(DP) :: r2, mu - real(DP), dimension(:), allocatable, save :: irh, irht - associate(tp => self, ntp => self%nbody, cb => system%cb, npl => system%pl%nbody) + associate(tp => self, ntp => self%nbody, cb => system%cb, pl => system%pl, npl => system%pl%nbody) if (present(lbeg)) system%lbeg = lbeg - call helio_getacch_int_tp(tp, system, param, t) + if (lbeg) then + call tp%accel_int(pl%Gmass(:), pl%xbeg(:,:), npl) + else + call tp%accel_int(pl%Gmass(:), pl%xend(:,:), npl) + end if if (param%loblatecb) call tp%accel_obl(system) if (param%lextra_force) call tp%accel_user(system, param, t) !if (param%lgr) call tp%gr_accel(param) @@ -65,79 +65,4 @@ module subroutine helio_getacch_tp(self, system, param, t, lbeg) return end subroutine helio_getacch_tp - subroutine helio_getacch_int_pl(pl, t) - !! author: David A. Minton - !! - !! Compute direct cross term heliocentric accelerations of massive bodiese - !! - !! Adapted from David E. Kaufmann's Swifter routine helio_getacch_int.f90 - !! Adapted from Hal Levison's Swift routine getacch_ah3.f - implicit none - ! Arguments - class(helio_pl), intent(inout) :: pl !! Helio massive body particle data structure - real(DP), intent(in) :: t !! Current time - ! Internals - integer(I4B) :: i, j - real(DP) :: rji2, irij3, faci, facj - real(DP), dimension(NDIM) :: dx - - associate(npl => pl%nbody) - pl%ah(:,:) = 0.0_DP - do i = 1, npl - 1 - do j = i + 1, npl - dx(:) = pl%xh(:,j) - pl%xh(:,i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - faci = pl%Gmass(i) * irij3 - facj = pl%Gmass(j) * irij3 - pl%ah(:,i) = pl%ah(:,i) + facj * dx(:) - pl%ah(:,j) = pl%ah(:,j) - faci * dx(:) - end do - end do - end associate - - return - end subroutine helio_getacch_int_pl - - subroutine helio_getacch_int_tp(tp, system, param, t) - !! author: David A. Minton - !! - !! Compute direct cross term heliocentric accelerations of test particles - !! - !! Adapted from David E. Kaufmann's Swifter routine helio_getacch_int_tp.f90 - !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f - implicit none - ! Arguments - class(helio_tp), intent(inout) :: tp !! Helio test particle object - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current times - ! Internals - integer(I4B) :: i, j - real(DP) :: r2, fac - real(DP), dimension(NDIM) :: dx - real(DP), dimension(:, :), allocatable :: xhp - - associate(ntp => tp%nbody, pl => system%pl, npl => system%pl%nbody, lbeg => system%lbeg) - if (lbeg) then - allocate(xhp, source=pl%xbeg) - else - allocate(xhp, source=pl%xend) - end if - - tp%ah(:,:) = 0.0_DP - do i = 1, ntp - if (tp%status(i) == ACTIVE) then - do j = 1, npl - dx(:) = tp%xh(:,i) - xhp(:,j) - r2 = dot_product(dx(:), dx(:)) - fac = pl%Gmass(j) / (r2 * sqrt(r2)) - tp%ah(:,i) = tp%ah(:,i) - fac * dx(:) - end do - end if - end do - end associate - return - end subroutine helio_getacch_int_tp - end submodule s_helio_getacch diff --git a/src/kick/kick.f90 b/src/kick/kick.f90 index a54677dcd..2cb6dcde8 100644 --- a/src/kick/kick.f90 +++ b/src/kick/kick.f90 @@ -1,7 +1,73 @@ submodule(swiftest_classes) s_kick use swiftest contains - module subroutine kickvh_body(self, dt) + module pure subroutine kick_getacch_int_pl(self) + !! author: David A. Minton + !! + !! Compute direct cross (third) term heliocentric accelerations of massive bodies + !! + !! Adapted from Hal Levison's Swift routine getacch_ah3.f + !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 and helio_getacch_int.f90 + implicit none + ! Arguments + class(swiftest_pl), intent(inout) :: self + ! Internals + integer(I4B) :: k + real(DP) :: rji2, irij3, faci, facj + real(DP), dimension(NDIM) :: dx + + associate(pl => self, npl => self%nbody, nplpl => self%nplpl) + do k = 1, nplpl + associate(i => pl%k_eucl(1, k), j => pl%k_eucl(2, k)) + dx(:) = pl%xh(:, j) - pl%xh(:, i) + rji2 = dot_product(dx(:), dx(:)) + irij3 = 1.0_DP / (rji2 * sqrt(rji2)) + faci = pl%Gmass(i) * irij3 + facj = pl%Gmass(j) * irij3 + pl%ah(:, i) = pl%ah(:, i) + facj * dx(:) + pl%ah(:, j) = pl%ah(:, j) - faci * dx(:) + end associate + end do + end associate + + return + end subroutine kick_getacch_int_pl + + module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) + !! author: David A. Minton + !! + !! Compute direct cross (third) term heliocentric accelerations of test particles by massive bodies + !! + !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 and helio_getacch_int_tp.f90 + implicit none + ! Arguments + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle + real(DP), dimension(:), intent(in) :: GMpl !! Massive body masses + real(DP), dimension(:,:), intent(in) :: xhp !! Massive body position vectors + integer(I4B), intent(in) :: npl !! Number of active massive bodies + ! Internals + integer(I4B) :: i, j + real(DP) :: rji2, irij3, fac + real(DP), dimension(NDIM) :: dx, acc + + associate(tp => self, ntp => self%nbody) + do concurrent(i = 1:ntp, tp%status(i) == ACTIVE) + acc(:) = 0.0_DP + do j = 1, npl + dx(:) = tp%xh(:,i) - xhp(:, j) + rji2 = dot_product(dx(:), dx(:)) + irij3 = 1.0_DP / (rji2 * sqrt(rji2)) + fac = GMpl(j) * irij3 + acc(:) = acc(:) - fac * dx(:) + end do + tp%ah(:, i) = tp%ah(:, i) + acc(:) + end do + end associate + return + end subroutine kick_getacch_int_tp + + module subroutine kick_vh_body(self, dt) !! author: David A. Minton !! !! Kick heliocentric velocities of bodies @@ -23,6 +89,8 @@ module subroutine kickvh_body(self, dt) end associate return - end subroutine kickvh_body + end subroutine kick_vh_body + + end submodule s_kick diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index c70d3159a..c1accb768 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -8,12 +8,12 @@ module swiftest_classes private public :: discard_pl, discard_system, discard_tp public :: drift_body, drift_one - public :: eucl_dist_index_plpl, eucl_dist_index_pltp, eucl_irij3_plpl + public :: eucl_dist_index_plpl, eucl_dist_index_pltp public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & io_read_cb_in, io_read_param_in, io_read_frame_body, io_read_frame_cb, io_read_frame_system, & io_toupper, io_write_discard, io_write_encounter, io_write_frame_body, io_write_frame_cb, io_write_frame_system - public :: kickvh_body + public :: kick_getacch_int_pl, kick_vh_body public :: obl_acc_body, obl_acc_pl, obl_acc_tp public :: orbel_el2xv_vec, orbel_xv2el_vec, orbel_scget, orbel_xv2aeq, orbel_xv2aqt public :: setup_body, setup_construct_system, setup_initialize_system, setup_pl, setup_tp @@ -179,7 +179,7 @@ module swiftest_classes procedure, public :: initialize => io_read_body_in !! Read in body initial conditions from a file procedure, public :: read_frame => io_read_frame_body !! I/O routine for writing out a single frame of time-series data for the central body procedure, public :: write_frame => io_write_frame_body !! I/O routine for writing out a single frame of time-series data for the central body - procedure, public :: kick => kickvh_body !! Kicks the heliocentric velocities + procedure, public :: kick => kick_vh_body !! Kicks the heliocentric velocities procedure, public :: accel_obl => obl_acc_body !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: el2xv => orbel_el2xv_vec !! Convert orbital elements to position and velocity vectors procedure, public :: xv2el => orbel_xv2el_vec !! Convert position and velocity vectors to orbital elements @@ -201,7 +201,6 @@ module swiftest_classes real(DP), dimension(:), allocatable :: Gmass !! Mass gravitational term G * mass (units GU * MU) real(DP), dimension(:), allocatable :: rhill !! Body mass (units MU) real(DP), dimension(:), allocatable :: radius !! Body radius (units DU) - real(DP), dimension(:), allocatable :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance real(DP), dimension(:,:), allocatable :: xbeg !! Position at beginning of step real(DP), dimension(:,:), allocatable :: xend !! Position at end of step real(DP), dimension(:,:), allocatable :: vbeg !! Velocity at beginning of step @@ -219,10 +218,10 @@ module swiftest_classes ! These are concrete because they are the same implemenation for all integrators procedure, public :: discard => discard_pl !! Placeholder method for discarding massive bodies procedure, public :: eucl_index => eucl_dist_index_plpl !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix - procedure, public :: eucl_irij3 => eucl_irij3_plpl !! Parallelized single loop blocking for Euclidean distance matrix calcualtion + procedure, public :: accel_int => kick_getacch_int_pl !! Compute direct cross (third) term heliocentric accelerations of massive bodies procedure, public :: accel_obl => obl_acc_pl !! Compute the barycentric accelerations of bodies due to the oblateness of the central body - procedure, public :: accel_tides => tides_getacch_pl !! Compute the accelerations of bodies due to tidal interactions with the central body procedure, public :: setup => setup_pl !! A base constructor that sets the number of bodies and allocates and initializes all arrays + procedure, public :: accel_tides => tides_getacch_pl !! Compute the accelerations of bodies due to tidal interactions with the central body procedure, public :: set_mu => util_set_mu_pl !! Method used to construct the vectorized form of the central body mass procedure, public :: set_rhill => util_set_rhill !! Calculates the Hill's radii for each body procedure, public :: h2b => util_coord_h2b_pl !! Convert massive bodies from heliocentric to barycentric coordinates (position and velocity) @@ -241,7 +240,6 @@ module swiftest_classes integer(I4B), dimension(:), allocatable :: isperi !! Perihelion passage flag real(DP), dimension(:), allocatable :: peri !! Perihelion distance real(DP), dimension(:), allocatable :: atp !! Semimajor axis following perihelion passage - real(DP), dimension(:, :), allocatable :: irij3 !! 1.0_DP / (rji2 * sqrt(rji2)) where rji2 is the square of the Euclidean distance betwen each pl-tp !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the !! component list, such as setup_tp and util_spill_tp contains @@ -250,6 +248,7 @@ module swiftest_classes ! These are concrete because they are the same implemenation for all integrators procedure, public :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies procedure, public :: eucl_index => eucl_dist_index_pltp !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix + procedure, public :: accel_int => kick_getacch_int_tp !! Compute direct cross (third) term heliocentric accelerations of test particles by massive bodies procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: setup => setup_tp !! A base constructor that sets the number of bodies and procedure, public :: set_mu => util_set_mu_tp !! Method used to construct the vectorized form of the central body mass @@ -412,11 +411,6 @@ module subroutine eucl_dist_index_pltp(self, pl) class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object end subroutine - module subroutine eucl_irij3_plpl(self) - implicit none - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object - end subroutine eucl_irij3_plpl - module pure subroutine gr_getaccb_ns_body(self, system, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest generic body object @@ -606,11 +600,24 @@ module subroutine io_write_frame_system(self, iu, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine io_write_frame_system - module subroutine kickvh_body(self, dt) + module pure subroutine kick_getacch_int_pl(self) + implicit none + class(swiftest_pl), intent(inout) :: self + end subroutine kick_getacch_int_pl + + module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) + implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle + real(DP), dimension(:), intent(in) :: GMpl !! Massive body masses + real(DP), dimension(:,:), intent(in) :: xhp !! Massive body position vectors + integer(I4B), intent(in) :: npl !! Number of active massive bodies + end subroutine kick_getacch_int_tp + + module subroutine kick_vh_body(self, dt) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest body object real(DP), intent(in) :: dt !! Stepsize - end subroutine kickvh_body + end subroutine kick_vh_body module subroutine obl_acc_body(self, system) implicit none diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 0aa438a5e..e950d855c 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -30,7 +30,7 @@ module subroutine whm_getacch_pl(self, system, param, t, lbeg) call whm_getacch_ah1(cb, pl) call whm_getacch_ah2(cb, pl) - call whm_getacch_ah3(pl) + call pl%accel_int() if (param%loblatecb) then cb%aoblbeg = cb%aobl @@ -67,23 +67,25 @@ module subroutine whm_getacch_tp(self, system, param, t, lbeg) ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: ah0 - real(DP), dimension(:,:), allocatable :: xhp associate(tp => self, ntp => self%nbody, pl => system%pl, cb => system%cb, npl => system%pl%nbody) if (ntp == 0 .or. npl == 0) return if (present(lbeg)) system%lbeg = lbeg if (system%lbeg) then - allocate(xhp, source=pl%xbeg) + ah0(:) = whm_getacch_ah0(pl%Gmass(:), pl%xbeg(:,:), npl) + do i = 1, ntp + tp%ah(:, i) = ah0(:) + end do + call tp%accel_int(pl%Gmass(:), pl%xbeg(:,:), npl) else - allocate(xhp, source=pl%xend) + ah0(:) = whm_getacch_ah0(pl%Gmass(:), pl%xend(:,:), npl) + do i = 1, ntp + tp%ah(:, i) = ah0(:) + end do + call tp%accel_int(pl%Gmass(:), pl%xend(:,:), npl) end if - ah0(:) = whm_getacch_ah0(pl%Gmass(:), xhp(:,:), npl) - do i = 1, ntp - tp%ah(:, i) = ah0(:) - end do - call whm_getacch_ah3_tp(system, xhp) if (param%loblatecb) call tp%accel_obl(system) if (param%lextra_force) call tp%accel_user(system, param, t) if (param%lgr) call tp%accel_gr(param) @@ -177,74 +179,4 @@ pure subroutine whm_getacch_ah2(cb, pl) return end subroutine whm_getacch_ah2 - pure subroutine whm_getacch_ah3(pl) - !! author: David A. Minton - !! - !! Compute direct cross (third) term heliocentric accelerations of planets - !! - !! Adapted from Hal Levison's Swift routine getacch_ah3.f - !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 - implicit none - - class(whm_pl), intent(inout) :: pl - integer(I4B) :: k - real(DP) :: rji2, irij3, faci, facj - real(DP), dimension(NDIM) :: dx - real(DP), dimension(:,:), allocatable :: ah3 - - associate(npl => pl%nbody, nplpl => pl%nplpl) - allocate(ah3, mold=pl%ah) - ah3(:, :) = 0.0_DP - do k = 1, nplpl - associate(i => pl%k_eucl(1, k), j => pl%k_eucl(2, k)) - dx(:) = pl%xh(:, j) - pl%xh(:, i) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - faci = pl%Gmass(i) * irij3 - facj = pl%Gmass(j) * irij3 - ah3(:, i) = ah3(:, i) + facj * dx(:) - ah3(:, j) = ah3(:, j) - faci * dx(:) - end associate - end do - do concurrent (k = 1:npl) - pl%ah(:, k) = pl%ah(:, k) + ah3(:, k) - end do - deallocate(ah3) - end associate - - return - end subroutine whm_getacch_ah3 - - pure subroutine whm_getacch_ah3_tp(system, xhp) - !! author: David A. Minton - !! - !! Compute direct cross (third) term heliocentric accelerations of test particles - !! - !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f - !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 - implicit none - ! Arguments - class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object - real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at the current substep - ! Internals - integer(I4B) :: i, j - real(DP) :: rji2, irij3, fac - real(DP), dimension(NDIM) :: dx, acc - - associate(ntp => system%tp%nbody, npl => system%pl%nbody, tp => system%tp, pl => system%pl) - if (ntp == 0) return - do i = 1, ntp - acc(:) = 0.0_DP - do j = 1, npl - dx(:) = tp%xh(:, i) - xhp(:, j) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - fac = pl%Gmass(j) * irij3 - acc(:) = acc(:) - fac * dx(:) - end do - tp%ah(:, i) = tp%ah(:, i) + acc(:) - end do - end associate - return - end subroutine whm_getacch_ah3_tp end submodule s_whm_getacch From f6cf54d12935b2af5337461607c4e3b84353e097 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 16:23:05 -0400 Subject: [PATCH 29/33] Corrected position vector for massive bodies from xb to xh --- src/helio/helio_drift.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 7ae65feab..7a6d4db06 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -34,7 +34,7 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) if (param%lgr) then do concurrent(i = 1:npl, mask(i)) - rmag = norm2(pl%xb(:, i)) + rmag = norm2(pl%xh(:, i)) vmag2 = dot_product(pl%vb(:, i), pl%vb(:, i)) energy = 0.5_DP * vmag2 - mu(i) / rmag dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) @@ -44,7 +44,7 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) end if do concurrent(i = 1:npl, mask(i)) - call drift_one(mu(i), pl%xb(1,i), pl%xb(2,i), pl%xb(3,i), & + call drift_one(mu(i), pl%xh(1,i), pl%xh(2,i), pl%xh(3,i), & pl%vb(1,i), pl%vb(2,i), pl%vb(3,i), & dtp(i), iflag(i)) end do @@ -52,7 +52,7 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) do i = 1, npl if (iflag(i) /= 0) then write(*, *) " Planet ", self%id(i), " is lost!!!!!!!!!!" - write(*, *) pl%xb(:,i) + write(*, *) pl%xh(:,i) write(*, *) pl%vb(:,i) write(*, *) " stopping " call util_exit(FAILURE) From 5d55ac1b35a108042d8b1bd410dbd4feb281a571 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 17:26:23 -0400 Subject: [PATCH 30/33] Wrote the helio drift subroutine for swiftest_body type and then wrapped it with interfaces so that they can be used as type-bound procedures for helio_pl and helio_tp --- src/helio/helio_drift.f90 | 41 ++++++++++++++++++++++++++++++----- src/helio/helio_getacch.f90 | 5 +++-- src/kick/kick.f90 | 10 +++++---- src/modules/helio_classes.f90 | 23 +++++++++++++++++++- 4 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 7a6d4db06..38e156e32 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -1,18 +1,17 @@ submodule (helio_classes) s_helio_drift use swiftest contains - module subroutine helio_drift_pl(self, system, param, dt, mask) + module subroutine helio_drift_body(self, system, param, dt, mask) !! author: David A. Minton !! - !! Loop through massive bodies and call Danby drift routine - !! New vectorized version included + !! Loop through bodies and call Danby drift routine on democratic heliocentric coordinates !! !! Adapted from David E. Kaufmann's Swifter routine helio_drift.f90 !! Adapted from Hal Levison's Swift routine drift.f implicit none ! Arguments - class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_body), intent(inout) :: self !! Swiftest body object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize @@ -51,7 +50,7 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then - write(*, *) " Planet ", self%id(i), " is lost!!!!!!!!!!" + write(*, *) " Body", self%id(i), " is lost!!!!!!!!!!" write(*, *) pl%xh(:,i) write(*, *) pl%vb(:,i) write(*, *) " stopping " @@ -63,7 +62,39 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) return + end subroutine helio_drift_body + + module subroutine helio_drift_pl(self, system, param, dt, mask) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a helio_pl structure + implicit none + ! Arguments + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + + call helio_drift_body(self, system, param, dt, mask) + return end subroutine helio_drift_pl + + module subroutine helio_drift_tp(self, system, param, dt, mask) + !! author: David A. Minton + !! + !! Wrapper function used to call the body drift routine from a helio_pl structure + implicit none + ! Arguments + class(helio_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + + call helio_drift_body(self, system, param, dt, mask) + return + end subroutine helio_drift_tp module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) !! author: David A. Minton diff --git a/src/helio/helio_getacch.f90 b/src/helio/helio_getacch.f90 index 9b00b698b..098549eff 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -51,9 +51,10 @@ module subroutine helio_getacch_tp(self, system, param, t, lbeg) real(DP), intent(in) :: t !! Current time logical, optional, intent(in) :: lbeg !! Optional argument that determines whether or not this is the beginning or end of the step - associate(tp => self, ntp => self%nbody, cb => system%cb, pl => system%pl, npl => system%pl%nbody) + associate(tp => self, cb => system%cb, pl => system%pl, npl => system%pl%nbody) + tp%ah(:,:) = 0.0_DP if (present(lbeg)) system%lbeg = lbeg - if (lbeg) then + if (system%lbeg) then call tp%accel_int(pl%Gmass(:), pl%xbeg(:,:), npl) else call tp%accel_int(pl%Gmass(:), pl%xend(:,:), npl) diff --git a/src/kick/kick.f90 b/src/kick/kick.f90 index 2cb6dcde8..61cd560bb 100644 --- a/src/kick/kick.f90 +++ b/src/kick/kick.f90 @@ -48,7 +48,7 @@ module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) integer(I4B), intent(in) :: npl !! Number of active massive bodies ! Internals integer(I4B) :: i, j - real(DP) :: rji2, irij3, fac + real(DP) :: rji2, irij3, fac, r2 real(DP), dimension(NDIM) :: dx, acc associate(tp => self, ntp => self%nbody) @@ -56,9 +56,11 @@ module pure subroutine kick_getacch_int_tp(self, GMpl, xhp, npl) acc(:) = 0.0_DP do j = 1, npl dx(:) = tp%xh(:,i) - xhp(:, j) - rji2 = dot_product(dx(:), dx(:)) - irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - fac = GMpl(j) * irij3 + !rji2 = dot_product(dx(:), dx(:)) + !irij3 = 1.0_DP / (rji2 * sqrt(rji2)) + !fac = GMpl(j) * irij3 + r2 = dot_product(dx(:), dx(:)) + fac = GMpl(j) / (r2 * sqrt(r2)) acc(:) = acc(:) - fac * dx(:) end do tp%ah(:, i) = tp%ah(:, i) + acc(:) diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index ae2693167..17366e88f 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -53,6 +53,7 @@ module helio_classes procedure, public :: vh2vb => helio_coord_vh2vb_tp !! Convert test particles from heliocentric to barycentric coordinates (velocity only) procedure, public :: vb2vh => helio_coord_vb2vh_tp !! Convert test particles from barycentric to heliocentric coordinates (velocity only) procedure, public :: lindrift => helio_drift_linear_tp !! Method for linear drift of massive bodies due to barycentric momentum of Sun + procedure, public :: drift => helio_drift_tp !! Method for Danby drift in Democratic Heliocentric coordinates procedure, public :: accel => helio_getacch_tp !! Compute heliocentric accelerations of massive bodies procedure, public :: kick => helio_kickvb_tp !! Kicks the barycentric velocities procedure, public :: step => helio_step_tp !! Steps the body forward one stepsize @@ -84,6 +85,16 @@ module subroutine helio_coord_vh2vb_tp(self, vbcb) class(helio_tp), intent(inout) :: self !! Helio massive body object real(DP), dimension(:), intent(in) :: vbcb !! Barycentric velocity of the central body end subroutine helio_coord_vh2vb_tp + + module subroutine helio_drift_body(self, system, param, dt, mask) + use swiftest_classes, only : swiftest_body, swiftest_nbody_system, swiftest_parameters + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift + end subroutine helio_drift_body module subroutine helio_drift_pl(self, system, param, dt, mask) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters @@ -92,9 +103,19 @@ module subroutine helio_drift_pl(self, system, param, dt, mask) class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize - logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift end subroutine helio_drift_pl + module subroutine helio_drift_tp(self, system, param, dt, mask) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_tp), intent(inout) :: self !! Helio massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift + end subroutine helio_drift_tp + module subroutine helio_drift_linear_pl(self, cb, dt, lbeg) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object From 205e666e956dd392069c7f50553085d4802b38d5 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 17:31:48 -0400 Subject: [PATCH 31/33] Refactored to remove associate statements since the helio_drift routine is generic to any kind of body --- src/helio/helio_drift.f90 | 65 +++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 34 deletions(-) diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 38e156e32..11d642159 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -22,46 +22,43 @@ module subroutine helio_drift_body(self, system, param, dt, mask) integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag real(DP), dimension(:), allocatable :: dtp, mu - associate(pl => self, npl => self%nbody, cb => system%cb) - if (npl == 0) return + if (self%nbody == 0) return - allocate(iflag(npl)) - iflag(:) = 0 - allocate(dtp(npl)) - allocate(mu(npl)) - mu(:) = cb%Gmass + allocate(iflag(self%nbody)) + iflag(:) = 0 + allocate(dtp(self%nbody)) + allocate(mu(self%nbody)) + mu(:) = system%cb%Gmass - if (param%lgr) then - do concurrent(i = 1:npl, mask(i)) - rmag = norm2(pl%xh(:, i)) - vmag2 = dot_product(pl%vb(:, i), pl%vb(:, i)) - energy = 0.5_DP * vmag2 - mu(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - where(mask(1:npl)) dtp(1:npl) = dt - end if + if (param%lgr) then + do concurrent(i = 1:self%nbody, mask(i)) + rmag = norm2(self%xh(:, i)) + vmag2 = dot_product(self%vb(:, i), self%vb(:, i)) + energy = 0.5_DP * vmag2 - mu(i) / rmag + dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) + end do + else + where(mask(1:self%nbody)) dtp(1:self%nbody) = dt + end if - do concurrent(i = 1:npl, mask(i)) - call drift_one(mu(i), pl%xh(1,i), pl%xh(2,i), pl%xh(3,i), & - pl%vb(1,i), pl%vb(2,i), pl%vb(3,i), & - dtp(i), iflag(i)) + do concurrent(i = 1:self%nbody, mask(i)) + call drift_one(mu(i), self%xh(1,i), self%xh(2,i), self%xh(3,i), & + self%vb(1,i), self%vb(2,i), self%vb(3,i), & + dtp(i), iflag(i)) + end do + if (any(iflag(1:self%nbody) /= 0)) then + do i = 1, self%nbody + if (iflag(i) /= 0) then + write(*, *) " Body", self%id(i), " is lost!!!!!!!!!!" + write(*, *) self%xh(:,i) + write(*, *) self%vb(:,i) + write(*, *) " stopping " + call util_exit(FAILURE) + end if end do - if (any(iflag(1:npl) /= 0)) then - do i = 1, npl - if (iflag(i) /= 0) then - write(*, *) " Body", self%id(i), " is lost!!!!!!!!!!" - write(*, *) pl%xh(:,i) - write(*, *) pl%vb(:,i) - write(*, *) " stopping " - call util_exit(FAILURE) - end if - end do - end if - end associate + end if return - end subroutine helio_drift_body module subroutine helio_drift_pl(self, system, param, dt, mask) From 2ef93640899308cf891377f6d423b58820795ae8 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 23 Jul 2021 17:50:12 -0400 Subject: [PATCH 32/33] Consolidated redundant drift subroutines into one single shared algorithm. Each type-bound procedure now feeds the correct position and velocities to the universal drift_all function --- .../swiftest_vs_swifter.ipynb | 99 +++---------------- src/drift/drift.f90 | 63 ++++++++---- src/helio/helio_drift.f90 | 48 +++------ src/modules/swiftest_classes.f90 | 13 ++- src/whm/whm_drift.f90 | 35 ++----- 5 files changed, 93 insertions(+), 165 deletions(-) diff --git a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb index 7f0b1d4b9..c5a777669 100644 --- a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb +++ b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [ { @@ -21,10 +21,7 @@ "output_type": "stream", "text": [ "Reading Swifter file param.swifter.in\n", - "Reading in time 1.000e+00\n", - "Creating Dataset\n", - "Successfully converted 1462 output frames.\n", - "Swifter simulation data stored as xarray DataSet .ds\n" + "Reading in time 2.580e-01" ] } ], @@ -35,21 +32,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Reading Swiftest file param.swiftest.in\n", - "Reading in time 1.001e+00\n", - "Creating Dataset\n", - "Successfully converted 1463 output frames.\n", - "Swiftest simulation data stored as xarray DataSet .ds\n" - ] - } - ], + "outputs": [], "source": [ "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", "swiftestsim.bin2xr()" @@ -57,7 +42,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -66,7 +51,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -75,7 +60,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -85,7 +70,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -95,22 +80,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dr'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -122,22 +94,9 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dr'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -148,22 +107,9 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dv'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -174,22 +120,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": { - "needs_background": "light" - }, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dv'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", diff --git a/src/drift/drift.f90 b/src/drift/drift.f90 index ce9f66761..4d9988f93 100644 --- a/src/drift/drift.f90 +++ b/src/drift/drift.f90 @@ -26,34 +26,16 @@ module subroutine drift_body(self, system, param, dt, mask) logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. ! Internals integer(I4B) :: i - real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation integer(I4B), dimension(:), allocatable :: iflag - real(DP), dimension(:), allocatable :: dtp associate(n => self%nbody) - if (n == 0) return allocate(iflag(n)) iflag(:) = 0 - allocate(dtp(n)) - if (param%lgr) then - do concurrent(i = 1:n, mask(i)) - rmag = norm2(self%xh(:, i)) - vmag2 = dot_product(self%vh(:, i), self%vh(:, i)) - energy = 0.5_DP * vmag2 - self%mu(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - where(mask(1:n)) dtp(1:n) = dt - end if - do concurrent(i = 1:n, mask(i)) - call drift_one(self%mu(i), self%xh(1,i), self%xh(2,i), self%xh(3,i), & - self%vh(1,i), self%vh(2,i), self%vh(3,i), & - dtp(i), iflag(i)) - end do + call drift_all(self%mu, self%xh, self%vh, self%nbody, param, dt, mask, iflag) if (any(iflag(1:n) /= 0)) then where(iflag(1:n) /= 0) self%status(1:n) = DISCARDED_DRIFTERR do i = 1, n - if (iflag(i) /= 0) write(*, *) "Particle ", self%id(i), " lost due to error in Danby drift" + if (iflag(i) /= 0) write(*, *) " Body ", self%id(i), " lost due to error in Danby drift" end do end if end associate @@ -61,6 +43,47 @@ module subroutine drift_body(self, system, param, dt, mask) return end subroutine drift_body + module pure subroutine drift_all(mu, x, v, n, param, dt, mask, iflag) + !! author: David A. Minton + !! + !! Loop bodies and call Danby drift routine on all bodies for the given position and velocity vector. + !! + !! Adapted from Hal Levison's Swift routine drift_tp.f + !! Adapted from David E. Kaufmann's Swifter routine whm_drift_tp.f9 + implicit none + ! Arguments + real(DP), dimension(:), intent(in) :: mu !! Vector of gravitational constants + real(DP), dimension(:,:), intent(inout) :: x, v !! Position and velocity vectors + integer(I4B), intent(in) :: n !! number of bodies + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + integer(I4B), dimension(:), intent(out) :: iflag !! Vector of error flags. 0 means no problem + ! Internals + integer(I4B) :: i + real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation + real(DP), dimension(:), allocatable :: dtp + + if (n == 0) return + + allocate(dtp(n)) + if (param%lgr) then + do concurrent(i = 1:n, mask(i)) + rmag = norm2(x(:, i)) + vmag2 = dot_product(v(:, i), v(:, i)) + energy = 0.5_DP * vmag2 - mu(i) / rmag + dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) + end do + else + where(mask(1:n)) dtp(1:n) = dt + end if + do concurrent(i = 1:n, mask(i)) + call drift_one(mu(i), x(1,i), x(2,i), x(3,i), v(1,i), v(2,i), v(3,i), dtp(i), iflag(i)) + end do + + return + end subroutine drift_all + module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 11d642159..0c146eea5 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -22,41 +22,19 @@ module subroutine helio_drift_body(self, system, param, dt, mask) integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag real(DP), dimension(:), allocatable :: dtp, mu - if (self%nbody == 0) return - - allocate(iflag(self%nbody)) - iflag(:) = 0 - allocate(dtp(self%nbody)) - allocate(mu(self%nbody)) - mu(:) = system%cb%Gmass - - if (param%lgr) then - do concurrent(i = 1:self%nbody, mask(i)) - rmag = norm2(self%xh(:, i)) - vmag2 = dot_product(self%vb(:, i), self%vb(:, i)) - energy = 0.5_DP * vmag2 - mu(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - where(mask(1:self%nbody)) dtp(1:self%nbody) = dt - end if - - do concurrent(i = 1:self%nbody, mask(i)) - call drift_one(mu(i), self%xh(1,i), self%xh(2,i), self%xh(3,i), & - self%vb(1,i), self%vb(2,i), self%vb(3,i), & - dtp(i), iflag(i)) - end do - if (any(iflag(1:self%nbody) /= 0)) then - do i = 1, self%nbody - if (iflag(i) /= 0) then - write(*, *) " Body", self%id(i), " is lost!!!!!!!!!!" - write(*, *) self%xh(:,i) - write(*, *) self%vb(:,i) - write(*, *) " stopping " - call util_exit(FAILURE) - end if - end do - end if + associate(n => self%nbody) + allocate(iflag(n)) + iflag(:) = 0 + allocate(mu(n)) + mu(:) = system%cb%Gmass + call drift_all(mu, self%xh, self%vb, self%nbody, param, dt, mask, iflag) + if (any(iflag(1:n) /= 0)) then + where(iflag(1:n) /= 0) self%status(1:n) = DISCARDED_DRIFTERR + do i = 1, n + if (iflag(i) /= 0) write(*, *) " Body ", self%id(i), " lost due to error in Danby drift" + end do + end if + end associate return end subroutine helio_drift_body diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index c1accb768..fc2ca4d39 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -7,7 +7,7 @@ module swiftest_classes implicit none private public :: discard_pl, discard_system, discard_tp - public :: drift_body, drift_one + public :: drift_all, drift_body, drift_one public :: eucl_dist_index_plpl, eucl_dist_index_pltp public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & @@ -383,6 +383,17 @@ module subroutine discard_tp(self, system, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_tp + module pure subroutine drift_all(mu, x, v, n, param, dt, mask, iflag) + implicit none + real(DP), dimension(:), intent(in) :: mu !! Vector of gravitational constants + real(DP), dimension(:,:), intent(inout) :: x, v !! Position and velocity vectors + integer(I4B), intent(in) :: n !! number of bodies + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: dt !! Stepsize + logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. + integer(I4B), dimension(:), intent(out) :: iflag !! Vector of error flags. 0 means no problem + end subroutine drift_all + module subroutine drift_body(self, system, param, dt, mask) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle data structure diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index 12d8494a8..454e1bc53 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -17,43 +17,26 @@ module subroutine whm_drift_pl(self, system, param, dt, mask) logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift ! Internals integer(I4B) :: i - real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation integer(I4B), dimension(:), allocatable :: iflag - real(DP), dimension(:), allocatable :: dtp associate(pl => self, npl => self%nbody) if (npl == 0) return allocate(iflag(npl)) iflag(:) = 0 - allocate(dtp(npl)) - - if (param%lgr) then - do concurrent(i = 1:npl, mask(i)) - rmag = norm2(pl%xj(:, i)) - vmag2 = dot_product(pl%vj(:, i), pl%vj(:, i)) - energy = 0.5_DP * vmag2 - pl%muj(i) / rmag - dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) - end do - else - where(mask(1:npl)) dtp(1:npl) = dt - end if - - do concurrent(i = 1:npl, mask(i)) - call drift_one(pl%muj(i), pl%xj(1,i), pl%xj(2,i), pl%xj(3,i), & - pl%vj(1,i), pl%vj(2,i), pl%vj(3,i), & - dtp(i), iflag(i)) - end do + call drift_all(pl%muj, pl%xj, pl%vj, npl, param, dt, mask, iflag) if (any(iflag(1:npl) /= 0)) then + where(iflag(1:npl) /= 0) pl%status(1:npl) = DISCARDED_DRIFTERR do i = 1, npl - if (iflag(i) /= 0) then - write(*, *) " Planet ", self%id(i), " is lost!!!!!!!!!!" - write(*, *) pl%xj(:,i) - write(*, *) pl%vj(:,i) - write(*, *) " stopping " - call util_exit(FAILURE) + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%id(i), " is lost!!!!!!!!!!!!" + WRITE(*, *) pl%muj(i), dt + WRITE(*, *) pl%xj(:,i) + WRITE(*, *) pl%vj(:,i) + WRITE(*, *) " STOPPING " end if end do + call util_exit(FAILURE) end if end associate From 4f30c8e5b40ed431f1cfa1474f774e3288f87b0c Mon Sep 17 00:00:00 2001 From: David A Minton Date: Sat, 24 Jul 2021 01:53:46 -0400 Subject: [PATCH 33/33] Added plpl encounter check adapted from Fragmentation branch --- .../swiftest_vs_swifter.ipynb | 99 ++++++++++++++++--- src/eucl/eucl.f90 | 21 +--- src/kick/kick.f90 | 2 +- src/modules/rmvs_classes.f90 | 26 ++--- src/modules/swiftest_classes.f90 | 17 +--- src/modules/symba_classes.f90 | 26 ++++- ...{rmvs_spill_and_fill.f90 => rmvs_util.f90} | 20 ++-- src/symba/symba_encounter_check.f90 | 82 ++++++++++----- src/symba/symba_setup.f90 | 13 ++- src/symba/symba_util.f90 | 67 +++++++++++++ 10 files changed, 277 insertions(+), 96 deletions(-) rename src/rmvs/{rmvs_spill_and_fill.f90 => rmvs_util.f90} (91%) create mode 100644 src/symba/symba_util.f90 diff --git a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb index c5a777669..7f0b1d4b9 100644 --- a/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb +++ b/examples/helio_swifter_comparison/swiftest_vs_swifter.ipynb @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -21,7 +21,10 @@ "output_type": "stream", "text": [ "Reading Swifter file param.swifter.in\n", - "Reading in time 2.580e-01" + "Reading in time 1.000e+00\n", + "Creating Dataset\n", + "Successfully converted 1462 output frames.\n", + "Swifter simulation data stored as xarray DataSet .ds\n" ] } ], @@ -32,9 +35,21 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Reading Swiftest file param.swiftest.in\n", + "Reading in time 1.001e+00\n", + "Creating Dataset\n", + "Successfully converted 1463 output frames.\n", + "Swiftest simulation data stored as xarray DataSet .ds\n" + ] + } + ], "source": [ "swiftestsim = swiftest.Simulation(param_file=\"param.swiftest.in\")\n", "swiftestsim.bin2xr()" @@ -42,7 +57,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -51,7 +66,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -60,7 +75,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -70,7 +85,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, "outputs": [], "source": [ @@ -80,9 +95,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dr'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -94,9 +122,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dr'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -107,9 +148,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dv'].sel(id=plidx).plot.line(x=\"time (y)\", ax=ax)\n", @@ -120,9 +174,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], "source": [ "fig, ax = plt.subplots()\n", "swiftdiff['dv'].sel(id=tpidx).plot.line(x=\"time (y)\", ax=ax)\n", diff --git a/src/eucl/eucl.f90 b/src/eucl/eucl.f90 index fb8afa131..24af7fd6e 100644 --- a/src/eucl/eucl.f90 +++ b/src/eucl/eucl.f90 @@ -19,13 +19,13 @@ module subroutine eucl_dist_index_plpl(self) npl = int(self%nbody, kind=I8B) associate(nplpl => self%nplpl) nplpl = (npl * (npl - 1) / 2) ! number of entries in a strict lower triangle, nplm x npl, minus first column - if (allocated(self%k_eucl)) deallocate(self%k_eucl) ! Reset the index array if it's been set previously - allocate(self%k_eucl(2, nplpl)) + if (allocated(self%k_plpl)) deallocate(self%k_plpl) ! Reset the index array if it's been set previously + allocate(self%k_plpl(2, nplpl)) do i = 1, npl counter = (i - 1_I8B) * npl - i * (i - 1_I8B) / 2_I8B + 1_I8B do j = i + 1_I8B, npl - self%k_eucl(1, counter) = i - self%k_eucl(2, counter) = j + self%k_plpl(1, counter) = i + self%k_plpl(2, counter) = j counter = counter + 1_I8B end do end do @@ -34,17 +34,4 @@ module subroutine eucl_dist_index_plpl(self) end subroutine eucl_dist_index_plpl - module subroutine eucl_dist_index_pltp(self, pl) - !! author: Jacob R. Elliott and David A. Minton - !! - !! Turns i,j indices into k index for use in the Euclidean distance matrix - !! - !! Reference: - !! - !! Mélodie Angeletti, Jean-Marie Bonny, Jonas Koko. Parallel Euclidean distance matrix computation on big datasets *. - !! 2019. hal-0204751 implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - end subroutine eucl_dist_index_pltp - end submodule s_eucl diff --git a/src/kick/kick.f90 b/src/kick/kick.f90 index 61cd560bb..efad4702a 100644 --- a/src/kick/kick.f90 +++ b/src/kick/kick.f90 @@ -18,7 +18,7 @@ module pure subroutine kick_getacch_int_pl(self) associate(pl => self, npl => self%nbody, nplpl => self%nplpl) do k = 1, nplpl - associate(i => pl%k_eucl(1, k), j => pl%k_eucl(2, k)) + associate(i => pl%k_plpl(1, k), j => pl%k_plpl(2, k)) dx(:) = pl%xh(:, j) - pl%xh(:, i) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index bf2a0cebd..8d0fb1f18 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -54,7 +54,7 @@ module rmvs_classes !! RMVS test particle class type, public, extends(whm_tp) :: rmvs_tp !! Note to developers: If you add componenets to this class, be sure to update methods and subroutines that traverse the - !! component list, such as rmvs_setup_tp and rmvs_spill_tp + !! component list, such as rmvs_setup_tp and rmvs_util_spill_tp ! encounter steps) logical, dimension(:), allocatable :: lperi !! planetocentric pericenter passage flag (persistent for a full rmvs time step) over a full RMVS time step) integer(I4B), dimension(:), allocatable :: plperP !! index of planet associated with pericenter distance peri (persistent over a full RMVS time step) @@ -70,11 +70,11 @@ module rmvs_classes private procedure, public :: discard => rmvs_discard_tp !! Check to see if test particles should be discarded based on pericenter passage distances with respect to planets encountered procedure, public :: encounter_check => rmvs_encounter_check_tp !! Checks if any test particles are undergoing a close encounter with a massive body - procedure, public :: fill => rmvs_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) + procedure, public :: fill => rmvs_util_fill_tp !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: accel => rmvs_getacch_tp !! Calculates either the standard or modified version of the acceleration depending if the !! if the test particle is undergoing a close encounter or not procedure, public :: setup => rmvs_setup_tp !! Constructor method - Allocates space for number of particles - procedure, public :: spill => rmvs_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure, public :: spill => rmvs_util_spill_tp !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) end type rmvs_tp !******************************************************************************************************************************** @@ -92,9 +92,9 @@ module rmvs_classes logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations contains private - procedure, public :: fill => rmvs_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) + procedure, public :: fill => rmvs_util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: setup => rmvs_setup_pl !! Constructor method - Allocates space for number of particles - procedure, public :: spill => rmvs_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) + procedure, public :: spill => rmvs_util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) end type rmvs_pl interface @@ -120,21 +120,21 @@ module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) logical :: lencounter !! Returns true if there is at least one close encounter end function rmvs_encounter_check_tp - module subroutine rmvs_fill_pl(self, inserts, lfill_list) + module subroutine rmvs_util_fill_pl(self, inserts, lfill_list) use swiftest_classes, only : swiftest_body implicit none class(rmvs_pl), intent(inout) :: self !! RMVS massive body object class(swiftest_body), intent(inout) :: inserts !! Inserted object logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps - end subroutine rmvs_fill_pl + end subroutine rmvs_util_fill_pl - module subroutine rmvs_fill_tp(self, inserts, lfill_list) + module subroutine rmvs_util_fill_tp(self, inserts, lfill_list) use swiftest_classes, only : swiftest_body implicit none class(rmvs_tp), intent(inout) :: self !! RMVS massive body object class(swiftest_body), intent(inout) :: inserts !! Inserted object logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps - end subroutine rmvs_fill_tp + end subroutine rmvs_util_fill_tp module subroutine rmvs_getacch_tp(self, system, param, t, lbeg) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters @@ -165,21 +165,21 @@ module subroutine rmvs_setup_tp(self,n) integer, intent(in) :: n !! Number of test particles to allocate end subroutine rmvs_setup_tp - module subroutine rmvs_spill_pl(self, discards, lspill_list) + module subroutine rmvs_util_spill_pl(self, discards, lspill_list) use swiftest_classes, only : swiftest_body implicit none class(rmvs_pl), intent(inout) :: self !! RMVS massive body object class(swiftest_body), intent(inout) :: discards !! Discarded object logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards - end subroutine rmvs_spill_pl + end subroutine rmvs_util_spill_pl - module subroutine rmvs_spill_tp(self, discards, lspill_list) + module subroutine rmvs_util_spill_tp(self, discards, lspill_list) use swiftest_classes, only : swiftest_body implicit none class(rmvs_tp), intent(inout) :: self !! RMVS test particle object class(swiftest_body), intent(inout) :: discards !! Discarded object logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards - end subroutine rmvs_spill_tp + end subroutine rmvs_util_spill_tp module subroutine rmvs_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index fc2ca4d39..5c6b83bdc 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -8,7 +8,7 @@ module swiftest_classes private public :: discard_pl, discard_system, discard_tp public :: drift_all, drift_body, drift_one - public :: eucl_dist_index_plpl, eucl_dist_index_pltp + public :: eucl_dist_index_plpl public :: gr_getaccb_ns_body, gr_p4_pos_kick, gr_pseudovel2vel, gr_vel2pseudovel public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, io_get_token, io_param_reader, io_param_writer, io_read_body_in, & io_read_cb_in, io_read_param_in, io_read_frame_body, io_read_frame_cb, io_read_frame_system, & @@ -162,8 +162,6 @@ module swiftest_classes real(DP), dimension(:), allocatable :: omega !! Argument of pericenter real(DP), dimension(:), allocatable :: capm !! Mean anomaly real(DP), dimension(:), allocatable :: mu !! G * (Mcb + [m]) - integer(I4B), dimension(:,:), allocatable :: k_eucl !! Index array used to convert flattened the body-body comparison upper triangular matrix - integer(I8B) :: nplpl !! Number of body-body comparisons in the flattened upper triangular matrix !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the !! component list, such as setup_body and util_spill contains @@ -209,7 +207,9 @@ module swiftest_classes real(DP), dimension(:,:), allocatable :: rot !! Body rotation vector in inertial coordinate frame (units rad / TU) real(DP), dimension(:), allocatable :: k2 !! Tidal Love number real(DP), dimension(:), allocatable :: Q !! Tidal quality factor - real(DP), dimension(:), allocatable :: tlag !! Tidal phase lag + real(DP), dimension(:), allocatable :: tlag !! Tidal phase lag + integer(I4B), dimension(:,:), allocatable :: k_plpl !! Index array used to convert flattened the body-body comparison upper triangular matrix + integer(I8B) :: nplpl !! Number of body-body comparisons in the flattened upper triangular matrix !! Note to developers: If you add components to this class, be sure to update methods and subroutines that traverse the !! component list, such as setup_pl and util_spill_pl contains @@ -247,7 +247,6 @@ module swiftest_classes ! Test particle-specific concrete methods ! These are concrete because they are the same implemenation for all integrators procedure, public :: discard => discard_tp !! Check to see if test particles should be discarded based on their positions relative to the massive bodies - procedure, public :: eucl_index => eucl_dist_index_pltp !! Sets up the (i, j) -> k indexing used for the single-loop blocking Euclidean distance matrix procedure, public :: accel_int => kick_getacch_int_tp !! Compute direct cross (third) term heliocentric accelerations of test particles by massive bodies procedure, public :: accel_obl => obl_acc_tp !! Compute the barycentric accelerations of bodies due to the oblateness of the central body procedure, public :: setup => setup_tp !! A base constructor that sets the number of bodies and @@ -388,7 +387,7 @@ module pure subroutine drift_all(mu, x, v, n, param, dt, mask, iflag) real(DP), dimension(:), intent(in) :: mu !! Vector of gravitational constants real(DP), dimension(:,:), intent(inout) :: x, v !! Position and velocity vectors integer(I4B), intent(in) :: n !! number of bodies - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize logical, dimension(:), intent(in) :: mask !! Logical mask of size self%nbody that determines which bodies to drift. integer(I4B), dimension(:), intent(out) :: iflag !! Vector of error flags. 0 means no problem @@ -416,12 +415,6 @@ module subroutine eucl_dist_index_plpl(self) class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object end subroutine - module subroutine eucl_dist_index_pltp(self, pl) - implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - end subroutine - module pure subroutine gr_getaccb_ns_body(self, system, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest generic body object diff --git a/src/modules/symba_classes.f90 b/src/modules/symba_classes.f90 index a25304a26..16e8de302 100644 --- a/src/modules/symba_classes.f90 +++ b/src/modules/symba_classes.f90 @@ -121,7 +121,9 @@ module symba_classes integer(I4B), dimension(:), allocatable :: index1 !! position of the planet in encounter integer(I4B), dimension(:), allocatable :: index2 !! position of the test particle in encounter contains - procedure, public :: setup => symba_setup_pltpenc !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure, public :: setup => symba_setup_pltpenc !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure, public :: copy => symba_util_copy_pltpenc !! Copies all elements of one pltpenc list to another + procedure, public :: resize => symba_util_resize_pltpenc !! Checks the current size of the pltpenc_list against the required size and extends it by a factor of 2 more than requested if it is too small end type symba_pltpenc !******************************************************************************************************************************** @@ -134,7 +136,8 @@ module symba_classes real(DP), dimension(:,:), allocatable :: vb1 !! the barycentric velocity of parent 1 in encounter real(DP), dimension(:,:), allocatable :: vb2 !! the barycentric velocity of parent 2 in encounter contains - procedure, public :: setup => symba_setup_plplenc !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure, public :: setup => symba_setup_plplenc !! A constructor that sets the number of encounters and allocates and initializes all arrays + procedure, public :: copy => symba_util_copy_plplenc !! Copies all elements of one plplenc list to another end type symba_plplenc !******************************************************************************************************************************** @@ -306,5 +309,24 @@ module subroutine symba_step_reset_system(self) implicit none class(symba_nbody_system), intent(inout) :: self !! SyMBA nbody system object end subroutine symba_step_reset_system + + module subroutine symba_util_copy_pltpenc(self, source) + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + class(symba_pltpenc), intent(in) :: source !! Source object to copy into + end subroutine symba_util_copy_pltpenc + + module subroutine symba_util_copy_plplenc(self, source) + implicit none + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_pltpenc), intent(in) :: source !! Source object to copy into + end subroutine symba_util_copy_plplenc + + module subroutine symba_util_resize_pltpenc(self, nrequested) + implicit none + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + integer(I4B), intent(in) :: nrequested !! New size of list needed + end subroutine symba_util_resize_pltpenc + end interface end module symba_classes \ No newline at end of file diff --git a/src/rmvs/rmvs_spill_and_fill.f90 b/src/rmvs/rmvs_util.f90 similarity index 91% rename from src/rmvs/rmvs_spill_and_fill.f90 rename to src/rmvs/rmvs_util.f90 index ae0ff563b..e950ab714 100644 --- a/src/rmvs/rmvs_spill_and_fill.f90 +++ b/src/rmvs/rmvs_util.f90 @@ -1,7 +1,7 @@ -submodule(rmvs_classes) s_rmvs_spill_and_fill +submodule(rmvs_classes) s_rmvs_util use swiftest contains - module subroutine rmvs_spill_pl(self, discards, lspill_list) + module subroutine rmvs_util_spill_pl(self, discards, lspill_list) !! author: David A. Minton !! !! Move spilled (discarded) RMVS test particle structure from active list to discard list @@ -31,9 +31,9 @@ module subroutine rmvs_spill_pl(self, discards, lspill_list) return - end subroutine rmvs_spill_pl + end subroutine rmvs_util_spill_pl - module subroutine rmvs_fill_pl(self, inserts, lfill_list) + module subroutine rmvs_util_fill_pl(self, inserts, lfill_list) !! author: David A. Minton !! !! Insert new RMVS massive body structure into an old one. @@ -62,9 +62,9 @@ module subroutine rmvs_fill_pl(self, inserts, lfill_list) return - end subroutine rmvs_fill_pl + end subroutine rmvs_util_fill_pl - module subroutine rmvs_spill_tp(self, discards, lspill_list) + module subroutine rmvs_util_spill_tp(self, discards, lspill_list) !! author: David A. Minton !! !! Move spilled (discarded) RMVS test particle structure from active list to discard list @@ -98,9 +98,9 @@ module subroutine rmvs_spill_tp(self, discards, lspill_list) return - end subroutine rmvs_spill_tp + end subroutine rmvs_util_spill_tp - module subroutine rmvs_fill_tp(self, inserts, lfill_list) + module subroutine rmvs_util_fill_tp(self, inserts, lfill_list) !! author: David A. Minton !! !! Insert new RMVS test particle structure into an old one. @@ -133,6 +133,6 @@ module subroutine rmvs_fill_tp(self, inserts, lfill_list) return - end subroutine rmvs_fill_tp + end subroutine rmvs_util_fill_tp -end submodule s_rmvs_spill_and_fill +end submodule s_rmvs_util diff --git a/src/symba/symba_encounter_check.f90 b/src/symba/symba_encounter_check.f90 index 633973dba..bbbb798de 100644 --- a/src/symba/symba_encounter_check.f90 +++ b/src/symba/symba_encounter_check.f90 @@ -1,36 +1,72 @@ submodule (symba_classes) s_symba_encounter_check use swiftest contains - module function symba_encounter_check_pl(self, system, dt, irec) result(lencounter) + module function symba_encounter_check_pl(self, system, dt, irec) result(lany_encounter) implicit none ! Arguments - class(symba_pl), intent(inout) :: self !! SyMBA test particle object - class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object - real(DP), intent(in) :: dt !! step size - integer(I4B), intent(in) :: irec !! Current recursion level + class(symba_pl), intent(inout) :: self !! SyMBA test particle object + class(symba_nbody_system), intent(inout) :: system !! SyMBA nbody system object + real(DP), intent(in) :: dt !! step size + integer(I4B), intent(in) :: irec !! Current recursion level ! Result - logical :: lencounter !! Returns true if there is at least one close encounter + logical :: lany_encounter !! Returns true if there is at least one close encounter ! Internals - integer(I4B) :: i, j - real(DP) :: r2, v2, vdotr - real(DP), dimension(NDIM) :: xr, vr - real(DP) :: rcrit, r2crit - logical :: lflag - - associate(pl => self, npl => self%nbody) - lencounter = .false. - !do concurrent(j = 1:npl, .not.pl%lmtiny(j)) - ! do i = 1, npl - rcrit = (pl%rhill(i) + pl%rhill(j)) * RHSCALE * (RSHELL**(irec)) - r2crit = r2crit**2 + real(DP) :: r2crit, vdotr, r2, v2, tmin, r2min, term2 + integer(I4B) :: j, nenc_old + integer(I8B) :: k + real(DP), dimension(NDIM) :: xr, vr + integer(I4B), dimension(:,:), allocatable :: ind + logical, dimension(:), allocatable :: lencounter, loc_lvdotr + + associate(pl => self, npl => self%nbody, nplpl => self%nplpl) + allocate(lencounter(nplpl), loc_lvdotr(nplpl)) + lencounter(:) = .false. + + term2 = RHSCALE * (RSHELL**irec) + + do k = 1, nplpl + associate(i => pl%k_plpl(1, k), j => pl%k_plpl(2, k)) xr(:) = pl%xh(:, j) - pl%xh(:, i) + r2 = dot_product(xr(:), xr(:)) + r2crit = ((pl%rhill(i) + pl%rhill(i)) * term2)**2 vr(:) = pl%vh(:, j) - pl%vh(:, i) - v2 = dot_product(vr(:), vr(:)) vdotr = dot_product(vr(:), xr(:)) - lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit) - if (lflag) lencounter = .true. - ! end do - !end do + if (r2 < r2crit) then + lencounter(k) = .true. + loc_lvdotr(k) = (vdotr < 0.0_DP) + else + if (vdotr < 0.0_DP) then + v2 = dot_product(vr(:), vr(:)) + tmin = -vdotr / v2 + if (tmin < dt) then + r2min = r2 - vdotr * vdotr / v2 + else + r2min = r2 + 2 * vdotr * dt + v2 * dt * dt + end if + r2min = min(r2min, r2) + if (r2min <= r2crit) then + lencounter(k) = .true. + loc_lvdotr(k) = (vdotr < 0.0_DP) + end if + end if + end if + end associate + end do + + lany_encounter = any(lencounter(:)) + if (lany_encounter) then + associate(plplenc_list => system%plplenc_list, nenc => system%plplenc_list%nenc) + nenc_old = nenc + call plplenc_list%resize(nenc_old + count(lencounter(:))) + plplenc_list%status(nenc_old+1:nenc) = ACTIVE + plplenc_list%level(nenc_old+1:nenc) = irec + plplenc_list%lvdotr(nenc_old+1:nenc) = pack(loc_lvdotr(:), lencounter(:)) + plplenc_list%index1(nenc_old+1:nenc) = pack(pl%k_plpl(1,:), lencounter(:)) + plplenc_list%index2(nenc_old+1:nenc) = pack(pl%k_plpl(2,:), lencounter(:)) + pl%lencounter(plplenc_list%index1(nenc_old+1:nenc)) = .true. + pl%lencounter(plplenc_list%index2(nenc_old+1:nenc)) = .true. + end associate + end if end associate return end function symba_encounter_check_pl diff --git a/src/symba/symba_setup.f90 b/src/symba/symba_setup.f90 index 94921f767..5ac26c220 100644 --- a/src/symba/symba_setup.f90 +++ b/src/symba/symba_setup.f90 @@ -1,7 +1,7 @@ submodule(symba_classes) s_symba_setup use swiftest contains - module subroutine symba_setup_pl(self,n) + module subroutine symba_setup_pl(self, n) !! author: David A. Minton !! !! Allocate SyMBA test particle structure @@ -43,7 +43,7 @@ module subroutine symba_setup_pl(self,n) return end subroutine symba_setup_pl - module subroutine symba_setup_pltpenc(self,n) + module subroutine symba_setup_pltpenc(self, n) !! author: David A. Minton !! !! A constructor that sets the number of encounters and allocates and initializes all arrays @@ -55,6 +55,11 @@ module subroutine symba_setup_pltpenc(self,n) self%nenc = n if (n == 0) return + if (allocated(self%lvdotr)) deallocate(self%lvdotr) + if (allocated(self%status)) deallocate(self%status) + if (allocated(self%level)) deallocate(self%level) + if (allocated(self%index1)) deallocate(self%index1) + if (allocated(self%index2)) deallocate(self%index2) allocate(self%lvdotr(n)) allocate(self%status(n)) allocate(self%level(n)) @@ -80,6 +85,10 @@ module subroutine symba_setup_plplenc(self,n) call symba_setup_pltpenc(self, n) if (n == 0) return + if (allocated(self%xh1)) deallocate(self%xh1) + if (allocated(self%xh2)) deallocate(self%xh2) + if (allocated(self%vb1)) deallocate(self%vb1) + if (allocated(self%vb2)) deallocate(self%vb2) allocate(self%xh1(NDIM,n)) allocate(self%xh2(NDIM,n)) allocate(self%vb1(NDIM,n)) diff --git a/src/symba/symba_util.f90 b/src/symba/symba_util.f90 new file mode 100644 index 000000000..81b351e65 --- /dev/null +++ b/src/symba/symba_util.f90 @@ -0,0 +1,67 @@ +submodule(symba_classes) s_symba_util + use swiftest +contains + module subroutine symba_util_copy_pltpenc(self, source) + !! author: David A. Minton + !! + !! Copies elements from the source encounter list into self. + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + class(symba_pltpenc), intent(in) :: source !! Source object to copy into + + associate(n => source%nenc) + self%nenc = n + self%lvdotr(1:n) = source%lvdotr(1:n) + self%status(1:n) = source%status(1:n) + self%level(1:n) = source%level(1:n) + self%index1(1:n) = source%index1(1:n) + self%index2(1:n) = source%index2(1:n) + end associate + end subroutine symba_util_copy_pltpenc + + module subroutine symba_util_copy_plplenc(self, source) + !! author: David A. Minton + !! + !! Copies elements from the source encounter list into self. + implicit none + ! Arguments + class(symba_plplenc), intent(inout) :: self !! SyMBA pl-pl encounter list + class(symba_pltpenc), intent(in) :: source !! Source object to copy into + + call symba_util_copy_pltpenc(self, source) + associate(n => source%nenc) + select type(source) + class is (symba_plplenc) + self%xh1(:,1:n) = source%xh1(:,1:n) + self%xh2(:,1:n) = source%xh2(:,1:n) + self%vb1(:,1:n) = source%vb1(:,1:n) + self%vb2(:,1:n) = source%vb2(:,1:n) + end select + end associate + end subroutine symba_util_copy_plplenc + + module subroutine symba_util_resize_pltpenc(self, nrequested) + !! author: David A. Minton + !! + !! Checks the current size of the encounter list against the required size and extends it by a factor of 2 more than requested if it is too small. + !! Polymorphic method works on both symba_pltpenc and symba_plplenc types + implicit none + ! Arguments + class(symba_pltpenc), intent(inout) :: self !! SyMBA pl-tp encounter list + integer(I4B), intent(in) :: nrequested !! New size of list needed + ! Internals + class(symba_pltpenc), allocatable :: enc_temp + integer(I4B) :: nold + + nold = size(self%status) + if (nrequested <= nold) return + allocate(enc_temp, source=self) + call self%setup(2 * nrequested) + call self%copy(enc_temp) + deallocate(enc_temp) + return + end subroutine symba_util_resize_pltpenc + + +end submodule s_symba_util \ No newline at end of file