def set_pmr_solver(K, M): # =========================== Solver setting =========================== # define solver # How to use # SLEPcEigenSolver(A): Create eigenvalue solver for Ax = \lambda x # SLEPcEigenSolver(A, B): Create eigenvalue solver Ax = \lambda Bx (Generalized Hermitian eigenvalue problem) eigensolver = df.SLEPcEigenSolver(K, M) # Ku = \lambda Mu # print( help(SLEPcEigenSolver) ) # print( help(eigensolver.get_options_prefix ) ) # monitor SLEP solver # PETScOptions.set("eps_view") # PETScOptions.set("ksp_type", "cg") # PETScOptions.set("pc_type", "none") # PETScOptions.set("ksp_monitor_singular_value", "") # print(help(PETScOptions.set)) # set solver's parameters pmr = eigensolver.parameters # solver setup 1 pmr["problem_type"] = "gen_hermitian" pmr["tolerance"] = 1e-14 pmr["spectral_transform"] = "shift-and-invert" # needed pmr["spectral_shift"] = 0.0 pmr["solver"] = "krylov-schur" #pmr['solver'] = 'lanczos' # too long, even parallelism is used return eigensolver
def compute_eig(M, filename): eigsolver = dl.SLEPcEigenSolver(M) eigsolver.solve() eig = [] for ii in range(eigsolver.get_number_converged()): eig.append(eigsolver.get_eigenvalue(ii)[0]) eig.sort() np.savetxt(filename, np.array(eig))
def eigen_xct(V, A, B=None, k=100, spect='LM', **kwargs): """ Get eigen-pairs of A (or generalized eigen-pairs for (A,B)) for the first k in the spectrum spect. """ if 'mpi_comm' in kwargs: mpi_comm = kwargs['mpi_comm'] else: mpi_comm = df.mpi_comm_world() # mixed functions to store eigenfunctions try: M = df.FunctionSpace(V.mesh(), df.MixedElement([V.ufl_element()] * k)) except: print('Warning: ' 'MixedFunctionSpace' ' has been deprecated after DOLFIN version 1.6.0.') M = df.MixedFunctionSpace([V] * k) # Extract subfunction dofs eigf_dofs = [M.sub(i).dofmap().dofs() for i in range(k)] eigf = df.Function(M) # try reading eigen-pairs from file eig_files = [ f for f in os.listdir(os.getcwd()) if f.startswith('prior_' + spect + 'eig') ] found_eigv = False found_eigf = False if any(eig_files): for f_i in eig_files: if int(f_i.split("_k")[-1].split(".")[0]) >= k: if f_i.endswith('.txt'): try: eigv_ = np.loadtxt(os.path.join(os.getcwd(), f_i), delimiter=',') eigv = eigv_[:k] found_eigv = True except: pass if f_i.endswith('.h5'): try: f = df.HDF5File(mpi_comm, os.path.join(os.getcwd(), f_i), "r") eigf_i = df.Function(V, name='eigenfunction') for i, dof_i in enumerate(eigf_dofs): f.read(eigf_i, 'eigf_{0}'.format(i)) eigf.vector()[dof_i] = eigf_i.vector() f.close() found_eigf = True except: f.close() pass if found_eigv and found_eigf: break if found_eigv and found_eigf: print('Read the first %d eigen-pairs with ' % k + { 'LM': 'largest magnitude', 'SM': 'smallest magnitude' }[spect] + ' successfully!') return (eigv, eigf), eigf_dofs else: # solve the associated eigen-problem f = df.HDF5File( mpi_comm, os.path.join(os.getcwd(), 'prior_' + spect + 'eigf_k' + str(k) + '.h5'), "w") eigf_i = df.Function(V, name='eigenfunction') if type(A) is df.PETScMatrix and df.has_slepc(): # using SLEPc print("Computing the first %d eigenvalues with " % k + { 'LM': 'largest magnitude', 'SM': 'smallest magnitude' }[spect] + "...") # Create eigen-solver if B is not None and type(B) is df.PETScMatrix: eigen = df.SLEPcEigenSolver(A, B) eigen.parameters['problem_type'] = 'gen_hermitian' else: eigen = df.SLEPcEigenSolver(A) # eigen.parameters['problem_type']='hermitian' eigen.parameters['spectrum'] = { 'LM': 'largest magnitude', 'SM': 'smallest magnitude' }[spect] if spect is 'SM': eigen.parameters['tolerance'] = 1e-10 eigen.parameters['maximum_iterations'] = 100 eigen.parameters['spectral_transform'] = 'shift-and-invert' eigen.parameters['spectral_shift'] = 10.0 * df.DOLFIN_EPS eigen.solve(k) print( 'Total number of iterations: %d, and total number of convergences: %d.' % (eigen.get_iteration_number(), eigen.get_number_converged())) # get eigen-pairs eigv = np.zeros(k) for i, dof_i in enumerate(eigf_dofs): eigv[i], _, eigf_vec_i, _ = eigen.get_eigenpair(i) eigf_i.vector()[:] = eigf_vec_i[:] f.write(eigf_i, 'eigf_{0}'.format(i)) eigf.vector()[dof_i] = eigf_i.vector() else: warnings.warn( 'petsc4py or SLEPc not found! Using scipy.sparse.linalg.eigsh...' ) import scipy.sparse.linalg as spsla eigv, eigf_vec = spsla.eigsh(A, k=k, M=B, which=spect) dsc_ord = eigv.argsort()[::-1] eigv = eigv[dsc_ord] eigf_vec = eigf_vec[:, dsc_ord] for i, dof_i in enumerate(eigf_dofs): eigf_i.vector()[:] = eigf_vec[:, i] f.write(eigf_i, 'eigf_{0}'.format(i)) eigf.vector()[dof_i] = eigf_i.vector() f.close() np.savetxt(os.path.join(os.getcwd(), 'prior_' + spect + 'eigv_k' + str(k) + '.txt'), eigv, delimiter=',') return (eigv, eigf), eigf_dofs
dolfin.assemble(t, tensor=T) print(S.size(1)) markers=dolfin.MeshFunction('size_t',mesh,1) markers.set_all(0) dolfin.DomainBoundary().mark(markers,1) electric_wall = dolfin.DirichletBC(V, dolfin.Constant(0.0), markers, 1) electric_wall.apply(S) electric_wall.apply(T) #from scipy.linalg import eig #lambds, vectors=eig(S.array(),T.array()) # Solve the eigensystem esolver = dolfin.SLEPcEigenSolver(S,T) esolver.solve(S.size(1)) res=[esolver.get_eigenpair(i) for i in range(esolver.get_number_converged())] res.sort(key=lambda tup: tup[0]) lambds=np.array([r[0] for r in res]) vect=[r[2] for r in res] #lambds=np.sort(np.array(lambds)) plt.close('all') plt.figure() plt.plot(lambds, '.', color='g') for lambd in lambds_real[:20]: plt.plot([0,len(lambds)],[lambd, lambd], '--', color='r') plt.ylim([-1,lambds_real[20]+1])
bb[:] = b lu.solve(xx, bb) return xx[:] M_matvec = lambda x: M * x arpack_eigs, v = speigs.ARPACK_gen_eigs(M_matvec, sigma_solve, M.size(0), sigma, 51, ncv=91) # Create eigensolver esolver = dol.SLEPcEigenSolver(S, M) esolver.parameters["spectrum"] = "smallest real" esolver.parameters["solver"] = "arnoldi" esolver.parameters["spectral_shift"] = sigma esolver.parameters["spectral_transform"] = "shift-and-invert" esolver.solve() eigs = [esolver.get_eigenvalue(i)[0] for i in range(4)] filtered_eigs = [] for i in range(S.size(0)): ev_r, ev_i = esolver.get_eigenvalue(i) if ev_r > 0.001: filtered_eigs.append(ev_r) print sorted(arpack_eigs)[0:4] print eigs[0:4]