Ejemplo n.º 1
0
def generate_integral_code(ir, prefix, parameters):
    "Generate code for integral from intermediate representation."

    info("Generating code from ffc.uflacs representation")

    # FIXME: Is this the right precision value to use? Make it default to None or 0.
    precision = ir["integrals_metadata"]["precision"]

    # Create FFC C++ backend
    backend = FFCBackend(ir, parameters)

    # Configure kernel generator
    ig = IntegralGenerator(ir, backend, precision)

    # Generate code ast for the tabulate_tensor body
    parts = ig.generate()

    # Format code as string
    body = format_indented_lines(parts.cs_format(precision), 1)

    # Generate generic ffc code snippets and add uflacs specific parts
    code = initialize_integral_code(ir, prefix, parameters)
    code["tabulate_tensor"] = body
    code["additional_includes_set"] = set(ig.get_includes())
    code["additional_includes_set"].update(
        ir.get("additional_includes_set", ()))

    # TODO: Move to initialize_integral_code, this is not representation specific
    if ir.get("num_cells") is not None:
        ret = backend.language.Return(ir["num_cells"])
        code["num_cells"] = format_indented_lines(ret.cs_format(), 1)

    return code
Ejemplo n.º 2
0
def UnitTriangle(color=(0.0, 1.0, 0.0, 0.5)):
    "Return model for unit tetrahedron."

    info("Plotting unit triangle")

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Create vertice
    v0 = soya.Vertex(scene, 0.0, 0.0, 0.0, diffuse=color)
    v1 = soya.Vertex(scene, 1.0, 0.0, 0.0, diffuse=color)
    v2 = soya.Vertex(scene, 0.0, 1.0, 0.0, diffuse=color)

    # Create edges
    e0 = Cylinder(scene, v0, v1, 0.007)
    e1 = Cylinder(scene, v0, v2, 0.007)
    e2 = Cylinder(scene, v1, v2, 0.007)

    # Create face
    f = soya.Face(scene, (v0, v1, v2))

    # Make face double sided
    f.double_sided = 1

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 3
0
def generate_integral_code(ir, prefix, parameters):
    "Generate code for integral from intermediate representation."

    info("Generating code from ffc.uflacs representation")

    # FIXME: Is this the right precision value to use? Make it default to None or 0.
    precision = ir["integrals_metadata"]["precision"]

    # Create FFC C++ backend
    backend = FFCBackend(ir, parameters)

    # Configure kernel generator
    ig = IntegralGenerator(ir, backend, precision)

    # Generate code ast for the tabulate_tensor body
    parts = ig.generate()

    # Format code as string
    body = format_indented_lines(parts.cs_format(precision), 1)

    # Generate generic ffc code snippets and add uflacs specific parts
    code = initialize_integral_code(ir, prefix, parameters)
    code["tabulate_tensor"] = body
    code["additional_includes_set"] = set(ig.get_includes())
    code["additional_includes_set"].update(ir.get("additional_includes_set", ()))

    # TODO: Move to initialize_integral_code, this is not representation specific
    if ir.get("num_cells") is not None:
        ret = backend.language.Return(ir["num_cells"])
        code["num_cells"] = format_indented_lines(ret.cs_format(), 1)

    return code
Ejemplo n.º 4
0
Archivo: test.py Proyecto: doru1004/FFC
def generate_test_cases(bench, only_forms):
    "Generate form files for all test cases."

    begin("Generating test cases")

    # Copy form files
    if bench:
        form_directory = bench_directory
    else:
        form_directory = demo_directory

    # Make list of form files
    form_files = [f for f in os.listdir(form_directory) if f.endswith(".ufl")]
    if only_forms:
        form_files = [f for f in form_files if f in only_forms]
    form_files.sort()

    for f in form_files:
        shutil.copy(os.path.join(form_directory, f), ".")
    info_green("Found %d form files" % len(form_files))

    # Generate form files for forms
    info("Generating form files for extra forms: Not implemented")

    # Generate form files for elements
    if not bench:
        from elements import elements
        info("Generating form files for extra elements (%d elements)"
             % len(elements))
        for (i, element) in enumerate(elements):
            open("X_Element%d.ufl" % i, "w").write("element = %s" % element)

    end()
Ejemplo n.º 5
0
def PointSecondDerivative(x):
    "Return model for evaluation of second derivatives at given point."

    info("Plotting dof: point derivative at x = %s" % str(x))

    # Make sure point is 3D
    x = to3d(x)

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Define material (color) for the sphere
    material = soya.Material()
    material.diffuse = (0.0, 0.0, 0.0, 0.05)

    # Create sphere
    sphere = Sphere(scene, material=material)

    # Scale and moveand move to coordinate
    sphere.scale(0.15, 0.15, 0.15)
    p = sphere.position()
    p.set_xyz(x[0], x[1], x[2])
    sphere.move(p)

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 6
0
Archivo: plot.py Proyecto: doru1004/FFC
def UnitTriangle(color=(0.0, 1.0, 0.0, 0.5)):
    "Return model for unit tetrahedron."

    info("Plotting unit triangle")

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Create vertice
    v0 = soya.Vertex(scene, 0.0, 0.0, 0.0, diffuse=color)
    v1 = soya.Vertex(scene, 1.0, 0.0, 0.0, diffuse=color)
    v2 = soya.Vertex(scene, 0.0, 1.0, 0.0, diffuse=color)

    # Create edges
    e0 = Cylinder(scene, v0, v1, 0.007)
    e1 = Cylinder(scene, v0, v2, 0.007)
    e2 = Cylinder(scene, v1, v2, 0.007)

    # Create face
    f = soya.Face(scene, (v0, v1, v2))

    # Make face double sided
    f.double_sided = 1

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 7
0
def generate_integral_code(ir, prefix, parameters):
    "Generate code for integral from intermediate representation."

    info("Generating code from tsfc representation")

    # Generate generic ffc code snippets
    code = initialize_integral_code(ir, prefix, parameters)

    # Go unoptimized if TSFC mode has not been set yet
    integral_data, form_data, prefix, parameters = ir["compile_integral"]
    parameters = parameters.copy()
    parameters.setdefault("mode", "vanilla")

    # Generate tabulate_tensor body
    ast = compile_integral(integral_data, form_data, None, parameters,
                           interface=ufc_interface)

    # COFFEE vectorize
    knl = ASTKernel(ast)
    knl.plan_cpu(dict(optlevel='Ov'))

    tsfc_code = "".join(b.gencode() for b in ast.body)
    tsfc_code = tsfc_code.replace("#pragma coffee", "//#pragma coffee") # FIXME
    code["tabulate_tensor"] = tsfc_code

    includes = set()
    includes.update(ir.get("additional_includes_set", ()))
    includes.update(ast.headers)
    includes.add("#include <cstring>")  # memset
    if any(node.funcall.symbol.startswith("boost::math::")
           for node in Find(coffee.FunCall).visit(ast)[coffee.FunCall]):
        includes.add("#include <boost/math/special_functions.hpp>")
    code["additional_includes_set"] = includes

    return code
Ejemplo n.º 8
0
def extract_monomial_form(integrals, function_replace_map):
    """
    Extract monomial representation of form (if possible). When
    successful, the form is represented as a sum of products of scalar
    components of basis functions or derivatives of basis functions.
    If unsuccessful, MonomialException is raised.
    """

    info("Extracting monomial form representation from UFL form")

    # Iterate over all integrals
    monomial_form = MonomialForm()
    for integral in integrals:

        # Get measure and integrand
        measure = integral.measure()
        if measure.domain_type() == "point":
            raise MonomialException(
                "Point integrals are not supported by tensor representation.")

        integrand = integral.integrand()

        # Extract monomial representation if possible
        integrand = extract_monomial_integrand(integrand, function_replace_map)
        monomial_form.append(integrand, measure)

    return monomial_form
