Example #1
0
def test_atmospheric_demise():
    # Test an orbital decay that hits Earth. No analytic solution.
    R = Earth.R.to(u.km).value

    orbit = Orbit.circular(Earth, 230 * u.km)
    t_decay = 48.2179 * u.d  # not an analytic value

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A_over_m = ((np.pi / 4.0) * (u.m**2) / (100 * u.kg)).to_value(
        u.km**2 / u.kg)  # km^2/kg

    # parameters of the atmosphere
    rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
    H0 = H0_earth.to(u.km).value  # km

    tofs = [365] * u.d  # actually hits the ground a bit after day 48

    lithobrake_event = LithobrakeEvent(R)
    events = [lithobrake_event]

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        tofs,
        ad=atmospheric_drag_exponential,
        R=R,
        C_D=C_D,
        A_over_m=A_over_m,
        H0=H0,
        rho0=rho0,
        events=events,
    )

    assert_quantity_allclose(norm(rr[0].to(u.km).value), R,
                             atol=1)  # below 1km

    assert_quantity_allclose(lithobrake_event.last_t, t_decay, rtol=1e-2)

    # make sure having the event not firing is ok
    tofs = [1] * u.d
    lithobrake_event = LithobrakeEvent(R)
    events = [lithobrake_event]

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        tofs,
        ad=atmospheric_drag_exponential,
        R=R,
        C_D=C_D,
        A_over_m=A_over_m,
        H0=H0,
        rho0=rho0,
        events=events,
    )

    assert lithobrake_event.last_t == tofs[-1]
def test_atmospheric_drag_exponential():
    # http://farside.ph.utexas.edu/teaching/celestial/Celestialhtml/node94.html#sair (10.148)
    # Given the expression for \dot{r} / r, aproximate \Delta r \approx F_r * \Delta t

    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value

    # Parameters of a circular orbit with h = 250 km (any value would do, but not too small)
    orbit = Orbit.circular(Earth, 250 * u.km)
    r0, _ = orbit.rv()
    r0 = r0.to(u.km).value

    # Parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A_over_m = ((np.pi / 4.0) * (u.m**2) / (100 * u.kg)).to_value(
        u.km**2 / u.kg)  # km^2/kg
    B = C_D * A_over_m

    # Parameters of the atmosphere
    rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
    H0 = H0_earth.to(u.km).value  # km
    tof = 100000  # s

    dr_expected = -B * rho0 * np.exp(-(norm(r0) - R) / H0) * np.sqrt(
        k * norm(r0)) * tof

    # Assuming the atmospheric decay during tof is small,
    # dr_expected = F_r * tof (Newton's integration formula), where
    # F_r = -B rho(r) |r|^2 sqrt(k / |r|^3) = -B rho(r) sqrt(k |r|)

    def f(t0, u_, k):
        du_kep = func_twobody(t0, u_, k)
        ax, ay, az = atmospheric_drag_exponential(t0,
                                                  u_,
                                                  k,
                                                  R=R,
                                                  C_D=C_D,
                                                  A_over_m=A_over_m,
                                                  H0=H0,
                                                  rho0=rho0)
        du_ad = np.array([0, 0, 0, ax, ay, az])
        return du_kep + du_ad

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        [tof] * u.s,
        f=f,
    )

    assert_quantity_allclose(norm(rr[0].to(u.km).value) - norm(r0),
                             dr_expected,
                             rtol=1e-2)
Example #3
0
def test_atmospheric_drag():
    # http://farside.ph.utexas.edu/teaching/celestial/Celestialhtml/node94.html#sair (10.148)
    # given the expression for \dot{r} / r, aproximate \Delta r \approx F_r * \Delta t

    R = Earth.R.to(u.km).value
    k = Earth.k.to(u.km**3 / u.s**2).value

    # parameters of a circular orbit with h = 250 km (any value would do, but not too small)
    orbit = Orbit.circular(Earth, 250 * u.km)
    r0, _ = orbit.rv()
    r0 = r0.to(u.km).value

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg
    B = C_D * A / m

    # parameters of the atmosphere
    rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
    H0 = H0_earth.to(u.km).value  # km
    tof = 100000  # s

    dr_expected = -B * rho0 * np.exp(-(norm(r0) - R) / H0) * np.sqrt(
        k * norm(r0)) * tof
    # assuming the atmospheric decay during tof is small,
    # dr_expected = F_r * tof (Newton's integration formula), where
    # F_r = -B rho(r) |r|^2 sqrt(k / |r|^3) = -B rho(r) sqrt(k |r|)

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        [tof] * u.s,
        ad=atmospheric_drag,
        R=R,
        C_D=C_D,
        A=A,
        m=m,
        H0=H0,
        rho0=rho0,
    )

    assert_quantity_allclose(norm(rr[0].to(u.km).value) - norm(r0),
                             dr_expected,
                             rtol=1e-2)
