Пример #1
0
    def calc_kG0(self,
                 size=None,
                 row0=0,
                 col0=0,
                 silent=False,
                 finalize=True,
                 c=None,
                 NLgeom=False):
        """Calculate the linear geometric stiffness matrix
        """
        self._rebuild()
        msg('Calculating kG0... ', level=2, silent=silent)

        kG0 = 0.
        if self.base is not None:
            #TODO include kG0 for pad-up and Nxx load that arrives there
            pass
        if self.flange is not None:
            kG0 += self.flange.calc_kG0(size=size,
                                        row0=row0,
                                        col0=col0,
                                        silent=True,
                                        finalize=False,
                                        NLgeom=NLgeom)

        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #2
0
    def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the mass matrix
        """
        self._rebuild()
        msg('Calculating kM... ', level=2, silent=silent)

        rowf = row0 + self.base.get_size()
        colf = col0 + self.base.get_size()

        kM = 0.
        kM += self.base.calc_kM(size=size,
                                row0=row0,
                                col0=col0,
                                silent=True,
                                finalize=False)
        kM += self.flange.calc_kM(size=size,
                                  row0=rowf,
                                  col0=colf,
                                  silent=True,
                                  finalize=False)

        if finalize:
            kM = finalize_symmetric_matrix(kM)
        self.kM = kM

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #3
0
    def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True,
            c=None):
        """Calculate the linear geometric stiffness matrix
        """
        #TODO
        if c is not None:
            raise NotImplementedError('numerical kG0 not implemented')

        self._rebuild()
        msg('Calculating kG0... ', level=2, silent=silent)

        kG0 = 0.
        if self.base is not None:
            # TODO include kG0 for padup
            #      now it is assumed that all the load goes to the flange
            pass
        if self.flam is not None:
            Fx = self.Fx if self.Fx is not None else 0.
            mod = modelDB.db[self.model]['matrices']
            bay = self.bay
            kG0 += mod.fkG0f(self.ys, Fx, bay.a, bay.b, self.bf, bay.m, bay.n,
                             bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                             bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                             size, row0, col0)

        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #4
0
    def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear constitutive stiffness matrix
        """
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)

        k0 = 0.
        if self.base is not None:
            k0 += self.base.calc_k0(size=size, row0=row0, col0=col0,
                    silent=True, finalize=False)
        if self.flam is not None:
            mod = modelDB.db[self.model]['matrices']
            bay = self.bay
            k0 += mod.fk0f(self.ys, bay.a, bay.b, self.bf, self.dbf, self.E1, self.F1,
                           self.S1, self.Jxx, bay.m, bay.n,
                           bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                           bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                           bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                           bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                           size=size, row0=row0, col0=col0)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #5
0
    def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True,
            c=None, NLgeom=False):
        """Calculate the linear geometric stiffness matrix
        """
        self._rebuild()
        msg('Calculating kG0... ', level=2, silent=silent)

        kG0 = 0.
        if self.base is not None:
            #TODO include kG0 for pad-up and Nxx load that arrives there
            pass
        if self.flange is not None:
            kG0 += self.flange.calc_kG0(size=size, row0=row0, col0=col0,
                    silent=True, finalize=False, NLgeom=NLgeom)

        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #6
0
 def calc_kT(self, c=None, silent=False, finalize=True, inc=None):
     msg('Calculating kT for assembly...', level=2, silent=silent)
     size = self.get_size()
     kT = 0
     #TODO use multiprocessing.Pool here
     for p in self.panels:
         if p.row_start is None or p.col_start is None:
             raise ValueError(
                 'Panel attributes "row_start" and "col_start" must be defined!'
             )
         kT += p.calc_k0(c=c,
                         size=size,
                         row0=p.row_start,
                         col0=p.col_start,
                         silent=True,
                         finalize=False,
                         inc=inc,
                         NLgeom=True)
         kT += p.calc_kG0(c=c,
                          size=size,
                          row0=p.row_start,
                          col0=p.col_start,
                          silent=True,
                          finalize=False,
                          NLgeom=True)
     if finalize:
         kT = finalize_symmetric_matrix(kT)
     k0_conn = self.get_k0_conn()
     kT += k0_conn
     self.kT = kT
     msg('finished!', level=2, silent=silent)
     return kT
Пример #7
0
def static(K, fext, silent=False):
    """Static Analyses

    Parameters
    ----------

    K : sparse_matrix
        Stiffness matrix. Should include initial stress stiffness matrix,
        aerodynamic matrix and so forth when applicable.
    fext : array-like
        Vector of external loads.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.

    """
    increments = []
    cs = []

    NLgeom=False
    if NLgeom:
        raise NotImplementedError('Independent static function not ready for NLgeom')
    else:
        msg('Started Linear Static Analysis', silent=silent)
        c = solve(K, fext, silent=silent)
        increments.append(1.)
        cs.append(c)
        msg('Finished Linear Static Analysis', silent=silent)

    return increments, cs
Пример #8
0
    def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the mass matrix
        """
        self._rebuild()
        msg('Calculating kM... ', level=2, silent=silent)

        mod = modelDB.db[self.model]['matrices']

        kM = 0.
        if self.base is not None:
            kM += self.base.calc_kM(size=size, row0=row0, col0=col0, silent=silent, finalize=False)
        if self.flam is not None:
            bay = self.bay
            h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
            kM += mod.fkMf(self.ys, self.mu, h, self.hb, self.hf, bay.a, bay.b,
                           self.bf, self.dbf, bay.m, bay.n,
                           bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                           bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx,
                           bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                           bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                           bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry,
                           bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                           size=size, row0=row0, col0=col0)

        if finalize:
            kM = finalize_symmetric_matrix(kM)
        self.kM = kM

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #9
0
def static(K, fext, silent=False):
    """Static Analyses

    Parameters
    ----------

    K : sparse_matrix
        Stiffness matrix. Should include initial stress stiffness matrix,
        aerodynamic matrix and so forth when applicable.
    fext : array-like
        Vector of external loads.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.

    """
    increments = []
    cs = []

    NLgeom = False
    if NLgeom:
        raise NotImplementedError(
            'Independent static function not ready for NLgeom')
    else:
        msg('Started Linear Static Analysis', silent=silent)
        c = solve(K, fext, silent=silent)
        increments.append(1.)
        cs.append(c)
        msg('Finished Linear Static Analysis', silent=silent)

    return increments, cs
Пример #10
0
    def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the mass matrix
        """
        self._rebuild()
        msg('Calculating kM... ', level=2, silent=silent)

        rowf = row0 + self.base.get_size()
        colf = col0 + self.base.get_size()

        kM = 0.
        kM += self.base.calc_kM(size=size, row0=row0, col0=col0, silent=True,
                finalize=False)
        kM += self.flange.calc_kM(size=size, row0=rowf, col0=colf, silent=True,
                finalize=False)

        if finalize:
            kM = finalize_symmetric_matrix(kM)
        self.kM = kM

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #11
0
    def calc_kM(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the mass matrix
        """
        self._rebuild()
        msg('Calculating kM... ', level=2, silent=silent)

        panmod = panmodelDB.db[self.panel1.model]['matrices']
        mod = modelDB.db[self.model]['matrices']

        bay = self.bay
        a = bay.a
        b = bay.b
        m = bay.m
        n = bay.n

        m1 = self.m1
        n1 = self.n1
        bf = self.bf

        kM = 0.

        if self.blam is not None:
            # stiffener pad-up
            y1 = self.ys - self.bb/2.
            y2 = self.ys + self.bb/2.
            kM += panmod.fkMy1y2(y1, y2, self.mu, self.db, self.hb, a, b, m, n,
                          bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                          bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx,
                          bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                          bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                          bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry,
                          bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                          size, 0, 0)

        if self.flam is not None:
            kM += mod.fkMf(self.mu, self.hf, a, bf, 0., m1, n1,
                           self.u1txf, self.u1rxf, self.u2txf, self.u2rxf,
                           self.v1txf, self.v1rxf, self.v2txf, self.v2rxf,
                           self.w1txf, self.w1rxf, self.w2txf, self.w2rxf,
                           self.u1tyf, self.u1ryf, self.u2tyf, self.u2ryf,
                           self.v1tyf, self.v1ryf, self.v2tyf, self.v2ryf,
                           self.w1tyf, self.w1ryf, self.w2tyf, self.w2ryf,
                           size, row0, col0)

        if finalize:
            assert np.any(np.isnan(kM.data)) == False
            assert np.any(np.isinf(kM.data)) == False
            kM = csr_matrix(make_symmetric(kM))

        self.kM = kM

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #12
0
    def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear constitutive stiffness matrix
        """
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)

        panmod = panmodelDB.db[self.panel1.model]['matrices']
        mod = modelDB.db[self.model]['matrices']

        bay = self.bay
        ys = self.ys
        a = bay.a
        b = bay.b
        m = self.panel1.m
        n = self.panel1.n
        r = self.panel1.r
        alphadeg = self.panel1.alphadeg
        alphadeg = alphadeg if alphadeg is not None else 0.
        alpharad = deg2rad(alphadeg)

        k0 = 0.
        if self.blam is not None:
            Fsb = self.blam.ABD
            y1 = ys - self.bb/2.
            y2 = ys + self.bb/2.
            k0 += panmod.fk0y1y2(y1, y2, a, b, r, alpharad, Fsb, m, n,
                                 bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                                 bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx,
                                 bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                                 bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                                 bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry,
                                 bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                                 size=size, row0=row0, col0=col0)

        if self.flam is not None:
            k0 += mod.fk0f(ys, a, b, self.bf, self.df, self.E1, self.F1,
                           self.S1, self.Jxx, m, n,
                           bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                           bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                           bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                           bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                           size=size, row0=row0, col0=col0)

        if finalize:
            assert np.any(np.isnan(k0.data)) == False
            assert np.any(np.isinf(k0.data)) == False
            k0 = csr_matrix(make_symmetric(k0))

        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #13
0
    def calc_k0(self, silent=False):
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)
        model = self.model
        a = self.a
        b = self.b
        r = self.r
        m = self.m
        n = self.n
        num = panmDB.db[self.model]['num']
        size = self.get_size()

        k0 = 0.

        # contributions from panels
        for p in self.panels:
            p.calc_k0(size=size, row0=0, col0=0, silent=True,
                          finalize=False)
            #TODO summing up coo_matrix objects may be slow!
            k0 += p.k0

        # contributions from bladestiff1ds
        for s in self.bladestiff1ds:
            s.calc_k0(size=size, row0=0, col0=0, silent=True,
                      finalize=False)
            #TODO summing up coo_matrix objects may be slow!
            k0 += s.k0

        # contributions from bladestiff2ds
        row0 = num*m*n
        col0 = num*m*n
        for i, s in enumerate(self.bladestiff2ds):
            num1 = stiffmDB.db[s.model]['num1']
            if i > 0:
                s_1 = bay.bladestiff2ds[i-1]
                row0 += num1*s_1.m1*s_1.n1
                col0 += num1*s_1.m1*s_1.n1
            s.calc_k0(size=size, row0=row0, col0=col0, silent=True,
                      finalize=False)
            #TODO summing up coo_matrix objects may be slow!
            k0 += s.k0

        # performing checks for the stiffness matrices
        assert np.any(np.isnan(k0.data)) == False
        assert np.any(np.isinf(k0.data)) == False
        k0 = csr_matrix(make_symmetric(k0))

        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #14
