Example #1
0
def create_forest(comm, depth, htarget):
    """
    Create an initial forest for analysis and optimization.

    This code loads in the model, sets names, meshes the geometry and creates
    an OctForest from the mesh. The forest is populated with octrees with
    the specified depth.

    Args:
        comm (MPI_Comm): MPI communicator
        depth (int): Depth of the initial trees
        htarget (float): Target global element mesh size

    Returns:
        OctForest: Initial forest for topology optimization
    """
    # Load the geometry model
    geo = TMR.LoadModel('../cantilever/cantilever.stp')

    # Mark the boundary condition faces
    verts = geo.getVertices()
    edges = geo.getEdges()
    faces = geo.getFaces()
    volumes = geo.getVolumes()

    faces[3].setName('fixed')
    faces[4].setSource(volumes[0], faces[5])
    verts[4].setName('pt1')
    verts[3].setName('pt2')

    # Set the boundary conditions for the problem
    bcs = TMR.BoundaryConditions()
    bcs.addBoundaryCondition('fixed')

    # Create the mesh
    mesh = TMR.Mesh(comm, geo)

    # Set the meshing options
    opts = TMR.MeshOptions()

    # Create the surface mesh
    mesh.mesh(args.htarget, opts)

    # Create a model from the mesh
    model = mesh.createModelFromMesh()

    # Create the corresponding mesh topology from the mesh-model
    topo = TMR.Topology(comm, model)

    # Create the quad forest and set the topology of the forest
    forest = TMR.OctForest(comm)
    forest.setTopology(topo)

    # Create the trees
    forest.createTrees(depth)

    return forest
Example #2
0
def create_forest(comm, depth, htarget):
    """
    Create an initial forest for analysis. and optimization

    This code loads in the model, sets names, meshes the geometry and creates
    a QuadForest from the mesh. The forest is populated with quadtrees with
    the specified depth.

    Args:
        comm (MPI_Comm): MPI communicator
        depth (int): Depth of the initial trees
        htarget (float): Target global element mesh size

    Returns:
        QuadForest: Initial forest for topology optimization
    """
    # Load the geometry model
    geo = TMR.LoadModel('biclamped_traction.stp')

    # Mark the boundary condition faces
    verts = geo.getVertices()
    edges = geo.getEdges()
    faces = geo.getFaces()

    edges[1].setName('fixed')
    edges[9].setName('fixed')
    edges[4].setName('traction')

    # Create the mesh
    mesh = TMR.Mesh(comm, geo)

    # Set the meshing options
    opts = TMR.MeshOptions()

    # Create the surface mesh
    mesh.mesh(htarget, opts)

    # Create a model from the mesh
    model = mesh.createModelFromMesh()

    # Create the corresponding mesh topology from the mesh-model
    topo = TMR.Topology(comm, model)

    # Create the quad forest and set the topology of the forest
    forest = TMR.QuadForest(comm)
    forest.setTopology(topo)

    # Set parameters for later usage
    forest.createTrees(depth)

    return forest
Example #3
0
    faces = [face]

    # Create the TMRModel
    geo = TMR.Model(verts, edges, faces)
    return geo


geo = create_panel(100.0, 100.0, use_hole=True)

# Create the mesh
comm = MPI.COMM_WORLD
mesh = TMR.Mesh(comm, geo)

# Mesh the part
opts = TMR.MeshOptions()
opts.num_smoothing_steps = 20
opts.write_mesh_quality_histogram = 1

# Mesh the geometry with the given target size
htarget = 10.0
mesh.mesh(htarget, opts=opts)
mesh.writeToVTK('surface-mesh.vtk')

# Create a model from the mesh
model = mesh.createModelFromMesh()

# Create the corresponding mesh topology from the mesh-model
topo = TMR.Topology(comm, model)

