Spaces:
Sleeping
Sleeping
File size: 6,398 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 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 | """Data schemas for structural mechanics dataset.
Pydantic models enforce type safety and validation across the entire pipeline.
All quantities use SI units (meters, Pascals, Newtons).
"""
from enum import Enum
from typing import Optional
from pydantic import BaseModel, Field, field_validator
class ProblemFamily(str, Enum):
BEAM = "beam"
PLATE = "plate"
VESSEL = "vessel"
class BeamConfig(str, Enum):
SS_POINT = "beam_ss_point"
SS_UDL = "beam_ss_udl"
CANTILEVER_POINT = "beam_cantilever_point"
CANTILEVER_UDL = "beam_cantilever_udl"
FIXED_POINT = "beam_fixed_point"
FIXED_UDL = "beam_fixed_udl"
class PlateConfig(str, Enum):
SS_UNIFORM = "plate_ss_uniform"
FIXED_UNIFORM = "plate_fixed_uniform"
class VesselConfig(str, Enum):
CYLINDER = "vessel_cylinder"
SPHERE = "vessel_sphere"
class SafetyCategory(str, Enum):
SAFE = "safe" # SF >= 2.0
MARGINAL = "marginal" # 1.0 <= SF < 2.0
FAILURE = "failure" # SF < 1.0
class MaterialProperties(BaseModel):
"""Material properties in SI units."""
elastic_modulus: float = Field(..., gt=0, description="Young's modulus E [Pa]")
poisson_ratio: float = Field(..., gt=0, lt=0.5, description="Poisson's ratio nu [-]")
yield_strength: float = Field(..., gt=0, description="Yield strength sigma_y [Pa]")
density: float = Field(..., gt=0, description="Density rho [kg/m^3]")
class BeamParameters(BaseModel):
"""Input parameters for Euler-Bernoulli beam analysis."""
length: float = Field(..., gt=0, description="Beam span L [m]")
width: float = Field(..., gt=0, description="Cross-section width b [m]")
height: float = Field(..., gt=0, description="Cross-section height h [m]")
material: MaterialProperties
point_load: float = Field(default=0.0, ge=0, description="Point load P [N]")
distributed_load: float = Field(default=0.0, ge=0, description="Distributed load w [N/m]")
@property
def moment_of_inertia(self) -> float:
"""Second moment of area I = bh^3/12 [m^4]."""
return self.width * self.height**3 / 12.0
@property
def section_modulus(self) -> float:
"""Section modulus S = bh^2/6 [m^3]."""
return self.width * self.height**2 / 6.0
@property
def cross_section_area(self) -> float:
"""Cross-section area A = bh [m^2]."""
return self.width * self.height
class PlateParameters(BaseModel):
"""Input parameters for Kirchhoff-Love plate analysis."""
length_a: float = Field(..., gt=0, description="Plate dimension a [m]")
length_b: float = Field(..., gt=0, description="Plate dimension b [m]")
thickness: float = Field(..., gt=0, description="Plate thickness t [m]")
material: MaterialProperties
pressure: float = Field(..., gt=0, description="Uniform pressure q [Pa]")
@property
def flexural_rigidity(self) -> float:
"""Flexural rigidity D = Et^3 / (12(1 - nu^2)) [N*m]."""
E = self.material.elastic_modulus
nu = self.material.poisson_ratio
t = self.thickness
return E * t**3 / (12.0 * (1.0 - nu**2))
@property
def aspect_ratio(self) -> float:
"""Aspect ratio a/b [-]."""
return self.length_a / self.length_b
class VesselParameters(BaseModel):
"""Input parameters for thick-walled pressure vessel analysis (Lame equations)."""
inner_radius: float = Field(..., gt=0, description="Inner radius r_i [m]")
outer_radius: float = Field(..., gt=0, description="Outer radius r_o [m]")
length: Optional[float] = Field(default=None, gt=0, description="Cylinder length L [m]")
material: MaterialProperties
internal_pressure: float = Field(..., gt=0, description="Internal pressure p [Pa]")
@field_validator("outer_radius")
@classmethod
def outer_must_exceed_inner(cls, v: float, info: dict) -> float:
if "inner_radius" in info.data and v <= info.data["inner_radius"]:
raise ValueError("outer_radius must be greater than inner_radius")
return v
@property
def radius_ratio(self) -> float:
"""Radius ratio r_o/r_i [-]."""
return self.outer_radius / self.inner_radius
@property
def wall_thickness(self) -> float:
"""Wall thickness t = r_o - r_i [m]."""
return self.outer_radius - self.inner_radius
class SolutionResult(BaseModel):
"""Output from an analytical solver."""
max_stress: float = Field(..., ge=0, description="Maximum stress [Pa]")
max_deflection: float = Field(..., ge=0, description="Maximum deflection [m]")
safety_factor: float = Field(..., ge=0, description="Safety factor = sigma_y / max_stress [-]")
safety_category: SafetyCategory
@classmethod
def from_stress(cls, max_stress: float, max_deflection: float, yield_strength: float) -> "SolutionResult":
"""Construct result and auto-classify safety category."""
sf = yield_strength / max_stress if max_stress > 0 else float("inf")
if sf >= 2.0:
category = SafetyCategory.SAFE
elif sf >= 1.0:
category = SafetyCategory.MARGINAL
else:
category = SafetyCategory.FAILURE
return cls(
max_stress=max_stress,
max_deflection=abs(max_deflection),
safety_factor=sf,
safety_category=category,
)
class DatasetSample(BaseModel):
"""A single row in the dataset. Flat structure for Parquet compatibility."""
sample_id: str
problem_family: ProblemFamily
config_id: str
# Geometry (SI: meters)
length: float
width: Optional[float] = None
height: Optional[float] = None
inner_radius: Optional[float] = None
outer_radius: Optional[float] = None
thickness: Optional[float] = None # plate thickness
# Material (SI)
elastic_modulus: float
poisson_ratio: float
yield_strength: float
density: float
# Loading (SI)
point_load: float = 0.0
distributed_load: float = 0.0
internal_pressure: float = 0.0
pressure: float = 0.0 # plate uniform pressure
# Derived geometry
moment_of_inertia: Optional[float] = None
section_modulus: Optional[float] = None
cross_section_area: Optional[float] = None
# Outputs
max_stress: float
max_deflection: float
safety_factor: float
safety_category: SafetyCategory
|