# ANN: DynamicGrids.jl

**URL:** <https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396>\
**Category:** Package Announcements\
**Created:** [August 6, 2020, 8:11am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396 "2020-08-06T08:11:36Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 6, 2020, 8:11am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/1 "2020-08-06T08:11:36Z")

</div>

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](https://github.com/cesaraustralia) 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:

> **[GitHub - cesaraustralia/DynamicGrids.jl: Grid-based simulations in Julia](https://github.com/cesaraustralia/DynamicGrids.jl)**
>
> Grid-based simulations in Julia. Contribute to cesaraustralia/DynamicGrids.jl development by creating an account on GitHub.

A live REPL simulation:

[![](https://global.discourse-cdn.com/julialang/original/3X/9/4/94927f472d4353b89e4b5c691bc9595a42ffef3c.jpeg "DynamicGrids.jl REPL output simulation") ](https://www.youtube.com/watch?v=k1iXwgowj2U)

(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:

[![](https://global.discourse-cdn.com/julialang/original/3X/8/8/88ea2d6c84d90286bfd73f6ed22558ca6c9fb066.jpeg "JuliaCon 2020 | DynamicGrids.jl: high-performance spatial simulations in Julia | Rafael Schouten") ](https://www.youtube.com/watch?v=MDvhIASXb6k)

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!**

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [August 6, 2020, 10:07am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/2 "2020-08-06T10:07:12Z")

</div>

Being too damn lazy to write it myself, I guess there is an easy implementation of the Game of Life here?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [August 6, 2020, 10:22am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/3 "2020-08-06T10:22:12Z")

</div>

Yep: `Life()`.

This is the code to run it in the repl:

```julia
using DynamicGrids, Crayons
init = rand(Bool, 150, 200)
output = REPLOutput(init; tspan=1:200, fps=30, color=Crayon(foreground=:red, background=:black, bold=true))
sim!(output, Life())

```

You can pass in args to `Life()` if you want other game of life behaviors besides the common 3, (2,3) rule.

But this is a complete script to implement GOL from scratch and run it:

```julia
const life_sum_states = 
   (false, false, false, true, false, false, false, false, false), 
   (false, false, true, true, false, false, false, false, false)
life = Neighbors(Moore(1)) do hood, state
    life_sum_states[state + 1][sum(hood) + 1]
end
output = REPLOutput(rand(Bool, 150, 200); tspan=1:200)
sim!(output, life)

```

So its ok to be lazy

---

<div class="post-metadata">

**Author:** ![johnh](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnh/32/3615_2.png) [@johnh](https://discourse.julialang.org/u/johnh)\
**Post date:** [August 6, 2020, 11:05am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/4 "2020-08-06T11:05:41Z")

</div>

> [@Raf](#):
>
> `sim!(output, life)`

Cool! Works great, thankyou.

---

<div class="post-metadata">

**Author:** ![ianxul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianxul/32/20955_2.png) [@ianxul](https://discourse.julialang.org/u/ianxul)\
**Post date:** [January 13, 2021, 5:22am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/5 "2021-01-13T05:22:25Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [January 13, 2021, 6:30am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/6 "2021-01-13T06:30:54Z")

</div>

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.

In Dispersal.jl (rules you see above in simulations) we use DynamicGrids capability to do this in a generic way. In this growth rule `carrycap` and `rate` can be from aux data:  
[https://github.com/cesaraustralia/Dispersal.jl/blob/master/src/growth.jl#L68-L69](https://github.com/cesaraustralia/Dispersal.jl/blob/master/src/growth.jl#L68-L69)

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 -

```julia
init[Lon(Near(144)), Lat(Near(-37)] = 1000.0

```

Or something similar.

---

<div class="post-metadata">

**Author:** ![ianxul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianxul/32/20955_2.png) [@ianxul](https://discourse.julialang.org/u/ianxul)\
**Post date:** [January 13, 2021, 6:09pm UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/7 "2021-01-13T18:09:16Z")

</div>

Thanks! I’ll try this out.

---

<div class="post-metadata">

**Author:** ![ianxul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianxul/32/20955_2.png) [@ianxul](https://discourse.julialang.org/u/ianxul)\
**Post date:** [February 9, 2021, 12:10am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/8 "2021-02-09T00:10:15Z")

</div>

Hello, I have a question on how to use the Interactive outputs. I’ve tried doing it like it says on the github readme, but I get the following error:

Params must include a `range` or `bounds` field to generate interactive sliders…

Is there maybe an example I can follow on how to use this package? It seems really cool.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 9, 2021, 1:51am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/9 "2021-02-09T01:51:19Z")

</div>

Good to put in an issue at DynamicGridsInteract.jl for this. It’s had a few changes (now built on [ModelParameters.jl](https://github.com/rafaqz/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.

---

<div class="post-metadata">

**Author:** ![ianxul](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianxul/32/20955_2.png) [@ianxul](https://discourse.julialang.org/u/ianxul)\
**Post date:** [February 9, 2021, 2:02am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/10 "2021-02-09T02:02:30Z")

</div>

Hello! Thanks for replying so quickly. This is a piece of the code I was using (where the error occurs):

```julia
using DynamicGrids,DynamicGridsInteract
import FieldMetadata: limits, @limits, logscaled, @logscaled

const S1,S2,I = 0,1,2

init = fill(S1, 100, 100)

@logscaled @limits struct infectrule{N,PA,PB,PG,PM} <: NeighborhoodRule
    neighborhood::N | _ | _
    p_alpha::PA | (0.0,1.0) | true
    p_beta::PB | (0.0,1.0) | true
    p_gamma::PG | (0.0,1.0) | true
    p_mm::PM | (0.0,1.0) | true
end

```

I tried to make an easy example to begin with by copying the code you show in a video example of the interactive grids…

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 9, 2021, 4:49am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/11 "2021-02-09T04:49:14Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [May 7, 2021, 8:31am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/12 "2021-05-07T08:31:56Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![suresh](https://avatars.discourse-cdn.com/v4/letter/s/aca169/32.png) [@suresh](https://discourse.julialang.org/u/suresh)\
**Post date:** [March 31, 2024, 7:49pm UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/13 "2024-03-31T19:49:07Z")

</div>

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 ?)

Thanks !

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [April 2, 2024, 11:00am UTC](https://discourse.julialang.org/t/ann-dynamicgrids-jl/44396/14 "2024-04-02T11:00:30Z")

</div>

Maybe? This insect dispersal simulation has long distance transport mapped to a connectivity graph or sorts using a GDP based gravity model:

![](https://global.discourse-cdn.com/julialang/original/3X/b/8/b89769d6ab71a6b0ab6c578a59a2ad8315368419.gif)  
But it also has local neighborhood dynamics.

If the long distance jumps are _all_ you are doing then it might not make as much sense, and you could instead just use a graph without the grid?

Is you data organised in a regular grid to start with?
