def apply_geometry_lowering(form, preserve_types=()):
    """Change GeometricQuantity objects in expression to the lowest level GeometricQuantity objects.

    Assumes the expression is preprocessed or at least that derivatives have been expanded.

    @param form:
        An Expr or Form.
    """
    if isinstance(form, Form):
        newintegrals = [
            apply_geometry_lowering(integral, preserve_types)
            for integral in form.integrals()
        ]
        return Form(newintegrals)

    elif isinstance(form, Integral):
        integral = form
        if integral.integral_type() in (custom_integral_types +
                                        point_integral_types):
            automatic_preserve_types = [SpatialCoordinate, Jacobian]
        else:
            automatic_preserve_types = [CellCoordinate]
        preserve_types = set(preserve_types) | set(automatic_preserve_types)

        mf = GeometryLoweringApplier(preserve_types)
        newintegrand = map_expr_dag(mf, integral.integrand())
        return integral.reconstruct(integrand=newintegrand)

    elif isinstance(form, Expr):
        expr = form
        mf = GeometryLoweringApplier(preserve_types)
        return map_expr_dag(mf, expr)

    else:
        error("Invalid type %s" % (form.__class__.__name__, ))
示例#2
0
def apply_geometry_lowering(form, preserve_types=()):
    """Change GeometricQuantity objects in expression to the lowest level GeometricQuantity objects.

    Assumes the expression is preprocessed or at least that derivatives have been expanded.

    @param form:
        An Expr or Form.
    """
    if isinstance(form, Form):
        newintegrals = [apply_geometry_lowering(integral, preserve_types)
                        for integral in form.integrals()]
        return Form(newintegrals)

    elif isinstance(form, Integral):
        integral = form
        if integral.integral_type() in (custom_integral_types + point_integral_types):
            automatic_preserve_types = [SpatialCoordinate, Jacobian]
        else:
            automatic_preserve_types = [CellCoordinate]
        preserve_types = set(preserve_types) | set(automatic_preserve_types)

        mf = GeometryLoweringApplier(preserve_types)
        newintegrand = map_expr_dag(mf, integral.integrand())
        return integral.reconstruct(integrand=newintegrand)

    elif isinstance(form, Expr):
        expr = form
        mf = GeometryLoweringApplier(preserve_types)
        return map_expr_dag(mf, expr)

    else:
        error("Invalid type %s" % (form.__class__.__name__,))
示例#3
0
def compile_ufl(expression, interior_facet=False, **kwargs):
    context = Context(**kwargs)

    # Abs-simplification
    expression = simplify_abs(expression)

    # Collect modified terminals
    modified_terminals = []
    map_expr_dag(CollectModifiedTerminals(modified_terminals), expression)

    # Collect maximal derivatives that needs tabulation
    max_derivs = collections.defaultdict(int)

    for mt in map(analyse_modified_terminal, modified_terminals):
        if isinstance(mt.terminal, FormArgument):
            ufl_element = mt.terminal.ufl_element()
            max_derivs[ufl_element] = max(mt.local_derivatives, max_derivs[ufl_element])

    # Collect tabulations for all components and derivatives
    tabulation_manager = TabulationManager(context.points, context.integration_dim, context.entity_ids, context.epsilon)
    for ufl_element, max_deriv in max_derivs.items():
        if ufl_element.family() != 'Real':
            tabulation_manager.tabulate(ufl_element, max_deriv)

    if interior_facet:
        expressions = []
        for rs in itertools.product(("+", "-"), repeat=len(context.argument_indices)):
            expressions.append(map_expr_dag(PickRestriction(*rs), expression))
    else:
        expressions = [expression]

    # Translate UFL to GEM, lowering finite element specific nodes
    translator = Translator(tabulation_manager, context)
    return map_expr_dags(translator, expressions)
