ANYmaterial 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. anymaterial-0.1.0/CHANGELOG.md +191 -0
  2. anymaterial-0.1.0/LICENSE +674 -0
  3. anymaterial-0.1.0/MANIFEST.in +8 -0
  4. anymaterial-0.1.0/MIGRATION.md +94 -0
  5. anymaterial-0.1.0/PKG-INFO +273 -0
  6. anymaterial-0.1.0/README.md +245 -0
  7. anymaterial-0.1.0/RELEASING.md +97 -0
  8. anymaterial-0.1.0/docs/ARCHITECTURE.md +69 -0
  9. anymaterial-0.1.0/pyproject.toml +68 -0
  10. anymaterial-0.1.0/setup.cfg +4 -0
  11. anymaterial-0.1.0/src/ANYmaterial.egg-info/PKG-INFO +273 -0
  12. anymaterial-0.1.0/src/ANYmaterial.egg-info/SOURCES.txt +39 -0
  13. anymaterial-0.1.0/src/ANYmaterial.egg-info/dependency_links.txt +1 -0
  14. anymaterial-0.1.0/src/ANYmaterial.egg-info/entry_points.txt +5 -0
  15. anymaterial-0.1.0/src/ANYmaterial.egg-info/requires.txt +8 -0
  16. anymaterial-0.1.0/src/ANYmaterial.egg-info/top_level.txt +1 -0
  17. anymaterial-0.1.0/src/anymaterial/__init__.py +135 -0
  18. anymaterial-0.1.0/src/anymaterial/__main__.py +351 -0
  19. anymaterial-0.1.0/src/anymaterial/contract.py +127 -0
  20. anymaterial-0.1.0/src/anymaterial/curves.py +323 -0
  21. anymaterial-0.1.0/src/anymaterial/data/dnv_rp_c208.json +41 -0
  22. anymaterial-0.1.0/src/anymaterial/data/materials.json +490 -0
  23. anymaterial-0.1.0/src/anymaterial/gui.py +747 -0
  24. anymaterial-0.1.0/src/anymaterial/isotropic.py +76 -0
  25. anymaterial-0.1.0/src/anymaterial/library.py +550 -0
  26. anymaterial-0.1.0/src/anymaterial/orthotropic.py +94 -0
  27. anymaterial-0.1.0/src/anymaterial/plot.py +218 -0
  28. anymaterial-0.1.0/src/anymaterial/reductions.py +125 -0
  29. anymaterial-0.1.0/src/anymaterial/spec.py +321 -0
  30. anymaterial-0.1.0/src/anymaterial/validation.py +171 -0
  31. anymaterial-0.1.0/src/anymaterial/yield_criteria.py +286 -0
  32. anymaterial-0.1.0/tests/conftest.py +42 -0
  33. anymaterial-0.1.0/tests/test_cli.py +292 -0
  34. anymaterial-0.1.0/tests/test_contract.py +283 -0
  35. anymaterial-0.1.0/tests/test_curves.py +291 -0
  36. anymaterial-0.1.0/tests/test_gui.py +326 -0
  37. anymaterial-0.1.0/tests/test_layering.py +104 -0
  38. anymaterial-0.1.0/tests/test_library.py +430 -0
  39. anymaterial-0.1.0/tests/test_packaging.py +81 -0
  40. anymaterial-0.1.0/tests/test_plot.py +149 -0
  41. anymaterial-0.1.0/tests/test_spec.py +194 -0
