示例#1
0
def choosing_element(V, degree):
    cell_geometry = V.mesh().ufl_cell()
    if cell_geometry == quadrilateral:
        T = UFCQuadrilateral()
        raise ValueError(
            "Point interpolation for quads implemented somewhere else.")

    elif cell_geometry == triangle:
        T = UFCTriangle()

    elif cell_geometry == tetrahedron:
        T = UFCTetrahedron()

    else:
        raise ValueError("Unrecognized cell geometry.")

    if V.ufl_element().family() == "Kong-Mulder-Veldhuizen":
        element = KMV(T, degree)
    elif V.ufl_element().family() == "Lagrange":
        element = CG(T, degree)
    elif V.ufl_element().family() == "Discontinuous Lagrange":
        element = DG(T, degree)
    else:
        raise ValueError("Function space not yet supported.")

    return element
示例#2
0
from __future__ import absolute_import, print_function, division

import pytest
import numpy as np

from FIAT.reference_element import UFCInterval, UFCTriangle, UFCTetrahedron
from FIAT.reference_element import FiredrakeQuadrilateral, TensorProductCell

from tsfc.fem import make_cell_facet_jacobian

interval = UFCInterval()
triangle = UFCTriangle()
quadrilateral = FiredrakeQuadrilateral()
tetrahedron = UFCTetrahedron()
interval_x_interval = TensorProductCell(interval, interval)
triangle_x_interval = TensorProductCell(triangle, interval)
quadrilateral_x_interval = TensorProductCell(quadrilateral, interval)


@pytest.mark.parametrize(
    ('cell', 'cell_facet_jacobian'),
    [(interval, [[], []]), (triangle, [[-1, 1], [0, 1], [1, 0]]),
     (quadrilateral, [[0, 1], [0, 1], [1, 0], [1, 0]]),
     (tetrahedron, [[-1, -1, 1, 0, 0, 1], [0, 0, 1, 0, 0, 1],
                    [1, 0, 0, 0, 0, 1], [1, 0, 0, 1, 0, 0]])])
def test_cell_facet_jacobian(cell, cell_facet_jacobian):
    facet_dim = cell.get_spatial_dimension() - 1
    for facet_number in range(len(cell.get_topology()[facet_dim])):
        actual = make_cell_facet_jacobian(cell, facet_dim, facet_number)
        expected = np.reshape(cell_facet_jacobian[facet_number], actual.shape)
        assert np.allclose(expected, actual)
示例#3
0
文件: test_fiat.py 项目: tj-sun/fiat
from FIAT.gauss_legendre import GaussLegendre  # noqa: F401
from FIAT.gauss_lobatto_legendre import GaussLobattoLegendre  # noqa: F401
from FIAT.restricted import RestrictedElement  # noqa: F401
from FIAT.tensor_product import TensorProductElement  # noqa: F401
from FIAT.tensor_product import FlattenedDimensions  # noqa: F401
from FIAT.hdivcurl import Hdiv, Hcurl  # noqa: F401
from FIAT.argyris import Argyris, QuinticArgyris  # noqa: F401
from FIAT.hermite import CubicHermite  # noqa: F401
from FIAT.morley import Morley  # noqa: F401
from FIAT.bubble import Bubble
from FIAT.enriched import EnrichedElement  # noqa: F401
from FIAT.nodal_enriched import NodalEnrichedElement

I = UFCInterval()  # noqa: E741
T = UFCTriangle()
S = UFCTetrahedron()


def test_basis_derivatives_scaling():
    "Regression test for issue #9"

    class Interval(ReferenceElement):
        def __init__(self, a, b):
            verts = ((a, ), (b, ))
            edges = {0: (0, 1)}
            topology = {0: {0: (0, ), 1: (1, )}, 1: edges}
            super(Interval, self).__init__(LINE, verts, topology)

    random.seed(42)
    for i in range(26):
        a = 1000.0 * (random.random() - 0.5)