0
 def calc_fext(self, inc=1., silent=False):
     msg('Calculating external forces for assembly...', level=2, silent=silent)
     size = self.get_size()
     fext = 0
     for p in self.panels:
         if p.col_start is None:
             raise ValueError('Panel attributes "col_start" must be defined!')
         fext += p.calc_fext(inc=inc, size=size, col0=p.col_start, silent=True)
     self.fext = fext
     msg('finished!', level=2, silent=silent)
     return fext
Пример #15
0
 def calc_fint(self, c, silent=False, inc=1.):
     msg('Calculating internal forces for assembly...', level=2, silent=silent)
     size = self.get_size()
     fint = 0
     for p in self.panels:
         if p.col_start is None:
             raise ValueError('Panel attributes "col_start" must be defined!')
         fint += p.calc_fint(c=c, size=size, col0=p.col_start, silent=True)
     k0_conn = self.get_k0_conn()
     fint += k0_conn*c
     self.fint = fint
     msg('finished!', level=2, silent=silent)
     return fint
Пример #16
0
 def calc_kM(self, silent=False, finalize=True):
     msg('Calculating kM for assembly...', level=2, silent=silent)
     size = self.get_size()
     kM = 0
     for p in self.panels:
         if p.row_start is None or p.col_start is None:
             raise ValueError('Panel attributes "row_start" and "col_start" must be defined!')
         kM += p.calc_kM(row0=p.row_start, col0=p.col_start, size=size, silent=True, finalize=False)
     if finalize:
         kM = finalize_symmetric_matrix(kM)
     self.kM = kM
     msg('finished!', level=2, silent=silent)
     return kM
Пример #17
0
    def calc_fext(self, silent=False):
        """Calculates the external force vector `\{F_{ext}\}`

        Parameters
        ----------
        silent : bool, optional
            A boolean to tell whether the msg messages should be printed.

        Returns
        -------
        fext : np.ndarray
            The external force vector

        """
        msg('Calculating external forces...', level=2, silent=silent)
        num = panmDB.db[self.model]['num']
        fg = panmDB.db[self.model]['field'].fg

        # punctual forces on skin
        size = num*self.m*self.n
        g = np.zeros((3, size), dtype=DOUBLE)
        fext_skin = np.zeros(size, dtype=DOUBLE)
        for i, force in enumerate(self.forces_skin):
            x, y, fx, fy, fz = force
            fg(g, self.m, self.n, x, y, self.a, self.b)

            fpt = np.array([[fx, fy, fz]])
            fext_skin += fpt.dot(g).ravel()

        fext = fext_skin
        # punctual forces on stiffener
        for s in self.bladestiff2ds:
            num1 = stiffmDB.db[s.model]['num1']
            m1 = s.m1
            n1 = s.n1
            bf = s.bf
            size = num1*m1*n1
            g_stiffener = np.zeros((3, size), dtype=DOUBLE)
            fext_stiffener = np.zeros(size, dtype=DOUBLE)
            for i, force in enumerate(s.forces):
                xf, yf, fx, fy, fz = force
                fg(g_stiffener, m1, n1, xf, yf, self.a, bf)

                fpt = np.array([[fx, fy, fz]])
                fext_stiffener += fpt.dot(g_stiffener).ravel()

            fext = np.concatenate((fext, fext_stiffener))

        msg('finished!', level=2, silent=silent)

        return fext
Пример #18
0
    def calc_kA(self, silent=False):
        self._rebuild()
        msg('Calculating kA... ', level=2, silent=silent)
        model = self.model
        a = self.a
        b = self.b
        r = self.r
        m = self.m
        n = self.n
        num = panmDB.db[self.model]['num']
        size = self.get_size()

        if self.beta is None:
            if self.Mach < 1:
                raise ValueError('Mach number must be >= 1')
            elif self.Mach == 1:
                self.Mach = 1.0001
            M = self.Mach
            beta = self.rho_air * self.V**2 / (M**2 - 1)**0.5
            gamma = beta*1./(2.*self.r*(M**2 - 1)**0.5)
            ainf = self.speed_sound
            aeromu = beta/(M*ainf)*(M**2 - 2)/(M**2 - 1)
        else:
            beta = self.beta
            gamma = self.gamma if self.gamma is not None else 0.
            aeromu = self.aeromu if self.aeromu is not None else 0.

        # contributions from panels
        #TODO summing up coo_matrix objects may be slow!
        p = self.panels[0]
        #TODO if the initialization of panel is correct, the line below is
        #     unnecessary
        p.flow = self.flow
        p.calc_kA(silent=silent, finalize=False)

        kA = p.kA

        assert np.any(np.isnan(kA.data)) == False
        assert np.any(np.isinf(kA.data)) == False
        kA = csr_matrix(make_skew_symmetric(kA))

        self.kA = kA

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #19
0
 def calc_fint(self, c, silent=False, inc=1.):
     msg('Calculating internal forces for assembly...',
         level=2,
         silent=silent)
     size = self.get_size()
     fint = 0
     for p in self.panels:
         if p.col_start is None:
             raise ValueError(
                 'Panel attributes "col_start" must be defined!')
         fint += p.calc_fint(c=c, size=size, col0=p.col_start, silent=True)
     k0_conn = self.get_k0_conn()
     fint += k0_conn * c
     self.fint = fint
     msg('finished!', level=2, silent=silent)
     return fint
Пример #20
0
    def save(self):
        """Save the ``AeroPistonPlate`` object using ``cPickle``

        Notes
        -----
        The pickled file will have the name stored in ``AeroPistonPlate.name``
        followed by a ``'.AeroPistonPlate'`` extension.

        """
        name = self.name + '.AeroPistonPlate'
        msg('Saving AeroPistonPlate to {}'.format(name))

        self._clear_matrices()

        with open(name, 'wb') as f:
            cPickle.dump(self, f, protocol=cPickle.HIGHEST_PROTOCOL)
Пример #21
0
    def save(self):
        """Save the :class:`StiffPanelBay` object using ``cPickle``

        Notes
        -----
        The pickled file will have the name stored in
        :property:`.StiffPanelBay.name` followed by a
        ``'.StiffPanelBay'`` extension.

        """
        name = self.name + '.StiffPanelBay'
        msg('Saving StiffPanelBay to {0}'.format(name))

        self._clear_matrices()

        with open(name, 'wb') as f:
            cPickle.dump(self, f, protocol=cPickle.HIGHEST_PROTOCOL)
Пример #22
0
 def calc_fext(self, inc=1., silent=False):
     msg('Calculating external forces for assembly...',
         level=2,
         silent=silent)
     size = self.get_size()
     fext = 0
     for p in self.panels:
         if p.col_start is None:
             raise ValueError(
                 'Panel attributes "col_start" must be defined!')
         fext += p.calc_fext(inc=inc,
                             size=size,
                             col0=p.col_start,
                             silent=True)
     self.fext = fext
     msg('finished!', level=2, silent=silent)
     return fext
Пример #23
0
    def calc_cA(self, silent=False):
        self._rebuild()
        msg('Calculating cA... ', level=2, silent=silent)
        model = self.model
        a = self.a
        b = self.b
        r = self.r
        m = self.m
        n = self.n
        num = panmDB.db[self.model]['num']
        size = self.get_size()

        if self.beta is None:
            if self.Mach < 1:
                raise ValueError('Mach number must be >= 1')
            elif self.Mach == 1:
                self.Mach = 1.0001
            M = self.Mach
            beta = self.rho_air * self.V**2 / (M**2 - 1)**0.5
            gamma = beta*1./(2.*self.r*(M**2 - 1)**0.5)
            ainf = self.speed_sound
            aeromu = beta/(M*ainf)*(M**2 - 2)/(M**2 - 1)
        else:
            beta = self.beta
            gamma = self.gamma if self.gamma is not None else 0.
            aeromu = self.aeromu if self.aeromu is not None else 0.

        # contributions from panels
        p = self.panels[0]
        p.calc_cA(size=size, row0=0, col0=0, silent=silent)
        cA = p.cA

        assert np.any(np.isnan(cA.data)) == False
        assert np.any(np.isinf(cA.data)) == False

        cA = csr_matrix(make_symmetric(cA))

        self.cA = cA

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #24
0
    def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear geometric stiffness matrix
        """
        self._rebuild()
        msg('Calculating kG0... ', level=2, silent=silent)

        panmod = panmodelDB.db[self.panel1.model]['matrices']
        mod = modelDB.db[self.model]['matrices']

        bay = self.bay

        ys = self.ys
        m = bay.m
        n = bay.n
        mu = self.mu

        kG0 = 0.

        if self.blam is not None:
            Fsb = self.blam.ABD
            y1 = ys - self.bb/2.
            y2 = ys + self.bb/2.
            # TODO include kG0 for padup
            #      now it is assumed that all the load goes to the flange

        if self.flam is not None:
            Fx = self.Fx if self.Fx is not None else 0.
            kG0 += mod.fkG0f(ys, Fx, bay.a, bay.b, self.bf, m, n,
                             bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                             bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                             size, row0, col0)

        if finalize:
            assert np.any((np.isnan(kG0.data) | np.isinf(kG0.data))) == False
            kG0 = csr_matrix(make_symmetric(kG0))

        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #25
0
 def calc_kT(self, c=None, silent=False, finalize=True, inc=None):
     msg('Calculating kT for assembly...', level=2, silent=silent)
     size = self.get_size()
     kT = 0
     #TODO use multiprocessing.Pool here
     for p in self.panels:
         if p.row_start is None or p.col_start is None:
             raise ValueError('Panel attributes "row_start" and "col_start" must be defined!')
         kT += p.calc_k0(c=c, size=size, row0=p.row_start, col0=p.col_start,
                 silent=True, finalize=False, inc=inc, NLgeom=True)
         kT += p.calc_kG0(c=c, size=size, row0=p.row_start,
                 col0=p.col_start, silent=True, finalize=False, NLgeom=True)
     if finalize:
         kT = finalize_symmetric_matrix(kT)
     k0_conn = self.get_k0_conn()
     kT += k0_conn
     self.kT = kT
     msg('finished!', level=2, silent=silent)
     return kT
Пример #26
0
 def calc_kM(self, silent=False, finalize=True):
     msg('Calculating kM for assembly...', level=2, silent=silent)
     size = self.get_size()
     kM = 0
     for p in self.panels:
         if p.row_start is None or p.col_start is None:
             raise ValueError(
                 'Panel attributes "row_start" and "col_start" must be defined!'
             )
         kM += p.calc_kM(row0=p.row_start,
                         col0=p.col_start,
                         size=size,
                         silent=True,
                         finalize=False)
     if finalize:
         kM = finalize_symmetric_matrix(kM)
     self.kM = kM
     msg('finished!', level=2, silent=silent)
     return kM
Пример #27
0
    def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear geometric stiffness matrix
        """
        self._rebuild()
        msg('Calculating kG0... ', level=2, silent=silent)

        mod = modelDB.db[self.model]['matrices']

        bay = self.bay
        a = bay.a

        kG0 = 0.

        if self.blam is not None:
            # stiffener pad-up
            #TODO include kG0 for pad-up (Nxx load that arrives there)
            pass

        if self.flam is not None:
            F = self.flam.ABD
            # stiffener flange

            Nxx = self.Nxx if self.Nxx is not None else 0.
            Nxy = self.Nxy if self.Nxy is not None else 0.
            kG0 += mod.fkG0f(Nxx, 0., Nxy, a, self.bf, self.m1, self.n1,
                             self.w1txf, self.w1rxf, self.w2txf, self.w2rxf,
                             self.w1tyf, self.w1ryf, self.w2tyf, self.w2ryf,
                             size, row0, col0)

        if finalize:
            assert np.any((np.isnan(kG0.data) | np.isinf(kG0.data))) == False
            kG0 = csr_matrix(make_symmetric(kG0))

        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #28
