Cylindrical shells modeled as panel multidomain assemblies#

panels.multidomain.cylinder.create_cylinder(height, r, stack, plyt, laminaprop, npanels, m=8, n=8)#

Create a cylinder multidomain assembly

The multidomain assembly looks like:

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

where edges A and B are connected to close the cylinder.

Parameters:
heightfloat

Cylinder height (along \(x\)).

rfloat

Cylinder radius.

stacklist or tuple

Stacking sequence for the cylinder.

plytfloat

Ply thickness.

laminaproplist or tuple

Orthotropic lamina properties: \(E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}\).

npanelsint

The number of panels the cylinder perimiter.

m, nint, optional

Number of approximation terms for each panel.

Returns:
md, connstuple

A tuple containing the multidomain assembly and the default connectivity list of dictionaries.

Notes

The code of this function is illustrative of how it constructs the multidomain assembly:

def create_cylinder(height, r, stack, plyt, laminaprop,
        npanels, m=8, n=8):
    r"""Create a cylinder multidomain assembly

    The multidomain assembly looks like::


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

    where edges ``A`` and ``B`` are connected to close the cylinder.


    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
    -------
    md, conns : tuple
        A tuple containing the multidomain assembly and the default connectivity
        list of dictionaries.

    Notes
    -----
    The code of this function is illustrative of how it constructs the
    multidomain assembly:

    .. literalinclude:: ../../panels/multidomain/cylinder.py
        :pyobject: create_cylinder


    """
    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 = Shell(group='skin', x0=0, y0=y0, a=height, b=b_skin,
            r=r, m=m, n=n, plyt=plyt, stack=stack, laminaprop=laminaprop,
            x1u=0, x1ur=1, x2u=0, x2ur=1,
            x1v=0, x1vr=1, x2v=0, x2vr=1,
            x1w=0, x1wr=1, x2w=0, x2wr=1,
            y1u=1, y1ur=1, y2u=1, y2ur=1,
            y1v=1, y1vr=1, y2v=1, y2vr=1,
            y1w=1, y1wr=1, y2w=1, y2wr=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))
    md = MultiDomain(skin)

    return md, conns
panels.multidomain.cylinder.cylinder_compression_lb_Nxx_cte(height, r, stack, plyt, laminaprop, npanels, Nxxs, m=8, n=8, num_eigvalues=20)#

Linear buckling analysis with a constant Nxx for each panel

See create_cylinder() for most parameters.

The cylinder has SS1 at the bottom and SS3 at the top. SS3 means that the edge is free to move in the axial direction.

Parameters:
Nxxslist

A Nxx for each panel.

num_eigvaluesint

Number of eigenvalues to be extracted.

Returns:
md, eigvals, eigvecstuple

Assembly, eigenvalues and eigenvectors.

Examples

The following example is one of the test cases:

def test_cylinder_compression_lb_Nxx_cte():
    print('Testing assembly function: cylinder_compression_lb_Nxx_cte')
    height = 0.500
    r = 0.250
    npanels = 5
    Nxxs = [-100.]*npanels
    assy, eigvals, eigvecs = cylinder_compression_lb_Nxx_cte(
        height=height,
        r=r,
        plyt=0.125e-3,
        stack=[0, 45, -45, 90, -45, 45],
        laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9),
        npanels=npanels,
        Nxxs=Nxxs,
        m=8, n=12)

    assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_compression_lb_Nxx_cte.png')

    assert np.isclose(Nxxs[0]*eigvals[0], -47319.181, atol=0.01, rtol=0.001)
panels.multidomain.cylinder.cylinder_compression_lb_Nxx_from_static(height, r, stack, plyt, laminaprop, npanels, Nxxs, m=8, n=8, num_eigvalues=20)#

Linear buckling analysis with a Nxx calculated using static analysis

See create_cylinder() for most parameters.

The cylinder has SS1 at the bottom and SS3 at the top. SS3 means that the edge is free to move in the axial direction.

Parameters:
Nxxslist

A Nxx for each panel.

num_eigvaluesint

Number of eigenvalues to be extracted.

Returns:
md, c, eigvals, eigvecstuple

Assembly, static results, eigenvalues and eigenvectors.

Examples

The following example is one of the test cases:

def test_cylinder_compression_lb_Nxx_from_static():
    print('Testing assembly function: cylinder_compression_lb_Nxx_from_static')
    height = 0.500
    r = 0.250
    npanels = 5
    Nxxs = [-100.]*npanels
    assy, c, eigvals, eigvecs = cylinder_compression_lb_Nxx_from_static(
        height=height,
        r=r,
        plyt=0.125e-3,
        stack=[0, 45, -45, 90, -45, 45],
        laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9),
        npanels=npanels,
        Nxxs=Nxxs,
        m=8, n=12)

    assy.plot(c, 'skin', filename='tmp_cylinder_compression_lb_Nxx_from_static_c.png')
    assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_compression_lb_Nxx_from_static_eigvec.png')

    assert np.isclose(Nxxs[0]*eigvals[0], -47417.912, atol=0.01, rtol=0.001)