示例#4
0
def coarsen_form(form):
    """Return a coarse mesh version of a form

    :arg form: The :class:`~ufl.classes.Form` to coarsen.

    This maps over the form and replaces coefficients and arguments
    with their coarse mesh equivalents."""
    if form is None:
        return None
    assert isinstance(form, ufl.Form), \
        "Don't know how to coarsen %r" % type(form)

    mapper = CoarsenIntegrand()
    forms = []
    # Ugh, visitors can't deal with measures (they're not actual
    # Exprs) so we need to map the transformer over the integrand and
    # reconstruct the integral by building the measure by hand.
    for it in form.integrals():
        integrand = map_expr_dag(mapper, it.integrand())
        mesh = it.ufl_domain()
        hierarchy, level = utils.get_level(mesh)
        new_mesh = hierarchy[level - 1]

        measure = ufl.Measure(it.integral_type(),
                              domain=new_mesh,
                              subdomain_id=it.subdomain_id(),
                              subdomain_data=it.subdomain_data(),
                              metadata=it.metadata())

        forms.append(integrand * measure)
    return reduce(add, forms)
示例#5
0
文件: fem.py 项目: jmv2009/tsfc
 def physical_points(self, point_set, entity=None):
     """Converts point_set from reference to physical space"""
     expr = SpatialCoordinate(self.mt.terminal.ufl_domain())
     point_shape, = point_set.expression.shape
     if entity is not None:
         e, _ = entity
         assert point_shape == e
     else:
         assert point_shape == expr.ufl_domain().topological_dimension()
     if self.mt.restriction == '+':
         expr = PositiveRestricted(expr)
     elif self.mt.restriction == '-':
         expr = NegativeRestricted(expr)
     config = {"point_set": point_set}
     config.update(self.config)
     if entity is not None:
         config.update({
             name: getattr(self.interface, name)
             for name in ["integration_dim", "entity_ids"]
         })
     context = PointSetContext(**config)
     expr = self.preprocess(expr, context)
     mapped = map_expr_dag(context.translator, expr)
     indices = tuple(gem.Index() for _ in mapped.shape)
     return gem.ComponentTensor(gem.Indexed(mapped, indices),
                                point_set.indices + indices)
示例#6
0
def coarsen_form(form):
    """Return a coarse mesh version of a form

    :arg form: The :class:`~ufl.classes.Form` to coarsen.

    This maps over the form and replaces coefficients and arguments
    with their coarse mesh equivalents."""
    if form is None:
        return None
    assert isinstance(form, ufl.Form), \
        "Don't know how to coarsen %r" % type(form)

    mapper = CoarsenIntegrand()
    forms = []
    # Ugh, visitors can't deal with measures (they're not actual
    # Exprs) so we need to map the transformer over the integrand and
    # reconstruct the integral by building the measure by hand.
    for it in form.integrals():
        integrand = map_expr_dag(mapper, it.integrand())
        mesh = it.ufl_domain()
        hierarchy, level = utils.get_level(mesh)
        new_mesh = hierarchy[level-1]

        measure = ufl.Measure(it.integral_type(),
                              domain=new_mesh,
                              subdomain_id=it.subdomain_id(),
                              subdomain_data=it.subdomain_data(),
                              metadata=it.metadata())

        forms.append(integrand * measure)
    return reduce(add, forms)
示例#7
0
 def coordinate_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     o_ = o.ufl_operands
     key = (CoordinateDerivative, o_[0])
     return CoordinateDerivative(map_expr_dag(self, o_[0],
                                              vcache=self.vcaches[key],
                                              rcache=self.rcaches[key]),
                                 o_[1], o_[2], o_[3])
示例#8
0
 def coefficient_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     dummy, w, v, cd = o.ufl_operands
     rules = GateauxDerivativeRuleset(w, v, cd)
     key = (GateauxDerivativeRuleset, w, v, cd)
     return map_expr_dag(rules, f,
                         vcache=self.vcaches[key],
                         rcache=self.rcaches[key])
