It’s been a long time coming, but finally it’s time to announce DynamicGrids.jl - a high performance grid-based modelling framework. It’s been developed at cesar for use in our ecological dispersal modelling, but it should be useful for a whole lot more than that.
DynamicGrids.jl is set up to easily write cellular-automata style rules, but can also simulate a wide range of other behaviors like jumps around the grid and interactions between multiple grids. These can also be composed together into large multi rule/multi grid models that still run really fast. Check out the docs and JuliaCon talk below for more details.
After a bunch of iterations I can also tentatively say it has a nice syntax! - you can specify the math and behaviors you want without much boilerplate. Anyway, check it out:
A live REPL simulation:
(note: the simulation is slowed down for viewing, not sped up! without visuals this model can run at ~1000fps on a regular desktop)
And check out my recent JuliaCon talk for a more thorough description:
PS: I’ve been working pretty hard on this and a bunch of other packages, but I’ve either published and not announced or not even published most of what I’m working on. But I’m in pretty serious COVID lockdown now, so what better time?
I hereby pledge to do a package ANN every week for the next 3 months!
Hello, I was wondering how you created the grids to have the spacial distribution of particular countries (such as Australia or the US)? Is there an easy way to do this for any given geographical region?
I use GeoData.jl to load rasterized data as an array. It will just pass though the simulation, and your outputs should also be plottable spatial GeoArray.
Normally I’m also running simulations with some kind of auxiliary data that is spatial (like environmental rasters or precalculated growth rates), and should match the size and spatial extent of the the initialization grids. The rules are passed the current cell index, so you can use that to index into the aux array.
The get method gets the data for the current index from aux data if rule.rate is e.g. Aux{:auxkey}(), or from another grid if it’s Grid{:gridkey}(). It just uses the value directly otherwise.
You pass in the aux array to the simulation Output constructor, using the aux keyword, along with the init conditions and the time span. If the aux data is an AbstractDimensionalArray (like a GeoArray) it will also synchronize the time dimension with the simulation, if it has one. There has been a lot of improvements in this syntax recently, so may not be the best documented.
GeoData.jl also lets you set initial conditions by Lat/Lon -
Good to put in an issue at DynamicGridsInteract.jl for this. It’s had a few changes (now built on ModelParameters.jl) so there could be an example that is out of date. Include the code you are trying to run with the issue.
But basically you have to wrap your parameters with ModelParameters.Param with a range (a range) or bounds (a tuple) field, and it will be able to find them and make sliders for them wherever they are in the rule object.
Yeah that’s the old method, sorry I didn’t update the docs. The readme links to the InteractModels.jl examples now.
This stuff is all very new and in flux - but you should find ModelParameters.jl is a lot nicer than using FieldMetadata.jl - there is not global state, everything is contained in the Param object.
A quick update, DynamicGrids now runs threaded and on GPUs!
It can run classic rules like stochastic forrest fire at over a billion times a second, and large multi-grid simulations are two orders of magnitude faster on GPU than a single CPU.
Hello, very naively, and at a high level, is this package potentially a good solution if one is interested not in spread that happens locally over a map, with units likely to influence some of their neighbours more than far away units, but instead is interested in more arbitrary, long-distance connectivity (like in a sheet-like neural network of neurons ?)