Exemple #1
0
    def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts,
            blaminaprops, fstack, fplyts, flaminaprops,
            model='tstiff2d_clt_donnell_bardell', mb=15, nb=12, mf=15, nf=12):

        print('\n\nWARNING - TStiff2D no longer recommended!\n'
              '          There is a numerically unstable way to compute the\n'
              '          connection between the skin and stiffener\'s base, it is\n'
              '          recommended to use panel.assembly instead.\n'
              '          Module panel.assembly allows stable ways to perform\n'
              '          connection among panels, and avoids using sliced\n'
              '          integration intervals that were causing trouble in\n'
              '          TStiff2D\n\n')

        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.model = model

        if bstack is None:
            raise ValueError('Base laminate must be defined!')
        self.ys = ys
        y1 = ys - bb/2.
        y2 = ys + bb/2.
        self.base = Panel(a=bay.a, b=bb, r=bay.r, alphadeg=bay.alphadeg,
                stack=bstack, plyts=bplyts, laminaprops=blaminaprops,
                mu=mu, m=mb, n=nb, offset=0.,
                u1tx=1, u1rx=0, u2tx=1, u2rx=0,
                v1tx=1, v1rx=0, v2tx=1, v2rx=0,
                w1tx=1, w1rx=1, w2tx=1, w2rx=1,
                u1ty=1, u1ry=0, u2ty=1, u2ry=0,
                v1ty=1, v1ry=0, v2ty=1, v2ry=0,
                w1ty=1, w1ry=1, w2ty=1, w2ry=1,
                y1=y1, y2=y2)
        self.base._rebuild()

        if fstack is None:
            raise ValueError('Flange laminate must be defined!')
        self.flange = Panel(a=bay.a, b=bf, model='plate_clt_donnell_bardell',
                stack=fstack, plyts=fplyts, laminaprops=flaminaprops,
                mu=mu, m=mf, n=nf, offset=0.,
                u1tx=0, u1rx=0, u2tx=0, u2rx=0,
                v1tx=0, v1rx=0, v2tx=0, v2rx=0,
                w1tx=0, w1rx=1, w2tx=0, w2rx=1,
                u1ty=1, u1ry=0, u2ty=1, u2ry=0,
                v1ty=1, v1ry=0, v2ty=1, v2ry=0,
                w1ty=1, w1ry=1, w2ty=1, w2ry=1)
        self.flange._rebuild()

        self.eta_conn_base = 0.
        self.eta_conn_flange = -1.

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self._rebuild()
Exemple #2
0
    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.m == self.panel2.m
        assert self.panel1.n == self.panel2.n
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg

        if self.fstack is not None:
            self.hf = sum(self.fplyts)
            self.Asf = self.bf*self.hf
            self.flam = laminate.read_stack(self.fstack, plyts=self.fplyts,
                                             laminaprops=self.flaminaprops)
            self.flam.calc_equivalent_modulus()

        h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
        hb = 0.
        if self.bstack is not None:
            hb = sum(self.bplyts)
            y1 = self.ys - self.bb/2.
            y2 = self.ys + self.bb/2.
            self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg,
                    stack=self.bstack, plyts=self.bplyts,
                    mu=self.mu, m=bay.m, n=bay.n,
                    laminaprops=self.blaminaprops, offset=(-h/2.-hb/2.),
                    u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx,
                    v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx,
                    w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx,
                    u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry,
                    v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry,
                    w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry,
                    y1=y1, y2=y2)
            self.Asb = self.bb*hb

        #TODO check offset effect on curved panels
        self.dbf = self.bf/2. + hb + h/2.
        self.Iyy = self.hf*self.bf**3/12.
        self.Jxx = self.hf*self.bf**3/12. + self.bf*self.hf**3/12.

        Asb = self.Asb if self.Asb is not None else 0.
        Asf = self.Asf if self.Asf is not None else 0.
        self.As = Asb + Asf

        if self.fstack is not None:
            self.E1 = 0
            #E3 = 0
            self.S1 = 0
            yply = self.flam.plies[0].t/2.
            for i, ply in enumerate(self.flam.plies):
                if i > 0:
                    yply += self.flam.plies[i-1].t/2. + self.flam.plies[i].t/2.
                q = ply.QL
                self.E1 += ply.t*(q[0,0] - q[0,1]**2/q[1,1])
                #E3 += ply.t*(q[2,2] - q[1,2]**2/q[1,1])
                self.S1 += -yply*ply.t*(q[0,2] - q[0,1]*q[1,2]/q[1,1])

            self.F1 = self.bf**2/12.*self.E1
Exemple #3
0
    def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts,
            blaminaprops, fstack, fplyts, flaminaprops, mf=14, nf=11):
        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.mu = mu
        self.ys = ys
        self.bb = bb
        self.forces_flange = []

        self.bstack = bstack
        self.bplyts = bplyts
        self.blaminaprops = blaminaprops

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self.base = None
        if bstack is not None:
            y1 = self.ys - bb/2.
            y2 = self.ys + bb/2.
            h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg,
                    stack=bstack, plyts=bplyts, laminaprops=blaminaprops,
                    mu=mu, m=bay.m, n=bay.n, offset=(-h/2.-hb/2.),
                    u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx,
                    v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx,
                    w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx,
                    u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry,
                    v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry,
                    w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry,
                    y1=y1, y2=y2)

        self.flange = None
        if fstack is not None:
            self.flange = Panel(m=mf, n=nf, a=bay.a, b=bf, mu=mu,
                    stack=fstack, plyts=fplyts, laminaprops=flaminaprops,
                    model='plate_clt_donnell_bardell',
                    u1tx=0., u1rx=0., u2tx=0., u2rx=0.,
                    v1tx=0., v1rx=0., v2tx=0., v2rx=0.,
                    w1tx=0., w1rx=1., w2tx=0., w2rx=1.,
                    u1ty=1., u1ry=0., u2ty=1., u2ry=0.,
                    v1ty=1., v1ry=0., v2ty=1., v2ry=0.,
                    w1ty=1., w1ry=1., w2ty=1., w2ry=1.)

        self._rebuild()
Exemple #4
0
class BladeStiff2D(object):
    r"""Blade Stiffener using 2D Formulation for Flange

    Blade-type of stiffener model using a 2D formulation for the flange and a
    2D formulation for the base (padup)::


                 || --> flange       |
                 ||                  |-> stiffener
               ======  --> padup     |
      =========================  --> panels
         Panel1      Panel2

    Both the flange and the base are optional. The stiffener's base is modeled
    using the same approximation functions as the skin, with the proper
    offset.

    Each stiffener has a constant `y_s` coordinate.

    """
    def __init__(self,
                 bay,
                 mu,
                 panel1,
                 panel2,
                 ys,
                 bb,
                 bf,
                 bstack,
                 bplyts,
                 blaminaprops,
                 fstack,
                 fplyts,
                 flaminaprops,
                 mf=14,
                 nf=11):
        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.mu = mu
        self.ys = ys
        self.bb = bb
        self.forces_flange = []

        self.bstack = bstack
        self.bplyts = bplyts
        self.blaminaprops = blaminaprops

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self.base = None
        if bstack is not None:
            y1 = self.ys - bb / 2.
            y2 = self.ys + bb / 2.
            h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.base = Panel(a=bay.a,
                              b=bay.b,
                              r=bay.r,
                              alphadeg=bay.alphadeg,
                              stack=bstack,
                              plyts=bplyts,
                              laminaprops=blaminaprops,
                              mu=mu,
                              m=bay.m,
                              n=bay.n,
                              offset=(-h / 2. - hb / 2.),
                              u1tx=bay.u1tx,
                              u1rx=bay.u1rx,
                              u2tx=bay.u2tx,
                              u2rx=bay.u2rx,
                              v1tx=bay.v1tx,
                              v1rx=bay.v1rx,
                              v2tx=bay.v2tx,
                              v2rx=bay.v2rx,
                              w1tx=bay.w1tx,
                              w1rx=bay.w1rx,
                              w2tx=bay.w2tx,
                              w2rx=bay.w2rx,
                              u1ty=bay.u1ty,
                              u1ry=bay.u1ry,
                              u2ty=bay.u2ty,
                              u2ry=bay.u2ry,
                              v1ty=bay.v1ty,
                              v1ry=bay.v1ry,
                              v2ty=bay.v2ty,
                              v2ry=bay.v2ry,
                              w1ty=bay.w1ty,
                              w1ry=bay.w1ry,
                              w2ty=bay.w2ty,
                              w2ry=bay.w2ry,
                              y1=y1,
                              y2=y2)

        self.flange = None
        if fstack is not None:
            self.flange = Panel(m=mf,
                                n=nf,
                                a=bay.a,
                                b=bf,
                                mu=mu,
                                stack=fstack,
                                plyts=fplyts,
                                laminaprops=flaminaprops,
                                model='plate_clt_donnell_bardell',
                                u1tx=0.,
                                u1rx=0.,
                                u2tx=0.,
                                u2rx=0.,
                                v1tx=0.,
                                v1rx=0.,
                                v2tx=0.,
                                v2rx=0.,
                                w1tx=0.,
                                w1rx=1.,
                                w2tx=0.,
                                w2rx=1.,
                                u1ty=1.,
                                u1ry=0.,
                                u2ty=1.,
                                u2ry=0.,
                                v1ty=1.,
                                v1ry=0.,
                                v2ty=1.,
                                v2ry=0.,
                                w1ty=1.,
                                w1ry=1.,
                                w2ty=1.,
                                w2ry=1.)

        self._rebuild()

    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.m == self.panel2.m
        assert self.panel1.n == self.panel2.n
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg
        if self.flange is not None:
            self.flange.lam = laminate.read_stack(
                self.flange.stack,
                plyts=self.flange.plyts,
                laminaprops=self.flange.laminaprops)
            self.flange.lam.calc_equivalent_modulus()

        if self.base is not None:
            h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.dpb = h / 2. + hb / 2.
            self.base.lam = laminate.read_stack(self.bstack,
                                                plyts=self.bplyts,
                                                laminaprops=self.blaminaprops,
                                                offset=(-h / 2. - hb / 2.))

    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)

    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)

    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)

        kM = 0.
        if self.base is not None:
            kM += self.base.calc_kM(size=size,
                                    row0=0,
                                    col0=0,
                                    silent=True,
                                    finalize=False)
        if self.flange is not None:
            kM += self.flange.calc_kM(size=size,
                                      row0=row0,
                                      col0=col0,
                                      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)
def test_fint():
    m = 6
    n = 6
    for model in ['plate_clt_donnell_bardell',
                  'cpanel_clt_donnell_bardell'
                  ]:
        p = Panel()
        p.model = model
        p.w1tx = 0
        p.w1rx = 1
        p.u1tx = 1
        p.u1ty = 1
        p.u2ty = 1
        p.a = 2.
        p.b = 1.
        p.r = 1.e5
        p.stack = [0, 90, -45, +45]
        p.plyt = 1e-3*0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.nx = m
        p.ny = n
        p.m = m
        p.n = n

        P = 1000.
        npts = 100
        p.forces_inc = []
        for y in np.linspace(0, p.b, npts):
            p.forces_inc.append([0., y, P/(npts-1.), 0, 0])
        p.forces_inc[0][2] /= 2.
        p.forces_inc[-1][2] /= 2.
        p.forces.append([p.a/2., p.b/2., 0, 0, 0.001])

        p.static(NLgeom=True, silent=True)
        c = p.analysis.cs[0]
        p.plot(c, vec='w', filename='tmp_test_non_linear.png', colorbar=True)


        p.uvw(p.analysis.cs[0])
        assert np.isclose(p.w.max(), 0.000144768080125, rtol=0.001)
Exemple #6
0
def test_panel_lb():
    for model in [
            'plate_clt_donnell_bardell', 'plate_clt_donnell_bardell_w',
            'cpanel_clt_donnell_bardell', 'kpanel_clt_donnell_bardell'
    ]:
        print('Linear buckling for model {0}'.format(model))
        # ssss
        p = Panel()
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 88.47696, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 85.2912, atol=0.1, rtol=0)

        p.Nxx = 0
        p.Nyy = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 26.45882, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 25.17562, atol=0.1, rtol=0)

        # ssfs
        p = Panel()
        p.u2ty = 1
        p.v2ty = 1
        p.w2ty = 1
        p.u2ry = 1
        p.v2ry = 1
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 17.14427, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 15.842356, atol=0.1, rtol=0)

        p.u2tx = 1
        p.v2tx = 1
        p.w2tx = 1
        p.u2rx = 1
        p.v2rx = 1
        p.u2ty = 0
        p.v2ty = 0
        p.w2ty = 0
        p.u2ry = 0
        p.v2ry = 0
        p.Nxx = 0
        p.Nyy = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 15.809986, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 13.9421988, atol=0.1, rtol=0)
Exemple #7
0
class BladeStiff1D(object):
    r"""Blade Stiffener using 1D Formulation for Flange

    Blade-type of stiffener model using a 1D formulation for the flange and a
    2D formulation for the padup (base)::


                 || --> flange       |
                 ||                  |-> stiffener
               ======  --> padup     |
      =========================  --> panels
         Panel1      Panel2

    Both the flange and the padup are optional, but one must exist.

    Each stiffener has a constant `y` coordinate.

    """
    def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts,
            blaminaprops, fstack, fplyts, flaminaprops):
        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.model = 'bladestiff1d_clt_donnell_bardell'
        self.mu = mu
        self.ys = ys
        self.bb = bb
        self.hb = 0.
        self.bf = bf
        self.hf = 0.

        self.bstack = bstack
        self.bplyts = bplyts
        self.blaminaprops = blaminaprops
        self.base = None
        self.fstack = fstack
        self.fplyts = fplyts
        self.flaminaprops = flaminaprops
        self.flam = None

        self.As = None
        self.Asb = None
        self.Asf = None
        self.Jxx = None
        self.Iyy = None

        self.Fx = None

        self._rebuild()


    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.m == self.panel2.m
        assert self.panel1.n == self.panel2.n
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg

        if self.fstack is not None:
            self.hf = sum(self.fplyts)
            self.Asf = self.bf*self.hf
            self.flam = laminate.read_stack(self.fstack, plyts=self.fplyts,
                                             laminaprops=self.flaminaprops)
            self.flam.calc_equivalent_modulus()

        h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
        hb = 0.
        if self.bstack is not None:
            hb = sum(self.bplyts)
            y1 = self.ys - self.bb/2.
            y2 = self.ys + self.bb/2.
            self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg,
                    stack=self.bstack, plyts=self.bplyts,
                    mu=self.mu, m=bay.m, n=bay.n,
                    laminaprops=self.blaminaprops, offset=(-h/2.-hb/2.),
                    u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx,
                    v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx,
                    w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx,
                    u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry,
                    v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry,
                    w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry,
                    y1=y1, y2=y2)
            self.Asb = self.bb*hb

        #TODO check offset effect on curved panels
        self.dbf = self.bf/2. + hb + h/2.
        self.Iyy = self.hf*self.bf**3/12.
        self.Jxx = self.hf*self.bf**3/12. + self.bf*self.hf**3/12.

        Asb = self.Asb if self.Asb is not None else 0.
        Asf = self.Asf if self.Asf is not None else 0.
        self.As = Asb + Asf

        if self.fstack is not None:
            self.E1 = 0
            #E3 = 0
            self.S1 = 0
            yply = self.flam.plies[0].t/2.
            for i, ply in enumerate(self.flam.plies):
                if i > 0:
                    yply += self.flam.plies[i-1].t/2. + self.flam.plies[i].t/2.
                q = ply.QL
                self.E1 += ply.t*(q[0,0] - q[0,1]**2/q[1,1])
                #E3 += ply.t*(q[2,2] - q[1,2]**2/q[1,1])
                self.S1 += -yply*ply.t*(q[0,2] - q[0,1]*q[1,2]/q[1,1])

            self.F1 = self.bf**2/12.*self.E1


    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)


    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)


    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)
