# Copyright (C) 2007 Marie Rognes
#
# This file is part of FFC.
#
# FFC is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# FFC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with FFC. If not, see <http://www.gnu.org/licenses/>.
#
# The bilinear form a(u, v) and linear form L(v) for the Hodge Laplace
# problem using 0- and 1-forms. Intended to demonstrate use of N1curl
# elements.

# Compile this form with FFC: ffc VectorLaplaceGradCurl.ufl

def HodgeLaplaceGradCurl(element, felement):
    """This is a formulation of the Hodge Laplacian using k=1 and n=3,
    i.e 0-forms and 1-forms in 3D.

    Appropriate elements are

    GRAD \times CURL =
         Lagrange_r \ times Ned^1_{r}
         Lagrange_{r+1} \ times Ned^2_{r}
    """

    (sigma, u) = TrialFunctions(element)
    (tau, v) = TestFunctions(element)
    f = Coefficient(felement)
    a = (inner(sigma, tau) - inner(grad(tau), u) +
        inner(grad(sigma), v) + inner(curl(u), curl(v)))*dx
    L = inner(f, v)*dx
    return [a, L]

shape = tetrahedron
order = 1

GRAD = FiniteElement("Lagrange", shape, order)
CURL = FiniteElement("N1curl", shape, order)
VectorLagrange = VectorElement("Lagrange", shape, order+1)

[a, L] = HodgeLaplaceGradCurl(GRAD * CURL, VectorLagrange)
