Пример #1
0
def test_curl_curl(compile_args):
    V = ufl.FiniteElement("N1curl", "triangle", 2)
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = ufl.inner(ufl.curl(u), ufl.curl(v)) * ufl.dx

    forms = [a]
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(forms, cffi_extra_compile_args=compile_args)
Пример #2
0
def HodgeLaplaceGradCurl(element, felement):
    tau, v = TestFunctions(element)
    sigma, u = TrialFunctions(element)
    f = Coefficient(felement)

    a = (inner(tau, sigma) - inner(grad(tau), u) + inner(v, grad(sigma)) +
         inner(curl(v), curl(u))) * dx
    L = inner(v, f) * dx

    return a, L
Пример #3
0
def norm(v, norm_type="L2", mesh=None):
    """Compute the norm of ``v``.

    :arg v: a :class:`.Function` to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    * L2

       .. math::

          ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

    * H1

       .. math::

          ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

    * Hdiv

       .. math::

          ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

    * Hcurl

       .. math::

          ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
    """
    assert isinstance(v, function.Function)

    typ = norm_type.lower()
    mesh = v.function_space().mesh()
    dx = mesh._dx
    if typ == 'l2':
        form = inner(v, v)*dx
    elif typ == 'h1':
        form = inner(v, v)*dx + inner(grad(v), grad(v))*dx
    elif typ == "hdiv":
        form = inner(v, v)*dx + div(v)*div(v)*dx
    elif typ == "hcurl":
        form = inner(v, v)*dx + inner(curl(v), curl(v))*dx
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return sqrt(solving.assemble(form))
Пример #4
0
def norm(v, norm_type="L2", mesh=None):
    """Compute the norm of ``v``.

    :arg v: a :class:`.Function` to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    * L2

       .. math::

          ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

    * H1

       .. math::

          ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

    * Hdiv

       .. math::

          ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

    * Hcurl

       .. math::

          ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
    """
    assert isinstance(v, function.Function)

    typ = norm_type.lower()
    mesh = v.function_space().mesh()
    dx = mesh._dx
    if typ == 'l2':
        form = inner(v, v)*dx
    elif typ == 'h1':
        form = inner(v, v)*dx + inner(grad(v), grad(v))*dx
    elif typ == "hdiv":
        form = inner(v, v)*dx + div(v)*div(v)*dx
    elif typ == "hcurl":
        form = inner(v, v)*dx + inner(curl(v), curl(v))*dx
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return sqrt(assemble(form))
Пример #5
0
def norm(v, norm_type="L2", degree=None):
    """Compute the norm of ``v``.

	:arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
	:arg norm_type: the type of norm to compute, see below for
		 options.

	Available norm types are:

	* L2

	   .. math::

		  ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

	* H1

	   .. math::

		  ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

	* Hdiv

	   .. math::

		  ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

	* Hcurl

	   .. math::

		  ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
	"""

    if not degree == None:
        dxn = dx(2 * degree + 1)
    else:
        dxn = dx
    typ = norm_type.lower()
    if typ == 'l2':
        form = inner(v, v) * dxn
    elif typ == 'h1':
        form = inner(v, v) * dxn + inner(grad(v), grad(v)) * dxn
    elif typ == "hdiv":
        form = inner(v, v) * dxn + div(v) * div(v) * dxn
    elif typ == "hcurl":
        form = inner(v, v) * dxn + inner(curl(v), curl(v)) * dxn
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    normform = ZeroForm(form)
    return sqrt(normform.assembleform())
Пример #6
0
def r2_norm(v, func_degree=None, norm_type="L2", mesh=None):
    """
    This function is a modification of FEniCS's built-in norm function that adopts the :math:`r^2dr`
    measure as opposed to the standard Cartesian :math:`dx` measure.

    For documentation and usage, see the 
    original module <https://bitbucket.org/fenics-project/dolfin/src/master/python/dolfin/fem/norms.py>_.

    .. note:: Note the extra argument func_degree: this is used to interpolate the :math:`r^2` 
              Expression to the same degree as used in the definition of the Trial and Test function
              spaces.

    """


    # Get mesh from function
    if isinstance(v, cpp.function.Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Define integration measure and domain
    dx = ufl.dx(mesh)

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())
    
    elif (isinstance(v, Coefficient) and isinstance(v, Function)):
        # DS: HERE IS WHERE I MODIFY
        r2 = Expression('pow(x[0],2)', degree=func_degree)
    
        if norm_type.lower() == "l2":
            M = v**2 * r2 * dx
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2) * r2 * dx
        elif norm_type.lower() == "h10":
            M = grad(v)**2 * r2 * dx
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2) * r2 * dx
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2 * r2 * dx
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2) * r2 * dx
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2 * r2 * dx
        else:
            raise ValueError("Unknown norm type {}".format(str(norm_type)))
    else:
        raise TypeError("Do not know how to compute norm of {}".format(str(v)))

    # Assemble value and return
    return sqrt(assemble(M))