0
    def calc_kG0(self, c=None, silent=False, finalize=True):
        """Calculate the geometric stiffness matrix of the assembly

        Parameters
        ----------

        c : array-like or None, optional
            This must be the result of a static analysis, used to compute
            non-linear terms based on the actual displacement field.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.
        finalize : bool, optional
            Asserts validity of output data and makes the output matrix
            symmetric, should be ``False`` when assemblying.

        """
        size = self.get_size()
        if c is None:
            msg('Calculating kG0 for assembly...', level=2, silent=silent)
        else:
            check_c(c, size)
            msg('Calculating kG for assembly...', level=2, silent=silent)
        kG0 = 0.
        for p in self.panels:
            if p.row_start is None or p.col_start is None:
                raise ValueError('Panel attributes "row_start" and "col_start" must be defined!')
            kG0 += p.calc_kG0(c=c, row0=p.row_start, col0=p.col_start, size=size,
                    silent=True, finalize=False)
        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0
        msg('finished!', level=2, silent=silent)
        return kG0
Пример #29
0
    def calc_kG0(self,
                 size=None,
                 row0=0,
                 col0=0,
                 silent=False,
                 finalize=True,
                 c=None,
                 NLgeom=False):
        """Calculate the linear geometric stiffness matrix

        See :meth:`.Panel.calc_k0` for details on each parameter.

        """
        self._rebuild()
        if c is None:
            msg('Calculating kG0... ', level=2, silent=silent)
        else:
            msg('Calculating kG... ', level=2, silent=silent)

        # NOTE:
        # - row0 and col0 define where the stiffener's base matrix starts
        # - rowf and colf define where the stiffener's flange matrix starts

        rowf = row0 + self.base.get_size()
        colf = col0 + self.base.get_size()

        kG0 = 0.
        kG0 += self.base.calc_kG0(c=c,
                                  size=size,
                                  row0=row0,
                                  col0=col0,
                                  silent=True,
                                  finalize=False,
                                  NLgeom=NLgeom)
        kG0 += self.flange.calc_kG0(c=c,
                                    size=size,
                                    row0=rowf,
                                    col0=colf,
                                    silent=True,
                                    finalize=False,
                                    NLgeom=NLgeom)

        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #30
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext()
            k0 = self.calc_k0()

            if self.calc_k0_bc is not None:
                k0_bc = self.calc_k0_bc()
                k0max = k0.max()
                k0 /= k0max

                fextmax = fext.max()
                fext /= fextmax

                k0 = k0 + k0_bc

            c = solve(k0, fext)

            if self.calc_k0_bc is not None:
                k0 *= k0max
                fext *= fextmax

                c /= k0max
                c *= fextmax

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Пример #31
0
    def calc_k0(self, conn=None, c=None, silent=False, finalize=True, inc=1.):
        """Calculate the constitutive stiffness matrix of the assembly

        Parameters
        ----------

        conn : dict, optional
            A connectivity dictionary. Optional if already defined for the
            assembly.
        c : array-like or None, optional
            This must be the result of a static analysis, used to compute
            non-linear terms based on the actual displacement field.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.
        finalize : bool, optional
            Asserts validity of output data and makes the output matrix
            symmetric, should be ``False`` when assemblying.
        inc : float, optional
            Dummy argument needed for non-linear analyses.

        """
        size = self.get_size()
        if c is None:
            msg('Calculating k0 for assembly...', level=2, silent=silent)
        else:
            check_c(c, size)
            msg('Calculating kL for assembly...', level=2, silent=silent)

        k0 = 0.
        for p in self.panels:
            if p.row_start is None or p.col_start is None:
                raise ValueError(
                    'Panel attributes "row_start" and "col_start" must be defined!'
                )
            k0 += p.calc_k0(c=c,
                            row0=p.row_start,
                            col0=p.col_start,
                            size=size,
                            silent=True,
                            finalize=False)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        k0_conn = self.get_k0_conn(conn=conn)
        k0 += self.k0_conn

        self.k0 = k0
        msg('finished!', level=2, silent=silent)
        return k0
Пример #32
0
    def calc_k0(self, conn=None, c=None, silent=False, finalize=True, inc=1.):
        """Calculate the constitutive stiffness matrix of the assembly

        Parameters
        ----------

        conn : dict, optional
            A connectivity dictionary. Optional if already defined for the
            assembly.
        c : array-like or None, optional
            This must be the result of a static analysis, used to compute
            non-linear terms based on the actual displacement field.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.
        finalize : bool, optional
            Asserts validity of output data and makes the output matrix
            symmetric, should be ``False`` when assemblying.
        inc : float, optional
            Dummy argument needed for non-linear analyses.

        """
        size = self.get_size()
        if c is None:
            msg('Calculating k0 for assembly...', level=2, silent=silent)
        else:
            check_c(c, size)
            msg('Calculating kL for assembly...', level=2, silent=silent)

        k0 = 0.
        for p in self.panels:
            if p.row_start is None or p.col_start is None:
                raise ValueError('Panel attributes "row_start" and "col_start" must be defined!')
            k0 += p.calc_k0(c=c, row0=p.row_start, col0=p.col_start, size=size,
                    silent=True, finalize=False)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        k0_conn = self.get_k0_conn(conn=conn)
        k0 += self.k0_conn

        self.k0 = k0
        msg('finished!', level=2, silent=silent)
        return k0
Пример #33
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        Parameters
        ----------

        NLgeom : bool
            Flag to indicate whether a linear or a non-linear analysis is to
            be performed.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self, silent=silent)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext(silent=silent)
            k0 = self.calc_k0(silent=silent)

            c = solve(k0, fext, silent=silent)

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Пример #34
0
    def static(self, NLgeom=False, silent=False):
        """General solver for static analyses

        Selects the specific solver based on the ``NL_method`` parameter.

        Parameters
        ----------

        NLgeom : bool
            Flag to indicate whether a linear or a non-linear analysis is to
            be performed.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.

        """
        self.increments = []
        self.cs = []

        if NLgeom:
            self.maxInc = max(self.initialInc, self.maxInc)
            msg('Started Non-Linear Static Analysis', silent=silent)
            if self.NL_method is 'NR':
                _solver_NR(self, silent=silent)
            elif self.NL_method is 'arc_length':
                _solver_arc_length(self)
            else:
                raise ValueError('{0} is an invalid NL_method')

        else:
            msg('Started Linear Static Analysis', silent=silent)
            fext = self.calc_fext(silent=silent)
            k0 = self.calc_k0(silent=silent)

            c = solve(k0, fext, silent=silent)

            self.cs.append(c)
            self.increments.append(1.)
            msg('Finished Linear Static Analysis', silent=silent)

        self.last_analysis = 'static'

        return self.increments, self.cs
Пример #35
0
    def calc_kG0(self, c=None, silent=False, finalize=True):
        """Calculate the geometric stiffness matrix of the assembly

        Parameters
        ----------

        c : array-like or None, optional
            This must be the result of a static analysis, used to compute
            non-linear terms based on the actual displacement field.
        silent : bool, optional
            A boolean to tell whether the log messages should be printed.
        finalize : bool, optional
            Asserts validity of output data and makes the output matrix
            symmetric, should be ``False`` when assemblying.

        """
        size = self.get_size()
        if c is None:
            msg('Calculating kG0 for assembly...', level=2, silent=silent)
        else:
            check_c(c, size)
            msg('Calculating kG for assembly...', level=2, silent=silent)
        kG0 = 0.
        for p in self.panels:
            if p.row_start is None or p.col_start is None:
                raise ValueError(
                    'Panel attributes "row_start" and "col_start" must be defined!'
                )
            kG0 += p.calc_kG0(c=c,
                              row0=p.row_start,
                              col0=p.col_start,
                              size=size,
                              silent=True,
                              finalize=False)
        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0
        msg('finished!', level=2, silent=silent)
        return kG0
Пример #36
0
    def calc_kG0(self, size=None, row0=0, col0=0, silent=False, finalize=True,
            c=None, NLgeom=False):
        """Calculate the linear geometric stiffness matrix

        See :meth:`.Panel.calc_k0` for details on each parameter.

        """
        self._rebuild()
        if c is None:
            msg('Calculating kG0... ', level=2, silent=silent)
        else:
            msg('Calculating kG... ', level=2, silent=silent)

        # NOTE:
        # - row0 and col0 define where the stiffener's base matrix starts
        # - rowf and colf define where the stiffener's flange matrix starts

        rowf = row0 + self.base.get_size()
        colf = col0 + self.base.get_size()

        kG0 = 0.
        kG0 += self.base.calc_kG0(c=c, size=size, row0=row0, col0=col0, silent=True,
                finalize=False, NLgeom=NLgeom)
        kG0 += self.flange.calc_kG0(c=c, size=size, row0=rowf, col0=colf,
                silent=True, finalize=False, NLgeom=NLgeom)

        if finalize:
            kG0 = finalize_symmetric_matrix(kG0)
        self.kG0 = kG0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #37
