earthsciencekit 0.2.0__tar.gz

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 (111) hide show
  1. earthsciencekit-0.2.0/CHANGELOG.md +75 -0
  2. earthsciencekit-0.2.0/CITATION.cff +11 -0
  3. earthsciencekit-0.2.0/CONTRIBUTING.md +16 -0
  4. earthsciencekit-0.2.0/LICENSE +15 -0
  5. earthsciencekit-0.2.0/MANIFEST.in +3 -0
  6. earthsciencekit-0.2.0/PKG-INFO +127 -0
  7. earthsciencekit-0.2.0/README.md +80 -0
  8. earthsciencekit-0.2.0/earthsciencekit/__init__.py +6 -0
  9. earthsciencekit-0.2.0/earthsciencekit/_validation.py +62 -0
  10. earthsciencekit-0.2.0/earthsciencekit/atmosphere/__init__.py +57 -0
  11. earthsciencekit-0.2.0/earthsciencekit/atmosphere/core/__init__.py +5 -0
  12. earthsciencekit-0.2.0/earthsciencekit/atmosphere/core/base.py +10 -0
  13. earthsciencekit-0.2.0/earthsciencekit/atmosphere/systems/__init__.py +1 -0
  14. earthsciencekit-0.2.0/earthsciencekit/atmosphere/systems/dynamics.py +208 -0
  15. earthsciencekit-0.2.0/earthsciencekit/atmosphere/systems/hydrostatics.py +214 -0
  16. earthsciencekit-0.2.0/earthsciencekit/atmosphere/systems/moisture.py +162 -0
  17. earthsciencekit-0.2.0/earthsciencekit/atmosphere/systems/thermodynamics.py +222 -0
  18. earthsciencekit-0.2.0/earthsciencekit/atmosphere/tests/__init__.py +0 -0
  19. earthsciencekit-0.2.0/earthsciencekit/atmosphere/tests/test_models.py +741 -0
  20. earthsciencekit-0.2.0/earthsciencekit/atmosphere/tests/test_physics.py +81 -0
  21. earthsciencekit-0.2.0/earthsciencekit/atmosphere/visualizers/__init__.py +9 -0
  22. earthsciencekit-0.2.0/earthsciencekit/climate/__init__.py +63 -0
  23. earthsciencekit-0.2.0/earthsciencekit/climate/core/__init__.py +5 -0
  24. earthsciencekit-0.2.0/earthsciencekit/climate/core/base.py +10 -0
  25. earthsciencekit-0.2.0/earthsciencekit/climate/systems/__init__.py +1 -0
  26. earthsciencekit-0.2.0/earthsciencekit/climate/systems/carbon.py +76 -0
  27. earthsciencekit-0.2.0/earthsciencekit/climate/systems/forcing.py +124 -0
  28. earthsciencekit-0.2.0/earthsciencekit/climate/systems/radiation.py +214 -0
  29. earthsciencekit-0.2.0/earthsciencekit/climate/systems/response.py +402 -0
  30. earthsciencekit-0.2.0/earthsciencekit/climate/systems/sea_level.py +77 -0
  31. earthsciencekit-0.2.0/earthsciencekit/climate/tests/__init__.py +0 -0
  32. earthsciencekit-0.2.0/earthsciencekit/climate/tests/test_models.py +1015 -0
  33. earthsciencekit-0.2.0/earthsciencekit/climate/tests/test_physics.py +16 -0
  34. earthsciencekit-0.2.0/earthsciencekit/climate/visualizers/__init__.py +9 -0
  35. earthsciencekit-0.2.0/earthsciencekit/constants/__init__.py +23 -0
  36. earthsciencekit-0.2.0/earthsciencekit/geophysics/__init__.py +77 -0
  37. earthsciencekit-0.2.0/earthsciencekit/geophysics/core/__init__.py +5 -0
  38. earthsciencekit-0.2.0/earthsciencekit/geophysics/core/base.py +10 -0
  39. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/__init__.py +1 -0
  40. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/deformation.py +161 -0
  41. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/dynamo.py +159 -0
  42. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/figure.py +292 -0
  43. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/gravity.py +235 -0
  44. earthsciencekit-0.2.0/earthsciencekit/geophysics/systems/magnetism.py +354 -0
  45. earthsciencekit-0.2.0/earthsciencekit/geophysics/tests/__init__.py +0 -0
  46. earthsciencekit-0.2.0/earthsciencekit/geophysics/tests/test_models.py +898 -0
  47. earthsciencekit-0.2.0/earthsciencekit/geophysics/tests/test_physics.py +171 -0
  48. earthsciencekit-0.2.0/earthsciencekit/geophysics/visualizers/__init__.py +9 -0
  49. earthsciencekit-0.2.0/earthsciencekit/integrators/__init__.py +62 -0
  50. earthsciencekit-0.2.0/earthsciencekit/oceanography/__init__.py +61 -0
  51. earthsciencekit-0.2.0/earthsciencekit/oceanography/core/__init__.py +5 -0
  52. earthsciencekit-0.2.0/earthsciencekit/oceanography/core/base.py +10 -0
  53. earthsciencekit-0.2.0/earthsciencekit/oceanography/systems/__init__.py +1 -0
  54. earthsciencekit-0.2.0/earthsciencekit/oceanography/systems/circulation.py +388 -0
  55. earthsciencekit-0.2.0/earthsciencekit/oceanography/systems/hydrography.py +212 -0
  56. earthsciencekit-0.2.0/earthsciencekit/oceanography/systems/inertial.py +86 -0
  57. earthsciencekit-0.2.0/earthsciencekit/oceanography/systems/waves.py +281 -0
  58. earthsciencekit-0.2.0/earthsciencekit/oceanography/tests/__init__.py +0 -0
  59. earthsciencekit-0.2.0/earthsciencekit/oceanography/tests/test_models.py +916 -0
  60. earthsciencekit-0.2.0/earthsciencekit/oceanography/tests/test_physics.py +102 -0
  61. earthsciencekit-0.2.0/earthsciencekit/oceanography/visualizers/__init__.py +9 -0
  62. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/__init__.py +59 -0
  63. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/core/__init__.py +5 -0
  64. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/core/base.py +10 -0
  65. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/systems/__init__.py +1 -0
  66. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/systems/boundaries.py +201 -0
  67. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/systems/cooling.py +238 -0
  68. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/systems/isostasy.py +157 -0
  69. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/systems/kinematics.py +290 -0
  70. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/tests/__init__.py +0 -0
  71. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/tests/test_models.py +920 -0
  72. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/tests/test_physics.py +94 -0
  73. earthsciencekit-0.2.0/earthsciencekit/plate_tectonics/visualizers/__init__.py +9 -0
  74. earthsciencekit-0.2.0/earthsciencekit/py.typed +0 -0
  75. earthsciencekit-0.2.0/earthsciencekit/results.py +73 -0
  76. earthsciencekit-0.2.0/earthsciencekit/seismology/__init__.py +59 -0
  77. earthsciencekit-0.2.0/earthsciencekit/seismology/core/__init__.py +5 -0
  78. earthsciencekit-0.2.0/earthsciencekit/seismology/core/base.py +10 -0
  79. earthsciencekit-0.2.0/earthsciencekit/seismology/systems/__init__.py +1 -0
  80. earthsciencekit-0.2.0/earthsciencekit/seismology/systems/interfaces.py +102 -0
  81. earthsciencekit-0.2.0/earthsciencekit/seismology/systems/rays.py +221 -0
  82. earthsciencekit-0.2.0/earthsciencekit/seismology/systems/sources.py +249 -0
  83. earthsciencekit-0.2.0/earthsciencekit/seismology/systems/waves.py +268 -0
  84. earthsciencekit-0.2.0/earthsciencekit/seismology/tests/__init__.py +0 -0
  85. earthsciencekit-0.2.0/earthsciencekit/seismology/tests/test_models.py +852 -0
  86. earthsciencekit-0.2.0/earthsciencekit/seismology/tests/test_physics.py +100 -0
  87. earthsciencekit-0.2.0/earthsciencekit/seismology/visualizers/__init__.py +9 -0
  88. earthsciencekit-0.2.0/earthsciencekit/tests/__init__.py +0 -0
  89. earthsciencekit-0.2.0/earthsciencekit/tests/test_core.py +181 -0
  90. earthsciencekit-0.2.0/earthsciencekit/tests/test_relations.py +36 -0
  91. earthsciencekit-0.2.0/earthsciencekit/units/__init__.py +66 -0
  92. earthsciencekit-0.2.0/earthsciencekit/visualizers/__init__.py +45 -0
  93. earthsciencekit-0.2.0/earthsciencekit/volcanology/__init__.py +61 -0
  94. earthsciencekit-0.2.0/earthsciencekit/volcanology/core/__init__.py +5 -0
  95. earthsciencekit-0.2.0/earthsciencekit/volcanology/core/base.py +10 -0
  96. earthsciencekit-0.2.0/earthsciencekit/volcanology/systems/__init__.py +1 -0
  97. earthsciencekit-0.2.0/earthsciencekit/volcanology/systems/eruptions.py +161 -0
  98. earthsciencekit-0.2.0/earthsciencekit/volcanology/systems/geochemistry.py +226 -0
  99. earthsciencekit-0.2.0/earthsciencekit/volcanology/systems/geochronology.py +304 -0
  100. earthsciencekit-0.2.0/earthsciencekit/volcanology/systems/magma.py +190 -0
  101. earthsciencekit-0.2.0/earthsciencekit/volcanology/tests/__init__.py +0 -0
  102. earthsciencekit-0.2.0/earthsciencekit/volcanology/tests/test_models.py +485 -0
  103. earthsciencekit-0.2.0/earthsciencekit/volcanology/tests/test_physics.py +176 -0
  104. earthsciencekit-0.2.0/earthsciencekit/volcanology/visualizers/__init__.py +9 -0
  105. earthsciencekit-0.2.0/earthsciencekit.egg-info/PKG-INFO +127 -0
  106. earthsciencekit-0.2.0/earthsciencekit.egg-info/SOURCES.txt +109 -0
  107. earthsciencekit-0.2.0/earthsciencekit.egg-info/dependency_links.txt +1 -0
  108. earthsciencekit-0.2.0/earthsciencekit.egg-info/requires.txt +35 -0
  109. earthsciencekit-0.2.0/earthsciencekit.egg-info/top_level.txt +1 -0
  110. earthsciencekit-0.2.0/pyproject.toml +44 -0
  111. earthsciencekit-0.2.0/setup.cfg +4 -0
