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.
Files changed (484) hide show
  1. physicskit/__init__.py +51 -0
  2. physicskit/astro/__init__.py +66 -0
  3. physicskit/astro/cosmic_web.py +395 -0
  4. physicskit/astro/galactic_dynamics.py +137 -0
  5. physicskit/astro/nbody.py +208 -0
  6. physicskit/astro/orbital_mechanics.py +220 -0
  7. physicskit/astro/stellar_dynamo.py +628 -0
  8. physicskit/astro/stellar_structure.py +198 -0
  9. physicskit/astro/tests/__init__.py +0 -0
  10. physicskit/astro/tests/conftest.py +7 -0
  11. physicskit/astro/tests/test_cosmic_web.py +159 -0
  12. physicskit/astro/tests/test_galactic_dynamics.py +46 -0
  13. physicskit/astro/tests/test_nbody.py +81 -0
  14. physicskit/astro/tests/test_orbital_mechanics.py +73 -0
  15. physicskit/astro/tests/test_stellar_dynamo.py +198 -0
  16. physicskit/astro/tests/test_stellar_structure.py +52 -0
  17. physicskit/astro/tests/test_visualizers.py +159 -0
  18. physicskit/astro/visualizers.py +628 -0
  19. physicskit/chaos/__init__.py +55 -0
  20. physicskit/chaos/core/__init__.py +3 -0
  21. physicskit/chaos/core/base_system.py +342 -0
  22. physicskit/chaos/core/integrators.py +40 -0
  23. physicskit/chaos/exceptions.py +24 -0
  24. physicskit/chaos/quantum/__init__.py +38 -0
  25. physicskit/chaos/quantum/billiards.py +274 -0
  26. physicskit/chaos/quantum/husimi.py +85 -0
  27. physicskit/chaos/quantum/maps.py +366 -0
  28. physicskit/chaos/systems/__init__.py +38 -0
  29. physicskit/chaos/systems/billiards.py +1131 -0
  30. physicskit/chaos/systems/continuous.py +1276 -0
  31. physicskit/chaos/systems/maps.py +557 -0
  32. physicskit/chaos/tests/__init__.py +0 -0
  33. physicskit/chaos/tests/test_basins.py +76 -0
  34. physicskit/chaos/tests/test_bifurcation.py +132 -0
  35. physicskit/chaos/tests/test_billiards.py +115 -0
  36. physicskit/chaos/tests/test_continuous.py +224 -0
  37. physicskit/chaos/tests/test_dimension.py +69 -0
  38. physicskit/chaos/tests/test_divergence.py +90 -0
  39. physicskit/chaos/tests/test_dynamic_plots.py +269 -0
  40. physicskit/chaos/tests/test_integrators.py +96 -0
  41. physicskit/chaos/tests/test_io.py +41 -0
  42. physicskit/chaos/tests/test_maps.py +110 -0
  43. physicskit/chaos/tests/test_metrics.py +115 -0
  44. physicskit/chaos/tests/test_phase_space.py +73 -0
  45. physicskit/chaos/tests/test_properties.py +116 -0
  46. physicskit/chaos/tests/test_quantum_billiards.py +94 -0
  47. physicskit/chaos/tests/test_quantum_maps.py +144 -0
  48. physicskit/chaos/tests/test_recurrence.py +51 -0
  49. physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
  50. physicskit/chaos/tests/test_section.py +49 -0
  51. physicskit/chaos/tests/test_spectral.py +48 -0
  52. physicskit/chaos/tests/test_streamlit_app.py +45 -0
  53. physicskit/chaos/tests/test_timeseries.py +131 -0
  54. physicskit/chaos/tests/test_viewer3d.py +41 -0
  55. physicskit/chaos/utils/__init__.py +46 -0
  56. physicskit/chaos/utils/dimension.py +139 -0
  57. physicskit/chaos/utils/io.py +95 -0
  58. physicskit/chaos/utils/metrics.py +304 -0
  59. physicskit/chaos/utils/recurrence.py +122 -0
  60. physicskit/chaos/utils/spectral.py +69 -0
  61. physicskit/chaos/utils/timeseries.py +303 -0
  62. physicskit/chaos/visualizers/__init__.py +85 -0
  63. physicskit/chaos/visualizers/basins.py +185 -0
  64. physicskit/chaos/visualizers/bifurcation.py +273 -0
  65. physicskit/chaos/visualizers/divergence.py +374 -0
  66. physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
  67. physicskit/chaos/visualizers/phase_space.py +133 -0
  68. physicskit/chaos/visualizers/quantum.py +299 -0
  69. physicskit/chaos/visualizers/recurrence.py +91 -0
  70. physicskit/chaos/visualizers/section.py +161 -0
  71. physicskit/chaos/visualizers/theme.py +31 -0
  72. physicskit/chaos/visualizers/viewer3d.py +82 -0
  73. physicskit/classical/__init__.py +55 -0
  74. physicskit/classical/core/__init__.py +17 -0
  75. physicskit/classical/core/base_system.py +510 -0
  76. physicskit/classical/core/integrators.py +397 -0
  77. physicskit/classical/systems/__init__.py +32 -0
  78. physicskit/classical/systems/chains.py +334 -0
  79. physicskit/classical/systems/hamiltonian.py +215 -0
  80. physicskit/classical/systems/lagrangian.py +308 -0
  81. physicskit/classical/systems/newtonian.py +536 -0
  82. physicskit/classical/systems/rotations.py +614 -0
  83. physicskit/classical/tests/__init__.py +0 -0
  84. physicskit/classical/tests/conftest.py +7 -0
  85. physicskit/classical/tests/test_base_system.py +113 -0
  86. physicskit/classical/tests/test_chains.py +84 -0
  87. physicskit/classical/tests/test_conservation.py +244 -0
  88. physicskit/classical/tests/test_conservation_utils.py +47 -0
  89. physicskit/classical/tests/test_hamiltonian.py +44 -0
  90. physicskit/classical/tests/test_integrators.py +123 -0
  91. physicskit/classical/tests/test_lagrangian.py +69 -0
  92. physicskit/classical/tests/test_newtonian.py +45 -0
  93. physicskit/classical/tests/test_rotations.py +160 -0
  94. physicskit/classical/tests/test_stepsize.py +149 -0
  95. physicskit/classical/tests/test_symbolic.py +125 -0
  96. physicskit/classical/tests/test_visualizers.py +172 -0
  97. physicskit/classical/utils/__init__.py +20 -0
  98. physicskit/classical/utils/conservation.py +126 -0
  99. physicskit/classical/utils/stepsize.py +187 -0
  100. physicskit/classical/utils/symbolic.py +235 -0
  101. physicskit/classical/visualizers/__init__.py +25 -0
  102. physicskit/classical/visualizers/animations.py +508 -0
  103. physicskit/classical/visualizers/interactive.py +113 -0
  104. physicskit/classical/visualizers/modal_analysis.py +97 -0
  105. physicskit/classical/visualizers/phase_space.py +214 -0
  106. physicskit/condensed/__init__.py +122 -0
  107. physicskit/condensed/anderson_localization.py +155 -0
  108. physicskit/condensed/correlated.py +284 -0
  109. physicskit/condensed/ginzburg_landau.py +220 -0
  110. physicskit/condensed/landau_levels.py +246 -0
  111. physicskit/condensed/laughlin.py +229 -0
  112. physicskit/condensed/models.py +627 -0
  113. physicskit/condensed/tests/__init__.py +0 -0
  114. physicskit/condensed/tests/test_condensed.py +518 -0
  115. physicskit/condensed/tests/test_visualizers.py +87 -0
  116. physicskit/condensed/tight_binding.py +445 -0
  117. physicskit/condensed/topological_insulator_3d.py +178 -0
  118. physicskit/condensed/topology.py +217 -0
  119. physicskit/condensed/visualizers.py +296 -0
  120. physicskit/condensed/weyl.py +180 -0
  121. physicskit/constants.py +184 -0
  122. physicskit/fields/__init__.py +111 -0
  123. physicskit/fields/electrodynamics.py +671 -0
  124. physicskit/fields/quantum_fields.py +510 -0
  125. physicskit/fields/solitons.py +527 -0
  126. physicskit/fields/tests/__init__.py +0 -0
  127. physicskit/fields/tests/conftest.py +7 -0
  128. physicskit/fields/tests/test_field_animations.py +154 -0
  129. physicskit/fields/tests/test_fields.py +439 -0
  130. physicskit/fields/tests/test_visualizers.py +101 -0
  131. physicskit/fields/visualizers.py +503 -0
  132. physicskit/fluids/__init__.py +134 -0
  133. physicskit/fluids/core/__init__.py +23 -0
  134. physicskit/fluids/core/grid.py +165 -0
  135. physicskit/fluids/core/timestepping.py +231 -0
  136. physicskit/fluids/exceptions.py +26 -0
  137. physicskit/fluids/systems/__init__.py +70 -0
  138. physicskit/fluids/systems/compressible_flow.py +281 -0
  139. physicskit/fluids/systems/instabilities.py +343 -0
  140. physicskit/fluids/systems/navier_stokes.py +221 -0
  141. physicskit/fluids/systems/potential_flow.py +440 -0
  142. physicskit/fluids/systems/viscous_flow.py +425 -0
  143. physicskit/fluids/systems/vortex_dynamics.py +304 -0
  144. physicskit/fluids/tests/__init__.py +0 -0
  145. physicskit/fluids/tests/conftest.py +7 -0
  146. physicskit/fluids/tests/test_compressible_flow.py +66 -0
  147. physicskit/fluids/tests/test_instabilities.py +115 -0
  148. physicskit/fluids/tests/test_navier_stokes.py +67 -0
  149. physicskit/fluids/tests/test_potential_flow.py +92 -0
  150. physicskit/fluids/tests/test_static_visualizers.py +91 -0
  151. physicskit/fluids/tests/test_utils.py +100 -0
  152. physicskit/fluids/tests/test_viscous_flow.py +110 -0
  153. physicskit/fluids/tests/test_visualizers.py +34 -0
  154. physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
  155. physicskit/fluids/utils/__init__.py +18 -0
  156. physicskit/fluids/utils/dimensionless.py +239 -0
  157. physicskit/fluids/utils/spectral_analysis.py +142 -0
  158. physicskit/fluids/visualizers/__init__.py +14 -0
  159. physicskit/fluids/visualizers/compressible.py +39 -0
  160. physicskit/fluids/visualizers/flow_fields.py +252 -0
  161. physicskit/fluids/visualizers/potential_flow.py +51 -0
  162. physicskit/fluids/visualizers/spectra.py +62 -0
  163. physicskit/fluids/visualizers/theme.py +38 -0
  164. physicskit/integrators/__init__.py +52 -0
  165. physicskit/integrators/adaptive.py +199 -0
  166. physicskit/integrators/fixed_step.py +360 -0
  167. physicskit/integrators/tests/__init__.py +0 -0
  168. physicskit/integrators/tests/test_integrators.py +101 -0
  169. physicskit/optics/__init__.py +124 -0
  170. physicskit/optics/_compat.py +5 -0
  171. physicskit/optics/gaussian.py +382 -0
  172. physicskit/optics/quantum_optics.py +428 -0
  173. physicskit/optics/ray.py +469 -0
  174. physicskit/optics/tests/__init__.py +0 -0
  175. physicskit/optics/tests/test_diffraction_animation.py +38 -0
  176. physicskit/optics/tests/test_gaussian.py +170 -0
  177. physicskit/optics/tests/test_quantum_optics.py +147 -0
  178. physicskit/optics/tests/test_ray.py +177 -0
  179. physicskit/optics/tests/test_visualizers.py +58 -0
  180. physicskit/optics/tests/test_wave.py +146 -0
  181. physicskit/optics/visualizers.py +264 -0
  182. physicskit/optics/wave.py +365 -0
  183. physicskit/particle/__init__.py +152 -0
  184. physicskit/particle/collider.py +382 -0
  185. physicskit/particle/confinement.py +125 -0
  186. physicskit/particle/decays.py +357 -0
  187. physicskit/particle/electroweak.py +300 -0
  188. physicskit/particle/kinematics.py +271 -0
  189. physicskit/particle/neutrinos.py +84 -0
  190. physicskit/particle/nuclear.py +100 -0
  191. physicskit/particle/scattering.py +159 -0
  192. physicskit/particle/tests/__init__.py +0 -0
  193. physicskit/particle/tests/conftest.py +7 -0
  194. physicskit/particle/tests/test_collider.py +119 -0
  195. physicskit/particle/tests/test_confinement.py +42 -0
  196. physicskit/particle/tests/test_decays.py +112 -0
  197. physicskit/particle/tests/test_electroweak.py +97 -0
  198. physicskit/particle/tests/test_kinematics.py +138 -0
  199. physicskit/particle/tests/test_neutrinos.py +36 -0
  200. physicskit/particle/tests/test_nuclear.py +45 -0
  201. physicskit/particle/tests/test_scattering.py +64 -0
  202. physicskit/particle/tests/test_visualizers.py +214 -0
  203. physicskit/particle/visualizers/__init__.py +38 -0
  204. physicskit/particle/visualizers/animations.py +705 -0
  205. physicskit/particle/visualizers/static.py +101 -0
  206. physicskit/plasma/__init__.py +176 -0
  207. physicskit/plasma/acceleration.py +152 -0
  208. physicskit/plasma/instabilities.py +417 -0
  209. physicskit/plasma/kinetic.py +588 -0
  210. physicskit/plasma/mhd.py +463 -0
  211. physicskit/plasma/single_particle.py +562 -0
  212. physicskit/plasma/tests/__init__.py +0 -0
  213. physicskit/plasma/tests/conftest.py +7 -0
  214. physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
  215. physicskit/plasma/tests/test_plasma.py +232 -0
  216. physicskit/plasma/tests/test_visualizers.py +79 -0
  217. physicskit/plasma/turbulence.py +219 -0
  218. physicskit/plasma/visualizers.py +868 -0
  219. physicskit/plasma/waves.py +549 -0
  220. physicskit/quantum/__init__.py +180 -0
  221. physicskit/quantum/_compat.py +20 -0
  222. physicskit/quantum/chapters/__init__.py +0 -0
  223. physicskit/quantum/chapters/entanglement.py +489 -0
  224. physicskit/quantum/chapters/harmonic_spin.py +517 -0
  225. physicskit/quantum/chapters/hydrogen_am.py +292 -0
  226. physicskit/quantum/chapters/perturbation.py +350 -0
  227. physicskit/quantum/chapters/potentials.py +997 -0
  228. physicskit/quantum/chapters/spin.py +306 -0
  229. physicskit/quantum/chapters/wave_packets.py +541 -0
  230. physicskit/quantum/core/__init__.py +0 -0
  231. physicskit/quantum/core/eigensolvers.py +311 -0
  232. physicskit/quantum/core/operators.py +296 -0
  233. physicskit/quantum/core/solvers.py +271 -0
  234. physicskit/quantum/tests/__init__.py +0 -0
  235. physicskit/quantum/tests/conftest.py +7 -0
  236. physicskit/quantum/tests/test_animations.py +225 -0
  237. physicskit/quantum/tests/test_compat.py +43 -0
  238. physicskit/quantum/tests/test_eigensolvers.py +24 -0
  239. physicskit/quantum/tests/test_entanglement.py +127 -0
  240. physicskit/quantum/tests/test_harmonic_spin.py +140 -0
  241. physicskit/quantum/tests/test_hydrogen_am.py +48 -0
  242. physicskit/quantum/tests/test_measure.py +110 -0
  243. physicskit/quantum/tests/test_operators.py +105 -0
  244. physicskit/quantum/tests/test_perturbation.py +112 -0
  245. physicskit/quantum/tests/test_physics_checks.py +131 -0
  246. physicskit/quantum/tests/test_potentials.py +191 -0
  247. physicskit/quantum/tests/test_solvers.py +70 -0
  248. physicskit/quantum/tests/test_spin.py +22 -0
  249. physicskit/quantum/tests/test_unitarity.py +84 -0
  250. physicskit/quantum/tests/test_wave_packets.py +53 -0
  251. physicskit/quantum/utils/__init__.py +0 -0
  252. physicskit/quantum/utils/measure.py +253 -0
  253. physicskit/quantum/visualizers/__init__.py +0 -0
  254. physicskit/quantum/visualizers/bloch_sphere.py +205 -0
  255. physicskit/quantum/visualizers/entanglement.py +58 -0
  256. physicskit/quantum/visualizers/orbitals.py +187 -0
  257. physicskit/quantum/visualizers/phase_space.py +179 -0
  258. physicskit/quantum/visualizers/wavefunctions.py +230 -0
  259. physicskit/relativity/__init__.py +61 -0
  260. physicskit/relativity/chapters/__init__.py +33 -0
  261. physicskit/relativity/chapters/cosmology.py +190 -0
  262. physicskit/relativity/chapters/gw_merger.py +399 -0
  263. physicskit/relativity/chapters/kerr.py +371 -0
  264. physicskit/relativity/chapters/lensing.py +196 -0
  265. physicskit/relativity/chapters/neutron_star.py +149 -0
  266. physicskit/relativity/chapters/schwarzschild.py +412 -0
  267. physicskit/relativity/chapters/timekeeping.py +133 -0
  268. physicskit/relativity/core/__init__.py +12 -0
  269. physicskit/relativity/core/geodesics.py +216 -0
  270. physicskit/relativity/core/kerr_raytracer.py +259 -0
  271. physicskit/relativity/core/raytracer.py +241 -0
  272. physicskit/relativity/core/tensors.py +468 -0
  273. physicskit/relativity/tests/__init__.py +0 -0
  274. physicskit/relativity/tests/test_conservations.py +54 -0
  275. physicskit/relativity/tests/test_constants.py +34 -0
  276. physicskit/relativity/tests/test_cosmology.py +61 -0
  277. physicskit/relativity/tests/test_gw_merger.py +117 -0
  278. physicskit/relativity/tests/test_kerr.py +116 -0
  279. physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
  280. physicskit/relativity/tests/test_lensing.py +75 -0
  281. physicskit/relativity/tests/test_neutron_star.py +48 -0
  282. physicskit/relativity/tests/test_raytracer.py +67 -0
  283. physicskit/relativity/tests/test_schwarzschild.py +126 -0
  284. physicskit/relativity/tests/test_shadow_render.py +81 -0
  285. physicskit/relativity/tests/test_tensors.py +86 -0
  286. physicskit/relativity/tests/test_timekeeping.py +51 -0
  287. physicskit/relativity/tests/test_visualizers_misc.py +115 -0
  288. physicskit/relativity/utils/__init__.py +1 -0
  289. physicskit/relativity/utils/constants.py +232 -0
  290. physicskit/relativity/visualizers/__init__.py +46 -0
  291. physicskit/relativity/visualizers/interactive.py +127 -0
  292. physicskit/relativity/visualizers/shadow_render.py +367 -0
  293. physicskit/relativity/visualizers/spacetime_3d.py +92 -0
  294. physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
  295. physicskit/relativity/visualizers/wave_plots.py +185 -0
  296. physicskit/rmt/__init__.py +8 -0
  297. physicskit/rmt/ensembles/__init__.py +108 -0
  298. physicskit/rmt/ensembles/banded.py +114 -0
  299. physicskit/rmt/ensembles/base.py +135 -0
  300. physicskit/rmt/ensembles/bdg.py +218 -0
  301. physicskit/rmt/ensembles/chiral.py +308 -0
  302. physicskit/rmt/ensembles/circular.py +104 -0
  303. physicskit/rmt/ensembles/crossover.py +82 -0
  304. physicskit/rmt/ensembles/density_matrix.py +148 -0
  305. physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
  306. physicskit/rmt/ensembles/embedded.py +207 -0
  307. physicskit/rmt/ensembles/gaussian.py +153 -0
  308. physicskit/rmt/ensembles/ginibre.py +110 -0
  309. physicskit/rmt/ensembles/girko.py +190 -0
  310. physicskit/rmt/ensembles/graph_laplacian.py +92 -0
  311. physicskit/rmt/ensembles/haar.py +57 -0
  312. physicskit/rmt/ensembles/jacobi.py +182 -0
  313. physicskit/rmt/ensembles/poisson.py +77 -0
  314. physicskit/rmt/ensembles/polynomial.py +139 -0
  315. physicskit/rmt/ensembles/pt_symmetric.py +120 -0
  316. physicskit/rmt/ensembles/single_ring.py +170 -0
  317. physicskit/rmt/ensembles/sparse.py +95 -0
  318. physicskit/rmt/ensembles/syk.py +170 -0
  319. physicskit/rmt/ensembles/truncated_unitary.py +80 -0
  320. physicskit/rmt/ensembles/universality.py +92 -0
  321. physicskit/rmt/ensembles/wishart.py +88 -0
  322. physicskit/rmt/py.typed +0 -0
  323. physicskit/rmt/spectrum.py +82 -0
  324. physicskit/rmt/stats/__init__.py +160 -0
  325. physicskit/rmt/stats/characteristic_polynomial.py +77 -0
  326. physicskit/rmt/stats/circular_law.py +54 -0
  327. physicskit/rmt/stats/correlations.py +162 -0
  328. physicskit/rmt/stats/density.py +70 -0
  329. physicskit/rmt/stats/entanglement.py +36 -0
  330. physicskit/rmt/stats/free_probability.py +202 -0
  331. physicskit/rmt/stats/localization.py +338 -0
  332. physicskit/rmt/stats/marchenko_pastur.py +55 -0
  333. physicskit/rmt/stats/pt_symmetric.py +265 -0
  334. physicskit/rmt/stats/ratios.py +110 -0
  335. physicskit/rmt/stats/real_ginibre.py +134 -0
  336. physicskit/rmt/stats/rigidity.py +272 -0
  337. physicskit/rmt/stats/single_ring.py +95 -0
  338. physicskit/rmt/stats/spacing.py +150 -0
  339. physicskit/rmt/stats/tracy_widom.py +175 -0
  340. physicskit/rmt/stats/truncated_unitary.py +40 -0
  341. physicskit/rmt/stats/unfolding.py +37 -0
  342. physicskit/rmt/stats/wachter.py +67 -0
  343. physicskit/rmt/tests/__init__.py +0 -0
  344. physicskit/rmt/tests/cache_utils.py +107 -0
  345. physicskit/rmt/tests/conftest.py +8 -0
  346. physicskit/rmt/tests/test_banded.py +86 -0
  347. physicskit/rmt/tests/test_base.py +29 -0
  348. physicskit/rmt/tests/test_bdg.py +133 -0
  349. physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
  350. physicskit/rmt/tests/test_chiral.py +273 -0
  351. physicskit/rmt/tests/test_circular.py +225 -0
  352. physicskit/rmt/tests/test_crossover.py +72 -0
  353. physicskit/rmt/tests/test_density.py +23 -0
  354. physicskit/rmt/tests/test_density_matrix.py +181 -0
  355. physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
  356. physicskit/rmt/tests/test_embedded.py +169 -0
  357. physicskit/rmt/tests/test_free_probability.py +81 -0
  358. physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
  359. physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
  360. physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
  361. physicskit/rmt/tests/test_girko.py +178 -0
  362. physicskit/rmt/tests/test_graph_laplacian.py +102 -0
  363. physicskit/rmt/tests/test_haar.py +118 -0
  364. physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
  365. physicskit/rmt/tests/test_localization.py +240 -0
  366. physicskit/rmt/tests/test_poisson.py +149 -0
  367. physicskit/rmt/tests/test_polynomial.py +107 -0
  368. physicskit/rmt/tests/test_pt_symmetric.py +178 -0
  369. physicskit/rmt/tests/test_random_state.py +19 -0
  370. physicskit/rmt/tests/test_real_ginibre.py +112 -0
  371. physicskit/rmt/tests/test_rigidity_universality.py +167 -0
  372. physicskit/rmt/tests/test_single_ring.py +132 -0
  373. physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
  374. physicskit/rmt/tests/test_sparse.py +71 -0
  375. physicskit/rmt/tests/test_spectrum.py +27 -0
  376. physicskit/rmt/tests/test_syk.py +136 -0
  377. physicskit/rmt/tests/test_tracy_widom.py +113 -0
  378. physicskit/rmt/tests/test_tridiagonal.py +41 -0
  379. physicskit/rmt/tests/test_truncated_unitary.py +80 -0
  380. physicskit/rmt/tests/test_validation_base.py +25 -0
  381. physicskit/rmt/tests/test_validation_misc.py +67 -0
  382. physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
  383. physicskit/rmt/utils/__init__.py +0 -0
  384. physicskit/rmt/utils/haar.py +128 -0
  385. physicskit/rmt/utils/random_state.py +24 -0
  386. physicskit/rmt/utils/tridiagonal.py +167 -0
  387. physicskit/rmt/validation/__init__.py +36 -0
  388. physicskit/rmt/validation/base.py +126 -0
  389. physicskit/rmt/validation/circular_law.py +80 -0
  390. physicskit/rmt/validation/marchenko_pastur.py +53 -0
  391. physicskit/rmt/validation/ratio_distribution.py +53 -0
  392. physicskit/rmt/validation/real_ginibre.py +60 -0
  393. physicskit/rmt/validation/sine_kernel.py +57 -0
  394. physicskit/rmt/validation/single_ring.py +68 -0
  395. physicskit/rmt/validation/tracy_widom.py +89 -0
  396. physicskit/rmt/validation/universality.py +100 -0
  397. physicskit/rmt/validation/wachter.py +52 -0
  398. physicskit/rmt/validation/wigner_semicircle.py +40 -0
  399. physicskit/rmt/validation/wigner_surmise.py +58 -0
  400. physicskit/semiclassical/__init__.py +94 -0
  401. physicskit/semiclassical/_compat.py +5 -0
  402. physicskit/semiclassical/core/__init__.py +41 -0
  403. physicskit/semiclassical/core/gutzwiller.py +215 -0
  404. physicskit/semiclassical/core/path_integral.py +594 -0
  405. physicskit/semiclassical/core/propagators.py +579 -0
  406. physicskit/semiclassical/core/wkb.py +308 -0
  407. physicskit/semiclassical/systems/__init__.py +13 -0
  408. physicskit/semiclassical/systems/scarring.py +278 -0
  409. physicskit/semiclassical/tests/__init__.py +0 -0
  410. physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
  411. physicskit/semiclassical/tests/test_path_integral.py +194 -0
  412. physicskit/semiclassical/tests/test_propagators.py +82 -0
  413. physicskit/semiclassical/tests/test_scarring.py +43 -0
  414. physicskit/semiclassical/tests/test_visualizers.py +89 -0
  415. physicskit/semiclassical/tests/test_wkb.py +30 -0
  416. physicskit/semiclassical/visualizers/__init__.py +17 -0
  417. physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
  418. physicskit/semiclassical/visualizers/path_integral.py +195 -0
  419. physicskit/semiclassical/visualizers/propagators.py +89 -0
  420. physicskit/semiclassical/visualizers/scarring.py +146 -0
  421. physicskit/semiclassical/visualizers/wkb.py +55 -0
  422. physicskit/statphys/__init__.py +80 -0
  423. physicskit/statphys/chapters/__init__.py +43 -0
  424. physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
  425. physicskit/statphys/chapters/ising_lattice.py +431 -0
  426. physicskit/statphys/chapters/kpz_growth.py +129 -0
  427. physicskit/statphys/chapters/molecular_dynamics.py +258 -0
  428. physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
  429. physicskit/statphys/chapters/percolation.py +305 -0
  430. physicskit/statphys/chapters/random_walk.py +142 -0
  431. physicskit/statphys/chapters/renormalization.py +148 -0
  432. physicskit/statphys/chapters/sandpile.py +109 -0
  433. physicskit/statphys/chapters/spin_glass.py +275 -0
  434. physicskit/statphys/core/__init__.py +10 -0
  435. physicskit/statphys/core/kpz_engine.py +53 -0
  436. physicskit/statphys/core/md_engine.py +157 -0
  437. physicskit/statphys/core/monte_carlo.py +462 -0
  438. physicskit/statphys/core/random_walk_engine.py +68 -0
  439. physicskit/statphys/core/sandpile_engine.py +52 -0
  440. physicskit/statphys/tests/__init__.py +0 -0
  441. physicskit/statphys/tests/test_dynamics.py +66 -0
  442. physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
  443. physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
  444. physicskit/statphys/tests/test_interactive.py +33 -0
  445. physicskit/statphys/tests/test_ising.py +68 -0
  446. physicskit/statphys/tests/test_kpz.py +55 -0
  447. physicskit/statphys/tests/test_landau_theory.py +49 -0
  448. physicskit/statphys/tests/test_md_engine.py +31 -0
  449. physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
  450. physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
  451. physicskit/statphys/tests/test_partition_function.py +26 -0
  452. physicskit/statphys/tests/test_percolation.py +116 -0
  453. physicskit/statphys/tests/test_potts_model.py +46 -0
  454. physicskit/statphys/tests/test_random_walk.py +50 -0
  455. physicskit/statphys/tests/test_renormalization.py +44 -0
  456. physicskit/statphys/tests/test_sandpile.py +44 -0
  457. physicskit/statphys/tests/test_spin_glass.py +73 -0
  458. physicskit/statphys/tests/test_thermodynamics.py +121 -0
  459. physicskit/statphys/tests/test_xy_model.py +45 -0
  460. physicskit/statphys/utils/__init__.py +1 -0
  461. physicskit/statphys/utils/dynamics.py +100 -0
  462. physicskit/statphys/utils/finite_size_scaling.py +171 -0
  463. physicskit/statphys/utils/landau_theory.py +151 -0
  464. physicskit/statphys/utils/partition_function.py +109 -0
  465. physicskit/statphys/utils/thermodynamics.py +356 -0
  466. physicskit/statphys/visualizers/__init__.py +87 -0
  467. physicskit/statphys/visualizers/interactive.py +161 -0
  468. physicskit/statphys/visualizers/jarzynski_render.py +44 -0
  469. physicskit/statphys/visualizers/kpz_render.py +65 -0
  470. physicskit/statphys/visualizers/lattice_render.py +212 -0
  471. physicskit/statphys/visualizers/particle_render.py +121 -0
  472. physicskit/statphys/visualizers/random_walk_render.py +106 -0
  473. physicskit/statphys/visualizers/rg_render.py +45 -0
  474. physicskit/statphys/visualizers/sandpile_render.py +65 -0
  475. physicskit/statphys/visualizers/spin_glass_render.py +40 -0
  476. physicskit/statphys/visualizers/urn_render.py +38 -0
  477. physicskit/statphys/visualizers/vortex_render.py +84 -0
  478. physicskit/tests/__init__.py +0 -0
  479. physicskit/tests/test_constants.py +38 -0
  480. physicskit-0.1.0.dist-info/METADATA +196 -0
  481. physicskit-0.1.0.dist-info/RECORD +484 -0
  482. physicskit-0.1.0.dist-info/WHEEL +5 -0
  483. physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
  484. physicskit-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,503 @@