Пример #7
0
def norm(v, norm_type="L2", mesh=None):
    """Compute the norm of ``v``.

    :arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    * L2

       .. math::

          ||v||_{L^2}^2 = \int (v, v) \mathrm{d}x

    * H1

       .. math::

          ||v||_{H^1}^2 = \int (v, v) + (\\nabla v, \\nabla v) \mathrm{d}x

    * Hdiv

       .. math::

          ||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\\nabla\cdot v, \\nabla \cdot v) \mathrm{d}x

    * Hcurl

       .. math::

          ||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\\nabla \wedge v, \\nabla \wedge v) \mathrm{d}x
    """
    typ = norm_type.lower()
    if typ == 'l2':
        form = inner(v, v)*dx
    elif typ == 'h1':
        form = inner(v, v)*dx + inner(grad(v), grad(v))*dx
    elif typ == "hdiv":
        form = inner(v, v)*dx + div(v)*div(v)*dx
    elif typ == "hcurl":
        form = inner(v, v)*dx + inner(curl(v), curl(v))*dx
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return sqrt(assemble(form))
Пример #8
0
def test_curl(space_type, order):
    """Test that curl is consistent for different cell permutations of a tetrahedron."""

    tdim = cpp.mesh.cell_dim(CellType.tetrahedron)
    points = unit_cell_points(CellType.tetrahedron)

    spaces = []
    results = []
    cell = list(range(len(points)))
    # Assemble vector on 5 randomly numbered cells
    for i in range(5):
        shuffle(cell)

        domain = ufl.Mesh(
            ufl.VectorElement("Lagrange",
                              cpp.mesh.to_string(CellType.tetrahedron), 1))
        mesh = create_mesh(MPI.COMM_WORLD, [cell], points, domain)
        mesh.topology.create_connectivity_all()

        V = FunctionSpace(mesh, (space_type, order))
        v = ufl.TestFunction(V)

        f = ufl.as_vector(tuple(1 if i == 0 else 0 for i in range(tdim)))
        form = ufl.inner(f, ufl.curl(v)) * ufl.dx
        result = fem.assemble_vector(form)
        spaces.append(V)
        results.append(result.array)

    # Check that all DOFs on edges agree
    V = spaces[0]
    result = results[0]
    connectivity = V.mesh.topology.connectivity(1, 0)
    for i, edge in enumerate(V.mesh.topology.connectivity(tdim, 1).links(0)):
        vertices = connectivity.links(edge)
        values = sorted([
            result[V.dofmap.cell_dofs(0)[a]]
            for a in V.dofmap.dof_layout.entity_dofs(1, i)
        ])

        for s, r in zip(spaces[1:], results[1:]):
            c = s.mesh.topology.connectivity(1, 0)
            for j, e in enumerate(
                    s.mesh.topology.connectivity(tdim, 1).links(0)):
                if sorted(c.links(e)) == sorted(vertices):
                    v = sorted([
                        r[s.dofmap.cell_dofs(0)[a]]
                        for a in s.dofmap.dof_layout.entity_dofs(1, j)
                    ])
                    assert np.allclose(values, v)
                    break
            else:
                continue
            break
