예제 #1
0
    def solve(self, flag):
        start = timer()
        A = self.get_laplace_matrix();
        b = self.get_source_vector();
        if flag == 1: 
            A += self.get_neuman_penalty_matrix();
            b += self.get_neuman_vector();
            bc = DirichletBC(self.space, self.pde.dirichlet)
        elif flag == 2:
            A += self.get_neuman_penalty_matrix();
            A += self.get_dirichlet_penalty_matrix();
            b += self.get_neuman_vector();
            b += self.get_dirichlet_vector();
            bc = None;
        elif flag == 3:
            b += self.get_laplace_dirichlet_vector();
            bc = DirichletBC(self.space, self.pde.dirichlet)
        elif flag == 4:
            A += self.get_neuman_penalty_matrix();
            b -= self.get_laplace_neuman_vector();
            b += self.get_neuman_vector();
            bc = None;
        end = timer()

        print("Construct linear system time:", end - start)

        if bc is not None:
            AD, b = bc.apply(A, b)
        else:
            if flag == 4:
                gdof = self.space.number_of_global_dofs()
                isBdDof = self.space.boundary_dof()
                x = np.zeros((gdof,), dtype=np.float)
                ipoints = self.space.interpolation_points()
                # the length of ipoints and isBdDof maybe different
                idx, = np.nonzero(isBdDof)
                x[idx[0]] = self.pde.dirichlet(ipoints[idx[0]])
                b -= A@x
                bdIdx = np.zeros(gdof, dtype=np.int)
                bdIdx[idx[0]] = 1
                Tbd = spdiags(bdIdx, 0, gdof, gdof)
                T = spdiags(1-bdIdx, 0, gdof, gdof)
                AD = T@A@T + Tbd

                b[idx[0]] = x[idx[0]] 
            else:
                AD = A

        start = timer()
        self.uh[:] = spsolve(AD, b)
        end = timer()

        print("Solve time:", end-start)

        self.recover_grad()
        self.recover_laplace()
예제 #2
0
    def solveDirect_mumps(self, b, factorize):
        """
            Use solve instead of this interface.

            :param numpy.ndarray b: the right hand side
            :param bool factorize: if you want to factorize and store factors
            :rtype: numpy.ndarray
            :return: x
        """
        if factorize and self.dsolve is None:
            self.mctx = mumps.DMumpsContext()
            self.mctx.set_icntl(14, 60)
            # self.mctx.set_silent()
            self.mctx.set_centralized_sparse(self.A)
            self.mctx.run(job=4)

            def mdsolve(rhs):
                x = rhs.copy()
                self.mctx.set_rhs(x)
                self.mctx.run(job=3)
                return x

            self.dsolve = mdsolve

        if len(b.shape) == 1 or b.shape[1] == 1:
            # Just one RHS
            if factorize:
                X = self.dsolve(b)
            else:
                X = mumps.spsolve(self.A, b)

        else:
            # Multiple RHSs
            X = np.empty_like(b)
            for i in range(b.shape[1]):
                if factorize:
                    X[:, i] = self.dsolve(b[:, i])
                else:
                    X[:, i] = mumps.spsolve(self.A, b[:, i])

        return X
예제 #3
0
    def solveDirect_mumps(self, b, factorize):
        """
            Use solve instead of this interface.

            :param numpy.ndarray b: the right hand side
            :param bool factorize: if you want to factorize and store factors
            :rtype: numpy.ndarray
            :return: x
        """
        if factorize and self.dsolve is None:
            self.mctx = mumps.DMumpsContext()
            self.mctx.set_icntl(14, 60)
            # self.mctx.set_silent()
            self.mctx.set_centralized_sparse(self.A)
            self.mctx.run(job=4)

            def mdsolve(rhs):
                x = rhs.copy()
                self.mctx.set_rhs(x)
                self.mctx.run(job=3)
                return x

            self.dsolve = mdsolve

        if len(b.shape) == 1 or b.shape[1] == 1:
            # Just one RHS
            if factorize:
                X = self.dsolve(b)
            else:
                X = mumps.spsolve(self.A, b)

        else:
            # Multiple RHSs
            X = np.empty_like(b)
            for i in range(b.shape[1]):
                if factorize:
                    X[:,i] = self.dsolve(b[:,i])
                else:
                    X[:,i] = mumps.spsolve(self.A,b[:,i])

        return X
