Beispiel #1
0
    def alg_3_4(self, maxit=None):
        """
        1. 最粗网格上求解最小特征特征值问题,得到最小特征值 d_H 和特征向量 u_H
        2. 自适应求解  - \Delta u_h = u_H
            *  u_H 插值到下一层网格上做为新 u_H
        3. 最新网格层上求出的 uh 做为一个基函数,加入到最粗网格的有限元空间中,
           求解最小特征值问题。

        自适应 maxit, picard:2
        """
        print("算法 3.4")
        if maxit is None:
            maxit = self.maxit

        start = timer()
        if self.step == 0:
            idx = []
        else:
            idx = list(range(0, self.maxit, self.step)) + [self.maxit - 1]

        mesh = self.pde.init_mesh(n=self.numrefine)
        integrator = mesh.integrator(self.q)

        # 1. 粗网格上求解最小特征值问题
        space = LagrangeFiniteElementSpace(mesh, 1)
        AH = self.get_stiff_matrix(space)
        MH = self.get_mass_matrix(space)
        isFreeHDof = ~(space.boundary_dof())

        gdof = space.number_of_global_dofs()
        print("initial mesh :", gdof)

        uH = np.zeros(gdof, dtype=np.float)

        A = AH[isFreeHDof, :][:, isFreeHDof].tocsr()
        M = MH[isFreeHDof, :][:, isFreeHDof].tocsr()

        if self.matlab is False:
            uH[isFreeHDof], d = self.eig(A, M)
        else:
            uH[isFreeHDof], d = self.meigs(A, M)

        uh = space.function()
        uh[:] = uH

        GD = mesh.geo_dimension()
        if (self.step > 0) and (0 in idx):
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_4_0_' + str(NN) + '.pdf')
            plt.close()
            self.savemesh(mesh,
                          self.resultdir + 'mesh_3_4_0_' + str(NN) + '.mat')

        # 2. 以 u_H 为右端项自适应求解 -\Deta u = u_H
        I = eye(gdof)
        final = 0
        for i in range(maxit):
            eta = self.residual_estimate(uh)
            markedCell = mark(eta, self.theta)
            IM = mesh.bisect(markedCell, returnim=True)
            print(i + 1, "refine :", mesh.number_of_nodes())
            if (self.step > 0) and (i in idx):
                NN = mesh.number_of_nodes()
                fig = plt.figure()
                fig.set_facecolor('white')
                if GD == 2:
                    axes = fig.gca()
                else:
                    axes = Axes3D(fig)
                mesh.add_plot(axes, cellcolor='w')
                fig.savefig(self.resultdir + 'mesh_3_4_' + str(i + 1) + '_' +
                            str(NN) + '.pdf')
                plt.close()
                self.savemesh(
                    mesh, self.resultdir + 'mesh_3_4_' + str(i + 1) + '_' +
                    str(NN) + '.mat')

            I = IM @ I
            uH = IM @ uH

            space = LagrangeFiniteElementSpace(mesh, 1)
            gdof = space.number_of_global_dofs()

            A = self.get_stiff_matrix(space)
            M = self.get_mass_matrix(space)
            isFreeDof = ~(space.boundary_dof())
            b = M @ uH

            uh = space.function()
            if self.matlab is False:
                uh[isFreeDof] = self.psolve(
                    A[isFreeDof, :][:, isFreeDof].tocsr(), b[isFreeDof],
                    M[isFreeDof, :][:, isFreeDof].tocsr())
            else:
                uh[isFreeDof] = self.msolve(
                    A[isFreeDof, :][:, isFreeDof].tocsr(), b[isFreeDof])
            final = i + 1
            if gdof > self.maxdof:
                break

        if self.step > 0:
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_4_' + str(final) + '_' +
                        str(NN) + '.pdf')
            plt.close()
            self.savemesh(
                mesh, self.resultdir + 'mesh_3_4_' + str(final) + '_' +
                str(NN) + '.mat')

        # 3. 把 uh 加入粗网格空间, 组装刚度和质量矩阵
        w0 = uh @ A
        w1 = w0 @ uh
        w2 = w0 @ I
        AA = bmat([[AH, w2.reshape(-1, 1)], [w2, w1]], format='csr')

        w0 = uh @ M
        w1 = w0 @ uh
        w2 = w0 @ I
        MM = bmat([[MH, w2.reshape(-1, 1)], [w2, w1]], format='csr')

        isFreeDof = np.r_[isFreeHDof, True]

        u = np.zeros(len(isFreeDof))

        ## 求解特征值
        A = AA[isFreeDof, :][:, isFreeDof].tocsr()
        M = MM[isFreeDof, :][:, isFreeDof].tocsr()

        if self.multieigs is True:
            self.A = A
            self.M = M
            self.ml = pyamg.ruge_stuben_solver(self.A)
            self.eigs()
        else:
            if self.matlab is False:
                u[isFreeDof], d = self.eig(A, M)
            else:
                u[isFreeDof], d = self.meigs(A, M)
            print("smallest eigns:", d)
            uh *= u[-1]
            uh += I @ u[:-1]

            uh /= np.max(np.abs(uh))
            uh = space.function(array=uh)
            return uh

        end = timer()
        print("with time: ", end - start)
