def draw_load(self, scale=1.): mp = [ self.beta * self.beam.i.coords[0] + self.alpha * self.beam.j.coords[0], self.beta * self.beam.i.coords[1] + self.alpha * self.beam.j.coords[1] ] ax = plt.gca() ax.scatter(mp[0], mp[1], marker='o', color='y', s=30, zorder=3)
def draw_load(self, scale=1.): mp = self.node.coords # starting point of the arrow for component, mass in self.mass.items(): if mass > 0: ax = plt.gca() ax.scatter(mp[0], mp[1], marker='o', color='gray', s=scale * 100, zorder=2) # nodes
def draw_load(self, scale=1.): mp = [ self.beta * self.beam.i.coords[0] + self.alpha * self.beam.j.coords[0], self.beta * self.beam.i.coords[1] + self.alpha * self.beam.j.coords[1] ] _norm = [1 * self.value / abs(self.value), 0] * transfer_matrix( alpha=-self.beam.direction, blocks=1, blocksize=2) _norm = np_matrix_tolist(_norm) ax = plt.gca() ax.arrow(mp[0], mp[1], _norm[0], _norm[1], head_width=0.5 * scale, head_length=scale, fc='blue', ec='blue')
def draw_load(self, scale=1.): p1 = [0, 0] p2 = [0, scale * -self.value] p3 = [self.beam.l, scale * -self.value] p4 = [self.beam.l, 0] pts = [p1, p2, p3, p4] _tr = transfer_matrix(alpha=-self.beam.direction, asdegree=False, blocks=1, blocksize=2) pts = [np_matrix_tolist(x * _tr + self.beam.i.coords) for x in pts] polygon = Polygon(pts, True) patches = [polygon] p = PatchCollection(patches, alpha=0.4, facecolors=['lightblue'], edgecolors=['blue']) # p.set_array(np.array('b')) ax = plt.gca() ax.add_collection(p)
def draw_load(self, scale=1.): mp = self.node.coords # starting point of the arrow for component, load in self.dynam.items(): if load > 0: if component == 'FX': _norm = ( load * scale / abs(load), 0, ) elif component == 'FY': _norm = (0, load * scale / abs(load)) else: _norm = (0, 0) # plotting, if there is a norm ax = plt.gca() ax.arrow(mp[0], mp[1], _norm[0], _norm[1], head_width=0.5 * scale, head_length=scale, fc='blue', ec='blue')
def draw_structure(structure, show=True, analysistype=None, mode=0, intac=None): if _plotting_available: for beam in structure.beams: # line width is in pixel plt.plot([p.x for p in beam.nodes], [p.y for p in beam.nodes], 'royalblue', linewidth=3, alpha=1, zorder=1) # beams plt.scatter([p.x for p in beam.nodes], [p.y for p in beam.nodes], marker='o', color='navy', alpha=0.5, s=30, zorder=2) # nodes # plot supports pixel_size = [ plt.rcParams["figure.dpi"] * x for x in plt.rcParams["figure.figsize"] ] # size of the pic in inches ax = plt.gca() xmin, xmax = ax.get_xlim() ymin, ymax = ax.get_ylim() _scale_base = math.sqrt( (xmax - xmin)**2 + (ymax - ymin)**2) # diagonal of the fig in units pixel_size = math.sqrt(pixel_size[0]**2 + pixel_size[1]**2) # diagnal physical size # size of the lines of the supports in drawing units supportsize = _scale_base / pixel_size * SUPPORT_SCALE for k, v in structure.supports.items(): _aktnode = [x for x in structure.nodes if x.ID == k][0] for dof in v: if dof == 'ux': # horizonatal plt.plot([_aktnode.x, _aktnode.x + supportsize], [_aktnode.y, _aktnode.y], 'g-', linewidth=4, zorder=6) # a horizontal line if dof == 'uy': # vertical plt.plot([_aktnode.x, _aktnode.x], [_aktnode.y, _aktnode.y - supportsize], 'g-', linewidth=4, zorder=6) # a horizontal line if dof == 'rotz': # rotation about Z plt.plot([_aktnode.x, _aktnode.x], [_aktnode.y, _aktnode.y], 'seagreen', markersize=16, zorder=7) # a point # plot the deformed shape # # displacements dre = 1. if structure.results[analysistype] is not None: dre = structure.results[analysistype].global_displacements( mode=0, asvector=True) dre = max(abs(dre)) # length of the longest beam - this will be the base for the scaling _long = sorted(structure.beams, key=lambda x: x.l)[-1].l # the scaling factor, based on the larges displacement and the length of the longest element _displacement_scaling = min(1e5, DISP_SCALE * _long / dre) for beam in structure.beams: # # beam displacements by component # dxs = structure.results[analysistype].element_displacements(local=False, mode=mode, beam=beam)['ux'] # dys = structure.results[analysistype].element_displacements(local=False, mode=mode, beam=beam)['uy'] # # # data to plot: original positions + displacements # _xdata = [p.x + dx * _scale for p, dx in zip(beam.nodes, dxs)] # _ydata = [p.y + dy * _scale for p, dy in zip(beam.nodes, dys)] # # # the nodes as squares # # plt.scatter(_xdata, _ydata, marker='o', color='k', s=30, zorder=3) # plot the deformed shape - using the internal points from the shape functions # beam.deflected_shape provides results in the GLOBAL system, based on the results in the LOCAL system coming from .results _deflected = beam.deflected_shape( local=False, scale=_displacement_scaling, disps=structure.results[analysistype].element_displacements( local=True, mode=mode, beam=beam, asvector=True)) plt.plot([x[0] for x in _deflected], [x[1] for x in _deflected], 'k-', zorder=3) if analysistype == 'modal': for nodalmass in structure.nodal_masses: nodalmass.draw_load() if analysistype == 'linear static': for nodalload in structure.nodal_loads: nodalload.draw_load(scale=ARROW_SCALE * _long) for beam in structure.beams: for intern in beam.internal_loads: intern.draw_load(scale=10) if intac is not None: # scaling for the internal actions react = -1e10 for b in structure.beams: # values of the internal action at the nodes ndx = b.internal_actions.index(intac) disp = structure.results[ 'linear static'].element_displacements(local=True, beam=b, asvector=True) v1 = b.nodal_reactions_asvector(disps=disp)[ndx, 0] v2 = b.nodal_reactions_asvector(disps=disp)[ndx + b.dof, 0] react = max(react, max([abs(val) for val in [v1, v2]])) # _internal_action_scaling = min(1e10, ((_scale_base / pixel_size) * INTAC_SCALE) / react) _internal_action_scaling = 1. for beam in structure.beams: disp = structure.results[ 'linear static'].element_displacements(local=True, beam=beam, asvector=True) beam.plot_internal_action(disp=disp, action=intac, scale=_internal_action_scaling) # title _title = "%s analysis" % analysistype if analysistype == 'modal': _res = structure.results[analysistype] _title += " %d. mode, f=%.3f Hz, T=%.3f sec" % ( mode + 1, _res.frequencies[mode], _res.periods[mode]) if analysistype == 'linear static': if intac is None: _title += ", deformed shape" else: _title += ", %s" % intac if show: plt.suptitle(_title) plt.axis('tight') plt.axis('equal') plt.show() return True else: return False
def plot_internal_action(self, action=None, disp=None, scale=1.): """ returns the node coordinates to be used for plotting :param action: :param disp: :return: """ # todo: as generator? assert action in self.internal_actions def baseline(_v1=0, _v2=0, _pos=0): if action == 'moment': # the baseline is the straight line between the values at the nodes # so this is just a linear interpolation assert 0 <= _pos <= 1 return _v1 + (_v2 - _v1) * _pos elif action in ['shear', 'axial']: return -_v1 # values of the internal action at the nodes ndx = self.internal_actions.index(action) v1 = self.nodal_reactions_asvector(disps=disp)[ndx, 0] v2 = self.nodal_reactions_asvector(disps=disp)[ndx + self.dof, 0] # the internal actions """ There is a base line defined by the nodal reactions calculated using the element stiffness matrix and the deformations at the endpoints of the beam element. The base line would be our solution, if we did not consider the internal loads. The values added to this line are calculated on a hinged-hinged beam. The result is then rotated in the global coordinate system for plotting. """ pois = self.internal_action_points # points of evaluation iad = self.internal_action_distribution( action=action) # internal actions at the points pois bases = [baseline(v1, -v2, pos) for pos in pois] # value of the base line at pois _contour = [x + y for x, y in zip(iad, bases) ] # adding the base and the value of the internal action _contour = [[x * self.l, y] for x, y in zip(pois, _contour)] # making them point pairs _contour.insert(0, [0, 0]) # adding first point _contour.append([self.l, 0]) # adding last point # scaling _contour = [[x[0], x[1] * scale] for x in _contour] # scaling # rotating the values in the global system for plotting _tr = transfer_matrix(alpha=-self.direction, asdegree=False, blocks=1, blocksize=2) pts = [np_matrix_tolist(x * _tr + self.i.coords) for x in _contour] patches = [Polygon(pts, True)] p = PatchCollection(patches, alpha=0.5, facecolors=['salmon'], edgecolors=['red']) ax = plt.gca() ax.add_collection(p) return pts