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,463 @@
1
+ """Magnetohydrodynamics: wave speeds, toroidal equilibrium, and magnetic reconnection.
2
+
3
+ Treats the plasma as a single conducting fluid rather than a collection of
4
+ orbiting particles. Three regimes are covered: the characteristic wave
5
+ speeds of ideal MHD (:func:`alfven_speed`, :func:`sound_speed`,
6
+ :func:`magnetosonic_speeds`); static toroidal equilibrium, obtained by
7
+ solving the Grad-Shafranov equation
8
+ :math:`\\Delta^*\\psi = -\\mu_0 R^2 p'(\\psi) - FF'(\\psi)` for the poloidal
9
+ flux function :math:`\\psi(R, Z)` that balances pressure against the
10
+ magnetic force in an axisymmetric device (:func:`solve_grad_shafranov`,
11
+ :func:`safety_factor_large_aspect_ratio`); and resistive magnetic
12
+ reconnection, where a thin current sheet lets field lines of opposite
13
+ polarity break and reconnect, converting magnetic energy to heat and flow
14
+ (:func:`sweet_parker_rate`, :func:`petschek_rate`).
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ import numpy as np
20
+ from numba import njit
21
+
22
+ __all__ = [
23
+ "MU0",
24
+ "alfven_speed",
25
+ "sound_speed",
26
+ "magnetosonic_speeds",
27
+ "solovev_particular_solution",
28
+ "grad_shafranov_rhs_solovev",
29
+ "solve_grad_shafranov",
30
+ "safety_factor_large_aspect_ratio",
31
+ "lundquist_number",
32
+ "resistive_diffusion_time",
33
+ "sweet_parker_rate",
34
+ "sweet_parker_layer_width",
35
+ "petschek_rate",
36
+ ]
37
+
38
+ MU0 = 4 * np.pi * 1e-7
39
+ """Vacuum permeability, in H/m."""
40
+
41
+
42
+ def alfven_speed(B: float, rho: float) -> float:
43
+ """Alfven speed :math:`v_A = B/\\sqrt{\\mu_0 \\rho}`, at which a perturbation propagates along tensioned field lines.
44
+
45
+ Hannes Alfven's 1942 discovery that a magnetized, perfectly conducting
46
+ fluid supports a transverse wave -- field lines behaving like strings
47
+ under tension :math:`B^2/\\mu_0`, plucked by the inertia of the frozen-in
48
+ plasma -- founded MHD as a distinct discipline and earned the 1970
49
+ Nobel Prize.
50
+
51
+ Parameters
52
+ ----------
53
+ B : float
54
+ Magnetic field magnitude in Tesla.
55
+ rho : float
56
+ Mass density in kg/m^3.
57
+
58
+ Returns
59
+ -------
60
+ float
61
+ Alfven speed in m/s.
62
+
63
+ See Also
64
+ --------
65
+ magnetosonic_speeds : The compressive (fast/slow) counterparts of this
66
+ purely magnetic wave.
67
+
68
+ Examples
69
+ --------
70
+ >>> round(float(alfven_speed(B=1.0, rho=1e-6)), 2)
71
+ 892062.06
72
+ """
73
+ return B / np.sqrt(MU0 * rho)
74
+
75
+
76
+ def sound_speed(gamma: float, p: float, rho: float) -> float:
77
+ """Ordinary adiabatic sound speed :math:`c_s = \\sqrt{\\gamma p/\\rho}`.
78
+
79
+ Parameters
80
+ ----------
81
+ gamma : float
82
+ Adiabatic index (5/3 for an ideal monatomic gas).
83
+ p : float
84
+ Pressure in Pa.
85
+ rho : float
86
+ Mass density in kg/m^3.
87
+
88
+ Returns
89
+ -------
90
+ float
91
+ Sound speed in m/s.
92
+
93
+ Examples
94
+ --------
95
+ >>> round(float(sound_speed(gamma=5 / 3, p=1.0, rho=1e-6)), 2)
96
+ 1290.99
97
+ """
98
+ return np.sqrt(gamma * p / rho)
99
+
100
+
101
+ def magnetosonic_speeds(vA: float, cs: float, theta: float) -> tuple:
102
+ """Fast and slow magnetosonic phase speeds at propagation angle :math:`\\theta` to :math:`\\mathbf{B}`.
103
+
104
+ The two compressive MHD normal modes solve
105
+ :math:`v_{f,s}^2 = \\tfrac{1}{2}\\left[(v_A^2+c_s^2) \\pm \\sqrt{(v_A^2+c_s^2)^2 - 4v_A^2c_s^2\\cos^2\\theta}\\right]`.
106
+ At :math:`\\theta=0` (propagation along :math:`\\mathbf{B}`) they reduce
107
+ to :math:`\\max(v_A, c_s)` and :math:`\\min(v_A, c_s)`; at
108
+ :math:`\\theta=\\pi/2` the fast mode becomes the purely compressive
109
+ :math:`\\sqrt{v_A^2+c_s^2}` and the slow mode vanishes, since a
110
+ perpendicular perturbation cannot bend field lines that are already
111
+ perpendicular to its wavevector.
112
+
113
+ Parameters
114
+ ----------
115
+ vA : float
116
+ Alfven speed in m/s, from :func:`alfven_speed`.
117
+ cs : float
118
+ Sound speed in m/s, from :func:`sound_speed`.
119
+ theta : float
120
+ Angle between the wavevector and :math:`\\mathbf{B}`, in radians.
121
+
122
+ Returns
123
+ -------
124
+ v_fast, v_slow : float
125
+ Fast and slow magnetosonic phase speeds in m/s.
126
+
127
+ Examples
128
+ --------
129
+ >>> import numpy as np
130
+ >>> vf, vs = magnetosonic_speeds(vA=892062.06, cs=1e5, theta=np.pi / 2)
131
+ >>> round(vf, 2)
132
+ 897649.55
133
+ >>> round(vs, 2)
134
+ 0.0
135
+ """
136
+ s = vA**2 + cs**2
137
+ d = np.sqrt(max(s**2 - 4.0 * vA**2 * cs**2 * np.cos(theta) ** 2, 0.0))
138
+ return float(np.sqrt(0.5 * (s + d))), float(np.sqrt(0.5 * (s - d)))
139
+
140
+
141
+ def solovev_particular_solution(R: np.ndarray, Z: np.ndarray, c1: float, c2: float) -> np.ndarray:
142
+ """Closed-form particular solution of the linear (Solov'ev) Grad-Shafranov equation.
143
+
144
+ When the source term is linear in :math:`R^2` -- i.e.
145
+ :math:`p'(\\psi) = \\text{const}` and :math:`FF'(\\psi) = \\text{const}`,
146
+ so :math:`\\Delta^*\\psi = c_1 R^2 + c_2` -- the Grad-Shafranov operator
147
+ :math:`\\Delta^*\\psi = \\partial_R^2\\psi - R^{-1}\\partial_R\\psi + \\partial_Z^2\\psi`
148
+ admits the exact polynomial solution :math:`\\psi_p = \\tfrac{c_1}{8}R^4 +
149
+ \\tfrac{c_2}{2}Z^2` (Solov'ev, 1968); adding any solution of the
150
+ homogeneous equation :math:`\\Delta^*\\psi=0` shapes the boundary into a
151
+ D-shaped or elongated cross-section without affecting the pressure and
152
+ current profile. Used here to validate :func:`solve_grad_shafranov`
153
+ against an exact answer, and to supply consistent Dirichlet boundary
154
+ data for it.
155
+
156
+ Parameters
157
+ ----------
158
+ R, Z : ndarray
159
+ Cylindrical coordinates (broadcastable), in meters.
160
+ c1, c2 : float
161
+ Coefficients of the linear source term :math:`\\Delta^*\\psi = c_1 R^2 + c_2`.
162
+
163
+ Returns
164
+ -------
165
+ ndarray
166
+ Poloidal flux :math:`\\psi(R, Z)`, same shape as ``R``/``Z``.
167
+
168
+ See Also
169
+ --------
170
+ grad_shafranov_rhs_solovev : The corresponding source term.
171
+ solve_grad_shafranov : Numerical solver validated against this solution.
172
+
173
+ Examples
174
+ --------
175
+ >>> import numpy as np
176
+ >>> solovev_particular_solution(np.array([1.0]), np.array([0.0]), c1=1.0, c2=-2.0)
177
+ array([0.125])
178
+ """
179
+ return (c1 / 8.0) * R**4 + (c2 / 2.0) * Z**2
180
+
181
+
182
+ def grad_shafranov_rhs_solovev(R: np.ndarray, c1: float, c2: float) -> np.ndarray:
183
+ """Source term :math:`\\Delta^*\\psi = c_1 R^2 + c_2` of the linear Solov'ev equilibrium.
184
+
185
+ Equivalent to :math:`-\\mu_0 R^2 p'(\\psi) - FF'(\\psi)` in the
186
+ Grad-Shafranov equation for the special case of constant
187
+ :math:`p'(\\psi)` and :math:`FF'(\\psi)`.
188
+
189
+ Parameters
190
+ ----------
191
+ R : ndarray
192
+ Major-radius coordinate, in meters.
193
+ c1, c2 : float
194
+ Source coefficients (related to :math:`p'` and :math:`FF'`).
195
+
196
+ Returns
197
+ -------
198
+ ndarray
199
+ The right-hand side :math:`\\Delta^*\\psi`, same shape as ``R``.
200
+
201
+ Examples
202
+ --------
203
+ >>> import numpy as np
204
+ >>> grad_shafranov_rhs_solovev(np.array([1.0, 2.0]), c1=1.0, c2=-2.0)
205
+ array([-1., 2.])
206
+ """
207
+ return c1 * R**2 + c2
208
+
209
+
210
+ @njit(cache=True)
211
+ def _sor_grad_shafranov(psi, R, dR, dZ, c1, c2, omega, max_iter):
212
+ nr, nz = psi.shape
213
+ for _ in range(max_iter):
214
+ for i in range(1, nr - 1):
215
+ Ri = R[i]
216
+ coef_ip = 1.0 / dR**2 - 1.0 / (2.0 * Ri * dR)
217
+ coef_im = 1.0 / dR**2 + 1.0 / (2.0 * Ri * dR)
218
+ coef_j = 1.0 / dZ**2
219
+ coef_c = -2.0 / dR**2 - 2.0 / dZ**2
220
+ for j in range(1, nz - 1):
221
+ source = c1 * Ri**2 + c2
222
+ rhs = source - coef_ip * psi[i + 1, j] - coef_im * psi[i - 1, j] - coef_j * psi[i, j + 1] - coef_j * psi[i, j - 1]
223
+ psi[i, j] = (1.0 - omega) * psi[i, j] + omega * (rhs / coef_c)
224
+ return psi
225
+
226
+
227
+ def solve_grad_shafranov(R: np.ndarray, Z: np.ndarray, c1: float, c2: float, omega: float = 1.8, max_iter: int = 4000) -> np.ndarray:
228
+ """Solve the axisymmetric Grad-Shafranov equation by successive over-relaxation (SOR).
229
+
230
+ Finite-differences the elliptic operator
231
+ :math:`\\Delta^*\\psi = \\partial_R^2\\psi - R^{-1}\\partial_R\\psi +
232
+ \\partial_Z^2\\psi` on a rectangular :math:`(R, Z)` grid and relaxes it
233
+ toward the linear (Solov'ev) source :math:`c_1 R^2 + c_2`, using
234
+ Dirichlet boundary data taken from the exact
235
+ :func:`solovev_particular_solution` -- so the interior solution this
236
+ converges to is known analytically and can be checked directly, rather
237
+ than only visually.
238
+
239
+ Parameters
240
+ ----------
241
+ R : ndarray, shape (nr,)
242
+ Major-radius grid points, in meters; must be strictly positive
243
+ (the operator is singular at :math:`R=0`).
244
+ Z : ndarray, shape (nz,)
245
+ Vertical grid points, in meters.
246
+ c1, c2 : float
247
+ Coefficients of the linear source term, as in :func:`grad_shafranov_rhs_solovev`.
248
+ omega : float, default=1.8
249
+ SOR relaxation parameter, :math:`1 < \\omega < 2`.
250
+ max_iter : int, default=4000
251
+ Number of relaxation sweeps.
252
+
253
+ Returns
254
+ -------
255
+ ndarray, shape (nr, nz)
256
+ Poloidal flux :math:`\\psi(R, Z)` on the grid.
257
+
258
+ See Also
259
+ --------
260
+ solovev_particular_solution : The exact solution this converges to.
261
+ safety_factor_large_aspect_ratio : A downstream equilibrium diagnostic.
262
+
263
+ Examples
264
+ --------
265
+ >>> import numpy as np
266
+ >>> R = np.linspace(0.5, 1.5, 41)
267
+ >>> Z = np.linspace(-0.5, 0.5, 41)
268
+ >>> c1, c2 = 1.0, -2.0
269
+ >>> psi = solve_grad_shafranov(R, Z, c1, c2)
270
+ >>> RR, ZZ = np.meshgrid(R, Z, indexing="ij")
271
+ >>> psi_exact = solovev_particular_solution(RR, ZZ, c1, c2)
272
+ >>> bool(np.max(np.abs(psi - psi_exact)) < 1e-3)
273
+ True
274
+ """
275
+ nr, nz = len(R), len(Z)
276
+ RR, ZZ = np.meshgrid(R, Z, indexing="ij")
277
+ psi_exact = solovev_particular_solution(RR, ZZ, c1, c2)
278
+ psi = np.zeros((nr, nz))
279
+ psi[0, :] = psi_exact[0, :]
280
+ psi[-1, :] = psi_exact[-1, :]
281
+ psi[:, 0] = psi_exact[:, 0]
282
+ psi[:, -1] = psi_exact[:, -1]
283
+ dR = float(R[1] - R[0])
284
+ dZ = float(Z[1] - Z[0])
285
+ return _sor_grad_shafranov(psi, np.asarray(R, dtype=float), dR, dZ, float(c1), float(c2), float(omega), int(max_iter))
286
+
287
+
288
+ def safety_factor_large_aspect_ratio(r: float, R0: float, Bt: float, Bp: float) -> float:
289
+ """Tokamak safety factor :math:`q \\approx rB_t/(R_0 B_p)` in the large-aspect-ratio approximation.
290
+
291
+ Counts how many times a field line winds the long way (toroidally)
292
+ around the torus for each time it winds the short way (poloidally).
293
+ Field lines with rational :math:`q = m/n` close on themselves after
294
+ :math:`n` toroidal transits and are resonant surfaces for
295
+ magnetic-island-forming instabilities; :math:`q=1` in particular marks
296
+ the sawtooth-unstable region at a tokamak's core.
297
+
298
+ Parameters
299
+ ----------
300
+ r : float
301
+ Minor-radius coordinate of the flux surface, in meters.
302
+ R0 : float
303
+ Major radius of the torus, in meters.
304
+ Bt : float
305
+ Toroidal field strength at the flux surface, in Tesla.
306
+ Bp : float
307
+ Poloidal field strength at the flux surface, in Tesla.
308
+
309
+ Returns
310
+ -------
311
+ float
312
+ Safety factor (dimensionless).
313
+
314
+ Examples
315
+ --------
316
+ >>> round(safety_factor_large_aspect_ratio(r=0.3, R0=1.0, Bt=2.0, Bp=0.2), 10)
317
+ 3.0
318
+ """
319
+ return r * Bt / (R0 * Bp)
320
+
321
+
322
+ def lundquist_number(L: float, vA: float, eta: float) -> float:
323
+ """Lundquist number :math:`S = L v_A/\\eta`, the magnetic Reynolds number built from the Alfven speed.
324
+
325
+ Parameters
326
+ ----------
327
+ L : float
328
+ Characteristic length scale (e.g. current-sheet length), in meters.
329
+ vA : float
330
+ Alfven speed in m/s, from :func:`alfven_speed`.
331
+ eta : float
332
+ Magnetic diffusivity in m^2/s.
333
+
334
+ Returns
335
+ -------
336
+ float
337
+ Lundquist number (dimensionless). Fusion and astrophysical plasmas
338
+ typically have :math:`S \\sim 10^{6}` -- :math:`10^{14}`.
339
+
340
+ See Also
341
+ --------
342
+ sweet_parker_rate : Reconnection rate scaling as :math:`S^{-1/2}`.
343
+
344
+ Examples
345
+ --------
346
+ >>> lundquist_number(L=1.0, vA=1e6, eta=1.0)
347
+ 1000000.0
348
+ """
349
+ return L * vA / eta
350
+
351
+
352
+ def resistive_diffusion_time(L: float, eta: float) -> float:
353
+ """Resistive diffusion time :math:`\\tau_\\eta = L^2/\\eta` for magnetic field to decay through a length :math:`L`.
354
+
355
+ Parameters
356
+ ----------
357
+ L : float
358
+ Length scale in meters.
359
+ eta : float
360
+ Magnetic diffusivity in m^2/s.
361
+
362
+ Returns
363
+ -------
364
+ float
365
+ Diffusion time in seconds.
366
+
367
+ Examples
368
+ --------
369
+ >>> resistive_diffusion_time(L=1.0, eta=1.0)
370
+ 1.0
371
+ """
372
+ return L**2 / eta
373
+
374
+
375
+ def sweet_parker_rate(S: float) -> float:
376
+ """Sweet-Parker reconnection rate :math:`v_{in}/v_A = S^{-1/2}`.
377
+
378
+ Sweet and Parker's 1957/1958 model treats reconnection as
379
+ steady inflow through a long, thin resistive current sheet of aspect
380
+ ratio :math:`\\delta/L \\sim S^{-1/2}`; mass conservation through that
381
+ narrow sheet throttles the inflow (and hence the whole reconnection
382
+ process) to the same :math:`S^{-1/2}` scaling. For solar-flare-scale
383
+ Lundquist numbers (:math:`S\\sim10^{12}`) this predicts reconnection
384
+ millions of times too slow to explain observed flare energy-release
385
+ times -- the puzzle :func:`petschek_rate` was proposed to resolve.
386
+
387
+ Parameters
388
+ ----------
389
+ S : float
390
+ Lundquist number, from :func:`lundquist_number`.
391
+
392
+ Returns
393
+ -------
394
+ float
395
+ Dimensionless reconnection rate :math:`v_{in}/v_A`.
396
+
397
+ See Also
398
+ --------
399
+ sweet_parker_layer_width : The current-sheet thickness behind this rate.
400
+ petschek_rate : The faster, X-point reconnection alternative.
401
+
402
+ Examples
403
+ --------
404
+ >>> round(float(sweet_parker_rate(S=1e6)), 6)
405
+ 0.001
406
+ """
407
+ return 1.0 / np.sqrt(S)
408
+
409
+
410
+ def sweet_parker_layer_width(L: float, S: float) -> float:
411
+ """Sweet-Parker current-sheet thickness :math:`\\delta = L/\\sqrt{S}`.
412
+
413
+ Parameters
414
+ ----------
415
+ L : float
416
+ Current-sheet length in meters.
417
+ S : float
418
+ Lundquist number, from :func:`lundquist_number`.
419
+
420
+ Returns
421
+ -------
422
+ float
423
+ Current-sheet thickness in meters.
424
+
425
+ Examples
426
+ --------
427
+ >>> round(float(sweet_parker_layer_width(L=1e7, S=1e6)), 4)
428
+ 10000.0
429
+ """
430
+ return L / np.sqrt(S)
431
+
432
+
433
+ def petschek_rate(S: float) -> float:
434
+ """Petschek reconnection rate :math:`v_{in}/v_A \\approx \\pi/(8\\ln S)`.
435
+
436
+ Petschek (1964) showed that if the diffusion region shrinks to a
437
+ small X-point rather than the full Sweet-Parker sheet length, four
438
+ standing slow-mode shocks can carry most of the inflowing flux and
439
+ energy conversion, giving a reconnection rate that falls only
440
+ logarithmically with :math:`S` instead of as :math:`S^{-1/2}` --
441
+ fast enough to plausibly explain solar flare and magnetospheric
442
+ substorm timescales.
443
+
444
+ Parameters
445
+ ----------
446
+ S : float
447
+ Lundquist number, from :func:`lundquist_number`.
448
+
449
+ Returns
450
+ -------
451
+ float
452
+ Dimensionless reconnection rate :math:`v_{in}/v_A`.
453
+
454
+ See Also
455
+ --------
456
+ sweet_parker_rate : The slower, steady-sheet reconnection rate this improves on.
457
+
458
+ Examples
459
+ --------
460
+ >>> round(float(petschek_rate(S=1e6)), 4)
461
+ 0.0284
462
+ """
463
+ return np.pi / (8.0 * np.log(S))