# Create the quad forest and set the topology of the forest
Example #4
0
def create_3d_unstruct_mesh(n, AR, prob, ratio1, ratio2, hole_r,
                            forced_portion, force_magnitude, MBB_bc_portion,
                            loaded_thickness, ly):

    comm = MPI.COMM_WORLD

    # Create the egads context
    ctx = egads.context()

    # dimensions
    Lx = ly * AR
    Ly = ly
    h = ly

    parts = []

    if prob == 'lbracket':
        # Create base
        x0 = [0, 0, 0]
        x1 = [Lx * ratio1, Ly * ratio2, h]
        B0 = ctx.makeSolidBody(egads.BOX, rdata=[x0, x1])
        parts.append(ctx.makeTopology(egads.MODEL, children=[B0]))

        # Create arm 1
        x0 = [0, Ly * ratio2, 0]
        x1 = [Lx * ratio1, Ly * (1 - ratio2), h]
        B1 = ctx.makeSolidBody(egads.BOX, rdata=[x0, x1])
        parts.append(ctx.makeTopology(egads.MODEL, children=[B1]))

        # Create arm 2
        x0 = [Lx * ratio1, 0, 0]
        x1 = [Lx * (1 - ratio1), Ly * ratio2, h]
        B2 = ctx.makeSolidBody(egads.BOX, rdata=[x0, x1])

        # Create the cylinder cutout
        xc = Lx * (ratio1 + 1) * 0.5
        yc = Ly * ratio2 * 0.5
        x0 = [xc, yc, 0]
        x1 = [xc, yc, h]
        r = hole_r * Ly * ratio2
        C1 = ctx.makeSolidBody(egads.CYLINDER, rdata=[x0, x1, r])
        parts.append(B2.solidBoolean(C1, egads.SUBTRACTION))

    else:
        # Create the box
        x0 = [0, 0, 0]
        x1 = [Lx, Ly, h]
        B1 = ctx.makeSolidBody(egads.BOX, rdata=[x0, x1])

        # Create the cylinder cutout
        xc = Lx / 2
        yc = Ly / 2
        x0 = [xc, yc, 0]
        x1 = [xc, yc, h]
        r = hole_r * Ly
        C1 = ctx.makeSolidBody(egads.CYLINDER, rdata=[x0, x1, r])
        # parts.append(ctx.makeTopology(egads.MODEL, children=[B1]))
        parts.append(B1.solidBoolean(C1, egads.SUBTRACTION))

    # Create all of the models
    geos = []
    for p in parts:
        geos.append(TMR.ConvertEGADSModel(p))

    # Create the full list of vertices, edges, faces and volumes
    verts = []
    edges = []
    faces = []
    vols = []
    for geo in geos:
        verts.extend(geo.getVertices())
        edges.extend(geo.getEdges())
        faces.extend(geo.getFaces())
        vols.extend(geo.getVolumes())

    # Set all of the matching faces
    TMR.setMatchingFaces(geos)

    # Create the geometry
    geo = TMR.Model(verts, edges, faces, vols)

    # Create the new mesh
    mesh = TMR.Mesh(comm, geo)

    # Set the meshing options
    opts = TMR.MeshOptions()
    # opts.mesh_type_default = TMR.UNSTRUCTURED
    opts.write_mesh_quality_histogram = 1
    opts.triangularize_print_iter = 50000

    # Create the surface mesh
    htarget = ly / n
    mesh.mesh(htarget, opts)

    # Write the surface mesh to a file
    # mesh.writeToVTK('block.vtk', 'hex')

    # Create the model from the unstructured volume mesh
    model = mesh.createModelFromMesh()

    # Create the corresponding mesh topology from the mesh-model
    topo = TMR.Topology(comm, model)

    # Create the quad forest and set the topology of the forest
    forest = TMR.OctForest(comm)
    forest.setTopology(topo)
    forest.createTrees()
    forest.balance(1)

    # Create the nodes
    forest.createNodes()

    # Get the mesh connectivity
    conn = forest.getMeshConn()
    nnodes = np.max(conn) + 1
    nelems = len(conn)

    # Get the node locations
    X = forest.getPoints()

    # Set boundary conditions
    dof = -np.ones((nnodes, 3), dtype=int)
    geo_bc_tol = 1e-6

    if prob == 'cantilever' or prob == 'michell':
        bc_x_max = geo_bc_tol
        bc_x_min = -geo_bc_tol
        bc_y_max = Ly + geo_bc_tol
        bc_y_min = -geo_bc_tol
        bc_z_max = h + geo_bc_tol
        bc_z_min = -geo_bc_tol

        ndof = 0
        for i in range(nnodes):
            if (bc_x_min <= X[i, 0] <= bc_x_max
                    and bc_y_min <= X[i, 1] <= bc_y_max
                    and bc_z_min <= X[i, 2] <= bc_z_max):
                # This is the bc node
                pass
            else:
                dof[i, 0] = ndof
                ndof += 1
                dof[i, 1] = ndof
                ndof += 1
                dof[i, 2] = ndof
                ndof += 1

    elif prob == 'MBB':
        bc1_x_max = geo_bc_tol
        bc1_x_min = -geo_bc_tol
        bc1_y_max = Ly + geo_bc_tol
        bc1_y_min = -geo_bc_tol
        bc1_z_max = h + geo_bc_tol
        bc1_z_min = -geo_bc_tol

        bc2_x_max = Lx + geo_bc_tol
        bc2_x_min = Lx * (1 - MBB_bc_portion) - geo_bc_tol
        bc2_y_max = geo_bc_tol + geo_bc_tol
        bc2_y_min = -geo_bc_tol
        bc2_z_max = h + geo_bc_tol
        bc2_z_min = -geo_bc_tol

        ndof = 0
        for i in range(nnodes):
            if (bc1_x_min <= X[i, 0] <= bc1_x_max
                    and bc1_y_min <= X[i, 1] <= bc1_y_max
                    and bc1_z_min <= X[i, 2] <= bc1_z_max):
                # This is the bc node
                dof[i, 1] = ndof
                ndof += 1
            elif (bc2_x_min <= X[i, 0] <= bc2_x_max
                  and bc2_y_min <= X[i, 1] <= bc2_y_max
                  and bc2_z_min <= X[i, 2] <= bc2_z_max):
                # This is also bc node
                dof[i, 0] = ndof
                ndof += 1
            else:
                dof[i, 0] = ndof
                ndof += 1
                dof[i, 1] = ndof
                ndof += 1
                dof[i, 2] = ndof
                ndof += 1

    elif prob == 'lbracket':
        bc_x_max = Lx * ratio1 + geo_bc_tol
        bc_x_min = -geo_bc_tol
        bc_y_max = Ly + geo_bc_tol
        bc_y_min = Ly - geo_bc_tol
        bc_z_max = h + geo_bc_tol
        bc_z_min = -geo_bc_tol

        ndof = 0
        for i in range(nnodes):
            if (bc_x_min <= X[i, 0] <= bc_x_max
                    and bc_y_min <= X[i, 1] <= bc_y_max
                    and bc_z_min <= X[i, 2] <= bc_z_max):
                # This is the bc node
                pass
            else:
                dof[i, 0] = ndof
                ndof += 1
                dof[i, 1] = ndof
                ndof += 1
                dof[i, 2] = ndof
                ndof += 1

    # Set loading
    force = np.zeros(ndof)
    geo_tol = 1e-6

    if prob == 'cantilever':
        load_x_max = Lx + geo_tol
        load_x_min = Lx - geo_tol
        load_y_max = Ly * forced_portion + geo_tol
        load_y_min = -geo_tol
        load_z_max = 0.5 * h * (1 + loaded_thickness)
        load_z_min = 0.5 * h * (1 - loaded_thickness)

        force_dir = 1
        force_scal = -1.0

    elif prob == 'MBB':
        load_x_max = Lx * MBB_bc_portion + geo_tol
        load_x_min = -geo_tol
        load_y_max = Ly + geo_tol
        load_y_min = Ly - geo_tol
        load_z_max = 0.5 * h * (1 + loaded_thickness) + geo_tol
        load_z_min = 0.5 * h * (1 - loaded_thickness) - geo_tol

        force_dir = 1
        force_scal = -1.0

    elif prob == 'michell':
        load_x_max = Lx + geo_tol
        load_x_min = Lx - geo_tol
        load_y_max = 0.5 * Ly * (1 + forced_portion) + geo_tol
        load_y_min = 0.5 * Ly * (1 - forced_portion) - geo_tol
        load_z_max = 0.5 * h * (1 + loaded_thickness) + geo_tol
        load_z_min = 0.5 * h * (1 - loaded_thickness) - geo_tol

        force_dir = 1
        force_scal = -1.0

    elif prob == 'lbracket':
        load_x_max = Lx + geo_tol
        load_x_min = Lx - geo_tol
        load_y_max = Ly * ratio2 + geo_tol
        load_y_min = Ly * ratio2 * (1 - forced_portion) - geo_tol
        load_z_max = 0.5 * h * (1 + loaded_thickness) + geo_tol
        load_z_min = 0.5 * h * (1 - loaded_thickness) - geo_tol

        force_dir = 1
        force_scal = -1.0

    nforce = 0
    for i in range(nnodes):
        if (load_x_min <= X[i, 0] <= load_x_max
                and load_y_min <= X[i, 1] <= load_y_max
                and load_z_min <= X[i, 2] <= load_z_max):
            force[dof[i, force_dir]] = force_scal * force_magnitude
            nforce += 1

    force /= nforce

    # for n in range(X.shape[0]):
    #     print('node:{:4d} x:{:6f} y:{:6f} z:{:6f}'.format(n, X[n, 0], X[n, 1], X[n, 2]))

    # for ne in range(conn.shape[0]):
    #     print('elem:{:4d} conn = [{:3d} {:3d} {:3d} {:3d}]'.format(ne, conn[ne,0], conn[ne,1], conn[ne,2], conn[ne,3]))

    return nelems, nnodes, ndof, conn, X, dof, force
