X = ST.mesh() # 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()
f_hat = inner(v, fj, output_array=f_hat) if family == 'legendre': f_hat *= -1. # Get left hand side of Poisson equation if family == 'chebyshev': A = inner(v, div(grad(u))) + alpha*inner(v, grad(u)) else: A = inner(grad(v), grad(u)) - alpha*inner(v, grad(u)) if family == 'chebyshev': f_hat[0] -= 0.5*np.pi*alpha*a f_hat[0] += 0.5*np.pi*alpha*b elif family == 'legendre': f_hat[0] += alpha*a f_hat[0] -= alpha*b f_hat[:-2] = A.solve(f_hat[:-2]) f_hat[-2] = a f_hat[-1] = b uj = SD.backward(f_hat) # Compare with analytical solution ua = ul(X) print("Error=%2.16e" %(np.linalg.norm(uj-ua))) assert np.allclose(uj, ua) point = np.array([0.1, 0.2]) p = SD.eval(point, f_hat) assert np.allclose(p, ul(point))
f_hat = Function(SD, buffer=inner(v, fj)) if family == 'legendre': f_hat *= -1. # Get left hand side of Poisson equation if family == 'chebyshev': A = inner(v, div(grad(u))) else: A = inner(grad(v), grad(u)) f_hat = A.solve(f_hat) # Solve and transform to real space u = np.zeros(N) # Solution real space u = SD.backward(f_hat, u) # Compare with analytical solution uj = ul(X) print(abs(uj-u).max()) assert np.allclose(uj, u) if not plt is None and not 'pytest' in os.environ: plt.figure() plt.plot(X, u) plt.figure() plt.plot(X, uj) plt.figure() plt.plot(X, u-uj)
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
# Compute right hand side of Poisson equation f_hat = Array(SD) f_hat = inner(v, fj, output_array=f_hat) # Get left hand side of Poisson equation if family == 'chebyshev': A = inner(v, -div(grad(u))) B = inner(v, alfa * u) else: A = inner(grad(v), grad(u)) B = inner(v, alfa * u) H = Solver(A, B) u_hat = Function(SD) # Solution spectral space u_hat = H(u_hat, f_hat) uj = SD.backward(u_hat) # Compare with analytical solution ua = ul(X) if family == 'chebyshev': # Compute L2 error norm using Clenshaw-Curtis integration from shenfun import clenshaw_curtis1D error = clenshaw_curtis1D((uj - ua)**2, quad=SD.quad) print("Error=%2.16e" % (error)) else: x, w = SD.points_and_weights() print("Error=%2.16e" % (np.sqrt(np.sum((uj - ua)**2 * w)))) assert np.allclose(uj, ua)
# Some work required for inhomogeneous boundary conditions only if SD.has_nonhomogeneous_bcs: bc_mats = extract_bc_matrices([matrices]) # Add boundary terms to the known right hand side SD.bc.set_boundary_dofs(u_hat, final=True) # Fixes boundary dofs in u_hat w0 = np.zeros_like(u_hat) for m in bc_mats: f_hat -= m.matvec(u_hat, w0) # Create linear algebra solver H = Solver(*matrices) u_hat = H(u_hat, f_hat) uj = Array(SD) uj = SD.backward(u_hat, uj) uh = uj.forward() # Compare with analytical solution uq = Array(SD, buffer=ue) print("Error=%2.16e" % (np.linalg.norm(uj - uq))) assert np.linalg.norm(uj - uq) < 1e-8 if 'pytest' not in os.environ: import matplotlib.pyplot as plt plt.figure() plt.plot(X, uq) plt.figure() plt.plot(X, uj)
# Compute right hand side of biharmonic equation f_hat = inner(v, fj) # Get left hand side of biharmonic equation (no integration by parts) S = inner(v, a*Dx(u, 0, 4)) A = inner(v, b*Dx(u, 0, 2)) B = inner(v, c*u) # Create linear algebra solver H = Solver(S, A, B) # Solve and transform to real space u_hat = Function(SD) # Solution spectral space u_hat = H(u_hat, f_hat) # Solve u = Array(SD) u = SD.backward(u_hat, u) uh = u.forward() # Compare with analytical solution uj = ul(X) print("Error=%2.16e" %(np.linalg.norm(uj-u))) assert np.allclose(uj, u) point = np.array([0.1, 0.2]) p = u_hat.eval(point) assert np.allclose(p, ul(point)) if 'pytest' not in os.environ: import matplotlib.pyplot as plt plt.figure() plt.plot(X, u)