Beispiel #2
0
    def alg_3_3(self, maxit=None):
        """
        1. 最粗网格上求解最小特征特征值问题,得到最小特征值 d_H 和特征向量 u_H
        2. 自适应求解  - \Delta u_h = u_H
            *  u_H 插值到下一层网格上做为新 u_H
        3. 在最细网格上求解一次最小特征值问题

        自适应 maxit, picard:2
        """
        print("算法 3.3")

        if maxit is None:
            maxit = self.maxit

        start = timer()

        if self.step == 0:
            idx = []
        else:
            idx = list(range(0, self.maxit, self.step))

        mesh = self.pde.init_mesh(n=self.numrefine)
        # 1. 粗网格上求解最小特征值问题
        space = LagrangeFiniteElementSpace(mesh, 1)
        AH = self.get_stiff_matrix(space)
        MH = self.get_mass_matrix(space)
        isFreeHDof = ~(space.boundary_dof())

        gdof = space.number_of_global_dofs()
        uH = np.zeros(gdof, dtype=mesh.ftype)
        print("initial mesh :", gdof)

        A = AH[isFreeHDof, :][:, isFreeHDof].tocsr()
        M = MH[isFreeHDof, :][:, isFreeHDof].tocsr()
        if self.matlab is False:
            uH[isFreeHDof], d = self.eig(A, M)
        else:
            uH[isFreeHDof], d = self.meigs(A, M)

        uh = space.function()
        uh[:] = uH

        GD = mesh.geo_dimension()
        if (self.step > 0) and (0 in idx):
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_3_0_' + str(NN) + '.pdf')
            plt.close()
            self.savemesh(mesh,
                          self.resultdir + 'mesh_3_3_0_' + str(NN) + '.mat')

        # 2. 以 u_H 为右端项自适应求解 -\Deta u = u_H
        I = eye(gdof)
        final = 0
        for i in range(maxit - 1):
            eta = self.residual_estimate(uh)
            markedCell = mark(eta, self.theta)
            IM = mesh.bisect(markedCell, returnim=True)
            NN = mesh.number_of_nodes()
            print(i + 1, "refine : ", NN)
            if (self.step > 0) and (i in idx):
                NN = mesh.number_of_nodes()
                fig = plt.figure()
                fig.set_facecolor('white')
                if GD == 2:
                    axes = fig.gca()
                else:
                    axes = Axes3D(fig)
                mesh.add_plot(axes, cellcolor='w')
                fig.savefig(self.resultdir + 'mesh_3_3_' + str(i + 1) + '_' +
                            str(NN) + '.pdf')
                plt.close()
                self.savemesh(
                    mesh, self.resultdir + 'mesh_3_3_' + str(i + 1) + '_' +
                    str(NN) + '.mat')
            final = i + 1
            if NN > self.maxdof:
                break

            I = IM @ I
            uH = IM @ uH

            space = LagrangeFiniteElementSpace(mesh, 1)
            gdof = space.number_of_global_dofs()

            A = self.get_stiff_matrix(space)
            M = self.get_mass_matrix(space)
            isFreeDof = ~(space.boundary_dof())
            b = M @ uH

            uh = space.function()
            if self.matlab is False:
                uh[isFreeDof] = self.psolve(
                    A[isFreeDof, :][:, isFreeDof].tocsr(), b[isFreeDof],
                    M[isFreeDof, :][:, isFreeDof].tocsr())
            else:
                uh[isFreeDof] = self.msolve(
                    A[isFreeDof, :][:, isFreeDof].tocsr(), b[isFreeDof])

        # 3. 在最细网格上求解一次最小特征值问题

        if self.step > 0:
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_3_' + str(final) + '_' +
                        str(NN) + '.pdf')
            plt.close()
            self.savemesh(
                mesh, self.resultdir + 'mesh_3_3_' + str(final) + '_' +
                str(NN) + '.mat')

        space = LagrangeFiniteElementSpace(mesh, 1)
        gdof = space.number_of_global_dofs()
        A = self.get_stiff_matrix(space)
        M = self.get_mass_matrix(space)
        isFreeDof = ~(space.boundary_dof())
        uh = space.function(array=uh)
        A = A[isFreeDof, :][:, isFreeDof].tocsr()
        M = M[isFreeDof, :][:, isFreeDof].tocsr()
        uh = space.function()

        if self.multieigs is True:
            self.A = A
            self.M = M
            self.ml = pyamg.ruge_stuben_solver(self.A)
            self.eigs()
        else:
            if self.matlab is False:
                uh[isFreeDof], d = self.eig(A, M)
            else:
                uh[isFreeDof], d = self.meigs(A, M)
            print("smallest eigns:", d)
            return uh
        end = timer()
        print("with time: ", end - start)
