Beispiel #1
0
def test_compile_extension_module():
    # This test should do basically the same as the docstring of the
    # compile_extension_module function in compilemodule.py.  Remember
    # to update the docstring if the test is modified!

    code = """
      #include <pybind11/pybind11.h>
      #include <petscvec.h>
      #include <dolfin/la/PETScVector.h>

      void PETSc_exp(Vec x)
      {
        assert(x);
        VecExp(x);
      }

    PYBIND11_MODULE(SIGNATURE, m)
    {
      m.def("PETSc_exp", &PETSc_exp);
    }
    """

    ext_module = compile_cpp_code(code)
    local_range = MPI.local_range(MPI.comm_world, 10)
    x = cpp.la.create_vector(MPI.comm_world, local_range, [], 1)
    x_np = np.arange(float(local_range[1] - local_range[0]))
    with x.localForm() as lf:
        lf[:] = x_np

    ext_module.PETSc_exp(x)
    x_np = np.exp(x_np)

    x = x.getArray()
    assert (x == x_np).all()
Beispiel #2
0
def test_mpi_pybind11():
    """
    Test MPICommWrapper <-> mpi4py.MPI.Comm conversion for JIT-ed code
    """
    cpp_code = """
    #include <pybind11/pybind11.h>
    #include <dolfin_wrappers/MPICommWrapper.h>
    namespace dolfin
    {
      dolfin_wrappers::MPICommWrapper
      test_comm_passing(const dolfin_wrappers::MPICommWrapper comm)
      {
        MPI_Comm c = comm.get();
        return dolfin_wrappers::MPICommWrapper(c);
      }
    }
    PYBIND11_MODULE(SIGNATURE, m)
    {
        m.def("test_comm_passing", &dolfin::test_comm_passing);
    }
    """

    # Import MPI_COMM_WORLD
    from mpi4py import MPI
    w1 = MPI.COMM_WORLD

    # Compile the JIT module
    return pytest.xfail('Include path for dolfin_wrappers/* not set up to '
                        'work in the JIT at the moment')
    mod = dolfin.compile_cpp_code(cpp_code)

    # Pass a comm into C++ and get a new wrapper of the same comm back
    w2 = mod.test_comm_passing(w1)

    assert isinstance(w2, MPI.Comm)
Beispiel #3
0
def _get_cpp_module(cpp_files, force_recompile=False):
    """
    Use the dolfin machinery to compile, wrap with swig and load a c++ module
    """
    cpp_dir = os.path.dirname(os.path.abspath(__file__))

    cpp_sources = []
    for cpp_filename in cpp_files:
        lines = []
        for line in open(os.path.join(cpp_dir, cpp_filename), 'rt'):
            if line.startswith('#include') and 'remove_in_jit' in line:
                pass
            else:
                lines.append(line)
        cpp_sources.append(''.join(lines))

    # Force recompilation
    if force_recompile:
        cpp_sources.append('// Force recompile, time is %s \n' % time.time())

    sep = '\n\n// ' + '$' * 77 + '\n\n'
    cpp_code = sep.join(cpp_sources)

    module = compile_cpp_code(cpp_code)
    assert module is not None

    return module
Beispiel #4
0
    def get_eigenvector(self, i):
        assert i < self.eigen_solver.get_number_converged()

        # Initialize eigenvectors
        real_vector = PETScVector()
        imag_vector = PETScVector()
        self.A.init_vector(real_vector, 0)
        self.A.init_vector(imag_vector, 0)

        # Condense input vectors
        if hasattr(self, "_is"):  # there were Dirichlet BCs
            condensed_real_vector = PETScVector(real_vector.vec().getSubVector(
                self._is))
            condensed_imag_vector = PETScVector(imag_vector.vec().getSubVector(
                self._is))
        else:
            condensed_real_vector = real_vector
            condensed_imag_vector = imag_vector

        # Get eigenpairs
        if dolfin_version.startswith(
                "2018.1"):  # TODO remove when 2018.2.0 is released
            # Helper functions
            cpp_code = """
                #include <pybind11/pybind11.h>
                #include <dolfin/la/PETScVector.h>
                #include <dolfin/la/SLEPcEigenSolver.h>
                
                void get_eigen_pair(std::shared_ptr<dolfin::SLEPcEigenSolver> eigen_solver, std::shared_ptr<dolfin::PETScVector> condensed_real_vector, std::shared_ptr<dolfin::PETScVector> condensed_imag_vector, std::size_t i)
                {
                    const PetscInt ii = static_cast<PetscInt>(i);
                    double real_value;
                    double imag_value;
                    EPSGetEigenpair(eigen_solver->eps(), ii, &real_value, &imag_value, condensed_real_vector->vec(), condensed_imag_vector->vec());
                }
                
                PYBIND11_MODULE(SIGNATURE, m)
                {
                    m.def("get_eigen_pair", &get_eigen_pair);
                }
            """

            get_eigen_pair = compile_cpp_code(cpp_code).get_eigen_pair
            get_eigen_pair(self.eigen_solver, condensed_real_vector,
                           condensed_imag_vector, i)
        else:
            self.eigen_solver.get_eigenpair(condensed_real_vector,
                                            condensed_imag_vector, i)

        # Restore input vectors
        if hasattr(self, "_is"):  # there were Dirichlet BCs
            real_vector.vec().restoreSubVector(self._is,
                                               condensed_real_vector.vec())
            imag_vector.vec().restoreSubVector(self._is,
                                               condensed_imag_vector.vec())

        # Return as Function
        return (Function(self.V, real_vector), Function(self.V, imag_vector))
