Exemple #1
0
def solve_eigensystem(A, B, problem_type=SLEPc.EPS.ProblemType.GHEP):
    # Create the results vectors
    xr, tmp = A.getVecs()
    xi, tmp = A.getVecs()

    pc = PETSc.PC().create()
    # pc.setType(pc.Type.HYPRE)
    pc.setType(pc.Type.BJACOBI)

    ksp = PETSc.KSP().create()
    ksp.setType(ksp.Type.PREONLY)
    ksp.setPC(pc)

    F = SLEPc.ST().create()
    F.setType(F.Type.PRECOND)
    F.setKSP(ksp)
    F.setShift(0)

    # Setup the eigensolver
    E = SLEPc.EPS().create()
    E.setST(F)
    E.setOperators(A, B)
    E.setType(E.Type.LOBPCG)
    E.setDimensions(10, PETSc.DECIDE)
    E.setWhichEigenpairs(E.Which.SMALLEST_REAL)
    E.setProblemType(problem_type)
    E.setFromOptions()

    # Solve the eigensystem
    E.solve()

    Print("")
    its = E.getIterationNumber()
    Print("Number of iterations of the method: %i" % its)
    sol_type = E.getType()
    Print("Solution method: %s" % sol_type)
    nev, ncv, mpd = E.getDimensions()
    Print("Number of requested eigenvalues: %i" % nev)
    tol, maxit = E.getTolerances()
    Print("Stopping condition: tol=%.4g, maxit=%d" % (tol, maxit))
    nconv = E.getConverged()
    Print("Number of converged eigenpairs: %d" % nconv)
    if nconv > 0:
        Print("")
        Print("        k          ||Ax-kx||/||kx|| ")
        Print("----------------- ------------------")
        for i in range(nconv):
            k = E.getEigenpair(i, xr, xi)
            error = E.computeError(i)
            if k.imag != 0.0:
                Print(" %9f%+9f j  %12g" % (k.real, k.imag, error))
            else:
                Print(" %12f       %12g" % (k.real, error))
        Print("")
Exemple #2
0
     def _create(self,nev,target):
         """ Create and setup the SLEPC solver"""
         
         # mpi stuff    
         comm=PETSc.COMM_WORLD.tompi4py()
         rank = comm.Get_rank()
         # create the solver with the selected factory
         E = self._SLEPc_PB()
         E.create()
         
         # Setup the spectral transformation
         SHIFT = SLEPc.ST().create()
         SHIFT.setType(SHIFT.Type.SINVERT)
         E.setST(SHIFT)  
         E.setTarget(target)
         # operator setup
         K = self.K
         if self.pb_type == 'std':
             # unpack the operator matrix        
             E.setOperators(*K)
         if self.pb_type == 'gen':
             # M=-K1      
             E.setOperators(K[0],-K[1])            
         else:
             E.setOperators(K)
             
         # number of eigenvlue we are looking for   
         E.setDimensions(nev=nev)
         # By defaut use non hermitian solver
         E.setProblemType(self.PB_TYPE[self.pb_type])
    
         # Direct solver seting (for shift and invert)      
         ksp=SHIFT.getKSP()    
         ksp.setType('preonly')  # direct solver in petsc= preconditioner        
         pc=ksp.getPC()
         pc.setType('lu')
         #pc.setFactorSolverType('superlu_dist')
 
         # set solver options
         pc.setFactorSolverType(gopts['direct_solver_name'])
         opts = PETSc.Options(gopts['direct_solver_petsc_options_name'])
         for op_name,op_value in gopts['direct_solver_petsc_options_dict'].items():
             opts[op_name]=op_value
         # Mumps options to avoid mumps crash with high fill in
         # The problem arise if the prediction/mem allocation is too different (default 20%)
         #opts["icntl_14"] = 50 # ICNTL(14) controls the percentage increase in the estimated working space
         #opts["icntl_6"] = 5  # Use ICNTL(6)= 5 for augmented system (which is asystem with a large zero diagonal block).     
   
         #  After all options have been set, the user should call the setFromOptions() 
         E.setFromOptions()
         
         # store the solver
         self.E=E
Exemple #3
0
def DirectModeSLEPc(ffdisc, shift, nev):

    from petsc4py import PETSc
    from slepc4py import SLEPc

    # Operators
    print 'Set operators'
    Lmat = CSR2Mat(ffdisc.L)
    Bmat = CSR2Mat(ffdisc.B)

    # Setup EPS
    print 'Set solver'

    S = SLEPc.EPS()
    S.create()
    S.setTarget(shift)
    S.setWhichEigenpairs(SLEPc.EPS.Which.TARGET_MAGNITUDE)
    SI = SLEPc.ST().create()
    SI.setType(SLEPc.ST.Type.SINVERT)
    SI.setOperators(Lmat, Bmat)
    SI.setShift(shift)
    S.setST(SI)

    S.setDimensions(nev=nev, ncv=60)
    S.setTolerances(tol=tol_ev, max_it=100)
    S.setFromOptions()

    # Solve the EVP
    print 'Solving EVP'
    S.solve()

    its = S.getIterationNumber()
    nconv = S.getConverged()

    omega = zeros(nconv, 'complex')
    modes = zeros([ffdisc.ndof, nconv], 'complex')

    ev = Lmat.getVecRight()

    for i in range(nconv):
        eigval = S.getEigenpair(i, ev)
        v = Vec2DOF(ev)

        omega[i] = eigval / (-1j)
        modes[:, i] = v

    return omega, modes