예제 #4
0
def active_set_solver(dmodel,
                      uh,
                      gh,
                      maxit=5000,
                      dirichlet=None,
                      solver='direct'):
    space = uh.space
    start = timer()
    A = dmodel.get_left_matrix()
    b = dmodel.get_right_vector()
    end = timer()
    print("Construct linear system time:", end - start)

    if dirichlet is not None:
        AD, b = dirichlet.apply(A, b)

    AD = AD.tolil()
    start = timer()
    lam = space.function()

    gdof = space.number_of_global_dofs()
    I = np.ones(gdof, dtype=np.bool)

    k = 0
    while k < maxit:
        print(k)
        k += 1
        I0 = I.copy()
        I[:] = (lam + gh - uh > 0)
        if np.all(I == I0) & (k > 1):
            break

        M = AD.copy()
        F = b.copy()

        idx, = np.nonzero(I)
        M[idx, :] = 0
        M[idx, idx] = 1
        F[idx] = gh[idx]

        if solver is 'direct':
            uh[:] = spsolve(M.tocsr(), F)
        elif solver is 'amg':
            ml = pyamg.ruge_stuben_solver(M.tocsr())
            uh[:] = ml.solve(F, tol=1e-12, accel='cg').reshape(-1)
        lam[:] = AD @ uh - b
    end = timer()
    print("Solve time:", end - start)
    return A, b
예제 #5
0
    def linear_operator(self, r):
        tgdof = self.tensorspace.number_of_global_dofs()
        vgdof = self.vectorspace.number_of_global_dofs()
        gdof = tgdof + vgdof
        gdim = self.tensorspace.geo_dimension()

        r0 = r[0:tgdof]
        r1 = r[tgdof:]

        u0 = r0/self.D
        u1 = np.zeros(vgdof, dtype=np.float)
        r2 = r1 - self.B@u0

        for i in range(3):
            u1[:] = spsolve(self.SL, r2 - self.SU@u1, permc_spec="NATURAL") 

        r3 = r2 - (self.SL@u1 + self.SU@u1)
        for i in range(gdim):
            u1[i::gdim] = [email protected](self.PI.transpose()@r3[i::gdim], tol=1e-8, accel='cg')

        for i in range(3):
            u1[:] = spsolve(self.SUT, r2 - self.SLT@u1, permc_spec="NATURAL")

        return np.r_[u0 + self.B.transpose()@u1, -u1]
예제 #6
0
    def solve(self):
        mesh = self.mesh
        NE = mesh.number_of_edges()
        NC = mesh.number_of_cells()
        itype = mesh.itype
        ftype = mesh.ftype

        A = self.get_left_matrix()
        b = self.get_right_vector()

        x = np.r_[self.uh, self.ph]  #把self.uh,self.ph组合在一起
        b = b - A @ x

        # Modify matrix
        bdIdx = np.zeros((A.shape[0], ), dtype=itype)
        bdIdx[NE] = 1

        Tbd = spdiags(bdIdx, 0, A.shape[0], A.shape[1])
        T = spdiags(1 - bdIdx, 0, A.shape[0], A.shape[1])
        AD = T @ A @ T + Tbd
        scipy.sparse.save_npz('AD.npz', AD)

        b[NE] = self.ph[0]
        with open("b.csv", "w", newline="") as datacsv:
            csvwriter = csv.writer(datacsv, dialect=("excel"))
            csvwriter.writerow(['b'])
            csvwriter.writerows([b])

        # solve

        x[:] = spsolve(AD, b)

        # solve
        from mumps import DMumpsContext
        ctx = DMumpsContext()
        if ctx.myid == 0:
            ctx.set_centralized_sparse(AD.tocoo())
            x = b.copy()
            ctx.set_rhs(x)
        ctx.set_silent()
        ctx.run(job=6)

        self.uh[:] = x[:NE]
        self.ph[:] = x[NE:]
        print('ph', self.ph)
        print('pI', self.pI)

        return x
