示例#1
0
    def setUp(self):
        self.sim = rebound.Simulation()
        self.rebx = reboundx.Extras(self.sim)
        data.add_earths(self.sim, ei=1.e-3)
        self.array = np.array([1., 2., 3., 4.])
        self.intarray = np.array([1, 2, 3, 4])
        self.cuintarray = np.array(
            [c_uint(1), c_uint(2), c_uint(3),
             c_uint(4)], dtype=object)
        self.cuint32array = np.array(
            [c_uint32(1), c_uint32(2),
             c_uint32(3), c_uint32(4)], dtype=object)
        self.ndarray = np.array([[[1., 2., 3.], [4., 5., 6.]],
                                 [[1., 2., 3.], [4., 5., 6.]],
                                 [[1., 2., 3.], [4., 5., 6.]],
                                 [[1., 2., 3.], [4., 5., 6.]]])
        self.orbitarray = np.array(self.sim.calculate_orbits(), dtype=object)
        o1 = self.sim.particles[1].orbit
        o2 = self.sim.particles[2].orbit
        self.objndarray = np.array(
            [[[o1, o2], [o2, o1], [o1, o1]], [[o1, o2], [o2, o1], [o1, o1]],
             [[o1, o2], [o2, o1], [o1, o1]], [[o1, o2], [o2, o1], [o1, o1]]],
            dtype=object)

        self.sim.particles[0].params["array"] = self.array
        self.sim.particles[0].params["intarray"] = self.intarray
        self.sim.particles[0].params["cuintarray"] = self.cuintarray
        self.sim.particles[0].params["cuint32array"] = self.cuint32array
        self.sim.particles[1].params["ndarray"] = self.ndarray
        self.sim.particles[0].params["orbitarray"] = self.orbitarray
        self.sim.particles[1].params["objndarray"] = self.objndarray
        self.sim.particles[1].params["scalar"] = 3
示例#2
0
    def test_modify_mass(self):
        name = 'modify_mass'
        try:
            rebbin = os.path.join(THIS_DIR, 'binaries/' + name + '.sa')
            rebxbin = os.path.join(THIS_DIR, 'binaries/' + name + '.rebx')
            sa = reboundx.SimulationArchive(rebbin, rebxbin)
        except:
            sim = rebound.Simulation('binaries/twoplanets.bin')
            sim.automateSimulationArchive('binaries/' + name + '.sa',
                                          interval=1e3,
                                          deletefile=True)
            rebx = reboundx.Extras(sim)
            mod = rebx.load_operator(name)
            rebx.add_operator(mod)
            ps = sim.particles
            ps[0].params['tau_mass'] = -1e4
            rebx.save('binaries/' + name + '.rebx')
            sim.integrate(1.e4)
            sa = reboundx.SimulationArchive('binaries/' + name + '.sa',
                                            'binaries/' + name + '.rebx')

        simf, rebx = sa[-1]
        sim, rebx = sa[0]
        sim.integrate(simf.t)
        self.assertEqual(sim.particles[0].x, simf.particles[0].x)
示例#3
0
def run_constant_damping(sim,
                         res,
                         times,
                         tau_e=1e2,
                         tau_a=1e3,
                         chaos=False,
                         stopping_criterion=mmr_stop,
                         direct=False):
    tau_a = res.tau_a
    tau_e = res.tau_e
    res.direct = res.direct

    rebx = rbx.Extras(sim)
    if direct:
        params = rebx.add_modify_orbits_direct()
    else:
        params = rebx.add_modify_orbits_forces()
    sim.particles[3].tau_a = -tau_a
    sim.particles[3].tau_e = -tau_e

    res = run_sim(sim,
                  res,
                  times,
                  chaos=chaos,
                  stopping_criterion=stopping_criterion)

    return res
示例#4
0
    def test_backwards_time(self):
        sim = rebound.Simulation(binary)
        sim.integrator = "ias15"
        rebx = reboundx.Extras(sim)
        times = [0, 2000., 4000., 6000., 8000., 10000.]
        values = [1., 0.8, 0.6, 0.4, 0.3, 0.2]
        starmass = reboundx.Interpolator(rebx, times, values, "spline")

        Nout = 1000
        ts = np.linspace(0., 1.e4, Nout)
        ps = sim.particles
        a10 = ps[1].a
        m0 = ps[0].m

        for i, time in enumerate(ts):
            sim.integrate(time)
            ps[0].m = starmass.interpolate(rebx, t=sim.t)
            sim.move_to_com(
            )  # lost mass had momentum, so need to move back to COM frame
        sim.dt = -0.001
        for i, time in enumerate(times[::-1]):
            sim.integrate(time)
            ps[0].m = starmass.interpolate(rebx, t=sim.t)
            sim.move_to_com(
            )  # lost mass had momentum, so need to move back to COM frame
        self.assertLess(abs((ps[0].m - m0) / m0), 1.e-2)
        self.assertLess(abs((ps[1].a - a10) / a10), 1.e-2)