panels.multidomain.cylinder_blade_stiffened.create_cylinder_blade_stiffened(height, r, stack, stack_blades, width_blades, plyt, laminaprop, npanels, m=8, n=8)#

Create a cylinder multidomain assembly with blade stiffeners

The multidomain 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 close de cylinder.

Parameters:
heightfloat

Cylinder height (along \(x\)).

rfloat

Cylinder radius.

stackarray-like

Stacking sequence for the cylinder.

stack_bladeslist of array-like

The stacking sequence for each blade (with length = npanels).

width_bladesarray-like

The width for each blade (with length = npanels).

plytfloat

Ply thickness (assumed unique for the whole structure).

laminaproplist or tuple

Orthotropic lamina properties: \(E_1, E_2, \nu_{12}, G_{12}, G_{13}, G_{23}\).

npanelsint

The number of panels the cylinder perimiter.

m, nint, optional

Number of approximation terms for each panel.

Returns:
md, connstuple

A tuple containing the multidomain assembly and the default connectivity list of dictionaries.

Notes

The code of this function is illustrative of how it constructs the multidomain assembly:

def create_cylinder_blade_stiffened(height, r, stack, stack_blades,
        width_blades, plyt, laminaprop, npanels, m=8, n=8):
    r"""Create a cylinder multidomain assembly with blade stiffeners

    The multidomain 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 close de cylinder.


    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
    -------
    md, conns : tuple
        A tuple containing the multidomain assembly and the default connectivity
        list of dictionaries.

    Notes
    -----
    The code of this function is illustrative of how it constructs the
    multidomain assembly:

    .. literalinclude:: ../../panels/multidomain/cylinder_blade_stiffened.py
        :pyobject: create_cylinder_blade_stiffened

    """
    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 = Shell(group='skin', x0=0, y0=y0, a=height, b=b_skin,
                      r=r, m=m, n=n, plyt=plyt,
                      stack=stack, laminaprop=laminaprop,
                      x1u=0, x1ur=1, x2u=0, x2ur=1,
                      x1v=0, x1vr=1, x2v=0, x2vr=1,
                      x1w=0, x1wr=1, x2w=0, x2wr=1,
                      y1u=1, y1ur=1, y2u=1, y2ur=1,
                      y1v=1, y1vr=1, y2v=1, y2vr=1,
                      y1w=1, y1wr=1, y2w=1, y2wr=1)
        skin.append(panel)
    for i, panel in enumerate(skin):
        y0 = i*b_skin
        blade_name = 'blade_%02d' % i
        blade = Shell(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,
                      x1u=0, x1ur=1, x2u=0, x2ur=1,
                      x1v=0, x1vr=1, x2v=0, x2vr=1,
                      x1w=0, x1wr=1, x2w=0, x2wr=1,
                      y1u=1, y1ur=1, y2u=1, y2ur=1,
                      y1v=1, y1vr=1, y2v=1, y2vr=1,
                      y1w=1, y1wr=1, y2w=1, y2wr=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))

    md = MultiDomain(skin + blades)

    return md, conns
panels.multidomain.cylinder_blade_stiffened.cylinder_blade_stiffened_compression_lb_Nxx_cte(height, r, stack, stack_blades, width_blades, plyt, laminaprop, npanels, Nxxs_skin, Nxxs_blade, m=8, n=8, num_eigvalues=20)#

Linear buckling analysis with a constant Nxx for each panel

See create_cylinder_blade_stiffened() for most parameters.

Parameters:
Nxxs_skinlist

A Nxx for each skin panel.

Nxxs_bladelist

A Nxx for each blade stiffener.

num_eigvaluesint

Number of eigenvalues to be extracted.

Returns:
md, eigvals, eigvecstuple

Assembly, eigenvalues and eigenvectors.

Examples

The following example is one of the test cases:

def test_cylinder_blade_stiffened_compression_lb_Nxx_cte():
    print('Testing assembly function: cylinder_blade_stiffened_compression_lb_Nxx_cte')
    height = 0.500
    r = 0.250
    npanels = 5
    Nxxs = [-100.]*npanels
    assy, eigvals, eigvecs = cylinder_blade_stiffened_compression_lb_Nxx_cte(
        height=height,
        r=r,
        plyt=0.125e-3,
        stack=[0, 45, -45, 90, -45, 45],
        stack_blades=[[0, 90, 0]*4]*npanels,
        width_blades=[0.02]*npanels,
        laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9),
        npanels=npanels,
        Nxxs_skin=Nxxs,
        Nxxs_blade=Nxxs,
        m=8, n=12)

    assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_cte_eigvec.png')

    assert np.isclose(Nxxs[0]*eigvals[0], -51905.843, atol=0.01, rtol=0.001)
