Esempio n. 1
0
 def __init__(self, mesh, pde, p, q, p0=None):
     """
     """
     self.space = SurfaceLagrangeFiniteElementSpace(mesh,
                                                    pde.surface,
                                                    p=p,
                                                    p0=p0)
     self.mesh = self.space.mesh
     self.surface = pde.surface
     self.pde = pde
     self.uh = self.space.function()
     self.uI = self.space.interpolation(pde.solution)
Esempio n. 2
0
    def __init__(self, pde, mesh, p=1, q=6, p0=None):
        from fealpy.functionspace import SurfaceLagrangeFiniteElementSpace
        from fealpy.boundarycondition import DirichletBC
        self.space = SurfaceLagrangeFiniteElementSpace(mesh, pde.surface, p=p,
                p0=p0, q=q)
        self.mesh = self.space.mesh
        self.surface = pde.surface
        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()
Esempio n. 3
0
class SurfaceParabolicFEMModel():
    def __init__(self, pde, mesh, p=1, q=6, p0=None):
        from fealpy.functionspace import SurfaceLagrangeFiniteElementSpace
        from fealpy.boundarycondition import DirichletBC
        self.space = SurfaceLagrangeFiniteElementSpace(mesh, pde.surface, p=p,
                p0=p0, q=q)
        self.mesh = self.space.mesh
        self.surface = pde.surface
        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):
        dt = timeline.current_time_step_length()
        i = timeline.current
        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] + F)

    def apply_boundary_condition(self, A, b, timeline):
        t1 = timeline.next_time_level()
        bc = DirichletBC(self.space, lambda x:self.pde.solution(x, t1), self.is_boundary_dof)
        A, b = bc.apply(A, b)
        return A, b

    def is_boundary_dof(self, p):
        isBdDof = np.zeros(p.shape[0], dtype=np.bool)
        isBdDof[0] = True
        return isBdDof

    def solve(self, uh, A, b, solver, timeline):
        i = timeline.current
        uh[:, i+1] = solver(A, b)
    def grad_recovery_test(self, p=1, plot=False):
        from fealpy.pde.surface_poisson_model_3d import SphereSinSinSinData
        pde = SphereSinSinSinData()
        surface = pde.domain()
        mesh = pde.init_mesh()
        for i in range(4):
            space = SurfaceLagrangeFiniteElementSpace(mesh, surface, p=p)
            uI = space.interpolation(pde.solution)
            rg = space.grad_recovery(uI)
            error0 = space.integralalg.L2_error(pde.solution, uI.value)
            error1 = space.integralalg.L2_error(pde.gradient, rg.value)

            def f(x):
                return np.sum(rg.value(x)**2, axis=-1)

            eta = space.integralalg.integral(f, celltype=True)

            mesh.uniform_refine(surface=surface)
            print(error1)
 def mesh_scale_test(self, plot=True):
     scale = 10
     pde = HeartSurfacetData()
     surface = pde.domain()
     mesh = pde.init_mesh()
     space = SurfaceLagrangeFiniteElementSpace(mesh,
                                               surface,
                                               p=1,
                                               scale=scale)
     mesh = space.mesh
     if plot is True:
         fig = plt.figure()
         axes = Axes3D(fig)
         mesh.add_plot(axes, showaxis=True)
         plt.show()
Esempio n. 6
0
    def test_adaptive(self):
        options = self.tritree.adaptive_options(maxrefine=1)
        mesh = self.tritree.to_conformmesh()
        for i in range(1):
            space = SurfaceLagrangeFiniteElementSpace(mesh, self.surface, p=1)
            uI = space.interpolation(self.pde.solution)
            phi = lambda x: uI.grad_value(x)**2
            eta = space.integralalg.integral(lambda x: uI.grad_value(x)**2,
                                             celltype=True,
                                             barycenter=True)
            eta = eta.sum(axis=-1)
            self.tritree.adaptive(eta, options, surface=self.surface)
            mesh = self.tritree.to_conformmesh()
            print(self.tritree.celldata['idxmap'])
            cell = self.tritree.entity('cell')
            print(cell[15])
            cell = mesh.entity('cell')
            print(cell[104])
            print(cell[140])

        fig = pl.figure()
        axes = a3.Axes3D(fig)
        self.tritree.add_plot(axes)
        plt.show()
