def generate_truss_by_grid(grid, enabled): """ enabled is a list of booleans indicating which members in the grid are enabled. Length must match the total possible members in the grid """ enabled = np.array(enabled) width = MIN_WIDTH / 2 height = MAX_HEIGHT all_possible_members = grid # print(f"number of possible members: {len(all_possible_members)}") assert len(all_possible_members) == len(enabled) members = all_possible_members[enabled] print(f"members selected: {len(members)}") # mirror the members to the right side members_mirror = np.copy(members) for member in members_mirror: for point in member: point[0] *= -1 point[0] += width * 2 members = np.append(members, members_mirror, axis=0) truss = SystemElements(EA=MODULUS_OF_ELASTICITY * BRASS_CROSS_SECTION_AREA, EI=MODULUS_OF_ELASTICITY * MOMENT_OF_INERTIA) for member in members: truss.add_truss_element(member) try: truss.add_support_hinged(node_id=truss.find_node_id(vertex=[0, 0])) truss.add_support_hinged(node_id=truss.find_node_id( vertex=[width * 2, 0])) return truss except: return None
def __init__(self, x, y, connections, loads, supports, density=880, unit='m', width=0.95 / 100, thick=1.8 / 1000, pop_compressive_strength=18100, pop_tensile_strength=70000): pop_cross_area = width * thick pop_mpl = pop_cross_area * density g = pop_mpl * 9.81 / 1000 unit_conv = 1 if (unit == 'cm'): unit_conv = (1 / 100) nodes = [[x[i] * unit_conv, y[i] * unit_conv] for i in range(len(x))] ss = SystemElements(EA=pop_cross_area * 8600000) for node1, node2 in connections: ss.add_element([nodes[node1], nodes[node2]], element_type='truss', g=g) for node in supports: id = ss.find_node_id(nodes[node]) ss.add_support_fixed(id) for node, load in loads: id = ss.find_node_id(nodes[node]) ss.point_load(id, Fy=-9.81 * load / 1000) ss.solve() self.ss = ss self.nodes = nodes self.connections = connections self.loads = loads self.supports = supports self.pop_mpl = pop_mpl self.cross_area = pop_cross_area self.compress = pop_compressive_strength self.tensile = pop_tensile_strength
from anastruct import SystemElements import math width = 15 height = 4 ss = SystemElements(EA=15000, EI=5000) ss.add_truss_element(location=[[0, 0], [0, height]]) ss.add_truss_element(location=[[0, 0], [width, 0]]) ss.add_truss_element(location=[[0, 4], [width, height]]) ss.add_truss_element(location=[[width, height], [width, 0]]) ss.add_truss_element(location=[[0, height], [width/4, 0]]) ss.add_truss_element(location=[[width/4*2, height], [width/4, 0]]) ss.add_truss_element(location=[[width/4*2, height], [width/4*3, 0]]) ss.add_truss_element(location=[[width, height], [width/4*3, 0]]) ss.add_support_fixed(node_id=ss.find_node_id(vertex=[0, 0])) ss.add_support_fixed(node_id=ss.find_node_id(vertex=[15, 0])) ss.point_load(Fy=-300, node_id=ss.find_node_id(vertex=[width/2, height])) ss.solve() # Get visual results. ss.show_structure() # ss.show_reaction_force() # ss.show_axial_force() # ss.show_shear_force() # ss.show_bending_moment() # ss.show_displacement()
def generate_truss(subdivide_mode=None, subdivides=None): """ Randomly generate a valid truss """ ss = SystemElements(EA=MODULUS_OF_ELASTICITY * BRASS_CROSS_SECTION_AREA, EI=MODULUS_OF_ELASTICITY * MOMENT_OF_INERTIA) width = MIN_WIDTH height = MAX_HEIGHT if not subdivide_mode: subdivide_mode = random.choice( ["triangle_subdivide", "radial_subdivide", "pillar_subdivide"]) if subdivide_mode == "triangle_subdivide": if not subdivides: subdivides = random.randint(1, 2) triangles = [ [ [[0, 0], [width, 0]], [[width, 0], [width / 2, height]], [[width / 2, height], [0, 0]], ], ] for _ in range(subdivides): new_triangles = [] for triangle in triangles: mids = [midpoint(*line) for line in triangle] new_triangles += [ [ [triangle[0][0], mids[0]], [mids[0], mids[2]], [mids[2], triangle[0][0]], ], [ [mids[2], mids[1]], [mids[1], triangle[2][0]], [triangle[2][0], mids[2]], ], [ [mids[0], triangle[1][0]], [triangle[1][0], mids[1]], [mids[1], mids[0]], ], [ [mids[2], mids[0]], [mids[0], mids[1]], [mids[1], mids[2]], ], ] triangles = new_triangles raw_lines = np.reshape(triangles, (-1, 2, 2)) # sort coordinates in each line raw_lines = [sorted(line, key=lambda p: p[0]) for line in raw_lines] # sort lines by first point's x value raw_lines = sorted(raw_lines, key=lambda l: l[0][0]) # remove duplicate lines lines = [] for line in raw_lines: is_duplicate = False for l in lines: if np.array_equal(line, l): is_duplicate = True if not is_duplicate: lines.append(line) for line in lines: ss.add_truss_element(location=line) elif subdivide_mode == "radial_subdivide": if not subdivides: subdivides = random.randint(1, 4) step_size = width / 2 / subdivides bottom_midpoint = midpoint([0, 0], [width, 0]) lines = [] for x in np.arange(0, width + 0.1, step_size): lines += [ [ bottom_midpoint, [ x, valmap(x, 0, width / 2, 0, height) if x <= width / 2 else valmap(x, width / 2, width, height, 0) ] ], ] lines[-1][1][1] = 0 # HACK: set last y value to 0 top_points = [p[1] for p in lines] top_lines = [] for i in range(1, len(top_points)): top_lines += [[top_points[i - 1], top_points[i]]] lines += top_lines for line in lines: ss.add_truss_element(location=line) elif subdivide_mode == "pillar_subdivide": if not subdivides: subdivides = random.randint(1, 4) step_size = width / 2 / subdivides lines = [] for x in np.arange(step_size, width, step_size): lines += [ [[x, 0], [ x, valmap(x, 0, width / 2, 0, height) if x <= width / 2 else valmap(x, width / 2, width, height, 0) ]], ] top_points = [p[1] for p in lines] edge_lines = [] for i in range(1, len(top_points)): edge_lines += [ [top_points[i - 1], top_points[i]], [[top_points[i - 1][0], 0], [top_points[i][0], 0]], ] if i < len(top_points) / 2: edge_lines += [ [[top_points[i - 1][0], 0], top_points[i]], ] else: edge_lines += [ [top_points[i - 1], [top_points[i][0], 0]], ] lines += [ [[0, 0], top_points[0]], [[0, 0], [top_points[0][0], 0]], [[width, 0], top_points[-1]], [[width, 0], [top_points[-1][0], 0]], ] lines += edge_lines for line in lines: ss.add_truss_element(location=line) ss.add_support_hinged(node_id=ss.find_node_id(vertex=[0, 0])) ss.add_support_hinged(node_id=ss.find_node_id(vertex=[width, 0])) return ss
for i in element_list: inicial = i.incidences_i final = i.incidences_f ss.add_element(location=[[inicial.x, inicial.y], [final.x, final.y]]) # for i in range(1, len(point_list)+1): # j = i+1 # for j in range(len(point_list)+1): # for element in element_list: # inicial = element.incidences_i # final = element.incidences_f # if i == int(inicial.name) and j == int(final.name): # ss.add_element(location=[[inicial.x,inicial.y], [final.x, final.y]]) for i in point_list: ponto = ss.find_node_id([i.x, i.y]) if i.x_fixed == True and i.y_fixed == False: ss.add_support_roll(node_id=ponto, direction=1) elif i.x_fixed == False and i.y_fixed == True: ss.add_support_roll(node_id=ponto, direction=2) elif i.x_fixed == True and i.y_fixed == True: ss.add_support_fixed(node_id=ponto) for i in load_list: ponto = ss.find_node_id( [point_list[int(i.point)-1].x, point_list[int(i.point)-1].y]) ss.point_load(node_id=ponto, Fx=int( i.intensity_x), Fy=int(i.intensity_y)) ss.show_structure() ss.solve()
ss.add_element([nodes[5],nodes_mid[5]], element_type='truss', g=g) ss.add_element([nodes[6],nodes_mid[5]], element_type='truss', g=g) ss.add_element([nodes[6],nodes_mid[6]], element_type='truss', g=g) ss.add_element([nodes[7],nodes_mid[6]], element_type='truss', g=g) ss.add_element([nodes[7],nodes_mid[7]], element_type='truss', g=g) ss.add_element([nodes[8],nodes_mid[7]], element_type='truss', g=g) ss.add_element([nodes[8],nodes_mid[8]], element_type='truss', g=g) ss.add_element([nodes[9],nodes_mid[8]], element_type='truss', g=g) #vertical beams at midpoints of triangles ss.add_element([nodes_mid[9],nodes_mid[4]], element_type='truss', g=g) ss.add_element([nodes[4],nodes[13]], element_type='truss', g=g) ss.add_element([nodes[5],nodes[14]], element_type='truss', g=g) for node in supports: id = ss.find_node_id(nodes[node]) ss.add_support_fixed(id) loads = [(4,9),(5,9)] for node, load in loads: id = ss.find_node_id(nodes_mid[node]) ss.point_load(id, Fy=-9.81*load/1000) ss.solve() def test(verbose=False): arr = ss.get_element_results() forces = [x['N'] for x in arr] if (verbose): print("Difference between maximum tens. pressure and tensile strength: {}".format(max(forces)/pop_cross_area - pop_tensile_strength))