Example #1
0
def test_poisson_fem_2d():
    degree = 1  
    dim = 2
    nrefine = 4 
    maxit = 4 

    from fealpy.pde.poisson_2d import CosCosData as PDE

    pde = PDE()
    mesh = pde.init_mesh(n=nrefine)

    errorMatrix = np.zeros((2, maxit), dtype=np.float64)
    NDof = np.zeros(maxit, dtype=np.int64)

    for i in range(maxit):
        space = LagrangeFiniteElementSpace(mesh, p=degree)
        NDof[i] = space.number_of_global_dofs()
        bc = DirichletBC(space, pde.dirichlet) 

        uh = space.function()
        A = space.stiff_matrix()

        F = space.source_vector(pde.source)

        A, F = bc.apply(A, F, uh)

        uh[:] = spsolve(A, F).reshape(-1)

        errorMatrix[0, i] = space.integralalg.L2_error(pde.solution, uh)
        errorMatrix[1, i] = space.integralalg.L2_error(pde.gradient, uh.grad_value)

        if i < maxit-1:
            mesh.uniform_refine()
Example #2
0
    def solve_poisson_3d(self, n=2):
        from fealpy.pde.poisson_3d import CosCosCosData as PDE
        from fealpy.mesh import MeshFactory
        from fealpy.functionspace import LagrangeFiniteElementSpace
        from fealpy.boundarycondition import DirichletBC

        pde = PDE()
        mf = MeshFactory()
        m = 2**n
        box = [0, 1, 0, 1, 0, 1]
        mesh = mf.boxmesh3d(box, nx=m, ny=m, nz=m, meshtype='tet')
        space = LagrangeFiniteElementSpace(mesh, p=1)
        gdof = space.number_of_global_dofs()
        NC = mesh.number_of_cells()
        print('gdof:', gdof, 'NC:', NC)
        bc = DirichletBC(space, pde.dirichlet)
        uh = space.function()
        A = space.stiff_matrix()
        A = space.parallel_stiff_matrix(q=1)

        M = space.parallel_mass_matrix(q=2)
        M = space.mass_matrix()

        F = space.source_vector(pde.source)

        A, F = bc.apply(A, F, uh)

        solver = PETScSolver()
        solver.solve(A, F, uh)
        error = space.integralalg.L2_error(pde.solution, uh)
        print(error)
Example #3
0
    def poisson_fem_2d_neuman_test(self, p=1):
        pde = CosCosData()
        mesh = pde.init_mesh(n=2)
        for i in range(4):
            space = LagrangeFiniteElementSpace(mesh, p=p)
            A = space.stiff_matrix()
            b = space.source_vector(pde.source)
            uh = space.function()
            bc = BoundaryCondition(space, neuman=pde.neuman)
            bc.apply_neuman_bc(b)
            c = space.integral_basis()
            AD = bmat([[A, c.reshape(-1, 1)], [c, None]], format='csr')
            bb = np.r_[b, 0]
            x = spsolve(AD, bb)
            uh[:] = x[:-1]

            area = np.sum(space.integralalg.cellmeasure)
            ubar = space.integralalg.integral(pde.solution,
                                              barycenter=False) / area

            def solution(p):
                return pde.solution(p) - ubar

            error = space.integralalg.L2_error(solution, uh)
            print(error)
            mesh.uniform_refine()
Example #4
0
    def solve_poisson_robin(self, p=1, n=1, plot=True):

        pde = XYData()
        mesh = pde.init_mesh(n=n)

        node = mesh.node
        cell = mesh.entity("cell")
        name = 'RobinBCTest.mat'
        space = LagrangeFiniteElementSpace(mesh, p=p)
        A = space.stiff_matrix()
        F = space.source_vector(pde.source)
#        print(A.toarray())