Beispiel #5
0
    def set_parameters(self, parameters):
        # Helper functions
        cpp_code = """
            #include <pybind11/pybind11.h>
            #include <dolfin/la/PETScLUSolver.h> // defines PCFactorSetMatSolverType macro for PETSc <= 3.8
            #include <dolfin/la/SLEPcEigenSolver.h>

            void throw_error(PetscErrorCode ierr, std::string reason);

            void set_linear_solver(std::shared_ptr<dolfin::SLEPcEigenSolver> eigen_solver, std::string lu_method)
            {
                ST st;
                KSP ksp;
                PC pc;
                PetscErrorCode ierr;

                ierr = EPSGetST(eigen_solver->eps(), &st);
                if (ierr != 0) throw_error(ierr, "EPSGetST");
                ierr = STGetKSP(st, &ksp);
                if (ierr != 0) throw_error(ierr, "STGetKSP");
                ierr = KSPGetPC(ksp, &pc);
                if (ierr != 0) throw_error(ierr, "KSPGetPC");

                ierr = STSetType(st, STSINVERT);
                if (ierr != 0) throw_error(ierr, "STSetType");
                ierr = KSPSetType(ksp, KSPPREONLY);
                if (ierr != 0) throw_error(ierr, "KSPSetType");
                ierr = PCSetType(pc, PCLU);
                if (ierr != 0) throw_error(ierr, "PCSetType");

                ierr = PCFactorSetMatSolverType(pc, lu_method.c_str());
                if (ierr != 0) throw_error(ierr, "PCFactorSetMatSolverType");
            }

            void throw_error(PetscErrorCode ierr, std::string reason)
            {
                throw std::runtime_error("Error in set_linear_solver: reason " + reason
                                         + ",error code " + std::to_string(ierr));
            }

            PYBIND11_MODULE(SIGNATURE, m)
            {
                m.def("set_linear_solver", &set_linear_solver);
            }
        """

        cpp_module = compile_cpp_code(cpp_code)
        set_linear_solver = cpp_module.set_linear_solver

        if "spectral_transform" in parameters and parameters[
                "spectral_transform"] == "shift-and-invert":
            parameters["spectrum"] = "target real"
            if "linear_solver" in parameters:
                set_linear_solver(self.eigen_solver,
                                  parameters["linear_solver"])
                parameters.pop("linear_solver")
        self.eigen_solver.parameters.update(parameters)
def _get_local_dof_to_component_map(V,
                                    component=None,
                                    dof_component_map=None,
                                    recursive=False):
    if component is None:
        component = [-1]
    if dof_component_map is None:
        dof_component_map = dict()

    # From dolfin/function/LagrangeInterpolator.cpp,
    # method LagrangeInterpolator::extract_dof_component_map
    # Copyright (C) 2014 Mikael Mortensen
    if V.num_sub_spaces() == 0:
        # Extract sub dofmaps recursively and store dof to component map
        if has_pybind11():
            cpp_code = """
                #include <pybind11/pybind11.h>
                #include <pybind11/stl.h>
                #include <dolfin/fem/DofMap.h>
                #include <dolfin/mesh/Mesh.h>
                
                std::vector<std::size_t> collapse_dofmap(std::shared_ptr<dolfin::DofMap> dofmap, std::shared_ptr<dolfin::Mesh> mesh)
                {
                    std::unordered_map<std::size_t, std::size_t> collapsed_map;
                    dofmap->collapse(collapsed_map, *mesh);
                    std::vector<std::size_t> collapsed_dofs;
                    collapsed_dofs.reserve(collapsed_map.size());
                    for (auto const& collapsed_map_item: collapsed_map)
                        collapsed_dofs.push_back(collapsed_map_item.second);
                    return collapsed_dofs;
                }
                
                PYBIND11_MODULE(SIGNATURE, m)
                {
                    m.def("collapse_dofmap", &collapse_dofmap);
                }
            """
            collapse_dofmap = compile_cpp_code(cpp_code).collapse_dofmap
            collapsed_dofs = collapse_dofmap(V.dofmap(), V.mesh())
        else:
            collapsed_dofs = V.dofmap().collapse(V.mesh())[1].values()
        component[0] += 1
        for collapsed_dof in collapsed_dofs:
            if not recursive:  # space with only one component, do not print it
                dof_component_map[collapsed_dof] = -1
            else:
                dof_component_map[collapsed_dof] = component[0]
    else:
        for i in range(V.num_sub_spaces()):
            Vs = V.sub(i)
            _get_local_dof_to_component_map(Vs, component, dof_component_map,
                                            True)

    if not recursive:
        return dof_component_map
    else:
        return None
