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,292 @@
|
|
|
1
|
+
r"""3D spherical harmonics and hydrogen-atom orbitals :math:`\lvert n,l,m\rangle`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from scipy.special import genlaguerre
|
|
9
|
+
|
|
10
|
+
from .._compat import sph_harm_y, trapz
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"spherical_harmonic",
|
|
14
|
+
"radial_wavefunction",
|
|
15
|
+
"HydrogenOrbital",
|
|
16
|
+
"orbital_superposition_psi",
|
|
17
|
+
"orbital_superposition_density",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
A0 = 1.0
|
|
21
|
+
"""float: Bohr radius, in atomic units (length measured in units of :math:`a_0`)."""
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def spherical_harmonic(l: int, m: int, theta: np.ndarray, phi: np.ndarray) -> np.ndarray:
|
|
25
|
+
r"""The spherical harmonic :math:`Y_l^m(\theta,\phi)`.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
l : int
|
|
30
|
+
Orbital angular momentum quantum number.
|
|
31
|
+
m : int
|
|
32
|
+
Magnetic quantum number (:math:`\lvert m\rvert \le l`).
|
|
33
|
+
theta : numpy.ndarray
|
|
34
|
+
Polar angle, in :math:`[0, \pi]`.
|
|
35
|
+
phi : numpy.ndarray
|
|
36
|
+
Azimuthal angle, in :math:`[0, 2\pi)`.
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
numpy.ndarray
|
|
41
|
+
Complex-valued :math:`Y_l^m(\theta,\phi)`.
|
|
42
|
+
"""
|
|
43
|
+
return sph_harm_y(l, m, theta, phi)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def radial_wavefunction(n: int, l: int, r: np.ndarray, Z: int = 1, a0: float = A0) -> np.ndarray:
|
|
47
|
+
r"""The hydrogenic radial wavefunction :math:`R_{nl}(r)`.
|
|
48
|
+
|
|
49
|
+
Normalized so that :math:`\int_0^\infty \lvert R_{nl}(r)\rvert^2 r^2\,dr = 1`.
|
|
50
|
+
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
n : int
|
|
54
|
+
Principal quantum number.
|
|
55
|
+
l : int
|
|
56
|
+
Orbital angular momentum quantum number (:math:`0 \le l < n`).
|
|
57
|
+
r : numpy.ndarray
|
|
58
|
+
Radii to evaluate at.
|
|
59
|
+
Z : int, default=1
|
|
60
|
+
Nuclear charge.
|
|
61
|
+
a0 : float, default=1.0
|
|
62
|
+
Bohr radius.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
numpy.ndarray
|
|
67
|
+
|
|
68
|
+
Raises
|
|
69
|
+
------
|
|
70
|
+
ValueError
|
|
71
|
+
If ``l >= n``.
|
|
72
|
+
"""
|
|
73
|
+
if l >= n:
|
|
74
|
+
raise ValueError("Require l < n.")
|
|
75
|
+
rho = 2 * Z * r / (n * a0)
|
|
76
|
+
L = genlaguerre(n - l - 1, 2 * l + 1)(rho)
|
|
77
|
+
from scipy.special import gammaln
|
|
78
|
+
|
|
79
|
+
log_norm = 1.5 * np.log(2 * Z / (n * a0)) + 0.5 * (gammaln(n - l) - np.log(2 * n) - gammaln(n + l + 1))
|
|
80
|
+
norm = np.exp(log_norm)
|
|
81
|
+
return norm * np.exp(-rho / 2) * rho**l * L
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@dataclass
|
|
85
|
+
class HydrogenOrbital:
|
|
86
|
+
r"""The hydrogenic wavefunction
|
|
87
|
+
:math:`\psi_{nlm}(r,\theta,\phi) = R_{nl}(r)\, Y_l^m(\theta,\phi)`.
|
|
88
|
+
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
n : int
|
|
92
|
+
Principal quantum number.
|
|
93
|
+
l : int
|
|
94
|
+
Orbital angular momentum quantum number (:math:`0 \le l < n`).
|
|
95
|
+
m : int
|
|
96
|
+
Magnetic quantum number (:math:`\lvert m\rvert \le l`).
|
|
97
|
+
Z : int, default=1
|
|
98
|
+
Nuclear charge.
|
|
99
|
+
a0 : float, default=1.0
|
|
100
|
+
Bohr radius.
|
|
101
|
+
|
|
102
|
+
Raises
|
|
103
|
+
------
|
|
104
|
+
ValueError
|
|
105
|
+
If the quantum numbers violate :math:`0 \le l < n` or
|
|
106
|
+
:math:`\lvert m\rvert \le l`.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
n: int
|
|
110
|
+
l: int
|
|
111
|
+
m: int
|
|
112
|
+
Z: int = 1
|
|
113
|
+
a0: float = A0
|
|
114
|
+
|
|
115
|
+
def __post_init__(self):
|
|
116
|
+
if not (0 <= self.l < self.n):
|
|
117
|
+
raise ValueError("Require 0 <= l < n.")
|
|
118
|
+
if abs(self.m) > self.l:
|
|
119
|
+
raise ValueError("Require |m| <= l.")
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def energy(self) -> float:
|
|
123
|
+
r"""float: Energy :math:`E_n = -Z^2/(2n^2)` Hartree (atomic units,
|
|
124
|
+
:math:`\hbar = m_e = e = 1`)."""
|
|
125
|
+
return -(self.Z**2) / (2 * self.n**2)
|
|
126
|
+
|
|
127
|
+
def radial(self, r: np.ndarray) -> np.ndarray:
|
|
128
|
+
"""The radial part :math:`R_{nl}(r)`; see :func:`radial_wavefunction`.
|
|
129
|
+
|
|
130
|
+
Parameters
|
|
131
|
+
----------
|
|
132
|
+
r : numpy.ndarray
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
numpy.ndarray
|
|
137
|
+
"""
|
|
138
|
+
return radial_wavefunction(self.n, self.l, r, self.Z, self.a0)
|
|
139
|
+
|
|
140
|
+
def angular(self, theta: np.ndarray, phi: np.ndarray) -> np.ndarray:
|
|
141
|
+
"""The angular part :math:`Y_l^m(\\theta,\\phi)`; see :func:`spherical_harmonic`.
|
|
142
|
+
|
|
143
|
+
Parameters
|
|
144
|
+
----------
|
|
145
|
+
theta, phi : numpy.ndarray
|
|
146
|
+
|
|
147
|
+
Returns
|
|
148
|
+
-------
|
|
149
|
+
numpy.ndarray
|
|
150
|
+
"""
|
|
151
|
+
return spherical_harmonic(self.l, self.m, theta, phi)
|
|
152
|
+
|
|
153
|
+
def psi(self, r: np.ndarray, theta: np.ndarray, phi: np.ndarray) -> np.ndarray:
|
|
154
|
+
r"""The full wavefunction :math:`\psi_{nlm}(r,\theta,\phi)`.
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
r, theta, phi : numpy.ndarray
|
|
159
|
+
|
|
160
|
+
Returns
|
|
161
|
+
-------
|
|
162
|
+
numpy.ndarray
|
|
163
|
+
Complex-valued.
|
|
164
|
+
"""
|
|
165
|
+
return self.radial(r) * self.angular(theta, phi)
|
|
166
|
+
|
|
167
|
+
def density(self, r: np.ndarray, theta: np.ndarray, phi: np.ndarray) -> np.ndarray:
|
|
168
|
+
r"""The probability density :math:`\lvert\psi_{nlm}\rvert^2`.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
r, theta, phi : numpy.ndarray
|
|
173
|
+
|
|
174
|
+
Returns
|
|
175
|
+
-------
|
|
176
|
+
numpy.ndarray
|
|
177
|
+
"""
|
|
178
|
+
return np.abs(self.psi(r, theta, phi)) ** 2
|
|
179
|
+
|
|
180
|
+
def radial_density(self, r: np.ndarray) -> np.ndarray:
|
|
181
|
+
r"""The radial probability density :math:`P(r) = r^2 \lvert R_{nl}(r)\rvert^2`.
|
|
182
|
+
|
|
183
|
+
The probability of finding the electron in a shell
|
|
184
|
+
:math:`[r, r+dr]`, already integrated over solid angle.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
r : numpy.ndarray
|
|
189
|
+
|
|
190
|
+
Returns
|
|
191
|
+
-------
|
|
192
|
+
numpy.ndarray
|
|
193
|
+
"""
|
|
194
|
+
return r**2 * np.abs(self.radial(r)) ** 2
|
|
195
|
+
|
|
196
|
+
def most_probable_radius(self, r_max: float | None = None, n_points: int = 20000) -> float:
|
|
197
|
+
"""The radius at which :meth:`radial_density` is maximal.
|
|
198
|
+
|
|
199
|
+
Parameters
|
|
200
|
+
----------
|
|
201
|
+
r_max : float or None, optional
|
|
202
|
+
Upper bound of the search range; defaults to a value scaled to
|
|
203
|
+
the orbital's expected extent.
|
|
204
|
+
n_points : int, default=20000
|
|
205
|
+
Number of grid points used for the search.
|
|
206
|
+
|
|
207
|
+
Returns
|
|
208
|
+
-------
|
|
209
|
+
float
|
|
210
|
+
"""
|
|
211
|
+
if r_max is None:
|
|
212
|
+
r_max = 4 * self.n**2 * self.a0 / self.Z + 10
|
|
213
|
+
r = np.linspace(1e-6, r_max, n_points)
|
|
214
|
+
P = self.radial_density(r)
|
|
215
|
+
return float(r[np.argmax(P)])
|
|
216
|
+
|
|
217
|
+
def check_normalization(self, r_max: float | None = None, n_points: int = 20000) -> float:
|
|
218
|
+
r"""Integrate :meth:`radial_density` over :math:`[0, r_\text{max}]` (should be 1).
|
|
219
|
+
|
|
220
|
+
Parameters
|
|
221
|
+
----------
|
|
222
|
+
r_max : float or None, optional
|
|
223
|
+
Upper integration limit; defaults to a value scaled to the
|
|
224
|
+
orbital's expected extent.
|
|
225
|
+
n_points : int, default=20000
|
|
226
|
+
Number of quadrature points.
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
float
|
|
231
|
+
"""
|
|
232
|
+
if r_max is None:
|
|
233
|
+
r_max = 6 * self.n**2 * self.a0 / self.Z + 20
|
|
234
|
+
r = np.linspace(1e-8, r_max, n_points)
|
|
235
|
+
return float(trapz(self.radial_density(r), r))
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def orbital_superposition_psi(
|
|
239
|
+
orb_a: HydrogenOrbital, orb_b: HydrogenOrbital, r: np.ndarray, theta: np.ndarray, phi: np.ndarray, t: float, ca: complex = 2**-0.5, cb: complex = 2**-0.5
|
|
240
|
+
) -> np.ndarray:
|
|
241
|
+
r"""A coherent superposition of two hydrogen eigenstates at time :math:`t`.
|
|
242
|
+
|
|
243
|
+
.. math::
|
|
244
|
+
|
|
245
|
+
\psi(t) = c_a\,\psi_a\, e^{-iE_a t} + c_b\,\psi_b\, e^{-iE_b t},
|
|
246
|
+
|
|
247
|
+
beating at the Bohr frequency :math:`\omega_{ab}=E_a-E_b` between the two
|
|
248
|
+
stationary densities -- genuine dynamics, unlike either eigenstate alone
|
|
249
|
+
(whose density is static).
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
orb_a, orb_b : HydrogenOrbital
|
|
254
|
+
The two eigenstates in the superposition (should differ in energy
|
|
255
|
+
for the beating to be visible).
|
|
256
|
+
r, theta, phi : numpy.ndarray
|
|
257
|
+
Coordinates to evaluate at (e.g. from a Cartesian grid, as in
|
|
258
|
+
:func:`~physicskit.quantum.visualizers.orbitals.orbital_density_grid`).
|
|
259
|
+
t : float
|
|
260
|
+
Time.
|
|
261
|
+
ca, cb : complex, default=1/sqrt(2) each
|
|
262
|
+
Superposition amplitudes (renormalized internally).
|
|
263
|
+
|
|
264
|
+
Returns
|
|
265
|
+
-------
|
|
266
|
+
numpy.ndarray
|
|
267
|
+
Complex-valued :math:`\psi(r,\theta,\phi,t)`.
|
|
268
|
+
"""
|
|
269
|
+
norm = np.sqrt(np.abs(ca) ** 2 + np.abs(cb) ** 2)
|
|
270
|
+
ca, cb = ca / norm, cb / norm
|
|
271
|
+
phase_a = np.exp(-1j * orb_a.energy * t)
|
|
272
|
+
phase_b = np.exp(-1j * orb_b.energy * t)
|
|
273
|
+
return ca * phase_a * orb_a.psi(r, theta, phi) + cb * phase_b * orb_b.psi(r, theta, phi)
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
def orbital_superposition_density(
|
|
277
|
+
orb_a: HydrogenOrbital, orb_b: HydrogenOrbital, r: np.ndarray, theta: np.ndarray, phi: np.ndarray, t: float, ca: complex = 2**-0.5, cb: complex = 2**-0.5
|
|
278
|
+
) -> np.ndarray:
|
|
279
|
+
r"""The probability density of :func:`orbital_superposition_psi`.
|
|
280
|
+
|
|
281
|
+
Parameters
|
|
282
|
+
----------
|
|
283
|
+
orb_a, orb_b : HydrogenOrbital
|
|
284
|
+
r, theta, phi : numpy.ndarray
|
|
285
|
+
t : float
|
|
286
|
+
ca, cb : complex, default=1/sqrt(2) each
|
|
287
|
+
|
|
288
|
+
Returns
|
|
289
|
+
-------
|
|
290
|
+
numpy.ndarray
|
|
291
|
+
"""
|
|
292
|
+
return np.abs(orbital_superposition_psi(orb_a, orb_b, r, theta, phi, t, ca, cb)) ** 2
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
r"""Stark and Zeeman splitting, and Floquet analysis of periodically driven
|
|
2
|
+
quantum boxes (multiphoton resonance, photon-assisted tunneling).
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from dataclasses import dataclass
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from .._compat import trapz
|
|
12
|
+
from ..core.solvers import SplitOperatorSolver1D
|
|
13
|
+
|
|
14
|
+
__all__ = ["zeeman_splitting", "zeeman_spectrum", "linear_stark_shift", "stark_n2_quartet", "FloquetDrivenBox"]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# --- Zeeman effect -----------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def zeeman_splitting(m_l: int, m_s: float, B: float, mu_B: float = 1.0, g_s: float = 2.0, hbar: float = 1.0) -> float:
|
|
21
|
+
r"""First-order (weak-field, no spin-orbit) Zeeman energy shift.
|
|
22
|
+
|
|
23
|
+
.. math::
|
|
24
|
+
|
|
25
|
+
\Delta E = \mu_B B\,(m_l + g_s m_s),
|
|
26
|
+
|
|
27
|
+
in the :math:`\lvert l, m_l; s, m_s\rangle` basis.
|
|
28
|
+
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
m_l : int
|
|
32
|
+
Orbital magnetic quantum number.
|
|
33
|
+
m_s : float
|
|
34
|
+
Spin magnetic quantum number.
|
|
35
|
+
B : float
|
|
36
|
+
Magnetic field strength.
|
|
37
|
+
mu_B : float, default=1.0
|
|
38
|
+
Bohr magneton.
|
|
39
|
+
g_s : float, default=2.0
|
|
40
|
+
Electron spin g-factor.
|
|
41
|
+
hbar : float, default=1.0
|
|
42
|
+
Value of :math:`\hbar` (unused in this first-order formula; kept
|
|
43
|
+
for API symmetry with other perturbation functions).
|
|
44
|
+
|
|
45
|
+
Returns
|
|
46
|
+
-------
|
|
47
|
+
float
|
|
48
|
+
"""
|
|
49
|
+
return mu_B * B * (m_l + g_s * m_s)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def zeeman_spectrum(l: int, B: float, mu_B: float = 1.0, g_s: float = 2.0) -> np.ndarray:
|
|
53
|
+
r"""All :math:`(m_l, m_s)` sublevel shifts for orbital number :math:`l`, spin-1/2.
|
|
54
|
+
|
|
55
|
+
Parameters
|
|
56
|
+
----------
|
|
57
|
+
l : int
|
|
58
|
+
Orbital angular momentum quantum number.
|
|
59
|
+
B : float
|
|
60
|
+
Magnetic field strength.
|
|
61
|
+
mu_B : float, default=1.0
|
|
62
|
+
Bohr magneton.
|
|
63
|
+
g_s : float, default=2.0
|
|
64
|
+
Electron spin g-factor.
|
|
65
|
+
|
|
66
|
+
Returns
|
|
67
|
+
-------
|
|
68
|
+
numpy.ndarray
|
|
69
|
+
Sorted array of :math:`2(2l+1)` energy shifts.
|
|
70
|
+
"""
|
|
71
|
+
m_l_values = np.arange(-l, l + 1)
|
|
72
|
+
m_s_values = np.array([-0.5, 0.5])
|
|
73
|
+
shifts = np.array([zeeman_splitting(ml, ms, B, mu_B, g_s) for ml in m_l_values for ms in m_s_values])
|
|
74
|
+
return np.sort(shifts)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# --- Linear Stark effect (hydrogen, degenerate perturbation theory) --------
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def linear_stark_shift(n: int, n1: int, n2: int, m: int, F: float, a0: float = 1.0) -> float:
|
|
81
|
+
r"""First-order Stark shift of a hydrogenic parabolic state.
|
|
82
|
+
|
|
83
|
+
For :math:`\lvert n, n_1, n_2, m\rangle` under a uniform field :math:`F`
|
|
84
|
+
along :math:`z`,
|
|
85
|
+
|
|
86
|
+
.. math::
|
|
87
|
+
|
|
88
|
+
\Delta E = \frac{3}{2}\, n\, (n_1 - n_2)\, a_0 F,
|
|
89
|
+
|
|
90
|
+
valid when :math:`n_1 + n_2 + \lvert m\rvert + 1 = n`. This linear-in-
|
|
91
|
+
:math:`F` splitting is a hallmark of hydrogen's "accidental"
|
|
92
|
+
:math:`l`-degeneracy (removed by any core penetration).
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
n : int
|
|
97
|
+
Principal quantum number.
|
|
98
|
+
n1, n2 : int
|
|
99
|
+
Parabolic quantum numbers.
|
|
100
|
+
m : int
|
|
101
|
+
Magnetic quantum number.
|
|
102
|
+
F : float
|
|
103
|
+
Electric field strength.
|
|
104
|
+
a0 : float, default=1.0
|
|
105
|
+
Bohr radius.
|
|
106
|
+
|
|
107
|
+
Returns
|
|
108
|
+
-------
|
|
109
|
+
float
|
|
110
|
+
|
|
111
|
+
Raises
|
|
112
|
+
------
|
|
113
|
+
ValueError
|
|
114
|
+
If ``n1 + n2 + abs(m) + 1 != n``.
|
|
115
|
+
"""
|
|
116
|
+
if n1 + n2 + abs(m) + 1 != n:
|
|
117
|
+
raise ValueError("Parabolic quantum numbers must satisfy n1+n2+|m|+1=n.")
|
|
118
|
+
return 1.5 * n * (n1 - n2) * a0 * F
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass
|
|
122
|
+
class StarkLevel:
|
|
123
|
+
"""One sublevel returned by :func:`stark_n2_quartet`."""
|
|
124
|
+
|
|
125
|
+
n1: int
|
|
126
|
+
"""int: Parabolic quantum number."""
|
|
127
|
+
|
|
128
|
+
n2: int
|
|
129
|
+
"""int: Parabolic quantum number."""
|
|
130
|
+
|
|
131
|
+
m: int
|
|
132
|
+
"""int: Magnetic quantum number."""
|
|
133
|
+
|
|
134
|
+
shift: float
|
|
135
|
+
"""float: The first-order Stark energy shift."""
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def stark_n2_quartet(F: float, a0: float = 1.0) -> list:
|
|
139
|
+
r"""The linear Stark splitting of hydrogen's :math:`n=2` shell.
|
|
140
|
+
|
|
141
|
+
The 4-fold degenerate :math:`n=2` level (2s, 2p0, :math:`2p_{\pm1}`)
|
|
142
|
+
splits under a field :math:`F` into three levels with shifts
|
|
143
|
+
:math:`\{-3a_0F, 0, 0, +3a_0F\}` -- the classic linear Stark quartet,
|
|
144
|
+
since only the :math:`m=0` pair (2s/2p0) is coupled by the perturbation.
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
----------
|
|
148
|
+
F : float
|
|
149
|
+
Electric field strength.
|
|
150
|
+
a0 : float, default=1.0
|
|
151
|
+
Bohr radius.
|
|
152
|
+
|
|
153
|
+
Returns
|
|
154
|
+
-------
|
|
155
|
+
list of StarkLevel
|
|
156
|
+
Sorted by energy shift.
|
|
157
|
+
"""
|
|
158
|
+
levels = []
|
|
159
|
+
for n1 in range(2):
|
|
160
|
+
for n2 in range(2):
|
|
161
|
+
for m in (-1, 0, 1):
|
|
162
|
+
if n1 + n2 + abs(m) + 1 == 2:
|
|
163
|
+
levels.append(StarkLevel(n1, n2, m, linear_stark_shift(2, n1, n2, m, F, a0)))
|
|
164
|
+
return sorted(levels, key=lambda lv: lv.shift)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# --- Floquet-driven infinite box --------------------------------------------
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
class FloquetDrivenBox:
|
|
171
|
+
r"""An infinite square well :math:`[0,L]` driven by an AC dipole field.
|
|
172
|
+
|
|
173
|
+
.. math::
|
|
174
|
+
|
|
175
|
+
V(x,t) = V_0 (x - L/2) \cos(\omega t),
|
|
176
|
+
|
|
177
|
+
simulated with the FFT split-operator propagator. The box walls are
|
|
178
|
+
emulated with a steep confining potential outside :math:`[0,L]` padded
|
|
179
|
+
into a larger FFT domain.
|
|
180
|
+
|
|
181
|
+
Provides both time-domain propagation (to see multiphoton Rabi
|
|
182
|
+
oscillations / photon-assisted tunneling between box eigenstates) and
|
|
183
|
+
the Floquet quasi-energy spectrum from the one-period propagator
|
|
184
|
+
:math:`\hat U(T)`.
|
|
185
|
+
|
|
186
|
+
Parameters
|
|
187
|
+
----------
|
|
188
|
+
L : float, default=1.0
|
|
189
|
+
Well width.
|
|
190
|
+
V0 : float, default=5.0
|
|
191
|
+
Driving field amplitude.
|
|
192
|
+
omega : float, default=20.0
|
|
193
|
+
Driving angular frequency :math:`\omega`.
|
|
194
|
+
hbar : float, default=1.0
|
|
195
|
+
Value of :math:`\hbar` to use.
|
|
196
|
+
m : float, default=1.0
|
|
197
|
+
Particle mass.
|
|
198
|
+
wall_height : float, default=5000.0
|
|
199
|
+
Height of the confining walls outside :math:`[0,L]`.
|
|
200
|
+
pad : float, default=0.4
|
|
201
|
+
Fractional padding of the FFT domain beyond :math:`[0,L]`.
|
|
202
|
+
n_grid : int, default=2048
|
|
203
|
+
Number of FFT grid points.
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
def __init__(
|
|
207
|
+
self,
|
|
208
|
+
L: float = 1.0,
|
|
209
|
+
V0: float = 5.0,
|
|
210
|
+
omega: float = 20.0,
|
|
211
|
+
hbar: float = 1.0,
|
|
212
|
+
m: float = 1.0,
|
|
213
|
+
wall_height: float = 5000.0,
|
|
214
|
+
pad: float = 0.4,
|
|
215
|
+
n_grid: int = 2048,
|
|
216
|
+
):
|
|
217
|
+
self.L, self.V0, self.omega, self.hbar, self.m = L, V0, omega, hbar, m
|
|
218
|
+
self.x = np.linspace(-pad * L, (1 + pad) * L, n_grid)
|
|
219
|
+
|
|
220
|
+
def wall(x):
|
|
221
|
+
return np.where((x >= 0) & (x <= L), 0.0, wall_height)
|
|
222
|
+
|
|
223
|
+
self._wall = wall(self.x)
|
|
224
|
+
|
|
225
|
+
def V(x, t):
|
|
226
|
+
return wall(x) + V0 * (x - L / 2) * np.cos(omega * t)
|
|
227
|
+
|
|
228
|
+
self.V = V
|
|
229
|
+
|
|
230
|
+
def box_eigenstate(self, n: int) -> np.ndarray:
|
|
231
|
+
"""The :math:`n`-th unperturbed infinite-well eigenstate on the grid.
|
|
232
|
+
|
|
233
|
+
Parameters
|
|
234
|
+
----------
|
|
235
|
+
n : int
|
|
236
|
+
Quantum number (:math:`n=1,2,\\dots`).
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
numpy.ndarray
|
|
241
|
+
"""
|
|
242
|
+
psi = np.zeros_like(self.x)
|
|
243
|
+
inside = (self.x >= 0) & (self.x <= self.L)
|
|
244
|
+
psi[inside] = np.sqrt(2 / self.L) * np.sin(n * np.pi * self.x[inside] / self.L)
|
|
245
|
+
norm = np.sqrt(trapz(psi**2, self.x))
|
|
246
|
+
return psi / norm
|
|
247
|
+
|
|
248
|
+
def box_energy(self, n: int) -> float:
|
|
249
|
+
r"""Unperturbed box eigenenergy :math:`E_n = n^2\pi^2\hbar^2/(2mL^2)`.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
n : int
|
|
254
|
+
|
|
255
|
+
Returns
|
|
256
|
+
-------
|
|
257
|
+
float
|
|
258
|
+
"""
|
|
259
|
+
return (n**2 * np.pi**2 * self.hbar**2) / (2 * self.m * self.L**2)
|
|
260
|
+
|
|
261
|
+
def make_solver(self, dt: float = 1e-4) -> SplitOperatorSolver1D:
|
|
262
|
+
"""Build a :class:`~physicskit.quantum.core.solvers.SplitOperatorSolver1D` for this drive.
|
|
263
|
+
|
|
264
|
+
Parameters
|
|
265
|
+
----------
|
|
266
|
+
dt : float, default=1e-4
|
|
267
|
+
Time step.
|
|
268
|
+
|
|
269
|
+
Returns
|
|
270
|
+
-------
|
|
271
|
+
physicskit.quantum.core.solvers.SplitOperatorSolver1D
|
|
272
|
+
"""
|
|
273
|
+
return SplitOperatorSolver1D(self.x, self.V, hbar=self.hbar, m=self.m, dt=dt)
|
|
274
|
+
|
|
275
|
+
def transition_probability(self, n_initial: int, n_final: int, t_max: float, dt: float = 1e-4) -> tuple[np.ndarray, np.ndarray]:
|
|
276
|
+
r"""Multiphoton transition probability :math:`P_{i\to f}(t)`.
|
|
277
|
+
|
|
278
|
+
Propagates the ``n_initial`` box eigenstate under the AC drive and
|
|
279
|
+
returns its overlap probability with the ``n_final`` unperturbed
|
|
280
|
+
box eigenstate -- shows resonant multiphoton transitions when
|
|
281
|
+
:math:`\hbar\omega` (or a multiple) bridges the level gap.
|
|
282
|
+
|
|
283
|
+
Parameters
|
|
284
|
+
----------
|
|
285
|
+
n_initial : int
|
|
286
|
+
Initial box quantum number.
|
|
287
|
+
n_final : int
|
|
288
|
+
Final box quantum number to project onto.
|
|
289
|
+
t_max : float
|
|
290
|
+
Total propagation time.
|
|
291
|
+
dt : float, default=1e-4
|
|
292
|
+
Time step.
|
|
293
|
+
|
|
294
|
+
Returns
|
|
295
|
+
-------
|
|
296
|
+
times : numpy.ndarray
|
|
297
|
+
probs : numpy.ndarray
|
|
298
|
+
:math:`P_{n_\text{initial}\to n_\text{final}}(t)`.
|
|
299
|
+
"""
|
|
300
|
+
solver = self.make_solver(dt)
|
|
301
|
+
psi0 = self.box_eigenstate(n_initial).astype(complex)
|
|
302
|
+
n_steps = int(t_max / dt)
|
|
303
|
+
save_every = max(n_steps // 400, 1)
|
|
304
|
+
frames, times = solver.propagate(psi0, n_steps, save_every=save_every)
|
|
305
|
+
|
|
306
|
+
target = self.box_eigenstate(n_final)
|
|
307
|
+
probs = np.array([np.abs(trapz(np.conj(target) * f, self.x)) ** 2 for f in frames])
|
|
308
|
+
return times, probs
|
|
309
|
+
|
|
310
|
+
def floquet_quasienergies(self, n_levels: int = 4, dt: float = 1e-4) -> np.ndarray:
|
|
311
|
+
r"""Floquet quasi-energy spectrum from the one-period propagator.
|
|
312
|
+
|
|
313
|
+
Diagonalizes :math:`\hat U(T)` (:math:`T=2\pi/\omega`), restricted
|
|
314
|
+
to the span of the lowest ``n_levels`` box eigenstates, to obtain
|
|
315
|
+
quasi-energies
|
|
316
|
+
|
|
317
|
+
.. math::
|
|
318
|
+
|
|
319
|
+
\epsilon_k = -\frac{\hbar}{T}\arg(\lambda_k),
|
|
320
|
+
|
|
321
|
+
where :math:`\lambda_k` are the eigenvalues of :math:`\hat U(T)`.
|
|
322
|
+
|
|
323
|
+
Parameters
|
|
324
|
+
----------
|
|
325
|
+
n_levels : int, default=4
|
|
326
|
+
Size of the truncated box-eigenstate basis.
|
|
327
|
+
dt : float, default=1e-4
|
|
328
|
+
Time step used to build :math:`\hat U(T)`.
|
|
329
|
+
|
|
330
|
+
Returns
|
|
331
|
+
-------
|
|
332
|
+
numpy.ndarray
|
|
333
|
+
Sorted quasi-energies, shape ``(n_levels,)``.
|
|
334
|
+
"""
|
|
335
|
+
T = 2 * np.pi / self.omega
|
|
336
|
+
solver = self.make_solver(dt)
|
|
337
|
+
n_steps = int(round(T / dt))
|
|
338
|
+
|
|
339
|
+
basis = [self.box_eigenstate(n) for n in range(1, n_levels + 1)]
|
|
340
|
+
U = np.zeros((n_levels, n_levels), dtype=complex)
|
|
341
|
+
for j, psi0 in enumerate(basis):
|
|
342
|
+
psi = psi0.astype(complex)
|
|
343
|
+
for _ in range(n_steps):
|
|
344
|
+
psi = solver.step(psi)
|
|
345
|
+
for i, target in enumerate(basis):
|
|
346
|
+
U[i, j] = trapz(np.conj(target) * psi, self.x)
|
|
347
|
+
|
|
348
|
+
eigvals = np.linalg.eigvals(U)
|
|
349
|
+
quasi_energies = -(self.hbar / T) * np.angle(eigvals)
|
|
350
|
+
return np.sort(quasi_energies)
|