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,503 @@
|
|
|
1
|
+
"""Plotting helpers for electrodynamics, soliton, and BEC fields.
|
|
2
|
+
|
|
3
|
+
Every function returns its figure object rather than calling ``show()``.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
import numpy as np
|
|
10
|
+
from matplotlib.animation import FuncAnimation
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"plot_field_1d",
|
|
14
|
+
"plot_poynting_field",
|
|
15
|
+
"plot_bec_density",
|
|
16
|
+
"plot_bec_phase",
|
|
17
|
+
"animate_field_1d",
|
|
18
|
+
"animate_field_2d",
|
|
19
|
+
"animate_density_2d",
|
|
20
|
+
"animate_flux_tube",
|
|
21
|
+
"animate_casimir_modes",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def plot_field_1d(x: np.ndarray, u: np.ndarray, ax=None, label: str | None = None):
|
|
26
|
+
"""Plot a 1D field snapshot (a KdV, NLS envelope, or Sine-Gordon profile).
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
x : ndarray
|
|
31
|
+
Spatial grid.
|
|
32
|
+
u : ndarray
|
|
33
|
+
Field values (real; pass ``numpy.abs(psi)`` for a complex envelope).
|
|
34
|
+
ax : matplotlib.axes.Axes, optional
|
|
35
|
+
Axes to draw into; a new figure is created if omitted.
|
|
36
|
+
label : str, optional
|
|
37
|
+
Legend label for this trace.
|
|
38
|
+
|
|
39
|
+
Returns
|
|
40
|
+
-------
|
|
41
|
+
fig : matplotlib.figure.Figure
|
|
42
|
+
ax : matplotlib.axes.Axes
|
|
43
|
+
|
|
44
|
+
Examples
|
|
45
|
+
--------
|
|
46
|
+
>>> import numpy as np
|
|
47
|
+
>>> from physicskit.fields.solitons import kdv_soliton
|
|
48
|
+
>>> x = np.linspace(-20, 20, 200)
|
|
49
|
+
>>> fig, ax = plot_field_1d(x, kdv_soliton(x, c=4.0))
|
|
50
|
+
>>> isinstance(fig, plt.Figure)
|
|
51
|
+
True
|
|
52
|
+
"""
|
|
53
|
+
if ax is None:
|
|
54
|
+
fig, ax = plt.subplots()
|
|
55
|
+
else:
|
|
56
|
+
fig = ax.figure
|
|
57
|
+
ax.plot(x, u, label=label)
|
|
58
|
+
ax.set_xlabel("x")
|
|
59
|
+
if label is not None:
|
|
60
|
+
ax.legend()
|
|
61
|
+
return fig, ax
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def plot_poynting_field(X: np.ndarray, Y: np.ndarray, Sx: np.ndarray, Sy: np.ndarray, ax=None, stride: int = 4):
|
|
65
|
+
"""Quiver-plot the Poynting energy-flux field over a 2D grid.
|
|
66
|
+
|
|
67
|
+
Parameters
|
|
68
|
+
----------
|
|
69
|
+
X, Y : ndarray
|
|
70
|
+
Real-space coordinate grids.
|
|
71
|
+
Sx, Sy : ndarray
|
|
72
|
+
Poynting vector components, as from
|
|
73
|
+
:func:`physicskit.fields.electrodynamics.poynting_vector_tmz`.
|
|
74
|
+
ax : matplotlib.axes.Axes, optional
|
|
75
|
+
Axes to draw into; a new figure is created if omitted.
|
|
76
|
+
stride : int, default=4
|
|
77
|
+
Subsample every ``stride``-th grid point, to keep the quiver plot legible.
|
|
78
|
+
|
|
79
|
+
Returns
|
|
80
|
+
-------
|
|
81
|
+
fig : matplotlib.figure.Figure
|
|
82
|
+
ax : matplotlib.axes.Axes
|
|
83
|
+
|
|
84
|
+
Examples
|
|
85
|
+
--------
|
|
86
|
+
>>> import numpy as np
|
|
87
|
+
>>> X, Y = np.meshgrid(np.linspace(-1, 1, 20), np.linspace(-1, 1, 20))
|
|
88
|
+
>>> Sx, Sy = -Y, X
|
|
89
|
+
>>> fig, ax = plot_poynting_field(X, Y, Sx, Sy)
|
|
90
|
+
>>> isinstance(fig, plt.Figure)
|
|
91
|
+
True
|
|
92
|
+
"""
|
|
93
|
+
if ax is None:
|
|
94
|
+
fig, ax = plt.subplots()
|
|
95
|
+
else:
|
|
96
|
+
fig = ax.figure
|
|
97
|
+
sl = (slice(None, None, stride), slice(None, None, stride))
|
|
98
|
+
ax.quiver(X[sl], Y[sl], Sx[sl], Sy[sl])
|
|
99
|
+
ax.set_xlabel("x")
|
|
100
|
+
ax.set_ylabel("y")
|
|
101
|
+
ax.set_aspect("equal")
|
|
102
|
+
return fig, ax
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def plot_bec_density(X: np.ndarray, Y: np.ndarray, psi: np.ndarray, ax=None):
|
|
106
|
+
"""Plot the condensate density :math:`|\\psi(\\mathbf{r})|^2` as a heatmap.
|
|
107
|
+
|
|
108
|
+
Parameters
|
|
109
|
+
----------
|
|
110
|
+
X, Y : ndarray
|
|
111
|
+
Real-space coordinate grids.
|
|
112
|
+
psi : ndarray of complex
|
|
113
|
+
Condensate wavefunction.
|
|
114
|
+
ax : matplotlib.axes.Axes, optional
|
|
115
|
+
Axes to draw into; a new figure is created if omitted.
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
fig : matplotlib.figure.Figure
|
|
120
|
+
ax : matplotlib.axes.Axes
|
|
121
|
+
|
|
122
|
+
See Also
|
|
123
|
+
--------
|
|
124
|
+
plot_bec_phase : Plot the phase, which reveals vortex cores as singularities.
|
|
125
|
+
|
|
126
|
+
Examples
|
|
127
|
+
--------
|
|
128
|
+
>>> import numpy as np
|
|
129
|
+
>>> from physicskit.fields.quantum_fields import harmonic_trap_grid
|
|
130
|
+
>>> X, Y, KX, KY, K2 = harmonic_trap_grid(40, 10.0)
|
|
131
|
+
>>> psi = np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex)
|
|
132
|
+
>>> fig, ax = plot_bec_density(X, Y, psi)
|
|
133
|
+
>>> isinstance(fig, plt.Figure)
|
|
134
|
+
True
|
|
135
|
+
"""
|
|
136
|
+
if ax is None:
|
|
137
|
+
fig, ax = plt.subplots()
|
|
138
|
+
else:
|
|
139
|
+
fig = ax.figure
|
|
140
|
+
im = ax.pcolormesh(X, Y, np.abs(psi) ** 2, cmap="viridis", shading="auto")
|
|
141
|
+
fig.colorbar(im, ax=ax, label=r"$|\psi|^2$")
|
|
142
|
+
ax.set_xlabel("x")
|
|
143
|
+
ax.set_ylabel("y")
|
|
144
|
+
ax.set_aspect("equal")
|
|
145
|
+
return fig, ax
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
def plot_bec_phase(X: np.ndarray, Y: np.ndarray, psi: np.ndarray, ax=None):
|
|
149
|
+
"""Plot the condensate phase :math:`\\arg\\psi(\\mathbf{r})`; vortex cores appear as :math:`2\\pi` singularities.
|
|
150
|
+
|
|
151
|
+
Parameters
|
|
152
|
+
----------
|
|
153
|
+
X, Y : ndarray
|
|
154
|
+
Real-space coordinate grids.
|
|
155
|
+
psi : ndarray of complex
|
|
156
|
+
Condensate wavefunction.
|
|
157
|
+
ax : matplotlib.axes.Axes, optional
|
|
158
|
+
Axes to draw into; a new figure is created if omitted.
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
fig : matplotlib.figure.Figure
|
|
163
|
+
ax : matplotlib.axes.Axes
|
|
164
|
+
|
|
165
|
+
See Also
|
|
166
|
+
--------
|
|
167
|
+
plot_bec_density : Plot the density, which shows vortex cores as zeros.
|
|
168
|
+
physicskit.fields.quantum_fields.count_vortices : Quantitative vortex detection.
|
|
169
|
+
|
|
170
|
+
Examples
|
|
171
|
+
--------
|
|
172
|
+
>>> import numpy as np
|
|
173
|
+
>>> from physicskit.fields.quantum_fields import harmonic_trap_grid, gpe_imprint_vortex
|
|
174
|
+
>>> X, Y, KX, KY, K2 = harmonic_trap_grid(40, 10.0)
|
|
175
|
+
>>> psi0 = np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex)
|
|
176
|
+
>>> psi = gpe_imprint_vortex(psi0, X, Y, [(0.0, 0.0)])
|
|
177
|
+
>>> fig, ax = plot_bec_phase(X, Y, psi)
|
|
178
|
+
>>> isinstance(fig, plt.Figure)
|
|
179
|
+
True
|
|
180
|
+
"""
|
|
181
|
+
if ax is None:
|
|
182
|
+
fig, ax = plt.subplots()
|
|
183
|
+
else:
|
|
184
|
+
fig = ax.figure
|
|
185
|
+
im = ax.pcolormesh(X, Y, np.angle(psi), cmap="twilight", vmin=-np.pi, vmax=np.pi, shading="auto")
|
|
186
|
+
fig.colorbar(im, ax=ax, label="phase (rad)")
|
|
187
|
+
ax.set_xlabel("x")
|
|
188
|
+
ax.set_ylabel("y")
|
|
189
|
+
ax.set_aspect("equal")
|
|
190
|
+
return fig, ax
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def animate_field_1d(x: np.ndarray, frames: np.ndarray, times: np.ndarray | None = None, interval: int = 50, ylabel: str = "u(x, t)", ax=None) -> FuncAnimation:
|
|
194
|
+
"""Animate a sequence of 1D field snapshots as a line plot.
|
|
195
|
+
|
|
196
|
+
Shared by the KdV, NLS, and Sine-Gordon evolvers: feed it the frames
|
|
197
|
+
from :func:`physicskit.fields.solitons.kdv_evolve_frames`,
|
|
198
|
+
:func:`~physicskit.fields.solitons.nls_evolve_frames`, or
|
|
199
|
+
:func:`~physicskit.fields.solitons.sine_gordon_evolve_frames`.
|
|
200
|
+
|
|
201
|
+
Parameters
|
|
202
|
+
----------
|
|
203
|
+
x : ndarray
|
|
204
|
+
Spatial grid.
|
|
205
|
+
frames : ndarray, shape (n_frames, len(x))
|
|
206
|
+
Field snapshots. Complex frames (an NLS wavefunction) are plotted
|
|
207
|
+
as :math:`|\\psi|`; real frames (KdV, Sine-Gordon) are plotted directly.
|
|
208
|
+
times : ndarray, optional
|
|
209
|
+
Time of each frame, shown in the title.
|
|
210
|
+
interval : int, default=50
|
|
211
|
+
Delay between frames, in milliseconds.
|
|
212
|
+
ylabel : str, default="u(x, t)"
|
|
213
|
+
Y-axis label.
|
|
214
|
+
ax : matplotlib.axes.Axes, optional
|
|
215
|
+
Axes to draw into; a new figure is created if omitted.
|
|
216
|
+
|
|
217
|
+
Returns
|
|
218
|
+
-------
|
|
219
|
+
matplotlib.animation.FuncAnimation
|
|
220
|
+
|
|
221
|
+
Examples
|
|
222
|
+
--------
|
|
223
|
+
>>> import numpy as np
|
|
224
|
+
>>> from physicskit.fields.solitons import kdv_soliton, kdv_evolve_frames
|
|
225
|
+
>>> x = np.linspace(-30, 30, 256, endpoint=False)
|
|
226
|
+
>>> frames, times = kdv_evolve_frames(kdv_soliton(x, c=4.0, x0=-15), x, dt=0.001, steps_per_frame=50, n_frames=3)
|
|
227
|
+
>>> anim = animate_field_1d(x, frames, times)
|
|
228
|
+
>>> isinstance(anim, FuncAnimation)
|
|
229
|
+
True
|
|
230
|
+
"""
|
|
231
|
+
if ax is None:
|
|
232
|
+
fig, ax = plt.subplots()
|
|
233
|
+
else:
|
|
234
|
+
fig = ax.figure
|
|
235
|
+
values = np.abs(frames) if np.iscomplexobj(frames) else np.asarray(frames)
|
|
236
|
+
ymin, ymax = values.min(), values.max()
|
|
237
|
+
pad = 0.1 * (ymax - ymin if ymax > ymin else 1.0)
|
|
238
|
+
(line,) = ax.plot(x, values[0])
|
|
239
|
+
ax.set_xlim(x.min(), x.max())
|
|
240
|
+
ax.set_ylim(ymin - pad, ymax + pad)
|
|
241
|
+
ax.set_xlabel("x")
|
|
242
|
+
ax.set_ylabel(ylabel)
|
|
243
|
+
|
|
244
|
+
def update(i):
|
|
245
|
+
line.set_ydata(values[i])
|
|
246
|
+
ax.set_title(f"t = {times[i]:.4g}" if times is not None else f"frame {i}")
|
|
247
|
+
return (line,)
|
|
248
|
+
|
|
249
|
+
return FuncAnimation(fig, update, frames=len(values), interval=interval, blit=False)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def animate_field_2d(
|
|
253
|
+
X: np.ndarray, Y: np.ndarray, frames: np.ndarray, times: np.ndarray | None = None, interval: int = 50, cmap: str = "RdBu_r", ax=None
|
|
254
|
+
) -> FuncAnimation:
|
|
255
|
+
"""Animate a sequence of 2D scalar field snapshots (e.g. FDTD ``Ez``) as an imshow heatmap.
|
|
256
|
+
|
|
257
|
+
Uses a diverging colormap centered at zero, symmetric about the
|
|
258
|
+
largest-magnitude value across all frames -- appropriate for an
|
|
259
|
+
oscillating field like ``Ez``, unlike the non-negative densities
|
|
260
|
+
handled by :func:`animate_density_2d`.
|
|
261
|
+
|
|
262
|
+
Parameters
|
|
263
|
+
----------
|
|
264
|
+
X, Y : ndarray
|
|
265
|
+
Real-space coordinate grids (used only for their extent).
|
|
266
|
+
frames : ndarray, shape (n_frames, Nx, Ny)
|
|
267
|
+
Field snapshots, e.g. from :func:`physicskit.fields.electrodynamics.fdtd_2d_tmz_evolve`.
|
|
268
|
+
times : ndarray, optional
|
|
269
|
+
Time of each frame, shown in the title.
|
|
270
|
+
interval : int, default=50
|
|
271
|
+
Delay between frames, in milliseconds.
|
|
272
|
+
cmap : str, default="RdBu_r"
|
|
273
|
+
Diverging colormap.
|
|
274
|
+
ax : matplotlib.axes.Axes, optional
|
|
275
|
+
Axes to draw into; a new figure is created if omitted.
|
|
276
|
+
|
|
277
|
+
Returns
|
|
278
|
+
-------
|
|
279
|
+
matplotlib.animation.FuncAnimation
|
|
280
|
+
|
|
281
|
+
Examples
|
|
282
|
+
--------
|
|
283
|
+
>>> import numpy as np
|
|
284
|
+
>>> from physicskit.fields.electrodynamics import (
|
|
285
|
+
... courant_limit_2d, fdtd_2d_tmz_evolve, oscillating_dipole_source)
|
|
286
|
+
>>> Nx, Ny = 30, 30
|
|
287
|
+
>>> x = np.arange(Nx) * 1e-3
|
|
288
|
+
>>> y = np.arange(Ny) * 1e-3
|
|
289
|
+
>>> X, Y = np.meshgrid(x, y, indexing="ij")
|
|
290
|
+
>>> Ez0 = Hx0 = Hy0 = np.zeros((Nx, Ny))
|
|
291
|
+
>>> eps_r = mu_r = np.ones((Nx, Ny))
|
|
292
|
+
>>> dt = 0.5 * courant_limit_2d(1e-3, 1e-3)
|
|
293
|
+
>>> source = oscillating_dipole_source(Nx // 2, Ny // 2, amplitude=1.0, freq=5e10)
|
|
294
|
+
>>> frames, times = fdtd_2d_tmz_evolve(Ez0, Hx0, Hy0, eps_r, mu_r, steps=10, dt=dt, dx=1e-3, dy=1e-3, source=source, snapshot_stride=2)
|
|
295
|
+
>>> anim = animate_field_2d(X, Y, frames, times)
|
|
296
|
+
>>> isinstance(anim, FuncAnimation)
|
|
297
|
+
True
|
|
298
|
+
"""
|
|
299
|
+
if ax is None:
|
|
300
|
+
fig, ax = plt.subplots()
|
|
301
|
+
else:
|
|
302
|
+
fig = ax.figure
|
|
303
|
+
vmax = np.max(np.abs(frames))
|
|
304
|
+
vmax = vmax if vmax > 0 else 1.0
|
|
305
|
+
extent = (X.min(), X.max(), Y.min(), Y.max())
|
|
306
|
+
im = ax.imshow(frames[0].T, extent=extent, origin="lower", cmap=cmap, vmin=-vmax, vmax=vmax, aspect="auto")
|
|
307
|
+
fig.colorbar(im, ax=ax, label="Ez")
|
|
308
|
+
ax.set_xlabel("x")
|
|
309
|
+
ax.set_ylabel("y")
|
|
310
|
+
|
|
311
|
+
def update(i):
|
|
312
|
+
im.set_data(frames[i].T)
|
|
313
|
+
ax.set_title(f"t = {times[i]:.3g}" if times is not None else f"frame {i}")
|
|
314
|
+
return (im,)
|
|
315
|
+
|
|
316
|
+
return FuncAnimation(fig, update, frames=len(frames), interval=interval, blit=False)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def animate_density_2d(
|
|
320
|
+
frames: np.ndarray, extent: tuple | None = None, times: np.ndarray | None = None, interval: int = 50, cmap: str = "viridis", ax=None
|
|
321
|
+
) -> FuncAnimation:
|
|
322
|
+
"""Animate a sequence of non-negative 2D density snapshots (e.g. BEC or flux-tube energy density) as an imshow heatmap.
|
|
323
|
+
|
|
324
|
+
Parameters
|
|
325
|
+
----------
|
|
326
|
+
frames : ndarray, shape (n_frames, Nx, Ny)
|
|
327
|
+
Snapshots. Complex frames (a wavefunction) are converted to
|
|
328
|
+
:math:`|\\psi|^2`; real frames are used directly as the density/energy map.
|
|
329
|
+
extent : tuple(float, float, float, float), optional
|
|
330
|
+
``(xmin, xmax, ymin, ymax)`` passed to ``imshow``; defaults to pixel indices.
|
|
331
|
+
times : ndarray, optional
|
|
332
|
+
Time (or other sweep parameter, e.g. propagation distance) of each frame.
|
|
333
|
+
interval : int, default=50
|
|
334
|
+
Delay between frames, in milliseconds.
|
|
335
|
+
cmap : str, default="viridis"
|
|
336
|
+
Colormap.
|
|
337
|
+
ax : matplotlib.axes.Axes, optional
|
|
338
|
+
Axes to draw into; a new figure is created if omitted.
|
|
339
|
+
|
|
340
|
+
Returns
|
|
341
|
+
-------
|
|
342
|
+
matplotlib.animation.FuncAnimation
|
|
343
|
+
|
|
344
|
+
Examples
|
|
345
|
+
--------
|
|
346
|
+
>>> import numpy as np
|
|
347
|
+
>>> from physicskit.fields.quantum_fields import harmonic_trap_grid, gpe_imprint_vortex, gpe_evolve
|
|
348
|
+
>>> n, length = 32, 12.0
|
|
349
|
+
>>> X, Y, KX, KY, K2 = harmonic_trap_grid(n, length)
|
|
350
|
+
>>> V = 0.5 * (X ** 2 + Y ** 2)
|
|
351
|
+
>>> psi0 = gpe_imprint_vortex(np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex), X, Y, [(1.0, 0.0)])
|
|
352
|
+
>>> frames, times = gpe_evolve(psi0, V, g=2.0, dt=1e-3, steps=20, K2=K2, snapshot_stride=5)
|
|
353
|
+
>>> anim = animate_density_2d(frames, times=times)
|
|
354
|
+
>>> isinstance(anim, FuncAnimation)
|
|
355
|
+
True
|
|
356
|
+
"""
|
|
357
|
+
if ax is None:
|
|
358
|
+
fig, ax = plt.subplots()
|
|
359
|
+
else:
|
|
360
|
+
fig = ax.figure
|
|
361
|
+
density = np.abs(frames) ** 2 if np.iscomplexobj(frames) else np.asarray(frames)
|
|
362
|
+
vmax = density.max()
|
|
363
|
+
vmax = vmax if vmax > 0 else 1.0
|
|
364
|
+
im = ax.imshow(density[0].T, extent=extent, origin="lower", cmap=cmap, vmin=0.0, vmax=vmax, aspect="auto")
|
|
365
|
+
fig.colorbar(im, ax=ax)
|
|
366
|
+
ax.set_xlabel("x")
|
|
367
|
+
ax.set_ylabel("y")
|
|
368
|
+
|
|
369
|
+
def update(i):
|
|
370
|
+
im.set_data(density[i].T)
|
|
371
|
+
ax.set_title(f"t = {times[i]:.3g}" if times is not None else f"frame {i}")
|
|
372
|
+
return (im,)
|
|
373
|
+
|
|
374
|
+
return FuncAnimation(fig, update, frames=len(density), interval=interval, blit=False)
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
def animate_flux_tube(shape: tuple, dx: float, dy: float, separations: np.ndarray, flux_quantum: float = 1.0, interval: int = 80, ax=None) -> FuncAnimation:
|
|
378
|
+
"""Animate the toy confinement flux tube stretching as two charges are pulled apart.
|
|
379
|
+
|
|
380
|
+
Builds a frame for each separation in ``separations`` via
|
|
381
|
+
:func:`physicskit.fields.electrodynamics.flux_tube_energy_density_2d`
|
|
382
|
+
and draws it as a heatmap with two markers tracking the charge
|
|
383
|
+
positions, so the confined-energy "tube" visibly stretches between them.
|
|
384
|
+
|
|
385
|
+
Parameters
|
|
386
|
+
----------
|
|
387
|
+
shape : tuple(int, int)
|
|
388
|
+
``(Nx, Ny)`` grid shape.
|
|
389
|
+
dx, dy : float
|
|
390
|
+
Grid spacing.
|
|
391
|
+
separations : ndarray
|
|
392
|
+
Sequence of charge separations to sweep over (the animation's "time" axis).
|
|
393
|
+
flux_quantum : float, default=1.0
|
|
394
|
+
Charge magnitude, as in :func:`~physicskit.fields.electrodynamics.flux_tube_field_1d`.
|
|
395
|
+
interval : int, default=80
|
|
396
|
+
Delay between frames, in milliseconds.
|
|
397
|
+
ax : matplotlib.axes.Axes, optional
|
|
398
|
+
Axes to draw into; a new figure is created if omitted.
|
|
399
|
+
|
|
400
|
+
Returns
|
|
401
|
+
-------
|
|
402
|
+
matplotlib.animation.FuncAnimation
|
|
403
|
+
|
|
404
|
+
Examples
|
|
405
|
+
--------
|
|
406
|
+
>>> import numpy as np
|
|
407
|
+
>>> anim = animate_flux_tube((120, 30), dx=0.2, dy=0.2, separations=np.linspace(4.0, 16.0, 5))
|
|
408
|
+
>>> isinstance(anim, FuncAnimation)
|
|
409
|
+
True
|
|
410
|
+
"""
|
|
411
|
+
from physicskit.fields.electrodynamics import flux_tube_energy_density_2d
|
|
412
|
+
|
|
413
|
+
if ax is None:
|
|
414
|
+
fig, ax = plt.subplots()
|
|
415
|
+
else:
|
|
416
|
+
fig = ax.figure
|
|
417
|
+
Nx, Ny = shape
|
|
418
|
+
x = (np.arange(Nx) - Nx // 2) * dx
|
|
419
|
+
y = (np.arange(Ny) - Ny // 2) * dy
|
|
420
|
+
extent = (x.min(), x.max(), y.min(), y.max())
|
|
421
|
+
frames = np.stack([flux_tube_energy_density_2d(shape, dx, dy, sep, flux_quantum) for sep in separations])
|
|
422
|
+
vmax = frames.max()
|
|
423
|
+
vmax = vmax if vmax > 0 else 1.0
|
|
424
|
+
im = ax.imshow(frames[0].T, extent=extent, origin="lower", cmap="magma", vmin=0.0, vmax=vmax, aspect="auto")
|
|
425
|
+
fig.colorbar(im, ax=ax, label="energy density")
|
|
426
|
+
(markers,) = ax.plot([], [], "o", color="cyan", markersize=8)
|
|
427
|
+
ax.set_xlabel("x")
|
|
428
|
+
ax.set_ylabel("y")
|
|
429
|
+
|
|
430
|
+
def update(i):
|
|
431
|
+
im.set_data(frames[i].T)
|
|
432
|
+
sep = separations[i]
|
|
433
|
+
markers.set_data([-sep / 2, sep / 2], [0.0, 0.0])
|
|
434
|
+
ax.set_title(f"separation = {sep:.2f}")
|
|
435
|
+
return im, markers
|
|
436
|
+
|
|
437
|
+
return FuncAnimation(fig, update, frames=len(separations), interval=interval, blit=False)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def animate_casimir_modes(d_values: np.ndarray, c: float = 1.0, n_show: int = 12, interval: int = 150) -> FuncAnimation:
|
|
441
|
+
"""Animate the discrete cavity mode spectrum and Casimir energy as the plate separation ``d`` is swept.
|
|
442
|
+
|
|
443
|
+
Left panel: the first ``n_show`` discrete mode frequencies
|
|
444
|
+
(:func:`physicskit.fields.quantum_fields.casimir_mode_frequencies`) as a
|
|
445
|
+
stem plot, against the continuum they approach at large ``d`` (dashed
|
|
446
|
+
line of slope :math:`\\pi c`) -- visibly denser (closer to the
|
|
447
|
+
continuum) at large separation. Right panel: the regularized Casimir
|
|
448
|
+
energy (:func:`physicskit.fields.quantum_fields.casimir_energy_1d`) as a
|
|
449
|
+
curve over the full sweep, with a marker tracking the current ``d``.
|
|
450
|
+
|
|
451
|
+
Parameters
|
|
452
|
+
----------
|
|
453
|
+
d_values : ndarray
|
|
454
|
+
Sequence of plate separations to sweep over (the animation's "time" axis).
|
|
455
|
+
c : float, default=1.0
|
|
456
|
+
Wave speed.
|
|
457
|
+
n_show : int, default=12
|
|
458
|
+
Number of discrete modes to show in the stem plot.
|
|
459
|
+
interval : int, default=150
|
|
460
|
+
Delay between frames, in milliseconds.
|
|
461
|
+
|
|
462
|
+
Returns
|
|
463
|
+
-------
|
|
464
|
+
matplotlib.animation.FuncAnimation
|
|
465
|
+
|
|
466
|
+
Examples
|
|
467
|
+
--------
|
|
468
|
+
>>> import numpy as np
|
|
469
|
+
>>> anim = animate_casimir_modes(np.linspace(1.0, 5.0, 5))
|
|
470
|
+
>>> isinstance(anim, FuncAnimation)
|
|
471
|
+
True
|
|
472
|
+
"""
|
|
473
|
+
from physicskit.fields.quantum_fields import casimir_energy_1d, casimir_mode_frequencies
|
|
474
|
+
|
|
475
|
+
fig, (ax_modes, ax_energy) = plt.subplots(1, 2, figsize=(10, 4))
|
|
476
|
+
n = np.arange(1, n_show + 1)
|
|
477
|
+
energies = np.array([casimir_energy_1d(d, c) for d in d_values])
|
|
478
|
+
|
|
479
|
+
ax_modes.set_xlim(0, n_show + 1)
|
|
480
|
+
ax_modes.set_ylim(0, np.pi * c * n_show / d_values.min() * 1.1)
|
|
481
|
+
ax_modes.set_xlabel("mode index n")
|
|
482
|
+
ax_modes.set_ylabel(r"$\omega_n$")
|
|
483
|
+
stem_container = ax_modes.stem(n, np.pi * c * n / d_values[0])
|
|
484
|
+
(continuum_line,) = ax_modes.plot(n, np.pi * c * n / d_values[0], "k--", alpha=0.4, label="continuum slope")
|
|
485
|
+
ax_modes.legend(loc="upper left")
|
|
486
|
+
|
|
487
|
+
ax_energy.plot(d_values, energies, color="C0")
|
|
488
|
+
(marker,) = ax_energy.plot([d_values[0]], [energies[0]], "o", color="C3", markersize=8)
|
|
489
|
+
ax_energy.set_xlabel("plate separation d")
|
|
490
|
+
ax_energy.set_ylabel("Casimir energy E(d)")
|
|
491
|
+
|
|
492
|
+
def update(i):
|
|
493
|
+
d = d_values[i]
|
|
494
|
+
omega = casimir_mode_frequencies(d, c, n_show)
|
|
495
|
+
stem_container.markerline.set_data(n, omega)
|
|
496
|
+
segments = [[[xi, 0], [xi, yi]] for xi, yi in zip(n, omega)]
|
|
497
|
+
stem_container.stemlines.set_segments(segments)
|
|
498
|
+
continuum_line.set_ydata(np.pi * c * n / d)
|
|
499
|
+
marker.set_data([d], [energies[i]])
|
|
500
|
+
fig.suptitle(f"d = {d:.3g}")
|
|
501
|
+
return stem_container.markerline, stem_container.stemlines, continuum_line, marker
|
|
502
|
+
|
|
503
|
+
return FuncAnimation(fig, update, frames=len(d_values), interval=interval, blit=False)
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"""physicskit.fluids: fluid dynamics from inviscid potential flow to compressible shocks.
|
|
2
|
+
|
|
3
|
+
Six physical regimes, each a module of :mod:`physicskit.fluids.systems`,
|
|
4
|
+
sharing the doubly-periodic pseudo-spectral grid and RK4 time-stepping core
|
|
5
|
+
in :mod:`physicskit.fluids.core` wherever a grid-based simulation is needed:
|
|
6
|
+
|
|
7
|
+
- :mod:`~physicskit.fluids.systems.potential_flow` -- inviscid, irrotational
|
|
8
|
+
flow built by superposing elementary solutions (uniform flow,
|
|
9
|
+
source/sink, doublet, point vortex), including flow past a cylinder with
|
|
10
|
+
lift.
|
|
11
|
+
- :mod:`~physicskit.fluids.systems.viscous_flow` -- classic exact viscous
|
|
12
|
+
solutions: Couette and Poiseuille flow, Stokes drag, and the Blasius
|
|
13
|
+
boundary layer.
|
|
14
|
+
- :mod:`~physicskit.fluids.systems.vortex_dynamics` -- point-vortex N-body
|
|
15
|
+
dynamics via the Biot-Savart law, and the von Karman vortex street.
|
|
16
|
+
- :mod:`~physicskit.fluids.systems.instabilities` -- the Kelvin-Helmholtz
|
|
17
|
+
and Rayleigh-Taylor instabilities, each with its linear growth-rate law
|
|
18
|
+
and a full nonlinear simulation.
|
|
19
|
+
- :mod:`~physicskit.fluids.systems.compressible_flow` -- the 1D Euler
|
|
20
|
+
equations, Rankine-Hugoniot shock relations, and the Sod shock tube.
|
|
21
|
+
- :mod:`~physicskit.fluids.systems.navier_stokes` -- the 2D incompressible
|
|
22
|
+
vorticity-streamfunction solver underlying the instability and
|
|
23
|
+
turbulence-spectrum tools.
|
|
24
|
+
|
|
25
|
+
Typical usage::
|
|
26
|
+
|
|
27
|
+
import physicskit as pk
|
|
28
|
+
import numpy as np
|
|
29
|
+
|
|
30
|
+
# Flow past a lifting cylinder:
|
|
31
|
+
flow = pk.fluids.flow_past_cylinder(U_inf=1.0, radius=1.0, circulation=4 * np.pi)
|
|
32
|
+
lift = pk.fluids.kutta_joukowski_lift(rho=1.2, U_inf=1.0, circulation=4 * np.pi)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
from physicskit.fluids.exceptions import FluidskitError, InvalidParameterError
|
|
36
|
+
from physicskit.fluids.systems.compressible_flow import (
|
|
37
|
+
normal_shock_relations,
|
|
38
|
+
rankine_hugoniot_jump_conditions,
|
|
39
|
+
sod_shock_tube,
|
|
40
|
+
)
|
|
41
|
+
from physicskit.fluids.systems.instabilities import (
|
|
42
|
+
kelvin_helmholtz_growth_rate,
|
|
43
|
+
kelvin_helmholtz_ic,
|
|
44
|
+
rayleigh_taylor_growth_rate,
|
|
45
|
+
rayleigh_taylor_ic,
|
|
46
|
+
simulate_rayleigh_taylor,
|
|
47
|
+
)
|
|
48
|
+
from physicskit.fluids.systems.navier_stokes import NavierStokes2D, simulate_vorticity_streamfunction
|
|
49
|
+
from physicskit.fluids.systems.potential_flow import (
|
|
50
|
+
PotentialFlow,
|
|
51
|
+
doublet_potential,
|
|
52
|
+
flow_past_cylinder,
|
|
53
|
+
kutta_joukowski_lift,
|
|
54
|
+
point_vortex_potential,
|
|
55
|
+
pressure_coefficient,
|
|
56
|
+
source_potential,
|
|
57
|
+
uniform_flow_potential,
|
|
58
|
+
)
|
|
59
|
+
from physicskit.fluids.systems.viscous_flow import (
|
|
60
|
+
blasius_boundary_layer_thickness,
|
|
61
|
+
blasius_skin_friction_coefficient,
|
|
62
|
+
blasius_solve,
|
|
63
|
+
couette_flow_velocity,
|
|
64
|
+
poiseuille_flow_rate,
|
|
65
|
+
poiseuille_flow_velocity,
|
|
66
|
+
stokes_drag,
|
|
67
|
+
)
|
|
68
|
+
from physicskit.fluids.systems.vortex_dynamics import (
|
|
69
|
+
VON_KARMAN_SPACING_RATIO,
|
|
70
|
+
PointVortexSystem,
|
|
71
|
+
point_vortex_velocities,
|
|
72
|
+
von_karman_vortex_street,
|
|
73
|
+
)
|
|
74
|
+
from physicskit.fluids.utils.dimensionless import (
|
|
75
|
+
froude_number,
|
|
76
|
+
mach_number,
|
|
77
|
+
reynolds_number,
|
|
78
|
+
strouhal_number,
|
|
79
|
+
weber_number,
|
|
80
|
+
)
|
|
81
|
+
from physicskit.fluids.utils.spectral_analysis import energy_spectrum, kolmogorov_reference_slope
|
|
82
|
+
from physicskit.fluids.visualizers.compressible import plot_shock_tube_profiles
|
|
83
|
+
from physicskit.fluids.visualizers.flow_fields import plot_streamlines, plot_vorticity_field
|
|
84
|
+
from physicskit.fluids.visualizers.potential_flow import plot_pressure_coefficient
|
|
85
|
+
from physicskit.fluids.visualizers.spectra import plot_energy_spectrum
|
|
86
|
+
|
|
87
|
+
__version__ = "0.1.0"
|
|
88
|
+
|
|
89
|
+
__all__ = [
|
|
90
|
+
"VON_KARMAN_SPACING_RATIO",
|
|
91
|
+
"FluidskitError",
|
|
92
|
+
"InvalidParameterError",
|
|
93
|
+
"NavierStokes2D",
|
|
94
|
+
"PointVortexSystem",
|
|
95
|
+
"PotentialFlow",
|
|
96
|
+
"blasius_boundary_layer_thickness",
|
|
97
|
+
"blasius_skin_friction_coefficient",
|
|
98
|
+
"blasius_solve",
|
|
99
|
+
"couette_flow_velocity",
|
|
100
|
+
"doublet_potential",
|
|
101
|
+
"energy_spectrum",
|
|
102
|
+
"flow_past_cylinder",
|
|
103
|
+
"froude_number",
|
|
104
|
+
"kelvin_helmholtz_growth_rate",
|
|
105
|
+
"kelvin_helmholtz_ic",
|
|
106
|
+
"kolmogorov_reference_slope",
|
|
107
|
+
"kutta_joukowski_lift",
|
|
108
|
+
"mach_number",
|
|
109
|
+
"normal_shock_relations",
|
|
110
|
+
"plot_energy_spectrum",
|
|
111
|
+
"plot_pressure_coefficient",
|
|
112
|
+
"plot_shock_tube_profiles",
|
|
113
|
+
"plot_streamlines",
|
|
114
|
+
"plot_vorticity_field",
|
|
115
|
+
"point_vortex_potential",
|
|
116
|
+
"point_vortex_velocities",
|
|
117
|
+
"poiseuille_flow_rate",
|
|
118
|
+
"poiseuille_flow_velocity",
|
|
119
|
+
"pressure_coefficient",
|
|
120
|
+
"rankine_hugoniot_jump_conditions",
|
|
121
|
+
"rayleigh_taylor_growth_rate",
|
|
122
|
+
"rayleigh_taylor_ic",
|
|
123
|
+
"reynolds_number",
|
|
124
|
+
"simulate_rayleigh_taylor",
|
|
125
|
+
"simulate_vorticity_streamfunction",
|
|
126
|
+
"sod_shock_tube",
|
|
127
|
+
"source_potential",
|
|
128
|
+
"stokes_drag",
|
|
129
|
+
"strouhal_number",
|
|
130
|
+
"uniform_flow_potential",
|
|
131
|
+
"von_karman_vortex_street",
|
|
132
|
+
"weber_number",
|
|
133
|
+
"__version__",
|
|
134
|
+
]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from physicskit.fluids.core.grid import (
|
|
2
|
+
poisson_solve_streamfunction,
|
|
3
|
+
spectral_grid,
|
|
4
|
+
velocity_from_streamfunction,
|
|
5
|
+
vorticity_from_velocity,
|
|
6
|
+
)
|
|
7
|
+
from physicskit.fluids.core.timestepping import (
|
|
8
|
+
buoyant_vorticity_rhs,
|
|
9
|
+
integrate_boussinesq,
|
|
10
|
+
integrate_vorticity_streamfunction,
|
|
11
|
+
vorticity_rhs,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"buoyant_vorticity_rhs",
|
|
16
|
+
"integrate_boussinesq",
|
|
17
|
+
"integrate_vorticity_streamfunction",
|
|
18
|
+
"poisson_solve_streamfunction",
|
|
19
|
+
"spectral_grid",
|
|
20
|
+
"velocity_from_streamfunction",
|
|
21
|
+
"vorticity_from_velocity",
|
|
22
|
+
"vorticity_rhs",
|
|
23
|
+
]
|