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,165 @@
1
+ """Doubly-periodic pseudo-spectral grid and Poisson solve.
2
+
3
+ The shared spatial machinery behind every grid-based solver in
4
+ :mod:`physicskit.fluids`: a real-space/wavenumber grid pair on the doubly
5
+ periodic domain ``[0, length) x [0, length)``, an exact spectral Poisson
6
+ solve (used to recover a streamfunction from a vorticity field), and the
7
+ spectral velocity recovery that follows from it. Because differentiation is
8
+ exact multiplication by ``i*k`` in Fourier space, every derivative used here
9
+ is exact up to machine precision and aliasing, with none of a finite
10
+ difference's truncation error -- the standard reason pseudo-spectral methods
11
+ are the tool of choice for smooth, periodic 2D flow.
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ import numpy as np
17
+ from numpy.typing import NDArray
18
+
19
+ from physicskit.fluids.exceptions import InvalidParameterError
20
+
21
+ __all__ = [
22
+ "spectral_grid",
23
+ "poisson_solve_streamfunction",
24
+ "velocity_from_streamfunction",
25
+ "vorticity_from_velocity",
26
+ ]
27
+
28
+
29
+ def spectral_grid(n: int, length: float) -> tuple[NDArray[np.float64], NDArray[np.float64], NDArray[np.float64], NDArray[np.float64], NDArray[np.float64]]:
30
+ """Build a doubly periodic real-space and wavenumber grid.
31
+
32
+ Parameters
33
+ ----------
34
+ n : int
35
+ Number of grid points along each axis. Must be at least 8, so that
36
+ the FFT-based derivatives resolve at least a few wavelengths of the
37
+ lowest nonzero mode.
38
+ length : float
39
+ Physical domain size (the domain is ``[0, length) x [0, length)``).
40
+
41
+ Returns
42
+ -------
43
+ X, Y : ndarray of float, shape (n, n)
44
+ Real-space coordinate grids.
45
+ KX, KY : ndarray of float, shape (n, n)
46
+ Wavenumber grids (angular, i.e. :math:`2\\pi/\\lambda` convention).
47
+ K2 : ndarray of float, shape (n, n)
48
+ :math:`K_X^2 + K_Y^2`, with the zero mode set to 1 to make Poisson
49
+ division safe (the zero mode of a vorticity field is always 0 for a
50
+ physical flow, so this entry is unused downstream).
51
+
52
+ Raises
53
+ ------
54
+ InvalidParameterError
55
+ If `n` is smaller than 8 or `length` is not positive.
56
+
57
+ Examples
58
+ --------
59
+ >>> X, Y, KX, KY, K2 = spectral_grid(64, 2 * 3.141592653589793)
60
+ >>> X.shape
61
+ (64, 64)
62
+ >>> bool(K2[0, 0] == 1.0)
63
+ True
64
+ """
65
+ if n < 8:
66
+ raise InvalidParameterError(f"n must be >= 8 for a usable doubly periodic spectral grid, got {n}")
67
+ if length <= 0:
68
+ raise InvalidParameterError(f"length must be positive, got {length}")
69
+ x = np.linspace(0, length, n, endpoint=False)
70
+ X, Y = np.meshgrid(x, x, indexing="ij")
71
+ k = 2 * np.pi * np.fft.fftfreq(n, d=length / n)
72
+ KX, KY = np.meshgrid(k, k, indexing="ij")
73
+ K2 = KX**2 + KY**2
74
+ K2 = K2.copy()
75
+ K2[0, 0] = 1.0
76
+ return X, Y, KX, KY, K2
77
+
78
+
79
+ def poisson_solve_streamfunction(omega: NDArray[np.float64], K2: NDArray[np.float64]) -> NDArray[np.float64]:
80
+ """Solve :math:`\\nabla^2 \\psi = -\\omega` for the streamfunction via FFT.
81
+
82
+ Parameters
83
+ ----------
84
+ omega : ndarray of float, shape (n, n)
85
+ Vorticity field.
86
+ K2 : ndarray of float, shape (n, n)
87
+ Squared wavenumber grid from :func:`spectral_grid`.
88
+
89
+ Returns
90
+ -------
91
+ ndarray of float, shape (n, n)
92
+ Streamfunction :math:`\\psi`.
93
+
94
+ Examples
95
+ --------
96
+ >>> import numpy as np
97
+ >>> X, Y, KX, KY, K2 = spectral_grid(64, 2 * np.pi)
98
+ >>> omega = np.sin(X) * np.sin(Y)
99
+ >>> psi = poisson_solve_streamfunction(omega, K2)
100
+ >>> expected = 0.5 * np.sin(X) * np.sin(Y)
101
+ >>> bool(np.max(np.abs(psi - expected)) < 1e-10)
102
+ True
103
+ """
104
+ omega_hat = np.fft.fft2(omega)
105
+ psi_hat = omega_hat / K2
106
+ psi_hat[0, 0] = 0.0
107
+ return np.real(np.fft.ifft2(psi_hat))
108
+
109
+
110
+ def velocity_from_streamfunction(psi: NDArray[np.float64], KX: NDArray[np.float64], KY: NDArray[np.float64]) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
111
+ """Recover the incompressible velocity field from a streamfunction.
112
+
113
+ Parameters
114
+ ----------
115
+ psi : ndarray of float, shape (n, n)
116
+ Streamfunction.
117
+ KX, KY : ndarray of float, shape (n, n)
118
+ Wavenumber grids from :func:`spectral_grid`.
119
+
120
+ Returns
121
+ -------
122
+ u, v : ndarray of float, shape (n, n)
123
+ Velocity components :math:`u=\\partial_y\\psi`, :math:`v=-\\partial_x\\psi`,
124
+ which satisfy :math:`\\nabla\\cdot\\mathbf{u}=0` identically.
125
+
126
+ Examples
127
+ --------
128
+ >>> import numpy as np
129
+ >>> X, Y, KX, KY, K2 = spectral_grid(64, 2 * np.pi)
130
+ >>> psi = 0.5 * np.sin(X) * np.sin(Y)
131
+ >>> u, v = velocity_from_streamfunction(psi, KX, KY)
132
+ >>> curl = vorticity_from_velocity(u, v, KX, KY)
133
+ >>> bool(np.max(np.abs(curl - np.sin(X) * np.sin(Y))) < 1e-10)
134
+ True
135
+ """
136
+ psi_hat = np.fft.fft2(psi)
137
+ u = np.real(np.fft.ifft2(1j * KY * psi_hat))
138
+ v = np.real(np.fft.ifft2(-1j * KX * psi_hat))
139
+ return u, v
140
+
141
+
142
+ def vorticity_from_velocity(u: NDArray[np.float64], v: NDArray[np.float64], KX: NDArray[np.float64], KY: NDArray[np.float64]) -> NDArray[np.float64]:
143
+ """Compute the vorticity :math:`\\omega=\\partial_x v-\\partial_y u` spectrally.
144
+
145
+ The inverse of :func:`velocity_from_streamfunction` followed by a curl;
146
+ mainly useful for validating that a velocity field is consistent with
147
+ some streamfunction, or for measuring the vorticity of a field built
148
+ directly (e.g. by superposing elementary potential-flow solutions)
149
+ rather than evolved from one.
150
+
151
+ Parameters
152
+ ----------
153
+ u, v : ndarray of float, shape (n, n)
154
+ Velocity components.
155
+ KX, KY : ndarray of float, shape (n, n)
156
+ Wavenumber grids from :func:`spectral_grid`.
157
+
158
+ Returns
159
+ -------
160
+ ndarray of float, shape (n, n)
161
+ Vorticity field :math:`\\omega`.
162
+ """
163
+ u_hat = np.fft.fft2(u)
164
+ v_hat = np.fft.fft2(v)
165
+ return np.real(np.fft.ifft2(1j * KX * v_hat - 1j * KY * u_hat))
@@ -0,0 +1,231 @@
1
+ """Pseudo-spectral RK4 time-stepping for advection-diffusion transport on the spectral grid.
2
+
3
+ The right-hand side of the vorticity-transport equation involves an FFT at
4
+ every evaluation (to invert the Laplacian for the streamfunction, and to
5
+ differentiate the advected field), so -- unlike
6
+ :mod:`physicskit.chaos.core.integrators` -- these steppers are plain NumPy
7
+ rather than Numba ``@njit`` functions: Numba's ``nopython`` mode does not
8
+ support ``numpy.fft``. What *is* shared and reused here is the algorithm:
9
+ one classical 4th-order Runge-Kutta step applied to the pseudo-spectrally
10
+ evaluated right-hand side, exactly as :mod:`physicskit.chaos.core.integrators`
11
+ does with its Numba-jitted right-hand sides.
12
+
13
+ :func:`vorticity_rhs` and :func:`integrate_vorticity_streamfunction` are the
14
+ single-field (pure vorticity-transport) engine reused, unmodified, by
15
+ :mod:`physicskit.fluids.systems.navier_stokes` as the package's
16
+ general-purpose incompressible-flow workhorse, and in turn by
17
+ :mod:`physicskit.fluids.systems.instabilities` to grow a Kelvin-Helmholtz
18
+ shear layer. :func:`buoyant_vorticity_rhs` and
19
+ :func:`integrate_boussinesq` extend the same scheme with a passively
20
+ advected buoyancy (density) field and its baroclinic torque on vorticity --
21
+ the minimal addition needed to grow a Rayleigh-Taylor instability, which
22
+ requires two fluid layers of different density and therefore cannot be
23
+ represented by vorticity alone.
24
+ """
25
+
26
+ from __future__ import annotations
27
+
28
+ import numpy as np
29
+ from numpy.typing import NDArray
30
+
31
+ from physicskit.fluids.core.grid import poisson_solve_streamfunction, spectral_grid, velocity_from_streamfunction
32
+
33
+ __all__ = [
34
+ "vorticity_rhs",
35
+ "integrate_vorticity_streamfunction",
36
+ "buoyant_vorticity_rhs",
37
+ "integrate_boussinesq",
38
+ ]
39
+
40
+
41
+ def vorticity_rhs(
42
+ omega: NDArray[np.float64],
43
+ KX: NDArray[np.float64],
44
+ KY: NDArray[np.float64],
45
+ K2: NDArray[np.float64],
46
+ nu: float,
47
+ ) -> NDArray[np.float64]:
48
+ """Right-hand side of the vorticity transport equation, evaluated pseudo-spectrally.
49
+
50
+ Parameters
51
+ ----------
52
+ omega : ndarray of float, shape (n, n)
53
+ Vorticity field.
54
+ KX, KY, K2 : ndarray of float, shape (n, n)
55
+ Wavenumber grids from :func:`physicskit.fluids.core.grid.spectral_grid`.
56
+ nu : float
57
+ Kinematic viscosity.
58
+
59
+ Returns
60
+ -------
61
+ ndarray of float, shape (n, n)
62
+ :math:`-(\\mathbf{u}\\cdot\\nabla)\\omega + \\nu\\nabla^2\\omega`.
63
+ """
64
+ psi = poisson_solve_streamfunction(omega, K2)
65
+ u, v = velocity_from_streamfunction(psi, KX, KY)
66
+ omega_hat = np.fft.fft2(omega)
67
+ domega_dx = np.real(np.fft.ifft2(1j * KX * omega_hat))
68
+ domega_dy = np.real(np.fft.ifft2(1j * KY * omega_hat))
69
+ advection = -(u * domega_dx + v * domega_dy)
70
+ diffusion = np.real(np.fft.ifft2(-nu * K2 * omega_hat))
71
+ return advection + diffusion
72
+
73
+
74
+ def integrate_vorticity_streamfunction(omega0: NDArray[np.float64], nu: float, dt: float, steps: int, length: float) -> dict[str, NDArray[np.float64]]:
75
+ """Time-step the 2D incompressible vorticity-streamfunction equations with RK4.
76
+
77
+ Parameters
78
+ ----------
79
+ omega0 : ndarray of float, shape (n, n)
80
+ Initial vorticity field on a doubly periodic ``[0, length)^2`` domain.
81
+ nu : float
82
+ Kinematic viscosity.
83
+ dt : float
84
+ Time step.
85
+ steps : int
86
+ Number of RK4 steps to advance.
87
+ length : float
88
+ Physical domain size.
89
+
90
+ Returns
91
+ -------
92
+ dict
93
+ ``{"omega": final vorticity, "psi": final streamfunction, "u": ..., "v": ...}``.
94
+
95
+ See Also
96
+ --------
97
+ physicskit.fluids.systems.navier_stokes.NavierStokes2D : Validated, documented wrapper.
98
+ """
99
+ n = omega0.shape[0]
100
+ _, _, KX, KY, K2 = spectral_grid(n, length)
101
+ omega = np.array(omega0, dtype=float, copy=True)
102
+ for _ in range(steps):
103
+ k1 = vorticity_rhs(omega, KX, KY, K2, nu)
104
+ k2 = vorticity_rhs(omega + dt / 2 * k1, KX, KY, K2, nu)
105
+ k3 = vorticity_rhs(omega + dt / 2 * k2, KX, KY, K2, nu)
106
+ k4 = vorticity_rhs(omega + dt * k3, KX, KY, K2, nu)
107
+ omega = omega + dt / 6 * (k1 + 2 * k2 + 2 * k3 + k4)
108
+ psi = poisson_solve_streamfunction(omega, K2)
109
+ u, v = velocity_from_streamfunction(psi, KX, KY)
110
+ return {"omega": omega, "psi": psi, "u": u, "v": v}
111
+
112
+
113
+ def buoyant_vorticity_rhs(
114
+ omega: NDArray[np.float64],
115
+ buoyancy: NDArray[np.float64],
116
+ KX: NDArray[np.float64],
117
+ KY: NDArray[np.float64],
118
+ K2: NDArray[np.float64],
119
+ nu: float,
120
+ kappa: float,
121
+ g: float,
122
+ ) -> tuple[NDArray[np.float64], NDArray[np.float64]]:
123
+ """Right-hand side of the Boussinesq vorticity-buoyancy system.
124
+
125
+ Extends :func:`vorticity_rhs` with a passively advected-and-diffused
126
+ dimensionless buoyancy field :math:`b = -\\delta\\rho/\\rho_0` (positive
127
+ `b` means locally lighter than the reference density) and its
128
+ baroclinic torque on vorticity, :math:`g\\,\\partial_x b`, which is
129
+ exactly the term through which a horizontal density gradient generates
130
+ vorticity under gravity -- the mechanism behind the Rayleigh-Taylor
131
+ instability.
132
+
133
+ .. math::
134
+
135
+ \\partial_t \\omega + (\\mathbf{u}\\cdot\\nabla)\\omega
136
+ = \\nu \\nabla^2 \\omega + g\\,\\partial_x b \\\\
137
+ \\partial_t b + (\\mathbf{u}\\cdot\\nabla) b = \\kappa \\nabla^2 b
138
+
139
+ Parameters
140
+ ----------
141
+ omega : ndarray of float, shape (n, n)
142
+ Vorticity field.
143
+ buoyancy : ndarray of float, shape (n, n)
144
+ Dimensionless buoyancy field :math:`b`.
145
+ KX, KY, K2 : ndarray of float, shape (n, n)
146
+ Wavenumber grids from :func:`physicskit.fluids.core.grid.spectral_grid`.
147
+ nu : float
148
+ Kinematic viscosity (vorticity diffusivity).
149
+ kappa : float
150
+ Molecular (or eddy) diffusivity of the buoyancy field.
151
+ g : float
152
+ Gravitational acceleration, pointing from ``+y`` toward ``-y``.
153
+
154
+ Returns
155
+ -------
156
+ domega_dt, dbuoyancy_dt : ndarray of float, shape (n, n)
157
+ Time derivatives of vorticity and buoyancy.
158
+ """
159
+ psi = poisson_solve_streamfunction(omega, K2)
160
+ u, v = velocity_from_streamfunction(psi, KX, KY)
161
+
162
+ omega_hat = np.fft.fft2(omega)
163
+ domega_dx = np.real(np.fft.ifft2(1j * KX * omega_hat))
164
+ domega_dy = np.real(np.fft.ifft2(1j * KY * omega_hat))
165
+ diffusion_omega = np.real(np.fft.ifft2(-nu * K2 * omega_hat))
166
+
167
+ b_hat = np.fft.fft2(buoyancy)
168
+ db_dx = np.real(np.fft.ifft2(1j * KX * b_hat))
169
+ db_dy = np.real(np.fft.ifft2(1j * KY * b_hat))
170
+ diffusion_b = np.real(np.fft.ifft2(-kappa * K2 * b_hat))
171
+
172
+ domega_dt = -(u * domega_dx + v * domega_dy) + diffusion_omega + g * db_dx
173
+ dbuoyancy_dt = -(u * db_dx + v * db_dy) + diffusion_b
174
+ return domega_dt, dbuoyancy_dt
175
+
176
+
177
+ def integrate_boussinesq(
178
+ omega0: NDArray[np.float64],
179
+ buoyancy0: NDArray[np.float64],
180
+ nu: float,
181
+ kappa: float,
182
+ g: float,
183
+ dt: float,
184
+ steps: int,
185
+ length: float,
186
+ ) -> dict[str, NDArray[np.float64]]:
187
+ """Time-step the coupled Boussinesq vorticity-buoyancy equations with RK4.
188
+
189
+ Parameters
190
+ ----------
191
+ omega0 : ndarray of float, shape (n, n)
192
+ Initial vorticity field on a doubly periodic ``[0, length)^2`` domain.
193
+ buoyancy0 : ndarray of float, shape (n, n)
194
+ Initial buoyancy field.
195
+ nu : float
196
+ Kinematic viscosity.
197
+ kappa : float
198
+ Buoyancy diffusivity.
199
+ g : float
200
+ Gravitational acceleration.
201
+ dt : float
202
+ Time step.
203
+ steps : int
204
+ Number of RK4 steps to advance.
205
+ length : float
206
+ Physical domain size.
207
+
208
+ Returns
209
+ -------
210
+ dict
211
+ ``{"omega": ..., "buoyancy": ..., "psi": ..., "u": ..., "v": ...}`` at
212
+ the final time.
213
+
214
+ See Also
215
+ --------
216
+ physicskit.fluids.systems.instabilities.simulate_rayleigh_taylor : Validated, documented wrapper.
217
+ """
218
+ n = omega0.shape[0]
219
+ _, _, KX, KY, K2 = spectral_grid(n, length)
220
+ omega = np.array(omega0, dtype=float, copy=True)
221
+ buoyancy = np.array(buoyancy0, dtype=float, copy=True)
222
+ for _ in range(steps):
223
+ k1o, k1b = buoyant_vorticity_rhs(omega, buoyancy, KX, KY, K2, nu, kappa, g)
224
+ k2o, k2b = buoyant_vorticity_rhs(omega + dt / 2 * k1o, buoyancy + dt / 2 * k1b, KX, KY, K2, nu, kappa, g)
225
+ k3o, k3b = buoyant_vorticity_rhs(omega + dt / 2 * k2o, buoyancy + dt / 2 * k2b, KX, KY, K2, nu, kappa, g)
226
+ k4o, k4b = buoyant_vorticity_rhs(omega + dt * k3o, buoyancy + dt * k3b, KX, KY, K2, nu, kappa, g)
227
+ omega = omega + dt / 6 * (k1o + 2 * k2o + 2 * k3o + k4o)
228
+ buoyancy = buoyancy + dt / 6 * (k1b + 2 * k2b + 2 * k3b + k4b)
229
+ psi = poisson_solve_streamfunction(omega, K2)
230
+ u, v = velocity_from_streamfunction(psi, KX, KY)
231
+ return {"omega": omega, "buoyancy": buoyancy, "psi": psi, "u": u, "v": v}
@@ -0,0 +1,26 @@
1
+ """Custom exception hierarchy for physicskit.fluids.
2
+
3
+ All exceptions physicskit.fluids raises intentionally (as opposed to
4
+ exceptions that bubble up unexpectedly from a dependency) inherit from
5
+ :class:`FluidskitError`, so callers can catch "any physicskit.fluids-raised
6
+ problem" with a single ``except FluidskitError``. Each concrete exception
7
+ also inherits from the closest matching built-in exception type (e.g.
8
+ :class:`InvalidParameterError` is also a :class:`ValueError`), so existing
9
+ code that catches the built-in type continues to work unchanged.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+
15
+ class FluidskitError(Exception):
16
+ """Base class for all exceptions raised intentionally by physicskit.fluids."""
17
+
18
+
19
+ class InvalidParameterError(FluidskitError, ValueError):
20
+ """A system or tool was constructed or called with a physically invalid parameter.
21
+
22
+ Examples include a non-positive Reynolds number or viscosity, a grid
23
+ size incompatible with the doubly-periodic pseudo-spectral method's FFT
24
+ assumptions, a cylinder radius too large to fit its sampling grid, or an
25
+ explicit time step that violates a CFL/Courant stability bound.
26
+ """
@@ -0,0 +1,70 @@
1
+ from physicskit.fluids.systems.compressible_flow import (
2
+ normal_shock_relations,
3
+ rankine_hugoniot_jump_conditions,
4
+ sod_shock_tube,
5
+ )
6
+ from physicskit.fluids.systems.instabilities import (
7
+ kelvin_helmholtz_growth_rate,
8
+ kelvin_helmholtz_ic,
9
+ rayleigh_taylor_growth_rate,
10
+ rayleigh_taylor_ic,
11
+ simulate_rayleigh_taylor,
12
+ )
13
+ from physicskit.fluids.systems.navier_stokes import NavierStokes2D, simulate_vorticity_streamfunction
14
+ from physicskit.fluids.systems.potential_flow import (
15
+ PotentialFlow,
16
+ doublet_potential,
17
+ flow_past_cylinder,
18
+ kutta_joukowski_lift,
19
+ point_vortex_potential,
20
+ pressure_coefficient,
21
+ source_potential,
22
+ uniform_flow_potential,
23
+ )
24
+ from physicskit.fluids.systems.viscous_flow import (
25
+ blasius_boundary_layer_thickness,
26
+ blasius_skin_friction_coefficient,
27
+ blasius_solve,
28
+ couette_flow_velocity,
29
+ poiseuille_flow_rate,
30
+ poiseuille_flow_velocity,
31
+ stokes_drag,
32
+ )
33
+ from physicskit.fluids.systems.vortex_dynamics import (
34
+ VON_KARMAN_SPACING_RATIO,
35
+ PointVortexSystem,
36
+ point_vortex_velocities,
37
+ von_karman_vortex_street,
38
+ )
39
+
40
+ __all__ = [
41
+ "VON_KARMAN_SPACING_RATIO",
42
+ "NavierStokes2D",
43
+ "PointVortexSystem",
44
+ "PotentialFlow",
45
+ "blasius_boundary_layer_thickness",
46
+ "blasius_skin_friction_coefficient",
47
+ "blasius_solve",
48
+ "couette_flow_velocity",
49
+ "doublet_potential",
50
+ "flow_past_cylinder",
51
+ "kelvin_helmholtz_growth_rate",
52
+ "kelvin_helmholtz_ic",
53
+ "kutta_joukowski_lift",
54
+ "normal_shock_relations",
55
+ "point_vortex_potential",
56
+ "point_vortex_velocities",
57
+ "poiseuille_flow_rate",
58
+ "poiseuille_flow_velocity",
59
+ "pressure_coefficient",
60
+ "rankine_hugoniot_jump_conditions",
61
+ "rayleigh_taylor_growth_rate",
62
+ "rayleigh_taylor_ic",
63
+ "simulate_rayleigh_taylor",
64
+ "simulate_vorticity_streamfunction",
65
+ "sod_shock_tube",
66
+ "source_potential",
67
+ "stokes_drag",
68
+ "uniform_flow_potential",
69
+ "von_karman_vortex_street",
70
+ ]