0
    def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear constitutive stiffness matrix
        """
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)

        flangemod = panmodelDB.db[self.flange.model]['matrices']

        bay = self.bay
        a = bay.a
        b = bay.b
        m = bay.m
        n = bay.n

        k0 = 0.
        if self.base is not None:
            k0 += self.base.calc_k0(size=size, row0=0, col0=0, silent=True,
                    finalize=False)
        if self.flange is not None:
            k0 += self.flange.calc_k0(size=size, row0=row0, col0=col0,
                    silent=True, finalize=False)

            # connectivity between stiffener'base and stiffener's flange
            if self.base is None:
                ktbf, krbf = calc_kt_kr(self.panel1, self.flange, 'ycte')
            else:
                ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte')

            mod = db['bladestiff2d_clt_donnell_bardell']['connections']
            k0 += mod.fkCss(ktbf, krbf, self.ys, a, b, m, n,
                            bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                            bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx,
                            bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                            bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                            bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry,
                            bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                            size, 0, 0)
            bf = self.flange.b
            k0 += mod.fkCsf(ktbf, krbf, self.ys, a, b, bf, m, n, self.flange.m, self.flange.n,
                            bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                            bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx,
                            bay.w1tx, bay.w1rx, bay.w2tx, bay.w2rx,
                            bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                            bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry,
                            bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                            self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx,
                            self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx,
                            self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx,
                            self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry,
                            self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry,
                            self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry,
                            size, 0, col0)
            k0 += mod.fkCff(ktbf, krbf, a, bf, self.flange.m, self.flange.n,
                            self.flange.u1tx, self.flange.u1rx, self.flange.u2tx, self.flange.u2rx,
                            self.flange.v1tx, self.flange.v1rx, self.flange.v2tx, self.flange.v2rx,
                            self.flange.w1tx, self.flange.w1rx, self.flange.w2tx, self.flange.w2rx,
                            self.flange.u1ty, self.flange.u1ry, self.flange.u2ty, self.flange.u2ry,
                            self.flange.v1ty, self.flange.v1ry, self.flange.v2ty, self.flange.v2ry,
                            self.flange.w1ty, self.flange.w1ry, self.flange.w2ty, self.flange.w2ry,
                            size, row0, col0)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #38
0
    def plot(self, c, group, invert_y=False, vec='w', filename='', ax=None,
            figsize=(3.5, 2.), save=True, title='', identify=False,
            show_boundaries=False, boundary_line='--k', boundary_linewidth=1.,
            colorbar=False, cbar_nticks=2, cbar_format=None, cbar_title='',
            cbar_fontsize=10, colormap='jet', aspect='equal', clean=True,
            dpi=400, texts=[], xs=None, ys=None, gridx=50, gridy=50,
            num_levels=400, vecmin=None, vecmax=None, calc_data_only=False):
        r"""Contour plot for a Ritz constants vector.

        Parameters
        ----------
        c : np.ndarray
            The Ritz constants that will be used to compute the field contour.
        group : str
            A group to plot. Each panel in ``panels`` should contain an
            attribute ``group``, which is used to identify which entities
            should be plotted together.
        vec : str, optional
            Can be one of the components:

            - Displacement: ``'u'``, ``'v'``, ``'w'``, ``'phix'``, ``'phiy'``
            - Strain: ``'exx'``, ``'eyy'``, ``'gxy'``, ``'kxx'``, ``'kyy'``,
              ``'kxy'``, ``'gyz'``, ``'gxz'``
            - Stress: ``'Nxx'``, ``'Nyy'``, ``'Nxy'``, ``'Mxx'``, ``'Myy'``,
              ``'Mxy'``, ``'Qy'``, ``'Qx'``
        invert_y : bool, optional
            Inverts the `y` axis of the plot.
        save : bool, optional
            Flag telling whether the contour should be saved to an image file.
        dpi : int, optional
            Resolution of the saved file in dots per inch.
        filename : str, optional
            The file name for the generated image file. If no value is given,
            the `name` parameter of the ``Panel`` object will be used.
        ax : AxesSubplot, optional
            When ``ax`` is given, the contour plot will be created inside it.
        figsize : tuple, optional
            The figure size given by ``(width, height)``.
        title : str, optional
            If any string is given a title is added to the contour plot.
        indentify : bool, optional
            If domains should be identified. If yes, the name of each panel is
            used.
        show_boundaries : bool, optional
            If boundaries between domains should be drawn.
        boundary_line : str, optional
            Matplotlib string to define line type and color.
        boundary_linewidth : float, optional
            Matplotlib float to define line width.
        colorbar : bool, optional
            If a colorbar should be added to the contour plot.
        cbar_nticks : int, optional
            Number of ticks added to the colorbar.
        cbar_format : [ None | format string | Formatter object ], optional
            See the ``matplotlib.pyplot.colorbar`` documentation.
        cbar_title : str, optional
            Colorbar title. If ``cbar_title == ''`` no title is added.
        cbar_fontsize : int, optional
            Fontsize of the colorbar labels.
        colormap : string, optional
            Name of a matplotlib available colormap.
        aspect : str, optional
            String that will be passed to the ``AxesSubplot.set_aspect()``
            method.
        clean : bool, optional
            Clean axes ticks, grids, spines etc.
        xs : np.ndarray, optional
            The `x` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        ys : np.ndarray, optional
            The ``y`` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        gridx : int, optional
            Number of points along the `x` axis where to calculate the
            displacement field.
        gridy : int, optional
            Number of points along the `y` where to calculate the
            displacement field.
        num_levels : int, optional
            Number of contour levels (higher values make the contour smoother).
        vecmin : float, optional
            Minimum value for the contour scale (useful to compare with other
            results). If not specified it will be taken from the calculated
            field.
        vecmax : float, optional
            Maximum value for the contour scale.
        calc_data_only : bool, optional
            If only calculated data should be returned.

        Returns
        -------
        ax : matplotlib.axes.Axes
            The Matplotlib object that can be used to modify the current plot
            if needed.
        data : dict
            Data calculated during the plotting procedure.

        """
        msg('Plotting contour...')

        import matplotlib
        if platform.system().lower() == 'linux':
            matplotlib.use('Agg')
        import matplotlib.pyplot as plt

        msg('Computing field variables...', level=1)
        displs = ['u', 'v', 'w', 'phix', 'phiy']
        strains = ['exx', 'eyy', 'gxy', 'kxx', 'kyy', 'kxy', 'gyz', 'gxz']
        stresses = ['Nxx', 'Nyy', 'Nxy', 'Mxx', 'Myy', 'Mxy', 'Qy', 'Qx']
        if vec in displs:
            res = self.uvw(c, group, gridx=gridx, gridy=gridy)
        elif vec in strains:
            res = self.strain(c, group, gridx=gridx, gridy=gridy)
        elif vec in stresses:
            res = self.stress(c, group, gridx=gridx, gridy=gridy)
        else:
            raise ValueError(
                    '{0} is not a valid vec parameter value!'.format(vec))
        field = np.array(res[vec])
        msg('Finished!', level=1)

        if vecmin is None:
            vecmin = field.min()
        if vecmax is None:
            vecmax = field.max()

        data = dict(vecmin=vecmin, vecmax=vecmax)

        if calc_data_only:
            return None, data

        levels = linspace(vecmin, vecmax, num_levels)

        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(111)
        else:
            if isinstance(ax, matplotlib.axes.Axes):
                ax = ax
                fig = ax.figure
                save = False
            else:
                raise ValueError('ax must be an Axes object')

        if invert_y == True:
            ax.invert_yaxis()
        ax.invert_xaxis()

        colormap_obj = getattr(cm, colormap, None)
        if colormap_obj is None:
            warn('Invalid colormap, using "jet"', level=1)
            colormap_obj = cm.jet

        count = -1
        for i, panel in enumerate(self.panels):
            if panel.group != group:
                continue
            count += 1
            xplot = res['y'][count] + panel.y0
            yplot = res['x'][count] + panel.x0
            field = res[vec][count]
            contour = ax.contourf(xplot, yplot, field, levels=levels,
                    cmap=colormap_obj)
            if identify:
                ax.text(xplot.mean(), yplot.mean(), 'P {0:02d}'.format(i+1),
                        transform=ax.transData, ha='center')
            if show_boundaries:
                x1, x2 = xplot.min(), xplot.max()
                y1, y2 = yplot.min(), yplot.max()
                ax.plot((x1, x2), (y1, y1), boundary_line, lw=boundary_linewidth)
                ax.plot((x1, x2), (y2, y2), boundary_line, lw=boundary_linewidth)
                ax.plot((x1, x1), (y1, y2), boundary_line, lw=boundary_linewidth)
                ax.plot((x2, x2), (y1, y2), boundary_line, lw=boundary_linewidth)

        if colorbar:
            from mpl_toolkits.axes_grid1 import make_axes_locatable

            fsize = cbar_fontsize
            divider = make_axes_locatable(ax)
            cax = divider.append_axes('right', size='5%', pad=0.05)
            cbarticks = linspace(vecmin, vecmax, cbar_nticks)
            cbar = plt.colorbar(contour, ticks=cbarticks, format=cbar_format,
                                cax=cax)
            if cbar_title:
                cax.text(0.5, 1.05, cbar_title, horizontalalignment='center',
                         verticalalignment='bottom', fontsize=fsize)
            cbar.outline.remove()
            cbar.ax.tick_params(labelsize=fsize, pad=0., tick2On=False)

        if title != '':
            ax.set_title(str(title))

        fig.tight_layout()
        ax.set_aspect(aspect)

        ax.grid(False)
        ax.set_frame_on(False)
        if clean:
            ax.xaxis.set_ticks_position('none')
            ax.yaxis.set_ticks_position('none')
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
        else:
            ax.xaxis.set_ticks_position('bottom')
            ax.yaxis.set_ticks_position('left')

        for kwargs in texts:
            ax.text(transform=ax.transAxes, **kwargs)

        if save:
            if not filename:
                filename = group + '.png'
            fig.savefig(filename, transparent=True,
                        bbox_inches='tight', pad_inches=0.05, dpi=dpi)
            plt.close()

        msg('finished!')

        return ax, data
Пример #39
0
    def plot(self,
             c,
             group,
             invert_y=False,
             vec='w',
             filename='',
             ax=None,
             figsize=(3.5, 2.),
             save=True,
             title='',
             identify=False,
             show_boundaries=False,
             boundary_line='--k',
             boundary_linewidth=1.,
             colorbar=False,
             cbar_nticks=2,
             cbar_format=None,
             cbar_title='',
             cbar_fontsize=10,
             colormap='jet',
             aspect='equal',
             clean=True,
             dpi=400,
             texts=[],
             xs=None,
             ys=None,
             gridx=50,
             gridy=50,
             num_levels=400,
             vecmin=None,
             vecmax=None,
             calc_data_only=False):
        r"""Contour plot for a Ritz constants vector.

        Parameters
        ----------
        c : np.ndarray
            The Ritz constants that will be used to compute the field contour.
        group : str
            A group to plot. Each panel in ``panels`` should contain an
            attribute ``group``, which is used to identify which entities
            should be plotted together.
        vec : str, optional
            Can be one of the components:

            - Displacement: ``'u'``, ``'v'``, ``'w'``, ``'phix'``, ``'phiy'``
            - Strain: ``'exx'``, ``'eyy'``, ``'gxy'``, ``'kxx'``, ``'kyy'``,
              ``'kxy'``, ``'gyz'``, ``'gxz'``
            - Stress: ``'Nxx'``, ``'Nyy'``, ``'Nxy'``, ``'Mxx'``, ``'Myy'``,
              ``'Mxy'``, ``'Qy'``, ``'Qx'``
        invert_y : bool, optional
            Inverts the `y` axis of the plot.
        save : bool, optional
            Flag telling whether the contour should be saved to an image file.
        dpi : int, optional
            Resolution of the saved file in dots per inch.
        filename : str, optional
            The file name for the generated image file. If no value is given,
            the `name` parameter of the ``Panel`` object will be used.
        ax : AxesSubplot, optional
            When ``ax`` is given, the contour plot will be created inside it.
        figsize : tuple, optional
            The figure size given by ``(width, height)``.
        title : str, optional
            If any string is given a title is added to the contour plot.
        indentify : bool, optional
            If domains should be identified. If yes, the name of each panel is
            used.
        show_boundaries : bool, optional
            If boundaries between domains should be drawn.
        boundary_line : str, optional
            Matplotlib string to define line type and color.
        boundary_linewidth : float, optional
            Matplotlib float to define line width.
        colorbar : bool, optional
            If a colorbar should be added to the contour plot.
        cbar_nticks : int, optional
            Number of ticks added to the colorbar.
        cbar_format : [ None | format string | Formatter object ], optional
            See the ``matplotlib.pyplot.colorbar`` documentation.
        cbar_title : str, optional
            Colorbar title. If ``cbar_title == ''`` no title is added.
        cbar_fontsize : int, optional
            Fontsize of the colorbar labels.
        colormap : string, optional
            Name of a matplotlib available colormap.
        aspect : str, optional
            String that will be passed to the ``AxesSubplot.set_aspect()``
            method.
        clean : bool, optional
            Clean axes ticks, grids, spines etc.
        xs : np.ndarray, optional
            The `x` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        ys : np.ndarray, optional
            The ``y`` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        gridx : int, optional
            Number of points along the `x` axis where to calculate the
            displacement field.
        gridy : int, optional
            Number of points along the `y` where to calculate the
            displacement field.
        num_levels : int, optional
            Number of contour levels (higher values make the contour smoother).
        vecmin : float, optional
            Minimum value for the contour scale (useful to compare with other
            results). If not specified it will be taken from the calculated
            field.
        vecmax : float, optional
            Maximum value for the contour scale.
        calc_data_only : bool, optional
            If only calculated data should be returned.

        Returns
        -------
        ax : matplotlib.axes.Axes
            The Matplotlib object that can be used to modify the current plot
            if needed.
        data : dict
            Data calculated during the plotting procedure.

        """
        msg('Plotting contour...')

        import matplotlib
        if platform.system().lower() == 'linux':
            matplotlib.use('Agg')
        import matplotlib.pyplot as plt

        msg('Computing field variables...', level=1)
        displs = ['u', 'v', 'w', 'phix', 'phiy']
        strains = ['exx', 'eyy', 'gxy', 'kxx', 'kyy', 'kxy', 'gyz', 'gxz']
        stresses = ['Nxx', 'Nyy', 'Nxy', 'Mxx', 'Myy', 'Mxy', 'Qy', 'Qx']
        if vec in displs:
            res = self.uvw(c, group, gridx=gridx, gridy=gridy)
        elif vec in strains:
            res = self.strain(c, group, gridx=gridx, gridy=gridy)
        elif vec in stresses:
            res = self.stress(c, group, gridx=gridx, gridy=gridy)
        else:
            raise ValueError(
                '{0} is not a valid vec parameter value!'.format(vec))
        field = np.array(res[vec])
        msg('Finished!', level=1)

        if vecmin is None:
            vecmin = field.min()
        if vecmax is None:
            vecmax = field.max()

        data = dict(vecmin=vecmin, vecmax=vecmax)

        if calc_data_only:
            return None, data

        levels = linspace(vecmin, vecmax, num_levels)

        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(111)
        else:
            if isinstance(ax, matplotlib.axes.Axes):
                ax = ax
                fig = ax.figure
                save = False
            else:
                raise ValueError('ax must be an Axes object')

        if invert_y == True:
            ax.invert_yaxis()
        ax.invert_xaxis()

        colormap_obj = getattr(cm, colormap, None)
        if colormap_obj is None:
            warn('Invalid colormap, using "jet"', level=1)
            colormap_obj = cm.jet

        count = -1
        for i, panel in enumerate(self.panels):
            if panel.group != group:
                continue
            count += 1
            xplot = res['y'][count] + panel.y0
            yplot = res['x'][count] + panel.x0
            field = res[vec][count]
            contour = ax.contourf(xplot,
                                  yplot,
                                  field,
                                  levels=levels,
                                  cmap=colormap_obj)
            if identify:
                ax.text(xplot.mean(),
                        yplot.mean(),
                        'P {0:02d}'.format(i + 1),
                        transform=ax.transData,
                        ha='center')
            if show_boundaries:
                x1, x2 = xplot.min(), xplot.max()
                y1, y2 = yplot.min(), yplot.max()
                ax.plot((x1, x2), (y1, y1),
                        boundary_line,
                        lw=boundary_linewidth)
                ax.plot((x1, x2), (y2, y2),
                        boundary_line,
                        lw=boundary_linewidth)
                ax.plot((x1, x1), (y1, y2),
                        boundary_line,
                        lw=boundary_linewidth)
                ax.plot((x2, x2), (y1, y2),
                        boundary_line,
                        lw=boundary_linewidth)

        if colorbar:
            from mpl_toolkits.axes_grid1 import make_axes_locatable

            fsize = cbar_fontsize
            divider = make_axes_locatable(ax)
            cax = divider.append_axes('right', size='5%', pad=0.05)
            cbarticks = linspace(vecmin, vecmax, cbar_nticks)
            cbar = plt.colorbar(contour,
                                ticks=cbarticks,
                                format=cbar_format,
                                cax=cax)
            if cbar_title:
                cax.text(0.5,
                         1.05,
                         cbar_title,
                         horizontalalignment='center',
                         verticalalignment='bottom',
                         fontsize=fsize)
            cbar.outline.remove()
            cbar.ax.tick_params(labelsize=fsize, pad=0., tick2On=False)

        if title != '':
            ax.set_title(str(title))

        fig.tight_layout()
        ax.set_aspect(aspect)

        ax.grid(False)
        ax.set_frame_on(False)
        if clean:
            ax.xaxis.set_ticks_position('none')
            ax.yaxis.set_ticks_position('none')
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
        else:
            ax.xaxis.set_ticks_position('bottom')
            ax.yaxis.set_ticks_position('left')

        for kwargs in texts:
            ax.text(transform=ax.transAxes, **kwargs)

        if save:
            if not filename:
                filename = group + '.png'
            fig.savefig(filename,
                        transparent=True,
                        bbox_inches='tight',
                        pad_inches=0.05,
                        dpi=dpi)
            plt.close()

        msg('finished!')

        return ax, data
Пример #40
0
    def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear constitutive stiffness matrix
        """
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)

        # NOTE
        #     row0 and col0 define where the stiffener's base matrix starts
        #     rowf and colf define where the stiffener's flange matrix starts
        rowf = row0 + self.base.get_size()
        colf = col0 + self.base.get_size()

        k0 = 0.
        k0 += self.base.calc_k0(size=size,
                                row0=row0,
                                col0=col0,
                                silent=True,
                                finalize=False)
        k0 += self.flange.calc_k0(size=size,
                                  row0=rowf,
                                  col0=colf,
                                  silent=True,
                                  finalize=False)

        # connectivity panel-base
        conn = stiffmDB.db[self.model]['connections']

        ktpb, krpb = calc_kt_kr(self.panel1, self.base, 'bot-top')
        ktpb = min(1.e7, ktpb)

        #TODO remove from Cython the capability to run with debonding defect
        y1 = self.ys - self.base.b / 2.
        y2 = self.ys + self.base.b / 2.
        bay = self.bay

        k0 += conn.fkCppy1y2(y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m,
                             bay.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                             bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx,
                             bay.w1rx, bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry,
                             bay.u2ty, bay.u2ry, bay.v1ty, bay.v1ry, bay.v2ty,
                             bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty, bay.w2ry,
                             size, 0, 0)

        k0 += conn.fkCpby1y2(
            y1, y2, ktpb, bay.a, bay.b, self.dpb, bay.m, bay.n, self.base.m,
            self.base.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx,
            bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx,
            bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry, bay.v1ty,
            bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry, bay.w2ty,
            bay.w2ry, self.base.u1tx, self.base.u1rx, self.base.u2tx,
            self.base.u2rx, self.base.v1tx, self.base.v1rx, self.base.v2tx,
            self.base.v2rx, self.base.w1tx, self.base.w1rx, self.base.w2tx,
            self.base.w2rx, self.base.u1ty, self.base.u1ry, self.base.u2ty,
            self.base.u2ry, self.base.v1ty, self.base.v1ry, self.base.v2ty,
            self.base.v2ry, self.base.w1ty, self.base.w1ry, self.base.w2ty,
            self.base.w2ry, size, 0, col0)

        k0 += conn.fkCbbpby1y2(y1, y2, ktpb, bay.a, bay.b, self.base.m,
                               self.base.n, self.base.u1tx, self.base.u1rx,
                               self.base.u2tx, self.base.u2rx, self.base.v1tx,
                               self.base.v1rx, self.base.v2tx, self.base.v2rx,
                               self.base.w1tx, self.base.w1rx, self.base.w2tx,
                               self.base.w2rx, self.base.u1ty, self.base.u1ry,
                               self.base.u2ty, self.base.u2ry, self.base.v1ty,
                               self.base.v1ry, self.base.v2ty, self.base.v2ry,
                               self.base.w1ty, self.base.w1ry, self.base.w2ty,
                               self.base.w2ry, size, row0, col0)

        # connectivity base-flange
        ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte')
        ycte1 = (self.eta_conn_base + 1) / 2. * self.base.b
        ycte2 = (self.eta_conn_flange + 1) / 2. * self.flange.b
        k0 += fkCBFycte11(ktbf, krbf, self.base, ycte1, size, row0, col0)
        k0 += fkCBFycte12(ktbf, krbf, self.base, self.flange, ycte1, ycte2,
                          size, row0, colf)
        k0 += fkCBFycte22(ktbf, krbf, self.base, self.flange, ycte2, size,
                          rowf, colf)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #41