Exemple #8
0
def test_panel_aero():
    for model in ['plate_clt_donnell_bardell',
                  'plate_clt_donnell_bardell_w',
                  'cpanel_clt_donnell_bardell']:
        for atype in [1, 2]:
            print('Flutter Analysis Piston Theory, atype={0}, model={1}'.
                  format(atype, model))
            p = Panel()
            p.model = model
            p.a = 1.
            p.b = 0.5
            p.r = 1.e8
            p.alphadeg = 0.
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3*0.125
            E2 = 8.7e9
            p.laminaprop = (142.5e9, E2, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.mu = 1.5e3
            p.m = 8
            p.n = 9

            # pre-stress applied when atype == 1
            p.Nxx = -60.
            p.Nyy = -5.

            # testing commong methodology based on betastar
            if atype == 1:
                betasstar = np.linspace(150, 350, 40)
            elif atype == 2:
                betasstar = np.linspace(670, 690, 40)
            betas = betasstar/(p.a**3/E2/(len(p.stack)*p.plyt)**3)
            p.beta = betas[0]
            p.freq(atype=1, reduced_dof=False, sparse_solver=False,
                   silent=True)
            out = np.zeros((len(betasstar), p.eigvals.shape[0]),
                    dtype=p.eigvals.dtype)
            for i, beta in enumerate(betas):
                p.beta = beta
                p.freq(atype=2, reduced_dof=False, sparse_solver=False,
                       silent=True)
                eigvals = p.eigvals*p.a**2/(np.pi**2*sum(p.plyts))*np.sqrt(p.mu/E2)
                out[i, :] = eigvals

            ind = np.where(np.any(out.imag != 0, axis=1))[0][0]
            if atype == 1:
                if not model.endswith('_w'):
                    assert np.isclose(betas[ind], 347.16346, atol=0.1, rtol=0)
                else:
                    assert np.isclose(betas[ind], 174.27885, atol=0.1, rtol=0)
            elif atype == 2:
                if not model.endswith('_w'):
                    assert np.isclose(betas[ind], 728.625, atol=0.1, rtol=0)
                else:
                    assert np.isclose(betas[ind], 728.625, atol=0.1, rtol=0)
def test_panel_fkG_num_Fnxny():
    for model in ['plate_clt_donnell_bardell',
                  'cpanel_clt_donnell_bardell']:
        print('Checking fkG_num for model {0}'.format(model))
        # ssss
        p = Panel()
        p.a = 8.
        p.b = 4.
        p.r = 1.e8
        p.stack = [0, 90, 90, 0, -45, +45]
        p.plyt = 1e-3*0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model

        p.Nxx = -1.

        p.m = 8
        p.n = 9

        p.u1ty = 1
        p.u2ty = 1
        p.u2tx = 1

        p.v1tx = 0
        p.v2tx = 1
        p.v1ty = 1
        p.v2ty = 1

        num = 1000.
        f = 0.
        for i in range(int(num)):
            if i == 0 or i == num - 2:
                fx = p.Nxx*p.b/(num-1.)/2.
            else:
                fx = p.Nxx*p.b/(num-1.)
            p.add_force(x=p.a, y=i*p.b/(num-1.), fx=fx, fy=0., fz=0.,
                        cte=True)
            f += fx

        p.static(silent=True)
        c = p.analysis.cs[0]

        p.lb(silent=True)
        assert np.isclose(p.eigvals[0], 4.5290911349518801, atol=0.01, rtol=0)

        nx = 9
        ny = 9
        Fnxny = p.F
        p.lb(silent=True, c=c, Fnxny=Fnxny, nx=nx, ny=ny)
        assert np.isclose(p.eigvals[0], 4.532851973656947, atol=0.01, rtol=0)

        nx = 12
        ny = 10
        Fnxny = np.array([[p.F]*ny]*nx)
        p.lb(silent=True, c=c, Fnxny=Fnxny, nx=nx, ny=ny)
        assert np.isclose(p.eigvals[0], 4.532851973656947, atol=0.01, rtol=0)
Exemple #10
0
def test_panel_aero():
    for model in [
            'plate_clt_donnell_bardell', 'plate_clt_donnell_bardell_w',
            'cpanel_clt_donnell_bardell'
    ]:
        for atype in [1, 2]:
            print(
                'Flutter Analysis Piston Theory, atype={0}, model={1}'.format(
                    atype, model))
            p = Panel()
            p.model = model
            p.a = 1.
            p.b = 0.5
            p.r = 1.e8
            p.alphadeg = 0.
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3 * 0.125
            E2 = 8.7e9
            p.laminaprop = (142.5e9, E2, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.mu = 1.5e3
            p.m = 8
            p.n = 9

            # pre-stress applied when atype == 1
            p.Nxx = -60.
            p.Nyy = -5.

            # testing commong methodology based on betastar
            if atype == 1:
                betasstar = np.linspace(150, 350, 40)
            elif atype == 2:
                betasstar = np.linspace(670, 690, 40)
            betas = betasstar / (p.a**3 / E2 / (len(p.stack) * p.plyt)**3)
            p.beta = betas[0]
            p.freq(atype=1,
                   reduced_dof=False,
                   sparse_solver=False,
                   silent=True)
            out = np.zeros((len(betasstar), p.eigvals.shape[0]),
                           dtype=p.eigvals.dtype)
            for i, beta in enumerate(betas):
                p.beta = beta
                p.freq(atype=2,
                       reduced_dof=False,
                       sparse_solver=False,
                       silent=True)
                eigvals = p.eigvals * p.a**2 / (
                    np.pi**2 * sum(p.plyts)) * np.sqrt(p.mu / E2)
                out[i, :] = eigvals

            ind = np.where(np.any(out.imag != 0, axis=1))[0][0]
            if atype == 1:
                if not model.endswith('_w'):
                    assert np.isclose(betas[ind], 347.16346, atol=0.1, rtol=0)
                else:
                    assert np.isclose(betas[ind], 174.27885, atol=0.1, rtol=0)
            elif atype == 2:
                if not model.endswith('_w'):
                    assert np.isclose(betas[ind], 728.625, atol=0.1, rtol=0)
                else:
                    assert np.isclose(betas[ind], 728.625, atol=0.1, rtol=0)
def test_fint():
    m = 6
    n = 6
    for model in ['plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell']:
        p = Panel()
        p.model = model
        p.w1tx = 0
        p.w1rx = 1
        p.u1tx = 1
        p.u1ty = 1
        p.u2ty = 1
        p.a = 2.
        p.b = 1.
        p.r = 1.e5
        p.stack = [0, 90, -45, +45]
        p.plyt = 1e-3 * 0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.nx = m
        p.ny = n
        p.m = m
        p.n = n

        P = 1000.
        npts = 100
        p.forces_inc = []
        for y in np.linspace(0, p.b, npts):
            p.forces_inc.append([0., y, P / (npts - 1.), 0, 0])
        p.forces_inc[0][2] /= 2.
        p.forces_inc[-1][2] /= 2.
        p.forces.append([p.a / 2., p.b / 2., 0, 0, 0.001])

        p.static(NLgeom=True, silent=True)
        c = p.analysis.cs[0]
        p.plot(c, vec='w', filename='tmp_test_non_linear.png', colorbar=True)

        p.uvw(p.analysis.cs[0])
        assert np.isclose(p.w.max(), 0.000144768080125, rtol=0.001)
Exemple #12
0
def test_lb():
    for model in ['plate_clt_donnell_bardell',
                  'plate_clt_donnell_bardell_w',
                  'cpanel_clt_donnell_bardell',
                  'kpanel_clt_donnell_bardell']:
        print('Linear buckling for model {0}'.format(model))
        # ssss
        p = Panel()
        p.bc_ssss()
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        p.lb(silent=True)
        if '_w' in model:
            assert np.allclose(p.eigvals[0], 88.4769618837)
        else:
            assert np.allclose(p.eigvals[0], 85.2911727144)

        p.Nxx = 0
        p.Nyy = -1
        p.lb(silent=True)
        if '_w' in model:
            assert np.allclose(p.eigvals[0], 26.4588171556)
        else:
            assert np.allclose(p.eigvals[0], 25.1756170679)

        # ssfs
        p = Panel()
        p.bc_ssfs()
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        p.lb(silent=True)
        if '_w' in model:
            assert np.allclose(p.eigvals[0], 17.1442703121)
        else:
            assert np.allclose(p.eigvals[0], 15.8423562314)

        p.bc_sfss()
        p.Nxx = 0
        p.Nyy = -1
        p.lb(silent=True)
        if '_w' in model:
            assert np.allclose(p.eigvals[0], 15.8099861083)
        else:
            assert np.allclose(p.eigvals[0], 13.9421987614)
Exemple #13
0
def test_freq():
    for model in ['plate_clt_donnell_bardell',
                  'plate_clt_donnell_bardell_w',
                  'cpanel_clt_donnell_bardell',
                  'kpanel_clt_donnell_bardell']:
        for atype in [3, 4]:
            print('Frequency Analysis, atype={0}, model={1}'.format(
                  atype, model))
            p = Panel()
            p.model = model
            p.bc_ssss()
            p.a = 1.
            p.b = 0.5
            p.r = 1.e8
            p.alphadeg = 0.
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3*0.125
            p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.mu = 1.3e3
            p.m = 11
            p.n = 12
            p.Nxx = -60.
            p.Nyy = -5.
            p.freq(sparse_solver=True, reduced_dof=False, silent=True,
                   atype=atype)
            if atype == 3:
                if '_w' in model:
                    assert np.allclose(p.eigvals[0], 19.9271684726)
                else:
                    assert np.allclose(p.eigvals[0], 17.8587479369)
            elif atype == 4:
                if '_w' in model:
                    assert np.allclose(p.eigvals[0], 40.3728103572)
                else:
                    assert np.allclose(p.eigvals[0], 39.3147553173)
Exemple #14
0
def create_cylinder_assy(height,
                         r,
                         stack,
                         plyt,
                         laminaprop,
                         npanels,
                         m=8,
                         n=8):
    r"""Cylinder Assembly

    The panel assembly looks like::


        B                             A
         _______ _______ _______ _______
        |       |       |       |       |
        |       |       |       |       |
        |       |       |       |       |
        |  p04  |  p03  |  p02  |  p01  |
        |       |       |       |       |    /\  x
        |       |       |       |       |    |
        |_______|_______|_______|_______|    |
                                             |
                                   y  <-------

    where edges ``A`` and ``B`` are connected to produce the cyclic effect.


    Parameters
    ----------

    height : float
        Cylinder height (along `x`).
    r : float
        Cylinder radius.
    stack : list or tuple
        Stacking sequence for the cylinder.
    plyt : float
        Ply thickness.
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    npanels : int
        The number of panels the cylinder perimiter.
    m, n : int, optional
        Number of approximation terms for each panel.

    Returns
    -------
    assy, conns : tuple
        A tuple containing the assembly and the default connectivity
        list of dictionaries.

    """
    if npanels < 2:
        raise ValueError('At least two panels are needed')
    skin = []
    perimiter = 2 * np.pi * r
    b_skin = perimiter / npanels
    for i in range(npanels):
        y0 = i * b_skin
        panel = Panel(group='skin',
                      x0=0,
                      y0=y0,
                      a=height,
                      b=b_skin,
                      r=r,
                      m=m,
                      n=n,
                      plyt=plyt,
                      stack=stack,
                      laminaprop=laminaprop,
                      u1tx=0,
                      u1rx=1,
                      u2tx=0,
                      u2rx=1,
                      v1tx=0,
                      v1rx=1,
                      v2tx=0,
                      v2rx=1,
                      w1tx=0,
                      w1rx=1,
                      w2tx=0,
                      w2rx=1,
                      u1ty=1,
                      u1ry=1,
                      u2ty=1,
                      u2ry=1,
                      v1ty=1,
                      v1ry=1,
                      v2ty=1,
                      v2ry=1,
                      w1ty=1,
                      w1ry=1,
                      w2ty=1,
                      w2ry=1)
        skin.append(panel)
    conns = []
    skin_loop = skin + [skin[0]]
    for i in range(len(skin)):
        if i != len(skin) - 1:
            p01 = skin_loop[i]
            p02 = skin_loop[i + 1]
            conns.append(
                dict(p1=p01, p2=p02, func='SSycte', ycte1=p01.b, ycte2=0))
        else:
            p01 = skin_loop[i + 1]
            p02 = skin_loop[i]
            conns.append(
                dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b))
    assy = PanelAssembly(skin)

    return assy, conns
Exemple #15
0
class TStiff2D(object):
    r"""T Stiffener using 2D Formulation for the Base and Flange

    T-type of stiffener model using a 2D formulation for the flange and a
    2D formulation for the base::


                 || --> flange       |
                 ||                  |-> stiffener
               ======  --> base      |
      =========================  --> panels
         Panel1      Panel2

    The difference between this model and :class:'.BladeStiff2D' is that here
    the stiffener's base has independent field variables allowing the
    simulation of skin-stiffener debounding effects.

    Each stiffener has a constant `y_s` coordinate.

    """
    def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts,
            blaminaprops, fstack, fplyts, flaminaprops,
            model='tstiff2d_clt_donnell_bardell', mb=15, nb=12, mf=15, nf=12):

        print('\n\nWARNING - TStiff2D no longer recommended!\n'
              '          There is a numerically unstable way to compute the\n'
              '          connection between the skin and stiffener\'s base, it is\n'
              '          recommended to use panel.assembly instead.\n'
              '          Module panel.assembly allows stable ways to perform\n'
              '          connection among panels, and avoids using sliced\n'
              '          integration intervals that were causing trouble in\n'
              '          TStiff2D\n\n')

        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.model = model

        if bstack is None:
            raise ValueError('Base laminate must be defined!')
        self.ys = ys
        y1 = ys - bb/2.
        y2 = ys + bb/2.
        self.base = Panel(a=bay.a, b=bb, r=bay.r, alphadeg=bay.alphadeg,
                stack=bstack, plyts=bplyts, laminaprops=blaminaprops,
                mu=mu, m=mb, n=nb, offset=0.,
                u1tx=1, u1rx=0, u2tx=1, u2rx=0,
                v1tx=1, v1rx=0, v2tx=1, v2rx=0,
                w1tx=1, w1rx=1, w2tx=1, w2rx=1,
                u1ty=1, u1ry=0, u2ty=1, u2ry=0,
                v1ty=1, v1ry=0, v2ty=1, v2ry=0,
                w1ty=1, w1ry=1, w2ty=1, w2ry=1,
                y1=y1, y2=y2)
        self.base._rebuild()

        if fstack is None:
            raise ValueError('Flange laminate must be defined!')
        self.flange = Panel(a=bay.a, b=bf, model='plate_clt_donnell_bardell',
                stack=fstack, plyts=fplyts, laminaprops=flaminaprops,
                mu=mu, m=mf, n=nf, offset=0.,
                u1tx=0, u1rx=0, u2tx=0, u2rx=0,
                v1tx=0, v1rx=0, v2tx=0, v2rx=0,
                w1tx=0, w1rx=1, w2tx=0, w2rx=1,
                u1ty=1, u1ry=0, u2ty=1, u2ry=0,
                v1ty=1, v1ry=0, v2ty=1, v2ry=0,
                w1ty=1, w1ry=1, w2ty=1, w2ry=1)
        self.flange._rebuild()

        self.eta_conn_base = 0.
        self.eta_conn_flange = -1.

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self._rebuild()


    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg
        a = None
        b = None
        if self.panel1 is not None:
            a = self.panel1.a
            b = self.panel1.b
        elif self.panel2 is not None:
            a = self.panel2.a
            b = self.panel2.b
        if a is not None and b is not None:
            if a / b > 10.:
                if self.base.m <= 15 and self.flange.m <= 15:
                    raise RuntimeError('For a/b > 10. use base.m and flange.m > 15')
                else:
                    warn('For a/b > 10. be sure to check convergence for base.m and flange.m')

        self.flange.lam = laminate.read_stack(self.flange.stack,
                plyts=self.flange.plyts, laminaprops=self.flange.laminaprops)
        #NOTE below offset is not needed since it is already considered in the
        #     connectivity matrices, using dpb
        h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
        hb = sum(self.base.plyts)
        self.dpb = h/2. + hb/2.
        self.base.lam = laminate.read_stack(self.base.stack,
                plyts=self.base.plyts, laminaprops=self.base.laminaprops,
                offset=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)


    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)


    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)
Exemple #16
0
    def __init__(self,
                 bay,
                 mu,
                 panel1,
                 panel2,
                 ys,
                 bb,
                 bf,
                 bstack,
                 bplyts,
                 blaminaprops,
                 fstack,
                 fplyts,
                 flaminaprops,
                 mf=14,
                 nf=11):
        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.mu = mu
        self.ys = ys
        self.bb = bb
        self.forces_flange = []

        self.bstack = bstack
        self.bplyts = bplyts
        self.blaminaprops = blaminaprops

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self.base = None
        if bstack is not None:
            y1 = self.ys - bb / 2.
            y2 = self.ys + bb / 2.
            h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.base = Panel(a=bay.a,
                              b=bay.b,
                              r=bay.r,
                              alphadeg=bay.alphadeg,
                              stack=bstack,
                              plyts=bplyts,
                              laminaprops=blaminaprops,
                              mu=mu,
                              m=bay.m,
                              n=bay.n,
                              offset=(-h / 2. - hb / 2.),
                              u1tx=bay.u1tx,
                              u1rx=bay.u1rx,
                              u2tx=bay.u2tx,
                              u2rx=bay.u2rx,
                              v1tx=bay.v1tx,
                              v1rx=bay.v1rx,
                              v2tx=bay.v2tx,
                              v2rx=bay.v2rx,
                              w1tx=bay.w1tx,
                              w1rx=bay.w1rx,
                              w2tx=bay.w2tx,
                              w2rx=bay.w2rx,
                              u1ty=bay.u1ty,
                              u1ry=bay.u1ry,
                              u2ty=bay.u2ty,
                              u2ry=bay.u2ry,
                              v1ty=bay.v1ty,
                              v1ry=bay.v1ry,
                              v2ty=bay.v2ty,
                              v2ry=bay.v2ry,
                              w1ty=bay.w1ty,
                              w1ry=bay.w1ry,
                              w2ty=bay.w2ty,
                              w2ry=bay.w2ry,
                              y1=y1,
                              y2=y2)

        self.flange = None
        if fstack is not None:
            self.flange = Panel(m=mf,
                                n=nf,
                                a=bay.a,
                                b=bf,
                                mu=mu,
                                stack=fstack,
                                plyts=fplyts,
                                laminaprops=flaminaprops,
                                model='plate_clt_donnell_bardell',
                                u1tx=0.,
                                u1rx=0.,
                                u2tx=0.,
                                u2rx=0.,
                                v1tx=0.,
                                v1rx=0.,
                                v2tx=0.,
                                v2rx=0.,
                                w1tx=0.,
                                w1rx=1.,
                                w2tx=0.,
                                w2rx=1.,
                                u1ty=1.,
                                u1ry=0.,
                                u2ty=1.,
                                u2ry=0.,
                                v1ty=1.,
                                v1ry=0.,
                                v2ty=1.,
                                v2ry=0.,
                                w1ty=1.,
                                w1ry=1.,
                                w2ty=1.,
                                w2ry=1.)

        self._rebuild()
Exemple #17
0
def test_4panels_kt_kr():
    """Compare result of 4 assembled panels with single-domain results

    The panel assembly looks like::

         _________ _____
        |         |     |
        |         |     |
        |   p01   | p02 |
        |         |     |
        |_________|_____|
        |   p03   | p04 |
        |         |     |
        |         |     |
        |         |     |
        |         |     |
        |         |     |
        |_________|_____|

    """
    print('Testing validity of the default kt and kr values')

    plyt = 1.e-3 * 0.125
    laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
    stack = [0, 45, -45, 90, -45, 45, 0]
    lam = laminate.read_stack(stack=stack, plyt=plyt, laminaprop=laminaprop)

    mu = 1.3e3

    r = 10.
    m = 8
    n = 8

    a1 = 1.5
    a2 = 1.5
    a3 = 2.5
    a4 = 2.5
    b1 = 1.5
    b2 = 0.5
    b3 = 1.5
    b4 = 0.5

    A11 = lam.ABD[0, 0]
    A22 = lam.ABD[1, 1]
    D11 = lam.ABD[3, 3]
    D22 = lam.ABD[4, 4]

    p01 = Panel(group='panels',
                x0=a3,
                y0=b2,
                a=a1,
                b=b1,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack,
                laminaprop=laminaprop,
                mu=mu)
    p02 = Panel(group='panels',
                x0=a3,
                y0=0,
                a=a2,
                b=b2,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack,
                laminaprop=laminaprop,
                mu=mu)
    p03 = Panel(group='panels',
                x0=0,
                y0=b2,
                a=a3,
                b=b3,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack,
                laminaprop=laminaprop,
                mu=mu)
    p04 = Panel(group='panels',
                x0=0,
                y0=0,
                a=a4,
                b=b4,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack,
                laminaprop=laminaprop,
                mu=mu)

    kt13, kr13 = connections.calc_kt_kr(p01, p03, 'xcte')
    kt24, kr24 = connections.calc_kt_kr(p02, p04, 'xcte')
    kt12, kr12 = connections.calc_kt_kr(p01, p02, 'ycte')
    kt34, kr34 = connections.calc_kt_kr(p03, p04, 'ycte')

    # boundary conditions
    p01.u1tx = 1
    p01.u1rx = 1
    p01.u2tx = 0
    p01.u2rx = 1
    p01.v1tx = 1
    p01.v1rx = 1
    p01.v2tx = 0
    p01.v2rx = 1
    p01.w1tx = 1
    p01.w1rx = 1
    p01.w2tx = 0
    p01.w2rx = 1
    p01.u1ty = 1
    p01.u1ry = 1
    p01.u2ty = 0
    p01.u2ry = 1
    p01.v1ty = 1
    p01.v1ry = 1
    p01.v2ty = 0
    p01.v2ry = 1
    p01.w1ty = 1
    p01.w1ry = 1
    p01.w2ty = 0
    p01.w2ry = 1

    p02.u1tx = 1
    p02.u1rx = 1
    p02.u2tx = 0
    p02.u2rx = 1
    p02.v1tx = 1
    p02.v1rx = 1
    p02.v2tx = 0
    p02.v2rx = 1
    p02.w1tx = 1
    p02.w1rx = 1
    p02.w2tx = 0
    p02.w2rx = 1
    p02.u1ty = 0
    p02.u1ry = 1
    p02.u2ty = 1
    p02.u2ry = 1
    p02.v1ty = 0
    p02.v1ry = 1
    p02.v2ty = 1
    p02.v2ry = 1
    p02.w1ty = 0
    p02.w1ry = 1
    p02.w2ty = 1
    p02.w2ry = 1

    p03.u1tx = 0
    p03.u1rx = 1
    p03.u2tx = 1
    p03.u2rx = 1
    p03.v1tx = 0
    p03.v1rx = 1
    p03.v2tx = 1
    p03.v2rx = 1
    p03.w1tx = 0
    p03.w1rx = 1
    p03.w2tx = 1
    p03.w2rx = 1
    p03.u1ty = 1
    p03.u1ry = 1
    p03.u2ty = 0
    p03.u2ry = 1
    p03.v1ty = 1
    p03.v1ry = 1
    p03.v2ty = 0
    p03.v2ry = 1
    p03.w1ty = 1
    p03.w1ry = 1
    p03.w2ty = 0
    p03.w2ry = 1

    p04.u1tx = 0
    p04.u1rx = 1
    p04.u2tx = 1
    p04.u2rx = 1
    p04.v1tx = 0
    p04.v1rx = 1
    p04.v2tx = 1
    p04.v2rx = 1
    p04.w1tx = 0
    p04.w1rx = 1
    p04.w2tx = 1
    p04.w2rx = 1
    p04.u1ty = 0
    p04.u1ry = 1
    p04.u2ty = 1
    p04.u2ry = 1
    p04.v1ty = 0
    p04.v1ry = 1
    p04.v2ty = 1
    p04.v2ry = 1
    p04.w1ty = 0
    p04.w1ry = 1
    p04.w2ty = 1
    p04.w2ry = 1

    conndict = [
        dict(p1=p01,
             p2=p02,
             func='SSycte',
             ycte1=0,
             ycte2=p02.b,
             kt=kt12,
             kr=kr12),
        dict(p1=p01,
             p2=p03,
             func='SSxcte',
             xcte1=0,
             xcte2=p03.a,
             kt=kt13,
             kr=kr13),
        dict(p1=p02,
             p2=p04,
             func='SSxcte',
             xcte1=0,
             xcte2=p04.a,
             kt=kt24,
             kr=kr24),
        dict(p1=p03,
             p2=p04,
             func='SSycte',
             ycte1=0,
             ycte2=p04.b,
             kt=kt34,
             kr=kr34),
    ]

    panels = [p01, p02, p03, p04]

    size = sum([3 * p.m * p.n for p in panels])

    k0 = 0
    kM = 0

    row0 = 0
    col0 = 0
    for p in panels:
        k0 += p.calc_k0(row0=row0,
                        col0=col0,
                        size=size,
                        silent=True,
                        finalize=False)
        kM += p.calc_kM(row0=row0,
                        col0=col0,
                        size=size,
                        silent=True,
                        finalize=False)
        p.row_start = row0
        p.col_start = col0
        row0 += 3 * p.m * p.n
        col0 += 3 * p.m * p.n
        p.row_end = row0
        p.col_end = col0

    for conn in conndict:
        if conn.get('has_deffect'):  # connecting if there is no deffect
            continue
        p1 = conn['p1']
        p2 = conn['p2']
        if conn['func'] == 'SSycte':
            k0 += connections.kCSSycte.fkCSSycte11(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   conn['ycte1'],
                                                   size,
                                                   p1.row_start,
                                                   col0=p1.col_start)
            k0 += connections.kCSSycte.fkCSSycte12(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   p2,
                                                   conn['ycte1'],
                                                   conn['ycte2'],
                                                   size,
                                                   p1.row_start,
                                                   col0=p2.col_start)
            k0 += connections.kCSSycte.fkCSSycte22(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   p2,
                                                   conn['ycte2'],
                                                   size,
                                                   p2.row_start,
                                                   col0=p2.col_start)
        elif conn['func'] == 'SSxcte':
            k0 += connections.kCSSxcte.fkCSSxcte11(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   conn['xcte1'],
                                                   size,
                                                   p1.row_start,
                                                   col0=p1.col_start)
            k0 += connections.kCSSxcte.fkCSSxcte12(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   p2,
                                                   conn['xcte1'],
                                                   conn['xcte2'],
                                                   size,
                                                   p1.row_start,
                                                   col0=p2.col_start)
            k0 += connections.kCSSxcte.fkCSSxcte22(conn['kt'],
                                                   conn['kr'],
                                                   p1,
                                                   p2,
                                                   conn['xcte2'],
                                                   size,
                                                   p2.row_start,
                                                   col0=p2.col_start)

    assert np.any(np.isnan(k0.data)) == False
    assert np.any(np.isinf(k0.data)) == False
    k0 = csr_matrix(make_symmetric(k0))
    assert np.any(np.isnan(kM.data)) == False
    assert np.any(np.isinf(kM.data)) == False
    kM = csr_matrix(make_symmetric(kM))

    eigvals, eigvecs = freq(k0,
                            kM,
                            tol=0,
                            sparse_solver=True,
                            silent=True,
                            sort=True,
                            reduced_dof=False,
                            num_eigvalues=25,
                            num_eigvalues_print=5)

    # Results for single panel
    m = 15
    n = 15
    singlepanel = Panel(a=(a1 + a3),
                        b=(b1 + b2),
                        r=r,
                        m=m,
                        n=n,
                        plyt=plyt,
                        stack=stack,
                        laminaprop=laminaprop,
                        mu=mu)
    singlepanel.freq(silent=True)

    assert np.isclose(eigvals[0], singlepanel.eigvals[0], atol=0.01, rtol=0.01)
