Пример #1
0
def initializeLatticeShell(startPoint,
                           latticeParam,
                           xHexagons,
                           yHexagons,
                           force=10,
                           theta=0,
                           elasticModulus=17000000000,
                           moment=5000000,
                           area=0.0005,
                           g=0,
                           invertHex=True,
                           saveDir=None):
    '''
    This function takes in initial parameters for a hexagon lattice, creates
    a mesh structure using the anaStruct library object SystemElements(). First, 
    the center points of hexagons in the lattice will be generated, the hexagon 
    vertices will be saved in a custom NumPy array to save the center points and 
    al 6 vertices. 

    The numpy array will hold 7 tuples( 1 tuple for the center-point, 6 tuples for
    coordinates of each hexagon vertex. )

    Args: 

        (startPoint): 
            (tuple): Tuple of dtype=np.float64 or dtype=np.float32 housing the 
            original start point (bottom left) of the hexagon lattice to be constructed.
        (latticeParam): 
            (float): The length of each 'sub triangle' length starting from the center
            of the hexagon to each vertex. 
        (xHexagons): 
            (int): Number of hexagons to be constructed in the x-direction in the lattice.
        (yHexagons): 
            (int): Number of hexagons to be constructed in the y-direction in the lattice.
    
    Returns: 

        (lattice): 
            (SystemElements() Object): The system elements object containing all trusses
            defined and fully constrained. 
        (lattice_coordinatews): 
            (numpy array): Custom numpy array of shape=( xHexagons, yHexagons, 7, 2 ). 
            Contains 7 coordinates per hexagon: Center coords, and vertex coordinates.
    '''
    # Initialize finite element material parameters
    EA = elasticModulus * area
    EI = elasticModulus * moment
    # Initialize timer
    start = timeit.default_timer()

    # Initialize anaStruct.py SystemElements() object...
    # ss = SystemElements(figsize=(12,8), EA=15000.0, EI=5e3)
    ss = SystemElements(EA=EA, EI=EI)
    '''
    EA - Standard axial stiffness of element 
    EI - Standard bending stiffness of elements 
    figsize - Matplotlibs standard figure size (inches) 
    '''

    # Initialize custom numpy array...
    lattice_coordinates = np.empty(shape=(xHexagons + 1, yHexagons, 7, 2))

    # Take not of all elements that are already saved so we don't repeat them
    # Save initialized system elements points as an array to be referenfced when
    # creating new system elements to the FEM mesh.
    old_ss = []

    # Initialize hexagon lattice centers:
    lattice_centers = getHexagonLatticeCenters(startPoint,
                                               latticeParam,
                                               xHexagons,
                                               yHexagons,
                                               invertHex=invertHex)
    print(lattice_centers)

    # Iterate through each hexagon center and fill lattice_coordinates numpy array
    for j in range(yHexagons):

        # Every odd numbered row (0 start counting) will have 1 extra hexagon to be drawn in.
        if j % 2 != 0:
            xHexagonCount = xHexagons + 1
        else:
            xHexagonCount = xHexagons

        for i in range(xHexagonCount):

            # Get hexagon points
            curr_hexPoints = hexagonPoints(lattice_centers[i, j],
                                           latticeParam,
                                           invertHex=invertHex)

            # Initialize start point
            lattice_coordinates[i, j, 0] = lattice_centers[i, j]
            lattice_coordinates[i, j, 1:] = curr_hexPoints

            # Iterating through first hexagon being drawn
            if i == 0:

                # For even values:
                if j % 2 != 0:
                    # Finds the point pair list of the right half of the hexagon
                    point_pair_list = [
                        (curr_hexPoints[1], curr_hexPoints[0]),
                        (curr_hexPoints[0], curr_hexPoints[5]),
                        (curr_hexPoints[5], curr_hexPoints[4]),
                    ]
                    for k in range(3):

                        # Check if current element is already added
                        is_added, index = checkSystemElement(
                            point_pair_list[k][0], point_pair_list[k][1],
                            old_ss)

                        # Check if element exists
                        if is_added == False:
                            ss.add_element(location=[
                                point_pair_list[k][0], point_pair_list[k][1]
                            ],
                                           EA=EA,
                                           EI=EI,
                                           g=g)
                            old_ss.append(
                                (point_pair_list[k][0], point_pair_list[k][1]))
                        else:
                            print(
                                "Point Pair {} has already been added at index {} of old_ss list."
                                .format(curr_point_pair, index))

                else:
                    # Iterate through all point pairs:

                    for k in range(6):

                        curr_point_pair = (curr_hexPoints[k - 1],
                                           curr_hexPoints[k])
                        is_added, index = checkSystemElement(
                            curr_point_pair[0], curr_point_pair[1], old_ss)

                        # If element doesn't already exist, add it to the mesh
                        if is_added == False:

                            ss.add_element(location=[
                                curr_hexPoints[k - 1], curr_hexPoints[k]
                            ],
                                           EA=EA,
                                           EI=EI,
                                           g=g)
                            old_ss.append(
                                (curr_hexPoints[k - 1], curr_hexPoints[k]))

                        else:

                            # save elements added
                            # old_ss.append( curr_hexPoints[k-1], curr_hexPoints[k] )

                            # testing line --------------------
                            print(
                                "Point Pair {} has already been added at index {} of old_ss list."
                                .format(curr_point_pair, index))
                            # end testing line ------------------

            elif j % 2 != 0 and i == xHexagons:

                # Uneven row numbers
                if j % 2 != 0:
                    # Finds the point pair list of the right half of the hexagon
                    point_pair_list = [
                        (curr_hexPoints[1], curr_hexPoints[2]),
                        (curr_hexPoints[2], curr_hexPoints[3]),
                        (curr_hexPoints[3], curr_hexPoints[4]),
                    ]
                    for k in range(3):

                        # Check if current element is already added
                        is_added, index = checkSystemElement(
                            point_pair_list[k][0], point_pair_list[k][1],
                            old_ss)

                        # Check if element exists
                        if is_added == False:
                            ss.add_element(location=[
                                point_pair_list[k][0], point_pair_list[k][1]
                            ],
                                           EA=EA,
                                           EI=EI,
                                           g=g)
                            old_ss.append(
                                (point_pair_list[k][0], point_pair_list[k][1]))
                        else:
                            print(
                                "Point Pair {} has already been added at index {} of old_ss list."
                                .format(curr_point_pair, index))

                # Even hexagon values:
                else:

                    for k in range(6):

                        # check if current element is already added...if not, add it!
                        curr_point_pair = (curr_hexPoints[k - 1],
                                           curr_hexPoints[k])
                        is_added, index = checkSystemElement(
                            curr_point_pair[0], curr_point_pair[1], old_ss)

                        # If element doesn't already exist, add it to the mesh
                        if is_added == False:

                            ss.add_element(location=[
                                curr_hexPoints[k - 1], curr_hexPoints[k]
                            ],
                                           EA=EA,
                                           EI=EI,
                                           g=g)
                            old_ss.append(
                                (curr_hexPoints[k - 1], curr_hexPoints[k]))

                        else:

                            # save elements added
                            # old_ss.append( curr_hexPoints[k-1], curr_hexPoints[k] )

                            # testing line --------------------
                            print(
                                "Point Pair {} has already been added at index {} of old_ss list."
                                .format(curr_point_pair, index))
                            # end testing line ------------------

            # add all system elements and save point pairs
            else:

                for k in range(6):

                    # check if current element is already added...if not, add it!
                    curr_point_pair = (curr_hexPoints[k - 1],
                                       curr_hexPoints[k])
                    is_added, index = checkSystemElement(
                        curr_point_pair[0], curr_point_pair[1], old_ss)

                    # If element doesn't already exist, add it to the mesh
                    if is_added == False:

                        ss.add_element(location=[
                            curr_hexPoints[k - 1], curr_hexPoints[k]
                        ],
                                       EA=EA,
                                       EI=EI,
                                       g=g)
                        old_ss.append(
                            (curr_hexPoints[k - 1], curr_hexPoints[k]))

                    else:

                        # save elements added
                        # old_ss.append( curr_hexPoints[k-1], curr_hexPoints[k] )

                        # testing line --------------------
                        print(
                            "Point Pair {} has already been added at index {} of old_ss list."
                            .format(curr_point_pair, index))
                        # end testing line ------------------

    end = timeit.default_timer()

    total_time = np.round((end - start), 2)

    print(
        "\n\nGenerating hexagon mesh of x-y dimensions, {}-{}, lattice parameter, {},  took {} seconds.\n\n"
        .format(xHexagons, yHexagons, latticeParam, total_time))

    lowest_nodes = findLowestNodes(ss, startPoint, latticeParam, xHexagons,
                                   yHexagons)
    highest_nodes = findHighestNodes(ss, startPoint, latticeParam, xHexagons,
                                     yHexagons)

    # add supports and flattening elements
    for i in range(len(lowest_nodes)):

        ss.add_element(location=[lowest_nodes[i - 1][1], lowest_nodes[i][1]])
        old_ss.append((lowest_nodes[i - 1], lowest_nodes[i]))

        # add fixed support on lowest nodes...
        ss.add_support_fixed(node_id=lowest_nodes[i][0])

    # add forces and node locations
    for i in range(len(highest_nodes)):

        ss.add_element(location=[highest_nodes[i - 1][1], highest_nodes[i][1]])
        old_ss.append((highest_nodes[i - 1], highest_nodes[i]))

        # add forces at highest nodes...
        # ss.q_load(q=-1, element_id=highest_nodes[i], direction='element')
        ss.point_load(node_id=highest_nodes[i][0],
                      Fx=0,
                      Fy=force,
                      rotation=theta)

    # Solve and time it
    solveTimeStart = np.round(timeit.default_timer(), 2)
    ss.solve()
    solveTimeEnd = np.round(timeit.default_timer(), 2)
    total_solve_time = solveTimeEnd - solveTimeStart

    print(
        "\n\nSolving beam element model of x-y dimensions, {}-{}, lattice parameter, {},  took {} seconds.\n\n"
        .format(xHexagons, yHexagons, latticeParam, total_solve_time))

    # Calculate average displacement of nodes
    totalDisplacement = 0
    displacements = ss.get_node_displacements(node_id=0)
    for i in range(len(displacements)):
        totalDisplacement += np.sqrt(displacements[i][1]**2 +
                                     displacements[i][2]**2)
    averageDisplacements = totalDisplacement / len(displacements)

    print("\n\nAverage Node Displacement: {}mm".format(averageDisplacements *
                                                       1000))

    if saveDir != None:
        diagnosticData = []
        diagnosticData.append(
            "Hexagon Lattice ({}-x-hexagons,{}-y-hexagons)\n".format(
                xHexagons, yHexagons))
        diagnosticData.append("Lattice Parameter: {}mm\n".format(latticeParam))
        diagnosticData.append("Force: {}N\n".format(force))
        diagnosticData.append("Elastic Modulus: {}MPa\n".format(
            elasticModulus / 1000))
        diagnosticData.append("Second Moment of Area: {}\n".format(moment))
        diagnosticData.append("Area: {}mm\n".format(area * 1000))
        diagnosticData.append("Bending Stiffness: {}\n".format(elasticModulus *
                                                               moment))
        diagnosticData.append(
            "Average Displacement: {}mm\n".format(averageDisplacements))
        diagnosticData.append("Mesh Generated in {}s\n".format(total_time))
        diagnosticData.append(
            "Beam Element Model Solved in {}s\n".format(total_solve_time))

        folderDir = snr.createFolder(
            saveDir,
            "a={}mm A={}mm f={}N E={}MPa".format(latticeParam, area, force,
                                                 elasticModulus / 1000))
        textFile = open("{}\\diagnostics.txt".format(folderDir), 'w')
        textFile.writelines(diagnosticData)
        textFile.close()

        # beam element model is solved in the call of this function.
        saveElementModel(
            ss, folderDir,
            "a={}mm A={}mm f={}N E={}MPa".format(latticeParam, area, force,
                                                 elasticModulus / 1000))

    return ss
