Example #1
0
def make_z_mesh(num_vertices, zmin=0, zmax=1):
    '''{(0, 0, zmin + t*(zmax - zmin))}'''

    t = zmin + np.linspace(0, 1, num_vertices)*(zmax - zmin)
    coordinates = np.c_[np.zeros_like(t), np.zeros_like(t), t]
    cells = np.c_[np.arange(num_vertices - 1), np.arange(1, num_vertices)]
    cells.dtype = 'uintp'

    mesh = Mesh(mpi_comm_world())
    make_mesh(coordinates, cells, 1, 3, mesh)

    return mesh
Example #2
0
def dual_mesh(mesh, center='centroid', nrefs=1):
    '''        
    Dual mesh (from FVM) is triangles is obtained by dividing each triangle 
    into 6 new ones containing cell (mid point|circumcenter) and edge midpoints.
    '''
    # Base case
    if nrefs == 1:
        tdim, gdim = mesh.topology().dim(), mesh.geometry().dim()
        # Data for the mesh and mapping of old mesh vertex to cells of the dual patch
        coordinates, cells, mapping = dual_mesh_data(mesh, center)

        # Fill
        dmesh = make_mesh(coordinates=coordinates,
                          cells=cells,
                          tdim=tdim,
                          gdim=gdim)
        # Attach data
        dmesh.parent_entity_map = {mesh.id(): mapping}

        return dmesh

    # At least 2
    root_id = mesh.id()
    tdim = mesh.topology().dim()

    mesh0 = dual_mesh(mesh, center, nrefs=1)
    nrefs -= 1
    # Root will stay the same for those are the vertices that
    # were originally in the mesh and only those can be traced
    ref_vertices, root_vertices = zip(
        *mesh0.parent_entity_map[mesh.id()][0].items())

    while nrefs > 0:
        nrefs -= 1

        mesh1 = dual_mesh(mesh0, center, nrefs=1)
        # Upda mesh1 mapping
        mapping0, = mesh0.parent_entity_map.values()
        mapping1, = mesh1.parent_entity_map.values()

        new_mapping = {}
        # New cells fall under some parent
        e_mapping0, e_mapping1 = mapping0[tdim], mapping1[tdim]
        new_mapping[tdim] = {k: e_mapping0[v] for k, v in e_mapping1.items()}
        # But that's not the case with vertices, we only look for root
        # ones in the new
        e_mapping1 = mapping1[0]
        ref_vertices = [
            ref_v for ref_v, coarse_v in e_mapping1.items()
            if coarse_v in ref_vertices
        ]
        assert len(ref_vertices) == len(root_vertices)
        new_mapping[0] = dict(zip(ref_vertices, root_vertices))

        mesh1.parent_entity_map = {root_id: new_mapping}

        mesh0 = mesh1

    return mesh0
Example #3
0
def line_mesh(branches, tol=1E-13):
    '''1d in 2d/3d mesh made up of branches. Branch = linked vertices'''
    it_branches = iter(branches)

    # In the mesh that we are building I want to put first the end nodes
    # of the branch and then the interior points of the branches as they
    # are visited.

    # Endpoints; first branch is not constrained and can add coordinates
    branch = next(it_branches)
    ext_nodes = branch[[0, -1]]

    ext_bounds = [(0, 1)]
    # For the other ones need to check collisions
    for branch in it_branches:
        endpoints = branch[[0, -1]]

        bounds = []
        for point in endpoints:
            dist_f = np.linalg.norm(ext_nodes - point, 2, axis=1)
            f_idx = np.argmin(dist_f)
            # Never seen this one
            if dist_f[f_idx] > tol:
                f_idx = len(ext_nodes)
                ext_nodes = np.vstack([ext_nodes, point])
            bounds.append(f_idx)
        ext_bounds.append(tuple(bounds))

    cells = []
    # For numbering the interior points we start with the next available
    fI = max(list(map(max, ext_bounds))) + 1  # Next avaiable
    for (fE, lE), branch in zip(ext_bounds, branches):
        int_nodes = branch[1:-1]

        if not len(int_nodes): continue

        # Get the node idices to encode cell connectivity
        lI = fI + len(int_nodes)
        vmap = np.r_[fE, np.arange(fI, lI), lE]

        # Actually add the coordinates
        ext_nodes = np.vstack([ext_nodes, int_nodes])

        # And the cells
        cells.extend(list(zip(vmap[:-1], vmap[1:])))

        # For next round
        fI = lI
    cells = np.array(cells, dtype='uintp').flatten()

    mesh = make_mesh(ext_nodes, cells, 1, ext_nodes.shape[1])

    return mesh