1
+ """Plotting helpers for electrodynamics, soliton, and BEC fields.
2
+
3
+ Every function returns its figure object rather than calling ``show()``.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ import matplotlib.pyplot as plt
9
+ import numpy as np
10
+ from matplotlib.animation import FuncAnimation
11
+
12
+ __all__ = [
13
+ "plot_field_1d",
14
+ "plot_poynting_field",
15
+ "plot_bec_density",
16
+ "plot_bec_phase",
17
+ "animate_field_1d",
18
+ "animate_field_2d",
19
+ "animate_density_2d",
20
+ "animate_flux_tube",
21
+ "animate_casimir_modes",
22
+ ]
23
+
24
+
25
+ def plot_field_1d(x: np.ndarray, u: np.ndarray, ax=None, label: str | None = None):
26
+ """Plot a 1D field snapshot (a KdV, NLS envelope, or Sine-Gordon profile).
27
+
28
+ Parameters
29
+ ----------
30
+ x : ndarray
31
+ Spatial grid.
32
+ u : ndarray
33
+ Field values (real; pass ``numpy.abs(psi)`` for a complex envelope).
34
+ ax : matplotlib.axes.Axes, optional
35
+ Axes to draw into; a new figure is created if omitted.
36
+ label : str, optional
37
+ Legend label for this trace.
38
+
39
+ Returns
40
+ -------
41
+ fig : matplotlib.figure.Figure
42
+ ax : matplotlib.axes.Axes
43
+
44
+ Examples
45
+ --------
46
+ >>> import numpy as np
47
+ >>> from physicskit.fields.solitons import kdv_soliton
48
+ >>> x = np.linspace(-20, 20, 200)
49
+ >>> fig, ax = plot_field_1d(x, kdv_soliton(x, c=4.0))
50
+ >>> isinstance(fig, plt.Figure)
51
+ True
52
+ """
53
+ if ax is None:
54
+ fig, ax = plt.subplots()
55
+ else:
56
+ fig = ax.figure
57
+ ax.plot(x, u, label=label)
58
+ ax.set_xlabel("x")
59
+ if label is not None:
60
+ ax.legend()
61
+ return fig, ax
62
+
63
+
64
+ def plot_poynting_field(X: np.ndarray, Y: np.ndarray, Sx: np.ndarray, Sy: np.ndarray, ax=None, stride: int = 4):
65
+ """Quiver-plot the Poynting energy-flux field over a 2D grid.
66
+
67
+ Parameters
68
+ ----------
69
+ X, Y : ndarray
70
+ Real-space coordinate grids.
71
+ Sx, Sy : ndarray
72
+ Poynting vector components, as from
73
+ :func:`physicskit.fields.electrodynamics.poynting_vector_tmz`.
74
+ ax : matplotlib.axes.Axes, optional
75
+ Axes to draw into; a new figure is created if omitted.
76
+ stride : int, default=4
77
+ Subsample every ``stride``-th grid point, to keep the quiver plot legible.
78
+
79
+ Returns
80
+ -------
81
+ fig : matplotlib.figure.Figure
82
+ ax : matplotlib.axes.Axes
83
+
84
+ Examples
85
+ --------
86
+ >>> import numpy as np
87
+ >>> X, Y = np.meshgrid(np.linspace(-1, 1, 20), np.linspace(-1, 1, 20))
88
+ >>> Sx, Sy = -Y, X
89
+ >>> fig, ax = plot_poynting_field(X, Y, Sx, Sy)
90
+ >>> isinstance(fig, plt.Figure)
91
+ True
92
+ """
93
+ if ax is None:
94
+ fig, ax = plt.subplots()
95
+ else:
96
+ fig = ax.figure
97
+ sl = (slice(None, None, stride), slice(None, None, stride))
98
+ ax.quiver(X[sl], Y[sl], Sx[sl], Sy[sl])
99
+ ax.set_xlabel("x")
100
+ ax.set_ylabel("y")
101
+ ax.set_aspect("equal")
102
+ return fig, ax
103
+
104
+
105
+ def plot_bec_density(X: np.ndarray, Y: np.ndarray, psi: np.ndarray, ax=None):
106
+ """Plot the condensate density :math:`|\\psi(\\mathbf{r})|^2` as a heatmap.
107
+
108
+ Parameters
109
+ ----------
110
+ X, Y : ndarray
111
+ Real-space coordinate grids.
112
+ psi : ndarray of complex
113
+ Condensate wavefunction.
114
+ ax : matplotlib.axes.Axes, optional
115
+ Axes to draw into; a new figure is created if omitted.
116
+
117
+ Returns
118
+ -------
119
+ fig : matplotlib.figure.Figure
120
+ ax : matplotlib.axes.Axes
121
+
122
+ See Also
123
+ --------
124
+ plot_bec_phase : Plot the phase, which reveals vortex cores as singularities.
125
+
126
+ Examples
127
+ --------
128
+ >>> import numpy as np
129
+ >>> from physicskit.fields.quantum_fields import harmonic_trap_grid
130
+ >>> X, Y, KX, KY, K2 = harmonic_trap_grid(40, 10.0)
131
+ >>> psi = np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex)
132
+ >>> fig, ax = plot_bec_density(X, Y, psi)
133
+ >>> isinstance(fig, plt.Figure)
134
+ True
135
+ """
136
+ if ax is None:
137
+ fig, ax = plt.subplots()
138
+ else:
139
+ fig = ax.figure
140
+ im = ax.pcolormesh(X, Y, np.abs(psi) ** 2, cmap="viridis", shading="auto")
141
+ fig.colorbar(im, ax=ax, label=r"$|\psi|^2$")
142
+ ax.set_xlabel("x")
143
+ ax.set_ylabel("y")
144
+ ax.set_aspect("equal")
145
+ return fig, ax
146
+
147
+
148
+ def plot_bec_phase(X: np.ndarray, Y: np.ndarray, psi: np.ndarray, ax=None):
149
+ """Plot the condensate phase :math:`\\arg\\psi(\\mathbf{r})`; vortex cores appear as :math:`2\\pi` singularities.
150
+
151
+ Parameters
152
+ ----------
153
+ X, Y : ndarray
154
+ Real-space coordinate grids.
155
+ psi : ndarray of complex
156
+ Condensate wavefunction.
157
+ ax : matplotlib.axes.Axes, optional
158
+ Axes to draw into; a new figure is created if omitted.
159
+
160
+ Returns
161
+ -------
162
+ fig : matplotlib.figure.Figure
163
+ ax : matplotlib.axes.Axes
164
+
165
+ See Also
166
+ --------
167
+ plot_bec_density : Plot the density, which shows vortex cores as zeros.
168
+ physicskit.fields.quantum_fields.count_vortices : Quantitative vortex detection.
169
+
170
+ Examples
171
+ --------
172
+ >>> import numpy as np
173
+ >>> from physicskit.fields.quantum_fields import harmonic_trap_grid, gpe_imprint_vortex
174
+ >>> X, Y, KX, KY, K2 = harmonic_trap_grid(40, 10.0)
175
+ >>> psi0 = np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex)
176
+ >>> psi = gpe_imprint_vortex(psi0, X, Y, [(0.0, 0.0)])
177
+ >>> fig, ax = plot_bec_phase(X, Y, psi)
178
+ >>> isinstance(fig, plt.Figure)
179
+ True
180
+ """
181
+ if ax is None:
182
+ fig, ax = plt.subplots()
183
+ else:
184
+ fig = ax.figure
185
+ im = ax.pcolormesh(X, Y, np.angle(psi), cmap="twilight", vmin=-np.pi, vmax=np.pi, shading="auto")
186
+ fig.colorbar(im, ax=ax, label="phase (rad)")
187
+ ax.set_xlabel("x")
188
+ ax.set_ylabel("y")
189
+ ax.set_aspect("equal")
190
+ return fig, ax
191
+
192
+
193
+ def animate_field_1d(x: np.ndarray, frames: np.ndarray, times: np.ndarray | None = None, interval: int = 50, ylabel: str = "u(x, t)", ax=None) -> FuncAnimation:
194
+ """Animate a sequence of 1D field snapshots as a line plot.
195
+
196
+ Shared by the KdV, NLS, and Sine-Gordon evolvers: feed it the frames
197
+ from :func:`physicskit.fields.solitons.kdv_evolve_frames`,
198
+ :func:`~physicskit.fields.solitons.nls_evolve_frames`, or
199
+ :func:`~physicskit.fields.solitons.sine_gordon_evolve_frames`.
200
+
201
+ Parameters
202
+ ----------
203
+ x : ndarray
204
+ Spatial grid.
205
+ frames : ndarray, shape (n_frames, len(x))
206
+ Field snapshots. Complex frames (an NLS wavefunction) are plotted
207
+ as :math:`|\\psi|`; real frames (KdV, Sine-Gordon) are plotted directly.
208
+ times : ndarray, optional
209
+ Time of each frame, shown in the title.
210
+ interval : int, default=50
211
+ Delay between frames, in milliseconds.
212
+ ylabel : str, default="u(x, t)"
213
+ Y-axis label.
214
+ ax : matplotlib.axes.Axes, optional
215
+ Axes to draw into; a new figure is created if omitted.
216
+
217
+ Returns
218
+ -------
219
+ matplotlib.animation.FuncAnimation
220
+
221
+ Examples
222
+ --------
223
+ >>> import numpy as np
224
+ >>> from physicskit.fields.solitons import kdv_soliton, kdv_evolve_frames
225
+ >>> x = np.linspace(-30, 30, 256, endpoint=False)
226
+ >>> frames, times = kdv_evolve_frames(kdv_soliton(x, c=4.0, x0=-15), x, dt=0.001, steps_per_frame=50, n_frames=3)
227
+ >>> anim = animate_field_1d(x, frames, times)
228
+ >>> isinstance(anim, FuncAnimation)
229
+ True
230
+ """
231
+ if ax is None:
232
+ fig, ax = plt.subplots()
233
+ else:
234
+ fig = ax.figure
235
+ values = np.abs(frames) if np.iscomplexobj(frames) else np.asarray(frames)
236
+ ymin, ymax = values.min(), values.max()
237
+ pad = 0.1 * (ymax - ymin if ymax > ymin else 1.0)
238
+ (line,) = ax.plot(x, values[0])
239
+ ax.set_xlim(x.min(), x.max())
240
+ ax.set_ylim(ymin - pad, ymax + pad)
241
+ ax.set_xlabel("x")
242
+ ax.set_ylabel(ylabel)
243
+
244
+ def update(i):
245
+ line.set_ydata(values[i])
246
+ ax.set_title(f"t = {times[i]:.4g}" if times is not None else f"frame {i}")
247
+ return (line,)
248
+
249
+ return FuncAnimation(fig, update, frames=len(values), interval=interval, blit=False)
250
+
251
+
252
+ def animate_field_2d(
253
+ X: np.ndarray, Y: np.ndarray, frames: np.ndarray, times: np.ndarray | None = None, interval: int = 50, cmap: str = "RdBu_r", ax=None
254
+ ) -> FuncAnimation:
255
+ """Animate a sequence of 2D scalar field snapshots (e.g. FDTD ``Ez``) as an imshow heatmap.
256
+
257
+ Uses a diverging colormap centered at zero, symmetric about the
258
+ largest-magnitude value across all frames -- appropriate for an
259
+ oscillating field like ``Ez``, unlike the non-negative densities
260
+ handled by :func:`animate_density_2d`.
261
+
262
+ Parameters
263
+ ----------
264
+ X, Y : ndarray
265
+ Real-space coordinate grids (used only for their extent).
266
+ frames : ndarray, shape (n_frames, Nx, Ny)
267
+ Field snapshots, e.g. from :func:`physicskit.fields.electrodynamics.fdtd_2d_tmz_evolve`.
268
+ times : ndarray, optional
269
+ Time of each frame, shown in the title.
270
+ interval : int, default=50
271
+ Delay between frames, in milliseconds.
272
+ cmap : str, default="RdBu_r"
273
+ Diverging colormap.
274
+ ax : matplotlib.axes.Axes, optional
275
+ Axes to draw into; a new figure is created if omitted.
276
+
277
+ Returns
278
+ -------
279
+ matplotlib.animation.FuncAnimation
280
+
281
+ Examples
282
+ --------
283
+ >>> import numpy as np
284
+ >>> from physicskit.fields.electrodynamics import (
285
+ ... courant_limit_2d, fdtd_2d_tmz_evolve, oscillating_dipole_source)
286
+ >>> Nx, Ny = 30, 30
287
+ >>> x = np.arange(Nx) * 1e-3
288
+ >>> y = np.arange(Ny) * 1e-3
289
+ >>> X, Y = np.meshgrid(x, y, indexing="ij")
290
+ >>> Ez0 = Hx0 = Hy0 = np.zeros((Nx, Ny))
291
+ >>> eps_r = mu_r = np.ones((Nx, Ny))
292
+ >>> dt = 0.5 * courant_limit_2d(1e-3, 1e-3)
293
+ >>> source = oscillating_dipole_source(Nx // 2, Ny // 2, amplitude=1.0, freq=5e10)
294
+ >>> frames, times = fdtd_2d_tmz_evolve(Ez0, Hx0, Hy0, eps_r, mu_r, steps=10, dt=dt, dx=1e-3, dy=1e-3, source=source, snapshot_stride=2)
295
+ >>> anim = animate_field_2d(X, Y, frames, times)
296
+ >>> isinstance(anim, FuncAnimation)
297
+ True
298
+ """
299
+ if ax is None:
300
+ fig, ax = plt.subplots()
301
+ else:
302
+ fig = ax.figure
303
+ vmax = np.max(np.abs(frames))
304
+ vmax = vmax if vmax > 0 else 1.0
305
+ extent = (X.min(), X.max(), Y.min(), Y.max())
306
+ im = ax.imshow(frames[0].T, extent=extent, origin="lower", cmap=cmap, vmin=-vmax, vmax=vmax, aspect="auto")
307
+ fig.colorbar(im, ax=ax, label="Ez")
308
+ ax.set_xlabel("x")
309
+ ax.set_ylabel("y")
310
+
311
+ def update(i):
312
+ im.set_data(frames[i].T)
313
+ ax.set_title(f"t = {times[i]:.3g}" if times is not None else f"frame {i}")
314
+ return (im,)
315
+
316
+ return FuncAnimation(fig, update, frames=len(frames), interval=interval, blit=False)
317
+
318
+
319
+ def animate_density_2d(
320
+ frames: np.ndarray, extent: tuple | None = None, times: np.ndarray | None = None, interval: int = 50, cmap: str = "viridis", ax=None
321
+ ) -> FuncAnimation:
322
+ """Animate a sequence of non-negative 2D density snapshots (e.g. BEC or flux-tube energy density) as an imshow heatmap.
323
+
324
+ Parameters
325
+ ----------
326
+ frames : ndarray, shape (n_frames, Nx, Ny)
327
+ Snapshots. Complex frames (a wavefunction) are converted to
328
+ :math:`|\\psi|^2`; real frames are used directly as the density/energy map.
329
+ extent : tuple(float, float, float, float), optional
330
+ ``(xmin, xmax, ymin, ymax)`` passed to ``imshow``; defaults to pixel indices.
331
+ times : ndarray, optional
332
+ Time (or other sweep parameter, e.g. propagation distance) of each frame.
333
+ interval : int, default=50
334
+ Delay between frames, in milliseconds.
335
+ cmap : str, default="viridis"
336
+ Colormap.
337
+ ax : matplotlib.axes.Axes, optional
338
+ Axes to draw into; a new figure is created if omitted.
339
+
340
+ Returns
341
+ -------
342
+ matplotlib.animation.FuncAnimation
343
+
344
+ Examples
345
+ --------
346
+ >>> import numpy as np
347
+ >>> from physicskit.fields.quantum_fields import harmonic_trap_grid, gpe_imprint_vortex, gpe_evolve
348
+ >>> n, length = 32, 12.0
349
+ >>> X, Y, KX, KY, K2 = harmonic_trap_grid(n, length)
350
+ >>> V = 0.5 * (X ** 2 + Y ** 2)
351
+ >>> psi0 = gpe_imprint_vortex(np.exp(-0.5 * (X ** 2 + Y ** 2)).astype(complex), X, Y, [(1.0, 0.0)])
352
+ >>> frames, times = gpe_evolve(psi0, V, g=2.0, dt=1e-3, steps=20, K2=K2, snapshot_stride=5)
353
+ >>> anim = animate_density_2d(frames, times=times)
354
+ >>> isinstance(anim, FuncAnimation)
355
+ True
356
+ """
357
+ if ax is None:
358
+ fig, ax = plt.subplots()
359
+ else:
360
+ fig = ax.figure
361
+ density = np.abs(frames) ** 2 if np.iscomplexobj(frames) else np.asarray(frames)
362
+ vmax = density.max()
363
+ vmax = vmax if vmax > 0 else 1.0
364
+ im = ax.imshow(density[0].T, extent=extent, origin="lower", cmap=cmap, vmin=0.0, vmax=vmax, aspect="auto")
365
+ fig.colorbar(im, ax=ax)
366
+ ax.set_xlabel("x")
367
+ ax.set_ylabel("y")
368
+
369
+ def update(i):
370
+ im.set_data(density[i].T)
371
+ ax.set_title(f"t = {times[i]:.3g}" if times is not None else f"frame {i}")
372
+ return (im,)
373
+
374
+ return FuncAnimation(fig, update, frames=len(density), interval=interval, blit=False)
375
+
376
+
377
+ def animate_flux_tube(shape: tuple, dx: float, dy: float, separations: np.ndarray, flux_quantum: float = 1.0, interval: int = 80, ax=None) -> FuncAnimation:
378
+ """Animate the toy confinement flux tube stretching as two charges are pulled apart.
379
+
380
+ Builds a frame for each separation in ``separations`` via
381
+ :func:`physicskit.fields.electrodynamics.flux_tube_energy_density_2d`
382
+ and draws it as a heatmap with two markers tracking the charge
383
+ positions, so the confined-energy "tube" visibly stretches between them.
384
+
385
+ Parameters
386
+ ----------
387
+ shape : tuple(int, int)
388
+ ``(Nx, Ny)`` grid shape.
389
+ dx, dy : float
390
+ Grid spacing.
391
+ separations : ndarray
392
+ Sequence of charge separations to sweep over (the animation's "time" axis).
393
+ flux_quantum : float, default=1.0
394
+ Charge magnitude, as in :func:`~physicskit.fields.electrodynamics.flux_tube_field_1d`.
395
+ interval : int, default=80
396
+ Delay between frames, in milliseconds.
397
+ ax : matplotlib.axes.Axes, optional
398
+ Axes to draw into; a new figure is created if omitted.
399
+
400
+ Returns
401
+ -------
402
+ matplotlib.animation.FuncAnimation
403
+
404
+ Examples
405
+ --------
406
+ >>> import numpy as np
407
+ >>> anim = animate_flux_tube((120, 30), dx=0.2, dy=0.2, separations=np.linspace(4.0, 16.0, 5))
408
+ >>> isinstance(anim, FuncAnimation)
409
+ True
410
+ """
411
+ from physicskit.fields.electrodynamics import flux_tube_energy_density_2d
412
+
413
+ if ax is None:
414
+ fig, ax = plt.subplots()
415
+ else:
416
+ fig = ax.figure
417
+ Nx, Ny = shape
418
+ x = (np.arange(Nx) - Nx // 2) * dx
419
+ y = (np.arange(Ny) - Ny // 2) * dy
420
+ extent = (x.min(), x.max(), y.min(), y.max())
421
+ frames = np.stack([flux_tube_energy_density_2d(shape, dx, dy, sep, flux_quantum) for sep in separations])
422
+ vmax = frames.max()
423
+ vmax = vmax if vmax > 0 else 1.0
424
+ im = ax.imshow(frames[0].T, extent=extent, origin="lower", cmap="magma", vmin=0.0, vmax=vmax, aspect="auto")
425
+ fig.colorbar(im, ax=ax, label="energy density")
426
+ (markers,) = ax.plot([], [], "o", color="cyan", markersize=8)
427
+ ax.set_xlabel("x")
428
+ ax.set_ylabel("y")
429
+
430
+ def update(i):
431
+ im.set_data(frames[i].T)
432
+ sep = separations[i]
433
+ markers.set_data([-sep / 2, sep / 2], [0.0, 0.0])
434
+ ax.set_title(f"separation = {sep:.2f}")
435
+ return im, markers
436
+
437
+ return FuncAnimation(fig, update, frames=len(separations), interval=interval, blit=False)
438
+
439
+
440
+ def animate_casimir_modes(d_values: np.ndarray, c: float = 1.0, n_show: int = 12, interval: int = 150) -> FuncAnimation:
441
+ """Animate the discrete cavity mode spectrum and Casimir energy as the plate separation ``d`` is swept.
442
+
443
+ Left panel: the first ``n_show`` discrete mode frequencies
444
+ (:func:`physicskit.fields.quantum_fields.casimir_mode_frequencies`) as a
445
+ stem plot, against the continuum they approach at large ``d`` (dashed
446
+ line of slope :math:`\\pi c`) -- visibly denser (closer to the
447
+ continuum) at large separation. Right panel: the regularized Casimir
448
+ energy (:func:`physicskit.fields.quantum_fields.casimir_energy_1d`) as a
449
+ curve over the full sweep, with a marker tracking the current ``d``.
450
+
451
+ Parameters
452
+ ----------
453
+ d_values : ndarray
454
+ Sequence of plate separations to sweep over (the animation's "time" axis).
455
+ c : float, default=1.0
456
+ Wave speed.
457
+ n_show : int, default=12
458
+ Number of discrete modes to show in the stem plot.
459
+ interval : int, default=150
460
+ Delay between frames, in milliseconds.
461
+
462
+ Returns
463
+ -------
464
+ matplotlib.animation.FuncAnimation
465
+
466
+ Examples
467
+ --------
468
+ >>> import numpy as np
469
+ >>> anim = animate_casimir_modes(np.linspace(1.0, 5.0, 5))
470
+ >>> isinstance(anim, FuncAnimation)
471
+ True
472
+ """
473
+ from physicskit.fields.quantum_fields import casimir_energy_1d, casimir_mode_frequencies
474
+
475
+ fig, (ax_modes, ax_energy) = plt.subplots(1, 2, figsize=(10, 4))
476
+ n = np.arange(1, n_show + 1)
477
+ energies = np.array([casimir_energy_1d(d, c) for d in d_values])
478
+
479
+ ax_modes.set_xlim(0, n_show + 1)
480
+ ax_modes.set_ylim(0, np.pi * c * n_show / d_values.min() * 1.1)
481
+ ax_modes.set_xlabel("mode index n")
482
+ ax_modes.set_ylabel(r"$\omega_n$")
483
+ stem_container = ax_modes.stem(n, np.pi * c * n / d_values[0])
484
+ (continuum_line,) = ax_modes.plot(n, np.pi * c * n / d_values[0], "k--", alpha=0.4, label="continuum slope")
485
+ ax_modes.legend(loc="upper left")
486
+
487
+ ax_energy.plot(d_values, energies, color="C0")
488
+ (marker,) = ax_energy.plot([d_values[0]], [energies[0]], "o", color="C3", markersize=8)
489
+ ax_energy.set_xlabel("plate separation d")
490
+ ax_energy.set_ylabel("Casimir energy E(d)")
491
+
492
+ def update(i):
493
+ d = d_values[i]
494
+ omega = casimir_mode_frequencies(d, c, n_show)
495
+ stem_container.markerline.set_data(n, omega)
496
+ segments = [[[xi, 0], [xi, yi]] for xi, yi in zip(n, omega)]
497
+ stem_container.stemlines.set_segments(segments)
498
+ continuum_line.set_ydata(np.pi * c * n / d)
499
+ marker.set_data([d], [energies[i]])
500
+ fig.suptitle(f"d = {d:.3g}")
501
+ return stem_container.markerline, stem_container.stemlines, continuum_line, marker
502
+
503
+ return FuncAnimation(fig, update, frames=len(d_values), interval=interval, blit=False)
@@ -0,0 +1,134 @@
1
+ """physicskit.fluids: fluid dynamics from inviscid potential flow to compressible shocks.
2
+
3
+ Six physical regimes, each a module of :mod:`physicskit.fluids.systems`,
4
+ sharing the doubly-periodic pseudo-spectral grid and RK4 time-stepping core
5
+ in :mod:`physicskit.fluids.core` wherever a grid-based simulation is needed:
6
+
7
+ - :mod:`~physicskit.fluids.systems.potential_flow` -- inviscid, irrotational
8
+ flow built by superposing elementary solutions (uniform flow,
9
+ source/sink, doublet, point vortex), including flow past a cylinder with
10
+ lift.
11
+ - :mod:`~physicskit.fluids.systems.viscous_flow` -- classic exact viscous
12
+ solutions: Couette and Poiseuille flow, Stokes drag, and the Blasius
13
+ boundary layer.
14
+ - :mod:`~physicskit.fluids.systems.vortex_dynamics` -- point-vortex N-body
15
+ dynamics via the Biot-Savart law, and the von Karman vortex street.
16
+ - :mod:`~physicskit.fluids.systems.instabilities` -- the Kelvin-Helmholtz
17
+ and Rayleigh-Taylor instabilities, each with its linear growth-rate law
18
+ and a full nonlinear simulation.
19
+ - :mod:`~physicskit.fluids.systems.compressible_flow` -- the 1D Euler
20
+ equations, Rankine-Hugoniot shock relations, and the Sod shock tube.
21
+ - :mod:`~physicskit.fluids.systems.navier_stokes` -- the 2D incompressible
22
+ vorticity-streamfunction solver underlying the instability and
23
+ turbulence-spectrum tools.
24
+
25
+ Typical usage::
26
+
27
+ import physicskit as pk
28
+ import numpy as np
29
+
30
+ # Flow past a lifting cylinder:
31
+ flow = pk.fluids.flow_past_cylinder(U_inf=1.0, radius=1.0, circulation=4 * np.pi)
32
+ lift = pk.fluids.kutta_joukowski_lift(rho=1.2, U_inf=1.0, circulation=4 * np.pi)
33
+ """
34
+
35
+ from physicskit.fluids.exceptions import FluidskitError, InvalidParameterError
36
+ from physicskit.fluids.systems.compressible_flow import (
37
+ normal_shock_relations,
38
+ rankine_hugoniot_jump_conditions,
39
+ sod_shock_tube,
40
+ )
41
+ from physicskit.fluids.systems.instabilities import (
42
+ kelvin_helmholtz_growth_rate,
43
+ kelvin_helmholtz_ic,
44
+ rayleigh_taylor_growth_rate,
45
+ rayleigh_taylor_ic,
46
+ simulate_rayleigh_taylor,
47
+ )
48
+ from physicskit.fluids.systems.navier_stokes import NavierStokes2D, simulate_vorticity_streamfunction
49
+ from physicskit.fluids.systems.potential_flow import (
50
+ PotentialFlow,
51
+ doublet_potential,
52
+ flow_past_cylinder,
53
+ kutta_joukowski_lift,
54
+ point_vortex_potential,
55
+ pressure_coefficient,
56
+ source_potential,
57
+ uniform_flow_potential,
58
+ )
59
+ from physicskit.fluids.systems.viscous_flow import (
60
+ blasius_boundary_layer_thickness,
61
+ blasius_skin_friction_coefficient,
62
+ blasius_solve,
63
+ couette_flow_velocity,
64
+ poiseuille_flow_rate,
65
+ poiseuille_flow_velocity,
66
+ stokes_drag,
67
+ )
68
+ from physicskit.fluids.systems.vortex_dynamics import (
69
+ VON_KARMAN_SPACING_RATIO,
70
+ PointVortexSystem,
71
+ point_vortex_velocities,
72
+ von_karman_vortex_street,
73
+ )
74
+ from physicskit.fluids.utils.dimensionless import (
75
+ froude_number,
76
+ mach_number,
77
+ reynolds_number,
78
+ strouhal_number,
79
+ weber_number,
80
+ )
81
+ from physicskit.fluids.utils.spectral_analysis import energy_spectrum, kolmogorov_reference_slope
82
+ from physicskit.fluids.visualizers.compressible import plot_shock_tube_profiles
83
+ from physicskit.fluids.visualizers.flow_fields import plot_streamlines, plot_vorticity_field
84
+ from physicskit.fluids.visualizers.potential_flow import plot_pressure_coefficient
85
+ from physicskit.fluids.visualizers.spectra import plot_energy_spectrum
86
+
87
+ __version__ = "0.1.0"
88
+
89
+ __all__ = [
90
+ "VON_KARMAN_SPACING_RATIO",
91
+ "FluidskitError",
92
+ "InvalidParameterError",
93
+ "NavierStokes2D",
94
+ "PointVortexSystem",
95
+ "PotentialFlow",
96
+ "blasius_boundary_layer_thickness",
97
+ "blasius_skin_friction_coefficient",
98
+ "blasius_solve",
99
+ "couette_flow_velocity",
100
+ "doublet_potential",
101
+ "energy_spectrum",
102
+ "flow_past_cylinder",
103
+ "froude_number",
104
+ "kelvin_helmholtz_growth_rate",
105
+ "kelvin_helmholtz_ic",
106
+ "kolmogorov_reference_slope",
107
+ "kutta_joukowski_lift",
108
+ "mach_number",
109
+ "normal_shock_relations",
110
+ "plot_energy_spectrum",
111
+ "plot_pressure_coefficient",
112
+ "plot_shock_tube_profiles",
113
+ "plot_streamlines",
114
+ "plot_vorticity_field",
115
+ "point_vortex_potential",
116
+ "point_vortex_velocities",
117
+ "poiseuille_flow_rate",
118
+ "poiseuille_flow_velocity",
119
+ "pressure_coefficient",
120
+ "rankine_hugoniot_jump_conditions",
121
+ "rayleigh_taylor_growth_rate",
122
+ "rayleigh_taylor_ic",
123
+ "reynolds_number",
124
+ "simulate_rayleigh_taylor",
125
+ "simulate_vorticity_streamfunction",
126
+ "sod_shock_tube",
127
+ "source_potential",
128
+ "stokes_drag",
129
+ "strouhal_number",
130
+ "uniform_flow_potential",
131
+ "von_karman_vortex_street",
132
+ "weber_number",
133
+ "__version__",
134
+ ]
@@ -0,0 +1,23 @@
1
+ from physicskit.fluids.core.grid import (
2
+ poisson_solve_streamfunction,
3
+ spectral_grid,
4
+ velocity_from_streamfunction,
5
+ vorticity_from_velocity,
6
+ )
7
+ from physicskit.fluids.core.timestepping import (
8
+ buoyant_vorticity_rhs,
9
+ integrate_boussinesq,
10
+ integrate_vorticity_streamfunction,
11
+ vorticity_rhs,
12
+ )
13
+
14
+ __all__ = [
15
+ "buoyant_vorticity_rhs",
16
+ "integrate_boussinesq",
17
+ "integrate_vorticity_streamfunction",
18
+ "poisson_solve_streamfunction",
19
+ "spectral_grid",
20
+ "velocity_from_streamfunction",
21
+ "vorticity_from_velocity",
22
+ "vorticity_rhs",
23
+ ]