# Get f on quad points and exact solution fj = Array(ST, buffer=fe) uj = Array(ST, buffer=ue) # Compute right hand side f_hat = Function(ST) f_hat = inner(v, fj, output_array=f_hat) # Solve Poisson equation A = inner(grad(v), grad(u)) u_hat = Function(ST) u_hat = A.solve(-f_hat, u_hat) uq = ST.backward(u_hat) u_hat = ST.forward(uq, u_hat, fast_transform=False) uq = ST.backward(u_hat, uq, fast_transform=False) assert np.allclose(uj, uq) point = np.array([0.1, 0.2]) p = ST.eval(point, u_hat) assert np.allclose(p, lambdify(x, ue)(point)) if 'pytest' not in os.environ: import matplotlib.pyplot as plt plt.figure() plt.plot(X, uj.real) plt.title("U") plt.figure() plt.plot(X, (uq - uj).real)
def main(N, dt=0.005, end_time=2, dealias_initial=True, plot_result=False): SD = Basis(N, 'F', dtype='D') X = SD.points_and_weights()[0] v = TestFunction(SD) U = Array(SD) dU = Function(SD) U_hat = Function(SD) U_hat0 = Function(SD) U_hat1 = Function(SD) w0 = Function(SD) a = [1./6., 1./3., 1./3., 1./6.] # Runge-Kutta parameter b = [0.5, 0.5, 1.] # Runge-Kutta parameter nu = 0.2 k = SD.wavenumbers().astype(float) # initialize U[:] = 3./(5.-4.*np.cos(X)) if not dealias_initial: U_hat = SD.forward(U, U_hat) else: U_hat[:] = 2**(-abs(k)) def compute_rhs(rhs, u_hat, w0): rhs.fill(0) w0.fill(0) rhs = inner(v, nu*div(grad(u_hat)), output_array=rhs) rhs -= inner(v, grad(u_hat), output_array=w0) return rhs # Integrate using a 4th order Rung-Kutta method t = 0.0 tstep = 0 if plot_result is True: im = plt.figure() ca = im.gca() ca.plot(X, U.real, 'b') plt.draw() plt.pause(1e-6) while t < end_time-1e-8: t += dt tstep += 1 U_hat1[:] = U_hat0[:] = U_hat for rk in range(4): dU = compute_rhs(dU, U_hat, w0) if rk < 3: U_hat[:] = U_hat0 + b[rk]*dt*dU U_hat1 += a[rk]*dt*dU U_hat[:] = U_hat1 if tstep % (200) == 0 and plot_result is True: ca.plot(X, U.real) plt.pause(1e-6) #plt.savefig('Ginzburg_Landau_pad_{}_real_{}.png'.format(N[0], int(np.round(t)))) U = SD.backward(U_hat, U) Ue = np.zeros_like(U) for k in range(-100, 101): Ue += 2**(-abs(k))*np.exp(1j*k*(X-t) - nu*k**2*t) err = np.sqrt(2*np.pi/N*np.linalg.norm(U-Ue.real)**2) return 1./N, err