File size: 2,175 Bytes
efeed27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Material definitions for origami simulation.

Provides dataclass-based material properties and preset materials
for paper, mylar, aluminum, and nitinol.
"""

from dataclasses import dataclass


@dataclass
class Material:
    name: str
    thickness_mm: float       # mm
    youngs_modulus_gpa: float  # GPa
    max_strain: float          # fraction (e.g. 0.03 = 3%)
    poissons_ratio: float = 0.3  # dimensionless

    @property
    def thickness_m(self) -> float:
        """Thickness in meters."""
        return self.thickness_mm / 1000.0

    @property
    def youngs_modulus_pa(self) -> float:
        """Young's modulus in Pascals."""
        return self.youngs_modulus_gpa * 1e9


# ── Preset materials ────────────────────────────────────────────────

MATERIAL_PRESETS: dict[str, Material] = {
    "paper": Material(
        name="paper",
        thickness_mm=0.1,
        youngs_modulus_gpa=2.0,
        max_strain=0.03,
        poissons_ratio=0.3,
    ),
    "mylar": Material(
        name="mylar",
        thickness_mm=0.05,
        youngs_modulus_gpa=4.0,
        max_strain=0.03,
        poissons_ratio=0.38,
    ),
    "aluminum": Material(
        name="aluminum",
        thickness_mm=0.1,
        youngs_modulus_gpa=69.0,
        max_strain=0.01,
        poissons_ratio=0.33,
    ),
    "nitinol": Material(
        name="nitinol",
        thickness_mm=0.1,
        youngs_modulus_gpa=75.0,
        max_strain=0.08,
        poissons_ratio=0.33,
    ),
}


def get_material(name: str) -> Material:
    """Return a copy of a preset material by name.

    Raises KeyError if name is not in MATERIAL_PRESETS.
    """
    if name not in MATERIAL_PRESETS:
        available = ", ".join(sorted(MATERIAL_PRESETS))
        raise KeyError(f"Unknown material '{name}'. Available: {available}")
    preset = MATERIAL_PRESETS[name]
    return Material(
        name=preset.name,
        thickness_mm=preset.thickness_mm,
        youngs_modulus_gpa=preset.youngs_modulus_gpa,
        max_strain=preset.max_strain,
        poissons_ratio=preset.poissons_ratio,
    )