Beispiel #1
0
def create_coordinate_map(o):
    """Return a compiled UFC coordinate_mapping object"""

    try:
        # Create a compiled coordinate map from an object with the
        # ufl_mesh attribute
        cmap_ptr = jit.ffc_jit(o.ufl_domain())
    except AttributeError:
        # FIXME: It would be good to avoid the type check, but ffc_jit
        # supports other objects so we could get, e.g., a compiled
        # finite element
        if isinstance(o, ufl.domain.Mesh):
            cmap_ptr = jit.ffc_jit(o)
        else:
            raise TypeError(
                "Cannot create coordinate map from an object of type: {}".
                format(type(o)))
    except Exception:
        print("Failed to create compiled coordinate map")
        raise

    # Wrap compiled coordinate map and return
    ffi = FFI()
    cmap = fem.dofmap.make_coordinate_mapping(ffi.cast("uintptr_t", cmap_ptr))
    return cmap
Beispiel #2
0
    def __init__(self,
                 mesh: cpp.mesh.Mesh,
                 element: typing.Union[ufl.FiniteElementBase, ElementMetaData],
                 cppV: typing.Optional[cpp.function.FunctionSpace] = None):
        """Create a finite element function space."""

        # Create function space from a UFL element and existing cpp
        # FunctionSpace
        if cppV is not None:
            assert mesh is None
            ufl_domain = cppV.mesh.ufl_domain()
            super().__init__(ufl_domain, element)
            self._cpp_object = cppV
            return

        # Initialise the ufl.FunctionSpace
        if isinstance(element, ufl.FiniteElementBase):
            super().__init__(mesh.ufl_domain(), element)
        else:
            e = ElementMetaData(*element)
            ufl_element = ufl.FiniteElement(e.family,
                                            mesh.ufl_cell(),
                                            e.degree,
                                            form_degree=e.form_degree)
            super().__init__(mesh.ufl_domain(), ufl_element)

        # Compile dofmap and element and create DOLFIN objects
        ufc_element, ufc_dofmap_ptr = jit.ffc_jit(
            self.ufl_element(),
            form_compiler_parameters=None,
            mpi_comm=mesh.mpi_comm())

        ffi = cffi.FFI()
        ufc_element = dofmap.make_ufc_finite_element(
            ffi.cast("uintptr_t", ufc_element))
        cpp_element = cpp.fem.FiniteElement(ufc_element)

        ufc_dofmap = dofmap.make_ufc_dofmap(
            ffi.cast("uintptr_t", ufc_dofmap_ptr))
        cpp_dofmap = cpp.fem.create_dofmap(ufc_dofmap, mesh)

        # Initialize the cpp.FunctionSpace
        self._cpp_object = cpp.function.FunctionSpace(mesh, cpp_element,
                                                      cpp_dofmap)
Beispiel #3
0
    def __init__(self, form: ufl.Form, form_compiler_parameters: dict = None):
        """Create dolfin Form

        Parameters
        ----------
        form
            Pure UFL form
        form_compiler_parameters
            Parameters used in JIT FFC compilation of this form

        Note
        ----
        This wrapper for UFL form is responsible for the actual FFC compilation
        and attaching coefficients and domains specific data to the underlying
        C++ Form.
        """
        self.form_compiler_parameters = form_compiler_parameters

        # Extract subdomain data from UFL form
        sd = form.subdomain_data()
        self._subdomains, = list(sd.values())  # Assuming single domain
        domain, = list(sd.keys())  # Assuming single domain
        mesh = domain.ufl_cargo()

        # Compile UFL form with JIT
        ufc_form = jit.ffc_jit(
            form,
            form_compiler_parameters=self.form_compiler_parameters,
            mpi_comm=mesh.mpi_comm())

        # Cast compiled library to pointer to ufc_form
        ffi = cffi.FFI()
        ufc_form = fem.dofmap.make_ufc_form(ffi.cast("uintptr_t", ufc_form))

        # For every argument in form extract its function space
        function_spaces = [
            func.function_space()._cpp_object for func in form.arguments()
        ]

        # Prepare dolfin.Form and hold it as a member
        self._cpp_object = cpp.fem.create_form(ufc_form, function_spaces)

        # Need to fill the form with coefficients data
        # For every coefficient in form take its CPP object
        original_coefficients = form.coefficients()
        for i in range(self._cpp_object.num_coefficients()):
            j = self._cpp_object.original_coefficient_position(i)
            self._cpp_object.set_coefficient(
                i, original_coefficients[j]._cpp_object)

        if mesh is None:
            raise RuntimeError("Expecting to find a Mesh in the form.")

        # Attach mesh (because function spaces and coefficients may be
        # empty lists)
        if not function_spaces:
            self._cpp_object.set_mesh(mesh)

        # Attach subdomains to C++ Form if we have them
        subdomains = self._subdomains.get("cell")
        if subdomains:
            self._cpp_object.set_cell_domains(subdomains)

        subdomains = self._subdomains.get("exterior_facet")
        if subdomains:
            self._cpp_object.set_exterior_facet_domains(subdomains)

        subdomains = self._subdomains.get("interior_facet")
        if subdomains:
            self._cpp_object.set_interior_facet_domains(subdomains)

        subdomains = self._subdomains.get("vertex")
        if subdomains:
            self._cpp_object.set_vertex_domains(subdomains)