示例#9
0
 def variable_derivative(self, o, f, dummy_v):
     op = o.ufl_operands[1]
     rules = VariableRuleset(op)
     key = (VariableRuleset, op)
     return map_expr_dag(rules, f,
                         vcache=self.vcaches[key],
                         rcache=self.rcaches[key])
示例#10
0
def coarsen_form(form, coefficient_mapping=None):
    """Return a coarse mesh version of a form

    :arg form: The :class:`~ufl.classes.Form` to coarsen.
    :kwarg mapping: an optional map from coefficients to their
        coarsened equivalents.

    This maps over the form and replaces coefficients and arguments
    with their coarse mesh equivalents."""
    if form is None:
        return None

    mapper = CoarsenIntegrand(coefficient_mapping)
    integrals = []
    for it in form.integrals():
        integrand = map_expr_dag(mapper, it.integrand())
        mesh = it.ufl_domain()
        hierarchy, level = utils.get_level(mesh)
        new_mesh = hierarchy[level-1]
        if isinstance(integrand, ufl.classes.Zero):
            continue
        if it.subdomain_data() is not None:
            raise CoarseningError("Don't know how to coarsen subdomain data")
        new_itg = it.reconstruct(integrand=integrand,
                                 domain=new_mesh)
        integrals.append(new_itg)
    return ufl.Form(integrals)
示例#11
0
def coarsen_form(form, coefficient_mapping=None):
    """Return a coarse mesh version of a form

    :arg form: The :class:`~ufl.classes.Form` to coarsen.
    :kwarg mapping: an optional map from coefficients to their
        coarsened equivalents.

    This maps over the form and replaces coefficients and arguments
    with their coarse mesh equivalents."""
    if form is None:
        return None

    mapper = CoarsenIntegrand(coefficient_mapping)
    integrals = []
    for it in form.integrals():
        integrand = map_expr_dag(mapper, it.integrand())
        mesh = it.ufl_domain()
        hierarchy, level = utils.get_level(mesh)
        new_mesh = hierarchy[level-1]
        if isinstance(integrand, ufl.classes.Zero):
            continue
        if it.subdomain_data() is not None:
            raise CoarseningError("Don't know how to coarsen subdomain data")
        new_itg = it.reconstruct(integrand=integrand,
                                 domain=new_mesh)
        integrals.append(new_itg)
    return ufl.Form(integrals)
示例#12
0
def split_coefficients(expression, split):
    """Split mixed coefficients, so mixed elements need not be
    implemented."""
    if split is None:
        # Skip this step for DOLFIN
        return expression
    splitter = CoefficientSplitter(split)
    return map_expr_dag(splitter, expression)
示例#13
0
def extract_tested_expressions(expr):
    """Extract scalar expression factors for each test function component.

    This is for internal usage and has several undocumented limitations.
    """
    func = ScalarFactorizer()
    e = map_expr_dag(func, expr, compress=False)
    return e, func._arg
示例#14
0
def extract_tested_expressions(expr):
    """Extract scalar expression factors for each test function component.

    This is for internal usage and has several undocumented limitations.
    """
    func = ScalarFactorizer()
    e = map_expr_dag(func, expr, compress=False)
    return e, func._arg
示例#15
0
 def restricted(self, o):
     "When hitting a restricted quantity, visit child with a separate restriction algorithm."
     # Assure that we have only two levels here, inside or outside
     # the Restricted node
     if self.current_restriction is not None:
         error("Cannot restrict an expression twice.")
     # Configure a propagator for this side and apply to subtree
     # FIXME: Reuse cache between these calls!
     return map_expr_dag(self._rp[o.side()], o.ufl_operands[0])
示例#16
0
 def restricted(self, o):
     "When hitting a restricted quantity, visit child with a separate restriction algorithm."
     # Assure that we have only two levels here, inside or outside
     # the Restricted node
     if self.current_restriction is not None:
         error("Cannot restrict an expression twice.")
     # Configure a propagator for this side and apply to subtree
     # FIXME: Reuse cache between these calls!
     return map_expr_dag(self._rp[o.side()], o.ufl_operands[0])
