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
Ejemplo n.º 2
0
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))
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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])
Ejemplo n.º 5
0
    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]