#        A, F = space.set_robin_bc(A, F, pde.robin)
 
        uh = space.function()
        #bc = BoundaryCondition(space, robin=pde.robin)
        A, b = space.set_robin_bc(A, F, pde.robin)
        uh[:] = spsolve(A, b).reshape(-1)
        error = space.integralalg.L2_error(pde.solution, uh)
        print(error)

#        print('A:', A.toarray())
#        print('F:', F)


        if plot:
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes)
            mesh.find_node(axes, showindex=True)
            mesh.find_cell(axes, showindex=True)
            plt.show()
Example #5
0
class ParabolicFEMModel():
    def __init__(self, pde, mesh, p=1, q=6):
        from fealpy.functionspace import LagrangeFiniteElementSpace
        from fealpy.boundarycondition import BoundaryCondition
        self.space = LagrangeFiniteElementSpace(mesh, p)
        self.mesh = self.space.mesh
        self.pde = pde

        self.ftype = self.mesh.ftype
        self.itype = self.mesh.itype

        self.M = self.space.mass_matrix()
        self.A = self.space.stiff_matrix()

    def init_solution(self, timeline):
        NL = timeline.number_of_time_levels()
        gdof = self.space.number_of_global_dofs()
        uh = np.zeros((gdof, NL), dtype=self.mesh.ftype)
        uh[:,
           0] = self.space.interpolation(lambda x: self.pde.solution(x, 0.0))
        return uh

    def interpolation(self, u, timeline):
        NL = timeline.number_of_time_levels()
        gdof = self.space.number_of_global_dofs()
        ps = self.space.interpolation_points()
        uI = np.zeros((gdof, NL), dtype=self.mesh.ftype)
        times = timeline.all_time_levels()
        for i, t in enumerate(times):
            uI[..., i] = u(ps, t)
        return uI

    def get_current_left_matrix(self, timeline):
        dt = timeline.current_time_step_length()
        return self.M + 0.5 * dt * self.A

    def get_current_right_vector(self, uh, timeline):
        i = timeline.current
        dt = timeline.current_time_step_length()
        t0 = timeline.current_time_level()
        t1 = timeline.next_time_level()
        f = lambda x: self.pde.source(x, t0) + self.pde.source(x, t1)
        F = self.space.source_vector(f)
        return self.M @ uh[:, i] - 0.5 * dt * self.A @ uh[:, i]

    def apply_boundary_condition(self, A, b, timeline):
        t1 = timeline.next_time_level()
        bc = BoundaryCondition(self.space,
                               neuamn=lambda x: self.pde.neuman(x, t1))
        b = bc.apply_neuman_bc(b)
        return A, b

    def solve(self, uh, A, b, solver, timeline):
        i = timeline.current
        uh[:, i + 1] = solver(A, b)
Example #6
0
 def poisson_fem_2d_test(self, p=1):
     pde = CosCosData()
     mesh = pde.init_mesh(n=3)
     for i in range(4):
         space = LagrangeFiniteElementSpace(mesh, p=p)
         A = space.stiff_matrix()
         b = space.source_vector(pde.source)
         uh = space.function()
         bc = BoundaryCondition(space, dirichlet=pde.dirichlet)
         A, b = bc.apply_dirichlet_bc(A, b, uh)
         uh[:] = spsolve(A, b).reshape(-1)
         error = space.integralalg.L2_error(pde.solution, uh)
         print(error)
         mesh.uniform_refine()
Example #7
0
    def solve_poisson_robin(self, p=1, n=1, plot=True):

        pde = CosCosCosData()
        mesh = pde.init_mesh(n=n)

        space = LagrangeFiniteElementSpace(mesh, p=p)

        A = space.stiff_matrix()
        F = space.source_vector(pde.source)
        uh = space.function()
        bc = BoundaryCondition(space, robin=pde.robin)
        A, b = space.set_robin_bc(A, F, pde.robin)
        uh[:] = spsolve(A, b).reshape(-1)
        error = space.integralalg.L2_error(pde.solution, uh)
        print(error)
