def purge_list_tensors(expr): """Get rid of all ListTensor instances by expanding expressions to use their components directly. Will usually increase the size of the expression.""" if any(isinstance(subexpr, ListTensor) for subexpr in unique_pre_traversal(expr)): return expand_indices(expr) # TODO: Only expand what's necessary to get rid of list tensors return expr
def purge_list_tensors(expr): """Get rid of all ListTensor instances by expanding expressions to use their components directly. Will usually increase the size of the expression.""" if any( isinstance(subexpr, ListTensor) for subexpr in unique_pre_traversal(expr)): return expand_indices( expr ) # TODO: Only expand what's necessary to get rid of list tensors return expr
def extract_type(a, ufl_type): """Build a set of all objects of class ufl_type found in a. The argument a can be a Form, Integral or Expr.""" if issubclass(ufl_type, Terminal): # Optimization return set(o for e in iter_expressions(a) for o in traverse_unique_terminals(e) if isinstance(o, ufl_type)) else: return set(o for e in iter_expressions(a) for o in unique_pre_traversal(e) if isinstance(o, ufl_type))
def test_pre_and_post_traversal(): element = FiniteElement("CG", "triangle", 1) v = TestFunction(element) f = Coefficient(element) g = Coefficient(element) p1 = f * v p2 = g * v s = p1 + p2 # NB! These traversal algorithms are intended to guarantee only # parent before child and vice versa, not this particular # ordering: assert list(pre_traversal(s)) == [s, p2, g, v, p1, f, v] assert list(post_traversal(s)) == [g, v, p2, f, v, p1, s] assert list(unique_pre_traversal(s)) == [s, p2, g, v, p1, f] assert list(unique_post_traversal(s)) == [v, f, p1, g, p2, s]
def build_graph(expr): # O(n) """Build a linearized graph from an UFL Expr. Returns G = (V, E), with V being a list of graph nodes (Expr objects) in post traversal ordering and E being a list of edges. Each edge is represented as a (i, j) tuple where i and j are vertex indices into V. """ V = [] E = [] handled = {} for v in reversed(list(unique_pre_traversal(expr))): i = handled.get(v) if i is None: i = len(V) handled[v] = i V.append(v) for o in v.ufl_operands: j = handled[o] e = (i, j) E.append(e) G = V, E return G
def __unused__extract_classes(a): """Build a set of all unique Expr subclasses used in a. The argument a can be a Form, Integral or Expr.""" return set(o._ufl_class_ for e in iter_expressions(a) for o in unique_pre_traversal(e))