Hey. I have a nonlocal PDE of the form
\partial_t y - \nu \Delta y + y + aY + b \cdot \nabla Y + \int_\Omega Y =0
with Neumann boundary. Each solver step takes 14-15 seconds right now, which seems too slow, please find a minimal running example below. The main issue lies in calling solve(A==0,Y) at each time step, I guess, and not specifying any solver. Moreover, I have to assemble in each time step the term \int_\Omega Y in the nonlocal term, I am not sure if there is a better way to do it. Because of this, I am also not sure how to write the problem in a class NonlinearVariationalProblem (as in this question) since the problem has to be updated in each time step. I am happy for any help.
from dolfin import *
from fenics import *
from mshr import *
import time
dt = 1e-3
number_time_steps = 20
final_time = number_time_steps*dt
mesh_resolution = 100
class InitialConditions(UserExpression):
def eval(self, values, x):
values[0] = 1-2*x[0]*x[1]
mesh = UnitSquareMesh.create(mesh_resolution,mesh_resolution, CellType.Type.quadrilateral)
x = SpatialCoordinate(mesh)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
P1space = FunctionSpace(mesh, "Lagrange", 1)
dY = TrialFunction(P1space)
test = TestFunction(P1space)
Y = Function(P1space)
Y0 = Function(P1space)
Y_initial = InitialConditions(degree=1)
Y = interpolate(Y_initial, P1space)
Y0 = interpolate(Y_initial, P1space)
a_fun = Expression('-1.5 + x[0] - abs(sin(6*t+x[0]))', t=0, degree=2)
b1_fun = Expression("x[0]+x[1]", degree=2)
b2_fun = Expression("abs(cos(6*t) * x[0] * x[1])", t=0, degree=2)
weak = (Y * test * dx
- Y0 * test * dx
+ dt * 0.1 * inner(grad(Y),grad(test)) * dx
+ dt * Y * test * dx
+ dt * a_fun * Y * test * dx #a
+ dt * b1_fun * Y.dx(0) * test * dx #b1
+ dt * b2_fun * Y.dx(1) * test * dx #b2
)
testdx = test * dx
Ydx = Y * dx
t = 0.0
while (t < final_time):
t += dt
tt = time.time()
a_fun.t = t
b1_fun.t = t
b2_fun.t = t
assemble_Ydx = assemble(Ydx)
nonlocalterm = dt * assemble_Ydx * testdx
solve(weak + nonlocalterm == 0, Y)
Y0.assign(Y)
elapsed = time.time() - tt
print("-------It took "+str(elapsed)+" seconds-------")