Exemple #4
0
def _init_spectral_inverter(STType="sinvert",
                            KSPType="preonly",
                            PCType="lu",
                            PCFactorSolverType="mumps",
                            comm=None):
    """Create a slepc spectral transformation object with specified solver.
    """
    SLEPc, comm = get_slepc(comm=comm)
    S = SLEPc.ST().create(comm=comm)
    S.setType(STType)
    # set the krylov subspace and preconditioner.
    if KSPType:
        K = _init_krylov_subspace(
            KSPType=KSPType, PCType=PCType, comm=comm,
            PCFactorSolverType=PCFactorSolverType)
        S.setKSP(K)
    S.setFromOptions()
    return S
Exemple #5
0
def help(args=None):
    import sys
    # program name
    try:
        prog = sys.argv[0]
    except Exception:
        prog = getattr(sys, 'executable', 'python')
    # arguments
    if args is None:
        args = sys.argv[1:]
    elif isinstance(args, str):
        args = args.split()
    else:
        args = [str(a) for a in args]
    # initialization
    import slepc4py
    slepc4py.init([prog, '-help'] + args)
    from slepc4py import SLEPc
    # and finally ...
    COMM = SLEPc.COMM_SELF
    if 'eps' in args:
        eps = SLEPc.EPS().create(comm=COMM)
        eps.setFromOptions()
        eps.destroy()
        del eps
    if 'svd' in args:
        svd = SLEPc.SVD().create(comm=COMM)
        svd.setFromOptions()
        svd.destroy()
        del svd
    if 'pep' in args:
        pep = SLEPc.PEP().create(comm=COMM)
        pep.setFromOptions()
        pep.destroy()
        del pep
    if 'nep' in args:
        nep = SLEPc.NEP().create(comm=COMM)
        nep.setFromOptions()
        nep.destroy()
        del nep
    if 'mfn' in args:
        mfn = SLEPc.MFN().create(comm=COMM)
        mfn.setFromOptions()
        mfn.destroy()
        del mfn
    if 'st' in args:
        st = SLEPc.ST().create(comm=COMM)
        st.setFromOptions()
        st.destroy()
        del st
    if 'bv' in args:
        bv = SLEPc.BV().create(comm=COMM)
        bv.setFromOptions()
        bv.destroy()
        del bv
    if 'rg' in args:
        rg = SLEPc.RG().create(comm=COMM)
        rg.setFromOptions()
        rg.destroy()
        del rg
    if 'fn' in args:
        fn = SLEPc.FN().create(comm=COMM)
        fn.setFromOptions()
        fn.destroy()
        del fn
    if 'ds' in args:
        ds = SLEPc.DS().create(comm=COMM)
        ds.setFromOptions()
        ds.destroy()
        del ds
Exemple #6
0
def DirectModeSLEPc(L, B, shift, nev):
    """
    Computes generalized eigenvectors and eigenvalues for the problem
    Lq = lambda Bq
    using SLEPc
    inputs : B,L, PETSc Mats
             shift, scalar (same on all procs). Shift parameter for 
               the shift-invert method
             nev, integer. Number of requested eigenvalues

    outputs: omega, complex array(nconv). Conputed eigenvalues
             modes, complex array(nconv,ndofs). Computed eigenvectors
             residual, real array(nconv). Actual residuals for each mode
    
    ALL OUTPUT ARE ONLY ON PROC 0 (=None on other procs)

    TO DO: compute left eigenvectors (adjoint problem)
    """

    comm = MPI.COMM_WORLD
    rank = comm.Get_rank()

    ev = L.getVecRight()
    Lq = ev.duplicate()
    Bq = ev.duplicate()

    ndof = ev.getSize()

    # Setup EPS
    Print("  - Setting up the EPS and the ST")
    SI = SLEPc.ST().create()
    SI.setType(SLEPc.ST.Type.SINVERT)
    SI.setOperators(L, B)
    SI.setShift(shift)
    SI.setFromOptions()

    S = SLEPc.EPS()
    S.create(comm)
    S.setTarget(shift)
    S.setWhichEigenpairs(SLEPc.EPS.Which.TARGET_MAGNITUDE)
    S.setST(SI)
    S.setDimensions(nev=nev, ncv=60)
    S.setTolerances(tol=tol_ev, max_it=100)
    S.setFromOptions()

    # Solve the EVP
    Print("  - Solving the EPS")
    S.solve()

    its = S.getIterationNumber()
    nconv = S.getConverged()

    if rank == 0:
        residual = zeros(nconv)
        omega = zeros(nconv, 'complex')
        modes = zeros([ndof, nconv], 'complex')
    else:
        residual = None
        omega = None
        modes = None

    for i in range(nconv):
        eigval = S.getEigenpair(i, ev)
        L.mult(ev, Lq)
        B.mult(ev, Bq)
        Bq.aypx(-eigval, Lq)
        res = Bq.norm() / ev.norm()
        v = Vec2DOF(ev)

        if rank == 0:
            omega[i] = eigval / (-1j)
            modes[:, i] = v
            residual[i] = res

    return omega, modes, residual