htpolynet 2.4.0__tar.gz → 2.6.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.
- htpolynet-2.6.0/.github/workflows/docker.yml +72 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/CHANGELOG.md +166 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/PKG-INFO +9 -6
- {htpolynet-2.4.0 → htpolynet-2.6.0}/README.md +8 -5
- {htpolynet-2.4.0 → htpolynet-2.6.0}/ROADMAP.md +114 -15
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docker/Dockerfile +26 -5
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/results.rst +17 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/install.rst +18 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/configs/configs-for-run.rst +7 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/container-usage.rst +59 -16
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/postcure-repair.rst +98 -3
- {htpolynet-2.4.0 → htpolynet-2.6.0}/pyproject.toml +1 -1
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/runtime.py +52 -1
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cure/curecontroller.py +119 -1
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/repair/__init__.py +9 -4
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/repair/cyanate_cap.py +228 -29
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/6-cyanate-ester.yaml +9 -1
- htpolynet-2.6.0/tests/unit/test_cap_placement.py +115 -0
- htpolynet-2.6.0/tests/unit/test_completion_bias.py +159 -0
- htpolynet-2.6.0/tests/unit/test_repair_conversion.py +63 -0
- htpolynet-2.4.0/.github/workflows/docker.yml +0 -38
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.claude/settings.json +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.claude/skills/htpolynet/SKILL.md +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.envrc +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.github/workflows/conda-forge-sync.yml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.github/workflows/release.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.github/workflows/test.yml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.gitignore +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/.readthedocs.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/CITATION.cff +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/CLAUDE.md +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/LICENSE +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/MANIFEST.in +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docker/compose.yml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docker/docker-entrypoint.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/Makefile +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/README.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/make.bat +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/requirements.txt +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/_static/.gitkeep +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/changelog.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/conf.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/monomer.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/0-liquid-styrene/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/monomer.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/STY.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/STYCC.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/final-box.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/sty-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/pics/styrene-polymerization.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/1-polystyrene/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/BPA.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/GMA.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/HIE.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.eps +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.fig +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/four_dimers.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/gma-sty-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/p1-traces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.eps +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.fig +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/pics/vesys.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/2-bisgma-styrene-thermoset/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-epoxy.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/DGE-labelled.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-2d.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/PAC-labelled.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dge-pac-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.eps +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.fig +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/dgesys.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/equil-rho_v_ns.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/postsim-typical.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-e.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-equil-rho_v_ns.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-rho_v_ns.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/prod-tg.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r1.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r2.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/r3.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/rho_v_ns.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-e.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/pics/short-tg.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/3-pacm-dgeba-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/monomers.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/dfa-fde-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/4-dfda-fde-epoxy-thermoset/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/monomers.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/htpb-ipdi-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/results.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/5-htpb-ipdi/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/configuration.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/introduction.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/monomers.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-coloring.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-cured.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-detail.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/badcy-liq.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/buildtraces.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/cure_info.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/densification-density.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/pics/reaction_network.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/reactions.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/run.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/htpolynetpackage.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/references/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/references/mol2-reference.pdf +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/references.bib +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/release-history.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/CURE.odg +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/bond_filter.odg +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/building-a-system.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/configs/configs-for-analyze.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/configs/configs-for-postsim.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/configuration-files.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/flow1.odg +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/flow1yaml.odg +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/hydrogenated.eps +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/hydrogenated.fig +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/index.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/molecular-structure-inputs.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/STY.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/STYCC.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/TypicalUsageFlow.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/bond_filter.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-emb.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/chemdoodle-2dsketcher-styrene.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/hydrogenated.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_cases.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/pics/ring_pierce/ring_pierce_linkcell.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/program-flow.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/user-guide/usage.rst +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/check-conda-sync.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/release.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/render-detail.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/render-detail.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/render-snapshot.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/scripts/run_all_examples.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/analysis/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/analysis/analyze.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/analysis/plot.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/analysis/postsim.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/analysis/utils.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cli.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/bondtemplate.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/configuration.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/coordinates.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/molecule.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/paramcache.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/projectfilesystem.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/topocoord.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/core/topology.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cure/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cure/chain.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cure/expandreactions.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/cure/reaction.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/ambertools.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/command.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/gromacs.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/slurm.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/smiles_input.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/external/software.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/bondlist.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/lattice.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/linkcell.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/matrix4.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/geometry/ring.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/io/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/io/gro.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/io/mol2.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/io/pdb.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/repair/topology_surgery.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/README.md +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/claude/SKILL.md +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/0-liquid-styrene.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/1-polystyrene.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/2-bisgma-styrene-thermoset.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/3-pacm-dgeba-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/4-dfda-fde-epoxy-thermoset.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/example_depot/5-htpb-ipdi.yaml +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/README.md +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/drag-min.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/drag-npt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/drag-nvt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/min.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/npt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/nvt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/relax-min.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/relax-npt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/relax-nvt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/single-molecule-min.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/mdp/single-molecule-nvt.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/DFA.pdb +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/DGE.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/EMB.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/FDE.pdb +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/GMA.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/PAC.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/inputs/STY.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/make-monomers.sh +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/DFA.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/DGE.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/EMB.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/FDE.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/GMA.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/PAC.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/pics/STY.png +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/DFA.pdb +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/DGE.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/EMB.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/FDE.pdb +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/GMA.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/PAC.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/molecules/sample-inputs/STY.mol2 +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/tcl/readbonds.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/tcl/readgrx.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/resources/tcl/render.tcl +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/banner.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/checkpoint.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/dataframetools.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/inputcheck.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/logsetup.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/profiling.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/stringthings.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/src/htpolynet/utils/vmd_viz.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/conftest.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/__init__.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/config1.gro +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/config1.top +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/config2.gro +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/config2.top +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/items31.edr +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/items43.edr +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/items45.edr +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/fixtures/short.mdp +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_bondtemplate.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_chain.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_configuration.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_dataframetools.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_gpu_usability.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_gromacs_get_energy_menu.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_gromacs_gmx_energy_trace.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_inputcheck.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_linkcell_pierce.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_paramcache.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_paramcache_ambertools.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_parameterize_react.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_plot_smoke.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_projectfilesystem.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_resources.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_ring.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_ring_pierce_figs.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_setup_claude.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_slurm_script.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_smiles_input.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_software_provenance.py +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_topology/test.top +0 -0
- {htpolynet-2.4.0 → htpolynet-2.6.0}/tests/unit/test_topology.py +0 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
name: Build and push Docker image
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
- "d*"
|
|
8
|
+
schedule:
|
|
9
|
+
# Rebuild weekly (Monday 03:00 UTC) to pick up latest Gromacs/AmberTools
|
|
10
|
+
- cron: '0 3 * * 1'
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
docker:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
packages: write
|
|
18
|
+
strategy:
|
|
19
|
+
fail-fast: false
|
|
20
|
+
matrix:
|
|
21
|
+
include:
|
|
22
|
+
# The default image. conda-forge's preferred linux-64 Gromacs is the
|
|
23
|
+
# OpenCL build, which cannot drive NVIDIA devices; this image is
|
|
24
|
+
# CPU-only by design and stays the default so `docker run` on a
|
|
25
|
+
# laptop keeps working without pulling the CUDA toolkit.
|
|
26
|
+
- variant: cpu
|
|
27
|
+
gromacs_build: ""
|
|
28
|
+
cuda_override: ""
|
|
29
|
+
tag_prefix: ""
|
|
30
|
+
# The CUDA image. gromacs=*=nompi_cuda* depends on the __cuda
|
|
31
|
+
# virtual package, which conda synthesizes only where an NVIDIA
|
|
32
|
+
# driver is present -- so the solve fails on this runner unless
|
|
33
|
+
# CONDA_OVERRIDE_CUDA declares one. That makes the image buildable
|
|
34
|
+
# here; it does NOT make it verifiable here. Nothing in CI can
|
|
35
|
+
# confirm that mdrun actually offloads, so smoke-test a new CUDA
|
|
36
|
+
# image on real hardware before recommending it.
|
|
37
|
+
- variant: cuda
|
|
38
|
+
gromacs_build: "nompi_cuda"
|
|
39
|
+
cuda_override: "12.9"
|
|
40
|
+
tag_prefix: "cuda-"
|
|
41
|
+
steps:
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
|
|
44
|
+
- name: Log in to GitHub Container Registry
|
|
45
|
+
uses: docker/login-action@v3
|
|
46
|
+
with:
|
|
47
|
+
registry: ghcr.io
|
|
48
|
+
username: ${{ github.actor }}
|
|
49
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
50
|
+
|
|
51
|
+
- name: Compute tags
|
|
52
|
+
id: tags
|
|
53
|
+
run: |
|
|
54
|
+
if [ "${{ matrix.variant }}" = "cuda" ]; then
|
|
55
|
+
moving="ghcr.io/cameronabrams/htpolynet:cuda"
|
|
56
|
+
else
|
|
57
|
+
moving="ghcr.io/cameronabrams/htpolynet:latest"
|
|
58
|
+
fi
|
|
59
|
+
printf 'tags<<EOF\n%s\nghcr.io/cameronabrams/htpolynet:%s%s\nEOF\n' \
|
|
60
|
+
"$moving" "${{ matrix.tag_prefix }}" "${{ github.sha }}" >> "$GITHUB_OUTPUT"
|
|
61
|
+
|
|
62
|
+
- name: Build and push
|
|
63
|
+
uses: docker/build-push-action@v6
|
|
64
|
+
with:
|
|
65
|
+
context: .
|
|
66
|
+
file: docker/Dockerfile
|
|
67
|
+
push: true
|
|
68
|
+
build-args: |
|
|
69
|
+
HTPOLYNET_COMMIT=${{ github.sha }}
|
|
70
|
+
GROMACS_BUILD=${{ matrix.gromacs_build }}
|
|
71
|
+
CONDA_OVERRIDE_CUDA=${{ matrix.cuda_override }}
|
|
72
|
+
tags: ${{ steps.tags.outputs.tags }}
|
|
@@ -7,6 +7,172 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [2.6.0] - 2026-08-26
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **Transferred `-C#N` caps are no longer placed blind, which is what has been
|
|
15
|
+
killing low-conversion builds.** The repair stage relocates a cap by
|
|
16
|
+
putting it along the bridge oxygen's old O-H vector, with no regard for
|
|
17
|
+
what is already there. In a box at polymer density that direction is
|
|
18
|
+
usually occupied: in a synthetic 13000-atom box at 93 atoms/nm³, blind
|
|
19
|
+
placement put 91 of 158 caps within 0.10 nm of a neighbour and the worst at
|
|
20
|
+
0.008 nm -- effectively superimposed, which is the step-0 Lennard-Jones
|
|
21
|
+
term of order 1e15 that no minimization recovers from.
|
|
22
|
+
|
|
23
|
+
The cap is now still tried along the O-H vector first, so a cap in open
|
|
24
|
+
space lands exactly where it always did; only when that direction is
|
|
25
|
+
occupied does the driver search the sphere for the clearest one, holding
|
|
26
|
+
both bond lengths fixed so only the orientation moves. Caps already placed
|
|
27
|
+
are part of the neighbourhood the next one sees. On the same synthetic box
|
|
28
|
+
no cap lands closer than 0.128 nm, at either 158 or 378 transfers.
|
|
29
|
+
|
|
30
|
+
This matters more the lower the conversion, because the number of caps to
|
|
31
|
+
place is an identity -- `total reactive sites - bonds formed` -- so it rises
|
|
32
|
+
as conversion falls. `completion_bias` does not reduce it.
|
|
33
|
+
|
|
34
|
+
- **The stage now says how many fragments it transferred, and complains about
|
|
35
|
+
the ones it could not place well.** The transfer count is the quantity that
|
|
36
|
+
predicts whether repair survives and it was buried in one mid-log INFO line;
|
|
37
|
+
it is now reported next to the conversion, along with the tightest placement
|
|
38
|
+
achieved. A cap that could not reach `cap_min_clearance` (new, default
|
|
39
|
+
0.15 nm) in any direction is named, with its oxygen, while that is still
|
|
40
|
+
cheap to act on -- the alternative was working back to cap placement from a
|
|
41
|
+
GROMACS internal error at step 0.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **`completion_bias` now says so when it is ranking the wrong side of the
|
|
46
|
+
reaction.** The bias ranks on the `B` reactant, because htpolynet's A2+B3
|
|
47
|
+
idiom puts the crosslinker there. Declare the crosslinker as `A` instead
|
|
48
|
+
and the bias quietly starts completing the *bridges* -- a different claim
|
|
49
|
+
about which partly-reacted species is a reactive intermediate, and almost
|
|
50
|
+
certainly not the one that was wanted. The first cure iteration now
|
|
51
|
+
compares the initial functionality of the two sides and warns if the `A`
|
|
52
|
+
side is the more functional one.
|
|
53
|
+
|
|
54
|
+
Worth recording why the obvious detector does not work: looking for an
|
|
55
|
+
all-zero bias key catches nothing, because a difunctional bridge
|
|
56
|
+
accumulates reactions perfectly well and the key is non-zero. What
|
|
57
|
+
separates the two cases is which side carries more reactive sites, and that
|
|
58
|
+
is readable straight off the atom dataframe -- forming a bond decrements an
|
|
59
|
+
atom's `z` and increments its `nreactions` in the same operation, so their
|
|
60
|
+
sum is conserved and reads the same at iteration 0 as at the end.
|
|
61
|
+
|
|
62
|
+
## [2.5.0] - 2026-08-26
|
|
63
|
+
|
|
64
|
+
### Added
|
|
65
|
+
|
|
66
|
+
- **The conversion a cyanate-ester run reports is now the conversion the
|
|
67
|
+
structure actually carries.** The cure iterates on bond conversion --
|
|
68
|
+
bonds formed over bonds possible -- and that is the only number it printed.
|
|
69
|
+
But `postcure_repair` then dismantles every crosslinker that did not fill
|
|
70
|
+
all of its sites, so the structure leaving the repair stage contains only
|
|
71
|
+
*complete* crosslinkers, and the fraction of those is what an experiment
|
|
72
|
+
measures. For a trifunctional crosslinker under random placement the
|
|
73
|
+
second number is roughly the cube of the first, so a run at a bond
|
|
74
|
+
conversion of 0.90 leaves a cyanate conversion near 0.73 -- and nothing
|
|
75
|
+
said so. The repair stage now logs both figures side by side and writes
|
|
76
|
+
them, with the counts behind them, to `repair-summary.yaml` in the repair
|
|
77
|
+
directory.
|
|
78
|
+
|
|
79
|
+
- **`CURE.controls.completion_bias`, an opt-in change to how bond candidates
|
|
80
|
+
are ranked.** Candidates have always been ordered by pair separation
|
|
81
|
+
alone. Separation is uncorrelated with how many bonds a crosslinker
|
|
82
|
+
already carries, and the downselection that follows admits at most one bond
|
|
83
|
+
per residue per iteration, so bonds spread evenly across every crosslinker
|
|
84
|
+
in the box instead of finishing any of them. With `completion_bias: true`
|
|
85
|
+
the number of bonds already on the candidate's `B`-side residue becomes the
|
|
86
|
+
primary sort key and separation the tie-break within each group, so a
|
|
87
|
+
crosslinker with two of three sites filled is completed before an untouched
|
|
88
|
+
one is started. Nothing else about the search changes: same radius growth,
|
|
89
|
+
same dragging and relaxation, same probability application, same cycle
|
|
90
|
+
handling.
|
|
91
|
+
|
|
92
|
+
This is a modelling option, not a fix, and it is **off by default** so that
|
|
93
|
+
every existing config and every shipped example behaves exactly as before.
|
|
94
|
+
Where a partly-reacted crosslinker is a stable species the old ranking is
|
|
95
|
+
the more faithful one; where it is a reactive intermediate -- a
|
|
96
|
+
cyclotrimerizing cyanate ester, whose triazine ring either closes or does
|
|
97
|
+
not -- the new one is. Turning it on changes what `desired_conversion`
|
|
98
|
+
means physically: a config that reaches a crosslinker conversion of 0.76 at
|
|
99
|
+
`desired_conversion: 0.90` unbiased reaches about 0.90 biased, so runs
|
|
100
|
+
either side of the setting must be compared at matched crosslinker
|
|
101
|
+
conversion, not matched `desired_conversion`.
|
|
102
|
+
|
|
103
|
+
It also reduces the repair stage's dismantling work: at a bond conversion
|
|
104
|
+
of 0.90 the driver dismantles roughly 24 crosslinkers instead of 58, and
|
|
105
|
+
places 72 caps instead of 174.
|
|
106
|
+
|
|
107
|
+
**Corrected 2026-08-26, after this section was published:** the original
|
|
108
|
+
text here claimed the bias also relieves the cap-placement blowup that has
|
|
109
|
+
killed builds at low conversion. It does not. Only *transferred* caps are
|
|
110
|
+
placed geometrically -- `_place_cyn_along` runs solely where
|
|
111
|
+
`bonded_o is None` -- and the number of those is an identity,
|
|
112
|
+
`total_sites - bonds`, with no term for how the bonds are distributed. So
|
|
113
|
+
the bias cannot change it at a matched bond conversion, and at a matched
|
|
114
|
+
crosslinker conversion it makes it *worse*, because it reaches that
|
|
115
|
+
conversion by forming fewer bonds and every bond not formed is a fragment
|
|
116
|
+
that must be transferred. The blowup is a separate defect in
|
|
117
|
+
`repair/cyanate_cap.py`; see `ROADMAP.md`.
|
|
118
|
+
|
|
119
|
+
- **A CUDA image, published as `ghcr.io/cameronabrams/htpolynet:cuda`.** The
|
|
120
|
+
only image until now installed conda-forge's default linux-64 Gromacs,
|
|
121
|
+
which is an OpenCL build; Gromacs no longer drives NVIDIA devices through
|
|
122
|
+
OpenCL, so that image cannot use a GPU at all. The new tag installs
|
|
123
|
+
`gromacs=*=nompi_cuda*` from the same Dockerfile and can.
|
|
124
|
+
|
|
125
|
+
The CPU image remains `:latest` and remains the default, because the CUDA
|
|
126
|
+
build pulls in the CUDA toolkit and inflates the image substantially --
|
|
127
|
+
`docker run` on a laptop should not download a toolkit it cannot use.
|
|
128
|
+
Both tags are built by the same workflow on the same triggers, and both
|
|
129
|
+
carry the per-commit tag scheme (`:<sha>` and `:cuda-<sha>`).
|
|
130
|
+
|
|
131
|
+
`external.software.gpu_unusable_reasons()` needed no change: it already
|
|
132
|
+
reconciled detected hardware against what the gmx build can drive, so the
|
|
133
|
+
CUDA image simply starts passing checks the CPU image fails.
|
|
134
|
+
|
|
135
|
+
Verified on hardware, since nothing in CI can check this: on a Picotte
|
|
136
|
+
V100 node the image reports `GPU support: CUDA` where `:latest` reports
|
|
137
|
+
OpenCL, `htpolynet info` detects the device instead of calling it
|
|
138
|
+
`unusable`, and a complete `fetch-example 1` build ran every one of its
|
|
139
|
+
`gmx mdrun` steps with `-gpu_id 0`, using cuFFT for PME. The CUDA 12.9
|
|
140
|
+
runtime in the image runs against that node's 12.4-era driver (550.127.05)
|
|
141
|
+
under CUDA minor-version compatibility, so a site does not need a
|
|
142
|
+
bleeding-edge driver to use the tag.
|
|
143
|
+
|
|
144
|
+
### Changed
|
|
145
|
+
|
|
146
|
+
- **Repair drivers now return a statistics dict rather than an operation
|
|
147
|
+
count**, and `htpolynet.repair.run_repair` returns `(total, stats)` rather
|
|
148
|
+
than a bare total. This is what carries the crosslinker-conversion figures
|
|
149
|
+
out to the runtime for reporting. Only affects code that calls a repair
|
|
150
|
+
driver directly; the `postcure_repair` config surface is unchanged.
|
|
151
|
+
|
|
152
|
+
### Fixed
|
|
153
|
+
|
|
154
|
+
- **The container documentation told users to give the image a GPU, which it
|
|
155
|
+
cannot use.** `container-usage.rst` carried a "GPU support" section
|
|
156
|
+
walking through the NVIDIA Container Toolkit and a `deploy.resources`
|
|
157
|
+
block reserving nvidia devices, ending "htpolynet will detect the
|
|
158
|
+
available GPU(s) automatically at startup" -- and then, sixty lines later
|
|
159
|
+
in the Singularity section, correctly warned that the image's conda-forge
|
|
160
|
+
Gromacs is an OpenCL build and cannot drive NVIDIA devices at all. The
|
|
161
|
+
page contradicted itself, and `README.md` repeated the wrong half with a
|
|
162
|
+
`docker run --gpus all` example.
|
|
163
|
+
|
|
164
|
+
Both now say the same thing: exposing a GPU to this image starts the
|
|
165
|
+
container and changes nothing about how it computes, so target CPU
|
|
166
|
+
partitions and do not hold a device another job could use. The reason and
|
|
167
|
+
the detection behavior are stated once, under Docker, and the HPC warning
|
|
168
|
+
points at it for the `--nv`/`--gres=gpu` specifics.
|
|
169
|
+
|
|
170
|
+
### Changed
|
|
171
|
+
|
|
172
|
+
- `htpolynet setup-claude` is now discoverable where a new user will meet
|
|
173
|
+
it: the installation page and the README, rather than only the subcommand
|
|
174
|
+
reference.
|
|
175
|
+
|
|
10
176
|
## [2.4.0] - 2026-08-25
|
|
11
177
|
|
|
12
178
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: htpolynet
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: Automated MD System Builder for Amorphous Network Polymers
|
|
5
5
|
Project-URL: Source, https://github.com/cameronabrams/htpolynet
|
|
6
6
|
Project-URL: Documentation, https://htpolynet.readthedocs.io/
|
|
@@ -67,21 +67,24 @@ pip install -e .
|
|
|
67
67
|
|
|
68
68
|
Once installed, the user has access to the main ``htpolynet`` command.
|
|
69
69
|
|
|
70
|
+
If you drive htpolynet with [Claude Code](https://claude.com/claude-code), install the bundled skill so the agent knows how to use it:
|
|
71
|
+
```bash
|
|
72
|
+
htpolynet setup-claude
|
|
73
|
+
```
|
|
74
|
+
This writes `~/.claude/skills/htpolynet/SKILL.md`; nothing is installed there unless you run it.
|
|
75
|
+
|
|
70
76
|
IMPORTANT NOTES: The programs ``antechamber``, ``parmchk2`` and ``tleap`` from AmberTools must be in your path. These can be installed using the ``ambertools`` package from ``conda-forge`` or compiled from source. You also need Gromacs installed so ``gmx`` is in your path. The examples show how to build input monomer structures using OpenBabel, so to use them you need ``obabel`` in your path as well.
|
|
71
77
|
|
|
72
78
|
## Docker
|
|
73
79
|
|
|
74
|
-
As an alternative to a local installation, a prebuilt container image is published at ``ghcr.io/cameronabrams/htpolynet``. It bundles htpolynet together with Gromacs, AmberTools, and OpenBabel, so no additional dependencies are required on the host beyond Docker
|
|
80
|
+
As an alternative to a local installation, a prebuilt container image is published at ``ghcr.io/cameronabrams/htpolynet``. It bundles htpolynet together with Gromacs, AmberTools, and OpenBabel, so no additional dependencies are required on the host beyond Docker.
|
|
75
81
|
|
|
76
82
|
Run htpolynet against a configuration file in the current directory:
|
|
77
83
|
```bash
|
|
78
84
|
docker run --rm -v $(pwd):/work ghcr.io/cameronabrams/htpolynet run config.yaml
|
|
79
85
|
```
|
|
80
86
|
|
|
81
|
-
|
|
82
|
-
```bash
|
|
83
|
-
docker run --rm --gpus all -v $(pwd):/work ghcr.io/cameronabrams/htpolynet run config.yaml
|
|
84
|
-
```
|
|
87
|
+
**The image cannot use a GPU.** Its Gromacs comes from conda-forge, built against OpenCL rather than CUDA, and Gromacs no longer drives NVIDIA devices through OpenCL. Passing `--gpus all` starts the container and changes nothing about how it computes; on a cluster, target CPU partitions and do not request `--gres=gpu` or pass `--nv`. If you need GPU-accelerated Gromacs, install htpolynet natively against a CUDA-enabled Gromacs.
|
|
85
88
|
|
|
86
89
|
A Docker Compose file is also provided in [docker/compose.yml](docker/compose.yml) for a shorter invocation (``docker compose run --rm htpolynet run config.yaml``). See [docs/source/user-guide/container-usage.rst](docs/source/user-guide/container-usage.rst) for the full story, including Singularity/Apptainer use on HPC systems.
|
|
87
90
|
|
|
@@ -33,21 +33,24 @@ pip install -e .
|
|
|
33
33
|
|
|
34
34
|
Once installed, the user has access to the main ``htpolynet`` command.
|
|
35
35
|
|
|
36
|
+
If you drive htpolynet with [Claude Code](https://claude.com/claude-code), install the bundled skill so the agent knows how to use it:
|
|
37
|
+
```bash
|
|
38
|
+
htpolynet setup-claude
|
|
39
|
+
```
|
|
40
|
+
This writes `~/.claude/skills/htpolynet/SKILL.md`; nothing is installed there unless you run it.
|
|
41
|
+
|
|
36
42
|
IMPORTANT NOTES: The programs ``antechamber``, ``parmchk2`` and ``tleap`` from AmberTools must be in your path. These can be installed using the ``ambertools`` package from ``conda-forge`` or compiled from source. You also need Gromacs installed so ``gmx`` is in your path. The examples show how to build input monomer structures using OpenBabel, so to use them you need ``obabel`` in your path as well.
|
|
37
43
|
|
|
38
44
|
## Docker
|
|
39
45
|
|
|
40
|
-
As an alternative to a local installation, a prebuilt container image is published at ``ghcr.io/cameronabrams/htpolynet``. It bundles htpolynet together with Gromacs, AmberTools, and OpenBabel, so no additional dependencies are required on the host beyond Docker
|
|
46
|
+
As an alternative to a local installation, a prebuilt container image is published at ``ghcr.io/cameronabrams/htpolynet``. It bundles htpolynet together with Gromacs, AmberTools, and OpenBabel, so no additional dependencies are required on the host beyond Docker.
|
|
41
47
|
|
|
42
48
|
Run htpolynet against a configuration file in the current directory:
|
|
43
49
|
```bash
|
|
44
50
|
docker run --rm -v $(pwd):/work ghcr.io/cameronabrams/htpolynet run config.yaml
|
|
45
51
|
```
|
|
46
52
|
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
docker run --rm --gpus all -v $(pwd):/work ghcr.io/cameronabrams/htpolynet run config.yaml
|
|
50
|
-
```
|
|
53
|
+
**The image cannot use a GPU.** Its Gromacs comes from conda-forge, built against OpenCL rather than CUDA, and Gromacs no longer drives NVIDIA devices through OpenCL. Passing `--gpus all` starts the container and changes nothing about how it computes; on a cluster, target CPU partitions and do not request `--gres=gpu` or pass `--nv`. If you need GPU-accelerated Gromacs, install htpolynet natively against a CUDA-enabled Gromacs.
|
|
51
54
|
|
|
52
55
|
A Docker Compose file is also provided in [docker/compose.yml](docker/compose.yml) for a shorter invocation (``docker compose run --rm htpolynet run config.yaml``). See [docs/source/user-guide/container-usage.rst](docs/source/user-guide/container-usage.rst) for the full story, including Singularity/Apptainer use on HPC systems.
|
|
53
56
|
|
|
@@ -8,21 +8,25 @@ Rough ordering within each section is by value, not by effort.
|
|
|
8
8
|
|
|
9
9
|
## Container and deployment
|
|
10
10
|
|
|
11
|
-
- **
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
11
|
+
- **The container's Gromacs is generic `AVX2_256`, on both tags.** The
|
|
12
|
+
`:cuda` image fixes the GPU half of this problem and not the SIMD half:
|
|
13
|
+
conda-forge builds for a portable baseline, so on an AVX-512 host both
|
|
14
|
+
images leave single-core throughput on the table relative to a natively
|
|
15
|
+
built or module-provided Gromacs. This is inherent to installing Gromacs
|
|
16
|
+
from conda-forge and cannot be fixed by choosing a different build string
|
|
17
|
+
-- it would take building Gromacs in the image, which trades the weekly
|
|
18
|
+
rebuild's freshness for a long build and a host-specific artifact.
|
|
19
|
+
|
|
20
|
+
Confirmed on hardware 2026-08-25: the `:cuda` image on Picotte's gpu001
|
|
21
|
+
reports `SIMD instructions: AVX2_256` on a node whose CPUs support
|
|
22
|
+
AVX-512, and Gromacs itself prints the hint that "AVX_512 ...
|
|
23
|
+
instructions will perform best on this hardware". Still unquantified, and
|
|
24
|
+
that is what would decide whether it matters: nobody has run the same
|
|
25
|
+
system against Picotte's own `abramsGrp-gromacs/2021.2/cpu-gpu` module on
|
|
26
|
+
the same node. Note Gromacs also observes that AVX2 is often the better
|
|
27
|
+
choice for runs that offload to a GPU anyway, so the penalty may be small
|
|
28
|
+
for exactly the case the `:cuda` image serves.
|
|
29
|
+
|
|
26
30
|
- **Publish a digest or version tag people can pin.** `:latest` moves
|
|
27
31
|
every week via the scheduled rebuild, so a run recorded as "built with
|
|
28
32
|
the container" is not reproducible. Per-commit tags already exist;
|
|
@@ -91,6 +95,40 @@ Coverage as of the last measurement: **38.8%** overall.
|
|
|
91
95
|
|
|
92
96
|
## Release and distribution
|
|
93
97
|
|
|
98
|
+
- **The release preflight cannot tell whether the *previous* release
|
|
99
|
+
actually shipped to conda-forge.** `scripts/check-conda-sync.py` compares
|
|
100
|
+
`pyproject.toml`'s runtime deps against the feedstock recipe, which
|
|
101
|
+
catches dependency drift the autotick bot cannot handle. It says nothing
|
|
102
|
+
about whether the bot's last PR ever merged. That gap ran for four
|
|
103
|
+
releases: `pip check` in the recipe's test section started failing when
|
|
104
|
+
`ambertools` began pulling in distributions with unsatisfiable metadata,
|
|
105
|
+
so the bot PRs for 2.2.0, 2.3.0, 2.3.1 and 2.4.0 all sat red and unmerged
|
|
106
|
+
while conda-forge served 2.1.0 from June. Every one of those releases
|
|
107
|
+
passed the preflight, because the deps genuinely did match. Nobody
|
|
108
|
+
noticed until a bot email got read.
|
|
109
|
+
|
|
110
|
+
Fixed on 2026-08-26 by dropping `pip check` from the recipe's test section
|
|
111
|
+
(it fails on `ambertools`' bundled distributions, never on ours) and
|
|
112
|
+
merging the 2.4.0 bump, which closed the other three. **The damage is
|
|
113
|
+
permanent and visible**: conda-forge's version list for this package now
|
|
114
|
+
reads 1.0.9 -> 2.1.0 -> 2.4.0, because 2.2.0, 2.3.0 and 2.3.1 were never
|
|
115
|
+
built there and never will be. That is worth knowing as a diagnostic in
|
|
116
|
+
its own right -- a published version list that skips releases the project
|
|
117
|
+
actually made is the retroactive signature of this failure, in any
|
|
118
|
+
package, without needing to have run any check at the time.
|
|
119
|
+
|
|
120
|
+
The check is cheap: query `api.anaconda.org/package/conda-forge/htpolynet`
|
|
121
|
+
for `latest_version` and compare it against the version being superseded.
|
|
122
|
+
A mismatch does not have to block the release -- the fix is usually on the
|
|
123
|
+
feedstock, not here -- but it must be loud, because the failure mode is
|
|
124
|
+
silence. Consider also listing open PRs on the feedstock, since a red bot
|
|
125
|
+
PR is the specific thing to look at.
|
|
126
|
+
|
|
127
|
+
The deeper point is that publishing to conda-forge is the one leg of the
|
|
128
|
+
release that completes *after* `release.sh` exits and on someone else's
|
|
129
|
+
infrastructure, so it is the only one that can fail without anything here
|
|
130
|
+
noticing.
|
|
131
|
+
|
|
94
132
|
- **External services still keyed to the old repo identity.** The Aug 2026
|
|
95
133
|
transfer from `AbramsGroup/HTPolyNet` to `cameronabrams/htpolynet` moved
|
|
96
134
|
the code but left every integration pointing at the old owner. Three
|
|
@@ -105,6 +143,12 @@ Coverage as of the last measurement: **38.8%** overall.
|
|
|
105
143
|
query". Fix the RTD project URL, then activate the tagged version. Worth
|
|
106
144
|
keeping this list as the checklist if the repo ever moves again.
|
|
107
145
|
|
|
146
|
+
A fourth instance turned up on 2026-08-26 and is fixed: the conda-forge
|
|
147
|
+
recipe's `about:` block still gave `AbramsGroup/HTPolyNet` for `home` and
|
|
148
|
+
`dev_url`, and a `doc_url` of `abramsgroup.github.io/HTPolyNet` that
|
|
149
|
+
returns 404. Corrected in the same feedstock PR that unblocked the version
|
|
150
|
+
bumps.
|
|
151
|
+
|
|
108
152
|
|
|
109
153
|
- **Mint a software DOI.** Enable the Zenodo GitHub integration for
|
|
110
154
|
`cameronabrams/htpolynet`, then the next `scripts/release.sh` run
|
|
@@ -120,6 +164,61 @@ Coverage as of the last measurement: **38.8%** overall.
|
|
|
120
164
|
it read `3.10 | 3.11 | 3.12 | 3.13`, which CI already verifies at both
|
|
121
165
|
ends.
|
|
122
166
|
|
|
167
|
+
## Cure and repair
|
|
168
|
+
|
|
169
|
+
- **`completion_bias` biases the `B` side only, and that is a convention,
|
|
170
|
+
not a law.** The new `CURE.controls.completion_bias` ranks bond candidates
|
|
171
|
+
by how many bonds their `B`-side residue already carries, because
|
|
172
|
+
htpolynet's A2+B3 idiom puts the multifunctional crosslinker in the `B`
|
|
173
|
+
position -- as example 6 does. A user who declares the crosslinker as `A`
|
|
174
|
+
gets the bias pointed at their *bridges* instead: not a no-op, a different
|
|
175
|
+
claim about which partly-reacted species is a reactive intermediate. That
|
|
176
|
+
case is now warned about at the first cure iteration, by comparing the
|
|
177
|
+
initial functionality of the two sides, so it is visible rather than silent
|
|
178
|
+
-- but it is still not *served*. The generalization is small (rank on the
|
|
179
|
+
`A` side, or on the sum of both) and each variant is a different physical
|
|
180
|
+
claim, none of them run. Do it when someone has a chemistry that needs it,
|
|
181
|
+
and make them say which side rather than inferring it from functionality:
|
|
182
|
+
the warning's heuristic is good enough to flag a probable mistake and not
|
|
183
|
+
good enough to silently redirect the ranking on.
|
|
184
|
+
|
|
185
|
+
- **Nobody has run example 6 with `completion_bias` on.** The ranking is
|
|
186
|
+
unit-tested -- ordering, tie-breaks, missing residues, the fallback when a
|
|
187
|
+
`.grx` predates the `nreactions` attribute -- but the acceptance criteria
|
|
188
|
+
that matter are system-scale and need gmx and a multi-hour build:
|
|
189
|
+
incomplete triazines should collapse from tens to ~1 at
|
|
190
|
+
`desired_conversion: 0.90`, crosslinker conversion should rise from ~0.76
|
|
191
|
+
to ~0.90, `TAZ + CYN/3` must still equal the initial triazine count
|
|
192
|
+
exactly, and atom conservation must still be exact. If the incomplete
|
|
193
|
+
count does *not* collapse, the sort key is not surviving as far as the
|
|
194
|
+
truncation and that is where to look. Until someone runs it, the directive
|
|
195
|
+
is documented as untested at scale.
|
|
196
|
+
|
|
197
|
+
- **Cap placement is greedy and never backtracks.** Transferred `-C#N`
|
|
198
|
+
fragments are now placed against the local neighbourhood rather than blindly
|
|
199
|
+
along the old O-H vector, which removes the catastrophic overlaps: in a
|
|
200
|
+
synthetic box at polymer density, blind placement put 91 of 158 caps within
|
|
201
|
+
0.10 nm of a neighbour and the worst at 0.008 nm, while the neighbourhood
|
|
202
|
+
search puts none below 0.128 nm. What it does not do is relax. Each cap is
|
|
203
|
+
placed once, in the clearest direction available *at that moment*, and later
|
|
204
|
+
caps must work around it; in a genuinely over-packed box a residue of
|
|
205
|
+
sub-target placements remains (17 of 158, 33 of 378 in the same synthetic
|
|
206
|
+
test) and is reported rather than fixed. The next lever is minimizing
|
|
207
|
+
incrementally as caps land, or placing in order of how constrained each site
|
|
208
|
+
is rather than in match order. Do it if the reported clearance warnings turn
|
|
209
|
+
out to correlate with builds that still die -- the instrumentation to decide
|
|
210
|
+
that now exists, and did not before.
|
|
211
|
+
|
|
212
|
+
- **`bdf.loc[:abs_max]` takes one bond more than the limit.** In
|
|
213
|
+
`curecontroller.py::_searchbonds`, the truncation that applies
|
|
214
|
+
`max_conversion_per_iteration` uses `.loc` with a slice, which is
|
|
215
|
+
inclusive of its endpoint, so an iteration limited to `n` bonds forms
|
|
216
|
+
`n + 1`. Harmless in practice -- the limit is a throttle, not a
|
|
217
|
+
correctness bound -- but it is off by one, and fixing it changes the
|
|
218
|
+
trajectory of every existing config by one bond per throttled iteration.
|
|
219
|
+
Worth doing at a version boundary where a small reproducibility break is
|
|
220
|
+
already expected, not before.
|
|
221
|
+
|
|
123
222
|
## Usability
|
|
124
223
|
|
|
125
224
|
- **`gen-slurm-script` doesn't stage to scratch.** The emitted script
|
|
@@ -20,10 +20,22 @@
|
|
|
20
20
|
#
|
|
21
21
|
# docker run --rm -v $(pwd):/work ghcr.io/cameronabrams/htpolynet run config.yaml
|
|
22
22
|
#
|
|
23
|
-
#
|
|
23
|
+
# GPUs: the DEFAULT image cannot use one. Its Gromacs is the conda-forge
|
|
24
|
+
# OpenCL build, and Gromacs no longer drives NVIDIA devices through OpenCL, so
|
|
25
|
+
# --gpus all starts the container and changes nothing about how it computes.
|
|
24
26
|
#
|
|
25
|
-
#
|
|
26
|
-
#
|
|
27
|
+
# Build the CUDA variant instead, which installs gromacs=*=nompi_cuda*:
|
|
28
|
+
#
|
|
29
|
+
# CONDA_OVERRIDE_CUDA=12.9 docker build -f docker/Dockerfile \
|
|
30
|
+
# --build-arg GROMACS_BUILD=nompi_cuda \
|
|
31
|
+
# --build-arg CONDA_OVERRIDE_CUDA=12.9 \
|
|
32
|
+
# -t ghcr.io/cameronabrams/htpolynet:cuda .
|
|
33
|
+
#
|
|
34
|
+
# CONDA_OVERRIDE_CUDA is required to build on a machine with no NVIDIA driver:
|
|
35
|
+
# the CUDA package depends on the __cuda virtual package, which conda
|
|
36
|
+
# synthesizes only where a driver is present, so the solve fails on an
|
|
37
|
+
# ordinary CI runner without it. Running the resulting image does need
|
|
38
|
+
# nvidia-container-toolkit and --gpus all.
|
|
27
39
|
|
|
28
40
|
FROM condaforge/miniforge3:latest
|
|
29
41
|
|
|
@@ -39,9 +51,18 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
|
39
51
|
gosu \
|
|
40
52
|
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
|
41
53
|
|
|
42
|
-
|
|
54
|
+
# Which Gromacs build to install. Empty (the default) takes whatever
|
|
55
|
+
# conda-forge considers best, which for linux-64 is the OpenCL build -- correct
|
|
56
|
+
# for a CPU image, and unable to drive an NVIDIA device. Pass
|
|
57
|
+
# GROMACS_BUILD=nompi_cuda for the CUDA image; that package depends on the
|
|
58
|
+
# __cuda virtual package, so a build host without an NVIDIA driver also needs
|
|
59
|
+
# CONDA_OVERRIDE_CUDA set to a version to satisfy the solve.
|
|
60
|
+
ARG GROMACS_BUILD=
|
|
61
|
+
ARG CONDA_OVERRIDE_CUDA=
|
|
62
|
+
|
|
63
|
+
RUN CONDA_OVERRIDE_CUDA="${CONDA_OVERRIDE_CUDA}" mamba install -y -n base -c conda-forge \
|
|
43
64
|
ambertools \
|
|
44
|
-
gromacs \
|
|
65
|
+
"gromacs${GROMACS_BUILD:+=*=${GROMACS_BUILD}*}" \
|
|
45
66
|
parmed \
|
|
46
67
|
rdkit \
|
|
47
68
|
&& mamba clean -afy
|
{htpolynet-2.4.0 → htpolynet-2.6.0}/docs/source/example-tutorials/6-cyanate-ester/results.rst
RENAMED
|
@@ -39,6 +39,23 @@ Diagnostic-log plots:
|
|
|
39
39
|
with k<3 are the ones the postcure repair stage subsequently
|
|
40
40
|
dismantled.
|
|
41
41
|
|
|
42
|
+
.. warning::
|
|
43
|
+
|
|
44
|
+
The 90 % above is a **bond** conversion, and it is not the number
|
|
45
|
+
this structure would be reported as in an experiment. Repair
|
|
46
|
+
dismantles every triazine that did not fill all three of its
|
|
47
|
+
sites, so what survives is complete triazines plus unreacted
|
|
48
|
+
cyanate — and the fraction of triazines that survive is what FTIR
|
|
49
|
+
measures at 2270 cm\ :sup:`-1`. Under random placement that
|
|
50
|
+
fraction is about the cube of the bond conversion, so a run at
|
|
51
|
+
0.90 leaves a cyanate conversion near 0.73. htpolynet reports
|
|
52
|
+
both figures at the end of the repair stage and writes them to
|
|
53
|
+
``repair-summary.yaml``; see :ref:`what repair reports
|
|
54
|
+
<postcure_repair_reporting>`. If what you want is a structure
|
|
55
|
+
that really is 90 % converted, see the
|
|
56
|
+
``CURE.controls.completion_bias`` directive.
|
|
57
|
+
|
|
58
|
+
|
|
42
59
|
For end-to-end traces:
|
|
43
60
|
|
|
44
61
|
.. code-block:: console
|
|
@@ -218,6 +218,24 @@ OpenBabel sources are in ``~/Downloads`` and the install prefix is
|
|
|
218
218
|
Then set ``PATH``, ``LD_LIBRARY_PATH``, and ``BABEL_LIBDIR`` to point
|
|
219
219
|
at ``${HOME}/opt/obabel``.
|
|
220
220
|
|
|
221
|
+
Driving htpolynet with Claude Code
|
|
222
|
+
----------------------------------
|
|
223
|
+
|
|
224
|
+
``htpolynet`` ships a skill for `Claude Code
|
|
225
|
+
<https://claude.com/claude-code>`_ that teaches the agent how to use it:
|
|
226
|
+
start from the nearest example, describe monomers in their active form,
|
|
227
|
+
check a configuration before spending compute, and recognize the failure
|
|
228
|
+
modes that are known rather than mysterious. Install it once, after
|
|
229
|
+
installing the package:
|
|
230
|
+
|
|
231
|
+
.. code-block:: console
|
|
232
|
+
|
|
233
|
+
$ htpolynet setup-claude
|
|
234
|
+
|
|
235
|
+
Installing ``htpolynet`` never writes to ``~/.claude/`` on its own; the
|
|
236
|
+
skill is copied only when you run this. See :doc:`/user-guide/usage` for the options,
|
|
237
|
+
including how to scope the skill to a single project.
|
|
238
|
+
|
|
221
239
|
Other Prerequisites
|
|
222
240
|
-------------------
|
|
223
241
|
|
|
@@ -208,6 +208,8 @@ In this section we show all subdirectives for each of the five main directives i
|
|
|
208
208
|
``gromacs`` list any ``mdp`` keyword:value pairs to include in all ``mdp`` files in the ``CURE`` sequence
|
|
209
209
|
===================================== ================= =====================
|
|
210
210
|
|
|
211
|
+
.. _cure.controls:
|
|
212
|
+
|
|
211
213
|
* ``CURE.controls`` parameters
|
|
212
214
|
|
|
213
215
|
================================== ================= ======================
|
|
@@ -221,10 +223,15 @@ In this section we show all subdirectives for each of the five main directives i
|
|
|
221
223
|
``late_threshold`` float [0-1] conversion above which bond probabilities are ignored (default 0.85)
|
|
222
224
|
``max_conversion_per_iteration`` float [0-1] upper limit, as a fraction of total reactable bonds, on the new bonds formed in any single iteration (default 1.0)
|
|
223
225
|
``min_allowable_bondcycle_length`` int minimum number of C atoms allowed in a cycle of C-C bonds that form via polymerization (default 0, disallow all such cycles)
|
|
226
|
+
``completion_bias`` bool rank bond candidates by how many bonds their ``B``-side residue already carries, and only then by distance, so that partly-reacted crosslinkers are completed before untouched ones are started (default ``False``)
|
|
224
227
|
================================== ================= ======================
|
|
225
228
|
|
|
226
229
|
The ``min_bonds_per_iteration`` knob batches small late-stage finds together: instead of accepting whichever 1-2 bonds happen to lie within the initial 0.5 nm radius and immediately moving on to relax + equilibrate, the search grows the radius until at least 10 (the default) eligible bonds have been gathered. On the DGEBA/PACM example, raising it from 1 to 10 cuts the cure iteration count from 41 to 15; raising further to 20 only buys one more iteration. The default of 10 is roughly the diminishing-returns sweet spot.
|
|
227
230
|
|
|
231
|
+
``completion_bias`` changes which bonds a CURE iteration chooses, and with it what ``desired_conversion`` means physically, so it is off by default and every shipped example runs without it. Candidates are ranked by separation alone by default. Separation is uncorrelated with how many bonds a crosslinker already carries, so in an A2+B3 system the bonds spread evenly across every ``B`` in the box rather than finishing any of them: at a bond conversion of 0.90, a trifunctional crosslinker placed at random is complete with probability 0.90\ :sup:`3`, about 0.73. Turning ``completion_bias`` on makes the number of bonds already on the candidate's ``B``-side residue the primary sort key, with separation as the tie-break inside each group, so a crosslinker with two of three sites filled is finished before an untouched one is started. The ``B`` side is where htpolynet's A2+B3 idiom puts the crosslinker; declare it as ``A`` instead and the bias completes your *bridges*, so the first cure iteration compares the two sides' functionality and warns if the more functional one is on ``A``. Nothing else about the search changes -- same radius growth, same dragging and relaxation, same probabilities, same cycle handling.
|
|
232
|
+
|
|
233
|
+
Which conversion this matters for depends on the chemistry. Where a partly-reacted crosslinker is a real, stable species, the unbiased ranking is the more faithful one. Where it is a reactive intermediate -- a cyclotrimerizing cyanate ester, whose triazine ring either closes or does not -- the biased ranking is, and the difference shows up directly in what :ref:`postcure repair <postcure_repair>` has to dismantle. Note that the two settings reach different structures at the same ``desired_conversion``: a config that yields a crosslinker conversion of 0.76 at ``desired_conversion: 0.90`` unbiased will yield about 0.90 biased. Comparisons across the setting have to be made at matched crosslinker conversion, not matched ``desired_conversion``.
|
|
234
|
+
|
|
228
235
|
The ``min_allowable_bondcycle_length`` refers to the fact that in systems that polymerize via activation of carbon-carbon double bonds, it is possible in the htpolynet implementation that the "head" of a chain of C-C bonds can attack the "tail" and form a cycle, because those represent atom types that can react. It is unclear whether such cycles actually form; if a monomer remains bound to a radical initiator it is hard to see how the head of the growing chain could attack it, but maybe it could. Setting ``min_allowable_bondcycle_length`` to zero (the default) disallows any bonds that would form cycles involving only atoms that were once part of C=C double bonds. (Think about the backbone of polystyrene, for example.) In a given CURE iteration, htpolynet tests the full set of suggested bonds to see if together they result in any cycles, and for each nascent cycle longer than ``min_allowable_bondcycle_length``, htpolynet will disallow the nascent bond that has the longest initial length.
|
|
229
236
|
|
|
230
237
|
.. _cure.drag:
|