Exemple #18
0
def test_panel_lb():
    for model in ['plate_clt_donnell_bardell',
                  'plate_clt_donnell_bardell_w',
                  'cpanel_clt_donnell_bardell',
                  'kpanel_clt_donnell_bardell']:
        print('Linear buckling for model {0}'.format(model))
        # ssss
        p = Panel()
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 88.47696, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 85.2912, atol=0.1, rtol=0)

        p.Nxx = 0
        p.Nyy = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 26.45882, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 25.17562, atol=0.1, rtol=0)

        # ssfs
        p = Panel()
        p.u2ty = 1
        p.v2ty = 1
        p.w2ty = 1
        p.u2ry = 1
        p.v2ry = 1
        p.m = 12
        p.n = 13
        p.stack = [0, 90, -45, +45]
        p.plyt = 0.125e-3
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 1.e8
        p.alphadeg = 0.
        p.Nxx = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 17.14427, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 15.842356, atol=0.1, rtol=0)

        p.u2tx = 1
        p.v2tx = 1
        p.w2tx = 1
        p.u2rx = 1
        p.v2rx = 1
        p.u2ty = 0
        p.v2ty = 0
        p.w2ty = 0
        p.u2ry = 0
        p.v2ry = 0
        p.Nxx = 0
        p.Nyy = -1
        k0 = p.calc_k0(silent=True)
        kG0 = p.calc_kG0(silent=True)
        eigvals, eigvecs = lb(k0, kG0, silent=True)
        if '_w' in model:
            assert np.isclose(eigvals[0], 15.809986, atol=0.1, rtol=0)
        else:
            assert np.isclose(eigvals[0], 13.9421988, atol=0.1, rtol=0)
Exemple #19
0
def test_panel_freq():
    for model in ['plate_clt_donnell_bardell',
                  'plate_clt_donnell_bardell_w',
                  'cpanel_clt_donnell_bardell',
                  'kpanel_clt_donnell_bardell']:
        for prestress in [True, False]:
            print('Frequency Analysis, prestress={0}, model={1}'.format(
                  prestress, model))
            p = Panel()
            p.model = model
            p.a = 1.
            p.b = 0.5
            p.r = 1.e8
            p.alphadeg = 0.
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3*0.125
            p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.mu = 1.3e3
            p.m = 11
            p.n = 12
            p.Nxx = -60.
            p.Nyy = -5.
            k0 = p.calc_k0(silent=True)
            M = p.calc_kM(silent=True)
            if prestress:
                kG0 = p.calc_kG0(silent=True)
                k0 += kG0
            eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True)
            if prestress:
                if '_w' in model:
                    assert np.isclose(eigvals[0], 19.9272, rtol=0.001)
                else:
                    assert np.isclose(eigvals[0], 17.85875, rtol=0.001)
            else:
                if '_w' in model:
                    assert np.isclose(eigvals[0], 40.37281, rtol=0.001)
                else:
                    assert np.isclose(eigvals[0], 39.31476, rtol=0.001)
def tstiff2d_1stiff_compression(a, b, ys, bb, bf, defect_a, mu, plyt,
        laminaprop, stack_skin, stack_base, stack_flange,
        Nxx_skin, Nxx_base, Nxx_flange, run_static_case=True,
        r=None, m=8, n=8, mb=None, nb=None, mf=None, nf=None,
        nx=None, ny=None, nxb=None, nyb=None, nxf=None, nyf=None):
    r"""Linear Buckling of T-Stiffened panel with debonding defect

    The panel assembly looks like::

        skin
         _________ _____ _________
        |         |     |         |
        |         |     |         |
        |   p01   | p02 |   p03   |
        |         |     |         |
        |_________|_____|_________|
        |   p04   | p05 |   p06   |      /\  x
        |_________|_____|_________|       |
        |         |     |         |       |
        |         |     |         |       |
        |   p07   | p08 |   p09   |
        |         |     |         |
        |         |     |         |
        |_________|_____|_________|
               loaded edge

                  base            flange
                   _____           _____
                  |     |         |     |
                  |     |         |     |
                  | p10 |         | p11 |
                  |     |         |     |
                  |_____|         |_____|
                  | p12 |         | p13 |
                  |_____|         |_____|
                  |     |         |     |
                  |     |         |     |
                  | p14 |         | p15 |
                  |     |         |     |
                  |     |         |     |
                  |_____|         |_____|
               loaded edge     loaded edge

    For more details about the theory involved, see
    [castro2017AssemblyModels]_.

    Parameters
    ----------

    a : float
        Total length of the assembly (along `x`).
    b : float
        Total width of the assembly (along `y`).
    ys : float
        Position of the stiffener along `y`.
    bb : float
        Stiffener's base width.
    bf : float
        Stiffener's flange width.
    defect_a : float
        Debonding defect/assembly length ratio.
    mu : float
        Material density.
    plyt : float
        Ply thickness.
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    stack_skin : list or tuple
        Stacking sequence for the skin.
    stack_base : list or tuple
        Stacking sequence for the stiffener's base.
    stack_flange : list or tuple
        Stacking sequence for the stiffener's flange.
    Nxx_skin : float
        Skin load distributed at the assembly edge at `x=0`.
    Nxx_base : float
        Stiffener's base load distributed at the assembly edge at `x=0`.
    Nxx_flange : float
        Stiffener's flange load distributed at the assembly edge at `x=0`.
    run_static_case : bool, optional
        If True a static analysis is run before the linear buckling analysis
        to compute the real membrane stress state along the domain, otherwise
        it is assumed constant values of `N_{xx}` for all components.
    r : float or None, optional
        Radius of the stiffened panel.
    m, n : int, optional
        Number of terms of the approximation function for the skin.
    mb, nb : int, optional
        Number of terms of the approximation function for the stiffener's base.
    mf, nf : int, optional
        Number of terms of the approximation function for the stiffener's
        flange.
    nx, ny, nxb, nyb, nxf, nyf : int, optional
        Define of integration points used for skin, stiffener's base or flange;
        along x and y. Keeping ``None`` will use the default (see
        :class:`.Panel`).

    Examples
    --------

    The following example is one of the test cases:

    .. literalinclude:: ../../../../../compmech/panel/assembly/tests/test_tstiff2d_assembly.py
        :pyobject: test_tstiff2d_1stiff_compression

    """
    defect = defect_a * a
    has_defect = True if defect > 0 else False
    defect = 0.33*a if defect == 0 else defect # to avoid weird domains
    aup = (a - defect)/2.
    alow = (a - defect)/2.
    bleft = b - ys - bb/2.
    bright = ys - bb/2.
    mb = m if mb is None else mb
    nb = n if nb is None else nb
    mf = m if mf is None else mf
    nf = n if nf is None else nf
    nx = m if nx is None else nx
    ny = n if ny is None else ny
    nxb = mb if nxb is None else nxb
    nyb = nb if nyb is None else nyb
    nxf = mf if nxf is None else nxf
    nyf = nf if nyf is None else nyf

    # skin panels
    p01 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=ys+bb/2., a=aup, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p02 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p03 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=0,        a=aup, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    # defect
    p04 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=ys+bb/2., a=defect, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p05 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p06 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=0,        a=defect, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    #
    p07 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=ys+bb/2., a=alow, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p08 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)
    p09 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=0,        a=alow, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, nx=nx, ny=ny)

    # stiffeners
    p10 = Panel(group='base', Nxx=Nxx_base, x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu, nx=nxb, ny=nyb)
    p11 = Panel(group='flange', Nxx=Nxx_flange, x0=alow+defect, y0=0,        a=aup, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu, nx=nxf, ny=nyf)
    # defect
    p12 = Panel(group='base', Nxx=Nxx_base, x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu, nx=nxb, ny=nyb)
    p13 = Panel(group='flange', Nxx=Nxx_flange, x0=alow, y0=0,        a=defect, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu, nx=nxf, ny=nyf)
    #
    p14 = Panel(group='base', Nxx=Nxx_base, x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu, nx=nxb, ny=nyb)
    p15 = Panel(group='flange', Nxx=Nxx_flange, x0=0, y0=0,        a=alow, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu, nx=nxf, ny=nyf)

    # boundary conditions
    p01.u1tx = 1 ; p01.u1rx = 1 ; p01.u2tx = 0 ; p01.u2rx = 1
    p01.v1tx = 1 ; p01.v1rx = 1 ; p01.v2tx = 0 ; p01.v2rx = 1
    p01.w1tx = 1 ; p01.w1rx = 1 ; p01.w2tx = 0 ; p01.w2rx = 1
    p01.u1ty = 1 ; p01.u1ry = 1 ; p01.u2ty = 1 ; p01.u2ry = 1
    p01.v1ty = 1 ; p01.v1ry = 1 ; p01.v2ty = 0 ; p01.v2ry = 1
    p01.w1ty = 1 ; p01.w1ry = 1 ; p01.w2ty = 0 ; p01.w2ry = 1

    p02.u1tx = 1 ; p02.u1rx = 1 ; p02.u2tx = 0 ; p02.u2rx = 1
    p02.v1tx = 1 ; p02.v1rx = 1 ; p02.v2tx = 0 ; p02.v2rx = 1
    p02.w1tx = 1 ; p02.w1rx = 1 ; p02.w2tx = 0 ; p02.w2rx = 1
    p02.u1ty = 1 ; p02.u1ry = 1 ; p02.u2ty = 1 ; p02.u2ry = 1
    p02.v1ty = 1 ; p02.v1ry = 1 ; p02.v2ty = 1 ; p02.v2ry = 1
    p02.w1ty = 1 ; p02.w1ry = 1 ; p02.w2ty = 1 ; p02.w2ry = 1

    p03.u1tx = 1 ; p03.u1rx = 1 ; p03.u2tx = 0 ; p03.u2rx = 1
    p03.v1tx = 1 ; p03.v1rx = 1 ; p03.v2tx = 0 ; p03.v2rx = 1
    p03.w1tx = 1 ; p03.w1rx = 1 ; p03.w2tx = 0 ; p03.w2rx = 1
    p03.u1ty = 1 ; p03.u1ry = 1 ; p03.u2ty = 1 ; p03.u2ry = 1
    p03.v1ty = 0 ; p03.v1ry = 1 ; p03.v2ty = 1 ; p03.v2ry = 1
    p03.w1ty = 0 ; p03.w1ry = 1 ; p03.w2ty = 1 ; p03.w2ry = 1

    p04.u1tx = 1 ; p04.u1rx = 1 ; p04.u2tx = 1 ; p04.u2rx = 1
    p04.v1tx = 1 ; p04.v1rx = 1 ; p04.v2tx = 1 ; p04.v2rx = 1
    p04.w1tx = 1 ; p04.w1rx = 1 ; p04.w2tx = 1 ; p04.w2rx = 1
    p04.u1ty = 1 ; p04.u1ry = 1 ; p04.u2ty = 1 ; p04.u2ry = 1
    p04.v1ty = 1 ; p04.v1ry = 1 ; p04.v2ty = 0 ; p04.v2ry = 1
    p04.w1ty = 1 ; p04.w1ry = 1 ; p04.w2ty = 0 ; p04.w2ry = 1

    p05.u1tx = 1 ; p05.u1rx = 1 ; p05.u2tx = 1 ; p05.u2rx = 1
    p05.v1tx = 1 ; p05.v1rx = 1 ; p05.v2tx = 1 ; p05.v2rx = 1
    p05.w1tx = 1 ; p05.w1rx = 1 ; p05.w2tx = 1 ; p05.w2rx = 1
    p05.u1ty = 1 ; p05.u1ry = 1 ; p05.u2ty = 1 ; p05.u2ry = 1
    p05.v1ty = 1 ; p05.v1ry = 1 ; p05.v2ty = 1 ; p05.v2ry = 1
    p05.w1ty = 1 ; p05.w1ry = 1 ; p05.w2ty = 1 ; p05.w2ry = 1

    p06.u1tx = 1 ; p06.u1rx = 1 ; p06.u2tx = 1 ; p06.u2rx = 1
    p06.v1tx = 1 ; p06.v1rx = 1 ; p06.v2tx = 1 ; p06.v2rx = 1
    p06.w1tx = 1 ; p06.w1rx = 1 ; p06.w2tx = 1 ; p06.w2rx = 1
    p06.u1ty = 1 ; p06.u1ry = 1 ; p06.u2ty = 1 ; p06.u2ry = 1
    p06.v1ty = 0 ; p06.v1ry = 1 ; p06.v2ty = 1 ; p06.v2ry = 1
    p06.w1ty = 0 ; p06.w1ry = 1 ; p06.w2ty = 1 ; p06.w2ry = 1

    if run_static_case:
        p07.u1tx = 1 ; p07.u1rx = 1 ; p07.u2tx = 1 ; p07.u2rx = 1
    else:
        p07.u1tx = 0 ; p07.u1rx = 1 ; p07.u2tx = 1 ; p07.u2rx = 1
    p07.v1tx = 0 ; p07.v1rx = 1 ; p07.v2tx = 1 ; p07.v2rx = 1
    p07.w1tx = 0 ; p07.w1rx = 1 ; p07.w2tx = 1 ; p07.w2rx = 1
    p07.u1ty = 1 ; p07.u1ry = 1 ; p07.u2ty = 1 ; p07.u2ry = 1
    p07.v1ty = 1 ; p07.v1ry = 1 ; p07.v2ty = 0 ; p07.v2ry = 1
    p07.w1ty = 1 ; p07.w1ry = 1 ; p07.w2ty = 0 ; p07.w2ry = 1

    if run_static_case:
        p08.u1tx = 1 ; p08.u1rx = 1 ; p08.u2tx = 1 ; p08.u2rx = 1
    else:
        p08.u1tx = 0 ; p08.u1rx = 1 ; p08.u2tx = 1 ; p08.u2rx = 1
    p08.v1tx = 0 ; p08.v1rx = 1 ; p08.v2tx = 1 ; p08.v2rx = 1
    p08.w1tx = 0 ; p08.w1rx = 1 ; p08.w2tx = 1 ; p08.w2rx = 1
    p08.u1ty = 1 ; p08.u1ry = 1 ; p08.u2ty = 1 ; p08.u2ry = 1
    p08.v1ty = 1 ; p08.v1ry = 1 ; p08.v2ty = 1 ; p08.v2ry = 1
    p08.w1ty = 1 ; p08.w1ry = 1 ; p08.w2ty = 1 ; p08.w2ry = 1

    if run_static_case:
        p09.u1tx = 1 ; p09.u1rx = 1 ; p09.u2tx = 1 ; p09.u2rx = 1
    else:
        p09.u1tx = 0 ; p09.u1rx = 1 ; p09.u2tx = 1 ; p09.u2rx = 1
    p09.v1tx = 0 ; p09.v1rx = 1 ; p09.v2tx = 1 ; p09.v2rx = 1
    p09.w1tx = 0 ; p09.w1rx = 1 ; p09.w2tx = 1 ; p09.w2rx = 1
    p09.u1ty = 1 ; p09.u1ry = 1 ; p09.u2ty = 1 ; p09.u2ry = 1
    p09.v1ty = 0 ; p09.v1ry = 1 ; p09.v2ty = 1 ; p09.v2ry = 1
    p09.w1ty = 0 ; p09.w1ry = 1 ; p09.w2ty = 1 ; p09.w2ry = 1

    # base up
    p10.u1tx = 1 ; p10.u1rx = 1 ; p10.u2tx = 1 ; p10.u2rx = 1
    p10.v1tx = 1 ; p10.v1rx = 1 ; p10.v2tx = 1 ; p10.v2rx = 1
    p10.w1tx = 1 ; p10.w1rx = 1 ; p10.w2tx = 1 ; p10.w2rx = 1
    p10.u1ty = 1 ; p10.u1ry = 1 ; p10.u2ty = 1 ; p10.u2ry = 1
    p10.v1ty = 1 ; p10.v1ry = 1 ; p10.v2ty = 1 ; p10.v2ry = 1
    p10.w1ty = 1 ; p10.w1ry = 1 ; p10.w2ty = 1 ; p10.w2ry = 1

    # flange up
    p11.u1tx = 1 ; p11.u1rx = 1 ; p11.u2tx = 0 ; p11.u2rx = 1
    p11.v1tx = 1 ; p11.v1rx = 1 ; p11.v2tx = 0 ; p11.v2rx = 1
    p11.w1tx = 1 ; p11.w1rx = 1 ; p11.w2tx = 0 ; p11.w2rx = 1
    p11.u1ty = 1 ; p11.u1ry = 1 ; p11.u2ty = 1 ; p11.u2ry = 1
    p11.v1ty = 1 ; p11.v1ry = 1 ; p11.v2ty = 1 ; p11.v2ry = 1
    p11.w1ty = 1 ; p11.w1ry = 1 ; p11.w2ty = 1 ; p11.w2ry = 1

    # base mid
    p12.u1tx = 1 ; p12.u1rx = 1 ; p12.u2tx = 1 ; p12.u2rx = 1
    p12.v1tx = 1 ; p12.v1rx = 1 ; p12.v2tx = 1 ; p12.v2rx = 1
    p12.w1tx = 1 ; p12.w1rx = 1 ; p12.w2tx = 1 ; p12.w2rx = 1
    p12.u1ty = 1 ; p12.u1ry = 1 ; p12.u2ty = 1 ; p12.u2ry = 1
    p12.v1ty = 1 ; p12.v1ry = 1 ; p12.v2ty = 1 ; p12.v2ry = 1
    p12.w1ty = 1 ; p12.w1ry = 1 ; p12.w2ty = 1 ; p12.w2ry = 1

    # flange mid
    p13.u1tx = 1 ; p13.u1rx = 1 ; p13.u2tx = 1 ; p13.u2rx = 1
    p13.v1tx = 1 ; p13.v1rx = 1 ; p13.v2tx = 1 ; p13.v2rx = 1
    p13.w1tx = 1 ; p13.w1rx = 1 ; p13.w2tx = 1 ; p13.w2rx = 1
    p13.u1ty = 1 ; p13.u1ry = 1 ; p13.u2ty = 1 ; p13.u2ry = 1
    p13.v1ty = 1 ; p13.v1ry = 1 ; p13.v2ty = 1 ; p13.v2ry = 1
    p13.w1ty = 1 ; p13.w1ry = 1 ; p13.w2ty = 1 ; p13.w2ry = 1

    # base low
    p14.u1tx = 1 ; p14.u1rx = 1 ; p14.u2tx = 1 ; p14.u2rx = 1
    p14.v1tx = 1 ; p14.v1rx = 1 ; p14.v2tx = 1 ; p14.v2rx = 1
    p14.w1tx = 1 ; p14.w1rx = 1 ; p14.w2tx = 1 ; p14.w2rx = 1
    p14.u1ty = 1 ; p14.u1ry = 1 ; p14.u2ty = 1 ; p14.u2ry = 1
    p14.v1ty = 1 ; p14.v1ry = 1 ; p14.v2ty = 1 ; p14.v2ry = 1
    p14.w1ty = 1 ; p14.w1ry = 1 ; p14.w2ty = 1 ; p14.w2ry = 1

    # flange low
    if run_static_case:
        p15.u1tx = 1 ; p15.u1rx = 1 ; p15.u2tx = 1 ; p15.u2rx = 1
    else:
        p15.u1tx = 0 ; p15.u1rx = 1 ; p15.u2tx = 1 ; p15.u2rx = 1
    p15.v1tx = 0 ; p15.v1rx = 1 ; p15.v2tx = 1 ; p15.v2rx = 1
    p15.w1tx = 0 ; p15.w1rx = 1 ; p15.w2tx = 1 ; p15.w2rx = 1
    p15.u1ty = 1 ; p15.u1ry = 1 ; p15.u2ty = 1 ; p15.u2ry = 1
    p15.v1ty = 1 ; p15.v1ry = 1 ; p15.v2ty = 1 ; p15.v2ry = 1
    p15.w1ty = 1 ; p15.w1ry = 1 ; p15.w2ty = 1 ; p15.w2ry = 1

    conn = [
        # skin-skin
        dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b),
        dict(p1=p01, p2=p04, func='SSxcte', xcte1=0, xcte2=p04.a),
        dict(p1=p02, p2=p03, func='SSycte', ycte1=0, ycte2=p03.b),
        dict(p1=p02, p2=p05, func='SSxcte', xcte1=0, xcte2=p05.a),
        dict(p1=p03, p2=p06, func='SSxcte', xcte1=0, xcte2=p06.a),
        dict(p1=p04, p2=p05, func='SSycte', ycte1=0, ycte2=p05.b),
        dict(p1=p04, p2=p07, func='SSxcte', xcte1=0, xcte2=p07.a),
        dict(p1=p05, p2=p06, func='SSycte', ycte1=0, ycte2=p06.b),
        dict(p1=p05, p2=p08, func='SSxcte', xcte1=0, xcte2=p08.a),
        dict(p1=p06, p2=p09, func='SSxcte', xcte1=0, xcte2=p09.a),
        dict(p1=p07, p2=p08, func='SSycte', ycte1=0, ycte2=p08.b),
        dict(p1=p08, p2=p09, func='SSycte', ycte1=0, ycte2=p09.b),

        # skin-base
        dict(p1=p02, p2=p10, func='SB'),
        dict(p1=p05, p2=p12, func='SB', has_defect=has_defect), # defect
        dict(p1=p08, p2=p14, func='SB'),

        # base-base
        dict(p1=p10, p2=p12, func='SSxcte', xcte1=0, xcte2=p12.a),
        dict(p1=p12, p2=p14, func='SSxcte', xcte1=0, xcte2=p14.a),

        # base-flange
        dict(p1=p10, p2=p11, func='BFycte', ycte1=p10.b/2., ycte2=0),
        dict(p1=p12, p2=p13, func='BFycte', ycte1=p12.b/2., ycte2=0),
        dict(p1=p14, p2=p15, func='BFycte', ycte1=p14.b/2., ycte2=0),

        # flange-flange
        dict(p1=p11, p2=p13, func='SSxcte', xcte1=0, xcte2=p13.a),
        dict(p1=p13, p2=p15, func='SSxcte', xcte1=0, xcte2=p15.a),
        ]

    panels = [p01, p02, p03, p04, p05, p06, p07, p08, p09,
            p10, p11, p12, p13, p14, p15]

    assy = PanelAssembly(panels)

    size = sum([3*p.m*p.n for p in panels])

    valid_conn = []
    for connecti in conn:
        if connecti.get('has_defect'): # connecting if there is no defect
            continue
        valid_conn.append(connecti)

    k0 = assy.calc_k0(valid_conn)
    c = None
    if run_static_case:
        fext = np.zeros(size)
        for p in [p07, p08, p09, p14, p15]:
            Nforces = 100
            fx = p.Nxx*p.b/(Nforces-1.)
            for i in range(Nforces):
                y = i*p.b/(Nforces-1.)
                if i == 0 or i == (Nforces - 1):
                    p.add_force(0, y, fx/2., 0, 0)
                else:
                    p.add_force(0, y, fx, 0, 0)
            fext[p.col_start: p.col_end] = p.calc_fext(silent=True)

        incs, cs = static(k0, -fext, silent=True)
        c = cs[0]

    kG = assy.calc_kG0(c=c)

    eigvals = eigvecs = None
    eigvals, eigvecs = lb(k0, kG, tol=0, sparse_solver=True, silent=True,
             num_eigvalues=25, num_eigvalues_print=5)

    if run_static_case:
        return assy, c, eigvals, eigvecs
    else:
        return assy, eigvals, eigvecs