0
    def calc_k0(self, size=None, row0=0, col0=0, silent=False, finalize=True):
        """Calculate the linear constitutive stiffness matrix
        """
        self._rebuild()
        msg('Calculating k0... ', level=2, silent=silent)

        flangemod = panmodelDB.db[self.flange.model]['matrices']

        bay = self.bay
        a = bay.a
        b = bay.b
        m = bay.m
        n = bay.n

        k0 = 0.
        if self.base is not None:
            k0 += self.base.calc_k0(size=size,
                                    row0=0,
                                    col0=0,
                                    silent=True,
                                    finalize=False)
        if self.flange is not None:
            k0 += self.flange.calc_k0(size=size,
                                      row0=row0,
                                      col0=col0,
                                      silent=True,
                                      finalize=False)

            # connectivity between stiffener'base and stiffener's flange
            if self.base is None:
                ktbf, krbf = calc_kt_kr(self.panel1, self.flange, 'ycte')
            else:
                ktbf, krbf = calc_kt_kr(self.base, self.flange, 'ycte')

            mod = db['bladestiff2d_clt_donnell_bardell']['connections']
            k0 += mod.fkCss(ktbf, krbf, self.ys, a, b, m, n, bay.u1tx,
                            bay.u1rx, bay.u2tx, bay.u2rx, bay.v1tx, bay.v1rx,
                            bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx, bay.w2tx,
                            bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                            bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty,
                            bay.w1ry, bay.w2ty, bay.w2ry, size, 0, 0)
            bf = self.flange.b
            k0 += mod.fkCsf(
                ktbf, krbf, self.ys, a, b, bf, m, n, self.flange.m,
                self.flange.n, bay.u1tx, bay.u1rx, bay.u2tx, bay.u2rx,
                bay.v1tx, bay.v1rx, bay.v2tx, bay.v2rx, bay.w1tx, bay.w1rx,
                bay.w2tx, bay.w2rx, bay.u1ty, bay.u1ry, bay.u2ty, bay.u2ry,
                bay.v1ty, bay.v1ry, bay.v2ty, bay.v2ry, bay.w1ty, bay.w1ry,
                bay.w2ty, bay.w2ry, self.flange.u1tx, self.flange.u1rx,
                self.flange.u2tx, self.flange.u2rx, self.flange.v1tx,
                self.flange.v1rx, self.flange.v2tx, self.flange.v2rx,
                self.flange.w1tx, self.flange.w1rx, self.flange.w2tx,
                self.flange.w2rx, self.flange.u1ty, self.flange.u1ry,
                self.flange.u2ty, self.flange.u2ry, self.flange.v1ty,
                self.flange.v1ry, self.flange.v2ty, self.flange.v2ry,
                self.flange.w1ty, self.flange.w1ry, self.flange.w2ty,
                self.flange.w2ry, size, 0, col0)
            k0 += mod.fkCff(
                ktbf, krbf, a, bf, self.flange.m, self.flange.n,
                self.flange.u1tx, self.flange.u1rx, self.flange.u2tx,
                self.flange.u2rx, self.flange.v1tx, self.flange.v1rx,
                self.flange.v2tx, self.flange.v2rx, self.flange.w1tx,
                self.flange.w1rx, self.flange.w2tx, self.flange.w2rx,
                self.flange.u1ty, self.flange.u1ry, self.flange.u2ty,
                self.flange.u2ry, self.flange.v1ty, self.flange.v1ry,
                self.flange.v2ty, self.flange.v2ry, self.flange.w1ty,
                self.flange.w1ry, self.flange.w2ty, self.flange.w2ry, size,
                row0, col0)

        if finalize:
            k0 = finalize_symmetric_matrix(k0)
        self.k0 = k0

        #NOTE forcing Python garbage collector to clean the memory
        #     it DOES make a difference! There is a memory leak not
        #     identified, probably in the csr_matrix process
        gc.collect()

        msg('finished!', level=2, silent=silent)
