File size: 4,214 Bytes
8e5ba9e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
"""Thick-walled pressure vessel solvers using Lame equations.

Two configurations:
- Thick-walled cylinder under internal pressure
- Thick-walled sphere under internal pressure

These are exact analytical solutions for linear elastic, isotropic materials
under axisymmetric loading. The maximum stress occurs at the inner surface.

Reference: Boresi, A.P. & Schmidt, R.J., "Advanced Mechanics of Materials"
"""

import math
from typing import Any

from src.data.schema import SolutionResult
from src.data.solvers.base import AnalyticalSolver


class ThickCylinder(AnalyticalSolver):
    """Thick-walled cylinder under internal pressure p (Lame equations).

    Hoop stress at inner surface (maximum):
        sigma_h = p * (r_o^2 + r_i^2) / (r_o^2 - r_i^2)

    Radial stress at inner surface:
        sigma_r = -p  (compressive)

    Radial displacement at inner surface:
        u_r = (p * r_i / E) * [(1-nu)(r_i^2) + (1+nu)(r_o^2)] / (r_o^2 - r_i^2)

    Von Mises equivalent stress at inner surface (plane stress, open ends):
        sigma_vm = sqrt(sigma_h^2 + sigma_r^2 - sigma_h*sigma_r)
    """

    @property
    def config_id(self) -> str:
        return "vessel_cylinder"

    @property
    def problem_family(self) -> str:
        return "vessel"

    def solve(self, params: dict[str, Any]) -> SolutionResult:
        r_i = params["inner_radius"]
        r_o = params["outer_radius"]
        E = params["elastic_modulus"]
        nu = params["poisson_ratio"]
        sigma_y = params["yield_strength"]
        p = params["internal_pressure"]

        ri2 = r_i**2
        ro2 = r_o**2
        denom = ro2 - ri2

        # Stresses at inner surface (r = r_i)
        sigma_hoop = p * (ro2 + ri2) / denom
        sigma_radial = -p  # compressive

        # Von Mises equivalent stress (plane stress, open-ended cylinder)
        sigma_vm = math.sqrt(
            sigma_hoop**2 + sigma_radial**2 - sigma_hoop * sigma_radial
        )

        # Radial displacement at inner surface
        u_r = (p * r_i / E) * ((1.0 - nu) * ri2 + (1.0 + nu) * ro2) / denom

        return SolutionResult.from_stress(sigma_vm, abs(u_r), sigma_y)


class ThickSphere(AnalyticalSolver):
    """Thick-walled sphere under internal pressure p.

    Hoop stress at inner surface (maximum, equal in both tangential directions):
        sigma_h = p * r_i^3 * (r_o^3 + 2*r_i^3) / (2 * r_i^3 * (r_o^3 - r_i^3))

    Simplified:
        sigma_h = p * (r_o^3 + 2*r_i^3) / (2 * (r_o^3 - r_i^3))

    Radial stress at inner surface:
        sigma_r = -p

    Von Mises at inner surface (biaxial hoop stress):
        sigma_vm = sqrt(sigma_h^2 + sigma_h^2 - sigma_h*sigma_h + 3*0)
        For sigma_1 = sigma_2 = sigma_h, sigma_3 = sigma_r:
        sigma_vm = sqrt(sigma_h^2 - sigma_h*sigma_r + sigma_r^2)

    Radial displacement at inner surface:
        u_r = (p * r_i) / (2*E) * [(1-2nu)*r_i^3 + (1+nu)*r_o^3] / (r_o^3 - r_i^3)
    """

    @property
    def config_id(self) -> str:
        return "vessel_sphere"

    @property
    def problem_family(self) -> str:
        return "vessel"

    def solve(self, params: dict[str, Any]) -> SolutionResult:
        r_i = params["inner_radius"]
        r_o = params["outer_radius"]
        E = params["elastic_modulus"]
        nu = params["poisson_ratio"]
        sigma_y = params["yield_strength"]
        p = params["internal_pressure"]

        ri3 = r_i**3
        ro3 = r_o**3
        denom = ro3 - ri3

        # Stresses at inner surface
        sigma_hoop = p * (ro3 + 2.0 * ri3) / (2.0 * denom)
        sigma_radial = -p

        # Von Mises: two equal hoop stresses + radial
        # sigma_vm = sqrt(s1^2 + s2^2 + s3^2 - s1*s2 - s2*s3 - s1*s3)
        # with s1 = s2 = sigma_hoop, s3 = sigma_radial
        sigma_vm = math.sqrt(
            sigma_hoop**2 - sigma_hoop * sigma_radial + sigma_radial**2
        )

        # Radial displacement at inner surface
        u_r = (p * r_i / (2.0 * E)) * (
            (1.0 - 2.0 * nu) * ri3 + (1.0 + nu) * ro3
        ) / denom

        return SolutionResult.from_stress(sigma_vm, abs(u_r), sigma_y)


VESSEL_SOLVERS: dict[str, type[AnalyticalSolver]] = {
    "vessel_cylinder": ThickCylinder,
    "vessel_sphere": ThickSphere,
}