Example #1
0
def test_create_quadrature_extr_quadrilateral(extr_quadrilateral, basedeg,
                                              extrdeg, scheme):
    q = FIAT.create_quadrature(extr_quadrilateral, (basedeg, extrdeg), scheme)
    assert numpy.allclose(
        q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg),
        (2**(basedeg + 2) - 2) / ((basedeg + 1) *
                                  (basedeg + 2)) * 1 / (extrdeg + 1))
Example #2
0
def convert_finiteelement(element, vector_is_mixed):
    if element.family() == "Real":
        # Real element is just DG0
        cell = element.cell()
        return create_element(ufl.FiniteElement("DG", cell, 0),
                              vector_is_mixed)
    cell = as_fiat_cell(element.cell())
    if element.family() == "Quadrature":
        degree = element.degree()
        scheme = element.quadrature_scheme()
        if degree is None or scheme is None:
            raise ValueError("Quadrature scheme and degree must be specified!")

        quad_rule = FIAT.create_quadrature(cell, degree, scheme)
        return FIAT.QuadratureElement(cell, quad_rule.get_points())
    lmbda = supported_elements[element.family()]
    if lmbda is None:
        if element.cell().cellname() == "quadrilateral":
            # Handle quadrilateral short names like RTCF and RTCE.
            element = element.reconstruct(cell=quadrilateral_tpc)
        elif element.cell().cellname() == "hexahedron":
            # Handle hexahedron short names like NCF and NCE.
            element = element.reconstruct(cell=hexahedron_tpc)
        else:
            raise ValueError("%s is supported, but handled incorrectly" %
                             element.family())
        return FlattenedDimensions(create_element(element, vector_is_mixed))

    kind = element.variant()
    if kind is None:
        kind = 'spectral' if element.cell().cellname(
        ) == 'interval' else 'equispaced'  # default variant

    if element.family() == "Lagrange":
        if kind == 'equispaced':
            lmbda = FIAT.Lagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLobattoLegendre
        else:
            raise ValueError("Variant %r not supported on %s" %
                             (kind, element.cell()))
    elif element.family() in [
            "Discontinuous Lagrange", "Discontinuous Lagrange L2"
    ]:
        if kind == 'equispaced':
            lmbda = FIAT.DiscontinuousLagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLegendre
        else:
            raise ValueError("Variant %r not supported on %s" %
                             (kind, element.cell()))
    return lmbda(cell, element.degree())
Example #3
0
def create_quadrature(shape, degree, scheme="default"):
    """
    Generate quadrature rule (points, weights) for given shape
    that will integrate an polynomial of order 'degree' exactly.
    """
    if isinstance(shape, int) and shape == 0:
        return (numpy.zeros((1, 0)), numpy.ones((1,)))

    if shape in cellname2dim and cellname2dim[shape] == 0:
        return (numpy.zeros((1, 0)), numpy.ones((1,)))

    if scheme == "vertex":
        # The vertex scheme, i.e., averaging the function value in the vertices
        # and multiplying with the simplex volume, is only of order 1 and
        # inferior to other generic schemes in terms of error reduction.
        # Equation systems generated with the vertex scheme have some
        # properties that other schemes lack, e.g., the mass matrix is
        # a simple diagonal matrix. This may be prescribed in certain cases.
        if degree > 1:
            from warnings import warn
            warn(("Explicitly selected vertex quadrature (degree 1), "
                 + "but requested degree is %d.") % degree)
        if shape == "tetrahedron":
            return (array([[0.0, 0.0, 0.0],
                           [1.0, 0.0, 0.0],
                           [0.0, 1.0, 0.0],
                           [0.0, 0.0, 1.0]]),
                    array([1.0 / 24.0, 1.0 / 24.0, 1.0 / 24.0, 1.0 / 24.0])
                    )
        elif shape == "triangle":
            return (array([[0.0, 0.0],
                           [1.0, 0.0],
                           [0.0, 1.0]]),
                    array([1.0 / 6.0, 1.0 / 6.0, 1.0 / 6.0])
                    )
        elif shape == "interval":
            # Trapezoidal rule.
            return (array([[0.0],
                           [1.0]]),
                    array([1.0 / 2.0, 1.0 / 2.0])
                    )

    quad_rule = FIAT.create_quadrature(reference_cell(shape), degree, scheme)
    points = numpy.asarray(quad_rule.get_points())
    weights = numpy.asarray(quad_rule.get_weights())
    return points, weights