示例#5
0
    def test_gr(self):
        name = 'gr'
        try:
            rebbin = os.path.join(THIS_DIR, 'binaries/' + name + '.sa')
            rebxbin = os.path.join(THIS_DIR, 'binaries/' + name + '.rebx')
            sa = reboundx.SimulationArchive(rebbin, rebxbin)
        except:
            sim = rebound.Simulation('binaries/twoplanets.bin')
            sim.automateSimulationArchive('binaries/' + name + '.sa',
                                          interval=1e3,
                                          deletefile=True)
            rebx = reboundx.Extras(sim)
            force = rebx.load_force(name)
            rebx.add_force(force)
            force.params['c'] = 1.e4
            ps = sim.particles
            rebx.save('binaries/' + name + '.rebx')
            sim.integrate(1.e4)
            sa = reboundx.SimulationArchive('binaries/' + name + '.sa',
                                            'binaries/' + name + '.rebx')

        simf, rebx = sa[-1]
        sim, rebx = sa[0]
        sim.integrate(simf.t)
        self.assertEqual(sim.particles[0].x, simf.particles[0].x)
示例#6
0
 def setUp(self):
     self.sim = rebound.Simulation()
     self.rebx = reboundx.Extras(self.sim)
     data.add_earths(self.sim, ei=1.e-3)
     self.sim.particles[0].params["a"] = 1.2
     self.sim.particles[0].params["b"] = 1.7
     self.sim.particles[0].params["N"] = 14
示例#7
0
 def setUp(self):
     self.sim = rebound.Simulation()
     data.add_earths(self.sim, ei=1.e-3)
     self.rebx = reboundx.Extras(self.sim)
     self.gr = self.rebx.add("gr")
     self.gr.params["a"] = 1.2
     self.gr.params["b"] = 1.7
     self.gr.params["N"] = 14
示例#8
0
 def setUp(self):
     self.sim = rebound.Simulation()
     self.sim.add(m=1., r=0.005)
     self.sim.add(m=1.e-3, a=0.05, e=0.1, r=0.0005)
     self.sim.move_to_com()
     self.rebx = reboundx.Extras(self.sim)
     self.force = self.rebx.load_force("tides_constant_time_lag")
     self.rebx.add_force(self.force)
示例#9
0
 def setUp(self):
     self.sim = rebound.Simulation()
     self.sim.add(m=1.)
     self.sim.add(a=1.)
     self.rebx = reboundx.Extras(self.sim)
     self.gr = self.rebx.load_force("gr")
     self.mm = self.rebx.load_operator("modify_mass")
     self.p = self.sim.particles[1]
示例#10
0
def addGR(sim, rebxintegrator, order, cfac):
    rebx = reboundx.Extras(sim)
    gr = rebx.add("gr")
    gr.params["c"] = 63197.8 * cfac  # AU/yr
    if rebxintegrator != "naive":
        rebx.integrator = rebxintegrator
        gr.operator_order = order
        gr.force_as_operator = 1
    return rebx
示例#11
0
def makesim(init_a):
    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')
    sim.add(m=M0)
    sim.add(m=3e-6, a=init_a)  # 1 Mearth
    sim.collision = "direct"
    rebx = reboundx.Extras(sim)
    # tides = rebx.load_force("tides_constant_time_lag")
    # rebx.add_force(tides)
    return sim, rebx  #, tides
示例#12
0
def makesim():
    sim = rebound.Simulation()
    sim.units = ('yr', 'AU', 'Msun')
    sim.add(m=M0)
    sim.add(m=1e-3, a=5)
    sim.collision = "direct"
    rebx = reboundx.Extras(sim)
    tides = rebx.load_force("tides_constant_time_lag")
    rebx.add_force(tides)
    return sim, rebx, tides