Beispiel #7
0
    def __init__(self,
                 V,
                 bnd,
                 objects,
                 vsources=None,
                 isources=None,
                 dt=None,
                 int_bnd_ids=None,
                 eps0=1):

        num_objects = len(objects)

        if int_bnd_ids == None:
            int_bnd_ids = [
                objects[i].domain_args[1] for i in range(num_objects)
            ]

        if vsources == None:
            vsources = []

        if isources == None:
            isources = []
            self.dt = 1
        else:
            assert dt != None
            self.dt = dt

        self.int_bnd_ids = int_bnd_ids
        self.vsources = vsources
        self.isources = isources
        self.objects = objects
        self.eps0 = eps0

        self.groups = get_charge_sharing_sets(vsources, num_objects)

        self.V = V
        mesh = V.mesh()
        R = df.FunctionSpace(mesh, "Real", 0)
        self.mu = df.TestFunction(R)
        self.phi = df.TrialFunction(V)
        self.dss = df.Measure("ds", domain=mesh, subdomain_data=bnd)
        self.n = df.FacetNormal(mesh)

        thisdir = os.path.dirname(__file__)
        path = os.path.join(thisdir, 'addrow.cpp')
        code = open(path, 'r').read()
        self.compiled = df.compile_cpp_code(code)

        # Rows in which to store charge and potential constraints
        rows_charge = [g[0] for g in self.groups]
        rows_potential = list(set(range(num_objects)) - set(rows_charge))
        self.rows_charge = [objects[i].get_free_row() for i in rows_charge]
        self.rows_potential = [
            objects[i].get_free_row() for i in rows_potential
        ]
Beispiel #8
0
def compile_extension_module(cpp_code, **kwargs):
    if DOLFIN_VERSION_MAJOR >= 2018:
        headers = kwargs.get('additional_system_headers', [])
        headers = ["#include <Eigen/Core>",
                   '#include <pybind11/pybind11.h>',
                   # "using Array = Eigen::Ref<const Eigen::ArrayXi>;;"] +\
                   "using Array = Eigen::ArrayXi;"] +\
            ['#include <' + h + '>' for h in headers if h != '']
        cpp_code = '\n'.join(headers) + cpp_code
        return dolfin.compile_cpp_code(cpp_code)
    else:
        return dolfin.compile_extension_module(cpp_code, **kwargs)
Beispiel #9
0
def test_slepc():
    create_eps_code = r'''
    #include <pybind11/pybind11.h>
    #include <dolfin.h>
    #include <slepc.h>
    namespace dolfin
    {
        std::shared_ptr<EPS> create_matrix(MPI_Comm comm) {
            EPS eps;
            EPSCreate(comm, &eps);
            std::shared_ptr<EPS> ptr = std::make_shared<EPS>(eps);
            return ptr;
        }
    }

    PYBIND11_MODULE(SIGNATURE, m)
    {
      m.def("create_matrix", &dolfin::create_matrix);
    }

    '''
    compile_cpp_code(create_eps_code)
Beispiel #10
0
def compile_extension_module(cpp_code, **kwargs):
    if DOLFIN_VERSION_MAJOR >= 2018:
        headers = kwargs.get("additional_system_headers", [])
        headers = [
            "#include <Eigen/Core>",
            "#include <pybind11/pybind11.h>",
            # "using Array = Eigen::Ref<const Eigen::ArrayXi>;;"] +\
            "using Array = Eigen::ArrayXi;",
        ] + ["#include <" + h + ">" for h in headers if h != ""]
        cpp_code = "\n".join(headers) + cpp_code
        return dolfin.compile_cpp_code(cpp_code)
    else:
        return dolfin.compile_extension_module(cpp_code, **kwargs)
Beispiel #11
0
def CellCircumcenter(mesh, codes=codes):
    '''Circumcenter of cells in mesh'''
    assert mesh.ufl_cell().cellname() in ('interval', 'triangle',
                                          'tetrahedron')

    gdim = mesh.geometry().dim()
    tdim = mesh.topology().dim()

    f = CompiledExpression(getattr(compile_cpp_code(codes[(tdim, gdim)]),
                                   f'Circumcenter_{tdim}_{gdim}')(),
                           degree=0,
                           mesh=mesh)

    V = df.VectorFunctionSpace(mesh, 'DG', 0)
    return df.interpolate(f, V)
Beispiel #12
0
    def __init__(self, *args, **kwargs):

        # Adds the missing argument (the value on the boundary) before calling
        # the parent constructor. The value must be zero to set the
        # corresponding elements in the load vector to zero.

        args = list(args)
        args.insert(1, df.Constant(0.0))
        self.monitor = False
        self.compiled_apply = kwargs.pop('compiled_apply', True)
        if self.compiled_apply:
            thisdir = os.path.dirname(__file__)
            path = os.path.join(thisdir, 'apply.cpp')
            code = open(path, 'r').read()
            self.compiled_apply = df.compile_cpp_code(code)

        df.DirichletBC.__init__(self, *args, **kwargs)
