Example #1
0
 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)
Example #2
0
 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
Example #3
0
 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')
Example #4
0
 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)
Example #5
0
    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')
Example #6
0
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
Example #7
0
    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