示例#17
0
def check_integrand_arity(expr, arguments):
    arguments = tuple(
        sorted(set(arguments), key=lambda x: (x.number(), x.part())))
    rules = ArityChecker(arguments)
    args = map_expr_dag(rules, expr, compress=False)
    if args != arguments:
        raise ArityMismatch(
            "Integrand arguments {0} differ from form arguments {1}.".format(
                args, arguments))
示例#18
0
def change_to_reference_grad(e):
    """Change Grad objects in expression to products of JacobianInverse and ReferenceGrad.

    Assumes the expression is preprocessed or at least that derivatives have been expanded.

    @param e:
        An Expr or Form.
    """
    mf = OLDChangeToReferenceGrad()
    # mf = NEWChangeToReferenceGrad()
    return map_expr_dag(mf, e)
示例#19
0
 def coordinate_derivative(self, o, f, w, v, cd):
     from ufl.algorithms import extract_unique_elements
     spaces = set(c.family() for c in extract_unique_elements(o))
     unsupported_spaces = {"Argyris", "Bell", "Hermite", "Morley"}
     if spaces & unsupported_spaces:
         error("CoordinateDerivative is not supported for elements of type %s. "
               "This is because their pullback is not implemented in UFL." % unsupported_spaces)
     _, w, v, cd = o.ufl_operands
     rules = CoordinateDerivativeRuleset(w, v, cd)
     key = (CoordinateDerivativeRuleset, w, v, cd)
     return map_expr_dag(rules, f, vcache=self.vcache[key], rcache=self.rcache[key])
示例#20
0
文件: fem.py 项目: jmv2009/tsfc
 def detJ_at(self, point):
     expr = JacobianDeterminant(self.mt.terminal.ufl_domain())
     if self.mt.restriction == '+':
         expr = PositiveRestricted(expr)
     elif self.mt.restriction == '-':
         expr = NegativeRestricted(expr)
     config = {"point_set": PointSingleton(point)}
     config.update(self.config)
     context = PointSetContext(**config)
     expr = self.preprocess(expr, context)
     return map_expr_dag(context.translator, expr)
示例#21
0
 def coordinate_derivative(self, o):
     from ufl.algorithms import extract_unique_elements
     spaces = set(c.family() for c in extract_unique_elements(o))
     unsupported_spaces = {"Argyris", "Bell", "Hermite", "Morley"}
     if spaces & unsupported_spaces:
         error("CoordinateDerivative is not supported for elements of type %s. "
               "This is because their pullback is not implemented in UFL." % unsupported_spaces)
     f, w, v, cd = o.ufl_operands
     f = self(f)  # transform f
     rules = CoordinateDerivativeRuleset(w, v, cd)
     return map_expr_dag(rules, f)
    def to_reference_coordinates(ufl_coordinate_element):
        # Set up UFL form
        cell = ufl_coordinate_element.cell()
        domain = ufl.Mesh(ufl_coordinate_element)
        K = ufl.JacobianInverse(domain)
        x = ufl.SpatialCoordinate(domain)
        x0_element = ufl.VectorElement("Real", cell, 0)
        x0 = ufl.Coefficient(ufl.FunctionSpace(domain, x0_element))
        expr = ufl.dot(K, x - x0)

        # Translation to GEM
        C = ufl_utils.coordinate_coefficient(domain)
        expr = ufl_utils.preprocess_expression(expr)
        expr = ufl_utils.replace_coordinates(expr, C)
        expr = ufl_utils.simplify_abs(expr)

        builder = firedrake_interface.KernelBuilderBase()
        builder._coefficient(C, "C")
        builder._coefficient(x0, "x0")

        dim = cell.topological_dimension()
        point = gem.Variable('X', (dim, ))
        context = tsfc.fem.GemPointContext(
            interface=builder,
            ufl_cell=cell,
            precision=parameters["precision"],
            point_indices=(),
            point_expr=point,
        )
        translator = tsfc.fem.Translator(context)
        ir = map_expr_dag(translator, expr)

        # Unroll result
        ir = [gem.Indexed(ir, alpha) for alpha in numpy.ndindex(ir.shape)]

        # Unroll IndexSums
        max_extent = parameters["unroll_indexsum"]
        if max_extent:

            def predicate(index):
                return index.extent <= max_extent

        ir = gem.optimise.unroll_indexsum(ir, predicate=predicate)

        # Translate to COFFEE
        ir = impero_utils.preprocess_gem(ir)
        return_variable = gem.Variable('dX', (dim, ))
        assignments = [(gem.Indexed(return_variable, (i, )), e)
                       for i, e in enumerate(ir)]
        impero_c = impero_utils.compile_gem(assignments, ())
        body = tsfc.coffee.generate(impero_c, {}, parameters["precision"])
        body.open_scope = False

        return body