Beispiel #13
0
def build_distributed_mesh(mesh):
    """
    Work around some missing dolfin pybind11 wrapped methods
    Performs the same actions as what happens when reading
    a mesh from an XML file, except for the very first step
    (constructing the whole global mesh on the root process)
    which is assumed to have happened allready
    """
    if build_distributed_mesh.func is None:
        cpp_code = """
        #include <pybind11/pybind11.h>
        #include <dolfin/common/MPI.h>
        #include <dolfin/mesh/MeshPartitioning.h>
        #include <dolfin/mesh/LocalMeshData.h>
        #include <dolfin/mesh/Mesh.h>
        #include <dolfin/parameter/GlobalParameters.h>

        /**
            Code taken from XMLFile::read(Mesh& input_mesh)
            in dolfin/io/XMLFile.cpp on 2018-03-21
        */
        void distribute_mesh(dolfin::Mesh &mesh)
        {
            // Distribute local data
            mesh.domains().clear();
            dolfin::LocalMeshData local_mesh_data(mesh);

            // Mesh domain data not present
            if (dolfin::MPI::rank(mesh.mpi_comm()) == 0)
                local_mesh_data.domain_data.clear();

            // Partition and build mesh
            const std::string ghost_mode = dolfin::parameters["ghost_mode"];
            dolfin::MeshPartitioning::build_distributed_mesh(mesh, local_mesh_data, ghost_mode);
        }

        namespace py = pybind11;

        PYBIND11_MODULE(SIGNATURE, m) {
           m.def("distribute_mesh", &distribute_mesh, py::arg("mesh"));
        }
        """
        build_distributed_mesh.func = dolfin.compile_cpp_code(
            cpp_code).distribute_mesh
    return build_distributed_mesh.func(mesh)
Beispiel #14
0
def _is_zero(form_or_block_form):
    assert (
        isinstance(form_or_block_form, (array, cpp_Form, Form, list))
            or
        (isinstance(form_or_block_form, (float, int)) and form_or_block_form in zeros)
    )
    if isinstance(form_or_block_form, Form):
        return form_or_block_form.empty()
    elif isinstance(form_or_block_form, cpp_Form):
        _is_zero_form_cpp_code = """
            #include <dolfin/fem/Form.h>
            #include <pybind11/pybind11.h>
            
            bool is_zero_form(std::shared_ptr<dolfin::Form> form)
            {
              return !form->ufc_form();
            }
            
            PYBIND11_MODULE(SIGNATURE, m)
            {
                m.def("is_zero_form", &is_zero_form);
            }
            """
        is_zero_form = compile_cpp_code(_is_zero_form_cpp_code).is_zero_form
        return is_zero_form(form_or_block_form)
    elif isinstance(form_or_block_form, (array, list)):
        block_form_rank = _get_block_form_rank(form_or_block_form)
        assert block_form_rank in (None, 1, 2)
        if block_form_rank == 2:
            for block_form_I in form_or_block_form:
                for block_form_IJ in block_form_I:
                    if not _is_zero(block_form_IJ):
                        return False
            return True
        elif block_form_rank == 1:
            for block_form_I in form_or_block_form:
                if not _is_zero(block_form_I):
                    return False
            return True
        elif block_form_rank is None:
            return True
    elif isinstance(form_or_block_form, (float, int)) and form_or_block_form in zeros:
        return True
    else:
        raise AssertionError("Invalid case in _is_zero")
Beispiel #15
0
def test_pass_array_int():
    code = """
    #include <Eigen/Core>
    #include <pybind11/pybind11.h>
    #include <pybind11/eigen.h>
    using IntVecIn = Eigen::Ref<const Eigen::VectorXi>;
    int test_int_array(const IntVecIn arr)
    {
    return arr.sum();
    }
    PYBIND11_MODULE(SIGNATURE, m)
    {
    m.def("test_int_array", &test_int_array);
    }
    """
    module = compile_cpp_code(code)
    arr = np.array([1, 2, 4, 8], dtype=np.intc)
    ans = module.test_int_array(arr)
    assert ans == arr.sum() == 15