Example #4
0
def create_quadrature(shape, degree: int, scheme: str = "default"):
    """Generate quadrature rule.

    Quadrature rule(points, weights) for given shape that will integrate
    an polynomial of order 'degree' exactly.

    """
    if isinstance(shape, int) and shape == 0:
        return (numpy.zeros((1, 0)), numpy.ones((1, )))

    if shape in ufl.cell.cellname2dim and ufl.cell.cellname2dim[shape] == 0:
        return (numpy.zeros((1, 0)), numpy.ones((1, )))

    quad_rule = FIAT.create_quadrature(FIAT.ufc_cell(shape), degree, scheme)
    points = numpy.asarray(quad_rule.get_points())
    weights = numpy.asarray(quad_rule.get_weights())
    return points, weights
Example #5
0
def _(element, vector_is_mixed):
    if element.family() == "Real":
        # Real element is just DG0
        cell = element.cell()
        return create_element(ufl.FiniteElement("DG", cell, 0), vector_is_mixed)
    cell = as_fiat_cell(element.cell())
    if element.family() == "Quadrature":
        degree = element.degree()
        scheme = element.quadrature_scheme()
        if degree is None or scheme is None:
            raise ValueError("Quadrature scheme and degree must be specified!")

        quad_rule = FIAT.create_quadrature(cell, degree, scheme)
        return FIAT.QuadratureElement(cell, quad_rule.get_points())
    lmbda = supported_elements[element.family()]
    if lmbda is None:
        if element.cell().cellname() != "quadrilateral":
            raise ValueError("%s is supported, but handled incorrectly" %
                             element.family())
        # Handle quadrilateral short names like RTCF and RTCE.
        element = element.reconstruct(cell=quad_tpc)
        return FlattenedDimensions(create_element(element, vector_is_mixed))

    kind = element.variant()
    if kind is None:
        kind = 'equispaced'  # default variant

    if element.family() == "Lagrange":
        if kind == 'equispaced':
            lmbda = FIAT.Lagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLobattoLegendre
        else:
            raise ValueError("Variant %r not supported on %s" % (kind, element.cell()))
    elif element.family() == "Discontinuous Lagrange":
        if kind == 'equispaced':
            lmbda = FIAT.DiscontinuousLagrange
        elif kind == 'spectral' and element.cell().cellname() == 'interval':
            lmbda = FIAT.GaussLegendre
        else:
            raise ValueError("Variant %r not supported on %s" % (kind, element.cell()))
    return lmbda(cell, element.degree())
Example #6
0
def create_quadrature(cell, degree, scheme="default"):
    """Create a quadrature rule.

    :arg cell: The FIAT cell.
    :arg degree: The degree of polynomial that should be integrated
        exactly by the rule.
    :kwarg scheme: optional scheme to use (either ``"default"``, or
         ``"canonical"``).

    .. note ::

       If the cell is a tensor product cell, the degree should be a
       tuple, indicating the degree in each direction of the tensor
       product.
    """
    if scheme not in ("default", "canonical"):
        raise ValueError("Unknown quadrature scheme '%s'" % scheme)

    rule = FIAT.create_quadrature(cell, degree, scheme)
    if len(rule.get_points()) > 900:
        raise RuntimeError("Requested a quadrature rule with %d points" % len(rule.get_points()))
    return rule
Example #7
0
def test_create_quadrature_tetrahedron(tetrahedron, degree, scheme):
    q = FIAT.create_quadrature(tetrahedron, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(2*degree + 6))
Example #8
0
def test_create_quadrature_quadrilateral(quadrilateral, degree, scheme):
    q = FIAT.create_quadrature(quadrilateral, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree),
                          (2**(degree + 2) - 2) / ((degree + 1)*(degree + 2)))
Example #9
0
def test_high_degree_runtime_error(cell):
    with pytest.raises(RuntimeError):
        FIAT.create_quadrature(cell, 60)
Example #10
0
def test_create_quadrature_triangle(triangle, degree, scheme):
    q = FIAT.create_quadrature(triangle, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(degree + 2))
Example #11
0
def test_create_quadrature_interval(interval, degree, scheme):
    q = FIAT.create_quadrature(interval, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: x[0]**degree), 1/(degree + 1))
Example #12
0
def test_create_quadrature_tetrahedron(tetrahedron, degree, scheme):
    q = FIAT.create_quadrature(tetrahedron, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(2*degree + 6))