示例#13
0
 def setUp(self):
     self.sim = rebound.Simulation()
     self.sim.add(m=1.)
     self.sim.add(m=1.e-4, a=1., e=0.2)
     self.sim.move_to_com()
     self.sim.dt = 1.e-2 * self.sim.particles[1].P
     self.rebx = reboundx.Extras(self.sim)
     self.gr = self.rebx.load_force('gr')
     self.gr.params['c'] = 1e2
     self.pomega0 = self.sim.particles[1].pomega
     self.E0 = self.rebx.gr_hamiltonian(self.gr)
示例#14
0
 def test_conservation_planet_highmratio(self):
     self.sim = rebound.Simulation()
     self.sim.add(m=1., r=0.005)
     self.sim.add(m=1., a=0.2, e=0.1, r=0.005)
     self.sim.move_to_com()
     self.rebx = reboundx.Extras(self.sim)
     self.force = self.rebx.load_force("tides_constant_time_lag")
     self.rebx.add_force(self.force)
     ps = self.sim.particles
     ps[1].params['tctl_k1'] = 0.04
     self.do_test_conservation()
 def test_gr(self):
     name = 'gr'
     sim = rebound.Simulation(binary)
     sim.integrator = "ias15"
     rebx = reboundx.Extras(sim)
     force = rebx.load_force(name)
     rebx.add_force(force)
     force.params['c'] = 1.e4
     ps = sim.particles
     H0 = rebx.gr_hamiltonian(force)
     sim.integrate(1.e4)
     H = rebx.gr_hamiltonian(force)
     self.assertLess(abs((H - H0) / H0), 1.e-12)
 def test_gr_potential(self):
     name = 'gr_potential'
     sim = rebound.Simulation(binary)
     sim.integrator = "ias15"
     rebx = reboundx.Extras(sim)
     force = rebx.load_force(name)
     rebx.add_force(force)
     force.params['c'] = 1.e4
     ps = sim.particles
     H0 = sim.calculate_energy() + rebx.gr_potential_potential(force)
     sim.integrate(1.e4)
     H = sim.calculate_energy() + rebx.gr_potential_potential(force)
     self.assertLess(abs((H - H0) / H0), 1.e-12)
示例#17
0
    def setUp(self):
        self.sim = rebound.Simulation()
        self.sim.add(m=1.)
        self.sim.add(a=1., e=0.2)
        self.rebx = reboundx.Extras(self.sim)
        self.cust = self.rebx.create_operator('addop')
        self.rebx.register_param('ctr', 'REBX_TYPE_INT')
        self.cust.params['ctr'] = 0

        def mystep(sim, operator, dt):
            operator.contents.params['ctr'] += 1

        self.cust.step_function = mystep
 def test_tides_precession(self):
     name = 'tides_precession'
     sim = rebound.Simulation(binary)
     sim.integrator = "ias15"
     rebx = reboundx.Extras(sim)
     force = rebx.load_force(name)
     rebx.add_force(force)
     ps = sim.particles
     ps[0].params['R_tides'] = 1.e-3
     ps[0].params['k1'] = 0.4
     H0 = sim.calculate_energy() + rebx.tides_precession_potential(force)
     sim.integrate(1.e4)
     H = sim.calculate_energy() + rebx.tides_precession_potential(force)
     self.assertLess(abs((H - H0) / H0), 1.e-12)
 def test_central_force(self):
     name = 'central_force'
     sim = rebound.Simulation(binary)
     sim.integrator = "ias15"
     rebx = reboundx.Extras(sim)
     force = rebx.load_force(name)
     rebx.add_force(force)
     ps = sim.particles
     ps[0].params['Acentral'] = 1.e-4
     ps[0].params['gammacentral'] = -1
     H0 = sim.calculate_energy() + rebx.central_force_potential()
     sim.integrate(1.e4)
     H = sim.calculate_energy() + rebx.central_force_potential()
     self.assertLess(abs((H - H0) / H0), 1.e-12)
 def test_gravitational_harmonics(self):
     name = 'gravitational_harmonics'
     sim = rebound.Simulation(binary)
     sim.integrator = "ias15"
     rebx = reboundx.Extras(sim)
     force = rebx.load_force(name)
     rebx.add_force(force)
     ps = sim.particles
     ps[0].params['J2'] = 1.e-3
     ps[0].params['J4'] = 1.e-3
     ps[0].params['R_eq'] = 1.e-3
     H0 = sim.calculate_energy() + rebx.gravitational_harmonics_potential()
     sim.integrate(1.e4)
     H = sim.calculate_energy() + rebx.gravitational_harmonics_potential()
     self.assertLess(abs((H - H0) / H0), 1.e-12)
