h, x, V, R, I = initialize(a, b, N) # initialization scene = vp.display(background=(1,1,1), ambient=1) # set scene bars = vpm.bars(x, z, z, z, h, 0.05, (1,0,1)) # wave function line = vpm.line(x, z, z, (1,0,1), 0.02) pot = vpm.line(x, V*0.05, z, (0,0,0), 0.02) # potential line t, ic, cycle = 0.0, 0, 10 # t, animation cycle dt, psi = 0.001, R + 1j*I # initialize dt, complex psi ta, pba = [], [] # time, prob. arrays A = np.ones((3, N+1), dtype=complex) # prepare band matrix A, B A[1,:] = 2*(2j*h*h/dt - 1 - h*h*V) dB = - np.conjugate(A[1,:]) # diagonal of B while(t<=3): C = dB*psi # prepare RHS C[1:-1] -= (psi[:-2] + psi[2:]) psi = solve_banded((1,1), A, C) # band matrix solver t, ic = t+dt, ic+1 if (ic % cycle == 0): pb = psi.real**2 + psi.imag**2 # probability ta.append(t), pba.append(pb) # store data line.move(x, mag*pb, z) bars.move(x, z, z, mag*pb) vp.rate(1200), vpm.wait(scene) (X, Y), ta = np.meshgrid(x, ta), np.array(ta) plt.figure() plt.contour(Y, X, pba, 36, linewidths=1) plt.plot(ta, 5 - ta*ta, 'r--') # classical free fall plt.xlabel('t (a.u.)'), plt.ylabel('x (a.u.)') plt.show()
rright = r[:, 0:-1] - r[:, 1:] # rel pos to right neighbor ftop, fright = force(rtop), force(rright) # forces from top, right f[0:-1, :] = ftop # force from top f[:, 0:-1] += fright # force from right f[1:, :] -= ftop # below, left: use 3rd law f[:, 1:] -= fright a = (f - damp*v)/mass + gvec v[0,0], v[0,-1], v[-1,0], v[-1,-1]=0, 0, 0, 0 # fixed coners return np.array([v,a]) L, M, N = 2.0, 15, 15 # size, (M,N) particle array h, mass, damp = 0.01, 0.004, 0.01 # keep damp between [.01,.1] x, y = np.linspace(0,L,M), np.linspace(0,L,N) # particle grid r, v = np.zeros((N,M,3)), np.zeros((N,M,3)) spring_k, spring_l = 50.0, x[1]-x[0] # spring const., relaxed length r[:,:, 0], r[:,:, 1] = np.meshgrid(x,y) # initialize pos Y, gvec = np.array([r, v]), np.array([0,0,-9.8]) # [v,a], g vector scene = vp.display(title='Tablecloth', background=(.2,.5,1), up=(0,0,1), center=(L/2,L/2,-L/4), forward=(1,2,-1)) vp.points(pos=[(0,0,0),(0,L,0),(L,L,0),(L,0,0)], size=50) # corners x, y, z = r[:,:,0], r[:,:,1], r[:,:,2] # mesh points net = vpm.net(x, y, z, vp.color.yellow, 0.005) # mesh net mesh = vpm.mesh(x, y, z, vp.color.red, vp.color.yellow) while (1): vp.rate(100), vpm.wait(scene) # pause if key pressed Y = ode.RK4(cloth, Y, 0, h) x, y, z = Y[0,:,:,0], Y[0,:,:,1], Y[0,:,:,2] net.move(x, y, z), mesh.move(x, y, z)
f[1:, :] -= ftop # below, left: use 3rd law f[:, 1:] -= fright a = (f - damp * v) / mass + gvec v[0, 0], v[0, -1], v[-1, 0], v[-1, -1] = 0, 0, 0, 0 # fixed coners return np.array([v, a]) L, M, N = 2.0, 15, 15 # size, (M,N) particle array h, mass, damp = 0.01, 0.004, 0.01 # keep damp between [.01,.1] x, y = np.linspace(0, L, M), np.linspace(0, L, N) # particle grid r, v = np.zeros((N, M, 3)), np.zeros((N, M, 3)) spring_k, spring_l = 50.0, x[1] - x[0] # spring const., relaxed length r[:, :, 0], r[:, :, 1] = np.meshgrid(x, y) # initialize pos Y, gvec = np.array([r, v]), np.array([0, 0, -9.8]) # [v,a], g vector scene = vp.display(title='Tablecloth', background=(.2, .5, 1), up=(0, 0, 1), center=(L / 2, L / 2, -L / 4), forward=(1, 2, -1)) vp.points(pos=[(0, 0, 0), (0, L, 0), (L, L, 0), (L, 0, 0)], size=50) # corners x, y, z = r[:, :, 0], r[:, :, 1], r[:, :, 2] # mesh points net = vpm.net(x, y, z, vp.color.yellow, 0.005) # mesh net mesh = vpm.mesh(x, y, z, vp.color.red, vp.color.yellow) while (1): vp.rate(100), vpm.wait(scene) # pause if key pressed Y = ode.RK4(cloth, Y, 0, h) x, y, z = Y[0, :, :, 0], Y[0, :, :, 1], Y[0, :, :, 2] net.move(x, y, z), mesh.move(x, y, z)
rij = r[i]-r[i+1:] # rij for all j>i rij[rij > HL] -= L # periodic bc rij[rij < -HL] += L r2 = np.sum(rij*rij, axis=1) # |rij|^2 r6 = r2*r2*r2 for k in [0,1,2]: # L-J force in x,y,z fij = 12.*(1. - r6)*rij[:,k]/(r6*r6*r2) a[i,k] += np.sum(fij) a[i+1:,k] -= fij # 3rd law return a L, N = 10.0, 32 # cube size, num. atoms atoms, HL, t, h = [], L/2., 0., 0.002 r, v = np.zeros((N,3)), np.zeros((N,3)) scene = vp.display(background=(.2,.5,1), center=(L/2, L/3, L/2)) vp.box(pos=(HL,HL,HL), length=L, height=L, width=L, opacity=0.3) for i in range(N): # initial pos, vel for k in range(3): r[i,k] = L*rnd.random() v[i,k] = 1-2*rnd.random() atoms.append(vp.sphere(pos=r[i], radius=0.04*L, color=(1,0,1))) v -= np.sum(v, axis=0)/N # center of mass frame while (1): vpm.wait(scene), vp.rate(1000) r, v = ode.leapfrog(nbody, r, v, t, h) r[r > L] -= L # periodic bc r[r < 0.] += L for i in range(N): atoms[i].pos = r[i] # move atoms
return [psi[1], 2*(V(x)-E)*psi[0]] # initialization and animation setup a, V0 = 4.0, 4. # well width, depth R, N = 4*a, 200 # limit, intervals xa = np.linspace(-R, R, 2*N+1) # grid h, z = xa[1]-xa[0], np.zeros(2*N+1) # step size E, dE, dpsi, psix = -V0, 0.001, 1.0, np.zeros(2*N+1) scene = vp.display(background=(.2,.5,1), range=1.5*a) wf = vpm.line(xa, psix, z, vp.color.red, .05) pot = vpm.line(xa, .5*np.vectorize(V)(xa), z, (1,1,1), .04) # pot. V info = vp.label(pos=(0, -0.6*a, 0), box=False, height=20) while (E < 0.0): psi, x = [.0, .1], -R for i in range(N): # WF for x <=0 psi = ode.RK45n(sch, psi, x, h) x += h psix[i+1] = psi[0] psix[N+1:] = psix[N-1::-1] # WF for x > 0 by reflection if (dpsi*psi[1] < 0.): # dpsi/dx changes sign info.text='Energy found, E=%5.4f' %(E-dE/2) vpm.pause(scene) # any key to continue else: info.text='E=%5.3f' %(E) wf.move(xa, 2*psix/max(psix), z), vpm.wait(scene), vp.rate(2000) dpsi = psi[1] # old dpsi/dx at E E += dE
vp.arrow(pos=(.2, -.2, L), axis=ay, length=0.2, color=(0,1,1)) vp.arrow(pos=(.2, -.2, L), axis=az, length=0.2, color=(1,1,1)) vp.label(pos=(.45, -.2, L), text='E', box=False, height=30) vp.label(pos=(.25, -.0, L), text='B', box=False, height=30) vp.label(pos=(.2, -.15, L+.3), text='v', box=False, height=30) idx, z = np.arange(n), np.linspace(-L, 2*L, n) # order of vectors mag = scale*np.sin(2*np.pi*z/L) # sine envelope ewave = vp.curve(color=(1,1,0), pos=np.column_stack((mag,0*z,z))) bwave = vp.curve(color=(0,1,1), pos=np.column_stack((0*z,mag,z))) for i in idx: E.append( vp.arrow(pos=(0, 0, z[i]), axis=ax, length=mag[i], color=(1,1,0)) ) B.append( vp.arrow(pos=(0, 0, z[i]), axis=ay, length=mag[i], color=(0,1,1)) ) while True: vp.rate(100), vpm.wait(scene) # hit a key to pause t, mg = t + dt, mag*np.cos(t) # sinusoidal wave for i in range(n): E[i].pos.z += v*dt # traveling wave B[i].pos.z += v*dt if (E[i].pos.z > 2*L): # wrap around E[i].pos.z, B[i].pos.z = -L, -L idx = np.insert(idx, 0, i)[:-1] # move to end E[i].axis, B[i].axis = ax, ay # reset axis to E[i].length, B[i].length = mg[i], mg[i] # draw correctly id = idx[i] ewave.pos[i] = (mg[id], 0, E[id].pos.z) # envelope curves bwave.pos[i] = (0, mg[id], B[id].pos.z)
h, x, V, R, I = initialize(a, b, N) # initialization scene = vp.display(background=(1, 1, 1), ambient=1) # set scene bars = vpm.bars(x, z, z, z, h, 0.05, (1, 0, 1)) # wave function line = vpm.line(x, z, z, (1, 0, 1), 0.02) pot = vpm.line(x, V * 0.05, z, (0, 0, 0), 0.02) # potential line t, ic, cycle = 0.0, 0, 10 # t, animation cycle dt, psi = 0.001, R + 1j * I # initialize dt, complex psi ta, pba = [], [] # time, prob. arrays A = np.ones((3, N + 1), dtype=complex) # prepare band matrix A, B A[1, :] = 2 * (2j * h * h / dt - 1 - h * h * V) dB = -np.conjugate(A[1, :]) # diagonal of B while (t <= 3): C = dB * psi # prepare RHS C[1:-1] -= (psi[:-2] + psi[2:]) psi = solve_banded((1, 1), A, C) # band matrix solver t, ic = t + dt, ic + 1 if (ic % cycle == 0): pb = psi.real**2 + psi.imag**2 # probability ta.append(t), pba.append(pb) # store data line.move(x, mag * pb, z) bars.move(x, z, z, mag * pb) vp.rate(1200), vpm.wait(scene) (X, Y), ta = np.meshgrid(x, ta), np.array(ta) plt.figure() plt.contour(Y, X, pba, 36, linewidths=1) plt.plot(ta, 5 - ta * ta, 'r--') # classical free fall plt.xlabel('t (a.u.)'), plt.ylabel('x (a.u.)') plt.show()
vp.arrow(pos=(.2, -.2, L), axis=ay, length=0.2, color=(0, 1, 1)) vp.arrow(pos=(.2, -.2, L), axis=az, length=0.2, color=(1, 1, 1)) vp.label(pos=(.45, -.2, L), text='E', box=False, height=30) vp.label(pos=(.25, -.0, L), text='B', box=False, height=30) vp.label(pos=(.2, -.15, L + .3), text='v', box=False, height=30) idx, z = np.arange(n), np.linspace(-L, 2 * L, n) # order of vectors mag = scale * np.sin(2 * np.pi * z / L) # sine envelope ewave = vp.curve(color=(1, 1, 0), pos=np.column_stack((mag, 0 * z, z))) bwave = vp.curve(color=(0, 1, 1), pos=np.column_stack((0 * z, mag, z))) for i in idx: E.append( vp.arrow(pos=(0, 0, z[i]), axis=ax, length=mag[i], color=(1, 1, 0))) B.append( vp.arrow(pos=(0, 0, z[i]), axis=ay, length=mag[i], color=(0, 1, 1))) while True: vp.rate(100), vpm.wait(scene) # hit a key to pause t, mg = t + dt, mag * np.cos(t) # sinusoidal wave for i in range(n): E[i].pos.z += v * dt # traveling wave B[i].pos.z += v * dt if (E[i].pos.z > 2 * L): # wrap around E[i].pos.z, B[i].pos.z = -L, -L idx = np.insert(idx, 0, i)[:-1] # move to end E[i].axis, B[i].axis = ax, ay # reset axis to E[i].length, B[i].length = mg[i], mg[i] # draw correctly id = idx[i] ewave.pos[i] = (mg[id], 0, E[id].pos.z) # envelope curves bwave.pos[i] = (0, mg[id], B[id].pos.z)
rij[rij < -HL] += L r2 = np.sum(rij * rij, axis=1) # |rij|^2 r6 = r2 * r2 * r2 for k in [0, 1, 2]: # L-J force in x,y,z fij = 12. * (1. - r6) * rij[:, k] / (r6 * r6 * r2) a[i, k] += np.sum(fij) a[i + 1:, k] -= fij # 3rd law return a L, N = 10.0, 32 # cube size, num. atoms atoms, HL, t, h = [], L / 2., 0., 0.002 r, v = np.zeros((N, 3)), np.zeros((N, 3)) scene = vp.display(background=(.2, .5, 1), center=(L / 2, L / 3, L / 2)) vp.box(pos=(HL, HL, HL), length=L, height=L, width=L, opacity=0.3) for i in range(N): # initial pos, vel for k in range(3): r[i, k] = L * rnd.random() v[i, k] = 1 - 2 * rnd.random() atoms.append(vp.sphere(pos=r[i], radius=0.04 * L, color=(1, 0, 1))) v -= np.sum(v, axis=0) / N # center of mass frame while (1): vpm.wait(scene), vp.rate(1000) r, v = ode.leapfrog(nbody, r, v, t, h) r[r > L] -= L # periodic bc r[r < 0.] += L for i in range(N): atoms[i].pos = r[i] # move atoms
return [psi[1], 2 * (V(x) - E) * psi[0]] # initialization and animation setup a, V0 = 4.0, 4. # well width, depth R, N = 4 * a, 200 # limit, intervals xa = np.linspace(-R, R, 2 * N + 1) # grid h, z = xa[1] - xa[0], np.zeros(2 * N + 1) # step size E, dE, dpsi, psix = -V0, 0.001, 1.0, np.zeros(2 * N + 1) scene = vp.display(background=(.2, .5, 1), range=1.5 * a) wf = vpm.line(xa, psix, z, vp.color.red, .05) pot = vpm.line(xa, .5 * np.vectorize(V)(xa), z, (1, 1, 1), .04) # pot. V info = vp.label(pos=(0, -0.6 * a, 0), box=False, height=20) while (E < 0.0): psi, x = [.0, .1], -R for i in range(N): # WF for x <=0 psi = ode.RK45n(sch, psi, x, h) x += h psix[i + 1] = psi[0] psix[N + 1:] = psix[N - 1::-1] # WF for x > 0 by reflection if (dpsi * psi[1] < 0.): # dpsi/dx changes sign info.text = 'Energy found, E=%5.4f' % (E - dE / 2) vpm.pause(scene) # any key to continue else: info.text = 'E=%5.3f' % (E) wf.move(xa, 2 * psix / max(psix), z), vpm.wait(scene), vp.rate(2000) dpsi = psi[1] # old dpsi/dx at E E += dE
amnt = amn0*np.outer(phase, phase) # $a_{mn}(t)=a_{mn}(0)e^{-i E_{mn} t}$ for m in range(N): s = 0.0 for n in range(N): s += amnt[m,n]*uny[n] # vector operation wf += s*umx[m] # $\sum a_{mn} u_m(x) u_n(y)$ return wf t, num, plot = 0., 1, False # set plot=False to animate forever time = [0.0, 0.5, 0.9, 1.4, 2.0, 3.0, 40, 63.7, 64.2] # snapshots a, N, En, amn0, X, Y, umx, uny = initialize() scene = vp.display(background=(.2,.5,1), center=(a/2,a/2,-0.5), up=(0,0,1), forward=(1,2,-1)) mesh = vpm.mesh(X, Y, 0*X, vp.color.yellow, vp.color.red) info = vp.label(pos=(a/4, .8*a,1), height=20) while True: wf = psi(amn0, t) mesh.move(X, Y, wf.real*3) # show real part, times 3 info.text='%5.2f' %(t) vpm.wait(scene), vp.rate(40) if (plot): plt.subplot(3, 3, num) plt.imshow(np.abs(wf)**2, cmap=plt.cm.jet) # try contourf() plt.xticks([],[]), plt.yticks([],[]) # omit ticks plt.xlabel('t=%s' %(t)) if (num > len(time)-1): break t, num = time[num], num+1 else: t = t + 0.05 if (plot): plt.show()
wf += s * umx[m] # $\sum a_{mn} u_m(x) u_n(y)$ return wf t, num, plot = 0., 1, False # set plot=False to animate forever time = [0.0, 0.5, 0.9, 1.4, 2.0, 3.0, 40, 63.7, 64.2] # snapshots a, N, En, amn0, X, Y, umx, uny = initialize() scene = vp.display(background=(.2, .5, 1), center=(a / 2, a / 2, -0.5), up=(0, 0, 1), forward=(1, 2, -1)) mesh = vpm.mesh(X, Y, 0 * X, vp.color.yellow, vp.color.red) info = vp.label(pos=(a / 4, .8 * a, 1), height=20) while True: wf = psi(amn0, t) mesh.move(X, Y, wf.real * 3) # show real part, times 3 info.text = '%5.2f' % (t) vpm.wait(scene), vp.rate(40) if (plot): plt.subplot(3, 3, num) plt.imshow(np.abs(wf)**2, cmap=plt.cm.jet) # try contourf() plt.xticks([], []), plt.yticks([], []) # omit ticks plt.xlabel('t=%s' % (t)) if (num > len(time) - 1): break t, num = time[num], num + 1 else: t = t + 0.05 if (plot): plt.show()
c = 1.0/np.sqrt(s*np.sqrt(np.pi)) return c*np.exp(-((x-x0)/s)**2/2) def initialize(a, b, N): # set parameters x = np.linspace(a, b, N+1) # grid points V = 0.5*x*x # SHO potential s, x0 = 0.5, -5.0 # width (sigma), center of gaussian R, I = gaussian(s, x0, x), np.zeros(N+1) # real, imag w.f. return x[1]-x[0], x,V,R,I # grid size, h=x[1]-x[0] a, b, N = -10., 10., 500 # space range [a,b], num. intervals z, mag = np.zeros(N+1), 4 # zeros, magnifying factor h, x, V, R, I = initialize(a, b, N) # initialization scene = vp.display(background=(1,1,1), ambient=1) # set scene bars = vpm.bars(x, z, z, z, h, 0.05, (1,0,1)) # wave function line = vpm.line(x, z, z, (1,0,1), 0.02) pot = vpm.line(x, V*0.1, z, (0,0,0), 0.02) # potential line t, ic, cycle = 0.0, 0, 20 # t, animation cycle dt = h*h*0.5 # time step, dt < h*h while True: R, I = ode.leapfrog(sch_eqn, R, I, t, dt) # main work ic += 1 if (ic % cycle == 0): # animate pb = R*R + I*I # probability line.move(x, mag*pb, z) bars.move(x, z, z, mag*pb) vp.rate(3000), vpm.wait(scene)
return c * np.exp(-((x - x0) / s)**2 / 2) def initialize(a, b, N): # set parameters x = np.linspace(a, b, N + 1) # grid points V = 0.5 * x * x # SHO potential s, x0 = 0.5, -5.0 # width (sigma), center of gaussian R, I = gaussian(s, x0, x), np.zeros(N + 1) # real, imag w.f. return x[1] - x[0], x, V, R, I # grid size, h=x[1]-x[0] a, b, N = -10., 10., 500 # space range [a,b], num. intervals z, mag = np.zeros(N + 1), 4 # zeros, magnifying factor h, x, V, R, I = initialize(a, b, N) # initialization scene = vp.display(background=(1, 1, 1), ambient=1) # set scene bars = vpm.bars(x, z, z, z, h, 0.05, (1, 0, 1)) # wave function line = vpm.line(x, z, z, (1, 0, 1), 0.02) pot = vpm.line(x, V * 0.1, z, (0, 0, 0), 0.02) # potential line t, ic, cycle = 0.0, 0, 20 # t, animation cycle dt = h * h * 0.5 # time step, dt < h*h while True: R, I = ode.leapfrog(sch_eqn, R, I, t, dt) # main work ic += 1 if (ic % cycle == 0): # animate pb = R * R + I * I # probability line.move(x, mag * pb, z) bars.move(x, z, z, mag * pb) vp.rate(3000), vpm.wait(scene)