import unittest
import numpy as np
from mapgen import plates as PL
from mapgen.pipeline import StageError
from tests.helpers import make_ctx
def two_plates(az_a, az_b, speed=5.0, kinds=("oceanic", "oceanic")):
return {"plate": [
{"id": "a", "seed": [0.0, -40.0], "kind": kinds[0], "motion": [az_a, speed]},
{"id": "b", "seed": [0.0, 40.0], "kind": kinds[1], "motion": [az_b, speed]},
]}
def ctx_for(tect, land=None, res=2):
ctx = make_ctx(res, tect=tect)
n = ctx.grid.n
ctx.data.update({"sk_land": np.zeros(n) if land is None else land, "m_land_hint": np.zeros(n)})
return ctx
class PlatesTest(unittest.TestCase):
def test_convergent_then_divergent(self):
for az_a, az_b, want in ((90.0, 270.0, PL.CONV), (270.0, 90.0, PL.DIV)):
ctx = ctx_for(two_plates(az_a, az_b))
out = PL.run(ctx)
g = ctx.grid
near = (np.abs(g.lon) < 12) & (np.abs(g.lat) < 30) & (out["bnd_type"] > 0)
self.assertGreater(near.sum(), 3)
self.assertTrue(np.mean(out["bnd_type"][near] == want) > 0.8, (az_a, want))
def test_every_cell_assigned_and_seeds_own_cells(self):
ctx = ctx_for(two_plates(90.0, 270.0))
out = PL.run(ctx)
g = ctx.grid
self.assertEqual(set(np.unique(out["plate"])), {0, 1})
self.assertEqual(out["plate"][g.cell_index(0.0, -40.0)], 0)
self.assertEqual(out["plate"][g.cell_index(0.0, 40.0)], 1)
def test_continent_stays_on_its_plate(self):
tect = {"plate": [
{"id": "c", "seed": [0.0, 0.0], "kind": "continental", "motion": [0.0, 1.0]},
{"id": "o", "seed": [0.0, 60.0], "kind": "oceanic", "motion": [0.0, 1.0]},
]}
ctx = make_ctx(2, tect=tect)
g = ctx.grid
land = ((np.abs(g.lat) < 20) & (np.abs(g.lon) < 40)).astype(float)
ctx.data.update({"sk_land": land, "m_land_hint": np.zeros(g.n)})
out = PL.run(ctx)
self.assertTrue(np.all(out["plate"][land > 0.5] == 0))
def test_duplicate_seed_cell_errors(self):
tect = two_plates(90.0, 270.0)
tect["plate"][1]["seed"] = [0.01, -40.01]
with self.assertRaisesRegex(StageError, "same cell"):
PL.run(ctx_for(tect))
def test_zero_speed_plate(self):
out = PL.run(ctx_for(two_plates(90.0, 270.0, speed=0.0)))
self.assertTrue(np.all(np.isfinite(out["vel"])))
self.assertTrue(np.allclose(out["vel"], 0.0))
class MeanderTest(unittest.TestCase):
def test_boundaries_meander(self):
ctx = ctx_for(two_plates(90.0, 270.0, kinds=("continental", "continental")), res=4)
g = ctx.grid
ctx.data["sk_land"] = ((np.abs(g.lat) < 40) & (np.abs(g.lon) < 70)).astype(float)
out = PL.run(ctx)
b = (out["bnd_type"] > 0) & (np.abs(g.lat) < 35) & (np.abs(g.lon) < 40)
self.assertGreater(g.lon[b].std(), 3.0)