Beispiel #16
0
def test_mpi_pybind11():
    """
    Test MPICommWrapper <-> mpi4py.MPI.Comm conversion for JIT-ed code
    """
    cpp_code = """
    #include <pybind11/pybind11.h>
    #include <dolfin_wrappers/MPICommWrapper.h>
    namespace dolfin
    {
      dolfin_wrappers::MPICommWrapper
      test_comm_passing(const dolfin_wrappers::MPICommWrapper comm)
      {
        MPI_Comm c = comm.get();
        return dolfin_wrappers::MPICommWrapper(c);
      }
    }
    PYBIND11_MODULE(SIGNATURE, m)
    {
        m.def("test_comm_passing", &dolfin::test_comm_passing);
    }
    """

    # Import MPI_COMM_WORLD
    if dolfin.has_mpi4py():
        from mpi4py import MPI
        w1 = MPI.COMM_WORLD
    else:
        w1 = dolfin.MPI.comm_world

    # Compile the JIT module
    return pytest.xfail('Include path for dolfin_wrappers/* not set up to '
                        'work in the JIT at the moment')
    mod = dolfin.compile_cpp_code(cpp_code)

    # Pass a comm into C++ and get a new wrapper of the same comm back
    w2 = mod.test_comm_passing(w1)

    if dolfin.has_mpi4py():
        assert isinstance(w2, MPI.Comm)
    else:
        assert isinstance(w2, dolfin.cpp.MPICommWrapper)
        assert w1.underlying_comm() == w2.underlying_comm()
Beispiel #17
0
def test_pass_array_double():
    code = """
    #include <Eigen/Core>
    #include <pybind11/pybind11.h>
    #include <pybind11/eigen.h>
    using DoubleVecIn = Eigen::Ref<const Eigen::VectorXd>;
    int test_double_array(const DoubleVecIn arr)
    {
    return arr.sum();
    }
    PYBIND11_MODULE(SIGNATURE, m)
    {
    m.def("test_double_array", &test_double_array);
    }
    """
    module = compile_cpp_code(code)
    arr = np.array([1, 2, 4, 8], dtype=float)
    ans = module.test_double_array(arr)
    assert abs(arr.sum() - 15) < 1e-15
    assert abs(ans - 15) < 1e-15
Beispiel #18
0
def test_petsc():
    create_matrix_code = r'''
    #include <pybind11/pybind11.h>
    #include <dolfin.h>
    namespace dolfin
    {
        std::shared_ptr<la::PETScMatrix> create_matrix(void) {
            Mat I;
            std::shared_ptr<la::PETScMatrix> ptr = std::make_shared<la::PETScMatrix>(I);
            return ptr;
        }
    }

    PYBIND11_MODULE(SIGNATURE, m)
    {
      m.def("create_matrix", &dolfin::create_matrix);
    }
    '''
    module = compile_cpp_code(create_matrix_code)
    assert (module)
Beispiel #19
0
def test_petsc():
    create_matrix_code = r'''
    #include <pybind11/pybind11.h>
    #include <dolfin.h>
    namespace dolfin
    {
        la::PETScMatrix create_matrix(void)
        {
            Mat I;
            la::PETScMatrix A = la::PETScMatrix(I);
            return A;
        }
    }

    PYBIND11_MODULE(SIGNATURE, m)
    {
      m.def("create_matrix", &dolfin::create_matrix);
    }
    '''
    module = compile_cpp_code(create_matrix_code)
    assert (module)
Beispiel #20
0
def cpp_module(
        header_names: Sequence[str],
        include_dir: str = "include",
        verbose: bool = False
) -> "class <'module'>":
    include_path = Path(__file__).parent.resolve() / include_dir

    header_list = []
    for header in header_names:
        with open(include_path / header, "r") as header_handle:
            header_list.append(header_handle.read())

    separator = "\n"*4
    cpp_code = separator.join(header_list)
    if verbose:
        print(cpp_code)

    module = compile_cpp_code(
        cpp_code,
        include_dirs=[]
    )
    assert module is not None
    return module
Beispiel #21
0
def test_compile_extension_module():

    # This test should do basically the same as the docstring of the
    # compile_extension_module function in compilemodule.py.  Remember
    # to update the docstring if the test is modified!

    from numpy import arange, exp
    code = """
      #include <pybind11/pybind11.h>

      #include <petscvec.h>
      #include <dolfin/la/PETScVector.h>

      void PETSc_exp(std::shared_ptr<dolfin::la::PETScVector> vec)
      {
        Vec x = vec->vec();
        assert(x);
        VecExp(x);
      }

    PYBIND11_MODULE(SIGNATURE, m)
    {
      m.def("PETSc_exp", &PETSc_exp);
    }
    """

    ext_module = compile_cpp_code(code)

    local_range = MPI.local_range(MPI.comm_world, 10)
    vec = PETScVector(MPI.comm_world, local_range, [], 1)
    np_vec = vec.get_local()
    np_vec[:] = arange(len(np_vec))
    vec[:] = np_vec
    ext_module.PETSc_exp(vec)
    np_vec[:] = exp(np_vec)
    assert (np_vec == vec.get_local()).all()
