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])
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")