physicskit 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- physicskit/__init__.py +51 -0
- physicskit/astro/__init__.py +66 -0
- physicskit/astro/cosmic_web.py +395 -0
- physicskit/astro/galactic_dynamics.py +137 -0
- physicskit/astro/nbody.py +208 -0
- physicskit/astro/orbital_mechanics.py +220 -0
- physicskit/astro/stellar_dynamo.py +628 -0
- physicskit/astro/stellar_structure.py +198 -0
- physicskit/astro/tests/__init__.py +0 -0
- physicskit/astro/tests/conftest.py +7 -0
- physicskit/astro/tests/test_cosmic_web.py +159 -0
- physicskit/astro/tests/test_galactic_dynamics.py +46 -0
- physicskit/astro/tests/test_nbody.py +81 -0
- physicskit/astro/tests/test_orbital_mechanics.py +73 -0
- physicskit/astro/tests/test_stellar_dynamo.py +198 -0
- physicskit/astro/tests/test_stellar_structure.py +52 -0
- physicskit/astro/tests/test_visualizers.py +159 -0
- physicskit/astro/visualizers.py +628 -0
- physicskit/chaos/__init__.py +55 -0
- physicskit/chaos/core/__init__.py +3 -0
- physicskit/chaos/core/base_system.py +342 -0
- physicskit/chaos/core/integrators.py +40 -0
- physicskit/chaos/exceptions.py +24 -0
- physicskit/chaos/quantum/__init__.py +38 -0
- physicskit/chaos/quantum/billiards.py +274 -0
- physicskit/chaos/quantum/husimi.py +85 -0
- physicskit/chaos/quantum/maps.py +366 -0
- physicskit/chaos/systems/__init__.py +38 -0
- physicskit/chaos/systems/billiards.py +1131 -0
- physicskit/chaos/systems/continuous.py +1276 -0
- physicskit/chaos/systems/maps.py +557 -0
- physicskit/chaos/tests/__init__.py +0 -0
- physicskit/chaos/tests/test_basins.py +76 -0
- physicskit/chaos/tests/test_bifurcation.py +132 -0
- physicskit/chaos/tests/test_billiards.py +115 -0
- physicskit/chaos/tests/test_continuous.py +224 -0
- physicskit/chaos/tests/test_dimension.py +69 -0
- physicskit/chaos/tests/test_divergence.py +90 -0
- physicskit/chaos/tests/test_dynamic_plots.py +269 -0
- physicskit/chaos/tests/test_integrators.py +96 -0
- physicskit/chaos/tests/test_io.py +41 -0
- physicskit/chaos/tests/test_maps.py +110 -0
- physicskit/chaos/tests/test_metrics.py +115 -0
- physicskit/chaos/tests/test_phase_space.py +73 -0
- physicskit/chaos/tests/test_properties.py +116 -0
- physicskit/chaos/tests/test_quantum_billiards.py +94 -0
- physicskit/chaos/tests/test_quantum_maps.py +144 -0
- physicskit/chaos/tests/test_recurrence.py +51 -0
- physicskit/chaos/tests/test_repr_and_api_consistency.py +134 -0
- physicskit/chaos/tests/test_section.py +49 -0
- physicskit/chaos/tests/test_spectral.py +48 -0
- physicskit/chaos/tests/test_streamlit_app.py +45 -0
- physicskit/chaos/tests/test_timeseries.py +131 -0
- physicskit/chaos/tests/test_viewer3d.py +41 -0
- physicskit/chaos/utils/__init__.py +46 -0
- physicskit/chaos/utils/dimension.py +139 -0
- physicskit/chaos/utils/io.py +95 -0
- physicskit/chaos/utils/metrics.py +304 -0
- physicskit/chaos/utils/recurrence.py +122 -0
- physicskit/chaos/utils/spectral.py +69 -0
- physicskit/chaos/utils/timeseries.py +303 -0
- physicskit/chaos/visualizers/__init__.py +85 -0
- physicskit/chaos/visualizers/basins.py +185 -0
- physicskit/chaos/visualizers/bifurcation.py +273 -0
- physicskit/chaos/visualizers/divergence.py +374 -0
- physicskit/chaos/visualizers/dynamic_plots.py +1372 -0
- physicskit/chaos/visualizers/phase_space.py +133 -0
- physicskit/chaos/visualizers/quantum.py +299 -0
- physicskit/chaos/visualizers/recurrence.py +91 -0
- physicskit/chaos/visualizers/section.py +161 -0
- physicskit/chaos/visualizers/theme.py +31 -0
- physicskit/chaos/visualizers/viewer3d.py +82 -0
- physicskit/classical/__init__.py +55 -0
- physicskit/classical/core/__init__.py +17 -0
- physicskit/classical/core/base_system.py +510 -0
- physicskit/classical/core/integrators.py +397 -0
- physicskit/classical/systems/__init__.py +32 -0
- physicskit/classical/systems/chains.py +334 -0
- physicskit/classical/systems/hamiltonian.py +215 -0
- physicskit/classical/systems/lagrangian.py +308 -0
- physicskit/classical/systems/newtonian.py +536 -0
- physicskit/classical/systems/rotations.py +614 -0
- physicskit/classical/tests/__init__.py +0 -0
- physicskit/classical/tests/conftest.py +7 -0
- physicskit/classical/tests/test_base_system.py +113 -0
- physicskit/classical/tests/test_chains.py +84 -0
- physicskit/classical/tests/test_conservation.py +244 -0
- physicskit/classical/tests/test_conservation_utils.py +47 -0
- physicskit/classical/tests/test_hamiltonian.py +44 -0
- physicskit/classical/tests/test_integrators.py +123 -0
- physicskit/classical/tests/test_lagrangian.py +69 -0
- physicskit/classical/tests/test_newtonian.py +45 -0
- physicskit/classical/tests/test_rotations.py +160 -0
- physicskit/classical/tests/test_stepsize.py +149 -0
- physicskit/classical/tests/test_symbolic.py +125 -0
- physicskit/classical/tests/test_visualizers.py +172 -0
- physicskit/classical/utils/__init__.py +20 -0
- physicskit/classical/utils/conservation.py +126 -0
- physicskit/classical/utils/stepsize.py +187 -0
- physicskit/classical/utils/symbolic.py +235 -0
- physicskit/classical/visualizers/__init__.py +25 -0
- physicskit/classical/visualizers/animations.py +508 -0
- physicskit/classical/visualizers/interactive.py +113 -0
- physicskit/classical/visualizers/modal_analysis.py +97 -0
- physicskit/classical/visualizers/phase_space.py +214 -0
- physicskit/condensed/__init__.py +122 -0
- physicskit/condensed/anderson_localization.py +155 -0
- physicskit/condensed/correlated.py +284 -0
- physicskit/condensed/ginzburg_landau.py +220 -0
- physicskit/condensed/landau_levels.py +246 -0
- physicskit/condensed/laughlin.py +229 -0
- physicskit/condensed/models.py +627 -0
- physicskit/condensed/tests/__init__.py +0 -0
- physicskit/condensed/tests/test_condensed.py +518 -0
- physicskit/condensed/tests/test_visualizers.py +87 -0
- physicskit/condensed/tight_binding.py +445 -0
- physicskit/condensed/topological_insulator_3d.py +178 -0
- physicskit/condensed/topology.py +217 -0
- physicskit/condensed/visualizers.py +296 -0
- physicskit/condensed/weyl.py +180 -0
- physicskit/constants.py +184 -0
- physicskit/fields/__init__.py +111 -0
- physicskit/fields/electrodynamics.py +671 -0
- physicskit/fields/quantum_fields.py +510 -0
- physicskit/fields/solitons.py +527 -0
- physicskit/fields/tests/__init__.py +0 -0
- physicskit/fields/tests/conftest.py +7 -0
- physicskit/fields/tests/test_field_animations.py +154 -0
- physicskit/fields/tests/test_fields.py +439 -0
- physicskit/fields/tests/test_visualizers.py +101 -0
- physicskit/fields/visualizers.py +503 -0
- physicskit/fluids/__init__.py +134 -0
- physicskit/fluids/core/__init__.py +23 -0
- physicskit/fluids/core/grid.py +165 -0
- physicskit/fluids/core/timestepping.py +231 -0
- physicskit/fluids/exceptions.py +26 -0
- physicskit/fluids/systems/__init__.py +70 -0
- physicskit/fluids/systems/compressible_flow.py +281 -0
- physicskit/fluids/systems/instabilities.py +343 -0
- physicskit/fluids/systems/navier_stokes.py +221 -0
- physicskit/fluids/systems/potential_flow.py +440 -0
- physicskit/fluids/systems/viscous_flow.py +425 -0
- physicskit/fluids/systems/vortex_dynamics.py +304 -0
- physicskit/fluids/tests/__init__.py +0 -0
- physicskit/fluids/tests/conftest.py +7 -0
- physicskit/fluids/tests/test_compressible_flow.py +66 -0
- physicskit/fluids/tests/test_instabilities.py +115 -0
- physicskit/fluids/tests/test_navier_stokes.py +67 -0
- physicskit/fluids/tests/test_potential_flow.py +92 -0
- physicskit/fluids/tests/test_static_visualizers.py +91 -0
- physicskit/fluids/tests/test_utils.py +100 -0
- physicskit/fluids/tests/test_viscous_flow.py +110 -0
- physicskit/fluids/tests/test_visualizers.py +34 -0
- physicskit/fluids/tests/test_vortex_dynamics.py +88 -0
- physicskit/fluids/utils/__init__.py +18 -0
- physicskit/fluids/utils/dimensionless.py +239 -0
- physicskit/fluids/utils/spectral_analysis.py +142 -0
- physicskit/fluids/visualizers/__init__.py +14 -0
- physicskit/fluids/visualizers/compressible.py +39 -0
- physicskit/fluids/visualizers/flow_fields.py +252 -0
- physicskit/fluids/visualizers/potential_flow.py +51 -0
- physicskit/fluids/visualizers/spectra.py +62 -0
- physicskit/fluids/visualizers/theme.py +38 -0
- physicskit/integrators/__init__.py +52 -0
- physicskit/integrators/adaptive.py +199 -0
- physicskit/integrators/fixed_step.py +360 -0
- physicskit/integrators/tests/__init__.py +0 -0
- physicskit/integrators/tests/test_integrators.py +101 -0
- physicskit/optics/__init__.py +124 -0
- physicskit/optics/_compat.py +5 -0
- physicskit/optics/gaussian.py +382 -0
- physicskit/optics/quantum_optics.py +428 -0
- physicskit/optics/ray.py +469 -0
- physicskit/optics/tests/__init__.py +0 -0
- physicskit/optics/tests/test_diffraction_animation.py +38 -0
- physicskit/optics/tests/test_gaussian.py +170 -0
- physicskit/optics/tests/test_quantum_optics.py +147 -0
- physicskit/optics/tests/test_ray.py +177 -0
- physicskit/optics/tests/test_visualizers.py +58 -0
- physicskit/optics/tests/test_wave.py +146 -0
- physicskit/optics/visualizers.py +264 -0
- physicskit/optics/wave.py +365 -0
- physicskit/particle/__init__.py +152 -0
- physicskit/particle/collider.py +382 -0
- physicskit/particle/confinement.py +125 -0
- physicskit/particle/decays.py +357 -0
- physicskit/particle/electroweak.py +300 -0
- physicskit/particle/kinematics.py +271 -0
- physicskit/particle/neutrinos.py +84 -0
- physicskit/particle/nuclear.py +100 -0
- physicskit/particle/scattering.py +159 -0
- physicskit/particle/tests/__init__.py +0 -0
- physicskit/particle/tests/conftest.py +7 -0
- physicskit/particle/tests/test_collider.py +119 -0
- physicskit/particle/tests/test_confinement.py +42 -0
- physicskit/particle/tests/test_decays.py +112 -0
- physicskit/particle/tests/test_electroweak.py +97 -0
- physicskit/particle/tests/test_kinematics.py +138 -0
- physicskit/particle/tests/test_neutrinos.py +36 -0
- physicskit/particle/tests/test_nuclear.py +45 -0
- physicskit/particle/tests/test_scattering.py +64 -0
- physicskit/particle/tests/test_visualizers.py +214 -0
- physicskit/particle/visualizers/__init__.py +38 -0
- physicskit/particle/visualizers/animations.py +705 -0
- physicskit/particle/visualizers/static.py +101 -0
- physicskit/plasma/__init__.py +176 -0
- physicskit/plasma/acceleration.py +152 -0
- physicskit/plasma/instabilities.py +417 -0
- physicskit/plasma/kinetic.py +588 -0
- physicskit/plasma/mhd.py +463 -0
- physicskit/plasma/single_particle.py +562 -0
- physicskit/plasma/tests/__init__.py +0 -0
- physicskit/plasma/tests/conftest.py +7 -0
- physicskit/plasma/tests/test_new_time_domain_features.py +222 -0
- physicskit/plasma/tests/test_plasma.py +232 -0
- physicskit/plasma/tests/test_visualizers.py +79 -0
- physicskit/plasma/turbulence.py +219 -0
- physicskit/plasma/visualizers.py +868 -0
- physicskit/plasma/waves.py +549 -0
- physicskit/quantum/__init__.py +180 -0
- physicskit/quantum/_compat.py +20 -0
- physicskit/quantum/chapters/__init__.py +0 -0
- physicskit/quantum/chapters/entanglement.py +489 -0
- physicskit/quantum/chapters/harmonic_spin.py +517 -0
- physicskit/quantum/chapters/hydrogen_am.py +292 -0
- physicskit/quantum/chapters/perturbation.py +350 -0
- physicskit/quantum/chapters/potentials.py +997 -0
- physicskit/quantum/chapters/spin.py +306 -0
- physicskit/quantum/chapters/wave_packets.py +541 -0
- physicskit/quantum/core/__init__.py +0 -0
- physicskit/quantum/core/eigensolvers.py +311 -0
- physicskit/quantum/core/operators.py +296 -0
- physicskit/quantum/core/solvers.py +271 -0
- physicskit/quantum/tests/__init__.py +0 -0
- physicskit/quantum/tests/conftest.py +7 -0
- physicskit/quantum/tests/test_animations.py +225 -0
- physicskit/quantum/tests/test_compat.py +43 -0
- physicskit/quantum/tests/test_eigensolvers.py +24 -0
- physicskit/quantum/tests/test_entanglement.py +127 -0
- physicskit/quantum/tests/test_harmonic_spin.py +140 -0
- physicskit/quantum/tests/test_hydrogen_am.py +48 -0
- physicskit/quantum/tests/test_measure.py +110 -0
- physicskit/quantum/tests/test_operators.py +105 -0
- physicskit/quantum/tests/test_perturbation.py +112 -0
- physicskit/quantum/tests/test_physics_checks.py +131 -0
- physicskit/quantum/tests/test_potentials.py +191 -0
- physicskit/quantum/tests/test_solvers.py +70 -0
- physicskit/quantum/tests/test_spin.py +22 -0
- physicskit/quantum/tests/test_unitarity.py +84 -0
- physicskit/quantum/tests/test_wave_packets.py +53 -0
- physicskit/quantum/utils/__init__.py +0 -0
- physicskit/quantum/utils/measure.py +253 -0
- physicskit/quantum/visualizers/__init__.py +0 -0
- physicskit/quantum/visualizers/bloch_sphere.py +205 -0
- physicskit/quantum/visualizers/entanglement.py +58 -0
- physicskit/quantum/visualizers/orbitals.py +187 -0
- physicskit/quantum/visualizers/phase_space.py +179 -0
- physicskit/quantum/visualizers/wavefunctions.py +230 -0
- physicskit/relativity/__init__.py +61 -0
- physicskit/relativity/chapters/__init__.py +33 -0
- physicskit/relativity/chapters/cosmology.py +190 -0
- physicskit/relativity/chapters/gw_merger.py +399 -0
- physicskit/relativity/chapters/kerr.py +371 -0
- physicskit/relativity/chapters/lensing.py +196 -0
- physicskit/relativity/chapters/neutron_star.py +149 -0
- physicskit/relativity/chapters/schwarzschild.py +412 -0
- physicskit/relativity/chapters/timekeeping.py +133 -0
- physicskit/relativity/core/__init__.py +12 -0
- physicskit/relativity/core/geodesics.py +216 -0
- physicskit/relativity/core/kerr_raytracer.py +259 -0
- physicskit/relativity/core/raytracer.py +241 -0
- physicskit/relativity/core/tensors.py +468 -0
- physicskit/relativity/tests/__init__.py +0 -0
- physicskit/relativity/tests/test_conservations.py +54 -0
- physicskit/relativity/tests/test_constants.py +34 -0
- physicskit/relativity/tests/test_cosmology.py +61 -0
- physicskit/relativity/tests/test_gw_merger.py +117 -0
- physicskit/relativity/tests/test_kerr.py +116 -0
- physicskit/relativity/tests/test_kerr_raytracer.py +103 -0
- physicskit/relativity/tests/test_lensing.py +75 -0
- physicskit/relativity/tests/test_neutron_star.py +48 -0
- physicskit/relativity/tests/test_raytracer.py +67 -0
- physicskit/relativity/tests/test_schwarzschild.py +126 -0
- physicskit/relativity/tests/test_shadow_render.py +81 -0
- physicskit/relativity/tests/test_tensors.py +86 -0
- physicskit/relativity/tests/test_timekeeping.py +51 -0
- physicskit/relativity/tests/test_visualizers_misc.py +115 -0
- physicskit/relativity/utils/__init__.py +1 -0
- physicskit/relativity/utils/constants.py +232 -0
- physicskit/relativity/visualizers/__init__.py +46 -0
- physicskit/relativity/visualizers/interactive.py +127 -0
- physicskit/relativity/visualizers/shadow_render.py +367 -0
- physicskit/relativity/visualizers/spacetime_3d.py +92 -0
- physicskit/relativity/visualizers/spacetime_diagrams.py +198 -0
- physicskit/relativity/visualizers/wave_plots.py +185 -0
- physicskit/rmt/__init__.py +8 -0
- physicskit/rmt/ensembles/__init__.py +108 -0
- physicskit/rmt/ensembles/banded.py +114 -0
- physicskit/rmt/ensembles/base.py +135 -0
- physicskit/rmt/ensembles/bdg.py +218 -0
- physicskit/rmt/ensembles/chiral.py +308 -0
- physicskit/rmt/ensembles/circular.py +104 -0
- physicskit/rmt/ensembles/crossover.py +82 -0
- physicskit/rmt/ensembles/density_matrix.py +148 -0
- physicskit/rmt/ensembles/effective_hamiltonian.py +230 -0
- physicskit/rmt/ensembles/embedded.py +207 -0
- physicskit/rmt/ensembles/gaussian.py +153 -0
- physicskit/rmt/ensembles/ginibre.py +110 -0
- physicskit/rmt/ensembles/girko.py +190 -0
- physicskit/rmt/ensembles/graph_laplacian.py +92 -0
- physicskit/rmt/ensembles/haar.py +57 -0
- physicskit/rmt/ensembles/jacobi.py +182 -0
- physicskit/rmt/ensembles/poisson.py +77 -0
- physicskit/rmt/ensembles/polynomial.py +139 -0
- physicskit/rmt/ensembles/pt_symmetric.py +120 -0
- physicskit/rmt/ensembles/single_ring.py +170 -0
- physicskit/rmt/ensembles/sparse.py +95 -0
- physicskit/rmt/ensembles/syk.py +170 -0
- physicskit/rmt/ensembles/truncated_unitary.py +80 -0
- physicskit/rmt/ensembles/universality.py +92 -0
- physicskit/rmt/ensembles/wishart.py +88 -0
- physicskit/rmt/py.typed +0 -0
- physicskit/rmt/spectrum.py +82 -0
- physicskit/rmt/stats/__init__.py +160 -0
- physicskit/rmt/stats/characteristic_polynomial.py +77 -0
- physicskit/rmt/stats/circular_law.py +54 -0
- physicskit/rmt/stats/correlations.py +162 -0
- physicskit/rmt/stats/density.py +70 -0
- physicskit/rmt/stats/entanglement.py +36 -0
- physicskit/rmt/stats/free_probability.py +202 -0
- physicskit/rmt/stats/localization.py +338 -0
- physicskit/rmt/stats/marchenko_pastur.py +55 -0
- physicskit/rmt/stats/pt_symmetric.py +265 -0
- physicskit/rmt/stats/ratios.py +110 -0
- physicskit/rmt/stats/real_ginibre.py +134 -0
- physicskit/rmt/stats/rigidity.py +272 -0
- physicskit/rmt/stats/single_ring.py +95 -0
- physicskit/rmt/stats/spacing.py +150 -0
- physicskit/rmt/stats/tracy_widom.py +175 -0
- physicskit/rmt/stats/truncated_unitary.py +40 -0
- physicskit/rmt/stats/unfolding.py +37 -0
- physicskit/rmt/stats/wachter.py +67 -0
- physicskit/rmt/tests/__init__.py +0 -0
- physicskit/rmt/tests/cache_utils.py +107 -0
- physicskit/rmt/tests/conftest.py +8 -0
- physicskit/rmt/tests/test_banded.py +86 -0
- physicskit/rmt/tests/test_base.py +29 -0
- physicskit/rmt/tests/test_bdg.py +133 -0
- physicskit/rmt/tests/test_characteristic_polynomial.py +50 -0
- physicskit/rmt/tests/test_chiral.py +273 -0
- physicskit/rmt/tests/test_circular.py +225 -0
- physicskit/rmt/tests/test_crossover.py +72 -0
- physicskit/rmt/tests/test_density.py +23 -0
- physicskit/rmt/tests/test_density_matrix.py +181 -0
- physicskit/rmt/tests/test_effective_hamiltonian.py +140 -0
- physicskit/rmt/tests/test_embedded.py +169 -0
- physicskit/rmt/tests/test_free_probability.py +81 -0
- physicskit/rmt/tests/test_gaussian_ensembles.py +22 -0
- physicskit/rmt/tests/test_gaussian_semicircle.py +127 -0
- physicskit/rmt/tests/test_ginibre_circular_law.py +131 -0
- physicskit/rmt/tests/test_girko.py +178 -0
- physicskit/rmt/tests/test_graph_laplacian.py +102 -0
- physicskit/rmt/tests/test_haar.py +118 -0
- physicskit/rmt/tests/test_jacobi_wachter.py +136 -0
- physicskit/rmt/tests/test_localization.py +240 -0
- physicskit/rmt/tests/test_poisson.py +149 -0
- physicskit/rmt/tests/test_polynomial.py +107 -0
- physicskit/rmt/tests/test_pt_symmetric.py +178 -0
- physicskit/rmt/tests/test_random_state.py +19 -0
- physicskit/rmt/tests/test_real_ginibre.py +112 -0
- physicskit/rmt/tests/test_rigidity_universality.py +167 -0
- physicskit/rmt/tests/test_single_ring.py +132 -0
- physicskit/rmt/tests/test_spacing_and_ratios.py +122 -0
- physicskit/rmt/tests/test_sparse.py +71 -0
- physicskit/rmt/tests/test_spectrum.py +27 -0
- physicskit/rmt/tests/test_syk.py +136 -0
- physicskit/rmt/tests/test_tracy_widom.py +113 -0
- physicskit/rmt/tests/test_tridiagonal.py +41 -0
- physicskit/rmt/tests/test_truncated_unitary.py +80 -0
- physicskit/rmt/tests/test_validation_base.py +25 -0
- physicskit/rmt/tests/test_validation_misc.py +67 -0
- physicskit/rmt/tests/test_wishart_marchenko_pastur.py +120 -0
- physicskit/rmt/utils/__init__.py +0 -0
- physicskit/rmt/utils/haar.py +128 -0
- physicskit/rmt/utils/random_state.py +24 -0
- physicskit/rmt/utils/tridiagonal.py +167 -0
- physicskit/rmt/validation/__init__.py +36 -0
- physicskit/rmt/validation/base.py +126 -0
- physicskit/rmt/validation/circular_law.py +80 -0
- physicskit/rmt/validation/marchenko_pastur.py +53 -0
- physicskit/rmt/validation/ratio_distribution.py +53 -0
- physicskit/rmt/validation/real_ginibre.py +60 -0
- physicskit/rmt/validation/sine_kernel.py +57 -0
- physicskit/rmt/validation/single_ring.py +68 -0
- physicskit/rmt/validation/tracy_widom.py +89 -0
- physicskit/rmt/validation/universality.py +100 -0
- physicskit/rmt/validation/wachter.py +52 -0
- physicskit/rmt/validation/wigner_semicircle.py +40 -0
- physicskit/rmt/validation/wigner_surmise.py +58 -0
- physicskit/semiclassical/__init__.py +94 -0
- physicskit/semiclassical/_compat.py +5 -0
- physicskit/semiclassical/core/__init__.py +41 -0
- physicskit/semiclassical/core/gutzwiller.py +215 -0
- physicskit/semiclassical/core/path_integral.py +594 -0
- physicskit/semiclassical/core/propagators.py +579 -0
- physicskit/semiclassical/core/wkb.py +308 -0
- physicskit/semiclassical/systems/__init__.py +13 -0
- physicskit/semiclassical/systems/scarring.py +278 -0
- physicskit/semiclassical/tests/__init__.py +0 -0
- physicskit/semiclassical/tests/test_gutzwiller.py +35 -0
- physicskit/semiclassical/tests/test_path_integral.py +194 -0
- physicskit/semiclassical/tests/test_propagators.py +82 -0
- physicskit/semiclassical/tests/test_scarring.py +43 -0
- physicskit/semiclassical/tests/test_visualizers.py +89 -0
- physicskit/semiclassical/tests/test_wkb.py +30 -0
- physicskit/semiclassical/visualizers/__init__.py +17 -0
- physicskit/semiclassical/visualizers/gutzwiller.py +55 -0
- physicskit/semiclassical/visualizers/path_integral.py +195 -0
- physicskit/semiclassical/visualizers/propagators.py +89 -0
- physicskit/semiclassical/visualizers/scarring.py +146 -0
- physicskit/semiclassical/visualizers/wkb.py +55 -0
- physicskit/statphys/__init__.py +80 -0
- physicskit/statphys/chapters/__init__.py +43 -0
- physicskit/statphys/chapters/ehrenfest_urn.py +112 -0
- physicskit/statphys/chapters/ising_lattice.py +431 -0
- physicskit/statphys/chapters/kpz_growth.py +129 -0
- physicskit/statphys/chapters/molecular_dynamics.py +258 -0
- physicskit/statphys/chapters/nonequilibrium_work.py +146 -0
- physicskit/statphys/chapters/percolation.py +305 -0
- physicskit/statphys/chapters/random_walk.py +142 -0
- physicskit/statphys/chapters/renormalization.py +148 -0
- physicskit/statphys/chapters/sandpile.py +109 -0
- physicskit/statphys/chapters/spin_glass.py +275 -0
- physicskit/statphys/core/__init__.py +10 -0
- physicskit/statphys/core/kpz_engine.py +53 -0
- physicskit/statphys/core/md_engine.py +157 -0
- physicskit/statphys/core/monte_carlo.py +462 -0
- physicskit/statphys/core/random_walk_engine.py +68 -0
- physicskit/statphys/core/sandpile_engine.py +52 -0
- physicskit/statphys/tests/__init__.py +0 -0
- physicskit/statphys/tests/test_dynamics.py +66 -0
- physicskit/statphys/tests/test_ehrenfest_urn.py +44 -0
- physicskit/statphys/tests/test_finite_size_scaling.py +62 -0
- physicskit/statphys/tests/test_interactive.py +33 -0
- physicskit/statphys/tests/test_ising.py +68 -0
- physicskit/statphys/tests/test_kpz.py +55 -0
- physicskit/statphys/tests/test_landau_theory.py +49 -0
- physicskit/statphys/tests/test_md_engine.py +31 -0
- physicskit/statphys/tests/test_molecular_dynamics.py +72 -0
- physicskit/statphys/tests/test_nonequilibrium_work.py +33 -0
- physicskit/statphys/tests/test_partition_function.py +26 -0
- physicskit/statphys/tests/test_percolation.py +116 -0
- physicskit/statphys/tests/test_potts_model.py +46 -0
- physicskit/statphys/tests/test_random_walk.py +50 -0
- physicskit/statphys/tests/test_renormalization.py +44 -0
- physicskit/statphys/tests/test_sandpile.py +44 -0
- physicskit/statphys/tests/test_spin_glass.py +73 -0
- physicskit/statphys/tests/test_thermodynamics.py +121 -0
- physicskit/statphys/tests/test_xy_model.py +45 -0
- physicskit/statphys/utils/__init__.py +1 -0
- physicskit/statphys/utils/dynamics.py +100 -0
- physicskit/statphys/utils/finite_size_scaling.py +171 -0
- physicskit/statphys/utils/landau_theory.py +151 -0
- physicskit/statphys/utils/partition_function.py +109 -0
- physicskit/statphys/utils/thermodynamics.py +356 -0
- physicskit/statphys/visualizers/__init__.py +87 -0
- physicskit/statphys/visualizers/interactive.py +161 -0
- physicskit/statphys/visualizers/jarzynski_render.py +44 -0
- physicskit/statphys/visualizers/kpz_render.py +65 -0
- physicskit/statphys/visualizers/lattice_render.py +212 -0
- physicskit/statphys/visualizers/particle_render.py +121 -0
- physicskit/statphys/visualizers/random_walk_render.py +106 -0
- physicskit/statphys/visualizers/rg_render.py +45 -0
- physicskit/statphys/visualizers/sandpile_render.py +65 -0
- physicskit/statphys/visualizers/spin_glass_render.py +40 -0
- physicskit/statphys/visualizers/urn_render.py +38 -0
- physicskit/statphys/visualizers/vortex_render.py +84 -0
- physicskit/tests/__init__.py +0 -0
- physicskit/tests/test_constants.py +38 -0
- physicskit-0.1.0.dist-info/METADATA +196 -0
- physicskit-0.1.0.dist-info/RECORD +484 -0
- physicskit-0.1.0.dist-info/WHEEL +5 -0
- physicskit-0.1.0.dist-info/licenses/LICENSE +21 -0
- physicskit-0.1.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,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
|
+
]
|