Initialize a matrix a
with value of $\alpha$ in central cell as "ice", and $\beta$ in every other cell.
L = 599; alpha = 0.501; beta = 0.3; gamma = 0.0001;
a = ConstantArray[beta, {L, L}];
a[[Ceiling[L/2], Ceiling[L/2]]] = alpha;
Store all ice cell in a1
, and store all water cell in a2
.
a1 = ParallelMap[If[# >= alpha, # , 0] &, a, {2}];
a2 = ParallelMap[If[# < alpha, #, 0] &, a, {2}];
Now scan all the cells in a
, copy all the ice cells and their neighbors into a1
, put zeros in a2
in these positions. Then add $\gamma$(growth rate) to non-zero cell in a1
.
Do[If[Total[Boole[{a[[i, j]] >= alpha, a[[i, j + 1]] >= alpha,
a[[i, j - 1]] >= alpha, a[[i + 1, j]] >= alpha,
a[[i + 1, j + 1]] >= alpha, a[[i + 1, j - 1]] >= alpha,
a[[i - 1, j]] >= alpha, a[[i - 1, j + 1]] >= alpha,
a[[i - 1, j - 1]] >= alpha}]] >= 1,
a1[[i, j]] = a[[i, j]] + gamma; a2[[i, j]] = 0;,
a2[[i, j]] = a[[i, j]]; a1[[i, j]] = 0;], {i, 2, L - 1}, {j, 2, L - 1}];
And I got(For L=9
)
a1 // MatrixForm
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0.3001 0.3001 0.3001 0 0 0
0 0 0 0.3001 0.5011 0.3001 0 0 0
0 0 0 0.3001 0.3001 0.3001 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
a2 // MatrixForm
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0 0 0 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3 0.3
The result is correct, but it's very slow when L
is large.I tried to use ParallelDo
instead of Do
, but there is side effect.
I was wondering if it's possible to parallelize the above code?
Boole[{a[[i, j]] >= alpha, a[[i, j + 1]] >= alpha, a[[i, j - 1]] >= alpha, a[[i + 1, j]] >= alpha, a[[i + 1, j + 1]] >= alpha, a[[i + 1, j - 1]] >= alpha, a[[i - 1, j]] >= alpha, a[[i - 1, j + 1]] >= alpha, a[[i - 1, j - 1]] >= alpha}] >= 0
won't work as you wished. (If you still don't understand what's wrong, tryBoole[{True, False}] >= 0
.) Also, I don't think the rest part of the code insideDo
is the correct interpretation of your description. $\endgroup$Total
beforeBoole
, the rest part of the code insideDo
is simply separatinga
intoa1
anda2
, wherea1
contains all ice and it's neighbor, anda2
contains all the other cells. $\endgroup$