Beispiel #22
0
    def __init__(self):
        cpp_link_code = """
        #include <hdf5.h>

        // dolfin headers
        #include <dolfin/io/HDF5Interface.h>
        #include <dolfin/common/MPI.h>

        // pybind headers
        #include <pybind11/pybind11.h>

        namespace py = pybind11;

        namespace dolfin
        {
        void link_dataset(const MPI_Comm comm,
                          const std::string hdf5_filename,
                          const std::string link_from,
                          const std::string link_to, bool use_mpiio)
        {
            hid_t hdf5_file_id = HDF5Interface::open_file(comm, hdf5_filename, "a", use_mpiio);
            herr_t status = H5Lcreate_hard(hdf5_file_id, link_from.c_str(), H5L_SAME_LOC,
                                link_to.c_str(), H5P_DEFAULT, H5P_DEFAULT);
            dolfin_assert(status != HDF5_FAIL);

            HDF5Interface::close_file(hdf5_file_id);
        }

        PYBIND11_MODULE(SIGNATURE, m) {
            m.def("link_dataset", &link_dataset);
        }

        }   // end namespace dolfin
        """
        # self.cpp_link_module = dolfin.compile_cpp_code(cpp_link_code, additional_system_headers=["dolfin/io/HDF5Interface.h"])
        self.cpp_link_module = dolfin.compile_cpp_code(cpp_link_code)
Beispiel #23
0
def test_compile_extension_module_kwargs():
    # This test check that instant_kwargs of compile_extension_module
    # are taken into account when computing signature
    m2 = compile_cpp_code('', cppargs='-O2')
    m0 = compile_cpp_code('', cppargs='')
    assert not m2.__file__ == m0.__file__
}

namespace py = pybind11;

PYBIND11_MODULE(SIGNATURE, m){
    m.def("restrict", [](py::object v,
                         const dolfin::FiniteElement& element,
                         const dolfin::Cell& cell){
        auto _v = v.attr("_cpp_object").cast<dolfin::Function&>();
        std::vector<double> _w(element.space_dimension());
        restrict(_v, element, cell, _w);
        return _w;
    });
}
"""
compiled = df.compile_cpp_code(code)
restrict = compiled.restrict

class Particle:
    __slots__ = ['position', 'properties']
    'Lagrangian particle with position and some other passive properties.'
    def __init__(self, x):
        self.position = x
        self.properties = {}

    def send(self, dest):
        'Send particle to dest.'
        comm.Send(self.position, dest=dest)
        comm.send(self.properties, dest=dest)

    def recv(self, source):
Beispiel #25
0
  m.def("dofmap_dofs_is", &dofmap_dofs_is);
}

namespace pybind11
{
  namespace detail
  {
    PETSC_CASTER_MACRO(IS, is);
  }
}
"""

# Load and wrap compiled function dofmap_dofs_is
path = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
module_dofs = compile_cpp_code(dofmap_dofs_is_cpp_code,
                               include_dirs=[path,
                                             petsc4py.get_include()])


def dofmap_dofs_is(dofmap):
    """Converts DofMap::dofs() to IS.

    This function is intended to circumvent NumPy which would be
    involved in code like::

        iset = PETSc.IS().createGeneral(dofmap.dofs(),
                                        comm=dofmap.index_map().mpi_comm())
    """
    iset = module_dofs.dofmap_dofs_is(dofmap)
    iset.decRef()
    assert iset.getRefCount() == 1
    def from_parameters(cls, params=None):
        params = params or {}
        parameters = cls.default_parameters()
        parameters.update(params)

        msh_name = Path("test.msh")
        create_benchmark_ellipsoid_mesh_gmsh(
            msh_name,
            r_short_endo=parameters["r_short_endo"],
            r_short_epi=parameters["r_short_epi"],
            r_long_endo=parameters["r_long_endo"],
            r_long_epi=parameters["r_long_epi"],
            quota_base=parameters["quota_base"],
            psize=parameters["mesh_generation"]["psize"],
            ndiv=parameters["mesh_generation"]["ndiv"],
        )

        geo: HeartGeometry = gmsh2dolfin(msh_name)
        msh_name.unlink()
        obj = cls(
            mesh=geo.mesh,
            marker_functions=geo.marker_functions,
            markers=geo.markers,
        )
        obj._parameters = parameters

        # microstructure
        mspace = obj._parameters["microstructure"]["function_space"]

        dolfin.info("Creating microstructure")
        # coordinate mapping

        cart2coords_code = obj._compile_cart2coords_code()
        cart2coords = dolfin.compile_cpp_code(cart2coords_code)
        cart2coords_expr = dolfin.CompiledExpression(
            cart2coords.SimpleEllipsoidCart2Coords(),
            degree=1,
        )

        # local coordinate base
        localbase_code = obj._compile_localbase_code()
        localbase = dolfin.compile_cpp_code(localbase_code)
        localbase_expr = dolfin.CompiledExpression(
            localbase.SimpleEllipsoidLocalCoords(
                cart2coords_expr.cpp_object()),
            degree=1,
        )

        # function space
        family, degree = mspace.split("_")
        degree = int(degree)
        V = dolfin.TensorFunctionSpace(obj.mesh, family, degree, shape=(3, 3))
        # microstructure expression
        alpha_endo = obj._parameters["microstructure"]["alpha_endo"]
        alpha_epi = obj._parameters["microstructure"]["alpha_epi"]

        microstructure_code = obj._compile_microstructure_code()
        microstructure = dolfin.compile_cpp_code(microstructure_code)
        microstructure_expr = dolfin.CompiledExpression(
            microstructure.EllipsoidMicrostructure(
                cart2coords_expr.cpp_object(),
                localbase_expr.cpp_object(),
                alpha_epi,
                alpha_endo,
            ),
            degree=1,
        )

        # interpolation
        W = dolfin.VectorFunctionSpace(obj.mesh, family, degree)
        microinterp = interpolate(microstructure_expr, V)
        s0 = project(microinterp[0, :], W)
        n0 = project(microinterp[1, :], W)
        f0 = project(microinterp[2, :], W)
        obj.microstructure = Microstructure(f0=f0, s0=s0, n0=n0)
        obj.update_xshift()

        return obj