示例#21
0
 def add_force(self):
     """Add tau damping force"""
     if self.verbose:
         print('adding modify_orbits_forces_edge')
     self.rebx = reboundx.Extras(self.sim)
     mof = self.rebx.load_force('modify_orbits_forces_edge')
     mof.params['res_redge'] = self.params['redge']
     mof.params['res_deltaredge'] = self.params['deltaredge']
     mof.params['res_tdep'] = self.params['tdep']
     mof.params['res_deltatdep'] = self.params['deltatdep']
     self.rebx.add_force(mof)
     self.mof = mof
     for pt in self.sim.particles[1:]:
         pt.params['tau_a'] = self.params['tau_a']
         pt.params['tau_e'] = self.params['tau_e']
         pt.params['tau_inc'] = self.params['tau_inc']
示例#22
0
 def add_force(self):
     """Add reboundx forces. This is a method so it can be overloaded easily"""
     if self.verbose:
         print(' adding modify_orbits_resonance_relax')
     self.rebx = reboundx.Extras(self.sim)
     mof = self.rebx.load_force('modify_orbits_resonance_relax')
     mof.params['res_aspectratio0'] = self.params['aspectratio0']
     mof.params['res_sigma0'] = self.params['sigma0']
     mof.params['res_redge'] = self.params['redge']
     mof.params['res_deltaredge'] = self.params['deltaredge']
     mof.params['res_alpha'] = self.params['alpha']
     mof.params['res_flaringindex'] = self.params['flaringindex']
     mof.params['res_ffudge'] = self.params['ffudge']
     mof.params['res_tdep'] = self.params['tdep']
     mof.params['res_deltatdep'] = self.params['deltatdep']
     self.rebx.add_force(mof)
     self.mof = mof
示例#23
0
    def setUp(self):
        self.sim = rebound.Simulation()
        self.sim.add(m=0.86, r = 0.78)   
        self.sim.add(m=3.e-6, a=1., e=0.05)
        self.sim.move_to_com()
        ps = self.sim.particles

        self.rebx = reboundx.Extras(self.sim)
        self.tides = self.rebx.load_force("tides_constant_time_lag")
        self.rebx.add_force(self.tides)
        ps[0].params["tctl_k1"] = 0.023 # in AU
        ps[0].params["tctl_tau"] = 0.3
        ps[0].params["Omega"] = 0.

        self.q = (ps[1].m/ps[0].m)
        self.T = ps[0].r**3/self.sim.G/ps[0].m/ps[0].params["tctl_tau"]
        self.taua = self.T/6/ps[0].params["tctl_k1"]/self.q/(1+self.q)*(ps[1].a/ps[0].r)**8
示例#24
0
    def test_klo(self):
        sim = rebound.Simulation(binary)
        sim.integrator = "ias15"
        rebx = reboundx.Extras(sim)
        times = [0, 2000., 4000., 6000., 8000., 10000.]
        values = [1., 0.8, 0.6, 0.4, 0.3, 0.2]
        starmass = reboundx.Interpolator(rebx, times, values, "spline")

        m0 = sim.particles[0].m
        mint0 = starmass.interpolate(rebx, t=0)

        self.assertLess(abs((m0 - mint0) / m0), 1.e-6)

        mint1 = starmass.interpolate(rebx, t=5000)  # advance klo
        mint1 = starmass.interpolate(rebx, t=0)  # advance klo

        self.assertLess(abs((m0 - mint1) / m0), 1.e-6)
示例#25
0
    def test_reproducibility(self):
        sim = rebound.Simulation()
        sim.add(m=1.)
        sim.add(m=1e-3, a=1.)
        rebx = reboundx.Extras(sim)
        gr = rebx.add("gr")
        gr.params['c'] = 1.e3
        sim.automateSimulationArchive("test.bin",
                                      interval=1e3,
                                      deletefile=True)
        sim.integrate(1.e4)
        rebx.save("rebx.bin")
        sa = rebound.SimulationArchive("test.bin", rebxfilename="rebx.bin")

        for i in [2, 5, 7]:
            sim = sa[i]
            x = sim.particles[1].x
            sim = sa[i - 1]
            sim.integrate(sa[i].t, exact_finish_time=0)
            self.assertEqual(x, sim.particles[1].x)
