def get_properties(): # build the lists of points, facets, holes and control points points = request.json['points'] facets = request.json['facets'] holes = request.json['holes'] control_points = request.json['controls'] # create the custom geometry object geometry = sections.CustomSection(points, facets, holes, control_points) geometry.clean_geometry() # clean the geometry # create the mesh - use a smaller refinement for the angle region mesh = geometry.create_mesh(mesh_sizes=[0.0005, 0.001]) # create a CrossSection object section = CrossSection(geometry, mesh) # perform a geometric, warping and plastic analysis section.calculate_geometric_properties() section.calculate_warping_properties() section.calculate_plastic_properties() properties = section.display_results() return jsonify({'properties': properties})
# create a mesh - use a mesh size of 5 for the UB, 20 for the panel mesh = geometry.create_mesh(mesh_sizes=[5, 20]) # create a CrossSection object - take care to list the materials in the same order as entered into # the MergedSection section = CrossSection(geometry, mesh, materials=[steel, timber]) section.display_mesh_info() # display the mesh information # plot the mesh with coloured materials and a line transparency of 0.5 section.plot_mesh(materials=True, alpha=0.5) # perform a geometric, warping and plastic analysis section.calculate_geometric_properties(time_info=True) section.calculate_warping_properties(time_info=True) section.calculate_plastic_properties(time_info=True, verbose=True) # perform a stress analysis with N = 100 kN, Mxx = 120 kN.m and Vy = 75 kN stress_post = section.calculate_stress(N=-100e3, Mxx=-120e6, Vy=-75e3, time_info=True) # print the results to the terminal section.display_results() # plot the centroids section.plot_centroids() stress_post.plot_stress_n_zz(pause=False) # plot the axial stress stress_post.plot_stress_m_zz(pause=False) # plot the bending stress
def test_angle(self): """Section properties are validated against results from the Strand7 beam section utility.""" geometry = sections.AngleSection(d=150, b=90, t=12, r_r=10, r_t=5, n_r=8) mesh = geometry.create_mesh(mesh_sizes=[2.5]) section = CrossSection(geometry, mesh) val_list = [] val_list.append({"prop": "area", "val": 2746.73, "tol": 2e-4}) val_list.append({"prop": "perimeter", "val": 471, "tol": 1e-3}) val_list.append({"prop": "cx", "val": 21.2255, "tol": 2e-4}) val_list.append({"prop": "cy", "val": 50.9893, "tol": 2e-4}) val_list.append({"prop": "ixx_g", "val": 1.3428e7, "tol": 2e-4}) val_list.append({"prop": "iyy_g", "val": 2.95629e6, "tol": 2e-4}) val_list.append({"prop": "ixy_g", "val": 1.08669e6, "tol": 2e-4}) val_list.append({"prop": "ixx_c", "val": 6.28678e6, "tol": 2e-4}) val_list.append({"prop": "iyy_c", "val": 1.71882e6, "tol": 3e-4}) val_list.append({"prop": "ixy_c", "val": -1.88603e6, "tol": 3e-4}) val_list.append({"prop": "zxx_plus", "val": 63496.0, "tol": 2e-4}) val_list.append({"prop": "zxx_minus", "val": 123296, "tol": 2e-4}) val_list.append({"prop": "zyy_plus", "val": 24992.1, "tol": 3e-4}) val_list.append({"prop": "zyy_minus", "val": 80979.0, "tol": 2e-4}) val_list.append({"prop": "rx", "val": 47.8416, "tol": 2e-4}) val_list.append({"prop": "ry", "val": 25.0154, "tol": 2e-4}) val_list.append({"prop": "i11_c", "val": 6.96484e6, "tol": 2e-4}) val_list.append({"prop": "i22_c", "val": 1.04076e6, "tol": 2e-4}) val_list.append({"prop": "phi", "val": 19.7744 - 180, "tol": 2e-4}) val_list.append({"prop": "z11_plus", "val": 97751.9, "tol": 2e-4}) val_list.append({"prop": "z11_minus", "val": 69403.3, "tol": 2e-4}) val_list.append({"prop": "z22_plus", "val": 27959.0, "tol": 2e-4}) val_list.append({"prop": "z22_minus", "val": 20761.6, "tol": 3e-4}) val_list.append({"prop": "r11", "val": 50.3556, "tol": 2e-4}) val_list.append({"prop": "r22", "val": 19.4656, "tol": 2e-4}) val_list.append({"prop": "sxx", "val": 113541, "tol": 2e-4}) val_list.append({"prop": "syy", "val": 45724.6, "tol": 2e-4}) val_list.append({ "prop": "sf_xx_plus", "val": 113541 / 63496.0, "tol": 2e-4 }) val_list.append({ "prop": "sf_xx_minus", "val": 113541 / 123296, "tol": 2e-4 }) val_list.append({ "prop": "sf_yy_plus", "val": 45724.6 / 24992.1, "tol": 3e-4 }) val_list.append({ "prop": "sf_yy_minus", "val": 45724.6 / 80979.0, "tol": 2e-4 }) val_list.append({"prop": "s11", "val": 121030, "tol": 2e-4}) val_list.append({"prop": "s22", "val": 43760.6, "tol": 2e-4}) val_list.append({ "prop": "sf_11_plus", "val": 121030 / 97751.9, "tol": 2e-4 }) val_list.append({ "prop": "sf_11_minus", "val": 121030 / 69403.3, "tol": 2e-4 }) val_list.append({ "prop": "sf_22_plus", "val": 43760.6 / 27959.0, "tol": 2e-4 }) val_list.append({ "prop": "sf_22_minus", "val": 43760.6 / 20761.6, "tol": 3e-4 }) val_list.append({"prop": "j", "val": 135333, "tol": 1e-3}) val_list.append({"prop": "gamma", "val": 1.62288e8, "tol": 5e-4}) val_list.append({"prop": "A_s11", "val": 885.444, "tol": 2e-4}) val_list.append({"prop": "A_s22", "val": 1459.72, "tol": 4e-4}) val_list.append({"prop": "x11_se", "val": 28.719, "tol": 1e-3}) val_list.append({"prop": "y22_se", "val": 35.2348, "tol": 5e-4}) section.calculate_geometric_properties() section.calculate_plastic_properties() section.calculate_warping_properties() validate_properties(self, val_list, section)
def test_custom(self): """Section properties are validated against results from the Strand7 beam section utility.""" points = [[-10, 0], [110, 0], [100, 10], [55, 10], [55, 90], [100, 90], [110, 100], [110, 110], [-10, 110], [-10, 100], [0, 90], [45, 90], [45, 10], [-10, 10]] facets = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 10], [10, 11], [11, 12], [12, 13], [13, 0]] holes = [] control_points = [[0, 5]] geometry = sections.CustomSection(points, facets, holes, control_points) mesh = geometry.create_mesh(mesh_sizes=[5]) section = CrossSection(geometry, mesh) val_list = [] val_list.append({"prop": "area", "val": 4250, "tol": None}) val_list.append({"prop": "cx", "val": 49.3333, "tol": None}) val_list.append({"prop": "cy", "val": 65.0196, "tol": None}) val_list.append({"prop": "ixx_g", "val": 2.56725e7, "tol": None}) val_list.append({"prop": "iyy_g", "val": 1.41858e7, "tol": None}) val_list.append({"prop": "ixy_g", "val": 1.37979e7, "tol": None}) val_list.append({"prop": "ixx_c", "val": 7.70542e6, "tol": None}) val_list.append({"prop": "iyy_c", "val": 3.84228e6, "tol": None}) val_list.append({"prop": "ixy_c", "val": 165472, "tol": None}) val_list.append({"prop": "zxx_plus", "val": 171306, "tol": None}) val_list.append({"prop": "zxx_minus", "val": 118509, "tol": None}) val_list.append({"prop": "zyy_plus", "val": 63334.2, "tol": None}) val_list.append({"prop": "zyy_minus", "val": 64757.5, "tol": None}) val_list.append({"prop": "rx", "val": 42.5798, "tol": None}) val_list.append({"prop": "ry", "val": 30.0677, "tol": None}) val_list.append({"prop": "phi", "val": 177.552 - 180, "tol": 1e-4}) val_list.append({"prop": "i11_c", "val": 7.71249e6, "tol": None}) val_list.append({"prop": "i22_c", "val": 3.8352e6, "tol": None}) val_list.append({"prop": "z11_plus", "val": 162263, "tol": None}) val_list.append({"prop": "z11_minus", "val": 114268, "tol": None}) val_list.append({"prop": "z22_plus", "val": 60503.0, "tol": None}) val_list.append({"prop": "z22_minus", "val": 62666.1, "tol": None}) val_list.append({"prop": "r11", "val": 42.5993, "tol": None}) val_list.append({"prop": "r22", "val": 30.04, "tol": None}) val_list.append({"prop": "sxx", "val": 153196, "tol": None}) val_list.append({"prop": "syy", "val": 101494, "tol": None}) val_list.append({ "prop": "sf_xx_plus", "val": 153196 / 171306, "tol": None }) val_list.append({ "prop": "sf_xx_minus", "val": 153196 / 118509, "tol": None }) val_list.append({ "prop": "sf_yy_plus", "val": 101494 / 63334.2, "tol": None }) val_list.append({ "prop": "sf_yy_minus", "val": 101494 / 64757.5, "tol": None }) val_list.append({"prop": "s11", "val": 153347, "tol": None}) val_list.append({"prop": "s22", "val": 101501, "tol": None}) val_list.append({ "prop": "sf_11_plus", "val": 153347 / 162263, "tol": None }) val_list.append({ "prop": "sf_11_minus", "val": 153347 / 114268, "tol": None }) val_list.append({ "prop": "sf_22_plus", "val": 101501 / 60503.0, "tol": None }) val_list.append({ "prop": "sf_22_minus", "val": 101501 / 62666.1, "tol": None }) val_list.append({"prop": "j", "val": 347040, "tol": 5e-3}) val_list.append({"prop": "gamma", "val": 7.53539e9, "tol": 1e-3}) val_list.append({"prop": "A_s11", "val": 2945.53, "tol": 5e-4}) val_list.append({"prop": "A_s22", "val": 956.014, "tol": 5e-4}) val_list.append({"prop": "x11_se", "val": 1.9134, "tol": 5e-3}) val_list.append({"prop": "y22_se", "val": 3.02028, "tol": 5e-3}) section.calculate_geometric_properties() section.calculate_plastic_properties() section.calculate_warping_properties() validate_properties(self, val_list, section)
class TestRectangle(unittest.TestCase): """Section properties are mostly validated against hand calcs. Results from Strand7 and Roark's Formulas for Stress and Strain are used for some warping properties.""" def setUp(self): self.geometry = sections.RectangularSection(d=100, b=50) self.mesh = self.geometry.create_mesh(mesh_sizes=[10]) self.section = CrossSection(self.geometry, self.mesh) def test_geometric(self): self.section.calculate_geometric_properties() val_list = [] val_list.append({"prop": "area", "val": 100 * 50, "tol": None}) val_list.append({ "prop": "perimeter", "val": 100 * 2 + 50 * 2, "tol": None }) val_list.append({"prop": "ea", "val": 1 * 100 * 50, "tol": None}) val_list.append({"prop": "qx", "val": 100 * 50 * 50, "tol": None}) val_list.append({"prop": "qy", "val": 100 * 50 * 25, "tol": None}) val_list.append({"prop": "ixx_g", "val": 50 * 100**3 / 3, "tol": None}) val_list.append({"prop": "iyy_g", "val": 100 * 50**3 / 3, "tol": None}) val_list.append({ "prop": "ixy_g", "val": 100 * 50 * 50 * 25, "tol": None }) val_list.append({"prop": "cx", "val": 50 / 2, "tol": None}) val_list.append({"prop": "cy", "val": 100 / 2, "tol": None}) val_list.append({ "prop": "ixx_c", "val": 50 * 100**3 / 12, "tol": None }) val_list.append({ "prop": "iyy_c", "val": 100 * 50**3 / 12, "tol": None }) val_list.append({"prop": "ixy_c", "val": 0, "tol": None}) val_list.append({ "prop": "zxx_plus", "val": 50 * 100**2 / 6, "tol": None }) val_list.append({ "prop": "zxx_minus", "val": 50 * 100**2 / 6, "tol": None }) val_list.append({ "prop": "zyy_plus", "val": 100 * 50**2 / 6, "tol": None }) val_list.append({ "prop": "zyy_minus", "val": 100 * 50**2 / 6, "tol": None }) val_list.append({ "prop": "rx", "val": (50 * 100**3 / 12 / 100 / 50)**0.5, "tol": None }) val_list.append({ "prop": "ry", "val": (100 * 50**3 / 12 / 100 / 50)**0.5, "tol": None }) val_list.append({ "prop": "i11_c", "val": 50 * 100**3 / 12, "tol": None }) val_list.append({ "prop": "i22_c", "val": 100 * 50**3 / 12, "tol": None }) val_list.append({"prop": "phi", "val": 0, "tol": None}) val_list.append({ "prop": "z11_plus", "val": 50 * 100**2 / 6, "tol": None }) val_list.append({ "prop": "z11_minus", "val": 50 * 100**2 / 6, "tol": None }) val_list.append({ "prop": "z22_plus", "val": 100 * 50**2 / 6, "tol": None }) val_list.append({ "prop": "z22_minus", "val": 100 * 50**2 / 6, "tol": None }) val_list.append({ "prop": "r11", "val": (50 * 100**3 / 12 / 100 / 50)**0.5, "tol": None }) val_list.append({ "prop": "r22", "val": (100 * 50**3 / 12 / 100 / 50)**0.5, "tol": None }) validate_properties(self, val_list, self.section) def test_plastic(self): self.section.calculate_geometric_properties() self.section.calculate_plastic_properties() val_list = [] val_list.append({"prop": "x_pc", "val": 50 / 2, "tol": None}) val_list.append({"prop": "y_pc", "val": 100 / 2, "tol": None}) val_list.append({"prop": "x11_pc", "val": 50 / 2, "tol": None}) val_list.append({"prop": "y22_pc", "val": 100 / 2, "tol": None}) val_list.append({"prop": "sxx", "val": 50 * 100**2 / 4, "tol": None}) val_list.append({"prop": "syy", "val": 100 * 50**2 / 4, "tol": None}) val_list.append({"prop": "s11", "val": 50 * 100**2 / 4, "tol": None}) val_list.append({"prop": "s22", "val": 100 * 50**2 / 4, "tol": None}) val_list.append({"prop": "sf_xx_plus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_xx_minus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_yy_plus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_yy_minus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_11_plus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_11_minus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_22_plus", "val": 1.5, "tol": None}) val_list.append({"prop": "sf_22_minus", "val": 1.5, "tol": None}) validate_properties(self, val_list, self.section) def test_warping(self): self.section.calculate_geometric_properties() self.section.calculate_warping_properties() val_list = [] val_list.append({"prop": "j", "val": 2861002, "tol": 0.04}) # roark's val_list.append({"prop": "j", "val": 2.85852e6, "tol": 2e-5}) # st7 val_list.append({ "prop": "gamma", "val": 3.17542e8, "tol": None }) # st7 val_list.append({"prop": "x_se", "val": 50 / 2, "tol": None}) val_list.append({"prop": "y_se", "val": 100 / 2, "tol": None}) val_list.append({"prop": "x11_se", "val": 0, "tol": None}) val_list.append({"prop": "y22_se", "val": 0, "tol": None}) val_list.append({"prop": "x_st", "val": 50 / 2, "tol": None}) val_list.append({"prop": "y_st", "val": 100 / 2, "tol": None}) val_list.append({"prop": "A_sx", "val": 5 / 6 * 100 * 50, "tol": None}) val_list.append({"prop": "A_sy", "val": 5 / 6 * 100 * 50, "tol": None}) val_list.append({ "prop": "A_s11", "val": 5 / 6 * 100 * 50, "tol": None }) val_list.append({ "prop": "A_s22", "val": 5 / 6 * 100 * 50, "tol": None })
t = 0.1 # build the lists of points, facets, holes and control points points = [ [-t / 2, -2 * a], [t / 2, -2 * a], [t / 2, -t / 2], [a, -t / 2], [a, t / 2], [-t / 2, t / 2], [-b / 2, -2 * a], [b / 2, -2 * a], [b / 2, -2 * a - t], [-b / 2, -2 * a - t] ] facets = [[0, 1], [1, 2], [2, 3], [3, 4], [4, 5], [5, 0], [6, 7], [7, 8], [8, 9], [9, 6]] holes = [] control_points = [[0, 0], [0, -2 * a - t / 2]] # create the custom geometry object geometry = sections.CustomSection(points, facets, holes, control_points) geometry.clean_geometry() # clean the geometry geometry.plot_geometry() # plot the geometry # create the mesh - use a smaller refinement for the angle region mesh = geometry.create_mesh(mesh_sizes=[0.0005, 0.001]) # create a CrossSection object section = CrossSection(geometry, mesh) section.plot_mesh() # plot the generated mesh # perform a geometric, warping and plastic analysis section.calculate_geometric_properties() section.calculate_warping_properties() section.calculate_plastic_properties() # plot the centroids section.plot_centroids()
def process_geometry(geometry, mesh_sizes, loadcases): # update this to receive the geometry, mesh info, material and loads # generate a finite element mesh mesh = geometry.create_mesh(mesh_sizes=mesh_sizes) # generate material - can be overwritten if needed --all in N and cm # create a CrossSection object for analysis section = CrossSection(geometry, mesh) # calculate various cross-section properties section.calculate_geometric_properties() section.calculate_warping_properties() section.calculate_plastic_properties() # Area area = section.get_area() sheararea = section.get_As() asx = sheararea[0] asy = sheararea[1] # Second Moment of Area about centroid (ixx, iyy, ixy) = section.get_ic() # Centroid (xg, yg) = section.get_c() # Radii of Gyration (rxx, ryy) = section.get_rc() # Principal bending axis angle phi = section.get_phi() # St. Venant torsion constant ipp = section.get_j() # Warping Constant cw = section.get_gamma() # Elastic Section Moduli (welx_top, welx_bottom, wely_top, wely_bottom) = section.get_z() # Plastic Section Moduli (wplx, wply) = section.get_s() # plot centroid to image section.plot_centroids(pause=False) buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight') buf.seek(0) plot_centroid = base64.b64encode(buf.getvalue()).decode() plt.close() # calculate torsion resistance from stress and torque #from the below can also return torsional stress if wanted stress_post = section.calculate_stress(Mzz=10) unit_mzz_zxy = [] maxstress = [] for group in stress_post.material_groups: maxstress.append(max(group.stress_result.sig_zxy_mzz)) unit_mzz_zxy.append(group.stress_result.sig_zxy_mzz.tolist()) #there should be only one maxstress value therefore: wt = 10 / maxstress[0] #plot this image stress_post.plot_stress_mzz_zxy(pause=False) buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight') buf.seek(0) plot_unittorsionstress = base64.b64encode(buf.getvalue()).decode() plt.close() #foreach load case submitted calculate vm stress state and create image vmStressImages = {} vmStressStates = {} for loadcase in loadcases: lc_name = loadcase[0] s_n = loadcase[1] s_vx = loadcase[2] s_vy = loadcase[3] s_mxx = loadcase[4] s_myy = loadcase[5] s_mzz = loadcase[6] stress_post = section.calculate_stress(N=s_n, Vx=s_vx, Vy=s_vy, Mxx=s_mxx, Myy=s_myy, Mzz=s_mzz) stress_state = [] for group in stress_post.material_groups: stress_state.append(group.stress_result.sig_vm.tolist()) vmStressStates['lc_' + str(lc_name) + '_vm_stress'] = stress_state #plot this image stress_post.plot_stress_vm(pause=False) buf = io.BytesIO() plt.savefig(buf, format='png', bbox_inches='tight') buf.seek(0) vmStressImages['lc_' + str(lc_name) + '_vm_stress'] = base64.b64encode( buf.getvalue()).decode() plt.close() # create rhino mesh rmesh = rhino_mesh_from_meshpy(mesh) # return send_file(path, as_attachment=True) # get some of the calculated section properties return_data = {} return_data['properties'] = { 'area': area, 'Avx': asx, 'Avy': asy, 'xg': xg, 'yg': yg, 'rxx': rxx, 'ryy': ryy, 'phi': phi, 'ixx': ixx, 'iyy': iyy, 'ipp': ipp, 'cw': cw, 'welx+': welx_top, 'welx-': welx_bottom, 'wely+': wely_top, 'wely-': wely_bottom, 'wplx': wplx, 'wply': wply, 'wt': wt, } return_data['geometry'] = { 'mesh': rhino.CommonObject.Encode(rmesh), } return_data['images'] = { 'centroids': plot_centroid, 'unittorsion_vxy_stress': plot_unittorsionstress, } return_data['images'].update(vmStressImages) return_data['stress_results'] = { 'unittorsion_vxy_stress': unit_mzz_zxy, } return_data['stress_results'].update(vmStressStates) return return_data