add structure plate

This commit is contained in:
2026-01-11 18:24:42 +01:00
parent 1f9ebe926f
commit 710506b4aa
2 changed files with 200 additions and 37 deletions

View File

@@ -1,18 +1,23 @@
"""Structure :py:class:`beam` and :py:class:`tube` objects. """Structure :py:class:`Beam` and :py:class:`Tube` objects.
""" """
import numpy as np import numpy as np
class beam: class Beam:
"""Euler-Bernoulli beam. r"""Euler-Bernoulli beam.
""" """
def __init__(self, E, I, A, L, rho):
""" def __init__(self, E: float, I: float, A: float, L: float, rho: float):
r"""
Args: Args:
E: Elastic modulus / Young's modulus E: Elastic modulus / Young's modulus
I: Second moment of area of the beam's cross-section I: Second moment of area of the beam's cross-section
A: Cross-section A: Cross-section
L: Length L: Length
rho: Density rho: Density
.. math::
I = \frac{h^3}{12}
""" """
self.E = E self.E = E
self.I = I self.I = I
@@ -21,20 +26,20 @@ class beam:
self.rho = rho self.rho = rho
@property @property
def V(self): def V(self) -> float:
return self.A * self.L return self.A * self.L
@property @property
def mu(self): def mu(self) -> float:
"""Mass per unit length (or the product of density and cross-section)""" """Mass per unit length (or the product of density and cross-section)"""
return self.rho * self.A return self.rho * self.A
@property @property
def m(self): def m(self) -> float:
return self.mu * self.L return self.mu * self.L
# return self.rho * self.V # return self.rho * self.V
def eigenfrequency(self, n:int, support : str = 'fixed-free') -> float: def eigenfrequency(self, n: int, support: str = 'fixed-free') -> float:
r"""Natural frequencies of the beam. r"""Natural frequencies of the beam.
Args: Args:
@@ -104,19 +109,18 @@ class beam:
f_n = \frac{a_n^2}{2\pi}\sqrt{\frac{E\,I}{\mu}} f_n = \frac{a_n^2}{2\pi}\sqrt{\frac{E\,I}{\mu}}
""" """
a_nLopi = [0.596864, 1.49418, 2.50025, 3.49999] a2_n = [0.596864, 1.49418, 2.50025, 3.49999] # a_n*L/pi
a_n = a_nLopi[n-1]*np.pi/self.L if n < len(a_nLopi) else 0 a_n = a2_n[n - 1] * np.pi / self.L if n < len(a2_n) else 0
return a_n**2*np.sqrt(self.E*self.I/self.mu)/(2*np.pi) return a_n**2 * np.sqrt(self.E * self.I / self.mu) / (2 * np.pi)
class tube: class TubeBuckling:
r"""Long thin circular tube uniformly loaded with external pressure. r"""Long thin circular tube uniformly loaded with external pressure.
Elemental ring of unit width (h) Elemental ring of unit width (h)
IMPORTANT: Can be used as long as the corresponding compressive stress does Important:
not exeed the proportional limit of the material. Can be used as long as the corresponding compressive stress does not exeed
the proportional limit of the material.
:math:`I = \frac{h^3}{12}`
References: References:
- Timoshenko, Stephen P., and James M. Gere. 1961. Theory of Elastic - Timoshenko, Stephen P., and James M. Gere. 1961. Theory of Elastic
@@ -124,7 +128,9 @@ class tube:
""" """
def __init__(self, E, nu, r, *, h=None, q=None, s=None): def __init__(
self, E: float, nu: float, r: float, *, h: float | None = None,
q: float | None = None, s: float | None = None):
r""" r"""
Args: Args:
E: Young's modulus E: Young's modulus
@@ -137,11 +143,14 @@ class tube:
self.E = E self.E = E
self.nu = nu self.nu = nu
self.r = r self.r = r
if (h or q or s):
pass
self.h = h self.h = h
self.s = s self.s = s
self.q = q self.q = q
def buckling_force(self): def force(self) -> float:
r"""Critical buckling value of the compressive force. r"""Critical buckling value of the compressive force.
A long circular tube uniformly compressed by external pressure. A long circular tube uniformly compressed by external pressure.
@@ -155,9 +164,11 @@ class tube:
Stability. 2nd ed. New York: McGraw-Hill Book. p. 289. Stability. 2nd ed. New York: McGraw-Hill Book. p. 289.
""" """
if self.h is None:
raise ValueError("h is not defined.")
return (self.E * self.h**3) / (4 * (1 - self.nu**2) * self.r**2) return (self.E * self.h**3) / (4 * (1 - self.nu**2) * self.r**2)
def buckling_pressure(self): def pressure(self) -> float:
r"""Critical buckling value of the compressive pressure. r"""Critical buckling value of the compressive pressure.
A long circular tube uniformly compressed by external pressure. A long circular tube uniformly compressed by external pressure.
@@ -175,9 +186,11 @@ class tube:
Stability. 2nd ed. New York: McGraw-Hill Book. p. 289. Stability. 2nd ed. New York: McGraw-Hill Book. p. 289.
""" """
if self.h is None:
raise ValueError("h is not defined.")
return self.E / (4 * (1 - self.nu**2)) * (self.h / self.r)**3 return self.E / (4 * (1 - self.nu**2)) * (self.h / self.r)**3
def buckling_stress(self): def stress(self) -> float:
r"""Critical buckling stress of a long thin circular tube uniformly r"""Critical buckling stress of a long thin circular tube uniformly
compressed by pressure. compressed by pressure.
@@ -194,36 +207,153 @@ class tube:
Stability. 2nd ed. New York: McGraw-Hill Book. p. 293. Stability. 2nd ed. New York: McGraw-Hill Book. p. 293.
""" """
if self.h is None:
raise ValueError("h is not defined.")
return self.E / (1 - self.nu**2) * (self.h / (2 * self.r))**2 return self.E / (1 - self.nu**2) * (self.h / (2 * self.r))**2
def buckling_thickness(self) -> float|None: def thickness(self) -> float | None:
r"""Critical buckling thickness of a long thin circular tube uniformly r"""Critical buckling thickness of a long thin circular tube uniformly
compressed by external pressure. compressed by external pressure.
Returns: Returns:
- Thickness regarding the internal stress, if stress is given - Thickness regarding the internal stress, if stress is given
.. math::
h_{\text{cr,}\sigma} = \sqrt{\sigma_\text{cr} \frac{1 - \nu^2}{E}} {2r}
- Thickness regarding the external pressure, if pressure is given - Thickness regarding the external pressure, if pressure is given
- Otherwise given thickness
- Or None
.. math:: See also:
:py:meth:`buckling_thickness_pressure` and
:py:meth:`buckling_thickness_stress`
h_\text{cr,q} = \left(q_\text{cr} \, 4 \frac{1 - \nu^2}{E}\right)^\frac{1}{3} {r} """
if self.s is not None:
return self.thickness_stress()
if self.q is not None:
return self.thickness_pressure()
if self.h is not None:
return self.h
return None
- Otherwise given thickness or None def thickness_pressure(self) -> float:
r"""Critical buckling thickness of a long thin circular tube uniformly
compressed by external pressure.
Thickness regarding the external pressure
.. math::
h_\text{cr,q} = \left(q_\text{cr} \, 4
\frac{1 - \nu^2}{E}\right)^\frac{1}{3} {r}
References: References:
- Timoshenko, Stephen P., and James M. Gere. 1961. Theory of Elastic - Timoshenko, Stephen P., and James M. Gere. 1961. Theory of Elastic
Stability. 2nd ed. New York: McGraw-Hill Book. p. 293. Stability. 2nd ed. New York: McGraw-Hill Book. p. 293.
""" """
if self.scr is not None: if self.q is None:
return np.sqrt(self.s * (1 - self.nu**2) / self.E) * (2 * self.r) raise ValueError("q is not defined.")
if self.qcr is not None: return np.power(self.q * 4 * (1 - self.nu**2) / self.E, 1 / 3) * self.r
return np.power(self.q * 4 * (1 - self.nu**2) / self.E, 1/3) * self.r
if self.h is not None: def thickness_stress(self) -> float:
return self.h r"""Critical buckling thickness of a long thin circular tube uniformly
compressed by external pressure.
Thickness regarding the internal stress
.. math::
h_{\text{cr,}\sigma} = \sqrt{\sigma_\text{cr} \frac{1 - \nu^2}{E}} {2r}
References:
- Timoshenko, Stephen P., and James M. Gere. 1961. Theory of Elastic
Stability. 2nd ed. New York: McGraw-Hill Book. p. 293.
"""
if self.s is None:
raise ValueError("s is not defined.")
return np.sqrt(self.s * (1 - self.nu**2) / self.E) * (2 * self.r)
class Plate:
r"""Thin circular plate uniformly loaded with external pressure.
Important:
Can be used as long as the corresponding stress does not exeed the
proportional limit of the material.
References:
- Timoshenko, Stephen P., and S. Woinowsky-Krieger. 1959. Theory of Plates
and Shells. 2nd ed. New York: McGraw-Hill Book.
"""
def __init__(self, E: float, nu: float, ra: float, h: float):
"""
Args:
E: Elastic modulus / Young's modulus
nu: Poisson's ratio
ra: radius
h: thickness
"""
self.E = E
self.nu = nu
self.ra = ra
self.h = h
@property
def D(self) -> float:
r"""Flexural rigidity of the plate.
.. math::
D = \frac{E\,h^3}{12(1-\nu^2)}
"""
return self.E * self.h**3 / (12 * (1 - self.nu**2))
def deflection(self, q, support: str = 'clamped') -> float | None:
r"""Central deflection of a clamped supported circular plate.
Args:
q: external pressure
support: clamped, simple
See also:
:py:meth:`deflection_clamped` and :py:meth:`deflection_simple`
"""
if support == 'clamped':
return self.deflection_clamped(q)
elif support == 'simple':
return self.deflection_simple(q)
return None return None
def deflection_clamped(self, q) -> float:
r"""Central deflection of a clamped supported circular plate.
Args:
q: external pressure
.. math::
w_\text{max} = \frac{q \, r_\text{a}^4}{64D}
References:
- Timoshenko, Stephen P., and S. Woinowsky-Krieger. 1959. Theory of Plates
and Shells. 2nd ed. New York: McGraw-Hill Book. p. 55.
"""
return q * self.ra**4 / (64 * self.D)
def deflection_simple(self, q) -> float:
r"""Central deflection of a simple/pinned supported circular plate.
Args:
q: external pressure
.. math::
w_\text{max} = \frac{q \, r_\text{a}^4}{64D} \frac{5+\nu}{1+\nu}
References:
- Timoshenko, Stephen P., and S. Woinowsky-Krieger. 1959. Theory of Plates
and Shells. 2nd ed. New York: McGraw-Hill Book. p. 57.
"""
return q * self.ra**4 / (64 * self.D) * (5 + self.nu) / (1 + self.nu)

