Example #1
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)
    def test_space_on_tet(self, p=3):
        pde = CosCosCosData()
        mesh = pde.init_mesh(0)
        space = LagrangeFiniteElementSpace(mesh, p=p)
        ips = space.interpolation_points()
        face2dof = space.dof.face_to_dof()
        print(face2dof)
        print(mesh.entity('cell'))
        print('cell2dof:', space.cell_to_dof())

        fig = pl.figure()
        axes = a3.Axes3D(fig)
        mesh.add_plot(axes, showedge=True)
        mesh.find_node(axes, node=ips, showindex=True)
        mesh.find_face(axes, showindex=True)
        pl.show()
Example #3
0
class SurfaceTriangleMesh():
    def __init__(self, mesh, surface, p=1, scale=None):
        """
        Initial a object of Surface Triangle Mesh.

        Parameters
        ----------
        self :
            Surface Triangle Mesh Object
        mesh :
            mesh object, represents a triangulation with flat triangle faces.
        surface :
            The continuous surface which was represented as a level set
            function.
        p : int
            The degree of the Lagrange space

        Returns
        -------

        See Also
        --------

        Notes
        -----
        """
        self.mesh = mesh
        self.p = p
        self.space = LagrangeFiniteElementSpace(mesh, p)
        self.surface = surface
        self.ds = mesh.ds
        self.scale = scale
        if scale is not None:
            self.mesh.node *= scale

        if scale is None:
            self.node, d = self.surface.project(
                self.space.interpolation_points())
        else:
            self.node, d = self.surface.project(
                self.space.interpolation_points() / scale)
            self.node *= scale

        self.meshtype = 'stri'
        self.ftype = mesh.ftype
        self.itype = mesh.itype
        self.nodedata = {}
        self.celldata = {}

    def vtk_cell_type(self):
        return 69

    def project(self, p):
        if self.scale is None:
            return self.surface.project(p)
        else:
            p, d = self.surface.project(p / self.scale)
            return p * self.scale, d * self.scale

    def integrator(self, k, etype='cell'):
        return TriangleQuadrature(k)

    def entity(self, etype=2):
        if etype in {'cell', 2}:
            return self.ds.cell
        elif etype in {'edge', 1}:
            return self.ds.edge
        elif etype in {'node', 0}:
            return self.mesh.node
        else:
            raise ValueError("`entitytype` is wrong!")

    def entity_measure(self, etype=2):
        p = self.p
        if etype in {'cell', 2}:
            return self.area(p + 1)
        elif etype in {'edge', 'face', 1}:
            return self.mesh.entity_measure('edge')
        else:
            raise ValueError("`entitytype` is wrong!")

    def entity_barycenter(self, etype=2):
        p = self.p
        return self.mesh.entity_barycenter(etype=etype)

    def number_of_nodes(self):
        return self.node.shape[0]

    def number_of_edges(self):
        return self.mesh.ds.NE

    def number_of_cells(self):
        return self.mesh.ds.NC

    def geo_dimension(self):
        return self.node.shape[1]

    def top_dimension(self):
        return 2

    def jacobi_matrix(self, bc, index=np.s_[:]):
        mesh = self.mesh
        cell2dof = self.space.dof.cell2dof

        grad = self.space.grad_basis(bc, index=index)
        # the tranpose of the jacobi matrix between S_h and K
        Jh = mesh.jacobi_matrix(index=index)

        # the tranpose of the jacobi matrix between S_p and S_h
        Jph = np.einsum('ijm, ...ijk->...imk', self.node[cell2dof[index], :],
                        grad)

        # the transpose of the jacobi matrix between S_p and K
        Jp = np.einsum('...ijk, imk->...imj', Jph, Jh)
        grad = np.einsum('ijk, ...imk->...imj', Jh, grad)
        return Jp, grad

    def normal(self, bc, index=None):
        Js, _, ps = self.surface_jacobi_matrix(bc, index=index)
        n = np.cross(Js[..., 0, :], Js[..., 1, :], axis=-1)
        return n, ps

    def surface_jacobi_matrix(self, bc, index=None):
        Jp, grad = self.jacobi_matrix(bc, index=index)
        ps = self.bc_to_point(bc, index=index)
        Jsp = self.surface.jacobi_matrix(ps)
        Js = np.einsum('...ijk, ...imk->...imj', Jsp, Jp)
        return Js, grad, ps

    def bc_to_point(self, bc, index=None):
        phi = self.space.basis(bc)
        cell2dof = self.space.dof.cell2dof
        if index is None:
            bcp = np.einsum('...ij, ijk->...ik', phi, self.node[cell2dof, :])
        else:
            bcp = np.einsum('...ij, ijk->...ik', phi,
                            self.node[cell2dof[index], :])

        bcp, _ = self.project(bcp)
        return bcp

    def area(self, q=3):
        integrator = self.integrator(q)
        bcs, ws = integrator.quadpts, integrator.weights
        Jp, _ = self.jacobi_matrix(bcs)
        n = np.cross(Jp[..., 0, :], Jp[..., 1, :], axis=-1)
        l = np.sqrt(np.sum(n**2, axis=-1))
        a = np.einsum('i, ij->j', ws, l) / 2.0
        return a

    def add_plot(self,
                 plot,
                 nodecolor='w',
                 edgecolor='k',
                 cellcolor=[0.5, 0.9, 0.45],
                 aspect='equal',
                 linewidths=1,
                 markersize=50,
                 showaxis=False,
                 showcolorbar=False,
                 cmap='rainbow'):

        if isinstance(plot, ModuleType):
            fig = plot.figure()
            fig.set_facecolor('white')
            axes = fig.gca()
        else:
            axes = plot
        return show_mesh_2d(axes,
                            self.mesh,
                            nodecolor=nodecolor,
                            edgecolor=edgecolor,
                            cellcolor=cellcolor,
                            aspect=aspect,
                            linewidths=linewidths,
                            markersize=markersize,
                            showaxis=showaxis,
                            showcolorbar=showcolorbar,
                            cmap=cmap)

    def find_node(self,
                  axes,
                  node=None,
                  index=None,
                  showindex=False,
                  color='r',
                  markersize=100,
                  fontsize=24,
                  fontcolor='k'):

        if node is None:
            node = self.node

        if (index is None) and (showindex is True):
            index = np.array(range(node.shape[0]))

        find_node(axes,
                  node,
                  index=index,
                  showindex=showindex,
                  color=color,
                  markersize=markersize,
                  fontsize=fontsize,
                  fontcolor=fontcolor)

    def find_edge(self,
                  axes,
                  index=None,
                  showindex=False,
                  color='g',
                  markersize=150,
                  fontsize=24,
                  fontcolor='k'):

        find_entity(axes,
                    self.mesh,
                    entity='edge',
                    index=index,
                    showindex=showindex,
                    color=color,
                    markersize=markersize,
                    fontsize=fontsize,
                    fontcolor=fontcolor)

    def find_cell(self,
                  axes,
                  index=None,
                  showindex=False,
                  color='y',
                  markersize=200,
                  fontsize=24,
                  fontcolor='k'):

        find_entity(axes,
                    self.mesh,
                    entity='cell',
                    index=index,
                    showindex=showindex,
                    color=color,
                    markersize=markersize,
                    fontsize=fontsize,
                    fontcolor=fontcolor)
