Beispiel #1
0
def project(expr, space):
    u, v = TrialFunction(space), TestFunction(space)
    a = inner(u, v)*dx
    L = inner(expr, v)*dx
    A, b = PETScMatrix(), PETScVector()
    assemble_system(a, L, A_tensor=A, b_tensor=b)

    uh = Function(space)
    x = uh.vector()
    solve(A, x, b, 'lu')

    lmax = SLEPcEigenSolver(A)
    lmax.parameters["spectrum"] = "largest magnitude"
    lmax.parameters["problem_type"] = "hermitian"
    lmax.solve(2)
    lmax = max([lmax.get_eigenpair(i)[0] for i in range(lmax.get_number_converged())])

    lmin = SLEPcEigenSolver(A)
    lmin.parameters["spectrum"] = "smallest magnitude"
    lmin.parameters["problem_type"] = "hermitian"
    lmin.solve(2)
    lmin = max([lmin.get_eigenpair(i)[0] for i in range(lmin.get_number_converged())])

    print space.dim(), 'Cond number', lmax/lmin



    
    return uh
Beispiel #2
0
 def __init__(self, V, A, B=None, bcs=None):
     self.V = V
     if bcs is not None:
         self._set_boundary_conditions(bcs)
     A = self._assemble_if_form(A)
     if B is not None:
         B = self._assemble_if_form(B)
     self._set_operators(A, B)
     if self.B is not None:
         self.eigen_solver = SLEPcEigenSolver(self.condensed_A,
                                              self.condensed_B)
     else:
         self.eigen_solver = SLEPcEigenSolver(self.condensed_A)
Beispiel #3
0
    def solve(self, mesh, num=5):
        """ Solve for num eigenvalues based on the mesh. """
        # conforming elements
        V = FunctionSpace(mesh, "CG", self.degree)
        u = TrialFunction(V)
        v = TestFunction(V)

        # weak formulation
        a = inner(grad(u), grad(v)) * dx
        b = u * v * ds
        A = PETScMatrix()
        B = PETScMatrix()
        A = assemble(a, tensor=A)
        B = assemble(b, tensor=B)

        # find eigenvalues
        eigensolver = SLEPcEigenSolver(A, B)
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["spectrum"] = "smallest real"
        eigensolver.parameters["spectral_shift"] = 1.0E-10
        eigensolver.solve(num + 1)

        # extract solutions
        lst = [
            eigensolver.get_eigenpair(i)
            for i in range(1, eigensolver.get_number_converged())
        ]
        for k in range(len(lst)):
            u = Function(V)
            u.vector()[:] = lst[k][2]
            lst[k] = (lst[k][0], u)  # pair (eigenvalue,eigenfunction)
        return np.array(lst)
Beispiel #4
0
 def setup_solver(self):
     shift = (2.0*pi*self.eigenmode_guess)**2
     self.esolver = SLEPcEigenSolver(self._A, self._B) 
     self.esolver.parameters["solver"] = "krylov-schur"
     self.esolver.parameters["tolerance"] = 1e-12
     self.esolver.parameters["spectral_transform"] = "shift-and-invert"
     self.esolver.parameters["spectral_shift"] = shift
     self.esolver.parameters["spectrum"] = "target magnitude"
Beispiel #5
0
 def __init__(self, mesh, materials):
     """ init class always require mesh and materials to
     build the weak form """
     self.mesh = mesh
     self.materials = materials #FIXME throw error if not all domains are initilized
     self.eigenmode_guess = 1.0
     self.n_modes = 10 # number of modes to solve for      
     self.plot_eigenmodes = True
     self._A = PETScMatrix()
     self._B = PETScMatrix()	
     self.esolver = SLEPcEigenSolver(self._A, self._B)
Beispiel #6
0
def compute_eig(M, filename, parameters=[]):
    """ Compute eigenvalues of a PETScMatrix M,
    and print to filename """
    mpirank = MPI.rank(M.mpi_comm())

    if mpirank == 0:    print '\t\tCompute eigenvalues'
    eigsolver = SLEPcEigenSolver(M)
    eigsolver.parameters.update(parameters)
    eigsolver.solve()

    if mpirank == 0:    
        print '\t\tSort eigenvalues'
        eig = []
        for ii in range(eigsolver.get_number_converged()):
            eig.append(eigsolver.get_eigenvalue(ii)[0])
        eig.sort()

        print '\t\tPrint results to file'
        np.savetxt(filename, np.array(eig))