Ejemplo n.º 9
0
def DirectionalEvaluation(x, n, flip=False, center=False):
    "Return model for directional evaluation at given point in given direction."

    info("Plotting dof: directional evaluation at x = %s in direction n = %s" % (str(x), str(n)))

    # Make sure points are 3D
    x = to3d(x)
    n = to3d(n)

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Normalize
    n = array(n)
    n = 0.75 * n / norm(n)

    # Flip normal if necessary
    if flip and not pointing_outwards(x, n):
        info("Flipping direction of arrow so it points outward.")
        n = -n

    # Create arrow
    arrow = Arrow(scene, x, n, center)

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 10
0
Archivo: plot.py Proyecto: doru1004/FFC
def PointSecondDerivative(x):
    "Return model for evaluation of second derivatives at given point."

    info("Plotting dof: point derivative at x = %s" % str(x))

    # Make sure point is 3D
    x = to3d(x)

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Define material (color) for the sphere
    material = soya.Material()
    material.diffuse = (0.0, 0.0, 0.0, 0.05)

    # Create sphere
    sphere = Sphere(scene, material=material)

    # Scale and moveand move to coordinate
    sphere.scale(0.15, 0.15, 0.15)
    p = sphere.position()
    p.set_xyz(x[0], x[1], x[2])
    sphere.move(p)

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 11
0
def verify_element(num_elements, i, ufl_element):
    info("\nVerifying element %d of %d: %s" %
         (i, num_elements, str(ufl_element)))
    error = compile_element(ufl_element, ffc_fail, log_file)

    # Return if test failed
    if error:
        return 1

    # Get FIAT values that are formatted in the same way as the values from
    # evaluate_basis and evaluate_basis_derivatives.
    # t = time.time()
    fiat_values = get_fiat_values(ufl_element)
    # print "fiat_vals: ", time.time() - t

    # Get FFC values.
    t = time.time()
    ffc_values = get_ffc_values(ufl_element)
    if ffc_values is None:
        return 1
    debug("  time to compute FFC values: %f" % (time.time() - t))

    # Compare values and return number of tests.
    return verify_values(ufl_element, fiat_values, ffc_values, dif_cri,
                         dif_acc, correct, log_file)
Ejemplo n.º 12
0
Archivo: plot.py Proyecto: doru1004/FFC
def DirectionalEvaluation(x, n, flip=False, center=False):
    "Return model for directional evaluation at given point in given direction."

    info("Plotting dof: directional evaluation at x = %s in direction n = %s" % (str(x), str(n)))

    # Make sure points are 3D
    x = to3d(x)
    n = to3d(n)

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Normalize
    n = array(n)
    n = 0.75 * n / norm(n)

    # Flip normal if necessary
    if flip and not pointing_outwards(x, n):
        info("Flipping direction of arrow so it points outward.")
        n = -n

    # Create arrow
    arrow = Arrow(scene, x, n, center)

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 13
0
def generate_test_cases(bench, only_forms):
    "Generate form files for all test cases."

    begin("Generating test cases")

    # Copy form files
    if bench:
        form_directory = bench_directory
    else:
        form_directory = demo_directory

    # Make list of form files
    form_files = [f for f in os.listdir(form_directory) if f.endswith(".ufl")]
    if only_forms:
        form_files = [f for f in form_files if f in only_forms]
    form_files.sort()

    for f in form_files:
        shutil.copy("%s/%s" % (form_directory, f), ".")
    info_green("Found %d form files" % len(form_files))

    # Generate form files for forms
    info("Generating form files for extra forms: Not implemented")

    # Generate form files for elements
    if not bench:
        from elements import elements
        info("Generating form files for extra elements (%d elements)" %
             len(elements))
        for (i, element) in enumerate(elements):
            open("X_Element%d.ufl" % i, "w").write("element = %s" % element)

    end()
Ejemplo n.º 14
0
def integrate(monomial, integral_type, facet0, facet1, quadrature_degree,
              quadrature_rule, cellname, facet_cellname):
    """Compute the reference tensor for a given monomial term of a
    multilinear form"""

    info("Precomputing integrals on reference element")

    # Start timing
    tic = time.time()

    # Initialize quadrature points and weights
    (points, weights) = _init_quadrature(monomial.arguments, integral_type,
                                         quadrature_degree, quadrature_rule,
                                         cellname, facet_cellname)

    # Initialize quadrature table for basis functions
    table = _init_table(monomial.arguments, integral_type, points, facet0,
                        facet1)

    # Compute table Psi for each factor
    psis = [_compute_psi(v, table, len(points), integral_type) \
                for v in monomial.arguments]

    # Compute product of all Psis
    A0 = _compute_product(psis, monomial.float_value * weights)

    # Report elapsed time and number of entries
    toc = time.time() - tic
    num_entries = numpy.prod(numpy.shape(A0))
    debug("%d entries computed in %.3g seconds" % (num_entries, toc))
    debug("Shape of reference tensor: " + str(numpy.shape(A0)))

    return A0
Ejemplo n.º 15
0
def _analyze_form(form, parameters):
    "Analyze form, returning form data."

    # Check that form is not empty
    ffc_assert(not form.empty(),
               "Form (%s) seems to be zero: cannot compile it." % str(form))

    # Compute form metadata
    if parameters["representation"] == "uflacs":
        # Temporary workaround to let uflacs have a different preprocessing pipeline
        # than the legacy representations quadrature and tensor. This approach imposes
        # a limitation that e.g. uflacs and tensor representation cannot be mixed in the same form.
        from ufl.classes import Jacobian
        form_data = compute_form_data(form,
                                      do_apply_function_pullbacks=True,
                                      do_apply_integral_scaling=True,
                                      do_apply_geometry_lowering=True,
                                      preserve_geometry_types=(Jacobian,),
                                      do_apply_restrictions=True,
                                      )
    else:
        form_data = compute_form_data(form)

    info("")
    info(str(form_data))

    # Attach integral meta data
    _attach_integral_metadata(form_data, parameters)

    return form_data
Ejemplo n.º 16
0
def _analyze_form(form, parameters):
    "Analyze form, returning form data."

    # Check that form is not empty
    if form.empty():
        error("Form (%s) seems to be zero: cannot compile it." % str(form))

    # Hack to override representation with environment variable
    forced_r = os.environ.get("FFC_FORCE_REPRESENTATION")
    if forced_r:
        warning(
            "representation:    forced by $FFC_FORCE_REPRESENTATION to '%s'" %
            forced_r)
        r = forced_r
    else:
        # Check representation parameters to figure out how to
        # preprocess
        r = _extract_representation_family(form, parameters)
    debug("Preprocessing form using '%s' representation family." % r)

    # Compute form metadata
    if r == "uflacs":
        # Temporary workaround to let uflacs have a different
        # preprocessing pipeline than the legacy quadrature
        # representation. This approach imposes a limitation that,
        # e.g. uflacs and qudrature, representations cannot be mixed
        # in the same form.
        from ufl.classes import Jacobian
        form_data = compute_form_data(form,
                                      do_apply_function_pullbacks=True,
                                      do_apply_integral_scaling=True,
                                      do_apply_geometry_lowering=True,
                                      preserve_geometry_types=(Jacobian, ),
                                      do_apply_restrictions=True)
    elif r == "tsfc":
        try:
            # TSFC provides compute_form_data wrapper using correct
            # kwargs
            from tsfc.ufl_utils import compute_form_data as tsfc_compute_form_data
        except ImportError:
            error(
                "Failed to import tsfc.ufl_utils.compute_form_data when asked "
                "for tsfc representation.")
        form_data = tsfc_compute_form_data(form)
    elif r == "quadrature":
        # quadrature representation
        form_data = compute_form_data(form)
    else:
        error("Unexpected representation family '%s' for form preprocessing." %
              r)

    info("")
    info(str(form_data))

    # Attach integral meta data
    _attach_integral_metadata(form_data, r, parameters)
    _validate_representation_choice(form_data, r)

    return form_data
