Commit 73ac2ed0 by Jigyasa Watwani

analytical and numerical solutions match exactly for alpha zero

parent 1a71fc46
Showing with 74 additions and 85 deletions
import dolfin as df
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from matplotlib.widgets import Slider from matplotlib.widgets import Slider
import progressbar import progressbar
import dolfin as df
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
# parameters def advection_diffusion(Nx, L, Nt, tmax, D, alpha):
alpha = 1.0 # mesh, function space, function, test function
T = 1 mesh = df.IntervalMesh(Nx, 0, L)
dt = 0.001 SFS = df.FunctionSpace(mesh, 'P', 1)
L0 = 1 c = df.Function(SFS)
D = 1.0 tc = df.TestFunction(SFS)
Nx = 2000
Nt = 1000 # x and t arrays
t = np.linspace(0,T,Nt) times = np.linspace(0, tmax, Nt+1)
dt = times[1] - times[0]
# diffusion and advection
def diffusion(c, tc): # initial condition
return (D * df.inner(c.dx(0), tc.dx(0))) c0 = df.Function(SFS)
c0.interpolate(df.Expression('1 + 0.2 * cos(pi*x[0]/L)', pi=np.pi, L=L, degree=1))
def advection(c, tc, v):
u = df.interpolate(v, c.function_space()) # arrays
return (df.inner((u*c).dx(0),tc)) c_array = np.zeros((Nt+1, Nx+1))
x_array = np.zeros((Nt+1, Nx+1))
# create mesh x_array[0] = mesh.coordinates()[:, 0]
mesh = df.IntervalMesh(Nx, 0, L0) c_array[0] = c0.compute_vertex_values(mesh)
x = mesh.coordinates()
# v = df.Constant(1.0) # velocity
v = df.Expression('alpha*x[0]',alpha = alpha,degree=1) v = df.Expression('alpha*x[0]', alpha=alpha, degree=1)
u = df.interpolate(v, SFS)
# create function space
conc_element = df.FiniteElement('P', mesh.ufl_cell(), 1) # form
function_space = df.FunctionSpace(mesh,conc_element) cform = (df.inner((c - c0)/dt, tc)
+ D * df.inner(df.nabla_grad(c), df.nabla_grad(tc))
# initial condition + df.inner((u*c).dx(0), tc) )* df.dx
c0 = df.interpolate(df.Expression('1 + 0.2*cos(pi*x[0]/L0)', pi = np.pi, L0 = L0,degree=1),function_space)
c0_array = c0.compute_vertex_values(mesh) # solve
for i in progressbar.progressbar(range(1, Nt+1)):
# define variational problem df.solve(cform == 0, c)
c = df.Function(function_space) c_array[i] = c.compute_vertex_values(mesh)
tc = df.TestFunction(function_space) c0.assign(c)
form = (df.inner((c - c0)/dt, tc) df.ALE.move(mesh, df.Expression('v*dt', v=v, dt=dt, degree=1))
+ diffusion(c,tc) x_array[i] = mesh.coordinates()[:,0]
+ advection(c, tc, v)
) return c_array, x_array
form = form * df.dx
# plot c(x,t) numerical and analytical for given dt
# time stepping Nx, L, Nt, tmax, D, alpha = 64, 1, 100, 1, 1, 1
ctot = np.zeros_like(t) x = advection_diffusion(Nx, L, Nt, tmax, D, alpha)[1]
x_array = np.zeros((len(t), mesh.num_vertices()))
# exact solution
x_array[0] = mesh.coordinates()[:,0] c_exact = np.zeros((Nt+1, Nx+1))
c_array = np.zeros((len(t), len(c0_array))) times = np.linspace(0, tmax, Nt+1)
c_array[0] = c0_array for j in range(Nt+1):
ctot[0] = df.assemble(c0*df.dx(mesh)) if alpha == 0:
c_exact[j] = 1 + 0.2 * np.cos(np.pi * x[j]/L) * np.exp(-np.pi**2 * D * times[j]/L**2)
for n in progressbar.progressbar(range(1, len(t))): else:
df.solve(form == 0, c) c_exact[j] = 1 + 0.2 * np.cos(np.pi*x[j]*np.exp(-alpha*times[j])/L) * np.exp(-np.pi**2 * D * (1 - np.exp(-2 * alpha * times[j]))/(2 * alpha * L**2)) * np.exp(-alpha * times[j])
c_array[n] = c.compute_vertex_values(mesh)
c0.assign(c) c = advection_diffusion(Nx, L, Nt, tmax, D, alpha)[0]
ctot[n] = df.assemble(c0*df.dx(mesh)) times = np.linspace(0, tmax, Nt+1)
df.ALE.move(mesh, df.Expression('v*dt',v=v,dt=dt,degree=1)) fig, ax = plt.subplots(1,1,figsize=(8,6))
x_array[n] = mesh.coordinates()[:,0] ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$c(x,t)$')
# analytical solution ax.set_xlim(np.min(x)-2, np.max(x)+2)
c_exact= np.zeros((len(t), len(x))) ax.set_ylim(np.min(c)-2, np.max(c)+2)
for i in range(len(t)): cplot, = ax.plot(x[0], c[0], 'go', ms=1)
xprime = x_array[0] / (L0 * np.exp(alpha * t[i])) cexactplot, = ax.plot(x[0], c_exact[0])
tprime = ( D / (2 * alpha * L0**2)) * ( 1 - np.exp(-2 * alpha * t[i]))
int = np.exp(-alpha * t[i])
c_exact[i] = int * (1 + 0.2 * np.cos(np.pi * xprime) * np.exp(-np.pi**2 * tprime))
# plot c(x,t) computed numerically
fig, ax_comp = plt.subplots(1,1,figsize=(8,6))
ax_comp.set_xlabel(r'$x$')
ax_comp.set_ylabel(r'$c(x,t)$')
ax_comp.set_xlim(np.min(x_array)-1, np.max(x_array)+1)
ax_comp.set_ylim(np.min(c_array)-1, np.max(c_array)+1)
cplot, = ax_comp.plot(x_array[0], c0_array)
c_exactplot, = ax_comp.plot(x_array[0], c_exact[0], 'ro', markersize=3, markevery=50)
def update(value): def update(value):
ti = np.abs(t-value).argmin() ti = np.abs(times-value).argmin()
cplot.set_xdata(x_array[ti]) cplot.set_xdata(x[ti])
cplot.set_ydata(c_array[ti]) cplot.set_ydata(c[ti])
c_exactplot.set_xdata(x_array[ti]) cexactplot.set_xdata(x[ti])
c_exactplot.set_ydata(c_exact[ti]) cexactplot.set_ydata(c_exact[ti])
plt.draw() plt.draw()
sax = plt.axes([0.1, 0.92, 0.7, 0.02]) sax = plt.axes([0.1, 0.92, 0.7, 0.02])
slider = Slider(sax, r'$t/\tau$', min(t), max(t), slider = Slider(sax, r'$t/\tau$', min(times), max(times),
valinit=min(t), valfmt='%3.1f', valinit=min(times), valfmt='%3.1f',
fc='#999999') fc='#999999')
slider.drawon = False slider.drawon = False
slider.on_changed(update) slider.on_changed(update)
......
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