Hi guys,
I’m writing a program in FEniCS 2019.1.0 to solve the following coupled reaction-diffusion system
where D_c, \; k, \; h, \; \kappa, \; \gamma_R and v are positive constants. My current program (see below) runs and generates the correct results - however, it’s quite slow.
The one promising thing I tried was to avoid assembling the entire linear system (matrix and rhs vector), but this didn’t work. Does anyone have suggestions?
from fenics import *
import numpy as np
import matplotlib.pyplot as plt
k = 10
t_ref = 1/k
D_c = 1e-9
l_ref = np.sqrt(D_c/k)
kappa=1000 # 100
Lx = 1
Ly = 1
T = 10*t_ref
Lambda = 4000
h = 1e-5
gamma_R = (h*kappa*t_ref**2)/(Lambda*t_ref**3)
dt = t_ref/200 # Time-step
Nt = int(round(T/float(dt)))
# Create mesh and define function space
nx = ny = 50
mesh = UnitSquareMesh(nx, ny)
V = FunctionSpace(mesh, 'P', 1)
particlePosition = np.zeros((Nt,2))
particlePosition[0,0] = 0.5
particlePosition[0,1] = 0.5
phi = np.zeros(Nt+1)
phi[0] = np.pi/3
speed = 0.005
c_0 = Expression('0',degree=2)
c_D = Expression('0*x[0] + 0*x[1]',degree=1)
def boundary(x, on_boundary):
return on_boundary
bc = DirichletBC(V, c_D, boundary)
c_n = interpolate(c_0, V)
# Define variational problem
c = TrialFunction(V)
v = TestFunction(V)
a = (1 + k*dt)*c*v*dx + D_c*dt*dot( grad(c),grad(v) )*dx
L = c_n*v*dx
# Time-stepping
c = Function(V)
t = 0
grad_c = np.zeros((Nt,2))
mod_grad_c = np.zeros(Nt)
for n in range(Nt-1):
if n == 0:
pos_curr = particlePosition[n,:]
else:
pos_curr = particlePosition[n-1,:]
pt = Point(pos_curr[0],pos_curr[1])
# Compute solution
[A,b] = assemble_system(a,L,bc)
delta = PointSource(V,pt,h*dt)
delta.apply(b)
solve(A, c.vector(), b)
c_n.assign(c)
V_vec = VectorFunctionSpace(mesh,"CG",1)
gradc = project(grad(c),V_vec)
grad_c[n,:] = gradc(( pos_curr[0],pos_curr[1] ))
mod_grad_c[n] = np.sqrt(grad_c[n,0]**2 + grad_c[n,1]**2)
dphi_dt = kappa/(gamma_R)*(-grad_c[n,0]*np.sin(phi[n])
+ grad_c[n,1]*np.cos(phi[n]))
phi[n+1] = dt*dphi_dt + phi[n]
particlePosition[n+1,0] = speed*np.cos(phi[n+1])*dt + particlePosition[n,0]
particlePosition[n+1,1] = speed*np.sin(phi[n+1])*dt + particlePosition[n,1]
plt.figure()
plt.plot(particlePosition[:,0],particlePosition[:,1])
plt.gca().set_aspect('equal')