def to_reference_coordinates(ufl_coordinate_element, parameters):
    # Set up UFL form
    cell = ufl_coordinate_element.cell()
    domain = ufl.Mesh(ufl_coordinate_element)
    K = ufl.JacobianInverse(domain)
    x = ufl.SpatialCoordinate(domain)
    x0_element = ufl.VectorElement("Real", cell, 0)
    x0 = ufl.Coefficient(ufl.FunctionSpace(domain, x0_element))
    expr = ufl.dot(K, x - x0)

    # Translation to GEM
    C = ufl.Coefficient(ufl.FunctionSpace(domain, ufl_coordinate_element))
    expr = ufl_utils.preprocess_expression(expr)
    expr = ufl_utils.simplify_abs(expr)

    builder = firedrake_interface.KernelBuilderBase()
    builder.domain_coordinate[domain] = C
    builder._coefficient(C, "C")
    builder._coefficient(x0, "x0")

    dim = cell.topological_dimension()
    point = gem.Variable('X', (dim,))
    context = tsfc.fem.GemPointContext(
        interface=builder,
        ufl_cell=cell,
        precision=parameters["precision"],
        point_indices=(),
        point_expr=point,
    )
    translator = tsfc.fem.Translator(context)
    ir = map_expr_dag(translator, expr)

    # Unroll result
    ir = [gem.Indexed(ir, alpha) for alpha in numpy.ndindex(ir.shape)]

    # Unroll IndexSums
    max_extent = parameters["unroll_indexsum"]
    if max_extent:
        def predicate(index):
            return index.extent <= max_extent
        ir = gem.optimise.unroll_indexsum(ir, predicate=predicate)

    # Translate to COFFEE
    ir = impero_utils.preprocess_gem(ir)
    return_variable = gem.Variable('dX', (dim,))
    assignments = [(gem.Indexed(return_variable, (i,)), e)
                   for i, e in enumerate(ir)]
    impero_c = impero_utils.compile_gem(assignments, ())
    body = tsfc.coffee.generate(impero_c, {}, parameters["precision"])
    body.open_scope = False

    return body
示例#24
0
文件: ufl_utils.py 项目: inducer/tsfc
def split_coefficients(expression, split):
    """Split mixed coefficients, so mixed elements need not be
    implemented.

    :arg split: A :py:class:`dict` mapping each mixed coefficient to a
                sequence of subcoefficients.  If None, calling this
                function is a no-op.
    """
    if split is None:
        return expression

    splitter = CoefficientSplitter(split)
    return map_expr_dag(splitter, expression)
示例#25
0
文件: fem.py 项目: peide/tsfc
    def physical_edge_lengths(self):
        expr = ufl.classes.CellEdgeVectors(self.mt.terminal.ufl_domain())
        if self.mt.restriction == '+':
            expr = PositiveRestricted(expr)
        elif self.mt.restriction == '-':
            expr = NegativeRestricted(expr)

        expr = ufl.as_vector([ufl.sqrt(ufl.dot(expr[i, :], expr[i, :])) for i in range(3)])
        expr = preprocess_expression(expr)
        config = {"point_set": PointSingleton([1/3, 1/3])}
        config.update(self.config)
        context = PointSetContext(**config)
        return map_expr_dag(context.translator, expr)
