示例#1
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()
示例#2
0
    def __init__(self, pde, mesh, timeline):
        self.pde = pde
        self.mesh = mesh
        NC = mesh.number_of_cells()
        self.integrator = mesh.integrator(3, 'cell')
        self.bc = mesh.entity_barycenter('cell')
        self.ec = mesh.entity_barycenter('edge')
        self.cellmeasure = mesh.entity_measure('cell')
        self.uspace = RaviartThomasFiniteElementSpace2d(mesh, p=0)
        self.pspace = self.uspace.smspace

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

        # 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()
        self.yh[:, 0] = pde.y_solution(self.bc, 0)

        # 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()  # TODO: 确定符号, 符号为正
        data = self.cellmeasure * np.ones(NC, )
        self.M = spdiags(data, 0, NC, NC)
示例#3
0
    def __init__(self,
                 vdata,
                 cdata,
                 mesh,
                 timeline,
                 p=0,
                 options={'rdir': '/home/why/result'}):

        self.options = options
        self.vdata = vdata
        self.cdata = cdata
        self.mesh = mesh
        self.timeline = timeline
        self.uspace = RaviartThomasFiniteElementSpace2d(mesh, p=p)
        self.cspace = ScaledMonomialSpace2d(mesh, p=p + 1)

        self.uh = self.uspace.function()  # 速度场自由度数组
        self.ph = self.uspace.smspace.function()  # 压力场自由度数组
        self.ch = self.cspace.function()  # 浓度场自由度数组

        # 初始浓度场设为 1
        ldof = self.cspace.number_of_local_dofs()
        self.ch[0::ldof] = 1.0

        self.M = self.cspace.cell_mass_matrix()
        self.H = inv(self.M)
        self.set_init_velocity_field()  # 计算初始的速度场和压力场

        # vtk 文件输出
        node, cell, cellType, NC = self.mesh.to_vtk()
        self.points = vtk.vtkPoints()
        self.points.SetData(vnp.numpy_to_vtk(node))
        self.cells = vtk.vtkCellArray()
        self.cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell))
        self.cellType = cellType
示例#4
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()
示例#5
0
文件: Model1.py 项目: zweien/fealpy
    def __init__(self):
        self.domain = [0, 50, 0, 50]
        self.mesh = MeshFactory().regular(self.domain, n=50)
        self.timeline = UniformTimeLine(0, 1, 100)
        self.space0 = RaviartThomasFiniteElementSpace2d(self.mesh, p=0)
        self.space1 = ScaledMonomialSpace2d(self.mesh, p=1)  # 线性间断有限元空间

        self.vh = self.space0.function()  # 速度
        self.ph = self.space0.smspace.function()  # 压力
        self.ch = self.space1.function(dim=3)  # 三个组分的摩尔密度
        self.options = {
            'viscosity': 1.0,
            'permeability': 1.0,
            'temperature': 397,
            'pressure': 50,
            'porosity': 0.2,
            'injecttion_rate': 0.1,
            'compressibility': (0.001, 0.001, 0.001),
            'pmv': (1.0, 1.0, 1.0),
            'dt': self.timeline.dt
        }

        c = self.options['viscosity'] / self.options['permeability']
        self.A = c * self.space0.mass_matrix()
        self.B = self.space0.div_matrix()

        phi = self.options['porosity']
        self.M = phi / dt * self.space0.smspace.mass_matrix()  #
        self.MC = self.space1.cell_mass_matrix() / dt
示例#6
0
    def mesh_with_fracture(self, plot=True):

        box = [0, 1, 0, 1]
        mesh = self.mf.boxmesh2d(box, nx=10, ny=10, meshtype='tri')

        def is_fracture(p):
            x = p[..., 0]
            y = p[..., 1]
            flag0 = (x == 0.5) & (y > 0.2) & (y < 0.8)
            flag1 = (y == 0.5) & (x > 0.2) & (x < 0.8)
            return flag0 | flag1

        bc = mesh.entity_barycenter('edge')
        isFEdge = is_fracture(bc)
        mesh.edgedata['fracture'] = isFEdge
        NE = mesh.number_of_edges()
        print('边的个数:', NE)

        space = RaviartThomasFiniteElementSpace2d(mesh, p=0)
        gdof = space.number_of_global_dofs()
        print('gdof:', gdof)

        if plot:
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes)
            mesh.find_edge(axes, index=isFEdge, color='r')
            plt.show()
