def makestructure(nodes, segs, fixednodes, loadnodes, thicknesses, tensile=tensilePLA, totalload=100): ss = SystemElements() #loop through segments and create them for s, thickness in zip(segs, thicknesses): ss.add_truss_element(location=[nodes[s[0]], nodes[s[1]]], EA=tensile * thickness * strutwidth, g=0, spring={ 1: 0.0001, 2: 0.0001 }) # for f, supporttype in fixednodes: if supporttype == 'hinged': ss.add_support_hinged(node_id=f + 1) elif supporttype == 'roll': ss.add_support_roll(node_id=f + 1, direction='x') elif supporttype == 'fixed': ss.add_support_fixed(node_id=f + 1) #add in other types of supports here for l in loadnodes: ss.point_load(l + 1, Fx=0, Fy=-totalload / len(loadnodes)) return ss
def Beam_objective_funciton_BD(depths): #def fn(*args): #beam1 = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing); #beam1.moment_capcity() #beam1.min_spacing() #beam1.max_spacing() FS = SystemElements() # Add beams to the system. FS.add_element(location=[0, 5], EA=15000, EI=5000) FS.add_element(location=[[0, 5], [5, 5]], EA=15000, EI=5000) FS.add_element(location=[[5, 5], [5, 0]], EA=15000, EI=5000) # Add a fixed support at node 1. FS.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. FS.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. FS.point_load(Fx=30, node_id=2) FS.q_load(q=-10, element_id=2) FS.q_load(q=-10, element_id=1) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve FS.solve() FS.get_element_results(element_id=1)['length'] FS.get_element_results(element_id=1)['Mmin'] deno = FS.get_element_results(element_id=1)['Mmax'] #breadth = randgen(300,600) #Asc = 0 #Ast = 0 #spacing = 150 #beam = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing) #Asc = beam.p_min() #Ast = beam.p_min() #beam1 = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing) #beam1.moment_capcity() #beam1.min_spacing() #beam1.max_spacing() #print(beam1.moment_capcity()*10**(-3)) #print(FS.get_element_results(element_id=1)['Mmax']) res, depth_f = Beam_gene(depths, deno) C_D = res / deno #print() return C_D
def Beam_objective_funciton(breadth): depth = randgen(300,600) Asc = 0 Ast = 0 spacing = 150 beam = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing); Asc = beam.p_min Ast = beam.p_min beam1 = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing); beam1.moment_capcity() beam1.min_spacing() beam1.max_spacing() FS = SystemElements() # Add beams to the system. FS.add_element(location=[0, 5],EA=15000, EI=5000) FS.add_element(location=[[0, 5], [5, 5]],EA=15000, EI=5000) FS.add_element(location=[[5, 5], [5, 0]],EA=15000, EI=5000) # Add a fixed support at node 1. FS.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. FS.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. FS.point_load(Fx=30, node_id=2) FS.q_load(q=-10, element_id=2) FS.q_load(q=-10, element_id=1) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve FS.solve() FS.get_element_results(element_id=1)['length'] FS.get_element_results(element_id=1)['Mmin'] FS.get_element_results(element_id=1)['Mmax'] print(beam1.moment_capcity()*10**(-3)) print(FS.get_element_results(element_id=1)['Mmax'])
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
def test_struct1(): ss = SystemElements() ss.add_element([[-2, 2], [-1, 0]]) ss.add_element([[-2, 3], [-2, 2]]) ss.add_element([[-1, 4], [-2, 3]]) # ss.add_element([[-1, 4], [0, 5]]) # ss.add_element([[0, 5], [1, 5]]) # ss.add_element([[1, 5], [2, 5]]) # ss.add_element([[2, 5], [3, 5]]) # ss.add_element([[3, 5], [5, 2]]) ss.add_element([[-3, 4], [-2, 3]]) ss.add_element([[-4, 4], [-3, 4]]) ss.add_element([[-3, 5], [-3, 4]]) ss.add_element([[-2, 0], [-1, 0]]) ss.add_element([[-2, 1], [-2, 0]]) ss.add_element([[-2, -1], [-2, 0]]) ss.add_element([[-3, 0], [-2, 0]]) ss.add_element([[-4, 1], [-3, 0]]) ss.add_element([[-5, 2], [-4, 1]]) ss.add_element([[-4, -1], [-3, 0]]) ss.add_element([[-5, -2], [-4, -1]]) ss.add_element([[-1, 0], [0, 0]]) ss.add_element([[0, 0], [1, 0]]) ss.add_element([[2, 0], [3, 0]]) ss.add_element([[1, 0], [2, 0]]) ss.add_element([[2, 0], [3, 1]]) ss.point_load(10, 5) ss.moment_load(1, 15) # ss.add_element([[3, 1], [4, 1]]) # ss.add_element([[3, 1], [3, 2]]) # ss.add_element([[4, 1], [5, 2]]) # ss.add_element([[4, 1], [6, 2]]) ss.add_element([[1, 0], [-1, 1]]) ss.show_structure() ass = Assembler(ss) ass.assemble_structure(main_path=(15, 20)) # ass.assemble_structure(main_path=(7, 13)) # ass.plot_solve_order(ass.plot_order, show=True, save_figure=False, plotting_start_node=15) [[print(f"section {index + 1}-{sub_index + 1}: {sympify(sub_string, evaluate=False)}") for sub_index, sub_string in enumerate(string)] for index, string in enumerate(ass.sections_strings)]
def test_struct(): ss = SystemElements() ss.add_element([[0, 0], [1, 0]]) ss.add_element([[1, 0], [1, 1]]) ss.add_element([[1, 0], [2, 0]]) ss.add_element([[2, 0], [3, 0]]) ss.add_element([[3, 0], [4, 1]]) ss.add_element([[4, 1], [5, 1]]) ss.point_load(2, Fy=10) ss.point_load(3, Fy=-20, Fx=5) ss.point_load(4, Fy=-30) ss.point_load(5, Fx=-40) ss.moment_load(2, Ty=-9) ss.moment_load(1, 7) ss.moment_load(3, 3) ss.q_load(element_id=3, q=(-10, -20)) ss.q_load(element_id=5, q=(-10, -20)) ss.add_support_roll(4) ss.add_support_hinged(5) # ss.add_support_fixed(3) mn = Manager(ss) mn.generate_pdf(pdf_path=r"C:\testfolder")
def test_struct2(): ss = SystemElements() ss.add_element([[0, 0], [1, 0]]) ss.add_element([[1, 0], [1, 1]]) ss.add_element([[1, 0], [2, 0]]) ss.add_element([[2, 0], [3, 0]]) ss.add_element([[3, 0], [4, 1]]) ss.add_element([[4, 1], [5, 1]]) ss.point_load(2, Fy=10) ss.point_load(3, Fy=-20) ss.point_load(4, Fy=-30) ss.point_load(5, Fx=-40) ss.moment_load(2, Ty=-9) ss.moment_load(1, 7) ss.moment_load(3, 3) ss.q_load(element_id=3, q=(-10, -20)) ss.add_support_roll(4) ss.add_support_hinged(5) # ss.show_structure() ss.solve() ss.show_reaction_force(show=False) ass = Assembler(ss) ass.assemble_structure(main_path=Setting.longest) [print(element.id, values) for element, values in ass.internal_stresses_dict.items()]
ss = SystemElements() # Add beams to the system. ss.add_element(location=[0, 5], EA=15000, EI=5000) ss.add_element(location=[[0, 5], [5, 5]], EA=15000, EI=5000) ss.add_element(location=[[5, 5], [5, 0]], EA=15000, EI=5000) # Add a fixed support at node 1. ss.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. ss.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. ss.point_load(Fx=30, node_id=2) ss.q_load(q=-10, element_id=2) ss.q_load(q=-10, element_id=1) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve ss.solve() #print(ss.get_element_results(element_id=1)) #result = (ss.get_element_results(element_id=0, verbose=False)) ##for el_result in result: ## print(el_result['length']) ## print(el_result['Mmin']) ## print(el_result['Mmax']) for i in range(1, 4):
class connections: def __init__(self, main_window, main_window_functions): self.mw = main_window self.fn = main_window_functions self.ss = SystemElements() self.ss.color_scheme = "dark" self.was_solved = False self.states = [] def add_beam(self): try: self.workaround() e = self.mw.elementtype.currentIndex() if self.mw.utilizeinfo.isChecked(): EI = float(self.fn.filter(self.mw.beam_E.text())) * float( self.fn.filter(self.mw.beam_I.text())) EA = float(self.fn.filter(self.mw.beam_E.text())) * float( self.fn.filter(self.mw.beam_A.text())) element_types = ["beam", "truss"] self.ss.add_element(location=[ [ float(self.fn.filter(self.mw.beam_x1.text())), float(self.fn.filter(self.mw.beam_y1.text())) ], [ float(self.fn.filter(self.mw.beam_x2.text())), float(self.fn.filter(self.mw.beam_y2.text())) ] ], EI=EI, EA=EA, element_type=element_types[e]) else: self.ss.add_element( location=[[ float(self.fn.filter(self.mw.beam_x1.text())), float(self.fn.filter(self.mw.beam_y1.text())) ], [ float(self.fn.filter( self.mw.beam_x2.text())), float(self.fn.filter(self.mw.beam_y2.text())) ]]) self.visualize_structure() self.states.append(pickle.dumps(self.ss)) except: self.fn.warning() def beam_info(self): if self.mw.utilizeinfo.isChecked(): self.mw.frame_4.setHidden(False) else: self.mw.frame_4.setHidden(True) def element_type_list(self): if self.mw.elementtype.currentIndex() == 1: self.mw.beam_I.setEnabled(False) elif self.mw.elementtype.currentIndex() == 0: self.mw.beam_I.setEnabled(True) def add_node(self): try: if int(self.mw.node_id.text()) in self.ss.node_map.keys(): self.workaround() self.ss.insert_node(element_id=int(self.mw.node_id.text()), location=[ self.fn.filter(self.mw.node_x.text()), self.fn.filter(self.mw.node_y.text()) ]) self.mw.last_figure.click() self.states.append(pickle.dumps(self.ss)) else: self.fn.invalid_id_warning() except: self.fn.warning() def add_support(self): try: if int(self.mw.support_pos.text()) in self.ss.node_map.keys(): self.workaround() if self.mw.support_hinged.isChecked(): self.ss.add_support_hinged( node_id=int(self.mw.support_pos.text())) elif self.mw.support_roll.isChecked(): self.ss.add_support_roll( node_id=int(self.mw.support_pos.text()), angle=float( self.fn.filter(self.mw.support_angle.text()))) elif self.mw.support_fixed.isChecked(): self.ss.add_support_fixed( node_id=int(self.mw.support_pos.text())) elif self.mw.support_spring.isChecked(): self.ss.add_support_spring( node_id=int(self.mw.support_pos.text()), translation=self.mw.spring_translation.text(), k=self.mw.spring_k.text()) elif self.mw.support_internal_hinge.isChecked(): pass self.mw.last_figure.click() self.states.append(pickle.dumps(self.ss)) self.fn.enable_buttons() else: self.fn.invalid_id_warning() except: self.fn.warning() def show_support_stuff(self): if self.mw.support_roll.isChecked(): self.mw.support_angle.setHidden( True) # Always true due to anaStruct bug self.mw.label_113.setHidden( True) # Always true due to anaStruct bug self.mw.label_27.setHidden( True) # Always true due to anaStruct bug self.mw.label_71.setHidden(True) self.mw.label_73.setHidden(True) self.mw.spring_k.setHidden(True) self.mw.spring_translation.setHidden(True) elif self.mw.support_spring.isChecked(): self.mw.label_71.setHidden(False) self.mw.label_73.setHidden(False) self.mw.spring_k.setHidden(False) self.mw.spring_translation.setHidden(False) self.mw.support_angle.setHidden( True) # Always true due to anaStruct bug self.mw.label_27.setHidden(True) self.mw.label_127.setHidden(False) else: self.mw.support_angle.setHidden( True) # Always true due to anaStruct bug self.mw.label_27.setHidden(True) self.mw.label_71.setHidden(True) self.mw.label_73.setHidden(True) self.mw.spring_k.setHidden(True) self.mw.label_113.setHidden(True) self.mw.label_127.setHidden(True) self.mw.spring_translation.setHidden(True) def add_point_load(self): try: if int(self.mw.load_pos.text()) in self.ss.node_map.keys(): self.workaround() if self.mw.load_moment.text() != '' and float( self.mw.load_moment.text()) != 0: self.ss.moment_load( node_id=int(self.mw.load_pos.text()), Ty=float(self.fn.filter(self.mw.load_moment.text()))) if float(self.mw.load_y.text()) == 0 and float( self.mw.load_x.text()) == 0 and float( self.mw.load_angle.text()) == 0: pass elif self.mw.load_y.text() != '' and self.mw.load_x.text( ) != '' and self.mw.load_angle.text() != '': self.ss.point_load( node_id=int(self.mw.load_pos.text()), Fy=float(self.fn.filter(self.mw.load_y.text())), Fx=float(self.fn.filter(self.mw.load_x.text())), rotation=float( self.fn.filter(self.mw.load_angle.text()))) self.mw.last_figure.click() self.states.append(pickle.dumps(self.ss)) self.fn.enable_buttons() else: self.fn.invalid_id_warning() except: self.fn.warning() def add_q_load(self): try: if int(self.mw.qload_pos.text()) in self.ss.node_map.keys(): if float(self.mw.qload_initial.text()) >= 0 and float(self.mw.qload_final.text()) >= 0 or \ float(self.mw.qload_initial.text()) <= 0 and float(self.mw.qload_final.text()) <= 0: self.workaround() if self.mw.qload_initial.text() == '': self.mw.qload_final.setText( self.fn.filter(self.mw.qload_final.text())) if self.mw.qload_final.text() == '': self.mw.qload_final.setText( self.fn.filter(self.mw.qload_initial.text())) self.ss.q_load( element_id=int(self.mw.qload_pos.text()), q=(float(self.fn.filter(self.mw.qload_initial.text())), float(self.fn.filter(self.mw.qload_final.text())))) self.mw.last_figure.click() self.states.append(pickle.dumps(self.ss)) self.fn.enable_buttons() else: msg = QMessageBox() msg.setWindowTitle(self.mw.warning_title) msg.setText(self.mw.qload_warning) msg.setIcon(QMessageBox.Warning) x = msg.exec_() else: self.fn.invalid_id_warning() except: self.fn.warning() def visualize_structure(self): if self.ss.element_map: self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) self.fn.visualize( self.ss.show_structure(show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) ax.patch.set_alpha(0.2) self.mw.last_figure = self.mw.show_structure else: self.mw.MplWidget.plot(has_grid=self.mw.gridBox.isChecked()) self.fn.figurefix() self.mw.last_figure = None def visualize_diagram(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_structure(show=False, free_body_diagram=1, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_diagram def visualize_supports(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_reaction_force( show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_supports def visualize_normal(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_axial_force(show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_normal def visualize_shear(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_shear_force(show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_shear def visualize_moment(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_bending_moment( show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_moment def visualize_displacement(self): self.solve() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_displacement(show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.mw.last_figure = self.mw.show_displacement def solve(self): self.was_solved = True self.ss.solve() def static_solver(self, clean=True): if find_executable('latex'): if self.mw.show_moment.isEnabled(): if (len(self.ss.supports_roll) == 1 and len(self.ss.supports_hinged) == 1) \ or (len(self.ss.supports_fixed) == 1): dialog = QDialog() prompt = PathPrompt(self.mw.language, dialog) dialog.exec_() if not prompt.userTerminated: solve_path = prompt.path file, ok = QFileDialog.getSaveFileName( self.mw, self.mw.pdf_title, self.mw.pdf_text, "PDF (*.pdf)") if ok: try: self.mw.toolBox.setCurrentIndex(0) pdf_dir, filename = split_dir_filename(file) make_pdf_folders(pdf_dir) self.ss.color_scheme = "bright" plt.style.use('default') mn = Manager(self.ss) pdf_generator_thread = PDFGeneratorThread( mn.generate_pdf, self.mw.language, pdf_path=pdf_dir, filename=filename, solve_path=solve_path, path_warning=self.fn.path_warning, ) self.fn.setupLoading(pdf_generator_thread) pdf_generator_thread.finished.connect( self.on_finished) pdf_generator_thread.start() self.mw.loadingScreen.exec_() if not self.mw.loadingUi.userTerminated: self.fn.pdf_generated_prompt() if clean: delete_folder(pdf_dir) self.ss.color_scheme = "dark" plt.style.use('dark_background') except: self.fn.latex_packages_warning() else: self.fn.static_warning() else: self.fn.warning() else: self.fn.latex_warning() def on_finished(self): self.mw.loadingScreen.close() def reset_struct_elems(self): self.ss = SystemElements() self.ss.color_scheme = "dark" self.states.clear() self.mw.MplWidget.plot(has_grid=self.mw.gridBox.isChecked()) self.mw.MplWidget.set_background_alpha() self.mw.MplWidget.set_subplot_alpha() self.fn.figurefix() self.was_solved = False self.fn.disable_buttons() def load_structure_aux(self, file): with open(f'{file}', 'rb') as f: self.ss, _, _ = pickle.load(f) self.mw.struct_loaded = True def workaround(self): if self.was_solved: self.ss = pickle.loads(self.states[-1]) self.was_solved = False def reset(self): self.workaround() self.ss.remove_loads() self.mw.MplWidget.canvas.figure.clear() ax = self.mw.MplWidget.canvas.figure.add_subplot(111) ax.patch.set_alpha(0.2) self.fn.visualize( self.ss.show_structure(show=False, figure=(self.mw.MplWidget.canvas.figure, ax))) self.states.append(pickle.dumps(self.ss)) self.fn.disable_buttons()
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 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
from StructuresExplained.solutions.structure.reactions.assembler import Assembler if __name__ == "__main__": from anastruct import SystemElements from sympy import sympify ss = SystemElements() ss.add_element([[0, 0], [1, 0]]) ss.add_element([[1, 0], [1, 1]]) ss.add_element([[1, 0], [2, 0]]) ss.add_element([[2, 0], [3, 0]]) ss.point_load(2, Fy=10) ss.point_load(3, Fy=-20) ss.point_load(4, Fy=-30) ss.point_load(5, Fx=-40) ss.moment_load(2, Ty=-9) ss.moment_load(1, 7) ss.moment_load(3, 3) ss.q_load(element_id=3, q=(-10, -20)) ss.add_support_roll(4) ss.add_support_hinged(5) ss.solve() ass = Assembler(ss) ass.assemble_structure() print( f"{sympify(ass.res.point_sum_y, evaluate=False)}\n{sympify(ass.res.point_sum_x, evaluate=False)}\n{ass.res.moments_sum}\n")
def shear_design(Ast, B, D, Vu, fck, fy): FS = SystemElements() # Add beams to the system. FS.add_element(location=[0, 5], EA=15000, EI=5000) FS.add_element(location=[[0, 5], [5, 5]], EA=15000, EI=5000) FS.add_element(location=[[5, 5], [5, 0]], EA=15000, EI=5000) # Add a fixed support at node 1. FS.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. FS.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. FS.point_load(Fx=30, node_id=2) FS.q_load(q=-10, element_id=2) FS.q_load(q=-10, element_id=1) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve FS.solve() FS.get_element_results(element_id=1)['length'] FS.get_element_results(element_id=1)['Mmin'] deno = FS.get_element_results(element_id=1)['shear'] #breadth = randgen(300,600) #Asc = 0 #Ast = 0 #spacing = 150 #beam = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing) #Asc = beam.p_min() #Ast = beam.p_min() #beam1 = Beam(depth,breadth,Asc,Ast,15,415,415,3.14*10**2/4,spacing) #beam1.moment_capcity() #beam1.min_spacing() #beam1.max_spacing() #print(beam1.moment_capcity()*10**(-3)) #print(FS.get_element_results(element_id=1)['Mmax']) res = Beam_gene(depths) beam1 = Beam(depth, breadth, Asc, Ast, 15, 415, 415, 3.14 * 10**2 / 4, spacing) beam1.moment_capcity() beam1.min_spacing() beam1.max_spacing() # Add a fixed support at node 1. FS.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. FS.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. FS.point_load(Fx=30, node_id=2) FS.q_load(q=-10, element_id=2) FS.q_load(q=-10, element_id=1) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve FS.solve() FS.get_element_results(element_id=1)['length'] FS.get_element_results(element_id=1)['Mmin'] FS.get_element_results(element_id=1)['Mmax'] FS.get_element_results(element_id=1)['shear'] #print(beam1.moment_capcity()*10**(-3)) #print(FS.get_element_results(element_id=1)['Mmax']) C_D = ((beam1.moment_capcity()) * 10**(-3)) / (FS.get_element_results(element_id=1)['Mmax']) print(C_D)
def accept(self): try: E = float(self.form.editE.text()) # N/mm2 I = float(self.form.editI.text()) # mm4 A = float(self.form.editA.text()) # mm2 ss = SystemElements() frame = FreeCAD.ActiveDocument.getObjectsByLabel( self.form.comboBox.currentText())[0] sk = frame.Base j = 0 # CREATE MEMBERS OF STRUCTURE for l in sk.Geometry: sp = [i * 1e-3 for i in list(l.StartPoint)[:2]] ep = [i * 1e-3 for i in list(l.EndPoint)[:2]] if self.combotypes[j].currentText() == 'beam': ss.add_element([sp, ep], EA=E * A * 1e-3, EI=E * I * 1e-9) elif self.combotypes[j].currentText() == 'brace': ss.add_truss_element([sp, ep], EA=E * A * 1e-3) j += 1 # SET DISTRIBUTED LOADS if self.form.radioFrame.isChecked(): for i in list(range(len(sk.Geometry))): if self.form.tableDistrib.item(i, 2): item = self.form.tableDistrib.item(i, 2) try: load = float(item.text()) # kN/m ss.q_load(element_id=(i + 1), q=load) except: pass for c in self.combos: i = self.combos.index(c) + 1 # SET NODE CONSTRAINTS if c.currentText() == 'fix': ss.add_support_fixed(node_id=i) elif c.currentText() == 'hinge': ss.add_support_hinged(node_id=i) elif c.currentText() == 'roll': ss.add_support_roll(node_id=i) # SET NODE FORCES if self.form.tableConc.item( i - 1, 1) or self.form.tableConc.item(i - 1, 2): itemX = self.form.tableConc.item(i - 1, 1) try: loadX = float(itemX.text()) # kN except: loadX = 0 itemY = self.form.tableConc.item(i - 1, 2) # kN try: loadY = float(itemY.text()) except: loadY = 0 ss.point_load(node_id=(i), Fx=loadX, Fy=loadY) # SOLVE AND VALIDATE ss.solve() # stable=ss.validate(.0000001) # SHOW RESULTS ACCORDING THE CALC TYPE if True: #stable: if self.form.radioFrame.isChecked(): ss.show_results() elif self.form.radioTruss.isChecked(): ss.show_axial_force() else: FreeCAD.Console.PrintError('The structure is not stable.\n') except: FreeCAD.Console.PrintError('Invalid input\n') for l in self.labNodes + self.labEl: l.removeLabel()
class Artist: fig_counter = 0 def __init__( self, system_elements, node_order=None, assemble_order=None, target_dir="tmp", ): self.ss = system_elements self.branch_ss = SystemElements() self.assemble_order = assemble_order self.node_order = node_order self.target_dir = target_dir def draw_structure(self, show=False, save_figure=True, plotting_start_node=0, element_id=0): plot_iterations = False node_index = 0 figure = plt.figure(figsize=(12, 8)) subplot = figure.add_subplot(111) plt.tight_layout() for branch in self.assemble_order: self.draw_element(branch) first_node = next(i for i in self.node_order if i == branch[0] or i == branch[1]) for roll in self.ss.supports_roll: if roll.id == first_node: self.draw_support(first_node, subplot) for hinged in self.ss.supports_hinged: if hinged.id == first_node: self.draw_support(first_node, subplot) for fixed in self.ss.supports_fixed: if fixed.id == first_node: self.draw_support(first_node, subplot) if self.ss.loads_point.get(first_node): self.draw_point_load(first_node) if self.ss.loads_moment.get(first_node): self.draw_moment(first_node) elements_node1 = self.ss.node_element_map.get(branch[0]) elements_node2 = self.ss.node_element_map.get(branch[1]) for element in elements_node1: if element in elements_node2: q_load = self.ss.loads_q.get(element.id) if q_load: if branch == self.assemble_order[-1]: self.draw_q_load( get_relative_element_by_coordinates( self.ss, self.branch_ss, element.id), q_load) else: xi = element.vertex_1.x yi = element.vertex_1.y xf = element.vertex_2.x yf = element.vertex_2.y x_average = (xi + xf) / 2 y_average = (yi + yf) / 2 base = ((xf - xi)**2 + (yf - yi)**2)**0.5 load = ((-q_load[0][0] + -q_load[1][0]) * base) / 2 Fz = load * math.cos(element.angle) Fx = load * math.cos(element.angle - (90 * math.pi / 180)) h = 0.2 * self.ss.plotter.max_val_structure x, y, len_x, len_y, point_load = get_arrow_patch_values( Fx, Fz, (x_average, y_average), h) plot_arrow(subplot, point_load, [h, h, [x, y, len_x, len_y]]) # needs further testing break node_index += 1 if plotting_start_node in branch: plot_iterations = True if show and plot_iterations: self.branch_ss.show_structure(show=False, figure=(figure, subplot)) figure.show() if save_figure and plot_iterations: fig = self.branch_ss.show_structure(show=False, figure=(figure, subplot)) fig.savefig(fr'{self.target_dir}\figs\structure{element_id}') def generate_figures_for_pdf(self): fig = self.ss.show_structure(show=False) fig.savefig(fr'{self.target_dir}\figs\structure') fig = self.ss.show_structure(show=False, free_body_diagram=3) fig.savefig(fr'{self.target_dir}\figs\diagram1') fig = self.ss.show_structure(show=False, free_body_diagram=2) fig.savefig(fr'{self.target_dir}\figs\diagram2') fig = self.ss.show_reaction_force(show=False) fig.savefig(fr'{self.target_dir}\figs\supports') fig = self.ss.show_axial_force(show=False) fig.savefig(fr'{self.target_dir}\figs\axial') fig = self.ss.show_shear_force(show=False) fig.savefig(fr'{self.target_dir}\figs\shear') fig = self.ss.show_bending_moment(show=False) fig.savefig(fr'{self.target_dir}\figs\moment') def draw_support(self, node_id, subplot, roll_direction=None): support_node = self.ss.reaction_forces.get(node_id) if round(support_node.Fx, 2): plot_arrow(subplot, support_node.Fx, self.ss.reaction_vectors_data.get(f"{node_id}Fx")) if round(support_node.Fz, 2): plot_arrow(subplot, support_node.Fz, self.ss.reaction_vectors_data.get(f"{node_id}Fz")) if round(support_node.Ty, 2): plot_moment(subplot, self.ss.node_map.get(node_id), support_node.Ty, self.ss.reaction_vectors_data.get(f"{node_id}Ty")) def draw_element(self, branch): self.add_element_to_plot(branch) def add_element_to_plot(self, element): for node in range(len(element) - 1): self.branch_ss.add_element( [[ self.ss.node_map.get(element[node]).vertex.x, self.ss.node_map.get(element[node]).vertex.y ], [ self.ss.node_map.get(element[node + 1]).vertex.x, self.ss.node_map.get(element[node + 1]).vertex.y ]]) def draw_point_load(self, node_id): point_load = self.ss.loads_point[node_id] self.branch_ss.point_load( node_id=self.get_relative_node_by_coordinates(node_id), Fx=point_load[0], Fy=-point_load[1]) def draw_q_load(self, element_id, q_load): self.branch_ss.q_load(element_id=element_id, q=(q_load[0][0], q_load[1][0])) def draw_moment(self, node_id): moment_load = self.ss.loads_moment.get(node_id) self.branch_ss.moment_load( node_id=self.get_relative_node_by_coordinates(node_id), Ty=moment_load) def get_relative_node_by_coordinates(self, node_id): coords = (self.ss.node_map.get(node_id).vertex.x, self.ss.node_map.get(node_id).vertex.y) for node_key in self.branch_ss.node_map: node = self.branch_ss.node_map.get(node_key) if coords[0] == node.vertex.x and coords[1] == node.vertex.y: return node.id return None
# 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.show_displacement() # point_list, element_list, load_list = calc(point_list, element_list, load_list) point_list, element_list, load_list = calc( point_list, element_list, load_list, args.m, args.ite) for i in element_list: inicial_x = float(i.incidences_i.x) + \ i.incidences_i.x_displacement * exagero inicial_y = float(i.incidences_i.y) + \ i.incidences_i.y_displacement * exagero final_x = float(i.incidences_f.x) + \
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)) print("Difference between maximum comp. pressure and compressive strength: {}".format(-1*min(forces)/pop_cross_area - pop_compressive_strength)) return (max(forces)/pop_cross_area < pop_tensile_strength and -1*min(forces)/pop_cross_area < pop_compressive_strength) def change_load(old_load_id, new_load): id = ss.find_node_id(nodes_mid[old_load_id]) ss.point_load(id, Fy=-9.81*new_load/1000) ss.solve()
ss.add_element(location=[[0, 3], [0, 6]], EA=2850000, EI=34295) ss.add_element(location=[[0, 6], [6, 6]], EA=1752000.0, EI=12937) ss.add_element(location=[[6, 6], [6, 3]], EA=2850000, EI=34295) ss.add_element(location=[[0, 6], [0, 9]], EA=2850000, EI=34295) ss.add_element(location=[[0, 9], [6, 9]], EA=1752000.0, EI=12937) ss.add_element(location=[[6, 9], [6, 6]], EA=2850000, EI=34295) # Add a fixed support at node 1. ss.add_support_fixed(node_id=1) ss.add_support_fixed(node_id=4) #ss.add_support_fixed(node_id=1) # Add a rotational spring support at node 4. #ss.add_support_spring(node_id=4, translation=3, k=4000) # Add loads. ss.point_load(Fx=2.477, node_id=2) ss.point_load(Fx=9.991, node_id=5) ss.point_load(Fx=15.032, node_id=7) ss.q_load(q=-10, element_id=2) ss.q_load(q=-10, element_id=5) ss.q_load(q=-10, element_id=8) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) # Solve ss.solve() #print(ss.get_element_results(element_id=1)) #result = (ss.get_element_results(element_id=0, verbose=False)) ##for el_result in result: ## print(el_result['length'])
#ss.point_load(Fx=, node_id=2) #ss.point_load(Fx=30, node_id=5) #ss.point_load(Fx=30, node_id=7) #ss.point_load(Fx=30, node_id=9) #ss.point_load(Fx=30, node_id=11) # ss.q_load(q=-10, element_id=2) ss.q_load(q=-10, element_id=5) ss.q_load(q=-10, element_id=8) ss.q_load(q=-10, element_id=11) ss.q_load(q=-10, element_id=14) ss.q_load(q=-10, element_id=17) ss.q_load(q=-10, element_id=20) #ss.q_load(q=-10, element_id=4) #print(ss.node_ranges()) ss.point_load(Fx=2.477, node_id=2) ss.point_load(Fx=9.991, node_id=5) ss.point_load(Fx=15.032, node_id=7) ss.point_load(Fx=15.032, node_id=9) ss.point_load(Fx=20.477, node_id=11) ss.point_load(Fx=32.991, node_id=13) ss.point_load(Fx=48.032, node_id=15) #ss.point_load(Fx=48.032, node_id=19) # Solve ss.solve() ss.show_structure() ss.show_bending_moment() ss.show_axial_force() #print(ss.get_element_results(element_id=1)) #result = (ss.get_element_results(element_id=0, verbose=False)) ##for el_result in result:
#36 ss.add_element(location=[[9.9, 1.5], [10.5, 0.7]]) #37 ss.add_element(location=[[10.5, 0.7], [11, 1.1]]) #38 ss.add_element(location=[[10.5, 1.2], [11, 1.1]]) #39 ss.add_element(location=[[9.9, 2.6], [11, 1.1]]) #40 ss.add_element(location=[[10.5, 0.7], [11.5, 0]]) #41 ss.add_element(location=[[11, 1.1], [11.5, 0]]) #supports and loads ss.add_support_fixed(node_id=[1]) ss.point_load(10, Fx=10, rotation=90) ss.add_support_fixed(node_id=ss.id_last_node) #ss.q_load(q=-20, element_id=23, direction='element') #ss.q_load(q=-20, element_id=16, direction='element') #ss.q_load(q=-20, element_id=13, direction='element') #ss.q_load(q=-20, element_id=28, direction='element') ss.show_structure() ss.solve() #ss.show_bending_moment() ss.show_displacement() #ss.show_reaction_force() #ss.show_shear_force() plt.gca() line = ax.lines[0] line.get_xydata()
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
def initializeLatticeShell(startPoint, latticeParam, xHexagons, yHexagons, force, theta=0, EA=15000, EI=5000, g=0, flushBottomTop=True): ''' 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 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, 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) print(lattice_centers) # Iterate through each hexagon center and fill lattice_coordinates numpy array for i in range(yHexagons): for j in range(xHexagons): # Get hexagon points curr_hexPoints = hexagonPoints(lattice_centers[i, j], latticeParam) # Initialize start point lattice_coordinates[i, j, 0] = lattice_centers[i, j] lattice_coordinates[i, j, 1:] = curr_hexPoints # add all system elements and save point pairs 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 here... for i in range(len(lowest_nodes)): # add fixed support on lowest nodes... ss.add_support_fixed(node_id=lowest_nodes[i]) # add forces here... for i in range(len(highest_nodes)): # 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], Fx=0, Fy=force, rotation=theta) return ss