Exemplo n.º 1
0
    def tabulate(self, ufl_element, max_deriv):
        """Prepare the tabulations of a finite element up to a given
        derivative order.

        :arg ufl_element: UFL element to tabulate
        :arg max_deriv: tabulate derivatives up this order
        """
        store = collections.defaultdict(list)
        for tabulator in self.tabulators:
            for c, D, table in tabulator(ufl_element, max_deriv):
                store[(ufl_element, c, D)].append(table)

        for key, tables in iteritems(store):
            table = gem.ListTensor(tables)
            if len(table.shape) == 2:
                # Cellwise constant; must not depend on the facet
                assert compat.allclose(table.array, table.array.mean(axis=0, keepdims=True), equal_nan=True)
                table = gem.Literal(table.array[0])
            self.tables[key] = table
Exemplo n.º 2
0
def tabulate(ufl_element, order, points, entity, epsilon):
    """Ask FIAT to tabulate ``points`` up to order ``order``, then
    rearranges the result into a series of ``(c, D, table)`` tuples,
    where:

    c: component index (for vector-valued and tensor-valued elements)
    D: derivative tuple (e.g. (1, 2) means d/dx d^2/dy^2)
    table: tabulation matrix for the given component and derivative.
           shape: len(points) x space_dimension

    :arg ufl_element: element to tabulate
    :arg order: FIAT gives all derivatives up to this order
    :arg points: points to tabulate the element on
    :arg entity: particular entity to tabulate on
    """
    element = create_element(ufl_element)
    phi = element.space_dimension()
    C = ufl_element.reference_value_size()
    q = len(points)
    for D, fiat_table in iteritems(element.tabulate(order, points, entity)):
        if isinstance(fiat_table, Exception):
            # In the case an exception is found in the fiat table, do not
            # perform any rounding
            gem_fail = gem.Failure((q, phi), fiat_table)
            for c in range(C):
                yield c, D, gem_fail
        else:
            reordered_table = fiat_table.reshape(phi, C, q).transpose(1, 2, 0)  # (C, q, phi)
            for c, table in enumerate(reordered_table):
                # Copied from FFC (ffc/quadrature/quadratureutils.py)
                table[abs(table) < epsilon] = 0
                table[abs(table - 1.0) < epsilon] = 1.0
                table[abs(table + 1.0) < epsilon] = -1.0
                table[abs(table - 0.5) < epsilon] = 0.5
                table[abs(table + 0.5) < epsilon] = -0.5

                if spanning_degree(ufl_element) <= sum(D) and ufl_element.family() != "HDiv Trace":
                    assert compat.allclose(table, table.mean(axis=0, keepdims=True), equal_nan=True)
                    table = table[0]

                yield c, D, gem.Literal(table)