def compute_integral_ir(itg_data,
                        form_data,
                        form_id,
                        parameters):
    "Compute intermediate represention of integral."

    info("Computing quadrature representation")

    # Initialise representation
    ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id)

    # Sort integrals into a dict with number of integral points as key
    sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata, form_data)

    # Tabulate quadrature points and basis function values in these points
    integrals_dict, psi_tables, quad_weights = \
        _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data)

    # Save tables for quadrature weights and points
    ir["quadrature_weights"]  = quad_weights

    # Create dimensions of primary indices, needed to reset the argument 'A'
    # given to tabulate_tensor() by the assembler.
    ir["prim_idims"] = [create_element(ufl_element).space_dimension()
                        for ufl_element in form_data.argument_elements]

    # Create and save the optisation parameters.
    ir["optimise_parameters"] = _parse_optimise_parameters(parameters)

    # Create transformer.
    if ir["optimise_parameters"]["optimisation"]:
        QuadratureTransformerClass = QuadratureTransformerOpt
    else:
        QuadratureTransformerClass = QuadratureTransformer
    transformer = QuadratureTransformerClass(psi_tables,
                                             quad_weights,
                                             form_data.geometric_dimension,
                                             form_data.topological_dimension,
                                             ir["entitytype"],
                                             form_data.function_replace_map,
                                             ir["optimise_parameters"])

    # Transform integrals.
    ir["trans_integrals"] = _transform_integrals_by_type(ir, transformer, integrals_dict,
                                                         itg_data.domain_type, form_data.cell)

    # Save tables populated by transformer
    ir["name_map"] = transformer.name_map
    ir["unique_tables"] = transformer.unique_tables  # Basis values?

    # Save tables map, to extract table names for optimisation option -O.
    ir["psi_tables_map"] = transformer.psi_tables_map
    ir["additional_includes_set"] = transformer.additional_includes_set

    # Insert empty data which will be populated if optimization is turned on
    ir["geo_consts"] = {}

    return ir
Ejemplo n.º 18
0
def compute_integral_ir(itg_data, form_data, form_id, parameters):
    "Compute intermediate represention of integral."

    info("Computing quadrature representation")

    # Initialise representation
    ir = initialize_integral_ir("quadrature", itg_data, form_data, form_id)

    # Sort integrals into a dict with number of integral points as key
    sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata,
                                       form_data)

    # Tabulate quadrature points and basis function values in these points
    integrals_dict, psi_tables, quad_weights = \
        _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data)

    # Save tables for quadrature weights and points
    ir["quadrature_weights"] = quad_weights

    # Create dimensions of primary indices, needed to reset the argument 'A'
    # given to tabulate_tensor() by the assembler.
    ir["prim_idims"] = [
        create_element(ufl_element).space_dimension()
        for ufl_element in form_data.argument_elements
    ]

    # Create and save the optisation parameters.
    ir["optimise_parameters"] = _parse_optimise_parameters(parameters)

    # Create transformer.
    if ir["optimise_parameters"]["optimisation"]:
        QuadratureTransformerClass = QuadratureTransformerOpt
    else:
        QuadratureTransformerClass = QuadratureTransformer
    transformer = QuadratureTransformerClass(psi_tables, quad_weights,
                                             form_data.geometric_dimension,
                                             form_data.topological_dimension,
                                             ir["entitytype"],
                                             form_data.function_replace_map,
                                             ir["optimise_parameters"])

    # Transform integrals.
    ir["trans_integrals"] = _transform_integrals_by_type(
        ir, transformer, integrals_dict, itg_data.domain_type, form_data.cell)

    # Save tables populated by transformer
    ir["name_map"] = transformer.name_map
    ir["unique_tables"] = transformer.unique_tables  # Basis values?

    # Save tables map, to extract table names for optimisation option -O.
    ir["psi_tables_map"] = transformer.psi_tables_map
    ir["additional_includes_set"] = transformer.additional_includes_set

    # Insert empty data which will be populated if optimization is turned on
    ir["geo_consts"] = {}

    return ir
Ejemplo n.º 19
0
def compute_integral_ir(itg_data,
                        form_data,
                        form_id,
                        element_numbers,
                        parameters):
    "Compute intermediate represention of integral."

    info("Computing tensor representation")

    # Extract monomial representation
    integrands = [itg.integrand() for itg in itg_data.integrals]
    monomial_form = extract_monomial_form(integrands, form_data.function_replace_map)

    # Transform monomial form to reference element
    transform_monomial_form(monomial_form)

    # Get some integral properties
    integral_type = itg_data.integral_type
    quadrature_degree = itg_data.metadata["quadrature_degree"]
    quadrature_rule = itg_data.metadata["quadrature_rule"]

    # Get some cell properties
    cell = itg_data.domain.ufl_cell()
    num_facets = cell.num_facets()

    # Helper to simplify code below
    compute_terms = lambda i, j: _compute_terms(monomial_form,
                                           i, j,
                                           integral_type,
                                           quadrature_degree,
                                           quadrature_rule,
                                           cell)

    # Compute representation of cell tensor
    if integral_type == "cell":
        # Compute sum of tensor representations
        terms = compute_terms(None, None)

    elif integral_type == "exterior_facet":
        # Compute sum of tensor representations for each facet
        terms = [compute_terms(i, None) for i in range(num_facets)]

    elif integral_type == "interior_facet":
        # Compute sum of tensor representations for each facet-facet pair
        terms = [[compute_terms(i, j) for j in range(num_facets)] for i in range(num_facets)]
        for i in range(num_facets):
            for j in range(num_facets):
                reorder_entries(terms[i][j])

    else:
        error("Unhandled domain type: " + str(integral_type))

    # Initialize representation and store terms
    ir = initialize_integral_ir("tensor", itg_data, form_data, form_id)
    ir["AK"] = terms

    return ir
Ejemplo n.º 20
0
def _write_file(output, prefix, postfix, parameters):
    "Write generated code to file."
    prefix = prefix.split(os.path.join(' ',' ').split()[0])[-1]
    full_prefix = os.path.join(parameters["output_dir"], prefix)
    filename = "%s%s" % (full_prefix, postfix)
    hfile = open(filename, "w")
    hfile.write(output)
    hfile.close()
    info("Output written to " + filename + ".")
Ejemplo n.º 21
0
def optimize_integral_ir(ir, parameters):
    "Compute optimized intermediate representation of integral."

    info("Optimizing uflacs representation")

    # TODO: Implement optimization of ssa representation prior to code generation here.
    oir = ir

    return oir
def optimize_integral_ir(ir, parameters):
    "Compute optimized intermediate representation of integral."

    info("Optimizing uflacs representation")

    # Call upon uflacs to optimize ssa representation prior to code generation. Should be possible to skip this step.
    import uflacs.backends.ffc
    oir = uflacs.backends.ffc.optimize_tabulate_tensor_ir(ir, parameters)

    return oir
Ejemplo n.º 23
0
def optimize_integral_ir(ir, parameters):
    "Compute optimized intermediate representation of integral."

    info("Optimizing uflacs representation")

    # Call upon uflacs to optimize ssa representation prior to code generation. Should be possible to skip this step.
    import uflacs.backends.ffc
    oir = uflacs.backends.ffc.optimize_tabulate_tensor_ir(ir, parameters)

    return oir