@@ -0,0 +1,191 @@
1
+ # Changelog
2
+
3
+ ## Unreleased
4
+
5
+ No changes yet.
6
+
7
+ ## 0.1.0 - 2026-08-20
8
+
9
+ First public feature release. The material code is extracted from ANYsolver and
10
+ ANYfem; see [MIGRATION.md](MIGRATION.md) for provenance.
11
+
12
+ Added:
13
+
14
+ - **Embeddable material selection.** `MaterialEditor(on_apply=...)` adds a
15
+ **Use material** button, and `open_material_editor` opens the same validated
16
+ editor inside an application's existing Tk event loop.
17
+ - **A material library.** `library()` returns 33 named materials, including the
18
+ 17 DNV-RP-C208 grade and thickness-class rows, curated cited entries, and
19
+ measured campaign means. `MaterialLibrary` supports `get`, `find` (by category, status,
20
+ text or whether it has a curve), `add`, `remove` and JSON round-tripping;
21
+ `LibraryEntry` carries the category, the standard, the source and free notes.
22
+ - **Provenance as a first-class field.** Every entry has a `status`:
23
+ `tabulated` for a standard's own table, `indicative` for a typical published
24
+ figure that is **not a design value**, `user` for anything added at runtime.
25
+ `LibraryEntry.is_design_value` exposes the distinction, and the CLI and the
26
+ editor both surface it.
27
+ - **User-extensible.** `add_to_user_library` writes to
28
+ `~/.anymaterial/materials.json`, or wherever `ANYMATERIAL_LIBRARY` points. A
29
+ user entry with the same name as a shipped one takes precedence, which is how a
30
+ grade gets corrected locally without editing the package. Anything added is
31
+ recorded as `status="user"` even if it claims otherwise, so adding cannot
32
+ launder provenance.
33
+ - **Curve plots as SVG.** `anymaterial.plot` renders flow curves without a
34
+ plotting dependency — hand-written SVG, so the output goes into a report or a
35
+ commit as text. `sample_curve`, `curve_svg` and `write_curve_svg`.
36
+ - **CLI** gained `library` (list and filter), `plot` (write an SVG) and `add`
37
+ (put a material in the user library).
38
+ - **Editor** gained a library pane: browse and filter on the left, load an entry
39
+ into the form, see the selected entry's provenance, and plot the edited
40
+ material against the library selection. Buttons add the current material to the
41
+ library and export the plotted curves to SVG.
42
+
43
+ **The shipped library is 33 materials.** It grew from 19 with a supplied
44
+ candidate set, then shrank again when the citations were checked: seven entries
45
+ were removed because their cited source does not support their numbers.
46
+
47
+ **One composite is back, properly sourced.** `IM7/8552 UD lamina, RTD (measured
48
+ mean)` uses room-temperature-dry campaign means from the
49
+ [NCAMP/NIAR Hexcel 8552 IM7 unidirectional qualification programme](https://www.wichita.edu/industry_and_defense/NIAR/Research/hexcel8552.php),
50
+ generated under FAA oversight — E1 23.51 Msi, E2 1.30 Msi, G12 0.68 Msi,
51
+ nu12 0.316, read from data report CAM-RP-2009-015 Rev A sections 2.3.1/2.3.2/2.3.5
52
+ with the environmental column resolved as RTD (70 °F, dry). The remaining five
53
+ constants are **not measured**: E3, nu13 and G13 follow from assumed transverse
54
+ isotropy, nu23 is assumed 0.45 outright, and G23 follows exactly from those. The
55
+ `calculation` record says which is which. Internal check: nu21 by reciprocity is
56
+ 0.0175 against the programme's separately measured transverse-compression nu21 of
57
+ 0.024. It carries no yield stress and defines no failure criterion.
58
+
59
+ Added `run_gui.py` at the repository root — an entry point for an IDE's Run
60
+ button that puts `src` on `sys.path` first, so the editor opens from a bare
61
+ checkout with nothing installed, and what runs is the working tree rather than an
62
+ installed copy. There is a test that executes it.
63
+
64
+ Added a new status, **`measured`**, and six entries under it from the
65
+ [Zenodo coupon database](https://doi.org/10.5281/zenodo.6965147) (Hartloper,
66
+ Ozden, de Castro e Sousa & Lignos 2022, v1.0.0, **CC-BY-4.0**): S235/275 JR+AR
67
+ 15 mm plate, S355 J2+N 15 mm plate, S355 J2+M IPE270 flange, S460 NL 25 mm plate,
68
+ S690 QL 12 mm plate and A992 Gr.50 W14X82 flange. Each is the mean of a named
69
+ campaign and carries its coupon count, the coefficient of variation on both yield
70
+ and modulus, the product form, the campaign citekey, the licence and the full
71
+ citation.
72
+
73
+ A `measured` entry is **not** a design value and says so loudly: the measured
74
+ mean yield of S355 is 412 MPa against 357 MPa tabulated, so using a mean as a
75
+ design strength is unconservative. `LibraryEntry` refuses `status="measured"`
76
+ without a measurement record — a measured value without its sample size and
77
+ scatter is a number claiming an authority it cannot show.
78
+
79
+ Removed, each after checking the cited source:
80
+
81
+ | Entry | Why |
82
+ | --- | --- |
83
+ | T300/5208 UD lamina | cited NASA report is *Space Radiation Effects on Graphite-Epoxy* and covers T300/**934** |
84
+ | E-glass/epoxy UD lamina | cited NASA report is *Thermal expansion properties of composite materials* |
85
+ | IM7/8552 UD lamina | the entry's own notes admitted the citation does not source its elastic constants |
86
+ | Norway spruce | Poisson ratios 0.37/0.47/0.44 are the Wood Handbook's **Sitka** spruce row, and the moduli match neither species |
87
+ | Titanium Grade 2 | cited TIMET datasheet URL returns HTTP 404 |
88
+ | Ti-6Al-4V Grade 5 | cited TIMET datasheet URL returns HTTP 404 |
89
+ | EN AW-6082-T6 extrusion | cited hydro.com URL returns HTTP 404, and a verified 6082-T6 entry already ships |
90
+
91
+ Re-sourced rather than removed:
92
+
93
+ - **EN AW-5083-H116** — dead hydro.com link replaced; the 215 MPa proof is
94
+ confirmed as the EN 485-2 minimum for the temper.
95
+ - **AA 6061-T6, AA 7075-T6** — no longer cite a licensed table as if it were the
96
+ source; the notes now say plainly that these are widely corroborated typical
97
+ values and that the authoritative minimums are elsewhere.
98
+ - **The three nonlinear stainless/duplex curves** — the notes now separate what
99
+ the source supports (the Ramberg-Osgood form per EN 1993-1-4 Annex C, and the
100
+ fy/fu inputs) from what was computed here (the tabulated points).
101
+
102
+ Everything that survived was validated before merging: it builds, its compliance
103
+ is symmetric and positive definite, and every flow curve is finite, monotonic and
104
+ has a non-negative hardening modulus.
105
+
106
+ - `LibraryEntry` gained **`calculation`** (how a derived entry was derived — the
107
+ Ramberg-Osgood exponent behind a tabulated curve) and **`measurement`** (coupon
108
+ count, scatter, campaign, licence, citation). Without the first, the candidate
109
+ set's derivation records would have been silently dropped on import.
110
+ - A test now fails the build if any shipped entry lacks a source, a standard or
111
+ notes.
112
+ - `anymaterial library` prints only the warning matching the statuses actually
113
+ listed, so it stays worth reading, and takes `--status measured`. The choices
114
+ are derived from the library's own status list so the two cannot drift.
115
+ - `anymaterial library` sizes its name column to the content, because a fixed
116
+ width truncated the longer alloy names into ambiguity.
117
+
118
+ The first two curated materials were added from sources found online. Their
119
+ numbers are attributed in `data/materials.json` and marked `indicative`:
120
+
121
+ - **EN AW-6082-T6** — E 70 GPa, 0.2% proof 310 MPa, tensile 340 MPa, density
122
+ 2700 kg/m³, from the thyssenkrupp datasheet. That datasheet does not separate
123
+ tempers, and EN 1999-1-1 characteristic values for design are lower and depend
124
+ on product form and thickness; the entry says so.
125
+ - **EN 1.4404 (316L)** — E 200 GPa and density 8000 kg/m³ from the thyssenkrupp
126
+ datasheet, 0.2% proof 220 MPa and tensile 500 MPa as commonly quoted for the
127
+ grade under EN 10088-3.
128
+
129
+ Neither carries a hardening curve, because no citable source for one was found.
130
+ Nothing was invented to fill the gap: an aluminium entry (EN AW-5083-H111) was
131
+ prepared and then dropped when both candidate sources returned HTTP 403 and the
132
+ numbers could not be verified.
133
+
134
+ ### Initial package foundation
135
+
136
+ Added:
137
+
138
+ - **Contract** — `StructuralMaterial` protocol, `ENGINEERING_VOIGT_ORDER`,
139
+ symmetry resolution and `elastic_compliance_matrix`. Structural rather than
140
+ inheritance-based, so a material defined in another package satisfies it
141
+ without importing anything from here.
142
+ - **Materials** — `IsotropicMaterial` and `OrthotropicMaterial`, both validated
143
+ on construction.
144
+ - **Reductions** — `shell_material_matrices`, `beam_material_properties` and
145
+ `shell_characteristic_modulus`, all derived from the 6x6 compliance so
146
+ isotropic and orthotropic materials reach a formulation by the same path.
147
+ - **Yield** — `Hill48Yield` plus free functions `hill48_strengths`,
148
+ `hill48_coefficients` and `hill48_equivalent_stress` that consume the
149
+ six-strength protocol by attribute lookup.
150
+ - **Curves** — the `HardeningCurve` protocol and four implementations:
151
+ `LinearHardeningCurve`, `PiecewiseLinearCurve`, `PowerLawHardeningCurve` and
152
+ the ported `DNVC208MaterialCurve`. The first three are new.
153
+ - **Library** — `steel()`, `available_grades()`, `thickness_classes()`,
154
+ `dnv_c208_steel_properties()` and `dnv_c208_steel_curve()`. The RP-C208 grade
155
+ table now lives in `data/dnv_rp_c208.json` instead of in code.
156
+ - **Specifications** — `MaterialSpec`, which records *how to rebuild* a
157
+ hardening curve rather than a frozen copy, so a saved material does not reload
158
+ as elastic. `hardening_descriptor` raises for a curve it cannot describe rather
159
+ than serializing it away.
160
+ - **Editor** — a tkinter form with live validation and a flow-curve plot on a
161
+ plain `Canvas`, entry point `anymaterial-gui`.
162
+ - **CLI** — `anymaterial grades|properties|curve|show|validate`, each with
163
+ `--json`.
164
+
165
+ Verified bit-exact against `anysolver` 0.1.3 at
166
+ `8b4553cc680ff925df850e627165fc336615eaba` for the full RP-C208 table (17 rows),
167
+ the flow stress and hardening modulus of every resulting curve, isotropic and
168
+ orthotropic compliance, all three reductions, the Hill-48 coefficients,
169
+ quadratic form, utilization and equivalent stress, and the exact wording of
170
+ every validation message.
171
+
172
+ Deliberate differences from the source, both to be confirmed when ANYsolver is
173
+ stripped:
174
+
175
+ - `IsotropicMaterial` validates on construction. `anysolver.fe_core.Material`
176
+ does not, so a caller that built a material with an inadmissible Poisson ratio
177
+ and never used it would now fail at construction instead of at first use.
178
+ - Ramberg-Osgood is not implemented. It has no distinct yield point, so as a
179
+ flow curve its stress tends to zero as plastic strain does, which a return
180
+ mapping cannot use; the usual repairs produce a different curve while keeping
181
+ the name. `PowerLawHardeningCurve.from_yield` covers the same behaviour with an
182
+ explicit yield stress.
183
+
184
+ Not included, and staying in ANYsolver: `FiberSectionPlasticityConfig` (a solver
185
+ fiber grid, not a material) and all section properties.
186
+
187
+ ## 0.0.1
188
+
189
+ - Repository scaffolding: packaging metadata, CI across Python 3.11-3.14 on
190
+ Windows and Linux, and the layering checks that keep the package a leaf of the
191
+ dependency graph.