Example #8
0
    def solve_poisson_3d(self, n=5):
        from fealpy.pde.poisson_3d import CosCosCosData as PDE
        from fealpy.functionspace import LagrangeFiniteElementSpace
        from fealpy.boundarycondition import DirichletBC

        pde = PDE()
        mesh = pde.init_mesh(n=n)
        space = LagrangeFiniteElementSpace(mesh, p=1)
        bc = DirichletBC(space, pde.dirichlet)
        uh = space.function()
        A = space.stiff_matrix()
        F = space.source_vector(pde.source)

        A, F = bc.apply(A, F, uh)

        solver = PETScSolver()
        solver.solve(A, F, uh)
        error = space.integralalg.L2_error(pde.solution, uh)
        print(error)
Example #9
0
    def solve_poisson_robin(self, p=1, n=1, plot=True):

        pde = XYData()
        mesh = pde.init_mesh(n=1)

        space = LagrangeFiniteElementSpace(mesh, p=p)
        A = space.stiff_matrix()
        F = space.source_vector(pde.source)

        space.set_robin_bc(A, F, pde.robin)

        print('A:', A.toarray())
        print('F:', F)

        if plot:
            fig = plt.figure()
            axes = fig.gca()
            mesh.add_plot(axes)
            mesh.find_node(axes, showindex=True)
            mesh.find_cell(axes, showindex=True)
            plt.show()
Example #10
0
def test_poisson():

    p = 1  # 有限元空间次数, 可以增大 p, 看输出结果的变化
    n = 4  # 初始网格加密次数
    maxit = 4  # 最大迭代次数

    pde = PDE()
    mesh = pde.init_mesh(n=n)

    errorMatrix = np.zeros((2, maxit), dtype=np.float)
    NDof = np.zeros(maxit, dtype=np.float)

    for i in range(maxit):
        space = LagrangeFiniteElementSpace(mesh, p=p)  # 建立有限元空间

        NDof[i] = space.number_of_global_dofs()  # 有限元空间自由度的个数
        bc = DirichletBC(space, pde.dirichlet)  # DirichletBC 条件

        uh = space.function()  # 有限元函数
        A = space.stiff_matrix()  # 刚度矩阵
        F = space.source_vector(pde.source)  # 载荷向量

        A, F = bc.apply(A, F, uh)  # 处理边界条件

        uh[:] = spsolve(A, F).reshape(-1)  # 稀疏矩阵直接解法器

        # ml = pyamg.ruge_stuben_solver(A)  # 代数多重网格解法器
        # uh[:] = ml.solve(F, tol=1e-12, accel='cg').reshape(-1)

        errorMatrix[0, i] = space.integralalg.L2_error(
            pde.solution, uh
        )  # 计算 L2 误差
        errorMatrix[1, i] = space.integralalg.L2_error(
            pde.gradient, uh.grad_value
        )  # 计算 H1 误差

        if i < maxit - 1:
            mesh.uniform_refine()  # 一致加密网格

    assert (errorMatrix < 1.0).all()
Example #11
0
    def Arctan(self, p=1, n=3):
        pde = ArctanData()

        node = np.array([[-1, -1], [1, -1], [1, 1], [-1, 1]], dtype=np.float_)
        cell = np.array([[0, 1, 2], [0, 2, 3]], dtype=np.int_)
        mesh = TriangleMesh(node, cell)
        mesh.uniform_refine(n=n)

        space = LagrangeFiniteElementSpace(mesh, p=p)
        uh = space.function()

        A = space.stiff_matrix()
        b = space.source_vector(pde.source)

        bc = DirichletBC(space, pde.dirichlet)
        A, b = bc.apply(A, b, uh)
        uh[:] = spsolve(A, b).reshape(-1)

        error0 = space.integralalg.L2_error(pde.solution, uh)
        error1 = space.integralalg.L2_error(pde.gradient, uh.grad_value)
        print(error0)
        print(error1)
Example #12
0
pde = CosCosData()
mesh = pde.init_mesh(n=3)