def create_mesh(n, AR, prob, ratio1, ratio2, forced_portion, MBB_bc_portion,
    force_magnitude, use_concentrated_force, use_hole, hole_radius):

    Ly = 1.0
    Lx = Ly*AR

    # Create tmr geometry object
    geo = create_geo(AR, prob, forced_portion, MBB_bc_portion,
        ratio1, ratio2, use_hole, hole_radius)

    # Create the mesh
    comm = MPI.COMM_WORLD
    mesh = TMR.Mesh(comm, geo)

    # Mesh the part
    opts = TMR.MeshOptions()
    opts.frontal_quality_factor = 1.25
    opts.num_smoothing_steps = 20
    opts.write_mesh_quality_histogram = 1

    # Mesh the geometry with the given target size
    htarget = Ly / n
    mesh.mesh(htarget, opts=opts)

    # Create a model from the mesh
    model = mesh.createModelFromMesh()

    # Create the corresponding mesh topology from the mesh-model
    topo = TMR.Topology(comm, model)

    # Create the quad forest and set the topology of the forest
    forest = TMR.QuadForest(comm)
    forest.setTopology(topo)

    # Create random trees and balance the mesh. Print the output file
    forest.createTrees()
    forest.balance(1)

    # Create the nodes
    forest.createNodes()

    # Get the mesh connectivity
    conn = forest.getMeshConn()

    # Get the node locations
    X = forest.getPoints()

    # Set the nodal positions using only the x and y locations
    X = np.array(X[:,:2])

    # Get the nodes with the specified name
    if prob == 'cantilever':
        bcs = forest.getNodesWithName('5')
    elif prob == 'MBB':
        bc1 = forest.getNodesWithName('6')
        bc2 = forest.getNodesWithName('2')
    elif prob == 'michell':
        bcs = forest.getNodesWithName('6')
    elif prob == 'lbracket':
        bcs = forest.getNodesWithName('6')

    # Create the vars array with the number of nodes
    nnodes = np.max(conn)+1
    dof = np.zeros((nnodes, 2), dtype=int)

    # Set the vars to a negative index where we have a constraint
    if prob == 'MBB':

        # If it is MBB problem, we only fix x degree of freedom at left edge
        dof[bc1, 0] = -1
        dof[bc2, 1] = -1

    else:
        dof[bcs, :] = -1

    # Assign variables to the nodes
    ndof = 0
    for i in range(nnodes):
        if dof[i,0] >= 0:
            dof[i,0] = ndof
            ndof += 1
        if dof[i,1] >= 0:
            dof[i,1] = ndof
            ndof += 1

    # Set up the force vector
    force = np.zeros(ndof)

    # Assign the force vector
    if prob == 'cantilever':

        if use_concentrated_force:

            south_east_corner_node = -1
            xpos = X[0, 0]
            ypos = X[0, 0]
            for i in range(nnodes):
                if X[i, 0] >= xpos and X[i, 1] <= ypos:
                    south_east_corner_node = i
                    xpos = X[i, 0]
                    ypos = X[i, 1]

            force[dof[south_east_corner_node, 1]] = -force_magnitude

        else:

            quads_on_edge = forest.getQuadsWithName('2')

            for q in quads_on_edge:
                if q.info < 2:
                    n1 = q.info
                    n2 = q.info + 2
                else:
                    n1 = q.info//2
                    n2 = n1 + 1

                v1 = dof[conn[q.face, n1], 1]
                v2 = dof[conn[q.face, n2], 1]

                force[v1] = -force_magnitude
                force[v2] = -force_magnitude

            force[:] /= np.count_nonzero(force)

    elif prob == 'michell':

        if use_concentrated_force:

            distance = Lx**2 + Ly**2
            xtarget = Lx
            ytarget = Ly / 2
            middle_node = -1
            for i in range(nnodes):
                xpos = X[i, 0]
                ypos = X[i, 1]
                if (xpos-xtarget)**2 + (ypos-ytarget)**2 <= distance:
                    middle_node = i
                    distance = (xpos-xtarget)**2 + (ypos-ytarget)**2

            force[dof[middle_node, 1]] = -force_magnitude

        else:

            quads_on_edge = forest.getQuadsWithName('3')

            for q in quads_on_edge:
                if q.info < 2:
                    n1 = q.info
                    n2 = q.info + 2
                else:
                    n1 = q.info//2
                    n2 = n1 + 1

                v1 = dof[conn[q.face, n1], 1]
                v2 = dof[conn[q.face, n2], 1]

                force[v1] = -force_magnitude
                force[v2] = -force_magnitude

            force[:] /= np.count_nonzero(force)

    elif prob == 'MBB':

        if use_concentrated_force:

            distance = Lx**2 + Ly**2
            xtarget = 0
            ytarget = Ly
            north_west_node = -1
            for i in range(nnodes):
                xpos = X[i, 0]
                ypos = X[i, 1]
                if (xpos-xtarget)**2 + (ypos-ytarget)**2 <= distance:
                    north_west_node = i
                    distance = (xpos-xtarget)**2 + (ypos-ytarget)**2

            force[dof[north_west_node, 1]] = -force_magnitude

        else:

            quads_on_edge = forest.getQuadsWithName('5')

            for q in quads_on_edge:
                if q.info < 2:
                    n1 = q.info
                    n2 = q.info + 2
                else:
                    n1 = q.info//2
                    n2 = n1 + 1

                v1 = dof[conn[q.face, n1], 1]
                v2 = dof[conn[q.face, n2], 1]

                force[v1] = -force_magnitude
                force[v2] = -force_magnitude

            force[:] /= np.count_nonzero(force)


    elif prob == 'lbracket':

        if use_concentrated_force:

            distance = Lx**2 + Ly**2
            xtarget = Lx
            ytarget = Ly*ratio2
            middle_node = -1
            for i in range(nnodes):
                xpos = X[i, 0]
                ypos = X[i, 1]
                if (xpos-xtarget)**2 + (ypos-ytarget)**2 <= distance:
                    middle_node = i
                    distance = (xpos-xtarget)**2 + (ypos-ytarget)**2

            force[dof[middle_node, 1]] = -force_magnitude

        else:

            quads_on_edge = forest.getQuadsWithName('3')

            for q in quads_on_edge:
                if q.info < 2:
                    n1 = q.info
                    n2 = q.info + 2
                else:
                    n1 = q.info//2
                    n2 = n1 + 1

                v1 = dof[conn[q.face, n1], 1]
                v2 = dof[conn[q.face, n2], 1]

                force[v1] = -force_magnitude
                force[v2] = -force_magnitude

            force[:] /= np.count_nonzero(force)

    nelems = len(conn)

    return nelems, nnodes, ndof, conn, X, dof, force