def cross_grid_refine(mesh):
    '''
    Cross section refine is

       x                      x   
      / \     becomes        /|\  
     /   \                  / x \
    /     \                / / \ \  
    x------x              x-------x
    '''
    x = mesh.coordinates()
    cells = mesh.cells()

    ncells, nvtx_cell = cells.shape
    assert any((nvtx_cell == 2, nvtx_cell == 3, nvtx_cell == 4
                and mesh.topology().dim() == 3))

    # Center points will be new coordinates
    xnew = np.mean(x[cells], axis=1)
    # Each cell gives rise to ...
    child2parent = np.empty(ncells * nvtx_cell, dtype='uintp')
    fine_cells = np.empty((ncells * nvtx_cell, nvtx_cell), dtype='uintp')
    # How we build new cells
    basis = map(list, combinations(range(nvtx_cell), nvtx_cell - 1))

    fc, center = 0, len(x)
    for pc, cell in enumerate(cells):
        for base in basis:
            fine_cells[fc, :] = np.r_[cell[base], center]
            child2parent[fc] = pc
            fc += 1
        center += 1

    tdim = mesh.topology().dim()
    fine_mesh = make_mesh(np.row_stack([x, xnew]), fine_cells, tdim,
                          mesh.geometry().dim())

    fine_mesh.set_parent(mesh)
    mesh.set_child(fine_mesh)

    fine_mesh.parent_entity_map = {
        mesh.id(): {
            0: dict(enumerate(range(mesh.num_vertices()))),
            tdim: dict(enumerate(child2parent))
        }
    }

    return fine_mesh