Example #13
0
def test_create_quadrature_hexahedron(hexahedron, degree, scheme):
    q = FIAT.create_quadrature(hexahedron, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree),
                          -3 * (2**(degree + 3) - 3**(degree + 2) - 1) / ((degree + 1)*(degree + 2)*(degree + 3)))
Example #14
0
def test_invalid_quadrature_degree_tensor_prod(cell):
    with pytest.raises(ValueError):
        FIAT.create_quadrature(cell, (-1, -1))
Example #15
0
def test_create_quadrature_extr_triangle(extr_triangle, basedeg, extrdeg, scheme):
    q = FIAT.create_quadrature(extr_triangle, (basedeg, extrdeg), scheme)
    assert numpy.allclose(q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg),
                          1/(basedeg + 2) * 1/(extrdeg + 1))
Example #16
0
def test_high_degree_runtime_error_tensor_prod(cell):
    with pytest.raises(RuntimeError):
        FIAT.create_quadrature(cell, (60, 60))
Example #17
0
def test_create_quadrature_extr_triangle(extr_triangle, basedeg, extrdeg, scheme):
    q = FIAT.create_quadrature(extr_triangle, (basedeg, extrdeg), scheme)
    assert numpy.allclose(q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg),
                          1/(basedeg + 2) * 1/(extrdeg + 1))
Example #18
0
def test_create_quadrature_extr_interval(extr_interval, basedeg, extrdeg, scheme):
    q = FIAT.create_quadrature(extr_interval, (basedeg, extrdeg), scheme)
    assert numpy.allclose(q.integrate(lambda x: x[0]**basedeg * x[1]**extrdeg),
                          1/(basedeg + 1) * 1/(extrdeg + 1))
def test_assembly_into_quadrature_function():
    """Test assembly into a Quadrature function.

    This test evaluates a UFL Expression into a Quadrature function space by
    evaluating the Expression on all cells of the mesh, and then inserting the
    evaluated values into a PETSc Vector constructed from a matching Quadrature
    function space.

    Concretely, we consider the evaluation of:

        e = B*(K(T)))**2 * grad(T)

    where

        K = 1/(A + B*T)

    where A and B are Constants and T is a Coefficient on a P2 finite element
    space with T = x + 2*y.

    The result is compared with interpolating the analytical expression of e
    directly into the Quadrature space.

    In parallel, each process evaluates the Expression on both local cells and
    ghost cells so that no parallel communication is required after insertion
    into the vector.
    """
    mesh = dolfinx.UnitSquareMesh(MPI.COMM_WORLD, 3, 6)

    quadrature_degree = 2
    quadrature_points = FIAT.create_quadrature(FIAT.ufc_simplex(
        mesh.topology.dim),
                                               quadrature_degree,
                                               scheme="default").get_points()
    Q_element = ufl.VectorElement("Quadrature",
                                  ufl.triangle,
                                  quadrature_degree,
                                  quad_scheme="default")
    Q = dolfinx.FunctionSpace(mesh, Q_element)

    def T_exact(x):
        return x[0] + 2.0 * x[1]

    P2 = dolfinx.FunctionSpace(mesh, ("P", 2))
    T = dolfinx.Function(P2)
    T.interpolate(T_exact)
    A = dolfinx.Constant(mesh, 1.0)
    B = dolfinx.Constant(mesh, 2.0)

    K = 1.0 / (A + B * T)
    e = B * K**2 * ufl.grad(T)

    e_expr = dolfinx.Expression(e, quadrature_points)

    map_c = mesh.topology.index_map(mesh.topology.dim)
    num_cells = map_c.size_local + map_c.num_ghosts
    cells = np.arange(0, num_cells, dtype=np.int32)

    e_eval = e_expr.eval(cells)

    # Assemble into Function
    e_Q = dolfinx.Function(Q)
    with e_Q.vector.localForm() as e_Q_local:
        e_Q_local.setValues(Q.dofmap.list.array,
                            e_eval,
                            addv=PETSc.InsertMode.INSERT)

    def e_exact(x):
        T = x[0] + 2.0 * x[1]
        K = 1.0 / (A.value + B.value * T)

        grad_T = np.zeros((2, x.shape[1]))
        grad_T[0, :] = 1.0
        grad_T[1, :] = 2.0

        e = B.value * K**2 * grad_T
        return e

    e_exact_Q = dolfinx.Function(Q)
    e_exact_Q.interpolate(e_exact)

    assert (np.isclose((e_exact_Q.vector - e_Q.vector).norm(), 0.0))