def trussbridge(Ediag,
                Adiag,
                Ebot,
                Abot,
                Etop,
                Atop,
                p,
                w_tri=4,
                h_tri=2,
                num_tri=6,
                disp=False):
    """
    Calculate displacement of middle point in bridge truss

    Args:
         Ediag (list): list of Young's modulus for each pair of diagonal trusses (Pa)
         Adiag (list): list of cross-sectional area for each pair of diagonal trusses (m2)
         Ebot (list): list of Young's modulus for each bottom truss (Pa)
         Abot (list): list of cross-sectional area for each bottom truss (m2)
         Etop (list): list of Young's modulus for each top truss (Pa)
         Atop (list): list of cross-sectional area for each top truss (m2)t
         p (list): list of force applied on the top nodes (N)
         num_tri (int): number of triangles
         disp (bool): display image or not

    """
    Ediag = np.array(Ediag)
    Adiag = np.array(Adiag)
    Ebot = np.array(Ebot)
    Abot = np.array(Abot)
    Etop = np.array(Etop)
    Atop = np.array(Atop)
    EAdiag = Ediag * Adiag
    EAbot = Ebot * Abot
    EAtop = Etop * Atop

    ss = SystemElements()

    # Triangle coord
    x_base = np.arange(0, num_tri + 1) * w_tri
    x_top = np.arange(0, num_tri) * w_tri + h_tri
    y = np.ones(num_tri) * h_tri

    # Create 6 triangles
    for i in range(num_tri):
        p1 = [x_base[i], 0]
        p2 = [x_top[i], y[i]]
        p3 = [x_base[i + 1], 0]
        ss.add_truss_element(location=[p1, p2], EA=EAdiag[i])
        ss.add_truss_element(location=[p2, p3], EA=EAdiag[i])
        ss.add_truss_element(location=[p1, p3], EA=EAbot[i])

    # Create 5 horizontal trusses
    for i in range(num_tri - 1):
        ss.add_truss_element(location=[[x_top[i], y[i]],
                                       [x_top[i + 1], y[i + 1]]],
                             EA=EAtop[i])

    # Create support
    ss.add_support_hinged(node_id=1)
    ss.add_support_roll(node_id=13, direction=2)

    # Create Load
    loadnode = [2, 4, 6, 8, 12]
    for index, point in enumerate(loadnode):
        ss.point_load(node_id=point, Fy=p[index])
        ss.point_load(node_id=point, Fy=p[index])
        ss.point_load(node_id=point, Fy=p[index])
        ss.point_load(node_id=point, Fy=p[index])

    ss.solve()
    disp7 = ss.get_node_displacements(node_id=7)

    if disp is True:
        ss.show_axial_force()
        ss.show_displacement(factor=10)

    return disp7