import numpy as np
import vtk
from vtk.numpy_interface import dataset_adapter as dsa
import vtk.util.numpy_support as vnp

from fealpy.geometry import Sphere
from fealpy.functionspace import SurfaceLagrangeFiniteElementSpace

order = 2
surface = Sphere()
surface.radius = 3.65
mesh = surface.init_mesh()

mesh.uniform_refine(n=2, surface=surface)
femspace = SurfaceLagrangeFiniteElementSpace(mesh, surface, p=order)
ldof = femspace.number_of_local_dofs()

mesh = femspace.mesh
node = mesh.node
NC = mesh.number_of_cells()
idx = np.array([0, 3, 5, 1, 4, 2], dtype=np.int64)
cell2dof = np.int64(mesh.space.cell_to_dof())

cell2dof = np.r_['1', ldof * np.ones((NC, 1), dtype=np.int), cell2dof[:, idx]]

points = vtk.vtkPoints()
points.SetData(vnp.numpy_to_vtk(node))
cells = vtk.vtkCellArray()
cells.SetCells(NC, vnp.numpy_to_vtkIdTypeArray(cell2dof))

uGrid = vtk.vtkUnstructuredGrid()
Esempio n. 8
0
    def test_interpolation_surface(self, p=1):
        options = self.tritree.adaptive_options(maxrefine=1, p=p)
        mesh = self.tritree.to_conformmesh()
        space = SurfaceLagrangeFiniteElementSpace(mesh, self.surface, p=p)
        uI = space.interpolation(self.pde.solution)
        print('1:', space.number_of_global_dofs())
        print('2:', uI.shape)
        error0 = space.integralalg.L2_error(self.pde.solution, uI)
        print(error0)
        data = self.tritree.interpolation(uI)
        print('3', data.shape)
        options['data'] = {'q': data}
        if 1:
            eta = space.integralalg.integral(lambda x: uI.grad_value(x)**2,
                                             celltype=True,
                                             barycenter=True)
            eta = eta.sum(axis=-1)
            self.tritree.adaptive(eta, options, surface=self.surface)
        else:
            self.tritree.uniform_refine(options=options, surface=self.surface)

        mesh = self.tritree.to_conformmesh(options)
        space = SurfaceLagrangeFiniteElementSpace(mesh, self.surface, p=p)
        data = options['data']['q']
        print('data:', data.shape)
        uh = space.to_function(data)
        print('uh:', uh.shape)
        error1 = space.integralalg.L2_error(self.pde.solution, uh)
        print(error1)

        uI = space.interpolation(self.pde.solution)
        error2 = space.integralalg.L2_error(self.pde.solution, uI)
        print(error2)

        data = self.tritree.interpolation(uI)
        options['data'] = {'q': data}
        if 0:
            eta = space.integralalg.integral(lambda x: uI.grad_value(x)**2,
                                             celltype=True,
                                             barycenter=True)
            eta = eta.sum(axis=-1)
            self.tritree.adaptive(eta, options, surface=self.surface)
        else:
            self.tritree.uniform_refine(options=options, surface=self.surface)

        mesh = self.tritree.to_conformmesh(options)
        space = SurfaceLagrangeFiniteElementSpace(mesh, self.surface, p=p)
        data = options['data']['q']
        uh = space.to_function(data)
        error3 = space.integralalg.L2_error(self.pde.solution, uh)
        print(error3)

        if 0:
            fig = pl.figure()
            axes = a3.Axes3D(fig)
            self.tritree.add_plot(axes)
            plt.show()
        else:
            fig = pl.figure()
            axes = a3.Axes3D(fig)
            mesh.add_plot(axes)
            plt.show()
