示例#1
0
 def shape(self, mesh, size=50):
     """Build mesh."""
     vf = np.vectorize(self.f)
     x = mesh.coordinates()[:, 0]
     y = mesh.coordinates()[:, 1]
     a = np.arctan2(y, x)
     x, y = [x * vf(a), y * vf(a)]
     mesh.coordinates()[:] = np.array([x, y]).transpose()
     boundary = BoundaryMesh(mesh, 'exterior')
     boundary.init()
     lst = [0]
     vs = list(vertices(boundary))
     while True:
         v = vs[lst[-1]]
         neighbors = set()
         for e in edges(v):
             neighbors.update(e.entities(0))
         neighbors.remove(v.index())
         neighbors = list(neighbors)
         k = 0
         if len(lst) > 1:
             if neighbors[0] == lst[-2]:
                 k = 1
         lst.append(neighbors[k])
         if lst[-1] == lst[0]:
             break
     lst = lst[:-1]
     points = boundary.coordinates()[lst]
     points = [Point(*p) for p in points]
     try:
         polygon = Polygon(points)
     except:
         polygon = Polygon(points[::-1])
     return generate_mesh(polygon, size)
示例#2
0
    def test_HarmonicSmoothing(self):

        print ""
        print "Testing HarmonicSmoothing::move(Mesh& mesh, " \
              "const BoundaryMesh& new_boundary)"

        # Create some mesh and its boundary
        mesh = UnitSquareMesh(10, 10)
        boundary = BoundaryMesh(mesh, 'exterior')

        # Move boundary
        disp = Expression(("0.3*x[0]*x[1]", "0.5*(1.0-x[1])"))
        boundary.move(disp)

        # Move mesh according to given boundary
        mesh.move(boundary)

        # Check that new boundary topology corresponds to given one
        boundary_new = BoundaryMesh(mesh, 'exterior')
        self.assertEqual(boundary.topology().hash(),
                         boundary_new.topology().hash())

        # Check that coordinates are almost equal
        err = sum(sum(abs(boundary.coordinates() \
                        - boundary_new.coordinates()))) / mesh.num_vertices()
        print "Current CG solver produced error in boundary coordinates", err
        self.assertAlmostEqual(err, 0.0, places=5)

        # Check mesh quality
        magic_number = 0.35
        rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
        self.assertTrue(rmin > magic_number)
示例#3
0
 def shape(self, mesh, size=50):
     """Build mesh."""
     vf = np.vectorize(self.f)
     x = mesh.coordinates()[:, 0]
     y = mesh.coordinates()[:, 1]
     a = np.arctan2(y, x)
     x, y = [x * vf(a), y * vf(a)]
     mesh.coordinates()[:] = np.array([x, y]).transpose()
     boundary = BoundaryMesh(mesh, 'exterior')
     boundary.init()
     lst = [0]
     vs = list(vertices(boundary))
     while True:
         v = vs[lst[-1]]
         neighbors = set()
         for e in edges(v):
             neighbors.update(e.entities(0))
         neighbors.remove(v.index())
         neighbors = list(neighbors)
         k = 0
         if len(lst) > 1:
             if neighbors[0] == lst[-2]:
                 k = 1
         lst.append(neighbors[k])
         if lst[-1] == lst[0]:
             break
     lst = lst[:-1]
     points = boundary.coordinates()[lst]
     points = [Point(*p) for p in points]
     try:
         polygon = Polygon(points)
     except:
         polygon = Polygon(points[::-1])
     return generate_mesh(polygon, size)