示例#7
0
 def show_basis(self):
     h = 0.5
     box = [-h, 1+h, -h, np.sqrt(3)/2+h]
     mesh = self.meshfactory.one_triangle_mesh('equ')
     space = RaviartThomasFiniteElementSpace2d(mesh, p=2, q=2)
     fig = plt.figure()
     space.show_basis(fig, box=box)
     plt.show()
示例#8
0
    def show_basis(self, p=0):
        h = 0.5
        box = [-h, 1 + h, -h, 1 + h]

        node = np.array([[0.0, 0.0], [1.0, 0.0], [1.0, 1.0], [0.0, 1.0]],
                        dtype=np.float)
        cell = np.array([[1, 2, 0]], dtype=np.int)
        mesh = TriangleMesh(node, cell)
        space = RaviartThomasFiniteElementSpace2d(mesh, p=p)
        fig = plt.figure()
        space.show_basis(fig, box=box)

        cell = np.array([[3, 0, 2]], dtype=np.int)
        mesh = TriangleMesh(node, cell)
        space = RaviartThomasFiniteElementSpace2d(mesh, p=p)
        fig = plt.figure()
        space.show_basis(fig, box=box)
        print(space.bcoefs)

        plt.show()
示例#9
0
    def __init__(self, vdata, cdata, mesh, p=0):
        self.vdata = vdata
        self.cdata = cdata
        self.mesh = mesh
        self.space = RaviartThomasFiniteElementSpace2d(mesh, p=p)

        self.uh = self.space.function() # 速度场函数
        self.ph = self.space.smspace.function() # 压力场函数
        self.ch = self.space.smspace.function() # 浓度场函数
        self.M = 0.2*self.space.smspace.cell_mass_matrix() 
        self.H = inv(self.M)
        self.set_init_velocity_field() # 计算初始的速度场和压力场
示例#10
0
文件: Model1.py 项目: ymjyxw/fealpy
    def __init__(self, model):
        self.model = model
        self.mesh = model.space_mesh()
        self.timeline = model.time_mesh(n=3650)
        self.uspace = RaviartThomasFiniteElementSpace2d(self.mesh, p=0)
        self.cspace = ScaledMonomialSpace2d(self.mesh, p=1)  # 线性间断有限元空间

        self.uh = self.uspace.function()  # 速度
        self.ph = model.init_pressure(self.uspace.smspace)  # 初始压力

        # 三个组分的摩尔密度, 三个组分一起计算
        self.ch = model.init_molar_density(self.cspace)

        # TODO:初始化三种物质的浓度
        # 1 muPa*s = 1e-11 bar*s = 1e-11*24*3600 bar*d = 8.64e-07 bar*d
        # 1 md = 9.869 233e-16 m^2
        self.options = {
            'viscosity':
            1.0,  # 粘性系数 1 muPa*s = 1e-6 Pa*s, 1 cP = 10^{−3} Pa⋅s = 1 mPa⋅s
            'permeability': 1.0,  # 1 md 渗透率, 1 md = 9.869233e-16 m^2
            'temperature': 397,  # 初始温度 K
            'pressure': 50,  # bar 初始压力
            'porosity': 0.2,  # 孔隙度
            'injecttion_rate': 0.1,  # 注入速率
            'compressibility': 0.001,  #压缩率
            'pmv': (1.0, 1.0, 1.0),  # 偏摩尔体积
            'rdir': '/home/why/result/test/',
            'step': 1
        }
        self.CM = self.cspace.cell_mass_matrix()
        self.H = inv(self.CM)

        c = 8.64 / 9.869233 * 1e+9
        self.M = c * self.uspace.mass_matrix()
        self.B = -self.uspace.div_matrix()

        dt = self.timeline.dt
        c = self.options['porosity'] * self.options['compressibility'] / dt
        self.D = c * self.uspace.smspace.mass_matrix()

        # 压力边界条件
        self.F0 = -self.uspace.set_neumann_bc(model.pressure_bc,
                                              threshold=model.is_pressure_bc)

        # vtk 文件输出
        node, cell, cellType, NC = self.mesh.to_vtk()
        self.points = vtk.vtkPoints()
        self.points.SetData(vnp.numpy_to_vtk(node))
        self.cells = vtk.vtkCellArray()
        self.cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell))
        self.cellType = cellType