示例#26
0
def split_coefficients(expression, split):
    """Split mixed coefficients, so mixed elements need not be
    implemented.

    :arg split: A :py:class:`dict` mapping each mixed coefficient to a
                sequence of subcoefficients.  If None, calling this
                function is a no-op.
    """
    if split is None:
        return expression

    splitter = CoefficientSplitter(split)
    return map_expr_dag(splitter, expression)
示例#27
0
文件: fem.py 项目: jmv2009/tsfc
 def jacobian_at(self, point):
     ps = PointSingleton(point)
     expr = Jacobian(self.mt.terminal.ufl_domain())
     assert ps.expression.shape == (
         expr.ufl_domain().topological_dimension(), )
     if self.mt.restriction == '+':
         expr = PositiveRestricted(expr)
     elif self.mt.restriction == '-':
         expr = NegativeRestricted(expr)
     config = {"point_set": PointSingleton(point)}
     config.update(self.config)
     context = PointSetContext(**config)
     expr = self.preprocess(expr, context)
     return map_expr_dag(context.translator, expr)
示例#28
0
def compile_ufl(expression, interior_facet=False, point_sum=False, **kwargs):
    context = PointSetContext(**kwargs)

    # Abs-simplification
    expression = simplify_abs(expression)
    if interior_facet:
        expressions = []
        for rs in itertools.product(("+", "-"), repeat=len(context.argument_multiindices)):
            expressions.append(map_expr_dag(PickRestriction(*rs), expression))
    else:
        expressions = [expression]

    # Translate UFL to GEM, lowering finite element specific nodes
    result = map_expr_dags(context.translator, expressions)
    if point_sum:
        result = [gem.index_sum(expr, context.point_indices) for expr in result]
    return result
示例#29
0
def check_integrand_arity(expr, arguments, complex_mode=False):
    arguments = tuple(sorted(set(arguments),
                             key=lambda x: (x.number(), x.part())))
    rules = ArityChecker(arguments)
    arg_tuples = map_expr_dag(rules, expr, compress=False)
    args = tuple(a[0] for a in arg_tuples)
    if args != arguments:
        raise ArityMismatch("Integrand arguments {0} differ from form arguments {1}.".format(args, arguments))
    if complex_mode:
        # Check that the test function is conjugated and that any
        # trial function is not conjugated. Further arguments are
        # treated as trial funtions (i.e. no conjugation) but this
        # might not be correct.
        for arg, conj in arg_tuples:
            if arg.number() == 0 and not conj:
                raise ArityMismatch("Failure to conjugate test function in complex Form")
            elif arg.number() > 0 and conj:
                raise ArityMismatch("Argument {0} is spuriously conjugated in complex Form".format(arg))
示例#30
0
def coarsen_bc(bc):
    new_V = coarsen_thing(bc.function_space())
    val = bc._original_val
    zeroed = bc._currently_zeroed
    subdomain = bc.sub_domain
    method = bc.method

    new_val = val

    if isinstance(val, firedrake.Expression):
        new_val = val

    if isinstance(val, (firedrake.Constant, firedrake.Function)):
        mapper = CoarsenIntegrand()
        new_val = map_expr_dag(mapper, val)

    new_bc = firedrake.DirichletBC(new_V, new_val, subdomain, method=method)

    if zeroed:
        new_bc.homogenize()

    return new_bc