Example #4
0
    def test_interpolation_plane(self):
        def u(p):
            x = p[..., 0]
            y = p[..., 1]
            return x * y

        node = np.array([(0, 0), (1, 0), (1, 1), (0, 1)], dtype=np.float)
        cell = np.array([(1, 2, 0), (3, 0, 2)], dtype=np.int)
        mesh = TriangleMesh(node, cell)

        node = mesh.entity('node')
        cell = mesh.entity('cell')
        tritree = Tritree(node, cell)
        mesh = tritree.to_conformmesh()

        space = LagrangeFiniteElementSpace(mesh, p=2)
        uI = space.interpolation(u)
        error0 = space.integralalg.L2_error(u, uI)

        fig = plt.figure()
        axes = fig.gca()
        mesh.add_plot(axes)
        mesh.find_node(axes, node=space.interpolation_points(), showindex=True)

        data = tritree.interpolation(uI)
        options = tritree.adaptive_options(method='numrefine',
                                           data={"q": data},
                                           maxrefine=1,
                                           p=2)
        if 1:
            #eta = space.integralalg.integral(lambda x : uI.grad_value(x)**2, celltype=True, barycenter=True)
            #eta = eta.sum(axis=-1)
            eta = np.array([1, 0], dtype=np.int)
            tritree.adaptive(eta, options)
        else:
            tritree.uniform_refine(options=options)

        fig = plt.figure()
        axes = fig.gca()
        tritree.add_plot(axes)
        tritree.find_node(axes, showindex=True)

        mesh = tritree.to_conformmesh(options)
        space = LagrangeFiniteElementSpace(mesh, p=2)
        data = options['data']['q']
        uh = space.to_function(data)

        error1 = space.integralalg.L2_error(u, uh)

        data = tritree.interpolation(uh)
        isLeafCell = tritree.is_leaf_cell()

        fig = plt.figure()
        axes = fig.gca()
        tritree.add_plot(axes)
        tritree.find_node(axes,
                          node=space.interpolation_points(),
                          showindex=True)
        tritree.find_cell(axes, index=isLeafCell, showindex=True)

        options = tritree.adaptive_options(method='numrefine',
                                           data={"q": data},
                                           maxrefine=1,
                                           maxcoarsen=1,
                                           p=2)
        if 1:
            #eta = space.integralalg.integral(lambda x : uI.grad_value(x)**2, celltype=True, barycenter=True)
            #eta = eta.sum(axis=-1)
            eta = np.array([-1, -1, -1, -1, 0, 1], dtype=np.int)
            tritree.adaptive(eta, options)
        else:
            tritree.uniform_refine(options=options)

        mesh = tritree.to_conformmesh(options)
        space = LagrangeFiniteElementSpace(mesh, p=2)
        data = options['data']['q']
        uh = space.to_function(data)

        fig = plt.figure()
        axes = fig.gca()
        mesh.add_plot(axes)
        mesh.find_node(axes, node=space.interpolation_points(), showindex=True)
        mesh.find_cell(axes, showindex=True)

        error2 = space.integralalg.L2_error(u, uh)
        print(error0)
        print(error1)
        print(error2)
        plt.show()