示例#11
0
    def interpolation(self, n=0, p=0, plot=True):

        box = [-0.5, 1.5, -0.5, 1.5]
        pde = CosCosData()
        mesh = pde.init_mesh(n=n, meshtype='tri')
        space = RaviartThomasFiniteElementSpace2d(mesh, p=p)
        uI = space.interpolation(pde.flux)
        error = space.integralalg.L2_error(pde.flux, uI)
        print(error)
        if plot:
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes, box=box)
            plt.show()
示例#12
0
    def interpolation(self, n=0, p=0):
        pde = CosCosData()
        mesh = pde.init_mesh(n=n, meshtype='tri')
        space = RaviartThomasFiniteElementSpace2d(mesh, p=p)
        uI = space.interpolation(pde.flux)
        print(space.basis.coordtype)
        u = Function(space)
        u[:] = uI

        qf = mesh.integrator(3, 'cell')
        bcs, ws = qf.get_quadrature_points_and_weights()
        error = space.integralalg.L2_error(pde.source, u.div_value)
        print('error:', error)
        print(dir(u))
示例#13
0
    def __init__(self, model):
        self.model = model
        self.mesh = model.space_mesh()
        self.timeline = model.time_mesh()
        dt = self.timeline.current_time_step_length()
        self.space = RaviartThomasFiniteElementSpace2d(self.mesh, p=0)
        self.uh = self.space.function()
        self.ph = model.init_pressure(self.space.smspace)

        self.M = self.space.mass_matrix()
        self.B = -self.space.div_matrix()
        self.D = self.space.smspace.mass_matrix()/dt
        self.F0 = -self.space.set_neumann_bc(model.pressure_bc, threshold=model.is_pressure_bc) 

        # vtk 文件输出
        node, cell, cellType, NC = self.mesh.to_vtk()
        self.points = vtk.vtkPoints()
        self.points.SetData(vnp.numpy_to_vtk(node))
        self.cells = vtk.vtkCellArray()
        self.cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell))
        self.cellType = cellType
示例#14
0
    def edge_basis(self, plot=True):
        pde = X2Y2Data()
        mesh = pde.init_mesh(n=0, meshtype='tri')
        space = RaviartThomasFiniteElementSpace2d(mesh, p=0)
        qf = mesh.integrator(3, 'edge')
        bcs, ws = qf.get_quadrature_points_and_weights()

        index = mesh.ds.boundary_edge_index()
        ps = mesh.bc_to_point(bcs, etype='edge', index=index)
        phi = space.edge_basis(bcs, index=index)

        if plot:
            box = [-0.5, 1.5, -0.5, 1.5]
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes, box=box)
            mesh.find_node(axes, showindex=True)
            mesh.find_edge(axes, showindex=True)
            mesh.find_cell(axes, showindex=True)
            node = ps.reshape(-1, 2)
            uv = phi.reshape(-1, 2)
            axes.quiver(node[:, 0], node[:, 1], uv[:, 0], uv[:, 1])
            plt.show()
