structural-analysis
4
总安装量
4
周安装量
#48495
全站排名
安装命令
npx skills add https://github.com/vamseeachanta/workspace-hub --skill structural-analysis
Agent 安装分布
opencode
4
gemini-cli
4
antigravity
4
github-copilot
4
codex
4
kimi-cli
4
Skill 文档
Structural Analysis Skill
Perform structural analysis for offshore and marine structures including stress calculations, buckling checks, and capacity verification.
Version Metadata
version: 1.0.0
python_min_version: '3.10'
compatibility:
tested_python:
- '3.10'
- '3.11'
- '3.12'
- '3.13'
os:
- Windows
- Linux
- macOS
Changelog
[1.0.0] – 2026-01-07
Added:
- Initial version metadata and dependency management
- Semantic versioning support
- Compatibility information for Python 3.10-3.13
Changed:
- Enhanced skill documentation structure
When to Use
- Von Mises stress calculations
- Plate buckling checks (DNV, API standards)
- Member capacity verification
- Combined loading assessment
- Weld strength verification
- Safety factor reporting
- Standards compliance documentation
Supported Standards
| Standard | Application |
|---|---|
| DNV-RP-C201 | Buckling strength of plated structures |
| DNV-RP-C202 | Buckling strength of shells |
| DNV-RP-C203 | Fatigue design |
| API RP 2A | Fixed offshore platforms |
| ISO 19902 | Fixed steel offshore structures |
| AISC 360 | Steel construction |
| Eurocode 3 | Steel structures |
Implementation Pattern
Stress Calculations
from dataclasses import dataclass
from typing import Dict, List, Optional, Tuple
import numpy as np
import logging
logger = logging.getLogger(__name__)
@dataclass
class StressState:
"""Complete stress state at a point."""
sigma_x: float = 0.0 # Normal stress in x direction (MPa)
sigma_y: float = 0.0 # Normal stress in y direction (MPa)
sigma_z: float = 0.0 # Normal stress in z direction (MPa)
tau_xy: float = 0.0 # Shear stress xy (MPa)
tau_xz: float = 0.0 # Shear stress xz (MPa)
tau_yz: float = 0.0 # Shear stress yz (MPa)
def von_mises(self) -> float:
"""Calculate Von Mises equivalent stress."""
return np.sqrt(
0.5 * (
(self.sigma_x - self.sigma_y)**2 +
(self.sigma_y - self.sigma_z)**2 +
(self.sigma_z - self.sigma_x)**2 +
6 * (self.tau_xy**2 + self.tau_xz**2 + self.tau_yz**2)
)
)
def principal_stresses(self) -> Tuple[float, float, float]:
"""Calculate principal stresses."""
# Build stress tensor
tensor = np.array([
[self.sigma_x, self.tau_xy, self.tau_xz],
[self.tau_xy, self.sigma_y, self.tau_yz],
[self.tau_xz, self.tau_yz, self.sigma_z]
])
# Eigenvalues are principal stresses
eigenvalues = np.linalg.eigvalsh(tensor)
return tuple(sorted(eigenvalues, reverse=True))
def max_shear(self) -> float:
"""Calculate maximum shear stress."""
s1, s2, s3 = self.principal_stresses()
return (s1 - s3) / 2
@dataclass
class MaterialProperties:
"""Material properties for structural analysis."""
yield_strength: float # MPa
ultimate_strength: float # MPa
youngs_modulus: float # MPa
poissons_ratio: float
density: float # kg/m³
name: str = "Steel"
# Common materials
STEEL_S355 = MaterialProperties(
yield_strength=355,
ultimate_strength=510,
youngs_modulus=210000,
poissons_ratio=0.3,
density=7850,
name="S355"
)
STEEL_S420 = MaterialProperties(
yield_strength=420,
ultimate_strength=520,
youngs_modulus=210000,
poissons_ratio=0.3,
density=7850,
name="S420"
)
class StressCalculator:
"""Calculate stresses in structural members."""
def __init__(self, material: MaterialProperties):
self.material = material
def beam_stress(
self,
axial_force: float,
moment_y: float,
moment_z: float,
area: float,
I_y: float,
I_z: float,
y: float,
z: float
) -> float:
"""
Calculate bending stress in a beam.
Args:
axial_force: Axial force (N)
moment_y: Moment about y-axis (N·m)
moment_z: Moment about z-axis (N·m)
area: Cross-sectional area (m²)
I_y: Moment of inertia about y (mâ´)
I_z: Moment of inertia about z (mâ´)
y: Distance from neutral axis in y (m)
z: Distance from neutral axis in z (m)
Returns:
Normal stress (MPa)
"""
sigma_axial = axial_force / area / 1e6 # Convert to MPa
sigma_bending_y = moment_y * z / I_y / 1e6
sigma_bending_z = moment_z * y / I_z / 1e6
return sigma_axial + sigma_bending_y + sigma_bending_z
def shear_stress(
self,
shear_force: float,
Q: float,
I: float,
t: float
) -> float:
"""
Calculate shear stress using VQ/It formula.
Args:
shear_force: Shear force (N)
Q: First moment of area (m³)
I: Moment of inertia (mâ´)
t: Thickness at section (m)
Returns:
Shear stress (MPa)
"""
return shear_force * Q / (I * t) / 1e6
def torsional_stress(
self,
torque: float,
r: float,
J: float
) -> float:
"""
Calculate torsional shear stress.
Args:
torque: Applied torque (N·m)
r: Radial distance from center (m)
J: Polar moment of inertia (mâ´)
Returns:
Shear stress (MPa)
"""
return torque * r / J / 1e6
def hoop_stress(
self,
pressure: float,
radius: float,
thickness: float
) -> float:
"""
Calculate hoop stress in thin-walled cylinder.
Args:
pressure: Internal pressure (MPa)
radius: Inner radius (m)
thickness: Wall thickness (m)
Returns:
Hoop stress (MPa)
"""
return pressure * radius / thickness
def longitudinal_stress(
self,
pressure: float,
radius: float,
thickness: float
) -> float:
"""
Calculate longitudinal stress in thin-walled cylinder.
Args:
pressure: Internal pressure (MPa)
radius: Inner radius (m)
thickness: Wall thickness (m)
Returns:
Longitudinal stress (MPa)
"""
return pressure * radius / (2 * thickness)
Buckling Analysis
@dataclass
class PlateGeometry:
"""Plate geometry for buckling analysis."""
length: float # a (mm)
width: float # b (mm)
thickness: float # t (mm)
@dataclass
class BucklingResult:
"""Results from buckling analysis."""
critical_stress: float # MPa
applied_stress: float # MPa
utilization: float
safety_factor: float
mode: str
passes: bool
class PlateBucklingAnalyzer:
"""
Plate buckling analysis per DNV-RP-C201.
"""
def __init__(self, material: MaterialProperties):
self.material = material
self.E = material.youngs_modulus
self.nu = material.poissons_ratio
self.fy = material.yield_strength
def elastic_buckling_stress(
self,
plate: PlateGeometry,
boundary_conditions: str = "simply_supported"
) -> float:
"""
Calculate elastic buckling stress.
Args:
plate: Plate geometry
boundary_conditions: Boundary condition type
Returns:
Elastic buckling stress (MPa)
"""
a = plate.length
b = plate.width
t = plate.thickness
# Aspect ratio
alpha = a / b
# Buckling coefficient (simply supported, uniform compression)
if alpha < 1:
k = (alpha + 1/alpha)**2
else:
k = 4.0
# Elastic buckling stress
sigma_e = k * np.pi**2 * self.E / (12 * (1 - self.nu**2)) * (t / b)**2
return sigma_e
def reduced_slenderness(
self,
plate: PlateGeometry
) -> float:
"""
Calculate reduced slenderness parameter.
Args:
plate: Plate geometry
Returns:
Reduced slenderness (lambda_p)
"""
sigma_e = self.elastic_buckling_stress(plate)
return np.sqrt(self.fy / sigma_e)
def johnson_ostenfeld(
self,
sigma_e: float
) -> float:
"""
Apply Johnson-Ostenfeld correction for inelastic buckling.
Args:
sigma_e: Elastic buckling stress
Returns:
Critical buckling stress
"""
if sigma_e <= 0.5 * self.fy:
return sigma_e
else:
return self.fy * (1 - self.fy / (4 * sigma_e))
def check_plate_buckling(
self,
plate: PlateGeometry,
sigma_x: float,
sigma_y: float = 0.0,
tau: float = 0.0,
gamma_m: float = 1.15
) -> BucklingResult:
"""
Check plate buckling under combined loading.
Args:
plate: Plate geometry
sigma_x: Compressive stress in x (MPa, positive = compression)
sigma_y: Compressive stress in y (MPa)
tau: Shear stress (MPa)
gamma_m: Material factor
Returns:
BucklingResult with utilization
"""
# Calculate individual buckling stresses
b = plate.width
t = plate.thickness
# Compressive buckling
sigma_e_x = self.elastic_buckling_stress(plate)
sigma_cr_x = self.johnson_ostenfeld(sigma_e_x)
# Shear buckling
k_tau = 5.34 + 4 * (b / plate.length)**2
tau_e = k_tau * np.pi**2 * self.E / (12 * (1 - self.nu**2)) * (t / b)**2
tau_cr = self.johnson_ostenfeld(tau_e)
# Combined check (interaction formula)
util_x = sigma_x / (sigma_cr_x / gamma_m) if sigma_cr_x > 0 else 0
util_tau = (tau / (tau_cr / gamma_m))**2 if tau_cr > 0 else 0
total_util = util_x + util_tau
return BucklingResult(
critical_stress=sigma_cr_x,
applied_stress=sigma_x,
utilization=total_util,
safety_factor=1 / total_util if total_util > 0 else float('inf'),
mode="plate_buckling",
passes=total_util <= 1.0
)
class ColumnBucklingAnalyzer:
"""
Column buckling analysis per Eurocode 3.
"""
def __init__(self, material: MaterialProperties):
self.material = material
self.E = material.youngs_modulus
self.fy = material.yield_strength
def euler_buckling_load(
self,
I: float,
L_eff: float
) -> float:
"""
Calculate Euler critical buckling load.
Args:
I: Moment of inertia (mmâ´)
L_eff: Effective length (mm)
Returns:
Critical load (N)
"""
return np.pi**2 * self.E * I / L_eff**2
def slenderness_ratio(
self,
L_eff: float,
r: float
) -> float:
"""
Calculate slenderness ratio.
Args:
L_eff: Effective length (mm)
r: Radius of gyration (mm)
Returns:
Slenderness ratio
"""
return L_eff / r
def reduction_factor(
self,
lambda_bar: float,
buckling_curve: str = "b"
) -> float:
"""
Calculate buckling reduction factor per EC3.
Args:
lambda_bar: Non-dimensional slenderness
buckling_curve: EC3 buckling curve (a0, a, b, c, d)
Returns:
Reduction factor chi
"""
# Imperfection factors
alpha_dict = {
"a0": 0.13,
"a": 0.21,
"b": 0.34,
"c": 0.49,
"d": 0.76
}
alpha = alpha_dict.get(buckling_curve, 0.34)
# Calculate reduction factor
phi = 0.5 * (1 + alpha * (lambda_bar - 0.2) + lambda_bar**2)
chi = 1 / (phi + np.sqrt(phi**2 - lambda_bar**2))
return min(chi, 1.0)
def check_column_buckling(
self,
axial_force: float,
area: float,
I_min: float,
L_eff: float,
buckling_curve: str = "b",
gamma_m: float = 1.0
) -> BucklingResult:
"""
Check column buckling capacity.
Args:
axial_force: Applied axial force (N)
area: Cross-sectional area (mm²)
I_min: Minimum moment of inertia (mmâ´)
L_eff: Effective length (mm)
buckling_curve: EC3 curve
gamma_m: Material factor
Returns:
BucklingResult
"""
# Calculate slenderness
r = np.sqrt(I_min / area)
lambda_1 = np.pi * np.sqrt(self.E / self.fy)
lambda_bar = (L_eff / r) / lambda_1
# Get reduction factor
chi = self.reduction_factor(lambda_bar, buckling_curve)
# Design capacity
N_cr = chi * area * self.fy / gamma_m
# Utilization
util = axial_force / N_cr if N_cr > 0 else float('inf')
return BucklingResult(
critical_stress=chi * self.fy / gamma_m,
applied_stress=axial_force / area,
utilization=util,
safety_factor=1 / util if util > 0 else float('inf'),
mode="column_buckling",
passes=util <= 1.0
)
Capacity Verification
@dataclass
class CapacityResult:
"""Results from capacity check."""
capacity: float
demand: float
utilization: float
governing_mode: str
passes: bool
details: Dict
class MemberCapacityChecker:
"""
Check member capacity for combined loading.
"""
def __init__(self, material: MaterialProperties):
self.material = material
self.stress_calc = StressCalculator(material)
self.plate_buckling = PlateBucklingAnalyzer(material)
self.column_buckling = ColumnBucklingAnalyzer(material)
def check_tension_member(
self,
axial_force: float,
area_gross: float,
area_net: float,
gamma_m0: float = 1.0,
gamma_m2: float = 1.25
) -> CapacityResult:
"""
Check tension capacity per EC3.
Args:
axial_force: Applied tension (N)
area_gross: Gross area (mm²)
area_net: Net area at connections (mm²)
gamma_m0: Material factor (yield)
gamma_m2: Material factor (ultimate)
Returns:
CapacityResult
"""
# Plastic capacity
N_pl = area_gross * self.material.yield_strength / gamma_m0
# Ultimate capacity at net section
N_u = 0.9 * area_net * self.material.ultimate_strength / gamma_m2
# Governing capacity
N_Rd = min(N_pl, N_u)
governing = "plastic" if N_pl <= N_u else "net_section"
util = axial_force / N_Rd if N_Rd > 0 else float('inf')
return CapacityResult(
capacity=N_Rd,
demand=axial_force,
utilization=util,
governing_mode=governing,
passes=util <= 1.0,
details={'N_pl': N_pl, 'N_u': N_u}
)
def check_combined_loading(
self,
N: float,
M_y: float,
M_z: float,
area: float,
W_pl_y: float,
W_pl_z: float,
N_cr_y: float,
N_cr_z: float,
gamma_m1: float = 1.0
) -> CapacityResult:
"""
Check member under combined axial and bending.
Args:
N: Axial force (N, positive = compression)
M_y: Moment about y-axis (N·mm)
M_z: Moment about z-axis (N·mm)
area: Cross-sectional area (mm²)
W_pl_y: Plastic section modulus y (mm³)
W_pl_z: Plastic section modulus z (mm³)
N_cr_y: Critical buckling load y (N)
N_cr_z: Critical buckling load z (N)
gamma_m1: Material factor
Returns:
CapacityResult
"""
fy = self.material.yield_strength
# Capacities
N_Rk = area * fy
M_y_Rk = W_pl_y * fy
M_z_Rk = W_pl_z * fy
# Reduction factors
chi_y = N_cr_y / N_Rk if N_Rk > 0 else 1.0
chi_z = N_cr_z / N_Rk if N_Rk > 0 else 1.0
chi = min(chi_y, chi_z, 1.0)
# Interaction check (simplified)
util_N = N / (chi * N_Rk / gamma_m1) if N > 0 else 0
util_My = M_y / (M_y_Rk / gamma_m1)
util_Mz = M_z / (M_z_Rk / gamma_m1)
# Combined utilization (simplified linear)
util_combined = util_N + util_My + util_Mz
return CapacityResult(
capacity=chi * N_Rk / gamma_m1,
demand=N,
utilization=util_combined,
governing_mode="combined",
passes=util_combined <= 1.0,
details={
'util_N': util_N,
'util_My': util_My,
'util_Mz': util_Mz
}
)
YAML Configuration
# config/structural_analysis.yaml
material:
name: S355
yield_strength: 355 # MPa
ultimate_strength: 510
youngs_modulus: 210000
poissons_ratio: 0.3
plates:
- id: bottom_plate
length: 2000
width: 1000
thickness: 20
loading:
sigma_x: 150
sigma_y: 0
tau: 30
- id: side_plate
length: 3000
width: 1500
thickness: 16
loading:
sigma_x: 200
sigma_y: 50
tau: 40
columns:
- id: leg_1
area: 15000 # mm²
I_min: 5.0e7 # mmâ´
L_eff: 8000 # mm
buckling_curve: b
axial_force: 2500000 # N
safety_factors:
gamma_m0: 1.0
gamma_m1: 1.0
gamma_m2: 1.25
output:
report_path: reports/structural_analysis.html
include_plots: true
Usage Examples
Stress Analysis
from structural_analysis import StressState, StressCalculator, STEEL_S355
# Create stress state
stress = StressState(
sigma_x=150.0,
sigma_y=50.0,
tau_xy=30.0
)
# Calculate Von Mises
vm = stress.von_mises()
print(f"Von Mises stress: {vm:.1f} MPa")
# Check against yield
sf = STEEL_S355.yield_strength / vm
print(f"Safety factor: {sf:.2f}")
Buckling Check
from structural_analysis import (
PlateBucklingAnalyzer, PlateGeometry, STEEL_S355
)
analyzer = PlateBucklingAnalyzer(STEEL_S355)
plate = PlateGeometry(
length=2000,
width=1000,
thickness=20
)
result = analyzer.check_plate_buckling(
plate=plate,
sigma_x=150,
tau=30,
gamma_m=1.15
)
print(f"Utilization: {result.utilization:.2%}")
print(f"Status: {'PASS' if result.passes else 'FAIL'}")
Combined Capacity Check
from structural_analysis import MemberCapacityChecker, STEEL_S355
checker = MemberCapacityChecker(STEEL_S355)
result = checker.check_combined_loading(
N=2500000, # N
M_y=500e6, # N·mm
M_z=200e6, # N·mm
area=15000,
W_pl_y=2.5e6,
W_pl_z=1.5e6,
N_cr_y=8e6,
N_cr_z=6e6
)
print(f"Combined utilization: {result.utilization:.2%}")
Best Practices
Analysis Approach
- Start with simple hand calculations
- Verify FEA results with analytical methods
- Check all load combinations
- Include manufacturing tolerances
Safety Factors
- Use code-specified factors
- Document any deviations
- Consider consequence of failure
- Account for inspection limitations
Documentation
- Clearly state assumptions
- Reference applicable standards
- Show detailed calculations
- Include sensitivity checks
Pipeline Wall Thickness & M-T Interaction Assessment
Supported Pipeline/Riser Codes
| Standard | Application | M-T Method |
|---|---|---|
| API RP 1111 | Offshore hydrocarbon pipelines | Von Mises equivalent stress |
| API STD 2RD | Dynamic risers for FPS | 4 methods (limit load, angle-based, DNV-equivalent, API-equivalent) |
| DNV-ST-F101 | Submarine pipeline systems | Local buckling (load-controlled & displacement-controlled) |
| DNV-OS-F201 | Dynamic risers | Combined loading criteria |
| PD 8010-2 | Subsea pipelines | Von Mises + buckling |
Report Structure for Pipeline Assessment
Engineers expect results first, inputs last:
- Executive Summary â PASS/FAIL, governing check, margin, recommendations
- Pressure-Only Checks â burst, collapse, propagation (prerequisites)
- Combined Loading Contour â Von Mises utilisation heatmap across T-M plane
- Allowable Bending Envelope â capacity curves per operating condition
- Capacity Limits Table â T+, T-, M_allow per condition
- Pressure Sensitivity â parametric study at varying internal pressure
- Key Points Summary â utilisation at selected reference points
- Input Data â geometry, material, design basis (appendix / collapsible)
What a Structural Engineer Looks For
- Clear PASS/FAIL verdict at the top with governing check identified
- Pressure-only checks first â if any fail, M-T analysis is moot
- Combined loading interaction diagram showing the design space
- Allowable envelopes overlaid with design operating points
- Margin quantification â not just pass/fail, but how much margin
- Code clause references for every check performed
- Input data traceability â can the reviewer reproduce the results?
- Consistency checks â do T_y and M_p match hand calculations?
- Units clearly stated in every table header and axis label
Review Checklist
Input Validation
- D/t ratio in valid range (15-45 typical for offshore pipe; <15 is thick-walled, >50 very thin)
- SMYS matches grade (X42:290, X52:359, X56:386, X60:414, X65:448, X70:483, X80:552 MPa)
- SMTS > SMYS (ratio typically 1.08-1.20 for carbon steel)
- Corrosion allowance reasonable (0-6 mm for 20+ year design life)
- Young’s modulus ~207 GPa, Poisson’s ratio ~0.3 for steel
Section Property Sanity
- A = pi/4 * (OD^2 – ID^2)
- I = pi/64 * (OD^4 – ID^4)
- Z = I / (OD/2) for elastic section modulus
- T_y = A * SMYS
- M_p per code (API RP 1111 uses SMYS * (D^3 – d_i^3) / 6)
Pressure Check Sanity
- Hoop utilisation sigma_h / SMYS < 0.50 typical; >0.60 is concerning
- If hoop utilisation > f_d * SMYS, pipe cannot satisfy combined check at any T,M
- Burst: P_b = 0.45 * (SMYS + SMTS) * ln(OD/ID)
- Propagation: P_pr = 24 * SMYS * (t/OD)^2.4
Combined Loading Sanity
- At origin (T=0, M=0), utilisation = sigma_h / sigma_allow (pressure-only baseline)
- Envelopes properly nested: Survival > Extreme > Installation > Normal Operating
- T_pos > |T_neg| when net internal pressure positive (hoop stress asymmetry)
- M_allow decreases monotonically past peak as |T| increases
Red Flags
- D/t < 15: Very thick-walled; thin-wall hoop formula may be inaccurate, consider Lame’s equation
- D/t > 50: Very thin-walled; susceptible to local buckling and ovality
- Hoop utilisation > 80%: Very little capacity for tension and bending
- Propagation util > 0.8: May need buckle arrestors
- Envelope curves crossing: Calculation error (nested property violated)
- Utilisation at origin > 1.0: Pressure alone exceeds capacity â fundamental design issue
API RP 1111 Design Factors
| Condition | f_d | Application |
|---|---|---|
| Normal Operating | 0.72 | Production, steady-state |
| Installation | 0.80 | Lay operations, pre-commissioning |
| Extreme | 0.96 | 100-year environmental |
| Survival | 1.00 | Abnormal / accidental |
API STD 2RD vs API RP 1111
| Aspect | API RP 1111 (Pipelines) | API STD 2RD (Risers) |
|---|---|---|
| Design philosophy | Limit state (WSD) | LRFD |
| Combined loading | Von Mises equivalent stress | 4 methods available |
| Stress components | Hoop + longitudinal (2D) | Full triaxial (3D) |
| Yield exceedance | Not permitted | Permitted for displacement-controlled |
| Additional checks | â | Fatigue, VIV, dynamic amplification |
Typical Follow-Up Analyses After M-T Interaction
- On-bottom stability (lateral/vertical under hydrodynamic loading)
- Free-span analysis (VIV and static bending at unsupported spans)
- Installation analysis (lay tension vs bending during S-lay/J-lay/reel-lay)
- Lateral buckling and walking under thermal/pressure cycling
- Fatigue at girth welds (especially for dynamic risers)
- Fracture mechanics / ECA per BS 7910
- Upheaval buckling for buried pipelines
- Tie-in spool M-T interaction at connections
- Riser touch-down zone combined loading (risers only)
Key Source Files
src/digitalmodel/structural/analysis/wall_thickness.pyâ Core dataclasses and analyzersrc/digitalmodel/structural/analysis/wall_thickness_mt_report.pyâ M-T interaction reportsrc/digitalmodel/structural/analysis/wall_thickness_codes.pyâ Code strategy registrytests/test_wall_thickness_mt_report.pyâ 13 tests covering envelope, bisection, asymmetry
Related Skills
- fatigue-analysis – Fatigue assessment
- mooring-design – Mooring structures
- viv-analysis – Vortex-induced vibration
- catenary-riser – Riser configuration analysis