def test_sub(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = rebound.Particle(m=1.4, x=1.6, vy=1.8) p3 = p1 - p2 self.assertAlmostEqual(p3.m, -0.3, delta=1e-15) self.assertAlmostEqual(p3.x, -0.4, delta=1e-15) self.assertAlmostEqual(p3.vy, -0.5, delta=1e-15)
def test_add(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = rebound.Particle(m=1.4, x=1.6, vy=1.8) p3 = p1 + p2 self.assertAlmostEqual(p3.m, 2.5, delta=1e-15) self.assertAlmostEqual(p3.x, 2.8, delta=1e-15) self.assertAlmostEqual(p3.vy, 3.1, delta=1e-15)
def test_create(self): p1 = rebound.Particle() p2 = rebound.Particle(x=1) with self.assertRaises(ValueError): p3 = rebound.Particle(a=1) with self.assertRaises(ValueError): p4 = rebound.Particle(p1)
def test_calculate_orbits_errors3(self): p1 = rebound.Particle(m=1., x=1., vy=0.4) p2 = rebound.Particle(m=1., x=4., vy=2.4) with self.assertRaises(ValueError): p2.calculate_orbit() with self.assertRaises(ValueError): p2.calculate_orbit(primary=p1) p2.calculate_orbit(primary=p1, G=1.)
def test_all_1st_order_full(self): vlist = ["a","e","i","Omega","omega","f","m"] paramslist = [ (1e-3,1.,0.1,0.02,0.3,0.56,0.4), (1e-6,2.,0.02,0.0132,0.33,1.56,0.14), (234.3e-6,1.7567,0.561,0.572,0.573,2.56,0.354), (1e-2,1.7567,0.1561,0.15472,0.24573,12.56,1.354), (1e-7,3.7567,0.00061,0.23572,0.523473,2.56,3.354), ] for params in paramslist: for v in vlist: m,a,e,inc,Omega,omega,f= params simvp = rebound.Simulation() simvp.add(m=1.) p = rebound.Particle(simulation=simvp, primary=simvp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simvp.add(p) simvp.add(primary=simvp.particles[0],a=1.76) var_i = simvp.add_variation() var_i.vary(1,v) simvp.integrate(10.) simsp = rebound.Simulation() simsp.add(m=1.) p = rebound.Particle(simulation=simsp, primary=simsp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simsp.add(p) simsp.add(primary=simsp.particles[0],a=1.76) Delta=1e-8 if v=="a": a+=Delta if v=="e": e+=Delta if v=="i": inc+=Delta if v=="Omega": Omega+=Delta if v=="omega": omega+=Delta if v=="f": f+=Delta if v=="m": m+=Delta sp = rebound.Particle(simulation=simsp, primary=simsp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simsp.particles[1] = sp simsp.integrate(10.) vp = var_i.particles[1] sp = simsp.particles[1] p = simvp.particles[1] prec = 1e-5 self.assertLess(abs((sp.x-p.x)/Delta-vp.x),prec) self.assertLess(abs((sp.y-p.y)/Delta-vp.y),prec) self.assertLess(abs((sp.z-p.z)/Delta-vp.z),prec) self.assertLess(abs((sp.vx-p.vx)/Delta-vp.vx),prec) self.assertLess(abs((sp.vy-p.vy)/Delta-vp.vy),prec) self.assertLess(abs((sp.vz-p.vz)/Delta-vp.vz),prec) self.assertLess(abs((sp.m-p.m)/Delta-vp.m),prec)
def get_canonical_heliocentric_orbits(sim): """ Compute orbital elements in canconical heliocentric coordinates. Arguments: ---------- sim : rb.Simulation simulation for which to compute orbits Returns ------- list of rebound.Orbits Orbits of particles in canonical heliocentric coordinates. """ star = sim.particles[0] orbits = [] fictitious_star = rb.Particle(m=star.m) com = sim.calculate_com() for planet in sim.particles[1:]: # Heliocentric position r = np.array(planet.xyz) - np.array(star.xyz) # Barycentric momentum rtilde = planet.m * ( np.array(planet.vxyz) - np.array(com.vxyz) ) # Mapping from (coordinate,momentum) pair to # orbital elments requires that the 'velocity' # be defined as the canonical momentum divided # by 'mu' appearing in the definition of the # Delauney variables (see, e.g., pg. 34 of # Morbidelli 2002). # # For Laskar & Robutel (1995)'s definition # of canonical action-angle pairs, this is # the reduced mass. # # For democratic heliocentric elements, # 'mu' is simply the planet mass. mu = planet.m * star.m / (planet.m + star.m) v_for_orbit = rtilde / mu fictitious_particle = rb.Particle( m=planet.m, x = r[0], y = r[1], z = r[2], vx = v_for_orbit[0], vy = v_for_orbit[1], vz = v_for_orbit[2] ) orbit = fictitious_particle.calculate_orbit(primary=fictitious_star,G = sim.G) orbits.append(orbit) return orbits
def test_add(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = rebound.Particle(m=1.4, x=1.6, vy=1.8) p3 = p1 + p2 self.assertEqual(p3.x, p1.x + p2.x) self.assertEqual(p3.y, p1.y + p2.y) self.assertEqual(p3.z, p1.z + p2.z) self.assertEqual(p3.vx, p1.vx + p2.vx) self.assertEqual(p3.vy, p1.vy + p2.vy) self.assertEqual(p3.vz, p1.vz + p2.vz) self.assertEqual(p3.m, p1.m + p2.m)
def test_sub(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = rebound.Particle(m=1.4, x=1.6, vy=1.8) p3 = p1 - p2 self.assertEqual(p3.x, p1.x - p2.x) self.assertEqual(p3.y, p1.y - p2.y) self.assertEqual(p3.z, p1.z - p2.z) self.assertEqual(p3.vx, p1.vx - p2.vx) self.assertEqual(p3.vy, p1.vy - p2.vy) self.assertEqual(p3.vz, p1.vz - p2.vz) self.assertEqual(p3.m, p1.m - p2.m)
def test_copy2(self): sim = rebound.Simulation() sim.add(m=1.) p1 = rebound.Particle(simulation=sim, m=1., e=0.2, a=1) p2 = rebound.Particle(p1) p1.m = 2. p2.m = 3. sim.add(p1) sim.add(p2) self.assertEqual(p1.m, 2.) self.assertEqual(p2.m, 3.) self.assertEqual(sim.particles[1].m, 2.) self.assertEqual(sim.particles[2].m, 3.)
def strong_regime(resolution, n_trials): print(f"Starting strong regime simulation with resolution {resolution}, " f"{n_trials} trials each...") xs = np.linspace(1, 100, resolution) f_eject = np.ones(resolution) for i, x in enumerate(xs): print("Running r_min =", x) eject_count = 0. # run n_trials trials detecting ejection directly after fly-by for j in range(n_trials): # get a fresh simulation sim = rebound.Simulation.from_file( "solar_system_outer_planets.bin") sim = randomize_sim(sim) intruder = rebound.Particle(m=1., x=x, y=-1000., vy=2.) sim = simulate_fly_by(sim, intruder) sim.move_to_hel() for particle in sim.particles[1:]: v = np.linalg.norm(particle.vxyz) v_esc = calc_escape_velocity(sim, particle) if v > v_esc: eject_count += 1 break print("Detected", eject_count, "ejections out of", n_trials, "trials.") f_eject[i] = eject_count / n_trials print(f_eject[i]) return (xs, f_eject)
def simulation(par): saturn_a, saturn_e = par sim = rebound.Simulation() sim.integrator = "whfast" sim.min_dt = 5. sim.dt = 1. # These parameters are only approximately those of Jupiter and Saturn. sun = rebound.Particle(m=1.) sim.add(sun) jupiter = sim.add(primary=sun, m=0.000954, a=5.204, M=0.600, omega=0.257, e=0.048) saturn = sim.add(primary=sun, m=0.000285, a=saturn_a, M=0.871, omega=1.616, e=saturn_e) sim.move_to_com() sim.init_megno() # Hide warning messages (WHFast timestep too large) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") sim.integrate(1e3 * 2. * np.pi) return [ sim.calculate_megno(), 1. / (sim.calculate_lyapunov() * 2. * np.pi) ] # returns MEGNO and Lypunov timescale in years
def simulation(par): saturn_a, saturn_e = par rebound.reset() rebound.integrator = "whfast-nocor" rebound.min_dt = 5. rebound.dt = 1. # These parameters are only approximately those of Jupiter and Saturn. sun = rebound.Particle(m=1.) rebound.add(sun) jupiter = rebound.add(primary=sun, m=0.000954, a=5.204, anom=0.600, omega=0.257, e=0.048) saturn = rebound.add(primary=sun, m=0.000285, a=saturn_a, anom=0.871, omega=1.616, e=saturn_e) rebound.move_to_com() rebound.init_megno(1e-16) rebound.integrate(1e3 * 2. * np.pi) return [ rebound.calculate_megno(), 1. / (rebound.calculate_lyapunov() * 2. * np.pi) ] # returns MEGNO and Lypunov timescale in years
def reb_cb(cb,tmin=None,tmax=None): '''Return transit times for a circumbinary system. Parameters ---------- cb : CBSys object Class holding system configuration. tmin, tmax : float Start and end times of simulation, in days. ''' sim = rebound.Simulation() sim.t = 0.0 sim.add(m = cb.m1) comp = rebound.Particle(simulation=sim, m=cb.m2, a=cb.ab, e=cb.eb, inc=cb.ib, omega=cb.wb, f=cb.fb, Omega=cb.Wb) sim.add(comp) sim.move_to_com() planet = rebound.Particle(simulation=sim, m=cb.mp, a=cb.ap, e=cb.ep, inc=cb.ip, omega=cb.wp, f=cb.fp, Omega=cb.Wp) sim.add(planet) sim.move_to_com() # integrate to start time sim.integrate(tmax = (tmin - cb.t0)/365.25 * 2 * np.pi ) # globals for heartbeat p = sim.particles global transittimes, lastt, lastdx1, lastdx2, lastdx12, lastdv1, lastdv2 lastt = sim.t; lastdx1 = p[2].x - p[0].x lastdx2 = p[2].x - p[1].x lastdx12 = p[1].x - p[0].x lastdv1 = p[2].vx - p[0].vx lastdv2 = p[2].vx - p[1].vx transittimes = () # integrate to end sim.heartbeat = heartbeat sim.integrate(tmax = (tmax - cb.t0)/365.25 * 2 * np.pi ) # get transit times and convert back to days tts = np.array(transittimes) tts[:,1] /= 2.0 * np.pi / 365.25 tts[:,1] += cb.t0 return tts
def test_close_encounter(self): sim = rebound.Simulation() sim.add(m=1.) sim.add(m=1.e-3, a=1.523, e=0.0146, f=0.24) rh = sim.particles[1].a * pow( sim.particles[1].m / (3. * sim.particles[0].m), 1. / 3) dust = rebound.Particle(simulation=sim, primary=sim.particles[1], a=0.25 * rh, e=0.000123, f=2.3, m=1e-8) sim.add(dust) sim.integrator = "hermes" sim.gravity = "basic" sim.ri_hermes.hill_switch_factor = 2. P = sim.particles[1].P sim.dt = 1e-4 * P for i in range(1000): sim.step() x_hermes = sim.particles[1].x sim = rebound.Simulation() sim.add(m=1.) sim.add(m=1.e-3, a=1.523, e=0.0146, f=0.24) dust = rebound.Particle(simulation=sim, primary=sim.particles[1], a=0.25 * rh, e=0.000123, f=2.3, m=1e-8) sim.add(dust) sim.integrator = "ias15" sim.gravity = "basic" P = sim.particles[1].P dt0 = 1e-4 * P sim.dt = dt0 t = 0. for i in range(1000): t += dt0 / 2. t += dt0 / 2. sim.integrate(t) x_ias15 = sim.particles[1].x self.assertEqual(x_hermes, x_ias15)
def test_mul(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = 2. * p1 self.assertEqual(p2.x, 2. * p1.x) self.assertEqual(p2.y, 2. * p1.y) self.assertEqual(p2.z, 2. * p1.z) self.assertEqual(p2.vx, 2. * p1.vx) self.assertEqual(p2.vy, 2. * p1.vy) self.assertEqual(p2.vz, 2. * p1.vz) self.assertEqual(p2.m, 2. * p1.m)
def test_truediv(self): p1 = rebound.Particle(m=1.2, x=1.4, vy=1.8) p2 = p1 / 2 self.assertEqual(p2.x, p1.x / 2.) self.assertEqual(p2.y, p1.y / 2.) self.assertEqual(p2.z, p1.z / 2.) self.assertEqual(p2.vx, p1.vx / 2.) self.assertEqual(p2.vy, p1.vy / 2.) self.assertEqual(p2.vz, p1.vz / 2.) self.assertEqual(p2.m, p1.m / 2.)
def add_planets(self): """Add the planets, using a list of a""" #init random number generator to get reproducible random phases rng = random.Random(self.hash) for ip in range(0, self.params['nchain']): true_anomaly = rng.uniform(0.0, 2.0*np.pi) inclination = rng.normalvariate(0.0, self.params['incscatter']) if self.verbose: print('adding {} at a={:e}'.format(ip+1,self.params['a'][ip])) pt = rebound.Particle(simulation=self.sim, primary=self.sim.particles[0], m=self.params['pmass'], a=self.params['a'][ip], inc=inclination, f=true_anomaly) pt.r = self.params['a'][ip]*np.sqrt(pt.m/3.0) self.sim.add(pt)
def add_planets(self): """Add the planets. In this method so it can be overloaded.""" #init random number generator to get reproducible random phases rng = random.Random(self.hash) a = self.params['a0'] for ip in range(1, self.params['nchain']+1): true_anomaly = rng.uniform(0.0, 2.0*np.pi) inclination = rng.normalvariate(0.0, self.params['incscatter']) if self.verbose: print('adding {} at a={:e}'.format(ip,a)) pt = rebound.Particle(simulation=self.sim, primary=self.sim.particles[0], m=self.params['pmass'], a=a, inc=inclination, f=true_anomaly) pt.r = a*np.sqrt(pt.m/3.0) self.sim.add(pt) # the 0.05 is a spread. but maybe this could be a param a *= (self.params['p_res'] / (self.params['p_res'] + self.params['q_res'] + self.params['aspread']))**(-2.0/3.0)
def strong_regime(resolution, n_trials): """ Simulates a fly-by and calculates whether the system is stable or not. """ print(f"Starting strong regime simulation with resolution {resolution}, " f"{n_trials} trials each...") xs = np.linspace(1, 50, resolution) f_eject = np.ones(resolution) f_stable = np.ones(resolution) for i, x in enumerate(xs): print(f"Running r_min = {x} at {round(100.*x/len(xs), 1)}%") eject_count = 0. stable_count = 0. # run n_trials trials detecting ejection directly after fly-by for j in range(n_trials): # get a fresh simulation sim = rebound.Simulation.from_file("solar_system_outer_planets.bin") sim = randomize_sim(sim) intruder = rebound.Particle(m=1.,x=x,y=-1000.,vy=2.) sim = simulate_fly_by(sim, intruder) sim.move_to_hel() for particle in sim.particles[1:]: v = np.linalg.norm(particle.vxyz) v_esc = calc_escape_velocity(sim, particle) if v > v_esc: eject_count += 1 break stable = analyze_stability(sim) if stable: stable_count += 1 print("Detected", eject_count, "ejections out of", n_trials, "trials.") if n_trials > eject_count: percentage = 100 * stable_count / (n_trials-eject_count) print(eject_count, n_trials, stable_count) print(f"Of the {n_trials - eject_count} systems left, " f"{percentage}% was not long term unstable.") f_eject[i] = eject_count / n_trials f_stable[i] = stable_count / n_trials return (xs, f_eject, f_stable)
def run_2nd_order_full(self, com=False): vlist = ["a","e","i","Omega","omega","f","m"] # Testing a few random initial conditions paramslist = [ (1e-3,1.,0.1,0.02,0.3,0.56,0.4), (1e-6,2.,0.02,0.0132,0.33,1.56,0.14), (234.3e-6,1.7567,0.561,0.572,0.573,2.56,0.354), (1e-2,1.7567,0.1561,0.15472,0.24573,12.56,1.354), (1e-7,3.7567,0.00061,0.23572,0.523473,2.56,3.354), ] for params in paramslist: for v1 in vlist: for v2 in vlist: m,a,e,inc,Omega,omega,f= params simvp = rebound.Simulation() simvp.add(m=1.) p = rebound.Particle(simulation=simvp, primary=simvp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simvp.add(p) simvp.add(primary=simvp.particles[0],a=1.76) var_ia = simvp.add_variation() var_ib = simvp.add_variation() var_ii = simvp.add_variation(order=2,first_order=var_ia,first_order_2=var_ib) var_ia.vary(1, v1) var_ib.vary(1, v2) var_ii.vary(1, v1, v2) if com: simvp.move_to_com() simvp.integrate(10.) p = simvp.particles[1] vp_ia = var_ia.particles[1] vp_ib = var_ib.particles[1] vp_ii = var_ii.particles[1] Delta = 1e-4 if v1==v2: m,a,e,inc,Omega,omega,f= params simp = rebound.Simulation() simp.add(m=1.) simp.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simp.add(a=1.76) if v1=="a": a+=Delta if v1=="e": e+=Delta if v1=="i": inc+=Delta if v1=="Omega": Omega+=Delta if v1=="omega": omega+=Delta if v1=="f": f+=Delta if v1=="m": m+=Delta simp.particles[1] = rebound.Particle(simulation=simp, primary=simp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simp.move_to_com() simp.integrate(10.) sp = simp.particles[1] m,a,e,inc,Omega,omega,f= params simm = rebound.Simulation() simm.add(m=1.) simm.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simm.add(a=1.76) if v1=="a": a-=Delta if v1=="e": e-=Delta if v1=="i": inc-=Delta if v1=="Omega": Omega-=Delta if v1=="omega": omega-=Delta if v1=="f": f-=Delta if v1=="m": m-=Delta simm.particles[1] = rebound.Particle(simulation=simm, primary=simm.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simm.move_to_com() simm.integrate(10.) sm = simm.particles[1] prec = 1e-4 self.assertLess(abs((sp.x-2.*p.x+sm.x)/Delta/Delta-vp_ii.x),prec) self.assertLess(abs((sp.y-2.*p.y+sm.y)/Delta/Delta-vp_ii.y),prec) self.assertLess(abs((sp.z-2.*p.z+sm.z)/Delta/Delta-vp_ii.z),prec) self.assertLess(abs((sp.vx-2.*p.vx+sm.vx)/Delta/Delta-vp_ii.vx),prec) self.assertLess(abs((sp.vy-2.*p.vy+sm.vy)/Delta/Delta-vp_ii.vy),prec) self.assertLess(abs((sp.vz-2.*p.vz+sm.vz)/Delta/Delta-vp_ii.vz),prec) self.assertLess(abs((sp.m-2.*p.m+sm.m)/Delta/Delta-vp_ii.m),prec) # Also checking first order prec = 1e-5 self.assertLess(abs((sp.x -sm.x )/Delta/2.-vp_ia.x ),prec) self.assertLess(abs((sp.y -sm.y )/Delta/2.-vp_ia.y ),prec) self.assertLess(abs((sp.z -sm.z )/Delta/2.-vp_ia.z ),prec) self.assertLess(abs((sp.vx-sm.vx)/Delta/2.-vp_ia.vx),prec) self.assertLess(abs((sp.vy-sm.vy)/Delta/2.-vp_ia.vy),prec) self.assertLess(abs((sp.vz-sm.vz)/Delta/2.-vp_ia.vz),prec) self.assertLess(abs((sp.m -sm.m) /Delta/2.-vp_ia.m ),prec) else: m,a,e,inc,Omega,omega,f= params simpp = rebound.Simulation() simpp.add(m=1.) simpp.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simpp.add(a=1.76) if v1=="a": a+=Delta if v1=="e": e+=Delta if v1=="i": inc+=Delta if v1=="Omega": Omega+=Delta if v1=="omega": omega+=Delta if v1=="f": f+=Delta if v1=="m": m+=Delta if v2=="a": a+=Delta if v2=="e": e+=Delta if v2=="i": inc+=Delta if v2=="Omega": Omega+=Delta if v2=="omega": omega+=Delta if v2=="f": f+=Delta if v2=="m": m+=Delta simpp.particles[1] = rebound.Particle(simulation=simpp, primary=simpp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simpp.move_to_com() simpp.integrate(10.) spp = simpp.particles[1] m,a,e,inc,Omega,omega,f= params simpm = rebound.Simulation() simpm.add(m=1.) simpm.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simpm.add(a=1.76) if v1=="a": a+=Delta if v1=="e": e+=Delta if v1=="i": inc+=Delta if v1=="Omega": Omega+=Delta if v1=="omega": omega+=Delta if v1=="f": f+=Delta if v1=="m": m+=Delta if v2=="a": a-=Delta if v2=="e": e-=Delta if v2=="i": inc-=Delta if v2=="Omega": Omega-=Delta if v2=="omega": omega-=Delta if v2=="f": f-=Delta if v2=="m": m-=Delta simpm.particles[1] = rebound.Particle(simulation=simpm, primary=simpm.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simpm.move_to_com() simpm.integrate(10.) spm = simpm.particles[1] m,a,e,inc,Omega,omega,f= params simmp = rebound.Simulation() simmp.add(m=1.) simmp.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simmp.add(a=1.76) if v1=="a": a-=Delta if v1=="e": e-=Delta if v1=="i": inc-=Delta if v1=="Omega": Omega-=Delta if v1=="omega": omega-=Delta if v1=="f": f-=Delta if v1=="m": m-=Delta if v2=="a": a+=Delta if v2=="e": e+=Delta if v2=="i": inc+=Delta if v2=="Omega": Omega+=Delta if v2=="omega": omega+=Delta if v2=="f": f+=Delta if v2=="m": m+=Delta simmp.particles[1] = rebound.Particle(simulation=simmp, primary=simmp.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simmp.move_to_com() simmp.integrate(10.) smp = simmp.particles[1] m,a,e,inc,Omega,omega,f= params simmm = rebound.Simulation() simmm.add(m=1.) simmm.add(m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) simmm.add(a=1.76) if v1=="a": a-=Delta if v1=="e": e-=Delta if v1=="i": inc-=Delta if v1=="Omega": Omega-=Delta if v1=="omega": omega-=Delta if v1=="f": f-=Delta if v1=="m": m-=Delta if v2=="a": a-=Delta if v2=="e": e-=Delta if v2=="i": inc-=Delta if v2=="Omega": Omega-=Delta if v2=="omega": omega-=Delta if v2=="f": f-=Delta if v2=="m": m-=Delta simmm.particles[1] = rebound.Particle(simulation=simmm, primary=simmm.particles[0],m=m,a=a,e=e,inc=inc,Omega=Omega,omega=omega,f=f) if com: simmm.move_to_com() simmm.integrate(10.) smm = simmm.particles[1] prec = 1e-4 self.assertLess(abs((spp.x -spm.x -smp.x +smm.x )/Delta/Delta/4.-vp_ii.x),prec) self.assertLess(abs((spp.y -spm.y -smp.y +smm.y )/Delta/Delta/4.-vp_ii.y),prec) self.assertLess(abs((spp.z -spm.z -smp.z +smm.z )/Delta/Delta/4.-vp_ii.z),prec) self.assertLess(abs((spp.vx -spm.vx -smp.vx +smm.vx )/Delta/Delta/4.-vp_ii.vx),prec) self.assertLess(abs((spp.vy -spm.vy -smp.vy +smm.vy )/Delta/Delta/4.-vp_ii.vy),prec) self.assertLess(abs((spp.vz -spm.vz -smp.vz +smm.vz )/Delta/Delta/4.-vp_ii.vz),prec) self.assertLess(abs((spp.m -spm.m -smp.m +smm.m )/Delta/Delta/4.-vp_ii.m),prec)
def reb_cb_dvm(cb, baseBody, transitingBody, tmin, tmax, timing_precision, close=0.5): '''Return transit times for a circumbinary system. This method is typically faster than functions that just integrate forward in time. Function returns arrays of transit times and durations, in days. Parameters ---------- cb : CBSys object Class holding system configuration. baseBody, transitingBody : int Which transits to extract. Use 0, 1, 2 for primary star, secondary star, planet. tmin, tmax : float Start and end times of simulation, in days. timing_precision : float Desired precision on transit times, in years/2pi (yes the units need updating). close : float Close encounter distance in Hill units of secondary. ''' # Load some initial stuff transittimes = [] transitdurations = [] # create the rebound simulation and set the units sim = rebound.Simulation() # set close encouter distance r_hill = cb.ab * (1-cb.eb) * ( cb.m2 / (cb.m1+cb.m2) )**(1/3.) sim.exit_min_distance = close * r_hill # put the radii into an array, to be used later for transit calculations R = [cb.r1,cb.r2,cb.rp] # add the three bodies to rebound sim.t = 0.0 sim.add(m = cb.m1) comp = rebound.Particle(simulation=sim, m=cb.m2, a=cb.ab, e=cb.eb, inc=cb.ib, omega=cb.wb, f=cb.fb, Omega=cb.Wb) sim.add(comp) sim.move_to_com() planet = rebound.Particle(simulation=sim, m=cb.mp, a=cb.ap, e=cb.ep, inc=cb.ip, omega=cb.wp, f=cb.fp, Omega=cb.Wp) sim.add(planet) # below you can set the number of active particles # active particle means it has mass and you therefore have to calculate its gravitational force # on other bodies. 3=all, 2=massless planet sim.N_active = 3 # put everything to the centre of mass sim.move_to_com() # integrate to start time sim.integrate(tmax = (tmin - cb.t0)/365.25 * 2 * np.pi ) # p is a reference to the positions and velocities of all three bodies p = sim.particles # Get a reference to the period of the transiting body, used for integration timing if (transitingBody == 0 or transitingBody == 1): P_bin = (cb.ab**3/(cb.m1+cb.m2))**(1./2.)/(2*np.pi) #in years/2pi P_transiter = P_bin elif (transitingBody == 2): P_p = p_p0 = (cb.ap**3/(cb.m1+cb.m2))**(1./2.)/(2*np.pi) #in years/2pi P_transiter = P_p # Integrate the system from time 0 to tMax while sim.t<(tmax - cb.t0)/365.25 * 2 * np.pi : # The old x position of the transiting body with respect to the base body x_old = p[transitingBody].x - p[baseBody].x # and the corresponding time t_old = sim.t # Integrate over a quarter of the planet's period sim.integrate(sim.t + P_transiter/4.) # Calculate a new position and time x_new = p[transitingBody].x - p[baseBody].x # old x position of the transiting body with respect to the base body t_new = sim.t # Check if the sign has changed on the x axis (a crossing) and the planet is in front of the star (z<0) # Remember that as an observer we are looking down the positive z-axis if x_old*x_new<0. and (p[transitingBody].z - p[baseBody].z) > 0: while t_new-t_old>timing_precision: # do a bisection to a set precision if x_old*x_new<0.: t_new = sim.t else: t_old = sim.t sim.integrate((t_new+t_old)/2.) x_new = p[transitingBody].x - p[baseBody].x # finished the bisection because the t_old and t_new are now within the precision # now we can store the time transittimes.append(sim.t) # Now want to calculate the transit duration # Calculate impact parameter over the star being transited # Calculated just by looking at the y parameter of the planet with respect to the star bi = np.abs(p[baseBody].y - p[transitingBody].y)/R[baseBody] if bi < 1: # a transit occurred because the impact parameter is less than 1 # the transit duration is just a simple distance/speed calculation transitdurations.append(2*((R[baseBody]+R[transitingBody])**2. - (bi*R[baseBody])**2.)**(1./2.)/((p[transitingBody].vx-p[baseBody].vx)**2. + (p[transitingBody].vy-p[baseBody].vy)**2.)**(1./2.)) else: # no transit occured transitdurations.append(0) # Note that the transit time is always stored, regardless of whether or not a transit actually occurs (impact parameter < 1) # The transit time is purely due to a crossing of the x-axis # A transit duration of 0 indicates that the planet missed the star. sim.integrate(sim.t + P_transiter/10.) # add a 10th of the planet's orbital period just to push past the transit # get transit times and convert back to days tts = np.array(transittimes) tds = np.array(transitdurations) tts /= 2.0 * np.pi / 365.25 tts += cb.t0 if np.sum(tds>0)>0: tds /= 2.0 * np.pi / 365.25 return tts, tds
def simulation(par): cruithne_a, cruithne_e = par sim = rebound.Simulation() sim.integrator = "janus" sim.min_dt = 0.05 sim.dt = 1 sim.G = 1.4880826e-34 #Units of AU^3/kg/day^2 ss_pos = np.array([ [-3.013424684820004E-03, 7.577400311699641E-03, 1.522327948994377E-06], [ -1.744888637875314E-01, -4.244459073219732E-01, -1.957052267164663E-02 ], [ -5.832166811075774E-01, -4.227197431546666E-01, 2.757923523005813E-02 ], [9.926803557750922E-01, 1.171071592931596E-01, -5.897765002577186E-06], [8.228862161210234E-01, 6.587996475726317E-01, -3.785334833271938E-01], [-1.644137782803167E+00, 2.530657764233049E-01, 4.541188790127934E-02], [ -1.699642400881444E-01, -5.250743091389841E+00, 2.557799438953158E-02 ], [3.337284978938324E+00, -9.463581115929795E+00, 3.169757971579321E-02], [1.643185373589321E+01, 1.110227970027843E+01, -1.716425425492940E-01], [ 2.917750633262754E+01, -6.646446374100315E+00, -5.355542983258703E-01 ], [ 1.269610583507422E+01, -3.141113199578617E+01, -3.112775015648088E-01 ] ]) ss_vel = np.array([ [ -8.492322341632166E-06, -9.353155515358904E-07, 2.301541419735291E-07 ], [ 2.048459325443986E-02, -8.995044409873299E-03, -2.614664569098718E-03 ], [ 1.189797004491595E-02, -1.634153795167905E-02, -9.110754924475504E-04 ], [ -2.170315646338148E-03, 1.703520105098581E-02, -5.463857304374388E-07 ], [-1.381007577874730E-02, 5.897333087115376E-03, 2.754466583425123E-03], [ -1.556986377304836E-03, -1.264431146517457E-02, -2.267130777538514E-04 ], [7.450947804402543E-03, 1.166544750377484E-04, -1.671012875749180E-04], [4.952121119936067E-03, 1.839073137038874E-03, -2.293132844397104E-04], [-2.230759206307085E-03, 3.075630739324861E-03, 4.027037883636828E-05], [6.759177587143499E-04, 3.079179855664010E-03, -7.882476544965271E-05], [2.988188173523851E-03, 5.096901737398172E-04, -9.289666940024388E-04] ]) ss_mass = np.array([ 1.988544e30, 3.302e23, 48.685e23, 6.045476731e24, 1.3e14, 6.4185e23, 1898.13e24, 5.68319e26, 86.8103e24, 102.41e24, 1.4639248e+22 ]) # These parameters are only approximately those of Jupiter and Saturn. #Add particles for x in [0, 1, 2, 3]: #,5,6,7,8,9,10]: p = rebound.Particle(m=ss_mass[x], x=ss_pos[x, 0], y=ss_pos[x, 1], z=ss_pos[x, 2], vx=ss_vel[x, 0], vy=ss_vel[x, 1], vz=ss_vel[x, 2]) sim.add(p) #cruithne = rebound.Particle() # M=0.6989875253, # M=4.97689734325, # Omega=2.205628636, # omega=0.7616728033, cruithne = sim.add(m=ss_mass[4], a=cruithne_a, e=cruithne_e, inc=0.34567242532, Omega=2.20306437947, omega=0.76510954706, f=3.98060732223) for x in [5, 6, 7, 8, 9, 10]: p = rebound.Particle(m=ss_mass[x], x=ss_pos[x, 0], y=ss_pos[x, 1], z=ss_pos[x, 2], vx=ss_vel[x, 0], vy=ss_vel[x, 1], vz=ss_vel[x, 2]) sim.add(p) #sun = rebound.Particle(m=1.) #sim.add(sun) #jupiter = sim.add(primary=sun,m=0.000954, a=5.204, M=0.600, omega=0.257, e=0.048) #saturn = sim.add(primary=sun,m=0.000285, a=saturn_a, M=0.871, omega=1.616, e=saturn_e) sim.move_to_com() sim.init_megno() # Hide warning messages (WHFast timestep too large) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") sim.integrate(1E4) return [ sim.calculate_megno(), 1. / (sim.calculate_lyapunov() * 2. * np.pi) ] # returns MEGNO and Lypunov timescale in years
def add_planet(sim, m, a, true_anomaly, hash): # vary f as the true anomaly sim.add(rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=0.0, inc = 0.0, Omega=0.0, omega=0.0, f = true_anomaly , r = a*np.sqrt(m/3.0), hash=hash))
def test_all_2nd_order_init(self): vlist = ["a", "e", "i", "Omega", "omega", "f", "m"] # Testing a few random initial conditions paramslist = [ (1e-3, 1., 0.1, 0.02, 0.3, 0.56, 0.4), (1e-6, 2., 0.02, 0.0132, 0.33, 1.56, 0.14), (234.3e-6, 1.7567, 0.561, 0.572, 0.573, 2.56, 0.354), (1e-2, 1.7567, 0.1561, 0.15472, 0.24573, 12.56, 1.354), (1e-7, 3.7567, 0.00061, 0.23572, 0.523473, 2.56, 3.354), ] for params in paramslist: for v1 in vlist: for v2 in vlist: sim = rebound.Simulation() sim.add(m=1.) m, a, e, inc, Omega, omega, f = params sim.add(m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) sim.add(a=1.76) p = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) vp = rebound.Particle(simulation=sim, primary=sim.particles[0], variation=v1, variation2=v2, variation_order=2, m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) Delta = 1e-4 if v1 == v2: m, a, e, inc, Omega, omega, f = params if v1 == "a": a += Delta if v1 == "e": e += Delta if v1 == "i": inc += Delta if v1 == "Omega": Omega += Delta if v1 == "omega": omega += Delta if v1 == "f": f += Delta if v1 == "m": m += Delta sp = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) m, a, e, inc, Omega, omega, f = params if v1 == "a": a -= Delta if v1 == "e": e -= Delta if v1 == "i": inc -= Delta if v1 == "Omega": Omega -= Delta if v1 == "omega": omega -= Delta if v1 == "f": f -= Delta if v1 == "m": m -= Delta sm = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) prec = 1e-6 self.assertLess( abs((sp.x - 2. * p.x + sm.x) / Delta / Delta - vp.x), prec) self.assertLess( abs((sp.y - 2. * p.y + sm.y) / Delta / Delta - vp.y), prec) self.assertLess( abs((sp.z - 2. * p.z + sm.z) / Delta / Delta - vp.z), prec) self.assertLess( abs((sp.vx - 2. * p.vx + sm.vx) / Delta / Delta - vp.vx), prec) self.assertLess( abs((sp.vy - 2. * p.vy + sm.vy) / Delta / Delta - vp.vy), prec) self.assertLess( abs((sp.vz - 2. * p.vz + sm.vz) / Delta / Delta - vp.vz), prec) self.assertLess( abs((sp.m - 2. * p.m + sm.m) / Delta / Delta - vp.m), prec) else: m, a, e, inc, Omega, omega, f = params if v1 == "a": a += Delta if v1 == "e": e += Delta if v1 == "i": inc += Delta if v1 == "Omega": Omega += Delta if v1 == "omega": omega += Delta if v1 == "f": f += Delta if v1 == "m": m += Delta if v2 == "a": a += Delta if v2 == "e": e += Delta if v2 == "i": inc += Delta if v2 == "Omega": Omega += Delta if v2 == "omega": omega += Delta if v2 == "f": f += Delta if v2 == "m": m += Delta spp = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) m, a, e, inc, Omega, omega, f = params if v1 == "a": a += Delta if v1 == "e": e += Delta if v1 == "i": inc += Delta if v1 == "Omega": Omega += Delta if v1 == "omega": omega += Delta if v1 == "f": f += Delta if v1 == "m": m += Delta if v2 == "a": a -= Delta if v2 == "e": e -= Delta if v2 == "i": inc -= Delta if v2 == "Omega": Omega -= Delta if v2 == "omega": omega -= Delta if v2 == "f": f -= Delta if v2 == "m": m -= Delta spm = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) m, a, e, inc, Omega, omega, f = params if v1 == "a": a -= Delta if v1 == "e": e -= Delta if v1 == "i": inc -= Delta if v1 == "Omega": Omega -= Delta if v1 == "omega": omega -= Delta if v1 == "f": f -= Delta if v1 == "m": m -= Delta if v2 == "a": a += Delta if v2 == "e": e += Delta if v2 == "i": inc += Delta if v2 == "Omega": Omega += Delta if v2 == "omega": omega += Delta if v2 == "f": f += Delta if v2 == "m": m += Delta smp = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) m, a, e, inc, Omega, omega, f = params if v1 == "a": a -= Delta if v1 == "e": e -= Delta if v1 == "i": inc -= Delta if v1 == "Omega": Omega -= Delta if v1 == "omega": omega -= Delta if v1 == "f": f -= Delta if v1 == "m": m -= Delta if v2 == "a": a -= Delta if v2 == "e": e -= Delta if v2 == "i": inc -= Delta if v2 == "Omega": Omega -= Delta if v2 == "omega": omega -= Delta if v2 == "f": f -= Delta if v2 == "m": m -= Delta smm = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) prec = 1e-6 self.assertLess( abs((spp.x - spm.x - smp.x + smm.x) / Delta / Delta / 4. - vp.x), prec) self.assertLess( abs((spp.y - spm.y - smp.y + smm.y) / Delta / Delta / 4. - vp.y), prec) self.assertLess( abs((spp.z - spm.z - smp.z + smm.z) / Delta / Delta / 4. - vp.z), prec) self.assertLess( abs((spp.vx - spm.vx - smp.vx + smm.vx) / Delta / Delta / 4. - vp.vx), prec) self.assertLess( abs((spp.vy - spm.vy - smp.vy + smm.vy) / Delta / Delta / 4. - vp.vy), prec) self.assertLess( abs((spp.vz - spm.vz - smp.vz + smm.vz) / Delta / Delta / 4. - vp.vz), prec) self.assertLess( abs((spp.m - spm.m - smp.m + smm.m) / Delta / Delta / 4. - vp.m), prec)
def test_all_1st_order_init(self): vlist = ["a", "e", "i", "Omega", "omega", "f", "m"] paramslist = [ (1e-3, 1., 0.1, 0.02, 0.3, 0.56, 0.4), (1e-6, 2., 0.02, 0.0132, 0.33, 1.56, 0.14), (234.3e-6, 1.7567, 0.561, 0.572, 0.573, 2.56, 0.354), (1e-2, 1.7567, 0.1561, 0.15472, 0.24573, 12.56, 1.354), (1e-7, 3.7567, 0.00061, 0.23572, 0.523473, 2.56, 3.354), ] for params in paramslist: for v in vlist: sim = rebound.Simulation() sim.add(m=1.) m, a, e, inc, Omega, omega, f = params Delta = 1e-8 sim.add(m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) sim.add(a=1.76) p = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) vp = rebound.Particle(simulation=sim, primary=sim.particles[0], variation=v, m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) if v == "a": a += Delta if v == "e": e += Delta if v == "i": inc += Delta if v == "Omega": Omega += Delta if v == "omega": omega += Delta if v == "f": f += Delta if v == "m": m += Delta sp = rebound.Particle(simulation=sim, primary=sim.particles[0], m=m, a=a, e=e, inc=inc, Omega=Omega, omega=omega, f=f) self.assertLess(abs((sp.x - p.x) / Delta - vp.x), 1e-6) self.assertLess(abs((sp.y - p.y) / Delta - vp.y), 1e-6) self.assertLess(abs((sp.z - p.z) / Delta - vp.z), 1e-6) self.assertLess(abs((sp.vx - p.vx) / Delta - vp.vx), 1e-6) self.assertLess(abs((sp.vy - p.vy) / Delta - vp.vy), 1e-6) self.assertLess(abs((sp.vz - p.vz) / Delta - vp.vz), 1e-6) self.assertLess(abs((sp.m - p.m) / Delta - vp.m), 1e-6)
def simulation(par): integrator, run, trial = par sim = rebound.Simulation() k = 0.01720209895 Gfac = 1. / k #Gfac = 1 sim.dt = dt if integrator == "whfast-nocor": integrator = "whfast" else: sim.ri_whfast.corrector = 17 sim.integrator = integrator sim.ri_whfast.safe_mode = 0 #massfac = 1. #sim.add(m=1.00000597682, x=-4.06428567034226e-3, y=-6.08813756435987e-3, z=-1.66162304225834e-6, vx=+6.69048890636161e-6*Gfac, vy=-6.33922479583593e-6*Gfac, vz=-3.13202145590767e-9*Gfac) # Sun #sim.add(m=massfac/1407.355, x=+3.40546614227466e+0, y=+3.62978190075864e+0, z=+3.42386261766577e-2, vx=-5.59797969310664e-3*Gfac, vy=+5.51815399480116e-3*Gfac, vz=-2.66711392865591e-6*Gfac) # Jupiter #sim.add(m=massfac/3501.6, x=+6.60801554403466e+0, y=+6.38084674585064e+0, z=-1.36145963724542e-1, vx=-4.17354020307064e-3*Gfac, vy=+3.99723751748116e-3*Gfac, vz=+1.67206320571441e-5*Gfac) # Saturn #sim.add(m=massfac/22869., x=+1.11636331405597e+1, y=+1.60373479057256e+1, z=+3.61783279369958e-1, vx=-3.25884806151064e-3*Gfac, vy=+2.06438412905916e-3*Gfac, vz=-2.17699042180559e-5*Gfac) # Uranus #sim.add(m=massfac/19314., x=-3.01777243405203e+1, y=+1.91155314998064e+0, z=-1.53887595621042e-1, vx=-2.17471785045538e-4*Gfac, vy=-3.11361111025884e-3*Gfac, vz=+3.58344705491441e-5*Gfac) # Neptune #sim.G = 1.4880826e-34 #Units of AU^3/kg/day^2 ss_pos = np.array([ [-3.013424684820004E-03, 7.577400311699641E-03, 1.522327948994377E-06], [ -1.744888637875314E-01, -4.244459073219732E-01, -1.957052267164663E-02 ], [ -5.832166811075774E-01, -4.227197431546666E-01, 2.757923523005813E-02 ], [9.926803557750922E-01, 1.171071592931596E-01, -5.897765002577186E-06], [8.228862161210234E-01, 6.587996475726317E-01, -3.785334833271938E-01], [-1.644137782803167E+00, 2.530657764233049E-01, 4.541188790127934E-02], [ -1.699642400881444E-01, -5.250743091389841E+00, 2.557799438953158E-02 ], [3.337284978938324E+00, -9.463581115929795E+00, 3.169757971579321E-02], [1.643185373589321E+01, 1.110227970027843E+01, -1.716425425492940E-01], [ 2.917750633262754E+01, -6.646446374100315E+00, -5.355542983258703E-01 ], [ 1.269610583507422E+01, -3.141113199578617E+01, -3.112775015648088E-01 ] ]) ss_vel = np.array([ [ -8.492322341632166E-06, -9.353155515358904E-07, 2.301541419735291E-07 ], [ 2.048459325443986E-02, -8.995044409873299E-03, -2.614664569098718E-03 ], [ 1.189797004491595E-02, -1.634153795167905E-02, -9.110754924475504E-04 ], [ -2.170315646338148E-03, 1.703520105098581E-02, -5.463857304374388E-07 ], [-1.381007577874730E-02, 5.897333087115376E-03, 2.754466583425123E-03], [ -1.556986377304836E-03, -1.264431146517457E-02, -2.267130777538514E-04 ], [7.450947804402543E-03, 1.166544750377484E-04, -1.671012875749180E-04], [4.952121119936067E-03, 1.839073137038874E-03, -2.293132844397104E-04], [-2.230759206307085E-03, 3.075630739324861E-03, 4.027037883636828E-05], [6.759177587143499E-04, 3.079179855664010E-03, -7.882476544965271E-05], [2.988188173523851E-03, 5.096901737398172E-04, -9.289666940024388E-04] ]) ss_mass = np.array([ 1.988544e30, 3.302e23, 48.685e23, 6.045476731e24, 1.3e14, 6.4185e23, 1898.13e24, 5.68319e26, 86.8103e24, 102.41e24, 1.4639248e+22 ]) # These parameters are only approximately those of Jupiter and Saturn. #Add particles for x in [0, 1, 2, 3, 4, 5]: #,6,7,8]:#,9,10]: #for x in [0,6,7]: p = rebound.Particle(m=ss_mass[x] / ss_mass[0], x=ss_pos[x, 0], y=ss_pos[x, 1], z=ss_pos[x, 2], vx=ss_vel[x, 0] * Gfac, vy=ss_vel[x, 1] * Gfac, vz=ss_vel[x, 2] * Gfac) #p = rebound.Particle(m=ss_mass[x],x=ss_pos[x,0],y=ss_pos[x,1],z=ss_pos[x,2],vx=ss_vel[x,0],vy=ss_vel[x,1],vz=ss_vel[x,2]) sim.add(p) N = sim.N particles = sim.particles np.random.seed(run) for p in particles: p.m *= 1. + 1e-3 * np.random.rand() p.x *= 1. + 1e-3 * np.random.rand() p.y *= 1. + 1e-3 * np.random.rand() p.z *= 1. + 1e-3 * np.random.rand() p.vx *= 1. + 1e-3 * np.random.rand() p.vy *= 1. + 1e-3 * np.random.rand() p.vz *= 1. + 1e-3 * np.random.rand() def move_to_heliocentric(): particles[0].x = 0. particles[0].y = 0. particles[0].z = 0. particles[0].vx = 0. particles[0].vy = 0. particles[0].vz = 0. def energy(): com_vx = 0. com_vy = 0. com_vz = 0. if integrator == "mercury" or integrator[0:7] == "swifter": mtot = 0. for p in particles: com_vx += p.vx * p.m com_vy += p.vy * p.m com_vz += p.vz * p.m mtot += p.m com_vx /= mtot com_vy /= mtot com_vz /= mtot E_kin = 0. E_pot = 0. for i in xrange(N): #Kinetic energy per particle dvx = particles[i].vx - com_vx dvy = particles[i].vy - com_vy dvz = particles[i].vz - com_vz E_kin += 0.5 * particles[i].m * (dvx * dvx + dvy * dvy + dvz * dvz) for j in xrange(i + 1, N): #Potential energy felt between all particles dx = particles[i].x - particles[j].x dy = particles[i].y - particles[j].y dz = particles[i].z - particles[j].z r2 = dx * dx + dy * dy + dz * dz E_pot -= particles[i].m * particles[j].m / np.sqrt(r2) #E_pot -= sim.G*particles[i].m*particles[j].m/np.sqrt(r2) return E_kin + E_pot def momentum(): com_vx = 0. com_vy = 0. com_vz = 0. if integrator == "mercury" or integrator[0:7] == "swifter": mtot = 0. for p in particles: com_vx += p.vx * p.m com_vy += p.vy * p.m com_vz += p.vz * p.m mtot += p.m com_vx /= mtot com_vy /= mtot com_vz /= mtot lin_mom = np.array([0., 0., 0.]) ang_mom = np.array([0., 0., 0.]) for i in xrange(N): #Velocities of all particles dvx = particles[i].vx - com_vx dvy = particles[i].vy - com_vy dvz = particles[i].vz - com_vz #Linear momentum lin_mom_temp = particles[i].m * np.array([dvx, dvy, dvz]) lin_mom += lin_mom_temp #Angular momentum r_sun = np.array([particles[0].x, particles[0].y, particles[0].z]) ang_mom += np.cross(r_sun, lin_mom_temp) #E_kin += 0.5*particles[i].m*(dvx*dvx + dvy*dvy + dvz*dvz) #for j in xrange(i+1,N): #Potential energy felt between all particles # dx = particles[i].x-particles[j].x # dy = particles[i].y-particles[j].y # dz = particles[i].z-particles[j].z # r2 = dx*dx + dy*dy + dz*dz # E_pot -= particles[i].m*particles[j].m/np.sqrt(r2) #E_pot -= sim.G*particles[i].m*particles[j].m/np.sqrt(r2) return lin_mom, ang_mom times = np.logspace(np.log10(orbit), np.log10(tmax), Ngrid) if integrator == "mercury" or integrator[0:7] == "swifter": move_to_heliocentric() else: sim.move_to_com() ei = energy() lm_i, am_i = momentum() mag_lm_i = np.linalg.norm(lm_i) mag_am_i = np.linalg.norm(am_i) es = [] lms = [] ams = [] runtime = 0. start = time.time() # Capture warning messages (WHFast timestep too large) with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") for t in times: sim.integrate(t, exact_finish_time=0) ef = energy() lm, am = momentum() e = np.fabs((ei - ef) / ei) + 1.1e-16 l = np.linalg.norm(lm - lm_i) #/mag_lm_i a = np.linalg.norm(am - am_i) #/mag_am_i es.append(e) lms.append(l) ams.append(a) integrator, run, trial = par print( integrator.ljust(13) + " %9.5fs" % (time.time() - start) + "\t Energy error: %e" % (e) + "\t Linear momentum error: %e" % (l) + "\t Angular momentum error: %e" % (a)) es = np.array(es) lms = np.array(lms) ams = np.array(ams) return [times, es, lms, ams]
def test_calculate_orbits_errors2(self): self.sim.add(m=1) p1 = rebound.Particle(simulation=self.sim, a=1, m=0.1) self.sim.add(p1) with self.assertRaises(ValueError): self.sim.particles[1].calculate_orbit(primary=p1)
def test_div(self): p1 = rebound.Particle(m=1.2, x=1.4, vy=1.8) p2 = p1 / 2. self.assertAlmostEqual(p2.m, 0.6, delta=1e-15) self.assertAlmostEqual(p2.x, 0.7, delta=1e-15) self.assertAlmostEqual(p2.vy, 0.9, delta=1e-15)
def test_irmul(self): p1 = rebound.Particle(m=1.1, x=1.2, vy=1.3) p2 = p1 * 2. self.assertAlmostEqual(p2.m, 2.2, delta=1e-15) self.assertAlmostEqual(p2.x, 2.4, delta=1e-15) self.assertAlmostEqual(p2.vy, 2.6, delta=1e-15)