Beispiel #1
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))

bc = DirichletBC(V, u_D, boundary_D)
u = TrialFunction(V)
v = TestFunction(V)
f = Expression("10*exp(-(pow(x[0] - 0.5, 2) + pow(x[1] - 0.5, 2) \
                 + pow(x[2] - 0.5, 2)) / 0.02)", degree=6)
g = Expression("sin(5.0*x[0])*sin(5.0*x[1])", degree=6)
a = dot(grad(u), grad(v)) * dx
L = f * v * dx + g * v * ds
A = PETScMatrix()
b = PETScVector()
assemble_system(a, L, bc, A_tensor=A, b_tensor=b)

A = A.mat()
b = b.vec()

# =========================================================================

# Construct the alist for systems on levels from fine to coarse
# construct the transfer operators first
ruse = [None] * (nl - 1)
Alist = [None] * (nl)

ruse[0] = Mat()
puse[0].transpose(ruse[0])
Alist[0] = A

for il in range(1, nl-1):
    ruse[il] = Mat()
    puse[il].transpose(ruse[il])
Beispiel #3
0
    def get_eigenvector(self, i):
        # Helper functions
        if has_pybind11():
            cpp_code = """
                #include <pybind11/pybind11.h>
                #include <dolfin/la/PETScVector.h>
                #include <dolfin/la/SLEPcEigenSolver.h>
                
                PetscInt get_converged(std::shared_ptr<dolfin::SLEPcEigenSolver> eigen_solver)
                {
                    PetscInt num_computed_eigenvalues;
                    EPSGetConverged(eigen_solver->eps(), &num_computed_eigenvalues);
                    return num_computed_eigenvalues;
                }
                
                void get_eigen_pair(std::shared_ptr<dolfin::SLEPcEigenSolver> eigen_solver, std::size_t i, std::shared_ptr<dolfin::PETScVector> condensed_real_vector, std::shared_ptr<dolfin::PETScVector> condensed_imag_vector)
                {
                    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_converged", &get_converged);
                    m.def("get_eigen_pair", &get_eigen_pair);
                }
            """

            cpp_module = compile_cpp_code(cpp_code)
            get_converged = cpp_module.get_converged
            get_eigen_pair = cpp_module.get_eigen_pair
        else:

            def get_converged(eigen_solver):
                return eigen_solver.eps().getConverged()

            def get_eigen_pair(eigen_solver, i, condensed_real_vector,
                               condensed_imag_vector):
                eigen_solver.eps().getEigenpair(i, condensed_real_vector.vec(),
                                                condensed_imag_vector.vec())

        # Get number of computed eigenvectors/values
        num_computed_eigenvalues = get_converged(self.eigen_solver)

        if (i < num_computed_eigenvalues):
            # 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
            get_eigen_pair(self.eigen_solver, i, condensed_real_vector,
                           condensed_imag_vector)

            # 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))
        else:
            raise RuntimeError("Requested eigenpair has not been computed")