Beispiel #4
0
    def __init__(self, form: ufl.Form, form_compiler_parameters: dict = None):
        """Create dolfin Form

        Parameters
        ----------
        form
            Pure UFL form
        form_compiler_parameters
            Parameters used in JIT FFC compilation of this form

        Note
        ----
        This wrapper for UFL form is responsible for the actual FFC compilation
        and attaching coefficients and domains specific data to the underlying
        C++ Form.
        """
        self.form_compiler_parameters = form_compiler_parameters

        # Add DOLFIN include paths (just the Boost path for special
        # math functions is really required)
        # FIXME: move getting include paths to elsewhere
        if self.form_compiler_parameters is None:
            self.form_compiler_parameters = {
                "external_include_dirs": jit.dolfin_pc["include_dirs"]
            }
        else:
            # FIXME: add paths if dict entry already exists
            self.form_compiler_parameters[
                "external_include_dirs"] = jit.dolfin_pc["include_dirs"]

        # Extract subdomain data from UFL form
        sd = form.subdomain_data()
        self._subdomains, = list(sd.values())  # Assuming single domain
        domain, = list(sd.keys())  # Assuming single domain
        mesh = domain.ufl_cargo()

        # Compile UFL form with JIT
        ufc_form = jit.ffc_jit(
            form,
            form_compiler_parameters=self.form_compiler_parameters,
            mpi_comm=mesh.mpi_comm())
        # Cast compiled library to pointer to ufc_form
        ufc_form = fem.dofmap.make_ufc_form(ufc_form[0])

        # For every argument in form extract its function space
        function_spaces = [
            func.function_space()._cpp_object for func in form.arguments()
        ]

        # Prepare dolfin.Form and hold it as a member
        self._cpp_object = cpp.fem.Form(ufc_form, function_spaces)

        # Need to fill the form with coefficients data
        # For every coefficient in form take its CPP object
        original_coefficients = form.coefficients()
        for i in range(self._cpp_object.num_coefficients()):
            j = self._cpp_object.original_coefficient_position(i)
            self._cpp_object.set_coefficient(
                j, original_coefficients[i]._cpp_object)

        if mesh is None:
            raise RuntimeError("Expecting to find a Mesh in the form.")

        # Attach mesh (because function spaces and coefficients may be
        # empty lists)
        if not function_spaces:
            self._cpp_object.set_mesh(mesh)

        # Attach subdomains to C++ Form if we have them
        subdomains = self._subdomains.get("cell")
        self._cpp_object.set_cell_domains(subdomains)

        subdomains = self._subdomains.get("exterior_facet")
        self._cpp_object.set_exterior_facet_domains(subdomains)

        subdomains = self._subdomains.get("interior_facet")
        self._cpp_object.set_interior_facet_domains(subdomains)

        subdomains = self._subdomains.get("vertex")
        self._cpp_object.set_vertex_domains(subdomains)