예제 #7
0
    def solve(self):
        tgdof = self.tensorspace.number_of_global_dofs()
        vgdof = self.vectorspace.number_of_global_dofs()
        gdof = tgdof + vgdof

        start = timer()
        M, B = self.get_left_matrix()
        b = self.get_right_vector()
        A = bmat([[M, B.transpose()], [B, None]]).tocsr()
        bb = np.r_[np.zeros(tgdof), b]
        end = timer()
        print("Construct linear system time:", end - start)

        start = timer()
        x = spsolve(A, bb)
        end = timer()
        print("Solve time:", end-start)
        self.sh[:] = x[0:tgdof]
        self.uh[:] = x[tgdof:]
예제 #8
0
def solve1(a, L, uh, dirichlet=None, neuman=None, solver='cg'):
    space = a.space

    start = timer()
    A = a.get_matrix()
    b = L.get_vector()
    end = timer()

    print("Construct linear system time:", end - start)

    if neuman is not None:
        b += neuman.get_vector()

    if dirichlet is not None:
        AD, b = dirichlet.apply(A, b)
    else:
        AD = A


#    print("The condtion number is: ", np.linalg.cond(AD.todense()))
    if solver is 'cg':
        start = timer()
        D = AD.diagonal()
        M = spdiags(1 / D, 0, AD.shape[0], AD.shape[1])
        uh[:], info = cg(AD, b, tol=1e-14, M=M)
        end = timer()
        print(info)
    elif solver is 'amg':
        start = timer()
        ml = pyamg.ruge_stuben_solver(AD)
        uh[:] = ml.solve(b, tol=1e-12, accel='cg').reshape((-1, ))
        end = timer()
        print(ml)
    elif solver is 'direct':
        start = timer()
        uh[:] = spsolve(AD, b)
        end = timer()
    else:
        print("We don't support solver: " + solver)

    print("Solve time:", end - start)

    return A
예제 #9
0
    def solve(self):
        mesh = self.mesh
        NE = mesh.number_of_edges()
        NC = mesh.number_of_cells()
        itype = mesh.itype
        ftype = mesh.ftype

        A = self.get_left_matrix()
        b = self.get_right_vector()

        x = np.r_[self.uh, self.ph]  #把self.uh,self.ph组合在一起
        b = b - A @ x

        # Modify matrix
        bdIdx = np.zeros((A.shape[0], ), dtype=itype)
        bdIdx[NE] = 1

        Tbd = spdiags(bdIdx, 0, A.shape[0], A.shape[1])
        T = spdiags(1 - bdIdx, 0, A.shape[0], A.shape[1])
        AD = T @ A @ T + Tbd

        b[NE] = self.ph[0]
        K = AD.todense()
        # solve

        x[:] = spsolve(AD, b)

        # solve
        from mumps import DMumpsContext
        ctx = DMumpsContext()
        if ctx.myid == 0:
            ctx.set_centralized_sparse(AD.tocoo())
            x = b.copy()
            ctx.set_rhs(x)
        ctx.set_silent()
        ctx.run(job=6)

        self.uh[:] = x[:NE]
        self.ph[:] = x[NE:]
        print('ph', self.ph)
        print('pI', self.pI)

        return x
예제 #10
0
def solve(dmodel, uh, dirichlet=None, solver='direct'):
    space = uh.space
    start = timer()
    A = dmodel.get_left_matrix()
    b = dmodel.get_right_vector()
    end = timer()

    print("Construct linear system time:", end - start)

    if dirichlet is not None:
        AD, b = dirichlet.apply(A, b)
    else:
        AD = A

    if solver is 'cg':
        start = timer()
        D = AD.diagonal()
        M = spdiags(1 / D, 0, AD.shape[0], AD.shape[1])
        uh[:], info = cg(AD, b, tol=1e-14, M=M)
        end = timer()
        print(info)
    elif solver is 'amg':
        start = timer()
        ml = pyamg.ruge_stuben_solver(AD)
        uh[:] = ml.solve(b, tol=1e-12, accel='cg').reshape(-1)
        end = timer()
        print(ml)
    elif solver is 'direct':
        start = timer()
        uh[:] = spsolve(AD, b)
        end = timer()
    else:
        raise ValueError("We don't support solver `{}`! ".format(solver))

    print("Solve time:", end - start)

    return AD, b