Cylinders modeled as multi-domain assemblies#
A MultiDomain assembly connects Shell domains, see
panels.multidomain.connections. The function
create_cylinder() creates a cylinder with panels along its
circumference, connecting the last panel to the first one to close the
cylinder.
The connections are imposed exactly with the default
conn_method='null-space', see Exact connections with the null-space method, or with penalty
stiffnesses with conn_method='penalty'. The closed cylinder below gives
-47113.0 N/m with the null-space method and -47056.0 N/m with the default
penalty constants, see tests/multidomain/test_null_space.py and
tests/multidomain/test_cylinder.py.
Linear buckling with a constant axial compression Nxx in each panel,
calculated with cylinder_compression_lb_Nxx_cte():
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,
num_eigvalues=10, conn_method='penalty')
assy.plot(eigvecs[:, 0], 'skin', filename='tmp_cylinder_compression_lb_Nxx_cte.png')
#NOTE Sanders kinematics, the default for cylinders, the Donnell
# kinematics gave -47319.181
assert np.isclose(Nxxs[0]*eigvals[0], -47055.984, atol=0.01, rtol=0.001)
Linear buckling with the pre-buckling stress state calculated from a static
analysis, with cylinder_compression_lb_Nxx_from_static():
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,
num_eigvalues=10, conn_method='penalty')
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')
#NOTE Sanders kinematics, the default for cylinders, the Donnell
# kinematics gave -47417.912
assert np.isclose(Nxxs[0]*eigvals[0], -47162.406, atol=0.01, rtol=0.001)
Blade stiffeners can be added along the length of the cylinder, modeled as
additional domains connected to the skin, see
create_cylinder_blade_stiffened():
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,
num_eigvalues=10, conn_method='penalty')
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')
#NOTE Sanders kinematics, the default for cylinders, the Donnell
# kinematics gave -40003, and -39921.838 with the rotation of
# 'BFycte' without the term v/r of the Sanders kinematics
assert np.isclose(Nxxs[0]*eigvals[0], -39993.838, atol=0.01, rtol=0.001)