def displace_galaxy(galaxy, rotation_mat, translation_vector, radial_velocity, transverse_velocity): widgets = [ 'Adjusting relative velocities and orientations: ', pbwg.AnimatedMarker(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: displaced_galaxy = Particles(len(galaxy)) displaced_galaxy.mass = galaxy.mass displaced_galaxy.position = galaxy.position displaced_galaxy.velocity = galaxy.velocity for body in displaced_galaxy: body.position = ([ body.x.value_in(units.kpc), body.y.value_in(units.kpc), body.z.value_in(units.kpc) ] @ rotation_mat) | units.kpc body.velocity = ([ body.vx.value_in(units.kms), body.vy.value_in(units.kms), body.vz.value_in(units.kms) ] @ rotation_mat) | units.kms displaced_galaxy.position += translation_vector displaced_galaxy.velocity += radial_velocity displaced_galaxy.velocity += transverse_velocity return displaced_galaxy
def load_galaxy_data(glxy_name, test=False, loaded='last'): if test == True: parent = __TEST_MODEL_DIR__ tf = '_test_' elif test == False: parent = __FULL_MODEL_DIR__ tf = '_full_' dirnames_list = [] mw_dirnames_list = [] m31_dirnames_list = [] for (dirpath, dirnames, filenames) in os.walk(parent): dirnames_list.extend(dirnames) break for dirname in dirnames_list: if dirname[0:2] == 'mw': mw_dirnames_list.append(dirname) elif dirname[0:3] == 'm31': m31_dirnames_list.append(dirname) if glxy_name == 'mw': current_dirlist = mw_dirnames_list elif glxy_name == 'm31_not_displaced': current_dirlist = m31_dirnames_list if loaded == 'last': try: glxy_dir = sorted(current_dirlist)[-1] except: try: glxy_dir = sorted(current_dirlist)[0] except: glxy_dir = '' else: for dirname in current_dirlist: if loaded == dirname: glxy_dir = dirname break glxy_data_name = glxy_dir glxy_data_dir = parent + glxy_dir + '/' glxy_data_path = glxy_data_dir + glxy_data_name if os.path.exists(glxy_data_path): widgets = [ 'Found galaxy data in {}, loading: '.format(glxy_data_dir), pbwg.AnimatedMarker(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: glxy = read_set_from_file(glxy_data_path, "hdf5") else: raise ValueError('No galaxy model found') return glxy, glxy_data_dir
def make_galaxy(n_halo, converter, glxy_name, test=False, **kwargs): widgets = [ 'Building {} galaxy: '.format(glxy_name), pbwg.AnimatedMarker(), ' ', pbwg.Timer(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: galaxy = new_galactics_model(n_halo, converter, **kwargs) out_path, current_model, tf = create_output_dir(glxy_name, test=test) galaxy_data_path = out_path + current_model widgets = [ 'Saving {} galaxy data in {}: '.format(glxy_name, out_path), pbwg.AnimatedMarker(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: write_set_to_file(galaxy, galaxy_data_path, 'hdf5') return galaxy, out_path
#disk_outer_radius = glxy_param['disk_outer_radius'], #disk_scale_height_sech2 = glxy_param['disk_scale_height_sech2'], #disk_central_radial_velocity_dispersion=m31_param['disk_central_radial_velocity_dispersion'], #bulge paramaters #bulge_scale_radius = glxy_param['bulge_scale_radius'], bulge_number_of_particles=m31_parameters['bulge_number_of_particles']) else: #mw, _ = gal.load_galaxy_data('mw', test=TEST) #m31_not_displaced, _ = gal.load_galaxy_data('m31_not_displaced', test=TEST) mw_data_dir = 'used_models/mw_test_2020-11-10-0001/' m31_data_dir = 'used_models/m31_not_displaced_test_2020-11-10-0001/' widgets = [ 'Found galaxy data in {}, loading: '.format(mw_data_dir), pbwg.AnimatedMarker(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: mw = read_set_from_file(mw_data_dir + 'mw_test_2020-11-10-0001', "hdf5") widgets = [ 'Found galaxy data in {}, loading: '.format(m31_data_dir), pbwg.AnimatedMarker(), pbwg.EndMsg() ] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: m31_not_displaced = read_set_from_file( m31_data_dir + 'm31_not_displaced_test_2020-11-10-0001', "hdf5") mw_mass = da.galaxy_total_mass(mw)
bulge_scale_radius = glxy_param['bulge_scale_radius'], bulge_number_of_particles = glxy_param['bulge_number_of_particles']) else: glxy, glxy_path = gal.load_galaxy_data(glxy_param['name'], test=True) ###### model analysis ###### if ANALYSIS: glxy_halo, glxy_disk, glxy_bulge = da.galaxy_structures(glxy, n_disk, n_bulge) print('Halo particles: {}; expected: {}'.format(len(glxy_halo), n_halo)) print('Disk particles: {}; expected: {}'.format(len(glxy_disk), n_disk)) print('Bulge particles: {}; expected: {}'.format(len(glxy_bulge), n_bulge)) widgets = ['Plotting galaxy structures: ', pbwg.AnimatedMarker(), pbwg.EndMsg()] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress: for structure, filename in zip([glxy_halo, glxy_disk, glxy_bulge], [glxy_name + '_halo', glxy_name + '_disk', glxy_name + '_bulge']): da.plot_galaxy_structure(structure, glxy_path, filename) _, csv_folder = da.create_model_analysis_dirs(glxy_path) halo_df_path = csv_folder + glxy_name + '_halo_velocities.csv' disk_df_path = csv_folder + glxy_name + '_disk_velocities.csv' bulge_df_path = csv_folder + glxy_name + '_bulge_velocities.csv' if os.path.exists(halo_df_path) and os.path.exists(disk_df_path) and os.path.exists(bulge_df_path): widgets = ['Found galaxy velocities data, loading: ', pbwg.AnimatedMarker(), pbwg.EndMsg()] with pbar.ProgressBar(widgets=widgets, fd=sys.stdout) as progress:
def simulate_merger(galaxy1, galaxy2, n_halo, n_disk, n_bulge, t_end, converter, solver, initial_conditions_dict, interval=0.5 | units.Myr, animation=False, snapshot=False, snap_freq=1000, sol_system=None, igm_gas_particles=None, igm_dm_particles=None, box_grid=0): #sets up the gravity solver dynamics_code = solver(converter, number_of_workers=4) dynamics_code.parameters.epsilon_squared = (100 | units.parsec)**2 dynamics_code.timestep = interval #if igm_gas_particles != None and igm_dm_particles != None: #dynamics_code.parameters.self_gravity_flag = True #computes coordinate difference between mw center of mass and solar system and moves it if sol_system != None: deltapos = galaxy1.center_of_mass() - sol_system.position sol_system.position = galaxy1.center_of_mass() - deltapos #uploads the particles into the gravity solver set1 = dynamics_code.dm_particles.add_particles(galaxy1) set2 = dynamics_code.dm_particles.add_particles(galaxy2) if sol_system != None: set5 = dynamics_code.dm_particles.add_particles(sol_system) else: set5 = None #moves system to center of mass dynamics_code.particles.move_to_center() #uploads igm particles if igm_gas_particles != None and igm_dm_particles != None: set3 = dynamics_code.dm_particles.add_particles(igm_gas_particles) set4 = dynamics_code.dm_particles.add_particles(igm_dm_particles) #creates channels mw_channel = dynamics_code.dm_particles.new_channel_to(set1) m31_channel = dynamics_code.dm_particles.new_channel_to(set2) if igm_gas_particles != None and igm_dm_particles != None: igm_gas_channel = dynamics_code.dm_particles.new_channel_to(set3) igm_dm_channel = dynamics_code.dm_particles.new_channel_to(set4) if sol_system != None: solar_channel = dynamics_code.dm_particles.new_channel_to(set5) #checks if the solver is Fi if isinstance(dynamics_code, Fi): dynamics_code.parameters.timestep = interval dynamics_code.update_particle_set() #creates output dirs out_dir, current_merger = create_merger_output_dir() diskbulge_merger_dir, contour_merger_dir, zoom_merger_dir, mw_zoom_dir, histogram_dir, igm_dir = create_merger_subdirs( out_dir) #initializes animations if animation: animation_number = 1 last_anim_time = 0 | units.Myr db_writer = GalaxyAnimWriter(current_merger + '_diskbulge_anim' + str(animation_number).zfill(2)) cr_writer = GalaxyAnimWriter(current_merger + '_contour_anim' + str(animation_number).zfill(2)) zm_writer = GalaxyAnimWriter(current_merger + '_zoom_anim' + str(animation_number).zfill(2)) else: db_writer = None cr_writer = None zm_writer = None #initializes snapshots start_zoom_plot = False last_snap_number = 0 last_plot_time = 0 | units.Myr current_time = 0 | units.Myr _a, _b = plt_anim_wrapper(set1, set2, n_disk, n_bulge, last_snap_number, current_time, last_plot_time, 'MW M31 merger', diskbulge_merger_dir, contour_merger_dir, zoom_merger_dir, mw_zoom_dir, 'mw_m31', t_end, 100000, particles=set5, animation=animation, snapshot=snapshot, diskbulge_writer=db_writer, contour_writer=cr_writer, zoom_writer=zm_writer, zoom=start_zoom_plot) #plots starting IGM #if igm_gas_particles != None and igm_dm_particles != None: # plot_igm(set3|set4, 500, Lg, igm_dir, 'IGM_density_t0') #initializes separation logs and solar system positions merger_dict = initial_conditions_dict merger_dict = update_merger_dict(merger_dict, current_time, set1, set2, solar=set5) #initializes progressbar current_iter = 0 t_end_in_Myr = t_end.as_quantity_in(units.Myr) total_iter = int(t_end_in_Myr / interval) + 1 widgets = [ 'Step ', pbwg.SimpleProgress(), ' ', pbwg.Bar(marker='=', tip='>', left='[', right=']', fill=' '), pbwg.Percentage(), ' - ', pbwg.ETA('ETA'), pbwg.EndMsg() ] progress = pbar.ProgressBar(widgets=widgets, maxval=total_iter, fd=sys.stdout).start() while dynamics_code.model_time < t_end: #evolves model dynamics_code.evolve_model(dynamics_code.model_time + interval) if isinstance(dynamics_code, Fi): dynamics_code.update_particle_set() #copies channels mw_channel.copy() m31_channel.copy() if sol_system != None: solar_channel.copy() if igm_gas_particles != None and igm_dm_particles != None: igm_gas_channel.copy() igm_dm_channel.copy() #current time of the solver current_time = dynamics_code.model_time #makes plots if last_plot_time.value_in(units.Myr) > 3000: start_zoom_plot = True last_plot_time, last_snap_number = plt_anim_wrapper( set1, set2, n_disk, n_bulge, last_snap_number, current_time, last_plot_time, 'MW M31 merger', diskbulge_merger_dir, contour_merger_dir, zoom_merger_dir, mw_zoom_dir, 'mw_m31', t_end, snap_freq, particles=set5, animation=animation, snapshot=snapshot, diskbulge_writer=db_writer, contour_writer=cr_writer, zoom_writer=zm_writer, zoom=start_zoom_plot) #updates separation logs and solar system positions merger_dict = update_merger_dict(merger_dict, current_time, set1, set2, solar=set5) #manages animations if animation: if close_animation(dynamics_code.model_time, last_anim_time): db_writer.close() cr_writer.close() zm_writer.close() animation_number += 1 last_anim_time = dynamics_code.model_time db_writer = GalaxyAnimWriter(current_merger + '_diskbulge_anim' + str(animation_number).zfill(2)) cr_writer = GalaxyAnimWriter(current_merger + '_contour_anim' + str(animation_number).zfill(2)) zm_writer = GalaxyAnimWriter(current_merger + '_zoom_anim' + str(animation_number).zfill(2)) #updates progressbar current_iter += 1 progress.update(current_iter) #closes progressbar progress.finish() #plots final IGM #if igm_gas_particles != None and igm_dm_particles != None: # plot_igm(igm_gas_particles|igm_dm_particles, 500, Lg, igm_dir, 'IGM_density_tfinal') #kills solver dynamics_code.stop() #checks if every dict key list has the same numer of elements merger_dict = pad_dict_list(merger_dict, -1) #saves merger logs into dataframe df_merger = pd.DataFrame(merger_dict) df_merger.to_csv('{}merger_logs.csv'.format(out_dir), index=False) #closes animations if animation: db_writer.close() cr_writer.close() zm_writer.close()
def mw_and_stars(galaxy1, stars, converter, n_disk, n_bulge, t_end, star_solver, interval=1 | units.Myr, snapshot=False, snap_freq=300): leapfrog = True if isinstance(star_solver, (BHTree)): leapfrog = False galaxy_dynamics_code = Fi(converter, redirection='none', number_of_workers=1) galaxy_dynamics_code.parameters.epsilon_squared = (100 | units.parsec)**2 set1 = galaxy_dynamics_code.dm_particles.add_particles(galaxy1) mw_channel = galaxy_dynamics_code.particles.new_channel_to(set1) galaxy_dynamics_code.particles.move_to_center() #mw_channel.update() halo1, disk1, bulge1 = galaxy_structures(set1, n_disk, n_bulge) if leapfrog: galaxy_dynamics_code.parameters.timestep = 0.5 | units.Myr solver = galaxy_dynamics_code else: star_converter = nbody_system.nbody_to_si(stars.mass.sum(), stars.position.length()) star_dynamics_code = star_solver(star_converter) star_dynamics_code.particles.add_particles(stars) ch_g2l = star_dynamics_code.particles.new_channel_to(stars) gravity = bridge.Bridge(use_threading=False) gravity.add_system(star_dynamics_code, (galaxy_dynamics_code, )) gravity.timestep = 0.5 | units.Myr solver = gravity if snapshot: plot_number = 0 last_plot_time = 0 | units.Myr make_plot_galstars(disk1, bulge1, stars, "MW and Solar System\nt = 0 Myr", 'galstars_' + str(plot_number).zfill(4)) x = [] | units.kpc y = [] | units.kpc current_iter = 0 total_iter = int(t_end / interval) + 1 t_end_scalar = t_end.value_in(units.Myr) times = np.arange(0., t_end_scalar, interval.value_in( units.Myr)) | units.Myr widgets = [ 'Step ', pbwg.SimpleProgress(), ' ', pbwg.Bar(marker='=', tip='>', left='[', right=']', fill=' '), pbwg.Percentage(), ' - ', pbwg.ETA('ETA'), pbwg.EndMsg() ] progress = pbar.ProgressBar(widgets=widgets, maxval=total_iter, fd=sys.stdout).start() for time in times: solver.evolve_model(time) mw_channel.copy() if leapfrog: star_solver(current_iter, stars, galaxy_dynamics_code) else: ch_g2l.copy() x.append(stars.x) y.append(stars.y) if snapshot: if check_last_plot_time(solver.model_time, last_plot_time, t_end / snap_freq): halo1, disk1, bulge1 = galaxy_structures(set1, n_disk, n_bulge) plot_number += 1 last_plot_time = solver.model_time make_plot_galstars( disk1, bulge1, stars, "MW and Solar System\nt = {} Myr".format( np.round(solver.model_time.value_in(units.Myr), decimals=0)), 'galstars_' + str(plot_number).zfill(4)) current_iter += 1 progress.update(current_iter) progress.finish() galaxy_dynamics_code.stop() if not leapfrog: star_dynamics_code.stop()
def simulate_single_galaxy(galaxy1, converter, n_halo, n_bulge, n_disk, t_end, glxy_path, solver=Gadget2, interval=0.5 | units.Myr, plot=False, plot_freq=100): if isinstance(solver, Gadget2): nw = 4 elif isinstance(solver, Fi): nw = 1 dynamics_code = solver(converter, number_of_workers=4) #dynamics_code = Fi(converter, redirection='none', number_of_workers=1) dynamics_code.parameters.epsilon_squared = (100 | units.parsec)**2 set1 = dynamics_code.dm_particles.add_particles(galaxy1) halo1 = set1[n_disk + n_bulge:] bulge1 = set1[n_disk:n_disk + n_bulge] disk1 = set1[:n_disk] dynamics_code.particles.move_to_center() if isinstance(dynamics_code, Gadget2): dynamics_code.timestep = interval elif isinstance(dynamics_code, Fi): dynamics_code.parameters.timestep = interval dynamics_code.update_particle_set() if plot == True: plot_number = 0 last_plot_time = 0 | units.Myr plot_single_galaxy(halo1, disk1, bulge1, "TEST\nt = 0 Myr", glxy_path, 'mw_testrun_' + str(plot_number).zfill(4)) current_iter = 0 t_end_in_Myr = t_end.as_quantity_in(units.Gyr) total_iter = int(t_end_in_Myr / interval) + 10 widgets = [ 'Step ', pbwg.SimpleProgress(), ' ', pbwg.Bar(marker='=', tip='>', left='[', right=']', fill=' '), pbwg.Percentage(), ' - ', pbwg.ETA('ETA'), pbwg.EndMsg() ] progress = pbar.ProgressBar(widgets=widgets, maxval=total_iter, fd=sys.stdout).start() while dynamics_code.model_time < t_end: current_iter += 1 dynamics_code.evolve_model(dynamics_code.model_time + interval) if isinstance(dynamics_code, Fi): dynamics_code.update_particle_set() if plot == True: if check_last_plot_time(dynamics_code.model_time, last_plot_time, t_end / plot_freq): plot_number += 1 last_plot_time = dynamics_code.model_time plot_single_galaxy( halo1, disk1, bulge1, "TEST\nt = {} Myr".format( int( np.round(dynamics_code.model_time.value_in( units.Myr), decimals=0))), glxy_path, 'mw_testrun_' + str(plot_number).zfill(4)) progress.update(current_iter) progress.finish() if plot == True: plot_number += 1 plot_single_galaxy( halo1, disk1, bulge1, "TEST\nt = {} Myr".format( int(np.round(t_end.value_in(units.Myr), decimals=0))), glxy_path, 'mw_testrun_' + str(plot_number).zfill(4)) dynamics_code.stop()