Ejemplo n.º 24
0
def compute_integral_ir(itg_data, form_data, form_id, element_numbers,
                        parameters):
    "Compute intermediate represention of integral."

    info("Computing tensor representation")

    # Extract monomial representation
    integrands = [itg.integrand() for itg in itg_data.integrals]
    monomial_form = extract_monomial_form(integrands,
                                          form_data.function_replace_map)

    # Transform monomial form to reference element
    transform_monomial_form(monomial_form)

    # Get some integral properties
    integral_type = itg_data.integral_type
    quadrature_degree = itg_data.metadata["quadrature_degree"]
    quadrature_rule = itg_data.metadata["quadrature_rule"]

    # Get some cell properties
    cell = itg_data.domain.cell()
    cellname = cell.cellname()
    facet_cellname = cell.facet_cellname()
    num_facets = cell.num_facets()

    # Helper to simplify code below
    compute_terms = lambda i, j: _compute_terms(
        monomial_form, i, j, integral_type, quadrature_degree, quadrature_rule,
        cellname, facet_cellname)

    # Compute representation of cell tensor
    if integral_type == "cell":
        # Compute sum of tensor representations
        terms = compute_terms(None, None)

    elif integral_type == "exterior_facet":
        # Compute sum of tensor representations for each facet
        terms = [compute_terms(i, None) for i in range(num_facets)]

    elif integral_type == "interior_facet":
        # Compute sum of tensor representations for each facet-facet pair
        terms = [[compute_terms(i, j) for j in range(num_facets)]
                 for i in range(num_facets)]
        for i in range(num_facets):
            for j in range(num_facets):
                reorder_entries(terms[i][j])

    else:
        error("Unhandled domain type: " + str(integral_type))

    # Initialize representation and store terms
    ir = initialize_integral_ir("tensor", itg_data, form_data, form_id)
    ir["AK"] = terms

    return ir
Ejemplo n.º 25
0
def _analyze_form(form, parameters):
    "Analyze form, returning form data."

    # Check that form is not empty
    if form.empty():
        error("Form (%s) seems to be zero: cannot compile it." % str(form))

    # Hack to override representation with environment variable
    forced_r = os.environ.get("FFC_FORCE_REPRESENTATION")
    if forced_r:
        warning("representation:    forced by $FFC_FORCE_REPRESENTATION to '%s'" % forced_r)
        r = forced_r
    else:
        # Check representation parameters to figure out how to
        # preprocess
        r = _extract_representation_family(form, parameters)
    debug("Preprocessing form using '%s' representation family." % r)

    # Compute form metadata
    if r == "uflacs":
        # Temporary workaround to let uflacs have a different
        # preprocessing pipeline than the legacy quadrature
        # representation. This approach imposes a limitation that,
        # e.g. uflacs and qudrature, representations cannot be mixed
        # in the same form.
        from ufl.classes import Jacobian
        form_data = compute_form_data(form,
                                      do_apply_function_pullbacks=True,
                                      do_apply_integral_scaling=True,
                                      do_apply_geometry_lowering=True,
                                      preserve_geometry_types=(Jacobian,),
                                      do_apply_restrictions=True)
    elif r == "tsfc":
        try:
            # TSFC provides compute_form_data wrapper using correct
            # kwargs
            from tsfc.ufl_utils import compute_form_data as tsfc_compute_form_data
        except ImportError:
            error("Failed to import tsfc.ufl_utils.compute_form_data when asked "
                  "for tsfc representation.")
        form_data = tsfc_compute_form_data(form)
    elif r == "quadrature":
        # quadrature representation
        form_data = compute_form_data(form)
    else:
        error("Unexpected representation family '%s' for form preprocessing." % r)

    info("")
    info(str(form_data))

    # Attach integral meta data
    _attach_integral_metadata(form_data, r, parameters)
    _validate_representation_choice(form_data, r)

    return form_data
Ejemplo n.º 26
0
def _extract_common_quadrature_rule(integral_metadatas):
    # Check that quadrature rule is the same (To support mixed rules
    # would be some work since num_points is used to identify
    # quadrature rules in large parts of the pipeline)
    quadrature_rules = [md["quadrature_rule"] for md in integral_metadatas]
    if all_equal(quadrature_rules):
        qr = quadrature_rules[0]
    else:
        qr = "canonical"
        # FIXME: Shouldn't we raise here?
        info("Quadrature rule must be equal within each sub domain, using %s rule." % qr)
    return qr
Ejemplo n.º 27
0
def _validate_quadrature_schemes_of_elements(quad_schemes, elements):
    # Update scheme for QuadratureElements
    if quad_schemes and all_equal(quad_schemes):
        scheme = quad_schemes[0]
    else:
        scheme = "canonical"
        info("Quadrature rule must be equal within each sub domain, using %s rule." % scheme)
    for element in elements:
        if element.family() == "Quadrature":
            qs = element.quadrature_scheme()
            if qs != scheme:
                error("Quadrature element must have specified quadrature scheme (%s) equal to the integral (%s)." % (qs, scheme))
Ejemplo n.º 28
0
def _extract_common_quadrature_rule(integral_metadatas):
    # Check that quadrature rule is the same (To support mixed rules
    # would be some work since num_points is used to identify
    # quadrature rules in large parts of the pipeline)
    quadrature_rules = [md["quadrature_rule"] for md in integral_metadatas]
    if all_equal(quadrature_rules):
        qr = quadrature_rules[0]
    else:
        qr = "canonical"
        # FIXME: Shouldn't we raise here?
        info(
            "Quadrature rule must be equal within each sub domain, using %s rule."
            % qr)
    return qr
Ejemplo n.º 29
0
def compute_integral_ir(itg_data, form_data, form_id, element_numbers,
                        parameters):
    "Compute intermediate represention of integral."

    info("Computing uflacs representation")

    # Initialise representation
    ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id)

    # Sort integrals into a dict with quadrature degree and rule as key
    sorted_integrals = sort_integrals(itg_data.integrals,
                                      itg_data.metadata["quadrature_degree"],
                                      itg_data.metadata["quadrature_rule"])

    # TODO: Might want to create the uflacs ir first and then create the tables we need afterwards!
    # Tabulate quadrature points and basis function values in these points
    integrals_dict, psi_tables, quadrature_rules = \
        tabulate_basis(sorted_integrals, form_data, itg_data)

    # Store element numbers, needed for classnames
    ir["element_numbers"] = element_numbers

    # Delegate to flacs to build its intermediate representation and add to ir
    uflacs_ir = compute_uflacs_integral_ir(psi_tables, ir["entitytype"],
                                           integrals_dict, form_data,
                                           parameters)

    # Store uflacs generated part separately
    ir["uflacs"] = uflacs_ir

    # Create and save the optisation parameters # TODO: Define uflacs specific optimization parameters instead
    #ir["optimise_parameters"] = parse_optimise_parameters(parameters)

    # Save tables for quadrature weights and points
    ir["quadrature_rules"] = quadrature_rules

    # Create dimensions of primary indices, needed to reset the argument 'A'
    # given to tabulate_tensor() by the assembler.
    ir["prim_idims"] = [
        create_element(ufl_element).space_dimension()
        for ufl_element in form_data.argument_elements
    ]

    # Added for uflacs, not sure if this is the best way to get this:
    ir["coeff_idims"] = [
        create_element(ufl_element).space_dimension()
        for ufl_element in form_data.coefficient_elements
    ]

    return ir
Ejemplo n.º 30
0
def generate_code(ir, prefix, parameters):
    "Generate code from intermediate representation."

    begin("Compiler stage 4: Generating code")

    # FIXME: Document option -fconvert_exceptions_to_warnings
    # FIXME: Remove option epsilon and just rely on precision?

    # Set code generation parameters
