def test10(self): particles = Particles(2) particles.position = [[1, 0, 0], [2,0,0]] | units.m particles.velocity = [[3, 0, 0], [4,0,0]] | units.m / units.s particles.mass = 1 | units.kg self.assertEquals(particles.total_mass(), 2 | units.kg) self.assertEquals(particles.total_momentum(), [7, 0, 0] | units.kg * units.m / units.s) self.assertEquals(particles.total_momentum(), particles.total_mass() * particles.center_of_mass_velocity()) self.assertEquals(particles.total_radius(), 0.5 | units.m) convert_nbody = nbody_system.nbody_to_si(1000 | units.kg, 1e-6 | units.m) numpy.random.seed(123) field = new_plummer_sphere(10000, convert_nbody) # small clump of particles, can be regarded as point mass self.assertAlmostRelativeEquals(particles.potential_energy_in_field(field), -constants.G * (1500 | units.kg**2 / units.m), 5) self.assertAlmostEquals(particles.potential_energy_in_field(field), -1.001142 | 1e-7 * units.kg * units.m**2 / units.s**2, 5) field.position *= ((5 | units.m) / field.position.lengths()).reshape((-1, 1)) # spherical shell around particles potential_energy = particles.potential_energy_in_field(field) particles.position += [0, 1, 2] | units.m # as long as particles remain inside the shell, the potential doesn't change self.assertAlmostEquals(particles.potential_energy_in_field(field), potential_energy, 5) particles.mass = [1, 2] | units.kg self.assertAlmostRelativeEquals(particles.potential(), -constants.G * ([2, 1] | units.kg / units.m)) self.assertAlmostRelativeEquals(particles.potential()[0], particles[0].potential()) self.assertAlmostRelativeEquals(particles.potential()[1], particles[1].potential())
def test58(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test58"+self.store_version()+".h5") if os.path.exists(output_file): os.remove(output_file) x = Particles(keys = (1,2)) x.mass = [1,2] | units.kg y = Particles(keys = (11,12,13,14)) y.mass = [40,50,60,70] | units.kg x.sub = None x[0].sub = y[0:2] y[0].sub = y[2:] io.write_set_to_file(x, output_file,"amuse", version=self.store_version()) z = io.read_set_from_file(output_file,"amuse") self.assertEqual(len(x), len(z)) self.assertEqual(len(x[0].sub), len(z[0].sub)) self.assertEqual(x[0].sub[0].sub.key, (13,14)) self.assertEqual(z[0].sub[0].sub.key, (13,14)) self.assertEqual(id(x[0].sub._original_set()), id(x[0].sub[0].sub._original_set())) # no more subsets, could this be fixed, would be very nice to do so # self.assertEqual(id(z[0].sub._original_set()), id(z[0].sub[0].sub._original_set())) self.assertTrue(z[1].sub==x[1].sub==None) os.remove(output_file)
def test10(self): print "Testing MI6 collision_detection" particles = Particles(7) particles.mass = 0.00000001 | nbody_system.mass particles.radius = 0.0001 | nbody_system.length particles.x = [-101.0, -100.0, -0.5, 0.5, 100.0, 101.0, 104.0] | nbody_system.length particles.y = 0 | nbody_system.length particles.z = 0 | nbody_system.length particles.velocity = [[2, 0, 0], [-2, 0, 0]] * 3 + [[-4, 0, 0]] | nbody_system.speed instance = MI6(**default_options) instance.initialize_code() instance.parameters.set_defaults() instance.particles.add_particles(particles) collisions = instance.stopping_conditions.collision_detection collisions.enable() instance.evolve_model(1.0 | nbody_system.time) self.assertTrue(collisions.is_set()) self.assertAlmostEquals( instance.model_time, -(particles[0].x - particles[1].x) / (particles[0].vx - particles[1].vx), 3 ) self.assertEquals(len(collisions.particles(0)), 3) self.assertEquals(len(collisions.particles(1)), 3) self.assertEquals(len(particles - collisions.particles(0) - collisions.particles(1)), 1) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) < (collisions.particles(0).radius + collisions.particles(1).radius), [True, True, True], ) sticky_merged = Particles(len(collisions.particles(0))) sticky_merged.mass = collisions.particles(0).mass + collisions.particles(1).mass sticky_merged.radius = collisions.particles(0).radius for p1, p2, merged in zip(collisions.particles(0), collisions.particles(1), sticky_merged): merged.position = (p1 + p2).center_of_mass() merged.velocity = (p1 + p2).center_of_mass_velocity() print instance.model_time print instance.particles instance.particles.remove_particles(collisions.particles(0) + collisions.particles(1)) instance.particles.add_particles(sticky_merged) instance.evolve_model(1.0 | nbody_system.time) print print instance.model_time print instance.particles self.assertTrue(collisions.is_set()) self.assertAlmostEquals( instance.model_time, -(particles[6].x - 0.5 * (particles[4].x + particles[5].x)) / particles[6].vx, 3 ) self.assertEquals(len(collisions.particles(0)), 1) self.assertEquals(len(collisions.particles(1)), 1) self.assertEquals(len(instance.particles - collisions.particles(0) - collisions.particles(1)), 2) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) < (collisions.particles(0).radius + collisions.particles(1).radius), [True], ) instance.stop()
def xtest10(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print "Testing Sakura collision_detection" particles = Particles(7) particles.mass = 0.00000001 | nbody_system.mass particles.radius = 0.01 | nbody_system.length particles.x = [-101.0, -100.0, -0.5, 0.5, 100.0, 101.0, 104.0] | nbody_system.length particles.y = 0 | nbody_system.length particles.z = 0 | nbody_system.length particles.velocity = [[2, 0, 0], [-2, 0, 0]] * 3 + [[-4, 0, 0]] | nbody_system.speed instance = Sakura() instance.initialize_code() instance.parameters.set_defaults() instance.particles.add_particles(particles) collisions = instance.stopping_conditions.collision_detection collisions.enable() instance.evolve_model(1.0 | nbody_system.time) self.assertTrue(collisions.is_set()) self.assertTrue(instance.model_time < 0.5 | nbody_system.time) self.assertEquals(len(collisions.particles(0)), 3) self.assertEquals(len(collisions.particles(1)), 3) self.assertEquals(len(particles - collisions.particles(0) - collisions.particles(1)), 1) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) < (collisions.particles(0).radius + collisions.particles(1).radius), [True, True, True], ) sticky_merged = Particles(len(collisions.particles(0))) sticky_merged.mass = collisions.particles(0).mass + collisions.particles(1).mass sticky_merged.radius = collisions.particles(0).radius for p1, p2, merged in zip(collisions.particles(0), collisions.particles(1), sticky_merged): merged.position = (p1 + p2).center_of_mass() merged.velocity = (p1 + p2).center_of_mass_velocity() print instance.model_time print instance.particles instance.particles.remove_particles(collisions.particles(0) + collisions.particles(1)) instance.particles.add_particles(sticky_merged) instance.evolve_model(1.0 | nbody_system.time) print print instance.model_time print instance.particles self.assertTrue(collisions.is_set()) self.assertTrue(instance.model_time < 1.0 | nbody_system.time) self.assertEquals(len(collisions.particles(0)), 1) self.assertEquals(len(collisions.particles(1)), 1) self.assertEquals(len(instance.particles - collisions.particles(0) - collisions.particles(1)), 2) self.assertEquals( abs(collisions.particles(0).x - collisions.particles(1).x) < (collisions.particles(0).radius + collisions.particles(1).radius), [True], ) instance.stop()
def test6(self): print "Test whether a set of stars evolves synchronously..." # Create an array of stars with a range in stellar mass masses = [.5, 1., 2., 5., 10., 30.] | units.MSun number_of_stars = len(masses) stars = Particles(number_of_stars) stars.mass = masses # Initialize stellar evolution code instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() from_code_to_model = instance.particles.new_channel_to(stars) from_code_to_model.copy() instance.evolve_model(end_time = 125 | units.Myr) from_code_to_model.copy() end_types = ( "deeply or fully convective low mass MS star", "Main Sequence star", "Main Sequence star", "Carbon/Oxygen White Dwarf", "Neutron Star", "Black Hole", ) for i in range(number_of_stars): self.assertAlmostEquals(stars[i].age, 125.0 | units.Myr) self.assertTrue(stars[i].mass <= masses[i]) self.assertEquals(str(stars[i].stellar_type), end_types[i]) instance.stop()
def test12(self): print "Testing adding and removing particles from stellar evolution code..." particles = Particles(3) particles.mass = 1.0 | units.MSun instance = SSE() instance.initialize_code() instance.commit_parameters() self.assertEquals(len(instance.particles), 0) # before creation instance.particles.add_particles(particles[:-1]) instance.commit_particles() instance.evolve_model(1.0 | units.Myr) self.assertEquals(len(instance.particles), 2) # before remove self.assertAlmostEqual(instance.particles.age, 1.0 | units.Myr) instance.particles.remove_particle(particles[0]) self.assertEquals(len(instance.particles), 1) instance.evolve_model(2.0 | units.Myr) self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) instance.particles.add_particles(particles[::2]) self.assertEquals(len(instance.particles), 3) # it's back... self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) self.assertAlmostEqual(instance.particles[1].age, 0.0 | units.Myr) self.assertAlmostEqual(instance.particles[2].age, 0.0 | units.Myr) # ... and rejuvenated. instance.evolve_model(3.0 | units.Myr) # The young stars keep their age offset from the old star self.assertAlmostEqual(instance.particles.age, [3.0, 1.0, 1.0] | units.Myr) instance.evolve_model(4.0 | units.Myr) self.assertAlmostEqual(instance.particles.age, [4.0, 2.0, 2.0] | units.Myr) instance.stop()
def new_colliders(self): colliders = Particles(2) colliders.mass = [5, 2] | units.MSun colliders.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.RSun colliders.velocity = [[0.0, 0.0, 0.0], [0.0, 2000.0, 0.0]] | units.km / units.s colliders.move_to_center() return colliders
def test1(self): particles = Particles(2) particles.mass = [1.0, 1.0] | nbody_system.mass particles.radius = [0.0001, 0.0001] | nbody_system.length particles.position = [[0.0,0.0,0.0], [2.0,0.0,0.0]] | nbody_system.length particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | nbody_system.speed instance = bridge.CalculateFieldForParticles(particles = particles, gravity_constant = nbody_system.G) zero = 0.0 | nbody_system.length print(instance.get_gravity_at_point([zero], [1.0] | nbody_system.length, [zero], [zero])) fx, fy, fz = instance.get_gravity_at_point([zero], [1.0] | nbody_system.length, [zero], [zero]) self.assertAlmostEqual(fx, [0.0] | nbody_system.acceleration, 6) self.assertAlmostEqual(fy, [0.0] | nbody_system.acceleration, 6) self.assertAlmostEqual(fz, [0.0] | nbody_system.acceleration, 6) for x in (0.25, 0.5, 0.75): x0 = x | nbody_system.length x1 = (2.0 - x) | nbody_system.length potential0 = instance.get_potential_at_point([zero], [x0], [zero], [zero]) potential1 = instance.get_potential_at_point([zero], [x1], [zero], [zero]) fx0, fy0, fz0 = instance.get_gravity_at_point([zero], [x0], [zero], [zero]) fx1, fy1, fz1 = instance.get_gravity_at_point([zero], [x1], [zero], [zero]) self.assertAlmostEqual(fy0[0], 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(fz0[0], 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(fy1[0], 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(fz1[0], 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(fx0, -1.0 * fx1, 5) fx = (-1.0 / (x0**2) + 1.0 / (x1**2)) * (1.0 | nbody_system.length ** 3 / nbody_system.time ** 2) self.assertAlmostEqual(fx, fx0[0], 5) self.assertAlmostEqual(potential0, potential1, 6)
def test3(self): self.assertRaises( AmuseException, StickySpheres, mass_loss=-0.1, expected_message="Mass-loss fraction must be in the range [0, 1)") self.assertRaises( AmuseException, StickySpheres, mass_loss=1.0, expected_message="Mass-loss fraction must be in the range [0, 1)") particles = Particles(6) particles.mass = range(1, 7) | units.kg particles.position = [[i, 1.0, 2.0] for i in range(1, 7)] | units.m particles.velocity = [[1.0, 0.0, 1.0], [0.0, -1.0, -1.0] ] | units.m / units.s for fraction in [0.01, 0.1, 0.5]: sticky_spheres = StickySpheres(mass_loss=fraction) for i in range(0, 6, 2): colliders = particles[i:i + 2] merged = sticky_spheres.handle_collision( colliders[0], colliders[1]) self.assertTrue(isinstance(merged, Particles)) self.assertAlmostEqual(merged.mass, (2 * i + 3.0) * (1 - fraction) | units.kg) self.assertAlmostEqual(merged.position, [((i + 1)**2 + (i + 2)**2) / (2 * i + 3.0), 1.0, 2.0] | units.m) self.assertAlmostEqual( merged.velocity, ([i + 1, -(i + 2), -1.0] | units.m / units.s) / (2 * i + 3.0))
def _planets_only(define_mercury_attributes = False): data = numpy.array([tuple(entry) for entry in _solsysdat], dtype=[('name','S10'), ('mass','<f8'), ('celimit','<f8'), ('density','<f8'), ('x','<f8'), ('y','<f8'), ('z','<f8'), ('vx','<f8'), ('vy','<f8'), ('vz','<f8'), ('Lx','<f8'), ('Ly','<f8'), ('Lz','<f8')]) planets = Particles(len(_solsysdat)) planets.name = list(data['name']) print planets.name.dtype planets.mass = units.MSun.new_quantity(data['mass']) density = (units.g/units.cm**3).new_quantity(data['density']) planets.radius = ((planets.mass/density) ** (1/3.0)).as_quantity_in(units.km) for attribute in ['x', 'y', 'z']: setattr(planets, attribute, units.AU.new_quantity(data[attribute])) for attribute in ['vx', 'vy', 'vz']: setattr(planets, attribute, units.AUd.new_quantity(data[attribute]).as_quantity_in(units.km / units.s)) if define_mercury_attributes: planets.density = density angular_momentum_unit = units.MSun * units.AU**2/units.day for attribute in ['Lx', 'Ly', 'Lz']: setattr(planets, attribute, angular_momentum_unit.new_quantity(data[attribute]).as_quantity_in(units.J * units.s)) planets.celimit = units.none.new_quantity(data['celimit']) return planets
def test3(self): print "Testing SinkParticles initialization from existing particles in set" particles = Particles(10) self.assertRaises(AttributeError, SinkParticles, particles[[4, 7]], expected_message= "You tried to access attribute 'radius' but this attribute is not defined for this set.") particles.radius = 42.0 | units.RSun particles.mass = range(1,11) | units.MSun particles.position = [[i, 2*i, 3*i] for i in range(10)] | units.parsec sinks = SinkParticles(particles[[4]]) self.assertEqual(sinks.mass, 5.0 | units.MSun) self.assertEqual(sinks.sink_radius, 42.0 | units.RSun) self.assertEqual(sinks.radius, 42.0 | units.RSun) self.assertEqual(sinks.position, [4.0, 8.0, 12.0] | units.parsec) sinks = SinkParticles(particles[[4, 7]], sink_radius=[1,2]|units.AU) self.assertEqual(sinks.sink_radius, [1.0, 2.0] | units.AU) self.assertEqual(sinks.radius, 42.0 | units.RSun) self.assertEqual(sinks.mass, [5.0, 8.0] | units.MSun) self.assertEqual(sinks.position, [[4, 8, 12], [7, 14, 21]] | units.parsec) self.assertEqual(set(['key', 'mass', 'radius', 'x', 'y', 'z', 'sink_radius', 'vx','vy','vz','lx','ly','lz']), set(str(sinks).split("\n")[0].split())) self.assertEqual(set(['key', 'mass', 'radius', 'x', 'y', 'z']), set(str(particles).split("\n")[0].split()))
def test7(self): particles = Particles(10) particles.mass = list(range(10)) | units.kg particles[0].child1 = particles[1] particles[0].child2 = particles[2] particles[1].child1 = particles[3] particles[1].child2 = particles[4] x = trees.BinaryTreesOnAParticleSet(particles, "child1", "child2") roots = list(x.iter_roots()) self.assertEqual(len(roots), 1) binary = roots[0] output = '' for level, particle in binary.iter_levels(): output += '..' * level output += str(particle.mass.value_in(units.kg)) output += '\n' self.assertEqual(output, """0.0 ..1.0 ....3.0 ....4.0 ..2.0 """)
def setup_stellar_evolution_model(): out_pickle_file = os.path.join( get_path_to_results(), "super_giant_stellar_structure.pkl") if os.path.exists(out_pickle_file): return out_pickle_file stellar_evolution = MESA(redirection="none") stars = Particles(1) stars.mass = 10.0 | units.MSun stellar_evolution.initialize_module_with_default_parameters() stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() print( "Evolving a MESA star with mass:", stellar_evolution.particles[0].mass ) try: while True: stellar_evolution.evolve_model() except AmuseException as ex: print "Evolved star to", stellar_evolution.particles[0].age print "Radius:", stellar_evolution.particles[0].radius pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file) stellar_evolution.stop() return out_pickle_file
def test5(self): print "Testing SinkParticles accrete, one particle within two sinks' radii" particles = Particles(10) particles.radius = 42.0 | units.RSun particles.mass = range(1,11) | units.MSun particles.position = [[i, 2*i, 3*i] for i in range(10)] | units.parsec particles.velocity = [[i, 0, -i] for i in range(10)] | units.km/units.s particles.age = range(10) | units.Myr copy = particles.copy() sinks = SinkParticles(particles[[3, 7]], sink_radius=[4,12]|units.parsec,looping_over=self.looping_over) self.assertEqual(sinks.sink_radius, [4.0, 12.0] | units.parsec) self.assertEqual(sinks.mass, [4.0, 8.0] | units.MSun) self.assertEqual(sinks.position, [[3, 6, 9], [7, 14, 21]] | units.parsec) sinks.accrete(particles) self.assertEqual(len(particles), 4) # 6 particles were accreted self.assertEqual(sinks.mass, [12.0, 40.0] | units.MSun) # mass of sinks increased self.assertEqual(sinks.get_intersecting_subset_in(particles).mass, [12.0, 40.0] | units.MSun) # original particles' masses match self.assertEqual(particles.total_mass(), copy.total_mass()) # total mass is conserved self.assertEqual(particles.center_of_mass(), copy.center_of_mass()) # center of mass is conserved self.assertEqual(particles.center_of_mass_velocity(), copy.center_of_mass_velocity()) # center of mass velocity is conserved self.assertEqual(particles.total_momentum(), copy.total_momentum()) # momentum is conserved self.assertEqual(particles.total_angular_momentum()+sinks.angular_momentum.sum(axis=0), copy.total_angular_momentum()) # angular_momentum is conserved
def test17(self): print("evolve_one_step and evolve_for after particle removal and addition") particles = Particles(10) particles.mass = list(range(1, 11)) | units.MSun instance = MOSSE() instance.particles.add_particles(particles) self.assertAlmostEqual(instance.particles.age, 0.0 | units.yr) time_steps = numpy.linspace(0.1, 1.0, num=10) | units.Myr for i in range(10): instance.particles[i].evolve_for(time_steps[i]) self.assertAlmostEqual(instance.particles.age, time_steps) instance.particles.remove_particles(particles[[1, 4, 8]]) revived = instance.particles.add_particle(particles[4]) revived.evolve_for(numpy.pi | units.Myr) for star in instance.particles: star.evolve_for(star.age) self.assertAlmostEqual(instance.particles.age[:-1], 2*time_steps[[0, 2,3, 5,6,7, 9]]) self.assertAlmostEqual(instance.particles.age[-1], 2*numpy.pi | units.Myr) instance.particles.remove_particles(particles[[2, 5, 6]]) instance.particles.add_particles(particles[[8, 1]]) self.assertEqual(len(instance.particles), 7) expected_ages = instance.particles.age + instance.particles.time_step for star in instance.particles: star.evolve_one_step() self.assertAlmostEqual(instance.particles.age, expected_ages) instance.stop()
def test12(self): print("Testing adding and removing particles from stellar evolution code...") particles = Particles(3) particles.mass = 1.0 | units.MSun instance = MOSSE() instance.initialize_code() instance.commit_parameters() self.assertEqual(len(instance.particles), 0) # before creation instance.particles.add_particles(particles[:-1]) instance.commit_particles() instance.evolve_model(1.0 | units.Myr) self.assertEqual(len(instance.particles), 2) # before remove self.assertAlmostEqual(instance.particles.age, 1.0 | units.Myr) instance.particles.remove_particle(particles[0]) self.assertEqual(len(instance.particles), 1) instance.evolve_model(2.0 | units.Myr) self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) instance.particles.add_particles(particles[::2]) self.assertEqual(len(instance.particles), 3) # it's back... self.assertAlmostEqual(instance.particles[0].age, 2.0 | units.Myr) self.assertAlmostEqual(instance.particles[1].age, 0.0 | units.Myr) self.assertAlmostEqual(instance.particles[2].age, 0.0 | units.Myr) # ... and rejuvenated. instance.evolve_model(3.0 | units.Myr) # The young stars keep their age offset from the old star self.assertAlmostEqual(instance.particles.age, [3.0, 1.0, 1.0] | units.Myr) instance.evolve_model(4.0 | units.Myr) self.assertAlmostEqual(instance.particles.age, [4.0, 2.0, 2.0] | units.Myr) instance.stop()
def test11(self): print("Test evolve_model optional arguments: end_time and keep_synchronous") stars = Particles(3) stars.mass = [1.0, 2.0, 3.0] | units.MSun instance = MOSSE() instance.commit_parameters() instance.particles.add_particles(stars) self.assertEqual(instance.particles.age, [0.0, 0.0, 0.0] | units.yr) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.877] | units.Myr, 2) self.assertAlmostEqual(instance.particles.radius, [0.8882494502, 1.610210385, 1.979134445] | units.RSun) print("evolve_model without arguments: use shared timestep = min(particles.time_step)") instance.evolve_model() self.assertAlmostEqual(instance.particles.age, [18.877, 18.877, 18.877] | units.Myr, 2) self.assertAlmostEqual(instance.particles.time_step, [550.157, 58.208, 18.877] | units.Myr, 2) self.assertAlmostEqual(instance.model_time, 18.877 | units.Myr, 2) print("evolve_model with end_time: take timesteps, until end_time is reached exactly") instance.evolve_model(100 | units.Myr) self.assertAlmostEqual(instance.particles.age, [100.0, 100.0, 100.0] | units.Myr, 2) self.assertAlmostEqual(instance.particles.time_step, [550.157, 58.208, 18.877] | units.Myr, 2) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 2) print("evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge") instance.evolve_model(keep_synchronous = False) self.assertAlmostEqual(instance.particles.age, (100 | units.Myr) + ([550.157, 58.208, 18.877] | units.Myr), 2) self.assertAlmostEqual(instance.particles.time_step, [550.157, 58.208, 18.877] | units.Myr, 2) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 2) # Unchanged! instance.stop()
def test17(self): print "evolve_one_step and evolve_for after particle removal and addition" particles = Particles(10) particles.mass = range(1, 11) | units.MSun instance = SSE() instance.particles.add_particles(particles) self.assertAlmostEqual(instance.particles.age, 0.0 | units.yr) time_steps = numpy.linspace(0.1, 1.0, num=10) | units.Myr for i in range(10): instance.particles[i].evolve_for(time_steps[i]) self.assertAlmostEqual(instance.particles.age, time_steps) instance.particles.remove_particles(particles[[1, 4, 8]]) revived = instance.particles.add_particle(particles[4]) revived.evolve_for(numpy.pi | units.Myr) for star in instance.particles: star.evolve_for(star.age) self.assertAlmostEqual(instance.particles.age[:-1], 2*time_steps[[0, 2,3, 5,6,7, 9]]) self.assertAlmostEqual(instance.particles.age[-1], 2*numpy.pi | units.Myr) instance.particles.remove_particles(particles[[2, 5, 6]]) instance.particles.add_particles(particles[[8, 1]]) self.assertEqual(len(instance.particles), 7) expected_ages = instance.particles.age + instance.particles.time_step for star in instance.particles: star.evolve_one_step() self.assertAlmostEqual(instance.particles.age, expected_ages) instance.stop()
def make_galaxies(): if os.path.exists('disk_galactICs.amuse'): galaxy1 = read_set_from_file('disk_galactICs.amuse', 'amuse') else: halo_number_of_particles = NHALO converter = nbody_system.nbody_to_si( 1.0e9 | units.MSun, 1. | units.kpc) galaxy1 = new_galactics_model( halo_number_of_particles, disk_number_of_particles=NDISK, generate_bulge_flag=False, unit_system_converter=converter, disk_random_seed=12345) write_set_to_file(galaxy1, 'disk_galactICs.amuse', 'amuse') galaxy2 = Particles(len(galaxy1)) galaxy2.mass = galaxy1.mass galaxy2.position = galaxy1.position galaxy2.velocity = galaxy1.velocity galaxy1.rotate(0.0, numpy.pi/4, 0.0) galaxy2.rotate(numpy.pi/6, 0.0, 0.0) galaxy1.position += [100.0, 0, 0] | units.kpc galaxy2.position -= [100.0, 0, 0] | units.kpc galaxy1.velocity += [0.0, 50.0, 0] | units.km/units.s galaxy2.velocity -= [0.0, 50.0, 0] | units.km/units.s return galaxy1, galaxy2
def test4(self): print "Testing Pikachu evolve_model, 2 particles" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Pikachu, converter, **default_options) instance.initialize_code() instance.parameters.timestep = 0.0125 * math.pi * particles[0].x / particles[0].vy instance.parameters.rcut_out_star_star = 10.0 | units.AU instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test4(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test4" + self.store_version() + ".hdf5") if os.path.exists(output_file): os.remove(output_file) particles = Particles(10) particles.mass = 1.0 | units.kg particles.x = 2.0 | units.m x = particles.savepoint(2.0 | units.s) io.write_set_to_file(x, output_file, format='amuse', version=self.store_version()) particles_from_file = io.read_set_from_file( output_file, format='amuse', version=self.store_version(), close_file=True) particles_in_memory = particles_from_file.copy() self.assertAlmostRelativeEquals(particles_in_memory.mass[1], 1.0 | units.kg) particles_in_memory.savepoint(4.0 | units.s) self.assertAlmostRelativeEquals(particles_from_file.mass[2], 1.0 | units.kg)
def new_solar_system_for_mercury(): """ Create initial conditions for the symplectic integrator Mercury, describing the solar system. Returns a tuple consisting of two particle sets. The first set contains the central particle (sun) and the second contains the planets and Pluto (the 'orbiters'). The positions and velocities are in heliocentric coordinates. Defined attributes sun: name, mass, radius, j2, j4, j6, Lx, Ly, Lz Defined attributes orbiters: name, mass, radius, density, x, y, z, vx, vy, vz, Lx, Ly, Lz, celimit """ planets = _planets_only(define_mercury_attributes=True) centre = Particles(1) centre.name = 'SUN' centre.mass = 1.0 | units.MSun centre.radius = 0.0000001 | units.AU centre.j2 = .0001 | units.AU**2 centre.j4 = .0 | units.AU**4 centre.j6 = .0 | units.AU**6 centre.angular_momentum = [0.0, 0.0, 0.0 ] | units.MSun * units.AU**2 / units.day return centre, planets
def test24(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test24" + self.store_version() + ".hdf5") if os.path.exists(output_file): os.remove(output_file) particles = Particles(20) #~ particles = Particles(1000000) # For testing memory usage particles.mass = 1.0 | units.kg particles.position = [0.0, 0.0, 0.0] | units.m for i in range(10): particles.position += [1.0, 2.0, 3.0] | units.m io.write_set_to_file(particles, output_file, format='amuse', version=self.store_version()) particles_from_file = io.read_set_from_file( output_file, format='amuse', version=self.store_version()) os.remove(output_file) self.assertEqual(len(list(particles_from_file.history)), 10) for i, snap in enumerate(particles_from_file.history): self.assertEqual(len(snap), 20) self.assertEqual((i + 1) * ([1.0, 2.0, 3.0] | units.m), snap.center_of_mass())
def test3(self): print("Testing SinkParticles initialization from existing particles in set") particles = Particles(10) self.assertRaises(AttributeError, SinkParticles, particles[[4, 7]], expected_message= "You tried to access attribute 'radius' but this attribute is not defined for this set.") particles.radius = 42.0 | units.RSun particles.mass = list(range(1,11)) | units.MSun particles.position = [[i, 2*i, 3*i] for i in range(10)] | units.parsec sinks = SinkParticles(particles[[4]]) self.assertEqual(sinks.mass, 5.0 | units.MSun) self.assertEqual(sinks.sink_radius, 42.0 | units.RSun) self.assertEqual(sinks.radius, 42.0 | units.RSun) self.assertEqual(sinks.position, [4.0, 8.0, 12.0] | units.parsec) sinks = SinkParticles(particles[[4, 7]], sink_radius=[1,2]|units.AU) self.assertEqual(sinks.sink_radius, [1.0, 2.0] | units.AU) self.assertEqual(sinks.radius, 42.0 | units.RSun) self.assertEqual(sinks.mass, [5.0, 8.0] | units.MSun) self.assertEqual(sinks.position, [[4, 8, 12], [7, 14, 21]] | units.parsec) self.assertEqual(set(['key', 'mass', 'radius', 'x', 'y', 'z', 'sink_radius', 'vx','vy','vz','lx','ly','lz']), set(str(sinks).split("\n")[0].split())) self.assertEqual(set(['key', 'mass', 'radius', 'x', 'y', 'z']), set(str(particles).split("\n")[0].split()))
def test25(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) particles = Particles(20) #~ particles = Particles(1000000) # For testing memory usage particles.mass = 1.0 | units.kg particles.position = [0.0, 0.0, 0.0] | units.m for i in range(10): particles.position += [1.0, 2.0, 3.0] | units.m io.write_set_to_file(particles, output_file, format='amuse', version=self.store_version()) particles_from_file = io.read_set_from_file( output_file, format='amuse', version=self.store_version(), copy_history=True, close_file=True) history = list(particles_from_file.history) self.assertEqual(len(history), 10) self.assertFalse( "HDF" in str(type(history[1]._private.attribute_storage))) for i, snap in enumerate(particles_from_file.history): self.assertEqual(len(snap), 20) self.assertEqual((i + 1) * ([1.0, 2.0, 3.0] | units.m), snap.center_of_mass()) os.remove(output_file)
def test13(self): print("Testing SSE states") stars = Particles(1) stars.mass = 1.0 | units.MSun print("First do everything manually:", end=' ') instance = SSE() self.assertEqual(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.initialize_code() self.assertEqual(instance.get_name_of_current_state(), 'INITIALIZED') instance.commit_parameters() self.assertEqual(instance.get_name_of_current_state(), 'RUN') instance.cleanup_code() self.assertEqual(instance.get_name_of_current_state(), 'END') instance.stop() print("ok") print("initialize_code(), commit_parameters(), " \ "and cleanup_code() should be called automatically:", end=' ') instance = SSE() self.assertEqual(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.parameters.reimers_mass_loss_coefficient = 0.5 self.assertEqual(instance.get_name_of_current_state(), 'INITIALIZED') instance.particles.add_particles(stars) self.assertEqual(instance.get_name_of_current_state(), 'RUN') instance.stop() self.assertEqual(instance.get_name_of_current_state(), 'STOPPED') print("ok")
def test30(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test30" + self.store_version() + ".hdf5") if os.path.exists(output_file): os.remove(output_file) particles = Particles(10) particles.mass = 10 | units.kg io.write_set_to_file(particles, output_file, format='amuse', version=self.store_version()) output = io.read_set_from_file(output_file, format='amuse', allow_writing=True) output.new_attribute = 2 * output.mass self.assertEqual(output.new_attribute, 2 * output.mass) output = next(output.iter_history()) output.new_attribute = 2 * output.mass self.assertEqual(output.new_attribute, 2 * output.mass)
def test5(self): print "Testing MI6 evolve_model, 2 particles, no SMBH" particles = Particles(2) particles.mass = 1.0 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (2.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() print particles converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = MI6(converter, **default_options) instance.initialize_code() instance.parameters.smbh_mass = 0.0 | units.MSun instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 3) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 3) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 3) instance.cleanup_code() instance.stop()
def test5(self): particles = Particles(10) particles.mass = list(range(10)) | units.kg particles[0].child1 = particles[1] particles[0].child2 = particles[2] particles[1].child1 = particles[3] particles[1].child2 = particles[4] x = particles.as_binary_tree() roots = list(x.iter_branches()) self.assertEqual(len(roots), 1) binary = roots[0] output = '' for level, node in binary.iter_levels(): output += '..' * level output += str(node.particle.mass.value_in(units.kg)) output += '\n' self.assertEqual(output, """0.0 ..1.0 ....3.0 ....4.0 ..2.0 """)
def result(self): masses, position_vectors, velocity_vectors = self.new_model() result = Particles(self.targetN) result.mass = masses result.position = position_vectors result.velocity = velocity_vectors return result
def test2(self): print "Test basic particle attributes and scale_to_standard - SI units" convert_nbody = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.parsec) particles = Particles(2) particles.position = [[-1, 0, 0], [1,0,0]] | units.parsec particles.velocity = [[-1, 0, 0], [1,0,0]] | units.parsec / units.Myr particles.mass = 0.5 | units.MSun self.assertAlmostRelativeEquals(particles.total_mass(), 1.0 | units.MSun) self.assertAlmostRelativeEquals(particles.kinetic_energy(), 1.0 * (0.5 | units.MSun) * (1 |units.parsec / units.Myr) **2 ) self.assertAlmostRelativeEquals(particles.potential_energy(), -constants.G * (0.5 | units.MSun) ** 2 / ([2,0,0] | units.parsec).length() ) self.assertAlmostRelativeEquals(particles.virial_radius(), 4.0 | units.parsec) particles.scale_to_standard(convert_nbody) self.assertAlmostRelativeEquals(particles.total_mass(), convert_nbody.to_si(1.0 | nbody_system.mass)) self.assertAlmostRelativeEquals(particles.kinetic_energy(), convert_nbody.to_si(0.25 | nbody_system.energy)) self.assertAlmostRelativeEquals(particles.potential_energy().as_quantity_in(units.J), convert_nbody.to_si(-0.5 | nbody_system.energy).as_quantity_in(units.J), 12) self.assertAlmostRelativeEquals(particles.virial_radius(), convert_nbody.to_si(1.0 | nbody_system.length)) particles.scale_to_standard(convert_nbody, virial_ratio=1) # unbound self.assertAlmostRelativeEquals(particles.kinetic_energy(), 0.5 * constants.G * (1 | units.MSun**2 / units.parsec), 13) self.assertAlmostRelativeEquals(particles.potential_energy(), -0.5 * constants.G * (1 | units.MSun**2 / units.parsec)) particles.scale_to_standard(convert_nbody, virial_ratio=0) # velocities zeroed self.assertAlmostRelativeEquals(particles.kinetic_energy(), 0 | units.J) self.assertAlmostRelativeEquals(particles.potential_energy(), -0.5 * constants.G * (1 | units.MSun**2 / units.parsec))
def test11(self): print "Test evolve_model optional arguments: end_time and keep_synchronous" stars = Particles(3) stars.mass = [1.0, 2.0, 3.0] | units.MSun instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) self.assertEqual(instance.particles.age, [0.0, 0.0, 0.0] | units.yr) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.particles.radius, [0.8882494502, 1.610210385, 1.979134445] | units.RSun) print "evolve_model without arguments: use shared timestep = min(particles.time_step)" instance.evolve_model() self.assertAlmostEqual(instance.particles.age, [18.8768, 18.8768, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 18.8768 | units.Myr, 3) print "evolve_model with end_time: take timesteps, until end_time is reached exactly" instance.evolve_model(100 | units.Myr) self.assertAlmostEqual(instance.particles.age, [100.0, 100.0, 100.0] | units.Myr, 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3) print "evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge" instance.evolve_model(keep_synchronous = False) self.assertAlmostEqual(instance.particles.age, (100 | units.Myr) + ([550.1565, 58.2081, 18.8768] | units.Myr), 3) self.assertAlmostEqual(instance.particles.time_step, [550.1565, 58.2081, 18.8768] | units.Myr, 3) self.assertAlmostEqual(instance.model_time, 100.0 | units.Myr, 3) # Unchanged! instance.stop()
def set_up_initial_conditions(orbital_period, kinetic_to_potential_ratio): print("Setting up initial conditions") stars = Particles(2) stars.mass = [10.0, 1.0] | units.MSun stars.radius = 0 | units.RSun stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s print("Binary with masses: "+str(stars.mass) + ", and orbital period: ", orbital_period) semimajor_axis = ((constants.G * stars.total_mass() * (orbital_period / (2 * pi))**2.0)**(1.0/3.0)) separation = 2 * semimajor_axis * (1 - kinetic_to_potential_ratio) print("Initial separation:", separation.as_quantity_in(units.AU)) relative_velocity = ( (kinetic_to_potential_ratio / (1.0 - kinetic_to_potential_ratio)) * constants.G * stars.total_mass() / semimajor_axis ).sqrt() print("Initial relative velocity:", relative_velocity.as_quantity_in(units.km / units.s)) stars[0].x = separation stars[0].vy = relative_velocity stars.move_to_center() return stars
def test13(self): print "Testing SSE states" stars = Particles(1) stars.mass = 1.0 | units.MSun print "First do everything manually:", instance = SSE() self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.initialize_code() self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') instance.commit_parameters() self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.cleanup_code() self.assertEquals(instance.get_name_of_current_state(), 'END') instance.stop() print "ok" print "initialize_code(), commit_parameters(), " \ "and cleanup_code() should be called automatically:", instance = SSE() self.assertEquals(instance.get_name_of_current_state(), 'UNINITIALIZED') instance.parameters.reimers_mass_loss_coefficient = 0.5 self.assertEquals(instance.get_name_of_current_state(), 'INITIALIZED') instance.particles.add_particles(stars) self.assertEquals(instance.get_name_of_current_state(), 'RUN') instance.stop() self.assertEquals(instance.get_name_of_current_state(), 'STOPPED') print "ok"
def test2(self): print("Testing SinkParticles initialization from existing particles") original = Particles(3) self.assertRaises( AttributeError, SinkParticles, original, expected_message= "You tried to access attribute 'radius' but this attribute is not defined for this set." ) original.radius = 42.0 | units.RSun original.mass = 10.0 | units.MSun original.position = [[i, -i, 2 * i] for i in range(3)] | units.parsec sinks = SinkParticles(original) self.assertEqual(sinks.sink_radius, 42.0 | units.RSun) self.assertEqual(sinks.mass, 10.0 | units.MSun) self.assertEqual(sinks.position, [[0, 0, 0], [1, -1, 2], [2, -2, 4]] | units.parsec) self.assertRaises( AttributeError, getattr, sinks, "bogus", expected_message= "You tried to access attribute 'bogus' but this attribute is not defined for this set." )
def new_sun_earth_system(self): particles = Particles(2) particles.mass = [1.0, 3.0037e-6] | units.MSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * particles.total_mass() / (1.0 | units.AU)).sqrt() return particles
def result(self): masses, position_vectors, velocity_vectors = self.new_model() result = Particles(self.targetN) result.mass = masses result.position = position_vectors result.velocity = velocity_vectors return result
def test9(self): test_results_path = self.get_path_to_results() output_file = os.path.join(test_results_path, "test9"+self.store_version()+".hdf5") if os.path.exists(output_file): os.remove(output_file) number_of_particles = 10 p = Particles(number_of_particles) p.mass = [x * 2.0 for x in range(number_of_particles)] | units.kg p.model_time = 2.0 | units.s io.write_set_to_file( p, output_file, "hdf5", timestamp = 2 | units.Myr, scale = 1 | units.kg, version = self.store_version(), close_file = True ) loaded_particles = io.read_set_from_file( output_file, "hdf5", version = self.store_version() ) loaded_particles = self.get_version_in_store(loaded_particles) a = loaded_particles.collection_attributes self.assertAlmostRelativeEquals(a.timestamp, 2 | units.Myr) self.assertAlmostRelativeEquals(a.scale, 1 | units.kg)
def add_comets(star, m_comets, n_comets, q_min, a_min, a_max, seed): #bodies.position -= star.position #bodies.velocity -= star.velocity cloud_xyz = generate_initial_oort_cloud(star.mass, n_comets, q_min, a_min, a_max, seed) masses = new_salpeter_mass_distribution(n_comets, 0.1 | units.MSun, 100 | units.MSun) masses = m_comets * masses / masses.sum() print("total mass in comets: M=", masses.sum().in_(units.MEarth)) comets = Particles(n_comets) comets.mass = masses comets.name = "comet" comets.host = star comets.x = cloud_xyz[:, 2] | units.au comets.y = cloud_xyz[:, 3] | units.au comets.z = cloud_xyz[:, 4] | units.au comets.vx = cloud_xyz[:, 5] | 2 * numpy.pi * units.au / units.yr comets.vy = cloud_xyz[:, 6] | 2 * numpy.pi * units.au / units.yr comets.vz = cloud_xyz[:, 7] | 2 * numpy.pi * units.au / units.yr comets.position += star.position comets.velocity += star.velocity return comets
def slowtest3(self): print "Testing ParallelStellarEvolution evolve_model" particles = Particles(4) particles.mass = range(1, 1 + len(particles)) | units.MSun serial = MESA() inserial = serial.particles.add_particles(particles) self.assertAlmostEqual(inserial.mass, range(1, 1 + len(particles)) | units.MSun) serial.evolve_model(0.2 | units.Myr) parallel = ParallelStellarEvolution(MESA, number_of_workers=3, **default_options) inparallel = parallel.particles.add_particles(particles) self.assertAlmostEqual(inparallel.mass, range(1, 1 + len(particles)) | units.MSun) parallel.evolve_model(0.2 | units.Myr) self.assertEqual(parallel.model_time, 0.2 | units.Myr) self.assertTrue(numpy.all(inparallel.age >= (0.2 | units.Myr))) self.assertTrue( numpy.all( inparallel.age - inparallel.time_step <= (0.2 | units.Myr))) self.assertEqual(inserial.luminosity, inparallel.luminosity) self.assertEqual(inserial.time_step, inparallel.time_step) self.assertEqual(inserial.temperature, inparallel.temperature) serial.stop() parallel.stop()
def new_colliders(self): colliders = Particles(2) colliders.mass = [5, 2] | units.MSun colliders.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.RSun colliders.velocity = [[0.0, 0.0, 0.0], [0.0, 2000.0, 0.0]] | units.km / units.s colliders.move_to_center() return colliders
def test1(self): particles = Particles(4) particles.mass = [1, 2, 3, 4] | km pickled_particles = pickle.dumps(particles) unpickled_particles = pickle.loads(pickled_particles) self.assertAlmostRelativeEquals(unpickled_particles.mass, [1, 2, 3, 4] | km)
def main(): "Test class with an IMF" import sys import numpy from amuse.units import units numpy.random.seed(11) try: from amuse_masc import make_a_star_cluster use_masc = True except ImportError: use_masc = False if len(sys.argv) > 1: from amuse.io import read_set_from_file stars = read_set_from_file(sys.argv[1], "amuse") elif use_masc: stars = make_a_star_cluster.new_cluster(number_of_stars=10001) else: from amuse.ic.salpeter import new_salpeter_mass_distribution stars = Particles(10000) stars.mass = new_salpeter_mass_distribution(len(stars)) print("Number of stars: %i" % (len(stars))) code = StellarEvolutionCode(evo_code=SeBa) code.particles.add_particles(stars) print(code.parameters) timestep = 0.2 | units.Myr for step in range(10): time = step * timestep code.evolve_model(time) print("Evolved to %s" % code.model_time.in_(units.Myr)) print("Most massive star: %s" % code.particles.mass.max())
def test5(self): print("Testing SinkParticles accrete, one particle within two sinks' radii") particles = Particles(10) particles.radius = 42.0 | units.RSun particles.mass = list(range(1,11)) | units.MSun particles.position = [[i, 2*i, 3*i] for i in range(10)] | units.parsec particles.velocity = [[i, 0, -i] for i in range(10)] | units.km/units.s particles.age = list(range(10)) | units.Myr copy = particles.copy() sinks = SinkParticles(particles[[3, 7]], sink_radius=[4,12]|units.parsec,looping_over=self.looping_over) self.assertEqual(sinks.sink_radius, [4.0, 12.0] | units.parsec) self.assertEqual(sinks.mass, [4.0, 8.0] | units.MSun) self.assertEqual(sinks.position, [[3, 6, 9], [7, 14, 21]] | units.parsec) sinks.accrete(particles) self.assertEqual(len(particles), 4) # 6 particles were accreted self.assertEqual(sinks.mass, [12.0, 40.0] | units.MSun) # mass of sinks increased self.assertEqual(sinks.get_intersecting_subset_in(particles).mass, [12.0, 40.0] | units.MSun) # original particles' masses match self.assertEqual(particles.total_mass(), copy.total_mass()) # total mass is conserved self.assertEqual(particles.center_of_mass(), copy.center_of_mass()) # center of mass is conserved self.assertEqual(particles.center_of_mass_velocity(), copy.center_of_mass_velocity()) # center of mass velocity is conserved self.assertEqual(particles.total_momentum(), copy.total_momentum()) # momentum is conserved self.assertEqual(particles.total_angular_momentum()+sinks.angular_momentum.sum(axis=0), copy.total_angular_momentum()) # angular_momentum is conserved
def test10(self): p = Particles(2) p[0].position = [1.0, 2.0, 3.0] | nbody_system.length p[1].position = [4.0, 5.0, 6.0] | nbody_system.length p[0].velocity = [7.0, 8.0, 10.0] | nbody_system.length / nbody_system.time p[1].velocity = [11.0, 12.0, 13.0] | nbody_system.length / nbody_system.time p.u = [3,4] | nbody_system.potential p.rho = [5,6] | nbody_system.density p.mass = [5,6] | nbody_system.mass x = gadget.GadgetFileFormatProcessor(set = p) file = BytesIO() x.store_body(file) input = BytesIO(file.getvalue()) positions = x.read_fortran_block_float_vectors(input) self.assertEquals(positions[0] , [1.0, 2.0, 3.0]) self.assertEquals(positions[1] , [4.0, 5.0, 6.0]) velocities = x.read_fortran_block_float_vectors(input) self.assertEquals(velocities[0] , [7.0, 8.0, 10.0]) self.assertEquals(velocities[1] , [11.0, 12.0, 13.0]) ids = x.read_fortran_block_ulongs(input) self.assertEquals(ids[0], p[0].key) self.assertEquals(ids[1], p[1].key) masses = x.read_fortran_block_floats(input) self.assertEquals(masses[0], 5) self.assertEquals(masses[1], 6) u = x.read_fortran_block_floats(input) self.assertEquals(u[0], 3) self.assertEquals(u[1], 4)
def new_sun_earth_system(): particles = Particles(2) particles.mass = [1, 0.2] | units.MSun particles.position = [[0, 0, 0], [1.0, 0, 0]] | units.AU particles.velocity = [0, 0, 0] | units.km / units.s particles[1].vy = (constants.G * particles.total_mass() / particles[1].x).sqrt() return particles
def test6(self): print "Test for obtaining the stellar structure model" stars = Particles(2) stars.mass = [1.0, 10.0] | units.MSun instance = EVtwin() instance.initialize_code() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() self.assertEquals(instance.particles.get_number_of_zones(), [199, 199]) self.assertEquals(len(instance.particles[0].get_radius_profile()), 199) self.assertRaises(AmuseException, instance.particles.get_radius_profile, expected_message = "Querying radius profiles of more than one particle at a time is not supported.") self.assertEquals(len(instance.particles[1].get_density_profile()), 199) self.assertIsOfOrder(instance.particles[0].get_radius_profile()[-1], 1.0 | units.RSun) self.assertIsOfOrder(instance.particles[0].get_temperature_profile()[0], 1.0e7 | units.K) self.assertIsOfOrder(instance.particles[0].get_temperature_profile()[-1], 5.0e3 | units.K) radius1 = instance.particles[0].get_radius_profile() radius2 = radius1[:-1] radius2.prepend(0|units.m) delta_radius_cubed = (radius1**3 - radius2**3) total_mass = (4./3. * pi * instance.particles[0].get_density_profile() * delta_radius_cubed).sum() self.assertAlmostRelativeEqual(total_mass, stars[0].mass, places = 1) self.assertAlmostEquals(instance.particles[0].get_mu_profile()[:100], [0.62]*100 | units.amu, places=1) instance.stop()
def test6(self): print("Test whether a set of stars evolves synchronously...") # Create an array of stars with a range in stellar mass masses = [.5, 1., 2., 5., 10., 30.] | units.MSun number_of_stars = len(masses) stars = Particles(number_of_stars) stars.mass = masses # Initialize stellar evolution code instance = SSE() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() from_code_to_model = instance.particles.new_channel_to(stars) from_code_to_model.copy() instance.evolve_model(end_time=125 | units.Myr) from_code_to_model.copy() end_types = ( "deeply or fully convective low mass MS star", "Main Sequence star", "Main Sequence star", "Carbon/Oxygen White Dwarf", "Neutron Star", "Black Hole", ) for i in range(number_of_stars): self.assertAlmostEqual(stars[i].age, 125.0 | units.Myr) self.assertTrue(stars[i].mass <= masses[i]) self.assertEqual(str(stars[i].stellar_type), end_types[i]) instance.stop()
def xtest9(self): print "Test for changing the stellar structure model (not yet implemented)" star = Particles(1) star.mass = 1.0 | units.MSun instance = EVtwin() instance.initialize_code() instance.commit_parameters() instance.particles.add_particles(star) instance.commit_particles() instance.evolve_model() density_profile = instance.particles[0].get_density_profile() self.assertRaises(AmuseException, instance.particles[0].set_density_profile, density_profile[2:], expected_message = "The length of the supplied vector (197) does not match the number of " "mesh zones of the star (199).") mass_factor = 1.1 instance.particles[0].set_density_profile(mass_factor*density_profile) self.assertAlmostRelativeEqual(instance.particles[0].get_density_profile(), density_profile*mass_factor, places=10) instance.particles.mass *= mass_factor instance.evolve_model() outer_radius = instance.particles[0].get_radius_profile() inner_radius = outer_radius[:-1] inner_radius.prepend(0|units.m) delta_radius_cubed = (outer_radius**3 - inner_radius**3) integrated_mass = (4./3.*pi*delta_radius_cubed*instance.particles[0].get_density_profile()).sum() self.assertAlmostRelativeEqual(integrated_mass, star.mass*mass_factor, places = 3) instance.stop() del instance
def test14a(self): print( "Testing basic operations: evolve_one_step and evolve_for (on particle)" ) stars = Particles(2) stars.mass = 1.0 | units.MSun instance = SSE() se_stars = instance.particles.add_particles(stars) self.assertAlmostEqual(se_stars.age, [0.0, 0.0] | units.yr) for i in range(3): se_stars[0].evolve_one_step() self.assertAlmostEqual(se_stars.age, [1650.46953688, 0.0] | units.Myr, 3) number_of_steps = 10 step_size = se_stars[0].age / number_of_steps for i in range(1, number_of_steps + 1): se_stars[1].evolve_for(step_size) self.assertAlmostEqual(se_stars.age, [number_of_steps, i] * step_size) self.assertAlmostRelativeEqual(se_stars[0].age, se_stars[1].age) self.assertAlmostRelativeEqual(se_stars[0].luminosity, se_stars[1].luminosity, 3) self.assertAlmostRelativeEqual(se_stars[0].radius, se_stars[1].radius, 3) self.assertAlmostRelativeEqual(se_stars[0].temperature, se_stars[1].temperature, 3) instance.stop()
def test3(self): n = 10 particles = Particles(n) particles.mass = list(range(n)) | units.kg particles[0].child1 = particles[1] particles[0].child2 = particles[2] particles[1].child1 = particles[3] particles[1].child2 = particles[4] self.assertEqual(particles[0].child1.child1.mass, 3 | units.kg) binaries = particles.select_array(lambda x: x != [None], [ "child1", ]) self.assertEqual(len(binaries), 2) binaries_children1 = binaries.child1.as_set().compressed( ).select_array(lambda x: x != [None], [ "child1", ]) binaries_children2 = binaries.child2.as_set().compressed( ).select_array(lambda x: x != [None], [ "child1", ]) binaries_roots = binaries - (binaries_children1 + binaries_children2) self.assertEqual(len(binaries_roots), 1) self.assertEqual(binaries_roots[0].mass, 0 | units.kg)
def test5(self): print "Testing adding and removing particles from stellar evolution code..." particles = Particles(3) particles.mass = 0.3 | units.MSun instance = EVtwin()#redirection="none") instance.initialize_code() instance.parameters.verbosity = True instance.commit_parameters() stars = instance.particles self.assertEquals(len(stars), 0) # before creation stars.add_particles(particles[:-1]) instance.commit_particles() instance.evolve_model(1.0 | units.Myr) self.assertEquals(len(stars), 2) # before remove self.assertAlmostEqual(stars.age, 1.0 | units.Myr) stars.remove_particle(particles[0]) self.assertEquals(len(stars), 1) self.assertEquals(instance.get_number_of_particles(), 1) instance.evolve_model(2.0 | units.Myr) self.assertAlmostEqual(stars[0].age, 2.0 | units.Myr) stars.add_particles(particles[::2]) self.assertEquals(len(stars), 3) # it's back... self.assertAlmostEqual(stars[0].age, 2.0 | units.Myr) self.assertAlmostEqual(stars[1].age, 0.0 | units.Myr) self.assertAlmostEqual(stars[2].age, 0.0 | units.Myr) # ... and rejuvenated. instance.evolve_model(3.0 | units.Myr) # The young stars keep their age offset from the old star self.assertAlmostEqual(stars.age, [3.0, 1.0, 1.0] | units.Myr) instance.evolve_model(4.0 | units.Myr) self.assertAlmostEqual(stars.age, [4.0, 2.0, 2.0] | units.Myr) instance.stop()
def test4(self): print "Testing Adaptb evolve_model, 2 particles" particles = Particles(2) particles.mass = 0.5 | units.MSun particles.radius = 1.0 | units.RSun particles.position = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]] | units.AU particles.velocity = [[0.0, 0.0, 0.0], [0.0, 0.0, 0.0]] | units.km / units.s particles[1].vy = (constants.G * (1.0 | units.MSun) / (1.0 | units.AU)).sqrt() particles.move_to_center() convert_nbody = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) instance = self.new_instance_of_an_optional_code(Adaptb, convert_nbody) instance.initialize_code() instance.parameters.dt_print = 0.1 | units.yr instance.parameters.bs_tolerance = 1.0e-8 instance.commit_parameters() instance.particles.add_particles(particles) instance.commit_particles() primary = instance.particles[0] P = 2 * math.pi * primary.x / primary.vy position_at_start = primary.position.x instance.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 6) instance.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 6) instance.evolve_model(P) self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 6) instance.cleanup_code() instance.stop()
def slowtest8(self): print "Test for obtaining the stellar composition structure - evolved star" stars = Particles(1) stars.mass = 1.0 | units.MSun instance = EVtwin() instance.initialize_code() instance.commit_parameters() instance.particles.add_particles(stars) instance.commit_particles() instance.evolve_model(11.7 | units.Gyr) self.assertTrue(instance.particles[0].age >= 11.7 | units.Gyr) print instance.particles[0].stellar_type #~ self.assertTrue(str(instance.particles[0].stellar_type) == "First Giant Branch") number_of_zones = instance.particles.get_number_of_zones()[0] number_of_species = instance.particles.get_number_of_species()[0] composition = instance.particles[0].get_chemical_abundance_profiles() species_names = instance.particles[0].get_names_of_species() self.assertEquals(number_of_zones, 199) self.assertEquals(number_of_species, 9) self.assertEquals(len(species_names), number_of_species) self.assertEquals(len(composition), number_of_species) self.assertEquals(len(composition[0]), number_of_zones) self.assertEquals(species_names, ['h1', 'he4', 'c12', 'n14', 'o16', 'ne20', 'mg24', 'si28', 'fe56']) self.assertAlmostRelativeEquals(composition[0, -1], 0.7 | units.none, 1) self.assertAlmostRelativeEquals(composition[1, -1], 0.3 - instance.parameters.metallicity, 1) self.assertAlmostRelativeEquals(composition[2:,-1].sum(), instance.parameters.metallicity, 1) self.assertAlmostEquals(composition.sum(axis=0), [1.0]*number_of_zones | units.none) self.assertAlmostEquals(composition[0, 0], 0.00 | units.none) self.assertAlmostEquals(composition[1, 0], 1.00 - instance.parameters.metallicity, 3) self.assertAlmostEquals(composition[2:,0].sum(), instance.parameters.metallicity, 3) instance.stop()
def setup_stellar_evolution_model(): out_pickle_file = os.path.join(get_path_to_results(), "super_giant_stellar_structure.pkl") if os.path.exists(out_pickle_file): return out_pickle_file stellar_evolution = MESA(redirection="none") stars = Particles(1) stars.mass = 10.0 | units.MSun stellar_evolution.initialize_module_with_default_parameters() stellar_evolution.particles.add_particles(stars) stellar_evolution.commit_particles() print "Evolving a MESA star with mass:", stellar_evolution.particles[ 0].mass try: while True: stellar_evolution.evolve_model() except AmuseException as ex: print "Evolved star to", stellar_evolution.particles[0].age print "Radius:", stellar_evolution.particles[0].radius pickle_stellar_model(stellar_evolution.particles[0], out_pickle_file) stellar_evolution.stop() return out_pickle_file
def xtest13(self): print "Test evolve_model optional arguments: end_time and keep_synchronous" stars = Particles(3) stars.mass = [1.0, 2.0, 3.0] | units.MSun instance = EVtwin() instance.particles.add_particles(stars) self.assertAlmostEqual(instance.particles.age, [0.0, 0.0, 0.0] | units.yr) self.assertAlmostEqual(instance.particles.time_step, [70465.105509, 6063.68785133, 1876.53255132] | units.yr, 3) print "evolve_model without arguments: use shared timestep = 0.99*min(particles.time_step)" instance.evolve_model() self.assertAlmostEqual(instance.particles.age, 0.99*([1876.53255132,1876.53255132,1876.53255132] | units.yr), 3) self.assertAlmostEqual(instance.particles.time_step, [70465.105509,6063.68785133,1876.53255132] | units.yr, 3) self.assertAlmostEqual(instance.model_time, 0.99*1876.53255132 | units.yr, 3) print "evolve_model with end_time: take timesteps, until end_time is reached exactly" instance.evolve_model(15000 | units.yr) self.assertAlmostEqual(instance.particles.age, [15000.0, 15000.0, 15000.0] | units.yr, 3) self.assertAlmostEqual(instance.particles.time_step, [ 84558.1266108,7276.4254216,2251.83906159] | units.yr, 3) self.assertAlmostEqual(instance.model_time, 15000.0 | units.yr, 3) print "evolve_model with keep_synchronous: use non-shared timestep, particle ages will typically diverge" instance.evolve_model(keep_synchronous = False) self.assertAlmostEqual(instance.particles.age, (15000 | units.yr) + ([ 84558.1266108,7276.4254216,2251.83906159] | units.yr), 3) self.assertAlmostRelativeEquals(instance.particles.time_step, [101469.751933,8731.71050591,2702.2068739] | units.yr, 1) self.assertAlmostEqual(instance.model_time, 15000.0 | units.yr, 3) # Unchanged! instance.stop()
def new_plummer_spatial_distribution( number_of_particles, total_mass=1.0 | nbody_system.mass, virial_radius=1.0 | nbody_system.length, mass_cutoff=0.999, **keyword_arguments ): # optional arguments for UniformSphericalDistribution """ Returns a Particles set with positions following a Plummer distribution. Only the positions and masses (equal-mass system) are set. """ particles = Particles(number_of_particles) particle_mass = total_mass * 1.0 / number_of_particles particles.mass = particle_mass x, y, z = UniformSphericalDistribution(number_of_particles, mass_cutoff=mass_cutoff, **keyword_arguments).result # Now scale the uniformly distributed particle positions to match the radial density profile r_old = numpy.sqrt(x * x + y * y + z * z) scale_factor = (0.1875 * numpy.pi * virial_radius.number) / numpy.sqrt(1.0 - r_old**2) particles.x = scale_factor * x | virial_radius.unit particles.y = scale_factor * y | virial_radius.unit particles.z = scale_factor * z | virial_radius.unit return particles