Below I have pasted the implementations of the cases with and without the LUSolver. Both the cases work fine, and I get the desired results. All I am trying to understand is the reason behind the different syntax in the function calculateNorm for the cases with and without the use LUSolver.
The case where I have not used the LUSolver: Here I have to project back the solution on the function spaces, in the function calculateNorm (otherwise I get an error " âSumâ object has no attribute âvectorâ " even if I give True as an argument to split function )
import matplotlib.pyplot as plt
from dolfin import *
from mshr import *
import logging
import time
mesh = Mesh("../meshes/annulus.xml")
V = VectorElement("Lagrange", mesh.ufl_cell(), 2)
Q = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
W = FunctionSpace(mesh,MixedElement([V,Q,Q,Q,Q]))
Re = Constant(1e-2) # Reynolds number
m = 0
debye = 0.1
kappa = 1.0
tol=0.1
tolout = 100.0
domain_end = 1000.0
def walls(x,on_boundary):
return on_boundary and near(x[0]**2 + x[1]**2,1.0,tol)
def farfield(x,on_boundary):
return on_boundary and near(sqrt(x[0]**2 + x[1]**2),domain_end,tolout)
beta = 1
bc_u_walls = DirichletBC(W.sub(0),Constant((0.0,0.0)),walls)
bc_u_farfield = DirichletBC(W.sub(0),Constant((0.0,0.0)),farfield)
bc_phi_walls = DirichletBC(W.sub(4),Constant(0.0),walls)
bc_phi_farfield = DirichletBC(W.sub(4),Expression("-beta*x[0]",beta=1,degree=2),farfield)
bc_c_farfield = DirichletBC(W.sub(2),Constant(2.0),farfield)
bc_q_farfield = DirichletBC(W.sub(3),Constant(0.0),farfield)
bcs = [bc_u_walls,bc_u_farfield,bc_c_farfield,bc_q_farfield,bc_phi_walls,bc_phi_farfield]
parameters["form_compiler"]["cpp_optimize"] = True
parameters["form_compiler"]["quadrature_degree"] = 3
def evolve(old_var,dt):
var,dvar = Function(W),TestFunction(W)
u,p,c,q,phi = split(var)
du,dp,dc,dq,dphi = split(dvar)
old_u,old_p,old_c,old_q,old_phi = split(old_var)
Res = (c-old_c)*dc*dx + dt*inner(old_u,grad(c))*dc*dx + kappa*dt*(inner(grad(c),grad(dc))*dx +\
old_q*inner(grad(phi),grad(dc))*dx)
Res += (q-old_q)*dq*dx + dt*inner(old_u,grad(q))*dq*dx + kappa*dt*(inner(grad(q),grad(dq))*dx +\
old_c*inner(grad(phi),grad(dq))*dx)
Res += inner(grad(phi),grad(dphi))*dx - (old_q/(2*debye**2))*dphi*dx
Res += Re*(inner(u-old_u,du)*dx + inner(du,grad(old_u)*old_u)*dt*dx) - p*div(du)*dt*dx +\
dt*inner(grad(u),grad(du))*dx - old_q*dt*inner(grad(phi),du)*dx + dt*dp*div(u)*dx
var.assign(old_var)
solve(Res==0,var,bcs)
return var
beta=1.0
var_init = Expression(("0","0","0","2","0","-beta*x[0]"),beta=beta,degree=2)
old_var = interpolate(var_init,W)
def calculateNorm(old_var,var):
old_u,old_p,old_c,old_q,old_phi = old_var.split()
u,p,c,q,phi = var.split()
U = project((u-old_u),VectorFunctionSpace(mesh, "CG", 2))
C = project((c-old_c),FunctionSpace(mesh, "CG", 1))
charge = project((q-old_q),FunctionSpace(mesh, "CG", 1))
eps_u = norm(U.vector())
eps_c = norm(C.vector())
eps_q = norm(charge.vector())
return max(set([eps_u,eps_c,eps_q]))
t = 0
dt = 0.01
res = 1
eps = 1e-8
i = 0
while res > eps:
i = i+1
t = t+dt
st = time.time()
var = evolve(old_var,dt)
et = time.time()
res = calculateNorm(old_var,var)
print(res)
old_var.assign(var)
The case where I have implemented the LUSolver. Unless I donât put True as an argument to the split function (in the calculateNorm function), norm isnât computed correctly.
import matplotlib.pyplot as plt
from dolfin import *
from mshr import *
import logging
import time
# Importing mesh
mesh = Mesh("../meshes/annulus.xml")
# Defining function space for fluid dynamics
V = VectorElement("Lagrange", mesh.ufl_cell(), 2)
Q = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
W = FunctionSpace(mesh,MixedElement([V,Q,Q,Q,Q]))
Re = Constant(1.0) # Reynolds number
m = 0
debye = 0.1
kappa = 1.0
# Boundaries
tol=0.1
tolout = 100.0
domain_end = 1000.0
def walls(x,on_boundary):
return on_boundary and near(x[0]**2 + x[1]**2,1.0,tol)
def farfield(x,on_boundary):
return on_boundary and near(sqrt(x[0]**2 + x[1]**2),domain_end,tolout)
# Boundary conditions
beta = 1
bc_u_walls = DirichletBC(W.sub(0),Constant((0.0,0.0)),walls)
bc_u_farfield = DirichletBC(W.sub(0),Constant((0.0,0.0)),farfield)
bc_phi_walls = DirichletBC(W.sub(4),Constant(0.0),walls)
bc_phi_farfield = DirichletBC(W.sub(4),Expression("-beta*x[0]",beta=1,degree=2),farfield)
bc_c_farfield = DirichletBC(W.sub(2),Constant(2.0),farfield)
bc_q_farfield = DirichletBC(W.sub(3),Constant(0.0),farfield)
bcs = [bc_c_farfield,bc_q_farfield,bc_phi_walls,bc_phi_farfield,bc_u_walls,bc_u_farfield]
parameters["form_compiler"]["cpp_optimize"] = True
parameters["form_compiler"]["quadrature_degree"] = 3
beta=1.0
var_init = Expression(("0","0","0","2","0","-beta*x[0]"),beta=beta,degree=2)
old_var = interpolate(var_init,W)
t=0
dt = 0.01
res = 1
eps = 1e-8
i = 0
var,dvar = TrialFunction(W),TestFunction(W)
u,p,c,q,phi = split(var)
du,dp,dc,dq,dphi = split(dvar)
old_u,old_p,old_c,old_q,old_phi = split(old_var)
Res = (c-old_c)*dc*dx + dt*inner(old_u,grad(c))*dc*dx + kappa*dt*(inner(grad(c),grad(dc))*dx +\
old_q*inner(grad(old_phi),grad(dc))*dx)
Res += (q-old_q)*dq*dx + dt*inner(old_u,grad(q))*dq*dx + kappa*dt*(inner(grad(q),grad(dq))*dx +\
old_c*inner(grad(old_phi),grad(dq))*dx)
Res += inner(grad(phi),grad(dphi))*dx - (q/(2*debye**2))*dphi*dx
Res += Re*(inner(u-old_u,du)*dx + inner(du,grad(old_u)*old_u)*dt*dx) - p*div(du)*dt*dx +\
dt*inner(grad(u),grad(du))*dx - old_q*dt*inner(grad(old_phi),du)*dx + dt*dp*div(u)*dx
a = lhs(Res)
ll = rhs(Res)
A = assemble(a)
[bc.apply(A) for bc in bcs]
solver = LUSolver(A)
varTilde = Function(W)
varTilde.assign(old_var)
def calculateNorm(old_var,var):
(old_u,old_p,old_c,old_q,old_phi) = old_var.split(True)
(u,p,c,q,phi) = var.split(True)
eps_u = norm((u.vector()-old_u.vector()),'l2')
eps_c = norm((c.vector()-old_c.vector()),'l2')
eps_q = norm((q.vector()-old_q.vector()),'l2')
return max(set([eps_u,eps_c,eps_q]))
while res > eps:
i = i+1
t = t+dt
st = time.time()
b = assemble(ll)
[bc.apply(b) for bc in bcs]
solver.solve(varTilde.vector(),b)
et = time.time()
res = calculateNorm(old_var,varTilde)
print(res)
old_var.assign(varTilde)
Pardon me if I have missed out on anything, and I am thankful to you for your time and patience.