From 9408ecb5c8352a4c3daefd590d42b40d26eab287 Mon Sep 17 00:00:00 2001 From: Aleksandr Slatov <115647936+alesanter@users.noreply.github.com> Date: Tue, 23 Jul 2024 04:53:43 +0400 Subject: [PATCH] Law: semimajor axis of a planet (#866) * Move law of semiminor axis to radial motion folder * Create law and test for semimajor axis * Fix description --- ...is_via_kepler_constant_and_total_energy.py | 77 +++++++++++++++++++ ...f_elliptical_orbit_via_orbit_parameters.py | 0 ...a_kepler_constant_and_total_energy_test.py | 39 ++++++++++ ...iptical_orbit_via_orbit_parameters_test.py | 2 +- 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 symplyphysics/laws/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy.py rename symplyphysics/laws/gravity/{ => radial_motion}/semiminor_axis_of_elliptical_orbit_via_orbit_parameters.py (100%) create mode 100644 test/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy_test.py rename test/gravity/{ => radial_motion}/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py (92%) diff --git a/symplyphysics/laws/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy.py b/symplyphysics/laws/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy.py new file mode 100644 index 000000000..e33a1190b --- /dev/null +++ b/symplyphysics/laws/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy.py @@ -0,0 +1,77 @@ +r""" +Semimajor axis via Kepler's constant and total energy +===================================================== + +The semi-major axis of an orbiting planet depends on the Kepler's constant of +the star---planet system and the total energy of the planet per unit of its mass. + +**Notes:** + +#. Works for both elliptical (:math:`\varepsilon < 0`) and hyperbolical + (:math:`\varepsilon > 0`) orbits. +""" + +from sympy import Eq, pi +from symplyphysics import ( + units, + Quantity, + Symbol, + validate_input, + validate_output, +) + +semimajor_axis = Symbol("semimajor_axis", units.length) +""" +The semi-major axis of the planet's orbit. + +Symbol: + a +""" + +kepler_constant = Symbol("kepler_constant", units.length**3 / units.time**2) +r""" +The Kepler's constant, whose value is determined by the mass of the orbited star. + +Symbol: + K + +Latex: + :math:`\mathfrak{K}` +""" + +total_energy_per_unit_mass = Symbol("total_energy_per_unit_mass", units.energy / units.mass) +r""" +The total energy of the planet per unit of its :attr:`~symplyphysics.symbols.basic.mass`. +Can be negative or positive. + +Symbol: + epsilon + +Latex: + :math:`\varepsilon` +""" + +law = Eq(semimajor_axis, 2 * pi**2 * kepler_constant / abs(total_energy_per_unit_mass)) +r""" +a = 2 * pi^2 * K / abs(epsilon) + +Latex: + .. math:: + a = \frac{2 \pi^2 \mathfrak{K}}{|\varepsilon|} +""" + + +@validate_input( + kepler_constant_=kepler_constant, + total_energy_per_unit_mass_=total_energy_per_unit_mass, +) +@validate_output(semimajor_axis) +def calculate_semimajor_axis( + kepler_constant_: Quantity, + total_energy_per_unit_mass_: Quantity, +) -> Quantity: + result = law.rhs.subs({ + kepler_constant: kepler_constant_, + total_energy_per_unit_mass: total_energy_per_unit_mass_, + }) + return Quantity(result) diff --git a/symplyphysics/laws/gravity/semiminor_axis_of_elliptical_orbit_via_orbit_parameters.py b/symplyphysics/laws/gravity/radial_motion/semiminor_axis_of_elliptical_orbit_via_orbit_parameters.py similarity index 100% rename from symplyphysics/laws/gravity/semiminor_axis_of_elliptical_orbit_via_orbit_parameters.py rename to symplyphysics/laws/gravity/radial_motion/semiminor_axis_of_elliptical_orbit_via_orbit_parameters.py diff --git a/test/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy_test.py b/test/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy_test.py new file mode 100644 index 000000000..284a65ec6 --- /dev/null +++ b/test/gravity/radial_motion/semimajor_axis_via_kepler_constant_and_total_energy_test.py @@ -0,0 +1,39 @@ +from collections import namedtuple +from pytest import fixture, raises +from symplyphysics import ( + assert_equal, + errors, + units, + Quantity, +) +from symplyphysics.laws.gravity.radial_motion import semimajor_axis_via_kepler_constant_and_total_energy as law + +Args = namedtuple("Args", "k e") + + +@fixture(name="test_args") +def test_args_fixture() -> Args: + k = Quantity(7.5e-6 * units.astronomical_unit**3 / units.day**2) + e = Quantity(-4.4e8 * units.joule / units.kilogram) + return Args(k=k, e=e) + + +def test_law(test_args: Args) -> None: + result = law.calculate_semimajor_axis(test_args.k, test_args.e) + assert_equal(result, 1.0 * units.astronomical_unit, tolerance=9e-3) + + +def test_bad_kepler_constant(test_args: Args) -> None: + kb = Quantity(units.coulomb) + with raises(errors.UnitsError): + law.calculate_semimajor_axis(kb, test_args.e) + with raises(TypeError): + law.calculate_semimajor_axis(100, test_args.e) + + +def test_bad_energy_per_mass(test_args: Args) -> None: + eb = Quantity(units.coulomb) + with raises(errors.UnitsError): + law.calculate_semimajor_axis(test_args.k, eb) + with raises(TypeError): + law.calculate_semimajor_axis(test_args.k, 100) diff --git a/test/gravity/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py b/test/gravity/radial_motion/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py similarity index 92% rename from test/gravity/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py rename to test/gravity/radial_motion/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py index 618f4d4de..14386f40d 100644 --- a/test/gravity/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py +++ b/test/gravity/radial_motion/semiminor_axis_of_elliptical_orbit_via_orbit_parameters_test.py @@ -6,7 +6,7 @@ units, Quantity, ) -from symplyphysics.laws.gravity import semiminor_axis_of_elliptical_orbit_via_orbit_parameters as law +from symplyphysics.laws.gravity.radial_motion import semiminor_axis_of_elliptical_orbit_via_orbit_parameters as law Args = namedtuple("Args", "s a m")