def speed_copy_to_superset(self): particles1 = new_plummer_model(self.total_number_of_points) particles2 = new_plummer_model(self.total_number_of_points) particles_all = ParticlesSuperset([particles1, particles2]) empty_particles = particles_all.empty_copy() channel1 = particles_all.new_channel_to(empty_particles) channel2 = empty_particles.new_channel_to(particles_all) self.start_measurement() channel1.copy_attributes(["x", "y", "z"]) channel2.copy_attributes(["x", "y", "z"]) self.end_measurement()
def speed_copy_to_superset(self): particles1 = new_plummer_model(self.total_number_of_points) particles2 = new_plummer_model(self.total_number_of_points) particles_all = ParticlesSuperset([particles1, particles2]) empty_particles = particles_all.empty_copy() channel1 = particles_all.new_channel_to(empty_particles) channel2 = empty_particles.new_channel_to(particles_all) self.start_measurement() channel1.copy_attributes(["x","y","z"]) channel2.copy_attributes(["x","y","z"]) self.end_measurement()
def test55(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test25" + self.store_version() + ".hdf5") if os.path.exists(output_file): os.remove(output_file) particles1 = Particles(2) particles1[0].x = 1.0 | units.km particles1[1].x = 2.0 | units.km particles2 = Particles(2) particles2[0].x = 3.0 | units.km particles2[1].x = 4.0 | units.km particles_superset = ParticlesSuperset([particles1, particles2]) self.assertAlmostRelativeEquals(particles_superset[0].x, 1.0 | units.km) self.assertAlmostRelativeEquals(particles_superset[2].x, 3.0 | units.km) io.write_set_to_file(particles_superset, output_file, "hdf5", version=self.store_version()) loaded_particles_superset = io.read_set_from_file( output_file, "hdf5", version=self.store_version()) self.assertAlmostRelativeEquals(loaded_particles_superset[0].x, 1.0 | units.km) self.assertAlmostRelativeEquals(loaded_particles_superset[2].x, 3.0 | units.km)
def slowtest1(self): stellar_evolution = self.new_instance(MESA) stellar_evolution.particles.add_particles(Particles(2, mass=[1.0, 5.0]|units.MSun)) stellar_evolution.evolve_model(10.0 | units.Myr) initial_separation = stellar_evolution.particles.radius.sum() sph_particles_1 = convert_stellar_model_to_SPH( stellar_evolution.particles[0], 200, seed=12345 ).gas_particles sph_particles_2 = convert_stellar_model_to_SPH( stellar_evolution.particles[1], 1000, seed=12345 ).gas_particles stellar_evolution.stop() initial_speed = 10.0 | units.km / units.s sph_particles_2.x += initial_separation sph_particles_1.vx += initial_speed all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2]) all_sph_particles.move_to_center() t_end = 4.0e3 | units.s print "Evolving to:", t_end n_steps = 4 unit_system_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun, 1.0 | units.MSun, t_end) hydro_code = Gadget2(unit_system_converter) hydro_code.gas_particles.add_particles(all_sph_particles) pyplot.ion() for time in [i*t_end/n_steps for i in range(1, n_steps+1)]: hydro_code.evolve_model(time) pyplot.close('all') pyplot.figure() pynbody_column_density_plot(hydro_code.gas_particles, width=10|units.RSun) pyplot.draw() pyplot.figure() loglog(hydro_code.gas_particles.position.lengths_squared(), hydro_code.gas_particles.pressure, 'bo') pyplot.draw() hydro_code.stop() sleep(3) pyplot.ioff()
def slowtest1(self): stellar_evolution = self.new_instance(MESA) stellar_evolution.particles.add_particles( Particles(2, mass=[1.0, 5.0] | units.MSun)) stellar_evolution.evolve_model(10.0 | units.Myr) initial_separation = stellar_evolution.particles.radius.sum() sph_particles_1 = convert_stellar_model_to_SPH( stellar_evolution.particles[0], 200, seed=12345).gas_particles sph_particles_2 = convert_stellar_model_to_SPH( stellar_evolution.particles[1], 1000, seed=12345).gas_particles stellar_evolution.stop() initial_speed = 10.0 | units.km / units.s sph_particles_2.x += initial_separation sph_particles_1.vx += initial_speed all_sph_particles = ParticlesSuperset( [sph_particles_1, sph_particles_2]) all_sph_particles.move_to_center() t_end = 4.0e3 | units.s print "Evolving to:", t_end n_steps = 4 unit_system_converter = ConvertBetweenGenericAndSiUnits( 1.0 | units.RSun, 1.0 | units.MSun, t_end) hydro_code = Gadget2(unit_system_converter) hydro_code.gas_particles.add_particles(all_sph_particles) pyplot.ion() for time in [i * t_end / n_steps for i in range(1, n_steps + 1)]: hydro_code.evolve_model(time) pyplot.close('all') pyplot.figure() pynbody_column_density_plot(hydro_code.gas_particles, width=10 | units.RSun) pyplot.draw() pyplot.figure() loglog(hydro_code.gas_particles.position.lengths_squared(), hydro_code.gas_particles.pressure, 'bo') pyplot.draw() hydro_code.stop() sleep(3) pyplot.ioff()
def evolve_disk_flyby(bodies, gravity, t_end, n_steps, converter, snap_dir, file_out): bodies = ParticlesSuperset([stars, planetesimals]) channel_from_gr_to_framework = gravity.particles.new_channel_to(bodies) rm_file(file_out) Etot_init = gravity.kinetic_energy + gravity.potential_energy Etot = Etot_init dt = t_end / float(n_steps) time = 0.0 | units.yr stdout = (file_out.split('.'))[0] stdout += '.txt' f = open(snap_dir + "/" + stdout, 'a') print " ** evolving: t_end = ", t_end, ", dt = ", dt.in_(units.yr) print " \t\t", "time", "\t\t", "dE" while time <= t_end: gravity.evolve_model(time) channel_from_gr_to_framework.copy() bodies.collection_attributes.timestamp = time Ekin = gravity.kinetic_energy Epot = gravity.potential_energy Etot = Ekin + Epot dE = Etot_init - Etot nb_E = converter.to_nbody(Etot) #nb_J = converter.nbody_length ** 2 * units.nbody_mass * units.nbody_time ** -2 # not supposed to work # A formatted string would work better than tabs. (Tabs never work) line = " \t" + str(time.value_in( units.yr)) + "\t" + str(nb_E) + "\t" + str(dE / Etot_init) print line f.write(line + "\n") # Write coordinates in Center of Mass frame # Move Stars to CoM (initially in CoM) #### The stars are already in CoM coordinates #### # Move planetesimals to CoM (initially in CoM) #### The stars are already in CoM coordinates #### (Does this mean the other method is wrong?) write_set_to_file(bodies, snap_dir + "/" + file_out, "hdf5") time += dt gravity.stop() return
def apply_for_superset(self, particles, *args, **kwargs): indices = self.method(*args, **kwargs) subset_results = [] for subset in particles._private.particle_sets: keys = [] for index in indices: if index in subset._private.attribute_storage.mapping_from_index_in_the_code_to_particle_key: keys.append(subset._private.attribute_storage.mapping_from_index_in_the_code_to_particle_key[index]) subset_results.append(subset._subset(keys)) return ParticlesSuperset(subset_results)
def evolve_disk_flyby_together_in_subsets(stars, planetesimals, gravity, t_start, t_end, n_steps, converter, file_out, verbose=True): bodies = ParticlesSuperset([stars, planetesimals]) channel_from_gr_to_framework = gravity.particles.new_channel_to(bodies) Etot_init = gravity.kinetic_energy() + gravity.potential_energy() Etot = Etot_init duration = t_end - t_start dt = duration / float(n_steps - 1) time = 0.0 | units.yr if verbose is True: #print " ** Huayno timestep parameter =", gravity.list_of_instances[0].get_timestep_parameter() print " ** evolving: t_start = ", t_start.in_( units.Myr), "t_end = ", t_end.in_(units.Myr), ", dt = ", dt.in_( units.Myr) print " \t", "time", "\t\t", "dE" while time <= duration: gravity.evolve_model(time) #channel_from_gr_to_framework.copy() # this is because the channel does not work bodies = gravity.particles.copy() bodies.collection_attributes.timestamp = time + t_start Ekin = gravity.kinetic_energy() Epot = gravity.potential_energy() Etot = Ekin + Epot dE = Etot_init - Etot nb_E = converter.to_nbody(Etot) if verbose is True: print " \t\t", time + t_start, "\t", dE / Etot_init #, "\t", nb_E if file_out is not None: write_set_to_file(bodies, file_out, "hdf5") time += dt gravity.stop() # this is because the channel does not work stars = bodies[:2].copy() planetesimals = bodies[2:].copy() return stars, planetesimals, bodies.collection_attributes.timestamp
def integrate_disk_flyby(stars, planetesimals, t_end, n_steps, snap_dir, file_out, file_redir, huayno_eta): converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) planetesimals.position += stars[0].position planetesimals.velocity += stars[0].velocity bodies = ParticlesSuperset([stars, planetesimals]) if file_redir is None: gravity = Huayno(converter, channel_type="sockets", mode="openmp") # Add this (specify a number of cores) elif file_redir == "0": gravity = Huayno(converter, channel_type="sockets", redirection="none", mode="openmp") else: gravity = Huayno(converter, channel_type="sockets", redirection="file", redirect_file=file_redir, mode="openmp") gravity.particles.add_particles(bodies) gravity.commit_particles() gravity.parameters.timestep_parameter = huayno_eta time_step = gravity.get_timestep_parameter() #gravity.set_inttype_parameter(12) #gravity.set_inttype_parameter(8) gravity.set_eps2_parameter(0.001 * 0.001) # Softening Parameter print ' ** timestep: ', gravity.get_timestep_parameter() print ' ** inttype: ', gravity.get_inttype_parameter() print ' ** eps2: ', gravity.get_eps2_parameter(), numpy.sqrt( gravity.get_eps2_parameter()) t0 = time.time() evolve_disk_flyby(bodies, gravity, t_end, n_steps, converter, snap_dir, file_out) t1 = time.time() dt = t1 - t0 print "Performace data: N =", len( bodies), "dt=", dt, "s =", dt / 60.0, "min" return
def head_on_stellar_merger( masses = [0.3, 3.0] | units.MSun, star_age = 310.0 | units.Myr, maximally_evolved_stars = False, initial_separation = 4.0 | units.RSun, angle = numpy.pi / 3, initial_speed = 3000.0 | units.km / units.s, initial_speed_perpendicular = 30.0 | units.km / units.s, number_of_sph_particles = 1000, t_end = 1.0e4 | units.s, sph_code = Fi, steps_per_snapshot = 4, snapshot_size = 100, use_stored_stellar_models = True ): """ masses: Mass of the two stars star_age: Initial age of the stars (if maximally_evolved_stars is False) maximally_evolved_stars: Evolve stars as far as the Stellar Evolution code can get number_of_sph_particles: Total number of particles of both stars, divided according to their masses t_end: (Physical, not computational) duration of the hydrodynamics simulation sph_code: Code to use for the hydrodynamics simulation steps_per_snapshot: A hydroplot snapshot is generated each time after this many steps (0 or None means no snapshots) snapshot_size: Size of the snapshot in pixels along one dimension use_stored_stellar_models: Flag to use previously stored stellar model files (for speed-up). """ # Convert some of the input parameters to string, for use in output file names: n_string = "n" + ("%1.0e"%(number_of_sph_particles)).replace("+0","").replace("+","") t_end_string = "t" + ("%1.0e"%(t_end.value_in(units.s))).replace("+0","").replace("+","") masses_string = ("m1_" + ("%0.3e"%(masses[0].value_in(units.MSun))).replace("+0","").replace("+","") + "_m2_" + ("%0.3e"%(masses[1].value_in(units.MSun))).replace("+0","").replace("+","")) if maximally_evolved_stars: star_age_string = "a_max" else: star_age_string = "a" + ("%0.3e"%(star_age.value_in(units.Myr))).replace("+0","").replace("+","") base_output_file_name = os.path.join(get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string) pickle_file_1 = os.path.join(get_path_to_results(), "stellar_merger_"+masses_string+"_"+star_age_string+"_1.pkl") pickle_file_2 = os.path.join(get_path_to_results(), "stellar_merger_"+masses_string+"_"+star_age_string+"_2.pkl") if not use_stored_stellar_models or not (os.path.exists(pickle_file_1) and os.path.exists(pickle_file_2)): stars = Particles(2) stars.mass = masses try: stellar_evolution = MESA() stellar_evolution.initialize_code() except: print "MESA was not built. Returning." return stellar_evolution.commit_parameters() stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() if maximally_evolved_stars: try: while True: stellar_evolution.evolve_model() except AmuseException as exception: print exception else: stellar_evolution.evolve_model(star_age) if os.path.exists(pickle_file_1): print "Could not save stellar model 1: file already exists." else: pickle_stellar_model(stellar_evolution.particles[0], pickle_file_1) print "Stellar model 1 saved at:", pickle_file_1 if os.path.exists(pickle_file_2): print "Could not save stellar model 2: file already exists." else: pickle_stellar_model(stellar_evolution.particles[1], pickle_file_2) print "Stellar model 2 saved at:", pickle_file_2 stellar_evolution.stop() model_1 = StellarModel2SPH(None, None, pickle_file = pickle_file_1) model_2 = StellarModel2SPH(None, None, pickle_file = pickle_file_2) model_1.unpickle_stellar_structure() model_2.unpickle_stellar_structure() composition = model_2.composition_profile midpoints = model_2.midpoints_profile[1:-1] specific_internal_energy = model_2.specific_internal_energy_profile number_of_sph_particles_1 = int(round(number_of_sph_particles * (model_1.mass / (model_1.mass + model_2.mass)))) number_of_sph_particles_2 = number_of_sph_particles - number_of_sph_particles_1 print "Creating initial conditions from a MESA stellar evolution model:" print model_1.mass, "star consisting of", number_of_sph_particles_1, "particles." sph_particles_1 = convert_stellar_model_to_SPH( None, number_of_sph_particles_1, seed=12345, pickle_file = pickle_file_1 ).gas_particles print model_2.mass, "star consisting of", number_of_sph_particles_2, "particles." sph_particles_2 = convert_stellar_model_to_SPH( None, number_of_sph_particles_2, pickle_file = pickle_file_2 ).gas_particles initial_separation += model_1.radius + model_2.radius sph_particles_2.x += numpy.cos(angle) * initial_separation sph_particles_2.y += numpy.sin(angle) * initial_separation sph_particles_1.vx += numpy.cos(angle) * initial_speed - numpy.sin(angle) * initial_speed_perpendicular sph_particles_1.vy += numpy.cos(angle) * initial_speed_perpendicular + numpy.sin(angle) * initial_speed view = [-0.5, 0.5, -0.5, 0.5] * (initial_separation + model_1.radius + model_2.radius) all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2]) all_sph_particles.move_to_center() unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun, constants.G, t_end) hydro_legacy_code = sph_code(unit_converter) n_steps = 100 hydro_legacy_code.parameters.n_smooth = 96 try: hydro_legacy_code.parameters.timestep = t_end / n_steps except Exception as exc: if not "parameter is read-only" in str(exc): raise hydro_legacy_code.gas_particles.add_particles(all_sph_particles) times = [] | units.Myr kinetic_energies = [] | units.J potential_energies = [] | units.J thermal_energies = [] | units.J print "Evolving to:", t_end for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]: hydro_legacy_code.evolve_model(time) times.append(time) kinetic_energies.append( hydro_legacy_code.kinetic_energy) potential_energies.append( hydro_legacy_code.potential_energy) thermal_energies.append( hydro_legacy_code.thermal_energy) if steps_per_snapshot and (not i_step % steps_per_snapshot): hydro_plot( view, hydro_legacy_code, (snapshot_size, snapshot_size), base_output_file_name + "_hydro_image{0:=03}.png".format(i_step) ) hydro_legacy_code.gas_particles.new_channel_to(all_sph_particles).copy_attributes( ['mass', 'x','y','z', 'vx','vy','vz', 'u']) center_of_mass = all_sph_particles.center_of_mass().as_quantity_in(units.RSun) center_of_mass_velocity = all_sph_particles.center_of_mass_velocity().as_quantity_in(units.km / units.s) print print "center_of_mass:", center_of_mass print "center_of_mass_velocity:", center_of_mass_velocity all_sph_particles.position -= center_of_mass sph_midpoints = all_sph_particles.position.lengths() energy_plot( times, kinetic_energies, potential_energies, thermal_energies, base_output_file_name+"_energy_evolution.png" ) thermal_energy_plot( times, thermal_energies, base_output_file_name+"_thermal_energy_evolution.png" ) composition_comparison_plot( midpoints, composition[0], sph_midpoints, all_sph_particles.h1, base_output_file_name+"_composition_h1.png" ) internal_energy_comparison_plot( midpoints, specific_internal_energy, sph_midpoints, all_sph_particles.u, base_output_file_name+"_new_u.png" ) hydro_plot( [-2.0, 2.0, -2.0, 2.0] | units.RSun, hydro_legacy_code, (100, 100), base_output_file_name + "_hydro_image.png" ) hydro_legacy_code.stop() print "All done!\n"
# because we rotate the disk with respect to the orbital plane, # we use longitude of ascending node instead of argument of pericenter in TT72, # where the orbit is rotated with respect to the disk (see Fig. 6 in TT72) disk_a_incl = get_inclined_disk(disk_a, incl_deg=o.incl_a, lon_deg=o.omega_a) disk_b_incl = get_inclined_disk(disk_b, incl_deg=o.incl_b, lon_deg=o.omega_b) disk_a_incl.position += galaxies[0].position disk_a_incl.velocity += galaxies[0].velocity disk_b_incl.position += galaxies[1].position disk_b_incl.velocity += galaxies[1].velocity ### particle superset disks = ParticlesSuperset([disk_a_incl, disk_b_incl]) ### parameters for the integration # t_end = -2.5*t_orbit t_end = -2.24 * t_orbit # approximately corresponds to the time showed in Fig. 23 file_redir="none" huayno_eps2 = (o.eps_factor*o.r_min)**2 huayno_inttype_parameter = 12 # number of test particles per subset in gravity_in_subsets nsub = 20 print " ** t_end", t_end.in_(units.Myr) print " ** HUAYNO parameters: eps2 =", huayno_eps2.in_(units.kpc**2), "eta =", o.eta_nbody, "inttype =", huayno_inttype_parameter ### integrate flyby
def integrate_disk_flyby(stars, planetesimals, t_end, t_peri, nb_end, n_steps, r_step, snap_dir, file_out, file_redir, bridge_dt, huayno_eta): """ stars --- Star bodies planetesimals --- Non-star bodies t_end --- Total Integration Time n_steps --- Number of Snapshots r_step --- snap_dir --- Snapshot Directory file_out --- Output File (cannot be None) file_redir --- Redirection File (can be None) bridge_dt --- Bridge Timestep huayno_eta --- Huayno Timestep """ converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) # set nbody scales # Initialize Huayno (N-body Solver) stars_gravity = initialize_huayno(stars, converter, huayno_eta) #print file_redir t0 = time.time() """ Notes: (1) Careful with coordinate system (2) Different timesteps (3) """ # Calculate t_end_a, t_end_b rm_file(snap_dir + "/" + file_out) # (Part A) # planetesimals_gravity = Kepler_0 [0, t_end_a] planetesimals_gravity = initialize_kepler(planetesimals, converter, file_redir, center=0) # Calculate number of steps for each integration t_0 = 0.0 | units.yr dt = (t_end - t_0) / float(n_steps) k_end = 0.84 t_end_a = k_end * abs(t_peri) n_steps_a = round(t_end_a / dt) # number of steps for (Part A) t_end_b = t_end_a + (nb_end - k_end) * abs( t_peri) #### <---- fix this later n_steps_b = round((t_end_b - t_end_a) / dt) # number of steps for (Part B) n_steps_c = n_steps - (n_steps_a + n_steps_b) print "t_peri", abs( t_peri.value_in(units.yr) ), "t_end_a", t_end_a, "n_steps_a", n_steps_a, "n_steps_c", n_steps_c, "dt", dt.value_in( units.yr) print stars, planetesimals = evolve_disk_flyby(stars, planetesimals, stars_gravity, planetesimals_gravity, t_0, t_end_a, n_steps_a, converter, snap_dir, file_out, r_step, bridge_dt, center=0) print stars print print planetesimals print # (Part B) # planetesimals_gravity = Huayno [t_end_a, t_end_b] bodies = ParticlesSuperset([stars, planetesimals]) gravity = initialize_huayno(bodies, converter, huayno_eta) stars, planetesimals = evolve_disk_flyby_together(stars, planetesimals, gravity, t_end_a, t_end_b, n_steps_b, converter, snap_dir, file_out) planetesimals.position -= stars[1].position planetesimals.velocity -= stars[1].velocity print stars print print planetesimals print # (Part C) # planetesimals_gravity = Kepler_1 [t_end_b, t_end] stars_gravity = initialize_huayno(stars, converter, huayno_eta) planetesimals_gravity = initialize_kepler(planetesimals, converter, file_redir, center=1) stars, planetesimals = evolve_disk_flyby(stars, planetesimals, stars_gravity, planetesimals_gravity, t_end_b, t_end, n_steps_c, converter, snap_dir, file_out, r_step, bridge_dt, center=1) print stars print print planetesimals print t1 = time.time() dt = t1 - t0 print " ** Performace data: N =", len(stars) + len( planetesimals), "dt=", dt, "s =", dt / 60.0, "min" return
def evolve_disk_flyby(stars, planetesimals, stars_gravity, planetesimals_gravity, t_start, t_end, n_steps, converter, snap_dir, file_out, r_step, bridge_dt, center=0): """ Input Parameters: stars --- Star bodies planetesimals --- Non-star bodies stars_gravity --- planetesimals_gravity --- t_end --- Total Integration Time n_steps --- Number of Snapshots converter --- snap_dir --- file_out --- r_step --- bridge_dt --- Bridge Timestep """ bodies = ParticlesSuperset([stars, planetesimals]) channel_from_stars_to_framework = stars_gravity.particles.new_channel_to( stars) channel_from_planetesimals_to_framework = planetesimals_gravity.particles.new_channel_to( planetesimals) pl_gravity = planet_gravity_for_disk(Huayno, stars_gravity.particles, converter, center=center) gravity = bridge.Bridge(use_threading=False) gravity.add_system(planetesimals_gravity, (pl_gravity, )) # stars work on planetesimals gravity.add_system(stars_gravity, ()) # stars are self aware (evolves itself) # timestep for BRIDGE relative to the period at r_step (or r_min, if no r_step is given) # BRIDGE_timestep = bridge_dt * P(r_step) if r_step is None: Porb_min = orbital_period((bodies[2:].position.lengths()).min(), bodies[0].mass) print " ** P_min_disk = ", Porb_min.in_(units.yr) gravity.timestep = bridge_dt * Porb_min else: Porb_min = orbital_period(r_step, bodies[0].mass) print " ** P_rin_disk = ", Porb_min.in_(units.yr) gravity.timestep = bridge_dt * Porb_min time_step = stars_gravity.get_timestep_parameter() print ' ** timesteps: \t stars gravity timestep parameter =', time_step print '\t\t bridge =', gravity.timestep Etot_init = stars_gravity.kinetic_energy + stars_gravity.potential_energy Etot = Etot_init ps.mkdir(snap_dir) duration = t_end - t_start dt = duration / float(n_steps) time = 0.0 | units.yr print "Duration:", duration, "t_start", t_start, "t_end", t_end, "dt:", dt print " ** evolving: t_start = ", t_start.value_in( 1000 * units.yr), "t_end = ", t_end.value_in(1000 * units.yr), ", dt = ", dt print " \t", "time", "\t\t\t", "E", "\t\t", "dE" stdout = (file_out.split('.'))[0] stdout += '.txt' f = open(snap_dir + "/" + stdout, 'a') # Joules J = units.m**2 * units.kg * units.s**-2 while time <= duration: gravity.evolve_model(time) channel_from_stars_to_framework.copy() channel_from_planetesimals_to_framework.copy() bodies.collection_attributes.timestamp = time + t_start Ekin = stars_gravity.kinetic_energy Epot = stars_gravity.potential_energy Etot = Ekin + Epot dE = Etot_init - Etot nb_E = converter.to_nbody(Etot) #nb_J = converter.nbody_length ** 2 * units.nbody_mass * units.nbody_time ** -2 # not supposed to work # A formatted string would work better than tabs. (Tabs never work) line = " \t" + str((time + t_start).value_in( units.yr)) + "\t" + str(nb_E) + "\t" + str(dE / Etot_init) print line f.write(line + "\n") # Write coordinates in Center of Mass frame # Move Stars to CoM (initially in CoM) #### The stars are already in CoM coordinates #### # Move planetesimals to CoM (initially w/ respect to star zero) planetesimals.velocity += stars[center].velocity planetesimals.position += stars[center].position write_set_to_file(bodies, snap_dir + "/" + file_out, "hdf5") time += dt f.close() # stdout gravity.stop() stars_gravity.stop() planetesimals_gravity.stop() pl_gravity.stop() # retrieval? return stars, planetesimals
class StubInterface(object): def __init__(self, **options): self.maximum_density = 1 | units.kg / units.m**3 self._gas_particles = Particles() self._dm_particles = Particles() self._all_particles = ParticlesSuperset([self._gas_particles, self._dm_particles]) def before_get_parameter(self): pass def before_set_parameter(self): pass def initialize_code(self): return 0 synchronize_model = commit_particles = recommit_particles = commit_parameters = initialize_code def new_particle(self, mass, x, y, z, vx, vy, vz, *args): next_id = len(self._dm_particles) temp = Particles(len(mass)) temp.mass = mass temp.x = x temp.y = y temp.z = z temp.vx = vx temp.vy = vy temp.vz = vz temp.id = list(range(next_id, next_id + len(mass))) self._dm_particles.add_particles(temp) return [temp.id, temp.id] def new_gas_particle(self, mass, x, y, z, vx, vy, vz, *args): next_id = len(self._gas_particles) + 1000000 temp = Particles(len(mass)) temp.mass = mass temp.x = x temp.y = y temp.z = z temp.vx = vx temp.vy = vy temp.vz = vz temp.id = list(range(next_id, next_id + len(mass))) self._gas_particles.add_particles(temp) return [temp.id, temp.id] def delete_particle(self, indices): for index in indices: for id, particle in zip(self._all_particles.id, self._all_particles): if id == index: self._all_particles.remove_particle(particle) return 0 def get_mass(self, indices): return [[mass for index in indices for id, mass in zip(self._all_particles.id, self._all_particles.mass) if index == id], [0]*len(indices)] def set_mass(self, indices, masses): for index, mass in zip(indices, masses): for id, particle in zip(self._all_particles.id, self._all_particles): if id == index: particle.mass = mass break return 0 def get_position(self, indices): return [[x for index in indices for id, x in zip(self._all_particles.id, self._all_particles.x) if index == id], [y for index in indices for id, y in zip(self._all_particles.id, self._all_particles.y) if index == id], [z for index in indices for id, z in zip(self._all_particles.id, self._all_particles.z) if index == id], [0]*len(indices)] def get_velocity(self, indices): return [[vx for index in indices for id, vx in zip(self._all_particles.id, self._all_particles.vx) if index == id], [vy for index in indices for id, vy in zip(self._all_particles.id, self._all_particles.vy) if index == id], [vz for index in indices for id, vz in zip(self._all_particles.id, self._all_particles.vz) if index == id], [0]*len(indices)] def has_stopping_condition(self, type): return 1 if type == 6 else 0 def get_stopping_condition_maximum_density_parameter(self): return self.maximum_density def set_stopping_condition_maximum_density_parameter(self, value): self.maximum_density = value is_stopping_condition_set = is_stopping_condition_enabled = has_stopping_condition def get_number_of_stopping_conditions_set(self): return 3 def get_stopping_condition_info(self, sc_indices): return [6]*len(sc_indices), [1]*len(sc_indices) def get_stopping_condition_particle_index(self, sc_index, sc_sub_index): return list(range(len(self._gas_particles) + 1000000 - len(sc_index), len(self._gas_particles) + 1000000)) def enable_stopping_condition(self, type): pass def evolve_model(self, time): return 0
def __init__(self, **options): self.maximum_density = 1 | units.kg / units.m**3 self._gas_particles = Particles() self._dm_particles = Particles() self._all_particles = ParticlesSuperset([self._gas_particles, self._dm_particles])
def head_on_stellar_merger( masses=[0.3, 3.0] | units.MSun, star_age=310.0 | units.Myr, maximally_evolved_stars=False, initial_separation=4.0 | units.RSun, angle=numpy.pi / 3, initial_speed=3000.0 | units.km / units.s, initial_speed_perpendicular=30.0 | units.km / units.s, number_of_sph_particles=1000, t_end=1.0e4 | units.s, sph_code=Fi, steps_per_snapshot=4, snapshot_size=100, use_stored_stellar_models=True ): """ masses: Mass of the two stars star_age: Initial age of the stars (if maximally_evolved_stars is False) maximally_evolved_stars: Evolve stars as far as the Stellar Evolution code can get number_of_sph_particles: Total number of particles of both stars, divided according to their masses t_end: (Physical, not computational) duration of the hydrodynamics simulation sph_code: Code to use for the hydrodynamics simulation steps_per_snapshot: A hydroplot snapshot is generated each time after this many steps (0 or None means no snapshots) snapshot_size: Size of the snapshot in pixels along one dimension use_stored_stellar_models: Flag to use previously stored stellar model files (for speed-up). """ # Convert some of the input parameters to string, for use in output file # names: n_string = "n" + ("%1.0e" % (number_of_sph_particles) ).replace("+0", "").replace("+", "") t_end_string = "t" + ("%1.0e" % (t_end.value_in(units.s)) ).replace("+0", "").replace("+", "") masses_string = ( "m1_" + ( "%0.3e" % (masses[0].value_in(units.MSun)) ).replace("+0", "").replace("+", "") + "_m2_" + ( "%0.3e" % (masses[1].value_in(units.MSun)) ).replace("+0", "").replace("+", "") ) if maximally_evolved_stars: star_age_string = "a_max" else: star_age_string = "a" + \ ("%0.3e" % (star_age.value_in(units.Myr))).replace( "+0", "").replace("+", "") base_output_file_name = os.path.join( get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string) pickle_file_1 = os.path.join(get_path_to_results( ), "stellar_merger_"+masses_string+"_"+star_age_string+"_1.pkl") pickle_file_2 = os.path.join(get_path_to_results( ), "stellar_merger_"+masses_string+"_"+star_age_string+"_2.pkl") if not use_stored_stellar_models or not (os.path.exists(pickle_file_1) and os.path.exists(pickle_file_2)): stars = Particles(2) stars.mass = masses try: stellar_evolution = MESA() stellar_evolution.initialize_code() except: print("MESA was not built. Returning.") return stellar_evolution.commit_parameters() stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() if maximally_evolved_stars: try: while True: stellar_evolution.evolve_model() except AmuseException as exception: print(exception) else: stellar_evolution.evolve_model(star_age) if os.path.exists(pickle_file_1): print("Could not save stellar model 1: file already exists.") else: pickle_stellar_model(stellar_evolution.particles[0], pickle_file_1) print("Stellar model 1 saved at:", pickle_file_1) if os.path.exists(pickle_file_2): print("Could not save stellar model 2: file already exists.") else: pickle_stellar_model(stellar_evolution.particles[1], pickle_file_2) print("Stellar model 2 saved at:", pickle_file_2) stellar_evolution.stop() model_1 = StellarModel2SPH(None, None, pickle_file=pickle_file_1) model_2 = StellarModel2SPH(None, None, pickle_file=pickle_file_2) model_1.unpickle_stellar_structure() model_2.unpickle_stellar_structure() composition = model_2.composition_profile midpoints = model_2.midpoints_profile[1:-1] specific_internal_energy = model_2.specific_internal_energy_profile number_of_sph_particles_1 = int( round( number_of_sph_particles * (model_1.mass / (model_1.mass + model_2.mass)) ) ) number_of_sph_particles_2 = ( number_of_sph_particles - number_of_sph_particles_1 ) print("Creating initial conditions from a MESA stellar evolution model:") print( model_1.mass, "star consisting of", number_of_sph_particles_1, "particles." ) sph_particles_1 = convert_stellar_model_to_SPH( None, number_of_sph_particles_1, seed=12345, pickle_file = pickle_file_1 ).gas_particles print( model_2.mass, "star consisting of", number_of_sph_particles_2, "particles." ) sph_particles_2 = convert_stellar_model_to_SPH( None, number_of_sph_particles_2, pickle_file=pickle_file_2 ).gas_particles initial_separation += model_1.radius + model_2.radius sph_particles_2.x += numpy.cos(angle) * initial_separation sph_particles_2.y += numpy.sin(angle) * initial_separation sph_particles_1.vx += ( numpy.cos(angle) * initial_speed - numpy.sin(angle) * initial_speed_perpendicular ) sph_particles_1.vy += ( numpy.cos(angle) * initial_speed_perpendicular + numpy.sin(angle) * initial_speed ) view = ( [-0.5, 0.5, -0.5, 0.5] * (initial_separation + model_1.radius + model_2.radius) ) all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2]) all_sph_particles.move_to_center() unit_converter = ConvertBetweenGenericAndSiUnits( 1.0 | units.RSun, constants.G, t_end) hydro_legacy_code = sph_code(unit_converter) n_steps = 100 hydro_legacy_code.parameters.n_smooth = 96 try: hydro_legacy_code.parameters.timestep = t_end / n_steps except Exception as exc: if "parameter is read-only" not in str(exc): raise hydro_legacy_code.gas_particles.add_particles(all_sph_particles) times = [] | units.Myr kinetic_energies = [] | units.J potential_energies = [] | units.J thermal_energies = [] | units.J print("Evolving to:", t_end) for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]: hydro_legacy_code.evolve_model(time) times.append(time) kinetic_energies.append(hydro_legacy_code.kinetic_energy) potential_energies.append(hydro_legacy_code.potential_energy) thermal_energies.append(hydro_legacy_code.thermal_energy) if steps_per_snapshot and (not i_step % steps_per_snapshot): hydro_plot( view, hydro_legacy_code, (snapshot_size, snapshot_size), base_output_file_name + "_hydro_image{0:=03}.png".format(i_step) ) hydro_legacy_code.gas_particles.new_channel_to( all_sph_particles ).copy_attributes( ['mass', 'x', 'y', 'z', 'vx', 'vy', 'vz', 'u'] ) center_of_mass = all_sph_particles.center_of_mass( ).as_quantity_in(units.RSun) center_of_mass_velocity = all_sph_particles.center_of_mass_velocity( ).as_quantity_in(units.km / units.s) print() print("center_of_mass:", center_of_mass) print("center_of_mass_velocity:", center_of_mass_velocity) all_sph_particles.position -= center_of_mass sph_midpoints = all_sph_particles.position.lengths() energy_plot( times, kinetic_energies, potential_energies, thermal_energies, base_output_file_name+"_energy_evolution.png" ) thermal_energy_plot( times, thermal_energies, base_output_file_name+"_thermal_energy_evolution.png" ) composition_comparison_plot( midpoints, composition[0], sph_midpoints, all_sph_particles.h1, base_output_file_name+"_composition_h1.png" ) internal_energy_comparison_plot( midpoints, specific_internal_energy, sph_midpoints, all_sph_particles.u, base_output_file_name+"_new_u.png" ) hydro_plot( [-2.0, 2.0, -2.0, 2.0] | units.RSun, hydro_legacy_code, (100, 100), base_output_file_name + "_hydro_image.png" ) hydro_legacy_code.stop() print("All done!\n")
class StubInterface(object): def __init__(self, **options): self.maximum_density = 1 | units.kg / units.m**3 self._gas_particles = Particles() self._dm_particles = Particles() self._all_particles = ParticlesSuperset([self._gas_particles, self._dm_particles]) def before_get_parameter(self): pass def before_set_parameter(self): pass def initialize_code(self): return 0 synchronize_model = commit_particles = recommit_particles = commit_parameters = initialize_code def new_particle(self, mass, x, y, z, vx, vy, vz, *args): next_id = len(self._dm_particles) temp = Particles(len(mass)) temp.mass = mass temp.x = x temp.y = y temp.z = z temp.vx = vx temp.vy = vy temp.vz = vz temp.id = list(range(next_id, next_id + len(mass))) self._dm_particles.add_particles(temp) return [temp.id, temp.id] def new_gas_particle(self, mass, x, y, z, vx, vy, vz, *args): next_id = len(self._gas_particles) + 1000000 temp = Particles(len(mass)) temp.mass = mass temp.x = x temp.y = y temp.z = z temp.vx = vx temp.vy = vy temp.vz = vz temp.id = list(range(next_id, next_id + len(mass))) self._gas_particles.add_particles(temp) return [temp.id, temp.id] def delete_particle(self, indices): for index in indices: for id, particle in zip(self._all_particles.id, self._all_particles): if id == index: self._all_particles.remove_particle(particle) return 0 def get_mass(self, indices): return [[mass for index in indices for id, mass in zip(self._all_particles.id, self._all_particles.mass) if index == id], [0]*len(indices)] def set_mass(self, indices, masses): for index, mass in zip(indices, masses): for id, particle in zip(self._all_particles.id, self._all_particles): if id == index: particle.mass = mass break return 0 def get_position(self, indices): return [[x for index in indices for id, x in zip(self._all_particles.id, self._all_particles.x) if index == id], [y for index in indices for id, y in zip(self._all_particles.id, self._all_particles.y) if index == id], [z for index in indices for id, z in zip(self._all_particles.id, self._all_particles.z) if index == id], [0]*len(indices)] def get_velocity(self, indices): return [[vx for index in indices for id, vx in zip(self._all_particles.id, self._all_particles.vx) if index == id], [vy for index in indices for id, vy in zip(self._all_particles.id, self._all_particles.vy) if index == id], [vz for index in indices for id, vz in zip(self._all_particles.id, self._all_particles.vz) if index == id], [0]*len(indices)] def has_stopping_condition(self, type): return 1 if type == 6 else 0 def get_stopping_condition_maximum_density_parameter(self): return self.maximum_density def set_stopping_condition_maximum_density_parameter(self, value): self.maximum_density = value is_stopping_condition_set = is_stopping_condition_enabled = has_stopping_condition def get_number_of_stopping_conditions_set(self): return 3 def get_stopping_condition_info(self, sc_indices): return [6]*len(sc_indices), [1]*len(sc_indices) def get_stopping_condition_particle_index(self, sc_index, sc_sub_index): return range(len(self._gas_particles) + 1000000 - len(sc_index), len(self._gas_particles) + 1000000) def enable_stopping_condition(self, type): pass def evolve_model(self, time): return 0
def run_diagnostics( model, logger=None, length_unit=units.pc, mass_unit=units.MSun, time_unit=units.Myr, ): """ Run diagnostics on model """ logger = logger or logging.getLogger(__name__) stars = model.star_particles sinks = model.sink_particles gas = model.gas_particles converter = model.star_converter if not sinks.is_empty(): non_collisional_bodies = Particles() non_collisional_bodies.add_particles(stars) non_collisional_bodies.add_particles(sinks) else: non_collisional_bodies = stars groups = identify_subgroups( converter, non_collisional_bodies, peak_density_threshold=1e-16 | units.g * units.cm**-3, ) n_groups = len(groups) if hasattr(stars, 'group_id'): group_id_offset = 1 + max(stars.group_id) else: group_id_offset = 1 # a group id of 0 would mean "no group found" logger.info("Found %i groups", n_groups) for i, group in enumerate(groups): group_id = i + group_id_offset if hasattr(group, 'group_id'): group.previous_group_id = group.group_id else: group.previous_group_id = 0 group.group_id = group_id stars_in_group = len(group) if (stars_in_group > 100): mass_in_group = group.total_mass().in_(mass_unit) mass_fraction = [0.01, 0.02, 0.05, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0] radii, new_mass_fraction = group.LagrangianRadii( unit_converter=converter, mf=mass_fraction, cm=group.center_of_mass(), ) assert (new_mass_fraction == mass_fraction) radii = radii.value_in(length_unit) x, y, z = group.center_of_mass().value_in(length_unit) median_previous_group_id = numpy.median(group.previous_group_id) logger.info( "step %i group %i nstars %i mass %s xyz %f %f %f %s origin %i " "LR %f %f %f %f %f %f %f %f %f %s", model.step, group_id, stars_in_group, mass_in_group, x, y, z, length_unit, median_previous_group_id, radii[0], radii[1], radii[2], radii[3], radii[4], radii[5], radii[6], radii[7], radii[8], length_unit, ) groups = ParticlesSuperset(groups) group_identifiers = Particles(keys=groups.key) group_identifiers.group_id = groups.group_id group_identifiers.previous_group_id = groups.previous_group_id return group_identifiers
def integrate_2disks_flyby(stars, planetesimals, t_end, n_steps, file_out, file_redir, huayno_eta_nbody, huayno_eps2, huayno_inttype_parameter, nsub, verbose=True): """ Integrate a binary orbit with test particles (e.g., disks around stars of the binary). -- integrated with gravity in subsets (the planetesimals are followed by N-body code in subsets including the binary) """ # to get the total computational time of the script t0 = time.time() # calculate number of steps for each integration t_ini = 0.0 | units.yr # initial time t_tot = t_end - t_ini # total time dt = t_tot / float(n_steps) # time step if verbose == True: print " ** n_steps: tot = ", n_steps if file_out is not None: print " ** output file exists -- removing", file_out rm_file(file_out) # set the converter converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) ### n-body integration # make superset bodies = ParticlesSuperset([stars, planetesimals]) # initialize HUAYNO for superset gravity_nbody = initialize_gravity_subsets( bodies, converter, Huayno, nsub, timestep_parameter=huayno_eta_nbody, epsilon_squared=huayno_eps2, inttype_parameter=huayno_inttype_parameter) if verbose == True: t11 = time.time() dt = t11 - t0 dt_kepler1 = dt stars, planetesimals, t_stop_nbody = evolve_disk_flyby_together_in_subsets( stars, planetesimals, gravity_nbody, t_ini, t_end, n_steps, converter, file_out, verbose=verbose) bodies_fin = ParticlesSuperset([stars, planetesimals]) if verbose is True: t1 = time.time() dt = t1 - t0 print "Performace data: N =", len(stars) + len( planetesimals), "dt=", dt, "s =", dt / 60.0, "min" return bodies_fin
def __init__(self, particle_sets, execute_all_threads_func=None): ParticlesSuperset.__init__(self, particle_sets) self._private.number_of_particles = 0 self._private.number_of_sets = len(particle_sets) self._private.execute_all_threads_func = execute_all_threads_func
def head_on_stellar_merger( masses=[0.3, 3.0] | units.MSun, star_age=310.0 | units.Myr, initial_separation=4.0 | units.RSun, angle=numpy.pi / 3, initial_speed=3000.0 | units.km / units.s, initial_speed_perpendicular=30.0 | units.km / units.s, number_of_sph_particles=50000, t_end=1.0e4 | units.s, sph_code=Fi, ): """ masses: Mass of the two stars star_age: Initial age of the stars number_of_sph_particles: Total number of particles of both stars, divided according to their masses t_end: (Physical, not computational) duration of the hydrodynamics simulation sph_code: Code to use for the hydrodynamics simulation """ # Convert some of the input parameters to string, for use in output file # names: n_string = "n" + ("%1.0e" % (number_of_sph_particles) ).replace("+0", "").replace("+", "") t_end_string = "t" + ("%1.0e" % (t_end.value_in(units.s)) ).replace("+0", "").replace("+", "") base_output_file_name = os.path.join( get_path_to_results(), "stellar_merger_"+n_string+"_"+t_end_string) stars = Particles(2) stars.mass = masses try: stellar_evolution = MESA() stellar_evolution.initialize_code() except: print "MESA was not built. Returning." return stellar_evolution.commit_parameters() stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() print "Evolving stars with MESA..." stellar_evolution.evolve_model(star_age) number_of_sph_particles_1 = int( round( number_of_sph_particles * ( stellar_evolution.particles[0].mass / stellar_evolution.particles.mass.sum() ) ) ) number_of_sph_particles_2 = ( number_of_sph_particles - number_of_sph_particles_1 ) print "Creating initial conditions from a MESA stellar evolution model:" print( stellar_evolution.particles[0].mass, "star consisting of", number_of_sph_particles_1, "particles." ) sph_particles_1 = convert_stellar_model_to_SPH( stellar_evolution.particles[0], number_of_sph_particles_1, seed=12345 ).gas_particles print( stellar_evolution.particles[1].mass, "star consisting of", number_of_sph_particles_2, "particles." ) sph_particles_2 = convert_stellar_model_to_SPH( stellar_evolution.particles[1], number_of_sph_particles_2 ).gas_particles initial_separation += stellar_evolution.particles.radius.sum() sph_particles_2.x += numpy.cos(angle) * initial_separation sph_particles_2.y += numpy.sin(angle) * initial_separation sph_particles_1.vx += numpy.cos(angle) * initial_speed - \ numpy.sin(angle) * initial_speed_perpendicular sph_particles_1.vy += numpy.cos(angle) * initial_speed_perpendicular + \ numpy.sin(angle) * initial_speed view = [-0.5, 0.5, -0.5, 0.5] * \ (initial_separation + stellar_evolution.particles.radius.sum()) stellar_evolution.stop() all_sph_particles = ParticlesSuperset([sph_particles_1, sph_particles_2]) all_sph_particles.move_to_center() unit_converter = ConvertBetweenGenericAndSiUnits( 1.0 | units.RSun, constants.G, t_end) hydro_legacy_code = sph_code(unit_converter) n_steps = 100 hydro_legacy_code.parameters.n_smooth = 96 try: hydro_legacy_code.parameters.timestep = t_end / n_steps except Exception as exc: if "parameter is read-only" not in str(exc): raise hydro_legacy_code.gas_particles.add_particles(all_sph_particles) print "Evolving to t =", t_end, " (using", sph_code.__name__, "SPH code)." for time, i_step in [(i*t_end/n_steps, i) for i in range(1, n_steps+1)]: hydro_legacy_code.evolve_model(time) if not i_step % 4: hydro_plot( view, hydro_legacy_code, (300, 300), base_output_file_name + "_hydro_image{0:=03}.png".format(i_step) ) hydro_legacy_code.stop() print "All done!\n"