# Copyright (c) 2006 Johan Hoffman 
# Licensed under the GNU GPL Version 2
#
# First added:  2006-11-01
#
# The dual momentum equation for the incompressible 
# Navier-Stokes equations using cG(1)cG(1)
#
# Compile this form with FFC: ffc NSEDualMomentum2D.form.

name = "NSEDualMomentum2D"
scalar = FiniteElement("Lagrange", "triangle", 1)
vector = FiniteElement("Vector Lagrange", "triangle", 1)
constant_scalar = FiniteElement("Discontinuous Lagrange", "triangle", 0)

v      = TestFunction(vector)      # test basis function
U      = TrialFunction(vector)     # trial basis function
up     = Function(vector)          # primal velocity
u0     = Function(vector)          # velocity from previous time step
f      = Function(vector)          # force term
p      = Function(scalar)          # pressure
delta1 = Function(constant_scalar) # stabilization parameter
delta2 = Function(constant_scalar) # stabilization parameter

k  = Constant()	# time step
nu = Constant() # viscosity

um = mean(up)   # cell mean value of primal velocity

i0 = Index()    # index for tensor notation
i1 = Index()    # index for tensor notation
i2 = Index()    # index for tensor notation

# Galerkin discretization of bilinear form  
G_a  = (- dot(v, U) + k*nu*0.5*dot(grad(v), grad(U)) - 0.5*k*v[i0]*up[i1]*U[i0].dx(i1) + 0.5*k*v[i0]*up[i1].dx(i0)*U[i1])*dx
# Least squares stabilization of bilinear form  
SD_a = (delta1*k*0.5*um[i1]*v[i0].dx(i1)*um[i2]*U[i0].dx(i2) + delta1*k*0.5*up[i1].dx(i0)*v[i1]*up[i2].dx(i0)*U[i2] + delta2*k*0.5*div(v)*div(U))*dx

# Galerkin discretization of linear form  
G_L  = (- dot(v, u0) + k*dot(v, f) + k*div(v)*p - k*nu*0.5*dot(grad(v), grad(u0)) + 0.5*k*v[i0]*up[i1]*u0[i0].dx(i1) -  + 0.5*k*v[i0]*up[i1].dx(i0)*u0[i1])*dx
# Least squares stabilization of linear form
SD_L = (- delta1*k*0.5*um[i1]*v[i0].dx(i1)*um[i2]*u0[i0].dx(i2) - delta1*k*0.5*up[i1].dx(i0)*v[i1]*up[i2].dx(i0)*u0[i2] - delta2*k*0.5*div(v)*div(u0))*dx

# Bilinear and linear forms
a = G_a + SD_a
L = G_L + SD_L

