Пример #1
0
def imgseq2funvec(img: np.array) -> np.array:
    """Takes a 3D array and returns an array suited to assign to piecewise
    linear approximation on a triangle grid.

    Each pixel corresponds to one vertex of a triangle mesh.

    Args:
        img (np.array): The input array.

    Returns:
        np.array: A vector.

    """
    # Create mesh.
    [m, n, o] = img.shape
    mesh = UnitCubeMesh(m-1, n-1, o-1)
    mc = mesh.coordinates().reshape((-1, 3))

    # Evaluate function at vertices.
    hx, hy, hz = 1./(m-1), 1./(n-1), 1./(o-1)
    x = np.array(np.round(mc[:, 0]/hx), dtype=int)
    y = np.array(np.round(mc[:, 1]/hy), dtype=int)
    z = np.array(np.round(mc[:, 2]/hz), dtype=int)
    fv = img[x, y, z]

    # Create function space.
    V = FunctionSpace(mesh, 'CG', 1)

    # Map pixel values to vertices.
    d2v = dof_to_vertex_map(V)
    return fv[d2v]
Пример #2
0
def generate_cube(Nelements, length, refinements=0):
    """
    Creates a square mesh of given elements and length with markers on
    the sides: left, bottom, right and top
    """
    from dolfin import UnitCubeMesh, SubDomain, MeshFunction, Measure, near, refine
    mesh = UnitCubeMesh(Nelements, Nelements, Nelements)
    for i in range(refinements):
        mesh = refine(mesh)
    mesh.coordinates()[:] *= length

    # Subdomains: Solid
    class Xp(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[0], length) and on_boundary

    class Xm(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[0], 0.0) and on_boundary

    class Yp(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[1], length) and on_boundary

    class Ym(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[1], 0.0) and on_boundary

    class Zp(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[2], length) and on_boundary

    class Zm(SubDomain):
        def inside(self, x, on_boundary):
            return near(x[2], 0.0) and on_boundary
    xp, xm, yp, ym, zp, zm = Xp(), Xm(), Yp(), Ym(), Zp(), Zm()
    XP, XM, YP, YM, ZP, ZM = 1, 2, 3, 4, 5, 6  # Set numbering

    markers = MeshFunction("size_t", mesh, 2)
    markers.set_all(0)

    boundaries = (xp, xm, yp, ym, zp, zm)
    def_names = (XP, XM, YP, YM, ZP, ZM)
    for side, num in zip(boundaries, def_names):
        side.mark(markers, num)

    return mesh, markers, XP, XM, YP, YM, ZP, ZM
Пример #3
0
    def test_vertex_3d(self):
        mesh = UnitCubeMesh(8, 8, 8)

        x = mesh.coordinates()
        min_ = np.min(x, axis=0)
        max_ = np.max(x, axis=0)

        tol = 1E-9  # The precision in gmsh isn't great, probably why DOLFIN's
        # periodic boundary computation is not working

        # Check x periodicity
        master = CompiledSubDomain('near(x[1], A, tol)', A=min_[1], tol=tol)
        slave = CompiledSubDomain('near(x[1], A, tol)', A=max_[1], tol=tol)

        shift_x = np.array([0, max_[1]-min_[1], 0])
        to_master = lambda x, shift=shift_x: x - shift

        error, mapping = compute_vertex_periodicity(mesh, master, slave, to_master)
        self.assertTrue(error < 10*tol)

        _, mapping = compute_entity_periodicity(2, mesh, master, slave, to_master)
        self.assertTrue(len(list(mapping.keys())) == 128)
Пример #4
0
def funvec2imgseq(v: np.array, m: int, n: int, o: int) -> np.array:
    """Takes values of piecewise linear interpolation of a function at the
    vertices and returns a 3-dimensional array.

    Each degree of freedom corresponds to one pixel in the array of
    size (m, n, o).

    Args:
        v (np.array): Values at vertices of triangle mesh.
        m (int): The number of rows.
        n (int): The number of columns.

    Returns:
        np.array: An array of size (m, n, o).

    """
    # Create image.
    img = np.zeros((m, n, o))

    # Create mesh and function space.
    mesh = UnitCubeMesh(m-1, n-1, o-1)
    mc = mesh.coordinates().reshape((-1, 3))

    # Evaluate function at vertices.
    hx, hy, hz = 1./(m-1), 1./(n-1), 1./(o-1)
    x = np.array(np.round(mc[:, 0]/hx), dtype=int)
    y = np.array(np.round(mc[:, 1]/hy), dtype=int)
    z = np.array(np.round(mc[:, 2]/hz), dtype=int)

    # Create function space and function.
    V = FunctionSpace(mesh, 'CG', 1)

    # Create image from function.
    v2d = vertex_to_dof_map(V)
    values = v[v2d]
    for (i, j, k, v) in zip(x, y, z, values):
        img[i, j, k] = v
    return img