Hi All,
I try to solve an stabilized advection dominated transient transport equation (my previous post about SUPG. In addition to SUPG, I am currently experimenting artificial viscosity as indicated in this tutorial (dealii step 31).
$R_{\alpha} = (\frac{\partial T}{\partial t} + \bf{u} \cdot \nabla T - \nabla \cdot k \nabla T) T^{\alpha - 1}$ with additional viscosity(diffusion) term as $\nu_{\alpha} = \beta ||u||_{l\inf(K)} \min({h_K, h^{\alpha}_K \frac{||R_{\alpha}||_{linf(K)}}{c_R||u||_{l\inf(\Omega)} var(T) diam(\Omega)^{\alpha - 2}}})$.
As you can see, the additional viscosity term dependents on local residual on cell $K$, and is large where residual is large and small where residual is small. This involves calculation of $||u||_{l\inf}$ both in cell $K$, and in entire domain $\Omega$, and $||R_{\alpha}||_{linf(K)}$ for cell $K$.
Here are my problems, and I am sorry if it is too basic.
How do I calculate velocity norm using expression ? Here is my attempt, but it does not work. I have also tried many other methods (project instead of interpolate, add .array() in the end..... etc), it does not work. I wonder what is the appropriate way to calculate norm given a expression ?
mesh = RectangleMesh(Point(-1,-1), Point(1, 1), 100, 100, "crossed")
W = VectorFunctionSpace(mesh, "CG", 1)
velocity = Expression(("x[1]" , "-x[0]"), domain = mesh, degree=3) # convecting velocity
velocity_vector = interpolate(velocity, W)
velocity_norm = norm(velocity_vector,'linf')
My guess above calculation is for entire domain. I wonder is there any way to calculate locally? Further, because residual changes respect to time and iterations. Thus, do I need to implement it during the time stepping loop ?
I have the similar question regarding to the output of cellSize(mesh). Is it a local mesh size, or averaged global mesh size ?
Any help will be greatly appreciated! I have attached my complete code as follow:
from dolfin import *
#read mesh info
mesh = RectangleMesh(Point(-1,-1), Point(1, 1), 100, 100, "crossed")
V = FunctionSpace(mesh, "CG", 1)
W = VectorFunctionSpace(mesh, "CG", 1)
tol = 1e-14
# initial condition
ic= Expression("((pow(x[0]+0.3,2)+pow(x[1]+0.3,2))<0.2*0.2)?(1.0):(0.0)", domain=mesh, degree = 3)
mesh = RectangleMesh(Point(-1,-1), Point(1, 1), 100, 100, "crossed")
velocity = Expression(("x[1]" , "-x[0]"), domain = mesh, degree=3) # convecting velocity
velocity_vector = interpolate(velocity, W)
velocity_norm = norm(velocity_vector,'linf')
# Define trial and test function and solution at previous time-step
u = Function(V) # set as nonlinear term
v = TestFunction(V)
u0 = Function(V)
#initial condition
ic= Expression("((pow(x[0]-0.2,2)+pow(x[1]-0.2,2))<0.1*0.1)?(1.0):(0.0)", domain=mesh, degree = 3)
u0.interpolate(ic)
# Crank Nicolson
u_mid = 0.5*(u0 + u)
# Equation coefficients
c = Constant(0.000000001)
h = CellSize(mesh)
t_end = 0.5
dt = 0.001
# Calculation of artifical viscosity
alpha = 1.0 # stablization parameters
beta = 0.017 * 2.0 # stablization parameters
R = abs((u - u0 + dt*(dot(velocity, grad(u_mid)) - c*div(grad(u_mid))))*pow(u_mid, alpha - 1.0)) # residual
c_R = pow(2.0, (4.0 - 2.0*alpha)/2.0) # constant
var_T = u.vector().array().max() - u.vector().array().min()# Note: u max - u min over entire domain
h_alpha = pow(h, alpha)*norm(R, 'linf')/(c_R*norm(velocity_vector,'linf')* var_T * pow(h, alpha - 2)) # Note: Here Linf of velocity is over entire domian but norm (R) should be local to each cell
nu = beta * norm(velocity_vector,'linf') * min(h, h_alpha)
# Galerkin variational problem
F = v*(u - u0)*dx + dt*(v*dot(velocity, grad(u_mid))*dx + (c + nu)*dot(grad(v), grad(u_mid))*dx)
# Time-stepping
t = 0.0
k = 0
while t < t_end:
# Solve the problem
solve(F == 0, u)
# Move to next time step
u0.assign(u)
t += dt
k += 1