示例#15
0
文件: Model5.py 项目: ymjyxw/fealpy
    def __init__(self, model, T=800 * 3600 * 24, NS=32, NT=800 * 24):
        self.model = model
        self.mesh = model.space_mesh(n=NS)
        self.timeline = model.time_mesh(T=T, n=NT)

        self.GD = model.GD
        if self.GD == 2:
            self.vspace = RaviartThomasFiniteElementSpace2d(self.mesh,
                                                            p=0)  # 速度空间
        elif self.GD == 3:
            self.vspace = RaviartThomasFiniteElementSpace3d(self.mesh, p=0)

        self.pspace = self.vspace.smspace  # 压强和饱和度所属的空间, 分片常数
        self.cspace = LagrangeFiniteElementSpace(self.mesh, p=1)  # 位移空间

        # 上一时刻物理量的值
        self.v = self.vspace.function()  # 速度函数
        self.p = self.pspace.function()  # 压强函数
        self.s = self.pspace.function()  # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0
        self.u = self.cspace.function(dim=self.GD)  # 位移函数
        self.phi = self.pspace.function()  # 孔隙度函数, 分片常数

        # 当前时刻物理量的值, 用于保存临时计算出的值, 模型中系数的计算由当前时刻
        # 的物理量的值决定
        self.cv = self.vspace.function()  # 速度函数
        self.cp = self.pspace.function()  # 压强函数
        self.cs = self.pspace.function()  # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0
        self.cu = self.cspace.function(dim=self.GD)  # 位移函数
        self.cphi = self.pspace.function()  # 孔隙度函数, 分片常数

        # 初值
        self.p[:] = model.rock['initial pressure']  # MPa
        self.phi[:] = model.rock['porosity']  # 初始孔隙度
        self.cp[:] = model.rock['initial pressure']  # 初始地层压强
        self.cphi[:] = model.rock['porosity']  # 当前孔隙度系数

        # 源项,  TODO: 注意这里假设用的是结构网格, 换其它的网格需要修改代码
        self.fo = self.cspace.function()
        self.fo[-1] = -self.model.oil['production rate']  # 产出

        self.fw = self.cspace.function()
        self.fw[0] = self.model.water['injection rate']  # 注入

        # 一些常数矩阵和向量

        # 速度散度矩阵, 速度方程对应的散度矩阵, (\nabla\cdot v, w)
        self.B = self.vspace.div_matrix()

        # 压强方程对应的位移散度矩阵, (\nabla\cdot u, w) 位移散度矩阵
        # * 注意这里利用了压强空间分片常数, 线性函数导数也是分片常数的事实
        c = self.mesh.entity_measure('cell')
        c *= self.model.rock['biot']

        val = self.mesh.grad_lambda()  # (NC, TD+1, GD)
        val *= c[:, None, None]
        pc2d = self.pspace.cell_to_dof()
        cc2d = self.cspace.cell_to_dof()
        pgdof = self.pspace.number_of_global_dofs()
        cgdof = self.cspace.number_of_global_dofs()
        I = np.broadcast_to(pc2d, shape=cc2d.shape)
        J = cc2d
        self.PU0 = csr_matrix((val[..., 0].flat, (I.flat, J.flat)),
                              shape=(pgdof, cgdof))
        self.PU1 = csr_matrix((val[..., 1].flat, (I.flat, J.flat)),
                              shape=(pgdof, cgdof))

        if self.GD == 3:
            self.PU2 = csr_matrix((val[..., 2].flat, (I.flat, J.flat)),
                                  shape=(pgdof, cgdof))

        # 线弹性矩阵的右端向量
        sigma0 = self.pspace.function()
        sigma0[:] = self.model.rock['initial stress']
        self.FU = np.zeros(self.GD * cgdof, dtype=np.float64)
        self.FU[0 * cgdof:1 * cgdof] -= self.p @ self.PU0
        self.FU[1 * cgdof:2 * cgdof] -= self.p @ self.PU1

        if self.GD == 3:
            self.FU[2 * cgdof:3 * cgdof] -= self.p @ self.PU2

        # 初始应力和等效应力项
        self.FU[0 * cgdof:1 * cgdof] -= sigma0 @ self.PU0
        self.FU[1 * cgdof:2 * cgdof] -= sigma0 @ self.PU1
        if self.GD == 3:
            self.FU[2 * cgdof:3 * cgdof] -= sigma0 @ self.PU2

        # vtk 文件输出
        node, cell, cellType, NC = self.mesh.to_vtk()
        self.points = vtk.vtkPoints()
        self.points.SetData(vnp.numpy_to_vtk(node))
        self.cells = vtk.vtkCellArray()
        self.cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell))
        self.cellType = cellType
示例#16
0
    def solve_poisson_2d(self):

        pde = CosCosData()
        mesh = pde.init_mesh(n=3, methtype='tri')
        space = RaviartThomasFiniteElementSpace2d(mesh, p=0)
