worldgen

git clone https://git.godosa.eu/worldgen

master

raw · 4416 bytes

import unittest

import numpy as np

from mapgen import fields as FI
from mapgen import ice as IC
from tests.helpers import make_ctx


class IceTest(unittest.TestCase):
    def test_sheet_glacier_sea_ice(self):
        ctx = make_ctx(3)
        g = ctx.grid
        polar_land = g.lat > 70
        z = np.where(polar_land, 500.0, -3000.0)
        peak = g.cell_index(0.0, 0.0)
        z[peak] = 6000.0
        t_mean = np.where(g.lat > 60, -25.0, 15.0)
        t_mean[peak] = -9.0          # too warm for a sheet, summer below zero → glacier
        t_sum = t_mean + 8
        t_win = t_mean - 8
        ctx.data.update({"elevation_eroded_m": z, "T_mean": t_mean, "T_jun": t_sum, "T_dec": t_win,
                         "P_ann": np.full(g.n, 300.0)})
        out = IC.run(ctx)
        self.assertEqual(out["ice"][g.cell_index(85.0, 0.0)], IC.ICE_SHEET)
        self.assertEqual(out["ice"][peak], IC.ICE_GLACIER)
        self.assertEqual(out["ice"][g.cell_index(65.0, 0.0)], IC.ICE_SEA_PERENNIAL)
        self.assertEqual(out["ice"][g.cell_index(0.0, 150.0)], IC.ICE_NONE)
        i = g.cell_index(85.0, 0.0)
        self.assertGreater(out["z_surface_m"][i], z[i] + 200)


class FieldsTest(unittest.TestCase):
    def test_o2_and_gravity(self):
        ctx = make_ctx(1)
        n = ctx.grid.n
        zs = np.zeros(n)
        zs[1] = 8000.0
        m_o2 = np.zeros(n)
        m_o2[2] = 1.0
        m_g = np.zeros(n)
        m_g[3] = -1.0
        ctx.data.update({"z_surface_m": zs, "m_o2_zones": m_o2, "m_gravity_zones": m_g})
        out = FI.run(ctx)
        self.assertAlmostEqual(out["po2_bar"][0], 0.21)
        self.assertAlmostEqual(out["po2_bar"][1], 0.21 * np.exp(-1), places=6)
        self.assertAlmostEqual(out["po2_bar"][2], 0.21 * 1.5)
        self.assertAlmostEqual(out["gravity_g"][0], 1.05)
        self.assertAlmostEqual(out["gravity_g"][3], 1.05 * 0.3)

    def test_pressure_o2_fraction_and_fire(self):
        ctx = make_ctx(1)
        n = ctx.grid.n
        zs = np.zeros(n)
        zs[1] = 8000.0
        m_o2 = np.zeros(n)
        m_o2[2] = 1.0
        ctx.data.update({"z_surface_m": zs, "m_o2_zones": m_o2, "m_gravity_zones": np.zeros(n)})
        out = FI.run(ctx)
        self.assertAlmostEqual(out["pressure_bar"][0], 1.0)
        self.assertAlmostEqual(out["pressure_bar"][1], np.exp(-1))
        self.assertAlmostEqual(out["o2_fraction"][2], 0.21 * 1.5)
        np.testing.assert_allclose(out["po2_bar"], out["o2_fraction"] * out["pressure_bar"])
        self.assertTrue(np.all(out["fire_reactivity"] == 1.0))
        np.testing.assert_allclose(out["plant_height_x"], ctx.cfg["planet"]["gravity_g"] / out["gravity_g"])
        np.testing.assert_allclose(FI.pressure(2.0, np.array([-100.0, 8000.0]), 8000.0), [2.0, 2.0 * np.exp(-1)])

class IceOceanMaskTest(unittest.TestCase):
    def test_cold_inland_basin_is_not_sea_ice(self):
        ctx = make_ctx(3)
        g = ctx.grid
        land = g.lat > 50
        z = np.where(land, 300.0, -3000.0)
        basin = (g.lat > 60) & (g.lat < 68) & (np.abs(g.lon) < 20)
        z[basin] = -20.0
        t = np.where(g.lat > 50, -5.0, 10.0)
        ctx.data.update({"elevation_eroded_m": z, "ocean": ~land, "T_mean": t, "T_jun": t + 8, "T_dec": t - 8,
                         "P_ann": np.full(g.n, 300.0)})
        out = IC.run(ctx)
        self.assertFalse(np.isin(out["ice"][basin], [IC.ICE_SEA_SEASONAL, IC.ICE_SEA_PERENNIAL]).any())


class SummerMeltRuleTest(unittest.TestCase):
    def test_ice_sheets_need_summers_below_freezing(self):
        ctx = make_ctx(3)
        g = ctx.grid
        land = g.lat > 55
        z = np.where(land, 300.0, -3000.0)
        t_mean = np.where(g.lat > 75, -25.0, -12.0)           # 55–75°: cold on average, but summers melt
        t_sum = np.where(g.lat > 75, -8.0, 4.0)
        peak = g.cell_index(0.0, 0.0)
        z[peak], t_mean[peak], t_sum[peak] = 6000.0, -9.0, -1.0
        ctx.data.update({"elevation_eroded_m": z, "ocean": ~(land | (np.arange(g.n) == peak)), "T_mean": t_mean,
                         "T_jun": t_sum, "T_dec": t_mean - 10, "P_ann": np.full(g.n, 300.0)})
        out = IC.run(ctx)
        self.assertEqual(out["ice"][g.cell_index(65.0, 0.0)], IC.ICE_NONE)        # tundra, not ice
        self.assertEqual(out["ice"][g.cell_index(85.0, 0.0)], IC.ICE_SHEET)
        self.assertEqual(out["ice"][peak], IC.ICE_GLACIER)                          # small cold spot = glacier