errorType = [
    '$|| u - u_h||_{\Omega,0}$', '$||\\nabla u - \\nabla u_h||_{\Omega, 0}$'
]
errorMatrix = np.zeros((2, maxit), dtype=np.float)
NDof = np.zeros(maxit, dtype=np.float)

for i in range(maxit):
    space = LagrangeFiniteElementSpace(mesh, p=p)
    NDof[i] = space.number_of_global_dofs()

    uh = space.function()
    A = space.stiff_matrix()
    F = space.source_vector(pde.source)

    bc = NeumannBC(space, pde.neumann)
    A, F = bc.apply(
        F, A=A)  # Here is the case for pure Neumann bc, we also need modify A
    # bc.apply(F) # Not pure Neumann bc case
    uh[:] = spsolve(A, F)[:-1]  # we add a addtional dof

    # Here can not work
    #ml = pyamg.ruge_stuben_solver(A)
    #x = ml.solve(F, tol=1e-12, accel='cg').reshape(-1)
    #uh[:] = x[-1]

    errorMatrix[0, i] = space.integralalg.L2_error(pde.solution, uh)
    errorMatrix[1, i] = space.integralalg.L2_error(pde.gradient, uh.grad_value)
Example #13
0
import numpy as np
from scipy.sparse.linalg import spsolve

import matplotlib.pyplot as plt

from fealpy.pde.linear_elasticity_model import HuangModel2d
from fealpy.functionspace import LagrangeFiniteElementSpace
from fealpy.boundarycondition import BoundaryCondition

p = int(sys.argv[1])
n = int(sys.argv[2])

pde = HuangModel2d(lam=100000, mu=1.0)
mu = pde.mu
lam = pde.lam
mesh = pde.init_mesh(n=n)

space = LagrangeFiniteElementSpace(mesh, p=p)
bc = BoundaryCondition(space, dirichlet=pde.dirichlet)
uh = space.function(dim=2)
#A = space.linear_elasticity_matrix(mu, lam)
A = space.recovery_linear_elasticity_matrix(mu, lam)
F = space.source_vector(pde.source, dim=2)
A, F = bc.apply_dirichlet_bc(A,
                             F,
                             uh,
                             is_dirichlet_boundary=pde.is_dirichlet_boundary)
uh.T.flat[:] = spsolve(A, F)
error = space.integralalg.L2_error(pde.displacement, uh)
print(error)
Example #14
0
    M = space.mass_matrix(c=r)
    b = np.array([1.0, 1.0], dtype=np.float64)
    B = space.convection_matrix(c=b)

    @cartesian
    def f(p):
        x = p[..., 0]
        y = p[..., 1]
        pi = np.pi
        return 2 * pi**2 * np.sin(pi * x) * np.sin(
            pi * y) + 12 * pi**2 * np.cos(pi * x) * np.cos(pi * y) + (
                -pi) * np.sin(pi * x) * np.cos(pi * y) - pi * np.cos(
                    pi * x) * np.sin(pi * y) + (1 + x**2 + y**2) * np.cos(
                        pi * x) * np.cos(pi * y)

    F = space.source_vector(f)
    A += B + M

    # 画出误差阶

    bc = DirichletBC(space, pde.dirichlet, threshold=pde)
    A, F = bc.apply(A, F, uh)
    uh[:] = spsolve(A, F).reshape(-1)
    errorMatrix[0, i] = space.integralalg.error(pde.solution, uh.value)
    errorMatrix[1, i] = space.integralalg.error(pde.gradient, uh.grad_value)
    # eta = residual_estimate(uh, pde.source)
    # eta = recovery_estimate(uh)
    # errorMatrix[2, i] = np.sqrt(np.sum(eta ** 2))

    if i < maxit - 1:
        mesh.uniform_refine()