示例#4
0
def HiptmairMatrixSetupBoundary(mesh, N, M,dim):
    def boundary(x, on_boundary):
        return on_boundary

    # mesh.geometry().dim()
    path = os.path.abspath(os.path.join(inspect.getfile(inspect.currentframe()), ".."))
    # if __version__ == '1.6.0':
    gradient_code = open(os.path.join(path, 'DiscreteGradientSecond.cpp'), 'r').read()
    # else:
        # gradient_code = open(os.path.join(path, 'DiscreteGradient.cpp'), 'r').read()
    compiled_gradient_module = compile_extension_module(code=gradient_code)
    tic()
    if dim == 3:
        EdgeBoundary = BoundaryEdge(mesh)
        EdgeBoundary = numpy.sort(EdgeBoundary)[::2].astype("float_","C")
    else:
        B = BoundaryMesh(mesh,"exterior",False)
        EdgeBoundary = numpy.sort(B.entity_map(1).array().astype("float_","C"))
    end = toc()
    MO.StrTimePrint("Compute edge boundary indices, time: ",end)


    row =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C") #, dtype="intc")
    column =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C") #, dtype="intc")
    data =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C") #, dtype="intc")

    dataX =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C")
    dataY =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C")
    dataZ =  numpy.zeros(2*(mesh.num_edges()-EdgeBoundary.size), order="C")
    # print 2*(mesh.num_edges()-EdgeBoundary.size)

    tic()

    # c = compiled_gradient_module.ProlongationGrad(mesh, EdgeBoundary, dataX,dataY,dataZ, data, row, column)
    c = compiled_gradient_module.ProlongationGradBoundary(mesh, EdgeBoundary, dataX,dataY,dataZ, data, row, column)
    # u, indices = numpy.unique(row, return_index=True)
    # indices = numpy.concatenate((indices,indices+1),axis=1)
    # # print VertexBoundary
    # print row
    # # print numpy.concatenate((indices,indices+1),axis=1)
    # # print  data
    # row = row[indices]
    # column = column[indices]
    # data = data[indices]
    # print row
    end = toc()
    MO.StrTimePrint("Data for C and P created, time: ",end)
    C = coo_matrix((data,(row,column)), shape=(N, M)).tocsr()
    Px = coo_matrix((dataX,(row,column)), shape=(N, M)).tocsr()
    Py = coo_matrix((dataY,(row,column)), shape=(N, M)).tocsr()
    Pz = coo_matrix((dataZ,(row,column)), shape=(N, M)).tocsr()
    del dataX, dataY, dataZ, row,column, mesh, EdgeBoundary
    return C, [Px,Py,Pz]
示例#5
0
def BoundaryEdge(mesh):
    path = os.path.abspath(os.path.join(inspect.getfile(inspect.currentframe()), ".."))
    # if __version__ == '1.6.0':
    gradient_code = open(os.path.join(path, 'DiscreteGradientSecond.cpp'), 'r').read()
    # else:
    #     gradient_code = open(os.path.join(path, 'DiscreteGradient.cpp'), 'r').read()
    compiled_gradient_module = compile_extension_module(code=gradient_code)
    B = BoundaryMesh(mesh,"exterior",False)
    FaceBoundary = numpy.sort(B.entity_map(2).array().astype("float_","C"))
    EdgeBoundary =  numpy.zeros(3*FaceBoundary.size, order="C")
    c = compiled_gradient_module.FaceToEdgeBoundary(mesh, FaceBoundary, FaceBoundary.size, EdgeBoundary)
    return EdgeBoundary #numpy.sort(EdgeBoundary)[::2].astype("float_","C")
