aboutsummaryrefslogtreecommitdiffziptar.gz
path: root/tests/test_crust.py
diff options
context:
space:
mode:
authorgodosa <godosa@godosa.eu>2026-10-06 23:52:03 +0200
committergodosa <godosa@godosa.eu>2026-10-06 23:52:03 +0200
commit346b1c5195bffc71ceaa9262453e3c189656400b (patch)
tree01ac0d31e2724cd6abcc689a5a228e2cbea2f6cf /tests/test_crust.py
downloadworldgen-346b1c5195bffc71ceaa9262453e3c189656400b.tar.gz
worldgen-346b1c5195bffc71ceaa9262453e3c189656400b.zip
worldgen: initial public history
Diffstat (limited to 'tests/test_crust.py')
-rw-r--r--tests/test_crust.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/tests/test_crust.py b/tests/test_crust.py
new file mode 100644
index 0000000..1bfca60
--- /dev/null
+++ b/tests/test_crust.py
@@ -0,0 +1,114 @@
+import unittest
+
+import numpy as np
+
+from mapgen import crust as CR
+from mapgen.plates import CONV, DIV
+from tests.helpers import make_ctx
+
+TECT = {"plate": [],
+ "lip": [{"name": "l", "center": [10.0, -30.0], "radius_km": 1500.0}],
+ "volcano": [{"name": "v", "center": [-10.0, 20.0], "radius_km": 700.0, "height_m": 7000.0,
+ "scar_azimuths": [90.0]}]}
+
+
+def ctx3():
+ ctx = make_ctx(3, tect=TECT, cfg={"crust": {"edge_noise": 0.0}})
+ g = ctx.grid
+ land = ((np.abs(g.lat) < 35) & (np.abs(g.lon) < 60)).astype(float)
+ bt = np.zeros(g.n, np.int8)
+ bt[np.abs(g.lon - 120) < 1.0] = DIV # a mid-ocean ridge along lon 120
+ bt[np.abs(g.lon - 0) < 1.0] = CONV
+ ctx.data.update({"sk_land": land, "m_land_hint": np.zeros(g.n), "bnd_type": bt})
+ return ctx
+
+
+class CrustTest(unittest.TestCase):
+ def test_classes(self):
+ ctx = ctx3()
+ out = CR.run(ctx)
+ g = ctx.grid
+ age = out["age_class"]
+ self.assertTrue(out["continental"][g.cell_index(20.0, -50.0)])
+ self.assertFalse(out["continental"][g.cell_index(0.0, 150.0)])
+ self.assertEqual(age[g.cell_index(0.0, 150.0)], CR.OCEANIC)
+ self.assertEqual(age[g.cell_index(10.0, -30.0)], CR.LIP)
+ self.assertEqual(age[g.cell_index(-10.0, 20.0)], CR.VOLCANO)
+ self.assertEqual(age[g.cell_index(-10.0, 24.0)], CR.SCAR) # east sector, ~900 km out
+ self.assertEqual(age[g.cell_index(20.0, 3.0)], CR.POST_OROGEN)
+
+ def test_ocean_age_grows_from_ridge(self):
+ ctx = ctx3()
+ out = CR.run(ctx)
+ g = ctx.grid
+ ocean = ~out["continental"] & (np.abs(g.lat) < 20) & (np.abs(g.lon - 120) < 20)
+ r = np.corrcoef(np.abs(g.lon[ocean] - 120), out["ocean_age_myr"][ocean])[0, 1]
+ self.assertGreater(r, 0.95)
+ self.assertTrue(np.all(out["ocean_age_myr"][out["continental"]] == 0))
+
+
+class ShelfTest(unittest.TestCase):
+ def test_continental_shelf_is_resolution_independent(self):
+ from mapgen.graph import distance_to
+ for res in (3, 4):
+ ctx = make_ctx(res, tect={"plate": []}, cfg={"crust": {"edge_noise": 0.0}})
+ g = ctx.grid
+ land = ((np.abs(g.lat) < 30) & (np.abs(g.lon) < 40)).astype(float)
+ ctx.data.update({"sk_land": land, "m_land_hint": np.zeros(g.n), "bnd_type": np.zeros(g.n, np.int8)})
+ cont = CR.run(ctx)["continental"]
+ d = distance_to(g, land > 0.5)
+ self.assertTrue(np.all(cont[land > 0.5]), res)
+ self.assertGreater(cont[(d > 0) & (d < 300)].mean(), 0.8, res) # shelf
+ self.assertEqual(cont[d > 700].sum(), 0, res) # but not far out
+
+
+class FractalMarginTest(unittest.TestCase):
+ @staticmethod
+ def _edge(noise):
+ from mapgen.graph import components
+ ctx = make_ctx(4, tect={"plate": []}, cfg={"crust": {"edge_noise": noise}})
+ g = ctx.grid
+ land = ((np.abs(g.lat) < 30) & (np.abs(g.lon) < 60)).astype(float)
+ ctx.data.update({"sk_land": land, "m_land_hint": np.zeros(g.n), "bnd_type": np.zeros(g.n, np.int8)})
+ cont = CR.run(ctx)["continental"]
+ lab = components(g, cont)
+ sizes = np.bincount(lab[cont])
+ return int(np.sum(cont[g.src] != cont[g.dst])), int(np.sum((sizes > 0) & (sizes < 0.05 * sizes.max())))
+
+ def test_margins_are_fractal_with_fragments(self):
+ smooth, _ = self._edge(0.0)
+ edges, fragments = self._edge(CR.DEFAULTS["edge_noise"])
+ self.assertGreater(edges, 1.4 * smooth)
+ self.assertGreaterEqual(fragments, 3)
+
+
+class RevisionCrustTest(unittest.TestCase):
+ def test_no_patch_no_plateau_keeps_crust(self):
+ out = CR.run(ctx3())
+ np.testing.assert_array_equal(out["continental"], out["continental_base"])
+ self.assertTrue(np.all(out["plateau_id"] == -1))
+
+ def test_land_patch_adds_continental_crust_only_around_its_disc(self):
+ ctx = ctx3()
+ ctx.tect = {**TECT, "land_patch": [{"name": "fill", "center": [0.0, 150.0], "radius_km": 2000.0,
+ "edge_noise": 0.4}]}
+ out = CR.run(ctx)
+ g = ctx.grid
+ i = g.cell_index(0.0, 150.0)
+ self.assertTrue(out["continental"][i])
+ self.assertFalse(out["continental_base"][i])
+ far = CR.center_dist(g, [0.0, 150.0]) > 4500.0
+ np.testing.assert_array_equal(out["continental"][far], out["continental_base"][far])
+ self.assertEqual(out["age_class"][i] == CR.OCEANIC, False)
+
+ def test_plateau_cells_become_continental_crust_with_ids(self):
+ ctx = ctx3()
+ ctx.tect = {**TECT, "plateau": [{"name": "p", "center": [0.0, 150.0], "area_km2": 3.0e6,
+ "top_m": [1500.0, 3000.0]}]}
+ out = CR.run(ctx)
+ i = ctx.grid.cell_index(0.0, 150.0)
+ self.assertEqual(out["plateau_id"][i], 0)
+ self.assertTrue(out["continental"][i])
+ self.assertFalse(out["continental_base"][i])
+ self.assertNotEqual(out["age_class"][i], CR.OCEANIC)
+ self.assertGreater(out["ocean_age_myr"][i], 0.0, "the plateau keeps the age of the sea floor around it")