worldhistory

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

master

raw · 2876 bytes

import functools

import numpy as np

from worldhistory.world import World, neighbours_from_ids

DEFAULTS = dict(ocean=False, elevation_m=100.0, T_mean=15.0, P_ann=1000.0, holdridge=20, landform=1, river=False,
                strahler=0, lake=False, ice=0, coal_potential=False, iron_potential=False, vent_potential=0.0,
                seabed_type=0, lithology=1, ground=0, gravity_g=1.0, o2_fraction=0.21, pressure_bar=1.0,
                bottom_temp_c=2.0, plate=0)


def fields(n, **over):
    out = {}
    for k, v in {**DEFAULTS, **over}.items():
        a = np.asarray(v)
        out[k] = np.broadcast_to(a, (n,)).copy() if a.ndim == 0 else a.copy()
    return out


def line_world(n, spacing_km=100.0, radius_km=6371.0, **over):
    """Cells on the equator in a row, each linked to the next: 1-D worlds with hand-checkable answers."""
    lon = np.arange(n) * np.degrees(spacing_km / radius_km)
    lat = np.zeros(n)
    xyz = np.stack([np.cos(np.radians(lon)), np.sin(np.radians(lon)), np.zeros(n)], 1)
    nb = np.full((n, 6), -1, np.int64)
    nb[1:, 0] = np.arange(n - 1)
    nb[:-1, 1] = np.arange(1, n)
    return World(nb=nb, lat=lat, lon=lon, xyz=xyz, area=np.full(n, spacing_km ** 2), radius_km=radius_km,
                 base=fields(n, **over))


@functools.lru_cache(maxsize=4)
def _h3_grid(res):
    import h3.api.basic_int as h3
    ids = sorted(c for r0 in h3.get_res0_cells() for c in h3.cell_to_children(r0, res))
    ll = np.array([h3.cell_to_latlng(c) for c in ids])
    area = np.array([h3.cell_area(c, unit="rads^2") for c in ids])
    return np.array(ids, np.uint64), ll, area


def globe_world(res=1, radius_km=6371.0):
    """A whole H3 globe (res 1 = 842 cells) with default fields; tests edit world.base afterwards."""
    ids, ll, area = _h3_grid(res)
    lat, lon = ll[:, 0].copy(), ll[:, 1].copy()
    la, lo = np.radians(lat), np.radians(lon)
    xyz = np.stack([np.cos(la) * np.cos(lo), np.cos(la) * np.sin(lo), np.sin(la)], 1)
    return World(nb=neighbours_from_ids(ids), lat=lat, lon=lon, xyz=xyz, area=area * radius_km ** 2,
                 radius_km=radius_km, base=fields(len(ids)))


from worldhistory.config import parse_history, parse_race


def make_race(id="a", **over):
    """A land race with density 1/km² at q=1, growth 0.1/step, no Allee, founder 1, no mobility; sections override."""
    d = {"id": id,
         "demography": {"density": 1.0, "growth": 0.1, "allee": 0.0, "founder": 1.0, "mobility": 0.0},
         "habitat": {"realm": "land", "terms": [{"p": "land", "w": 1.0}]}}
    for k, v in over.items():
        d[k] = {**d.get(k, {}), **v} if isinstance(v, dict) and isinstance(d.get(k), dict) else v
    return parse_race(d, f"test:{id}")


def make_history(**over):
    d = {"run": {"years": 100, "step": 10, "snapshot_every": 50, "seed": 1}}
    d.update(over)
    return parse_history(d, "test:history")