Laminated plate and ABD matrix#

laminated_plate() creates a Laminate from the stacking sequence, from the bottom to the top ply, see Defining a laminate: conventions. The ABD matrix of the CLPT and the FSDT, the corrected transverse shear stiffness Ats, the equivalent properties and the mass integrals are computed at once. The code below is extracted from one of the composites unit tests:

def test_example_laminated_plate():
    # quasi-isotropic CFRP laminate [0/45/-45/90]s, SI units
    laminaprop = (142e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 3.2e9) # E11, E22, nu12, G12, G13, G23
    stack = [0, 45, -45, 90, 90, -45, 45, 0] # from the bottom to the top
    lam = laminated_plate(stack, plyt=0.125e-3, laminaprop=laminaprop,
                          rho=1600.)
    # ABD relates {Nxx, Nyy, Nxy, Mxx, Myy, Mxy} to the generalized strains
    # {exx0, eyy0, gxy0, kxx, kyy, kxy}
    ABD = lam.ABD
    assert ABD.shape == (6, 6)
    assert np.allclose(ABD[:3, :3], lam.A) and np.allclose(ABD[:3, 3:], lam.B)
    assert np.allclose(ABD[3:, 3:], lam.D)
    # symmetric laminate: no membrane-bending coupling
    assert np.allclose(lam.B, 0, atol=1e-12*lam.A11*lam.h)
    # quasi-isotropic membrane stiffness
    assert np.isclose(lam.A11, lam.A22, rtol=1e-12)
    assert np.isclose(lam.A66, (lam.A11 - lam.A12)/2, rtol=1e-12)
    assert np.allclose([lam.A16, lam.A26], 0, atol=1e-12*lam.A11)
    # but not quasi-isotropic in bending: the +-45 plies give D16, D26
    assert abs(lam.D16) > 1e-3*lam.D11
    # equivalent membrane properties
    assert np.isclose(lam.e1, lam.e2, rtol=1e-12)
    assert np.isclose(lam.g12, lam.e1/(2*(1 + lam.nu12)), rtol=1e-12)
    # FSDT: transverse shear stiffness with the shear correction applied
    assert lam.shear_correction == 'rohwer'
    assert np.allclose(lam.Ats, lam.Ats.T)
    assert np.isclose(lam.scf_k13, lam.A55/lam.Abar55, rtol=1e-15)
    assert np.isclose(lam.scf_k23, lam.A44/lam.Abar44, rtol=1e-15)
    # mass per unit area
    assert np.isclose(lam.intrho, 1600.*lam.h, rtol=1e-12)

The matrices of all the theories of a laminate with three plies are compared with reference values in:

def test_laminated_plate_plane_stress():
    lamprop = (71e9, 7e9, 0.28, 7e9, 7e9, 7e9)
    stack = [0, 45, 90]
    plyt = 0.000125
    lam = laminated_plate(stack, plyt, lamprop)
    A = np.array([[ 13280892.30559593, 2198758.85719477, 2015579.57848837],
                  [  2198758.85719477,13280892.30559593, 2015579.57848837],
                  [  2015579.57848837, 2015579.57848837, 4083033.36210029]])
    B = np.array([[ -1.00778979e+03, 0.00000000e+00, 8.53496487e-15],
                  [  0.00000000e+00, 1.00778979e+03, 5.31743621e-14],
                  [  8.53496487e-15, 5.31743621e-14, 0.00000000e+00]])
    D = np.array([[ 0.1708233 , 0.01057886, 0.00262445],
                  [ 0.01057886, 0.1708233 , 0.00262445],
                  [ 0.00262445, 0.00262445, 0.0326602 ]])
    E = np.array([[-1.96833943e-05, 0.00000000e+00, 1.66698533e-22],
                  [0.00000000e+00, 1.96833943e-05, 1.03856176e-21],
                  [1.66698533e-22, 1.03856176e-21, 0.00000000e+00]])
    F = np.array([[3.63890059e-09, 1.87551265e-10, 6.15106073e-12],
                  [1.87551265e-10, 3.63890059e-09, 6.15106073e-12],
                  [6.15106073e-12, 6.15106073e-12, 6.53329570e-10]])
    H = np.array([[9.14779627e-17, 4.61039304e-18, 1.71625578e-20],
                  [4.61039304e-18, 9.14779627e-17, 1.71625578e-20],
                  [1.71625578e-20, 1.71625578e-20, 1.63068348e-17]])
    Abar_ts = np.array([[ 2625000.,       0.],
                        [       0., 2625000.]])
    Ats = np.array([[2014905.27266639, -27210.29377157],
                    [ -27210.29377157, 2014905.27266639]])
    Dts = np.array([[0.03076172, 0.],
                    [0., 0.03076172]])
    Fts = np.array([[6.48880005e-10, 0.00000000e+00],
                    [0.00000000e+00, 6.48880005e-10]])

    assert np.allclose(lam.A, A)
    assert np.allclose(lam.B, B)
    assert np.allclose(lam.D, D)
    assert np.allclose(lam.E, E)
    assert np.allclose(lam.F, F)
    assert np.allclose(lam.H, H)
    assert np.allclose(lam.Abar_ts, Abar_ts)
    assert np.allclose(lam.Ats, Ats)
    assert np.allclose(lam.Dts, Dts)
    assert np.allclose(lam.Fts, Fts)
    with pytest.warns(DeprecationWarning):
        lam.calc_scf()
    lam.calc_equivalent_properties()
    lp = lam.calc_lamination_parameters()
    matlamina = lam.plies[0].matlamina
    thickness = lam.h
    lam_2 = laminate_from_LaminationParameters(thickness, matlamina, lp)
    assert np.allclose(lam_2.A, lam.A)
    assert np.allclose(lam_2.B, lam.B)
    assert np.allclose(lam_2.D, lam.D)
    assert np.allclose(lam_2.Ats, lam.Abar_ts)

    lam.make_balanced()
    make_balanced_LP(lp)
    lam_2 = laminate_from_LaminationParameters(thickness, matlamina, lp)
    assert np.allclose(lam_2.A, lam.A)
    assert np.allclose(lam_2.B, lam.B)
    assert np.allclose(lam_2.D, lam.D)
    assert np.allclose(lam_2.Ats, lam.Abar_ts)

    lam.make_orthotropic()
    make_orthotropic_LP(lp)
    lam_2 = laminate_from_LaminationParameters(thickness, matlamina, lp)
    assert np.allclose(lam_2.A, lam.A)
    assert np.allclose(lam_2.B, lam.B)
    assert np.allclose(lam_2.D, lam.D)
    assert np.allclose(lam_2.Ats, lam.Abar_ts)

    lam = laminated_plate(stack, plyt, lamprop)
    lp = lam.calc_lamination_parameters()
    lam.make_symmetric()
    make_symmetric_LP(lp)
    lam_2 = laminate_from_LaminationParameters(thickness, matlamina, lp)
    assert np.allclose(lam_2.A, lam.A)
    assert np.allclose(lam_2.B, lam.B)
    assert np.allclose(lam_2.D, lam.D)
    assert np.allclose(lam_2.Ats, lam.Abar_ts)

    lam = laminated_plate(stack, plyt, lamprop)
    lp = lam.calc_lamination_parameters()
    lam.make_smeared()
    assert np.allclose(lam.D, lam.h**2/12*lam.A)
    assert np.allclose(lam.B, 0)