Example #5
0
    u = df.Function(df.FunctionSpace(mesh, 'CG', 1))
    op = Average(u, line_mesh, sq)

    from scipy.spatial import Delaunay
    from dolfin import File

    surface = render_avg_surface(op)

    nodes = np.row_stack(surface)
    tri = Delaunay(nodes)

    cells = np.fromiter(tri.simplices.flatten(),
                        dtype='uintp').reshape(tri.simplices.shape)

    bounded_volume = make_mesh(nodes, cells, tdim=2, gdim=3)
    File('foo.pvd') << bounded_volume

    # for points in surface

    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    for plane in surface:
        ax.plot3D(plane[:, 0],
                  plane[:, 1],
                  plane[:, 2],
                  marker='o',
                  linestyle='none')

    sq_integrate = lambda f, shape=sq, n=n, x0=x0: shape_integrate(
Example #6
0
def inner_point_refine(mesh, new_pts, strict):
    ''''
    Mesh refine by adding point inside each celll

       x                      x   
      / \     becomes        /|\  
     /   \                  / x \
    /     \                / / \ \  
    x------x              x-------x

    Strict is the rel tol for checing whether new_pts[i] is inside cell[i]
    '''
    x = mesh.coordinates()
    cells = mesh.cells()

    ncells, nvtx_cell = cells.shape
    assert any((nvtx_cell == 2, nvtx_cell == 3, nvtx_cell == 4
                and mesh.topology().dim() == 3))

    # Center points will be new coordinates
    xnew = new_pts(mesh)
    # We have to check for duplicates
    #if not unique_guarantee:
    #    pass
    if strict > 0:
        tol = mesh.hmin() * strict
        # The collision
        assert point_is_inside(xnew, x[cells], tol)

    # Each cell gives rise to ...
    child2parent = np.empty(ncells * nvtx_cell, dtype='uintp')
    fine_cells = np.empty((ncells * nvtx_cell, nvtx_cell), dtype='uintp')
    # How we build new cells
    basis = map(list, combinations(range(nvtx_cell), nvtx_cell - 1))

    fine_coords = np.row_stack([x, xnew])

    fc, center = 0, len(x)
    for pc, cell in enumerate(cells):
        for base in basis:
            new_cell = np.r_[cell[base], center]
            # Every new cell must be non-empty
            assert simplex_area(fine_coords[new_cell]) > 1E-15

            fine_cells[fc, :] = new_cell
            child2parent[fc] = pc
            fc += 1
        center += 1

    tdim = mesh.topology().dim()
    fine_mesh = make_mesh(fine_coords, fine_cells, tdim, mesh.geometry().dim())

    fine_mesh.set_parent(mesh)
    mesh.set_child(fine_mesh)

    fine_mesh.parent_entity_map = {
        mesh.id(): {
            0: dict(enumerate(range(mesh.num_vertices()))),
            tdim: dict(enumerate(child2parent))
        }
    }

    return fine_mesh
Example #7
0
def inner_point_refine(mesh, new_pts, strict, nrefs=1):
    r'''
    Mesh refine by adding point inside each celll

       x                      x   
      / \     becomes        /|\  
     /   \                  / x \
    /     \                / / \ \  
    x------x              x-------x

    Strict is the rel tol for checing whether new_pts[i] is inside cell[i]
    '''
    if nrefs > 1:
        root_id = mesh.id()
        tdim = mesh.topology().dim()

        mesh0 = inner_point_refine(mesh, new_pts, strict, 1)
        nrefs -= 1
        # Root will stay the same for those are the vertices that
        # were originally in the mesh and only those can be traced
        ref_vertices, root_vertices = zip(
            *mesh0.parent_entity_map[mesh.id()][0].items())

        while nrefs > 0:
            nrefs -= 1

            mesh1 = inner_point_refine(mesh0, new_pts, strict, 1)
            # Upda mesh1 mapping
            mapping0, = mesh0.parent_entity_map.values()
            mapping1, = mesh1.parent_entity_map.values()

            new_mapping = {}
            # New cells fall under some parent
            e_mapping0, e_mapping1 = mapping0[tdim], mapping1[tdim]
            new_mapping[tdim] = {
                k: e_mapping0[v]
                for k, v in e_mapping1.items()
            }
            # But that's not the case with vertices, we only look for root
            # ones in the new
            e_mapping1 = mapping1[0]
            ref_vertices = [
                ref_v for ref_v, coarse_v in e_mapping1.items()
                if coarse_v in ref_vertices
            ]
            assert len(ref_vertices) == len(root_vertices)
            new_mapping[0] = dict(zip(ref_vertices, root_vertices))

            mesh1.parent_entity_map = {root_id: new_mapping}

            mesh0 = mesh1

        return mesh0

    # One refinement
    x = mesh.coordinates()
    cells = mesh.cells()

    ncells, nvtx_cell = cells.shape
    assert any((nvtx_cell == 2, nvtx_cell == 3, nvtx_cell == 4
                and mesh.topology().dim() == 3))

    # Center points will be new coordinates
    xnew = new_pts(mesh)
    # We have to check for duplicates
    #if not unique_guarantee:
    #    pass
    if strict > 0:
        tol = mesh.hmin() * strict
        # The collision
        assert point_is_inside(xnew, x[cells], tol)

    # Each cell gives rise to ...
    child2parent = np.empty(ncells * nvtx_cell, dtype='uintp')
    fine_cells = np.empty((ncells * nvtx_cell, nvtx_cell), dtype='uintp')
    # How we build new cells
    basis = list(map(list, combinations(list(range(nvtx_cell)),
                                        nvtx_cell - 1)))

    fine_coords = np.row_stack([x, xnew])

    fc, center = 0, len(x)
    for pc, cell in enumerate(cells):
        for base in basis:
            new_cell = np.r_[cell[base], center]
            # Every new cell must be non-empty
            assert simplex_area(fine_coords[new_cell]) > 1E-15

            fine_cells[fc, :] = new_cell
            child2parent[fc] = pc
            fc += 1
        center += 1

    tdim = mesh.topology().dim()

    fine_mesh = make_mesh(fine_coords, fine_cells, tdim, mesh.geometry().dim())

    fine_mesh.parent_entity_map = {
        mesh.id(): {
            0: dict(enumerate(range(mesh.num_vertices()))),
            tdim: dict(enumerate(child2parent))
        }
    }

    return fine_mesh