示例#4
0
def _tetrahedron_scheme(degree):
    """Return a quadrature scheme on a tetrahedron of specified
    degree. Falls back on canonical rule for higher orders"""

    if degree == 0 or degree == 1:
        # Scheme from Zienkiewicz and Taylor, 1 point, degree of precision 1
        x = array([[1.0/4.0, 1.0/4.0, 1.0/4.0]])
        w = array([1.0/6.0])
    elif degree == 2:
        # Scheme from Zienkiewicz and Taylor, 4 points, degree of precision 2
        a, b = 0.585410196624969, 0.138196601125011
        x = array([[a, b, b],
                   [b, a, b],
                   [b, b, a],
                   [b, b, b]])
        w = arange(4, dtype=float64)
        w[:] = 1.0/24.0
    elif degree == 3:
        # Scheme from Zienkiewicz and Taylor, 5 points, degree of precision 3
        # Note: this scheme has a negative weight
        x = array([[0.2500000000000000, 0.2500000000000000, 0.2500000000000000],
                   [0.5000000000000000, 0.1666666666666666, 0.1666666666666666],
                   [0.1666666666666666, 0.5000000000000000, 0.1666666666666666],
                   [0.1666666666666666, 0.1666666666666666, 0.5000000000000000],
                   [0.1666666666666666, 0.1666666666666666, 0.1666666666666666]])
        w = arange(5, dtype=float64)
        w[0] = -0.8
        w[1:5] = 0.45
        w = w/6.0
    elif degree == 4:
        # Keast rule, 14 points, degree of precision 4
        # Values taken from http://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_tet/quadrature_rules_tet.html
        # (KEAST5)
        x = array([[0.0000000000000000, 0.5000000000000000, 0.5000000000000000],
                   [0.5000000000000000, 0.0000000000000000, 0.5000000000000000],
                   [0.5000000000000000, 0.5000000000000000, 0.0000000000000000],
                   [0.5000000000000000, 0.0000000000000000, 0.0000000000000000],
                   [0.0000000000000000, 0.5000000000000000, 0.0000000000000000],
                   [0.0000000000000000, 0.0000000000000000, 0.5000000000000000],
                   [0.6984197043243866, 0.1005267652252045, 0.1005267652252045],
                   [0.1005267652252045, 0.1005267652252045, 0.1005267652252045],
                   [0.1005267652252045, 0.1005267652252045, 0.6984197043243866],
                   [0.1005267652252045, 0.6984197043243866, 0.1005267652252045],
                   [0.0568813795204234, 0.3143728734931922, 0.3143728734931922],
                   [0.3143728734931922, 0.3143728734931922, 0.3143728734931922],
                   [0.3143728734931922, 0.3143728734931922, 0.0568813795204234],
                   [0.3143728734931922, 0.0568813795204234, 0.3143728734931922]])
        w = arange(14, dtype=float64)
        w[0:6] = 0.0190476190476190
        w[6:10] = 0.0885898247429807
        w[10:14] = 0.1328387466855907
        w = w/6.0
    elif degree == 5:
        # Keast rule, 15 points, degree of precision 5
        # Values taken from http://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_tet/quadrature_rules_tet.html
        # (KEAST6)
        x = array([[0.2500000000000000, 0.2500000000000000, 0.2500000000000000],
                   [0.0000000000000000, 0.3333333333333333, 0.3333333333333333],
                   [0.3333333333333333, 0.3333333333333333, 0.3333333333333333],
                   [0.3333333333333333, 0.3333333333333333, 0.0000000000000000],
                   [0.3333333333333333, 0.0000000000000000, 0.3333333333333333],
                   [0.7272727272727273, 0.0909090909090909, 0.0909090909090909],
                   [0.0909090909090909, 0.0909090909090909, 0.0909090909090909],
                   [0.0909090909090909, 0.0909090909090909, 0.7272727272727273],
                   [0.0909090909090909, 0.7272727272727273, 0.0909090909090909],
                   [0.4334498464263357, 0.0665501535736643, 0.0665501535736643],
                   [0.0665501535736643, 0.4334498464263357, 0.0665501535736643],
                   [0.0665501535736643, 0.0665501535736643, 0.4334498464263357],
                   [0.0665501535736643, 0.4334498464263357, 0.4334498464263357],
                   [0.4334498464263357, 0.0665501535736643, 0.4334498464263357],
                   [0.4334498464263357, 0.4334498464263357, 0.0665501535736643]])
        w = arange(15, dtype=float64)
        w[0] = 0.1817020685825351
        w[1:5] = 0.0361607142857143
        w[5:9] = 0.0698714945161738
        w[9:15] = 0.0656948493683187
        w = w/6.0
    elif degree == 6:
        # Keast rule, 24 points, degree of precision 6
        # Values taken from http://people.sc.fsu.edu/~jburkardt/datasets/quadrature_rules_tet/quadrature_rules_tet.html
        # (KEAST7)
        x = array([[0.3561913862225449, 0.2146028712591517, 0.2146028712591517],
                   [0.2146028712591517, 0.2146028712591517, 0.2146028712591517],
                   [0.2146028712591517, 0.2146028712591517, 0.3561913862225449],
                   [0.2146028712591517, 0.3561913862225449, 0.2146028712591517],
                   [0.8779781243961660, 0.0406739585346113, 0.0406739585346113],
                   [0.0406739585346113, 0.0406739585346113, 0.0406739585346113],
                   [0.0406739585346113, 0.0406739585346113, 0.8779781243961660],
                   [0.0406739585346113, 0.8779781243961660, 0.0406739585346113],
                   [0.0329863295731731, 0.3223378901422757, 0.3223378901422757],
                   [0.3223378901422757, 0.3223378901422757, 0.3223378901422757],
                   [0.3223378901422757, 0.3223378901422757, 0.0329863295731731],
                   [0.3223378901422757, 0.0329863295731731, 0.3223378901422757],
                   [0.2696723314583159, 0.0636610018750175, 0.0636610018750175],
                   [0.0636610018750175, 0.2696723314583159, 0.0636610018750175],
                   [0.0636610018750175, 0.0636610018750175, 0.2696723314583159],
                   [0.6030056647916491, 0.0636610018750175, 0.0636610018750175],
                   [0.0636610018750175, 0.6030056647916491, 0.0636610018750175],
                   [0.0636610018750175, 0.0636610018750175, 0.6030056647916491],
                   [0.0636610018750175, 0.2696723314583159, 0.6030056647916491],
                   [0.2696723314583159, 0.6030056647916491, 0.0636610018750175],
                   [0.6030056647916491, 0.0636610018750175, 0.2696723314583159],
                   [0.0636610018750175, 0.6030056647916491, 0.2696723314583159],
                   [0.2696723314583159, 0.0636610018750175, 0.6030056647916491],
                   [0.6030056647916491, 0.2696723314583159, 0.0636610018750175]])
        w = arange(24, dtype=float64)
        w[0:4] = 0.0399227502581679
        w[4:8] = 0.0100772110553207
        w[8:12] = 0.0553571815436544
        w[12:24] = 0.0482142857142857
        w = w/6.0
    else:
        # Get canonical scheme
        return _fiat_scheme(UFCTetrahedron(), degree)

    # Return scheme
    return QuadratureRule(UFCTetrahedron(), x, w)
