pyodide/benchmark/benchmarks/wave.py

58 lines
1.4 KiB
Python
Raw Normal View History

2018-10-03 18:59:01 +00:00
# from https://github.com/sklam/numba-example-wavephysics
# setup: N=100
# run: wave(N)
2018-04-05 22:07:33 +00:00
import numpy as np
2018-10-03 18:59:01 +00:00
2018-04-05 22:07:33 +00:00
def physics(masspoints, dt, plunk, which):
2018-10-03 18:59:01 +00:00
ppos = masspoints[1]
cpos = masspoints[0]
N = cpos.shape[0]
# apply hooke's law
HOOKE_K = 2100000.0
2018-10-03 18:59:01 +00:00
DAMPING = 0.0001
MASS = 0.01
2018-10-03 18:59:01 +00:00
force = np.zeros((N, 2))
for i in range(1, N):
dx, dy = cpos[i] - cpos[i - 1]
dist = np.sqrt(dx ** 2 + dy ** 2)
2018-10-03 18:59:01 +00:00
assert dist != 0
fmag = -HOOKE_K * dist
cosine = dx / dist
sine = dy / dist
fvec = np.array([fmag * cosine, fmag * sine])
force[i - 1] -= fvec
force[i] += fvec
force[0] = force[-1] = 0, 0
force[which][1] += plunk
accel = force / MASS
# verlet integration
npos = (2 - DAMPING) * cpos - (1 - DAMPING) * ppos + accel * (dt ** 2)
2018-10-03 18:59:01 +00:00
masspoints[1] = cpos
masspoints[0] = npos
2018-10-03 18:59:01 +00:00
# pythran export wave(int)
2018-04-05 22:07:33 +00:00
def wave(PARTICLE_COUNT):
SUBDIVISION = 300
FRAMERATE = 60
count = PARTICLE_COUNT
width, height = 1200, 400
masspoints = np.empty((2, count, 2), np.float64)
initpos = np.zeros(count, np.float64)
for i in range(1, count):
initpos[i] = initpos[i - 1] + float(width) / count
masspoints[:, :, 0] = initpos
masspoints[:, :, 1] = height / 2
f = 15
plunk_pos = count // 2
physics(masspoints, 1.0 / (SUBDIVISION * FRAMERATE), f, plunk_pos)
2018-04-05 22:07:33 +00:00
return masspoints[0, count // 2]