Esempio n. 9
0
class SurfacePoissonFEMModel():
    def __init__(self, mesh, pde, p, q, p0=None):
        """
        """
        self.space = SurfaceLagrangeFiniteElementSpace(mesh,
                                                       pde.surface,
                                                       p=p,
                                                       p0=p0)
        self.mesh = self.space.mesh
        self.surface = pde.surface
        self.pde = pde
        self.uh = self.space.function()
        self.uI = self.space.interpolation(pde.solution)

    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.area
        return np.sqrt(e)

    def get_grad_basis(self, bc):
        return self.space.grad_basis(bc, returncond=True)

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

    def get_right_vector(self):
        b = self.space.source_vector(self.pde.source)
        b -= np.mean(b)
        return b

    def solve(self):
        u = self.pde.solution
        bc = DirichletBC(self.space, u, self.is_boundary_dof)
        solver = MatlabSolver()
        A = self.get_left_matrix()
        b = self.get_right_vector()
        AD, b = bc.apply(A, b)
        self.uh[:] = solver.divide(AD, b)

    def is_boundary_dof(self, p):
        isBdDof = np.zeros(p.shape[0], dtype=np.bool)
        isBdDof[0] = True
        return isBdDof

    def error(self):
        e0 = self.L2_error()
        e1 = self.H1_semi_error()
        return e0, e1

    def L2_error(self):
        u = self.pde.solution
        uh = self.uh.value
        return self.space.integralalg.L2_error(u, uh)

    def H1_semi_error(self):
        gu = self.pde.gradient
        guh = self.uh.grad_value
        return self.space.integralalg.L2_error(gu, guh)
Esempio n. 10
0
class SurfaceParabolicFEMModel():
    def __init__(self, pde, mesh, p=1, q=6, p0=None):
        from fealpy.functionspace import SurfaceLagrangeFiniteElementSpace
        from fealpy.boundarycondition import DirichletBC
        self.space = SurfaceLagrangeFiniteElementSpace(mesh, pde.surface, p=p,
                p0=p0, q=q)
        self.mesh = self.space.mesh
        self.surface = pde.surface
        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 init_source(self, timeline):
        NL = timeline.number_of_time_levels()
        gdof = self.space.number_of_global_dofs()
        F = np.zeros((gdof, NL), dtype=self.mesh.ftype)
        times = timeline.all_time_levels()
        for i, t in enumerate(times):
            F[:, i] = self.space.source_vector(lambda x: self.pde.source(x, t))
        return F

    def init_delta(self, timeline):
        NL = timeline.number_of_time_levels()
        gdof = self.space.number_of_global_dofs()
        delta = np.zeros((gdof, NL), dtype=self.mesh.ftype)
        return delta

    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, sdc=False):
        dt = timeline.current_time_step_length()
        i = timeline.current
        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)
        if sdc is False:
            return self.M@uh[:, i] - 0.5*dt*(self.A@uh[:, i] - F)
        else:
            return self.M@uh[:, i] - 0.5*dt*self.A@uh[:, i]

    def residual_integration(self, uh, timeline):
        A = self.space.stiff_matrix()
        F = self.init_source(timeline)
        q = -A@uh + F
        return timeline.dct_time_integral(q, return_all=True)

    def error_integration(self, data, timeline):
        uh = data[0]
        intq = data[1]
        M = self.space.mass_matrix()
        r = uh[:, [0]] + spsolve(M, intq) - uh
        return timeline.diff(r)

    def get_error_right_vector(self, data, timeline):
        uh = data[0]
        d = data[2]
        delta = data[-1]
        M = self.space.mass_matrix()
        i = timeline.current
        dt = timeline.current_time_step_length()
        return self.get_current_right_vector(delta, timeline, sdc=True) + dt*M@d[:, i+1]

    def apply_boundary_condition(self, A, b, timeline, sdc=False):
        if sdc is False:
            t1 = timeline.next_time_level()
            bc = DirichletBC(self.space, lambda x:self.pde.solution(x, t1), self.is_boundary_dof)
            A, b = bc.apply(A, b)
            return A, b
        else:
            bc = DirichletBC(self.space, lambda x:0, self.is_boundary_dof)
            A, b = bc.apply(A, b)
            return A, b

    def is_boundary_dof(self, p):
        isBdDof = np.zeros(p.shape[0], dtype=np.bool)
        isBdDof[0] = True
        return isBdDof

    def solve(self, data, A, b, solver, timeline):
        i = timeline.current
        data[:, i+1] = solver(A, b)