示例#5
0
from FIAT import finite_element, polynomial_set, dual_set, functional
from FIAT.reference_element import (Point, DefaultLine, UFCInterval,
                                    UFCQuadrilateral, UFCHexahedron,
                                    UFCTriangle, UFCTetrahedron,
                                    make_affine_mapping,
                                    flatten_reference_cube)
from FIAT.P0 import P0Dual
import numpy as np

hypercube_simplex_map = {
    Point(): Point(),
    DefaultLine(): DefaultLine(),
    UFCInterval(): UFCInterval(),
    UFCQuadrilateral(): UFCTriangle(),
    UFCHexahedron(): UFCTetrahedron()
}


class DPC0(finite_element.CiarletElement):
    def __init__(self, ref_el):
        flat_el = flatten_reference_cube(ref_el)
        poly_set = polynomial_set.ONPolynomialSet(
            hypercube_simplex_map[flat_el], 0)
        dual = P0Dual(ref_el)
        degree = 0
        formdegree = ref_el.get_spatial_dimension()  # n-form
        super(DPC0, self).__init__(poly_set=poly_set,
                                   dual=dual,
                                   order=degree,
                                   ref_el=ref_el,
示例#6
0
def tetrahedron():
    return UFCTetrahedron()
示例#7
0
def _kmv_lump_scheme(ref_el, degree):
    """Specialized quadrature schemes for P < 6 for KMV simplical elements."""

    sd = ref_el.get_spatial_dimension()
    # set the unit element
    if sd == 2:
        T = UFCTriangle()
    elif sd == 3:
        T = UFCTetrahedron()
    else:
        raise ValueError("Dimension not supported")

    if degree == 1:
        x = ref_el.vertices
        w = arange(sd + 1, dtype=float64)
        if sd == 2:
            w[:] = 1.0 / 6.0
        elif sd == 3:
            w[:] = 1.0 / 24.0
        else:
            raise ValueError("Dimension not supported")
    elif degree == 2:
        if sd == 2:
            x = list(ref_el.vertices)
            for e in range(3):
                x.extend(ref_el.make_points(1, e, 2))  # edge midpoints
            x.extend(ref_el.make_points(2, 0, 3))  # barycenter
            w = arange(7, dtype=float64)
            w[0:3] = 1.0 / 40.0
            w[3:6] = 1.0 / 15.0
            w[6] = 9.0 / 40.0
        elif sd == 3:
            x = list(ref_el.vertices)
            x.extend([
                (0.0, 0.50, 0.50),
                (0.50, 0.0, 0.50),
                (0.50, 0.50, 0.0),
                (0.0, 0.0, 0.50),
                (0.0, 0.50, 0.0),
                (0.50, 0.0, 0.0),
            ])
            # in facets
            x.extend([
                (0.33333333333333337, 0.3333333333333333, 0.3333333333333333),
                (0.0, 0.3333333333333333, 0.3333333333333333),
                (0.3333333333333333, 0.0, 0.3333333333333333),
                (0.3333333333333333, 0.3333333333333333, 0.0),
            ])
            # in the cell
            x.extend([(1 / 4, 1 / 4, 1 / 4)])
            w = arange(15, dtype=float64)
            w[0:4] = 17.0 / 5040.0
            w[4:10] = 2.0 / 315.0
            w[10:14] = 9.0 / 560.0
            w[14] = 16.0 / 315.0
        else:
            raise ValueError("Dimension not supported")

    elif degree == 3:
        if sd == 2:
            alpha = 0.2934695559090401
            beta = 0.2073451756635909
            x = list(ref_el.vertices)
            x.extend([
                (1 - alpha, alpha),
                (alpha, 1 - alpha),
                (0.0, 1 - alpha),
                (0.0, alpha),
                (alpha, 0.0),
                (1 - alpha, 0.0),
            ]  # edge points
                     )
            x.extend([(beta, beta), (1 - 2 * beta, beta),
                      (beta, 1 - 2 * beta)])  # points in center of cell
            w = arange(12, dtype=float64)
            w[0:3] = 0.007436456512410291
            w[3:9] = 0.02442084061702551
            w[9:12] = 0.1103885289202054
        elif sd == 3:
            x = list(ref_el.vertices)
            x.extend([
                (0, 0.685789657581967, 0.314210342418033),
                (0, 0.314210342418033, 0.685789657581967),
                (0.314210342418033, 0, 0.685789657581967),
                (0.685789657581967, 0, 0.314210342418033),
                (0.685789657581967, 0.314210342418033, 0.0),
                (0.314210342418033, 0.685789657581967, 0.0),
                (0, 0, 0.685789657581967),
                (0, 0, 0.314210342418033),
                (0, 0.314210342418033, 0.0),
                (0, 0.685789657581967, 0.0),
                (0.314210342418033, 0, 0.0),
                (0.685789657581967, 0, 0.0),
            ])  # 12 points on edges of facets (0-->1-->2)

            x.extend(
                [
                    (0.21548220313557542, 0.5690355937288492,
                     0.21548220313557542),
                    (0.21548220313557542, 0.21548220313557542,
                     0.5690355937288492),
                    (0.5690355937288492, 0.21548220313557542,
                     0.21548220313557542),
                    (0.0, 0.5690355937288492, 0.21548220313557542),
                    (0.0, 0.21548220313557542, 0.5690355937288492),
                    (0.0, 0.21548220313557542, 0.21548220313557542),
                    (0.5690355937288492, 0.0, 0.21548220313557542),
                    (0.21548220313557542, 0.0, 0.5690355937288492),
                    (0.21548220313557542, 0.0, 0.21548220313557542),
                    (0.5690355937288492, 0.21548220313557542, 0.0),
                    (0.21548220313557542, 0.5690355937288492, 0.0),
                    (0.21548220313557542, 0.21548220313557542, 0.0),
                ]
            )  # 12 points (3 points on each facet, 1st two parallel to edge 0)
            alpha = 1 / 6
            x.extend([
                (alpha, alpha, 0.5),
                (0.5, alpha, alpha),
                (alpha, 0.5, alpha),
                (alpha, alpha, alpha),
            ])  # 4 points inside the cell
            w = arange(32, dtype=float64)
            w[0:4] = 0.00068688236002531922325120561367839
            w[4:16] = 0.0015107814913526136472998739890272
            w[16:28] = 0.0050062894680040258624242888174649
            w[28:32] = 0.021428571428571428571428571428571
        else:
            raise ValueError("Dimension not supported")
    elif degree == 4:
        if sd == 2:
            alpha = 0.2113248654051871  # 0.2113248654051871
            beta1 = 0.4247639617258106  # 0.4247639617258106
            beta2 = 0.130791593829745  # 0.130791593829745
            x = list(ref_el.vertices)
            for e in range(3):
                x.extend(ref_el.make_points(1, e, 2))  # edge midpoints
            x.extend([
                (1 - alpha, alpha),
                (alpha, 1 - alpha),
                (0.0, 1 - alpha),
                (0.0, alpha),
                (alpha, 0.0),
                (1 - alpha, 0.0),
            ]  # edge points
                     )
            x.extend([(beta1, beta1), (1 - 2 * beta1, beta1),
                      (beta1, 1 - 2 * beta1)])  # points in center of cell
            x.extend([(beta2, beta2), (1 - 2 * beta2, beta2),
                      (beta2, 1 - 2 * beta2)])  # points in center of cell
            w = arange(18, dtype=float64)
            w[0:3] = 0.003174603174603175  # chk
            w[3:6] = 0.0126984126984127  # chk 0.0126984126984127
            w[6:12] = 0.01071428571428571  # chk 0.01071428571428571
            w[12:15] = 0.07878121446939182  # chk 0.07878121446939182
            w[15:18] = 0.05058386489568756  # chk 0.05058386489568756
        else:
            raise ValueError("Dimension not supported")

    elif degree == 5:
        if sd == 2:
            alpha1 = 0.3632980741536860e-00
            alpha2 = 0.1322645816327140e-00
            beta1 = 0.4578368380791611e-00
            beta2 = 0.2568591072619591e-00
            beta3 = 0.5752768441141011e-01
            gamma1 = 0.7819258362551702e-01
            delta1 = 0.2210012187598900e-00
            x = list(ref_el.vertices)
            x.extend([
                (1 - alpha1, alpha1),
                (alpha1, 1 - alpha1),
                (0.0, 1 - alpha1),
                (0.0, alpha1),
                (alpha1, 0.0),
                (1 - alpha1, 0.0),
            ]  # edge points
                     )
            x.extend([
                (1 - alpha2, alpha2),
                (alpha2, 1 - alpha2),
                (0.0, 1 - alpha2),
                (0.0, alpha2),
                (alpha2, 0.0),
                (1 - alpha2, 0.0),
            ]  # edge points
                     )
            x.extend([(beta1, beta1), (1 - 2 * beta1, beta1),
                      (beta1, 1 - 2 * beta1)])  # points in center of cell
            x.extend([(beta2, beta2), (1 - 2 * beta2, beta2),
                      (beta2, 1 - 2 * beta2)])  # points in center of cell
            x.extend([(beta3, beta3), (1 - 2 * beta3, beta3),
                      (beta3, 1 - 2 * beta3)])  # points in center of cell
            x.extend([
                (gamma1, delta1),
                (1 - gamma1 - delta1, delta1),
                (gamma1, 1 - gamma1 - delta1),
                (delta1, gamma1),
                (1 - gamma1 - delta1, gamma1),
                (delta1, 1 - gamma1 - delta1),
            ]  # edge points
                     )
            w = arange(30, dtype=float64)
            w[0:3] = 0.7094239706792450e-03
            w[3:9] = 0.6190565003676629e-02
            w[9:15] = 0.3480578640489211e-02
            w[15:18] = 0.3453043037728279e-01
            w[18:21] = 0.4590123763076286e-01
            w[21:24] = 0.1162613545961757e-01
            w[24:30] = 0.2727857596999626e-01
        else:
            raise ValueError("Dimension not supported")

    # Return scheme
    return QuadratureRule(T, x, w)