示例#26
0
    def test_modify_orbits_forces(self):
        name = "modify_orbits_forces"
        try:
            rebbin = os.path.join(THIS_DIR, 'binaries/' + name + '.sa')
            rebxbin = os.path.join(THIS_DIR, 'binaries/' + name + '.rebx')
            sa = reboundx.SimulationArchive(rebbin, rebxbin)
        except:
            try:
                sim = rebound.Simulation('binaries/twoplanets.bin')
            except:
                sim = rebound.Simulation()
                sim.add(m=1.)
                sim.add(m=1.e-4, a=1., e=0.1)
                sim.add(m=1.e-4, a=2, e=0.1, inc=0.2)
                sim.integrator = "whfast"
                sim.dt = sim.particles[1].P / 100
                sim.move_to_com()
                sim.save('binaries/twoplanets.bin')

            sim.automateSimulationArchive('binaries/modify_orbits_forces.sa',
                                          interval=1e3,
                                          deletefile=True)
            rebx = reboundx.Extras(sim)
            mod = rebx.load_force('binaries/modify_orbits_forces')
            rebx.add_force(mod)
            ps = sim.particles
            ps[1].params['tau_a'] = -1e4
            ps[1].params['tau_e'] = -1e3
            ps[2].params['tau_e'] = -1e3
            ps[2].params['tau_inc'] = -1e3
            rebx.save('binaries/modify_orbits_forces.rebx')
            sim.integrate(1.e4)
            sa = reboundx.SimulationArchive(
                'binaries/modify_orbits_forces.sa',
                'binaries/modify_orbits_forces.rebx')

        simf, rebx = sa[-1]
        sim, rebx = sa[0]
        sim.integrate(simf.t)
        self.assertEqual(sim.particles[0].x, simf.particles[0].x)
		if keep_going == 'n':
			raise Exception("A keyboard interruption occurred.")
			break

		unstable = 'n' #### initialize assuming stability, until shown otherwise.

		try:
			running_period_list = np.load(projectdir+'/running_list_of_derived_TTV_periods.npy').tolist()
		except:
			running_period_list = []		

		### create a simulations instance.
		sim = rebound.Simulation()
		if include_J2 == 'y':
			rebx = reboundx.Extras(sim)
			gh = rebx.load_force('gravitational_harmonics')
			rebx.add_force(gh)
		stability_model = FeatureClassifier()

		### put these in familiar units
		sim.G = G.value
		sim.units = ('s', 'm', 'kg') ### mks 


		#### now let's add Jupiter, Io, Europa, Ganymede, and Callisto!

		### Jupiter

		if make_imaginary_system == 'n':
			### MAKE JUPITER!
    def dyvars_to_rebound_simulation(self,z,Q=0,pomega1=0,osculating_correction = True,include_dissipation = False,**kwargs):
        r"""
        Convert dynamical variables
        .. math:
            z = (\sigma_1,\sigma_2,I_1,I_2,{\cal C}
        to a Rebound simulation.

        Arguments
        ---------
        z : ndarray
            Dynamical variables
        pomega1 : float, optional
            Planet 1's longitude of periapse. 
            Default is 0
        Q : float, optional
            Angle variable Q = (lambda2-lambda1) / k. 
            Default is Q=0. Resonant periodic orbits
            are 2pi-periodic in Q.
        include_dissipation : bool, optional
            Include dissipative effects through 
            reboundx's external forces.
            Default is False

        Keyword Arguments
        -----------------
        Mstar : float
            Default=1.0
            Stellar mass.
        inc : float, default = 0.0
            Inclination of planets' orbits.
        period1 : float
            Default = 1.0
            Orbital period of inner planet
        units : tuple
            Default = ('AU','Msun','days')
            Units of rebound simulation.

        Returns
        -------
        tuple :
            Returns a tuple. The first item
            of the tuple is a rebound simulation. 
            The second item is a reboundx.Extras object
            if 'include_dissipation' is True, otherwise
            the second item is None.
        """
        mean_orbels = self.dyvars_to_orbels(z)
        a1_mean,_,_,a2_mean,_,_ = mean_orbels 
        if osculating_correction:
            zosc = self.mean_to_osculating_dyvars(Q,z)
            orbels = self.dyvars_to_orbels(zosc)
        else:
            orbels = mean_orbels
        j,k = self.j, self.k
        a1,e1,theta1,a2,e2,theta2 = orbels
        syn_angle = self.k * Q
        pomega2 = np.mod( pomega1 -  (theta2 - theta1) / k, 2*np.pi)
        M1 = np.mod( (theta1 - j*syn_angle) / k ,2*np.pi )
        l1 = np.mod(M1 + pomega1,2*np.pi)
        l2 = np.mod( syn_angle + l1,2*np.pi)
        
        Mstar = kwargs.pop('Mstar',1.0)
        inc = kwargs.pop('inc',0.0)
        period1 = kwargs.pop('period1',1.0)
        units  = kwargs.pop('units', ('AU','Msun','days'))

        sim = rb.Simulation()
        sim.units = units
        mpl1 = self.m1 * Mstar
        mpl2 = self.m2 * Mstar
        # Rescale distance scale so that the proper semi-major axis of planet 1 corresponds to orbital period 'period1'
        a1_physical = (a1 / a1_mean) * (sim.G * (Mstar + mpl1) * period1**2 / (4*np.pi*np.pi))**(1/3)
        a2_physical = a2 * a1_physical / a1
        sim.add(m=Mstar)
        sim.add(m = mpl1, a=a1_physical, e=e1, l=l1, pomega=pomega1, inc=inc, jacobi_masses=True)
        sim.add(m = mpl2, a=a2_physical, e=e2, l=l2, pomega=pomega2, inc=inc, jacobi_masses=True)
        sim.move_to_com()

        rebx = None
        if include_dissipation:
            ps = sim.particles
            n2 = ps[2].n
            rebx = reboundx.Extras(sim)
            mod = rebx.load_operator("modify_orbits_direct")
            rebx.add_operator(mod)
            mod.params["p"] = self.p
            timescales = self.timescales
            ps[1].params["tau_a"]=-1*timescales['tau_a1'] / n2
            ps[2].params["tau_a"]=-1*timescales['tau_a2'] / n2
            ps[1].params["tau_e"]=-1*timescales['tau_e1'] / n2
            ps[2].params["tau_e"]=-1*timescales['tau_e2'] / n2
        return sim,rebx