Beispiel #27
0
                return "superlu_dist";
                #elif PETSC_HAVE_PASTIX
                return "pastix";
                #else
                throw std::logic_error("No suitable solver for parallel LU found");
                #endif
            }
        }
"""

if has_pybind11():
    cpp_code = "".join([
        """
        #include <petscksp.h>
        #include <dolfin/common/MPI.h>
        #include <pybind11/pybind11.h>
        """, cpp_code, """
        PYBIND11_MODULE(SIGNATURE, m)
        {
            m.def("get_default_linear_solver", &get_default_linear_solver);
        }
        """
    ])
    get_default_linear_solver = compile_cpp_code(
        cpp_code).get_default_linear_solver
else:
    get_default_linear_solver = compile_extension_module(
        cpp_code,
        additional_system_headers=["petscksp.h", "dolfin/common/MPI.h"
                                   ]).get_default_linear_solver
Beispiel #28
0
            }
            values[0] = tau;
        };

};


PYBIND11_MODULE(SIGNATURE, m){
    py::class_<SUPG, std::shared_ptr<SUPG>, dolfin::Expression>
    (m, "SUPG").def(py::init<std::shared_ptr<dolfin::Function>>())
    .def("eval", &SUPG::eval)
    .def_readwrite("D", &SUPG::D);
}

'''

tau_code_compiled = df.compile_cpp_code(tau_code)
tau_c = df.CompiledExpression(tau_code_compiled.SUPG(u_.cpp_object()),
                              D=.1, element=r_.ufl_element())

# tau_c.value_rank()
values = np.zeros(2)
x = np.array([0.5, 0.5])
tau_c.eval(values, x)

print(df.assemble(tau_c*df.dx(domain=mesh)))
tau = df.interpolate(tau_c, Q)

df.plot(tau)
plt.show()
Beispiel #29
0
    double R = sqrt(pow(x[0],2)+pow(x[1],2));
    double phi = atan2(x[1],x[0]);

    double d_0 = C_9 + C_2*cyl_bessel_k(0, R*lambda_2/tau) + C_8*cyl_bessel_i(0, R*lambda_2/tau);
    double d = - (10*A_1 * pow(R,2))/(27*tau) + (4*C_4*R)/(tau) - (2*C_5*tau)/R + C_14*cyl_bessel_k(1, R*lambda_2/tau) + C_15* cyl_bessel_i(1, R*lambda_2/tau);

    values[0] = d_0 + cos(phi) * d;
  }

    // The data stored in mesh functions
  double R;

};

PYBIND11_MODULE(SIGNATURE, m)
{
  py::class_<Pressure, std::shared_ptr<Pressure>, dolfin::Expression>
    (m, "Pressure")
  .def(py::init<>());
}
"""

c = df.CompiledExpression(df.compile_cpp_code(p_code).Pressure(), degree=1)
print(2 * c([1, 1]))

p_i = df.interpolate(c, V)
df.plot(p_i)

file = df.File("out.pvd")
file.write(p_i)
Beispiel #30
0
from dolfin import SystemAssembler, assemble, NewtonSolver, PETScFactory, NonlinearProblem, compile_cpp_code

_cpp = """
#include <pybind11/pybind11.h>
#include <dolfin/nls/NewtonSolver.h>
PYBIND11_MODULE(SIGNATURE, m)
{
  pybind11::class_<dolfin::NewtonSolver, std::shared_ptr<dolfin::NewtonSolver>>
  (m, "NewtonSolverExt", pybind11::module_local())
  .def("krylov_iterations", &dolfin::NewtonSolver::krylov_iterations);
}
"""
NewtonSolver.krylov_iterations = compile_cpp_code(
    _cpp).NewtonSolverExt.krylov_iterations


class rmtursAssembler(object):
    def __init__(self, a, L, bcs, a_pc=None):
        self.assembler = SystemAssembler(a, L, bcs)
        if a_pc is not None:
            self.assembler_pc = SystemAssembler(a_pc, L, bcs)
        else:
            self.assembler_pc = None
        self._bcs = bcs

    def rhs_vector(self, b, x=None):
        if x is not None:
            self.assembler.assemble(b, x)
        else:
            self.assembler.assemble(b)