Пример #42
0
    def calc_Vf(self, rho=None, M=None, modes=(0, 1, 2, 3, 4, 5), num=10,
                silent=False):
        r"""Calculate the flutter speed

        If ``rho`` and ``M`` are not supplied, ``beta`` will be returned.

        Parameters
        ----------
        rho : float, optional
            Air density.
        M : float, optional
            Mach number.
        modes : tuple, optional
            The modes that should be monitored.
        num : int, optional
            Number of points to search for each iteration.

        Returns
        -------
        lambdacr : float
            The critical ``beta``.

        """
        #TODO
        # - use a linear or parabolic interpolation to estimate new_lim1
        msg('Flutter calculation...', level=1, silent=silent)
        lim1 = 0.1
        lim2 = 100.
        new_lim1 = 1e6
        new_lim2 = -1e6
        eigvals_imag = np.zeros((num, len(modes)))
        if max(modes) > self.num_eigvalues-1:
            self.num_eigvalues = max(modes)+1

        count = 0
        while True:
            count += 1
            betas = np.linspace(lim1, lim2, num)
            msg('iteration %d:' % count, level=2, silent=silent)
            msg('lambda_min: %1.3f' % lim1, level=3, silent=silent)
            msg('lambda_max: %1.3f' % lim2, level=3, silent=silent)

            for i, beta in enumerate(betas):
                self.beta = beta
                self.freq(atype=1, sparse_solver=False, silent=True)
                for j, mode in enumerate(modes):
                    eigvals_imag[i, j] = self.eigvals[mode].imag

            check = np.where(eigvals_imag != 0.)
            if not np.any(check):
                continue
            if np.abs(eigvals_imag[check]).min() < 0.01:
                break
            if 0 in check[0]:
                new_lim1 = min(new_lim1, 0.5*betas[check[0][0]])
                new_lim2 = max(new_lim2, 1.5*betas[check[0][-1]])
            elif check[0].min() > 0:
                new_lim1 = betas[check[0][0]-1]
                new_lim2 = betas[check[0][0]]
            else:
                new_lim1 = min(new_lim1, lim1/2.)
                new_lim2 = max(new_lim2, 2*lim2)

            lim1 = new_lim1
            lim2 = new_lim2
        msg('finished!', level=1)
        msg('Number of analyses = %d' % (count*num), level=1)
        return lim1
