physicskit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- physicskit/__init__.py +51 -0
- physicskit/astro/__init__.py +66 -0
- physicskit/astro/cosmic_web.py +395 -0
- physicskit/astro/galactic_dynamics.py +137 -0
- physicskit/astro/nbody.py +208 -0
- physicskit/astro/orbital_mechanics.py +220 -0
- physicskit/astro/stellar_dynamo.py +628 -0
- physicskit/astro/stellar_structure.py +198 -0
- physicskit/astro/tests/__init__.py +0 -0
- physicskit/astro/tests/conftest.py +7 -0
- physicskit/astro/tests/test_cosmic_web.py +159 -0
- physicskit/astro/tests/test_galactic_dynamics.py +46 -0
- physicskit/astro/tests/test_nbody.py +81 -0
- physicskit/astro/tests/test_orbital_mechanics.py +73 -0
- physicskit/astro/tests/test_stellar_dynamo.py +198 -0
- physicskit/astro/tests/test_stellar_structure.py +52 -0
- physicskit/astro/tests/test_visualizers.py +159 -0
- physicskit/astro/visualizers.py +628 -0
- physicskit/chaos/__init__.py +55 -0
- physicskit/chaos/core/__init__.py +3 -0
- physicskit/chaos/core/base_system.py +342 -0
- physicskit/chaos/core/integrators.py +40 -0
- physicskit/chaos/exceptions.py +24 -0
- physicskit/chaos/quantum/__init__.py +38 -0
- physicskit/chaos/quantum/billiards.py +274 -0
- physicskit/chaos/quantum/husimi.py +85 -0
- physicskit/chaos/quantum/maps.py +366 -0
- physicskit/chaos/systems/__init__.py +38 -0
- physicskit/chaos/systems/billiards.py +1131 -0
- physicskit/chaos/systems/continuous.py +1276 -0
- physicskit/chaos/systems/maps.py +557 -0
- physicskit/chaos/tests/__init__.py +0 -0
- physicskit/chaos/tests/test_basins.py +76 -0
- physicskit/chaos/tests/test_bifurcation.py +132 -0
- physicskit/chaos/tests/test_billiards.py +115 -0
- physicskit/chaos/tests/test_continuous.py +224 -0
- physicskit/chaos/tests/test_dimension.py +69 -0
- physicskit/chaos/tests/test_divergence.py +90 -0
- physicskit/chaos/tests/test_dynamic_plots.py +269 -0
- physicskit/chaos/tests/test_integrators.py +96 -0
- physicskit/chaos/tests/test_io.py +41 -0
- physicskit/chaos/tests/test_maps.py +110 -0
- physicskit/chaos/tests/test_metrics.py +115 -0
- physicskit/chaos/tests/test_phase_space.py +73 -0
- physicskit/chaos/tests/test_properties.py +116 -0
- physicskit/chaos/tests/test_quantum_billiards.py +94 -0
- physicskit/chaos/tests/test_quantum_maps.py +144 -0
- physicskit/chaos/tests/test_recurrence.py +51 -0
- physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
- physicskit/chaos/tests/test_section.py +49 -0
- physicskit/chaos/tests/test_spectral.py +48 -0
- physicskit/chaos/tests/test_streamlit_app.py +45 -0
- physicskit/chaos/tests/test_timeseries.py +131 -0
- physicskit/chaos/tests/test_viewer3d.py +41 -0
- physicskit/chaos/utils/__init__.py +46 -0
- physicskit/chaos/utils/dimension.py +139 -0
- physicskit/chaos/utils/io.py +95 -0
- physicskit/chaos/utils/metrics.py +304 -0
- physicskit/chaos/utils/recurrence.py +122 -0
- physicskit/chaos/utils/spectral.py +69 -0
- physicskit/chaos/utils/timeseries.py +303 -0
- physicskit/chaos/visualizers/__init__.py +85 -0
- physicskit/chaos/visualizers/basins.py +185 -0
- physicskit/chaos/visualizers/bifurcation.py +273 -0
- physicskit/chaos/visualizers/divergence.py +374 -0
- physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
- physicskit/chaos/visualizers/phase_space.py +133 -0
- physicskit/chaos/visualizers/quantum.py +299 -0
- physicskit/chaos/visualizers/recurrence.py +91 -0
- physicskit/chaos/visualizers/section.py +161 -0
- physicskit/chaos/visualizers/theme.py +31 -0
- physicskit/chaos/visualizers/viewer3d.py +82 -0
- physicskit/classical/__init__.py +55 -0
- physicskit/classical/core/__init__.py +17 -0
- physicskit/classical/core/base_system.py +510 -0
- physicskit/classical/core/integrators.py +397 -0
- physicskit/classical/systems/__init__.py +32 -0
- physicskit/classical/systems/chains.py +334 -0
- physicskit/classical/systems/hamiltonian.py +215 -0
- physicskit/classical/systems/lagrangian.py +308 -0
- physicskit/classical/systems/newtonian.py +536 -0
- physicskit/classical/systems/rotations.py +614 -0
- physicskit/classical/tests/__init__.py +0 -0
- physicskit/classical/tests/conftest.py +7 -0
- physicskit/classical/tests/test_base_system.py +113 -0
- physicskit/classical/tests/test_chains.py +84 -0
- physicskit/classical/tests/test_conservation.py +244 -0
- physicskit/classical/tests/test_conservation_utils.py +47 -0
- physicskit/classical/tests/test_hamiltonian.py +44 -0
- physicskit/classical/tests/test_integrators.py +123 -0
- physicskit/classical/tests/test_lagrangian.py +69 -0
- physicskit/classical/tests/test_newtonian.py +45 -0
- physicskit/classical/tests/test_rotations.py +160 -0
- physicskit/classical/tests/test_stepsize.py +149 -0
- physicskit/classical/tests/test_symbolic.py +125 -0
- physicskit/classical/tests/test_visualizers.py +172 -0
- physicskit/classical/utils/__init__.py +20 -0
- physicskit/classical/utils/conservation.py +126 -0
- physicskit/classical/utils/stepsize.py +187 -0
- physicskit/classical/utils/symbolic.py +235 -0
- physicskit/classical/visualizers/__init__.py +25 -0
- physicskit/classical/visualizers/animations.py +508 -0
- physicskit/classical/visualizers/interactive.py +113 -0
- physicskit/classical/visualizers/modal_analysis.py +97 -0
- physicskit/classical/visualizers/phase_space.py +214 -0
- physicskit/condensed/__init__.py +122 -0
- physicskit/condensed/anderson_localization.py +155 -0
- physicskit/condensed/correlated.py +284 -0
- physicskit/condensed/ginzburg_landau.py +220 -0
- physicskit/condensed/landau_levels.py +246 -0
- physicskit/condensed/laughlin.py +229 -0
- physicskit/condensed/models.py +627 -0
- physicskit/condensed/tests/__init__.py +0 -0
- physicskit/condensed/tests/test_condensed.py +518 -0
- physicskit/condensed/tests/test_visualizers.py +87 -0
- physicskit/condensed/tight_binding.py +445 -0
- physicskit/condensed/topological_insulator_3d.py +178 -0
- physicskit/condensed/topology.py +217 -0
- physicskit/condensed/visualizers.py +296 -0
- physicskit/condensed/weyl.py +180 -0
- physicskit/constants.py +184 -0
- physicskit/fields/__init__.py +111 -0
- physicskit/fields/electrodynamics.py +671 -0
- physicskit/fields/quantum_fields.py +510 -0
- physicskit/fields/solitons.py +527 -0
- physicskit/fields/tests/__init__.py +0 -0
- physicskit/fields/tests/conftest.py +7 -0
- physicskit/fields/tests/test_field_animations.py +154 -0
- physicskit/fields/tests/test_fields.py +439 -0
- physicskit/fields/tests/test_visualizers.py +101 -0
- physicskit/fields/visualizers.py +503 -0
- physicskit/fluids/__init__.py +134 -0
- physicskit/fluids/core/__init__.py +23 -0
- physicskit/fluids/core/grid.py +165 -0
- physicskit/fluids/core/timestepping.py +231 -0
- physicskit/fluids/exceptions.py +26 -0
- physicskit/fluids/systems/__init__.py +70 -0
- physicskit/fluids/systems/compressible_flow.py +281 -0
- physicskit/fluids/systems/instabilities.py +343 -0
- physicskit/fluids/systems/navier_stokes.py +221 -0
- physicskit/fluids/systems/potential_flow.py +440 -0
- physicskit/fluids/systems/viscous_flow.py +425 -0
- physicskit/fluids/systems/vortex_dynamics.py +304 -0
- physicskit/fluids/tests/__init__.py +0 -0
- physicskit/fluids/tests/conftest.py +7 -0
- physicskit/fluids/tests/test_compressible_flow.py +66 -0
- physicskit/fluids/tests/test_instabilities.py +115 -0
- physicskit/fluids/tests/test_navier_stokes.py +67 -0
- physicskit/fluids/tests/test_potential_flow.py +92 -0
- physicskit/fluids/tests/test_static_visualizers.py +91 -0
- physicskit/fluids/tests/test_utils.py +100 -0
- physicskit/fluids/tests/test_viscous_flow.py +110 -0
- physicskit/fluids/tests/test_visualizers.py +34 -0
- physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
- physicskit/fluids/utils/__init__.py +18 -0
- physicskit/fluids/utils/dimensionless.py +239 -0
- physicskit/fluids/utils/spectral_analysis.py +142 -0
- physicskit/fluids/visualizers/__init__.py +14 -0
- physicskit/fluids/visualizers/compressible.py +39 -0
- physicskit/fluids/visualizers/flow_fields.py +252 -0
- physicskit/fluids/visualizers/potential_flow.py +51 -0
- physicskit/fluids/visualizers/spectra.py +62 -0
- physicskit/fluids/visualizers/theme.py +38 -0
- physicskit/integrators/__init__.py +52 -0
- physicskit/integrators/adaptive.py +199 -0
- physicskit/integrators/fixed_step.py +360 -0
- physicskit/integrators/tests/__init__.py +0 -0
- physicskit/integrators/tests/test_integrators.py +101 -0
- physicskit/optics/__init__.py +124 -0
- physicskit/optics/_compat.py +5 -0
- physicskit/optics/gaussian.py +382 -0
- physicskit/optics/quantum_optics.py +428 -0
- physicskit/optics/ray.py +469 -0
- physicskit/optics/tests/__init__.py +0 -0
- physicskit/optics/tests/test_diffraction_animation.py +38 -0
- physicskit/optics/tests/test_gaussian.py +170 -0
- physicskit/optics/tests/test_quantum_optics.py +147 -0
- physicskit/optics/tests/test_ray.py +177 -0
- physicskit/optics/tests/test_visualizers.py +58 -0
- physicskit/optics/tests/test_wave.py +146 -0
- physicskit/optics/visualizers.py +264 -0
- physicskit/optics/wave.py +365 -0
- physicskit/particle/__init__.py +152 -0
- physicskit/particle/collider.py +382 -0
- physicskit/particle/confinement.py +125 -0
- physicskit/particle/decays.py +357 -0
- physicskit/particle/electroweak.py +300 -0
- physicskit/particle/kinematics.py +271 -0
- physicskit/particle/neutrinos.py +84 -0
- physicskit/particle/nuclear.py +100 -0
- physicskit/particle/scattering.py +159 -0
- physicskit/particle/tests/__init__.py +0 -0
- physicskit/particle/tests/conftest.py +7 -0
- physicskit/particle/tests/test_collider.py +119 -0
- physicskit/particle/tests/test_confinement.py +42 -0
- physicskit/particle/tests/test_decays.py +112 -0
- physicskit/particle/tests/test_electroweak.py +97 -0
- physicskit/particle/tests/test_kinematics.py +138 -0
- physicskit/particle/tests/test_neutrinos.py +36 -0
- physicskit/particle/tests/test_nuclear.py +45 -0
- physicskit/particle/tests/test_scattering.py +64 -0
- physicskit/particle/tests/test_visualizers.py +214 -0
- physicskit/particle/visualizers/__init__.py +38 -0
- physicskit/particle/visualizers/animations.py +705 -0
- physicskit/particle/visualizers/static.py +101 -0
- physicskit/plasma/__init__.py +176 -0
- physicskit/plasma/acceleration.py +152 -0
- physicskit/plasma/instabilities.py +417 -0
- physicskit/plasma/kinetic.py +588 -0
- physicskit/plasma/mhd.py +463 -0
- physicskit/plasma/single_particle.py +562 -0
- physicskit/plasma/tests/__init__.py +0 -0
- physicskit/plasma/tests/conftest.py +7 -0
- physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
- physicskit/plasma/tests/test_plasma.py +232 -0
- physicskit/plasma/tests/test_visualizers.py +79 -0
- physicskit/plasma/turbulence.py +219 -0
- physicskit/plasma/visualizers.py +868 -0
- physicskit/plasma/waves.py +549 -0
- physicskit/quantum/__init__.py +180 -0
- physicskit/quantum/_compat.py +20 -0
- physicskit/quantum/chapters/__init__.py +0 -0
- physicskit/quantum/chapters/entanglement.py +489 -0
- physicskit/quantum/chapters/harmonic_spin.py +517 -0
- physicskit/quantum/chapters/hydrogen_am.py +292 -0
- physicskit/quantum/chapters/perturbation.py +350 -0
- physicskit/quantum/chapters/potentials.py +997 -0
- physicskit/quantum/chapters/spin.py +306 -0
- physicskit/quantum/chapters/wave_packets.py +541 -0
- physicskit/quantum/core/__init__.py +0 -0
- physicskit/quantum/core/eigensolvers.py +311 -0
- physicskit/quantum/core/operators.py +296 -0
- physicskit/quantum/core/solvers.py +271 -0
- physicskit/quantum/tests/__init__.py +0 -0
- physicskit/quantum/tests/conftest.py +7 -0
- physicskit/quantum/tests/test_animations.py +225 -0
- physicskit/quantum/tests/test_compat.py +43 -0
- physicskit/quantum/tests/test_eigensolvers.py +24 -0
- physicskit/quantum/tests/test_entanglement.py +127 -0
- physicskit/quantum/tests/test_harmonic_spin.py +140 -0
- physicskit/quantum/tests/test_hydrogen_am.py +48 -0
- physicskit/quantum/tests/test_measure.py +110 -0
- physicskit/quantum/tests/test_operators.py +105 -0
- physicskit/quantum/tests/test_perturbation.py +112 -0
- physicskit/quantum/tests/test_physics_checks.py +131 -0
- physicskit/quantum/tests/test_potentials.py +191 -0
- physicskit/quantum/tests/test_solvers.py +70 -0
- physicskit/quantum/tests/test_spin.py +22 -0
- physicskit/quantum/tests/test_unitarity.py +84 -0
- physicskit/quantum/tests/test_wave_packets.py +53 -0
- physicskit/quantum/utils/__init__.py +0 -0
- physicskit/quantum/utils/measure.py +253 -0
- physicskit/quantum/visualizers/__init__.py +0 -0
- physicskit/quantum/visualizers/bloch_sphere.py +205 -0
- physicskit/quantum/visualizers/entanglement.py +58 -0
- physicskit/quantum/visualizers/orbitals.py +187 -0
- physicskit/quantum/visualizers/phase_space.py +179 -0
- physicskit/quantum/visualizers/wavefunctions.py +230 -0
- physicskit/relativity/__init__.py +61 -0
- physicskit/relativity/chapters/__init__.py +33 -0
- physicskit/relativity/chapters/cosmology.py +190 -0
- physicskit/relativity/chapters/gw_merger.py +399 -0
- physicskit/relativity/chapters/kerr.py +371 -0
- physicskit/relativity/chapters/lensing.py +196 -0
- physicskit/relativity/chapters/neutron_star.py +149 -0
- physicskit/relativity/chapters/schwarzschild.py +412 -0
- physicskit/relativity/chapters/timekeeping.py +133 -0
- physicskit/relativity/core/__init__.py +12 -0
- physicskit/relativity/core/geodesics.py +216 -0
- physicskit/relativity/core/kerr_raytracer.py +259 -0
- physicskit/relativity/core/raytracer.py +241 -0
- physicskit/relativity/core/tensors.py +468 -0
- physicskit/relativity/tests/__init__.py +0 -0
- physicskit/relativity/tests/test_conservations.py +54 -0
- physicskit/relativity/tests/test_constants.py +34 -0
- physicskit/relativity/tests/test_cosmology.py +61 -0
- physicskit/relativity/tests/test_gw_merger.py +117 -0
- physicskit/relativity/tests/test_kerr.py +116 -0
- physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
- physicskit/relativity/tests/test_lensing.py +75 -0
- physicskit/relativity/tests/test_neutron_star.py +48 -0
- physicskit/relativity/tests/test_raytracer.py +67 -0
- physicskit/relativity/tests/test_schwarzschild.py +126 -0
- physicskit/relativity/tests/test_shadow_render.py +81 -0
- physicskit/relativity/tests/test_tensors.py +86 -0
- physicskit/relativity/tests/test_timekeeping.py +51 -0
- physicskit/relativity/tests/test_visualizers_misc.py +115 -0
- physicskit/relativity/utils/__init__.py +1 -0
- physicskit/relativity/utils/constants.py +232 -0
- physicskit/relativity/visualizers/__init__.py +46 -0
- physicskit/relativity/visualizers/interactive.py +127 -0
- physicskit/relativity/visualizers/shadow_render.py +367 -0
- physicskit/relativity/visualizers/spacetime_3d.py +92 -0
- physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
- physicskit/relativity/visualizers/wave_plots.py +185 -0
- physicskit/rmt/__init__.py +8 -0
- physicskit/rmt/ensembles/__init__.py +108 -0
- physicskit/rmt/ensembles/banded.py +114 -0
- physicskit/rmt/ensembles/base.py +135 -0
- physicskit/rmt/ensembles/bdg.py +218 -0
- physicskit/rmt/ensembles/chiral.py +308 -0
- physicskit/rmt/ensembles/circular.py +104 -0
- physicskit/rmt/ensembles/crossover.py +82 -0
- physicskit/rmt/ensembles/density_matrix.py +148 -0
- physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
- physicskit/rmt/ensembles/embedded.py +207 -0
- physicskit/rmt/ensembles/gaussian.py +153 -0
- physicskit/rmt/ensembles/ginibre.py +110 -0
- physicskit/rmt/ensembles/girko.py +190 -0
- physicskit/rmt/ensembles/graph_laplacian.py +92 -0
- physicskit/rmt/ensembles/haar.py +57 -0
- physicskit/rmt/ensembles/jacobi.py +182 -0
- physicskit/rmt/ensembles/poisson.py +77 -0
- physicskit/rmt/ensembles/polynomial.py +139 -0
- physicskit/rmt/ensembles/pt_symmetric.py +120 -0
- physicskit/rmt/ensembles/single_ring.py +170 -0
- physicskit/rmt/ensembles/sparse.py +95 -0
- physicskit/rmt/ensembles/syk.py +170 -0
- physicskit/rmt/ensembles/truncated_unitary.py +80 -0
- physicskit/rmt/ensembles/universality.py +92 -0
- physicskit/rmt/ensembles/wishart.py +88 -0
- physicskit/rmt/py.typed +0 -0
- physicskit/rmt/spectrum.py +82 -0
- physicskit/rmt/stats/__init__.py +160 -0
- physicskit/rmt/stats/characteristic_polynomial.py +77 -0
- physicskit/rmt/stats/circular_law.py +54 -0
- physicskit/rmt/stats/correlations.py +162 -0
- physicskit/rmt/stats/density.py +70 -0
- physicskit/rmt/stats/entanglement.py +36 -0
- physicskit/rmt/stats/free_probability.py +202 -0
- physicskit/rmt/stats/localization.py +338 -0
- physicskit/rmt/stats/marchenko_pastur.py +55 -0
- physicskit/rmt/stats/pt_symmetric.py +265 -0
- physicskit/rmt/stats/ratios.py +110 -0
- physicskit/rmt/stats/real_ginibre.py +134 -0
- physicskit/rmt/stats/rigidity.py +272 -0
- physicskit/rmt/stats/single_ring.py +95 -0
- physicskit/rmt/stats/spacing.py +150 -0
- physicskit/rmt/stats/tracy_widom.py +175 -0
- physicskit/rmt/stats/truncated_unitary.py +40 -0
- physicskit/rmt/stats/unfolding.py +37 -0
- physicskit/rmt/stats/wachter.py +67 -0
- physicskit/rmt/tests/__init__.py +0 -0
- physicskit/rmt/tests/cache_utils.py +107 -0
- physicskit/rmt/tests/conftest.py +8 -0
- physicskit/rmt/tests/test_banded.py +86 -0
- physicskit/rmt/tests/test_base.py +29 -0
- physicskit/rmt/tests/test_bdg.py +133 -0
- physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
- physicskit/rmt/tests/test_chiral.py +273 -0
- physicskit/rmt/tests/test_circular.py +225 -0
- physicskit/rmt/tests/test_crossover.py +72 -0
- physicskit/rmt/tests/test_density.py +23 -0
- physicskit/rmt/tests/test_density_matrix.py +181 -0
- physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
- physicskit/rmt/tests/test_embedded.py +169 -0
- physicskit/rmt/tests/test_free_probability.py +81 -0
- physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
- physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
- physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
- physicskit/rmt/tests/test_girko.py +178 -0
- physicskit/rmt/tests/test_graph_laplacian.py +102 -0
- physicskit/rmt/tests/test_haar.py +118 -0
- physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
- physicskit/rmt/tests/test_localization.py +240 -0
- physicskit/rmt/tests/test_poisson.py +149 -0
- physicskit/rmt/tests/test_polynomial.py +107 -0
- physicskit/rmt/tests/test_pt_symmetric.py +178 -0
- physicskit/rmt/tests/test_random_state.py +19 -0
- physicskit/rmt/tests/test_real_ginibre.py +112 -0
- physicskit/rmt/tests/test_rigidity_universality.py +167 -0
- physicskit/rmt/tests/test_single_ring.py +132 -0
- physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
- physicskit/rmt/tests/test_sparse.py +71 -0
- physicskit/rmt/tests/test_spectrum.py +27 -0
- physicskit/rmt/tests/test_syk.py +136 -0
- physicskit/rmt/tests/test_tracy_widom.py +113 -0
- physicskit/rmt/tests/test_tridiagonal.py +41 -0
- physicskit/rmt/tests/test_truncated_unitary.py +80 -0
- physicskit/rmt/tests/test_validation_base.py +25 -0
- physicskit/rmt/tests/test_validation_misc.py +67 -0
- physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
- physicskit/rmt/utils/__init__.py +0 -0
- physicskit/rmt/utils/haar.py +128 -0
- physicskit/rmt/utils/random_state.py +24 -0
- physicskit/rmt/utils/tridiagonal.py +167 -0
- physicskit/rmt/validation/__init__.py +36 -0
- physicskit/rmt/validation/base.py +126 -0
- physicskit/rmt/validation/circular_law.py +80 -0
- physicskit/rmt/validation/marchenko_pastur.py +53 -0
- physicskit/rmt/validation/ratio_distribution.py +53 -0
- physicskit/rmt/validation/real_ginibre.py +60 -0
- physicskit/rmt/validation/sine_kernel.py +57 -0
- physicskit/rmt/validation/single_ring.py +68 -0
- physicskit/rmt/validation/tracy_widom.py +89 -0
- physicskit/rmt/validation/universality.py +100 -0
- physicskit/rmt/validation/wachter.py +52 -0
- physicskit/rmt/validation/wigner_semicircle.py +40 -0
- physicskit/rmt/validation/wigner_surmise.py +58 -0
- physicskit/semiclassical/__init__.py +94 -0
- physicskit/semiclassical/_compat.py +5 -0
- physicskit/semiclassical/core/__init__.py +41 -0
- physicskit/semiclassical/core/gutzwiller.py +215 -0
- physicskit/semiclassical/core/path_integral.py +594 -0
- physicskit/semiclassical/core/propagators.py +579 -0
- physicskit/semiclassical/core/wkb.py +308 -0
- physicskit/semiclassical/systems/__init__.py +13 -0
- physicskit/semiclassical/systems/scarring.py +278 -0
- physicskit/semiclassical/tests/__init__.py +0 -0
- physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
- physicskit/semiclassical/tests/test_path_integral.py +194 -0
- physicskit/semiclassical/tests/test_propagators.py +82 -0
- physicskit/semiclassical/tests/test_scarring.py +43 -0
- physicskit/semiclassical/tests/test_visualizers.py +89 -0
- physicskit/semiclassical/tests/test_wkb.py +30 -0
- physicskit/semiclassical/visualizers/__init__.py +17 -0
- physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
- physicskit/semiclassical/visualizers/path_integral.py +195 -0
- physicskit/semiclassical/visualizers/propagators.py +89 -0
- physicskit/semiclassical/visualizers/scarring.py +146 -0
- physicskit/semiclassical/visualizers/wkb.py +55 -0
- physicskit/statphys/__init__.py +80 -0
- physicskit/statphys/chapters/__init__.py +43 -0
- physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
- physicskit/statphys/chapters/ising_lattice.py +431 -0
- physicskit/statphys/chapters/kpz_growth.py +129 -0
- physicskit/statphys/chapters/molecular_dynamics.py +258 -0
- physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
- physicskit/statphys/chapters/percolation.py +305 -0
- physicskit/statphys/chapters/random_walk.py +142 -0
- physicskit/statphys/chapters/renormalization.py +148 -0
- physicskit/statphys/chapters/sandpile.py +109 -0
- physicskit/statphys/chapters/spin_glass.py +275 -0
- physicskit/statphys/core/__init__.py +10 -0
- physicskit/statphys/core/kpz_engine.py +53 -0
- physicskit/statphys/core/md_engine.py +157 -0
- physicskit/statphys/core/monte_carlo.py +462 -0
- physicskit/statphys/core/random_walk_engine.py +68 -0
- physicskit/statphys/core/sandpile_engine.py +52 -0
- physicskit/statphys/tests/__init__.py +0 -0
- physicskit/statphys/tests/test_dynamics.py +66 -0
- physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
- physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
- physicskit/statphys/tests/test_interactive.py +33 -0
- physicskit/statphys/tests/test_ising.py +68 -0
- physicskit/statphys/tests/test_kpz.py +55 -0
- physicskit/statphys/tests/test_landau_theory.py +49 -0
- physicskit/statphys/tests/test_md_engine.py +31 -0
- physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
- physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
- physicskit/statphys/tests/test_partition_function.py +26 -0
- physicskit/statphys/tests/test_percolation.py +116 -0
- physicskit/statphys/tests/test_potts_model.py +46 -0
- physicskit/statphys/tests/test_random_walk.py +50 -0
- physicskit/statphys/tests/test_renormalization.py +44 -0
- physicskit/statphys/tests/test_sandpile.py +44 -0
- physicskit/statphys/tests/test_spin_glass.py +73 -0
- physicskit/statphys/tests/test_thermodynamics.py +121 -0
- physicskit/statphys/tests/test_xy_model.py +45 -0
- physicskit/statphys/utils/__init__.py +1 -0
- physicskit/statphys/utils/dynamics.py +100 -0
- physicskit/statphys/utils/finite_size_scaling.py +171 -0
- physicskit/statphys/utils/landau_theory.py +151 -0
- physicskit/statphys/utils/partition_function.py +109 -0
- physicskit/statphys/utils/thermodynamics.py +356 -0
- physicskit/statphys/visualizers/__init__.py +87 -0
- physicskit/statphys/visualizers/interactive.py +161 -0
- physicskit/statphys/visualizers/jarzynski_render.py +44 -0
- physicskit/statphys/visualizers/kpz_render.py +65 -0
- physicskit/statphys/visualizers/lattice_render.py +212 -0
- physicskit/statphys/visualizers/particle_render.py +121 -0
- physicskit/statphys/visualizers/random_walk_render.py +106 -0
- physicskit/statphys/visualizers/rg_render.py +45 -0
- physicskit/statphys/visualizers/sandpile_render.py +65 -0
- physicskit/statphys/visualizers/spin_glass_render.py +40 -0
- physicskit/statphys/visualizers/urn_render.py +38 -0
- physicskit/statphys/visualizers/vortex_render.py +84 -0
- physicskit/tests/__init__.py +0 -0
- physicskit/tests/test_constants.py +38 -0
- physicskit-0.1.0.dist-info/METADATA +196 -0
- physicskit-0.1.0.dist-info/RECORD +484 -0
- physicskit-0.1.0.dist-info/WHEEL +5 -0
- physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
- physicskit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
r"""Direct-summation N-body gravitational dynamics.
|
|
2
|
+
|
|
3
|
+
Uses **gravitational units with** :math:`G=1` by default -- every function
|
|
4
|
+
accepts ``G`` as a keyword argument, the same convention
|
|
5
|
+
:mod:`physicskit.relativity` uses for its own geometrized units.
|
|
6
|
+
|
|
7
|
+
- :func:`gravitational_acceleration` -- pairwise Plummer-softened gravity.
|
|
8
|
+
- :func:`leapfrog_step` -- one symplectic kick-drift-kick integration step.
|
|
9
|
+
- :class:`NBodySystem` -- a stateful N-body simulation with energy and
|
|
10
|
+
angular-momentum diagnostics.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import numpy as np
|
|
16
|
+
from numba import njit
|
|
17
|
+
|
|
18
|
+
from physicskit.integrators.fixed_step import leapfrog_step as _leapfrog_step
|
|
19
|
+
|
|
20
|
+
__all__ = ["gravitational_acceleration", "leapfrog_step", "NBodySystem", "figure_eight_initial_conditions"]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@njit(cache=True)
|
|
24
|
+
def _pairwise_acceleration(positions, masses, G, softening):
|
|
25
|
+
n = positions.shape[0]
|
|
26
|
+
acc = np.zeros((n, 3))
|
|
27
|
+
eps2 = softening**2
|
|
28
|
+
for i in range(n):
|
|
29
|
+
ax, ay, az = 0.0, 0.0, 0.0
|
|
30
|
+
for j in range(n):
|
|
31
|
+
if i == j:
|
|
32
|
+
continue
|
|
33
|
+
dx = positions[j, 0] - positions[i, 0]
|
|
34
|
+
dy = positions[j, 1] - positions[i, 1]
|
|
35
|
+
dz = positions[j, 2] - positions[i, 2]
|
|
36
|
+
dist2 = dx * dx + dy * dy + dz * dz + eps2
|
|
37
|
+
inv_dist3 = dist2 ** (-1.5)
|
|
38
|
+
f = G * masses[j] * inv_dist3
|
|
39
|
+
ax += f * dx
|
|
40
|
+
ay += f * dy
|
|
41
|
+
az += f * dz
|
|
42
|
+
acc[i, 0] = ax
|
|
43
|
+
acc[i, 1] = ay
|
|
44
|
+
acc[i, 2] = az
|
|
45
|
+
return acc
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def gravitational_acceleration(positions, masses, G=1.0, softening=0.0):
|
|
49
|
+
r"""Pairwise Plummer-softened gravitational acceleration.
|
|
50
|
+
|
|
51
|
+
.. math::
|
|
52
|
+
|
|
53
|
+
\vec a_i = G\sum_{j\neq i} m_j\,
|
|
54
|
+
\frac{\vec r_j-\vec r_i}{\left(|\vec r_j-\vec r_i|^2+\epsilon^2\right)^{3/2}}
|
|
55
|
+
|
|
56
|
+
Parameters
|
|
57
|
+
----------
|
|
58
|
+
positions : ndarray of shape (N, 3)
|
|
59
|
+
masses : ndarray of shape (N,)
|
|
60
|
+
G : float, default=1.0
|
|
61
|
+
softening : float, default=0.0
|
|
62
|
+
Plummer softening length :math:`\epsilon`.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
ndarray of shape (N, 3)
|
|
67
|
+
|
|
68
|
+
Examples
|
|
69
|
+
--------
|
|
70
|
+
>>> import numpy as np
|
|
71
|
+
>>> pos = np.array([[0.0, 0.0, 0.0], [1.0, 0.0, 0.0]])
|
|
72
|
+
>>> m = np.array([1.0, 1.0])
|
|
73
|
+
>>> acc = gravitational_acceleration(pos, m)
|
|
74
|
+
>>> round(float(acc[0, 0]), 6)
|
|
75
|
+
1.0
|
|
76
|
+
"""
|
|
77
|
+
positions = np.ascontiguousarray(positions, dtype=np.float64)
|
|
78
|
+
masses = np.ascontiguousarray(masses, dtype=np.float64)
|
|
79
|
+
return _pairwise_acceleration(positions, masses, float(G), float(softening))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@njit(cache=True)
|
|
83
|
+
def _nbody_accel(positions, t, params):
|
|
84
|
+
"""Adapt :func:`_pairwise_acceleration` to the shared ``force(pos, t,
|
|
85
|
+
params) -> acc`` convention, packing ``masses``, ``G`` and ``softening``
|
|
86
|
+
into a single ``params`` vector (``masses`` followed by ``[G,
|
|
87
|
+
softening]``) so it can be passed as a first-class function into
|
|
88
|
+
:func:`physicskit.integrators.leapfrog_step`."""
|
|
89
|
+
n = positions.shape[0]
|
|
90
|
+
masses = params[:n]
|
|
91
|
+
G = params[n]
|
|
92
|
+
softening = params[n + 1]
|
|
93
|
+
return _pairwise_acceleration(positions, masses, G, softening)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def leapfrog_step(positions, velocities, masses, dt, G=1.0, softening=0.0):
|
|
97
|
+
"""One kick-drift-kick leapfrog (symplectic) integration step.
|
|
98
|
+
|
|
99
|
+
Delegates to the shared :func:`physicskit.integrators.leapfrog_step`.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
positions : ndarray of shape (N, 3)
|
|
104
|
+
velocities : ndarray of shape (N, 3)
|
|
105
|
+
masses : ndarray of shape (N,)
|
|
106
|
+
dt : float
|
|
107
|
+
Timestep.
|
|
108
|
+
G : float, default=1.0
|
|
109
|
+
softening : float, default=0.0
|
|
110
|
+
|
|
111
|
+
Returns
|
|
112
|
+
-------
|
|
113
|
+
new_positions, new_velocities : ndarray of shape (N, 3)
|
|
114
|
+
"""
|
|
115
|
+
positions = np.ascontiguousarray(positions, dtype=np.float64)
|
|
116
|
+
velocities = np.ascontiguousarray(velocities, dtype=np.float64)
|
|
117
|
+
masses = np.ascontiguousarray(masses, dtype=np.float64)
|
|
118
|
+
params = np.concatenate((masses, np.array([G, softening], dtype=np.float64)))
|
|
119
|
+
return _leapfrog_step(_nbody_accel, positions, velocities, 0.0, dt, params)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
class NBodySystem:
|
|
123
|
+
"""A stateful direct-summation N-body gravitational simulation.
|
|
124
|
+
|
|
125
|
+
Parameters
|
|
126
|
+
----------
|
|
127
|
+
positions : ndarray of shape (N, 3)
|
|
128
|
+
velocities : ndarray of shape (N, 3)
|
|
129
|
+
masses : ndarray of shape (N,)
|
|
130
|
+
G : float, default=1.0
|
|
131
|
+
softening : float, default=0.0
|
|
132
|
+
"""
|
|
133
|
+
|
|
134
|
+
def __init__(self, positions, velocities, masses, G=1.0, softening=0.0):
|
|
135
|
+
self.positions = np.array(positions, dtype=np.float64, copy=True)
|
|
136
|
+
self.velocities = np.array(velocities, dtype=np.float64, copy=True)
|
|
137
|
+
self.masses = np.array(masses, dtype=np.float64, copy=True)
|
|
138
|
+
self.G = G
|
|
139
|
+
self.softening = softening
|
|
140
|
+
|
|
141
|
+
def step(self, dt):
|
|
142
|
+
"""Advance the system's stored state by one leapfrog step, in place."""
|
|
143
|
+
self.positions, self.velocities = leapfrog_step(self.positions, self.velocities, self.masses, dt, self.G, self.softening)
|
|
144
|
+
|
|
145
|
+
def simulate(self, dt, n_steps):
|
|
146
|
+
"""Advance ``n_steps`` steps, returning the position history.
|
|
147
|
+
|
|
148
|
+
Returns
|
|
149
|
+
-------
|
|
150
|
+
ndarray of shape (n_steps + 1, N, 3)
|
|
151
|
+
"""
|
|
152
|
+
n = self.positions.shape[0]
|
|
153
|
+
history = np.zeros((n_steps + 1, n, 3))
|
|
154
|
+
history[0] = self.positions
|
|
155
|
+
for k in range(n_steps):
|
|
156
|
+
self.step(dt)
|
|
157
|
+
history[k + 1] = self.positions
|
|
158
|
+
return history
|
|
159
|
+
|
|
160
|
+
def total_energy(self):
|
|
161
|
+
r"""Kinetic plus (softened) gravitational potential energy, at the current state."""
|
|
162
|
+
kinetic = 0.5 * np.sum(self.masses[:, None] * self.velocities**2)
|
|
163
|
+
n = self.positions.shape[0]
|
|
164
|
+
potential = 0.0
|
|
165
|
+
eps2 = self.softening**2
|
|
166
|
+
for i in range(n):
|
|
167
|
+
for j in range(i + 1, n):
|
|
168
|
+
d = np.linalg.norm(self.positions[i] - self.positions[j])
|
|
169
|
+
potential -= self.G * self.masses[i] * self.masses[j] / np.sqrt(d**2 + eps2)
|
|
170
|
+
return float(kinetic + potential)
|
|
171
|
+
|
|
172
|
+
def total_angular_momentum(self):
|
|
173
|
+
r"""Total angular momentum, :math:`\vec L=\sum_im_i\,\vec r_i\times\vec v_i`."""
|
|
174
|
+
L = np.sum(self.masses[:, None] * np.cross(self.positions, self.velocities), axis=0)
|
|
175
|
+
return L
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def figure_eight_initial_conditions():
|
|
179
|
+
r"""Initial conditions for the equal-mass planar figure-eight three-body choreography.
|
|
180
|
+
|
|
181
|
+
Three equal masses, in :math:`G=1` units, chase each other forever
|
|
182
|
+
around a single figure-eight-shaped curve -- a periodic solution
|
|
183
|
+
discovered numerically by Moore (1993) and proven to exist by
|
|
184
|
+
Chenciner & Montgomery (2000, *Annals of Mathematics* 152). Unlike
|
|
185
|
+
typical three-body configurations it is planar, collision-free, and
|
|
186
|
+
exactly periodic, making it a clean, visually striking demo for
|
|
187
|
+
:class:`NBodySystem`.
|
|
188
|
+
|
|
189
|
+
Returns
|
|
190
|
+
-------
|
|
191
|
+
positions : ndarray of shape (3, 3)
|
|
192
|
+
velocities : ndarray of shape (3, 3)
|
|
193
|
+
masses : ndarray of shape (3,)
|
|
194
|
+
|
|
195
|
+
Examples
|
|
196
|
+
--------
|
|
197
|
+
>>> positions, velocities, masses = figure_eight_initial_conditions()
|
|
198
|
+
>>> system = NBodySystem(positions, velocities, masses)
|
|
199
|
+
>>> history = system.simulate(dt=0.001, n_steps=100)
|
|
200
|
+
>>> history.shape
|
|
201
|
+
(101, 3, 3)
|
|
202
|
+
"""
|
|
203
|
+
r1 = np.array([0.9700436, -0.24308753, 0.0])
|
|
204
|
+
v3 = np.array([0.93240737, 0.86473146, 0.0])
|
|
205
|
+
positions = np.array([r1, -r1, [0.0, 0.0, 0.0]])
|
|
206
|
+
velocities = np.array([-0.5 * v3, -0.5 * v3, v3])
|
|
207
|
+
masses = np.array([1.0, 1.0, 1.0])
|
|
208
|
+
return positions, velocities, masses
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
r"""Two-body Keplerian orbital mechanics: elements, state vectors, and transfers.
|
|
2
|
+
|
|
3
|
+
Uses **gravitational units with** :math:`G=1` by default; the standard
|
|
4
|
+
gravitational parameter :math:`\mu=GM` appears directly as a function
|
|
5
|
+
argument, the normal convention in orbital mechanics regardless of unit
|
|
6
|
+
system (the same style :mod:`physicskit.relativity` uses for its own
|
|
7
|
+
geometrized units).
|
|
8
|
+
|
|
9
|
+
- :func:`orbital_period`, :func:`vis_viva_speed` -- Kepler's third law and
|
|
10
|
+
the vis-viva equation.
|
|
11
|
+
- :func:`orbital_elements_from_state`, :func:`state_from_orbital_elements`
|
|
12
|
+
-- converting between Cartesian state vectors and the six classical
|
|
13
|
+
orbital elements.
|
|
14
|
+
- :func:`hohmann_transfer` -- the two-burn transfer between circular orbits.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import numpy as np
|
|
20
|
+
|
|
21
|
+
__all__ = [
|
|
22
|
+
"orbital_period",
|
|
23
|
+
"vis_viva_speed",
|
|
24
|
+
"orbital_elements_from_state",
|
|
25
|
+
"state_from_orbital_elements",
|
|
26
|
+
"hohmann_transfer",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def orbital_period(a, mu):
|
|
31
|
+
r"""Kepler's third law, :math:`T=2\pi\sqrt{a^3/\mu}`.
|
|
32
|
+
|
|
33
|
+
Parameters
|
|
34
|
+
----------
|
|
35
|
+
a : float
|
|
36
|
+
Semi-major axis (bound orbit, ``a > 0``).
|
|
37
|
+
mu : float
|
|
38
|
+
Gravitational parameter, :math:`\mu=GM`.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
float
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
--------
|
|
46
|
+
>>> round(orbital_period(1.0, 1.0) / (2 * np.pi), 6)
|
|
47
|
+
1.0
|
|
48
|
+
"""
|
|
49
|
+
return float(2.0 * np.pi * np.sqrt(a**3 / mu))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def vis_viva_speed(r, a, mu):
|
|
53
|
+
r"""The vis-viva equation, :math:`v=\sqrt{\mu\left(2/r-1/a\right)}`.
|
|
54
|
+
|
|
55
|
+
Works for ``a > 0`` (ellipse), ``a < 0`` (hyperbola), and ``a = inf``
|
|
56
|
+
(parabolic escape trajectory, where the formula reduces to
|
|
57
|
+
:math:`v=\sqrt{2\mu/r}`).
|
|
58
|
+
|
|
59
|
+
Parameters
|
|
60
|
+
----------
|
|
61
|
+
r : float
|
|
62
|
+
Current orbital radius.
|
|
63
|
+
a : float
|
|
64
|
+
Semi-major axis.
|
|
65
|
+
mu : float
|
|
66
|
+
Gravitational parameter.
|
|
67
|
+
|
|
68
|
+
Returns
|
|
69
|
+
-------
|
|
70
|
+
float
|
|
71
|
+
|
|
72
|
+
Examples
|
|
73
|
+
--------
|
|
74
|
+
>>> round(vis_viva_speed(1.0, np.inf, 1.0), 6)
|
|
75
|
+
1.414214
|
|
76
|
+
"""
|
|
77
|
+
return float(np.sqrt(mu * (2.0 / r - 1.0 / a)))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def orbital_elements_from_state(r_vec, v_vec, mu):
|
|
81
|
+
r"""Classical (Keplerian) orbital elements from a Cartesian state vector.
|
|
82
|
+
|
|
83
|
+
Returns semi-major axis, eccentricity, inclination, right ascension of
|
|
84
|
+
the ascending node, argument of periapsis, and true anomaly (angles
|
|
85
|
+
in radians). For a near-equatorial orbit (:math:`i\approx0` or
|
|
86
|
+
:math:`\pi`), the node vector is near zero and ``raan`` is undefined;
|
|
87
|
+
this implementation returns ``raan=0.0`` in that case rather than
|
|
88
|
+
raising -- a documented simplification, not a fully general
|
|
89
|
+
equatorial-orbit treatment.
|
|
90
|
+
|
|
91
|
+
Parameters
|
|
92
|
+
----------
|
|
93
|
+
r_vec, v_vec : ndarray of shape (3,)
|
|
94
|
+
Position and velocity.
|
|
95
|
+
mu : float
|
|
96
|
+
Gravitational parameter.
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
a, e, i, raan, argp, nu : float
|
|
101
|
+
|
|
102
|
+
Examples
|
|
103
|
+
--------
|
|
104
|
+
>>> r_vec, v_vec = state_from_orbital_elements(1.0, 0.3, 0.5, 1.0, 0.7, 1.2, mu=1.0)
|
|
105
|
+
>>> a, e, i, raan, argp, nu = orbital_elements_from_state(r_vec, v_vec, mu=1.0)
|
|
106
|
+
>>> [round(x, 6) for x in (a, e, i, raan, argp, nu)]
|
|
107
|
+
[1.0, 0.3, 0.5, 1.0, 0.7, 1.2]
|
|
108
|
+
"""
|
|
109
|
+
r_vec = np.asarray(r_vec, dtype=float)
|
|
110
|
+
v_vec = np.asarray(v_vec, dtype=float)
|
|
111
|
+
r = np.linalg.norm(r_vec)
|
|
112
|
+
v = np.linalg.norm(v_vec)
|
|
113
|
+
|
|
114
|
+
h_vec = np.cross(r_vec, v_vec)
|
|
115
|
+
h = np.linalg.norm(h_vec)
|
|
116
|
+
n_vec = np.cross([0.0, 0.0, 1.0], h_vec)
|
|
117
|
+
n = np.linalg.norm(n_vec)
|
|
118
|
+
e_vec = np.cross(v_vec, h_vec) / mu - r_vec / r
|
|
119
|
+
e = np.linalg.norm(e_vec)
|
|
120
|
+
|
|
121
|
+
energy = v**2 / 2.0 - mu / r
|
|
122
|
+
a = np.inf if abs(e - 1.0) < 1e-12 else -mu / (2.0 * energy)
|
|
123
|
+
|
|
124
|
+
i = float(np.arccos(np.clip(h_vec[2] / h, -1.0, 1.0)))
|
|
125
|
+
|
|
126
|
+
if n > 1e-12:
|
|
127
|
+
raan = float(np.arccos(np.clip(n_vec[0] / n, -1.0, 1.0)))
|
|
128
|
+
if n_vec[1] < 0:
|
|
129
|
+
raan = 2 * np.pi - raan
|
|
130
|
+
else:
|
|
131
|
+
raan = 0.0
|
|
132
|
+
|
|
133
|
+
if n > 1e-12 and e > 1e-12:
|
|
134
|
+
argp = float(np.arccos(np.clip(np.dot(n_vec, e_vec) / (n * e), -1.0, 1.0)))
|
|
135
|
+
if e_vec[2] < 0:
|
|
136
|
+
argp = 2 * np.pi - argp
|
|
137
|
+
else:
|
|
138
|
+
argp = 0.0
|
|
139
|
+
|
|
140
|
+
if e > 1e-12:
|
|
141
|
+
nu = float(np.arccos(np.clip(np.dot(e_vec, r_vec) / (e * r), -1.0, 1.0)))
|
|
142
|
+
if np.dot(r_vec, v_vec) < 0:
|
|
143
|
+
nu = 2 * np.pi - nu
|
|
144
|
+
else:
|
|
145
|
+
nu = 0.0
|
|
146
|
+
|
|
147
|
+
return float(a), float(e), i, raan, argp, nu
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def state_from_orbital_elements(a, e, i, raan, argp, nu, mu):
|
|
151
|
+
"""The inverse of :func:`orbital_elements_from_state`.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
a, e, i, raan, argp, nu : float
|
|
156
|
+
Classical orbital elements (angles in radians).
|
|
157
|
+
mu : float
|
|
158
|
+
Gravitational parameter.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
r_vec, v_vec : ndarray of shape (3,)
|
|
163
|
+
"""
|
|
164
|
+
p = a * (1.0 - e**2)
|
|
165
|
+
r = p / (1.0 + e * np.cos(nu))
|
|
166
|
+
r_pf = np.array([r * np.cos(nu), r * np.sin(nu), 0.0])
|
|
167
|
+
v_pf = np.sqrt(mu / p) * np.array([-np.sin(nu), e + np.cos(nu), 0.0])
|
|
168
|
+
|
|
169
|
+
cO, sO = np.cos(raan), np.sin(raan)
|
|
170
|
+
ci, si = np.cos(i), np.sin(i)
|
|
171
|
+
cw, sw = np.cos(argp), np.sin(argp)
|
|
172
|
+
|
|
173
|
+
# 3-1-3 Euler rotation (raan, i, argp): perifocal -> reference frame.
|
|
174
|
+
R = np.array(
|
|
175
|
+
[
|
|
176
|
+
[cO * cw - sO * sw * ci, -cO * sw - sO * cw * ci, sO * si],
|
|
177
|
+
[sO * cw + cO * sw * ci, -sO * sw + cO * cw * ci, -cO * si],
|
|
178
|
+
[sw * si, cw * si, ci],
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
return R @ r_pf, R @ v_pf
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def hohmann_transfer(r1, r2, mu):
|
|
185
|
+
r"""The two burns and transfer time for a Hohmann transfer.
|
|
186
|
+
|
|
187
|
+
Parameters
|
|
188
|
+
----------
|
|
189
|
+
r1 : float
|
|
190
|
+
Initial circular orbit radius.
|
|
191
|
+
r2 : float
|
|
192
|
+
Final circular orbit radius.
|
|
193
|
+
mu : float
|
|
194
|
+
Gravitational parameter.
|
|
195
|
+
|
|
196
|
+
Returns
|
|
197
|
+
-------
|
|
198
|
+
delta_v1 : float
|
|
199
|
+
Speed change (magnitude) to leave the initial circular orbit and
|
|
200
|
+
enter the transfer ellipse.
|
|
201
|
+
delta_v2 : float
|
|
202
|
+
Speed change (magnitude) to circularize at ``r2``.
|
|
203
|
+
transfer_time : float
|
|
204
|
+
Time to complete the transfer, half the transfer ellipse's period.
|
|
205
|
+
|
|
206
|
+
Examples
|
|
207
|
+
--------
|
|
208
|
+
>>> dv1, dv2, t = hohmann_transfer(1.0, 4.0, mu=1.0)
|
|
209
|
+
>>> dv1 > 0 and dv2 > 0 and t > 0
|
|
210
|
+
True
|
|
211
|
+
"""
|
|
212
|
+
a_t = (r1 + r2) / 2.0
|
|
213
|
+
v1_circular = vis_viva_speed(r1, r1, mu)
|
|
214
|
+
v1_transfer = vis_viva_speed(r1, a_t, mu)
|
|
215
|
+
v2_transfer = vis_viva_speed(r2, a_t, mu)
|
|
216
|
+
v2_circular = vis_viva_speed(r2, r2, mu)
|
|
217
|
+
delta_v1 = abs(v1_transfer - v1_circular)
|
|
218
|
+
delta_v2 = abs(v2_circular - v2_transfer)
|
|
219
|
+
transfer_time = orbital_period(a_t, mu) / 2.0
|
|
220
|
+
return float(delta_v1), float(delta_v2), float(transfer_time)
|