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
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)