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 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 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 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 resolve_sinks(self): print "processing high dens particles...", highdens=self.gas_particles.select_array(lambda rho:rho>self.density_threshold,["rho"]) print "N=", len(highdens) candidate_stars=highdens.copy() self.gas_particles.remove_particles(highdens) self.gas_particles.synchronize_to(self.code.gas_particles) print "new sinks..." if len(candidate_stars)>0: # had to make some changes to prevent double adding particles print "Adding stars, N=", len(candidate_stars) newstars_in_code = self.code.dm_particles.add_particles(candidate_stars) newstars = Particles() for nsi in newstars_in_code: if nsi not in self.star_particles: newstars.add_particle(nsi) else: print "this star should not exicst" newstars.name = "Star" newstars.birth_age = self.code.model_time newstars.Lx = 0 | (units.g * units.m**2)/units.s newstars.Ly = 0 | (units.g * units.m**2)/units.s newstars.Lz = 0 | (units.g * units.m**2)/units.s print "pre N=", len(self.star_particles), len(newstars), len(self.code.dm_particles) #self.star_particles.add_sinks(newstars) self.star_particles.add_particles(newstars) print "post N=", len(self.star_particles), len(newstars), len(self.code.dm_particles) else: print "N candidates:", len(candidate_stars)
def merge_two_stars(bodies, particles_in_encounter): com_pos = particles_in_encounter.center_of_mass() com_vel = particles_in_encounter.center_of_mass_velocity() new_particle=Particles(1) mu = particles_in_encounter[0].mass/particles_in_encounter.mass.sum() new_particle.birth_age = particles_in_encounter.birth_age.min() new_particle.mass = particles_in_encounter.total_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.value_in(units.AU) print "new radius:", new_particle.radius.value_in(units.AU) bodies.add_particles(new_particle) print "Two stars (M=",particles_in_encounter.mass,") collided at d=", com_pos.length() bodies.remove_particles(particles_in_encounter)
def merge_two_stars(bodies, particles_in_encounter): com_pos = particles_in_encounter.center_of_mass() com_vel = particles_in_encounter.center_of_mass_velocity() new_particle = Particles(1) mu = particles_in_encounter[0].mass / particles_in_encounter.mass.sum() new_particle.birth_age = particles_in_encounter.birth_age.min() new_particle.mass = particles_in_encounter.total_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.value_in(units.AU)) print("new radius:", new_particle.radius.value_in(units.AU)) bodies.add_particles(new_particle) print("Two stars (M=", particles_in_encounter.mass, ") collided at d=", com_pos.length()) bodies.remove_particles(particles_in_encounter)
def construct_particle_set_from_orbital_elements(name, mass, a, ecc, inc, Ma, Aop, LoAn, Mparent=1 | units.MSun): print("length:", len(a), len(ecc), len(inc), len(Ma), len(Aop), len(LoAn), len(name)) p = Particles(len(a)) print(name) p.name = name p.type = "asteroid" p.host = "Sun" p.mass = mass from orbital_elements_to_cartesian import orbital_elements_to_pos_and_vel from orbital_elements_to_cartesian import orbital_period from amuse.ext.orbital_elements import new_binary_from_orbital_elements for i in range(len(p)): Ta = True_anomaly_from_mean_anomaly(numpy.rad2deg(Ma[i]), ecc[i]) b = new_binary_from_orbital_elements(Mparent, p[i].mass, a[i], ecc[i], Ta, inc[i], LoAn[i], Aop[i], G=constants.G) p[i].position = b[1].position - b[0].position p[i].velocity = b[1].velocity - b[0].velocity rho = 2.0 | units.g / units.cm**3 p.radius = (p.mass / rho)**(1. / 3.) return p
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 resolve_sinks(self): print("processing high dens particles...", end=' ') highdens = self.gas_particles.select_array( lambda rho: rho > self.density_threshold, ["rho"]) print("N=", len(highdens)) candidate_stars = highdens.copy() self.gas_particles.remove_particles(highdens) self.gas_particles.synchronize_to(self.code.gas_particles) print("new sinks...") if len( candidate_stars ) > 0: # had to make some changes to prevent double adding particles print("Adding stars, N=", len(candidate_stars)) newstars_in_code = self.code.dm_particles.add_particles( candidate_stars) newstars = Particles() for nsi in newstars_in_code: if nsi not in self.star_particles: newstars.add_particle(nsi) else: print("this star should not exicst") newstars.name = "Star" newstars.birth_age = self.code.model_time newstars.Lx = 0 | (units.g * units.m**2) / units.s newstars.Ly = 0 | (units.g * units.m**2) / units.s newstars.Lz = 0 | (units.g * units.m**2) / units.s print("pre N=", len(self.star_particles), len(newstars), len(self.code.dm_particles)) # self.star_particles.add_sinks(newstars) self.star_particles.add_particles(newstars) print("post N=", len(self.star_particles), len(newstars), len(self.code.dm_particles)) else: print("N candidates:", len(candidate_stars))
def get_sun_and_planets(delta_JD=0.|units.day): """ eight planets of the Solar System as for JD = 2457099.500000000 = A.D. 2015-Mar-18 00:00:00.0000 (CT) http://ssd.jpl.nasa.gov/horizons.cgi """ planets = Particles(8) # mass planets.mass = [3.302e23, 48.685e23, 5.97219e24, 6.4185e23, 1898.13e24, 5.68319e26, 86.8103e24, 102.41e24] | units.kg # eccentricity planets_ecc = [2.056263501026885E-01, 6.756759719005901E-03, 1.715483324953308E-02, 9.347121362500883E-02, 4.877287772914470E-02, 5.429934603664216E-02, 4.911406962716518E-02, 8.494660388602767E-03] # semi-major axis planets_semi = [3.870989725156447E-01, 7.233252880006816E-01, 1.000816989613834E+00, 1.523624142457679E+00, 5.203543088590996E+00, 9.547316304899041E+00, 1.915982879739036E+01, 2.997013749028780E+01] | units.AU # mean anomaly [degrees] planets_mean_anomaly = [2.256667460183225E+02, 3.096834722926926E+02, 6.970055236286768E+01, 5.013506750245609E+01, 1.213203242081277E+02, 1.423311616732398E+02, 2.079860620353052E+02, 2.712246916734600E+02] planets_mean_anomaly = numpy.array(planets_mean_anomaly) * pi_over_180 # inclination [IN degrees] planets_inclination = [7.004026765179669E+00, 3.394480103844425E+00, 3.563477431351056E-03, 1.848403408106458E+00, 1.303457729562742E+00, 2.488017444885577E+00, 7.728000142736371E-01, 1.767720502209091E+00] planets_inclination = numpy.array(planets_inclination) * pi_over_180 # Longitude of Ascending Node [OM degrees] planets_longitude = [4.831163083479358E+01, 7.663982595051040E+01, 1.775515437672556E+02, 4.951282677064384E+01, 1.005036717671826E+02, 1.135683875842263E+02, 7.388411509910506E+01, 1.317497218434830E+02] planets_longitude = numpy.array(planets_longitude) * pi_over_180 # Argument of Perihelion [W degrees] planets_argument = [2.916964171964058E+01, 5.469102797401222E+01, 2.877495001117996E+02, 2.865420083537150E+02, 2.740725976811202E+02, 3.398666856578898E+02, 9.666856264946740E+01, 2.951871807292030E+02] planets_argument = numpy.array(planets_argument) * pi_over_180 planets.name = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Satrun', 'Uranus', 'Neptune'] ### to compare with JPL, mass of the Sun needs to be rescaled #mg_nasa = 1.32712440018e20 | (units.m**3 / units.s**2) #g_nasa = 6.67259e-11 | (units.m**3 / units.kg / units.s**2) #ms = mg_nasa / g_nasa sun = Particle() sun.name = 'Sun' #sun.mass = ms sun.mass = 1.0 | units.MSun sun.position = [0.,0.,0.] | units.AU sun.velocity = [0.,0.,0.] | units.kms # get the position and velocity vectors relative to sun # by evolving in Kepler for i,ecc_i in enumerate(planets_ecc): r, v = get_position(sun.mass, planets[i].mass, planets_ecc[i], planets_semi[i], planets_mean_anomaly[i], planets_inclination[i], planets_longitude[i], planets_argument[i], delta_t=delta_JD) planets[i].position = r planets[i].velocity = v return sun, planets