Пример #9
0
def split_vector_laplace(cell, degree):
    m = Mesh(VectorElement('CG', cell, 1))
    if cell.cellname() in ['interval * interval', 'quadrilateral']:
        hcurl_element = FiniteElement('RTCE', cell, degree)
    elif cell.cellname() == 'triangle * interval':
        U0 = FiniteElement('RT', triangle, degree)
        U1 = FiniteElement('CG', triangle, degree)
        V0 = FiniteElement('CG', interval, degree)
        V1 = FiniteElement('DG', interval, degree - 1)
        Wa = HCurlElement(TensorProductElement(U0, V0))
        Wb = HCurlElement(TensorProductElement(U1, V1))
        hcurl_element = EnrichedElement(Wa, Wb)
    elif cell.cellname() == 'quadrilateral * interval':
        hcurl_element = FiniteElement('NCE', cell, degree)
    RT = FunctionSpace(m, hcurl_element)
    CG = FunctionSpace(m, FiniteElement('Q', cell, degree))
    sigma = TrialFunction(CG)
    u = TrialFunction(RT)
    tau = TestFunction(CG)
    v = TestFunction(RT)
    return [dot(u, grad(tau))*dx, dot(grad(sigma), v)*dx, dot(curl(u), curl(v))*dx]
Пример #10
0
def norm(v, norm_type="L2", mesh=None):
    r"""Compute the norm of ``v``.

    :arg v: a ufl expression (:class:`~.ufl.classes.Expr`) to compute the norm of
    :arg norm_type: the type of norm to compute, see below for
         options.
    :arg mesh: an optional mesh on which to compute the norm
         (currently ignored).

    Available norm types are:

    - Lp :math:`||v||_{L^p} = (\int |v|^p)^{\frac{1}{p}} \mathrm{d}x`
    - H1 :math:`||v||_{H^1}^2 = \int (v, v) + (\nabla v, \nabla v) \mathrm{d}x`
    - Hdiv :math:`||v||_{H_\mathrm{div}}^2 = \int (v, v) + (\nabla\cdot v, \nabla \cdot v) \mathrm{d}x`
    - Hcurl :math:`||v||_{H_\mathrm{curl}}^2 = \int (v, v) + (\nabla \wedge v, \nabla \wedge v) \mathrm{d}x`

    """
    typ = norm_type.lower()
    p = 2
    if typ == 'l2':
        expr = inner(v, v)
    elif typ.startswith('l'):
        try:
            p = int(typ[1:])
            if p < 1:
                raise ValueError
        except ValueError:
            raise ValueError("Don't know how to interpret %s-norm" % norm_type)
        expr = inner(v, v)
    elif typ == 'h1':
        expr = inner(v, v) + inner(grad(v), grad(v))
    elif typ == "hdiv":
        expr = inner(v, v) + div(v)*div(v)
    elif typ == "hcurl":
        expr = inner(v, v) + inner(curl(v), curl(v))
    else:
        raise RuntimeError("Unknown norm type '%s'" % norm_type)

    return assemble((expr**(p/2))*dx)**(1/p)
Пример #11
0
    def initialize(self, obj):
        A, P = obj.getOperators()
        prefix = obj.getOptionsPrefix()
        V = get_function_space(obj.getDM())
        mesh = V.mesh()

        family = str(V.ufl_element().family())
        degree = V.ufl_element().degree()
        if family != 'Raviart-Thomas' or degree != 1:
            raise ValueError(
                "Hypre ADS requires lowest order RT elements! (not %s of degree %d)"
                % (family, degree))

        P1 = FunctionSpace(mesh, "Lagrange", 1)
        NC1 = FunctionSpace(mesh, "N1curl", 1)
        # DiscreteGradient
        G = Interpolator(grad(TestFunction(P1)), NC1).callable().handle
        # DiscreteCurl
        C = Interpolator(curl(TestFunction(NC1)), V).callable().handle

        pc = PETSc.PC().create(comm=obj.comm)
        pc.incrementTabLevel(1, parent=obj)
        pc.setOptionsPrefix(prefix + "hypre_ads_")
        pc.setOperators(A, P)

        pc.setType('hypre')
        pc.setHYPREType('ads')
        pc.setHYPREDiscreteGradient(G)
        pc.setHYPREDiscreteCurl(C)
        V = VectorFunctionSpace(mesh, "Lagrange", 1)
        linear_coordinates = interpolate(SpatialCoordinate(mesh),
                                         V).dat.data_ro.copy()
        pc.setCoordinates(linear_coordinates)

        pc.setUp()
        self.pc = pc