示例#6
0
def HiptmairBCsetupBoundary(C, P, mesh):

    dim = mesh.geometry().dim()
    tic()
    if dim == 3:
        EdgeBoundary = BoundaryEdge(mesh)
    else:
        B = BoundaryMesh(mesh,"exterior",False)
        EdgeBoundary = numpy.sort(B.entity_map(1).array().astype("int","C"))


    B = BoundaryMesh(mesh,"exterior",False)
    NodalBoundary = B.entity_map(0).array()#.astype("int","C")
    onelagrange = numpy.ones(mesh.num_vertices())
    onelagrange[NodalBoundary] = 0
    Diaglagrange = spdiags(onelagrange,0,mesh.num_vertices(),mesh.num_vertices())

    onemagnetiic = numpy.ones(mesh.num_edges())
    onemagnetiic[EdgeBoundary.astype("int","C")] = 0
    Diagmagnetic = spdiags(onemagnetiic,0,mesh.num_edges(),mesh.num_edges())

    del mesh
    tic()
    C = Diagmagnetic*C*Diaglagrange
    # C = C
    G = PETSc.Mat().createAIJ(size=C.shape,csr=(C.indptr, C.indices, C.data))
    end = toc()
    MO.StrTimePrint("BC applied to gradient, time: ",end)

    if dim == 2:
        tic()
        # Px = P[0]
        # Py = P[1]
        Px = Diagmagnetic*P[0]*Diaglagrange
        Py = Diagmagnetic*P[1]*Diaglagrange
        end = toc()
        MO.StrTimePrint("BC applied to Prolongation, time: ",end)
        P = [PETSc.Mat().createAIJ(size=Px.shape,csr=(Px.indptr, Px.indices, Px.data)),PETSc.Mat().createAIJ(size=Py.shape,csr=(Py.indptr, Py.indices, Py.data))]
    else:
        tic()
        # Px = P[0]
        # Py = P[1]
        # Pz = P[2]
        Px = Diagmagnetic*P[0]*Diaglagrange
        Py = Diagmagnetic*P[1]*Diaglagrange
        Pz = Diagmagnetic*P[2]*Diaglagrange
        end = toc()
        MO.StrTimePrint("BC applied to Prolongation, time: ",end)
        P = [PETSc.Mat().createAIJ(size=Px.shape,csr=(Px.indptr, Px.indices, Px.data)),PETSc.Mat().createAIJ(size=Py.shape,csr=(Py.indptr, Py.indices, Py.data)),PETSc.Mat().createAIJ(size=Pz.shape,csr=(Pz.indptr, Pz.indices, Pz.data))]
    del Px, Py, Diaglagrange
    return  G, P
示例#7
0
def test_HarmonicSmoothing():

    # Create some mesh and its boundary
    mesh = UnitSquareMesh(10, 10)
    boundary = BoundaryMesh(mesh, 'exterior')

    # Move boundary
    disp = Expression(("0.3*x[0]*x[1]", "0.5*(1.0-x[1])"))
    ALE.move(boundary, disp)

    # Move mesh according to given boundary
    ALE.move(mesh, boundary)

    # Check that new boundary topology corresponds to given one
    boundary_new = BoundaryMesh(mesh, 'exterior')
    assert boundary.topology().hash() == boundary_new.topology().hash()

    # Check that coordinates are almost equal
    err = sum(sum(abs(boundary.coordinates() \
                    - boundary_new.coordinates()))) / mesh.num_vertices()
    print("Current CG solver produced error in boundary coordinates", err)
    assert round(err - 0.0, 5) == 0

    # Check mesh quality
    magic_number = 0.35
    rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
    assert rmin > magic_number
def test_HarmonicSmoothing():
    #print("Testing HarmonicSmoothing::move(Mesh& mesh, "const BoundaryMesh& new_boundary)")

    # Create some mesh and its boundary
    mesh = UnitSquareMesh(10, 10)
    boundary = BoundaryMesh(mesh, 'exterior')

    # Move boundary
    disp = Expression(("0.3*x[0]*x[1]", "0.5*(1.0-x[1])"))
    boundary.move(disp)

    # Move mesh according to given boundary
    mesh.move(boundary)

    # Check that new boundary topology corresponds to given one
    boundary_new = BoundaryMesh(mesh, 'exterior')
    assert boundary.topology().hash() == boundary_new.topology().hash()

    # Check that coordinates are almost equal
    err = sum(sum(abs(boundary.coordinates() \
                    - boundary_new.coordinates()))) / mesh.num_vertices()
    print("Current CG solver produced error in boundary coordinates", err)
    assert round(err - 0.0, 5) == 0

    # Check mesh quality
    magic_number = 0.35
    rmin = MeshQuality.radius_ratio_min_max(mesh)[0]
    assert rmin > magic_number