def test_kT():
    mns = [[4, 4], [4, 5], [4, 6], [5, 5], [5, 6], [6, 6], [8, 9], [9, 8]]
    for m, n in mns:
        for model in [
                'plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell'
        ]:
            p = Panel()
            p.model = model
            p.w1tx = 0
            p.u1tx = 1
            p.u1ty = 1
            p.u2ty = 1
            p.a = 2.
            p.b = 0.5
            p.r = 10
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3 * 0.125
            p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.m = m
            p.n = n
            p.nx = m
            p.ny = n

            P = 1000.
            npts = 5
            p.forces_inc = []
            for y in np.linspace(0, p.b, npts):
                p.forces_inc.append([0., y, P / (npts - 1.), 0, 0])
            p.forces_inc[0][2] /= 2.
            p.forces_inc[-1][2] /= 2.

            k0 = p.calc_k0(silent=True)
            kT = p.calc_kT(c=np.zeros(p.get_size()), silent=True)

            error = np.abs(kT - k0).sum()

            assert error < 1.e-7
def create_cylinder_blade_stiffened(height, r, stack, stack_blades,
        width_blades, plyt, laminaprop, npanels, m=8, n=8):
    r"""Cylinder Assembly

    The panel assembly looks like::


        B                               A
         _______ _______ _______ _______
        |       |       |       |       |
        |       |       |       |       |
        |       |       |       |       |
        |  p04  |  p03  |  p02  |  p01  |
        |       |       |       |       |
        |       |       |       |       |
        |_______|_______|_______|_______|

        Blade   Blade   Blade   Blade
        04      03      02      01
         _       _       _       _
        | |     | |     | |     | |
        | |     | |     | |     | |
        | |     | |     | |     | |
        | |     | |     | |     | |
        |_|     |_|     |_|     |_|
                                               x
                                             /\
                                             |
                                             |
                                   y  <-------

    where edges ``A`` and ``B`` are connected to produce the cyclic effect.


    Parameters
    ----------

    height : float
        Cylinder height (along `x`).
    r : float
        Cylinder radius.
    stack : array-like
        Stacking sequence for the cylinder.
    stack_blades : list of array-like
        The stacking sequence for each blade (with length = npanels).
    width_blades : array-like
        The width for each blade (with length = npanels).
    plyt : float
        Ply thickness (assumed unique for the whole structure).
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    npanels : int
        The number of panels the cylinder perimiter.
    m, n : int, optional
        Number of approximation terms for each panel.

    Returns
    -------
    assy, conns : tuple
        A tuple containing the assembly and the default connectivity
        list of dictionaries.

    """
    if npanels < 2:
        raise ValueError('At least two panels are needed')
    if len(stack_blades) != npanels:
        raise ValueError('stack_blades must have length = npanels')
    if len(width_blades) != npanels:
        raise ValueError('width_blades must have length = npanels')
    skin = []
    blades = []
    perimiter = 2*np.pi*r
    b_skin = perimiter / npanels
    for i in range(npanels):
        y0 = i*b_skin
        panel = Panel(group='skin', x0=0, y0=y0, a=height, b=b_skin,
            r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop,
            u1tx=0, u1rx=1, u2tx=0, u2rx=1,
            v1tx=0, v1rx=1, v2tx=0, v2rx=1,
            w1tx=0, w1rx=1, w2tx=0, w2rx=1,
            u1ty=1, u1ry=1, u2ty=1, u2ry=1,
            v1ty=1, v1ry=1, v2ty=1, v2ry=1,
            w1ty=1, w1ry=1, w2ty=1, w2ry=1)
        skin.append(panel)
    for i, panel in enumerate(skin):
        y0 = i*b_skin
        blade_name = 'blade_%02d' % i
        blade = Panel(group=blade_name, x0=0, y0=y0, a=height,
                    b=width_blades[i], m=m, n=n, plyt=plyt,
                    stack=stack_blades[i], laminaprop=laminaprop,
                    u1tx=0, u1rx=1, u2tx=0, u2rx=1,
                    v1tx=0, v1rx=1, v2tx=0, v2rx=1,
                    w1tx=0, w1rx=1, w2tx=0, w2rx=1,
                    u1ty=1, u1ry=1, u2ty=1, u2ry=1,
                    v1ty=1, v1ry=1, v2ty=1, v2ry=1,
                    w1ty=1, w1ry=1, w2ty=1, w2ry=1)
        blades.append(blade)

    conns = []
    skin_loop = skin + [skin[0]]
    for i in range(len(skin)):
        if i != len(skin) - 1:
            p01 = skin_loop[i]
            p02 = skin_loop[i+1]
            conns.append(dict(p1=p01, p2=p02, func='SSycte', ycte1=p01.b, ycte2=0))
        else:
            p01 = skin_loop[i+1]
            p02 = skin_loop[i]
            conns.append(dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b))

    for panel, blade in zip(skin, blades):
        conns.append(dict(p1=panel, p2=blade, func='BFycte', ycte1=0, ycte2=0))

    assy = PanelAssembly(skin + blades)

    return assy, conns
def test_panel_field_outputs():
    m = 7
    n = 6
    #TODO implement for conical panels
    strain_field = dict(exx=None, eyy=None, gxy=None, kxx=None, kyy=None, kxy=None)
    stress_field = dict(Nxx=None, Nyy=None, Nxy=None, Mxx=None, Myy=None, Mxy=None)
    for model in ['plate_clt_donnell_bardell',
                  'cpanel_clt_donnell_bardell']:
        p = Panel()
        p.model = model
        p.u1tx = 1
        p.u1ty = 1
        p.u2ty = 1
        p.v1tx = 0
        p.v2tx = 0
        p.v1ty = 0
        p.v2ty = 0

        p.a = 2.
        p.b = 1.
        p.r = 1.e5
        p.stack = [0, -45, +45, 90, +45, -45, 0, 0]
        p.plyt = 1e-3*0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.nx = m
        p.ny = n
        p.m = m
        p.n = n

        P = 1000.
        npts = 100
        p.forces_inc = []
        for y in np.linspace(0, p.b, npts):
            p.forces_inc.append([0., y, P/(npts-1.), 0, 0])
        p.forces_inc[0][2] /= 2.
        p.forces_inc[-1][2] /= 2.

        p.static()
        c = p.analysis.cs[0]
        Ns = p.stress(c, gridx=50, gridy=50)
        es = p.strain(c, gridx=50, gridy=50)
        for k, v in strain_field.items():
            if v is None:
                strain_field[k] = es.get(k).min()
            else:
                assert np.isclose(strain_field[k], es.get(k).min(), rtol=0.05)
            p.plot(c, vec=k, filename='tmp_test_panel_strain_field_%s.png' % k)
        for k, v in stress_field.items():
            if v is None:
                stress_field[k] = Ns.get(k).min()
            else:
                assert np.isclose(stress_field[k], Ns.get(k).min(), rtol=0.05)
            p.plot(c, vec=k, filename='tmp_test_panel_stress_field_%s.png' % k)