Beispiel #31
0
def evaluate_basis_functions(V, positions, cell_indices, factors):
    """
    Current FEniCS pybind11 bindings lack wrappers for these functions,
    so a small C++ snippet is used to generate the necessary dof factors
    to evaluate a function at the given points
    """
    if evaluate_basis_functions.func is None:
        cpp_code = """
        #include <vector>
        #include <pybind11/pybind11.h>
        #include <pybind11/eigen.h>
        #include <pybind11/numpy.h>
        #include <dolfin/fem/FiniteElement.h>
        #include <dolfin/function/FunctionSpace.h>
        #include <dolfin/mesh/Mesh.h>
        #include <dolfin/mesh/Cell.h>
        #include <Eigen/Core>

        using IntVecIn = Eigen::Ref<const Eigen::VectorXi>;
        using RowMatrixXd = Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
        namespace py = pybind11;

        void dof_factors(const dolfin::FunctionSpace &V, const RowMatrixXd &positions,
                         const IntVecIn &cell_indices, Eigen::Ref<RowMatrixXd> out)
        {
            const int N = out.rows();
            if (N == 0)
                return;

            const auto &element = V.element();
            const auto &mesh = V.mesh();
            const auto &ufc_element = element->ufc_element();
            std::vector<double> coordinate_dofs;

            const std::size_t size = ufc_element->value_size();
            const std::size_t space_dimension = ufc_element->space_dimension();
            if (size * space_dimension != out.cols())
                throw std::length_error("ERROR: out.cols() != ufc element size * ufc element space_dimension");

            for (int i = 0; i < N; i++)
            {
                int cell_index = cell_indices(i);
                dolfin::Cell cell(*mesh, cell_index);
                cell.get_coordinate_dofs(coordinate_dofs);
                element->evaluate_basis_all(out.row(i).data(),
                                            positions.row(i).data(),
                                            coordinate_dofs.data(),
                                            cell.orientation());
            }
        }

        PYBIND11_MODULE(SIGNATURE, m) {
           m.def("dof_factors", &dof_factors, py::arg("V"),
                 py::arg("positions"), py::arg("cell_indices"),
                 py::arg("out").noconvert());
        }
        """
        evaluate_basis_functions.func = dolfin.compile_cpp_code(cpp_code).dof_factors

    assert len(cell_indices) == len(positions) == len(factors)
    evaluate_basis_functions.func(V._cpp_object, positions, cell_indices, factors)
Beispiel #32
0
# terms of the GNU General Public License (as published by the Free
# Software Foundation) version 2.0 dated June 1991.

import dolfin as dl
import ufl
import numpy as np
import os

abspath = os.path.dirname(os.path.abspath(__file__))
source_directory = os.path.join(abspath, "cpp_AssemblePointwiseObservation")
with open(os.path.join(source_directory, "AssemblePointwiseObservation.cpp"),
          "r") as cpp_file:
    cpp_code = cpp_file.read()

include_dirs = [".", source_directory]
cpp_module = dl.compile_cpp_code(cpp_code, include_dirs=include_dirs)


def assemblePointwiseObservation(Vh, targets, prune_and_sort=False):
    """
    Assemble the pointwise observation matrix:

    Inputs

        - :code:`Vh`: FEniCS finite element space.
        - :code:`targets`: observation points (numpy array).
    """
    #Ensure that PetscInitialize is called
    dummy = dl.assemble(
        ufl.inner(dl.TrialFunction(Vh), dl.TestFunction(Vh)) * ufl.dx)
    #Call the cpp module to compute the pointwise observation matrix
Beispiel #33
0
from dolfin import SubSystemsManager
SubSystemsManager.init_petsc()  # init PETSc by DOLFIN before petsc4py import
from petsc4py import PETSc
PETSc.Sys.pushErrorHandler("traceback")
del SubSystemsManager, PETSc

# Import public API
from fenapack.field_split import PCDKSP, PCDKrylovSolver
from fenapack.assembling import PCDAssembler, PCDForm
from fenapack.nonlinear_solvers import PCDNewtonSolver, PCDNonlinearProblem
from fenapack.preconditioners import PCDPC_BRM1, PCDPC_BRM2
from fenapack.preconditioners import PCDRPC_BRM1, PCDRPC_BRM2
from fenapack.stabilization import StabilizationParameterSD


# Monkey patch dolfin.NewtonSolver in 2018.1.0
from dolfin import NewtonSolver, compile_cpp_code
_cpp = """
#include <pybind11/pybind11.h>
#include <dolfin/nls/NewtonSolver.h>

PYBIND11_MODULE(SIGNATURE, m)
{
  pybind11::class_<dolfin::NewtonSolver, std::shared_ptr<dolfin::NewtonSolver>>
  (m, "NewtonSolverExt", pybind11::module_local())
  .def("krylov_iterations", &dolfin::NewtonSolver::krylov_iterations);
}
"""
NewtonSolver.krylov_iterations = compile_cpp_code(_cpp).NewtonSolverExt.krylov_iterations
del _cpp, NewtonSolver, compile_cpp_code