示例#29
0
    def integrate_orbit(self,
                        t_val,
                        M0,
                        R0,
                        a,
                        e,
                        inc,
                        Omega,
                        omega,
                        tp,
                        x0=0,
                        y0=0,
                        vx0=0,
                        vy0=0,
                        vz0=0,
                        **effect_kwargs):
        # account for factor of R0 in l_unit
        gravitational_constant = gravitational_constant_times_R03 / R0**3
        speed_of_light = speed_of_light_times_R0 / R0
        velocity_conversion_factor = velocity_conversion_factor_per_R0 * R0

        t_val = np.sort(t_val)

        sim = rebound.Simulation()
        rebx = reboundx.Extras(sim)

        sim.integrator = "ias15"
        sim.G = gravitational_constant
        sim.t = t_val[0]

        # enable post-Newtonian corrections
        gr = rebx.load_force("gr")
        rebx.add_force(gr)
        gr.params["c"] = speed_of_light

        # add black hole particle
        sim.add(hash="black_hole", m=M0)  # placed at the origin
        bh = sim.particles["black_hole"]
        bh.params["gr_source"] = 1

        # add star "test" particle
        sim.add(hash="test_particle",
                m=0,
                a=a,
                e=e,
                inc=inc,
                Omega=Omega,
                omega=omega,
                T=tp)
        p = sim.particles["test_particle"]

        if "Mp" and "rp" in effect_kwargs:
            # account for an extended mass distribution (Plummer profile)
            mass_effect = rebx.add_custom_force(
                central_force, force_is_velocity_dependent=False)
            mass_effect.params["Mp"] = effect_kwargs["Mp"]
            mass_effect.params["rp"] = effect_kwargs["rp"]

        data = pd.DataFrame(index=t_val, columns=["t'", "x", "y", "vz"])

        for step, t_obs in enumerate(t_val):
            sim.integrate(t_obs, exact_finish_time=1)  # time of observation

            # account for the light propagation delay (Roemer effect)
            t = t_obs - (p.z / speed_of_light * (1 - p.vz / speed_of_light))
            sim.integrate(t, exact_finish_time=1)  # time of emission

            # convert to the coordinate system of the observations
            x_obs = -p.y
            y_obs = p.x

            # account for a possible drift of the astrometric reference frame
            x_obs += x0 + vx0 * (t - reference_time)
            y_obs += y0 + vy0 * (t - reference_time)

            # account for the relativistic Doppler effect
            beta_costheta = p.vz / speed_of_light
            beta2 = (p.vx**2 + p.vy**2 + p.vz**2) / speed_of_light**2
            zD = (1 + beta_costheta) / np.sqrt(1 - beta2) - 1

            # account for the gravitational redshift
            rs = 2 * sim.G * bh.m / speed_of_light**2
            zG = 1 / np.sqrt(1 - rs / np.sqrt(p.x**2 + p.y**2 + p.z**2)) - 1

            # calculate the measured radial velocity
            vz_obs = (zD + zG) * speed_of_light

            # convert to observed units
            vz_obs *= velocity_conversion_factor

            # account for a possible radial velocity offset
            vz_obs += vz0

            data.loc[t_obs] = {"t'": t, "x": x_obs, "y": y_obs, "vz": vz_obs}

        return data