Beispiel #3
0
    def alg_3_1(self, maxit=None):
        """
        1. 自适应在每层网格上求解最小特征值问题

        refine: maxit, picard: maxit + 1
        """
        print("算法 3.1")

        if maxit is None:
            maxit = self.maxit

        start = timer()
        if self.step == 0:
            idx = []
        else:
            idx = list(range(0, self.maxit, self.step)) + [self.maxit - 1]

        mesh = self.pde.init_mesh(n=self.numrefine)
        GD = mesh.geo_dimension()
        if (self.step > 0) and (0 in idx):
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_1_0_' + str(NN) + '.pdf')
            plt.close()
            self.savemesh(mesh,
                          self.resultdir + 'mesh_3_1_0_' + str(NN) + '.mat')

        space = LagrangeFiniteElementSpace(mesh, 1)
        isFreeDof = ~(space.boundary_dof())
        gdof = space.number_of_global_dofs()
        uh = np.ones(gdof, dtype=mesh.ftype)
        uh[~isFreeDof] = 0
        IM = eye(gdof)
        for i in range(maxit + 1):
            area = mesh.entity_measure('cell')
            A = self.get_stiff_matrix(space)
            M = self.get_mass_matrix(space)
            uh = IM @ uh
            A = A[isFreeDof, :][:, isFreeDof].tocsr()
            M = M[isFreeDof, :][:, isFreeDof].tocsr()

            if self.matlab is False:
                uh[isFreeDof], d = self.eig(A, M)
            else:
                uh[isFreeDof], d = self.meigs(A, M)

            if i < maxit:
                uh = space.function(array=uh)
                eta = self.residual_estimate(uh)
                markedCell = mark(eta, self.theta)
                IM = mesh.bisect(markedCell, returnim=True)
                print(i + 1, "refine: ", mesh.number_of_nodes())

                if (self.step > 0) and (i in idx):
                    NN = mesh.number_of_nodes()
                    fig = plt.figure()
                    fig.set_facecolor('white')
                    if GD == 2:
                        axes = fig.gca()
                    else:
                        axes = Axes3D(fig)
                    mesh.add_plot(axes, cellcolor='w')
                    fig.savefig(self.resultdir + 'mesh_3_1_' + str(i + 1) +
                                '_' + str(NN) + '.pdf')
                    plt.close()
                    self.savemesh(
                        mesh, self.resultdir + 'mesh_3_1_' + str(i + 1) + '_' +
                        str(NN) + '.mat')

                space = LagrangeFiniteElementSpace(mesh, 1)
                isFreeDof = ~(space.boundary_dof())
                gdof = space.number_of_global_dofs()
            if gdof > self.maxdof:
                break

        if self.step > 0:
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_1_' + str(i + 1) + '_' +
                        str(NN) + '.pdf')
            plt.close()
            self.savemesh(
                mesh, self.resultdir + 'mesh_3_1_' + str(i + 1) + '_' +
                str(NN) + '.mat')

        if self.multieigs is True:
            self.A = A
            self.M = M
            self.ml = pyamg.ruge_stuben_solver(self.A)
            self.eigs()

        end = timer()
        print("smallest eigns:", d, "with time: ", end - start)

        uh = space.function(array=uh)
        return uh