Пример #43
0
def freq(K, M, tol=0, sparse_solver=True, silent=False,
         sort=True, reduced_dof=False,
         num_eigvalues=25, num_eigvalues_print=5):
    """Frequency Analysis

    Parameters
    ----------
    K : sparse_matrix
        Stiffness matrix. Should include initial stress stiffness matrix,
        aerodynamic matrix and so forth when applicable.
    M : sparse_matrix
        Mass matrix.
    tol : float, optional
        A tolerance value passed to ``scipy.sparse.linalg.eigs``.
    sparse_solver : bool, optional
        Tells if solver :func:`scipy.linalg.eig` or
        :func:`scipy.sparse.linalg.eigs` should be used.

        .. note:: It is recommended ``sparse_solver=False``, because it
                  was verified that the sparse solver becomes unstable
                  for some cases, though the sparse solver is faster.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.
    sort : bool, optional
        Sort the output eigenvalues and eigenmodes.
    reduced_dof : bool, optional
        Considers only the contributions of `v` and `w` to the stiffness
        matrix and accelerates the run. Only effective when
        ``sparse_solver=False``.
    num_eigvalues : int, optional
        Number of calculated eigenvalues.
    num_eigvalues_print : int, optional
        Number of eigenvalues to print.

    Returns
    -------
    The extracted eigenvalues are stored in the ``eigvals`` parameter and
    the `i^{th}` eigenvector in the ``eigvecs[:, i-1]`` parameter.

    """
    msg('Running frequency analysis...', silent=silent)

    msg('Eigenvalue solver... ', level=2, silent=silent)

    k = min(num_eigvalues, M.shape[0]-2)
    if sparse_solver:
        msg('eigs() solver...', level=3, silent=silent)
        sizebkp = M.shape[0]
        K, M, used_cols = remove_null_cols(K, M, silent=silent,
                level=3)
        #NOTE Looking for better performance with symmetric matrices, I tried
        #     using compmech.sparse.is_symmetric and eigsh, but it seems not
        #     to improve speed (I did not try passing only half of the sparse
        #     matrices to the solver)
        eigvals, peigvecs = eigs(A=K, k=k, which='LM', M=M, tol=tol,
                                 sigma=-1.)
        eigvecs = np.zeros((sizebkp, num_eigvalues), dtype=peigvecs.dtype)
        eigvecs[used_cols, :] = peigvecs

        eigvals = np.sqrt(eigvals) # omega^2 to omega, in rad/s

    else:
        msg('eig() solver...', level=3, silent=silent)
        M = M.toarray()
        K = K.toarray()
        sizebkp = M.shape[0]
        col_sum = M.sum(axis=0)
        check = col_sum != 0
        used_cols = np.arange(M.shape[0])[check]
        M = M[:, check][check, :]
        K = K[:, check][check, :]

        if reduced_dof:
            i = np.arange(M.shape[0])
            take = np.column_stack((i[1::3], i[2::3])).flatten()
            M = M[:, take][take, :]
            K = K[:, take][take, :]
        #TODO did not try using eigh when input is symmetric to see if there
        #     will be speed improvements
        eigvals, peigvecs = eig(a=-M, b=K)
        eigvecs = np.zeros((sizebkp, K.shape[0]),
                           dtype=peigvecs.dtype)
        eigvecs[check, :] = peigvecs
        eigvals = np.sqrt(-1./eigvals) # -1/omega^2 to omega, in rad/s
        eigvals = eigvals

    msg('finished!', level=3, silent=silent)

    if sort:
        sort_ind = np.lexsort((np.round(eigvals.imag, 1),
                               np.round(eigvals.real, 1)))
        eigvals = eigvals[sort_ind]
        eigvecs = eigvecs[:, sort_ind]

        higher_zero = eigvals.real > 1e-6

        eigvals = eigvals[higher_zero]
        eigvecs = eigvecs[:, higher_zero]

    if not sparse_solver and reduced_dof:
        new_eigvecs = np.zeros((3*eigvecs.shape[0]//2, eigvecs.shape[1]),
                dtype=eigvecs.dtype)
        new_eigvecs[take, :] = eigvecs
        eigvecs = new_eigvecs


    msg('finished!', level=2, silent=silent)

    msg('first {0} eigenvalues:'.format(num_eigvalues_print), level=1,
        silent=silent)
    for eigval in eigvals[:num_eigvalues_print]:
        msg('{0} rad/s'.format(eigval), level=2, silent=silent)

    return eigvals, eigvecs
Пример #44
0
def _solver_NR(run, silent=False):
    """Newton-Raphson solver

    """
    msg('Initialization...', level=1, silent=silent)

    modified_NR = run.modified_NR
    inc = run.initialInc
    total = inc
    once_at_total = False
    max_total = 0.

    fext = run.calc_fext(inc=inc, silent=silent)
    k0 = run.calc_k0(silent=silent)
    c = solve(k0, fext, silent=silent)
    kT_last = k0

    if modified_NR:
        compute_kT = False
    else:
        compute_kT = True

    step_num = 1
    while True:
        msg('Started Load Step {} - '.format(step_num) +
            'Attempting time = {0}'.format(total),
            level=1,
            silent=silent)

        # TODO maybe for pdC=True, pdT the fext must be calculated with
        # the last kT available...

        absERR = 1.e6
        relERR = 1.e6
        min_Rmax = 1.e6
        prev_Rmax = 1.e6
        last_min_Rmax = 1.e6
        iteration = 0
        converged = False

        kT = kT_last

        fext = run.calc_fext(inc=total, silent=silent)

        iter_NR = 0
        while True:
            iteration += 1
            msg('Iteration: {}'.format(iteration), level=2, silent=silent)
            if iteration > run.maxNumIter:
                warn('Maximum number of iterations achieved!',
                     level=2,
                     silent=silent)
                break

            if compute_kT or (run.kT_initial_state and step_num == 1
                              and iteration
                              == 1) or iter_NR == (run.compute_every_n - 1):
                iter_NR = 0
                kT = run.calc_kT(c=c, inc=total, silent=silent)
            else:
                iter_NR += 1
                if not modified_NR:
                    compute_kT = True

            fint = run.calc_fint(c=c, inc=total, silent=silent)

            R = fext - fint

            # convergence criteria:
            # - maximum residual force Rmax
            Rmax = np.abs(R).max()
            msg('Rmax = {0}'.format(Rmax), level=3, silent=silent)

            if iteration >= 2 and Rmax < run.absTOL:
                converged = True
                break
            if (Rmax > prev_Rmax and Rmax > min_Rmax and iteration > 2):
                warn('Diverged!', level=2, silent=silent)
                break
            else:
                min_Rmax = min(min_Rmax, Rmax)
            change_rate_Rmax = abs(prev_Rmax - Rmax) / abs(prev_Rmax)
            if (iteration > 2 and change_rate_Rmax < run.too_slow_TOL):
                warn('Diverged! (convergence too slow)',
                     level=2,
                     silent=silent)
                break
            prev_Rmax = Rmax

            msg('Solving... ', level=2, silent=silent)
            delta_c = solve(kT, R, silent=silent)
            msg('finished!', level=2, silent=silent)

            eta1 = 0.
            eta2 = 1.
            if run.line_search:
                msg('Performing line-search... ', level=2, silent=silent)
                iter_line_search = 0
                while True:
                    c1 = c + eta1 * delta_c
                    c2 = c + eta2 * delta_c
                    fint1 = run.calc_fint(c=c1, inc=total, silent=silent)
                    fint2 = run.calc_fint(c=c2, inc=total, silent=silent)
                    R1 = fext - fint1
                    R2 = fext - fint2
                    s1 = delta_c.dot(R1)
                    s2 = delta_c.dot(R2)
                    eta_new = (eta2 - eta1) * (-s1 / (s2 - s1)) + eta1
                    eta1 = eta2
                    eta2 = eta_new
                    eta2 = min(max(eta2, 0.2), 10.)
                    if abs(eta2 - eta1) < 0.01:
                        break
                    iter_line_search += 1
                    if iter_line_search == run.max_iter_line_search:
                        eta2 = 1.
                        warn('maxinum number of iterations',
                             level=3,
                             silent=silent)
                        break
                msg('finished!', level=2, silent=silent)
            c = c + eta2 * delta_c

        if converged:
            msg('Finished Load Step {} at'.format(step_num) +
                ' time = {0}'.format(total),
                level=1,
                silent=silent)
            run.increments.append(total)
            run.cs.append(c.copy())  #NOTE copy required
            finished = False
            if abs(total - 1) < 1e-3:
                finished = True
            else:
                factor = 1.1
                if once_at_total:
                    inc_new = min(factor * inc, run.maxInc, (1. - total) / 2)
                else:
                    inc_new = min(factor * inc, run.maxInc, 1. - total)
                msg('Changing time increment from {0:1.9f} to {1:1.9f}'.format(
                    inc, inc_new),
                    level=1,
                    silent=silent)
                inc = inc_new
                total += inc
                total = min(1, total)
                step_num += 1
            if finished:
                break
            if modified_NR:
                msg('Updating kT...', level=1, silent=silent)
                kT = run.calc_kT(c=c, inc=total, silent=silent)
                msg('kT updated!', level=1, silent=silent)
            compute_kT = False
            kT_last = kT
        else:
            max_total = max(max_total, total)
            while True:
                factor = 0.3
                msg('Bisecting time increment from {0} to {1}'.format(
                    inc, inc * factor),
                    level=1,
                    silent=silent)
                if abs(total - 1) < 1e-3:
                    once_at_total = True
                total -= inc
                inc *= factor
                if inc < run.minInc:
                    msg('Minimum step size achieved!', level=1, silent=silent)
                    break
                total += inc
                if total >= max_total:
                    continue
                else:
                    break
            if inc < run.minInc:
                msg('Stopping solver: minimum step size achieved!',
                    level=1,
                    silent=silent)
                break

        if len(run.cs) > 0:
            c = run.cs[-1].copy()  #NOTE copy required
        else:
            # means that run bisection must be done in initialInc
            fext = run.calc_fext(inc=inc, silent=silent)
            c = solve(k0, fext, silent=silent)

    msg('Finished Non-Linear Static Analysis', silent=silent)
    msg('at time {0}'.format(total), level=1, silent=silent)
Пример #45
0
    def plot_skin(self, c, invert_y=False, plot_type=1, vec='w',
             deform_u=False, deform_u_sf=100.,
             filename='',
             ax=None, figsize=(3.5, 2.), save=True,
             add_title=False, title='',
             colorbar=False, cbar_nticks=2, cbar_format=None,
             cbar_title='', cbar_fontsize=10,
             aspect='equal', clean=True, dpi=400,
             texts=[], xs=None, ys=None, gridx=300, gridy=300,
             num_levels=400, vecmin=None, vecmax=None):
        r"""Contour plot for a Ritz constants vector.

        Parameters
        ----------
        c : np.ndarray
            The Ritz constants that will be used to compute the field contour.
        vec : str, optional
            Can be one of the components:

            - Displacement: ``'u'``, ``'v'``, ``'w'``, ``'phix'``, ``'phiy'``
            - Strain: ``'exx'``, ``'eyy'``, ``'gxy'``, ``'kxx'``, ``'kyy'``,
              ``'kxy'``, ``'gyz'``, ``'gxz'``
            - Stress: ``'Nxx'``, ``'Nyy'``, ``'Nxy'``, ``'Mxx'``, ``'Myy'``,
              ``'Mxy'``, ``'Qy'``, ``'Qx'``
        deform_u : bool, optional
            If ``True`` the contour plot will look deformed.
        deform_u_sf : float, optional
            The scaling factor used to deform the contour.
        invert_y : bool, optional
            Inverts the `y` axis of the plot. It may be used to match
            the coordinate system of the finite element models created
            using the ``desicos.abaqus`` module.
        plot_type : int, optional
            For cylinders only ``4`` and ``5`` are valid.
            For cones all the following types can be used:

            - ``1``: concave up (with ``invert_y=False``) (default)
            - ``2``: concave down (with ``invert_y=False``)
            - ``3``: stretched closed
            - ``4``: stretched opened (`r \times y` vs. `a`)
            - ``5``: stretched opened (`y` vs. `a`)

        save : bool, optional
            Flag telling whether the contour should be saved to an image file.
        dpi : int, optional
            Resolution of the saved file in dots per inch.
        filename : str, optional
            The file name for the generated image file. If no value is given,
            the `name` parameter of the :class:`StiffPanelBay` object
            will be used.
        ax : AxesSubplot, optional
            When ``ax`` is given, the contour plot will be created inside it.
        figsize : tuple, optional
            The figure size given by ``(width, height)``.
        add_title : bool, optional
            If a title should be added to the figure.
        title : str, optional
            If any string is given ``add_title`` will be ignored and the given
            title added to the contour plot.
        colorbar : bool, optional
            If a colorbar should be added to the contour plot.
        cbar_nticks : int, optional
            Number of ticks added to the colorbar.
        cbar_format : [ None | format string | Formatter object ], optional
            See the ``matplotlib.pyplot.colorbar`` documentation.
        cbar_fontsize : int, optional
            Fontsize of the colorbar labels.
        cbar_title : str, optional
            Colorbar title. If ``cbar_title == ''`` no title is added.
        aspect : str, optional
            String that will be passed to the ``AxesSubplot.set_aspect()``
            method.
        clean : bool, optional
            Clean axes ticks, grids, spines etc.
        xs : np.ndarray, optional
            The `x` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        ys : np.ndarray, optional
            The ``y`` positions where to calculate the displacement field.
            Default is ``None`` and the method ``_default_field`` is used.
        gridx : int, optional
            Number of points along the `x` axis where to calculate the
            displacement field.
        gridy : int, optional
            Number of points along the `y` where to calculate the
            displacement field.
        num_levels : int, optional
            Number of contour levels (higher values make the contour smoother).
        vecmin : float, optional
            Minimum value for the contour scale (useful to compare with other
            results). If not specified it will be taken from the calculated
            field.
        vecmax : float, optional
            Maximum value for the contour scale.

        Returns
        -------
        ax : matplotlib.axes.Axes
            The Matplotlib object that can be used to modify the current plot
            if needed.

        """
        msg('Plotting contour...')

        ubkp, vbkp, wbkp, phixbkp, phiybkp = (self.u, self.v, self.w,
                                              self.phix, self.phiy)

        import matplotlib.pyplot as plt
        import matplotlib

        msg('Computing field variables...', level=1)
        displs = ['u', 'v', 'w', 'phix', 'phiy']

        if vec in displs:
            self.uvw_skin(c, xs=xs, ys=ys, gridx=gridx, gridy=gridy)
            field = getattr(self, vec)
        else:
            raise ValueError(
                    '{0} is not a valid vec parameter value!'.format(vec))

        msg('Finished!', level=1)

        Xs = self.Xs
        Ys = self.Ys

        if vecmin is None:
            vecmin = field.min()
        if vecmax is None:
            vecmax = field.max()

        levels = linspace(vecmin, vecmax, num_levels)

        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(111)
        else:
            if isinstance(ax, matplotlib.axes.Axes):
                ax = ax
                fig = ax.figure
                save = False
            else:
                raise ValueError('ax must be an Axes object')

        x = Ys
        y = Xs

        if deform_u:
            if vec in displs:
                pass
            else:
                self.uvw_skin(c, xs=xs, ys=ys, gridx=gridx, gridy=gridy)
            field_u = self.u
            field_v = self.v
            y -= deform_u_sf*field_u
            x += deform_u_sf*field_v
        contour = ax.contourf(x, y, field, levels=levels)

        if colorbar:
            from mpl_toolkits.axes_grid1 import make_axes_locatable

            fsize = cbar_fontsize
            divider = make_axes_locatable(ax)
            cax = divider.append_axes('right', size='5%', pad=0.05)
            cbarticks = linspace(vecmin, vecmax, cbar_nticks)
            cbar = plt.colorbar(contour, ticks=cbarticks, format=cbar_format,
                                cax=cax)
            if cbar_title:
                cax.text(0.5, 1.05, cbar_title, horizontalalignment='center',
                         verticalalignment='bottom', fontsize=fsize)
            cbar.outline.remove()
            cbar.ax.tick_params(labelsize=fsize, pad=0., tick2On=False)

        if invert_y == True:
            ax.invert_yaxis()
        ax.invert_xaxis()

        if title != '':
            ax.set_title(str(title))

        elif add_title:
            if self.analysis.last_analysis == 'static':
                ax.set_title('$m, n={0}, {1}$'.format(self.m, self.n))

            elif self.analysis.last_analysis == 'lb':
                ax.set_title(
       r'$m, n={0}, {1}$, $\lambda_{{CR}}={4:1.3e}$'.format(
            self.m, self.n, self.eigvals[0]))

        fig.tight_layout()
        ax.set_aspect(aspect)

        ax.grid(False)
        ax.set_frame_on(False)
        if clean:
            ax.xaxis.set_ticks_position('none')
            ax.yaxis.set_ticks_position('none')
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
        else:
            ax.xaxis.set_ticks_position('bottom')
            ax.yaxis.set_ticks_position('left')

        for kwargs in texts:
            ax.text(transform=ax.transAxes, **kwargs)

        if save:
            if not filename:
                filename = 'test.png'
            fig.savefig(filename, transparent=True,
                        bbox_inches='tight', pad_inches=0.05, dpi=dpi)
            plt.close()

        if ubkp is not None:
            self.u = ubkp
        if vbkp is not None:
            self.v = vbkp
        if wbkp is not None:
            self.w = wbkp
        if phixbkp is not None:
            self.phix = phixbkp
        if phiybkp is not None:
            self.phiy = phiybkp

        msg('finished!')

        return ax
Пример #46
0
def inv_weighted(data, mesh, num_sub, col, ncp=5, power_parameter=2):
    r"""Interpolates the values taken at one group of points into
    another using an inverse-weighted algorithm

    In the inverse-weighted algorithm a number of `n_{CP}` measured points
    of the input parameter ``data`` that are closest to a given node in
    the input parameter ``mesh`` are found and the imperfection value of
    this node (represented by the normal displacement `{w_0}_{node}`) is
    calculated as follows:

    .. math::
        {w_0}_{node} = \frac{\sum_{i}^{n_{CP}}{{w_0}_i\frac{1}{w_i}}}
                            {\sum_{i}^{n_{CP}}{\frac{1}{w_i}}}

    where `w_i` is the imperfection at each measured point, calculated as:

    .. math::
        w_i = \left[(x_{node}-x_i)^2+(y_{node}-y_i)^2+(z_{node}-y_i)^2
              \right]^p

    with `p` being a power parameter that when increased will increase the
    relative influence of a closest point.

    Parameters
    ----------
    data : numpy.ndarray, shape (N, ndim+1)
        The data or an array containing the imperfection file. The values
        to be interpolated must be in the last column.
    mesh : numpy.ndarray, shape (M, ndim)
        The new coordinates where the values will be interpolated to.
    num_sub : int
        The number of sub-sets used during the interpolation. The points
        are divided in sub-sets to increase the algorithm's efficiency.
    col : int
        The index of the column to be used in order to divide the data
        in sub-sets. Note that the first column index is ``0``.
    ncp : int, optional
        Number of closest points used in the inverse-weighted interpolation.
    power_parameter : float, optional
        Power of inverse weighted interpolation function.

    Returns
    -------
    ans : numpy.ndarray
        A 1-D array with the interpolated values. The size of this array
        is ``mesh.shape[0]``.

    """
    if mesh.shape[1] != data.shape[1] - 1:
        raise ValueError('Invalid input: mesh.shape[1] != data.shape[1]')

    msg('Interpolating... ')
    num_sub = int(num_sub)
    mesh_size = mesh.shape[0]

    # memory control
    mem_limit = 1024 * 1024 * 1024 * 8 * 2  # 2 GB
    mem_entries = int(mem_limit / 64)  # if float64 is used
    sec_size = int(mesh_size / num_sub)
    while sec_size**2 * 10 > mem_entries:
        num_sub += 1
        sec_size = int(mesh_size / num_sub)
        if sec_size**2 * 10 <= mem_entries:
            warn('New num_sub: {0}'.format(int(mesh_size / float(sec_size))))
            break

    mesh_seq = np.arange(mesh.shape[0])

    mesh_argsort = np.argsort(mesh[:, col])
    mesh_seq = mesh_seq[mesh_argsort]
    back_argsort = np.argsort(mesh_seq)

    mesh = np.asarray(mesh[mesh_argsort], order='F')

    length = mesh[:, col].max() - mesh[:, col].min()

    data = np.asarray(data[np.argsort(data[:, col])], order='F')

    ans = np.zeros(mesh.shape[0], dtype=mesh.dtype)

    # max_num_limits defines how many times the log will print
    # "processed ... out of ... entries"
    max_num_limits = 10
    for den in range(max_num_limits, 0, -1):
        if num_sub % den == 0:
            limit = int(num_sub / den)
            break

    for i in range(num_sub + 1):
        i_inf = sec_size * i
        i_sup = sec_size * (i + 1)

        if i % limit == 0:
            msg('\t processed {0:7d} out of {1:7d} entries'.format(
                min(i_sup, mesh_size), mesh_size))
        sub_mesh = mesh[i_inf:i_sup]
        if not np.any(sub_mesh):
            continue
        inf = sub_mesh[:, col].min()
        sup = sub_mesh[:, col].max()

        tol = 0.03
        if i == 0 or i == num_sub:
            tol = 0.06

        while True:
            cond1 = data[:, col] >= inf - tol * length
            cond2 = data[:, col] <= sup + tol * length
            cond = np.all(np.array((cond1, cond2)), axis=0)
            sub_data = data[cond]
            if not np.any(sub_data):
                tol += 0.01
            else:
                break

        dist = np.subtract.outer(sub_mesh[:, 0], sub_data[:, 0])**2
        for j in range(1, sub_mesh.shape[1]):
            dist += np.subtract.outer(sub_mesh[:, j], sub_data[:, j])**2
        asort = np.argsort(dist, axis=1)
        lenn = sub_mesh.shape[0]
        lenp = sub_data.shape[0]
        asort_mesh = asort + np.meshgrid(
            np.arange(lenn) * lenp, np.arange(lenp))[0].transpose()
        # getting the distance of the closest points
        dist_cp = np.take(dist, asort_mesh[:, :ncp])
        # avoiding division by zero
        dist_cp[(dist_cp == 0)] == 1.e-12
        # fetching the imperfection of the sub-data
        imp = sub_data[:, -1]
        # taking only the imperfection of the closest points
        imp_cp = np.take(imp, asort[:, :ncp])
        # weight calculation
        total_weight = np.sum(1. / (dist_cp**power_parameter), axis=1)
        weight = 1. / (dist_cp**power_parameter)
        # computing the new imp
        imp_new = np.sum(imp_cp * weight, axis=1) / total_weight
        # updating the answer array
        ans[i_inf:i_sup] = imp_new

    ans = ans[back_argsort]

    msg('Interpolation completed!')

    return ans
Пример #47
0
def lb(K, KG, tol=0, sparse_solver=True, silent=False,
       num_eigvalues=25, num_eigvalues_print=5):
    """Linear Buckling Analysis

    It can also be used for more general eigenvalue analyzes if `K` is the
    tangent stiffness matrix of a given load state.

    Parameters
    ----------
    K : sparse_matrix
        Stiffness matrix. Should include all constant terms of the initial
        stress stiffness matrix, aerodynamic matrix and so forth when
        applicable.
    KG : sparse_matrix
        Initial stress stiffness matrix that multiplies the load multiplcator
        `\lambda` of the eigenvalue problem.
    tol : float, optional
        A float tolerance passsed to the eigenvalue solver.
    sparse_solver : bool, optional
        Tells if solver :func:`scipy.linalg.eigh` or
        :func:`scipy.sparse.linalg.eigsh` should be used.
    silent : bool, optional
        A boolean to tell whether the log messages should be printed.
    num_eigvalues : int, optional
        Number of calculated eigenvalues.
    num_eigvalues_print : int, optional
        Number of eigenvalues to print.

    Notes
    -----
    The extracted eigenvalues are stored in the ``eigvals`` parameter
    of the ``Panel`` object and the `i^{th}` eigenvector in the
    ``eigvecs[:, i-1]`` parameter.

    """
    msg('Running linear buckling analysis...', silent=silent)

    msg('Eigenvalue solver... ', level=2, silent=silent)

    k = min(num_eigvalues, KG.shape[0]-2)
    if sparse_solver:
        mode = 'cayley'
        try:
            msg('eigsh() solver...', level=3, silent=silent)
            eigvals, eigvecs = eigsh(A=KG, k=k,
                    which='SM', M=K, tol=tol, sigma=1., mode=mode)
            msg('finished!', level=3, silent=silent)
        except Exception as e:
            warn(str(e), level=4, silent=silent)
            msg('aborted!', level=3, silent=silent)
            sizebkp = KG.shape[0]
            K, KG, used_cols = remove_null_cols(K, KG, silent=silent)
            msg('eigsh() solver...', level=3, silent=silent)
            eigvals, peigvecs = eigsh(A=KG, k=k,
                    which='SM', M=K, tol=tol, sigma=1., mode=mode)
            msg('finished!', level=3, silent=silent)
            eigvecs = np.zeros((sizebkp, num_eigvalues),
                               dtype=peigvecs.dtype)
            eigvecs[used_cols, :] = peigvecs

    else:
        size = KG.shape[0]
        K, KG, used_cols = remove_null_cols(K, KG, silent=silent)
        K = K.toarray()
        KG = KG.toarray()
        msg('eigh() solver...', level=3, silent=silent)
        eigvals, peigvecs = eigh(a=KG, b=K)
        msg('finished!', level=3, silent=silent)
        eigvecs = np.zeros((size, num_eigvalues), dtype=peigvecs.dtype)
        eigvecs[used_cols, :] = peigvecs[:, :num_eigvalues]

    eigvals = -1./eigvals

    eigvals = eigvals
    eigvecs = eigvecs

    msg('finished!', level=2, silent=silent)

    msg('first {0} eigenvalues:'.format(num_eigvalues_print), level=1,
        silent=silent)

    for eig in eigvals[:num_eigvalues_print]:
        msg('{0}'.format(eig), level=2, silent=silent)

    return eigvals, eigvecs