示例#30
0
    def perform(self, node, inputs, outputs):
        # NOTE: Units should be AU, M_sun, year/2pi
        import rebound

        masses, initial_coords, times = inputs
        masses = np.atleast_1d(masses)
        initial_coords = np.atleast_2d(initial_coords)
        times = np.atleast_1d(times)

        if len(np.shape(masses)) != 1:
            raise ValueError("the array of masses must be 1D")
        num_bodies = len(masses)

        if np.shape(initial_coords) != (num_bodies, 6):
            raise ValueError(
                "the initial coordinates must have shape {0}".format(
                    (num_bodies, 6)))

        if len(np.shape(times)) != 1:
            raise ValueError("the array of times must be 1D")
        num_times = len(times)
        time_inds = np.argsort(times)
        sorted_times = times[time_inds]

        # Set up the simulation
        sim = rebound.Simulation()
        gr_sources = []
        for k, v in self.rebound_args.items():
            if "gr" in k and "force" not in k:
                gr_sources += [v]
                continue
            setattr(sim, k, v)

        if "gr_force" in self.rebound_args.keys():
            force = self.rebound_args["gr_force"]
        else:
            force = "gr"  # default to the gr force

        for i in range(num_bodies):
            sim.add(
                m=masses[i],
                x=initial_coords[i, 0],
                y=initial_coords[i, 1],
                z=initial_coords[i, 2],
                vx=initial_coords[i, 3],
                vy=initial_coords[i, 4],
                vz=initial_coords[i, 5],
            )

        ps = sim.particles

        if len(gr_sources) != 0:  # if gr_sources have been added
            try:
                import reboundx
                from reboundx import constants
            except ImportError:
                raise ImportError("""Please install REBOUNDx to include
                                relativistic effects.""")
            rebx = reboundx.Extras(sim)
            gr = rebx.load_force(force)
            gr.params["c"] = constants.C
            for i, particle in enumerate(ps):
                particle.params["gr_source"] = gr_sources[i]
            rebx.add_force(gr)
        # Add the variational particles to track the derivatives
        var_systems = np.empty((num_bodies, 7), dtype=object)
        for i in range(num_bodies):
            for j, coord in enumerate("m x y z vx vy vz".split()):
                var = sim.add_variation()
                setattr(var.particles[i], coord, 1.0)
                var_systems[i, j] = var

        # Integrate the system
        coords = np.empty((num_times, num_bodies, 6))
        jac = np.empty((num_times, num_bodies, 6, num_bodies, 7))
        for ind in range(num_times):
            sim.integrate(sorted_times[ind])

            # Save the coordinates at this time
            for i in range(num_bodies):
                for j, coord in enumerate("x y z vx vy vz".split()):
                    coords[ind, i, j] = getattr(sim.particles[i], coord)

            # Save the jacobian at this time
            for i in range(num_bodies):
                for j, coord in enumerate("x y z vx vy vz".split()):
                    for k in range(num_bodies):
                        for l in range(7):
                            jac[ind, i, j, k,
                                l] = getattr(var_systems[k, l].particles[i],
                                             coord)

        # Save the results
        outputs[0][0] = np.ascontiguousarray(coords[time_inds])
        outputs[1][0] = np.ascontiguousarray(jac[time_inds])