Example #5
0
axes.set_axis_off()
edge0 = np.array([(0, 1), (0, 3), (1, 2), (1, 3), (2, 3)], dtype=np.int)
lines = a3.art3d.Line3DCollection(point[edge0], color='k', linewidths=2)
axes.add_collection3d(lines)
edge1 = np.array([(0, 2)], dtype=np.int)
lines = a3.art3d.Line3DCollection(point[edge1],
                                  color='gray',
                                  linewidths=2,
                                  alpha=0.5)
axes.add_collection3d(lines)
#mesh.add_plot(axes,  alpha=0.3)
mesh.find_point(axes, showindex=True, color='k', fontsize=20, markersize=100)

V = LagrangeFiniteElementSpace(mesh, degree)
ldof = V.number_of_local_dofs()
ipoints = V.interpolation_points()
cell2dof = V.dof.cell2dof[0]

ipoints = ipoints[cell2dof]

idx = np.arange(1, degree + 2)
idx = np.cumsum(np.cumsum(idx))

d = Delaunay(ipoints)
mesh2 = TetrahedronMesh(ipoints, d.simplices)
face = mesh2.ds.face
isFace = np.zeros(len(face), dtype=np.bool)
for i in range(len(idx) - 1):
    flag = np.sum((face >= idx[i]) & (face < idx[i + 1]), axis=-1) == 3
    isFace[flag] = True
face = face[isFace]
Example #6
0
import sys
import numpy as np
import matplotlib.pyplot as plt

from fealpy.mesh import MeshFactory
from fealpy.functionspace import LagrangeFiniteElementSpace


p = int(sys.argv[1])

mf = MeshFactory()
box = [0, 1, 0, 1]
mesh = mf.boxmesh2d(box, nx=1, ny=1, meshtype='tri')
space = LagrangeFiniteElementSpace(mesh, p=p)

ipoints = space.interpolation_points() # (gdof, 2)
cell2dof = space.cell_to_dof() 
print('cell2dof:')
for i, val in enumerate(cell2dof):
    print(i, ": ", val)

fig = plt.figure()
axes = fig.gca()
mesh.add_plot(axes)
mesh.find_node(axes, showindex=True, fontsize=24)
mesh.find_edge(axes, showindex=True, fontsize=22)
mesh.find_cell(axes, showindex=True, fontsize=20)

fig = plt.figure()
axes = fig.gca()
mesh.add_plot(axes)
Example #7
0
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

from fealpy.mesh import MeshFactory as MF
from fealpy.functionspace import LagrangeFiniteElementSpace

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

edge = mesh.entity('edge')

space1 = LagrangeFiniteElementSpace(mesh, p=1)
cell2dof = space1.cell_to_dof()
ips = space1.interpolation_points()
print('cell2dof:\n', cell2dof)
print('ips:\n', ips)

space2 = LagrangeFiniteElementSpace(mesh, p=2)
cell2dof = space2.cell_to_dof()
ips = space2.interpolation_points()
print('cell2dof:\n', cell2dof)
print('ips:\n', ips)

space3 = LagrangeFiniteElementSpace(mesh, p=3)
cell2dof = space3.cell_to_dof()
ips = space3.interpolation_points()
print('cell2dof:\n', cell2dof)
print('ips:\n', ips)
print('edge:\n', edge)