Example #20
0
def test_create_quadrature_extr_interval(extr_interval, basedeg, extrdeg, scheme):
    q = FIAT.create_quadrature(extr_interval, (basedeg, extrdeg), scheme)
    assert numpy.allclose(q.integrate(lambda x: x[0]**basedeg * x[1]**extrdeg),
                          1/(basedeg + 1) * 1/(extrdeg + 1))
Example #21
0
def test_create_quadrature_hexahedron(hexahedron, degree, scheme):
    q = FIAT.create_quadrature(hexahedron, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree),
                          -3 * (2**(degree + 3) - 3**(degree + 2) - 1) / ((degree + 1)*(degree + 2)*(degree + 3)))
Example #22
0
def test_create_quadrature_quadrilateral(quadrilateral, degree, scheme):
    q = FIAT.create_quadrature(quadrilateral, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree),
                          (2**(degree + 2) - 2) / ((degree + 1)*(degree + 2)))
Example #23
0
def test_create_quadrature_extr_quadrilateral(extr_quadrilateral, basedeg, extrdeg, scheme):
    q = FIAT.create_quadrature(extr_quadrilateral, (basedeg, extrdeg), scheme)
    assert numpy.allclose(q.integrate(lambda x: (x[0] + x[1])**basedeg * x[2]**extrdeg),
                          (2**(basedeg + 2) - 2) / ((basedeg + 1)*(basedeg + 2)) * 1/(extrdeg + 1))
Example #24
0
def test_invalid_quadrature_degree(cell, scheme):
    with pytest.raises(ValueError):
        FIAT.create_quadrature(cell, -1, scheme)
Example #25
0
def test_invalid_quadrature_degree(cell, scheme):
    with pytest.raises(ValueError):
        FIAT.create_quadrature(cell, -1, scheme)
Example #26
0
def test_tensor_product_composition(interval, triangle, extr_triangle, scheme):
    degree = (4, 4)
    qa = FIAT.create_quadrature(triangle, degree[0], scheme)
    qb = FIAT.create_quadrature(interval, degree[1], scheme)
    q = FIAT.create_quadrature(extr_triangle, degree, scheme)
    assert len(q.get_points()) == len(qa.get_points())*len(qb.get_points())
Example #27
0
def test_invalid_quadrature_degree_tensor_prod(cell):
    with pytest.raises(ValueError):
        FIAT.create_quadrature(cell, (-1, -1))
Example #28
0
def test_create_quadrature_triangle(triangle, degree, scheme):
    q = FIAT.create_quadrature(triangle, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: sum(x)**degree), 1/(degree + 2))
Example #29
0
def test_tensor_product_composition(interval, triangle, extr_triangle, scheme):
    degree = (4, 4)
    qa = FIAT.create_quadrature(triangle, degree[0], scheme)
    qb = FIAT.create_quadrature(interval, degree[1], scheme)
    q = FIAT.create_quadrature(extr_triangle, degree, scheme)
    assert len(q.get_points()) == len(qa.get_points())*len(qb.get_points())
Example #30
0
V = dolfinx.FunctionSpace(mesh, ("Lagrange", 1))
u = ufl.TrialFunction(V)
v = ufl.TestFunction(V)
f = dolfinx.Function(V)
def rhs(x):
    return sin(pi*x[0])*sin(pi*x[1])
f.interpolate(rhs)

a_eqn = inner(grad(u), grad(v))
L_eqn = inner(f, v)

a = a_eqn*ufl.dx(metadata={"quadrature_rule": "runtime"})
L = L_eqn*ufl.dx(metadata={"quadrature_rule": "runtime"})

degree = 2
q = FIAT.create_quadrature(FIAT.reference_element.UFCQuadrilateral(), degree)
qr_pts = q.get_points().flatten()
qr_w = q.get_weights().flatten()

A = libcutfemx.custom_assemble_matrix(a, [(cells, [qr_pts], [qr_w])])
A.assemble()
b = libcutfemx.custom_assemble_vector(L, [(cells, [qr_pts], [qr_w])])
print(A.norm())
print(numpy.linalg.norm(b.array))

vec = ksp_solve(A, b)
u = vec_to_function(vec, V, "u")
write("poisson.xdmf", mesh, u)


# Reference
Example #31
0
def test_create_quadrature_interval(interval, degree, scheme):
    q = FIAT.create_quadrature(interval, degree, scheme)
    assert numpy.allclose(q.integrate(lambda x: x[0]**degree), 1/(degree + 1))