metafold 0.12.dev3__tar.gz → 0.12.dev5__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.
- {metafold-0.12.dev3 → metafold-0.12.dev5}/PKG-INFO +1 -1
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/simulation/compression_simulation.py +8 -4
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/simulation/run_experiment.py +14 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold.egg-info/PKG-INFO +1 -1
- {metafold-0.12.dev3 → metafold-0.12.dev5}/pyproject.toml +1 -1
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_compression_simulation.py +14 -12
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_run_experiment.py +12 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/LICENSE +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/README.md +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/__init__.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/api.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/assets.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/auth.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/client.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/exceptions.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/jobs.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/materials.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/projects.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/simulation/__init__.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/simulation/compression_experiment.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/utils.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold/workflows.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold.egg-info/SOURCES.txt +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold.egg-info/dependency_links.txt +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold.egg-info/requires.txt +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/metafold.egg-info/top_level.txt +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/setup.cfg +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_assets.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_compession_experiment.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_jobs.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_projects.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_shear_simulation.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_utils.py +0 -0
- {metafold-0.12.dev3 → metafold-0.12.dev5}/tests/test_workflows.py +0 -0
|
@@ -589,8 +589,12 @@ class CompressionSimulation:
|
|
|
589
589
|
cancelled = []
|
|
590
590
|
for state in ("pending", "started"):
|
|
591
591
|
for wf in client.workflows.list(q=f"state:{state}", project_id=project_id):
|
|
592
|
-
|
|
593
|
-
|
|
592
|
+
try:
|
|
593
|
+
client.workflows.cancel(wf.id, project_id=project_id)
|
|
594
|
+
cancelled.append(wf.id)
|
|
595
|
+
except HTTPError:
|
|
596
|
+
# Workflow already finished/uncancellable — ignore and move on.
|
|
597
|
+
pass
|
|
594
598
|
return cancelled
|
|
595
599
|
|
|
596
600
|
@staticmethod
|
|
@@ -887,10 +891,10 @@ class CompressionSimulation:
|
|
|
887
891
|
grid_min = np.minimum(grid_min, pmin)
|
|
888
892
|
grid_max = np.maximum(grid_max, pmax)
|
|
889
893
|
|
|
890
|
-
# Apply margins after all parts included
|
|
894
|
+
# Apply margins after all parts are included. Note z- gets no margin
|
|
895
|
+
# since the bottom of the grid is the support boundary the stack sits on
|
|
891
896
|
grid_min[:2] -= self.simulation_parameters.margin_xy
|
|
892
897
|
grid_max[:2] += self.simulation_parameters.margin_xy
|
|
893
|
-
grid_min[2] -= self.simulation_parameters.margin_z
|
|
894
898
|
grid_max[2] += self.simulation_parameters.margin_z
|
|
895
899
|
|
|
896
900
|
grid_size = grid_max - grid_min
|
|
@@ -18,6 +18,8 @@ JSON manifest format
|
|
|
18
18
|
"parts": [
|
|
19
19
|
{
|
|
20
20
|
"type": "piston_cylinder",
|
|
21
|
+
# optional geometry - omit to use default
|
|
22
|
+
"shape_parameters": {"top": [...], "bottom": [...], "radius": 0.02},
|
|
21
23
|
"velocity": [ # optional — defaults to DEFAULT_PISTON_VELOCITY
|
|
22
24
|
[0.0, 0, 0, 0.0],
|
|
23
25
|
[0.002, 0, 0, -1.25],
|
|
@@ -26,6 +28,7 @@ JSON manifest format
|
|
|
26
28
|
[0.04, 0, 0, 0.0]
|
|
27
29
|
]
|
|
28
30
|
},
|
|
31
|
+
{"type": "piston_box", "shape_parameters": {"min": [...], "max": [...]}},
|
|
29
32
|
{"type": "piston_mesh", "file": "piston.ply", "velocity": [...]},
|
|
30
33
|
{
|
|
31
34
|
"type": "mesh",
|
|
@@ -132,6 +135,7 @@ from metafold.simulation.compression_simulation import (
|
|
|
132
135
|
CompressionSimulation,
|
|
133
136
|
ExperimentMesh,
|
|
134
137
|
ExperimentPart,
|
|
138
|
+
ExperimentPistonBox,
|
|
135
139
|
ExperimentPistonCylinder,
|
|
136
140
|
ExperimentPistonMesh,
|
|
137
141
|
SimulationParameters,
|
|
@@ -171,8 +175,18 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
|
|
|
171
175
|
kwargs = {}
|
|
172
176
|
if "velocity" in entry:
|
|
173
177
|
kwargs["velocity"] = entry["velocity"]
|
|
178
|
+
if "shape_parameters" in entry:
|
|
179
|
+
kwargs["shape_parameters"] = entry["shape_parameters"]
|
|
174
180
|
parts.append(ExperimentPistonCylinder(**kwargs))
|
|
175
181
|
|
|
182
|
+
elif part_type == "piston_box":
|
|
183
|
+
kwargs = {}
|
|
184
|
+
if "velocity" in entry:
|
|
185
|
+
kwargs["velocity"] = entry["velocity"]
|
|
186
|
+
if "shape_parameters" in entry:
|
|
187
|
+
kwargs["shape_parameters"] = entry["shape_parameters"]
|
|
188
|
+
parts.append(ExperimentPistonBox(**kwargs))
|
|
189
|
+
|
|
176
190
|
elif part_type == "piston_mesh":
|
|
177
191
|
kwargs = {"filename": entry["file"]}
|
|
178
192
|
if "velocity" in entry:
|
|
@@ -277,21 +277,23 @@ class TestGridBounds:
|
|
|
277
277
|
}
|
|
278
278
|
self._prepare(sim, patches)
|
|
279
279
|
lower, _ = self._grid_bounds(sim)
|
|
280
|
-
|
|
281
|
-
#
|
|
282
|
-
assert lower[2] == pytest.approx(-0.05
|
|
283
|
-
|
|
284
|
-
def
|
|
285
|
-
#
|
|
286
|
-
# flush
|
|
287
|
-
|
|
280
|
+
# grid bottom (metres) = outsole bottom (-50 mm = -0.05 m), flush — the
|
|
281
|
+
# z- face is the support boundary and gets NO margin.
|
|
282
|
+
assert lower[2] == pytest.approx(-0.05, abs=1e-6)
|
|
283
|
+
|
|
284
|
+
def test_bottom_is_flush_no_margin(self, sim):
|
|
285
|
+
# The z- face is the support boundary the stack reacts against, so it
|
|
286
|
+
# must sit flush with the lowest part — adding margin there leaves the
|
|
287
|
+
# stack unsupported and it sags under the piston before compressing.
|
|
288
|
+
flat = {"size": [100.0, 100.0, 50.0], "offset": [0.0, 0.0, 0.0], "resolution": [32, 32, 16]}
|
|
288
289
|
self._prepare(sim, {n: flat for n in
|
|
289
290
|
["piston", "upper_foam", "midsole", "outsole"]})
|
|
290
|
-
lower,
|
|
291
|
+
lower, upper = self._grid_bounds(sim)
|
|
291
292
|
mz = sim.simulation_parameters.margin_z
|
|
292
|
-
# Lowest part bottom is z=0
|
|
293
|
-
|
|
294
|
-
|
|
293
|
+
# Lowest part bottom is z=0 -> grid bottom is exactly 0 (no margin).
|
|
294
|
+
assert lower[2] == pytest.approx(0.0, abs=1e-6)
|
|
295
|
+
# Top (z+, above the piston) still gets clearance.
|
|
296
|
+
assert upper[2] > 0.05 + mz - 1e-6
|
|
295
297
|
|
|
296
298
|
|
|
297
299
|
class TestSampleAssets:
|
|
@@ -16,6 +16,7 @@ from metafold.materials import (
|
|
|
16
16
|
)
|
|
17
17
|
from metafold.simulation.compression_simulation import (
|
|
18
18
|
ExperimentMesh,
|
|
19
|
+
ExperimentPistonBox,
|
|
19
20
|
ExperimentPistonCylinder,
|
|
20
21
|
ExperimentPistonMesh,
|
|
21
22
|
SimulationParameters,
|
|
@@ -92,6 +93,17 @@ class TestBuildParts:
|
|
|
92
93
|
parts = _build_parts([{"type": "piston_cylinder"}])
|
|
93
94
|
assert parts[0].velocity == DEFAULT_PISTON_VELOCITY
|
|
94
95
|
|
|
96
|
+
def test_piston_cylinder_with_shape_parameters(self):
|
|
97
|
+
shape = {"top": [0, 0, 0.01], "bottom": [0, 0, 0.012], "radius": 0.015}
|
|
98
|
+
parts = _build_parts([{"type": "piston_cylinder", "shape_parameters": shape}])
|
|
99
|
+
assert parts[0].shape_parameters == shape
|
|
100
|
+
|
|
101
|
+
def test_piston_box(self):
|
|
102
|
+
shape = {"min": [0, 0, 0.01], "max": [0.02, 0.02, 0.012]}
|
|
103
|
+
parts = _build_parts([{"type": "piston_box", "shape_parameters": shape}])
|
|
104
|
+
assert isinstance(parts[0], ExperimentPistonBox)
|
|
105
|
+
assert parts[0].shape_parameters == shape
|
|
106
|
+
|
|
95
107
|
def test_piston_mesh(self):
|
|
96
108
|
parts = _build_parts([{"type": "piston_mesh", "file": "piston.ply"}])
|
|
97
109
|
assert isinstance(parts[0], ExperimentPistonMesh)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|