@@ -0,0 +1,75 @@
1
+ # Changelog
2
+
3
+ ## [0.2.0] - 2026-10-17
4
+
5
+ - First release on PyPI, with the git history on GitHub, CI, tag-driven
6
+ releases (`release.yml`), docs hosted on GitHub Pages (`docs.yml`), a mypy
7
+ step in CI, JupyterLite buttons on the gallery and a Colab quickstart
8
+ notebook (ROADMAP item 1).
9
+ - New `geophysics` domain (ROADMAP item 6): gravity anomalies and reductions,
10
+ normal gravity, Clairaut's theorem and the flattening, satellite J2, Stokes's
11
+ geoid kernel, the axial dipole and zonal Gauss coefficients, field elements,
12
+ virtual geomagnetic poles, magnetic anomalies of reversed blocks, the dynamo
13
+ scales, Love numbers and GRACE equivalent water: 30 algebraic models and the
14
+ dynamic `simulate_rikitake_dynamo`. Its history is a dated chronology of 16
15
+ breakthroughs, from Gilbert's magnetic Earth (1600) to GRACE (2002), each with
16
+ its own executed example.
17
+ - New units `m/s^2`, `mGal`, `T` and `nT`.
18
+ - New `volcanology` domain (ROADMAP item 7): radioactive decay and the age
19
+ equation, radiocarbon, Pb-Pb ages, the U-Pb concordia and the isochron,
20
+ Rayleigh fractionation and delta values, fractional and equilibrium
21
+ crystallization, lattice-strain partitioning, the oxygen-isotope
22
+ thermometer, Arrhenius and Shaw viscosity, water solubility, dike ascent,
23
+ the Mogi source, plume and eruption-column heights and the VEI: 23
24
+ algebraic models and the dynamic `simulate_eruption_column`. Its history is
25
+ a dated chronology of 17 breakthroughs, from Rayleigh's fractional
26
+ distillation (1896) to the Volcanic Explosivity Index (1982), each with its
27
+ own executed example.
28
+ - New units `kyr`, `Ma`, `Ga` and `GPa`; new constants `AVOGADRO`,
29
+ `LAMBDA_U238`, `LAMBDA_U235`, `U238_U235` and `LIBBY_MEAN_LIFE`.
30
+ - Family layout: each domain is a package of `systems/<topic>.py` modules with
31
+ `core/`, `visualizers/` and `tests/`; `constants` and `units` are packages and
32
+ the cross-cutting tests moved from `tests/` to `earthsciencekit/tests/`. Every
33
+ public import path, such as `from earthsciencekit.climate import simulate_one_box`,
34
+ is unchanged.
35
+ - `plate_tectonics` history is a dated chronology of 16 breakthroughs, from Euler's
36
+ rotation theorem (1776) to NUVEL-1 (1990), each with its own executed example;
37
+ the three shared plate_tectonics gallery scripts are removed.
38
+ - New `plate_tectonics` models: `mantle_rayleigh_number`, `flexural_deflection`,
39
+ `hotspot_age`, `ocean_depth` and `compose_euler_vectors`.
40
+ - `seismology` history is a dated chronology of 16 breakthroughs, from Poisson's
41
+ two elastic waves (1829) to PREM (1981), each with its own executed example;
42
+ the three shared seismology gallery scripts are removed.
43
+ - New `seismology` models: `rayleigh_wave_speed`, `head_wave_travel_time`,
44
+ `crossover_distance`, `love_wave_angular_frequency`, `ray_parameter`,
45
+ `local_magnitude` and `vertical_travel_time`.
46
+ - `atmosphere` history is a dated chronology of 16 breakthroughs, from Torricelli's
47
+ barometer (1643) to the ENIAC forecast (1950), each with its own executed example;
48
+ the three shared atmosphere gallery scripts are removed.
49
+ - New `atmosphere` models: `barometer_column_height`, `two_layer_temperature`,
50
+ `richardson_number`, `surface_pressure_tendency`, `rossby_wave_speed` and the
51
+ dynamic `simulate_barotropic_vorticity`.
52
+ - `climate` history is a dated chronology of 16 breakthroughs, from Fourier's
53
+ greenhouse (1824) to the sea-level budget (2005), each with its own executed
54
+ example; the three shared climate gallery scripts are removed.
55
+ - New `climate` models: `greenhouse_surface_temperature`, `daily_insolation`,
56
+ `radiative_convective_temperature`, `equilibrium_solar_constant`,
57
+ `red_noise_spectrum`, `methane_forcing`, `nitrous_oxide_forcing` and
58
+ `gregory_regression`.
59
+ - `oceanography` history is a dated chronology of 16 breakthroughs, from Newton's
60
+ equilibrium tide (1687) to TEOS-10 (2010), each with its own executed example;
61
+ the three shared oceanography gallery scripts are removed.
62
+ - New `oceanography` models: `gerstner_orbit_radius`, `ekman_spiral_velocity`,
63
+ `sverdrup_transport`, `stommel_streamfunction`, `thermohaline_forcing`,
64
+ `abyssal_temperature`, `simplified_seawater_density` and the dynamic
65
+ `simulate_thermohaline_boxes`.
66
+
67
+ ## [0.1.0] - 2026-10-04
68
+
69
+ Initial educational release.
70
+
71
+ - Five domains: plate_tectonics, seismology, atmosphere, climate, oceanography.
72
+ - 77 validated algebraic models and five sampled dynamical models.
73
+ - Shared integration, immutable results, explicit units, labeled plots and animations.
74
+ - MathematicsKit-style Sphinx hubs, histories, guides and 15 executed examples.
75
+ - Independent reference, conservation, limit and invalid-input tests; coverage gate.
@@ -0,0 +1,11 @@
1
+ cff-version: 1.2.0
2
+ message: "Please cite EarthScienceKit when using its educational models."
3
+ title: "EarthScienceKit: inspectable Earth-system computations"
4
+ authors:
5
+ - family-names: Poli
6
+ given-names: Charles
7
+ version: 0.2.0
8
+ date-released: 2026-10-17
9
+ license: MIT
10
+ repository-code: "https://github.com/cpoli/earthsciencekit"
11
+ url: "https://cpoli.github.io/earthsciencekit/"
@@ -0,0 +1,16 @@
1
+ # Contributing
2
+
3
+ Install `python -m pip install -e '.[dev]'`. Use Python 3.10 or newer.
4
+
5
+ For every public model, document the governing expression, every input/output
6
+ unit, physical conventions and applicability limits. Validate mathematical bounds
7
+ and finite real inputs. Test independent known values and at least one meaningful
8
+ identity or limit. Add a runnable example and update the guide/history when the
9
+ model extends a scientific concept. Avoid runtime formula evaluation or hidden
10
+ network requests.
11
+
12
+ Run pytest with production coverage, Ruff lint/format and Sphinx warnings-as-errors
13
+ before proposing a change. CI enforces 100% statement coverage; this is a release
14
+ check, not proof of scientific accuracy. Keep version changes explicit and update
15
+ CHANGELOG.md. Releases are cut by pushing a `vX.Y.Z` tag (see
16
+ `.github/workflows/release.yml`).
@@ -0,0 +1,15 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Charles Poli
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
15
+ SOFTWARE.
@@ -0,0 +1,3 @@
1
+ include README.md LICENSE CHANGELOG.md CITATION.cff
2
+ recursive-include earthsciencekit *.py py.typed
3
+ include CONTRIBUTING.md
@@ -0,0 +1,127 @@
1
+ Metadata-Version: 2.4
2
+ Name: earthsciencekit
3
+ Version: 0.2.0
4
+ Summary: Inspectable Earth-system models for learning and teaching.
5
+ Author-email: Charles Poli <cpoli374@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/cpoli/earthsciencekit
8
+ Project-URL: Documentation, https://cpoli.github.io/earthsciencekit/
9
+ Project-URL: Issues, https://github.com/cpoli/earthsciencekit/issues
10
+ Project-URL: Changelog, https://github.com/cpoli/earthsciencekit/blob/main/CHANGELOG.md
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: numpy>=1.24
15
+ Requires-Dist: scipy>=1.10
16
+ Requires-Dist: matplotlib>=3.6
17
+ Provides-Extra: test
18
+ Requires-Dist: pytest>=7; extra == "test"
19
+ Requires-Dist: pytest-cov; extra == "test"
20
+ Provides-Extra: docs
21
+ Requires-Dist: sphinx-design>=0.6; extra == "docs"
22
+ Requires-Dist: sphinx-gallery>=0.19; extra == "docs"
23
+ Requires-Dist: sphinx-autodoc-typehints>=2; extra == "docs"
24
+ Requires-Dist: sphinx>=7; extra == "docs"
25
+ Requires-Dist: pydata-sphinx-theme>=0.15; extra == "docs"
26
+ Requires-Dist: sphinx-sitemap>=2.6; extra == "docs"
27
+ Requires-Dist: sphinxext-opengraph>=0.9; extra == "docs"
28
+ Requires-Dist: jupyterlite-sphinx>=0.17; extra == "docs"
29
+ Requires-Dist: jupyterlite-pyodide-kernel>=0.4; extra == "docs"
30
+ Provides-Extra: dev
31
+ Requires-Dist: sphinx-design>=0.6; extra == "dev"
32
+ Requires-Dist: sphinx-sitemap>=2.6; extra == "dev"
33
+ Requires-Dist: sphinxext-opengraph>=0.9; extra == "dev"
34
+ Requires-Dist: sphinx-gallery>=0.19; extra == "dev"
35
+ Requires-Dist: sphinx-autodoc-typehints>=2; extra == "dev"
36
+ Requires-Dist: pytest>=7; extra == "dev"
37
+ Requires-Dist: pytest-cov; extra == "dev"
38
+ Requires-Dist: sphinx>=7; extra == "dev"
39
+ Requires-Dist: pydata-sphinx-theme>=0.15; extra == "dev"
40
+ Requires-Dist: jupyterlite-sphinx>=0.17; extra == "dev"
41
+ Requires-Dist: jupyterlite-pyodide-kernel>=0.4; extra == "dev"
42
+ Requires-Dist: ruff>=0.6; extra == "dev"
43
+ Requires-Dist: mypy>=1.10; extra == "dev"
44
+ Requires-Dist: build>=1.2; extra == "dev"
45
+ Requires-Dist: twine>=5; extra == "dev"
46
+ Dynamic: license-file
47
+
48
+ # EarthScienceKit
49
+
50
+ Inspectable Earth-system computations for learning and teaching.
51
+
52
+ [![PyPI](https://img.shields.io/pypi/v/earthsciencekit)](https://pypi.org/project/earthsciencekit/)
53
+ [![CI](https://github.com/cpoli/earthsciencekit/actions/workflows/ci.yml/badge.svg)](https://github.com/cpoli/earthsciencekit/actions/workflows/ci.yml)
54
+ [![Docs](https://img.shields.io/badge/docs-cpoli.github.io-blue)](https://cpoli.github.io/earthsciencekit/)
55
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/cpoli/earthsciencekit/blob/main/notebooks/quickstart.ipynb)
56
+ [![JupyterLite](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://cpoli.github.io/earthsciencekit/lite/lab/)
57
+
58
+ EarthScienceKit **0.2.0** follows the MathematicsKit family structure with seven
59
+ subpackages and 171 domain models: 162 algebraic equations and nine sampled
60
+ dynamic models. Every model documents its units, input bounds and applicability.
61
+ NumPy and SciPy supply mature numerical foundations.
62
+
63
+ | Subpackage | Models | Focus |
64
+ | --- | ---: | --- |
65
+ | `plate_tectonics` | 23 | Euler rotation, spreading, subduction, isostasy, flexure, convection, hotspots, cooling |
66
+ | `seismology` | 23 | Elastic, surface and head waves, rays, interfaces, magnitudes, pulses, rebound |
67
+ | `atmosphere` | 22 | Hydrostatics, dry thermodynamics, humidity, stratification, rotation, Rossby waves, barotropic vorticity |
68
+ | `climate` | 24 | Radiation, greenhouse layers, insolation, forcing, feedback, ice-albedo hysteresis, red noise, heat storage, carbon and sea level |
69
+ | `oceanography` | 24 | Tides, trochoidal and dispersive waves, density and TEOS-10 cabbeling, dynamic method, Ekman spiral, gyres, two-box overturning, abyssal mixing |
70
+ | `geophysics` | 31 | Gravity anomalies, normal gravity and flattening, satellite J2, Stokes's geoid, dipole and Gauss coefficients, paleomagnetic poles, reversal anomalies, Love numbers, GRACE water, Rikitake dynamo |
71
+ | `volcanology` | 24 | Decay and radiometric ages, radiocarbon, Pb-Pb, concordia and isochron dating, Rayleigh and crystal fractionation, lattice strain, isotope thermometry, magma viscosity and ascent, Mogi inflation, plume and column heights, VEI |
72
+
73
+ ## Install and explore
74
+
75
+ ```bash
76
+ python -m pip install earthsciencekit
77
+ # Or from a checkout:
78
+ python -m pip install -e '.[dev]'
79
+ ```
80
+
81
+ ```python
82
+ import numpy as np
83
+ from earthsciencekit.climate import simulate_one_box
84
+ from earthsciencekit.units import convert
85
+
86
+ time = convert(np.linspace(0, 100, 201), "year", "s")
87
+ result = simulate_one_box(4, 1.2, 2e8, time)
88
+ print(result.summary())
89
+ figure, axes = result.plot()
90
+ animation = result.animate(interval=40)
91
+ ```
92
+
93
+ SI units apply unless an argument explicitly states otherwise. Latitude and
94
+ angles use radians. Algebraic functions accept scalars and broadcast arrays;
95
+ finite real quantities and physical bounds are validated. Unit conversions are
96
+ explicit. Sampled histories copy their arrays, retain labels and support plots
97
+ and animation export.
98
+
99
+ ## Documentation and validation
100
+
101
+ The Sphinx site has Subpackages, History, Examples and API entry points,
102
+ MathematicsKit-style cards/hubs and cross-links. Seven history pages connect
103
+ at least fifteen dated breakthroughs each to the APIs; seven guides explain equations,
104
+ conventions and independent checks. One executed gallery script per breakthrough
105
+ provides figures and Python/notebook downloads.
106
+
107
+ ```bash
108
+ MPLBACKEND=Agg python -m pytest --cov=earthsciencekit --cov-report=term-missing
109
+ python -m ruff check .
110
+ python -m ruff format --check .
111
+ MPLBACKEND=Agg python -m sphinx -E -W --keep-going -b html docs/source docs/_build/html
112
+ python -m build
113
+ ```
114
+
115
+ Coverage enforces 100% of production statements, including validators and
116
+ visualization; test files alone are omitted. This metric does not establish
117
+ physical applicability. Tests include independent analytic solutions,
118
+ conservation balances, limiting cases and invalid-input contracts. Exact release
119
+ results are in VERIFICATION.md; model limits are in docs/source/limitations.rst.
120
+ The documentation is hosted at https://cpoli.github.io/earthsciencekit/, and
121
+ `notebooks/quickstart.ipynb` runs in Colab from the badge above.
122
+
123
+ ## Contribute
124
+
125
+ See CONTRIBUTING.md. Educational models should have explicit equations, units,
126
+ assumptions, independent benchmarks and an executable example. The MIT license
127
+ is in LICENSE. Please cite this software using CITATION.cff.
@@ -0,0 +1,80 @@
1
+ # EarthScienceKit
2
+
3
+ Inspectable Earth-system computations for learning and teaching.
4
+
5
+ [![PyPI](https://img.shields.io/pypi/v/earthsciencekit)](https://pypi.org/project/earthsciencekit/)
6
+ [![CI](https://github.com/cpoli/earthsciencekit/actions/workflows/ci.yml/badge.svg)](https://github.com/cpoli/earthsciencekit/actions/workflows/ci.yml)
7
+ [![Docs](https://img.shields.io/badge/docs-cpoli.github.io-blue)](https://cpoli.github.io/earthsciencekit/)
8
+ [![Open in Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/cpoli/earthsciencekit/blob/main/notebooks/quickstart.ipynb)
9
+ [![JupyterLite](https://jupyterlite.rtfd.io/en/latest/_static/badge.svg)](https://cpoli.github.io/earthsciencekit/lite/lab/)
10
+
11
+ EarthScienceKit **0.2.0** follows the MathematicsKit family structure with seven
12
+ subpackages and 171 domain models: 162 algebraic equations and nine sampled
13
+ dynamic models. Every model documents its units, input bounds and applicability.
14
+ NumPy and SciPy supply mature numerical foundations.
15
+
16
+ | Subpackage | Models | Focus |
17
+ | --- | ---: | --- |
18
+ | `plate_tectonics` | 23 | Euler rotation, spreading, subduction, isostasy, flexure, convection, hotspots, cooling |
19
+ | `seismology` | 23 | Elastic, surface and head waves, rays, interfaces, magnitudes, pulses, rebound |
20
+ | `atmosphere` | 22 | Hydrostatics, dry thermodynamics, humidity, stratification, rotation, Rossby waves, barotropic vorticity |
21
+ | `climate` | 24 | Radiation, greenhouse layers, insolation, forcing, feedback, ice-albedo hysteresis, red noise, heat storage, carbon and sea level |
22
+ | `oceanography` | 24 | Tides, trochoidal and dispersive waves, density and TEOS-10 cabbeling, dynamic method, Ekman spiral, gyres, two-box overturning, abyssal mixing |
23
+ | `geophysics` | 31 | Gravity anomalies, normal gravity and flattening, satellite J2, Stokes's geoid, dipole and Gauss coefficients, paleomagnetic poles, reversal anomalies, Love numbers, GRACE water, Rikitake dynamo |
24
+ | `volcanology` | 24 | Decay and radiometric ages, radiocarbon, Pb-Pb, concordia and isochron dating, Rayleigh and crystal fractionation, lattice strain, isotope thermometry, magma viscosity and ascent, Mogi inflation, plume and column heights, VEI |
25
+
26
+ ## Install and explore
27
+
28
+ ```bash
29
+ python -m pip install earthsciencekit
30
+ # Or from a checkout:
31
+ python -m pip install -e '.[dev]'
32
+ ```
33
+
34
+ ```python
35
+ import numpy as np
36
+ from earthsciencekit.climate import simulate_one_box
37
+ from earthsciencekit.units import convert
38
+
39
+ time = convert(np.linspace(0, 100, 201), "year", "s")
40
+ result = simulate_one_box(4, 1.2, 2e8, time)
41
+ print(result.summary())
42
+ figure, axes = result.plot()
43
+ animation = result.animate(interval=40)
44
+ ```
45
+
46
+ SI units apply unless an argument explicitly states otherwise. Latitude and
47
+ angles use radians. Algebraic functions accept scalars and broadcast arrays;
48
+ finite real quantities and physical bounds are validated. Unit conversions are
49
+ explicit. Sampled histories copy their arrays, retain labels and support plots
50
+ and animation export.
51
+
52
+ ## Documentation and validation
53
+
54
+ The Sphinx site has Subpackages, History, Examples and API entry points,
55
+ MathematicsKit-style cards/hubs and cross-links. Seven history pages connect
56
+ at least fifteen dated breakthroughs each to the APIs; seven guides explain equations,
57
+ conventions and independent checks. One executed gallery script per breakthrough
58
+ provides figures and Python/notebook downloads.
59
+
60
+ ```bash
61
+ MPLBACKEND=Agg python -m pytest --cov=earthsciencekit --cov-report=term-missing
62
+ python -m ruff check .
63
+ python -m ruff format --check .
64
+ MPLBACKEND=Agg python -m sphinx -E -W --keep-going -b html docs/source docs/_build/html
65
+ python -m build
66
+ ```
67
+
68
+ Coverage enforces 100% of production statements, including validators and
69
+ visualization; test files alone are omitted. This metric does not establish
70
+ physical applicability. Tests include independent analytic solutions,
71
+ conservation balances, limiting cases and invalid-input contracts. Exact release
72
+ results are in VERIFICATION.md; model limits are in docs/source/limitations.rst.
73
+ The documentation is hosted at https://cpoli.github.io/earthsciencekit/, and
74
+ `notebooks/quickstart.ipynb` runs in Colab from the badge above.
75
+
76
+ ## Contribute
77
+
78
+ See CONTRIBUTING.md. Educational models should have explicit equations, units,
79
+ assumptions, independent benchmarks and an executable example. The MIT license
80
+ is in LICENSE. Please cite this software using CITATION.cff.
@@ -0,0 +1,6 @@
1
+ """Educational Earth-system computations with explicit units and model limits."""
2
+
3
+ from . import atmosphere, climate, geophysics, oceanography, plate_tectonics, seismology, volcanology
4
+
5
+ __version__ = "0.2.0"
6
+ __all__ = ["plate_tectonics", "seismology", "atmosphere", "climate", "oceanography", "volcanology", "geophysics"]
@@ -0,0 +1,62 @@
1
+ """Central contracts for real, finite, nonempty numerical quantities."""
2
+
3
+ from functools import wraps
4
+
5
+ import numpy as np
6
+
7
+
8
+ def quantity(name, value, *, lower=None, upper=None, strict_lower=False, strict_upper=False):
9
+ """Return a floating NumPy quantity after validating physical bounds."""
10
+ array = np.asarray(value)
11
+ if array.dtype.kind not in "iuf" or not array.size or not np.all(np.isfinite(array)):
12
+ raise ValueError(f"{name} must contain finite real numbers, excluding booleans")
13
+ array = array.astype(float)
14
+ if lower is not None:
15
+ require(array > lower if strict_lower else array >= lower, f"{name} violates its lower bound")
16
+ if upper is not None:
17
+ require(array < upper if strict_upper else array <= upper, f"{name} violates its upper bound")
18
+ return array
19
+
20
+
21
+ def require(condition, message):
22
+ """Reject any violated relation, including array-valued physical constraints."""
23
+ if not np.all(condition):
24
+ raise ValueError(message)
25
+
26
+
27
+ def model(function):
28
+ """Preserve signatures and turn arithmetic singularities into ValueError."""
29
+
30
+ @wraps(function)
31
+ def wrapped(*args, **kwargs):
32
+ try:
33
+ with np.errstate(over="raise", divide="raise", invalid="raise"):
34
+ result = function(*args, **kwargs)
35
+ except FloatingPointError as error:
36
+ raise ValueError(f"{function.__name__}: singular or overflowing arithmetic") from error
37
+ require(np.all(np.isfinite(result)), f"{function.__name__}: nonfinite result")
38
+ return result
39
+
40
+ return wrapped
41
+
42
+
43
+ def time_grid(value):
44
+ """Validate a nonnegative strictly increasing vector of sampled seconds."""
45
+ time = quantity("time", value, lower=0)
46
+ require(time.ndim == 1 and time.size >= 2, "time must be a vector with at least two samples")
47
+ require(np.all(np.diff(time) > 0), "time must strictly increase")
48
+ return time
49
+
50
+
51
+ def safe_arithmetic(function):
52
+ """Translate floating arithmetic failures in structured numerical models."""
53
+
54
+ @wraps(function)
55
+ def wrapped(*args, **kwargs):
56
+ try:
57
+ with np.errstate(over="raise", divide="raise", invalid="raise"):
58
+ return function(*args, **kwargs)
59
+ except FloatingPointError as error:
60
+ raise ValueError(f"{function.__name__}: singular or overflowing arithmetic") from error
61
+
62
+ return wrapped
@@ -0,0 +1,57 @@
1
+ """Inspectable atmosphere models; SI units unless stated otherwise."""
2
+
3
+ from earthsciencekit.atmosphere.systems.dynamics import (
4
+ coriolis_parameter,
5
+ geostrophic_speed,
6
+ rossby_number,
7
+ rossby_wave_speed,
8
+ simulate_barotropic_vorticity,
9
+ )
10
+ from earthsciencekit.atmosphere.systems.hydrostatics import (
11
+ barometer_column_height,
12
+ barometric_pressure,
13
+ dry_air_density,
14
+ scale_height,
15
+ surface_pressure_tendency,
16
+ two_layer_temperature,
17
+ )
18
+ from earthsciencekit.atmosphere.systems.moisture import (
19
+ mixing_ratio,
20
+ relative_humidity,
21
+ saturation_vapor_pressure,
22
+ specific_humidity,
23
+ virtual_temperature,
24
+ )
25
+ from earthsciencekit.atmosphere.systems.thermodynamics import (
26
+ brunt_vaisala_squared,
27
+ dry_adiabatic_lapse_rate,
28
+ potential_temperature,
29
+ richardson_number,
30
+ simulate_dry_ascent,
31
+ temperature_from_potential,
32
+ )
33
+
34
+ __all__ = [
35
+ "dry_air_density",
36
+ "scale_height",
37
+ "barometric_pressure",
38
+ "potential_temperature",
39
+ "temperature_from_potential",
40
+ "dry_adiabatic_lapse_rate",
41
+ "saturation_vapor_pressure",
42
+ "mixing_ratio",
43
+ "specific_humidity",
44
+ "virtual_temperature",
45
+ "relative_humidity",
46
+ "coriolis_parameter",
47
+ "brunt_vaisala_squared",
48
+ "geostrophic_speed",
49
+ "rossby_number",
50
+ "barometer_column_height",
51
+ "two_layer_temperature",
52
+ "richardson_number",
53
+ "surface_pressure_tendency",
54
+ "rossby_wave_speed",
55
+ "simulate_dry_ascent",
56
+ "simulate_barotropic_vorticity",
57
+ ]
@@ -0,0 +1,5 @@
1
+ """Result containers for earthsciencekit.atmosphere."""
2
+
3
+ from earthsciencekit.atmosphere.core.base import TimeSeries
4
+
5
+ __all__ = ["TimeSeries"]
@@ -0,0 +1,10 @@
1
+ """Result containers for earthsciencekit.atmosphere.
2
+
3
+ Algebraic models return NumPy scalars or arrays. The sampled dynamic models
4
+ return the package-wide immutable :class:`~earthsciencekit.results.TimeSeries`,
5
+ which is re-exported here as this domain's result type.
6
+ """
7
+
8
+ from earthsciencekit.results import TimeSeries
9
+
10
+ __all__ = ["TimeSeries"]
@@ -0,0 +1 @@
1
+ """Models of earthsciencekit.atmosphere, grouped by topic."""