示例#9
0
    def test_HarmonicSmoothing(self):

        print ""
        print "Testing HarmonicSmoothing::move(Mesh& mesh, " \
              "const BoundaryMesh& new_boundary)"

        # Create some mesh and its boundary
        mesh = UnitSquareMesh(10, 10)
        boundary = BoundaryMesh(mesh, 'exterior')

        # Move boundary
        disp = Expression(("0.3*x[0]*x[1]", "0.5*(1.0-x[1])"))
        boundary.move(disp)

        # Move mesh according to given boundary
        mesh.move(boundary)

        # Check that new boundary topology corresponds to given one
        boundary_new = BoundaryMesh(mesh, 'exterior')
        self.assertEqual(boundary.topology().hash(),
                         boundary_new.topology().hash())

        # Check that coordinates are almost equal
        err = sum(sum(abs(boundary.coordinates() \
                        - boundary_new.coordinates()))) / mesh.num_vertices()
        print "Current CG solver produced error in boundary coordinates", err
        self.assertAlmostEqual(err, 0.0, places=5)

        # Check mesh quality
        magic_number = 0.35
        self.assertTrue(mesh.radius_ratio_min()>magic_number)
示例#10
0
            cell_vtx = cell_vtx[:, :2]

        vertices = np.vstack([old_vtx, facet_vtx, cell_vtx])

        return vertices, cells, macro_map


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

if __name__ == '__main__':
    from dolfin import (UnitCubeMesh, MeshFunction, File, BoundaryMesh,
                        UnitSquareMesh)
    import matplotlib.pyplot as plt
    import operator

    mesh = BoundaryMesh(UnitCubeMesh(4, 4, 4), 'exterior')

    dual_mesh = DualMesh(mesh)
    mapping = dual_mesh.macro_map

    # We kept the mesh area unchanged
    old = sum(c.volume() for c in df.cells(mesh))
    dual = sum(c.volume() for c in df.cells(dual_mesh))
    assert abs(old - dual) < 1E-13

    # The overlap vertex of the patch has to be the same geometrical
    # point as the corresponding old mesh vertex
    x_old = mesh.coordinates()
    x_new = dual_mesh.coordinates()

    patch_vertices = []