panels.multidomain.cylinder_blade_stiffened.cylinder_blade_stiffened_compression_lb_Nxx_from_static(height, r, stack, stack_blades, width_blades, plyt, laminaprop, npanels, Nxxs_skin, Nxxs_blade, m=8, n=8, num_eigvalues=20)#

Linear buckling analysis with a Nxx calculated using static analysis

See create_cylinder_blade_stiffened() for most parameters.

Parameters:
Nxxs_skinlist

A Nxx for each skin panel.

Nxxs_bladelist

A Nxx for each blade stiffener.

num_eigvaluesint

Number of eigenvalues to be extracted.

Returns:
md, c, eigvals, eigvecstuple

Assembly, static results, eigenvalues and eigenvectors.

Examples

The following example is one of the test cases:

def test_cylinder_blade_stiffened_compression_lb_Nxx_from_static():
    print('Testing assembly function: cylinder_blade_stiffened_compression_lb_Nxx_from_static')
    height = 0.500
    r = 0.250
    npanels = 5
    Nxxs = [-100.]*npanels
    assy, c, eigvals, eigvecs = cylinder_blade_stiffened_compression_lb_Nxx_from_static(
        height=height,
        r=r,
        plyt=0.125e-3,
        stack=[0, 45, -45, 90, -45, 45],
        stack_blades=[[0, 90, 0]*4]*npanels,
        width_blades=[0.02]*npanels,
        laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9),
        npanels=npanels,
        Nxxs_skin=Nxxs,
        Nxxs_blade=Nxxs,
        m=8, n=12)

    assy.plot(c, 'skin', vec='u', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_from_static_u.png', colorbar=True)
    assy.plot(c, 'skin', vec='w', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_from_static_w.png', colorbar=True)
    assy.plot(c, 'skin', vec='Nxx', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_from_static_Nxx.png', colorbar=True)
    assy.plot(c, 'skin', vec='Nyy', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_from_static_Nyy.png', colorbar=True)
    assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_blade_stiffened_compression_lb_Nxx_from_static_eigvec.png')

    assert np.isclose(Nxxs[0]*eigvals[0], -40003, atol=0.01, rtol=0.001)
panels.multidomain.cylinder_blade_stiffened.cylinder_blade_stiffened_compression_lb_pd_from_static(height, r, stack, stack_blades, width_blades, plyt, laminaprop, npanels, pds_skin, pds_blade, m=8, n=8, num_eigvalues=20, ku=1000000.0)#

Linear buckling analysis with prescribed displacement

See create_cylinder_blade_stiffened() for most parameters.

Parameters:
pds_skinlist

A prescribed axial compression displacement for each skin panel.

pds_bladelist

A prescribed axial compression displacement for each blade stiffener.

num_eigvaluesint

Number of eigenvalues to be extracted.

kufloat

Penalty stiffness used for prescribing displacements.

Returns:
md, c, eigvals, eigvecstuple

Assembly, static results, eigenvalues and eigenvectors.

Examples

The following example is one of the test cases:

def test_cylinder_blade_stiffened_compression_lb_pd_from_static():
    print('Testing assembly function: cylinder_blade_stiffened_compression_lb_pd_from_static')
    height = 0.500
    r = 0.250
    npanels = 5
    pds = [-1.e-3]*npanels
    assy, c, eigvals, eigvecs = cylinder_blade_stiffened_compression_lb_pd_from_static(
        height=height,
        r=r,
        plyt=0.125e-3,
        stack=[0, 45, -45, 90, -45, 45],
        stack_blades=[[0, 90, 0]*4]*npanels,
        width_blades=[0.02]*npanels,
        laminaprop=(142.5e9, 8.7e9, 0.28, 5.1e9, 5.1e9, 5.1e9),
        npanels=npanels,
        pds_skin=pds,
        pds_blade=pds,
        m=8, n=12)

    assy.plot(c, 'skin', vec='u', filename='tmp_cylinder_blade_stiffened_compression_lb_pd_from_static_u.png', colorbar=True)
    assy.plot(c, 'skin', vec='w', filename='tmp_cylinder_blade_stiffened_compression_lb_pd_from_static_w.png', colorbar=True)
    assy.plot(c, 'skin', vec='Nxx', filename='tmp_cylinder_blade_stiffened_compression_lb_pd_from_static_Nxx.png', colorbar=True)
    assy.plot(c, 'skin', vec='Nyy', filename='tmp_cylinder_blade_stiffened_compression_lb_pd_from_static_Nyy.png', colorbar=True)
    assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_blade_stiffened_compression_lb_pd_from_static_eigvec.png')