.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "api/gallery/classical/newtonian/plot_04_conservation_diagnostics.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_api_gallery_classical_newtonian_plot_04_conservation_diagnostics.py: Angular momentum: a different conservation law from energy ================================================================ ``physicskit.classical.utils.conservation`` has more than just energy-drift helpers. ``angular_momentum_2d`` and ``angular_momentum_drift`` track the planar angular momentum .. math:: L = x p_y - y p_x , which is conserved whenever a system's dynamics are rotationally symmetric about the origin (a central force, :math:`V = V(r)`) -- regardless of whether energy-conserving perturbations also happen to break other symmetries. This contrasts two systems: - KeplerSystem, even with a post-Newtonian perturbation that makes the Laplace-Runge-Lenz vector precess (a genuine physical effect: the perturbation breaks the *extra*, non-obvious SO(4) symmetry special to the exact 1/r potential), still exactly conserves angular momentum -- because it is still a central force, and central forces exert no torque about their center regardless of their radial profile. - ProjectileMotion, a *uniform* gravitational field, is not a central force from the origin at all: gravity exerts a real torque there, so L changes -- growing steadily as the projectile falls. .. GENERATED FROM PYTHON SOURCE LINES 30-35 .. code-block:: Python import matplotlib.pyplot as plt from physicskit.classical.systems.newtonian import KeplerSystem, ProjectileMotion from physicskit.classical.utils.conservation import angular_momentum_2d, angular_momentum_drift, relative_energy_drift .. GENERATED FROM PYTHON SOURCE LINES 36-38 Kepler, with a precession-causing perturbation: L still conserved ------------------------------------------------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 38-45 .. code-block:: Python kepler = KeplerSystem.from_orbital_elements(a=1.0, e=0.5, c_pn=0.02) result_k = kepler.integrate((0, 100), dt=1e-3, method="yoshida4") L_drift_k = angular_momentum_drift(result_k.q, result_k.p) E_drift_k = relative_energy_drift(result_k.energy) print(f"perturbed Kepler: max |L(t)-L(0)| = {L_drift_k.max():.2e}, max relative energy drift = {E_drift_k.max():.2e}") .. rst-class:: sphx-glr-script-out .. code-block:: none perturbed Kepler: max |L(t)-L(0)| = 2.94e-14, max relative energy drift = 1.41e-11 .. GENERATED FROM PYTHON SOURCE LINES 46-48 Projectile motion: uniform gravity is not a central force, L drifts -------------------------------------------------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 48-67 .. code-block:: Python proj = ProjectileMotion.from_launch(speed=20.0, angle_deg=45.0, g=9.81) result_p = proj.integrate((0, 2.9), dt=1e-3, method="yoshida4") L_p = angular_momentum_2d(result_p.q, result_p.p) print(f"projectile motion: L(0) = {L_p[0]:.3f}, L(end) = {L_p[-1]:.3f} (steadily changing, as expected)") fig, axes = plt.subplots(1, 2, figsize=(10, 4.3)) axes[0].plot(result_k.t, L_drift_k, color="steelblue") axes[0].set_xlabel("t") axes[0].set_ylabel(r"$|L(t) - L(0)|$") axes[0].set_title("Perturbed KeplerSystem:\nangular momentum exactly conserved") axes[1].plot(result_p.t, L_p, color="firebrick") axes[1].set_xlabel("t") axes[1].set_ylabel("L(t)") axes[1].set_title("ProjectileMotion:\nnot a central force, so L is not conserved") fig.suptitle("Angular momentum conservation depends on rotational symmetry, not on energy conservation", fontsize=12) fig.tight_layout(rect=[0, 0, 1, 0.90]) .. image-sg:: /api/gallery/classical/newtonian/images/sphx_glr_plot_04_conservation_diagnostics_001.png :alt: Angular momentum conservation depends on rotational symmetry, not on energy conservation, Perturbed KeplerSystem: angular momentum exactly conserved, ProjectileMotion: not a central force, so L is not conserved :srcset: /api/gallery/classical/newtonian/images/sphx_glr_plot_04_conservation_diagnostics_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none projectile motion: L(0) = 0.000, L(end) = -583.378 (steadily changing, as expected) .. GENERATED FROM PYTHON SOURCE LINES 68-72 This is the practical content of Noether's theorem: energy conservation comes from time-translation symmetry, angular momentum conservation from rotational symmetry, and the two can be switched on or off independently, as shown here. .. GENERATED FROM PYTHON SOURCE LINES 72-74 .. code-block:: Python plt.show() .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 0.663 seconds) .. _sphx_glr_download_api_gallery_classical_newtonian_plot_04_conservation_diagnostics.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_04_conservation_diagnostics.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_04_conservation_diagnostics.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_04_conservation_diagnostics.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_