示例#1
0
    def get_costate_current_right_vector(self, sq, nt):
        '''
        sq: (NE, 1) n 到 N 时间层的累加
        nt: 正序的 n-1 个时间层的值, 则逆序所对应的时间层为 NL - nt -1
        NL: 时间方向剖分的总的层数
        '''
        dt = self.timeline.current_time_step_length()
        NL = self.timeline.number_of_time_levels()

        #  f1 = -\sum_{i=1}^n-1\Delta t (q^i, v)
        f1 = -sq

        # f2 = (\tilde p^n_h - \tilde p^n_d, v)
        b = self.uspace.source_vector(
            cartesian(lambda x: self.pde.tpd(x, (NL - nt - 1) * dt)))
        f2 = self.A @ self.tph[:, NL - nt - 1] - b

        # f3 = \Delta t(y^n_h - y^n_d, w) + (z^n_h, w)
        bb0 = self.pspace.source_vector(
            cartesian(lambda x: self.pde.yd(x, (NL - nt - 1) * dt)))
        bb1 = self.M @ self.zh[:, NL - nt - 1]
        bb2 = dt * self.M @ self.yh[:, NL - nt - 1] - dt * bb0
        f3 = bb1 + bb2

        return np.r_[f1, f2, f3]
示例#2
0
    def __init__(self, pde, mesh, timeline):
        self.pde = pde
        self.mesh = mesh

        self.uspace = RaviartThomasFiniteElementSpace2d(mesh, p=0)
        self.pspace = self.uspace.smspace

        self.timeline = timeline
        NL = timeline.number_of_time_levels()

        # state variable
        self.yh = self.pspace.function(dim=NL)
        self.uh = self.pspace.function(dim=NL)
        self.tph = self.uspace.function(dim=NL)
        self.ph = self.uspace.function()

        f = cartesian(lambda p: pde.y_solution(p, 0))
        self.yh[:, 0] = self.pspace.local_projection(f)

        # costate variable
        self.zh = self.pspace.function(dim=NL)
        self.tqh = self.uspace.function(dim=NL)
        self.qh = self.uspace.function()

        self.A = self.uspace.stiff_matrix()  # RT 质量矩阵
        self.D = self.uspace.div_matrix()  # (p, \div v)
        self.M = self.pspace.mass_matrix()
示例#3
0
    def __init__(self, pde, timeline, n=1):
        self.pde = pde
        box = pde.domain()
        mf = MeshFactory()
        self.mesh = mf.boxmesh2d(box, nx=n, ny=n, meshtype='tri')

        self.uspace = RaviartThomasFiniteElementSpace2d(self.mesh, p=0)
        self.pspace = self.uspace.smspace

        self.timeline = timeline
        NL = timeline.number_of_time_levels()

        # state variable
        self.yh = self.pspace.function(dim=NL)
        self.uh = self.pspace.function(dim=NL)
        self.tph = self.uspace.function(dim=NL)
        self.ph = self.uspace.function()
        bc = self.mesh.entity_barycenter('cell')

        f = cartesian(lambda p: pde.y_solution(p, 0))
        self.yh[:, 0] = self.pspace.local_projection(f)

        # costate variable
        self.zh = self.pspace.function(dim=NL)
        self.tqh = self.uspace.function(dim=NL)
        self.qh = self.uspace.function()

        self.A = self.uspace.stiff_matrix()  # RT 质量矩阵
        self.D = self.uspace.div_matrix()  # (p, \div v)
        self.M = self.pspace.mass_matrix()
示例#4
0
    def L2error(self):
        dt = self.timeline.current_time_step_length()
        NL = self.timeline.number_of_time_levels()
        T = dt * (NL - 1)

        pL2error = self.uspace.integralalg.error(cartesian(lambda x: \
                self.pde.p_solution(x, T)), barycentric(self.ph))
        print('pL2error', pL2error)

        tpL2error = self.uspace.integralalg.error(cartesian(lambda x: \
                self.pde.tp_solution(x, T)), \
                barycentric(self.uspace.function(array=self.tph[:, NL-1])))
        print('tpL2error', tpL2error)

        uL2error = self.pspace.integralalg.error(
            cartesian(lambda x: self.pde.u_solution(x, T)),
            cartesian(self.pspace.function(array=self.uh[:, NL - 1])))
        print('uerror', uL2error)

        yL2error = self.pspace.integralalg.error(
            cartesian(lambda x: self.pde.y_solution(x, T)),
            cartesian(self.pspace.function(array=self.yh[:, NL - 1])))
        print('yerror', yL2error)

        qL2error = self.uspace.integralalg.error(cartesian(lambda x: \
                self.pde.q_solution(x, T)), barycentric(self.qh))
        print('qL2error', qL2error)
        tqL2error = self.uspace.integralalg.error(cartesian(lambda x: \
                self.pde.tq(x, T, T)), \
                barycentric(self.uspace.function(array=self.tqh[:, NL-1])))
        print('tqL2error', tqL2error)

        zL2error = self.pspace.integralalg.error(
            cartesian(lambda x: self.pde.z_solution(x, T)),
            cartesian(self.pspace.function(array=self.zh[:, NL - 1])))
        print('zerror', zL2error)

        return pL2error
示例#5
0
    def get_state_current_right_vector(self, sp, nt):
        '''
        sp: (NE, 1), 前 n-1 层的累加
        nt: 表示 n-1 时间层,要求的是 n 个时间层的方程
        '''
        dt = self.timeline.current_time_step_length()
        u = self.uh[:, nt + 1]
        NE = self.mesh.number_of_edges()
        # f1 = -\sum_{i=1}^n-1\Delta t (p^i, v^i)
        f1 = -sp

        # f2 = 0
        f2 = np.zeros(NE, dtype=self.mesh.ftype)

        # f3 = \Delta t(f^n + u^n, w_h) + (y^{n-1}, w_h)
        b = self.pspace.source_vector(
            cartesian(lambda x: self.pde.source(x, (nt + 1) * dt)))

        f3 = dt * b + dt * self.M @ u + self.M @ self.yh[:, nt]

        return np.r_[f1, f2, f3]
示例#6
0
    def costate_solve(self):
        timeline = self.timeline
        dt = timeline.current_time_step_length()
        NL = timeline.number_of_time_levels()
        NE = self.mesh.number_of_edges()
        cellmeasure = self.mesh.entity_measure('cell')
        sq = np.zeros(NE, dtype=self.mesh.ftype)
        zh1 = self.pspace.function()

        timeline.reset()
        while not timeline.stop():
            QZ = self.costate_one_step_solve(timeline.current, sq)
            self.tqh[:, NL - timeline.current - 2] = QZ[:NE]
            self.qh[:] = QZ[NE:2 * NE]
            self.zh[:, NL - timeline.current - 2] = QZ[2 * NE:]
            zh1[:] = self.zh[:, NL - timeline.current - 2]
            e = self.pspace.integralalg.cell_integral(cartesian(zh1))
            self.uh[:, NL-timeline.current-1] = max(0, np.sum(e)/np.sum(cellmeasure)) \
                            - self.zh[:, NL - timeline.current-2]
            timeline.current += 1
            sq = sq + dt * self.A @ self.qh
        timeline.reset()
        return sq