
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.

// version 1.2.10
 
import java.util.Random
 
val rand = Random()
const val RAND_MAX = 32767
const val NUL = '\u0000'
 
val x = 15
val y = 15
var grid = StringBuilder((x + 1) * (y + 1) + 1)
var cell = 0
var end = 0
var m = 0
var n = 0
 
fun makeGrid(p: Double) {
    val thresh = (p * RAND_MAX).toInt()
    m = x
    n = y
    grid.setLength(0)  // clears grid
    grid.setLength(m + 1)  // sets first (m + 1) chars to NUL
    end = m + 1
    cell = m + 1
    for (i in 0 until n) {
        for (j in 0 until m) {
            val r = rand.nextInt(RAND_MAX + 1)
            grid.append(if (r < thresh) '+' else '.')
            end++
        }
        grid.append('\n')
        end++
    }
    grid[end - 1] = NUL
    end -= ++m  // end is the index of the first cell of bottom row  
}
 
fun ff(p: Int): Boolean { // flood fill
    if (grid[p] != '+') return false
    grid[p] = '#'
    return p >= end || ff(p + m) || ff(p + 1) || ff(p - 1) || ff(p - m)
}
 
fun percolate(): Boolean {
    var i = 0
    while (i < m && !ff(cell + i)) i++
    return i < m
}
 
fun main(args: Array<String>) {
    makeGrid(0.5)
    percolate()
 
    println("$x x $y grid:")
    println(grid)
 
    println("\nrunning 10,000 tests for each case:")
    for (ip in 0..10) {
        val p = ip / 10.0
        var cnt = 0
        for (i in 0 until 10_000) {
            makeGrid(p)
            if (percolate()) cnt++
        }
        println("p = %.1f:  %.4f".format(p, cnt / 10000.0))
    }
}