示例#17
0
    def __init__(self, mesh, args, ctx):
        self.ctx = ctx
        self.args = args # 模拟相关参数

        NT = int((args.T1 - args.T0)/args.DT)
        self.timeline = UniformTimeLine(args.T0, args.T1, NT)
        self.mesh = mesh 

        if self.ctx.myid == 0:
            self.GD = mesh.geo_dimension()
            if self.GD == 2:
                self.vspace = RaviartThomasFiniteElementSpace2d(self.mesh, p=0) # 速度空间
            elif self.GD == 3:
                self.vspace = RaviartThomasFiniteElementSpace3d(self.mesh, p=0)

            self.pspace = self.vspace.smspace # 压力和饱和度所属的空间, 分片常数
            self.cspace = LagrangeFiniteElementSpace(self.mesh, p=1) # 位移空间

            # 上一时刻物理量的值
            self.v = self.vspace.function() # 速度函数
            self.p = self.pspace.function() # 压力函数
            self.s = self.pspace.function() # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0
            self.u = self.cspace.function(dim=self.GD) # 位移函数
            self.phi = self.pspace.function() # 孔隙度函数, 分片常数

            # 当前时刻物理量的值, 用于保存临时计算出的值, 模型中系数的计算由当前时刻
            # 的物理量的值决定
            self.cv = self.vspace.function() # 速度函数
            self.cp = self.pspace.function() # 压力函数
            self.cs = self.pspace.function() # 水的饱和度函数 默认为0, 初始时刻区域内水的饱和度为0
            self.cu = self.cspace.function(dim=self.GD) # 位移函数
            self.cphi = self.pspace.function() # 孔隙度函数, 分片常数

            # 初值
            self.s[:] = self.mesh.celldata['fluid_0']
            self.p[:] = self.mesh.celldata['pressure_0']  # MPa
            self.phi[:] = self.mesh.celldata['porosity_0'] # 初始孔隙度 

            self.s[:] = self.mesh.celldata['fluid_0']
            self.cp[:] = self.p # 初始地层压力
            self.cphi[:] = self.phi # 当前孔隙度系数

            # 源汇项 
            self.f0 = self.cspace.function()
            self.f1 = self.cspace.function()

            self.f0[:] = self.mesh.nodedata['source_0'] # 流体 0 的源汇项
            self.f1[:] = self.mesh.nodedata['source_1'] # 流体 1 的源汇项

            # 一些常数矩阵和向量

            # 速度散度矩阵, 速度方程对应的散度矩阵, (\nabla\cdot v, w) 
            self.B = self.vspace.div_matrix()

            # 压力方程对应的位移散度矩阵, (\nabla\cdot u, w) 位移散度矩阵
            # * 注意这里利用了压力空间分片常数, 线性函数导数也是分片常数的事实
            c = self.mesh.entity_measure('cell')
            c *= self.mesh.celldata['biot']

            val = self.mesh.grad_lambda() # (NC, TD+1, GD)
            val *= c[:, None, None]
            pc2d = self.pspace.cell_to_dof()
            cc2d = self.cspace.cell_to_dof()
            pgdof = self.pspace.number_of_global_dofs()
            cgdof = self.cspace.number_of_global_dofs()
            I = np.broadcast_to(pc2d, shape=cc2d.shape)
            J = cc2d 
            self.PU0 = csr_matrix(
                    (val[..., 0].flat, (I.flat, J.flat)), 
                    shape=(pgdof, cgdof)
                    )
            self.PU1 = csr_matrix(
                    (val[..., 1].flat, (I.flat, J.flat)),
                    shape=(pgdof, cgdof)
                    )

            if self.GD == 3:
                self.PU2 = csr_matrix(
                        (val[..., 2].flat, (I.flat, J.flat)),
                        shape=(pgdof, cgdof)
                        )

            # 线弹性矩阵的右端向量
            self.FU = np.zeros(self.GD*cgdof, dtype=np.float64)
            self.FU[0*cgdof:1*cgdof] -= [email protected]
            self.FU[1*cgdof:2*cgdof] -= [email protected]

            if self.GD == 3:
                self.FU[2*cgdof:3*cgdof] -= [email protected]

            # 初始应力和等效应力项
            sigma = self.mesh.celldata['stress_0'] + self.mesh.celldata['stress_eff']# 初始应力和等效应力之和
            self.FU[0*cgdof:1*cgdof] -= [email protected]
            self.FU[1*cgdof:2*cgdof] -= [email protected]
            if self.GD == 3:
                self.FU[2*cgdof:3*cgdof] -= [email protected]
示例#18
0
from fealpy.solver import SaddlePointFastSolver


p = int(sys.argv[1]) # RT 空间的次数
n = int(sys.argv[2]) # 初始网格部分段数
maxit = int(sys.argv[3]) # 迭代求解次数


pde = CosCosData()  # pde 模型
box = pde.domain()  # 模型区域
mf = MeshFactory() # 网格工场

for i in range(maxit):
    mesh = mf.boxmesh2d(box, nx=n, ny=n, meshtype='tri')
    space = RaviartThomasFiniteElementSpace2d(mesh, p=p)

    udof = space.number_of_global_dofs()
    pdof = space.smspace.number_of_global_dofs()
    gdof = udof + pdof

    print("step ", i, " with number of dofs:", gdof)

    uh = space.function()
    ph = space.smspace.function()

    M = space.mass_matrix()
    B = -space.div_matrix()

    F0 = -space.set_neumann_bc(pde.dirichlet) # Poisson 的 D 氏边界变为 Neumann
    F1 = -space.smspace.source_vector(pde.source)