Example #15
0
class PoissonFEMModel(object):
    def __init__(self, pde, mesh, p, q=3):
        self.space = LagrangeFiniteElementSpace(mesh, p, q=q)
        self.mesh = self.space.mesh
        self.pde = pde
        self.uh = self.space.function()
        self.uI = self.space.interpolation(pde.solution)
        self.integrator = self.mesh.integrator(p + 2)

    def recover_estimate(self, rguh):
        qf = self.integrator
        bcs, ws = qf.quadpts, qf.weights

        val0 = rguh.value(bcs)
        val1 = self.uh.grad_value(bcs)
        l = np.sum((val1 - val0)**2, axis=-1)
        e = np.einsum('i, ij->j', ws, l)
        e *= self.space.cellmeasure
        return np.sqrt(e)

    def residual_estimate(self, uh=None):
        if uh is None:
            uh = self.uh
        mesh = self.mesh
        GD = mesh.geo_dimension()
        NC = mesh.number_of_cells()

        n = mesh.face_normal()
        bc = np.array([1 / (GD + 1)] * (GD + 1), dtype=mesh.ftype)
        grad = uh.grad_value(bc)

        ps = mesh.bc_to_point(bc)
        try:
            d = self.pde.diffusion_coefficient(ps)
        except AttributeError:
            d = np.ones(NC, dtype=mesh.ftype)

        if isinstance(d, float):
            grad *= d
        elif len(d) == GD:
            grad = np.einsum('m, im->im', d, grad)
        elif isinstance(d, np.ndarray):
            if len(d.shape) == 1:
                grad = np.einsum('i, im->im', d, grad)
            elif len(d.shape) == 2:
                grad = np.einsum('im, im->im', d, grad)
            elif len(d.shape) == 3:
                grad = np.einsum('imn, in->in', d, grad)

        if GD == 2:
            face2cell = mesh.ds.edge_to_cell()
            h = np.sqrt(np.sum(n**2, axis=-1))
        elif GD == 3:
            face2cell = mesh.ds.face_to_cell()
            h = np.sum(n**2, axis=-1)**(1 / 4)

        J = h * np.sum(
            (grad[face2cell[:, 0]] - grad[face2cell[:, 1]]) * n, axis=-1)**2

        NC = mesh.number_of_cells()
        eta = np.zeros(NC, dtype=mesh.ftype)
        np.add.at(eta, face2cell[:, 0], J)
        np.add.at(eta, face2cell[:, 1], J)
        return np.sqrt(eta)

    def get_left_matrix(self):
        return self.space.stiff_matrix()

    def get_right_vector(self):
        return self.space.source_vector(self.pde.source)

    def solve(self):
        bc = DirichletBC(self.space, self.pde.dirichlet)

        start = timer()
        A = self.get_left_matrix()
        b = self.get_right_vector()
        end = timer()
        self.A = A

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

        AD, b = bc.apply(A, b)

        start = timer()
        self.uh[:] = spsolve(AD, b)
        end = timer()
        print("Solve time:", end - start)

        ls = {'A': AD, 'b': b, 'solution': self.uh.copy()}

        return ls  # return the linear system

    def l2_error(self):
        e = self.uh - self.uI
        return np.sqrt(np.mean(e**2))

    def uIuh_error(self):
        e = self.uh - self.uI
        return np.sqrt(e @ self.A @ e)

    def L2_error(self, uh=None):
        u = self.pde.solution
        if uh is None:
            uh = self.uh.value
        else:
            uh = uh.value
        L2 = self.space.integralalg.L2_error(u, uh)
        return L2

    def H1_semi_error(self, uh=None):
        gu = self.pde.gradient
        if uh is None:
            guh = self.uh.grad_value
        else:
            guh = uh.grad_value
        H1 = self.space.integralalg.L2_error(gu, guh)
        return H1

    def recover_error(self, rguh):
        gu = self.pde.gradient
        guh = rguh.value
        mesh = self.mesh
        re = self.space.integralalg.L2_error(gu, guh, mesh)
        return re