Repository navigation
Restructure into headless solver + viewer, TOML config, VTKHDF run files, Quarto docs - #1
Merged
Merged
Conversation
Commits the existing simulator as-is (plus the VTK pin relaxation and RESTRUCTURING_PLAN.md) as the starting point for the restructuring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tools/reference_run.py records two short headless scenarios (sessile drop with global split + collapse; quasi-static sphere with local remeshing and wetting) into tests/reference/*.json. tests/test_reference.py (slow) compares final scalars tightly and, with DROPLET_REFERENCE_HASH=1, the SHA-256 of the final mesh. main() now takes an optional cfg and returns a summary of the final state. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Move the solver modules into the flat package DropletRelaxer/ (git mv, relative imports); surface_free_energy moves to DropletRelaxer.analysis. - pyproject.toml (hatchling + hatch-vcs, Python >= 3.12, test extra); pytest settings move there. tests/ -> test/. - Drop run_tests.sh, pytest.ini, the fast marker, the sys.path hack and the selftest. Slow tests are deselected by conftest unless -m is given or the test is named by node id. - flake8 (.flake8) via pre-commit; tests.yml (3.12-3.14, slow nightly or on the 'slow' label) and flake8.yml workflows. Reference runs reproduce bit-identically. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ckage - DropletRelaxer.driver.Driver: the remesh/restart loop formerly in main.py. It emits read-only Frames (energy, force, COM, gap, curvature computed by the driver), Events (remesh, diverged, log) and ticks to FrameSinks and honours a StopRequest. - DropletRelaxer.io.frame: Frame, Event, RunInfo, RunStatus, StopRequest. - DropletRelaxer.console.ConsoleSink: log lines + optional progress bar. - config: OutputConfig (every = ex VisConfig.render_every) and apply_volume_scale(), shared by the driver and test/runhelpers.py. - viewer/ (distribution DropletViewer): ViewerConfig (ex VisConfig), scene.py (ex visualize.py, plus a Scene class), charts, interaction, history slider, video export, and LiveWindow, a frame sink with Stop button, throttled event handling and stop-on-close. - Save records the replay video (+ frames.csv in quasi-static mode); the .npy export (export.py) is gone. - main.py only wires Driver + ConsoleSink + LiveWindow. - Tests: solver imports without pyvista; sinks/live window do not change results; frame/event contents; stop requests. Reference runs reproduce bit-identically, with and without the live window. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- config: load()/loads() read a scenario TOML strictly (unknown keys and wrong types are errors, with 'did you mean' hints), --set style overrides parse TOML values, dumps() writes a complete config (exact float round trip), optionally with documentation as comments. - Field comments become attribute docstrings (read by field_docs()); a test fails if a field is undocumented. Same for ViewerConfig, which reads the [viewer] table. - Runtime state leaves the config: Config.roughness_field and the CONFIG global are gone; surface_free_energy takes roughness= explicitly. - mesh.target_volume is a float; 0 means no rescaling. - droplet-relax run|restart|info|show-config (restart/info need the run file, next commit); SIGTERM/Ctrl-C end a run cleanly. - examples/: default, sessile, anomaly scenarios and a SLURM job-array sweep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- io/schema.py: single definition of the file contents (per-frame arrays, groups); io/writer.py (H5Writer frame sink) and io/reader.py (RunFile). - /VTKHDF holds temporal PolyData (one part per frame, topology may change between frames) with point, cell and per-step field data; verified with vtkHDFReader of VTK 9.3.1 and 9.7.1. /DropletRelaxer holds the config (as given and effective), start mesh, ragged contact-line rings, events, the sampled roughness field and two alternating checkpoint slots. - The file is written in SWMR mode (HDF5 1.10 format, readable by VTK's bundled HDF5); a frame becomes visible only when complete, so RunFile(follow=True) can read a run in progress. - The driver hands checkpoints (complete loop state incl. the quasi-static controller) to the sinks every output.checkpoint_every iterations and at the end, and can restart from one. droplet-relax restart/info. - Tests: round trip, VTKHDF offsets, restart after a simulated kill equals the uninterrupted run (also for the quasi-static sphere reference, bit-identical), restart overrides are restricted, reading while another process writes, CLI. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- droplet-view run.h5 replays a run (history slider, Play, Save = video into the run's folder); --follow keeps up with a run being written; --video renders the replay off screen; live scenario.toml runs the solver in-process with the live window, always writing a run file (default runs/<timestamp>/run.h5) that the window replays afterwards. - --software-gl and display/Conda hints replace run.sh, which is removed together with main.py and requirements.txt. - Tests: droplet-view live (off screen) writes and replays; video export; run file readable by vtkHDFReader. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- docs/mathematical_background.tex converted (pandoc + fix-ups) into a Quarto book: Theory, Implementation, Comparison and Outlook, plus a new part 'Using the Code' (getting started, configuration, troubleshooting). Cross-references are Quarto refs; the TikZ figure is compiled to PDF/PNG (source kept), the algorithm is a Markdown list, the bibliography is references.bib. The .tex/.txt/.pdf copies are removed. - Chapters on program structure, output and verification describe the new architecture; the equation-to-code table uses dotted names that test/test_docs.py imports. - Executable cells generate the parameter reference (from the field docstrings) and the run-file tables (from io/schema.py). - The README design log moves to an appendix with an old-to-new name map; README shrinks to overview, install, quick start, docs, tests. - documentation.yml renders the PDF on every push/PR (artifact) and attaches it to releases; docs extra in pyproject; PR template. - CLAUDE.md rewritten for the new layout. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- publish.yml builds both distributions on v* tags and uploads them to PyPI via trusted publishing. - CHANGELOG.md; RESTRUCTURING_PLAN.md records what was implemented and where the implementation deviates from the plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The writer sets the final status after the last frame, so refreshing the status first guarantees that a 'finished' status comes with every frame. Before, a reader could see 'finished' with a stale frame count (flaky test under load; --follow could attach the history slider without the last frames). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements
RESTRUCTURING_PLAN.md: the flat simulator becomes a headless solver package and a separate viewer, connected by a run file, with TOML configuration, a CLI, restartable runs and a Quarto book as documentation.Numerics are unchanged. Two reference runs (
test/test_reference.py) were recorded on the original code before any refactoring and reproduce bit-identically after every commit: a sessile drop with global split and collapse, and a quasi-static sphere run with local remeshing and wetting.What changes
DropletRelaxer, the solver: numpy, scipy and h5py only; a test makes sure it never imports PyVista.DropletViewer(viewer/): PyVista viewer.DropletRelaxer/driver.py,io/frame.py): the remesh loop frommain.py. Every output is a sink: HDF5 writer, console, live window. Only a stop request flows back, so attaching a window or writer does not change results (tested).--set section.key=valueoverrides. The field comments became attribute docstrings; a test enforces that every parameter is documented, anddroplet-relax show-configprints them.vtkHDFReaderof VTK 9.3.1 and 9.7.1, so ParaView opens it.droplet-relax run|restart|info|show-config; SIGTERM and Ctrl-C stop cleanly with a checkpoint.droplet-view run.h5 [--follow | --video out.mp4].droplet-view live scenario.toml: in-process live window with a Stop button. It always writes the run file and replays it after the run.docs/mathematical_background.texconverted to a Quarto book, with a new "Using the Code" part.run.sh,run_tests.sh,main.py,requirements.txt, the selftest, and the.npyexport (the Save button now records the replay video). Thevtk<9.5cap is gone: the GLX crash it guarded against is handled by disabling multisampling.tests.yml: Python 3.12–3.14; viewer tests under xvfb with the latest VTK; slow tests nightly or with theslowlabel.flake8.yml: pre-commit.documentation.yml: renders the PDF as an artifact and attaches it to releases.publish.yml: uploads to PyPI via trusted publishing onv*tags.Where the implementation deviates from the plan
Section 8 of
RESTRUCTURING_PLAN.mdlists these:geometry/,energies/andoptimizer/subpackages would only have added import cycles.FieldDataSizesis ordered[components, tuples].Steps/Values.Testing
pytest -m ""passes (154 tests), and the reference runs are bit-identical withDROPLET_REFERENCE_HASH=1.twine check.Not covered
publish.ymlneeds the PyPI projects and apypienvironment set up for trusted publishing first.🤖 Generated with Claude Code