def tstiff2d_1stiff_flutter(a, b, ys, bb, bf, defect_a, mu, plyt,
        laminaprop, stack_skin, stack_base, stack_flange,
        air_speed=None, rho_air=None, Mach=None, speed_sound=None, flow='x',
        Nxx_skin=None, Nxx_base=None, Nxx_flange=None, run_static_case=True,
        r=None, m=8, n=8, mb=None, nb=None, mf=None, nf=None):
    r"""Flutter of T-Stiffened Panel with possible defect at middle

    For more details about each parameter and the aerodynamic formulation see
    Ref. [castro2016FlutterPanel]_ .


    The panel assembly looks like::

        skin
         _________ _____ _________
        |         |     |         |
        |         |     |         |
        |   p01   | p02 |   p03   |
        |         |     |         |
        |_________|_____|_________|
        |   p04   | p05 |   p06   |      /\  x
        |_________|_____|_________|       |
        |         |     |         |       |
        |         |     |         |       |
        |   p07   | p08 |   p09   |
        |         |     |         |
        |         |     |         |
        |_________|_____|_________|
               loaded edge

                  base            flange
                   _____           _____
                  |     |         |     |
                  |     |         |     |
                  | p10 |         | p11 |
                  |     |         |     |
                  |_____|         |_____|
                  | p12 |         | p13 |
                  |_____|         |_____|
                  |     |         |     |
                  |     |         |     |
                  | p14 |         | p15 |
                  |     |         |     |
                  |     |         |     |
                  |_____|         |_____|
               loaded edge     loaded edge

    Parameters
    ----------

    a : float
        Total length of the assembly (along `x`).
    b : float
        Total width of the assembly (along `y`).
    ys : float
        Position of the stiffener along `y`.
    bb : float
        Stiffener's base width.
    bf : float
        Stiffener's flange width.
    defect_a : float
        Debonding defect/assembly length ratio.
    mu : float
        Material density.
    plyt : float
        Ply thickness.
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    stack_skin : list or tuple
        Stacking sequence for the skin.
    stack_base : list or tuple
        Stacking sequence for the stiffener's base.
    stack_flange : list or tuple
        Stacking sequence for the stiffener's flange.
    air_speed : float
        Airflow speed.
    rho_air : float
        Air density.
    Mach : float
        Mach number.
    speed_sound : float
        Speed of sound.
    flow : "x" or "y"
        Direction of airflow.
    Nxx_skin : float
        Skin load distributed at the assembly edge at `x=0`.
    Nxx_base : float
        Stiffener's base load distributed at the assembly edge at `x=0`.
    Nxx_flange : float
        Stiffener's flange load distributed at the assembly edge at `x=0`.
    run_static_case : bool, optional
        If True a static analysis is run before the linear buckling analysis
        to compute the real membrane stress state along the domain, otherwise
        it is assumed constant values of `N_{xx}` for all components.
    r : float or None, optional
        Radius of the stiffened panel.
    m, n : int, optional
        Number of terms of the approximation function for the skin.
    mb, nb : int, optional
        Number of terms of the approximation function for the stiffener's base.
    mf, nf : int, optional
        Number of terms of the approximation function for the stiffener's
        flange.

    Examples
    --------

    The following example is one of the test cases:

    .. literalinclude:: ../../../../../compmech/panel/assembly/tests/test_tstiff2d_assembly.py
        :pyobject: test_tstiff2d_1stiff_flutter

    """
    defect = defect_a * a
    has_defect = True if defect > 0 else False
    defect = 0.33*a if defect == 0 else defect # to avoid weird domains
    aup = (a - defect)/2.
    alow = (a - defect)/2.
    bleft = b - ys - bb/2.
    bright = ys - bb/2.
    mb = m if mb is None else mb
    nb = n if nb is None else nb
    mf = m if mf is None else mf
    nf = n if nf is None else nf
    # skin panels
    p01 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=ys+bb/2., a=aup, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p02 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p03 = Panel(group='skin', Nxx=Nxx_skin, x0=alow+defect, y0=0, a=aup, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    # defect
    p04 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=ys+bb/2., a=defect, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p05 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p06 = Panel(group='skin', Nxx=Nxx_skin, x0=alow, y0=0, a=defect, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    #
    p07 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=ys+bb/2., a=alow, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p08 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)
    p09 = Panel(group='skin', Nxx=Nxx_skin, x0=0, y0=0, a=alow, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu, rho_air=rho_air, speed_sound=speed_sound, Mach=Mach, V=air_speed, flow=flow)

    # stiffeners
    p10 = Panel(group='base', Nxx=Nxx_base, x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p11 = Panel(group='flange', Nxx=Nxx_flange, x0=alow+defect, y0=0,        a=aup, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)
    # defect
    p12 = Panel(group='base', Nxx=Nxx_base, x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p13 = Panel(group='flange', Nxx=Nxx_flange, x0=alow, y0=0,        a=defect, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)
    #
    p14 = Panel(group='base', Nxx=Nxx_base, x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p15 = Panel(group='flange', Nxx=Nxx_flange, x0=0, y0=0,        a=alow, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)

    # boundary conditions
    p01.u1tx = 1 ; p01.u1rx = 1 ; p01.u2tx = 0 ; p01.u2rx = 1
    p01.v1tx = 1 ; p01.v1rx = 1 ; p01.v2tx = 0 ; p01.v2rx = 1
    p01.w1tx = 1 ; p01.w1rx = 1 ; p01.w2tx = 0 ; p01.w2rx = 1
    p01.u1ty = 1 ; p01.u1ry = 1 ; p01.u2ty = 1 ; p01.u2ry = 1
    p01.v1ty = 1 ; p01.v1ry = 1 ; p01.v2ty = 0 ; p01.v2ry = 1
    p01.w1ty = 1 ; p01.w1ry = 1 ; p01.w2ty = 0 ; p01.w2ry = 1

    p02.u1tx = 1 ; p02.u1rx = 1 ; p02.u2tx = 0 ; p02.u2rx = 1
    p02.v1tx = 1 ; p02.v1rx = 1 ; p02.v2tx = 0 ; p02.v2rx = 1
    p02.w1tx = 1 ; p02.w1rx = 1 ; p02.w2tx = 0 ; p02.w2rx = 1
    p02.u1ty = 1 ; p02.u1ry = 1 ; p02.u2ty = 1 ; p02.u2ry = 1
    p02.v1ty = 1 ; p02.v1ry = 1 ; p02.v2ty = 1 ; p02.v2ry = 1
    p02.w1ty = 1 ; p02.w1ry = 1 ; p02.w2ty = 1 ; p02.w2ry = 1

    p03.u1tx = 1 ; p03.u1rx = 1 ; p03.u2tx = 0 ; p03.u2rx = 1
    p03.v1tx = 1 ; p03.v1rx = 1 ; p03.v2tx = 0 ; p03.v2rx = 1
    p03.w1tx = 1 ; p03.w1rx = 1 ; p03.w2tx = 0 ; p03.w2rx = 1
    p03.u1ty = 1 ; p03.u1ry = 1 ; p03.u2ty = 1 ; p03.u2ry = 1
    p03.v1ty = 0 ; p03.v1ry = 1 ; p03.v2ty = 1 ; p03.v2ry = 1
    p03.w1ty = 0 ; p03.w1ry = 1 ; p03.w2ty = 1 ; p03.w2ry = 1

    p04.u1tx = 1 ; p04.u1rx = 1 ; p04.u2tx = 1 ; p04.u2rx = 1
    p04.v1tx = 1 ; p04.v1rx = 1 ; p04.v2tx = 1 ; p04.v2rx = 1
    p04.w1tx = 1 ; p04.w1rx = 1 ; p04.w2tx = 1 ; p04.w2rx = 1
    p04.u1ty = 1 ; p04.u1ry = 1 ; p04.u2ty = 1 ; p04.u2ry = 1
    p04.v1ty = 1 ; p04.v1ry = 1 ; p04.v2ty = 0 ; p04.v2ry = 1
    p04.w1ty = 1 ; p04.w1ry = 1 ; p04.w2ty = 0 ; p04.w2ry = 1

    p05.u1tx = 1 ; p05.u1rx = 1 ; p05.u2tx = 1 ; p05.u2rx = 1
    p05.v1tx = 1 ; p05.v1rx = 1 ; p05.v2tx = 1 ; p05.v2rx = 1
    p05.w1tx = 1 ; p05.w1rx = 1 ; p05.w2tx = 1 ; p05.w2rx = 1
    p05.u1ty = 1 ; p05.u1ry = 1 ; p05.u2ty = 1 ; p05.u2ry = 1
    p05.v1ty = 1 ; p05.v1ry = 1 ; p05.v2ty = 1 ; p05.v2ry = 1
    p05.w1ty = 1 ; p05.w1ry = 1 ; p05.w2ty = 1 ; p05.w2ry = 1

    p06.u1tx = 1 ; p06.u1rx = 1 ; p06.u2tx = 1 ; p06.u2rx = 1
    p06.v1tx = 1 ; p06.v1rx = 1 ; p06.v2tx = 1 ; p06.v2rx = 1
    p06.w1tx = 1 ; p06.w1rx = 1 ; p06.w2tx = 1 ; p06.w2rx = 1
    p06.u1ty = 1 ; p06.u1ry = 1 ; p06.u2ty = 1 ; p06.u2ry = 1
    p06.v1ty = 0 ; p06.v1ry = 1 ; p06.v2ty = 1 ; p06.v2ry = 1
    p06.w1ty = 0 ; p06.w1ry = 1 ; p06.w2ty = 1 ; p06.w2ry = 1

    p07.u1tx = 1 ; p07.u1rx = 1 ; p07.u2tx = 1 ; p07.u2rx = 1
    p07.v1tx = 0 ; p07.v1rx = 1 ; p07.v2tx = 1 ; p07.v2rx = 1
    p07.w1tx = 0 ; p07.w1rx = 1 ; p07.w2tx = 1 ; p07.w2rx = 1
    p07.u1ty = 1 ; p07.u1ry = 1 ; p07.u2ty = 1 ; p07.u2ry = 1
    p07.v1ty = 1 ; p07.v1ry = 1 ; p07.v2ty = 0 ; p07.v2ry = 1
    p07.w1ty = 1 ; p07.w1ry = 1 ; p07.w2ty = 0 ; p07.w2ry = 1

    p08.u1tx = 1 ; p08.u1rx = 1 ; p08.u2tx = 1 ; p08.u2rx = 1
    p08.v1tx = 0 ; p08.v1rx = 1 ; p08.v2tx = 1 ; p08.v2rx = 1
    p08.w1tx = 0 ; p08.w1rx = 1 ; p08.w2tx = 1 ; p08.w2rx = 1
    p08.u1ty = 1 ; p08.u1ry = 1 ; p08.u2ty = 1 ; p08.u2ry = 1
    p08.v1ty = 1 ; p08.v1ry = 1 ; p08.v2ty = 1 ; p08.v2ry = 1
    p08.w1ty = 1 ; p08.w1ry = 1 ; p08.w2ty = 1 ; p08.w2ry = 1

    p09.u1tx = 1 ; p09.u1rx = 1 ; p09.u2tx = 1 ; p09.u2rx = 1
    p09.v1tx = 0 ; p09.v1rx = 1 ; p09.v2tx = 1 ; p09.v2rx = 1
    p09.w1tx = 0 ; p09.w1rx = 1 ; p09.w2tx = 1 ; p09.w2rx = 1
    p09.u1ty = 1 ; p09.u1ry = 1 ; p09.u2ty = 1 ; p09.u2ry = 1
    p09.v1ty = 0 ; p09.v1ry = 1 ; p09.v2ty = 1 ; p09.v2ry = 1
    p09.w1ty = 0 ; p09.w1ry = 1 ; p09.w2ty = 1 ; p09.w2ry = 1

    # base up
    p10.u1tx = 1 ; p10.u1rx = 1 ; p10.u2tx = 1 ; p10.u2rx = 1
    p10.v1tx = 1 ; p10.v1rx = 1 ; p10.v2tx = 1 ; p10.v2rx = 1
    p10.w1tx = 1 ; p10.w1rx = 1 ; p10.w2tx = 1 ; p10.w2rx = 1
    p10.u1ty = 1 ; p10.u1ry = 1 ; p10.u2ty = 1 ; p10.u2ry = 1
    p10.v1ty = 1 ; p10.v1ry = 1 ; p10.v2ty = 1 ; p10.v2ry = 1
    p10.w1ty = 1 ; p10.w1ry = 1 ; p10.w2ty = 1 ; p10.w2ry = 1

    # flange up
    p11.u1tx = 1 ; p11.u1rx = 1 ; p11.u2tx = 0 ; p11.u2rx = 1
    p11.v1tx = 1 ; p11.v1rx = 1 ; p11.v2tx = 0 ; p11.v2rx = 1
    p11.w1tx = 1 ; p11.w1rx = 1 ; p11.w2tx = 0 ; p11.w2rx = 1
    p11.u1ty = 1 ; p11.u1ry = 1 ; p11.u2ty = 1 ; p11.u2ry = 1
    p11.v1ty = 1 ; p11.v1ry = 1 ; p11.v2ty = 1 ; p11.v2ry = 1
    p11.w1ty = 1 ; p11.w1ry = 1 ; p11.w2ty = 1 ; p11.w2ry = 1

    # base mid
    p12.u1tx = 1 ; p12.u1rx = 1 ; p12.u2tx = 1 ; p12.u2rx = 1
    p12.v1tx = 1 ; p12.v1rx = 1 ; p12.v2tx = 1 ; p12.v2rx = 1
    p12.w1tx = 1 ; p12.w1rx = 1 ; p12.w2tx = 1 ; p12.w2rx = 1
    p12.u1ty = 1 ; p12.u1ry = 1 ; p12.u2ty = 1 ; p12.u2ry = 1
    p12.v1ty = 1 ; p12.v1ry = 1 ; p12.v2ty = 1 ; p12.v2ry = 1
    p12.w1ty = 1 ; p12.w1ry = 1 ; p12.w2ty = 1 ; p12.w2ry = 1

    # flange mid
    p13.u1tx = 1 ; p13.u1rx = 1 ; p13.u2tx = 1 ; p13.u2rx = 1
    p13.v1tx = 1 ; p13.v1rx = 1 ; p13.v2tx = 1 ; p13.v2rx = 1
    p13.w1tx = 1 ; p13.w1rx = 1 ; p13.w2tx = 1 ; p13.w2rx = 1
    p13.u1ty = 1 ; p13.u1ry = 1 ; p13.u2ty = 1 ; p13.u2ry = 1
    p13.v1ty = 1 ; p13.v1ry = 1 ; p13.v2ty = 1 ; p13.v2ry = 1
    p13.w1ty = 1 ; p13.w1ry = 1 ; p13.w2ty = 1 ; p13.w2ry = 1

    # base low
    p14.u1tx = 1 ; p14.u1rx = 1 ; p14.u2tx = 1 ; p14.u2rx = 1
    p14.v1tx = 1 ; p14.v1rx = 1 ; p14.v2tx = 1 ; p14.v2rx = 1
    p14.w1tx = 1 ; p14.w1rx = 1 ; p14.w2tx = 1 ; p14.w2rx = 1
    p14.u1ty = 1 ; p14.u1ry = 1 ; p14.u2ty = 1 ; p14.u2ry = 1
    p14.v1ty = 1 ; p14.v1ry = 1 ; p14.v2ty = 1 ; p14.v2ry = 1
    p14.w1ty = 1 ; p14.w1ry = 1 ; p14.w2ty = 1 ; p14.w2ry = 1

    # flange low
    p15.u1tx = 1 ; p15.u1rx = 1 ; p15.u2tx = 1 ; p15.u2rx = 1
    p15.v1tx = 0 ; p15.v1rx = 1 ; p15.v2tx = 1 ; p15.v2rx = 1
    p15.w1tx = 0 ; p15.w1rx = 1 ; p15.w2tx = 1 ; p15.w2rx = 1
    p15.u1ty = 1 ; p15.u1ry = 1 ; p15.u2ty = 1 ; p15.u2ry = 1
    p15.v1ty = 1 ; p15.v1ry = 1 ; p15.v2ty = 1 ; p15.v2ry = 1
    p15.w1ty = 1 ; p15.w1ry = 1 ; p15.w2ty = 1 ; p15.w2ry = 1

    conn = [
        # skin-skin
        dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b),
        dict(p1=p01, p2=p04, func='SSxcte', xcte1=0, xcte2=p04.a),
        dict(p1=p02, p2=p03, func='SSycte', ycte1=0, ycte2=p03.b),
        dict(p1=p02, p2=p05, func='SSxcte', xcte1=0, xcte2=p05.a),
        dict(p1=p03, p2=p06, func='SSxcte', xcte1=0, xcte2=p06.a),
        dict(p1=p04, p2=p05, func='SSycte', ycte1=0, ycte2=p05.b),
        dict(p1=p04, p2=p07, func='SSxcte', xcte1=0, xcte2=p07.a),
        dict(p1=p05, p2=p06, func='SSycte', ycte1=0, ycte2=p06.b),
        dict(p1=p05, p2=p08, func='SSxcte', xcte1=0, xcte2=p08.a),
        dict(p1=p06, p2=p09, func='SSxcte', xcte1=0, xcte2=p09.a),
        dict(p1=p07, p2=p08, func='SSycte', ycte1=0, ycte2=p08.b),
        dict(p1=p08, p2=p09, func='SSycte', ycte1=0, ycte2=p09.b),

        # skin-base
        dict(p1=p02, p2=p10, func='SB'),
        dict(p1=p05, p2=p12, func='SB', has_defect=has_defect), # defect
        dict(p1=p08, p2=p14, func='SB'),

        # base-base
        dict(p1=p10, p2=p12, func='SSxcte', xcte1=0, xcte2=p12.a),
        dict(p1=p12, p2=p14, func='SSxcte', xcte1=0, xcte2=p14.a),

        # base-flange
        dict(p1=p10, p2=p11, func='BFycte', ycte1=p10.b/2., ycte2=0),
        dict(p1=p12, p2=p13, func='BFycte', ycte1=p12.b/2., ycte2=0),
        dict(p1=p14, p2=p15, func='BFycte', ycte1=p14.b/2., ycte2=0),

        # flange-flange
        dict(p1=p11, p2=p13, func='SSxcte', xcte1=0, xcte2=p13.a),
        dict(p1=p13, p2=p15, func='SSxcte', xcte1=0, xcte2=p15.a),
        ]

    panels = [p01, p02, p03, p04, p05, p06, p07, p08, p09,
            p10, p11, p12, p13, p14, p15]
    skin = [p01, p02, p03, p04, p05, p06, p07, p08, p09]

    assy = PanelAssembly(panels)

    size = assy.get_size()

    valid_conn = []
    for connecti in conn:
        if connecti.get('has_defect'): # connecting if there is no defect
            continue
        valid_conn.append(connecti)

    k0 = assy.calc_k0(valid_conn)
    c = None
    if (run_static_case and not
            (Nxx_skin is None and Nxx_base is None and Nxx_flange is None)):
        fext = np.zeros(size)
        for p in [p07, p08, p09, p14, p15]:
            Nforces = 100
            fx = p.Nxx*p.b/(Nforces-1.)
            for i in range(Nforces):
                y = i*p.b/(Nforces-1.)
                if i == 0 or i == (Nforces - 1):
                    p.add_force(0, y, fx/2., 0, 0)
                else:
                    p.add_force(0, y, fx, 0, 0)
            fext[p.col_start: p.col_end] = p.calc_fext(silent=True)

        incs, cs = static(k0, -fext, silent=True)
        c = cs[0]

    kM = assy.calc_kM()
    kG = assy.calc_kG0(c=c)

    kA = 0
    for p in skin:
        # TODO the current approach has somewhat hiden settings
        #     check this strategy:
        #     - define module aerodynamics
        #     - function calc_kA inside a module piston_theory
        #     - pass piston_theory parameters and compute kA
        kA += p.calc_kA(size=size, row0=p.row_start, col0=p.col_start, silent=True, finalize=False)

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

    eigvals, eigvecs = freq((k0 + kG + kA), kM, tol=0, sparse_solver=True, silent=True,
             sort=True, reduced_dof=False,
             num_eigvalues=25, num_eigvalues_print=5)

    if run_static_case:
        return assy, c, eigvals, eigvecs
    else:
        return assy, eigvals, eigvecs
def test_4panels_kt_kr():
    """Compare result of 4 assembled panels with single-domain results

    The panel assembly looks like::

         _________ _____
        |         |     |
        |         |     |
        |   p01   | p02 |
        |         |     |
        |_________|_____|
        |   p03   | p04 |
        |         |     |
        |         |     |
        |         |     |
        |         |     |
        |         |     |
        |_________|_____|

    """
    print('Testing validity of the default kt and kr values')

    plyt = 1.e-3 * 0.125
    laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
    stack=[0, 45, -45, 90, -45, 45, 0]
    lam = laminate.read_stack(stack=stack, plyt=plyt, laminaprop=laminaprop)

    mu=1.3e3

    r = 10.
    m = 8
    n = 8

    a1 = 1.5
    a2 = 1.5
    a3 = 2.5
    a4 = 2.5
    b1 = 1.5
    b2 = 0.5
    b3 = 1.5
    b4 = 0.5

    A11 = lam.ABD[0, 0]
    A22 = lam.ABD[1, 1]
    D11 = lam.ABD[3, 3]
    D22 = lam.ABD[4, 4]

    p01 = Panel(group='panels', x0=a3, y0=b2, a=a1, b=b1, r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop, mu=mu)
    p02 = Panel(group='panels', x0=a3, y0=0, a=a2, b=b2, r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop, mu=mu)
    p03 = Panel(group='panels', x0=0, y0=b2, a=a3, b=b3, r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop, mu=mu)
    p04 = Panel(group='panels', x0=0, y0=0, a=a4, b=b4, r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop, mu=mu)

    kt13, kr13 = connections.calc_kt_kr(p01, p03, 'xcte')
    kt24, kr24 = connections.calc_kt_kr(p02, p04, 'xcte')
    kt12, kr12 = connections.calc_kt_kr(p01, p02, 'ycte')
    kt34, kr34 = connections.calc_kt_kr(p03, p04, 'ycte')

    # boundary conditions
    p01.u1tx = 1 ; p01.u1rx = 1 ; p01.u2tx = 0 ; p01.u2rx = 1
    p01.v1tx = 1 ; p01.v1rx = 1 ; p01.v2tx = 0 ; p01.v2rx = 1
    p01.w1tx = 1 ; p01.w1rx = 1 ; p01.w2tx = 0 ; p01.w2rx = 1
    p01.u1ty = 1 ; p01.u1ry = 1 ; p01.u2ty = 0 ; p01.u2ry = 1
    p01.v1ty = 1 ; p01.v1ry = 1 ; p01.v2ty = 0 ; p01.v2ry = 1
    p01.w1ty = 1 ; p01.w1ry = 1 ; p01.w2ty = 0 ; p01.w2ry = 1

    p02.u1tx = 1 ; p02.u1rx = 1 ; p02.u2tx = 0 ; p02.u2rx = 1
    p02.v1tx = 1 ; p02.v1rx = 1 ; p02.v2tx = 0 ; p02.v2rx = 1
    p02.w1tx = 1 ; p02.w1rx = 1 ; p02.w2tx = 0 ; p02.w2rx = 1
    p02.u1ty = 0 ; p02.u1ry = 1 ; p02.u2ty = 1 ; p02.u2ry = 1
    p02.v1ty = 0 ; p02.v1ry = 1 ; p02.v2ty = 1 ; p02.v2ry = 1
    p02.w1ty = 0 ; p02.w1ry = 1 ; p02.w2ty = 1 ; p02.w2ry = 1

    p03.u1tx = 0 ; p03.u1rx = 1 ; p03.u2tx = 1 ; p03.u2rx = 1
    p03.v1tx = 0 ; p03.v1rx = 1 ; p03.v2tx = 1 ; p03.v2rx = 1
    p03.w1tx = 0 ; p03.w1rx = 1 ; p03.w2tx = 1 ; p03.w2rx = 1
    p03.u1ty = 1 ; p03.u1ry = 1 ; p03.u2ty = 0 ; p03.u2ry = 1
    p03.v1ty = 1 ; p03.v1ry = 1 ; p03.v2ty = 0 ; p03.v2ry = 1
    p03.w1ty = 1 ; p03.w1ry = 1 ; p03.w2ty = 0 ; p03.w2ry = 1

    p04.u1tx = 0 ; p04.u1rx = 1 ; p04.u2tx = 1 ; p04.u2rx = 1
    p04.v1tx = 0 ; p04.v1rx = 1 ; p04.v2tx = 1 ; p04.v2rx = 1
    p04.w1tx = 0 ; p04.w1rx = 1 ; p04.w2tx = 1 ; p04.w2rx = 1
    p04.u1ty = 0 ; p04.u1ry = 1 ; p04.u2ty = 1 ; p04.u2ry = 1
    p04.v1ty = 0 ; p04.v1ry = 1 ; p04.v2ty = 1 ; p04.v2ry = 1
    p04.w1ty = 0 ; p04.w1ry = 1 ; p04.w2ty = 1 ; p04.w2ry = 1

    conndict = [
        dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b, kt=kt12, kr=kr12),
        dict(p1=p01, p2=p03, func='SSxcte', xcte1=0, xcte2=p03.a, kt=kt13, kr=kr13),
        dict(p1=p02, p2=p04, func='SSxcte', xcte1=0, xcte2=p04.a, kt=kt24, kr=kr24),
        dict(p1=p03, p2=p04, func='SSycte', ycte1=0, ycte2=p04.b, kt=kt34, kr=kr34),
        ]

    panels = [p01, p02, p03, p04]

    size = sum([3*p.m*p.n for p in panels])

    k0 = 0
    kM = 0

    row0 = 0
    col0 = 0
    for p in panels:
        k0 += p.calc_k0(row0=row0, col0=col0, size=size, silent=True, finalize=False)
        kM += p.calc_kM(row0=row0, col0=col0, size=size, silent=True, finalize=False)
        p.row_start = row0
        p.col_start = col0
        row0 += 3*p.m*p.n
        col0 += 3*p.m*p.n
        p.row_end = row0
        p.col_end = col0

    for conn in conndict:
        if conn.get('has_deffect'): # connecting if there is no deffect
            continue
        p1 = conn['p1']
        p2 = conn['p2']
        if conn['func'] == 'SSycte':
            k0 += connections.kCSSycte.fkCSSycte11(
                    conn['kt'], conn['kr'], p1, conn['ycte1'],
                    size, p1.row_start, col0=p1.col_start)
            k0 += connections.kCSSycte.fkCSSycte12(
                    conn['kt'], conn['kr'], p1, p2, conn['ycte1'], conn['ycte2'],
                    size, p1.row_start, col0=p2.col_start)
            k0 += connections.kCSSycte.fkCSSycte22(
                    conn['kt'], conn['kr'], p1, p2, conn['ycte2'],
                    size, p2.row_start, col0=p2.col_start)
        elif conn['func'] == 'SSxcte':
            k0 += connections.kCSSxcte.fkCSSxcte11(
                    conn['kt'], conn['kr'], p1, conn['xcte1'],
                    size, p1.row_start, col0=p1.col_start)
            k0 += connections.kCSSxcte.fkCSSxcte12(
                    conn['kt'], conn['kr'], p1, p2, conn['xcte1'], conn['xcte2'],
                    size, p1.row_start, col0=p2.col_start)
            k0 += connections.kCSSxcte.fkCSSxcte22(
                    conn['kt'], conn['kr'], p1, p2, conn['xcte2'],
                    size, p2.row_start, col0=p2.col_start)

    assert np.any(np.isnan(k0.data)) == False
    assert np.any(np.isinf(k0.data)) == False
    k0 = csr_matrix(make_symmetric(k0))
    assert np.any(np.isnan(kM.data)) == False
    assert np.any(np.isinf(kM.data)) == False
    kM = csr_matrix(make_symmetric(kM))

    eigvals, eigvecs = freq(k0, kM, tol=0, sparse_solver=True, silent=True,
             sort=True, reduced_dof=False,
             num_eigvalues=25, num_eigvalues_print=5)

    # Results for single panel
    m = 15
    n = 15
    singlepanel = Panel(a=(a1+a3), b=(b1+b2), r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop, mu=mu)
    singlepanel.freq(silent=True)

    assert np.isclose(eigvals[0], singlepanel.eigvals[0], atol=0.01, rtol=0.01)
Exemple #26
0
def test_reduced_dof_freq_plate():
    models = ['plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell']
    for model in models:
        print(
            'Test reduced_dof solver, prestress=True, model={0}'.format(model))
        p = Panel()
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 100.
        p.alphadeg = 0.
        p.stack = [0, 90, -45, +45]
        p.plyt = 1e-3 * 0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.mu = 1.3e3
        p.m = 11
        p.n = 12
        p.Nxx = -60.
        p.Nyy = -5.
        k0 = p.calc_k0(silent=True)
        M = p.calc_kM(silent=True)
        kG0 = p.calc_kG0(silent=True)
        k0 += kG0
        eigvals, eigvecs = freq(k0,
                                M,
                                sparse_solver=True,
                                reduced_dof=False,
                                silent=True)
        reduced_false = eigvals[0]
        freq(k0, M, sparse_solver=True, reduced_dof=True, silent=True)
        reduced_true = eigvals[0]
        assert np.isclose(reduced_false, reduced_true, rtol=0.001)
    def add_panel(self, y1, y2, stack=None, plyts=None, plyt=None,
            laminaprops=None, laminaprop=None, model=None, mu=None, **kwargs):
        """Add a new panel to the current panel bay

        Parameters
        ----------
        y1 : float
            Position of the first panel edge along `y`.
        y2 : float
            Position of the second panel edge along `y`.
        stack : list, optional
            Panel stacking sequence. If not given the stacking sequence of the
            bay will be used.
        plyts : list, optional
            Thicknesses for each panel ply. If not supplied the bay ``plyts``
            attribute will be used.
        plyt : float, optional
            Unique thickness to be used for all panel plies. If not supplied
            the bay ``plyt`` attribute will be used.
        laminaprops : list, optional
            Lamina properties for each panel ply.
        laminaprop : list, optional
            Unique lamina properties for all panel plies.
        model : str, optional
            Not recommended to pass this parameter, but the user can use a
            different model for each panel. It is recommended to defined
            ``model`` for the bay object.
        mu : float, optional
            Panel material density. If not given the bay density will be used.

        Notes
        -----
        Additional parameters can be passed using the ``kwargs``.

        """
        p = Panel()
        p.m = self.m
        p.n = self.n
        p.a = self.a
        p.b = self.b
        p.r = self.r
        p.y1 = y1
        p.y2 = y2
        p.d = 0.
        p.model = model if model is not None else self.model
        p.stack = stack if stack is not None else self.stack
        p.plyt = plyt if plyt is not None else self.plyt
        p.plyts = plyts if plyts is not None else self.plyts
        p.laminaprop = laminaprop if laminaprop is not None else self.laminaprop
        p.laminaprops = laminaprops if laminaprops is not None else self.laminaprops
        p.mu = mu if mu is not None else self.mu

        p.u1tx = self.u1tx
        p.u1rx = self.u1rx
        p.u2tx = self.u2tx
        p.u2rx = self.u2rx
        p.v1tx = self.v1tx
        p.v1rx = self.v1rx
        p.v2tx = self.v2tx
        p.v2rx = self.v2rx
        p.w1tx = self.w1tx
        p.w1rx = self.w1rx
        p.w2tx = self.w2tx
        p.w2rx = self.w2rx
        p.u1ty = self.u1ty
        p.u1ry = self.u1ry
        p.u2ty = self.u2ty
        p.u2ry = self.u2ry
        p.v1ty = self.v1ty
        p.v1ry = self.v1ry
        p.v2ty = self.v2ty
        p.v2ry = self.v2ry
        p.w1ty = self.w1ty
        p.w1ry = self.w1ry
        p.w2ty = self.w2ty
        p.w2ry = self.w2ry

        for k, v in kwargs.items():
            setattr(p, k, v)

        self.panels.append(p)
Exemple #28
0
class BladeStiff2D(object):
    r"""Blade Stiffener using 2D Formulation for Flange

    Blade-type of stiffener model using a 2D formulation for the flange and a
    2D formulation for the base (padup)::


                 || --> flange       |
                 ||                  |-> stiffener
               ======  --> padup     |
      =========================  --> panels
         Panel1      Panel2

    Both the flange and the base are optional. The stiffener's base is modeled
    using the same approximation functions as the skin, with the proper
    offset.

    Each stiffener has a constant `y_s` coordinate.

    """
    def __init__(self, bay, mu, panel1, panel2, ys, bb, bf, bstack, bplyts,
            blaminaprops, fstack, fplyts, flaminaprops, mf=14, nf=11):
        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.mu = mu
        self.ys = ys
        self.bb = bb
        self.forces_flange = []

        self.bstack = bstack
        self.bplyts = bplyts
        self.blaminaprops = blaminaprops

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self.base = None
        if bstack is not None:
            y1 = self.ys - bb/2.
            y2 = self.ys + bb/2.
            h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.base = Panel(a=bay.a, b=bay.b, r=bay.r, alphadeg=bay.alphadeg,
                    stack=bstack, plyts=bplyts, laminaprops=blaminaprops,
                    mu=mu, m=bay.m, n=bay.n, offset=(-h/2.-hb/2.),
                    u1tx=bay.u1tx, u1rx=bay.u1rx, u2tx=bay.u2tx, u2rx=bay.u2rx,
                    v1tx=bay.v1tx, v1rx=bay.v1rx, v2tx=bay.v2tx, v2rx=bay.v2rx,
                    w1tx=bay.w1tx, w1rx=bay.w1rx, w2tx=bay.w2tx, w2rx=bay.w2rx,
                    u1ty=bay.u1ty, u1ry=bay.u1ry, u2ty=bay.u2ty, u2ry=bay.u2ry,
                    v1ty=bay.v1ty, v1ry=bay.v1ry, v2ty=bay.v2ty, v2ry=bay.v2ry,
                    w1ty=bay.w1ty, w1ry=bay.w1ry, w2ty=bay.w2ty, w2ry=bay.w2ry,
                    y1=y1, y2=y2)

        self.flange = None
        if fstack is not None:
            self.flange = Panel(m=mf, n=nf, a=bay.a, b=bf, mu=mu,
                    stack=fstack, plyts=fplyts, laminaprops=flaminaprops,
                    model='plate_clt_donnell_bardell',
                    u1tx=0., u1rx=0., u2tx=0., u2rx=0.,
                    v1tx=0., v1rx=0., v2tx=0., v2rx=0.,
                    w1tx=0., w1rx=1., w2tx=0., w2rx=1.,
                    u1ty=1., u1ry=0., u2ty=1., u2ry=0.,
                    v1ty=1., v1ry=0., v2ty=1., v2ry=0.,
                    w1ty=1., w1ry=1., w2ty=1., w2ry=1.)

        self._rebuild()


    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.m == self.panel2.m
        assert self.panel1.n == self.panel2.n
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg
        if self.flange is not None:
            self.flange.lam = laminate.read_stack(self.flange.stack, plyts=self.flange.plyts,
                                            laminaprops=self.flange.laminaprops)
            self.flange.lam.calc_equivalent_modulus()

        if self.base is not None:
            h = 0.5*sum(self.panel1.plyts) + 0.5*sum(self.panel2.plyts)
            hb = sum(self.bplyts)
            self.dpb = h/2. + hb/2.
            self.base.lam = laminate.read_stack(self.bstack, plyts=self.bplyts,
                                            laminaprops=self.blaminaprops,
                                            offset=(-h/2.-hb/2.))


    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)


    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)


    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)

        kM = 0.
        if self.base is not None:
            kM += self.base.calc_kM(size=size, row0=0, col0=0, silent=True, finalize=False)
        if self.flange is not None:
            kM += self.flange.calc_kM(size=size, row0=row0, col0=col0, 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)
