diff --git a/src/collision/collision_generate.f90 b/src/collision/collision_generate.f90 index d89353e44..f646c45ea 100644 --- a/src/collision/collision_generate.f90 +++ b/src/collision/collision_generate.f90 @@ -8,11 +8,57 @@ !! You should have received a copy of the GNU General Public License along with Swiftest. !! If not, see: https://www.gnu.org/licenses. -submodule(collision) s_collision_model +submodule(collision) s_collision_generate use swiftest contains - module subroutine collision_generate_merge_system(self, nbody_system, param, t) + module subroutine collision_generate_hitandrun(collider, nbody_system, param, t) + !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton + !! + !! Create the fragments resulting from a non-catastrophic hit-and-run collision + !! + implicit none + ! Arguments + class(collision_merge), intent(inout) :: collider !! Fraggle collision system object + class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object + class(base_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions + real(DP), intent(in) :: t !! Time of collision + ! Internals + integer(I4B) :: i, ibiggest, nfrag, jtarg, jproj + logical :: lpure + character(len=STRMAX) :: message + real(DP) :: dpe + + select type(nbody_system) + class is (swiftest_nbody_system) + select type (pl => nbody_system%pl) + class is (swiftest_pl) + select type(before => collider%after) + class is (swiftest_nbody_system) + select type(after => collider%after) + class is (swiftest_nbody_system) + associate(impactors => collider%impactors, fragments => collider%fragments, pl => nbody_system%pl) + message = "Hit and run between" + call collision_io_collider_message(nbody_system%pl, impactors%id, message) + call swiftest_io_log_one_message(COLLISION_LOG_OUT, trim(adjustl(message))) + + collider%status = HIT_AND_RUN_PURE + pl%status(impactors%id(:)) = ACTIVE + pl%ldiscard(impactors%id(:)) = .false. + pl%lcollision(impactors%id(:)) = .false. + allocate(after%pl, source=before%pl) ! Be sure to save the pl so that snapshots still work + end associate + end select + end select + end select + end select + + + return + end subroutine collision_generate_hitandrun + + + module subroutine collision_generate_merge(self, nbody_system, param, t) !! author: Jennifer L.L. Pouplin, Carlisle A. Wishard, and David A. Minton !! !! Merge massive bodies in any collisionals ystem. @@ -22,7 +68,7 @@ module subroutine collision_generate_merge_system(self, nbody_system, param, t) !! Adapted from Hal Levison's Swift routines symba5_merge.f and discard_mass_merge.f implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Merge fragment system object + class(collision_merge), intent(inout) :: self !! Merge fragment system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision @@ -106,23 +152,49 @@ module subroutine collision_generate_merge_system(self, nbody_system, param, t) end associate end select return - end subroutine collision_generate_merge_system + end subroutine collision_generate_merge - module subroutine collision_generate_bounce_system(self, nbody_system, param, t) + module subroutine collision_generate_bounce(self, nbody_system, param, t) + !! author: David A. Minton + !! + !! In this collision model, if the collision would result in a disruption, the bodies are instead "bounced" off + !! of the center of mass. This is done as a reflection in the 2-body equivalent distance vector direction. implicit none + ! Arguments class(collision_bounce), intent(inout) :: self !! Bounce fragment system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - end subroutine collision_generate_bounce_system + ! Internals + integer(I4B) :: nfrag + + select type(nbody_system) + class is (swiftest_nbody_system) + associate(impactors => nbody_system%collider%impactors, fragments => nbody_system%collider%fragments) + select case (impactors%regime) + case (COLLRESOLVE_REGIME_DISRUPTION, COLLRESOLVE_REGIME_SUPERCATASTROPHIC) + nfrag = size(impactors%id(:)) + case (COLLRESOLVE_REGIME_HIT_AND_RUN) + call collision_generate_hitandrun(self, nbody_system, param, t) + case (COLLRESOLVE_REGIME_MERGE, COLLRESOLVE_REGIME_GRAZE_AND_MERGE) + call self%collision_merge%generate(nbody_system, param, t) ! Use the default collision model, which is merge + case default + write(*,*) "Error in swiftest_collision, unrecognized collision regime" + call util_exit(FAILURE) + end select + end associate + end select + + return + end subroutine collision_generate_bounce - module subroutine collision_generate_simple_system(self, nbody_system, param, t) + module subroutine collision_generate_simple(self, nbody_system, param, t) implicit none class(collision_simple), intent(inout) :: self !! Simple fragment system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - end subroutine collision_generate_simple_system + end subroutine collision_generate_simple -end submodule s_collision_model \ No newline at end of file +end submodule s_collision_generate \ No newline at end of file diff --git a/src/collision/collision_io.f90 b/src/collision/collision_io.f90 index 0eccda309..1a11bf43a 100644 --- a/src/collision/collision_io.f90 +++ b/src/collision/collision_io.f90 @@ -51,7 +51,7 @@ module subroutine collision_io_log_regime(self) !! Writes a log of the results of the collisional regime determination implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Collision system object + class(collision_merge), intent(inout) :: self !! Collision system object ! Internals character(STRMAX) :: errmsg diff --git a/src/collision/collision_module.f90 b/src/collision/collision_module.f90 index 5e1166ea3..494855d12 100644 --- a/src/collision/collision_module.f90 +++ b/src/collision/collision_module.f90 @@ -110,11 +110,11 @@ module collision end type collision_fragments - type :: collision_system + type :: collision_merge !! This class defines a collisional nbody_system that stores impactors and fragments. This is written so that various collision models (i.e. Fraggle) could potentially be used !! to resolve collision by defining extended types of encounters_impactors and/or encounetr_fragments !! - !! The generate method for this class is the merge model. This allows any extended type to have access to the merge procedure by selecting the collision_system parent class + !! The generate method for this class is the merge model. This allows any extended type to have access to the merge procedure by selecting the collision_merge parent class class(collision_fragments(:)), allocatable :: fragments !! Object containing information on the pre-collision system class(collision_impactors), allocatable :: impactors !! Object containing information on the post-collision system class(base_nbody_system), allocatable :: before !! A snapshot of the subset of the nbody_system involved in the collision @@ -138,19 +138,19 @@ module collision procedure :: get_energy_and_momentum => collision_util_get_energy_momentum !! Calculates total nbody_system energy in either the pre-collision outcome state (lbefore = .true.) or the post-collision outcome state (lbefore = .false.) procedure :: reset => collision_util_reset_system !! Deallocates all allocatables procedure :: set_coordinate_system => collision_util_set_coordinate_system !! Sets the coordinate nbody_system of the collisional nbody_system - procedure :: generate => collision_generate_merge_system !! Merges the impactors to make a single final body - end type collision_system + procedure :: generate => collision_generate_merge !! Merges the impactors to make a single final body + end type collision_merge - type, extends(collision_system) :: collision_bounce + type, extends(collision_merge) :: collision_bounce contains - procedure :: generate => collision_generate_bounce_system !! If a collision would result in a disruption, "bounce" the bodies instead. - final :: collision_final_bounce_system !! Finalizer will deallocate all allocatables + procedure :: generate => collision_generate_bounce !! If a collision would result in a disruption, "bounce" the bodies instead. + final :: collision_final_bounce !! Finalizer will deallocate all allocatables end type collision_bounce - type, extends(collision_system) :: collision_simple + type, extends(collision_merge) :: collision_simple contains - procedure :: generate => collision_generate_simple_system !! If a collision would result in a disruption [TODO: SOMETHING LIKE CHAMBERS 2012] - final :: collision_final_simple_system !! Finalizer will deallocate all allocatables + procedure :: generate => collision_generate_simple !! If a collision would result in a disruption [TODO: SOMETHING LIKE CHAMBERS 2012] + final :: collision_final_simple !! Finalizer will deallocate all allocatables end type collision_simple @@ -178,7 +178,7 @@ module collision type, extends(encounter_snapshot) :: collision_snapshot logical :: lcollision !! Indicates that this snapshot contains at least one collision - class(collision_system), allocatable :: collider !! Collider object at this snapshot + class(collision_merge), allocatable :: collider !! Collider object at this snapshot contains procedure :: write_frame => collision_io_netcdf_write_frame_snapshot !! Writes a frame of encounter data to file procedure :: get_idvals => collision_util_get_idvalues_snapshot !! Gets an array of all id values saved in this snapshot @@ -197,29 +197,38 @@ module collision interface - module subroutine collision_generate_merge_system(self, nbody_system, param, t) + + module subroutine collision_generate_hitandrun(collider, nbody_system, param, t) + implicit none + class(collision_merge), intent(inout) :: collider !! Merge (or extended) collision system object + class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object + class(base_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions + real(DP), intent(in) :: t !! Time of collision + end subroutine collision_generate_hitandrun + + module subroutine collision_generate_merge(self, nbody_system, param, t) implicit none - class(collision_system), intent(inout) :: self !! Merge fragment nbody_system object + class(collision_merge), intent(inout) :: self !! Merge fragment nbody_system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - end subroutine collision_generate_merge_system + end subroutine collision_generate_merge - module subroutine collision_generate_bounce_system(self, nbody_system, param, t) + module subroutine collision_generate_bounce(self, nbody_system, param, t) implicit none class(collision_bounce), intent(inout) :: self !! Bounce fragment nbody_system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - end subroutine collision_generate_bounce_system + end subroutine collision_generate_bounce - module subroutine collision_generate_simple_system(self, nbody_system, param, t) + module subroutine collision_generate_simple(self, nbody_system, param, t) implicit none class(collision_simple), intent(inout) :: self !! Simple fragment nbody_system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - end subroutine collision_generate_simple_system + end subroutine collision_generate_simple module subroutine collision_io_collider_message(pl, collidx, collider_message) implicit none @@ -230,7 +239,7 @@ end subroutine collision_io_collider_message module subroutine collision_io_log_regime(self) implicit none - class(collision_system), intent(inout) :: self !! Collision system object + class(collision_merge), intent(inout) :: self !! Collision system object end subroutine collision_io_log_regime module subroutine collision_io_netcdf_dump(self, param) @@ -339,36 +348,36 @@ end subroutine collision_resolve_pltp module subroutine collision_util_set_coordinate_system(self) implicit none - class(collision_system), intent(inout) :: self !! Collisional nbody_system + class(collision_merge), intent(inout) :: self !! Collisional nbody_system end subroutine collision_util_set_coordinate_system module subroutine collision_setup_system(self, nbody_system) implicit none - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object class(base_nbody_system), intent(in) :: nbody_system !! Current nbody system. Used as a mold for the before/after snapshots end subroutine collision_setup_system module subroutine collision_setup_impactors_system(self) implicit none - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object end subroutine collision_setup_impactors_system module subroutine collision_setup_fragments_system(self, nfrag) implicit none - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object integer(I4B), intent(in) :: nfrag !! Number of fragments to create end subroutine collision_setup_fragments_system module subroutine collision_util_add_fragments_to_system(self, nbody_system, param) implicit none - class(collision_system), intent(in) :: self !! Collision system object + class(collision_merge), intent(in) :: self !! Collision system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters end subroutine collision_util_add_fragments_to_system module subroutine collision_util_construct_temporary_system(self, nbody_system, param, tmpsys, tmpparam) implicit none - class(collision_system), intent(inout) :: self !! Collision system object + class(collision_merge), intent(inout) :: self !! Collision system object class(base_nbody_system), intent(in) :: nbody_system !! Original swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters class(base_nbody_system), allocatable, intent(out) :: tmpsys !! Output temporary swiftest nbody system object @@ -389,7 +398,7 @@ end subroutine collision_util_get_idvalues_snapshot module subroutine collision_util_get_energy_momentum(self, nbody_system, param, lbefore) use base, only : base_nbody_system, base_parameters implicit none - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current swiftest run configuration parameters logical, intent(in) :: lbefore !! Flag indicating that this the "before" state of the nbody_system, with impactors included and fragments excluded or vice versa @@ -407,7 +416,7 @@ end subroutine collision_util_reset_impactors module subroutine collision_util_reset_system(self) implicit none - class(collision_system), intent(inout) :: self !! Collision system object + class(collision_merge), intent(inout) :: self !! Collision system object end subroutine collision_util_reset_system module subroutine collision_util_snapshot(self, param, nbody_system, t, arg) @@ -523,7 +532,7 @@ subroutine collision_final_storage(self) end subroutine collision_final_storage - subroutine collision_final_bounce_system(self) + subroutine collision_final_bounce(self) !! author: David A. Minton !! !! Finalizer will deallocate all allocatables @@ -536,10 +545,10 @@ subroutine collision_final_bounce_system(self) if (allocated(self%fragments)) deallocate(self%fragments) return - end subroutine collision_final_bounce_system + end subroutine collision_final_bounce - subroutine collision_final_simple_system(self) + subroutine collision_final_simple(self) !! author: David A. Minton !! !! Finalizer will deallocate all allocatables @@ -552,9 +561,7 @@ subroutine collision_final_simple_system(self) if (allocated(self%fragments)) deallocate(self%fragments) return - end subroutine collision_final_simple_system - - + end subroutine collision_final_simple end module collision diff --git a/src/collision/collision_resolve.f90 b/src/collision/collision_resolve.f90 index f4ade21b7..d7eff07eb 100644 --- a/src/collision/collision_resolve.f90 +++ b/src/collision/collision_resolve.f90 @@ -323,7 +323,7 @@ module subroutine collision_resolve_mergeaddsub(nbody_system, param, t, status) select type(param) class is (swiftest_parameters) associate(pl => nbody_system%pl, pl_discards => nbody_system%pl_discards, info => nbody_system%pl%info, pl_adds => nbody_system%pl_adds, cb => nbody_system%cb, npl => pl%nbody, & - collision_system => nbody_system%collider, impactors => nbody_system%collider%impactors,fragments => nbody_system%collider%fragments) + collision_merge => nbody_system%collider, impactors => nbody_system%collider%impactors,fragments => nbody_system%collider%fragments) ! Add the impactors%id bodies to the subtraction list nimpactors = impactors%ncoll @@ -437,7 +437,7 @@ module subroutine collision_resolve_mergeaddsub(nbody_system, param, t, status) end where ! Log the properties of the new bodies - select type(after => collision_system%after) + select type(after => collision_merge%after) class is (swiftest_nbody_system) allocate(after%pl, source=plnew) end select diff --git a/src/collision/collision_setup.f90 b/src/collision/collision_setup.f90 index d3be371d3..5b621a44f 100644 --- a/src/collision/collision_setup.f90 +++ b/src/collision/collision_setup.f90 @@ -18,7 +18,7 @@ module subroutine collision_setup_system(self, nbody_system) !! but not fragments. Those are setup later when the number of fragments is known. implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object class(base_nbody_system), intent(in) :: nbody_system !! Current nbody system. Used as a mold for the before/after snapshots call self%setup_impactors() @@ -38,7 +38,7 @@ module subroutine collision_setup_impactors_system(self) !! Initializer for the impactors for the encounter collision system. Deallocates old impactors before creating new ones implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object if (allocated(self%impactors)) deallocate(self%impactors) allocate(collision_impactors :: self%impactors) @@ -53,7 +53,7 @@ module subroutine collision_setup_fragments_system(self, nfrag) !! Initializer for the fragments of the collision system. implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object integer(I4B), intent(in) :: nfrag !! Number of fragments to create if (allocated(self%fragments)) deallocate(self%fragments) diff --git a/src/collision/collision_util.f90 b/src/collision/collision_util.f90 index c2d3a1924..4474544c1 100644 --- a/src/collision/collision_util.f90 +++ b/src/collision/collision_util.f90 @@ -17,7 +17,7 @@ module subroutine collision_util_add_fragments_to_system(self, nbody_system, par !! Adds fragments to the temporary system pl object implicit none ! Arguments - class(collision_system), intent(in) :: self !! Collision system system object + class(collision_merge), intent(in) :: self !! Collision system system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters ! Internals @@ -67,7 +67,7 @@ module subroutine collision_util_construct_temporary_system(self, nbody_system, !! Constructs a temporary internal system consisting of active bodies and additional fragments. This internal temporary system is used to calculate system energy with and without fragments implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Fraggle collision system object + class(collision_merge), intent(inout) :: self !! Fraggle collision system object class(base_nbody_system), intent(in) :: nbody_system !! Original swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters class(base_nbody_system), allocatable, intent(out) :: tmpsys !! Output temporary swiftest nbody system object @@ -180,7 +180,7 @@ module subroutine collision_util_get_energy_momentum(self, nbody_system, param, !! This will temporarily expand the massive body object in a temporary system object called tmpsys to feed it into symba_energy implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Encounter collision system object + class(collision_merge), intent(inout) :: self !! Encounter collision system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current swiftest run configuration parameters logical, intent(in) :: lbefore !! Flag indicating that this the "before" state of the nbody_system, with impactors included and fragments excluded or vice versa @@ -349,7 +349,7 @@ module subroutine collision_util_reset_system(self) !! Resets the collider nbody_system and deallocates all allocatables implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Collision system object + class(collision_merge), intent(inout) :: self !! Collision system object if (allocated(self%before)) deallocate(self%before) if (allocated(self%after)) deallocate(self%after) @@ -375,7 +375,7 @@ module subroutine collision_util_set_coordinate_system(self) !! Defines the collisional coordinate nbody_system, including the unit vectors of both the nbody_system and individual fragments. implicit none ! Arguments - class(collision_system), intent(inout) :: self !! Collisional nbody_system + class(collision_merge), intent(inout) :: self !! Collisional nbody_system ! Internals integer(I4B) :: i real(DP), dimension(NDIM) :: delta_r, delta_v, Ltot diff --git a/src/fraggle/fraggle_generate.f90 b/src/fraggle/fraggle_generate.f90 index a85c783aa..d7d3766a0 100644 --- a/src/fraggle/fraggle_generate.f90 +++ b/src/fraggle/fraggle_generate.f90 @@ -25,7 +25,7 @@ module subroutine fraggle_generate_disruption(collider, nbody_system, param, t) !! implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider + class(collision_fraggle), intent(inout) :: collider class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions real(DP), intent(in) :: t !! Time of collision @@ -102,7 +102,7 @@ module subroutine fraggle_generate_hitandrun(collider, nbody_system, param, t) !! implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions real(DP), intent(in) :: t !! Time of collision @@ -180,12 +180,10 @@ end subroutine fraggle_generate_hitandrun module subroutine fraggle_generate_system(self, nbody_system, param, t) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle fragment nbody_system object + class(collision_fraggle), intent(inout) :: self !! Fraggle fragment nbody_system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! The time of the collision - ! Internals - integer(I4B) :: i select type(nbody_system) class is (swiftest_nbody_system) @@ -197,7 +195,7 @@ module subroutine fraggle_generate_system(self, nbody_system, param, t) case (COLLRESOLVE_REGIME_HIT_AND_RUN) call fraggle_generate_hitandrun(self, nbody_system, param, t) case (COLLRESOLVE_REGIME_MERGE, COLLRESOLVE_REGIME_GRAZE_AND_MERGE) - call self%collision_system%generate(nbody_system, param, t) + call self%collision_merge%generate(nbody_system, param, t) case default write(*,*) "Error in swiftest_collision, unrecognized collision regime" call util_exit(FAILURE) @@ -216,7 +214,7 @@ module subroutine fraggle_generate_fragments(collider, nbody_system, param, lfai use, intrinsic :: ieee_exceptions implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle nbody_system object the outputs will be the fragmentation + class(collision_fraggle), intent(inout) :: collider !! Fraggle nbody_system object the outputs will be the fragmentation class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters logical, intent(out) :: lfailure !! Answers the question: Should this have been a merger instead? @@ -377,7 +375,7 @@ subroutine fraggle_generate_pos_vec(collider, r_max_start) !! The initial positions do not conserve energy or momentum, so these need to be adjusted later. implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object real(DP), intent(in) :: r_max_start !! Initial guess for the starting maximum radial distance of fragments ! Internals real(DP) :: dis, rad, r_max, fdistort @@ -460,7 +458,7 @@ subroutine fraggle_generate_spins(collider, f_spin, lfailure) !! A failure will trigger a restructuring of the fragments so we will try new values of the radial position distribution. implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object real(DP), intent(in) :: f_spin !! Fraction of energy or momentum that goes into spin (whichever gives the lowest kinetic energy) logical, intent(out) :: lfailure !! Logical flag indicating whether this step fails or succeeds! ! Internals @@ -557,7 +555,7 @@ subroutine fraggle_generate_tan_vel(collider, lfailure) !! A failure will trigger a restructuring of the fragments so we will try new values of the radial position distribution. implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object logical, intent(out) :: lfailure !! Logical flag indicating whether this step fails or succeeds ! Internals integer(I4B) :: i, try @@ -741,7 +739,7 @@ subroutine fraggle_generate_rad_vel(collider, lfailure) !! Adjust the fragment velocities to set the fragment orbital kinetic energy. This will minimize the difference between the fragment kinetic energy and the energy budget implicit none ! Arguments - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object logical, intent(out) :: lfailure !! Logical flag indicating whether this step fails or succeeds! ! Internals real(DP), parameter :: TOL_MIN = FRAGGLE_ETOL ! This needs to be more accurate than the tangential step, as we are trying to minimize the total residual energy diff --git a/src/fraggle/fraggle_module.f90 b/src/fraggle/fraggle_module.f90 index d3bd3c9af..83aaee06b 100644 --- a/src/fraggle/fraggle_module.f90 +++ b/src/fraggle/fraggle_module.f90 @@ -37,7 +37,7 @@ module fraggle end type fraggle_fragments - type, extends(collision_system) :: fraggle_system + type, extends(collision_merge) :: collision_fraggle ! Scale factors used to scale dimensioned quantities to a more "natural" system where important quantities (like kinetic energy, momentum) are of order ~1 real(DP) :: dscale = 1.0_DP !! Distance dimension scale factor real(DP) :: mscale = 1.0_DP !! Mass scale factor @@ -55,68 +55,68 @@ module fraggle procedure :: construct_temporary_system => fraggle_util_construct_temporary_system !! Constructs temporary n-body system in order to compute pre- and post-impact energy and momentum procedure :: reset => fraggle_util_reset_system !! Deallocates all allocatables final :: fraggle_final_system !! Finalizer will deallocate all allocatables - end type fraggle_system + end type collision_fraggle interface + + module subroutine fraggle_generate_disruption(collider, nbody_system, param, t) + implicit none + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object + class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions + real(DP), intent(in) :: t !! Time of collision + end subroutine fraggle_generate_disruption + module subroutine fraggle_generate_fragments(collider, nbody_system, param, lfailure) implicit none - class(fraggle_system), intent(inout) :: collider !! Fraggle system object the outputs will be the fragmentation + class(collision_fraggle), intent(inout) :: collider !! Fraggle system object the outputs will be the fragmentation class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters logical, intent(out) :: lfailure !! Answers the question: Should this have been a merger instead? end subroutine fraggle_generate_fragments + module subroutine fraggle_generate_hitandrun(collider, nbody_system, param, t) + implicit none + class(collision_fraggle), intent(inout) :: collider !! Fraggle collision system object + class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object + class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions + real(DP), intent(in) :: t !! Time of collision + end subroutine fraggle_generate_hitandrun + module subroutine fraggle_generate_system(self, nbody_system, param, t) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle fragment system object + class(collision_fraggle), intent(inout) :: self !! Fraggle fragment system object class(base_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object class(base_parameters), intent(inout) :: param !! Current run configuration parameters real(DP), intent(in) :: t !! Time of collision end subroutine fraggle_generate_system - module subroutine fraggle_set_budgets(self) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object end subroutine fraggle_set_budgets module subroutine fraggle_set_mass_dist(self, param) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object class(swiftest_parameters), intent(in) :: param !! Current Swiftest run configuration parameters end subroutine fraggle_set_mass_dist module subroutine fraggle_set_natural_scale_factors(self) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object end subroutine fraggle_set_natural_scale_factors - module subroutine fraggle_generate_disruption(collider, nbody_system, param, t) - implicit none - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object - class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions - real(DP), intent(in) :: t !! Time of collision - end subroutine fraggle_generate_disruption - - module subroutine fraggle_generate_hitandrun(collider, nbody_system, param, t) - implicit none - class(fraggle_system), intent(inout) :: collider !! Fraggle collision system object - class(swiftest_nbody_system), intent(inout) :: nbody_system !! Swiftest nbody system object - class(swiftest_parameters), intent(inout) :: param !! Current run configuration parameters with SyMBA additions - real(DP), intent(in) :: t !! Time of collision - end subroutine fraggle_generate_hitandrun - module subroutine fraggle_set_original_scale_factors(self) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object end subroutine fraggle_set_original_scale_factors module subroutine fraggle_setup_fragments_system(self, nfrag) implicit none - class(fraggle_system), intent(inout) :: self !! Encounter collision system object + class(collision_fraggle), intent(inout) :: self !! Encounter collision system object integer(I4B), intent(in) :: nfrag !! Number of fragments to create end subroutine fraggle_setup_fragments_system @@ -127,7 +127,7 @@ end subroutine fraggle_util_get_angular_momentum module subroutine fraggle_util_construct_temporary_system(self, nbody_system, param, tmpsys, tmpparam) implicit none - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object class(base_nbody_system), intent(in) :: nbody_system !! Original swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters class(base_nbody_system), allocatable, intent(out) :: tmpsys !! Output temporary swiftest nbody system object @@ -146,7 +146,7 @@ end subroutine fraggle_util_reset_fragments module subroutine fraggle_util_reset_system(self) implicit none - class(fraggle_system), intent(inout) :: self !! Collision system object + class(collision_fraggle), intent(inout) :: self !! Collision system object end subroutine fraggle_util_reset_system module subroutine fraggle_util_restructure(self, impactors, try, f_spin, r_max_start) @@ -198,7 +198,7 @@ subroutine fraggle_final_system(self) !! Finalizer will deallocate all allocatables implicit none ! Arguments - type(fraggle_system), intent(inout) :: self !! Collision impactors storage object + type(collision_fraggle), intent(inout) :: self !! Collision impactors storage object call self%reset() if (allocated(self%impactors)) deallocate(self%impactors) diff --git a/src/fraggle/fraggle_set.f90 b/src/fraggle/fraggle_set.f90 index d466db871..21ba46588 100644 --- a/src/fraggle/fraggle_set.f90 +++ b/src/fraggle/fraggle_set.f90 @@ -18,7 +18,7 @@ module subroutine fraggle_set_budgets(self) !! Sets the energy and momentum budgets of the fragments based on the collider values and the before/after values of energy and momentum implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object ! Internals real(DP) :: dEtot real(DP), dimension(NDIM) :: dL @@ -48,7 +48,7 @@ module subroutine fraggle_set_mass_dist(self, param) !! implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object class(swiftest_parameters), intent(in) :: param !! Current Swiftest run configuration parameters ! Internals integer(I4B) :: i, jproj, jtarg, nfrag, istart @@ -183,39 +183,39 @@ module subroutine fraggle_set_natural_scale_factors(self) !! This scaling makes it easier for the non-linear minimization to converge on a solution implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object ! Internals integer(I4B) :: i - associate(collision_system => self, fragments => self%fragments, impactors => self%impactors) + associate(collision_merge => self, fragments => self%fragments, impactors => self%impactors) ! Set scale factors - collision_system%Escale = 0.5_DP * ( impactors%mass(1) * dot_product(impactors%vb(:,1), impactors%vb(:,1)) & + collision_merge%Escale = 0.5_DP * ( impactors%mass(1) * dot_product(impactors%vb(:,1), impactors%vb(:,1)) & + impactors%mass(2) * dot_product(impactors%vb(:,2), impactors%vb(:,2))) - collision_system%dscale = sum(impactors%radius(:)) - collision_system%mscale = fragments%mtot - collision_system%vscale = sqrt(collision_system%Escale / collision_system%mscale) - collision_system%tscale = collision_system%dscale / collision_system%vscale - collision_system%Lscale = collision_system%mscale * collision_system%dscale * collision_system%vscale + collision_merge%dscale = sum(impactors%radius(:)) + collision_merge%mscale = fragments%mtot + collision_merge%vscale = sqrt(collision_merge%Escale / collision_merge%mscale) + collision_merge%tscale = collision_merge%dscale / collision_merge%vscale + collision_merge%Lscale = collision_merge%mscale * collision_merge%dscale * collision_merge%vscale ! Scale all dimensioned quantities of impactors and fragments - impactors%rbcom(:) = impactors%rbcom(:) / collision_system%dscale - impactors%vbcom(:) = impactors%vbcom(:) / collision_system%vscale - impactors%rbimp(:) = impactors%rbimp(:) / collision_system%dscale - impactors%rb(:,:) = impactors%rb(:,:) / collision_system%dscale - impactors%vb(:,:) = impactors%vb(:,:) / collision_system%vscale - impactors%mass(:) = impactors%mass(:) / collision_system%mscale - impactors%radius(:) = impactors%radius(:) / collision_system%dscale - impactors%Lspin(:,:) = impactors%Lspin(:,:) / collision_system%Lscale - impactors%Lorbit(:,:) = impactors%Lorbit(:,:) / collision_system%Lscale + impactors%rbcom(:) = impactors%rbcom(:) / collision_merge%dscale + impactors%vbcom(:) = impactors%vbcom(:) / collision_merge%vscale + impactors%rbimp(:) = impactors%rbimp(:) / collision_merge%dscale + impactors%rb(:,:) = impactors%rb(:,:) / collision_merge%dscale + impactors%vb(:,:) = impactors%vb(:,:) / collision_merge%vscale + impactors%mass(:) = impactors%mass(:) / collision_merge%mscale + impactors%radius(:) = impactors%radius(:) / collision_merge%dscale + impactors%Lspin(:,:) = impactors%Lspin(:,:) / collision_merge%Lscale + impactors%Lorbit(:,:) = impactors%Lorbit(:,:) / collision_merge%Lscale do i = 1, 2 impactors%rot(:,i) = impactors%Lspin(:,i) / (impactors%mass(i) * impactors%radius(i)**2 * impactors%Ip(3, i)) end do - fragments%mtot = fragments%mtot / collision_system%mscale - fragments%mass = fragments%mass / collision_system%mscale - fragments%radius = fragments%radius / collision_system%dscale - impactors%Qloss = impactors%Qloss / collision_system%Escale + fragments%mtot = fragments%mtot / collision_merge%mscale + fragments%mass = fragments%mass / collision_merge%mscale + fragments%radius = fragments%radius / collision_merge%dscale + impactors%Qloss = impactors%Qloss / collision_merge%Escale end associate return @@ -229,7 +229,7 @@ module subroutine fraggle_set_original_scale_factors(self) use, intrinsic :: ieee_exceptions implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Fraggle fragment system object + class(collision_fraggle), intent(inout) :: self !! Fraggle fragment system object ! Internals integer(I4B) :: i logical, dimension(size(IEEE_ALL)) :: fpe_halting_modes @@ -237,50 +237,50 @@ module subroutine fraggle_set_original_scale_factors(self) call ieee_get_halting_mode(IEEE_ALL,fpe_halting_modes) ! Save the current halting modes so we can turn them off temporarily call ieee_set_halting_mode(IEEE_ALL,.false.) - associate(collision_system => self, fragments => self%fragments, impactors => self%impactors) + associate(collision_merge => self, fragments => self%fragments, impactors => self%impactors) ! Restore scale factors - impactors%rbcom(:) = impactors%rbcom(:) * collision_system%dscale - impactors%vbcom(:) = impactors%vbcom(:) * collision_system%vscale - impactors%rbimp(:) = impactors%rbimp(:) * collision_system%dscale + impactors%rbcom(:) = impactors%rbcom(:) * collision_merge%dscale + impactors%vbcom(:) = impactors%vbcom(:) * collision_merge%vscale + impactors%rbimp(:) = impactors%rbimp(:) * collision_merge%dscale - impactors%mass = impactors%mass * collision_system%mscale - impactors%radius = impactors%radius * collision_system%dscale - impactors%rb = impactors%rb * collision_system%dscale - impactors%vb = impactors%vb * collision_system%vscale - impactors%Lspin = impactors%Lspin * collision_system%Lscale + impactors%mass = impactors%mass * collision_merge%mscale + impactors%radius = impactors%radius * collision_merge%dscale + impactors%rb = impactors%rb * collision_merge%dscale + impactors%vb = impactors%vb * collision_merge%vscale + impactors%Lspin = impactors%Lspin * collision_merge%Lscale do i = 1, 2 impactors%rot(:,i) = impactors%Lspin(:,i) * (impactors%mass(i) * impactors%radius(i)**2 * impactors%Ip(3, i)) end do - fragments%mtot = fragments%mtot * collision_system%mscale - fragments%mass = fragments%mass * collision_system%mscale - fragments%radius = fragments%radius * collision_system%dscale - fragments%rot = fragments%rot / collision_system%tscale - fragments%rc = fragments%rc * collision_system%dscale - fragments%vc = fragments%vc * collision_system%vscale + fragments%mtot = fragments%mtot * collision_merge%mscale + fragments%mass = fragments%mass * collision_merge%mscale + fragments%radius = fragments%radius * collision_merge%dscale + fragments%rot = fragments%rot / collision_merge%tscale + fragments%rc = fragments%rc * collision_merge%dscale + fragments%vc = fragments%vc * collision_merge%vscale do i = 1, fragments%nbody fragments%rb(:, i) = fragments%rc(:, i) + impactors%rbcom(:) fragments%vb(:, i) = fragments%vc(:, i) + impactors%vbcom(:) end do - impactors%Qloss = impactors%Qloss * collision_system%Escale + impactors%Qloss = impactors%Qloss * collision_merge%Escale - collision_system%Lorbit(:,:) = collision_system%Lorbit(:,:) * collision_system%Lscale - collision_system%Lspin(:,:) = collision_system%Lspin(:,:) * collision_system%Lscale - collision_system%Ltot(:,:) = collision_system%Ltot(:,:) * collision_system%Lscale - collision_system%ke_orbit(:) = collision_system%ke_orbit(:) * collision_system%Escale - collision_system%ke_spin(:) = collision_system%ke_spin(:) * collision_system%Escale - collision_system%pe(:) = collision_system%pe(:) * collision_system%Escale - collision_system%Etot(:) = collision_system%Etot(:) * collision_system%Escale + collision_merge%Lorbit(:,:) = collision_merge%Lorbit(:,:) * collision_merge%Lscale + collision_merge%Lspin(:,:) = collision_merge%Lspin(:,:) * collision_merge%Lscale + collision_merge%Ltot(:,:) = collision_merge%Ltot(:,:) * collision_merge%Lscale + collision_merge%ke_orbit(:) = collision_merge%ke_orbit(:) * collision_merge%Escale + collision_merge%ke_spin(:) = collision_merge%ke_spin(:) * collision_merge%Escale + collision_merge%pe(:) = collision_merge%pe(:) * collision_merge%Escale + collision_merge%Etot(:) = collision_merge%Etot(:) * collision_merge%Escale - collision_system%mscale = 1.0_DP - collision_system%dscale = 1.0_DP - collision_system%vscale = 1.0_DP - collision_system%tscale = 1.0_DP - collision_system%Lscale = 1.0_DP - collision_system%Escale = 1.0_DP + collision_merge%mscale = 1.0_DP + collision_merge%dscale = 1.0_DP + collision_merge%vscale = 1.0_DP + collision_merge%tscale = 1.0_DP + collision_merge%Lscale = 1.0_DP + collision_merge%Escale = 1.0_DP end associate call ieee_set_halting_mode(IEEE_ALL,fpe_halting_modes) diff --git a/src/fraggle/fraggle_setup.f90 b/src/fraggle/fraggle_setup.f90 index b612f05b2..65e48718a 100644 --- a/src/fraggle/fraggle_setup.f90 +++ b/src/fraggle/fraggle_setup.f90 @@ -18,7 +18,7 @@ module subroutine fraggle_setup_fragments_system(self, nfrag) !! Initializer for the fragments of the collision system. implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Encounter collision system object + class(collision_fraggle), intent(inout) :: self !! Encounter collision system object integer(I4B), intent(in) :: nfrag !! Number of fragments to create if (allocated(self%fragments)) deallocate(self%fragments) diff --git a/src/fraggle/fraggle_util.f90 b/src/fraggle/fraggle_util.f90 index b8f6ef57d..07b5eef50 100644 --- a/src/fraggle/fraggle_util.f90 +++ b/src/fraggle/fraggle_util.f90 @@ -42,7 +42,7 @@ module subroutine fraggle_util_construct_temporary_system(self, nbody_system, pa !! Constructs a temporary internal system consisting of active bodies and additional fragments. This internal temporary system is used to calculate system energy with and without fragments implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Fraggle collision system object + class(collision_fraggle), intent(inout) :: self !! Fraggle collision system object class(base_nbody_system), intent(in) :: nbody_system !! Original swiftest nbody system object class(base_parameters), intent(in) :: param !! Current swiftest run configuration parameters class(base_nbody_system), allocatable, intent(out) :: tmpsys !! Output temporary swiftest nbody system object @@ -97,7 +97,7 @@ module subroutine fraggle_util_reset_system(self) !! Resets the collider system and deallocates all allocatables implicit none ! Arguments - class(fraggle_system), intent(inout) :: self !! Collision system object + class(collision_fraggle), intent(inout) :: self !! Collision system object self%dscale = 1.0_DP self%mscale = 1.0_DP diff --git a/src/swiftest/swiftest_module.f90 b/src/swiftest/swiftest_module.f90 index 7a6fe0b79..ff94cb85c 100644 --- a/src/swiftest/swiftest_module.f90 +++ b/src/swiftest/swiftest_module.f90 @@ -322,7 +322,7 @@ module swiftest class(encounter_list), allocatable :: plpl_encounter !! List of massive body-massive body encounters in a single step class(collision_list_plpl), allocatable :: plpl_collision !! List of massive body-massive body collisions in a single step class(collision_list_plpl), allocatable :: pltp_collision !! List of massive body-massive body collisions in a single step - class(collision_system), allocatable :: collider !! Collision system object + class(collision_merge), allocatable :: collider !! Collision system object class(encounter_storage(nframes=:)), allocatable :: encounter_history !! Stores encounter history for later retrieval and saving to file class(collision_storage(nframes=:)), allocatable :: collision_history !! Stores encounter history for later retrieval and saving to file diff --git a/src/swiftest/swiftest_setup.f90 b/src/swiftest/swiftest_setup.f90 index ffa455ac0..ae7f0dc40 100644 --- a/src/swiftest/swiftest_setup.f90 +++ b/src/swiftest/swiftest_setup.f90 @@ -117,13 +117,13 @@ module subroutine swiftest_setup_construct_system(nbody_system, param) select case(param%collision_model) case("MERGE") - allocate(collision_system :: nbody_system%collider) + allocate(collision_merge :: nbody_system%collider) case("BOUNCE") allocate(collision_bounce :: nbody_system%collider) case("SIMPLE") allocate(collision_simple :: nbody_system%collider) case("FRAGGLE") - allocate(fraggle_system :: nbody_system%collider) + allocate(collision_fraggle :: nbody_system%collider) end select call nbody_system%collider%setup(nbody_system)