Commit 1a71fc46 by Jigyasa Watwani

max error scaling linearly with dt

parent f83b6210
Showing with 46 additions and 46 deletions
...@@ -7,61 +7,61 @@ import progressbar ...@@ -7,61 +7,61 @@ import progressbar
df.set_log_level(df.LogLevel.ERROR) df.set_log_level(df.LogLevel.ERROR)
df.parameters['form_compiler']['optimize'] = True df.parameters['form_compiler']['optimize'] = True
Nx, L, D, tmax, dt = 32, 1.0, 0.1, 2.0, 0.05 def advection_diffusion(Nx, L, Nt, tmax, D):
Nt = int(tmax/dt) # mesh, function space, function, test function
mesh = df.IntervalMesh(Nx, 0, L)
mesh = df.IntervalMesh(Nx, 0, L) SFS = df.FunctionSpace(mesh, 'P', 1)
x = mesh.coordinates()[:, 0] c = df.Function(SFS)
times = np.linspace(0, tmax, Nt+1) tc = df.TestFunction(SFS)
SFS = df.FunctionSpace(mesh, 'P', 1) # x and t arrays
c = df.Function(SFS) x = mesh.coordinates()[:, 0]
tc = df.TestFunction(SFS) times = np.linspace(0, tmax, Nt+1)
c0 = df.Function(SFS) dt = times[1] - times[0]
c0.interpolate(df.Expression('1 + 0.1 * cos(2*pi*x[0]/L)', pi=np.pi,L=L, degree=1)) # initial condition
c0 = df.Function(SFS)
c_exact = np.zeros((Nt+1, Nx+1)) c0.interpolate(df.Expression('1 + 0.1 * cos(2*pi*x[0]/L)', pi=np.pi,L=L, degree=1))
for i in range(Nt+1):
c_exact[i] = 1 + 0.1 * np.cos(2*np.pi*x/L) * np.exp(-4*np.pi**2*D*times[i]/L**2) # arrays
c_array = np.zeros((Nt+1, Nx+1))
c_array = np.zeros((Nt+1, Nx+1)) c_array[0] = c0.compute_vertex_values(mesh)
c_array[0] = c0.compute_vertex_values(mesh)
# form
cform = (df.inner((c - c0)/dt, tc) cform = (df.inner((c - c0)/dt, tc)
+ D * df.inner(df.nabla_grad(c), df.nabla_grad(tc))) * df.dx + D * df.inner(df.nabla_grad(c), df.nabla_grad(tc))) * df.dx
for i in progressbar.progressbar(range(1, Nt+1)): # solve
for i in progressbar.progressbar(range(1, Nt+1)):
df.solve(cform == 0, c) df.solve(cform == 0, c)
c0.assign(c) c0.assign(c)
c_array[i] = c0.compute_vertex_values(mesh) c_array[i] = c0.compute_vertex_values(mesh)
fig, (ax, ax1) = plt.subplots(2, 1) return c_array
fig.suptitle(r'$N_x = %d, \Delta t = %4.3f$' % (Nx, dt))
cplot, = ax.plot(x, c_array[0], 'ro', mfc='none', ms=6, label='Numerics')
ceplot, = ax.plot(x, c_exact[0], label='Exact')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$c(x,t)$')
ax.legend(loc=1)
error = c_array-c_exact
print(np.max(error))
err_plot, = ax1.plot(x, error[0], 'bo', mfc='none', ms=6) # parameters
ax1.set_ylim(np.min(error), np.max(error)) Nx, L, D, tmax = 64, 1.0, 0.1, 1.0
ax1.set_xlabel(r'$x$') nt_array = np.array([50, 100, 200, 400, 600, 800, 1600])
ax1.set_ylabel(r'$c(x,t)-c_{\rm exact}(x,t)$') dt_array = tmax/nt_array
mesh = df.IntervalMesh(Nx, 0, L)
x = mesh.coordinates()[:, 0]
def update(val): # error array
ti = (abs(times-val)).argmin() error = np.zeros(len(nt_array))
cplot.set_ydata(c_array[ti])
ceplot.set_ydata(c_exact[ti])
err_plot.set_ydata(error[ti]) for i in range(0, len(nt_array)):
plt.draw()
sax = plt.axes([0.1, 0.92, 0.7, 0.025]) # exact solution
sl = Slider(sax, 't', times.min(), times.max(), valinit=times.min()) c_exact = np.zeros((nt_array[i]+1, Nx+1))
sl.on_changed(update) times = np.linspace(0, tmax, nt_array[i]+1)
for j in range(nt_array[i]+1):
c_exact[j] = 1 + 0.1 * np.cos(2*np.pi*x/L) * np.exp(-4*np.pi**2*D*times[j]/L**2)
c = advection_diffusion(Nx, L, nt_array[i], tmax, D)
error[i] = np.max(np.abs(c - c_exact))
fig, ax = plt.subplots(1)
ax.plot(dt_array, error, 'bo')
ax.set_xlabel('$dt$')
ax.set_ylabel('error')
plt.show() plt.show()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment