! Copyright 2024 - The Minton Group at Purdue University ! This file is part of Swiftest. ! Swiftest is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License ! as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ! Swiftest is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty ! of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. ! You should have received a copy of the GNU General Public License along with Swiftest. ! If not, see: https://www.gnu.org/licenses. module whm !! author: David A. Minton !! !! Definition of classes and methods specific to the Democratic Heliocentric Method !! Partially adapted from David E. Kaufmann's Swifter module: module_whm.f90 use swiftest implicit none public !> Swiftest central body particle class type, extends(swiftest_cb) :: whm_cb contains end type whm_cb !> WHM massive body particle class type, extends(swiftest_pl) :: whm_pl real(DP), dimension(:), allocatable :: eta !! Jacobi mass real(DP), dimension(:,:), allocatable :: xj !! Jacobi position real(DP), dimension(:,:), allocatable :: vj !! Jacobi velocity real(DP), dimension(:), allocatable :: muj !! Jacobi mu: GMcb * eta(i) / eta(i - 1) real(DP), dimension(:), allocatable :: ir3j !! Third term of heliocentric acceleration ! 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_util_setup_pl and whm_util_spill_pl contains procedure :: h2j => whm_coord_h2j_pl !! Convert position and velcoity vectors from heliocentric to Jacobi coordinates procedure :: j2h => whm_coord_j2h_pl !! Convert position and velcoity vectors from Jacobi to helliocentric coordinates procedure :: vh2vj => whm_coord_vh2vj_pl !! Convert velocity vectors from heliocentric to Jacobi coordinates procedure :: drift => whm_drift_pl !! Loop through massive bodies and call Danby drift routine to jacobi coordinates procedure :: accel_gr => whm_gr_kick_getacch_pl !! Acceleration term arising from the post-Newtonian correction procedure :: gr_pos_kick => whm_gr_p4_pl !! Position kick due to p**4 term in the post-Newtonian correction procedure :: accel => whm_kick_getacch_pl !! Compute heliocentric accelerations of massive bodies procedure :: kick => whm_kick_vh_pl !! Kick heliocentric velocities of massive bodies procedure :: append => whm_util_append_pl !! Appends elements from one structure to another procedure :: dealloc => whm_util_dealloc_pl !! Deallocates all allocatable arrays procedure :: fill => whm_util_fill_pl !! "Fills" bodies from one object into another depending on the results of a mask (uses the UNPACK intrinsic) procedure :: resize => whm_util_resize_pl !! Checks the current size of a Swiftest body against the requested size and resizes it if it is too small. procedure :: set_ir3 => whm_util_set_ir3j !! Sets both the heliocentric and jacobi inverse radius terms (1/rj**3 and 1/rh**3) procedure :: set_mu => whm_util_set_mu_eta_pl !! Sets the Jacobi mass value for all massive bodies. procedure :: sort => whm_util_sort_pl !! Sort a WHM massive body object in-place. procedure :: rearrange => whm_util_sort_rearrange_pl !! Rearranges the order of array elements of body based on an input index array. Used in sorting methods procedure :: spill => whm_util_spill_pl !! "Spills" bodies from one object to another depending on the results of a mask (uses the PACK intrinsic) procedure :: setup => whm_util_setup_pl !! Constructor method - Allocates space for the input number of bodiess procedure :: step => whm_step_pl !! Steps the body forward one stepsize final :: whm_final_pl !! Finalizes the WHM massive body object - deallocates all allocatables end type whm_pl !> WHM test particle class type, 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_util_spill_tp contains procedure :: accel_gr => whm_gr_kick_getacch_tp !! Acceleration term arising from the post-Newtonian correction procedure :: gr_pos_kick => whm_gr_p4_tp !! Position kick due to p**4 term in the post-Newtonian correction procedure :: accel => whm_kick_getacch_tp !! Compute heliocentric accelerations of test particles procedure :: kick => whm_kick_vh_tp !! Kick heliocentric velocities of test particles procedure :: step => whm_step_tp !! Steps the particle forward one stepsize final :: whm_final_tp !! Finalizes the WHM test particle object - deallocates all allocatables end type whm_tp !> An abstract class for the WHM integrator nbody system type, extends(swiftest_nbody_system) :: whm_nbody_system contains ! Replace the abstract procedures with concrete ones procedure :: initialize => whm_util_setup_initialize_system !! Performs WHM-specific initilization steps, like calculating the Jacobi masses procedure :: step => whm_step_system !! Advance the WHM nbody system forward in time by one step final :: whm_final_system !! Finalizes the WHM nbody_system object - deallocates all allocatables end type whm_nbody_system interface module subroutine whm_coord_h2j_pl(self, 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 end subroutine whm_coord_h2j_pl module subroutine whm_coord_j2h_pl(self, 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 end subroutine whm_coord_j2h_pl module subroutine whm_coord_vh2vj_pl(self, 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 end subroutine whm_coord_vh2vj_pl module subroutine whm_drift_pl(self, nbody_system, param, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: nbody_system !! WHM nbody system object class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Stepsize end subroutine whm_drift_pl !> Get heliocentric accelration of massive bodies module subroutine whm_kick_getacch_pl(self, nbody_system, param, t, lbeg) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_nbody_system), intent(inout) :: nbody_system !! WHM nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current simulation time logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step end subroutine whm_kick_getacch_pl !> Get heliocentric accelration of the test particle module subroutine whm_kick_getacch_tp(self, nbody_system, param, t, lbeg) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: nbody_system !! WHM nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time logical, intent(in) :: lbeg !! Logical flag that determines whether or not this is the beginning or end of the step end subroutine whm_kick_getacch_tp module subroutine whm_kick_vh_pl(self, nbody_system, param, t, dt, lbeg) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. end subroutine whm_kick_vh_pl module subroutine whm_kick_vh_tp(self, nbody_system, param, t, dt, lbeg) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Current time real(DP), intent(in) :: dt !! Stepsize logical, intent(in) :: lbeg !! Logical flag indicating whether this is the beginning of the half step or not. end subroutine whm_kick_vh_tp pure module subroutine whm_gr_kick_getacch_pl(self, param) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body particle data structure class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine whm_gr_kick_getacch_pl pure module subroutine whm_gr_kick_getacch_tp(self, param) 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_kick_getacch_tp pure module subroutine whm_gr_p4_pl(self, nbody_system, param, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_pl pure module subroutine whm_gr_p4_tp(self, nbody_system, param, dt) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters real(DP), intent(in) :: dt !! Step size end subroutine whm_gr_p4_tp !> Reads WHM massive body object in from file module subroutine whm_util_setup_pl(self, n, param) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body objectobject integer(I4B), intent(in) :: n !! Number of particles to allocate space for class(swiftest_parameters), intent(in) :: param !! Current run configuration parameters end subroutine whm_util_setup_pl module subroutine whm_util_setup_initialize_system(self, system_history, param) implicit none class(whm_nbody_system), intent(inout) :: self !! WHM nbody system object class(swiftest_storage), allocatable, intent(inout) :: system_history !! Stores the system history between output dumps class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters end subroutine whm_util_setup_initialize_system module subroutine whm_step_pl(self, nbody_system, param, t, dt) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest 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 whm_step_pl module subroutine whm_step_system(self, param, t, dt) implicit none class(whm_nbody_system), intent(inout) :: self !! WHM 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 whm_step_system module subroutine whm_step_tp(self, nbody_system, param, t, dt) implicit none class(whm_tp), intent(inout) :: self !! WHM test particle data structure class(swiftest_nbody_system), intent(inout) :: nbody_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_util_append_pl(self, source, lsource_mask) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_body), intent(in) :: source !! Source object to append logical, dimension(:), intent(in) :: lsource_mask !! Logical mask indicating which elements to append to end subroutine whm_util_append_pl module subroutine whm_util_dealloc_pl(self) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object end subroutine whm_util_dealloc_pl module subroutine whm_util_spill_pl(self, discards, lspill_list, ldestructive) implicit none class(whm_pl), intent(inout) :: self !! WHM 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, intent(in) :: ldestructive !! Logical flag indicating whether or not this operation should alter the keeps array or not end subroutine whm_util_spill_pl module subroutine whm_util_fill_pl(self, inserts, lfill_list) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object class(swiftest_body), intent(in) :: inserts !! inserted object logical, dimension(:), intent(in) :: lfill_list !! Logical array of bodies to merge into the keeps end subroutine whm_util_fill_pl module subroutine whm_util_resize_pl(self, nnew) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object integer(I4B), intent(in) :: nnew !! New size neded end subroutine whm_util_resize_pl module subroutine whm_util_set_ir3j(self) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object end subroutine whm_util_set_ir3j module subroutine whm_util_set_mu_eta_pl(self, 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_util_set_mu_eta_pl module subroutine whm_util_sort_pl(self, sortby, ascending) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object character(*), intent(in) :: sortby !! Sorting attribute logical, intent(in) :: ascending !! Logical flag indicating whether or not the sorting should be in ascending or descending order end subroutine whm_util_sort_pl module subroutine whm_util_sort_rearrange_pl(self, ind) implicit none class(whm_pl), intent(inout) :: self !! WHM massive body object integer(I4B), dimension(:), intent(in) :: ind !! Index array used to restructure the body (should contain all 1:n index values in the desired order) end subroutine whm_util_sort_rearrange_pl end interface #ifdef COARRAY interface coclone module procedure whm_coarray_coclone_tp end interface interface cocollect module procedure whm_coarray_cocollect_tp end interface #endif contains subroutine whm_final_pl(self) !! author: David A. Minton !! !! Finalize the WHM massive body object - deallocates all allocatables implicit none ! Argument type(whm_pl), intent(inout) :: self !! WHM massive body object call self%dealloc() return end subroutine whm_final_pl subroutine whm_final_system(self) !! author: David A. Minton !! !! Finalize the WHM nbody system object - deallocates all allocatables implicit none ! Arguments type(whm_nbody_system), intent(inout) :: self !! WHM nbody system object call self%dealloc() return end subroutine whm_final_system subroutine whm_final_tp(self) !! author: David A. Minton !! !! Finalize the WHM test particle object - deallocates all allocatables implicit none ! Arguments type(whm_tp), intent(inout) :: self !! WHM test particle object call self%dealloc() return end subroutine whm_final_tp #ifdef COARRAY subroutine whm_coarray_coclone_tp(tp) !! author: David A. Minton !! !! Broadcasts the image 1 object to all other images in a coarray implicit none ! Arguments type(whm_tp),intent(inout),codimension[*] :: tp !! WHM tp object call co_broadcast(tp%lfirst,1) call co_broadcast(tp%nbody,1) call coclone(tp%id) call coclone(tp%info) call coclone(tp%lmask) call coclone(tp%status) call coclone(tp%ldiscard) call coclone(tp%lcollision) call coclone(tp%lencounter) call coclone(tp%mu) call coclone(tp%rh) call coclone(tp%vh) call coclone(tp%rb) call coclone(tp%vb) call coclone(tp%ah) call coclone(tp%aobl) call coclone(tp%agr) call coclone(tp%atide) call coclone(tp%isperi) call coclone(tp%peri) call coclone(tp%atp) call coclone(tp%a) call coclone(tp%e) call coclone(tp%inc) call coclone(tp%capom) call coclone(tp%omega) call coclone(tp%capm) call coclone(tp%nplenc) return end subroutine whm_coarray_coclone_tp subroutine whm_coarray_cocollect_tp(tp) !! author: David A. Minton !! !! Collects all object array components from all images and combines them into the image 1 object implicit none ! Arguments type(whm_tp),intent(inout),codimension[*] :: tp !! Swiftest body object call co_sum(tp%npltp,1) call cocollect(tp%nplenc) call co_sum(tp%nbody,1) call cocollect(tp%id) call cocollect(tp%info) call cocollect(tp%lmask) call cocollect(tp%status) call cocollect(tp%ldiscard) call cocollect(tp%lcollision) call cocollect(tp%lencounter) call cocollect(tp%mu) call cocollect(tp%rh) call cocollect(tp%vh) call cocollect(tp%rb) call cocollect(tp%vb) call cocollect(tp%ah) call cocollect(tp%aobl) call cocollect(tp%agr) call cocollect(tp%atide) call cocollect(tp%ir3h) call cocollect(tp%isperi) call cocollect(tp%peri) call cocollect(tp%atp) call cocollect(tp%a) call cocollect(tp%e) call cocollect(tp%inc) call cocollect(tp%capom) call cocollect(tp%omega) call cocollect(tp%capm) return end subroutine whm_coarray_cocollect_tp #endif end module whm