#    set_float_formatting(int(parameters["precision"]))
    set_exception_handling(parameters["convert_exceptions_to_warnings"])

    # Extract representations
    ir_elements, ir_dofmaps, ir_integrals, ir_forms = ir

    # Generate code for elements
    info("Generating code for %d element(s)" % len(ir_elements))
    code_elements = [_generate_element_code(ir, prefix, parameters) for ir in ir_elements]

    # Generate code for dofmaps
    info("Generating code for %d dofmap(s)" % len(ir_dofmaps))
    code_dofmaps = [_generate_dofmap_code(ir, prefix, parameters) for ir in ir_dofmaps]

    # Generate code for integrals
    info("Generating code for integrals")
    code_integrals = [_generate_integral_code(ir, prefix, parameters) for ir in ir_integrals]

    # Generate code for forms
    info("Generating code for forms")
    code_forms = [_generate_form_code(ir, prefix, parameters) for ir in ir_forms]

    end()

    return code_elements, code_dofmaps, code_integrals, code_forms
Ejemplo n.º 31
0
def compute_ir(analysis, parameters):
    "Compute intermediate representation."

    begin("Compiler stage 2: Computing intermediate representation")

    # Set code generation parameters
    set_float_formatting(int(parameters["precision"]))

    # Extract data from analysis
    form_datas, elements, element_numbers = analysis

    # Compute representation of elements
    info("Computing representation of %d elements" % len(elements))
    ir_elements = [_compute_element_ir(e, i, element_numbers) \
                       for (i, e) in enumerate(elements)]

    # Compute representation of dofmaps
    info("Computing representation of %d dofmaps" % len(elements))
    ir_dofmaps = [_compute_dofmap_ir(e, i, element_numbers)
                      for (i, e) in enumerate(elements)]

    # Compute and flatten representation of integrals
    info("Computing representation of integrals")
    irs = [_compute_integral_ir(fd, i, parameters) \
               for (i, fd) in enumerate(form_datas)]
    ir_integrals = [ir for ir in chain(*irs) if not ir is None]

    # Compute representation of forms
    info("Computing representation of forms")
    ir_forms = [_compute_form_ir(fd, i, element_numbers) \
                    for (i, fd) in enumerate(form_datas)]

    end()

    return ir_elements, ir_dofmaps, ir_integrals, ir_forms
Ejemplo n.º 32
0
def _extract_common_quadrature_degree(integral_metadatas):
    # Check that quadrature degree is the same
    quadrature_degrees = [md["quadrature_degree"] for md in integral_metadatas]
    for d in quadrature_degrees:
        if not isinstance(d, int):
            error("Invalid non-integer quadrature degree %s" % (str(d),))
    qd = max(quadrature_degrees)
    if not all_equal(quadrature_degrees):
        # FIXME: Shouldn't we raise here?
        # TODO: This may be loosened up without too much effort,
        # if the form compiler handles mixed integration degree,
        # something that most of the pipeline seems to be ready for.
        info("Quadrature degree must be equal within each sub domain, using degree %d." % qd)
    return qd
def generate_integral_code(ir, prefix, parameters):
    "Generate code for integral from intermediate representation."

    info("Generating code from uflacs representation")

    # Generate generic ffc code snippets
    code = initialize_integral_code(ir, prefix, parameters)

    # Delegate to uflacs to generate tabulate_tensor body
    import uflacs.backends.ffc
    ucode = uflacs.backends.ffc.generate_tabulate_tensor_code(ir, parameters)
    code["tabulate_tensor"] = ucode["tabulate_tensor"]
    code["additional_includes_set"] = ir.get("additional_includes_set",set()) | set(ucode["additional_includes_set"])
    return code
Ejemplo n.º 34
0
def _transform_integrals_by_type(ir, transformer, integrals_dict,
                                 integral_type, cell):
    num_facets = cell.num_facets()
    num_vertices = cell.num_vertices()

    if integral_type == "cell":
        # Compute transformed integrals.
        info("Transforming cell integral")
        transformer.update_cell()
        terms = _transform_integrals(transformer, integrals_dict,
                                     integral_type)

    elif integral_type == "exterior_facet":
        # Compute transformed integrals.
        terms = [None] * num_facets
        for i in range(num_facets):
            info("Transforming exterior facet integral %d" % i)
            transformer.update_facets(i, None)
            terms[i] = _transform_integrals(transformer, integrals_dict,
                                            integral_type)

    elif integral_type == "interior_facet":
        # Compute transformed integrals.
        terms = [[None] * num_facets for i in range(num_facets)]
        for i in range(num_facets):
            for j in range(num_facets):
                info("Transforming interior facet integral (%d, %d)" % (i, j))
                transformer.update_facets(i, j)
                terms[i][j] = _transform_integrals(transformer, integrals_dict,
                                                   integral_type)

    elif integral_type == "point":
        # Compute transformed integrals.
        terms = [None] * num_vertices
        for i in range(num_vertices):
            info("Transforming point integral (%d)" % i)
            transformer.update_vertex(i)
            terms[i] = _transform_integrals(transformer, integrals_dict,
                                            integral_type)

    elif integral_type == "custom":
        # Compute transformed integrale: same as for cell integrals
        info("Transforming custom integral")
        transformer.update_cell()
        terms = _transform_integrals(transformer, integrals_dict,
                                     integral_type)

    else:
        error("Unhandled domain type: " + str(integral_type))
    return terms
Ejemplo n.º 35
0
def compute_ir(analysis, prefix, parameters, object_names=None):
    "Compute intermediate representation."

    begin("Compiler stage 2: Computing intermediate representation")

    # Set code generation parameters
    set_float_formatting(int(parameters["precision"]))

    # Extract data from analysis
    form_datas, elements, element_numbers, coordinate_elements = analysis

    # Compute representation of elements
    if not parameters["format"] == "pyop2":
        info("Computing representation of %d elements" % len(elements))
        ir_elements = [_compute_element_ir(e, prefix, element_numbers)
                       for e in elements]
    else:
        ir_elements = [None]

    # Compute representation of dofmaps
    if not parameters["format"] == "pyop2":
        info("Computing representation of %d dofmaps" % len(elements))
        ir_dofmaps = [_compute_dofmap_ir(e, prefix, element_numbers)
                      for e in elements]
        # Compute representation of coordinate mappings
        info("Computing representation of %d coordinate mappings" % len(coordinate_elements))
        ir_compute_coordinate_mappings = [_compute_coordinate_mapping_ir(e, prefix, element_numbers)
                                          for e in coordinate_elements]
    else:
        ir_dofmaps = [None]
        ir_compute_coordinate_mappings = [None]

    # Compute and flatten representation of integrals
    info("Computing representation of integrals")
    irs = [_compute_integral_ir(fd, i, prefix, element_numbers, parameters, object_names=object_names)
           for (i, fd) in enumerate(form_datas)]
    ir_integrals = [ir for ir in chain(*irs) if not ir is None]

    # Compute representation of forms
    if not parameters["format"] == "pyop2":
        info("Computing representation of forms")
        ir_forms = [_compute_form_ir(fd, i, prefix, element_numbers)
                    for (i, fd) in enumerate(form_datas)]
    else:
        ir_forms = [None]

    end()

    return ir_elements, ir_dofmaps, ir_compute_coordinate_mappings, ir_integrals, ir_forms