View File

@@ -6,15 +6,48 @@ import fvr.structure
class TestStructureBeam(unittest.TestCase): class TestStructureBeam(unittest.TestCase):
def setUp(self): def setUp(self):
self.obj = fvr.structure.beam(1, 2, 3, 4, 5) self.obj = fvr.structure.Beam(1, 2, 3, 4, 5)
def test_volume(self): def test_volume(self):
self.assertEqual(self.obj.V, 12, 'incorrect volume after creation') self.assertEqual(self.obj.V, 12, 'incorrect volume after creation')
def test_volume_a(self): def test_volume_a(self):
self.obj.A = 6 self.obj.A = 6
self.assertEqual(self.obj.V, 24, 'incorrect volume after changing A') self.assertEqual(self.obj.V, 24, 'incorrect volume after changing A')
def test_volume_l(self): def test_volume_l(self):
self.obj.L = 7 self.obj.L = 7
self.assertEqual(self.obj.V, 21, 'incorrect volume after changing L') self.assertEqual(self.obj.V, 21, 'incorrect volume after changing L')
def test_mu(self):
self.assertEqual(self.obj.mu, 15, 'incorrect specific mass after creation')
def test_m(self):
self.assertEqual(self.obj.m, 60, 'incorrect mass after creation')
def test_eigenfrequency(self):
self.assertEqual(
self.obj.eigenfrequency(1), 0.012770856732837836,
'incorrect eigen-frequency after creation')
class TestStructureTubeBuckling(unittest.TestCase):
def setUp(self):
self.obj = fvr.structure.TubeBuckling(1, 0.2, 3, h=4)
def test_force(self):
self.assertEqual(
self.obj.force(), 1.8518518518518516,
'incorrect buckling force after creation')
def test_pressure(self):
self.assertEqual(
self.obj.pressure(), 0.6172839506172838,
'incorrect buckling force after creation')
def test_stress(self):
self.assertEqual(
self.obj.stress(), 0.46296296296296297,
'incorrect buckling force after creation')
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()