def __init__(self, r, gridsize, spin, cells, tilt, landr, dt, atmdt, lifedt): """Create a simulation for a planet with the given characteristics. """ self._timing = Timing() initt = self._timing.routine('simulation setup') self.spin, self.cells, self.tilt = spin, cells, tilt # max speed is 100km per million years self._dp = 100.0/r * dt self._build = dt/5.0 self._erode = dt tilearea = 4 * pi * r**2 initt.start('building grid') self._initgrid(gridsize) self.tiles = {} for v in self._grid.faces: x, y, z = v lat = 180/pi * atan2(z, sqrt(x*x + y*y)) lon = 180/pi * atan2(y, x) self.tiles[v] = Tile(lat, lon) initt.start('building indexes') self.initindexes() initt.start('creating initial landmass') tilearea /= len(self._indexedtiles) # the numerator of the split probability, where # the number of tiles in the shape is the denomenator: # a 50M km^2 continent has a 50/50 chance of splitting in a given step self._splitnum = 25e6/tilearea # initial location p = [random.uniform(-1, 1) for i in range(3)] p /= norm(p) # 0 velocity vector v = (0, 0, 0) # orienting point o = [0, 0, 0] mini = min(range(len(p)), key=lambda i: abs(p[i])) o[mini] = 1 if p[mini] < 0 else -1 shape = SphericalPolygon([rotate(rotate(p, o, landr*random.uniform(0.9,1.1)), p, th) for th in [i*pi/8 for i in range(16)]]) self._shapes = [Group([t for t in self.tiles.values() if shape.contains(t.vector)], v)] # initial landmass starts at elevation based on distance from center c = self._indexedtiles[self._index.nearest(p)[0]] r2 = landr*landr # on land, one random tile is the center of a felsic chunk f = random.choice(self._shapes[0].tiles) for t in self._indexedtiles: if t in self._shapes[0].tiles: dc = t.distance(c) df = t.distance(f) r = igneous.extrusive(max(0.5, 1 - df*df/r2)) h = 1 - dc*dc/r2 t.emptyland(r, h) else: t.emptyocean(self.seafloor()) for t in self.tiles.values(): t.climate = t.seasons = None initt.done() self._atmosphereticks = atmdt / dt self._lifeticks = lifedt / dt self._climatemappings = {} self._climateprof = None self.dirty = True
def seafloor(): return igneous.extrusive(0.5)
def __init__(self, r, dt): """Create a simulation for a planet of radius r km and timesteps of dt million years. """ self._timing = Timing() initt = self._timing.routine('simulation setup') # max speed is 100km per million years self._dp = 100.0/r * dt self._build = dt/5.0 self._erode = dt tilearea = 4 * pi * r**2 initt.start('building grid') grid = Grid() while grid.size < 6: grid = Grid(grid) grid.populate() self._grid = grid self.tiles = {} for v in self._grid.faces: x, y, z = v lat = 180/pi * atan2(y, sqrt(x*x + z*z)) lon = 180/pi * atan2(-x, z) self.tiles[v] = Tile(lat, lon) initt.start('building indexes') self.initindexes() initt.start('creating initial landmass') tilearea /= len(self._indexedtiles) # the numerator of the split probability, where # the number of tiles in the shape is the denomenator: # a 50M km^2 continent has a 50/50 chance of splitting in a given step self._splitnum = 25e6/tilearea # initial location p = (0, 1, 0) # 0 velocity vector v = (0, 0, 0) # orienting point o = (1, 0, 0) r = 1.145 shape = [(r*random.uniform(0.9,1.1)*cos(th), r*random.uniform(0.9,1.1)*sin(th)) for th in [i*pi/8 for i in range(16)]] shape = Shape(shape, p, o, v).projection() self._shapes = [Group([t for t in self.tiles.itervalues() if shape.contains(t.vector)], v)] # initial landmass starts at elevation based on distance from center c = self._indexedtiles[self._index.nearest(p)[0]] r2 = r*r # on land, one random tile is the center of a felsic chunk f = random.choice(self._shapes[0].tiles) for t in self._indexedtiles: if t in self._shapes[0].tiles: dc = t.distance(c) df = t.distance(f) r = igneous.extrusive(max(0.5, 1 - df*df/r2)) h = 1 - dc*dc/r2 t.emptyland(r, h) else: t.emptyocean(self.seafloor()) for t in self.tiles.itervalues(): t.climate = None initt.done() self._atmosphere = self._life = False self._climatemappings = {} self._climateprof = None self.dirty = True