
Percolation Simulation

This is a simulation of aspects of mathematical percolation theory.

For other percolation simulations, see Category:Percolation Simulations, or:
1D finite grid simulation
Mean run density 
2D finite grid simulations
Site percolation | Bond percolation | Mean cluster density

Given an 



M
×
N


{\displaystyle M\times N}

 rectangular array of cells numbered 




c
e
l
l

[
0..
M
−
1
,
0..
N
−
1
]


{\displaystyle \mathrm {cell} [0..M-1,0..N-1]}

assume 



M


{\displaystyle M}

 is horizontal and 



N


{\displaystyle N}

 is downwards.

Assume that the probability of any cell being filled is a constant 



p


{\displaystyle p}

 where

 



0.0
≤
p
≤
1.0


{\displaystyle 0.0\leq p\leq 1.0}


The task

Simulate creating the array of cells with probability 



p


{\displaystyle p}

 and then
testing if there is a route through adjacent filled cells from any on row 



0


{\displaystyle 0}

 to any on row 



N


{\displaystyle N}

, i.e. testing for site percolation.

Given 



p


{\displaystyle p}

 repeat the percolation 



t


{\displaystyle t}

 times to estimate the proportion of times that the fluid can percolate to the bottom for any given 



p


{\displaystyle p}

.

Show how the probability of percolating through the random grid changes with 



p


{\displaystyle p}

 going from 



0.0


{\displaystyle 0.0}

 to 



1.0


{\displaystyle 1.0}

 in 



0.1


{\displaystyle 0.1}

 increments and with the number of repetitions to estimate the fraction at any given 



p


{\displaystyle p}

 as 



t
>=
100


{\displaystyle t>=100}

.

Use an 



M
=
15
,
N
=
15


{\displaystyle M=15,N=15}

 grid of cells for all cases.

Optionally depict a percolation through a cell grid graphically.

Show all output on this page.

import "random" for Random
import "/fmt" for Fmt
 
var rand = Random.new()
var RAND_MAX = 32767
var EMPTY = ""
 
var x = 15
var y = 15
var grid = List.filled((x + 1) * (y + 1) + 1, EMPTY)
var cell = 0
var end = 0
var m = 0
var n = 0
 
var makeGrid = Fn.new { |p|
    var thresh = (p * RAND_MAX).truncate
    m = x
    n = y
    grid.clear()
    grid = List.filled(m + 1, EMPTY)
    end = m + 1
    cell = m + 1
    for (i in 0...n) {
        for (j in 0...m) {
            var r = rand.int(RAND_MAX+1)
            grid.add((r < thresh) ? "+" : ".")
            end = end + 1
        }
        grid.add("\n")
        end = end + 1
    }
    grid[end-1] = EMPTY
    m = m + 1
    end = end - m  // end is the index of the first cell of bottom row
}
 
var ff // recursive
ff = Fn.new { |p|  // flood fill
   if (grid[p] != "+") return false
   grid[p] = "#"
   return p >= end || ff.call(p + m) || ff.call(p + 1) || ff.call(p - 1) ||
        ff.call(p - m)
}
 
var percolate = Fn.new {
    var i = 0
    while (i < m && !ff.call(cell + i)) i = i + 1
    return i < m
}
 
makeGrid.call(0.5)
percolate.call()
System.print("%(x) x %(y) grid:")
System.print(grid.join(""))
System.print("\nRunning 10,000 tests for each case:")
for (ip in 0..10) {
    var p = ip / 10
    var cnt = 0
    for (i in 0...10000) {
        makeGrid.call(p)
        if (percolate.call()) cnt = cnt + 1
    }
    Fmt.print("p = $.1f:  $.4f", p, cnt / 10000)
}