示例#31
0
def check_integrand_arity(expr, arguments, complex_mode=False):
    arguments = tuple(
        sorted(set(arguments), key=lambda x: (x.number(), x.part())))
    rules = ArityChecker(arguments)
    arg_tuples = map_expr_dag(rules, expr, compress=False)
    args = tuple(a[0] for a in arg_tuples)
    if args != arguments:
        raise ArityMismatch(
            "Integrand arguments {0} differ from form arguments {1}.".format(
                args, arguments))
    if complex_mode:
        # Check that the test function is conjugated and that any
        # trial function is not conjugated. Further arguments are
        # treated as trial funtions (i.e. no conjugation) but this
        # might not be correct.
        for arg, conj in arg_tuples:
            if arg.number() == 0 and not conj:
                raise ArityMismatch(
                    "Failure to conjugate test function in complex Form")
            elif arg.number() > 0 and conj:
                raise ArityMismatch(
                    "Argument {0} is spuriously conjugated in complex Form".
                    format(arg))
示例#32
0
def coarsen_bc(bc):
    new_V = coarsen_thing(bc.function_space())
    val = bc._original_val
    zeroed = bc._currently_zeroed
    subdomain = bc.sub_domain
    method = bc.method

    new_val = val

    if isinstance(val, firedrake.Expression):
        new_val = val

    if isinstance(val, (firedrake.Constant, firedrake.Function)):
        mapper = CoarsenIntegrand()
        new_val = map_expr_dag(mapper, val)

    new_bc = firedrake.DirichletBC(new_V, new_val, subdomain,
                                   method=method)

    if zeroed:
        new_bc.homogenize()

    return new_bc
示例#33
0
def strip_terminal_data(o):
    """Return a new form where all terminals have been replaced by UFL-only
    equivalents.

    :arg o: The object to be stripped. This must either be a :class:`~.Form`
        or :class:`~.Integral`.
    :returns: A 2-tuple containing an equivalent UFL-only object and a mapping
        allowing the original form to be reconstructed using
        :func:`replace_terminal_data`.

    This function is useful for forms containing augmented UFL objects that
    hold references to large data structures. These objects are be extracted
    into the mapping allowing the form to be cached without leaking memory.
    """
    # We need to keep track of two maps because integrals store references to the
    # domain and ``replace`` expects only a mapping containing ``Expr`` objects.
    if isinstance(o, Form):
        integrals = []
        expr_map = {}
        domain_map = {}
        for integral in o.integrals():
            itg, (emap, dmap) = strip_terminal_data(integral)
            integrals.append(itg)
            expr_map.update(emap)
            domain_map.update(dmap)
        return Form(integrals), (expr_map, domain_map)
    elif isinstance(o, Integral):
        handler = TerminalStripper()
        integrand = map_expr_dag(handler, o.integrand())
        domain = strip_domain(o.ufl_domain())
        # invert the mapping so it can be passed straight into replace_terminal_data
        expr_map = {v: k for k, v in handler.mapping.items()}
        domain_map = {domain: o.ufl_domain()}
        return o.reconstruct(integrand, domain=domain), (expr_map, domain_map)
    else:
        raise ValueError("Only Form or Integral inputs expected")
示例#34
0
def coarse_expr(expr, self, coefficient_mapping=None):
    if expr is None:
        return None
    mapper = CoarsenIntegrand(self, coefficient_mapping)
    return map_expr_dag(mapper, expr)
示例#35
0
        # Adding test function and other expression
        TestFunction(U) + 1.0,
        # Multiplying test functions:
        TestFunction(U) * TestFunction(U),
        TestFunction(U) * TestFunction(V)[0],
        # Nonlinear operator applied to test function
        sin(TestFunction(U)),
        sin(TestFunction(V)[1]),
    ]

    from ufl.classes import Sum, Operator, Expr, Argument

    for expr in expressions:
        func = ScalarFactorizer()

        e = map_expr_dag(func, expr, compress=False)
        print
        if isinstance(e, dict):
            print str(expr), " = ", ",  ".join(
                "%s[%d]: %s" % (func._arg, k, e[k]) for k in e)
        else:
            assert expr == e
            print str(expr), " = ", str(e)

    for expr in errors:
        func = ScalarFactorizer()
        try:
            e = map_expr_dag(func, expr, compress=False)
            ok = False
        except:
            ok = True
