Example #1
0
def cyclic3D(u):
    """ Symmetrize with respect to (xyz) cycle. """
    try:
        nrm = np.linalg.norm(u.vector())
        V = u.function_space()
        assert V.mesh().topology().dim() == 3
        mesh1 = Mesh(V.mesh())
        mesh1.coordinates()[:, :] = mesh1.coordinates()[:, [1, 2, 0]]
        W1 = FunctionSpace(mesh1, 'CG', 1)

        # testing if symmetric
        bc = DirichletBC(V, 1, DomainBoundary())
        test = Function(V)
        bc.apply(test.vector())
        test = interpolate(Function(W1, test.vector()), V)
        assert max(test.vector()) - min(test.vector()) < 1.1

        v1 = interpolate(Function(W1, u.vector()), V)

        mesh2 = Mesh(mesh1)
        mesh2.coordinates()[:, :] = mesh2.coordinates()[:, [1, 2, 0]]
        W2 = FunctionSpace(mesh2, 'CG', 1)
        v2 = interpolate(Function(W2, u.vector()), V)
        pr = project(u + v1 + v2)
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        print "Cyclic symmetrization failed!"
        return u
Example #2
0
def symmetrize(u, d, sym):
    """ Symmetrize function u. """
    if len(d) == 3:
        # three dimensions -> cycle XYZ
        return cyclic3D(u)
    elif len(d) >= 4:
        # four dimensions -> rotations in 2D
        return rotational(u, d[-1])
    nrm = np.linalg.norm(u.vector())
    V = u.function_space()
    mesh = Mesh(V.mesh())

    # test if domain is symmetric using function equal 0 inside, 1 on boundary
    # extrapolation will force large values if not symmetric since the flipped
    # domain is different
    bc = DirichletBC(V, 1, DomainBoundary())
    test = Function(V)
    bc.apply(test.vector())

    if len(d) == 2:
        # two dimensions given: swap dimensions
        mesh.coordinates()[:, d] = mesh.coordinates()[:, d[::-1]]
    else:
        # one dimension given: reflect
        mesh.coordinates()[:, d[0]] *= -1
    # FIXME functionspace takes a long time to construct, maybe copy?
    W = FunctionSpace(mesh, 'CG', 1)
    try:
        # testing
        test = interpolate(Function(W, test.vector()), V)
        # max-min should be around 1 if domain was symmetric
        # may be slightly above due to boundary approximation
        assert max(test.vector()) - min(test.vector()) < 1.1

        v = interpolate(Function(W, u.vector()), V)
        if sym:
            # symmetric
            pr = project(u + v)
        else:
            # antisymmetric
            pr = project(u - v)
        # small solution norm most likely means that symmetrization gives
        # trivial function
        assert np.linalg.norm(pr.vector()) / nrm > 0.01
        return pr
    except:
        # symmetrization failed for some reason
        print "Symmetrization " + str(d) + " failed!"
        return u
Example #3
0
    def before_first_compute(self, get):
        u = get("Velocity")
        assert len(u) == 2, "Can only compute stream function for 2D problems"
        V = u.function_space()
        spaces = SpacePool(V.mesh())
        degree = V.ufl_element().degree()
        V = spaces.get_space(degree, 0)

        psi = TrialFunction(V)
        self.q = TestFunction(V)
        a = dot(grad(psi), grad(self.q)) * dx()

        self.bc = DirichletBC(V, Constant(0), DomainBoundary())
        self.A = assemble(a)
        self.L = Vector()
        self.bc.apply(self.A)
        self.solver = KrylovSolver(self.A, "cg")
        self.psi = Function(V)
    return child_f

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

