metafold 0.13.dev1__tar.gz → 0.13.dev3__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.13.dev1 → metafold-0.13.dev3}/PKG-INFO +1 -1
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/compression_experiment.py +5 -3
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/compression_simulation.py +4 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/run_experiment.py +9 -11
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/PKG-INFO +1 -1
- {metafold-0.13.dev1 → metafold-0.13.dev3}/pyproject.toml +1 -1
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_compession_experiment.py +6 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_run_experiment.py +12 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/LICENSE +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/README.md +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/__init__.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/api.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/assets.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/auth.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/client.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/exceptions.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/jobs.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/materials.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/projects.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/simulation/__init__.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/utils.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold/workflows.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/SOURCES.txt +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/dependency_links.txt +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/requires.txt +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/metafold.egg-info/top_level.txt +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/setup.cfg +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_assets.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_compression_simulation.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_jobs.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_materials.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_projects.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_shear_simulation.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_utils.py +0 -0
- {metafold-0.13.dev1 → metafold-0.13.dev3}/tests/test_workflows.py +0 -0
|
@@ -206,15 +206,17 @@ class CompressionExperiment:
|
|
|
206
206
|
return custom or f"{self.base_simulation.simulation_name}_sim{sim_index}"
|
|
207
207
|
|
|
208
208
|
def _validate_simulation_names(self):
|
|
209
|
-
"""Names must be a list of path-safe strings
|
|
210
|
-
name per sim (they become filenames
|
|
209
|
+
"""Names must be a list of path-safe strings (None or "" = use the
|
|
210
|
+
auto name) and resolve to a unique name per sim (they become filenames
|
|
211
|
+
and zip member paths)."""
|
|
211
212
|
if not isinstance(self.simulation_names, list) or not all(
|
|
212
|
-
isinstance(n, str) for n in self.simulation_names
|
|
213
|
+
n is None or isinstance(n, str) for n in self.simulation_names
|
|
213
214
|
):
|
|
214
215
|
raise ValueError(
|
|
215
216
|
f"simulation_names must be a list of strings, got: "
|
|
216
217
|
f"{self.simulation_names!r}"
|
|
217
218
|
)
|
|
219
|
+
self.simulation_names = [n or "" for n in self.simulation_names]
|
|
218
220
|
for name in self.simulation_names:
|
|
219
221
|
if any(c in name for c in "/\\:"):
|
|
220
222
|
raise ValueError(
|
|
@@ -2544,6 +2544,10 @@ class CompressionSimulation:
|
|
|
2544
2544
|
server_result["data"] = {}
|
|
2545
2545
|
server_results.append(server_result)
|
|
2546
2546
|
|
|
2547
|
+
# ensure material index is set on all parts for a multi-simulation experiment
|
|
2548
|
+
for i, part_info in enumerate(self.part_infos):
|
|
2549
|
+
part_info.material_index = i
|
|
2550
|
+
|
|
2547
2551
|
self.make_manifest_v2(results=server_results)
|
|
2548
2552
|
manifest = copy.deepcopy(self.manifest)
|
|
2549
2553
|
manifest["results"] = server_results
|
|
@@ -92,9 +92,9 @@ JSON manifest format
|
|
|
92
92
|
],
|
|
93
93
|
|
|
94
94
|
# Optional display name per simulation variant, index-aligned with the variants
|
|
95
|
-
# the varying entries produce. A blank/missing entry falls back to
|
|
96
|
-
# Names must be unique and must not contain path separators.
|
|
97
|
-
"simulation_names": ["slow piston",
|
|
95
|
+
# the varying entries produce. A null/blank/missing entry falls back to
|
|
96
|
+
# "<name>_sim<i>". Names must be unique and must not contain path separators.
|
|
97
|
+
"simulation_names": ["slow piston", null, "fastest piston"]
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
Available material presets
|
|
@@ -193,6 +193,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
|
|
|
193
193
|
|
|
194
194
|
if part_type == "piston_cylinder":
|
|
195
195
|
kwargs = {}
|
|
196
|
+
if "name" in entry:
|
|
197
|
+
kwargs["name"] = entry["name"]
|
|
196
198
|
if "velocity" in entry:
|
|
197
199
|
kwargs["velocity"] = entry["velocity"]
|
|
198
200
|
if "shape_parameters" in entry:
|
|
@@ -203,6 +205,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
|
|
|
203
205
|
|
|
204
206
|
elif part_type == "piston_box":
|
|
205
207
|
kwargs = {}
|
|
208
|
+
if "name" in entry:
|
|
209
|
+
kwargs["name"] = entry["name"]
|
|
206
210
|
if "velocity" in entry:
|
|
207
211
|
kwargs["velocity"] = entry["velocity"]
|
|
208
212
|
if "shape_parameters" in entry:
|
|
@@ -213,6 +217,8 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
|
|
|
213
217
|
|
|
214
218
|
elif part_type == "piston_mesh":
|
|
215
219
|
kwargs = {"filename": entry["file"]}
|
|
220
|
+
if "name" in entry:
|
|
221
|
+
kwargs["name"] = entry["name"]
|
|
216
222
|
if "velocity" in entry:
|
|
217
223
|
kwargs["velocity"] = entry["velocity"]
|
|
218
224
|
if "material" in entry:
|
|
@@ -240,14 +246,6 @@ def _build_parts(parts_config: list[dict]) -> list[ExperimentPart]:
|
|
|
240
246
|
def _build_varying(varying_config: list[dict]) -> list[ExperimentVarying]:
|
|
241
247
|
varying: list[ExperimentVarying] = []
|
|
242
248
|
for entry in varying_config:
|
|
243
|
-
# Each entry varies exactly one thing; to vary several, use several entries.
|
|
244
|
-
kinds = [k for k in ("files", "material", "velocity", "values") if k in entry]
|
|
245
|
-
if len(kinds) > 1:
|
|
246
|
-
raise ValueError(
|
|
247
|
-
f"varying entry may only vary one of files/material/velocity/values, "
|
|
248
|
-
f"got {kinds}: {entry}"
|
|
249
|
-
)
|
|
250
|
-
|
|
251
249
|
if "part" in entry and "files" in entry:
|
|
252
250
|
files = entry["files"]
|
|
253
251
|
if not isinstance(files, list):
|
|
@@ -331,6 +331,12 @@ class TestSimulationNames:
|
|
|
331
331
|
with pytest.raises(ValueError, match="path separator"):
|
|
332
332
|
self._experiment(mock_sim, ["run/1"])
|
|
333
333
|
|
|
334
|
+
def test_none_entry_falls_back_to_auto(self, mock_sim):
|
|
335
|
+
exp = self._experiment(mock_sim, [None, "custom2", None])
|
|
336
|
+
exp.prepare()
|
|
337
|
+
assert [s.simulation_name for s in exp.sims] == [
|
|
338
|
+
"base_sim_sim0", "custom2", "base_sim_sim2"]
|
|
339
|
+
|
|
334
340
|
def test_non_list_rejected(self, mock_sim):
|
|
335
341
|
with pytest.raises(ValueError, match="list of strings"):
|
|
336
342
|
self._experiment(mock_sim, "baseline")
|
|
@@ -110,6 +110,18 @@ class TestBuildParts:
|
|
|
110
110
|
assert isinstance(parts[0], ExperimentPistonMesh)
|
|
111
111
|
assert parts[0].filename == "piston.ply"
|
|
112
112
|
|
|
113
|
+
def test_piston_parts_custom_name(self):
|
|
114
|
+
parts = _build_parts([
|
|
115
|
+
{"type": "piston_mesh", "name": "last", "file": "last.ply"},
|
|
116
|
+
{"type": "piston_cylinder", "name": "press"},
|
|
117
|
+
{"type": "piston_box", "name": "anvil"},
|
|
118
|
+
])
|
|
119
|
+
assert [p.name for p in parts] == ["last", "press", "anvil"]
|
|
120
|
+
|
|
121
|
+
def test_piston_parts_default_name_when_omitted(self):
|
|
122
|
+
parts = _build_parts([{"type": "piston_mesh", "file": "piston.ply"}])
|
|
123
|
+
assert parts[0].name == "piston"
|
|
124
|
+
|
|
113
125
|
def test_piston_mesh_with_velocity(self):
|
|
114
126
|
velocity = [[0.0, 0, 0, 0.0], [0.02, 0, 0, -1.25], [0.04, 0, 0, 0.0]]
|
|
115
127
|
parts = _build_parts([{"type": "piston_mesh", "file": "piston.ply", "velocity": velocity}])
|
|
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
|