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,518 @@
|
|
|
1
|
+
"""Physics-correctness tests for physicskit.condensed."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
import physicskit as pk
|
|
9
|
+
from physicskit.condensed.anderson_localization import (
|
|
10
|
+
anderson_chain_hamiltonian,
|
|
11
|
+
inverse_participation_ratio,
|
|
12
|
+
localization_length,
|
|
13
|
+
)
|
|
14
|
+
from physicskit.condensed.correlated import bdg_bcs_hamiltonian, bdg_spectrum, hubbard_1d_exact_diagonalization, hubbard_spin_correlations
|
|
15
|
+
from physicskit.condensed.ginzburg_landau import (
|
|
16
|
+
ginzburg_landau_parameter,
|
|
17
|
+
gl_coherence_length,
|
|
18
|
+
gl_equilibrium_order_parameter,
|
|
19
|
+
gl_order_parameter_profile,
|
|
20
|
+
gl_penetration_depth,
|
|
21
|
+
)
|
|
22
|
+
from physicskit.condensed.landau_levels import (
|
|
23
|
+
filling_factor,
|
|
24
|
+
landau_degeneracy,
|
|
25
|
+
landau_density_of_states,
|
|
26
|
+
landau_level_energies,
|
|
27
|
+
)
|
|
28
|
+
from physicskit.condensed.laughlin import laughlin_metropolis_sweep, laughlin_pair_correlation, laughlin_radial_density
|
|
29
|
+
from physicskit.condensed.models import (
|
|
30
|
+
bhz_hamiltonian,
|
|
31
|
+
bhz_ribbon_hamiltonian,
|
|
32
|
+
graphene_hamiltonian,
|
|
33
|
+
graphene_lattice_hamiltonian,
|
|
34
|
+
haldane_lattice_hamiltonian,
|
|
35
|
+
haldane_model,
|
|
36
|
+
harper_hofstadter_hamiltonian,
|
|
37
|
+
kane_mele_hamiltonian,
|
|
38
|
+
kitaev_chain_bdg_real_space,
|
|
39
|
+
kitaev_chain_hamiltonian,
|
|
40
|
+
ssh_lattice_hamiltonian,
|
|
41
|
+
)
|
|
42
|
+
from physicskit.condensed.tight_binding import Hamiltonian, Lattice, apply_peierls_phase, build_finite_cluster, build_ribbon
|
|
43
|
+
from physicskit.condensed.topological_insulator_3d import (
|
|
44
|
+
surface_dirac_hamiltonian,
|
|
45
|
+
topological_insulator_3d_hamiltonian,
|
|
46
|
+
topological_insulator_3d_slab_hamiltonian,
|
|
47
|
+
)
|
|
48
|
+
from physicskit.condensed.topology import compute_chern_number, z2_invariant, zak_phase
|
|
49
|
+
from physicskit.condensed.weyl import weyl_node_locations, weyl_semimetal_hamiltonian, weyl_semimetal_slab_hamiltonian
|
|
50
|
+
|
|
51
|
+
K_DIRAC = np.array([2 * np.pi / 3, 4 * np.pi / 3])
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class TestGrapheneDiracCone:
|
|
55
|
+
def test_gap_closes_at_dirac_point(self):
|
|
56
|
+
eigs = np.linalg.eigvalsh(graphene_hamiltonian(*K_DIRAC))
|
|
57
|
+
assert np.allclose(eigs, 0.0, atol=1e-10)
|
|
58
|
+
|
|
59
|
+
@pytest.mark.parametrize("direction", [(1.0, 0.0), (0.0, 1.0), (1.0, 1.0)])
|
|
60
|
+
def test_linear_dispersion_near_dirac_point(self, direction):
|
|
61
|
+
direction = np.array(direction) / np.linalg.norm(direction)
|
|
62
|
+
slopes = []
|
|
63
|
+
for dq in (1e-3, 5e-4, 2.5e-4):
|
|
64
|
+
eigs = np.linalg.eigvalsh(graphene_hamiltonian(*(K_DIRAC + dq * direction)))
|
|
65
|
+
slopes.append(eigs[1] / dq)
|
|
66
|
+
# |E(k)| grows linearly in |k - K|, so the extracted slope should be
|
|
67
|
+
# essentially constant (not vanishing as expected for a quadratic band).
|
|
68
|
+
assert np.allclose(slopes, slopes[0], rtol=1e-3)
|
|
69
|
+
assert slopes[0] > 0.5
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TestHaldaneChernNumber:
|
|
73
|
+
def test_topological_phase_chern_pm1(self):
|
|
74
|
+
H = lambda k1, k2: haldane_model(k1, k2, t=1.0, t2=0.2, phi=np.pi / 2, M=0.0)
|
|
75
|
+
c = compute_chern_number(H, grid_size=24)
|
|
76
|
+
assert c == [1, -1]
|
|
77
|
+
|
|
78
|
+
def test_trivial_phase_chern_zero(self):
|
|
79
|
+
# M = 2.0 >> 3*sqrt(3)*t2 = 1.039, well inside the trivial insulator regime.
|
|
80
|
+
H = lambda k1, k2: haldane_model(k1, k2, t=1.0, t2=0.2, phi=np.pi / 2, M=2.0)
|
|
81
|
+
c = compute_chern_number(H, grid_size=24)
|
|
82
|
+
assert c == [0, 0]
|
|
83
|
+
|
|
84
|
+
def test_time_reversal_flips_chern_sign(self):
|
|
85
|
+
H_plus = lambda k1, k2: haldane_model(k1, k2, phi=np.pi / 2)
|
|
86
|
+
H_minus = lambda k1, k2: haldane_model(k1, k2, phi=-np.pi / 2)
|
|
87
|
+
assert compute_chern_number(H_plus, grid_size=20) == [1, -1]
|
|
88
|
+
assert compute_chern_number(H_minus, grid_size=20) == [-1, 1]
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class TestSSHTopology:
|
|
92
|
+
def test_open_boundary_hosts_near_zero_mode_when_topological(self):
|
|
93
|
+
H = ssh_lattice_hamiltonian(v=0.5, w=1.0)
|
|
94
|
+
H_wire = build_ribbon(H, open_direction=0, n_cells=30)
|
|
95
|
+
spectrum = np.linalg.eigvalsh(H_wire(np.array([])))
|
|
96
|
+
assert np.any(np.abs(spectrum) < 1e-6)
|
|
97
|
+
|
|
98
|
+
def test_open_boundary_has_no_zero_mode_when_trivial(self):
|
|
99
|
+
H = ssh_lattice_hamiltonian(v=1.0, w=0.5)
|
|
100
|
+
H_wire = build_ribbon(H, open_direction=0, n_cells=30)
|
|
101
|
+
spectrum = np.linalg.eigvalsh(H_wire(np.array([])))
|
|
102
|
+
assert np.all(np.abs(spectrum) > 0.1)
|
|
103
|
+
|
|
104
|
+
def test_zak_phase_quantization(self):
|
|
105
|
+
from physicskit.condensed.models import ssh_hamiltonian
|
|
106
|
+
|
|
107
|
+
topological = lambda k: ssh_hamiltonian(k, v=0.5, w=1.0)
|
|
108
|
+
trivial = lambda k: ssh_hamiltonian(k, v=1.0, w=0.5)
|
|
109
|
+
assert abs(zak_phase(topological)) == pytest.approx(np.pi, abs=1e-6)
|
|
110
|
+
assert abs(zak_phase(trivial)) == pytest.approx(0.0, abs=1e-6)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
class TestBuildFiniteCluster:
|
|
114
|
+
def test_ssh_open_chain_site_and_bond_count(self):
|
|
115
|
+
H, positions, bonds = build_finite_cluster(ssh_lattice_hamiltonian(v=0.5, w=1.0), n_cells=10)
|
|
116
|
+
assert H.shape == (20, 20)
|
|
117
|
+
assert positions.shape == (20, 1)
|
|
118
|
+
# 10 intracell (v) + 9 intercell (w) bonds; the last cell's w-bond is cut open.
|
|
119
|
+
assert len(bonds) == 19
|
|
120
|
+
|
|
121
|
+
def test_ssh_hermitian_and_matches_ribbon_spectrum(self):
|
|
122
|
+
H_cluster, _, _ = build_finite_cluster(ssh_lattice_hamiltonian(v=0.5, w=1.0), n_cells=15)
|
|
123
|
+
assert np.allclose(H_cluster, H_cluster.conj().T)
|
|
124
|
+
H_ribbon = build_ribbon(ssh_lattice_hamiltonian(v=0.5, w=1.0), open_direction=0, n_cells=15)(np.array([]))
|
|
125
|
+
# A 1D lattice's ribbon (periodic in zero remaining directions) is exactly
|
|
126
|
+
# the same finite, open chain that build_finite_cluster constructs.
|
|
127
|
+
assert np.allclose(np.linalg.eigvalsh(H_cluster), np.linalg.eigvalsh(H_ribbon))
|
|
128
|
+
|
|
129
|
+
def test_ssh_topological_open_chain_hosts_near_zero_mode(self):
|
|
130
|
+
H, _, _ = build_finite_cluster(ssh_lattice_hamiltonian(v=0.5, w=1.0), n_cells=15)
|
|
131
|
+
eigs = np.linalg.eigvalsh(H)
|
|
132
|
+
assert np.abs(eigs[np.argmin(np.abs(eigs))]) < 1e-3
|
|
133
|
+
|
|
134
|
+
def test_graphene_flake_hermitian_with_boundary_zero_modes(self):
|
|
135
|
+
H, positions, bonds = build_finite_cluster(graphene_lattice_hamiltonian(t=1.0), n_cells=(10, 10))
|
|
136
|
+
assert H.shape == (200, 200)
|
|
137
|
+
assert positions.shape == (200, 2)
|
|
138
|
+
assert np.allclose(H, H.conj().T)
|
|
139
|
+
# Zigzag-terminated finite flakes host a macroscopically-growing band
|
|
140
|
+
# of near-zero-energy edge states with no bulk counterpart.
|
|
141
|
+
eigs = np.linalg.eigvalsh(H)
|
|
142
|
+
assert np.sum(np.abs(eigs) < 0.2) > 5
|
|
143
|
+
|
|
144
|
+
def test_scalar_n_cells_broadcasts_to_every_dimension(self):
|
|
145
|
+
"""A single int n_cells for a 2D lattice means the same cell count
|
|
146
|
+
along both dimensions, equivalent to passing the explicit tuple."""
|
|
147
|
+
H_scalar, positions_scalar, _ = build_finite_cluster(graphene_lattice_hamiltonian(t=1.0), n_cells=4)
|
|
148
|
+
H_tuple, positions_tuple, _ = build_finite_cluster(graphene_lattice_hamiltonian(t=1.0), n_cells=(4, 4))
|
|
149
|
+
assert H_scalar.shape == H_tuple.shape
|
|
150
|
+
assert np.allclose(positions_scalar, positions_tuple)
|
|
151
|
+
|
|
152
|
+
def test_keep_predicate_carves_a_disk(self):
|
|
153
|
+
lat = Lattice.honeycomb()
|
|
154
|
+
n_cells = 10
|
|
155
|
+
center = np.array([n_cells / 2, n_cells / 2]) @ lat.lattice_vectors
|
|
156
|
+
radius = 4.0
|
|
157
|
+
|
|
158
|
+
def in_disk(cell, orbital, position):
|
|
159
|
+
return np.linalg.norm(position - center) <= radius
|
|
160
|
+
|
|
161
|
+
H, positions, _ = build_finite_cluster(haldane_lattice_hamiltonian(t=1.0, t2=0.2), n_cells=(n_cells, n_cells), keep=in_disk)
|
|
162
|
+
assert len(positions) < n_cells * n_cells * 2
|
|
163
|
+
assert np.all(np.linalg.norm(positions - center, axis=1) <= radius)
|
|
164
|
+
|
|
165
|
+
def test_haldane_disk_flake_edge_state_hugs_boundary_only_when_topological(self):
|
|
166
|
+
lat = Lattice.honeycomb()
|
|
167
|
+
n_cells = 14
|
|
168
|
+
center = np.array([n_cells / 2, n_cells / 2]) @ lat.lattice_vectors
|
|
169
|
+
radius = 6.0
|
|
170
|
+
|
|
171
|
+
def in_disk(cell, orbital, position):
|
|
172
|
+
return np.linalg.norm(position - center) <= radius
|
|
173
|
+
|
|
174
|
+
def weighted_edge_radius(M):
|
|
175
|
+
H, positions, _ = build_finite_cluster(haldane_lattice_hamiltonian(t=1.0, t2=0.2, phi=np.pi / 2, M=M), n_cells=(n_cells, n_cells), keep=in_disk)
|
|
176
|
+
eigenvalues, eigenvectors = np.linalg.eigh(H)
|
|
177
|
+
mid = len(eigenvalues) // 2
|
|
178
|
+
density = np.sum(np.abs(eigenvectors[:, mid - 3 : mid + 3]) ** 2, axis=1)
|
|
179
|
+
r = np.linalg.norm(positions - center, axis=1)
|
|
180
|
+
return np.sum(r * density) / density.sum(), r.mean()
|
|
181
|
+
|
|
182
|
+
topological_r, mean_r = weighted_edge_radius(M=0.0)
|
|
183
|
+
trivial_r, _ = weighted_edge_radius(M=2.0)
|
|
184
|
+
# In the topological phase the near-gap states hug the disk's
|
|
185
|
+
# (crystallographically meaningless) boundary; in the trivial phase
|
|
186
|
+
# the near-gap states are ordinary bulk states with no such preference.
|
|
187
|
+
assert topological_r > mean_r
|
|
188
|
+
assert trivial_r < topological_r
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class TestKaneMeleZ2:
|
|
192
|
+
def test_trivial_when_soc_zero(self):
|
|
193
|
+
H = lambda k1, k2: kane_mele_hamiltonian(k1, k2, lambda_so=0.0)
|
|
194
|
+
assert z2_invariant(H, grid_size=16) == 0
|
|
195
|
+
|
|
196
|
+
def test_topological_when_soc_nonzero(self):
|
|
197
|
+
H = lambda k1, k2: kane_mele_hamiltonian(k1, k2, lambda_so=0.06)
|
|
198
|
+
assert z2_invariant(H, grid_size=16) == 1
|
|
199
|
+
|
|
200
|
+
def test_hermitian(self):
|
|
201
|
+
H = kane_mele_hamiltonian(0.4, 1.1, lambda_so=0.06, lambda_r=0.05)
|
|
202
|
+
assert np.allclose(H, H.conj().T)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class TestBHZModel:
|
|
206
|
+
def test_hermitian_and_time_reversal_block_structure(self):
|
|
207
|
+
H = bhz_hamiltonian(0.3, -0.7, M=1.0, B=1.0)
|
|
208
|
+
assert np.allclose(H, H.conj().T)
|
|
209
|
+
assert np.allclose(H[:2, :2], H[2:, 2:].conj())
|
|
210
|
+
|
|
211
|
+
def test_gap_closes_at_topological_transition(self):
|
|
212
|
+
# M/B = 0 is the band-inversion transition where the gap must close at Gamma.
|
|
213
|
+
eigs = np.linalg.eigvalsh(bhz_hamiltonian(0.0, 0.0, M=0.0, B=1.0, A=1.0))
|
|
214
|
+
assert np.allclose(eigs, 0.0, atol=1e-10)
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
class TestKitaevChain:
|
|
218
|
+
def test_majorana_zero_mode_in_topological_phase(self):
|
|
219
|
+
H = kitaev_chain_bdg_real_space(n_sites=60, mu=0.0, t=1.0, delta=1.0)
|
|
220
|
+
eigs = np.linalg.eigvalsh(H)
|
|
221
|
+
assert np.abs(eigs[np.argmin(np.abs(eigs))]) < 1e-6
|
|
222
|
+
|
|
223
|
+
def test_no_zero_mode_in_trivial_phase(self):
|
|
224
|
+
# |mu| > 2t is the trivial (non-topological) regime.
|
|
225
|
+
H = kitaev_chain_bdg_real_space(n_sites=60, mu=3.0, t=1.0, delta=1.0)
|
|
226
|
+
eigs = np.linalg.eigvalsh(H)
|
|
227
|
+
assert np.abs(eigs[np.argmin(np.abs(eigs))]) > 0.1
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
class TestSuperconductivity:
|
|
231
|
+
def test_bdg_gap_equals_pairing_amplitude(self):
|
|
232
|
+
eigs = np.linalg.eigvalsh(bdg_bcs_hamiltonian(k=np.pi / 2, mu=0.0, t=1.0, delta=0.5))
|
|
233
|
+
assert np.isclose(eigs[1], 0.5)
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
class TestHubbardModel:
|
|
237
|
+
def test_two_site_dimer_exact_energy(self):
|
|
238
|
+
result = hubbard_1d_exact_diagonalization(n_sites=2, n_up=1, n_dn=1, t=1.0, U=4.0)
|
|
239
|
+
expected = 0.5 * (4.0 - np.sqrt(4.0**2 + 16 * 1.0**2))
|
|
240
|
+
assert result["ground_state_energy"] == pytest.approx(expected, abs=1e-8)
|
|
241
|
+
|
|
242
|
+
def test_large_u_suppresses_double_occupancy_energy_gap(self):
|
|
243
|
+
low_u = hubbard_1d_exact_diagonalization(n_sites=4, n_up=2, n_dn=2, t=1.0, U=1.0)
|
|
244
|
+
high_u = hubbard_1d_exact_diagonalization(n_sites=4, n_up=2, n_dn=2, t=1.0, U=20.0)
|
|
245
|
+
assert high_u["ground_state_energy"] > low_u["ground_state_energy"]
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
class TestLandauLevels:
|
|
249
|
+
def test_equally_spaced_harmonic_oscillator_spectrum(self):
|
|
250
|
+
energies = landau_level_energies(n_max=4, B=1.0, m=1.0, e=1.0, hbar=1.0)
|
|
251
|
+
assert np.allclose(energies, np.arange(5) + 0.5)
|
|
252
|
+
assert np.allclose(np.diff(energies), 1.0)
|
|
253
|
+
|
|
254
|
+
def test_degeneracy_scales_linearly_with_field_and_area(self):
|
|
255
|
+
assert landau_degeneracy(area=10.0, B=1.0) == pytest.approx(2 * landau_degeneracy(area=5.0, B=1.0))
|
|
256
|
+
assert landau_degeneracy(area=10.0, B=2.0) == pytest.approx(2 * landau_degeneracy(area=10.0, B=1.0))
|
|
257
|
+
|
|
258
|
+
def test_filling_factor_matches_degeneracy_ratio(self):
|
|
259
|
+
# nu = n_e / n_B by definition: a density equal to the per-area degeneracy gives nu=1.
|
|
260
|
+
B = 1.5
|
|
261
|
+
n_B = landau_degeneracy(area=1.0, B=B)
|
|
262
|
+
assert filling_factor(density=n_B, B=B) == pytest.approx(1.0)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class TestGinzburgLandau:
|
|
266
|
+
def test_equilibrium_order_parameter_minimizes_free_energy(self):
|
|
267
|
+
a, b = -2.0, 3.0
|
|
268
|
+
psi0 = gl_equilibrium_order_parameter(a, b)
|
|
269
|
+
f0 = pk.condensed.gl_free_energy_density(psi0, a, b)
|
|
270
|
+
for psi in np.linspace(0, 2 * psi0, 25):
|
|
271
|
+
assert pk.condensed.gl_free_energy_density(psi, a, b) >= f0 - 1e-10
|
|
272
|
+
|
|
273
|
+
def test_larger_disorder_parameter_a_shrinks_coherence_length(self):
|
|
274
|
+
assert gl_coherence_length(a=-1.0) > gl_coherence_length(a=-4.0)
|
|
275
|
+
|
|
276
|
+
def test_denser_condensate_shrinks_penetration_depth_and_kappa(self):
|
|
277
|
+
# Higher condensate density psi0 screens fields over a shorter distance.
|
|
278
|
+
xi = gl_coherence_length(a=-1.0)
|
|
279
|
+
lam_dilute = gl_penetration_depth(psi0=0.3)
|
|
280
|
+
lam_dense = gl_penetration_depth(psi0=3.0)
|
|
281
|
+
assert lam_dense < lam_dilute
|
|
282
|
+
assert ginzburg_landau_parameter(xi, lam_dense) < ginzburg_landau_parameter(xi, lam_dilute)
|
|
283
|
+
|
|
284
|
+
def test_order_parameter_profile_heals_from_boundary_to_bulk(self):
|
|
285
|
+
xi = 2.0
|
|
286
|
+
x = np.array([0.0, xi, 5 * xi, 50 * xi])
|
|
287
|
+
profile = gl_order_parameter_profile(x, xi)
|
|
288
|
+
assert profile[0] == pytest.approx(0.0)
|
|
289
|
+
assert np.all(np.diff(profile) > 0)
|
|
290
|
+
assert profile[-1] == pytest.approx(1.0, abs=1e-6)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
class TestAndersonLocalization:
|
|
294
|
+
def test_clean_chain_ground_state_is_extended(self):
|
|
295
|
+
H = anderson_chain_hamiltonian(n_sites=200, disorder_strength=0.0, t=1.0)
|
|
296
|
+
eigs, vecs = np.linalg.eigh(H)
|
|
297
|
+
ipr_clean = inverse_participation_ratio(vecs[:, np.argmin(eigs)])
|
|
298
|
+
assert ipr_clean < 5.0 / 200
|
|
299
|
+
|
|
300
|
+
def test_strong_disorder_localizes_states(self):
|
|
301
|
+
H = anderson_chain_hamiltonian(n_sites=200, disorder_strength=20.0, t=1.0, seed=0)
|
|
302
|
+
eigs, vecs = np.linalg.eigh(H)
|
|
303
|
+
mid_state = vecs[:, len(eigs) // 2]
|
|
304
|
+
assert inverse_participation_ratio(mid_state) > 0.05
|
|
305
|
+
|
|
306
|
+
def test_localized_state_has_finite_localization_length(self):
|
|
307
|
+
H = anderson_chain_hamiltonian(n_sites=300, disorder_strength=15.0, t=1.0, seed=1)
|
|
308
|
+
eigs, vecs = np.linalg.eigh(H)
|
|
309
|
+
mid_state = vecs[:, len(eigs) // 2]
|
|
310
|
+
xi = localization_length(mid_state)
|
|
311
|
+
assert 0 < xi < 300
|
|
312
|
+
|
|
313
|
+
def test_flat_density_has_infinite_localization_length(self):
|
|
314
|
+
"""A uniform |psi|^2 has neither a growing left flank nor a decaying
|
|
315
|
+
right flank around its (arbitrary) peak, so neither slope condition
|
|
316
|
+
is met and the function reports infinite localization length."""
|
|
317
|
+
assert localization_length(np.ones(200)) == float("inf")
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
class TestBHZEdgeStates:
|
|
321
|
+
def test_helical_edge_states_in_topological_regime(self):
|
|
322
|
+
spectrum = np.linalg.eigvalsh(bhz_ribbon_hamiltonian(kx=0.0, n_cells=40, M=1.0, B=1.0))
|
|
323
|
+
assert np.any(np.abs(spectrum) < 1e-6)
|
|
324
|
+
|
|
325
|
+
def test_no_edge_states_in_trivial_regime(self):
|
|
326
|
+
spectrum = np.linalg.eigvalsh(bhz_ribbon_hamiltonian(kx=0.0, n_cells=40, M=-1.0, B=1.0))
|
|
327
|
+
assert np.all(np.abs(spectrum) > 0.1)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
class TestTopologicalInsulator3D:
|
|
331
|
+
def test_bulk_hermitian(self):
|
|
332
|
+
H = topological_insulator_3d_hamiltonian(0.3, -0.5, 0.7, m=1.5)
|
|
333
|
+
assert np.allclose(H, H.conj().T)
|
|
334
|
+
|
|
335
|
+
def test_surface_dirac_cone_in_strong_ti_regime(self):
|
|
336
|
+
# 1 < |m/t| < 3 is the strong topological insulator window.
|
|
337
|
+
spectrum = np.linalg.eigvalsh(topological_insulator_3d_slab_hamiltonian(0.0, 0.0, n_layers=40, m=-2.0))
|
|
338
|
+
assert np.min(np.abs(spectrum)) < 1e-8
|
|
339
|
+
|
|
340
|
+
def test_no_surface_state_in_trivial_regime(self):
|
|
341
|
+
spectrum = np.linalg.eigvalsh(topological_insulator_3d_slab_hamiltonian(0.0, 0.0, n_layers=40, m=0.0))
|
|
342
|
+
assert np.min(np.abs(spectrum)) > 0.5
|
|
343
|
+
|
|
344
|
+
def test_surface_state_localized_on_one_layer(self):
|
|
345
|
+
H = topological_insulator_3d_slab_hamiltonian(0.0, 0.0, n_layers=40, m=-2.0)
|
|
346
|
+
eigs, vecs = np.linalg.eigh(H)
|
|
347
|
+
near_zero = vecs[:, np.argmin(np.abs(eigs))]
|
|
348
|
+
density = (np.abs(near_zero.reshape(40, 4)) ** 2).sum(axis=1)
|
|
349
|
+
assert density[0] + density[-1] > 0.99
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
class TestHarperHofstadter:
|
|
353
|
+
def test_band_chern_numbers_sum_to_zero(self):
|
|
354
|
+
# The full q-band Hilbert space is a trivial bundle: whatever the
|
|
355
|
+
# individual bands do, their Chern numbers must cancel.
|
|
356
|
+
H = lambda k1, k2: harper_hofstadter_hamiltonian(k1, k2, p=1, q=3)
|
|
357
|
+
assert sum(compute_chern_number(H, grid_size=24)) == 0
|
|
358
|
+
|
|
359
|
+
def test_flux_one_third_matches_known_chern_numbers(self):
|
|
360
|
+
H = lambda k1, k2: harper_hofstadter_hamiltonian(k1, k2, p=1, q=3)
|
|
361
|
+
assert compute_chern_number(H, grid_size=24) == [-1, 2, -1]
|
|
362
|
+
|
|
363
|
+
def test_hermitian(self):
|
|
364
|
+
H = harper_hofstadter_hamiltonian(0.3, -0.7, p=2, q=5)
|
|
365
|
+
assert np.allclose(H, H.conj().T)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
class TestHubbardSpinCorrelations:
|
|
369
|
+
def test_nearest_neighbor_antiferromagnetic_at_strong_coupling(self):
|
|
370
|
+
result = hubbard_1d_exact_diagonalization(n_sites=6, n_up=3, n_dn=3, t=1.0, U=8.0, pbc=True, return_eigenvectors=True)
|
|
371
|
+
corr = hubbard_spin_correlations(6, result["ground_state_vector"], result["states_up"], result["states_dn"])
|
|
372
|
+
assert corr[1] < 0
|
|
373
|
+
|
|
374
|
+
def test_antiferromagnetic_correlation_strengthens_with_u(self):
|
|
375
|
+
nn_corr = []
|
|
376
|
+
for U in (0.0, 4.0, 16.0):
|
|
377
|
+
result = hubbard_1d_exact_diagonalization(n_sites=6, n_up=3, n_dn=3, t=1.0, U=U, pbc=True, return_eigenvectors=True)
|
|
378
|
+
corr = hubbard_spin_correlations(6, result["ground_state_vector"], result["states_up"], result["states_dn"])
|
|
379
|
+
nn_corr.append(corr[1])
|
|
380
|
+
assert nn_corr[0] > nn_corr[1] > nn_corr[2]
|
|
381
|
+
|
|
382
|
+
def test_onsite_correlation_is_quarter_minus_double_occupancy(self):
|
|
383
|
+
# <(Sz_i)^2> = 1/4 whenever site i is never doubly (or never)
|
|
384
|
+
# occupied; strong repulsion pushes every basis weight there.
|
|
385
|
+
result = hubbard_1d_exact_diagonalization(n_sites=4, n_up=2, n_dn=2, t=1.0, U=50.0, pbc=True, return_eigenvectors=True)
|
|
386
|
+
corr = hubbard_spin_correlations(4, result["ground_state_vector"], result["states_up"], result["states_dn"])
|
|
387
|
+
assert corr[0] == pytest.approx(0.25, abs=0.02)
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
class TestWeylSemimetal:
|
|
391
|
+
def test_nodes_gapless_bulk_gapped_elsewhere(self):
|
|
392
|
+
k0 = weyl_node_locations(m=2.0, t=1.0)[1]
|
|
393
|
+
eigs_at_node = np.linalg.eigvalsh(weyl_semimetal_hamiltonian(0.0, 0.0, k0, m=2.0))
|
|
394
|
+
assert np.max(np.abs(eigs_at_node)) < 1e-8
|
|
395
|
+
eigs_away = np.linalg.eigvalsh(weyl_semimetal_hamiltonian(0.0, 0.0, 0.0, m=2.0))
|
|
396
|
+
assert np.min(np.abs(eigs_away)) > 0.5
|
|
397
|
+
|
|
398
|
+
def test_no_nodes_outside_window(self):
|
|
399
|
+
assert weyl_node_locations(m=4.0, t=1.0) is None
|
|
400
|
+
assert weyl_node_locations(m=0.5, t=1.0) is None
|
|
401
|
+
|
|
402
|
+
def test_slab_gapless_between_nodes_gapped_outside(self):
|
|
403
|
+
gap_inside = np.min(np.abs(np.linalg.eigvalsh(weyl_semimetal_slab_hamiltonian(0.0, 0.0, n_layers=40, m=2.0))))
|
|
404
|
+
gap_outside = np.min(np.abs(np.linalg.eigvalsh(weyl_semimetal_slab_hamiltonian(0.0, np.pi, n_layers=40, m=2.0))))
|
|
405
|
+
assert gap_inside < 1e-6
|
|
406
|
+
assert gap_outside > 0.5
|
|
407
|
+
|
|
408
|
+
|
|
409
|
+
class TestLaughlin:
|
|
410
|
+
def test_metropolis_sweep_keeps_particles_apart(self):
|
|
411
|
+
z = np.array([0.1, -0.1, 0.2j, -0.2j]) + 0j
|
|
412
|
+
for _ in range(100):
|
|
413
|
+
laughlin_metropolis_sweep(z, m=3, step=0.5)
|
|
414
|
+
dists = np.abs(z[:, None] - z[None, :]) + np.eye(4) * 10
|
|
415
|
+
assert dists.min() > 1e-3
|
|
416
|
+
|
|
417
|
+
def test_correlation_hole_vanishes_near_origin(self):
|
|
418
|
+
rng = np.random.default_rng(1)
|
|
419
|
+
N, m = 10, 3
|
|
420
|
+
R0 = np.sqrt(2 * m * N)
|
|
421
|
+
r0 = R0 * np.sqrt(rng.random(N))
|
|
422
|
+
theta0 = rng.uniform(0, 2 * np.pi, N)
|
|
423
|
+
z = (r0 * np.cos(theta0) + 1j * r0 * np.sin(theta0)).astype(np.complex128)
|
|
424
|
+
for _ in range(500):
|
|
425
|
+
laughlin_metropolis_sweep(z, m=m, step=1.0)
|
|
426
|
+
samples = np.array([laughlin_metropolis_sweep(z, m=m, step=1.0).copy() for _ in range(150)])
|
|
427
|
+
r, g = laughlin_pair_correlation(samples, m=m, r_max=8.0, n_bins=40)
|
|
428
|
+
assert g[0] < 0.1
|
|
429
|
+
assert g[-5:].mean() > g[0]
|
|
430
|
+
|
|
431
|
+
def test_density_falls_off_at_droplet_edge(self):
|
|
432
|
+
rng = np.random.default_rng(2)
|
|
433
|
+
N, m = 10, 3
|
|
434
|
+
R0 = np.sqrt(2 * m * N)
|
|
435
|
+
r0 = R0 * np.sqrt(rng.random(N))
|
|
436
|
+
theta0 = rng.uniform(0, 2 * np.pi, N)
|
|
437
|
+
z = (r0 * np.cos(theta0) + 1j * r0 * np.sin(theta0)).astype(np.complex128)
|
|
438
|
+
for _ in range(500):
|
|
439
|
+
laughlin_metropolis_sweep(z, m=m, step=1.0)
|
|
440
|
+
samples = np.array([laughlin_metropolis_sweep(z, m=m, step=1.0).copy() for _ in range(150)])
|
|
441
|
+
r, density = laughlin_radial_density(samples, r_max=2 * R0, n_bins=20)
|
|
442
|
+
assert density[-1] < density[2]
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
class TestLatticeFactories:
|
|
446
|
+
def test_triangular_kagome_and_cubic_have_expected_orbital_counts(self):
|
|
447
|
+
assert Lattice.triangular().n_orbitals == 1
|
|
448
|
+
assert Lattice.kagome().n_orbitals == 3
|
|
449
|
+
assert Lattice.cubic().dim == 3
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def test_add_hopping_rejects_diagonal_onsite_term():
|
|
453
|
+
H = Hamiltonian(Lattice.chain())
|
|
454
|
+
with pytest.raises(ValueError, match="onsite"):
|
|
455
|
+
H.add_hopping(0, 0, (0,), 1.0)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def test_lattice_square_has_two_orthogonal_orbital_lattice_vectors():
|
|
459
|
+
lat = Lattice.square(a=2.0)
|
|
460
|
+
assert lat.n_orbitals == 1
|
|
461
|
+
np.testing.assert_allclose(lat.lattice_vectors, [[2.0, 0.0], [0.0, 2.0]])
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def test_reciprocal_vectors_of_square_lattice():
|
|
465
|
+
lat = Lattice.square(a=1.0)
|
|
466
|
+
np.testing.assert_allclose(lat.reciprocal_vectors(), 2 * np.pi * np.eye(2))
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
def test_hamiltonian_bands_matches_bloch_eigenvalues():
|
|
470
|
+
H = Hamiltonian(Lattice.chain())
|
|
471
|
+
H.add_hopping(0, 0, (1,), 1.0)
|
|
472
|
+
np.testing.assert_allclose(H.bands([np.pi]), [-2.0])
|
|
473
|
+
|
|
474
|
+
|
|
475
|
+
def test_apply_peierls_phase_matches_docstring_example():
|
|
476
|
+
positions = np.array([[0.0, 0.0], [1.0, 0.0]])
|
|
477
|
+
bonds = [(0, 1, 1.0)]
|
|
478
|
+
out = apply_peierls_phase(positions, bonds, flux_quanta_per_plaquette=0.25, area_per_plaquette=1.0)
|
|
479
|
+
assert len(out) == 1
|
|
480
|
+
i, j, amp = out[0]
|
|
481
|
+
assert (i, j) == (0, 1)
|
|
482
|
+
assert abs(amp) == pytest.approx(1.0)
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def test_bdg_spectrum_minimum_energy_equals_pairing_gap():
|
|
486
|
+
k, E = bdg_spectrum(mu=0.0, t=1.0, delta=0.5, n_k=400)
|
|
487
|
+
assert k.shape == E.shape
|
|
488
|
+
assert E.min() == pytest.approx(0.5, abs=1e-3)
|
|
489
|
+
assert np.all(E >= 0.0)
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def test_landau_density_of_states_matches_docstring_value():
|
|
493
|
+
dos = landau_density_of_states([0.5], B=1.0, n_max=0, broadening=0.1)
|
|
494
|
+
assert dos[0] == pytest.approx(0.6349, abs=1e-4)
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
def test_kitaev_chain_hamiltonian_matches_docstring_eigenvalues():
|
|
498
|
+
H = kitaev_chain_hamiltonian(k=np.pi / 2, mu=0.0, t=1.0, delta=1.0)
|
|
499
|
+
np.testing.assert_allclose(np.sort(np.linalg.eigvalsh(H)), [-2.0, 2.0])
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def test_surface_dirac_hamiltonian_matches_docstring_eigenvalues():
|
|
503
|
+
H = surface_dirac_hamiltonian(0.3, -0.4, v_f=2.0)
|
|
504
|
+
np.testing.assert_allclose(np.sort(np.linalg.eigvalsh(H)), [-1.0, 1.0])
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
def test_public_api_exposed_via_pk_condensed():
|
|
508
|
+
assert pk.condensed.compute_chern_number is compute_chern_number
|
|
509
|
+
assert hasattr(pk.condensed, "haldane_model")
|
|
510
|
+
assert hasattr(pk.condensed, "landau_level_energies")
|
|
511
|
+
assert hasattr(pk.condensed, "gl_coherence_length")
|
|
512
|
+
assert hasattr(pk.condensed, "anderson_chain_hamiltonian")
|
|
513
|
+
assert hasattr(pk.condensed, "topological_insulator_3d_hamiltonian")
|
|
514
|
+
assert hasattr(pk.condensed, "bhz_ribbon_hamiltonian")
|
|
515
|
+
assert hasattr(pk.condensed, "harper_hofstadter_hamiltonian")
|
|
516
|
+
assert hasattr(pk.condensed, "hubbard_spin_correlations")
|
|
517
|
+
assert hasattr(pk.condensed, "weyl_semimetal_hamiltonian")
|
|
518
|
+
assert hasattr(pk.condensed, "laughlin_pair_correlation")
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Smoke tests for physicskit.condensed.visualizers: every plot returns a
|
|
2
|
+
populated figure, covering both the ax=None and ax=<given> branches. All
|
|
3
|
+
pure matplotlib/plotly plotting -- no numba, no file I/O -- so kept small
|
|
4
|
+
and fast."""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
import numpy as np
|
|
10
|
+
|
|
11
|
+
from physicskit.condensed.models import graphene_hamiltonian, haldane_model, ssh_lattice_hamiltonian
|
|
12
|
+
from physicskit.condensed.tight_binding import build_finite_cluster, build_ribbon
|
|
13
|
+
from physicskit.condensed.topology import compute_berry_curvature
|
|
14
|
+
from physicskit.condensed.visualizers import (
|
|
15
|
+
plot_band_structure,
|
|
16
|
+
plot_berry_curvature,
|
|
17
|
+
plot_edge_state_density,
|
|
18
|
+
plot_fermi_surface_3d,
|
|
19
|
+
plot_lattice_structure,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def test_plot_band_structure_with_and_without_labels_and_given_ax():
|
|
24
|
+
path = [(0, 0), (2 * np.pi / 3, 4 * np.pi / 3), (0, 0)]
|
|
25
|
+
fig, ax = plot_band_structure(lambda k1, k2: graphene_hamiltonian(k1, k2), path)
|
|
26
|
+
assert isinstance(fig, plt.Figure)
|
|
27
|
+
|
|
28
|
+
fig2, ax2 = plot_band_structure(lambda k1, k2: graphene_hamiltonian(k1, k2), path, labels=["G", "K", "G"])
|
|
29
|
+
assert [t.get_text() for t in ax2.get_xticklabels()] == ["G", "K", "G"]
|
|
30
|
+
|
|
31
|
+
_, ax_given = plot_band_structure(lambda k1, k2: graphene_hamiltonian(k1, k2), path, ax=ax)
|
|
32
|
+
assert ax_given is ax
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_plot_berry_curvature_returns_heatmap():
|
|
36
|
+
H = lambda k1, k2: haldane_model(k1, k2, phi=np.pi / 2)
|
|
37
|
+
F = compute_berry_curvature(H, grid_size=8, band_index=0)
|
|
38
|
+
fig, ax = plot_berry_curvature(F)
|
|
39
|
+
assert isinstance(fig, plt.Figure)
|
|
40
|
+
assert len(ax.images) == 1
|
|
41
|
+
|
|
42
|
+
_, ax_given = plot_berry_curvature(F, ax=ax)
|
|
43
|
+
assert ax_given is ax
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_plot_edge_state_density_returns_density_array():
|
|
47
|
+
H = ssh_lattice_hamiltonian(v=0.5, w=1.0)
|
|
48
|
+
H_wire = build_ribbon(H, open_direction=0, n_cells=6)
|
|
49
|
+
fig, ax, density = plot_edge_state_density(H_wire, k_parallel=[])
|
|
50
|
+
assert isinstance(fig, plt.Figure)
|
|
51
|
+
assert density[0] > density[len(density) // 2]
|
|
52
|
+
|
|
53
|
+
_, ax_given, _ = plot_edge_state_density(H_wire, k_parallel=[], ax=ax)
|
|
54
|
+
assert ax_given is ax
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_plot_lattice_structure_with_and_without_weights():
|
|
58
|
+
H, positions, bonds = build_finite_cluster(ssh_lattice_hamiltonian(v=0.5, w=1.0), n_cells=3)
|
|
59
|
+
_, states = np.linalg.eigh(H)
|
|
60
|
+
density = np.abs(states[:, 0]) ** 2
|
|
61
|
+
|
|
62
|
+
fig, ax = plot_lattice_structure(positions, bonds)
|
|
63
|
+
assert isinstance(fig, plt.Figure)
|
|
64
|
+
assert len(ax.collections) == 1 # unweighted scatter, no colorbar
|
|
65
|
+
|
|
66
|
+
fig2, ax2 = plot_lattice_structure(positions, bonds, weights=density)
|
|
67
|
+
assert len(fig2.axes) == 2 # main axes + colorbar axes
|
|
68
|
+
assert len(ax2.collections) == 1
|
|
69
|
+
|
|
70
|
+
_, ax_given = plot_lattice_structure(positions, bonds, ax=ax)
|
|
71
|
+
assert ax_given is ax
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def test_plot_lattice_structure_1d_positions_and_zero_max_weight():
|
|
75
|
+
"""1D positions (dim=1) get y=0, and an all-zero weights array takes
|
|
76
|
+
the max_w<=0 fallback branch for marker sizing."""
|
|
77
|
+
positions = np.array([[0.0], [1.0], [2.0]])
|
|
78
|
+
bonds = [(0, 1, 1.0), (1, 2, 1.0)]
|
|
79
|
+
fig, ax = plot_lattice_structure(positions, bonds, weights=np.zeros(3))
|
|
80
|
+
assert isinstance(fig, plt.Figure)
|
|
81
|
+
assert len(ax.collections) == 1
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_plot_fermi_surface_3d_returns_isosurface_trace():
|
|
85
|
+
eps = lambda kx, ky, kz: -2 * (np.cos(kx) + np.cos(ky) + np.cos(kz))
|
|
86
|
+
fig = plot_fermi_surface_3d(eps, mu=0.0, grid_size=6)
|
|
87
|
+
assert fig.data[0].type == "isosurface"
|