Example #1
0
def test_make_1():
    coords = np.array([[0, 0], [1, 0], [1, 1], [0, 1.]])
    mesh = make_line_mesh(coords, close_path=True)

    assert np.linalg.norm(mesh.coordinates() - coords) < 1E-13
    cells = np.array([[0, 1], [1, 2], [2, 3], [0, 3]])

    assert np.linalg.norm(mesh.cells() - cells) < 1E-13, mesh.cells()
Example #2
0
def stitch(mesh, edges):
    '''Remove edge and stitch together vertices'''
    assert mesh.topology().dim() == 1

    vertices = list(range(mesh.num_vertices()))
    # We want to rewrite this such that given edges are
    # kept but based on their connectivity we perform stitches
    # changing other cells
    e2v = mesh.topology()(1, 0)
    # NOTE: by saying that edge is to be removed we're saying that its
    # vertices can be regarded as same. A piece of graph of connected
    # edges is thus a substitution rule that all vertices in that piece
    # can be condensed
    g = nx.Graph()
    g.add_edges_from(map(e2v, edges))

    rules = {}
    # Substitution rule
    for cc in sorted(nx.algorithms.connected_components(g), key=len):
        substitute = cc.pop()
        for node in cc:
            assert node not in rules
            rules[node] = substitute

    # Edges are definitely part of the new mesh. Some other cells might
    # be added as well if substitution produces two equal nodes
    edges = list(edges)
    # We want to keep a mapping from new mesh cell_idx to what was approx
    # the parent cells in the oritinal mesh
    cell_map, new_cells = [], []
    # Now we rewrite
    cells = mesh.cells().tolist()
    for cell_id, cell in enumerate(cells):
        if cell_id not in edges:
            # Subs
            if cell[0] in rules: cell[0] = rules[cell[0]]
            if cell[1] in rules: cell[1] = rules[cell[1]]
            # Invalid
            cell[0] == cell[1] and edges.append(cell_id)
            # A valid cell will keep it's position in new mesh
            if cell[0] != cell[1]:
                cell_map.append(cell_id)
                new_cells.append(cell)

    # Which vertices will be used; this is also a map from new to old
    vertex_map = list(set(sum(new_cells, [])))
    # Need to finally rewrte the cells this way; so vertex old -> new needed
    ivertex_map = {o: n for n, o in enumerate(vertex_map)}
    new_cells = np.fromiter((ivertex_map[v] for v in sum(new_cells, [])),
                            dtype='uintp').reshape((-1, 2))

    new_coordinates = mesh.coordinates()[vertex_map]

    return make_line_mesh(new_coordinates, new_cells), cell_map, vertex_map
Example #3
0
def test_make_2():
    coords = np.array([[0, 0, 2], [1, 0, 2], [1, 1, 2], [0, 1., 2]])
    cells = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])

    mesh = make_line_mesh(coords, cells=cells)
    assert np.linalg.norm(mesh.coordinates() - coords) < 1E-13

    cells = np.array([[0, 1], [1, 2], [2, 3], [0, 3], [0, 2]])
    cells0 = np.array(map(sorted, mesh.cells()))

    assert np.linalg.norm(cells0 - cells) < 1E-13, mesh.cells()

    assert mesh.ufl_cell() == ufl.Cell('interval', 3)
Example #4
0
def refine(mesh, threshold):
    '''Refine such that the new mesh has cell size of at most dx'''
    assert mesh.topology().dim() == 1

    e2v = mesh.topology()(1, 0)

    cells = {old: [c.tolist()] for old, c in enumerate(mesh.cells())}
    x = mesh.coordinates()

    lengths = edge_lengths(mesh)
    needs_refine = find_edges(lengths, predicate=lambda v, x: v > threshold)

    next_v = len(x)
    for cell in needs_refine:
        v0, v1 = cells[cell].pop()
        x0, x1 = x[v0], x[v1]
        l = np.linalg.norm(x0 - x1)

        nodes = [v0]

        ts = np.linspace(0., 1., int(ceil(l / threshold)) + 1)[1:-1]
        dx = x1 - x0
        for t in ts:
            xmid = x0 + t * dx

            x = np.row_stack([x, xmid])

            nodes.append(next_v)
            next_v += 1

        nodes.append(v1)

        cells[cell] = list(zip(nodes[:-1], nodes[1:]))

    # Mapping for
    parent_cell_map = sum(([k] * len(cells[k]) for k in sorted(cells)), [])

    cells = np.array(sum((cells[k] for k in sorted(cells)), []), dtype='uintp')
    mesh = make_line_mesh(x, cells)

    return mesh, np.array(parent_cell_map, dtype='uintp')
