From 20a86221381a9d7d98671cb806bb86da96dcff79 Mon Sep 17 00:00:00 2001 From: Aleksandr Slatov <115647936+alesanter@users.noreply.github.com> Date: Thu, 18 Jul 2024 01:53:41 +0400 Subject: [PATCH] Law: gravitational shift of spectral lines (#854) * Create outlines of law and test * Create law and test * Update symplyphysics/laws/waves/vector/__init__.py --------- Co-authored-by: blackyblack --- symplyphysics/laws/waves/__init__.py | 6 ++ ...ional_to_gravitational_potential_change.py | 90 +++++++++++++++++++ symplyphysics/laws/waves/vector/__init__.py | 6 ++ ..._to_gravitational_potential_change_test.py | 42 +++++++++ 4 files changed, 144 insertions(+) create mode 100644 symplyphysics/laws/waves/light_frequency_change_is_proportional_to_gravitational_potential_change.py create mode 100644 test/waves/light_frequency_change_is_proportional_to_gravitational_potential_change_test.py diff --git a/symplyphysics/laws/waves/__init__.py b/symplyphysics/laws/waves/__init__.py index e69de29bb..b0d3b327b 100644 --- a/symplyphysics/laws/waves/__init__.py +++ b/symplyphysics/laws/waves/__init__.py @@ -0,0 +1,6 @@ +""" +Waves +===== + +A *wave* is a propagating dynamic disturbance (change from equilibrium) of one or more quantities. +""" diff --git a/symplyphysics/laws/waves/light_frequency_change_is_proportional_to_gravitational_potential_change.py b/symplyphysics/laws/waves/light_frequency_change_is_proportional_to_gravitational_potential_change.py new file mode 100644 index 000000000..4c0ba852c --- /dev/null +++ b/symplyphysics/laws/waves/light_frequency_change_is_proportional_to_gravitational_potential_change.py @@ -0,0 +1,90 @@ +r""" +Light frequency change is proportional to gravitational potential change +======================================================================== + +When light is propagating in a gravitational field, its frequency changes proportionally to the +change in the potential of the gravitational field. + +Let us consider an infinitesimally small section :math:`d \vec r` of the light's path, such that +the frequency of light is constant within that section. In that case we can obtain a dependency +between the change in light's frequency and the change in the gravitational potential. +""" + +from sympy import Eq, solve +from symplyphysics import ( + units, + Symbol, + Quantity, + validate_input, + validate_output, +) + +frequency_change = Symbol("frequency_change", units.frequency) +r""" +The infinitesimal change in frequency after passing an infinitesimal section :math:`d \vec r`. + +Symbol: + frequency_change + +Latex: + :math:`d \nu` +""" + +frequency = Symbol("frequency", units.frequency) +r""" +The frequency of light within an infinitesimal section :math:`d \vec r`. + +Symbol: + frequency + +Latex: + :math:`\nu` +""" + +gravitational_potential_change = Symbol("gravitational_potential_change", units.velocity**2) +r""" +The infinitesimal change in gravitational potential after passing an infinitesimal section :math:`d \vec r`. + +The *gravitational potential* :math:`\varphi` is defined as a scalar quantity such that the equation +:math:`\vec g = - \nabla \varphi` is hold where :math:`\vec g` is the vector of acceleration due to gravity +and :math:`\nabla` is the nabla operator. + +Note that :math:`d \varphi = - \left( \vec g, d \vec r \right)` where :math:`\left( \vec a_1, \vec a_2 \right)` is +the dot product between :math:`\vec a_1` and :math:`\vec a_2`. + +Symbol: + gravitational_potential_change + +Latex: + :math:`d \varphi` +""" + +law = Eq( + frequency_change / frequency, + -1 * gravitational_potential_change / units.speed_of_light**2, +) +r""" +frequency_change / frequency = -1 * gravitational_potential_change / speed_of_light^2 + +Latex: + :math:`\frac{d \nu}{\nu} = - \frac{d \varphi}{c^2}` +""" + + +@validate_input( + frequency_=frequency, + gravitational_potential_change_=gravitational_potential_change, +) +@validate_output(frequency_change) +def calculate_frequency_change( + frequency_: Quantity, + gravitational_potential_change_: Quantity, +) -> Quantity: + expr = solve(law, frequency_change)[0] + result = expr.subs( + { + frequency: frequency_, + gravitational_potential_change: gravitational_potential_change_, + } + ) + return Quantity(result) diff --git a/symplyphysics/laws/waves/vector/__init__.py b/symplyphysics/laws/waves/vector/__init__.py index e69de29bb..b4c0a42bd 100644 --- a/symplyphysics/laws/waves/vector/__init__.py +++ b/symplyphysics/laws/waves/vector/__init__.py @@ -0,0 +1,6 @@ +""" +Waves (Vector) +=================== + +Laws related to waves in vector form. +""" diff --git a/test/waves/light_frequency_change_is_proportional_to_gravitational_potential_change_test.py b/test/waves/light_frequency_change_is_proportional_to_gravitational_potential_change_test.py new file mode 100644 index 000000000..c40037a24 --- /dev/null +++ b/test/waves/light_frequency_change_is_proportional_to_gravitational_potential_change_test.py @@ -0,0 +1,42 @@ +from collections import namedtuple +from pytest import fixture, raises +from symplyphysics import ( + assert_equal, + errors, + units, + prefixes, + Quantity, +) +from symplyphysics.laws.waves import ( + light_frequency_change_is_proportional_to_gravitational_potential_change as law, +) + +Args = namedtuple("Args", "nu dphi") + + +@fixture(name="test_args") +def test_args_fixture() -> Args: + nu = Quantity(6e14 * units.hertz) + dphi = Quantity(1e-9 * (units.meter / units.second)**2) + return Args(nu=nu, dphi=dphi) + + +def test_law(test_args: Args) -> None: + result = law.calculate_frequency_change(test_args.nu, test_args.dphi) + assert_equal(result, -6.7e-12 * units.hertz, tolerance=4e-3) + + +def test_bad_frequency(test_args: Args) -> None: + nub = Quantity(units.coulomb) + with raises(errors.UnitsError): + law.calculate_frequency_change(nub, test_args.dphi) + with raises(TypeError): + law.calculate_frequency_change(100, test_args.dphi) + + +def test_bad_potential(test_args: Args) -> None: + phib = Quantity(units.coulomb) + with raises(errors.UnitsError): + law.calculate_frequency_change(test_args.nu, phib) + with raises(TypeError): + law.calculate_frequency_change(test_args.nu, 100)