示例#36
0
 def coordinate_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     o_ = o.ufl_operands
     return CoordinateDerivative(map_expr_dag(self, o_[0]), o_[1], o_[2],
                                 o_[3])
示例#37
0
 def variable_derivative(self, o, f, dummy_v):
     rules = VariableRuleset(o.ufl_operands[1])
     return map_expr_dag(rules, f)
示例#38
0
 def grad(self, o, f):
     rules = GradRuleset(o.ufl_shape[-1])
     return map_expr_dag(rules, f)
示例#39
0
 def grad(self, o, f):
     rules = GradRuleset(o.ufl_shape[-1])
     return map_expr_dag(rules, f)
示例#40
0
 def coordinate_derivative(self, o):
     o = o.ufl_operands
     return CoordinateDerivative(map_expr_dag(self, o[0]), o[1], o[2], o[3])
示例#41
0
def balance_modifiers(expr):
    mf = BalanceModifiers()
    return map_expr_dag(mf, expr)
def relabel_indices(expr):
    relabeller._reset()
    return map_expr_dag(relabeller, expr, compress=True)
示例#43
0
def replace_coordinates(integrand, coordinate_coefficient):
    """Replace SpatialCoordinate nodes with Coefficients."""
    return map_expr_dag(SpatialCoordinateReplacer(coordinate_coefficient), integrand)
示例#44
0
 def coordinate_derivative(self, o):
     o = o.ufl_operands
     return CoordinateDerivative(map_expr_dag(self, o[0]), o[1], o[2], o[3])
示例#45
0
 def reference_grad(self, o, f):
     rules = ReferenceGradRuleset(o.ufl_shape[-1])  # FIXME: Look over this and test better.
     return map_expr_dag(rules, f)
示例#46
0
 def reference_grad(self, o, f):
     rules = ReferenceGradRuleset(
         o.ufl_shape[-1])  # FIXME: Look over this and test better.
     return map_expr_dag(rules, f)
示例#47
0
 def variable_derivative(self, o, f, dummy_v):
     rules = VariableRuleset(o.ufl_operands[1])
     return map_expr_dag(rules, f)
示例#48
0
 def coefficient_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     dummy, w, v, cd = o.ufl_operands
     rules = GateauxDerivativeRuleset(w, v, cd)
     return map_expr_dag(rules, f)
示例#49
0
 def coefficient_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     dummy, w, v, cd = o.ufl_operands
     rules = GateauxDerivativeRuleset(w, v, cd)
     return map_expr_dag(rules, f)
示例#50
0
def expression2latex(expression, argument_names=None, coefficient_names=None):
    rules = Expression2LatexHandler(argument_names, coefficient_names)
    return map_expr_dag(rules, expression)
示例#51
0
 def coordinate_derivative(self, o, f, dummy_w, dummy_v, dummy_cd):
     o_ = o.ufl_operands
     return CoordinateDerivative(map_expr_dag(self, o_[0]), o_[1], o_[2], o_[3])
示例#52
0
def expression2unicode(expression, argument_names=None, coefficient_names=None):
    rules = Expression2UnicodeHandler(argument_names, coefficient_names)
    return map_expr_dag(rules, expression)
示例#53
0
 def coordinate_derivative(self, o):
     f, w, v, cd = o.ufl_operands
     f = self(f)  # transform f
     rules = CoordinateDerivativeRuleset(w, v, cd)
     return map_expr_dag(rules, f)
示例#54
0
def extract_tested_expressions(expr):
    func = ScalarFactorizer()
    e = map_expr_dag(func, expr, compress=False)
    return e, func._arg
示例#55
0
def map_integrand_dags(function, form, only_integral_type=None, compress=True):
    return map_integrands(lambda expr: map_expr_dag(function, expr, compress),
                          form, only_integral_type)