Example #6
0
def create_forest(comm, depth, htarget):
    '''
    Load the 3D step file and convert it to a 2D model
    '''

    geo = TMR.LoadModel('battery_3d.step')
    verts = []
    edges = []
    faces = []
    all_faces = geo.getFaces()

    # Select only the facs on one face
    faces.append(all_faces[3])  # The structure's face
    faces.extend(all_faces[(len(all_faces) -
                            9):len(all_faces)])  # The face of the 9 batteries

    # Add only the verts and edges associated with the faces that we selected
    vert_ids = []
    edge_ids = []
    for f in faces:
        num_loops = f.getNumEdgeLoops()
        for i in range(num_loops):
            el = f.getEdgeLoop(i)
            edge_list, _ = el.getEdgeLoop()
            for e in edge_list:
                if e.getEntityId() not in edge_ids:
                    edges.append(e)
                    edge_ids.append(e.getEntityId())
                v1, v2 = e.getVertices()
                if v1.getEntityId() not in vert_ids:
                    verts.append(v1)
                    vert_ids.append(v1.getEntityId())
                if v2.getEntityId() not in vert_ids:
                    verts.append(v2)
                    vert_ids.append(v2.getEntityId())

    # Create the new 2D geometry model
    geo = TMR.Model(verts, edges, faces)

    # Name the faces that we need to use
    faces[7].setName('battery_0')  # Corner battery face
    faces[8].setName('battery_1')  # Adjacent battery
    faces[1].setName('battery_2')  # Diagonal battery
    faces[2].setName('battery')  # All the other batteries
    faces[3].setName('battery')
    faces[4].setName('battery')
    faces[5].setName('battery')
    faces[6].setName('battery')
    faces[9].setName('battery')
    faces[0].setName('aluminum')

    # Create the mesh object
    mesh = TMR.Mesh(comm, geo)

    # Mesh the part
    opts = TMR.MeshOptions()
    opts.write_mesh_quality_histogram = 1

    # Mesh the geometry with the given target size
    mesh.mesh(htarget, opts=opts)
    # mesh.writeToVTK('battery_mesh.vtk')

    # Create a model from the mesh
    model = mesh.createModelFromMesh()

    # Create the corresponding mesh topology from the mesh-model
    topo = TMR.Topology(comm, model)

    # Create the quad forest and set the topology of the forest
    forest = TMR.QuadForest(comm)
    forest.setTopology(topo)
    forest.createTrees(depth)

    return forest