Пример #12
0
def rD_norm(v, D=None, func_degree=None, norm_type="L2", mesh=None):
    r"""
    This function is a modification of FEniCS's built-in norm function to adopt the :math:`r^2dr`
    measure as opposed to the standard Cartesian :math:`dx` one. For documentation and usage, see the 
    `standard module <https://github.com/FEniCS/dolfin/blob/master/site-packages/dolfin/fem/norms.py>`_.

    .. note:: Note the extra argument func_degree: this is used to interpolate the :math:`r^2` 
              Expression to the same degree as used in the definition of the Trial and Test function
              spaces.

    .. note:: I am manually implementing this bug fix that is not in the current FEniCS release:
              <https://bitbucket.org/fenics-project/dolfin/commits/c438724fa5d7f19504d4e0c48695e17b774b2c2d>_

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        cpp.dolfin_error("norms.py", "compute norm",
                         "expected a GenericVector or GenericFunction")

    # Check arguments
    if not isinstance(norm_type, string_types):
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, cpp.Mesh):
        cpp.dolfin_error("norms.py", "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Get mesh from function
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Define integration measure and domain
    dx = ufl.dx(mesh)

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        # DS: HERE IS WHERE I MODIFY
        rD = Expression('pow(x[0],D-1)', D=D, degree=func_degree)

        if norm_type.lower() == "l2":
            M = v**2 * rD * dx
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2) * rD * dx
        elif norm_type.lower() == "h10":
            M = grad(v)**2 * rD * dx
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2) * rD * dx
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2 * rD * dx
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2) * rD * dx
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2 * rD * dx
        else:
            cpp.dolfin_error(
                "norms.py", "compute norm",
                "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Unknown object type. Must be a vector or a function")

    # DS CHANGED: applied this bug fix:
    # https://bitbucket.org/fenics-project/dolfin/diff/site-packages/dolfin/fem/norms.py?diff2=c438724fa5d7&at=jan/general-discrete-gradient
    # Assemble value
    # r = assemble(M, form_compiler_parameters={"representation": "quadrature"})
    r = assemble(M)

    # Check value
    if r < 0.0:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
Пример #13
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    # if not isinstance(v, (GenericVector, GenericFunction)):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "expected a GenericVector or GenericFunction")

    # Check arguments
    # if not isinstance(norm_type, string_types):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Norm type must be a string, not " +
    #                      str(type(norm_type)))
    # if mesh is not None and not isinstance(mesh, cpp.Mesh):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Expecting a Mesh, not " + str(type(mesh)))

    # Get mesh from function
    if isinstance(v, cpp.function.Function) and mesh is None:
        mesh = v.function_space().mesh()
    elif isinstance(v, MultiMeshFunction) and mesh is None:
        mesh = v.function_space().multimesh()

    # Define integration measure and domain
    if isinstance(v, MultiMeshFunction):
        dc = ufl.dx(mesh) + ufl.dC(mesh)
        assemble_func = functools.partial(assemble_multimesh, form_compiler_parameters={"representation": "quadrature"})
    else:
        dc = ufl.dx(mesh)
        assemble_func = assemble
    # Select norm type
    if isinstance(v, cpp.la.GenericVector):
        return v.norm(norm_type.lower())

    elif isinstance(v, ufl.Coefficient):
        if norm_type.lower() == "l2":
            M = v**2 * dc
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2) * dc
        elif norm_type.lower() == "h10":
            M = grad(v)**2 * dc
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2) * dc
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2 * dc
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2) * dc
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2 * dc
        else:
            raise ValueError("Unknown norm type {}".format(str(norm_type)))
    else:
        raise TypeError("Do not know how to compute norm of {}".format(str(v)))

    # Assemble value and return
    return sqrt(assemble_func(M))
Пример #14
0
import ufl
from ufl import inner, curl, dx

from minidolfin.assembling import jit_compile_form

# for fixing https://github.com/FEniCS/ffcx/pull/25

cell = ufl.tetrahedron
element = ufl.FiniteElement("Nedelec 1st kind H(curl)", cell, 3)

u = ufl.TrialFunction(element)
v = ufl.TestFunction(element)

a = inner(curl(u), curl(v)) * dx - inner(u, v) * dx

jit_compile_form(a, {
    "compiler": "ffc",
    "max_preintegrated_unrolled_table_size": 2000
})
Пример #15
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        raise TypeError, "expected a GenericVector or GenericFunction"

    # Check arguments
    if not isinstance(norm_type, str):
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, Mesh):
        cpp.dolfin_error("norms.py", "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        if norm_type.lower() == "l2":
            M = inner(v, v) * dx()
        elif norm_type.lower() == "h1":
            M = inner(v, v) * dx() + inner(grad(v), grad(v)) * dx()
        elif norm_type.lower() == "h10":
            M = inner(grad(v), grad(v)) * dx()
        elif norm_type.lower() == "hdiv":
            M = inner(v, v) * dx() + div(v) * div(v) * dx()
        elif norm_type.lower() == "hdiv0":
            M = div(v) * div(v) * dx()
        elif norm_type.lower() == "hcurl":
            M = inner(v, v) * dx() + inner(curl(v), curl(v)) * dx()
        elif norm_type.lower() == "hcurl0":
            M = inner(curl(v), curl(v)) * dx()
        else:
            cpp.dolfin_error(
                "norms.py", "compute norm",
                "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Unknown object type. Must be a vector or a function")

    # Get mesh
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Assemble value
    r = assemble(M,
                 mesh=mesh,
                 form_compiler_parameters={"representation": "quadrature"})

    # Check value
    if r < 0.0:
        cpp.dolfin_error(
            "norms.py", "compute norm",
            "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
Пример #16
0
from minidolfin.meshing import build_unit_cube_mesh
from minidolfin.dofmap import build_dofmap
from minidolfin.dofmap import build_sparsity_pattern
from minidolfin.dofmap import pattern_to_csr
from minidolfin.petsc import create_matrix_from_csr
from minidolfin.assembling import assemble

import dijitso
dijitso.set_log_level("debug")

# UFL form
element = ufl.FiniteElement("N1E", ufl.tetrahedron, 2)
u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
omega2 = 1e3
a = (ufl.inner(ufl.curl(u), ufl.curl(v)) - omega2 * ufl.dot(u, v)) * ufl.dx

# Build mesh
mesh = build_unit_cube_mesh(1, 1, 1)
tdim = mesh.reference_cell.get_dimension()
print('Number cells: {}'.format(mesh.num_entities(tdim)))

# Build dofmap
dofmap = build_dofmap(element, mesh)
print('Number dofs: {}'.format(dofmap.dim))

# Build sparsity pattern
pattern = build_sparsity_pattern(dofmap)
i, j = pattern_to_csr(pattern)
A = create_matrix_from_csr((i, j))
Пример #17
0
def norm(v, norm_type="L2", mesh=None, condition=None, boundary=False):
    r"""
    Overload Firedrake's ``norm`` function to
    allow for :math:`\ell^p` norms.

    Note that this version is case sensitive,
    i.e. ``'l2'`` and ``'L2'`` will give
    different results in general.

    :arg v: the :class:`Function` to take the norm of
    :kwarg norm_type: choose from 'l1', 'l2', 'linf',
        'L2', 'Linf', 'H1', 'Hdiv', 'Hcurl', or any
        'Lp' with :math:`p >= 1`.
    :kwarg mesh: the mesh that `v` is defined upon
    :kwarg condition: a UFL condition for specifying
        a subdomain to compute the norm over
    :kwarg boundary: should the norm be computed over
        the domain boundary?
    """
    norm_codes = {"l1": 0, "l2": 2, "linf": 3}
    if norm_type in norm_codes or norm_type == "Linf":
        if boundary:
            raise NotImplementedError("lp errors on the boundary not yet implemented.")
        if condition is not None:
            v.interpolate(condition * v)
        if norm_type == "Linf":
            with v.dat.vec_ro as vv:
                return vv.max()[1]
        else:
            with v.dat.vec_ro as vv:
                return vv.norm(norm_codes[norm_type])
    elif norm_type[0] == "l":
        raise NotImplementedError(
            "lp norm of order {:s} not supported.".format(norm_type[1:])
        )
    else:
        condition = condition or firedrake.Constant(1.0)
        dX = ufl.ds if boundary else ufl.dx
        if norm_type.startswith("L"):
            try:
                p = int(norm_type[1:])
                if p < 1:
                    raise ValueError(f"{norm_type} norm does not make sense.")
            except ValueError:
                raise ValueError(f"Don't know how to interpret {norm_type} norm.")
            return firedrake.assemble(condition * ufl.inner(v, v) ** (p / 2) * dX) ** (
                1 / p
            )
        elif norm_type.lower() == "h1":
            return ufl.sqrt(
                firedrake.assemble(
                    condition
                    * (ufl.inner(v, v) + ufl.inner(ufl.grad(v), ufl.grad(v)))
                    * dX
                )
            )
        elif norm_type.lower() == "hdiv":
            return ufl.sqrt(
                firedrake.assemble(
                    condition * (ufl.inner(v, v) + ufl.div(v) * ufl.div(v)) * dX
                )
            )
        elif norm_type.lower() == "hcurl":
            return ufl.sqrt(
                firedrake.assemble(
                    condition
                    * (ufl.inner(v, v) + ufl.inner(ufl.curl(v), ufl.curl(v)))
                    * dX
                )
            )
        else:
            raise ValueError(f"Unknown norm type {norm_type}")
Пример #18
0
def test_curl(space_type, order):
    """Test that curl is consistent for different cell permutations of a tetrahedron."""

    tdim = cpp.mesh.cell_dim(CellType.tetrahedron)
    points = unit_cell_points(CellType.tetrahedron)

    spaces = []
    results = []
    cell = list(range(len(points)))
    random.seed(2)

    # Assemble vector on 5 randomly numbered cells
    for i in range(5):
        random.shuffle(cell)

        domain = ufl.Mesh(
            ufl.VectorElement("Lagrange",
                              cpp.mesh.to_string(CellType.tetrahedron), 1))
        mesh = create_mesh(MPI.COMM_WORLD, [cell], points, domain)

        V = FunctionSpace(mesh, (space_type, order))
        v = ufl.TestFunction(V)

        f = ufl.as_vector(tuple(1 if i == 0 else 0 for i in range(tdim)))
        form = ufl.inner(f, ufl.curl(v)) * ufl.dx
        result = fem.assemble_vector(form)
        spaces.append(V)
        results.append(result.array)

    # Set data for first space
    V0 = spaces[0]
    c10_0 = V.mesh.topology.connectivity(1, 0)

    # Check that all DOFs on edges agree

    # Loop over cell edges
    for i, edge in enumerate(V0.mesh.topology.connectivity(tdim, 1).links(0)):

        # Get the edge vertices
        vertices0 = c10_0.links(edge)  # Need to map back

        # Get assembled values on edge
        values0 = sorted([
            result[V0.dofmap.cell_dofs(0)[a]]
            for a in V0.dofmap.dof_layout.entity_dofs(1, i)
        ])

        for V, result in zip(spaces[1:], results[1:]):
            # Get edge->vertex connectivity
            c10 = V.mesh.topology.connectivity(1, 0)

            # Loop over cell edges
            for j, e in enumerate(
                    V.mesh.topology.connectivity(tdim, 1).links(0)):
                if sorted(c10.links(e)) == sorted(
                        vertices0):  # need to map back c.links(e)
                    values = sorted([
                        result[V.dofmap.cell_dofs(0)[a]]
                        for a in V.dofmap.dof_layout.entity_dofs(1, j)
                    ])
                    assert np.allclose(values0, values)
                    break
            else:
                continue
            break
Пример #19
0
def norm(v, norm_type="L2", mesh=None):
    r"""
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    # if not isinstance(v, (GenericVector, GenericFunction)):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "expected a GenericVector or GenericFunction")

    # Check arguments
    # if not isinstance(norm_type, string_types):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Norm type must be a string, not " +
    #                      str(type(norm_type)))
    # if mesh is not None and not isinstance(mesh, cpp.Mesh):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Expecting a Mesh, not " + str(type(mesh)))

    # Get mesh from function
    if isinstance(v, cpp.function.Function) and mesh is None:
        mesh = v.function_space().mesh()
    elif isinstance(v, MultiMeshFunction) and mesh is None:
        mesh = v.function_space().multimesh()

    # Define integration measure and domain
    if isinstance(v, MultiMeshFunction):
        dc = ufl.dx(mesh) + ufl.dC(mesh)
        assemble_func = functools.partial(assemble_multimesh, form_compiler_parameters={"representation": "quadrature"})
    else:
        dc = ufl.dx(mesh)
        assemble_func = assemble
    # Select norm type
    if isinstance(v, cpp.la.GenericVector):
        return v.norm(norm_type.lower())

    elif isinstance(v, ufl.Coefficient):
        if norm_type.lower() == "l2":
            M = v**2 * dc
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2) * dc
        elif norm_type.lower() == "h10":
            M = grad(v)**2 * dc
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2) * dc
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2 * dc
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2) * dc
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2 * dc
        else:
            raise ValueError("Unknown norm type {}".format(str(norm_type)))
    else:
        raise TypeError("Do not know how to compute norm of {}".format(str(v)))

    # Assemble value and return
    return sqrt(assemble_func(M))