Ejemplo n.º 36
0
def compile_element(elements,
                    prefix="Element",
                    parameters=default_parameters()):
    """This function generates UFC code for a given UFL element or
    list of UFL elements."""

    info("Compiling element %s\n" % prefix)

    # Reset timing
    cpu_time_0 = time()

    # Check input arguments
    elements = _check_elements(elements)
    parameters = _check_parameters(parameters)
    if not elements: return

    # Stage 1: analysis
    cpu_time = time()
    analysis = analyze_elements(elements, parameters)
    _print_timing(1, time() - cpu_time)

    # Stage 2: intermediate representation
    cpu_time = time()
    ir = compute_ir(analysis, parameters)
    _print_timing(2, time() - cpu_time)

    # Stage 3: optimization
    cpu_time = time()
    oir = optimize_ir(ir, parameters)
    _print_timing(3, time() - cpu_time)

    # Stage 4: code generation
    cpu_time = time()
    code = generate_code(oir, prefix, parameters)
    _print_timing(4, time() - cpu_time)

    # Stage 4.1: generate wrappers
    cpu_time = time()
    object_names = {}
    wrapper_code = generate_wrapper_code(analysis, prefix, object_names,
                                         parameters)
    _print_timing(4.1, time() - cpu_time)

    # Stage 5: format code
    cpu_time = time()
    format_code(code, wrapper_code, prefix, parameters)
    _print_timing(5, time() - cpu_time)

    info_green("FFC finished in %g seconds.", time() - cpu_time_0)
Ejemplo n.º 37
0
def _transform_integrals_by_type(ir, transformer, integrals_dict,
                                 integral_type, cell):
    num_facets = cell.num_facets()
    num_vertices = cell.num_vertices()

    if integral_type == "cell":
        # Compute transformed integrals.
        info("Transforming cell integral")
        transformer.update_cell()
        terms = _transform_integrals(transformer, integrals_dict, integral_type)

    elif integral_type == "exterior_facet":
        # Compute transformed integrals.
        terms = [None]*num_facets
        for i in range(num_facets):
            info("Transforming exterior facet integral %d" % i)
            transformer.update_facets(i, None)
            terms[i] = _transform_integrals(transformer, integrals_dict,
                                            integral_type)

    elif integral_type == "interior_facet":
        # Compute transformed integrals.
        terms = [[None]*num_facets for i in range(num_facets)]
        for i in range(num_facets):
            for j in range(num_facets):
                info("Transforming interior facet integral (%d, %d)" % (i, j))
                transformer.update_facets(i, j)
                terms[i][j] = _transform_integrals(transformer, integrals_dict,
                                                   integral_type)

    elif integral_type == "vertex":
        # Compute transformed integrals.
        terms = [None]*num_vertices
        for i in range(num_vertices):
            info("Transforming vertex integral (%d)" % i)
            transformer.update_vertex(i)
            terms[i] = _transform_integrals(transformer, integrals_dict,
                                            integral_type)

    elif integral_type in custom_integral_types:

        # Compute transformed integrals: same as for cell integrals
        info("Transforming custom integral")
        transformer.update_cell()
        terms = _transform_integrals(transformer, integrals_dict, integral_type)

    else:
        error("Unhandled domain type: " + str(integral_type))
    return terms
Ejemplo n.º 38
0
def optimize_integral_ir(ir, parameters):
    "Compute optimized intermediate representation of integral."

    # FIXME: input argument "parameters" has been added to optimize_integral_ir
    # FIXME: which shadows a local parameter

    parameters = ir["optimise_parameters"]
    if parameters["optimisation"]:
        integrals = ir["trans_integrals"]
        domain_type = ir["domain_type"]
        num_facets = ir["num_facets"]
        num_vertices = ir["num_vertices"]
        geo_consts = ir["geo_consts"]
        psi_tables_map = ir["psi_tables_map"]
        if domain_type == "cell":
            info("Optimising expressions for cell integral")
            if parameters["optimisation"] in ("precompute_ip_const",
                                              "precompute_basis_const"):
                _precompute_expressions(integrals, geo_consts,
                                        parameters["optimisation"])
            else:
                _simplify_expression(integrals, geo_consts, psi_tables_map)
        elif domain_type == "exterior_facet":
            for i in range(num_facets):
                info("Optimising expressions for facet integral %d" % i)
                if parameters["optimisation"] in ("precompute_ip_const",
                                                  "precompute_basis_const"):
                    _precompute_expressions(integrals[i], geo_consts,
                                            parameters["optimisation"])
                else:
                    _simplify_expression(integrals[i], geo_consts,
                                         psi_tables_map)
        elif domain_type == "interior_facet":
            for i in range(num_facets):
                for j in range(num_facets):
                    info("Optimising expressions for facet integral (%d, %d)" %
                         (i, j))
                    if parameters["optimisation"] in (
                            "precompute_ip_const", "precompute_basis_const"):
                        _precompute_expressions(integrals[i][j], geo_consts,
                                                parameters["optimisation"])
                    else:
                        _simplify_expression(integrals[i][j], geo_consts,
                                             psi_tables_map)
        elif domain_type == "point":
            for i in range(num_vertices):
                info("Optimising expressions for poin integral %d" % i)
                if parameters["optimisation"] in ("precompute_ip_const",
                                                  "precompute_basis_const"):
                    _precompute_expressions(integrals[i], geo_consts,
                                            parameters["optimisation"])
                else:
                    _simplify_expression(integrals[i], geo_consts,
                                         psi_tables_map)
        else:
            error("Unhandled domain type: " + str(domain_type))

    return ir
Ejemplo n.º 39
0
def compute_integral_ir(integral_data, form_data, form_id, element_numbers,
                        classnames, parameters):
    "Compute intermediate represention of integral."

    info("Computing tsfc representation")

    # Initialise representation
    ir = initialize_integral_ir("tsfc", integral_data, form_data, form_id)

    # TSFC treats None and unset differently, so remove None values.
    parameters = {k: v for k, v in parameters.items() if v is not None}

    # Delay TSFC compilation
    ir["compile_integral"] = (integral_data, form_data, None, parameters)

    return ir
def generate_integral_code(ir, prefix, parameters):
    "Generate code for integral from intermediate representation."

    info("Generating code from uflacs representation")

    # Generate generic ffc code snippets
    code = initialize_integral_code(ir, prefix, parameters)

    # Delegate to uflacs to generate tabulate_tensor body
    import uflacs.backends.ffc
    ucode = uflacs.backends.ffc.generate_tabulate_tensor_code(ir, parameters)
    code["tabulate_tensor"] = ucode["tabulate_tensor"]
    code["additional_includes_set"] = ir.get(
        "additional_includes_set", set()) | set(
            ucode["additional_includes_set"])
    return code
Ejemplo n.º 41
0
def _generate_dolfin_wrapper(analysis, prefix, object_names, parameters):

    begin("Compiler stage 4.1: Generating additional wrapper code")

    # Encapsulate data
    (capsules, common_space) = _encapsulate(prefix, object_names, analysis, parameters)

    # Generate code
    info("Generating wrapper code for DOLFIN")
    code = generate_dolfin_code(prefix, "",
                                capsules, common_space,
                                error_control=parameters["error_control"])
    code += "\n\n"
    end()

    return code
Ejemplo n.º 42
0
def _extract_common_quadrature_degree(integral_metadatas):
    # Check that quadrature degree is the same
    quadrature_degrees = [md["quadrature_degree"] for md in integral_metadatas]
    for d in quadrature_degrees:
        if not isinstance(d, int):
            error("Invalid non-integer quadrature degree %s" % (str(d), ))
    qd = max(quadrature_degrees)
    if not all_equal(quadrature_degrees):
        # FIXME: Shouldn't we raise here?
        # TODO: This may be loosened up without too much effort,
        # if the form compiler handles mixed integration degree,
        # something that most of the pipeline seems to be ready for.
        info(
            "Quadrature degree must be equal within each sub domain, using degree %d."
            % qd)
    return qd
Ejemplo n.º 43
0
def _validate_quadrature_schemes_of_elements(quad_schemes, elements):
    # Update scheme for QuadratureElements
    if quad_schemes and all_equal(quad_schemes):
        scheme = quad_schemes[0]
    else:
        scheme = "canonical"
        info(
            "Quadrature rule must be equal within each sub domain, using %s rule."
            % scheme)
    for element in elements:
        if element.family() == "Quadrature":
            qs = element.quadrature_scheme()
            if qs != scheme:
                error(
                    "Quadrature element must have specified quadrature scheme (%s) equal to the integral (%s)."
                    % (qs, scheme))