if __name__ == '__main__':
    from dolfin import (CompiledSubDomain, DomainBoundary, SubsetIterator,
                        UnitSquareMesh, Facet)
    from xii import EmbeddedMesh

    mesh = UnitSquareMesh(4, 4)
    surfaces = MeshFunction('size_t', mesh, 2, 0)
    CompiledSubDomain('x[0] > 0.5-DOLFIN_EPS').mark(surfaces, 1)

    # What should be trasfered
    f = MeshFunction('size_t', mesh, 1, 0)
    DomainBoundary().mark(f, 1)
    CompiledSubDomain('near(x[0], 0.5)').mark(f, 1)
    # Assign funky colors
    for i, e in enumerate(SubsetIterator(f, 1), 1): f[e] = i

    ch_mesh = EmbeddedMesh(surfaces, 1)
    ch_f = transfer_markers(ch_mesh, f)

    # Every color in child is found in parent and we get the midpoint right
    p_values, ch_values = list(f.array()), list(ch_f.array())

    for ch_value in set(ch_f.array()) - set((0, )):
        assert ch_value in p_values

        x = Facet(mesh, p_values.index(ch_value)).midpoint()
        y = Facet(ch_mesh, ch_values.index(ch_value)).midpoint()
Example #5
0
def union_mesh(meshes, tol=1E-12):
    '''Glue together meshes into a big one.'''
    assert meshes

    num_meshes = len(meshes)
    # Nothing to do
    if num_meshes == 1:
        return meshes[0]
    # Recurse
    if num_meshes > 2:
        return union_mesh([
            union_mesh(meshes[:num_meshes / 2 + 1]),
            union_mesh(meshes[num_meshes / 2 + 1:])
        ])

    gdim, = set(m.geometry().dim() for m in meshes)
    tdim, = set(m.topology().dim() for m in meshes)

    fdim = tdim - 1
    bdries = [MeshFunction('size_t', m, fdim, 0) for m in meshes]
    [DomainBoundary().mark(bdry, 1) for bdry in bdries]
    # We are after boundary vertices of both; NOTE that the assumption
    # here is that the meshes share only the boundary vertices
    [m.init(fdim) for m in meshes]
    [m.init(fdim, 0) for m in meshes]

    bdry_vertices0, bdry_vertices1 = map(
        list,
        (set(np.concatenate([f.entities(0) for f in SubsetIterator(bdry, 1)]))
         for bdry in bdries))

    x0, x1 = [m.coordinates() for m in meshes]

    x1 = x1[bdry_vertices1]
    shared_vertices = {}
    while bdry_vertices0:
        i = bdry_vertices0.pop()
        x = x0[i]
        # Try to match it
        dist = np.linalg.norm(x1 - x, 2, axis=1)
        imin = np.argmin(dist)
        if dist[imin] < tol:
            shared_vertices[bdry_vertices1[imin]] = i
            x1 = np.delete(x1, imin, axis=0)
            del bdry_vertices1[imin]

    mesh0, mesh1 = meshes
    # We make 0 the master - it adds all its vertices
    # The other on add all but those that are not shared
    unshared = list(
        set(range(mesh1.num_vertices())) - set(shared_vertices.keys()))

    merge_x = mesh0.coordinates()
    offset = len(merge_x)
    # Vertices of the merged mesh
    merge_x = np.row_stack([merge_x, mesh1.coordinates()[unshared]])
    # Mapping for cells from meshes
    lg1 = {k: v for v, k in enumerate(unshared, offset)}
    lg1.update(shared_vertices)
    # Collapse to list
    _, lg1 = zip(*sorted(lg1.items(), key=lambda v: v[0]))
    lg1 = np.array(lg1)

    mapped_cells = np.fromiter((lg1[v] for v in np.concatenate(mesh1.cells())),
                               dtype='uintp').reshape((mesh1.num_cells(), -1))
    merged_cells = np.row_stack([mesh0.cells(), mapped_cells])

    merged_mesh = make_mesh(coordinates=merge_x,
                            cells=merged_cells,
                            tdim=tdim,
                            gdim=gdim)

    lg0 = np.arange(mesh0.num_vertices())
    # Mapping from leafs
    if not hasattr(mesh0, 'leafs'):
        merged_mesh.leafs = [(mesh0.id(), lg0)]
    else:
        merged_mesh.leafs = mesh0.leafs

    if not hasattr(mesh1, 'leafs'):
        merged_mesh.leafs.append([mesh1.id(), lg1])
    else:
        for id_, map_ in mesh1.leafs:
            merged_mesh.leafs.append((id_, lg1[map_]))

    return merged_mesh