def example2(self): """ Lidov-Kozai problem of a planet around a star around a supermassive black hole. Includes perturbations from other stars in the form of vector resonant relaxation (VRR) """ code = SecularMultiple() ### initialize the code CONST_G = code.CONST_G ### extract physical constants from the code CONST_C = code.CONST_C CONST_R_SUN = code.CONST_R_SUN RJup = 0.1027922358015816 * CONST_R_SUN MJup = 0.0009546386983890755 day = 1.0 / 365.25 second = day / (24.0 * 3600.0) meter = 1.0 / 1.496e+11 ### Input parameters ### m1 = 1.0 m2 = MJup m3 = 4.0e6 a1 = 1.0e-1 a2 = 1.0e4 e1 = 0.01 e2 = 0.1 i1 = 4.5 * np.pi / 180.0 i2 = 19.9 * np.pi / 180.0 AP1 = np.pi AP2 = 0.38 * np.pi LAN1 = 0.01 LAN2 = np.pi R1 = 1.0 * CONST_R_SUN R2 = 1.0 * RJup R3 = CONST_G * m3 / (CONST_C**2) m_star = 1.0 gamma = 3.0 / 2.0 VRR_model = 3 ### Simulation parameters ### VRR_include_mass_precession = True include_inner_1PN_terms = True include_outer_1PN_terms = True ### Process parameters ### P1 = 2.0 * np.pi * np.sqrt(a1**3 / (CONST_G * (m1 + m2))) P2 = 2.0 * np.pi * np.sqrt(a2**3 / (CONST_G * (m1 + m2 + m3))) masses = [m1, m2, m3] radii = [R1, R2, R3] semimajor_axes = [a1, a2] eccentricities = [e1, e2] inclinations = [i1, i2] APs = [AP1, AP2] LANs = [LAN1, LAN2] N = len(masses) particles = Tools.create_nested_multiple(N, masses, semimajor_axes, eccentricities, inclinations, APs, LANs, radii=radii) orbits = [x for x in particles if x.is_binary == True] N_orbits = len(orbits) inner_orbit = orbits[0] outer_orbit = orbits[1] c1 = 4.8 c2 = -2.9 log10_sigma_h_km_s = (np.log10(m3) - c2) / c1 sigma_h_km_s = pow(10.0, log10_sigma_h_km_s) sigma_h = 1.0e3 * sigma_h_km_s * meter / second print('sigma_h_km_s', sigma_h_km_s, 'sigma_h', sigma_h) # K_12 = K_12_function(gamma) # K_32 = K_32_function(gamma) # C_NRR = ((3.0*numpy.pi)/(64.0))*1.0/( K_12 - (1.0/5.0)*K_32 + (5.0*numpy.pi/8.0)*(1.0/(2.0*gamma-1.0)) ) r_h = CONST_G * m3 * (1.0 / (sigma_h**2 * (1.0 + gamma))) * (1.0 + (1.0 + gamma) / (gamma - 1.0)) r_0 = r_h n_0 = (2.0 * m3 / m_star) * ((3.0 - gamma) / (4.0 * np.pi * r_h**3)) r = a2 rho_star = compute_rho_star_r(r, gamma, n_0, r_0, m_star) n_star = compute_n_star_r(r, gamma, n_0, r_0, m_star) M_star = compute_M_star_r(r, gamma, n_0, r_0, m_star) N_star = compute_N_star_r(r, gamma, n_0, r_0, m_star) sigma_r = compute_sigma_r(r, gamma, n_0, r_0, m_star, m3, CONST_G) print('n_star', n_star, 'M_star', M_star, 'N_star', N_star, 'sigma_r', sigma_r) LK_timescale = (P2**2 / P1) * ( (m1 + m2 + m3) / m3) * pow(1.0 - e2**2, 3.0 / 2.0) print('LK_timescale', LK_timescale) VRR_mass_precession_timescale = (1.0 / 2.0) * pow( 1.0 - e2**2, -1.0 / 2.0) * (m3 / M_star) * P2 VRR_mass_precession_rate = 1.0 / VRR_mass_precession_timescale VRR_timescale = (P2 / 2.0) * (m3 / m_star) * 1.0 / np.sqrt(N_star) #VRR_timescale *= 0.1 print('VRR_mass_precession_timescale', VRR_mass_precession_timescale, 'VRR_timescale', VRR_timescale) outer_orbit.VRR_include_mass_precession = VRR_include_mass_precession outer_orbit.VRR_mass_precession_rate = VRR_mass_precession_rate VRR_reorientation_timestep = np.sqrt(0.1) * VRR_timescale print('VRR_reorientation_timestep', VRR_reorientation_timestep) outer_orbit.VRR_model = VRR_model reorientation_function(VRR_model, VRR_timescale, VRR_reorientation_timestep, outer_orbit) v_bin = np.sqrt(CONST_G * (m1 + m2) / a1) q_sigma = (m1 + m2) / m_star log_Lambda = np.log(3.0 * ((1.0 + 1.0 / q_sigma) / (1.0 + 2.0 / q_sigma)) * sigma_r**2 / v_bin**2) evaporation_timescale = np.sqrt( (1.0 + q_sigma) / (2.0 * np.pi * q_sigma)) * (m1 + m2) * sigma_r / (8.0 * np.sqrt( np.pi) * CONST_G * a1 * m_star**2 * n_star * log_Lambda) print('evaporation_timescale', evaporation_timescale) inner_orbit.include_1PN_terms = include_inner_1PN_terms outer_orbit.include_1PN_terms = include_outer_1PN_terms code.add_particles(particles) primary = code.particles[0] code.enable_tides = False code.enable_root_finding = True code.enable_VRR = True a_AU_print = [[] for x in range(N_orbits)] e_print = [[] for x in range(N_orbits)] INCL_print = [[] for x in range(N_orbits)] rel_INCL_print = [[] for x in range(N_orbits)] t_print = [] t = 0.0 Nsteps = 1000 tend = evaporation_timescale dt_fixed = tend / float(Nsteps) t_next_reorientation = VRR_reorientation_timestep import time start = time.time() while t <= tend: dt = dt_fixed if t + dt > t_next_reorientation: dt = t_next_reorientation - t t_next_reorientation += VRR_reorientation_timestep reorientation_function(VRR_model, VRR_timescale, t_next_reorientation, outer_orbit) t += dt code.evolve_model(t) print('t', t, 'es', [o.e for o in orbits], 'Omegas', [o.LAN for o in orbits]) for i in range(N_orbits): rel_INCL_print[i].append(orbits[i].INCL_parent) a_AU_print[i].append(orbits[i].a) e_print[i].append(orbits[i].e) INCL_print[i].append(orbits[i].INCL) t_print.append(t) print('wall time', time.time() - start) t_print = np.array(t_print) for i in range(N_orbits): INCL_print[i] = np.array(INCL_print[i]) rel_INCL_print[i] = np.array(rel_INCL_print[i]) e_print[i] = np.array(e_print[i]) a_AU_print[i] = np.array(a_AU_print[i]) from matplotlib import pyplot fig = pyplot.figure(figsize=(8, 8)) plot1 = fig.add_subplot(2, 1, 1, yscale="log") plot2 = fig.add_subplot(2, 1, 2, yscale="linear") colors = ['k', 'r', 'g'] for i in range(N_orbits): color = colors[i] plot1.plot(1.0e-6 * t_print, a_AU_print[i], color=color) plot1.plot(1.0e-6 * t_print, a_AU_print[i] * (1.0 - e_print[i]), color=color) plot1.plot(1.0e-6 * t_print, a_AU_print[i] * (1.0 + e_print[i]), color=color) #plot2.plot(1.0e-6*t_print,INCL_print[i]*180.0/np.pi,color=color,linestyle='dotted') plot2.plot(1.0e-6 * t_print, rel_INCL_print[i] * 180.0 / np.pi, color=color) plot1.set_xlabel("$t/\mathrm{Myr}$") plot2.set_xlabel("$t/\mathrm{Myr}$") plot1.set_ylabel("$r_i/\mathrm{AU}$") plot2.set_ylabel("$\mathrm{incl}_\mathrm{rel}/\mathrm{deg}$") fig.savefig("example2.pdf") pyplot.show()
def run_simulation(tend,Nsteps,particles, \ VRR_reorientation_timestep,VRR_model,VRR_timescale,outer_orbit, \ enable_tides=False,enable_root_finding=True,enable_VRR=True): code = SecularMultiple() ### initialize the code code.add_particles(particles) primary = code.particles[0] code.enable_tides = enable_tides code.enable_root_finding = enable_root_finding code.enable_VRR = enable_VRR orbits = [x for x in particles if x.is_binary == True] N_orbits = len(orbits) a_AU_print = [[] for x in range(N_orbits)] e_print = [[] for x in range(N_orbits)] rp_AU_print = [[] for x in range(N_orbits)] INCL_print = [[] for x in range(N_orbits)] rel_INCL_print = [[] for x in range(N_orbits)] t_print = [] t = 0.0 dt_fixed = tend / float(Nsteps) t_next_reorientation = VRR_reorientation_timestep found_root = False import time start = time.time() while t <= tend: dt = dt_fixed if t + dt > t_next_reorientation: dt = t_next_reorientation - t t_next_reorientation += VRR_reorientation_timestep reorientation_function(VRR_model, VRR_timescale, t_next_reorientation, outer_orbit) t += dt code.evolve_model(t) #print 't',t,'es',[o.e for o in orbits],'Omegas',[o.LAN for o in orbits] if code.flag == 2: t = code.model_time print 'root found at t=', t found_root = True for i in range(N_orbits): rel_INCL_print[i].append(orbits[i].INCL_parent) a_AU_print[i].append(orbits[i].a) e_print[i].append(orbits[i].e) INCL_print[i].append(orbits[i].INCL) rp_AU_print[i].append(orbits[i].a * (1.0 - orbits[i].e)) t_print.append(t) if found_root == True: break print 'wall time', time.time() - start t_print = np.array(t_print) for i in range(N_orbits): INCL_print[i] = np.array(INCL_print[i]) rel_INCL_print[i] = np.array(rel_INCL_print[i]) e_print[i] = np.array(e_print[i]) a_AU_print[i] = np.array(a_AU_print[i]) rp_AU_print[i] = np.array(rp_AU_print[i]) code.reset() data = found_root, t_print, rel_INCL_print, e_print, a_AU_print, rp_AU_print return data