def update_orb_elem(host_star, planets, converter=None, kepler_worker=None): if kepler_worker == None: if converter == None: tot_sys = Particles(particles=(host_star, planets)) converter = nbody_system.nbody_to_si(tot_sys.mass.sum(), 2 * host_star.radius) kep_p = Kepler(unit_converter=converter, redirection='none') kep_p.initialize_code() else: kep_p = kepler_worker for planet in planets: total_mass = host_star.mass + planet.mass kep_pos = host_star.position - planet.position kep_vel = host_star.velocity - planet.velocity kep_p.initialize_from_dyn(total_mass, kep_pos[0], kep_pos[1], kep_pos[2], kep_vel[0], kep_vel[1], kep_vel[2]) planet.semimajor_axis, planet.eccentricity = kep_p.get_elements() planet.period = kep_p.get_period() planet.true_anomaly, planet.mean_anomaly = kep_p.get_angles() if kepler_worker == None: kep_p.stop()
def get_heirarchical_systems_from_set(bodies, kepler_workers=None, converter=None, RelativePosition=False): # Initialize Kepler if kepler_workers == None: if converter == None: converter = nbody_system.nbody_to_si( bodies.mass.sum(), 2 * np.max(bodies.radius.number) | bodies.radius.unit) kep_p = Kepler(unit_converter=converter, redirection='none') kep_p.initialize_code() kep_s = Kepler(unit_converter=converter, redirection='none') kep_s.initialize_code() else: kep_p = kepler_workers[0] kep_s = kepler_workers[1] # Seperate Out Planets and Stars from Bodies stars, planets = util.get_stars(bodies), util.get_planets(bodies) num_stars, num_planets = len(stars), len(planets) # Initialize the Dictionary that Contains all Planetary Systems systems = {} # Initialize the List Used to Check Star IDs Against Already Classified Binaries binary_ids = [] # Find Nearest Neighbors of the Set closest_neighbours = stars.nearest_neighbour() # Start Looping Through Stars to Find Bound Planets for index, star in enumerate(stars): # If the star is already in Binary_IDs, just go to the next star. if star.id in binary_ids: continue # If not, Set the System ID and Set-up Data Structure. system_id = star.id current_system = systems.setdefault(system_id, Particles()) current_system.add_particle(star) noStellarHierarchy = False # If there is only one stars, there is obviously no stellar heirarchy in # the encounter that is occuring. if len(stars) == 1: noStellarHierarchy = True if not noStellarHierarchy: # Check to see if the Nearest Neighbor is Mutual star_neighbour_id = closest_neighbours[index].id neighbour_neighbour_id = closest_neighbours[ stars.id == star_neighbour_id].id[0] for other_star in (stars - star): # Check to see if the two stars are bound. kep_s.initialize_from_dyn( star.mass + other_star.mass, star.x - other_star.x, star.y - other_star.y, star.z - other_star.z, star.vx - other_star.vx, star.vy - other_star.vy, star.vz - other_star.vz) a_s, e_s = kep_s.get_elements() print(star.id, other_star.id, e_s) # If they ARE NOT bound ... if e_s >= 1.0: noStellarHierarchy = True # If they ARE bound ... else: # If the star is the star's neighbour's neighbour and visa-versa, then proceed. print(star.id, other_star.id, star_neighbour_id, neighbour_neighbour_id) if star.id == neighbour_neighbour_id and other_star.id == star_neighbour_id: noStellarHierarchy = False print("Binary composed of Star", star.id, "and Star", other_star.id, "has been detected!") current_system.add_particle(other_star) binary_ids.append(star.id) binary_ids.append(other_star.id) else: print( "!!! Alert: Bound Stars are not closest neighbours ..." ) print("!!! Current Star:", star.id, "| Other Star:", other_star.id) print("!!! CS's Neighbour:", star_neighbour_id, \ "| CS's Neighbour's Neighbour:", neighbour_neighbour_id) checked_planet_ids = [] for KeyID in systems.keys(): current_system = systems[KeyID] sys_stars = util.get_stars(current_system) noStellarHierarchy = False # If there is only one stars, there is obviously no stellar heirarchy in # the encounter that is occuring. if len(sys_stars) == 1: noStellarHierarchy = True for planet in planets: if planet.id in checked_planet_ids: continue star = sys_stars[sys_stars.id == KeyID][0] total_mass = star.mass + planet.mass kep_pos = star.position - planet.position kep_vel = star.velocity - planet.velocity kep_p.initialize_from_dyn(total_mass, kep_pos[0], kep_pos[1], kep_pos[2], kep_vel[0], kep_vel[1], kep_vel[2]) a_p, e_p = kep_p.get_elements() P_p = kep_p.get_period() Ta_p, Ma_p = kep_p.get_angles() host_star_id = star.id if e_p < 1.0: # Check to See if The Planetary System is tied to a Stellar Binary # Note: Things get complicated if it is ... if noStellarHierarchy: # Get Additional Information on Orbit planet.semimajor_axis = a_p planet.eccentricity = e_p planet.period = P_p planet.true_anomaly = Ta_p planet.mean_anomaly = Ma_p planet.host_star = star.id # Add the Planet to the System Set current_system.add_particle(planet) else: # Handling for Planetary Systems in Stellar Heirarchical Structures # Note: We check to see which other star in the current systems # have a better boundness with the planet and choose that # as the new host star. for other_star in sys_stars - star: total_mass = other_star.mass + planet.mass kep_pos = other_star.position - planet.position kep_vel = other_star.velocity - planet.velocity kep_p.initialize_from_dyn(total_mass, kep_pos[0], kep_pos[1], kep_pos[2], kep_vel[0], kep_vel[1], kep_vel[2]) a_p2, e_p2 = kep_p.get_elements() # Check to see if the planet is more bound to 'star' or # 'other_star'. If its more bound to 'other_star', # set the attributes to the more bound object. This will # replace *_p with the better values with each loop. if e_p2 < e_p: a_p = a_p2 e_p = e_p2 P_p = kep_p.get_period() Ta_p, Ma_p = kep_p.get_angles() host_star_id = other_star.id planet.semimajor_axis = a_p planet.eccentricity = e_p planet.period = P_p planet.true_anomaly = Ta_p planet.mean_anomaly = Ma_p planet.host_star = host_star_id # Add the Planet to the System Set current_system.add_particle(planet) checked_planet_ids.append(planet.id) elif not noStellarHierarchy: # Handling for Planetary Systems in Stellar Heirarchical Structures # Note: We check to see which other star in the current systems # have a better boundness with the planet and choose that # as the new host star. for other_star in sys_stars - star: total_mass = other_star.mass + planet.mass kep_pos = other_star.position - planet.position kep_vel = other_star.velocity - planet.velocity kep_p.initialize_from_dyn(total_mass, kep_pos[0], kep_pos[1], kep_pos[2], kep_vel[0], kep_vel[1], kep_vel[2]) a_p2, e_p2 = kep_p.get_elements() # Check to see if the planet is more bound to 'star' or # 'other_star'. If its more bound to 'other_star', # set the attributes to the more bound object. This will # replace *_p with the better values with each loop. if e_p2 < e_p: a_p = a_p2 e_p = e_p2 P_p = kep_p.get_period() Ta_p, Ma_p = kep_p.get_angles() host_star_id = other_star.id planet.semimajor_axis = a_p planet.eccentricity = e_p planet.period = P_p planet.true_anomaly = Ta_p planet.mean_anomaly = Ma_p planet.host_star = host_star_id # Add the Planet to the System Set current_system.add_particle(planet) else: print( "!!! Alert: Planet is not bound nor is it bound to any other star." ) if kepler_workers == None: kep_p.stop() kep_s.stop() return systems
def get_planetary_systems_from_set(bodies, converter=None, RelativePosition=False): # Initialize Kepler if converter == None: converter = nbody_system.nbody_to_si( bodies.mass.sum(), 2 * np.max(bodies.radius.number) | bodies.radius.unit) kep_p = Kepler(unit_converter=converter, redirection='none') kep_p.initialize_code() kep_s = Kepler(unit_converter=converter, redirection='none') kep_s.initialize_code() # Seperate Out Planets and Stars from Bodies stars, planets = util.get_stars(bodies), util.get_planets(bodies) num_stars, num_planets = len(stars), len(planets) # Initialize the Dictionary that Contains all Planetary Systems systems = {} # Start Looping Through Stars to Find Bound Planets for star in stars: system_id = star.id #star.semimajor_axis, star.eccentricity, star.period, star.true_anomaly, star.mean_anomaly, star.kep_energy, star.angular_momentum = \ # None, None, None, None, None, None, None current_system = systems.setdefault(system_id, Particles()) current_system.add_particle(star) for planet in planets: total_mass = star.mass + planet.mass kep_pos = star.position - planet.position kep_vel = star.velocity - planet.velocity kep_p.initialize_from_dyn(total_mass, kep_pos[0], kep_pos[1], kep_pos[2], kep_vel[0], kep_vel[1], kep_vel[2]) a_p, e_p = kep_p.get_elements() if e_p < 1.0: # Check to See if The Stellar System is a Binary # Note: Things get complicated if it is ... noStellarHeirarchy = False for other_star in (stars - star): kep_s.initialize_from_dyn( star.mass + other_star.mass, star.x - other_star.x, star.y - other_star.y, star.z - other_star.z, star.vx - other_star.vx, star.vy - other_star.vy, star.vz - other_star.vz) a_s, e_s = kep_s.get_elements() r_apo = kep_s.get_apastron() HillR = util.calc_HillRadius(a_s, e_s, other_star.mass, star.mass) if e_s >= 1.0 or HillR < r_apo: noStellarHeirarchy = True else: noStellarHeirarchy = False if noStellarHeirarchy: # Get Additional Information on Orbit planet.semimajor_axis = a_p planet.eccentricity = e_p planet.period = kep_p.get_period() planet.true_anomaly, planet.mean_anomaly = kep_p.get_angles( ) #planet.kep_energy, planet.angular_momentum = kep_p.get_integrals() # Add the Planet to the System Set current_system.add_particle(planet) else: # Handling for Planetary Systems in Stellar Heirarchical Structures # Note: This is empty for now, maybe consider doing it by the heaviest bound stellar object as the primary. pass else: continue kep_p.stop() kep_s.stop() return systems
def get_orbit_ini(m0, m1, peri, ecc, incl, omega, rel_force=0.01, r_disk=50|units.AU): converter=nbody_system.nbody_to_si(1|units.MSun,1|units.AU) # semi-major axis if ecc!=1.0: semi = peri/(1.0-ecc) else: semi = 1.0e10 | units.AU # relative position and velocity vectors at the pericenter using kepler kepler = Kepler_twobody(converter) kepler.initialize_code() kepler.initialize_from_elements(mass=(m0+m1), semi=semi, ecc=ecc, periastron=peri) # at pericenter # moving particle backwards to radius r where: F_m1(r) = rel_force*F_m0(r_disk) #r_disk = peri r_ini = r_disk*(1.0 + numpy.sqrt(m1/m0)/rel_force) kepler.return_to_radius(radius=r_ini) rl = kepler.get_separation_vector() r = [rl[0].value_in(units.AU), rl[1].value_in(units.AU), rl[2].value_in(units.AU)] | units.AU vl = kepler.get_velocity_vector() v = [vl[0].value_in(units.kms), vl[1].value_in(units.kms), vl[2].value_in(units.kms)] | units.kms period_kepler = kepler.get_period() time_peri = kepler.get_time() kepler.stop() # rotation of the orbital plane by inclination and argument of periapsis a1 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a2 = ([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(a1,a2) r_au = numpy.reshape(r.value_in(units.AU), 3, 1) v_kms = numpy.reshape(v.value_in(units.kms), 3, 1) r_rot = numpy.dot(rot, r_au) | units.AU v_rot = numpy.dot(rot, v_kms) | units.kms bodies = Particles(2) bodies[0].mass = m0 bodies[0].radius = 1.0|units.RSun bodies[0].position = (0,0,0) | units.AU bodies[0].velocity = (0,0,0) | units.kms bodies[1].mass = m1 bodies[1].radius = 1.0|units.RSun bodies[1].x = r_rot[0] bodies[1].y = r_rot[1] bodies[1].z = r_rot[2] bodies[1].vx = v_rot[0] bodies[1].vy = v_rot[1] bodies[1].vz = v_rot[2] bodies.age = 0.0 | units.yr bodies.move_to_center() print "\t r_rel_ini = ", r_rot.in_(units.AU) print "\t v_rel_ini = ", v_rot.in_(units.kms) print "\t time since peri = ", time_peri.in_(units.yr) a_orbit, e_orbit, p_orbit = orbital_parameters(r_rot, v_rot, (m0+m1)) print "\t a = ", a_orbit.in_(units.AU), "\t e = ", e_orbit, "\t period = ", p_orbit.in_(units.yr) return bodies, time_peri
sun_and_stone = Particles(2) sun_and_stone[0].position = [-5.40085336308e+13, -5.92288255636e+13, 0. ] | units.m sun_and_stone[0].velocity = [-68.4281023588, -90.213640012, 0. ] | (units.m / units.s) sun_and_stone[0].mass = 1.98892e+30 | units.kg sun_and_stone[1].position = [2.31421952844e+17, 1.72742642121e+17, 0. ] | units.m sun_and_stone[1].velocity = [500794.477878, 373808.365427, 0. ] | (units.m / units.s) sun_and_stone[1].mass = 0. | units.kg print " particles:" print sun_and_stone converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) kepler = Kepler(converter) kepler.initialize_code() kepler.initialize_from_particles(sun_and_stone) semi, ecc = kepler.get_elements() apo = kepler.get_apastron() per = kepler.get_periastron() period = kepler.get_period() kepler.stop() print " semi-major axis ", semi.in_(units.AU) print " eccentricity ", ecc print " apocenter ", apo.in_(units.AU) print " pericenter ", per.in_(units.AU) print " period", period
def get_orbit_ini(m0, m1, peri, ecc, incl, omega, rel_force=0.01, r_disk=50 | units.AU): converter = nbody_system.nbody_to_si(1 | units.MSun, 1 | units.AU) # semi-major axis if ecc != 1.0: semi = peri / (1.0 - ecc) else: semi = 1.0e10 | units.AU # relative position and velocity vectors at the pericenter using kepler kepler = Kepler_twobody(converter) kepler.initialize_code() kepler.initialize_from_elements(mass=(m0 + m1), semi=semi, ecc=ecc, periastron=peri) # at pericenter # moving particle backwards to radius r where: F_m1(r) = rel_force*F_m0(r_disk) #r_disk = peri r_ini = r_disk * (1.0 + numpy.sqrt(m1 / m0) / rel_force) kepler.return_to_radius(radius=r_ini) rl = kepler.get_separation_vector() r = [ rl[0].value_in(units.AU), rl[1].value_in(units.AU), rl[2].value_in( units.AU) ] | units.AU vl = kepler.get_velocity_vector() v = [ vl[0].value_in(units.kms), vl[1].value_in(units.kms), vl[2].value_in( units.kms) ] | units.kms period_kepler = kepler.get_period() time_peri = kepler.get_time() kepler.stop() # rotation of the orbital plane by inclination and argument of periapsis a1 = ([1.0, 0.0, 0.0], [0.0, numpy.cos(incl), -numpy.sin(incl)], [0.0, numpy.sin(incl), numpy.cos(incl)]) a2 = ([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(a1, a2) r_au = numpy.reshape(r.value_in(units.AU), 3, 1) v_kms = numpy.reshape(v.value_in(units.kms), 3, 1) r_rot = numpy.dot(rot, r_au) | units.AU v_rot = numpy.dot(rot, v_kms) | units.kms bodies = Particles(2) bodies[0].mass = m0 bodies[0].radius = 1.0 | units.RSun bodies[0].position = (0, 0, 0) | units.AU bodies[0].velocity = (0, 0, 0) | units.kms bodies[1].mass = m1 bodies[1].radius = 1.0 | units.RSun bodies[1].x = r_rot[0] bodies[1].y = r_rot[1] bodies[1].z = r_rot[2] bodies[1].vx = v_rot[0] bodies[1].vy = v_rot[1] bodies[1].vz = v_rot[2] bodies.age = 0.0 | units.yr bodies.move_to_center() print "\t r_rel_ini = ", r_rot.in_(units.AU) print "\t v_rel_ini = ", v_rot.in_(units.kms) print "\t time since peri = ", time_peri.in_(units.yr) a_orbit, e_orbit, p_orbit = orbital_parameters(r_rot, v_rot, (m0 + m1)) print "\t a = ", a_orbit.in_( units.AU), "\t e = ", e_orbit, "\t period = ", p_orbit.in_(units.yr) return bodies, time_peri