tpmslab 0.3.4__tar.gz → 0.3.9.dev12__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.
- tpmslab-0.3.9.dev12/CHANGELOG.md +376 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/CITATION.cff +1 -1
- tpmslab-0.3.9.dev12/MANIFEST.in +17 -0
- tpmslab-0.3.9.dev12/PKG-INFO +423 -0
- tpmslab-0.3.9.dev12/README.md +391 -0
- tpmslab-0.3.9.dev12/Run-ComsolConvergence.cmd +3 -0
- tpmslab-0.3.9.dev12/Run-ComsolConvergence.ps1 +18 -0
- tpmslab-0.3.9.dev12/SOURCE_ORIGIN.json +10 -0
- tpmslab-0.3.9.dev12/Setup-Python.ps1 +22 -0
- tpmslab-0.3.9.dev12/Start-TpmsLab.cmd +3 -0
- tpmslab-0.3.9.dev12/Start-TpmsLab.ps1 +23 -0
- tpmslab-0.3.9.dev12/benchmarks/bcc_crosscompare.py +132 -0
- tpmslab-0.3.9.dev12/benchmarks/bcc_figures.py +348 -0
- tpmslab-0.3.9.dev12/benchmarks/bcc_vs_kuhn.py +85 -0
- tpmslab-0.3.9.dev12/benchmarks/comsol_convergence.py +192 -0
- tpmslab-0.3.9.dev12/benchmarks/conditioning_study.py +170 -0
- tpmslab-0.3.9.dev12/benchmarks/itt_layers.py +77 -0
- tpmslab-0.3.9.dev12/benchmarks/itt_prototype.py +404 -0
- tpmslab-0.3.9.dev12/benchmarks/itt_study.py +108 -0
- tpmslab-0.3.9.dev12/benchmarks/microgen_worker.py +31 -0
- tpmslab-0.3.9.dev12/benchmarks/other_tools.py +123 -0
- tpmslab-0.3.9.dev12/benchmarks/quality_vs_gmsh.py +293 -0
- tpmslab-0.3.9.dev12/benchmarks/refine_experiment.py +216 -0
- tpmslab-0.3.9.dev12/benchmarks/snapping_study.py +232 -0
- tpmslab-0.3.9.dev12/benchmarks/transport_convergence.py +266 -0
- tpmslab-0.3.9.dev12/docs/COMBINED_TPMS.md +79 -0
- tpmslab-0.3.9.dev12/docs/COMPARISON_ZH.md +217 -0
- tpmslab-0.3.9.dev12/docs/CONVERGENCE_STUDY_ZH.md +72 -0
- tpmslab-0.3.9.dev12/docs/HANDOFF_ZH.md +147 -0
- tpmslab-0.3.9.dev12/docs/PYTHON_COMSOL_ZH.md +125 -0
- tpmslab-0.3.9.dev12/docs/QUALITY_CONDITIONING_ZH.md +80 -0
- tpmslab-0.3.9.dev12/docs/QUALITY_REMESH.md +60 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/QUICKSTART_EN.md +17 -2
- tpmslab-0.3.9.dev12/docs/RELEASE_0.3.9.dev12.md +32 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/SOLID_FLUID.md +1 -1
- tpmslab-0.3.9.dev12/docs/VERTEX_SNAPPING_ZH.md +118 -0
- tpmslab-0.3.9.dev12/examples/combined_gyroid_diamond.json +21 -0
- tpmslab-0.3.9.dev12/examples/combined_tpms.py +15 -0
- tpmslab-0.3.9.dev12/examples/python_comsol.py +28 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/pyproject.toml +1 -1
- tpmslab-0.3.9.dev12/requirements-python-comsol-verified.txt +3 -0
- tpmslab-0.3.9.dev12/requirements-quality-verified.txt +4 -0
- tpmslab-0.3.9.dev12/src/tpmslab/__init__.py +73 -0
- tpmslab-0.3.9.dev12/src/tpmslab/batch_smoothing.py +184 -0
- tpmslab-0.3.9.dev12/src/tpmslab/cli.py +148 -0
- tpmslab-0.3.9.dev12/src/tpmslab/comsol.py +534 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/comsol_audit.py +36 -42
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/comsol_dual.py +76 -22
- tpmslab-0.3.9.dev12/src/tpmslab/comsol_remesh.py +336 -0
- tpmslab-0.3.9.dev12/src/tpmslab/conditioning.py +307 -0
- tpmslab-0.3.9.dev12/src/tpmslab/convergence.py +65 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/io.py +87 -72
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/model.py +138 -19
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/multidomain.py +149 -9
- tpmslab-0.3.9.dev12/src/tpmslab/optimize.py +925 -0
- tpmslab-0.3.9.dev12/src/tpmslab/periodic.py +223 -0
- tpmslab-0.3.9.dev12/src/tpmslab/quality.py +284 -0
- tpmslab-0.3.9.dev12/src/tpmslab/reporting.py +84 -0
- tpmslab-0.3.9.dev12/src/tpmslab/sampling.py +55 -0
- tpmslab-0.3.9.dev12/src/tpmslab/snapping.py +293 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/app.js +5 -5
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/index.html +2 -2
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/style.css +2 -0
- tpmslab-0.3.9.dev12/src/tpmslab/surface_smoothing.py +421 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/verification.py +4 -2
- tpmslab-0.3.9.dev12/src/tpmslab/volume.py +593 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/web.py +23 -6
- tpmslab-0.3.9.dev12/src/tpmslab.egg-info/PKG-INFO +423 -0
- tpmslab-0.3.9.dev12/src/tpmslab.egg-info/SOURCES.txt +132 -0
- tpmslab-0.3.9.dev12/tests/test_bcc_lattice.py +145 -0
- tpmslab-0.3.9.dev12/tests/test_benchmark_workflow.py +84 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_calibration_config.py +0 -1
- tpmslab-0.3.9.dev12/tests/test_combined.py +145 -0
- tpmslab-0.3.9.dev12/tests/test_comsol_remesh.py +32 -0
- tpmslab-0.3.9.dev12/tests/test_comsol_workflow.py +170 -0
- tpmslab-0.3.9.dev12/tests/test_conditioning.py +187 -0
- tpmslab-0.3.9.dev12/tests/test_convergence.py +38 -0
- tpmslab-0.3.9.dev12/tests/test_edge_projection.py +60 -0
- tpmslab-0.3.9.dev12/tests/test_generation_speed_dev6.py +56 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_multidomain.py +13 -1
- tpmslab-0.3.9.dev12/tests/test_optimization_budgets_dev6.py +178 -0
- tpmslab-0.3.9.dev12/tests/test_optimize.py +171 -0
- tpmslab-0.3.9.dev12/tests/test_optimizer_cache_dev7.py +39 -0
- tpmslab-0.3.9.dev12/tests/test_periodic.py +39 -0
- tpmslab-0.3.9.dev12/tests/test_review_fixes.py +283 -0
- tpmslab-0.3.9.dev12/tests/test_sampling.py +19 -0
- tpmslab-0.3.9.dev12/tests/test_smoothing_dev7.py +101 -0
- tpmslab-0.3.9.dev12/tests/test_snapping.py +198 -0
- tpmslab-0.3.9.dev12/tests/test_speed_dev7.py +73 -0
- tpmslab-0.3.9.dev12/tests/test_speed_paths.py +96 -0
- tpmslab-0.3.9.dev12/tests/test_surface_guard_dev6.py +110 -0
- tpmslab-0.3.4/.zenodo.json +0 -24
- tpmslab-0.3.4/CHANGELOG.md +0 -58
- tpmslab-0.3.4/MANIFEST.in +0 -14
- tpmslab-0.3.4/PKG-INFO +0 -227
- tpmslab-0.3.4/README.md +0 -195
- tpmslab-0.3.4/src/tpmslab/__init__.py +0 -30
- tpmslab-0.3.4/src/tpmslab/cli.py +0 -63
- tpmslab-0.3.4/src/tpmslab/comsol.py +0 -250
- tpmslab-0.3.4/src/tpmslab/quality.py +0 -46
- tpmslab-0.3.4/src/tpmslab/volume.py +0 -311
- tpmslab-0.3.4/src/tpmslab.egg-info/PKG-INFO +0 -227
- tpmslab-0.3.4/src/tpmslab.egg-info/SOURCES.txt +0 -86
- tpmslab-0.3.4/validation/README.md +0 -44
- tpmslab-0.3.4/validation/checksums.json +0 -18
- tpmslab-0.3.4/validation/code_commit.json +0 -4
- tpmslab-0.3.4/validation/density/density_results.json +0 -404
- tpmslab-0.3.4/validation/environment.json +0 -23
- tpmslab-0.3.4/validation/existing_Diamond_audit/audit.json +0 -35
- tpmslab-0.3.4/validation/existing_Gyroid_audit/audit.json +0 -35
- tpmslab-0.3.4/validation/existing_Primitive_Schwartz_audit/audit.json +0 -35
- tpmslab-0.3.4/validation/historical_windows_checksums.json +0 -17
- tpmslab-0.3.4/validation/performance_summary.csv +0 -5
- tpmslab-0.3.4/validation/provenance.json +0 -72
- tpmslab-0.3.4/validation/quality_summary.csv +0 -5
- tpmslab-0.3.4/validation/reference_configs/Diamond.json +0 -33
- tpmslab-0.3.4/validation/reference_configs/Gyroid.json +0 -33
- tpmslab-0.3.4/validation/reference_configs/Primitive_Schwartz.json +0 -33
- tpmslab-0.3.4/validation/refinement_summary.csv +0 -10
- tpmslab-0.3.4/validation/summary.json +0 -606
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/LICENSE +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/THIRD_PARTY_NOTICES.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/density_study.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/release_reference.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/revision_study.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/run_benchmarks.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/verify_comsol.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/benchmarks/verify_solid_fluid.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/METHOD.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/PYPI_PUBLISHING.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/QUICKSTART_ZH.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/RELEASE_NOTES_v0.3.0.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/RELEASE_NOTES_v0.3.1.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/RELEASE_NOTES_v0.3.3.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/RELEASE_NOTES_v0.3.4.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/VALIDATION.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/VERIFICATION.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/VERSION_0.3.0.md +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/lattgen_reference.m +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/docs/runtime_hashes_0.3.1.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/graded_gyroid.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/graded_gyroid.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/gyroid_graded.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/primitive_graded.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/solid_fluid.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/examples/solid_fluid_api.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/licenses/LattGen-MIT.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/setup.cfg +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/__main__.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/families.json +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/py.typed +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/vendor/OrbitControls.js +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/vendor/THREE-LICENSE.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab/static/vendor/three.module.js +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab.egg-info/dependency_links.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab.egg-info/entry_points.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab.egg-info/requires.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/src/tpmslab.egg-info/top_level.txt +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_core.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_english_runtime.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_package.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_report_version.py +0 -0
- {tpmslab-0.3.4 → tpmslab-0.3.9.dev12}/tests/test_verification.py +0 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
# 0.3.9.dev12 — linear tetrahedron export
|
|
2
|
+
|
|
3
|
+
- Remove the optional 10-node curved export and its COMSOL import validation case.
|
|
4
|
+
The NAS and NPZ exports contain four-node tetrahedra.
|
|
5
|
+
|
|
6
|
+
# 0.3.9.dev11 — optional surface envelope; hand-off (2026-11-05)
|
|
7
|
+
|
|
8
|
+
- `optimize_mesh(..., surface_envelope=mm)` (CLI `--surface-envelope`):
|
|
9
|
+
interface nodes may leave the exact implicit surface by at most this
|
|
10
|
+
first-order distance |g|/|grad g| when that improves the local worst quality
|
|
11
|
+
(fTetWild-style envelope; default None keeps the exact surface). The maximum
|
|
12
|
+
deviation is checked and reported (`optimization.surface_deviation_max_mm`).
|
|
13
|
+
With effort="high" and 8.66 µm (fTetWild's default 1e-3 of the box diagonal)
|
|
14
|
+
over the 16 bcc_crosscompare cases: median solid p01 0.62, median minimum
|
|
15
|
+
0.48; versus fTetWild on the same boundary p01 higher in 15/16, minimum
|
|
16
|
+
higher in 15/16, faster in 16/16 (1.4–4.2x), but solid volume error lower
|
|
17
|
+
in only 4/16 (typically +0.01 to +0.1 pp higher; the envelope moves are not
|
|
18
|
+
volume-neutral yet).
|
|
19
|
+
- docs/HANDOFF_ZH.md: state, architecture, reproduction commands and the open
|
|
20
|
+
task list for the next maintainer.
|
|
21
|
+
|
|
22
|
+
# 0.3.9.dev10 — high-effort optimisation (2026-11-05)
|
|
23
|
+
|
|
24
|
+
- `optimize_mesh(..., effort="high")` (CLI `--optimize-effort high`, web
|
|
25
|
+
"高质量优化"): every cell below quality 0.7 is targeted instead of 0.5. The
|
|
26
|
+
standard threshold capped the BCC solid p01 near 0.52 at every resolution.
|
|
27
|
+
16 bcc_crosscompare cases (BCC α 0.3 / boundary 0.35): median p01 0.51 →
|
|
28
|
+
0.57 (up to 0.66), median end-to-end time 2.7 s → 4.1 s. Against fTetWild on
|
|
29
|
+
the same boundary (single thread): p01 higher in 12 of 16 cases, solid volume
|
|
30
|
+
error lower in 15 of 16, 2–5× less time; fTetWild keeps a higher minimum in
|
|
31
|
+
8 of 16 (mostly Diamond and IWP box layers) and higher p01 on the coarsest
|
|
32
|
+
Diamond/IWP levels.
|
|
33
|
+
- Edge-removal candidates are scored with the same scalar arithmetic but
|
|
34
|
+
without per-call cache overhead (identical meshes; about 7 % less time).
|
|
35
|
+
|
|
36
|
+
# 0.3.9.dev9 — box-layer snapping, curved quadratic export, periodic faces (2026-11-05)
|
|
37
|
+
|
|
38
|
+
- `Config.snap_alpha_boundary` (CLI `--snap-alpha-boundary`): separate snap
|
|
39
|
+
threshold for lattice vertices on the outer box. Diagnosis on the BCC meshes:
|
|
40
|
+
80–100 % of the worst 1 % cells touch the box, mostly where the TPMS meets a
|
|
41
|
+
box face at a shallow angle. With BCC α 0.3 / boundary 0.35 over the 16
|
|
42
|
+
bcc_crosscompare cases: solid p01 up in 12 and down in 2 (at most −0.013),
|
|
43
|
+
solid minimum up in 8 and down in 1 (−0.003), volume error unchanged within
|
|
44
|
+
±0.05 pp. 0.4 produced a degenerate case (Diamond r10) and is not recommended.
|
|
45
|
+
Default None keeps dev8 arrays.
|
|
46
|
+
- `make_quadratic(model)` / `save_model(..., quadratic=True)` / CLI
|
|
47
|
+
`--quadratic`: `mesh_quadratic.nas` with 10-node CTETRA and CTRIA6; mid-edge
|
|
48
|
+
nodes of implicit-surface edges lie on the exact level set (box planes kept
|
|
49
|
+
flat, both phases share them). Jacobian sampled at 19 points per element;
|
|
50
|
+
curvature halved where det J / det J_linear < 0.2. Solid volume error versus
|
|
51
|
+
the 256³ integral drops 5–64× (e.g. Gyroid r13 0.335 → 0.006 pp); solid +
|
|
52
|
+
fluid still fill the box exactly. COMSOL import of the 10-node file is not
|
|
53
|
+
yet verified (evidence/run_dev9_validation.py).
|
|
54
|
+
- `Config.periodic_faces` (CLI `--periodic-faces`): on every axis where the
|
|
55
|
+
field repeats (checked numerically), opposite faces get identical node sets
|
|
56
|
+
and triangulations: field samples copied, snaps paired, coordinates enforced
|
|
57
|
+
and `report["periodic"]` verified after generation and optimisation. The
|
|
58
|
+
optimiser moves paired face nodes together and skips face retriangulation
|
|
59
|
+
there (p01 Gyroid 0.511 → 0.505, Diamond 0.504 → 0.492; about 2× slower).
|
|
60
|
+
- `report["wall_resolution"]` for sheets: 2q/|∇f| wall thickness against the
|
|
61
|
+
lattice spacing, with a warning when the thinnest 5 % is under one cell.
|
|
62
|
+
- Optimiser incidence is built by array grouping: identical meshes, 14 % less
|
|
63
|
+
optimisation time on the 12-case BCC timing set.
|
|
64
|
+
- Not adopted: thin-wall adaptive edge bisection (benchmarks/refine_experiment.py)
|
|
65
|
+
did not beat uniform BCC at equal element count (Diamond_low and Gyroid
|
|
66
|
+
0.08→0.5, P1 k_eff) and was 2–4× slower.
|
|
67
|
+
- Benchmarks: bcc_crosscompare.py, other_tools.py (TetGen, fTetWild, microgen),
|
|
68
|
+
quadratic_volume.py, bcc_figures.py; validation launcher Run-Dev9Validation.cmd.
|
|
69
|
+
|
|
70
|
+
# 0.3.9.dev8 — optional body-centred cubic background lattice (2026-11-05)
|
|
71
|
+
|
|
72
|
+
- New `Config.lattice = "kuhn" | "bcc"` (CLI `--lattice`, web "背景格子").
|
|
73
|
+
`bcc` adds voxel centres and box-face centres; every pair of face-adjacent
|
|
74
|
+
voxels contributes four congruent tetrahedra (mean ratio 0.952, dihedral
|
|
75
|
+
angles 60°/90°), and each box-face square is coned through its face centre
|
|
76
|
+
(four half tetrahedra, mean ratio 0.800). The background is conforming to
|
|
77
|
+
the box faces, so clipping, snapping, implicit-root cuts, two-phase
|
|
78
|
+
generation and `optimize_mesh` are unchanged. Default stays `kuhn`.
|
|
79
|
+
- BCC has about twice the tetrahedra per voxel: use about 5/6 of the Kuhn
|
|
80
|
+
resolution for a similar element count. Recommended with `snap_alpha=0.3`
|
|
81
|
+
(web UI uses 0.3 for BCC, 0.25 for Kuhn).
|
|
82
|
+
- `benchmarks/bcc_vs_kuhn.py`: four quality_vs_gmsh designs, Kuhn r12/r16
|
|
83
|
+
(α 0.25) vs BCC r10/r13 (α 0.3), optimised: solid p01 higher in 6 of 8
|
|
84
|
+
cases (equal in one, −0.013 in one), minimum higher in 7 of 8, median
|
|
85
|
+
+0.07 to +0.17 in all, volume error within ±0.07 pp of Kuhn, generate +
|
|
86
|
+
optimise 1.1–3.8× faster. Larger α (0.4, or 0.25/0.40 by edge length) raises
|
|
87
|
+
quality further on some designs but increases the volume error.
|
|
88
|
+
- Per-voxel density bookkeeping uses an explicit background-to-voxel owner
|
|
89
|
+
map instead of `owner // 6`.
|
|
90
|
+
- `benchmarks/itt_*.py`: stage-0 prototype of template inheritance and
|
|
91
|
+
iso-surface transport (not part of the package; see evidence/itt_stage0).
|
|
92
|
+
|
|
93
|
+
# 0.3.9.dev7 — less repeated work and phase-aware surface moves (2026-11-05)
|
|
94
|
+
|
|
95
|
+
- Generation reuses SVD polygon ordering only for shared faces with exactly
|
|
96
|
+
matching vertex IDs and order. Scalar fan screening rejects clear failures;
|
|
97
|
+
close decisions and accepted fans retain the original NumPy arithmetic.
|
|
98
|
+
- Cache ordered-tetrahedron metrics during reconnection, up to 65,536 entries;
|
|
99
|
+
invalidate on every coordinate refresh. The cache preserves signed volume
|
|
100
|
+
and does not change numerical decisions.
|
|
101
|
+
- Evaluate chord error on actual incident faces, without padded five-dimensional
|
|
102
|
+
triangle copies; skip candidates already excluded by quality or orientation.
|
|
103
|
+
- Mixed-phase surface moves preserve each phase's local minimum quality.
|
|
104
|
+
Round-level quality, median, chord and volume budgets remain unchanged.
|
|
105
|
+
This can retain more rounds and improve final quality, with a design-dependent
|
|
106
|
+
time cost. Record rejected phase trials in each round's history.
|
|
107
|
+
- Add numerical regressions for scalar screening, cache invalidation, packed
|
|
108
|
+
chord errors and per-phase trial acceptance.
|
|
109
|
+
|
|
110
|
+
# 0.3.9.dev6 — generation work reuse and geometry budgets (2026-11-05)
|
|
111
|
+
|
|
112
|
+
- Generation reuses face incidence for connected components, precomputes face
|
|
113
|
+
masks, and batches shared-vertex coordinate validation in two-phase meshes.
|
|
114
|
+
- Surface smoothing recomputes hard chord guards against the current geometry
|
|
115
|
+
of each independent batch, with bounded chunk memory. `optimize_mesh` now
|
|
116
|
+
defaults to `chord_tolerance=0.0`; explicit `None` retains soft ranking only.
|
|
117
|
+
- Each optimisation round checks per-phase minimum/p01/poor-volume quality,
|
|
118
|
+
the existing median-loss budget, and cumulative phase-volume drift (default
|
|
119
|
+
0.3 percentage points of box volume; configurable or `None`). A failed round
|
|
120
|
+
restores the previous mesh and records its rejection reasons.
|
|
121
|
+
- Recompute density profiles, domain/phase volumes, counts and interface area
|
|
122
|
+
from the final mesh. Profile `slab_count` records unequal-bin weights.
|
|
123
|
+
- Rebuild current boundaries before optional SLSQP conditioning. Clear input
|
|
124
|
+
COMSOL solve evidence after optimisation.
|
|
125
|
+
- Add regressions for live-neighbour chord guards, exact rollback, geometry
|
|
126
|
+
reports, SLSQP boundaries, shared-coordinate validation and face components.
|
|
127
|
+
|
|
128
|
+
# 0.3.9.dev5 — speed (2026-11-05)
|
|
129
|
+
|
|
130
|
+
- Generation: identical meshes (mesh_sha256 checked on eight configurations
|
|
131
|
+
against 0.3.9.dev3), about 30% faster.
|
|
132
|
+
- `choose_fan` scores its 3-10 cell fans with scalar volume / edge-length
|
|
133
|
+
arithmetic that reproduces numpy's bit for bit (the 3-term `einsum` order
|
|
134
|
+
is detected at import against the local numpy; `pow` stays in numpy);
|
|
135
|
+
falls back to the numpy path if no order matches.
|
|
136
|
+
- `quality.unique_rows` packs integer rows into one int64 key: identical
|
|
137
|
+
output to `np.unique(axis=0)`, several times faster; used for face/edge
|
|
138
|
+
incidence in generation, two-phase partition, conditioning and audits.
|
|
139
|
+
- `boundary_digest` is vectorised (same stable sorts, same bytes).
|
|
140
|
+
- Expressions are compiled once (whitelisted AST, empty builtins) instead of
|
|
141
|
+
walked node by node on every evaluation; values are bitwise identical.
|
|
142
|
+
- `optimize_mesh`: about 2x faster than 0.3.9.dev4 at equal or better quality.
|
|
143
|
+
- New `tpmslab.batch_smoothing`: interior and surface smoothing move
|
|
144
|
+
independent vertex sets (stars sharing no cell) together; all trial
|
|
145
|
+
positions of a batch are scored in one pass with the vertex-affine volume
|
|
146
|
+
and vertex-quadratic edge-length forms, without materialising the moved
|
|
147
|
+
tetrahedra.
|
|
148
|
+
- Adjacency is built once per round and shared; boundary arrays for the
|
|
149
|
+
surface step come from the mesh bookkeeping; oriented arrays are rebuilt
|
|
150
|
+
once at the end.
|
|
151
|
+
- The chord-error criterion uses one |grad g| per candidate vertex (six
|
|
152
|
+
fewer field evaluations per triangle centroid); cap flips compare
|
|
153
|
+
area x |g| directly.
|
|
154
|
+
- Mesh results of `optimize=True` change (Jacobi-style batches instead of
|
|
155
|
+
vertex-by-vertex order); default meshes do not.
|
|
156
|
+
|
|
157
|
+
# 0.3.9.dev4 — faster, stronger cut-layer optimisation (2026-11-05)
|
|
158
|
+
|
|
159
|
+
- Local mesh operations score their 1-20 cell stars in pure Python
|
|
160
|
+
(`quality.tet_scalar`/`star_scalar`) or one vectorised pass over all trial
|
|
161
|
+
positions (`quality.star_trials`) instead of one numpy call per star;
|
|
162
|
+
numpy call overhead was ~95% of the dev3 optimiser time.
|
|
163
|
+
- General Shewchuk-style edge removal (`_Mesh.remove_edge`): an interior edge
|
|
164
|
+
with a ring of 3-7 tetrahedra is replaced by the maximin triangulation of
|
|
165
|
+
its ring (O(n^3) dynamic programme); 3-2 and 4-4 flips are the n=3 and n=4
|
|
166
|
+
cases. Candidate edges/faces that failed are not retried within a round.
|
|
167
|
+
- Interior and surface smoothing try two directions per vertex (neighbour
|
|
168
|
+
centroid and the point that makes the worst incident cell regular) at four
|
|
169
|
+
step lengths and keep the best admissible one.
|
|
170
|
+
- Each round works on the quality tail (cells below the 5% quantile, never
|
|
171
|
+
above `quality_threshold`), `focus_quantile=0.05`.
|
|
172
|
+
- Surface moves are chosen with a chord-error criterion: among positions that
|
|
173
|
+
reach at least `chord_gain_floor` (0.1) of the best quality gain, the one
|
|
174
|
+
whose incident surface triangles depart least from the level set
|
|
175
|
+
(area x |g|/|grad g| at the centroids) is taken. An optional hard gate is
|
|
176
|
+
`chord_tolerance`. Without this, the stronger smoothing moved the phase
|
|
177
|
+
volume away from the exact implicit volume on coarse meshes.
|
|
178
|
+
- The per-round SLSQP `condition_mesh` pass is no longer part of the default
|
|
179
|
+
`smooth=True` path (it changed no p01/minimum value in the study);
|
|
180
|
+
`smooth="slsqp"` keeps it.
|
|
181
|
+
- Tests: edge removal on a five-cell ring, vectorised star trials, and the
|
|
182
|
+
optimise test now asserts that the solid volume does not move away from a
|
|
183
|
+
128^3 midpoint integral of the exact field (was: shift < 0.1 pp).
|
|
184
|
+
- Box-face edge removal (`_Mesh.remove_boundary_edge`): an edge lying in a
|
|
185
|
+
flat box face, whose two box-face triangles are coplanar, is removed with
|
|
186
|
+
its open ring; the face quad takes the other diagonal. Region, box faces
|
|
187
|
+
and phase volumes are exactly unchanged.
|
|
188
|
+
- Interface cap flips (`_Mesh.cap_flip`, two-phase, `surface=True` only): a
|
|
189
|
+
cell with all four vertices on the interface and two interface faces is
|
|
190
|
+
handed to the other phase (the interface takes the other triangulation of
|
|
191
|
+
the same four surface points) and its now-interior edge is removed; kept
|
|
192
|
+
only when quality improves and the new interface triangles are not further
|
|
193
|
+
from the level set. Interface conformity, triangle counts per boundary id
|
|
194
|
+
and connectivity are preserved; exterior/interface arrays are rebuilt.
|
|
195
|
+
- Default meshes (optimize=False) are unchanged.
|
|
196
|
+
|
|
197
|
+
# 0.3.9.dev3 — cut-layer mesh optimisation (2026-11-05)
|
|
198
|
+
|
|
199
|
+
- New `optimize_mesh` (`tpmslab.optimize`, `generate(..., optimize=True)`,
|
|
200
|
+
`tpmslab generate --optimize`, browser checkbox): local reconnection of the
|
|
201
|
+
cut layer (2-3, 3-2 and 4-4 flips restricted to interior faces/edges),
|
|
202
|
+
maximin Laplacian interior smoothing with SLSQP refinement of the poorest
|
|
203
|
+
stars, and `tpmslab.surface_smoothing`: boundary vertices slide within the
|
|
204
|
+
box faces and *along the exact implicit level set* (vectorised Newton
|
|
205
|
+
re-projection, residual < 1e-9 mm). Exterior/interface connectivity, phase
|
|
206
|
+
and domain labels are unchanged; phase volumes shift by ~0.01 pp; the
|
|
207
|
+
result is audited (`quality_audit`, interface, box planes, residuals).
|
|
208
|
+
- `benchmarks/quality_vs_gmsh.py`: like-for-like comparison with Gmsh on the
|
|
209
|
+
same boundary polyhedron (fixed boundary, interior only) and with Gmsh
|
|
210
|
+
re-meshing the surface as well; see docs/COMPARISON_ZH.md for numbers.
|
|
211
|
+
- `condition_mesh(max_median_loss=...)` exposes the median-loss budget of the
|
|
212
|
+
non-regression gate (default unchanged, 5%).
|
|
213
|
+
- `quality.cross` / `quality.signed_volumes`: fast small-array helpers.
|
|
214
|
+
- Default meshes (optimize=False) are unchanged from 0.3.9.dev2.
|
|
215
|
+
- Not yet run in COMSOL: `evidence/run_dev2_validation.py` gained an
|
|
216
|
+
`optimized_r12` case (flow and elasticity on optimised meshes).
|
|
217
|
+
|
|
218
|
+
# 0.3.9.dev2 — review fixes (2026-11-05)
|
|
219
|
+
|
|
220
|
+
Read-only review of 0.3.9.dev1 followed by these changes. No COMSOL run was
|
|
221
|
+
made for this version; see `evidence/README.md` for what the shipped
|
|
222
|
+
evidence does and does not cover.
|
|
223
|
+
|
|
224
|
+
- Evidence: rebuild `evidence/authorized_smoke_summary.json` from the attempt
|
|
225
|
+
records (both smoke cases passed on their second attempt; the first-attempt
|
|
226
|
+
summary is kept as `authorized_smoke_summary.first_attempt.json`); make
|
|
227
|
+
`evidence/run_authorized_smoke.py` idempotent; add `evidence/README.md`.
|
|
228
|
+
- One COMSOL launcher (`tpmslab.comsol.run_comsol_class`) for the
|
|
229
|
+
elasticity/flow bridge, `comsol_remesh` and `comsol_audit`: 6.2/6.3 mesh
|
|
230
|
+
API reflection, isolated `-prefsdir`, short `-tmpdir/-recoverydir/-data`
|
|
231
|
+
paths, log capture, marker parsing and the COMSOL version string recorded
|
|
232
|
+
in `run.json`/`comsol_verification.json`. `remesh-quality` previously used a
|
|
233
|
+
hard-coded `geometricModel("")` that does not compile on 6.2.
|
|
234
|
+
- `volume_components` now counts connectivity through shared faces in both
|
|
235
|
+
single- and two-phase modes; vertex/edge-only contacts are reported as
|
|
236
|
+
`pinched_contacts` with a warning instead of counting as one body.
|
|
237
|
+
- Reopen check compares the integrated volume with a relative tolerance
|
|
238
|
+
(was an absolute 1e-15 m^3).
|
|
239
|
+
- Pre-flight estimate of the background-lattice memory; oversized
|
|
240
|
+
`cells`×`resolution` fail with an explicit message (limit adjustable via
|
|
241
|
+
`TPMSLAB_MAX_LATTICE_BYTES`).
|
|
242
|
+
- Two-phase generation samples, calibrates, audits and snaps the lattice
|
|
243
|
+
once and shares it between the solid and complementary passes.
|
|
244
|
+
- `edge_interpolation="implicit_root"` uses vectorised bracketed bisection
|
|
245
|
+
started from the linear cut instead of per-edge `brentq`; the
|
|
246
|
+
unbracketed-cut fallback is unchanged. All other modes produce
|
|
247
|
+
byte-identical meshes to 0.3.9.dev1 (checked by mesh_sha256 on seven
|
|
248
|
+
configurations). `implicit_root` meshes differ only on edges where the
|
|
249
|
+
field grazes zero several times within a few micrometres (12 of 5001
|
|
250
|
+
nodes, at most 4.3 um, in the n=10 Gyroid check): both versions return
|
|
251
|
+
a point on the implicit surface, but not always the same one.
|
|
252
|
+
- Two-phase `density_profile` is recomputed from the final (projected) solid
|
|
253
|
+
cells; `density_profile_method` names the binning.
|
|
254
|
+
- Off-grid sampling probes run for built-in families as well; custom
|
|
255
|
+
formulas are still rejected on a miss, built-in families get a warning.
|
|
256
|
+
- Flow demo restricts `spf` to fluid domains that connect Z- and Z+ and
|
|
257
|
+
records `excluded_fluid_domains`; only a model without any spanning
|
|
258
|
+
channel is rejected.
|
|
259
|
+
- `element_order` (1 or 2) and `processes` (`-np`) options on `build_mph`,
|
|
260
|
+
`run_comsol`, the CLI and the convergence benchmark; recorded per attempt.
|
|
261
|
+
Order 2 is not yet covered by any shipped evidence.
|
|
262
|
+
- `generate --mph/--solve` accepts the same launch options as `comsol`.
|
|
263
|
+
- The browser COMSOL path no longer deletes the previous top-level
|
|
264
|
+
verification file; `build_mph` preserves it inside the new attempt.
|
|
265
|
+
- Documentation: version wording aligned with the 6.2.0.290 evidence.
|
|
266
|
+
|
|
267
|
+
# 0.3.9.dev1 — isolated COMSOL execution
|
|
268
|
+
|
|
269
|
+
- Explicit per-attempt preference files, CLI and benchmark options; global preferences unchanged.
|
|
270
|
+
- Short native temporary, recovery and workspace paths prevent Windows path-length failures.
|
|
271
|
+
- Actual COMSOL 6.2 solid and pore-flow smoke checks and documented comparison with related tools.
|
|
272
|
+
|
|
273
|
+
# 0.3.9.dev0 — Python to COMSOL workflow
|
|
274
|
+
|
|
275
|
+
- Correct nonuniform three-grid power-law fits and document the revised estimates.
|
|
276
|
+
- Preserve a separate, input-hashed directory for each COMSOL attempt; clear failed current state.
|
|
277
|
+
- Add run_comsol API and a comsol CLI command for saved models and material settings.
|
|
278
|
+
- Fix empty-cut projection and add bounded off-grid probes for custom formulas.
|
|
279
|
+
- Check compiler output as well as exit status; support 6.2/6.3 mesh API signatures.
|
|
280
|
+
- Checkpoint convergence rows, resume studies, fix Gmsh cleanup and label elasticity snapping accurately.
|
|
281
|
+
- Stream hashes; preserve historical delivery records under history/pre_0.3.9.
|
|
282
|
+
- Real COMSOL 6.2 Java compilation succeeded for both smoke cases; NAS import blocked by file-system security preferences. No successful solver validation is claimed.
|
|
283
|
+
|
|
284
|
+
# 0.3.8.dev0 (local improvement build; not published)
|
|
285
|
+
|
|
286
|
+
- Add opt-in pre-cut lattice-vertex snapping (`Config.snap_alpha`, `--snap-alpha`): a lattice vertex within `snap_alpha` of a cut point along one of its lattice edges is moved onto the isosurface before clipping, so the near-degenerate sliver that cut would have produced is never created. Default `snap_alpha=0` leaves every existing output byte-identical.
|
|
287
|
+
- Snap onto the exact implicit root by default (`snap_target="implicit"`); `"linear"` keeps the linear-cut point. Outer-box nodes may only move within their box face; moves that would invert a background tetrahedron, flatten a tetrahedron onto one isosurface, or pinch the material or its complement along a lattice edge are reverted and counted in `report["vertex_snapping"]`.
|
|
288
|
+
- Snapping is applied to the full inequality set before any fluid-side sign flip, so complementary solid/fluid passes share identical vertices and cut keys; the interface audit, box-face audit and scalar-diffusion patch check pass on all 12 study designs.
|
|
289
|
+
- Add `benchmarks/snapping_study.py` (12 paired designs, three variants, recomputed statistics, dense-sample reference density and implicit-surface fidelity) and `tests/test_snapping.py`.
|
|
290
|
+
- Allow `snap_alpha` together with `edge_interpolation="implicit_root"` / `"quadratic_root"`: root projection now uses the snapped lattice coordinates and keeps the linear cut when the true field does not bracket a root (`report["edge_root_unbracketed_cuts"]`). With both enabled every interface node lies on the implicit surface; the median solid-density error drops from 1.52 to 0.69 pp (worst 3.66 -> 2.03 pp) while the Q<0.01 count stays at 1 on the 12 designs.
|
|
291
|
+
- Add a browser checkbox (切割前顶点吸附) that sets `snap_alpha=0.25`, restore it from saved parameters, and show snapped/reverted vertex counts in the result notes.
|
|
292
|
+
- Measured on the 12 designs at `snap_alpha=0.25`: aggregate Q<0.01 cells 2710 -> 1 (Q<0.1: 60217 -> 250), tetrahedra 489696 -> 211328, per-phase minimum quality typically 0.001-0.01 -> 0.08-0.18. Costs: median absolute solid-density error unchanged (1.52 -> 1.51 pp) but the worst case rises (3.66 -> 4.03 pp); interface-node RMS distance to the implicit surface rises 10-25 % (10-40 um at 5 mm / resolution 12). No solver-accuracy or speedup claim is made.
|
|
293
|
+
|
|
294
|
+
# 0.3.7.dev0 (local improvement build; not published)
|
|
295
|
+
|
|
296
|
+
- Add bounded interior maximin smoothing with analytic quality derivatives and unchanged boundary/interface nodes, connectivity, domains and phase labels.
|
|
297
|
+
- Reconstruct input cell incidence; reject inverted cells, duplicates, nonmanifold faces and missing boundary/interface declarations.
|
|
298
|
+
- Audit candidates independently of optimizer success. Enforce phase minimum/p01/poor-count non-regression, a 5% relative median-loss budget and per-domain volume retention; roll back failed candidates with evidence.
|
|
299
|
+
- Expose `condition_mesh`, `quality_audit`, `generate(..., condition=True)`, CLI flags and a browser checkbox. Optional quality thresholds reject before export.
|
|
300
|
+
- Include 12 paired mesh records with independent geometry and exact scalar-diffusion patch checks. Do not infer FE/CFD accuracy or speedup from geometric quality alone.
|
|
301
|
+
|
|
302
|
+
# 0.3.6.dev0 (local development source; not a public release)
|
|
303
|
+
|
|
304
|
+
- Add `combine="blend"` for spatial transitions between two built-in or custom TPMS fields.
|
|
305
|
+
- Expose the secondary family, transition axis and bounds, weight profile, and calibration weight-sample count in Python, JSON, and the local browser interface.
|
|
306
|
+
- Calibrate the blended field using fixed-weight periodic quantiles; preserve exact original fields outside the transition and when both expressions are identical.
|
|
307
|
+
- Use one blended field for complementary solid/pore meshes and root interpolation, and export complete combined-design metadata.
|
|
308
|
+
- Add tests, a Python example, a JSON example, and combined-geometry documentation. The feature adds one composite solid phase and its complementary pore phase.
|
|
309
|
+
- Preserve frozen experiment sources and unchanged default mesh arrays; this feature has not established a mesh-quality or FEM accuracy advantage.
|
|
310
|
+
|
|
311
|
+
# 0.3.5.dev0 (local experimental source; not a public release)
|
|
312
|
+
|
|
313
|
+
- Add an optional COMSOL-native `RemeshFaces` plus `FreeTet` workflow for already verified two-phase exports.
|
|
314
|
+
- Require save/reopen, preserved domain and boundary selections, exact cross-phase face incidence, volume and interface-area tolerances, and improved solid quality before accepting the output.
|
|
315
|
+
- Add opt-in `edge_interpolation="implicit_root"` for two-phase meshes. It projects shared cut vertices to implicit-field edge roots subject to local positive-tetrahedron checks; the default remains linear interpolation.
|
|
316
|
+
- Add experimental `edge_interpolation="quadratic_root"`: batch-evaluate the continuous field at three positions on each cut edge, fit a quadratic crossing, and apply the same inversion guard to both phases. It offers a lower-cost approximation to iterative exact roots in the tested graded designs.
|
|
317
|
+
- Keep COMSOL external and optional. Preserve the 0.3.4 direct-mesh benchmark provenance separately from these exploratory modes.
|
|
318
|
+
|
|
319
|
+
# 0.3.4
|
|
320
|
+
|
|
321
|
+
- Add configurable density-calibration sampling via `m_cal` (default 56).
|
|
322
|
+
|
|
323
|
+
- Remove fixed upper limits on per-cell resolution and per-axis cell counts.
|
|
324
|
+
- Use an uncapped integer input in the browser interface.
|
|
325
|
+
- Preserve lower bounds, integer validation and numerical algorithms.
|
|
326
|
+
|
|
327
|
+
# 0.3.3
|
|
328
|
+
|
|
329
|
+
- Set the per-cell resolution maximum to 48 in Python and the browser slider.
|
|
330
|
+
- Retain removal of the total background-grid cap.
|
|
331
|
+
- Synchronize documentation and add boundary regression checks.
|
|
332
|
+
- Report the running generator version instead of a stale literal; geometry is unchanged.
|
|
333
|
+
|
|
334
|
+
# 0.3.2
|
|
335
|
+
|
|
336
|
+
- Remove the fixed 200,000-background-voxel limit from configuration validation.
|
|
337
|
+
- Retain per-axis cell-count and per-cell resolution validation.
|
|
338
|
+
- Add configuration regression coverage for grids above the former limit.
|
|
339
|
+
|
|
340
|
+
# 0.3.1
|
|
341
|
+
|
|
342
|
+
- Use English for Python progress callbacks, exceptions, API messages and exported warnings.
|
|
343
|
+
- Update generator metadata; preserve numerical algorithms and historical validation records.
|
|
344
|
+
|
|
345
|
+
# Changelog
|
|
346
|
+
|
|
347
|
+
## 0.3.0
|
|
348
|
+
|
|
349
|
+
- Package the verified complementary solid/fluid workflow and independent audits.
|
|
350
|
+
- Include density, refinement, interface, channel and performance records with provenance.
|
|
351
|
+
- Retain the validated numerical implementation from commit 686b783e0385.
|
|
352
|
+
- Clarify geometry/solver response stability and local quality-strategy limitations.
|
|
353
|
+
- Add isolated-wheel reference checks, exact-commit release preparation and public version documentation.
|
|
354
|
+
- Preserve historical validation provenance; GitHub publication and DOI registration remain separate records.
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
## 0.3.0rc1 — solid and pore-fluid domains
|
|
358
|
+
|
|
359
|
+
- Add complementary solid/fluid meshes with shared interface vertices and faces.
|
|
360
|
+
- Preserve independently connected solid and fluid domains, phase arrays and named boundaries.
|
|
361
|
+
- Add fluid preview, domain metadata and optional COMSOL named selections.
|
|
362
|
+
- Verify three fixed-wall pore-flow examples in COMSOL; deformation-coupled FSI is not implemented.
|
|
363
|
+
- Add analytical partition and multi-family interface regression tests.
|
|
364
|
+
|
|
365
|
+
## 0.2.0rc1 — local release candidate
|
|
366
|
+
|
|
367
|
+
- Introduce src-layout packaging, public Python API and command-line commands.
|
|
368
|
+
- Keep Flask and the browser interface optional; COMSOL remains optional.
|
|
369
|
+
- Add conservative interior-fan selection with unchanged external boundary.
|
|
370
|
+
- Add quality-tail diagnostics, deterministic mesh/boundary fingerprints,
|
|
371
|
+
environment records and file-integrity manifests.
|
|
372
|
+
- Normalize configuration lists to immutable tuples and apply phase controls
|
|
373
|
+
consistently in the field helper.
|
|
374
|
+
- Include reproducible comparisons, automated tests and release documentation.
|
|
375
|
+
|
|
376
|
+
Earlier rc entries describe local release candidates.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
include README.md LICENSE CHANGELOG.md THIRD_PARTY_NOTICES.md
|
|
2
|
+
recursive-include licenses *.txt
|
|
3
|
+
recursive-include docs *.md *.m
|
|
4
|
+
recursive-include examples *.json *.py
|
|
5
|
+
recursive-include tests *.py
|
|
6
|
+
include CITATION.cff
|
|
7
|
+
include requirements-quality-verified.txt
|
|
8
|
+
include Start-TpmsLab.ps1
|
|
9
|
+
include Start-TpmsLab.cmd
|
|
10
|
+
include Setup-Python.ps1
|
|
11
|
+
include Run-ComsolConvergence.ps1
|
|
12
|
+
include Run-ComsolConvergence.cmd
|
|
13
|
+
include requirements-python-comsol-verified.txt
|
|
14
|
+
include SOURCE_ORIGIN.json
|
|
15
|
+
recursive-include benchmarks *.py
|
|
16
|
+
|
|
17
|
+
include docs/runtime_hashes_0.3.1.json
|