Example #5
0
def curve_distance(edge_f, nlayers=4, outside_val=-1):
    '''
    Compute distance (P1) function that has for each vertex distance 
    from curve edge_f == 1.
    '''
    # Want to build a P1 function
    mesh = edge_f.mesh()
    V = df.FunctionSpace(mesh, 'CG', 1)
    d = df.Function(V)
    d_values = d.vector().get_local()
    # Default
    d_values[:] = outside_val

    # Want to set points layer by layer
    v2d = df.vertex_to_dof_map(V)
    layers = layer_neighbor_vertex_generator(edge_f, nlayers=nlayers + 1)

    curve_points = next(layers)
    # On curve is 0
    d_values[v2d[list(curve_points)]] = 0.

    x = mesh.coordinates()
    # For others we need to compute distance from edges
    mesh.init(1, 0)
    e2v = mesh.topology()(1, 0)
    segments = np.row_stack(map(e2v, np.where(edge_f.array() == 1)[0]))
    # In local numbering
    vtx_idx, segments = np.unique(segments.flatten(), return_inverse=True)

    line_mesh = make_line_mesh(x[vtx_idx], segments.reshape((-1, 2)))
    tree = line_mesh.bounding_box_tree()

    for points in map(list, layers):
        d_values[v2d[points]] = np.fromiter(
            (tree.compute_closest_entity(df.Point(x[p]))[1] for p in points),
            dtype=float)
    d.vector().set_local(d_values)

    return d
Example #6
0
def test():
    coords = np.array([[0, 0], [1, 0], [1, 0.2], [1, 0.5], [1, 0.7], [1, 1],
                       [0, 1.]])
    mesh = make_line_mesh(coords, close_path=True)

    rmesh, mapping = refine(mesh, threshold=0.6)

    x = mesh.coordinates()
    y = rmesh.coordinates()
    assert np.linalg.norm(x - y[:len(x)]) < 1E-13

    e2v, E2V = mesh.topology()(1, 0), rmesh.topology()(1, 0)
    for c in range(mesh.num_cells()):
        x0, x1 = x[e2v(c)]
        e = x1 - x0
        e = e / np.linalg.norm(e)

        for C in np.where(mapping == c)[0]:
            y0, y1 = y[E2V(C)]
            E = y1 - y0
            E = E / np.linalg.norm(E)

            assert abs(1 - abs(np.dot(e, E))) < 1E-13
Example #7
0
    # Mapping for
    parent_cell_map = sum(([k] * len(cells[k]) for k in sorted(cells)), [])

    cells = np.array(sum((cells[k] for k in sorted(cells)), []), dtype='uintp')
    mesh = make_line_mesh(x, cells)

    return mesh, np.array(parent_cell_map, dtype='uintp')


# --------------------------------------------------------------------

if __name__ == '__main__':
    coords = np.array([[0, 0], [1, 0], [1, 0.2], [1, 0.5], [1, 0.7], [1, 1],
                       [0, 1.]])
    mesh = make_line_mesh(coords, close_path=True)

    rmesh, mapping = refine(mesh, threshold=0.6)

    x = mesh.coordinates()
    y = rmesh.coordinates()
    assert np.linalg.norm(x - y[:len(x)]) < 1E-13

    e2v, E2V = mesh.topology()(1, 0), rmesh.topology()(1, 0)
    for c in range(mesh.num_cells()):
        x0, x1 = x[e2v(c)]
        e = x1 - x0
        e = e / np.linalg.norm(e)

        for C in np.where(mapping == c)[0]:
            y0, y1 = y[E2V(C)]
Example #8
0
from mbed.generation import make_line_mesh
from mbed.meshing import embed_mesh1d
import numpy as np
import sys

coords = np.array([[0, 0], [1, 0], [1, 1], [0, 1.]])
mesh1d = make_line_mesh(coords, close_path=True)

embed_mesh1d(mesh1d,
             bounding_shape=0.1,
             how='as_lines',
             gmsh_args=sys.argv,
             save_geo='model',
             save_msh='model',
             save_embedding='test_embed_line')

print()

embed_mesh1d(mesh1d,
             bounding_shape=0.1,
             how='as_points',
             gmsh_args=sys.argv,
             save_geo='model',
             save_msh='model',
             niters=2,
             save_embedding='test_embed_point')