예제 #1
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)
예제 #2
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)
예제 #3
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)
예제 #4
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)
예제 #5
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)
예제 #6
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)
예제 #7
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)
예제 #8
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)
예제 #9
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)