Beispiel #7
0
 def _assemble(self):
     # Get input:
     self.gamma = self.Parameters['gamma']
     if self.Parameters.has_key('beta'): self.beta = self.Parameters['beta']
     else: self.beta = 0.0
     self.Vm = self.Parameters['Vm']
     if self.Parameters.has_key('m0'):
         self.m0 = self.Parameters['m0'].copy(deepcopy=True)
         isFunction(self.m0)
     else:
         self.m0 = Function(self.Vm)
     self.mtrial = TrialFunction(self.Vm)
     self.mtest = TestFunction(self.Vm)
     self.mysample = Function(self.Vm)
     self.draw = Function(self.Vm)
     # Assemble:
     self.R = assemble(inner(nabla_grad(self.mtrial), \
     nabla_grad(self.mtest))*dx)
     self.M = PETScMatrix()
     assemble(inner(self.mtrial, self.mtest) * dx, tensor=self.M)
     # preconditioner is Gamma^{-1}:
     if self.beta > 1e-16:
         self.precond = self.gamma * self.R + self.beta * self.M
     else:
         self.precond = self.gamma * self.R + (1e-14) * self.M
     # Discrete operator K:
     self.K = self.gamma * self.R + self.beta * self.M
     # Get eigenvalues for M:
     self.eigsolM = SLEPcEigenSolver(self.M)
     self.eigsolM.solve()
     # Solver for M^{-1}:
     self.solverM = LUSolver()
     self.solverM.parameters['reuse_factorization'] = True
     self.solverM.parameters['symmetric'] = True
     self.solverM.set_operator(self.M)
     # Solver for K^{-1}:
     self.solverK = LUSolver()
     self.solverK.parameters['reuse_factorization'] = True
     self.solverK.parameters['symmetric'] = True
     self.solverK.set_operator(self.K)
Beispiel #8
0
    def solve(self, n=None):
        """
        solve(n=None):

        Solve the eigenvalue problem and return the converged
        eigenvalues

        n indicates the number of eigenvalues to be calculated
        """

        # Standard eigenvalue problem
        if self.b is None:
            A = PETScMatrix()
            assemble(self.a, tensor=A)

            if self.bc:
                self.bc.apply(A)

            solver = SLEPcEigenSolver(A)
            solver.solve()

        # Generalized eigenvalue problem
        else:
            A = PETScMatrix()
            assemble(self.a, tensor=A)
            B = PETScMatrix()
            assemble(self.b, tensor=B)

            # Set options for eigensolver
            solver = SLEPcEigenSolver(A, B)
            for key, key_info in self.parameters.iterdata():
                solver.parameters[key] = self.parameters[key]

            if n is None:
                n = A.size(0)

            if self.bc:
                self.bc.apply(A)
                self.bc.apply(B)

            solver.solve(n)

        # Pick real part of eigenvalues computed
        m = solver.get_number_converged()

        complex_eps = 0.001
        eigenvalues = [solver.get_eigenvalue(i)[0] for i in range(m)
                       if abs(solver.get_eigenvalue(i)[1]) < complex_eps]

        if len(eigenvalues) == 0:
            raise RuntimeError("No real-valued eigenvalues found")

        # Compute all eigenvalues if eigenvalue is zero and not only
        # testing for stability
        if (n < A.size(0)
            and abs(eigenvalues[0]) < ascot_parameters["eps"]
            and not ascot_parameters["only_stable"]):

            info("Only zero eigenvalues detected. Computing all.")
            solver.solve(A.size(0))
            m = solver.get_number_converged()
            eigenvalues = [solver.get_eigenvalue(i)[0] for i in range(m)
                           if abs(solver.get_eigenvalue(i)[1]) < 0.1]

        return eigenvalues
