def generate_binaries(primary_mass, secondary_mass, semi_major_axis, eccentricity=0 | units.rad, true_anomaly=0 | units.rad, inclination=0 | units.rad, longitude_of_the_ascending_node=0 | units.rad, argument_of_periapsis=0 | units.rad, G=nbody_system.G): """ returns two particlesets, which contain the primaries and the secondaries in binary pairs. """ mass_unit = primary_mass.unit try: number_of_primaries = len(primary_mass) except: number_of_primaries = 1 primary_mass = numpy.array([primary_mass.value_in(mass_unit) ]) | mass_unit try: number_of_secondaries = len(secondary_mass) except: number_of_secondaries = 1 secondary_mass = numpy.array([secondary_mass.value_in(mass_unit) ]) | mass_unit # mass arrays need to be the same length if number_of_secondaries != number_of_primaries: raise Exception("The number of primaries is not the same as the number\ of secondaries, this is not supported.") position_vector, velocity_vector = rel_posvel_arrays_from_orbital_elements( primary_mass, secondary_mass, semi_major_axis, eccentricity=eccentricity, true_anomaly=true_anomaly, inclination=inclination, longitude_of_the_ascending_node=longitude_of_the_ascending_node, argument_of_periapsis=argument_of_periapsis, G=G) number_of_primaries primaries = Particles(number_of_primaries) secondaries = Particles(number_of_secondaries) primaries.mass = primary_mass secondaries.mass = secondary_mass centers_of_mass = center_of_mass_array(position_vector, primary_mass, secondary_mass) centers_of_mass_velocity = center_of_mass_array(velocity_vector, primary_mass, secondary_mass) primaries.position = -centers_of_mass secondaries.position = position_vector - centers_of_mass primaries.velocity = -centers_of_mass_velocity secondaries.velocity = velocity_vector - centers_of_mass_velocity return primaries, secondaries
def test13(self): print "Test box_counting_dimension" # Particles distributed uniformly in 3D particles = Particles(4096) particles.position = numpy.mgrid[0:16.0, 0:16.0, 0:16.0].reshape(3, -1).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 3.0, 1) # Fractal dimension is scale-free particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles distributed in the x-y plane particles.position = numpy.concatenate((numpy.mgrid[0:64.0, 0:64.0].reshape(2, -1), numpy.zeros((1, 4096)))).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 2.0, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles distributed along a line particles.position = numpy.concatenate([numpy.arange(4096.0).reshape(1, -1)]*3).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 1.0, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles on a Koch curve x, y = self.new_koch_star(level=7) numpy.random.seed(123456) sel = numpy.random.randint(len(x), size=4096) particles.position = numpy.hstack((x[sel], y[sel], numpy.zeros(4096))) | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 1.26186, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10)
def get_inclined_disk(disk, incl_deg=0., omega_deg=0., lon_deg=0.): """ rotate particles by inclination, longitude of ascending node, and argument of pericenter """ incl = incl_deg * pi_180 omega = omega_deg * pi_180 longitude = lon_deg * pi_180 # get rotation matrix a1 = ([numpy.cos(longitude), -numpy.sin(longitude), 0.0], [numpy.sin(longitude), numpy.cos(longitude), 0.0], [0.0, 0.0, 1.0]) a2 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a3 = ([numpy.cos(omega), -numpy.sin(omega), 0.0], [numpy.sin(omega), numpy.cos(omega), 0.0], [0.0, 0.0, 1.0]) rot = numpy.dot(numpy.dot(a1,a2),a3) # reshape positions and velocity vectors pos = disk.position.value_in(units.kpc) vel = disk.velocity.value_in(units.kpc/units.Myr) # rotate pos_rot = (numpy.dot(rot, pos.T)).T | units.kpc vel_rot = (numpy.dot(rot, vel.T)).T | (units.kpc/units.Myr) inclined_disk = Particles(len(disk)) inclined_disk.mass = disk.mass inclined_disk.position = pos_rot inclined_disk.velocity = vel_rot inclined_disk.id = disk.id return inclined_disk
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(), append_to_file=True) 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 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 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 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 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 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 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 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 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 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 make_galaxies(): # File 'disk_galactICs.amuse' contains 30k particles, (10k disk, no bulge, 20k halo) if os.path.exists('disk_galactICs.amuse'): galaxy1 = read_set_from_file('disk_galactICs.amuse', 'amuse') else: halo_number_of_particles = 20000 converter = generic_unit_converter.ConvertBetweenGenericAndSiUnits( constants.G, 1.0e12 | units.MSun, 50.0 | units.kpc) galaxy1 = new_galactics_model(halo_number_of_particles, disk_number_of_particles=10000, generate_bulge_flag=False, do_scale=True, unit_system_converter=converter) 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 test7(self): instance = self.new_fastkick_instance() instance.parameters.epsilon_squared = 0.00001 | nbody_system.length**2 particles = Particles(2) particles.mass = [1.0, 1.0] | nbody_system.mass particles.position = [[0.0,0.0,0.0], [2.0,0.0,0.0]] | nbody_system.length instance.particles.add_particles(particles) zero = 0.0 | nbody_system.length ax, ay, az = instance.get_gravity_at_point(zero, 1.0 | nbody_system.length, zero, zero) self.assertAlmostEqual(ax, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(ay, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(az, 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) ax0, ay0, az0 = instance.get_gravity_at_point(zero, x0, zero, zero) ax1, ay1, az1 = instance.get_gravity_at_point(zero, x1, zero, zero) self.assertAlmostEqual(ay0, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(az0, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(ay1, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(az1, 0.0 | nbody_system.acceleration, 6) self.assertAlmostEqual(ax0, -ax1, 5) ax = (-1.0 / (x0**2) + 1.0 / (x1**2)) * (1.0 | nbody_system.length**3 / nbody_system.time**2) self.assertAlmostEqual(ax, ax0, 2) self.assertAlmostEqual(potential0, potential1, 5) instance.stop()
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 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 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 merge_two_stars(bodies, particles_in_encounter): """ Merge two stars into one """ com_pos = particles_in_encounter.center_of_mass() com_vel = particles_in_encounter.center_of_mass_velocity() star_0 = particles_in_encounter[0] star_1 = particles_in_encounter[1] new_particle = Particles(1) new_particle.birth_age = particles_in_encounter.birth_age.min() new_particle.mass = particles_in_encounter.total_mass() new_particle.age = min(particles_in_encounter.age) \ * max(particles_in_encounter.mass)/new_particle.mass new_particle.position = com_pos new_particle.velocity = com_vel new_particle.name = "Star" new_particle.radius = particles_in_encounter.radius.max() print("# old radius:", particles_in_encounter.radius.in_(units.AU)) print("# new radius:", new_particle.radius.in_(units.AU)) bodies.add_particles(new_particle) print("# Two stars (M=", particles_in_encounter.mass.in_(units.MSun), ") collided at d=", (star_0.position - star_1.position).length().in_(units.AU)) bodies.remove_particles(particles_in_encounter)
def test9(self): print "Testing FastKick for Bridge: evolving a binary" particles = Particles(2) particles.mass = [3.0, 1.0] | units.MSun particles.position = [0, 0, 0] | units.AU particles.velocity = [0, 0, 0] | units.km / units.s particles[1].x = 2.0 | units.AU particles[1].vy = (constants.G * (4.0 | units.MSun) / (2.0 | units.AU)).sqrt() particles.move_to_center() primary_sys = new_gravity_code(particles[:1]) secondary_sys = new_gravity_code(particles[1:]) primary = primary_sys.particles[0] P = 2 * math.pi * primary.x / primary.vy converter = nbody_system.nbody_to_si(1.0 | units.MSun, 1.0 | units.AU) kick_from_primary = CalculateFieldForCodesUsingReinitialize(self.new_fastkick_instance(converter), (primary_sys,)) kick_from_secondary = CalculateFieldForCodesUsingReinitialize(self.new_fastkick_instance(converter), (secondary_sys,)) bridgesys = Bridge(timestep = P / 64.0) bridgesys.add_system(primary_sys, (kick_from_secondary,)) bridgesys.add_system(secondary_sys, (kick_from_primary,)) position_at_start = primary.position.x bridgesys.evolve_model(P / 4.0) self.assertAlmostRelativeEqual(position_at_start, primary.position.y, 2) bridgesys.evolve_model(P / 2.0) self.assertAlmostRelativeEqual(position_at_start, -primary.position.x, 2) bridgesys.evolve_model(P) kick_from_primary.code.stop() kick_from_secondary.code.stop() self.assertAlmostRelativeEqual(position_at_start, primary.position.x, 2)
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_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 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 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 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 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 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 integrate_amuse(orb,pot,tmax,vo,ro): """Integrate a snapshot in infile until tmax in Gyr, save to outfile""" time=0.0 | tmax.unit dt = tmax/10001. orbit = Particles(1) orbit.mass= 1. | units.MSun orbit.radius = 1. |units.RSun orbit.position=[orb.x(),orb.y(),orb.z()] | units.kpc orbit.velocity=[orb.vx(),orb.vy(),orb.vz()] | units.kms galaxy_code = to_amuse(pot,ro=ro,vo=vo) orbit_gravity=drift_without_gravity(orbit) orbit_gravity.particles.add_particles(orbit) channel_from_gravity_to_orbit= orbit_gravity.particles.new_channel_to(orbit) gravity = bridge.Bridge(use_threading=False) gravity.add_system(orbit_gravity, (galaxy_code,)) gravity.add_system(galaxy_code,) gravity.timestep = dt while time <= tmax: time += dt gravity.evolve_model(time) channel_from_gravity_to_orbit.copy() gravity.stop() return orbit.x[0].value_in(units.kpc),orbit.y[0].value_in(units.kpc),orbit.z[0].value_in(units.kpc),orbit.vx[0].value_in(units.kms),orbit.vy[0].value_in(units.kms),orbit.vz[0].value_in(units.kms)
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 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 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 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 make_amuse_fresco_stars_only(x, mstar, age_yr, L, res=512, p=5e-4, mass_limits=[0, 0], mass_rescale=1., filename=None, vmax=None): number_of_stars = len(mstar) # print(np.max(mstar)) # ind = mstar>30 # x=x[ind] # mstar=mstar[ind] # age_yr=age_yr[ind] # number_of_stars = len(mstar) if (mass_limits[0] != 0.0) or (mass_limits[1] != 0.0): if (mass_limits[0] == 0.0): mass_limits[0] = np.min(mstar) if (mass_limits[1] == 0.0): mass_limits[1] = np.max(mstar) mstar_new = np.clip(mstar, mass_limits[0], mass_limits[1]) #small correction to make them stand apart (e.g. instea of clipping both 100 and 50 msun to 50, we get 50 and 60 so they don't look identical) mstar_new = mstar_new + (mstar - mstar_new) * 0.1 ##limits masses of star #logm = np.log10(mstar); logm0 = np.max(logm) + np.min(logm); #mstar_new = 10**( (logm - logm0)/mass_limits + logm0 ) mstar_new = mstar**mass_rescale new_stars = Particles(number_of_stars) new_stars.age = age_yr | units.yr new_stars.mass = mstar_new | units.MSun new_stars.position = x | units.pc stars = new_stars gas = Particles() #inspectvar(units) stars.luminosity = lum_MS(mstar_new) | units.LSun #stars.main_sequence_lifetime = [450.0, 420.0] | units.Myr stars.radius = rad_MS(mstar_new) | units.RSun #stars.spin = [4700, 4700] | units.yr**-1 # stars.stellar_type = [1, 1] | units.stellar_type # se = SSE() # se.particles.add_particles(stars) # from_se = se.particles.new_channel_to(stars) # from_se.copy() # inspectvar(stars) image, _ = make_fresco_image( stars, gas, return_vmax=True,\ image_width=[L | units.pc,L | units.pc], image_size=[res,res],percentile=1-p,vmax=vmax) #image: (2048,2048,3) RGB if not (filename is None): #Save image to file plt.imshow(image[::-1], extent=(-L / 2.0, L / 2.0, -L / 2.0, L / 2.0)) plt.xlim(-L / 2.0, L / 2.0) plt.ylim(-L / 2.0, L / 2.0) plt.imsave(filename, image[::-1]) return image[::-1]
def new_sun_earth_system(self): particles = Particles(2) particles.mass = [1.0, 3.0037e-6] | 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 * particles.total_mass() / (1.0 | units.AU)).sqrt() return particles
def wind_sphere(self, star, Ngas): wind=Particles(Ngas) r_max = self.r_max or self.r_max_ratio * star.radius wind.position, direction = random_positions(Ngas, star.radius, r_max) wind.velocity = [0, 0, 0] | units.kms return wind
def wind_sphere(self, star, Ngas): wind = Particles(Ngas) r_max = self.r_max or self.r_max_ratio * star.radius wind.position, direction = self.generate_positions(Ngas, star.radius, r_max) wind.velocity = [0, 0, 0] | units.kms return wind
def test2(self): particles = Particles(4) particles.mass = [1, 2, 3, 6] | kg particles.position = [[0, 0, 0], [3, 0, 0], [0, 4, 0], [3, 4, 0]] | m self.assertEqual(particles.center_of_mass(), [2, 3, 0] | m) pickled_particles = pickle.dumps(particles) unpickled_particles = pickle.loads(pickled_particles) self.assertAlmostRelativeEquals(unpickled_particles.mass, [1, 2, 3, 6] | kg) self.assertEqual(unpickled_particles.center_of_mass(), [2, 3, 0] | m)
def test2(self): particles = Particles(4) particles.mass = [1, 2, 3, 6] | kg particles.position = [[0, 0, 0], [3, 0, 0], [0, 4, 0], [3, 4, 0]] | m self.assertEqual(particles.center_of_mass(), [2, 3, 0] | m) pickled_particles = pickle.dumps(particles) unpickled_particles = pickle.loads(pickled_particles) self.assertAlmostRelativeEquals(unpickled_particles.mass, [1, 2, 3, 6] | kg) self.assertEqual(unpickled_particles.center_of_mass(), [2, 3, 0] | m)
def handle_collision(self, primary, secondary): colliders = primary + secondary result = Particles(1) result.mass = colliders.total_mass() * (1 - self.mass_loss) result.position = colliders.center_of_mass() result.velocity = colliders.center_of_mass_velocity() if hasattr(colliders, "radius"): result.radius = colliders.radius.amax() return result
def handle_collision(self, primary, secondary): colliders = primary + secondary result = Particles(1) result.mass = colliders.total_mass() * (1 - self.mass_loss) result.position = colliders.center_of_mass() result.velocity = colliders.center_of_mass_velocity() if hasattr(colliders, "radius"): result.radius = colliders.radius.amax() return result
def test13(self): print "Test box_counting_dimension" # Particles distributed uniformly in 3D particles = Particles(4096) particles.position = numpy.mgrid[0:16.0, 0:16.0, 0:16.0].reshape( 3, -1).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 3.0, 1) # Fractal dimension is scale-free particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles distributed in the x-y plane particles.position = numpy.concatenate( (numpy.mgrid[0:64.0, 0:64.0].reshape(2, -1), numpy.zeros( (1, 4096)))).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 2.0, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles distributed along a line particles.position = numpy.concatenate( [numpy.arange(4096.0).reshape(1, -1)] * 3).transpose() | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 1.0, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10) # Particles on a Koch curve x, y = self.new_koch_star(level=7) numpy.random.seed(123456) sel = numpy.random.randint(len(x), size=4096) particles.position = numpy.hstack( (x[sel], y[sel], numpy.zeros(4096))) | units.m dimension = particles.box_counting_dimension() self.assertAlmostRelativeEquals(dimension, 1.26186, 1) particles.position *= 1000 self.assertAlmostRelativeEquals(dimension, particles.box_counting_dimension(), 10)
def wind_sphere(self, star, Ngas): wind=Particles(Ngas) wind_velocity = self.initial_wind_velocity(star) outer_wind_distance = wind_velocity * (self.model_time - star.wind_release_time) wind.position, direction = random_positions(Ngas, star.radius, outer_wind_distance) wind.velocity = direction * wind_velocity return wind
def test7(self): print "Test minimum_spanning_tree_length" particles = Particles(6) particles.position = [[-5,0,0], [-1,0,0], [0,0,0], [0,1,0], [0,-2,0], [-1,0.1,0]] | units.m self.assertEqual(particles[:1].minimum_spanning_tree_length(), 0 | units.m) self.assertEqual(particles[:2].minimum_spanning_tree_length(), 4 | units.m) self.assertEqual(particles[:3].minimum_spanning_tree_length(), 5 | units.m) self.assertEqual(particles[:4].minimum_spanning_tree_length(), 6 | units.m) self.assertEqual(particles[:5].minimum_spanning_tree_length(), 8 | units.m) self.assertEqual(particles[:6].minimum_spanning_tree_length(), 8.1 | units.m)
def evolve_gravity(bodies, converter, t_end, dt_integration): #Positions and velocities centered on the center of mass bodies.move_to_center() gravity = initialize_code(bodies, timestep_parameter = dt_integration.value_in(nbody_system.time)) channel_from_gr_to_framework = gravity.particles.new_channel_to(bodies) if(t_end != 0.0 | nbody_system.time): #Evolve it gravity.evolve_model(t_end) channel_from_gr_to_framework.copy() #Orbital Elements star = bodies[0] ffp = bodies[1] bp = bodies[2] #Star+BP and FFP cm_x = (star.mass*star.x + bp.mass*bp.x)/(star.mass+bp.mass) cm_y = (star.mass*star.y + bp.mass*bp.y)/(star.mass+bp.mass) cm_vx = (star.mass*star.vx + bp.mass*bp.vx)/(star.mass+bp.mass) cm_vy = (star.mass*star.vy + bp.mass*bp.vy)/(star.mass+bp.mass) star_bp = Particles(1) star_bp.mass = star.mass + bp.mass star_bp.position = [cm_x, cm_y, 0.0 | nbody_system.length] star_bp.velocity = [cm_vx, cm_vy, 0.0 | nbody_system.speed] binary = [star_bp[0], ffp] sma_starbp_ffp, e_starbp_ffp, inc_starbp_ffp, lan_starbp_ffp, ap_starbp_ffp = my_orbital_elements_from_binary(binary) bodies[1].eccentricity = e_starbp_ffp bodies[1].semimajoraxis = sma_starbp_ffp #Star and BP binary = [star, bp] sma_star_bp, e_star_bp, inc_star_bp, lan_star_bp, ap_star_bp = my_orbital_elements_from_binary(binary) bodies[2].eccentricity = e_star_bp bodies[2].semimajoraxis = sma_star_bp is_stable = is_hill_stable(bodies.mass, bodies.semimajoraxis, bodies.eccentricity, converter) #Star and FFP binary = [star, ffp] sma_star_ffp, e_star_ffp, inc_star_ffp, lan_star_ffp, ap_star_ffp = my_orbital_elements_from_binary(binary) max_energy_change = 0.0 gravity.stop() return max_energy_change, is_stable, e_star_ffp, e_star_bp, sma_star_ffp, sma_star_bp, inc_star_ffp, inc_star_bp, lan_star_ffp, lan_star_bp, ap_star_ffp, ap_star_bp else: return 1.0, False, 0.0, 0.0, 1.0 | nbody_system.length, 1.0 | nbody_system.length, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
def new_particles_with_internal_structure_from_models(self): def get_internal_structure(set, particle=None): return self.models[(set.key == particle.key).nonzero()[0]] result = Particles(len(self.models)) result.add_function_attribute("get_internal_structure", None, get_internal_structure) result.mass = [model.dmass.sum().as_quantity_in(self.mass_unit) for model in self.models] result.radius = [model.radius[-1].as_quantity_in(self.radius_unit) for model in self.models] result.position = (self.original_center_of_mass + self.stars_after_encounter.position).as_quantity_in(self.position_unit) result.velocity = (self.original_center_of_mass_velocity + self.stars_after_encounter.velocity).as_quantity_in(self.velocity_unit) return result
def new_particles_with_internal_structure_from_models(self): def get_internal_structure(set, particle=None): return self.models[(set.key == particle.key).nonzero()[0]] result = Particles(len(self.models)) result.add_function_attribute("get_internal_structure", None, get_internal_structure) result.mass = [model.dmass.sum().as_quantity_in(self.mass_unit) for model in self.models] result.radius = [model.radius[-1].as_quantity_in(self.radius_unit) for model in self.models] result.position = (self.original_center_of_mass + self.stars_after_encounter.position).as_quantity_in(self.position_unit) result.velocity = (self.original_center_of_mass_velocity + self.stars_after_encounter.velocity).as_quantity_in(self.velocity_unit) return result
def new_particles(): particles = Particles(3) particles.mass = [3., 4., 5.] | nbody_system.mass particles.position = [ [1, 3, 0], [-2, -1, 0], [1, -1, 0], ] | nbody_system.length particles.velocity = [0., 0., 0.] | nbody_system.speed particles.radius = 0 | nbody_system.length return particles
def test2(self): colliders = Particles(2) colliders.mass = [5, 5] | units.kg colliders.position = [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]] | units.m colliders.velocity = [[0.0, 0.0, 0.0], [2.0, 2.0, 2.0]] | units.m / units.s merged = StickySpheres(mass_loss=0.2).handle_collision(colliders[0], colliders[1]) self.assertTrue(isinstance(merged, Particles)) self.assertEqual(merged.mass, 8 | units.kg) self.assertAlmostEqual(merged.position, [0.5, 0.5, 0.5] | units.m) self.assertAlmostEqual(merged.velocity, [1.0, 1.0, 1.0] | units.m / units.s) copy = colliders.copy() copy.move_to_center() self.assertAlmostEqual(colliders.kinetic_energy(), merged.as_set().kinetic_energy() / 0.8 + copy.kinetic_energy())
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 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 new_particles(): particles = Particles(3) particles.mass=[3.,4.,5.] | nbody_system.mass particles.position = [ [1, 3, 0], [-2, -1, 0], [1, -1, 0], ] | nbody_system.length particles.velocity = [0.,0.,0.] | nbody_system.speed particles.radius = 0 | nbody_system.length return particles
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 test2(self): colliders = Particles(2) colliders.mass = [5, 5] | units.kg colliders.position = [[0.0, 0.0, 0.0], [1.0, 1.0, 1.0]] | units.m colliders.velocity = [[0.0, 0.0, 0.0], [2.0, 2.0, 2.0]] | units.m / units.s merged = StickySpheres(mass_loss=0.2).handle_collision(colliders[0], colliders[1]) self.assertTrue(isinstance(merged, Particles)) self.assertEqual(merged.mass, 8 | units.kg) self.assertAlmostEqual(merged.position, [0.5, 0.5, 0.5] | units.m) self.assertAlmostEqual(merged.velocity, [1.0, 1.0, 1.0] | units.m / units.s) copy = colliders.copy() copy.move_to_center() self.assertAlmostEqual(colliders.kinetic_energy(), merged.as_set().kinetic_energy() / 0.8 + copy.kinetic_energy())
def get_bodies_in_orbit(m0, m_ffp, m_bp, a_bp, e_bp, phi_bp, lan_bp, b_ffp, r_inf): #Bodies bodies = Particles() ##Get BP in orbit #Binary star_planet = new_binary_from_orbital_elements(m0, m_bp, a_bp, e_bp, true_anomaly=phi_bp, inclination = 28, longitude_of_the_ascending_node = lan_bp) #Planet attributes star_planet.eccentricity = e_bp star_planet.semimajoraxis = a_bp #Center on the star star_planet.position -= star_planet[0].position star_planet.velocity -= star_planet[0].velocity cm_p = star_planet.center_of_mass() cm_v = star_planet.center_of_mass_velocity() ##Get FFP in orbit #Particle set m0_ffp = Particles(2) #Zeros and parabolic velocity zero_p = 0.0 | nbody_system.length zero_v = 0.0 | nbody_system.speed parabolic_velocity = get_parabolic_velocity(m0, m_ffp, b_ffp, r_inf, m_bp, a_bp, phi_bp) #Central star m0_ffp[0].mass = m0 m0_ffp[0].position = (zero_p,zero_p,zero_p) m0_ffp[0].velocity = (zero_v,zero_v,zero_v) #Free-floating planet m0_ffp[1].mass = m_ffp m0_ffp[1].position = (-r_inf-cm_p[0],-b_ffp-cm_p[1],zero_p) m0_ffp[1].velocity = (parabolic_velocity,zero_v,zero_v) #Orbital Elements star_planet_as_one = Particles(1) star_planet_as_one.mass = m0 + m_bp star_planet_as_one.position = cm_p star_planet_as_one.velocity = cm_v binary = [star_planet_as_one[0], m0_ffp[1]] m1, m2, sma, e = my_orbital_elements_from_binary(binary) #For the star it sets the initial values of semimajoraxis and eccentricity of the ffp around star+bp m0_ffp.eccentricity = e m0_ffp.semimajoraxis = sma #Order: star, ffp, bp bodies.add_particle(m0_ffp[0]) bodies.add_particle(m0_ffp[1]) bodies.add_particle(star_planet[1]) return bodies
def result(self): self.setup_lookup_tables() self.setup_variates() sph_particles = Particles(self.number_of_sph_particles) sph_particles.position = self.new_particle_positions() sph_particles.velocity = self.new_particle_velocities() sph_particles.u = self.new_particle_specific_internal_energies() sph_particles.rho = self.new_particle_densities() sph_particles.mass = (self.mass.number * 1.0 / self.number_of_sph_particles) | self.mass.unit # Crude estimate of the smoothing length; the SPH code will calculate the true value itself. sph_particles.h_smooth = (self.grid.get_volume() * 50.0/self.number_of_sph_particles)**(1/3.0) return sph_particles
def set_up_inner_binary(inclination): semimajor_axis = triple_parameters["a_in"] masses = triple_parameters["masses_in"] print " Initializing inner binary" stars = Particles(2) stars.mass = masses stars.position = [0.0, 0.0, 0.0] | units.AU stars.velocity = [0.0, 0.0, 0.0] | units.km / units.s stars[0].y = semimajor_axis stars[0].vx = -math.cos(inclination) * get_relative_velocity_at_apastron( stars.total_mass(), semimajor_axis, 0) stars[0].vz = math.sin(inclination) * get_relative_velocity_at_apastron( stars.total_mass(), semimajor_axis, 0) stars.move_to_center() return stars
def xtest08(self): if MODULES_MISSING: self.skip("Failed to import a module required for Sakura") print("Testing Sakura get_gravity_at_point and get_potential_at_point") instance = self.new_instance_of_an_optional_code( Sakura, **default_options) instance.initialize_code() instance.parameters.epsilon_squared = 0.0 | nbody_system.length**2 # instance.parameters.smbh_mass = 0.0 | nbody_system.mass particles = Particles(2) particles.mass = 1.0 | nbody_system.mass particles.radius = 0.0 | 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.particles.add_particles(particles) zero = 0.0 | nbody_system.length fx, fy, fz = instance.get_gravity_at_point(zero, 1.0 | nbody_system.length, zero, zero) self.assertAlmostEqual(fx, 0.0 | nbody_system.acceleration) self.assertAlmostEqual(fy, 0.0 | nbody_system.acceleration) self.assertAlmostEqual(fz, 0.0 | nbody_system.acceleration) 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 | nbody_system.acceleration) self.assertAlmostEqual(fz0, 0.0 | nbody_system.acceleration) self.assertAlmostEqual(fy1, 0.0 | nbody_system.acceleration) self.assertAlmostEqual(fz1, 0.0 | nbody_system.acceleration) self.assertAlmostEqual(fx0, -1.0 * fx1) fx = (-1.0 / (x0**2) + 1.0 / (x1**2)) * (1.0 | nbody_system.length**3 / nbody_system.time**2) self.assertAlmostEqual(fx, fx0) self.assertAlmostEqual(potential0, potential1) instance.stop()
def test1(self): colliders = Particles(2) colliders.mass = [5, 2] | units.kg colliders.position = [[0.0, 0.0, 0.0], [0.7, 1.4, -0.35]] | units.m colliders.velocity = [[0.4, -0.6, 0.0], [0.0, 0.0, -3.0]] | units.m / units.s self.assertAlmostEqual(colliders.center_of_mass_velocity().length(), 1.0 | units.m / units.s) merged = StickySpheres().handle_collision(colliders[0], colliders[1]) self.assertTrue(isinstance(merged, Particles)) self.assertEqual(merged.mass, 7 | units.kg) self.assertAlmostEqual(merged.position, [0.2, 0.4, -0.1] | units.m) self.assertAlmostEqual(merged.velocity, ([2.0, -3.0, -6.0] | units.m / units.s) / 7.0) self.assertAlmostEqual(merged.velocity.length(), 1.0 | units.m / units.s) copy = colliders.copy() copy.move_to_center() self.assertAlmostEqual(colliders.kinetic_energy(), merged.as_set().kinetic_energy() + copy.kinetic_energy())