Last active
July 9, 2017 14:02
-
-
Save zeffii/9e156f0d37977fd1b0ca3c65d0ddc611 to your computer and use it in GitHub Desktop.
reaction diffusion script node sverchok - slow
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import random | |
import numpy as np | |
class DiffReact2(): | |
verts = [] | |
params = [] | |
params.append((0.16, 0.08, 0.035, 0.065)) # Bacteria 1 | |
params.append((0.14, 0.06, 0.035, 0.065)) # Bacteria 2 | |
params.append((0.16, 0.08, 0.060, 0.062)) # Coral | |
params.append((0.19, 0.05, 0.060, 0.062)) # Fingerprint | |
params.append((0.10, 0.10, 0.018, 0.050)) # Spirals | |
params.append((0.12, 0.08, 0.020, 0.050)) # Spirals Dense | |
params.append((0.10, 0.16, 0.020, 0.050)) # Spirals Fast | |
params.append((0.16, 0.08, 0.020, 0.055)) # Unstable | |
params.append((0.16, 0.08, 0.050, 0.065)) # Worms 1 | |
params.append((0.16, 0.08, 0.054, 0.063)) # Worms 2 | |
params.append((0.16, 0.08, 0.035, 0.060)) # Zebrafish | |
def __init__(self, np, random): | |
n = 256 | |
imgx = n; imgy = n # image size | |
steps = 5000 | |
(Du, Dv, F, k) = random.choice(self.params) | |
Z = np.zeros((n+2,n+2), [('U', np.double), ('V', np.double)]) | |
U,V = Z['U'], Z['V'] | |
u,v = U[1:-1,1:-1], V[1:-1,1:-1] | |
r = 20 | |
u[...] = 1.0 | |
U[n/2-r:n/2+r,n/2-r:n/2+r] = 0.50 | |
V[n/2-r:n/2+r,n/2-r:n/2+r] = 0.25 | |
u += 0.05*np.random.random((n,n)) | |
v += 0.05*np.random.random((n,n)) | |
######### loop start ############ | |
p = 0 | |
for i in range(steps): | |
Lu = ( U[0:-2,1:-1] + | |
U[1:-1,0:-2] - 4*U[1:-1,1:-1] + U[1:-1,2:] + | |
U[2: ,1:-1] ) | |
Lv = ( V[0:-2,1:-1] + | |
V[1:-1,0:-2] - 4*V[1:-1,1:-1] + V[1:-1,2:] + | |
V[2: ,1:-1] ) | |
uvv = u*v*v | |
u += (Du*Lu - uvv + F *(1-u)) | |
v += (Dv*Lv + uvv - (F+k)*v ) | |
pn = 100 * (i + 1) / steps # percent completed | |
if pn != p: | |
p = pn | |
print("%" + str(p).zfill(2)) | |
######### loop end ############ | |
add_vert = self.verts.append | |
vMin=V.min(); vMax=V.max() | |
for iy in range(imgy): | |
for ix in range(imgx): | |
w = V[iy, ix] | |
c = int(255 * (w - vMin) / (vMax - vMin)) | |
if c > 190: | |
add_vert((ix/40, iy/40, 0)) | |
label = "Du=" + str(Du) + " Dv=" + str(Dv) + " F=" + str(F) + " k=" + str(k) | |
print(label) | |
GK = DiffReact2(np, random) | |
def sv_main(iterations=4): | |
verts_out = [] | |
in_sockets = [ | |
['s', 'iterations', iterations] | |
] | |
verts_out.append(GK.verts) | |
out_sockets = [ | |
['v', 'verts', verts_out] | |
] | |
return in_sockets, out_sockets |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
from math import floor | |
class DiffReact(): | |
_grid = [] | |
_next = [] | |
verts = [] | |
def __init__(self, np): | |
self.width = 140 | |
self.height = 140 | |
self.dA = 1 | |
self.dB = 0.5 | |
self.feed = 0.055 | |
self.k = 0.062 | |
self.setup(np) | |
def setup(self, np): | |
self._grid = np.ones((self.height, self.width, 2)) | |
self._next = np.ones((self.height, self.width, 2)) | |
for x in range(self.width): | |
for y in range(self.height): | |
self._grid[x][y][0] = 1 | |
self._grid[x][y][1] = 0 | |
self._next[x][y][0] = 1 | |
self._next[x][y][1] = 0 | |
for i in range(100, 110): | |
for j in range(100, 110): | |
self._grid[i][j][1] = 1 | |
def constrain(self, inval, _min, _max): | |
if inval < _min: | |
return _min | |
if inval > _max: | |
return _max | |
return inval | |
def swap(self): | |
self._grid, self._next = self._next, self._grid | |
def laplace(self, element, x, y): | |
_sum = 0 | |
_sum += self._grid[x][y][element] * -1 | |
_sum += self._grid[x - 1][y][element] * 0.2 | |
_sum += self._grid[x + 1][y][element] * 0.2 | |
_sum += self._grid[x][y + 1][element] * 0.2 | |
_sum += self._grid[x][y - 1][element] * 0.2 | |
_sum += self._grid[x - 1][y - 1][element] * 0.05 | |
_sum += self._grid[x + 1][y - 1][element] * 0.05 | |
_sum += self._grid[x + 1][y + 1][element] * 0.05 | |
_sum += self._grid[x - 1][y + 1][element] * 0.05 | |
return _sum | |
def draw(self): | |
for x in range(1, self.width - 1): | |
for y in range(1, self.height - 1): | |
a = self._grid[x][y][0] | |
b = self._grid[x][y][1] | |
_a = a + (self.dA * self.laplace(0, x, y)) - (a * b * b) + (self.feed * (1 - a)) | |
_b = b + (self.dB * self.laplace(1, x, y)) + (a * b * b) - ((self.k + self.feed) * b) | |
self._next[x][y][0] = _a | |
self._next[x][y][1] = _b | |
self._next.flatten() | |
np.clip(self._next, 0, 1, out=self._next) | |
self._next = self._next.reshape((self.height, self.width, 2)) | |
def yielder(): | |
for x in range(self.width): | |
for y in range(self.height): | |
a = self._next[x][y][0] | |
b = self._next[x][y][1] | |
c = floor((a - b) * 255) | |
c = self.constrain(c, 0, 255) | |
if c < 6: | |
yield x/20 | |
yield y/20 | |
yield 0 | |
em_yielder = yielder() | |
verts = np.fromiter(em_yielder, float) | |
h = len(verts) / 3 | |
self.verts = verts.reshape(h, 3).tolist() | |
self.swap() | |
GK = DiffReact(np) | |
def sv_main(iterations=4): | |
verts_out = [] | |
in_sockets = [ | |
['s', 'iterations', iterations] | |
] | |
for i in range(iterations): | |
GK.draw() | |
verts_out.append(GK.verts) | |
out_sockets = [ | |
['v', 'verts', verts_out] | |
] | |
return in_sockets, out_sockets |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
found potentially faster one.. http://code.activestate.com/recipes/579114-reaction-diffusion-simulation/