logo

Diffusion in Lattice Model Simulations 📂Dynamics

Diffusion in Lattice Model Simulations

Simulation

SI\_diffusion.gif

In this post, we aim to mimic the diffusion of an ingredient in a lattice space. This simultaneously serves as a simulation of the SI disease spreading model and can also be considered an SIR model due to the limited space.

Variables

  • $t$: Represents the current turn.
  • $I(t) \in \mathbb{N}$: The amount of the ingredient being diffused at turn $t$.
  • $S(t) \in \mathbb{N}$: The amount of empty space at turn $t$.

Parameters

  • $\beta \in [0,1]$: The diffusion rate, indicating how the ingredient diffuses.

Actions

(For each cell, on every turn)

  • Calculation: Count how many times an ingredient is present in the neighboring cells (up, down, left, right). Let’s call the calculated number at row $i$ and column $j$ as $n_{ij}$.
  • Diffusion: Each cell gains the ingredient with a probability of $1-(1-\beta)^{n_{ij}}$.

Code Review

Step 1. Initialization and lattice space creation

julia> row\_size = 10
10

julia> column\_size = 10
10

julia> β = 0.5 # 확산률
0.5

julia> Random.seed!(0);

julia> stage\_lattice = rand(['S'], row\_size, column\_size)
10×10 Array{Char,2}:
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'

julia> stage\_lattice[rand(1:row\_size), rand(1:column\_size)] = 'I'; stage\_lattice
10×10 Array{Char,2}:
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'I'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'
 'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'  'S'

Similar to the lattice-based simulation tutorial, we create a lattice space and place ingredients at random positions. In the above case, they are created at row $6$ and column $6$. This can be visualized using a heatmap as follows:

06-01.png

Step 2. Calculation

julia> I\_lattice = (stage\_lattice .== 'I')
10×10 BitArray{2}:
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  1  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0

julia> count\_lattice =
         vcat(I\_lattice[2:end, :], zeros(Int64, 1, column\_size)) +
         vcat(zeros(Int64, 1, column\_size), I\_lattice[1:end-1, :]) +
         hcat(I\_lattice[:, 2:end], zeros(Int64, row\_size, 1)) +
         hcat(zeros(Int64, column\_size, 1), I\_lattice[:, 1:end-1])
10×10 Array{Int64,2}:
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  1  0  0  0  0
 0  0  0  0  1  0  1  0  0  0
 0  0  0  0  0  1  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0

Create a matrix $(n_{ij})$ that counts how many ingredients are around. In the example, vector operations were used to calculate it, but it’s not necessary to always compute it this way.

Step 3. Diffusion

julia> probability\_lattice = 1 .- (1-β).^count\_lattice
10×10 Array{Float64,2}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.5  0.0  0.5  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 
julia> hit\_lattice = probability\_lattice .> rand(row\_size, column\_size)
10×10 BitArray{2}:
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  1  0  0  0  0
 0  0  0  0  1  0  1  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0

Calculate the probability of diffusion for each cell and create matrix $\left( 1-(1-\beta)^{n_{ij}} \right)$. This calculation is done because the more ingredients are around, the higher the diffusion rate. The probability of an empty space receiving an ingredient is $\beta$, and not receiving is $(1-\beta)$. The probability of an empty space at row $i$ and column $j$ not getting diffused from the surrounding $n_{ij}$ ingredients is $(1-\beta)^{n_{ij}}$, and the probability of getting at least one diffusion is exactly $\left( 1-(1-\beta)^{n_{ij}} \right)$.

julia> probability\_lattice = 1 .- (1-β).^count\_lattice
10×10 Array{Float64,2}:
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.5  0.0  0.5  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.5  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
 0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0

julia> hit\_lattice = probability\_lattice .> rand(row\_size, column\_size)
10×10 BitArray{2}:
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  1  0  0  0  0
 0  0  0  0  1  0  1  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0
 0  0  0  0  0  0  0  0  0  0

Now, we generate a matrix of the same size from the uniform distribution $U(0,1)$ to decide whether diffusion occurred or not. In the case above, we can see the ingredient spreading up, left, and right. When visualized as a heatmap, it looks as follows:

06-02.png

Repeating this process yields a gif like the one at the beginning and top of this post.