示例#11
0
    def steepest_descent():
        o_u = [File("output/u_mesh%d.pvd" % i) for i in range(solver.N)]
        search = moola.linesearch.ArmijoLineSearch(start_stp=1)
        outmesh = File("output/steepest.pvd")
        extra_opts = 0
        r_step = 8
        max_it = 3 * r_step

        opts = 0
        rel_tol = 1e-4
        solver.solve()
        solver.eval_J()
        plot(solver.multimesh.part(1),
             color=colors[0],
             linewidth=0.75,
             zorder=0)
        b_mesh = BoundaryMesh(solver.multimesh.part(1), "exterior", True)
        plot(b_mesh,
             color=colors[0],
             linestyle="None",
             markersize=1,
             marker=markers[0],
             label="Iteration {}".format(0),
             zorder=1)

        J_it = [solver.J]
        J_i = J_it[0]
        i = 1
        while i <= max_it:
            outmesh << solver.multimesh.part(1)
            for k in range(solver.N):
                o_u[k] << solver.u.part(k)
            print("-" * 10)
            print("It: {0:1d}, J: {1:.5f}".format(i, J_it[-1]))
            solver.recompute_dJ()
            solver.generate_mesh_deformation()
            #solver.generate_H1_deformation()

            dJ_i = 0
            for j in range(1, solver.N):
                dJ_i += assemble(
                    action(solver.dJ_form[j - 1], solver.deformation[j - 1]))
            print("Gradient at current iteration {0:.2e}".format(dJ_i))

            def J_steepest(step):
                solver.update_multimesh(step)
                solver.solve()
                solver.eval_J()
                solver.get_checkpoint()
                return float(solver.J)

            def dJ0_steepest():
                return float(J_it[-1]), dJ_i

            def increase_opt_number():
                solver.vfac *= 2
                solver.bfac *= 2
                if opts < extra_opts:
                    return True
                else:
                    print("{0:d} optimizations done, exiting".format(opts + 1))
                    return False

            try:
                step_a = search.search(J_steepest, None, dJ0_steepest())
                print(
                    "Linesearch found decreasing step: {0:.2e}".format(step_a))
                # Backup in case step is too large
                backup_coordinates = [
                    solver.multimesh.part(k).coordinates().copy()
                    for k in range(1, solver.N)
                ]
                solver.update_multimesh(step_a)
                solver.set_checkpoint()
                solver.solve()

                solver.eval_J()
                J_it.append(solver.J)
                J_i = J_it[-1]
                if J_i > 0:
                    if i % r_step == 0:
                        print("Increasing volume and barycenter penalty")
                        solver.vfac *= 2
                        solver.bfac *= 2
                        solver.eval_J()
                        J_it.append(solver.J)
                    if i % r_step == 0:
                        b_mesh = BoundaryMesh(solver.multimesh.part(1),
                                              "exterior", True)
                        plot(b_mesh,
                             color=colors[i // r_step],
                             linestyle="None",
                             markersize=1,
                             marker=markers[i // r_step],
                             label="Iteration {}".format(i),
                             zorder=i // r_step + 2)

                    i += 1
                    search.start_stp = 1
                else:
                    # If Armjio linesearch returns an unfeasible
                    # functional value, literally deforming too much.
                    # We know that J in our problem has to be positive
                    # Decrease initial stepsize and retry
                    search.start_stp = 0.5 * step_a
                    for k in range(1, solver.N):
                        solver.multimesh.part(
                            k).coordinates()[:] = backup_coordinates[k - 1]
                    solver.multimesh.build()
                    for key in solver.cover_points.keys():
                        solver.multimesh.auto_cover(key,
                                                    solver.cover_points[key])
                    solver.set_checkpoint()
                    solver.solve()
                    solver.eval_J()
                    J_it[-1] = solver.J
                rel_reduction = abs(J_it[-1] - J_it[-2]) / abs(J_it[-2])
                if rel_reduction < rel_tol and solver.move_norm < rel_tol:
                    raise ValueError(
                        "Relative reduction less than {0:1e1}".format(rel_tol))
            except Warning:
                print("Linesearch could not find descent direction")
                print("Restart with stricter penalty")
                print("*" * 15)
                if not increase_opt_number():
                    break
                else:
                    # Reset linesearch
                    opts += 1
                    # In new optimization run, the deformed geometry
                    # should not have a higher functional value than the first
                    # iteration
                    J_i = J_it[0]
            except ValueError:
                print("Stopping criteria met")
                print("abs((J_k-J_k-1)/J_k)={0:.2e}<{1:.2e}".format(
                    rel_reduction, rel_tol))
                print("L^2(Gamma)(s)={0:.2e}<{1:.2e}".format(
                    solver.move_norm, rel_tol))
                print("Increase volume and barycenter penalty")
                print("*" * 15)
                if not increase_opt_number():
                    break
                else:
                    opts += 1
                    solver.solve()
                    solver.eval_J()
                    print("V_r {0:.2e}, Bx_r {1:.2e}, By_r {2:.2e}".format(
                        float(solver.Voloff / solver.Vol0),
                        float(solver.bxoff / solver.bx0),
                        float(solver.byoff / solver.by0)))
                    J_i = solver.J  # Old solution with new penalization
        print("V_r {0:.2e}, Bx_r {1:.2e}, By_r {2:.2e}".format(
            float(solver.Voloff / solver.Vol0) * 100,
            float(solver.bxoff / solver.bx0) * 100,
            float(solver.byoff / solver.by0) * 100))
        plot(solver.multimesh.part(1),
             zorder=2,
             color=colors[i // r_step],
             linewidth=1)
        plt.legend(prop={'size': 10}, markerscale=2)
        manager = plt.get_current_fig_manager()
        plt.tight_layout()
        manager.resize(*manager.window.maxsize())
        plt.axis("off")
        plt.savefig("StokesRugbyMeshes.png", dpi=300)
        import os
        os.system("convert StokesRugbyMeshes.png -trim StokesRugbyMeshes.png")
示例#12
0
 def BoundaryMesh(self):
     if self._boundary is None:
         self._boundary = BoundaryMesh(self.mesh, "exterior")
     return self._boundary