Stiffened panel bays#

A StiffPanelBay is built by setting the attributes of the bay, adding the panels of the skin, separated along \(y\), and then the blade stiffeners at the edges between the panels, see Stiffened panels. The bay below has one stiffener at the middle of its width, with a 1D or a 2D flange and with or without a base:

def _bay(stiffener=None, m=8, n=8):
    """Two-panel bay with an optional stiffener at mid-width"""
    bay = StiffPanelBay()
    bay.a = 2*b
    bay.b = b
    bay.r = None
    bay.model = 'plate_clpt_donnell'
    bay.stack = stack
    bay.plyt = plyt
    bay.laminaprop = laminaprop
    bay.rho = 1600.
    bay.m = m
    bay.n = n
    bay.add_panel(0, b/2, Nxx=-1.)
    bay.add_panel(b/2, b, Nxx=-1.)
    if stiffener == '1d':
        bay.add_bladestiff1d(ys=b/2, bf=9*tskin, fstack=stack, fplyt=plyt,
                             flaminaprop=laminaprop)
    elif stiffener == '1d_base':
        bay.add_bladestiff1d(ys=b/2, bb=10*tskin, bstack=stack, bplyt=plyt,
                             blaminaprop=laminaprop, bf=9*tskin, fstack=stack,
                             fplyt=plyt, flaminaprop=laminaprop)
    elif stiffener == '2d':
        bay.add_bladestiff2d(ys=b/2, bf=9*tskin, fstack=stack, fplyt=plyt,
                             flaminaprop=laminaprop, mf=MF, nf=NF)
    elif stiffener == '2d_base':
        bay.add_bladestiff2d(ys=b/2, bb=10*tskin, bstack=stack, bplyt=plyt,
                             blaminaprop=laminaprop, bf=9*tskin, fstack=stack,
                             fplyt=plyt, flaminaprop=laminaprop, mf=MF, nf=NF)
    return bay

Its linear buckling analysis uses the matrices of the bay as those of a Shell:

def _lb(bay):
    eigvals, eigvecs = lb(bay.calc_kC(silent=True), bay.calc_kG(silent=True),
                          silent=True, num_eigvalues=3)
    return eigvals, eigvecs

A flange, and a base, increase the buckling load of the bay, and the two formulations of the flange agree roughly:

@pytest.mark.slow
def test_bladestiff2d_increases_buckling_load():
    unstiffened, _ = _lb(_bay())
    flange, _ = _lb(_bay('2d'))
    flange_base, _ = _lb(_bay('2d_base'))
    assert flange[0] > 3*unstiffened[0]
    # the base adds stiffness to the skin
    assert flange_base[0] > flange[0]
@pytest.mark.slow
def test_bladestiff2d_close_to_bladestiff1d():
    """Both blade formulations model the same stiffener

    The 1D flange is a beam following the skin, whereas the 2D flange is a
    plate connected to the skin by penalties, so the two agree only roughly.

    """
    ev1d, _ = _lb(_bay('1d'))
    ev2d, _ = _lb(_bay('2d'))
    assert np.isclose(ev1d[0], ev2d[0], rtol=0.2)

Dividing an unstiffened skin into panels does not change its buckling load, since the panels share the approximation functions of the bay:

def _bay(nstiff, m=14, n=14):
    b = 100*tskin
    bay = StiffPanelBay()
    bay.a = 2*b
    bay.b = b
    bay.r = None
    bay.model = 'plate_clpt_donnell'
    bay.stack = stack
    bay.plyt = plyt
    bay.laminaprop = laminaprop
    bay.rho = 1600.
    bay.m = m
    bay.n = n

    ys = [(j + 1)*b/(nstiff + 1) for j in range(nstiff)]
    y_prev = 0.
    for y in ys + [b]:
        bay.add_panel(y1=y_prev, y2=y, Nxx=-1.)
        y_prev = y
    for y in ys:
        bay.add_bladestiff1d(ys=y, bf=9*tskin, fstack=stack, fplyt=plyt,
                             flaminaprop=laminaprop)
    return bay
@pytest.mark.slow
def test_unstiffened_bay_matches_single_shell():
    """Splitting the skin into panels must not change the buckling load"""
    bay = _bay(nstiff=0)
    bay.panels = []
    b = bay.b
    #NOTE the default 2*m x 2*n Gauss-Legendre points of each panel already
    #     integrate exactly the polynomial integrands of the matrices
    for y1, y2 in zip([0, b/3, 2*b/3], [b/3, 2*b/3, b]):
        bay.add_panel(y1=y1, y2=y2, Nxx=-1.)
    eigvals_bay, _ = lb(bay.calc_kC(silent=True), bay.calc_kG(silent=True),
                        silent=True, num_eigvalues=4)

    s = Shell(a=bay.a, b=bay.b, r=None, stack=stack, plyt=plyt,
              laminaprop=laminaprop, model=bay.model, m=bay.m, n=bay.n)
    s.Nxx = -1.
    eigvals_shell, _ = lb(s.calc_kC(silent=True), s.calc_kG(silent=True),
                          silent=True, num_eigvalues=4)

    assert np.allclose(eigvals_bay[:3], eigvals_shell[:3], rtol=3e-3)