Beispiel #4
0
    def alg_3_2(self, maxit=None):
        """
        1. 自适应求解 -\Delta u = 1。
        1. 在最细网格上求最小特征值和特征向量。

        refine maxit, picard: 1
        """
        print("算法 3.2")
        if maxit is None:
            maxit = self.maxit

        start = timer()
        if self.step == 0:
            idx = []
        else:
            idx = list(range(0, self.maxit, self.step)) + [self.maxit - 1]

        mesh = self.pde.init_mesh(n=self.numrefine)
        GD = mesh.geo_dimension()
        if (self.step > 0) and (0 in idx):
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_2_0_' + str(NN) + '.pdf')
            plt.close()
            self.savemesh(mesh,
                          self.resultdir + 'mesh_3_2_0_' + str(NN) + '.mat')

        final = 0
        integrator = mesh.integrator(self.q)
        for i in range(maxit):
            space = LagrangeFiniteElementSpace(mesh, 1)
            gdof = space.number_of_global_dofs()

            A = self.get_stiff_matrix(space)
            M = self.get_mass_matrix(space)
            b = M @ np.ones(gdof)

            isFreeDof = ~(space.boundary_dof())
            A = A[isFreeDof, :][:, isFreeDof].tocsr()
            M = M[isFreeDof, :][:, isFreeDof].tocsr()

            uh = space.function()
            if self.matlab is False:
                uh[isFreeDof] = self.psolve(A, b[isFreeDof], M)
            else:
                uh[isFreeDof] = self.msolve(A, b[isFreeDof])

            eta = self.residual_estimate(uh)
            markedCell = mark(eta, self.theta)
            IM = mesh.bisect(markedCell, returnim=True)
            NN = mesh.number_of_nodes()
            print(i + 1, "refine :", NN)
            if (self.step > 0) and (i in idx):
                fig = plt.figure()
                fig.set_facecolor('white')
                if GD == 2:
                    axes = fig.gca()
                else:
                    axes = Axes3D(fig)
                mesh.add_plot(axes, cellcolor='w')
                fig.savefig(self.resultdir + 'mesh_3_2_' + str(i + 1) + '_' +
                            str(NN) + '.pdf')
                plt.close()
                self.savemesh(
                    mesh, self.resultdir + 'mesh_3_2_' + str(i + 1) + '_' +
                    str(NN) + '.mat')
            final = i + 1
            if NN > self.maxdof:
                break

        if self.step > 0:
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_3_2_' + str(final) + '_' +
                        str(NN) + '.pdf')
            plt.close()
            self.savemesh(
                mesh, self.resultdir + 'mesh_3_2_' + str(final) + '_' +
                str(NN) + '.mat')

        space = LagrangeFiniteElementSpace(mesh, 1)
        gdof = space.number_of_global_dofs()

        A = self.get_stiff_matrix(space)
        M = self.get_mass_matrix(space)
        isFreeDof = ~(space.boundary_dof())
        A = A[isFreeDof, :][:, isFreeDof].tocsr()
        M = M[isFreeDof, :][:, isFreeDof].tocsr()

        if self.multieigs is True:
            self.A = A
            self.M = M
            self.ml = pyamg.ruge_stuben_solver(self.A)
            self.eigs()
        else:
            uh = IM @ uh
            if self.matlab is False:
                uh[isFreeDof], d = self.eig(A, M)
            else:
                uh[isFreeDof], d = self.meigs(A, M)
            print("smallest eigns:", d)
            return space.function(array=uh)
        end = timer()
        print("with time: ", end - start)