Example #4
0
def test_altitude_crossing():
    # Test decreasing altitude cross over Earth. No analytic solution.
    R = Earth.R.to(u.km).value

    orbit = Orbit.circular(Earth, 230 * u.km)
    t_flight = 48.209538 * u.d

    # Parameters of a body
    C_D = 2.2  # Dimensionless (any value would do)
    A_over_m = ((np.pi / 4.0) * (u.m**2) / (100 * u.kg)).to_value(
        u.km**2 / u.kg)  # km^2/kg

    # Parameters of the atmosphere
    rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
    H0 = H0_earth.to(u.km).value  # km

    tofs = [50] * u.d

    thresh_alt = 50  # km
    altitude_cross_event = AltitudeCrossEvent(thresh_alt, R)
    events = [altitude_cross_event]

    def f(t0, u_, k):
        du_kep = func_twobody(t0, u_, k)
        ax, ay, az = atmospheric_drag_exponential(t0,
                                                  u_,
                                                  k,
                                                  R=R,
                                                  C_D=C_D,
                                                  A_over_m=A_over_m,
                                                  H0=H0,
                                                  rho0=rho0)
        du_ad = np.array([0, 0, 0, ax, ay, az])
        return du_kep + du_ad

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        tofs,
        events=events,
        f=f,
    )

    assert_quantity_allclose(norm(rr[0].to(u.km).value) - thresh_alt, R)
    assert_quantity_allclose(altitude_cross_event.last_t, t_flight, rtol=1e-2)
    def setup(self):
        from poliastro.twobody import Orbit

        self.R = Earth.R.to(u.km).value
        self.k = Earth.k.to(u.km**3 / u.s**2).value

        self.orbit = Orbit.circular(Earth, 250 * u.km)

        # parameters of a body
        self.C_D = 2.2  # dimentionless (any value would do)
        self.A_over_m = ((np.pi / 4.0) * (u.m**2) / (100 * u.kg)).to_value(
            u.km**2 / u.kg)  # km^2/kg
        self.B = self.C_D * self.A_over_m

        # parameters of the atmosphere
        self.rho0 = rho0_earth.to(u.kg / u.km**3)  # kg/km^3
        self.H0 = H0_earth.to(u.km).value
        self.tof = [60.0] * u.s
Example #6
0
def test_atmospheric_demise():
    # Test an orbital decay that hits Earth. No analytic solution.
    R = Earth.R.to(u.km).value

    orbit = Orbit.circular(Earth, 230 * u.km)
    t_decay = 48.2179 * u.d

    # parameters of a body
    C_D = 2.2  # dimentionless (any value would do)
    A = ((np.pi / 4.0) * (u.m**2)).to(u.km**2).value  # km^2
    m = 100  # kg

    # parameters of the atmosphere
    rho0 = rho0_earth.to(u.kg / u.km**3).value  # kg/km^3
    H0 = H0_earth.to(u.km).value  # km

    tofs = [365] * u.d  # actually hits the ground a bit after day 48

    lithobrake_event = LithobrakeEvent(R)
    events = [lithobrake_event]

    rr, _ = cowell(
        Earth.k,
        orbit.r,
        orbit.v,
        tofs,
        ad=atmospheric_drag,
        R=R,
        C_D=C_D,
        A=A,
        m=m,
        H0=H0,
        rho0=rho0,
        events=events,
    )

    assert_quantity_allclose(norm(rr[0].to(u.km).value), R,
                             atol=1)  # below 1km

    # last_t is not an analytic value
    assert_quantity_allclose(lithobrake_event.last_t, t_decay, rtol=1e-2)
Example #7
0
		# adder = 2*np.pi * u.rad
		# for i in range(1,len(lons)):
		# 	if np.abs(lons[i].value-lons[i-1].value) > 1:
		# 		sgn=np.sign(lons[i].value-lons[i-1].value)
		# 		lons[i:] += -sgn*adder

		
		#interpolation of manipulated and folded points 
		#flats = interp1d(tofs,lats)
		#flons = interp1d(tofs,lons)
		#tofs = np.linspace(0,T*3600*24*u.s,int(T*3600*24/dt))
		#lats = flats(tofs) * u.rad
		#lons = (lons.value) % (2*np.pi) * u.rad 

		return lons,lats






rho0 = rho0_earth.to(u.kg / u.km ** 3).value
H0 = H0_earth.to(u.km).value

@jit
def J2_and_drag(t0, state, k, J2, R, C_D, A_over_m, H0, rho0):
    return J2_perturbation(t0, state, k, J2, R) + atmospheric_drag_exponential(
        t0, state, k, R, C_D, A_over_m, H0, rho0
    )