Beispiel #9
0
    def solve(self):
        """ Find eigenvalues for transformed mesh. """
        self.progress("Building mesh.")
        # build transformed mesh
        mesh = self.refineMesh()
        # dim = mesh.topology().dim()
        if self.bcLast:
            mesh = transform_mesh(mesh, self.transformList)
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
        else:
            Robin, Steklov, shift, bcs = get_bc_parts(mesh, self.bcList)
            mesh = transform_mesh(mesh, self.transformList)
            # boundary conditions computed on non-transformed mesh
            # copy the values to transformed mesh
            fun = FacetFunction("size_t", mesh, shift)
            fun.array()[:] = bcs.array()[:]
            bcs = fun
        ds = Measure('ds', domain=mesh, subdomain_data=bcs)
        V = FunctionSpace(mesh, self.method, self.deg)
        u = TrialFunction(V)
        v = TestFunction(V)
        self.progress("Assembling matrices.")
        wTop = Expression(self.wTop)
        wBottom = Expression(self.wBottom)

        #
        # build stiffness matrix form
        #
        s = dot(grad(u), grad(v)) * wTop * dx
        # add Robin parts
        for bc in Robin:
            s += Constant(bc.parValue) * u * v * wTop * ds(bc.value + shift)

        #
        # build mass matrix form
        #
        if len(Steklov) > 0:
            m = 0
            for bc in Steklov:
                m += Constant(
                    bc.parValue) * u * v * wBottom * ds(bc.value + shift)
        else:
            m = u * v * wBottom * dx

        # assemble
        # if USE_EIGEN:
        #     S, M = EigenMatrix(), EigenMatrix()
        # tempv = EigenVector()
        # else:
        S, M = PETScMatrix(), PETScMatrix()
        # tempv = PETScVector()

        if not np.any(bcs.array() == shift + 1):
            # no Dirichlet parts
            assemble(s, tensor=S)
            assemble(m, tensor=M)
        else:
            #
            # with EIGEN we could
            #   apply Dirichlet condition symmetrically
            #   completely remove rows and columns
            #
            # Dirichlet parts are marked with shift+1
            #
            # temp = Constant(0)*v*dx
            bc = DirichletBC(V, Constant(0.0), bcs, shift + 1)
            # assemble_system(s, temp, bc, A_tensor=S, b_tensor=tempv)
            # assemble_system(m, temp, bc, A_tensor=M, b_tensor=tempv)
            assemble(s, tensor=S)
            bc.apply(S)
            assemble(m, tensor=M)
            # bc.zero(M)

        # if USE_EIGEN:
        #    M = M.sparray()
        #    M.eliminate_zeros()
        #    print M.shape
        #    indices = M.indptr[:-1] - M.indptr[1:] < 0
        #    M = M[indices, :].tocsc()[:, indices]
        #    S = S.sparray()[indices, :].tocsc()[:, indices]
        #    print M.shape
        #
        # solve the eigenvalue problem
        #
        self.progress("Solving eigenvalue problem.")
        eigensolver = SLEPcEigenSolver(S, M)
        eigensolver.parameters["problem_type"] = "gen_hermitian"
        eigensolver.parameters["solver"] = "krylov-schur"
        if self.target is not None:
            eigensolver.parameters["spectrum"] = "target real"
            eigensolver.parameters["spectral_shift"] = self.target
        else:
            eigensolver.parameters["spectrum"] = "smallest magnitude"
            eigensolver.parameters["spectral_shift"] = -0.01
        eigensolver.parameters["spectral_transform"] = "shift-and-invert"
        eigensolver.solve(self.number)
        self.progress("Generating eigenfunctions.")
        if eigensolver.get_number_converged() == 0:
            return None
        eigf = []
        eigv = []
        if self.deg > 1:
            mesh = refine(mesh)
        W = FunctionSpace(mesh, 'CG', 1)
        for i in range(eigensolver.get_number_converged()):
            pair = eigensolver.get_eigenpair(i)[::2]
            eigv.append(pair[0])
            u = Function(V)
            u.vector()[:] = pair[1]
            eigf.append(interpolate(u, W))
        return eigv, eigf
Beispiel #10
0
def standard_solver(K, M):
    solver = SLEPcEigenSolver(K, M)
    solver.parameters['spectrum'] = 'smallest magnitude'
    solver.parameters['tolerance'] = 1e-4
    solver.parameters['problem_type'] = 'pos_gen_non_hermitian'
    return solver