From c5874591d8b2fcb75e45e04b4f1c157858c020b1 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 2 Jul 2021 16:16:02 -0400 Subject: [PATCH 01/12] Rewrote comments describing input parameters. Started process of adding system to the step method for bodies to make it more generalizable across all integrators. I'm doing this so that the system object always gets passed down, rather than pulling out individual components for each method --- Makefile.Defines | 4 +- src/discard/discard.f90 | 6 +-- src/helio/helio_drift.f90 | 4 +- src/helio/helio_getacch.f90 | 4 +- src/helio/helio_step.f90 | 7 ++-- src/io/io.f90 | 30 ++++++------- src/main/swiftest_driver.f90 | 2 +- src/modules/helio_classes.f90 | 14 +++---- src/modules/rmvs_classes.f90 | 6 +-- src/modules/swiftest_classes.f90 | 72 ++++++++++++++++++-------------- src/modules/symba.f90 | 4 +- src/modules/whm_classes.f90 | 32 +++++++------- src/rmvs/rmvs_getacch.f90 | 2 +- src/rmvs/rmvs_setup.f90 | 2 +- src/rmvs/rmvs_step.f90 | 10 ++--- src/setup/setup.f90 | 2 +- src/user/user_getacch.f90 | 2 +- src/whm/whm_drift.f90 | 4 +- src/whm/whm_getacch.f90 | 4 +- src/whm/whm_gr.f90 | 20 ++++----- src/whm/whm_setup.f90 | 2 +- src/whm/whm_step.f90 | 7 ++-- 22 files changed, 125 insertions(+), 115 deletions(-) diff --git a/Makefile.Defines b/Makefile.Defines index 820ad6d7d..07126f842 100644 --- a/Makefile.Defines +++ b/Makefile.Defines @@ -65,8 +65,8 @@ GPAR = -fopenmp -ftree-parallelize-loops=4 GMEM = -fsanitize=undefined -fsanitize=address -fsanitize=leak GWARNINGS = -Wall -Warray-bounds -Wimplicit-interface -Wextra -Warray-temporaries -#FFLAGS = $(IDEBUG) $(HEAPARR) -FFLAGS = -init=snan,arrays -no-wrap-margin -O3 $(STRICTREAL) $(SIMDVEC) $(PAR) +FFLAGS = $(IDEBUG) $(HEAPARR) +#FFLAGS = -init=snan,arrays -no-wrap-margin -O3 $(STRICTREAL) $(SIMDVEC) $(PAR) FORTRAN = ifort #AR = xiar diff --git a/src/discard/discard.f90 b/src/discard/discard.f90 index 513a59122..754cb468c 100644 --- a/src/discard/discard.f90 +++ b/src/discard/discard.f90 @@ -10,7 +10,7 @@ module subroutine discard_system(self, param) !! Adapted from Hal Levison's Swift routine discard.f implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters if (self%tp%nbody == 0) return select type(self) @@ -51,7 +51,7 @@ module subroutine discard_sun_tp(self, cb, param, t, msys) ! Arguments class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_parameters), intent(in) :: param !! parameters parameters + class(swiftest_parameters), intent(in) :: param !! parameters real(DP), intent(in) :: t !! Current simulation tim real(DP), intent(in) :: msys !! Total system mass ! Internals @@ -102,7 +102,7 @@ module subroutine discard_peri_tp(self, cb, pl, param, t, msys) class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - class(swiftest_parameters), intent(in) :: param !! parameters parameters + class(swiftest_parameters), intent(in) :: param !! parameters real(DP), intent(in) :: t !! Current simulation tim real(DP), intent(in) :: msys !! Total system mass ! Internals diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index ff0adc03a..1244533a0 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -13,7 +13,7 @@ module subroutine helio_drift_pl(self, cb, param, dt) ! Arguments class(helio_pl), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: dt !! Stepsize ! Internals integer(I4B) :: i !! Loop counter @@ -105,7 +105,7 @@ module subroutine helio_drift_tp(self, cb, param, dt) ! Arguments class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of 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 14fd76b4a..3dbcc4e45 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -12,7 +12,7 @@ module subroutine helio_getacch_pl(self, cb, param, t) ! Arguments class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time ! Internals logical, save :: lmalloc = .true. @@ -48,7 +48,7 @@ module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets ! Internals diff --git a/src/helio/helio_step.f90 b/src/helio/helio_step.f90 index df92c58c1..ca6df15fa 100644 --- a/src/helio/helio_step.f90 +++ b/src/helio/helio_step.f90 @@ -11,7 +11,7 @@ module subroutine helio_step_system(self, param) implicit none ! Arguments class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters select type(cb => self%cb) class is (helio_cb) @@ -45,7 +45,7 @@ module subroutine helio_step_pl(self, cb, param, t, dt) ! Arguments class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize ! Internals @@ -63,6 +63,7 @@ module subroutine helio_step_pl(self, cb, param, t, dt) call self%lindrift(cb, dth, ptbeg) call self%getacch(cb, param, t) call self%kickvb(dth) + call self%drift(cb, param, dt) call self%getacch(cb, param, t + dt) call self%kickvb(dth) @@ -85,7 +86,7 @@ module subroutine helio_step_tp(self, cb, pl, param, t, dt) class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize ! Internals diff --git a/src/io/io.f90 b/src/io/io.f90 index 0b75066af..6f40423c9 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -13,7 +13,7 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) !! Adapted from Martin Duncan's Swift routine io_init_param.f implicit none ! Arguments - class(swiftest_parameters), intent(inout) :: self !! Collection of parameters parameters + class(swiftest_parameters), intent(inout) :: self !! Collection of parameters integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. @@ -316,7 +316,7 @@ module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) !! Adapted from Martin Duncan's Swift routine io_dump_param.f implicit none ! Arguments - class(swiftest_parameters),intent(in) :: self !! Collection of parameters parameters + class(swiftest_parameters),intent(in) :: self !! Collection of parameters integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. @@ -405,7 +405,7 @@ module subroutine io_dump_param(self, param_file_name, t, dt) !! Adapted from Martin Duncan's Swift routine io_dump_param.f implicit none ! Arguments - class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + class(swiftest_parameters),intent(in) :: self !! Output collection of parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) real(DP),intent(in) :: t !! Current simulation time real(DP),intent(in) :: dt !! Step size @@ -444,7 +444,7 @@ module subroutine io_dump_swiftest(self, param, t, dt, msg) implicit none ! Arguments class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -483,7 +483,7 @@ module subroutine io_dump_system(self, param, t, dt, msg) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -636,7 +636,7 @@ module subroutine io_read_body_in(self, param) implicit none ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file integer(I4B) :: iu = LUN @@ -776,7 +776,7 @@ module subroutine io_read_param_in(self, param_file_name) !! Adapted from Martin Duncan's Swift routine io_init_param.f implicit none ! Arguments - class(swiftest_parameters),intent(out) :: self !! Input collection of parameters parameters + class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters of parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file @@ -870,7 +870,7 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -932,7 +932,7 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) ! Arguments class(swiftest_cb), intent(inout) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error cod @@ -966,7 +966,7 @@ module subroutine io_read_frame_system(self, iu, param, form, t, ierr) ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Current simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -1042,7 +1042,7 @@ module subroutine io_read_initialize_system(self, param) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters call self%cb%initialize(param) call self%pl%initialize(param) @@ -1063,7 +1063,7 @@ module subroutine io_write_discard(self, param, discards) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters class(swiftest_body), intent(inout) :: discards !! Swiftest discard object ! Internals integer(I4B), parameter :: LUN = 40 @@ -1196,7 +1196,7 @@ module subroutine io_write_frame_body(self, iu, param, t, dt) ! Arguments class(swiftest_body), intent(in) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size @@ -1252,7 +1252,7 @@ module subroutine io_write_frame_cb(self, iu, param, t, dt) ! Arguments class(swiftest_cb), intent(in) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size @@ -1288,7 +1288,7 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) ! Arguments class(swiftest_nbody_system), intent(in) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size ! Internals diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index 166dbe409..e88118d12 100644 --- a/src/main/swiftest_driver.f90 +++ b/src/main/swiftest_driver.f90 @@ -12,7 +12,7 @@ program swiftest_driver class(swiftest_nbody_system), allocatable :: nbody_system !! Polymorphic object containing the nbody system to be integrated type(swiftest_parameters) :: param integer(I4B) :: integrator !! Integrator type code (see swiftest_globals for symbolic names) - character(len=:),allocatable :: param_file_name !! Name of the file containing user-defined parameters parameters + character(len=:),allocatable :: param_file_name !! Name of the file containing user-defined parameters integer(I4B) :: ierr !! I/O error code logical :: lfirst !! Flag indicating that this is the first time through the main loop integer(I8B) :: iloop !! Loop counter diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index d7b2d2d8d..3d12882b2 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -97,7 +97,7 @@ module subroutine helio_drift_pl(self, cb, param, dt) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_pl @@ -106,7 +106,7 @@ module subroutine helio_drift_tp(self, cb, param, dt) implicit none class(helio_tp), intent(inout) :: self !! Helio test particle object class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_tp @@ -131,7 +131,7 @@ module subroutine helio_getacch_pl(self, cb, param, t) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current time end subroutine helio_getacch_pl @@ -142,7 +142,7 @@ module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! Swiftest massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine helio_getacch_tp @@ -178,7 +178,7 @@ module subroutine helio_step_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters end subroutine helio_step_system module subroutine helio_step_pl(self, cb, param, t, dt) @@ -186,7 +186,7 @@ module subroutine helio_step_pl(self, cb, param, t, dt) implicit none class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize end subroutine helio_step_pl @@ -198,7 +198,7 @@ module subroutine helio_step_tp(self, cb, pl, param, t, dt) class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize end subroutine helio_step_tp diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index 881185af1..4dea2e59f 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -124,7 +124,7 @@ module subroutine rmvs_getacch_tp(self, cb, pl, param, t, xh) class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of parameter + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine rmvs_getacch_tp @@ -133,7 +133,7 @@ module subroutine rmvs_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine rmvs_setup_system module subroutine rmvs_setup_pl(self,n) @@ -152,7 +152,7 @@ module subroutine rmvs_step_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters end subroutine rmvs_step_system module subroutine rmvs_setup_tp(self,n) diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 7be1b04b3..5dd39f74d 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -11,7 +11,7 @@ module swiftest_classes ! swiftest_parameters class definitions !******************************************************************************************************************************** - !> User defined parameters parameters that are read in from the parameters input file. + !> User defined parameters that are read in from the parameters input file. !> Each paramter is initialized to a default values. type, public :: swiftest_parameters integer(I4B) :: integrator = UNKNOWN_INTEGRATOR !! Symbolic name of the nbody integrator used @@ -141,8 +141,9 @@ module swiftest_classes !! component list, such as setup_body and util_spill contains private - procedure(abstract_set_mu), public, deferred :: set_mu + procedure(abstract_set_mu), public, deferred :: set_mu procedure(abstract_gr_getacch), public, deferred :: gr_getacch + procedure(abstract_step_body), public, deferred :: step ! These are concrete because the implementation is the same for all types of particles procedure, public :: gr_getaccb => gr_getaccb_ns_body !! Add relativistic correction acceleration for non-symplectic integrators procedure, public :: initialize => io_read_body_in !! Read in body initial conditions from a file @@ -160,6 +161,7 @@ module swiftest_classes procedure, public :: fill => util_fill_body !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: spill => util_spill_body !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) procedure, public :: reverse_status => util_reverse_status !! Reverses the active/inactive status of all particles in a structure + procedure, public :: step end type swiftest_body !******************************************************************************************************************************** @@ -272,20 +274,20 @@ subroutine abstract_gr_getacch(self, cb, param) import swiftest_body, swiftest_cb, swiftest_parameters class(swiftest_body), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of parameter + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter end subroutine abstract_gr_getacch subroutine abstract_initialize(self, param) import swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine abstract_initialize subroutine abstract_read_frame(self, iu, param, form, t, ierr) import DP, I4B, swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -294,21 +296,29 @@ end subroutine abstract_read_frame subroutine abstract_set_mu(self, cb) import swiftest_body, swiftest_cb class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body objectt + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object end subroutine abstract_set_mu + subroutine abstract_step_body(self, system, param, dt) + import swiftest_nbody_system, swiftest_parameters + implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + end subroutine abstract_step_body + subroutine abstract_step_system(self, param) import swiftest_nbody_system, swiftest_parameters implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine abstract_step_system subroutine abstract_write_frame(self, iu, param, t, dt) import DP, I4B, swiftest_base, swiftest_parameters class(swiftest_base), intent(in) :: self !! Swiftest base object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size end subroutine abstract_write_frame @@ -320,7 +330,7 @@ module subroutine discard_peri_tp(self, cb, pl, param, t, msys) class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - class(swiftest_parameters), intent(in) :: param !! parameters parameters + class(swiftest_parameters), intent(in) :: param !! parameters real(DP), intent(in) :: t !! Current simulation tim real(DP), intent(in) :: msys !! Total system mass end subroutine discard_peri_tp @@ -345,7 +355,7 @@ module subroutine discard_sun_tp(self, cb, param, t, msys) implicit none class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_parameters), intent(in) :: param !! parameters parameters + class(swiftest_parameters), intent(in) :: param !! parameters real(DP), intent(in) :: t !! Current simulation tim real(DP), intent(in) :: msys !! Total system mass end subroutine discard_sun_tp @@ -353,7 +363,7 @@ end subroutine discard_sun_tp module subroutine discard_system(self, param) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters end subroutine discard_system module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) @@ -402,7 +412,7 @@ module subroutine kick_vh_body(self, dt) end subroutine kick_vh_body module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) - class(swiftest_parameters), intent(inout) :: self !! Collection of parameters parameters + class(swiftest_parameters), intent(inout) :: self !! Collection of parameters integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. @@ -412,7 +422,7 @@ module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) end subroutine io_param_reader module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) - class(swiftest_parameters),intent(in) :: self !! Collection of parameters parameters + class(swiftest_parameters),intent(in) :: self !! Collection of parameters integer, intent(in) :: unit !! File unit number character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. !! If you do not include a char-literal-constant, the iotype argument contains only DT. @@ -422,7 +432,7 @@ module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) end subroutine io_param_writer module subroutine io_dump_param(self, param_file_name, t, dt) - class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + class(swiftest_parameters),intent(in) :: self !! Output collection of parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) real(DP),intent(in) :: t !! Current simulation time real(DP),intent(in) :: dt !! Step size @@ -431,7 +441,7 @@ end subroutine io_dump_param module subroutine io_dump_swiftest(self, param, t, dt, msg) implicit none class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -440,7 +450,7 @@ end subroutine io_dump_swiftest module subroutine io_dump_system(self, param, t, dt, msg) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -464,7 +474,7 @@ end function io_get_token module subroutine io_read_body_in(self, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine io_read_body_in module subroutine io_read_cb_in(self, param) @@ -474,7 +484,7 @@ module subroutine io_read_cb_in(self, param) end subroutine io_read_cb_in module subroutine io_read_param_in(self, param_file_name) - class(swiftest_parameters),intent(out) :: self !! Input collection of parameters parameters + class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters of parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) end subroutine io_read_param_in @@ -492,7 +502,7 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -502,7 +512,7 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) implicit none class(swiftest_cb), intent(inout) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -512,7 +522,7 @@ module subroutine io_read_frame_system(self, iu, param, form, t, ierr) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Current simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -531,13 +541,13 @@ end function io_read_hdr 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 !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine io_read_initialize_system module subroutine io_write_discard(self, param, discards) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters class(swiftest_body), intent(inout) :: discards !! Swiftest discard object end subroutine io_write_discard @@ -554,7 +564,7 @@ module subroutine io_write_frame_body(self, iu, param, t, dt) implicit none class(swiftest_body), intent(in) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size end subroutine io_write_frame_body @@ -563,7 +573,7 @@ module subroutine io_write_frame_cb(self, iu, param, t, dt) implicit none class(swiftest_cb), intent(in) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size end subroutine io_write_frame_cb @@ -572,7 +582,7 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) implicit none class(swiftest_nbody_system), intent(in) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size end subroutine io_write_frame_system @@ -633,7 +643,7 @@ end subroutine setup_body module subroutine setup_construct_system(system, param) implicit none class(swiftest_nbody_system), allocatable, intent(inout) :: system !! Swiftest system object - type(swiftest_parameters), intent(in) :: param !! Swiftest parameters parameters + type(swiftest_parameters), intent(in) :: param !! Swiftest parameters end subroutine setup_construct_system module subroutine setup_pl(self,n) @@ -655,13 +665,13 @@ end subroutine setup_set_msys module subroutine setup_set_mu_pl(self, cb) implicit none class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body objectt + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object end subroutine setup_set_mu_pl module subroutine setup_set_mu_tp(self, cb) implicit none class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body objectt + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object end subroutine setup_set_mu_tp module subroutine setup_set_rhill(self,cb) @@ -680,7 +690,7 @@ module subroutine user_getacch_body(self, cb, param, t) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time end subroutine user_getacch_body diff --git a/src/modules/symba.f90 b/src/modules/symba.f90 index bb0361d5c..82ff837a1 100644 --- a/src/modules/symba.f90 +++ b/src/modules/symba.f90 @@ -457,7 +457,7 @@ module subroutine symba_set_initial_conditions(symba_plA, symba_tpA, param) implicit none type(symba_pl), intent(inout) :: symba_plA !! SyMBA massive body structure type(symba_tp), intent(inout) :: symba_tpA !! SyMBA test particle structure - type(swiftest_parameters) :: param !! Input collection of on parameters + type(swiftest_parameters) :: param !! Current run configuration parameters of on parameters end subroutine symba_set_initial_conditions !> Method to remove the inactive symba test particles and spill them to a discard object @@ -745,7 +745,7 @@ subroutine symba_encounter_dummy_input(self,param) !! This method is needed in order to extend the abstract type swiftest_body. It does nothing implicit none class(symba_encounter), intent(inout) :: self !! SyMBA encounter data structure - type(swiftest_parameters),intent(in) :: param !! Input collection of on parameters + type(swiftest_parameters),intent(in) :: param !! Current run configuration parameters of on parameters return end subroutine symba_encounter_dummy_input diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index 02e4c0806..af6d62106 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -112,7 +112,7 @@ module subroutine whm_step_pl(self, cb, param, t, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize end subroutine whm_step_pl @@ -123,7 +123,7 @@ module subroutine whm_getacch_pl(self, cb, param, t) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time end subroutine whm_getacch_pl @@ -132,7 +132,7 @@ module subroutine whm_drift_pl(self, cb, param, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structur - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: dt !! Stepsize end subroutine whm_drift_pl @@ -169,14 +169,14 @@ module subroutine whm_gr_getacch_pl(self, cb, param) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of end subroutine whm_gr_getacch_pl module pure subroutine whm_gr_p4_pl(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl @@ -184,14 +184,14 @@ module pure subroutine whm_gr_vh2pv_pl(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_vh2pv_pl module pure subroutine whm_gr_pv2vh_pl(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_pv2vh_pl !> WHM test particle constructor @@ -206,7 +206,7 @@ module subroutine whm_drift_tp(self, cb, param, dt) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: dt !! Stepsize end subroutine whm_drift_tp @@ -217,7 +217,7 @@ module subroutine whm_getacch_tp(self, cb, pl, param, t, xh) class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Generic Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine whm_getacch_tp @@ -228,7 +228,7 @@ module subroutine whm_step_tp(self, cb, pl, param, t, dt) class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize end subroutine whm_step_tp @@ -245,14 +245,14 @@ module subroutine whm_gr_getacch_tp(self, cb, param) implicit none class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of end subroutine whm_gr_getacch_tp module pure subroutine whm_gr_p4_tp(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp @@ -260,21 +260,21 @@ module pure subroutine whm_gr_vh2pv_tp(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_vh2pv_tp module pure subroutine whm_gr_pv2vh_tp(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_pv2vh_tp module subroutine whm_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters end subroutine whm_setup_system module subroutine whm_spill_pl(self, discards, lspill_list) @@ -298,7 +298,7 @@ module subroutine whm_step_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(whm_nbody_system), intent(inout) :: self !! WHM system object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_step_system end interface diff --git a/src/rmvs/rmvs_getacch.f90 b/src/rmvs/rmvs_getacch.f90 index 6201c42da..15fbc3b7a 100644 --- a/src/rmvs/rmvs_getacch.f90 +++ b/src/rmvs/rmvs_getacch.f90 @@ -13,7 +13,7 @@ module subroutine rmvs_getacch_tp(self, cb, pl, param, t, xh) class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of parameter + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets ! Internals diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index 95634e0a1..845f8d5b0 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -86,7 +86,7 @@ module subroutine rmvs_setup_system(self, param) implicit none ! Arguments class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object - class(swiftest_parameters), intent(inout) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters ! Internals integer(I4B) :: i, j diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 index 4d864e807..0fad19590 100644 --- a/src/rmvs/rmvs_step.f90 +++ b/src/rmvs/rmvs_step.f90 @@ -11,7 +11,7 @@ module subroutine rmvs_step_system(self, param) implicit none ! Arguments class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters ! Internals logical :: lencounter, lfirstpl, lfirsttp real(DP) :: rts @@ -77,7 +77,7 @@ subroutine rmvs_step_out(pl, cb, tp, dt, param) class(rmvs_cb), intent(inout) :: cb !! RMVS central body object class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object real(DP), intent(in) :: dt !! Step size - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters ! Internals integer(I4B) :: outer_index, j, k real(DP) :: dto, outer_time, rts @@ -131,7 +131,7 @@ subroutine rmvs_step_in(pl, cb, tp, param, outer_time, dto) class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object class(rmvs_cb), intent(inout) :: cb !! RMVS central body object class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: outer_time !! Current time real(DP), intent(in) :: dto !! Step size ! Internals @@ -386,7 +386,7 @@ subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) logical, intent(in) :: lfirst !! Logical flag indicating whether current invocation is the first integer(I4B), intent(in) :: inner_index !! Outer substep number within current set integer(I4B), intent(in) :: ipleP !! index of RMVS planet being closely encountered - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters ! Internals integer(I4B) :: i, id1, id2 real(DP) :: r2, mu, rhill2, vdotr, a, peri, capm, tperi, rpl @@ -465,7 +465,7 @@ subroutine rmvs_make_planetocentric(pl, cb, tp, param) class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object class(rmvs_cb), intent(inout) :: cb !! RMVS central body particle type class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters ! Internals integer(I4B) :: i, j, inner_index, ipc2hc logical, dimension(:), allocatable :: encmask diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index 753c3e90c..779cab908 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -9,7 +9,7 @@ module subroutine setup_construct_system(system, param) implicit none ! Arguments class(swiftest_nbody_system), allocatable, intent(inout) :: system !! Swiftest system object - type(swiftest_parameters), intent(in) :: param !! Swiftest parameters parameters + type(swiftest_parameters), intent(in) :: param !! Swiftest parameters select case(param%integrator) case (BS) diff --git a/src/user/user_getacch.f90 b/src/user/user_getacch.f90 index 59b922f15..e3733303a 100644 --- a/src/user/user_getacch.f90 +++ b/src/user/user_getacch.f90 @@ -11,7 +11,7 @@ module subroutine user_getacch_body(self, cb, param, t) ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of user parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of user parameters real(DP), intent(in) :: t !! Current time return diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index d5f915b13..19213bc23 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -12,7 +12,7 @@ module subroutine whm_drift_pl(self, cb, param, dt) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structur - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: dt !! Stepsize ! Internals integer(I4B) :: i @@ -75,7 +75,7 @@ module subroutine whm_drift_tp(self, cb, param, dt) ! Arguments class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: dt !! Stepsize ! Internals integer(I4B) :: i diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 2bfed8d8f..128915360 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -12,7 +12,7 @@ module subroutine whm_getacch_pl(self, cb, param, t) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time ! Internals integer(I4B) :: i @@ -51,7 +51,7 @@ module subroutine whm_getacch_tp(self, cb, pl, param, t, xh) class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Generic Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! Generic Swiftest massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets ! Internals diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 index e938b0b9b..073ddc2ae 100644 --- a/src/whm/whm_gr.f90 +++ b/src/whm/whm_gr.f90 @@ -12,7 +12,7 @@ module subroutine whm_gr_getacch_pl(self, cb, param) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: suma @@ -50,7 +50,7 @@ module subroutine whm_gr_getacch_tp(self, cb, param) ! Arguments class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of ! Internals integer(I4B) :: i real(DP) :: rjmag4, beta @@ -78,7 +78,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 !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters real(DP), intent(in) :: dt !! Step size ! Internals integer(I4B) :: i @@ -104,7 +104,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 !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters real(DP), intent(in) :: dt !! Step size ! Internals integer(I4B) :: i @@ -128,7 +128,7 @@ module pure subroutine whm_gr_pv2vh_pl(self, param) implicit none ! Arguments class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion @@ -154,7 +154,7 @@ module pure subroutine whm_gr_pv2vh_tp(self, param) implicit none ! Arguments class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: vh !! Temporary holder of pseudovelocity for in-place conversion @@ -180,7 +180,7 @@ module pure subroutine whm_gr_vh2pv_pl(self, param) implicit none ! Arguments class(whm_pl), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion @@ -206,7 +206,7 @@ module pure subroutine whm_gr_vh2pv_tp(self, param) implicit none ! Arguments class(whm_tp), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters ! Internals integer(I4B) :: i real(DP), dimension(:,:), allocatable :: pv !! Temporary holder of pseudovelocity for in-place conversion @@ -234,7 +234,7 @@ pure subroutine gr_vel2pseudovel(param, mu, xh, vh, pv) !! Adapted from David A. Minton's Swifter routine gr_vel2pseudovel.f90 implicit none - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector real(DP), dimension(:), intent(in) :: vh !! Heliocentric velocity vector @@ -306,7 +306,7 @@ pure subroutine gr_pseudovel2vel(param, mu, xh, pv, vh) !! !! Adapted from David A. Minton's Swifter routine gr_pseudovel2vel.f90 implicit none - class(swiftest_parameters), intent(in) :: param !! Input collection of parameters parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector real(DP), dimension(:), intent(in) :: pv !! Pseudovelocity velocity vector - see Saha & Tremain (1994), eq. (32) diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 index af3f4c774..cdec4e1fb 100644 --- a/src/whm/whm_setup.f90 +++ b/src/whm/whm_setup.f90 @@ -80,7 +80,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 !! Input collection of on parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters call io_read_initialize_system(self, param) ! Make sure that the discard list gets allocated initially call self%tp_discards%setup(self%tp%nbody) diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index da504963b..05aeebde9 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -2,7 +2,6 @@ use swiftest contains - module subroutine whm_step_system(self, param) !! author: David A. Minton !! @@ -13,7 +12,7 @@ module subroutine whm_step_system(self, param) implicit none ! Arguments class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Input collection of on parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters select type(cb => self%cb) class is (whm_cb) @@ -48,7 +47,7 @@ module subroutine whm_step_pl(self, cb, param, t, dt) ! Arguments class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize ! Internals @@ -88,7 +87,7 @@ module subroutine whm_step_tp(self, cb, pl, param, t, dt) class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Input collection of + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize ! Internals From 8f4e883353e6d6fd5e3a00c39ba12d8dcf0af5e8 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 2 Jul 2021 17:19:47 -0400 Subject: [PATCH 02/12] Restructured the swiftest and whm classes to accept system variabiles in place of individual cb, pl, and tp for most cases --- src/main/swiftest_driver.f90 | 8 +- src/modules/rmvs_classes.f90 | 21 +-- src/modules/swiftest_classes.f90 | 218 ++++++++++++++----------------- src/modules/whm_classes.f90 | 112 ++++++++-------- src/rmvs/rmvs_step.f90 | 46 +++---- src/whm/whm_drift.f90 | 38 +++--- src/whm/whm_getacch.f90 | 46 +++---- src/whm/whm_gr.f90 | 24 ++-- src/whm/whm_step.f90 | 51 ++++---- 9 files changed, 263 insertions(+), 301 deletions(-) diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index e88118d12..3c9f3c8ac 100644 --- a/src/main/swiftest_driver.f90 +++ b/src/main/swiftest_driver.f90 @@ -48,7 +48,7 @@ program swiftest_driver iloop = 0 iout = istep_out idump = istep_dump - if (istep_out > 0) call nbody_system%write_frame(iu, param, t, dt) + if (istep_out > 0) call nbody_system%write_frame(iu, param) !> Define the maximum number of threads nthreads = 1 ! In the *serial* case !$ nthreads = omp_get_max_threads() ! In the *parallel* case @@ -60,7 +60,7 @@ program swiftest_driver ntp = nbody_system%tp%nbody npl = nbody_system%pl%nbody !> Step the system forward in time - call nbody_system%step(param) + call nbody_system%step(param, t, dt) t = t0 + iloop * dt if (t > tstop) exit @@ -72,7 +72,7 @@ program swiftest_driver if (istep_out > 0) then iout = iout - 1 if (iout == 0) then - call nbody_system%write_frame(iu, param, t, dt) + call nbody_system%write_frame(iu, param) iout = istep_out end if end if @@ -81,7 +81,7 @@ program swiftest_driver if (istep_dump > 0) then idump = idump - 1 if (idump == 0) then - call nbody_system%dump(param, t, dt, statusfmt) + call nbody_system%dump(param, statusfmt) idump = istep_dump end if end if diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index 4dea2e59f..b67c354b0 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -117,16 +117,15 @@ module subroutine rmvs_discard_pl_tp(self, pl, t, dt) real(DP), intent(in) :: dt !! Stepsize end subroutine rmvs_discard_pl_tp - module subroutine rmvs_getacch_tp(self, cb, pl, param, t, xh) + module subroutine rmvs_getacch_tp(self, system, param, t, xh) use swiftest_classes, only : swiftest_cb, swiftest_parameters - use whm_classes, only : whm_pl + use whm_classes, only : whm_nbody_system implicit none - class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. + class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure + class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine rmvs_getacch_tp module subroutine rmvs_setup_system(self, param) @@ -148,11 +147,13 @@ module subroutine rmvs_setup_set_beg_end(self, xbeg, xend, vbeg) real(DP), dimension(:,:), intent(in), optional :: xbeg, xend, vbeg end subroutine rmvs_setup_set_beg_end - module subroutine rmvs_step_system(self, param) + module subroutine rmvs_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine rmvs_step_system module subroutine rmvs_setup_tp(self,n) diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 5dd39f74d..62ea97d6f 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -142,10 +142,8 @@ module swiftest_classes contains private procedure(abstract_set_mu), public, deferred :: set_mu - procedure(abstract_gr_getacch), public, deferred :: gr_getacch procedure(abstract_step_body), public, deferred :: step ! These are concrete because the implementation is the same for all types of particles - procedure, public :: gr_getaccb => gr_getaccb_ns_body !! Add relativistic correction acceleration for non-symplectic integrators 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 @@ -161,7 +159,6 @@ module swiftest_classes procedure, public :: fill => util_fill_body !! "Fills" bodies from one object into another depending on the results of a mask (uses the MERGE intrinsic) procedure, public :: spill => util_spill_body !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) procedure, public :: reverse_status => util_reverse_status !! Reverses the active/inactive status of all particles in a structure - procedure, public :: step end type swiftest_body !******************************************************************************************************************************** @@ -270,13 +267,6 @@ subroutine abstract_copy(self, src, mask) logical, dimension(:), intent(in) :: mask end subroutine abstract_copy - subroutine abstract_gr_getacch(self, cb, param) - import swiftest_body, swiftest_cb, swiftest_parameters - class(swiftest_body), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter - end subroutine abstract_gr_getacch - subroutine abstract_initialize(self, param) import swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object @@ -299,48 +289,50 @@ subroutine abstract_set_mu(self, cb) class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object end subroutine abstract_set_mu - subroutine abstract_step_body(self, system, param, dt) - import swiftest_nbody_system, swiftest_parameters + subroutine abstract_step_body(self, system, param, t, dt) + import DP, swiftest_body, swiftest_nbody_system, swiftest_parameters implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine abstract_step_body - subroutine abstract_step_system(self, param) - import swiftest_nbody_system, swiftest_parameters + subroutine abstract_step_system(self, param, t, dt) + import DP, swiftest_nbody_system, swiftest_parameters implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine abstract_step_system - subroutine abstract_write_frame(self, iu, param, t, dt) + subroutine abstract_write_frame(self, iu, param) import DP, I4B, swiftest_base, swiftest_parameters - class(swiftest_base), intent(in) :: self !! Swiftest base object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_base), intent(in) :: self !! Swiftest base 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 of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size end subroutine abstract_write_frame end interface interface module subroutine discard_peri_tp(self, cb, pl, param, t, msys) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: msys !! Total system mass + real(DP), intent(in) :: t !! Current simulation tim + real(DP), intent(in) :: msys !! Total system mass end subroutine discard_peri_tp module subroutine discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) implicit none - real(DP), dimension(:), intent(in) :: dx, dv - real(DP), intent(in) :: dt, r2crit - integer(I4B), intent(out) :: iflag - real(DP), intent(out) :: r2min + real(DP), dimension(:), intent(in) :: dx, dv + real(DP), intent(in) :: dt, r2crit + integer(I4B), intent(out) :: iflag + real(DP), intent(out) :: r2min end subroutine discard_pl_close module subroutine discard_pl_tp(self, pl, t, dt) @@ -351,19 +343,18 @@ module subroutine discard_pl_tp(self, pl, t, dt) real(DP), intent(in) :: dt !! Stepsize end subroutine discard_pl_tp - module subroutine discard_sun_tp(self, cb, param, t, msys) + module subroutine discard_sun_tp(self, cb, param, msys) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: msys !! Total system mass + real(DP), intent(in) :: msys !! Total system mass end subroutine discard_sun_tp module subroutine discard_system(self, param) implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters end subroutine discard_system module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) @@ -376,33 +367,24 @@ end subroutine drift_one module subroutine eucl_dist_index_plpl(self) implicit none - class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + 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 + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + 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 + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object end subroutine eucl_irij3_plpl - module subroutine gr_getaccb_ns_body(self, cb, param, agr, agr0) - implicit none - class(swiftest_body), intent(inout) :: self - class(swiftest_cb), intent(inout) :: cb - class(swiftest_parameters), intent(in) :: param - real(DP), dimension(:, :), intent(inout) :: agr - real(DP), dimension(NDIM), intent(out) :: agr0 - end subroutine gr_getaccb_ns_body - module subroutine kick_vb_body(self, dt) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest generic body object - real(DP), intent(in) :: dt !! Stepsize + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + real(DP), intent(in) :: dt !! Stepsize end subroutine kick_vb_body module subroutine kick_vh_body(self, dt) @@ -412,47 +394,44 @@ module subroutine kick_vh_body(self, dt) end subroutine kick_vh_body module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + implicit none class(swiftest_parameters), intent(inout) :: self !! Collection of parameters - integer, intent(in) :: unit !! File unit number - character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. - !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer, intent(in) :: v_list(:) !! The first element passes the integrator code to the reader - integer, intent(out) :: iostat !! IO status code - character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 end subroutine io_param_reader module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) - class(swiftest_parameters),intent(in) :: self !! Collection of parameters - integer, intent(in) :: unit !! File unit number - character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. - !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer, intent(in) :: v_list(:) !! Not used in this procedure - integer, intent(out) :: iostat !! IO status code - character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + implicit none + class(swiftest_parameters), intent(in) :: self !! Collection of parameters + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! Not used in this procedure + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 end subroutine io_param_writer - module subroutine io_dump_param(self, param_file_name, t, dt) - class(swiftest_parameters),intent(in) :: self !! Output collection of parameters - character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) - real(DP),intent(in) :: t !! Current simulation time - real(DP),intent(in) :: dt !! Step size + module subroutine io_dump_param(self, param_file_name) + implicit none + class(swiftest_parameters),intent(in) :: self !! Output collection of parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) end subroutine io_dump_param - module subroutine io_dump_swiftest(self, param, t, dt, msg) + module subroutine io_dump_swiftest(self, param, msg) implicit none class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters character(*), optional, intent(in) :: msg !! Message to display with dump operation end subroutine io_dump_swiftest - module subroutine io_dump_system(self, param, t, dt, msg) + module subroutine io_dump_system(self, param, msg) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters character(*), optional, intent(in) :: msg !! Message to display with dump operation end subroutine io_dump_system @@ -473,59 +452,60 @@ end function io_get_token module subroutine io_read_body_in(self, param) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_body), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters end subroutine io_read_body_in module subroutine io_read_cb_in(self, param) implicit none - class(swiftest_cb), intent(inout) :: self + class(swiftest_cb), intent(inout) :: self class(swiftest_parameters), intent(inout) :: param end subroutine io_read_cb_in module subroutine io_read_param_in(self, param_file_name) - class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters of parameters - character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) + implicit none + class(swiftest_parameters), intent(out) :: self !! Current run configuration parameters of parameters + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) end subroutine io_read_param_in module function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & xh1, xh2, vh1, vh2, encounter_file, out_type) result(ierr) implicit none - integer(I4B) :: ierr - integer(I4B), intent(out) :: name1, name2 - real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 - real(DP), dimension(NDIM), intent(out) :: xh1, xh2, vh1, vh2 - character(*), intent(in) :: encounter_file,out_type + integer(I4B) :: ierr + integer(I4B), intent(out) :: name1, name2 + real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(NDIM), intent(out) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: encounter_file,out_type end function io_read_encounter module subroutine io_read_frame_body(self, iu, param, form, t, ierr) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest particle object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time - integer(I4B), intent(out) :: ierr !! Error code + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + real(DP), intent(out) :: t !! Simulation time + integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_body module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) implicit none - class(swiftest_cb), intent(inout) :: self !! Swiftest central body object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_cb), intent(inout) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time - integer(I4B), intent(out) :: ierr !! Error code + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + real(DP), intent(out) :: t !! Simulation time + integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_cb module subroutine io_read_frame_system(self, iu, param, form, t, ierr) implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Current simulation time - integer(I4B), intent(out) :: ierr !! Error code + class(swiftest_nbody_system),intent(inout) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + real(DP), intent(out) :: t !! Current simulation time + integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_system module function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) @@ -560,31 +540,25 @@ module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, rad character(*), intent(in) :: encounter_file, out_type end subroutine io_write_encounter - module subroutine io_write_frame_body(self, iu, param, t, dt) + module subroutine io_write_frame_body(self, iu, param) implicit none class(swiftest_body), intent(in) :: self !! Swiftest particle 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 of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size end subroutine io_write_frame_body - module subroutine io_write_frame_cb(self, iu, param, t, dt) + module subroutine io_write_frame_cb(self, iu, param) implicit none class(swiftest_cb), intent(in) :: self !! Swiftest central body 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 of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size end subroutine io_write_frame_cb - module subroutine io_write_frame_system(self, iu, param, t, dt) + module subroutine io_write_frame_system(self, iu, param) implicit none class(swiftest_nbody_system), intent(in) :: self !! Swiftest system 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 of parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters end subroutine io_write_frame_system module subroutine io_write_hdr(iu, t, npl, ntp, out_form, out_type) @@ -688,10 +662,10 @@ end subroutine setup_tp module subroutine user_getacch_body(self, cb, param, t) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: t !! Current time end subroutine user_getacch_body module subroutine util_coord_b2h_pl(self, cb) @@ -720,7 +694,7 @@ end subroutine util_coord_h2b_tp module subroutine util_copy_body(self, src, mask) implicit none - class(swiftest_body), intent(inout) :: self + class(swiftest_body), intent(inout) :: self class(swiftest_base), intent(in) :: src logical, dimension(:), intent(in) :: mask end subroutine util_copy_body @@ -756,8 +730,8 @@ end subroutine util_copy_system module subroutine util_fill_body(self, inserts, lfill_list) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest generic body object - class(swiftest_body), intent(inout) :: inserts !! Insertted object + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_body), intent(inout) :: inserts !! Insertted object logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps end subroutine util_fill_body diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index af6d62106..282ced72a 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -107,130 +107,127 @@ module subroutine whm_setup_set_ir3j(self) class(whm_pl), intent(inout) :: self !! WHM massive body object end subroutine whm_setup_set_ir3j - module subroutine whm_step_pl(self, cb, param, t, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module subroutine whm_step_pl(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine whm_step_pl !> Get heliocentric accelration of massive bodies - module subroutine whm_getacch_pl(self, cb, param, t) + module subroutine whm_getacch_pl(self, system, param, t) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + real(DP), intent(in) :: t !! Current simulation time end subroutine whm_getacch_pl - module subroutine whm_drift_pl(self, cb, param, dt) + module subroutine whm_drift_pl(self, system, param, dt) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structur - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(whm_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_pl module subroutine whm_getacch_int_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure end subroutine whm_getacch_int_pl module subroutine whm_coord_h2j_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree end subroutine whm_coord_h2j_pl module subroutine whm_coord_j2h_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree end subroutine whm_coord_j2h_pl module subroutine whm_coord_vh2vj_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree end subroutine whm_coord_vh2vj_pl - module subroutine whm_gr_getacch_pl(self, cb, param) + 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_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of end subroutine whm_gr_getacch_pl module pure subroutine whm_gr_p4_pl(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl module pure subroutine whm_gr_vh2pv_pl(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_vh2pv_pl module pure subroutine whm_gr_pv2vh_pl(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_pv2vh_pl !> WHM test particle constructor module subroutine whm_setup_tp(self,n) implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - integer, intent(in) :: n !! Number of test particles to allocate + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + integer, intent(in) :: n !! Number of test particles to allocate end subroutine whm_setup_tp - module subroutine whm_drift_tp(self, cb, param, dt) + module subroutine whm_drift_tp(self, system, param, dt) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(whm_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 + real(DP), intent(in) :: dt !! Stepsize end subroutine whm_drift_tp !> Get heliocentric accelration of the test particle - module subroutine whm_getacch_tp(self, cb, pl, param, t, xh) + module subroutine whm_getacch_tp(self, system, param, t, xh) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Generic Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine whm_getacch_tp - module subroutine whm_step_tp(self, cb, pl, param, t, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module subroutine whm_step_tp(self, system, param, t, 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_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + 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(inout) :: param !! Current run configuration parameters of + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize end subroutine whm_step_tp module subroutine whm_setup_set_beg_end(self, xbeg, xend, vbeg) @@ -240,26 +237,25 @@ module subroutine whm_setup_set_beg_end(self, xbeg, xend, vbeg) real(DP), dimension(:,:), intent(in), optional :: vbeg ! vbeg is an unused variable to keep this method forward compatible with RMVS end subroutine whm_setup_set_beg_end - module subroutine whm_gr_getacch_tp(self, cb, param) + module subroutine whm_gr_getacch_tp(self, param) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of end subroutine whm_gr_getacch_tp module pure subroutine whm_gr_p4_tp(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp module pure subroutine whm_gr_vh2pv_tp(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_vh2pv_tp @@ -294,11 +290,13 @@ module subroutine whm_fill_pl(self, inserts, lfill_list) end subroutine whm_fill_pl !> Steps the Swiftest nbody system forward in time one stepsize - module subroutine whm_step_system(self, param) + module subroutine whm_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_nbody_system), intent(inout) :: self !! WHM system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(whm_nbody_system), intent(inout) :: self !! WHM system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + real(DP), intent(in) :: t !! Simulation time + real(DP), intent(in) :: dt !! Current stepsize end subroutine whm_step_system end interface diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 index 0fad19590..82c6d28c4 100644 --- a/src/rmvs/rmvs_step.f90 +++ b/src/rmvs/rmvs_step.f90 @@ -1,7 +1,7 @@ submodule(rmvs_classes) s_rmvs_step use swiftest contains - module subroutine rmvs_step_system(self, param) + module subroutine rmvs_step_system(self, param, dt) !! author: David A. Minton !! !! Step massive bodies and and active test particles ahead in heliocentric coordinates @@ -10,23 +10,24 @@ module subroutine rmvs_step_system(self, param) !! Adapted from David E. Kaufmann's Swifter routine rmvs_step.f90 implicit none ! Arguments - class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + integer(I4B), intent(in) :: dt !! Current stepsize ! Internals logical :: lencounter, lfirstpl, lfirsttp real(DP) :: rts real(DP), dimension(:,:), allocatable :: xbeg, xend, vbeg integer(I4B) :: i - + + select type(system => self) + class is (rmvs_nbody_system) select type(cb => self%cb) class is (rmvs_cb) select type(pl => self%pl) class is (rmvs_pl) select type(tp => self%tp) class is (rmvs_tp) - associate(ntp => tp%nbody, npl => pl%nbody, t => param%t, dt => param%dt, & - xhpl => pl%xh, vhpl => pl%vh, xjpl => pl%xj, vjpl => pl%vj, & - xhtp => tp%xh, vhtp => tp%vh) + associate(ntp => tp%nbody, npl => pl%nbody, t => param%t) allocate(xbeg, source=pl%xh) allocate(vbeg, source=pl%vh) call pl%set_rhill(cb) @@ -39,16 +40,16 @@ module subroutine rmvs_step_system(self, param) lfirsttp = tp%lfirst pl%outer(0)%x(:,:) = xbeg(:,:) pl%outer(0)%v(:,:) = vbeg(:,:) - call pl%step(cb, param, t, dt) + call pl%step(system, param, dt) pl%outer(NTENC)%x(:,:) = pl%xh(:,:) pl%outer(NTENC)%v(:,:) = pl%vh(:,:) call tp%set_beg_end(xend = pl%xh) - call rmvs_interp_out(pl,cb, dt, param) - call rmvs_step_out(pl, cb, tp, dt, param) + call rmvs_interp_out(system, param, dt) + call rmvs_step_out(system, param, dt) call tp%reverse_status() call tp%set_beg_end(xbeg = xbeg, xend = xend) tp%lfirst = .true. - call tp%step(cb, pl, param, t, dt) + call tp%step(system, param, dt) where (tp%status(:) == INACTIVE) tp%status(:) = ACTIVE pl%lfirst = lfirstpl tp%lfirst = lfirsttp @@ -59,11 +60,12 @@ module subroutine rmvs_step_system(self, param) end select end select end select + end select return end subroutine rmvs_step_system - subroutine rmvs_step_out(pl, cb, tp, dt, param) + subroutine rmvs_step_out(system, param, dt) !! author: David A. Minton !! !! Step ACTIVE test particles ahead in the outer encounter region, setting up and calling the inner region @@ -73,17 +75,15 @@ subroutine rmvs_step_out(pl, cb, tp, dt, param) !! Adapted from David E. Kaufmann's Swifter routines rmvs_step_out.f90 and rmvs_step_out2.f90 implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body object - class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - real(DP), intent(in) :: dt !! Step size - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(rmvs_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + integer(I4B), intent(in) :: dt !! Current stepsize ! Internals - integer(I4B) :: outer_index, j, k - real(DP) :: dto, outer_time, rts - logical :: lencounter, lfirsttp + integer(I4B) :: outer_index, j, k + real(DP) :: dto, outer_time, rts + logical :: lencounter, lfirsttp - associate(npl => pl%nbody, ntp => tp%nbody, t => param%t) + associate(cb => system%cb, pl => system%pl, npl => system%pl%nbody, tp => system%tp, ntp => system%tp%nbody, t => param%t) dto = dt / NTENC where(tp%plencP(:) == 0) tp%status(:) = INACTIVE @@ -99,9 +99,9 @@ subroutine rmvs_step_out(pl, cb, tp, dt, param) lencounter = tp%encounter_check(cb, pl, dt, rts) if (lencounter) then ! Interpolate planets in inner encounter region - call rmvs_interp_in(pl, cb, dto, outer_index, param) + call rmvs_interp_in(system, param, dto, outer_index) ! Step through the inner region - call rmvs_step_in(pl, cb, tp, param, outer_time, dto) + call rmvs_step_in(system, param, outer_time, dto) lfirsttp = tp%lfirst tp%lfirst = .true. call tp%step(cb, pl, param, outer_time, dto) diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index 19213bc23..c18648364 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, cb, param, dt) + module subroutine whm_drift_pl(self, system, param, dt) !! author: David A. Minton !! !! Loop through planets and call Danby drift routine @@ -10,15 +10,15 @@ module subroutine whm_drift_pl(self, cb, param, dt) !! Adapted from David E. Kaufmann's Swifter routine whm_drift.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structur - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(whm_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 + integer(I4B) :: i + real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation + integer(I4B), dimension(:), allocatable :: iflag + real(DP), dimension(:), allocatable :: dtp associate(npl => self%nbody, & xj => self%xj, & @@ -63,7 +63,7 @@ module subroutine whm_drift_pl(self, cb, param, dt) end subroutine whm_drift_pl - module subroutine whm_drift_tp(self, cb, param, dt) + module subroutine whm_drift_tp(self, system, param, dt) !! author: David A. Minton !! !! Loop through test particles and call Danby drift routine @@ -73,22 +73,22 @@ module subroutine whm_drift_tp(self, cb, param, dt) !! 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_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(whm_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 + 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 + integer(I4B) :: i + real(DP) :: energy, vmag2, rmag !! Variables used in GR calculation + integer(I4B), dimension(:), allocatable :: iflag + real(DP), dimension(:), allocatable :: dtp associate(ntp => self%nbody, & xh => self%xh, & vh => self%vh, & status => self%status,& - mu => self%mu) + mu => self%mu, GMcb => system%cb%Gmass) if (ntp == 0) return allocate(iflag(ntp)) @@ -98,7 +98,7 @@ module subroutine whm_drift_tp(self, cb, param, dt) do i = 1,ntp rmag = norm2(xh(:, i)) vmag2 = dot_product(vh(:, i), vh(:, i)) - energy = 0.5_DP * vmag2 - cb%Gmass / rmag + energy = 0.5_DP * vmag2 - GMcb / rmag dtp(i) = dt * (1.0_DP + 3 * param%inv_c2 * energy) end do else diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 128915360..53cd9b97a 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -1,7 +1,7 @@ submodule(whm_classes) s_whm_getacch use swiftest contains - module subroutine whm_getacch_pl(self, cb, param, t) + module subroutine whm_getacch_pl(self, system, param, t) !! author: David A. Minton !! !! Compute heliocentric accelerations of planets @@ -10,16 +10,15 @@ module subroutine whm_getacch_pl(self, cb, param, t) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + real(DP), intent(in) :: t !! Current time ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: ah0 - associate(pl => self, npl => self%nbody, j2rp2 => cb%j2rp2, & - ah => self%ah, xh => self%xh, xj => self%xj, vh => self%vh, vj => self%vj) + associate(pl => self, cb => system%cb, npl => self%nbody) if (npl == 0) return call pl%set_ir3() @@ -33,13 +32,13 @@ module subroutine whm_getacch_pl(self, cb, param, t) if (param%loblatecb) call pl%obl_acc(cb) if (param%lextra_force) call pl%user_getacch(cb, param, t) - if (param%lgr) call pl%gr_getacch(cb, param) + if (param%lgr) call pl%gr_getacch(param) end associate return end subroutine whm_getacch_pl - module subroutine whm_getacch_tp(self, cb, pl, param, t, xh) + module subroutine whm_getacch_tp(self, system, param, t, xh) !! author: David A. Minton !! !! Compute heliocentric accelerations of test particles @@ -48,28 +47,27 @@ module subroutine whm_getacch_tp(self, cb, pl, param, t, xh) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_tp.f90 implicit none ! Arguments - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Generic Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! Generic Swiftest massive body particle data structure. + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure + class(whm_pl), intent(inout) :: pl !! Generic Swiftest massive body particle data structure. class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets ! Internals - integer(I4B) :: i - real(DP), dimension(NDIM) :: ah0 + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah0 - associate(tp => self, ntp => self%nbody, npl => pl%nbody, j2rp2 => cb%j2rp2, aht => self%ah, & - ir3h => pl%ir3h, GMpl => pl%Gmass) + associate(tp => self, ntp => self%nbody, pl => system%pl, npl => system%pl%nbody) if (ntp == 0 .or. npl == 0) return ah0 = whm_getacch_ah0(pl%Gmass(:), xh(:,:), npl) do i = 1, ntp tp%ah(:, i) = ah0(:) end do - call whm_getacch_ah3_tp(cb, pl, tp, xh) + call whm_getacch_ah3_tp(system, xh) if (param%loblatecb) call tp%obl_acc(cb) if (param%lextra_force) call tp%user_getacch(cb, param, t) - if (param%lgr) call tp%gr_getacch(cb, param) + if (param%lgr) call tp%gr_getacch(param) end associate return end subroutine whm_getacch_tp @@ -198,7 +196,7 @@ pure subroutine whm_getacch_ah3(pl) return end subroutine whm_getacch_ah3 - pure subroutine whm_getacch_ah3_tp(cb, pl, tp, xh) + pure subroutine whm_getacch_ah3_tp(system, xh) !! author: David A. Minton !! !! Compute direct cross (third) term heliocentric accelerations of test particles @@ -207,16 +205,14 @@ pure subroutine whm_getacch_ah3_tp(cb, pl, tp, xh) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 implicit none ! Arguments - class(swiftest_cb), intent(in) :: cb !! Swiftest central body object - class(whm_pl), intent(in) :: pl !! WHM massive body object - class(whm_tp), intent(inout) :: tp !! WHM test particle object + class(whm_nbody_system) :: system !! WHM nbody system object real(DP), dimension(:,:), intent(in) :: xh !! Position vector of massive bodies at required point in step ! Internals integer(I4B) :: i, j real(DP) :: rji2, irij3, fac real(DP), dimension(NDIM) :: dx, acc - associate(ntp => tp%nbody, npl => pl%nbody, msun => cb%Gmass, GMpl => pl%Gmass, xht => tp%xh, aht => tp%ah) + associate(ntp => system%tp%nbody, npl => system%pl%nbody, msun => system%cb%Gmass, GMpl => system%pl%Gmass, xht => system%tp%xh, aht => system%tp%ah) if (ntp == 0) return do i = 1, ntp acc(:) = 0.0_DP diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 index 073ddc2ae..47f4bd449 100644 --- a/src/whm/whm_gr.f90 +++ b/src/whm/whm_gr.f90 @@ -1,8 +1,7 @@ submodule(whm_classes) s_whm_gr use swiftest contains - module subroutine whm_gr_getacch_pl(self, cb, param) - !! author: David A. Minton + module subroutine whm_gr_getacch_pl(self, param) !! author: David A. Minton !! !! Compute relativisitic accelerations of massive bodies !! Based on Saha & Tremaine (1994) Eq. 28 @@ -10,8 +9,7 @@ module subroutine whm_gr_getacch_pl(self, cb, param) !! Adapted from David A. Minton's Swifter routine routine gr_whm_getacch.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of ! Internals integer(I4B) :: i @@ -19,11 +17,10 @@ module subroutine whm_gr_getacch_pl(self, cb, param) real(DP), dimension(:, :), allocatable :: aj real(DP) :: beta, rjmag4 - associate(n => self%nbody, msun => cb%Gmass, mu => self%muj, c2 => param%inv_c2, & + associate(n => self%nbody, mu => self%muj, c2 => param%inv_c2, & ah => self%ah, xj => self%xj, GMpl => self%Gmass, eta => self%eta) if (n == 0) return allocate(aj, mold = ah) - !do concurrent(i = 1:n) do i = 1, n rjmag4 = (dot_product(xj(:, i), xj(:, i)))**2 beta = - mu(i)**2 * c2 @@ -39,7 +36,7 @@ module subroutine whm_gr_getacch_pl(self, cb, param) return end subroutine whm_gr_getacch_pl - module subroutine whm_gr_getacch_tp(self, cb, param) + module subroutine whm_gr_getacch_tp(self, param) !! author: David A. Minton !! !! Compute relativisitic accelerations of test particles @@ -48,17 +45,15 @@ module subroutine whm_gr_getacch_tp(self, cb, param) !! Adapted from David A. Minton's Swifter routine routine gr_whm_getacch.f90 implicit none ! Arguments - class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i real(DP) :: rjmag4, beta - associate(n => self%nbody, msun => cb%Gmass, mu => self%mu,& + associate(n => self%nbody, mu => self%mu,& c2 => param%inv_c2, ah => self%ah, xh => self%xh, status => self%status) if (n == 0) return - !do concurrent (i = 1:n, status(i) == active) do i = 1, n rjmag4 = (dot_product(xh(:, i), xh(:, i)))**2 beta = - mu(i)**2 * c2 @@ -77,15 +72,14 @@ module pure subroutine whm_gr_p4_pl(self, param, dt) !! Adapted from David A. Minton's Swifter routine routine gr_whm_p4.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size ! Internals integer(I4B) :: i associate(n => self%nbody, xj => self%xj, vj => self%vj, status => self%status, c2 => param%inv_c2) if (n == 0) return - !do concurrent (i = 1:n, status(i) == ACTIVE) do i = 1,n call p4_func(xj(:, i), vj(:, i), dt, c2) end do diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index 05aeebde9..41d3394fa 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -2,7 +2,7 @@ use swiftest contains - module subroutine whm_step_system(self, param) + module subroutine whm_step_system(self, param, dt) !! author: David A. Minton !! !! Step massive bodies and and active test particles ahead in heliocentric coordinates @@ -11,9 +11,12 @@ module subroutine whm_step_system(self, param) !! Adapted from David E. Kaufmann's Swifter routine whm_step.f90 implicit none ! Arguments - class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + integer(I4B), intent(in) :: dt !! Current stepsize + select type (system => self) + class is (whm_nbody_system) select type(cb => self%cb) class is (whm_cb) select type(pl => self%pl) @@ -23,19 +26,20 @@ module subroutine whm_step_system(self, param) associate(ntp => tp%nbody, npl => pl%nbody, t => param%t, dt => param%dt) call pl%set_rhill(cb) call tp%set_beg_end(xbeg = pl%xh) - call pl%step(cb, param, t, dt) + call pl%step(system, param, dt) if (ntp > 0) then call tp%set_beg_end(xend = pl%xh) - call tp%step(cb, pl, param, t, dt) + call tp%step(system, param, dt) end if end associate end select end select end select + end select return end subroutine whm_step_system - module subroutine whm_step_pl(self, cb, param, t, dt) + module subroutine whm_step_pl(self, system, param, dt) !! author: David A. Minton !! !! Step planets ahead using kick-drift-kick algorithm @@ -45,20 +49,18 @@ module subroutine whm_step_pl(self, cb, param, t, dt) !logical, save :: lfirst = .true. implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + integer(I4B), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth - associate(pl => self, xh => self%xh, vh => self%vh, ah => self%ah, & - xj => self%xj, vj => self%vj) + associate(cb => system%cb, t => param%t) dth = 0.5_DP * dt if (pl%lfirst) then call pl%h2j(cb) - call pl%getacch(cb, param, t) + call pl%getacch(system, param, t) pl%lfirst = .false. end if @@ -69,13 +71,13 @@ module subroutine whm_step_pl(self, cb, param, t, dt) call pl%drift(cb, param, dt) if (param%lgr) call pl%gr_p4(param, dth) call pl%j2h(cb) - call pl%getacch(cb, param, t + dt) + call pl%getacch(system, param, t + dt) call pl%kickvh(dth) end associate return end subroutine whm_step_pl - module subroutine whm_step_tp(self, cb, pl, param, t, dt) + module subroutine whm_step_tp(self, system, param, dt) !! author: David A. Minton !! !! Step active test particles ahead using kick-drift-kick algorithm @@ -84,20 +86,17 @@ module subroutine whm_step_tp(self, cb, pl, param, t, dt) !! Adapted from David E. Kaufmann's Swifter routine whm_step_tp.f90 implicit none ! Arguments - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + integer(I4B), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth - associate(tp => self, xht => self%xh, vht => self%vh, aht => self%ah, & - xbeg => self%xbeg, xend => self%xend) + associate(cb => system%cb, pl => system%pl, t => param%t, xbeg => self%xbeg, xend => self%xend) dth = 0.5_DP * dt if (tp%lfirst) then - call tp%getacch(cb, pl, param, t, xbeg) + call tp%getacch(system, param, t, xbeg) tp%lfirst = .false. end if call tp%kickvh(dth) @@ -105,7 +104,7 @@ module subroutine whm_step_tp(self, cb, pl, param, t, dt) if (param%lgr) call tp%gr_p4(param, dth) call tp%drift(cb, param, dt) if (param%lgr) call tp%gr_p4(param, dth) - call tp%getacch(cb, pl, param, t + dt, xend) + call tp%getacch(system, param, t + dt, xend) call tp%kickvh(dth) end associate return From 98b79fc8ea99837907bdccc1dda07fc697dd192a Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 2 Jul 2021 17:37:34 -0400 Subject: [PATCH 03/12] Fixed bad comment --- src/discard/discard.f90 | 2 +- src/io/io.f90 | 24 ++++++++++----------- src/modules/helio_classes.f90 | 14 +++++++------ src/modules/rmvs_classes.f90 | 4 ++-- src/modules/swiftest_classes.f90 | 36 ++++++++++++++++---------------- src/modules/whm_classes.f90 | 4 ++-- src/rmvs/rmvs_setup.f90 | 2 +- src/rmvs/rmvs_step.f90 | 10 ++++----- src/whm/whm_gr.f90 | 4 ++-- src/whm/whm_step.f90 | 4 ++-- 10 files changed, 53 insertions(+), 51 deletions(-) diff --git a/src/discard/discard.f90 b/src/discard/discard.f90 index 754cb468c..1e69639be 100644 --- a/src/discard/discard.f90 +++ b/src/discard/discard.f90 @@ -10,7 +10,7 @@ module subroutine discard_system(self, param) !! Adapted from Hal Levison's Swift routine discard.f implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters if (self%tp%nbody == 0) return select type(self) diff --git a/src/io/io.f90 b/src/io/io.f90 index 6f40423c9..6f930cdf2 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -444,7 +444,7 @@ module subroutine io_dump_swiftest(self, param, t, dt, msg) implicit none ! Arguments class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -483,7 +483,7 @@ module subroutine io_dump_system(self, param, t, dt, msg) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize character(*), optional, intent(in) :: msg !! Message to display with dump operation @@ -636,7 +636,7 @@ module subroutine io_read_body_in(self, param) implicit none ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file integer(I4B) :: iu = LUN @@ -776,7 +776,7 @@ module subroutine io_read_param_in(self, param_file_name) !! Adapted from Martin Duncan's Swift routine io_init_param.f implicit none ! Arguments - class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters of parameters + class(swiftest_parameters),intent(out) :: self !! Current run configuration parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file @@ -870,7 +870,7 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) ! Arguments class(swiftest_body), intent(inout) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -932,7 +932,7 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) ! Arguments class(swiftest_cb), intent(inout) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error cod @@ -966,7 +966,7 @@ module subroutine io_read_frame_system(self, iu, param, form, t, ierr) ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Current simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -1042,7 +1042,7 @@ module subroutine io_read_initialize_system(self, param) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters call self%cb%initialize(param) call self%pl%initialize(param) @@ -1063,7 +1063,7 @@ module subroutine io_write_discard(self, param, discards) implicit none ! Arguments class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters class(swiftest_body), intent(inout) :: discards !! Swiftest discard object ! Internals integer(I4B), parameter :: LUN = 40 @@ -1196,7 +1196,7 @@ module subroutine io_write_frame_body(self, iu, param, t, dt) ! Arguments class(swiftest_body), intent(in) :: self !! Swiftest particle 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size @@ -1252,7 +1252,7 @@ module subroutine io_write_frame_cb(self, iu, param, t, dt) ! Arguments class(swiftest_cb), intent(in) :: self !! Swiftest central body 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size @@ -1288,7 +1288,7 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) ! Arguments class(swiftest_nbody_system), intent(in) :: self !! Swiftest system 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Step size ! Internals diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 3d12882b2..dd2e08d63 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -97,7 +97,7 @@ module subroutine helio_drift_pl(self, cb, param, dt) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_pl @@ -106,7 +106,7 @@ module subroutine helio_drift_tp(self, cb, param, dt) implicit none class(helio_tp), intent(inout) :: self !! Helio test particle object class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_tp @@ -131,7 +131,7 @@ module subroutine helio_getacch_pl(self, cb, param, t) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time end subroutine helio_getacch_pl @@ -142,7 +142,7 @@ module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree class(whm_pl), intent(inout) :: pl !! Swiftest massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine helio_getacch_tp @@ -177,8 +177,10 @@ end subroutine helio_setup_tp module subroutine helio_step_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + 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_pl(self, cb, param, t, dt) diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index b67c354b0..8a1f94a8e 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -132,7 +132,7 @@ module subroutine rmvs_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine rmvs_setup_system module subroutine rmvs_setup_pl(self,n) @@ -151,7 +151,7 @@ module subroutine rmvs_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + 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 rmvs_step_system diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 62ea97d6f..905044f17 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -270,14 +270,14 @@ end subroutine abstract_copy subroutine abstract_initialize(self, param) import swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine abstract_initialize subroutine abstract_read_frame(self, iu, param, form, t, ierr) import DP, I4B, swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -294,7 +294,7 @@ subroutine abstract_step_body(self, system, param, t, dt) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + 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 abstract_step_body @@ -303,7 +303,7 @@ subroutine abstract_step_system(self, param, t, dt) import DP, swiftest_nbody_system, swiftest_parameters implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + 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 abstract_step_system @@ -312,7 +312,7 @@ subroutine abstract_write_frame(self, iu, param) import DP, I4B, swiftest_base, swiftest_parameters class(swiftest_base), intent(in) :: self !! Swiftest base 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine abstract_write_frame end interface @@ -354,7 +354,7 @@ end subroutine discard_sun_tp module subroutine discard_system(self, param) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_system module pure elemental subroutine drift_one(mu, px, py, pz, vx, vy, vz, dt, iflag) @@ -424,14 +424,14 @@ end subroutine io_dump_param module subroutine io_dump_swiftest(self, param, msg) implicit none class(swiftest_base), intent(inout) :: self !! Swiftest base object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters character(*), optional, intent(in) :: msg !! Message to display with dump operation end subroutine io_dump_swiftest module subroutine io_dump_system(self, param, msg) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters character(*), optional, intent(in) :: msg !! Message to display with dump operation end subroutine io_dump_system @@ -453,7 +453,7 @@ end function io_get_token module subroutine io_read_body_in(self, param) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine io_read_body_in module subroutine io_read_cb_in(self, param) @@ -464,7 +464,7 @@ end subroutine io_read_cb_in module subroutine io_read_param_in(self, param_file_name) implicit none - class(swiftest_parameters), intent(out) :: self !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(out) :: self !! Current run configuration parameters character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) end subroutine io_read_param_in @@ -482,7 +482,7 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -492,7 +492,7 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) implicit none class(swiftest_cb), intent(inout) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -502,7 +502,7 @@ module subroutine io_read_frame_system(self, iu, param, form, t, ierr) implicit none class(swiftest_nbody_system),intent(inout) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") real(DP), intent(out) :: t !! Current simulation time integer(I4B), intent(out) :: ierr !! Error code @@ -521,13 +521,13 @@ end function io_read_hdr 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 of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine io_read_initialize_system module subroutine io_write_discard(self, param, discards) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters class(swiftest_body), intent(inout) :: discards !! Swiftest discard object end subroutine io_write_discard @@ -544,21 +544,21 @@ module subroutine io_write_frame_body(self, iu, param) implicit none class(swiftest_body), intent(in) :: self !! Swiftest particle 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine io_write_frame_body module subroutine io_write_frame_cb(self, iu, param) implicit none class(swiftest_cb), intent(in) :: self !! Swiftest central body 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine io_write_frame_cb module subroutine io_write_frame_system(self, iu, param) implicit none class(swiftest_nbody_system), intent(in) :: self !! Swiftest system 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 of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine io_write_frame_system module subroutine io_write_hdr(iu, t, npl, ntp, out_form, out_type) diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index 282ced72a..c0e95ccb4 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -112,7 +112,7 @@ module subroutine whm_step_pl(self, system, param, t, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + 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 whm_step_pl @@ -294,7 +294,7 @@ module subroutine whm_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters implicit none class(whm_nbody_system), intent(inout) :: self !! WHM system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + 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 whm_step_system diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index 845f8d5b0..b3bcf8f28 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -86,7 +86,7 @@ module subroutine rmvs_setup_system(self, param) implicit none ! Arguments class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i, j diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 index 82c6d28c4..7995efdd8 100644 --- a/src/rmvs/rmvs_step.f90 +++ b/src/rmvs/rmvs_step.f90 @@ -11,7 +11,7 @@ module subroutine rmvs_step_system(self, param, dt) implicit none ! Arguments class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters integer(I4B), intent(in) :: dt !! Current stepsize ! Internals logical :: lencounter, lfirstpl, lfirsttp @@ -76,7 +76,7 @@ subroutine rmvs_step_out(system, param, dt) implicit none ! Arguments class(rmvs_nbody_system), intent(inout) :: system !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters integer(I4B), intent(in) :: dt !! Current stepsize ! Internals integer(I4B) :: outer_index, j, k @@ -131,7 +131,7 @@ subroutine rmvs_step_in(pl, cb, tp, param, outer_time, dto) class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object class(rmvs_cb), intent(inout) :: cb !! RMVS central body object class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: outer_time !! Current time real(DP), intent(in) :: dto !! Step size ! Internals @@ -386,7 +386,7 @@ subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) logical, intent(in) :: lfirst !! Logical flag indicating whether current invocation is the first integer(I4B), intent(in) :: inner_index !! Outer substep number within current set integer(I4B), intent(in) :: ipleP !! index of RMVS planet being closely encountered - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i, id1, id2 real(DP) :: r2, mu, rhill2, vdotr, a, peri, capm, tperi, rpl @@ -465,7 +465,7 @@ subroutine rmvs_make_planetocentric(pl, cb, tp, param) class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object class(rmvs_cb), intent(inout) :: cb !! RMVS central body particle type class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i, j, inner_index, ipc2hc logical, dimension(:), allocatable :: encmask diff --git a/src/whm/whm_gr.f90 b/src/whm/whm_gr.f90 index 47f4bd449..363ce5ad4 100644 --- a/src/whm/whm_gr.f90 +++ b/src/whm/whm_gr.f90 @@ -228,7 +228,7 @@ pure subroutine gr_vel2pseudovel(param, mu, xh, vh, pv) !! Adapted from David A. Minton's Swifter routine gr_vel2pseudovel.f90 implicit none - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector real(DP), dimension(:), intent(in) :: vh !! Heliocentric velocity vector @@ -300,7 +300,7 @@ pure subroutine gr_pseudovel2vel(param, mu, xh, pv, vh) !! !! Adapted from David A. Minton's Swifter routine gr_pseudovel2vel.f90 implicit none - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: mu !! G * (Mcb + m), G = gravitational constant, Mcb = mass of central body, m = mass of body real(DP), dimension(:), intent(in) :: xh !! Heliocentric position vector real(DP), dimension(:), intent(in) :: pv !! Pseudovelocity velocity vector - see Saha & Tremain (1994), eq. (32) diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index 41d3394fa..c3c7a098f 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -51,7 +51,7 @@ module subroutine whm_step_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 !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters integer(I4B), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth @@ -88,7 +88,7 @@ module subroutine whm_step_tp(self, system, param, dt) ! Arguments class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of parameters + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters integer(I4B), intent(in) :: dt !! Current stepsize ! Internals real(DP) :: dth From 1d0ac61f86dd53298c1bb0e3748569bc6797846b Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 2 Jul 2021 17:40:46 -0400 Subject: [PATCH 04/12] Fixed comments and a couple of bad interfaces --- src/modules/helio_classes.f90 | 30 ++++++++++++++---------------- src/modules/whm_classes.f90 | 18 +++++++++--------- 2 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index dd2e08d63..751e94fed 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -183,26 +183,24 @@ module subroutine helio_step_system(self, param) real(DP), intent(in) :: dt !! Current stepsize end subroutine helio_step_system - module subroutine helio_step_pl(self, cb, param, t, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - implicit none - class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + module subroutine helio_step_pl(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize end subroutine helio_step_pl - module subroutine helio_step_tp(self, cb, pl, param, t, dt) + module subroutine helio_step_tp(self, system, param, t, dt) use swiftest_classes, only : swiftest_cb, swiftest_parameters - use whm_classes, only : whm_pl implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsizee end subroutine helio_step_tp end interface end module helio_classes diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index c0e95ccb4..e411201ae 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -224,8 +224,8 @@ module subroutine whm_step_tp(self, system, param, t, 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 !! Swiftest central body particle data structure - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time real(DP), intent(in) :: dt !! Stepsize end subroutine whm_step_tp @@ -240,36 +240,36 @@ end subroutine whm_setup_set_beg_end module subroutine whm_gr_getacch_tp(self, param) use swiftest_classes, only : swiftest_cb, swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine whm_gr_getacch_tp module pure subroutine whm_gr_p4_tp(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp module pure subroutine whm_gr_vh2pv_tp(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_vh2pv_tp module pure subroutine whm_gr_pv2vh_tp(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_pv2vh_tp module subroutine whm_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_nbody_system), intent(inout) :: self !! Swiftest system object + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters end subroutine whm_setup_system From 294cdbc7c91ffdfa614a7ee6d335e3a8e91e4626 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Fri, 2 Jul 2021 17:51:16 -0400 Subject: [PATCH 05/12] Fixed Helio interfaces --- src/helio/helio_step.f90 | 105 +++++++++++++++++----------------- src/modules/helio_classes.f90 | 66 ++++++++++----------- 2 files changed, 87 insertions(+), 84 deletions(-) diff --git a/src/helio/helio_step.f90 b/src/helio/helio_step.f90 index ca6df15fa..480de821d 100644 --- a/src/helio/helio_step.f90 +++ b/src/helio/helio_step.f90 @@ -1,7 +1,7 @@ submodule(helio_classes) s_helio_step use swiftest contains - module subroutine helio_step_system(self, param) + module subroutine helio_step_system(self, param, t, dt) !! author: David A. Minton !! !! Step massive bodies and and active test particles ahead in heliocentric coordinates @@ -10,31 +10,34 @@ module subroutine helio_step_system(self, param) !! Adapted from David E. Kaufmann's Swifter routine helio_step.f90 implicit none ! Arguments - class(helio_nbody_system), intent(inout) :: self !! Helio nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + 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 + select type(system => self) + class is (helio_nbody_system) select type(cb => self%cb) class is (helio_cb) select type(pl => self%pl) class is (helio_pl) select type(tp => self%tp) class is (helio_tp) - associate(ntp => tp%nbody, npl => pl%nbody, t => param%t, dt => param%dt) call pl%set_rhill(cb) call tp%set_beg_end(xbeg = pl%xh) - call pl%step(cb, param, t, dt) + call pl%step(system, param, t, dt) if (ntp > 0) then call tp%set_beg_end(xend = pl%xh) - call tp%step(cb, pl, param, t, dt) + call tp%step(system, param, t, dt) end if - end associate + end select end select end select end select return end subroutine helio_step_system - module subroutine helio_step_pl(self, cb, param, t, dt) + module subroutine helio_step_pl(self, system, param, t, dt) !! author: David A. Minton !! !! Step massive bodies ahead Democratic Heliocentric method @@ -43,38 +46,39 @@ module subroutine helio_step_pl(self, cb, param, t, dt) !! Adapted from Hal Levison's Swift routine helio_step_pl.f implicit none ! Arguments - class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize ! Internals - integer(I4B) :: i,npl + integer(I4B) :: i real(DP) :: dth, msys real(DP), dimension(NDIM) :: ptbeg, ptend !! TODO: Incorporate these into the tp structure logical, save :: lfirst = .true. - - npl = self%nbody - dth = 0.5_DP * dt - if (lfirst) then - call self%vh2vb(cb) - lfirst = .false. - end if - call self%lindrift(cb, dth, ptbeg) - call self%getacch(cb, param, t) - call self%kickvb(dth) + + associate(cb => system%cb) + dth = 0.5_DP * dt + if (lfirst) then + call self%vh2vb(cb) + lfirst = .false. + end if + call self%lindrift(cb, dth, ptbeg) + call self%getacch(system, param, t) + call self%kickvb(dth) - call self%drift(cb, param, dt) - call self%getacch(cb, param, t + dt) - call self%kickvb(dth) - call self%lindrift(cb, dth, ptend) - call self%vb2vh(cb) + call self%drift(system, param, dt) + call self%getacch(system, param, t + dt) + call self%kickvb(dth) + call self%lindrift(cb, dth, ptend) + call self%vb2vh(cb) + end associate return end subroutine helio_step_pl - module subroutine helio_step_tp(self, cb, pl, param, t, dt) + module subroutine helio_step_tp(self, system, param, t, dt) !! author: David A. Minton !! !! Step active test particles ahead using Democratic Heliocentric method @@ -83,32 +87,31 @@ module subroutine helio_step_tp(self, cb, pl, param, t, dt) !! Adapted from Hal Levison's Swift routine helio_step_tp.f implicit none ! Arguments - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(whm_pl), intent(inout) :: pl !! WHM massive body data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), intent(in) :: dt !! Stepsize + class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsiz ! Internals logical, save :: lfirst = .true. !! Flag to indicate that this is the first call real(DP) :: dth !! Half step size - real(DP) :: mu !! Central mass term ! executable code - dth = 0.5_DP * dt - mu = cb%Gmass - if (lfirst) then - call self%vh2vb(vbcb = -self%ptbeg) - lfirst = .false. - end if - call self%lindrift(dth, self%ptbeg) - call self%getacch(cb, pl, param, t, self%xbeg) - call self%kickvb(dth) - call self%drift(cb, param, dt) - call self%getacch(cb, pl, param, t + dt, self%xend) - call self%kickvb(dth) - call self%lindrift(dth, self%ptend) - call self%vb2vh(vbcb = -self%ptend) + associate(cb => system%cb, pl => system%pl) + dth = 0.5_DP * dt + if (lfirst) then + call self%vh2vb(vbcb = -self%ptbeg) + lfirst = .false. + end if + call self%lindrift(dth, self%ptbeg) + call self%getacch(system, param, t, self%xbeg) + call self%kickvb(dth) + call self%drift(system, param, dt) + call self%getacch(system, param, t + dt, self%xend) + call self%kickvb(dth) + call self%lindrift(dth, self%ptend) + call self%vb2vh(vbcb = -self%ptend) + end associate return diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 751e94fed..15c61343b 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -63,9 +63,7 @@ module helio_classes procedure, public :: step => helio_step_tp !! Steps the body forward one stepsize end type helio_tp - interface - module subroutine helio_coord_vb2vh_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none @@ -92,22 +90,24 @@ 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, cb, param, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module subroutine helio_drift_pl(self, system, param, dt) + use swiftest_classes, only : swiftest_parameters + use whm_classes, only : whm_nbody_system implicit none - class(helio_pl), intent(inout) :: self !! Helio massive body object - class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: dt !! Stepsize + class(helio_pl), intent(inout) :: self !! Helio massive body object + class(whm_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 helio_drift_pl - module subroutine helio_drift_tp(self, cb, param, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module subroutine helio_drift_tp(self, system, param, dt) + use swiftest_classes, only : swiftest_parameters + use whm_classes, only : whm_nbody_system implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle object - class(swiftest_cb), intent(inout) :: cb !! Helio central body object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: dt !! Stepsize + class(helio_tp), intent(inout) :: self !! Helio test particle object + class(whm_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 !! Stepsiz end subroutine helio_drift_tp module subroutine helio_drift_linear_pl(self, cb, dt, pt) @@ -126,25 +126,25 @@ module subroutine helio_drift_linear_tp(self, dt, pt) real(DP), dimension(:), intent(in) :: pt !! negative barycentric velocity of the Sun end subroutine helio_drift_linear_tp - module subroutine helio_getacch_pl(self, cb, param, t) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module subroutine helio_getacch_pl(self, system, param, t) + use swiftest_classes, only : swiftest_parameters + use whm_classes, only : whm_nbody_system implicit none - class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current time + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure + class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + real(DP), intent(in) :: t !! Current simulation time end subroutine helio_getacch_pl - module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - use whm_classes, only : whm_pl + module subroutine helio_getacch_tp(self, system, param, t, xh) + use swiftest_classes, only : swiftest_parameters + use whm_classes, only : whm_nbody_system implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! Swiftest massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets end subroutine helio_getacch_tp module subroutine helio_getacch_int_pl(self, t) @@ -156,9 +156,9 @@ end subroutine helio_getacch_int_pl module subroutine helio_getacch_int_tp(self, pl, t, xh) use whm_classes, only : whm_pl implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle data structure + class(helio_tp), intent(inout) :: self !! Helio test particle data structure class(whm_pl), intent(inout) :: pl !! WhM massive body particle data structure - real(DP), intent(in) :: t !! Current time + real(DP), intent(in) :: t !! Current time real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planet end subroutine helio_getacch_int_tp @@ -174,7 +174,7 @@ module subroutine helio_setup_tp(self,n) integer, intent(in) :: n !! Number of test particles to allocate end subroutine helio_setup_tp - module subroutine helio_step_system(self, param) + 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 @@ -186,7 +186,7 @@ end subroutine helio_step_system module subroutine helio_step_pl(self, system, param, t, dt) use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none - class(helio_pl), intent(inout) :: self !! WHM massive body particle data structure + class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nboody system class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time From 058889a3979e6e0f0ec7bd5383e63b09ba591a13 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Mon, 5 Jul 2021 17:09:04 -0400 Subject: [PATCH 06/12] Changed to explicit interfaces --- src/setup/setup.f90 | 48 +++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index 779cab908..55140ac88 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -58,13 +58,15 @@ module subroutine setup_construct_system(system, param) return end subroutine setup_construct_system - module procedure setup_body + module subroutine setup_body(self,n) !! author: David A. Minton !! !! Constructor for base Swiftest particle class. Allocates space for all particles and !! initializes all components with a value. !! Note: Timing tests indicate that (NDIM, n) is more efficient than (NDIM, n) implicit none + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + integer, intent(in) :: n !! Number of particles to allocate space for self%nbody = n if (n <= 0) return @@ -108,14 +110,16 @@ end subroutine setup_construct_system self%mu(:) = 0.0_DP return - end procedure setup_body + end subroutine setup_body - module procedure setup_pl + module subroutine setup_pl(self,n) !! author: David A. Minton !! !! Constructor for base Swiftest massive body class. Allocates space for all particles and !! initializes all components with a value. implicit none + class(swiftest_pl), intent(inout) :: self !! Swiftest massive body object + integer, intent(in) :: n !! Number of massive bodies to allocate space for !> Call allocation method for parent class !> The parent class here is the abstract swiftest_body class, so we can't use the type-bound procedure @@ -143,14 +147,16 @@ end subroutine setup_construct_system self%Q(:) = 0.0_DP self%num_comparisons = 0 return - end procedure setup_pl + end subroutine setup_pl - module procedure setup_tp + module subroutine setup_tp(self, n) !! author: David A. Minton !! !! Constructor for base Swiftest test particle particle class. Allocates space for !! all particles and initializes all components with a value. implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + integer, intent(in) :: n !! Number of bodies to allocate space for !> Call allocation method for parent class !> The parent class here is the abstract swiftest_body class, so we can't use the type-bound procedure @@ -166,45 +172,52 @@ end subroutine setup_construct_system self%atp(:) = 0.0_DP return - end procedure setup_tp + end subroutine setup_tp - module procedure setup_set_msys + module subroutine setup_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 self%msys = self%cb%mass + sum(self%pl%mass(1:self%pl%nbody)) return - end procedure setup_set_msys + end subroutine setup_set_msys - module procedure setup_set_mu_pl + module subroutine setup_set_mu_pl(self, cb) !! author: David A. Minton !! !! Computes G * (M + m) for each massive body implicit none + 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 procedure setup_set_mu_pl + end subroutine setup_set_mu_pl - module procedure setup_set_mu_tp + module subroutine setup_set_mu_tp(self, cb) !! author: David A. Minton !! !! Converts certain scalar values to arrays so that they can be used in elemental functions implicit none + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object if (self%nbody > 0) self%mu(:) = cb%Gmass return - end procedure setup_set_mu_tp + end subroutine setup_set_mu_tp - module procedure setup_set_rhill + module subroutine setup_set_rhill(self,cb) !! author: David A. Minton !! !! 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 if (self%nbody > 0) then call self%xv2el(cb) @@ -212,13 +225,14 @@ end subroutine setup_construct_system end if return - end procedure setup_set_rhill + end subroutine setup_set_rhill - module procedure setup_set_ir3h + module subroutine setup_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 @@ -233,6 +247,6 @@ end subroutine setup_construct_system end if return - end procedure setup_set_ir3h + end subroutine setup_set_ir3h end submodule s_setup From 69acd2964534b92a503431ce80bd1073f7e38445 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Mon, 5 Jul 2021 23:07:51 -0400 Subject: [PATCH 07/12] Major restructuring of classes and method interfaces. Trying to consolidate all cb, pl, tp arguments into system class --- src/discard/discard.f90 | 60 +-- src/gr/gr.f90 | 14 +- src/helio/helio_drift.f90 | 68 ++- src/helio/helio_getacch.f90 | 81 ++-- src/io/io.f90 | 192 ++++---- src/modules/helio_classes.f90 | 65 +-- src/modules/rmvs_classes.f90 | 156 +++--- src/modules/swiftest_classes.f90 | 107 +---- src/modules/whm_classes.f90 | 274 ++++++----- src/rmvs/rmvs_discard.f90 | 13 +- src/rmvs/rmvs_encounter_check.f90 | 61 +-- src/rmvs/rmvs_getacch.f90 | 107 ++--- src/rmvs/rmvs_setup.f90 | 85 ++-- src/rmvs/rmvs_spill_and_fill.f90 | 8 +- src/rmvs/rmvs_step.f90 | 759 ++++++++++++++++-------------- src/setup/setup.f90 | 2 +- src/user/user_getacch.f90 | 10 +- src/whm/whm_drift.f90 | 63 +-- src/whm/whm_getacch.f90 | 126 ++--- src/whm/whm_setup.f90 | 2 +- src/whm/whm_step.f90 | 81 ++-- 21 files changed, 1120 insertions(+), 1214 deletions(-) diff --git a/src/discard/discard.f90 b/src/discard/discard.f90 index 1e69639be..daee4b15a 100644 --- a/src/discard/discard.f90 +++ b/src/discard/discard.f90 @@ -9,37 +9,35 @@ module subroutine discard_system(self, param) !! Adapted from David E. Kaufmann's Swifter routine: discard.f90 !! Adapted from Hal Levison's Swift routine discard.f implicit none - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters if (self%tp%nbody == 0) return - select type(self) + select type(system => self) class is (whm_nbody_system) - associate(cb => self%cb, pl => self%pl, tp => self%tp, t => param%t, dt => param%dt, & - msys => self%msys, discards => self%tp_discards, & - ntp => self%tp%nbody, ldiscard => self%tp%ldiscard) + associate(cb => system%cb, pl => system%pl, npl => system%pl%nbody, tp => system%tp, ntp => system%tp%nbody) if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. & (param%rmaxu >= 0.0_DP) .or. ((param%qmin >= 0.0_DP) .and. (param%qmin_coord == "BARY"))) then - call pl%h2b(cb) + if (npl > 0) call pl%h2b(cb) if (ntp > 0) call tp%h2b(cb) end if if ((param%rmin >= 0.0_DP) .or. (param%rmax >= 0.0_DP) .or. (param%rmaxu >= 0.0_DP)) then - if (ntp > 0) call tp%discard_sun(cb, param, t, msys) + if (ntp > 0) call tp%discard_sun(system, param) end if - if (param%qmin >= 0.0_DP .and. ntp > 0) call tp%discard_peri(cb, pl, param, t, msys) - if (param%lclose .and. ntp > 0) call tp%discard_pl(pl, t, dt) + if (param%qmin >= 0.0_DP .and. ntp > 0) call tp%discard_peri(system, param) + if (param%lclose .and. ntp > 0) call tp%discard_pl(system, param) if (any(tp%ldiscard(1:ntp))) then ! Spill the discards to the spill list - call tp%spill(discards, ldiscard) - call self%write_discard(param, discards) + call tp%spill(system%tp_discards, tp%ldiscard) + call self%write_discard(param, system%tp_discards) end if end associate end select return end subroutine discard_system - module subroutine discard_sun_tp(self, cb, param, t, msys) + module subroutine discard_sun_tp(self, system, param) !! author: David A. Minton !! !! Check to see if test particles should be discarded based on their positions relative to the Sun @@ -49,16 +47,14 @@ module subroutine discard_sun_tp(self, cb, param, t, msys) !! Adapted from Hal Levison's Swift routine discard_sun.f implicit none ! Arguments - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: msys !! Total system mass + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i real(DP) :: energy, vb2, rb2, rh2, rmin2, rmax2, rmaxu2 - associate(tp => self, ntp => self%nbody) + associate(tp => self, ntp => self%nbody, cb => system%cb, t => param%t, msys => system%msys) rmin2 = max(param%rmin * param%rmin, cb%radius * cb%radius) rmax2 = param%rmax**2 rmaxu2 = param%rmaxu**2 @@ -90,7 +86,7 @@ module subroutine discard_sun_tp(self, cb, param, t, msys) return end subroutine discard_sun_tp - module subroutine discard_peri_tp(self, cb, pl, param, t, msys) + module subroutine discard_peri_tp(self, system, param) !! author: David A. Minton !! !! Check to see if a test particle should be discarded because its perihelion distance becomes too small @@ -99,19 +95,16 @@ module subroutine discard_peri_tp(self, cb, pl, param, t, msys) !! Adapted from Hal Levison's Swift routine discard_peri.f implicit none ! Arguments - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: msys !! Total system mass + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameterss ! Internals logical, save :: lfirst = .true. integer(I4B) :: i, j, ih real(DP) :: r2 real(DP), dimension(NDIM) :: dx - associate(tp => self, ntp => self%nbody, npl => pl%nbody, qmin_coord => param%qmin_coord) + associate(cb => system%cb, tp => self, ntp => self%nbody, pl => system%pl, npl => system%pl%nbody, qmin_coord => param%qmin_coord, t => param%t, msys => system%msys) if (lfirst) then call util_hills(npl, pl) call util_peri(lfirst, ntp, tp, cb%Gmass, msys, param%qmin_coord) @@ -145,7 +138,7 @@ module subroutine discard_peri_tp(self, cb, pl, param, t, msys) end subroutine discard_peri_tp - module subroutine discard_pl_tp(self, pl, t, dt) + module subroutine discard_pl_tp(self, system, param) !! author: David A. Minton !! !! Check to see if test particles should be discarded based on their positions relative to the massive bodies @@ -154,16 +147,15 @@ module subroutine discard_pl_tp(self, pl, t, dt) !! Adapted from Hal Levison's Swift routine discard_pl.f implicit none ! Arguments - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: dt !! Stepsize + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i, j, isp real(DP) :: r2min, radius real(DP), dimension(NDIM) :: dx, dv - associate(tp => self, ntp => self%nbody, npl => pl%nbody) + associate(tp => self, ntp => self%nbody, pl => system%pl, npl => system%pl%nbody, t => param%t, dt => param%dt) do i = 1, ntp if (tp%status(i) == ACTIVE) then do j = 1, npl @@ -187,7 +179,7 @@ module subroutine discard_pl_tp(self, pl, t, dt) end subroutine discard_pl_tp - module subroutine discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) + subroutine discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) !! author: David A. Minton !! !! Check to see if a test particle and massive body are having, or will have within the next time step, an encounter such diff --git a/src/gr/gr.f90 b/src/gr/gr.f90 index d50968ad1..6afc9f5ed 100644 --- a/src/gr/gr.f90 +++ b/src/gr/gr.f90 @@ -1,7 +1,8 @@ submodule(swiftest_classes) s_gr use swiftest contains - module procedure gr_getaccb_ns_body + subroutine gr_getaccb_ns_body(self, cb, param, agr, agr0) + !! author: David A. Minton !! !! Add relativistic correction acceleration for non-symplectic integrators @@ -9,7 +10,13 @@ !! !! Adapted from David A. Minton's Swifter routine routine gr_getaccb_ns.f90 implicit none - + ! Arguments + class(swiftest_body), intent(inout) :: self + class(swiftest_cb), intent(inout) :: cb + class(swiftest_parameters), intent(in) :: param + real(DP), dimension(:, :), intent(inout) :: agr + real(DP), dimension(NDIM), intent(out) :: agr0 + ! Internals real(DP), dimension(NDIM) :: xh, vh real(DP) :: rmag, rdotv, vmag2 integer(I4B) :: i @@ -29,7 +36,6 @@ agr0 = 0.0_DP select type(self) class is (swiftest_pl) - !do concurrent(i = 1:NDIM) do i = 1, NDIM agr0(i) = -sum(self%Gmass(1:n) * agr(1:n, i) / msun) end do @@ -39,6 +45,6 @@ return - end procedure gr_getaccb_ns_body + end subroutine gr_getaccb_ns_body end submodule s_gr \ No newline at end of file diff --git a/src/helio/helio_drift.f90 b/src/helio/helio_drift.f90 index 1244533a0..59f828425 100644 --- a/src/helio/helio_drift.f90 +++ b/src/helio/helio_drift.f90 @@ -1,7 +1,8 @@ submodule (helio_classes) s_helio_drift use swiftest contains - module subroutine helio_drift_pl(self, cb, param, dt) + module subroutine helio_drift_pl(self, system, param, dt) + !! author: David A. Minton !! !! Loop through massive bodies and call Danby drift routine @@ -11,22 +12,17 @@ module subroutine helio_drift_pl(self, cb, param, dt) !! Adapted from Hal Levison's Swift routine drift.f implicit none ! Arguments - class(helio_pl), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize + 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 + real(DP), intent(in) :: dt !! Stepsize) ! Internals integer(I4B) :: i !! Loop counter real(DP) :: rmag, vmag2, energy integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag real(DP), dimension(:), allocatable :: dtp - associate(npl => self%nbody, & - xh => self%xh, & - vb => self%vb, & - status => self%status,& - mu => self%mu) - + associate(pl => self, npl => self%nbody) if (npl == 0) return allocate(iflag(npl)) @@ -35,23 +31,23 @@ module subroutine helio_drift_pl(self, cb, param, dt) if (param%lgr) then do i = 1,npl - rmag = norm2(xh(:, i)) - vmag2 = dot_product(vb(:, i), vb(:, i)) - energy = 0.5_DP * vmag2 - mu(i) / rmag + rmag = norm2(pl%xh(:, i)) + vmag2 = dot_product(pl%vb(:, i), pl%vb(:, i)) + energy = 0.5_DP * vmag2 - pl%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:npl), xh(1,1:npl), xh(2,1:npl), xh(3,1:npl), & - vb(1,1:npl), vb(2,1:npl), vb(3,1:npl), & - dtp(1:npl), iflag(1:npl)) + call drift_one(pl%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)) if (any(iflag(1:npl) /= 0)) then do i = 1, npl - write(*, *) " Planet ", self%name(i), " is lost!!!!!!!!!!" - write(*, *) xh(:,i) - write(*, *) vb(:,i) + write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) pl%xh(:,i) + write(*, *) pl%vb(:,i) write(*, *) " stopping " call util_exit(FAILURE) end do @@ -94,7 +90,7 @@ module subroutine helio_drift_linear_pl(self, cb, dt, pt) end subroutine helio_drift_linear_pl - module subroutine helio_drift_tp(self, cb, param, dt) + module subroutine helio_drift_tp(self, system, param, dt) !! author: David A. Minton !! !! Loop through test particles and call Danby drift routine @@ -103,21 +99,17 @@ module subroutine helio_drift_tp(self, cb, param, dt) !! Adapted from Hal Levison's Swift routine drift_tp.f implicit none ! Arguments - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Helio central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: dt !! Stepsize + class(helio_tp), intent(inout) :: self !! Helio test particle object + 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 !! Stepsiz ! Internals integer(I4B) :: i !! Loop counter real(DP) :: rmag, vmag2, energy real(DP), dimension(:), allocatable :: dtp integer(I4B), dimension(:),allocatable :: iflag !! Vectorized error code flag - associate(ntp => self%nbody, & - xh => self%xh, & - vh => self%vh, & - status => self%status,& - mu => self%mu) + associate(tp => self, ntp => self%nbody) if (ntp == 0) return allocate(iflag(ntp)) allocate(dtp(ntp)) @@ -128,21 +120,21 @@ module subroutine helio_drift_tp(self, cb, param, dt) if (param%lgr) then do i = 1,ntp - rmag = norm2(xh(:, i)) - vmag2 = dot_product(vh(:, i), vh(:, i)) - energy = 0.5_DP * vmag2 - mu(i) / rmag + 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), xh(1,1:ntp), xh(2,1:ntp), xh(3,1:ntp), & - vh(1,1:ntp), vh(2,1:ntp), vh(3,1:ntp), & - dtp(1:ntp), iflag(1:ntp)) + call drift_one(tp%mu(1:ntp), tp%xh(1,1:ntp), tp%xh(2,1:ntp), tp%xh(3,1:ntp), & + tp%vh(1,1:ntp), tp%vh(2,1:ntp), tp%vh(3,1:ntp), & + dtp(1:ntp), iflag(1:ntp)) if (any(iflag(1:ntp) /= 0)) then - status = DISCARDED_DRIFTERR + tp%status = DISCARDED_DRIFTERR do i = 1, ntp - if (iflag(i) /= 0) write(*, *) "Particle ", self%name(i), " lost due to error in Danby drift" + if (iflag(i) /= 0) write(*, *) "Particle ", tp%name(i), " lost due to error in Danby drift" end do end if end associate diff --git a/src/helio/helio_getacch.f90 b/src/helio/helio_getacch.f90 index 3dbcc4e45..806047cc3 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -1,7 +1,7 @@ submodule (helio_classes) s_helio_getacch use swiftest contains - module subroutine helio_getacch_pl(self, cb, param, t) + module subroutine helio_getacch_pl(self, system, param, t) !! author: David A. Minton !! !! Compute heliocentric accelerations of massive bodies @@ -10,10 +10,10 @@ module subroutine helio_getacch_pl(self, cb, param, t) !! Adapted from Hal Levison's Swift routine helio_getacch.f implicit none ! Arguments - class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + 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 + real(DP), intent(in) :: t !! Current simulation time ! Internals logical, save :: lmalloc = .true. integer(I4B) :: i @@ -21,22 +21,22 @@ module subroutine helio_getacch_pl(self, cb, param, t) real(DP), dimension(:), allocatable, save :: irh real(DP), dimension(:, :), allocatable, save :: xh_loc, aobl - associate(npl => self%nbody) + associate(pl => self, npl => self%nbody) !if (lflag) then - self%ahi(:,2:npl) = 0.0_DP - call helio_getacch_int_pl(self, t) + pl%ahi(:,2:npl) = 0.0_DP + call helio_getacch_int_pl(pl, t) !end if !if (param%loblatecb) call self%obl_acc(cb) TODO: Fix this !else - self%ah(:,:) = self%ahi(:,:) + pl%ah(:,:) = pl%ahi(:,:) !end if - if (param%lextra_force) call self%user_getacch(cb, param, t) + if (param%lextra_force) call pl%user_getacch(system, param, t) end associate return end subroutine helio_getacch_pl - module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) + module subroutine helio_getacch_tp(self, system, param, t, xhp) !! author: David A. Minton !! !! Compute heliocentric accelerations of test particles @@ -45,34 +45,35 @@ module subroutine helio_getacch_tp(self, cb, pl, param, t, xh) !! Adapted from Hal Levison's Swift routine helio_getacch_tp.f implicit none ! Arguments - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + 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 + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at the current substep ! Internals logical, save :: lmalloc = .true. integer(I4B) :: i real(DP) :: r2, mu real(DP), dimension(:), allocatable, save :: irh, irht - real(DP), dimension(:, :), allocatable, save :: aobl, xht, aoblt ! executable code - associate(ntp => self%nbody, npl => pl%nbody) - !if (lflag) then - self%ahi(:,:) = 0.0_DP - call helio_getacch_int_tp(self, pl, t, xh) - !end if - !if (param%loblatecb) call self%obl_acc(cb) TODO: Fix this - self%ah(:,:) = self%ahi(:,:) - if (param%lextra_force) call self%user_getacch(cb, param, t) - if (param%lgr) call self%gr_getacch(cb, param) + associate(tp => self, ntp => self%nbody, npl => system%pl%nbody) + select type(pl => system%pl) + class is (rmvs_pl) + !if (lflag) then + self%ahi(:,:) = 0.0_DP + call helio_getacch_int_tp(tp, pl, t, xhp) + !end if + !if (param%loblatecb) call self%obl_acc(cb) TODO: Fix this + tp%ah(:,:) = tp%ahi(:,:) + if (param%lextra_force) call tp%user_getacch(system, param, t) + if (param%lgr) call tp%gr_getacch(system, param) + end select end associate return end subroutine helio_getacch_tp - module subroutine helio_getacch_int_pl(self, t) + subroutine helio_getacch_int_pl(pl, t) !! author: David A. Minton !! !! Compute direct cross term heliocentric accelerations of massive bodiese @@ -81,17 +82,17 @@ module subroutine helio_getacch_int_pl(self, t) !! Adapted from Hal Levison's Swift routine getacch_ah3.f implicit none ! Arguments - class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure - real(DP), intent(in) :: t !! Current time + 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 => self%nbody) + associate(npl => pl%nbody) do i = 2, npl - 1 do j = i + 1, npl - dx(:) = self%xh(:,j) - self%xh(:,i) + dx(:) = pl%xh(:,j) - pl%xh(:,i) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) faci = self%Gmass(i) * irij3 @@ -105,7 +106,7 @@ module subroutine helio_getacch_int_pl(self, t) return end subroutine helio_getacch_int_pl - module subroutine helio_getacch_int_tp(self, pl, t, xh) + subroutine helio_getacch_int_tp(tp, pl, t, xhp) !! author: David A. Minton !! !! Compute direct cross term heliocentric accelerations of test particles @@ -114,23 +115,23 @@ module subroutine helio_getacch_int_tp(self, pl, t, xh) !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f implicit none ! Arguments - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(whm_pl), intent(inout) :: pl !! Helio massive body particle data structure + class(helio_tp), intent(inout) :: tp !! Helio test particle data structure + class(helio_pl), intent(inout) :: pl !! Helio massive body particle data structure real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets ! Internals integer(I4B) :: i, j real(DP) :: r2, fac real(DP), dimension(NDIM) :: dx - associate(ntp => self%nbody, npl => pl%nbody) + associate(ntp => tp%nbody, npl => pl%nbody) do i = 1, ntp - if (self%status(i) == ACTIVE) then + if (tp%status(i) == ACTIVE) then do j = 2, npl - dx(:) = self%xh(:,i) - xh(:,j) + dx(:) = tp%xh(:,i) - xhp(:,j) r2 = dot_product(dx(:), dx(:)) fac = pl%Gmass(j) / (r2 * sqrt(r2)) - self%ahi(:,i) = self%ahi(:,i) - fac * dx(:) + tp%ahi(:,i) = tp%ahi(:,i) - fac * dx(:) end do end if end do diff --git a/src/io/io.f90 b/src/io/io.f90 index 6f930cdf2..629a4952f 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -392,11 +392,13 @@ module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) write(unit, Lfmt) "ENERGY", self%lenergy !write(unit, Lfmt) "YARKOVSKY", self%lyarkovsky !write(unit, Lfmt) "YORP", self%lyorp + iostat = 0 + iomsg = "UDIO not implemented" return end subroutine io_param_writer - module subroutine io_dump_param(self, param_file_name, t, dt) + module subroutine io_dump_param(self, param_file_name) !! author: David A. Minton !! !! Dump integration parameters to file @@ -406,13 +408,11 @@ module subroutine io_dump_param(self, param_file_name, t, dt) implicit none ! Arguments class(swiftest_parameters),intent(in) :: self !! Output collection of parameters - character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) - real(DP),intent(in) :: t !! Current simulation time - real(DP),intent(in) :: dt !! Step size + character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) ! Internals - integer(I4B), parameter :: LUN = 7 !! Unit number of output file - integer(I4B) :: ierr !! Error code - character(STRMAX) :: error_message !! Error message in UDIO procedure + integer(I4B), parameter :: LUN = 7 !! Unit number of output file + integer(I4B) :: ierr !! Error code + character(STRMAX) :: error_message !! Error message in UDIO procedure open(unit = LUN, file = param_file_name, status='replace', form = 'FORMATTED', iostat =ierr) if (ierr /=0) then @@ -434,7 +434,7 @@ module subroutine io_dump_param(self, param_file_name, t, dt) return end subroutine io_dump_param - module subroutine io_dump_swiftest(self, param, t, dt, msg) + module subroutine io_dump_swiftest(self, param, msg) !! author: David A. Minton !! !! Dump massive body data to files @@ -443,11 +443,9 @@ module subroutine io_dump_swiftest(self, param, t, dt, msg) !! Adapted from Hal Levison's Swift routine io_dump_pl.f and io_dump_tp.f implicit none ! Arguments - class(swiftest_base), intent(inout) :: self !! Swiftest base object + class(swiftest_base), intent(inout) :: self !! Swiftest base object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize - character(*), optional, intent(in) :: msg !! Message to display with dump operation + character(*), optional, intent(in) :: msg !! Message to display with dump operation ! Internals integer(I4B) :: ierr !! Error code integer(I4B),parameter :: LUN = 7 !! Unit number for dump file @@ -468,13 +466,13 @@ module subroutine io_dump_swiftest(self, param, t, dt, msg) write(*, *) " Unable to open binary dump file " // dump_file_name call util_exit(FAILURE) end if - call self%write_frame(iu, param, t, dt) + call self%write_frame(iu, param) close(LUN) return end subroutine io_dump_swiftest - module subroutine io_dump_system(self, param, t, dt, msg) + module subroutine io_dump_system(self, param, msg) !! author: David A. Minton !! !! Dumps the state of the system to files in case the simulation is interrupted. @@ -482,11 +480,9 @@ module subroutine io_dump_system(self, param, t, dt, 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 - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize - 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 @@ -495,26 +491,25 @@ module subroutine io_dump_system(self, param, t, dt, msg) character(len=:), allocatable :: param_file_name real(DP) :: tfrac - allocate(dump_param, source=param) - param_file_name = trim(adjustl(DUMP_PARAM_FILE(idx))) + param_file_name = trim(adjustl(DUMP_PARAM_FILE(idx))) dump_param%incbfile = trim(adjustl(DUMP_CB_FILE(idx))) dump_param%inplfile = trim(adjustl(DUMP_PL_FILE(idx))) dump_param%intpfile = trim(adjustl(DUMP_TP_FILE(idx))) dump_param%out_form = XV dump_param%out_stat = 'APPEND' - call dump_param%dump(param_file_name,t,dt) + call dump_param%dump(param_file_name) - call self%cb%dump(dump_param, t, dt) - if (self%pl%nbody > 0) call self%pl%dump(dump_param, t, dt) - if (self%tp%nbody > 0) call self%tp%dump(dump_param, t, dt) + call self%cb%dump(dump_param) + if (self%pl%nbody > 0) call self%pl%dump(dump_param) + if (self%tp%nbody > 0) call self%tp%dump(dump_param) idx = idx + 1 if (idx > NDUMPFILES) idx = 1 ! Print the status message (format code passed in from main driver) - tfrac = (t - param%t0) / (param%tstop - param%t0) - write(*,msg) t, tfrac, self%pl%nbody, self%tp%nbody + tfrac = (param%t - param%t0) / (param%tstop - param%t0) + write(*,msg) param%t, tfrac, self%pl%nbody, self%tp%nbody return end subroutine io_dump_system @@ -588,12 +583,12 @@ module function io_get_token(buffer, ifirst, ilast, ierr) result(token) !! Adapted from David E. Kaufmann's Swifter routine io_get_token.f90 implicit none ! Arguments - character(len=*), intent(in) :: buffer !! Input string buffer - integer(I4B), intent(inout) :: ifirst !! Index of the buffer at which to start the search for a token - integer(I4B), intent(out) :: ilast !! Index of the buffer at the end of the returned token - integer(I4B), intent(out) :: ierr !! Error code + character(len=*), intent(in) :: buffer !! Input string buffer + integer(I4B), intent(inout) :: ifirst !! Index of the buffer at which to start the search for a token + integer(I4B), intent(out) :: ilast !! Index of the buffer at the end of the returned token + integer(I4B), intent(out) :: ierr !! Error code ! Result - character(len=:),allocatable :: token !! Returned token string + character(len=:), allocatable :: token !! Returned token string ! Internals integer(I4B) :: i,ilength @@ -635,7 +630,7 @@ module subroutine io_read_body_in(self, param) !! Adapted from Martin Duncan's Swift routine swiftest_init_pl.f and swiftest_init_tp.f implicit none ! Arguments - class(swiftest_body), intent(inout) :: self !! Swiftest particle object + class(swiftest_body), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file @@ -699,7 +694,7 @@ module subroutine io_read_body_in(self, param) read(iu, iostat = ierr) nbody call self%setup(nbody) if (nbody > 0) then - call self%read_frame(iu, param, XV, t, ierr) + call self%read_frame(iu, param, XV, ierr) self%status(:) = ACTIVE end if case default @@ -724,7 +719,7 @@ module subroutine io_read_cb_in(self, param) !! Adapted from Martin Duncan's Swift routine swiftest_init_pl.f implicit none ! Arguments - class(swiftest_cb), intent(inout) :: self + class(swiftest_cb), intent(inout) :: self class(swiftest_parameters), intent(inout) :: param ! Internals integer(I4B), parameter :: LUN = 7 !! Unit number of input file @@ -755,7 +750,7 @@ module subroutine io_read_cb_in(self, param) else open(unit = iu, file = param%incbfile, status = 'old', form = 'UNFORMATTED', iostat = ierr) - call self%read_frame(iu, param, XV, t, ierr) + call self%read_frame(iu, param, XV, ierr) end if close(iu) if (ierr /= 0) then @@ -808,7 +803,7 @@ module subroutine io_read_param_in(self, param_file_name) return end subroutine io_read_param_in - module function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & xh1, xh2, vh1, vh2, encounter_file, out_type) result(ierr) !! author: David A. Minton !! @@ -818,10 +813,10 @@ module function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius !! Adapted from David E. Kaufmann's Swifter routine: io_read_encounter.f90 implicit none ! Arguments - integer(I4B), intent(out) :: name1, name2 - real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 - real(DP), dimension(NDIM), intent(out) :: xh1, xh2, vh1, vh2 - character(*), intent(in) :: encounter_file, out_type + integer(I4B), intent(out) :: name1, name2 + real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(out) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: encounter_file, out_type ! Result integer(I4B) :: ierr ! Internals @@ -858,7 +853,7 @@ module function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius return end function io_read_encounter - module subroutine io_read_frame_body(self, iu, param, form, t, ierr) + module subroutine io_read_frame_body(self, iu, param, form, ierr) !! author: David A. Minton !! !! Reads a frame of output of either test particle or massive body data to the binary output file @@ -868,12 +863,11 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) !! Adapted from Hal Levison's Swift routine io_read_frame.F implicit none ! Arguments - class(swiftest_body), intent(inout) :: self !! Swiftest particle object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_body), intent(inout) :: self !! Swiftest particle object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time - integer(I4B), intent(out) :: ierr !! Error code + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code associate(n => self%nbody) read(iu, iostat = ierr) self%name(1:n) @@ -921,7 +915,7 @@ module subroutine io_read_frame_body(self, iu, param, form, t, ierr) return end subroutine io_read_frame_body - module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) + module subroutine io_read_frame_cb(self, iu, param, form, ierr) !! author: David A. Minton !! !! Reads a frame of output of central body data to the binary output file @@ -930,12 +924,11 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) !! Adapted from Hal Levison's Swift routine io_read_frame.F implicit none ! Arguments - class(swiftest_cb), intent(inout) :: self !! Swiftest central body object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_cb), intent(inout) :: self !! Swiftest central body object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time - integer(I4B), intent(out) :: ierr !! Error cod + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error cod read(iu, iostat = ierr) self%Gmass self%mass = self%Gmass / param%GU @@ -958,18 +951,17 @@ module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) return end subroutine io_read_frame_cb - module subroutine io_read_frame_system(self, iu, param, form, t, ierr) + module subroutine io_read_frame_system(self, iu, param, form, ierr) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! !! Read a frame (header plus records for each massive body and active test particle) from a output binary file implicit none ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Current simulation time - integer(I4B), intent(out) :: ierr !! Error code + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + character(*), intent(in) :: form !! Input format code ("XV" or "EL") + integer(I4B), intent(out) :: ierr !! Error code ! Internals logical, save :: lfirst = .true. @@ -983,21 +975,21 @@ module subroutine io_read_frame_system(self, iu, param, form, t, ierr) return end if end if - ierr = io_read_hdr(iu, t, self%pl%nbody, self%tp%nbody, param%out_form, param%out_type) + ierr = io_read_hdr(iu, param%t, self%pl%nbody, self%tp%nbody, param%out_form, param%out_type) if (ierr /= 0) then write(*, *) "Swiftest error:" write(*, *) " Binary output file already exists or cannot be accessed" return end if - call self%cb%read_frame(iu, param, form, t, ierr) + call self%cb%read_frame(iu, param, form, ierr) if (ierr /= 0) return - call self%pl%read_frame(iu, param, form, t, ierr) + call self%pl%read_frame(iu, param, form, ierr) if (ierr /= 0) return - call self%tp%read_frame(iu, param, form, t, ierr) + call self%tp%read_frame(iu, param, form, ierr) return end subroutine io_read_frame_system - module function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) + function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) !! author: David A. Minton !! !! Read frame header from input binary files @@ -1009,7 +1001,7 @@ module function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) integer(I4B), intent(in) :: iu integer(I4B), intent(out) :: npl, ntp character(*), intent(out) :: out_form - real(DP), intent(out) :: t + real(DP), intent(out) :: t character(*), intent(in) :: out_type ! Result integer(I4B) :: ierr @@ -1041,8 +1033,8 @@ module subroutine io_read_initialize_system(self, param) !! implicit none ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + 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) @@ -1062,9 +1054,9 @@ module subroutine io_write_discard(self, param, discards) !! Adapted from Hal Levison's Swift routine io_discard_write.f implicit none ! Arguments - class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - class(swiftest_body), intent(inout) :: discards !! Swiftest discard object + class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + class(swiftest_body), intent(inout) :: discards !! Swiftest discard object ! Internals integer(I4B), parameter :: LUN = 40 integer(I4B) :: i, ierr @@ -1134,8 +1126,8 @@ module subroutine io_write_discard(self, param, discards) end subroutine io_write_discard - module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & - xh1, xh2, vh1, vh2, encounter_file, out_type) + subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + xh1, xh2, vh1, vh2, encounter_file, out_type) !! author: David A. Minton !! !! Write close encounter data to output binary files @@ -1145,10 +1137,10 @@ module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, rad !! Adapted from Hal Levison's Swift routine io_write_encounter.f implicit none ! Arguments - integer(I4B), intent(in) :: name1, name2 - real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 - real(DP), dimension(NDIM), intent(in) :: xh1, xh2, vh1, vh2 - character(*), intent(in) :: encounter_file, out_type + integer(I4B), intent(in) :: name1, name2 + real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(in) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: encounter_file, out_type ! Internals logical , save :: lfirst = .true. integer(I4B), parameter :: lun = 30 @@ -1184,7 +1176,7 @@ module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, rad end subroutine io_write_encounter - module subroutine io_write_frame_body(self, iu, param, t, dt) + module subroutine io_write_frame_body(self, iu, param) !! author: David A. Minton !! !! Write a frame of output of either test particle or massive body data to the binary output file @@ -1194,11 +1186,9 @@ module subroutine io_write_frame_body(self, iu, param, t, dt) !! Adapted from Hal Levison's Swift routine io_write_frame.F implicit none ! Arguments - class(swiftest_body), intent(in) :: self !! Swiftest particle object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_body), intent(in) :: self !! Swiftest particle 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 - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size associate(n => self%nbody) if (n == 0) return @@ -1241,7 +1231,7 @@ module subroutine io_write_frame_body(self, iu, param, t, dt) return end subroutine io_write_frame_body - module subroutine io_write_frame_cb(self, iu, param, t, dt) + module subroutine io_write_frame_cb(self, iu, param) !! author: David A. Minton !! !! Write a frame of output of central body data to the binary output file @@ -1250,11 +1240,9 @@ module subroutine io_write_frame_cb(self, iu, param, t, dt) !! Adapted from Hal Levison's Swift routine io_write_frame.F implicit none ! Arguments - class(swiftest_cb), intent(in) :: self !! Swiftest central body object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_cb), intent(in) :: self !! Swiftest central body 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 - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size write(iu) self%Gmass write(iu) self%radius @@ -1276,7 +1264,7 @@ module subroutine io_write_frame_cb(self, iu, param, t, dt) return end subroutine io_write_frame_cb - module subroutine io_write_frame_system(self, iu, param, t, dt) + module subroutine io_write_frame_system(self, iu, param) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! !! Write a frame (header plus records for each massive body and active test particle) to output binary file @@ -1286,18 +1274,16 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) !! Adapted from Hal Levison's Swift routine io_write_frame.F implicit none ! Arguments - class(swiftest_nbody_system), intent(in) :: self !! Swiftest system 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 - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Step size + class(swiftest_nbody_system), intent(in) :: self !! Swiftest system 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 ! Internals - logical, save :: lfirst = .true. !! Flag to determine if this is the first call of this method - integer(I4B) :: ierr !! I/O error code + logical, save :: lfirst = .true. !! Flag to determine if this is the first call of this method + integer(I4B) :: ierr !! I/O error code - class(swiftest_cb), allocatable :: cb !! Temporary local version of pl structure used for non-destructive conversions - class(swiftest_pl), allocatable :: pl !! Temporary local version of pl structure used for non-destructive conversions - class(swiftest_tp), allocatable :: tp !! Temporary local version of pl structure used for non-destructive conversions + class(swiftest_cb), allocatable :: cb !! Temporary local version of pl structure used for non-destructive conversions + class(swiftest_pl), allocatable :: pl !! Temporary local version of pl structure used for non-destructive conversions + class(swiftest_tp), allocatable :: tp !! Temporary local version of pl structure used for non-destructive conversions allocate(cb, source = self%cb) allocate(pl, source = self%pl) @@ -1329,7 +1315,7 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) call util_exit(FAILURE) end if end if - call io_write_hdr(iu, t, pl%nbody, tp%nbody, param%out_form, param%out_type) + call io_write_hdr(iu, param%t, pl%nbody, tp%nbody, param%out_form, param%out_type) if (param%lgr) then associate(vh => pl%vh, vht => tp%vh) @@ -1350,9 +1336,9 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) end if ! Write out each data type frame - call cb%write_frame(iu, param, t, dt) - call pl%write_frame(iu, param, t, dt) - call tp%write_frame(iu, param, t, dt) + call cb%write_frame(iu, param) + call pl%write_frame(iu, param) + call tp%write_frame(iu, param) deallocate(cb, pl, tp) @@ -1361,7 +1347,7 @@ module subroutine io_write_frame_system(self, iu, param, t, dt) return end subroutine io_write_frame_system - module subroutine io_write_hdr(iu, t, npl, ntp, out_form, out_type) + subroutine io_write_hdr(iu, t, npl, ntp, out_form, out_type) !! author: The Purdue Swiftest Team - David A. Minton, Carlisle A. Wishard, Jennifer L.L. Pouplin, and Jacob R. Elliott !! !! Write frame header to output binary file diff --git a/src/modules/helio_classes.f90 b/src/modules/helio_classes.f90 index 15c61343b..ad10018a2 100644 --- a/src/modules/helio_classes.f90 +++ b/src/modules/helio_classes.f90 @@ -38,7 +38,6 @@ module helio_classes procedure, public :: drift => helio_drift_pl !! Method for Danby drift in Democratic Heliocentric coordinates procedure, public :: lindrift => helio_drift_linear_pl !! Method for linear drift of massive bodies due to barycentric momentum of Sun procedure, public :: getacch => helio_getacch_pl !! Compute heliocentric accelerations of massive bodies - procedure, public :: getacch_int => helio_getacch_int_pl !! Compute direct cross term heliocentric accelerations of planets procedure, public :: setup => helio_setup_pl !! Constructor method - Allocates space for number of particles procedure, public :: step => helio_step_pl !! Steps the body forward one stepsize end type helio_pl @@ -58,7 +57,6 @@ module helio_classes 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 :: getacch => helio_getacch_tp !! Compute heliocentric accelerations of massive bodies - procedure, public :: getacch_int => helio_getacch_int_tp !! Compute direct cross term heliocentric accelerations of test particles procedure, public :: setup => helio_setup_tp !! Constructor method - Allocates space for number of particles procedure, public :: step => helio_step_tp !! Steps the body forward one stepsize end type helio_tp @@ -91,23 +89,21 @@ module subroutine helio_coord_vh2vb_tp(self, vbcb) end subroutine helio_coord_vh2vb_tp module subroutine helio_drift_pl(self, system, param, dt) - use swiftest_classes, only : swiftest_parameters - use whm_classes, only : whm_nbody_system + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none - class(helio_pl), intent(inout) :: self !! Helio massive body object - class(whm_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 + 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 + real(DP), intent(in) :: dt !! Stepsize end subroutine helio_drift_pl module subroutine helio_drift_tp(self, system, param, dt) - use swiftest_classes, only : swiftest_parameters - use whm_classes, only : whm_nbody_system + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle object - class(whm_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 !! Stepsiz + class(helio_tp), intent(inout) :: self !! Helio test particle object + 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 helio_drift_tp module subroutine helio_drift_linear_pl(self, cb, dt, pt) @@ -127,41 +123,24 @@ module subroutine helio_drift_linear_tp(self, dt, pt) end subroutine helio_drift_linear_tp module subroutine helio_getacch_pl(self, system, param, t) - use swiftest_classes, only : swiftest_parameters - use whm_classes, only : whm_nbody_system + use swiftest_classes, only : swiftest_parameters, swiftest_nbody_system implicit none - class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure - class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current simulation time + 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 + real(DP), intent(in) :: t !! Current simulation time end subroutine helio_getacch_pl - module subroutine helio_getacch_tp(self, system, param, t, xh) - use swiftest_classes, only : swiftest_parameters - use whm_classes, only : whm_nbody_system + module subroutine helio_getacch_tp(self, system, param, t, xhp) + use swiftest_classes, only : swiftest_parameters, swiftest_nbody_system implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + class(helio_tp), intent(inout) :: self !! Helio 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 + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets end subroutine helio_getacch_tp - module subroutine helio_getacch_int_pl(self, t) - implicit none - class(helio_pl), intent(inout) :: self !! Helio massive body particle data structure - real(DP), intent(in) :: t !! Current time - end subroutine helio_getacch_int_pl - - module subroutine helio_getacch_int_tp(self, pl, t, xh) - use whm_classes, only : whm_pl - implicit none - class(helio_tp), intent(inout) :: self !! Helio test particle data structure - class(whm_pl), intent(inout) :: pl !! WhM massive body particle data structure - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planet - end subroutine helio_getacch_int_tp - module subroutine helio_setup_pl(self, n) implicit none class(helio_pl), intent(inout) :: self !! Helio massive body object diff --git a/src/modules/rmvs_classes.f90 b/src/modules/rmvs_classes.f90 index 8a1f94a8e..8fc57cadf 100644 --- a/src/modules/rmvs_classes.f90 +++ b/src/modules/rmvs_classes.f90 @@ -21,12 +21,15 @@ module rmvs_classes !******************************************************************************************************************************** type, public, extends(whm_nbody_system) :: rmvs_nbody_system !> In the RMVS integrator, only test particles are discarded - logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations + real(DP) :: rts !! fraction of Hill's sphere radius to use as radius of encounter region + real(DP), dimension(:,:), allocatable :: vbeg !! Planet velocities at beginning ot step contains private !> Replace the abstract procedures with concrete ones procedure, public :: initialize => rmvs_setup_system !! Performs RMVS-specific initilization steps, like calculating the Jacobi masses procedure, public :: step => rmvs_step_system + procedure, public :: set_beg_end => rmvs_setup_set_beg_end !! Sets the beginning and ending values of planet positions. Also adds the end velocity for RMVS end type rmvs_nbody_system type, private :: rmvs_interp @@ -40,9 +43,9 @@ module rmvs_classes !******************************************************************************************************************************* !> RMVS central body particle class type, public, extends(whm_cb) :: rmvs_cb - logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of test particles used for close encounter calculations - type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters - type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters + type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations end type rmvs_cb !******************************************************************************************************************************** @@ -54,24 +57,22 @@ module rmvs_classes !! 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 ! encounter steps) - logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of test particles used for close encounter calculations 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) integer(I4B), dimension(:), allocatable :: plencP !! index of planet that test particle is encountering (not persistent for a full RMVS time step) - real(DP), dimension(:,:), allocatable :: vbeg !! Planet velocities at beginning ot step ! The following are used to correctly set the oblateness values of the acceleration during an inner encounter with a planet - type(rmvs_cb) :: cb_heliocentric !! Copy of original central body object passed to close encounter (used for oblateness acceleration during planetocentric encoountters) - real(DP), dimension(:,:), allocatable :: xheliocentric !! original heliocentric position (used for oblateness calculation during close encounters) - integer(I4B) :: index !! inner substep number within current set - integer(I4B) :: ipleP !! index value of encountering planet + type(rmvs_cb) :: cb_heliocentric !! Copy of original central body object passed to close encounter (used for oblateness acceleration during planetocentric encoountters) + real(DP), dimension(:,:), allocatable :: xheliocentric !! original heliocentric position (used for oblateness calculation during close encounters) + integer(I4B) :: index !! inner substep number within current set + integer(I4B) :: ipleP !! index value of encountering planet + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations contains procedure, public :: discard_pl => rmvs_discard_pl_tp 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 :: getacch => 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 :: set_beg_end => rmvs_setup_set_beg_end !! Sets the beginning and ending values of planet positions. Also adds the end velocity for RMVS 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) end type rmvs_tp @@ -80,81 +81,82 @@ module rmvs_classes ! rmvs_pl class definitions and method interfaces !******************************************************************************************************************************* - !> RMVS massive body particle class - type, private, extends(whm_pl) :: rmvs_base_pl - logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations - integer(I4B), dimension(:), allocatable :: nenc !! number of test particles encountering planet this full rmvs time step - integer(I4B), dimension(:), allocatable :: tpenc1P !! index of first test particle encountering planet - integer(I4B), dimension(:), allocatable :: plind ! Connects the planetocentric indices back to the heliocentric planet list - type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters - type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + type, private, extends(whm_pl) :: rmvs_pl + integer(I4B), dimension(:), allocatable :: nenc !! number of test particles encountering planet this full rmvs time step + integer(I4B), dimension(:), allocatable :: tpenc1P !! index of first test particle encountering planet + integer(I4B), dimension(:), allocatable :: plind ! Connects the planetocentric indices back to the heliocentric planet list + type(rmvs_interp), dimension(:), allocatable :: outer !! interpolated heliocentric central body position for outer encounters + type(rmvs_interp), dimension(:), allocatable :: inner !! interpolated heliocentric central body position for inner encounters + class(rmvs_nbody_system), dimension(:), allocatable :: planetocentric + logical :: lplanetocentric = .false. !! Flag that indicates that the object is a planetocentric set of masive bodies used for close encounter calculations contains 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 :: 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) - end type rmvs_base_pl - - type, public :: rmvs_encounter_system - class(rmvs_cb), allocatable :: cb - class(rmvs_tp), allocatable :: tp - class(rmvs_base_pl), allocatable :: pl - end type rmvs_encounter_system - - type, public, extends(rmvs_base_pl) :: rmvs_pl - type(rmvs_encounter_system), dimension(:), allocatable :: planetocentric - !! 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_pl and rmvs_spill_pl end type rmvs_pl - + interface - module subroutine rmvs_discard_pl_tp(self, pl, t, dt) - use swiftest_classes, only : swiftest_cb, swiftest_pl, swiftest_parameters + module subroutine rmvs_discard_pl_tp(self, system, param) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters implicit none - class(rmvs_tp), intent(inout) :: self - class(swiftest_pl), intent(inout) :: pl !! WHM massive body particle data structure. - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine rmvs_discard_pl_tp - module subroutine rmvs_getacch_tp(self, system, param, t, xh) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - use whm_classes, only : whm_nbody_system + module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) implicit none - class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure - class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets - end subroutine rmvs_getacch_tp + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + real(DP), intent(in) :: dt !! step size + logical :: lencounter !! Returns true if there is at least one close encounter + end function rmvs_encounter_check_tp - module subroutine rmvs_setup_system(self, param) - use swiftest_classes, only : swiftest_parameters + module subroutine rmvs_fill_pl(self, inserts, lfill_list) + use swiftest_classes, only : swiftest_body implicit none - class(rmvs_nbody_system), intent(inout) :: self !! RMVS system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - end subroutine rmvs_setup_system + 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 + + module subroutine rmvs_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 + + module subroutine rmvs_getacch_tp(self, system, param, t, xhp) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at current substep + end subroutine rmvs_getacch_tp module subroutine rmvs_setup_pl(self,n) implicit none - class(rmvs_base_pl), intent(inout) :: self !! RMVS test particle object + class(rmvs_pl), intent(inout) :: self !! RMVS test particle object integer, intent(in) :: n !! Number of test particles to allocate end subroutine rmvs_setup_pl module subroutine rmvs_setup_set_beg_end(self, xbeg, xend, vbeg) implicit none - class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object real(DP), dimension(:,:), intent(in), optional :: xbeg, xend, vbeg end subroutine rmvs_setup_set_beg_end - module subroutine rmvs_step_system(self, param, t, dt) + module subroutine rmvs_setup_system(self, param) use swiftest_classes, only : swiftest_parameters implicit none - class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object + class(rmvs_nbody_system), intent(inout) :: self !! RMVS 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 rmvs_step_system + end subroutine rmvs_setup_system module subroutine rmvs_setup_tp(self,n) implicit none @@ -162,32 +164,14 @@ module subroutine rmvs_setup_tp(self,n) integer, intent(in) :: n !! Number of test particles to allocate end subroutine rmvs_setup_tp - module function rmvs_encounter_check_tp(self, cb, pl, dt, rts) result(lencounter) - implicit none - class(rmvs_tp), intent(inout) :: self !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body object - class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object - real(DP), intent(in) :: dt !! step size - real(DP), intent(in) :: rts !! fraction of Hill's sphere radius to use as radius of encounter regio - logical :: lencounter !! Returns true if there is at least one close encounter - end function rmvs_encounter_check_tp - module subroutine rmvs_spill_pl(self, discards, lspill_list) use swiftest_classes, only : swiftest_body implicit none - class(rmvs_base_pl), intent(inout) :: self !! RMVS massive body object + 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 + logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards end subroutine rmvs_spill_pl - module subroutine rmvs_fill_pl(self, inserts, lfill_list) - use swiftest_classes, only : swiftest_body - implicit none - class(rmvs_base_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 - module subroutine rmvs_spill_tp(self, discards, lspill_list) use swiftest_classes, only : swiftest_body implicit none @@ -196,13 +180,15 @@ module subroutine rmvs_spill_tp(self, discards, lspill_list) logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards end subroutine rmvs_spill_tp - module subroutine rmvs_fill_tp(self, inserts, lfill_list) - use swiftest_classes, only : swiftest_body + module subroutine rmvs_step_system(self, param, t, dt) + use swiftest_classes, only : swiftest_parameters 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 + class(rmvs_nbody_system), intent(inout) :: self !! RMVS 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 rmvs_step_system + end interface end module rmvs_classes diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 905044f17..150408537 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -273,13 +273,12 @@ subroutine abstract_initialize(self, param) class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine abstract_initialize - subroutine abstract_read_frame(self, iu, param, form, t, ierr) + subroutine abstract_read_frame(self, iu, param, form, ierr) import DP, I4B, swiftest_base, swiftest_parameters class(swiftest_base), intent(inout) :: self !! Swiftest base object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code end subroutine abstract_read_frame @@ -317,38 +316,25 @@ end subroutine abstract_write_frame end interface interface - module subroutine discard_peri_tp(self, cb, pl, param, t, msys) - implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: msys !! Total system mass - end subroutine discard_peri_tp - - module subroutine discard_pl_close(dx, dv, dt, r2crit, iflag, r2min) + module subroutine discard_peri_tp(self, system, param) implicit none - real(DP), dimension(:), intent(in) :: dx, dv - real(DP), intent(in) :: dt, r2crit - integer(I4B), intent(out) :: iflag - real(DP), intent(out) :: r2min - end subroutine discard_pl_close + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter + end subroutine discard_peri_tp - module subroutine discard_pl_tp(self, pl, t, dt) + module subroutine discard_pl_tp(self, system, param) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_pl), intent(inout) :: pl !! Swiftest massive body object - real(DP), intent(in) :: t !! Current simulation tim - real(DP), intent(in) :: dt !! Stepsize + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameter end subroutine discard_pl_tp - module subroutine discard_sun_tp(self, cb, param, msys) + module subroutine discard_sun_tp(self, system, param) implicit none - class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - class(swiftest_parameters), intent(in) :: param !! parameters - real(DP), intent(in) :: msys !! Total system mass + class(swiftest_tp), intent(inout) :: self !! Swiftest test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine discard_sun_tp module subroutine discard_system(self, param) @@ -468,56 +454,33 @@ module subroutine io_read_param_in(self, param_file_name) character(len=*), intent(in) :: param_file_name !! Parameter input file name (i.e. param.in) end subroutine io_read_param_in - module function io_read_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & - xh1, xh2, vh1, vh2, encounter_file, out_type) result(ierr) - implicit none - integer(I4B) :: ierr - integer(I4B), intent(out) :: name1, name2 - real(DP), intent(out) :: t, mass1, mass2, radius1, radius2 - real(DP), dimension(NDIM), intent(out) :: xh1, xh2, vh1, vh2 - character(*), intent(in) :: encounter_file,out_type - end function io_read_encounter - - module subroutine io_read_frame_body(self, iu, param, form, t, ierr) + module subroutine io_read_frame_body(self, iu, param, form, ierr) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest particle object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_body - module subroutine io_read_frame_cb(self, iu, param, form, t, ierr) + module subroutine io_read_frame_cb(self, iu, param, form, ierr) implicit none class(swiftest_cb), intent(inout) :: self !! Swiftest central body object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Simulation time integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_cb - module subroutine io_read_frame_system(self, iu, param, form, t, ierr) + module subroutine io_read_frame_system(self, iu, param, form, ierr) implicit none class(swiftest_nbody_system),intent(inout) :: self !! Swiftest system object integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters character(*), intent(in) :: form !! Input format code ("XV" or "EL") - real(DP), intent(out) :: t !! Current simulation time integer(I4B), intent(out) :: ierr !! Error code end subroutine io_read_frame_system - module function io_read_hdr(iu, t, npl, ntp, out_form, out_type) result(ierr) - implicit none - integer(I4B) :: ierr - integer(I4B), intent(in) :: iu - integer(I4B), intent(out) :: npl, ntp - character(*), intent(out) :: out_form - real(DP), intent(out) :: t - character(*), intent(in) :: out_type - end function io_read_hdr - module subroutine io_read_initialize_system(self, param) implicit none class(swiftest_nbody_system), intent(inout) :: self !! Swiftest system object @@ -531,26 +494,17 @@ module subroutine io_write_discard(self, param, discards) class(swiftest_body), intent(inout) :: discards !! Swiftest discard object end subroutine io_write_discard - module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & - xh1, xh2, vh1, vh2, encounter_file, out_type) - implicit none - integer(I4B), intent(in) :: name1, name2 - real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 - real(DP), dimension(NDIM), intent(in) :: xh1, xh2, vh1, vh2 - character(*), intent(in) :: encounter_file, out_type - end subroutine io_write_encounter - module subroutine io_write_frame_body(self, iu, param) implicit none - class(swiftest_body), intent(in) :: self !! Swiftest particle object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_body), intent(in) :: self !! Swiftest particle 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 end subroutine io_write_frame_body module subroutine io_write_frame_cb(self, iu, param) implicit none - class(swiftest_cb), intent(in) :: self !! Swiftest central body object - integer(I4B), intent(inout) :: iu !! Unit number for the output file to write frame to + class(swiftest_cb), intent(in) :: self !! Swiftest central body 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 end subroutine io_write_frame_cb @@ -561,15 +515,6 @@ 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 io_write_hdr(iu, t, npl, ntp, out_form, out_type) - integer(I4B), intent(in) :: iu !! Output file unit number - real(DP), intent(in) :: t !! Current time of simulation - integer(I4B), intent(in) :: npl !! Number of massive bodies - integer(I4B), intent(in) :: ntp !! Number of test particles - character(*), intent(in) :: out_form !! Output format type ("EL" or "XV") - character(*), intent(in) :: out_type !! Output file format type (REAL4, REAL8 - see swiftest module for symbolic name definitions) - end subroutine io_write_hdr - module subroutine obl_acc_body(self, cb) implicit none class(swiftest_body), intent(inout) :: self !! Swiftest generic body object @@ -660,12 +605,12 @@ module subroutine setup_tp(self, n) integer, intent(in) :: n !! Number of bodies to allocate space for end subroutine setup_tp - module subroutine user_getacch_body(self, cb, param, t) + module subroutine user_getacch_body(self, system, param, t) implicit none - class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nobody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of + real(DP), intent(in) :: t !! Current time end subroutine user_getacch_body module subroutine util_coord_b2h_pl(self, cb) diff --git a/src/modules/whm_classes.f90 b/src/modules/whm_classes.f90 index e411201ae..031318161 100644 --- a/src/modules/whm_classes.f90 +++ b/src/modules/whm_classes.f90 @@ -9,19 +9,6 @@ module whm_classes implicit none public - !******************************************************************************************************************************** - ! whm_nbody_system class definitions and method interfaces - !******************************************************************************************************************************** - !> An abstract class for the WHM integrator nbody system - type, public, extends(swiftest_nbody_system) :: whm_nbody_system - !> In the WHM integrator, only test particles are discarded - class(swiftest_tp), allocatable :: tp_discards - contains - private - !> Replace the abstract procedures with concrete ones - procedure, public :: initialize => whm_setup_system !! Performs WHM-specific initilization steps, like calculating the Jacobi masses - procedure, public :: step => whm_step_system - end type whm_nbody_system !******************************************************************************************************************************** ! whm_cb class definitions and method interfaces @@ -71,8 +58,6 @@ module whm_classes type, public, extends(swiftest_tp) :: whm_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 whm_setup_tp and whm_spill_tp - real(DP), dimension(:,:), allocatable :: xbeg, xend - logical :: beg logical :: lfirst = .true. contains private @@ -82,67 +67,27 @@ module whm_classes procedure, public :: gr_p4 => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction procedure, public :: gr_vh2pv => whm_gr_vh2pv_tp !! Converts from heliocentric velocity to psudeovelocity for GR calculations procedure, public :: gr_pv2vh => whm_gr_pv2vh_tp !! Converts from psudeovelocity to heliocentric velocity for GR calculations - procedure, public :: set_beg_end => whm_setup_set_beg_end !! Sets the beginning and ending positions of planets. procedure, public :: setup => whm_setup_tp !! Allocates new components of the whm class and recursively calls parent allocations procedure, public :: step => whm_step_tp !! Steps the particle forward one stepsize end type whm_tp - interface - !> WHM massive body constructor method - module subroutine whm_setup_pl(self,n) - implicit none - class(whm_pl), intent(inout) :: self !! Swiftest test particle object - integer(I4B), intent(in) :: n !! Number of test particles to allocate - end subroutine whm_setup_pl - - module subroutine whm_setup_set_mu_eta_pl(self, cb) - use swiftest_classes, only : swiftest_cb - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body object - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object - end subroutine whm_setup_set_mu_eta_pl - - module subroutine whm_setup_set_ir3j(self) - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body object - end subroutine whm_setup_set_ir3j - - module subroutine whm_step_pl(self, system, param, t, dt) - use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body object - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest 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 whm_step_pl - - !> Get heliocentric accelration of massive bodies - module subroutine whm_getacch_pl(self, system, param, t) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current simulation time - end subroutine whm_getacch_pl - - module subroutine whm_drift_pl(self, system, param, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(whm_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_pl - - module subroutine whm_getacch_int_pl(self, cb) - use swiftest_classes, only : swiftest_cb - implicit none - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structure - end subroutine whm_getacch_int_pl + !******************************************************************************************************************************** + ! whm_nbody_system class definitions and method interfaces + !******************************************************************************************************************************** + !> An abstract class for the WHM integrator nbody system + type, public, extends(swiftest_nbody_system) :: whm_nbody_system + !> In the WHM integrator, only test particles are discarded + class(whm_tp), allocatable :: tp_discards !! WHM test particle object that + real(DP), dimension(:,:), allocatable :: xbeg, xend !! Positions of massive bodies at beginning and end of a step. Required in order to separate the test particle step from the massive body step + contains + private + !> Replace the abstract procedures with concrete ones + procedure, public :: initialize => whm_setup_system !! Performs WHM-specific initilization steps, like calculating the Jacobi masses + procedure, public :: step => whm_step_system + procedure, public :: set_beg_end => whm_setup_set_beg_end !! Sets the beginning and ending positions of planets. + end type whm_nbody_system + interface module subroutine whm_coord_h2j_pl(self, cb) use swiftest_classes, only : swiftest_cb implicit none @@ -164,27 +109,82 @@ 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) + 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 of + 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 + class(whm_pl), intent(inout) :: self !! WHM 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 whm_fill_pl + + !> Get heliocentric accelration of massive bodies + module subroutine whm_getacch_pl(self, system, param, t) + use swiftest_classes, only : swiftest_cb, 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 of + real(DP), intent(in) :: t !! Current simulation time + end subroutine whm_getacch_pl + + !> Get heliocentric accelration of the test particle + module subroutine whm_getacch_tp(self, system, param, t, xhp) + use swiftest_classes, only : swiftest_cb, 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) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at the current substep + end subroutine whm_getacch_tp + 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(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of end subroutine whm_gr_getacch_pl + module subroutine whm_gr_getacch_tp(self, param) + use swiftest_classes, only : swiftest_cb, swiftest_parameters + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + end subroutine whm_gr_getacch_tp + module pure subroutine whm_gr_p4_pl(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_pl), intent(inout) :: self !! Swiftest particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - real(DP), intent(in) :: dt !! Step size + real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl - module pure subroutine whm_gr_vh2pv_pl(self, param) + module pure subroutine whm_gr_p4_tp(self, param, dt) use swiftest_classes, only : swiftest_parameters implicit none - class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters - end subroutine whm_gr_vh2pv_pl + real(DP), intent(in) :: dt !! Step size + end subroutine whm_gr_p4_tp module pure subroutine whm_gr_pv2vh_pl(self, param) use swiftest_classes, only : swiftest_parameters @@ -193,78 +193,53 @@ module pure subroutine whm_gr_pv2vh_pl(self, param) class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters end subroutine whm_gr_pv2vh_pl - !> WHM test particle constructor - module subroutine whm_setup_tp(self,n) + module pure subroutine whm_gr_pv2vh_tp(self, param) + use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - integer, intent(in) :: n !! Number of test particles to allocate - end subroutine whm_setup_tp + class(whm_tp), intent(inout) :: self !! WHM test particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + end subroutine whm_gr_pv2vh_tp - module subroutine whm_drift_tp(self, system, param, dt) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module pure subroutine whm_gr_vh2pv_pl(self, param) + use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(whm_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 + class(whm_pl), intent(inout) :: self !! Swiftest particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + end subroutine whm_gr_vh2pv_pl - !> Get heliocentric accelration of the test particle - module subroutine whm_getacch_tp(self, system, param, t, xh) - use swiftest_classes, only : swiftest_cb, swiftest_parameters + module pure subroutine whm_gr_vh2pv_tp(self, param) + use swiftest_classes, only : swiftest_parameters implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(whm_nbody_system), intent(inout) :: system !! WHM nbody system object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets - end subroutine whm_getacch_tp + class(whm_tp), intent(inout) :: self !! WHM test particle object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of on parameters + end subroutine whm_gr_vh2pv_tp - module subroutine whm_step_tp(self, system, param, t, dt) - use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + + !> Reads WHM massive body object in from file + module subroutine whm_setup_pl(self,n) implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize - end subroutine whm_step_tp + class(whm_pl), intent(inout) :: self !! Swiftest test particle object + integer(I4B), intent(in) :: n !! Number of test particles to allocate + end subroutine whm_setup_pl module subroutine whm_setup_set_beg_end(self, xbeg, xend, vbeg) implicit none - class(whm_tp), intent(inout) :: self !! Swiftest test particle object + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object real(DP), dimension(:,:), intent(in), optional :: xbeg, xend real(DP), dimension(:,:), intent(in), optional :: vbeg ! vbeg is an unused variable to keep this method forward compatible with RMVS end subroutine whm_setup_set_beg_end - module subroutine whm_gr_getacch_tp(self, param) - use swiftest_classes, only : swiftest_cb, swiftest_parameters - implicit none - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - end subroutine whm_gr_getacch_tp - - 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 - real(DP), intent(in) :: dt !! Step size - end subroutine whm_gr_p4_tp - - module pure subroutine whm_gr_vh2pv_tp(self, param) - use swiftest_classes, only : swiftest_parameters + module subroutine whm_setup_set_ir3j(self) 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 - end subroutine whm_gr_vh2pv_tp + class(whm_pl), intent(inout) :: self !! WHM massive body object + end subroutine whm_setup_set_ir3j - module pure subroutine whm_gr_pv2vh_tp(self, param) - use swiftest_classes, only : swiftest_parameters + module subroutine whm_setup_set_mu_eta_pl(self, cb) + use swiftest_classes, only : swiftest_cb 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 - end subroutine whm_gr_pv2vh_tp + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + end subroutine whm_setup_set_mu_eta_pl module subroutine whm_setup_system(self, param) use swiftest_classes, only : swiftest_parameters @@ -273,6 +248,33 @@ module subroutine whm_setup_system(self, param) class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters end subroutine whm_setup_system + !> Reads WHM test particle object in from file + module subroutine whm_setup_tp(self,n) + implicit none + class(whm_tp), intent(inout) :: self !! WHM test particle data structure + integer, intent(in) :: n !! Number of test particles to allocate + end subroutine whm_setup_tp + + module subroutine whm_step_pl(self, system, param, t, dt) + use swiftest_classes, only : swiftest_nbody_system, swiftest_parameters + implicit none + class(whm_pl), intent(inout) :: self !! WHM massive body object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest 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 whm_step_pl + + module subroutine whm_step_tp(self, system, param, t, 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 !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Stepsize + end subroutine whm_step_tp + module subroutine whm_spill_pl(self, discards, lspill_list) use swiftest_classes, only : swiftest_body implicit none @@ -281,14 +283,6 @@ module subroutine whm_spill_pl(self, discards, lspill_list) logical, dimension(:), intent(in) :: lspill_list !! Logical array of bodies to spill into the discards end subroutine whm_spill_pl - module subroutine whm_fill_pl(self, inserts, lfill_list) - use swiftest_classes, only : swiftest_body - implicit none - class(whm_pl), intent(inout) :: self !! WHM 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 whm_fill_pl - !> Steps the Swiftest nbody system forward in time one stepsize module subroutine whm_step_system(self, param, t, dt) use swiftest_classes, only : swiftest_parameters diff --git a/src/rmvs/rmvs_discard.f90 b/src/rmvs/rmvs_discard.f90 index 4f75cd645..dc8b4b9bb 100644 --- a/src/rmvs/rmvs_discard.f90 +++ b/src/rmvs/rmvs_discard.f90 @@ -1,7 +1,7 @@ submodule(rmvs_classes) s_rmvs_discard use swiftest contains - module subroutine rmvs_discard_pl_tp(self, pl, t, dt) + module subroutine rmvs_discard_pl_tp(self, system, param) !! author: David A. Minton !! !! Check to see if test particles should be discarded based on pericenter passage distances with respect to @@ -11,14 +11,13 @@ module subroutine rmvs_discard_pl_tp(self, pl, t, dt) !! Adapted from Hal Levison's Swift routine rmvs_discard_pl.f90 implicit none ! Arguments - class(rmvs_tp), intent(inout) :: self - class(swiftest_pl), intent(inout) :: pl !! WHM massive body particle data structure. - real(DP), intent(in) :: t !! Current simulation time - real(DP), intent(in) :: dt !! Stepsize + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters ! Internals integer(I4B) :: i - associate(tp => self, ntp => self%nbody) + associate(tp => self, ntp => self%nbody, pl => system%pl, t => param%t) do i = 1, ntp associate(iplperP => tp%plperP(i)) if ((tp%status(i) == ACTIVE) .and. (tp%lperi(i))) then @@ -30,7 +29,7 @@ module subroutine rmvs_discard_pl_tp(self, pl, t, dt) end if end associate end do - call discard_pl_tp(tp, pl, t, dt) + call discard_pl_tp(tp, system, param) end associate end subroutine rmvs_discard_pl_tp diff --git a/src/rmvs/rmvs_encounter_check.f90 b/src/rmvs/rmvs_encounter_check.f90 index 3d5543166..9719567a9 100644 --- a/src/rmvs/rmvs_encounter_check.f90 +++ b/src/rmvs/rmvs_encounter_check.f90 @@ -1,7 +1,7 @@ submodule (rmvs_classes) s_rmvs_chk use swiftest contains - module function rmvs_encounter_check_tp(self, cb, pl, dt, rts) result(lencounter) + module function rmvs_encounter_check_tp(self, system, dt) result(lencounter) !! author: David A. Minton !! !! Determine whether a test particle and planet are having or will have an encounter within the next time step @@ -10,38 +10,39 @@ module function rmvs_encounter_check_tp(self, cb, pl, dt, rts) result(lencounter !! Adapted from Hal Levison's Swift routine rmvs3_chk.f implicit none ! Arguments - class(rmvs_tp), intent(inout) :: self !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body object - class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object - real(DP), intent(in) :: dt !! step size - real(DP), intent(in) :: rts !! fraction of Hill's sphere radius to use as radius of encounter regio - logical :: lencounter !! Returns true if there is at least one close encounter + class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + real(DP), intent(in) :: dt !! step size + ! 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), dimension(pl%nbody) :: r2crit - logical :: lflag + integer(I4B) :: i, j + real(DP) :: r2, v2, vdotr + real(DP), dimension(NDIM) :: xr, vr + real(DP), dimension(system%pl%nbody) :: r2crit + logical :: lflag - associate(tp => self, ntp => self%nbody, npl => pl%nbody, rhill => pl%rhill, xht => self%xh, vht => self%vh, & - xbeg => self%xbeg, vbeg => self%vbeg, status => self%status, plencP => self%plencP, nenc => pl%nenc) - r2crit(:) = (rts * rhill(:))**2 - plencP(:) = 0 - do j = 1, npl - do i = 1, ntp - if ((status(i) /= ACTIVE).or.(plencP(i) /= 0)) cycle - xr(:) = xht(:, i) - xbeg(:, j) - vr(:) = vht(:, i) - vbeg(:, j) - r2 = dot_product(xr(:), xr(:)) - v2 = dot_product(vr(:), vr(:)) - vdotr = dot_product(vr(:), xr(:)) - lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit(j)) - if (lflag) plencP(i) = j + select type(pl => system%pl) + class is (rmvs_pl) + associate(tp => self, ntp => self%nbody, npl => pl%nbody, xbeg => system%xbeg, vbeg => system%vbeg, rts => system%rts) + r2crit(:) = (rts * pl%rhill(:))**2 + tp%plencP(:) = 0 + do j = 1, npl + do i = 1, ntp + if ((tp%status(i) /= ACTIVE).or.(tp%plencP(i) /= 0)) cycle + xr(:) = tp%xh(:, i) - xbeg(:, j) + vr(:) = tp%vh(:, i) - vbeg(:, j) + r2 = dot_product(xr(:), xr(:)) + v2 = dot_product(vr(:), vr(:)) + vdotr = dot_product(vr(:), xr(:)) + lflag = rmvs_chk_ind(r2, v2, vdotr, dt, r2crit(j)) + if (lflag) tp%plencP(i) = j + end do + pl%nenc(j) = count(tp%plencP(:) == j) end do - nenc(j) = count(plencP(:) == j) - end do - lencounter = any(nenc(:) > 0) - end associate + lencounter = any(pl%nenc(:) > 0) + end associate + end select return end function rmvs_encounter_check_tp diff --git a/src/rmvs/rmvs_getacch.f90 b/src/rmvs/rmvs_getacch.f90 index 15fbc3b7a..8329b580a 100644 --- a/src/rmvs/rmvs_getacch.f90 +++ b/src/rmvs/rmvs_getacch.f90 @@ -1,7 +1,8 @@ submodule(rmvs_classes) s_rmvs_getacch use swiftest contains - module subroutine rmvs_getacch_tp(self, cb, pl, param, t, xh) + module subroutine rmvs_getacch_tp(self, system, param, t, xhp) + !! author: David A. Minton !! !! Compute the oblateness acceleration in the inner encounter region with planets @@ -10,69 +11,69 @@ module subroutine rmvs_getacch_tp(self, cb, pl, param, t, xh) !! uses object polymorphism, and so is not directly adapted. implicit none ! Arguments - class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(whm_pl), intent(inout) :: pl !! WHM massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of parameter - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + class(rmvs_tp), intent(inout) :: self !! RMVS test particle data structure + class(swiftest_nbody_system), intent(inout) :: system !! Swiftest central body particle data structuree + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at current substep ! Internals type(swiftest_parameters) :: param_planetocen real(DP), dimension(:, :), allocatable :: xh_original integer(I4B) :: i - associate(tp => self, ntp => self%nbody, ipleP => self%ipleP, & - inner_index => self%index, cb_heliocentric => self%cb_heliocentric) - - if (tp%lplanetocentric) then ! This is a close encounter step, so any accelerations requiring heliocentric position values - ! must be handeled outside the normal WHM method call - select type(pl) - class is (rmvs_pl) - select type (cb) - class is (rmvs_cb) - associate(xpc => pl%xh, xpct => self%xh) - allocate(xh_original, source=tp%xh) - param_planetocen = param - ! Temporarily turn off the heliocentric-dependent acceleration terms during an inner encounter - param_planetocen%loblatecb = .false. - param_planetocen%lextra_force = .false. - param_planetocen%lgr = .false. - ! Now compute the planetocentric values of acceleration - call whm_getacch_tp(tp, cb, pl, param_planetocen, t, xh) + associate(tp => self, ntp => self%nbody, ipleP => self%ipleP, inner_index => self%index, cb_heliocentric => self%cb_heliocentric) + select type(system) + class is (rmvs_nbody_system) + if (system%lplanetocentric) then ! This is a close encounter step, so any accelerations requiring heliocentric position values + ! must be handeled outside the normal WHM method call + select type(pl => system%pl) + class is (rmvs_pl) + select type (cb => system%cb) + class is (rmvs_cb) + associate(xpc => pl%xh, xpct => self%xh) + allocate(xh_original, source=tp%xh) + param_planetocen = param + ! Temporarily turn off the heliocentric-dependent acceleration terms during an inner encounter + param_planetocen%loblatecb = .false. + param_planetocen%lextra_force = .false. + param_planetocen%lgr = .false. + ! Now compute the planetocentric values of acceleration + call whm_getacch_tp(tp, system, param, t, xhp) - ! Now compute any heliocentric values of acceleration - if (tp%lfirst) then - do i = 1, ntp - tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index - 1)%x(:,1) - end do - else - do i = 1, ntp - tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index )%x(:,1) - end do - end if - ! Swap the planetocentric and heliocentric position vectors - tp%xh(:,:) = tp%xheliocentric(:,:) - if (param%loblatecb) then - ! Put in the current encountering planet's oblateness acceleration as the central body's + ! Now compute any heliocentric values of acceleration if (tp%lfirst) then - cb_heliocentric%aobl(:) = cb%inner(inner_index - 1)%aobl(:,1) + do i = 1, ntp + tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index - 1)%x(:,1) + end do else - cb_heliocentric%aobl(:) = cb%inner(inner_index )%aobl(:,1) + do i = 1, ntp + tp%xheliocentric(:,i) = tp%xh(:,i) + cb%inner(inner_index )%x(:,1) + end do + end if + ! Swap the planetocentric and heliocentric position vectors + tp%xh(:,:) = tp%xheliocentric(:,:) + if (param%loblatecb) then + ! Put in the current encountering planet's oblateness acceleration as the central body's + if (tp%lfirst) then + cb_heliocentric%aobl(:) = cb%inner(inner_index - 1)%aobl(:,1) + else + cb_heliocentric%aobl(:) = cb%inner(inner_index )%aobl(:,1) + end if + call tp%obl_acc(cb_heliocentric) end if - call tp%obl_acc(cb_heliocentric) - end if - if (param%lextra_force) call tp%user_getacch(cb_heliocentric, param, t) - if (param%lgr) call tp%gr_getacch(cb_heliocentric, param) - - tp%xh(:,:) = xh_original(:,:) - end associate - end select - end select - else ! Not a close encounter, so just proceded with the standard WHM method - call whm_getacch_tp(tp, cb, pl, param, t, xh) - end if + if (param%lextra_force) call tp%user_getacch(system, param, t) + if (param%lgr) call tp%gr_getacch(param) + + tp%xh(:,:) = xh_original(:,:) + end associate + end select + end select + else ! Not a close encounter, so just proceded with the standard WHM method + call whm_getacch_tp(tp, system, param, t, xhp) + end if + end select end associate diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index b3bcf8f28..2835aea6c 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -9,7 +9,7 @@ module subroutine rmvs_setup_pl(self,n) !! Equivalent in functionality to David E. Kaufmann's Swifter routine rmvs_setup.f90 implicit none ! Arguments - class(rmvs_base_pl), intent(inout) :: self !! RMVS test particle object + class(rmvs_pl), intent(inout) :: self !! RMVS test particle object integer(I4B), intent(in) :: n !! Number of test particles to allocate ! Internals integer(I4B) :: i,j @@ -97,46 +97,49 @@ module subroutine rmvs_setup_system(self, param) ! generated as necessary during close encounter steps. select type(pl => self%pl) class is(rmvs_pl) - select type(cb => self%cb) - class is (rmvs_cb) - select type (tp => self%tp) - class is (rmvs_tp) - tp%cb_heliocentric = cb - pl%lplanetocentric = .false. - tp%lplanetocentric = .false. - cb%lplanetocentric = .false. - associate(npl => pl%nbody) - allocate(pl%planetocentric(npl)) - do i = 1, npl - allocate(pl%planetocentric(i)%cb, source=cb) - allocate(rmvs_pl :: pl%planetocentric(i)%pl) - associate(plenci => pl%planetocentric(i)%pl, cbenci => pl%planetocentric(i)%cb) - cbenci%lplanetocentric = .true. - plenci%lplanetocentric = .true. - call plenci%setup(npl) - plenci%status(:) = ACTIVE - - ! plind stores the heliocentric index value of a planetocentric planet - ! e.g. Consider an encounter with planet 3. - ! Then the following will be the values of plind: - ! pl%planetocentric(3)%pl%plind(1) = 0 (central body - never used) - ! pl%planetocentric(3)%pl%plind(2) = 1 - ! pl%planetocentric(3)%pl%plind(3) = 2 - ! pl%planetocentric(3)%pl%plind(4) = 4 - ! pl%planetocentric(3)%pl%plind(5) = 5 - ! etc. - allocate(plenci%plind(npl)) - plenci%plind(1:npl) = [(j,j=1,npl)] - plenci%plind(2:npl) = pack(plenci%plind(1:npl), plenci%plind(1:npl) /= i) - plenci%plind(1) = 0 - plenci%Gmass(1) = cb%Gmass - plenci%Gmass(2:npl) = pl%Gmass(plenci%plind(2:npl)) - cbenci%Gmass = pl%Gmass(i) + select type(cb => self%cb) + class is (rmvs_cb) + select type (tp => self%tp) + class is (rmvs_tp) + tp%cb_heliocentric = cb + pl%lplanetocentric = .false. + tp%lplanetocentric = .false. + cb%lplanetocentric = .false. + associate(npl => pl%nbody) + allocate(pl%planetocentric(npl)) + do i = 1, npl + pl%planetocentric(i)%lplanetocentric = .true. + allocate(pl%planetocentric(i)%cb, source=cb) + allocate(rmvs_cb :: pl%planetocentric(i)%cb) + allocate(rmvs_pl :: pl%planetocentric(i)%pl) + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + call plenci%setup(npl) + plenci%status(:) = ACTIVE + ! plind stores the heliocentric index value of a planetocentric planet + ! e.g. Consider an encounter with planet 3. + ! Then the following will be the values of plind: + ! pl%planetocentric(3)%pl%plind(1) = 0 (central body - never used) + ! pl%planetocentric(3)%pl%plind(2) = 1 + ! pl%planetocentric(3)%pl%plind(3) = 2 + ! pl%planetocentric(3)%pl%plind(4) = 4 + ! pl%planetocentric(3)%pl%plind(5) = 5 + ! etc. + allocate(plenci%plind(npl)) + plenci%plind(1:npl) = [(j,j=1,npl)] + plenci%plind(2:npl) = pack(plenci%plind(1:npl), plenci%plind(1:npl) /= i) + plenci%plind(1) = 0 + plenci%Gmass(1) = cb%Gmass + plenci%Gmass(2:npl) = pl%Gmass(plenci%plind(2:npl)) + cbenci%Gmass = pl%Gmass(i) + end select + end select + end do end associate - end do - end associate - end select - end select + end select + end select end select end subroutine rmvs_setup_system @@ -147,7 +150,7 @@ module subroutine rmvs_setup_set_beg_end(self, xbeg, xend, vbeg) !! Sets one or more of the values of xbeg, xend, and vbeg implicit none ! Arguments - class(rmvs_tp), intent(inout) :: self !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: self !! RMVS test particle object real(DP), dimension(:,:), intent(in), optional :: xbeg, xend, vbeg if (present(xbeg)) then diff --git a/src/rmvs/rmvs_spill_and_fill.f90 b/src/rmvs/rmvs_spill_and_fill.f90 index 4eb1e81dc..ae0ff563b 100644 --- a/src/rmvs/rmvs_spill_and_fill.f90 +++ b/src/rmvs/rmvs_spill_and_fill.f90 @@ -9,9 +9,9 @@ module subroutine rmvs_spill_pl(self, discards, lspill_list) !! Adapted from David E. Kaufmann's Swifter routine discard_discard_spill.f90 implicit none ! Arguments - class(rmvs_base_pl), intent(inout) :: self !! Swiftest massive body 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 + class(rmvs_pl), intent(inout) :: self !! Swiftest massive body 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 ! Internals integer(I4B) :: i @@ -41,7 +41,7 @@ module subroutine rmvs_fill_pl(self, inserts, lfill_list) !! implicit none ! Arguments - class(rmvs_base_pl), intent(inout) :: self !! RMVS massive body object + 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 ! Internals diff --git a/src/rmvs/rmvs_step.f90 b/src/rmvs/rmvs_step.f90 index 7995efdd8..3336d3e98 100644 --- a/src/rmvs/rmvs_step.f90 +++ b/src/rmvs/rmvs_step.f90 @@ -1,7 +1,7 @@ submodule(rmvs_classes) s_rmvs_step use swiftest contains - module subroutine rmvs_step_system(self, param, dt) + module subroutine rmvs_step_system(self, param, t, dt) !! author: David A. Minton !! !! Step massive bodies and and active test particles ahead in heliocentric coordinates @@ -12,60 +12,58 @@ module subroutine rmvs_step_system(self, param, dt) ! Arguments class(rmvs_nbody_system), intent(inout) :: self !! RMVS nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - integer(I4B), intent(in) :: dt !! Current stepsize + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsiz ! Internals logical :: lencounter, lfirstpl, lfirsttp real(DP) :: rts real(DP), dimension(:,:), allocatable :: xbeg, xend, vbeg integer(I4B) :: i - select type(system => self) - class is (rmvs_nbody_system) select type(cb => self%cb) class is (rmvs_cb) - select type(pl => self%pl) - class is (rmvs_pl) - select type(tp => self%tp) - class is (rmvs_tp) - associate(ntp => tp%nbody, npl => pl%nbody, t => param%t) - allocate(xbeg, source=pl%xh) - allocate(vbeg, source=pl%vh) - call pl%set_rhill(cb) - call tp%set_beg_end(xbeg = xbeg, vbeg = vbeg) - ! ****** Check for close encounters ***** ! - rts = RHSCALE - lencounter = tp%encounter_check(cb, pl, dt, rts) - if (lencounter) then - lfirstpl = pl%lfirst - lfirsttp = tp%lfirst - pl%outer(0)%x(:,:) = xbeg(:,:) - pl%outer(0)%v(:,:) = vbeg(:,:) - call pl%step(system, param, dt) - pl%outer(NTENC)%x(:,:) = pl%xh(:,:) - pl%outer(NTENC)%v(:,:) = pl%vh(:,:) - call tp%set_beg_end(xend = pl%xh) - call rmvs_interp_out(system, param, dt) - call rmvs_step_out(system, param, dt) - call tp%reverse_status() - call tp%set_beg_end(xbeg = xbeg, xend = xend) - tp%lfirst = .true. - call tp%step(system, param, dt) - where (tp%status(:) == INACTIVE) tp%status(:) = ACTIVE - pl%lfirst = lfirstpl - tp%lfirst = lfirsttp - else - call whm_step_system(self, param) - end if - end associate - end select - end select - end select + select type(pl => self%pl) + class is (rmvs_pl) + select type(tp => self%tp) + class is (rmvs_tp) + associate(system => self, ntp => tp%nbody, npl => pl%nbody) + allocate(xbeg, source=pl%xh) + allocate(vbeg, source=pl%vh) + call pl%set_rhill(cb) + call system%set_beg_end(xbeg = xbeg, vbeg = vbeg) + ! ****** Check for close encounters ***** ! + system%rts = RHSCALE + lencounter = tp%encounter_check(system, dt) + if (lencounter) then + lfirstpl = pl%lfirst + lfirsttp = tp%lfirst + pl%outer(0)%x(:,:) = xbeg(:,:) + pl%outer(0)%v(:,:) = vbeg(:,:) + call pl%step(system, param, t, dt) + pl%outer(NTENC)%x(:,:) = pl%xh(:,:) + pl%outer(NTENC)%v(:,:) = pl%vh(:,:) + call system%set_beg_end(xend = pl%xh) + call rmvs_interp_out(system, param, dt) + call rmvs_step_out(system, param, t, dt) + call tp%reverse_status() + call system%set_beg_end(xbeg = xbeg, xend = xend) + tp%lfirst = .true. + call tp%step(system, param, t, dt) + where (tp%status(:) == INACTIVE) tp%status(:) = ACTIVE + pl%lfirst = lfirstpl + tp%lfirst = lfirsttp + else + call whm_step_system(self, param, t, dt) + end if + end associate + end select + end select end select return end subroutine rmvs_step_system - subroutine rmvs_step_out(system, param, dt) + subroutine rmvs_step_out(system, param, t, dt) !! author: David A. Minton !! !! Step ACTIVE test particles ahead in the outer encounter region, setting up and calling the inner region @@ -77,49 +75,56 @@ subroutine rmvs_step_out(system, param, dt) ! Arguments class(rmvs_nbody_system), intent(inout) :: system !! Swiftest system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - integer(I4B), intent(in) :: dt !! Current stepsize + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsiz ! Internals integer(I4B) :: outer_index, j, k real(DP) :: dto, outer_time, rts logical :: lencounter, lfirsttp - associate(cb => system%cb, pl => system%pl, npl => system%pl%nbody, tp => system%tp, ntp => system%tp%nbody, t => param%t) - dto = dt / NTENC - where(tp%plencP(:) == 0) - tp%status(:) = INACTIVE - elsewhere - tp%lperi(:) = .false. - end where - do outer_index = 1, NTENC - outer_time = t + (outer_index - 1) * dto - call tp%set_beg_end(xbeg = pl%outer(outer_index - 1)%x(:, :), & - vbeg = pl%outer(outer_index - 1)%v(:, :), & - xend = pl%outer(outer_index )%x(:, :)) - rts = RHPSCALE - lencounter = tp%encounter_check(cb, pl, dt, rts) - if (lencounter) then - ! Interpolate planets in inner encounter region - call rmvs_interp_in(system, param, dto, outer_index) - ! Step through the inner region - call rmvs_step_in(system, param, outer_time, dto) - lfirsttp = tp%lfirst - tp%lfirst = .true. - call tp%step(cb, pl, param, outer_time, dto) - tp%lfirst = lfirsttp - else - call tp%step(cb, pl, param, outer_time, dto) - end if - do j = 1, npl - if (pl%nenc(j) == 0) cycle - where((tp%plencP(:) == j) .and. (tp%status(:) == INACTIVE)) tp%status(:) = ACTIVE - end do - end do - end associate + select type(pl => system%pl) + class is (rmvs_pl) + select type(tp => system%tp) + class is (rmvs_tp) + associate(cb => system%cb, npl => pl%nbody, ntp => tp%nbody) + dto = dt / NTENC + where(tp%plencP(:) == 0) + tp%status(:) = INACTIVE + elsewhere + tp%lperi(:) = .false. + end where + do outer_index = 1, NTENC + outer_time = t + (outer_index - 1) * dto + call system%set_beg_end(xbeg = pl%outer(outer_index - 1)%x(:, :), & + vbeg = pl%outer(outer_index - 1)%v(:, :), & + xend = pl%outer(outer_index )%x(:, :)) + system%rts = RHPSCALE + lencounter = tp%encounter_check(system, dt) + if (lencounter) then + ! Interpolate planets in inner encounter region + call rmvs_interp_in(system, param, dto, outer_index) + ! Step through the inner region + call rmvs_step_in(system, param, outer_time, dto) + lfirsttp = tp%lfirst + tp%lfirst = .true. + call tp%step(system, param, outer_time, dto) + tp%lfirst = lfirsttp + else + call tp%step(system, param, outer_time, dto) + end if + do j = 1, npl + if (pl%nenc(j) == 0) cycle + where((tp%plencP(:) == j) .and. (tp%status(:) == INACTIVE)) tp%status(:) = ACTIVE + end do + end do + end associate + end select + end select return end subroutine rmvs_step_out - subroutine rmvs_step_in(pl, cb, tp, param, outer_time, dto) + subroutine rmvs_step_in(system, param, outer_time, dto) !! author: David A. Minton !! !! Step active test particles ahead in the inner encounter region @@ -128,57 +133,63 @@ subroutine rmvs_step_in(pl, cb, tp, param, outer_time, dto) !! Adapted from David E. Kaufmann's Swifter routine rmvs_step_in.f90 implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS massive body object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body object - class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters - real(DP), intent(in) :: outer_time !! Current time - real(DP), intent(in) :: dto !! Step size + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters + real(DP), intent(in) :: outer_time !! Current time + real(DP), intent(in) :: dto !! Outer step size ! Internals - logical :: lfirsttp - integer(I4B) :: i, j, ipleP - real(DP) :: dti, inner_time - real(DP), dimension(:, :), allocatable :: xbeg, xend, vbeg + logical :: lfirsttp + integer(I4B) :: i, j, ipleP + real(DP) :: dti, inner_time - associate(npl => pl%nbody, nenc => pl%nenc) - dti = dto / NTPHENC - allocate(xbeg, mold=pl%xh) - allocate(xend, mold=pl%xh) - allocate(vbeg, mold=pl%vh) - if (param%loblatecb) call pl%obl_acc(cb) - call rmvs_make_planetocentric(pl, cb, tp, param) - do i = 1, npl - if (nenc(i) == 0) cycle - associate(cbenci => pl%planetocentric(i)%cb, plenci => pl%planetocentric(i)%pl, & - tpenci => pl%planetocentric(i)%tp) - associate(inner_index => tpenci%index) - ! There are inner encounters with this planet...switch to planetocentric coordinates to proceed - tpenci%lfirst = .true. - inner_time = outer_time - call rmvs_peri_tp(tpenci, pl, inner_time, dti, .true., 0, i, param) - ! now step the encountering test particles fully through the inner encounter - lfirsttp = .true. - do inner_index = 1, NTPHENC ! Integrate over the encounter region, using the "substitute" planetocentric systems at each level - plenci%xh(:,:) = plenci%inner(inner_index - 1)%x(:,:) - call tpenci%set_beg_end(xbeg = plenci%inner(inner_index - 1)%x, & - xend = plenci%inner(inner_index)%x) - call tpenci%step(cbenci, plenci, param, inner_time, dti) - do j = 1, nenc(i) - tpenci%xheliocentric(:, j) = tpenci%xh(:, j) + pl%inner(inner_index)%x(:,i) - end do - inner_time = outer_time + j * dti - call rmvs_peri_tp(tpenci, pl, inner_time, dti, .false., inner_index, i, param) - end do - where(tpenci%status(:) == ACTIVE) tpenci%status(:) = INACTIVE - end associate + select type(pl => system%pl) + class is (rmvs_pl) + select type (tp => system%tp) + class is (rmvs_tp) + associate(npl => pl%nbody, cb => system%cb) + dti = dto / NTPHENC + if (param%loblatecb) call pl%obl_acc(cb) + call rmvs_make_planetocentric(system, param) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + select type(planetocen_system => pl%planetocentric(i)) + class is (rmvs_nbody_system) + select type(plenci => planetocen_system%pl) + class is (rmvs_pl) + select type(tpenci => planetocen_system%tp) + class is (rmvs_tp) + associate(inner_index => tpenci%index) + ! There are inner encounters with this planet...switch to planetocentric coordinates to proceed + tpenci%lfirst = .true. + inner_time = outer_time + call rmvs_peri_tp(tpenci, pl, inner_time, dti, .true., 0, i, param) + ! now step the encountering test particles fully through the inner encounter + lfirsttp = .true. + do inner_index = 1, NTPHENC ! Integrate over the encounter region, using the "substitute" planetocentric systems at each level + plenci%xh(:,:) = plenci%inner(inner_index - 1)%x(:,:) + call planetocen_system%set_beg_end(xbeg = plenci%inner(inner_index - 1)%x, & + xend = plenci%inner(inner_index)%x) + call tpenci%step(planetocen_system, param, inner_time, dti) + do j = 1, pl%nenc(i) + tpenci%xheliocentric(:, j) = tpenci%xh(:, j) + pl%inner(inner_index)%x(:,i) + end do + inner_time = outer_time + j * dti + call rmvs_peri_tp(tpenci, pl, inner_time, dti, .false., inner_index, i, param) + end do + where(tpenci%status(:) == ACTIVE) tpenci%status(:) = INACTIVE + end associate + end select + end select + end select + end do + call rmvs_end_planetocentric(system) end associate - end do - call rmvs_end_planetocentric(pl, cb, tp) - end associate + end select + end select return end subroutine rmvs_step_in - subroutine rmvs_interp_in(pl, cb, dt, outer_index, param) + subroutine rmvs_interp_in(system, param, dt, outer_index) !! author: David A. Minton !! !! Interpolate planet positions between two Keplerian orbits in inner encounter regio @@ -188,107 +199,109 @@ subroutine rmvs_interp_in(pl, cb, dt, outer_index, param) !! Adapted from Hal Levison's Swift routine rmvs3_interp.f implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body particle type - real(DP), intent(in) :: dt !! Step size - integer(I4B), intent(in) :: outer_index !! Outer substep number within current se - class(swiftest_parameters), intent(in) :: param !! Swiftest parameters file + class(rmvs_nbody_system), intent(inout) :: system !! RMVS test particle object + class(swiftest_parameters), intent(in) :: param !! Swiftest parameters file + real(DP), intent(in) :: dt !! Step size + integer(I4B), intent(in) :: outer_index !! Outer substep number within current set ! Internals - integer(I4B) :: i, inner_index - real(DP) :: frac, dntphenc - real(DP), dimension(:,:), allocatable :: xtmp, vtmp, xh_original - real(DP), dimension(:), allocatable :: msun, dti - integer(I4B), dimension(:), allocatable :: iflag - - associate (npl => pl%nbody) - dntphenc = real(NTPHENC, kind=DP) + integer(I4B) :: i, inner_index + real(DP) :: frac, dntphenc + real(DP), dimension(:,:), allocatable :: xtmp, vtmp, xh_original + real(DP), dimension(:), allocatable :: GMcb, dti + integer(I4B), dimension(:), allocatable :: iflag - ! Set the endpoints of the inner region from the outer region values in the current outer step index - pl%inner(0)%x(:,:) = pl%outer(outer_index - 1)%x(:, :) - pl%inner(0)%v(:,:) = pl%outer(outer_index - 1)%v(:, :) - pl%inner(NTPHENC)%x(:,:) = pl%outer(outer_index)%x(:, :) - pl%inner(NTPHENC)%v(:,:) = pl%outer(outer_index)%v(:, :) - - allocate(xtmp,mold=pl%xh) - allocate(vtmp,mold=pl%vh) - allocate(msun(npl)) - allocate(dti(npl)) - allocate(iflag(npl)) - dti(:) = dt / dntphenc - msun(:) = cb%Gmass - xtmp(:, :) = pl%inner(0)%x(:, :) - vtmp(:, :) = pl%inner(0)%v(:, :) - if (param%loblatecb) then - allocate(xh_original,source=pl%xh) - pl%xh(:, :) = xtmp(:, :) ! Temporarily replace heliocentric position with inner substep values to calculate the oblateness terms - call pl%obl_acc(cb) - pl%inner(0)%aobl(:, :) = pl%aobl(:, :) ! Save the oblateness acceleration on the planet for this substep - end if - - do inner_index = 1, NTPHENC - 1 - call drift_one(msun(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & - vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & - dti(1:npl), iflag(1:npl)) - if (any(iflag(1:npl) /= 0)) then - do i = 1, npl - if (iflag(i) /=0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" - write(*, *) msun(i), dti(i) - write(*, *) xtmp(:,i) - write(*, *) vtmp(:,i) - write(*, *) " STOPPING " - call util_exit(failure) - end if - end do - end if - frac = 1.0_DP - inner_index / dntphenc - pl%inner(inner_index)%x(:, :) = frac * xtmp(:,:) - pl%inner(inner_index)%v(:, :) = frac * vtmp(:,:) - end do + associate (cb => system%cb, npl => system%pl%nbody) + select type(pl => system%pl) + class is (rmvs_pl) + dntphenc = real(NTPHENC, kind=DP) - xtmp(:,:) = pl%inner(NTPHENC)%x(:, :) - vtmp(:,:) = pl%inner(NTPHENC)%v(:, :) - - do inner_index = NTPHENC - 1, 1, -1 - call drift_one(msun(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & - vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & - -dti(1:npl), iflag(1:npl)) - if (any(iflag(1:npl) /= 0)) then - do i = 1, npl - if (iflag(i) /=0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" - write(*, *) msun(i), -dti(i) - write(*, *) xtmp(:,i) - write(*, *) vtmp(:,i) - write(*, *) " STOPPING " - call util_exit(failure) - end if - end do + ! Set the endpoints of the inner region from the outer region values in the current outer step index + pl%inner(0)%x(:,:) = pl%outer(outer_index - 1)%x(:, :) + pl%inner(0)%v(:,:) = pl%outer(outer_index - 1)%v(:, :) + pl%inner(NTPHENC)%x(:,:) = pl%outer(outer_index)%x(:, :) + pl%inner(NTPHENC)%v(:,:) = pl%outer(outer_index)%v(:, :) + + allocate(xtmp,mold=pl%xh) + allocate(vtmp,mold=pl%vh) + allocate(GMcb(npl)) + allocate(dti(npl)) + allocate(iflag(npl)) + dti(:) = dt / dntphenc + GMcb(:) = cb%Gmass + xtmp(:, :) = pl%inner(0)%x(:, :) + vtmp(:, :) = pl%inner(0)%v(:, :) + if (param%loblatecb) then + allocate(xh_original,source=pl%xh) + pl%xh(:, :) = xtmp(:, :) ! Temporarily replace heliocentric position with inner substep values to calculate the oblateness terms + call pl%obl_acc(cb) + pl%inner(0)%aobl(:, :) = pl%aobl(:, :) ! Save the oblateness acceleration on the planet for this substep end if - frac = inner_index / dntphenc - pl%inner(inner_index)%x(:, :) = pl%inner(inner_index)%x(:, :) + frac * xtmp(:, :) - pl%inner(inner_index)%v(:, :) = pl%inner(inner_index)%v(:, :) + frac * vtmp(:, :) - + + do inner_index = 1, NTPHENC - 1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + dti(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /=0) then + write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), dti(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(failure) + end if + end do + end if + frac = 1.0_DP - inner_index / dntphenc + pl%inner(inner_index)%x(:, :) = frac * xtmp(:,:) + pl%inner(inner_index)%v(:, :) = frac * vtmp(:,:) + end do + + xtmp(:,:) = pl%inner(NTPHENC)%x(:, :) + vtmp(:,:) = pl%inner(NTPHENC)%v(:, :) + + do inner_index = NTPHENC - 1, 1, -1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + -dti(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /=0) then + write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), -dti(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(failure) + end if + end do + end if + frac = inner_index / dntphenc + pl%inner(inner_index)%x(:, :) = pl%inner(inner_index)%x(:, :) + frac * xtmp(:, :) + pl%inner(inner_index)%v(:, :) = pl%inner(inner_index)%v(:, :) + frac * vtmp(:, :) + + if (param%loblatecb) then + pl%xh(:,:) = pl%inner(inner_index)%x(:, :) + call pl%obl_acc(cb) + pl%inner(inner_index)%aobl(:, :) = pl%aobl(:, :) + end if + end do if (param%loblatecb) then - pl%xh(:,:) = pl%inner(inner_index)%x(:, :) + ! Calculate the final value of oblateness accelerations at the final inner substep + pl%xh(:,:) = pl%inner(NTPHENC)%x(:, :) call pl%obl_acc(cb) - pl%inner(inner_index)%aobl(:, :) = pl%aobl(:, :) + pl%inner(NTPHENC)%aobl(:, :) = pl%aobl(:, :) + ! Put the planet positions back into place + call move_alloc(xh_original, pl%xh) end if - end do - if (param%loblatecb) then - ! Calculate the final value of oblateness accelerations at the final inner substep - pl%xh(:,:) = pl%inner(NTPHENC)%x(:, :) - call pl%obl_acc(cb) - pl%inner(NTPHENC)%aobl(:, :) = pl%aobl(:, :) - ! Put the planet positions back into place - call move_alloc(xh_original, pl%xh) - end if + end select end associate return end subroutine rmvs_interp_in - subroutine rmvs_interp_out(pl, cb, dt, param) + subroutine rmvs_interp_out(system, param, dt) !! author: David A. Minton !! !! Interpolate planet positions between two Keplerian orbits in outer encounter region @@ -298,72 +311,73 @@ subroutine rmvs_interp_out(pl, cb, dt, param) !! Adapted from Hal Levison's Swift routine rmvs3_interp.f implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body particle type - real(DP), intent(in) :: dt !! Step size + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object class(swiftest_parameters), intent(in) :: param !! Swiftest parameters file + real(DP), intent(in) :: dt !! Step size ! Internals - integer(I4B) :: i, outer_index - real(DP) :: frac, dntenc - real(DP), dimension(:,:), allocatable :: xtmp, vtmp - real(DP), dimension(:), allocatable :: msun, dto - integer(I4B), dimension(:), allocatable :: iflag + integer(I4B) :: i, outer_index + real(DP) :: frac, dntenc + real(DP), dimension(:,:), allocatable :: xtmp, vtmp + real(DP), dimension(:), allocatable :: GMcb, dto + integer(I4B), dimension(:), allocatable :: iflag - ! executable code - dntenc = real(NTENC, DP) - associate (npl => pl%nbody) - allocate(xtmp, mold = pl%xh) - allocate(vtmp, mold = pl%vh) - allocate(msun(npl)) - allocate(dto(npl)) - allocate(iflag(npl)) - dto(:) = dt / dntenc - msun(:) = cb%Gmass - xtmp(:,:) = pl%outer(0)%x(:, :) - vtmp(:,:) = pl%outer(0)%v(:, :) - do outer_index = 1, NTENC - 1 - call drift_one(msun(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & - vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & - dto(1:npl), iflag(1:npl)) + dntenc = real(NTENC, kind=DP) + associate (cb => system%cb, pl => system%pl, npl => system%pl%nbody) + select type(pl => system%pl) + class is (rmvs_pl) + allocate(xtmp, mold = pl%xh) + allocate(vtmp, mold = pl%vh) + allocate(GMcb(npl)) + allocate(dto(npl)) + allocate(iflag(npl)) + dto(:) = dt / dntenc + GMcb(:) = cb%Gmass + xtmp(:,:) = pl%outer(0)%x(:, :) + vtmp(:,:) = pl%outer(0)%v(:, :) + do outer_index = 1, NTENC - 1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + dto(1:npl), iflag(1:npl)) - if (any(iflag(1:npl) /= 0)) then - do i = 1, npl - if (iflag(i) /= 0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" - write(*, *) msun(i), dto(i) - write(*, *) xtmp(:,i) - write(*, *) vtmp(:,i) - write(*, *) " STOPPING " - call util_exit(FAILURE) - end if - end do - end if - frac = 1.0_DP - outer_index / dntenc - pl%outer(outer_index)%x(:, :) = frac * xtmp(:,:) - pl%outer(outer_index)%v(:, :) = frac * vtmp(:,:) - end do - xtmp(:,:) = pl%outer(NTENC)%x(:, :) - vtmp(:,:) = pl%outer(NTENC)%v(:, :) - do outer_index = NTENC - 1, 1, -1 - call drift_one(msun(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & - vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & - -dto(1:npl), iflag(1:npl)) - if (any(iflag(1:npl) /= 0)) then - do i = 1, npl - if (iflag(i) /= 0) then - write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" - write(*, *) msun(i), -dto(i) - write(*, *) xtmp(:,i) - write(*, *) vtmp(:,i) - write(*, *) " STOPPING " - call util_exit(FAILURE) - end if - end do - end if - frac = outer_index / dntenc - pl%outer(outer_index)%x(:, :) = pl%outer(outer_index)%x(:, :) + frac * xtmp(:,:) - pl%outer(outer_index)%v(:, :) = pl%outer(outer_index)%v(:, :) + frac * vtmp(:,:) - end do + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), dto(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(FAILURE) + end if + end do + end if + frac = 1.0_DP - outer_index / dntenc + pl%outer(outer_index)%x(:, :) = frac * xtmp(:,:) + pl%outer(outer_index)%v(:, :) = frac * vtmp(:,:) + end do + xtmp(:,:) = pl%outer(NTENC)%x(:, :) + vtmp(:,:) = pl%outer(NTENC)%v(:, :) + do outer_index = NTENC - 1, 1, -1 + call drift_one(GMcb(1:npl), xtmp(1,1:npl), xtmp(2,1:npl), xtmp(3,1:npl), & + vtmp(1,1:npl), vtmp(2,1:npl), vtmp(3,1:npl), & + -dto(1:npl), iflag(1:npl)) + if (any(iflag(1:npl) /= 0)) then + do i = 1, npl + if (iflag(i) /= 0) then + write(*, *) " Planet ", pl%name(i), " is lost!!!!!!!!!!" + write(*, *) GMcb(i), -dto(i) + write(*, *) xtmp(:,i) + write(*, *) vtmp(:,i) + write(*, *) " STOPPING " + call util_exit(FAILURE) + end if + end do + end if + frac = outer_index / dntenc + pl%outer(outer_index)%x(:, :) = pl%outer(outer_index)%x(:, :) + frac * xtmp(:,:) + pl%outer(outer_index)%v(:, :) = pl%outer(outer_index)%v(:, :) + frac * vtmp(:,:) + end do + end select end associate return @@ -453,7 +467,7 @@ subroutine rmvs_peri_tp(tp, pl, t, dt, lfirst, inner_index, ipleP, param) end subroutine rmvs_peri_tp - subroutine rmvs_make_planetocentric(pl, cb, tp, param) + subroutine rmvs_make_planetocentric(system, param) !! author: David A. Minton !! !! When encounters are detected, this method will call the interpolation methods for the planets and @@ -462,112 +476,135 @@ subroutine rmvs_make_planetocentric(pl, cb, tp, param) !! implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body particle type - class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object + class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters + ! Internals integer(I4B) :: i, j, inner_index, ipc2hc logical, dimension(:), allocatable :: encmask - associate(npl => pl%nbody, ntp => tp%nbody, GMpl => pl%Gmass, nenc => pl%nenc) - do i = 1, npl - if (nenc(i) == 0) cycle - ! There are inner encounters with this planet - if (allocated(encmask)) deallocate(encmask) - allocate(encmask(ntp)) - encmask(:) = tp%plencP(:) == i - - ! Create encountering test particle structure - allocate(rmvs_tp :: pl%planetocentric(i)%tp) - associate(cbenci => pl%planetocentric(i)%cb, & - plenci => pl%planetocentric(i)%pl, & - tpenci => pl%planetocentric(i)%tp) - tpenci%lplanetocentric = .true. - call tpenci%setup(nenc(i)) - tpenci%cb_heliocentric = cb - tpenci%ipleP = i - tpenci%status(:) = ACTIVE - tpenci%name(:) = pack(tp%name(:), encmask(:)) - ! Grab all the encountering test particles and convert them to a planetocentric frame - do j = 1, NDIM - tpenci%xheliocentric(j, :) = pack(tp%xh(j,:), encmask(:)) - tpenci%xh(j, :) = tpenci%xheliocentric(j, :) - pl%inner(0)%x(j, i) - tpenci%vh(j, :) = pack(tp%vh(j,:), encmask(:)) - pl%inner(0)%v(j, i) - end do - ! Make sure that the test particles get the planetocentric value of mu - allocate(cbenci%inner(0:NTPHENC)) - do inner_index = 0, NTPHENC - allocate(plenci%inner(inner_index)%x, mold=pl%inner(inner_index)%x) - allocate(plenci%inner(inner_index)%v, mold=pl%inner(inner_index)%x) - allocate(plenci%inner(inner_index)%aobl, mold=pl%inner(inner_index)%aobl) - allocate(cbenci%inner(inner_index)%x(NDIM,1)) - allocate(cbenci%inner(inner_index)%v(NDIM,1)) - allocate(cbenci%inner(inner_index)%aobl(NDIM,1)) - cbenci%inner(inner_index)%x(:,1) = pl%inner(inner_index)%x(:, i) - cbenci%inner(inner_index)%v(:,1) = pl%inner(inner_index)%v(:, i) - cbenci%inner(inner_index)%aobl(:,1) = pl%inner(inner_index)%aobl(:, i) - - plenci%inner(inner_index)%x(:,1) = -cbenci%inner(inner_index)%x(:,1) - plenci%inner(inner_index)%v(:,1) = -cbenci%inner(inner_index)%v(:,1) - do j = 2, npl - ipc2hc = plenci%plind(j) - plenci%inner(inner_index)%x(:,j) = pl%inner(inner_index)%x(:, ipc2hc) - cbenci%inner(inner_index)%x(:,1) - plenci%inner(inner_index)%v(:,j) = pl%inner(inner_index)%v(:, ipc2hc) - cbenci%inner(inner_index)%v(:,1) + select type(cb => system%cb) + class is (rmvs_cb) + select type(pl => system%pl) + class is (rmvs_pl) + select type (tp => system%tp) + class is (rmvs_tp) + associate (npl => pl%nbody, ntp => tp%nbody) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + ! There are inner encounters with this planet + if (allocated(encmask)) deallocate(encmask) + allocate(encmask(ntp)) + encmask(:) = tp%plencP(:) == i + allocate(rmvs_tp :: pl%planetocentric(i)%tp) + ! Create encountering test particle structure + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + select type(tpenci => pl%planetocentric(i)%tp) + class is (rmvs_tp) + tpenci%lplanetocentric = .true. + call tpenci%setup(pl%nenc(i)) + tpenci%cb_heliocentric = cb + tpenci%ipleP = i + tpenci%status(:) = ACTIVE + tpenci%name(:) = pack(tp%name(:), encmask(:)) + ! Grab all the encountering test particles and convert them to a planetocentric frame + do j = 1, NDIM + tpenci%xheliocentric(j, :) = pack(tp%xh(j,:), encmask(:)) + tpenci%xh(j, :) = tpenci%xheliocentric(j, :) - pl%inner(0)%x(j, i) + tpenci%vh(j, :) = pack(tp%vh(j,:), encmask(:)) - pl%inner(0)%v(j, i) + end do + ! Make sure that the test particles get the planetocentric value of mu + allocate(cbenci%inner(0:NTPHENC)) + do inner_index = 0, NTPHENC + allocate(plenci%inner(inner_index)%x, mold=pl%inner(inner_index)%x) + allocate(plenci%inner(inner_index)%v, mold=pl%inner(inner_index)%x) + allocate(plenci%inner(inner_index)%aobl, mold=pl%inner(inner_index)%aobl) + allocate(cbenci%inner(inner_index)%x(NDIM,1)) + allocate(cbenci%inner(inner_index)%v(NDIM,1)) + allocate(cbenci%inner(inner_index)%aobl(NDIM,1)) + cbenci%inner(inner_index)%x(:,1) = pl%inner(inner_index)%x(:, i) + cbenci%inner(inner_index)%v(:,1) = pl%inner(inner_index)%v(:, i) + cbenci%inner(inner_index)%aobl(:,1) = pl%inner(inner_index)%aobl(:, i) + plenci%inner(inner_index)%x(:,1) = -cbenci%inner(inner_index)%x(:,1) + plenci%inner(inner_index)%v(:,1) = -cbenci%inner(inner_index)%v(:,1) + do j = 2, npl + ipc2hc = plenci%plind(j) + plenci%inner(inner_index)%x(:,j) = pl%inner(inner_index)%x(:, ipc2hc) - cbenci%inner(inner_index)%x(:,1) + plenci%inner(inner_index)%v(:,j) = pl%inner(inner_index)%v(:, ipc2hc) - cbenci%inner(inner_index)%v(:,1) + end do + end do + call tpenci%set_mu(cbenci) + end select + end select + end select end do - end do - call tpenci%set_mu(cbenci) - end associate - end do - end associate + end associate + end select + end select + end select return - end subroutine rmvs_make_planetocentric + end subroutine rmvs_make_planetocentric - subroutine rmvs_end_planetocentric(pl, cb, tp) + subroutine rmvs_end_planetocentric(system) !! author: David A. Minton !! !! Deallocates all of the encountering particle data structures for next time !! implicit none ! Arguments - class(rmvs_pl), intent(inout) :: pl !! RMVS test particle object - class(rmvs_cb), intent(inout) :: cb !! RMVS central body object - class(rmvs_tp), intent(inout) :: tp !! RMVS test particle object + class(rmvs_nbody_system), intent(inout) :: system !! RMVS nbody system object ! Internals integer(I4B) :: i, j, inner_index integer(I4B), dimension(:), allocatable :: tpind logical, dimension(:), allocatable :: encmask - associate(nenc => pl%nenc, npl => pl%nbody, ntp => tp%nbody) - do i = 1, npl - if (nenc(i) == 0) cycle - associate(cbenci => pl%planetocentric(i)%cb, & - tpenci => pl%planetocentric(i)%tp, & - plenci => pl%planetocentric(i)%pl) - if (allocated(tpind)) deallocate(tpind) - allocate(tpind(nenc(i))) - ! Index array of encountering test particles - if (allocated(encmask)) deallocate(encmask) - allocate(encmask(ntp)) - encmask(:) = tp%plencP(:) == i - tpind(:) = pack([(j,j=1,ntp)], encmask(:)) - - ! Copy the results of the integration back over and shift back to heliocentric reference - tp%status(tpind(1:nenc(i))) = tpenci%status(1:nenc(i)) - do j = 1, NDIM - tp%xh(j, tpind(1:nenc(i))) = tpenci%xh(j,1:nenc(i)) + pl%inner(NTPHENC)%x(j, i) - tp%vh(j, tpind(1:nenc(i))) = tpenci%vh(j,1:nenc(i)) + pl%inner(NTPHENC)%v(j, i) - end do - deallocate(pl%planetocentric(i)%tp) - deallocate(cbenci%inner) - do inner_index = 0, NTPHENC - deallocate(plenci%inner(inner_index)%x) - deallocate(plenci%inner(inner_index)%v) - deallocate(plenci%inner(inner_index)%aobl) - end do - end associate - end do - end associate + select type(cb => system%cb) + class is (rmvs_cb) + select type(pl => system%pl) + class is (rmvs_pl) + select type (tp => system%tp) + class is (rmvs_tp) + associate (npl => pl%nbody, ntp => tp%nbody) + do i = 1, npl + if (pl%nenc(i) == 0) cycle + select type(cbenci => pl%planetocentric(i)%cb) + class is (rmvs_cb) + select type(plenci => pl%planetocentric(i)%pl) + class is (rmvs_pl) + select type(tpenci => pl%planetocentric(i)%tp) + class is (rmvs_tp) + if (allocated(tpind)) deallocate(tpind) + allocate(tpind(pl%nenc(i))) + ! Index array of encountering test particles + if (allocated(encmask)) deallocate(encmask) + allocate(encmask(ntp)) + encmask(:) = tp%plencP(:) == i + tpind(:) = pack([(j,j=1,ntp)], encmask(:)) + + ! Copy the results of the integration back over and shift back to heliocentric reference + tp%status(tpind(1:pl%nenc(i))) = tpenci%status(1:pl%nenc(i)) + do j = 1, NDIM + tp%xh(j, tpind(1:pl%nenc(i))) = tpenci%xh(j,1:pl%nenc(i)) + pl%inner(NTPHENC)%x(j, i) + tp%vh(j, tpind(1:pl%nenc(i))) = tpenci%vh(j,1:pl%nenc(i)) + pl%inner(NTPHENC)%v(j, i) + end do + deallocate(pl%planetocentric(i)%tp) + deallocate(cbenci%inner) + do inner_index = 0, NTPHENC + deallocate(plenci%inner(inner_index)%x) + deallocate(plenci%inner(inner_index)%v) + deallocate(plenci%inner(inner_index)%aobl) + end do + end select + end select + end select + end do + end associate + end select + end select + end select return end subroutine rmvs_end_planetocentric diff --git a/src/setup/setup.f90 b/src/setup/setup.f90 index 55140ac88..03fd6f0f0 100644 --- a/src/setup/setup.f90 +++ b/src/setup/setup.f90 @@ -9,7 +9,7 @@ module subroutine setup_construct_system(system, param) implicit none ! Arguments class(swiftest_nbody_system), allocatable, intent(inout) :: system !! Swiftest system object - type(swiftest_parameters), intent(in) :: param !! Swiftest parameters + type(swiftest_parameters), intent(in) :: param !! Swiftest parameters select case(param%integrator) case (BS) diff --git a/src/user/user_getacch.f90 b/src/user/user_getacch.f90 index e3733303a..da3d00578 100644 --- a/src/user/user_getacch.f90 +++ b/src/user/user_getacch.f90 @@ -1,7 +1,7 @@ submodule(swiftest_classes) s_user_getacch use swiftest contains - module subroutine user_getacch_body(self, cb, param, t) + module subroutine user_getacch_body(self, system, param, t) !! author: David A. Minton !! !! Add user-supplied heliocentric accelerations to planets @@ -9,10 +9,10 @@ module subroutine user_getacch_body(self, cb, param, t) !! Adapted from David E. Kaufmann's Swifter routine whm_user_getacch.f90 implicit none ! Arguments - class(swiftest_body), intent(inout) :: self !! Swiftest massive body particle data structure - class(swiftest_cb), intent(inout) :: cb !! Swiftest central body particle data structuree - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of user parameters - real(DP), intent(in) :: t !! Current time + 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 + real(DP), intent(in) :: t !! Current time return end subroutine user_getacch_body diff --git a/src/whm/whm_drift.f90 b/src/whm/whm_drift.f90 index c18648364..0ac170991 100644 --- a/src/whm/whm_drift.f90 +++ b/src/whm/whm_drift.f90 @@ -10,21 +10,17 @@ module subroutine whm_drift_pl(self, system, param, dt) !! Adapted from David E. Kaufmann's Swifter routine whm_drift.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(whm_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 + 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 + 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(npl => self%nbody, & - xj => self%xj, & - vj => self%vj, & - status => self%status,& - mu => self%muj) + associate(pl => self, npl => self%nbody) if (npl == 0) return @@ -34,24 +30,24 @@ module subroutine whm_drift_pl(self, system, param, dt) if (param%lgr) then do i = 1,npl - rmag = norm2(xj(:, i)) - vmag2 = dot_product(vj(:, i), vj(:, i)) - energy = 0.5_DP * vmag2 - mu(i) / rmag + 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 end if - call drift_one(mu(1:npl), xj(1,1:npl), xj(2,1:npl), xj(3,1:npl), & - vj(1,1:npl), vj(2,1:npl), vj(3,1:npl), & + 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)) if (any(iflag(1:npl) /= 0)) then do i = 1, npl if (iflag(i) /= 0) then write(*, *) " Planet ", self%name(i), " is lost!!!!!!!!!!" - write(*, *) xj(:,i) - write(*, *) vj(:,i) + write(*, *) pl%xj(:,i) + write(*, *) pl%vj(:,i) write(*, *) " stopping " call util_exit(FAILURE) end if @@ -73,44 +69,38 @@ module subroutine whm_drift_tp(self, system, param, dt) !! 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(whm_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 + 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(ntp => self%nbody, & - xh => self%xh, & - vh => self%vh, & - status => self%status,& - mu => self%mu, GMcb => system%cb%Gmass) - + 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(xh(:, i)) - vmag2 = dot_product(vh(:, i), vh(:, i)) - energy = 0.5_DP * vmag2 - GMcb / rmag + 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, status(i) == ACTIVE) - call drift_one(mu(i), xh(1,i), xh(2,i), xh(3,i), & - vh(1,i), vh(2,i), vh(3,i), & - dtp(i), iflag(i)) + 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) status(1:ntp) = DISCARDED_DRIFTERR + where(iflag(1:ntp) /= 0) tp%status(1:ntp) = DISCARDED_DRIFTERR do i = 1, ntp if (iflag(i) /= 0) write(*, *) "Particle ", self%name(i), " lost due to error in Danby drift" end do @@ -118,6 +108,5 @@ module subroutine whm_drift_tp(self, system, param, dt) end associate return - end subroutine whm_drift_tp end submodule whm_drift diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 53cd9b97a..d2e1bdc3e 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -10,15 +10,15 @@ module subroutine whm_getacch_pl(self, system, param, t) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch.f90 implicit none ! Arguments - class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure - class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time + 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 + real(DP), intent(in) :: t !! Current time ! Internals - integer(I4B) :: i - real(DP), dimension(NDIM) :: ah0 + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah0 - associate(pl => self, cb => system%cb, npl => self%nbody) + associate(pl => self, npl => self%nbody) if (npl == 0) return call pl%set_ir3() @@ -26,19 +26,23 @@ module subroutine whm_getacch_pl(self, system, param, t) do i = 1, npl pl%ah(:, i) = ah0(:) end do - call whm_getacch_ah1(cb, pl) - call whm_getacch_ah2(cb, pl) - call whm_getacch_ah3(pl) + select type(cb => system%cb) + class is (whm_cb) + + call whm_getacch_ah1(cb, pl) + call whm_getacch_ah2(cb, pl) + call whm_getacch_ah3(pl) - if (param%loblatecb) call pl%obl_acc(cb) - if (param%lextra_force) call pl%user_getacch(cb, param, t) - if (param%lgr) call pl%gr_getacch(param) + if (param%loblatecb) call pl%obl_acc(cb) + if (param%lextra_force) call pl%user_getacch(system, param, t) + if (param%lgr) call pl%gr_getacch(param) + end select end associate return end subroutine whm_getacch_pl - module subroutine whm_getacch_tp(self, system, param, t, xh) + module subroutine whm_getacch_tp(self, system, param, t, xhp) !! author: David A. Minton !! !! Compute heliocentric accelerations of test particles @@ -47,39 +51,38 @@ module subroutine whm_getacch_tp(self, system, param, t, xh) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_tp.f90 implicit none ! Arguments - class(whm_tp), intent(inout) :: self !! WHM test particle data structure - class(whm_nbody_system), intent(inout) :: system !! Swiftest central body particle data structure - class(whm_pl), intent(inout) :: pl !! Generic Swiftest massive body particle data structure. - class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters of - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xh !! Heliocentric positions of planets + 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 + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets at the current substep ! Internals - integer(I4B) :: i - real(DP), dimension(NDIM) :: ah0 + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah0 - associate(tp => self, ntp => self%nbody, pl => system%pl, npl => system%pl%nbody) + associate(tp => self, ntp => self%nbody, pl => system%pl, cb => system%cb, npl => system%pl%nbody) if (ntp == 0 .or. npl == 0) return - ah0 = whm_getacch_ah0(pl%Gmass(:), xh(:,:), npl) + ah0 = whm_getacch_ah0(pl%Gmass(:), xhp(:,:), npl) do i = 1, ntp tp%ah(:, i) = ah0(:) end do - call whm_getacch_ah3_tp(system, xh) + call whm_getacch_ah3_tp(system) if (param%loblatecb) call tp%obl_acc(cb) - if (param%lextra_force) call tp%user_getacch(cb, param, t) + if (param%lextra_force) call tp%user_getacch(system, param, t) if (param%lgr) call tp%gr_getacch(param) end associate return end subroutine whm_getacch_tp - function whm_getacch_ah0(mu, xh, n) result(ah0) + function whm_getacch_ah0(mu, xhp, n) result(ah0) !! author: David A. Minton !! !! Compute zeroth term heliocentric accelerations of planets implicit none ! Arguments real(DP), dimension(:), intent(in) :: mu - real(DP), dimension(:,:), intent(in) :: xh + real(DP), dimension(:,:), intent(in) :: xhp integer(I4B), intent(in) :: n ! Result real(DP), dimension(NDIM) :: ah0 @@ -89,10 +92,10 @@ function whm_getacch_ah0(mu, xh, n) result(ah0) ah0(:) = 0.0_DP do i = 1, n - r2 = dot_product(xh(:, i), xh(:, i)) + r2 = dot_product(xhp(:, i), xhp(:, i)) ir3h = 1.0_DP / (r2 * sqrt(r2)) fac = mu(i) * ir3h - ah0(:) = ah0(:) - fac * xh(:, i) + ah0(:) = ah0(:) - fac * xhp(:, i) end do return @@ -107,17 +110,17 @@ pure subroutine whm_getacch_ah1(cb, pl) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah1.f90 implicit none ! Arguments - class(swiftest_cb), intent(in) :: cb !! Swiftest central body object - class(whm_pl), intent(inout) :: pl !! WHM massive body object + class(whm_cb), intent(in) :: cb !! WHM central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object ! Internals - integer(I4B) :: i - real(DP), dimension(NDIM) :: ah1h, ah1j + integer(I4B) :: i + real(DP), dimension(NDIM) :: ah1h, ah1j - associate(npl => pl%nbody, msun => cb%Gmass, xh => pl%xh, xj => pl%xj, ir3j => pl%ir3j, ir3h => pl%ir3h ) + associate(npl => pl%nbody) do i = 2, npl - ah1j(:) = xj(:, i) * ir3j(i) - ah1h(:) = xh(:, i) * ir3h(i) - pl%ah(:, i) = pl%ah(:, i) + msun * (ah1j(:) - ah1h(:)) + ah1j(:) = pl%xj(:, i) * pl%ir3j(i) + ah1h(:) = pl%xh(:, i) * pl%ir3h(i) + pl%ah(:, i) = pl%ah(:, i) + cb%Gmass * (ah1j(:) - ah1h(:)) end do end associate @@ -134,21 +137,21 @@ pure subroutine whm_getacch_ah2(cb, pl) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah2.f90 implicit none ! Arguments - class(swiftest_cb), intent(in) :: cb !! Swiftest central body object - class(whm_pl), intent(inout) :: pl !! WHM massive body object + class(whm_cb), intent(in) :: cb !! Swiftest central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object ! Internals - integer(I4B) :: i - real(DP) :: etaj, fac - real(DP), dimension(NDIM) :: ah2, ah2o + integer(I4B) :: i + real(DP) :: etaj, fac + real(DP), dimension(NDIM) :: ah2, ah2o - associate(npl => pl%nbody, Gmsun => cb%Gmass, xh => pl%xh, xj => pl%xj, Gmpl => pl%Gmass, ir3j => pl%ir3j) + associate(npl => pl%nbody, GMcb => cb%Gmass) ah2(:) = 0.0_DP ah2o(:) = 0.0_DP - etaj = Gmsun + etaj = GMcb do i = 2, npl - etaj = etaj + Gmpl(i - 1) - fac = Gmpl(i) * Gmsun * ir3j(i) / etaj - ah2(:) = ah2o + fac * xj(:, i) + etaj = etaj + pl%Gmass(i - 1) + fac = pl%Gmass(i) * GMcb * pl%ir3j(i) / etaj + ah2(:) = ah2o + fac * pl%xj(:, i) pl%ah(:,i) = pl%ah(:, i) + ah2(:) ah2o(:) = ah2(:) end do @@ -172,17 +175,17 @@ pure subroutine whm_getacch_ah3(pl) real(DP), dimension(NDIM) :: dx real(DP), dimension(:,:), allocatable :: ah3 - associate(npl => pl%nbody, xh => pl%xh, Gmpl => pl%Gmass) + associate(npl => pl%nbody) allocate(ah3, mold=pl%ah) ah3(:, 1:npl) = 0.0_DP do i = 1, npl - 1 do j = i + 1, npl - dx(:) = xh(:, j) - xh(:, i) + dx(:) = pl%xh(:, j) - pl%xh(:, i) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - faci = Gmpl(i) * irij3 - facj = Gmpl(j) * irij3 + faci = pl%Gmass(i) * irij3 + facj = pl%Gmass(j) * irij3 ah3(:, i) = ah3(:, i) + facj * dx(:) ah3(:, j) = ah3(:, j) - faci * dx(:) end do @@ -196,7 +199,7 @@ pure subroutine whm_getacch_ah3(pl) return end subroutine whm_getacch_ah3 - pure subroutine whm_getacch_ah3_tp(system, xh) + pure subroutine whm_getacch_ah3_tp(system) !! author: David A. Minton !! !! Compute direct cross (third) term heliocentric accelerations of test particles @@ -205,25 +208,24 @@ pure subroutine whm_getacch_ah3_tp(system, xh) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 implicit none ! Arguments - class(whm_nbody_system) :: system !! WHM nbody system object - real(DP), dimension(:,:), intent(in) :: xh !! Position vector of massive bodies at required point in step + class(swiftest_nbody_system), intent(inout) :: system !! WHM nbody system object ! Internals - integer(I4B) :: i, j - real(DP) :: rji2, irij3, fac - real(DP), dimension(NDIM) :: dx, acc + integer(I4B) :: i, j + real(DP) :: rji2, irij3, fac + real(DP), dimension(NDIM) :: dx, acc - associate(ntp => system%tp%nbody, npl => system%pl%nbody, msun => system%cb%Gmass, GMpl => system%pl%Gmass, xht => system%tp%xh, aht => system%tp%ah) + 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(:) = xht(:, i) - xh(:, j) + dx(:) = tp%xh(:, i) - pl%xh(:, j) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - fac = GMpl(j) * irij3 + fac = pl%Gmass(j) * irij3 acc(:) = acc(:) - fac * dx(:) end do - aht(:, i) = aht(:, i) + acc(:) + tp%ah(:, i) = tp%ah(:, i) + acc(:) end do end associate return diff --git a/src/whm/whm_setup.f90 b/src/whm/whm_setup.f90 index cdec4e1fb..e0812d00d 100644 --- a/src/whm/whm_setup.f90 +++ b/src/whm/whm_setup.f90 @@ -133,7 +133,7 @@ module subroutine whm_setup_set_beg_end(self, xbeg, xend, vbeg) !! Sets one or more of the values of xbeg and xend implicit none ! Arguments - class(whm_tp), intent(inout) :: self !! Swiftest test particle object + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object real(DP), dimension(:,:), intent(in), optional :: xbeg, xend real(DP), dimension(:,:), intent(in), optional :: vbeg ! vbeg is an unused variable to keep this method forward compatible with RMVS diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index c3c7a098f..b37d06bbe 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -2,7 +2,7 @@ use swiftest contains - module subroutine whm_step_system(self, param, dt) + module subroutine whm_step_system(self, param, t, dt) !! author: David A. Minton !! !! Step massive bodies and and active test particles ahead in heliocentric coordinates @@ -11,35 +11,24 @@ module subroutine whm_step_system(self, param, dt) !! Adapted from David E. Kaufmann's Swifter routine whm_step.f90 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 - integer(I4B), intent(in) :: dt !! Current stepsize + class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters of on parameters + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize - select type (system => self) - class is (whm_nbody_system) - select type(cb => self%cb) - class is (whm_cb) - select type(pl => self%pl) - class is (whm_pl) - select type(tp => self%tp) - class is (whm_tp) - associate(ntp => tp%nbody, npl => pl%nbody, t => param%t, dt => param%dt) + associate(system => self, cb => self%cb, pl => self%pl, tp => self%tp, ntp => self%tp%nbody, npl => self%pl%nbody) call pl%set_rhill(cb) - call tp%set_beg_end(xbeg = pl%xh) - call pl%step(system, param, dt) + call self%set_beg_end(xbeg = pl%xh) + call pl%step(system, param, t, dt) if (ntp > 0) then - call tp%set_beg_end(xend = pl%xh) - call tp%step(system, param, dt) + call self%set_beg_end(xend = pl%xh) + call tp%step(system, param, t, dt) end if end associate - end select - end select - end select - end select return end subroutine whm_step_system - module subroutine whm_step_pl(self, system, param, dt) + module subroutine whm_step_pl(self, system, param, t, dt) !! author: David A. Minton !! !! Step planets ahead using kick-drift-kick algorithm @@ -52,23 +41,23 @@ module subroutine whm_step_pl(self, system, param, dt) class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - integer(I4B), intent(in) :: dt !! Current stepsize + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize ! Internals - real(DP) :: dth + real(DP) :: dth - associate(cb => system%cb, t => param%t) + associate(pl => self, cb => system%cb) dth = 0.5_DP * dt if (pl%lfirst) then call pl%h2j(cb) call pl%getacch(system, param, t) pl%lfirst = .false. end if - call pl%kickvh(dth) call pl%vh2vj(cb) !If GR enabled, calculate the p4 term before and after each drift if (param%lgr) call pl%gr_p4(param, dth) - call pl%drift(cb, param, dt) + call pl%drift(system, param, dt) if (param%lgr) call pl%gr_p4(param, dth) call pl%j2h(cb) call pl%getacch(system, param, t + dt) @@ -77,7 +66,7 @@ module subroutine whm_step_pl(self, system, param, dt) return end subroutine whm_step_pl - module subroutine whm_step_tp(self, system, param, dt) + module subroutine whm_step_tp(self, system, param, t, dt) !! author: David A. Minton !! !! Step active test particles ahead using kick-drift-kick algorithm @@ -89,24 +78,28 @@ module subroutine whm_step_tp(self, system, param, dt) class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: system !! Swiftest system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters - integer(I4B), intent(in) :: dt !! Current stepsize + real(DP), intent(in) :: t !! Current simulation time + real(DP), intent(in) :: dt !! Current stepsize ! Internals - real(DP) :: dth + real(DP) :: dth - associate(cb => system%cb, pl => system%pl, t => param%t, xbeg => self%xbeg, xend => self%xend) - dth = 0.5_DP * dt - if (tp%lfirst) then - call tp%getacch(system, param, t, xbeg) - tp%lfirst = .false. - end if - call tp%kickvh(dth) - !If GR enabled, calculate the p4 term before and after each drift - if (param%lgr) call tp%gr_p4(param, dth) - call tp%drift(cb, param, dt) - if (param%lgr) call tp%gr_p4(param, dth) - call tp%getacch(system, param, t + dt, xend) - call tp%kickvh(dth) - end associate + select type(system) + class is (whm_nbody_system) + associate(tp => self, cb => system%cb, pl => system%pl) + dth = 0.5_DP * dt + if (tp%lfirst) then + call tp%getacch(system, param, t, system%xbeg) + tp%lfirst = .false. + end if + call tp%kickvh(dth) + !If GR enabled, calculate the p4 term before and after each drift + if (param%lgr) call tp%gr_p4(param, dth) + call tp%drift(system, param, dt) + if (param%lgr) call tp%gr_p4(param, dth) + call tp%getacch(system, param, t + dt, system%xend) + call tp%kickvh(dth) + end associate + end select return end subroutine whm_step_tp From f8c3decaac979afa9da0b4e38e74b9816e24f22d Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 6 Jul 2021 09:17:17 -0400 Subject: [PATCH 08/12] Finished major restructuring of data types. It now compiles. --- Makefile | 18 ++++-- src/{driftkick => drift}/drift.f90 | 0 src/helio/helio_getacch.f90 | 44 +++++++-------- src/helio/helio_step.f90 | 87 +++++++++++++++-------------- src/io/io.f90 | 8 +-- src/{driftkick => kick}/kick.f90 | 0 src/modules/swiftest_classes.f90 | 88 ++++++++++++++++++------------ src/obl/obl.f90 | 35 ++++++------ src/whm/whm_getacch.f90 | 39 ++++++------- src/whm/whm_step.f90 | 6 +- 10 files changed, 171 insertions(+), 154 deletions(-) rename src/{driftkick => drift}/drift.f90 (100%) rename src/{driftkick => kick}/kick.f90 (100%) diff --git a/Makefile b/Makefile index 9bda6503a..dfc6fd5c0 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ lib: ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir - cd $(SWIFTEST_HOME)/src/driftkick; \ + cd $(SWIFTEST_HOME)/src/drift; \ rm -f Makefile.Defines Makefile; \ ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ ln -s $(SWIFTEST_HOME)/Makefile .; \ @@ -106,6 +106,11 @@ lib: ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ ln -s $(SWIFTEST_HOME)/Makefile .; \ make libdir + cd $(SWIFTEST_HOME)/src/kick; \ + rm -f Makefile.Defines Makefile; \ + ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ + ln -s $(SWIFTEST_HOME)/Makefile .; \ + make libdir cd $(SWIFTEST_HOME)/src/obl; \ rm -f Makefile.Defines Makefile; \ ln -s $(SWIFTEST_HOME)/Makefile.Defines .; \ @@ -179,20 +184,21 @@ bin: *.f90 clean: cd $(SWIFTEST_HOME)/src/modules; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/discard; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTEST_HOME)/src/driftkick; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/drift; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/eucl; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/gr; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/helio; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/io; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/kick; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/main; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/obl; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/operators; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/orbel; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/rmvs; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/setup; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTEST_HOME)/src/util; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/user; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTEST_HOME)/src/main; rm -f Makefile.Defines Makefile *.gc* + cd $(SWIFTEST_HOME)/src/util; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/src/whm; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTEST_HOME)/src/rmvs; rm -f Makefile.Defines Makefile *.gc* - cd $(SWIFTEST_HOME)/src/helio; rm -f Makefile.Defines Makefile *.gc* cd $(SWIFTEST_HOME)/bin; rm -f swiftest_* cd $(SWIFTEST_HOME)/bin; rm -f tool_* cd $(SWIFTEST_HOME)/lib; rm -f lib* diff --git a/src/driftkick/drift.f90 b/src/drift/drift.f90 similarity index 100% rename from src/driftkick/drift.f90 rename to src/drift/drift.f90 diff --git a/src/helio/helio_getacch.f90 b/src/helio/helio_getacch.f90 index 806047cc3..af6ab9e4d 100644 --- a/src/helio/helio_getacch.f90 +++ b/src/helio/helio_getacch.f90 @@ -21,16 +21,13 @@ module subroutine helio_getacch_pl(self, system, param, t) real(DP), dimension(:), allocatable, save :: irh real(DP), dimension(:, :), allocatable, save :: xh_loc, aobl - associate(pl => self, npl => self%nbody) - !if (lflag) then - pl%ahi(:,2:npl) = 0.0_DP - call helio_getacch_int_pl(pl, t) - !end if - !if (param%loblatecb) call self%obl_acc(cb) TODO: Fix this - !else + associate(cb => system%cb, pl => self, npl => self%nbody) + pl%ahi(:,2:npl) = 0.0_DP + call helio_getacch_int_pl(pl, t) pl%ah(:,:) = pl%ahi(:,:) - !end if + if (param%loblatecb) call pl%obl_acc(cb) if (param%lextra_force) call pl%user_getacch(system, param, t) + if (param%lgr) call pl%gr_getacch(param) end associate return @@ -56,18 +53,15 @@ module subroutine helio_getacch_tp(self, system, param, t, xhp) real(DP) :: r2, mu real(DP), dimension(:), allocatable, save :: irh, irht - ! executable code - associate(tp => self, ntp => self%nbody, npl => system%pl%nbody) + associate(tp => self, ntp => self%nbody, cb => system%cb, pl => system%pl, npl => system%pl%nbody) select type(pl => system%pl) - class is (rmvs_pl) - !if (lflag) then - self%ahi(:,:) = 0.0_DP - call helio_getacch_int_tp(tp, pl, t, xhp) - !end if - !if (param%loblatecb) call self%obl_acc(cb) TODO: Fix this + class is (helio_pl) + self%ahi(:,:) = 0.0_DP + call helio_getacch_int_tp(tp, pl, t, xhp) tp%ah(:,:) = tp%ahi(:,:) + if (param%loblatecb) call tp%obl_acc(cb) if (param%lextra_force) call tp%user_getacch(system, param, t) - if (param%lgr) call tp%gr_getacch(system, param) + if (param%lgr) call tp%gr_getacch(param) end select end associate return @@ -95,10 +89,10 @@ subroutine helio_getacch_int_pl(pl, t) dx(:) = pl%xh(:,j) - pl%xh(:,i) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) - faci = self%Gmass(i) * irij3 - facj = self%Gmass(j) * irij3 - self%ahi(:,i) = self%ahi(:,i) + facj * dx(:) - self%ahi(:,i) = self%ahi(:,j) - faci * dx(:) + faci = pl%Gmass(i) * irij3 + facj = pl%Gmass(j) * irij3 + pl%ahi(:,i) = pl%ahi(:,i) + facj * dx(:) + pl%ahi(:,i) = pl%ahi(:,j) - faci * dx(:) end do end do end associate @@ -115,10 +109,10 @@ subroutine helio_getacch_int_tp(tp, pl, t, xhp) !! Adapted from Hal Levison's Swift routine getacch_ah3_tp.f implicit none ! Arguments - class(helio_tp), intent(inout) :: tp !! Helio test particle data structure - class(helio_pl), intent(inout) :: pl !! Helio massive body particle data structure - real(DP), intent(in) :: t !! Current time - real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets + class(helio_tp), intent(inout) :: tp !! Helio test particle data structure + class(swiftest_pl), intent(inout) :: pl !! Helio massive body particle data structure + real(DP), intent(in) :: t !! Current time + real(DP), dimension(:,:), intent(in) :: xhp !! Heliocentric positions of planets ! Internals integer(I4B) :: i, j real(DP) :: r2, fac diff --git a/src/helio/helio_step.f90 b/src/helio/helio_step.f90 index 480de821d..53052fc9e 100644 --- a/src/helio/helio_step.f90 +++ b/src/helio/helio_step.f90 @@ -17,22 +17,22 @@ module subroutine helio_step_system(self, param, t, dt) select type(system => self) class is (helio_nbody_system) - select type(cb => self%cb) - class is (helio_cb) - select type(pl => self%pl) - class is (helio_pl) - select type(tp => self%tp) - class is (helio_tp) - call pl%set_rhill(cb) - call tp%set_beg_end(xbeg = pl%xh) - call pl%step(system, param, t, dt) - if (ntp > 0) then - call tp%set_beg_end(xend = pl%xh) - call tp%step(system, param, t, dt) - end if - end select - end select - end select + select type(cb => self%cb) + class is (helio_cb) + select type(pl => self%pl) + class is (helio_pl) + select type(tp => self%tp) + class is (helio_tp) + call pl%set_rhill(cb) + call system%set_beg_end(xbeg = pl%xh) + call pl%step(system, param, t, dt) + if (tp%nbody > 0) then + call system%set_beg_end(xend = pl%xh) + call tp%step(system, param, t, dt) + end if + end select + end select + end select end select return end subroutine helio_step_system @@ -57,21 +57,21 @@ module subroutine helio_step_pl(self, system, param, t, dt) real(DP), dimension(NDIM) :: ptbeg, ptend !! TODO: Incorporate these into the tp structure logical, save :: lfirst = .true. - associate(cb => system%cb) + associate(pl => self, cb => system%cb) dth = 0.5_DP * dt if (lfirst) then - call self%vh2vb(cb) + call pl%vh2vb(cb) lfirst = .false. end if - call self%lindrift(cb, dth, ptbeg) - call self%getacch(system, param, t) - call self%kickvb(dth) + call pl%lindrift(cb, dth, ptbeg) + call pl%getacch(system, param, t) + call pl%kickvb(dth) - call self%drift(system, param, dt) - call self%getacch(system, param, t + dt) - call self%kickvb(dth) - call self%lindrift(cb, dth, ptend) - call self%vb2vh(cb) + call pl%drift(system, param, dt) + call pl%getacch(system, param, t + dt) + call pl%kickvb(dth) + call pl%lindrift(cb, dth, ptend) + call pl%vb2vh(cb) end associate return @@ -79,6 +79,7 @@ module subroutine helio_step_pl(self, system, param, t, dt) end subroutine helio_step_pl module subroutine helio_step_tp(self, system, param, t, dt) + !! author: David A. Minton !! !! Step active test particles ahead using Democratic Heliocentric method @@ -96,22 +97,24 @@ module subroutine helio_step_tp(self, system, param, t, dt) logical, save :: lfirst = .true. !! Flag to indicate that this is the first call real(DP) :: dth !! Half step size - ! executable code - associate(cb => system%cb, pl => system%pl) - dth = 0.5_DP * dt - if (lfirst) then - call self%vh2vb(vbcb = -self%ptbeg) - lfirst = .false. - end if - call self%lindrift(dth, self%ptbeg) - call self%getacch(system, param, t, self%xbeg) - call self%kickvb(dth) - call self%drift(system, param, dt) - call self%getacch(system, param, t + dt, self%xend) - call self%kickvb(dth) - call self%lindrift(dth, self%ptend) - call self%vb2vh(vbcb = -self%ptend) - end associate + select type(system) + class is (helio_nbody_system) + associate(tp => self, cb => system%cb, pl => system%pl, xbeg => system%xbeg, xend => system%xend) + dth = 0.5_DP * dt + if (lfirst) then + call tp%vh2vb(vbcb = -tp%ptbeg) + lfirst = .false. + end if + call tp%lindrift(dth, tp%ptbeg) + call tp%getacch(system, param, t, xbeg) + call tp%kickvb(dth) + call tp%drift(system, param, dt) + call tp%getacch(system, param, t + dt, xend) + call tp%kickvb(dth) + call tp%lindrift(dth, tp%ptend) + call tp%vb2vh(vbcb = -tp%ptend) + end associate + end select return diff --git a/src/io/io.f90 b/src/io/io.f90 index 629a4952f..c1774f7ca 100644 --- a/src/io/io.f90 +++ b/src/io/io.f90 @@ -517,13 +517,13 @@ end subroutine io_dump_system module function io_get_args(integrator, param_file_name) result(ierr) !! author: David A. Minton !! - !! Reads in the name of the parameters file. + !! Reads in the name of the parameter file from command line arguments. implicit none ! Arguments integer(I4B) :: integrator !! Symbolic code of the requested integrator character(len=:), allocatable :: param_file_name !! Name of the input parameters file ! Result - integer(I4B) :: ierr !! I/O error cod + integer(I4B) :: ierr !! I/O error code ! Internals character(len=STRMAX) :: arg1, arg2 integer :: narg,ierr_arg1, ierr_arg2 @@ -574,7 +574,7 @@ module function io_get_args(integrator, param_file_name) result(ierr) if (ierr /= 0) call util_exit(USAGE) end function io_get_args - module function io_get_token(buffer, ifirst, ilast, ierr) result(token) + function io_get_token(buffer, ifirst, ilast, ierr) result(token) !! author: David A. Minton !! !! Retrieves a character token from an input string. Here a token is defined as any set of contiguous non-blank characters not @@ -1126,7 +1126,7 @@ module subroutine io_write_discard(self, param, discards) end subroutine io_write_discard - subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & xh1, xh2, vh1, vh2, encounter_file, out_type) !! author: David A. Minton !! diff --git a/src/driftkick/kick.f90 b/src/kick/kick.f90 similarity index 100% rename from src/driftkick/kick.f90 rename to src/kick/kick.f90 diff --git a/src/modules/swiftest_classes.f90 b/src/modules/swiftest_classes.f90 index 150408537..f7ed5beb2 100644 --- a/src/modules/swiftest_classes.f90 +++ b/src/modules/swiftest_classes.f90 @@ -5,7 +5,22 @@ module swiftest_classes !! Adapted from David E. Kaufmann's Swifter routine: module_swifter.f90 use swiftest_globals implicit none - public + private + public :: discard_pl_tp, discard_sun_tp, discard_system + public :: drift_one + public :: eucl_dist_index_plpl, eucl_dist_index_pltp, eucl_irij3_plpl + public :: kick_vb_body, kick_vh_body + public :: io_dump_param, io_dump_swiftest, io_dump_system, io_get_args, 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_write_discard, io_write_encounter, io_write_frame_body, io_write_frame_cb, io_write_frame_system + public :: obl_acc_body + public :: orbel_el2xv_vec, orbel_xv2el_vec, orbel_scget, orbel_xv2aeq, orbel_xv2aqt + public :: setup_body, setup_construct_system, setup_pl, setup_set_ir3h, setup_set_msys, setup_set_mu_pl, setup_set_mu_tp, & + setup_set_rhill, setup_tp + public :: user_getacch_body + public :: util_coord_b2h_pl, util_coord_b2h_tp, util_coord_h2b_pl, util_coord_h2b_tp, util_copy_body, util_copy_cb, util_copy_pl, & + util_copy_tp, util_copy_system, util_fill_body, util_fill_pl, util_fill_tp, util_reverse_status, util_spill_body, & + util_spill_pl, util_spill_tp !******************************************************************************************************************************** ! swiftest_parameters class definitions @@ -62,10 +77,11 @@ module swiftest_classes logical :: lyarkovsky = .false. !! Turn on Yarkovsky effect logical :: lyorp = .false. !! Turn on YORP effect contains - procedure :: reader => io_param_reader - procedure :: writer => io_param_writer - procedure :: dump => io_dump_param - procedure :: read_from_file => io_read_param_in + private + procedure, public :: reader => io_param_reader + procedure, public :: writer => io_param_writer + procedure, public :: dump => io_dump_param + procedure, public :: read_from_file => io_read_param_in !TODO: Figure out if user-defined derived-type io can be made to work properly !generic :: read(FORMATTED) => param_reader !generic :: write(FORMATTED) => param_writer @@ -379,28 +395,6 @@ module subroutine kick_vh_body(self, dt) real(DP), intent(in) :: dt !! Stepsize end subroutine kick_vh_body - module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) - implicit none - class(swiftest_parameters), intent(inout) :: self !! Collection of parameters - integer(I4B), intent(in) :: unit !! File unit number - character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. - !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer(I4B), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader - integer(I4B), intent(out) :: iostat !! IO status code - character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 - end subroutine io_param_reader - - module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) - implicit none - class(swiftest_parameters), intent(in) :: self !! Collection of parameters - integer(I4B), intent(in) :: unit !! File unit number - character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. - !! If you do not include a char-literal-constant, the iotype argument contains only DT. - integer(I4B), intent(in) :: v_list(:) !! Not used in this procedure - integer(I4B), intent(out) :: iostat !! IO status code - character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 - end subroutine io_param_writer - module subroutine io_dump_param(self, param_file_name) implicit none class(swiftest_parameters),intent(in) :: self !! Output collection of parameters @@ -425,16 +419,30 @@ module function io_get_args(integrator, param_file_name) result(ierr) implicit none integer(I4B) :: integrator !! Symbolic code of the requested integrator character(len=:), allocatable :: param_file_name !! Name of the input parameters file - integer(I4B) :: ierr !! I/O error code + integer(I4B) :: ierr !! I/O error code end function io_get_args - module function io_get_token(buffer, ifirst, ilast, ierr) result(token) - character(len=*), intent(in) :: buffer !! Input string buffer - integer(I4B), intent(inout) :: ifirst !! Index of the buffer at which to start the search for a token - integer(I4B), intent(out) :: ilast !! Index of the buffer at the end of the returned token - integer(I4B), intent(out) :: ierr !! Error code - character(len=:),allocatable :: token !! Returned token string - end function io_get_token + module subroutine io_param_reader(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(swiftest_parameters), intent(inout) :: self !! Collection of parameters + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! The first element passes the integrator code to the reader + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine io_param_reader + + module subroutine io_param_writer(self, unit, iotype, v_list, iostat, iomsg) + implicit none + class(swiftest_parameters), intent(in) :: self !! Collection of parameters + integer(I4B), intent(in) :: unit !! File unit number + character(len=*), intent(in) :: iotype !! Dummy argument passed to the input/output procedure contains the text from the char-literal-constant, prefixed with DT. + !! If you do not include a char-literal-constant, the iotype argument contains only DT. + integer(I4B), intent(in) :: v_list(:) !! Not used in this procedure + integer(I4B), intent(out) :: iostat !! IO status code + character(len=*), intent(inout) :: iomsg !! Message to pass if iostat /= 0 + end subroutine io_param_writer module subroutine io_read_body_in(self, param) implicit none @@ -494,6 +502,15 @@ module subroutine io_write_discard(self, param, discards) class(swiftest_body), intent(inout) :: discards !! Swiftest discard object end subroutine io_write_discard + module subroutine io_write_encounter(t, name1, name2, mass1, mass2, radius1, radius2, & + xh1, xh2, vh1, vh2, encounter_file, out_type) + implicit none + integer(I4B), intent(in) :: name1, name2 + real(DP), intent(in) :: t, mass1, mass2, radius1, radius2 + real(DP), dimension(:), intent(in) :: xh1, xh2, vh1, vh2 + character(*), intent(in) :: encounter_file, out_type + end subroutine io_write_encounter + module subroutine io_write_frame_body(self, iu, param) implicit none class(swiftest_body), intent(in) :: self !! Swiftest particle object @@ -651,7 +668,6 @@ module subroutine util_copy_cb(self, src, mask) logical, dimension(:), intent(in) :: mask end subroutine util_copy_cb - module subroutine util_copy_pl(self, src, mask) implicit none class(swiftest_pl), intent(inout) :: self diff --git a/src/obl/obl.f90 b/src/obl/obl.f90 index 1a6b77d09..6d1487872 100644 --- a/src/obl/obl.f90 +++ b/src/obl/obl.f90 @@ -1,7 +1,7 @@ submodule (swiftest_classes) s_obl use swiftest contains - module procedure obl_acc_body + module subroutine obl_acc_body(self, cb) !! author: David A. Minton !! !! Compute the barycentric accelerations of bodies due to the oblateness of the central body @@ -10,39 +10,40 @@ !! Adapted from David E. Kaufmann's Swifter routine: obl_acc.f90 and obl_acc_tp.f90 !! Adapted from Hal Levison's Swift routine obl_acc.f and obl_acc_tp.f implicit none + ! Arguments + class(swiftest_body), intent(inout) :: self !! Swiftest generic body object + class(swiftest_cb), intent(inout) :: cb !! Swiftest central body object + ! Internals integer(I4B) :: i real(DP) :: r2, irh, rinv2, t0, t1, t2, t3, fac1, fac2 - associate(n => self%nbody, aobl => self%aobl, xh => self%xh, j2rp2 => cb%j2rp2, j4rp4 => cb%j4rp4, & - msun => cb%Gmass, aoblcb => cb%aobl, ah => self%ah) + associate(n => self%nbody) do i = 1, n - r2 = dot_product(xh(:, i), xh(:, i)) + r2 = dot_product(self%xh(:, i), self%xh(:, i)) irh = 1.0_DP / sqrt(r2) rinv2 = irh**2 - t0 = -msun * rinv2*rinv2*irh - t1 = 1.5_DP * j2rp2 - t2 = xh(3, i) * xh(3, i) * rinv2 - t3 = 1.875_DP * j4rp4 * rinv2 + t0 = -cb%Gmass * rinv2 * rinv2 * irh + t1 = 1.5_DP * cb%j2rp2 + t2 = self%xh(3, i) * self%xh(3, i) * rinv2 + t3 = 1.875_DP * cb%j4rp4 * rinv2 fac1 = t0 * (t1 - t3 - (5.0_DP * t1 - (14.0_DP - 21.0_DP * t2) * t3) * t2) fac2 = 2.0_DP * t0 * (t1 - (2.0_DP - (14.0_DP * t2 / 3.0_DP)) * t3) - aobl(:, i) = fac1 * xh(:, i) - aobl(3, i) = fac2 * xh(3, i) + aobl(3, i) + self%aobl(:, i) = fac1 * self%xh(:, i) + self%aobl(3, i) = fac2 * self%xh(3, i) + self%aobl(3, i) end do select type(self) class is (swiftest_pl) - associate(Mpl => self%Gmass) - do i = 1, NDIM - aoblcb(i) = -sum(Mpl(1:n) * aobl(i, 1:n)) / msun - end do - end associate + do i = 1, NDIM + cb%aobl(i) = -sum(self%Gmass(1:n) * self%aobl(i, 1:n)) / cb%Gmass + end do end select do i = 1, NDIM - ah(i, 1:n) = ah(i, 1:n) + aobl(i, 1:n) - aoblcb(i) + self%ah(i, 1:n) = self%ah(i, 1:n) + self%aobl(i, 1:n) - cb%aobl(i) end do end associate return - end procedure obl_acc_body + end subroutine obl_acc_body end submodule s_obl diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index d2e1bdc3e..7985fac5f 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -18,7 +18,7 @@ module subroutine whm_getacch_pl(self, system, param, t) integer(I4B) :: i real(DP), dimension(NDIM) :: ah0 - associate(pl => self, npl => self%nbody) + associate(cb => system%cb, pl => self, npl => self%nbody) if (npl == 0) return call pl%set_ir3() @@ -26,17 +26,14 @@ module subroutine whm_getacch_pl(self, system, param, t) do i = 1, npl pl%ah(:, i) = ah0(:) end do - select type(cb => system%cb) - class is (whm_cb) - call whm_getacch_ah1(cb, pl) - call whm_getacch_ah2(cb, pl) - call whm_getacch_ah3(pl) + call whm_getacch_ah1(cb, pl) + call whm_getacch_ah2(cb, pl) + call whm_getacch_ah3(pl) - if (param%loblatecb) call pl%obl_acc(cb) - if (param%lextra_force) call pl%user_getacch(system, param, t) - if (param%lgr) call pl%gr_getacch(param) - end select + if (param%loblatecb) call pl%obl_acc(cb) + if (param%lextra_force) call pl%user_getacch(system, param, t) + if (param%lgr) call pl%gr_getacch(param) end associate return @@ -63,7 +60,7 @@ module subroutine whm_getacch_tp(self, system, param, t, xhp) associate(tp => self, ntp => self%nbody, pl => system%pl, cb => system%cb, npl => system%pl%nbody) if (ntp == 0 .or. npl == 0) return - ah0 = whm_getacch_ah0(pl%Gmass(:), xhp(:,:), npl) + ah0(:) = whm_getacch_ah0(pl%Gmass(:), xhp(:,:), npl) do i = 1, ntp tp%ah(:, i) = ah0(:) end do @@ -110,8 +107,8 @@ pure subroutine whm_getacch_ah1(cb, pl) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah1.f90 implicit none ! Arguments - class(whm_cb), intent(in) :: cb !! WHM central body object - class(whm_pl), intent(inout) :: pl !! WHM massive body object + class(swiftest_cb), intent(in) :: cb !! WHM central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: ah1h, ah1j @@ -137,8 +134,8 @@ pure subroutine whm_getacch_ah2(cb, pl) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah2.f90 implicit none ! Arguments - class(whm_cb), intent(in) :: cb !! Swiftest central body object - class(whm_pl), intent(inout) :: pl !! WHM massive body object + class(swiftest_cb), intent(in) :: cb !! Swiftest central body object + class(whm_pl), intent(inout) :: pl !! WHM massive body object ! Internals integer(I4B) :: i real(DP) :: etaj, fac @@ -169,15 +166,15 @@ pure subroutine whm_getacch_ah3(pl) !! Adapted from David E. Kaufmann's Swifter routine whm_getacch_ah3.f90 implicit none - class(whm_pl), intent(inout) :: pl - integer(I4B) :: i, j - real(DP) :: rji2, irij3, faci, facj - real(DP), dimension(NDIM) :: dx - real(DP), dimension(:,:), allocatable :: ah3 + class(whm_pl), intent(inout) :: pl + integer(I4B) :: i, j + real(DP) :: rji2, irij3, faci, facj + real(DP), dimension(NDIM) :: dx + real(DP), dimension(:,:), allocatable :: ah3 associate(npl => pl%nbody) allocate(ah3, mold=pl%ah) - ah3(:, 1:npl) = 0.0_DP + ah3(:, :) = 0.0_DP do i = 1, npl - 1 do j = i + 1, npl diff --git a/src/whm/whm_step.f90 b/src/whm/whm_step.f90 index b37d06bbe..8e87796ea 100644 --- a/src/whm/whm_step.f90 +++ b/src/whm/whm_step.f90 @@ -85,10 +85,10 @@ module subroutine whm_step_tp(self, system, param, t, dt) select type(system) class is (whm_nbody_system) - associate(tp => self, cb => system%cb, pl => system%pl) + associate(tp => self, cb => system%cb, pl => system%pl, xbeg => system%xbeg, xend => system%xend) dth = 0.5_DP * dt if (tp%lfirst) then - call tp%getacch(system, param, t, system%xbeg) + call tp%getacch(system, param, t, xbeg) tp%lfirst = .false. end if call tp%kickvh(dth) @@ -96,7 +96,7 @@ module subroutine whm_step_tp(self, system, param, t, dt) if (param%lgr) call tp%gr_p4(param, dth) call tp%drift(system, param, dt) if (param%lgr) call tp%gr_p4(param, dth) - call tp%getacch(system, param, t + dt, system%xend) + call tp%getacch(system, param, t + dt, xend) call tp%kickvh(dth) end associate end select From d9eaa18ba1f2a51d4af61dd89412197eccf784b4 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 6 Jul 2021 09:30:17 -0400 Subject: [PATCH 09/12] Fixed double allocation problem for planetocentric structure --- src/rmvs/rmvs_setup.f90 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index 2835aea6c..7955fc74a 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -24,7 +24,7 @@ module subroutine rmvs_setup_pl(self,n) allocate(pl%inner(0:NTPHENC)) if (.not.pl%lplanetocentric) then allocate(pl%nenc(n)) - pl%nenc(:) = 0 + pl%nenc(:) = 0 ! Set up inner and outer planet interpolation vector storage containers do i = 0, NTENC @@ -108,14 +108,14 @@ module subroutine rmvs_setup_system(self, param) associate(npl => pl%nbody) allocate(pl%planetocentric(npl)) do i = 1, npl - pl%planetocentric(i)%lplanetocentric = .true. allocate(pl%planetocentric(i)%cb, source=cb) - allocate(rmvs_cb :: pl%planetocentric(i)%cb) allocate(rmvs_pl :: pl%planetocentric(i)%pl) select type(cbenci => pl%planetocentric(i)%cb) class is (rmvs_cb) select type(plenci => pl%planetocentric(i)%pl) class is (rmvs_pl) + cbenci%lplanetocentric = .true. + plenci%lplanetocentric = .true. call plenci%setup(npl) plenci%status(:) = ACTIVE ! plind stores the heliocentric index value of a planetocentric planet From 10c3a0056be685d53fcafa430cbe7e944e45a189 Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 6 Jul 2021 10:37:11 -0400 Subject: [PATCH 10/12] Fixed issue where the driver didn't output the final step. Also fixed bad massive body position used in 3rd whm test particle acceleration term --- .../9pl_18tp_encounters/param.swifter.in | 4 +- .../swiftest_rmvs_vs_swifter_rmvs.ipynb | 219 +++++++----------- src/main/swiftest_driver.f90 | 2 +- src/whm/whm_getacch.f90 | 13 +- 4 files changed, 94 insertions(+), 144 deletions(-) diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in index 25267812a..ec31caa63 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/param.swifter.in @@ -11,8 +11,8 @@ BIN_OUT bin.swifter.dat OUT_TYPE REAL8 OUT_FORM XV OUT_STAT UNKNOWN -J2 0.0 -J4 0.0 +J2 4.7535806948127355e-12 +J4 -2.2473967953572827e-18 CHK_CLOSE yes CHK_RMIN 0.004650467260962157 CHK_RMAX 1000.0 diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb index 304a0c190..197f09290 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb @@ -22,13 +22,16 @@ "output_type": "stream", "text": [ "Reading Swifter file param.swifter.in\n", + "Reading in time 3.660e+02\n", + "Creating Dataset\n", + "Successfully converted 367 output frames.\n", "Swifter simulation data stored as xarray DataSet .ds\n" ] } ], "source": [ "inparfile = 'param.swifter.in'\n", - "swiftersim = swiftest.Simulation(source=inparfile, codename=\"Swifter\")\n", + "swiftersim = swiftest.Simulation(param_file=inparfile, codename=\"Swifter\")\n", "swiftersim.bin2xr()\n", "swifterdat = swiftersim.ds" ] @@ -43,13 +46,16 @@ "output_type": "stream", "text": [ "Reading Swiftest file param.swiftest.in\n", + "Reading in time 3.660e+02\n", + "Creating Dataset\n", + "Successfully converted 367 output frames.\n", "Swiftest simulation data stored as xarray DataSet .ds\n" ] } ], "source": [ "inparfile = 'param.swiftest.in'\n", - "swiftestsim = swiftest.Simulation(source=inparfile)\n", + "swiftestsim = swiftest.Simulation(param_file=inparfile)\n", "swiftestsim.bin2xr()\n", "swiftestdat = swiftestsim.ds" ] @@ -451,138 +457,81 @@ " stroke: currentColor;\n", " fill: currentColor;\n", "}\n", - "
<xarray.DataArray 'px' (time (d): 366)>\n",
-       "array([0.00000000e+00, 2.22044605e-16, 4.44089210e-16, 8.88178420e-16,\n",
-       "       1.55431223e-15, 2.66453526e-15, 3.99680289e-15, 5.55111512e-15,\n",
-       "       7.32747196e-15, 9.32587341e-15, 1.13242749e-14, 1.35447209e-14,\n",
-       "       1.62092562e-14, 1.90958360e-14, 2.22044605e-14, 2.55351296e-14,\n",
-       "       2.90878432e-14, 3.28626015e-14, 3.68594044e-14, 4.13002965e-14,\n",
-       "       4.59632332e-14, 5.08482145e-14, 5.59552404e-14, 6.12843110e-14,\n",
-       "       6.68354261e-14, 7.26085858e-14, 7.86037901e-14, 8.50430837e-14,\n",
-       "       9.17044218e-14, 9.85878046e-14, 1.05693232e-13, 1.13242749e-13,\n",
-       "       1.20792265e-13, 1.28563826e-13, 1.36779477e-13, 1.45217172e-13,\n",
-       "       1.53876911e-13, 1.62980740e-13, 1.72528658e-13, 1.81854531e-13,\n",
-       "       1.91624494e-13, 2.01838546e-13, 2.12274642e-13, 2.22932783e-13,\n",
-       "       2.33812969e-13, 2.45137244e-13, 2.56905608e-13, 2.68896017e-13,\n",
-       "       2.81108470e-13, 2.93765012e-13, 3.06643599e-13, 3.19744231e-13,\n",
-       "       3.33066907e-13, 3.46611628e-13, 3.60822483e-13, 3.75477427e-13,\n",
-       "       3.90132371e-13, 4.05231404e-13, 4.20774526e-13, 4.36761738e-13,\n",
-       "       4.52748949e-13, 4.69180250e-13, 4.86277685e-13, 5.03153075e-13,\n",
-       "       5.20472554e-13, 5.37792033e-13, 5.55999691e-13, 5.74651438e-13,\n",
-       "       5.93525229e-13, 6.12843110e-13, 6.32827124e-13, 6.52811138e-13,\n",
-       "       6.73017198e-13, 6.93223257e-13, 7.14317494e-13, 7.36077865e-13,\n",
-       "       7.57838237e-13, 7.79820652e-13, 8.02691247e-13, 8.25561841e-13,\n",
-       "...\n",
-       "       1.31983313e-11, 1.32187594e-11, 1.32370226e-11, 1.32530653e-11,\n",
-       "       1.32669986e-11, 1.32788225e-11, 1.32883704e-11, 1.32956424e-11,\n",
-       "       1.33005829e-11, 1.33031919e-11, 1.33035249e-11, 1.33012490e-11,\n",
-       "       1.32966971e-11, 1.32894806e-11, 1.32797107e-11, 1.32676092e-11,\n",
-       "       1.32526212e-11, 1.32353017e-11, 1.32149847e-11, 1.31921141e-11,\n",
-       "       1.31665789e-11, 1.31382683e-11, 1.31069600e-11, 1.30728761e-11,\n",
-       "       1.30360167e-11, 1.29962707e-11, 1.29535271e-11, 1.29078970e-11,\n",
-       "       1.28593802e-11, 1.28074218e-11, 1.27525768e-11, 1.26949562e-11,\n",
-       "       1.26338939e-11, 1.25698341e-11, 1.25023325e-11, 1.24318333e-11,\n",
-       "       1.23581145e-11, 1.22810651e-11, 1.22007959e-11, 1.21171961e-11,\n",
-       "       1.20300436e-11, 1.19397825e-11, 1.18460797e-11, 1.17490462e-11,\n",
-       "       1.16484600e-11, 1.15446541e-11, 1.14370735e-11, 1.13261622e-11,\n",
-       "       1.12119203e-11, 1.10941256e-11, 1.09725562e-11, 1.08476561e-11,\n",
-       "       1.07189813e-11, 1.05870868e-11, 1.04514175e-11, 1.03119735e-11,\n",
-       "       1.01691988e-11, 1.00233155e-11, 9.87299131e-12, 9.71933645e-12,\n",
-       "       9.56190682e-12, 9.40092448e-12, 9.23616739e-12, 9.06807962e-12,\n",
-       "       8.89599505e-12, 8.72013572e-12, 8.54050164e-12, 8.35753688e-12,\n",
-       "       8.17101942e-12, 7.98094923e-12, 7.78666021e-12, 7.58904051e-12,\n",
-       "       7.38742401e-12, 7.18247684e-12, 6.97397695e-12, 6.76170231e-12,\n",
-       "       6.54609700e-12, 6.32649488e-12])\n",
+       "
<xarray.DataArray 'px' (time (d): 367)>\n",
+       "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n",
+       "       0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n",
        "Coordinates:\n",
        "    id        int64 4\n",
-       "  * time (d)  (time (d)) float64 0.0 1.0 2.0 3.0 4.0 ... 362.0 363.0 364.0 365.0
" + " * time (d) (time (d)) float64 0.0 1.0 2.0 3.0 4.0 ... 363.0 364.0 365.0 366.0
" ], "text/plain": [ - "\n", - "array([0.00000000e+00, 2.22044605e-16, 4.44089210e-16, 8.88178420e-16,\n", - " 1.55431223e-15, 2.66453526e-15, 3.99680289e-15, 5.55111512e-15,\n", - " 7.32747196e-15, 9.32587341e-15, 1.13242749e-14, 1.35447209e-14,\n", - " 1.62092562e-14, 1.90958360e-14, 2.22044605e-14, 2.55351296e-14,\n", - " 2.90878432e-14, 3.28626015e-14, 3.68594044e-14, 4.13002965e-14,\n", - " 4.59632332e-14, 5.08482145e-14, 5.59552404e-14, 6.12843110e-14,\n", - " 6.68354261e-14, 7.26085858e-14, 7.86037901e-14, 8.50430837e-14,\n", - " 9.17044218e-14, 9.85878046e-14, 1.05693232e-13, 1.13242749e-13,\n", - " 1.20792265e-13, 1.28563826e-13, 1.36779477e-13, 1.45217172e-13,\n", - " 1.53876911e-13, 1.62980740e-13, 1.72528658e-13, 1.81854531e-13,\n", - " 1.91624494e-13, 2.01838546e-13, 2.12274642e-13, 2.22932783e-13,\n", - " 2.33812969e-13, 2.45137244e-13, 2.56905608e-13, 2.68896017e-13,\n", - " 2.81108470e-13, 2.93765012e-13, 3.06643599e-13, 3.19744231e-13,\n", - " 3.33066907e-13, 3.46611628e-13, 3.60822483e-13, 3.75477427e-13,\n", - " 3.90132371e-13, 4.05231404e-13, 4.20774526e-13, 4.36761738e-13,\n", - " 4.52748949e-13, 4.69180250e-13, 4.86277685e-13, 5.03153075e-13,\n", - " 5.20472554e-13, 5.37792033e-13, 5.55999691e-13, 5.74651438e-13,\n", - " 5.93525229e-13, 6.12843110e-13, 6.32827124e-13, 6.52811138e-13,\n", - " 6.73017198e-13, 6.93223257e-13, 7.14317494e-13, 7.36077865e-13,\n", - " 7.57838237e-13, 7.79820652e-13, 8.02691247e-13, 8.25561841e-13,\n", - "...\n", - " 1.31983313e-11, 1.32187594e-11, 1.32370226e-11, 1.32530653e-11,\n", - " 1.32669986e-11, 1.32788225e-11, 1.32883704e-11, 1.32956424e-11,\n", - " 1.33005829e-11, 1.33031919e-11, 1.33035249e-11, 1.33012490e-11,\n", - " 1.32966971e-11, 1.32894806e-11, 1.32797107e-11, 1.32676092e-11,\n", - " 1.32526212e-11, 1.32353017e-11, 1.32149847e-11, 1.31921141e-11,\n", - " 1.31665789e-11, 1.31382683e-11, 1.31069600e-11, 1.30728761e-11,\n", - " 1.30360167e-11, 1.29962707e-11, 1.29535271e-11, 1.29078970e-11,\n", - " 1.28593802e-11, 1.28074218e-11, 1.27525768e-11, 1.26949562e-11,\n", - " 1.26338939e-11, 1.25698341e-11, 1.25023325e-11, 1.24318333e-11,\n", - " 1.23581145e-11, 1.22810651e-11, 1.22007959e-11, 1.21171961e-11,\n", - " 1.20300436e-11, 1.19397825e-11, 1.18460797e-11, 1.17490462e-11,\n", - " 1.16484600e-11, 1.15446541e-11, 1.14370735e-11, 1.13261622e-11,\n", - " 1.12119203e-11, 1.10941256e-11, 1.09725562e-11, 1.08476561e-11,\n", - " 1.07189813e-11, 1.05870868e-11, 1.04514175e-11, 1.03119735e-11,\n", - " 1.01691988e-11, 1.00233155e-11, 9.87299131e-12, 9.71933645e-12,\n", - " 9.56190682e-12, 9.40092448e-12, 9.23616739e-12, 9.06807962e-12,\n", - " 8.89599505e-12, 8.72013572e-12, 8.54050164e-12, 8.35753688e-12,\n", - " 8.17101942e-12, 7.98094923e-12, 7.78666021e-12, 7.58904051e-12,\n", - " 7.38742401e-12, 7.18247684e-12, 6.97397695e-12, 6.76170231e-12,\n", - " 6.54609700e-12, 6.32649488e-12])\n", + "\n", + "array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,\n", + " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n", "Coordinates:\n", " id int64 4\n", - " * time (d) (time (d)) float64 0.0 1.0 2.0 3.0 4.0 ... 362.0 363.0 364.0 365.0" + " * time (d) (time (d)) float64 0.0 1.0 2.0 3.0 4.0 ... 363.0 364.0 365.0 366.0" ] }, "execution_count": 8, @@ -601,7 +550,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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28LyI4HB6WMi8NsaxGRmGWtsQqr3pqQ8qVliiIhHgXdaWGUccF0kngR6S9q5NtGZWVbqvcaQR3nqfN4FWFDwvCGd9yGSJkqaIWnGkiVLahKcmbUPdz7nT54SQ6nztEp+UiLiyogYExFj+vTp085hmVl72tiU5BpDbuQpMTQA/Que9wMWZhSLmVndylNimAqcosQBwN8jYlHWQZlZ+3JTUv7ULDFIugl4AthTUoOkCZLOkHRGuso04FVgHnAV8K1axWZm2XFTUmW+9rWvscMOOzBixIeuAihbza5jiIjxm1gewLdrFI6Z5UTjGElODOU59dRTOfPMMznllFOqVmaempLMrI7V+yB65TrooIPYdtttq1qmh8Qws0xtrCl08ArDBXfM5sWFy6ta5rC+W/Ojzw+vapmt4RqDmWXKfQz54xqDmWWqs1z5nMUv+/biGoOZZcqnq+aPE4OZZcpNSZUZP348H//4x5k7dy79+vXj97//fcVluinJzKwDu+mmm6pepmsMZpYpD7udP04MZpapztL53Jk4MZhZptz5nD9ODGaWKXc+548Tg5llyk1J+ePEYGaZ2tiE5LyQG04MZpapxprCBjyIXlstWLCAQw89lKFDhzJ8+HAmT55clXJ9HYOZZcqnq5ava9eu/OpXv2LUqFGsWLGC0aNHc/jhhzNs2LCKynWNwcwy5T6G8u28886MGjUKgF69ejF06FDeeOONist1jcHMcqHDJ4a7z4U3X6humTvtBUde1KpVX3vtNZ577jn233//infrGoOZZcqdz5VbuXIlxx13HJdccglbb711xeW5xmBmmeo0TUmt/GVfbWvXruW4447jpJNO4thjj61Kma4xmFmmfOVz+SKCCRMmMHToUH7wgx9UrVwnBjPLlK98Lt/06dO5/vrreeihhxg5ciQjR45k2rRpFZfrpiQzy1SnaUrKwIEHHtguNS3XGMwsF9yUlB9ODGaWqQ3hK57zxonBzDLlPob8cWIws0z5rKT8cWIws0xtHETPTUq54cRgZtlyRSF3apoYJI2VNFfSPEnnlli+jaQ7JD0vabak02oZn5nVnk9XLd/q1avZb7/92GeffRg+fDg/+tGPqlJuza5jkNQFuAw4HGgAnpY0NSJeLFjt28CLEfF5SX2AuZJujIg1tYrTzGrLfQzl23zzzXnooYfo2bMna9eu5cADD+TI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\n", "text/plain": [ "
" ] @@ -627,7 +576,7 @@ "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZQAAAElCAYAAADDUxRwAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjMuNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8QVMy6AAAACXBIWXMAAAsTAAALEwEAmpwYAAAm+0lEQVR4nO3de5xVdb3/8dc7LqKA4gWUqyCi3FJCAivDS2HgsYOKmqilSZId7dhJU9N+lfUrqX6pWKZHzXtH6ng0yfAKeDQvKQooRigqyggKogSIyMXP74+1Jjfjnpk9e6+ZvTfzfj4e+zHr8l3f9dnfuXzm+11rf5ciAjMzs1J9rNwBmJnZtsEJxczMMuGEYmZmmXBCMTOzTDihmJlZJpxQzMwsE04oljlJP5R0a7rcR9I6SW3KHVdDJH1W0qIWPmdI2rvEOp6XdEg2EX2k7nq/j5J2l/SwpLWSfqnEDZLekfRkc8Rjlc8JxT5C0hJJn6+z7VRJf2lqXRHxWkR0iogt2UXYNIX84Y6IRyJi35aKKSsRMSQiHoKtE0AznKfu93Ey8BawY0ScAxwEjAF6RcTI5ojBKp8TirV6ktqWO4YqtCfwt/jwk9F7Aksi4t2mVuT233Y4oVhRJPWQ9D+SVkp6RdK/11Oub9pDaJtz3HRJb0taLOn0nLJtJF0o6aV0KOVpSb3TfQMlPZAet0jS8TnH3SjpSkl/To/7q6T+6b6H02Lz0yGbL0k6RFKNpPMlvQHcULstp87eku5I398qSb+upw3ek7RLzrZPSHpLUrt0/TRJC9OhoPsk7VlPO+0k6eb0fK9K+p6kj+XsPz2tZ62kv0kanm5fIunzksYCFwJfSt/nfEnHSXq6znnOkfTHemLoJ+l/03M8AOyW7/so6UbgFOC89FxfB64DPpWuX5wec6SkeZJWS3pM0n459S1J2/9Z4N203gPTcqvT+A/JKf+QpB9LejSN735JufEdlHPsUkmnptu3k/T/JL0m6U1JV0vaPt23m6S702PelvRIbptbESLCL7+2egFLgM/X2XYq8Jd0+WPA08D3gfbAXsDLwBfS/T8Ebk2X+wIBtE3X/xf4DdABGAasBD6X7vsO8BywLyBgf2BXoCOwFPgq0BYYTjLcMiQ97kbgbWBkuv93wLSc2APYO2f9EGAz8DNgO2D7dFtNur8NMB+4LD13B+CgetpqFnB6zvovgKvT5aOAxcCgNK7vAY/liwu4GbgL6Jy22QvApHTfccDrwCfTdtkb2LPu9yq33dP17dJ2GZSzbS4woZ738jhwaXrcaGBtA9/HG4H/m+/nI10fDqwARqXteUoa63Y5cc8Deqft3xNYBRxB8vM1Jl3vmpZ/CHgJ2Cct/xAwJd3XJ411ItCO5GdmWLrvcmA6sEvatn8CLkn3XQJcnR7TDvgsoHL//lXzq+wB+FV5r/SXfR2wOue1ng8TyijgtTrHfBe4IV3+5x+23D9E6R+PLUDnnOMuAW5MlxcB4/PE8yXgkTrb/hP4Qbp8I3Bdzr4jgL/nrOdLKBuBDnW21SaUT5EkurYFtNXXgFnpskgS3+h0/R7SpJCufyxtxz1z4yL5g/s+MDin7NeBh9Ll+4CzG/he5U0o6bargJ+ky0OAd0j/qNcp14ckyXbM2fZf+b6POW3eUEK5CvhxnXMsAg7Oifu0nH3nA7fUKX8fcEq6/BDwvZx9/wbcm/Ozd2ee9yTgXaB/zrZPAa+kyz8iSeJ71z3Wr+Je7t5ZfY6KiC61L5Jf4Fp7Aj3SoYLVklaTDLfs3kidPYC3I2JtzrZXSf47hSThvJTnuD2BUXXOdxKwR06ZN3KW1wOdGollZURsqGdfb+DViNjcSB0At5MM9fQg+a8+gEdy4p6aE/PbJH/ketapYzeSnt6rOdsKaZdC3AScKEnAl4E/RMT7ecr1AN6Jra+BvJqnXKH2BM6p8z3rnZ6n1tI65Y+rU/4goHtOmfq+x/W1T1dgB+DpnDrvTbdD0ptcDNwv6WVJFzT9bVouXwyzYiwl+S9vQBOPWwbsIqlzTlLpQzKcU1tvf2BBnvP9b0SMKTbgPBqaZnsp0EdS28aSSkSslnQ/cDzJ0NZtkf77m9bzk4j4XSOxvAVsIr3QnW7L1y6N+ch7iognJG0kGc45MX3lsxzYWVLHnKTSJ1+dBap97z8pMN6lJD2U0+sr3Mi58t1Z9hbwHsnQ6Ot1d6Y/g+eQJL4hwGxJT0XEzCJiMHxR3orzJLAmvai6vZKL6UMlfbKhgyJiKfAYcImkDulF2kkk1zwgubD7Y0kDlNhP0q7A3cA+kr4sqV36+qSkQQXG+ybJdZ6mvL/lwBRJHdNYP9NA+f8CvgJMSJdrXQ18N/1jVXvh/bi6B0dyK+4fgJ9I6qzkwv23gdpbgK8DzpV0QNoueyv/xf03gb55LizfDPwa2BwReW/9johXgTnAxZLaSzoI+GID77kx1wJnSBqVxtxR0r9I6lxP+VuBL0r6Qvrz1EHJjRK9CjjX74DPSzo+vbi/q6RhEfFBGsdlkroBSOop6Qvp8pFpWwpYQzIcW7bb27cFTijWZOkfwC+SXFR/heQ/weuAnQo4fCLJePwy4E6S6yAPpPsuJfnDej/JL/hvge3T/yQPB05Ij3uDDy+oF+KHwE3psMfxjRXOeX97A68BNSTXceozHRgAvBkR83PquTONc5qkNSQ9r3H11PFNkvH+l4G/kCSm69N6/hv4SbptLfBHkovMdf13+nWVpGdytt8CDE2/NuREkutjbwM/IElERYmIOcDpJInsHZKhpVMbKL8UGE8ydLqSpNfxHQr4GxURr5FcNzsnjX0eyQ0dkFybWQw8kX4PHiS56QOS79mDJNcLHwd+E+lneqw4+rB3bmbbovQ22RXA8Ih4sdzx2LbLPRSzbd83gKecTKy5+aK82TZM0hKSO8uOKm8k1hp4yMvMzDLhIS8zM8uEE4pZEyjPTMzbCtWZd82sqZxQzOpI/6i+q2Siw9clXaoWfp6LMnhWillLc0Ixy2//iOgEfI7k8xnFfILbrFVxQjFrQET8nWRurqF190kaKenx9AOTyyX9WlL7nP0h6QxJLyqZvv7K9FPZtfvzTm2v/FPuFzzVuqRPS3pK0j/Sr5/O2dfgNPA55Zo09b0ZOKGYNUjSYJJ5sObm2b0F+A+SyR0/RdKb+bc6ZY4kmXZ+f5L5vmqn/TiK5FPhx5BMVvgIcBtARIxOj90/kqck/p7kU+A1adnd02M/coumkmez/Bm4gmQa90uBP6dT2NQ6keRRAN1IJqU8N897mw70qzO9zck0/ml7a8WcUMzye0bSOyTPz7gOuKFugYh4OiKeiIjNEbGEZEr9g+sUmxIRq9PpQWaTTFcDyfT0l0TEwnQCyp8Cw+qZowuSySO7k0x9vymSRxbnu+f/X4AXI+KWNK7bgL+z9bxcN0TECxHxHslUN8PqVpLOSPx7kiRCOh9ZX5J51czyckIxy294ROwcEf0j4nvpRINbkbRPOgz1RjpP1E/Jecphqr4p1wud2r5WoVOt9+Cj087nToXfUEx1FTr1vRnghGJWiqtI/vsfEBE7kgxDqeFD/mkp8PXcZ85ExPYR8Vi+whGxNiLOiYi9SHob35b0uTxFl5Ekq1y5U+EXLCKeIHkQWe3U9x7usgY5oZgVrzPJrMjrJA0kmTOrUI1Nbb/VlPtNmGp9BslU/yemU7l/CRhM8UNVjU59b1bLCcWseOeS/Oe+luS5G78v9MACprb/IVtPuV/QVOsRsYrkRoBzSJ7Jfh5wZES81dQ3lyp06nszz+VlZvXz1PfWFO6hmFlDPPW9Fcxz9phZXp763prKQ15mZpYJD3mZmVkmWvWQ12677RZ9+/YtdxhmZlXl6aeffisiutbd3qoTSt++fZkzZ065wzAzqyqS6s7GAHjIy8zMMuKEYmZmmXBCMTOzTLTqayhmZuWwadMmampq2LBhQ7lDaVCHDh3o1asX7dq1K6i8E4qZWQurqamhc+fO9O3bl5yHeFaUiGDVqlXU1NTQr1+/go7xkJeZWQvbsGEDu+66a8UmEwBJ7Lrrrk3qRTmhmJmVQSUnk1pNjdEJxczMMuGEYmZWpT796U/n3X7qqady++23t3A0TihmZlXrscfyPjG6bHyXl5lZlerUqRPr1q0jIvjmN7/JrFmz6NevH+WaRd49FDOzKnfnnXeyaNEinnvuOa699tqy9VycUMzMqtzDDz/MxIkTadOmDT169OCwww4rSxxOKGZm24BKuA3ZCcXMrMqNHj2aadOmsWXLFpYvX87s2bPLEocvypuZVbmjjz6aWbNm8fGPf5x99tmHgw8+uCxxOKGYmVWpdevWAclw169//esyR+MhLzMzy4gTipmZZcIJxczMMuGEYmZmmXBCMTOzTDihmJlZJpxQzMxaqdNOO41u3boxdOjQTOpzQjEza6VOPfVU7r333szqq6iEImmspEWSFku6IM9+Sboi3f+spOF19reRNFfS3S0XtZlZdRo9ejS77LJLZvVVzCflJbUBrgTGADXAU5KmR8TfcoqNAwakr1HAVenXWmcDC4EdWyRoM7MSXfyn5/nbsjWZ1jm4x4784ItDMq2zEJXUQxkJLI6IlyNiIzANGF+nzHjg5kg8AXSR1B1AUi/gX4DrWjJoMzNLVEwPBegJLM1Zr2Hr3kd9ZXoCy4HLgfOAzg2dRNJkYDJAnz59SgrYzKxU5ehJNJdK6qHkm8y/7nMs85aRdCSwIiKebuwkEXFNRIyIiBFdu3YtJk4zM8ujkhJKDdA7Z70XsKzAMp8B/lXSEpKhssMk3dp8oZqZVb+JEyfyqU99ikWLFtGrVy9++9vfllRfJQ15PQUMkNQPeB04ATixTpnpwFmSppEMh/0jIpYD301fSDoEODciTm6huM3MqtJtt92WaX0Vk1AiYrOks4D7gDbA9RHxvKQz0v1XAzOAI4DFwHrgq+WK18zMtlYxCQUgImaQJI3cbVfnLAdwZiN1PAQ81AzhmZlZAyrpGoqZmVUxJxQzM8uEE4qZmWXCCcXMzDLhhGJm1gotXbqUQw89lEGDBjFkyBCmTp1acp0VdZeXmZm1jLZt2/LLX/6S4cOHs3btWg444ADGjBnD4MGDi67TPRQzs1aoe/fuDB+ePAGkc+fODBo0iNdff72kOt1DMTMrp3sugDeey7bOPT4O46YUXHzJkiXMnTuXUaPqzsfbNO6hmJm1YuvWrWPChAlcfvnl7LhjaY+Scg/FzKycmtCTyNqmTZuYMGECJ510Esccc0zJ9bmHYmbWCkUEkyZNYtCgQXz729/OpE4nFDOzVujRRx/llltuYdasWQwbNoxhw4YxY8aMxg9sgIe8zMxaoYMOOohkvt3suIdiZmaZcEIxM7NMOKGYmVkmnFDMzCwTTihmZpYJJxQzM8uEE4qZWSu0YcMGRo4cyf7778+QIUP4wQ9+UHKd/hyKmVkrtN122zFr1iw6derEpk2bOOiggxg3bhwHHnhg0XW6h2Jm1gpJolOnTkAyp9emTZuQVFKd7qGYmZXRz578GX9/+++Z1jlwl4GcP/L8Rstt2bKFAw44gMWLF3PmmWd6+nozMytOmzZtmDdvHjU1NTz55JMsWLCgpPrcQzEzK6NCehLNrUuXLhxyyCHce++9DB06tOh63EMxM2uFVq5cyerVqwF47733ePDBBxk4cGBJdbqHYmbWCi1fvpxTTjmFLVu28MEHH3D88cdz5JFHllSnE4qZWSu03377MXfu3Ezr9JCXmZllwgnFzMwyUVEJRdJYSYskLZZ0QZ79knRFuv9ZScPT7b0lzZa0UNLzks5u+ejNzFq3ikkoktoAVwLjgMHAREmD6xQbBwxIX5OBq9Ltm4FzImIQcCBwZp5jzcysGVVMQgFGAosj4uWI2AhMA8bXKTMeuDkSTwBdJHWPiOUR8QxARKwFFgI9WzJ4M7PWrtG7vCT1KbCu1RGxpoRYegJLc9ZrgLrzAOQr0xNYXrtBUl/gE8BfS4jFzMyaqJDbhm8CAmho1rAAbgRuLiGWfPVHU8pI6gT8D/Ct+pKbpMkkw2X06VNorjQz2zZt2bKFESNG0LNnT+6+++6S6mo0oUTEoXW3SdojIt4o6cwfVQP0zlnvBSwrtIykdiTJ5HcRcUd9J4mIa4BrAEaMGFE3YZmZtSpTp05l0KBBrFlTygBTothrKF8p+cwf9RQwQFI/Se2BE4DpdcpMB76S3u11IPCPiFiuZM7l3wILI+LSZojNzGybU1NTw5///Ge+9rWvZVJfsZ+UHy9pPfBARCzKIpCI2CzpLOA+oA1wfUQ8L+mMdP/VwAzgCGAxsB74anr4Z4AvA89JmpduuzAiZmQRm5lZc3njpz/l/YXZTl+/3aCB7HHhhY2W+9a3vsXPf/5z1q5dm8l5i00ox5Bc+D5a0t4RkUl6SxPAjDrbrs5ZDuDMPMf9hYav8ZiZWY67776bbt26ccABB/DQQw9lUmdRCSUi3gTuTV9mZlakQnoSzeHRRx9l+vTpzJgxgw0bNrBmzRpOPvlkbr311qLrLOoaiqQrJd2YLh9e9NnNzKwsLrnkEmpqaliyZAnTpk3jsMMOKymZQPEX5TcCL6fLh5UUgZmZbROKvYayHtgpvVXXH+YwM6tihxxyCIccckjJ9RSbUN4G3iOZe+vRkqMwM7Oq16QhL0ldJN0ATEg33QyMyDwqMzOrOk3qoUTEaklTgL7AW8B+QL2fSjczs9ajmCGvScArEXEf8HTG8ZiZWZUqJqG8A5whaV9gPjAvIrJ9MLGZmVWdJieUiLhE0kzgBWAYMBpwQjEza+WanFAk/Yhkrq15JL2ThzKOyczMWkDfvn3p3Lkzbdq0oW3btsyZM6ek+orpoXxf0vdJ7hCbIKl/RJxeUhRmZlYWs2fPZrfddsukrmI/KX89MAjYFfhNJpGYmVlVK/aDjf9OMv1KW2AqyXUUMzNrokf+8AJvLV2XaZ279e7EZ4/fp9Fykjj88MORxNe//nUmT55c0nmLTSgvAQOAuyLiP0qKwMzMyuLRRx+lR48erFixgjFjxjBw4EBGjy6+f1BsQnkeWApMkvSLiPhk0RGYmbVihfQkmkuPHj0A6NatG0cffTRPPvlkSQml2Gso/UmS0TV8+NREMzOrEu++++4/n9T47rvvcv/99zN06NCS6iy2h7I0ImZJ6g6sKCkCMzNrcW+++SZHH300AJs3b+bEE09k7NixJdVZbEIZK+kFktmGXyW5SG9mZlVir732Yv78+ZnWWeyQVxfgfOA84P3MojEzs6pVbA/lR8DAiFgkaUuWAZmZWXUquIciaf/a5YioiYgH0+ULmiMwMzOrLk0Z8por6VlJ50nq3WwRmZlZVWpKQvkl0BGYArwiabak05onLDMzqzYFJ5SI+E5E9Cd55O91JNOtXNNcgZmZWXVpyjWUXSV9DfgpyYcZRfJpeTMzq0KrV6/m2GOPZeDAgQwaNIjHH3+8pPqacpfXGyQJ6B3gBuDWiPhLSWc3M7OyOfvssxk7diy33347GzduZP369SXV15SEcidwK3BPRGwq6axmZlZWa9as4eGHH+bGG28EoH379rRv376kOgtOKBFxfElnMjOzj5h94zWsePXlTOvstudeHHpqw1PRv/zyy3Tt2pWvfvWrzJ8/nwMOOICpU6fSsWPHos9b7Cflzcysim3evJlnnnmGb3zjG8ydO5eOHTsyZcqUkuos5pnyX4yIP5V0VjMzA2i0J9FcevXqRa9evRg1ahQAxx57bMkJpZgeyk9KOmMDJI2VtEjSYkkf+QS+Elek+5+VNLzQY83M7EN77LEHvXv3ZtGiRQDMnDmTwYMHl1RnMXN5qaQz1lep1IZk9uIxQA3wlKTpEfG3nGLjSJ4UOQAYBVwFjCrwWDMzy/GrX/2Kk046iY0bN7LXXntxww03lFRfMQklSjpj/UYCiyPiZQBJ04DxQG5SGA/cHBEBPCGpS/pMlr4FHJuZO64fT9udVjVH1WbWCvTs+2NWv9Ms/5sXLLa0ZdiwYcyZMyezOivponxPtv6gZE26rZAyhRwLgKTJkuZImrNy5cqSgzYzs0Sx09c3h3zpum5vqL4yhRybbIy4hnTKmBEjRhTV2zrmtLuKOczMDICFCxfSZeeB5Q4jc8UklDczjyJRA+TOYtwLWFZgmfYFHGtmZs2oyUNeETGmOQIBngIGSOonqT1wAjC9TpnpwFfSu70OBP4REcsLPNbMzJpRxQx5RcRmSWcB9wFtgOsj4nlJZ6T7rwZmAEcAi4H1JJNU1ntsGd6GmVmrVTEJBSAiZpAkjdxtV+csB3BmoceamVnLKeouL0nfzlneN7twzMysJSxatIhhw4b987Xjjjty+eWXl1Rnk3ookroAlwEDJW0AngUmkQ49mZlZddh3332ZN28eAFu2bKFnz54cffTRJdXZpIQSEauBr0r6AvAWsB9wR0kRmJlZWc2cOZP+/fuz5557llRPsddQNkXE05KWAStKisDMrBVb/aeX2Ljs3UzrbN+jI12+2L/g8tOmTWPixIkln7fYT8qPldQLuJpkCMzMzKrQxo0bmT59Oscdd1zJdRXbQ+kCnA+cB3yt5CjMzFqppvQkmsM999zD8OHD2X333Uuuq9iE8iNg34hYJGlLyVGYmVlZ3HbbbZkMd0HxQ17fBb6cLs/OJBIzM2tR69ev54EHHuCYY47JpL5iE8pGoPYhyIdmEomZmbWoHXbYgVWrVrHTTjtlUl+xCWU9sJOkdkCfTCIxM7OqVmxC+QHwEslTEn+XXThmZlatir0o/+8RcSl46hUzM0sUM/XKVcCe6dQr80luG/bUK2ZmrVyTp16RVAM8DPwV2B9PvWJmZhQ35LUKOAPYl6SHUpNpRGZmVpWKeWLjFOB04IfAK8BnM47JzMxawGWXXcaQIUMYOnQoEydOZMOGDSXV1+SEIulHwHhgDPB6RFxRUgRmZtbiXn/9da644grmzJnDggUL2LJlC9OmTSupziYPeUXE9yXtDnwCmCCpf0ScXlIUZmbW4jZv3sx7771Hu3btWL9+PT169CipvmJvG/468J8RcW9JZzcza+Xuuece3njjjUzr3GOPPRg3blyDZXr27Mm5555Lnz592H777Tn88MM5/PDDSzpvsR9svB74hqRfSBpWUgRmZtbi3nnnHe666y5eeeUVli1bxrvvvsutt95aUp1Ff7CRZD6vtsAVwOiSojAza6Ua60k0lwcffJB+/frRtWtXAI455hgee+wxTj755KLrLLaH8hLQAbgrIpxMzMyqTJ8+fXjiiSdYv349EcHMmTMZNGhQSXUWm1CeB2YBkyQ9VVIEZmbW4kaNGsWxxx7L8OHD+fjHP84HH3zA5MmTS6qz2CGv/sA7wDXpVzMzqzIXX3wxF198cWb1FZtQlkbELEndgRWZRWNmZlWr2CGvsZJ6AVcDl2UYj5mZValiE0oX4HzgPOD9zKIxM7OqVXBCkbR/zuqPSO7wWgRsyTwqMzOrOk3pocyV9Kyk8wBFxIMAEXFB84RmZmbVpCkJ5ZdAR2AK8Iqk2ZJOa56wzMys2hScUCLiOxHRHxgBXEfy6fhrsghC0i6SHpD0Yvp153rKjZW0SNJiSRfkbP+FpL+nPag70ydLmplZA6ZOncrQoUMZMmQIl19+ecn1NeUayq6Svgb8lOSRvwKWlhxB4gJgZkQMAGam63XP3wa4EhgHDAYmShqc7n4AGBoR+wEvAN/NKC4zs23SggULuPbaa3nyySeZP38+d999Ny+++GJJdTZlyOsN4D9Jeig3AKMjol9JZ//QeOCmdPkm4Kg8ZUYCiyPi5YjYCExLjyMi7o+IzWm5J4BeGcVlZrZNWrhwIQceeCA77LADbdu25eCDD+bOO+8sqc6mfLDxTuBW4J6I2FTSWT9q94hYDhARyyV1y1OmJ1v3iGqAUXnKnQb8PuP4zMyaxQsv/Ji16xZmWmfnToPYZ5//02CZoUOHctFFF7Fq1Sq23357ZsyYwYgRI0o6b6MJRVKfdPHc9Gt3SfmKro6INQ3U8yCwR55dFzUWQ20VebZFnXNcBGwGftdAHJOByZBMjmZm1hoNGjSI888/nzFjxtCpUyf2339/2rYtdvKURCFH38SHf7jzZpJ0/43AzfVVEhGfr2+fpDcldU97J/VN51ID9M5Z7wUsy6njFOBI4HMREdQjIq4hvZlgxIgR9ZYzM2sJjfUkmtOkSZOYNGkSABdeeCG9epV2taDRhBIRh5Z0hsJMB04huSX5FOCuPGWeAgZI6ge8DpwAnAjJ3V8kn9w/OCLWt0C8ZmZVb8WKFXTr1o3XXnuNO+64g8cff7yk+krr32RnCvAHSZOA14DjACT1AK6LiCMiYrOks4D7gDbA9RHxfHr8r4HtgAfS4bgnIuKMln4TZmbVZMKECaxatYp27dpx5ZVXsvPOeT+xUbCKSCgRsQr4XJ7ty4AjctZnADPylNu7WQM0M9sGPfLII5nWV+zkkGZmZltxQjEzs0w4oZiZlUEDN6NWjKbG6IRiZtbCOnTowKpVqyo6qUQEq1atokOHDgUfUxEX5c3MWpNevXpRU1PDypUryx1Kgzp06NCkz6Y4oZiZtbB27drRr19WUyFWDg95mZlZJpxQzMwsE04oZmaWCScUMzPLhBOKmZllwgnFzMwy4YRiZmaZcEIxM7NMOKGYmVkmnFDMzCwTTihmZpYJJxQzM8uEE4qZmWXCCcXMzDLhhGJmZplwQjEzs0w4oZiZWSacUMzMLBNOKGZmlgknFDMzy4QTipmZZcIJxczMMuGEYmZmmXBCMTOzTDihmJlZJioioUjaRdIDkl5Mv+5cT7mxkhZJWizpgjz7z5UUknZr/qjNzCxXRSQU4AJgZkQMAGam61uR1Aa4EhgHDAYmShqcs783MAZ4rUUiNjOzrVRKQhkP3JQu3wQclafMSGBxRLwcERuBaelxtS4DzgOiGeM0M7N6VEpC2T0ilgOkX7vlKdMTWJqzXpNuQ9K/Aq9HxPzGTiRpsqQ5kuasXLmy9MjNzAyAti11IkkPAnvk2XVRoVXk2RaSdkjrOLyQSiLiGuAagBEjRrg3Y2aWkRZLKBHx+fr2SXpTUveIWC6pO7AiT7EaoHfOei9gGdAf6AfMl1S7/RlJIyPijczegJmZNahShrymA6eky6cAd+Up8xQwQFI/Se2BE4DpEfFcRHSLiL4R0Zck8Qx3MjEza1mVklCmAGMkvUhyp9YUAEk9JM0AiIjNwFnAfcBC4A8R8XyZ4jUzszpabMirIRGxCvhcnu3LgCNy1mcAMxqpq2/W8ZmZWeMqpYdiZmZVzgnFzMwy4YRiZmaZcEIxM7NMOKGYmVkmnFDMzCwTTihmZpYJJxQzM8uEE4qZmWXCCcXMzDLhhGJmZplwQjEzs0w4oZiZWSacUMzMLBNOKGZmlgknFDMzy4QTipmZZcIJxczMMuGEYmZmmXBCMTOzTDihmJlZJpxQzMwsE04oZmaWCScUMzPLhCKi3DGUjaSVwKtFHr4b8FaG4TSXaoizGmKE6oizGmIEx5mlcsS4Z0R0rbuxVSeUUkiaExEjyh1HY6ohzmqIEaojzmqIERxnliopRg95mZlZJpxQzMwsE04oxbum3AEUqBrirIYYoTrirIYYwXFmqWJi9DUUMzPLhHsoZmaWCScUMzPLhBNKESSNlbRI0mJJF5Q7nlqSlkh6TtI8SXPSbbtIekDSi+nXncsQ1/WSVkhakLOt3rgkfTdt20WSvlDGGH8o6fW0PedJOqKcMabn7S1ptqSFkp6XdHa6vWLas4EYK6o9JXWQ9KSk+WmcF6fbK6kt64uxotrynyLCrya8gDbAS8BeQHtgPjC43HGlsS0Bdquz7efABenyBcDPyhDXaGA4sKCxuIDBaZtuB/RL27pNmWL8IXBunrJliTE9d3dgeLrcGXghjadi2rOBGCuqPQEBndLldsBfgQMrrC3ri7Gi2rL25R5K040EFkfEyxGxEZgGjC9zTA0ZD9yULt8EHNXSAUTEw8DbdTbXF9d4YFpEvB8RrwCLSdq8HDHWpywxAkTE8oh4Jl1eCywEelJB7dlAjPUp1/c8ImJdutoufQWV1Zb1xVifsv1sgoe8itETWJqzXkPDvywtKYD7JT0taXK6bfeIWA7JLzrQrWzRba2+uCqtfc+S9Gw6JFY79FERMUrqC3yC5L/WimzPOjFChbWnpDaS5gErgAciouLasp4YocLaEpxQiqE82yrl3uvPRMRwYBxwpqTR5Q6oCJXUvlcB/YFhwHLgl+n2sscoqRPwP8C3ImJNQ0XzbGuRWPPEWHHtGRFbImIY0AsYKWloA8XLEmc9MVZcW4ITSjFqgN45672AZWWKZSsRsSz9ugK4k6Sr+6ak7gDp1xXli3Ar9cVVMe0bEW+mv8wfANfy4dBBWWOU1I7kD/XvIuKOdHNFtWe+GCu1PdPYVgMPAWOpsLbMF2OltqUTStM9BQyQ1E9Se+AEYHqZY0JSR0mda5eBw4EFJLGdkhY7BbirPBF+RH1xTQdOkLSdpH7AAODJMsRX+8ek1tEk7QlljFGSgN8CCyPi0pxdFdOe9cVYae0pqaukLuny9sDngb9TWW2ZN8ZKa8t/aqmr/9vSCziC5M6Vl4CLyh1PGtNeJHd3zAeer40L2BWYCbyYft2lDLHdRtIt30TyH9SkhuICLkrbdhEwrowx3gI8BzxL8ovavZwxpuc9iGQI41lgXvo6opLas4EYK6o9gf2AuWk8C4Dvp9srqS3ri7Gi2rL25alXzMwsEx7yMjOzTDihmJlZJpxQzMwsE04oZmaWCScUMzPLhBOKWQYkdZH0bznrPSTd3kznOkrS9+vZty792lXSvc1xfrP6OKGYZaML8M+EEhHLIuLYZjrXecBvGioQESuB5ZI+00wxmH2EE4pZNqYA/dNnU/xCUl+lz1aRdKqkP0r6k6RXJJ0l6duS5kp6QtIuabn+ku5NJ/d8RNLAuieRtA/wfkS8la73k/S4pKck/bhO8T8CJzXruzbL4YRilo0LgJciYlhEfCfP/qHAiSRzLv0EWB8RnwAeB76SlrkG+GZEHACcS/5eyGeAZ3LWpwJXRcQngTfqlJ0DfLbI92PWZG3LHYBZKzE7kmeDrJX0D+BP6fbngP3SmXk/Dfx3MhUWkDwkqa7uwMqc9c8AE9LlW4Cf5exbAfTIJnyzxjmhmLWM93OWP8hZ/4Dk9/BjwOpIpilvyHvATnW21Td/Uoe0vFmL8JCXWTbWkjzutiiRPC/kFUnHQTJjr6T98xRdCOyds/4oyYzX8NHrJfvw4Sy0Zs3OCcUsAxGxCnhU0gJJvyiympOASZJqZ4zO92jph4FP6MNxsbNJHqb2FB/tuRwK/LnIWMyazLMNm1UZSVOBP0XEg42UexgYHxHvtExk1tq5h2JWfX4K7NBQAUldgUudTKwluYdiZmaZcA/FzMwy4YRiZmaZcEIxM7NMOKGYmVkmnFDMzCwT/x/kw0LaLC7BZwAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] @@ -660,7 +609,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -695,7 +644,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ "
" ] @@ -726,9 +675,9 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3", + "display_name": "swiftestOOF", "language": "python", - "name": "python3" + "name": "swiftestoof" }, "language_info": { "codemirror_mode": { @@ -740,7 +689,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.6" + "version": "3.7.10" } }, "nbformat": 4, diff --git a/src/main/swiftest_driver.f90 b/src/main/swiftest_driver.f90 index 3c9f3c8ac..b2384757a 100644 --- a/src/main/swiftest_driver.f90 +++ b/src/main/swiftest_driver.f90 @@ -63,7 +63,6 @@ program swiftest_driver call nbody_system%step(param, t, dt) t = t0 + iloop * dt - if (t > tstop) exit !> Evaluate any discards or mergers call nbody_system%discard(param) @@ -85,6 +84,7 @@ program swiftest_driver idump = istep_dump end if end if + if (t > tstop) exit end do !> Dump the final state of the system to file diff --git a/src/whm/whm_getacch.f90 b/src/whm/whm_getacch.f90 index 7985fac5f..67ecc7487 100644 --- a/src/whm/whm_getacch.f90 +++ b/src/whm/whm_getacch.f90 @@ -64,7 +64,7 @@ module subroutine whm_getacch_tp(self, system, param, t, xhp) do i = 1, ntp tp%ah(:, i) = ah0(:) end do - call whm_getacch_ah3_tp(system) + call whm_getacch_ah3_tp(system, xhp) if (param%loblatecb) call tp%obl_acc(cb) if (param%lextra_force) call tp%user_getacch(system, param, t) if (param%lgr) call tp%gr_getacch(param) @@ -141,13 +141,13 @@ pure subroutine whm_getacch_ah2(cb, pl) real(DP) :: etaj, fac real(DP), dimension(NDIM) :: ah2, ah2o - associate(npl => pl%nbody, GMcb => cb%Gmass) + associate(npl => pl%nbody) ah2(:) = 0.0_DP ah2o(:) = 0.0_DP - etaj = GMcb + etaj = cb%Gmass do i = 2, npl etaj = etaj + pl%Gmass(i - 1) - fac = pl%Gmass(i) * GMcb * pl%ir3j(i) / etaj + fac = pl%Gmass(i) * cb%Gmass * pl%ir3j(i) / etaj ah2(:) = ah2o + fac * pl%xj(:, i) pl%ah(:,i) = pl%ah(:, i) + ah2(:) ah2o(:) = ah2(:) @@ -196,7 +196,7 @@ pure subroutine whm_getacch_ah3(pl) return end subroutine whm_getacch_ah3 - pure subroutine whm_getacch_ah3_tp(system) + pure subroutine whm_getacch_ah3_tp(system, xhp) !! author: David A. Minton !! !! Compute direct cross (third) term heliocentric accelerations of test particles @@ -206,6 +206,7 @@ pure subroutine whm_getacch_ah3_tp(system) 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 @@ -216,7 +217,7 @@ pure subroutine whm_getacch_ah3_tp(system) do i = 1, ntp acc(:) = 0.0_DP do j = 1, npl - dx(:) = tp%xh(:, i) - pl%xh(:, j) + dx(:) = tp%xh(:, i) - xhp(:, j) rji2 = dot_product(dx(:), dx(:)) irij3 = 1.0_DP / (rji2 * sqrt(rji2)) fac = pl%Gmass(j) * irij3 From f8d52a1356df80c62bb3c2090564f966022e3aaf Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 6 Jul 2021 11:00:27 -0400 Subject: [PATCH 11/12] Set planetocentric flag correctly on setup --- src/rmvs/rmvs_setup.f90 | 1 + 1 file changed, 1 insertion(+) diff --git a/src/rmvs/rmvs_setup.f90 b/src/rmvs/rmvs_setup.f90 index 7955fc74a..9d5916f56 100644 --- a/src/rmvs/rmvs_setup.f90 +++ b/src/rmvs/rmvs_setup.f90 @@ -107,6 +107,7 @@ module subroutine rmvs_setup_system(self, param) cb%lplanetocentric = .false. associate(npl => pl%nbody) allocate(pl%planetocentric(npl)) + pl%planetocentric(:)%lplanetocentric = .true. do i = 1, npl allocate(pl%planetocentric(i)%cb, source=cb) allocate(rmvs_pl :: pl%planetocentric(i)%pl) From 27dbf184042e0080bbf8029e086acd95e017033b Mon Sep 17 00:00:00 2001 From: David A Minton Date: Tue, 6 Jul 2021 11:41:07 -0400 Subject: [PATCH 12/12] Fixed problem with planetocentric-specific parameters not being passed properly during an encounter. RMVS now works with oblateness. --- .../9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb | 4 ++-- src/obl/obl.f90 | 6 +++--- src/rmvs/rmvs_getacch.f90 | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb index 197f09290..0a95cb75e 100644 --- a/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb +++ b/examples/rmvs_swifter_comparison/9pl_18tp_encounters/swiftest_rmvs_vs_swifter_rmvs.ipynb @@ -482,7 +482,7 @@ " 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])\n", "Coordinates:\n", " id int64 4\n", - " * time (d) (time (d)) float64 0.0 1.0 2.0 3.0 4.0 ... 363.0 364.0 365.0 366.0
    • id
      ()
      int64
      4
      array(4)
    • time (d)
      (time (d))
      float64
      0.0 1.0 2.0 ... 364.0 365.0 366.0
      array([  0.,   1.,   2., ..., 364., 365., 366.])
  • " ], "text/plain": [ "\n", diff --git a/src/obl/obl.f90 b/src/obl/obl.f90 index 6d1487872..1192189df 100644 --- a/src/obl/obl.f90 +++ b/src/obl/obl.f90 @@ -17,7 +17,7 @@ module subroutine obl_acc_body(self, cb) integer(I4B) :: i real(DP) :: r2, irh, rinv2, t0, t1, t2, t3, fac1, fac2 - associate(n => self%nbody) + associate(n => self%nbody, xh => self%xh, vh => self%vh, ah => self%ah) do i = 1, n r2 = dot_product(self%xh(:, i), self%xh(:, i)) irh = 1.0_DP / sqrt(r2) @@ -26,8 +26,8 @@ module subroutine obl_acc_body(self, cb) t1 = 1.5_DP * cb%j2rp2 t2 = self%xh(3, i) * self%xh(3, i) * rinv2 t3 = 1.875_DP * cb%j4rp4 * rinv2 - fac1 = t0 * (t1 - t3 - (5.0_DP * t1 - (14.0_DP - 21.0_DP * t2) * t3) * t2) - fac2 = 2.0_DP * t0 * (t1 - (2.0_DP - (14.0_DP * t2 / 3.0_DP)) * t3) + fac1 = t0 * (t1 - t3 - (5 * t1 - (14.0_DP - 21.0_DP * t2) * t3) * t2) + fac2 = 2 * t0 * (t1 - (2.0_DP - (14.0_DP * t2 / 3.0_DP)) * t3) self%aobl(:, i) = fac1 * self%xh(:, i) self%aobl(3, i) = fac2 * self%xh(3, i) + self%aobl(3, i) end do diff --git a/src/rmvs/rmvs_getacch.f90 b/src/rmvs/rmvs_getacch.f90 index 8329b580a..dcbf5aff9 100644 --- a/src/rmvs/rmvs_getacch.f90 +++ b/src/rmvs/rmvs_getacch.f90 @@ -31,7 +31,7 @@ module subroutine rmvs_getacch_tp(self, system, param, t, xhp) class is (rmvs_pl) select type (cb => system%cb) class is (rmvs_cb) - associate(xpc => pl%xh, xpct => self%xh) + associate(xpc => pl%xh, xpct => self%xh, apct => self%ah) allocate(xh_original, source=tp%xh) param_planetocen = param ! Temporarily turn off the heliocentric-dependent acceleration terms during an inner encounter @@ -39,7 +39,7 @@ module subroutine rmvs_getacch_tp(self, system, param, t, xhp) param_planetocen%lextra_force = .false. param_planetocen%lgr = .false. ! Now compute the planetocentric values of acceleration - call whm_getacch_tp(tp, system, param, t, xhp) + call whm_getacch_tp(tp, system, param_planetocen, t, xhp) ! Now compute any heliocentric values of acceleration if (tp%lfirst) then