def tstiff2d_1stiff_freq(a,
                         b,
                         ys,
                         bb,
                         bf,
                         defect_a,
                         mu,
                         plyt,
                         laminaprop,
                         stack_skin,
                         stack_base,
                         stack_flange,
                         r=None,
                         m=8,
                         n=8,
                         mb=None,
                         nb=None,
                         mf=None,
                         nf=None):
    r"""Frequency T-Stiffened Panel with possible defect at middle

    For more details about each parameter and the aerodynamic formulation see
    Ref. [castro2016FlutterPanel]_ .

    For more details about the theory involved on the assembly of panels, see
    [castro2017AssemblyModels]_.

    The panel assembly looks like::

        skin
         _________ _____ _________
        |         |     |         |
        |         |     |         |
        |   p01   | p02 |   p03   |
        |         |     |         |
        |_________|_____|_________|
        |   p04   | p05 |   p06   |
        |_________|_____|_________|
        |         |     |         |
        |         |     |         |
        |   p07   | p08 |   p09   |
        |         |     |         |
        |         |     |         |
        |_________|_____|_________|

                  base            flange
                   _____           _____
                  |     |         |     |
                  |     |         |     |
                  | p10 |         | p11 |
                  |     |         |     |
                  |_____|         |_____|
                  | p12 |         | p13 |
                  |_____|         |_____|
                  |     |         |     |
                  |     |         |     |
                  | p14 |         | p15 |
                  |     |         |     |
                  |     |         |     |
                  |_____|         |_____|

    Parameters
    ----------

    a : float
        Total length of the assembly (along `x`).
    b : float
        Total width of the assembly (along `y`).
    ys : float
        Position of the stiffener along `y`.
    bb : float
        Stiffener's base width.
    bf : float
        Stiffener's flange width.
    defect_a : float
        Debonding defect/assembly length ratio.
    mu : float
        Material density.
    plyt : float
        Ply thickness.
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    stack_skin : list or tuple
        Stacking sequence for the skin.
    stack_base : list or tuple
        Stacking sequence for the stiffener's base.
    stack_flange : list or tuple
        Stacking sequence for the stiffener's flange.
    r : float or None, optional
        Radius of the stiffened panel.
    m, n : int, optional
        Number of terms of the approximation function for the skin.
    mb, nb : int, optional
        Number of terms of the approximation function for the stiffener's base.
    mf, nf : int, optional
        Number of terms of the approximation function for the stiffener's
        flange.

    Examples
    --------

    The following example is one of the test cases:

    .. literalinclude:: ../../../../../compmech/panel/assembly/tests/test_tstiff2d_assembly.py
        :pyobject: test_tstiff2d_1stiff_freq


    """
    defect = defect_a * a
    has_defect = True if defect > 0 else False
    defect = 0.33 * a if defect == 0 else defect  # to avoid weird domains
    aup = (a - defect) / 2.
    alow = (a - defect) / 2.
    bleft = b - ys - bb / 2.
    bright = ys - bb / 2.
    mb = m if mb is None else mb
    nb = n if nb is None else nb
    mf = m if mf is None else mf
    nf = n if nf is None else nf
    # skin panels
    p01 = Panel(group='skin',
                x0=alow + defect,
                y0=ys + bb / 2.,
                a=aup,
                b=bleft,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p02 = Panel(group='skin',
                x0=alow + defect,
                y0=ys - bb / 2.,
                a=aup,
                b=bb,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p03 = Panel(group='skin',
                x0=alow + defect,
                y0=0,
                a=aup,
                b=bright,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    # defect
    p04 = Panel(group='skin',
                x0=alow,
                y0=ys + bb / 2.,
                a=defect,
                b=bleft,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p05 = Panel(group='skin',
                x0=alow,
                y0=ys - bb / 2.,
                a=defect,
                b=bb,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p06 = Panel(group='skin',
                x0=alow,
                y0=0,
                a=defect,
                b=bright,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    #
    p07 = Panel(group='skin',
                x0=0,
                y0=ys + bb / 2.,
                a=alow,
                b=bleft,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p08 = Panel(group='skin',
                x0=0,
                y0=ys - bb / 2.,
                a=alow,
                b=bb,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)
    p09 = Panel(group='skin',
                x0=0,
                y0=0,
                a=alow,
                b=bright,
                r=r,
                m=m,
                n=n,
                plyt=plyt,
                stack=stack_skin,
                laminaprop=laminaprop,
                mu=mu)

    # stiffeners
    p10 = Panel(group='base',
                x0=alow + defect,
                y0=ys - bb / 2.,
                a=aup,
                b=bb,
                r=r,
                m=mb,
                n=nb,
                plyt=plyt,
                stack=stack_base,
                laminaprop=laminaprop,
                mu=mu)
    p11 = Panel(group='flange',
                x0=alow + defect,
                y0=0,
                a=aup,
                b=bf,
                m=mf,
                n=nf,
                plyt=plyt,
                stack=stack_flange,
                laminaprop=laminaprop,
                mu=mu)
    # defect
    p12 = Panel(group='base',
                x0=alow,
                y0=ys - bb / 2.,
                a=defect,
                b=bb,
                r=r,
                m=mb,
                n=nb,
                plyt=plyt,
                stack=stack_base,
                laminaprop=laminaprop,
                mu=mu)
    p13 = Panel(group='flange',
                x0=alow,
                y0=0,
                a=defect,
                b=bf,
                m=mf,
                n=nf,
                plyt=plyt,
                stack=stack_flange,
                laminaprop=laminaprop,
                mu=mu)
    #
    p14 = Panel(group='base',
                x0=0,
                y0=ys - bb / 2.,
                a=alow,
                b=bb,
                r=r,
                m=mb,
                n=nb,
                plyt=plyt,
                stack=stack_base,
                laminaprop=laminaprop,
                mu=mu)
    p15 = Panel(group='flange',
                x0=0,
                y0=0,
                a=alow,
                b=bf,
                m=mf,
                n=nf,
                plyt=plyt,
                stack=stack_flange,
                laminaprop=laminaprop,
                mu=mu)

    # boundary conditions
    p01.u1tx = 1
    p01.u1rx = 1
    p01.u2tx = 0
    p01.u2rx = 1
    p01.v1tx = 1
    p01.v1rx = 1
    p01.v2tx = 0
    p01.v2rx = 1
    p01.w1tx = 1
    p01.w1rx = 1
    p01.w2tx = 0
    p01.w2rx = 1
    p01.u1ty = 1
    p01.u1ry = 1
    p01.u2ty = 0
    p01.u2ry = 1
    p01.v1ty = 1
    p01.v1ry = 1
    p01.v2ty = 0
    p01.v2ry = 1
    p01.w1ty = 1
    p01.w1ry = 1
    p01.w2ty = 0
    p01.w2ry = 1

    p02.u1tx = 1
    p02.u1rx = 1
    p02.u2tx = 0
    p02.u2rx = 1
    p02.v1tx = 1
    p02.v1rx = 1
    p02.v2tx = 0
    p02.v2rx = 1
    p02.w1tx = 1
    p02.w1rx = 1
    p02.w2tx = 0
    p02.w2rx = 1
    p02.u1ty = 1
    p02.u1ry = 1
    p02.u2ty = 1
    p02.u2ry = 1
    p02.v1ty = 1
    p02.v1ry = 1
    p02.v2ty = 1
    p02.v2ry = 1
    p02.w1ty = 1
    p02.w1ry = 1
    p02.w2ty = 1
    p02.w2ry = 1

    p03.u1tx = 1
    p03.u1rx = 1
    p03.u2tx = 0
    p03.u2rx = 1
    p03.v1tx = 1
    p03.v1rx = 1
    p03.v2tx = 0
    p03.v2rx = 1
    p03.w1tx = 1
    p03.w1rx = 1
    p03.w2tx = 0
    p03.w2rx = 1
    p03.u1ty = 0
    p03.u1ry = 1
    p03.u2ty = 1
    p03.u2ry = 1
    p03.v1ty = 0
    p03.v1ry = 1
    p03.v2ty = 1
    p03.v2ry = 1
    p03.w1ty = 0
    p03.w1ry = 1
    p03.w2ty = 1
    p03.w2ry = 1

    p04.u1tx = 1
    p04.u1rx = 1
    p04.u2tx = 1
    p04.u2rx = 1
    p04.v1tx = 1
    p04.v1rx = 1
    p04.v2tx = 1
    p04.v2rx = 1
    p04.w1tx = 1
    p04.w1rx = 1
    p04.w2tx = 1
    p04.w2rx = 1
    p04.u1ty = 1
    p04.u1ry = 1
    p04.u2ty = 0
    p04.u2ry = 1
    p04.v1ty = 1
    p04.v1ry = 1
    p04.v2ty = 0
    p04.v2ry = 1
    p04.w1ty = 1
    p04.w1ry = 1
    p04.w2ty = 0
    p04.w2ry = 1

    p05.u1tx = 1
    p05.u1rx = 1
    p05.u2tx = 1
    p05.u2rx = 1
    p05.v1tx = 1
    p05.v1rx = 1
    p05.v2tx = 1
    p05.v2rx = 1
    p05.w1tx = 1
    p05.w1rx = 1
    p05.w2tx = 1
    p05.w2rx = 1
    p05.u1ty = 1
    p05.u1ry = 1
    p05.u2ty = 1
    p05.u2ry = 1
    p05.v1ty = 1
    p05.v1ry = 1
    p05.v2ty = 1
    p05.v2ry = 1
    p05.w1ty = 1
    p05.w1ry = 1
    p05.w2ty = 1
    p05.w2ry = 1

    p06.u1tx = 1
    p06.u1rx = 1
    p06.u2tx = 1
    p06.u2rx = 1
    p06.v1tx = 1
    p06.v1rx = 1
    p06.v2tx = 1
    p06.v2rx = 1
    p06.w1tx = 1
    p06.w1rx = 1
    p06.w2tx = 1
    p06.w2rx = 1
    p06.u1ty = 0
    p06.u1ry = 1
    p06.u2ty = 1
    p06.u2ry = 1
    p06.v1ty = 0
    p06.v1ry = 1
    p06.v2ty = 1
    p06.v2ry = 1
    p06.w1ty = 0
    p06.w1ry = 1
    p06.w2ty = 1
    p06.w2ry = 1

    p07.u1tx = 0
    p07.u1rx = 1
    p07.u2tx = 1
    p07.u2rx = 1
    p07.v1tx = 0
    p07.v1rx = 1
    p07.v2tx = 1
    p07.v2rx = 1
    p07.w1tx = 0
    p07.w1rx = 1
    p07.w2tx = 1
    p07.w2rx = 1
    p07.u1ty = 1
    p07.u1ry = 1
    p07.u2ty = 0
    p07.u2ry = 1
    p07.v1ty = 1
    p07.v1ry = 1
    p07.v2ty = 0
    p07.v2ry = 1
    p07.w1ty = 1
    p07.w1ry = 1
    p07.w2ty = 0
    p07.w2ry = 1

    p08.u1tx = 0
    p08.u1rx = 1
    p08.u2tx = 1
    p08.u2rx = 1
    p08.v1tx = 0
    p08.v1rx = 1
    p08.v2tx = 1
    p08.v2rx = 1
    p08.w1tx = 0
    p08.w1rx = 1
    p08.w2tx = 1
    p08.w2rx = 1
    p08.u1ty = 1
    p08.u1ry = 1
    p08.u2ty = 1
    p08.u2ry = 1
    p08.v1ty = 1
    p08.v1ry = 1
    p08.v2ty = 1
    p08.v2ry = 1
    p08.w1ty = 1
    p08.w1ry = 1
    p08.w2ty = 1
    p08.w2ry = 1

    p09.u1tx = 0
    p09.u1rx = 1
    p09.u2tx = 1
    p09.u2rx = 1
    p09.v1tx = 0
    p09.v1rx = 1
    p09.v2tx = 1
    p09.v2rx = 1
    p09.w1tx = 0
    p09.w1rx = 1
    p09.w2tx = 1
    p09.w2rx = 1
    p09.u1ty = 0
    p09.u1ry = 1
    p09.u2ty = 1
    p09.u2ry = 1
    p09.v1ty = 0
    p09.v1ry = 1
    p09.v2ty = 1
    p09.v2ry = 1
    p09.w1ty = 0
    p09.w1ry = 1
    p09.w2ty = 1
    p09.w2ry = 1

    # base up
    p10.u1tx = 1
    p10.u1rx = 1
    p10.u2tx = 1
    p10.u2rx = 1
    p10.v1tx = 1
    p10.v1rx = 1
    p10.v2tx = 1
    p10.v2rx = 1
    p10.w1tx = 1
    p10.w1rx = 1
    p10.w2tx = 1
    p10.w2rx = 1
    p10.u1ty = 1
    p10.u1ry = 1
    p10.u2ty = 1
    p10.u2ry = 1
    p10.v1ty = 1
    p10.v1ry = 1
    p10.v2ty = 1
    p10.v2ry = 1
    p10.w1ty = 1
    p10.w1ry = 1
    p10.w2ty = 1
    p10.w2ry = 1

    # flange up
    p11.u1tx = 1
    p11.u1rx = 1
    p11.u2tx = 0
    p11.u2rx = 1
    p11.v1tx = 1
    p11.v1rx = 1
    p11.v2tx = 0
    p11.v2rx = 1
    p11.w1tx = 1
    p11.w1rx = 1
    p11.w2tx = 0
    p11.w2rx = 1
    p11.u1ty = 1
    p11.u1ry = 1
    p11.u2ty = 1
    p11.u2ry = 1
    p11.v1ty = 1
    p11.v1ry = 1
    p11.v2ty = 1
    p11.v2ry = 1
    p11.w1ty = 1
    p11.w1ry = 1
    p11.w2ty = 1
    p11.w2ry = 1

    # base mid
    p12.u1tx = 1
    p12.u1rx = 1
    p12.u2tx = 1
    p12.u2rx = 1
    p12.v1tx = 1
    p12.v1rx = 1
    p12.v2tx = 1
    p12.v2rx = 1
    p12.w1tx = 1
    p12.w1rx = 1
    p12.w2tx = 1
    p12.w2rx = 1
    p12.u1ty = 1
    p12.u1ry = 1
    p12.u2ty = 1
    p12.u2ry = 1
    p12.v1ty = 1
    p12.v1ry = 1
    p12.v2ty = 1
    p12.v2ry = 1
    p12.w1ty = 1
    p12.w1ry = 1
    p12.w2ty = 1
    p12.w2ry = 1

    # flange mid
    p13.u1tx = 1
    p13.u1rx = 1
    p13.u2tx = 1
    p13.u2rx = 1
    p13.v1tx = 1
    p13.v1rx = 1
    p13.v2tx = 1
    p13.v2rx = 1
    p13.w1tx = 1
    p13.w1rx = 1
    p13.w2tx = 1
    p13.w2rx = 1
    p13.u1ty = 1
    p13.u1ry = 1
    p13.u2ty = 1
    p13.u2ry = 1
    p13.v1ty = 1
    p13.v1ry = 1
    p13.v2ty = 1
    p13.v2ry = 1
    p13.w1ty = 1
    p13.w1ry = 1
    p13.w2ty = 1
    p13.w2ry = 1

    # base low
    p14.u1tx = 1
    p14.u1rx = 1
    p14.u2tx = 1
    p14.u2rx = 1
    p14.v1tx = 1
    p14.v1rx = 1
    p14.v2tx = 1
    p14.v2rx = 1
    p14.w1tx = 1
    p14.w1rx = 1
    p14.w2tx = 1
    p14.w2rx = 1
    p14.u1ty = 1
    p14.u1ry = 1
    p14.u2ty = 1
    p14.u2ry = 1
    p14.v1ty = 1
    p14.v1ry = 1
    p14.v2ty = 1
    p14.v2ry = 1
    p14.w1ty = 1
    p14.w1ry = 1
    p14.w2ty = 1
    p14.w2ry = 1

    # flange low
    p15.u1tx = 0
    p15.u1rx = 1
    p15.u2tx = 1
    p15.u2rx = 1
    p15.v1tx = 0
    p15.v1rx = 1
    p15.v2tx = 1
    p15.v2rx = 1
    p15.w1tx = 0
    p15.w1rx = 1
    p15.w2tx = 1
    p15.w2rx = 1
    p15.u1ty = 1
    p15.u1ry = 1
    p15.u2ty = 1
    p15.u2ry = 1
    p15.v1ty = 1
    p15.v1ry = 1
    p15.v2ty = 1
    p15.v2ry = 1
    p15.w1ty = 1
    p15.w1ry = 1
    p15.w2ty = 1
    p15.w2ry = 1

    conn = [
        # skin-skin
        dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b),
        dict(p1=p01, p2=p04, func='SSxcte', xcte1=0, xcte2=p04.a),
        dict(p1=p02, p2=p03, func='SSycte', ycte1=0, ycte2=p03.b),
        dict(p1=p02, p2=p05, func='SSxcte', xcte1=0, xcte2=p05.a),
        dict(p1=p03, p2=p06, func='SSxcte', xcte1=0, xcte2=p06.a),
        dict(p1=p04, p2=p05, func='SSycte', ycte1=0, ycte2=p05.b),
        dict(p1=p04, p2=p07, func='SSxcte', xcte1=0, xcte2=p07.a),
        dict(p1=p05, p2=p06, func='SSycte', ycte1=0, ycte2=p06.b),
        dict(p1=p05, p2=p08, func='SSxcte', xcte1=0, xcte2=p08.a),
        dict(p1=p06, p2=p09, func='SSxcte', xcte1=0, xcte2=p09.a),
        dict(p1=p07, p2=p08, func='SSycte', ycte1=0, ycte2=p08.b),
        dict(p1=p08, p2=p09, func='SSycte', ycte1=0, ycte2=p09.b),

        # skin-base
        dict(p1=p02, p2=p10, func='SB'),
        dict(p1=p05, p2=p12, func='SB', has_defect=has_defect),  # defect
        dict(p1=p08, p2=p14, func='SB'),

        # base-base
        dict(p1=p10, p2=p12, func='SSxcte', xcte1=0, xcte2=p12.a),
        dict(p1=p12, p2=p14, func='SSxcte', xcte1=0, xcte2=p14.a),

        # base-flange
        dict(p1=p10, p2=p11, func='BFycte', ycte1=p10.b / 2., ycte2=0),
        dict(p1=p12, p2=p13, func='BFycte', ycte1=p12.b / 2., ycte2=0),
        dict(p1=p14, p2=p15, func='BFycte', ycte1=p14.b / 2., ycte2=0),

        # flange-flange
        dict(p1=p11, p2=p13, func='SSxcte', xcte1=0, xcte2=p13.a),
        dict(p1=p13, p2=p15, func='SSxcte', xcte1=0, xcte2=p15.a),
    ]

    panels = [
        p01, p02, p03, p04, p05, p06, p07, p08, p09, p10, p11, p12, p13, p14,
        p15
    ]
    skin = [p01, p02, p03, p04, p05, p06, p07, p08, p09]
    base = [p10, p12, p14]
    flange = [p11, p13, p15]

    assy = PanelAssembly(panels)

    size = assy.get_size()

    valid_conn = []
    for connecti in conn:
        if connecti.get('has_defect'):
            continue
        valid_conn.append(connecti)

    k0 = assy.calc_k0(conn=valid_conn)
    kM = assy.calc_kM()

    eigvals, eigvecs = freq(k0,
                            kM,
                            tol=0,
                            sparse_solver=True,
                            silent=True,
                            sort=True,
                            reduced_dof=False,
                            num_eigvalues=25,
                            num_eigvalues_print=5)

    return assy, eigvals, eigvecs
Exemple #30
0
def test_panel_fkG_num_Fnxny():
    for model in ['plate_clt_donnell_bardell', 'cpanel_clt_donnell_bardell']:
        print('Checking fkG_num for model {0}'.format(model))
        # ssss
        p = Panel()
        p.a = 8.
        p.b = 4.
        p.r = 1.e8
        p.stack = [0, 90, 90, 0, -45, +45]
        p.plyt = 1e-3 * 0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.model = model

        p.Nxx = -1.

        p.m = 8
        p.n = 9

        p.u1ty = 1
        p.u2ty = 1
        p.u2tx = 1

        p.v1tx = 0
        p.v2tx = 1
        p.v1ty = 1
        p.v2ty = 1

        num = 1000.
        f = 0.
        for i in range(int(num)):
            if i == 0 or i == num - 2:
                fx = p.Nxx * p.b / (num - 1.) / 2.
            else:
                fx = p.Nxx * p.b / (num - 1.)
            p.add_force(x=p.a,
                        y=i * p.b / (num - 1.),
                        fx=fx,
                        fy=0.,
                        fz=0.,
                        cte=True)
            f += fx

        p.static(silent=True)
        c = p.analysis.cs[0]

        p.lb(silent=True)
        assert np.isclose(p.eigvals[0], 4.5290911349518801, atol=0.01, rtol=0)

        nx = 9
        ny = 9
        Fnxny = p.F
        p.lb(silent=True, c=c, Fnxny=Fnxny, nx=nx, ny=ny)
        assert np.isclose(p.eigvals[0], 4.532851973656947, atol=0.01, rtol=0)

        nx = 12
        ny = 10
        Fnxny = np.array([[p.F] * ny] * nx)
        p.lb(silent=True, c=c, Fnxny=Fnxny, nx=nx, ny=ny)
        assert np.isclose(p.eigvals[0], 4.532851973656947, atol=0.01, rtol=0)
Exemple #31
0
def test_panel_freq():
    for model in [
            'plate_clt_donnell_bardell', 'plate_clt_donnell_bardell_w',
            'cpanel_clt_donnell_bardell', 'kpanel_clt_donnell_bardell'
    ]:
        for prestress in [True, False]:
            print('Frequency Analysis, prestress={0}, model={1}'.format(
                prestress, model))
            p = Panel()
            p.model = model
            p.a = 1.
            p.b = 0.5
            p.r = 1.e8
            p.alphadeg = 0.
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3 * 0.125
            p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.mu = 1.3e3
            p.m = 11
            p.n = 12
            p.Nxx = -60.
            p.Nyy = -5.
            k0 = p.calc_k0(silent=True)
            M = p.calc_kM(silent=True)
            if prestress:
                kG0 = p.calc_kG0(silent=True)
                k0 += kG0
            eigvals, eigvecs = freq(k0,
                                    M,
                                    sparse_solver=True,
                                    reduced_dof=False,
                                    silent=True)
            if prestress:
                if '_w' in model:
                    assert np.isclose(eigvals[0], 19.9272, rtol=0.001)
                else:
                    assert np.isclose(eigvals[0], 17.85875, rtol=0.001)
            else:
                if '_w' in model:
                    assert np.isclose(eigvals[0], 40.37281, rtol=0.001)
                else:
                    assert np.isclose(eigvals[0], 39.31476, rtol=0.001)
Exemple #32
0
class TStiff2D(object):
    r"""T Stiffener using 2D Formulation for the Base and Flange

    T-type of stiffener model using a 2D formulation for the flange and a
    2D formulation for the base::


                 || --> flange       |
                 ||                  |-> stiffener
               ======  --> base      |
      =========================  --> panels
         Panel1      Panel2

    The difference between this model and :class:'.BladeStiff2D' is that here
    the stiffener's base has independent field variables allowing the
    simulation of skin-stiffener debounding effects.

    Each stiffener has a constant `y_s` coordinate.

    """
    def __init__(self,
                 bay,
                 mu,
                 panel1,
                 panel2,
                 ys,
                 bb,
                 bf,
                 bstack,
                 bplyts,
                 blaminaprops,
                 fstack,
                 fplyts,
                 flaminaprops,
                 model='tstiff2d_clt_donnell_bardell',
                 mb=15,
                 nb=12,
                 mf=15,
                 nf=12):

        print(
            '\n\nWARNING - TStiff2D no longer recommended!\n'
            '          There is a numerically unstable way to compute the\n'
            '          connection between the skin and stiffener\'s base, it is\n'
            '          recommended to use panel.assembly instead.\n'
            '          Module panel.assembly allows stable ways to perform\n'
            '          connection among panels, and avoids using sliced\n'
            '          integration intervals that were causing trouble in\n'
            '          TStiff2D\n\n')

        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.model = model

        if bstack is None:
            raise ValueError('Base laminate must be defined!')
        self.ys = ys
        y1 = ys - bb / 2.
        y2 = ys + bb / 2.
        self.base = Panel(a=bay.a,
                          b=bb,
                          r=bay.r,
                          alphadeg=bay.alphadeg,
                          stack=bstack,
                          plyts=bplyts,
                          laminaprops=blaminaprops,
                          mu=mu,
                          m=mb,
                          n=nb,
                          offset=0.,
                          u1tx=1,
                          u1rx=0,
                          u2tx=1,
                          u2rx=0,
                          v1tx=1,
                          v1rx=0,
                          v2tx=1,
                          v2rx=0,
                          w1tx=1,
                          w1rx=1,
                          w2tx=1,
                          w2rx=1,
                          u1ty=1,
                          u1ry=0,
                          u2ty=1,
                          u2ry=0,
                          v1ty=1,
                          v1ry=0,
                          v2ty=1,
                          v2ry=0,
                          w1ty=1,
                          w1ry=1,
                          w2ty=1,
                          w2ry=1,
                          y1=y1,
                          y2=y2)
        self.base._rebuild()

        if fstack is None:
            raise ValueError('Flange laminate must be defined!')
        self.flange = Panel(a=bay.a,
                            b=bf,
                            model='plate_clt_donnell_bardell',
                            stack=fstack,
                            plyts=fplyts,
                            laminaprops=flaminaprops,
                            mu=mu,
                            m=mf,
                            n=nf,
                            offset=0.,
                            u1tx=0,
                            u1rx=0,
                            u2tx=0,
                            u2rx=0,
                            v1tx=0,
                            v1rx=0,
                            v2tx=0,
                            v2rx=0,
                            w1tx=0,
                            w1rx=1,
                            w2tx=0,
                            w2rx=1,
                            u1ty=1,
                            u1ry=0,
                            u2ty=1,
                            u2ry=0,
                            v1ty=1,
                            v1ry=0,
                            v2ty=1,
                            v2ry=0,
                            w1ty=1,
                            w1ry=1,
                            w2ty=1,
                            w2ry=1)
        self.flange._rebuild()

        self.eta_conn_base = 0.
        self.eta_conn_flange = -1.

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self._rebuild()

    def _rebuild(self):
        assert self.panel1.model == self.panel2.model
        assert self.panel1.r == self.panel2.r
        assert self.panel1.alphadeg == self.panel2.alphadeg
        a = None
        b = None
        if self.panel1 is not None:
            a = self.panel1.a
            b = self.panel1.b
        elif self.panel2 is not None:
            a = self.panel2.a
            b = self.panel2.b
        if a is not None and b is not None:
            if a / b > 10.:
                if self.base.m <= 15 and self.flange.m <= 15:
                    raise RuntimeError(
                        'For a/b > 10. use base.m and flange.m > 15')
                else:
                    warn(
                        'For a/b > 10. be sure to check convergence for base.m and flange.m'
                    )

        self.flange.lam = laminate.read_stack(
            self.flange.stack,
            plyts=self.flange.plyts,
            laminaprops=self.flange.laminaprops)
        #NOTE below offset is not needed since it is already considered in the
        #     connectivity matrices, using dpb
        h = 0.5 * sum(self.panel1.plyts) + 0.5 * sum(self.panel2.plyts)
        hb = sum(self.base.plyts)
        self.dpb = h / 2. + hb / 2.
        self.base.lam = laminate.read_stack(self.base.stack,
                                            plyts=self.base.plyts,
                                            laminaprops=self.base.laminaprops,
                                            offset=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)

    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)

    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)
Exemple #33
0
    def __init__(self,
                 bay,
                 mu,
                 panel1,
                 panel2,
                 ys,
                 bb,
                 bf,
                 bstack,
                 bplyts,
                 blaminaprops,
                 fstack,
                 fplyts,
                 flaminaprops,
                 model='tstiff2d_clt_donnell_bardell',
                 mb=15,
                 nb=12,
                 mf=15,
                 nf=12):

        print(
            '\n\nWARNING - TStiff2D no longer recommended!\n'
            '          There is a numerically unstable way to compute the\n'
            '          connection between the skin and stiffener\'s base, it is\n'
            '          recommended to use panel.assembly instead.\n'
            '          Module panel.assembly allows stable ways to perform\n'
            '          connection among panels, and avoids using sliced\n'
            '          integration intervals that were causing trouble in\n'
            '          TStiff2D\n\n')

        self.bay = bay
        self.panel1 = panel1
        self.panel2 = panel2
        self.model = model

        if bstack is None:
            raise ValueError('Base laminate must be defined!')
        self.ys = ys
        y1 = ys - bb / 2.
        y2 = ys + bb / 2.
        self.base = Panel(a=bay.a,
                          b=bb,
                          r=bay.r,
                          alphadeg=bay.alphadeg,
                          stack=bstack,
                          plyts=bplyts,
                          laminaprops=blaminaprops,
                          mu=mu,
                          m=mb,
                          n=nb,
                          offset=0.,
                          u1tx=1,
                          u1rx=0,
                          u2tx=1,
                          u2rx=0,
                          v1tx=1,
                          v1rx=0,
                          v2tx=1,
                          v2rx=0,
                          w1tx=1,
                          w1rx=1,
                          w2tx=1,
                          w2rx=1,
                          u1ty=1,
                          u1ry=0,
                          u2ty=1,
                          u2ry=0,
                          v1ty=1,
                          v1ry=0,
                          v2ty=1,
                          v2ry=0,
                          w1ty=1,
                          w1ry=1,
                          w2ty=1,
                          w2ry=1,
                          y1=y1,
                          y2=y2)
        self.base._rebuild()

        if fstack is None:
            raise ValueError('Flange laminate must be defined!')
        self.flange = Panel(a=bay.a,
                            b=bf,
                            model='plate_clt_donnell_bardell',
                            stack=fstack,
                            plyts=fplyts,
                            laminaprops=flaminaprops,
                            mu=mu,
                            m=mf,
                            n=nf,
                            offset=0.,
                            u1tx=0,
                            u1rx=0,
                            u2tx=0,
                            u2rx=0,
                            v1tx=0,
                            v1rx=0,
                            v2tx=0,
                            v2rx=0,
                            w1tx=0,
                            w1rx=1,
                            w2tx=0,
                            w2rx=1,
                            u1ty=1,
                            u1ry=0,
                            u2ty=1,
                            u2ry=0,
                            v1ty=1,
                            v1ry=0,
                            v2ty=1,
                            v2ry=0,
                            w1ty=1,
                            w1ry=1,
                            w2ty=1,
                            w2ry=1)
        self.flange._rebuild()

        self.eta_conn_base = 0.
        self.eta_conn_flange = -1.

        self.k0 = None
        self.kM = None
        self.kG0 = None

        self._rebuild()
Exemple #34
0
def test_reduced_dof_freq_plate():
    models = ['plate_clt_donnell_bardell',
              'cpanel_clt_donnell_bardell']
    for model in models:
        print('Test reduced_dof solver, prestress=True, model={0}'.format(model))
        p = Panel()
        p.model = model
        p.a = 1.
        p.b = 0.5
        p.r = 100.
        p.alphadeg = 0.
        p.stack = [0, 90, -45, +45]
        p.plyt = 1e-3*0.125
        p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
        p.mu = 1.3e3
        p.m = 11
        p.n = 12
        p.Nxx = -60.
        p.Nyy = -5.
        k0 = p.calc_k0(silent=True)
        M = p.calc_kM(silent=True)
        kG0 = p.calc_kG0(silent=True)
        k0 += kG0
        eigvals, eigvecs = freq(k0, M, sparse_solver=True, reduced_dof=False, silent=True)
        reduced_false = eigvals[0]
        freq(k0, M, sparse_solver=True, reduced_dof=True, silent=True)
        reduced_true = eigvals[0]
        assert np.isclose(reduced_false, reduced_true, rtol=0.001)
def test_kT():
    mns = [[4, 4], [4, 5], [4, 6], [5, 5], [5, 6], [6, 6],
           [8, 9], [9, 8]]
    for m, n in mns:
        for model in ['plate_clt_donnell_bardell',
                      'cpanel_clt_donnell_bardell']:
            p = Panel()
            p.model = model
            p.w1tx = 0
            p.u1tx = 1
            p.u1ty = 1
            p.u2ty = 1
            p.a = 2.
            p.b = 0.5
            p.r = 10
            p.stack = [0, 90, -45, +45]
            p.plyt = 1e-3*0.125
            p.laminaprop = (142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9)
            p.m = m
            p.n = n
            p.nx = m
            p.ny = n

            P = 1000.
            npts = 5
            p.forces_inc = []
            for y in np.linspace(0, p.b, npts):
                p.forces_inc.append([0., y, P/(npts-1.), 0, 0])
            p.forces_inc[0][2] /= 2.
            p.forces_inc[-1][2] /= 2.

            k0 = p.calc_k0(silent=True)
            kT = p.calc_kT(c=np.zeros(p.get_size()), silent=True)

            error = np.abs(kT-k0).sum()

            assert error < 1.e-7
def tstiff2d_1stiff_freq(a, b, ys, bb, bf, defect_a, mu, plyt, laminaprop,
        stack_skin, stack_base, stack_flange,
        r=None, m=8, n=8, mb=None, nb=None, mf=None, nf=None):
    r"""Frequency T-Stiffened Panel with possible defect at middle

    For more details about each parameter and the aerodynamic formulation see
    Ref. [castro2016FlutterPanel]_ .

    For more details about the theory involved on the assembly of panels, see
    [castro2017AssemblyModels]_.

    The panel assembly looks like::

        skin
         _________ _____ _________
        |         |     |         |
        |         |     |         |
        |   p01   | p02 |   p03   |
        |         |     |         |
        |_________|_____|_________|
        |   p04   | p05 |   p06   |
        |_________|_____|_________|
        |         |     |         |
        |         |     |         |
        |   p07   | p08 |   p09   |
        |         |     |         |
        |         |     |         |
        |_________|_____|_________|

                  base            flange
                   _____           _____
                  |     |         |     |
                  |     |         |     |
                  | p10 |         | p11 |
                  |     |         |     |
                  |_____|         |_____|
                  | p12 |         | p13 |
                  |_____|         |_____|
                  |     |         |     |
                  |     |         |     |
                  | p14 |         | p15 |
                  |     |         |     |
                  |     |         |     |
                  |_____|         |_____|

    Parameters
    ----------

    a : float
        Total length of the assembly (along `x`).
    b : float
        Total width of the assembly (along `y`).
    ys : float
        Position of the stiffener along `y`.
    bb : float
        Stiffener's base width.
    bf : float
        Stiffener's flange width.
    defect_a : float
        Debonding defect/assembly length ratio.
    mu : float
        Material density.
    plyt : float
        Ply thickness.
    laminaprop : list or tuple
        Orthotropic lamina properties: `E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}`.
    stack_skin : list or tuple
        Stacking sequence for the skin.
    stack_base : list or tuple
        Stacking sequence for the stiffener's base.
    stack_flange : list or tuple
        Stacking sequence for the stiffener's flange.
    r : float or None, optional
        Radius of the stiffened panel.
    m, n : int, optional
        Number of terms of the approximation function for the skin.
    mb, nb : int, optional
        Number of terms of the approximation function for the stiffener's base.
    mf, nf : int, optional
        Number of terms of the approximation function for the stiffener's
        flange.

    Examples
    --------

    The following example is one of the test cases:

    .. literalinclude:: ../../../../../compmech/panel/assembly/tests/test_tstiff2d_assembly.py
        :pyobject: test_tstiff2d_1stiff_freq


    """
    defect = defect_a * a
    has_defect = True if defect > 0 else False
    defect = 0.33*a if defect == 0 else defect # to avoid weird domains
    aup = (a - defect)/2.
    alow = (a - defect)/2.
    bleft = b - ys - bb/2.
    bright = ys - bb/2.
    mb = m if mb is None else mb
    nb = n if nb is None else nb
    mf = m if mf is None else mf
    nf = n if nf is None else nf
    # skin panels
    p01 = Panel(group='skin', x0=alow+defect, y0=ys+bb/2., a=aup, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p02 = Panel(group='skin', x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p03 = Panel(group='skin', x0=alow+defect, y0=0,        a=aup, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    # defect
    p04 = Panel(group='skin', x0=alow, y0=ys+bb/2., a=defect, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p05 = Panel(group='skin', x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p06 = Panel(group='skin', x0=alow, y0=0,        a=defect, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    #
    p07 = Panel(group='skin', x0=0, y0=ys+bb/2., a=alow, b=bleft, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p08 = Panel(group='skin', x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)
    p09 = Panel(group='skin', x0=0, y0=0,        a=alow, b=bright, r=r, m=m, n=n, plyt=plyt, stack=stack_skin, laminaprop=laminaprop, mu=mu)

    # stiffeners
    p10 = Panel(group='base', x0=alow+defect, y0=ys-bb/2., a=aup, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p11 = Panel(group='flange', x0=alow+defect, y0=0,        a=aup, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)
    # defect
    p12 = Panel(group='base', x0=alow, y0=ys-bb/2., a=defect, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p13 = Panel(group='flange', x0=alow, y0=0,        a=defect, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)
    #
    p14 = Panel(group='base', x0=0, y0=ys-bb/2., a=alow, b=bb, r=r, m=mb, n=nb, plyt=plyt, stack=stack_base, laminaprop=laminaprop, mu=mu)
    p15 = Panel(group='flange', x0=0, y0=0,        a=alow, b=bf, m=mf, n=nf, plyt=plyt, stack=stack_flange, laminaprop=laminaprop, mu=mu)

    # boundary conditions
    p01.u1tx = 1 ; p01.u1rx = 1 ; p01.u2tx = 0 ; p01.u2rx = 1
    p01.v1tx = 1 ; p01.v1rx = 1 ; p01.v2tx = 0 ; p01.v2rx = 1
    p01.w1tx = 1 ; p01.w1rx = 1 ; p01.w2tx = 0 ; p01.w2rx = 1
    p01.u1ty = 1 ; p01.u1ry = 1 ; p01.u2ty = 0 ; p01.u2ry = 1
    p01.v1ty = 1 ; p01.v1ry = 1 ; p01.v2ty = 0 ; p01.v2ry = 1
    p01.w1ty = 1 ; p01.w1ry = 1 ; p01.w2ty = 0 ; p01.w2ry = 1

    p02.u1tx = 1 ; p02.u1rx = 1 ; p02.u2tx = 0 ; p02.u2rx = 1
    p02.v1tx = 1 ; p02.v1rx = 1 ; p02.v2tx = 0 ; p02.v2rx = 1
    p02.w1tx = 1 ; p02.w1rx = 1 ; p02.w2tx = 0 ; p02.w2rx = 1
    p02.u1ty = 1 ; p02.u1ry = 1 ; p02.u2ty = 1 ; p02.u2ry = 1
    p02.v1ty = 1 ; p02.v1ry = 1 ; p02.v2ty = 1 ; p02.v2ry = 1
    p02.w1ty = 1 ; p02.w1ry = 1 ; p02.w2ty = 1 ; p02.w2ry = 1

    p03.u1tx = 1 ; p03.u1rx = 1 ; p03.u2tx = 0 ; p03.u2rx = 1
    p03.v1tx = 1 ; p03.v1rx = 1 ; p03.v2tx = 0 ; p03.v2rx = 1
    p03.w1tx = 1 ; p03.w1rx = 1 ; p03.w2tx = 0 ; p03.w2rx = 1
    p03.u1ty = 0 ; p03.u1ry = 1 ; p03.u2ty = 1 ; p03.u2ry = 1
    p03.v1ty = 0 ; p03.v1ry = 1 ; p03.v2ty = 1 ; p03.v2ry = 1
    p03.w1ty = 0 ; p03.w1ry = 1 ; p03.w2ty = 1 ; p03.w2ry = 1

    p04.u1tx = 1 ; p04.u1rx = 1 ; p04.u2tx = 1 ; p04.u2rx = 1
    p04.v1tx = 1 ; p04.v1rx = 1 ; p04.v2tx = 1 ; p04.v2rx = 1
    p04.w1tx = 1 ; p04.w1rx = 1 ; p04.w2tx = 1 ; p04.w2rx = 1
    p04.u1ty = 1 ; p04.u1ry = 1 ; p04.u2ty = 0 ; p04.u2ry = 1
    p04.v1ty = 1 ; p04.v1ry = 1 ; p04.v2ty = 0 ; p04.v2ry = 1
    p04.w1ty = 1 ; p04.w1ry = 1 ; p04.w2ty = 0 ; p04.w2ry = 1

    p05.u1tx = 1 ; p05.u1rx = 1 ; p05.u2tx = 1 ; p05.u2rx = 1
    p05.v1tx = 1 ; p05.v1rx = 1 ; p05.v2tx = 1 ; p05.v2rx = 1
    p05.w1tx = 1 ; p05.w1rx = 1 ; p05.w2tx = 1 ; p05.w2rx = 1
    p05.u1ty = 1 ; p05.u1ry = 1 ; p05.u2ty = 1 ; p05.u2ry = 1
    p05.v1ty = 1 ; p05.v1ry = 1 ; p05.v2ty = 1 ; p05.v2ry = 1
    p05.w1ty = 1 ; p05.w1ry = 1 ; p05.w2ty = 1 ; p05.w2ry = 1

    p06.u1tx = 1 ; p06.u1rx = 1 ; p06.u2tx = 1 ; p06.u2rx = 1
    p06.v1tx = 1 ; p06.v1rx = 1 ; p06.v2tx = 1 ; p06.v2rx = 1
    p06.w1tx = 1 ; p06.w1rx = 1 ; p06.w2tx = 1 ; p06.w2rx = 1
    p06.u1ty = 0 ; p06.u1ry = 1 ; p06.u2ty = 1 ; p06.u2ry = 1
    p06.v1ty = 0 ; p06.v1ry = 1 ; p06.v2ty = 1 ; p06.v2ry = 1
    p06.w1ty = 0 ; p06.w1ry = 1 ; p06.w2ty = 1 ; p06.w2ry = 1

    p07.u1tx = 0 ; p07.u1rx = 1 ; p07.u2tx = 1 ; p07.u2rx = 1
    p07.v1tx = 0 ; p07.v1rx = 1 ; p07.v2tx = 1 ; p07.v2rx = 1
    p07.w1tx = 0 ; p07.w1rx = 1 ; p07.w2tx = 1 ; p07.w2rx = 1
    p07.u1ty = 1 ; p07.u1ry = 1 ; p07.u2ty = 0 ; p07.u2ry = 1
    p07.v1ty = 1 ; p07.v1ry = 1 ; p07.v2ty = 0 ; p07.v2ry = 1
    p07.w1ty = 1 ; p07.w1ry = 1 ; p07.w2ty = 0 ; p07.w2ry = 1

    p08.u1tx = 0 ; p08.u1rx = 1 ; p08.u2tx = 1 ; p08.u2rx = 1
    p08.v1tx = 0 ; p08.v1rx = 1 ; p08.v2tx = 1 ; p08.v2rx = 1
    p08.w1tx = 0 ; p08.w1rx = 1 ; p08.w2tx = 1 ; p08.w2rx = 1
    p08.u1ty = 1 ; p08.u1ry = 1 ; p08.u2ty = 1 ; p08.u2ry = 1
    p08.v1ty = 1 ; p08.v1ry = 1 ; p08.v2ty = 1 ; p08.v2ry = 1
    p08.w1ty = 1 ; p08.w1ry = 1 ; p08.w2ty = 1 ; p08.w2ry = 1

    p09.u1tx = 0 ; p09.u1rx = 1 ; p09.u2tx = 1 ; p09.u2rx = 1
    p09.v1tx = 0 ; p09.v1rx = 1 ; p09.v2tx = 1 ; p09.v2rx = 1
    p09.w1tx = 0 ; p09.w1rx = 1 ; p09.w2tx = 1 ; p09.w2rx = 1
    p09.u1ty = 0 ; p09.u1ry = 1 ; p09.u2ty = 1 ; p09.u2ry = 1
    p09.v1ty = 0 ; p09.v1ry = 1 ; p09.v2ty = 1 ; p09.v2ry = 1
    p09.w1ty = 0 ; p09.w1ry = 1 ; p09.w2ty = 1 ; p09.w2ry = 1

    # base up
    p10.u1tx = 1 ; p10.u1rx = 1 ; p10.u2tx = 1 ; p10.u2rx = 1
    p10.v1tx = 1 ; p10.v1rx = 1 ; p10.v2tx = 1 ; p10.v2rx = 1
    p10.w1tx = 1 ; p10.w1rx = 1 ; p10.w2tx = 1 ; p10.w2rx = 1
    p10.u1ty = 1 ; p10.u1ry = 1 ; p10.u2ty = 1 ; p10.u2ry = 1
    p10.v1ty = 1 ; p10.v1ry = 1 ; p10.v2ty = 1 ; p10.v2ry = 1
    p10.w1ty = 1 ; p10.w1ry = 1 ; p10.w2ty = 1 ; p10.w2ry = 1

    # flange up
    p11.u1tx = 1 ; p11.u1rx = 1 ; p11.u2tx = 0 ; p11.u2rx = 1
    p11.v1tx = 1 ; p11.v1rx = 1 ; p11.v2tx = 0 ; p11.v2rx = 1
    p11.w1tx = 1 ; p11.w1rx = 1 ; p11.w2tx = 0 ; p11.w2rx = 1
    p11.u1ty = 1 ; p11.u1ry = 1 ; p11.u2ty = 1 ; p11.u2ry = 1
    p11.v1ty = 1 ; p11.v1ry = 1 ; p11.v2ty = 1 ; p11.v2ry = 1
    p11.w1ty = 1 ; p11.w1ry = 1 ; p11.w2ty = 1 ; p11.w2ry = 1

    # base mid
    p12.u1tx = 1 ; p12.u1rx = 1 ; p12.u2tx = 1 ; p12.u2rx = 1
    p12.v1tx = 1 ; p12.v1rx = 1 ; p12.v2tx = 1 ; p12.v2rx = 1
    p12.w1tx = 1 ; p12.w1rx = 1 ; p12.w2tx = 1 ; p12.w2rx = 1
    p12.u1ty = 1 ; p12.u1ry = 1 ; p12.u2ty = 1 ; p12.u2ry = 1
    p12.v1ty = 1 ; p12.v1ry = 1 ; p12.v2ty = 1 ; p12.v2ry = 1
    p12.w1ty = 1 ; p12.w1ry = 1 ; p12.w2ty = 1 ; p12.w2ry = 1

    # flange mid
    p13.u1tx = 1 ; p13.u1rx = 1 ; p13.u2tx = 1 ; p13.u2rx = 1
    p13.v1tx = 1 ; p13.v1rx = 1 ; p13.v2tx = 1 ; p13.v2rx = 1
    p13.w1tx = 1 ; p13.w1rx = 1 ; p13.w2tx = 1 ; p13.w2rx = 1
    p13.u1ty = 1 ; p13.u1ry = 1 ; p13.u2ty = 1 ; p13.u2ry = 1
    p13.v1ty = 1 ; p13.v1ry = 1 ; p13.v2ty = 1 ; p13.v2ry = 1
    p13.w1ty = 1 ; p13.w1ry = 1 ; p13.w2ty = 1 ; p13.w2ry = 1

    # base low
    p14.u1tx = 1 ; p14.u1rx = 1 ; p14.u2tx = 1 ; p14.u2rx = 1
    p14.v1tx = 1 ; p14.v1rx = 1 ; p14.v2tx = 1 ; p14.v2rx = 1
    p14.w1tx = 1 ; p14.w1rx = 1 ; p14.w2tx = 1 ; p14.w2rx = 1
    p14.u1ty = 1 ; p14.u1ry = 1 ; p14.u2ty = 1 ; p14.u2ry = 1
    p14.v1ty = 1 ; p14.v1ry = 1 ; p14.v2ty = 1 ; p14.v2ry = 1
    p14.w1ty = 1 ; p14.w1ry = 1 ; p14.w2ty = 1 ; p14.w2ry = 1

    # flange low
    p15.u1tx = 0 ; p15.u1rx = 1 ; p15.u2tx = 1 ; p15.u2rx = 1
    p15.v1tx = 0 ; p15.v1rx = 1 ; p15.v2tx = 1 ; p15.v2rx = 1
    p15.w1tx = 0 ; p15.w1rx = 1 ; p15.w2tx = 1 ; p15.w2rx = 1
    p15.u1ty = 1 ; p15.u1ry = 1 ; p15.u2ty = 1 ; p15.u2ry = 1
    p15.v1ty = 1 ; p15.v1ry = 1 ; p15.v2ty = 1 ; p15.v2ry = 1
    p15.w1ty = 1 ; p15.w1ry = 1 ; p15.w2ty = 1 ; p15.w2ry = 1

    conn = [
        # skin-skin
        dict(p1=p01, p2=p02, func='SSycte', ycte1=0, ycte2=p02.b),
        dict(p1=p01, p2=p04, func='SSxcte', xcte1=0, xcte2=p04.a),
        dict(p1=p02, p2=p03, func='SSycte', ycte1=0, ycte2=p03.b),
        dict(p1=p02, p2=p05, func='SSxcte', xcte1=0, xcte2=p05.a),
        dict(p1=p03, p2=p06, func='SSxcte', xcte1=0, xcte2=p06.a),
        dict(p1=p04, p2=p05, func='SSycte', ycte1=0, ycte2=p05.b),
        dict(p1=p04, p2=p07, func='SSxcte', xcte1=0, xcte2=p07.a),
        dict(p1=p05, p2=p06, func='SSycte', ycte1=0, ycte2=p06.b),
        dict(p1=p05, p2=p08, func='SSxcte', xcte1=0, xcte2=p08.a),
        dict(p1=p06, p2=p09, func='SSxcte', xcte1=0, xcte2=p09.a),
        dict(p1=p07, p2=p08, func='SSycte', ycte1=0, ycte2=p08.b),
        dict(p1=p08, p2=p09, func='SSycte', ycte1=0, ycte2=p09.b),

        # skin-base
        dict(p1=p02, p2=p10, func='SB'),
        dict(p1=p05, p2=p12, func='SB', has_defect=has_defect), # defect
        dict(p1=p08, p2=p14, func='SB'),

        # base-base
        dict(p1=p10, p2=p12, func='SSxcte', xcte1=0, xcte2=p12.a),
        dict(p1=p12, p2=p14, func='SSxcte', xcte1=0, xcte2=p14.a),

        # base-flange
        dict(p1=p10, p2=p11, func='BFycte', ycte1=p10.b/2., ycte2=0),
        dict(p1=p12, p2=p13, func='BFycte', ycte1=p12.b/2., ycte2=0),
        dict(p1=p14, p2=p15, func='BFycte', ycte1=p14.b/2., ycte2=0),

        # flange-flange
        dict(p1=p11, p2=p13, func='SSxcte', xcte1=0, xcte2=p13.a),
        dict(p1=p13, p2=p15, func='SSxcte', xcte1=0, xcte2=p15.a),
        ]

    panels = [p01, p02, p03, p04, p05, p06, p07, p08, p09,
            p10, p11, p12, p13, p14, p15]
    skin = [p01, p02, p03, p04, p05, p06, p07, p08, p09]
    base = [p10, p12, p14]
    flange = [p11, p13, p15]

    assy = PanelAssembly(panels)

    size = assy.get_size()

    valid_conn = []
    for connecti in conn:
        if connecti.get('has_defect'):
            continue
        valid_conn.append(connecti)

    k0 = assy.calc_k0(conn=valid_conn)
    kM = assy.calc_kM()

    eigvals, eigvecs = freq(k0, kM, tol=0, sparse_solver=True, silent=True,
             sort=True, reduced_dof=False,
             num_eigvalues=25, num_eigvalues_print=5)

    return assy, eigvals, eigvecs