Beispiel #5
0
    def alg_0(self, maxit=None):
        """
        1. 最粗网格上求解最小特征特征值问题,得到最小特征值 d_H 和特征向量 u_H
        2. 自适应求解  - \Delta u_h = d_H*u_H
            *  每层网格上求出的 u_h,插值到下一层网格上做为 u_H
            *  并更新 d_H = u_h@A@u_h/u_h@M@u_h, 其中 A 是当前网格层上的刚度矩
               阵,M 为当前网格层的质量矩阵。

        自适应 maxit, picard: 1
        """
        print("算法 0")
        if maxit is None:
            maxit = self.maxit

        start = timer()
        if self.step == 0:
            idx = []
        else:
            idx = list(range(0, self.maxit, self.step)) + [self.maxit - 1]

        mesh = self.pde.init_mesh(n=self.numrefine)

        # 1. 粗网格上求解最小特征值问题
        space = LagrangeFiniteElementSpace(mesh, 1)
        gdof = space.number_of_global_dofs()
        print("initial mesh:", gdof)
        uh = np.zeros(gdof, dtype=np.float)
        AH = self.get_stiff_matrix(space)
        MH = self.get_mass_matrix(space)
        isFreeHDof = ~(space.boundary_dof())
        A = AH[isFreeHDof, :][:, isFreeHDof].tocsr()
        M = MH[isFreeHDof, :][:, isFreeHDof].tocsr()

        if self.picard is True:
            uh[isFreeHDof], d = picard(A,
                                       M,
                                       np.ones(sum(isFreeHDof)),
                                       sigma=self.sigma)
        else:
            uh[isFreeHDof], d = self.eig(A, M)

        GD = mesh.geo_dimension()
        if (self.step > 0) and (0 in idx):
            NN = mesh.number_of_nodes()
            fig = plt.figure()
            fig.set_facecolor('white')
            if GD == 2:
                axes = fig.gca()
            else:
                axes = Axes3D(fig)
            mesh.add_plot(axes, cellcolor='w')
            fig.savefig(self.resultdir + 'mesh_0_0_' + str(NN) + '.pdf')
            plt.close()
            self.savemesh(mesh,
                          self.resultdir + 'mesh_0_0_' + str(NN) + '.mat')

        # 2. 以 u_h 为右端项自适应求解 -\Deta u = d*u_h
        I = eye(gdof)
        for i in range(maxit):
            uh = space.function(array=uh)
            eta = self.residual_estimate(uh)
            markedCell = mark(eta, self.theta)
            IM = mesh.bisect(markedCell, returnim=True)
            print(i + 1, "refine: ", mesh.number_of_nodes())
            if (self.step > 0) and (i in idx):
                NN = mesh.number_of_nodes()
                fig = plt.figure()
                fig.set_facecolor('white')
                if GD == 2:
                    axes = fig.gca()
                else:
                    axes = Axes3D(fig)
                mesh.add_plot(axes, cellcolor='w')
                fig.savefig(self.resultdir + 'mesh_0_' + str(i + 1) + '_' +
                            str(NN) + '.pdf')
                plt.close()
                self.savemesh(
                    mesh, self.resultdir + 'mesh_0_' + str(i + 1) + '_' +
                    str(NN) + '.mat')

            I = IM @ I
            uh = IM @ uh
            space = LagrangeFiniteElementSpace(mesh, 1)
            gdof = space.number_of_global_dofs()
            A = self.get_stiff_matrix(space)
            M = self.get_mass_matrix(space)
            isFreeDof = ~(space.boundary_dof())
            b = d * M @ uh
            if self.sigma is None:
                ml = pyamg.ruge_stuben_solver(
                    A[isFreeDof, :][:, isFreeDof].tocsr())
                uh[isFreeDof] = ml.solve(b[isFreeDof],
                                         x0=uh[isFreeDof],
                                         tol=1e-12,
                                         accel='cg').reshape((-1, ))
            else:
                K = A[isFreeDof, :][:, isFreeDof].tocsr(
                ) + self.sigma * M[isFreeDof, :][:, isFreeDof].tocsr()
                b += self.sigma * M @ uh
                ml = pyamg.ruge_stuben_solver(K)
                uh[isFreeDof] = ml.solve(b[isFreeDof],
                                         x0=uh[isFreeDof],
                                         tol=1e-12,
                                         accel='cg').reshape(-1)
                # uh[isFreeDof] = spsolve(A[isFreeDof, :][:, isFreeDof].tocsr(), b[isFreeDof])
            d = uh @ A @ uh / (uh @ M @ uh)

            if gdof > self.maxdof:
                break

        if self.multieigs is True:
            self.A = A[isFreeDof, :][:, isFreeDof].tocsr()
            self.M = M[isFreeDof, :][:, isFreeDof].tocsr()
            self.ml = pyamg.ruge_stuben_solver(self.A)
            self.eigs()

        end = timer()
        print("smallest eigns:", d, "with time: ", end - start)

        uh = space.function(array=uh)
        return uh