Ejemplo n.º 44
0
def _generate_dolfin_wrapper(analysis, prefix, object_names, parameters):

    begin("Compiler stage 4.1: Generating additional wrapper code")

    # Encapsulate data
    (capsules, common_space) = _encapsulate(prefix, object_names, analysis, parameters)

    # Generate code
    info("Generating wrapper code for DOLFIN")
    code = generate_dolfin_code(prefix, "",
                                capsules, common_space,
                                error_control=parameters["error_control"])
    code += "\n\n"
    end()

    return code
Ejemplo n.º 45
0
def generate_code(ir, parameters):
    "Generate code from intermediate representation."

    begin("Compiler stage 4: Generating code")

    full_ir = ir

    # FIXME: This has global side effects
    # Set code generation parameters
    # set_float_formatting(parameters["precision"])
    # set_exception_handling(parameters["convert_exceptions_to_warnings"])

    # Extract representations
    ir_finite_elements, ir_dofmaps, ir_coordinate_mappings, ir_integrals, ir_forms = ir

    # Generate code for finite_elements
    info("Generating code for %d finite_element(s)" % len(ir_finite_elements))
    code_finite_elements = [_generate_finite_element_code(ir, parameters)
                            for ir in ir_finite_elements]

    # Generate code for dofmaps
    info("Generating code for %d dofmap(s)" % len(ir_dofmaps))
    code_dofmaps = [_generate_dofmap_code(ir, parameters)
                    for ir in ir_dofmaps]

    # Generate code for coordinate_mappings
    info("Generating code for %d coordinate_mapping(s)" % len(ir_coordinate_mappings))
    code_coordinate_mappings = [_generate_coordinate_mapping_code(ir, parameters)
                                for ir in ir_coordinate_mappings]

    # Generate code for integrals
    info("Generating code for integrals")
    code_integrals = [_generate_integral_code(ir, parameters)
                      for ir in ir_integrals]

    # Generate code for forms
    info("Generating code for forms")
    code_forms = [_generate_form_code(ir, parameters)
                  for ir in ir_forms]

    # Extract additional includes
    includes = _extract_includes(full_ir, code_integrals)

    end()

    return (code_finite_elements, code_dofmaps, code_coordinate_mappings,
            code_integrals, code_forms, includes)
Ejemplo n.º 46
0
def compute_integral_ir(itg_data,
                        form_data,
                        form_id,
                        element_numbers,
                        parameters):
    "Compute intermediate represention of integral."

    info("Computing uflacs representation")

    # Initialise representation
    ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id)

    # Sort integrals into a dict with quadrature degree and rule as key
    sorted_integrals = sort_integrals(itg_data.integrals,
                                      itg_data.metadata["quadrature_degree"],
                                      itg_data.metadata["quadrature_rule"])

    # TODO: Might want to create the uflacs ir first and then create the tables we need afterwards!
    # Tabulate quadrature points and basis function values in these points
    integrals_dict, psi_tables, quadrature_rules = \
        tabulate_basis(sorted_integrals, form_data, itg_data)

    # Store element numbers, needed for classnames
    ir["element_numbers"] = element_numbers

    # Delegate to flacs to build its intermediate representation and add to ir
    uflacs_ir = compute_uflacs_integral_ir(psi_tables, ir["entitytype"], integrals_dict, form_data, parameters)

    # Store uflacs generated part separately
    ir["uflacs"] = uflacs_ir

    # Create and save the optisation parameters # TODO: Define uflacs specific optimization parameters instead
    #ir["optimise_parameters"] = parse_optimise_parameters(parameters)

    # Save tables for quadrature weights and points
    ir["quadrature_rules"] = quadrature_rules

    # Create dimensions of primary indices, needed to reset the argument 'A'
    # given to tabulate_tensor() by the assembler.
    ir["prim_idims"] = [create_element(ufl_element).space_dimension()
                        for ufl_element in form_data.argument_elements]

    # Added for uflacs, not sure if this is the best way to get this:
    ir["coeff_idims"] = [create_element(ufl_element).space_dimension()
                         for ufl_element in form_data.coefficient_elements]

    return ir
Ejemplo n.º 47
0
def compile_form(forms, object_names={}, prefix="Form",\
                 parameters=default_parameters()):
    """This function generates UFC code for a given UFL form or list
    of UFL forms."""

    info("Compiling form %s\n" % prefix)

    # Reset timing
    cpu_time_0 = time()

    # Check input arguments
    forms = _check_forms(forms)
    parameters = _check_parameters(parameters)
    if not forms: return

    # Stage 1: analysis
    cpu_time = time()
    analysis = analyze_forms(forms, object_names, parameters)
    _print_timing(1, time() - cpu_time)

    # Stage 2: intermediate representation
    cpu_time = time()
    ir = compute_ir(analysis, parameters)
    _print_timing(2, time() - cpu_time)

    # Stage 3: optimization
    cpu_time = time()
    oir = optimize_ir(ir, parameters)
    _print_timing(3, time() - cpu_time)

    # Stage 4: code generation
    cpu_time = time()
    code = generate_code(oir, prefix, parameters)
    _print_timing(4, time() - cpu_time)

    # Stage 4.1: generate wrappers
    cpu_time = time()
    wrapper_code = generate_wrapper_code(analysis, prefix, parameters)
    _print_timing(4.1, time() - cpu_time)

    # Stage 5: format code
    cpu_time = time()
    format_code(code, wrapper_code, prefix, parameters)
    _print_timing(5, time() - cpu_time)

    info_green("FFC finished in %g seconds.", time() - cpu_time_0)
Ejemplo n.º 48
0
def _analyze_form(form, parameters):
    "Analyze form, returning form data."

    # Check that form is not empty
    ffc_assert(not form.empty(),
               "Form (%s) seems to be zero: cannot compile it." % str(form))

    # Compute form metadata
    form_data = compute_form_data(form)

    info("")
    info(str(form_data))

    # Attach integral meta data
    _attach_integral_metadata(form_data, parameters)

    return form_data
Ejemplo n.º 49
0
def compute_integral_ir(itg_data, form_data, form_id, parameters):
    "Compute intermediate represention of integral."

    info("Computing uflacs representation")

    # Initialise representation
    ir = initialize_integral_ir("uflacs", itg_data, form_data, form_id)

    # Sort integrals into a dict with number of integral points as key
    sorted_integrals = _sort_integrals(itg_data.integrals, itg_data.metadata,
                                       form_data)

    # Tabulate quadrature points and basis function values in these points
    integrals_dict, psi_tables, quad_weights = \
        _tabulate_basis(sorted_integrals, itg_data.domain_type, form_data)

    # Save tables for quadrature weights and points
    ir["quadrature_weights"] = quad_weights

    # Save tables for basis function values
    ir["psi_tables"] = psi_tables

    # Create dimensions of primary indices, needed to reset the argument 'A'
    # given to tabulate_tensor() by the assembler.
    ir["prim_idims"] = [
        create_element(ufl_element).space_dimension()
        for ufl_element in form_data.argument_elements
    ]

    # Added for uflacs, not sure if this is the best way to get this:
    ir["coeff_idims"] = [
        create_element(ufl_element).space_dimension()
        for ufl_element in form_data.coefficient_elements
    ]

    # Create and save the optisation parameters.
    ir["optimise_parameters"] = _parse_optimise_parameters(parameters)

    # Delegate to flacs to build its intermediate representation and add to ir
    import uflacs.backends.ffc
    uir = uflacs.backends.ffc.compute_tabulate_tensor_ir(
        ir, integrals_dict, form_data, parameters)
    ir.update(uir)

    return ir
