Dear dengzhekai,
few comments:
- It is very skeptical, to use degree=3 for constant Expression :)
- I do not understand your strange use of initial conditions.
- Your intuition is right, condition
- u*(1.0-u)*v*dsTop - u*(1.0-u)*v*dsBottom
is not good. The normals are oriented in opposite way on top and bottom boundary! You should change it to - u*(1.0-u)*v*dsTop + u*(1.0-u)*v*dsBottom
.
I have changed your code with the above adjustments to:
from dolfin import *
# Create mesh and build function space
mesh = UnitSquareMesh(50, 50, 'crossed')
V = FunctionSpace(mesh, "Lagrange", 1)
# Create boundary markers
boundary_parts = FacetFunction('size_t', mesh)
left = AutoSubDomain(lambda x: near(x[0], 0.0))
top = AutoSubDomain(lambda x: near(x[1], 1.0))
bottom = AutoSubDomain(lambda x: near(x[1], 0.0))
left .mark(boundary_parts, 1)
top .mark(boundary_parts, 2)
bottom.mark(boundary_parts, 3)
# initial condition
ic = Expression("0.5", degree=0)
# Equation coefficients
Pe = Constant(10.) # Pe number
velocity = Expression(("x[1]", "0"), degree=3) # convecting velocity
local_shear_rate = Expression(("0", "1"), degree=3) #local shear rate
# Define boundary measure on Neumann part of boundary
dsTop = Measure("ds", subdomain_id=2, subdomain_data=boundary_parts)
dsBottom = Measure("ds", subdomain_id=3, subdomain_data=boundary_parts)
def separation_v(u):
return local_shear_rate*(1.0 - u)
# Define steady part of the equation
def operator(u, v):
return 1.0/Pe*inner(u.dx(1), v.dx(1))*dx + dot(velocity, grad(u))*v*dx + dot(local_shear_rate, grad(u*(1.0-u)))*v*dx - u*(1.0-u)*v*dsTop + u*(1.0-u)*v*dsBottom
# Define trial and test function and solution at previous time-step
u = Function(V) # set as nonlinear term
v = TestFunction(V)
u0 = Function(V)
# Time-stepping parameters
t_end = 1
dt = 0.05
theta = Constant(0.5) # Crank-Nicolson scheme
# Define time discretized equation
F = (1.0/dt)*inner(u-u0, v)*dx + theta*operator(u, v) + (1.0-theta)*operator(u0, v)
# Define boundary condition
bc = DirichletBC(V, Constant(0.5), boundary_parts, 1)
# Prepare initial condition
u0.interpolate(ic)
# Create file for storing results
vtkfile = File('mass_transfer/mass_transfer.pvd')
# Time-stepping
t = 0.0
while t < t_end:
# Solve the problem
solve(F == 0, u, bc)
# Store solution to file and plot
u.rename("u", "concentration")
vtkfile << u
# Move to next time step
u0.assign(u)
t += dt
Do you expect (after some time) pictures like this?