def setup_sph_code(self, sph_code, number_of_particles, L, rho, u): converter = ConvertBetweenGenericAndSiUnits(L, rho, constants.G) sph_code = sph_code(converter, mode='periodic') #, redirection = 'none') sph_code.parameters.periodic_box_size = 10.0 | units.parsec gas = Particles(number_of_particles) gas.mass = (rho * L**3) / number_of_particles numpy.random.seed(12345) gas.x = L * numpy.random.uniform(0.0, 1.0, number_of_particles) gas.y = L * numpy.random.uniform(0.0, 1.0, number_of_particles) gas.z = L * numpy.random.uniform(0.0, 1.0, number_of_particles) gas.vx = numpy.zeros(number_of_particles) | units.cm / units.s gas.vy = numpy.zeros(number_of_particles) | units.cm / units.s gas.vz = numpy.zeros(number_of_particles) | units.cm / units.s gas.u = u if isinstance(sph_code, Fi): sph_code.parameters.self_gravity_flag = False sph_code.parameters.timestep = 0.1 | generic_unit_system.time gas.h_smooth = L / number_of_particles**(1 / 3.0) gas.position -= 0.5 * L sph_code.gas_particles.add_particles(gas) sph_code.commit_particles() #~ sph_code.evolve_model(0.01 | units.Myr) return sph_code
def setup_sph_code(sph_code, N, L, rho, u): converter = ConvertBetweenGenericAndSiUnits(L, rho, constants.G) sph_code = sph_code(converter, mode='periodic') #, redirection = 'none') sph_code.parameters.periodic_box_size = 10.0 | units.parsec plummer = new_plummer_gas_model(N, convert_nbody=converter) plummer = plummer.select(lambda r: r.length() < 0.5 * L, ["position"]) N = len(plummer) print "N=", len(plummer) plummer.mass = (rho * L**3) / N gas = Particles(N) gas.mass = 0.01 * (rho * L**3) / N numpy.random.seed(12345) gas.x = L * numpy.random.uniform(0.0, 1.0, N) gas.y = L * numpy.random.uniform(0.0, 1.0, N) gas.z = L * numpy.random.uniform(0.0, 1.0, N) gas.vx = numpy.zeros(N) | units.cm / units.s gas.vy = numpy.zeros(N) | units.cm / units.s gas.vz = numpy.zeros(N) | units.cm / units.s gas.u = u if isinstance(sph_code, Fi): sph_code.parameters.self_gravity_flag = False sph_code.parameters.timestep = 0.1 | generic_unit_system.time gas.h_smooth = L / N**(1 / 3.0) gas.position -= 0.5 * L sph_code.gas_particles.add_particles(gas) sph_code.gas_particles.add_particles(plummer) sph_code.commit_particles() return sph_code
def run_supernova(): use_hydro_code = Gadget2 hydro_code_options = dict(number_of_workers=3) number_of_sph_particles = 3000 t_end = 1.0e4 | units.s pickle_file = setup_stellar_evolution_model() model = convert_stellar_model_to_SPH(None, number_of_sph_particles, seed=12345, pickle_file=pickle_file, with_core_particle=True, target_core_mass=1.4 | units.MSun) print("model=", model.core_particle) core, gas_without_core, core_radius \ = model.core_particle, model.gas_particles, model.core_radius inject_supernova_energy(gas_without_core) print("\nEvolving (SPH) to:", t_end) n_steps = 100 unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun, constants.G, t_end) hydro_code = use_hydro_code(unit_converter, **hydro_code_options) try: hydro_code.parameters.timestep = t_end / n_steps except Exception as exc: if not "parameter is read-only" in str(exc): raise hydro_code.parameters.epsilon_squared = core_radius**2 hydro_code.parameters.n_smooth_tol = 0.01 hydro_code.gas_particles.add_particles(gas_without_core) hydro_code.dm_particles.add_particle(core) times = [] | units.s potential_energies = [] | units.J kinetic_energies = [] | units.J thermal_energies = [] | units.J for time, i_step in [(i * t_end / n_steps, i) for i in range(0, n_steps + 1)]: hydro_code.evolve_model(time) times.append(time) potential_energies.append(hydro_code.potential_energy) kinetic_energies.append(hydro_code.kinetic_energy) thermal_energies.append(hydro_code.thermal_energy) hydro_plot([-1.0, 1.0, -1.0, 1.0] * (350 | units.RSun), hydro_code, (100, 100), time, os.path.join( get_path_to_results(), "supernova_hydro_image{0:=03}.png".format(i_step))) energy_plot(times, kinetic_energies, potential_energies, thermal_energies, "supernova_energy_evolution.pdf") hydro_code.stop()
def relax_in_isolation(giant_in_sph, sph_code, output_base_name): total_mass = giant_in_sph.gas_particles.total_mass() + giant_in_sph.core_particle.mass total_radius = max(giant_in_sph.gas_particles.position.lengths_squared()).sqrt() dynamical_timescale = (total_radius**3 / (2 * constants.G * total_mass)).sqrt().as_quantity_in(units.day) t_end = (10.0 * dynamical_timescale).as_quantity_in(units.day) n_steps = 100 hydro_code_options = dict(number_of_workers=2, redirection='file', redirect_file='hydrodynamics_code_relax_out.log') unit_converter = ConvertBetweenGenericAndSiUnits(total_radius, total_mass, t_end) hydrodynamics = sph_code(unit_converter, **hydro_code_options) hydrodynamics.parameters.epsilon_squared = giant_in_sph.core_radius**2 hydrodynamics.parameters.max_size_timestep = t_end hydrodynamics.parameters.time_max = 1.1 * t_end hydrodynamics.parameters.time_limit_cpu = 7.0 | units.day hydrodynamics.gas_particles.add_particles(giant_in_sph.gas_particles) hydrodynamics.dm_particles.add_particle(giant_in_sph.core_particle) potential_energies = hydrodynamics.potential_energy.as_vector_with_length(1).as_quantity_in(units.erg) kinetic_energies = hydrodynamics.kinetic_energy.as_vector_with_length(1).as_quantity_in(units.erg) thermal_energies = hydrodynamics.thermal_energy.as_vector_with_length(1).as_quantity_in(units.erg) print(" Relaxing for", t_end, "(10 * dynamical timescale)") times = (t_end * list(range(1, n_steps+1)) / n_steps).as_quantity_in(units.day) for i_step, time in enumerate(times): hydrodynamics.evolve_model(time) print(" Relaxed for:", time) potential_energies.append(hydrodynamics.potential_energy) kinetic_energies.append(hydrodynamics.kinetic_energy) thermal_energies.append(hydrodynamics.thermal_energy) hydrodynamics.gas_particles.copy_values_of_attributes_to( ['mass', 'x','y','z', 'vx','vy','vz', 'u', 'h_smooth'], giant_in_sph.gas_particles) giant_in_sph.core_particle.position = hydrodynamics.dm_particles[0].position giant_in_sph.core_particle.velocity = hydrodynamics.dm_particles[0].velocity hydrodynamics.stop() snapshotfile = output_base_name + "_gas.amuse" write_set_to_file(giant_in_sph.gas_particles, snapshotfile, format='amuse') shutil.copy(snapshotfile, os.path.join("..", "giant_models")) snapshotfile = output_base_name + "_core.amuse" # temporarily store core_radius on the core particle giant_in_sph.core_particle.radius = giant_in_sph.core_radius write_set_to_file(giant_in_sph.core_particle.as_set(), snapshotfile, format='amuse') giant_in_sph.core_particle.radius = 0.0 | units.m shutil.copy(snapshotfile, os.path.join("..", "giant_models")) energy_evolution_plot(times, kinetic_energies, potential_energies, thermal_energies, figname = output_base_name + "_energy_evolution.png")
def test2(self): print("Demonstrate new_sink_particles usage") cloud = Particles(100) cloud.mass = 1 | units.MSun cloud.position = [[0, 0, 0], [100, 100, 100], [200, 200, 200], [300, 300, 300]] * 25 | units.parsec cloud.velocity = [[0, 0, 0], [1, 1, 1]] * 50 | units.km / units.s unit_converter = ConvertBetweenGenericAndSiUnits( 1 | units.m, 1 | units.kg, 1 | units.s) sph_code = Stub(unit_converter) sph_code.parameters.stopping_condition_maximum_density = 1 | units.kg / units.m**3 sph_code.gas_particles.add_particles(cloud) density_limit_detection = sph_code.stopping_conditions.density_limit_detection density_limit_detection.enable() sph_code.evolve_model(1 | units.Myr) self.assertTrue(density_limit_detection.is_set()) self.assertEqual(len(density_limit_detection.particles()), 3) self.assertEqual(density_limit_detection.particles().position, [[100, 100, 100], [200, 200, 200], [300, 300, 300]] | units.parsec) print(density_limit_detection.particles()) clumps = density_limit_detection.particles().copy() sph_code.gas_particles.remove_particles(clumps) sinks = new_sink_particles(clumps, sink_radius=1 | units.parsec, looping_over=self.looping_over) self.assertEqual(sinks.sink_radius, 1.0 | units.parsec) self.assertEqual(sinks.mass, 1.0 | units.MSun) self.assertEqual(sinks.position, [[100, 100, 100], [200, 200, 200], [300, 300, 300]] | units.parsec) self.assertEqual(len(sph_code.gas_particles), 97) self.assertAlmostRelativeEqual( sph_code.gas_particles.total_mass() + clumps.total_mass(), 100 | units.MSun, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), 97 | units.MSun, 10) sinks.accrete(sph_code.gas_particles) self.assertAlmostRelativeEqual(sinks.mass, [25, 25, 25] | units.MSun, 10) self.assertEqual(len(sph_code.gas_particles), 25) self.assertAlmostRelativeEqual( sph_code.gas_particles.total_mass() + clumps.total_mass(), 100 | units.MSun, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), 25 | units.MSun, 10)
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 prepare_giant_system(sph_code, giant_model, view_on_giant, time_unit, n_steps): hydro_code_options = dict(number_of_workers=2, redirection='file', redirect_file='hydrodynamics_code_out.log') unit_converter = ConvertBetweenGenericAndSiUnits( 1.0 | units.RSun, giant_model.gas_particles.total_mass() + giant_model.core_particle.mass, time_unit) system = sph_code(unit_converter, **hydro_code_options) system.parameters.epsilon_squared = giant_model.core_radius**2 system.parameters.max_size_timestep = time_unit / n_steps system.parameters.time_max = 1.1 * time_unit system.parameters.time_limit_cpu = 7.0 | units.day giant_model.gas_particles.position += view_on_giant.position giant_model.gas_particles.velocity += view_on_giant.velocity giant_model.core_particle.position += view_on_giant.position giant_model.core_particle.velocity += view_on_giant.velocity system.gas_particles.add_particles(giant_model.gas_particles) system.dm_particles.add_particle(giant_model.core_particle) return system
def new_particles(self): input_file = os.path.join(get_path_to_results(), "test_sph_to_star_input.hdf5") if os.path.exists(input_file): return read_set_from_file(input_file, "hdf5") stellar_evolution = EVtwin() stellar_evolution.particles.add_particle( Particle(mass=1.0 | units.MSun)) stellar_evolution.evolve_model(100.0 | units.Myr) particles = convert_stellar_model_to_SPH( stellar_evolution.particles[0], 500, seed=12345).gas_particles stellar_evolution.stop() hydrodynamics = Gadget2( ConvertBetweenGenericAndSiUnits(1.0 | units.MSun, 1.0 | units.RSun, 1.0e3 | units.s)) hydrodynamics.gas_particles.add_particles(particles) hydrodynamics.evolve_model(1.0 | units.s) hydrodynamics.gas_particles.copy_values_of_attributes_to( ["density", "u", "pressure"], particles) hydrodynamics.stop() write_set_to_file(particles, input_file, "hdf5") return particles
class CalculateSolutionIn3D(object): number_of_workers = 1 number_of_grid_points = 10 gamma = 5.0 / 3.0 name_of_the_code = "gadget2" hydro_code_options = dict(redirection="none") convert_generic_units = ConvertBetweenGenericAndSiUnits( 1.0 | units.kpc, 1.0e10 | units.MSun, constants.G) convert_nbody_units = nbody_to_si(1.0 | units.kpc, 1.0e10 | units.MSun) def __init__(self, **keyword_arguments): for x in keyword_arguments: # print x, keyword_arguments[x] setattr(self, x, keyword_arguments[x]) self.dimensions_of_mesh = (self.number_of_grid_points * 3, self.number_of_grid_points, self.number_of_grid_points) def new_instance_of_code(self): attribute = "new_instance_of_{0}_code".format( self.name_of_the_code.lower()) return getattr(self, attribute)() def new_instance_of_athena_code(self): result = Athena(number_of_workers=self.number_of_workers, **self.hydro_code_options) result.initialize_code() result.parameters.gamma = self.gamma result.parameters.courant_number = 0.3 return result def new_instance_of_mpiamrvac_code(self): result = MpiAmrVac(number_of_workers=self.number_of_workers, **self.hydro_code_options) result.set_parameters_filename(result.default_parameters_filename) result.initialize_code() return result def new_instance_of_capreole_code(self): result = Capreole(number_of_workers=self.number_of_workers, **self.hydro_code_options) result.initialize_code() return result grid_hydro_codes = ("athena", "mpiamrvac", "capreole") def new_instance_of_gadget2_code(self): result = Gadget2(self.convert_generic_units, number_of_workers=self.number_of_workers, mode="periodic", **self.hydro_code_options) result.initialize_code() return result def new_instance_of_fi_code(self): result = Fi(self.convert_nbody_units, number_of_workers=self.number_of_workers, mode="periodic", **self.hydro_code_options) result.initialize_code() result.parameters.self_gravity_flag = False result.parameters.timestep = 0.01 | time return result sph_hydro_codes = ("gadget2", "fi") def set_parameters(self, instance): if self.name_of_the_code in self.sph_hydro_codes: instance.parameters.periodic_box_size = 1.0 | length else: instance.parameters.mesh_size = self.dimensions_of_mesh instance.parameters.length_x = 1 | length instance.parameters.length_y = 1 | length instance.parameters.length_z = 1 | length instance.parameters.x_boundary_conditions = ("periodic", "periodic") instance.parameters.y_boundary_conditions = ("periodic", "periodic") instance.parameters.z_boundary_conditions = ("periodic", "periodic") result = instance.commit_parameters() def new_grid(self): grid = Grid.create(self.dimensions_of_mesh, [1, 1, 1] | length) self.clear_grid(grid) return grid def clear_grid(self, grid): density = mass / length**3 momentum = speed * density energy = mass / (time**2 * length) grid.rho = 0.0 | density grid.rhovx = 0.0 | momentum grid.rhovy = 0.0 | momentum grid.rhovz = 0.0 | momentum grid.energy = 0.0 | energy return grid def initialize_grid_with_shock(self, grid): energy = mass / (time**2 * length) halfway = self.dimensions_of_mesh[0] / 2 - 1 firsthalf = grid.x <= 0.5 | length secondhalf = grid.x > 0.5 | length grid[firsthalf].rho = 4.0 | density grid[firsthalf].energy = (1.0 | energy) / (self.gamma - 1) grid[secondhalf].rho = 1.0 | density grid[secondhalf].energy = (0.1795 | energy) / (self.gamma - 1) def set_initial_conditions(self, instance): if self.name_of_the_code in self.sph_hydro_codes: initial_grid = self.new_grid() self.initialize_grid_with_shock(initial_grid) if self.name_of_the_code == "fi": initial_grid.position -= 0.5 | length sph_particles = convert_grid_to_SPH(initial_grid, self.number_of_particles) instance.gas_particles.add_particles(sph_particles) else: for x in instance.itergrids(): inmem = x.copy() self.clear_grid(inmem) self.initialize_grid_with_shock(inmem) from_model_to_code = inmem.new_channel_to(x) from_model_to_code.copy() instance.initialize_grid() def copy_results(self, instance): if self.name_of_the_code in self.sph_hydro_codes: n_samples = self.number_of_grid_points * 3 result = Particles(n_samples) result.position = [(x, 0.5, 0.5) | length for x in numpy.linspace(0.0, 1.0, n_samples)] x, y, z = result.x, result.y, result.z if self.name_of_the_code == "fi": x -= (0.5 | length) y -= (0.5 | length) z -= (0.5 | length) no_speed = [0.0] * n_samples | speed result.rho, result.rhovx, result.rhovy, result.rhovz, result.energy = [ self.convert_generic_units.to_generic(quantity) for quantity in instance.get_hydro_state_at_point( x, y, z, no_speed, no_speed, no_speed) ] else: result = [] for x in instance.itergrids(): result.append(x.copy()) return result def get_solution_at_time(self, time): instance = self.new_instance_of_code() self.set_parameters(instance) self.set_initial_conditions(instance) print "start evolve" instance.evolve_model(time) print "copying results" result = self.copy_results(instance) print "terminating code" instance.stop() return result
def test3(self): print("Demonstrate new_sink_particles usage (using Gadget2)") UnitLength = 1.0 | units.kpc UnitMass = 1.0e10 | units.MSun UnitVelocity = 1.0 | units.km / units.s convert_nbody = nbody_system.nbody_to_si(UnitLength, UnitMass) converter = ConvertBetweenGenericAndSiUnits(UnitLength, UnitMass, UnitVelocity) number_gas_particles = 1000 gas = new_evrard_gas_sphere(number_gas_particles, convert_nbody, do_scale=True, seed=12345) sph_code = Gadget2(converter) sph_code.initialize_code() sph_code.parameters.stopping_condition_maximum_density = 10 * UnitMass / UnitLength**3 sph_code.gas_particles.add_particles(gas) self.assertIsOfOrder(max(sph_code.gas_particles.density), UnitMass / UnitLength**3) density_limit_detection = sph_code.stopping_conditions.density_limit_detection density_limit_detection.enable() sph_code.evolve_model(10.0 | units.Myr) self.assertTrue(density_limit_detection.is_set()) self.assertTrue(sph_code.model_time < 10.0 | units.Myr) print("density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr)) self.assertEqual(len(density_limit_detection.particles()), 1) self.assertTrue(density_limit_detection.particles().density > 10 * UnitMass / UnitLength**3) clumps = density_limit_detection.particles().copy() sph_code.gas_particles.remove_particles(clumps) clumps_in_code = sph_code.dm_particles.add_particles(clumps) sinks = new_sink_particles(clumps_in_code,looping_over=self.looping_over) self.assertEqual(sinks.sink_radius, clumps.radius) self.assertAlmostRelativeEqual(sinks.mass, UnitMass / number_gas_particles, 10) self.assertAlmostRelativeEqual(sinks.position, clumps.position, 10) self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 1) self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10) self.assertEqual(set(sinks.get_attribute_names_defined_in_store()) - set(["sink_radius","lx","ly","lz"]), set(sph_code.particles.get_attribute_names_defined_in_store())) sinks.accrete(sph_code.gas_particles) self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10) self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 3) self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10) sinks.accrete(sph_code.particles) # Nothing happens: gas already gone, and cannot accrete itself self.assertAlmostRelativeEqual(sinks.mass, 3 * UnitMass / number_gas_particles, 10) self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10) steps = 0 while True: sph_code.evolve_model(sph_code.model_time + (0.1 | units.Myr)) sinks.sink_radius = 4 * clumps_in_code.radius sinks.accrete(sph_code.gas_particles) steps += 1 if density_limit_detection.is_set(): break self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 7) self.assertAlmostRelativeEqual(sinks.mass, 7 * UnitMass / number_gas_particles, 10) self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10) self.assertTrue(density_limit_detection.is_set()) self.assertEqual(steps, 5) self.assertTrue(sph_code.model_time < 10.0 | units.Myr) print("density_limit exceeded at t =", sph_code.model_time.as_quantity_in(units.Myr)) self.assertEqual(len(density_limit_detection.particles()), 5) self.assertTrue((density_limit_detection.particles().density > 10 * UnitMass / UnitLength**3).all()) clumps = density_limit_detection.particles().copy() sph_code.gas_particles.remove_particles(clumps) clumps_in_code = sph_code.dm_particles.add_particles(clumps) sinks.add_sinks(clumps_in_code, sink_radius=0.1|units.kpc) self.assertEqual(sinks[1:].sink_radius, 0.1 | units.kpc) self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 12) self.assertAlmostRelativeEqual(sinks.mass[1:], UnitMass / number_gas_particles, 10) self.assertAlmostRelativeEqual(sinks.position[1:], clumps.position, 10) self.assertAlmostRelativeEqual(sph_code.particles.total_mass(), UnitMass, 10) self.assertAlmostRelativeEqual(sph_code.gas_particles.total_mass(), UnitMass - sinks.total_mass(), 10) sinks.accrete(sph_code.gas_particles) self.assertEqual(len(sph_code.gas_particles), number_gas_particles - 66) self.assertAlmostRelativeEqual(sph_code.particles.total_mass().as_quantity_in(units.MSun), UnitMass, 10) self.assertAlmostRelativeEqual(sinks.mass, [7.0, 13.0, 15.0, 9.0, 11.0, 11.0] * UnitMass / number_gas_particles, 10)
class CalculateSolutionIn3D(object): size = 10.0 | length number_of_workers = 1 number_of_grid_points = 25 gamma = 5.0 / 3.0 rho_medium = 0 | density rho_sphere = 0.5 | density center = [1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0] * size radius = 1.0 | length total_mass = 1.0 | mass name_of_the_code = "athena_selfgravity" convert_generic_units = ConvertBetweenGenericAndSiUnits( 1.0 | units.kpc, 1.0e10 | units.MSun, constants.G) def __init__(self, **keyword_arguments): for x in keyword_arguments: print(x, keyword_arguments[x]) setattr(self, x, keyword_arguments[x]) self.dimensions_of_mesh = (self.number_of_grid_points, self.number_of_grid_points, self.number_of_grid_points) self.instance = None def new_instance_of_code(self): attribute = "new_instance_of_{0}_code".format( self.name_of_the_code.lower()) return getattr(self, attribute)() def new_instance_of_athena_selfgravity_code(self): result = Athena(mode=AthenaInterface.MODE_SELF_GRAVITY, redirection="none", number_of_workers=1) result.initialize_code() result.parameters.gamma = self.gamma result.parameters.courant_number = 0.3 result.set_grav_mean_rho(self.rho_mean) return result def new_instance_of_athena_code(self): result = Athena(redirection="none", number_of_workers=1) result.initialize_code() result.parameters.gamma = self.gamma result.parameters.courant_number = 0.3 return result def new_instance_of_athena_and_nbody_code(self): gridcode = Athena(redirection="none", number_of_workers=1) gridcode.initialize_code() gridcode.parameters.gamma = self.gamma gridcode.parameters.courant_number = 0.3 gridcode.set_has_external_gravitational_potential(1) nbodycode = PhiGRAPE(mode="gpu") # nbodycode = Octgrav(mode="gpu") nbodycode.initialize_code() nbodycode.parameters.epsilon_squared = ( self.size / (10000.0 * self.number_of_grid_points))**2 nbodycode.commit_parameters() result = HydroGridAndNbody(gridcode, nbodycode) return result def new_instance_of_capreole_and_nbody_code(self): gridcode = Capreole(number_of_workers=self.number_of_workers) gridcode.initialize_code() nbodycode = PhiGRAPE(mode="gpu") # nbodycode = Octgrav(mode="gpu") nbodycode.initialize_code() nbodycode.parameters.epsilon_squared = ( self.size / (10000.0 * self.number_of_grid_points))**2 nbodycode.commit_parameters() result = HydroGridAndNbodyWithAccelerationTransfer(gridcode, nbodycode) return result def set_parameters(self, instance): instance.parameters.mesh_size = self.dimensions_of_mesh instance.parameters.length_x = self.size instance.parameters.length_y = self.size instance.parameters.length_z = self.size instance.parameters.x_boundary_conditions = ("periodic", "periodic") instance.parameters.y_boundary_conditions = ("periodic", "periodic") instance.parameters.z_boundary_conditions = ("periodic", "periodic") result = instance.commit_parameters() def new_grid(self): density = mass / length**3 density = density momentum = speed * density energy = mass / (time**2 * length) grid = Grid.create(self.dimensions_of_mesh, (10.0, 10.0, 10.0) | length) grid.rho = self.rho_medium grid.rhovx = 0.0 | momentum grid.rhovy = 0.0 | momentum grid.rhovz = 0.0 | momentum grid.energy = 0.0 | energy return grid def initialize_grid_with_plummer_sphere(self, grid): scaled_radius = self.radius # / 1.695 radii = (grid.position - self.center).lengths() selected_radii = radii[radii < self.radius] print("number of cells in cloud (number of cells in grid)", len(selected_radii), grid.shape, grid.size) self.rho_sphere = ((0.75 * self.total_mass / (pi * (scaled_radius**3)))) grid.rho = (self.rho_medium + (self.rho_sphere * ((1 + (radii**2) / (scaled_radius**2))**(-5.0 / 2.0)))) internal_energy = ((0.25 | potential) * (1.0 | length / mass) * self.total_mass / scaled_radius) # 1.0 * grid.rho * grid.energy = grid.rho * \ (internal_energy/((1.0+(radii/scaled_radius)**2)**(1.0/2.0))) def setup_code(self): print("setup code") self.grid = self.new_grid() self.initialize_grid_with_plummer_sphere(self.grid) print("Mean density", self.grid.rho.flatten().mean()) self.rho_mean = self.grid.rho.flatten().mean() self.instance = self.new_instance_of_code() self.set_parameters(self.instance) self.from_model_to_code = self.grid.new_channel_to(self.instance.grid) self.from_code_to_model = self.instance.grid.new_channel_to(self.grid) self.from_code_to_model.copy_attributes(( "x", "y", "z", )) self.from_model_to_code.copy() self.instance.initialize_grid() def get_solution_at_time(self, time): if self.instance is None: self.setup_code() print("start evolve") self.instance.evolve_model(time) print("copying results") self.from_code_to_model.copy() # print "max,min", max(self.grid.rhovx.flatten()), min(self.grid.rhovx.flatten()) # print "max,min", max(self.grid.rhovy.flatten()), min(self.grid.rhovy.flatten()) # print "max,min", max(self.grid.rhovz.flatten()), min(self.grid.rhovz.flatten()) # print "max,min", max(self.grid.energy.flatten()), min(self.grid.energy.flatten()) # print "max,min", max(self.grid.rho.flatten()), min(self.grid.rho.flatten()) return self.grid
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")
from amuse.community.fi.interface import Fi from amuse.rfi.core import is_mpd_running usage = """\ usage: amuse.sh %prog [options] This example script will simulate the spherical collapse of an initially-cold adiabatic gas cloud, with a radial density profile proportional to 1/r. """ labels = [['K', 'V', 'U', 'E'], ['K', 'V', 'U', 'E']] fi_gadget_labels = [['K_fi', 'V_fi', 'U_fi', 'E_fi'], ['K_gadget', 'V_gadget', 'U_gadget', 'E_gadget']] convert_generic_units = ConvertBetweenGenericAndSiUnits( 1.0 | units.kpc, 1.0e10 | units.MSun, constants.G) convert_nbody_units = nbody_system.nbody_to_si(1.0 | units.kpc, 1.0e10 | units.MSun) def run_evrard(hydro_legacy_codes, number_of_particles, random_seed=None, name_of_the_figure="evrard_collapse_test.png"): print "\nThe spherical collapse of an initially-cold adiabatic gas cloud,\n", \ "consisting of ", str(number_of_particles), "particles will be simulated...\n" t_end = 3.0 * convert_nbody_units.to_si( 1.0 | nbody_system.time) # (3 natural timescales) print "Evolving to (3 natural timescales): ", t_end.as_quantity_in(
def run_supernova(): # options: use_hydro_code = Gadget2 # Fi -or- Gadget2 hydro_code_options = dict( number_of_workers=3 ) # e.g. dict(use_gl = True) or dict(redirection = "none") number_of_sph_particles = 30000 t_end = 1.0e5 | units.s pickle_file = setup_stellar_evolution_model() print "Creating initial conditions from a MESA stellar evolution model..." model = convert_stellar_model_to_SPH( None, number_of_sph_particles, seed=12345, pickle_file=pickle_file, # base_grid_options = dict(type = "glass", target_rms = 0.01), with_core_particle=True) core, gas_without_core, core_radius = model.core_particle, model.gas_particles, model.core_radius if len(core): print "Created", len( gas_without_core), "SPH particles and one 'core-particle':\n", core print "Setting gravitational smoothing to:", core_radius else: print "Warning: Only SPH particles created." inject_supernova_energy(gas_without_core) print "\nEvolving (SPH) to:", t_end n_steps = 100 unit_converter = ConvertBetweenGenericAndSiUnits(1.0 | units.RSun, constants.G, t_end) hydro_code = use_hydro_code(unit_converter, **hydro_code_options) try: hydro_code.parameters.timestep = t_end / n_steps except Exception as exc: if not "parameter is read-only" in str(exc): raise hydro_code.parameters.epsilon_squared = core_radius**2 hydro_code.parameters.n_smooth_tol = 0.01 hydro_code.gas_particles.add_particles(gas_without_core) hydro_code.dm_particles.add_particles(core) times = [] | units.s potential_energies = [] | units.J kinetic_energies = [] | units.J thermal_energies = [] | units.J for time, i_step in [(i * t_end / n_steps, i) for i in range(0, n_steps + 1)]: hydro_code.evolve_model(time) times.append(time) potential_energies.append(hydro_code.potential_energy) kinetic_energies.append(hydro_code.kinetic_energy) thermal_energies.append(hydro_code.thermal_energy) hydro_plot([-1.0, 1.0, -1.0, 1.0] * (350 | units.RSun), hydro_code, (100, 100), os.path.join( get_path_to_results(), "supernova_hydro_image{0:=03}.png".format(i_step))) energy_plot( times, kinetic_energies, potential_energies, thermal_energies, os.path.join(get_path_to_results(), "supernova_energy_evolution.png")) hydro_code.stop() print "All done!\n"
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"