def plot_reaction_forces(structure, step, layer=None, scale=1.0): """ Plots reaction forces for the Structure analysis results. Parameters ---------- structure : obj Structure object. step : str Name of the Step. layer : str Layer name for plotting. scale : float Scale of the arrows. Returns ------- None """ if not layer: layer = '{0}-{1}'.format(step, 'reactions') rs.CurrentLayer(rs.AddLayer(layer)) rs.DeleteObjects(rs.ObjectsByLayer(layer)) rs.EnableRedraw(False) rfx = structure.results[step]['nodal']['rfx'] rfy = structure.results[step]['nodal']['rfy'] rfz = structure.results[step]['nodal']['rfz'] nkeys = rfx.keys() v = [scale_vector([rfx[i], rfy[i], rfz[i]], -scale * 0.001) for i in nkeys] rm = [length_vector(i) for i in v] rmax = max(rm) nodes = structure.nodes_xyz(nkeys) for i in nkeys: if rm[i] > 0.001: l = rs.AddLine(nodes[i], add_vectors(nodes[i], v[i])) rs.CurveArrows(l, 1) col = [ int(j) for j in colorbar(rm[i] / rmax, input='float', type=255) ] rs.ObjectColor(l, col) vector = [rfx[i], rfy[i], rfz[i]] name = json.dumps({ 'rfx': rfx[i], 'rfy': rfy[i], 'rfz': rfz[i], 'rfm': length_vector(vector) }) rs.ObjectName(l, '_' + name) rs.CurrentLayer(rs.AddLayer('Default')) rs.LayerVisible(layer, False) rs.EnableRedraw(True)
def plot_reaction_forces(structure, step, layer=None, scale=1.0): """ Plots reaction forces for the Structure analysis results. Parameters ---------- structure : obj Structure object. step : str Name of the Step. layer : str Layer name for plotting. scale : float Scale of the arrows. Returns ------- None """ if not layer: layer = '{0}-{1}'.format(step, 'reactions') try: clear_layer(layer) except: create_layer(layer) rfx = array(list( structure.results[step]['nodal']['rfx'].values()))[:, newaxis] rfy = array(list( structure.results[step]['nodal']['rfy'].values()))[:, newaxis] rfz = array(list( structure.results[step]['nodal']['rfz'].values()))[:, newaxis] rf = hstack([rfx, rfy, rfz]) rfm = norm(rf, axis=1) rmax = max(rfm) nodes = array(structure.nodes_xyz()) for i in where(rfm > 0)[0]: sp = nodes[i, :] ep = nodes[i, :] + rf[i, :] * -scale * 0.001 col = colorbar(rfm[i] / rmax, input='float', type=1) line = draw_line(start=sp, end=ep, width=0.01, color=col, layer=layer) set_object_property(object=line, property='rfx', value=rf[i, 0]) set_object_property(object=line, property='rfy', value=rf[i, 1]) set_object_property(object=line, property='rfz', value=rf[i, 2]) set_object_property(object=line, property='rfm', value=rfm[i])
def plot_data(structure, step, field='um', layer=None, scale=1.0, radius=0.05, cbar=[None, None], iptype='mean', nodal='mean', mode='', colorbar_size=1): """ Plots analysis results on the deformed shape of the Structure. Parameters ---------- structure : obj Structure object. step : str Name of the Step. field : str Field to plot, e.g. 'um', 'sxx', 'sm1'. layer : str Layer name for plotting. scale : float Scale on displacements for the deformed plot. radius : float Radius of the pipe visualisation meshes. cbar : list Minimum and maximum limits on the colorbar. iptype : str 'mean', 'max' or 'min' of an element's integration point data. nodal : str 'mean', 'max' or 'min' for nodal values. mode : int Mode or frequency number to plot, for modal, harmonic or buckling analysis. colorbar_size : float Scale on the size of the colorbar. Returns ------- None Notes ----- - Pipe visualisation of line elements is not based on the element section. """ # Create and clear Rhino layer if not layer: layer = '{0}-{1}'.format(step, field) rs.CurrentLayer(rs.AddLayer(layer)) rs.DeleteObjects(rs.ObjectsByLayer(layer)) rs.EnableRedraw(False) # Node and element data nodes = structure.nodes_xyz() elements = [ structure.elements[i].nodes for i in sorted(structure.elements, key=int) ] nodal_data = structure.results[step]['nodal'] nkeys = sorted(structure.nodes, key=int) ux = [nodal_data['ux{0}'.format(mode)][i] for i in nkeys] uy = [nodal_data['uy{0}'.format(mode)][i] for i in nkeys] uz = [nodal_data['uz{0}'.format(mode)][i] for i in nkeys] try: data = [nodal_data['{0}{1}'.format(field, mode)][i] for i in nkeys] dtype = 'nodal' except (Exception): data = structure.results[step]['element'][field] dtype = 'element' # Postprocess basedir = utilities.__file__.split('__init__.py')[0] xfunc = XFunc('postprocess', basedir=basedir, tmpdir=structure.path) xfunc.funcname = 'functions.postprocess' result = xfunc(nodes, elements, ux, uy, uz, data, dtype, scale, cbar, 255, iptype, nodal) try: toc, U, cnodes, fabs, fscaled, celements, eabs = result print('\n***** Data processed : {0} s *****'.format(toc)) # Plot meshes mesh_faces = [] line_faces = [[0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0]] block_faces = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]] tet_faces = [[0, 2, 1, 1], [1, 2, 3, 3], [1, 3, 0, 0], [0, 3, 2, 2]] for element, nodes in enumerate(elements): n = len(nodes) if n == 2: u, v = nodes sp, ep = U[u], U[v] plane = rs.PlaneFromNormal(sp, subtract_vectors(ep, sp)) xa = plane.XAxis ya = plane.YAxis r = radius xa_pr = scale_vector(xa, +r) xa_mr = scale_vector(xa, -r) ya_pr = scale_vector(ya, +r) ya_mr = scale_vector(ya, -r) pts = [ add_vectors(sp, xa_pr), add_vectors(sp, ya_pr), add_vectors(sp, xa_mr), add_vectors(sp, ya_mr), add_vectors(ep, xa_pr), add_vectors(ep, ya_pr), add_vectors(ep, xa_mr), add_vectors(ep, ya_mr) ] guid = rs.AddMesh(pts, line_faces) if dtype == 'element': col1 = col2 = celements[element] elif dtype == 'nodal': col1 = cnodes[u] col2 = cnodes[v] rs.MeshVertexColors(guid, [col1] * 4 + [col2] * 4) elif n == 3: mesh_faces.append(nodes + [nodes[-1]]) elif n == 4: if structure.elements[element].__name__ in [ 'ShellElement', 'MembraneElement' ]: mesh_faces.append(nodes) else: for face in tet_faces: mesh_faces.append([nodes[i] for i in face]) elif n == 8: for block in block_faces: mesh_faces.append([nodes[i] for i in block]) if mesh_faces: guid = rs.AddMesh(U, mesh_faces) rs.MeshVertexColors(guid, cnodes) # Plot colorbar xr, yr, _ = structure.node_bounds() yran = yr[1] - yr[0] if yr[1] - yr[0] else 1 s = yran * 0.1 * colorbar_size xmin = xr[1] + 3 * s ymin = yr[0] xl = [xmin, xmin + s] yl = [ymin + i * s for i in range(11)] verts = [[xi, yi, 0] for xi in xl for yi in yl] faces = [[i, i + 1, i + 12, i + 11] for i in range(10)] id = rs.AddMesh(verts, faces) y = [i[1] for i in verts] yn = yran * colorbar_size colors = [ colorbar(2 * (yi - ymin - 0.5 * yn) / yn, input='float', type=255) for yi in y ] rs.MeshVertexColors(id, colors) h = 0.6 * s for i in range(5): x0 = xmin + 1.2 * s yu = ymin + (5.8 + i) * s yl = ymin + (3.8 - i) * s vu = float(+max(eabs, fabs) * (i + 1) / 5.) vl = float(-max(eabs, fabs) * (i + 1) / 5.) rs.AddText('{0:.5g}'.format(vu), [x0, yu, 0], height=h) rs.AddText('{0:.5g}'.format(vl), [x0, yl, 0], height=h) rs.AddText('0', [x0, ymin + 4.8 * s, 0], height=h) rs.AddText('Step:{0} Field:{1}'.format(step, field), [xmin, ymin + 12 * s, 0], height=h) if mode != '': freq = str(round(structure.results[step]['frequencies'][mode], 3)) rs.AddText('Mode:{0} Freq:{1}Hz'.format(mode, freq), [xmin, ymin - 1.5 * s, 0], height=h) # Return to Default layer rs.CurrentLayer(rs.AddLayer('Default')) rs.LayerVisible(layer, False) rs.EnableRedraw(True) except: print( '\n***** Error encountered during data processing or plotting *****' )
def plot_data(structure, step, field='um', layer=None, scale=1.0, radius=0.05, cbar=[None, None], iptype='mean', nodal='mean', mode='', cbar_size=1): """ Plots analysis results on the deformed shape of the Structure. Parameters ---------- structure : obj Structure object. step : str Name of the Step. field : str Field to plot, e.g. 'um', 'sxx', 'sm1'. layer : str Layer name for plotting. scale : float Scale on displacements for the deformed plot. radius : float Radius of the pipe visualisation meshes. cbar : list Minimum and maximum limits on the colorbar. iptype : str 'mean', 'max' or 'min' of an element's integration point data. nodal : str 'mean', 'max' or 'min' for nodal values. mode : int Mode or frequency number to plot, for modal, harmonic or buckling analysis. cbar_size : float Scale on the size of the colorbar. Returns ------- None Notes ----- - Pipe visualisation of line elements is not based on the element section. """ if field in ['smaxp', 'smises']: nodal = 'max' iptype = 'max' elif field in ['sminp']: nodal = 'min' iptype = 'min' # Create and clear Blender layer if not layer: layer = '{0}-{1}{2}'.format(step, field, mode) try: clear_layer(layer) except: create_layer(layer) # Node and element data nodes = structure.nodes_xyz() elements = [ structure.elements[i].nodes for i in sorted(structure.elements, key=int) ] nodal_data = structure.results[step]['nodal'] nkeys = sorted(structure.nodes, key=int) ux = [nodal_data['ux{0}'.format(mode)][i] for i in nkeys] uy = [nodal_data['uy{0}'.format(mode)][i] for i in nkeys] uz = [nodal_data['uz{0}'.format(mode)][i] for i in nkeys] try: data = [nodal_data['{0}{1}'.format(field, mode)][i] for i in nkeys] dtype = 'nodal' except (Exception): data = structure.results[step]['element'][field] dtype = 'element' # Postprocess result = postprocess(nodes, elements, ux, uy, uz, data, dtype, scale, cbar, 1, iptype, nodal) try: toc, U, cnodes, fabs, fscaled, celements, eabs = result U = array(U) print('\n***** Data processed : {0} s *****'.format(toc)) except: print( '\n***** Error encountered during data processing or plotting *****' ) # Plot meshes npts = 8 mesh_faces = [] block_faces = [[0, 1, 2, 3], [4, 5, 6, 7], [0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7]] tet_faces = [[0, 2, 1], [1, 2, 3], [1, 3, 0], [0, 3, 2]] pipes = [] mesh_add = [] for element, nodes in enumerate(elements): n = len(nodes) if n == 2: u, v = nodes pipe = draw_cylinder(start=U[u], end=U[v], radius=radius, div=npts, layer=layer) pipes.append(pipe) if dtype == 'element': col1 = col2 = celements[element] elif dtype == 'nodal': col1 = cnodes[u] col2 = cnodes[v] try: blendermesh = BlenderMesh(object=pipe) blendermesh.set_vertices_colors( {i: col1 for i in range(0, 2 * npts, 2)}) blendermesh.set_vertices_colors( {i: col2 for i in range(1, 2 * npts, 2)}) except: pass elif n in [3, 4]: if structure.elements[element].__name__ in [ 'ShellElement', 'MembraneElement' ]: mesh_faces.append(nodes) else: for face in tet_faces: mesh_faces.append([nodes[i] for i in face]) elif n == 8: for block in block_faces: mesh_faces.append([nodes[i] for i in block]) if mesh_faces: bmesh = xdraw_mesh(name='bmesh', vertices=U, faces=mesh_faces, layer=layer) blendermesh = BlenderMesh(bmesh) blendermesh.set_vertices_colors( {i: col for i, col in enumerate(cnodes)}) mesh_add = [bmesh] # Plot colourbar xr, yr, _ = structure.node_bounds() yran = yr[1] - yr[0] if yr[1] - yr[0] else 1 s = yran * 0.1 * cbar_size xmin = xr[1] + 3 * s ymin = yr[0] cmesh = draw_plane(name='colorbar', Lx=s, dx=s, Ly=10 * s, dy=s, layer=layer) set_objects_coordinates(objects=[cmesh], coords=[[xmin, ymin, 0]]) blendermesh = BlenderMesh(object=cmesh) vertices = blendermesh.get_vertices_coordinates().values() y = array(list(vertices))[:, 1] yn = yran * cbar_size colors = colorbar(((y - ymin - 0.5 * yn) * 2 / yn)[:, newaxis], input='array', type=1) blendermesh.set_vertices_colors( {i: j for i, j in zip(range(len(vertices)), colors)}) set_deselect() set_select(objects=pipes + mesh_add + [cmesh]) bpy.context.view_layer.objects.active = cmesh bpy.ops.object.join() h = 0.6 * s for i in range(5): x0 = xmin + 1.2 * s yu = ymin + (5.8 + i) * s yl = ymin + (3.8 - i) * s vu = +max([eabs, fabs]) * (i + 1) / 5. vl = -max([eabs, fabs]) * (i + 1) / 5. draw_text(radius=h, pos=[x0, yu, 0], text='{0:.3g}'.format(vu), layer=layer) draw_text(radius=h, pos=[x0, yl, 0], text='{0:.3g}'.format(vl), layer=layer) draw_text(radius=h, pos=[x0, ymin + 4.8 * s, 0], text='0', layer=layer) draw_text(radius=h, pos=[xmin, ymin + 12 * s, 0], text='Step:{0} Field:{1}'.format(step, field), layer=layer)
def plot_data(structure, step, field, layer, scale=1.0, radius=0.05, cbar=[None, None], iptype='mean', nodal='mean', mode='', colorbar_size=1): """ Plots analysis results on the deformed shape of the Structure. Parameters ---------- structure : obj Structure object. step : str Name of the Step. field : str Field to plot, e.g. 'um', 'sxx', 'sm1'. layer : int Layer number for plotting. scale : float Scale on displacements for the deformed plot. radius : float Radius of the pipe visualisation meshes. cbar : list Minimum and maximum limits on the colorbar. iptype : str 'mean', 'max' or 'min' of an element's integration point data. nodal : str 'mean', 'max' or 'min' for nodal values. mode : int Mode or frequency number to plot, for modal, harmonic or buckling analysis. colorbar_size : float Scale on the size of the colorbar. Returns ------- None Notes ----- - Pipe visualisation of line elements is not based on the element section. """ clear_layer(layer=layer) # Node and element data nodes = structure.nodes_xyz() elements = [ structure.elements[i].nodes for i in sorted(structure.elements, key=int) ] nodal_data = structure.results[step]['nodal'] nkeys = sorted(structure.nodes, key=int) ux = [nodal_data['ux{0}'.format(mode)][i] for i in nkeys] uy = [nodal_data['uy{0}'.format(mode)][i] for i in nkeys] uz = [nodal_data['uz{0}'.format(mode)][i] for i in nkeys] try: data = [nodal_data['{0}{1}'.format(field, mode)][i] for i in nkeys] dtype = 'nodal' except (Exception): data = structure.results[step]['element'][field] dtype = 'element' # Postprocess result = postprocess(nodes, elements, ux, uy, uz, data, dtype, scale, cbar, 1, iptype, nodal) try: toc, U, cnodes, fabs, fscaled, celements, eabs = result U = array(U) print('\n***** Data processed : {0:.3f} s *****'.format(toc)) except: print( '\n***** Error encountered during data processing or plotting *****' ) # Plot meshes npts = 8 mesh_faces = [] for element, nodes in enumerate(elements): n = len(nodes) if n == 2: u, v = nodes pipe = draw_pipes(start=[U[u]], end=[U[v]], radius=radius, layer=layer)[0] if dtype == 'element': col1 = col2 = [celements[element]] * npts elif dtype == 'nodal': col1 = [cnodes[u]] * npts col2 = [cnodes[v]] * npts blendermesh = BlenderMesh(pipe) blendermesh.set_vertex_colors(vertices=range(0, 2 * npts, 2), colors=col1) blendermesh.set_vertex_colors(vertices=range(1, 2 * npts, 2), colors=col2) elif n in [3, 4]: mesh_faces.append(nodes) if mesh_faces: bmesh = xdraw_mesh(name='bmesh', vertices=U, faces=mesh_faces, layer=layer) blendermesh = BlenderMesh(bmesh) blendermesh.set_vertex_colors(vertices=range(U.shape[0]), colors=cnodes) # Plot colourbar xr, yr, _ = structure.node_bounds() yran = yr[1] - yr[0] if yr[1] - yr[0] else 1 s = yran * 0.1 * colorbar_size xmin = xr[1] + 3 * s ymin = yr[0] cmesh = draw_plane(name='colorbar', Lx=s, dx=s, Ly=10 * s, dy=s, layer=layer) set_object_location(object=cmesh, location=[xmin, ymin, 0]) blendermesh = BlenderMesh(cmesh) verts = blendermesh.get_vertex_coordinates() y = array(verts)[:, 1] yn = yran * colorbar_size colors = colorbar(((y - ymin - 0.5 * yn) * 2 / yn)[:, newaxis], input='array', type=1) blendermesh.set_vertex_colors(vertices=range(len(verts)), colors=colors) h = 0.6 * s texts = [] for i in range(5): x0 = xmin + 1.2 * s yu = ymin + (5.8 + i) * s yl = ymin + (3.8 - i) * s vu = float(+max(eabs, fabs) * (i + 1) / 5.) vl = float(-max(eabs, fabs) * (i + 1) / 5.) texts.extend([{ 'radius': h, 'pos': [x0, yu, 0], 'text': '{0:.3g}'.format(vu), 'layer': layer }, { 'radius': h, 'pos': [x0, yl, 0], 'text': '{0:.3g}'.format(vl), 'layer': layer }]) texts.extend([{ 'radius': h, 'pos': [x0, ymin + 4.8 * s, 0], 'text': '0', 'layer': layer }, { 'radius': h, 'pos': [xmin, ymin + 12 * s, 0], 'text': 'Step:{0} Field:{1}'.format(step, field), 'layer': layer }]) xdraw_texts(texts)
def plot_principal_stresses(structure, step, ptype, scale, rotate=0, layer=None): """ Plots the principal stresses of the elements. Parameters ---------- structure : obj Structure object. step : str Name of the Step. ptype : str 'max' or 'min' for maximum or minimum principal stresses. scale : float Scale on the length of the line markers. rotate : int Rotate lines by 90 deg, 0 or 1. layer : str Layer name for plotting. Returns ------- None Notes ----- - Currently an alpha script and only for triangular shell elements in Abaqus. - Centroids are taken on the undeformed geometry. """ data = structure.results[step]['element'] result = functions.principal_stresses(data, ptype, scale, rotate) try: vec1, vec5, pr1, pr5, pmax = result if not layer: layer = '{0}_principal_{1}'.format(step, ptype) rs.CurrentLayer(rs.AddLayer(layer)) rs.DeleteObjects(rs.ObjectsByLayer(layer)) rs.EnableRedraw(False) centroids = [ structure.element_centroid(i) for i in sorted(structure.elements, key=int) ] for c, centroid in enumerate(centroids): v1 = vec1[c] v5 = vec5[c] id1 = rs.AddLine(add_vectors(centroid, scale_vector(v1, -1)), add_vectors(centroid, v1)) id5 = rs.AddLine(add_vectors(centroid, scale_vector(v5, -1)), add_vectors(centroid, v5)) col1 = colorbar(pr1[c] / pmax, input='float', type=255) col5 = colorbar(pr5[c] / pmax, input='float', type=255) rs.ObjectColor(id1, col1) rs.ObjectColor(id5, col5) rs.EnableRedraw(True) except: print('\n***** Error calculating or plotting principal stresses *****')