Ejemplo n.º 50
0
def extract_monomial_form(integrands, function_replace_map):
    """
    Extract monomial representation of form (if possible). When
    successful, the form is represented as a sum of products of scalar
    components of basis functions or derivatives of basis functions.
    If unsuccessful, MonomialException is raised.
    """

    info("Extracting monomial form representation from UFL form")

    # Iterate over all integrals
    monomial_form = MonomialForm()
    for integrand in integrands:
        # Extract monomial representation if possible
        monomial_integrand = extract_monomial_integrand(integrand, function_replace_map)
        monomial_form.append(monomial_integrand)

    return monomial_form
def _optimize_tensor_contraction(A0, rank):
    "Compute optimized tensor contraction for given reference tensor."

    # Select FErari optimization algorithm
    if rank == 2:
        optimize = binary.optimize
    elif rank == 1:
        optimize = binary.optimize_action
    else:
        warning("Tensor optimization only available for rank 1 and 2 tensors, skipping optimizations")
        return None

    # Write a message
    info("Calling FErari to optimize tensor of size %s (%d entries)",
         " x ".join(str(d) for d in shape(A0)), product(shape(A0)))#

    # Compute optimized tensor contraction
    return optimize(A0)
Ejemplo n.º 52
0
def optimize_integral_ir(ir, parameters):
    "Compute optimized intermediate representation of integral."

    # FIXME: input argument "parameters" has been added to optimize_integral_ir
    # FIXME: which shadows a local parameter

    # Get integral type and optimization parameters
    integral_type = ir["integral_type"]
    parameters = ir["optimise_parameters"]

    # Check whether we should optimize
    if parameters["optimisation"]:

        # Get parameters
        integrals      = ir["trans_integrals"]
        integral_type  = ir["integral_type"]
        num_facets     = ir["num_facets"]
        num_vertices   = ir["num_vertices"]
        geo_consts     = ir["geo_consts"]
        psi_tables_map = ir["psi_tables_map"]

        # Optimize based on integral type
        if integral_type == "cell":
            info("Optimising expressions for cell integral")
            if parameters["optimisation"] in ("precompute_ip_const", "precompute_basis_const"):
                _precompute_expressions(integrals, geo_consts, parameters["optimisation"])
            else:
                _simplify_expression(integrals, geo_consts, psi_tables_map)
        elif integral_type == "exterior_facet":
            for i in range(num_facets):
                info("Optimising expressions for facet integral %d" % i)
                if parameters["optimisation"] in ("precompute_ip_const", "precompute_basis_const"):
                    _precompute_expressions(integrals[i], geo_consts, parameters["optimisation"])
                else:
                    _simplify_expression(integrals[i], geo_consts, psi_tables_map)
        elif integral_type == "interior_facet":
            for i in range(num_facets):
                for j in range(num_facets):
                    info("Optimising expressions for facet integral (%d, %d)" % (i, j))
                    if parameters["optimisation"] in ("precompute_ip_const", "precompute_basis_const"):
                        _precompute_expressions(integrals[i][j], geo_consts,parameters["optimisation"])
                    else:
                        _simplify_expression(integrals[i][j], geo_consts, psi_tables_map)
        elif integral_type == "vertex":
            for i in range(num_vertices):
                info("Optimising expressions for poin integral %d" % i)
                if parameters["optimisation"] in ("precompute_ip_const", "precompute_basis_const"):
                    _precompute_expressions(integrals[i], geo_consts, parameters["optimisation"])
                else:
                    _simplify_expression(integrals[i], geo_consts, psi_tables_map)
        else:
            error("Unhandled domain type: " + str(integral_type))

    return ir
Ejemplo n.º 53
0
Archivo: plot.py Proyecto: doru1004/FFC
def IntegralMoment(cellname, num_moments, x=None):
    "Return model for integral moment for given element."

    info("Plotting dof: integral moment")

    # Set position
    if x is None and cellname == "triangle":
        a = 1.0 / (2 + sqrt(2)) # this was a fun exercise
        x = (a, a, 0.0)
    elif x is None:
        a = 1.0 / (3 + sqrt(3)) # so was this
        x = (a, a, a)

    # Make sure point is 3D
    x = to3d(x)

    # Fancy scaling of radius and color
    r = 1.0 / (num_moments + 5)
    if num_moments % 2 == 0:
        c = 1.0
    else:
        c = 0.0

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Define material (color) for the sphere
    material = soya.Material()
    material.diffuse = (c, c, c, 0.7)

    # Create sphere
    sphere = Sphere(scene, material=material)

    # Scale and moveand move to coordinate
    sphere.scale(r, r, r)
    p = sphere.position()
    p.set_xyz(x[0], x[1], x[2])
    sphere.move(p)

    # Extract model
    model = scene.to_model()

    return model
Ejemplo n.º 54
0
def _analyze_form(form, object_names, parameters):
    "Analyze form, returning form data."

    # Check that form is not empty
    ffc_assert(len(form.integrals()),
               "Form (%s) seems to be zero: cannot compile it." % str(form))

    # Compute form metadata
    form_data = form.form_data()
    if form_data is None:
        form_data = form.compute_form_data(object_names=object_names)

    info("")
    info(str(form_data))

    # Attach integral meta data
    _attach_integral_metadata(form_data, parameters)

    return form_data
Ejemplo n.º 55
0
def IntegralMoment(cellname, num_moments, x=None):
    "Return model for integral moment for given element."

    info("Plotting dof: integral moment")

    # Set position
    if x is None and cellname == "triangle":
        a = 1.0 / (2 + sqrt(2)) # this was a fun exercise
        x = (a, a, 0.0)
    elif x is None:
        a = 1.0 / (3 + sqrt(3)) # so was this
        x = (a, a, a)

    # Make sure point is 3D
    x = to3d(x)

    # Fancy scaling of radius and color
    r = 1.0 / (num_moments + 5)
    if num_moments % 2 == 0:
        c = 1.0
    else:
        c = 0.0

    # Create separate scene (since we will extract a model, not render)
    scene = soya.World()

    # Define material (color) for the sphere
    material = soya.Material()
    material.diffuse = (c, c, c, 0.7)

    # Create sphere
    sphere = Sphere(scene, material=material)

    # Scale and moveand move to coordinate
    sphere.scale(r, r, r)
    p = sphere.position()
    p.set_xyz(x[0], x[1], x[2])
    sphere.move(p)

    # Extract model
    model = scene.to_model()

    return model
def integrate(monomial,
              domain_type,
              facet0, facet1,
              quadrature_degree,
              quadrature_rule,
              cellname,
              facet_cellname):
    """Compute the reference tensor for a given monomial term of a
    multilinear form"""

    info("Precomputing integrals on reference element")

    # Start timing
    tic = time.time()

    # Initialize quadrature points and weights
    (points, weights) = _init_quadrature(monomial.arguments,
                                         domain_type,
                                         quadrature_degree,
                                         quadrature_rule,
                                         cellname,
                                         facet_cellname)

    # Initialize quadrature table for basis functions
    table = _init_table(monomial.arguments,
                        domain_type,
                        points,
                        facet0, facet1)

    # Compute table Psi for each factor
    psis = [_compute_psi(v, table, len(points), domain_type) \
                for v in monomial.arguments]

    # Compute product of all Psis
    A0 = _compute_product(psis, monomial.float_value * weights)

    # Report elapsed time and number of entries
    toc = time.time() - tic
    num_entries = numpy.prod(numpy.shape(A0))
    debug("%d entries computed in %.3g seconds" % (num_entries, toc))
    debug("Shape of reference tensor: " + str(numpy.shape(A0)))

    return A0