Пример #1
0
 def __init__(self, ref_el, m):
   from FIAT.lagrange import Lagrange
   vertices = Lagrange(ref_el, m).dual.get_nodes()
   pts = [v.get_point_dict().keys()[0] for v in vertices]
   npts = len(pts)
   wts = (ref_el.volume()/npts,)*npts
   
   QuadratureRule.__init__(self, ref_el, pts, wts)
   return
Пример #2
0
    def __init__(self, cell, s, entity, mom_deg, comp_deg, nm=""):
        sd = cell.get_spatial_dimension()
        assert sd == 2
        shp = (sd, )
        quadpoints = comp_deg + 1
        Q = GaussLegendreQuadratureLineRule(interval(), quadpoints)
        legendre = numpy.polynomial.legendre.legval(2 * Q.get_points() - 1,
                                                    [0] * mom_deg + [1])
        f_at_qpts = numpy.array([s * legendre[i] for i in range(quadpoints)])
        fmap = cell.get_entity_transform(sd - 1, entity)
        mappedqpts = [fmap(pt) for pt in Q.get_points()]
        mappedQ = QuadratureRule(cell, mappedqpts, Q.get_weights())
        qwts = mappedQ.wts
        qpts = mappedQ.pts

        pt_dict = OrderedDict()

        for k in range(len(qpts)):
            pt_cur = tuple(qpts[k])
            pt_dict[pt_cur] = [(qwts[k] * f_at_qpts[k, i], (i, ))
                               for i in range(2)]

        super().__init__(cell, shp, pt_dict, {}, nm)
Пример #3
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)
Пример #4
0
def _triangle_scheme(degree):
    """Return a quadrature scheme on a triangle of specified order. 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/3.0, 1.0/3.0]])
        w = array([0.5])
    elif degree == 2:
        # Scheme from Strang and Fix, 3 points, degree of precision 2
        x = array([[1.0/6.0, 1.0/6.0],
                   [1.0/6.0, 2.0/3.0],
                   [2.0/3.0, 1.0/6.0]])
        w = arange(3, dtype=float64)
        w[:] = 1.0/6.0
    elif degree == 3:
        # Scheme from Strang and Fix, 6 points, degree of precision 3
        x = array([[0.659027622374092, 0.231933368553031],
                   [0.659027622374092, 0.109039009072877],
                   [0.231933368553031, 0.659027622374092],
                   [0.231933368553031, 0.109039009072877],
                   [0.109039009072877, 0.659027622374092],
                   [0.109039009072877, 0.231933368553031]])
        w = arange(6, dtype=float64)
        w[:] = 1.0/12.0
    elif degree == 4:
        # Scheme from Strang and Fix, 6 points, degree of precision 4
        x = array([[0.816847572980459, 0.091576213509771],
                   [0.091576213509771, 0.816847572980459],
                   [0.091576213509771, 0.091576213509771],
                   [0.108103018168070, 0.445948490915965],
                   [0.445948490915965, 0.108103018168070],
                   [0.445948490915965, 0.445948490915965]])
        w = arange(6, dtype=float64)
        w[0:3] = 0.109951743655322
        w[3:6] = 0.223381589678011
        w = w/2.0
    elif degree == 5:
        # Scheme from Strang and Fix, 7 points, degree of precision 5
        x = array([[0.33333333333333333, 0.33333333333333333],
                   [0.79742698535308720, 0.10128650732345633],
                   [0.10128650732345633, 0.79742698535308720],
                   [0.10128650732345633, 0.10128650732345633],
                   [0.05971587178976981, 0.47014206410511505],
                   [0.47014206410511505, 0.05971587178976981],
                   [0.47014206410511505, 0.47014206410511505]])
        w = arange(7, dtype=float64)
        w[0] = 0.22500000000000000
        w[1:4] = 0.12593918054482717
        w[4:7] = 0.13239415278850616
        w = w/2.0
    elif degree == 6:
        # Scheme from Strang and Fix, 12 points, degree of precision 6
        x = array([[0.873821971016996, 0.063089014491502],
                   [0.063089014491502, 0.873821971016996],
                   [0.063089014491502, 0.063089014491502],
                   [0.501426509658179, 0.249286745170910],
                   [0.249286745170910, 0.501426509658179],
                   [0.249286745170910, 0.249286745170910],
                   [0.636502499121399, 0.310352451033785],
                   [0.636502499121399, 0.053145049844816],
                   [0.310352451033785, 0.636502499121399],
                   [0.310352451033785, 0.053145049844816],
                   [0.053145049844816, 0.636502499121399],
                   [0.053145049844816, 0.310352451033785]])
        w = arange(12, dtype=float64)
        w[0:3] = 0.050844906370207
        w[3:6] = 0.116786275726379
        w[6:12] = 0.082851075618374
        w = w/2.0
    else:
        # Get canonical scheme
        return _fiat_scheme(UFCTriangle(), degree)

    # Return scheme
    return QuadratureRule(UFCTriangle(), x, w)
Пример #5
0
def test_invalid_quadrature_rule():
    from FIAT.quadrature import QuadratureRule
    with pytest.raises(ValueError):
        QuadratureRule(UFCInterval(), [[0.5, 0.5]], [0.5, 0.5, 0.5])
Пример #6
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)