Example #1
0
def test_compute_missing_body_laplace_radius_raises_error(missing_body):
    with pytest.raises(RuntimeError) as excinfo:
        laplace_radius(missing_body)
    assert (
        "To compute the semimajor axis for Moon and Pluto use the JPL ephemeris"
        in excinfo.exconly()
    )
Example #2
0
    def change_attractor(self, new_attractor, force=False):
        """Changes orbit attractor.

        Only changes from attractor to parent or the other way around are allowed.

        Parameters
        ----------
        new_attractor : poliastro.bodies.Body
            Desired new attractor.
        force : bool
            If `True`, changes attractor even if physically has no-sense.

        Returns
        -------
        ss: poliastro.twobody.orbit.Orbit
            Orbit with new attractor

        """
        if self.attractor == new_attractor:
            return self
        elif self.attractor == new_attractor.parent:  # "Sun -> Earth"
            r_soi = laplace_radius(new_attractor)
            barycentric_position = get_body_barycentric(new_attractor.name, self.epoch)
            # Transforming new_attractor's frame into frame of attractor
            new_attractor_r = (
                ICRS(barycentric_position)
                .transform_to(self.get_frame())
                .represent_as(CartesianRepresentation)
                .xyz
            )
            distance = norm(self.r - new_attractor_r)
        elif self.attractor.parent == new_attractor:  # "Earth -> Sun"
            r_soi = laplace_radius(self.attractor)
            distance = norm(self.r)
        else:
            raise ValueError("Cannot change to unrelated attractor")

        if distance > r_soi and not force:
            raise ValueError(
                "Orbit is out of new attractor's SOI. If required, use 'force=True'."
            )
        elif self.ecc < 1.0 and not force:
            raise ValueError("Orbit will never leave the SOI of its current attractor")
        else:
            warn(
                "Leaving the SOI of the current attractor",
                PatchedConicsWarning,
                stacklevel=2,
            )

        new_frame = get_frame(new_attractor, self.plane, obstime=self.epoch)
        coords = self.get_frame().realize_frame(
            self.represent_as(CartesianRepresentation, CartesianDifferential)
        )
        ss = Orbit.from_coords(new_attractor, coords.transform_to(new_frame))

        return ss
Example #3
0
def test_laplace_radius(body, expected_r_SOI):
    if expected_r_SOI is not None:
        expected_r_SOI = expected_r_SOI * u.m

    r_SOI = laplace_radius(body)

    assert_quantity_allclose(r_SOI, expected_r_SOI, rtol=1e-1)
Example #4
0
def test_laplace_radius(body, expected_r_SOI):
    if expected_r_SOI is not None:
        expected_r_SOI = expected_r_SOI * u.m

    r_SOI = laplace_radius(body)

    assert_quantity_allclose(r_SOI, expected_r_SOI, rtol=1e-1)
Example #5
0
    def change_attractor(self, new_attractor):
        """Changes orbit attractor.

        Only changes from attractor to parent or the other way around are allowed.

        Parameters
        ----------
        new_attractor: poliastro.bodies.Body
            Desired new attractor.

        Returns
        -------
        ss: poliastro.twobody.orbit.Orbit
            Orbit with new attractor

        """
        if self.attractor == new_attractor:
            return self
        elif self.attractor == new_attractor.parent:  # "Sun -> Earth"
            r_soi = laplace_radius(new_attractor)
            distance = norm(
                self.r -
                get_body_barycentric(new_attractor.name, self.epoch).xyz)
        elif self.attractor.parent == new_attractor:  # "Earth -> Sun"
            r_soi = laplace_radius(self.attractor)
            distance = norm(self.r)
        else:
            raise ValueError("Cannot change to unrelated attractor")

        if distance > r_soi:
            raise ValueError("Orbit is out of new attractor's SOI")
        elif self.ecc < 1.0:
            raise ValueError(
                "Orbit will never leave the SOI of its current attractor")
        else:
            warn("Leaving the SOI of the current attractor",
                 PatchedConicsWarning)

        new_frame = get_frame(new_attractor, self.plane, obstime=self.epoch)
        coords = self.frame.realize_frame(
            self.represent_as(CartesianRepresentation))
        ss = Orbit.from_coords(new_attractor, coords.transform_to(new_frame))

        return ss
    def _calculate_system_laplace_radii(self):
        body_soi = {}

        for body in self.body_list:
            if body.name == "Sun":
                pass
            else:
                try:
                    soi_rad = laplace_radius(body)

                    body_soi[body.name] = soi_rad
                except KeyError:
                    pass
                    # a = get_mean_elements(body).a <- semimajor axis
                    # r_SOI = a * (body.k / body.parent.k) ** (2 / 5)
                    # todo: calculate laplace radius from mass ratio and semimajor axis
                    #  for bodies where get_mean_elements fails
        return body_soi
Example #7
0
def test_laplace_radius_given_a():
    parent = Body(None, 1 * u.km**3 / u.s**2, "Parent")
    body = Body(parent, 1 * u.km**3 / u.s**2, "Body")
    r_SOI = laplace_radius(body, 1 * u.km)

    assert r_SOI == 1 * u.km
Example #8
0
def test_laplace_radius(body, expected_r_SOI):
    r_SOI = laplace_radius(body)

    assert_quantity_allclose(r_SOI, expected_r_SOI, rtol=1e-1)
Example #9
0
def test_laplace_radius_given_a():
    parent = Body(None, 1 * u.km ** 3 / u.s ** 2, "Parent")
    body = Body(parent, 1 * u.km ** 3 / u.s ** 2, "Body")
    r_SOI = laplace_radius(body, 1 * u.km)

    assert r_SOI == 1 * u.km