Пример #20
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    # if not isinstance(v, (GenericVector, GenericFunction)):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "expected a GenericVector or GenericFunction")

    # Check arguments
    # if not isinstance(norm_type, string_types):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Norm type must be a string, not " +
    #                      str(type(norm_type)))
    # if mesh is not None and not isinstance(mesh, cpp.Mesh):
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Expecting a Mesh, not " + str(type(mesh)))

    # Get mesh from function
    if isinstance(v, cpp.function.Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Define integration measure and domain
    dx = ufl.dx(mesh)

    # Select norm type
    if isinstance(v, cpp.la.GenericVector):
        return v.norm(norm_type.lower())

    elif isinstance(v, ufl.Coefficient):
        if norm_type.lower() == "l2":
            M = v**2*dx
        elif norm_type.lower() == "h1":
            M = (v**2 + grad(v)**2)*dx
        elif norm_type.lower() == "h10":
            M = grad(v)**2*dx
        elif norm_type.lower() == "hdiv":
            M = (v**2 + div(v)**2)*dx
        elif norm_type.lower() == "hdiv0":
            M = div(v)**2*dx
        elif norm_type.lower() == "hcurl":
            M = (v**2 + curl(v)**2)*dx
        elif norm_type.lower() == "hcurl0":
            M = curl(v)**2*dx
        # else:
        #     cpp.dolfin_error("norms.py",
        #                      "compute norm",
        #                      "Unknown norm type (\"%s\") for functions"
        #                      % str(norm_type))
    # else:
    #     cpp.dolfin_error("norms.py",
    #                      "compute norm",
    #                      "Unknown object type. Must be a vector or a function")

    # Assemble value
    r = assemble(M)

    # Check value
    if r < 0.0:
        pass
        # cpp.dolfin_error("norms.py",
        #                  "compute norm",
        #                  "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
Пример #21
0
def norm(v, norm_type="L2", mesh=None):
    """
    Return the norm of a given vector or function.

    *Arguments*
        v
            a :py:class:`Vector <dolfin.cpp.Vector>` or
            a :py:class:`Function <dolfin.functions.function.Function>`.
        norm_type
            see below for alternatives.
        mesh
            optional :py:class:`Mesh <dolfin.cpp.Mesh>` on
            which to compute the norm.

    If the norm type is not specified, the standard :math:`L^2` -norm
    is computed. Possible norm types include:

    *Vectors*

    ================   =================  ================
    Norm               Usage
    ================   =================  ================
    :math:`l^2`        norm(x, 'l2')      Default
    :math:`l^1`        norm(x, 'l1')
    :math:`l^\infty`   norm(x, 'linf')
    ================   =================  ================

    *Functions*

    ================  =================  =================================
    Norm              Usage              Includes the :math:`L^2` -term
    ================  =================  =================================
    :math:`L^2`       norm(v, 'L2')      Yes
    :math:`H^1`       norm(v, 'H1')      Yes
    :math:`H^1_0`     norm(v, 'H10')     No
    :math:`H` (div)   norm(v, 'Hdiv')    Yes
    :math:`H` (div)   norm(v, 'Hdiv0')   No
    :math:`H` (curl)  norm(v, 'Hcurl')   Yes
    :math:`H` (curl)  norm(v, 'Hcurl0')  No
    ================  =================  =================================

    *Examples of usage*

    .. code-block:: python

        v = Function(V)
        x = v.vector()

        print norm(x, 'linf')   # print the infinity norm of vector x

        n = norm(v)             # compute L^2 norm of v
        print norm(v, 'Hdiv')   # print H(div) norm of v
        n = norm(v, 'H1', mesh) # compute H^1 norm of v on given mesh

    """

    if not isinstance(v, (GenericVector, GenericFunction)):
        raise TypeError, "expected a GenericVector or GenericFunction"

    # Check arguments
    if not isinstance(norm_type, str):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Norm type must be a string, not " + str(type(norm_type)))
    if mesh is not None and not isinstance(mesh, Mesh):
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Expecting a Mesh, not " + str(type(mesh)))

    # Select norm type
    if isinstance(v, GenericVector):
        return v.norm(norm_type.lower())

    elif (isinstance(v, Coefficient) and isinstance(v, GenericFunction)):
        if norm_type.lower() == "l2":
            M = inner(v, v)*dx()
        elif norm_type.lower() == "h1":
            M = inner(v, v)*dx() + inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "h10":
            M = inner(grad(v), grad(v))*dx()
        elif norm_type.lower() == "hdiv":
            M = inner(v, v)*dx() + div(v)*div(v)*dx()
        elif norm_type.lower() == "hdiv0":
            M = div(v)*div(v)*dx()
        elif norm_type.lower() == "hcurl":
            M = inner(v, v)*dx() + inner(curl(v), curl(v))*dx()
        elif norm_type.lower() == "hcurl0":
            M = inner(curl(v), curl(v))*dx()
        else:
            cpp.dolfin_error("norms.py",
                             "compute norm",
                             "Unknown norm type (\"%s\") for functions" % str(norm_type))
    else:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Unknown object type. Must be a vector or a function")

    # Get mesh
    if isinstance(v, Function) and mesh is None:
        mesh = v.function_space().mesh()

    # Assemble value
    r = assemble(M, mesh=mesh, form_compiler_parameters={"representation": "quadrature"})

    # Check value
    if r < 0.0:
        cpp.dolfin_error("norms.py",
                         "compute norm",
                         "Square of norm is negative, might be a round-off error")
    elif r == 0.0:
        return 0.0
    else:
        return sqrt(r)
Пример #22
0
def test_curl_curl_eigenvalue(family, order):
    """curl curl eigenvalue problem.

    Solved using H(curl)-conforming finite element method.
    See https://www-users.cse.umn.edu/~arnold/papers/icm2002.pdf for details.
    """
    slepc4py = pytest.importorskip("slepc4py")  # noqa: F841
    from slepc4py import SLEPc

    mesh = create_rectangle(
        MPI.COMM_WORLD,
        [np.array([0.0, 0.0]), np.array([np.pi, np.pi])], [24, 24],
        CellType.triangle)

    element = ufl.FiniteElement(family, ufl.triangle, order)
    V = FunctionSpace(mesh, element)

    u = ufl.TrialFunction(V)
    v = ufl.TestFunction(V)

    a = inner(ufl.curl(u), ufl.curl(v)) * dx
    b = inner(u, v) * dx

    boundary_facets = locate_entities_boundary(
        mesh, mesh.topology.dim - 1,
        lambda x: np.full(x.shape[1], True, dtype=bool))
    boundary_dofs = locate_dofs_topological(V, mesh.topology.dim - 1,
                                            boundary_facets)

    zero_u = Function(V)
    zero_u.x.array[:] = 0.0
    bcs = [dirichletbc(zero_u, boundary_dofs)]

    a, b = form(a), form(b)

    A = assemble_matrix(a, bcs=bcs)
    A.assemble()

    B = assemble_matrix(b, bcs=bcs, diagonal=0.01)
    B.assemble()

    eps = SLEPc.EPS().create()
    eps.setOperators(A, B)
    PETSc.Options()["eps_type"] = "krylovschur"
    PETSc.Options()["eps_gen_hermitian"] = ""
    PETSc.Options()["eps_target_magnitude"] = ""
    PETSc.Options()["eps_target"] = 5.0
    PETSc.Options()["eps_view"] = ""
    PETSc.Options()["eps_nev"] = 12
    eps.setFromOptions()
    eps.solve()

    num_converged = eps.getConverged()
    eigenvalues_unsorted = np.zeros(num_converged, dtype=np.complex128)

    for i in range(0, num_converged):
        eigenvalues_unsorted[i] = eps.getEigenvalue(i)

    assert np.isclose(np.imag(eigenvalues_unsorted), 0.0).all()
    eigenvalues_sorted = np.sort(np.real(eigenvalues_unsorted))[:-1]
    eigenvalues_sorted = eigenvalues_sorted[np.logical_not(
        eigenvalues_sorted < 1E-8)]

    eigenvalues_exact = np.array([1.0, 1.0, 2.0, 4.0, 4.0, 5.0, 5.0, 8.0, 9.0])
    assert np.isclose(eigenvalues_sorted[0:eigenvalues_exact.shape[0]],
                      eigenvalues_exact,
                      rtol=1E-2).all()