示例#19
0
from fealpy.mesh import TriangleMesh, PolygonMesh, MeshFactory

## space
from fealpy.functionspace import RaviartThomasFiniteElementSpace2d
from fealpy.functionspace import DivFreeNonConformingVirtualElementSpace2d
from fealpy.functionspace import ReducedDivFreeNonConformingVirtualElementSpace2d
from fealpy.functionspace import ScaledMonomialSpace2d

from fealpy.pde.stokes_model_2d import StokesModelData_0, StokesModelData_1

p = 2
n = 5
tmesh = MeshFactory.boxmesh2d([0, 1, 0, 1], nx=5, ny=5, meshtype='tri')

# RT 空间
space0 = RaviartThomasFiniteElementSpace2d(tmesh, p=p - 1)

# 三角形转化为多边形网格, 注意这里要求三角形的 0 号边转化后仍然是多边形的 0
# 号边
NC = tmesh.number_of_cells()
NV = 3
node = tmesh.entity('node')
cell = tmesh.entity('cell')[:, [1, 2, 0]]
cellLocation = np.arange(0, (NC + 1) * NV, NV)
pmesh = PolygonMesh(node, cell.reshape(-1), cellLocation)

# 缩减虚单元空间
space1 = ReducedDivFreeNonConformingVirtualElementSpace2d(pmesh, p=p)

b0 = space1.source_vector(pde.source)
b1 = space1.pressure_robust_source_vector(pde.source, space0)
示例#20
0
    def solve_poisson_2d(self, n=3, p=0, plot=True):
        pde = CosCosData()

        mesh = pde.init_mesh(n=n, meshtype='tri')
        space = RaviartThomasFiniteElementSpace2d(mesh, p=p)

        udof = space.number_of_global_dofs()
        pdof = space.smspace.number_of_global_dofs()
        gdof = udof + pdof

        uh = space.function()
        ph = space.smspace.function()
        A = space.stiff_matrix()
        B = space.div_matrix()
        F1 = space.source_vector(pde.source)
        AA = bmat([[A, -B], [-B.T, None]], format='csr')

        if True:
            F0 = -space.set_neumann_bc(pde.dirichlet)
            FF = np.r_['0', F0, F1]
            x = spsolve(AA, FF).reshape(-1)
            uh[:] = x[:udof]
            ph[:] = x[udof:]
            error0 = space.integralalg.L2_error(pde.flux, uh)

            def f(bc):
                xx = mesh.bc_to_point(bc)
                return (pde.solution(xx) - ph(xx))**2

            error1 = space.integralalg.integral(f)
            print(error0, error1)
        else:
            isBdDof = -space.set_dirichlet_bc(uh, pde.neumann)
            x = np.r_['0', uh, ph]
            isBdDof = np.r_['0', isBdDof, np.zeros(pdof, dtype=np.bool_)]

            FF = np.r_['0', np.zeros(udof, dtype=np.float64), F1]

            FF -= AA @ x
            bdIdx = np.zeros(gdof, dtype=np.int)
            bdIdx[isBdDof] = 1
            Tbd = spdiags(bdIdx, 0, gdof, gdof)
            T = spdiags(1 - bdIdx, 0, gdof, gdof)
            AA = T @ AA @ T + Tbd
            FF[isBdDof] = x[isBdDof]
            x[:] = spsolve(AA, FF)
            uh[:] = x[:udof]
            ph[:] = x[udof:]

            error0 = space.integralalg.L2_error(pde.flux, uh)

            def f(bc):
                xx = mesh.bc_to_point(bc)
                return (pde.solution(xx) - ph(xx))**2

            error1 = space.integralalg.integral(f)
            print(error0, error1)

        if plot:
            box = [-0.5, 1.5, -0.5, 1.5]
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes, box=box)
            #mesh.find_node(axes, showindex=True)
            #mesh.find_edge(axes, showindex=True)
            #mesh.find_cell(axes, showindex=True)
            node = ps.reshape(-1, 2)
            uv = uh.reshape(-1, 2)
            axes.quiver(node[:, 0], node[:, 1], uv[:, 0], uv[:, 1])
            plt.show()